@treeseed/cli 0.1.1 → 0.4.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.
- package/README.md +27 -26
- package/dist/cli/handlers/auth-login.d.ts +2 -0
- package/dist/cli/handlers/auth-login.js +67 -0
- package/dist/cli/handlers/auth-logout.d.ts +2 -0
- package/dist/cli/handlers/auth-logout.js +20 -0
- package/dist/cli/handlers/auth-whoami.d.ts +2 -0
- package/dist/cli/handlers/auth-whoami.js +24 -0
- package/dist/cli/handlers/close.js +19 -53
- package/dist/cli/handlers/config.js +33 -53
- package/dist/cli/handlers/destroy.js +34 -79
- package/dist/{src/cli/handlers/ship.d.ts → cli/handlers/dev.d.ts} +1 -1
- package/dist/cli/handlers/dev.js +19 -0
- package/dist/cli/handlers/doctor.js +13 -6
- package/dist/cli/handlers/init.js +32 -8
- package/dist/cli/handlers/release.js +21 -53
- package/dist/cli/handlers/rollback.js +8 -8
- package/dist/cli/handlers/save.js +21 -79
- package/dist/cli/handlers/stage.d.ts +2 -0
- package/dist/cli/handlers/stage.js +28 -0
- package/dist/cli/handlers/status.js +35 -26
- package/dist/{src/cli/handlers/deploy.d.ts → cli/handlers/switch.d.ts} +1 -1
- package/dist/cli/handlers/switch.js +29 -0
- package/dist/{src/cli/handlers/next.d.ts → cli/handlers/sync.d.ts} +1 -1
- package/dist/cli/handlers/sync.js +26 -0
- package/dist/cli/handlers/tasks.d.ts +2 -0
- package/dist/cli/handlers/tasks.js +31 -0
- package/dist/cli/handlers/template.d.ts +2 -0
- package/dist/cli/handlers/template.js +27 -0
- package/dist/cli/handlers/workflow.d.ts +6 -0
- package/dist/cli/handlers/workflow.js +71 -0
- package/dist/{src/cli → cli}/help.d.ts +2 -2
- package/dist/cli/help.js +36 -24
- package/dist/cli/main.d.ts +6 -0
- package/dist/cli/main.js +14 -19
- package/dist/cli/operations-help.d.ts +1 -0
- package/dist/cli/operations-help.js +1 -0
- package/dist/cli/operations-parser.d.ts +1 -0
- package/dist/cli/operations-parser.js +1 -0
- package/dist/cli/operations-registry.d.ts +5 -0
- package/dist/cli/operations-registry.js +260 -0
- package/dist/cli/operations-types.d.ts +72 -0
- package/dist/cli/parser.d.ts +3 -0
- package/dist/cli/parser.js +1 -6
- package/dist/cli/registry.d.ts +25 -0
- package/dist/cli/registry.js +28 -416
- package/dist/cli/repair.js +6 -4
- package/dist/cli/runtime.d.ts +31 -0
- package/dist/cli/runtime.js +240 -111
- package/dist/cli/types.d.ts +1 -0
- package/dist/{src/cli → cli}/workflow-state.d.ts +9 -0
- package/dist/cli/workflow-state.js +45 -21
- package/package.json +13 -13
- package/dist/cli/handlers/continue.js +0 -23
- package/dist/cli/handlers/deploy.js +0 -139
- package/dist/cli/handlers/next.js +0 -27
- package/dist/cli/handlers/prepare.js +0 -8
- package/dist/cli/handlers/promote.js +0 -8
- package/dist/cli/handlers/publish.js +0 -8
- package/dist/cli/handlers/setup.js +0 -48
- package/dist/cli/handlers/ship.js +0 -49
- package/dist/cli/handlers/start.js +0 -97
- package/dist/cli/handlers/teardown.js +0 -50
- package/dist/cli/handlers/work.js +0 -85
- package/dist/scripts/aggregate-book.d.ts +0 -1
- package/dist/scripts/aggregate-book.js +0 -121
- package/dist/scripts/assert-release-tag-version.d.ts +0 -1
- package/dist/scripts/assert-release-tag-version.js +0 -21
- package/dist/scripts/build-dist.d.ts +0 -1
- package/dist/scripts/build-dist.js +0 -108
- package/dist/scripts/build-tenant-worker.d.ts +0 -1
- package/dist/scripts/build-tenant-worker.js +0 -36
- package/dist/scripts/cleanup-markdown.d.ts +0 -2
- package/dist/scripts/cleanup-markdown.js +0 -373
- package/dist/scripts/config-runtime-lib.d.ts +0 -122
- package/dist/scripts/config-runtime-lib.js +0 -505
- package/dist/scripts/config-treeseed.d.ts +0 -2
- package/dist/scripts/config-treeseed.js +0 -81
- package/dist/scripts/d1-migration-lib.d.ts +0 -6
- package/dist/scripts/d1-migration-lib.js +0 -90
- package/dist/scripts/deploy-lib.d.ts +0 -127
- package/dist/scripts/deploy-lib.js +0 -841
- package/dist/scripts/ensure-mailpit.d.ts +0 -1
- package/dist/scripts/ensure-mailpit.js +0 -29
- package/dist/scripts/git-workflow-lib.d.ts +0 -25
- package/dist/scripts/git-workflow-lib.js +0 -136
- package/dist/scripts/github-automation-lib.d.ts +0 -156
- package/dist/scripts/github-automation-lib.js +0 -242
- package/dist/scripts/local-dev-lib.d.ts +0 -9
- package/dist/scripts/local-dev-lib.js +0 -84
- package/dist/scripts/local-dev.d.ts +0 -1
- package/dist/scripts/local-dev.js +0 -129
- package/dist/scripts/logs-mailpit.d.ts +0 -1
- package/dist/scripts/logs-mailpit.js +0 -2
- package/dist/scripts/mailpit-runtime.d.ts +0 -4
- package/dist/scripts/mailpit-runtime.js +0 -57
- package/dist/scripts/package-tools.d.ts +0 -22
- package/dist/scripts/package-tools.js +0 -255
- package/dist/scripts/patch-starlight-content-path.d.ts +0 -1
- package/dist/scripts/patch-starlight-content-path.js +0 -172
- package/dist/scripts/paths.d.ts +0 -17
- package/dist/scripts/paths.js +0 -26
- package/dist/scripts/publish-package.d.ts +0 -1
- package/dist/scripts/publish-package.js +0 -19
- package/dist/scripts/release-verify.d.ts +0 -1
- package/dist/scripts/release-verify.js +0 -136
- package/dist/scripts/run-fixture-astro-command.d.ts +0 -1
- package/dist/scripts/run-fixture-astro-command.js +0 -18
- package/dist/scripts/save-deploy-preflight-lib.d.ts +0 -34
- package/dist/scripts/save-deploy-preflight-lib.js +0 -69
- package/dist/scripts/scaffold-site.d.ts +0 -2
- package/dist/scripts/scaffold-site.js +0 -92
- package/dist/scripts/stop-mailpit.d.ts +0 -1
- package/dist/scripts/stop-mailpit.js +0 -5
- package/dist/scripts/sync-dev-vars.d.ts +0 -1
- package/dist/scripts/sync-dev-vars.js +0 -6
- package/dist/scripts/template-registry-lib.d.ts +0 -47
- package/dist/scripts/template-registry-lib.js +0 -137
- package/dist/scripts/tenant-astro-command.d.ts +0 -1
- package/dist/scripts/tenant-astro-command.js +0 -3
- package/dist/scripts/tenant-build.d.ts +0 -1
- package/dist/scripts/tenant-build.js +0 -16
- package/dist/scripts/tenant-check.d.ts +0 -1
- package/dist/scripts/tenant-check.js +0 -7
- package/dist/scripts/tenant-d1-migrate-local.d.ts +0 -1
- package/dist/scripts/tenant-d1-migrate-local.js +0 -11
- package/dist/scripts/tenant-deploy.d.ts +0 -2
- package/dist/scripts/tenant-deploy.js +0 -180
- package/dist/scripts/tenant-destroy.d.ts +0 -2
- package/dist/scripts/tenant-destroy.js +0 -104
- package/dist/scripts/tenant-dev.d.ts +0 -1
- package/dist/scripts/tenant-dev.js +0 -171
- package/dist/scripts/tenant-lint.d.ts +0 -1
- package/dist/scripts/tenant-lint.js +0 -4
- package/dist/scripts/tenant-test.d.ts +0 -1
- package/dist/scripts/tenant-test.js +0 -4
- package/dist/scripts/test-cloudflare-local.d.ts +0 -1
- package/dist/scripts/test-cloudflare-local.js +0 -212
- package/dist/scripts/test-scaffold.d.ts +0 -2
- package/dist/scripts/test-scaffold.js +0 -297
- package/dist/scripts/treeseed.d.ts +0 -2
- package/dist/scripts/treeseed.js +0 -4
- package/dist/scripts/validate-templates.d.ts +0 -2
- package/dist/scripts/validate-templates.js +0 -4
- package/dist/scripts/watch-dev-lib.d.ts +0 -21
- package/dist/scripts/watch-dev-lib.js +0 -277
- package/dist/scripts/workspace-close.d.ts +0 -2
- package/dist/scripts/workspace-close.js +0 -24
- package/dist/scripts/workspace-command-e2e.d.ts +0 -2
- package/dist/scripts/workspace-command-e2e.js +0 -718
- package/dist/scripts/workspace-lint.d.ts +0 -1
- package/dist/scripts/workspace-lint.js +0 -9
- package/dist/scripts/workspace-preflight-lib.d.ts +0 -36
- package/dist/scripts/workspace-preflight-lib.js +0 -179
- package/dist/scripts/workspace-preflight.d.ts +0 -2
- package/dist/scripts/workspace-preflight.js +0 -22
- package/dist/scripts/workspace-publish-changed-packages.d.ts +0 -1
- package/dist/scripts/workspace-publish-changed-packages.js +0 -16
- package/dist/scripts/workspace-release-verify.d.ts +0 -1
- package/dist/scripts/workspace-release-verify.js +0 -81
- package/dist/scripts/workspace-release.d.ts +0 -2
- package/dist/scripts/workspace-release.js +0 -42
- package/dist/scripts/workspace-save-lib.d.ts +0 -42
- package/dist/scripts/workspace-save-lib.js +0 -220
- package/dist/scripts/workspace-save.d.ts +0 -2
- package/dist/scripts/workspace-save.js +0 -124
- package/dist/scripts/workspace-start-warning.js +0 -3
- package/dist/scripts/workspace-start.d.ts +0 -2
- package/dist/scripts/workspace-start.js +0 -71
- package/dist/scripts/workspace-test-unit.d.ts +0 -1
- package/dist/scripts/workspace-test-unit.js +0 -4
- package/dist/scripts/workspace-test.d.ts +0 -1
- package/dist/scripts/workspace-test.js +0 -11
- package/dist/scripts/workspace-tools.d.ts +0 -13
- package/dist/scripts/workspace-tools.js +0 -226
- package/dist/src/cli/handlers/continue.d.ts +0 -2
- package/dist/src/cli/handlers/prepare.d.ts +0 -2
- package/dist/src/cli/handlers/promote.d.ts +0 -2
- package/dist/src/cli/handlers/publish.d.ts +0 -2
- package/dist/src/cli/handlers/setup.d.ts +0 -2
- package/dist/src/cli/handlers/start.d.ts +0 -3
- package/dist/src/cli/handlers/teardown.d.ts +0 -2
- package/dist/src/cli/handlers/work.d.ts +0 -2
- package/dist/src/cli/main.d.ts +0 -6
- package/dist/src/cli/parser.d.ts +0 -3
- package/dist/src/cli/registry.d.ts +0 -27
- package/dist/src/cli/runtime.d.ts +0 -4
- package/dist/src/cli/types.d.ts +0 -71
- /package/dist/{src/cli → cli}/handlers/close.d.ts +0 -0
- /package/dist/{src/cli → cli}/handlers/config.d.ts +0 -0
- /package/dist/{src/cli → cli}/handlers/destroy.d.ts +0 -0
- /package/dist/{src/cli → cli}/handlers/doctor.d.ts +0 -0
- /package/dist/{src/cli → cli}/handlers/init.d.ts +0 -0
- /package/dist/{src/cli → cli}/handlers/release.d.ts +0 -0
- /package/dist/{src/cli → cli}/handlers/rollback.d.ts +0 -0
- /package/dist/{src/cli → cli}/handlers/save.d.ts +0 -0
- /package/dist/{src/cli → cli}/handlers/status.d.ts +0 -0
- /package/dist/{src/cli → cli}/handlers/utils.d.ts +0 -0
- /package/dist/{scripts/workspace-start-warning.d.ts → cli/operations-types.js} +0 -0
- /package/dist/{src/cli → cli}/repair.d.ts +0 -0
- /package/dist/{src/index.d.ts → index.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -2,22 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
Operator-facing Treeseed CLI package.
|
|
4
4
|
|
|
5
|
-
This package publishes the `treeseed` binary.
|
|
5
|
+
This package publishes the `treeseed` binary. `@treeseed/sdk` owns the reusable workflow and runtime capabilities; `@treeseed/cli` owns argv parsing, command help, terminal formatting, command handlers, and the installable executable surface.
|
|
6
6
|
|
|
7
7
|
## Requirements
|
|
8
8
|
|
|
9
|
-
- Node `>=
|
|
9
|
+
- Node `>=22`
|
|
10
10
|
- npm as the canonical package manager for install, CI, and release flows
|
|
11
11
|
|
|
12
12
|
## Install
|
|
13
13
|
|
|
14
|
-
Install the CLI
|
|
14
|
+
Install the CLI with its runtime dependencies:
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
-
npm install @treeseed/cli @treeseed/
|
|
17
|
+
npm install @treeseed/cli @treeseed/sdk @treeseed/agent
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
`@treeseed/cli`
|
|
20
|
+
`@treeseed/cli` is a thin installable wrapper over `@treeseed/sdk` workflow and operations interfaces plus the `@treeseed/agent` command namespace. In normal consumer installs, npm resolves the runtime dependencies automatically.
|
|
21
21
|
|
|
22
22
|
After installation, the published binary is available as:
|
|
23
23
|
|
|
@@ -29,36 +29,37 @@ treeseed --help
|
|
|
29
29
|
|
|
30
30
|
The main workflow commands exposed by the current CLI are:
|
|
31
31
|
|
|
32
|
-
- `treeseed setup`
|
|
33
|
-
- `treeseed work <branch-name> [--preview]`
|
|
34
|
-
- `treeseed ship "<commit message>"`
|
|
35
|
-
- `treeseed publish --environment <local|staging|prod>`
|
|
36
|
-
- `treeseed promote --major|--minor|--patch`
|
|
37
|
-
- `treeseed rollback <staging|prod> [--to <deploy-id|commit>]`
|
|
38
|
-
- `treeseed teardown [--environment <local|staging|prod>]`
|
|
39
32
|
- `treeseed status [--json]`
|
|
40
|
-
- `treeseed
|
|
41
|
-
- `treeseed
|
|
42
|
-
- `treeseed
|
|
43
|
-
|
|
44
|
-
|
|
33
|
+
- `treeseed config`
|
|
34
|
+
- `treeseed tasks [--json]`
|
|
35
|
+
- `treeseed switch <branch-name> [--preview]`
|
|
36
|
+
- `treeseed dev`
|
|
37
|
+
- `treeseed save "<commit message>"`
|
|
38
|
+
- `treeseed stage "<resolution message>"`
|
|
39
|
+
- `treeseed close "<close reason>"`
|
|
40
|
+
- `treeseed release --major|--minor|--patch`
|
|
41
|
+
- `treeseed destroy --environment <local|staging|prod>`
|
|
42
|
+
|
|
43
|
+
Support utilities such as `treeseed rollback`, `treeseed doctor`, `treeseed auth:*`, `treeseed template`, `treeseed sync`, `treeseed lint`, `treeseed test`, `treeseed build`, service helpers, and `treeseed agents ...` remain available.
|
|
45
44
|
|
|
46
45
|
Use `treeseed help` for the full command list and `treeseed help <command>` for command-specific usage, options, and examples.
|
|
47
46
|
|
|
48
47
|
## Common Commands
|
|
49
48
|
|
|
50
49
|
```bash
|
|
51
|
-
treeseed
|
|
52
|
-
treeseed
|
|
53
|
-
treeseed
|
|
54
|
-
treeseed
|
|
55
|
-
treeseed
|
|
50
|
+
treeseed status
|
|
51
|
+
treeseed config
|
|
52
|
+
treeseed switch feature/search-improvements --preview
|
|
53
|
+
treeseed dev
|
|
54
|
+
treeseed save "feat: add search filters"
|
|
55
|
+
treeseed stage "feat: add search filters"
|
|
56
|
+
treeseed release --patch
|
|
56
57
|
treeseed status --json
|
|
57
58
|
```
|
|
58
59
|
|
|
59
60
|
## Maintainer Workflow
|
|
60
61
|
|
|
61
|
-
All package maintenance commands are npm-based and run from the `cli/` package root.
|
|
62
|
+
All package maintenance commands are npm-based and run from the `cli/` package root. This package verifies the published command surface, parser/help behavior, and packaged artifact shape.
|
|
62
63
|
|
|
63
64
|
Install dependencies:
|
|
64
65
|
|
|
@@ -88,8 +89,8 @@ The release verification flow is intentionally stricter than a normal test run:
|
|
|
88
89
|
|
|
89
90
|
1. Build `dist`
|
|
90
91
|
2. Validate publishable output for forbidden workspace references
|
|
91
|
-
3.
|
|
92
|
-
4. Run
|
|
92
|
+
3. Assert the published artifact only contains the thin wrapper entrypoints
|
|
93
|
+
4. Run the CLI wrapper test suite
|
|
93
94
|
5. Pack the CLI tarball
|
|
94
95
|
6. Smoke-test the packed install by running `treeseed --help` from the packed artifact
|
|
95
96
|
|
|
@@ -112,4 +113,4 @@ For example, package version `0.1.0` publishes from tag `0.1.0`.
|
|
|
112
113
|
## Notes
|
|
113
114
|
|
|
114
115
|
- `package-lock.json` should be committed and kept current so `npm ci` remains reproducible in CI and release jobs.
|
|
115
|
-
- The README intentionally documents the command surface at a high level. The canonical source of
|
|
116
|
+
- The README intentionally documents the command surface at a high level. The canonical source of operation identity and semantics is `@treeseed/sdk`, while `@treeseed/cli` owns argv parsing, help rendering, and terminal formatting.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { RemoteTreeseedAuthClient, RemoteTreeseedClient } from "@treeseed/sdk/remote";
|
|
2
|
+
import {
|
|
3
|
+
resolveTreeseedRemoteConfig,
|
|
4
|
+
setTreeseedRemoteSession
|
|
5
|
+
} from "@treeseed/sdk/workflow-support";
|
|
6
|
+
import { guidedResult } from "./utils.js";
|
|
7
|
+
function sleep(ms) {
|
|
8
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
9
|
+
}
|
|
10
|
+
const handleAuthLogin = async (invocation, context) => {
|
|
11
|
+
const tenantRoot = context.cwd;
|
|
12
|
+
const remoteConfig = resolveTreeseedRemoteConfig(tenantRoot, context.env);
|
|
13
|
+
const hostId = typeof invocation.args.host === "string" ? invocation.args.host : remoteConfig.activeHostId;
|
|
14
|
+
const client = new RemoteTreeseedAuthClient(new RemoteTreeseedClient({
|
|
15
|
+
...remoteConfig,
|
|
16
|
+
activeHostId: hostId
|
|
17
|
+
}));
|
|
18
|
+
const started = await client.startDeviceFlow({
|
|
19
|
+
clientName: "treeseed-cli",
|
|
20
|
+
scopes: ["auth:me", "sdk", "operations"]
|
|
21
|
+
});
|
|
22
|
+
if (context.outputFormat !== "json") {
|
|
23
|
+
context.write(`Open ${started.verificationUriComplete}`, "stdout");
|
|
24
|
+
context.write(`User code: ${started.userCode}`, "stdout");
|
|
25
|
+
context.write("Waiting for approval...", "stdout");
|
|
26
|
+
}
|
|
27
|
+
const deadline = Date.parse(started.expiresAt);
|
|
28
|
+
while (Date.now() < deadline) {
|
|
29
|
+
const response = await client.pollDeviceFlow({ deviceCode: started.deviceCode });
|
|
30
|
+
if (response.ok && response.status === "approved") {
|
|
31
|
+
setTreeseedRemoteSession(tenantRoot, {
|
|
32
|
+
hostId,
|
|
33
|
+
accessToken: response.accessToken,
|
|
34
|
+
refreshToken: response.refreshToken,
|
|
35
|
+
expiresAt: response.expiresAt,
|
|
36
|
+
principal: response.principal
|
|
37
|
+
});
|
|
38
|
+
return guidedResult({
|
|
39
|
+
command: "auth:login",
|
|
40
|
+
summary: "Treeseed API login completed successfully.",
|
|
41
|
+
facts: [
|
|
42
|
+
{ label: "Host", value: hostId },
|
|
43
|
+
{ label: "Principal", value: response.principal.displayName ?? response.principal.id },
|
|
44
|
+
{ label: "Scopes", value: response.principal.scopes.join(", ") }
|
|
45
|
+
],
|
|
46
|
+
report: {
|
|
47
|
+
hostId,
|
|
48
|
+
principal: response.principal
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
if (!response.ok && response.status !== "already_used") {
|
|
53
|
+
return {
|
|
54
|
+
exitCode: 1,
|
|
55
|
+
stderr: [response.error]
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
await sleep(started.intervalSeconds * 1e3);
|
|
59
|
+
}
|
|
60
|
+
return {
|
|
61
|
+
exitCode: 1,
|
|
62
|
+
stderr: ["Treeseed API login expired before approval completed."]
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
export {
|
|
66
|
+
handleAuthLogin
|
|
67
|
+
};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
clearTreeseedRemoteSession,
|
|
3
|
+
resolveTreeseedRemoteConfig
|
|
4
|
+
} from "@treeseed/sdk/workflow-support";
|
|
5
|
+
import { guidedResult } from "./utils.js";
|
|
6
|
+
const handleAuthLogout = async (invocation, context) => {
|
|
7
|
+
const tenantRoot = context.cwd;
|
|
8
|
+
const remoteConfig = resolveTreeseedRemoteConfig(tenantRoot, context.env);
|
|
9
|
+
const hostId = typeof invocation.args.host === "string" ? invocation.args.host : remoteConfig.activeHostId;
|
|
10
|
+
clearTreeseedRemoteSession(tenantRoot, hostId);
|
|
11
|
+
return guidedResult({
|
|
12
|
+
command: "auth:logout",
|
|
13
|
+
summary: "Cleared the local Treeseed API session.",
|
|
14
|
+
facts: [{ label: "Host", value: hostId }],
|
|
15
|
+
report: { hostId }
|
|
16
|
+
});
|
|
17
|
+
};
|
|
18
|
+
export {
|
|
19
|
+
handleAuthLogout
|
|
20
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { RemoteTreeseedAuthClient, RemoteTreeseedClient } from "@treeseed/sdk/remote";
|
|
2
|
+
import { resolveTreeseedRemoteConfig } from "@treeseed/sdk/workflow-support";
|
|
3
|
+
import { guidedResult } from "./utils.js";
|
|
4
|
+
const handleAuthWhoAmI = async (_invocation, context) => {
|
|
5
|
+
const remoteConfig = resolveTreeseedRemoteConfig(context.cwd, context.env);
|
|
6
|
+
const client = new RemoteTreeseedAuthClient(new RemoteTreeseedClient(remoteConfig));
|
|
7
|
+
const response = await client.whoAmI();
|
|
8
|
+
return guidedResult({
|
|
9
|
+
command: "auth:whoami",
|
|
10
|
+
summary: "Treeseed API identity",
|
|
11
|
+
facts: [
|
|
12
|
+
{ label: "Host", value: remoteConfig.activeHostId },
|
|
13
|
+
{ label: "Principal", value: response.payload.displayName ?? response.payload.id },
|
|
14
|
+
{ label: "Scopes", value: response.payload.scopes.join(", ") }
|
|
15
|
+
],
|
|
16
|
+
report: {
|
|
17
|
+
hostId: remoteConfig.activeHostId,
|
|
18
|
+
principal: response.payload
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
export {
|
|
23
|
+
handleAuthWhoAmI
|
|
24
|
+
};
|
|
@@ -1,59 +1,25 @@
|
|
|
1
|
-
import { applyTreeseedEnvironmentToProcess } from "../../scripts/config-runtime-lib.js";
|
|
2
|
-
import {
|
|
3
|
-
cleanupDestroyedState,
|
|
4
|
-
createBranchPreviewDeployTarget,
|
|
5
|
-
destroyCloudflareResources,
|
|
6
|
-
loadDeployState,
|
|
7
|
-
printDestroySummary,
|
|
8
|
-
validateDestroyPrerequisites
|
|
9
|
-
} from "../../scripts/deploy-lib.js";
|
|
10
|
-
import {
|
|
11
|
-
assertFeatureBranch,
|
|
12
|
-
deleteLocalBranch,
|
|
13
|
-
deleteRemoteBranch,
|
|
14
|
-
mergeCurrentBranchIntoStaging
|
|
15
|
-
} from "../../scripts/git-workflow-lib.js";
|
|
16
|
-
import { loadCliDeployConfig } from "../../scripts/package-tools.js";
|
|
17
|
-
import { runWorkspaceSavePreflight } from "../../scripts/save-deploy-preflight-lib.js";
|
|
18
1
|
import { guidedResult } from "./utils.js";
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
applyTreeseedEnvironmentToProcess({ tenantRoot, scope: "staging" });
|
|
30
|
-
validateDestroyPrerequisites(tenantRoot, { requireRemote: true });
|
|
31
|
-
const result = destroyCloudflareResources(tenantRoot, { target: previewTarget });
|
|
32
|
-
printDestroySummary(result);
|
|
33
|
-
}
|
|
34
|
-
cleanupDestroyedState(tenantRoot, { target: previewTarget });
|
|
35
|
-
deleteRemoteBranch(repoDir, featureBranch);
|
|
36
|
-
deleteLocalBranch(repoDir, featureBranch);
|
|
37
|
-
return {
|
|
38
|
-
...guidedResult({
|
|
39
|
-
command: commandName,
|
|
40
|
-
summary: `Treeseed ${commandName} completed successfully.`,
|
|
2
|
+
import { createWorkflowSdk, renderWorkflowNextSteps, workflowErrorResult } from "./workflow.js";
|
|
3
|
+
const handleClose = async (invocation, context) => {
|
|
4
|
+
try {
|
|
5
|
+
const result = await createWorkflowSdk(context).close({
|
|
6
|
+
message: invocation.positionals.join(" ").trim()
|
|
7
|
+
});
|
|
8
|
+
const payload = result.payload;
|
|
9
|
+
return guidedResult({
|
|
10
|
+
command: invocation.commandName || "close",
|
|
11
|
+
summary: "Treeseed close completed successfully.",
|
|
41
12
|
facts: [
|
|
42
|
-
{ label: "
|
|
43
|
-
{ label: "
|
|
44
|
-
{ label: "Preview cleanup", value:
|
|
45
|
-
],
|
|
46
|
-
nextSteps: [
|
|
47
|
-
"treeseed deploy --environment staging",
|
|
48
|
-
"treeseed release --patch"
|
|
13
|
+
{ label: "Closed branch", value: payload.branchName },
|
|
14
|
+
{ label: "Deprecated tag", value: payload.deprecatedTag.tagName },
|
|
15
|
+
{ label: "Preview cleanup", value: payload.previewCleanup.performed ? "performed" : "not needed" }
|
|
49
16
|
],
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
};
|
|
17
|
+
nextSteps: renderWorkflowNextSteps(result),
|
|
18
|
+
report: payload
|
|
19
|
+
});
|
|
20
|
+
} catch (error) {
|
|
21
|
+
return workflowErrorResult(error);
|
|
22
|
+
}
|
|
57
23
|
};
|
|
58
24
|
export {
|
|
59
25
|
handleClose
|
|
@@ -1,72 +1,52 @@
|
|
|
1
1
|
import readline from "node:readline/promises";
|
|
2
2
|
import { stdin as input, stdout as output } from "node:process";
|
|
3
|
-
import { collectCliPreflight } from "../../scripts/workspace-preflight-lib.js";
|
|
4
|
-
import {
|
|
5
|
-
applyTreeseedEnvironmentToProcess,
|
|
6
|
-
ensureTreeseedGitignoreEntries,
|
|
7
|
-
getTreeseedMachineConfigPaths,
|
|
8
|
-
runTreeseedConfigWizard,
|
|
9
|
-
writeTreeseedLocalEnvironmentFiles
|
|
10
|
-
} from "../../scripts/config-runtime-lib.js";
|
|
11
3
|
import { guidedResult } from "./utils.js";
|
|
4
|
+
import { createWorkflowSdk, renderWorkflowNextSteps, workflowErrorResult } from "./workflow.js";
|
|
12
5
|
const handleConfig = async (invocation, context) => {
|
|
13
|
-
const commandName = invocation.commandName || "config";
|
|
14
|
-
const tenantRoot = context.cwd;
|
|
15
|
-
const scopes = Array.isArray(invocation.args.environment) ? invocation.args.environment : invocation.args.environment ? [invocation.args.environment] : ["local", "staging", "prod"];
|
|
16
|
-
const sync = typeof invocation.args.sync === "string" ? invocation.args.sync : "none";
|
|
17
|
-
ensureTreeseedGitignoreEntries(tenantRoot);
|
|
18
|
-
const preflight = collectCliPreflight({ cwd: tenantRoot, requireAuth: false });
|
|
19
6
|
const rl = readline.createInterface({ input, output });
|
|
20
7
|
try {
|
|
21
|
-
|
|
22
|
-
context.
|
|
23
|
-
context.write
|
|
24
|
-
context.write('Enter a value to set it, press Enter to keep the current/default value, or enter "-" to clear a value.\n', "stdout");
|
|
25
|
-
}
|
|
26
|
-
const result = await runTreeseedConfigWizard({
|
|
27
|
-
tenantRoot,
|
|
28
|
-
scopes,
|
|
29
|
-
sync,
|
|
30
|
-
authStatus: preflight.checks.auth,
|
|
31
|
-
write: context.outputFormat === "json" ? () => {
|
|
32
|
-
} : ((line) => context.write(line, "stdout")),
|
|
8
|
+
const workflow = createWorkflowSdk(context, {
|
|
9
|
+
write: context.outputFormat === "json" ? (() => {
|
|
10
|
+
}) : context.write,
|
|
33
11
|
prompt: async (message) => {
|
|
34
12
|
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
35
13
|
return "";
|
|
36
14
|
}
|
|
37
|
-
|
|
38
|
-
return await rl.question(message);
|
|
39
|
-
} catch {
|
|
40
|
-
return "";
|
|
41
|
-
}
|
|
15
|
+
return rl.question(message);
|
|
42
16
|
}
|
|
43
17
|
});
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
18
|
+
const result = await workflow.config({
|
|
19
|
+
environment: invocation.args.environment,
|
|
20
|
+
sync: invocation.args.sync,
|
|
21
|
+
printEnv: invocation.args.printEnv === true,
|
|
22
|
+
printEnvOnly: invocation.args.printEnvOnly === true,
|
|
23
|
+
showSecrets: invocation.args.showSecrets === true,
|
|
24
|
+
rotateMachineKey: invocation.args.rotateMachineKey === true,
|
|
25
|
+
nonInteractive: context.outputFormat === "json"
|
|
26
|
+
});
|
|
27
|
+
const payload = result.payload;
|
|
28
|
+
const toolHealth = payload.toolHealth;
|
|
29
|
+
const summary = payload.mode === "print-env-only" ? "Treeseed config environment report completed." : payload.mode === "rotate-machine-key" ? "Treeseed machine key rotated successfully." : "Treeseed config completed successfully.";
|
|
47
30
|
return guidedResult({
|
|
48
|
-
command: commandName,
|
|
49
|
-
summary
|
|
31
|
+
command: invocation.commandName || "config",
|
|
32
|
+
summary,
|
|
50
33
|
facts: [
|
|
51
|
-
{ label: "
|
|
52
|
-
{ label: "
|
|
53
|
-
{ label: "
|
|
54
|
-
{ label: "
|
|
55
|
-
{ label: "
|
|
56
|
-
{ label: "
|
|
34
|
+
{ label: "Mode", value: payload.mode },
|
|
35
|
+
{ label: "Scopes", value: Array.isArray(payload.scopes) ? payload.scopes.join(", ") : "(none)" },
|
|
36
|
+
{ label: "Sync", value: payload.sync ?? "all" },
|
|
37
|
+
{ label: "Safe repairs", value: Array.isArray(payload.repairs) ? payload.repairs.length : 0 },
|
|
38
|
+
{ label: "Machine config", value: payload.configPath },
|
|
39
|
+
{ label: "Machine key", value: payload.keyPath },
|
|
40
|
+
{ label: "GitHub CLI", value: toolHealth?.githubCli?.available ? "ready" : "missing" },
|
|
41
|
+
{ label: "gh act", value: toolHealth?.ghActExtension?.available ? "ready" : "missing" },
|
|
42
|
+
{ label: "Docker", value: toolHealth?.dockerDaemon?.available ? "ready" : "missing" },
|
|
43
|
+
{ label: "ACT verify", value: toolHealth?.actVerificationReady ? "ready" : "not ready" }
|
|
57
44
|
],
|
|
58
|
-
nextSteps:
|
|
59
|
-
|
|
60
|
-
...scopes.includes("staging") ? ["treeseed deploy --environment staging"] : [],
|
|
61
|
-
...scopes.includes("prod") ? ["treeseed deploy --environment prod"] : []
|
|
62
|
-
],
|
|
63
|
-
report: {
|
|
64
|
-
scopes,
|
|
65
|
-
sync,
|
|
66
|
-
result,
|
|
67
|
-
preflight
|
|
68
|
-
}
|
|
45
|
+
nextSteps: renderWorkflowNextSteps(result),
|
|
46
|
+
report: payload
|
|
69
47
|
});
|
|
48
|
+
} catch (error) {
|
|
49
|
+
return workflowErrorResult(error);
|
|
70
50
|
} finally {
|
|
71
51
|
rl.close();
|
|
72
52
|
}
|
|
@@ -1,93 +1,48 @@
|
|
|
1
1
|
import readline from "node:readline/promises";
|
|
2
2
|
import { stdin as input, stdout as output } from "node:process";
|
|
3
|
-
import { applyTreeseedEnvironmentToProcess, assertTreeseedCommandEnvironment } from "../../scripts/config-runtime-lib.js";
|
|
4
|
-
import {
|
|
5
|
-
cleanupDestroyedState,
|
|
6
|
-
createPersistentDeployTarget,
|
|
7
|
-
destroyCloudflareResources,
|
|
8
|
-
loadDeployState,
|
|
9
|
-
printDestroySummary,
|
|
10
|
-
validateDestroyPrerequisites
|
|
11
|
-
} from "../../scripts/deploy-lib.js";
|
|
12
3
|
import { guidedResult } from "./utils.js";
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
context.write(" This action is irreversible.", "stderr");
|
|
22
|
-
context.write(` To continue, type exactly: ${expectedConfirmation}`, "stderr");
|
|
4
|
+
import { createWorkflowSdk, renderWorkflowNextSteps, workflowErrorResult } from "./workflow.js";
|
|
5
|
+
async function promptForConfirmation(expected) {
|
|
6
|
+
const rl = readline.createInterface({ input, output });
|
|
7
|
+
try {
|
|
8
|
+
return (await rl.question("Confirmation: ")).trim();
|
|
9
|
+
} finally {
|
|
10
|
+
rl.close();
|
|
11
|
+
}
|
|
23
12
|
}
|
|
24
13
|
const handleDestroy = async (invocation, context) => {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
assertTreeseedCommandEnvironment({ tenantRoot, scope, purpose: "destroy" });
|
|
36
|
-
const deployConfig = validateDestroyPrerequisites(tenantRoot, { requireRemote: !dryRun });
|
|
37
|
-
const state = loadDeployState(tenantRoot, deployConfig, { target });
|
|
38
|
-
const expectedConfirmation = deployConfig.slug;
|
|
39
|
-
if (!skipConfirmation) {
|
|
40
|
-
printDangerMessage(context, deployConfig, state, expectedConfirmation);
|
|
41
|
-
const confirmed = confirm !== null ? confirm === expectedConfirmation : await (async () => {
|
|
42
|
-
const rl = readline.createInterface({ input, output });
|
|
43
|
-
try {
|
|
44
|
-
return (await rl.question("Confirmation: ")).trim() === expectedConfirmation;
|
|
45
|
-
} finally {
|
|
46
|
-
rl.close();
|
|
14
|
+
try {
|
|
15
|
+
const result = await createWorkflowSdk(context, {
|
|
16
|
+
confirm: async (_message, expected) => {
|
|
17
|
+
if (typeof invocation.args.confirm === "string") {
|
|
18
|
+
return invocation.args.confirm === expected;
|
|
19
|
+
}
|
|
20
|
+
if (invocation.args.skipConfirmation === true || context.outputFormat === "json" || !process.stdin.isTTY || !process.stdout.isTTY) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
return await promptForConfirmation(expected) === expected;
|
|
47
24
|
}
|
|
48
|
-
})(
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
if (dryRun) {
|
|
25
|
+
}).destroy({
|
|
26
|
+
environment: String(invocation.args.environment),
|
|
27
|
+
dryRun: invocation.args.dryRun === true,
|
|
28
|
+
force: invocation.args.force === true,
|
|
29
|
+
removeBuildArtifacts: invocation.args.removeBuildArtifacts === true
|
|
30
|
+
});
|
|
31
|
+
const payload = result.payload;
|
|
56
32
|
return guidedResult({
|
|
57
|
-
command: commandName,
|
|
58
|
-
summary:
|
|
33
|
+
command: invocation.commandName || "destroy",
|
|
34
|
+
summary: payload.dryRun ? "Treeseed destroy dry run completed." : "Treeseed destroy completed successfully.",
|
|
59
35
|
facts: [
|
|
60
|
-
{ label: "Environment", value: scope },
|
|
61
|
-
{ label: "
|
|
36
|
+
{ label: "Environment", value: payload.scope },
|
|
37
|
+
{ label: "Dry run", value: payload.dryRun ? "yes" : "no" },
|
|
38
|
+
{ label: "Removed build artifacts", value: payload.removeBuildArtifacts ? "yes" : "no" }
|
|
62
39
|
],
|
|
63
|
-
nextSteps:
|
|
64
|
-
report:
|
|
65
|
-
scope,
|
|
66
|
-
dryRun: true,
|
|
67
|
-
force,
|
|
68
|
-
removeBuildArtifacts
|
|
69
|
-
}
|
|
40
|
+
nextSteps: renderWorkflowNextSteps(result),
|
|
41
|
+
report: payload
|
|
70
42
|
});
|
|
43
|
+
} catch (error) {
|
|
44
|
+
return workflowErrorResult(error);
|
|
71
45
|
}
|
|
72
|
-
cleanupDestroyedState(tenantRoot, { target, removeBuildArtifacts });
|
|
73
|
-
return guidedResult({
|
|
74
|
-
command: commandName,
|
|
75
|
-
summary: `Treeseed ${commandName} completed and local deployment state was removed.`,
|
|
76
|
-
facts: [
|
|
77
|
-
{ label: "Environment", value: scope },
|
|
78
|
-
{ label: "Removed build artifacts", value: removeBuildArtifacts ? "yes" : "no" }
|
|
79
|
-
],
|
|
80
|
-
nextSteps: [
|
|
81
|
-
`treeseed config --environment ${scope}`,
|
|
82
|
-
"treeseed status"
|
|
83
|
-
],
|
|
84
|
-
report: {
|
|
85
|
-
scope,
|
|
86
|
-
dryRun: false,
|
|
87
|
-
force,
|
|
88
|
-
removeBuildArtifacts
|
|
89
|
-
}
|
|
90
|
-
});
|
|
91
46
|
};
|
|
92
47
|
export {
|
|
93
48
|
handleDestroy
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { TreeseedCommandHandler } from '../types.js';
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const handleDev: TreeseedCommandHandler;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { createWorkflowSdk, workflowErrorResult } from "./workflow.js";
|
|
2
|
+
const handleDev = async (invocation, context) => {
|
|
3
|
+
try {
|
|
4
|
+
const result = await createWorkflowSdk(context).dev({
|
|
5
|
+
watch: invocation.commandName === "dev:watch" || invocation.args.watch === true,
|
|
6
|
+
background: false,
|
|
7
|
+
stdio: "inherit"
|
|
8
|
+
});
|
|
9
|
+
return {
|
|
10
|
+
exitCode: result.ok ? 0 : 1,
|
|
11
|
+
report: result.payload
|
|
12
|
+
};
|
|
13
|
+
} catch (error) {
|
|
14
|
+
return workflowErrorResult(error);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
export {
|
|
18
|
+
handleDev
|
|
19
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { collectCliPreflight } from "
|
|
1
|
+
import { collectCliPreflight } from "@treeseed/sdk/workflow-support";
|
|
2
2
|
import { guidedResult } from "./utils.js";
|
|
3
3
|
import { resolveTreeseedWorkflowState } from "../workflow-state.js";
|
|
4
4
|
import { applyTreeseedSafeRepairs } from "../repair.js";
|
|
@@ -6,19 +6,26 @@ const handleDoctor = (invocation, context) => {
|
|
|
6
6
|
const performedFixes = invocation.args.fix === true && resolveTreeseedWorkflowState(context.cwd).deployConfigPresent ? applyTreeseedSafeRepairs(context.cwd) : [];
|
|
7
7
|
const state = resolveTreeseedWorkflowState(context.cwd);
|
|
8
8
|
const preflight = collectCliPreflight({ cwd: context.cwd, requireAuth: false });
|
|
9
|
+
const railwayManagedServicesEnabled = Object.values(state.managedServices).some((service) => service.enabled);
|
|
9
10
|
const mustFixNow = [];
|
|
10
11
|
const optional = [];
|
|
11
|
-
if (!state.workspaceRoot) mustFixNow.push("Run Treeseed
|
|
12
|
-
if (!state.repoRoot) mustFixNow.push("Initialize or clone the git repository before using save, close,
|
|
12
|
+
if (!state.workspaceRoot) mustFixNow.push("Run Treeseed inside a Treeseed workspace so package commands and workflow state can resolve correctly.");
|
|
13
|
+
if (!state.repoRoot) mustFixNow.push("Initialize or clone the git repository before using save, close, stage, or release flows.");
|
|
13
14
|
if (!state.deployConfigPresent) mustFixNow.push("Create or restore treeseed.site.yaml so the tenant contract can be loaded.");
|
|
14
15
|
if (preflight.missingCommands.includes("git")) mustFixNow.push("Install Git.");
|
|
15
16
|
if (preflight.missingCommands.includes("npm")) mustFixNow.push("Install npm 10 or newer.");
|
|
16
17
|
if (!state.files.machineConfig) mustFixNow.push("Run `treeseed config --environment local` to create the local machine config.");
|
|
17
18
|
if (!state.files.envLocal) optional.push("Create `.env.local` or run `treeseed config --environment local` to generate it.");
|
|
18
19
|
if (!state.files.devVars) optional.push("Generate `.dev.vars` by running `treeseed config --environment local`.");
|
|
19
|
-
if (!state.auth.gh) optional.push("
|
|
20
|
-
if (!state.auth.wrangler) optional.push("
|
|
21
|
-
if (!state.auth.
|
|
20
|
+
if (!state.auth.gh) optional.push("Configure `GH_TOKEN` for GitHub CLI automation and Copilot-backed workflows.");
|
|
21
|
+
if (!state.auth.wrangler) optional.push("Configure `CLOUDFLARE_API_TOKEN` before staging, preview, or production deployment work.");
|
|
22
|
+
if (!state.auth.railway && railwayManagedServicesEnabled) {
|
|
23
|
+
optional.push("Configure `RAILWAY_API_TOKEN` before deploying the managed Railway services.");
|
|
24
|
+
}
|
|
25
|
+
if (!state.auth.remoteApi && state.managedServices.api.enabled) {
|
|
26
|
+
optional.push("Run `treeseed auth:login` so the CLI can use the configured remote API.");
|
|
27
|
+
}
|
|
28
|
+
if (!state.auth.copilot) optional.push("Configure `GH_TOKEN` if you rely on local Copilot-assisted workflows.");
|
|
22
29
|
return guidedResult({
|
|
23
30
|
command: "doctor",
|
|
24
31
|
summary: mustFixNow.length === 0 ? "Treeseed doctor found no blocking issues." : "Treeseed doctor found issues that need attention.",
|