@treeseed/sdk 0.10.22 → 0.10.24

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 (47) hide show
  1. package/dist/db/market-schema.js +3 -2
  2. package/dist/market-client.d.ts +4 -0
  3. package/dist/market-client.js +6 -0
  4. package/dist/operations/providers/default.js +26 -4
  5. package/dist/operations/repository-operations.js +6 -2
  6. package/dist/operations/services/bootstrap-runner.d.ts +5 -1
  7. package/dist/operations/services/bootstrap-runner.js +34 -5
  8. package/dist/operations/services/config-runtime.d.ts +2 -1
  9. package/dist/operations/services/deploy.d.ts +18 -1
  10. package/dist/operations/services/deploy.js +176 -24
  11. package/dist/operations/services/github-automation.d.ts +10 -1
  12. package/dist/operations/services/github-automation.js +18 -4
  13. package/dist/operations/services/hosting-audit.d.ts +2 -1
  14. package/dist/operations/services/hosting-audit.js +12 -1
  15. package/dist/operations/services/hub-launch.d.ts +1 -0
  16. package/dist/operations/services/hub-launch.js +1 -0
  17. package/dist/operations/services/hub-provider-launch.d.ts +9 -0
  18. package/dist/operations/services/hub-provider-launch.js +140 -40
  19. package/dist/operations/services/managed-host-security.d.ts +1 -1
  20. package/dist/operations/services/managed-host-security.js +4 -1
  21. package/dist/operations/services/project-platform.d.ts +25 -0
  22. package/dist/operations/services/project-platform.js +91 -23
  23. package/dist/operations/services/railway-api.js +2 -1
  24. package/dist/operations/services/railway-deploy.d.ts +32 -2
  25. package/dist/operations/services/railway-deploy.js +94 -27
  26. package/dist/operations/services/template-registry.js +33 -3
  27. package/dist/platform/contracts.d.ts +1 -0
  28. package/dist/platform/deploy-config.js +8 -1
  29. package/dist/platform/deploy-runtime.js +1 -0
  30. package/dist/platform/environment.d.ts +1 -1
  31. package/dist/platform/environment.js +1 -1
  32. package/dist/reconcile/builtin-adapters.js +155 -25
  33. package/dist/reconcile/contracts.d.ts +1 -1
  34. package/dist/reconcile/desired-state.js +17 -1
  35. package/dist/reconcile/engine.d.ts +2 -0
  36. package/dist/reconcile/engine.js +58 -3
  37. package/dist/reconcile/units.js +1 -0
  38. package/dist/sdk-types.d.ts +1 -1
  39. package/dist/sdk-types.js +2 -0
  40. package/dist/timing.d.ts +20 -0
  41. package/dist/timing.js +73 -0
  42. package/dist/treeseed/template-catalog/catalog.fixture.json +150 -0
  43. package/dist/workflow/operations.d.ts +2 -0
  44. package/drizzle/market/0000_market_control_plane.sql +3 -3
  45. package/drizzle/market/0003_project_team_slug_unique.sql +4 -0
  46. package/package.json +1 -1
  47. package/templates/github/deploy-web.workflow.yml +4 -0
