beth-copilot 1.0.18 → 1.1.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/CHANGELOG.md +41 -28
- package/README.md +87 -247
- package/bin/cli.js +158 -358
- package/dist/__tests__/smoke.test.d.ts +8 -0
- package/dist/__tests__/smoke.test.d.ts.map +1 -0
- package/dist/__tests__/smoke.test.js +49 -0
- package/dist/__tests__/smoke.test.js.map +1 -0
- package/dist/cli/commands/beads.e2e.test.d.ts +13 -0
- package/dist/cli/commands/beads.e2e.test.d.ts.map +1 -0
- package/dist/cli/commands/beads.e2e.test.js +526 -0
- package/dist/cli/commands/beads.e2e.test.js.map +1 -0
- package/dist/cli/commands/cli-edge-cases.e2e.test.d.ts +32 -0
- package/dist/cli/commands/cli-edge-cases.e2e.test.d.ts.map +1 -0
- package/dist/cli/commands/cli-edge-cases.e2e.test.js +162 -0
- package/dist/cli/commands/cli-edge-cases.e2e.test.js.map +1 -0
- package/dist/cli/commands/close.d.ts +89 -0
- package/dist/cli/commands/close.d.ts.map +1 -0
- package/dist/cli/commands/close.e2e.test.d.ts +27 -0
- package/dist/cli/commands/close.e2e.test.d.ts.map +1 -0
- package/dist/cli/commands/close.e2e.test.js +252 -0
- package/dist/cli/commands/close.e2e.test.js.map +1 -0
- package/dist/cli/commands/close.js +309 -0
- package/dist/cli/commands/close.js.map +1 -0
- package/dist/cli/commands/close.test.d.ts +15 -0
- package/dist/cli/commands/close.test.d.ts.map +1 -0
- package/dist/cli/commands/close.test.js +634 -0
- package/dist/cli/commands/close.test.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +23 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/doctor.js +93 -0
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/doctor.test.js +209 -0
- package/dist/cli/commands/doctor.test.js.map +1 -1
- package/dist/cli/commands/framework-isolation.test.d.ts +30 -0
- package/dist/cli/commands/framework-isolation.test.d.ts.map +1 -0
- package/dist/cli/commands/framework-isolation.test.js +119 -0
- package/dist/cli/commands/framework-isolation.test.js.map +1 -0
- package/dist/cli/commands/help.e2e.test.js +4 -4
- package/dist/cli/commands/help.e2e.test.js.map +1 -1
- package/dist/cli/commands/init-logic.e2e.test.d.ts +37 -0
- package/dist/cli/commands/init-logic.e2e.test.d.ts.map +1 -0
- package/dist/cli/commands/init-logic.e2e.test.js +305 -0
- package/dist/cli/commands/init-logic.e2e.test.js.map +1 -0
- package/dist/cli/commands/land.d.ts +142 -0
- package/dist/cli/commands/land.d.ts.map +1 -0
- package/dist/cli/commands/land.js +647 -0
- package/dist/cli/commands/land.js.map +1 -0
- package/dist/cli/commands/land.test.d.ts +20 -0
- package/dist/cli/commands/land.test.d.ts.map +1 -0
- package/dist/cli/commands/land.test.js +622 -0
- package/dist/cli/commands/land.test.js.map +1 -0
- package/dist/cli/commands/mcp.e2e.test.js +22 -29
- package/dist/cli/commands/mcp.e2e.test.js.map +1 -1
- package/dist/cli/commands/pipeline.e2e.test.js +20 -20
- package/dist/cli/commands/pipeline.e2e.test.js.map +1 -1
- package/dist/cli/commands/pre-push-guard.d.ts +84 -0
- package/dist/cli/commands/pre-push-guard.d.ts.map +1 -0
- package/dist/cli/commands/pre-push-guard.e2e.test.d.ts +24 -0
- package/dist/cli/commands/pre-push-guard.e2e.test.d.ts.map +1 -0
- package/dist/cli/commands/pre-push-guard.e2e.test.js +171 -0
- package/dist/cli/commands/pre-push-guard.e2e.test.js.map +1 -0
- package/dist/cli/commands/pre-push-guard.js +257 -0
- package/dist/cli/commands/pre-push-guard.js.map +1 -0
- package/dist/cli/commands/pre-push-guard.test.d.ts +15 -0
- package/dist/cli/commands/pre-push-guard.test.d.ts.map +1 -0
- package/dist/cli/commands/pre-push-guard.test.js +397 -0
- package/dist/cli/commands/pre-push-guard.test.js.map +1 -0
- package/dist/cli/commands/quickstart-expanded.e2e.test.d.ts +23 -0
- package/dist/cli/commands/quickstart-expanded.e2e.test.d.ts.map +1 -0
- package/dist/cli/commands/quickstart-expanded.e2e.test.js +179 -0
- package/dist/cli/commands/quickstart-expanded.e2e.test.js.map +1 -0
- package/dist/cli/commands/quickstart.d.ts.map +1 -1
- package/dist/cli/commands/quickstart.js +7 -23
- package/dist/cli/commands/quickstart.js.map +1 -1
- package/dist/cli/commands/quickstart.test.js +40 -67
- package/dist/cli/commands/quickstart.test.js.map +1 -1
- package/dist/core/agents/suite.test.js +4 -2
- package/dist/core/agents/suite.test.js.map +1 -1
- package/dist/core/agents/tools.test.js +5 -1
- package/dist/core/agents/tools.test.js.map +1 -1
- package/dist/index.d.ts +3 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -10
- package/dist/index.js.map +1 -1
- package/package.json +15 -9
- package/sbom.json +2011 -819
- package/templates/.github/agents/beth.agent.md +220 -66
- package/templates/.github/agents/developer.agent.md +53 -90
- package/templates/.github/agents/product-manager.agent.md +15 -68
- package/templates/.github/agents/researcher.agent.md +20 -71
- package/templates/.github/agents/security-reviewer.agent.md +29 -81
- package/templates/.github/agents/tester.agent.md +40 -69
- package/templates/.github/agents/ux-designer.agent.md +20 -74
- package/templates/.github/copilot-instructions.md +217 -225
- package/templates/AGENTS.md +108 -20
- package/templates/mcp.json.example +0 -3
- package/dist/cli/commands/client-config.d.ts +0 -31
- package/dist/cli/commands/client-config.d.ts.map +0 -1
- package/dist/cli/commands/client-config.e2e.test.d.ts +0 -15
- package/dist/cli/commands/client-config.e2e.test.d.ts.map +0 -1
- package/dist/cli/commands/client-config.e2e.test.js +0 -556
- package/dist/cli/commands/client-config.e2e.test.js.map +0 -1
- package/dist/cli/commands/client-config.js +0 -73
- package/dist/cli/commands/client-config.js.map +0 -1
- package/dist/cli/commands/client-config.test.d.ts +0 -6
- package/dist/cli/commands/client-config.test.d.ts.map +0 -1
- package/dist/cli/commands/client-config.test.js +0 -133
- package/dist/cli/commands/client-config.test.js.map +0 -1
- package/dist/cli/commands/init-quickstart.e2e.test.d.ts +0 -11
- package/dist/cli/commands/init-quickstart.e2e.test.d.ts.map +0 -1
- package/dist/cli/commands/init-quickstart.e2e.test.js +0 -221
- package/dist/cli/commands/init-quickstart.e2e.test.js.map +0 -1
- package/dist/core/context.d.ts +0 -171
- package/dist/core/context.d.ts.map +0 -1
- package/dist/core/context.js +0 -353
- package/dist/core/context.js.map +0 -1
- package/dist/core/context.test.d.ts +0 -8
- package/dist/core/context.test.d.ts.map +0 -1
- package/dist/core/context.test.js +0 -253
- package/dist/core/context.test.js.map +0 -1
- package/dist/core/handoffs.d.ts +0 -151
- package/dist/core/handoffs.d.ts.map +0 -1
- package/dist/core/handoffs.js +0 -220
- package/dist/core/handoffs.js.map +0 -1
- package/dist/core/handoffs.test.d.ts +0 -8
- package/dist/core/handoffs.test.d.ts.map +0 -1
- package/dist/core/handoffs.test.js +0 -231
- package/dist/core/handoffs.test.js.map +0 -1
- package/dist/core/orchestrator.d.ts +0 -246
- package/dist/core/orchestrator.d.ts.map +0 -1
- package/dist/core/orchestrator.js +0 -514
- package/dist/core/orchestrator.js.map +0 -1
- package/dist/core/orchestrator.test.d.ts +0 -8
- package/dist/core/orchestrator.test.d.ts.map +0 -1
- package/dist/core/orchestrator.test.js +0 -517
- package/dist/core/orchestrator.test.js.map +0 -1
- package/dist/core/router.d.ts +0 -102
- package/dist/core/router.d.ts.map +0 -1
- package/dist/core/router.js +0 -178
- package/dist/core/router.js.map +0 -1
- package/dist/core/router.test.d.ts +0 -8
- package/dist/core/router.test.d.ts.map +0 -1
- package/dist/core/router.test.js +0 -215
- package/dist/core/router.test.js.map +0 -1
- package/dist/init.test.js +0 -288
- package/dist/providers/azure.d.ts +0 -147
- package/dist/providers/azure.d.ts.map +0 -1
- package/dist/providers/azure.js +0 -491
- package/dist/providers/azure.js.map +0 -1
- package/dist/providers/azure.test.d.ts +0 -11
- package/dist/providers/azure.test.d.ts.map +0 -1
- package/dist/providers/azure.test.js +0 -330
- package/dist/providers/azure.test.js.map +0 -1
- package/dist/providers/config.d.ts +0 -87
- package/dist/providers/config.d.ts.map +0 -1
- package/dist/providers/config.js +0 -193
- package/dist/providers/config.js.map +0 -1
- package/dist/providers/config.test.d.ts +0 -7
- package/dist/providers/config.test.d.ts.map +0 -1
- package/dist/providers/config.test.js +0 -370
- package/dist/providers/config.test.js.map +0 -1
- package/dist/providers/index.d.ts +0 -18
- package/dist/providers/index.d.ts.map +0 -1
- package/dist/providers/index.js +0 -14
- package/dist/providers/index.js.map +0 -1
- package/dist/providers/interface.d.ts +0 -191
- package/dist/providers/interface.d.ts.map +0 -1
- package/dist/providers/interface.js +0 -94
- package/dist/providers/interface.js.map +0 -1
- package/dist/providers/retry.d.ts +0 -128
- package/dist/providers/retry.d.ts.map +0 -1
- package/dist/providers/retry.js +0 -205
- package/dist/providers/retry.js.map +0 -1
- package/dist/providers/retry.test.d.ts +0 -7
- package/dist/providers/retry.test.d.ts.map +0 -1
- package/dist/providers/retry.test.js +0 -439
- package/dist/providers/retry.test.js.map +0 -1
- package/dist/providers/streaming.d.ts +0 -157
- package/dist/providers/streaming.d.ts.map +0 -1
- package/dist/providers/streaming.js +0 -233
- package/dist/providers/streaming.js.map +0 -1
- package/dist/providers/streaming.test.d.ts +0 -7
- package/dist/providers/streaming.test.d.ts.map +0 -1
- package/dist/providers/streaming.test.js +0 -372
- package/dist/providers/streaming.test.js.map +0 -1
- package/dist/providers/types.d.ts +0 -209
- package/dist/providers/types.d.ts.map +0 -1
- package/dist/providers/types.js +0 -53
- package/dist/providers/types.js.map +0 -1
- package/dist/providers/types.test.d.ts +0 -7
- package/dist/providers/types.test.d.ts.map +0 -1
- package/dist/providers/types.test.js +0 -141
- package/dist/providers/types.test.js.map +0 -1
- package/dist/tools/cli/beads.d.ts +0 -27
- package/dist/tools/cli/beads.d.ts.map +0 -1
- package/dist/tools/cli/beads.js +0 -172
- package/dist/tools/cli/beads.js.map +0 -1
- package/dist/tools/cli/beads.test.d.ts +0 -8
- package/dist/tools/cli/beads.test.d.ts.map +0 -1
- package/dist/tools/cli/beads.test.js +0 -264
- package/dist/tools/cli/beads.test.js.map +0 -1
- package/dist/tools/cli/editFile.d.ts +0 -17
- package/dist/tools/cli/editFile.d.ts.map +0 -1
- package/dist/tools/cli/editFile.js +0 -125
- package/dist/tools/cli/editFile.js.map +0 -1
- package/dist/tools/cli/editFile.test.d.ts +0 -8
- package/dist/tools/cli/editFile.test.d.ts.map +0 -1
- package/dist/tools/cli/editFile.test.js +0 -177
- package/dist/tools/cli/editFile.test.js.map +0 -1
- package/dist/tools/cli/readFile.d.ts +0 -25
- package/dist/tools/cli/readFile.d.ts.map +0 -1
- package/dist/tools/cli/readFile.js +0 -118
- package/dist/tools/cli/readFile.js.map +0 -1
- package/dist/tools/cli/readFile.test.d.ts +0 -8
- package/dist/tools/cli/readFile.test.d.ts.map +0 -1
- package/dist/tools/cli/readFile.test.js +0 -194
- package/dist/tools/cli/readFile.test.js.map +0 -1
- package/dist/tools/cli/search.d.ts +0 -16
- package/dist/tools/cli/search.d.ts.map +0 -1
- package/dist/tools/cli/search.js +0 -261
- package/dist/tools/cli/search.js.map +0 -1
- package/dist/tools/cli/search.test.d.ts +0 -8
- package/dist/tools/cli/search.test.d.ts.map +0 -1
- package/dist/tools/cli/search.test.js +0 -172
- package/dist/tools/cli/search.test.js.map +0 -1
- package/dist/tools/cli/subagent.d.ts +0 -43
- package/dist/tools/cli/subagent.d.ts.map +0 -1
- package/dist/tools/cli/subagent.js +0 -99
- package/dist/tools/cli/subagent.js.map +0 -1
- package/dist/tools/cli/subagent.test.d.ts +0 -8
- package/dist/tools/cli/subagent.test.d.ts.map +0 -1
- package/dist/tools/cli/subagent.test.js +0 -190
- package/dist/tools/cli/subagent.test.js.map +0 -1
- package/dist/tools/cli/terminal.d.ts +0 -19
- package/dist/tools/cli/terminal.d.ts.map +0 -1
- package/dist/tools/cli/terminal.js +0 -164
- package/dist/tools/cli/terminal.js.map +0 -1
- package/dist/tools/cli/terminal.test.d.ts +0 -8
- package/dist/tools/cli/terminal.test.d.ts.map +0 -1
- package/dist/tools/cli/terminal.test.js +0 -161
- package/dist/tools/cli/terminal.test.js.map +0 -1
- package/dist/tools/index.d.ts +0 -25
- package/dist/tools/index.d.ts.map +0 -1
- package/dist/tools/index.js +0 -41
- package/dist/tools/index.js.map +0 -1
- package/dist/tools/interface.d.ts +0 -64
- package/dist/tools/interface.d.ts.map +0 -1
- package/dist/tools/interface.js +0 -37
- package/dist/tools/interface.js.map +0 -1
- package/dist/tools/interface.test.d.ts +0 -7
- package/dist/tools/interface.test.d.ts.map +0 -1
- package/dist/tools/interface.test.js +0 -179
- package/dist/tools/interface.test.js.map +0 -1
- package/dist/tools/mcp/bridge.d.ts +0 -48
- package/dist/tools/mcp/bridge.d.ts.map +0 -1
- package/dist/tools/mcp/bridge.js +0 -128
- package/dist/tools/mcp/bridge.js.map +0 -1
- package/dist/tools/mcp/bridge.test.d.ts +0 -8
- package/dist/tools/mcp/bridge.test.d.ts.map +0 -1
- package/dist/tools/mcp/bridge.test.js +0 -300
- package/dist/tools/mcp/bridge.test.js.map +0 -1
- package/dist/tools/mcp/client.d.ts +0 -135
- package/dist/tools/mcp/client.d.ts.map +0 -1
- package/dist/tools/mcp/client.js +0 -263
- package/dist/tools/mcp/client.js.map +0 -1
- package/dist/tools/mcp/client.test.d.ts +0 -8
- package/dist/tools/mcp/client.test.d.ts.map +0 -1
- package/dist/tools/mcp/client.test.js +0 -390
- package/dist/tools/mcp/client.test.js.map +0 -1
- package/dist/tools/registry.d.ts +0 -82
- package/dist/tools/registry.d.ts.map +0 -1
- package/dist/tools/registry.js +0 -99
- package/dist/tools/registry.js.map +0 -1
- package/dist/tools/registry.test.d.ts +0 -7
- package/dist/tools/registry.test.d.ts.map +0 -1
- package/dist/tools/registry.test.js +0 -199
- package/dist/tools/registry.test.js.map +0 -1
- package/dist/tools/suite.test.d.ts +0 -11
- package/dist/tools/suite.test.d.ts.map +0 -1
- package/dist/tools/suite.test.js +0 -119
- package/dist/tools/suite.test.js.map +0 -1
- package/dist/tools/types.d.ts +0 -75
- package/dist/tools/types.d.ts.map +0 -1
- package/dist/tools/types.js +0 -30
- package/dist/tools/types.js.map +0 -1
- package/dist/tools/types.test.d.ts +0 -7
- package/dist/tools/types.test.d.ts.map +0 -1
- package/dist/tools/types.test.js +0 -178
- package/dist/tools/types.test.js.map +0 -1
- package/templates/.vscode/mcp.json +0 -20
- package/templates/CLAUDE.md +0 -129
|
@@ -0,0 +1,647 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Land Command — Partial session completion automation
|
|
3
|
+
*
|
|
4
|
+
* `npx beth-copilot land` automates the **git-mechanical** portion of the
|
|
5
|
+
* "Landing the Plane" checklist defined in AGENTS.md. It does NOT replace
|
|
6
|
+
* the full checklist — several steps require agent judgment and are left
|
|
7
|
+
* to the caller.
|
|
8
|
+
*
|
|
9
|
+
* What this command handles:
|
|
10
|
+
* 1. Verify we're on an epic branch (not main/master)
|
|
11
|
+
* 2. Run quality gates (npm test)
|
|
12
|
+
* 3. Backup beads data (bd backup)
|
|
13
|
+
* 4. Stage, commit, and push to origin
|
|
14
|
+
* 5. Report final status
|
|
15
|
+
*
|
|
16
|
+
* What this command does NOT handle (manual / agent responsibility):
|
|
17
|
+
* - Closing beads issues (`npx beth-copilot close <id>`)
|
|
18
|
+
* - Creating follow-up issues (`bd create`)
|
|
19
|
+
* - Updating Backlog.md (human-readable completed-work archive)
|
|
20
|
+
* - Generating test gate report (`npm run test:gate`)
|
|
21
|
+
* - Creating a PR to main (`gh pr create` or GitHub MCP)
|
|
22
|
+
*
|
|
23
|
+
* See AGENTS.md → "Landing the Plane (Session Completion)" for the full
|
|
24
|
+
* checklist. Agents should complete the manual steps before or after
|
|
25
|
+
* invoking this command.
|
|
26
|
+
*
|
|
27
|
+
* Options:
|
|
28
|
+
* --skip-tests Skip test execution (not recommended)
|
|
29
|
+
* --skip-backup Skip beads backup
|
|
30
|
+
* --message, -m Custom commit message (default: "<epic-id>: session work")
|
|
31
|
+
* --force Push even if tests fail (DANGEROUS)
|
|
32
|
+
* --dry-run Show what would happen without executing
|
|
33
|
+
*/
|
|
34
|
+
import { execFileSync } from 'child_process';
|
|
35
|
+
const COLORS = {
|
|
36
|
+
reset: '\x1b[0m',
|
|
37
|
+
bright: '\x1b[1m',
|
|
38
|
+
red: '\x1b[31m',
|
|
39
|
+
green: '\x1b[32m',
|
|
40
|
+
yellow: '\x1b[33m',
|
|
41
|
+
cyan: '\x1b[36m',
|
|
42
|
+
dim: '\x1b[2m',
|
|
43
|
+
};
|
|
44
|
+
// Protected branches — cannot land from these
|
|
45
|
+
const PROTECTED_BRANCHES = ['main', 'master'];
|
|
46
|
+
// Epic branch pattern: epic/<rig>-<hash>
|
|
47
|
+
const EPIC_BRANCH_PATTERN = /^epic\/([a-z]+-[a-z0-9]+)$/;
|
|
48
|
+
/**
|
|
49
|
+
* Parse land command arguments.
|
|
50
|
+
*/
|
|
51
|
+
export function parseLandArgs(rawArgs) {
|
|
52
|
+
const opts = {};
|
|
53
|
+
for (let i = 0; i < rawArgs.length; i++) {
|
|
54
|
+
const arg = rawArgs[i];
|
|
55
|
+
if (arg === '--skip-tests') {
|
|
56
|
+
opts.skipTests = true;
|
|
57
|
+
}
|
|
58
|
+
else if (arg === '--skip-backup') {
|
|
59
|
+
opts.skipBackup = true;
|
|
60
|
+
}
|
|
61
|
+
else if (arg === '--force' || arg === '-f') {
|
|
62
|
+
opts.force = true;
|
|
63
|
+
}
|
|
64
|
+
else if (arg === '--dry-run') {
|
|
65
|
+
opts.dryRun = true;
|
|
66
|
+
}
|
|
67
|
+
else if (arg === '--message' || arg === '-m') {
|
|
68
|
+
opts.message = rawArgs[++i];
|
|
69
|
+
}
|
|
70
|
+
else if (arg.startsWith('--message=')) {
|
|
71
|
+
opts.message = arg.slice('--message='.length);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return opts;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Get the current git branch name.
|
|
78
|
+
* Returns null if not in a git repo or detached HEAD.
|
|
79
|
+
*/
|
|
80
|
+
export function getCurrentBranch() {
|
|
81
|
+
try {
|
|
82
|
+
const output = execFileSync('git', ['branch', '--show-current'], {
|
|
83
|
+
encoding: 'utf-8',
|
|
84
|
+
timeout: 10000,
|
|
85
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
86
|
+
});
|
|
87
|
+
const branch = output.trim();
|
|
88
|
+
return branch.length > 0 ? branch : null;
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Extract the epic ID from a branch name.
|
|
96
|
+
* e.g. "epic/beth-z9n" → "beth-z9n"
|
|
97
|
+
* Returns null if branch doesn't follow epic convention.
|
|
98
|
+
*/
|
|
99
|
+
export function extractEpicId(branch) {
|
|
100
|
+
const match = EPIC_BRANCH_PATTERN.exec(branch);
|
|
101
|
+
return match ? match[1] : null;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Check if a branch is a protected branch (main/master).
|
|
105
|
+
*/
|
|
106
|
+
export function isProtectedBranch(branch) {
|
|
107
|
+
return PROTECTED_BRANCHES.includes(branch);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Check if there are uncommitted changes in the working tree.
|
|
111
|
+
*/
|
|
112
|
+
export function hasUncommittedChanges() {
|
|
113
|
+
try {
|
|
114
|
+
const output = execFileSync('git', ['status', '--porcelain'], {
|
|
115
|
+
encoding: 'utf-8',
|
|
116
|
+
timeout: 10000,
|
|
117
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
118
|
+
});
|
|
119
|
+
return output.trim().length > 0;
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Check if there are staged changes ready to commit.
|
|
127
|
+
*/
|
|
128
|
+
export function hasStagedChanges() {
|
|
129
|
+
try {
|
|
130
|
+
execFileSync('git', ['diff', '--cached', '--quiet'], {
|
|
131
|
+
encoding: 'utf-8',
|
|
132
|
+
timeout: 10000,
|
|
133
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
134
|
+
});
|
|
135
|
+
return false; // exit 0 means no diff
|
|
136
|
+
}
|
|
137
|
+
catch (err) {
|
|
138
|
+
// exit 1 means there are diffs; any other error is unexpected
|
|
139
|
+
if (err && typeof err === 'object' && 'status' in err && err.status === 1) {
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Check if there are unpushed commits on the current branch.
|
|
147
|
+
*/
|
|
148
|
+
export function hasUnpushedCommits(branch) {
|
|
149
|
+
try {
|
|
150
|
+
// First check if origin/<branch> exists
|
|
151
|
+
execFileSync('git', ['show-ref', '--verify', '--quiet', `refs/remotes/origin/${branch}`], {
|
|
152
|
+
encoding: 'utf-8',
|
|
153
|
+
timeout: 10000,
|
|
154
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
155
|
+
});
|
|
156
|
+
// If it exists, check for unpushed commits
|
|
157
|
+
const output = execFileSync('git', ['log', `origin/${branch}..HEAD`, '--oneline'], {
|
|
158
|
+
encoding: 'utf-8',
|
|
159
|
+
timeout: 10000,
|
|
160
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
161
|
+
});
|
|
162
|
+
return output.trim().length > 0;
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
// If origin/<branch> doesn't exist, all local commits are unpushed
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Run npm test and return pass/fail with output.
|
|
171
|
+
*/
|
|
172
|
+
export function runTests() {
|
|
173
|
+
try {
|
|
174
|
+
const output = execFileSync('npm', ['test'], {
|
|
175
|
+
encoding: 'utf-8',
|
|
176
|
+
timeout: 300000, // 5 minutes max
|
|
177
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
178
|
+
});
|
|
179
|
+
return { passed: true, output };
|
|
180
|
+
}
|
|
181
|
+
catch (error) {
|
|
182
|
+
const output = (error && typeof error === 'object' && 'stdout' in error ? String(error.stdout) : '') +
|
|
183
|
+
(error && typeof error === 'object' && 'stderr' in error ? String(error.stderr) : '');
|
|
184
|
+
return { passed: false, output };
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Run beads backup (bd backup).
|
|
189
|
+
*/
|
|
190
|
+
export function runBeadsBackup() {
|
|
191
|
+
try {
|
|
192
|
+
const output = execFileSync('bd', ['backup'], {
|
|
193
|
+
encoding: 'utf-8',
|
|
194
|
+
timeout: 30000,
|
|
195
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
196
|
+
});
|
|
197
|
+
return { success: true, output };
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
const output = (error && typeof error === 'object' && 'stderr' in error ? String(error.stderr) : '');
|
|
201
|
+
return { success: false, output };
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Stage all changes (git add -A).
|
|
206
|
+
*/
|
|
207
|
+
export function gitAddAll() {
|
|
208
|
+
try {
|
|
209
|
+
execFileSync('git', ['add', '-A'], {
|
|
210
|
+
encoding: 'utf-8',
|
|
211
|
+
timeout: 30000,
|
|
212
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
213
|
+
});
|
|
214
|
+
return true;
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
return false;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Commit staged changes.
|
|
222
|
+
*/
|
|
223
|
+
export function gitCommit(message) {
|
|
224
|
+
try {
|
|
225
|
+
execFileSync('git', ['commit', '-m', message], {
|
|
226
|
+
encoding: 'utf-8',
|
|
227
|
+
timeout: 30000,
|
|
228
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
229
|
+
});
|
|
230
|
+
return true;
|
|
231
|
+
}
|
|
232
|
+
catch {
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Check if a remote tracking branch exists for the given branch.
|
|
238
|
+
*/
|
|
239
|
+
export function remoteBranchExists(branch) {
|
|
240
|
+
try {
|
|
241
|
+
execFileSync('git', ['show-ref', '--verify', '--quiet', `refs/remotes/origin/${branch}`], {
|
|
242
|
+
encoding: 'utf-8',
|
|
243
|
+
timeout: 10000,
|
|
244
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
245
|
+
});
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
return false;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Abort an in-progress rebase.
|
|
254
|
+
*/
|
|
255
|
+
export function gitRebaseAbort() {
|
|
256
|
+
try {
|
|
257
|
+
execFileSync('git', ['rebase', '--abort'], {
|
|
258
|
+
encoding: 'utf-8',
|
|
259
|
+
timeout: 10000,
|
|
260
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
// Best-effort — if there's no rebase in progress, this will fail harmlessly
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Pull with rebase from origin.
|
|
269
|
+
*/
|
|
270
|
+
export function gitPullRebase(branch) {
|
|
271
|
+
try {
|
|
272
|
+
const output = execFileSync('git', ['pull', 'origin', branch, '--rebase'], {
|
|
273
|
+
encoding: 'utf-8',
|
|
274
|
+
timeout: 60000,
|
|
275
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
276
|
+
});
|
|
277
|
+
return { success: true, output };
|
|
278
|
+
}
|
|
279
|
+
catch (error) {
|
|
280
|
+
const output = (error && typeof error === 'object' && 'stderr' in error ? String(error.stderr) : '');
|
|
281
|
+
return { success: false, output };
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Push to origin.
|
|
286
|
+
*/
|
|
287
|
+
export function gitPush(branch) {
|
|
288
|
+
try {
|
|
289
|
+
const output = execFileSync('git', ['push', 'origin', branch], {
|
|
290
|
+
encoding: 'utf-8',
|
|
291
|
+
timeout: 60000,
|
|
292
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
293
|
+
});
|
|
294
|
+
return { success: true, output };
|
|
295
|
+
}
|
|
296
|
+
catch (error) {
|
|
297
|
+
const output = (error && typeof error === 'object' && 'stderr' in error ? String(error.stderr) : '');
|
|
298
|
+
return { success: false, output };
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Verify the current branch is up to date with origin.
|
|
303
|
+
*/
|
|
304
|
+
export function isUpToDateWithOrigin(branch) {
|
|
305
|
+
try {
|
|
306
|
+
execFileSync('git', ['fetch', 'origin', branch], {
|
|
307
|
+
encoding: 'utf-8',
|
|
308
|
+
timeout: 30000,
|
|
309
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
310
|
+
});
|
|
311
|
+
// Compare local HEAD with the fetched remote ref directly.
|
|
312
|
+
// Using git status --branch is unreliable when no upstream tracking is set
|
|
313
|
+
// (it omits ahead/behind, falsely appearing "up to date").
|
|
314
|
+
const localSha = execFileSync('git', ['rev-parse', 'HEAD'], {
|
|
315
|
+
encoding: 'utf-8',
|
|
316
|
+
timeout: 10000,
|
|
317
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
318
|
+
}).trim();
|
|
319
|
+
const remoteSha = execFileSync('git', ['rev-parse', `origin/${branch}`], {
|
|
320
|
+
encoding: 'utf-8',
|
|
321
|
+
timeout: 10000,
|
|
322
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
323
|
+
}).trim();
|
|
324
|
+
return localSha === remoteSha;
|
|
325
|
+
}
|
|
326
|
+
catch {
|
|
327
|
+
return false;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
// ─── Step Execution ──────────────────────────────────────────────────────────
|
|
331
|
+
/**
|
|
332
|
+
* Execute a single step with logging and dry-run support.
|
|
333
|
+
*/
|
|
334
|
+
function executeStep(stepName, dryRun, fn) {
|
|
335
|
+
if (dryRun) {
|
|
336
|
+
const result = {
|
|
337
|
+
step: stepName,
|
|
338
|
+
status: 'skip',
|
|
339
|
+
message: `[DRY RUN] Would execute: ${stepName}`,
|
|
340
|
+
};
|
|
341
|
+
logStep(result);
|
|
342
|
+
return result;
|
|
343
|
+
}
|
|
344
|
+
const result = fn();
|
|
345
|
+
logStep(result);
|
|
346
|
+
return result;
|
|
347
|
+
}
|
|
348
|
+
function logStep(result) {
|
|
349
|
+
const icon = result.status === 'pass'
|
|
350
|
+
? `${COLORS.green}✓`
|
|
351
|
+
: result.status === 'fail'
|
|
352
|
+
? `${COLORS.red}✗`
|
|
353
|
+
: result.status === 'warn'
|
|
354
|
+
? `${COLORS.yellow}⚠`
|
|
355
|
+
: `${COLORS.dim}○`;
|
|
356
|
+
console.log(`${icon} ${COLORS.bright}${result.step}${COLORS.reset}: ${result.message}`);
|
|
357
|
+
if (result.details) {
|
|
358
|
+
console.log(` ${COLORS.dim}${result.details}${COLORS.reset}`);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
// ─── Main Command ────────────────────────────────────────────────────────────
|
|
362
|
+
/**
|
|
363
|
+
* Execute the full landing sequence.
|
|
364
|
+
* Returns structured result for programmatic use.
|
|
365
|
+
*/
|
|
366
|
+
export function executeLanding(options = {}) {
|
|
367
|
+
const steps = [];
|
|
368
|
+
const { skipTests, skipBackup, message, force, dryRun } = options;
|
|
369
|
+
console.log(`\n${COLORS.bright}${COLORS.cyan}━━━ Landing the Plane ━━━${COLORS.reset}\n`);
|
|
370
|
+
if (dryRun) {
|
|
371
|
+
console.log(`${COLORS.yellow}[DRY RUN] No changes will be made.${COLORS.reset}\n`);
|
|
372
|
+
}
|
|
373
|
+
// Step 1: Verify branch
|
|
374
|
+
const branch = getCurrentBranch();
|
|
375
|
+
if (!branch) {
|
|
376
|
+
steps.push({
|
|
377
|
+
step: 'Branch check',
|
|
378
|
+
status: 'fail',
|
|
379
|
+
message: 'Not in a git repository or detached HEAD',
|
|
380
|
+
});
|
|
381
|
+
logStep(steps[0]);
|
|
382
|
+
return { success: false, steps };
|
|
383
|
+
}
|
|
384
|
+
if (isProtectedBranch(branch)) {
|
|
385
|
+
steps.push({
|
|
386
|
+
step: 'Branch check',
|
|
387
|
+
status: 'fail',
|
|
388
|
+
message: `Cannot land from protected branch '${branch}'. Use an epic branch.`,
|
|
389
|
+
});
|
|
390
|
+
logStep(steps[0]);
|
|
391
|
+
return { success: false, steps };
|
|
392
|
+
}
|
|
393
|
+
const epicId = extractEpicId(branch);
|
|
394
|
+
if (!epicId) {
|
|
395
|
+
steps.push({
|
|
396
|
+
step: 'Branch check',
|
|
397
|
+
status: 'warn',
|
|
398
|
+
message: `Branch '${branch}' doesn't follow epic/<id> convention`,
|
|
399
|
+
details: 'Continuing anyway, but commits won\'t have epic prefix',
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
else {
|
|
403
|
+
steps.push({
|
|
404
|
+
step: 'Branch check',
|
|
405
|
+
status: 'pass',
|
|
406
|
+
message: `On epic branch: ${branch} (epic: ${epicId})`,
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
logStep(steps[steps.length - 1]);
|
|
410
|
+
// Step 2: Run tests
|
|
411
|
+
if (skipTests) {
|
|
412
|
+
const step = {
|
|
413
|
+
step: 'Tests',
|
|
414
|
+
status: 'skip',
|
|
415
|
+
message: 'Skipped (--skip-tests)',
|
|
416
|
+
};
|
|
417
|
+
steps.push(step);
|
|
418
|
+
logStep(step);
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
const testStep = executeStep('Tests', !!dryRun, () => {
|
|
422
|
+
console.log(` ${COLORS.dim}Running npm test...${COLORS.reset}`);
|
|
423
|
+
const { passed, output } = runTests();
|
|
424
|
+
if (passed) {
|
|
425
|
+
// Extract test count from output if possible
|
|
426
|
+
const countMatch = output.match(/(\d+)\s+(?:tests?\s+)?pass/i);
|
|
427
|
+
const count = countMatch ? ` (${countMatch[1]} passed)` : '';
|
|
428
|
+
return {
|
|
429
|
+
step: 'Tests',
|
|
430
|
+
status: 'pass',
|
|
431
|
+
message: `All tests passed${count}`,
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
return {
|
|
435
|
+
step: 'Tests',
|
|
436
|
+
status: 'fail',
|
|
437
|
+
message: 'Tests failed',
|
|
438
|
+
details: output.split('\n').slice(-5).join('\n'),
|
|
439
|
+
};
|
|
440
|
+
});
|
|
441
|
+
steps.push(testStep);
|
|
442
|
+
if (testStep.status === 'fail' && !force) {
|
|
443
|
+
console.log(`\n${COLORS.red}✗ Landing aborted — tests must pass before pushing.${COLORS.reset}`);
|
|
444
|
+
console.log(`${COLORS.yellow} Fix the failures, or use --force to push anyway (DANGEROUS).${COLORS.reset}\n`);
|
|
445
|
+
return { success: false, steps, branch, epicId: epicId ?? undefined };
|
|
446
|
+
}
|
|
447
|
+
if (testStep.status === 'fail' && force) {
|
|
448
|
+
console.log(`\n${COLORS.yellow}⚠ Tests failed but --force was specified. Continuing...${COLORS.reset}\n`);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
// Step 3: Beads backup
|
|
452
|
+
if (skipBackup) {
|
|
453
|
+
const step = {
|
|
454
|
+
step: 'Beads backup',
|
|
455
|
+
status: 'skip',
|
|
456
|
+
message: 'Skipped (--skip-backup)',
|
|
457
|
+
};
|
|
458
|
+
steps.push(step);
|
|
459
|
+
logStep(step);
|
|
460
|
+
}
|
|
461
|
+
else {
|
|
462
|
+
const backupStep = executeStep('Beads backup', !!dryRun, () => {
|
|
463
|
+
const { success } = runBeadsBackup();
|
|
464
|
+
if (success) {
|
|
465
|
+
return {
|
|
466
|
+
step: 'Beads backup',
|
|
467
|
+
status: 'pass',
|
|
468
|
+
message: 'Beads data backed up',
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
return {
|
|
472
|
+
step: 'Beads backup',
|
|
473
|
+
status: 'warn',
|
|
474
|
+
message: 'Beads backup failed (bd not available or no data)',
|
|
475
|
+
details: 'Non-blocking — continuing with landing',
|
|
476
|
+
};
|
|
477
|
+
});
|
|
478
|
+
steps.push(backupStep);
|
|
479
|
+
}
|
|
480
|
+
// Step 4: Check for changes to commit
|
|
481
|
+
const hasChanges = hasUncommittedChanges();
|
|
482
|
+
const unpushed = hasUnpushedCommits(branch);
|
|
483
|
+
if (!hasChanges && !unpushed) {
|
|
484
|
+
const step = {
|
|
485
|
+
step: 'Git status',
|
|
486
|
+
status: 'pass',
|
|
487
|
+
message: 'Working tree clean, nothing to push',
|
|
488
|
+
};
|
|
489
|
+
steps.push(step);
|
|
490
|
+
logStep(step);
|
|
491
|
+
console.log(`\n${COLORS.green}✓ Already up to date. Nothing to land.${COLORS.reset}\n`);
|
|
492
|
+
return { success: true, steps, branch, epicId: epicId ?? undefined };
|
|
493
|
+
}
|
|
494
|
+
// Step 5: Stage changes
|
|
495
|
+
if (hasChanges) {
|
|
496
|
+
const stageStep = executeStep('Stage changes', !!dryRun, () => {
|
|
497
|
+
if (gitAddAll()) {
|
|
498
|
+
return {
|
|
499
|
+
step: 'Stage changes',
|
|
500
|
+
status: 'pass',
|
|
501
|
+
message: 'All changes staged (git add -A)',
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
return {
|
|
505
|
+
step: 'Stage changes',
|
|
506
|
+
status: 'fail',
|
|
507
|
+
message: 'Failed to stage changes',
|
|
508
|
+
};
|
|
509
|
+
});
|
|
510
|
+
steps.push(stageStep);
|
|
511
|
+
if (stageStep.status === 'fail') {
|
|
512
|
+
return { success: false, steps, branch, epicId: epicId ?? undefined };
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
// Step 6: Commit
|
|
516
|
+
if (hasChanges) {
|
|
517
|
+
const commitMsg = message || `${epicId ? epicId + ': ' : ''}session work`;
|
|
518
|
+
const commitStep = executeStep('Commit', !!dryRun, () => {
|
|
519
|
+
if (gitCommit(commitMsg)) {
|
|
520
|
+
return {
|
|
521
|
+
step: 'Commit',
|
|
522
|
+
status: 'pass',
|
|
523
|
+
message: `Committed: "${commitMsg}"`,
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
// Could fail if nothing to commit after staging
|
|
527
|
+
return {
|
|
528
|
+
step: 'Commit',
|
|
529
|
+
status: 'warn',
|
|
530
|
+
message: 'Nothing to commit (changes may already be committed)',
|
|
531
|
+
};
|
|
532
|
+
});
|
|
533
|
+
steps.push(commitStep);
|
|
534
|
+
}
|
|
535
|
+
// Step 7: Pull with rebase
|
|
536
|
+
const pullStep = executeStep('Pull rebase', !!dryRun, () => {
|
|
537
|
+
if (!remoteBranchExists(branch)) {
|
|
538
|
+
return {
|
|
539
|
+
step: 'Pull rebase',
|
|
540
|
+
status: 'warn',
|
|
541
|
+
message: `No remote branch origin/${branch} yet (new branch, will be created on push)`,
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
const { success, output } = gitPullRebase(branch);
|
|
545
|
+
if (success) {
|
|
546
|
+
return {
|
|
547
|
+
step: 'Pull rebase',
|
|
548
|
+
status: 'pass',
|
|
549
|
+
message: `Rebased on origin/${branch}`,
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
// Remote exists but rebase failed — likely a conflict. Abort the rebase to restore clean state.
|
|
553
|
+
gitRebaseAbort();
|
|
554
|
+
return {
|
|
555
|
+
step: 'Pull rebase',
|
|
556
|
+
status: 'fail',
|
|
557
|
+
message: `Rebase conflict with origin/${branch} — landing aborted. Resolve conflicts manually.`,
|
|
558
|
+
details: output.split('\n').slice(0, 5).join('\n'),
|
|
559
|
+
};
|
|
560
|
+
});
|
|
561
|
+
steps.push(pullStep);
|
|
562
|
+
if (pullStep.status === 'fail') {
|
|
563
|
+
console.log(`\n${COLORS.red}✗ Rebase conflict detected. Resolve conflicts and retry: git pull origin ${branch} --rebase${COLORS.reset}\n`);
|
|
564
|
+
return { success: false, steps, branch, epicId: epicId ?? undefined };
|
|
565
|
+
}
|
|
566
|
+
// Step 8: Push
|
|
567
|
+
const pushStep = executeStep('Push', !!dryRun, () => {
|
|
568
|
+
const { success, output } = gitPush(branch);
|
|
569
|
+
if (success) {
|
|
570
|
+
return {
|
|
571
|
+
step: 'Push',
|
|
572
|
+
status: 'pass',
|
|
573
|
+
message: `Pushed to origin/${branch}`,
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
return {
|
|
577
|
+
step: 'Push',
|
|
578
|
+
status: 'fail',
|
|
579
|
+
message: `Push to origin/${branch} failed`,
|
|
580
|
+
details: output,
|
|
581
|
+
};
|
|
582
|
+
});
|
|
583
|
+
steps.push(pushStep);
|
|
584
|
+
if (pushStep.status === 'fail') {
|
|
585
|
+
console.log(`\n${COLORS.red}✗ Push failed. Resolve and retry: git push origin ${branch}${COLORS.reset}\n`);
|
|
586
|
+
return { success: false, steps, branch, epicId: epicId ?? undefined };
|
|
587
|
+
}
|
|
588
|
+
// Step 9: Verify
|
|
589
|
+
if (!dryRun) {
|
|
590
|
+
const verifyStep = (() => {
|
|
591
|
+
if (isUpToDateWithOrigin(branch)) {
|
|
592
|
+
return {
|
|
593
|
+
step: 'Verify',
|
|
594
|
+
status: 'pass',
|
|
595
|
+
message: `Branch is up to date with origin/${branch}`,
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
return {
|
|
599
|
+
step: 'Verify',
|
|
600
|
+
status: 'warn',
|
|
601
|
+
message: 'Branch may not be fully synced — check manually',
|
|
602
|
+
};
|
|
603
|
+
})();
|
|
604
|
+
steps.push(verifyStep);
|
|
605
|
+
logStep(verifyStep);
|
|
606
|
+
}
|
|
607
|
+
// Summary
|
|
608
|
+
const failed = steps.filter((s) => s.status === 'fail').length;
|
|
609
|
+
const warnings = steps.filter((s) => s.status === 'warn').length;
|
|
610
|
+
console.log(`\n${COLORS.bright}${COLORS.cyan}━━━ Landing Summary ━━━${COLORS.reset}`);
|
|
611
|
+
if (failed === 0) {
|
|
612
|
+
console.log(`${COLORS.green}✓ Landed successfully on ${branch}${COLORS.reset}`);
|
|
613
|
+
console.log(`\n${COLORS.bright}Remaining manual steps (see AGENTS.md):${COLORS.reset}`);
|
|
614
|
+
console.log(`${COLORS.dim} 1. Close completed beads issues npx beth-copilot close <id>${COLORS.reset}`);
|
|
615
|
+
console.log(`${COLORS.dim} 2. Create follow-up issues bd create "..." ${COLORS.reset}`);
|
|
616
|
+
console.log(`${COLORS.dim} 3. Update Backlog.md (completed-work archive)${COLORS.reset}`);
|
|
617
|
+
console.log(`${COLORS.dim} 4. Generate test gate report npm run test:gate${COLORS.reset}`);
|
|
618
|
+
if (epicId) {
|
|
619
|
+
console.log(`${COLORS.dim} 5. Create a PR to main gh pr create --base main --head ${branch}${COLORS.reset}`);
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
else {
|
|
623
|
+
console.log(`${COLORS.red}✗ Landing incomplete — ${failed} step(s) failed${COLORS.reset}`);
|
|
624
|
+
}
|
|
625
|
+
if (warnings > 0) {
|
|
626
|
+
console.log(`${COLORS.yellow} ${warnings} warning(s)${COLORS.reset}`);
|
|
627
|
+
}
|
|
628
|
+
console.log('');
|
|
629
|
+
return {
|
|
630
|
+
success: failed === 0,
|
|
631
|
+
steps,
|
|
632
|
+
branch,
|
|
633
|
+
epicId: epicId ?? undefined,
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
/**
|
|
637
|
+
* Main land command entry point.
|
|
638
|
+
* Called from CLI routing with raw args after 'land'.
|
|
639
|
+
*/
|
|
640
|
+
export async function land(rawArgs) {
|
|
641
|
+
const options = parseLandArgs(rawArgs);
|
|
642
|
+
const result = executeLanding(options);
|
|
643
|
+
if (!result.success) {
|
|
644
|
+
process.exit(1);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
//# sourceMappingURL=land.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"land.js","sourceRoot":"","sources":["../../../src/cli/commands/land.ts"],"names":[],"mappings":"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"}
|