Skip to content

Release 0.22.1 — CLI contract overhaul & skills adoption#127

Merged
ronaldeddings merged 1 commit into
mainfrom
release/0.22.1
Jul 3, 2026
Merged

Release 0.22.1 — CLI contract overhaul & skills adoption#127
ronaldeddings merged 1 commit into
mainfrom
release/0.22.1

Conversation

@ronaldeddings

@ronaldeddings ronaldeddings commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

Summary

Ships the CLI-contract overhaul and skills adoption work, version-bumped to 0.22.1 across all surfaces (CLI, extension MV2/MV3, package). No PRD/internal references, filesystem paths, or PII in the diff.

What's new

  • Order-independent argument parsingcli/normalize.ts rewrites argv to [cmd, ...positionals, ...flags] at the dispatch choke point, driven by a per-family value-flag registry. open --text-only <url> no longer treats the URL as the flag value; adds --flag=value and -- terminator support to all normalized commands.
  • Progressive-disclosure help — bare interceptor / --help / help print a concise tier-0 capability card (was ~33KB); help <cmd> prints one command's contract + Returns/Example from the manifest; help --all keeps the full reference, filtered to installed surfaces.
  • Surface gating — browser-only installs no longer see macOS/iOS verbs in help, and interceptor macos|ios fails fast with an upgrade pointer before any daemon spawn (--all-surfaces / INTERCEPTOR_ALL_SURFACES override).
  • Agent capability discoveryinterceptor manifest emits machine-readable specs (usage, flags, returns semantics) for 50+ verbs plus surfaces and skills state.
  • Skills adoptioninterceptor skills list|status|show|adopt links the bundled browser-surface skill packs into supported agent runtimes.
  • iOS connection clarityios devices explains that connected:false is the normal idle state; the on-device runner auto-connects on the next verb.
  • Installer polishFixes Installer Summary pane unreadable in macOS dark mode (code/path spans + clipped heading) #123: conclusion panes declare light/dark color-scheme with explicit fg/bg pairs and an unclippable heading.

Validation

  • bunx tsc — clean
  • bun test — 649 pass, 10 skip, 0 fail

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a new skills command to list, inspect, and adopt skill packs across supported runtimes.
    • Introduced machine-readable manifest output and improved command help with clearer usage examples and surface-specific guidance.
    • Added install-time options to link skill packs automatically during setup.
  • Bug Fixes

    • Improved iOS connection/status messaging so idle devices are reported more clearly.
    • Updated status output to show skill-pack linking progress and warn when some targets are only partially linked.
  • Documentation

    • Expanded help text and installer instructions for connection behavior and skill-pack management.

Fixes #123: installer conclusion panes declare color-scheme light/dark with
explicit fg/bg pairs per scheme and an unclippable heading.

Order-independent argument parsing: cli/normalize.ts rewrites argv to
[cmd, ...positionals, ...flags] at the dispatch choke point, driven by a
per-family value-flag registry harvested from every command module.
`open --text-only <url>` no longer opens a tab whose URL is "--text-only".
Adds --flag=value and `--` terminator support to all normalized commands.

Progressive-disclosure help: bare `interceptor` / --help / help print a
concise tier-0 capability card (was ~33KB); `help <cmd>` prints one command's
contract plus Returns/Example from the manifest spec; `help --all` keeps the
full reference, filtered to installed surfaces.

Surface gating: browser-only installs no longer see macos/ios verbs in help,
and `interceptor macos|ios` fails fast with an upgrade pointer before any
daemon spawn. --all-surfaces / INTERCEPTOR_ALL_SURFACES override.

Agent capability discovery: `interceptor manifest` emits machine-readable
specs (usage, flags, returns semantics — innerText vs textContent vs markdown
vs a11y tree) for 50+ verbs plus surfaces and skills state.

Skills adoption: `interceptor skills list|status|show|adopt` links the bundled
browser-surface skill packs into supported agent runtimes.

iOS connection clarity: `ios devices` explains that `connected:false` is the
normal idle state and the on-device runner auto-connects on the next verb.

Bumps all version surfaces (package.json, cli/version.ts, extension manifests)
to 0.22.1.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds a skills-adoption system to the CLI (discovery, classification, and linking of AI skill packs into runtimes like Claude/Codex), introduces surface detection, argv normalization, a manifest command, an overhauled tiered help system, status renderer integration, installer/release skill-pack staging with dark-mode fixes, and version bumps.

