@te-river/opencode-team-mode 1.5.4 → 1.5.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.
Files changed (158) hide show
  1. package/README.md +732 -634
  2. package/README.zh-CN.md +655 -576
  3. package/dist/agents.d.ts +6 -1
  4. package/dist/agents.d.ts.map +1 -1
  5. package/dist/agents.js +103 -522
  6. package/dist/agents.js.map +1 -1
  7. package/dist/approval-gate.d.ts +16 -0
  8. package/dist/approval-gate.d.ts.map +1 -1
  9. package/dist/approval-gate.js +8 -1
  10. package/dist/approval-gate.js.map +1 -1
  11. package/dist/blackboard.d.ts.map +1 -1
  12. package/dist/blackboard.js +3 -2
  13. package/dist/blackboard.js.map +1 -1
  14. package/dist/commands.d.ts.map +1 -1
  15. package/dist/commands.js +7 -6
  16. package/dist/commands.js.map +1 -1
  17. package/dist/envprotect/bash-classify.d.ts +42 -0
  18. package/dist/envprotect/bash-classify.d.ts.map +1 -0
  19. package/dist/envprotect/bash-classify.js +221 -0
  20. package/dist/envprotect/bash-classify.js.map +1 -0
  21. package/dist/envprotect/gate-predicates.d.ts +57 -0
  22. package/dist/envprotect/gate-predicates.d.ts.map +1 -0
  23. package/dist/envprotect/gate-predicates.js +174 -0
  24. package/dist/envprotect/gate-predicates.js.map +1 -0
  25. package/dist/envprotect/hook.d.ts +45 -0
  26. package/dist/envprotect/hook.d.ts.map +1 -0
  27. package/dist/envprotect/hook.js +158 -0
  28. package/dist/envprotect/hook.js.map +1 -0
  29. package/dist/envprotect/path-classify.d.ts +16 -0
  30. package/dist/envprotect/path-classify.d.ts.map +1 -0
  31. package/dist/envprotect/path-classify.js +72 -0
  32. package/dist/envprotect/path-classify.js.map +1 -0
  33. package/dist/envprotect/patterns.d.ts +77 -0
  34. package/dist/envprotect/patterns.d.ts.map +1 -0
  35. package/dist/envprotect/patterns.js +182 -0
  36. package/dist/envprotect/patterns.js.map +1 -0
  37. package/dist/envprotect.d.ts +19 -217
  38. package/dist/envprotect.d.ts.map +1 -1
  39. package/dist/envprotect.js +18 -803
  40. package/dist/envprotect.js.map +1 -1
  41. package/dist/fs-safe.d.ts +16 -0
  42. package/dist/fs-safe.d.ts.map +1 -0
  43. package/dist/fs-safe.js +56 -0
  44. package/dist/fs-safe.js.map +1 -0
  45. package/dist/index.d.ts.map +1 -1
  46. package/dist/index.js +22 -6
  47. package/dist/index.js.map +1 -1
  48. package/dist/prompts/lead.d.ts +7 -0
  49. package/dist/prompts/lead.d.ts.map +1 -0
  50. package/dist/prompts/lead.js +230 -0
  51. package/dist/prompts/lead.js.map +1 -0
  52. package/dist/prompts/shared.d.ts +8 -0
  53. package/dist/prompts/shared.d.ts.map +1 -0
  54. package/dist/prompts/shared.js +118 -0
  55. package/dist/prompts/shared.js.map +1 -0
  56. package/dist/prompts/specialists.d.ts +12 -0
  57. package/dist/prompts/specialists.d.ts.map +1 -0
  58. package/dist/prompts/specialists.js +218 -0
  59. package/dist/prompts/specialists.js.map +1 -0
  60. package/dist/shell-text.d.ts +14 -0
  61. package/dist/shell-text.d.ts.map +1 -0
  62. package/dist/shell-text.js +16 -0
  63. package/dist/shell-text.js.map +1 -0
  64. package/dist/tm/args-schema.d.ts +36 -0
  65. package/dist/tm/args-schema.d.ts.map +1 -0
  66. package/dist/tm/args-schema.js +191 -0
  67. package/dist/tm/args-schema.js.map +1 -0
  68. package/dist/tm/browser.d.ts +52 -0
  69. package/dist/tm/browser.d.ts.map +1 -0
  70. package/dist/tm/browser.js +361 -0
  71. package/dist/tm/browser.js.map +1 -0
  72. package/dist/tm/client-unwrap.d.ts +38 -0
  73. package/dist/tm/client-unwrap.d.ts.map +1 -0
  74. package/dist/tm/client-unwrap.js +113 -0
  75. package/dist/tm/client-unwrap.js.map +1 -0
  76. package/dist/tm/config.d.ts +46 -18
  77. package/dist/tm/config.d.ts.map +1 -1
  78. package/dist/tm/config.js +60 -17
  79. package/dist/tm/config.js.map +1 -1
  80. package/dist/tm/guard.d.ts.map +1 -1
  81. package/dist/tm/guard.js +4 -7
  82. package/dist/tm/guard.js.map +1 -1
  83. package/dist/tm/index.d.ts +15 -5
  84. package/dist/tm/index.d.ts.map +1 -1
  85. package/dist/tm/index.js +95 -19
  86. package/dist/tm/index.js.map +1 -1
  87. package/dist/tm/memory.d.ts +82 -0
  88. package/dist/tm/memory.d.ts.map +1 -0
  89. package/dist/tm/memory.js +350 -0
  90. package/dist/tm/memory.js.map +1 -0
  91. package/dist/tm/pipelines.d.ts +58 -0
  92. package/dist/tm/pipelines.d.ts.map +1 -0
  93. package/dist/tm/pipelines.js +301 -0
  94. package/dist/tm/pipelines.js.map +1 -0
  95. package/dist/tm/preview.d.ts +6 -1
  96. package/dist/tm/preview.d.ts.map +1 -1
  97. package/dist/tm/preview.js +31 -8
  98. package/dist/tm/preview.js.map +1 -1
  99. package/dist/tm/ptc/budgets.d.ts +38 -0
  100. package/dist/tm/ptc/budgets.d.ts.map +1 -0
  101. package/dist/tm/ptc/budgets.js +59 -0
  102. package/dist/tm/ptc/budgets.js.map +1 -0
  103. package/dist/tm/ptc/contract.d.ts +131 -0
  104. package/dist/tm/ptc/contract.d.ts.map +1 -0
  105. package/dist/tm/ptc/contract.js +47 -0
  106. package/dist/tm/ptc/contract.js.map +1 -0
  107. package/dist/tm/ptc/driver.d.ts +37 -0
  108. package/dist/tm/ptc/driver.d.ts.map +1 -0
  109. package/dist/tm/ptc/driver.js +181 -0
  110. package/dist/tm/ptc/driver.js.map +1 -0
  111. package/dist/tm/ptc/engines.d.ts +32 -0
  112. package/dist/tm/ptc/engines.d.ts.map +1 -0
  113. package/dist/tm/ptc/engines.js +201 -0
  114. package/dist/tm/ptc/engines.js.map +1 -0
  115. package/dist/tm/ptc/gate.d.ts +28 -0
  116. package/dist/tm/ptc/gate.d.ts.map +1 -0
  117. package/dist/tm/ptc/gate.js +127 -0
  118. package/dist/tm/ptc/gate.js.map +1 -0
  119. package/dist/tm/ptc/index.d.ts +19 -0
  120. package/dist/tm/ptc/index.d.ts.map +1 -0
  121. package/dist/tm/ptc/index.js +15 -0
  122. package/dist/tm/ptc/index.js.map +1 -0
  123. package/dist/tm/ptc/pscan.d.ts +11 -0
  124. package/dist/tm/ptc/pscan.d.ts.map +1 -0
  125. package/dist/tm/ptc/pscan.js +27 -0
  126. package/dist/tm/ptc/pscan.js.map +1 -0
  127. package/dist/tm/ptc/summary.d.ts +17 -0
  128. package/dist/tm/ptc/summary.d.ts.map +1 -0
  129. package/dist/tm/ptc/summary.js +107 -0
  130. package/dist/tm/ptc/summary.js.map +1 -0
  131. package/dist/tm/ptc/tool.d.ts +35 -0
  132. package/dist/tm/ptc/tool.d.ts.map +1 -0
  133. package/dist/tm/ptc/tool.js +135 -0
  134. package/dist/tm/ptc/tool.js.map +1 -0
  135. package/dist/tm/ptc.d.ts +45 -26
  136. package/dist/tm/ptc.d.ts.map +1 -1
  137. package/dist/tm/ptc.js +71 -45
  138. package/dist/tm/ptc.js.map +1 -1
  139. package/dist/tm/result.d.ts +34 -0
  140. package/dist/tm/result.d.ts.map +1 -0
  141. package/dist/tm/result.js +87 -0
  142. package/dist/tm/result.js.map +1 -0
  143. package/dist/tm/shell-bridge.d.ts +22 -0
  144. package/dist/tm/shell-bridge.d.ts.map +1 -0
  145. package/dist/tm/shell-bridge.js +70 -0
  146. package/dist/tm/shell-bridge.js.map +1 -0
  147. package/dist/tm/store.d.ts.map +1 -1
  148. package/dist/tm/store.js +2 -1
  149. package/dist/tm/store.js.map +1 -1
  150. package/dist/tm/tools.d.ts +13 -71
  151. package/dist/tm/tools.d.ts.map +1 -1
  152. package/dist/tm/tools.js +23 -656
  153. package/dist/tm/tools.js.map +1 -1
  154. package/dist/tm/webfetch.d.ts +94 -0
  155. package/dist/tm/webfetch.d.ts.map +1 -0
  156. package/dist/tm/webfetch.js +225 -0
  157. package/dist/tm/webfetch.js.map +1 -0
  158. package/package.json +2 -2
