@tom2012/cc-web 2026.5.14-b → 2026.5.15-b

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 (236) hide show
  1. package/README.md +1 -1
  2. package/backend/dist/index.d.ts.map +1 -1
  3. package/backend/dist/index.js +51 -0
  4. package/backend/dist/index.js.map +1 -1
  5. package/backend/dist/routes/flows.d.ts.map +1 -1
  6. package/backend/dist/routes/flows.js +10 -0
  7. package/backend/dist/routes/flows.js.map +1 -1
  8. package/backend/dist/routes/global-tracks.d.ts +11 -0
  9. package/backend/dist/routes/global-tracks.d.ts.map +1 -0
  10. package/backend/dist/routes/global-tracks.js +86 -0
  11. package/backend/dist/routes/global-tracks.js.map +1 -0
  12. package/backend/dist/routes/tracks.d.ts +14 -0
  13. package/backend/dist/routes/tracks.d.ts.map +1 -0
  14. package/backend/dist/routes/tracks.js +184 -0
  15. package/backend/dist/routes/tracks.js.map +1 -0
  16. package/backend/dist/tracks/__tests__/verify-track-t1.d.ts +11 -0
  17. package/backend/dist/tracks/__tests__/verify-track-t1.d.ts.map +1 -0
  18. package/backend/dist/tracks/__tests__/verify-track-t1.js +293 -0
  19. package/backend/dist/tracks/__tests__/verify-track-t1.js.map +1 -0
  20. package/backend/dist/tracks/__tests__/verify-track.d.ts +20 -0
  21. package/backend/dist/tracks/__tests__/verify-track.d.ts.map +1 -0
  22. package/backend/dist/tracks/__tests__/verify-track.js +187 -0
  23. package/backend/dist/tracks/__tests__/verify-track.js.map +1 -0
  24. package/backend/dist/tracks/ask-user-bridge.d.ts +59 -0
  25. package/backend/dist/tracks/ask-user-bridge.d.ts.map +1 -0
  26. package/backend/dist/tracks/ask-user-bridge.js +186 -0
  27. package/backend/dist/tracks/ask-user-bridge.js.map +1 -0
  28. package/backend/dist/tracks/ccweb-train-adapter.d.ts +40 -0
  29. package/backend/dist/tracks/ccweb-train-adapter.d.ts.map +1 -0
  30. package/backend/dist/tracks/ccweb-train-adapter.js +111 -0
  31. package/backend/dist/tracks/ccweb-train-adapter.js.map +1 -0
  32. package/backend/dist/tracks/cross-lock.d.ts +30 -0
  33. package/backend/dist/tracks/cross-lock.d.ts.map +1 -0
  34. package/backend/dist/tracks/cross-lock.js +44 -0
  35. package/backend/dist/tracks/cross-lock.js.map +1 -0
  36. package/backend/dist/tracks/index.d.ts +20 -0
  37. package/backend/dist/tracks/index.d.ts.map +1 -0
  38. package/backend/dist/tracks/index.js +42 -0
  39. package/backend/dist/tracks/index.js.map +1 -0
  40. package/backend/dist/tracks/registry.d.ts +56 -0
  41. package/backend/dist/tracks/registry.d.ts.map +1 -0
  42. package/backend/dist/tracks/registry.js +161 -0
  43. package/backend/dist/tracks/registry.js.map +1 -0
  44. package/backend/dist/tracks/store.d.ts +37 -0
  45. package/backend/dist/tracks/store.d.ts.map +1 -0
  46. package/backend/dist/tracks/store.js +254 -0
  47. package/backend/dist/tracks/store.js.map +1 -0
  48. package/backend/dist/tracks/track-runner.d.ts +62 -0
  49. package/backend/dist/tracks/track-runner.d.ts.map +1 -0
  50. package/backend/dist/tracks/track-runner.js +134 -0
  51. package/backend/dist/tracks/track-runner.js.map +1 -0
  52. package/backend/dist/tracks/train-loader.d.ts +44 -0
  53. package/backend/dist/tracks/train-loader.d.ts.map +1 -0
  54. package/backend/dist/tracks/train-loader.js +32 -0
  55. package/backend/dist/tracks/train-loader.js.map +1 -0
  56. package/backend/dist/tracks/types-train.d.ts +12 -0
  57. package/backend/dist/tracks/types-train.d.ts.map +1 -0
  58. package/backend/dist/tracks/types-train.js +13 -0
  59. package/backend/dist/tracks/types-train.js.map +1 -0
  60. package/backend/dist/tracks/types.d.ts +66 -0
  61. package/backend/dist/tracks/types.d.ts.map +1 -0
  62. package/backend/dist/tracks/types.js +12 -0
  63. package/backend/dist/tracks/types.js.map +1 -0
  64. package/backend/dist/tracks/workflow-data-watcher.d.ts +47 -0
  65. package/backend/dist/tracks/workflow-data-watcher.d.ts.map +1 -0
  66. package/backend/dist/tracks/workflow-data-watcher.js +166 -0
  67. package/backend/dist/tracks/workflow-data-watcher.js.map +1 -0
  68. package/backend/package-lock.json +107 -0
  69. package/backend/package.json +6 -1
  70. package/backend/vendor/@train-lang/adapter-spec/dist/index.d.ts +164 -0
  71. package/backend/vendor/@train-lang/adapter-spec/dist/index.d.ts.map +1 -0
  72. package/backend/vendor/@train-lang/adapter-spec/dist/index.js +13 -0
  73. package/backend/vendor/@train-lang/adapter-spec/dist/index.js.map +1 -0
  74. package/backend/vendor/@train-lang/adapter-spec/package.json +15 -0
  75. package/backend/vendor/@train-lang/core/dist/ast-cache.d.ts +74 -0
  76. package/backend/vendor/@train-lang/core/dist/ast-cache.d.ts.map +1 -0
  77. package/backend/vendor/@train-lang/core/dist/ast-cache.js +157 -0
  78. package/backend/vendor/@train-lang/core/dist/ast-cache.js.map +1 -0
  79. package/backend/vendor/@train-lang/core/dist/ast.d.ts +350 -0
  80. package/backend/vendor/@train-lang/core/dist/ast.d.ts.map +1 -0
  81. package/backend/vendor/@train-lang/core/dist/ast.js +15 -0
  82. package/backend/vendor/@train-lang/core/dist/ast.js.map +1 -0
  83. package/backend/vendor/@train-lang/core/dist/builder.d.ts +21 -0
  84. package/backend/vendor/@train-lang/core/dist/builder.d.ts.map +1 -0
  85. package/backend/vendor/@train-lang/core/dist/builder.js +1221 -0
  86. package/backend/vendor/@train-lang/core/dist/builder.js.map +1 -0
  87. package/backend/vendor/@train-lang/core/dist/builtins.d.ts +17 -0
  88. package/backend/vendor/@train-lang/core/dist/builtins.d.ts.map +1 -0
  89. package/backend/vendor/@train-lang/core/dist/builtins.js +488 -0
  90. package/backend/vendor/@train-lang/core/dist/builtins.js.map +1 -0
  91. package/backend/vendor/@train-lang/core/dist/index.d.ts +54 -0
  92. package/backend/vendor/@train-lang/core/dist/index.d.ts.map +1 -0
  93. package/backend/vendor/@train-lang/core/dist/index.js +66 -0
  94. package/backend/vendor/@train-lang/core/dist/index.js.map +1 -0
  95. package/backend/vendor/@train-lang/core/dist/interpreter.d.ts +110 -0
  96. package/backend/vendor/@train-lang/core/dist/interpreter.d.ts.map +1 -0
  97. package/backend/vendor/@train-lang/core/dist/interpreter.js +894 -0
  98. package/backend/vendor/@train-lang/core/dist/interpreter.js.map +1 -0
  99. package/backend/vendor/@train-lang/core/dist/lexer.d.ts +88 -0
  100. package/backend/vendor/@train-lang/core/dist/lexer.d.ts.map +1 -0
  101. package/backend/vendor/@train-lang/core/dist/lexer.js +243 -0
  102. package/backend/vendor/@train-lang/core/dist/lexer.js.map +1 -0
  103. package/backend/vendor/@train-lang/core/dist/module-loader.d.ts +74 -0
  104. package/backend/vendor/@train-lang/core/dist/module-loader.d.ts.map +1 -0
  105. package/backend/vendor/@train-lang/core/dist/module-loader.js +134 -0
  106. package/backend/vendor/@train-lang/core/dist/module-loader.js.map +1 -0
  107. package/backend/vendor/@train-lang/core/dist/parser.d.ts +135 -0
  108. package/backend/vendor/@train-lang/core/dist/parser.d.ts.map +1 -0
  109. package/backend/vendor/@train-lang/core/dist/parser.js +838 -0
  110. package/backend/vendor/@train-lang/core/dist/parser.js.map +1 -0
  111. package/backend/vendor/@train-lang/core/dist/prompt-composer.d.ts +49 -0
  112. package/backend/vendor/@train-lang/core/dist/prompt-composer.d.ts.map +1 -0
  113. package/backend/vendor/@train-lang/core/dist/prompt-composer.js +159 -0
  114. package/backend/vendor/@train-lang/core/dist/prompt-composer.js.map +1 -0
  115. package/backend/vendor/@train-lang/core/dist/runtime.d.ts +146 -0
  116. package/backend/vendor/@train-lang/core/dist/runtime.d.ts.map +1 -0
  117. package/backend/vendor/@train-lang/core/dist/runtime.js +156 -0
  118. package/backend/vendor/@train-lang/core/dist/runtime.js.map +1 -0
  119. package/backend/vendor/@train-lang/core/dist/type-descriptor.d.ts +18 -0
  120. package/backend/vendor/@train-lang/core/dist/type-descriptor.d.ts.map +1 -0
  121. package/backend/vendor/@train-lang/core/dist/type-descriptor.js +94 -0
  122. package/backend/vendor/@train-lang/core/dist/type-descriptor.js.map +1 -0
  123. package/backend/vendor/@train-lang/core/dist/validation.d.ts +44 -0
  124. package/backend/vendor/@train-lang/core/dist/validation.d.ts.map +1 -0
  125. package/backend/vendor/@train-lang/core/dist/validation.js +271 -0
  126. package/backend/vendor/@train-lang/core/dist/validation.js.map +1 -0
  127. package/backend/vendor/@train-lang/core/package.json +35 -0
  128. package/frontend/dist/assets/{ChatOverlay-B4bHclb4.js → ChatOverlay-59ZxvtRP.js} +1 -1
  129. package/frontend/dist/assets/{GraphPreview-CBR4uFHb.js → GraphPreview-sbpMfB9C.js} +2 -2
  130. package/frontend/dist/assets/{MobilePage-B7u9HJ1Y.js → MobilePage-Dcx6MXJq.js} +3 -3
  131. package/frontend/dist/assets/{OfficePreview-V-X3ON2u.js → OfficePreview-pFRYqbUT.js} +2 -2
  132. package/frontend/dist/assets/{PdfPreview-NktKOUdL.js → PdfPreview-YuE4294t.js} +1 -1
  133. package/frontend/dist/assets/{ProjectPage-DAU6cEkl.js → ProjectPage-99jMQxFL.js} +5 -5
  134. package/frontend/dist/assets/{SettingsPage-CtBCvofK.js → SettingsPage-lBTzzVSA.js} +2 -2
  135. package/frontend/dist/assets/{SkillHubPage-CHvWwI8j.js → SkillHubPage-Ba16r6gG.js} +3 -3
  136. package/frontend/dist/assets/TrackEditor-BHghiFPX.js +14 -0
  137. package/frontend/dist/assets/abap-LPLW346S.js +7 -0
  138. package/frontend/dist/assets/apex-Dk-jUCUV.js +7 -0
  139. package/frontend/dist/assets/azcli-DPUMmPlX.js +7 -0
  140. package/frontend/dist/assets/bat-C1Qbg1bV.js +7 -0
  141. package/frontend/dist/assets/bicep-D-e-VSJi.js +7 -0
  142. package/frontend/dist/assets/cameligo-CjUqTgqL.js +7 -0
  143. package/frontend/dist/assets/{chevron-down-COdWD3xd.js → chevron-down-D8NwXKSN.js} +1 -1
  144. package/frontend/dist/assets/clojure-BWsu6Kju.js +7 -0
  145. package/frontend/dist/assets/codicon-DCmgc-ay.ttf +0 -0
  146. package/frontend/dist/assets/coffee-DeC36AK3.js +7 -0
  147. package/frontend/dist/assets/cpp-DcZnmBWT.js +7 -0
  148. package/frontend/dist/assets/csharp-DqBXBMf0.js +7 -0
  149. package/frontend/dist/assets/csp-CkO7y8ul.js +7 -0
  150. package/frontend/dist/assets/css-OAcfVtED.js +7 -0
  151. package/frontend/dist/assets/cssMode-JswmrBJm.js +7 -0
  152. package/frontend/dist/assets/cypher-40UGrUjD.js +7 -0
  153. package/frontend/dist/assets/dart-DmixyLor.js +7 -0
  154. package/frontend/dist/assets/dockerfile-CayO4nTA.js +7 -0
  155. package/frontend/dist/assets/ecl-DRrKCuVc.js +7 -0
  156. package/frontend/dist/assets/editor-B5EY1bb8.css +1 -0
  157. package/frontend/dist/assets/editor.main-DxKJbewY.js +37 -0
  158. package/frontend/dist/assets/elixir-J3qpp9mX.js +7 -0
  159. package/frontend/dist/assets/flow9-DzW2c4Im.js +7 -0
  160. package/frontend/dist/assets/freemarker2-DSk3lXcG.js +7 -0
  161. package/frontend/dist/assets/fsharp-D00tn_6c.js +7 -0
  162. package/frontend/dist/assets/go-NnNmgWK_.js +7 -0
  163. package/frontend/dist/assets/graphql-C9_--VLF.js +7 -0
  164. package/frontend/dist/assets/handlebars-3L3xIxMF.js +7 -0
  165. package/frontend/dist/assets/hcl-BhbOULbp.js +7 -0
  166. package/frontend/dist/assets/html-jGWDYvg4.js +7 -0
  167. package/frontend/dist/assets/htmlMode-BNn43R0H.js +7 -0
  168. package/frontend/dist/assets/index-BWlHiqbD.js +1 -0
  169. package/frontend/dist/assets/index-BmPb0Wl1.css +1 -0
  170. package/frontend/dist/assets/{index-CZ4PAGPA.js → index-CcOfgS18.js} +2 -2
  171. package/frontend/dist/assets/{index-CaO8S0F7.js → index-DbB1EvuS.js} +1 -1
  172. package/frontend/dist/assets/{index-CRhUXLfj.js → index-DzYcaccz.js} +1 -1
  173. package/frontend/dist/assets/ini-zR-_X5iG.js +7 -0
  174. package/frontend/dist/assets/java-CSTjsyoZ.js +7 -0
  175. package/frontend/dist/assets/javascript-DrTQenPf.js +7 -0
  176. package/frontend/dist/assets/jsonMode-BJqz4hx6.js +7 -0
  177. package/frontend/dist/assets/{jszip.min-CP_BBUld.js → jszip.min-Dn7y6lhP.js} +1 -1
  178. package/frontend/dist/assets/julia-DioMOKVu.js +7 -0
  179. package/frontend/dist/assets/kotlin-Dsb0PKmW.js +7 -0
  180. package/frontend/dist/assets/less-CZYLoAVD.js +7 -0
  181. package/frontend/dist/assets/lexon-d5JUiwNk.js +7 -0
  182. package/frontend/dist/assets/liquid-51VrCPM1.js +7 -0
  183. package/frontend/dist/assets/lua-1Al72GG8.js +7 -0
  184. package/frontend/dist/assets/m3-hx1xCPC3.js +7 -0
  185. package/frontend/dist/assets/markdown-DPGrH1xZ.js +7 -0
  186. package/frontend/dist/assets/mdx-B9MBogQu.js +7 -0
  187. package/frontend/dist/assets/mips-CYbZjkIm.js +7 -0
  188. package/frontend/dist/assets/msdax-DAioKM5A.js +7 -0
  189. package/frontend/dist/assets/mysql-7e9GUebS.js +7 -0
  190. package/frontend/dist/assets/objective-c-BGf8QNjz.js +7 -0
  191. package/frontend/dist/assets/pascal-hEDRz3un.js +7 -0
  192. package/frontend/dist/assets/pascaligo-gqEhN6pG.js +7 -0
  193. package/frontend/dist/assets/perl-CN8Ht9Vk.js +7 -0
  194. package/frontend/dist/assets/pgsql-CRCqHQBx.js +7 -0
  195. package/frontend/dist/assets/php-DTZrlAwe.js +7 -0
  196. package/frontend/dist/assets/pla-CRmh4UcC.js +7 -0
  197. package/frontend/dist/assets/postiats-Car2G7g8.js +7 -0
  198. package/frontend/dist/assets/powerquery-BJKl8V3o.js +7 -0
  199. package/frontend/dist/assets/powershell-Du7a_J7r.js +7 -0
  200. package/frontend/dist/assets/protobuf-ChneWI0H.js +7 -0
  201. package/frontend/dist/assets/pug-BH6LSJaf.js +7 -0
  202. package/frontend/dist/assets/python-B4lxjc3U.js +7 -0
  203. package/frontend/dist/assets/qsharp-CU-Hxpxi.js +7 -0
  204. package/frontend/dist/assets/r-Bw-W15zh.js +7 -0
  205. package/frontend/dist/assets/razor-Df88ZAwt.js +7 -0
  206. package/frontend/dist/assets/redis-bY-X9-ol.js +7 -0
  207. package/frontend/dist/assets/redshift-CMu3ubbS.js +7 -0
  208. package/frontend/dist/assets/restructuredtext-KNkiWGNN.js +7 -0
  209. package/frontend/dist/assets/ruby-dQWMhU86.js +7 -0
  210. package/frontend/dist/assets/rust-BAcHhnEU.js +7 -0
  211. package/frontend/dist/assets/sb-Bidr5w2z.js +7 -0
  212. package/frontend/dist/assets/scala-imTtxsGY.js +7 -0
  213. package/frontend/dist/assets/scheme-BY-WHKiB.js +7 -0
  214. package/frontend/dist/assets/scss-NDoRP52C.js +7 -0
  215. package/frontend/dist/assets/{select-Cf6Q2O8Z.js → select-BCKg8P7d.js} +1 -1
  216. package/frontend/dist/assets/shell-DrIjotnh.js +7 -0
  217. package/frontend/dist/assets/solidity-DTahNycF.js +7 -0
  218. package/frontend/dist/assets/sophia-DtyrjGkZ.js +7 -0
  219. package/frontend/dist/assets/sparql-CFuS5E3z.js +7 -0
  220. package/frontend/dist/assets/sql-BRxcnbRv.js +7 -0
  221. package/frontend/dist/assets/st-Dz4uh7MK.js +7 -0
  222. package/frontend/dist/assets/swift-Digsrw1G.js +11 -0
  223. package/frontend/dist/assets/systemverilog-7TDrkMau.js +7 -0
  224. package/frontend/dist/assets/tcl-BtaFcnDi.js +7 -0
  225. package/frontend/dist/assets/tsMode-BHae3zIH.js +7 -0
  226. package/frontend/dist/assets/twig-Deid_oBs.js +7 -0
  227. package/frontend/dist/assets/typescript-Bv6gAW_5.js +7 -0
  228. package/frontend/dist/assets/typespec-zUaxhbG8.js +7 -0
  229. package/frontend/dist/assets/{user-B4YUPhU8.js → user-CGd4Ayhq.js} +1 -1
  230. package/frontend/dist/assets/vb-DK0rKJzo.js +7 -0
  231. package/frontend/dist/assets/wgsl-B8fNVlOQ.js +7 -0
  232. package/frontend/dist/assets/xml-C70S0rct.js +7 -0
  233. package/frontend/dist/assets/yaml-BZVXvTCX.js +7 -0
  234. package/frontend/dist/index.html +2 -2
  235. package/package.json +2 -1
  236. package/frontend/dist/assets/index-BkQ6KI1l.css +0 -1
