@treeseed/core 0.4.9 → 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.
Files changed (82) hide show
  1. package/README.md +1 -2
  2. package/dist/agent.d.ts +0 -1
  3. package/dist/agent.js +0 -2
  4. package/dist/agents/spec-types.d.ts +10 -10
  5. package/dist/api/agent-routes.d.ts +2 -2
  6. package/dist/api/agent-routes.js +51 -125
  7. package/dist/api/app.js +56 -4
  8. package/dist/api/auth/d1-store.d.ts +1 -0
  9. package/dist/api/auth/d1-store.js +21 -1
  10. package/dist/api/auth/rbac.d.ts +2 -2
  11. package/dist/api/auth/rbac.js +2 -1
  12. package/dist/api/config.js +4 -0
  13. package/dist/api/http.d.ts +4 -0
  14. package/dist/api/http.js +7 -0
  15. package/dist/api/index.d.ts +1 -1
  16. package/dist/api/index.js +2 -2
  17. package/dist/api/operations-routes.d.ts +1 -0
  18. package/dist/api/operations-routes.js +6 -1
  19. package/dist/api/railway.d.ts +4 -0
  20. package/dist/api/sdk-dispatch.d.ts +2 -11
  21. package/dist/api/sdk-dispatch.js +1 -133
  22. package/dist/api/sdk-routes.d.ts +1 -0
  23. package/dist/api/sdk-routes.js +5 -1
  24. package/dist/api/types.d.ts +32 -16
  25. package/dist/components/site/RouteNotFound.astro +25 -0
  26. package/dist/content-config.d.ts +1 -0
  27. package/dist/content.d.ts +1 -0
  28. package/dist/content.js +177 -1
  29. package/dist/dev.d.ts +7 -2
  30. package/dist/dev.js +83 -2
  31. package/dist/index.d.ts +1 -1
  32. package/dist/index.js +9 -3
  33. package/dist/middleware/editorial-preview.d.ts +26 -0
  34. package/dist/middleware/editorial-preview.js +37 -0
  35. package/dist/middleware/starlightRouteData.js +15 -4
  36. package/dist/pages/[slug].astro +12 -10
  37. package/dist/pages/agents/[slug].astro +28 -21
  38. package/dist/pages/books/[slug].astro +19 -12
  39. package/dist/pages/feed.xml.js +6 -4
  40. package/dist/pages/index.astro +43 -14
  41. package/dist/pages/notes/[slug].astro +19 -12
  42. package/dist/pages/objectives/[slug].astro +30 -23
  43. package/dist/pages/people/[slug].astro +28 -21
  44. package/dist/pages/questions/[slug].astro +30 -23
  45. package/dist/scripts/build-dist.js +6 -1
  46. package/dist/scripts/dev-platform.js +9 -1
  47. package/dist/scripts/test-smoke.js +0 -1
  48. package/dist/services/agents.d.ts +22 -0
  49. package/dist/services/agents.js +29 -0
  50. package/dist/services/common.d.ts +37 -4
  51. package/dist/services/common.js +135 -17
  52. package/dist/services/index.d.ts +4 -1
  53. package/dist/services/index.js +14 -2
  54. package/dist/services/manager.d.ts +246 -3
  55. package/dist/services/manager.js +1101 -171
  56. package/dist/services/remote-runner.d.ts +30 -0
  57. package/dist/services/remote-runner.js +111 -0
  58. package/dist/services/workday-content.d.ts +53 -0
  59. package/dist/services/workday-content.js +190 -0
  60. package/dist/services/workday-report.d.ts +160 -2
  61. package/dist/services/workday-report.js +4 -31
  62. package/dist/services/workday-start.d.ts +174 -1
  63. package/dist/services/workday-start.js +3 -13
  64. package/dist/services/worker-pool-scaler.d.ts +27 -0
  65. package/dist/services/worker-pool-scaler.js +109 -0
  66. package/dist/services/worker.d.ts +7 -0
  67. package/dist/services/worker.js +41 -57
  68. package/dist/site.js +43 -27
  69. package/dist/templates.d.ts +98 -0
  70. package/dist/templates.js +170 -0
  71. package/dist/tenant/runtime-config.d.ts +4 -0
  72. package/dist/tenant/runtime-config.js +34 -1
  73. package/dist/utils/hub-content.js +35 -0
  74. package/dist/utils/published-content.js +60 -0
  75. package/dist/utils/site-models.d.ts +6 -0
  76. package/dist/utils/site-models.js +16 -0
  77. package/dist/utils/starlight-nav.js +50 -0
  78. package/package.json +23 -9
  79. package/templates/github/deploy.workflow.yml +404 -9
  80. package/templates/github/hosted-project.workflow.yml +77 -0
  81. package/dist/api/gateway.d.ts +0 -5
  82. package/dist/api/gateway.js +0 -35