Changes

Skills Adoption, Help/Manifest, and CLI Wiring

Layer / File(s) Summary
Surface detection and argv normalization
cli/lib/surfaces.ts, cli/normalize.ts, test/normalize-args.test.ts
Adds detectSurfaces/SURFACE_UPGRADE_HINT for browser/macOS/iOS capability detection and normalizeArgs to reorder argv into [cmd, ...positionals, ...flags].
Skills discovery, classification, and adoption
cli/commands/skills.ts, test/skills-adopt.test.ts
Implements pack discovery, runtime target enumeration, link state classification (linked/stale-copy/foreign/missing), adoptSkill symlink creation/replacement, status summary, and rate-limited hint emission.
Skills command dispatcher
cli/commands/skills.ts
Implements runSkillsCommand supporting list, status, show, and adopt subcommands with --into/--force/--all flags and JSON output.
Manifest command and COMMAND_SPECS
cli/manifest.ts, test/manifest-coverage.test.ts
Adds CommandSpec/FlagSpec types, the COMMAND_SPECS catalog, and runManifestCommand that outputs a JSON capability manifest including surfaces and skills status.
Tiered help overhaul
cli/help.ts, test/cli-meta-additions.test.ts
Adds shortHelp/SHORT_HELP tier-0 capability map, fullHelp surface-filtered Tier-2 help, manifest-derived Returns/Example text, and new skills/manifest/group close help entries.
CLI dispatch wiring
cli/index.ts
Wires skills/manifest commands into known-command sets, applies normalizeArgs, adds surface fail-fast checks, hint emission, and dispatch to the new handlers.
Status renderer integration
cli/lib/status-renderer.ts
Extends StatusSnapshot with skills, populates it via skillsStatusSummary, and renders/serializes per-target link status.
iOS device and help text
daemon/ios/manager.ts, cli/commands/ios.ts, .agents/skills/interceptor-ios/SKILL.md
Adds idle/auto-connect notes to devices(), expands the "Connection model" help section, and rewords runner signature renewal wording.

Estimated code review effort: 4 (Complex) | ~60 minutes

Installer, Release Scripts, and Version Bumps

Layer / File(s) Summary
Installer conclusion dark-mode styling
scripts/release/Resources/conclusion-browser.html, scripts/release/Resources/conclusion-full.html
Adds color-scheme/@media (prefers-color-scheme: dark) overrides for body/heading/code/path colors and rewrites skill-pack instructions to use interceptor skills adopt/status.
Windows installer and release staging
scripts/installer/interceptor.iss, scripts/installer/post-install.txt, scripts/release.sh, scripts/release/postinstall-browser, scripts/release/postinstall-full
Adds a linkskills installer task copying skill packs and running skills adopt, stages interceptor-ios into full daemon payload, and writes .skills-refresh marker files during postinstall.
Version bumps
cli/version.ts, package.json, extension/manifest.json, extension/dist-mv2/manifest.json
Bumps versions to 0.22.1.

Estimated code review effort: 2 (Simple) | ~15 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI as interceptor CLI
  participant Skills as runSkillsCommand
  participant FS as Filesystem
  participant Target as Runtime Target Dir

  CLI->>Skills: skills adopt --into claude
  Skills->>FS: resolvePackDir()
  Skills->>FS: discoverSkills(packDir)
  Skills->>Target: classifyLink(targetDir, skill, srcDir)
  Target-->>Skills: linked/foreign/stale-copy/missing
  Skills->>Target: adoptSkill(target, skill, force)
  Target-->>Skills: linked/already-linked/replaced-copy/error
  Skills-->>CLI: AdoptResult[] printed
Loading
sequenceDiagram
  participant User
  participant CLIIndex as cli/index.ts
  participant Surfaces as detectSurfaces
  participant Help as cli/help.ts

  User->>CLIIndex: interceptor --help
  CLIIndex->>Surfaces: detectSurfaces(args)
  Surfaces-->>CLIIndex: { browser, macos, ios }
  CLIIndex->>Help: shortHelp(surfaces)
  Help-->>CLIIndex: tier-0 capability map
  CLIIndex-->>User: printed help text
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR includes many unrelated CLI, skills, manifest, and version-bump changes beyond issue #123’s installer Summary pane fix. Split the CLI/skills/version work into separate PRs and keep this change focused on the installer Summary pane dark-mode fix.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and matches the release-wide CLI overhaul and skills adoption work.
Linked Issues check ✅ Passed The installer conclusion HTML changes address #123’s dark-mode contrast and heading clipping requirements.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch release/0.22.1

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ronaldeddings ronaldeddings merged commit 4a9cf8e into main Jul 3, 2026
1 of 2 checks passed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (5)
scripts/release/postinstall-full (1)

