@treeseed/sdk 0.4.13 → 0.5.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.
Files changed (82) hide show
  1. package/dist/control-plane-client.d.ts +60 -1
  2. package/dist/control-plane-client.js +59 -0
  3. package/dist/control-plane.d.ts +1 -1
  4. package/dist/control-plane.js +11 -4
  5. package/dist/d1-store.d.ts +58 -0
  6. package/dist/d1-store.js +64 -0
  7. package/dist/dispatch.js +6 -0
  8. package/dist/graph/schema.js +4 -0
  9. package/dist/index.d.ts +5 -1
  10. package/dist/index.js +32 -0
  11. package/dist/knowledge-coop.d.ts +223 -0
  12. package/dist/knowledge-coop.js +82 -0
  13. package/dist/model-registry.js +79 -0
  14. package/dist/operations/providers/default.js +126 -7
  15. package/dist/operations/services/config-runtime.d.ts +102 -24
  16. package/dist/operations/services/config-runtime.js +896 -160
  17. package/dist/operations/services/deploy.d.ts +223 -15
  18. package/dist/operations/services/deploy.js +626 -55
  19. package/dist/operations/services/github-automation.d.ts +60 -0
  20. package/dist/operations/services/github-automation.js +138 -0
  21. package/dist/operations/services/key-agent.d.ts +118 -0
  22. package/dist/operations/services/key-agent.js +476 -0
  23. package/dist/operations/services/knowledge-coop-launch.d.ts +90 -0
  24. package/dist/operations/services/knowledge-coop-launch.js +753 -0
  25. package/dist/operations/services/knowledge-coop-packaging.d.ts +59 -0
  26. package/dist/operations/services/knowledge-coop-packaging.js +234 -0
  27. package/dist/operations/services/local-dev.d.ts +0 -1
  28. package/dist/operations/services/local-dev.js +1 -14
  29. package/dist/operations/services/project-platform.d.ts +42 -182
  30. package/dist/operations/services/project-platform.js +162 -59
  31. package/dist/operations/services/railway-deploy.d.ts +1 -0
  32. package/dist/operations/services/railway-deploy.js +31 -13
  33. package/dist/operations/services/runtime-tools.d.ts +52 -5
  34. package/dist/operations/services/runtime-tools.js +186 -26
  35. package/dist/operations/services/watch-dev.js +2 -4
  36. package/dist/operations/services/workspace-preflight.d.ts +4 -4
  37. package/dist/operations/services/workspace-preflight.js +22 -20
  38. package/dist/operations-registry.js +7 -2
  39. package/dist/platform/contracts.d.ts +39 -3
  40. package/dist/platform/deploy-config.d.ts +12 -1
  41. package/dist/platform/deploy-config.js +214 -15
  42. package/dist/platform/deploy-runtime.d.ts +1 -0
  43. package/dist/platform/deploy-runtime.js +10 -2
  44. package/dist/platform/env.yaml +93 -61
  45. package/dist/platform/environment.d.ts +13 -2
  46. package/dist/platform/environment.js +90 -20
  47. package/dist/platform/plugins/constants.d.ts +1 -0
  48. package/dist/platform/plugins/constants.js +7 -6
  49. package/dist/platform/tenant/runtime-config.js +8 -1
  50. package/dist/platform/tenant-config.js +4 -0
  51. package/dist/platform/utils/site-config-schema.js +18 -0
  52. package/dist/plugin-default.js +2 -2
  53. package/dist/scripts/key-agent.js +165 -0
  54. package/dist/scripts/tenant-build.js +4 -1
  55. package/dist/scripts/tenant-check.js +4 -1
  56. package/dist/scripts/tenant-deploy.js +43 -4
  57. package/dist/scripts/tenant-dev.js +0 -1
  58. package/dist/sdk-types.d.ts +2 -2
  59. package/dist/sdk-types.js +2 -0
  60. package/dist/sdk.d.ts +13 -0
  61. package/dist/sdk.js +40 -0
  62. package/dist/stores/knowledge-coop-store.d.ts +56 -0
  63. package/dist/stores/knowledge-coop-store.js +482 -0
  64. package/dist/treeseed/template-catalog/templates/starter-basic/template/package.json +6 -2
  65. package/dist/treeseed/template-catalog/templates/starter-basic/template/src/api/server.js +4 -0
  66. package/dist/treeseed/template-catalog/templates/starter-basic/template/src/config.yaml +25 -0
  67. package/dist/treeseed/template-catalog/templates/starter-basic/template/src/content/decisions/adopt-initial-proposal-loop.mdx +22 -0
  68. package/dist/treeseed/template-catalog/templates/starter-basic/template/src/content/people/starter-steward.mdx +11 -0
  69. package/dist/treeseed/template-catalog/templates/starter-basic/template/src/content/proposals/establish-initial-proposal-loop.mdx +17 -0
  70. package/dist/treeseed/template-catalog/templates/starter-basic/template/src/manifest.yaml +17 -10
  71. package/dist/treeseed/template-catalog/templates/starter-basic/template/treeseed.site.yaml +69 -7
  72. package/dist/treeseed/template-catalog/templates/starter-basic/template.config.json +1 -0
  73. package/dist/workflow/operations.d.ts +98 -0
  74. package/dist/workflow/operations.js +229 -7
  75. package/dist/workflow-state.d.ts +54 -2
  76. package/dist/workflow-state.js +170 -24
  77. package/dist/workflow-support.d.ts +1 -1
  78. package/dist/workflow-support.js +32 -2
  79. package/dist/workflow.d.ts +29 -0
  80. package/package.json +1 -1
  81. package/templates/github/deploy.workflow.yml +11 -1
  82. package/dist/scripts/sync-dev-vars.js +0 -6
