veryfront 0.1.75 → 0.1.77
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 +2 -0
- package/esm/cli/commands/files/command.d.ts +3 -3
- package/esm/cli/commands/pull/command.js +2 -2
- package/esm/cli/commands/task/command.d.ts.map +1 -1
- package/esm/cli/commands/task/command.js +57 -51
- package/esm/cli/commands/workflow/command-help.d.ts +3 -0
- package/esm/cli/commands/workflow/command-help.d.ts.map +1 -0
- package/esm/cli/commands/workflow/command-help.js +19 -0
- package/esm/cli/commands/workflow/command.d.ts +5 -0
- package/esm/cli/commands/workflow/command.d.ts.map +1 -0
- package/esm/cli/commands/workflow/command.js +119 -0
- package/esm/cli/commands/workflow/handler.d.ts +28 -0
- package/esm/cli/commands/workflow/handler.d.ts.map +1 -0
- package/esm/cli/commands/workflow/handler.js +19 -0
- package/esm/cli/help/command-definitions.d.ts.map +1 -1
- package/esm/cli/help/command-definitions.js +2 -0
- package/esm/cli/router.d.ts.map +1 -1
- package/esm/cli/router.js +2 -0
- package/esm/cli/shared/project-source-context.d.ts +18 -0
- package/esm/cli/shared/project-source-context.d.ts.map +1 -0
- package/esm/cli/shared/project-source-context.js +52 -0
- package/esm/deno.d.ts +6 -0
- package/esm/deno.js +12 -6
- package/esm/src/data/server-data-fetcher.d.ts.map +1 -1
- package/esm/src/data/server-data-fetcher.js +17 -1
- package/esm/src/jobs/index.d.ts +34 -0
- package/esm/src/jobs/index.d.ts.map +1 -0
- package/esm/src/jobs/index.js +33 -0
- package/esm/src/jobs/jobs-client.d.ts +134 -0
- package/esm/src/jobs/jobs-client.d.ts.map +1 -0
- package/esm/src/jobs/jobs-client.js +218 -0
- package/esm/src/jobs/schemas.d.ts +1304 -0
- package/esm/src/jobs/schemas.d.ts.map +1 -0
- package/esm/src/jobs/schemas.js +159 -0
- package/esm/src/platform/adapters/veryfront-api-client/operations.d.ts +3 -3
- package/esm/src/platform/adapters/veryfront-api-client/operations.d.ts.map +1 -1
- package/esm/src/platform/adapters/veryfront-api-client/operations.js +12 -10
- package/esm/src/platform/adapters/veryfront-api-client/retry-handler.d.ts +4 -0
- package/esm/src/platform/adapters/veryfront-api-client/retry-handler.d.ts.map +1 -1
- package/esm/src/platform/adapters/veryfront-api-client/retry-handler.js +12 -6
- package/esm/src/platform/adapters/veryfront-api-client/schemas/api.schema.d.ts +4 -4
- package/esm/src/platform/adapters/veryfront-api-client/schemas/api.schema.js +4 -4
- package/esm/src/platform/index.d.ts +1 -0
- package/esm/src/platform/index.d.ts.map +1 -1
- package/esm/src/platform/index.js +1 -0
- package/esm/src/proxy/handler.d.ts.map +1 -1
- package/esm/src/proxy/handler.js +21 -21
- package/esm/src/routing/api/route-executor.d.ts.map +1 -1
- package/esm/src/routing/api/route-executor.js +30 -3
- package/esm/src/security/deno-permissions.d.ts +1 -1
- package/esm/src/security/deno-permissions.d.ts.map +1 -1
- package/esm/src/security/deno-permissions.js +2 -1
- package/esm/src/security/sandbox/project-worker.d.ts.map +1 -1
- package/esm/src/security/sandbox/project-worker.js +2 -2
- package/esm/src/security/sandbox/worker-permissions.d.ts.map +1 -1
- package/esm/src/security/sandbox/worker-permissions.js +23 -20
- package/esm/src/security/sandbox/worker-pool.d.ts.map +1 -1
- package/esm/src/security/sandbox/worker-pool.js +17 -14
- package/esm/src/security/sandbox/worker-types.d.ts +2 -0
- package/esm/src/security/sandbox/worker-types.d.ts.map +1 -1
- package/esm/src/security/sandbox/worker-types.js +2 -0
- package/esm/src/task/types.d.ts +6 -0
- package/esm/src/task/types.d.ts.map +1 -1
- package/package.json +5 -1
- package/src/cli/commands/pull/command.ts +3 -3
- package/src/cli/commands/task/command.ts +66 -57
- package/src/cli/commands/workflow/command-help.ts +21 -0
- package/src/cli/commands/workflow/command.ts +152 -0
- package/src/cli/commands/workflow/handler.ts +25 -0
- package/src/cli/help/command-definitions.ts +2 -0
- package/src/cli/router.ts +2 -0
- package/src/cli/shared/project-source-context.ts +96 -0
- package/src/deno.js +12 -6
- package/src/src/data/server-data-fetcher.ts +30 -2
- package/src/src/jobs/index.ts +85 -0
- package/src/src/jobs/jobs-client.ts +503 -0
- package/src/src/jobs/schemas.ts +202 -0
- package/src/src/platform/adapters/veryfront-api-client/operations.ts +14 -14
- package/src/src/platform/adapters/veryfront-api-client/retry-handler.ts +15 -6
- package/src/src/platform/adapters/veryfront-api-client/schemas/api.schema.ts +4 -4
- package/src/src/platform/index.ts +1 -0
- package/src/src/proxy/handler.ts +27 -19
- package/src/src/routing/api/route-executor.ts +43 -7
- package/src/src/security/deno-permissions.ts +2 -1
- package/src/src/security/sandbox/project-worker.ts +2 -2
- package/src/src/security/sandbox/worker-permissions.ts +22 -19
- package/src/src/security/sandbox/worker-pool.ts +21 -13
- package/src/src/security/sandbox/worker-types.ts +3 -0
- package/src/src/task/types.ts +6 -0
|
@@ -11,6 +11,19 @@
|
|
|
11
11
|
* See: https://docs.deno.com/runtime/fundamentals/permissions/
|
|
12
12
|
*/
|
|
13
13
|
import * as dntShim from "../../../_dnt.shims.js";
|
|
14
|
+
// Cache compiled binary check — Deno.execPath() is a syscall that never changes at runtime
|
|
15
|
+
const _isCompiledBinary = (() => {
|
|
16
|
+
try {
|
|
17
|
+
const exec = typeof dntShim.Deno !== "undefined" ? dntShim.Deno.execPath?.() : undefined;
|
|
18
|
+
if (!exec)
|
|
19
|
+
return false;
|
|
20
|
+
const name = exec.split(/[/\\]/).pop()?.toLowerCase() ?? "";
|
|
21
|
+
return name !== "deno" && name !== "deno.exe";
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
})();
|
|
14
27
|
/**
|
|
15
28
|
* Build scoped permissions for a project worker.
|
|
16
29
|
*
|
|
@@ -27,26 +40,16 @@ export function buildWorkerPermissions(readPaths) {
|
|
|
27
40
|
// is outside the project directory. Rather than trying to enumerate all
|
|
28
41
|
// read paths, grant full read access — the security boundary is enforced
|
|
29
42
|
// by denying write/run/ffi/sys, not by restricting reads.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
env: true,
|
|
41
|
-
run: false,
|
|
42
|
-
ffi: false,
|
|
43
|
-
sys: false,
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
catch {
|
|
49
|
-
// execPath may not be available
|
|
43
|
+
if (_isCompiledBinary) {
|
|
44
|
+
return {
|
|
45
|
+
read: true,
|
|
46
|
+
write: false,
|
|
47
|
+
net: true,
|
|
48
|
+
env: true,
|
|
49
|
+
run: false,
|
|
50
|
+
ffi: false,
|
|
51
|
+
sys: false,
|
|
52
|
+
};
|
|
50
53
|
}
|
|
51
54
|
return {
|
|
52
55
|
read: readPaths.length > 0 ? readPaths : false,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-pool.d.ts","sourceRoot":"","sources":["../../../../src/src/security/sandbox/worker-pool.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAWzF,qBAAa,UAAU;IACrB,OAAO,CAAC,IAAI,CAAgC;IAC5C,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,MAAM,CAAmB;IAEjC,OAAO,CAAC,eAAe,CAAqD;IAC5E,OAAO,CAAC,mBAAmB,CAAqD;gBAEpE,MAAM,GAAE,OAAO,CAAC,gBAAgB,CAAM;IAMlD;;OAEG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,aAAa;IA0CxE;;;OAGG;IACH,OAAO,CACL,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EAAE,EACnB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"worker-pool.d.ts","sourceRoot":"","sources":["../../../../src/src/security/sandbox/worker-pool.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAWzF,qBAAa,UAAU;IACrB,OAAO,CAAC,IAAI,CAAgC;IAC5C,OAAO,CAAC,SAAS,CAAqB;IACtC,OAAO,CAAC,MAAM,CAAmB;IAEjC,OAAO,CAAC,eAAe,CAAqD;IAC5E,OAAO,CAAC,mBAAmB,CAAqD;gBAEpE,MAAM,GAAE,OAAO,CAAC,gBAAgB,CAAM;IAMlD;;OAEG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,aAAa;IA0CxE;;;OAGG;IACH,OAAO,CACL,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EAAE,EACnB,OAAO,EAAE,aAAa,GACrB,OAAO,CAAC,cAAc,CAAC;IA0D1B;;OAEG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAUpC;;OAEG;IACH,QAAQ,IAAI;QACV,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;QACpB,cAAc,EAAE,MAAM,CAAC;QACvB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE;YACtB,MAAM,EAAE,MAAM,CAAC;YACf,YAAY,EAAE,MAAM,CAAC;YACrB,UAAU,EAAE,OAAO,CAAC;YACpB,MAAM,EAAE,MAAM,CAAC;YACf,KAAK,EAAE,MAAM,CAAC;SACf,CAAC,CAAC;KACJ;IA4BD;;OAEG;IACH,UAAU,IAAI;QACZ,uCAAuC;QACvC,cAAc,EAAE,MAAM,CAAC;QACvB,oDAAoD;QACpD,kBAAkB,EAAE,MAAM,CAAC;QAC3B,kDAAkD;QAClD,sBAAsB,EAAE,MAAM,CAAC;QAC/B,qDAAqD;QACrD,WAAW,EAAE,MAAM,CAAC;QACpB,kEAAkE;QAClE,cAAc,EAAE,MAAM,CAAC;KACxB;IAoBD;;OAEG;IACH,QAAQ,IAAI,IAAI;IAgBhB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,gBAAgB;IAmBxB,OAAO,CAAC,aAAa;YA4BP,WAAW;IAmBzB;;;;OAIG;IACH,OAAO,CAAC,wBAAwB;CA8BjC;AAqBD;;;GAGG;AACH,wBAAgB,wBAAwB,IAAI,OAAO,CAGlD;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,IAAI,OAAO,CAGhD;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAG/C;AAKD,wBAAgB,aAAa,IAAI,UAAU,CAiB1C;AAED,8DAA8D;AAC9D,wBAAgB,mBAAmB,IAAI,IAAI,CAO1C"}
|
|
@@ -85,22 +85,25 @@ export class WorkerPool {
|
|
|
85
85
|
(entry && Date.now() - entry.createdAt > this.config.maxWorkerAgeMs);
|
|
86
86
|
if (shouldRecycle && !this.recycling.has(projectId)) {
|
|
87
87
|
this.recycling.add(projectId);
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
88
|
+
logger.debug("Recycling worker", {
|
|
89
|
+
projectId,
|
|
90
|
+
requestCount: worker.requestCount,
|
|
91
|
+
ageMs: entry ? Date.now() - entry.createdAt : 0,
|
|
92
|
+
reason: worker.requestCount >= this.config.maxRequestsPerWorker
|
|
93
|
+
? "request_count"
|
|
94
|
+
: "age",
|
|
95
|
+
});
|
|
96
|
+
// Warm replacement: let the old worker handle this last request,
|
|
97
|
+
// then evict it and create a replacement after the request settles.
|
|
98
|
+
// This avoids cold-start latency for the caller AND prevents the
|
|
99
|
+
// old worker from being terminated while it still has pending work.
|
|
100
|
+
const result = worker.execute(request);
|
|
101
|
+
void result.finally(() => {
|
|
97
102
|
this.evictWorker(projectId);
|
|
98
|
-
|
|
99
|
-
return fresh.execute(request);
|
|
100
|
-
}
|
|
101
|
-
finally {
|
|
103
|
+
this.getOrCreateWorker(projectId, readPaths);
|
|
102
104
|
this.recycling.delete(projectId);
|
|
103
|
-
}
|
|
105
|
+
});
|
|
106
|
+
return result;
|
|
104
107
|
}
|
|
105
108
|
return worker.execute(request);
|
|
106
109
|
}, { "workerPool.projectId": projectId });
|
|
@@ -161,5 +161,7 @@ export interface WorkerPoolConfig {
|
|
|
161
161
|
/** Per-worker memory budget in MB (default: 64). Workers exceeding this are evicted. */
|
|
162
162
|
memoryBudgetMb: number;
|
|
163
163
|
}
|
|
164
|
+
/** Maximum request body size for worker isolation (10 MB) */
|
|
165
|
+
export declare const MAX_WORKER_BODY_BYTES: number;
|
|
164
166
|
export declare const DEFAULT_WORKER_POOL_CONFIG: WorkerPoolConfig;
|
|
165
167
|
//# sourceMappingURL=worker-types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker-types.d.ts","sourceRoot":"","sources":["../../../../src/src/security/sandbox/worker-types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;IAC5B,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;IAC5B,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC1C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;IAC5B,IAAI,EAAE,UAAU,GAAG,IAAI,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC1C,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,iBAAiB,CAAC;IAC3B,qBAAqB;IACrB,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACxD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;CAC7B;AAMD,MAAM,MAAM,aAAa,GACrB,sBAAsB,GACtB,wBAAwB,GACxB,gBAAgB,GAChB,gBAAgB,CAAC;AAErB,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,mBAAmB,CAAC;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,iBAAiB,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,qBAAqB,CAAC;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,sBAAsB,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,YAAY,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,qBAAqB,CAAC;CAChC;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,YAAY,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,mDAAmD;IACnD,cAAc,EAAE,MAAM,CAAC;IACvB,+DAA+D;IAC/D,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,+CAA+C;IAC/C,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,4EAA4E;IAC5E,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACvC,8BAA8B;IAC9B,QAAQ,EAAE,QAAQ,GAAG,QAAQ,CAAC;CAC/B;AAMD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,cAAc,CAAC;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,YAAY,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,MAAM,cAAc,GACtB,oBAAoB,GACpB,wBAAwB,GACxB,uBAAuB,GACvB,mBAAmB,CAAC;AAExB,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,YAAY,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,QAAQ,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,kBAAkB,CAAC;CAC9B;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,aAAa,CAAC;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,oBAAoB,CAAC;CAC9B;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,OAAO,CAAC;IACd,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,eAAe,CAAC;CACxB;AAMD,MAAM,WAAW,gBAAgB;IAC/B,yDAAyD;IACzD,WAAW,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,aAAa,EAAE,MAAM,CAAC;IACtB,8DAA8D;IAC9D,gBAAgB,EAAE,MAAM,CAAC;IACzB,8CAA8C;IAC9C,qBAAqB,EAAE,MAAM,CAAC;IAC9B,iEAAiE;IACjE,oBAAoB,EAAE,MAAM,CAAC;IAC7B,qFAAqF;IACrF,cAAc,EAAE,MAAM,CAAC;IACvB,wFAAwF;IACxF,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,0BAA0B,EAAE,gBAQxC,CAAC"}
|
|
1
|
+
{"version":3,"file":"worker-types.d.ts","sourceRoot":"","sources":["../../../../src/src/security/sandbox/worker-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @module security/sandbox/worker-types
|
|
8
8
|
*/
|
|
9
|
+
/** Maximum request body size for worker isolation (10 MB) */
|
|
10
|
+
export const MAX_WORKER_BODY_BYTES = 10 * 1024 * 1024;
|
|
9
11
|
export const DEFAULT_WORKER_POOL_CONFIG = {
|
|
10
12
|
maxPoolSize: 20,
|
|
11
13
|
idleTimeoutMs: 300_000,
|
package/esm/src/task/types.d.ts
CHANGED
|
@@ -24,6 +24,12 @@ export interface TaskDefinition {
|
|
|
24
24
|
name?: string;
|
|
25
25
|
/** Task description */
|
|
26
26
|
description?: string;
|
|
27
|
+
/** Optional JSON-schema-like input contract surfaced in APIs/UIs */
|
|
28
|
+
inputSchema?: Record<string, unknown>;
|
|
29
|
+
/** Optional JSON-schema-like output contract surfaced in APIs/UIs */
|
|
30
|
+
outputSchema?: Record<string, unknown>;
|
|
31
|
+
/** Whether this task can be scheduled via cron jobs */
|
|
32
|
+
schedulable?: boolean;
|
|
27
33
|
/** The function to execute */
|
|
28
34
|
run: (ctx: TaskContext) => Promise<unknown> | unknown;
|
|
29
35
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/src/task/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,4BAA4B;IAC5B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,0BAA0B;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8BAA8B;IAC9B,GAAG,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;CACvD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,cAAc,CAIxE"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/src/task/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,4BAA4B;IAC5B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5B,2CAA2C;IAC3C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,2CAA2C;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,0BAA0B;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,qEAAqE;IACrE,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,uDAAuD;IACvD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,8BAA8B;IAC9B,GAAG,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;CACvD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,cAAc,CAIxE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "veryfront",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.77",
|
|
4
4
|
"description": "The simplest way to build AI-powered apps",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -76,6 +76,9 @@
|
|
|
76
76
|
"./resource": {
|
|
77
77
|
"import": "./esm/src/resource/index.js"
|
|
78
78
|
},
|
|
79
|
+
"./jobs": {
|
|
80
|
+
"import": "./esm/src/jobs/index.js"
|
|
81
|
+
},
|
|
79
82
|
"./mcp": {
|
|
80
83
|
"import": "./esm/src/mcp/index.js"
|
|
81
84
|
},
|
|
@@ -149,6 +152,7 @@
|
|
|
149
152
|
"esbuild": "0.20.2",
|
|
150
153
|
"github-slugger": "2.0.0",
|
|
151
154
|
"gray-matter": "4.0.3",
|
|
155
|
+
"jose": "5.9.6",
|
|
152
156
|
"mdast-util-to-string": "4.0.0",
|
|
153
157
|
"mime-types": "2.1.35",
|
|
154
158
|
"react": "19.1.1",
|
|
@@ -159,7 +159,7 @@ export function buildFilesListUrl(projectSlug: string, source: PullSource): stri
|
|
|
159
159
|
case "release":
|
|
160
160
|
return `/projects/${projectSlug}/releases/${encodeURIComponent(source.version)}/files`;
|
|
161
161
|
case "branch":
|
|
162
|
-
return `/projects/${projectSlug}/
|
|
162
|
+
return `/projects/${projectSlug}/files?branch=${encodeURIComponent(source.name)}`;
|
|
163
163
|
case "main":
|
|
164
164
|
return `/projects/${projectSlug}/files`;
|
|
165
165
|
}
|
|
@@ -211,9 +211,9 @@ export function buildFileContentUrl(projectSlug: string, path: string, source: P
|
|
|
211
211
|
encodeURIComponent(source.version)
|
|
212
212
|
}/files/${encodedPath}`;
|
|
213
213
|
case "branch":
|
|
214
|
-
return `/projects/${projectSlug}/
|
|
214
|
+
return `/projects/${projectSlug}/files/${encodedPath}?branch=${
|
|
215
215
|
encodeURIComponent(source.name)
|
|
216
|
-
}
|
|
216
|
+
}`;
|
|
217
217
|
case "main":
|
|
218
218
|
return `/projects/${projectSlug}/files/${encodedPath}`;
|
|
219
219
|
}
|
|
@@ -9,14 +9,12 @@ import * as dntShim from "../../../_dnt.shims.js";
|
|
|
9
9
|
|
|
10
10
|
import { cliLogger } from "../../utils/index.js";
|
|
11
11
|
import { exitProcess } from "../../utils/index.js";
|
|
12
|
+
import { withProjectSourceContext } from "../../shared/project-source-context.js";
|
|
12
13
|
import type { TaskArgs } from "./handler.js";
|
|
13
14
|
|
|
14
15
|
export interface TaskOptions extends TaskArgs {}
|
|
15
16
|
|
|
16
17
|
export async function taskCommand(options: TaskOptions): Promise<void> {
|
|
17
|
-
const { getAdapter } = await import(
|
|
18
|
-
"../../../src/platform/adapters/detect.js"
|
|
19
|
-
);
|
|
20
18
|
const { discoverTasks } = await import(
|
|
21
19
|
"../../../src/task/discovery.js"
|
|
22
20
|
);
|
|
@@ -32,67 +30,78 @@ export async function taskCommand(options: TaskOptions): Promise<void> {
|
|
|
32
30
|
}
|
|
33
31
|
|
|
34
32
|
const projectDir = dntShim.Deno.cwd();
|
|
35
|
-
|
|
33
|
+
await withProjectSourceContext(
|
|
34
|
+
projectDir,
|
|
35
|
+
async ({ adapter, config, projectId, proxyContext }) => {
|
|
36
|
+
const sourceLabel = proxyContext?.branchRef
|
|
37
|
+
? `branch ${proxyContext.branchRef}`
|
|
38
|
+
: proxyContext
|
|
39
|
+
? "main"
|
|
40
|
+
: `${projectDir}/tasks/...`;
|
|
36
41
|
|
|
37
|
-
|
|
42
|
+
cliLogger.info(`Discovering tasks in ${sourceLabel}`);
|
|
38
43
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
const { tasks, errors } = await discoverTasks({
|
|
45
|
+
projectDir,
|
|
46
|
+
adapter,
|
|
47
|
+
config,
|
|
48
|
+
debug: options.debug,
|
|
49
|
+
});
|
|
44
50
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
51
|
+
if (errors.length > 0 && options.debug) {
|
|
52
|
+
for (const err of errors) {
|
|
53
|
+
cliLogger.warn(` Warning: ${err.filePath}: ${err.error}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
50
56
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
57
|
+
const task = tasks.find((t) => t.id === taskName);
|
|
58
|
+
if (!task) {
|
|
59
|
+
cliLogger.error(`Task "${taskName}" not found.`);
|
|
60
|
+
if (tasks.length > 0) {
|
|
61
|
+
cliLogger.info("Available tasks:");
|
|
62
|
+
for (const t of tasks) {
|
|
63
|
+
cliLogger.info(` - ${t.id}${t.name !== t.id ? ` (${t.name})` : ""}`);
|
|
64
|
+
}
|
|
65
|
+
} else {
|
|
66
|
+
cliLogger.info("No tasks found. Create a task file in tasks/ directory:");
|
|
67
|
+
cliLogger.info(" tasks/my-task.ts");
|
|
68
|
+
}
|
|
69
|
+
exitProcess(1);
|
|
70
|
+
return;
|
|
58
71
|
}
|
|
59
|
-
} else {
|
|
60
|
-
cliLogger.info("No tasks found. Create a task file in tasks/ directory:");
|
|
61
|
-
cliLogger.info(" tasks/my-task.ts");
|
|
62
|
-
}
|
|
63
|
-
exitProcess(1);
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
72
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
73
|
+
let taskConfig: Record<string, unknown> = {};
|
|
74
|
+
if (options.config) {
|
|
75
|
+
try {
|
|
76
|
+
taskConfig = JSON.parse(options.config);
|
|
77
|
+
} catch {
|
|
78
|
+
cliLogger.error("Invalid --config JSON");
|
|
79
|
+
exitProcess(1);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
78
83
|
|
|
79
|
-
|
|
80
|
-
|
|
84
|
+
cliLogger.info(`Running task: ${task.name} (${task.id})`);
|
|
85
|
+
cliLogger.info("");
|
|
81
86
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
+
const result = await runTask({
|
|
88
|
+
task,
|
|
89
|
+
config: taskConfig,
|
|
90
|
+
projectId,
|
|
91
|
+
debug: options.debug,
|
|
92
|
+
});
|
|
87
93
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
94
|
+
cliLogger.info("");
|
|
95
|
+
if (result.success) {
|
|
96
|
+
cliLogger.info(`Task completed in ${result.durationMs}ms`);
|
|
97
|
+
if (result.result !== undefined) {
|
|
98
|
+
cliLogger.info(`Result: ${JSON.stringify(result.result, null, 2)}`);
|
|
99
|
+
}
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
cliLogger.error(`Task failed after ${result.durationMs}ms: ${result.error}`);
|
|
104
|
+
exitProcess(1);
|
|
105
|
+
},
|
|
106
|
+
);
|
|
98
107
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { CommandHelp } from "../../help/types.js";
|
|
2
|
+
|
|
3
|
+
export const workflowHelp: CommandHelp = {
|
|
4
|
+
name: "workflow",
|
|
5
|
+
description: "Run a workflow from the app/workflows directory",
|
|
6
|
+
usage: "veryfront workflow run <id> [options]",
|
|
7
|
+
options: [
|
|
8
|
+
{
|
|
9
|
+
flag: "--input <json>",
|
|
10
|
+
description: "JSON input to pass to the workflow",
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
flag: "--debug",
|
|
14
|
+
description: "Enable debug logging",
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
examples: [
|
|
18
|
+
"veryfront workflow run publish-site",
|
|
19
|
+
'veryfront workflow run content-pipeline --input \'{"topic":"AI"}\'',
|
|
20
|
+
],
|
|
21
|
+
};
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import * as dntShim from "../../../_dnt.shims.js";
|
|
2
|
+
import { cliLogger } from "../../utils/index.js";
|
|
3
|
+
import { exitProcess } from "../../utils/index.js";
|
|
4
|
+
import { withProjectSourceContext } from "../../shared/project-source-context.js";
|
|
5
|
+
import { getEnv } from "../../../src/platform/index.js";
|
|
6
|
+
import type { WorkflowArgs } from "./handler.js";
|
|
7
|
+
|
|
8
|
+
const WORKFLOW_STATUS_POLL_INTERVAL_MS = 1_000;
|
|
9
|
+
|
|
10
|
+
export interface WorkflowOptions extends WorkflowArgs {}
|
|
11
|
+
|
|
12
|
+
async function createWorkflowClient(debug: boolean) {
|
|
13
|
+
const { createWorkflowClient } = await import(
|
|
14
|
+
"../../../src/workflow/api/workflow-client.js"
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
const redisUrl = getEnv("REDIS_URL")?.trim();
|
|
18
|
+
if (!redisUrl) {
|
|
19
|
+
return createWorkflowClient({ debug });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const { RedisBackend } = await import(
|
|
23
|
+
"../../../src/workflow/backends/redis.js"
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
const backend = new RedisBackend({ url: redisUrl, debug });
|
|
27
|
+
if (backend.initialize) {
|
|
28
|
+
await backend.initialize();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return createWorkflowClient({ backend, debug });
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function waitForWorkflowExit(
|
|
35
|
+
client: Awaited<ReturnType<typeof createWorkflowClient>>,
|
|
36
|
+
runId: string,
|
|
37
|
+
): Promise<void> {
|
|
38
|
+
while (true) {
|
|
39
|
+
const run = await client.getRun(runId);
|
|
40
|
+
if (!run) {
|
|
41
|
+
throw new Error(`Workflow run not found: ${runId}`);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (run.status === "completed") {
|
|
45
|
+
cliLogger.info(`Workflow completed: ${runId}`);
|
|
46
|
+
if (run.output !== undefined) {
|
|
47
|
+
cliLogger.info(`Result: ${JSON.stringify(run.output, null, 2)}`);
|
|
48
|
+
}
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (run.status === "waiting") {
|
|
53
|
+
cliLogger.info(`Workflow is waiting: ${runId}`);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (run.status === "failed") {
|
|
58
|
+
throw new Error(run.error?.message || `Workflow failed: ${runId}`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (run.status === "cancelled") {
|
|
62
|
+
throw new Error(`Workflow was cancelled: ${runId}`);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
await new Promise((resolve) => dntShim.setTimeout(resolve, WORKFLOW_STATUS_POLL_INTERVAL_MS));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export async function workflowCommand(options: WorkflowOptions): Promise<void> {
|
|
70
|
+
if (options.action !== "run") {
|
|
71
|
+
cliLogger.error(`Unknown workflow action: ${options.action}`);
|
|
72
|
+
exitProcess(1);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const workflowId = options.name;
|
|
77
|
+
if (!workflowId) {
|
|
78
|
+
cliLogger.error("Workflow ID is required. Usage: veryfront workflow run <id>");
|
|
79
|
+
exitProcess(1);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
let input: Record<string, unknown> = {};
|
|
84
|
+
if (options.input) {
|
|
85
|
+
try {
|
|
86
|
+
input = JSON.parse(options.input);
|
|
87
|
+
} catch {
|
|
88
|
+
cliLogger.error("Invalid --input JSON");
|
|
89
|
+
exitProcess(1);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const { discoverWorkflows } = await import(
|
|
95
|
+
"../../../src/workflow/discovery/index.js"
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
await withProjectSourceContext(dntShim.Deno.cwd(), async ({ adapter, config, proxyContext }) => {
|
|
99
|
+
const sourceLabel = proxyContext?.branchRef
|
|
100
|
+
? `branch ${proxyContext.branchRef}`
|
|
101
|
+
: proxyContext
|
|
102
|
+
? "main"
|
|
103
|
+
: `${dntShim.Deno.cwd()}/app/workflows/...`;
|
|
104
|
+
|
|
105
|
+
cliLogger.info(`Discovering workflows in ${sourceLabel}`);
|
|
106
|
+
|
|
107
|
+
const discovery = await discoverWorkflows({
|
|
108
|
+
projectDir: dntShim.Deno.cwd(),
|
|
109
|
+
adapter,
|
|
110
|
+
config,
|
|
111
|
+
debug: options.debug,
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
if (discovery.errors.length > 0 && options.debug) {
|
|
115
|
+
for (const err of discovery.errors) {
|
|
116
|
+
cliLogger.warn(` Warning: ${err.filePath}: ${err.error}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const workflow = discovery.workflows.find((candidate) => candidate.id === workflowId);
|
|
121
|
+
if (!workflow) {
|
|
122
|
+
cliLogger.error(`Workflow "${workflowId}" not found.`);
|
|
123
|
+
if (discovery.workflows.length > 0) {
|
|
124
|
+
cliLogger.info("Available workflows:");
|
|
125
|
+
for (const candidate of discovery.workflows) {
|
|
126
|
+
cliLogger.info(` - ${candidate.id}`);
|
|
127
|
+
}
|
|
128
|
+
} else {
|
|
129
|
+
cliLogger.info("No workflows found. Create a workflow file in app/workflows/.");
|
|
130
|
+
}
|
|
131
|
+
exitProcess(1);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const client = await createWorkflowClient(options.debug);
|
|
136
|
+
|
|
137
|
+
try {
|
|
138
|
+
client.register(workflow.definition);
|
|
139
|
+
cliLogger.info(`Running workflow: ${workflow.id}`);
|
|
140
|
+
cliLogger.info("");
|
|
141
|
+
|
|
142
|
+
const handle = await client.start(workflow.id, input);
|
|
143
|
+
await waitForWorkflowExit(client, handle.runId);
|
|
144
|
+
} finally {
|
|
145
|
+
await client.destroy();
|
|
146
|
+
}
|
|
147
|
+
}).catch((error: unknown) => {
|
|
148
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
149
|
+
cliLogger.error(message);
|
|
150
|
+
exitProcess(1);
|
|
151
|
+
});
|
|
152
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { createArgParser, parseArgsOrThrow } from "../../shared/args.js";
|
|
3
|
+
import type { ParsedArgs } from "../../shared/types.js";
|
|
4
|
+
|
|
5
|
+
const WorkflowArgsSchema = z.object({
|
|
6
|
+
action: z.enum(["run"]),
|
|
7
|
+
name: z.string(),
|
|
8
|
+
input: z.string().optional(),
|
|
9
|
+
debug: z.boolean().default(false),
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export type WorkflowArgs = z.infer<typeof WorkflowArgsSchema>;
|
|
13
|
+
|
|
14
|
+
export const parseWorkflowArgs = createArgParser(WorkflowArgsSchema, {
|
|
15
|
+
action: { keys: ["action"], type: "string", positional: 0 },
|
|
16
|
+
name: { keys: ["name"], type: "string", positional: 1 },
|
|
17
|
+
input: { keys: ["input"], type: "string" },
|
|
18
|
+
debug: { keys: ["debug"], type: "boolean" },
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
export async function handleWorkflowCommand(args: ParsedArgs): Promise<void> {
|
|
22
|
+
const opts = parseArgsOrThrow(parseWorkflowArgs, "workflow", args);
|
|
23
|
+
const { workflowCommand } = await import("./command.js");
|
|
24
|
+
await workflowCommand(opts);
|
|
25
|
+
}
|
|
@@ -36,6 +36,7 @@ import { mcpHelp } from "../commands/mcp/command-help.js";
|
|
|
36
36
|
import { issuesHelp } from "../commands/issues/command-help.js";
|
|
37
37
|
import { startHelp } from "../commands/start/command-help.js";
|
|
38
38
|
import { taskHelp } from "../commands/task/command-help.js";
|
|
39
|
+
import { workflowHelp } from "../commands/workflow/command-help.js";
|
|
39
40
|
|
|
40
41
|
/**
|
|
41
42
|
* Central registry of all command help definitions.
|
|
@@ -71,4 +72,5 @@ export const COMMANDS: CommandRegistry = {
|
|
|
71
72
|
issues: issuesHelp,
|
|
72
73
|
start: startHelp,
|
|
73
74
|
task: taskHelp,
|
|
75
|
+
workflow: workflowHelp,
|
|
74
76
|
};
|
package/src/cli/router.ts
CHANGED
|
@@ -31,6 +31,7 @@ import { handleStartCommand } from "./commands/start/handler.js";
|
|
|
31
31
|
import { handleStudioCommand } from "./commands/studio/handler.js";
|
|
32
32
|
import { handleUpCommand } from "./commands/up/index.js";
|
|
33
33
|
import { handleTaskCommand } from "./commands/task/handler.js";
|
|
34
|
+
import { handleWorkflowCommand } from "./commands/workflow/handler.js";
|
|
34
35
|
import { handleWorkerCommand } from "./commands/worker/handler.js";
|
|
35
36
|
import { login, logout, whoami } from "./auth/index.js";
|
|
36
37
|
import { parseLoginMethod } from "./auth/utils.js";
|
|
@@ -81,6 +82,7 @@ const commands: Record<string, (args: ParsedArgs) => Promise<void>> = {
|
|
|
81
82
|
"issues": handleIssuesCommand,
|
|
82
83
|
"start": handleStartCommand,
|
|
83
84
|
"task": handleTaskCommand,
|
|
85
|
+
"workflow": handleWorkflowCommand,
|
|
84
86
|
"worker": handleWorkerCommand,
|
|
85
87
|
};
|
|
86
88
|
|