159-168: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Identical marker-writing block duplicated between postinstall-browser and postinstall-full.

Both scripts implement the same skills-refresh marker logic verbatim. Consider extracting a shared helper (e.g., a sourced common script) to avoid drift if the marker format changes later.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/release/postinstall-full` around lines 159 - 168, The skills-refresh
marker-writing logic is duplicated in both postinstall scripts, so changes can
drift over time. Extract the shared marker creation flow from the duplicated
block in the postinstall script into a common helper that both paths source, and
keep the existing behavior of writing .skills-refresh and never failing install.
Use the duplicated marker block and the skills-refresh logic as the reference
point when refactoring.
cli/lib/surfaces.ts (2)

26-34: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

No dedicated unit tests for detectSurfaces.

Unlike normalizeArgs (fully covered in test/normalize-args.test.ts), this branching logic (override via argv/env, darwin-only checks, three existsSync paths) has no visible test coverage in this batch. Given it gates which commands/help text are exposed, a small test suite (override precedence, darwin vs non-darwin, each existsSync path) would be cheap insurance.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/lib/surfaces.ts` around lines 26 - 34, Add dedicated unit tests for
detectSurfaces to cover all branching paths: the --all-surfaces argv override,
the INTERCEPTOR_ALL_SURFACES env override, the darwin-only platform check, and
each existsSync path used by the full flag. Put the tests near the existing
normalizeArgs coverage so detectSurfaces is exercised with mocked
process.platform, launchAgentUser, and existsSync, and verify browser/macos/ios
are returned correctly for each case.

20-24: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consolidate duplicated LaunchAgent/bridge-socket path constants.

LAUNCH_AGENT_SYSTEM / launchAgentUser() and the /tmp/interceptor-bridge.sock literal here duplicate the same constants independently defined in cli/lib/status-renderer.ts (LAUNCH_AGENT_PATH_SYSTEM, LAUNCH_AGENT_PATH_USER, BRIDGE_SOCK_PATH). If either file's paths drift, surface detection (which gates macOS/iOS command visibility) and interceptor status reporting could silently disagree.

Extract these into a shared constants module imported by both files.

Also applies to: 30-33

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/lib/surfaces.ts` around lines 20 - 24, The LaunchAgent and bridge socket
paths are duplicated between surfaces handling and status rendering, so the
values can drift and make command visibility and status output disagree. Move
the shared path values out of LAUNCH_AGENT_SYSTEM, launchAgentUser(), and the
bridge socket literal into a common constants module, then import those shared
constants from both this file and status-renderer.ts so all path checks use one
source of truth.
cli/commands/skills.ts (1)

249-256: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Redundant discoverSkills(packDir) call.

skills is already computed at line 249; line 254 recomputes it via a second call instead of reusing the variable, re-reading every skill directory and its SKILL.md unnecessarily.

♻️ Proposed fix
     if (jsonMode) {
-      console.log(JSON.stringify({ packDir, skills: discoverSkills(packDir), targets: summary.targets }, null, 2))
+      console.log(JSON.stringify({ packDir, skills, targets: summary.targets }, null, 2))
       return null
     }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/commands/skills.ts` around lines 249 - 256, The list/json path in
skills.ts is recalculating discoverSkills(packDir) even though skills is already
available, causing unnecessary re-reading of skill directories and SKILL.md
files. Update the sub === "list" JSON branch in the skills command to reuse the
existing skills variable instead of calling discoverSkills(packDir) again,
keeping the same data flow through skillsStatusSummary() and the list output.
cli/help.ts (1)

640-649: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicate literal instead of reusing SURFACE_UPGRADE_HINT.

The pushed string in fullHelp is identical to SURFACE_UPGRADE_HINT (exported by cli/lib/surfaces.ts, already imported and used for the same message in cli/index.ts). Reuse the constant to avoid the two copies drifting apart.