@@ -1,8 +1,8 @@
1
1
  export { createTreeseedApiApp } from './app.ts';
2
- export { createTreeseedGatewayApp } from './gateway.ts';
3
2
  export { resolveApiConfig } from './config.ts';
4
3
  export { createRailwayTreeseedApiServer } from './railway.ts';
5
4
  export { resolveApiRuntimeProviders } from './providers.ts';
5
+ export { resolveApiD1Database } from './auth/d1-database.ts';
6
6
  export { loadTemplateCatalog } from './templates.ts';
7
7
  export { MemoryDeviceCodeAuthProvider } from './auth/memory-provider.ts';
8
8
  export { D1AuthProvider } from './auth/d1-provider.ts';
package/dist/api/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { createTreeseedApiApp } from "./app.js";
2
- import { createTreeseedGatewayApp } from "./gateway.js";
3
2
  import { resolveApiConfig } from "./config.js";
4
3
  import { createRailwayTreeseedApiServer } from "./railway.js";
5
4
  import { resolveApiRuntimeProviders } from "./providers.js";
5
+ import { resolveApiD1Database } from "./auth/d1-database.js";
6
6
  import { loadTemplateCatalog } from "./templates.js";
7
7
  import { MemoryDeviceCodeAuthProvider } from "./auth/memory-provider.js";
8
8
  import { D1AuthProvider } from "./auth/d1-provider.js";
@@ -11,8 +11,8 @@ export {
11
11
  MemoryDeviceCodeAuthProvider,
12
12
  createRailwayTreeseedApiServer,
13
13
  createTreeseedApiApp,
14
- createTreeseedGatewayApp,
15
14
  loadTemplateCatalog,
16
15
  resolveApiConfig,
16
+ resolveApiD1Database,
17
17
  resolveApiRuntimeProviders
18
18
  };
@@ -2,5 +2,6 @@ import type { Hono } from 'hono';
2
2
  import { executeHttpWorkflowOperation } from './operations.ts';
3
3
  export declare function registerOperationRoutes(app: Hono<any>, options: {
4
4
  scope: string;
5
+ prefix?: string;
5
6
  executeOperation?: typeof executeHttpWorkflowOperation;
6
7
  }): void;
@@ -3,7 +3,12 @@ import { executeHttpWorkflowOperation, isHttpWorkflowOperationAllowed } from "./
3
3
  import { jsonError, requireScope } from "./http.js";