@@ -1,7 +1,67 @@
1
+ export interface GitHubRepositoryProvisionInput {
2
+ owner: string;
3
+ name: string;
4
+ description?: string | null;
5
+ visibility?: 'private' | 'public' | 'internal';
6
+ homepageUrl?: string | null;
7
+ topics?: string[];
8
+ }
9
+ export interface GitHubProvisionedRepository {
10
+ slug: string;
11
+ owner: string;
12
+ name: string;
13
+ url: string;
14
+ sshUrl: string;
15
+ httpsUrl: string;
16
+ visibility: 'private' | 'public' | 'internal';
17
+ defaultBranch: string;
18
+ }
1
19
  export declare function getGitHubAutomationMode(): "stub" | "real";
2
20
  export declare function parseGitHubRepositoryFromRemote(remoteUrl: any): string | null;
3
21
  export declare function resolveGitHubRepositorySlug(tenantRoot: any): string;
4
22
  export declare function maybeResolveGitHubRepositorySlug(tenantRoot: any): string | null;
23
+ export declare function resolveDefaultGitHubOwner(): string;
24
+ export declare function createGitHubRepository(input: any): {
25
+ visibility: any;
26
+ defaultBranch: string;
27
+ mode: string;
28
+ slug: string;
29
+ owner: string;
30
+ name: string;
31
+ sshUrl: string;
32
+ httpsUrl: string;
33
+ url: string;
34
+ } | {
35
+ owner: string;
36
+ name: string;
37
+ url: string;
38
+ visibility: string;
39
+ defaultBranch: string;
40
+ slug: string;
41
+ sshUrl: string;
42
+ httpsUrl: string;
43
+ };
44
+ export declare function initializeGitHubRepositoryWorkingTree(cwd: any, repository: any, { defaultBranch, createStaging, commitMessage, remoteName, push, }?: {
45
+ defaultBranch?: string | undefined;
46
+ createStaging?: boolean | undefined;
47
+ commitMessage?: string | undefined;
48
+ remoteName?: string | undefined;
49
+ push?: boolean | undefined;
50
+ }): {
51
+ repository: any;
52
+ remoteName: string;
53
+ defaultBranch: string;
54
+ stagingBranch: string | null;
55
+ pushed: boolean;
56
+ mode: string;
57
+ } | {
58
+ repository: any;
59
+ remoteName: string;
60
+ defaultBranch: string;
61
+ stagingBranch: string | null;
62
+ pushed: boolean;
63
+ mode?: undefined;
64
+ };
5
65
  export declare function resolveGitRepositoryRoot(tenantRoot: any): any;
