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.
Files changed (54) hide show
  1. package/esm/cli/commands/pull/command.js +2 -2
  2. package/esm/cli/commands/task/command.d.ts.map +1 -1
  3. package/esm/cli/commands/task/command.js +57 -51
  4. package/esm/cli/commands/workflow/command-help.d.ts +3 -0
  5. package/esm/cli/commands/workflow/command-help.d.ts.map +1 -0
  6. package/esm/cli/commands/workflow/command-help.js +19 -0
  7. package/esm/cli/commands/workflow/command.d.ts +5 -0
  8. package/esm/cli/commands/workflow/command.d.ts.map +1 -0
  9. package/esm/cli/commands/workflow/command.js +119 -0
  10. package/esm/cli/commands/workflow/handler.d.ts +28 -0
  11. package/esm/cli/commands/workflow/handler.d.ts.map +1 -0
  12. package/esm/cli/commands/workflow/handler.js +19 -0
  13. package/esm/cli/help/command-definitions.d.ts.map +1 -1
  14. package/esm/cli/help/command-definitions.js +2 -0
  15. package/esm/cli/router.d.ts.map +1 -1
  16. package/esm/cli/router.js +2 -0
  17. package/esm/cli/shared/project-source-context.d.ts +18 -0
  18. package/esm/cli/shared/project-source-context.d.ts.map +1 -0
  19. package/esm/cli/shared/project-source-context.js +52 -0
  20. package/esm/deno.d.ts +1 -0
  21. package/esm/deno.js +2 -1
  22. package/esm/src/platform/adapters/veryfront-api-client/operations.d.ts +3 -3
  23. package/esm/src/platform/adapters/veryfront-api-client/operations.d.ts.map +1 -1
  24. package/esm/src/platform/adapters/veryfront-api-client/operations.js +12 -10
  25. package/esm/src/platform/adapters/veryfront-api-client/schemas/api.schema.d.ts +4 -4
  26. package/esm/src/platform/adapters/veryfront-api-client/schemas/api.schema.js +4 -4
  27. package/esm/src/platform/index.d.ts +1 -0
  28. package/esm/src/platform/index.d.ts.map +1 -1
  29. package/esm/src/platform/index.js +1 -0
  30. package/esm/src/server/runtime-handler/index.d.ts +1 -1
  31. package/esm/src/server/runtime-handler/index.d.ts.map +1 -1
  32. package/esm/src/server/runtime-handler/index.js +0 -3
  33. package/package.json +1 -1
  34. package/src/cli/commands/pull/command.ts +3 -3
  35. package/src/cli/commands/task/command.ts +66 -57
  36. package/src/cli/commands/workflow/command-help.ts +21 -0
  37. package/src/cli/commands/workflow/command.ts +152 -0
  38. package/src/cli/commands/workflow/handler.ts +25 -0
  39. package/src/cli/help/command-definitions.ts +2 -0
  40. package/src/cli/router.ts +2 -0
  41. package/src/cli/shared/project-source-context.ts +96 -0
  42. package/src/deno.js +2 -1
  43. package/src/src/platform/adapters/veryfront-api-client/operations.ts +14 -14
  44. package/src/src/platform/adapters/veryfront-api-client/schemas/api.schema.ts +4 -4
  45. package/src/src/platform/index.ts +1 -0
  46. package/src/src/server/runtime-handler/index.ts +0 -3
  47. package/esm/src/server/handlers/request/internal-tasks-list.handler.d.ts +0 -11
  48. package/esm/src/server/handlers/request/internal-tasks-list.handler.d.ts.map +0 -1
  49. package/esm/src/server/handlers/request/internal-tasks-list.handler.js +0 -72
  50. package/esm/src/task/control-plane.d.ts +0 -105
  51. package/esm/src/task/control-plane.d.ts.map +0 -1
  52. package/esm/src/task/control-plane.js +0 -52
  53. package/src/src/server/handlers/request/internal-tasks-list.handler.ts +0 -103
  54. package/src/src/task/control-plane.ts +0 -76