♻️ Proposed fix
+import { SURFACE_UPGRADE_HINT } from "./lib/surfaces"
...
   if (!surfaces.macos || !surfaces.ios) {
-    parts.push("macos/ios: not available in this install — 'interceptor upgrade --full' adds computer-use mode (macOS only).")
+    parts.push(SURFACE_UPGRADE_HINT)
   }

(Skip the import if cli/help.ts already imports from ./lib/surfaces elsewhere.)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/help.ts` around lines 640 - 649, The fullHelp function is duplicating the
surface upgrade message instead of reusing the shared SURFACE_UPGRADE_HINT
constant. Update fullHelp in cli/help.ts to reference the existing exported
constant from cli/lib/surfaces, matching the usage already in cli/index.ts, and
remove the hardcoded literal so the message stays consistent in one place. If
cli/help.ts already imports from ./lib/surfaces, reuse that import rather than
adding another.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.agents/skills/interceptor-ios/SKILL.md:
- Line 37: The renewal sentence in the interceptor iOS setup section is too
narrow and implies only free-tier certificates are renewed; update the wording
in the setup description to state that the background timer renews any expiring
runner install/signing, including paid Apple accounts as well as free-tier
certificates. Keep the instruction attached to the setup/login guidance so
readers understand the behavior regardless of account type.

In `@cli/manifest.ts`:
- Around line 187-188: The fallback `skills` object in `manifest.ts` has a
different shape than the normal no-pack result from `skillsStatusSummary()`, so
make the catch-path return the same schema as that function’s "no pack dir"
branch. Update the `skills` initialization/try-catch around
`skillsStatusSummary()` so consumers of `interceptor manifest` always receive
`packDir`, `skills`, and `targets` keys, even when `skillsStatusSummary()`
throws.
- Around line 168-172: Update the manifest command documentation so the
`returns` string in the `manifest` spec matches `runManifestCommand`’s actual
payload: include `sha` at the top level and add the missing `surface` and
`example` fields to the `commands[]` object shape. Keep the wording aligned with
the emitted object from `runManifestCommand` in `cli/manifest.ts`, and make sure
the `manifest` entry’s doc accurately reflects the full JSON structure.
- Line 149: The browser command spec is mislabeled: the passive network-log
entry in manifest.ts uses name "network" even though its usage, summary, and
help text all refer to "net", so helpForCommand() cannot match it for net.
Update the spec in the manifest entry to use the same identifier as the command
documented in cli/help.ts (the passive network command), and keep the
usage/summary/returns aligned so net --help and help net can inject the correct
Returns/Example content.

In `@scripts/installer/interceptor.iss`:
- Around line 51-65: Update the installer comments and post-install messaging to
match the actual staged skill packs in interceptor.iss: the current “router +
browser skills” note and the post-install text only describe two packs, but the
[Files] section and skills adopt logic include interceptor-research as well.
Align the documentation/comments with the real behavior, or remove the extra
staged pack if it should not ship; check the linkskills entry, the [Files]
skill-pack sources, and the post-install text so they all describe the same set
of installed/linked skills.
- Line 50: The installer entry for the `addtopath` task is currently selected by
default, which makes `linkskills` run automatically on fresh installs; update
the Inno Setup item definition in `interceptor.iss` so this option is opt-in by
adding `unchecked`, and keep the `Name`, `Description`, and `GroupDescription`
entries aligned with the `linkskills`/skills adoption behavior.

---

Nitpick comments:
In `@cli/commands/skills.ts`:
- Around line 249-256: The list/json path in skills.ts is recalculating
discoverSkills(packDir) even though skills is already available, causing
unnecessary re-reading of skill directories and SKILL.md files. Update the sub
=== "list" JSON branch in the skills command to reuse the existing skills
variable instead of calling discoverSkills(packDir) again, keeping the same data
flow through skillsStatusSummary() and the list output.

In `@cli/help.ts`:
- Around line 640-649: The fullHelp function is duplicating the surface upgrade
message instead of reusing the shared SURFACE_UPGRADE_HINT constant. Update
fullHelp in cli/help.ts to reference the existing exported constant from
cli/lib/surfaces, matching the usage already in cli/index.ts, and remove the
hardcoded literal so the message stays consistent in one place. If cli/help.ts
already imports from ./lib/surfaces, reuse that import rather than adding
another.

In `@cli/lib/surfaces.ts`:
- Around line 26-34: Add dedicated unit tests for detectSurfaces to cover all
branching paths: the --all-surfaces argv override, the INTERCEPTOR_ALL_SURFACES
env override, the darwin-only platform check, and each existsSync path used by
the full flag. Put the tests near the existing normalizeArgs coverage so
detectSurfaces is exercised with mocked process.platform, launchAgentUser, and
existsSync, and verify browser/macos/ios are returned correctly for each case.
- Around line 20-24: The LaunchAgent and bridge socket paths are duplicated
between surfaces handling and status rendering, so the values can drift and make
command visibility and status output disagree. Move the shared path values out
of LAUNCH_AGENT_SYSTEM, launchAgentUser(), and the bridge socket literal into a
common constants module, then import those shared constants from both this file
and status-renderer.ts so all path checks use one source of truth.

In `@scripts/release/postinstall-full`:
- Around line 159-168: The skills-refresh marker-writing logic is duplicated in
both postinstall scripts, so changes can drift over time. Extract the shared
marker creation flow from the duplicated block in the postinstall script into a
common helper that both paths source, and keep the existing behavior of writing
.skills-refresh and never failing install. Use the duplicated marker block and
the skills-refresh logic as the reference point when refactoring.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9fd8fcb3-e048-4dd8-a378-ed8dbbc2ee45

📥 Commits

Reviewing files that changed from the base of the PR and between 5705548 and c2fa703.

📒 Files selected for processing (25)
  • .agents/skills/interceptor-ios/SKILL.md
  • cli/commands/ios.ts
  • cli/commands/skills.ts
  • cli/help.ts
  • cli/index.ts
  • cli/lib/status-renderer.ts
  • cli/lib/surfaces.ts
  • cli/manifest.ts
  • cli/normalize.ts
  • cli/version.ts
  • daemon/ios/manager.ts
  • extension/dist-mv2/manifest.json
  • extension/manifest.json
  • package.json
  • scripts/installer/interceptor.iss
  • scripts/installer/post-install.txt
  • scripts/release.sh
  • scripts/release/Resources/conclusion-browser.html
  • scripts/release/Resources/conclusion-full.html
  • scripts/release/postinstall-browser
  • scripts/release/postinstall-full
  • test/cli-meta-additions.test.ts
  • test/manifest-coverage.test.ts
  • test/normalize-args.test.ts
  • test/skills-adopt.test.ts

- **Unlocked + foreground matters.** A locked phone refuses app launches. If launches stall, the phone is likely locked — unlock it. The runner drops on idle and re-dials per verb, so between calls the phone may return to the Home screen; chain a launch and its follow-up verbs closely.
- **UI only.** Interceptor drives the touchscreen and buttons. It cannot pass Face ID / passcode / Apple Pay or unlock the phone.
- **Setup is one-time.** `interceptor ios setup` (Xcode signed in) or `interceptor ios login` (no-Xcode, the user's own Apple ID) installs + signs the runner. A background timer re-signs before the free-tier certificate expires.
- **Setup is one-time.** `interceptor ios setup` (Xcode signed in) or `interceptor ios login` (no-Xcode, the user's own Apple ID) installs + signs the runner. A background timer renews the runner signature before the free-tier certificate expires.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Widen the renewal wording.

This timer renews any expiring install, not just free-tier certificates, so the current sentence can mislead operators into thinking paid Apple accounts are exempt.

♻️ Suggested tweak
- A background timer renews the runner signature before the free-tier certificate expires.
+ A background timer renews the runner signature before the installed certificate expires.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- **Setup is one-time.** `interceptor ios setup` (Xcode signed in) or `interceptor ios login` (no-Xcode, the user's own Apple ID) installs + signs the runner. A background timer renews the runner signature before the free-tier certificate expires.
- **Setup is one-time.** `interceptor ios setup` (Xcode signed in) or `interceptor ios login` (no-Xcode, the user's own Apple ID) installs + signs the runner. A background timer renews the runner signature before the installed certificate expires.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.agents/skills/interceptor-ios/SKILL.md at line 37, The renewal sentence in
the interceptor iOS setup section is too narrow and implies only free-tier
certificates are renewed; update the wording in the setup description to state
that the background timer renews any expiring runner install/signing, including
paid Apple accounts as well as free-tier certificates. Keep the instruction
attached to the setup/login guidance so readers understand the behavior
regardless of account type.

Comment thread cli/manifest.ts
// ── tabs / network / capture / data ─────────────────────────────────────────
{ name: "tabs", surface: "browser", usage: "interceptor tabs", summary: "List managed tabs", returns: "Tab list (id, url, title)." },
{ name: "tab", surface: "browser", usage: "interceptor tab new|close|activate|reload […]", summary: "Tab lifecycle", returns: "ok / tab info." },
{ name: "network", surface: "browser", usage: "interceptor net [--filter <pattern>] [--limit <n>] [--format har|json|pcapng --out <path>]", summary: "Passive network log", returns: "Recent requests (method, url, status, type); exportable to HAR/pcapng." },

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

"network" spec name doesn't match its own usage/summary — likely should be "net".

name: "network" but usage, summary, and returns all describe the passive network-log command documented elsewhere as interceptor net ... (see cli/help.ts MAP_BROWSER: net (passive log → HAR/pcapng), and HELP_BROWSER's Passive Network section). Since helpForCommand() looks up specs by s.name === cmd, this mismatch means interceptor net --help / interceptor help net never picks up this spec's Returns:/Example: injection — defeating the point of this feature for a real, commonly used command.

🐛 Proposed fix
-  { name: "network", surface: "browser", usage: "interceptor net [--filter <pattern>] [--limit <n>] [--format har|json|pcapng --out <path>]", summary: "Passive network log", returns: "Recent requests (method, url, status, type); exportable to HAR/pcapng." },
+  { name: "net", surface: "browser", usage: "interceptor net [--filter <pattern>] [--limit <n>] [--format har|json|pcapng --out <path>]", summary: "Passive network log", returns: "Recent requests (method, url, status, type); exportable to HAR/pcapng." },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{ name: "network", surface: "browser", usage: "interceptor net [--filter <pattern>] [--limit <n>] [--format har|json|pcapng --out <path>]", summary: "Passive network log", returns: "Recent requests (method, url, status, type); exportable to HAR/pcapng." },
{ name: "net", surface: "browser", usage: "interceptor net [--filter <pattern>] [--limit <n>] [--format har|json|pcapng --out <path>]", summary: "Passive network log", returns: "Recent requests (method, url, status, type); exportable to HAR/pcapng." },
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/manifest.ts` at line 149, The browser command spec is mislabeled: the
passive network-log entry in manifest.ts uses name "network" even though its
usage, summary, and help text all refer to "net", so helpForCommand() cannot
match it for net. Update the spec in the manifest entry to use the same
identifier as the command documented in cli/help.ts (the passive network
command), and keep the usage/summary/returns aligned so net --help and help net
can inject the correct Returns/Example content.

