@dsh-workbench/module-tools 1.2.4 → 1.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -351,3 +351,7 @@ dry-run、真发后的元数据与发布失败回滚。
|
|
|
351
351
|
| 判据红了怎么读 | [REVIEW.md](../core/skills/workbench-module-diy/REVIEW.md) |
|
|
352
352
|
| 最小可安装样本 | [module-hello](../module-hello/README.md) |
|
|
353
353
|
| 契约类型与共享组件 | [shared](../shared/README.md) |
|
|
354
|
+
|
|
355
|
+
模块的 `apply(ctx)` / `mount(deps)` 只拿工作台自己的类型(`HostContext` / `ClientContext` /
|
|
356
|
+
`ToolDefinition` / `ToolRegistry` / `ToolRunContext`,都在 `@dsh-workbench/core/contract`);
|
|
357
|
+
要用 dsh 的官方类型,把对应包放进**模块自己的** `devDependencies`,不要放进 `dependencies`。
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dsh-workbench/module-tools",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.6",
|
|
4
4
|
"description": "模块包的构建与门禁工具:build(单文件 ESM 宿主侧 + 套 loader 壳的浏览器侧)、check(契约/产物边界/源码边界/卡片渲染)。模块包不再各带一份构建脚本。",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"semver": "^7.8.5",
|
|
34
34
|
"typescript": "5.9.3",
|
|
35
35
|
"typescript-eslint": "^8.71.0",
|
|
36
|
-
"@dsh-workbench/shared": "1.2.
|
|
36
|
+
"@dsh-workbench/shared": "1.2.6"
|
|
37
37
|
},
|
|
38
38
|
"repository": {
|
|
39
39
|
"type": "git",
|
|
@@ -2,7 +2,7 @@ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
|
2
2
|
import { tmpdir } from 'node:os';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import { afterAll, describe, expect, it, vi } from 'vitest';
|
|
5
|
-
import type {
|
|
5
|
+
import type { ToolDefinition, ToolRunContext } from '@dsh-workbench/core/contract';
|
|
6
6
|
import { createFlowHost, createLongTaskHost, type LongTaskBase } from '@dsh-workbench/shared/host';
|
|
7
7
|
|
|
8
8
|
vi.mock('@dsh-workbench/core/client', () => ({
|
|
@@ -90,7 +90,7 @@ interface OverviewAnswer {
|
|
|
90
90
|
|
|
91
91
|
interface Harness {
|
|
92
92
|
readonly mounted: Mounted;
|
|
93
|
-
readonly tools:
|
|
93
|
+
readonly tools: ToolDefinition[];
|
|
94
94
|
}
|
|
95
95
|
|
|
96
96
|
const scratch = mkdtempSync(join(tmpdir(), 'dsh-wb-diy-'));
|
|
@@ -104,7 +104,7 @@ afterAll(() => {
|
|
|
104
104
|
});
|
|
105
105
|
|
|
106
106
|
function harness(): Harness {
|
|
107
|
-
const tools:
|
|
107
|
+
const tools: ToolDefinition[] = [];
|
|
108
108
|
const longTasks = createLongTaskHost({ scope: 'plugin-test', unit: '__UNIT__', bump: () => {} });
|
|
109
109
|
const files = new Map<string, Map<string, unknown>>();
|
|
110
110
|
const storeFor = (workspace: string | null) => {
|
|
@@ -126,7 +126,7 @@ function harness(): Harness {
|
|
|
126
126
|
get: (target: string) =>
|
|
127
127
|
target === 'tools'
|
|
128
128
|
? {
|
|
129
|
-
register(tool:
|
|
129
|
+
register(tool: ToolDefinition) {
|
|
130
130
|
tools.push(tool);
|
|
131
131
|
return () => {};
|
|
132
132
|
},
|
|
@@ -150,7 +150,7 @@ function harness(): Harness {
|
|
|
150
150
|
return { mounted: hostFace().mount(deps), tools };
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
-
function toolOf(h: Harness, name: string):
|
|
153
|
+
function toolOf(h: Harness, name: string): ToolDefinition | undefined {
|
|
154
154
|
return h.tools.find((tool) => tool.name === name);
|
|
155
155
|
}
|
|
156
156
|
|
|
@@ -208,7 +208,7 @@ async function settled(h: Harness, id: string): Promise<LongTaskBase | null> {
|
|
|
208
208
|
|
|
209
209
|
const execContext = {
|
|
210
210
|
agent: { session: { id: 'session-1', header: { cwd: join(scratch, 'sample') } } },
|
|
211
|
-
} as unknown as
|
|
211
|
+
} as unknown as ToolRunContext;
|
|
212
212
|
|
|
213
213
|
describe('__NAME__ 的面', () => {
|
|
214
214
|
it('插件名就是包名', () => {
|
|
@@ -294,7 +294,7 @@ describe('宿主侧的长任务与工具', () => {
|
|
|
294
294
|
const tool = toolOf(h, DECLARED_TOOLS.run.name);
|
|
295
295
|
const started = (await tool?.execute({}, execContext)) as { ok: boolean; runId: string };
|
|
296
296
|
await settled(h, started.runId);
|
|
297
|
-
const again = (await tool?.execute({ runId: started.runId }, {} as
|
|
297
|
+
const again = (await tool?.execute({ runId: started.runId }, {} as ToolRunContext)) as { ok: boolean; runId: string };
|
|
298
298
|
expect(again.runId).toBe(started.runId);
|
|
299
299
|
});
|
|
300
300
|
|
|
@@ -309,7 +309,7 @@ describe('宿主侧的长任务与工具', () => {
|
|
|
309
309
|
it('没有工作区时工具说清楚,不抛', async () => {
|
|
310
310
|
const h = harness();
|
|
311
311
|
h.mounted.registerTools();
|
|
312
|
-
const answer = (await toolOf(h, DECLARED_TOOLS.run.name)?.execute({}, {} as
|
|
312
|
+
const answer = (await toolOf(h, DECLARED_TOOLS.run.name)?.execute({}, {} as ToolRunContext)) as { ok: boolean; text: string };
|
|
313
313
|
expect(answer.ok).toBe(false);
|
|
314
314
|
expect(answer.text).toContain('工作区');
|
|
315
315
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ToolDefinition, UnitMountDeps } from '@dsh-workbench/core/contract';
|
|
3
3
|
import { TEXT_OUTPUT, recordOf, sessionWorkspace, textOf } from '@dsh-workbench/shared/host';
|
|
4
4
|
import { DECLARED_TOOLS } from '../declared-tools';
|
|
5
5
|
import {
|
|
@@ -24,7 +24,7 @@ export interface NotesResult {
|
|
|
24
24
|
export interface Notes {
|
|
25
25
|
list(workspace: string): Note[];
|
|
26
26
|
add(workspace: string, rawText: unknown): NotesResult;
|
|
27
|
-
readonly tool:
|
|
27
|
+
readonly tool: ToolDefinition;
|
|
28
28
|
handle(payload: unknown): unknown;
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -48,7 +48,7 @@ export function createNotes(deps: UnitMountDeps): Notes {
|
|
|
48
48
|
return { ok: true, note, notes };
|
|
49
49
|
};
|
|
50
50
|
|
|
51
|
-
const tool:
|
|
51
|
+
const tool: ToolDefinition = {
|
|
52
52
|
name: DECLARED_TOOLS.addNote.name,
|
|
53
53
|
description: '往当前工作区的模块笔记里加一条(最多 20 条,只写本模块自己的文件夹,不动平台)。',
|
|
54
54
|
parameters: {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ToolDefinition, UnitMountDeps } from '@dsh-workbench/core/contract';
|
|
2
2
|
import {
|
|
3
3
|
TEXT_OUTPUT,
|
|
4
4
|
createFlowTask,
|
|
@@ -25,7 +25,7 @@ export interface StartResult {
|
|
|
25
25
|
|
|
26
26
|
export interface Sample {
|
|
27
27
|
readonly runs: LongTaskRegistry<LongTaskBase> | undefined;
|
|
28
|
-
readonly runTool:
|
|
28
|
+
readonly runTool: ToolDefinition;
|
|
29
29
|
startFromPayload(payload: unknown): StartResult;
|
|
30
30
|
}
|
|
31
31
|
|
|
@@ -78,7 +78,7 @@ export function createSample(deps: UnitMountDeps): Sample {
|
|
|
78
78
|
return { ok: true, runId: run.id, status: run.status, text: headlineOf(run) };
|
|
79
79
|
};
|
|
80
80
|
|
|
81
|
-
const runTool:
|
|
81
|
+
const runTool: ToolDefinition = flowTask?.tool ?? {
|
|
82
82
|
name: DECLARED_TOOLS.run.name,
|
|
83
83
|
description: runDescription,
|
|
84
84
|
parameters: { type: 'object', properties: {}, additionalProperties: true },
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ToolRegistry, UnitModuleFace } from '@dsh-workbench/core/contract';
|
|
2
2
|
import {
|
|
3
3
|
defineUnitHostPlugin,
|
|
4
4
|
factOfRoute,
|
|
@@ -60,7 +60,7 @@ const face: UnitModuleFace = {
|
|
|
60
60
|
},
|
|
61
61
|
},
|
|
62
62
|
registerTools: () => {
|
|
63
|
-
const tools =
|
|
63
|
+
const tools = deps.ctx.get<ToolRegistry>('tools');
|
|
64
64
|
if (tools === undefined) {
|
|
65
65
|
deps.logger?.warn?.(`[${UNIT_ID}] 外壳没有提供 tools 服务:这两把工具注册不进去`);
|
|
66
66
|
return [];
|