style: make new files lint-clean (prettier + eqeqeq + remove unused eslint-disables)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
fe45c80dd2
commit
47a774f237
@@ -24,10 +24,12 @@
|
||||
### Task 1: OpenCodeCellActions 组件(TDD)
|
||||
|
||||
**Files:**
|
||||
|
||||
- Test: `src/__tests__/opencode_cell_actions.spec.ts`(新建)
|
||||
- Create: `src/components/opencode_cell_actions.ts`(新建)
|
||||
|
||||
**Interfaces:**
|
||||
|
||||
- Consumes: `callOpenCodeEdit(request, serverSettings)`(来自 `../api/opencode_client`,不变);`extractCellContext(cell, notebookPanel)`(来自 `../context/cell_context`,不变);`../types` 全部类型(不变)。
|
||||
- Produces: `class OpenCodeCellActions extends Widget`,构造函数 `constructor(cell: CodeCell)`;`setOpenCodeRuntime(args: { settings: OpenCodeSettings; serverSettings: ServerConnection.ISettings }): void`;CSS 类 `opencode-cell-actions` / `opencode-btn opencode-btn-{optimize|fix|edit}`。Task 2 的 index.ts 依赖这两个导出。
|
||||
|
||||
@@ -115,15 +117,25 @@ function makeFakeCell(
|
||||
content: notebook
|
||||
};
|
||||
for (let i = 0; i < cellIndex; i++) {
|
||||
notebook.widgets.push({ model: { sharedModel: { getSource: () => '' } } } as any);
|
||||
notebook.widgets.push({
|
||||
model: { sharedModel: { getSource: () => '' } }
|
||||
} as any);
|
||||
}
|
||||
notebook.widgets.push(cell);
|
||||
for (let i = cellIndex + 1; i < totalCells; i++) {
|
||||
notebook.widgets.push({ model: { sharedModel: { getSource: () => '' } } } as any);
|
||||
notebook.widgets.push({
|
||||
model: { sharedModel: { getSource: () => '' } }
|
||||
} as any);
|
||||
}
|
||||
|
||||
Object.defineProperty(cell, 'parent', { value: notebook, configurable: true });
|
||||
Object.defineProperty(notebook, 'parent', { value: panel, configurable: true });
|
||||
Object.defineProperty(cell, 'parent', {
|
||||
value: notebook,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(notebook, 'parent', {
|
||||
value: panel,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
return cell as CodeCell;
|
||||
}
|
||||
@@ -403,10 +415,12 @@ git commit -m "feat: add OpenCodeCellActions widget for the native Cell toolbar"
|
||||
### Task 2: 注册进原生 Cell toolbar,拆除 footer 链路
|
||||
|
||||
**Files:**
|
||||
|
||||
- Modify: `src/index.ts`(整体重写,下方给完整内容)
|
||||
- Delete: `src/components/opencode_cell_footer.ts`、`src/components/opencode_cell_factory.ts`、`src/components/opencode_installer.ts`、`src/__tests__/opencode_cell_footer.spec.ts`
|
||||
|
||||
**Interfaces:**
|
||||
|
||||
- Consumes: Task 1 的 `OpenCodeCellActions` / `setOpenCodeRuntime`;`IToolbarWidgetRegistry.addFactory<T>(widgetFactory: string, toolbarItemName: string, factory: (main: T) => Widget)`(apputils 4.5.10)。
|
||||
- Produces: 注册名 `opencode-cell-actions`(Task 3 的 schema 必须逐字引用);插件不再依赖 `INotebookTracker`。
|
||||
|
||||
@@ -476,7 +490,9 @@ const plugin: JupyterFrontEndPlugin<void> = {
|
||||
|
||||
void callOpenCodeProviders(app.serviceManager.serverSettings)
|
||||
.then(data => {
|
||||
const lines: string[] = ['[opencode_bridge] Available OpenCode providers:'];
|
||||
const lines: string[] = [
|
||||
'[opencode_bridge] Available OpenCode providers:'
|
||||
];
|
||||
for (const p of data.providers) {
|
||||
const models = p.models.map(m => m.id).join(', ');
|
||||
lines.push(` - ${p.id}: ${models || '(no models)'}`);
|
||||
@@ -540,10 +556,12 @@ git commit -m "refactor: register AI actions in native Cell toolbar; remove cell
|
||||
### Task 3: schema 贡献 + 样式
|
||||
|
||||
**Files:**
|
||||
|
||||
- Modify: `schema/plugin.json`(顶层加 `jupyter.lab.toolbars`)
|
||||
- Modify: `style/base.css`
|
||||
|
||||
**Interfaces:**
|
||||
|
||||
- Consumes: Task 2 注册的 item 名 `opencode-cell-actions`;Task 1 的 CSS 类 `opencode-cell-actions` / `opencode-btn`。
|
||||
- Produces: 无新接口。
|
||||
|
||||
@@ -616,9 +634,11 @@ git commit -m "feat: contribute opencode-cell-actions to Cell toolbar settings +
|
||||
### Task 4: design.md 更新 + 全量验证
|
||||
|
||||
**Files:**
|
||||
|
||||
- Modify: `design.md`(第 2 节"交互与UI流程设计"第 1 条)
|
||||
|
||||
**Interfaces:**
|
||||
|
||||
- Consumes: 无。
|
||||
- Produces: 无。
|
||||
|
||||
|
||||
@@ -11,12 +11,12 @@
|
||||
|
||||
## 已确认的决策
|
||||
|
||||
| 问题 | 决策 |
|
||||
|---|---|
|
||||
| 可见性语义 | 跟随原生 toolbar:只在 **active cell** 右上角显示(与上移/下移按钮行为严格一致) |
|
||||
| 底部 footer | **删除**,三个按钮全部上移 |
|
||||
| 点击交互 | 本次不变:`🪄 编辑` 仍用 `window.prompt`;结果仍走 `Notification`;inline prompt box / diff 面板留待后续 |
|
||||
| 作用范围 | 仅 `CodeCell`;Markdown 等 cell 不显示 AI 按钮(现状 footer 挂在所有 cell 上,属顺带修正) |
|
||||
| 问题 | 决策 |
|
||||
| ----------- | ----------------------------------------------------------------------------------------------------- |
|
||||
| 可见性语义 | 跟随原生 toolbar:只在 **active cell** 右上角显示(与上移/下移按钮行为严格一致) |
|
||||
| 底部 footer | **删除**,三个按钮全部上移 |
|
||||
| 点击交互 | 本次不变:`🪄 编辑` 仍用 `window.prompt`;结果仍走 `Notification`;inline prompt box / diff 面板留待后续 |
|
||||
| 作用范围 | 仅 `CodeCell`;Markdown 等 cell 不显示 AI 按钮(现状 footer 挂在所有 cell 上,属顺带修正) |
|
||||
|
||||
## 机制(JupyterLab 4.6 真实扩展点,已核实源码)
|
||||
|
||||
|
||||
@@ -79,15 +79,25 @@ function makeFakeCell(
|
||||
content: notebook
|
||||
};
|
||||
for (let i = 0; i < cellIndex; i++) {
|
||||
notebook.widgets.push({ model: { sharedModel: { getSource: () => '' } } } as any);
|
||||
notebook.widgets.push({
|
||||
model: { sharedModel: { getSource: () => '' } }
|
||||
} as any);
|
||||
}
|
||||
notebook.widgets.push(cell);
|
||||
for (let i = cellIndex + 1; i < totalCells; i++) {
|
||||
notebook.widgets.push({ model: { sharedModel: { getSource: () => '' } } } as any);
|
||||
notebook.widgets.push({
|
||||
model: { sharedModel: { getSource: () => '' } }
|
||||
} as any);
|
||||
}
|
||||
|
||||
Object.defineProperty(cell, 'parent', { value: notebook, configurable: true });
|
||||
Object.defineProperty(notebook, 'parent', { value: panel, configurable: true });
|
||||
Object.defineProperty(cell, 'parent', {
|
||||
value: notebook,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(notebook, 'parent', {
|
||||
value: panel,
|
||||
configurable: true
|
||||
});
|
||||
|
||||
return cell as CodeCell;
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ export class OpenCodeCellActions extends Widget {
|
||||
const node = this.node;
|
||||
node.textContent = '';
|
||||
|
||||
const hasError = this._context?.error != null;
|
||||
const hasError = !!this._context?.error;
|
||||
const loading = this._status === 'loading';
|
||||
const baseDisabled = !this._context || loading;
|
||||
|
||||
|
||||
+3
-3
@@ -61,16 +61,16 @@ const plugin: JupyterFrontEndPlugin<void> = {
|
||||
|
||||
void callOpenCodeProviders(app.serviceManager.serverSettings)
|
||||
.then(data => {
|
||||
const lines: string[] = ['[opencode_bridge] Available OpenCode providers:'];
|
||||
const lines: string[] = [
|
||||
'[opencode_bridge] Available OpenCode providers:'
|
||||
];
|
||||
for (const p of data.providers) {
|
||||
const models = p.models.map(m => m.id).join(', ');
|
||||
lines.push(` - ${p.id}: ${models || '(no models)'}`);
|
||||
}
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(lines.join('\n'));
|
||||
})
|
||||
.catch(reason => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(
|
||||
'[opencode_bridge] Could not fetch providers (is the opencode-bridge server extension enabled and opencode serve running?):',
|
||||
reason
|
||||
|
||||
Reference in New Issue
Block a user