6
66
  export declare function requiredGitHubEnvironment(tenantRoot: any, { scope, purpose }?: {
7
67
  scope?: string | undefined;
@@ -7,6 +7,9 @@ function envOrNull(key) {
7
7
  const value = process.env[key];
8
8
  return typeof value === "string" && value.length > 0 ? value : null;
9
9
  }
10
+ function slugifySegment(value, fallback = "project") {
11
+ return String(value ?? "").trim().toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").replace(/-{2,}/g, "-").slice(0, 96) || fallback;
12
+ }
10
13
  function getGitHubAutomationMode() {
11
14
  return process.env.TREESEED_GITHUB_AUTOMATION_MODE === "stub" ? "stub" : "real";
12
15
  }
@@ -61,6 +64,28 @@ function sleepSeconds(seconds) {
61
64
  stdio: "ignore"
62
65
  });
63
66
  }
67
+ function resolveGitHubRemoteUrls(owner, name) {
68
+ const normalizedOwner = slugifySegment(owner, "owner");
69
+ const normalizedName = slugifySegment(name, "repo");
70
+ return {
71
+ slug: `${normalizedOwner}/${normalizedName}`,
72
+ owner: normalizedOwner,
73
+ name: normalizedName,
74
+ sshUrl: `git@github.com:${normalizedOwner}/${normalizedName}.git`,
75
+ httpsUrl: `https://github.com/${normalizedOwner}/${normalizedName}.git`,
76
+ url: `https://github.com/${normalizedOwner}/${normalizedName}`
77
+ };
78
+ }
79
+ function ensureGitIdentity(cwd) {
80
+ const currentName = runGit(["config", "--get", "user.name"], { cwd, allowFailure: true }).stdout?.trim() ?? "";
81
+ const currentEmail = runGit(["config", "--get", "user.email"], { cwd, allowFailure: true }).stdout?.trim() ?? "";
82
+ if (!currentName) {
83
+ runGit(["config", "user.name", envOrNull("TREESEED_GITHUB_COMMITTER_NAME") ?? "Treeseed Launch"], { cwd });
84
+ }
85
+ if (!currentEmail) {
86
+ runGit(["config", "user.email", envOrNull("TREESEED_GITHUB_COMMITTER_EMAIL") ?? "launch@knowledge.coop"], { cwd });
87
+ }
88
+ }
64
89
  function resolveGitHubRepositorySlug(tenantRoot) {
65
90
  const remoteResult = runGit(["remote", "get-url", "origin"], { cwd: tenantRoot });
66
91
  const remoteUrl = remoteResult.stdout?.trim() ?? "";
@@ -77,6 +102,116 @@ function maybeResolveGitHubRepositorySlug(tenantRoot) {
77
102
  return null;
78
103
  }
79
104
  }