4
4
  function registerOperationRoutes(app, options) {
5
5
  const executeOperation = options.executeOperation ?? executeHttpWorkflowOperation;
6
- app.post("/operations/:operation", async (c) => {
6
+ const prefix = options.prefix ?? "";
7
+ function withPrefix(path) {
8
+ if (!prefix) return path;
9
+ return `${prefix}${path}`.replace(/\/{2,}/g, "/");
10
+ }
11
+ app.post(withPrefix("/operations/:operation"), async (c) => {
7
12
  const unauthorized = requireScope(c, options.scope);
8
13
  if (unauthorized) return unauthorized;
9
14
  const requestedOperation = c.req.param("operation");
@@ -22,7 +22,11 @@ export declare function createRailwayTreeseedApiServer(options?: ApiServerOption
22
22
  baseUrl: string;
23
23
  issuer: string;
24
24
  repoRoot: string;
25
+ projectId: string;
25
26
  authSecret: string;
27
+ projectApiKey?: string;
28
+ projectApiLabel: string;
29
+ projectApiPermissions: string[];
26
30
  cloudflareAccountId?: string;
27
31
  cloudflareApiToken?: string;
28
32
  d1DatabaseId?: string;
@@ -1,14 +1,5 @@
1
1
  import type { AgentSdk, RemoteSdkOperationRequest } from '@treeseed/sdk';
2
+ import { executeSdkOperation, findSdkOperation, listSdkOperationNames } from '@treeseed/sdk';
2
3
  import type { ApiConfig } from './types.ts';
3
- type JsonRecord = Record<string, unknown>;
4
- type SdkOperationHandler = (sdk: AgentSdk, input: JsonRecord) => Promise<unknown> | unknown;
5
- interface SdkOperationSpec {
6
- name: string;
7
- aliases?: string[];
8
- handler: SdkOperationHandler;
9
- }
10
- export declare function listSdkOperationNames(): string[];
11
- export declare function findSdkOperation(name: string): SdkOperationSpec;
4
+ export { executeSdkOperation, findSdkOperation, listSdkOperationNames, };
12
5
  export declare function resolveSdkInstance(sharedSdk: AgentSdk | undefined, config: ApiConfig, request: RemoteSdkOperationRequest): AgentSdk;
13
- export declare function executeSdkOperation(sdk: AgentSdk, operationName: string, input: JsonRecord): Promise<unknown>;
14
- export {};
@@ -1,142 +1,10 @@
1
- import { AgentSdk as AgentSdkClass } from "@treeseed/sdk";
2
- function passthrough(methodName) {
3
- return (sdk, input) => sdk[methodName](input);
4
- }
5
- const SDK_OPERATION_SPECS = [
6
- { name: "get", handler: passthrough("get") },
7
- { name: "read", handler: passthrough("read") },
8
- { name: "search", handler: passthrough("search") },
9
- { name: "follow", handler: passthrough("follow") },
10
- { name: "pick", handler: passthrough("pick") },
11
- { name: "create", handler: passthrough("create") },
12
- { name: "update", handler: passthrough("update") },
13
- { name: "claimMessage", aliases: ["claim-message"], handler: passthrough("claimMessage") },
14
- { name: "ackMessage", aliases: ["ack-message"], handler: passthrough("ackMessage") },
15
- { name: "createMessage", aliases: ["create-message"], handler: passthrough("createMessage") },
16
- { name: "recordRun", aliases: ["record-run"], handler: passthrough("recordRun") },
17
- { name: "getCursor", aliases: ["get-cursor"], handler: passthrough("getCursor") },
18
- { name: "upsertCursor", aliases: ["upsert-cursor"], handler: passthrough("upsertCursor") },
19
- { name: "releaseLease", aliases: ["release-lease"], handler: passthrough("releaseLease") },
20
- {
21
- name: "releaseAllLeases",
22
- aliases: ["release-all-leases"],
23
- handler: (sdk) => sdk.releaseAllLeases()
24
- },
25
- { name: "startWorkDay", aliases: ["start-work-day"], handler: passthrough("startWorkDay") },
26
- { name: "closeWorkDay", aliases: ["close-work-day"], handler: passthrough("closeWorkDay") },
27
- { name: "createTask", aliases: ["create-task"], handler: passthrough("createTask") },
28
- { name: "claimTask", aliases: ["claim-task"], handler: passthrough("claimTask") },
29
- {
30
- name: "recordTaskProgress",
31
- aliases: ["record-task-progress"],
32
- handler: passthrough("recordTaskProgress")
33
- },
34
- { name: "completeTask", aliases: ["complete-task"], handler: passthrough("completeTask") },
35
- { name: "failTask", aliases: ["fail-task"], handler: passthrough("failTask") },
36
- { name: "appendTaskEvent", aliases: ["append-task-event"], handler: passthrough("appendTaskEvent") },
37
- { name: "searchTasks", aliases: ["search-tasks"], handler: passthrough("searchTasks") },
38
- {
39
- name: "getManagerContext",
40
- aliases: ["get-manager-context"],
41
- handler: (sdk, input) => sdk.getManagerContext(String(input.taskId ?? input.id ?? ""))
42
- },
43
- { name: "createReport", aliases: ["create-report"], handler: passthrough("createReport") },
44
- {
45
- name: "listAgentSpecs",
46
- aliases: ["list-agent-specs"],
47
- handler: (sdk, input) => sdk.listAgentSpecs(input)
48
- },
49
- { name: "refreshGraph", aliases: ["refresh-graph"], handler: passthrough("refreshGraph") },
50
- {
51
- name: "searchFiles",
52
- aliases: ["search-files"],
53
- handler: (sdk, input) => sdk.searchFiles(String(input.query ?? ""), input.options)
54
- },
55
- {
56
- name: "searchSections",
57
- aliases: ["search-sections"],
58
- handler: (sdk, input) => sdk.searchSections(String(input.query ?? ""), input.options)
59
- },
60
- {
61
- name: "searchEntities",
62
- aliases: ["search-entities"],
63
- handler: (sdk, input) => sdk.searchEntities(String(input.query ?? ""), input.options)
64
- },
65
- {
66
- name: "getGraphNode",
67
- aliases: ["get-graph-node"],
68
- handler: (sdk, input) => sdk.getGraphNode(String(input.id ?? ""))
69
- },
70
- {
71
- name: "getNeighbors",
72
- aliases: ["get-neighbors"],
73
- handler: (sdk, input) => sdk.getNeighbors(String(input.id ?? ""), input.options)
74
- },
75
- {
76
- name: "followReferences",
77
- aliases: ["follow-references"],
78
- handler: (sdk, input) => sdk.followReferences(String(input.id ?? ""), input.options)
79
- },
80
- {
81
- name: "getBacklinks",
82
- aliases: ["get-backlinks"],
83
- handler: (sdk, input) => sdk.getBacklinks(String(input.id ?? ""), input.options)
84
- },
85
- {
86
- name: "getRelated",
87
- aliases: ["get-related"],
88
- handler: (sdk, input) => sdk.getRelated(String(input.id ?? ""), input.options)
89
- },
90
- {
91
- name: "getSubgraph",
92
- aliases: ["get-subgraph"],
93
- handler: (sdk, input) => sdk.getSubgraph(Array.isArray(input.seedIds) ? input.seedIds.map(String) : [], input.options)
94
- },
95
- { name: "resolveSeeds", aliases: ["resolve-seeds"], handler: passthrough("resolveSeeds") },
96
- { name: "queryGraph", aliases: ["query-graph"], handler: passthrough("queryGraph") },
97
- { name: "buildContextPack", aliases: ["build-context-pack"], handler: passthrough("buildContextPack") },
98
- {
99
- name: "parseGraphDsl",
100
- aliases: ["parse-graph-dsl"],
101
- handler: (sdk, input) => sdk.parseGraphDsl(String(input.source ?? input.query ?? ""))
102
- },
103
- {
104
- name: "resolveReference",
105
- aliases: ["resolve-reference"],
106
- handler: (sdk, input) => sdk.resolveReference(String(input.reference ?? ""), input.options)
107
- },
108
- {
109
- name: "explainReferenceChain",
110
- aliases: ["explain-reference-chain"],
111
- handler: (sdk, input) => sdk.explainReferenceChain(String(input.fromId ?? ""), String(input.toId ?? ""))
112
- }
113
- ];
114
- const SDK_OPERATION_INDEX = /* @__PURE__ */ new Map();
115
- for (const spec of SDK_OPERATION_SPECS) {
116
- SDK_OPERATION_INDEX.set(spec.name, spec);
117
- for (const alias of spec.aliases ?? []) {
118
- SDK_OPERATION_INDEX.set(alias, spec);
119
- }
120
- }
121
- function listSdkOperationNames() {
122
- return [...new Set(SDK_OPERATION_SPECS.map((entry) => entry.name))];
123
- }
124
- function findSdkOperation(name) {
125
- return SDK_OPERATION_INDEX.get(name) ?? null;
126
- }
1
+ import { AgentSdk as AgentSdkClass, executeSdkOperation, findSdkOperation, listSdkOperationNames } from "@treeseed/sdk";
127
2
  function resolveSdkInstance(sharedSdk, config, request) {
128
3
  if (!request.repoRoot || request.repoRoot === config.repoRoot) {
129
4
  return sharedSdk ?? new AgentSdkClass({ repoRoot: config.repoRoot });
130
5
  }
131
6
  return new AgentSdkClass({ repoRoot: request.repoRoot });
132
7
  }
133
- async function executeSdkOperation(sdk, operationName, input) {
134
- const spec = findSdkOperation(operationName);
135
- if (!spec) {
136
- throw new Error(`Unknown SDK operation "${operationName}".`);
137
- }
138
- return await spec.handler(sdk, input);
139
- }
140
8
  export {
141
9
  executeSdkOperation,
142
10
  findSdkOperation,
@@ -5,6 +5,7 @@ interface RegisterSdkRoutesOptions {
5
5
  config: ApiConfig;
6
6
  sharedSdk?: AgentSdk;
7
7
  scope: string;
8
+ prefix?: string;
8
9
  }
9
10
  export declare function registerSdkRoutes(app: Hono<any>, options: RegisterSdkRoutesOptions): void;
10
11
  export {};
@@ -1,7 +1,11 @@
1
1
  import { executeSdkOperation, resolveSdkInstance } from "./sdk-dispatch.js";
2
2
  import { jsonError, requireScope } from "./http.js";
3
+ function withPrefix(prefix, path) {
4
+ if (!prefix) return path;
5
+ return `${prefix}${path}`.replace(/\/{2,}/g, "/");
6
+ }
3
7
  function registerSdkRoutes(app, options) {
4
- app.post("/sdk/:operation", async (c) => {
8
+ app.post(withPrefix(options.prefix ?? "", "/sdk/:operation"), async (c) => {
5
9
  const unauthorized = requireScope(c, options.scope);
6
10
  if (unauthorized) return unauthorized;
7
11
  const operation = c.req.param("operation");
@@ -1,4 +1,5 @@
1
- import type { AgentSdk, SdkQueueMessageEnvelope } from '@treeseed/sdk';
1
+ import type { Hono } from 'hono';
2
+ import type { AgentSdk } from '@treeseed/sdk';
2
3
  import type { ApiPrincipal, ApiScope, DeviceCodeApproveRequest as SdkDeviceCodeApproveRequest, DeviceCodePollRequest, DeviceCodePollResponse, DeviceCodeStartRequest, DeviceCodeStartResponse, RemoteWorkflowOperationRequest as WorkflowHttpOperationRequest, RemoteWorkflowOperationResponse as ApiWorkflowOperationResponse, RemoteSdkOperationRequest as SdkHttpOperationRequest, TokenRefreshRequest, TokenRefreshResponse } from '@treeseed/sdk/remote';
3
4
  export type { ApiPrincipal, ApiScope, DeviceCodePollRequest, DeviceCodePollResponse, DeviceCodeStartRequest, DeviceCodeStartResponse, WorkflowHttpOperationRequest, ApiWorkflowOperationResponse, SdkHttpOperationRequest, TokenRefreshRequest, TokenRefreshResponse, };
4
5
  export type DeviceCodeApproveRequest = SdkDeviceCodeApproveRequest;
@@ -87,7 +88,11 @@ export interface ApiConfig {
87
88
  baseUrl: string;
88
89
  issuer: string;
89
90
  repoRoot: string;
91
+ projectId: string;
90
92
  authSecret: string;
93
+ projectApiKey?: string;
94
+ projectApiLabel: string;
95
+ projectApiPermissions: string[];
91
96
  cloudflareAccountId?: string;
92
97
  cloudflareApiToken?: string;
93
98
  d1DatabaseId?: string;
@@ -111,11 +116,11 @@ export interface AppVariables {
111
116
  principal: ApiPrincipal | null;
112
117
  actingUser: ApiPrincipal | null;
113
118
  credential: ApiCredential | null;
114
- actorType: 'anonymous' | 'user' | 'service';
119
+ actorType: 'anonymous' | 'user' | 'service' | 'project';
115
120
  permissionGrants: string[];
116
121
  }
117
122
  export interface ApiCredential {
118
- type: 'access_token' | 'personal_access_token' | 'service_secret' | 'service_token';
123
+ type: 'access_token' | 'personal_access_token' | 'service_secret' | 'service_token' | 'project_api_key' | 'team_api_key';
119
124
  id: string;
120
125
  label?: string;
121
126
  }
@@ -158,6 +163,28 @@ export interface ResolvedApiRuntimeProviders {
158
163
  };
159
164
  selections: ApiRuntimeProviderSelections;
160
165
  }
166
+ export interface ApiResolvedSettings {
167
+ config: ApiConfig;
168
+ surfaces: {
169
+ auth: boolean;
170
+ templates: boolean;
171
+ sdk: boolean;
172
+ agent: boolean;
173
+ operations: boolean;
174
+ };
175
+ scopes: {
176
+ authMe: ApiScope;
177
+ sdk: ApiScope;
178
+ agent: ApiScope;
179
+ operations: ApiScope;
180
+ };
181
+ }
182
+ export interface ApiAppRuntime {
183
+ resolved: ApiResolvedSettings;
184
+ runtimeProviders: ResolvedApiRuntimeProviders;
185
+ sharedSdk: AgentSdk;
186
+ internalPrefix: string;
187
+ }
161
188
  export interface ApiServerOptions {
162
189
  config?: Partial<ApiConfig>;
163
190
  runtimeProviders?: ApiRuntimeProviders;
@@ -176,18 +203,7 @@ export interface ApiServerOptions {
176
203
  agent: ApiScope;
177
204
  operations: ApiScope;
178
205
  }>;
206
+ internalPrefix?: string;
207
+ extendApp?: (app: Hono<any>, runtime: ApiAppRuntime) => void;
179
208
  log?: (message: string, details?: Record<string, unknown>) => void;
180
209
  }
181
- export interface GatewayQueueProducer {
182
- enqueue(request: {
183
- queueName?: string;
184
- message: SdkQueueMessageEnvelope;
185
- delaySeconds?: number;
186
- }): Promise<void>;
187
- }
188
- export interface GatewayServerOptions {
189
- sdk: AgentSdk;
190
- bearerToken: string;
191
- queueProducer?: GatewayQueueProducer;
192
- projectId?: string;
193
- }
@@ -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>
@@ -7,4 +7,5 @@ export declare function createTreeseedTenantCollections(manifestPath?: string):
7
7
  agents: any;
8
8
  books: any;
9
9
  docs: any;
10
+ workdays?: any;
10
11
  };
@@ -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
- return {
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 type TreeseedIntegratedDevSurface = 'integrated' | 'web' | 'api';
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[];