@treeseed/core 0.8.3 → 0.8.4
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 +7 -11
- package/dist/dev-watch.js +1 -1
- package/dist/dev.d.ts +2 -4
- package/dist/dev.js +4 -124
- package/dist/env.yaml +23 -175
- package/dist/index.d.ts +0 -4
- package/dist/index.js +0 -6
- package/dist/scripts/build-dist.js +3 -3
- package/dist/scripts/dev-platform.js +1 -7
- package/dist/scripts/run-fixture-astro-command.js +25 -51
- package/dist/scripts/test-smoke.js +50 -7
- package/package.json +5 -78
- package/templates/github/deploy-web.workflow.yml +106 -0
- package/templates/github/hosted-project.workflow.yml +4 -4
- package/dist/agent-runtime.d.ts +0 -17
- package/dist/agent-runtime.js +0 -117
- package/dist/agent.d.ts +0 -11
- package/dist/agent.js +0 -25
- package/dist/agents/adapters/execution.d.ts +0 -41
- package/dist/agents/adapters/execution.js +0 -73
- package/dist/agents/adapters/mutations.d.ts +0 -22
- package/dist/agents/adapters/mutations.js +0 -30
- package/dist/agents/adapters/notification.d.ts +0 -26
- package/dist/agents/adapters/notification.js +0 -46
- package/dist/agents/adapters/repository.d.ts +0 -23
- package/dist/agents/adapters/repository.js +0 -61
- package/dist/agents/adapters/research.d.ts +0 -26
- package/dist/agents/adapters/research.js +0 -59
- package/dist/agents/adapters/verification.d.ts +0 -36
- package/dist/agents/adapters/verification.js +0 -62
- package/dist/agents/cli-tools.d.ts +0 -1
- package/dist/agents/cli-tools.js +0 -5
- package/dist/agents/cli.d.ts +0 -15
- package/dist/agents/cli.js +0 -109
- package/dist/agents/contracts/messages.d.ts +0 -88
- package/dist/agents/contracts/messages.js +0 -138
- package/dist/agents/contracts/run.d.ts +0 -21
- package/dist/agents/contracts/run.js +0 -0
- package/dist/agents/index.d.ts +0 -1
- package/dist/agents/index.js +0 -5
- package/dist/agents/kernel/agent-kernel.d.ts +0 -51
- package/dist/agents/kernel/agent-kernel.js +0 -292
- package/dist/agents/kernel/trigger-resolver.d.ts +0 -19
- package/dist/agents/kernel/trigger-resolver.js +0 -157
- package/dist/agents/registry-helper.d.ts +0 -4
- package/dist/agents/registry-helper.js +0 -14
- package/dist/agents/registry.d.ts +0 -6
- package/dist/agents/registry.js +0 -98
- package/dist/agents/runtime-types.d.ts +0 -118
- package/dist/agents/runtime-types.js +0 -0
- package/dist/agents/spec-loader.d.ts +0 -18
- package/dist/agents/spec-loader.js +0 -55
- package/dist/agents/spec-normalizer.d.ts +0 -2
- package/dist/agents/spec-normalizer.js +0 -327
- package/dist/agents/spec-types.d.ts +0 -64
- package/dist/agents/spec-types.js +0 -0
- package/dist/agents/testing/agents-smoke.d.ts +0 -1
- package/dist/agents/testing/agents-smoke.js +0 -32
- package/dist/agents/testing/e2e-harness.d.ts +0 -44
- package/dist/agents/testing/e2e-harness.js +0 -504
- package/dist/api/agent-routes.d.ts +0 -13
- package/dist/api/agent-routes.js +0 -327
- package/dist/api/app.d.ts +0 -5
- package/dist/api/app.js +0 -361
- package/dist/api/auth/d1-database.d.ts +0 -3
- package/dist/api/auth/d1-database.js +0 -20
- package/dist/api/auth/d1-provider.d.ts +0 -79
- package/dist/api/auth/d1-provider.js +0 -92
- package/dist/api/auth/d1-store.d.ts +0 -114
- package/dist/api/auth/d1-store.js +0 -895
- package/dist/api/auth/memory-provider.d.ts +0 -77
- package/dist/api/auth/memory-provider.js +0 -249
- package/dist/api/auth/rbac.d.ts +0 -22
- package/dist/api/auth/rbac.js +0 -162
- package/dist/api/auth/tokens.d.ts +0 -18
- package/dist/api/auth/tokens.js +0 -56
- package/dist/api/capabilities.d.ts +0 -9
- package/dist/api/capabilities.js +0 -33
- package/dist/api/config.d.ts +0 -2
- package/dist/api/config.js +0 -77
- package/dist/api/http.d.ts +0 -28
- package/dist/api/http.js +0 -51
- package/dist/api/index.d.ts +0 -9
- package/dist/api/index.js +0 -18
- package/dist/api/operations-routes.d.ts +0 -11
- package/dist/api/operations-routes.js +0 -87
- package/dist/api/operations.d.ts +0 -3
- package/dist/api/operations.js +0 -26
- package/dist/api/project-routes.d.ts +0 -8
- package/dist/api/project-routes.js +0 -586
- package/dist/api/providers.d.ts +0 -2
- package/dist/api/providers.js +0 -62
- package/dist/api/railway.d.ts +0 -50
- package/dist/api/railway.js +0 -69
- package/dist/api/sdk-dispatch.d.ts +0 -5
- package/dist/api/sdk-dispatch.js +0 -13
- package/dist/api/sdk-routes.d.ts +0 -11
- package/dist/api/sdk-routes.js +0 -29
- package/dist/api/server.d.ts +0 -2
- package/dist/api/server.js +0 -10
- package/dist/api/templates.d.ts +0 -3
- package/dist/api/templates.js +0 -31
- package/dist/api/types.d.ts +0 -231
- package/dist/api/types.js +0 -0
- package/dist/api.d.ts +0 -1
- package/dist/api.js +0 -1
- package/dist/railway.d.ts +0 -1
- package/dist/railway.js +0 -4
- package/dist/services/agents.d.ts +0 -11
- package/dist/services/agents.js +0 -48
- package/dist/services/common.d.ts +0 -66
- package/dist/services/common.js +0 -212
- package/dist/services/index.d.ts +0 -6
- package/dist/services/index.js +0 -19
- package/dist/services/manager.d.ts +0 -267
- package/dist/services/manager.js +0 -1368
- package/dist/services/remote-runner.d.ts +0 -30
- package/dist/services/remote-runner.js +0 -230
- package/dist/services/workday-content.d.ts +0 -53
- package/dist/services/workday-content.js +0 -190
- package/dist/services/workday-manager.d.ts +0 -279
- package/dist/services/workday-manager.js +0 -163
- package/dist/services/workday-report.d.ts +0 -195
- package/dist/services/workday-report.js +0 -17
- package/dist/services/workday-start.d.ts +0 -195
- package/dist/services/workday-start.js +0 -17
- package/dist/services/worker-capacity.d.ts +0 -58
- package/dist/services/worker-capacity.js +0 -208
- package/dist/services/worker-pool-scaler.d.ts +0 -27
- package/dist/services/worker-pool-scaler.js +0 -127
- package/dist/services/worker.d.ts +0 -19
- package/dist/services/worker.js +0 -436
- package/templates/github/deploy.workflow.yml +0 -577
package/dist/api/agent-routes.js
DELETED
|
@@ -1,327 +0,0 @@
|
|
|
1
|
-
import { listRegisteredAgentHandlers as listCoreRegisteredAgentHandlers } from "../agents/registry.js";
|
|
2
|
-
import { buildTaskContext, enqueueTaskFromSdk } from "../services/common.js";
|
|
3
|
-
import { jsonError, requireScope } from "./http.js";
|
|
4
|
-
async function listRegisteredHandlers() {
|
|
5
|
-
return listCoreRegisteredAgentHandlers();
|
|
6
|
-
}
|
|
7
|
-
async function safeListRegisteredHandlers() {
|
|
8
|
-
try {
|
|
9
|
-
return {
|
|
10
|
-
handlers: await listRegisteredHandlers(),
|
|
11
|
-
error: null
|
|
12
|
-
};
|
|
13
|
-
} catch (error) {
|
|
14
|
-
return {
|
|
15
|
-
handlers: [],
|
|
16
|
-
error: error instanceof Error ? error.message : String(error)
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
function withPrefix(prefix, path) {
|
|
21
|
-
return `${prefix}${path}`.replace(/\/{2,}/g, "/");
|
|
22
|
-
}
|
|
23
|
-
function actor(body, fallback) {
|
|
24
|
-
return String(body.actor ?? fallback);
|
|
25
|
-
}
|
|
26
|
-
function authorizeRequest(c, options) {
|
|
27
|
-
const routeUnauthorized = options.authorize?.(c);
|
|
28
|
-
if (routeUnauthorized) {
|
|
29
|
-
return routeUnauthorized;
|
|
30
|
-
}
|
|
31
|
-
if (options.scope) {
|
|
32
|
-
return requireScope(c, options.scope);
|
|
33
|
-
}
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
36
|
-
function registerAgentRoutes(app, options) {
|
|
37
|
-
const prefix = options.prefix ?? "/agent";
|
|
38
|
-
const defaultActor = options.defaultActor ?? "api";
|
|
39
|
-
app.get(withPrefix(prefix, "/healthz"), async (c) => {
|
|
40
|
-
const registration = await safeListRegisteredHandlers();
|
|
41
|
-
return c.json({
|
|
42
|
-
ok: true,
|
|
43
|
-
service: "treeseed-agent-api",
|
|
44
|
-
handlerCount: registration.handlers.length,
|
|
45
|
-
registrationError: registration.error
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
app.get(withPrefix(prefix, "/specs"), async (c) => {
|
|
49
|
-
const unauthorized = authorizeRequest(c, options);
|
|
50
|
-
if (unauthorized) return unauthorized;
|
|
51
|
-
const payload = await options.sdk.listAgentSpecs({ enabled: true });
|
|
52
|
-
return c.json({
|
|
53
|
-
ok: true,
|
|
54
|
-
payload,
|
|
55
|
-
handlers: await listRegisteredHandlers()
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
app.post(withPrefix(prefix, "/workdays/start"), async (c) => {
|
|
59
|
-
const unauthorized = authorizeRequest(c, options);
|
|
60
|
-
if (unauthorized) return unauthorized;
|
|
61
|
-
return jsonError(c, 410, "Starting workdays through /agent/workdays/start is deprecated. Use project workday policy and workday requests instead.");
|
|
62
|
-
});
|
|
63
|
-
app.post(withPrefix(prefix, "/workdays/:id/close"), async (c) => {
|
|
64
|
-
const unauthorized = authorizeRequest(c, options);
|
|
65
|
-
if (unauthorized) return unauthorized;
|
|
66
|
-
const body = await c.req.json().catch(() => ({}));
|
|
67
|
-
const result = await options.sdk.closeWorkDay({
|
|
68
|
-
id: c.req.param("id"),
|
|
69
|
-
state: body.state,
|
|
70
|
-
summary: body.summary ?? null,
|
|
71
|
-
actor: actor(body, defaultActor)
|
|
72
|
-
});
|
|
73
|
-
return result.payload ? c.json(result) : jsonError(c, 404, "Unknown work day.");
|
|
74
|
-
});
|
|
75
|
-
app.post(withPrefix(prefix, "/tasks"), async (c) => {
|
|
76
|
-
const unauthorized = authorizeRequest(c, options);
|
|
77
|
-
if (unauthorized) return unauthorized;
|
|
78
|
-
const body = await c.req.json().catch(() => ({}));
|
|
79
|
-
const result = await options.sdk.createTask({
|
|
80
|
-
id: typeof body.id === "string" ? body.id : void 0,
|
|
81
|
-
workDayId: String(body.workDayId ?? ""),
|
|
82
|
-
agentId: String(body.agentId ?? ""),
|
|
83
|
-
type: String(body.type ?? ""),
|
|
84
|
-
state: typeof body.state === "string" ? body.state : "pending",
|
|
85
|
-
priority: body.priority === void 0 ? void 0 : Number(body.priority),
|
|
86
|
-
idempotencyKey: String(body.idempotencyKey ?? ""),
|
|
87
|
-
payload: body.payload ?? {},
|
|
88
|
-
payloadHash: typeof body.payloadHash === "string" ? body.payloadHash : null,
|
|
89
|
-
maxAttempts: body.maxAttempts === void 0 ? void 0 : Number(body.maxAttempts),
|
|
90
|
-
availableAt: typeof body.availableAt === "string" ? body.availableAt : void 0,
|
|
91
|
-
graphVersion: typeof body.graphVersion === "string" ? body.graphVersion : null,
|
|
92
|
-
parentTaskId: typeof body.parentTaskId === "string" ? body.parentTaskId : null,
|
|
93
|
-
actor: actor(body, defaultActor)
|
|
94
|
-
});
|
|
95
|
-
return c.json(result);
|
|
96
|
-
});
|
|
97
|
-
app.post(withPrefix(prefix, "/tasks/search"), async (c) => {
|
|
98
|
-
const unauthorized = authorizeRequest(c, options);
|
|
99
|
-
if (unauthorized) return unauthorized;
|
|
100
|
-
const body = await c.req.json().catch(() => ({}));
|
|
101
|
-
const result = await options.sdk.searchTasks({
|
|
102
|
-
workDayId: typeof body.workDayId === "string" ? body.workDayId : void 0,
|
|
103
|
-
agentId: typeof body.agentId === "string" ? body.agentId : void 0,
|
|
104
|
-
state: Array.isArray(body.state) || typeof body.state === "string" ? body.state : void 0,
|
|
105
|
-
limit: body.limit === void 0 ? void 0 : Number(body.limit)
|
|
106
|
-
});
|
|
107
|
-
return c.json(result);
|
|
108
|
-
});
|
|
109
|
-
app.post(withPrefix(prefix, "/tasks/:id/claim"), async (c) => {
|
|
110
|
-
const unauthorized = authorizeRequest(c, options);
|
|
111
|
-
if (unauthorized) return unauthorized;
|
|
112
|
-
const body = await c.req.json().catch(() => ({}));
|
|
113
|
-
const result = await options.sdk.claimTask({
|
|
114
|
-
id: c.req.param("id"),
|
|
115
|
-
workerId: String(body.workerId ?? "worker"),
|
|
116
|
-
leaseSeconds: Number(body.leaseSeconds ?? 120),
|
|
117
|
-
actor: actor(body, defaultActor)
|
|
118
|
-
});
|
|
119
|
-
return result.payload ? c.json(result) : jsonError(c, 404, "Unknown task.");
|
|
120
|
-
});
|
|
121
|
-
app.post(withPrefix(prefix, "/tasks/:id/progress"), async (c) => {
|
|
122
|
-
const unauthorized = authorizeRequest(c, options);
|
|
123
|
-
if (unauthorized) return unauthorized;
|
|
124
|
-
const body = await c.req.json().catch(() => ({}));
|
|
125
|
-
const result = await options.sdk.recordTaskProgress({
|
|
126
|
-
id: c.req.param("id"),
|
|
127
|
-
workerId: typeof body.workerId === "string" ? body.workerId : null,
|
|
128
|
-
state: typeof body.state === "string" ? body.state : void 0,
|
|
129
|
-
appendEvent: body.appendEvent,
|
|
130
|
-
patch: body.patch,
|
|
131
|
-
actor: actor(body, defaultActor)
|
|
132
|
-
});
|
|
133
|
-
return result.payload ? c.json(result) : jsonError(c, 404, "Unknown task.");
|
|
134
|
-
});
|
|
135
|
-
app.post(withPrefix(prefix, "/tasks/:id/complete"), async (c) => {
|
|
136
|
-
const unauthorized = authorizeRequest(c, options);
|
|
137
|
-
if (unauthorized) return unauthorized;
|
|
138
|
-
const body = await c.req.json().catch(() => ({}));
|
|
139
|
-
const result = await options.sdk.completeTask({
|
|
140
|
-
id: c.req.param("id"),
|
|
141
|
-
output: body.output ?? null,
|
|
142
|
-
outputRef: typeof body.outputRef === "string" ? body.outputRef : null,
|
|
143
|
-
summary: body.summary ?? null,
|
|
144
|
-
actor: actor(body, defaultActor)
|
|
145
|
-
});
|
|
146
|
-
return result.payload ? c.json(result) : jsonError(c, 404, "Unknown task.");
|
|
147
|
-
});
|
|
148
|
-
app.post(withPrefix(prefix, "/tasks/:id/fail"), async (c) => {
|
|
149
|
-
const unauthorized = authorizeRequest(c, options);
|
|
150
|
-
if (unauthorized) return unauthorized;
|
|
151
|
-
const body = await c.req.json().catch(() => ({}));
|
|
152
|
-
const result = await options.sdk.failTask({
|
|
153
|
-
id: c.req.param("id"),
|
|
154
|
-
errorCode: typeof body.errorCode === "string" ? body.errorCode : null,
|
|
155
|
-
errorMessage: String(body.errorMessage ?? "Task failed"),
|
|
156
|
-
retryable: Boolean(body.retryable),
|
|
157
|
-
nextVisibleAt: typeof body.nextVisibleAt === "string" ? body.nextVisibleAt : null,
|
|
158
|
-
actor: actor(body, defaultActor)
|
|
159
|
-
});
|
|
160
|
-
return result.payload ? c.json(result) : jsonError(c, 404, "Unknown task.");
|
|
161
|
-
});
|
|
162
|
-
app.post(withPrefix(prefix, "/tasks/:id/requeue"), async (c) => {
|
|
163
|
-
const unauthorized = authorizeRequest(c, options);
|
|
164
|
-
if (unauthorized) return unauthorized;
|
|
165
|
-
const body = await c.req.json().catch(() => ({}));
|
|
166
|
-
try {
|
|
167
|
-
return c.json(await enqueueTaskFromSdk(options.sdk, {
|
|
168
|
-
taskId: c.req.param("id"),
|
|
169
|
-
queueName: typeof body.queueName === "string" ? body.queueName : void 0,
|
|
170
|
-
deliveryDelaySeconds: body.delaySeconds === void 0 ? void 0 : Number(body.delaySeconds),
|
|
171
|
-
actor: actor(body, defaultActor)
|
|
172
|
-
}));
|
|
173
|
-
} catch (error) {
|
|
174
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
175
|
-
return jsonError(c, /Unknown task/.test(message) ? 404 : /Queue producer/.test(message) ? 501 : 500, message);
|
|
176
|
-
}
|
|
177
|
-
});
|
|
178
|
-
app.post(withPrefix(prefix, "/tasks/:id/followups"), async (c) => {
|
|
179
|
-
const unauthorized = authorizeRequest(c, options);
|
|
180
|
-
if (unauthorized) return unauthorized;
|
|
181
|
-
const body = await c.req.json().catch(() => ({}));
|
|
182
|
-
const current = await options.sdk.get({ model: "task", id: c.req.param("id") });
|
|
183
|
-
if (!current.payload) {
|
|
184
|
-
return jsonError(c, 404, "Unknown task.");
|
|
185
|
-
}
|
|
186
|
-
const currentTask = current.payload;
|
|
187
|
-
const followups = Array.isArray(body.followups) ? body.followups : [];
|
|
188
|
-
const created = [];
|
|
189
|
-
for (const followup of followups) {
|
|
190
|
-
created.push(await options.sdk.createTask({
|
|
191
|
-
workDayId: String(followup.workDayId ?? currentTask.workDayId ?? ""),
|
|
192
|
-
agentId: String(followup.agentId ?? currentTask.agentId ?? ""),
|
|
193
|
-
type: String(followup.type ?? "followup"),
|
|
194
|
-
priority: followup.priority === void 0 ? void 0 : Number(followup.priority),
|
|
195
|
-
idempotencyKey: String(followup.idempotencyKey ?? `${c.req.param("id")}:${created.length}`),
|
|
196
|
-
payload: followup.payload ?? {},
|
|
197
|
-
graphVersion: typeof followup.graphVersion === "string" ? followup.graphVersion : null,
|
|
198
|
-
parentTaskId: c.req.param("id"),
|
|
199
|
-
actor: actor(followup, defaultActor)
|
|
200
|
-
}));
|
|
201
|
-
}
|
|
202
|
-
return c.json({ ok: true, payload: created.map((entry) => entry.payload) });
|
|
203
|
-
});
|
|
204
|
-
app.post(withPrefix(prefix, "/queue/enqueue"), async (c) => {
|
|
205
|
-
const unauthorized = authorizeRequest(c, options);
|
|
206
|
-
if (unauthorized) return unauthorized;
|
|
207
|
-
const body = await c.req.json().catch(() => ({}));
|
|
208
|
-
try {
|
|
209
|
-
return c.json(await enqueueTaskFromSdk(options.sdk, {
|
|
210
|
-
taskId: String(body.taskId ?? ""),
|
|
211
|
-
queueName: typeof body.queueName === "string" ? body.queueName : void 0,
|
|
212
|
-
deliveryDelaySeconds: body.deliveryDelaySeconds === void 0 ? void 0 : Number(body.deliveryDelaySeconds),
|
|
213
|
-
actor: actor(body, defaultActor)
|
|
214
|
-
}));
|
|
215
|
-
} catch (error) {
|
|
216
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
217
|
-
return jsonError(c, /Unknown task/.test(message) ? 404 : /Queue push client/.test(message) ? 501 : 500, message);
|
|
218
|
-
}
|
|
219
|
-
});
|
|
220
|
-
app.post(withPrefix(prefix, "/reports"), async (c) => {
|
|
221
|
-
const unauthorized = authorizeRequest(c, options);
|
|
222
|
-
if (unauthorized) return unauthorized;
|
|
223
|
-
const body = await c.req.json().catch(() => ({}));
|
|
224
|
-
const result = await options.sdk.createReport({
|
|
225
|
-
id: typeof body.id === "string" ? body.id : void 0,
|
|
226
|
-
workDayId: String(body.workDayId ?? ""),
|
|
227
|
-
kind: String(body.kind ?? "workday_summary"),
|
|
228
|
-
body: body.body ?? {},
|
|
229
|
-
renderedRef: typeof body.renderedRef === "string" ? body.renderedRef : null,
|
|
230
|
-
sentAt: typeof body.sentAt === "string" ? body.sentAt : null,
|
|
231
|
-
actor: actor(body, defaultActor)
|
|
232
|
-
});
|
|
233
|
-
return c.json(result);
|
|
234
|
-
});
|
|
235
|
-
app.post(withPrefix(prefix, "/context/resolve-task"), async (c) => {
|
|
236
|
-
const unauthorized = authorizeRequest(c, options);
|
|
237
|
-
if (unauthorized) return unauthorized;
|
|
238
|
-
const body = await c.req.json().catch(() => ({}));
|
|
239
|
-
return c.json({
|
|
240
|
-
ok: true,
|
|
241
|
-
payload: await buildTaskContext(options.sdk, String(body.taskId ?? ""))
|
|
242
|
-
});
|
|
243
|
-
});
|
|
244
|
-
app.post(withPrefix(prefix, "/graph/search"), async (c) => {
|
|
245
|
-
const unauthorized = authorizeRequest(c, options);
|
|
246
|
-
if (unauthorized) return unauthorized;
|
|
247
|
-
const body = await c.req.json().catch(() => ({}));
|
|
248
|
-
const query = String(body.query ?? "");
|
|
249
|
-
const scope = String(body.scope ?? "sections");
|
|
250
|
-
const payload = scope === "files" ? await options.sdk.searchFiles(query, body.options) : scope === "entities" ? await options.sdk.searchEntities(query, body.options) : await options.sdk.searchSections(query, body.options);
|
|
251
|
-
return c.json({ ok: true, payload });
|
|
252
|
-
});
|
|
253
|
-
app.post(withPrefix(prefix, "/graph/subgraph"), async (c) => {
|
|
254
|
-
const unauthorized = authorizeRequest(c, options);
|
|
255
|
-
if (unauthorized) return unauthorized;
|
|
256
|
-
const body = await c.req.json().catch(() => ({}));
|
|
257
|
-
const payload = await options.sdk.getSubgraph(
|
|
258
|
-
Array.isArray(body.seedIds) ? body.seedIds.map(String) : [],
|
|
259
|
-
body.options
|
|
260
|
-
);
|
|
261
|
-
return c.json({ ok: true, payload });
|
|
262
|
-
});
|
|
263
|
-
app.post(withPrefix(prefix, "/graph/query"), async (c) => {
|
|
264
|
-
const unauthorized = authorizeRequest(c, options);
|
|
265
|
-
if (unauthorized) return unauthorized;
|
|
266
|
-
const body = await c.req.json().catch(() => ({}));
|
|
267
|
-
const payload = await options.sdk.queryGraph(body);
|
|
268
|
-
if (typeof body.workDayId === "string" && body.workDayId) {
|
|
269
|
-
await options.sdk.create({
|
|
270
|
-
model: "graph_run",
|
|
271
|
-
data: {
|
|
272
|
-
workDayId: body.workDayId,
|
|
273
|
-
corpusHash: String(body.corpusHash ?? "query-graph"),
|
|
274
|
-
graphVersion: String(body.graphVersion ?? ""),
|
|
275
|
-
queryJson: JSON.stringify(body),
|
|
276
|
-
seedIdsJson: JSON.stringify(payload.seedIds),
|
|
277
|
-
selectedNodeIdsJson: JSON.stringify(payload.nodes.map((entry) => entry.node.id)),
|
|
278
|
-
statsJson: JSON.stringify({ nodeCount: payload.nodes.length, edgeCount: payload.edges.length })
|
|
279
|
-
},
|
|
280
|
-
actor: actor(body, defaultActor)
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
|
-
return c.json({ ok: true, payload });
|
|
284
|
-
});
|
|
285
|
-
app.post(withPrefix(prefix, "/graph/context-pack"), async (c) => {
|
|
286
|
-
const unauthorized = authorizeRequest(c, options);
|
|
287
|
-
if (unauthorized) return unauthorized;
|
|
288
|
-
const body = await c.req.json().catch(() => ({}));
|
|
289
|
-
const payload = await options.sdk.buildContextPack(body);
|
|
290
|
-
if (typeof body.workDayId === "string" && body.workDayId) {
|
|
291
|
-
await options.sdk.create({
|
|
292
|
-
model: "graph_run",
|
|
293
|
-
data: {
|
|
294
|
-
workDayId: body.workDayId,
|
|
295
|
-
corpusHash: String(body.corpusHash ?? "context-pack"),
|
|
296
|
-
graphVersion: String(body.graphVersion ?? ""),
|
|
297
|
-
queryJson: JSON.stringify(body),
|
|
298
|
-
seedIdsJson: JSON.stringify(payload.seedIds),
|
|
299
|
-
selectedNodeIdsJson: JSON.stringify(payload.includedNodeIds),
|
|
300
|
-
statsJson: JSON.stringify({
|
|
301
|
-
nodeCount: payload.nodes.length,
|
|
302
|
-
edgeCount: payload.edges.length,
|
|
303
|
-
totalTokenEstimate: payload.totalTokenEstimate
|
|
304
|
-
})
|
|
305
|
-
},
|
|
306
|
-
actor: actor(body, defaultActor)
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
|
-
return c.json({ ok: true, payload });
|
|
310
|
-
});
|
|
311
|
-
app.post(withPrefix(prefix, "/graph/parse-dsl"), async (c) => {
|
|
312
|
-
const unauthorized = authorizeRequest(c, options);
|
|
313
|
-
if (unauthorized) return unauthorized;
|
|
314
|
-
const body = await c.req.json().catch(() => ({}));
|
|
315
|
-
const payload = await options.sdk.parseGraphDsl(String(body.source ?? body.query ?? ""));
|
|
316
|
-
return c.json({ ok: true, payload });
|
|
317
|
-
});
|
|
318
|
-
app.get(withPrefix(prefix, "/graph/node/:id"), async (c) => {
|
|
319
|
-
const unauthorized = authorizeRequest(c, options);
|
|
320
|
-
if (unauthorized) return unauthorized;
|
|
321
|
-
const payload = await options.sdk.getGraphNode(c.req.param("id"));
|
|
322
|
-
return payload ? c.json({ ok: true, payload }) : jsonError(c, 404, "Unknown graph node.");
|
|
323
|
-
});
|
|
324
|
-
}
|
|
325
|
-
export {
|
|
326
|
-
registerAgentRoutes
|
|
327
|
-
};
|
package/dist/api/app.d.ts
DELETED
package/dist/api/app.js
DELETED
|
@@ -1,361 +0,0 @@
|
|
|
1
|
-
import crypto from "node:crypto";
|
|
2
|
-
import { AgentSdk, TREESEED_REMOTE_CONTRACT_HEADER, TREESEED_REMOTE_CONTRACT_VERSION } from "@treeseed/sdk";
|
|
3
|
-
import { Hono } from "hono";
|
|
4
|
-
import { registerAgentRoutes } from "./agent-routes.js";
|
|
5
|
-
import { resolveApiConfig } from "./config.js";
|
|
6
|
-
import { bearerTokenFromRequest, jsonError, requirePermission, requireScope } from "./http.js";
|
|
7
|
-
import { registerOperationRoutes } from "./operations-routes.js";
|
|
8
|
-
import { resolveApiRuntimeProviders } from "./providers.js";
|
|
9
|
-
import { registerProjectRoutes } from "./project-routes.js";
|
|
10
|
-
import { registerSdkRoutes } from "./sdk-routes.js";
|
|
11
|
-
import { loadTemplateCatalog } from "./templates.js";
|
|
12
|
-
function mergeApiOptions(options) {
|
|
13
|
-
const baseConfig = resolveApiConfig();
|
|
14
|
-
return {
|
|
15
|
-
config: {
|
|
16
|
-
...baseConfig,
|
|
17
|
-
...options.config ?? {},
|
|
18
|
-
providers: {
|
|
19
|
-
...baseConfig.providers,
|
|
20
|
-
...options.config?.providers ?? {},
|
|
21
|
-
agents: {
|
|
22
|
-
...baseConfig.providers.agents,
|
|
23
|
-
...options.config?.providers?.agents ?? {}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
surfaces: {
|
|
28
|
-
auth: true,
|
|
29
|
-
templates: true,
|
|
30
|
-
sdk: true,
|
|
31
|
-
agent: true,
|
|
32
|
-
operations: true,
|
|
33
|
-
project: true,
|
|
34
|
-
...options.surfaces ?? {}
|
|
35
|
-
},
|
|
36
|
-
scopes: {
|
|
37
|
-
authMe: "auth:me",
|
|
38
|
-
sdk: "sdk",
|
|
39
|
-
agent: "agent",
|
|
40
|
-
operations: "operations",
|
|
41
|
-
...options.scopes ?? {}
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
function normalizePrefix(prefix) {
|
|
46
|
-
if (!prefix?.trim()) return "";
|
|
47
|
-
const normalized = prefix.trim().replace(/\/+$/u, "");
|
|
48
|
-
return normalized.startsWith("/") ? normalized : `/${normalized}`;
|
|
49
|
-
}
|
|
50
|
-
function principalScopes(permissions) {
|
|
51
|
-
const scopes = /* @__PURE__ */ new Set(["auth:me"]);
|
|
52
|
-
if (permissions.includes("*:*:*") || permissions.includes("sdk:execute:global")) scopes.add("sdk");
|
|
53
|
-
if (permissions.includes("*:*:*") || permissions.includes("agent:execute:global")) scopes.add("agent");
|
|
54
|
-
if (permissions.includes("*:*:*") || permissions.includes("operations:execute:global")) scopes.add("operations");
|
|
55
|
-
return [...scopes];
|
|
56
|
-
}
|
|
57
|
-
function buildProjectApiPrincipal(config) {
|
|
58
|
-
return {
|
|
59
|
-
id: `project:${config.projectId}`,
|
|
60
|
-
displayName: config.projectApiLabel,
|
|
61
|
-
roles: ["project_api"],
|
|
62
|
-
permissions: [...config.projectApiPermissions],
|
|
63
|
-
scopes: principalScopes(config.projectApiPermissions),
|
|
64
|
-
metadata: {
|
|
65
|
-
projectId: config.projectId
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
function matchesProjectApiKey(token, projectApiKey) {
|
|
70
|
-
if (!projectApiKey) return false;
|
|
71
|
-
const left = Buffer.from(token);
|
|
72
|
-
const right = Buffer.from(projectApiKey);
|
|
73
|
-
return left.length === right.length && crypto.timingSafeEqual(left, right);
|
|
74
|
-
}
|
|
75
|
-
function createTreeseedApiApp(options = {}) {
|
|
76
|
-
const resolved = mergeApiOptions(options);
|
|
77
|
-
const runtimeProviders = resolveApiRuntimeProviders(resolved.config, options.runtimeProviders);
|
|
78
|
-
const sharedSdk = options.sdk ?? new AgentSdk({ repoRoot: resolved.config.repoRoot });
|
|
79
|
-
const app = new Hono();
|
|
80
|
-
const internalPrefix = normalizePrefix(options.internalPrefix);
|
|
81
|
-
app.use("*", async (c, next) => {
|
|
82
|
-
c.set("requestId", crypto.randomUUID());
|
|
83
|
-
c.set("config", resolved.config);
|
|
84
|
-
c.set("principal", null);
|
|
85
|
-
c.set("actingUser", null);
|
|
86
|
-
c.set("credential", null);
|
|
87
|
-
c.set("actorType", "anonymous");
|
|
88
|
-
c.set("permissionGrants", []);
|
|
89
|
-
c.header(TREESEED_REMOTE_CONTRACT_HEADER, String(TREESEED_REMOTE_CONTRACT_VERSION));
|
|
90
|
-
await next();
|
|
91
|
-
});
|
|
92
|
-
app.use("*", async (c, next) => {
|
|
93
|
-
const serviceId = c.req.header("x-treeseed-service-id");
|
|
94
|
-
const serviceSecret = c.req.header("x-treeseed-service-secret");
|
|
95
|
-
if (serviceId && serviceSecret) {
|
|
96
|
-
const result = await runtimeProviders.auth.authenticateServiceCredential(serviceId, serviceSecret);
|
|
97
|
-
if (!result) {
|
|
98
|
-
return jsonError(c, 401, "Invalid internal service credential.");
|
|
99
|
-
}
|
|
100
|
-
c.set("principal", result.principal);
|
|
101
|
-
c.set("credential", result.credential);
|
|
102
|
-
c.set("actorType", "service");
|
|
103
|
-
c.set("permissionGrants", result.principal.permissions);
|
|
104
|
-
}
|
|
105
|
-
await next();
|
|
106
|
-
});
|
|
107
|
-
app.use("*", async (c, next) => {
|
|
108
|
-
const token = bearerTokenFromRequest(c.req.raw);
|
|
109
|
-
if (token) {
|
|
110
|
-
if (matchesProjectApiKey(token, resolved.config.projectApiKey)) {
|
|
111
|
-
const principal = buildProjectApiPrincipal(resolved.config);
|
|
112
|
-
c.set("principal", principal);
|
|
113
|
-
c.set("credential", {
|
|
114
|
-
type: "project_api_key",
|
|
115
|
-
id: resolved.config.projectId,
|
|
116
|
-
label: resolved.config.projectApiLabel
|
|
117
|
-
});
|
|
118
|
-
c.set("actorType", "project");
|
|
119
|
-
c.set("permissionGrants", principal.permissions);
|
|
120
|
-
await next();
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
const result = await runtimeProviders.auth.authenticateBearerToken(token);
|
|
124
|
-
if (result) {
|
|
125
|
-
c.set("principal", result.principal);
|
|
126
|
-
c.set("credential", result.credential);
|
|
127
|
-
c.set("actorType", result.credential.type === "service_token" ? "service" : "user");
|
|
128
|
-
c.set("permissionGrants", result.principal.permissions);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
await next();
|
|
132
|
-
});
|
|
133
|
-
app.use("*", async (c, next) => {
|
|
134
|
-
const assertion = c.req.header("x-treeseed-user-assertion");
|
|
135
|
-
if (c.get("actorType") === "service" && assertion) {
|
|
136
|
-
const claims = runtimeProviders.auth.verifyTrustedUserAssertion(assertion);
|
|
137
|
-
if (!claims) {
|
|
138
|
-
return jsonError(c, 401, "Invalid trusted user assertion.");
|
|
139
|
-
}
|
|
140
|
-
const exchange = await runtimeProviders.auth.exchangeTrustedUserAssertion(claims);
|
|
141
|
-
c.set("actingUser", exchange.principal);
|
|
142
|
-
c.set("principal", exchange.principal);
|
|
143
|
-
c.set("actorType", "user");
|
|
144
|
-
c.set("permissionGrants", exchange.principal.permissions);
|
|
145
|
-
}
|
|
146
|
-
await next();
|
|
147
|
-
});
|
|
148
|
-
app.get("/healthz", (c) => c.json({
|
|
149
|
-
ok: true,
|
|
150
|
-
service: resolved.config.name,
|
|
151
|
-
status: "ok",
|
|
152
|
-
requestId: c.get("requestId")
|
|
153
|
-
}));
|
|
154
|
-
app.get("/readyz", (c) => c.json({
|
|
155
|
-
ok: true,
|
|
156
|
-
ready: true,
|
|
157
|
-
providers: runtimeProviders.selections,
|
|
158
|
-
surfaces: resolved.surfaces
|
|
159
|
-
}));
|
|
160
|
-
if (resolved.surfaces.templates) {
|
|
161
|
-
app.get("/templates", (c) => c.json(loadTemplateCatalog(resolved.config)));
|
|
162
|
-
app.get("/search/templates", (c) => c.json(loadTemplateCatalog(resolved.config)));
|
|
163
|
-
app.get("/templates/:id", (c) => {
|
|
164
|
-
const catalog = loadTemplateCatalog(resolved.config);
|
|
165
|
-
const item = catalog.items.find((entry) => entry.id === c.req.param("id"));
|
|
166
|
-
return item ? c.json({ ok: true, payload: item }) : jsonError(c, 404, `Unknown template "${c.req.param("id")}".`);
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
if (resolved.surfaces.auth) {
|
|
170
|
-
app.post("/auth/device/start", async (c) => {
|
|
171
|
-
const body = await c.req.json().catch(() => ({}));
|
|
172
|
-
return c.json(await runtimeProviders.auth.startDeviceFlow(body));
|
|
173
|
-
});
|
|
174
|
-
app.post("/auth/device/poll", async (c) => {
|
|
175
|
-
const body = await c.req.json().catch(() => ({}));
|
|
176
|
-
const response = await runtimeProviders.auth.pollDeviceFlow(body);
|
|
177
|
-
return c.json(response, { status: response.ok ? 200 : response.status === "expired" ? 410 : 400 });
|
|
178
|
-
});
|
|
179
|
-
app.post("/auth/device/approve", async (c) => {
|
|
180
|
-
const body = await c.req.json().catch(() => ({}));
|
|
181
|
-
try {
|
|
182
|
-
return c.json(await runtimeProviders.auth.approveDeviceFlow(body));
|
|
183
|
-
} catch (error) {
|
|
184
|
-
return jsonError(c, 400, error instanceof Error ? error.message : String(error));
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
app.post("/auth/token/refresh", async (c) => {
|
|
188
|
-
const body = await c.req.json().catch(() => ({}));
|
|
189
|
-
try {
|
|
190
|
-
return c.json(await runtimeProviders.auth.refreshAccessToken(body));
|
|
191
|
-
} catch (error) {
|
|
192
|
-
return jsonError(c, 401, error instanceof Error ? error.message : String(error));
|
|
193
|
-
}
|
|
194
|
-
});
|
|
195
|
-
app.get("/auth/me", (c) => {
|
|
196
|
-
const unauthorized = requireScope(c, resolved.scopes.authMe);
|
|
197
|
-
if (unauthorized) return unauthorized;
|
|
198
|
-
return c.json({
|
|
199
|
-
ok: true,
|
|
200
|
-
payload: c.get("principal")
|
|
201
|
-
});
|
|
202
|
-
});
|
|
203
|
-
app.post("/auth/pat", async (c) => {
|
|
204
|
-
const unauthorized = requirePermission(c, "api_tokens:create:self");
|
|
205
|
-
if (unauthorized) return unauthorized;
|
|
206
|
-
const principal = c.get("principal");
|
|
207
|
-
const body = await c.req.json().catch(() => ({}));
|
|
208
|
-
if (!body.name?.trim() || !principal) {
|
|
209
|
-
return jsonError(c, 400, "Token name is required.");
|
|
210
|
-
}
|
|
211
|
-
return c.json({
|
|
212
|
-
ok: true,
|
|
213
|
-
payload: await runtimeProviders.auth.createPersonalAccessToken(principal.id, {
|
|
214
|
-
name: body.name.trim(),
|
|
215
|
-
scopes: body.scopes,
|
|
216
|
-
expiresAt: body.expiresAt ?? null
|
|
217
|
-
})
|
|
218
|
-
});
|
|
219
|
-
});
|
|
220
|
-
app.get("/auth/pat", async (c) => {
|
|
221
|
-
const unauthorized = requirePermission(c, "api_tokens:read:self");
|
|
222
|
-
if (unauthorized) return unauthorized;
|
|
223
|
-
const principal = c.get("principal");
|
|
224
|
-
if (!principal) return jsonError(c, 401, "Authentication required.");
|
|
225
|
-
return c.json({
|
|
226
|
-
ok: true,
|
|
227
|
-
payload: await runtimeProviders.auth.listPersonalAccessTokens(principal.id)
|
|
228
|
-
});
|
|
229
|
-
});
|
|
230
|
-
app.delete("/auth/pat/:id", async (c) => {
|
|
231
|
-
const unauthorized = requirePermission(c, "api_tokens:delete:self");
|
|
232
|
-
if (unauthorized) return unauthorized;
|
|
233
|
-
const principal = c.get("principal");
|
|
234
|
-
if (!principal) return jsonError(c, 401, "Authentication required.");
|
|
235
|
-
await runtimeProviders.auth.revokePersonalAccessToken(principal.id, c.req.param("id"));
|
|
236
|
-
return c.json({ ok: true });
|
|
237
|
-
});
|
|
238
|
-
app.post("/auth/admin/users", async (c) => {
|
|
239
|
-
const unauthorized = requirePermission(c, "users:manage:global");
|
|
240
|
-
if (unauthorized) return unauthorized;
|
|
241
|
-
if (!runtimeProviders.auth.createUser) {
|
|
242
|
-
return jsonError(c, 501, "User management is unavailable for this auth provider.");
|
|
243
|
-
}
|
|
244
|
-
const body = await c.req.json().catch(() => ({}));
|
|
245
|
-
return c.json({
|
|
246
|
-
ok: true,
|
|
247
|
-
payload: await runtimeProviders.auth.createUser({
|
|
248
|
-
email: body.email ?? null,
|
|
249
|
-
displayName: body.displayName ?? null,
|
|
250
|
-
metadata: typeof body.metadata === "object" && body.metadata ? body.metadata : {}
|
|
251
|
-
})
|
|
252
|
-
});
|
|
253
|
-
});
|
|
254
|
-
app.post("/auth/admin/users/:userId/roles", async (c) => {
|
|
255
|
-
const unauthorized = requirePermission(c, "roles:manage:global");
|
|
256
|
-
if (unauthorized) return unauthorized;
|
|
257
|
-
if (!runtimeProviders.auth.setUserRoles) {
|
|
258
|
-
return jsonError(c, 501, "Role management is unavailable for this auth provider.");
|
|
259
|
-
}
|
|
260
|
-
const body = await c.req.json().catch(() => ({}));
|
|
261
|
-
const roles = Array.isArray(body.roles) ? body.roles.map(String) : [];
|
|
262
|
-
return c.json({
|
|
263
|
-
ok: true,
|
|
264
|
-
payload: await runtimeProviders.auth.setUserRoles(c.req.param("userId"), roles)
|
|
265
|
-
});
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
app.post("/internal/auth/web/sync-user", async (c) => {
|
|
269
|
-
if (c.get("actorType") !== "service") {
|
|
270
|
-
return jsonError(c, 401, "Trusted service authentication required.");
|
|
271
|
-
}
|
|
272
|
-
const unauthorized = requirePermission(c, "services:impersonate:global");
|
|
273
|
-
if (unauthorized) return unauthorized;
|
|
274
|
-
const body = await c.req.json().catch(() => ({}));
|
|
275
|
-
return c.json({
|
|
276
|
-
ok: true,
|
|
277
|
-
payload: await runtimeProviders.auth.syncUserIdentity(body)
|
|
278
|
-
});
|
|
279
|
-
});
|
|
280
|
-
app.post("/internal/auth/web/exchange", async (c) => {
|
|
281
|
-
if (c.get("actorType") !== "service") {
|
|
282
|
-
return jsonError(c, 401, "Trusted service authentication required.");
|
|
283
|
-
}
|
|
284
|
-
const unauthorized = requirePermission(c, "services:impersonate:global");
|
|
285
|
-
if (unauthorized) return unauthorized;
|
|
286
|
-
const body = await c.req.json().catch(() => ({}));
|
|
287
|
-
return c.json(await runtimeProviders.auth.exchangeTrustedUserAssertion(body));
|
|
288
|
-
});
|
|
289
|
-
app.post("/internal/auth/service/token", async (c) => {
|
|
290
|
-
const unauthorized = requirePermission(c, "services:manage:global");
|
|
291
|
-
if (unauthorized) return unauthorized;
|
|
292
|
-
const body = await c.req.json().catch(() => ({}));
|
|
293
|
-
if (!body.serviceId?.trim() || !body.name?.trim()) {
|
|
294
|
-
return jsonError(c, 400, "serviceId and name are required.");
|
|
295
|
-
}
|
|
296
|
-
return c.json({
|
|
297
|
-
ok: true,
|
|
298
|
-
payload: await runtimeProviders.auth.createServiceToken({
|
|
299
|
-
serviceId: body.serviceId.trim(),
|
|
300
|
-
name: body.name.trim(),
|
|
301
|
-
roles: body.roles,
|
|
302
|
-
permissions: body.permissions
|
|
303
|
-
})
|
|
304
|
-
});
|
|
305
|
-
});
|
|
306
|
-
app.post("/internal/auth/service/rotate", async (c) => {
|
|
307
|
-
const unauthorized = requirePermission(c, "services:manage:global");
|
|
308
|
-
if (unauthorized) return unauthorized;
|
|
309
|
-
const body = await c.req.json().catch(() => ({}));
|
|
310
|
-
if (!body.serviceId?.trim()) {
|
|
311
|
-
return jsonError(c, 400, "serviceId is required.");
|
|
312
|
-
}
|
|
313
|
-
return c.json({
|
|
314
|
-
ok: true,
|
|
315
|
-
payload: await runtimeProviders.auth.rotateServiceToken(body.serviceId.trim())
|
|
316
|
-
});
|
|
317
|
-
});
|
|
318
|
-
if (resolved.surfaces.sdk) {
|
|
319
|
-
registerSdkRoutes(app, {
|
|
320
|
-
config: resolved.config,
|
|
321
|
-
sharedSdk,
|
|
322
|
-
scope: resolved.scopes.sdk,
|
|
323
|
-
prefix: internalPrefix
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
if (resolved.surfaces.agent) {
|
|
327
|
-
registerAgentRoutes(app, {
|
|
328
|
-
sdk: sharedSdk,
|
|
329
|
-
prefix: `${internalPrefix}/agent`,
|
|
330
|
-
scope: resolved.scopes.agent,
|
|
331
|
-
projectId: resolved.config.projectId,
|
|
332
|
-
defaultActor: "api"
|
|
333
|
-
});
|
|
334
|
-
}
|
|
335
|
-
if (resolved.surfaces.operations) {
|
|
336
|
-
registerOperationRoutes(app, {
|
|
337
|
-
config: resolved.config,
|
|
338
|
-
scope: resolved.scopes.operations,
|
|
339
|
-
prefix: internalPrefix,
|
|
340
|
-
sdk: sharedSdk,
|
|
341
|
-
executeOperation: options.workflowExecutor
|
|
342
|
-
});
|
|
343
|
-
}
|
|
344
|
-
if (resolved.surfaces.project) {
|
|
345
|
-
registerProjectRoutes(app, {
|
|
346
|
-
config: resolved.config,
|
|
347
|
-
sharedSdk
|
|
348
|
-
});
|
|
349
|
-
}
|
|
350
|
-
options.extendApp?.(app, {
|
|
351
|
-
resolved,
|
|
352
|
-
runtimeProviders,
|
|
353
|
-
sharedSdk,
|
|
354
|
-
internalPrefix
|
|
355
|
-
});
|
|
356
|
-
app.notFound((c) => jsonError(c, 404, "Not found."));
|
|
357
|
-
return app;
|
|
358
|
-
}
|
|
359
|
-
export {
|
|
360
|
-
createTreeseedApiApp
|
|
361
|
-
};
|