@dsh-workbench/shared 0.1.0 → 0.1.1

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.
Files changed (60) hide show
  1. package/dist/api/blocker-table.d.ts +4 -4
  2. package/dist/api/dsh.d.ts +1 -1
  3. package/dist/api/host-write.d.ts +1 -1
  4. package/dist/api/unit-board.d.ts +3 -3
  5. package/dist/components/LongTaskRow.js +2 -2
  6. package/dist/host/http.d.ts +1 -1
  7. package/dist/host/http.js +2 -2
  8. package/dist/host/opencli-runtime.d.ts +1 -1
  9. package/dist/host/opencli-runtime.js +1 -1
  10. package/dist/host/opencli.js +2 -2
  11. package/dist/host/tool-kit.js +1 -1
  12. package/dist/host/unit-face.d.ts +1 -1
  13. package/dist/host/unit-libs.d.ts +2 -2
  14. package/dist/host.d.ts +18 -19
  15. package/dist/host.js +18 -19
  16. package/dist/i18n/en.d.ts +1 -1
  17. package/dist/i18n/index.d.ts +1 -1
  18. package/dist/i18n/index.js +2 -2
  19. package/dist/i18n/merge.d.ts +1 -1
  20. package/dist/index.d.ts +33 -33
  21. package/dist/index.js +33 -33
  22. package/dist/testing/host-fakes.d.ts +41 -0
  23. package/dist/testing/host-fakes.js +76 -0
  24. package/dist/testing.d.ts +1 -0
  25. package/dist/testing.js +1 -0
  26. package/package.json +6 -2
  27. package/src/api/__tests__/blocker-table.test.ts +3 -3
  28. package/src/api/__tests__/facts.test.ts +1 -1
  29. package/src/api/__tests__/host-write.test.ts +1 -1
  30. package/src/api/__tests__/long-task.test.ts +1 -1
  31. package/src/api/__tests__/unit-board.test.ts +3 -3
  32. package/src/api/blocker-table.ts +4 -4
  33. package/src/api/dsh.ts +1 -1
  34. package/src/api/host-write.ts +1 -1
  35. package/src/api/unit-board.ts +3 -3
  36. package/src/api/workbench-client.test.ts +1 -1
  37. package/src/components/LongTaskRow.tsx +2 -2
  38. package/src/config/constants.test.ts +1 -1
  39. package/src/config/storage.test.ts +1 -1
  40. package/src/host/http.ts +2 -2
  41. package/src/host/opencli-runtime.ts +1 -1
  42. package/src/host/opencli.ts +2 -2
  43. package/src/host/tool-kit.ts +1 -1
  44. package/src/host/unit-face.ts +1 -1
  45. package/src/host/unit-libs.ts +2 -2
  46. package/src/host.ts +18 -19
  47. package/src/i18n/en.ts +1 -1
  48. package/src/i18n/index.test.ts +3 -3
  49. package/src/i18n/index.ts +2 -2
  50. package/src/i18n/merge.test.ts +1 -1
  51. package/src/i18n/merge.ts +1 -1
  52. package/src/i18n/zh.test.ts +2 -2
  53. package/src/index.ts +33 -33
  54. package/src/lib/blocker-action.test.ts +1 -1
  55. package/src/lib/busy.test.ts +1 -1
  56. package/src/lib/react.test.ts +1 -1
  57. package/src/lib/text.test.ts +1 -1
  58. package/src/lib/ui.test.ts +1 -1
  59. package/src/{host/__tests__/fakes.ts → testing/host-fakes.ts} +2 -2
  60. package/src/testing.ts +1 -0