package/dist/timing.js ADDED
@@ -0,0 +1,73 @@
1
+ function nowMs() {
2
+ return performance.now();
3
+ }
4
+ function elapsedMs(startMs) {
5
+ return Math.max(0, performance.now() - startMs);
6
+ }
7
+ function formatDurationMs(durationMs) {
8
+ const value = Math.max(0, Number(durationMs) || 0);
9
+ if (value < 1e3) {
10
+ return `${Math.round(value)}ms`;
11
+ }
12
+ if (value < 6e4) {
13
+ return `${(value / 1e3).toFixed(value < 1e4 ? 1 : 0)}s`;
14
+ }
15
+ const minutes = Math.floor(value / 6e4);
16
+ const seconds = Math.round(value % 6e4 / 1e3);
17
+ return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;
18
+ }
19
+ function summarizeSlowestTimings(entries, limit = 8) {
20
+ return flattenTimings(entries).sort((left, right) => right.durationMs - left.durationMs).slice(0, Math.max(0, limit));
21
+ }
22
+ function flattenTimings(entries) {
23
+ const flattened = [];
24
+ const visit = (entry) => {
25
+ flattened.push(entry);
26
+ for (const child of entry.children ?? []) {
27
+ visit(child);
28
+ }
29
+ };
30
+ for (const entry of entries) {
31
+ visit(entry);
32
+ }
33
+ return flattened;
34
+ }
35
+ function formatTimingSummary(entries, { title = "Provider deploy timing summary", limit = 12 } = {}) {
36
+ const slowest = summarizeSlowestTimings(entries, limit);
37
+ const lines = [`${title}:`];
38
+ if (slowest.length === 0) {
39
+ lines.push("- no timed steps recorded");
40
+ return lines.join("\n");
41
+ }
42
+ for (const entry of slowest) {
43
+ const status = entry.status ? ` [${entry.status}]` : "";
44
+ lines.push(`- ${entry.name}: ${formatDurationMs(entry.durationMs)}${status}`);
45
+ }
46
+ return lines.join("\n");
47
+ }
48
+ function formatTimingMarkdown(entries, { title = "Provider deploy timing summary", limit = 20 } = {}) {
49
+ const slowest = summarizeSlowestTimings(entries, limit);
50
+ const lines = [`### ${title}`, "", "| Step | Duration | Status |", "| --- | ---: | --- |"];
51
+ if (slowest.length === 0) {
52
+ lines.push("| No timed steps recorded | 0ms | skipped |");
53
+ return `${lines.join("\n")}
54
+ `;
55
+ }
56
+ for (const entry of slowest) {
57
+ lines.push(`| ${escapeMarkdownCell(entry.name)} | ${formatDurationMs(entry.durationMs)} | ${escapeMarkdownCell(entry.status ?? "")} |`);
58
+ }
59
+ return `${lines.join("\n")}
60
+ `;
61
+ }
62
+ function escapeMarkdownCell(value) {
63
+ return value.replace(/\\/gu, "\\\\").replace(/\|/gu, "\\|").replace(/\n/gu, " ");
64
+ }
65
+ export {
66
+ elapsedMs,
67
+ flattenTimings,
68
+ formatDurationMs,
69
+ formatTimingMarkdown,
70
+ formatTimingSummary,
71
+ nowMs,
72
+ summarizeSlowestTimings
73
+ };
@@ -47,6 +47,156 @@
47
47
  "relatedBooks": [],
48
48
  "relatedKnowledge": [],
49
49
  "relatedObjectives": []
50
+ },
51
+ {
52
+ "id": "starter-research",
53
+ "displayName": "TreeSeed Research",
54
+ "description": "First-party TreeSeed starter for freestanding research projects and knowledge-pack publishing.",
55
+ "summary": "A research starter for building source-backed books, gathered assets, synthesis notes, and reusable knowledge packs.",
56
+ "status": "live",
57
+ "featured": true,
58
+ "category": "starter",
59
+ "audience": [
60
+ "researchers",
61
+ "maintainers"
62
+ ],
63
+ "tags": [
64
+ "starter",
65
+ "research",
66
+ "books",
67
+ "knowledge-packs",
68
+ "agents"
69
+ ],
70
+ "publisher": {
71
+ "id": "treeseed",
72
+ "name": "TreeSeed",
73
+ "url": "https://treeseed.ai"
74
+ },
75
+ "publisherVerified": true,
76
+ "templateVersion": "1.0.0",
77
+ "templateApiVersion": 1,
78
+ "minCliVersion": "0.1.1",
79
+ "minCoreVersion": "0.1.2",
80
+ "fulfillment": {
81
+ "mode": "git",
82
+ "source": {
83
+ "kind": "git",
84
+ "repoUrl": "https://github.com/treeseed-ai/starter-research.git",
85
+ "directory": ".",
86
+ "ref": "main",
87
+ "integrity": "pending-external-repo"
88
+ },
89
+ "hooksPolicy": "builtin_only",
90
+ "supportsReconcile": true
91
+ },
92
+ "offer": {
93
+ "priceModel": "free",
94
+ "license": "AGPL-3.0-only",
95
+ "support": "community"
96
+ },
97
+ "relatedBooks": [],
98
+ "relatedKnowledge": [],
99
+ "relatedObjectives": []
100
+ },
101
+ {
102
+ "id": "starter-engineering",
103
+ "displayName": "TreeSeed Engineering",
104
+ "description": "First-party TreeSeed starter for integrated software guidance, docs, and engineering agents.",
105
+ "summary": "An engineering starter for guiding software projects with research, architecture, implementation, review, and release agents.",
106
+ "status": "live",
107
+ "featured": true,
108
+ "category": "starter",
109
+ "audience": [
110
+ "engineers",
111
+ "maintainers"
112
+ ],
113
+ "tags": [
114
+ "starter",
115
+ "engineering",
116
+ "software",
117
+ "docs",
118
+ "agents"
119
+ ],
120
+ "publisher": {
121
+ "id": "treeseed",
122
+ "name": "TreeSeed",
123
+ "url": "https://treeseed.ai"
124
+ },
125
+ "publisherVerified": true,
126
+ "templateVersion": "1.0.0",
127
+ "templateApiVersion": 1,
128
+ "minCliVersion": "0.1.1",
129
+ "minCoreVersion": "0.1.2",
130
+ "fulfillment": {
131
+ "mode": "git",
132
+ "source": {
133
+ "kind": "git",
134
+ "repoUrl": "https://github.com/treeseed-ai/starter-engineering.git",
135
+ "directory": ".",
136
+ "ref": "main",
137
+ "integrity": "pending-external-repo"
138
+ },
139
+ "hooksPolicy": "builtin_only",
140
+ "supportsReconcile": true
141
+ },
142
+ "offer": {
143
+ "priceModel": "free",
144
+ "license": "AGPL-3.0-only",
145
+ "support": "community"
146
+ },
147
+ "relatedBooks": [],
148
+ "relatedKnowledge": [],
149
+ "relatedObjectives": []
150
+ },
151
+ {
152
+ "id": "starter-information-hub",
153
+ "displayName": "TreeSeed Information Hub",
154
+ "description": "First-party TreeSeed starter for recurring information retrieval, distillation, and downstream distribution.",
155
+ "summary": "An information distribution starter for retrieving updates over time, distilling derived knowledge, and packaging it for downstream projects.",
156
+ "status": "live",
157
+ "featured": true,
158
+ "category": "starter",
159
+ "audience": [
160
+ "curators",
161
+ "maintainers"
162
+ ],
163
+ "tags": [
164
+ "starter",
165
+ "information-hub",
166
+ "distribution",
167
+ "knowledge-packs",
168
+ "agents"
169
+ ],
170
+ "publisher": {
171
+ "id": "treeseed",
172
+ "name": "TreeSeed",
173
+ "url": "https://treeseed.ai"
174
+ },
175
+ "publisherVerified": true,
176
+ "templateVersion": "1.0.0",
177
+ "templateApiVersion": 1,
178
+ "minCliVersion": "0.1.1",
179
+ "minCoreVersion": "0.1.2",
180
+ "fulfillment": {
181
+ "mode": "git",
182
+ "source": {
183
+ "kind": "git",
184
+ "repoUrl": "https://github.com/treeseed-ai/starter-information-hub.git",
185
+ "directory": ".",
186
+ "ref": "main",
187
+ "integrity": "pending-external-repo"
188
+ },
189
+ "hooksPolicy": "builtin_only",
190
+ "supportsReconcile": true
191
+ },
192
+ "offer": {
193
+ "priceModel": "free",
194
+ "license": "AGPL-3.0-only",
195
+ "support": "community"
196
+ },
197
+ "relatedBooks": [],
198
+ "relatedKnowledge": [],
199
+ "relatedObjectives": []
50
200
  }