105
+ function resolveDefaultGitHubOwner() {
106
+ const explicit = envOrNull("TREESEED_KNOWLEDGE_COOP_GITHUB_OWNER");
107
+ if (explicit) {
108
+ return explicit;
109
+ }
110
+ try {
111
+ const repository = maybeResolveGitHubRepositorySlug(process.cwd());
112
+ if (repository?.includes("/")) {
113
+ return repository.split("/")[0];
114
+ }
115
+ } catch {
116
+ }
117
+ return "treeseed-ai";
118
+ }
119
+ function createGitHubRepository(input) {
120
+ const visibility = input.visibility ?? "private";
121
+ const remotes = resolveGitHubRemoteUrls(input.owner, input.name);
122
+ if (isGitHubAutomationStubbed()) {
123
+ return {
124
+ ...remotes,
125
+ visibility,
126
+ defaultBranch: "main",
127
+ mode: "stub"
128
+ };
129
+ }
130
+ const existing = runGh(["repo", "view", remotes.slug, "--json", "name,owner,url,isPrivate,defaultBranchRef,visibility"], {
131
+ allowFailure: true
132
+ });
133
+ if (existing.status !== 0) {
134
+ const args = ["repo", "create", remotes.slug, "--disable-wiki", "--confirm"];
135
+ if (visibility === "public") {
136
+ args.push("--public");
137
+ } else if (visibility === "internal") {
138
+ args.push("--internal");
139
+ } else {
140
+ args.push("--private");
141
+ }
142
+ if (input.description) {
143
+ args.push("--description", input.description);
144
+ }
145
+ if (input.homepageUrl) {
146
+ args.push("--homepage", input.homepageUrl);
147
+ }
148
+ runGh(args, { capture: false });
149
+ }
150
+ if (Array.isArray(input.topics) && input.topics.length > 0) {
151
+ runGh(
152
+ ["repo", "edit", remotes.slug, ...input.topics.flatMap((topic) => ["--add-topic", slugifySegment(topic, "treeseed")])],
153
+ { capture: false }
154
+ );
155
+ }
156
+ const viewed = runGh(["repo", "view", remotes.slug, "--json", "name,owner,url,isPrivate,defaultBranchRef,visibility"], {});
157
+ const payload = JSON.parse(viewed.stdout || "{}");
158
+ return {
159
+ ...remotes,
160
+ owner: String(payload.owner?.login ?? remotes.owner),
161
+ name: String(payload.name ?? remotes.name),
162
+ url: String(payload.url ?? remotes.url),
163
+ visibility: String(payload.visibility ?? (payload.isPrivate === true ? "private" : visibility)),
164
+ defaultBranch: String(payload.defaultBranchRef?.name ?? "main")
165
+ };
166
+ }
167
+ function initializeGitHubRepositoryWorkingTree(cwd, repository, {
168
+ defaultBranch = "main",
169
+ createStaging = true,
170
+ commitMessage = "Initialize Knowledge Coop hub",
171
+ remoteName = "origin",
172
+ push = true
173
+ } = {}) {
174
+ if (isGitHubAutomationStubbed()) {
175
+ return {
176
+ repository,
177
+ remoteName,
178
+ defaultBranch,
179
+ stagingBranch: createStaging ? "staging" : null,
180
+ pushed: false,
181
+ mode: "stub"
182
+ };
183
+ }
184
+ runGit(["init", "-b", defaultBranch], { cwd, allowFailure: true });
185
+ ensureGitIdentity(cwd);
186
+ const currentRemote = runGit(["remote", "get-url", remoteName], { cwd, allowFailure: true }).stdout?.trim() ?? "";
187
+ if (!currentRemote) {
188
+ runGit(["remote", "add", remoteName, repository.sshUrl], { cwd });
189
+ } else if (currentRemote !== repository.sshUrl && currentRemote !== repository.httpsUrl) {
190
+ runGit(["remote", "set-url", remoteName, repository.sshUrl], { cwd });
191
+ }
192
+ runGit(["add", "-A"], { cwd });
193
+ const hasChanges = runGit(["status", "--porcelain"], { cwd }).stdout?.trim().length > 0;
194
+ if (hasChanges) {
195
+ runGit(["commit", "-m", commitMessage], { cwd });
196
+ }
197
+ if (push) {
198
+ runGit(["push", "-u", remoteName, defaultBranch], { cwd, capture: false });
199
+ }
200
+ if (createStaging) {
201
+ runGit(["checkout", "-B", "staging"], { cwd });
202
+ if (push) {
203
+ runGit(["push", "-u", remoteName, "staging"], { cwd, capture: false });
204
+ }
205
+ runGit(["checkout", defaultBranch], { cwd });
206
+ }
207
+ return {
208
+ repository,
209
+ remoteName,
210
+ defaultBranch,
211
+ stagingBranch: createStaging ? "staging" : null,
212
+ pushed: push
213
+ };
214
+ }
80
215
  function resolveGitRepositoryRoot(tenantRoot) {
81
216
  const result = runGit(["rev-parse", "--show-toplevel"], { cwd: tenantRoot, allowFailure: true });
82
217
  return result.status === 0 ? result.stdout.trim() : tenantRoot;
@@ -372,6 +507,7 @@ function waitForGitHubWorkflowCompletion(tenantRoot, {
372
507
  throw new Error(`Timed out waiting for GitHub workflow ${workflow} in ${repo}.`);
373
508
  }
374
509
  export {
510
+ createGitHubRepository,
375
511
  ensureDeployWorkflow,
376
512
  ensureGitHubDeployAutomation,
377
513
  ensureGitHubEnvironment,
@@ -380,6 +516,7 @@ export {
380
516
  ensureStandardizedGitHubWorkflows,
381
517
  formatMissingSecretsReport,
382
518
  getGitHubAutomationMode,
519
+ initializeGitHubRepositoryWorkingTree,
383
520
  listGitHubSecretNames,
384
521
  listGitHubVariableNames,
385
522
  maybeResolveGitHubRepositorySlug,
@@ -388,6 +525,7 @@ export {
388
525
  renderHostedProjectWorkflow,
389
526
  requiredGitHubEnvironment,
390
527
  requiredGitHubSecrets,
528
+ resolveDefaultGitHubOwner,
391
529
  resolveGitHubRepositorySlug,
392
530
  resolveGitRepositoryRoot,
393
531
  waitForGitHubWorkflowCompletion
@@ -0,0 +1,118 @@
1
+ export declare const TRESEED_MACHINE_KEY_PASSPHRASE_ENV = "TREESEED_KEY_PASSPHRASE";
2
+ export declare const TRESEED_KEY_AGENT_IDLE_TIMEOUT_MS: number;
3
+ export declare const TREESEED_KEY_AGENT_IDLE_TIMEOUT_MS: number;
4
+ export declare const TRESEED_WRAPPED_MACHINE_KEY_VERSION = 2;
5
+ export declare const TRESEED_WRAPPED_MACHINE_KEY_KIND = "treeseed-wrapped-machine-key";
6
+ export declare const TREESEED_MACHINE_KEY_PASSPHRASE_ENV = "TREESEED_KEY_PASSPHRASE";
7
+ export type TreeseedWrappedMachineKey = {
8
+ version: 2;
9
+ kind: typeof TRESEED_WRAPPED_MACHINE_KEY_KIND;
10
+ createdAt: string;
11
+ updatedAt: string;
12
+ kdf: {
13
+ algorithm: 'scrypt';
14
+ salt: string;
15
+ N: number;
16
+ r: number;
17
+ p: number;
18
+ keyLength: number;
19
+ };
20
+ wrappedKey: {
21
+ algorithm: 'aes-256-gcm';
22
+ iv: string;
23
+ tag: string;
24
+ ciphertext: string;
25
+ };
26
+ fingerprint: string;
27
+ };
28
+ export type TreeseedKeyAgentStatus = {
29
+ running: boolean;
30
+ unlocked: boolean;
31
+ wrappedKeyPresent: boolean;
32
+ migrationRequired: boolean;
33
+ keyPath: string;
34
+ socketPath: string;
35
+ idleTimeoutMs: number;
36
+ idleRemainingMs: number;
37
+ };
38
+ export type TreeseedKeyAgentCommand = {
39
+ command: 'status';
40
+ keyPath: string;
41
+ socketPath: string;
42
+ idleTimeoutMs: number;
43
+ } | {
44
+ command: 'unlock';
45
+ keyPath: string;
46
+ socketPath: string;
47
+ idleTimeoutMs: number;
48
+ passphrase: string;
49
+ createIfMissing?: boolean;
50
+ allowMigration?: boolean;
51
+ } | {
52
+ command: 'lock';
53
+ keyPath: string;
54
+ socketPath: string;
55
+ idleTimeoutMs: number;
56
+ } | {
57
+ command: 'touch';
58
+ keyPath: string;
59
+ socketPath: string;
60
+ idleTimeoutMs: number;
61
+ } | {
62
+ command: 'get-machine-key';
63
+ keyPath: string;
64
+ socketPath: string;
65
+ idleTimeoutMs: number;
66
+ };
67
+ export type TreeseedKeyAgentResponse = {
68
+ ok: boolean;
69
+ code?: string;
70
+ message?: string;
71
+ status?: TreeseedKeyAgentStatus;
72
+ machineKey?: string;
73
+ };
74
+ export declare class TreeseedKeyAgentError extends Error {
75
+ code: 'locked' | 'unlock_required' | 'unlock_failed' | 'wrapped_key_missing' | 'wrapped_key_migration_required' | 'interactive_required' | 'daemon_unavailable' | 'corrupt_wrapped_key';
76
+ details?: Record<string, unknown>;
77
+ constructor(code: TreeseedKeyAgentError['code'], message: string, details?: Record<string, unknown>);
78
+ }
79
+ type TreeseedKeyAgentSessionState = {
80
+ machineKey: Buffer | null;
81
+ lastTouchedAt: number;
82
+ idleTimeoutMs: number;
83
+ };
84
+ export declare function unwrapMachineKey(payload: TreeseedWrappedMachineKey, passphrase: string): Buffer<ArrayBuffer>;
85
+ export declare function readWrappedMachineKeyFile(keyPath: string): {
86
+ exists: boolean;
87
+ wrapped: null;
88
+ plaintextLegacy: null;
89
+ migrationRequired: boolean;
90
+ } | {
91
+ exists: boolean;
92
+ wrapped: TreeseedWrappedMachineKey;
93
+ plaintextLegacy: null;
94
+ migrationRequired: boolean;
95
+ } | {
96
+ exists: boolean;
97
+ wrapped: null;
98
+ plaintextLegacy: Buffer<ArrayBuffer>;
99
+ migrationRequired: boolean;
100
+ };
101
+ export declare function writeWrappedMachineKeyFile(keyPath: string, payload: TreeseedWrappedMachineKey): void;
102
+ export declare function replaceWrappedMachineKey(keyPath: string, machineKey: Buffer, passphrase: string): TreeseedWrappedMachineKey;
103
+ export declare function getTreeseedKeyAgentPaths(): {
104
+ homeRoot: string;
105
+ socketPath: string;
106
+ };
107
+ export declare function handleTreeseedKeyAgentCommand(command: TreeseedKeyAgentCommand, session: TreeseedKeyAgentSessionState): TreeseedKeyAgentResponse;
108
+ export declare function requestTreeseedKeyAgent(command: TreeseedKeyAgentCommand): Promise<TreeseedKeyAgentResponse>;
109
+ export declare function startTreeseedKeyAgentServer(options: {
110
+ keyPath: string;
111
+ socketPath?: string;
112
+ idleTimeoutMs?: number;
113
+ }): Promise<void>;
114
+ export declare function assertTreeseedKeyAgentResponse(response: TreeseedKeyAgentResponse, fallback?: string): TreeseedKeyAgentResponse;
115
+ export declare function rotateWrappedMachineKeyPassphrase(keyPath: string, machineKey: Buffer, passphrase: string): TreeseedWrappedMachineKey;
116
+ export declare function migrateLegacyProjectMachineKeyToWrapped(keyPath: string, legacyKeyPath: string, passphrase: string): TreeseedWrappedMachineKey;
117
+ export declare function machineKeysEqual(left: Buffer, right: Buffer): boolean;
118
+ export {};