Comment thread cli/manifest.ts
Comment on lines +168 to +172
name: "manifest", surface: "local",
usage: "interceptor manifest",
summary: "This machine-readable capability manifest",
returns: "JSON: {name, version, surfaces, commands[{name,usage,summary,returns,flags}], skills}.",
},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

"manifest" command's own returns doc is out of sync with the actual output shape.

runManifestCommand (Line 189-196) emits {name, version, sha, surfaces, commands, skills}, but the spec's returns string omits sha, and the commands[] sub-shape omits surface/example which are present on every emitted command object.

📝 Proposed fix
-    returns: "JSON: {name, version, surfaces, commands[{name,usage,summary,returns,flags}], skills}.",
+    returns: "JSON: {name, version, sha, surfaces, commands[{name,surface,usage,summary,returns,flags,example}], skills}.",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
name: "manifest", surface: "local",
usage: "interceptor manifest",
summary: "This machine-readable capability manifest",
returns: "JSON: {name, version, surfaces, commands[{name,usage,summary,returns,flags}], skills}.",
},
name: "manifest", surface: "local",
usage: "interceptor manifest",
summary: "This machine-readable capability manifest",
returns: "JSON: {name, version, sha, surfaces, commands[{name,surface,usage,summary,returns,flags,example}], skills}.",
},
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/manifest.ts` around lines 168 - 172, Update the manifest command
documentation so the `returns` string in the `manifest` spec matches
`runManifestCommand`’s actual payload: include `sha` at the top level and add
the missing `surface` and `example` fields to the `commands[]` object shape.
Keep the wording aligned with the emitted object from `runManifestCommand` in
`cli/manifest.ts`, and make sure the `manifest` entry’s doc accurately reflects
the full JSON structure.

Comment thread cli/manifest.ts
Comment on lines +187 to +188
let skills: ReturnType<typeof skillsStatusSummary> | { packDir: null } = { packDir: null }
try { skills = skillsStatusSummary() } catch {}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Fallback skills value has an inconsistent shape vs. skillsStatusSummary()'s own "no pack" result.

When skillsStatusSummary() throws unexpectedly, skills stays { packDir: null }, but the function's own "no pack dir" path returns { packDir: null, skills: [], targets: [] }. Consumers of interceptor manifest JSON get a schema-inconsistent skills field depending on which failure path was hit.

🔧 Proposed fix
-  let skills: ReturnType<typeof skillsStatusSummary> | { packDir: null } = { packDir: null }
+  let skills: ReturnType<typeof skillsStatusSummary> = { packDir: null, skills: [], targets: [] }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let skills: ReturnType<typeof skillsStatusSummary> | { packDir: null } = { packDir: null }
try { skills = skillsStatusSummary() } catch {}
let skills: ReturnType<typeof skillsStatusSummary> = { packDir: null, skills: [], targets: [] }
try { skills = skillsStatusSummary() } catch {}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@cli/manifest.ts` around lines 187 - 188, The fallback `skills` object in
`manifest.ts` has a different shape than the normal no-pack result from
`skillsStatusSummary()`, so make the catch-path return the same schema as that
function’s "no pack dir" branch. Update the `skills` initialization/try-catch
around `skillsStatusSummary()` so consumers of `interceptor manifest` always
receive `packDir`, `skills`, and `targets` keys, even when
`skillsStatusSummary()` throws.

