@treeseed/cli 0.6.34 → 0.6.36
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.
- package/dist/cli/handlers/tags-cleanup.d.ts +2 -0
- package/dist/cli/handlers/tags-cleanup.js +42 -0
- package/dist/cli/handlers/tool-wrapper.d.ts +2 -0
- package/dist/cli/handlers/tool-wrapper.js +77 -0
- package/dist/cli/operations-registry.js +113 -1
- package/dist/cli/parser.js +4 -0
- package/dist/cli/registry.d.ts +4 -0
- package/dist/cli/registry.js +6 -0
- package/dist/cli/runtime.js +11 -3
- package/package.json +2 -2
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { guidedResult } from "./utils.js";
|
|
2
|
+
import { createWorkflowSdk, renderWorkflowNextSteps, workflowErrorResult } from "./workflow.js";
|
|
3
|
+
function parseIncludePackages(value) {
|
|
4
|
+
if (typeof value !== "string" || value.trim().length === 0) return void 0;
|
|
5
|
+
return value.split(",").map((entry) => entry.trim()).filter(Boolean);
|
|
6
|
+
}
|
|
7
|
+
const handleTagsCleanup = async (invocation, context) => {
|
|
8
|
+
try {
|
|
9
|
+
const result = await createWorkflowSdk(context).tagsCleanup({
|
|
10
|
+
includePackages: parseIncludePackages(invocation.args.includePackages),
|
|
11
|
+
branchScope: typeof invocation.args.branchScope === "string" ? invocation.args.branchScope : void 0,
|
|
12
|
+
plan: invocation.args.plan === true || invocation.args.dryRun === true,
|
|
13
|
+
dryRun: invocation.args.dryRun === true
|
|
14
|
+
});
|
|
15
|
+
const payload = result.payload;
|
|
16
|
+
return guidedResult({
|
|
17
|
+
command: invocation.commandName || "tags:cleanup",
|
|
18
|
+
summary: result.executionMode === "plan" ? "Treeseed dev tag cleanup plan ready." : "Treeseed dev tag cleanup completed.",
|
|
19
|
+
facts: [
|
|
20
|
+
{ label: "Status", value: payload.status ?? (result.executionMode === "plan" ? "planned" : "completed") },
|
|
21
|
+
{ label: "Branch scope", value: payload.branchScope ?? "all" },
|
|
22
|
+
{ label: "Included packages", value: (payload.includePackages ?? []).join(", ") || "all" },
|
|
23
|
+
{ label: "Candidate tags", value: String(payload.candidateCount ?? 0) },
|
|
24
|
+
{ label: "Cleaned tags", value: String(payload.cleanedCount ?? 0) },
|
|
25
|
+
{ label: "Skipped tags", value: String(payload.skippedCount ?? 0) }
|
|
26
|
+
],
|
|
27
|
+
sections: [
|
|
28
|
+
{
|
|
29
|
+
title: "Repositories",
|
|
30
|
+
lines: (payload.repos ?? []).map((repo) => `- ${repo.name ?? "repo"}: candidates ${repo.candidateCount ?? 0}, cleaned ${repo.cleanedCount ?? 0}, skipped ${repo.skippedCount ?? 0}`)
|
|
31
|
+
}
|
|
32
|
+
],
|
|
33
|
+
nextSteps: renderWorkflowNextSteps(result),
|
|
34
|
+
report: result
|
|
35
|
+
});
|
|
36
|
+
} catch (error) {
|
|
37
|
+
return workflowErrorResult(error);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
export {
|
|
41
|
+
handleTagsCleanup
|
|
42
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createTreeseedManagedToolEnv,
|
|
3
|
+
resolveTreeseedLaunchEnvironment,
|
|
4
|
+
resolveTreeseedToolCommand
|
|
5
|
+
} from "@treeseed/sdk/workflow-support";
|
|
6
|
+
import { workflowErrorResult } from "./workflow.js";
|
|
7
|
+
const WRAPPED_TOOLS = /* @__PURE__ */ new Set(["gh", "railway", "wrangler"]);
|
|
8
|
+
const ENVIRONMENT_SCOPES = /* @__PURE__ */ new Set(["local", "staging", "prod"]);
|
|
9
|
+
function wrappedToolName(value) {
|
|
10
|
+
if (WRAPPED_TOOLS.has(value)) {
|
|
11
|
+
return value;
|
|
12
|
+
}
|
|
13
|
+
throw new Error(`Unsupported Treeseed tool wrapper: ${value}`);
|
|
14
|
+
}
|
|
15
|
+
function wrapperScope(value) {
|
|
16
|
+
if (typeof value === "string" && ENVIRONMENT_SCOPES.has(value)) {
|
|
17
|
+
return value;
|
|
18
|
+
}
|
|
19
|
+
return "staging";
|
|
20
|
+
}
|
|
21
|
+
const handleToolWrapper = (invocation, context) => {
|
|
22
|
+
try {
|
|
23
|
+
const toolName = wrappedToolName(invocation.commandName);
|
|
24
|
+
const scope = wrapperScope(invocation.args.environment);
|
|
25
|
+
const launchEnv = resolveTreeseedLaunchEnvironment({
|
|
26
|
+
tenantRoot: context.cwd,
|
|
27
|
+
scope,
|
|
28
|
+
baseEnv: { ...process.env, ...context.env ?? {} }
|
|
29
|
+
});
|
|
30
|
+
const managedEnv = createTreeseedManagedToolEnv({
|
|
31
|
+
...process.env,
|
|
32
|
+
...context.env ?? {},
|
|
33
|
+
...launchEnv,
|
|
34
|
+
TREESEED_ACTIVE_ENVIRONMENT: scope
|
|
35
|
+
});
|
|
36
|
+
const resolved = resolveTreeseedToolCommand(toolName, { env: managedEnv });
|
|
37
|
+
if (!resolved) {
|
|
38
|
+
return {
|
|
39
|
+
exitCode: 1,
|
|
40
|
+
stderr: [
|
|
41
|
+
`Treeseed managed tool \`${toolName}\` is not installed or could not be resolved.`,
|
|
42
|
+
"Run `npx trsd install --json` and retry the wrapper command."
|
|
43
|
+
],
|
|
44
|
+
report: {
|
|
45
|
+
command: toolName,
|
|
46
|
+
ok: false,
|
|
47
|
+
scope,
|
|
48
|
+
error: `Unable to resolve ${toolName}.`
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
const targetArgs = invocation.positionals;
|
|
53
|
+
const result = context.spawn(resolved.command, [...resolved.argsPrefix, ...targetArgs], {
|
|
54
|
+
cwd: context.cwd,
|
|
55
|
+
env: managedEnv,
|
|
56
|
+
stdio: "inherit"
|
|
57
|
+
});
|
|
58
|
+
return {
|
|
59
|
+
exitCode: result.status ?? 1,
|
|
60
|
+
suppressJsonResult: true,
|
|
61
|
+
report: {
|
|
62
|
+
command: toolName,
|
|
63
|
+
ok: (result.status ?? 1) === 0,
|
|
64
|
+
scope,
|
|
65
|
+
executable: resolved.command,
|
|
66
|
+
binaryPath: resolved.binaryPath,
|
|
67
|
+
argsPrefix: resolved.argsPrefix,
|
|
68
|
+
args: targetArgs
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
} catch (error) {
|
|
72
|
+
return workflowErrorResult(error);
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
export {
|
|
76
|
+
handleToolWrapper
|
|
77
|
+
};
|
|
@@ -114,7 +114,7 @@ function genericWarnings(spec) {
|
|
|
114
114
|
if (spec.name === "release") {
|
|
115
115
|
warnings.push("Release operations assume staging is the source of truth for what should move to production. Treat version bumps and promotion as deliberate release events.");
|
|
116
116
|
}
|
|
117
|
-
if (spec.
|
|
117
|
+
if (spec.group === "Passthrough") {
|
|
118
118
|
warnings.push("This command forwards to another CLI surface. Flags after `--` or positional forwarding may follow the target tool semantics rather than Treeseed-specific semantics.");
|
|
119
119
|
}
|
|
120
120
|
return warnings;
|
|
@@ -148,6 +148,9 @@ function mergeHelpSpec(metadata, overlay, spec) {
|
|
|
148
148
|
};
|
|
149
149
|
}
|
|
150
150
|
const PASS_THROUGH_ARGS = (invocation) => ({ args: invocation.rawArgs });
|
|
151
|
+
const TOOL_WRAPPER_OPTIONS = [
|
|
152
|
+
{ name: "environment", flags: "--environment <scope>", description: "Treeseed environment scope used to decrypt and inject provider credentials.", kind: "enum", values: ["local", "staging", "prod"] }
|
|
153
|
+
];
|
|
151
154
|
const CLI_COMMAND_OVERLAYS = /* @__PURE__ */ new Map([
|
|
152
155
|
["status", command({
|
|
153
156
|
options: [
|
|
@@ -456,6 +459,43 @@ const CLI_COMMAND_OVERLAYS = /* @__PURE__ */ new Map([
|
|
|
456
459
|
executionMode: "handler",
|
|
457
460
|
handlerName: "stage"
|
|
458
461
|
})],
|
|
462
|
+
["tags:cleanup", command({
|
|
463
|
+
usage: "treeseed tags:cleanup [--plan|--dry-run] [--include-packages <names>] [--branch-scope <staging|preview|all>] [--json]",
|
|
464
|
+
options: [
|
|
465
|
+
{ name: "plan", flags: "--plan", description: "Compute stale dev tag cleanup without deleting tags.", kind: "boolean" },
|
|
466
|
+
{ name: "dryRun", flags: "--dry-run", description: "Alias for --plan.", kind: "boolean" },
|
|
467
|
+
{ name: "includePackages", flags: "--include-packages <names>", description: "Comma-separated package names to inspect.", kind: "string" },
|
|
468
|
+
{ name: "branchScope", flags: "--branch-scope <scope>", description: "Limit cleanup to staging tags, preview tags, or all dev branch tags.", kind: "enum", values: ["staging", "preview", "all"] },
|
|
469
|
+
{ name: "json", flags: "--json", description: "Emit machine-readable JSON instead of human-readable text.", kind: "boolean" }
|
|
470
|
+
],
|
|
471
|
+
examples: ["treeseed tags:cleanup --plan", "treeseed tags:cleanup --branch-scope staging", "treeseed tags:cleanup --include-packages @treeseed/sdk,@treeseed/core --json"],
|
|
472
|
+
notes: ["Only deletes Treeseed-managed package dev tags older than each package current version line."],
|
|
473
|
+
help: {
|
|
474
|
+
workflowPosition: "maintain workspace",
|
|
475
|
+
longSummary: [
|
|
476
|
+
"Tags cleanup removes stale Treeseed-managed package dev tags from staging and preview branch saves."
|
|
477
|
+
],
|
|
478
|
+
whenToUse: [
|
|
479
|
+
"Use this when old staging or preview package tags have accumulated after many saves and releases.",
|
|
480
|
+
"Use `--plan` first to inspect exactly which tags would be removed."
|
|
481
|
+
],
|
|
482
|
+
outcomes: [
|
|
483
|
+
"Plans or deletes stale local and origin package dev tags.",
|
|
484
|
+
"Preserves current-version dev tags, active dependency references, stable release tags, and non-Treeseed tags."
|
|
485
|
+
],
|
|
486
|
+
examples: [
|
|
487
|
+
example("treeseed tags:cleanup --plan", "Inspect cleanup", "Show stale tag candidates without deleting anything."),
|
|
488
|
+
example("treeseed tags:cleanup --branch-scope preview", "Clean preview tags", "Delete stale non-staging branch dev tags while leaving staging dev tags alone."),
|
|
489
|
+
example("treeseed tags:cleanup --json", "Automate cleanup", "Emit structured per-repository cleanup counts and skipped reasons.")
|
|
490
|
+
],
|
|
491
|
+
relatedDetails: [
|
|
492
|
+
related("release", "Release also runs safe dev tag cleanup after successful stable promotion."),
|
|
493
|
+
related("status", "Use `status` to inspect workspace alignment before maintenance.")
|
|
494
|
+
]
|
|
495
|
+
},
|
|
496
|
+
executionMode: "handler",
|
|
497
|
+
handlerName: "tags:cleanup"
|
|
498
|
+
})],
|
|
459
499
|
["resume", command({
|
|
460
500
|
arguments: [{ name: "run-id", description: "Interrupted workflow run id to resume.", required: true }],
|
|
461
501
|
options: [{ name: "json", flags: "--json", description: "Emit machine-readable JSON instead of human-readable text.", kind: "boolean" }],
|
|
@@ -1217,6 +1257,78 @@ const CLI_COMMAND_OVERLAYS = /* @__PURE__ */ new Map([
|
|
|
1217
1257
|
["starlight:patch", command({ examples: ["treeseed starlight:patch"], executionMode: "adapter" })]
|
|
1218
1258
|
]);
|
|
1219
1259
|
const CLI_ONLY_OPERATION_SPECS = [
|
|
1260
|
+
{
|
|
1261
|
+
id: "tools.gh",
|
|
1262
|
+
name: "gh",
|
|
1263
|
+
aliases: [],
|
|
1264
|
+
group: "Passthrough",
|
|
1265
|
+
summary: "Run the managed GitHub CLI with Treeseed environment credentials.",
|
|
1266
|
+
description: "Decrypt Treeseed machine configuration for the selected environment and pass it to the managed GitHub CLI.",
|
|
1267
|
+
provider: "default",
|
|
1268
|
+
related: ["tools", "install", "config"],
|
|
1269
|
+
usage: "treeseed gh [--environment staging] -- <gh-args>",
|
|
1270
|
+
arguments: [{ name: "args", description: "Arguments forwarded to GitHub CLI.", required: false }],
|
|
1271
|
+
options: TOOL_WRAPPER_OPTIONS,
|
|
1272
|
+
examples: ["treeseed gh --environment staging -- run list --limit 5", "treeseed gh -- repo view"],
|
|
1273
|
+
help: {
|
|
1274
|
+
longSummary: ["The GitHub wrapper resolves the Treeseed-managed `gh` executable, decrypts scoped machine configuration, and passes the resulting GitHub token only to the child process environment."],
|
|
1275
|
+
whenToUse: ["Use this when provider auth lives in Treeseed machine config rather than your shell environment."],
|
|
1276
|
+
beforeYouRun: ["Run from a Treeseed project. Use `--environment staging` unless you intentionally need local or production credentials."],
|
|
1277
|
+
automationNotes: ["Use `--` before target CLI flags when a flag could be parsed by Treeseed itself. The wrapper does not print decrypted secrets."]
|
|
1278
|
+
},
|
|
1279
|
+
helpVisible: true,
|
|
1280
|
+
helpFeatured: false,
|
|
1281
|
+
executionMode: "handler",
|
|
1282
|
+
handlerName: "gh"
|
|
1283
|
+
},
|
|
1284
|
+
{
|
|
1285
|
+
id: "tools.railway",
|
|
1286
|
+
name: "railway",
|
|
1287
|
+
aliases: [],
|
|
1288
|
+
group: "Passthrough",
|
|
1289
|
+
summary: "Run the managed Railway CLI with Treeseed environment credentials.",
|
|
1290
|
+
description: "Decrypt Treeseed machine configuration for the selected environment and pass it to the managed Railway CLI.",
|
|
1291
|
+
provider: "default",
|
|
1292
|
+
related: ["tools", "install", "config"],
|
|
1293
|
+
usage: "treeseed railway [--environment staging] -- <railway-args>",
|
|
1294
|
+
arguments: [{ name: "args", description: "Arguments forwarded to Railway CLI.", required: false }],
|
|
1295
|
+
options: TOOL_WRAPPER_OPTIONS,
|
|
1296
|
+
examples: ["treeseed railway --environment staging -- whoami", "treeseed railway --environment staging -- status"],
|
|
1297
|
+
help: {
|
|
1298
|
+
longSummary: ["The Railway wrapper resolves the Treeseed-managed Railway executable, decrypts scoped machine configuration, and passes the resulting Railway token only to the child process environment."],
|
|
1299
|
+
whenToUse: ["Use this to debug Railway projects and service builds with the same decrypted `RAILWAY_API_TOKEN` Treeseed deploys use."],
|
|
1300
|
+
beforeYouRun: ["Run from a Treeseed project. Use `--environment staging` when inspecting staging deployments."],
|
|
1301
|
+
automationNotes: ["Use `--` before target CLI flags when a flag could be parsed by Treeseed itself. The wrapper does not print decrypted secrets."]
|
|
1302
|
+
},
|
|
1303
|
+
helpVisible: true,
|
|
1304
|
+
helpFeatured: false,
|
|
1305
|
+
executionMode: "handler",
|
|
1306
|
+
handlerName: "railway"
|
|
1307
|
+
},
|
|
1308
|
+
{
|
|
1309
|
+
id: "tools.wrangler",
|
|
1310
|
+
name: "wrangler",
|
|
1311
|
+
aliases: [],
|
|
1312
|
+
group: "Passthrough",
|
|
1313
|
+
summary: "Run the managed Wrangler CLI with Treeseed environment credentials.",
|
|
1314
|
+
description: "Decrypt Treeseed machine configuration for the selected environment and pass it to the managed Wrangler CLI.",
|
|
1315
|
+
provider: "default",
|
|
1316
|
+
related: ["tools", "install", "config"],
|
|
1317
|
+
usage: "treeseed wrangler [--environment staging] -- <wrangler-args>",
|
|
1318
|
+
arguments: [{ name: "args", description: "Arguments forwarded to Wrangler CLI.", required: false }],
|
|
1319
|
+
options: TOOL_WRAPPER_OPTIONS,
|
|
1320
|
+
examples: ["treeseed wrangler --environment staging -- whoami", "treeseed wrangler --environment staging -- d1 list"],
|
|
1321
|
+
help: {
|
|
1322
|
+
longSummary: ["The Wrangler wrapper resolves the Treeseed-managed Wrangler executable, decrypts scoped machine configuration, and passes the resulting Cloudflare token and account settings only to the child process environment."],
|
|
1323
|
+
whenToUse: ["Use this to debug Cloudflare resources with the same decrypted `CLOUDFLARE_API_TOKEN` and account settings Treeseed deploys use."],
|
|
1324
|
+
beforeYouRun: ["Run from a Treeseed project. Use `--environment staging` when inspecting staging resources."],
|
|
1325
|
+
automationNotes: ["Use `--` before target CLI flags when a flag could be parsed by Treeseed itself. The wrapper does not print decrypted secrets."]
|
|
1326
|
+
},
|
|
1327
|
+
helpVisible: true,
|
|
1328
|
+
helpFeatured: false,
|
|
1329
|
+
executionMode: "handler",
|
|
1330
|
+
handlerName: "wrangler"
|
|
1331
|
+
},
|
|
1220
1332
|
{
|
|
1221
1333
|
id: "market.registry",
|
|
1222
1334
|
name: "market",
|
package/dist/cli/parser.js
CHANGED
|
@@ -21,6 +21,10 @@ function parseTreeseedInvocation(command, argv) {
|
|
|
21
21
|
const [flag, inlineValue] = current.split("=", 2);
|
|
22
22
|
const spec = byFlag.get(flag);
|
|
23
23
|
if (!spec) {
|
|
24
|
+
if (command.group === "Passthrough") {
|
|
25
|
+
positionals.push(current);
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
24
28
|
throw new Error(`Unknown option: ${flag}`);
|
|
25
29
|
}
|
|
26
30
|
if (spec.kind === "boolean") {
|
package/dist/cli/registry.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export declare const COMMAND_HANDLERS: {
|
|
|
18
18
|
readonly tasks: import("./operations-types.js").TreeseedCommandHandler;
|
|
19
19
|
readonly switch: import("./operations-types.js").TreeseedCommandHandler;
|
|
20
20
|
readonly stage: import("./operations-types.js").TreeseedCommandHandler;
|
|
21
|
+
readonly 'tags:cleanup': import("./operations-types.js").TreeseedCommandHandler;
|
|
21
22
|
readonly resume: import("./operations-types.js").TreeseedCommandHandler;
|
|
22
23
|
readonly recover: import("./operations-types.js").TreeseedCommandHandler;
|
|
23
24
|
readonly export: import("./operations-types.js").TreeseedCommandHandler;
|
|
@@ -28,6 +29,9 @@ export declare const COMMAND_HANDLERS: {
|
|
|
28
29
|
readonly teams: import("./operations-types.js").TreeseedCommandHandler;
|
|
29
30
|
readonly projects: import("./operations-types.js").TreeseedCommandHandler;
|
|
30
31
|
readonly packs: import("./operations-types.js").TreeseedCommandHandler;
|
|
32
|
+
readonly gh: import("./operations-types.js").TreeseedCommandHandler;
|
|
33
|
+
readonly railway: import("./operations-types.js").TreeseedCommandHandler;
|
|
34
|
+
readonly wrangler: import("./operations-types.js").TreeseedCommandHandler;
|
|
31
35
|
readonly 'secrets:status': import("./operations-types.js").TreeseedCommandHandler;
|
|
32
36
|
readonly 'secrets:unlock': import("./operations-types.js").TreeseedCommandHandler;
|
|
33
37
|
readonly 'secrets:lock': import("./operations-types.js").TreeseedCommandHandler;
|
package/dist/cli/registry.js
CHANGED
|
@@ -23,6 +23,7 @@ import { handleMarket } from "./handlers/market.js";
|
|
|
23
23
|
import { handleTeams } from "./handlers/teams.js";
|
|
24
24
|
import { handleProjects } from "./handlers/projects.js";
|
|
25
25
|
import { handlePacks } from "./handlers/packs.js";
|
|
26
|
+
import { handleToolWrapper } from "./handlers/tool-wrapper.js";
|
|
26
27
|
import {
|
|
27
28
|
handleSecretsLock,
|
|
28
29
|
handleSecretsMigrateKey,
|
|
@@ -34,6 +35,7 @@ import {
|
|
|
34
35
|
import { handleTasks } from "./handlers/tasks.js";
|
|
35
36
|
import { handleSwitch } from "./handlers/switch.js";
|
|
36
37
|
import { handleStage } from "./handlers/stage.js";
|
|
38
|
+
import { handleTagsCleanup } from "./handlers/tags-cleanup.js";
|
|
37
39
|
import { handleExport } from "./handlers/export.js";
|
|
38
40
|
import { handleResume } from "./handlers/resume.js";
|
|
39
41
|
import { handleRecover } from "./handlers/recover.js";
|
|
@@ -57,6 +59,7 @@ const COMMAND_HANDLERS = {
|
|
|
57
59
|
tasks: handleTasks,
|
|
58
60
|
switch: handleSwitch,
|
|
59
61
|
stage: handleStage,
|
|
62
|
+
"tags:cleanup": handleTagsCleanup,
|
|
60
63
|
resume: handleResume,
|
|
61
64
|
recover: handleRecover,
|
|
62
65
|
[workspaceCommand("status")]: handleWorkspace,
|
|
@@ -70,6 +73,9 @@ const COMMAND_HANDLERS = {
|
|
|
70
73
|
teams: handleTeams,
|
|
71
74
|
projects: handleProjects,
|
|
72
75
|
packs: handlePacks,
|
|
76
|
+
gh: handleToolWrapper,
|
|
77
|
+
railway: handleToolWrapper,
|
|
78
|
+
wrangler: handleToolWrapper,
|
|
73
79
|
"secrets:status": handleSecretsStatus,
|
|
74
80
|
"secrets:unlock": handleSecretsUnlock,
|
|
75
81
|
"secrets:lock": handleSecretsLock,
|
package/dist/cli/runtime.js
CHANGED
|
@@ -14,6 +14,14 @@ const require2 = createRequire(import.meta.url);
|
|
|
14
14
|
function isHelpFlag(value) {
|
|
15
15
|
return value === "--help" || value === "-h";
|
|
16
16
|
}
|
|
17
|
+
function shouldRenderCommandHelp(spec, argv) {
|
|
18
|
+
if (spec.group !== "Passthrough") {
|
|
19
|
+
return argv.some(isHelpFlag);
|
|
20
|
+
}
|
|
21
|
+
const separatorIndex = argv.indexOf("--");
|
|
22
|
+
const treeseedArgs = separatorIndex >= 0 ? argv.slice(0, separatorIndex) : argv;
|
|
23
|
+
return treeseedArgs.some(isHelpFlag);
|
|
24
|
+
}
|
|
17
25
|
function isNoColorFlag(value) {
|
|
18
26
|
return value === "--no-color";
|
|
19
27
|
}
|
|
@@ -294,7 +302,7 @@ class TreeseedOperationsSdk {
|
|
|
294
302
|
lines.push("Run `treeseed help` to see the full command list.");
|
|
295
303
|
return writeTreeseedResult({ exitCode: 1, stderr: [lines.join("\n")] }, context);
|
|
296
304
|
}
|
|
297
|
-
if (argv
|
|
305
|
+
if (shouldRenderCommandHelp(spec, argv)) {
|
|
298
306
|
if (shouldUseInkHelp(context)) {
|
|
299
307
|
const helpExitCode = await renderTreeseedHelpInk(spec.name, context);
|
|
300
308
|
if (typeof helpExitCode === "number") {
|
|
@@ -376,7 +384,7 @@ async function executeTreeseedCommand(commandName, argv, context) {
|
|
|
376
384
|
if (!spec) {
|
|
377
385
|
return cliOperationsSdk.executeOperation({ commandName, argv: cleanArgv }, commandContext);
|
|
378
386
|
}
|
|
379
|
-
if (cleanArgv
|
|
387
|
+
if (shouldRenderCommandHelp(spec, cleanArgv)) {
|
|
380
388
|
return cliOperationsSdk.executeOperation({ commandName, argv: cleanArgv }, commandContext);
|
|
381
389
|
}
|
|
382
390
|
const resolved = resolveTreeseedCommandCwd(spec, commandContext.cwd);
|
|
@@ -402,7 +410,7 @@ async function runTreeseedCli(argv, overrides = {}) {
|
|
|
402
410
|
if (!spec) {
|
|
403
411
|
return cliOperationsSdk.run(cleanArgv, { ...overrides, colorEnabled });
|
|
404
412
|
}
|
|
405
|
-
if (cleanArgv.slice(1)
|
|
413
|
+
if (shouldRenderCommandHelp(spec, cleanArgv.slice(1))) {
|
|
406
414
|
return cliOperationsSdk.run(cleanArgv, { ...overrides, colorEnabled });
|
|
407
415
|
}
|
|
408
416
|
const baseCwd = overrides.cwd ?? process.cwd();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@treeseed/cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.36",
|
|
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.
|
|
48
|
+
"@treeseed/sdk": "0.6.40",
|
|
49
49
|
"ink": "^7.0.0",
|
|
50
50
|
"react": "^19.2.5"
|
|
51
51
|
},
|