@treeseed/sdk 0.4.8 → 0.4.9

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 CHANGED
@@ -168,7 +168,7 @@ const scoped = sdk.scopeForAgent({
168
168
  The package also exports:
169
169
 
170
170
  - workflow helpers such as `TreeseedWorkflowSdk`
171
- - gateway and queue clients such as `TreeseedGatewayClient` and `CloudflareQueuePullClient`
171
+ - remote and queue clients such as `RemoteTreeseedClient`, `CloudflareQueuePullClient`, and `CloudflareQueuePushClient`
172
172
  - model registry, field, and filter utilities
173
173
  - plugin/runtime types and helpers
174
174
 
@@ -0,0 +1,4 @@
1
+ import type { SdkDispatchCapability, SdkDispatchNamespace } from './sdk-types.ts';
2
+ export declare function listSdkDispatchCapabilities(): SdkDispatchCapability[];
3
+ export declare function listWorkflowDispatchCapabilities(): SdkDispatchCapability[];
4
+ export declare function findDispatchCapability(namespace: SdkDispatchNamespace, operation: string): SdkDispatchCapability | null;
@@ -0,0 +1,180 @@
1
+ import {
2
+ findTreeseedOperation
3
+ } from "./operations-registry.js";
4
+ function capability(namespace, operation, options) {
5
+ return {
6
+ namespace,
7
+ operation,
8
+ executionClass: options.executionClass,
9
+ allowedTargets: options.allowedTargets,
10
+ defaultTarget: options.defaultTarget,
11
+ defaultDispatchMode: options.defaultDispatchMode ?? "auto",
12
+ summary: options.summary
13
+ };
14
+ }
15
+ const INLINE_PROJECT_API_SDK_OPERATIONS = [
16
+ "get",
17
+ "read",
18
+ "search",
19
+ "follow",
20
+ "pick",
21
+ "create",
22
+ "update",
23
+ "claimMessage",
24
+ "ackMessage",
25
+ "createMessage",
26
+ "recordRun",
27
+ "getCursor",
28
+ "upsertCursor",
29
+ "releaseLease",
30
+ "releaseAllLeases",
31
+ "startWorkDay",
32
+ "closeWorkDay",
33
+ "createTask",
34
+ "claimTask",
35
+ "recordTaskProgress",
36
+ "completeTask",
37
+ "failTask",
38
+ "appendTaskEvent",
39
+ "searchTasks",
40
+ "createReport",
41
+ "getManagerContext",
42
+ "listAgentSpecs",
43
+ "listRawAgentSpecs",
44
+ "searchFiles",
45
+ "searchSections",
46
+ "searchEntities",
47
+ "getGraphNode",
48
+ "getNeighbors",
49
+ "followReferences",
50
+ "getBacklinks",
51
+ "getRelated",
52
+ "getSubgraph",
53
+ "resolveSeeds",
54
+ "parseGraphDsl",
55
+ "resolveReference",
56
+ "explainReferenceChain"
57
+ ];
58
+ const REMOTE_JOB_SDK_OPERATIONS = [
59
+ "refreshGraph",
60
+ "queryGraph",
61
+ "buildContextPack"
62
+ ];
63
+ const LOCAL_ONLY_WORKFLOW_OPERATIONS = /* @__PURE__ */ new Set([
64
+ "init",
65
+ "config",
66
+ "auth:login",
67
+ "auth:logout",
68
+ "dev",
69
+ "dev:watch",
70
+ "mailpit:up",
71
+ "mailpit:down",
72
+ "mailpit:logs",
73
+ "d1:migrate:local",
74
+ "cleanup-markdown",
75
+ "cleanup-markdown:check",
76
+ "astro",
77
+ "sync-devvars",
78
+ "starlight:patch",
79
+ "build",
80
+ "check",
81
+ "preview",
82
+ "lint",
83
+ "test",
84
+ "test:unit"
85
+ ]);
86
+ const REMOTE_JOB_WORKFLOW_OPERATIONS = /* @__PURE__ */ new Set([
87
+ "save",
88
+ "close",
89
+ "stage",
90
+ "release",
91
+ "rollback",
92
+ "destroy",
93
+ "sync",
94
+ "export",
95
+ "test:e2e",
96
+ "test:e2e:local",
97
+ "test:e2e:staging",
98
+ "test:e2e:full",
99
+ "test:fast",
100
+ "verify",
101
+ "publish:changed"
102
+ ]);
103
+ const INLINE_WORKFLOW_OPERATIONS = /* @__PURE__ */ new Set([
104
+ "status",
105
+ "tasks",
106
+ "doctor",
107
+ "template",
108
+ "auth:whoami"
109
+ ]);
110
+ const SDK_CAPABILITIES = [
111
+ ...INLINE_PROJECT_API_SDK_OPERATIONS.map((operation) => capability("sdk", operation, {
112
+ executionClass: "remote_inline",
113
+ allowedTargets: ["local", "project_api"],
114
+ defaultTarget: "project_api"
115
+ })),
116
+ ...REMOTE_JOB_SDK_OPERATIONS.map((operation) => capability("sdk", operation, {
117
+ executionClass: "remote_job",
118
+ allowedTargets: ["local", "project_api", "project_runner"],
119
+ defaultTarget: "project_runner",
120
+ defaultDispatchMode: "prefer_remote"
121
+ }))
122
+ ];
123
+ const SDK_CAPABILITY_INDEX = new Map(
124
+ SDK_CAPABILITIES.map((entry) => [`${entry.namespace}:${entry.operation}`, entry])
125
+ );
126
+ function workflowCapability(operation) {
127
+ const resolved = findTreeseedOperation(operation);
128
+ if (!resolved) {
129
+ return null;
130
+ }
131
+ if (LOCAL_ONLY_WORKFLOW_OPERATIONS.has(resolved.name)) {
132
+ return capability("workflow", resolved.name, {
133
+ executionClass: "local_only",
134
+ allowedTargets: ["local"],
135
+ defaultTarget: "local"
136
+ });
137
+ }
138
+ if (REMOTE_JOB_WORKFLOW_OPERATIONS.has(resolved.name)) {
139
+ return capability("workflow", resolved.name, {
140
+ executionClass: "remote_job",
141
+ allowedTargets: ["local", "project_runner"],
142
+ defaultTarget: "project_runner",
143
+ defaultDispatchMode: "prefer_remote"
144
+ });
145
+ }
146
+ if (INLINE_WORKFLOW_OPERATIONS.has(resolved.name)) {
147
+ return capability("workflow", resolved.name, {
148
+ executionClass: "remote_inline",
149
+ allowedTargets: resolved.name === "template" ? ["local", "market_catalog", "project_api"] : ["local", "project_api"],
150
+ defaultTarget: resolved.name === "template" ? "market_catalog" : "project_api"
151
+ });
152
+ }
153
+ return capability("workflow", resolved.name, {
154
+ executionClass: "remote_job",
155
+ allowedTargets: ["local", "project_runner"],
156
+ defaultTarget: "project_runner",
157
+ defaultDispatchMode: "prefer_remote"
158
+ });
159
+ }
160
+ function listSdkDispatchCapabilities() {
161
+ return [...SDK_CAPABILITIES];
162
+ }
163
+ function listWorkflowDispatchCapabilities() {
164
+ return [
165
+ ...LOCAL_ONLY_WORKFLOW_OPERATIONS,
166
+ ...REMOTE_JOB_WORKFLOW_OPERATIONS,
167
+ ...INLINE_WORKFLOW_OPERATIONS
168
+ ].map((operation) => workflowCapability(operation)).filter((entry) => Boolean(entry));
169
+ }
170
+ function findDispatchCapability(namespace, operation) {
171
+ if (namespace === "sdk") {
172
+ return SDK_CAPABILITY_INDEX.get(`sdk:${operation}`) ?? null;
173
+ }
174
+ return workflowCapability(operation);
175
+ }
176
+ export {
177
+ findDispatchCapability,
178
+ listSdkDispatchCapabilities,
179
+ listWorkflowDispatchCapabilities
180
+ };
package/dist/index.d.ts CHANGED
@@ -4,16 +4,18 @@ export { parseGraphDsl } from './graph/dsl.ts';
4
4
  export { createDefaultGraphRankingProvider, DEFAULT_GRAPH_RANKING_PROVIDER } from './graph/ranking.ts';
5
5
  export { BUILTIN_MODEL_REGISTRY, MODEL_REGISTRY, buildBuiltinModelRegistry, buildModelRegistry, buildScopedModelRegistry, mergeModelRegistries, resolveModelDefinition, } from './model-registry.ts';
6
6
  export { normalizeAgentCliOptions, buildCopilotAllowToolArgs } from './cli-tools.ts';
7
+ export { findDispatchCapability, listSdkDispatchCapabilities, listWorkflowDispatchCapabilities, } from './dispatch.ts';
8
+ export { executeSdkOperation, findSdkOperation, listSdkOperationNames, } from './sdk-dispatch.ts';
7
9
  export { resolveSdkRecordVersion } from './sdk-version.ts';
8
10
  export { normalizeAliasedRecord, preprocessAliasedRecord, resolveAliasedField, } from './field-aliases.ts';
9
11
  export { canonicalizeFrontmatter, normalizeFilterFields, normalizeMutationData, normalizeRecordToCanonicalShape, normalizeSortFields, readCanonicalFieldValue, resolveModelField, validateModelFieldAliases, } from './sdk-fields.ts';
10
12
  export { RemoteTemplateCatalogClient, parseTemplateCatalogResponse } from './template-catalog.ts';
11
- export { TREESEED_REMOTE_CONTRACT_HEADER, TREESEED_REMOTE_CONTRACT_VERSION, CloudflareQueuePullClient, RemoteTreeseedClient, RemoteTreeseedAuthClient, RemoteTreeseedSdkClient, RemoteTreeseedOperationsClient, TreeseedGatewayClient, } from './remote.ts';
13
+ export { TREESEED_REMOTE_CONTRACT_HEADER, TREESEED_REMOTE_CONTRACT_VERSION, CloudflareQueuePullClient, CloudflareQueuePushClient, RemoteTreeseedClient, RemoteTreeseedAuthClient, RemoteTreeseedDispatchClient, RemoteTreeseedJobsClient, RemoteTreeseedRunnerClient, RemoteTreeseedSdkClient, RemoteTreeseedOperationsClient, } from './remote.ts';
12
14
  export { TRESEED_OPERATION_SPECS, findTreeseedOperation, listTreeseedOperationNames, } from './operations-registry.ts';
13
15
  export { TreeseedOperationsSdk } from './operations/runtime.ts';
14
16
  export { TreeseedWorkflowSdk } from './workflow.ts';
15
17
  export { getTreeseedVerifyDriverStatus, runTreeseedVerifyDriver } from './verification.ts';
16
- export type { SdkContentEntry, SdkCursorEntity, SdkFilterCondition, SdkFollowRequest, SdkGraphEdge, SdkGraphEdgeType, SdkGraphDslRelation, SdkGraphDslParseResult, SdkGraphModelConfig, SdkGraphNode, SdkGraphNodeType, SdkGraphPathExplanation, SdkGraphQueryStage, SdkGraphQueryView, SdkGraphQueryOptions, SdkGraphQueryRequest, SdkGraphQueryResult, SdkGraphRankingBuildInput, SdkGraphRankingDiagnostics, SdkGraphRankingIndex, SdkGraphRankingNodeResult, SdkGraphRankingProvider, SdkGraphRankingQueryRequest, SdkGraphRankingQueryResult, SdkGraphRankingSearchRequest, SdkGraphRefreshPayload, SdkGraphRefreshRequest, SdkGraphSearchOptions, SdkGraphSearchResult, SdkGraphSeed, SdkGraphSeedResolution, SdkGraphTraversalResult, SdkGraphWhereFilter, SdkContextPack, SdkContextPackRequest, SdkGetRequest, SdkJsonEnvelope, SdkLeaseEntity, SdkManagerContextPayload, SdkMessageEntity, SdkModelFieldBinding, SdkModelDefinition, SdkModelRegistry, SdkModelName, SdkMutationRequest, SdkOperation, SdkPickRequest, SdkPickResult, SdkQueueMessageEnvelope, SdkRunEntity, SdkSearchRequest, SdkTaskEntity, SdkTaskEventEntity, SdkTaskOutputEntity, SdkWorkDayEntity, SdkGraphRunEntity, SdkReportEntity, SdkSubscriptionEntity, SdkTemplateCatalogEntry, SdkTemplateCatalogPublisher, SdkTemplateCatalogResponse, SdkTemplateCatalogSource, SdkUpdateRequest, } from './sdk-types.ts';
18
+ export type { SdkContentEntry, SdkDispatchCapability, SdkDispatchConfig, SdkDispatchCredentialSource, SdkDispatchExecutionClass, SdkDispatchNamespace, SdkDispatchPolicy, SdkDispatchRequest, SdkDispatchResult, SdkDispatchTarget, SdkCursorEntity, SdkFilterCondition, SdkFollowRequest, SdkGraphEdge, SdkGraphEdgeType, SdkGraphDslRelation, SdkGraphDslParseResult, SdkGraphModelConfig, SdkGraphNode, SdkGraphNodeType, SdkGraphPathExplanation, SdkGraphQueryStage, SdkGraphQueryView, SdkGraphQueryOptions, SdkGraphQueryRequest, SdkGraphQueryResult, SdkGraphRankingBuildInput, SdkGraphRankingDiagnostics, SdkGraphRankingIndex, SdkGraphRankingNodeResult, SdkGraphRankingProvider, SdkGraphRankingQueryRequest, SdkGraphRankingQueryResult, SdkGraphRankingSearchRequest, SdkGraphRefreshPayload, SdkGraphRefreshRequest, SdkGraphSearchOptions, SdkGraphSearchResult, SdkGraphSeed, SdkGraphSeedResolution, SdkGraphTraversalResult, SdkGraphWhereFilter, SdkContextPack, SdkContextPackRequest, SdkGetRequest, SdkJsonEnvelope, SdkLeaseEntity, SdkManagerContextPayload, SdkMessageEntity, SdkModelFieldBinding, SdkModelDefinition, SdkModelRegistry, SdkModelName, SdkMutationRequest, SdkOperation, SdkPickRequest, SdkPickResult, SdkQueueMessageEnvelope, SdkRunEntity, SdkSearchRequest, SdkTaskEntity, SdkTaskEventEntity, SdkTaskOutputEntity, SdkWorkDayEntity, SdkGraphRunEntity, SdkReportEntity, SdkSubscriptionEntity, SdkTemplateCatalogEntry, SdkTemplateCatalogPublisher, SdkTemplateCatalogResponse, SdkTemplateCatalogSource, SdkUpdateRequest, ProjectCapabilityGrant, ProjectConnection, ProjectConnectionMode, ProjectExecutionOwner, ProjectRunnerRegistrationState, RemoteJob, RemoteJobEvent, RemoteJobStatus, } from './sdk-types.ts';
17
19
  export type { TreeseedFieldAliasBinding, TreeseedFieldAliasRegistry, } from './field-aliases.ts';
18
20
  export type * from './operations-types.ts';
19
21
  export type * from './workflow.ts';
package/dist/index.js CHANGED
@@ -12,6 +12,16 @@ import {
12
12
  resolveModelDefinition
13
13
  } from "./model-registry.js";
14
14
  import { normalizeAgentCliOptions, buildCopilotAllowToolArgs } from "./cli-tools.js";
15
+ import {
16
+ findDispatchCapability,
17
+ listSdkDispatchCapabilities,
18
+ listWorkflowDispatchCapabilities
19
+ } from "./dispatch.js";
20
+ import {
21
+ executeSdkOperation,
22
+ findSdkOperation,
23
+ listSdkOperationNames
24
+ } from "./sdk-dispatch.js";
15
25
  import { resolveSdkRecordVersion } from "./sdk-version.js";
16
26
  import {
17
27
  normalizeAliasedRecord,
@@ -33,11 +43,14 @@ import {
33
43
  TREESEED_REMOTE_CONTRACT_HEADER,
34
44
  TREESEED_REMOTE_CONTRACT_VERSION,
35
45
  CloudflareQueuePullClient,
46
+ CloudflareQueuePushClient,
36
47
  RemoteTreeseedClient,
37
48
  RemoteTreeseedAuthClient,
49
+ RemoteTreeseedDispatchClient,
50
+ RemoteTreeseedJobsClient,
51
+ RemoteTreeseedRunnerClient,
38
52
  RemoteTreeseedSdkClient,
39
- RemoteTreeseedOperationsClient,
40
- TreeseedGatewayClient
53
+ RemoteTreeseedOperationsClient
41
54
  } from "./remote.js";
42
55
  import {
43
56
  TRESEED_OPERATION_SPECS,
@@ -53,19 +66,22 @@ export {
53
66
  BUILTIN_MODEL_REGISTRY,
54
67
  CloudflareHttpD1Database,
55
68
  CloudflareQueuePullClient,
69
+ CloudflareQueuePushClient,
56
70
  ContentGraphRuntime,
57
71
  DEFAULT_GRAPH_RANKING_PROVIDER,
58
72
  MODEL_REGISTRY,
59
73
  RemoteTemplateCatalogClient,
60
74
  RemoteTreeseedAuthClient,
61
75
  RemoteTreeseedClient,
76
+ RemoteTreeseedDispatchClient,
77
+ RemoteTreeseedJobsClient,
62
78
  RemoteTreeseedOperationsClient,
79
+ RemoteTreeseedRunnerClient,
63
80
  RemoteTreeseedSdkClient,
64
81
  ScopedAgentSdk,
65
82
  TREESEED_REMOTE_CONTRACT_HEADER,
66
83
  TREESEED_REMOTE_CONTRACT_VERSION,
67
84
  TRESEED_OPERATION_SPECS,
68
- TreeseedGatewayClient,
69
85
  TreeseedOperationsSdk,
70
86
  TreeseedWorkflowSdk,
71
87
  buildBuiltinModelRegistry,
@@ -74,9 +90,15 @@ export {
74
90
  buildScopedModelRegistry,
75
91
  canonicalizeFrontmatter,
76
92
  createDefaultGraphRankingProvider,
93
+ executeSdkOperation,
94
+ findDispatchCapability,
95
+ findSdkOperation,
77
96
  findTreeseedOperation,
78
97
  getTreeseedVerifyDriverStatus,
98
+ listSdkDispatchCapabilities,
99
+ listSdkOperationNames,
79
100
  listTreeseedOperationNames,
101
+ listWorkflowDispatchCapabilities,
80
102
  mergeModelRegistries,
81
103
  normalizeAgentCliOptions,
82
104
  normalizeAliasedRecord,
@@ -1181,14 +1181,14 @@ function syncTreeseedRailwayEnvironment({ tenantRoot, scope = "prod", dryRun = f
1181
1181
  const values = resolveTreeseedMachineEnvironmentValues(tenantRoot, scope);
1182
1182
  const registry = collectTreeseedEnvironmentContext(tenantRoot);
1183
1183
  const railwaySecretNames = registry.entries.filter((entry) => entry.scopes.includes(scope) && entry.targets.includes("railway-secret")).map((entry) => entry.id).filter((key) => typeof values[key] === "string" && values[key].length > 0);
1184
- const services = ["api", "agents", "manager", "worker", "workdayStart", "workdayReport"].map((serviceKey) => {
1184
+ const services = ["api", "agents", "manager", "worker", "runner", "workdayStart", "workdayReport"].map((serviceKey) => {
1185
1185
  const service = deployConfig.services?.[serviceKey];
1186
1186
  if (!service || service.enabled === false || (service.provider ?? "railway") !== "railway") {
1187
1187
  return null;
1188
1188
  }
1189
1189
  const environment = service.environments?.[scope];
1190
1190
  const fallbackServiceName = serviceKey === "api" ? config.settings.services.railway.apiServiceName : serviceKey === "agents" ? config.settings.services.railway.agentsServiceName : "";
1191
- const defaultRootDir = ["api", "manager", "worker", "workdayStart", "workdayReport"].includes(serviceKey) ? "." : "packages/core";
1191
+ const defaultRootDir = ["api", "manager", "worker", "runner", "workdayStart", "workdayReport"].includes(serviceKey) ? "." : "packages/core";
1192
1192
  return {
1193
1193
  service: serviceKey,
1194
1194
  projectName: service.railway?.projectName ?? config.settings.services.railway.projectName,
@@ -23,7 +23,6 @@ export declare function ensureGeneratedWranglerConfig(tenantRoot: any, options?:
23
23
  cloudflare: {
24
24
  accountId: string;
25
25
  workerName: string | undefined;
26
- gatewayWorkerName: string | undefined;
27
26
  queueName: string | undefined;
28
27
  dlqName: string | undefined;
29
28
  d1Binding: string | undefined;
@@ -126,7 +125,6 @@ export declare function validateDeployPrerequisites(tenantRoot: any, { requireRe
126
125
  cloudflare: {
127
126
  accountId: string;
128
127
  workerName: string | undefined;
129
- gatewayWorkerName: string | undefined;
130
128
  queueName: string | undefined;
131
129
  dlqName: string | undefined;
132
130
  d1Binding: string | undefined;
@@ -210,7 +208,6 @@ export declare function validateDestroyPrerequisites(tenantRoot: any, { requireR
210
208
  cloudflare: {
211
209
  accountId: string;
212
210
  workerName: string | undefined;
213
- gatewayWorkerName: string | undefined;
214
211
  queueName: string | undefined;
215
212
  dlqName: string | undefined;
216
213
  d1Binding: string | undefined;
@@ -10,7 +10,7 @@ const DEFAULT_COMPATIBILITY_FLAGS = ["nodejs_compat"];
10
10
  const GENERATED_ROOT = ".treeseed/generated";
11
11
  const STATE_ROOT = ".treeseed/state";
12
12
  const PERSISTENT_SCOPES = /* @__PURE__ */ new Set(["local", "staging", "prod"]);
13
- const MANAGED_SERVICE_KEYS = ["api", "agents", "gateway", "manager", "worker", "workdayStart", "workdayReport"];
13
+ const MANAGED_SERVICE_KEYS = ["api", "agents", "manager", "worker", "runner", "workdayStart", "workdayReport"];
14
14
  const TRESEED_ENVELOPE_SCHEMA_GENERATION = "runtime-envelopes-v1";
15
15
  const TRESEED_MIGRATION_WAVE_ID = "0005_runtime_envelopes";
16
16
  const TRESEED_SUPPORTED_PAYLOAD_RANGE = { min: 1, max: 1 };
@@ -5,7 +5,7 @@ import { loadCliDeployConfig } from "./runtime-tools.js";
5
5
  function normalizeScope(scope) {
6
6
  return scope === "prod" ? "prod" : scope === "staging" ? "staging" : "local";
7
7
  }
8
- const RAILWAY_SERVICE_KEYS = ["api", "agents", "manager", "worker", "workdayStart", "workdayReport"];
8
+ const RAILWAY_SERVICE_KEYS = ["api", "agents", "manager", "worker", "runner", "workdayStart", "workdayReport"];
9
9
  function runRailway(args, { cwd, capture = false, allowFailure = false } = {}) {
10
10
  const result = spawnSync("railway", args, {
11
11
  cwd,
@@ -26,7 +26,7 @@ function configuredRailwayServices(tenantRoot, scope) {
26
26
  if (!service || service.enabled === false || (service.provider ?? "railway") !== "railway") {
27
27
  return null;
28
28
  }
29
- const defaultRootDir = ["api", "manager", "worker", "workdayStart", "workdayReport"].includes(serviceKey) ? "." : "packages/core";
29
+ const defaultRootDir = ["api", "manager", "worker", "runner", "workdayStart", "workdayReport"].includes(serviceKey) ? "." : "packages/core";
30
30
  const serviceRoot = resolve(tenantRoot, service.railway?.rootDir ?? service.rootDir ?? defaultRootDir);
31
31
  const railwayEnvironment = service.environments?.[normalizedScope]?.railwayEnvironment ?? normalizedScope;
32
32
  const publicBaseUrl = service.environments?.[normalizedScope]?.baseUrl ?? service.publicBaseUrl ?? null;
@@ -38,7 +38,6 @@ export declare function loadCliDeployConfig(tenantRoot: any): {
38
38
  cloudflare: {
39
39
  accountId: string;
40
40
  workerName: string | undefined;
41
- gatewayWorkerName: string | undefined;
42
41
  queueName: string | undefined;
43
42
  dlqName: string | undefined;
44
43
  d1Binding: string | undefined;
@@ -50,7 +50,7 @@ const TREESEED_DEFAULT_PROVIDER_SELECTIONS = {
50
50
  },
51
51
  site: "default"
52
52
  };
53
- const TRESEED_MANAGED_SERVICE_KEYS = ["api", "agents", "gateway", "manager", "worker", "workdayStart", "workdayReport"];
53
+ const TRESEED_MANAGED_SERVICE_KEYS = ["api", "agents", "manager", "worker", "runner", "workdayStart", "workdayReport"];
54
54
  const TRESEED_WORKSPACE_PACKAGE_DIRS = ["sdk", "core", "cli"];
55
55
  const CLOUDFLARE_ACCOUNT_ID_PLACEHOLDER = "replace-with-cloudflare-account-id";
56
56
  function parseServiceEnvironmentConfig(value) {
@@ -301,7 +301,6 @@ function parseFallbackDeployConfig(configPath) {
301
301
  cloudflare: {
302
302
  accountId: optionalCloudflareAccountId(cloudflare.accountId) ?? optionalCloudflareAccountId(process.env.CLOUDFLARE_ACCOUNT_ID) ?? CLOUDFLARE_ACCOUNT_ID_PLACEHOLDER,
303
303
  workerName: optionalString(cloudflare.workerName),
304
- gatewayWorkerName: optionalString(cloudflare.gatewayWorkerName),
305
304
  queueName: optionalString(cloudflare.queueName),
306
305
  dlqName: optionalString(cloudflare.dlqName),
307
306
  d1Binding: optionalString(cloudflare.d1Binding),
@@ -83,7 +83,7 @@ export interface TreeseedPluginReference {
83
83
  enabled?: boolean;
84
84
  config?: Record<string, unknown>;
85
85
  }
86
- export type TreeseedPlatformSurfaceName = 'web' | 'api' | 'gateway' | (string & {});
86
+ export type TreeseedPlatformSurfaceName = 'web' | 'api' | (string & {});
87
87
  export type TreeseedPlatformResourceKind = 'pages' | 'styles' | 'components' | 'routes' | 'middleware' | 'handlers' | 'config';
88
88
  export interface TreeseedPlatformLayerDefinition {
89
89
  root: string;
@@ -135,7 +135,6 @@ export interface TreeseedManagedServicesConfig {
135
135
  export interface TreeseedPlatformSurfacesConfig {
136
136
  web?: TreeseedPlatformSurfaceConfig;
137
137
  api?: TreeseedPlatformSurfaceConfig;
138
- gateway?: TreeseedPlatformSurfaceConfig;
139
138
  [key: string]: TreeseedPlatformSurfaceConfig | undefined;
140
139
  }
141
140
  export interface TreeseedProviderSelections {
package/dist/remote.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { RemoteJob, RemoteJobEvent, SdkDispatchRequest, SdkDispatchResult } from './sdk-types.ts';
1
2
  export declare const TREESEED_REMOTE_CONTRACT_VERSION = 1;
2
3
  export declare const TREESEED_REMOTE_CONTRACT_HEADER = "x-treeseed-remote-contract-version";
3
4
  export type ApiScope = string;
@@ -111,6 +112,25 @@ export interface RemoteWorkflowOperationResponse {
111
112
  payload?: Record<string, unknown> | null;
112
113
  nextSteps?: RemoteWorkflowNextStep[];
113
114
  }
115
+ export interface RemoteJobPullRequest {
116
+ limit?: number;
117
+ runnerId?: string;
118
+ }
119
+ export interface RemoteJobPullResponse {
120
+ ok: true;
121
+ payload: RemoteJob[];
122
+ }
123
+ export interface RemoteJobProgressRequest {
124
+ summary?: string;
125
+ data?: Record<string, unknown>;
126
+ }
127
+ export interface RemoteJobCompletionRequest {
128
+ output?: unknown;
129
+ }
130
+ export interface RemoteJobFailureRequest {
131
+ code?: string;
132
+ message: string;
133
+ }
114
134
  export declare class RemoteTreeseedClient {
115
135
  readonly config: RemoteTreeseedConfig;
116
136
  private readonly fetchImpl;
@@ -141,15 +161,6 @@ export declare class RemoteTreeseedSdkClient {
141
161
  constructor(client: RemoteTreeseedClient);
142
162
  execute<T = unknown>(operation: string, request: RemoteSdkOperationRequest): Promise<T>;
143
163
  }
144
- export declare class TreeseedGatewayClient {
145
- private readonly baseUrl;
146
- private readonly token;
147
- private readonly fetchImpl;
148
- constructor(config: import('./sdk-types.ts').SdkGatewayClientConfig);
149
- requestJson<T>(path: string, options?: RemoteGatewayRequest): Promise<T & {
150
- error?: string;
151
- }>;
152
- }
153
164
  export declare class CloudflareQueuePullClient {
154
165
  private readonly baseUrl;
155
166
  private readonly token;
@@ -170,8 +181,53 @@ export declare class CloudflareQueuePullClient {
170
181
  delaySeconds?: number;
171
182
  }>): Promise<unknown>;
172
183
  }
184
+ export declare class CloudflareQueuePushClient {
185
+ private readonly baseUrl;
186
+ private readonly token;
187
+ private readonly fetchImpl;
188
+ constructor(config: import('./sdk-types.ts').SdkQueuePushClientConfig);
189
+ enqueue(request: import('./sdk-types.ts').SdkQueuePushRequest): Promise<void>;
190
+ }
173
191
  export declare class RemoteTreeseedOperationsClient {
174
192
  private readonly client;
175
193
  constructor(client: RemoteTreeseedClient);
176
194
  execute(operation: string, request: RemoteWorkflowOperationRequest): Promise<RemoteWorkflowOperationResponse>;
177
195
  }
196
+ export declare class RemoteTreeseedDispatchClient {
197
+ private readonly client;
198
+ constructor(client: RemoteTreeseedClient);
199
+ dispatch(projectId: string, request: SdkDispatchRequest): Promise<SdkDispatchResult>;
200
+ }
201
+ export declare class RemoteTreeseedJobsClient {
202
+ private readonly client;
203
+ constructor(client: RemoteTreeseedClient);
204
+ get(jobId: string): Promise<{
205
+ ok: true;
206
+ payload: RemoteJob;
207
+ }>;
208
+ cancel(jobId: string): Promise<{
209
+ ok: true;
210
+ payload: RemoteJob;
211
+ }>;
212
+ events(jobId: string): Promise<{
213
+ ok: true;
214
+ payload: RemoteJobEvent[];
215
+ }>;
216
+ }
217
+ export declare class RemoteTreeseedRunnerClient {
218
+ private readonly client;
219
+ constructor(client: RemoteTreeseedClient);
220
+ pull(projectId: string, request?: RemoteJobPullRequest): Promise<RemoteJobPullResponse>;
221
+ progress(jobId: string, request?: RemoteJobProgressRequest): Promise<{
222
+ ok: true;
223
+ payload: RemoteJob;
224
+ }>;
225
+ complete(jobId: string, request?: RemoteJobCompletionRequest): Promise<{
226
+ ok: true;
227
+ payload: RemoteJob;
228
+ }>;
229
+ fail(jobId: string, request: RemoteJobFailureRequest): Promise<{
230
+ ok: true;
231
+ payload: RemoteJob;
232
+ }>;
233
+ }
package/dist/remote.js CHANGED
@@ -100,32 +100,6 @@ class RemoteTreeseedSdkClient {
100
100
  function normalizeExternalBaseUrl(baseUrl) {
101
101
  return baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
102
102
  }
103
- class TreeseedGatewayClient {
104
- baseUrl;
105
- token;
106
- fetchImpl;
107
- constructor(config) {
108
- this.baseUrl = normalizeExternalBaseUrl(config.baseUrl);
109
- this.token = config.bearerToken;
110
- this.fetchImpl = config.fetchImpl ?? fetch;
111
- }
112
- async requestJson(path, options = {}) {
113
- const response = await this.fetchImpl(`${this.baseUrl}${path}`, {
114
- method: options.method ?? "POST",
115
- headers: {
116
- accept: "application/json",
117
- authorization: `Bearer ${this.token}`,
118
- ...options.body === void 0 ? {} : { "content-type": "application/json" }
119
- },
120
- body: options.body === void 0 ? void 0 : JSON.stringify(options.body)
121
- });
122
- const payload = await response.json().catch(() => ({}));
123
- if (!response.ok) {
124
- throw new Error(typeof payload.error === "string" ? payload.error : `Gateway request failed with ${response.status}.`);
125
- }
126
- return payload;
127
- }
128
- }
129
103
  class CloudflareQueuePullClient {
130
104
  baseUrl;
131
105
  token;
@@ -177,6 +151,36 @@ class CloudflareQueuePullClient {
177
151
  });
178
152
  }
179
153
  }
154
+ class CloudflareQueuePushClient {
155
+ baseUrl;
156
+ token;
157
+ fetchImpl;
158
+ constructor(config) {
159
+ const apiBaseUrl = config.apiBaseUrl ?? "https://api.cloudflare.com/client/v4/accounts";
160
+ this.baseUrl = `${normalizeExternalBaseUrl(apiBaseUrl)}/${config.accountId}/queues/${config.queueId}`;
161
+ this.token = config.token;
162
+ this.fetchImpl = config.fetchImpl ?? fetch;
163
+ }
164
+ async enqueue(request) {
165
+ const response = await this.fetchImpl(`${this.baseUrl}/messages`, {
166
+ method: "POST",
167
+ headers: {
168
+ accept: "application/json",
169
+ authorization: `Bearer ${this.token}`,
170
+ "content-type": "application/json"
171
+ },
172
+ body: JSON.stringify({
173
+ body: request.message,
174
+ content_type: "json",
175
+ delay_seconds: request.delaySeconds ?? 0
176
+ })
177
+ });
178
+ const payload = await response.json().catch(() => ({}));
179
+ if (!response.ok || payload.success === false) {
180
+ throw new Error(payload.errors?.[0]?.message ?? `Queue request failed with ${response.status}.`);
181
+ }
182
+ }
183
+ }
180
184
  class RemoteTreeseedOperationsClient {
181
185
  constructor(client) {
182
186
  this.client = client;
@@ -190,13 +194,85 @@ class RemoteTreeseedOperationsClient {
190
194
  });
191
195
  }
192
196
  }
197
+ class RemoteTreeseedDispatchClient {
198
+ constructor(client) {
199
+ this.client = client;
200
+ }
201
+ client;
202
+ dispatch(projectId, request) {
203
+ return this.client.requestJson(`/v1/projects/${encodeURIComponent(projectId)}/dispatch`, {
204
+ method: "POST",
205
+ body: request,
206
+ requireAuth: true
207
+ });
208
+ }
209
+ }
210
+ class RemoteTreeseedJobsClient {
211
+ constructor(client) {
212
+ this.client = client;
213
+ }
214
+ client;
215
+ get(jobId) {
216
+ return this.client.requestJson(`/v1/jobs/${encodeURIComponent(jobId)}`, {
217
+ requireAuth: true
218
+ });
219
+ }
220
+ cancel(jobId) {
221
+ return this.client.requestJson(`/v1/jobs/${encodeURIComponent(jobId)}/cancel`, {
222
+ method: "POST",
223
+ requireAuth: true
224
+ });
225
+ }
226
+ events(jobId) {
227
+ return this.client.requestJson(`/v1/jobs/${encodeURIComponent(jobId)}/events`, {
228
+ requireAuth: true
229
+ });
230
+ }
231
+ }
232
+ class RemoteTreeseedRunnerClient {
233
+ constructor(client) {
234
+ this.client = client;
235
+ }
236
+ client;
237
+ pull(projectId, request = {}) {
238
+ return this.client.requestJson(`/v1/projects/${encodeURIComponent(projectId)}/runner/jobs/pull`, {
239
+ method: "POST",
240
+ body: request,
241
+ requireAuth: true
242
+ });
243
+ }
244
+ progress(jobId, request = {}) {
245
+ return this.client.requestJson(`/v1/jobs/${encodeURIComponent(jobId)}/progress`, {
246
+ method: "POST",
247
+ body: request,
248
+ requireAuth: true
249
+ });
250
+ }
251
+ complete(jobId, request = {}) {
252
+ return this.client.requestJson(`/v1/jobs/${encodeURIComponent(jobId)}/complete`, {
253
+ method: "POST",
254
+ body: request,
255
+ requireAuth: true
256
+ });
257
+ }
258
+ fail(jobId, request) {
259
+ return this.client.requestJson(`/v1/jobs/${encodeURIComponent(jobId)}/fail`, {
260
+ method: "POST",
261
+ body: request,
262
+ requireAuth: true
263
+ });
264
+ }
265
+ }
193
266
  export {
194
267
  CloudflareQueuePullClient,
268
+ CloudflareQueuePushClient,
195
269
  RemoteTreeseedAuthClient,
196
270
  RemoteTreeseedClient,
271
+ RemoteTreeseedDispatchClient,
272
+ RemoteTreeseedJobsClient,
197
273
  RemoteTreeseedOperationsClient,
274
+ RemoteTreeseedRunnerClient,
198
275
  RemoteTreeseedSdkClient,
199
276
  TREESEED_REMOTE_CONTRACT_HEADER,
200
- TREESEED_REMOTE_CONTRACT_VERSION,
201
- TreeseedGatewayClient
277
+ TREESEED_REMOTE_CONTRACT_VERSION
202
278
  };
@@ -0,0 +1,12 @@
1
+ import type { AgentSdk } from './sdk.ts';
2
+ type JsonRecord = Record<string, unknown>;
3
+ type SdkOperationHandler = (sdk: AgentSdk, input: JsonRecord) => Promise<unknown> | unknown;
4
+ interface SdkOperationSpec {
5
+ name: string;
6
+ aliases?: string[];
7
+ handler: SdkOperationHandler;
8
+ }
9
+ export declare function listSdkOperationNames(): string[];
10
+ export declare function findSdkOperation(name: string): SdkOperationSpec | null;
11
+ export declare function executeSdkOperation(sdk: AgentSdk, operationName: string, input: JsonRecord): Promise<unknown>;
12
+ export {};
@@ -0,0 +1,142 @@
1
+ function passthrough(methodName) {
2
+ return (sdk, input) => sdk[methodName](input);
3
+ }
4
+ const SDK_OPERATION_SPECS = [
5
+ { name: "get", handler: passthrough("get") },
6
+ { name: "read", handler: passthrough("read") },
7
+ { name: "search", handler: passthrough("search") },
8
+ { name: "follow", handler: passthrough("follow") },
9
+ { name: "pick", handler: passthrough("pick") },
10
+ { name: "create", handler: passthrough("create") },
11
+ { name: "update", handler: passthrough("update") },
12
+ { name: "claimMessage", aliases: ["claim-message"], handler: passthrough("claimMessage") },
13
+ { name: "ackMessage", aliases: ["ack-message"], handler: passthrough("ackMessage") },
14
+ { name: "createMessage", aliases: ["create-message"], handler: passthrough("createMessage") },
15
+ { name: "recordRun", aliases: ["record-run"], handler: passthrough("recordRun") },
16
+ { name: "getCursor", aliases: ["get-cursor"], handler: passthrough("getCursor") },
17
+ { name: "upsertCursor", aliases: ["upsert-cursor"], handler: passthrough("upsertCursor") },
18
+ { name: "releaseLease", aliases: ["release-lease"], handler: passthrough("releaseLease") },
19
+ {
20
+ name: "releaseAllLeases",
21
+ aliases: ["release-all-leases"],
22
+ handler: (sdk) => sdk.releaseAllLeases()
23
+ },
24
+ { name: "startWorkDay", aliases: ["start-work-day"], handler: passthrough("startWorkDay") },
25
+ { name: "closeWorkDay", aliases: ["close-work-day"], handler: passthrough("closeWorkDay") },
26
+ { name: "createTask", aliases: ["create-task"], handler: passthrough("createTask") },
27
+ { name: "claimTask", aliases: ["claim-task"], handler: passthrough("claimTask") },
28
+ {
29
+ name: "recordTaskProgress",
30
+ aliases: ["record-task-progress"],
31
+ handler: passthrough("recordTaskProgress")
32
+ },
33
+ { name: "completeTask", aliases: ["complete-task"], handler: passthrough("completeTask") },
34
+ { name: "failTask", aliases: ["fail-task"], handler: passthrough("failTask") },
35
+ { name: "appendTaskEvent", aliases: ["append-task-event"], handler: passthrough("appendTaskEvent") },
36
+ { name: "searchTasks", aliases: ["search-tasks"], handler: passthrough("searchTasks") },
37
+ {
38
+ name: "getManagerContext",
39
+ aliases: ["get-manager-context"],
40
+ handler: (sdk, input) => sdk.getManagerContext(String(input.taskId ?? input.id ?? ""))
41
+ },
42
+ { name: "createReport", aliases: ["create-report"], handler: passthrough("createReport") },
43
+ {
44
+ name: "listAgentSpecs",
45
+ aliases: ["list-agent-specs"],
46
+ handler: (sdk, input) => sdk.listAgentSpecs(input)
47
+ },
48
+ {
49
+ name: "listRawAgentSpecs",
50
+ aliases: ["list-raw-agent-specs"],
51
+ handler: (sdk, input) => sdk.listRawAgentSpecs(input)
52
+ },
53
+ { name: "refreshGraph", aliases: ["refresh-graph"], handler: passthrough("refreshGraph") },
54
+ {
55
+ name: "searchFiles",
56
+ aliases: ["search-files"],
57
+ handler: (sdk, input) => sdk.searchFiles(String(input.query ?? ""), input.options)
58
+ },
59
+ {
60
+ name: "searchSections",
61
+ aliases: ["search-sections"],
62
+ handler: (sdk, input) => sdk.searchSections(String(input.query ?? ""), input.options)
63
+ },
64
+ {
65
+ name: "searchEntities",
66
+ aliases: ["search-entities"],
67
+ handler: (sdk, input) => sdk.searchEntities(String(input.query ?? ""), input.options)
68
+ },
69
+ {
70
+ name: "getGraphNode",
71
+ aliases: ["get-graph-node"],
72
+ handler: (sdk, input) => sdk.getGraphNode(String(input.id ?? ""))
73
+ },
74
+ {
75
+ name: "getNeighbors",
76
+ aliases: ["get-neighbors"],
77
+ handler: (sdk, input) => sdk.getNeighbors(String(input.id ?? ""), input.options)
78
+ },
79
+ {
80
+ name: "followReferences",
81
+ aliases: ["follow-references"],
82
+ handler: (sdk, input) => sdk.followReferences(String(input.id ?? ""), input.options)
83
+ },
84
+ {
85
+ name: "getBacklinks",
86
+ aliases: ["get-backlinks"],
87
+ handler: (sdk, input) => sdk.getBacklinks(String(input.id ?? ""), input.options)
88
+ },
89
+ {
90
+ name: "getRelated",
91
+ aliases: ["get-related"],
92
+ handler: (sdk, input) => sdk.getRelated(String(input.id ?? ""), input.options)
93
+ },
94
+ {
95
+ name: "getSubgraph",
96
+ aliases: ["get-subgraph"],
97
+ handler: (sdk, input) => sdk.getSubgraph(Array.isArray(input.seedIds) ? input.seedIds.map(String) : [], input.options)
98
+ },
99
+ { name: "resolveSeeds", aliases: ["resolve-seeds"], handler: passthrough("resolveSeeds") },
100
+ { name: "queryGraph", aliases: ["query-graph"], handler: passthrough("queryGraph") },
101
+ { name: "buildContextPack", aliases: ["build-context-pack"], handler: passthrough("buildContextPack") },
102
+ {
103
+ name: "parseGraphDsl",
104
+ aliases: ["parse-graph-dsl"],
105
+ handler: (sdk, input) => sdk.parseGraphDsl(String(input.source ?? input.query ?? ""))
106
+ },
107
+ {
108
+ name: "resolveReference",
109
+ aliases: ["resolve-reference"],
110
+ handler: (sdk, input) => sdk.resolveReference(String(input.reference ?? ""), input.options)
111
+ },
112
+ {
113
+ name: "explainReferenceChain",
114
+ aliases: ["explain-reference-chain"],
115
+ handler: (sdk, input) => sdk.explainReferenceChain(String(input.fromId ?? ""), String(input.toId ?? ""))
116
+ }
117
+ ];
118
+ const SDK_OPERATION_INDEX = /* @__PURE__ */ new Map();
119
+ for (const spec of SDK_OPERATION_SPECS) {
120
+ SDK_OPERATION_INDEX.set(spec.name, spec);
121
+ for (const alias of spec.aliases ?? []) {
122
+ SDK_OPERATION_INDEX.set(alias, spec);
123
+ }
124
+ }
125
+ function listSdkOperationNames() {
126
+ return [...new Set(SDK_OPERATION_SPECS.map((entry) => entry.name))];
127
+ }
128
+ function findSdkOperation(name) {
129
+ return SDK_OPERATION_INDEX.get(name) ?? null;
130
+ }
131
+ async function executeSdkOperation(sdk, operationName, input) {
132
+ const spec = findSdkOperation(operationName);
133
+ if (!spec) {
134
+ throw new Error(`Unknown SDK operation "${operationName}".`);
135
+ }
136
+ return await spec.handler(sdk, input);
137
+ }
138
+ export {
139
+ executeSdkOperation,
140
+ findSdkOperation,
141
+ listSdkOperationNames
142
+ };
@@ -3,12 +3,139 @@ export declare const SDK_MODEL_NAMES: readonly ["page", "note", "question", "boo
3
3
  export declare const SDK_OPERATIONS: readonly ["get", "read", "search", "follow", "pick", "create", "update"];
4
4
  export declare const SDK_STORAGE_BACKENDS: readonly ["content", "d1"];
5
5
  export declare const SDK_PICK_STRATEGIES: readonly ["latest", "highest_priority", "oldest"];
6
+ export declare const SDK_DISPATCH_EXECUTION_CLASSES: readonly ["local_only", "remote_inline", "remote_job"];
7
+ export declare const SDK_DISPATCH_TARGETS: readonly ["local", "project_api", "project_runner", "market_catalog"];
8
+ export declare const SDK_DISPATCH_POLICIES: readonly ["auto", "prefer_local", "prefer_remote", "remote_only"];
9
+ export declare const SDK_DISPATCH_NAMESPACES: readonly ["sdk", "workflow"];
10
+ export declare const PROJECT_CONNECTION_MODES: readonly ["hosted", "self_hosted", "hybrid"];
11
+ export declare const PROJECT_RUNNER_REGISTRATION_STATES: readonly ["pending", "registered", "offline"];
12
+ export declare const PROJECT_EXECUTION_OWNERS: readonly ["project_api", "project_runner", "market"];
13
+ export declare const REMOTE_JOB_STATUSES: readonly ["pending", "claimed", "running", "completed", "failed", "cancelled"];
6
14
  export type SdkBuiltinModelName = (typeof SDK_MODEL_NAMES)[number];
7
15
  export type SdkModelName = SdkBuiltinModelName | (string & {});
8
16
  export type SdkOperation = (typeof SDK_OPERATIONS)[number];
9
17
  export type SdkStorageBackend = (typeof SDK_STORAGE_BACKENDS)[number];
10
18
  export type SdkPickStrategy = (typeof SDK_PICK_STRATEGIES)[number];
11
19
  export type SdkComparableAs = 'string' | 'number' | 'date' | 'boolean' | 'string_array';
20
+ export type SdkDispatchExecutionClass = (typeof SDK_DISPATCH_EXECUTION_CLASSES)[number];
21
+ export type SdkDispatchTarget = (typeof SDK_DISPATCH_TARGETS)[number];
22
+ export type SdkDispatchPolicy = (typeof SDK_DISPATCH_POLICIES)[number];
23
+ export type SdkDispatchNamespace = (typeof SDK_DISPATCH_NAMESPACES)[number];
24
+ export type ProjectConnectionMode = (typeof PROJECT_CONNECTION_MODES)[number];
25
+ export type ProjectRunnerRegistrationState = (typeof PROJECT_RUNNER_REGISTRATION_STATES)[number];
26
+ export type ProjectExecutionOwner = (typeof PROJECT_EXECUTION_OWNERS)[number];
27
+ export type RemoteJobStatus = (typeof REMOTE_JOB_STATUSES)[number];
28
+ export type RemoteJobRequestedByType = 'user' | 'team_api_key' | 'service' | 'runner' | 'system';
29
+ export interface SdkDispatchCapability {
30
+ namespace: SdkDispatchNamespace;
31
+ operation: string;
32
+ executionClass: SdkDispatchExecutionClass;
33
+ allowedTargets: SdkDispatchTarget[];
34
+ defaultTarget: SdkDispatchTarget;
35
+ defaultDispatchMode: SdkDispatchPolicy;
36
+ summary?: string;
37
+ }
38
+ export interface ProjectConnection {
39
+ id: string;
40
+ projectId: string;
41
+ mode: ProjectConnectionMode;
42
+ projectApiBaseUrl: string | null;
43
+ runnerRegistrationState: ProjectRunnerRegistrationState;
44
+ executionOwner: ProjectExecutionOwner;
45
+ runnerRegisteredAt: string | null;
46
+ runnerLastSeenAt: string | null;
47
+ createdAt: string;
48
+ updatedAt: string;
49
+ metadata?: Record<string, unknown>;
50
+ }
51
+ export interface ProjectCapabilityGrant {
52
+ id: string;
53
+ projectId: string;
54
+ namespace: SdkDispatchNamespace;
55
+ operation: string;
56
+ executionClass: SdkDispatchExecutionClass;
57
+ allowedTargets: SdkDispatchTarget[];
58
+ defaultDispatchMode: SdkDispatchPolicy;
59
+ enabled: boolean;
60
+ createdAt: string;
61
+ updatedAt: string;
62
+ }
63
+ export interface RemoteJobError {
64
+ code?: string | null;
65
+ message: string;
66
+ }
67
+ export interface RemoteJob {
68
+ id: string;
69
+ projectId: string;
70
+ namespace: SdkDispatchNamespace;
71
+ operation: string;
72
+ status: RemoteJobStatus;
73
+ preferredMode: SdkDispatchPolicy;
74
+ selectedTarget: SdkDispatchTarget;
75
+ input: Record<string, unknown>;
76
+ output?: unknown;
77
+ error?: RemoteJobError | null;
78
+ requestedByType: RemoteJobRequestedByType;
79
+ requestedById: string | null;
80
+ assignedRunnerId: string | null;
81
+ idempotencyKey: string | null;
82
+ capability?: SdkDispatchCapability | null;
83
+ pollUrl?: string | null;
84
+ streamUrl?: string | null;
85
+ createdAt: string;
86
+ updatedAt: string;
87
+ startedAt: string | null;
88
+ finishedAt: string | null;
89
+ cancelledAt: string | null;
90
+ }
91
+ export interface RemoteJobEvent {
92
+ id: string;
93
+ jobId: string;
94
+ seq: number;
95
+ kind: string;
96
+ data?: Record<string, unknown>;
97
+ createdAt: string;
98
+ }
99
+ export interface SdkDispatchRequest {
100
+ namespace?: SdkDispatchNamespace;
101
+ operation: string;
102
+ input?: Record<string, unknown>;
103
+ preferredMode?: SdkDispatchPolicy;
104
+ idempotencyKey?: string;
105
+ }
106
+ export interface SdkDispatchInlineResult {
107
+ ok: true;
108
+ mode: 'inline';
109
+ namespace: SdkDispatchNamespace;
110
+ operation: string;
111
+ target: SdkDispatchTarget;
112
+ capability: SdkDispatchCapability;
113
+ payload: unknown;
114
+ }
115
+ export interface SdkDispatchJobResult {
116
+ ok: true;
117
+ mode: 'job';
118
+ namespace: SdkDispatchNamespace;
119
+ operation: string;
120
+ target: SdkDispatchTarget;
121
+ capability: SdkDispatchCapability;
122
+ job: RemoteJob;
123
+ }
124
+ export type SdkDispatchResult = SdkDispatchInlineResult | SdkDispatchJobResult;
125
+ export type SdkDispatchCredentialSource = {
126
+ type: 'bearer';
127
+ token: string;
128
+ } | {
129
+ type: 'resolver';
130
+ resolveToken: () => Promise<string | null> | string | null;
131
+ };
132
+ export interface SdkDispatchConfig {
133
+ projectId: string;
134
+ marketBaseUrl: string;
135
+ policy?: SdkDispatchPolicy;
136
+ credentialSource?: SdkDispatchCredentialSource;
137
+ fetchImpl?: typeof fetch;
138
+ }
12
139
  export type SdkFilterOperator = 'eq' | 'in' | 'contains' | 'prefix' | 'gt' | 'gte' | 'lt' | 'lte' | 'updated_since' | 'related_to';
13
140
  export type TreeseedSchemaVersion = number;
14
141
  export type TreeseedRuntimeRecordType = 'subscription' | 'contact_submission' | 'agent_run' | 'message' | 'agent_cursor' | 'content_lease' | 'work_day' | 'task' | 'task_event' | 'task_output' | 'graph_run' | 'report';
@@ -701,12 +828,14 @@ export interface SdkManagerContextPayload {
701
828
  agent: Record<string, unknown> | null;
702
829
  graph: Record<string, unknown> | null;
703
830
  }
704
- export interface SdkGatewayClientConfig {
705
- baseUrl: string;
706
- bearerToken: string;
831
+ export interface SdkQueuePullClientConfig {
832
+ accountId: string;
833
+ queueId: string;
834
+ token: string;
835
+ apiBaseUrl?: string;
707
836
  fetchImpl?: typeof fetch;
708
837
  }
709
- export interface SdkQueuePullClientConfig {
838
+ export interface SdkQueuePushClientConfig {
710
839
  accountId: string;
711
840
  queueId: string;
712
841
  token: string;
@@ -738,6 +867,10 @@ export interface SdkPulledQueueMessage {
738
867
  export interface SdkQueuePullResult {
739
868
  messages: SdkPulledQueueMessage[];
740
869
  }
870
+ export interface SdkQueuePushRequest {
871
+ message: SdkQueueMessageEnvelope;
872
+ delaySeconds?: number;
873
+ }
741
874
  export interface SdkFollowResult<TItem> {
742
875
  items: TItem[];
743
876
  since: string;
package/dist/sdk-types.js CHANGED
@@ -22,7 +22,23 @@ const SDK_MODEL_NAMES = [
22
22
  const SDK_OPERATIONS = ["get", "read", "search", "follow", "pick", "create", "update"];
23
23
  const SDK_STORAGE_BACKENDS = ["content", "d1"];
24
24
  const SDK_PICK_STRATEGIES = ["latest", "highest_priority", "oldest"];
25
+ const SDK_DISPATCH_EXECUTION_CLASSES = ["local_only", "remote_inline", "remote_job"];
26
+ const SDK_DISPATCH_TARGETS = ["local", "project_api", "project_runner", "market_catalog"];
27
+ const SDK_DISPATCH_POLICIES = ["auto", "prefer_local", "prefer_remote", "remote_only"];
28
+ const SDK_DISPATCH_NAMESPACES = ["sdk", "workflow"];
29
+ const PROJECT_CONNECTION_MODES = ["hosted", "self_hosted", "hybrid"];
30
+ const PROJECT_RUNNER_REGISTRATION_STATES = ["pending", "registered", "offline"];
31
+ const PROJECT_EXECUTION_OWNERS = ["project_api", "project_runner", "market"];
32
+ const REMOTE_JOB_STATUSES = ["pending", "claimed", "running", "completed", "failed", "cancelled"];
25
33
  export {
34
+ PROJECT_CONNECTION_MODES,
35
+ PROJECT_EXECUTION_OWNERS,
36
+ PROJECT_RUNNER_REGISTRATION_STATES,
37
+ REMOTE_JOB_STATUSES,
38
+ SDK_DISPATCH_EXECUTION_CLASSES,
39
+ SDK_DISPATCH_NAMESPACES,
40
+ SDK_DISPATCH_POLICIES,
41
+ SDK_DISPATCH_TARGETS,
26
42
  SDK_MODEL_NAMES,
27
43
  SDK_OPERATIONS,
28
44
  SDK_PICK_STRATEGIES,
package/dist/sdk.d.ts CHANGED
@@ -2,7 +2,7 @@ import type { AgentPermissionConfig, AgentRuntimeSpec } from './types/agents.ts'
2
2
  import { ContentStore } from './content-store.ts';
3
3
  import { type AgentDatabase } from './d1-store.ts';
4
4
  import { type LoadedTreeseedPluginEntry } from './platform/plugins.ts';
5
- import type { SdkAckMessageRequest, SdkClaimMessageRequest, SdkClaimTaskRequest, SdkCloseWorkDayRequest, SdkCompleteTaskRequest, SdkCreateReportRequest, SdkCreateMessageRequest, SdkCreateTaskRequest, SdkCursorRequest, SdkFailTaskRequest, SdkFollowRequest, SdkGetRequest, SdkGetCursorRequest, SdkJsonEnvelope, SdkLeaseReleaseRequest, SdkManagerContextPayload, SdkMutationRequest, SdkGraphQueryOptions, SdkGraphQueryRequest, SdkGraphRefreshRequest, SdkGraphSearchOptions, SdkContextPackRequest, SdkGraphDslParseResult, SdkPickRequest, SdkRecordRunRequest, SdkSearchRequest, SdkStartWorkDayRequest, SdkTaskProgressRequest, SdkTaskSearchRequest, SdkUpdateRequest, SdkModelDefinition, SdkModelRegistry, SdkGraphRankingProvider } from './sdk-types.ts';
5
+ import type { SdkAckMessageRequest, SdkClaimMessageRequest, SdkClaimTaskRequest, SdkCloseWorkDayRequest, SdkCompleteTaskRequest, SdkCreateReportRequest, SdkCreateMessageRequest, SdkCreateTaskRequest, SdkCursorRequest, SdkFailTaskRequest, SdkFollowRequest, SdkGetRequest, SdkGetCursorRequest, SdkJsonEnvelope, SdkLeaseReleaseRequest, SdkManagerContextPayload, SdkMutationRequest, SdkGraphQueryOptions, SdkGraphQueryRequest, SdkGraphRefreshRequest, SdkGraphSearchOptions, SdkContextPackRequest, SdkGraphDslParseResult, SdkPickRequest, SdkRecordRunRequest, SdkSearchRequest, SdkStartWorkDayRequest, SdkTaskProgressRequest, SdkTaskSearchRequest, SdkUpdateRequest, SdkModelDefinition, SdkModelRegistry, SdkGraphRankingProvider, SdkDispatchConfig, SdkDispatchRequest, SdkDispatchResult } from './sdk-types.ts';
6
6
  export interface AgentSdkOptions {
7
7
  repoRoot?: string;
8
8
  database?: AgentDatabase;
@@ -10,12 +10,15 @@ export interface AgentSdkOptions {
10
10
  modelRegistry?: SdkModelRegistry;
11
11
  graphRankingProvider?: SdkGraphRankingProvider;
12
12
  plugins?: LoadedTreeseedPluginEntry[];
13
+ dispatch?: SdkDispatchConfig;
13
14
  }
14
15
  export declare class AgentSdk {
16
+ readonly repoRoot: string;
15
17
  readonly database: AgentDatabase;
16
18
  readonly content: ContentStore;
17
19
  readonly models: SdkModelRegistry;
18
20
  private readonly graph;
21
+ private readonly dispatchConfig?;
19
22
  constructor(options?: AgentSdkOptions);
20
23
  static createLocal(options: {
21
24
  repoRoot?: string;
@@ -24,6 +27,9 @@ export declare class AgentSdk {
24
27
  models?: SdkModelDefinition[];
25
28
  modelRegistry?: SdkModelRegistry;
26
29
  }): AgentSdk;
30
+ private resolveDispatchToken;
31
+ private executeDispatchLocally;
32
+ dispatch(request: SdkDispatchRequest): Promise<SdkDispatchResult>;
27
33
  private envelope;
28
34
  get(request: SdkGetRequest): Promise<SdkJsonEnvelope<Record<string, unknown> | import("./sdk-types.ts").SdkContentEntry | null>>;
29
35
  read(request: SdkGetRequest): Promise<{
package/dist/sdk.js CHANGED
@@ -5,6 +5,10 @@ import { CloudflareD1AgentDatabase, MemoryAgentDatabase } from "./d1-store.js";
5
5
  import { ContentGraphRuntime } from "./graph.js";
6
6
  import { loadTreeseedPlugins } from "./platform/plugins.js";
7
7
  import { buildScopedModelRegistry, resolveModelDefinition } from "./model-registry.js";
8
+ import { findDispatchCapability } from "./dispatch.js";
9
+ import { RemoteTreeseedClient, RemoteTreeseedDispatchClient } from "./remote.js";
10
+ import { executeSdkOperation } from "./sdk-dispatch.js";
11
+ import { TreeseedOperationsSdk } from "./operations/runtime.js";
8
12
  import { WranglerD1Database } from "./wrangler-d1.js";
9
13
  function normalizeAgentSpec(entry) {
10
14
  if (!entry) {
@@ -27,12 +31,15 @@ function operationAllowed(permissions, model, operation) {
27
31
  );
28
32
  }
29
33
  class AgentSdk {
34
+ repoRoot;
30
35
  database;
31
36
  content;
32
37
  models;
33
38
  graph;
39
+ dispatchConfig;
34
40
  constructor(options = {}) {
35
41
  const repoRoot = resolveSdkRepoRoot(options.repoRoot);
42
+ this.repoRoot = repoRoot;
36
43
  this.models = options.modelRegistry ?? buildScopedModelRegistry(repoRoot, options.models);
37
44
  this.database = options.database ?? new MemoryAgentDatabase();
38
45
  this.content = new ContentStore(repoRoot, this.database, this.models);
@@ -48,6 +55,7 @@ class AgentSdk {
48
55
  rankingProvider: options.graphRankingProvider,
49
56
  plugins
50
57
  });
58
+ this.dispatchConfig = options.dispatch;
51
59
  }
52
60
  static createLocal(options) {
53
61
  const repoRoot = resolveSdkRepoRoot(options.repoRoot);
@@ -63,6 +71,67 @@ class AgentSdk {
63
71
  modelRegistry: options.modelRegistry
64
72
  });
65
73
  }
74
+ async resolveDispatchToken(source) {
75
+ if (!source) {
76
+ return null;
77
+ }
78
+ if (source.type === "bearer") {
79
+ return source.token;
80
+ }
81
+ return await source.resolveToken();
82
+ }
83
+ async executeDispatchLocally(request) {
84
+ const namespace = request.namespace ?? "sdk";
85
+ if (namespace === "workflow") {
86
+ const operations = new TreeseedOperationsSdk();
87
+ return operations.execute({
88
+ operationName: request.operation,
89
+ input: request.input ?? {}
90
+ }, {
91
+ cwd: this.repoRoot,
92
+ env: process.env,
93
+ transport: "sdk"
94
+ });
95
+ }
96
+ return executeSdkOperation(this, request.operation, request.input ?? {});
97
+ }
98
+ async dispatch(request) {
99
+ const namespace = request.namespace ?? "sdk";
100
+ const capability = findDispatchCapability(namespace, request.operation);
101
+ if (!capability) {
102
+ throw new Error(`Unknown dispatch operation "${namespace}:${request.operation}".`);
103
+ }
104
+ const preferredMode = request.preferredMode ?? this.dispatchConfig?.policy ?? capability.defaultDispatchMode;
105
+ const dispatchConfig = this.dispatchConfig;
106
+ if (!dispatchConfig && preferredMode === "remote_only") {
107
+ throw new Error(`Dispatch for "${namespace}:${request.operation}" requires a remote market configuration.`);
108
+ }
109
+ const shouldStayLocal = capability.executionClass === "local_only" || !dispatchConfig || preferredMode === "prefer_local";
110
+ if (shouldStayLocal) {
111
+ return {
112
+ ok: true,
113
+ mode: "inline",
114
+ namespace,
115
+ operation: request.operation,
116
+ target: "local",
117
+ capability,
118
+ payload: await this.executeDispatchLocally({ ...request, namespace })
119
+ };
120
+ }
121
+ const token = await this.resolveDispatchToken(dispatchConfig.credentialSource);
122
+ const client = new RemoteTreeseedDispatchClient(new RemoteTreeseedClient({
123
+ hosts: [{ id: "market", baseUrl: dispatchConfig.marketBaseUrl }],
124
+ activeHostId: "market",
125
+ auth: token ? { accessToken: token } : void 0
126
+ }, {
127
+ fetchImpl: dispatchConfig.fetchImpl
128
+ }));
129
+ return client.dispatch(dispatchConfig.projectId, {
130
+ ...request,
131
+ namespace,
132
+ preferredMode
133
+ });
134
+ }
66
135
  envelope(model, operation, payload, meta) {
67
136
  return {
68
137
  ok: true,
@@ -88,6 +88,7 @@ function resolveTreeseedWorkflowState(cwd) {
88
88
  agents: { enabled: false, initialized: false, lastDeploymentTimestamp: null, lastDeployedUrl: null, provider: null },
89
89
  manager: { enabled: false, initialized: false, lastDeploymentTimestamp: null, lastDeployedUrl: null, provider: null },
90
90
  worker: { enabled: false, initialized: false, lastDeploymentTimestamp: null, lastDeployedUrl: null, provider: null },
91
+ runner: { enabled: false, initialized: false, lastDeploymentTimestamp: null, lastDeployedUrl: null, provider: null },
91
92
  workdayStart: { enabled: false, initialized: false, lastDeploymentTimestamp: null, lastDeployedUrl: null, provider: null },
92
93
  workdayReport: { enabled: false, initialized: false, lastDeploymentTimestamp: null, lastDeployedUrl: null, provider: null }
93
94
  },
@@ -128,7 +129,7 @@ function resolveTreeseedWorkflowState(cwd) {
128
129
  url: typeof latestHistory?.url === "string" ? latestHistory.url : deployState.lastDeployedUrl ?? null
129
130
  });
130
131
  }
131
- for (const serviceKey of ["api", "agents", "manager", "worker", "workdayStart", "workdayReport"]) {
132
+ for (const serviceKey of ["api", "agents", "manager", "worker", "runner", "workdayStart", "workdayReport"]) {
132
133
  const service = deployState.services?.[serviceKey];
133
134
  if (!service) continue;
134
135
  state.managedServices[serviceKey] = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treeseed/sdk",
3
- "version": "0.4.8",
3
+ "version": "0.4.9",
4
4
  "description": "Shared Treeseed SDK for content-backed and D1-backed object models.",
5
5
  "license": "AGPL-3.0-only",
6
6
  "repository": {