@treeseed/cli 0.6.9 → 0.6.11

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.
@@ -4,6 +4,7 @@ const handleClose = async (invocation, context) => {
4
4
  try {
5
5
  const result = await createWorkflowSdk(context).close({
6
6
  message: invocation.positionals.join(" ").trim(),
7
+ worktreeMode: typeof invocation.args.worktreeMode === "string" ? invocation.args.worktreeMode : void 0,
7
8
  workspaceLinks: typeof invocation.args.workspaceLinks === "string" ? invocation.args.workspaceLinks : void 0,
8
9
  plan: invocation.args.plan === true || invocation.args.dryRun === true,
9
10
  dryRun: invocation.args.dryRun === true
@@ -17,10 +18,12 @@ const handleClose = async (invocation, context) => {
17
18
  { label: "Mode", value: payload.mode },
18
19
  { label: "Closed branch", value: payload.branchName },
19
20
  { label: "Auto-saved", value: payload.autoSaved ? "yes" : "no" },
20
- { label: "Deprecated tag", value: payload.rootRepo.tagName ?? payload.deprecatedTag.tagName },
21
+ { label: "Deprecated tag", value: payload.rootRepo.tagName ?? payload.deprecatedTag?.tagName ?? "(planned)" },
21
22
  { label: "Package branches cleaned", value: String(deletedPackages) },
22
- { label: "Preview cleanup", value: payload.previewCleanup.performed ? "performed" : "not needed" },
23
- { label: "Final branch", value: payload.finalBranch }
23
+ { label: "Preview cleanup", value: payload.previewCleanup?.performed ? "performed" : result.executionMode === "plan" ? "planned" : "not needed" },
24
+ { label: "Worktree cleanup", value: payload.worktreeCleanup?.removed ? "removed" : "not needed" },
25
+ { label: "Worktree path", value: payload.worktreePath ?? "(in-place)" },
26
+ { label: "Final branch", value: payload.finalBranch ?? "staging" }
24
27
  ],
25
28
  nextSteps: renderWorkflowNextSteps(result),
26
29
  report: result
@@ -3,7 +3,10 @@ import { createWorkflowSdk, workflowErrorResult } from "./workflow.js";
3
3
  const handleExport = async (invocation, context) => {
4
4
  try {
5
5
  const directory = typeof invocation.positionals[0] === "string" && invocation.positionals[0].trim().length > 0 ? invocation.positionals[0] : void 0;
6
- const result = await createWorkflowSdk(context).export({ directory });
6
+ const result = await createWorkflowSdk(context).export({
7
+ directory,
8
+ worktreeMode: typeof invocation.args.worktreeMode === "string" ? invocation.args.worktreeMode : void 0
9
+ });
7
10
  const exported = result.payload;
8
11
  return guidedResult({
9
12
  command: "export",
@@ -15,7 +18,8 @@ const handleExport = async (invocation, context) => {
15
18
  { label: "Timestamp", value: exported.timestamp },
16
19
  { label: "Files", value: exported.summary?.totalFiles },
17
20
  { label: "Tokens", value: exported.summary?.totalTokens },
18
- { label: "Bundled paths", value: Array.isArray(exported.includedBundlePaths) ? exported.includedBundlePaths.length : 0 }
21
+ { label: "Bundled paths", value: Array.isArray(exported.includedBundlePaths) ? exported.includedBundlePaths.length : 0 },
22
+ { label: "Worktree path", value: exported.worktreePath ?? "(in-place)" }
19
23
  ],
20
24
  report: exported
21
25
  });
@@ -1,8 +1,10 @@
1
1
  import { guidedResult } from "./utils.js";
2
2
  import { createWorkflowSdk, renderWorkflowNextSteps, workflowErrorResult } from "./workflow.js";
3
- const handleRecover = async (_invocation, context) => {
3
+ const handleRecover = async (invocation, context) => {
4
4
  try {
5
- const result = await createWorkflowSdk(context).recover({});
5
+ const result = await createWorkflowSdk(context).recover({
6
+ pruneStale: invocation.args.pruneStale === true
7
+ });
6
8
  const payload = result.payload;
7
9
  return guidedResult({
8
10
  command: "recover",
@@ -11,6 +13,8 @@ const handleRecover = async (_invocation, context) => {
11
13
  { label: "Active lock", value: payload.lock.active ? "yes" : "no" },
12
14
  { label: "Stale lock", value: payload.lock.stale ? "yes" : "no" },
13
15
  { label: "Interrupted runs", value: payload.interruptedRuns.length },
16
+ { label: "Stale runs", value: payload.staleRuns?.length ?? 0 },
17
+ { label: "Pruned runs", value: payload.prunedRuns?.length ?? 0 },
14
18
  { label: "Recorded runs", value: payload.runCount }
15
19
  ],
16
20
  nextSteps: renderWorkflowNextSteps(result),
@@ -58,6 +58,8 @@ const handleRelease = async (invocation, context) => {
58
58
  const bump = ["major", "minor", "patch"].find((candidate) => invocation.args[candidate] === true) ?? "patch";
59
59
  const result = await createWorkflowSdk(context).release({
60
60
  bump,
61
+ worktreeMode: typeof invocation.args.worktreeMode === "string" ? invocation.args.worktreeMode : void 0,
62
+ ciMode: typeof invocation.args.ciMode === "string" ? invocation.args.ciMode : void 0,
61
63
  workspaceLinks: typeof invocation.args.workspaceLinks === "string" ? invocation.args.workspaceLinks : void 0,
62
64
  plan: invocation.args.plan === true || invocation.args.dryRun === true,
63
65
  dryRun: invocation.args.dryRun === true
@@ -83,6 +85,9 @@ const handleRelease = async (invocation, context) => {
83
85
  { label: "Dependent packages", value: String(payload.packageSelection.dependents.length) },
84
86
  { label: result.executionMode === "plan" ? "Packages planned" : "Released packages", value: String((payload.touchedPackages ?? payload.packageSelection.selected).length) },
85
87
  { label: "Publish waits", value: result.executionMode === "plan" ? String(plannedPublishes) : String(completedPublishes) },
88
+ { label: "CI mode", value: payload.ciMode ?? "auto" },
89
+ { label: "Workflow gates", value: String(payload.workflowGates?.length ?? 0) },
90
+ { label: "Worktree path", value: payload.worktreePath ?? "(in-place)" },
86
91
  { label: "Final branch", value: payload.finalBranch ?? (result.executionMode === "plan" ? payload.stagingBranch : "(unknown)") }
87
92
  ],
88
93
  sections: result.executionMode === "plan" ? formatReleasePlanSections(payload) : [],
@@ -51,6 +51,9 @@ const handleSave = async (invocation, context) => {
51
51
  message: invocation.positionals.join(" ").trim(),
52
52
  hotfix: invocation.args.hotfix === true,
53
53
  preview: invocation.args.preview === true,
54
+ worktreeMode: typeof invocation.args.worktreeMode === "string" ? invocation.args.worktreeMode : void 0,
55
+ ciMode: typeof invocation.args.ciMode === "string" ? invocation.args.ciMode : void 0,
56
+ verifyMode: typeof invocation.args.verifyMode === "string" ? invocation.args.verifyMode : void 0,
54
57
  workspaceLinks: typeof invocation.args.workspaceLinks === "string" ? invocation.args.workspaceLinks : void 0,
55
58
  plan: invocation.args.plan === true || invocation.args.dryRun === true,
56
59
  dryRun: invocation.args.dryRun === true
@@ -78,7 +81,10 @@ const handleSave = async (invocation, context) => {
78
81
  value: result.executionMode === "plan" ? plannedRepos || "not applicable" : savedRepos || ((payload.repos ?? []).length > 0 ? "none saved" : "not applicable")
79
82
  },
80
83
  { label: "Market pushed", value: payload.rootRepo?.pushed ? "yes" : "no" },
81
- { label: "Preview action", value: payload.previewAction?.status ?? "skipped" }
84
+ { label: "Preview action", value: payload.previewAction?.status ?? "skipped" },
85
+ { label: "CI mode", value: payload.ciMode ?? "auto" },
86
+ { label: "Workflow gates", value: String(payload.workflowGates?.length ?? 0) },
87
+ { label: "Worktree path", value: payload.worktreePath ?? "(in-place)" }
82
88
  ],
83
89
  sections: result.executionMode === "plan" ? [
84
90
  ...payload.plannedSteps?.length ? [{ title: "Dependency mode transitions", lines: payload.plannedSteps.filter((step) => /workspace-(?:link|unlink)/u.test(String(step.id ?? ""))).map((step) => `- ${step.description ?? step.id}`) }] : [],
@@ -4,6 +4,8 @@ const handleStage = async (invocation, context) => {
4
4
  try {
5
5
  const result = await createWorkflowSdk(context).stage({
6
6
  message: invocation.positionals.join(" ").trim(),
7
+ worktreeMode: typeof invocation.args.worktreeMode === "string" ? invocation.args.worktreeMode : void 0,
8
+ ciMode: typeof invocation.args.ciMode === "string" ? invocation.args.ciMode : void 0,
7
9
  workspaceLinks: typeof invocation.args.workspaceLinks === "string" ? invocation.args.workspaceLinks : void 0,
8
10
  plan: invocation.args.plan === true || invocation.args.dryRun === true,
9
11
  dryRun: invocation.args.dryRun === true
@@ -19,11 +21,14 @@ const handleStage = async (invocation, context) => {
19
21
  { label: "Merge target", value: payload.mergeTarget },
20
22
  { label: "Merge strategy", value: payload.mergeStrategy },
21
23
  { label: "Auto-saved", value: payload.autoSaved ? "yes" : "no" },
22
- { label: "Deprecated tag", value: payload.rootRepo.tagName ?? payload.deprecatedTag.tagName },
24
+ { label: "Deprecated tag", value: payload.rootRepo.tagName ?? payload.deprecatedTag?.tagName ?? "(planned)" },
23
25
  { label: "Package merges", value: String(mergedPackages) },
24
- { label: "Staging wait", value: payload.stagingWait.status },
25
- { label: "Preview cleanup", value: payload.previewCleanup.performed ? "performed" : "not needed" },
26
- { label: "Final branch", value: payload.finalBranch }
26
+ { label: "Staging wait", value: payload.stagingWait?.status ?? (result.executionMode === "plan" ? "planned" : "unknown") },
27
+ { label: "Workflow gates", value: String(payload.workflowGates?.length ?? 0) },
28
+ { label: "Preview cleanup", value: payload.previewCleanup?.performed ? "performed" : result.executionMode === "plan" ? "planned" : "not needed" },
29
+ { label: "Worktree cleanup", value: payload.worktreeCleanup?.removed ? "removed" : "not needed" },
30
+ { label: "Worktree path", value: payload.worktreePath ?? "(in-place)" },
31
+ { label: "Final branch", value: payload.finalBranch ?? payload.mergeTarget }
27
32
  ],
28
33
  nextSteps: renderWorkflowNextSteps(result),
29
34
  report: result
@@ -6,6 +6,7 @@ const handleSwitch = async (invocation, context) => {
6
6
  const result = await createWorkflowSdk(context).switchTask({
7
7
  branch,
8
8
  preview: invocation.args.preview === true,
9
+ worktreeMode: typeof invocation.args.worktreeMode === "string" ? invocation.args.worktreeMode : void 0,
9
10
  workspaceLinks: typeof invocation.args.workspaceLinks === "string" ? invocation.args.workspaceLinks : void 0,
10
11
  plan: invocation.args.plan === true || invocation.args.dryRun === true,
11
12
  dryRun: invocation.args.dryRun === true
@@ -22,8 +23,10 @@ const handleSwitch = async (invocation, context) => {
22
23
  { label: "Market created", value: payload.rootRepo.created ? "yes" : "no" },
23
24
  { label: "Package branches created", value: String(packageCreated) },
24
25
  { label: "Package branches resumed", value: String(packageResumed) },
25
- { label: "Preview", value: payload.preview.enabled ? "enabled" : "disabled" },
26
- { label: "Preview URL", value: payload.preview.url ?? "(none)" }
26
+ { label: "Preview", value: payload.preview?.enabled ? "enabled" : payload.previewRequested ? "planned" : "disabled" },
27
+ { label: "Preview URL", value: payload.preview?.url ?? "(none)" },
28
+ { label: "Worktree mode", value: payload.worktreeMode ?? "auto" },
29
+ { label: "Worktree path", value: payload.worktreePath ?? "(in-place)" }
27
30
  ],
28
31
  nextSteps: renderWorkflowNextSteps(result),
29
32
  report: result
@@ -208,6 +208,7 @@ const CLI_COMMAND_OVERLAYS = /* @__PURE__ */ new Map([
208
208
  arguments: [{ name: "branch-name", description: "Task branch to create or resume.", required: true }],
209
209
  options: [
210
210
  { name: "preview", flags: "--preview", description: "Provision or refresh a branch-scoped Cloudflare preview environment.", kind: "boolean" },
211
+ { name: "worktreeMode", flags: "--worktree <mode>", description: "Control managed workflow worktrees.", kind: "enum", values: ["auto", "on", "off"] },
211
212
  { name: "workspaceLinks", flags: "--workspace-links <mode>", description: "Control local workspace package links.", kind: "enum", values: ["auto", "off"] },
212
213
  { name: "plan", flags: "--plan", description: "Compute the recursive branch switch plan without mutating any repo.", kind: "boolean" },
213
214
  { name: "dryRun", flags: "--dry-run", description: "Alias for --plan.", kind: "boolean" },
@@ -261,6 +262,9 @@ const CLI_COMMAND_OVERLAYS = /* @__PURE__ */ new Map([
261
262
  options: [
262
263
  { name: "hotfix", flags: "--hotfix", description: "Allow save on main for an explicit hotfix.", kind: "boolean" },
263
264
  { name: "preview", flags: "--preview", description: "Create or refresh the branch preview during save.", kind: "boolean" },
265
+ { name: "worktreeMode", flags: "--worktree <mode>", description: "Control managed workflow worktrees.", kind: "enum", values: ["auto", "on", "off"] },
266
+ { name: "ciMode", flags: "--ci <mode>", description: "Control hosted GitHub Actions waits.", kind: "enum", values: ["auto", "hosted", "off"] },
267
+ { name: "verifyMode", flags: "--verify <mode>", description: "Control save verification depth.", kind: "enum", values: ["fast", "local", "hosted", "both", "skip"] },
264
268
  { name: "workspaceLinks", flags: "--workspace-links <mode>", description: "Control local workspace package links.", kind: "enum", values: ["auto", "off"] },
265
269
  { name: "plan", flags: "--plan", description: "Compute the recursive save plan without mutating any repo.", kind: "boolean" },
266
270
  { name: "dryRun", flags: "--dry-run", description: "Alias for --plan.", kind: "boolean" },
@@ -309,6 +313,7 @@ const CLI_COMMAND_OVERLAYS = /* @__PURE__ */ new Map([
309
313
  arguments: [{ name: "message", description: "Reason for closing the task without staging it.", required: true, kind: "message_tail" }],
310
314
  options: [
311
315
  { name: "plan", flags: "--plan", description: "Compute the recursive close plan without mutating any repo.", kind: "boolean" },
316
+ { name: "worktreeMode", flags: "--worktree <mode>", description: "Control managed workflow worktrees.", kind: "enum", values: ["auto", "on", "off"] },
312
317
  { name: "workspaceLinks", flags: "--workspace-links <mode>", description: "Control local workspace package links.", kind: "enum", values: ["auto", "off"] },
313
318
  { name: "dryRun", flags: "--dry-run", description: "Alias for --plan.", kind: "boolean" },
314
319
  { name: "json", flags: "--json", description: "Emit machine-readable JSON instead of human-readable text.", kind: "boolean" }
@@ -348,6 +353,8 @@ const CLI_COMMAND_OVERLAYS = /* @__PURE__ */ new Map([
348
353
  arguments: [{ name: "message", description: "Resolution message for the staged task.", required: true, kind: "message_tail" }],
349
354
  options: [
350
355
  { name: "plan", flags: "--plan", description: "Compute the recursive staging plan without mutating any repo.", kind: "boolean" },
356
+ { name: "worktreeMode", flags: "--worktree <mode>", description: "Control managed workflow worktrees.", kind: "enum", values: ["auto", "on", "off"] },
357
+ { name: "ciMode", flags: "--ci <mode>", description: "Control hosted GitHub Actions waits.", kind: "enum", values: ["auto", "hosted", "off"] },
351
358
  { name: "workspaceLinks", flags: "--workspace-links <mode>", description: "Control local workspace package links.", kind: "enum", values: ["auto", "off"] },
352
359
  { name: "dryRun", flags: "--dry-run", description: "Alias for --plan.", kind: "boolean" },
353
360
  { name: "json", flags: "--json", description: "Emit machine-readable JSON instead of human-readable text.", kind: "boolean" }
@@ -407,8 +414,11 @@ const CLI_COMMAND_OVERLAYS = /* @__PURE__ */ new Map([
407
414
  handlerName: "resume"
408
415
  })],
409
416
  ["recover", command({
410
- options: [{ name: "json", flags: "--json", description: "Emit machine-readable JSON instead of human-readable text.", kind: "boolean" }],
411
- examples: ["treeseed recover", "treeseed recover --json"],
417
+ options: [
418
+ { name: "pruneStale", flags: "--prune-stale", description: "Archive stale interrupted runs that are no longer safe to resume.", kind: "boolean" },
419
+ { name: "json", flags: "--json", description: "Emit machine-readable JSON instead of human-readable text.", kind: "boolean" }
420
+ ],
421
+ examples: ["treeseed recover", "treeseed recover --json", "treeseed recover --prune-stale --json"],
412
422
  help: {
413
423
  workflowPosition: "recover",
414
424
  longSummary: [
@@ -422,10 +432,11 @@ const CLI_COMMAND_OVERLAYS = /* @__PURE__ */ new Map([
422
432
  "Run it from the market workspace root or anywhere inside the tenant so the CLI can inspect the correct `.treeseed/workflow` journal directory."
423
433
  ],
424
434
  outcomes: [
425
- "Reports the active workflow lock, interrupted runs, and the exact `treeseed resume <run-id>` command for resumable runs."
435
+ "Reports the active workflow lock, resumable interrupted runs, stale runs, obsolete runs, and the exact `treeseed resume <run-id>` command for resumable runs."
426
436
  ],
427
437
  automationNotes: [
428
- "`recover --json` is the supported discovery entrypoint for agents that need to inspect lock state and resumable run ids safely before mutating the workspace."
438
+ "`recover --json` is the supported discovery entrypoint for agents that need to inspect lock state and resumable run ids safely before mutating the workspace.",
439
+ "Use `recover --prune-stale --json` to archive stale journals after the recorded branch or release heads no longer match current state."
429
440
  ]
430
441
  },
431
442
  executionMode: "handler",
@@ -555,6 +566,33 @@ const CLI_COMMAND_OVERLAYS = /* @__PURE__ */ new Map([
555
566
  force: invocation.args.force === true
556
567
  })
557
568
  })],
569
+ ["tools", command({
570
+ options: [
571
+ { name: "json", flags: "--json", description: "Emit machine-readable JSON instead of human-readable text.", kind: "boolean" }
572
+ ],
573
+ examples: ["treeseed tools", "trsd tools --json"],
574
+ help: {
575
+ workflowPosition: "setup",
576
+ longSummary: [
577
+ "Tools reports the Treeseed-managed executable cache, exact binary paths, invocation mode, and GitHub CLI authentication state without installing or mutating tools."
578
+ ],
579
+ whenToUse: [
580
+ "Use this before shelling out to `gh`, Wrangler, Railway, or Copilot from an agent or script.",
581
+ "Use this when a command claims an executable is missing but `treeseed install` has already prepared the managed tool cache."
582
+ ],
583
+ outcomes: [
584
+ "Reports toolsHome, ghConfigDir, per-tool binaryPath, invocation command, and GitHub auth remediation."
585
+ ],
586
+ examples: [
587
+ example("trsd tools --json", "Resolve managed paths for automation", "Emit stable executable paths and auth status for scripts or agents.")
588
+ ],
589
+ relatedDetails: [
590
+ related("install", "Use `install` when tools are missing or the managed cache needs repair."),
591
+ related("doctor", "Use `doctor` when tools exist but workflow readiness is still blocked.")
592
+ ]
593
+ },
594
+ executionMode: "adapter"
595
+ })],
558
596
  ["auth:login", command({
559
597
  options: [
560
598
  { name: "host", flags: "--host <id>", description: "Override the configured remote host id for this login.", kind: "string" },
@@ -863,6 +901,7 @@ const CLI_COMMAND_OVERLAYS = /* @__PURE__ */ new Map([
863
901
  ["export", command({
864
902
  arguments: [{ name: "directory", description: "Directory subtree to export. Defaults to the current shell directory.", required: false }],
865
903
  options: [
904
+ { name: "worktreeMode", flags: "--worktree <mode>", description: "Include managed workflow worktree mode metadata.", kind: "enum", values: ["auto", "on", "off"] },
866
905
  { name: "json", flags: "--json", description: "Emit machine-readable JSON instead of human-readable text.", kind: "boolean" }
867
906
  ],
868
907
  examples: ["treeseed export", "treeseed export src", "treeseed export packages/sdk --json"],
@@ -905,6 +944,8 @@ const CLI_COMMAND_OVERLAYS = /* @__PURE__ */ new Map([
905
944
  { name: "major", flags: "--major", description: "Bump to the next major version.", kind: "boolean" },
906
945
  { name: "minor", flags: "--minor", description: "Bump to the next minor version.", kind: "boolean" },
907
946
  { name: "patch", flags: "--patch", description: "Bump to the next patch version.", kind: "boolean" },
947
+ { name: "worktreeMode", flags: "--worktree <mode>", description: "Control managed workflow worktrees.", kind: "enum", values: ["auto", "on", "off"] },
948
+ { name: "ciMode", flags: "--ci <mode>", description: "Control hosted GitHub Actions waits.", kind: "enum", values: ["auto", "hosted", "off"] },
908
949
  { name: "workspaceLinks", flags: "--workspace-links <mode>", description: "Control local workspace package links.", kind: "enum", values: ["auto", "off"] },
909
950
  { name: "plan", flags: "--plan", description: "Compute the recursive release plan without mutating any repo.", kind: "boolean" },
910
951
  { name: "dryRun", flags: "--dry-run", description: "Alias for --plan.", kind: "boolean" },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treeseed/cli",
3
- "version": "0.6.9",
3
+ "version": "0.6.11",
4
4
  "description": "Operator-facing Treeseed CLI package.",
5
5
  "license": "AGPL-3.0-only",
6
6
  "repository": {
@@ -45,7 +45,7 @@
45
45
  "release:publish": "node ./scripts/run-ts.mjs ./scripts/publish-package.ts"
46
46
  },
47
47
  "dependencies": {
48
- "@treeseed/sdk": "0.6.9",
48
+ "@treeseed/sdk": "0.6.11",
49
49
  "ink": "^7.0.0",
50
50
  "react": "^19.2.5"
51
51
  },