@treeseed/sdk 0.6.35 → 0.6.37

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.
@@ -420,8 +420,8 @@ function createDeprecatedTaskTag(repoDir, branchName, message) {
420
420
  return { tagName, head };
421
421
  }
422
422
  function waitForStagingAutomation(repoDir) {
423
- if (process.env.TREESEED_STAGE_WAIT_MODE === "skip" || process.env.TREESEED_GITHUB_AUTOMATION_MODE === "stub") {
424
- return { status: "skipped", reason: "stubbed" };
423
+ if (process.env.TREESEED_STAGE_WAIT_MODE === "skip") {
424
+ return { status: "skipped", reason: "disabled" };
425
425
  }
426
426
  try {
427
427
  const gh = resolveTreeseedToolBinary("gh");
@@ -22,7 +22,7 @@ export interface TreeseedGitHubRepositoryTarget {
22
22
  visibility: 'private' | 'public' | 'internal';
23
23
  source: 'config' | 'origin' | 'default';
24
24
  }
25
- export declare function getGitHubAutomationMode(): "stub" | "real";
25
+ export declare function getGitHubAutomationMode(): string;
26
26
  export declare function parseGitHubRepositoryFromRemote(remoteUrl: any): string | null;
27
27
  export declare function resolveGitHubRepositorySlug(tenantRoot: any): string;
28
28
  export declare function maybeResolveGitHubRepositorySlug(tenantRoot: any): string | null;
@@ -51,17 +51,7 @@ export declare function ensureGitHubBootstrapRepository(tenantRoot: string, { va
51
51
  pushed: boolean;
52
52
  mode: string;
53
53
  }>;
54
- export declare function createGitHubRepository(input: any): Promise<import("./github-api.ts").GitHubRepositorySummary | {
55
- visibility: any;
56
- defaultBranch: string;
57
- mode: string;
58
- slug: string;
59
- owner: string;
60
- name: string;
61
- sshUrl: string;
62
- httpsUrl: string;
63
- url: string;
64
- }>;
54
+ export declare function createGitHubRepository(input: any): Promise<import("./github-api.ts").GitHubRepositorySummary>;
65
55
  export declare function initializeGitHubRepositoryWorkingTree(cwd: any, repository: any, { defaultBranch, createStaging, commitMessage, remoteName, push, }?: {
66
56
  defaultBranch?: string | undefined;
67
57
  createStaging?: boolean | undefined;
@@ -74,14 +64,6 @@ export declare function initializeGitHubRepositoryWorkingTree(cwd: any, reposito
74
64
  defaultBranch: string;
75
65
  stagingBranch: string | null;
76
66
  pushed: boolean;
77
- mode: string;
78
- } | {
79
- repository: any;
80
- remoteName: string;
81
- defaultBranch: string;
82
- stagingBranch: string | null;
83
- pushed: boolean;
84
- mode?: undefined;
85
67
  };
86
68
  export declare function resolveGitRepositoryRoot(tenantRoot: any): any;
87
69
  export declare function requiredGitHubEnvironment(tenantRoot: any, { scope, purpose }?: {
@@ -99,38 +81,20 @@ export declare function renderHostedProjectWorkflow({ workingDirectory }: {
99
81
  workingDirectory: any;
100
82
  }): string;
101
83
  export declare function ensureDeployWorkflow(tenantRoot: any): {
102
- workflowPath: string;
103
- changed: boolean;
104
- workingDirectory: string;
105
- mode: string;
106
- } | {
107
84
  workingDirectory: string;
108
85
  workflowPath: string;
109
86
  changed: boolean;
110
- mode?: undefined;
111
87
  };
112
88
  export declare function ensureHostedProjectWorkflow(tenantRoot: any): {
113
- workflowPath: string;
114
- changed: boolean;
115
- workingDirectory: string;
116
- mode: string;
117
- } | {
118
89
  workingDirectory: string;
119
90
  workflowPath: string;
120
91
  changed: boolean;
121
- mode?: undefined;
122
92
  };
123
- export declare function ensureStandardizedGitHubWorkflows(tenantRoot: any): ({
124
- workflowPath: string;
125
- changed: boolean;
126
- workingDirectory: string;
127
- mode: string;
128
- } | {
93
+ export declare function ensureStandardizedGitHubWorkflows(tenantRoot: any): {
129
94
  workingDirectory: string;
130
95
  workflowPath: string;
131
96
  changed: boolean;
132
- mode?: undefined;
133
- })[];
97
+ }[];
134
98
  export declare function listGitHubSecretNames(repository: any, tenantRoot: any): Promise<Set<string>>;
135
99
  export declare function listGitHubVariableNames(repository: any, tenantRoot: any): Promise<Set<string>>;
136
100
  export declare function formatMissingSecretsReport(repository: any, missingSecrets: any, reason?: string): string;
@@ -139,9 +103,6 @@ export declare function ensureGitHubSecrets(tenantRoot: any, { dryRun }?: {
139
103
  }): Promise<{
140
104
  existing: never[];
141
105
  created: never[];
142
- } | {
143
- existing: never[];
144
- created: never[];
145
106
  } | {
146
107
  existing: string[];
147
108
  created: string[];
@@ -152,18 +113,6 @@ export declare function ensureGitHubEnvironment(tenantRoot: any, { dryRun, scope
152
113
  purpose?: string | undefined;
153
114
  valuesOverlay?: {} | undefined;
154
115
  }): Promise<{
155
- repository: string | null;
156
- secrets: {
157
- existing: never[];
158
- created: never[];
159
- };
160
- variables: {
161
- existing: never[];
162
- created: never[];
163
- };
164
- skipped: string;
165
- mode: string;
166
- } | {
167
116
  repository: null;
168
117
  secrets: {
169
118
  existing: never[];
@@ -174,7 +123,6 @@ export declare function ensureGitHubEnvironment(tenantRoot: any, { dryRun, scope
174
123
  created: never[];
175
124
  };
176
125
  skipped: string;
177
- mode?: undefined;
178
126
  } | {
179
127
  repository: string;
180
128
  secrets: {
@@ -186,7 +134,6 @@ export declare function ensureGitHubEnvironment(tenantRoot: any, { dryRun, scope
186
134
  created: string[];
187
135
  };
188
136
  skipped?: undefined;
189
- mode?: undefined;
190
137
  }>;
191
138
  export declare function ensureGitHubDeployAutomation(tenantRoot: any, { dryRun, valuesOverlay }?: {
192
139
  dryRun?: boolean | undefined;
@@ -194,33 +141,18 @@ export declare function ensureGitHubDeployAutomation(tenantRoot: any, { dryRun,
194
141
  }): Promise<{
195
142
  mode: string;
196
143
  workflow: {
197
- workflowPath: string;
198
- changed: boolean;
199
- workingDirectory: string;
200
- mode: string;
201
- } | {
202
144
  workingDirectory: string;
203
145
  workflowPath: string;
204
146
  changed: boolean;
205
- mode?: undefined;
206
147
  };
207
- workflows: ({
208
- workflowPath: string;
209
- changed: boolean;
210
- workingDirectory: string;
211
- mode: string;
212
- } | {
148
+ workflows: {
213
149
  workingDirectory: string;
214
150
  workflowPath: string;
215
151
  changed: boolean;
216
- mode?: undefined;
217
- })[];
152
+ }[];
218
153
  secrets: {
219
154
  existing: never[];
220
155
  created: never[];
221
- } | {
222
- existing: never[];
223
- created: never[];
224
156
  } | {
225
157
  existing: string[];
226
158
  created: string[];
@@ -228,26 +160,11 @@ export declare function ensureGitHubDeployAutomation(tenantRoot: any, { dryRun,
228
160
  variables: {
229
161
  existing: never[];
230
162
  created: never[];
231
- } | {
232
- existing: never[];
233
- created: never[];
234
163
  } | {
235
164
  existing: string[];
236
165
  created: string[];
237
166
  };
238
167
  environment: {
239
- repository: string | null;
240
- secrets: {
241
- existing: never[];
242
- created: never[];
243
- };
244
- variables: {
245
- existing: never[];
246
- created: never[];
247
- };
248
- skipped: string;
249
- mode: string;
250
- } | {
251
168
  repository: null;
252
169
  secrets: {
253
170
  existing: never[];
@@ -258,7 +175,6 @@ export declare function ensureGitHubDeployAutomation(tenantRoot: any, { dryRun,
258
175
  created: never[];
259
176
  };
260
177
  skipped: string;
261
- mode?: undefined;
262
178
  } | {
263
179
  repository: string;
264
180
  secrets: {
@@ -270,7 +186,6 @@ export declare function ensureGitHubDeployAutomation(tenantRoot: any, { dryRun,
270
186
  created: string[];
271
187
  };
272
188
  skipped?: undefined;
273
- mode?: undefined;
274
189
  };
275
190
  }>;
276
191
  export declare function waitForGitHubWorkflowCompletion(tenantRoot: any, { repository, workflow, headSha, branch, timeoutSeconds, pollSeconds, onProgress, }?: {
@@ -290,11 +205,4 @@ export declare function waitForGitHubWorkflowCompletion(tenantRoot: any, { repos
290
205
  url: string | null;
291
206
  jobs: import("./github-api.ts").GitHubWorkflowJobSummary[];
292
207
  failedJobs: import("./github-api.ts").GitHubWorkflowJobSummary[];
293
- } | {
294
- status: string;
295
- reason: string;
296
- repository: any;
297
- workflow: string;
298
- headSha: any;
299
- branch: any;
300
208
  }>;
@@ -22,10 +22,7 @@ function slugifySegment(value, fallback = "project") {
22
22
  return String(value ?? "").trim().toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "").replace(/-{2,}/g, "-").slice(0, 96) || fallback;
23
23
  }
24
24
  function getGitHubAutomationMode() {
25
- return process.env.TREESEED_GITHUB_AUTOMATION_MODE === "stub" ? "stub" : "real";
26
- }
27
- function isGitHubAutomationStubbed() {
28
- return getGitHubAutomationMode() === "stub";
25
+ return "real";
29
26
  }
30
27
  function parseGitHubRepositoryFromRemote(remoteUrl) {
31
28
  if (!remoteUrl) {
@@ -170,17 +167,6 @@ async function ensureGitHubBootstrapRepository(tenantRoot, {
170
167
  const remotes = resolveGitHubRemoteUrls(target.owner, target.name);
171
168
  const slug = remotes.slug;
172
169
  onProgress?.(`[local][github][repo] Preparing ${slug} from ${target.source}...`);
173
- if (isGitHubAutomationStubbed()) {
174
- onProgress?.(`[local][github][repo] Stubbed GitHub automation; repository ${slug} not changed.`);
175
- return {
176
- repository: slug,
177
- target,
178
- created: false,
179
- remote: { changed: false, previous: null, next: remotes.sshUrl },
180
- pushed: false,
181
- mode: "stub"
182
- };
183
- }
184
170
  const client = createGitHubApiClient({
185
171
  env: {
186
172
  GH_TOKEN: configuredValue(values, "GH_TOKEN") || configuredValue(values, "GITHUB_TOKEN"),
@@ -217,14 +203,6 @@ async function ensureGitHubBootstrapRepository(tenantRoot, {
217
203
  async function createGitHubRepository(input) {
218
204
  const visibility = input.visibility ?? "private";
219
205
  const remotes = resolveGitHubRemoteUrls(input.owner, input.name);
220
- if (isGitHubAutomationStubbed()) {
221
- return {
222
- ...remotes,
223
- visibility,
224
- defaultBranch: "main",
225
- mode: "stub"
226
- };
227
- }
228
206
  return await ensureGitHubRepository({
229
207
  owner: remotes.owner,
230
208
  name: remotes.name,
@@ -243,16 +221,6 @@ function initializeGitHubRepositoryWorkingTree(cwd, repository, {
243
221
  remoteName = "origin",
244
222
  push = true
245
223
  } = {}) {
246
- if (isGitHubAutomationStubbed()) {
247
- return {
248
- repository,
249
- remoteName,
250
- defaultBranch,
251
- stagingBranch: createStaging ? "staging" : null,
252
- pushed: false,
253
- mode: "stub"
254
- };
255
- }
256
224
  runGit(["init", "-b", defaultBranch], { cwd, allowFailure: true });
257
225
  ensureGitIdentity(cwd);
258
226
  const currentRemote = runGit(["remote", "get-url", remoteName], { cwd, allowFailure: true }).stdout?.trim() ?? "";
@@ -348,14 +316,6 @@ function ensureWorkflowFile(tenantRoot, fileName, expected) {
348
316
  return { workflowPath, changed: true };
349
317
  }
350
318
  function ensureDeployWorkflow(tenantRoot) {
351
- if (isGitHubAutomationStubbed()) {
352
- return {
353
- workflowPath: resolve(tenantRoot, ".github", "workflows", "deploy.yml"),
354
- changed: false,
355
- workingDirectory: ".",
356
- mode: "stub"
357
- };
358
- }
359
319
  const repositoryRoot = resolveGitRepositoryRoot(tenantRoot);
360
320
  const workingDirectory = relative(repositoryRoot, tenantRoot).replaceAll("\\", "/") || ".";
361
321
  const expected = renderDeployWorkflow({ workingDirectory });
@@ -365,14 +325,6 @@ function ensureDeployWorkflow(tenantRoot) {
365
325
  };
366
326
  }
367
327
  function ensureHostedProjectWorkflow(tenantRoot) {
368
- if (isGitHubAutomationStubbed()) {
369
- return {
370
- workflowPath: resolve(tenantRoot, ".github", "workflows", "hosted-project.yml"),
371
- changed: false,
372
- workingDirectory: ".",
373
- mode: "stub"
374
- };
375
- }
376
328
  const repositoryRoot = resolveGitRepositoryRoot(tenantRoot);
377
329
  const workingDirectory = relative(repositoryRoot, tenantRoot).replaceAll("\\", "/") || ".";
378
330
  const expected = renderHostedProjectWorkflow({ workingDirectory });
@@ -419,21 +371,6 @@ function nonEmptyValues(values = {}) {
419
371
  );
420
372
  }
421
373
  async function ensureGitHubEnvironment(tenantRoot, { dryRun = false, scope = "prod", purpose = "save", valuesOverlay = {} } = {}) {
422
- if (isGitHubAutomationStubbed()) {
423
- return {
424
- repository: maybeResolveGitHubRepositorySlug(tenantRoot),
425
- secrets: {
426
- existing: [],
427
- created: []
428
- },
429
- variables: {
430
- existing: [],
431
- created: []
432
- },
433
- skipped: "stubbed",
434
- mode: "stub"
435
- };
436
- }
437
374
  const repository = maybeResolveGitHubRepositorySlug(tenantRoot);
438
375
  if (!repository) {
439
376
  if (dryRun) {
@@ -518,16 +455,6 @@ async function waitForGitHubWorkflowCompletion(tenantRoot, {
518
455
  pollSeconds = 5,
519
456
  onProgress
520
457
  } = {}) {
521
- if (isGitHubAutomationStubbed()) {
522
- return {
523
- status: "skipped",
524
- reason: "stubbed",
525
- repository: repository ?? maybeResolveGitHubRepositorySlug(tenantRoot),
526
- workflow,
527
- headSha: headSha ?? null,
528
- branch: branch ?? null
529
- };
530
- }
531
458
  const repo = repository ?? resolveGitHubRepositorySlug(tenantRoot);
532
459
  return await waitForGitHubWorkflowRunCompletion(repo, {
533
460
  client: createGitHubApiClient(),
@@ -4,7 +4,7 @@ import { cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, write
4
4
  import { tmpdir } from "node:os";
5
5
  import { dirname, join, relative, resolve } from "node:path";
6
6
  import { isTreeseedEnvironmentEntryRelevant, isTreeseedEnvironmentEntryRequired } from "../../platform/environment.js";
7
- import { getGitHubAutomationMode, maybeResolveGitHubRepositorySlug } from "./github-automation.js";
7
+ import { maybeResolveGitHubRepositorySlug } from "./github-automation.js";
8
8
  import { createGitHubApiClient, listGitHubEnvironmentSecretNames, listGitHubEnvironmentVariableNames } from "./github-api.js";
9
9
  import { collectInternalDevReferenceIssues } from "./package-reference-policy.js";
10
10
  import { collectTreeseedEnvironmentContext, resolveTreeseedMachineEnvironmentValues, validateTreeseedCommandEnvironment } from "./config-runtime.js";
@@ -123,9 +123,6 @@ function packageReadinessChecks(root, selectedPackageNames, failures) {
123
123
  if (selectedPackageNames.length === 0) {
124
124
  return { name: "package-release-readiness", status: "skipped", detail: "No packages are selected for this release." };
125
125
  }
126
- if (getGitHubAutomationMode() === "stub") {
127
- return { name: "package-release-readiness", status: "skipped", detail: "GitHub automation is stubbed." };
128
- }
129
126
  const selected = new Set(selectedPackageNames);
130
127
  const packages = workspacePackages(root).filter((pkg) => selected.has(pkg.name));
131
128
  for (const pkg of packages) {
@@ -266,8 +263,8 @@ function buildRehearsalWorkspacePackageArtifacts(root) {
266
263
  }
267
264
  }
268
265
  function runProductionDependencyRehearsal(root, plannedVersions, selectedPackageNames, failures) {
269
- if (getGitHubAutomationMode() === "stub" || process.env.TREESEED_RELEASE_CANDIDATE_REHEARSAL_MODE === "skip") {
270
- return "Skipped clean install rehearsal in stub/skip mode.";
266
+ if (process.env.TREESEED_RELEASE_CANDIDATE_REHEARSAL_MODE === "skip") {
267
+ return "Skipped clean install rehearsal by request.";
271
268
  }
272
269
  const selectedPackageSet = new Set(selectedPackageNames);
273
270
  let tempParent = null;
@@ -379,9 +376,6 @@ function localConfigCheck(root, scope, failures) {
379
376
  }
380
377
  }
381
378
  async function githubRemoteConfigCheck(root, scope, failures) {
382
- if (getGitHubAutomationMode() === "stub") {
383
- return;
384
- }
385
379
  const repository = maybeResolveGitHubRepositorySlug(root);
386
380
  if (!repository) {
387
381
  addFailure(failures, {
@@ -490,8 +484,8 @@ function providerResourceIdentifierCheck(root, scope, failures) {
490
484
  }
491
485
  }
492
486
  async function configParityChecks(root, failures) {
493
- if (getGitHubAutomationMode() === "stub") {
494
- return { name: "config-parity", status: "skipped", detail: "GitHub automation is stubbed." };
487
+ if (process.env.TREESEED_RELEASE_CANDIDATE_CONFIG_PARITY_MODE === "skip") {
488
+ return { name: "config-parity", status: "skipped", detail: "Remote config parity skipped by request." };
495
489
  }
496
490
  const before = failures.length;
497
491
  localConfigCheck(root, "staging", failures);
@@ -2,7 +2,6 @@ import { existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "no
2
2
  import { tmpdir } from "node:os";
3
3
  import { basename, resolve, relative } from "node:path";
4
4
  import { spawn, spawnSync } from "node:child_process";
5
- import { getGitHubAutomationMode } from "./github-automation.js";
6
5
  import {
7
6
  ensureSshPushUrlForOrigin,
8
7
  remoteWriteUrl,
@@ -578,7 +577,7 @@ function applyPackageVersion(node, version) {
578
577
  return true;
579
578
  }
580
579
  function shouldSkipNetworkInstall() {
581
- return getGitHubAutomationMode() === "stub" || process.env.TREESEED_SAVE_NPM_INSTALL_MODE === "skip";
580
+ return process.env.TREESEED_SAVE_NPM_INSTALL_MODE === "skip";
582
581
  }
583
582
  function shouldSkipGitDependencySmoke(options) {
584
583
  return shouldSkipNetworkInstall() || process.env.TREESEED_GIT_DEPENDENCY_SMOKE === "skip" || options?.verifyMode === "skip";
@@ -628,7 +627,7 @@ async function runGitDependencySmoke(node, options, reference) {
628
627
  async function runNpmInstallWithRetry(node, options, gitDependencyRefreshSpecs = []) {
629
628
  if (shouldSkipNetworkInstall()) {
630
629
  emitProgress(options, node, "install", "Skipped npm install because network install mode is disabled.");
631
- return { status: "skipped", attempts: 0, reason: "stubbed" };
630
+ return { status: "skipped", attempts: 0, reason: "disabled" };
632
631
  }
633
632
  let lastError = null;
634
633
  const packageJson = node.packageJson ?? (existsSync(resolve(node.path, "package.json")) ? readJson(resolve(node.path, "package.json")) : null);
@@ -678,7 +677,7 @@ async function validateRepositoryLockfile(node, options) {
678
677
  const commandText = `${command} ${args.join(" ")}`;
679
678
  if (shouldSkipNetworkInstall()) {
680
679
  emitProgress(options, node, "lockfile", `Skipped ${commandText} because network install mode is disabled.`);
681
- return { status: "skipped", command: commandText, issues: [], error: "stubbed" };
680
+ return { status: "skipped", command: commandText, issues: [], error: "disabled" };
682
681
  }
683
682
  try {
684
683
  runCapturedCommand(node, options, "lockfile", command, args, { timeoutMs: 12e4, emitOutputOnSuccess: false });
@@ -710,9 +709,9 @@ async function runScript(node, options, scriptName) {
710
709
  await runStreamingCommand(node, options, "verify", "npm", ["run", scriptName]);
711
710
  }
712
711
  async function runRepoVerification(node, options, verifyMode) {
713
- if (verifyMode === "skip" || getGitHubAutomationMode() === "stub") {
714
- emitProgress(options, node, "verify", getGitHubAutomationMode() === "stub" ? "Skipped verification in stub automation mode." : "Skipped verification by request.");
715
- return { mode: verifyMode, status: "skipped", primary: null, fallbackUsed: false, error: getGitHubAutomationMode() === "stub" ? "stubbed" : null };
712
+ if (verifyMode === "skip") {
713
+ emitProgress(options, node, "verify", "Skipped verification by request.");
714
+ return { mode: verifyMode, status: "skipped", primary: null, fallbackUsed: false, error: null };
716
715
  }
717
716
  if (node.kind !== "package") {
718
717
  emitProgress(options, node, "verify", "Skipped package verification for project repository.");
@@ -897,7 +896,7 @@ function ensureRemoteAccessBeforeVerification(node, options, state) {
897
896
  }
898
897
  }
899
898
  function shouldSkipRemoteAccessPreflight() {
900
- return getGitHubAutomationMode() === "stub" || process.env.TREESEED_SAVE_REMOTE_PREFLIGHT === "skip";
899
+ return process.env.TREESEED_SAVE_REMOTE_PREFLIGHT === "skip";
901
900
  }
902
901
  function localTreeseedTagWasCreatedByThisRun(node, tagName, workflowRunId) {
903
902
  const message = localTagMessage(node.path, tagName);
@@ -1,11 +1,6 @@
1
1
  export declare function validateSaveAutomationPrerequisites({ cwd }: {
2
2
  cwd: any;
3
3
  }): {
4
- ok: boolean;
5
- mode: string;
6
- missingEnv: never[];
7
- preflight: null;
8
- } | {
9
4
  ok: boolean;
10
5
  mode: string;
11
6
  missingEnv: never[];
@@ -2,7 +2,7 @@ import { spawnSync } from "node:child_process";
2
2
  import { packageScriptPath } from "./runtime-tools.js";
3
3
  import { applyTreeseedEnvironmentToProcess, assertTreeseedCommandEnvironment } from "./config-runtime.js";
4
4
  import { collectCliPreflight } from "./workspace-preflight.js";
5
- import { getGitHubAutomationMode, requiredGitHubEnvironment } from "./github-automation.js";
5
+ import { requiredGitHubEnvironment } from "./github-automation.js";
6
6
  function runStep(label, scriptName, { cwd, env } = {}) {
7
7
  const result = spawnSync(process.execPath, [packageScriptPath(scriptName)], {
8
8
  cwd,
@@ -25,14 +25,6 @@ function missingRequiredEnv(requiredKeys) {
25
25
  function validateSaveAutomationPrerequisites({ cwd }) {
26
26
  applyTreeseedEnvironmentToProcess({ tenantRoot: cwd, scope: "prod", override: true });
27
27
  assertTreeseedCommandEnvironment({ tenantRoot: cwd, scope: "prod", purpose: "save" });
28
- if (getGitHubAutomationMode() !== "real") {
29
- return {
30
- ok: true,
31
- mode: "stub",
32
- missingEnv: [],
33
- preflight: null
34
- };
35
- }
36
28
  const preflight = collectCliPreflight({ cwd, requireAuth: true });
37
29
  if (!preflight.ok) {
38
30
  const error = new Error("Treeseed save prerequisites failed: required GitHub, Cloudflare, or Railway tokens are missing.");
@@ -346,7 +346,7 @@ function appendSaveMarker(filePath, marker) {
346
346
  }
347
347
  function writeWorkspaceStub(repoDir) {
348
348
  writeFileSync(resolve(repoDir, 'package.json'), `${JSON.stringify({
349
- name: 'treeseed-save-stub',
349
+ name: 'treeseed-save-local',
350
350
  private: true,
351
351
  workspaces: ['packages/*'],
352
352
  }, null, 2)}\n`, 'utf8');
@@ -556,7 +556,7 @@ async function runLocalSuite() {
556
556
  rmSync(clonedWorkspace.cloneRoot, { recursive: true, force: true });
557
557
  }
558
558
  });
559
- await withStep('save success: local bare origin with stubbed automation', async () => {
559
+ await withStep('save success: local bare origin with local-only install checks', async () => {
560
560
  const clonedWorkspace = cloneLocalWorkspaceWithBareOrigin();
561
561
  try {
562
562
  const notePath = resolve(clonedWorkspace.workingRoot, 'src/content/notes/first-note.mdx');
@@ -566,7 +566,7 @@ async function runLocalSuite() {
566
566
  cwd: clonedWorkspace.workingRoot,
567
567
  env: {
568
568
  ...cacheEnv(),
569
- TREESEED_GITHUB_AUTOMATION_MODE: 'stub',
569
+ TREESEED_SAVE_NPM_INSTALL_MODE: 'skip',
570
570
  TREESEED_SAVE_REPORT_PATH: saveReportPath,
571
571
  },
572
572
  timeoutMs: 1800000,
@@ -101,7 +101,6 @@ jobs:
101
101
  working-directory: ${relativePackageRoot}
102
102
  env:
103
103
  CI: "true"
104
- TREESEED_GITHUB_AUTOMATION_MODE: stub
105
104
  TREESEED_STAGE_WAIT_MODE: skip
106
105
  TREESEED_AGENT_DISABLE_GIT: "true"
107
106
  TREESEED_FIXTURE_ID: treeseed-working-site
@@ -68,7 +68,7 @@ import {
68
68
  squashMergeBranchIntoStaging,
69
69
  syncBranchWithOrigin
70
70
  } from "../operations/services/git-workflow.js";
71
- import { getGitHubAutomationMode, resolveGitHubRepositorySlug } from "../operations/services/github-automation.js";
71
+ import { resolveGitHubRepositorySlug } from "../operations/services/github-automation.js";
72
72
  import {
73
73
  formatGitHubActionsGateFailure,
74
74
  inspectGitHubActionsVerification,
@@ -338,9 +338,6 @@ function shouldDispatchSwitchToManagedWorktree(root, input, env) {
338
338
  return !isManagedWorkflowWorktree(root) && effectiveWorkflowWorktreeMode(input.worktreeMode, env) === "on";
339
339
  }
340
340
  function assertHostedGitHubWorkflowAuthReady(operation, root) {
341
- if (getGitHubAutomationMode() === "stub") {
342
- return null;
343
- }
344
341
  const tools = collectTreeseedToolStatus({
345
342
  tenantRoot: root,
346
343
  env: process.env
@@ -372,7 +369,7 @@ function assertHostedGitHubWorkflowAuthReady(operation, root) {
372
369
  }
373
370
  async function waitForWorkflowGates(operation, gates, ciMode, options = {}) {
374
371
  if (ciMode === "off" || process.env.TREESEED_STAGE_WAIT_MODE === "skip") {
375
- return gates.map((gate) => skippedGitHubActionsGate(gate, ciMode === "off" ? "disabled" : "stubbed"));
372
+ return gates.map((gate) => skippedGitHubActionsGate(gate, "disabled"));
376
373
  }
377
374
  if (gates.length === 0) {
378
375
  return [];
@@ -452,10 +449,10 @@ function recordHostedDeploymentStatesFromRootGates(root, rootRelease, workflowGa
452
449
  return reports;
453
450
  }
454
451
  function ensureTreeseedCommandReadiness(root) {
455
- if (getGitHubAutomationMode() === "stub") {
452
+ if (process.env.TREESEED_COMMAND_READINESS_MODE === "skip") {
456
453
  return {
457
454
  status: "skipped",
458
- reason: "stubbed",
455
+ reason: "disabled",
459
456
  checks: [],
460
457
  missing: []
461
458
  };
@@ -1368,9 +1365,6 @@ function failWorkflowRun(root, runId, error, recovery) {
1368
1365
  releaseWorkflowLock(root, runId);
1369
1366
  }
1370
1367
  function validatePackageReleaseWorkflows(root, packageNames) {
1371
- if (process.env.TREESEED_GITHUB_AUTOMATION_MODE === "stub") {
1372
- return;
1373
- }
1374
1368
  const missing = checkedOutWorkspacePackageRepos(root).filter((pkg) => packageNames.includes(pkg.name)).filter((pkg) => !existsSync(resolve(pkg.dir, ".github", "workflows", "publish.yml"))).map((pkg) => pkg.name);
1375
1369
  if (missing.length > 0) {
1376
1370
  workflowError("release", "workflow_contract_missing", `Treeseed release requires .github/workflows/publish.yml in: ${missing.join(", ")}.`, {
@@ -1381,7 +1375,7 @@ function validatePackageReleaseWorkflows(root, packageNames) {
1381
1375
  }
1382
1376
  }
1383
1377
  function validateStagingWorkflowContracts(root) {
1384
- if (process.env.TREESEED_GITHUB_AUTOMATION_MODE === "stub" || process.env.TREESEED_STAGE_WAIT_MODE === "skip") {
1378
+ if (process.env.TREESEED_STAGE_WAIT_MODE === "skip") {
1385
1379
  return;
1386
1380
  }
1387
1381
  const missing = [];
@@ -1397,11 +1391,11 @@ function validateStagingWorkflowContracts(root) {
1397
1391
  }
1398
1392
  }
1399
1393
  function shouldSkipReleaseInstall() {
1400
- return process.env.TREESEED_GITHUB_AUTOMATION_MODE === "stub" || process.env.TREESEED_SAVE_NPM_INSTALL_MODE === "skip";
1394
+ return process.env.TREESEED_SAVE_NPM_INSTALL_MODE === "skip";
1401
1395
  }
1402
1396
  function runReleaseNpmInstall(repoDir, options = {}) {
1403
1397
  if (shouldSkipReleaseInstall()) {
1404
- return { status: "skipped", reason: "stubbed" };
1398
+ return { status: "skipped", reason: "disabled" };
1405
1399
  }
1406
1400
  const args = repoDir === options.workspaceRoot ? ["install", "--package-lock-only", "--ignore-scripts"] : ["install", "--package-lock-only", "--ignore-scripts", "--workspaces=false"];
1407
1401
  run("npm", args, { cwd: repoDir });
@@ -1590,8 +1584,8 @@ function collectReleasePlanBlockers(session, mode, selectedPackageNames) {
1590
1584
  }
1591
1585
  return blockers;
1592
1586
  }
1593
- function assertReleaseGitHubAutomationReady(root, selectedPackageNames) {
1594
- if (process.env.TREESEED_GITHUB_AUTOMATION_MODE === "stub") {
1587
+ function assertReleaseGitHubAutomationReady(root, selectedPackageNames, ciMode) {
1588
+ if (ciMode === "off") {
1595
1589
  return;
1596
1590
  }
1597
1591
  assertHostedGitHubWorkflowAuthReady("release", root);
@@ -3494,7 +3488,10 @@ async function workflowRelease(helpers, input) {
3494
3488
  const freshPreparation = freshRelease && executionMode === "execute" ? prepareFreshReleaseRun(root, session.branchName, rootRepo, packageReports) : { archived: [], blockers: [] };
3495
3489
  const autoResumeRun = executionMode === "execute" && !explicitResumeRunId && !freshRelease ? findAutoResumableReleaseRun(root, session.branchName, rootRepo, packageReports) : null;
3496
3490
  const planAutoResumeRun = executionMode === "plan" && input.fresh !== true ? findAutoResumableReleaseRun(root, session.branchName, rootRepo, packageReports) : null;
3497
- const effectiveInput = autoResumeRun ? autoResumeRun.input : input;
3491
+ const effectiveInput = autoResumeRun ? {
3492
+ ...autoResumeRun.input,
3493
+ ciMode: input.ciMode ?? autoResumeRun.input.ciMode
3494
+ } : input;
3498
3495
  const level = effectiveInput.bump ?? "patch";
3499
3496
  const ciMode = normalizeCiMode(effectiveInput.ciMode, "release");
3500
3497
  const isResume = Boolean(explicitResumeRunId || autoResumeRun);
@@ -3584,7 +3581,7 @@ async function workflowRelease(helpers, input) {
3584
3581
  const effectiveVersions = releasePlanVersionMap(releasePlan.plannedVersions);
3585
3582
  const rootVersion = String(releasePlan.rootVersion);
3586
3583
  applyTreeseedEnvironmentToProcess({ tenantRoot: root, scope: "staging", override: true });
3587
- assertReleaseGitHubAutomationReady(root, effectiveSelectedPackageNames);
3584
+ assertReleaseGitHubAutomationReady(root, effectiveSelectedPackageNames, ciMode);
3588
3585
  const releaseCandidate = await executeJournalStep(root, workflowRun.runId, "release-candidate", () => runReleaseCandidateForPlan("release", root, releasePlan, { allowReuse: true }));
3589
3586
  if (!isResume) {
3590
3587
  assertSessionBranchSafety("release", session, { requireCleanPackages: true, requireCurrentBranch: true });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treeseed/sdk",
3
- "version": "0.6.35",
3
+ "version": "0.6.37",
4
4
  "description": "Shared Treeseed SDK for content-backed and D1-backed object models.",
5
5
  "license": "AGPL-3.0-only",
6
6
  "repository": {