@winmatrix/agent-sdk 0.1.0

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 (93) hide show
  1. package/dist/adapters/claude/ClaudeAdapter.d.ts +40 -0
  2. package/dist/adapters/claude/ClaudeAdapter.d.ts.map +1 -0
  3. package/dist/adapters/claude/ClaudeAdapter.js +515 -0
  4. package/dist/adapters/claude/ClaudeAdapter.js.map +1 -0
  5. package/dist/adapters/claude/ClaudeStreamParser.d.ts +39 -0
  6. package/dist/adapters/claude/ClaudeStreamParser.d.ts.map +1 -0
  7. package/dist/adapters/claude/ClaudeStreamParser.js +80 -0
  8. package/dist/adapters/claude/ClaudeStreamParser.js.map +1 -0
  9. package/dist/adapters/hermes/HermesAdapter.d.ts +37 -0
  10. package/dist/adapters/hermes/HermesAdapter.d.ts.map +1 -0
  11. package/dist/adapters/hermes/HermesAdapter.js +342 -0
  12. package/dist/adapters/hermes/HermesAdapter.js.map +1 -0
  13. package/dist/adapters/openclaw/OpenClawAdapter.d.ts +77 -0
  14. package/dist/adapters/openclaw/OpenClawAdapter.d.ts.map +1 -0
  15. package/dist/adapters/openclaw/OpenClawAdapter.js +798 -0
  16. package/dist/adapters/openclaw/OpenClawAdapter.js.map +1 -0
  17. package/dist/adapters/openclaw/unwrapOpenClawPayloads.d.ts +6 -0
  18. package/dist/adapters/openclaw/unwrapOpenClawPayloads.d.ts.map +1 -0
  19. package/dist/adapters/openclaw/unwrapOpenClawPayloads.js +24 -0
  20. package/dist/adapters/openclaw/unwrapOpenClawPayloads.js.map +1 -0
  21. package/dist/core/AdapterRegistry.d.ts +21 -0
  22. package/dist/core/AdapterRegistry.d.ts.map +1 -0
  23. package/dist/core/AdapterRegistry.js +37 -0
  24. package/dist/core/AdapterRegistry.js.map +1 -0
  25. package/dist/core/AgentAdapter.d.ts +165 -0
  26. package/dist/core/AgentAdapter.d.ts.map +1 -0
  27. package/dist/core/AgentAdapter.js +23 -0
  28. package/dist/core/AgentAdapter.js.map +1 -0
  29. package/dist/core/DaemonClient.d.ts +102 -0
  30. package/dist/core/DaemonClient.d.ts.map +1 -0
  31. package/dist/core/DaemonClient.js +225 -0
  32. package/dist/core/DaemonClient.js.map +1 -0
  33. package/dist/core/Protocol.d.ts +257 -0
  34. package/dist/core/Protocol.d.ts.map +1 -0
  35. package/dist/core/Protocol.js +140 -0
  36. package/dist/core/Protocol.js.map +1 -0
  37. package/dist/core/RuntimeDetector.d.ts +7 -0
  38. package/dist/core/RuntimeDetector.d.ts.map +1 -0
  39. package/dist/core/RuntimeDetector.js +45 -0
  40. package/dist/core/RuntimeDetector.js.map +1 -0
  41. package/dist/core/WinMatrixAgentClient.d.ts +134 -0
  42. package/dist/core/WinMatrixAgentClient.d.ts.map +1 -0
  43. package/dist/core/WinMatrixAgentClient.js +382 -0
  44. package/dist/core/WinMatrixAgentClient.js.map +1 -0
  45. package/dist/index.d.ts +36 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +33 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/runtime/DualRuntimeBridge.d.ts +38 -0
  50. package/dist/runtime/DualRuntimeBridge.d.ts.map +1 -0
  51. package/dist/runtime/DualRuntimeBridge.js +305 -0
  52. package/dist/runtime/DualRuntimeBridge.js.map +1 -0
  53. package/dist/runtime/bridgeConfigLoader.d.ts +14 -0
  54. package/dist/runtime/bridgeConfigLoader.d.ts.map +1 -0
  55. package/dist/runtime/bridgeConfigLoader.js +133 -0
  56. package/dist/runtime/bridgeConfigLoader.js.map +1 -0
  57. package/dist/runtime/bridgeConfigTypes.d.ts +26 -0
  58. package/dist/runtime/bridgeConfigTypes.d.ts.map +1 -0
  59. package/dist/runtime/bridgeConfigTypes.js +6 -0
  60. package/dist/runtime/bridgeConfigTypes.js.map +1 -0
  61. package/dist/runtime/bridgeHome.d.ts +19 -0
  62. package/dist/runtime/bridgeHome.d.ts.map +1 -0
  63. package/dist/runtime/bridgeHome.js +61 -0
  64. package/dist/runtime/bridgeHome.js.map +1 -0
  65. package/dist/runtime/bridgeReconnectPolicy.d.ts +8 -0
  66. package/dist/runtime/bridgeReconnectPolicy.d.ts.map +1 -0
  67. package/dist/runtime/bridgeReconnectPolicy.js +16 -0
  68. package/dist/runtime/bridgeReconnectPolicy.js.map +1 -0
  69. package/dist/runtime/bridgeTaskJournal.d.ts +7 -0
  70. package/dist/runtime/bridgeTaskJournal.d.ts.map +1 -0
  71. package/dist/runtime/bridgeTaskJournal.js +66 -0
  72. package/dist/runtime/bridgeTaskJournal.js.map +1 -0
  73. package/dist/runtime/localRuntimeAvailabilityMonitor.d.ts +22 -0
  74. package/dist/runtime/localRuntimeAvailabilityMonitor.d.ts.map +1 -0
  75. package/dist/runtime/localRuntimeAvailabilityMonitor.js +81 -0
  76. package/dist/runtime/localRuntimeAvailabilityMonitor.js.map +1 -0
  77. package/dist/runtime/runDualRuntimeBridge.d.ts +2 -0
  78. package/dist/runtime/runDualRuntimeBridge.d.ts.map +1 -0
  79. package/dist/runtime/runDualRuntimeBridge.js +32 -0
  80. package/dist/runtime/runDualRuntimeBridge.js.map +1 -0
  81. package/dist/utils/parseSkillMd.d.ts +10 -0
  82. package/dist/utils/parseSkillMd.d.ts.map +1 -0
  83. package/dist/utils/parseSkillMd.js +34 -0
  84. package/dist/utils/parseSkillMd.js.map +1 -0
  85. package/dist/utils/processUtils.d.ts +8 -0
  86. package/dist/utils/processUtils.d.ts.map +1 -0
  87. package/dist/utils/processUtils.js +31 -0
  88. package/dist/utils/processUtils.js.map +1 -0
  89. package/dist/utils/spawnHelper.d.ts +38 -0
  90. package/dist/utils/spawnHelper.d.ts.map +1 -0
  91. package/dist/utils/spawnHelper.js +122 -0
  92. package/dist/utils/spawnHelper.js.map +1 -0
  93. package/package.json +61 -0
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Dual Runtime Bridge 用户目录布局(类似 Hermes:固定用户目录下的状态与配置)。
3
+ *
4
+ * 默认:`~/.winmatrix-bridge/`
5
+ * 覆盖:`WINMATRIX_BRIDGE_HOME`(绝对路径或相对于 cwd)
6
+ */
7
+ import { mkdirSync, existsSync, readdirSync } from 'node:fs';
8
+ import { homedir } from 'node:os';
9
+ import path from 'node:path';
10
+ export const DEFAULT_BRIDGE_DIR_NAME = '.winmatrix-bridge';
11
+ /** 与 {@link bridgeConfigLoader.DEFAULT_BRIDGE_CONFIG_BASENAME} 一致 */
12
+ export const BRIDGE_CONFIG_FILENAME = 'bridge.config.json';
13
+ /** 日志目录(相对 bridge home) */
14
+ export const REL_LOG_DIR = 'logs';
15
+ /** 进行中任务快照(崩溃后可对照 recovery) */
16
+ export const REL_TASKS_PENDING = path.join('tasks', 'pending');
17
+ /** 已完成任务追加日志(JSON Lines) */
18
+ export const REL_TASKS_RECOVERY = path.join('tasks', 'recovery');
19
+ export function getBridgeHomeDir() {
20
+ const override = process.env.WINMATRIX_BRIDGE_HOME?.trim();
21
+ if (override) {
22
+ return path.isAbsolute(override) ? override : path.join(process.cwd(), override);
23
+ }
24
+ return path.join(homedir(), DEFAULT_BRIDGE_DIR_NAME);
25
+ }
26
+ export function getBridgeConfigPath() {
27
+ return path.join(getBridgeHomeDir(), BRIDGE_CONFIG_FILENAME);
28
+ }
29
+ /** 创建 ~/.winmatrix-bridge/{logs,tasks/pending,tasks/recovery}(幂等) */
30
+ export function ensureBridgeHomeLayout() {
31
+ const root = getBridgeHomeDir();
32
+ const dirs = [
33
+ root,
34
+ path.join(root, REL_LOG_DIR),
35
+ path.join(root, REL_TASKS_PENDING),
36
+ path.join(root, REL_TASKS_RECOVERY),
37
+ ];
38
+ for (const d of dirs) {
39
+ mkdirSync(d, { recursive: true });
40
+ }
41
+ return root;
42
+ }
43
+ /**
44
+ * 若上次异常退出后 `tasks/pending` 仍有快照,启动时打印一行提示(仅人工对照,不触发服务端重派)。
45
+ * 详见 README「tasks/pending 与 tasks/recovery 的语义」。
46
+ */
47
+ export function logPendingTasksRecoveryHint() {
48
+ const dir = path.join(getBridgeHomeDir(), REL_TASKS_PENDING);
49
+ if (!existsSync(dir))
50
+ return;
51
+ try {
52
+ const n = readdirSync(dir).filter((f) => f.endsWith('.json')).length;
53
+ if (n > 0) {
54
+ console.log(`[bridge] recovery hint: ${n} pending task record(s) under ${dir}`);
55
+ }
56
+ }
57
+ catch {
58
+ /* ignore */
59
+ }
60
+ }
61
+ //# sourceMappingURL=bridgeHome.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridgeHome.js","sourceRoot":"","sources":["../../src/runtime/bridgeHome.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,CAAC,MAAM,uBAAuB,GAAG,mBAAmB,CAAC;AAE3D,qEAAqE;AACrE,MAAM,CAAC,MAAM,sBAAsB,GAAG,oBAAoB,CAAC;AAE3D,2BAA2B;AAC3B,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC;AAElC,+BAA+B;AAC/B,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;AAE/D,4BAA4B;AAC5B,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;AAEjE,MAAM,UAAU,gBAAgB;IAC9B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,IAAI,EAAE,CAAC;IAC3D,IAAI,QAAQ,EAAE,CAAC;QACb,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;IACnF,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,uBAAuB,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,OAAO,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,sBAAsB,CAAC,CAAC;AAC/D,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,sBAAsB;IACpC,MAAM,IAAI,GAAG,gBAAgB,EAAE,CAAC;IAChC,MAAM,IAAI,GAAG;QACX,IAAI;QACJ,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC;QAC5B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,CAAC;QAClC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,kBAAkB,CAAC;KACpC,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,SAAS,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,2BAA2B;IACzC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,iBAAiB,CAAC,CAAC;IAC7D,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO;IAC7B,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;QACrE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACV,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,iCAAiC,GAAG,EAAE,CAAC,CAAC;QAClF,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,YAAY;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Decide whether bridge should keep retrying after a WinMatrixAgentClient connect error.
3
+ *
4
+ * Credential / registration mismatches won't fix themselves by reconnecting alone.
5
+ */
6
+ export declare function isNonRecoverableExternalAgentAuthError(err: unknown): boolean;
7
+ export declare function nextReconnectDelayMs(current: number): number;
8
+ //# sourceMappingURL=bridgeReconnectPolicy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridgeReconnectPolicy.d.ts","sourceRoot":"","sources":["../../src/runtime/bridgeReconnectPolicy.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,wBAAgB,sCAAsC,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAI5E;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE5D"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Decide whether bridge should keep retrying after a WinMatrixAgentClient connect error.
3
+ *
4
+ * Credential / registration mismatches won't fix themselves by reconnecting alone.
5
+ */
6
+ const MAX_BACKOFF_MS = 60_000;
7
+ export function isNonRecoverableExternalAgentAuthError(err) {
8
+ const msg = err instanceof Error ? err.message : String(err);
9
+ if (/invalid_credentials/i.test(msg))
10
+ return true;
11
+ return /Registration failed:/i.test(msg) && /invalid_credentials/i.test(msg);
12
+ }
13
+ export function nextReconnectDelayMs(current) {
14
+ return Math.min(current * 2, MAX_BACKOFF_MS);
15
+ }
16
+ //# sourceMappingURL=bridgeReconnectPolicy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridgeReconnectPolicy.js","sourceRoot":"","sources":["../../src/runtime/bridgeReconnectPolicy.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,cAAc,GAAG,MAAM,CAAC;AAE9B,MAAM,UAAU,sCAAsC,CAAC,GAAY;IACjE,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC7D,IAAI,sBAAsB,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAClD,OAAO,uBAAuB,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,sBAAsB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/E,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,OAAe;IAClD,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,EAAE,cAAc,CAAC,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { TaskInput } from '../core/WinMatrixAgentClient.js';
2
+ export type BridgeRuntimeKindJournal = 'hermes' | 'openclaw';
3
+ /** task.assign 收到后写入 pending(供崩溃对照;不负责服务端重派语义) */
4
+ export declare function recordTaskStarted(runtime: BridgeRuntimeKindJournal, task: TaskInput): void;
5
+ /** complete / fail 后删除 pending,并追加一行 recovery */
6
+ export declare function recordTaskFinished(runtime: BridgeRuntimeKindJournal, taskId: string, outcome: 'complete' | 'fail'): void;
7
+ //# sourceMappingURL=bridgeTaskJournal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridgeTaskJournal.d.ts","sourceRoot":"","sources":["../../src/runtime/bridgeTaskJournal.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAGjE,MAAM,MAAM,wBAAwB,GAAG,QAAQ,GAAG,UAAU,CAAC;AAmB7D,kDAAkD;AAClD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI,CAe1F;AAED,iDAAiD;AACjD,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,wBAAwB,EACjC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,UAAU,GAAG,MAAM,GAC3B,IAAI,CAuBN"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * 本地任务快照:进行中写入 tasks/pending,结束后移至 recovery(JSON Lines)。
3
+ */
4
+ import { appendFileSync, existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs';
5
+ import path from 'node:path';
6
+ import { ensureBridgeHomeLayout, getBridgeHomeDir, REL_TASKS_PENDING, REL_TASKS_RECOVERY } from './bridgeHome.js';
7
+ function sanitizeTaskId(taskId) {
8
+ const safe = taskId.replace(/[^a-zA-Z0-9._-]/g, '_');
9
+ return safe.slice(0, 180) || 'unknown';
10
+ }
11
+ function pendingFile(taskId) {
12
+ ensureBridgeHomeLayout();
13
+ return path.join(getBridgeHomeDir(), REL_TASKS_PENDING, `${sanitizeTaskId(taskId)}.json`);
14
+ }
15
+ function recoveryLogFile() {
16
+ ensureBridgeHomeLayout();
17
+ const dir = path.join(getBridgeHomeDir(), REL_TASKS_RECOVERY);
18
+ mkdirSync(dir, { recursive: true });
19
+ return path.join(dir, 'completed.jsonl');
20
+ }
21
+ /** task.assign 收到后写入 pending(供崩溃对照;不负责服务端重派语义) */
22
+ export function recordTaskStarted(runtime, task) {
23
+ try {
24
+ ensureBridgeHomeLayout();
25
+ const payload = {
26
+ taskId: task.taskId,
27
+ runtime,
28
+ receivedAt: Date.now(),
29
+ inputPreview: task.input.slice(0, 4000),
30
+ ...(task.context?.projectId ? { projectId: task.context.projectId } : {}),
31
+ };
32
+ writeFileSync(pendingFile(task.taskId), `${JSON.stringify(payload, null, 2)}\n`, 'utf8');
33
+ }
34
+ catch (err) {
35
+ const msg = err instanceof Error ? err.message : String(err);
36
+ console.warn(`[bridge] task journal pending write failed: ${msg}`);
37
+ }
38
+ }
39
+ /** complete / fail 后删除 pending,并追加一行 recovery */
40
+ export function recordTaskFinished(runtime, taskId, outcome) {
41
+ try {
42
+ ensureBridgeHomeLayout();
43
+ const pf = pendingFile(taskId);
44
+ let snapshot = { taskId, runtime };
45
+ if (existsSync(pf)) {
46
+ try {
47
+ snapshot = JSON.parse(readFileSync(pf, 'utf8'));
48
+ }
49
+ catch {
50
+ /* ignore parse */
51
+ }
52
+ unlinkSync(pf);
53
+ }
54
+ const line = {
55
+ ...snapshot,
56
+ outcome,
57
+ finishedAt: Date.now(),
58
+ };
59
+ appendFileSync(recoveryLogFile(), `${JSON.stringify(line)}\n`, 'utf8');
60
+ }
61
+ catch (err) {
62
+ const msg = err instanceof Error ? err.message : String(err);
63
+ console.warn(`[bridge] task journal finish failed: ${msg}`);
64
+ }
65
+ }
66
+ //# sourceMappingURL=bridgeTaskJournal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridgeTaskJournal.js","sourceRoot":"","sources":["../../src/runtime/bridgeTaskJournal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Probe local Hermes/OpenClaw HTTP endpoints and notify WinMatrix via runtime.availability events.
3
+ */
4
+ import type { WinMatrixAgentClient } from '../core/WinMatrixAgentClient.js';
5
+ export type LocalRuntimeKindBridge = 'hermes' | 'openclaw';
6
+ /**
7
+ * Lightweight reachability probe: HEAD the base URL — process down ⇒ fetch throws before status.
8
+ */
9
+ export declare function probeLocalHttpEndpoint(endpointUrl: string): Promise<{
10
+ reachable: boolean;
11
+ error?: string;
12
+ }>;
13
+ export declare function startLocalRuntimeAvailabilityMonitor(options: {
14
+ client: WinMatrixAgentClient;
15
+ runtimeKind: LocalRuntimeKindBridge;
16
+ mode: 'endpoint' | 'command';
17
+ /** Required when mode is endpoint */
18
+ endpointUrl?: string;
19
+ probeIntervalMs?: number;
20
+ isStopped: () => boolean;
21
+ }): () => void;
22
+ //# sourceMappingURL=localRuntimeAvailabilityMonitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localRuntimeAvailabilityMonitor.d.ts","sourceRoot":"","sources":["../../src/runtime/localRuntimeAvailabilityMonitor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AAG5E,MAAM,MAAM,sBAAsB,GAAG,QAAQ,GAAG,UAAU,CAAC;AAK3D;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAYjH;AAED,wBAAgB,oCAAoC,CAAC,OAAO,EAAE;IAC5D,MAAM,EAAE,oBAAoB,CAAC;IAC7B,WAAW,EAAE,sBAAsB,CAAC;IACpC,IAAI,EAAE,UAAU,GAAG,SAAS,CAAC;IAC7B,qCAAqC;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,OAAO,CAAC;CAC1B,GAAG,MAAM,IAAI,CA4Db"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Probe local Hermes/OpenClaw HTTP endpoints and notify WinMatrix via runtime.availability events.
3
+ */
4
+ const DEFAULT_PROBE_INTERVAL_MS = 15_000;
5
+ const FETCH_TIMEOUT_MS = 10_000;
6
+ /**
7
+ * Lightweight reachability probe: HEAD the base URL — process down ⇒ fetch throws before status.
8
+ */
9
+ export async function probeLocalHttpEndpoint(endpointUrl) {
10
+ const ctl = new AbortController();
11
+ const tid = setTimeout(() => ctl.abort(), FETCH_TIMEOUT_MS);
12
+ try {
13
+ await fetch(endpointUrl, { method: 'HEAD', signal: ctl.signal, redirect: 'manual' });
14
+ return { reachable: true };
15
+ }
16
+ catch (err) {
17
+ const error = err instanceof Error ? err.message : String(err);
18
+ return { reachable: false, error };
19
+ }
20
+ finally {
21
+ clearTimeout(tid);
22
+ }
23
+ }
24
+ export function startLocalRuntimeAvailabilityMonitor(options) {
25
+ const intervalMs = options.probeIntervalMs ?? DEFAULT_PROBE_INTERVAL_MS;
26
+ /** null = never emitted yet */
27
+ let lastReachableEmitted = null;
28
+ const notify = (payload) => {
29
+ if (options.isStopped())
30
+ return;
31
+ options.client.notifyRuntimeAvailability(payload);
32
+ };
33
+ const tick = async () => {
34
+ if (options.isStopped())
35
+ return;
36
+ if (options.mode === 'command') {
37
+ const reachable = true;
38
+ if (lastReachableEmitted === reachable)
39
+ return;
40
+ lastReachableEmitted = reachable;
41
+ notify({
42
+ runtimeKind: options.runtimeKind,
43
+ reachable,
44
+ mode: 'command',
45
+ checkedAtIso: new Date().toISOString(),
46
+ });
47
+ return;
48
+ }
49
+ const url = options.endpointUrl?.trim();
50
+ if (!url) {
51
+ if (lastReachableEmitted === false)
52
+ return;
53
+ lastReachableEmitted = false;
54
+ notify({
55
+ runtimeKind: options.runtimeKind,
56
+ reachable: false,
57
+ mode: 'endpoint',
58
+ checkedAtIso: new Date().toISOString(),
59
+ error: 'missing_endpoint',
60
+ });
61
+ return;
62
+ }
63
+ const { reachable, error } = await probeLocalHttpEndpoint(url);
64
+ if (lastReachableEmitted === reachable)
65
+ return;
66
+ lastReachableEmitted = reachable;
67
+ notify({
68
+ runtimeKind: options.runtimeKind,
69
+ reachable,
70
+ mode: 'endpoint',
71
+ checkedAtIso: new Date().toISOString(),
72
+ ...(error !== undefined ? { error } : {}),
73
+ });
74
+ };
75
+ void tick();
76
+ const timer = setInterval(() => void tick(), intervalMs);
77
+ return () => {
78
+ clearInterval(timer);
79
+ };
80
+ }
81
+ //# sourceMappingURL=localRuntimeAvailabilityMonitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"localRuntimeAvailabilityMonitor.js","sourceRoot":"","sources":["../../src/runtime/localRuntimeAvailabilityMonitor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=runDualRuntimeBridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runDualRuntimeBridge.d.ts","sourceRoot":"","sources":["../../src/runtime/runDualRuntimeBridge.ts"],"names":[],"mappings":""}
@@ -0,0 +1,32 @@
1
+ import { loadBridgeConfig } from './bridgeConfigLoader.js';
2
+ import { startDualRuntimeBridge } from './DualRuntimeBridge.js';
3
+ async function main() {
4
+ const config = loadBridgeConfig();
5
+ const bridge = await startDualRuntimeBridge(config);
6
+ console.log('[bridge] started. Press Ctrl+C to stop.');
7
+ const shutdown = () => {
8
+ console.log('[bridge] shutting down...');
9
+ bridge.stop();
10
+ process.exit(0);
11
+ };
12
+ process.on('SIGINT', shutdown);
13
+ process.on('SIGTERM', shutdown);
14
+ }
15
+ main().catch((err) => {
16
+ if (err instanceof Error) {
17
+ const msg = err.message?.trim()
18
+ ? err.message
19
+ : [err.name, err.code && `code=${err.code}`]
20
+ .filter(Boolean)
21
+ .join(' ')
22
+ || '(empty error message; see stack below)';
23
+ console.error(`[bridge] failed: ${msg}`);
24
+ if (err.stack)
25
+ console.error(err.stack);
26
+ }
27
+ else {
28
+ console.error('[bridge] failed:', err);
29
+ }
30
+ process.exit(1);
31
+ });
32
+ //# sourceMappingURL=runDualRuntimeBridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runDualRuntimeBridge.js","sourceRoot":"","sources":["../../src/runtime/runDualRuntimeBridge.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,gBAAgB,EAAE,CAAC;IAClC,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC,MAAM,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;IAEvD,MAAM,QAAQ,GAAG,GAAG,EAAE;QACpB,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;QACzC,MAAM,CAAC,IAAI,EAAE,CAAC;QACd,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE;YAC7B,CAAC,CAAC,GAAG,CAAC,OAAO;YACb,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAG,GAA6B,CAAC,IAAI,IAAI,QAAS,GAA6B,CAAC,IAAI,EAAE,CAAC;iBAC7F,MAAM,CAAC,OAAO,CAAC;iBACf,IAAI,CAAC,GAAG,CAAC;mBACX,wCAAwC,CAAC;QAC9C,OAAO,CAAC,KAAK,CAAC,oBAAoB,GAAG,EAAE,CAAC,CAAC;QACzC,IAAI,GAAG,CAAC,KAAK;YAAE,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC1C,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * 解析 SKILL.md 的 YAML frontmatter,提取 name/description/category。
3
+ * 返回 null 表示文件不存在、无 frontmatter 或 name 为空。
4
+ */
5
+ export declare function parseSkillMd(filePath: string): {
6
+ name: string;
7
+ description?: string;
8
+ category?: string;
9
+ } | null;
10
+ //# sourceMappingURL=parseSkillMd.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parseSkillMd.d.ts","sourceRoot":"","sources":["../../src/utils/parseSkillMd.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAqB/G"}
@@ -0,0 +1,34 @@
1
+ import { readFileSync } from 'node:fs';
2
+ /**
3
+ * 解析 SKILL.md 的 YAML frontmatter,提取 name/description/category。
4
+ * 返回 null 表示文件不存在、无 frontmatter 或 name 为空。
5
+ */
6
+ export function parseSkillMd(filePath) {
7
+ try {
8
+ const content = readFileSync(filePath, 'utf-8');
9
+ // 要求结尾 --- 独占一行(仅允许行尾空白),避免匹配 YAML 多行字符串内的 ---
10
+ const match = content.match(/^---[\t ]*\n([\s\S]*?)\n---[\t ]*(?:\n|$)/);
11
+ if (!match)
12
+ return null;
13
+ const fm = match[1];
14
+ const result = { name: '' };
15
+ for (const line of fm.split('\n')) {
16
+ const kv = line.match(/^(\w[\w\s]*?)\s*:\s*(.*)$/);
17
+ if (!kv)
18
+ continue;
19
+ const key = kv[1].trim().toLowerCase();
20
+ const value = kv[2].trim().replace(/^['"](.*)['"]$/, '$1');
21
+ if (key === 'name')
22
+ result.name = value;
23
+ else if (key === 'description')
24
+ result.description = value;
25
+ else if (key === 'category')
26
+ result.category = value;
27
+ }
28
+ return result.name ? result : null;
29
+ }
30
+ catch {
31
+ return null;
32
+ }
33
+ }
34
+ //# sourceMappingURL=parseSkillMd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parseSkillMd.js","sourceRoot":"","sources":["../../src/utils/parseSkillMd.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB;IAC3C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAChD,+CAA+C;QAC/C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;QACzE,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAC;QACxB,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACpB,MAAM,MAAM,GAA8D,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;QACvF,KAAK,MAAM,IAAI,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;YACnD,IAAI,CAAC,EAAE;gBAAE,SAAS;YAClB,MAAM,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;YACvC,MAAM,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;YAC3D,IAAI,GAAG,KAAK,MAAM;gBAAE,MAAM,CAAC,IAAI,GAAG,KAAK,CAAC;iBACnC,IAAI,GAAG,KAAK,aAAa;gBAAE,MAAM,CAAC,WAAW,GAAG,KAAK,CAAC;iBACtD,IAAI,GAAG,KAAK,UAAU;gBAAE,MAAM,CAAC,QAAQ,GAAG,KAAK,CAAC;QACvD,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { type ChildProcess } from 'node:child_process';
2
+ export declare const CANCEL_GRACE_MS = 10000;
3
+ export declare function waitForExit(proc: ChildProcess): Promise<{
4
+ code: number | null;
5
+ error?: string;
6
+ }>;
7
+ export declare function killProcess(proc: ChildProcess): void;
8
+ //# sourceMappingURL=processUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processUtils.d.ts","sourceRoot":"","sources":["../../src/utils/processUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,eAAO,MAAM,eAAe,QAAS,CAAC;AAEtC,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAYhG;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI,CAYpD"}
@@ -0,0 +1,31 @@
1
+ export const CANCEL_GRACE_MS = 10_000;
2
+ export function waitForExit(proc) {
3
+ return new Promise((resolve) => {
4
+ proc.once('exit', (code, sig) => {
5
+ resolve({
6
+ code,
7
+ error: sig ? `Process killed by signal ${sig}` : undefined,
8
+ });
9
+ });
10
+ proc.once('error', (err) => {
11
+ resolve({ code: null, error: err.message });
12
+ });
13
+ });
14
+ }
15
+ export function killProcess(proc) {
16
+ if (proc.exitCode !== null || proc.signalCode !== null)
17
+ return;
18
+ try {
19
+ proc.kill('SIGTERM');
20
+ setTimeout(() => {
21
+ try {
22
+ if (proc.exitCode === null && proc.signalCode === null) {
23
+ proc.kill('SIGKILL');
24
+ }
25
+ }
26
+ catch { /* already dead */ }
27
+ }, CANCEL_GRACE_MS);
28
+ }
29
+ catch { /* already dead */ }
30
+ }
31
+ //# sourceMappingURL=processUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"processUtils.js","sourceRoot":"","sources":["../../src/utils/processUtils.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC;AAEtC,MAAM,UAAU,WAAW,CAAC,IAAkB;IAC5C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YAC9B,OAAO,CAAC;gBACN,IAAI;gBACJ,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC,4BAA4B,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS;aAC3D,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;YACzB,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAAkB;IAC5C,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI;QAAE,OAAO;IAC/D,IAAI,CAAC;QACH,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACrB,UAAU,CAAC,GAAG,EAAE;YACd,IAAI,CAAC;gBACH,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,IAAI,IAAI,CAAC,UAAU,KAAK,IAAI,EAAE,CAAC;oBACvD,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACvB,CAAC;YACH,CAAC;YAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;QAChC,CAAC,EAAE,eAAe,CAAC,CAAC;IACtB,CAAC;IAAC,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * 统一子进程 spawn 封装
3
+ *
4
+ * 供 ClaudeAdapter 和 HermesAdapter 共用。
5
+ * 提供超时、取消、stderr 转发、环境变量注入。
6
+ */
7
+ import { type ChildProcess } from 'node:child_process';
8
+ export interface SpawnHelperOptions {
9
+ /** 命令 */
10
+ command: string;
11
+ /** 参数 */
12
+ args: string[];
13
+ /** 工作目录 */
14
+ cwd?: string;
15
+ /** 环境变量(合并到 process.env) */
16
+ env?: NodeJS.ProcessEnv;
17
+ /** 超时时间 (ms),超时后 SIGTERM → SIGKILL */
18
+ timeoutMs?: number;
19
+ /** AbortSignal 用于外部取消 */
20
+ signal?: AbortSignal;
21
+ /** 可选:将 stderr 内容转发到此回调 */
22
+ onStderr?: (text: string) => void;
23
+ }
24
+ export interface SpawnResult {
25
+ proc: ChildProcess;
26
+ /** stdout 异步迭代器 */
27
+ stdout: AsyncIterable<string>;
28
+ /** 等待进程退出 */
29
+ waitForExit: () => Promise<{
30
+ code: number | null;
31
+ error?: string;
32
+ }>;
33
+ }
34
+ /**
35
+ * 启动子进程并返回统一的流式接口
36
+ */
37
+ export declare function spawnHelper(options: SpawnHelperOptions): SpawnResult;
38
+ //# sourceMappingURL=spawnHelper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawnHelper.d.ts","sourceRoot":"","sources":["../../src/utils/spawnHelper.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAS,KAAK,YAAY,EAAqB,MAAM,oBAAoB,CAAC;AAEjF,MAAM,WAAW,kBAAkB;IACjC,SAAS;IACT,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS;IACT,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,WAAW;IACX,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,sCAAsC;IACtC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,YAAY,CAAC;IACnB,mBAAmB;IACnB,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC9B,aAAa;IACb,WAAW,EAAE,MAAM,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrE;AAID;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,WAAW,CAqGpE"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * 统一子进程 spawn 封装
3
+ *
4
+ * 供 ClaudeAdapter 和 HermesAdapter 共用。
5
+ * 提供超时、取消、stderr 转发、环境变量注入。
6
+ */
7
+ import { spawn } from 'node:child_process';
8
+ const CANCEL_GRACE_MS = 10_000;
9
+ /**
10
+ * 启动子进程并返回统一的流式接口
11
+ */
12
+ export function spawnHelper(options) {
13
+ const spawnOpts = {
14
+ stdio: ['pipe', 'pipe', 'pipe'],
15
+ cwd: options.cwd ?? process.cwd(),
16
+ env: { ...process.env, ...(options.env ?? {}) },
17
+ };
18
+ const proc = spawn(options.command, options.args, spawnOpts);
19
+ // Timeout
20
+ let timeoutTimer;
21
+ if (options.timeoutMs && options.timeoutMs > 0) {
22
+ timeoutTimer = setTimeout(() => {
23
+ killProcess(proc);
24
+ }, options.timeoutMs);
25
+ }
26
+ // Abort signal
27
+ const onAbort = () => killProcess(proc);
28
+ options.signal?.addEventListener('abort', onAbort, { once: true });
29
+ // stderr forwarding
30
+ if (options.onStderr) {
31
+ proc.stderr?.on('data', (chunk) => {
32
+ options.onStderr?.(chunk.toString('utf-8'));
33
+ });
34
+ }
35
+ // stdout async iterator
36
+ const stdoutIterable = {
37
+ [Symbol.asyncIterator]() {
38
+ const buffer = [];
39
+ let resolveNext = null;
40
+ let done = false;
41
+ const onData = (chunk) => {
42
+ const text = chunk.toString('utf-8');
43
+ if (resolveNext) {
44
+ resolveNext({ value: text, done: false });
45
+ resolveNext = null;
46
+ }
47
+ else {
48
+ buffer.push(text);
49
+ }
50
+ };
51
+ const onEnd = () => {
52
+ done = true;
53
+ if (resolveNext) {
54
+ resolveNext({ value: undefined, done: true });
55
+ resolveNext = null;
56
+ }
57
+ };
58
+ proc.stdout?.on('data', onData);
59
+ proc.once('exit', onEnd);
60
+ proc.stdout?.once('end', onEnd);
61
+ return {
62
+ async next() {
63
+ if (done && buffer.length === 0) {
64
+ return { value: undefined, done: true };
65
+ }
66
+ if (buffer.length > 0) {
67
+ return { value: buffer.shift(), done: false };
68
+ }
69
+ return new Promise((resolve) => {
70
+ resolveNext = resolve;
71
+ });
72
+ },
73
+ async return() {
74
+ proc.stdout?.removeListener('data', onData);
75
+ done = true;
76
+ if (resolveNext) {
77
+ resolveNext({ value: undefined, done: true });
78
+ resolveNext = null;
79
+ }
80
+ return { value: undefined, done: true };
81
+ },
82
+ };
83
+ },
84
+ };
85
+ const waitForExit = () => {
86
+ return new Promise((resolve) => {
87
+ proc.once('exit', (code, sig) => {
88
+ if (timeoutTimer)
89
+ clearTimeout(timeoutTimer);
90
+ options.signal?.removeEventListener('abort', onAbort);
91
+ resolve({
92
+ code,
93
+ error: sig ? `${options.command} killed by signal ${sig}` : undefined,
94
+ });
95
+ });
96
+ proc.once('error', (err) => {
97
+ if (timeoutTimer)
98
+ clearTimeout(timeoutTimer);
99
+ options.signal?.removeEventListener('abort', onAbort);
100
+ resolve({ code: null, error: err.message });
101
+ });
102
+ });
103
+ };
104
+ return { proc, stdout: stdoutIterable, waitForExit };
105
+ }
106
+ function killProcess(proc) {
107
+ if (proc.exitCode !== null || proc.signalCode !== null)
108
+ return;
109
+ try {
110
+ proc.kill('SIGTERM');
111
+ setTimeout(() => {
112
+ try {
113
+ if (proc.exitCode === null && proc.signalCode === null) {
114
+ proc.kill('SIGKILL');
115
+ }
116
+ }
117
+ catch { /* already dead */ }
118
+ }, CANCEL_GRACE_MS);
119
+ }
120
+ catch { /* already dead */ }
121
+ }
122
+ //# sourceMappingURL=spawnHelper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spawnHelper.js","sourceRoot":"","sources":["../../src/utils/spawnHelper.ts"],"names":[],"mappings":"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"}