boxdown 1.0.0 → 1.2.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 +135 -12
- package/assets/devcontainer/README.md +49 -17
- package/assets/devcontainer/devcontainer.json +24 -7
- package/assets/devcontainer/hooks/initialize.sh +32 -0
- package/assets/devcontainer/hooks/post-create.sh +59 -12
- package/assets/devcontainer/hooks/post-start.sh +21 -4
- package/assets/devcontainer/ssh-config-install.sh +12 -3
- package/assets/devcontainer/start.sh +721 -44
- package/assets/devcontainer/utils/coding-agent-cli-update.sh +267 -3
- package/assets/devcontainer/utils/deps-install.sh +68 -0
- package/assets/devcontainer/utils/git-config-bootstrap.sh +128 -0
- package/assets/devcontainer/utils/git-signing-bootstrap.sh +56 -0
- package/assets/devcontainer/utils/python-bootstrap.sh +69 -0
- package/assets/devcontainer/utils/ssh-bootstrap.sh +9 -0
- package/dist/bin/cli.cjs +1 -1
- package/dist/bin/cli.mjs +1 -1
- package/dist/main-Df4E8ARj.cjs +5498 -0
- package/dist/main-XMBsKjIK.mjs +5458 -0
- package/dist/main-XMBsKjIK.mjs.map +1 -0
- package/dist/main.cjs +5 -2
- package/dist/main.d.cts +495 -4
- package/dist/main.d.cts.map +1 -1
- package/dist/main.d.mts +495 -4
- package/dist/main.d.mts.map +1 -1
- package/dist/main.mjs +2 -2
- package/docs/README.md +1 -0
- package/docs/architecture.md +32 -0
- package/docs/development.md +13 -6
- package/docs/features/README.md +2 -0
- package/docs/features/commit-signing.md +23 -0
- package/docs/features/generated-config-and-state.md +57 -4
- package/docs/features/github-auth-refresh.md +12 -0
- package/docs/features/lifecycle.md +97 -11
- package/docs/features/setup.md +66 -0
- package/docs/features/ssh-config-and-proxy.md +228 -7
- package/docs/features/start-and-shell.md +40 -5
- package/docs/superpowers/plans/2026-07-11-default-commit-signing.md +110 -0
- package/docs/superpowers/plans/2026-07-11-progress-ci-regression.md +125 -0
- package/docs/superpowers/specs/2026-07-11-default-commit-signing-design.md +396 -0
- package/docs/superpowers/specs/2026-07-11-progress-ci-regression-design.md +43 -0
- package/docs/testing.md +35 -2
- package/docs/todo.md +2 -2
- package/package.json +1 -1
- package/src/claude-app-config.ts +304 -0
- package/src/cli-style.ts +43 -0
- package/src/codex-app-config.ts +656 -0
- package/src/config.ts +68 -10
- package/src/constants.ts +5 -0
- package/src/devcontainer.ts +500 -64
- package/src/doctor.ts +195 -30
- package/src/git-signing.ts +87 -0
- package/src/interactive-prompts.ts +692 -0
- package/src/list.ts +16 -2
- package/src/logging.ts +154 -0
- package/src/main.ts +1213 -63
- package/src/metadata.ts +52 -3
- package/src/package-info.ts +18 -0
- package/src/paths.ts +50 -10
- package/src/process.ts +80 -2
- package/src/progress.ts +593 -0
- package/src/purge.ts +208 -0
- package/src/shell.ts +19 -0
- package/src/ssh-config.ts +134 -16
- package/src/ssh-install-targets.ts +111 -0
- package/src/ssh-key.ts +53 -13
- package/src/status.ts +5 -0
- package/dist/main-BuEptwlL.cjs +0 -1707
- package/dist/main-ZFTrSVgt.mjs +0 -1685
- package/dist/main-ZFTrSVgt.mjs.map +0 -1
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
boxdown start
|
|
7
7
|
boxdown codex
|
|
8
8
|
boxdown claude
|
|
9
|
-
boxdown cc
|
|
10
9
|
boxdown opencode
|
|
11
10
|
boxdown antigravity
|
|
12
11
|
```
|
|
@@ -16,18 +15,30 @@ boxdown antigravity
|
|
|
16
15
|
```sh
|
|
17
16
|
--workspace <path>
|
|
18
17
|
--recreate
|
|
18
|
+
--verbose
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
+
Use `boxdown setup` when you want to prepare the devcontainer and SSH/app
|
|
22
|
+
integration without opening an interactive shell.
|
|
23
|
+
|
|
21
24
|
`boxdown shell` remains supported as an alias for `boxdown start`, but `start`
|
|
22
25
|
is the canonical command used in help and documentation.
|
|
26
|
+
`boxdown cc` remains supported as an alias for `boxdown claude`, but `claude`
|
|
27
|
+
is the canonical command used in help and documentation.
|
|
23
28
|
|
|
24
29
|
The coding-agent aliases start or reuse the same workspace devcontainer and
|
|
25
30
|
launch the selected CLI directly:
|
|
26
31
|
|
|
27
32
|
- `boxdown codex` launches `codex`.
|
|
28
|
-
- `boxdown claude`
|
|
29
|
-
- `boxdown opencode` launches
|
|
30
|
-
|
|
33
|
+
- `boxdown claude` launches `claude`.
|
|
34
|
+
- `boxdown opencode` installs/updates OpenCode when needed, then launches
|
|
35
|
+
`opencode`.
|
|
36
|
+
- `boxdown antigravity` installs/updates Antigravity when needed, then launches
|
|
37
|
+
`agy`.
|
|
38
|
+
|
|
39
|
+
Container bring-up eagerly installs only Codex and Claude Code. OpenCode and
|
|
40
|
+
Antigravity are lazy installs so projects that do not use them avoid the extra
|
|
41
|
+
disk usage.
|
|
31
42
|
|
|
32
43
|
Pass agent-specific arguments after `--` so Boxdown options stay unambiguous:
|
|
33
44
|
|
|
@@ -42,7 +53,7 @@ boxdown claude -- --continue
|
|
|
42
53
|
3. Generate a Boxdown-owned devcontainer config.
|
|
43
54
|
4. Install or reuse the pinned Dev Containers CLI.
|
|
44
55
|
5. Run `devcontainer up --workspace-folder <repo> --override-config <config>`.
|
|
45
|
-
6. Run container lifecycle hooks, including a best-effort
|
|
56
|
+
6. Run container lifecycle hooks, including a best-effort Codex/Claude CLI refresh.
|
|
46
57
|
7. Print a dynamic port hint when the configured published port is mapped.
|
|
47
58
|
8. Run `devcontainer exec ... bash` to open an interactive shell.
|
|
48
59
|
|
|
@@ -50,6 +61,11 @@ Coding-agent aliases use the same startup flow but skip the port hint, run a
|
|
|
50
61
|
best-effort refresh for the selected agent, and exec the agent binary instead of
|
|
51
62
|
opening `bash`.
|
|
52
63
|
|
|
64
|
+
Startup progress is concise by default. Raw Docker, Dev Containers CLI,
|
|
65
|
+
lifecycle hook, and coding-agent install/update logs are captured; on failure,
|
|
66
|
+
Boxdown prints the failed step and a short output tail. Pass `--verbose` to
|
|
67
|
+
stream the full startup output before the interactive shell or agent takes over.
|
|
68
|
+
|
|
53
69
|
## Terminal Width
|
|
54
70
|
|
|
55
71
|
Some terminal UIs behave poorly when a host terminal reports an extremely wide
|
|
@@ -57,6 +73,12 @@ PTY, especially from embedded terminals. Before opening the shell, Boxdown
|
|
|
57
73
|
clamps interactive terminal width to 120 columns when the reported width is
|
|
58
74
|
larger.
|
|
59
75
|
|
|
76
|
+
Before starting the interactive shell or a coding-agent command, Boxdown also
|
|
77
|
+
checks whether the container recognizes the forwarded `TERM` value. If the
|
|
78
|
+
container does not have terminfo for a host-specific terminal such as Ghostty,
|
|
79
|
+
Boxdown falls back to `xterm-256color` while preserving truecolor support with
|
|
80
|
+
`COLORTERM=truecolor`.
|
|
81
|
+
|
|
60
82
|
Override the default width when you want a wider layout:
|
|
61
83
|
|
|
62
84
|
```sh
|
|
@@ -81,3 +103,16 @@ Docker `runArgs`.
|
|
|
81
103
|
The v1 asset config publishes container port `3000` with a dynamic host port.
|
|
82
104
|
After `up`, Boxdown asks Docker for the mapped host binding and prints the
|
|
83
105
|
result as an HTTP URL when available.
|
|
106
|
+
|
|
107
|
+
For dev servers that choose another port after the container is already running,
|
|
108
|
+
use the SSH tunnel command instead. Interactive terminals can omit `--port` to
|
|
109
|
+
be prompted for the mapping:
|
|
110
|
+
|
|
111
|
+
```sh
|
|
112
|
+
boxdown tunnel
|
|
113
|
+
boxdown tunnel --port 3030
|
|
114
|
+
boxdown tunnel --workspace /path/to/project --port 3030
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
This is the preferred path for host browsers and the Codex in-app browser when a
|
|
118
|
+
server is listening on container-local `localhost`.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Default Commit Signing Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
4
|
+
|
|
5
|
+
**Goal:** Make new Boxdown environments sign commits through the host SSH agent by default, while retaining an unsigned, warning-only fallback.
|
|
6
|
+
|
|
7
|
+
**Architecture:** A host-side resolver selects one unambiguous public SSH key and snapshots only that key into workspace state. The generated devcontainer config mounts the host agent and the public-key snapshot. A container bootstrap validates a disposable SSH-signed commit and configures global Git for SSH signing or disables it without touching repository-local Git config.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** Node.js 24, TypeScript, Bash, Git, OpenSSH, Docker/Dev Containers CLI, Node test runner.
|
|
10
|
+
|
|
11
|
+
## Global Constraints
|
|
12
|
+
|
|
13
|
+
- Never copy private signing-key material into Boxdown state or the container.
|
|
14
|
+
- Multiple ambiguous agent identities disable signing and warn; never select one arbitrarily.
|
|
15
|
+
- Signing diagnostics are `warn`, never a setup-preflight failure.
|
|
16
|
+
- Never write `commit.gpgsign` in the repository-local `.git/config`.
|
|
17
|
+
- Docker integration is optional and must not pull images or push commits.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
### Task 1: Resolve and persist a signing plan
|
|
22
|
+
|
|
23
|
+
**Files:**
|
|
24
|
+
|
|
25
|
+
- Create: `src/git-signing.ts`
|
|
26
|
+
- Modify: `src/constants.ts`, `src/paths.ts`, `src/config.ts`
|
|
27
|
+
- Test: `__tests__/app.test.ts`
|
|
28
|
+
|
|
29
|
+
**Interfaces:**
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
export type GitSigningReason = 'agent-unavailable' | 'no-identities' | 'ambiguous-identities' | 'configured-key-not-loaded' | 'agent-mount-unavailable'
|
|
33
|
+
export interface GitSigningPlan { enabled: boolean, reason?: GitSigningReason, publicKey?: string, agentSocketSource?: string }
|
|
34
|
+
export function parseSshPublicKey(value: string): string | undefined
|
|
35
|
+
export function selectGitSigningKey(identities: string[], configuredKey?: string, githubKeys?: string[]): { key?: string, reason?: GitSigningReason }
|
|
36
|
+
export function writeGitSigningPublicKey(context: WorkspaceContext, key: string): void
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
- [ ] Write focused failing tests for parsing keys without comments, configured-key selection, a unique GitHub-key match, single-key fallback, ambiguous fallback, and config mount generation.
|
|
40
|
+
- [ ] Run `node --import tsx --test --test-name-pattern='git signing|devcontainer config generation' __tests__/app.test.ts` and confirm the new assertions fail because the module and mounts do not exist.
|
|
41
|
+
- [ ] Add state paths and container constants, implement the pure resolver and public-key snapshot, and let `buildGeneratedDevcontainerConfig(context, signingPlan)` add read-only key-state and agent mounts only for enabled plans.
|
|
42
|
+
- [ ] Rerun the focused tests and confirm they pass.
|
|
43
|
+
|
|
44
|
+
### Task 2: Configure and validate container-side Git signing
|
|
45
|
+
|
|
46
|
+
**Files:**
|
|
47
|
+
|
|
48
|
+
- Create: `assets/devcontainer/utils/git-signing-bootstrap.sh`
|
|
49
|
+
- Modify: `assets/devcontainer/utils/git-config-bootstrap.sh`, `assets/devcontainer/hooks/post-create.sh`, `assets/devcontainer/hooks/post-start.sh`
|
|
50
|
+
- Test: `__tests__/app.test.ts`
|
|
51
|
+
|
|
52
|
+
**Interfaces:**
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
bash /opt/boxdown/devcontainer/utils/git-signing-bootstrap.sh
|
|
56
|
+
# Reads BOXDOWN_GIT_SIGNING_ENABLED and BOXDOWN_GIT_SIGNING_KEY_PATH.
|
|
57
|
+
# Exits 0 in both signed and unsigned fallback modes.
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
- [ ] Write failing shell-hook tests for successful SSH configuration, absent-agent fallback, removal of incompatible `gpg.program`, and absence of repository-local `commit.gpgsign` writes.
|
|
61
|
+
- [ ] Run the matching `devcontainer git config hooks` tests and confirm the new assertions fail.
|
|
62
|
+
- [ ] Implement a temporary-repository signing probe using `ssh-add -L`, a temporary allowed-signers file, and `git commit --allow-empty`; set global SSH signing only after it succeeds, otherwise set global `commit.gpgsign=false` and print a warning.
|
|
63
|
+
- [ ] Remove unconditional global signing disablement and all post-create local `commit.gpgsign` mutations; call the bootstrap after create and start.
|
|
64
|
+
- [ ] Rerun the hook tests and confirm they pass.
|
|
65
|
+
|
|
66
|
+
### Task 3: Use one signing-aware lifecycle for every command
|
|
67
|
+
|
|
68
|
+
**Files:**
|
|
69
|
+
|
|
70
|
+
- Modify: `src/devcontainer.ts`, `src/main.ts`
|
|
71
|
+
- Test: `__tests__/app.test.ts`
|
|
72
|
+
|
|
73
|
+
**Interfaces:**
|
|
74
|
+
|
|
75
|
+
```ts
|
|
76
|
+
export async function resolveGitSigningPlan(context: WorkspaceContext): Promise<GitSigningPlan>
|
|
77
|
+
export async function ensureContainerGitSigning(context: WorkspaceContext, plan: GitSigningPlan, options?: ContainerCommandOptions): Promise<void>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
- [ ] Write failing command-flow tests proving `startDevcontainer` writes a signing-aware config and invokes the non-fatal container signing refresh for fresh and reused containers.
|
|
81
|
+
- [ ] Run the relevant `CLI execution` and `coding-agent command mapping` tests and confirm they fail on the missing signing lifecycle.
|
|
82
|
+
- [ ] Resolve the plan before writing generated config, pass plan state to the lifecycle script, and call the refresh from shared startup so setup, shell, coding agents, SSH proxy, and tunnels all inherit it.
|
|
83
|
+
- [ ] Ensure refresh failures only warn and do not change the command exit code.
|
|
84
|
+
- [ ] Rerun focused lifecycle tests and confirm they pass.
|
|
85
|
+
|
|
86
|
+
### Task 4: Add doctor/preflight warnings and user documentation
|
|
87
|
+
|
|
88
|
+
**Files:**
|
|
89
|
+
|
|
90
|
+
- Modify: `src/doctor.ts`, `src/main.ts`, `README.md`, `docs/features/setup.md`, `docs/architecture.md`, `docs/features/README.md`
|
|
91
|
+
- Create: `docs/features/commit-signing.md`, `.changeset/<generated-name>.md`
|
|
92
|
+
- Test: `__tests__/app.test.ts`
|
|
93
|
+
|
|
94
|
+
- [ ] Write failing doctor tests for unavailable agent, ambiguous identities, unusable mount, missing GitHub signing registration, and warning-only setup behavior.
|
|
95
|
+
- [ ] Run the `doctor output` and setup-preflight tests and confirm the new checks are absent.
|
|
96
|
+
- [ ] Add warning-only host signing checks, including an optional GitHub signing-key query; do not add account mutations or required preflight failures.
|
|
97
|
+
- [ ] Document automatic selection order, unsigned fallback, Docker mount limitations, agent security exposure, and GitHub's one-time separate signing-key registration.
|
|
98
|
+
- [ ] Add a changeset for default-on best-effort commit signing.
|
|
99
|
+
- [ ] Rerun focused doctor/setup tests and lint changed Markdown.
|
|
100
|
+
|
|
101
|
+
### Task 5: Verify the full feature
|
|
102
|
+
|
|
103
|
+
**Files:**
|
|
104
|
+
|
|
105
|
+
- Test: `__tests__/app.test.ts`
|
|
106
|
+
|
|
107
|
+
- [ ] Run `node --import tsx --test __tests__/**/*.test.ts`; record the two known unrelated baseline failures and require no additional failures.
|
|
108
|
+
- [ ] Run `npm run build` and `npm run lint` using local project tooling where available.
|
|
109
|
+
- [ ] With Docker and a loaded agent available, create a disposable container using the generated mount, make an empty signed commit, and verify its SSH fingerprint; do not push it.
|
|
110
|
+
- [ ] Review `git diff --check`, changed docs, and the implementation against `docs/superpowers/specs/2026-07-11-default-commit-signing-design.md`.
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# Progress CI Regression Implementation Plan
|
|
2
|
+
|
|
3
|
+
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
|
4
|
+
|
|
5
|
+
**Goal:** Restore CI by making progress checklist cleanup mode-independent and updating stale spinner-label source assertions.
|
|
6
|
+
|
|
7
|
+
**Architecture:** Preserve the existing `ProgressReporter` API and output behavior. Move only internal cleanup ahead of rendering guards, then loosen two source-presence assertions while leaving runtime checklist-output coverage intact.
|
|
8
|
+
|
|
9
|
+
**Tech Stack:** TypeScript, Node.js 24 test runner, `node:assert`, pnpm, ESLint, tsdown
|
|
10
|
+
|
|
11
|
+
## Global Constraints
|
|
12
|
+
|
|
13
|
+
- Do not change progress APIs, spinner copy, output formatting, or command flow.
|
|
14
|
+
- Use Node.js 24 for tests because the current Node.js 26 host runtime is incompatible with an installed CommonJS test dependency.
|
|
15
|
+
- Commit documentation separately from the implementation, as explicitly requested.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
### Task 1: Commit the approved documentation
|
|
20
|
+
|
|
21
|
+
**Files:**
|
|
22
|
+
|
|
23
|
+
- Create: `docs/superpowers/specs/2026-07-11-progress-ci-regression-design.md`
|
|
24
|
+
- Create: `docs/superpowers/plans/2026-07-11-progress-ci-regression.md`
|
|
25
|
+
|
|
26
|
+
**Interfaces:**
|
|
27
|
+
|
|
28
|
+
- Consumes: The user-approved diagnosis and design.
|
|
29
|
+
- Produces: Durable design and execution context for the CI fix.
|
|
30
|
+
|
|
31
|
+
- [ ] **Step 1: Verify documentation formatting**
|
|
32
|
+
|
|
33
|
+
Run:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
git diff --check
|
|
37
|
+
fnm exec --using v24.15.0 node ../../node_modules/markdownlint-cli/markdownlint.js \
|
|
38
|
+
-c .github/.markdownlint.yml -i 'apm_modules/**' -i '.git' -i '__tests__' \
|
|
39
|
+
-i '.github' -i '.changeset' -i 'CODE_OF_CONDUCT.md' -i 'CHANGELOG.md' \
|
|
40
|
+
-i 'node_modules' -i 'dist' '**/**.md'
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Expected: PASS with no whitespace or Markdown lint errors.
|
|
44
|
+
|
|
45
|
+
- [ ] **Step 2: Commit documentation only**
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
git add docs/superpowers/specs/2026-07-11-progress-ci-regression-design.md docs/superpowers/plans/2026-07-11-progress-ci-regression.md
|
|
49
|
+
git commit -m "docs: design progress CI regression fix"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Expected: A commit containing only the design specification and implementation plan.
|
|
53
|
+
|
|
54
|
+
### Task 2: Fix progress cleanup and stale assertions
|
|
55
|
+
|
|
56
|
+
**Files:**
|
|
57
|
+
|
|
58
|
+
- Modify: `src/progress.ts:147`
|
|
59
|
+
- Test: `__tests__/app.test.ts:3080`
|
|
60
|
+
- Test: `__tests__/app.test.ts:3427`
|
|
61
|
+
|
|
62
|
+
**Interfaces:**
|
|
63
|
+
|
|
64
|
+
- Consumes: `ProgressReporter.end()` and `ProgressReporter.isChecklistActive()`.
|
|
65
|
+
- Produces: Mode-independent reporter cleanup without API changes.
|
|
66
|
+
|
|
67
|
+
- [ ] **Step 1: Verify the existing tests reproduce both CI failures**
|
|
68
|
+
|
|
69
|
+
Run:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
fnm exec --using v24.15.0 node --import tsx --test \
|
|
73
|
+
--test-name-pattern='reports whether a checklist is active|hidden command helpers use friendly spinner labels' \
|
|
74
|
+
__tests__/app.test.ts
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Expected: FAIL because checklist state remains active in `none` mode and the SSH label regular expressions require an outdated direct-property expression.
|
|
78
|
+
|
|
79
|
+
- [ ] **Step 2: Make cleanup independent of rendering mode**
|
|
80
|
+
|
|
81
|
+
In `ProgressReporter.end()`, clear internal state immediately after stopping timers:
|
|
82
|
+
|
|
83
|
+
```ts
|
|
84
|
+
this.#steps = []
|
|
85
|
+
this.#renderedStepLineCount = 0
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Remove the existing duplicate cleanup after the interactive section terminator.
|
|
89
|
+
|
|
90
|
+
- [ ] **Step 3: Make the source-presence assertions expression-shape independent**
|
|
91
|
+
|
|
92
|
+
Replace the two SSH assertions with:
|
|
93
|
+
|
|
94
|
+
```ts
|
|
95
|
+
assert.match(sshKeySource, /Generating Boxdown SSH identity/)
|
|
96
|
+
assert.match(sshKeySource, /Writing Boxdown SSH public key/)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
- [ ] **Step 4: Verify the focused regression tests pass**
|
|
100
|
+
|
|
101
|
+
Run the Step 1 command again.
|
|
102
|
+
|
|
103
|
+
Expected: PASS for both selected tests.
|
|
104
|
+
|
|
105
|
+
- [ ] **Step 5: Run full verification**
|
|
106
|
+
|
|
107
|
+
Run:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
fnm exec --using v24.15.0 node ../../node_modules/c8/bin/c8.js node --import tsx --test __tests__/**/*.test.ts
|
|
111
|
+
fnm exec --using v24.15.0 node ../../node_modules/eslint/bin/eslint.js .
|
|
112
|
+
fnm exec --using v24.15.0 node ../../node_modules/typescript/bin/tsc
|
|
113
|
+
fnm exec --using v24.15.0 node ../../node_modules/tsdown/dist/run.mjs
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Expected: All tests pass, ESLint reports no errors, TypeScript compilation succeeds, and tsdown builds successfully.
|
|
117
|
+
|
|
118
|
+
- [ ] **Step 6: Commit the implementation separately**
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
git add src/progress.ts __tests__/app.test.ts
|
|
122
|
+
git commit -m "fix(progress): clear checklist state in every mode"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Expected: A second commit containing only the production fix and updated assertions.
|