@treeseed/agent 0.8.5

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 (138) hide show
  1. package/Dockerfile +7 -0
  2. package/README.md +198 -0
  3. package/dist/agent-runtime.d.ts +17 -0
  4. package/dist/agent-runtime.js +117 -0
  5. package/dist/agents/adapters/execution.d.ts +41 -0
  6. package/dist/agents/adapters/execution.js +73 -0
  7. package/dist/agents/adapters/mutations.d.ts +22 -0
  8. package/dist/agents/adapters/mutations.js +30 -0
  9. package/dist/agents/adapters/notification.d.ts +26 -0
  10. package/dist/agents/adapters/notification.js +46 -0
  11. package/dist/agents/adapters/repository.d.ts +28 -0
  12. package/dist/agents/adapters/repository.js +61 -0
  13. package/dist/agents/adapters/research.d.ts +26 -0
  14. package/dist/agents/adapters/research.js +59 -0
  15. package/dist/agents/adapters/verification.d.ts +36 -0
  16. package/dist/agents/adapters/verification.js +62 -0
  17. package/dist/agents/cli-tools.d.ts +1 -0
  18. package/dist/agents/cli-tools.js +5 -0
  19. package/dist/agents/cli.d.ts +15 -0
  20. package/dist/agents/cli.js +109 -0
  21. package/dist/agents/contracts/messages.d.ts +88 -0
  22. package/dist/agents/contracts/messages.js +138 -0
  23. package/dist/agents/contracts/run.d.ts +21 -0
  24. package/dist/agents/contracts/run.js +0 -0
  25. package/dist/agents/index.d.ts +1 -0
  26. package/dist/agents/index.js +5 -0
  27. package/dist/agents/kernel/agent-kernel.d.ts +63 -0
  28. package/dist/agents/kernel/agent-kernel.js +291 -0
  29. package/dist/agents/kernel/trigger-resolver.d.ts +19 -0
  30. package/dist/agents/kernel/trigger-resolver.js +157 -0
  31. package/dist/agents/registry-helper.d.ts +4 -0
  32. package/dist/agents/registry-helper.js +14 -0
  33. package/dist/agents/registry.d.ts +6 -0
  34. package/dist/agents/registry.js +98 -0
  35. package/dist/agents/runtime-types.d.ts +118 -0
  36. package/dist/agents/runtime-types.js +0 -0
  37. package/dist/agents/spec-loader.d.ts +18 -0
  38. package/dist/agents/spec-loader.js +54 -0
  39. package/dist/agents/spec-normalizer.d.ts +2 -0
  40. package/dist/agents/spec-normalizer.js +327 -0
  41. package/dist/agents/spec-types.d.ts +64 -0
  42. package/dist/agents/spec-types.js +0 -0
  43. package/dist/agents/testing/agents-smoke.d.ts +1 -0
  44. package/dist/agents/testing/agents-smoke.js +32 -0
  45. package/dist/agents/testing/e2e-harness.d.ts +44 -0
  46. package/dist/agents/testing/e2e-harness.js +503 -0
  47. package/dist/api/agent-routes.d.ts +13 -0
  48. package/dist/api/agent-routes.js +327 -0
  49. package/dist/api/app.d.ts +8 -0
  50. package/dist/api/app.js +444 -0
  51. package/dist/api/auth/d1-database.d.ts +3 -0
  52. package/dist/api/auth/d1-database.js +20 -0
  53. package/dist/api/auth/d1-provider.d.ts +79 -0
  54. package/dist/api/auth/d1-provider.js +92 -0
  55. package/dist/api/auth/d1-store.d.ts +114 -0
  56. package/dist/api/auth/d1-store.js +895 -0
  57. package/dist/api/auth/memory-provider.d.ts +77 -0
  58. package/dist/api/auth/memory-provider.js +249 -0
  59. package/dist/api/auth/rbac.d.ts +22 -0
  60. package/dist/api/auth/rbac.js +162 -0
  61. package/dist/api/auth/tokens.d.ts +18 -0
  62. package/dist/api/auth/tokens.js +56 -0
  63. package/dist/api/capabilities.d.ts +9 -0
  64. package/dist/api/capabilities.js +33 -0
  65. package/dist/api/config.d.ts +2 -0
  66. package/dist/api/config.js +77 -0
  67. package/dist/api/http.d.ts +28 -0
  68. package/dist/api/http.js +51 -0
  69. package/dist/api/index.d.ts +9 -0
  70. package/dist/api/index.js +20 -0
  71. package/dist/api/operations-routes.d.ts +11 -0
  72. package/dist/api/operations-routes.js +87 -0
  73. package/dist/api/operations.d.ts +3 -0
  74. package/dist/api/operations.js +26 -0
  75. package/dist/api/project-routes.d.ts +8 -0
  76. package/dist/api/project-routes.js +585 -0
  77. package/dist/api/providers.d.ts +2 -0
  78. package/dist/api/providers.js +62 -0
  79. package/dist/api/railway.d.ts +51 -0
  80. package/dist/api/railway.js +71 -0
  81. package/dist/api/sdk-dispatch.d.ts +5 -0
  82. package/dist/api/sdk-dispatch.js +13 -0
  83. package/dist/api/sdk-routes.d.ts +11 -0
  84. package/dist/api/sdk-routes.js +29 -0
  85. package/dist/api/server.d.ts +2 -0
  86. package/dist/api/server.js +10 -0
  87. package/dist/api/templates.d.ts +3 -0
  88. package/dist/api/templates.js +31 -0
  89. package/dist/api/types.d.ts +237 -0
  90. package/dist/api/types.js +0 -0
  91. package/dist/env.yaml +957 -0
  92. package/dist/index.d.ts +14 -0
  93. package/dist/index.js +41 -0
  94. package/dist/scripts/assert-release-tag-version.d.ts +1 -0
  95. package/dist/scripts/assert-release-tag-version.js +20 -0
  96. package/dist/scripts/build-dist.d.ts +1 -0
  97. package/dist/scripts/build-dist.js +106 -0
  98. package/dist/scripts/package-tools.d.ts +1 -0
  99. package/dist/scripts/package-tools.js +7 -0
  100. package/dist/scripts/publish-package.d.ts +1 -0
  101. package/dist/scripts/publish-package.js +24 -0
  102. package/dist/scripts/release-verify.d.ts +1 -0
  103. package/dist/scripts/release-verify.js +152 -0
  104. package/dist/scripts/test-smoke.d.ts +1 -0
  105. package/dist/scripts/test-smoke.js +23 -0
  106. package/dist/scripts/treeseed-agent-api.d.ts +2 -0
  107. package/dist/scripts/treeseed-agent-api.js +25 -0
  108. package/dist/scripts/treeseed-agent-service.d.ts +2 -0
  109. package/dist/scripts/treeseed-agent-service.js +36 -0
  110. package/dist/scripts/treeseed-agents.d.ts +2 -0
  111. package/dist/scripts/treeseed-agents.js +13 -0
  112. package/dist/services/agents.d.ts +17 -0
  113. package/dist/services/agents.js +48 -0
  114. package/dist/services/common.d.ts +66 -0
  115. package/dist/services/common.js +212 -0
  116. package/dist/services/index.d.ts +6 -0
  117. package/dist/services/index.js +19 -0
  118. package/dist/services/manager.d.ts +333 -0
  119. package/dist/services/manager.js +1368 -0
  120. package/dist/services/remote-runner.d.ts +30 -0
  121. package/dist/services/remote-runner.js +230 -0
  122. package/dist/services/workday-content.d.ts +53 -0
  123. package/dist/services/workday-content.js +190 -0
  124. package/dist/services/workday-manager.d.ts +391 -0
  125. package/dist/services/workday-manager.js +163 -0
  126. package/dist/services/workday-report.d.ts +238 -0
  127. package/dist/services/workday-report.js +17 -0
  128. package/dist/services/workday-start.d.ts +238 -0
  129. package/dist/services/workday-start.js +17 -0
  130. package/dist/services/worker-capacity.d.ts +58 -0
  131. package/dist/services/worker-capacity.js +208 -0
  132. package/dist/services/worker-pool-scaler.d.ts +27 -0
  133. package/dist/services/worker-pool-scaler.js +127 -0
  134. package/dist/services/worker.d.ts +19 -0
  135. package/dist/services/worker.js +436 -0
  136. package/dist/templates/github/deploy-processing.workflow.yml +119 -0
  137. package/package.json +136 -0
  138. package/templates/github/deploy-processing.workflow.yml +119 -0