@@ -0,0 +1,187 @@
1
+ "use strict";
2
+ /**
3
+ * T0 verification script for the Track subsystem.
4
+ *
5
+ * NOT a vitest/jest test — ccweb backend has no test framework yet.
6
+ * Runs as a standalone Node script to verify end-to-end:
7
+ *
8
+ * 1. TrackRunner can load a .tr file
9
+ * 2. train-lang composes prompt + calls CcwebTrainAdapter
10
+ * 3. CcwebTrainAdapter injects prompt (capture into a mock buffer)
11
+ * 4. We programmatically simulate the LLM writing outputs by editing
12
+ * workflow_data.json + setting task_progress[].finish = true
13
+ * 5. WorkflowDataWatcher detects the finish signal
14
+ * 6. Adapter reads variables.<name> → returns FaiResult.success
15
+ * 7. train continues execution → main() returns
16
+ * 8. TrackRunner reports ok=true with the returned value
17
+ *
18
+ * Run: cd backend && npx ts-node src/tracks/__tests__/verify-track.ts
19
+ */
20
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
21
+ if (k2 === undefined) k2 = k;
22
+ var desc = Object.getOwnPropertyDescriptor(m, k);
23
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
24
+ desc = { enumerable: true, get: function() { return m[k]; } };
25
+ }
26
+ Object.defineProperty(o, k2, desc);
27
+ }) : (function(o, m, k, k2) {
28
+ if (k2 === undefined) k2 = k;
29
+ o[k2] = m[k];
30
+ }));
31
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
32
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
33
+ }) : function(o, v) {
34
+ o["default"] = v;
35
+ });
36
+ var __importStar = (this && this.__importStar) || (function () {
37
+ var ownKeys = function(o) {
38
+ ownKeys = Object.getOwnPropertyNames || function (o) {
39
+ var ar = [];
40
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
41
+ return ar;
42
+ };
43
+ return ownKeys(o);
44
+ };
45
+ return function (mod) {
46
+ if (mod && mod.__esModule) return mod;
47
+ var result = {};
48
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
49
+ __setModuleDefault(result, mod);
50
+ return result;
51
+ };
52
+ })();
53
+ Object.defineProperty(exports, "__esModule", { value: true });
54
+ const fs = __importStar(require("fs/promises"));
55
+ const os = __importStar(require("os"));
56
+ const path = __importStar(require("path"));
57
+ const __1 = require("..");
58
+ let failed = 0;
59
+ function check(name, cond, msg) {
60
+ if (cond) {
61
+ console.log(` ✓ ${name}`);
62
+ }
63
+ else {
64
+ failed++;
65
+ console.error(` ✗ ${name}${msg ? ': ' + msg : ''}`);
66
+ }
67
+ }
68
+ const DEMO_TR = `
69
+ fai analyze(file_path: string, prompt: prompt) -> rating: int 0-10, comment: string maxLen=500 { }
70
+
71
+ func main(input_path: string) -> string {
72
+ let r = analyze(input_path, "评分 0-10")
73
+ return r.comment
74
+ }
75
+
76
+ export main
77
+ `;
78
+ async function readWf(p) {
79
+ const text = await fs.readFile(p, 'utf8');
80
+ return JSON.parse(text);
81
+ }
82
+ async function writeWf(p, w) {
83
+ await fs.writeFile(p, JSON.stringify(w, null, 2), 'utf8');
84
+ }
85
+ async function main() {
86
+ console.log('=== Track T0 verification ===\n');
87
+ const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'ccweb-track-t0-'));
88
+ console.log(`tmpDir = ${tmpDir}`);
89
+ const trackPath = path.join(tmpDir, 'demo.tr');
90
+ const wfPath = path.join(tmpDir, 'workflow_data.json');
91
+ await fs.writeFile(trackPath, DEMO_TR, 'utf8');
92
+ await writeWf(wfPath, {
93
+ constants: {},
94
+ variables: {},
95
+ task_progress: [],
96
+ });
97
+ const watcher = (0, __1.createWorkflowDataWatcher)(wfPath);
98
+ // Capture prompts injected by adapter
99
+ const promptsInjected = [];
100
+ // Mock injector: instead of writing to a PTY, it parses the
101
+ // [Required outputs] section from the prompt, fabricates legal
102
+ // values, and writes them to workflow_data.json after a short
103
+ // delay (simulating LLM round-trip latency).
104
+ const injector = async (text) => {
105
+ promptsInjected.push(text);
106
+ // Extract taskIndex from the ccweb header (first 3 lines)
107
+ const m = text.match(/taskIndex = (\d+)/);
108
+ if (!m)
109
+ throw new Error('no taskIndex in prompt — adapter contract broken');
110
+ const taskIndex = Number(m[1]);
111
+ // Simulate LLM writing outputs after 30ms
112
+ setTimeout(async () => {
113
+ const wf = await readWf(wfPath);
114
+ // Pretend the LLM gave rating=8 + comment="OK"
115
+ wf.variables.rating = 8;
116
+ wf.variables.comment = 'OK';
117
+ wf.task_progress.push({
118
+ nodeId: taskIndex,
119
+ name: 'analyze',
120
+ finish: true,
121
+ startedAt: Date.now() - 10,
122
+ finishedAt: Date.now(),
123
+ });
124
+ await writeWf(wfPath, wf);
125
+ }, 30);
126
+ };
127
+ const runner = (0, __1.createTrackRunner)({
128
+ projectId: 'demo-proj',
129
+ injector,
130
+ watcher,
131
+ maxFaiAttempts: 2,
132
+ defaultFaiTimeoutMs: 5000,
133
+ });
134
+ const result = await runner.run(trackPath, ['src/foo.ts']);
135
+ // Assertions
136
+ check('result.ok is true', result.ok, JSON.stringify(result.error));
137
+ check('result.value is the LLM-supplied comment ("OK")', result.value === 'OK', `got: ${JSON.stringify(result.value)}`);
138
+ check('injector called exactly once', promptsInjected.length === 1);
139
+ check('prompt contains writeProtocolHint marker', promptsInjected[0]?.includes('[Write outputs to .ccweb/workflow_data.json') ?? false);
140
+ check('prompt does NOT contain stale train default hint', !(promptsInjected[0]?.includes('stack[<callId>]') ?? false));
141
+ check('prompt contains ccweb track context header (taskIndex)', promptsInjected[0]?.includes('taskIndex = ') ?? false);
142
+ check('final workflow_data.task_progress has 1 finished entry', (await readWf(wfPath)).task_progress.length === 1);
143
+ // Verify cancellation path
144
+ console.log('\n--- cancellation path ---');
145
+ await writeWf(wfPath, {
146
+ constants: {},
147
+ variables: {},
148
+ task_progress: [],
149
+ });
150
+ // Use an injector that never resolves the finish signal
151
+ const slowPromptsInjected = [];
152
+ const slowInjector = async (text) => {
153
+ slowPromptsInjected.push(text);
154
+ // Don't write anything — simulate LLM hung
155
+ };
156
+ const watcher2 = (0, __1.createWorkflowDataWatcher)(wfPath);
157
+ const cancelRunner = (0, __1.createTrackRunner)({
158
+ projectId: 'demo-proj',
159
+ injector: slowInjector,
160
+ watcher: watcher2,
161
+ maxFaiAttempts: 1,
162
+ defaultFaiTimeoutMs: 60000, // long timeout — we'll cancel before this
163
+ });
164
+ // Cancel after 100ms
165
+ const cancelTimer = setTimeout(() => cancelRunner.cancel(), 100);
166
+ const cancelResult = await cancelRunner.run(trackPath, ['src/foo.ts']);
167
+ clearTimeout(cancelTimer);
168
+ check('cancel: ok is false', !cancelResult.ok);
169
+ check('cancel: error is UserCancelError-like', /cancel/i.test(cancelResult.error?.errorType ?? '') ||
170
+ /cancel/i.test(cancelResult.error?.message ?? ''), `got: ${JSON.stringify(cancelResult.error)}`);
171
+ // Verify writeProtocolHint factory shape (smoke test)
172
+ console.log('\n--- buildCcwebWriteProtocolHint shape ---');
173
+ const hint = (0, __1.buildCcwebWriteProtocolHint)();
174
+ check('hint mentions workflow_data.json', hint.includes('workflow_data.json'));
175
+ check('hint mentions variables', hint.includes('variables.<name>'));
176
+ check('hint mentions task_progress', hint.includes('task_progress'));
177
+ check('hint mentions finish: true', hint.includes('finish: true'));
178
+ // Cleanup
179
+ await fs.rm(tmpDir, { recursive: true, force: true });
180
+ console.log(`\n${failed === 0 ? '✅ ALL CHECKS PASSED' : `❌ ${failed} CHECK(S) FAILED`}`);
181
+ process.exit(failed === 0 ? 0 : 1);
182
+ }
183
+ main().catch((e) => {
184
+ console.error('verify-track crashed:', e);
185
+ process.exit(2);
186
+ });
187
+ //# sourceMappingURL=verify-track.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-track.js","sourceRoot":"","sources":["../../../src/tracks/__tests__/verify-track.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * AskUserBridge — bridges train-lang's host builtin call to the ccweb
3
+ * frontend.
4
+ *
5
+ * Flow:
6
+ * 1. .tr code calls `__ccweb_ask_user({ fields: [...] })`
7
+ * 2. train evaluates this as a builtin → call our bridge.requestInput()
8
+ * 3. bridge pushes a "track_ask_user" event (via onPush callback)
9
+ * to the WebSocket layer, which broadcasts to the frontend
10
+ * 4. frontend renders a form, user submits → POST /api/.../tracks/input
11
+ * 5. route handler calls bridge.submitInput(runId, requestId, data)
12
+ * 6. bridge resolves the pending Promise → train continues
13
+ *
14
+ * The bridge maintains one pending request per runId. Concurrent
15
+ * ask_user calls within one track would queue (only the most recent
16
+ * pending request is active). For T1 this is fine; multi-prompt would
17
+ * need a queue (T2+).
18
+ *
19
+ * Cancellation: AbortSignal aborts the pending request immediately,
20
+ * rejecting the Promise with a TrainException-shaped error.
21
+ */
22
+ import type { Value, BuiltinFunction } from '../tracks/types-train';
23
+ export interface AskUserFieldSpec {
24
+ key: string;
25
+ label: string;
26
+ type: 'text' | 'enum' | 'number' | 'bool';
27
+ variants?: string[];
28
+ placeholder?: string;
29
+ required?: boolean;
30
+ }
31
+ export interface AskUserRequest {
32
+ runId: string;
33
+ requestId: string;
34
+ fields: AskUserFieldSpec[];
35
+ }
36
+ export interface AskUserPushEvent extends AskUserRequest {
37
+ kind: 'track_ask_user';
38
+ }
39
+ export type AskUserPushFn = (event: AskUserPushEvent) => void;
40
+ export interface AskUserBridge {
41
+ /** Called from the builtin when train evaluates __ccweb_ask_user(...). */
42
+ requestInput(runId: string, spec: AskUserFieldSpec[], signal?: AbortSignal): Promise<Record<string, Value>>;
43
+ /** Called from the route handler when the user submits the form. */
44
+ submitInput(runId: string, requestId: string, data: Record<string, Value>): {
45
+ ok: boolean;
46
+ message?: string;
47
+ };
48
+ /** Reject all pending requests for a runId (e.g. on track cancel). */
49
+ cancelAllForRun(runId: string, reason?: string): void;
50
+ /** For diagnostics + tests. */
51
+ getPending(runId: string): AskUserRequest | null;
52
+ }
53
+ export declare function createAskUserBridge(onPush: AskUserPushFn): AskUserBridge;
54
+ /**
55
+ * Build the `__ccweb_ask_user` builtin function bound to this run's
56
+ * bridge + AbortSignal. Pass into TrainOptions.extraBuiltins.
57
+ */
58
+ export declare function createAskUserBuiltin(bridge: AskUserBridge, runId: string, signal?: AbortSignal): Promise<BuiltinFunction>;
59
+ //# sourceMappingURL=ask-user-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ask-user-bridge.d.ts","sourceRoot":"","sources":["../../src/tracks/ask-user-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAGnE,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAA;IACzC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,gBAAgB,EAAE,CAAA;CAC3B;AAED,MAAM,WAAW,gBAAiB,SAAQ,cAAc;IACtD,IAAI,EAAE,gBAAgB,CAAA;CACvB;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAA;AAE7D,MAAM,WAAW,aAAa;IAC5B,0EAA0E;IAC1E,YAAY,CACV,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,gBAAgB,EAAE,EACxB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAA;IAEjC,oEAAoE;IACpE,WAAW,CACT,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GAC1B;QAAE,EAAE,EAAE,OAAO,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;IAEpC,sEAAsE;IACtE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAErD,+BAA+B;IAC/B,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAAA;CACjD;AAiBD,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,CA2IxE;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,eAAe,CAAC,CAiB1B"}
@@ -0,0 +1,186 @@
1
+ "use strict";
2
+ /**
3
+ * AskUserBridge — bridges train-lang's host builtin call to the ccweb
4
+ * frontend.
5
+ *
6
+ * Flow:
7
+ * 1. .tr code calls `__ccweb_ask_user({ fields: [...] })`
8
+ * 2. train evaluates this as a builtin → call our bridge.requestInput()
9
+ * 3. bridge pushes a "track_ask_user" event (via onPush callback)
10
+ * to the WebSocket layer, which broadcasts to the frontend
11
+ * 4. frontend renders a form, user submits → POST /api/.../tracks/input
12
+ * 5. route handler calls bridge.submitInput(runId, requestId, data)
13
+ * 6. bridge resolves the pending Promise → train continues
14
+ *
15
+ * The bridge maintains one pending request per runId. Concurrent
16
+ * ask_user calls within one track would queue (only the most recent
17
+ * pending request is active). For T1 this is fine; multi-prompt would
18
+ * need a queue (T2+).
19
+ *
20
+ * Cancellation: AbortSignal aborts the pending request immediately,
21
+ * rejecting the Promise with a TrainException-shaped error.
22
+ */
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.createAskUserBridge = createAskUserBridge;
25
+ exports.createAskUserBuiltin = createAskUserBuiltin;
26
+ const train_loader_1 = require("./train-loader");
27
+ function detachSignal(entry) {
28
+ if (entry.signal && entry.signalHandler) {
29
+ entry.signal.removeEventListener('abort', entry.signalHandler);
30
+ entry.signalHandler = undefined;
31
+ }
32
+ }
33
+ function createAskUserBridge(onPush) {
34
+ const pending = new Map(); // runId → PendingRequest
35
+ function newRequestId() {
36
+ return 'req-' + Math.random().toString(36).slice(2, 10);
37
+ }
38
+ function validateSpec(spec) {
39
+ if (!Array.isArray(spec) || spec.length === 0) {
40
+ throw new Error('ask_user requires a non-empty fields array');
41
+ }
42
+ const seen = new Set();
43
+ for (const f of spec) {
44
+ if (!f.key || typeof f.key !== 'string') {
45
+ throw new Error('ask_user field missing string key');
46
+ }
47
+ if (seen.has(f.key)) {
48
+ throw new Error(`ask_user duplicate field key: ${f.key}`);
49
+ }
50
+ seen.add(f.key);
51
+ if (f.type === 'enum' && (!f.variants || f.variants.length === 0)) {
52
+ throw new Error(`ask_user enum field "${f.key}" missing variants`);
53
+ }
54
+ }
55
+ }
56
+ function validateResponse(spec, data) {
57
+ for (const f of spec) {
58
+ const v = data[f.key];
59
+ if (v === undefined && f.required !== false) {
60
+ return { ok: false, message: `missing required field: ${f.key}` };
61
+ }
62
+ if (v === undefined)
63
+ continue;
64
+ switch (f.type) {
65
+ case 'text':
66
+ if (typeof v !== 'string') {
67
+ return { ok: false, message: `${f.key}: expected string` };
68
+ }
69
+ break;
70
+ case 'number':
71
+ if (typeof v !== 'number') {
72
+ return { ok: false, message: `${f.key}: expected number` };
73
+ }
74
+ break;
75
+ case 'bool':
76
+ if (typeof v !== 'boolean') {
77
+ return { ok: false, message: `${f.key}: expected boolean` };
78
+ }
79
+ break;
80
+ case 'enum':
81
+ if (typeof v !== 'string' || !f.variants?.includes(v)) {
82
+ return {
83
+ ok: false,
84
+ message: `${f.key}: must be one of [${f.variants?.join(', ') ?? ''}]`,
85
+ };
86
+ }
87
+ break;
88
+ }
89
+ }
90
+ return { ok: true };
91
+ }
92
+ return {
93
+ requestInput(runId, spec, signal) {
94
+ validateSpec(spec);
95
+ return new Promise((resolve, reject) => {
96
+ // If a previous request for this runId is still pending,
97
+ // detach its abort listener BEFORE rejecting + replacing.
98
+ // Otherwise an abort on the old signal would `pending.delete(runId)`
99
+ // and clobber the new request.
100
+ const existing = pending.get(runId);
101
+ if (existing) {
102
+ detachSignal(existing);
103
+ pending.delete(runId);
104
+ existing.reject(new Error('superseded by new ask_user request'));
105
+ }
106
+ const request = {
107
+ runId,
108
+ requestId: newRequestId(),
109
+ fields: spec,
110
+ };
111
+ const entry = { request, resolve, reject, signal };
112
+ if (signal) {
113
+ if (signal.aborted) {
114
+ reject(new Error('ask_user cancelled'));
115
+ return;
116
+ }
117
+ // The handler validates that THIS entry is still the active one
118
+ // before mutating the map (defense in depth — supersede path above
119
+ // already detaches, but a separate abort + supersede race could
120
+ // still try to fire stale handlers).
121
+ entry.signalHandler = () => {
122
+ const current = pending.get(runId);
123
+ if (current === entry) {
124
+ pending.delete(runId);
125
+ reject(new Error('ask_user cancelled'));
126
+ }
127
+ };
128
+ signal.addEventListener('abort', entry.signalHandler, { once: true });
129
+ }
130
+ pending.set(runId, entry);
131
+ onPush({ kind: 'track_ask_user', ...request });
132
+ });
133
+ },
134
+ submitInput(runId, requestId, data) {
135
+ const entry = pending.get(runId);
136
+ if (!entry) {
137
+ return { ok: false, message: `no pending ask_user for runId=${runId}` };
138
+ }
139
+ if (entry.request.requestId !== requestId) {
140
+ return {
141
+ ok: false,
142
+ message: `requestId mismatch (expected ${entry.request.requestId}, got ${requestId})`,
143
+ };
144
+ }
145
+ const v = validateResponse(entry.request.fields, data);
146
+ if (!v.ok)
147
+ return v;
148
+ pending.delete(runId);
149
+ detachSignal(entry);
150
+ entry.resolve(data);
151
+ return { ok: true };
152
+ },
153
+ cancelAllForRun(runId, reason = 'cancelled') {
154
+ const entry = pending.get(runId);
155
+ if (!entry)
156
+ return;
157
+ pending.delete(runId);
158
+ detachSignal(entry);
159
+ entry.reject(new Error(`ask_user ${reason}`));
160
+ },
161
+ getPending(runId) {
162
+ return pending.get(runId)?.request ?? null;
163
+ },
164
+ };
165
+ }
166
+ /**
167
+ * Build the `__ccweb_ask_user` builtin function bound to this run's
168
+ * bridge + AbortSignal. Pass into TrainOptions.extraBuiltins.
169
+ */
170
+ async function createAskUserBuiltin(bridge, runId, signal) {
171
+ return (0, train_loader_1.makeBuiltinDynamic)('__ccweb_ask_user', async (args) => {
172
+ // args[0] is the spec object passed from .tr:
173
+ // __ccweb_ask_user({ fields: [...] })
174
+ const arg = args[0];
175
+ if (!arg || typeof arg !== 'object') {
176
+ throw new Error('__ccweb_ask_user expects 1 argument: { fields: [...] }');
177
+ }
178
+ const fields = arg.fields;
179
+ if (!Array.isArray(fields)) {
180
+ throw new Error('__ccweb_ask_user spec.fields must be an array');
181
+ }
182
+ const result = await bridge.requestInput(runId, fields, signal);
183
+ return result;
184
+ });
185
+ }
186
+ //# sourceMappingURL=ask-user-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ask-user-bridge.js","sourceRoot":"","sources":["../../src/tracks/ask-user-bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * CcwebTrainAdapter — bridges train-lang's LLMAdapter interface to
3
+ * ccweb's PTY + workflow_data.json infrastructure.
4
+ *
5
+ * Paradigm: writesWorkflowData=true (agent CLI). train-lang composes
6
+ * the [System][Inputs][Task][Outputs] prompt; ccweb appends a
7
+ * writeProtocolHint that tells the LLM to write outputs into
8
+ * `.ccweb/workflow_data.json` at `variables.<name>`, then signal
9
+ * completion via `task_progress.push({...finish:true})`.
10
+ *
11
+ * 详见 ~/Obsidian/Base/cc-web/工作轨重构规划.md §5。
12
+ */
13
+ import type { LLMAdapter } from '@train-lang/adapter-spec';
14
+ import type { WorkflowDataWatcher } from './workflow-data-watcher';
15
+ export interface CcwebAdapterDeps {
16
+ projectId: string;
17
+ runId: string;
18
+ /** Inject text into the project's active CLI PTY. */
19
+ injector: (text: string) => Promise<void> | void;
20
+ /** Watcher for `.ccweb/workflow_data.json`. */
21
+ watcher: WorkflowDataWatcher;
22
+ /** Per-run monotonic counter assigning task_progress[] index. */
23
+ nextTaskIndex: () => number;
24
+ /** Optional logger (pino-compatible interface). */
25
+ logger?: {
26
+ debug?: (msg: string, ...args: unknown[]) => void;
27
+ info?: (msg: string, ...args: unknown[]) => void;
28
+ warn?: (msg: string, ...args: unknown[]) => void;
29
+ error?: (msg: string, ...args: unknown[]) => void;
30
+ };
31
+ }
32
+ /**
33
+ * The writeProtocolHint string injected into train's prompt. ccweb's
34
+ * single authoritative "how to write back" instruction — replaces
35
+ * train's default `stack[<callId>].outputs` hint (which doesn't match
36
+ * ccweb v2 schema).
37
+ */
38
+ export declare function buildCcwebWriteProtocolHint(): string;
39
+ export declare function createCcwebTrainAdapter(deps: CcwebAdapterDeps): LLMAdapter;
40
+ //# sourceMappingURL=ccweb-train-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ccweb-train-adapter.d.ts","sourceRoot":"","sources":["../../src/tracks/ccweb-train-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EACV,UAAU,EAGX,MAAM,0BAA0B,CAAA;AACjC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAA;AAElE,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;IACb,qDAAqD;IACrD,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAChD,+CAA+C;IAC/C,OAAO,EAAE,mBAAmB,CAAA;IAC5B,iEAAiE;IACjE,aAAa,EAAE,MAAM,MAAM,CAAA;IAC3B,mDAAmD;IACnD,MAAM,CAAC,EAAE;QACP,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;QACjD,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;QAChD,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;QAChD,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;KAClD,CAAA;CACF;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,IAAI,MAAM,CAapD;AA+BD,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,gBAAgB,GAAG,UAAU,CAgE1E"}
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ /**
3
+ * CcwebTrainAdapter — bridges train-lang's LLMAdapter interface to
4
+ * ccweb's PTY + workflow_data.json infrastructure.
5
+ *
6
+ * Paradigm: writesWorkflowData=true (agent CLI). train-lang composes
7
+ * the [System][Inputs][Task][Outputs] prompt; ccweb appends a
8
+ * writeProtocolHint that tells the LLM to write outputs into
9
+ * `.ccweb/workflow_data.json` at `variables.<name>`, then signal
10
+ * completion via `task_progress.push({...finish:true})`.
11
+ *
12
+ * 详见 ~/Obsidian/Base/cc-web/工作轨重构规划.md §5。
13
+ */
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.buildCcwebWriteProtocolHint = buildCcwebWriteProtocolHint;
16
+ exports.createCcwebTrainAdapter = createCcwebTrainAdapter;
17
+ /**
18
+ * The writeProtocolHint string injected into train's prompt. ccweb's
19
+ * single authoritative "how to write back" instruction — replaces
20
+ * train's default `stack[<callId>].outputs` hint (which doesn't match
21
+ * ccweb v2 schema).
22
+ */
23
+ function buildCcwebWriteProtocolHint() {
24
+ return [
25
+ '[Write outputs to .ccweb/workflow_data.json, then signal completion:]',
26
+ ' 1. For each declared output `<name>` in [Required outputs] above:',
27
+ ' set variables.<name> = <your value matching the declared type>',
28
+ ' 2. Append to task_progress:',
29
+ ' { nodeId: <taskIndex from prompt header>, name: "<fai name>", ' +
30
+ 'finish: true, finishedAt: <unix ms> }',
31
+ '',
32
+ 'Do NOT touch other variables. Do NOT modify constants. Do NOT remove ' +
33
+ 'existing task_progress entries.',
34
+ 'After writing, the train runtime will read variables.<name> and continue.',
35
+ ].join('\n');
36
+ }
37
+ /**
38
+ * Compose the ccweb-specific prompt prefix that identifies the current
39
+ * call's taskIndex (for the writeProtocolHint instructions to reference).
40
+ *
41
+ * This is prepended (NOT appended) to the prompt train already composed,
42
+ * so it's visible above [Required outputs].
43
+ */
44
+ function buildCcwebHeader(taskIndex, fnName) {
45
+ return `[ccweb track context]\n taskIndex = ${taskIndex}\n fai = ${fnName}\n`;
46
+ }
47
+ /**
48
+ * Filter workflow_data.variables to just the outputs declared on the
49
+ * fai call. Extra keys are ignored (train validator will catch missing
50
+ * keys as schema mismatch).
51
+ */
52
+ function pickOutputs(variables, outputSchema) {
53
+ const out = {};
54
+ for (const key of Object.keys(outputSchema)) {
55
+ if (key in variables) {
56
+ out[key] = variables[key];
57
+ }
58
+ }
59
+ return out;
60
+ }
61
+ function createCcwebTrainAdapter(deps) {
62
+ return {
63
+ name: 'ccweb',
64
+ version: '0.0.0',
65
+ capabilities: {
66
+ parallel: false, // one CLI process per project
67
+ cancellation: true, // honors req.options.signal
68
+ writesWorkflowData: true,
69
+ },
70
+ async call(req) {
71
+ const taskIndex = deps.nextTaskIndex();
72
+ deps.logger?.debug?.('[CcwebTrainAdapter] dispatch', { fnName: req.fnName, taskIndex, callId: req.callId, attempt: req.options.attempt });
73
+ // Compose final prompt = ccweb header + train's prompt (which
74
+ // already includes writeProtocolHint from RunOptions).
75
+ const finalPrompt = buildCcwebHeader(taskIndex, req.fnName) + '\n' + req.prompt;
76
+ // 1. Inject into PTY
77
+ try {
78
+ await deps.injector(finalPrompt);
79
+ }
80
+ catch (e) {
81
+ return {
82
+ kind: 'error',
83
+ message: `ccweb adapter: failed to inject prompt: ${e.message}`,
84
+ recoverable: false,
85
+ };
86
+ }
87
+ // 2. Wait for task_progress[taskIndex].finish=true
88
+ const outcome = await deps.watcher.waitForFinish(taskIndex, req.options.timeoutMs, req.options.signal);
89
+ if (outcome.kind === 'timeout') {
90
+ deps.logger?.warn?.('[CcwebTrainAdapter] timeout', { taskIndex });
91
+ return { kind: 'timeout' };
92
+ }
93
+ if (outcome.kind === 'cancelled') {
94
+ deps.logger?.info?.('[CcwebTrainAdapter] cancelled', { taskIndex });
95
+ return { kind: 'cancelled' };
96
+ }
97
+ if (outcome.kind === 'error') {
98
+ return {
99
+ kind: 'error',
100
+ message: `ccweb adapter: watcher error: ${outcome.message}`,
101
+ recoverable: false,
102
+ };
103
+ }
104
+ // 3. Read outputs from workflow_data.variables
105
+ const outputs = pickOutputs(outcome.data.variables ?? {}, req.outputs);
106
+ deps.logger?.debug?.('[CcwebTrainAdapter] success', { taskIndex, outputKeys: Object.keys(outputs) });
107
+ return { kind: 'success', outputs };
108
+ },
109
+ };
110
+ }
111
+ //# sourceMappingURL=ccweb-train-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ccweb-train-adapter.js","sourceRoot":"","sources":["../../src/tracks/ccweb-train-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Cross-subsystem lock between flows and tracks.
3
+ *
4
+ * Both flows/runner.ts and tracks/registry.ts write
5
+ * <project>/.ccweb/workflow_data.json. Concurrent runs on the same
6
+ * project would corrupt that file (RMW race). This module exposes a
7
+ * small registry so each side can ask "is the other currently running
8
+ * on this project?" without creating an import cycle between
9
+ * routes/flows.ts and routes/tracks.ts or between flows/runner.ts and
10
+ * tracks/registry.ts.
11
+ *
12
+ * Usage:
13
+ * - index.ts constructs `trackRegistry` and calls
14
+ * `setTrackRunningProbe((pid) => trackRegistry.isRunning(pid))`
15
+ * - routes/flows.ts's run handler calls `isTrackRunning(pid)` before
16
+ * starting a flow; rejects with 409 if a track is in flight.
17
+ * - routes/tracks.ts's run handler imports flowRunner directly
18
+ * (already in the same module graph) and calls
19
+ * `flowRunner.isRunning(pid)` before starting a track.
20
+ *
21
+ * The asymmetry (flows side uses a probe, tracks side imports
22
+ * flowRunner) is intentional: flowRunner has been a stable module
23
+ * singleton since v1; trackRegistry was created later inside index.ts
24
+ * to avoid leaking PTY infra into module init.
25
+ */
26
+ type RunningProbe = (projectId: string) => boolean;
27
+ export declare function setTrackRunningProbe(fn: RunningProbe): void;
28
+ export declare function isTrackRunning(projectId: string): boolean;
29
+ export {};
30
+ //# sourceMappingURL=cross-lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cross-lock.d.ts","sourceRoot":"","sources":["../../src/tracks/cross-lock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,KAAK,YAAY,GAAG,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAA;AAIlD,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAE3D;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAOzD"}