@treeseed/sdk 0.4.12 → 0.4.13

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.
@@ -1,12 +1,31 @@
1
1
  import { resolveTreeseedWorkflowState } from './workflow-state.ts';
2
2
  import { listTaskBranches } from './operations/services/git-workflow.ts';
3
3
  import { TreeseedWorkflowError, type TreeseedWorkflowErrorCode } from './workflow/operations.ts';
4
- export type TreeseedWorkflowOperationId = 'status' | 'config' | 'tasks' | 'switch' | 'dev' | 'save' | 'close' | 'stage' | 'release' | 'destroy' | 'export';
4
+ export type TreeseedWorkflowOperationId = 'status' | 'config' | 'tasks' | 'switch' | 'dev' | 'save' | 'close' | 'stage' | 'release' | 'resume' | 'recover' | 'destroy' | 'export';
5
5
  export type TreeseedWorkflowNextStep = {
6
6
  operation: string;
7
7
  reason?: string;
8
8
  input?: Record<string, unknown>;
9
9
  };
10
+ export type TreeseedWorkflowFact = {
11
+ label: string;
12
+ value: string | number | boolean | null;
13
+ };
14
+ export type TreeseedWorkflowErrorDetail = {
15
+ code: string;
16
+ message: string;
17
+ details?: Record<string, unknown> | null;
18
+ };
19
+ export type TreeseedWorkflowRecovery = {
20
+ resumable: boolean;
21
+ runId?: string | null;
22
+ command?: string | null;
23
+ message?: string | null;
24
+ recoverCommand?: string | null;
25
+ resumeCommand?: string | null;
26
+ lock?: Record<string, unknown> | null;
27
+ };
28
+ export type TreeseedWorkflowExecutionMode = 'execute' | 'plan';
10
29
  export type TreeseedWorkflowContext = {
11
30
  cwd?: string;
12
31
  env?: NodeJS.ProcessEnv;
@@ -14,12 +33,25 @@ export type TreeseedWorkflowContext = {
14
33
  prompt?: (message: string) => Promise<string> | string;
15
34
  confirm?: (message: string, expected: string) => Promise<boolean> | boolean;
16
35
  transport?: 'sdk' | 'cli' | 'api';
36
+ workflow?: {
37
+ resumeRunId?: string;
38
+ };
17
39
  };
18
40
  export type TreeseedWorkflowResult<TPayload = Record<string, unknown>> = {
41
+ schemaVersion: 1;
42
+ kind: 'treeseed.workflow.result';
43
+ command: TreeseedWorkflowOperationId;
44
+ executionMode: TreeseedWorkflowExecutionMode;
45
+ runId: string | null;
19
46
  ok: boolean;
20
47
  operation: TreeseedWorkflowOperationId;
48
+ summary?: string;
49
+ facts?: TreeseedWorkflowFact[];
21
50
  payload: TPayload;
51
+ result: TPayload;
22
52
  nextSteps?: TreeseedWorkflowNextStep[];
53
+ recovery?: TreeseedWorkflowRecovery | null;
54
+ errors?: TreeseedWorkflowErrorDetail[];
23
55
  };
24
56
  export type TreeseedTaskBranchMetadata = ReturnType<typeof listTaskBranches>[number] & {
25
57
  ageDays: number | null;
@@ -29,6 +61,16 @@ export type TreeseedTaskBranchMetadata = ReturnType<typeof listTaskBranches>[num
29
61
  url: string | null;
30
62
  lastDeploymentTimestamp: string | null;
31
63
  };
64
+ packages?: Array<{
65
+ name: string;
66
+ path: string;
67
+ local: boolean;
68
+ remote: boolean;
69
+ current: boolean;
70
+ head: string | null;
71
+ pointer: string | null;
72
+ aligned: boolean;
73
+ }>;
32
74
  };
33
75
  export type TreeseedSaveInput = {
34
76
  message: string;
@@ -37,12 +79,16 @@ export type TreeseedSaveInput = {
37
79
  refreshPreview?: boolean;
38
80
  preview?: boolean;
39
81
  rebase?: boolean;
82
+ plan?: boolean;
83
+ dryRun?: boolean;
40
84
  };
41
85
  export type TreeseedCloseInput = {
42
86
  message: string;
43
87
  deletePreview?: boolean;
44
88
  deleteBranch?: boolean;
45
89
  autoSave?: boolean;
90
+ plan?: boolean;
91
+ dryRun?: boolean;
46
92
  };
47
93
  export type TreeseedStageInput = {
48
94
  message: string;
@@ -50,6 +96,8 @@ export type TreeseedStageInput = {
50
96
  deletePreview?: boolean;
51
97
  deleteBranch?: boolean;
52
98
  autoSave?: boolean;
99
+ plan?: boolean;
100
+ dryRun?: boolean;
53
101
  };
54
102
  export type TreeseedSwitchInput = {
55
103
  branch?: string;
@@ -57,6 +105,8 @@ export type TreeseedSwitchInput = {
57
105
  preview?: boolean;
58
106
  createIfMissing?: boolean;
59
107
  baseBranch?: string;
108
+ plan?: boolean;
109
+ dryRun?: boolean;
60
110
  };
61
111
  export type TreeseedConfigScope = 'all' | 'local' | 'staging' | 'prod';
62
112
  export type TreeseedConfigInput = {
@@ -82,12 +132,21 @@ export type TreeseedExportInput = {
82
132
  };
83
133
  export type TreeseedReleaseInput = {
84
134
  bump: 'major' | 'minor' | 'patch';
135
+ plan?: boolean;
136
+ dryRun?: boolean;
137
+ };
138
+ export type TreeseedResumeInput = {
139
+ runId: string;
140
+ };
141
+ export type TreeseedRecoverInput = {
142
+ runId?: string;
85
143
  };
86
144
  export type TreeseedDestroyInput = {
87
145
  target?: 'local' | 'staging' | 'prod';
88
146
  environment?: 'local' | 'staging' | 'prod';
89
147
  confirm?: boolean | string;
90
148
  dryRun?: boolean;
149
+ plan?: boolean;
91
150
  destroyRemote?: boolean;
92
151
  destroyLocal?: boolean;
93
152
  force?: boolean;
@@ -105,9 +164,9 @@ export declare class TreeseedWorkflowSdk {
105
164
  private readonly context;
106
165
  constructor(context?: TreeseedWorkflowContext);
107
166
  private helpers;
108
- execute(operation: TreeseedWorkflowOperationId, input?: Record<string, unknown>): Promise<TreeseedWorkflowResult<import("./workflow-state.ts").TreeseedWorkflowState> | TreeseedWorkflowResult<Record<string, unknown>> | TreeseedWorkflowResult<{
167
+ execute(operation: TreeseedWorkflowOperationId, input?: Record<string, unknown>): Promise<TreeseedWorkflowResult<import("./workflow-state.ts").TreeseedWorkflowState> | TreeseedWorkflowResult<{
109
168
  tasks: TreeseedTaskBranchMetadata[];
110
- }>>;
169
+ }> | TreeseedWorkflowResult<Record<string, unknown>>>;
111
170
  status(): Promise<TreeseedWorkflowResult<ReturnType<typeof resolveTreeseedWorkflowState>>>;
112
171
  tasks(): Promise<TreeseedWorkflowResult<{
113
172
  tasks: TreeseedTaskBranchMetadata[];
@@ -119,6 +178,8 @@ export declare class TreeseedWorkflowSdk {
119
178
  close(input: TreeseedCloseInput): Promise<TreeseedWorkflowResult>;
120
179
  stage(input: TreeseedStageInput): Promise<TreeseedWorkflowResult>;
121
180
  release(input: TreeseedReleaseInput): Promise<TreeseedWorkflowResult>;
181
+ resume(input: TreeseedResumeInput): Promise<TreeseedWorkflowResult>;
182
+ recover(input?: TreeseedRecoverInput): Promise<TreeseedWorkflowResult>;
122
183
  destroy(input: TreeseedDestroyInput): Promise<TreeseedWorkflowResult>;
123
184
  export(input?: TreeseedExportInput): Promise<TreeseedWorkflowResult>;
124
185
  }
package/dist/workflow.js CHANGED
@@ -6,7 +6,9 @@ import {
6
6
  workflowDestroy,
7
7
  workflowDev,
8
8
  workflowExport,
9
+ workflowRecover,
9
10
  workflowRelease,
11
+ workflowResume,
10
12
  workflowSave,
11
13
  workflowStage,
12
14
  workflowStatus,
@@ -56,6 +58,10 @@ class TreeseedWorkflowSdk {
56
58
  return this.stage(input);
57
59
  case "release":
58
60
  return this.release(input);
61
+ case "resume":
62
+ return this.resume(input);
63
+ case "recover":
64
+ return this.recover(input);
59
65
  case "destroy":
60
66
  return this.destroy(input);
61
67
  case "export":
@@ -91,6 +97,12 @@ class TreeseedWorkflowSdk {
91
97
  async release(input) {
92
98
  return workflowRelease(this.helpers(), input);
93
99
  }
100
+ async resume(input) {
101
+ return workflowResume(this.helpers(), input);
102
+ }
103
+ async recover(input = {}) {
104
+ return workflowRecover(this.helpers(), input);
105
+ }
94
106
  async destroy(input) {
95
107
  return workflowDestroy(this.helpers(), input);
96
108
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treeseed/sdk",
3
- "version": "0.4.12",
3
+ "version": "0.4.13",
4
4
  "description": "Shared Treeseed SDK for content-backed and D1-backed object models.",
5
5
  "license": "AGPL-3.0-only",
6
6
  "repository": {
@@ -1,24 +0,0 @@
1
- #!/usr/bin/env node
2
- import { applyTreeseedEnvironmentToProcess } from '../operations/services/config-runtime.js';
3
- import { cleanupDestroyedState, createBranchPreviewDeployTarget, destroyCloudflareResources, loadDeployState, printDestroySummary, validateDestroyPrerequisites, } from '../operations/services/deploy.js';
4
- import { assertFeatureBranch, deleteLocalBranch, deleteRemoteBranch, mergeCurrentBranchIntoStaging, } from '../operations/services/git-workflow.js';
5
- import { loadCliDeployConfig } from '../operations/services/runtime-tools.js';
6
- import { runWorkspaceSavePreflight } from '../operations/services/save-deploy-preflight.js';
7
- const tenantRoot = process.cwd();
8
- const featureBranch = assertFeatureBranch(tenantRoot);
9
- const previewTarget = createBranchPreviewDeployTarget(featureBranch);
10
- const deployConfig = loadCliDeployConfig(tenantRoot);
11
- const previewState = loadDeployState(tenantRoot, deployConfig, { target: previewTarget });
12
- runWorkspaceSavePreflight({ cwd: tenantRoot });
13
- const repoDir = mergeCurrentBranchIntoStaging(tenantRoot, featureBranch);
14
- if (previewState.readiness?.initialized) {
15
- applyTreeseedEnvironmentToProcess({ tenantRoot, scope: 'staging', override: true });
16
- validateDestroyPrerequisites(tenantRoot, { requireRemote: true });
17
- const result = destroyCloudflareResources(tenantRoot, { target: previewTarget });
18
- printDestroySummary(result);
19
- }
20
- cleanupDestroyedState(tenantRoot, { target: previewTarget });
21
- deleteRemoteBranch(repoDir, featureBranch);
22
- deleteLocalBranch(repoDir, featureBranch);
23
- console.log('Treeseed close completed successfully.');
24
- console.log(`Merged ${featureBranch} into staging and removed branch artifacts.`);
@@ -1,42 +0,0 @@
1
- #!/usr/bin/env node
2
- import { readFileSync, writeFileSync } from 'node:fs';
3
- import { resolve } from 'node:path';
4
- import { applyTreeseedEnvironmentToProcess } from '../operations/services/config-runtime.js';
5
- import { PRODUCTION_BRANCH, STAGING_BRANCH, mergeStagingIntoMain, prepareReleaseBranches, pushBranch } from '../operations/services/git-workflow.js';
6
- import { incrementVersion, planWorkspaceReleaseBump, applyWorkspaceVersionChanges, repoRoot } from '../operations/services/workspace-save.js';
7
- import { run, workspaceRoot } from '../operations/services/workspace-tools.js';
8
- import { runWorkspaceSavePreflight } from '../operations/services/save-deploy-preflight.js';
9
- function parseArgs(argv) {
10
- const flags = new Set(argv);
11
- const selected = ['major', 'minor', 'patch'].filter((level) => flags.has(`--${level}`));
12
- if (selected.length !== 1) {
13
- throw new Error('Treeseed release requires exactly one version bump flag: --major, --minor, or --patch.');
14
- }
15
- return { level: selected[0] };
16
- }
17
- function bumpRootPackageJson(root, level) {
18
- const packageJsonPath = resolve(root, 'package.json');
19
- const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
20
- packageJson.version = incrementVersion(packageJson.version, level);
21
- writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`, 'utf8');
22
- return packageJson.version;
23
- }
24
- const { level } = parseArgs(process.argv.slice(2));
25
- const root = workspaceRoot();
26
- const gitRoot = repoRoot(root);
27
- prepareReleaseBranches(root);
28
- applyTreeseedEnvironmentToProcess({ tenantRoot: root, scope: 'staging', override: true });
29
- runWorkspaceSavePreflight({ cwd: root });
30
- const plan = planWorkspaceReleaseBump(level, root);
31
- applyWorkspaceVersionChanges(plan);
32
- const rootVersion = bumpRootPackageJson(root, level);
33
- run('git', ['checkout', STAGING_BRANCH], { cwd: gitRoot });
34
- run('git', ['add', '-A'], { cwd: gitRoot });
35
- run('git', ['commit', '-m', `release: ${level} bump`], { cwd: gitRoot });
36
- pushBranch(gitRoot, STAGING_BRANCH);
37
- mergeStagingIntoMain(root);
38
- console.log('Treeseed release completed successfully.');
39
- console.log(`Staging branch: ${STAGING_BRANCH}`);
40
- console.log(`Production branch: ${PRODUCTION_BRANCH}`);
41
- console.log(`Release level: ${level}`);
42
- console.log(`Root version: ${rootVersion}`);
@@ -1,71 +0,0 @@
1
- #!/usr/bin/env node
2
- import { spawnSync } from 'node:child_process';
3
- import { applyTreeseedEnvironmentToProcess, assertTreeseedCommandEnvironment } from '../operations/services/config-runtime.js';
4
- import { createBranchPreviewDeployTarget, deployTargetLabel, ensureGeneratedWranglerConfig, finalizeDeploymentState, printDeploySummary, provisionCloudflareResources, runRemoteD1Migrations, syncCloudflareSecrets, validateDeployPrerequisites, } from '../operations/services/deploy.js';
5
- import { createFeatureBranchFromStaging, pushBranch } from '../operations/services/git-workflow.js';
6
- import { packageScriptPath, resolveWranglerBin } from '../operations/services/runtime-tools.js';
7
- function parseArgs(argv) {
8
- const parsed = {
9
- branchName: null,
10
- preview: false,
11
- };
12
- for (const current of argv) {
13
- if (current === '--preview') {
14
- parsed.preview = true;
15
- continue;
16
- }
17
- if (!parsed.branchName) {
18
- parsed.branchName = current;
19
- continue;
20
- }
21
- throw new Error(`Unknown start argument: ${current}`);
22
- }
23
- if (!parsed.branchName) {
24
- throw new Error('Usage: treeseed start <branch-name> [--preview]');
25
- }
26
- return parsed;
27
- }
28
- function runNodeScript(scriptPath, scriptArgs = [], cwd) {
29
- const result = spawnSync(process.execPath, [scriptPath, ...scriptArgs], {
30
- stdio: 'inherit',
31
- cwd,
32
- env: { ...process.env },
33
- });
34
- if (result.status !== 0) {
35
- process.exit(result.status ?? 1);
36
- }
37
- }
38
- function runWranglerDeploy(configPath, cwd) {
39
- const result = spawnSync(process.execPath, [resolveWranglerBin(), 'deploy', '--config', configPath], {
40
- stdio: 'inherit',
41
- cwd,
42
- env: { ...process.env },
43
- });
44
- if (result.status !== 0) {
45
- process.exit(result.status ?? 1);
46
- }
47
- }
48
- const options = parseArgs(process.argv.slice(2));
49
- const tenantRoot = process.cwd();
50
- const result = createFeatureBranchFromStaging(tenantRoot, options.branchName);
51
- pushBranch(result.repoDir, options.branchName, { setUpstream: true });
52
- if (!options.preview) {
53
- console.log(`Created feature branch ${options.branchName} from staging.`);
54
- console.log('Preview mode is disabled. Use local development for this branch.');
55
- process.exit(0);
56
- }
57
- applyTreeseedEnvironmentToProcess({ tenantRoot, scope: 'staging', override: true });
58
- assertTreeseedCommandEnvironment({ tenantRoot, scope: 'staging', purpose: 'deploy' });
59
- validateDeployPrerequisites(tenantRoot, { requireRemote: true });
60
- const target = createBranchPreviewDeployTarget(options.branchName);
61
- const summary = provisionCloudflareResources(tenantRoot, { target });
62
- printDeploySummary(summary);
63
- const { wranglerPath } = ensureGeneratedWranglerConfig(tenantRoot, { target });
64
- syncCloudflareSecrets(tenantRoot, { target });
65
- runRemoteD1Migrations(tenantRoot, { target });
66
- runNodeScript(packageScriptPath('tenant-build'), [], tenantRoot);
67
- runWranglerDeploy(wranglerPath, tenantRoot);
68
- const state = finalizeDeploymentState(tenantRoot, { target });
69
- console.log(`Treeseed start preview completed for ${options.branchName}.`);
70
- console.log(`Target: ${deployTargetLabel(target)}`);
71
- console.log(`Preview URL: ${state.lastDeployedUrl}`);