51
201
  ],
52
202
  "meta": {
@@ -1243,6 +1243,7 @@ export declare function workflowDestroy(helpers: WorkflowOperationHelpers, input
1243
1243
  siteUrl: any;
1244
1244
  accountId: any;
1245
1245
  pages: any;
1246
+ turnstileWidget: any;
1246
1247
  formGuardKv: any;
1247
1248
  sessionKv: any;
1248
1249
  siteDataDb: any;
@@ -1254,6 +1255,7 @@ export declare function workflowDestroy(helpers: WorkflowOperationHelpers, input
1254
1255
  queue: any;
1255
1256
  dlq: any;
1256
1257
  database: any;
1258
+ turnstileWidget: any;
1257
1259
  formGuardKv: any;
1258
1260
  railwayProject: any;
1259
1261
  webDomain: any;
@@ -986,8 +986,7 @@ CREATE TABLE IF NOT EXISTS "projects" (
986
986
  "description" text,
987
987
  "metadata_json" text,
988
988
  "created_at" text NOT NULL,
989
- "updated_at" text NOT NULL,
990
- CONSTRAINT "projects_slug_unique" UNIQUE("slug")
989
+ "updated_at" text NOT NULL
991
990
  );
992
991
 
993
992
  CREATE TABLE IF NOT EXISTS "provider_credential_sessions" (
@@ -2839,8 +2838,8 @@ CREATE INDEX IF NOT EXISTS "idx_capacity_routing_decisions_project_workday" ON "
2839
2838
  CREATE UNIQUE INDEX IF NOT EXISTS "idx_catalog_artifact_versions_item_version" ON "catalog_artifact_versions" USING btree ("item_id","version");
2840
2839
  CREATE INDEX IF NOT EXISTS "idx_catalog_artifact_versions_team_kind" ON "catalog_artifact_versions" USING btree ("team_id","kind","published_at");
2841
2840
  CREATE UNIQUE INDEX IF NOT EXISTS "idx_catalog_item_collaborators_subject_role" ON "catalog_item_collaborators" USING btree ("item_id","subject_type","subject_id","role");
2842
- CREATE UNIQUE INDEX IF NOT EXISTS "idx_catalog_items_kind_slug" ON "catalog_items" USING btree ("kind","slug");
2843
2841
  CREATE INDEX IF NOT EXISTS "idx_catalog_items_team_kind" ON "catalog_items" USING btree ("team_id","kind","updated_at");
2842
+ CREATE UNIQUE INDEX IF NOT EXISTS "idx_catalog_items_team_kind_slug" ON "catalog_items" USING btree ("team_id","kind","slug");
2844
2843
  CREATE INDEX IF NOT EXISTS "idx_catalog_items_visibility_listing" ON "catalog_items" USING btree ("visibility","listing_enabled","updated_at");
2845
2844
  CREATE UNIQUE INDEX IF NOT EXISTS "idx_credit_conversion_profiles_profile_key" ON "credit_conversion_profiles" USING btree ("task_signature","execution_profile_id","execution_provider_kind","native_unit");
2846
2845
  CREATE INDEX IF NOT EXISTS "idx_credit_conversion_profiles_kind_unit" ON "credit_conversion_profiles" USING btree ("execution_provider_kind","native_unit","updated_at");
@@ -2884,6 +2883,7 @@ CREATE INDEX IF NOT EXISTS "idx_project_summary_snapshots_team_generated" ON "pr
2884
2883
  CREATE INDEX IF NOT EXISTS "idx_project_update_plans_hub" ON "project_update_plans" USING btree ("hub_id","created_at");
2885
2884
  CREATE INDEX IF NOT EXISTS "idx_project_workday_summaries_project_environment_created" ON "project_workday_summaries" USING btree ("project_id","environment","created_at");
2886
2885
  CREATE INDEX IF NOT EXISTS "idx_projects_team_id" ON "projects" USING btree ("team_id");
2886
+ CREATE UNIQUE INDEX IF NOT EXISTS "idx_projects_team_slug" ON "projects" USING btree ("team_id","slug");
2887
2887
  CREATE INDEX IF NOT EXISTS "idx_provider_credential_sessions_team_host" ON "provider_credential_sessions" USING btree ("team_id","host_kind","host_id","status");
2888
2888
  CREATE INDEX IF NOT EXISTS "idx_provider_credential_sessions_job" ON "provider_credential_sessions" USING btree ("job_id","status");
2889
2889
  CREATE UNIQUE INDEX IF NOT EXISTS "idx_remote_job_events_job_seq" ON "remote_job_events" USING btree ("job_id","seq");
@@ -0,0 +1,4 @@
1
+ ALTER TABLE "projects" DROP CONSTRAINT IF EXISTS "projects_slug_unique";
2
+ CREATE UNIQUE INDEX IF NOT EXISTS "idx_projects_team_slug" ON "projects" USING btree ("team_id","slug");
3
+ DROP INDEX IF EXISTS "idx_catalog_items_kind_slug";
4
+ CREATE UNIQUE INDEX IF NOT EXISTS "idx_catalog_items_team_kind_slug" ON "catalog_items" USING btree ("team_id","kind","slug");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treeseed/sdk",
3
- "version": "0.10.22",
3
+ "version": "0.10.24",
4
4
  "description": "Shared Treeseed SDK for content-backed and D1-backed object models.",
5
5
  "license": "AGPL-3.0-only",
6
6
  "repository": {
@@ -120,7 +120,11 @@ __WORKING_DIRECTORY_BLOCK__ web:
120
120
  shell: bash
121
121
  run: |
122
122
  set -euo pipefail
123
+ TIMING_SUMMARY="${RUNNER_TEMP:-/tmp}/treeseed-provider-timing.md"
124
+ : > "${TIMING_SUMMARY}"
125
+ export TREESEED_PROVIDER_TIMING_SUMMARY_PATH="${TIMING_SUMMARY}"
123
126
  EXTRA_ARGS=()
124
127
  if [[ -n "${TREESEED_WORKFLOW_PROJECT:-}" ]]; then EXTRA_ARGS+=(--project-id "${TREESEED_WORKFLOW_PROJECT}"); fi
125
128
  if [[ -n "${TREESEED_WORKFLOW_PREVIEW_ID:-}" ]]; then EXTRA_ARGS+=(--preview-id "${TREESEED_WORKFLOW_PREVIEW_ID}"); fi
126
129
  node ./packages/sdk/scripts/run-ts.mjs ./packages/sdk/scripts/tenant-workflow-action.ts --action "${TREESEED_WORKFLOW_ACTION}" --environment "${TREESEED_WORKFLOW_ENVIRONMENT}" "${EXTRA_ARGS[@]}"
130
+ if [[ -n "${GITHUB_STEP_SUMMARY:-}" && -s "${TIMING_SUMMARY}" ]]; then cat "${TIMING_SUMMARY}" >> "${GITHUB_STEP_SUMMARY}"; fi