@@ -48,11 +48,25 @@ InfoAfterFile=post-install.txt

[Tasks]
Name: addtopath; Description: "Add Interceptor to your user PATH"; GroupDescription: "Additional integrations:"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Inno Setup Tasks section: are checkboxes checked by default without the unchecked flag?

💡 Result:

Yes, in Inno Setup, tasks defined in the [Tasks] section are checked by default unless the unchecked flag is explicitly included [1]. If the unchecked flag is omitted, the task's checkbox will appear checked when the installer is first run [1]. It is important to note that by default, Inno Setup uses the UsePreviousTasks directive [2][3]. If a previous version of your application is detected, the installer will automatically default to the task settings used in the previous installation, regardless of whether the unchecked flag was specified in the script [1][2][3]. To disable this behavior and enforce the default settings defined in your script (ignoring previous user choices), you can set UsePreviousTasks=no in the [Setup] section [1][3].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail
printf '--- file excerpt ---\n'
cat -n scripts/installer/interceptor.iss | sed -n '1,120p'
printf '\n--- search ---\n'
rg -n "UsePreviousTasks|linkskills|addtopath" scripts/installer/interceptor.iss

Repository: Hacker-Valley-Media/Interceptor

Length of output: 260


🏁 Script executed:

#!/bin/bash
set -euo pipefail
echo '--- file excerpt ---'
cat -n scripts/installer/interceptor.iss | sed -n '1,120p'
echo
echo '--- search ---'
rg -n "UsePreviousTasks|linkskills|addtopath" scripts/installer/interceptor.iss

