@treeseed/sdk 0.10.28 → 0.11.0
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 +207 -6
- package/dist/capacity-provider.d.ts +3 -1
- package/dist/capacity-provider.js +25 -5
- package/dist/control-plane.d.ts +1 -0
- package/dist/control-plane.js +38 -13
- package/dist/db/market-schema.d.ts +8860 -6172
- package/dist/db/market-schema.js +108 -0
- package/dist/db/node-sqlite.js +7 -2
- package/dist/hosting/apps.d.ts +12 -0
- package/dist/hosting/apps.js +107 -0
- package/dist/hosting/builtins.d.ts +25 -0
- package/dist/hosting/builtins.js +791 -0
- package/dist/hosting/contracts.d.ts +207 -0
- package/dist/hosting/contracts.js +0 -0
- package/dist/hosting/graph.d.ts +192 -0
- package/dist/hosting/graph.js +1106 -0
- package/dist/hosting/index.d.ts +4 -0
- package/dist/hosting/index.js +4 -0
- package/dist/index.d.ts +10 -3
- package/dist/index.js +63 -6
- package/dist/managed-dependencies.js +1 -2
- package/dist/market-client.d.ts +63 -3
- package/dist/market-client.js +83 -11
- package/dist/operations/services/bootstrap-runner.d.ts +3 -1
- package/dist/operations/services/bootstrap-runner.js +22 -2
- package/dist/operations/services/config-runtime.d.ts +10 -5
- package/dist/operations/services/config-runtime.js +209 -66
- package/dist/operations/services/deploy.d.ts +70 -7
- package/dist/operations/services/deploy.js +579 -64
- package/dist/operations/services/deployment-readiness.d.ts +30 -0
- package/dist/operations/services/deployment-readiness.js +175 -0
- package/dist/operations/services/git-workflow.d.ts +2 -1
- package/dist/operations/services/git-workflow.js +9 -3
- package/dist/operations/services/github-actions-verification.d.ts +1 -0
- package/dist/operations/services/github-actions-verification.js +1 -0
- package/dist/operations/services/github-api.js +1 -1
- package/dist/operations/services/github-automation.d.ts +1 -1
- package/dist/operations/services/github-automation.js +4 -3
- package/dist/operations/services/github-credentials.d.ts +13 -0
- package/dist/operations/services/github-credentials.js +58 -0
- package/dist/operations/services/hosted-service-checks.d.ts +63 -0
- package/dist/operations/services/hosted-service-checks.js +327 -0
- package/dist/operations/services/hub-provider-launch.js +3 -3
- package/dist/operations/services/live-hosted-service-checks.d.ts +25 -0
- package/dist/operations/services/live-hosted-service-checks.js +350 -0
- package/dist/operations/services/managed-host-security.js +1 -1
- package/dist/operations/services/operations-runner-smoke.d.ts +30 -0
- package/dist/operations/services/operations-runner-smoke.js +180 -0
- package/dist/operations/services/package-adapters.d.ts +95 -0
- package/dist/operations/services/package-adapters.js +288 -0
- package/dist/operations/services/package-reference-policy.d.ts +1 -0
- package/dist/operations/services/package-reference-policy.js +15 -2
- package/dist/operations/services/project-platform.d.ts +80 -22
- package/dist/operations/services/project-platform.js +49 -8
- package/dist/operations/services/project-web-monitor.js +26 -4
- package/dist/operations/services/railway-api.d.ts +88 -5
- package/dist/operations/services/railway-api.js +626 -35
- package/dist/operations/services/railway-deploy.d.ts +46 -40
- package/dist/operations/services/railway-deploy.js +261 -293
- package/dist/operations/services/release-candidate.d.ts +19 -0
- package/dist/operations/services/release-candidate.js +375 -38
- package/dist/operations/services/repository-save-orchestrator.d.ts +3 -1
- package/dist/operations/services/repository-save-orchestrator.js +279 -66
- package/dist/operations/services/runtime-tools.d.ts +1 -0
- package/dist/operations/services/runtime-tools.js +10 -9
- package/dist/operations/services/verification-cache.d.ts +25 -0
- package/dist/operations/services/verification-cache.js +71 -0
- package/dist/operations/services/workspace-dependency-mode.js +9 -1
- package/dist/operations/services/workspace-save.js +1 -1
- package/dist/operations/services/workspace-tools.js +2 -1
- package/dist/platform/contracts.d.ts +32 -1
- package/dist/platform/deploy-config.js +73 -8
- package/dist/platform/env.yaml +163 -35
- package/dist/platform/environment.d.ts +1 -0
- package/dist/platform/environment.js +74 -5
- package/dist/platform/plugin.d.ts +9 -0
- package/dist/platform-operation-store.js +2 -2
- package/dist/platform-operations.js +1 -1
- package/dist/reconcile/bootstrap-systems.js +2 -2
- package/dist/reconcile/builtin-adapters.js +372 -189
- package/dist/reconcile/contracts.d.ts +9 -5
- package/dist/reconcile/desired-state.d.ts +1 -0
- package/dist/reconcile/desired-state.js +5 -5
- package/dist/reconcile/engine.d.ts +5 -2
- package/dist/reconcile/engine.js +53 -32
- package/dist/reconcile/index.d.ts +2 -0
- package/dist/reconcile/index.js +2 -0
- package/dist/reconcile/live-acceptance.d.ts +79 -0
- package/dist/reconcile/live-acceptance.js +1615 -0
- package/dist/reconcile/platform.d.ts +104 -0
- package/dist/reconcile/platform.js +100 -0
- package/dist/reconcile/state.js +4 -4
- package/dist/reconcile/units.js +2 -2
- package/dist/scripts/deployment-readiness.js +20 -0
- package/dist/scripts/generate-treedx-openapi-types.js +186 -0
- package/dist/scripts/operations-runner-smoke.js +16 -0
- package/dist/scripts/release-verify.js +4 -1
- package/dist/scripts/tenant-workflow-action.js +10 -1
- package/dist/sdk-types.d.ts +169 -4
- package/dist/sdk-types.js +20 -2
- package/dist/sdk.d.ts +35 -24
- package/dist/sdk.js +186 -17
- package/dist/template-launch-requirements.js +9 -0
- package/dist/treedx/adapters.d.ts +6 -0
- package/dist/treedx/adapters.js +36 -0
- package/dist/treedx/client.d.ts +222 -0
- package/dist/treedx/client.js +871 -0
- package/dist/treedx/errors.d.ts +13 -0
- package/dist/treedx/errors.js +17 -0
- package/dist/treedx/federated-client.d.ts +27 -0
- package/dist/treedx/federated-client.js +158 -0
- package/dist/treedx/generated/openapi-types.d.ts +3558 -0
- package/dist/treedx/generated/openapi-types.js +0 -0
- package/dist/treedx/graph-adapter.d.ts +33 -0
- package/dist/treedx/graph-adapter.js +156 -0
- package/dist/treedx/index.d.ts +14 -0
- package/dist/treedx/index.js +48 -0
- package/dist/treedx/market-integration.d.ts +27 -0
- package/dist/treedx/market-integration.js +131 -0
- package/dist/treedx/ports.d.ts +166 -0
- package/dist/treedx/ports.js +231 -0
- package/dist/treedx/query-adapter.d.ts +19 -0
- package/dist/treedx/query-adapter.js +62 -0
- package/dist/treedx/registry-client.d.ts +11 -0
- package/dist/treedx/registry-client.js +19 -0
- package/dist/treedx/repository-adapter.d.ts +45 -0
- package/dist/treedx/repository-adapter.js +308 -0
- package/dist/treedx/sdk-integration.d.ts +27 -0
- package/dist/treedx/sdk-integration.js +63 -0
- package/dist/treedx/types.d.ts +1084 -0
- package/dist/treedx/types.js +8 -0
- package/dist/treedx/workspace-adapter.d.ts +27 -0
- package/dist/treedx/workspace-adapter.js +65 -0
- package/dist/treedx-backends.d.ts +218 -0
- package/dist/treedx-backends.js +632 -0
- package/dist/treedx-client.d.ts +86 -0
- package/dist/treedx-client.js +175 -0
- package/dist/treeseed/template-catalog/catalog.fixture.json +23 -23
- package/dist/workflow/operations.d.ts +119 -13
- package/dist/workflow/operations.js +309 -53
- package/dist/workflow-state.d.ts +13 -0
- package/dist/workflow-state.js +43 -26
- package/dist/workflow-support.d.ts +11 -3
- package/dist/workflow-support.js +67 -3
- package/dist/workflow.d.ts +5 -0
- package/drizzle/market/0004_treedx_market_integration.sql +99 -0
- package/package.json +34 -3
- package/templates/github/deploy-web.workflow.yml +39 -6
package/README.md
CHANGED
|
@@ -4,6 +4,21 @@
|
|
|
4
4
|
|
|
5
5
|
For most consumers, the right entrypoint is `AgentSdk`.
|
|
6
6
|
|
|
7
|
+
Use the SDK when you are writing automation, services, scripts, agents, or package internals that need Treeseed data, graph, workflow, config, reconciliation, hosting, package, or TreeDX integration primitives. Use the CLI when you want an operator command. Use Admin when you want a browser UI. Use API when you need the deployed backend service. Use UI when you need reusable components.
|
|
8
|
+
|
|
9
|
+
## How SDK Fits With Treeseed
|
|
10
|
+
|
|
11
|
+
The SDK is the shared platform substrate used by:
|
|
12
|
+
|
|
13
|
+
- `@treeseed/core` for site runtime, content, plugin, and hosting integration
|
|
14
|
+
- `@treeseed/admin` for admin contracts, view models, API facades, and platform primitives
|
|
15
|
+
- `@treeseed/api` for backend contracts, reconciliation, operation state, and shared data models
|
|
16
|
+
- `@treeseed/cli` for workflow, config, hosting, release, and reconciliation commands
|
|
17
|
+
- `@treeseed/agent` for provider contracts and runtime coordination
|
|
18
|
+
- root `@treeseed/market` for tenant config, content, and hosted workflow integration
|
|
19
|
+
|
|
20
|
+
The SDK is not a UI package, admin portal, backend server, CLI parser, capacity-provider runtime, or ecommerce implementation. See the root [Package Ownership](../../docs/package-ownership.md) guide for the full system map.
|
|
21
|
+
|
|
7
22
|
## Which Surface Should I Use?
|
|
8
23
|
|
|
9
24
|
Treeseed exposes three public SDK surfaces, but they are not peers:
|
|
@@ -24,9 +39,44 @@ If you are unsure, use `AgentSdk`.
|
|
|
24
39
|
- operational runtime state such as messages, runs, cursors, and leases
|
|
25
40
|
- control-plane orchestration for work days, tasks, task events, graph runs, and reports
|
|
26
41
|
- provider-neutral capacity scheduling contracts for task classification, admission, execution profiles, routing, estimates, planning proposals, attention load, utility, predictive reserve, hybrid execution, checkpoints, and usage actuals
|
|
42
|
+
- hosting graph compilation, deployment readiness, live hosted-service checks, Treeseed runner smoke helpers, and verification cache support for Treeseed workflows
|
|
27
43
|
- graph-first context retrieval through `parseGraphDsl()`, `resolveSeeds()`, `queryGraph()`, and `buildContextPack()`
|
|
28
44
|
- agent scoping through `scopeForAgent()`
|
|
29
45
|
|
|
46
|
+
## Workflow And Hosting Support
|
|
47
|
+
|
|
48
|
+
The SDK owns the shared implementation behind the fail-fast `trsd` deployment workflow.
|
|
49
|
+
It also owns the canonical reconciliation platform for desired-state infrastructure. See the root workspace `docs/reconciliation-platform.md` for the full contract.
|
|
50
|
+
|
|
51
|
+
Current workflow-support exports include:
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import {
|
|
55
|
+
collectTreeseedDeploymentReadiness,
|
|
56
|
+
collectTreeseedLiveHostedServiceChecks,
|
|
57
|
+
formatTreeseedReadinessReport,
|
|
58
|
+
runTreeseedOperationsRunnerSmoke,
|
|
59
|
+
} from '@treeseed/sdk/workflow-support';
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
These helpers are used by:
|
|
63
|
+
|
|
64
|
+
- `trsd ready <local|staging|prod>`
|
|
65
|
+
- `trsd hosting plan|apply|verify --environment <env> --service <id>`
|
|
66
|
+
- `trsd audit hosting --environment <env> --live`
|
|
67
|
+
- `trsd doctor --live --hosted-services`
|
|
68
|
+
- `trsd operations smoke --environment <env> --service operationsRunner`
|
|
69
|
+
- `trsd stage|release --verify-deployed-resources`
|
|
70
|
+
|
|
71
|
+
For the API app, the expected hosted backend services are the API service, indexed Treeseed operations runner, PostgreSQL, and public TreeDX federation nodes owned by `packages/api`. The root web app remains a web UI and `/v1/*` proxy/client surface, with admin routes contributed by `@treeseed/admin` and visual primitives contributed by `@treeseed/ui`.
|
|
72
|
+
|
|
73
|
+
Reconciliation guarantees:
|
|
74
|
+
|
|
75
|
+
- command surfaces compile desired resources before provider mutation
|
|
76
|
+
- cached state can locate resources but live observation proves readiness
|
|
77
|
+
- hosted apply cannot report `ok: true` when live postconditions fail
|
|
78
|
+
- adapter reports use `desiredGraph`, `observedGraph`, `stateGraph`, `diff`, `actions`, `postconditions`, `blockedDrift`, `providerLimitations`, `liveVerification`, and `ok`
|
|
79
|
+
|
|
30
80
|
## Install
|
|
31
81
|
|
|
32
82
|
```bash
|
|
@@ -61,6 +111,16 @@ const sdk = AgentSdk.createLocal({
|
|
|
61
111
|
});
|
|
62
112
|
```
|
|
63
113
|
|
|
114
|
+
## TreeDX Content Repository
|
|
115
|
+
|
|
116
|
+
TreeDX is the generic repository service used by Treeseed when TreeDX service configuration is available. The SDK is the Treeseed integration and client layer: it configures the TreeDX portfolio, maps Treeseed model registry behavior onto generic repository/ref/path/frontmatter/body/query requests, and keeps product semantics outside TreeDX. The API package may host public TreeDX federation nodes as part of backend reconciliation.
|
|
117
|
+
|
|
118
|
+
Project site code and optional project repositories remain local filesystem/git
|
|
119
|
+
workspace concerns by default. Use `contentRepository: { adapter: 'local' }` or
|
|
120
|
+
`AgentSdk.createLocal()` for explicit local content behavior.
|
|
121
|
+
|
|
122
|
+
See [TreeDX Content Repository](./docs/treedx-content-repository.md).
|
|
123
|
+
|
|
64
124
|
## Preferred Graph Workflow
|
|
65
125
|
|
|
66
126
|
The preferred graph API for new integrations is:
|
|
@@ -91,7 +151,7 @@ The public `ctx` syntax is:
|
|
|
91
151
|
|
|
92
152
|
```text
|
|
93
153
|
ctx <target>
|
|
94
|
-
[for <
|
|
154
|
+
[for <focus>]
|
|
95
155
|
[in <scope>]
|
|
96
156
|
[via <relation[,relation...]>]
|
|
97
157
|
[depth <0-3>]
|
|
@@ -103,9 +163,150 @@ ctx <target>
|
|
|
103
163
|
|
|
104
164
|
The old `key=value` graph DSL is no longer supported.
|
|
105
165
|
|
|
166
|
+
## TreeDX Remote Repository Mode
|
|
167
|
+
|
|
168
|
+
TreeDX support is opt-in. Local SDK behavior remains the default.
|
|
169
|
+
|
|
170
|
+
Use the low-level TreeDX client when you want direct repository, workspace, query, graph, registry, or context calls:
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
import { TreeDxClient } from '@treeseed/sdk/treedx';
|
|
174
|
+
|
|
175
|
+
const treeDx = new TreeDxClient({
|
|
176
|
+
baseUrl: 'http://localhost:4000',
|
|
177
|
+
token: process.env.TREEDX_TOKEN,
|
|
178
|
+
repoId: 'repo_123',
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
const whoami = await treeDx.whoami();
|
|
182
|
+
const file = await treeDx.readRepositoryFile({
|
|
183
|
+
path: 'docs/readme.md',
|
|
184
|
+
parseFrontmatter: true,
|
|
185
|
+
});
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
`AgentSdk` can delegate content-backed model and graph calls to TreeDX when configured explicitly:
|
|
189
|
+
|
|
190
|
+
```ts
|
|
191
|
+
import { AgentSdk, TreeDxClient } from '@treeseed/sdk';
|
|
192
|
+
|
|
193
|
+
const treeDx = new TreeDxClient({
|
|
194
|
+
baseUrl: 'http://localhost:4000',
|
|
195
|
+
token: process.env.TREEDX_TOKEN,
|
|
196
|
+
repoId: 'repo_123',
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
const sdk = new AgentSdk({
|
|
200
|
+
repoRoot: process.cwd(),
|
|
201
|
+
treeDx: {
|
|
202
|
+
enabled: true,
|
|
203
|
+
client: treeDx,
|
|
204
|
+
repoId: 'repo_123',
|
|
205
|
+
defaultRef: 'refs/heads/main',
|
|
206
|
+
},
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
const docs = await sdk.search({
|
|
210
|
+
model: 'knowledge',
|
|
211
|
+
filters: [{ field: 'status', op: 'eq', value: 'published' }],
|
|
212
|
+
});
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
TreeDX mode keeps TreeSeed model semantics in the SDK model registry. TreeDX receives generic repository/ref/path/frontmatter/body/query requests and returns generic repository/file/query/graph results.
|
|
216
|
+
|
|
217
|
+
TreeDX auth, policy, audit, and federation helpers are available on the same client:
|
|
218
|
+
|
|
219
|
+
```ts
|
|
220
|
+
const mode = await treeDx.authMode();
|
|
221
|
+
const scope = await treeDx.effectiveScope({ repoId: 'repo_123' });
|
|
222
|
+
|
|
223
|
+
await treeDx.putCapabilityGrant({
|
|
224
|
+
actorId: 'actor_agent',
|
|
225
|
+
tenantId: 'tenant_demo',
|
|
226
|
+
repoIds: ['repo_123'],
|
|
227
|
+
capabilities: ['files:read', 'files:search'],
|
|
228
|
+
refs: ['refs/heads/main'],
|
|
229
|
+
paths: ['docs/**'],
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
const audit = await treeDx.listAuditEvents({
|
|
233
|
+
repoId: 'repo_123',
|
|
234
|
+
eventType: 'repo.query_executed',
|
|
235
|
+
limit: 25,
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
const plan = await treeDx.planFederatedQuery({
|
|
239
|
+
repoIds: ['repo_123'],
|
|
240
|
+
capabilities: ['files:search'],
|
|
241
|
+
paths: { repo_123: ['docs/**'] },
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
const search = await treeDx.federatedSearch({
|
|
245
|
+
repoIds: ['repo_123'],
|
|
246
|
+
refs: { repo_123: 'refs/heads/main' },
|
|
247
|
+
paths: { repo_123: ['docs/**'] },
|
|
248
|
+
query: 'release',
|
|
249
|
+
includeErrors: true,
|
|
250
|
+
});
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
Federation planning performs scope reduction before execution. The SDK delegates global execution to TreeDX instead of fanning out across every node and filtering locally.
|
|
254
|
+
|
|
255
|
+
Snapshot, artifact, mirror sync, and migration helpers are also available on `TreeDxClient`:
|
|
256
|
+
|
|
257
|
+
```ts
|
|
258
|
+
const snapshot = await treeDx.buildSnapshot({
|
|
259
|
+
ref: 'refs/heads/main',
|
|
260
|
+
kind: 'repository_snapshot',
|
|
261
|
+
paths: ['docs/**'],
|
|
262
|
+
includeGraph: true,
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
const artifact = await treeDx.exportArtifact({
|
|
266
|
+
snapshotId: snapshot.snapshotId,
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
const download = await treeDx.downloadArtifact({
|
|
270
|
+
snapshotId: snapshot.snapshotId,
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
await treeDx.syncMirror({
|
|
274
|
+
mirrorId: 'mirror_123',
|
|
275
|
+
remoteName: 'origin',
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
await treeDx.createMigration({
|
|
279
|
+
targetNodeId: 'node_mirror',
|
|
280
|
+
mode: 'primary_transfer',
|
|
281
|
+
dryRun: true,
|
|
282
|
+
requireMirrorSynced: false,
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
await treeDx.ready();
|
|
286
|
+
await treeDx.deepHealth();
|
|
287
|
+
await treeDx.metrics();
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
`downloadArtifact()` returns an `ArrayBuffer` plus content type, filename, checksum, and snapshot headers. These APIs are generic TreeDX repository operations; TreeSeed package or release semantics are not encoded in TreeDX.
|
|
291
|
+
|
|
292
|
+
Mocked end-to-end TreeDX contract tests prove the SDK can drive the TreeDX repository loop without an agent-side clone when `contentPathMap` is supplied:
|
|
293
|
+
|
|
294
|
+
```bash
|
|
295
|
+
npx vitest run --config ./vitest.config.ts test/utils/treedx-e2e-contract.test.ts
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
The optional live contract command reports `not configured` and exits
|
|
299
|
+
successfully unless all of these are set:
|
|
300
|
+
|
|
301
|
+
```text
|
|
302
|
+
TREEDX_LIVE_URL
|
|
303
|
+
TREEDX_LIVE_TOKEN
|
|
304
|
+
TREEDX_LIVE_REPO_ID
|
|
305
|
+
```
|
|
306
|
+
|
|
106
307
|
## Capacity Scheduling Contracts
|
|
107
308
|
|
|
108
|
-
The SDK owns the provider-neutral capacity runtime helpers used by the agent manager, workers, and market control plane. These helpers keep work estimation separate from provider cost by normalizing `taskSignature + executionProfileId` estimates, then routing against grants, provider lanes, quality requirements, quota/congestion pressure, attention/context saturation, utility, predictive reserve, and hybrid
|
|
309
|
+
The SDK owns the provider-neutral capacity runtime helpers used by the agent manager, workers, and market control plane. These helpers keep work estimation separate from provider cost by normalizing `taskSignature + executionProfileId` estimates, then routing against grants, provider lanes, quality requirements, quota/congestion pressure, attention/context saturation, utility, predictive reserve, and hybrid execution metadata.
|
|
109
310
|
|
|
110
311
|
Capacity records remain metadata-compatible: advanced scheduling data lives in task payload JSON, routing decision candidates/scores, reservation metadata, capacity plan metadata, checkpoint artifacts, and usage actual metadata. Missing metadata is neutral, so older callers continue to use the credit-only behavior.
|
|
111
312
|
|
|
@@ -165,10 +366,10 @@ const scoped = sdk.scopeForAgent({
|
|
|
165
366
|
|
|
166
367
|
## Reference Docs
|
|
167
368
|
|
|
168
|
-
- [SDK Interface Reference](
|
|
169
|
-
- [Graph API Guide](
|
|
170
|
-
- [ctx Query Language](
|
|
171
|
-
- [How ctx Works](
|
|
369
|
+
- [SDK Interface Reference](../../src/content/knowledge/sdk/interface-reference.mdx)
|
|
370
|
+
- [Graph API Guide](../../src/content/knowledge/sdk/graph-api-guide.mdx)
|
|
371
|
+
- [ctx Query Language](../../src/content/knowledge/sdk/ctx-query-language.mdx)
|
|
372
|
+
- [How ctx Works](../../src/content/knowledge/sdk/ctx-query-engine.mdx)
|
|
172
373
|
|
|
173
374
|
## Other Public Capabilities
|
|
174
375
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { NativeUsageObservation } from './sdk-types.ts';
|
|
2
|
+
import type { ProjectRepositoryTopology } from './sdk-types.ts';
|
|
2
3
|
export declare const CAPACITY_PROVIDER_ENDPOINTS: {
|
|
3
4
|
readonly register: "/v1/provider/register";
|
|
4
5
|
readonly heartbeat: "/v1/provider/heartbeat";
|
|
@@ -12,7 +13,7 @@ export declare const CAPACITY_PROVIDER_ENDPOINTS: {
|
|
|
12
13
|
readonly reports: "/v1/provider/reports";
|
|
13
14
|
};
|
|
14
15
|
export declare const CAPACITY_PROVIDER_SCOPES: readonly ["provider:register", "provider:heartbeat", "provider:portfolio:read", "provider:tasks:claim", "provider:tasks:update", "provider:usage:report", "provider:reports:write", "provider:capabilities:write"];
|
|
15
|
-
export declare const CAPACITY_PROVIDER_ENV_KEYS: readonly ["TREESEED_MARKET_URL", "
|
|
16
|
+
export declare const CAPACITY_PROVIDER_ENV_KEYS: readonly ["TREESEED_MARKET_URL", "TREESEED_MANAGER_ID", "TREESEED_CAPACITY_PROVIDER_API_KEY", "TREESEED_PROVIDER_HOST_DATA_DIR", "TREESEED_PROVIDER_DATA_DIR", "TREESEED_PROVIDER_API_PORT", "TREESEED_PROVIDER_HOST_API_PORT", "TREESEED_PROVIDER_ENVIRONMENT", "TREESEED_PROVIDER_CAPABILITIES_FILE", "TREESEED_PROVIDER_BUDGET_FILE", "TREESEED_PROVIDER_MAX_CONCURRENT_WORKDAYS", "TREESEED_PROVIDER_MAX_CONCURRENT_RUNNERS", "TREESEED_PROVIDER_DAILY_CREDIT_BUDGET", "TREESEED_PROVIDER_MONTHLY_CREDIT_BUDGET", "TREESEED_PROVIDER_STARTUP_MODE", "TREESEED_CODEX_AUTH_FILE", "TREESEED_CODEX_AUTH_JSON_B64", "TREESEED_CODEX_AUTH_OVERWRITE"];
|
|
16
17
|
export type CapacityProviderScope = (typeof CAPACITY_PROVIDER_SCOPES)[number];
|
|
17
18
|
export type CapacityProviderEnvironmentName = 'local' | 'staging' | 'prod' | 'production' | string;
|
|
18
19
|
export type CapacityProviderLaunchMode = 'self_hosted' | 'managed_market_host' | 'connected_host';
|
|
@@ -154,6 +155,7 @@ export interface CapacityProviderPortfolioProject {
|
|
|
154
155
|
submodulePath?: string | null;
|
|
155
156
|
webUrl?: string | null;
|
|
156
157
|
};
|
|
158
|
+
repositoryTopology?: ProjectRepositoryTopology;
|
|
157
159
|
agentSpecs: {
|
|
158
160
|
root: string;
|
|
159
161
|
testsRoot: string;
|
|
@@ -32,7 +32,7 @@ const CAPACITY_PROVIDER_SCOPES = [
|
|
|
32
32
|
];
|
|
33
33
|
const CAPACITY_PROVIDER_ENV_KEYS = [
|
|
34
34
|
"TREESEED_MARKET_URL",
|
|
35
|
-
"
|
|
35
|
+
"TREESEED_MANAGER_ID",
|
|
36
36
|
"TREESEED_CAPACITY_PROVIDER_API_KEY",
|
|
37
37
|
"TREESEED_PROVIDER_HOST_DATA_DIR",
|
|
38
38
|
"TREESEED_PROVIDER_DATA_DIR",
|
|
@@ -158,6 +158,26 @@ function assertCapacityProviderPortfolioManifest(value) {
|
|
|
158
158
|
requireString(project, "slug", `Capacity provider portfolio project ${index}`);
|
|
159
159
|
requireString(project, "name", `Capacity provider portfolio project ${index}`);
|
|
160
160
|
if (!isRecord(project.repository)) throw new Error(`Capacity provider portfolio project ${index} is missing repository.`);
|
|
161
|
+
if (project.repositoryTopology !== void 0) {
|
|
162
|
+
if (!isRecord(project.repositoryTopology)) {
|
|
163
|
+
throw new Error(`Capacity provider portfolio project ${index} repositoryTopology must be an object.`);
|
|
164
|
+
}
|
|
165
|
+
if (!isRecord(project.repositoryTopology.contentRepository)) {
|
|
166
|
+
throw new Error(`Capacity provider portfolio project ${index} repositoryTopology is missing contentRepository.`);
|
|
167
|
+
}
|
|
168
|
+
if (project.repositoryTopology.contentRepository.accessMode !== "treedx") {
|
|
169
|
+
throw new Error(`Capacity provider portfolio project ${index} contentRepository must use treedx access.`);
|
|
170
|
+
}
|
|
171
|
+
if (!isRecord(project.repositoryTopology.siteRepository)) {
|
|
172
|
+
throw new Error(`Capacity provider portfolio project ${index} repositoryTopology is missing siteRepository.`);
|
|
173
|
+
}
|
|
174
|
+
if (project.repositoryTopology.siteRepository.accessMode !== "filesystem") {
|
|
175
|
+
throw new Error(`Capacity provider portfolio project ${index} siteRepository must use filesystem access.`);
|
|
176
|
+
}
|
|
177
|
+
if (project.repositoryTopology.projectRepository !== void 0 && project.repositoryTopology.projectRepository !== null && (!isRecord(project.repositoryTopology.projectRepository) || project.repositoryTopology.projectRepository.accessMode !== "filesystem")) {
|
|
178
|
+
throw new Error(`Capacity provider portfolio project ${index} projectRepository must use filesystem access.`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
161
181
|
if (!isRecord(project.agentSpecs)) throw new Error(`Capacity provider portfolio project ${index} is missing agentSpecs.`);
|
|
162
182
|
if (!isRecord(project.workPolicy)) throw new Error(`Capacity provider portfolio project ${index} is missing workPolicy.`);
|
|
163
183
|
}
|
|
@@ -165,13 +185,13 @@ function assertCapacityProviderPortfolioManifest(value) {
|
|
|
165
185
|
function resolveCapacityProviderEnvironment(input) {
|
|
166
186
|
const env = {
|
|
167
187
|
TREESEED_MARKET_URL: normalizeBaseUrl(input.marketUrl),
|
|
168
|
-
|
|
188
|
+
TREESEED_MANAGER_ID: input.marketId.trim(),
|
|
169
189
|
TREESEED_CAPACITY_PROVIDER_API_KEY: input.apiKey.trim(),
|
|
170
190
|
TREESEED_PROVIDER_DATA_DIR: input.providerDataDir ?? "/data",
|
|
171
191
|
TREESEED_PROVIDER_API_PORT: stringValue(input.providerApiPort, "3100"),
|
|
172
192
|
TREESEED_PROVIDER_ENVIRONMENT: input.providerEnvironment ?? "local"
|
|
173
193
|
};
|
|
174
|
-
if (!env.
|
|
194
|
+
if (!env.TREESEED_MANAGER_ID) throw new Error("Capacity provider Market ID is required.");
|
|
175
195
|
if (!env.TREESEED_CAPACITY_PROVIDER_API_KEY) throw new Error("Capacity provider API key is required.");
|
|
176
196
|
if (input.providerHostDataDir) env.TREESEED_PROVIDER_HOST_DATA_DIR = input.providerHostDataDir;
|
|
177
197
|
if (input.capabilitiesFile) env.TREESEED_PROVIDER_CAPABILITIES_FILE = input.capabilitiesFile;
|
|
@@ -230,7 +250,7 @@ function resolveCapacityProviderLaunchEnvironment(input = {}) {
|
|
|
230
250
|
}
|
|
231
251
|
const required = [
|
|
232
252
|
"TREESEED_MARKET_URL",
|
|
233
|
-
"
|
|
253
|
+
"TREESEED_MANAGER_ID",
|
|
234
254
|
...diagnostic ? [] : ["TREESEED_CAPACITY_PROVIDER_API_KEY"],
|
|
235
255
|
"TREESEED_PROVIDER_HOST_DATA_DIR"
|
|
236
256
|
];
|
|
@@ -262,7 +282,7 @@ function persistCapacityProviderConnectionToTreeseedConfig(input) {
|
|
|
262
282
|
const entryById = new Map(registryEntries.map((entry) => [entry.id, entry]));
|
|
263
283
|
const keys = [
|
|
264
284
|
"TREESEED_MARKET_URL",
|
|
265
|
-
"
|
|
285
|
+
"TREESEED_MANAGER_ID",
|
|
266
286
|
"TREESEED_CAPACITY_PROVIDER_API_KEY",
|
|
267
287
|
"TREESEED_PROVIDER_HOST_DATA_DIR",
|
|
268
288
|
"TREESEED_PROVIDER_ENVIRONMENT"
|
package/dist/control-plane.d.ts
CHANGED
|
@@ -91,6 +91,7 @@ export interface ControlPlaneReporterOptions {
|
|
|
91
91
|
baseUrl?: string | null;
|
|
92
92
|
runnerToken?: string | null;
|
|
93
93
|
fetchImpl?: typeof fetch;
|
|
94
|
+
requestTimeoutMs?: number | null;
|
|
94
95
|
}
|
|
95
96
|
export interface ResolveControlPlaneReporterOptions extends ControlPlaneReporterOptions {
|
|
96
97
|
hostingKind?: TreeseedHostingKind | null;
|
package/dist/control-plane.js
CHANGED
|
@@ -21,8 +21,8 @@ function resolveReporterKind(options) {
|
|
|
21
21
|
if (hostingKind === "self_hosted_project" && registration === "optional") {
|
|
22
22
|
return "market_http";
|
|
23
23
|
}
|
|
24
|
-
if (hostingKind === "
|
|
25
|
-
return normalizeUrl(options.baseUrl ?? process.env.
|
|
24
|
+
if (hostingKind === "treeseed_control_plane") {
|
|
25
|
+
return normalizeUrl(options.baseUrl ?? process.env.TREESEED_API_BASE_URL ?? options.deployConfig?.hosting?.marketBaseUrl) ? "self_http" : "noop";
|
|
26
26
|
}
|
|
27
27
|
return "noop";
|
|
28
28
|
}
|
|
@@ -60,13 +60,14 @@ class NoopControlPlaneReporter {
|
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
class HttpControlPlaneReporter {
|
|
63
|
-
constructor(kind, projectId, baseUrl, runnerToken, fetchImpl = fetch) {
|
|
63
|
+
constructor(kind, projectId, baseUrl, runnerToken, fetchImpl = fetch, requestTimeoutMs) {
|
|
64
64
|
this.kind = kind;
|
|
65
65
|
this.projectId = projectId;
|
|
66
66
|
this.baseUrl = baseUrl;
|
|
67
67
|
this.runnerToken = runnerToken;
|
|
68
68
|
this.fetchImpl = fetchImpl;
|
|
69
69
|
this.enabled = Boolean(this.projectId && this.baseUrl && this.runnerToken);
|
|
70
|
+
this.requestTimeoutMs = normalizeRequestTimeoutMs(requestTimeoutMs);
|
|
70
71
|
}
|
|
71
72
|
kind;
|
|
72
73
|
projectId;
|
|
@@ -74,18 +75,32 @@ class HttpControlPlaneReporter {
|
|
|
74
75
|
runnerToken;
|
|
75
76
|
fetchImpl;
|
|
76
77
|
enabled;
|
|
78
|
+
requestTimeoutMs;
|
|
77
79
|
async request(method, pathname, body) {
|
|
78
80
|
if (!this.enabled || !this.baseUrl || !this.runnerToken) {
|
|
79
81
|
return null;
|
|
80
82
|
}
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
83
|
+
const controller = new AbortController();
|
|
84
|
+
const timeout = setTimeout(() => controller.abort(), this.requestTimeoutMs);
|
|
85
|
+
let response;
|
|
86
|
+
try {
|
|
87
|
+
response = await this.fetchImpl(new URL(pathname, this.baseUrl), {
|
|
88
|
+
method,
|
|
89
|
+
headers: {
|
|
90
|
+
authorization: `Bearer ${this.runnerToken}`,
|
|
91
|
+
"content-type": "application/json"
|
|
92
|
+
},
|
|
93
|
+
body: body === void 0 ? void 0 : JSON.stringify(body),
|
|
94
|
+
signal: controller.signal
|
|
95
|
+
});
|
|
96
|
+
} catch (error) {
|
|
97
|
+
if (controller.signal.aborted) {
|
|
98
|
+
throw new Error(`Control-plane request timed out for ${pathname} after ${this.requestTimeoutMs}ms.`);
|
|
99
|
+
}
|
|
100
|
+
throw error;
|
|
101
|
+
} finally {
|
|
102
|
+
clearTimeout(timeout);
|
|
103
|
+
}
|
|
89
104
|
if (!response.ok) {
|
|
90
105
|
throw new Error(`Control-plane request failed for ${pathname}: ${response.status} ${response.statusText}`);
|
|
91
106
|
}
|
|
@@ -154,6 +169,16 @@ class HttpControlPlaneReporter {
|
|
|
154
169
|
return this.request("POST", `/v1/projects/${this.projectId}/runner/approval-requests`, input);
|
|
155
170
|
}
|
|
156
171
|
}
|
|
172
|
+
function normalizeRequestTimeoutMs(value) {
|
|
173
|
+
if (Number.isFinite(value) && Number(value) > 0) {
|
|
174
|
+
return Number(value);
|
|
175
|
+
}
|
|
176
|
+
const fromEnv = Number.parseInt(String(process.env.TREESEED_CONTROL_PLANE_REQUEST_TIMEOUT_MS ?? ""), 10);
|
|
177
|
+
if (Number.isFinite(fromEnv) && fromEnv > 0) {
|
|
178
|
+
return fromEnv;
|
|
179
|
+
}
|
|
180
|
+
return 15e3;
|
|
181
|
+
}
|
|
157
182
|
function createControlPlaneReporter(options = {}) {
|
|
158
183
|
const kind = resolveReporterKind(options);
|
|
159
184
|
if (kind === "noop") {
|
|
@@ -163,13 +188,13 @@ function createControlPlaneReporter(options = {}) {
|
|
|
163
188
|
options.projectId ?? process.env.TREESEED_PROJECT_ID ?? options.deployConfig?.hosting?.projectId ?? ""
|
|
164
189
|
).trim() || null;
|
|
165
190
|
const baseUrl = normalizeUrl(
|
|
166
|
-
options.baseUrl ?? process.env.
|
|
191
|
+
options.baseUrl ?? process.env.TREESEED_API_BASE_URL ?? options.deployConfig?.hosting?.marketBaseUrl ?? null
|
|
167
192
|
);
|
|
168
193
|
const runnerToken = String(options.runnerToken ?? process.env.TREESEED_PROJECT_RUNNER_TOKEN ?? "").trim() || null;
|
|
169
194
|
if (!projectId || !baseUrl || !runnerToken) {
|
|
170
195
|
return new NoopControlPlaneReporter();
|
|
171
196
|
}
|
|
172
|
-
return new HttpControlPlaneReporter(kind, projectId, baseUrl, runnerToken, options.fetchImpl);
|
|
197
|
+
return new HttpControlPlaneReporter(kind, projectId, baseUrl, runnerToken, options.fetchImpl, options.requestTimeoutMs);
|
|
173
198
|
}
|
|
174
199
|
export {
|
|
175
200
|
createControlPlaneReporter
|