@tom2012/cc-web 2026.5.14-a → 2026.5.15-a
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/backend/dist/index.d.ts.map +1 -1
- package/backend/dist/index.js +51 -0
- package/backend/dist/index.js.map +1 -1
- package/backend/dist/routes/flows.d.ts.map +1 -1
- package/backend/dist/routes/flows.js +10 -0
- package/backend/dist/routes/flows.js.map +1 -1
- package/backend/dist/routes/global-tracks.d.ts +11 -0
- package/backend/dist/routes/global-tracks.d.ts.map +1 -0
- package/backend/dist/routes/global-tracks.js +86 -0
- package/backend/dist/routes/global-tracks.js.map +1 -0
- package/backend/dist/routes/tracks.d.ts +14 -0
- package/backend/dist/routes/tracks.d.ts.map +1 -0
- package/backend/dist/routes/tracks.js +184 -0
- package/backend/dist/routes/tracks.js.map +1 -0
- package/backend/dist/tracks/__tests__/verify-track-t1.d.ts +11 -0
- package/backend/dist/tracks/__tests__/verify-track-t1.d.ts.map +1 -0
- package/backend/dist/tracks/__tests__/verify-track-t1.js +293 -0
- package/backend/dist/tracks/__tests__/verify-track-t1.js.map +1 -0
- package/backend/dist/tracks/__tests__/verify-track.d.ts +20 -0
- package/backend/dist/tracks/__tests__/verify-track.d.ts.map +1 -0
- package/backend/dist/tracks/__tests__/verify-track.js +187 -0
- package/backend/dist/tracks/__tests__/verify-track.js.map +1 -0
- package/backend/dist/tracks/ask-user-bridge.d.ts +59 -0
- package/backend/dist/tracks/ask-user-bridge.d.ts.map +1 -0
- package/backend/dist/tracks/ask-user-bridge.js +186 -0
- package/backend/dist/tracks/ask-user-bridge.js.map +1 -0
- package/backend/dist/tracks/ccweb-train-adapter.d.ts +40 -0
- package/backend/dist/tracks/ccweb-train-adapter.d.ts.map +1 -0
- package/backend/dist/tracks/ccweb-train-adapter.js +111 -0
- package/backend/dist/tracks/ccweb-train-adapter.js.map +1 -0
- package/backend/dist/tracks/cross-lock.d.ts +30 -0
- package/backend/dist/tracks/cross-lock.d.ts.map +1 -0
- package/backend/dist/tracks/cross-lock.js +44 -0
- package/backend/dist/tracks/cross-lock.js.map +1 -0
- package/backend/dist/tracks/index.d.ts +20 -0
- package/backend/dist/tracks/index.d.ts.map +1 -0
- package/backend/dist/tracks/index.js +42 -0
- package/backend/dist/tracks/index.js.map +1 -0
- package/backend/dist/tracks/registry.d.ts +56 -0
- package/backend/dist/tracks/registry.d.ts.map +1 -0
- package/backend/dist/tracks/registry.js +161 -0
- package/backend/dist/tracks/registry.js.map +1 -0
- package/backend/dist/tracks/store.d.ts +37 -0
- package/backend/dist/tracks/store.d.ts.map +1 -0
- package/backend/dist/tracks/store.js +254 -0
- package/backend/dist/tracks/store.js.map +1 -0
- package/backend/dist/tracks/track-runner.d.ts +62 -0
- package/backend/dist/tracks/track-runner.d.ts.map +1 -0
- package/backend/dist/tracks/track-runner.js +134 -0
- package/backend/dist/tracks/track-runner.js.map +1 -0
- package/backend/dist/tracks/train-loader.d.ts +44 -0
- package/backend/dist/tracks/train-loader.d.ts.map +1 -0
- package/backend/dist/tracks/train-loader.js +32 -0
- package/backend/dist/tracks/train-loader.js.map +1 -0
- package/backend/dist/tracks/types-train.d.ts +12 -0
- package/backend/dist/tracks/types-train.d.ts.map +1 -0
- package/backend/dist/tracks/types-train.js +13 -0
- package/backend/dist/tracks/types-train.js.map +1 -0
- package/backend/dist/tracks/types.d.ts +66 -0
- package/backend/dist/tracks/types.d.ts.map +1 -0
- package/backend/dist/tracks/types.js +12 -0
- package/backend/dist/tracks/types.js.map +1 -0
- package/backend/dist/tracks/workflow-data-watcher.d.ts +47 -0
- package/backend/dist/tracks/workflow-data-watcher.d.ts.map +1 -0
- package/backend/dist/tracks/workflow-data-watcher.js +166 -0
- package/backend/dist/tracks/workflow-data-watcher.js.map +1 -0
- package/backend/package-lock.json +107 -0
- package/backend/package.json +6 -1
- package/backend/vendor/@train-lang/adapter-spec/dist/index.d.ts +164 -0
- package/backend/vendor/@train-lang/adapter-spec/dist/index.d.ts.map +1 -0
- package/backend/vendor/@train-lang/adapter-spec/dist/index.js +13 -0
- package/backend/vendor/@train-lang/adapter-spec/dist/index.js.map +1 -0
- package/backend/vendor/@train-lang/adapter-spec/package.json +15 -0
- package/backend/vendor/@train-lang/core/dist/ast-cache.d.ts +74 -0
- package/backend/vendor/@train-lang/core/dist/ast-cache.d.ts.map +1 -0
- package/backend/vendor/@train-lang/core/dist/ast-cache.js +157 -0
- package/backend/vendor/@train-lang/core/dist/ast-cache.js.map +1 -0
- package/backend/vendor/@train-lang/core/dist/ast.d.ts +350 -0
- package/backend/vendor/@train-lang/core/dist/ast.d.ts.map +1 -0
- package/backend/vendor/@train-lang/core/dist/ast.js +15 -0
- package/backend/vendor/@train-lang/core/dist/ast.js.map +1 -0
- package/backend/vendor/@train-lang/core/dist/builder.d.ts +21 -0
- package/backend/vendor/@train-lang/core/dist/builder.d.ts.map +1 -0
- package/backend/vendor/@train-lang/core/dist/builder.js +1221 -0
- package/backend/vendor/@train-lang/core/dist/builder.js.map +1 -0
- package/backend/vendor/@train-lang/core/dist/builtins.d.ts +17 -0
- package/backend/vendor/@train-lang/core/dist/builtins.d.ts.map +1 -0
- package/backend/vendor/@train-lang/core/dist/builtins.js +488 -0
- package/backend/vendor/@train-lang/core/dist/builtins.js.map +1 -0
- package/backend/vendor/@train-lang/core/dist/index.d.ts +54 -0
- package/backend/vendor/@train-lang/core/dist/index.d.ts.map +1 -0
- package/backend/vendor/@train-lang/core/dist/index.js +66 -0
- package/backend/vendor/@train-lang/core/dist/index.js.map +1 -0
- package/backend/vendor/@train-lang/core/dist/interpreter.d.ts +110 -0
- package/backend/vendor/@train-lang/core/dist/interpreter.d.ts.map +1 -0
- package/backend/vendor/@train-lang/core/dist/interpreter.js +894 -0
- package/backend/vendor/@train-lang/core/dist/interpreter.js.map +1 -0
- package/backend/vendor/@train-lang/core/dist/lexer.d.ts +88 -0
- package/backend/vendor/@train-lang/core/dist/lexer.d.ts.map +1 -0
- package/backend/vendor/@train-lang/core/dist/lexer.js +243 -0
- package/backend/vendor/@train-lang/core/dist/lexer.js.map +1 -0
- package/backend/vendor/@train-lang/core/dist/module-loader.d.ts +74 -0
- package/backend/vendor/@train-lang/core/dist/module-loader.d.ts.map +1 -0
- package/backend/vendor/@train-lang/core/dist/module-loader.js +134 -0
- package/backend/vendor/@train-lang/core/dist/module-loader.js.map +1 -0
- package/backend/vendor/@train-lang/core/dist/parser.d.ts +135 -0
- package/backend/vendor/@train-lang/core/dist/parser.d.ts.map +1 -0
- package/backend/vendor/@train-lang/core/dist/parser.js +838 -0
- package/backend/vendor/@train-lang/core/dist/parser.js.map +1 -0
- package/backend/vendor/@train-lang/core/dist/prompt-composer.d.ts +49 -0
- package/backend/vendor/@train-lang/core/dist/prompt-composer.d.ts.map +1 -0
- package/backend/vendor/@train-lang/core/dist/prompt-composer.js +159 -0
- package/backend/vendor/@train-lang/core/dist/prompt-composer.js.map +1 -0
- package/backend/vendor/@train-lang/core/dist/runtime.d.ts +146 -0
- package/backend/vendor/@train-lang/core/dist/runtime.d.ts.map +1 -0
- package/backend/vendor/@train-lang/core/dist/runtime.js +156 -0
- package/backend/vendor/@train-lang/core/dist/runtime.js.map +1 -0
- package/backend/vendor/@train-lang/core/dist/type-descriptor.d.ts +18 -0
- package/backend/vendor/@train-lang/core/dist/type-descriptor.d.ts.map +1 -0
- package/backend/vendor/@train-lang/core/dist/type-descriptor.js +94 -0
- package/backend/vendor/@train-lang/core/dist/type-descriptor.js.map +1 -0
- package/backend/vendor/@train-lang/core/dist/validation.d.ts +44 -0
- package/backend/vendor/@train-lang/core/dist/validation.d.ts.map +1 -0
- package/backend/vendor/@train-lang/core/dist/validation.js +271 -0
- package/backend/vendor/@train-lang/core/dist/validation.js.map +1 -0
- package/backend/vendor/@train-lang/core/package.json +35 -0
- package/frontend/dist/assets/{ChatOverlay-DsfZXjjz.js → ChatOverlay-D0AFod2I.js} +1 -1
- package/frontend/dist/assets/{GraphPreview-BGZHA8KW.js → GraphPreview-BTnlkocf.js} +2 -2
- package/frontend/dist/assets/{MobilePage-B-FiVfUE.js → MobilePage-CnjdRqIt.js} +3 -3
- package/frontend/dist/assets/{OfficePreview-CvHPeAlI.js → OfficePreview-nTZKPD9R.js} +2 -2
- package/frontend/dist/assets/{PdfPreview-D1OVG7jG.js → PdfPreview-DlB-s5M8.js} +1 -1
- package/frontend/dist/assets/{ProjectPage-CyKEenc5.js → ProjectPage-C_3_sZbd.js} +5 -5
- package/frontend/dist/assets/{SettingsPage-CIe3HZml.js → SettingsPage-BYSCQKoh.js} +2 -2
- package/frontend/dist/assets/{SkillHubPage-CG1-G4Pf.js → SkillHubPage-CUgZXyeE.js} +3 -3
- package/frontend/dist/assets/TrackEditor-R2lmPugZ.js +14 -0
- package/frontend/dist/assets/abap-LPLW346S.js +7 -0
- package/frontend/dist/assets/apex-Dk-jUCUV.js +7 -0
- package/frontend/dist/assets/azcli-DPUMmPlX.js +7 -0
- package/frontend/dist/assets/bat-C1Qbg1bV.js +7 -0
- package/frontend/dist/assets/bicep-D-e-VSJi.js +7 -0
- package/frontend/dist/assets/cameligo-CjUqTgqL.js +7 -0
- package/frontend/dist/assets/{chevron-down-CS7uu2Ol.js → chevron-down-Bc6Xpnnk.js} +1 -1
- package/frontend/dist/assets/clojure-BWsu6Kju.js +7 -0
- package/frontend/dist/assets/codicon-DCmgc-ay.ttf +0 -0
- package/frontend/dist/assets/coffee-DeC36AK3.js +7 -0
- package/frontend/dist/assets/cpp-DcZnmBWT.js +7 -0
- package/frontend/dist/assets/csharp-DqBXBMf0.js +7 -0
- package/frontend/dist/assets/csp-CkO7y8ul.js +7 -0
- package/frontend/dist/assets/css-OAcfVtED.js +7 -0
- package/frontend/dist/assets/cssMode-oT-78_Ke.js +7 -0
- package/frontend/dist/assets/cypher-40UGrUjD.js +7 -0
- package/frontend/dist/assets/dart-DmixyLor.js +7 -0
- package/frontend/dist/assets/dockerfile-CayO4nTA.js +7 -0
- package/frontend/dist/assets/ecl-DRrKCuVc.js +7 -0
- package/frontend/dist/assets/editor-B5EY1bb8.css +1 -0
- package/frontend/dist/assets/editor.main-CKHkO4rf.js +37 -0
- package/frontend/dist/assets/elixir-J3qpp9mX.js +7 -0
- package/frontend/dist/assets/flow9-DzW2c4Im.js +7 -0
- package/frontend/dist/assets/freemarker2-gLqtlSdW.js +7 -0
- package/frontend/dist/assets/fsharp-D00tn_6c.js +7 -0
- package/frontend/dist/assets/go-NnNmgWK_.js +7 -0
- package/frontend/dist/assets/graphql-C9_--VLF.js +7 -0
- package/frontend/dist/assets/handlebars-CMR-cKzv.js +7 -0
- package/frontend/dist/assets/hcl-BhbOULbp.js +7 -0
- package/frontend/dist/assets/html-er6LXl7Q.js +7 -0
- package/frontend/dist/assets/htmlMode-BY7CWp3G.js +7 -0
- package/frontend/dist/assets/index-BmPb0Wl1.css +1 -0
- package/frontend/dist/assets/{index-DN91i4kg.js → index-C6JmYBh3.js} +1 -1
- package/frontend/dist/assets/{index-BThL9NV3.js → index-C7QaGdFu.js} +2 -2
- package/frontend/dist/assets/{index-DCc5jmus.js → index-CuoDBJ4_.js} +1 -1
- package/frontend/dist/assets/index-LxjrLxfp.js +1 -0
- package/frontend/dist/assets/ini-zR-_X5iG.js +7 -0
- package/frontend/dist/assets/java-CSTjsyoZ.js +7 -0
- package/frontend/dist/assets/javascript-R0QZ7Rw2.js +7 -0
- package/frontend/dist/assets/jsonMode-dh6Js0Qv.js +7 -0
- package/frontend/dist/assets/{jszip.min-DHcltCpp.js → jszip.min-D7W3wEX7.js} +1 -1
- package/frontend/dist/assets/julia-DioMOKVu.js +7 -0
- package/frontend/dist/assets/kotlin-Dsb0PKmW.js +7 -0
- package/frontend/dist/assets/less-CZYLoAVD.js +7 -0
- package/frontend/dist/assets/lexon-d5JUiwNk.js +7 -0
- package/frontend/dist/assets/liquid-ggFR895M.js +7 -0
- package/frontend/dist/assets/lua-1Al72GG8.js +7 -0
- package/frontend/dist/assets/m3-hx1xCPC3.js +7 -0
- package/frontend/dist/assets/markdown-DPGrH1xZ.js +7 -0
- package/frontend/dist/assets/mdx-B4WBy0Yh.js +7 -0
- package/frontend/dist/assets/mips-CYbZjkIm.js +7 -0
- package/frontend/dist/assets/msdax-DAioKM5A.js +7 -0
- package/frontend/dist/assets/mysql-7e9GUebS.js +7 -0
- package/frontend/dist/assets/objective-c-BGf8QNjz.js +7 -0
- package/frontend/dist/assets/pascal-hEDRz3un.js +7 -0
- package/frontend/dist/assets/pascaligo-gqEhN6pG.js +7 -0
- package/frontend/dist/assets/perl-CN8Ht9Vk.js +7 -0
- package/frontend/dist/assets/pgsql-CRCqHQBx.js +7 -0
- package/frontend/dist/assets/php-DTZrlAwe.js +7 -0
- package/frontend/dist/assets/pla-CRmh4UcC.js +7 -0
- package/frontend/dist/assets/postiats-Car2G7g8.js +7 -0
- package/frontend/dist/assets/powerquery-BJKl8V3o.js +7 -0
- package/frontend/dist/assets/powershell-Du7a_J7r.js +7 -0
- package/frontend/dist/assets/protobuf-ChneWI0H.js +7 -0
- package/frontend/dist/assets/pug-BH6LSJaf.js +7 -0
- package/frontend/dist/assets/python-AIGmVleM.js +7 -0
- package/frontend/dist/assets/qsharp-CU-Hxpxi.js +7 -0
- package/frontend/dist/assets/r-Bw-W15zh.js +7 -0
- package/frontend/dist/assets/razor-BGAZW957.js +7 -0
- package/frontend/dist/assets/redis-bY-X9-ol.js +7 -0
- package/frontend/dist/assets/redshift-CMu3ubbS.js +7 -0
- package/frontend/dist/assets/restructuredtext-KNkiWGNN.js +7 -0
- package/frontend/dist/assets/ruby-dQWMhU86.js +7 -0
- package/frontend/dist/assets/rust-BAcHhnEU.js +7 -0
- package/frontend/dist/assets/sb-Bidr5w2z.js +7 -0
- package/frontend/dist/assets/scala-imTtxsGY.js +7 -0
- package/frontend/dist/assets/scheme-BY-WHKiB.js +7 -0
- package/frontend/dist/assets/scss-NDoRP52C.js +7 -0
- package/frontend/dist/assets/{select-C09dwvOR.js → select-B9gOzVx5.js} +1 -1
- package/frontend/dist/assets/shell-DrIjotnh.js +7 -0
- package/frontend/dist/assets/solidity-DTahNycF.js +7 -0
- package/frontend/dist/assets/sophia-DtyrjGkZ.js +7 -0
- package/frontend/dist/assets/sparql-CFuS5E3z.js +7 -0
- package/frontend/dist/assets/sql-BRxcnbRv.js +7 -0
- package/frontend/dist/assets/st-Dz4uh7MK.js +7 -0
- package/frontend/dist/assets/swift-Digsrw1G.js +11 -0
- package/frontend/dist/assets/systemverilog-7TDrkMau.js +7 -0
- package/frontend/dist/assets/tcl-BtaFcnDi.js +7 -0
- package/frontend/dist/assets/tsMode-UrEEwBkN.js +7 -0
- package/frontend/dist/assets/twig-Deid_oBs.js +7 -0
- package/frontend/dist/assets/typescript-BTfMCp5C.js +7 -0
- package/frontend/dist/assets/typespec-zUaxhbG8.js +7 -0
- package/frontend/dist/assets/{user-Bj8X-WCQ.js → user-BG-Xqf8M.js} +1 -1
- package/frontend/dist/assets/vb-DK0rKJzo.js +7 -0
- package/frontend/dist/assets/wgsl-B8fNVlOQ.js +7 -0
- package/frontend/dist/assets/xml-BCL5DPdB.js +7 -0
- package/frontend/dist/assets/yaml-B__nW1c2.js +7 -0
- package/frontend/dist/index.html +2 -2
- package/package.json +2 -1
- package/frontend/dist/assets/index-BkQ6KI1l.css +0 -1
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* /api/projects/:projectId/tracks/* routes — track CRUD + runtime.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors backend/src/routes/flows.ts shape, adapted for .tr source
|
|
6
|
+
* files instead of FlowDef JSON. Routes are read/write of UTF-8 text,
|
|
7
|
+
* no per-node schema validation (parse errors surface at run time).
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.buildTracksRouter = buildTracksRouter;
|
|
11
|
+
const express_1 = require("express");
|
|
12
|
+
const config_1 = require("../config");
|
|
13
|
+
const authz_1 = require("../middleware/authz");
|
|
14
|
+
const store_1 = require("../tracks/store");
|
|
15
|
+
const runner_1 = require("../flows/runner");
|
|
16
|
+
const logger_1 = require("../logger");
|
|
17
|
+
const log = (0, logger_1.modLogger)('tracks-route');
|
|
18
|
+
function buildTracksRouter(deps) {
|
|
19
|
+
const router = (0, express_1.Router)();
|
|
20
|
+
const { registry } = deps;
|
|
21
|
+
// ── CRUD ────────────────────────────────────────────────────────────────
|
|
22
|
+
// GET /api/projects/:projectId/tracks
|
|
23
|
+
router.get('/:projectId/tracks', (0, authz_1.requireProjectOwner)('projectId'), (req, res) => {
|
|
24
|
+
const project = (0, config_1.getProject)(req.params.projectId);
|
|
25
|
+
if (!project) {
|
|
26
|
+
res.status(404).json({ error: 'Project not found' });
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
res.json({ files: (0, store_1.listTracks)(project.folderPath) });
|
|
30
|
+
});
|
|
31
|
+
// GET /api/projects/:projectId/tracks/file/:filename → { source }
|
|
32
|
+
router.get('/:projectId/tracks/file/:filename', (0, authz_1.requireProjectOwner)('projectId'), (req, res) => {
|
|
33
|
+
const project = (0, config_1.getProject)(req.params.projectId);
|
|
34
|
+
if (!project) {
|
|
35
|
+
res.status(404).json({ error: 'Project not found' });
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const safe = (0, store_1.sanitizeTrackFilename)(req.params.filename);
|
|
39
|
+
if (!safe) {
|
|
40
|
+
res.status(400).json({ error: 'invalid filename' });
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const source = (0, store_1.loadTrack)(project.folderPath, safe);
|
|
44
|
+
if (source === null) {
|
|
45
|
+
res.status(404).json({ error: 'Track not found' });
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
res.json({ filename: safe, source });
|
|
49
|
+
});
|
|
50
|
+
// PUT /api/projects/:projectId/tracks/file/:filename body: { source }
|
|
51
|
+
router.put('/:projectId/tracks/file/:filename', (0, authz_1.requireProjectOwner)('projectId'), (req, res) => {
|
|
52
|
+
const project = (0, config_1.getProject)(req.params.projectId);
|
|
53
|
+
if (!project) {
|
|
54
|
+
res.status(404).json({ error: 'Project not found' });
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const safe = (0, store_1.sanitizeTrackFilename)(req.params.filename);
|
|
58
|
+
if (!safe) {
|
|
59
|
+
res.status(400).json({ error: 'invalid filename' });
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const source = req.body?.source;
|
|
63
|
+
if (typeof source !== 'string') {
|
|
64
|
+
res.status(400).json({ error: 'body.source must be a string' });
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
// Soft size cap to prevent abuse; ~1MB is way more than any sane .tr.
|
|
68
|
+
if (source.length > 1048576) {
|
|
69
|
+
res.status(413).json({ error: 'source too large (>1MB)' });
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const ok = (0, store_1.saveTrack)(project.folderPath, safe, source);
|
|
73
|
+
log.info({ projectId: project.id, filename: safe, bytes: source.length }, 'track saved');
|
|
74
|
+
res.json({ ok });
|
|
75
|
+
});
|
|
76
|
+
// DELETE /api/projects/:projectId/tracks/file/:filename
|
|
77
|
+
router.delete('/:projectId/tracks/file/:filename', (0, authz_1.requireProjectOwner)('projectId'), (req, res) => {
|
|
78
|
+
const project = (0, config_1.getProject)(req.params.projectId);
|
|
79
|
+
if (!project) {
|
|
80
|
+
res.status(404).json({ error: 'Project not found' });
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const safe = (0, store_1.sanitizeTrackFilename)(req.params.filename);
|
|
84
|
+
if (!safe) {
|
|
85
|
+
res.status(400).json({ error: 'invalid filename' });
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const ok = (0, store_1.deleteTrack)(project.folderPath, safe);
|
|
89
|
+
log.info({ projectId: project.id, filename: safe, ok }, 'track deleted');
|
|
90
|
+
res.json({ ok });
|
|
91
|
+
});
|
|
92
|
+
// ── Runtime ─────────────────────────────────────────────────────────────
|
|
93
|
+
// POST /api/projects/:projectId/tracks/run
|
|
94
|
+
// body: { filename, source?: 'project' | 'global', args?: any[] }
|
|
95
|
+
router.post('/:projectId/tracks/run', (0, authz_1.requireProjectOwner)('projectId'), async (req, res) => {
|
|
96
|
+
const project = (0, config_1.getProject)(req.params.projectId);
|
|
97
|
+
if (!project) {
|
|
98
|
+
res.status(404).json({ error: 'Project not found' });
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const filename = typeof req.body?.filename === 'string' ? req.body.filename : '';
|
|
102
|
+
const safe = (0, store_1.sanitizeTrackFilename)(filename);
|
|
103
|
+
if (!safe) {
|
|
104
|
+
res.status(400).json({ error: 'invalid filename' });
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const source = req.body?.source === 'global' ? 'global' : 'project';
|
|
108
|
+
let absPath;
|
|
109
|
+
if (source === 'global') {
|
|
110
|
+
const username = req.user?.username;
|
|
111
|
+
if (!username) {
|
|
112
|
+
res.status(401).json({ error: 'auth required' });
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (!(0, store_1.loadGlobalTrack)(username, safe)) {
|
|
116
|
+
res.status(404).json({ error: 'Global track not found' });
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
absPath = (0, store_1.resolveGlobalTrackPath)(username, safe);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
if (!(0, store_1.loadTrack)(project.folderPath, safe)) {
|
|
123
|
+
res.status(404).json({ error: 'Track not found' });
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
absPath = (0, store_1.resolveTrackPath)(project.folderPath, safe);
|
|
127
|
+
}
|
|
128
|
+
// Cross-subsystem lock: refuse to start a track if a flow is
|
|
129
|
+
// currently running on the same project. Both subsystems write
|
|
130
|
+
// <project>/.ccweb/workflow_data.json; concurrent writes would
|
|
131
|
+
// corrupt state. The opposite check (flows refusing track) is in
|
|
132
|
+
// routes/flows.ts.
|
|
133
|
+
if (runner_1.flowRunner.isRunning(project.id)) {
|
|
134
|
+
res.status(409).json({
|
|
135
|
+
error: 'a flow is currently running on this project; abort it first',
|
|
136
|
+
});
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const args = Array.isArray(req.body?.args) ? req.body.args : [];
|
|
140
|
+
const result = await registry.start(project.id, absPath, safe, args);
|
|
141
|
+
if (!result.ok) {
|
|
142
|
+
res.status(409).json({ error: result.reason });
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
log.info({ projectId: project.id, track: safe, source, runId: result.runId }, 'track started');
|
|
146
|
+
res.json({ ok: true, runId: result.runId });
|
|
147
|
+
});
|
|
148
|
+
// POST /api/projects/:projectId/tracks/abort
|
|
149
|
+
router.post('/:projectId/tracks/abort', (0, authz_1.requireProjectOwner)('projectId'), (req, res) => {
|
|
150
|
+
const ok = registry.abort(req.params.projectId);
|
|
151
|
+
log.info({ projectId: req.params.projectId, ok }, 'track abort requested');
|
|
152
|
+
res.json({ ok });
|
|
153
|
+
});
|
|
154
|
+
// POST /api/projects/:projectId/tracks/input body: { requestId, data }
|
|
155
|
+
router.post('/:projectId/tracks/input', (0, authz_1.requireProjectOwner)('projectId'), (req, res) => {
|
|
156
|
+
const requestId = req.body?.requestId;
|
|
157
|
+
const data = req.body?.data;
|
|
158
|
+
if (typeof requestId !== 'string') {
|
|
159
|
+
res.status(400).json({ error: 'requestId is required' });
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (!data || typeof data !== 'object') {
|
|
163
|
+
res.status(400).json({ error: 'data is required' });
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
const result = registry.submitInput(req.params.projectId, requestId, data);
|
|
167
|
+
if (!result.ok) {
|
|
168
|
+
res.status(409).json({ error: result.message ?? 'submit failed' });
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
log.info({ projectId: req.params.projectId, requestId, keys: Object.keys(data).length }, 'track ask_user submitted');
|
|
172
|
+
res.json({ ok: true });
|
|
173
|
+
});
|
|
174
|
+
// GET /api/projects/:projectId/tracks/state
|
|
175
|
+
router.get('/:projectId/tracks/state', (0, authz_1.requireProjectOwner)('projectId'), (req, res) => {
|
|
176
|
+
res.json({
|
|
177
|
+
running: registry.isRunning(req.params.projectId),
|
|
178
|
+
state: registry.getState(req.params.projectId),
|
|
179
|
+
pendingAskUser: registry.getPendingAskUser(req.params.projectId),
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
return router;
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=tracks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tracks.js","sourceRoot":"","sources":["../../src/routes/tracks.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AA0BH,8CAyNC;AAjPD,qCAA0C;AAE1C,sCAAsC;AACtC,+CAAyD;AACzD,2CASwB;AAExB,4CAA4C;AAC5C,sCAAqC;AAErC,MAAM,GAAG,GAAG,IAAA,kBAAS,EAAC,cAAc,CAAC,CAAA;AAMrC,SAAgB,iBAAiB,CAAC,IAAqB;IACrD,MAAM,MAAM,GAAG,IAAA,gBAAM,GAAE,CAAA;IACvB,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAA;IAEzB,2EAA2E;IAE3E,sCAAsC;IACtC,MAAM,CAAC,GAAG,CACR,oBAAoB,EACpB,IAAA,2BAAmB,EAAC,WAAW,CAAC,EAChC,CAAC,GAAgB,EAAE,GAAa,EAAQ,EAAE;QACxC,MAAM,OAAO,GAAG,IAAA,mBAAU,EAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QAChD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAA;YACpD,OAAM;QACR,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAA,kBAAU,EAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;IACrD,CAAC,CACF,CAAA;IAED,kEAAkE;IAClE,MAAM,CAAC,GAAG,CACR,mCAAmC,EACnC,IAAA,2BAAmB,EAAC,WAAW,CAAC,EAChC,CAAC,GAAgB,EAAE,GAAa,EAAQ,EAAE;QACxC,MAAM,OAAO,GAAG,IAAA,mBAAU,EAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QAChD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAA;YACpD,OAAM;QACR,CAAC;QACD,MAAM,IAAI,GAAG,IAAA,6BAAqB,EAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QACvD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAA;YACnD,OAAM;QACR,CAAC;QACD,MAAM,MAAM,GAAG,IAAA,iBAAS,EAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;QAClD,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAA;YAClD,OAAM;QACR,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;IACtC,CAAC,CACF,CAAA;IAED,uEAAuE;IACvE,MAAM,CAAC,GAAG,CACR,mCAAmC,EACnC,IAAA,2BAAmB,EAAC,WAAW,CAAC,EAChC,CAAC,GAAgB,EAAE,GAAa,EAAQ,EAAE;QACxC,MAAM,OAAO,GAAG,IAAA,mBAAU,EAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QAChD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAA;YACpD,OAAM;QACR,CAAC;QACD,MAAM,IAAI,GAAG,IAAA,6BAAqB,EAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QACvD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAA;YACnD,OAAM;QACR,CAAC;QACD,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,MAAM,CAAA;QAC/B,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC/B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,8BAA8B,EAAE,CAAC,CAAA;YAC/D,OAAM;QACR,CAAC;QACD,sEAAsE;QACtE,IAAI,MAAM,CAAC,MAAM,GAAG,OAAS,EAAE,CAAC;YAC9B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,yBAAyB,EAAE,CAAC,CAAA;YAC1D,OAAM;QACR,CAAC;QACD,MAAM,EAAE,GAAG,IAAA,iBAAS,EAAC,OAAO,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;QACtD,GAAG,CAAC,IAAI,CACN,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,EAC/D,aAAa,CACd,CAAA;QACD,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IAClB,CAAC,CACF,CAAA;IAED,wDAAwD;IACxD,MAAM,CAAC,MAAM,CACX,mCAAmC,EACnC,IAAA,2BAAmB,EAAC,WAAW,CAAC,EAChC,CAAC,GAAgB,EAAE,GAAa,EAAQ,EAAE;QACxC,MAAM,OAAO,GAAG,IAAA,mBAAU,EAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QAChD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAA;YACpD,OAAM;QACR,CAAC;QACD,MAAM,IAAI,GAAG,IAAA,6BAAqB,EAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QACvD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAA;YACnD,OAAM;QACR,CAAC;QACD,MAAM,EAAE,GAAG,IAAA,mBAAW,EAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;QAChD,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,eAAe,CAAC,CAAA;QACxE,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IAClB,CAAC,CACF,CAAA;IAED,2EAA2E;IAE3E,2CAA2C;IAC3C,oEAAoE;IACpE,MAAM,CAAC,IAAI,CACT,wBAAwB,EACxB,IAAA,2BAAmB,EAAC,WAAW,CAAC,EAChC,KAAK,EAAE,GAAgB,EAAE,GAAa,EAAiB,EAAE;QACvD,MAAM,OAAO,GAAG,IAAA,mBAAU,EAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QAChD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAA;YACpD,OAAM;QACR,CAAC;QACD,MAAM,QAAQ,GAAG,OAAO,GAAG,CAAC,IAAI,EAAE,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAA;QAChF,MAAM,IAAI,GAAG,IAAA,6BAAqB,EAAC,QAAQ,CAAC,CAAA;QAC5C,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAA;YACnD,OAAM;QACR,CAAC;QACD,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAA;QACnE,IAAI,OAAe,CAAA;QACnB,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YACxB,MAAM,QAAQ,GAAG,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAA;YACnC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAA;gBAChD,OAAM;YACR,CAAC;YACD,IAAI,CAAC,IAAA,uBAAe,EAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,CAAC;gBACrC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAA;gBACzD,OAAM;YACR,CAAC;YACD,OAAO,GAAG,IAAA,8BAAsB,EAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;QAClD,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,IAAA,iBAAS,EAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,CAAC;gBACzC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC,CAAA;gBAClD,OAAM;YACR,CAAC;YACD,OAAO,GAAG,IAAA,wBAAgB,EAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAA;QACtD,CAAC;QACD,6DAA6D;QAC7D,+DAA+D;QAC/D,+DAA+D;QAC/D,iEAAiE;QACjE,mBAAmB;QACnB,IAAI,mBAAU,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;YACrC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,6DAA6D;aACrE,CAAC,CAAA;YACF,OAAM;QACR,CAAC;QACD,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA;QAC/D,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,CAAA;QACpE,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAA;YAC9C,OAAM;QACR,CAAC;QACD,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,EAAE,eAAe,CAAC,CAAA;QAC9F,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAA;IAC7C,CAAC,CACF,CAAA;IAED,6CAA6C;IAC7C,MAAM,CAAC,IAAI,CACT,0BAA0B,EAC1B,IAAA,2BAAmB,EAAC,WAAW,CAAC,EAChC,CAAC,GAAgB,EAAE,GAAa,EAAQ,EAAE;QACxC,MAAM,EAAE,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;QAC/C,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,uBAAuB,CAAC,CAAA;QAC1E,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IAClB,CAAC,CACF,CAAA;IAED,wEAAwE;IACxE,MAAM,CAAC,IAAI,CACT,0BAA0B,EAC1B,IAAA,2BAAmB,EAAC,WAAW,CAAC,EAChC,CAAC,GAAgB,EAAE,GAAa,EAAQ,EAAE;QACxC,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,EAAE,SAAS,CAAA;QACrC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,IAAI,CAAA;QAC3B,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;YAClC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC,CAAA;YACxD,OAAM;QACR,CAAC;QACD,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAA;YACnD,OAAM;QACR,CAAC;QACD,MAAM,MAAM,GAAG,QAAQ,CAAC,WAAW,CACjC,GAAG,CAAC,MAAM,CAAC,SAAS,EACpB,SAAS,EACT,IAA+B,CAChC,CAAA;QACD,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,IAAI,eAAe,EAAE,CAAC,CAAA;YAClE,OAAM;QACR,CAAC;QACD,GAAG,CAAC,IAAI,CACN,EAAE,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAC9E,0BAA0B,CAC3B,CAAA;QACD,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;IACxB,CAAC,CACF,CAAA;IAED,4CAA4C;IAC5C,MAAM,CAAC,GAAG,CACR,0BAA0B,EAC1B,IAAA,2BAAmB,EAAC,WAAW,CAAC,EAChC,CAAC,GAAgB,EAAE,GAAa,EAAQ,EAAE;QACxC,GAAG,CAAC,IAAI,CAAC;YACP,OAAO,EAAE,QAAQ,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC;YACjD,KAAK,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC;YAC9C,cAAc,EAAE,QAAQ,CAAC,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC;SACjE,CAAC,CAAA;IACJ,CAAC,CACF,CAAA;IAED,OAAO,MAAM,CAAA;AACf,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T1 verification — extends T0 with:
|
|
3
|
+
* - __ccweb_ask_user builtin闭环 (bridge → push → submit → resume)
|
|
4
|
+
* - store CRUD (list / load / save / delete)
|
|
5
|
+
* - global-tracks store CRUD
|
|
6
|
+
* - TrackRegistry start / abort / state / submitInput
|
|
7
|
+
*
|
|
8
|
+
* Run: cd backend && npx ts-node src/tracks/__tests__/verify-track-t1.ts
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=verify-track-t1.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-track-t1.d.ts","sourceRoot":"","sources":["../../../src/tracks/__tests__/verify-track-t1.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG"}
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* T1 verification — extends T0 with:
|
|
4
|
+
* - __ccweb_ask_user builtin闭环 (bridge → push → submit → resume)
|
|
5
|
+
* - store CRUD (list / load / save / delete)
|
|
6
|
+
* - global-tracks store CRUD
|
|
7
|
+
* - TrackRegistry start / abort / state / submitInput
|
|
8
|
+
*
|
|
9
|
+
* Run: cd backend && npx ts-node src/tracks/__tests__/verify-track-t1.ts
|
|
10
|
+
*/
|
|
11
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
+
}
|
|
17
|
+
Object.defineProperty(o, k2, desc);
|
|
18
|
+
}) : (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
o[k2] = m[k];
|
|
21
|
+
}));
|
|
22
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
23
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
24
|
+
}) : function(o, v) {
|
|
25
|
+
o["default"] = v;
|
|
26
|
+
});
|
|
27
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
28
|
+
var ownKeys = function(o) {
|
|
29
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
30
|
+
var ar = [];
|
|
31
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
32
|
+
return ar;
|
|
33
|
+
};
|
|
34
|
+
return ownKeys(o);
|
|
35
|
+
};
|
|
36
|
+
return function (mod) {
|
|
37
|
+
if (mod && mod.__esModule) return mod;
|
|
38
|
+
var result = {};
|
|
39
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
40
|
+
__setModuleDefault(result, mod);
|
|
41
|
+
return result;
|
|
42
|
+
};
|
|
43
|
+
})();
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
const fs = __importStar(require("fs/promises"));
|
|
46
|
+
const os = __importStar(require("os"));
|
|
47
|
+
const path = __importStar(require("path"));
|
|
48
|
+
const __1 = require("..");
|
|
49
|
+
let failed = 0;
|
|
50
|
+
function check(name, cond, msg) {
|
|
51
|
+
if (cond) {
|
|
52
|
+
console.log(` ✓ ${name}`);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
failed++;
|
|
56
|
+
console.error(` ✗ ${name}${msg ? ': ' + msg : ''}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async function readWf(p) {
|
|
60
|
+
return JSON.parse(await fs.readFile(p, 'utf8'));
|
|
61
|
+
}
|
|
62
|
+
async function writeWf(p, w) {
|
|
63
|
+
await fs.writeFile(p, JSON.stringify(w, null, 2), 'utf8');
|
|
64
|
+
}
|
|
65
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
66
|
+
async function testStore() {
|
|
67
|
+
console.log('\n=== store CRUD ===');
|
|
68
|
+
const tmpRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'ccweb-t1-store-'));
|
|
69
|
+
// Project store
|
|
70
|
+
check('listTracks empty when dir missing', (0, __1.listTracks)(tmpRoot).length === 0);
|
|
71
|
+
const ok1 = (0, __1.saveTrack)(tmpRoot, 'foo.tr', 'fai f() -> r: int { }\nexport f\n');
|
|
72
|
+
check('saveTrack returns true', ok1);
|
|
73
|
+
const list1 = (0, __1.listTracks)(tmpRoot);
|
|
74
|
+
check('list reports 1 file', list1.length === 1 && list1[0].filename === 'foo.tr');
|
|
75
|
+
const src = (0, __1.loadTrack)(tmpRoot, 'foo.tr');
|
|
76
|
+
check('loadTrack returns content', src !== null && src.includes('fai f()'));
|
|
77
|
+
check('loadTrack on missing returns null', (0, __1.loadTrack)(tmpRoot, 'bogus.tr') === null);
|
|
78
|
+
check('deleteTrack returns true', (0, __1.deleteTrack)(tmpRoot, 'foo.tr'));
|
|
79
|
+
check('list empty after delete', (0, __1.listTracks)(tmpRoot).length === 0);
|
|
80
|
+
// sanitize
|
|
81
|
+
check('sanitize accepts foo.tr', (0, __1.sanitizeTrackFilename)('foo.tr') === 'foo.tr');
|
|
82
|
+
check('sanitize adds .tr extension', (0, __1.sanitizeTrackFilename)('foo') === 'foo.tr');
|
|
83
|
+
check('sanitize rejects slash', (0, __1.sanitizeTrackFilename)('a/b.tr') === null);
|
|
84
|
+
check('sanitize rejects ..', (0, __1.sanitizeTrackFilename)('..foo.tr') === null);
|
|
85
|
+
check('sanitize rejects empty', (0, __1.sanitizeTrackFilename)('') === null);
|
|
86
|
+
check('sanitize rejects non-string', (0, __1.sanitizeTrackFilename)(42) === null);
|
|
87
|
+
// Global track store (per fake username under tmp HOME). We can't
|
|
88
|
+
// easily redirect os.homedir() in this verify script, so we test
|
|
89
|
+
// by directly using a temp user-scope dir via env trick — skip this
|
|
90
|
+
// round and only test list returns empty for an unknown user.
|
|
91
|
+
check('listGlobalTracks empty for unknown user', (0, __1.listGlobalTracks)('definitely-no-such-user-zxqv').length === 0);
|
|
92
|
+
check('loadGlobalTrack returns null for unknown user', (0, __1.loadGlobalTrack)('definitely-no-such-user-zxqv', 'foo.tr') === null);
|
|
93
|
+
await fs.rm(tmpRoot, { recursive: true, force: true });
|
|
94
|
+
}
|
|
95
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
96
|
+
async function testAskUserBridge() {
|
|
97
|
+
console.log('\n=== ask-user-bridge unit ===');
|
|
98
|
+
const pushed = [];
|
|
99
|
+
const bridge = (0, __1.createAskUserBridge)((ev) => {
|
|
100
|
+
pushed.push(ev);
|
|
101
|
+
});
|
|
102
|
+
// Validation
|
|
103
|
+
let threw = false;
|
|
104
|
+
try {
|
|
105
|
+
await bridge.requestInput('r1', []);
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
threw = true;
|
|
109
|
+
}
|
|
110
|
+
check('empty spec rejected', threw);
|
|
111
|
+
let threw2 = false;
|
|
112
|
+
try {
|
|
113
|
+
await bridge.requestInput('r2', [
|
|
114
|
+
{ key: 'x', label: 'X', type: 'enum' }, // missing variants
|
|
115
|
+
]);
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
threw2 = true;
|
|
119
|
+
}
|
|
120
|
+
check('enum without variants rejected', threw2);
|
|
121
|
+
// Happy path
|
|
122
|
+
const pending = bridge.requestInput('r3', [
|
|
123
|
+
{ key: 'name', label: 'Name', type: 'text' },
|
|
124
|
+
{ key: 'age', label: 'Age', type: 'number' },
|
|
125
|
+
]);
|
|
126
|
+
check('push event emitted', pushed.length === 1);
|
|
127
|
+
check('push event has fields', pushed[0].fields.length === 2);
|
|
128
|
+
check('push event has runId', pushed[0].runId === 'r3');
|
|
129
|
+
const reqId = pushed[0].requestId;
|
|
130
|
+
check('getPending returns the request', bridge.getPending('r3')?.requestId === reqId);
|
|
131
|
+
const submitResult = bridge.submitInput('r3', reqId, { name: 'Tom', age: 30 });
|
|
132
|
+
check('submit returned ok', submitResult.ok);
|
|
133
|
+
const got = await pending;
|
|
134
|
+
check('promise resolved with submitted data', got.name === 'Tom' && got.age === 30);
|
|
135
|
+
check('pending cleared after submit', bridge.getPending('r3') === null);
|
|
136
|
+
// requestId mismatch
|
|
137
|
+
const p2 = bridge.requestInput('r4', [{ key: 'x', label: 'X', type: 'text' }]);
|
|
138
|
+
// wait one tick so push happens
|
|
139
|
+
await new Promise((r) => setImmediate(r));
|
|
140
|
+
const reqId2 = pushed[pushed.length - 1].requestId;
|
|
141
|
+
const wrongResult = bridge.submitInput('r4', 'wrong-id', { x: 'y' });
|
|
142
|
+
check('mismatched requestId rejected', !wrongResult.ok);
|
|
143
|
+
// Submit correct one to drain
|
|
144
|
+
bridge.submitInput('r4', reqId2, { x: 'y' });
|
|
145
|
+
await p2;
|
|
146
|
+
// Type validation
|
|
147
|
+
const p3 = bridge.requestInput('r5', [
|
|
148
|
+
{ key: 'flag', label: 'F', type: 'bool' },
|
|
149
|
+
]);
|
|
150
|
+
await new Promise((r) => setImmediate(r));
|
|
151
|
+
const reqId3 = pushed[pushed.length - 1].requestId;
|
|
152
|
+
const bad = bridge.submitInput('r5', reqId3, { flag: 'not-a-bool' });
|
|
153
|
+
check('type-mismatched submit rejected', !bad.ok && (bad.message?.includes('boolean') ?? false));
|
|
154
|
+
bridge.submitInput('r5', reqId3, { flag: true });
|
|
155
|
+
await p3;
|
|
156
|
+
// AbortSignal
|
|
157
|
+
const ac = new AbortController();
|
|
158
|
+
const p4 = bridge.requestInput('r6', [{ key: 'x', label: 'X', type: 'text' }], ac.signal);
|
|
159
|
+
await new Promise((r) => setImmediate(r));
|
|
160
|
+
ac.abort();
|
|
161
|
+
let p4ThrowMsg = '';
|
|
162
|
+
try {
|
|
163
|
+
await p4;
|
|
164
|
+
}
|
|
165
|
+
catch (e) {
|
|
166
|
+
p4ThrowMsg = e.message;
|
|
167
|
+
}
|
|
168
|
+
check('signal-aborted request rejects', p4ThrowMsg.includes('cancelled'));
|
|
169
|
+
// cancelAllForRun
|
|
170
|
+
const p5 = bridge.requestInput('r7', [{ key: 'x', label: 'X', type: 'text' }]);
|
|
171
|
+
await new Promise((r) => setImmediate(r));
|
|
172
|
+
bridge.cancelAllForRun('r7', 'manual');
|
|
173
|
+
let p5ThrowMsg = '';
|
|
174
|
+
try {
|
|
175
|
+
await p5;
|
|
176
|
+
}
|
|
177
|
+
catch (e) {
|
|
178
|
+
p5ThrowMsg = e.message;
|
|
179
|
+
}
|
|
180
|
+
check('cancelAllForRun rejects pending', p5ThrowMsg.includes('manual'));
|
|
181
|
+
}
|
|
182
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
183
|
+
async function testAskUserEndToEnd() {
|
|
184
|
+
console.log('\n=== ask_user end-to-end (.tr → bridge → submit → resume) ===');
|
|
185
|
+
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'ccweb-t1-asku-'));
|
|
186
|
+
const trackPath = path.join(tmpDir, 'asku.tr');
|
|
187
|
+
const wfPath = path.join(tmpDir, 'workflow_data.json');
|
|
188
|
+
// .tr that calls __ccweb_ask_user then returns the user's answer
|
|
189
|
+
const trSource = `
|
|
190
|
+
func main() -> string {
|
|
191
|
+
let answer = __ccweb_ask_user({
|
|
192
|
+
fields: [
|
|
193
|
+
{ key: "decision", label: "继续吗?", type: "enum", variants: ["yes", "no"] }
|
|
194
|
+
]
|
|
195
|
+
})
|
|
196
|
+
return answer.decision
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export main
|
|
200
|
+
`;
|
|
201
|
+
await fs.writeFile(trackPath, trSource, 'utf8');
|
|
202
|
+
await writeWf(wfPath, { constants: {}, variables: {}, task_progress: [] });
|
|
203
|
+
const watcher = (0, __1.createWorkflowDataWatcher)(wfPath);
|
|
204
|
+
const pushed = [];
|
|
205
|
+
const bridge = (0, __1.createAskUserBridge)((ev) => {
|
|
206
|
+
pushed.push(ev);
|
|
207
|
+
});
|
|
208
|
+
const runner = (0, __1.createTrackRunner)({
|
|
209
|
+
projectId: 'asku-proj',
|
|
210
|
+
injector: () => { }, // no fai in this .tr, injector won't fire
|
|
211
|
+
watcher,
|
|
212
|
+
askUserBridge: bridge,
|
|
213
|
+
maxFaiAttempts: 1,
|
|
214
|
+
defaultFaiTimeoutMs: 5000,
|
|
215
|
+
});
|
|
216
|
+
const runPromise = runner.run(trackPath);
|
|
217
|
+
// Wait for push event (with timeout)
|
|
218
|
+
const start = Date.now();
|
|
219
|
+
while (pushed.length === 0 && Date.now() - start < 3000) {
|
|
220
|
+
await new Promise((r) => setTimeout(r, 20));
|
|
221
|
+
}
|
|
222
|
+
check('runner pushed ask_user event', pushed.length === 1);
|
|
223
|
+
if (pushed.length === 1) {
|
|
224
|
+
check('event runId matches runner state', pushed[0].runId === runner.getState()?.runId);
|
|
225
|
+
check('event has decision field', pushed[0].fields[0].key === 'decision');
|
|
226
|
+
// Submit response
|
|
227
|
+
const reqId = pushed[0].requestId;
|
|
228
|
+
const submitResult = bridge.submitInput(pushed[0].runId, reqId, {
|
|
229
|
+
decision: 'yes',
|
|
230
|
+
});
|
|
231
|
+
check('submitInput accepted', submitResult.ok);
|
|
232
|
+
}
|
|
233
|
+
const result = await runPromise;
|
|
234
|
+
check('runner completed ok', result.ok, JSON.stringify(result.error));
|
|
235
|
+
check('runner returned the submitted decision', result.value === 'yes', `got: ${JSON.stringify(result.value)}`);
|
|
236
|
+
await fs.rm(tmpDir, { recursive: true, force: true });
|
|
237
|
+
}
|
|
238
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
239
|
+
async function testRegistry() {
|
|
240
|
+
console.log('\n=== TrackRegistry (start/abort/state/submitInput) ===');
|
|
241
|
+
const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'ccweb-t1-reg-'));
|
|
242
|
+
const projectDir = path.join(tmpDir, 'proj1');
|
|
243
|
+
await fs.mkdir(path.join(projectDir, '.ccweb'), { recursive: true });
|
|
244
|
+
const wfPath = path.join(projectDir, '.ccweb', 'workflow_data.json');
|
|
245
|
+
await writeWf(wfPath, { constants: {}, variables: {}, task_progress: [] });
|
|
246
|
+
// Create a track
|
|
247
|
+
(0, __1.saveTrack)(projectDir, 'reg.tr', `func main() -> int { return 1 }\nexport main\n`);
|
|
248
|
+
const broadcastEvents = [];
|
|
249
|
+
const registry = (0, __1.createTrackRegistry)({
|
|
250
|
+
getProjectFolder: (id) => (id === 'proj1' ? projectDir : null),
|
|
251
|
+
injectIntoPty: () => { },
|
|
252
|
+
broadcast: (projectId, msg) => {
|
|
253
|
+
broadcastEvents.push({ projectId, msg });
|
|
254
|
+
},
|
|
255
|
+
});
|
|
256
|
+
check('isRunning false initially', !registry.isRunning('proj1'));
|
|
257
|
+
check('getState null initially', registry.getState('proj1') === null);
|
|
258
|
+
check('getPendingAskUser null initially', registry.getPendingAskUser('proj1') === null);
|
|
259
|
+
const trackAbs = path.join(projectDir, '.ccweb', 'tracks', 'reg.tr');
|
|
260
|
+
const start = await registry.start('proj1', trackAbs, 'reg.tr', []);
|
|
261
|
+
check('start ok=true', start.ok && 'runId' in start);
|
|
262
|
+
// Wait for run to complete
|
|
263
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
264
|
+
const finalState = registry.getState('proj1');
|
|
265
|
+
check('final state non-null', finalState !== null);
|
|
266
|
+
check('final status is completed', finalState?.status === 'completed');
|
|
267
|
+
check('result value is 1', finalState?.result === 1);
|
|
268
|
+
check('isRunning false after completion', !registry.isRunning('proj1'));
|
|
269
|
+
// Verify broadcasts happened (status_change + run_complete)
|
|
270
|
+
const statusChanges = broadcastEvents.filter((e) => e.msg.type === 'track_status_change');
|
|
271
|
+
check('at least one track_status_change emitted', statusChanges.length >= 1);
|
|
272
|
+
const completes = broadcastEvents.filter((e) => e.msg.type === 'track_run_complete');
|
|
273
|
+
check('track_run_complete emitted', completes.length === 1);
|
|
274
|
+
// unknown project rejected
|
|
275
|
+
const bogus = await registry.start('no-such-proj', trackAbs, 'reg.tr', []);
|
|
276
|
+
check('start rejects unknown project', !bogus.ok);
|
|
277
|
+
await fs.rm(tmpDir, { recursive: true, force: true });
|
|
278
|
+
}
|
|
279
|
+
// ────────────────────────────────────────────────────────────────────────────
|
|
280
|
+
async function main() {
|
|
281
|
+
console.log('=== T1 verification ===');
|
|
282
|
+
await testStore();
|
|
283
|
+
await testAskUserBridge();
|
|
284
|
+
await testAskUserEndToEnd();
|
|
285
|
+
await testRegistry();
|
|
286
|
+
console.log(`\n${failed === 0 ? '✅ ALL T1 CHECKS PASSED' : `❌ ${failed} CHECK(S) FAILED`}`);
|
|
287
|
+
process.exit(failed === 0 ? 0 : 1);
|
|
288
|
+
}
|
|
289
|
+
main().catch((e) => {
|
|
290
|
+
console.error('verify-track-t1 crashed:', e);
|
|
291
|
+
process.exit(2);
|
|
292
|
+
});
|
|
293
|
+
//# sourceMappingURL=verify-track-t1.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-track-t1.js","sourceRoot":"","sources":["../../../src/tracks/__tests__/verify-track-t1.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T0 verification script for the Track subsystem.
|
|
3
|
+
*
|
|
4
|
+
* NOT a vitest/jest test — ccweb backend has no test framework yet.
|
|
5
|
+
* Runs as a standalone Node script to verify end-to-end:
|
|
6
|
+
*
|
|
7
|
+
* 1. TrackRunner can load a .tr file
|
|
8
|
+
* 2. train-lang composes prompt + calls CcwebTrainAdapter
|
|
9
|
+
* 3. CcwebTrainAdapter injects prompt (capture into a mock buffer)
|
|
10
|
+
* 4. We programmatically simulate the LLM writing outputs by editing
|
|
11
|
+
* workflow_data.json + setting task_progress[].finish = true
|
|
12
|
+
* 5. WorkflowDataWatcher detects the finish signal
|
|
13
|
+
* 6. Adapter reads variables.<name> → returns FaiResult.success
|
|
14
|
+
* 7. train continues execution → main() returns
|
|
15
|
+
* 8. TrackRunner reports ok=true with the returned value
|
|
16
|
+
*
|
|
17
|
+
* Run: cd backend && npx ts-node src/tracks/__tests__/verify-track.ts
|
|
18
|
+
*/
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=verify-track.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-track.d.ts","sourceRoot":"","sources":["../../../src/tracks/__tests__/verify-track.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG"}
|