@treeseed/core 0.4.10 → 0.4.11
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/dist/api/auth/rbac.d.ts +2 -2
- package/dist/api/auth/rbac.js +2 -1
- package/dist/components/site/RouteNotFound.astro +25 -0
- package/dist/content-config.d.ts +1 -0
- package/dist/content.d.ts +1 -0
- package/dist/content.js +177 -1
- package/dist/dev.d.ts +7 -2
- package/dist/dev.js +59 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +9 -1
- package/dist/middleware/editorial-preview.d.ts +26 -0
- package/dist/middleware/editorial-preview.js +37 -0
- package/dist/middleware/starlightRouteData.js +15 -4
- package/dist/pages/[slug].astro +12 -10
- package/dist/pages/agents/[slug].astro +28 -21
- package/dist/pages/books/[slug].astro +19 -12
- package/dist/pages/feed.xml.js +6 -4
- package/dist/pages/index.astro +43 -14
- package/dist/pages/notes/[slug].astro +19 -12
- package/dist/pages/objectives/[slug].astro +30 -23
- package/dist/pages/people/[slug].astro +28 -21
- package/dist/pages/questions/[slug].astro +30 -23
- package/dist/scripts/build-dist.js +6 -1
- package/dist/scripts/dev-platform.js +9 -1
- package/dist/services/agents.d.ts +22 -0
- package/dist/services/agents.js +29 -0
- package/dist/services/index.d.ts +3 -0
- package/dist/services/index.js +11 -0
- package/dist/services/manager.d.ts +247 -0
- package/dist/services/manager.js +1129 -0
- package/dist/services/remote-runner.d.ts +7 -0
- package/dist/services/remote-runner.js +6 -0
- package/dist/services/workday-content.d.ts +53 -0
- package/dist/services/workday-content.js +190 -0
- package/dist/services/workday-report.d.ts +160 -2
- package/dist/services/workday-report.js +3 -26
- package/dist/services/workday-start.d.ts +170 -1
- package/dist/services/workday-start.js +3 -7
- package/dist/services/worker-pool-scaler.d.ts +27 -0
- package/dist/services/worker-pool-scaler.js +109 -0
- package/dist/services/worker.d.ts +7 -0
- package/dist/services/worker.js +3 -0
- package/dist/site.js +43 -27
- package/dist/templates.d.ts +98 -0
- package/dist/templates.js +170 -0
- package/dist/tenant/runtime-config.d.ts +4 -0
- package/dist/tenant/runtime-config.js +34 -1
- package/dist/utils/hub-content.js +35 -0
- package/dist/utils/published-content.js +60 -0
- package/dist/utils/site-models.d.ts +6 -0
- package/dist/utils/site-models.js +16 -0
- package/dist/utils/starlight-nav.js +50 -0
- package/package.json +20 -2
- package/templates/github/deploy.workflow.yml +404 -9
- package/templates/github/hosted-project.workflow.yml +77 -0
package/dist/api/auth/rbac.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export declare const CONTENT_RESOURCES: readonly ["pages", "notes", "questions", "objectives", "people", "agents", "books", "templates", "
|
|
1
|
+
export declare const CONTENT_RESOURCES: readonly ["pages", "notes", "questions", "objectives", "people", "agents", "books", "templates", "knowledge_packs", "workdays"];
|
|
2
2
|
export declare const PLATFORM_RESOURCES: readonly ["users", "roles", "api_tokens", "services", "jobs", "audit", "auth", "sdk", "agent", "operations"];
|
|
3
|
-
export declare const ALL_PERMISSION_RESOURCES: readonly ["pages", "notes", "questions", "objectives", "people", "agents", "books", "templates", "
|
|
3
|
+
export declare const ALL_PERMISSION_RESOURCES: readonly ["pages", "notes", "questions", "objectives", "people", "agents", "books", "templates", "knowledge_packs", "workdays", "users", "roles", "api_tokens", "services", "jobs", "audit", "auth", "sdk", "agent", "operations"];
|
|
4
4
|
export type PermissionResource = (typeof ALL_PERMISSION_RESOURCES)[number];
|
|
5
5
|
export type PermissionAction = 'read' | 'create' | 'update' | 'delete' | 'manage' | 'execute' | 'impersonate';
|
|
6
6
|
export type PermissionScope = 'self' | 'global';
|
package/dist/api/auth/rbac.js
CHANGED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
import MainLayout from '../../layouts/MainLayout.astro';
|
|
3
|
+
|
|
4
|
+
const {
|
|
5
|
+
title = 'Page not found',
|
|
6
|
+
description = 'The requested Treeseed content could not be found.',
|
|
7
|
+
currentPath = '/404/',
|
|
8
|
+
} = Astro.props;
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
<MainLayout title={title} description={description} currentPath={currentPath}>
|
|
12
|
+
<section class="mx-auto max-w-3xl space-y-6 py-20">
|
|
13
|
+
<p class="text-sm font-semibold uppercase tracking-[0.16em] text-[color:var(--site-accent-strong)]">404</p>
|
|
14
|
+
<h1 class="font-serif text-5xl text-[color:var(--site-text)]">{title}</h1>
|
|
15
|
+
<p class="text-lg leading-9 text-[color:var(--site-text-muted)]">{description}</p>
|
|
16
|
+
<div class="flex flex-wrap gap-4">
|
|
17
|
+
<a href="/" class="border border-[color:var(--site-accent)] bg-[color:var(--site-accent)] px-5 py-3 text-base font-semibold text-[color:var(--site-text)] transition hover:border-[color:var(--site-blue)] hover:bg-[color:var(--site-blue-soft)]">
|
|
18
|
+
Go home
|
|
19
|
+
</a>
|
|
20
|
+
<a href="/knowledge/" class="border border-[color:var(--site-border-strong)] px-5 py-3 text-base font-semibold text-[color:var(--site-text)] transition hover:border-[color:var(--site-blue)] hover:bg-[color:var(--site-blue-soft)]">
|
|
21
|
+
Open knowledge
|
|
22
|
+
</a>
|
|
23
|
+
</div>
|
|
24
|
+
</section>
|
|
25
|
+
</MainLayout>
|
package/dist/content-config.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function createTreeseedCollections(tenantConfig: any, dependencies: any): Record<string, any>;
|
package/dist/content.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { defineCollection, reference } from "astro:content";
|
|
2
2
|
import { z } from "astro/zod";
|
|
3
3
|
import { glob } from "astro/loaders";
|
|
4
|
+
import { existsSync, readdirSync } from "node:fs";
|
|
4
5
|
import { AGENT_CLI_ALLOW_TOOLS } from "@treeseed/sdk/types/agents";
|
|
5
6
|
import { loadTreeseedPluginRuntime } from "@treeseed/sdk/platform/plugins";
|
|
6
7
|
import { loadTreeseedDeployConfig } from "@treeseed/sdk/platform/deploy-config";
|
|
@@ -22,6 +23,30 @@ const timeHorizonValues = ["near-term", "mid-term", "long-term"];
|
|
|
22
23
|
const runtimeStatusValues = ["active", "experimental", "dormant"];
|
|
23
24
|
const agentTriggerTypeValues = ["schedule", "message", "follow", "startup"];
|
|
24
25
|
const agentPermissionOperationValues = ["get", "search", "follow", "pick", "create", "update"];
|
|
26
|
+
function hasMarkdownContent(base) {
|
|
27
|
+
if (!existsSync(base)) {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
for (const entry of readdirSync(base, { withFileTypes: true, recursive: true })) {
|
|
31
|
+
if (entry.isFile() && /\.(md|mdx)$/iu.test(entry.name)) {
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
function optionalMarkdownGlob(base) {
|
|
38
|
+
const delegate = glob({ pattern: "**/*.{md,mdx}", base });
|
|
39
|
+
return {
|
|
40
|
+
name: `treeseed-optional-markdown-glob:${base}`,
|
|
41
|
+
async load(context) {
|
|
42
|
+
if (!hasMarkdownContent(base)) {
|
|
43
|
+
context.store.clear();
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
await delegate.load(context);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
}
|
|
25
50
|
function withOptionalDefault(schema, defaultValue) {
|
|
26
51
|
return defaultValue === void 0 ? schema : schema.default(defaultValue);
|
|
27
52
|
}
|
|
@@ -244,8 +269,140 @@ function createTreeseedCollections(tenantConfig, { docsLoader, docsSchema }) {
|
|
|
244
269
|
sidebarItems: z.array(sidebarItemSchema).min(1),
|
|
245
270
|
tags: z.array(z.string()).default(BOOK_MODEL_DEFAULTS.tags ?? [])
|
|
246
271
|
}));
|
|
272
|
+
const publisherSchema = z.object({
|
|
273
|
+
id: z.string(),
|
|
274
|
+
name: z.string(),
|
|
275
|
+
url: z.string().optional()
|
|
276
|
+
});
|
|
277
|
+
const templateGitSourceSchema = z.object({
|
|
278
|
+
kind: z.literal("git"),
|
|
279
|
+
repoUrl: z.string(),
|
|
280
|
+
directory: z.string(),
|
|
281
|
+
ref: z.string(),
|
|
282
|
+
integrity: z.string().optional()
|
|
283
|
+
});
|
|
284
|
+
const templateR2SourceSchema = z.object({
|
|
285
|
+
kind: z.literal("r2"),
|
|
286
|
+
bucket: z.string().optional(),
|
|
287
|
+
objectKey: z.string(),
|
|
288
|
+
version: z.string(),
|
|
289
|
+
publicUrl: z.string().optional(),
|
|
290
|
+
integrity: z.string().optional()
|
|
291
|
+
});
|
|
292
|
+
const templateProductSchema = z.object({
|
|
293
|
+
slug: z.string(),
|
|
294
|
+
title: z.string(),
|
|
295
|
+
description: z.string(),
|
|
296
|
+
summary: z.string(),
|
|
297
|
+
status: z.enum(["draft", "live", "archived"]),
|
|
298
|
+
featured: z.boolean().default(false),
|
|
299
|
+
teamId: z.string().optional(),
|
|
300
|
+
listingEnabled: z.boolean().default(true),
|
|
301
|
+
category: z.string(),
|
|
302
|
+
audience: z.array(z.string()).default([]),
|
|
303
|
+
tags: z.array(z.string()).default([]),
|
|
304
|
+
publisher: publisherSchema,
|
|
305
|
+
publisherVerified: z.boolean().default(false),
|
|
306
|
+
templateVersion: z.string(),
|
|
307
|
+
templateApiVersion: z.number().int().positive(),
|
|
308
|
+
minCliVersion: z.string(),
|
|
309
|
+
minCoreVersion: z.string(),
|
|
310
|
+
fulfillment: z.object({
|
|
311
|
+
mode: z.enum(["packaged", "git", "r2"]).default("packaged"),
|
|
312
|
+
source: z.union([templateGitSourceSchema, templateR2SourceSchema]),
|
|
313
|
+
hooksPolicy: z.enum(["builtin_only", "trusted_only", "disabled"]).default("builtin_only"),
|
|
314
|
+
supportsReconcile: z.boolean().default(true)
|
|
315
|
+
}),
|
|
316
|
+
offer: z.object({
|
|
317
|
+
priceModel: z.enum(["free", "paid", "contact", "one_time_current_version", "subscription_updates", "private"]).default("free"),
|
|
318
|
+
license: z.string().optional(),
|
|
319
|
+
support: z.string().optional()
|
|
320
|
+
}).default({ priceModel: "free" }),
|
|
321
|
+
relatedBooks: z.array(z.string()).default([]),
|
|
322
|
+
relatedKnowledge: z.array(z.string()).default([]),
|
|
323
|
+
relatedObjectives: z.array(z.string()).default([])
|
|
324
|
+
});
|
|
325
|
+
const knowledgePackSchema = z.object({
|
|
326
|
+
slug: z.string(),
|
|
327
|
+
title: z.string(),
|
|
328
|
+
description: z.string(),
|
|
329
|
+
status: z.enum(["draft", "live", "archived"]).default("draft")
|
|
330
|
+
});
|
|
331
|
+
const workdaySummaryTaskSchema = z.object({
|
|
332
|
+
id: z.string(),
|
|
333
|
+
agentId: z.string().optional(),
|
|
334
|
+
type: z.string().optional(),
|
|
335
|
+
state: z.string().optional(),
|
|
336
|
+
priority: z.number().optional(),
|
|
337
|
+
idempotencyKey: z.string().optional(),
|
|
338
|
+
createdAt: z.coerce.date().optional(),
|
|
339
|
+
startedAt: z.coerce.date().optional(),
|
|
340
|
+
completedAt: z.coerce.date().optional(),
|
|
341
|
+
lastErrorCode: z.string().nullable().optional(),
|
|
342
|
+
lastErrorMessage: z.string().nullable().optional(),
|
|
343
|
+
lastEventKind: z.string().optional(),
|
|
344
|
+
outputCount: z.number().int().optional(),
|
|
345
|
+
changedFiles: z.array(z.string()).default([])
|
|
346
|
+
});
|
|
347
|
+
const workdayPriorityItemSchema = z.object({
|
|
348
|
+
id: z.string(),
|
|
349
|
+
model: z.string(),
|
|
350
|
+
slug: z.string().optional(),
|
|
351
|
+
title: z.string().optional(),
|
|
352
|
+
status: z.string().optional(),
|
|
353
|
+
priority: z.number(),
|
|
354
|
+
estimatedCredits: z.number().optional(),
|
|
355
|
+
reason: z.string().optional()
|
|
356
|
+
});
|
|
357
|
+
const workdayReleaseSchema = z.object({
|
|
358
|
+
id: z.string().optional(),
|
|
359
|
+
deploymentKind: z.string(),
|
|
360
|
+
status: z.string(),
|
|
361
|
+
releaseTag: z.string().nullable().optional(),
|
|
362
|
+
commitSha: z.string().nullable().optional(),
|
|
363
|
+
sourceRef: z.string().nullable().optional(),
|
|
364
|
+
startedAt: z.coerce.date().optional(),
|
|
365
|
+
finishedAt: z.coerce.date().optional(),
|
|
366
|
+
createdAt: z.coerce.date().optional()
|
|
367
|
+
});
|
|
368
|
+
const workdaySchema = z.object({
|
|
369
|
+
title: z.string(),
|
|
370
|
+
slug: z.string(),
|
|
371
|
+
workDayId: z.string(),
|
|
372
|
+
reportVersion: z.string(),
|
|
373
|
+
reportKind: z.string().default("workday_summary"),
|
|
374
|
+
projectId: z.string(),
|
|
375
|
+
teamId: z.string().optional(),
|
|
376
|
+
environment: z.string(),
|
|
377
|
+
status: z.string().default("live"),
|
|
378
|
+
visibility: z.enum(["public", "authenticated", "team", "private"]).default("team"),
|
|
379
|
+
workdayState: z.string(),
|
|
380
|
+
startedAt: z.coerce.date(),
|
|
381
|
+
endedAt: z.coerce.date().nullable().optional(),
|
|
382
|
+
generatedAt: z.coerce.date(),
|
|
383
|
+
createdAt: z.coerce.date().optional(),
|
|
384
|
+
summary: z.string(),
|
|
385
|
+
dailyTaskCreditBudget: z.number().default(0),
|
|
386
|
+
usedTaskCredits: z.number().default(0),
|
|
387
|
+
remainingTaskCredits: z.number().default(0),
|
|
388
|
+
creditLedgerEntries: z.number().int().default(0),
|
|
389
|
+
prioritySnapshotId: z.string().nullable().optional(),
|
|
390
|
+
priorityItemCount: z.number().int().default(0),
|
|
391
|
+
priorityItems: z.array(workdayPriorityItemSchema).default([]),
|
|
392
|
+
totalTasks: z.number().int().default(0),
|
|
393
|
+
completedTasks: z.number().int().default(0),
|
|
394
|
+
failedTasks: z.number().int().default(0),
|
|
395
|
+
queuedTasks: z.number().int().default(0),
|
|
396
|
+
activeTasks: z.number().int().default(0),
|
|
397
|
+
taskItems: z.array(workdaySummaryTaskSchema).default([]),
|
|
398
|
+
changedFiles: z.array(z.string()).default([]),
|
|
399
|
+
releases: z.array(workdayReleaseSchema).default([]),
|
|
400
|
+
scaleDecision: z.record(z.any()).default({}),
|
|
401
|
+
scaleResult: z.record(z.any()).default({}),
|
|
402
|
+
metadata: z.record(z.any()).default({})
|
|
403
|
+
});
|
|
247
404
|
const docsCollectionProvider = resolveDocsCollectionProvider(tenantConfig, { docsLoader, docsSchema });
|
|
248
|
-
|
|
405
|
+
const collections = {
|
|
249
406
|
pages: defineCollection({ loader: glob({ pattern: "**/*.{md,mdx}", base: tenantConfig.content.pages }), schema: pageSchema }),
|
|
250
407
|
notes: defineCollection({ loader: glob({ pattern: "**/*.{md,mdx}", base: tenantConfig.content.notes }), schema: noteSchema }),
|
|
251
408
|
questions: defineCollection({ loader: glob({ pattern: "**/*.{md,mdx}", base: tenantConfig.content.questions }), schema: questionSchema }),
|
|
@@ -258,6 +415,25 @@ function createTreeseedCollections(tenantConfig, { docsLoader, docsSchema }) {
|
|
|
258
415
|
schema: docsCollectionProvider.schema
|
|
259
416
|
})
|
|
260
417
|
};
|
|
418
|
+
if (tenantConfig.content.workdays) {
|
|
419
|
+
collections.workdays = defineCollection({
|
|
420
|
+
loader: optionalMarkdownGlob(tenantConfig.content.workdays),
|
|
421
|
+
schema: workdaySchema
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
if (tenantConfig.content.templates) {
|
|
425
|
+
collections.templates = defineCollection({
|
|
426
|
+
loader: optionalMarkdownGlob(tenantConfig.content.templates),
|
|
427
|
+
schema: templateProductSchema
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
if (tenantConfig.content.knowledge_packs) {
|
|
431
|
+
collections.knowledge_packs = defineCollection({
|
|
432
|
+
loader: optionalMarkdownGlob(tenantConfig.content.knowledge_packs),
|
|
433
|
+
schema: knowledgePackSchema
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
return collections;
|
|
261
437
|
}
|
|
262
438
|
export {
|
|
263
439
|
createTreeseedCollections
|
package/dist/dev.d.ts
CHANGED
|
@@ -3,7 +3,8 @@ export declare const TREESEED_DEFAULT_WEB_HOST = "127.0.0.1";
|
|
|
3
3
|
export declare const TREESEED_DEFAULT_WEB_PORT = 4321;
|
|
4
4
|
export declare const TREESEED_DEFAULT_API_HOST = "127.0.0.1";
|
|
5
5
|
export declare const TREESEED_DEFAULT_API_PORT = 3000;
|
|
6
|
-
export
|
|
6
|
+
export declare const TREESEED_DEFAULT_MANAGER_PORT = 3100;
|
|
7
|
+
export type TreeseedIntegratedDevSurface = 'integrated' | 'services' | 'web' | 'api' | 'manager' | 'worker' | 'agents';
|
|
7
8
|
export type TreeseedIntegratedDevOptions = {
|
|
8
9
|
surface?: TreeseedIntegratedDevSurface;
|
|
9
10
|
watch?: boolean;
|
|
@@ -14,9 +15,13 @@ export type TreeseedIntegratedDevOptions = {
|
|
|
14
15
|
webPort?: number;
|
|
15
16
|
apiHost?: string;
|
|
16
17
|
apiPort?: number;
|
|
18
|
+
managerPort?: number;
|
|
19
|
+
includeServices?: boolean;
|
|
20
|
+
projectId?: string;
|
|
21
|
+
teamId?: string;
|
|
17
22
|
};
|
|
18
23
|
export type TreeseedIntegratedDevCommand = {
|
|
19
|
-
id: 'web' | 'api';
|
|
24
|
+
id: 'web' | 'api' | 'manager' | 'worker' | 'agents';
|
|
20
25
|
label: string;
|
|
21
26
|
command: string;
|
|
22
27
|
args: string[];
|
package/dist/dev.js
CHANGED
|
@@ -10,6 +10,7 @@ const TREESEED_DEFAULT_WEB_HOST = "127.0.0.1";
|
|
|
10
10
|
const TREESEED_DEFAULT_WEB_PORT = 4321;
|
|
11
11
|
const TREESEED_DEFAULT_API_HOST = "127.0.0.1";
|
|
12
12
|
const TREESEED_DEFAULT_API_PORT = 3e3;
|
|
13
|
+
const TREESEED_DEFAULT_MANAGER_PORT = 3100;
|
|
13
14
|
function resolvePackageRoot(packageName, tenantRoot) {
|
|
14
15
|
const resolvedPath = require2.resolve(packageName, {
|
|
15
16
|
paths: [tenantRoot, packageRoot, process.cwd()]
|
|
@@ -74,6 +75,10 @@ function createTreeseedIntegratedDevPlan(options = {}) {
|
|
|
74
75
|
const webPort = normalizePort(options.webPort, TREESEED_DEFAULT_WEB_PORT);
|
|
75
76
|
const apiHost = options.apiHost ?? TREESEED_DEFAULT_API_HOST;
|
|
76
77
|
const apiPort = normalizePort(options.apiPort, TREESEED_DEFAULT_API_PORT);
|
|
78
|
+
const managerPort = normalizePort(options.managerPort, TREESEED_DEFAULT_MANAGER_PORT);
|
|
79
|
+
const includeServices = options.includeServices ?? (surface === "integrated" || surface === "services");
|
|
80
|
+
const projectId = options.projectId ?? process.env.TREESEED_PROJECT_ID;
|
|
81
|
+
const teamId = options.teamId ?? process.env.TREESEED_HOSTING_TEAM_ID;
|
|
77
82
|
const mergedEnv = { ...process.env, ...options.env ?? {} };
|
|
78
83
|
const apiBaseUrl = mergedEnv.TREESEED_API_BASE_URL?.trim() || `http://${apiHost}:${apiPort}`;
|
|
79
84
|
const sdkPackageRoot = resolvePackageRoot("@treeseed/sdk", tenantRoot);
|
|
@@ -88,6 +93,21 @@ function createTreeseedIntegratedDevPlan(options = {}) {
|
|
|
88
93
|
"src/api/server.ts",
|
|
89
94
|
"dist/api/server.js"
|
|
90
95
|
);
|
|
96
|
+
const managerEntrypoint = resolveNodeEntrypoint(
|
|
97
|
+
packageRoot,
|
|
98
|
+
"src/services/manager.ts",
|
|
99
|
+
"dist/services/manager.js"
|
|
100
|
+
);
|
|
101
|
+
const workerEntrypoint = resolveNodeEntrypoint(
|
|
102
|
+
packageRoot,
|
|
103
|
+
"src/services/worker.ts",
|
|
104
|
+
"dist/services/worker.js"
|
|
105
|
+
);
|
|
106
|
+
const agentsEntrypoint = resolveNodeEntrypoint(
|
|
107
|
+
packageRoot,
|
|
108
|
+
"src/services/agents.ts",
|
|
109
|
+
"dist/services/agents.js"
|
|
110
|
+
);
|
|
91
111
|
const watchPaths = [
|
|
92
112
|
resolve(packageRoot, existsSync(resolve(packageRoot, "src")) ? "src" : "dist"),
|
|
93
113
|
resolve(tenantRoot, "src"),
|
|
@@ -97,7 +117,10 @@ function createTreeseedIntegratedDevPlan(options = {}) {
|
|
|
97
117
|
const sharedEnv = {
|
|
98
118
|
...mergedEnv,
|
|
99
119
|
TREESEED_LOCAL_DEV_MODE: mergedEnv.TREESEED_LOCAL_DEV_MODE ?? "cloudflare",
|
|
100
|
-
TREESEED_API_BASE_URL: apiBaseUrl
|
|
120
|
+
TREESEED_API_BASE_URL: apiBaseUrl,
|
|
121
|
+
TREESEED_MARKET_API_BASE_URL: mergedEnv.TREESEED_MARKET_API_BASE_URL ?? apiBaseUrl,
|
|
122
|
+
TREESEED_PROJECT_ID: projectId ?? mergedEnv.TREESEED_PROJECT_ID,
|
|
123
|
+
TREESEED_HOSTING_TEAM_ID: teamId ?? mergedEnv.TREESEED_HOSTING_TEAM_ID
|
|
101
124
|
};
|
|
102
125
|
if (watch) {
|
|
103
126
|
sharedEnv.TREESEED_PUBLIC_DEV_WATCH_RELOAD = sharedEnv.TREESEED_PUBLIC_DEV_WATCH_RELOAD || "true";
|
|
@@ -126,6 +149,40 @@ function createTreeseedIntegratedDevPlan(options = {}) {
|
|
|
126
149
|
}
|
|
127
150
|
});
|
|
128
151
|
}
|
|
152
|
+
if (includeServices || surface === "manager") {
|
|
153
|
+
commands.push({
|
|
154
|
+
id: "manager",
|
|
155
|
+
label: "Manager",
|
|
156
|
+
command: managerEntrypoint.command,
|
|
157
|
+
args: watch ? withWatchArgs(managerEntrypoint.args, watchPaths) : managerEntrypoint.args,
|
|
158
|
+
cwd: tenantRoot,
|
|
159
|
+
env: {
|
|
160
|
+
...sharedEnv,
|
|
161
|
+
PORT: sharedEnv.PORT ?? String(managerPort),
|
|
162
|
+
TREESEED_MANAGER_BASE_URL: sharedEnv.TREESEED_MANAGER_BASE_URL ?? `http://${apiHost}:${managerPort}`
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
if (includeServices || surface === "worker") {
|
|
167
|
+
commands.push({
|
|
168
|
+
id: "worker",
|
|
169
|
+
label: "Worker",
|
|
170
|
+
command: workerEntrypoint.command,
|
|
171
|
+
args: watch ? withWatchArgs(workerEntrypoint.args, watchPaths) : workerEntrypoint.args,
|
|
172
|
+
cwd: tenantRoot,
|
|
173
|
+
env: sharedEnv
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
if (includeServices || surface === "agents") {
|
|
177
|
+
commands.push({
|
|
178
|
+
id: "agents",
|
|
179
|
+
label: "Agents",
|
|
180
|
+
command: agentsEntrypoint.command,
|
|
181
|
+
args: watch ? withWatchArgs(agentsEntrypoint.args, watchPaths) : agentsEntrypoint.args,
|
|
182
|
+
cwd: tenantRoot,
|
|
183
|
+
env: sharedEnv
|
|
184
|
+
});
|
|
185
|
+
}
|
|
129
186
|
return {
|
|
130
187
|
surface,
|
|
131
188
|
tenantRoot,
|
|
@@ -205,6 +262,7 @@ async function runTreeseedIntegratedDev(options = {}, deps = {}) {
|
|
|
205
262
|
export {
|
|
206
263
|
TREESEED_DEFAULT_API_HOST,
|
|
207
264
|
TREESEED_DEFAULT_API_PORT,
|
|
265
|
+
TREESEED_DEFAULT_MANAGER_PORT,
|
|
208
266
|
TREESEED_DEFAULT_WEB_HOST,
|
|
209
267
|
TREESEED_DEFAULT_WEB_PORT,
|
|
210
268
|
createTreeseedIntegratedDevPlan,
|
package/dist/index.d.ts
CHANGED
|
@@ -5,4 +5,5 @@ export { createTreeseedApiApp } from './api/app';
|
|
|
5
5
|
export { createRailwayTreeseedApiServer } from './api/railway';
|
|
6
6
|
export { resolveApiConfig } from './api/config';
|
|
7
7
|
export { createTreeseedIntegratedDevPlan, runTreeseedIntegratedDev, type TreeseedIntegratedDevCommand, type TreeseedIntegratedDevOptions, type TreeseedIntegratedDevPlan, type TreeseedIntegratedDevSurface, } from './dev';
|
|
8
|
+
export { filterSiteRenderedModels, isSiteRenderedModel, siteModelRendered, } from './utils/site-models.ts';
|
|
8
9
|
export type * from './api/types';
|
package/dist/index.js
CHANGED
|
@@ -18,6 +18,11 @@ import {
|
|
|
18
18
|
createTreeseedIntegratedDevPlan,
|
|
19
19
|
runTreeseedIntegratedDev
|
|
20
20
|
} from "./dev.js";
|
|
21
|
+
import {
|
|
22
|
+
filterSiteRenderedModels,
|
|
23
|
+
isSiteRenderedModel,
|
|
24
|
+
siteModelRendered
|
|
25
|
+
} from "./utils/site-models.js";
|
|
21
26
|
export {
|
|
22
27
|
TREESEED_PLATFORM_RESOURCE_KINDS,
|
|
23
28
|
TREESEED_SITE_RESOURCE_KINDS,
|
|
@@ -26,11 +31,14 @@ export {
|
|
|
26
31
|
createRailwayTreeseedApiServer,
|
|
27
32
|
createTreeseedApiApp,
|
|
28
33
|
createTreeseedIntegratedDevPlan,
|
|
34
|
+
filterSiteRenderedModels,
|
|
35
|
+
isSiteRenderedModel,
|
|
29
36
|
parseSiteConfig,
|
|
30
37
|
resolveApiConfig,
|
|
31
38
|
resolveTreeseedPageEntrypoint,
|
|
32
39
|
resolveTreeseedPlatformResource,
|
|
33
40
|
resolveTreeseedSiteResource,
|
|
34
41
|
resolveTreeseedStyleEntrypoint,
|
|
35
|
-
runTreeseedIntegratedDev
|
|
42
|
+
runTreeseedIntegratedDev,
|
|
43
|
+
siteModelRendered
|
|
36
44
|
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type EditorialPreviewTokenPayload } from '@treeseed/sdk/platform/published-content';
|
|
2
|
+
type CookieValue = {
|
|
3
|
+
value: string;
|
|
4
|
+
} | undefined;
|
|
5
|
+
export interface EditorialPreviewContextLike {
|
|
6
|
+
url: URL;
|
|
7
|
+
cookies: {
|
|
8
|
+
get(name: string): CookieValue;
|
|
9
|
+
set(name: string, value: string, options?: {
|
|
10
|
+
httpOnly?: boolean;
|
|
11
|
+
path?: string;
|
|
12
|
+
sameSite?: 'lax' | 'strict' | 'none';
|
|
13
|
+
secure?: boolean;
|
|
14
|
+
expires?: Date;
|
|
15
|
+
}): void;
|
|
16
|
+
delete(name: string, options?: {
|
|
17
|
+
path?: string;
|
|
18
|
+
}): void;
|
|
19
|
+
};
|
|
20
|
+
locals: object;
|
|
21
|
+
}
|
|
22
|
+
export declare function resolveEditorialPreview(context: EditorialPreviewContextLike, options?: {
|
|
23
|
+
secret?: string | null;
|
|
24
|
+
cookieName?: string;
|
|
25
|
+
}): EditorialPreviewTokenPayload | null;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import {
|
|
2
|
+
EDITORIAL_PREVIEW_COOKIE,
|
|
3
|
+
verifyEditorialPreviewToken
|
|
4
|
+
} from "@treeseed/sdk/platform/published-content";
|
|
5
|
+
function previewSecretFromLocals(locals) {
|
|
6
|
+
const runtime = locals?.runtime;
|
|
7
|
+
return typeof runtime?.env?.TREESEED_EDITORIAL_PREVIEW_SECRET === "string" ? runtime.env.TREESEED_EDITORIAL_PREVIEW_SECRET : "";
|
|
8
|
+
}
|
|
9
|
+
function resolveEditorialPreview(context, options = {}) {
|
|
10
|
+
const cookieName = options.cookieName ?? EDITORIAL_PREVIEW_COOKIE;
|
|
11
|
+
const secret = typeof options.secret === "string" ? options.secret : previewSecretFromLocals(context.locals);
|
|
12
|
+
const queryPreview = context.url.searchParams.get("preview");
|
|
13
|
+
if (queryPreview === "clear") {
|
|
14
|
+
context.cookies.delete(cookieName, { path: "/" });
|
|
15
|
+
context.locals.contentPreview = null;
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
const cookiePreview = context.cookies.get(cookieName)?.value ?? null;
|
|
19
|
+
const activeToken = queryPreview || cookiePreview;
|
|
20
|
+
const resolvedPreview = activeToken && secret ? verifyEditorialPreviewToken(activeToken, secret) : null;
|
|
21
|
+
if (queryPreview && resolvedPreview) {
|
|
22
|
+
context.cookies.set(cookieName, queryPreview, {
|
|
23
|
+
httpOnly: true,
|
|
24
|
+
path: "/",
|
|
25
|
+
sameSite: "lax",
|
|
26
|
+
secure: context.url.protocol === "https:",
|
|
27
|
+
expires: new Date(resolvedPreview.expiresAt)
|
|
28
|
+
});
|
|
29
|
+
} else if (activeToken && !resolvedPreview) {
|
|
30
|
+
context.cookies.delete(cookieName, { path: "/" });
|
|
31
|
+
}
|
|
32
|
+
context.locals.contentPreview = resolvedPreview;
|
|
33
|
+
return resolvedPreview;
|
|
34
|
+
}
|
|
35
|
+
export {
|
|
36
|
+
resolveEditorialPreview
|
|
37
|
+
};
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { defineRouteMiddleware } from "../vendor/starlight/route-data.js";
|
|
2
|
-
import {
|
|
2
|
+
import { TREESEED_LINKS, buildStarlightSidebarEntriesFromRuntime, normalizeHref } from "../utils/starlight-nav.js";
|
|
3
|
+
import { loadHostedBookRuntime } from "../utils/published-content.js";
|
|
4
|
+
import { BOOKS, BOOKS_LINK, TREESEED_LIBRARY_DOWNLOAD } from "@treeseed/sdk/platform/books-data";
|
|
5
|
+
import { loadTreeseedManifest, tenantModelRendered } from "@treeseed/sdk/platform/tenant-config";
|
|
3
6
|
const copyLink = (entry) => ({ ...entry, attrs: { ...entry.attrs } });
|
|
4
7
|
const copyEntry = (entry) => entry.type === "link" ? copyLink(entry) : {
|
|
5
8
|
...entry,
|
|
@@ -23,10 +26,18 @@ const setRouteSidebar = (route, currentPath, sidebar, paginationSource) => {
|
|
|
23
26
|
route.hasSidebar = sidebar.length > 0;
|
|
24
27
|
route.pagination = paginationSource ? buildPagination(paginationSource, currentPath) : { prev: void 0, next: void 0 };
|
|
25
28
|
};
|
|
26
|
-
const
|
|
29
|
+
const defaultRuntime = { BOOKS, BOOKS_LINK, TREESEED_LIBRARY_DOWNLOAD, TREESEED_LINKS };
|
|
30
|
+
const tenantConfig = loadTreeseedManifest();
|
|
31
|
+
const onRequest = defineRouteMiddleware(async (context) => {
|
|
27
32
|
const route = context.locals.starlightRoute;
|
|
28
33
|
const currentPath = normalizeHref(context.url.pathname);
|
|
29
|
-
|
|
34
|
+
if (!tenantModelRendered(tenantConfig, "books")) {
|
|
35
|
+
setRouteSidebar(route, currentPath, [], null);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const runtime = await loadHostedBookRuntime(context.locals) ?? defaultRuntime;
|
|
39
|
+
route.sidebar = buildStarlightSidebarEntriesFromRuntime(runtime, currentPath);
|
|
40
|
+
const activeBook = runtime.BOOKS.find(
|
|
30
41
|
(book) => currentPath.startsWith(normalizeHref(book.basePath))
|
|
31
42
|
);
|
|
32
43
|
if (activeBook) {
|
|
@@ -35,7 +46,7 @@ const onRequest = defineRouteMiddleware((context) => {
|
|
|
35
46
|
setRouteSidebar(route, currentPath, [copyEntry(bookGroup)], bookGroup.entries);
|
|
36
47
|
return;
|
|
37
48
|
}
|
|
38
|
-
if (currentPath === normalizeHref(TREESEED_LINKS.home)) {
|
|
49
|
+
if (currentPath === normalizeHref(runtime.TREESEED_LINKS.home)) {
|
|
39
50
|
setRouteSidebar(route, currentPath, [], null);
|
|
40
51
|
return;
|
|
41
52
|
}
|
package/dist/pages/[slug].astro
CHANGED
|
@@ -2,23 +2,25 @@
|
|
|
2
2
|
import { getCollection, render } from 'astro:content';
|
|
3
3
|
import ContentLayout from '../layouts/ContentLayout.astro';
|
|
4
4
|
import BridgeLayout from '../layouts/BridgeLayout.astro';
|
|
5
|
+
import RouteNotFound from '../components/site/RouteNotFound.astro';
|
|
5
6
|
|
|
6
|
-
export
|
|
7
|
-
const entries = await getCollection('pages');
|
|
7
|
+
export const prerender = false;
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
9
|
+
const slug = String(Astro.params.slug ?? '');
|
|
10
|
+
const entries = await getCollection('pages');
|
|
11
|
+
const entry = entries.find((candidate) => candidate.data.slug === slug) ?? null;
|
|
12
|
+
if (!entry) {
|
|
13
|
+
Astro.response.status = 404;
|
|
13
14
|
}
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
const { Content } = await render(entry);
|
|
15
|
+
const rendered = entry ? await render(entry) : null;
|
|
16
|
+
const Content = rendered?.Content ?? null;
|
|
17
17
|
const currentPath = Astro.url.pathname;
|
|
18
18
|
---
|
|
19
19
|
|
|
20
20
|
{
|
|
21
|
-
entry
|
|
21
|
+
!entry || !Content ? (
|
|
22
|
+
<RouteNotFound title="Page not found" description="The requested page is not available in this Treeseed." currentPath={currentPath} />
|
|
23
|
+
) : entry.data.pageLayout === 'bridge' ? (
|
|
22
24
|
<BridgeLayout entry={entry.data} currentPath={currentPath}>
|
|
23
25
|
<Content />
|
|
24
26
|
</BridgeLayout>
|
|
@@ -2,28 +2,35 @@
|
|
|
2
2
|
import { getCollection, render } from 'astro:content';
|
|
3
3
|
import ProfileLayout from '../../layouts/ProfileLayout.astro';
|
|
4
4
|
import { resolveReferences } from '../../utils/hub-content';
|
|
5
|
+
import RouteNotFound from '../../components/site/RouteNotFound.astro';
|
|
5
6
|
|
|
6
|
-
export
|
|
7
|
-
const agents = await getCollection('agents');
|
|
8
|
-
return agents.map((agent) => ({
|
|
9
|
-
params: { slug: agent.id },
|
|
10
|
-
props: { agent },
|
|
11
|
-
}));
|
|
12
|
-
}
|
|
7
|
+
export const prerender = false;
|
|
13
8
|
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
|
|
9
|
+
const slug = String(Astro.params.slug ?? '');
|
|
10
|
+
const agents = await getCollection('agents');
|
|
11
|
+
const agent = agents.find((candidate) => candidate.id === slug) ?? null;
|
|
12
|
+
if (!agent) {
|
|
13
|
+
Astro.response.status = 404;
|
|
14
|
+
}
|
|
15
|
+
const rendered = agent ? await render(agent) : null;
|
|
16
|
+
const Content = rendered?.Content ?? null;
|
|
17
|
+
const relatedQuestions = agent ? await resolveReferences(agent.data.relatedQuestions) : [];
|
|
18
|
+
const relatedObjectives = agent ? await resolveReferences(agent.data.relatedObjectives) : [];
|
|
18
19
|
---
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
21
|
+
{
|
|
22
|
+
!agent || !Content ? (
|
|
23
|
+
<RouteNotFound title="Agent not found" description="The requested agent profile could not be found in this Treeseed." currentPath="/agents/" />
|
|
24
|
+
) : (
|
|
25
|
+
<ProfileLayout
|
|
26
|
+
entry={agent.data}
|
|
27
|
+
currentPath="/agents/"
|
|
28
|
+
metaLabel="Operator"
|
|
29
|
+
metaValue={`${agent.data.operator} · ${agent.data.runtimeStatus}`}
|
|
30
|
+
relatedQuestions={relatedQuestions}
|
|
31
|
+
relatedObjectives={relatedObjectives}
|
|
32
|
+
>
|
|
33
|
+
<Content />
|
|
34
|
+
</ProfileLayout>
|
|
35
|
+
)
|
|
36
|
+
}
|
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
---
|
|
2
2
|
import { getCollection, render } from 'astro:content';
|
|
3
3
|
import BookLayout from '../../layouts/BookLayout.astro';
|
|
4
|
+
import RouteNotFound from '../../components/site/RouteNotFound.astro';
|
|
4
5
|
|
|
5
|
-
export
|
|
6
|
-
const books = (await getCollection('books')).sort((a, b) => a.data.order - b.data.order);
|
|
7
|
-
return books.map((book) => ({
|
|
8
|
-
params: { slug: book.id },
|
|
9
|
-
props: { book },
|
|
10
|
-
}));
|
|
11
|
-
}
|
|
6
|
+
export const prerender = false;
|
|
12
7
|
|
|
13
|
-
const
|
|
14
|
-
const
|
|
8
|
+
const slug = String(Astro.params.slug ?? '');
|
|
9
|
+
const books = (await getCollection('books')).sort((a, b) => a.data.order - b.data.order);
|
|
10
|
+
const book = books.find((candidate) => candidate.id === slug) ?? null;
|
|
11
|
+
if (!book) {
|
|
12
|
+
Astro.response.status = 404;
|
|
13
|
+
}
|
|
14
|
+
const rendered = book ? await render(book) : null;
|
|
15
|
+
const Content = rendered?.Content ?? null;
|
|
15
16
|
---
|
|
16
17
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
{
|
|
19
|
+
!book || !Content ? (
|
|
20
|
+
<RouteNotFound title="Book not found" description="The requested book could not be found in this Treeseed." currentPath="/books/" />
|
|
21
|
+
) : (
|
|
22
|
+
<BookLayout entry={book.data} currentPath="/books/">
|
|
23
|
+
<Content />
|
|
24
|
+
</BookLayout>
|
|
25
|
+
)
|
|
26
|
+
}
|