veryfront 0.1.76 → 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/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 +1 -0
- package/esm/deno.js +2 -1
- 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/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/server/runtime-handler/index.d.ts +1 -1
- package/esm/src/server/runtime-handler/index.d.ts.map +1 -1
- package/esm/src/server/runtime-handler/index.js +0 -3
- package/package.json +1 -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 +2 -1
- package/src/src/platform/adapters/veryfront-api-client/operations.ts +14 -14
- 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/server/runtime-handler/index.ts +0 -3
- package/esm/src/server/handlers/request/internal-tasks-list.handler.d.ts +0 -11
- package/esm/src/server/handlers/request/internal-tasks-list.handler.d.ts.map +0 -1
- package/esm/src/server/handlers/request/internal-tasks-list.handler.js +0 -72
- package/esm/src/task/control-plane.d.ts +0 -105
- package/esm/src/task/control-plane.d.ts.map +0 -1
- package/esm/src/task/control-plane.js +0 -52
- package/src/src/server/handlers/request/internal-tasks-list.handler.ts +0 -103
- package/src/src/task/control-plane.ts +0 -76
|
@@ -15,5 +15,6 @@ export { lookup as lookupMimeType } from "./compat/media-types.js";
|
|
|
15
15
|
export { createKVStore, MemoryKv } from "./compat/kv/index.js";
|
|
16
16
|
export { isDeno } from "./compat/runtime.js";
|
|
17
17
|
export { createFSAdapter, VeryfrontFSAdapter } from "./adapters/fs/index.js";
|
|
18
|
+
export { enhanceAdapterWithFS, isExtendedFSAdapter } from "./adapters/fs/index.js";
|
|
18
19
|
export { VeryfrontApiClient } from "./adapters/veryfront-api-client/index.js";
|
|
19
20
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/platform/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGzD,OAAO,EACL,KAAK,EACL,GAAG,EACH,GAAG,EACH,IAAI,EACJ,OAAO,EACP,MAAM,EACN,SAAS,EACT,iBAAiB,EACjB,SAAS,EACT,eAAe,EACf,aAAa,EACb,WAAW,EACX,aAAa,EACb,QAAQ,EACR,UAAU,EACV,iBAAiB,EACjB,UAAU,EACV,MAAM,EACN,WAAW,EACX,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,gBAAgB,EAChB,MAAM,EACN,KAAK,UAAU,EACf,KAAK,EACL,OAAO,EACP,YAAY,EACZ,MAAM,EACN,aAAa,GACd,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,UAAU,EACV,KAAK,WAAW,GACjB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,MAAM,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGnE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAG/D,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAG7C,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/src/platform/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGzD,OAAO,EACL,KAAK,EACL,GAAG,EACH,GAAG,EACH,IAAI,EACJ,OAAO,EACP,MAAM,EACN,SAAS,EACT,iBAAiB,EACjB,SAAS,EACT,eAAe,EACf,aAAa,EACb,WAAW,EACX,aAAa,EACb,QAAQ,EACR,UAAU,EACV,iBAAiB,EACjB,UAAU,EACV,MAAM,EACN,WAAW,EACX,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,gBAAgB,EAChB,MAAM,EACN,KAAK,UAAU,EACf,KAAK,EACL,OAAO,EACP,YAAY,EACZ,MAAM,EACN,aAAa,GACd,MAAM,gBAAgB,CAAC;AAGxB,OAAO,EACL,kBAAkB,EAClB,cAAc,EACd,UAAU,EACV,KAAK,WAAW,GACjB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,MAAM,IAAI,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAGnE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAG/D,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAG7C,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAGnF,OAAO,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAC"}
|
|
@@ -22,5 +22,6 @@ export { createKVStore, MemoryKv } from "./compat/kv/index.js";
|
|
|
22
22
|
export { isDeno } from "./compat/runtime.js";
|
|
23
23
|
// Adapters: filesystem
|
|
24
24
|
export { createFSAdapter, VeryfrontFSAdapter } from "./adapters/fs/index.js";
|
|
25
|
+
export { enhanceAdapterWithFS, isExtendedFSAdapter } from "./adapters/fs/index.js";
|
|
25
26
|
// Adapters: API client
|
|
26
27
|
export { VeryfrontApiClient } from "./adapters/veryfront-api-client/index.js";
|
|
@@ -14,7 +14,7 @@ import type { Handler } from "../../types/index.js";
|
|
|
14
14
|
import { ApiHandlerWrapper } from "../handlers/request/api/index.js";
|
|
15
15
|
export { parseProxyEnvironment, type ProxyEnvironment } from "./proxy-environment.js";
|
|
16
16
|
/** Handler names in registration order. */
|
|
17
|
-
export declare const HANDLER_NAMES: readonly ["AuthHandler", "CsrfHandler", "HMRHandler", "CorsHandler", "HealthHandler", "MetricsHandler", "MemoryDebugHandler", "ClientLogHandler", "DevEndpointsHandler", "StylesCSSHandler", "DebugContextHandler", "OpenAPIHandler", "OpenAPIDocsHandler", "InternalAgentsListHandler", "
|
|
17
|
+
export declare const HANDLER_NAMES: readonly ["AuthHandler", "CsrfHandler", "HMRHandler", "CorsHandler", "HealthHandler", "MetricsHandler", "MemoryDebugHandler", "ClientLogHandler", "DevEndpointsHandler", "StylesCSSHandler", "DebugContextHandler", "OpenAPIHandler", "OpenAPIDocsHandler", "InternalAgentsListHandler", "AgentStreamHandler", "AgentRunResumeHandler", "AgentRunCancelHandler", "ChannelInvokeHandler", "DevDashboardHandler", "ProjectsHandler", "StudioBridgeModulesHandler", "CSSHandler", "DevFileHandler", "SnippetHandler", "StaticHandler", "LibModulesHandler", "RSCHandler", "ModuleHandler", "ApiHandlerWrapper", "MarkdownPreviewHandler", "SSRHandler", "NotFoundHandler"];
|
|
18
18
|
/** Union of all registered handler names. */
|
|
19
19
|
export type HandlerName = (typeof HANDLER_NAMES)[number];
|
|
20
20
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/src/server/runtime-handler/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,OAAO,MAAM,wBAAwB,CAAC;AAQlD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAK7D,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AA0BpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/src/server/runtime-handler/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,OAAO,MAAM,wBAAwB,CAAC;AAQlD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAK7D,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AA0BpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AA8DrE,OAAO,EAAE,qBAAqB,EAAE,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAMtF,2CAA2C;AAC3C,eAAO,MAAM,aAAa,yoBAiChB,CAAC;AAEX,6CAA6C;AAC7C,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAEzD;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,8CAA8C;IAC9C,SAAS,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;IAClD,mDAAmD;IACnD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAyCD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,cAAc,EACvB,IAAI,GAAE,mBAAwB,GAC7B;IAAE,QAAQ,EAAE,aAAa,CAAC;IAAC,UAAU,EAAE,iBAAiB,CAAA;CAAE,CAuB5D;AAED,MAAM,WAAW,qBAAqB;IACpC,UAAU,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,wEAAwE;IACxE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,0DAA0D;IAC1D,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,oFAAoF;IACpF,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,sFAAsF;IACtF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,oFAAoF;IACpF,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,uGAAuG;IACvG,kBAAkB,CAAC,EAAE,SAAS,GAAG,YAAY,CAAC;CAC/C;AAED,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,cAAc,EACvB,IAAI,GAAE,qBAAsC,GAC3C,CAAC,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAsYnF;AAGD,YAAY,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC"}
|
|
@@ -43,7 +43,6 @@ import { MarkdownPreviewHandler } from "../handlers/preview/markdown-preview.han
|
|
|
43
43
|
import { OpenAPIHandler } from "../handlers/request/openapi.handler.js";
|
|
44
44
|
import { OpenAPIDocsHandler } from "../handlers/request/openapi-docs.handler.js";
|
|
45
45
|
import { InternalAgentsListHandler } from "../handlers/request/internal-agents-list.handler.js";
|
|
46
|
-
import { InternalTasksListHandler } from "../handlers/request/internal-tasks-list.handler.js";
|
|
47
46
|
import { AgentStreamHandler } from "../handlers/request/agent-stream.handler.js";
|
|
48
47
|
import { AgentRunResumeHandler } from "../handlers/request/agent-run-resume.handler.js";
|
|
49
48
|
import { AgentRunCancelHandler } from "../handlers/request/agent-run-cancel.handler.js";
|
|
@@ -84,7 +83,6 @@ export const HANDLER_NAMES = [
|
|
|
84
83
|
"OpenAPIHandler",
|
|
85
84
|
"OpenAPIDocsHandler",
|
|
86
85
|
"InternalAgentsListHandler",
|
|
87
|
-
"InternalTasksListHandler",
|
|
88
86
|
"AgentStreamHandler",
|
|
89
87
|
"AgentRunResumeHandler",
|
|
90
88
|
"AgentRunCancelHandler",
|
|
@@ -120,7 +118,6 @@ const handlerFactories = {
|
|
|
120
118
|
OpenAPIHandler: () => new OpenAPIHandler(),
|
|
121
119
|
OpenAPIDocsHandler: () => new OpenAPIDocsHandler(),
|
|
122
120
|
InternalAgentsListHandler: () => new InternalAgentsListHandler(),
|
|
123
|
-
InternalTasksListHandler: () => new InternalTasksListHandler(),
|
|
124
121
|
AgentStreamHandler: () => new AgentStreamHandler(),
|
|
125
122
|
AgentRunResumeHandler: () => new AgentRunResumeHandler(),
|
|
126
123
|
AgentRunCancelHandler: () => new AgentRunCancelHandler(),
|
package/package.json
CHANGED
|
@@ -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
|
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { getConfig, type VeryfrontConfig } from "../../src/config/index.js";
|
|
2
|
+
import {
|
|
3
|
+
enhanceAdapterWithFS,
|
|
4
|
+
getEnv,
|
|
5
|
+
isExtendedFSAdapter,
|
|
6
|
+
runtime,
|
|
7
|
+
type RuntimeAdapter,
|
|
8
|
+
} from "../../src/platform/index.js";
|
|
9
|
+
|
|
10
|
+
interface ProxyProjectSourceContext {
|
|
11
|
+
projectSlug: string;
|
|
12
|
+
token: string;
|
|
13
|
+
projectId?: string;
|
|
14
|
+
branchRef?: string | null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface ProjectSourceExecutionContext {
|
|
18
|
+
adapter: RuntimeAdapter;
|
|
19
|
+
config: VeryfrontConfig;
|
|
20
|
+
projectDir: string;
|
|
21
|
+
projectId?: string;
|
|
22
|
+
proxyContext?: ProxyProjectSourceContext;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function getProxyProjectSourceContext(): ProxyProjectSourceContext | null {
|
|
26
|
+
const projectSlug = getEnv("VERYFRONT_PROJECT_SLUG")?.trim();
|
|
27
|
+
const token = getEnv("VERYFRONT_API_TOKEN")?.trim();
|
|
28
|
+
|
|
29
|
+
if (!projectSlug || !token) {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const projectId = getEnv("VERYFRONT_PROJECT_ID")?.trim();
|
|
34
|
+
const branchRef = getEnv("VERYFRONT_BRANCH_REF")?.trim();
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
projectSlug,
|
|
38
|
+
token,
|
|
39
|
+
projectId: projectId || undefined,
|
|
40
|
+
branchRef: branchRef || null,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async function loadProjectConfig(
|
|
45
|
+
projectDir: string,
|
|
46
|
+
adapter: RuntimeAdapter,
|
|
47
|
+
proxyContext?: ProxyProjectSourceContext,
|
|
48
|
+
): Promise<VeryfrontConfig> {
|
|
49
|
+
const cacheKey = proxyContext?.projectId ?? proxyContext?.projectSlug;
|
|
50
|
+
return await getConfig(projectDir, adapter, cacheKey ? { cacheKey } : undefined);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function withProjectSourceContext<T>(
|
|
54
|
+
projectDir: string,
|
|
55
|
+
run: (context: ProjectSourceExecutionContext) => Promise<T>,
|
|
56
|
+
): Promise<T> {
|
|
57
|
+
const baseAdapter = await runtime.get();
|
|
58
|
+
const initialConfig = await getConfig(projectDir, baseAdapter);
|
|
59
|
+
const adapter = await enhanceAdapterWithFS(baseAdapter, initialConfig, projectDir);
|
|
60
|
+
const proxyContext = getProxyProjectSourceContext();
|
|
61
|
+
|
|
62
|
+
if (
|
|
63
|
+
proxyContext &&
|
|
64
|
+
isExtendedFSAdapter(adapter.fs) &&
|
|
65
|
+
adapter.fs.isMultiProjectMode()
|
|
66
|
+
) {
|
|
67
|
+
return await adapter.fs.runWithContext(
|
|
68
|
+
proxyContext.projectSlug,
|
|
69
|
+
proxyContext.token,
|
|
70
|
+
async () => {
|
|
71
|
+
const config = await loadProjectConfig(projectDir, adapter, proxyContext);
|
|
72
|
+
return await run({
|
|
73
|
+
adapter,
|
|
74
|
+
config,
|
|
75
|
+
projectDir,
|
|
76
|
+
projectId: proxyContext.projectId,
|
|
77
|
+
proxyContext,
|
|
78
|
+
});
|
|
79
|
+
},
|
|
80
|
+
proxyContext.projectId,
|
|
81
|
+
{
|
|
82
|
+
productionMode: false,
|
|
83
|
+
branch: proxyContext.branchRef ?? null,
|
|
84
|
+
},
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const config = await loadProjectConfig(projectDir, adapter);
|
|
89
|
+
return await run({
|
|
90
|
+
adapter,
|
|
91
|
+
config,
|
|
92
|
+
projectDir,
|
|
93
|
+
projectId: proxyContext?.projectId,
|
|
94
|
+
proxyContext: proxyContext ?? undefined,
|
|
95
|
+
});
|
|
96
|
+
}
|
package/src/deno.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
"name": "veryfront",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.77",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"nodeModulesDir": "auto",
|
|
6
6
|
"exclude": [
|
|
@@ -114,6 +114,7 @@ export default {
|
|
|
114
114
|
"#cli/shared/types": "./cli/shared/types.ts",
|
|
115
115
|
"#cli/shared/constants": "./cli/shared/constants.ts",
|
|
116
116
|
"#cli/shared/config": "./cli/shared/config.ts",
|
|
117
|
+
"#cli/shared/project-source-context": "./cli/shared/project-source-context.ts",
|
|
117
118
|
"#cli/shared/slug": "./cli/shared/slug.ts",
|
|
118
119
|
"#cli/shared/reserve-slug": "./cli/shared/reserve-slug.ts",
|
|
119
120
|
"#cli/shared/server-startup": "./cli/shared/server-startup.ts",
|