@@ -0,0 +1,77 @@
1
+ import { existsSync } from "node:fs";
2
+ import { resolve } from "node:path";
3
+ function parseInteger(value, fallback) {
4
+ if (!value) return fallback;
5
+ const parsed = Number.parseInt(value, 10);
6
+ return Number.isFinite(parsed) ? parsed : fallback;
7
+ }
8
+ function resolveLocalWranglerConfigPath(repoRoot, env) {
9
+ const explicit = env.TREESEED_API_D1_WRANGLER_CONFIG?.trim() || env.TREESEED_LOCAL_WRANGLER_CONFIG?.trim();
10
+ if (explicit) return resolve(repoRoot, explicit);
11
+ const generated = resolve(repoRoot, ".treeseed", "generated", "environments", "local", "wrangler.toml");
12
+ return existsSync(generated) ? generated : void 0;
13
+ }
14
+ function normalizeUrl(value) {
15
+ return value.endsWith("/") ? value.slice(0, -1) : value;
16
+ }
17
+ function parseCsv(value) {
18
+ return (value ?? "").split(",").map((entry) => entry.trim().toLowerCase()).filter(Boolean);
19
+ }
20
+ function resolveBaseUrl(env, host, port) {
21
+ if (env.TREESEED_API_BASE_URL?.trim()) {
22
+ return normalizeUrl(env.TREESEED_API_BASE_URL.trim());
23
+ }
24
+ if (env.RAILWAY_PUBLIC_DOMAIN?.trim()) {
25
+ return normalizeUrl(`https://${env.RAILWAY_PUBLIC_DOMAIN.trim()}`);
26
+ }
27
+ return normalizeUrl(`http://${host}:${port}`);
28
+ }
29
+ function resolveApiConfig(env = process.env) {
30
+ const host = env.HOST?.trim() || "0.0.0.0";
31
+ const port = parseInteger(env.PORT, 3e3);
32
+ const baseUrl = resolveBaseUrl(env, host === "0.0.0.0" ? "127.0.0.1" : host, port);
33
+ const issuer = normalizeUrl(env.TREESEED_API_ISSUER?.trim() || baseUrl);
34
+ const repoRoot = resolve(env.TREESEED_API_REPO_ROOT?.trim() || process.cwd());
35
+ return {
36
+ name: env.TREESEED_API_NAME?.trim() || "@treeseed/agent/api",
37
+ host,
38
+ port,
39
+ baseUrl,
40
+ issuer,
41
+ repoRoot,
42
+ projectId: env.TREESEED_PROJECT_ID?.trim() || "treeseed-project",
43
+ authSecret: env.TREESEED_API_AUTH_SECRET?.trim() || "treeseed-api-dev-secret",
44
+ projectApiKey: env.TREESEED_API_PROJECT_KEY?.trim() || void 0,
45
+ projectApiLabel: env.TREESEED_API_PROJECT_LABEL?.trim() || "Project API Key",
46
+ projectApiPermissions: parseCsv(env.TREESEED_API_PROJECT_KEY_PERMISSIONS).length > 0 ? parseCsv(env.TREESEED_API_PROJECT_KEY_PERMISSIONS) : ["sdk:execute:global", "agent:execute:global", "operations:execute:global"],
47
+ cloudflareAccountId: env.CLOUDFLARE_ACCOUNT_ID?.trim() || void 0,
48
+ cloudflareApiToken: env.CLOUDFLARE_API_TOKEN?.trim() || void 0,
49
+ d1DatabaseId: env.TREESEED_API_D1_DATABASE_ID?.trim() || void 0,
50
+ d1DatabaseName: env.TREESEED_API_D1_DATABASE_NAME?.trim() || env.SITE_DATA_DB?.trim() || void 0,
51
+ d1LocalPersistTo: env.TREESEED_API_D1_LOCAL_PERSIST_TO?.trim() || resolve(repoRoot, ".wrangler/state/v3/d1"),
52
+ d1WranglerConfigPath: resolveLocalWranglerConfigPath(repoRoot, env),
53
+ webServiceId: env.TREESEED_API_WEB_SERVICE_ID?.trim() || "web",
54
+ webServiceSecret: env.TREESEED_API_WEB_SERVICE_SECRET?.trim() || "treeseed-web-service-dev-secret",
55
+ webAssertionSecret: env.TREESEED_API_WEB_ASSERTION_SECRET?.trim() || env.TREESEED_API_AUTH_SECRET?.trim() || "treeseed-web-assertion-dev-secret",
56
+ webExchangeTtlSeconds: parseInteger(env.TREESEED_API_WEB_EXCHANGE_TTL, 300),
57
+ bootstrapAdminAllowlist: parseCsv(env.TREESEED_API_BOOTSTRAP_ADMIN_ALLOWLIST),
58
+ accessTokenTtlSeconds: parseInteger(env.TREESEED_API_ACCESS_TOKEN_TTL, 900),
59
+ refreshTokenTtlSeconds: parseInteger(env.TREESEED_API_REFRESH_TOKEN_TTL, 7 * 24 * 60 * 60),
60
+ deviceCodeTtlSeconds: parseInteger(env.TREESEED_API_DEVICE_CODE_TTL, 10 * 60),
61
+ deviceCodePollIntervalSeconds: parseInteger(env.TREESEED_API_DEVICE_CODE_POLL_INTERVAL, 5),
62
+ templateCatalogPath: env.TREESEED_API_TEMPLATE_CATALOG_PATH?.trim() || void 0,
63
+ providers: {
64
+ auth: env.TREESEED_API_PROVIDER_AUTH?.trim() || "d1",
65
+ agents: {
66
+ execution: env.TREESEED_API_PROVIDER_AGENT_EXECUTION?.trim() || "stub",
67
+ queue: env.TREESEED_API_PROVIDER_AGENT_QUEUE?.trim() || "memory",
68
+ notification: env.TREESEED_API_PROVIDER_AGENT_NOTIFICATION?.trim() || "stub",
69
+ repository: env.TREESEED_API_PROVIDER_AGENT_REPOSITORY?.trim() || "stub",
70
+ verification: env.TREESEED_API_PROVIDER_AGENT_VERIFICATION?.trim() || "stub"
71
+ }
72
+ }
73
+ };
74
+ }
75
+ export {
76
+ resolveApiConfig
77
+ };
@@ -0,0 +1,28 @@
1
+ import type { Context } from 'hono';
2
+ import type { ApiPrincipal, ApiScope } from '@treeseed/sdk/remote';
3
+ import type { AppVariables } from './types.ts';
4
+ export type ApiContext = Context<{
5
+ Variables: AppVariables;
6
+ }>;
7
+ export declare function jsonError(c: Context, status: number, error: string, details?: Record<string, unknown>): Response & import("hono").TypedResponse<{
8
+ ok: false;
9
+ error: string;
10
+ }, never, "json">;
11
+ export declare function bearerTokenFromRequest(request: Request): string | null;
12
+ export declare function hasScope(principal: ApiPrincipal | null, requiredScope: ApiScope): boolean;
13
+ export declare function requireScope(c: ApiContext, requiredScope: ApiScope): (Response & import("hono").TypedResponse<{
14
+ ok: false;
15
+ error: string;
16
+ }, never, "json">) | null;
17
+ export declare function requireAuthentication(c: ApiContext): (Response & import("hono").TypedResponse<{
18
+ ok: false;
19
+ error: string;
20
+ }, never, "json">) | null;
21
+ export declare function requireActorType(c: ApiContext, actorType: 'anonymous' | 'user' | 'service' | 'project', message?: string): (Response & import("hono").TypedResponse<{
22
+ ok: false;
23
+ error: string;
24
+ }, never, "json">) | null;
25
+ export declare function requirePermission(c: ApiContext, permission: string): (Response & import("hono").TypedResponse<{
26
+ ok: false;
27
+ error: string;
28
+ }, never, "json">) | null;
@@ -0,0 +1,51 @@
1
+ import { permissionGranted } from "./auth/rbac.js";
2
+ function jsonError(c, status, error, details) {
3
+ return c.json({
4
+ ok: false,
5
+ error,
6
+ ...details ?? {}
7
+ }, { status });
8
+ }
9
+ function bearerTokenFromRequest(request) {
10
+ const header = request.headers.get("authorization");
11
+ if (!header) return null;
12
+ const match = header.match(/^Bearer\s+(.+)$/i);
13
+ return match?.[1] ?? null;
14
+ }
15
+ function hasScope(principal, requiredScope) {
16
+ return Boolean(principal && (principal.scopes.includes(requiredScope) || principal.scopes.includes("*")));
17
+ }
18
+ function requireScope(c, requiredScope) {
19
+ if (!hasScope(c.get("principal"), requiredScope)) {
20
+ return jsonError(c, 401, "Authentication required.", { requiredScope });
21
+ }
22
+ return null;
23
+ }
24
+ function requireAuthentication(c) {
25
+ if (!c.get("principal")) {
26
+ return jsonError(c, 401, "Authentication required.");
27
+ }
28
+ return null;
29
+ }
30
+ function requireActorType(c, actorType, message = "Trusted service authentication required.") {
31
+ if (c.get("actorType") !== actorType) {
32
+ return jsonError(c, 401, message);
33
+ }
34
+ return null;
35
+ }
36
+ function requirePermission(c, permission) {
37
+ const principal = c.get("principal");
38
+ if (!principal || !permissionGranted(c.get("permissionGrants"), permission)) {
39
+ return jsonError(c, 403, "Permission denied.", { permission });
40
+ }
41
+ return null;
42
+ }
43
+ export {
44
+ bearerTokenFromRequest,
45
+ hasScope,
46
+ jsonError,
47
+ requireActorType,
48
+ requireAuthentication,
49
+ requirePermission,
50
+ requireScope
51
+ };
@@ -0,0 +1,9 @@
1
+ export { createTreeseedApiApp, createTreeseedApiRouter } from './app.ts';
2
+ export { resolveApiConfig } from './config.ts';
3
+ export { createRailwayTreeseedApiServer, createTreeseedNodeServer } from './railway.ts';
4
+ export { resolveApiRuntimeProviders } from './providers.ts';
5
+ export { resolveApiD1Database } from './auth/d1-database.ts';
6
+ export { loadTemplateCatalog } from './templates.ts';
7
+ export { MemoryDeviceCodeAuthProvider } from './auth/memory-provider.ts';
8
+ export { D1AuthProvider } from './auth/d1-provider.ts';
9
+ export type * from './types.ts';
@@ -0,0 +1,20 @@
1
+ import { createTreeseedApiApp, createTreeseedApiRouter } from "./app.js";
2
+ import { resolveApiConfig } from "./config.js";
3
+ import { createRailwayTreeseedApiServer, createTreeseedNodeServer } from "./railway.js";
4
+ import { resolveApiRuntimeProviders } from "./providers.js";
5
+ import { resolveApiD1Database } from "./auth/d1-database.js";
6
+ import { loadTemplateCatalog } from "./templates.js";
7
+ import { MemoryDeviceCodeAuthProvider } from "./auth/memory-provider.js";
8
+ import { D1AuthProvider } from "./auth/d1-provider.js";
9
+ export {
10
+ D1AuthProvider,
11
+ MemoryDeviceCodeAuthProvider,
12
+ createRailwayTreeseedApiServer,
13
+ createTreeseedApiApp,
14
+ createTreeseedApiRouter,
15
+ createTreeseedNodeServer,
16
+ loadTemplateCatalog,
17
+ resolveApiConfig,
18
+ resolveApiD1Database,
19
+ resolveApiRuntimeProviders
20
+ };
@@ -0,0 +1,11 @@
1
+ import type { Hono } from 'hono';
2
+ import type { AgentSdk } from '@treeseed/sdk';
3
+ import { executeHttpWorkflowOperation } from './operations.ts';
4
+ import type { ApiConfig } from './types.ts';
5
+ export declare function registerOperationRoutes(app: Hono<any>, options: {
6
+ config: ApiConfig;
7
+ scope: string;
8
+ prefix?: string;
9
+ sdk?: AgentSdk;
10
+ executeOperation?: typeof executeHttpWorkflowOperation;
11
+ }): void;
@@ -0,0 +1,87 @@
1
+ import crypto from "node:crypto";
2
+ import { findDispatchCapability, findTreeseedOperation } from "@treeseed/sdk";
3
+ import { executeHttpWorkflowOperation, isHttpWorkflowOperationAllowed } from "./operations.js";
4
+ import { enqueueTaskFromSdk } from "../services/common.js";
5
+ import { enqueueTaskAndEnsureCapacity } from "../services/worker-capacity.js";
6
+ import { jsonError, requireScope } from "./http.js";
7
+ function registerOperationRoutes(app, options) {
8
+ const executeOperation = options.executeOperation ?? executeHttpWorkflowOperation;
9
+ const prefix = options.prefix ?? "";
10
+ function withPrefix(path) {
11
+ if (!prefix) return path;
12
+ return `${prefix}${path}`.replace(/\/{2,}/g, "/");
13
+ }
14
+ app.post(withPrefix("/operations/:operation"), async (c) => {
15
+ const unauthorized = requireScope(c, options.scope);
16
+ if (unauthorized) return unauthorized;
17
+ const requestedOperation = c.req.param("operation");
18
+ const resolvedOperation = findTreeseedOperation(requestedOperation);
19
+ if (!resolvedOperation) {
20
+ return jsonError(c, 400, `Unknown Treeseed operation "${requestedOperation}".`, {
21
+ operation: requestedOperation
22
+ });
23
+ }
24
+ if (!isHttpWorkflowOperationAllowed(resolvedOperation.name)) {
25
+ return jsonError(c, 400, `Workflow operation "${resolvedOperation.name}" is not supported over HTTP.`, {
26
+ operation: resolvedOperation.name
27
+ });
28
+ }
29
+ const body = await c.req.json().catch(() => ({}));
30
+ try {
31
+ const capability = findDispatchCapability("workflow", resolvedOperation.name);
32
+ if (capability?.executionClass === "remote_job" && options.sdk) {
33
+ const input = body && typeof body.input === "object" ? body.input : {};
34
+ const idempotencyKey = typeof body.idempotencyKey === "string" && body.idempotencyKey.trim() ? body.idempotencyKey.trim() : `workflow:${resolvedOperation.name}:${crypto.createHash("sha256").update(JSON.stringify(input)).digest("hex")}`;
35
+ const created = await options.sdk.createTask({
36
+ workDayId: typeof body.workDayId === "string" ? body.workDayId : "",
37
+ agentId: "workflow-dispatch",
38
+ type: "workflow_dispatch",
39
+ priority: typeof body.priority === "number" ? body.priority : 75,
40
+ idempotencyKey,
41
+ payload: {
42
+ executionKind: "workflow_dispatch",
43
+ namespace: "workflow",
44
+ operation: resolvedOperation.name,
45
+ input,
46
+ requestedByType: c.get("actorType"),
47
+ requestedById: c.get("principal")?.id ?? null
48
+ },
49
+ actor: c.get("principal")?.id ?? "api"
50
+ });
51
+ if (!created.payload) {
52
+ return jsonError(c, 500, `Failed to create workflow task for "${resolvedOperation.name}".`, {
53
+ operation: resolvedOperation.name
54
+ });
55
+ }
56
+ const capacity = await enqueueTaskAndEnsureCapacity(options.sdk, {
57
+ taskId: String(created.payload.id ?? ""),
58
+ actor: c.get("principal")?.id ?? "api",
59
+ priorityClass: "interactive",
60
+ projectId: options.config.projectId,
61
+ enqueueTask: enqueueTaskFromSdk
62
+ });
63
+ return c.json({
64
+ ok: true,
65
+ mode: "task",
66
+ operation: resolvedOperation.name,
67
+ payload: created.payload,
68
+ workerState: capacity.workerState,
69
+ capacity: {
70
+ desiredWorkers: capacity.desiredWorkers,
71
+ scaleApplied: capacity.scaleApplied,
72
+ reason: capacity.scaleReason
73
+ }
74
+ }, { status: 202 });
75
+ }
76
+ const result = await executeOperation(resolvedOperation.name, body);
77
+ return c.json(result, { status: result.ok ? 200 : 400 });
78
+ } catch (error) {
79
+ const message = error instanceof Error ? error.message : String(error);
80
+ const status = /Unknown Treeseed operation|not supported over HTTP|confirmation required/i.test(message) ? 400 : 500;
81
+ return jsonError(c, status, message, { operation: resolvedOperation.name });
82
+ }
83
+ });
84
+ }
85
+ export {
86
+ registerOperationRoutes
87
+ };
@@ -0,0 +1,3 @@
1
+ import type { ApiWorkflowOperationResponse, WorkflowHttpOperationRequest } from './types.ts';
2
+ export declare function isHttpWorkflowOperationAllowed(operation: string): boolean;
3
+ export declare function executeHttpWorkflowOperation(operation: string, request: WorkflowHttpOperationRequest): Promise<ApiWorkflowOperationResponse>;
@@ -0,0 +1,26 @@
1
+ import { TreeseedOperationsSdk } from "@treeseed/sdk";
2
+ const HTTP_BLOCKED_WORKFLOW_OPERATIONS = /* @__PURE__ */ new Set(["dev", "dev:watch"]);
3
+ function isHttpWorkflowOperationAllowed(operation) {
4
+ return !HTTP_BLOCKED_WORKFLOW_OPERATIONS.has(operation);
5
+ }
6
+ async function executeHttpWorkflowOperation(operation, request) {
7
+ if (!isHttpWorkflowOperationAllowed(operation)) {
8
+ throw new Error(`Workflow operation "${operation}" is not supported over HTTP.`);
9
+ }
10
+ const operations = new TreeseedOperationsSdk();
11
+ return operations.execute({
12
+ operationName: operation,
13
+ input: request.input ?? {}
14
+ }, {
15
+ cwd: request.cwd ?? process.cwd(),
16
+ env: {
17
+ ...process.env,
18
+ ...request.env ?? {}
19
+ },
20
+ transport: "api"
21
+ });
22
+ }
23
+ export {
24
+ executeHttpWorkflowOperation,
25
+ isHttpWorkflowOperationAllowed
26
+ };
@@ -0,0 +1,8 @@
1
+ import type { Hono } from 'hono';
2
+ import type { AgentSdk } from '@treeseed/sdk';
3
+ import type { ApiConfig } from './types.ts';
4
+ export declare function registerProjectRoutes(app: Hono<any>, options: {
5
+ config: ApiConfig;
6
+ sharedSdk: AgentSdk;
7
+ prefix?: string;
8
+ }): void;