Repository: Hacker-Valley-Media/Interceptor

Length of output: 7031


Make linkskills opt-in linkskills is checked by default here, so skills adopt --all --into claude runs on a fresh install and mutates ~/.claude/skills unless the user unchecks it. Add unchecked if this should be a manual choice.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/installer/interceptor.iss` at line 50, The installer entry for the
`addtopath` task is currently selected by default, which makes `linkskills` run
automatically on fresh installs; update the Inno Setup item definition in
`interceptor.iss` so this option is opt-in by adding `unchecked`, and keep the
`Name`, `Description`, and `GroupDescription` entries aligned with the
`linkskills`/skills adoption behavior.

Comment on lines +51 to +65
; link the browser-surface skill packs into Claude Code's skills
; directory (%USERPROFILE%\.claude\skills). Junctions — created by
; `interceptor skills adopt` — need neither Developer Mode nor elevation.
; Windows is browser-only, so only the router + browser skills ship here.
Name: linkskills; Description: "Link Interceptor AI skill packs into %USERPROFILE%\.claude\skills (Claude Code)"; GroupDescription: "Additional integrations:"

[Files]
Source: "..\..\dist\interceptor.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "..\..\daemon\interceptor-daemon.exe"; DestDir: "{app}\daemon"; Flags: ignoreversion
Source: "..\..\extension\dist\*"; DestDir: "{app}\extension"; Flags: ignoreversion recursesubdirs createallsubdirs
; Skill packs — resolved by the CLI's skills verb at {app}\skills
Source: "..\..\.agents\skills\interceptor\*"; DestDir: "{app}\skills\interceptor"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "..\..\.agents\skills\interceptor-browser\*"; DestDir: "{app}\skills\interceptor-browser"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "..\..\.agents\skills\interceptor-research\*"; DestDir: "{app}\skills\interceptor-research"; Flags: ignoreversion recursesubdirs createallsubdirs

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Comment/behavior mismatch: "router + browser skills" vs. 3 staged packs.

The task description comment says only router + browser skills ship on Windows, but the [Files] block stages three packs — interceptor, interceptor-browser, and interceptor-research — and skills adopt --all (line 69) will link all three. post-install.txt (lines 21-23) also only mentions two packs being linked, so a user reading either the code comment or the post-install doc will be misled about interceptor-research being installed/linked.

Suggested comment/doc fix
-  ; Windows is browser-only, so only the router + browser skills ship here.
+  ; Windows is browser-only, so the router, browser, and research skills ship here.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
; link the browser-surface skill packs into Claude Code's skills
; directory (%USERPROFILE%\.claude\skills). Junctions — created by
; `interceptor skills adopt` — need neither Developer Mode nor elevation.
; Windows is browser-only, so only the router + browser skills ship here.
Name: linkskills; Description: "Link Interceptor AI skill packs into %USERPROFILE%\.claude\skills (Claude Code)"; GroupDescription: "Additional integrations:"
[Files]
Source: "..\..\dist\interceptor.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "..\..\daemon\interceptor-daemon.exe"; DestDir: "{app}\daemon"; Flags: ignoreversion
Source: "..\..\extension\dist\*"; DestDir: "{app}\extension"; Flags: ignoreversion recursesubdirs createallsubdirs
; Skill packs — resolved by the CLI's skills verb at {app}\skills
Source: "..\..\.agents\skills\interceptor\*"; DestDir: "{app}\skills\interceptor"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "..\..\.agents\skills\interceptor-browser\*"; DestDir: "{app}\skills\interceptor-browser"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "..\..\.agents\skills\interceptor-research\*"; DestDir: "{app}\skills\interceptor-research"; Flags: ignoreversion recursesubdirs createallsubdirs
; link the browser-surface skill packs into Claude Code's skills
; directory (%USERPROFILE%\.claude\skills). Junctions — created by
; `interceptor skills adopt` — need neither Developer Mode nor elevation.
; Windows is browser-only, so the router, browser, and research skills ship here.
Name: linkskills; Description: "Link Interceptor AI skill packs into %USERPROFILE%\.claude\skills (Claude Code)"; GroupDescription: "Additional integrations:"
[Files]
Source: "..\..\dist\interceptor.exe"; DestDir: "{app}"; Flags: ignoreversion
Source: "..\..\daemon\interceptor-daemon.exe"; DestDir: "{app}\daemon"; Flags: ignoreversion
Source: "..\..\extension\dist\*"; DestDir: "{app}\extension"; Flags: ignoreversion recursesubdirs createallsubdirs
; Skill packs — resolved by the CLI's skills verb at {app}\skills
Source: "..\..\.agents\skills\interceptor\*"; DestDir: "{app}\skills\interceptor"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "..\..\.agents\skills\interceptor-browser\*"; DestDir: "{app}\skills\interceptor-browser"; Flags: ignoreversion recursesubdirs createallsubdirs
Source: "..\..\.agents\skills\interceptor-research\*"; DestDir: "{app}\skills\interceptor-research"; Flags: ignoreversion recursesubdirs createallsubdirs
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/installer/interceptor.iss` around lines 51 - 65, Update the installer
comments and post-install messaging to match the actual staged skill packs in
interceptor.iss: the current “router + browser skills” note and the post-install
text only describe two packs, but the [Files] section and skills adopt logic
include interceptor-research as well. Align the documentation/comments with the
real behavior, or remove the extra staged pack if it should not ship; check the
linkskills entry, the [Files] skill-pack sources, and the post-install text so
they all describe the same set of installed/linked skills.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Installer Summary pane unreadable in macOS dark mode (code/path spans + clipped heading)

1 participant