@@ -154,14 +154,13 @@ export class VeryfrontAPIOperations {
154
154
 
155
155
  async listBranchFiles(
156
156
  projectRef: string,
157
- branchName = "main",
157
+ branchRef = "main",
158
158
  options: ListFilesOptions = {},
159
159
  ): Promise<FileListResult> {
160
160
  const params = buildListParams(options);
161
- const url = `/projects/${encodeURIComponent(projectRef)}/branches/${
162
- encodeURIComponent(branchName)
163
- }/files?${params}`;
164
- logger.debug("listBranchFiles", { projectRef, branchName, pattern: options.pattern });
161
+ params.set("branch", branchRef);
162
+ const url = `/projects/${encodeURIComponent(projectRef)}/files?${params}`;
163
+ logger.debug("listBranchFiles", { projectRef, branchRef, pattern: options.pattern });
165
164
 
166
165
  const raw = await this.request(url);
167
166
  const response = ListBranchFilesResponseSchema.parse(raw);
@@ -174,11 +173,11 @@ export class VeryfrontAPIOperations {
174
173
 
175
174
  async listAllBranchFiles(
176
175
  projectRef: string,
177
- branchName = "main",
176
+ branchRef = "main",
178
177
  options: Omit<ListFilesOptions, "cursor"> = {},
179
178
  ): Promise<ProjectFile[]> {
180
179
  const allFiles = await listAllFiles((cursor) =>
181
- this.listBranchFiles(projectRef, branchName, {
180
+ this.listBranchFiles(projectRef, branchRef, {
182
181
  ...options,
183
182
  cursor,
184
183
  limit: DEFAULT_PAGE_LIMIT,
@@ -187,21 +186,22 @@ export class VeryfrontAPIOperations {
187
186
 
188
187
  logger.debug("listAllBranchFiles DONE", {
189
188
  projectRef,
190
- branchName,
189
+ branchRef,
191
190
  totalFiles: allFiles.length,
192
191
  });
193
192
 
194
193
  return allFiles;
195
194
  }
196
195
 
197
- getBranchFile(projectRef: string, branchName: string, pathOrId: string): Promise<FileDetail> {
196
+ getBranchFile(projectRef: string, branchRef: string, pathOrId: string): Promise<FileDetail> {
198
197
  return withSpan(
199
198
  SpanNames.API_GET_FILE,
200
199
  async () => {
201
- const url = `/projects/${encodeURIComponent(projectRef)}/branches/${
202
- encodeURIComponent(branchName)
203
- }/files/${encodeURIComponent(pathOrId)}`;
204
- logger.debug("getBranchFile", { projectRef, branchName, pathOrId });
200
+ const params = new URLSearchParams({ branch: branchRef });
201
+ const url = `/projects/${encodeURIComponent(projectRef)}/files/${
202
+ encodeURIComponent(pathOrId)
203
+ }?${params}`;
204
+ logger.debug("getBranchFile", { projectRef, branchRef, pathOrId });
205
205
 
206
206
  const raw = await this.request(url);
207
207
  const response = BranchFileDetailSchema.parse(raw);
@@ -217,7 +217,7 @@ export class VeryfrontAPIOperations {
217
217
  {
218
218
  "api.operation": "getBranchFile",
219
219
  "api.project": projectRef,
220
- "api.branch": branchName,
220
+ "api.branch": branchRef,
221
221
  "api.path": pathOrId,
222
222
  },
223
223
  );
@@ -179,13 +179,13 @@ export const API_ENDPOINTS = {
179
179
  },
180
180
  listBranchFiles: {
181
181
  method: "GET" as const,
182
- path: "/projects/{projectRef}/branches/{branchName}/files",
183
- description: "List files in a branch (draft/working copy)",
182
+ path: "/projects/{projectRef}/files?branch={branchRef}",
183
+ description: "List files for a branch ref or name (omit branch for main branch)",
184
184
  },
185
185
  getBranchFile: {
186
186
  method: "GET" as const,
187
- path: "/projects/{projectRef}/branches/{branchName}/files/{pathOrId}",
188
- description: "Get file from a branch by path or UUID",
187
+ path: "/projects/{projectRef}/files/{pathOrId}?branch={branchRef}",
188
+ description: "Get file from a branch ref or name by path or UUID",
189
189
  },
190
190
  listEnvironmentFiles: {
191
191
  method: "GET" as const,
@@ -66,6 +66,7 @@ export { isDeno } from "./compat/runtime.js";
66
66
 
67
67
  // Adapters: filesystem
68
68
  export { createFSAdapter, VeryfrontFSAdapter } from "./adapters/fs/index.js";
69
+ export { enhanceAdapterWithFS, isExtendedFSAdapter } from "./adapters/fs/index.js";
69
70
 
70
71
  // Adapters: API client
71
72
  export { VeryfrontApiClient } from "./adapters/veryfront-api-client/index.js";
@@ -55,7 +55,6 @@ import { MarkdownPreviewHandler } from "../handlers/preview/markdown-preview.han
55
55
  import { OpenAPIHandler } from "../handlers/request/openapi.handler.js";
56
56
  import { OpenAPIDocsHandler } from "../handlers/request/openapi-docs.handler.js";
57
57
  import { InternalAgentsListHandler } from "../handlers/request/internal-agents-list.handler.js";
58
- import { InternalTasksListHandler } from "../handlers/request/internal-tasks-list.handler.js";
59
58
  import { AgentStreamHandler } from "../handlers/request/agent-stream.handler.js";
60
59
  import { AgentRunResumeHandler } from "../handlers/request/agent-run-resume.handler.js";
61
60
  import { AgentRunCancelHandler } from "../handlers/request/agent-run-cancel.handler.js";
@@ -132,7 +131,6 @@ export const HANDLER_NAMES = [
132
131
  "OpenAPIHandler",
133
132
  "OpenAPIDocsHandler",
134
133
  "InternalAgentsListHandler",
135
- "InternalTasksListHandler",
136
134
  "AgentStreamHandler",
137
135
  "AgentRunResumeHandler",
138
136
  "AgentRunCancelHandler",
@@ -187,7 +185,6 @@ const handlerFactories: Record<
187
185
  OpenAPIHandler: () => new OpenAPIHandler(),
188
186
  OpenAPIDocsHandler: () => new OpenAPIDocsHandler(),
189
187
  InternalAgentsListHandler: () => new InternalAgentsListHandler(),
190
- InternalTasksListHandler: () => new InternalTasksListHandler(),
191
188
  AgentStreamHandler: () => new AgentStreamHandler(),
192
189
  AgentRunResumeHandler: () => new AgentRunResumeHandler(),
193
190
  AgentRunCancelHandler: () => new AgentRunCancelHandler(),
@@ -1,11 +0,0 @@
1
- import * as dntShim from "../../../../_dnt.shims.js";
2
- import { type RuntimeTaskDiscoveryDeps } from "../../../task/control-plane.js";
3
- import { BaseHandler } from "../response/base.js";
4
- import type { HandlerContext, HandlerMetadata, HandlerResult } from "../types.js";
5
- export declare class InternalTasksListHandler extends BaseHandler {
6
- private readonly deps;
7
- metadata: HandlerMetadata;
8
- constructor(deps?: RuntimeTaskDiscoveryDeps);
9
- handle(req: dntShim.Request, ctx: HandlerContext): Promise<HandlerResult>;
10
- }
11
- //# sourceMappingURL=internal-tasks-list.handler.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"internal-tasks-list.handler.d.ts","sourceRoot":"","sources":["../../../../../src/src/server/handlers/request/internal-tasks-list.handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,2BAA2B,CAAC;AAGrD,OAAO,EAKL,KAAK,wBAAwB,EAC9B,MAAM,gCAAgC,CAAC;AAUxC,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAmB,aAAa,EAAE,MAAM,aAAa,CAAC;AAEnG,qBAAa,wBAAyB,SAAQ,WAAW;IAQrD,OAAO,CAAC,QAAQ,CAAC,IAAI;IAPvB,QAAQ,EAAE,eAAe,CAIvB;gBAGiB,IAAI,GAAE,wBAA0D;IAK7E,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,OAAO,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;CAmEhF"}
@@ -1,72 +0,0 @@
1
- import { PRIORITY_MEDIUM_API } from "../../../utils/constants/index.js";
2
- import { ZodError } from "zod";
3
- import { ControlPlaneTasksListRequestSchema, defaultRuntimeTaskDiscoveryDeps, listRuntimeTasks, } from "../../../task/control-plane.js";
4
- import { ControlPlaneRequestError, verifyControlPlaneRequest, } from "../../../internal-agents/control-plane-auth.js";
5
- import { INTERNAL_AGENT_CONTROL_PLANE_MAX_BODY_BYTES, InternalAgentRequestBodyTooLargeError, readInternalAgentRequestBody, } from "../../../internal-agents/request-body.js";
6
- import { BaseHandler } from "../response/base.js";
7
- export class InternalTasksListHandler extends BaseHandler {
8
- deps;
9
- metadata = {
10
- name: "InternalTasksListHandler",
11
- priority: PRIORITY_MEDIUM_API,
12
- patterns: [{ pattern: "/internal/tasks/list", exact: true, method: "POST" }],
13
- };
14
- constructor(deps = defaultRuntimeTaskDiscoveryDeps) {
15
- super();
16
- this.deps = deps;
17
- }
18
- async handle(req, ctx) {
19
- if (!this.shouldHandle(req, ctx)) {
20
- return this.continue();
21
- }
22
- return this.withProxyContext(ctx, async () => {
23
- const builder = this.createResponseBuilder(ctx)
24
- .withCORS(req, ctx.securityConfig?.cors)
25
- .withSecurity(ctx.securityConfig ?? undefined, req);
26
- try {
27
- const rawBody = await readInternalAgentRequestBody(req, INTERNAL_AGENT_CONTROL_PLANE_MAX_BODY_BYTES);
28
- const payload = ControlPlaneTasksListRequestSchema.parse(JSON.parse(rawBody));
29
- const claims = await verifyControlPlaneRequest(req, ctx, rawBody, {
30
- expectedSubject: payload.requestId,
31
- expectedSurface: payload.surface,
32
- });
33
- if (payload.projectId !== claims.project_id ||
34
- (ctx.projectId !== undefined && payload.projectId !== ctx.projectId)) {
35
- this.logWarn("Internal tasks list request body did not match signed claims", {
36
- projectSlug: ctx.projectSlug,
37
- projectId: ctx.projectId,
38
- requestId: payload.requestId,
39
- signedRequestId: claims.sub,
40
- surface: payload.surface,
41
- signedSurface: claims.surface,
42
- });
43
- return this.respond(builder.json({ error: "Invalid control-plane signature" }, 401));
44
- }
45
- const response = await listRuntimeTasks(ctx, this.deps);
46
- return this.respond(builder.json(response, 200));
47
- }
48
- catch (error) {
49
- if (error instanceof InternalAgentRequestBodyTooLargeError) {
50
- return this.respond(builder.json({ error: error.message }, error.status));
51
- }
52
- if (error instanceof ControlPlaneRequestError) {
53
- this.logWarn("Internal tasks list signature verification failed", {
54
- error: error.message,
55
- projectSlug: ctx.projectSlug,
56
- projectId: ctx.projectId,
57
- });
58
- return this.respond(builder.json({ error: error.message }, error.status));
59
- }
60
- if (error instanceof SyntaxError || error instanceof ZodError) {
61
- this.logWarn("Internal tasks list request validation failed", {
62
- error: error instanceof Error ? error.message : String(error),
63
- projectSlug: ctx.projectSlug,
64
- projectId: ctx.projectId,
65
- });
66
- return this.respond(builder.json({ error: "Invalid internal tasks request" }, 400));
67
- }
68
- throw error;
69
- }
70
- });
71
- }
72
- }
@@ -1,105 +0,0 @@
1
- import type { HandlerContext } from "../types/index.js";
2
- import { z } from "zod";
3
- import { discoverTasks, type TaskDiscoveryOptions } from "./discovery.js";
4
- export declare const ControlPlaneTasksListRequestSchema: z.ZodObject<{
5
- requestId: z.ZodString;
6
- projectId: z.ZodString;
7
- surface: z.ZodEnum<["studio", "channels", "a2a", "mcp"]>;
8
- }, "strip", z.ZodTypeAny, {
9
- requestId: string;
10
- projectId: string;
11
- surface: "mcp" | "studio" | "channels" | "a2a";
12
- }, {
13
- requestId: string;
14
- projectId: string;
15
- surface: "mcp" | "studio" | "channels" | "a2a";
16
- }>;
17
- export declare const RuntimeTaskSchema: z.ZodObject<{
18
- id: z.ZodString;
19
- name: z.ZodString;
20
- description: z.ZodNullable<z.ZodString>;
21
- target: z.ZodString;
22
- sourcePath: z.ZodString;
23
- inputSchema: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
24
- outputSchema: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
25
- schedulable: z.ZodBoolean;
26
- }, "strip", z.ZodTypeAny, {
27
- description: string | null;
28
- name: string;
29
- id: string;
30
- target: string;
31
- sourcePath: string;
32
- outputSchema: Record<string, unknown> | null;
33
- inputSchema: Record<string, unknown> | null;
34
- schedulable: boolean;
35
- }, {
36
- description: string | null;
37
- name: string;
38
- id: string;
39
- target: string;
40
- sourcePath: string;
41
- outputSchema: Record<string, unknown> | null;
42
- inputSchema: Record<string, unknown> | null;
43
- schedulable: boolean;
44
- }>;
45
- export declare const RuntimeTaskListResponseSchema: z.ZodObject<{
46
- tasks: z.ZodArray<z.ZodObject<{
47
- id: z.ZodString;
48
- name: z.ZodString;
49
- description: z.ZodNullable<z.ZodString>;
50
- target: z.ZodString;
51
- sourcePath: z.ZodString;
52
- inputSchema: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
53
- outputSchema: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
54
- schedulable: z.ZodBoolean;
55
- }, "strip", z.ZodTypeAny, {
56
- description: string | null;
57
- name: string;
58
- id: string;
59
- target: string;
60
- sourcePath: string;
61
- outputSchema: Record<string, unknown> | null;
62
- inputSchema: Record<string, unknown> | null;
63
- schedulable: boolean;
64
- }, {
65
- description: string | null;
66
- name: string;
67
- id: string;
68
- target: string;
69
- sourcePath: string;
70
- outputSchema: Record<string, unknown> | null;
71
- inputSchema: Record<string, unknown> | null;
72
- schedulable: boolean;
73
- }>, "many">;
74
- }, "strip", z.ZodTypeAny, {
75
- tasks: {
76
- description: string | null;
77
- name: string;
78
- id: string;
79
- target: string;
80
- sourcePath: string;
81
- outputSchema: Record<string, unknown> | null;
82
- inputSchema: Record<string, unknown> | null;
83
- schedulable: boolean;
84
- }[];
85
- }, {
86
- tasks: {
87
- description: string | null;
88
- name: string;
89
- id: string;
90
- target: string;
91
- sourcePath: string;
92
- outputSchema: Record<string, unknown> | null;
93
- inputSchema: Record<string, unknown> | null;
94
- schedulable: boolean;
95
- }[];
96
- }>;
97
- export type ControlPlaneTasksListRequest = z.infer<typeof ControlPlaneTasksListRequestSchema>;
98
- export type RuntimeTask = z.infer<typeof RuntimeTaskSchema>;
99
- export type RuntimeTaskListResponse = z.infer<typeof RuntimeTaskListResponseSchema>;
100
- export interface RuntimeTaskDiscoveryDeps {
101
- discoverTasks: (options: TaskDiscoveryOptions) => ReturnType<typeof discoverTasks>;
102
- }
103
- export declare const defaultRuntimeTaskDiscoveryDeps: RuntimeTaskDiscoveryDeps;
104
- export declare function listRuntimeTasks(ctx: HandlerContext, deps?: RuntimeTaskDiscoveryDeps): Promise<RuntimeTaskListResponse>;
105
- //# sourceMappingURL=control-plane.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"control-plane.d.ts","sourceRoot":"","sources":["../../../src/src/task/control-plane.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAE1E,eAAO,MAAM,kCAAkC;;;;;;;;;;;;EAI7C,CAAC;AAIH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;EAS5B,CAAC;AAEH,eAAO,MAAM,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAExC,CAAC;AAEH,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAC9F,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,MAAM,MAAM,uBAAuB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,6BAA6B,CAAC,CAAC;AAEpF,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;CACpF;AAED,eAAO,MAAM,+BAA+B,EAAE,wBAE7C,CAAC;AAUF,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,cAAc,EACnB,IAAI,GAAE,wBAA0D,GAC/D,OAAO,CAAC,uBAAuB,CAAC,CAwBlC"}
@@ -1,52 +0,0 @@
1
- import { ControlPlaneSurfaceSchema } from "../channels/control-plane.js";
2
- import { z } from "zod";
3
- import { discoverTasks } from "./discovery.js";
4
- export const ControlPlaneTasksListRequestSchema = z.object({
5
- requestId: z.string().min(1),
6
- projectId: z.string().min(1),
7
- surface: ControlPlaneSurfaceSchema,
8
- });
9
- const JsonSchemaRecordSchema = z.record(z.unknown());
10
- export const RuntimeTaskSchema = z.object({
11
- id: z.string().min(1),
12
- name: z.string().min(1),
13
- description: z.string().nullable(),
14
- target: z.string().min(1),
15
- sourcePath: z.string().min(1),
16
- inputSchema: JsonSchemaRecordSchema.nullable(),
17
- outputSchema: JsonSchemaRecordSchema.nullable(),
18
- schedulable: z.boolean(),
19
- });
20
- export const RuntimeTaskListResponseSchema = z.object({
21
- tasks: z.array(RuntimeTaskSchema),
22
- });
23
- export const defaultRuntimeTaskDiscoveryDeps = {
24
- discoverTasks,
25
- };
26
- function normalizeJsonSchema(value) {
27
- if (value == null || typeof value !== "object" || Array.isArray(value)) {
28
- return null;
29
- }
30
- return value;
31
- }
32
- export async function listRuntimeTasks(ctx, deps = defaultRuntimeTaskDiscoveryDeps) {
33
- const discovery = await deps.discoverTasks({
34
- projectDir: ctx.projectDir,
35
- adapter: ctx.adapter,
36
- config: ctx.config,
37
- debug: ctx.debug ?? false,
38
- });
39
- const tasks = discovery.tasks
40
- .map((task) => RuntimeTaskSchema.parse({
41
- id: task.id,
42
- name: task.name,
43
- description: task.definition.description ?? null,
44
- target: `task:${task.id}`,
45
- sourcePath: task.filePath,
46
- inputSchema: normalizeJsonSchema(task.definition.inputSchema),
47
- outputSchema: normalizeJsonSchema(task.definition.outputSchema),
48
- schedulable: task.definition.schedulable ?? true,
49
- }))
50
- .sort((left, right) => left.name.localeCompare(right.name));
51
- return RuntimeTaskListResponseSchema.parse({ tasks });
52
- }
@@ -1,103 +0,0 @@
1
- import * as dntShim from "../../../../_dnt.shims.js";
2
- import { PRIORITY_MEDIUM_API } from "../../../utils/constants/index.js";
3
- import { ZodError } from "zod";
4
- import {
5
- type ControlPlaneTasksListRequest,
6
- ControlPlaneTasksListRequestSchema,
7
- defaultRuntimeTaskDiscoveryDeps,
8
- listRuntimeTasks,
9
- type RuntimeTaskDiscoveryDeps,
10
- } from "../../../task/control-plane.js";
11
- import {
12
- ControlPlaneRequestError,
13
- verifyControlPlaneRequest,
14
- } from "../../../internal-agents/control-plane-auth.js";
15
- import {
16
- INTERNAL_AGENT_CONTROL_PLANE_MAX_BODY_BYTES,
17
- InternalAgentRequestBodyTooLargeError,
18
- readInternalAgentRequestBody,
19
- } from "../../../internal-agents/request-body.js";
20
- import { BaseHandler } from "../response/base.js";
21
- import type { HandlerContext, HandlerMetadata, HandlerPriority, HandlerResult } from "../types.js";
22
-
23
- export class InternalTasksListHandler extends BaseHandler {
24
- metadata: HandlerMetadata = {
25
- name: "InternalTasksListHandler",
26
- priority: PRIORITY_MEDIUM_API as HandlerPriority,
27
- patterns: [{ pattern: "/internal/tasks/list", exact: true, method: "POST" }],
28
- };
29
-
30
- constructor(
31
- private readonly deps: RuntimeTaskDiscoveryDeps = defaultRuntimeTaskDiscoveryDeps,
32
- ) {
33
- super();
34
- }
35
-
36
- async handle(req: dntShim.Request, ctx: HandlerContext): Promise<HandlerResult> {
37
- if (!this.shouldHandle(req, ctx)) {
38
- return this.continue();
39
- }
40
-
41
- return this.withProxyContext(ctx, async () => {
42
- const builder = this.createResponseBuilder(ctx)
43
- .withCORS(req, ctx.securityConfig?.cors)
44
- .withSecurity(ctx.securityConfig ?? undefined, req);
45
-
46
- try {
47
- const rawBody = await readInternalAgentRequestBody(
48
- req,
49
- INTERNAL_AGENT_CONTROL_PLANE_MAX_BODY_BYTES,
50
- );
51
- const payload: ControlPlaneTasksListRequest = ControlPlaneTasksListRequestSchema.parse(
52
- JSON.parse(rawBody),
53
- );
54
- const claims = await verifyControlPlaneRequest(req, ctx, rawBody, {
55
- expectedSubject: payload.requestId,
56
- expectedSurface: payload.surface,
57
- });
58
-
59
- if (
60
- payload.projectId !== claims.project_id ||
61
- (ctx.projectId !== undefined && payload.projectId !== ctx.projectId)
62
- ) {
63
- this.logWarn("Internal tasks list request body did not match signed claims", {
64
- projectSlug: ctx.projectSlug,
65
- projectId: ctx.projectId,
66
- requestId: payload.requestId,
67
- signedRequestId: claims.sub,
68
- surface: payload.surface,
69
- signedSurface: claims.surface,
70
- });
71
- return this.respond(builder.json({ error: "Invalid control-plane signature" }, 401));
72
- }
73
-
74
- const response = await listRuntimeTasks(ctx, this.deps);
75
- return this.respond(builder.json(response, 200));
76
- } catch (error) {
77
- if (error instanceof InternalAgentRequestBodyTooLargeError) {
78
- return this.respond(builder.json({ error: error.message }, error.status));
79
- }
80
-
81
- if (error instanceof ControlPlaneRequestError) {
82
- this.logWarn("Internal tasks list signature verification failed", {
83
- error: error.message,
84
- projectSlug: ctx.projectSlug,
85
- projectId: ctx.projectId,
86
- });
87
- return this.respond(builder.json({ error: error.message }, error.status));
88
- }
89
-
90
- if (error instanceof SyntaxError || error instanceof ZodError) {
91
- this.logWarn("Internal tasks list request validation failed", {
92
- error: error instanceof Error ? error.message : String(error),
93
- projectSlug: ctx.projectSlug,
94
- projectId: ctx.projectId,
95
- });
96
- return this.respond(builder.json({ error: "Invalid internal tasks request" }, 400));
97
- }
98
-
99
- throw error;
100
- }
101
- });
102
- }
103
- }
@@ -1,76 +0,0 @@
1
- import { ControlPlaneSurfaceSchema } from "../channels/control-plane.js";
2
- import type { HandlerContext } from "../types/index.js";
3
- import { z } from "zod";
4
- import { discoverTasks, type TaskDiscoveryOptions } from "./discovery.js";
5
-
6
- export const ControlPlaneTasksListRequestSchema = z.object({
7
- requestId: z.string().min(1),
8
- projectId: z.string().min(1),
9
- surface: ControlPlaneSurfaceSchema,
10
- });
11
-
12
- const JsonSchemaRecordSchema = z.record(z.unknown());
13
-
14
- export const RuntimeTaskSchema = z.object({
15
- id: z.string().min(1),
16
- name: z.string().min(1),
17
- description: z.string().nullable(),
18
- target: z.string().min(1),
19
- sourcePath: z.string().min(1),
20
- inputSchema: JsonSchemaRecordSchema.nullable(),
21
- outputSchema: JsonSchemaRecordSchema.nullable(),
22
- schedulable: z.boolean(),
23
- });
24
-
25
- export const RuntimeTaskListResponseSchema = z.object({
26
- tasks: z.array(RuntimeTaskSchema),
27
- });
28
-
29
- export type ControlPlaneTasksListRequest = z.infer<typeof ControlPlaneTasksListRequestSchema>;
30
- export type RuntimeTask = z.infer<typeof RuntimeTaskSchema>;
31
- export type RuntimeTaskListResponse = z.infer<typeof RuntimeTaskListResponseSchema>;
32
-
33
- export interface RuntimeTaskDiscoveryDeps {
34
- discoverTasks: (options: TaskDiscoveryOptions) => ReturnType<typeof discoverTasks>;
35
- }
36
-
37
- export const defaultRuntimeTaskDiscoveryDeps: RuntimeTaskDiscoveryDeps = {
38
- discoverTasks,
39
- };
40
-
41
- function normalizeJsonSchema(value: unknown): Record<string, unknown> | null {
42
- if (value == null || typeof value !== "object" || Array.isArray(value)) {
43
- return null;
44
- }
45
-
46
- return value as Record<string, unknown>;
47
- }
48
-
49
- export async function listRuntimeTasks(
50
- ctx: HandlerContext,
51
- deps: RuntimeTaskDiscoveryDeps = defaultRuntimeTaskDiscoveryDeps,
52
- ): Promise<RuntimeTaskListResponse> {
53
- const discovery = await deps.discoverTasks({
54
- projectDir: ctx.projectDir,
55
- adapter: ctx.adapter,
56
- config: ctx.config,
57
- debug: ctx.debug ?? false,
58
- });
59
-
60
- const tasks = discovery.tasks
61
- .map((task) =>
62
- RuntimeTaskSchema.parse({
63
- id: task.id,
64
- name: task.name,
65
- description: task.definition.description ?? null,
66
- target: `task:${task.id}`,
67
- sourcePath: task.filePath,
68
- inputSchema: normalizeJsonSchema(task.definition.inputSchema),
69
- outputSchema: normalizeJsonSchema(task.definition.outputSchema),
70
- schedulable: task.definition.schedulable ?? true,
71
- })
72
- )
73
- .sort((left, right) => left.name.localeCompare(right.name));
74
-
75
- return RuntimeTaskListResponseSchema.parse({ tasks });
76
- }