@@ -1,7 +1,7 @@
1
- import type { Translate } from './dsh-client';
2
- import type { CapabilityPayload } from './workbench-contract';
3
- import type { ApiError } from './workbench-client';
4
- import type { ModuleBlocker } from './blocker';
1
+ import type { Translate } from './dsh-client.js';
2
+ import type { CapabilityPayload } from './workbench-contract.js';
3
+ import type { ApiError } from './workbench-client.js';
4
+ import type { ModuleBlocker } from './blocker.js';
5
5
  export declare function blockerOfError(error: ApiError | undefined, t: Translate, context?: {
6
6
  path?: string | null;
7
7
  platform?: string;
package/dist/api/dsh.d.ts CHANGED
@@ -137,7 +137,7 @@ export interface DshToolDefinition {
137
137
  schema: Record<string, unknown>;
138
138
  render(args: unknown, value: unknown): Array<Record<string, unknown>>;
139
139
  };
140
- execute(args: any, exec: DshToolRunContext): Promise<unknown>;
140
+ execute(args: unknown, exec: DshToolRunContext): Promise<unknown>;
141
141
  }
142
142
  export interface DshToolRunContext {
143
143
  readonly agent?: {
@@ -1,4 +1,4 @@
1
- import type { ApiResponse } from './workbench-client';
1
+ import type { ApiResponse } from './workbench-client.js';
2
2
  export type WriteChannel = 'prefs' | 'actions' | 'provision';
3
3
  export declare function writeRoute(channel: WriteChannel, resource: string): string;
4
4
  export type WriteOutcome<T> = {
@@ -1,6 +1,6 @@
1
- import type { ModuleBlocker } from './blocker';
2
- import type { CapabilityPayload } from './workbench-contract';
3
- import type { ApiError } from './workbench-client';
1
+ import type { ModuleBlocker } from './blocker.js';
2
+ import type { CapabilityPayload } from './workbench-contract.js';
3
+ import type { ApiError } from './workbench-client.js';
4
4
  export type GateMode = 'capability' | 'none';
5
5
  export interface UnitGate {
6
6
  readonly gated: boolean;
@@ -1,7 +1,7 @@
1
1
  import { longTaskDot } from '../api/long-task.js';
2
2
  import { Fragment, h } from '../lib/react.js';
3
- import { IconRightUp } from './icons';
4
- import { StateDot } from './StateDot';
3
+ import { IconRightUp } from './icons.js';
4
+ import { StateDot } from './StateDot.js';
5
5
  function RowLink({ href, text }) {
6
6
  return (h("a", { className: "wb-linkButton wb-longTaskLink", href: href, target: "_blank", rel: "noreferrer noopener" },
7
7
  text,
@@ -1,5 +1,5 @@
1
1
  import type { DshHostContext } from '../api/dsh.js';
2
- import { type ProvisionHandler } from './provision';
2
+ import { type ProvisionHandler } from './provision.js';
3
3
  export type RouteHandler = (search: URLSearchParams) => Promise<unknown> | unknown;
4
4
  export type RouteTable = Record<string, RouteHandler>;
5
5
  export declare function flag(search: URLSearchParams, name: string): boolean;
package/dist/host/http.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { unitFactScope } from '../api/facts.js';
2
2
  import { ACTIONS_PREFIX, API_PREFIX, PLUGIN_ID, PREFS_PREFIX, PROVISION_PREFIX } from '../config/constants.js';
3
- import { isDependencyAction, PROVISION_ACTIONS, } from './provision';
3
+ import { isDependencyAction, PROVISION_ACTIONS, } from './provision.js';
4
4
  import { WorkbenchDataError } from '../host/opencli.js';
5
- import { writeResultForClient } from './write-result';
5
+ import { writeResultForClient } from './write-result.js';
6
6
  const MAX_PREFS_BODY_BYTES = 8 * 1024;
7
7
  const PROVISION_FACTS = ['capability', 'panels'];
8
8
  function provisionFacts(provision, request) {
@@ -1,5 +1,5 @@
1
1
  import type { UnitLibNeed } from '../api/unit.js';
2
- import { dshHome } from './data-root';
2
+ import { dshHome } from './data-root.js';
3
3
  export { dshHome };
4
4
  export declare function isolatedRoot(): string;
5
5
  export declare function isolatedHome(): string;
@@ -1,6 +1,6 @@
1
1
  import { OPENCLI_PIN } from '../config/constants.js';
2
2
  import { quoteShellArg } from '../lib/text.js';
3
- import { dshHome } from './data-root';
3
+ import { dshHome } from './data-root.js';
4
4
  export { dshHome };
5
5
  export function isolatedRoot() {
6
6
  return `${dshHome()}/workbench/opencli`;
@@ -1,7 +1,7 @@
1
1
  import { OPENCLI_MAX_CONCURRENT, OPENCLI_TIMEOUT_MS } from '../config/constants.js';
2
2
  import { parseJsonLoose, quoteShellArg, tailLines } from '../lib/text.js';
3
- import { helpUrlOf, parseCliErrorEnvelope } from './cli-error';
4
- import { runShell } from './shell';
3
+ import { helpUrlOf, parseCliErrorEnvelope } from './cli-error.js';
4
+ import { runShell } from './shell.js';
5
5
  const FORBIDDEN_CODES = new Set(['FORBIDDEN', 'PERMISSION_DENIED']);
6
6
  const SITE_SESSION_ARGS = ['--site-session', 'persistent'];
7
7
  export class WorkbenchDataError extends Error {
@@ -1,4 +1,4 @@
1
- import { WorkbenchDataError } from './opencli';
1
+ import { WorkbenchDataError } from './opencli.js';
2
2
  export function sessionWorkspace(exec) {
3
3
  const cwd = exec?.agent?.session?.header?.cwd;
4
4
  return typeof cwd === 'string' && cwd.trim() !== '' ? cwd.trim() : null;
@@ -3,7 +3,7 @@ import type { UnitManifest } from '../api/unit.js';
3
3
  import type { RouteTable } from '../host/http.js';
4
4
  import type { LongTaskBase, LongTaskHost, LongTaskRegistry } from '../host/long-task.js';
5
5
  import type { ProvisionHandler } from '../host/provision.js';
6
- import type { UnitCapability } from './unit-libs';
6
+ import type { UnitCapability } from './unit-libs.js';
7
7
  import type { ApprovalCall, ApprovalFacts } from '../host/tool-approval.js';
8
8
  import type { ValueHandoff } from '../host/value-handoff.js';
9
9
  import type { WorkspaceStore } from '../host/workspace-store.js';
@@ -1,5 +1,5 @@
1
- import type { PluginSourceProblem } from './plugin-source';
2
- import type { PluginRelease, UnitLibNeed, UnitPluginNeed } from '../api/unit';
1
+ import type { PluginSourceProblem } from './plugin-source.js';
2
+ import type { PluginRelease, UnitLibNeed, UnitPluginNeed } from '../api/unit.js';
3
3
  export interface UnitLibState {
4
4
  readonly name: string;
5
5
  readonly purpose: string;
package/dist/host.d.ts CHANGED
@@ -1,19 +1,18 @@
1
- export * from './host/__tests__/fakes';
2
- export * from './host/cli-error';
3
- export * from './host/data-root';
4
- export * from './host/facts';
5
- export * from './host/git';
6
- export * from './host/http';
7
- export * from './host/long-task';
8
- export * from './host/opencli-runtime';
9
- export * from './host/opencli';
10
- export * from './host/plugin-source';
11
- export * from './host/provision';
12
- export * from './host/shell';
13
- export * from './host/tool-approval';
14
- export * from './host/tool-kit';
15
- export * from './host/unit-face';
16
- export * from './host/unit-libs';
17
- export * from './host/value-handoff';
18
- export * from './host/workspace-store';
19
- export * from './host/write-result';
1
+ export * from './host/cli-error.js';
2
+ export * from './host/data-root.js';
3
+ export * from './host/facts.js';
4
+ export * from './host/git.js';
5
+ export * from './host/http.js';
6
+ export * from './host/long-task.js';
7
+ export * from './host/opencli-runtime.js';
8
+ export * from './host/opencli.js';
9
+ export * from './host/plugin-source.js';
10
+ export * from './host/provision.js';
11
+ export * from './host/shell.js';
12
+ export * from './host/tool-approval.js';
13
+ export * from './host/tool-kit.js';
14
+ export * from './host/unit-face.js';
15
+ export * from './host/unit-libs.js';
16
+ export * from './host/value-handoff.js';
17
+ export * from './host/workspace-store.js';
18
+ export * from './host/write-result.js';
package/dist/host.js CHANGED
@@ -1,19 +1,18 @@
1
- export * from './host/__tests__/fakes';
2
- export * from './host/cli-error';
3
- export * from './host/data-root';
4
- export * from './host/facts';
5
- export * from './host/git';
6
- export * from './host/http';
7
- export * from './host/long-task';
8
- export * from './host/opencli-runtime';
9
- export * from './host/opencli';
10
- export * from './host/plugin-source';
11
- export * from './host/provision';
12
- export * from './host/shell';
13
- export * from './host/tool-approval';
14
- export * from './host/tool-kit';
15
- export * from './host/unit-face';
16
- export * from './host/unit-libs';
17
- export * from './host/value-handoff';
18
- export * from './host/workspace-store';
19
- export * from './host/write-result';
1
+ export * from './host/cli-error.js';
2
+ export * from './host/data-root.js';
3
+ export * from './host/facts.js';
4
+ export * from './host/git.js';
5
+ export * from './host/http.js';
6
+ export * from './host/long-task.js';
7
+ export * from './host/opencli-runtime.js';
8
+ export * from './host/opencli.js';
9
+ export * from './host/plugin-source.js';
10
+ export * from './host/provision.js';
11
+ export * from './host/shell.js';
12
+ export * from './host/tool-approval.js';
13
+ export * from './host/tool-kit.js';
14
+ export * from './host/unit-face.js';
15
+ export * from './host/unit-libs.js';
16
+ export * from './host/value-handoff.js';
17
+ export * from './host/workspace-store.js';
18
+ export * from './host/write-result.js';
package/dist/i18n/en.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import type { WorkbenchMessages } from './zh';
1
+ import type { WorkbenchMessages } from './zh.js';
2
2
  export declare const en: Record<keyof WorkbenchMessages, string>;
@@ -1,4 +1,4 @@
1
- import { type WorkbenchMessages } from './zh';
1
+ import { type WorkbenchMessages } from './zh.js';
2
2
  export declare const dictionaries: {
3
3
  zh: {
4
4
  readonly 'brand.name': "工作台";
@@ -1,3 +1,3 @@
1
- import { en } from './en';
2
- import { zh } from './zh';
1
+ import { en } from './en.js';
2
+ import { zh } from './zh.js';
3
3
  export const dictionaries = { zh, en };
@@ -1,4 +1,4 @@
1
- import type { Dictionaries } from './index';
1
+ import type { Dictionaries } from './index.js';
2
2
  export interface MessagesContribution {
3
3
  readonly unit: string;
4
4
  readonly messages?: Dictionaries | undefined;
package/dist/index.d.ts CHANGED
@@ -1,33 +1,33 @@
1
- export * from './api/blocker-table';
2
- export * from './api/blocker';
3
- export * from './api/context-ref';
4
- export * from './api/dsh-client';
5
- export * from './api/dsh';
6
- export * from './api/facts';
7
- export * from './api/host-write';
8
- export * from './api/long-task';
9
- export * from './api/unit-board';
10
- export * from './api/unit';
11
- export * from './api/workbench-client';
12
- export * from './api/workbench-contract';
13
- export * from './components/ApprovalDetail';
14
- export * from './components/CardHead';
15
- export * from './components/ChoiceGroup';
16
- export * from './components/LongTaskRow';
17
- export * from './components/MockStrip';
18
- export * from './components/ResourceStates';
19
- export * from './components/SaveBar';
20
- export * from './components/StateDot';
21
- export * from './components/board-module';
22
- export * from './components/icons';
23
- export * from './config/constants';
24
- export * from './config/storage';
25
- export * from './i18n/en';
26
- export * from './i18n/index';
27
- export * from './i18n/merge';
28
- export * from './i18n/zh';
29
- export * from './lib/blocker-action';
30
- export * from './lib/busy';
31
- export * from './lib/react';
32
- export * from './lib/text';
33
- export * from './lib/ui';
1
+ export * from './api/blocker-table.js';
2
+ export * from './api/blocker.js';
3
+ export * from './api/context-ref.js';
4
+ export * from './api/dsh-client.js';
5
+ export * from './api/dsh.js';
6
+ export * from './api/facts.js';
7
+ export * from './api/host-write.js';
8
+ export * from './api/long-task.js';
9
+ export * from './api/unit-board.js';
10
+ export * from './api/unit.js';
11
+ export * from './api/workbench-client.js';
12
+ export * from './api/workbench-contract.js';
13
+ export * from './components/ApprovalDetail.js';
14
+ export * from './components/CardHead.js';
15
+ export * from './components/ChoiceGroup.js';
16
+ export * from './components/LongTaskRow.js';
17
+ export * from './components/MockStrip.js';
18
+ export * from './components/ResourceStates.js';
19
+ export * from './components/SaveBar.js';
20
+ export * from './components/StateDot.js';
21
+ export * from './components/board-module.js';
22
+ export * from './components/icons.js';
23
+ export * from './config/constants.js';
24
+ export * from './config/storage.js';
25
+ export * from './i18n/en.js';
26
+ export * from './i18n/index.js';
27
+ export * from './i18n/merge.js';
28
+ export * from './i18n/zh.js';
29
+ export * from './lib/blocker-action.js';
30
+ export * from './lib/busy.js';
31
+ export * from './lib/react.js';
32
+ export * from './lib/text.js';
33
+ export * from './lib/ui.js';
package/dist/index.js CHANGED
@@ -1,33 +1,33 @@
1
- export * from './api/blocker-table';
2
- export * from './api/blocker';
3
- export * from './api/context-ref';
4
- export * from './api/dsh-client';
5
- export * from './api/dsh';
6
- export * from './api/facts';
7
- export * from './api/host-write';
8
- export * from './api/long-task';
9
- export * from './api/unit-board';
10
- export * from './api/unit';
11
- export * from './api/workbench-client';
12
- export * from './api/workbench-contract';
13
- export * from './components/ApprovalDetail';
14
- export * from './components/CardHead';
15
- export * from './components/ChoiceGroup';
16
- export * from './components/LongTaskRow';
17
- export * from './components/MockStrip';
18
- export * from './components/ResourceStates';
19
- export * from './components/SaveBar';
20
- export * from './components/StateDot';
21
- export * from './components/board-module';
22
- export * from './components/icons';
23
- export * from './config/constants';
24
- export * from './config/storage';
25
- export * from './i18n/en';
26
- export * from './i18n/index';
27
- export * from './i18n/merge';
28
- export * from './i18n/zh';
29
- export * from './lib/blocker-action';
30
- export * from './lib/busy';
31
- export * from './lib/react';
32
- export * from './lib/text';
33
- export * from './lib/ui';
1
+ export * from './api/blocker-table.js';
2
+ export * from './api/blocker.js';
3
+ export * from './api/context-ref.js';
4
+ export * from './api/dsh-client.js';
5
+ export * from './api/dsh.js';
6
+ export * from './api/facts.js';
7
+ export * from './api/host-write.js';
8
+ export * from './api/long-task.js';
9
+ export * from './api/unit-board.js';
10
+ export * from './api/unit.js';
11
+ export * from './api/workbench-client.js';
12
+ export * from './api/workbench-contract.js';
13
+ export * from './components/ApprovalDetail.js';
14
+ export * from './components/CardHead.js';
15
+ export * from './components/ChoiceGroup.js';
16
+ export * from './components/LongTaskRow.js';
17
+ export * from './components/MockStrip.js';
18
+ export * from './components/ResourceStates.js';
19
+ export * from './components/SaveBar.js';
20
+ export * from './components/StateDot.js';
21
+ export * from './components/board-module.js';
22
+ export * from './components/icons.js';
23
+ export * from './config/constants.js';
24
+ export * from './config/storage.js';
25
+ export * from './i18n/en.js';
26
+ export * from './i18n/index.js';
27
+ export * from './i18n/merge.js';
28
+ export * from './i18n/zh.js';
29
+ export * from './lib/blocker-action.js';
30
+ export * from './lib/busy.js';
31
+ export * from './lib/react.js';
32
+ export * from './lib/text.js';
33
+ export * from './lib/ui.js';
@@ -0,0 +1,41 @@
1
+ import type { DshShell } from '../api/dsh.js';
2
+ import type { Opencli } from '../host/opencli.js';
3
+ export interface ShellCall {
4
+ command: string;
5
+ workdir?: string;
6
+ timeoutMs?: number;
7
+ onExpiry?: string;
8
+ stdoutMaxBytes?: number;
9
+ }
10
+ export interface ShellReply {
11
+ stdout?: string;
12
+ stderr?: string;
13
+ exitCode?: number | null;
14
+ timedOut?: boolean;
15
+ aborted?: boolean;
16
+ failWith?: Error;
17
+ }
18
+ export declare function createFakeShell(replies?: ShellReply[] | ((call: ShellCall, index: number) => ShellReply)): {
19
+ shell: DshShell;
20
+ calls: ShellCall[];
21
+ peak: () => number;
22
+ commands: () => string[];
23
+ };
24
+ export interface OpencliCall {
25
+ args: readonly string[];
26
+ key?: string;
27
+ workdir?: string;
28
+ refresh?: boolean;
29
+ }
30
+ export declare function createFakeOpencli(replies?: Array<unknown | Error> | ((call: OpencliCall, index: number) => unknown | Error)): {
31
+ opencli: Opencli;
32
+ calls: OpencliCall[];
33
+ keys: () => (string | undefined)[];
34
+ };
35
+ export declare function createFakeLogger(): {
36
+ logger: {
37
+ info: () => void;
38
+ warn: (message: string) => void;
39
+ };
40
+ warnings: string[];
41
+ };
@@ -0,0 +1,76 @@
1
+ import { setTimeout as delay } from 'node:timers/promises';
2
+ const tick = () => delay(0);
3
+ export function createFakeShell(replies = []) {
4
+ const calls = [];
5
+ let running = 0;
6
+ let peak = 0;
7
+ const replyAt = (index) => typeof replies === 'function' ? replies(calls[index], index) : (replies[index] ?? {});
8
+ const shell = {
9
+ resolve(request) {
10
+ calls.push(request);
11
+ return request;
12
+ },
13
+ async execute() {
14
+ const index = calls.length - 1;
15
+ const reply = replyAt(index);
16
+ if (reply.failWith !== undefined)
17
+ throw reply.failWith;
18
+ running += 1;
19
+ peak = Math.max(peak, running);
20
+ return {
21
+ async result() {
22
+ await tick();
23
+ running -= 1;
24
+ return {
25
+ exitCode: reply.exitCode ?? 0,
26
+ timedOut: reply.timedOut ?? false,
27
+ aborted: reply.aborted ?? false,
28
+ stdout: { text: reply.stdout ?? '', truncated: false },
29
+ stderr: { text: reply.stderr ?? '', truncated: false },
30
+ };
31
+ },
32
+ };
33
+ },
34
+ };
35
+ return {
36
+ shell,
37
+ calls,
38
+ peak: () => peak,
39
+ commands: () => calls.map((call) => call.command),
40
+ };
41
+ }
42
+ export function createFakeOpencli(replies = []) {
43
+ const calls = [];
44
+ const opencli = {
45
+ async json(args, options = {}) {
46
+ const call = {
47
+ args,
48
+ ...(options.key === undefined ? {} : { key: options.key }),
49
+ ...(options.workdir === undefined ? {} : { workdir: options.workdir }),
50
+ };
51
+ calls.push(call);
52
+ const index = calls.length - 1;
53
+ const reply = typeof replies === 'function' ? replies(call, index) : (replies[index] ?? []);
54
+ if (reply instanceof Error)
55
+ throw reply;
56
+ return { value: reply, at: Date.now() };
57
+ },
58
+ };
59
+ return {
60
+ opencli,
61
+ calls,
62
+ keys: () => calls.map((call) => call.key),
63
+ };
64
+ }
65
+ export function createFakeLogger() {
66
+ const warnings = [];
67
+ return {
68
+ logger: {
69
+ info: () => { },
70
+ warn: (message) => {
71
+ warnings.push(message);
72
+ },
73
+ },
74
+ warnings,
75
+ };
76
+ }
@@ -0,0 +1 @@
1
+ export * from './testing/host-fakes.js';
@@ -0,0 +1 @@
1
+ export * from './testing/host-fakes.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dsh-workbench/shared",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "工作台与模块共享的纯代码与契约类型:类型、纯逻辑、哑组件、平台解析。宿主侧的东西从 /host 进(不影响浏览器产物)。",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -12,6 +12,10 @@
12
12
  "./host": {
13
13
  "types": "./dist/host.d.ts",
14
14
  "default": "./dist/host.js"
15
+ },
16
+ "./testing": {
17
+ "types": "./dist/testing.d.ts",
18
+ "default": "./dist/testing.js"
15
19
  }
16
20
  },
17
21
  "files": [
@@ -26,7 +30,7 @@
26
30
  },
27
31
  "devDependencies": {
28
32
  "@arch-guard/core": "^0.10.0",
29
- "@types/node": "^20.0.0",
33
+ "@types/node": "^24.19.0",
30
34
  "@types/react": "^19.0.0",
31
35
  "@vitest/coverage-v8": "^5.0.2",
32
36
  "react": "^18.0.0",
@@ -1,7 +1,7 @@
1
1
  import { describe, expect, it } from 'vitest';
2
- import type { Translate } from '../dsh-client';
3
- import type { CapabilityPayload } from '../workbench-contract';
4
- import { blockerOfCapability, blockerOfError } from '../blocker-table';
2
+ import type { Translate } from '../dsh-client.js';
3
+ import type { CapabilityPayload } from '../workbench-contract.js';
4
+ import { blockerOfCapability, blockerOfError } from '../blocker-table.js';
5
5
 
6
6
  const t: Translate = (key, params) => (params === undefined ? key : `${key}(${JSON.stringify(params)})`);
7
7
 
@@ -8,7 +8,7 @@ import {
8
8
  unitFactScope,
9
9
  type FactFrame,
10
10
  type FactTransport,
11
- } from '../facts';
11
+ } from '../facts.js';
12
12
 
13
13
  function fakeTransport(): {
14
14
  transport: FactTransport;
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from 'vitest';
2
- import { writeOutcomeOf, writeRoute } from '../host-write';
2
+ import { writeOutcomeOf, writeRoute } from '../host-write.js';
3
3
 
4
4
  describe('writeRoute', () => {
5
5
  it('三条通道各自拼得出路由(面板上的写只有这三条)', () => {
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from 'vitest';
2
- import { longTaskDot, longTaskPollMs, longTaskRunsOf, runsRouteOf } from '../long-task';
2
+ import { longTaskDot, longTaskPollMs, longTaskRunsOf, runsRouteOf } from '../long-task.js';
3
3
 
4
4
  describe('runsRouteOf', () => {
5
5
  it('★ 事实名 = 路由名(三处同一个来源,改一处不可能漏另一处)', () => {
@@ -1,7 +1,7 @@
1
1
  import { describe, expect, it } from 'vitest';
2
- import type { ModuleBlocker } from '../blocker';
3
- import type { CapabilityPayload } from '../workbench-contract';
4
- import { gateOf, probeKeyOf, splitBlocker } from '../unit-board';
2
+ import type { ModuleBlocker } from '../blocker.js';
3
+ import type { CapabilityPayload } from '../workbench-contract.js';
4
+ import { gateOf, probeKeyOf, splitBlocker } from '../unit-board.js';
5
5
 
6
6
  function capability(status: CapabilityPayload['status']): CapabilityPayload {
7
7
  return { unit: 'issues', status, required: [], missing: [], detail: '测试用的结论' };
@@ -1,7 +1,7 @@
1
- import type { Translate } from './dsh-client';
2
- import type { CapabilityPayload } from './workbench-contract';
3
- import type { ApiError } from './workbench-client';
4
- import type { BlockerAction, ModuleBlocker } from './blocker';
1
+ import type { Translate } from './dsh-client.js';
2
+ import type { CapabilityPayload } from './workbench-contract.js';
3
+ import type { ApiError } from './workbench-client.js';
4
+ import type { BlockerAction, ModuleBlocker } from './blocker.js';
5
5
  import { shortenPath } from '../lib/ui.js';
6
6
 
7
7
  function retryAction(t: Translate): BlockerAction {
package/src/api/dsh.ts CHANGED
@@ -140,7 +140,7 @@ export interface DshToolDefinition {
140
140
  schema: Record<string, unknown>;
141
141
  render(args: unknown, value: unknown): Array<Record<string, unknown>>;
142
142
  };
143
- execute(args: any, exec: DshToolRunContext): Promise<unknown>;
143
+ execute(args: unknown, exec: DshToolRunContext): Promise<unknown>;
144
144
  }
145
145
 
146
146
  export interface DshToolRunContext {
@@ -1,4 +1,4 @@
1
- import type { ApiResponse } from './workbench-client';
1
+ import type { ApiResponse } from './workbench-client.js';
2
2
 
3
3
  export type WriteChannel = 'prefs' | 'actions' | 'provision';
4
4
 
@@ -1,6 +1,6 @@
1
- import type { ModuleBlocker } from './blocker';
2
- import type { CapabilityPayload } from './workbench-contract';
3
- import type { ApiError } from './workbench-client';
1
+ import type { ModuleBlocker } from './blocker.js';
2
+ import type { CapabilityPayload } from './workbench-contract.js';
3
+ import type { ApiError } from './workbench-client.js';
4
4
 
5
5
  export type GateMode =
6
6
  | 'capability'
@@ -1,6 +1,6 @@
1
1
  import { afterEach, describe, expect, it, vi } from 'vitest';
2
2
  import { API_PREFIX } from '../config/constants.js';
3
- import { apiGet } from './workbench-client';
3
+ import { apiGet } from './workbench-client.js';
4
4
 
5
5
  interface FetchRecord {
6
6
  url: string;
@@ -1,7 +1,7 @@
1
1
  import { longTaskDot, type LongTaskStatus } from '../api/long-task.js';
2
2
  import { Fragment, h } from '../lib/react.js';
3
- import { IconRightUp } from './icons';
4
- import { StateDot } from './StateDot';
3
+ import { IconRightUp } from './icons.js';
4
+ import { StateDot } from './StateDot.js';
5
5
 
6
6
  export interface LongTaskRowLink {
7
7
  readonly href: string;
@@ -8,7 +8,7 @@ import {
8
8
  PLUGIN_ID,
9
9
  STORAGE_KEY_PROJECT,
10
10
  STORAGE_KEY_RIGHTBAR,
11
- } from './constants';
11
+ } from './constants.js';
12
12
 
13
13
  describe('constants', () => {
14
14
  it('API_PREFIX 是合法前缀:以 / 开头、不以 / 结尾、不带查询符', () => {
@@ -1,5 +1,5 @@
1
1
  import { afterEach, describe, expect, it, vi } from 'vitest';
2
- import { readFlag, readText, writeFlag, writeText } from './storage';
2
+ import { readFlag, readText, writeFlag, writeText } from './storage.js';
3
3
 
4
4
  function fakeStorage(options: { throwOnWrite?: boolean } = {}) {
5
5
  const data = new Map<string, string>();
package/src/host/http.ts CHANGED
@@ -7,9 +7,9 @@ import {
7
7
  type ProvisionAction,
8
8
  type ProvisionHandler,
9
9
  type ProvisionRequest,
10
- } from './provision';
10
+ } from './provision.js';
11
11
  import { WorkbenchDataError } from '../host/opencli.js';
12
- import { writeResultForClient } from './write-result';
12
+ import { writeResultForClient } from './write-result.js';
13
13
 
14
14
  export type RouteHandler = (search: URLSearchParams) => Promise<unknown> | unknown;
15
15
 
@@ -2,7 +2,7 @@ import { OPENCLI_PIN } from '../config/constants.js';
2
2
  import type { UnitLibNeed } from '../api/unit.js';
3
3
  import { quoteShellArg } from '../lib/text.js';
4
4
 
5
- import { dshHome } from './data-root';
5
+ import { dshHome } from './data-root.js';
6
6
 
7
7
  export { dshHome };
8
8
 
@@ -1,8 +1,8 @@
1
1
  import type { DshShell } from '../api/dsh.js';
2
2
  import { OPENCLI_MAX_CONCURRENT, OPENCLI_TIMEOUT_MS } from '../config/constants.js';
3
3
  import { parseJsonLoose, quoteShellArg, tailLines } from '../lib/text.js';
4
- import { helpUrlOf, parseCliErrorEnvelope } from './cli-error';
5
- import { runShell } from './shell';
4
+ import { helpUrlOf, parseCliErrorEnvelope } from './cli-error.js';
5
+ import { runShell } from './shell.js';
6
6
 
7
7
  const FORBIDDEN_CODES = new Set(['FORBIDDEN', 'PERMISSION_DENIED']);
8
8
 
@@ -1,5 +1,5 @@
1
1
  import type { DshToolRunContext } from '../api/dsh.js';
2
- import { WorkbenchDataError } from './opencli';
2
+ import { WorkbenchDataError } from './opencli.js';
3
3
 
4
4
  export function sessionWorkspace(exec: DshToolRunContext | undefined): string | null {
5
5
  const cwd = exec?.agent?.session?.header?.cwd;
@@ -3,7 +3,7 @@ import type { UnitManifest } from '../api/unit.js';
3
3
  import type { RouteTable } from '../host/http.js';
4
4
  import type { LongTaskBase, LongTaskHost, LongTaskRegistry } from '../host/long-task.js';
5
5
  import type { ProvisionHandler } from '../host/provision.js';
6
- import type { UnitCapability } from './unit-libs';
6
+ import type { UnitCapability } from './unit-libs.js';
7
7
  import type { ApprovalCall, ApprovalFacts } from '../host/tool-approval.js';
8
8
  import type { ValueHandoff } from '../host/value-handoff.js';
9
9
  import type { WorkspaceStore } from '../host/workspace-store.js';
@@ -1,5 +1,5 @@
1
- import type { PluginSourceProblem } from './plugin-source';
2
- import type { PluginRelease, UnitLibNeed, UnitPluginNeed } from '../api/unit';
1
+ import type { PluginSourceProblem } from './plugin-source.js';
2
+ import type { PluginRelease, UnitLibNeed, UnitPluginNeed } from '../api/unit.js';
3
3
 
4
4
  export interface UnitLibState {
5
5
  readonly name: string;
package/src/host.ts CHANGED
@@ -1,19 +1,18 @@
1
- export * from './host/__tests__/fakes';
2
- export * from './host/cli-error';
3
- export * from './host/data-root';
4
- export * from './host/facts';
5
- export * from './host/git';
6
- export * from './host/http';
7
- export * from './host/long-task';
8
- export * from './host/opencli-runtime';
9
- export * from './host/opencli';
10
- export * from './host/plugin-source';
11
- export * from './host/provision';
12
- export * from './host/shell';
13
- export * from './host/tool-approval';
14
- export * from './host/tool-kit';
15
- export * from './host/unit-face';
16
- export * from './host/unit-libs';
17
- export * from './host/value-handoff';
18
- export * from './host/workspace-store';
19
- export * from './host/write-result';
1
+ export * from './host/cli-error.js';
2
+ export * from './host/data-root.js';
3
+ export * from './host/facts.js';
4
+ export * from './host/git.js';
5
+ export * from './host/http.js';
6
+ export * from './host/long-task.js';
7
+ export * from './host/opencli-runtime.js';
8
+ export * from './host/opencli.js';
9
+ export * from './host/plugin-source.js';
10
+ export * from './host/provision.js';
11
+ export * from './host/shell.js';
12
+ export * from './host/tool-approval.js';
13
+ export * from './host/tool-kit.js';
14
+ export * from './host/unit-face.js';
15
+ export * from './host/unit-libs.js';
16
+ export * from './host/value-handoff.js';
17
+ export * from './host/workspace-store.js';
18
+ export * from './host/write-result.js';
package/src/i18n/en.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { WorkbenchMessages } from './zh';
1
+ import type { WorkbenchMessages } from './zh.js';
2
2
 
3
3
  export const en: Record<keyof WorkbenchMessages, string> = {
4
4
  'brand.name': 'Workbench',
@@ -1,7 +1,7 @@
1
1
  import { describe, expect, it } from 'vitest';
2
- import { en } from './en';
3
- import { dictionaries } from './index';
4
- import { zh } from './zh';
2
+ import { en } from './en.js';
3
+ import { dictionaries } from './index.js';
4
+ import { zh } from './zh.js';
5
5
 
6
6
  describe('dictionaries', () => {
7
7
  it('同时导出两种语言,且就是那两份字典', () => {
package/src/i18n/index.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { en } from './en';
2
- import { zh, type WorkbenchMessages } from './zh';
1
+ import { en } from './en.js';
2
+ import { zh, type WorkbenchMessages } from './zh.js';
3
3
 
4
4
  export const dictionaries = { zh, en };
5
5
 
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from 'vitest';
2
- import { mergeMessages } from './merge';
2
+ import { mergeMessages } from './merge.js';
3
3
 
4
4
  const base = { zh: { 'board.title': '看板' }, en: { 'board.title': 'Board' } };
5
5
 
package/src/i18n/merge.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { Dictionaries } from './index';
1
+ import type { Dictionaries } from './index.js';
2
2
 
3
3
  export interface MessagesContribution {
4
4
  readonly unit: string;
@@ -1,6 +1,6 @@
1
1
  import { describe, expect, it } from 'vitest';
2
- import { en } from './en';
3
- import { zh } from './zh';
2
+ import { en } from './en.js';
3
+ import { zh } from './zh.js';
4
4
 
5
5
  function placeholders(text: string): string[] {
6
6
  return [...text.matchAll(/\{(\w+)\}/g)].map((match) => match[1] ?? '').sort();
package/src/index.ts CHANGED
@@ -1,33 +1,33 @@
1
- export * from './api/blocker-table';
2
- export * from './api/blocker';
3
- export * from './api/context-ref';
4
- export * from './api/dsh-client';
5
- export * from './api/dsh';
6
- export * from './api/facts';
7
- export * from './api/host-write';
8
- export * from './api/long-task';
9
- export * from './api/unit-board';
10
- export * from './api/unit';
11
- export * from './api/workbench-client';
12
- export * from './api/workbench-contract';
13
- export * from './components/ApprovalDetail';
14
- export * from './components/CardHead';
15
- export * from './components/ChoiceGroup';
16
- export * from './components/LongTaskRow';
17
- export * from './components/MockStrip';
18
- export * from './components/ResourceStates';
19
- export * from './components/SaveBar';
20
- export * from './components/StateDot';
21
- export * from './components/board-module';
22
- export * from './components/icons';
23
- export * from './config/constants';
24
- export * from './config/storage';
25
- export * from './i18n/en';
26
- export * from './i18n/index';
27
- export * from './i18n/merge';
28
- export * from './i18n/zh';
29
- export * from './lib/blocker-action';
30
- export * from './lib/busy';
31
- export * from './lib/react';
32
- export * from './lib/text';
33
- export * from './lib/ui';
1
+ export * from './api/blocker-table.js';
2
+ export * from './api/blocker.js';
3
+ export * from './api/context-ref.js';
4
+ export * from './api/dsh-client.js';
5
+ export * from './api/dsh.js';
6
+ export * from './api/facts.js';
7
+ export * from './api/host-write.js';
8
+ export * from './api/long-task.js';
9
+ export * from './api/unit-board.js';
10
+ export * from './api/unit.js';
11
+ export * from './api/workbench-client.js';
12
+ export * from './api/workbench-contract.js';
13
+ export * from './components/ApprovalDetail.js';
14
+ export * from './components/CardHead.js';
15
+ export * from './components/ChoiceGroup.js';
16
+ export * from './components/LongTaskRow.js';
17
+ export * from './components/MockStrip.js';
18
+ export * from './components/ResourceStates.js';
19
+ export * from './components/SaveBar.js';
20
+ export * from './components/StateDot.js';
21
+ export * from './components/board-module.js';
22
+ export * from './components/icons.js';
23
+ export * from './config/constants.js';
24
+ export * from './config/storage.js';
25
+ export * from './i18n/en.js';
26
+ export * from './i18n/index.js';
27
+ export * from './i18n/merge.js';
28
+ export * from './i18n/zh.js';
29
+ export * from './lib/blocker-action.js';
30
+ export * from './lib/busy.js';
31
+ export * from './lib/react.js';
32
+ export * from './lib/text.js';
33
+ export * from './lib/ui.js';
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from 'vitest';
2
- import { blockerActionLabel, blockerPending } from './blocker-action';
2
+ import { blockerActionLabel, blockerPending } from './blocker-action.js';
3
3
 
4
4
  const t = (key: string): string => `«${key}»`;
5
5
 
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from 'vitest';
2
- import { holdBusy } from './busy';
2
+ import { holdBusy } from './busy.js';
3
3
 
4
4
  describe('holdBusy', () => {
5
5
  it('这一轮忙刚开了头:还要按住,剩下的时长报出来(计时器按它收尾)', () => {
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { describe, expect, it } from 'vitest';
3
- import { Fragment, h, useCallback, useEffect, useMemo, useRef, useState } from './react';
3
+ import { Fragment, h, useCallback, useEffect, useMemo, useRef, useState } from './react.js';
4
4
 
5
5
  describe('react 入口', () => {
6
6
  it('h 就是 React.createElement(同一个引用,不是包装)', () => {
@@ -1,6 +1,6 @@
1
1
  import { execFileSync } from 'node:child_process';
2
2
  import { describe, expect, it } from 'vitest';
3
- import { excerpt, parseJsonLoose, quoteShellArg, tailLines } from './text';
3
+ import { excerpt, parseJsonLoose, quoteShellArg, tailLines } from './text.js';
4
4
 
5
5
  function shellSees(value: string): string {
6
6
  return execFileSync('/bin/sh', ['-c', `printf '%s' ${quoteShellArg(value)}`], {
@@ -5,7 +5,7 @@ import {
5
5
  relativeTime,
6
6
  shortenPath,
7
7
  type TimeTranslate,
8
- } from './ui';
8
+ } from './ui.js';
9
9
 
10
10
  const t: TimeTranslate = (key, params) =>
11
11
  params === undefined ? key : `${key}:${String(params.n ?? '')}`;
@@ -1,6 +1,6 @@
1
1
  import { setTimeout as delay } from 'node:timers/promises';
2
- import type { DshShell } from '../../api/dsh.js';
3
- import type { Opencli, OpencliResult } from '../../host/opencli.js';
2
+ import type { DshShell } from '../api/dsh.js';
3
+ import type { Opencli, OpencliResult } from '../host/opencli.js';
4
4
 
5
5
  export interface ShellCall {
6
6
  command: string;
package/src/testing.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './testing/host-fakes.js';