@@ -0,0 +1,131 @@
1
+ /**
2
+ * tm_ptc_run — public contract types + the frozen engine seam.
3
+ *
4
+ * Design: .git/opencode-team/.../ptc-run/02-architect-ptc-run-design.md §2/§3.
5
+ * Everything in this module is CONTRACT — frozen since M1 so M2's engines and
6
+ * M3's registration could land without touching the driver or the tool.
7
+ * (Split out of the former monolithic ptc.ts; behavior unchanged.)
8
+ *
9
+ * Governance is REUSED, never forked (D6 lock): the bridge calls the exact
10
+ * four exported pipelines, so threshold offload, P2/P3, R6 and handle/TTL
11
+ * semantics apply to every bridged call verbatim. PTC is NOT a bypass layer.
12
+ */
13
+ import type { TmPhase } from "../result.js";
14
+ /** The five PTC run statuses (design §2). */
15
+ export declare const PTC_STATUS_VALUES: readonly ["ok", "stopped-error-budget", "stopped-call-budget", "timeout", "engine-error"];
16
+ export type PtcStatus = (typeof PTC_STATUS_VALUES)[number];
17
+ export type BridgeTool = "tm_read" | "tm_grep" | "tm_bash" | "tm_fetch";
18
+ /** Bridge allow set — read-only; tm_ptc_run itself is excluded (no nesting). */
19
+ export declare const BRIDGE_ALLOW: readonly BridgeTool[];
20
+ /** Phases safe to retry once (idempotent read-only bridges; design §4.2). */
21
+ export declare const RETRYABLE_PHASES: readonly TmPhase[];
22
+ /** Error body the bridge surfaces (T1.4 shape: tool/phase/message/line?). */
23
+ export interface PtcErrorBody {
24
+ tool: string;
25
+ phase: TmPhase;
26
+ message: string;
27
+ line?: number;
28
+ }
29
+ /** A single bridged-call outcome (design §2 program protocol). */
30
+ export type PtcCallResult = {
31
+ ok: true;
32
+ data: unknown;
33
+ } | {
34
+ ok: false;
35
+ error: PtcErrorBody;
36
+ };
37
+ /** The bridge the engine drives — every call runs the gate-wrapped pipelines. */
38
+ export interface PtcBridge {
39
+ call(tool: BridgeTool, args: Record<string, unknown>): Promise<PtcCallResult>;
40
+ }
41
+ /** Parent → engine: run the program. */
42
+ export interface PtcRunRequest {
43
+ program: string;
44
+ /** monotonic token so a caller can correlate a call with its response. */
45
+ startDeadlineMs: number;
46
+ }
47
+ /** Engine → driver: a single bridged call to execute under the gate. */
48
+ export interface PtcRpcRequest {
49
+ t: "call";
50
+ id: number;
51
+ tool: BridgeTool;
52
+ args: Record<string, unknown>;
53
+ }
54
+ /** Driver → engine: the gated result of a call. */
55
+ export interface PtcRpcResponse {
56
+ t: "result";
57
+ id: number;
58
+ r: PtcCallResult;
59
+ }
60
+ /** Driver → engine: stop the run (budget / time hit); engine must unwind. */
61
+ export interface PtcRpcAbort {
62
+ t: "abort";
63
+ id: number;
64
+ reason: "timeout" | "error-budget" | "call-budget";
65
+ }
66
+ export type PtcEngineMessage = PtcRpcRequest | PtcRpcResponse | PtcRpcAbort;
67
+ export type PtcEngineName = "worker" | "inline";
68
+ /**
69
+ * The engine seam — FROZEN. InlineSequentialEngine shipped in M1,
70
+ * WorkerEngine + InlineVmEngine in M2; a future engine implements this same
71
+ * shape and neither the driver nor the tool changes.
72
+ */
73
+ export interface PtcEngine {
74
+ readonly name: PtcEngineName;
75
+ /**
76
+ * Run `program`, driving every bridge call through `bridge` (already
77
+ * gate-wrapped by the driver). Resolve with the program's return value;
78
+ * reject with a `PtcStopSignal` for a budget/time stop, or any other Error
79
+ * for an engine/program fault. `signal` lets the driver race a timeout.
80
+ */
81
+ run(program: string, bridge: PtcBridge, signal: AbortSignal): Promise<unknown>;
82
+ }
83
+ /**
84
+ * The stop signal unwinding a program on a budget/time hit. Thrown by the
85
+ * StepGate (call/error budget, pre-call deadline) and rejected through the
86
+ * engines' abort promises (wall-clock timeout); caught by the driver, which
87
+ * maps it to a status. Never escapes as an engine-error.
88
+ */
89
+ export declare class PtcStopSignal extends Error {
90
+ readonly reason: "timeout" | "error-budget" | "call-budget";
91
+ constructor(reason: "timeout" | "error-budget" | "call-budget");
92
+ }
93
+ /** Short display code for a ref: the `steps/<id>` step segment. Shared by
94
+ * the gate (success table) and the summary renderer (error refs). */
95
+ export declare function shortRefCode(ref: string): string;
96
+ export interface PtcStepRecord {
97
+ n: number;
98
+ tool: BridgeTool;
99
+ ok: boolean;
100
+ ms: number;
101
+ /** ok rows: estimated tokens (inline text) or the offload handle's tokens. */
102
+ tokens: number;
103
+ /** ok rows: "inline" or a short ref code for an offloaded payload. */
104
+ dest: string;
105
+ /** ok rows: the offload ref (when the data was a handle), else null. */
106
+ ref?: string | null;
107
+ /** err rows only. */
108
+ phase?: TmPhase;
109
+ line?: number;
110
+ retry?: boolean;
111
+ message?: string;
112
+ errorRef?: string;
113
+ }
114
+ export interface PtcRunOutcome {
115
+ label: string;
116
+ status: PtcStatus;
117
+ steps: PtcStepRecord[];
118
+ okCount: number;
119
+ errCount: number;
120
+ retries: number;
121
+ calls: number;
122
+ ms: number;
123
+ engine: PtcEngineName;
124
+ degraded: boolean;
125
+ returnValue: unknown;
126
+ returned: boolean;
127
+ /** set when the program threw (status=engine-error). */
128
+ engineError?: PtcErrorBody;
129
+ parentStepId: string;
130
+ }
131
+ //# sourceMappingURL=contract.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../../src/tm/ptc/contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAK3C,6CAA6C;AAC7C,eAAO,MAAM,iBAAiB,2FAMpB,CAAA;AACV,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAA;AAE1D,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,UAAU,CAAA;AAEvE,gFAAgF;AAChF,eAAO,MAAM,YAAY,EAAE,SAAS,UAAU,EAAkD,CAAA;AAEhG,6EAA6E;AAC7E,eAAO,MAAM,gBAAgB,EAAE,SAAS,OAAO,EAAmC,CAAA;AAElF,6EAA6E;AAC7E,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,OAAO,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,kEAAkE;AAClE,MAAM,MAAM,aAAa,GACrB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC3B;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,YAAY,CAAA;CAAE,CAAA;AAEtC,iFAAiF;AACjF,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,CAAA;CAC9E;AAID,wCAAwC;AACxC,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,0EAA0E;IAC1E,eAAe,EAAE,MAAM,CAAA;CACxB;AAED,wEAAwE;AACxE,MAAM,WAAW,aAAa;IAC5B,CAAC,EAAE,MAAM,CAAA;IACT,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,UAAU,CAAA;IAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAC9B;AAED,mDAAmD;AACnD,MAAM,WAAW,cAAc;IAC7B,CAAC,EAAE,QAAQ,CAAA;IACX,EAAE,EAAE,MAAM,CAAA;IACV,CAAC,EAAE,aAAa,CAAA;CACjB;AAED,6EAA6E;AAC7E,MAAM,WAAW,WAAW;IAC1B,CAAC,EAAE,OAAO,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,SAAS,GAAG,cAAc,GAAG,aAAa,CAAA;CACnD;AAED,MAAM,MAAM,gBAAgB,GAAG,aAAa,GAAG,cAAc,GAAG,WAAW,CAAA;AAE3E,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAE/C;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAA;IAC5B;;;;;OAKG;IACH,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CAC/E;AAED;;;;;GAKG;AACH,qBAAa,aAAc,SAAQ,KAAK;IAC1B,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,cAAc,GAAG,aAAa;gBAAlD,MAAM,EAAE,SAAS,GAAG,cAAc,GAAG,aAAa;CAIxE;AAED;sEACsE;AACtE,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGhD;AAID,MAAM,WAAW,aAAa;IAC5B,CAAC,EAAE,MAAM,CAAA;IACT,IAAI,EAAE,UAAU,CAAA;IAChB,EAAE,EAAE,OAAO,CAAA;IACX,EAAE,EAAE,MAAM,CAAA;IACV,8EAA8E;IAC9E,MAAM,EAAE,MAAM,CAAA;IACd,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAA;IACZ,wEAAwE;IACxE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,qBAAqB;IACrB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,SAAS,CAAA;IACjB,KAAK,EAAE,aAAa,EAAE,CAAA;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,aAAa,CAAA;IACrB,QAAQ,EAAE,OAAO,CAAA;IACjB,WAAW,EAAE,OAAO,CAAA;IACpB,QAAQ,EAAE,OAAO,CAAA;IACjB,wDAAwD;IACxD,WAAW,CAAC,EAAE,YAAY,CAAA;IAC1B,YAAY,EAAE,MAAM,CAAA;CACrB"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * tm_ptc_run — public contract types + the frozen engine seam.
3
+ *
4
+ * Design: .git/opencode-team/.../ptc-run/02-architect-ptc-run-design.md §2/§3.
5
+ * Everything in this module is CONTRACT — frozen since M1 so M2's engines and
6
+ * M3's registration could land without touching the driver or the tool.
7
+ * (Split out of the former monolithic ptc.ts; behavior unchanged.)
8
+ *
9
+ * Governance is REUSED, never forked (D6 lock): the bridge calls the exact
10
+ * four exported pipelines, so threshold offload, P2/P3, R6 and handle/TTL
11
+ * semantics apply to every bridged call verbatim. PTC is NOT a bypass layer.
12
+ */
13
+ import { shorten } from "../config.js";
14
+ // ---------- statuses + bridge surface (design §2) ---------------------------
15
+ /** The five PTC run statuses (design §2). */
16
+ export const PTC_STATUS_VALUES = [
17
+ "ok",
18
+ "stopped-error-budget",
19
+ "stopped-call-budget",
20
+ "timeout",
21
+ "engine-error",
22
+ ];
23
+ /** Bridge allow set — read-only; tm_ptc_run itself is excluded (no nesting). */
24
+ export const BRIDGE_ALLOW = ["tm_read", "tm_grep", "tm_bash", "tm_fetch"];
25
+ /** Phases safe to retry once (idempotent read-only bridges; design §4.2). */
26
+ export const RETRYABLE_PHASES = ["client", "execute", "store"];
27
+ /**
28
+ * The stop signal unwinding a program on a budget/time hit. Thrown by the
29
+ * StepGate (call/error budget, pre-call deadline) and rejected through the
30
+ * engines' abort promises (wall-clock timeout); caught by the driver, which
31
+ * maps it to a status. Never escapes as an engine-error.
32
+ */
33
+ export class PtcStopSignal extends Error {
34
+ reason;
35
+ constructor(reason) {
36
+ super(`ptc-stop:${reason}`);
37
+ this.reason = reason;
38
+ this.name = "PtcStopSignal";
39
+ }
40
+ }
41
+ /** Short display code for a ref: the `steps/<id>` step segment. Shared by
42
+ * the gate (success table) and the summary renderer (error refs). */
43
+ export function shortRefCode(ref) {
44
+ const m = /\/steps\/([^/]+)\/result/.exec(ref);
45
+ return m ? m[1] : shorten(ref, 24);
46
+ }
47
+ //# sourceMappingURL=contract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../../../src/tm/ptc/contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAEtC,+EAA+E;AAE/E,6CAA6C;AAC7C,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,IAAI;IACJ,sBAAsB;IACtB,qBAAqB;IACrB,SAAS;IACT,cAAc;CACN,CAAA;AAKV,gFAAgF;AAChF,MAAM,CAAC,MAAM,YAAY,GAA0B,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,CAAC,CAAA;AAEhG,6EAA6E;AAC7E,MAAM,CAAC,MAAM,gBAAgB,GAAuB,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAA;AAuElF;;;;;GAKG;AACH,MAAM,OAAO,aAAc,SAAQ,KAAK;IACjB;IAArB,YAAqB,MAAkD;QACrE,KAAK,CAAC,YAAY,MAAM,EAAE,CAAC,CAAA;QADR,WAAM,GAAN,MAAM,CAA4C;QAErE,IAAI,CAAC,IAAI,GAAG,eAAe,CAAA;IAC7B,CAAC;CACF;AAED;sEACsE;AACtE,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,MAAM,CAAC,GAAG,0BAA0B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IAC9C,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;AACpC,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * tm_ptc_run — the run driver: engine selection (auto / worker / inline),
3
+ * the static pre-scan handoff, wall-clock timeout, status mapping, and the
4
+ * trajectory parent events. Split out of the former monolithic ptc.ts;
5
+ * behavior unchanged.
6
+ */
7
+ import type { TmConfig } from "../config.js";
8
+ import type { RunStore } from "../store.js";
9
+ import type { PtcBridge, PtcEngine, PtcRunOutcome } from "./contract.js";
10
+ import type { PtcBudgets } from "./budgets.js";
11
+ export interface EngineSelection {
12
+ engine: PtcEngine;
13
+ /** true when the auto chain degraded from worker to inline. */
14
+ degraded: boolean;
15
+ }
16
+ /**
17
+ * Select the PTC engine based on the TM_PTC_ENGINE mode.
18
+ * - "worker": WorkerEngine only (throws on failure → engine-error status).
19
+ * - "inline": InlineVmEngine only (script timeout for pre-await busy-loops).
20
+ * - "auto" (default): worker-first — the REAL auto-degrade happens in
21
+ * runPtc, which re-runs the whole program on InlineVmEngine when a worker
22
+ * run returns engine-error.
23
+ */
24
+ export declare function selectEngine(mode: "auto" | "worker" | "inline", bridge: PtcBridge): EngineSelection;
25
+ export interface RunPtcOptions {
26
+ program: string;
27
+ label: string;
28
+ budgets: PtcBudgets;
29
+ parentStepId: string;
30
+ cfg: TmConfig;
31
+ store?: RunStore;
32
+ bridge: PtcBridge;
33
+ engine?: PtcEngine;
34
+ now?: () => number;
35
+ }
36
+ export declare function runPtc(o: RunPtcOptions): Promise<PtcRunOutcome>;
37
+ //# sourceMappingURL=driver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../../../src/tm/ptc/driver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAa,MAAM,eAAe,CAAA;AAMnF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAI9C,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,SAAS,CAAA;IACjB,+DAA+D;IAC/D,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,EAAE,MAAM,EAAE,SAAS,GAAG,eAAe,CAQnG;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,UAAU,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,GAAG,EAAE,QAAQ,CAAA;IACb,KAAK,CAAC,EAAE,QAAQ,CAAA;IAChB,MAAM,EAAE,SAAS,CAAA;IACjB,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACnB;AAED,wBAAsB,MAAM,CAAC,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAwIrE"}
@@ -0,0 +1,181 @@
1
+ /**
2
+ * tm_ptc_run — the run driver: engine selection (auto / worker / inline),
3
+ * the static pre-scan handoff, wall-clock timeout, status mapping, and the
4
+ * trajectory parent events. Split out of the former monolithic ptc.ts;
5
+ * behavior unchanged.
6
+ */
7
+ import * as crypto from "node:crypto";
8
+ import { PtcStopSignal } from "./contract.js";
9
+ import { createGateBridge } from "./gate.js";
10
+ import { InlineVmEngine, WorkerEngine } from "./engines.js";
11
+ import { staticPscan } from "./pscan.js";
12
+ /**
13
+ * Select the PTC engine based on the TM_PTC_ENGINE mode.
14
+ * - "worker": WorkerEngine only (throws on failure → engine-error status).
15
+ * - "inline": InlineVmEngine only (script timeout for pre-await busy-loops).
16
+ * - "auto" (default): worker-first — the REAL auto-degrade happens in
17
+ * runPtc, which re-runs the whole program on InlineVmEngine when a worker
18
+ * run returns engine-error.
19
+ */
20
+ export function selectEngine(mode, bridge) {
21
+ void bridge;
22
+ if (mode === "inline") {
23
+ return { engine: new InlineVmEngine(), degraded: false };
24
+ }
25
+ // auto and worker both start on the worker engine (construction never
26
+ // throws — no spawn until run()).
27
+ return { engine: new WorkerEngine(), degraded: false };
28
+ }
29
+ export async function runPtc(o) {
30
+ const now = o.now ?? Date.now;
31
+ const start = now();
32
+ const deadlineAt = start + o.budgets.timeoutMs;
33
+ // engine selection — explicit override or auto/worker/inline from config.
34
+ let engine;
35
+ let degraded = false;
36
+ if (o.engine) {
37
+ engine = o.engine;
38
+ }
39
+ else {
40
+ const sel = selectEngine(o.cfg.ptcEngine, o.bridge);
41
+ engine = sel.engine;
42
+ degraded = sel.degraded;
43
+ }
44
+ // static pre-scan — reject programs with banned tokens before any
45
+ // engine runs. Shape: engine-error with the pscan tokens listed.
46
+ // (Design §3: "辅助手段,声明不作安全边界".)
47
+ const pscan = staticPscan(o.program);
48
+ if (pscan.rejected) {
49
+ return {
50
+ label: o.label,
51
+ status: "engine-error",
52
+ steps: [],
53
+ okCount: 0,
54
+ errCount: 0,
55
+ retries: 0,
56
+ calls: 0,
57
+ ms: 0,
58
+ engine: engine.name,
59
+ degraded,
60
+ returnValue: undefined,
61
+ returned: false,
62
+ engineError: {
63
+ tool: "tm_ptc_run",
64
+ phase: "args",
65
+ message: `程序包含禁止标识符(${pscan.tokens.join(", ")}),已拒绝执行。`,
66
+ },
67
+ parentStepId: o.parentStepId,
68
+ };
69
+ }
70
+ // Auto-degrade: if the selected engine throws (not a PtcStopSignal),
71
+ // and we're in auto mode with no explicit override, retry with InlineVmEngine.
72
+ const tryRun = async (eng) => {
73
+ const state = { calls: 0, errors: 0, retries: 0, steps: [] };
74
+ const gate = createGateBridge(o.bridge, o.parentStepId, o.budgets, state, {
75
+ now,
76
+ deadlineAt,
77
+ store: o.store,
78
+ });
79
+ // parent call event (design §6)
80
+ o.store?.appendTrajectory({
81
+ tool: "tm_ptc_run",
82
+ step_id: o.parentStepId,
83
+ event: "call",
84
+ label: o.label,
85
+ program_sha256: crypto.createHash("sha256").update(o.program).digest("hex"),
86
+ budgets: o.budgets,
87
+ });
88
+ const ac = new AbortController();
89
+ const remaining = Math.max(0, deadlineAt - now());
90
+ const timer = setTimeout(() => ac.abort(), remaining);
91
+ let status;
92
+ let returnValue;
93
+ let returned = false;
94
+ let engineError;
95
+ try {
96
+ returnValue = await eng.run(o.program, gate, ac.signal);
97
+ returned = true;
98
+ status = state.stopReason ? mapStop(state.stopReason) : "ok";
99
+ }
100
+ catch (err) {
101
+ if (err instanceof PtcStopSignal) {
102
+ status = mapStop(err.reason);
103
+ }
104
+ else {
105
+ status = "engine-error";
106
+ const line = extractLine(err);
107
+ engineError = {
108
+ tool: "tm_ptc_run",
109
+ phase: "execute",
110
+ message: err instanceof Error ? err.message : String(err ?? "engine error"),
111
+ ...(line != null ? { line } : {}),
112
+ };
113
+ }
114
+ }
115
+ finally {
116
+ clearTimeout(timer);
117
+ }
118
+ const ms = now() - start;
119
+ const outcome = {
120
+ label: o.label,
121
+ status,
122
+ steps: state.steps,
123
+ okCount: state.steps.filter((s) => s.ok).length,
124
+ errCount: state.steps.filter((s) => !s.ok).length,
125
+ retries: state.retries,
126
+ calls: state.calls,
127
+ ms,
128
+ engine: eng.name,
129
+ degraded,
130
+ returnValue,
131
+ returned,
132
+ ...(engineError ? { engineError } : {}),
133
+ parentStepId: o.parentStepId,
134
+ };
135
+ o.store?.appendTrajectory({
136
+ tool: "tm_ptc_run",
137
+ step_id: o.parentStepId,
138
+ event: "finish",
139
+ status: outcome.status,
140
+ calls: outcome.calls,
141
+ errors: outcome.errCount,
142
+ retries: outcome.retries,
143
+ ms: outcome.ms,
144
+ });
145
+ return outcome;
146
+ };
147
+ // Auto mode: try worker first; on engine-error → degrade to inline.
148
+ if (!o.engine && o.cfg.ptcEngine === "auto" && engine.name === "worker") {
149
+ const result = await tryRun(engine);
150
+ if (result.status === "engine-error") {
151
+ // Degrade to inline-vm and re-run.
152
+ const inlineEngine = new InlineVmEngine();
153
+ const fallback = await tryRun(inlineEngine);
154
+ fallback.degraded = true;
155
+ fallback.engine = "inline";
156
+ return fallback;
157
+ }
158
+ return result;
159
+ }
160
+ return tryRun(engine);
161
+ }
162
+ function mapStop(reason) {
163
+ if (reason === "timeout")
164
+ return "timeout";
165
+ if (reason === "error-budget")
166
+ return "stopped-error-budget";
167
+ return "stopped-call-budget";
168
+ }
169
+ /** Best-effort line extraction from a program-side thrown error stack. */
170
+ function extractLine(err) {
171
+ const s = err instanceof Error ? err.stack ?? "" : String(err ?? "");
172
+ const m = /:(\d+):/.exec(s);
173
+ if (m) {
174
+ const n = Number(m[1]);
175
+ if (Number.isFinite(n))
176
+ return n;
177
+ }
178
+ const m2 = /line[:#]?\s*(\d+)/i.exec(s);
179
+ return m2 ? Number(m2[1]) : undefined;
180
+ }
181
+ //# sourceMappingURL=driver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"driver.js","sourceRoot":"","sources":["../../../src/tm/ptc/driver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * tm_ptc_run — the three engines behind the frozen `PtcEngine` seam.
3
+ * Split out of the former monolithic ptc.ts; behavior unchanged.
4
+ *
5
+ * M1 legacy: InlineSequentialEngine (test-only — runs on the MAIN thread,
6
+ * no sandbox, no timeout; a post-await busy loop blocks the host event loop
7
+ * irrecoverably).
8
+ * M2 primary: WorkerEngine (worker_threads + MessagePort RPC, env:{},
9
+ * resourceLimits, hard `terminate()` wall-clock kill; bootstrap as a
10
+ * build-time string, strict-mode program body).
11
+ * M2 fallback: InlineVmEngine (node:vm runInNewContext — the script timeout
12
+ * kills PRE-await synchronous busy-loops; a POST-await busy loop blocks the
13
+ * host event loop irrecoverably, documented — prefer worker/auto).
14
+ */
15
+ import type { PtcBridge, PtcEngine, PtcEngineName } from "./contract.js";
16
+ export declare class InlineSequentialEngine implements PtcEngine {
17
+ readonly name: PtcEngineName;
18
+ run(program: string, bridge: PtcBridge, signal: AbortSignal): Promise<unknown>;
19
+ }
20
+ export declare class WorkerEngine implements PtcEngine {
21
+ readonly name: PtcEngineName;
22
+ run(program: string, bridge: PtcBridge, signal: AbortSignal): Promise<unknown>;
23
+ }
24
+ export declare class InlineVmEngine implements PtcEngine {
25
+ readonly name: PtcEngineName;
26
+ /** Script execution timeout in ms (kills pre-await synchronous
27
+ * busy-loops). Injectable so tests can pin the kill fast. */
28
+ private readonly compileTimeoutMs;
29
+ constructor(compileTimeoutMs?: number);
30
+ run(program: string, bridge: PtcBridge, signal: AbortSignal): Promise<unknown>;
31
+ }
32
+ //# sourceMappingURL=engines.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engines.d.ts","sourceRoot":"","sources":["../../../src/tm/ptc/engines.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,aAAa,EAAiC,MAAM,eAAe,CAAA;AAYvG,qBAAa,sBAAuB,YAAW,SAAS;IACtD,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAW;IACjC,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;CAyBrF;AAID,qBAAa,YAAa,YAAW,SAAS;IAC5C,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAW;IAEjC,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;CA8GrF;AAID,qBAAa,cAAe,YAAW,SAAS;IAC9C,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAW;IACvC;mEAC+D;IAC/D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAQ;gBAC7B,gBAAgB,SAAS;IAI/B,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;CAuBrF"}
@@ -0,0 +1,201 @@
1
+ /**
2
+ * tm_ptc_run — the three engines behind the frozen `PtcEngine` seam.
3
+ * Split out of the former monolithic ptc.ts; behavior unchanged.
4
+ *
5
+ * M1 legacy: InlineSequentialEngine (test-only — runs on the MAIN thread,
6
+ * no sandbox, no timeout; a post-await busy loop blocks the host event loop
7
+ * irrecoverably).
8
+ * M2 primary: WorkerEngine (worker_threads + MessagePort RPC, env:{},
9
+ * resourceLimits, hard `terminate()` wall-clock kill; bootstrap as a
10
+ * build-time string, strict-mode program body).
11
+ * M2 fallback: InlineVmEngine (node:vm runInNewContext — the script timeout
12
+ * kills PRE-await synchronous busy-loops; a POST-await busy loop blocks the
13
+ * host event loop irrecoverably, documented — prefer worker/auto).
14
+ */
15
+ import * as vm from "node:vm";
16
+ import { PtcStopSignal } from "./contract.js";
17
+ /** Build the `tm` facade the program body sees (one method per bridge tool). */
18
+ function makeFacade(bridge) {
19
+ const one = (tool) => (args) => bridge.call(tool, args && typeof args === "object" ? args : {});
20
+ return { read: one("tm_read"), grep: one("tm_grep"), bash: one("tm_bash"), fetch: one("tm_fetch") };
21
+ }
22
+ export class InlineSequentialEngine {
23
+ name = "inline";
24
+ async run(program, bridge, signal) {
25
+ // M1 legacy engine, kept test-only: the program runs as a trusted async
26
+ // function body on the MAIN thread — no sandbox, no timeout, and a
27
+ // post-await busy loop blocks the host event loop irrecoverably (same
28
+ // residual as InlineVmEngine). Production runs WorkerEngine (auto
29
+ // default) or InlineVmEngine.
30
+ const AsyncFunction = Object.getPrototypeOf(async function () { }).constructor;
31
+ const tm = makeFacade(bridge);
32
+ let abortHandler;
33
+ const abortP = new Promise((_, rej) => {
34
+ // The driver only aborts on wall-clock timeout (budget stops flow through
35
+ // the gate as PtcStopSignal).
36
+ abortHandler = () => rej(new PtcStopSignal("timeout"));
37
+ if (signal.aborted)
38
+ abortHandler();
39
+ else
40
+ signal.addEventListener("abort", abortHandler, { once: true });
41
+ });
42
+ try {
43
+ const fn = new AsyncFunction("tm", `"use strict";\n${program}`);
44
+ return await Promise.race([fn(tm), abortP]);
45
+ }
46
+ finally {
47
+ if (abortHandler)
48
+ signal.removeEventListener("abort", abortHandler);
49
+ }
50
+ }
51
+ }
52
+ // ---------- worker engine (MessagePort RPC over worker_threads) --------------
53
+ export class WorkerEngine {
54
+ name = "worker";
55
+ async run(program, bridge, signal) {
56
+ const { Worker } = await import("node:worker_threads");
57
+ // Build the worker bootstrap source as a regular string (ts-safe).
58
+ // The worker receives {program, startDeadlineMs} via its first message,
59
+ // creates the tm facade, runs the program, and sends RPC call requests
60
+ // back to the driver which executes them through the gate bridge.
61
+ const src = [
62
+ '"use strict";',
63
+ 'const { parentPort } = require("node:worker_threads");',
64
+ "parentPort.on(" + JSON.stringify("message") + ", async function onMsg(msg) {",
65
+ " if (msg && msg.t === " + JSON.stringify("run") + ") {",
66
+ " const program = msg.program;",
67
+ " const AsyncFunction = Object.getPrototypeOf(async function(){}).constructor;",
68
+ " const callMap = new Map();",
69
+ " let nextId = 0;",
70
+ ' const one = function(tool) { return function(args) { return new Promise(function(resolve, reject) {',
71
+ " const id = nextId++;",
72
+ " callMap.set(id, { resolve: resolve, reject: reject });",
73
+ ' parentPort.postMessage({ t: "call", id: id, tool: tool, args: args || {} });',
74
+ " }); }; };",
75
+ " var tm = { read: one(" + JSON.stringify("tm_read") + "), grep: one(" + JSON.stringify("tm_grep") + "), bash: one(" + JSON.stringify("tm_bash") + "), fetch: one(" + JSON.stringify("tm_fetch") + ") };",
76
+ ' parentPort.on("message", function(inner) {',
77
+ ' if (inner && inner.t === "result" && callMap.has(inner.id)) {',
78
+ " callMap.get(inner.id).resolve(inner.r);",
79
+ " callMap.delete(inner.id);",
80
+ ' } else if (inner && inner.t === "abort") {',
81
+ " for (const e of callMap.values()) e.reject(new Error(" + JSON.stringify("ptc-stop:") + " + inner.reason));",
82
+ " callMap.clear();",
83
+ " }",
84
+ " });",
85
+ " try {",
86
+ // strict-mode body, same as the inline engines (they prefix the program
87
+ // with "use strict"; the worker builds the body string here)
88
+ " var body = " + JSON.stringify('"use strict";\n') + " + program;",
89
+ " var fn = new AsyncFunction(" + JSON.stringify("tm") + ", body);",
90
+ " var result = await fn(tm);",
91
+ ' parentPort.postMessage({ t: "done", result: result });',
92
+ " } catch (err) {",
93
+ ' parentPort.postMessage({ t: "error", message: err instanceof Error ? err.message : String(err), stack: err instanceof Error ? err.stack : undefined });',
94
+ " }",
95
+ " }",
96
+ "});",
97
+ ].join("\n");
98
+ return new Promise((resolve, reject) => {
99
+ let settled = false;
100
+ const w = new Worker(src, {
101
+ eval: true,
102
+ env: {},
103
+ resourceLimits: { maxOldGenerationSizeMb: 128, maxYoungGenerationSizeMb: 16 },
104
+ });
105
+ function settle(fn) {
106
+ if (settled)
107
+ return;
108
+ settled = true;
109
+ fn();
110
+ }
111
+ w.on("message", (msg) => {
112
+ if (!msg || settled)
113
+ return;
114
+ if (msg.t === "done") {
115
+ settle(() => {
116
+ w.terminate();
117
+ resolve(msg.result);
118
+ });
119
+ }
120
+ else if (msg.t === "error") {
121
+ settle(() => {
122
+ w.terminate();
123
+ const err = new Error(typeof msg.message === "string" ? msg.message : "worker error");
124
+ if (typeof msg.stack === "string")
125
+ err.stack = msg.stack;
126
+ reject(err);
127
+ });
128
+ }
129
+ else if (msg.t === "call") {
130
+ // Driver executes the bridge call through the gate and replies.
131
+ const req = msg;
132
+ bridge
133
+ .call(req.tool, req.args)
134
+ .then((r) => {
135
+ if (!settled) {
136
+ w.postMessage({ t: "result", id: req.id, r });
137
+ }
138
+ })
139
+ .catch(() => {
140
+ if (!settled) {
141
+ w.postMessage({
142
+ t: "result",
143
+ id: req.id,
144
+ r: { ok: false, error: { tool: req.tool, phase: "execute", message: "bridge call failed" } },
145
+ });
146
+ }
147
+ });
148
+ }
149
+ });
150
+ w.on("error", (err) => {
151
+ settle(() => reject(err instanceof Error ? err : new Error(String(err))));
152
+ });
153
+ // Wire signal abort → terminate the worker.
154
+ const onAbort = () => {
155
+ settle(() => {
156
+ w.terminate().then(() => reject(new PtcStopSignal("timeout")));
157
+ });
158
+ };
159
+ if (signal.aborted)
160
+ onAbort();
161
+ else
162
+ signal.addEventListener("abort", onAbort, { once: true });
163
+ // Send the run request.
164
+ w.postMessage({ t: "run", program });
165
+ });
166
+ }
167
+ }
168
+ // ---------- inline-vm fallback engine (node:vm with script timeout) ----------
169
+ export class InlineVmEngine {
170
+ name = "inline";
171
+ /** Script execution timeout in ms (kills pre-await synchronous
172
+ * busy-loops). Injectable so tests can pin the kill fast. */
173
+ compileTimeoutMs;
174
+ constructor(compileTimeoutMs = 30_000) {
175
+ this.compileTimeoutMs = compileTimeoutMs;
176
+ }
177
+ async run(program, bridge, signal) {
178
+ const tm = makeFacade(bridge);
179
+ let abortHandler;
180
+ const abortP = new Promise((_, rej) => {
181
+ abortHandler = () => rej(new PtcStopSignal("timeout"));
182
+ if (signal.aborted)
183
+ abortHandler();
184
+ else
185
+ signal.addEventListener("abort", abortHandler, { once: true });
186
+ });
187
+ try {
188
+ // The async-IIFE is the program wrapper: `return` stays legal in the
189
+ // body, the `tm` facade rides the context globals, and the script's
190
+ // completion value IS the program's promise. The timeout kills
191
+ // pre-await synchronous busy-loops (see the module doc).
192
+ const promise = vm.runInNewContext(`(async () => {\n"use strict";\n${program}\n})()`, { tm }, { timeout: this.compileTimeoutMs });
193
+ return await Promise.race([promise, abortP]);
194
+ }
195
+ finally {
196
+ if (abortHandler)
197
+ signal.removeEventListener("abort", abortHandler);
198
+ }
199
+ }
200
+ }
201
+ //# sourceMappingURL=engines.js.map