Commit Graph

70 Commits

Author SHA1 Message Date
Yeachan-Heo
45dc4f6ff0 Stabilize JSON action contract for local CLI surfaces
Guard the local/no-credential JSON command sweep so future additions fail fast when action is absent or empty.

Constraint: ROADMAP #710-#713 fixed most JSON surfaces; #714 dogfood sweep found remaining help and sandbox gaps.

Rejected: Schema redesign for help output | outside the action-field contract scope.

Confidence: high

Scope-risk: narrow

Directive: Keep --output-format json envelopes carrying a stable non-empty action on every local CLI surface.

Tested: cargo fmt --manifest-path rust/Cargo.toml --all; cargo fmt --manifest-path rust/Cargo.toml --all -- --check; cargo test --manifest-path rust/Cargo.toml -p rusty-claude-cli --test output_format_contract -- --nocapture; cargo check --manifest-path rust/Cargo.toml -p rusty-claude-cli; git diff --check

Not-tested: full workspace cargo test
2026-05-25 19:06:16 +00:00
YeonGyu-Kim
bae0099c7c fix(#711): add missing action fields to version/system-prompt/export/init json responses; add contract test assertions 2026-05-26 02:33:26 +09:00
YeonGyu-Kim
f8a901c2a5 fix(#710): diff --output-format json adds missing action:diff and working_directory fields to both ok and error branches 2026-05-26 02:07:46 +09:00
Yeachan-Heo
1b5a9b02c2 test: cover config warning dedup for inventory commands
Add a CLI contract proving plugins list and mcp list emit a deprecated enabledPlugins warning only once per process after config warning dedup landed. Covers ROADMAP #698.
2026-05-25 15:30:48 +00:00
YeonGyu-Kim
8f809d9a9e fix(#704): DiagnosticCheck.json_value now emits stable snake_case id field; doctor checks addressable without scraping name prose 2026-05-25 23:04:06 +09:00
YeonGyu-Kim
1a6f54b970 fix(#703): plugins list JSON now has summary:{total,enabled,disabled,load_failures}; drop reload_runtime/target from list response in both top-level and resume paths 2026-05-25 22:34:20 +09:00
Yeachan-Heo
566992c331 Unify inventory provenance for generic parsers
Expose a stable source object on agent and skill inventory entries with the same id/label/detail_label keys while preserving skill origin for compatibility.\n\nConstraint: ROADMAP #702 scope only; keep existing skills origin field for compatibility.\nRejected: Rename agent source to origin | would break existing agents consumers and still require per-resource branching during migration.\nConfidence: high\nScope-risk: narrow\nDirective: Future inventory resources should expose provenance through source.id, source.label, and source.detail_label.\nTested: cargo fmt --manifest-path rust/Cargo.toml --all -- --check; cargo test --manifest-path rust/Cargo.toml -p commands renders_skills_reports_as_json -- --nocapture; cargo test --manifest-path rust/Cargo.toml -p rusty-claude-cli --test output_format_contract -- --nocapture; cargo build --manifest-path rust/Cargo.toml --workspace --locked; git diff --check\nNot-tested: full cargo test --manifest-path rust/Cargo.toml --workspace
2026-05-25 12:05:50 +00:00
YeonGyu-Kim
ee24ff2d83 Merge pull request #3102 from Yeachan-Heo/fix/issue-696-compact-nontty
Fix compact non-TTY hang
2026-05-25 19:41:27 +09:00
Yeachan-Heo
9e6f753640 Fail closed for compact without an interactive session
Route bare compact invocations to a typed interactive-only error before prompt/provider startup so non-TTY JSON probes terminate predictably. Keep the existing resume-session /compact path as the supported automation surface.\n\nConstraint: ROADMAP pinpoint #696 requires no spinner/hang for closed stdin and --output-format json.\nRejected: Broad help-schema rewrites | #699/#700/#701 are outside this PR scope.\nConfidence: high\nScope-risk: narrow\nDirective: Do not route bare slash-command names through the prompt fallback when they require a session.\nTested: cargo fmt --manifest-path rust/Cargo.toml --all -- --check; cargo test --manifest-path rust/Cargo.toml -p rusty-claude-cli --test compact_output compact_subcommand_ -- --nocapture; cargo build --manifest-path rust/Cargo.toml --workspace; cargo build --manifest-path rust/Cargo.toml --workspace --locked; timeout probes for compact JSON/text with stdin closed.\nNot-tested: Full workspace test suite.
2026-05-25 10:37:12 +00:00
YeonGyu-Kim
9d1998b3fd test(#458/#700/#701/#702): add status:ok assertions for help/bootstrap-plan/export-help contracts; add diff/export JSON shape tests 2026-05-25 19:07:03 +09:00
Nils
fc26e16ce2 fix: resolve model aliases before syntax validation
Fixes alias resolution ordering: aliases (opus/sonnet/haiku) are now resolved to their full provider/model form BEFORE syntax validation. Previously, aliases bypassed validation via an early-return check. Also adds the 'log' crate for debug tracing of alias resolution and wraps PermissionsExt import in #[cfg(unix)] for portability.
2026-05-25 11:21:32 +09:00
bellman
04c2abb412 Stabilize final gate before release checkpoint
Resolve the G012 evidence gate by fixing permission-mode regressions, platform-sensitive tests, and the clippy surface that blocked an all-targets verification run.

Constraint: G012 final gate required docs, board, full workspace tests, and clippy -D warnings evidence before checkpointing.

Rejected: documenting the worker-2 gate failure as an accepted gap | the failing tests and lints were locally reproducible and fixable.

Confidence: high

Scope-risk: moderate

Directive: Preserve read-only permission requirements for read/glob/grep tools; write/edit remain workspace-write or danger-full-access when outside the workspace.

Tested: python3 .github/scripts/check_doc_source_of_truth.py; python3 .github/scripts/check_release_readiness.py; python3 scripts/validate_cc2_board.py --board .omx/cc2/board.json; python3 .omx/cc2/validate_issue_parity_intake.py .omx/cc2/issue-parity-intake.json; cargo fmt --manifest-path rust/Cargo.toml --all -- --check; cargo check --manifest-path rust/Cargo.toml --workspace; cargo test --manifest-path rust/Cargo.toml --workspace -- --nocapture; cargo clippy --manifest-path rust/Cargo.toml --workspace --all-targets -- -D warnings

Not-tested: live network provider smoke tests and remote PR/issue mutations.
2026-05-15 13:34:57 +09:00
bellman
4cd2bb859b omx(team): auto-checkpoint worker-1 [1] 2026-05-15 11:49:01 +09:00
bellman
3767addd11 omx(team): auto-checkpoint worker-2 [unknown] 2026-05-15 10:43:35 +09:00
bellman
7ed1cabc14 Prove observable MCP required optional contracts
Added CLI JSON regression coverage for MCP required versus optional flags, redacted env/header values, degraded malformed config reporting, and failed unsupported usage reporting without touching runtime internals.

Constraint: Task 12 scope preferred rusty-claude-cli tests and avoid worker-1/3 MCP internals.

Rejected: Runtime lifecycle edits | existing observable JSON contracts already expose required, redacted keys, degraded config, and unsupported-action failure semantics.

Confidence: high

Scope-risk: narrow

Directive: Preserve secret-value redaction by exposing env/header keys only; keep degraded config distinct from usage errors.

Tested: cargo fmt --manifest-path Cargo.toml -p rusty-claude-cli --check; cargo test --manifest-path Cargo.toml -p rusty-claude-cli --test output_format_contract mcp_ -- --nocapture; cargo check --manifest-path Cargo.toml -p rusty-claude-cli.

Not-tested: Full output_format_contract currently has unrelated pre-existing failures in plugin/doctor contract tests.
2026-05-15 10:07:47 +09:00
bellman
ace260139e omx(team): auto-checkpoint worker-3 [4] 2026-05-15 09:59:06 +09:00
bellman
db6f30fa33 verify plugin lifecycle JSON contract
Lock the plugin inventory JSON contract so lifecycle state and lifecycle summary fields stay visible to orchestrators while allowing bundled plugins to coexist in isolated inventories.

Constraint: G007-plugin-mcp Task 1 requires plugin/MCP lifecycle contract evidence without mutating .omx/ultragoal.

Rejected: Assuming an empty plugin inventory in tests | bundled plugins are auto-synced and should not make lifecycle contract verification brittle.

Confidence: high

Scope-risk: narrow

Directive: Keep plugin inventory JSON machine-readable for lifecycle_state, lifecycle, status, and load_failures; do not collapse it back to message-only JSON.

Tested: cargo test -p plugins plugin_registry_report_collects_load_failures_without_dropping_valid_plugins -- --nocapture; cargo test -p commands renders_plugins_report -- --nocapture; cargo test -p rusty-claude-cli --test output_format_contract plugins_json_surfaces_lifecycle_contract_when_plugin_is_installed -- --nocapture; cargo test -p rusty-claude-cli --test output_format_contract inventory_commands_emit_structured_json_when_requested -- --nocapture; cargo check --workspace; cargo fmt --all -- --check

Not-tested: cargo clippy -p rusty-claude-cli --test output_format_contract -- -D warnings is blocked by pre-existing runtime::policy_engine::LaneContext clippy::struct_excessive_bools.

Co-authored-by: OmX <omx@oh-my-codex.dev>
2026-05-15 09:59:02 +09:00
bellman
983ceb939c omx(team): auto-checkpoint worker-1 [1] 2026-05-15 09:57:03 +09:00
bellman
cac73b4410 omx(team): auto-checkpoint worker-3 [4] 2026-05-15 09:57:00 +09:00
bellman
985c6e97f9 omx(team): auto-checkpoint worker-1 [1] 2026-05-15 09:56:50 +09:00
bellman
c522dc970f Preserve plugin lifecycle JSON in G007 CLI output
Constraint: G007 worker integrations made plugin command JSON degraded-aware but omitted the structured plugin/load-failure arrays expected by inventory contracts.\nRejected: Drop lifecycle arrays from tests | G007 requires plugin lifecycle state to stay machine-readable across plugin surfaces.\nConfidence: high\nScope-risk: narrow\nDirective: Keep  carrying plugin entries, lifecycle state, and load failures even when config loading degrades.\nTested: cargo fmt --manifest-path rust/Cargo.toml --all -- --check; cargo check --manifest-path rust/Cargo.toml -p runtime -p tools -p rusty-claude-cli -p commands -p plugins; cargo test --manifest-path rust/Cargo.toml -p rusty-claude-cli --test output_format_contract plugins_json_surfaces_lifecycle_contract_when_plugin_is_installed -- --nocapture; cargo test --manifest-path rust/Cargo.toml -p rusty-claude-cli --test output_format_contract inventory_commands_emit_structured_json_when_requested -- --nocapture; git diff --check\nNot-tested: full workspace suite\n\nCo-authored-by: OmX <omx@oh-my-codex.dev>
2026-05-15 09:56:46 +09:00
bellman
2454f012b6 omx(team): auto-checkpoint worker-1 [1] 2026-05-15 09:52:29 +09:00
bellman
aec291caab omx(team): auto-checkpoint worker-4 [unknown] 2026-05-14 17:51:53 +09:00
bellman
43b182882a Lock doctor JSON boot preflight contract
Constraint: G003 boot/session work adds a structured doctor boot-preflight check that must be visible in JSON output.
Rejected: reducing the doctor check count back to six | boot preflight is an explicit G003 acceptance surface.
Confidence: high
Scope-risk: narrow
Directive: Keep doctor/status JSON contract tests aligned with boot_preflight schema fields when extending preflight diagnostics.
Tested: git diff --check; cargo fmt --manifest-path rust/Cargo.toml --all -- --check; cargo test --manifest-path rust/Cargo.toml -p runtime trusted_roots -- --nocapture; cargo test --manifest-path rust/Cargo.toml -p runtime startup -- --nocapture; cargo test --manifest-path rust/Cargo.toml -p runtime worker_boot -- --nocapture; cargo test --manifest-path rust/Cargo.toml -p tools path_scope -- --nocapture; cargo test --manifest-path rust/Cargo.toml -p rusty-claude-cli --test output_format_contract -- --nocapture; cargo check --manifest-path rust/Cargo.toml --workspace
Not-tested: full cargo test --workspace remains deferred during active G003 team reconciliation.

Co-authored-by: OmX <omx@oh-my-codex.dev>
2026-05-14 17:51:47 +09:00
bellman
9ab569e626 omx(team): auto-checkpoint worker-2 [3] 2026-05-14 17:18:55 +09:00
YeonGyu-Kim
75c08bc982 fix: REPL display, /compact panic, identity leak, DeepSeek reasoning, thinking blocks
Five interrelated fixes from parallel Hephaestus sessions:

1. fix(repl): display assistant text after spinner (#2981, #2982, #2937)
   - Added final_assistant_text() call after run_turn spinner completes
   - REPL now shows response text like run_prompt_json does

2. fix(compact): handle Thinking content blocks (#2985)
   - Added ContentBlock::Thinking variant throughout compact summarizer
   - Prevents panic when /compact encounters thinking blocks

3. fix(prompt): provider-aware model identity (#2822)
   - New ModelFamilyIdentity enum (Claude vs Generic)
   - Non-Anthropic models no longer say 'I am Claude'
   - model_family_identity_for() detects provider and sets identity

4. fix(openai): preserve DeepSeek reasoning_content (#2821)
   - Stream parser now captures reasoning_content from OpenAI-compat
   - Emits ThinkingDelta/SignatureDelta events for reasoning models
   - Thinking blocks included in conversation history for re-send

5. feat(runtime): Thinking block support across codebase
   - AssistantEvent::Thinking variant in conversation.rs
   - ContentBlock::Thinking in session serialization
   - Thinking-aware compact summarization
   - Tests for thinking block ordering and content

Closes #2981, #2982, #2937, #2985, #2822, #2821
2026-05-06 15:32:34 +09:00
YeonGyu-Kim
b4733b67a6 Merge pull request #2949 from Yeachan-Heo/fix/export-help-json
Fix export help JSON output
2026-05-06 14:52:09 +09:00
YeonGyu-Kim
65aa559733 fix: support /plugins slash command in resume mode (#2973)
* fix: support /plugins slash command in resume mode

Move SlashCommand::Plugins out of the 'unsupported resumed slash
command' catch-all and add a handler arm in run_resume_command that
calls handle_plugins_slash_command for list/help actions.

Mutation actions (install/uninstall/enable/disable) are rejected with
a clear error since there is no runtime to reload in resume mode.

Add /plugins coverage to resumed_inventory_commands test in
output_format_contract.rs: kind, action, reload_runtime, target.

Before: claw --resume session.jsonl /plugins --output-format json
-> {error: 'unsupported resumed slash command', type: 'error'}, exit 1

After: claw --resume session.jsonl /plugins --output-format json
-> {kind: 'plugin', action: 'list', ...}, exit 0

* style: cargo fmt line wrap in run_resume_command plugins handler

* fix: block /plugins update in resume mode, fix comment

Address REQUEST_CHANGES from OMX review:
1. Add 'update' to the blocked mutation actions in resume mode
   (previously only install/uninstall/enable/disable were blocked)
2. Fix comment: 'Only list is supported' instead of 'Only list/help'
   since /plugins help doesn't actually parse as a valid action

* style: cargo fmt after conflict resolution
2026-05-05 04:55:39 +09:00
YeonGyu-Kim
ac8a24b30b fix(config): emit section and section_value in JSON output for config subcommands (#2990)
`claw config model --output-format json` and all other section subcommands
(`env`, `hooks`, `plugins`) returned identical output with no section field
— the section arg was parsed but discarded (_section parameter).

Fix: render_config_json now:
- Passes section through to handler
- Looks up the section value via runtime_config.get(), converting the
  internal JsonValue to serde_json::Value via render()+parse
- Emits `section` (string) and `section_value` (JSON value or null)
  in the response envelope
- Returns ok:false + error for unsupported section tokens

Test: config_section_json_emits_section_and_value asserts:
- No section field when no section arg
- section + section_value fields present for all known sections
- ok:false + error for unknown section

Pinpoint: ROADMAP #126
2026-05-05 04:50:33 +09:00
YeonGyu-Kim
9b97c4d832 fix(tests): isolate CLAW_CONFIG_HOME in resumed_status JSON test (#2992)
resumed_status_command_emits_structured_json_when_requested was reading
the real ~/.claw/settings.json, causing loaded_config_files to be 1
instead of the expected 0 on machines with user config present.

Root cause: unlike other tests (e.g. resumed_config_command_loads_settings_files),
this test did not pass an isolated CLAW_CONFIG_HOME env var to run_claw,
so claw fell back to the real HOME and loaded the developer's settings file.

Fix: create a temp config-home dir and pass it as CLAW_CONFIG_HOME via
run_claw_with_env. This gives the assertion a clean 0-file baseline.

Unblocks PRs #2973, #2988, #2990 which all failed this same test on main.

Ref: ROADMAP #65
2026-05-05 04:49:46 +09:00
YeonGyu-Kim
1206f4131d fix(resume): emit structured JSON for /agents --output-format json (#2987)
Resumed /agents --output-format json was returning a human-readable
text render wrapped in a JSON envelope field instead of the actual
structured agent list. The run_resume_command handler was calling
handle_agents_slash_command (text) for the json field instead of
handle_agents_slash_command_json.

Fix: use handle_agents_slash_command_json for the json outcome field,
matching the pattern already used by /skills and /plugins.

Test: extended resumed_inventory_commands_emit_structured_json_when_requested
to cover /agents, asserting kind=="agents", action=="list",
agents is an array, and count is a number (not a text render).
2026-05-05 04:20:52 +09:00
YeonGyu-Kim
c99330372c fix(version): add build_date and executable_path to version JSON output
`claw version --output-format json` was missing build_date and
executable_path, making it impossible to identify which binary is
running or correlate it with a specific build/commit.

Fix: version_json_value() now includes:
- build_date: compile-time BUILD_DATE env (already in text output)
- executable_path: std::env::current_exe() at runtime

Test: version_emits_json_when_requested extended to assert both fields
are strings in the JSON envelope.

Pinpoint: ROADMAP #507
2026-05-05 04:20:12 +09:00
YeonGyu-Kim
8e45f1850c test(output_format_contract): add plugins json coverage to inventory_commands test (#2972)
Add four assertions to inventory_commands_emit_structured_json_when_requested:
- kind == "plugin"
- action == "list"
- reload_runtime is boolean
- target is null when no plugin is targeted

Closes the only major --output-format json surface with zero contract
coverage. All other surfaces (agents, mcp, skills, status, sandbox,
doctor, help, version, acp, bootstrap-plan, system-prompt, init, diff,
config) already had test assertions.
2026-05-01 06:03:31 +09:00
Yeachan-Heo
51b9e6b37f Fix export help JSON output 2026-04-30 09:04:11 +00:00
Yeachan-Heo
74ea754d29 Restore Rust formatting compliance
Run rustfmt from the Rust workspace so CI format checks pass without changing behavior.

Constraint: Scope is formatting-only across tracked Rust files

Confidence: high

Scope-risk: narrow

Tested: cd rust && cargo fmt --check

Tested: git diff --check
2026-04-28 09:19:16 +00:00
YeonGyu-Kim
eaa077bf91 fix: #150 — eliminate symlink canonicalization flake in resume_latest test + file #246 (reminder outcome ambiguity)
## #150 Fix: resume_latest test flake

**Problem:** `resume_latest_restores_the_most_recent_managed_session` intermittently
fails when run in the workspace suite or multiple times in sequence, but passes in
isolation.

**Root cause:** `workspace_fingerprint(path)` hashes the path string without
canonicalization. On macOS, `/tmp` is a symlink to `/private/tmp`. The test
creates a temp dir via `std::env::temp_dir().join(...)` which returns
`/var/folders/...` (non-canonical). When the subprocess spawns,
`env::current_dir()` returns the canonical path `/private/var/folders/...`.
The two fingerprints differ, so the subprocess looks in
`.claw/sessions/<hash1>` while files are in `.claw/sessions/<hash2>`.
Session discovery fails.

**Fix:** Call `fs::canonicalize(&project_dir)` after creating the directory
to ensure test and subprocess use identical path representations.

**Verification:** 5 consecutive runs of the full test suite — all pass.
Previously: 5/5 failed when run in sequence.

## #246 Filing: Reminder cron outcome ambiguity (control-loop blocker)

The `clawcode-dogfood-cycle-reminder` cron times out repeatedly with no
structured feedback on whether the nudge was delivered, skipped, or died in-flight.

**Phase 1 outcome schema** — add explicit field to cron result:
- `delivered` — nudge posted to Discord
- `timed_out_before_send` — died before posting
- `timed_out_after_send` — posted but cleanup timed out
- `skipped_due_to_active_cycle` — previous cycle active
- `aborted_gateway_draining` — daemon shutdown

Assigned to gaebal-gajae (cron/orchestration domain). Unblocks trustworthy
dogfood cycle observability.

Closes ROADMAP #150. Filed ROADMAP #246.
2026-04-21 21:01:09 +09:00
YeonGyu-Kim
a8beca1463 fix: #136 support --output-format json with --compact flag
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-21 14:47:15 +09:00
Yeachan-Heo
ac45bbec15 Make ACP/Zed status obvious before users go source-diving
ROADMAP #21, #22, and #23 were already closed on current main, so the next real repo-local backlog item was the ACP/Zed discoverability gap. This adds a local `claw acp` status surface plus aliases, updates help/docs, and separates the shipped discoverability fix from the still-open daemon/protocol follow-up so editor-first users get a crisp answer immediately.

Constraint: No ACP/Zed daemon or protocol server exists in claw-code yet, so the new surface must be explicit status guidance rather than a fake implementation
Rejected: Add a pretend `acp serve` daemon path | would imply supported protocol behavior that does not exist
Rejected: Docs-only clarification | still leaves `claw --help` unable to answer the editor-launch question directly
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep ROADMAP discoverability fixes separate from future ACP daemon/protocol work so help text and backlog IDs stay unambiguous
Tested: cargo fmt --check; cargo clippy --workspace --all-targets -- -D warnings; cargo test --workspace; cargo run -q -p rusty-claude-cli -- acp; cargo run -q -p rusty-claude-cli -- --output-format json acp; architect review APPROVED
Not-tested: Real ACP/Zed daemon launch because no protocol-serving surface exists yet
2026-04-16 03:13:50 +00:00
Yeachan-Heo
2e34949507 Keep latest-session timestamps increasing under tight loops
The next repo-local sweep target was ROADMAP #73: repeated backlog
sweeps exposed that session writes could share the same wall-clock
millisecond, which made semantic recency fragile and forced the
resume-latest regression to sleep between saves. The fix makes session
timestamps monotonic within the process and removes the timing hack
from the test so latest-session selection stays stable under tight
loops.

Constraint: Preserve the existing session file format while changing only the timestamp source semantics
Rejected: Keep the sleep-based test workaround | hides the real ordering hazard instead of fixing timestamp generation
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Any future session-recency logic must keep `current_time_millis`, ordering tests, and latest-session expectations aligned
Tested: cargo fmt --all --check; cargo clippy --workspace --all-targets -- -D warnings; cargo test --workspace; architect review APPROVE
Not-tested: Cross-process monotonicity when multiple binaries write sessions concurrently
2026-04-12 10:51:19 +00:00
Yeachan-Heo
8f53524bd3 Make backlog-scan lanes say what they actually selected
The next repo-local sweep target was ROADMAP #65: backlog-scanning
lanes could stop with prose-only summaries naming roadmap items, but
there was no machine-readable record of which items were chosen,
which were skipped, or whether the lane intended to execute, review,
or no-op. The fix teaches completed lane persistence to extract a
structured selection outcome while preserving the existing quality-
floor and review-verdict behavior for other lanes.

Constraint: Keep selection-outcome extraction on the existing `lane.finished` metadata path instead of inventing a separate event stream
Rejected: Add a dedicated selection event type first | unnecessary for this focused closeout because `lane.finished` already persists structured data downstream can read
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: If backlog-scan summary conventions change later, update `extract_selection_outcome`, its regression test, and the ROADMAP closeout wording together
Tested: cargo fmt --all --check; cargo clippy --workspace --all-targets -- -D warnings; cargo test --workspace; architect review APPROVE after roadmap closeout update
Not-tested: Downstream consumers that may still ignore `lane.finished.data.selectionOutcome`
2026-04-12 09:54:37 +00:00
Yeachan-Heo
3b806702e7 Make the CLI point users at the real install source
The next repo-local backlog item was ROADMAP #70: users could
mistake third-party pages or the deprecated `cargo install
claw-code` path for the official install route. The CLI now
surfaces the source of truth directly in `claw doctor` and
`claw --help`, and the roadmap closeout records the change.

Constraint: Keep the fix inside repo-local Rust CLI surfaces instead of relying on docs alone
Rejected: Close #70 with README-only wording | the bug was user-facing CLI ambiguity, so the warning needed to appear in runtime help/doctor output
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: If install guidance changes later, update both the doctor check payload and the help-text warning together
Tested: cargo fmt --all --check; cargo clippy --workspace --all-targets -- -D warnings; cargo test --workspace; architect review APPROVE
Not-tested: Third-party websites outside this repo that may still present stale install instructions
2026-04-12 04:50:03 +00:00
Yeachan-Heo
4f83a81cf6 Make dump-manifests recoverable outside the inferred build tree
The backlog sweep found that the user-cited #21-#23 items were already
closed, and the next real pain point was `claw dump-manifests` failing
without a direct way to point at the upstream manifest source. This adds
an explicit `--manifests-dir` path, upgrades the failure messages to say
whether the source root or required files are missing, and updates the
ROADMAP closeout to reflect that #45 is now fixed.

Constraint: Preserve existing dump-manifests behavior when no explicit override is supplied
Rejected: Require CLAUDE_CODE_UPSTREAM for every invocation | breaks existing build-tree workflows and is unnecessarily rigid
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: Keep manifest-source override guidance centralized so future error-path edits do not drift
Tested: cargo fmt --all; cargo clippy --workspace --all-targets -- -D warnings; cargo test --workspace; architect review APPROVE
Not-tested: Manual invocation against every legacy env-based manifest lookup layout
2026-04-12 02:57:11 +00:00
Yeachan-Heo
61c01ff7da Prevent cross-worktree session bleed during managed session resume/load
ROADMAP #41 was still leaving a phantom-completion class open: managed
sessions could be resumed from the wrong workspace, and the CLI/runtime
paths were split between partially isolated storage and older helper
flows. This squashes the verified team work into one deliverable that
routes managed session operations through the per-worktree SessionStore,
rejects workspace mismatches explicitly, extends lane-event taxonomy for
workspace mismatch reporting, and updates the affected CLI regression
fixtures/docs so the new contract is enforced without losing same-
workspace legacy coverage.

Constraint: Keep same-workspace legacy flat sessions readable while blocking cross-worktree misuse
Constraint: No new dependencies; stay within the ROADMAP #41 changed-file scope
Rejected: Leave team auto-checkpoint history as final branch state | noisy/non-lore history for a single roadmap fix
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Preserve workspace_root validation on future resume/load helpers; do not reintroduce path-only fallback without equivalent mismatch checks
Tested: cargo test -p runtime session_control -- --nocapture; cargo test -p rusty-claude-cli resume -- --nocapture; cargo test -p rusty-claude-cli --test cli_flags_and_config_defaults; cargo test -p rusty-claude-cli --test output_format_contract; cargo test -p rusty-claude-cli --test resume_slash_commands; cargo test --workspace --exclude compat-harness; cargo check --workspace --all-targets; git diff --check
Not-tested: cargo clippy --workspace --all-targets -- -D warnings (pre-existing failures in unchanged rust/crates/rusty-claude-cli/build.rs)
Related: ROADMAP #41
2026-04-11 16:08:28 +00:00
YeonGyu-Kim
810036bf09 test(cli): add integration test for model persistence in resumed /status
New test: resumed_status_surfaces_persisted_model
- Creates session with model='claude-sonnet-4-6'
- Resumes with --output-format json /status
- Asserts model round-trips through session metadata

Resume integration tests: 11 → 12.
2026-04-10 10:31:05 +09:00
YeonGyu-Kim
74311cc511 test(cli): add 5 integration tests for resume JSON parity
New integration tests covering recent JSON parity work:
- resumed_version_command_emits_structured_json
- resumed_export_command_emits_structured_json
- resumed_help_command_emits_structured_json
- resumed_no_command_emits_restored_json
- resumed_stub_command_emits_not_implemented_json

Prevents regression on ROADMAP #54 (stub command error), #55 (session
list), #56 (--resume no-command JSON), #57 (session load errors).

Resume integration tests: 6 → 11.
2026-04-10 08:03:17 +09:00
YeonGyu-Kim
0845705639 fix(tests): update test assertions for null model in resume /status; drop unused import
Two integration tests expected 'model':'restored-session' in the /status
JSON output but dc4fa55 changed resume mode to emit null for model.
Updated both assertions to assert model is null (correct behavior).

Also remove unused 'estimate_session_tokens' import in compact.rs tests
(surfaced as warning in CI, kept failing CI green noise).

All workspace tests pass.
2026-04-10 03:21:58 +09:00
YeonGyu-Kim
5851f2dee8 fix(cli): 6 cascading test regressions hidden behind client_integration gate
- compact flag: was parsed then discarded (`compact: _`) instead of
  passed to `run_turn_with_output` — hardcoded `false` meant --compact
  never took effect
- piped stdin vs permission prompter: `read_piped_stdin()` consumed all
  stdin before `CliPermissionPrompter::decide()` could read interactive
  approval answers; now only consumes stdin as prompt context when
  permission mode is `DangerFullAccess` (fully unattended)
- session resolver: `resolve_managed_session_path` and
  `list_managed_sessions` now fall back to the pre-isolation flat
  `.claw/sessions/` layout so legacy sessions remain accessible
- help assertion: match on stable prefix after `/session delete` was
  added in batch 5
- prompt shorthand: fix copy-paste that changed expected prompt from
  "help me debug" to "$help overview"
- mock parity harness: filter captured requests to `/v1/messages` path
  only, excluding count_tokens preflight calls added by `be561bf`

All 6 failures were pre-existing but masked because `client_integration`
always failed first (fixed in 8c6dfe5).

Workspace: 810+ tests passing, 0 failing.
2026-04-08 14:54:10 +09:00
YeonGyu-Kim
4be4b46bd9 feat: b5-git-aware — batch 5 upstream parity 2026-04-07 14:51:26 +09:00
Yeachan-Heo
f9cb42fb44 Resolve claw-code main merge conflicts 2026-04-06 07:16:57 +00:00
Yeachan-Heo
fe4da2aa65 Keep resumed JSON command surfaces machine-readable
Resumed slash dispatch was still dropping back to prose for several JSON-capable local commands, which forced automation to special-case direct CLI invocations versus --resume flows. This routes resumed local-command handlers through the same structured JSON payloads used by direct status, sandbox, inventory, version, and init commands, and records the inventory parity audit result in the roadmap.

Constraint: Text-mode resumed output must stay unchanged for existing shell users
Rejected: Teach callers to scrape resumed text output | brittle and defeats the JSON contract
Confidence: high
Scope-risk: narrow
Reversibility: clean
Directive: When a direct local command has a JSON renderer, keep resumed slash dispatch on the same serializer instead of adding one-off format branches
Tested: cargo fmt --check; cargo test --workspace; cargo clippy --workspace --all-targets -- -D warnings
Not-tested: Live provider-backed REPL resume flows outside the local test harness
2026-04-06 02:00:33 +00:00