@macintacos/caret 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +16 -9
- package/bin/caret +1 -1
- package/commands/doctor.md +139 -0
- package/commands/plan.md +25 -0
- package/dist/cli.js +1845 -821
- package/opencode/caret.plugin.ts +6 -5
- package/opencode/commands/doctor.md +120 -0
- package/opencode/commands/plan.md +24 -0
- package/package.json +1 -1
- package/ui/dist/assets/{angular-html-CNIx69MF.js → angular-html-BECXXPyr.js} +1 -1
- package/ui/dist/assets/{angular-ts-B6ob15kD.js → angular-ts-CJKAKY9F.js} +1 -1
- package/ui/dist/assets/{apl-BzQg5wKE.js → apl-CCcfDDqZ.js} +1 -1
- package/ui/dist/assets/{astro-DQ6PiTON.js → astro-DKCnAnVR.js} +1 -1
- package/ui/dist/assets/{blade-DdGMUzbN.js → blade-DQ_JdT2N.js} +1 -1
- package/ui/dist/assets/{c-DhrAH2di.js → c-D3TwszVj.js} +1 -1
- package/ui/dist/assets/{chapel-BIJH6n90.js → chapel-C-2sPcCX.js} +1 -1
- package/ui/dist/assets/{cobol-CR-dFJ1T.js → cobol-BPmo_4f_.js} +1 -1
- package/ui/dist/assets/{coffee-DWT27RO5.js → coffee-DMTsNDVt.js} +1 -1
- package/ui/dist/assets/{cpp-CuONTEvg.js → cpp-BJr6_Y8R.js} +1 -1
- package/ui/dist/assets/{crystal-Bvc0l-OM.js → crystal-pIWESUkD.js} +1 -1
- package/ui/dist/assets/{css-BYejQHVV.js → css-DRd9Q4Li.js} +1 -1
- package/ui/dist/assets/{dist-COogZ9jg.js → dist-BFQBMwmz.js} +1 -1
- package/ui/dist/assets/{dist-BgZhLp84.js → dist-BGfsV7n2.js} +1 -1
- package/ui/dist/assets/{dist-Cuerw0_4.js → dist-BJ7SLVNC.js} +1 -1
- package/ui/dist/assets/{dist-D-lJ6tIg.js → dist-BNr0c85A.js} +1 -1
- package/ui/dist/assets/{dist-C-FIXuZc.js → dist-C6t67BjE.js} +1 -1
- package/ui/dist/assets/{dist-Bn_ExXCc.js → dist-CD25BkNS.js} +1 -1
- package/ui/dist/assets/{dist-BbAsmjOe.js → dist-CU5aMlNo.js} +1 -1
- package/ui/dist/assets/{dist-CCPLuvXB.js → dist-DoJTqy3z.js} +1 -1
- package/ui/dist/assets/{dist-RKZBj-sl.js → dist-RKKeH1zs.js} +1 -1
- package/ui/dist/assets/{dist-DV7t-p4N.js → dist-aKlRxpD_.js} +1 -1
- package/ui/dist/assets/{edge-B_-8Eolr.js → edge-DeNk4F2G.js} +1 -1
- package/ui/dist/assets/{elixir-CAhwbI74.js → elixir-DHc-DOO8.js} +1 -1
- package/ui/dist/assets/{elm-yg-VSwEl.js → elm-CJRqEcvz.js} +1 -1
- package/ui/dist/assets/{erb-CIMOpWGO.js → erb-BEWGTHDA.js} +1 -1
- package/ui/dist/assets/{git-rebase-DI22snkc.js → git-rebase-DzlcWhg9.js} +1 -1
- package/ui/dist/assets/{glimmer-js-CZHZNAs-.js → glimmer-js-B-aWCRIZ.js} +1 -1
- package/ui/dist/assets/{glimmer-ts-C2rq-JGq.js → glimmer-ts-DcjmPyQn.js} +1 -1
- package/ui/dist/assets/{glsl-ByXN6hIN.js → glsl-C9FOT-Uv.js} +1 -1
- package/ui/dist/assets/{graphql-DiiJwLqR.js → graphql-BgKSoRp0.js} +1 -1
- package/ui/dist/assets/{hack-hQSSm1D1.js → hack-BOedpUUE.js} +1 -1
- package/ui/dist/assets/{haml-cf9hcOgw.js → haml-Cpngw1vd.js} +1 -1
- package/ui/dist/assets/{handlebars-B3tg892p.js → handlebars-CpW1IyBg.js} +1 -1
- package/ui/dist/assets/{html-CkIr2qlC.js → html-CV142D8s.js} +1 -1
- package/ui/dist/assets/{html-derivative-U1EOyk5J.js → html-derivative-Df7h1Nuw.js} +1 -1
- package/ui/dist/assets/{http-ek0-hDT8.js → http-Cneddv9N.js} +1 -1
- package/ui/dist/assets/{hurl-DbN52Bpk.js → hurl-D6TS55N6.js} +1 -1
- package/ui/dist/assets/{index-uBaTjG1U.js → index-Ci9yCNtV.js} +248 -214
- package/ui/dist/assets/index-t6i4na1R.css +1 -0
- package/ui/dist/assets/{java-DXEu0FGs.js → java-BicD3zQH.js} +1 -1
- package/ui/dist/assets/{javascript-Bi95ibpN.js → javascript-l6vKHWBV.js} +1 -1
- package/ui/dist/assets/{jinja-BcKnkqjY.js → jinja-BJF2iot2.js} +1 -1
- package/ui/dist/assets/{jison-CFaHQ730.js → jison-DiXPFJAT.js} +1 -1
- package/ui/dist/assets/{json--ulVurkL.js → json-BDRuI4UV.js} +1 -1
- package/ui/dist/assets/{jsx-ZonywBBD.js → jsx-BvfdkIOy.js} +1 -1
- package/ui/dist/assets/{julia-Bnt3bGqT.js → julia-bXAhreI5.js} +1 -1
- package/ui/dist/assets/{just-CBpil8Tz.js → just-BOxCfXDg.js} +1 -1
- package/ui/dist/assets/{latex-D-qwKUqq.js → latex-B9OiTBLF.js} +1 -1
- package/ui/dist/assets/{liquid-Bu8cI_b1.js → liquid-DuLKDeWE.js} +1 -1
- package/ui/dist/assets/{lua-DO_5Mymc.js → lua-Dbh9FQm_.js} +1 -1
- package/ui/dist/assets/{marko-DJfs6dcc.js → marko--tjEBgDM.js} +1 -1
- package/ui/dist/assets/{mdc-CnkU1WJT.js → mdc-ByNJpl3m.js} +1 -1
- package/ui/dist/assets/{nginx-B5LxXEA3.js → nginx-D4wsmFK9.js} +1 -1
- package/ui/dist/assets/{nim-DLTorTuD.js → nim-Cy8RxisP.js} +1 -1
- package/ui/dist/assets/{org-DnNvsXCU.js → org-CAm7o61d.js} +1 -1
- package/ui/dist/assets/{perl-Q5Q2rA31.js → perl-BAvaFGKe.js} +1 -1
- package/ui/dist/assets/{php-S65hjGBt.js → php-DpAf3w7u.js} +1 -1
- package/ui/dist/assets/{pug-k-MB8PEo.js → pug-Dm7otyJU.js} +1 -1
- package/ui/dist/assets/{qml-Bf9cLRPv.js → qml-D4rWQQKC.js} +1 -1
- package/ui/dist/assets/{r-Cr3hDQkZ.js → r-DMKUX8qf.js} +1 -1
- package/ui/dist/assets/{razor-BO5-wpmp.js → razor-BIUJkuf_.js} +1 -1
- package/ui/dist/assets/{regexp-ffQ9gsih.js → regexp-D8W_pVHj.js} +1 -1
- package/ui/dist/assets/{rst-B4AQC5xj.js → rst-aFr0DP5H.js} +1 -1
- package/ui/dist/assets/{ruby-Dr8kfvLX.js → ruby-BzH6kUKr.js} +1 -1
- package/ui/dist/assets/{sas-Kuo2pLeL.js → sas-CDk9DyCV.js} +1 -1
- package/ui/dist/assets/{scss-Ci63BQ8y.js → scss-DABbvU5W.js} +1 -1
- package/ui/dist/assets/{shellscript-DBh4gnVx.js → shellscript-B0ObP3K-.js} +1 -1
- package/ui/dist/assets/{shellsession-L5KFvHI3.js → shellsession-2sv3Jq0j.js} +1 -1
- package/ui/dist/assets/{soy-D6F5ilyd.js → soy-irSRV4oq.js} +1 -1
- package/ui/dist/assets/{sql-xwRblxjL.js → sql-DJCHoKvP.js} +1 -1
- package/ui/dist/assets/{stata-l8sBIGPT.js → stata-a8YnzbIc.js} +1 -1
- package/ui/dist/assets/{surrealql-DL2sOSzB.js → surrealql-DdXPOg8s.js} +1 -1
- package/ui/dist/assets/{svelte-Dp5d2Ja3.js → svelte-ClAKUEZR.js} +1 -1
- package/ui/dist/assets/{templ-B3LfgeSM.js → templ-NUCvvUBA.js} +1 -1
- package/ui/dist/assets/{tex-CfLQjgEV.js → tex-DwZeSAfC.js} +1 -1
- package/ui/dist/assets/{ts-tags-BCfi6Eh_.js → ts-tags-CFJEHYY_.js} +1 -1
- package/ui/dist/assets/{tsx-BXhT7ita.js → tsx-B934yX2T.js} +1 -1
- package/ui/dist/assets/{twig-t6tdMpRg.js → twig-NFkkOj3w.js} +1 -1
- package/ui/dist/assets/{typescript-CFIlDlxn.js → typescript-7bmMC_xU.js} +1 -1
- package/ui/dist/assets/{typst-CVQ9ief2.js → typst-BQEjp9tn.js} +1 -1
- package/ui/dist/assets/{vue-D92U7PL6.js → vue-JqD9ieOF.js} +1 -1
- package/ui/dist/assets/{vue-html-B_-4d7cG.js → vue-html-CT4XQRX1.js} +1 -1
- package/ui/dist/assets/{vue-vine-LaG8znAe.js → vue-vine-DIR27Dmn.js} +1 -1
- package/ui/dist/assets/{xml-DgAE0jfV.js → xml-DhsMbw-1.js} +1 -1
- package/ui/dist/assets/{xsl-DkD8aIzS.js → xsl-BvqsVUg9.js} +1 -1
- package/ui/dist/assets/{yaml-CEG92fN8.js → yaml-C8eWjK_Q.js} +1 -1
- package/ui/dist/index.html +2 -2
- package/commands/debug.md +0 -138
- package/commands/discovery.md +0 -35
- package/opencode/commands/debug.md +0 -59
- package/opencode/commands/discovery.md +0 -31
- package/ui/dist/assets/index-CAl4rX7_.css +0 -1
package/README.md
CHANGED
|
@@ -35,6 +35,8 @@ After installing:
|
|
|
35
35
|
1. **Restart the agent.** OpenCode installs the plugin package on its next start.
|
|
36
36
|
2. **Run `/caret:demo`.** It presents a short demo plan that points at files in the repo
|
|
37
37
|
you run it from, so you can exercise the whole flow before a real one arrives.
|
|
38
|
+
3. **Run `/caret:plan <what you want done>`** to plan a real change and review it in
|
|
39
|
+
`caret` before the agent implements it.
|
|
38
40
|
|
|
39
41
|
### Running `caret` yourself
|
|
40
42
|
|
|
@@ -59,7 +61,8 @@ bunx --no-cache @macintacos/caret@latest install --uninstall # remove
|
|
|
59
61
|
```
|
|
60
62
|
|
|
61
63
|
`caret`'s UI is designed to check for updates, at most once a day. When a newer `caret` is
|
|
62
|
-
out, the review UI says so once: a toast on load
|
|
64
|
+
out, the review UI says so once: a toast on load that opens **What's new** (the skipped
|
|
65
|
+
release notes or trunk commits), a mark on the settings button, and a
|
|
63
66
|
**Settings → Updates** pane naming the version and the exact command to take it.
|
|
64
67
|
|
|
65
68
|
Turn the check off from that same pane, or by hand in
|
|
@@ -87,10 +90,12 @@ your browser instead of the terminal prompt. There you:
|
|
|
87
90
|
and re-present.
|
|
88
91
|
|
|
89
92
|
> [!TIP]
|
|
90
|
-
> You don't have to wait to be intercepted:
|
|
91
|
-
>
|
|
92
|
-
> `
|
|
93
|
-
> same
|
|
93
|
+
> You don't have to wait to be intercepted: `/caret:plan <what you want done>` asks the
|
|
94
|
+
> agent for a plan and routes it straight to the review UI. In OpenCode it runs on the
|
|
95
|
+
> `plan` agent, so switch to `build` to implement once you approve. A skill of your own
|
|
96
|
+
> can do the same with the plan-review tool `caret` gives both agents — `review_plan` in
|
|
97
|
+
> Claude Code (from the plugin's MCP server) and `caret_review_plan` in OpenCode. The tool
|
|
98
|
+
> is for plans only; see
|
|
94
99
|
> [`doc/ARCHITECTURE.md`](doc/ARCHITECTURE.md#calling-the-review-tool-from-your-own-skill).
|
|
95
100
|
|
|
96
101
|
## Configuration
|
|
@@ -114,10 +119,12 @@ Two more live at the repo root:
|
|
|
114
119
|
|
|
115
120
|
## Diagnostics
|
|
116
121
|
|
|
117
|
-
- `/caret:
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
122
|
+
- `/caret:doctor` runs `caret doctor`: a one-shot, read-only check of your install —
|
|
123
|
+
what's wrong, how to fix it, and the state it read that from. Always redacted, and it
|
|
124
|
+
never contains plan, prompt, or feedback bodies, nor any log message, error or stack
|
|
125
|
+
text.
|
|
126
|
+
- `caret doctor --bundle` archives the raw logs and review records when a maintainer needs
|
|
127
|
+
them. That archive is **not** redacted, so caret asks before writing it.
|
|
121
128
|
|
|
122
129
|
## License
|
|
123
130
|
|
package/bin/caret
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
#
|
|
3
3
|
# caret plugin entrypoint shim (EXC-643). This is the ONE file Claude Code's
|
|
4
4
|
# hooks invoke — `${CLAUDE_PLUGIN_ROOT}/bin/caret <subcommand>` (see
|
|
5
|
-
# hooks/hooks.json and commands/
|
|
5
|
+
# hooks/hooks.json and commands/doctor.md). It is committed and shipped in
|
|
6
6
|
# every install; it resolves the actual caret runtime from whatever the install
|
|
7
7
|
# method placed beside it:
|
|
8
8
|
#
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Diagnose this caret install — run caret doctor, relay each failing check's remedy, and present the report ready to share
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
caret's `doctor` subcommand renders a verdict over a one-shot, read-only snapshot of the
|
|
6
|
+
local install: a `checks:` block naming what is wrong and how to fix it, then the state it
|
|
7
|
+
read that from — running caret processes, daemon identity, lock/port state, effective
|
|
8
|
+
settings, review counts, the agent adapter's install-state probe (plugin version, enabled
|
|
9
|
+
state, and whether a manual hook sits in the agent's user settings), log sizes and error
|
|
10
|
+
counts, recent failures grouped by review with their codes, install/runtime info, and
|
|
11
|
+
system basics. The report is **always redacted** (home paths become `~`, usernames in
|
|
12
|
+
foreign home paths are censored) and never contains plan, prompt, or feedback bodies, nor
|
|
13
|
+
any log message, error or stack text — it exists to be shared.
|
|
14
|
+
|
|
15
|
+
## 1. Run it
|
|
16
|
+
|
|
17
|
+
First ask the user (via `AskUserQuestion`) which format they want:
|
|
18
|
+
|
|
19
|
+
- **JSON** — for feeding to tooling.
|
|
20
|
+
- **Human-readable** — for scanning in the conversation.
|
|
21
|
+
|
|
22
|
+
Then run the matching invocation:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
"${CLAUDE_PLUGIN_ROOT}/bin/caret" doctor --json # JSON
|
|
26
|
+
"${CLAUDE_PLUGIN_ROOT}/bin/caret" doctor # human-readable
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The exit code is the verdict: `0` every check passed, `1` at least one failed, `2` no
|
|
30
|
+
report — doctor could not produce one, or a `--bundle` run had no terminal to ask consent
|
|
31
|
+
at and stopped before collecting anything. On `2`, present the exit code and stderr
|
|
32
|
+
instead — and if the binary itself is missing (a source checkout that has never been
|
|
33
|
+
built), say so and point at `mise run build` (or `mise run build --install`).
|
|
34
|
+
|
|
35
|
+
## 2. Relay each failing check
|
|
36
|
+
|
|
37
|
+
A failing check already carries the remedy that closes it; relay it rather than inventing
|
|
38
|
+
one. What each id means:
|
|
39
|
+
|
|
40
|
+
| id | what failed | relay |
|
|
41
|
+
| --- | --- | --- |
|
|
42
|
+
| `daemon-reachable` | a caret service is recorded but the daemon did not answer, or the effective port answers as something other than caret | the check's remedy verbatim, then offer to read any log it names |
|
|
43
|
+
| `daemon-lock` | the lock names a dead pid, or a port caret is not configured to bind | the check's remedy verbatim |
|
|
44
|
+
| `agent-install` | the agent the check names does not have caret enabled | `caret install` |
|
|
45
|
+
| `log-errors` | a live log wrote an NDJSON error record in the last 24h; the detail names which log and when it last erred | step 4 |
|
|
46
|
+
| `opencode-caret-version` | OpenCode would load a caret behind the published one | the check's remedy verbatim |
|
|
47
|
+
|
|
48
|
+
An `unknown` check is not a failure: it names its own `reason` — no network, an unreadable
|
|
49
|
+
config, or a report section that never collected, which also shows as `<name> error: …`
|
|
50
|
+
(`"error": "…"` under `--json`) and leaves the check with no detail. A doctor run offline
|
|
51
|
+
reaching one is the normal case; present it as-is rather than treating it as a failure of
|
|
52
|
+
this command. A daemon that is simply not running is not one of these — it reports
|
|
53
|
+
`reachable false` and *passes*, because an on-demand daemon idle-exits by design.
|
|
54
|
+
|
|
55
|
+
## 3. Present the report
|
|
56
|
+
|
|
57
|
+
End your output with the command's stdout **verbatim** in a fenced code block —
|
|
58
|
+
` ```json ` for the JSON format, plain ` ``` ` for the human-readable one — so the user
|
|
59
|
+
can copy it out in one piece. Add nothing inside the block and do not summarize away
|
|
60
|
+
sections; the report is already redacted and complete.
|
|
61
|
+
|
|
62
|
+
## 4. Debug a failing `log-errors`
|
|
63
|
+
|
|
64
|
+
When `log-errors` failed and the `/systematic-debugging` skill is available, invoke it to
|
|
65
|
+
drive root-cause investigation from the logs the check named. Otherwise read the last
|
|
66
|
+
error records yourself and reason from the failing step, code, msg, cause, and stack.
|
|
67
|
+
|
|
68
|
+
Read the report's `failures` first. Each group is one review's error records from both
|
|
69
|
+
logs with their codes (a session's, when the failure came before a review id existed), so
|
|
70
|
+
a hook-side record sits beside any daemon-side record from that review's own requests. A
|
|
71
|
+
daemon-wide failure (a crash, a bind failure, a failed update check) carries no id and
|
|
72
|
+
lands in `ungrouped`: read it alongside the group and correlate the two by `time`. Pull a
|
|
73
|
+
group's full records from both logs (`.sessionId` for a session group):
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
dir="${XDG_STATE_HOME:-$HOME/.local/state}/caret"
|
|
77
|
+
grep -h '^{' "$dir/logs/caret.log" "$dir/logs/daemon.log" | jq -c 'select(.reviewId == "<id>")'
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
For records outside any group or the report's window, fall back to the last error records
|
|
81
|
+
of each log:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
grep '^{' "$dir/logs/caret.log" | jq -s '[.[] | select(.level >= 50)] | .[-5:]'
|
|
85
|
+
grep '^{' "$dir/logs/daemon.log" | jq -s '[.[] | select(.level >= 50)] | .[-5:]'
|
|
86
|
+
tail -n 40 "$dir/logs/daemon-stderr.log"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`log-errors` counts only NDJSON error records, so a crash that reached `daemon-stderr.log`
|
|
90
|
+
alone leaves it passing — tail that file even when the check is green. It fails only on
|
|
91
|
+
records from the last 24h, so a log that has settled passes while still reporting when it
|
|
92
|
+
last erred; work from that time rather than from the count. If a failure predates the
|
|
93
|
+
current live file, `gunzip -c` the segment you need from `logs/archive/` and rerun the
|
|
94
|
+
recipe against the result.
|
|
95
|
+
|
|
96
|
+
## 5. Review this session's plans
|
|
97
|
+
|
|
98
|
+
The report counts reviews in aggregate; it does not say what happened in *this* session.
|
|
99
|
+
When the user wants that timeline, reconstruct it from the records — identify the session
|
|
100
|
+
by the most recently updated review whose `cwd` matches, then list every review in it,
|
|
101
|
+
oldest first:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
dir="${XDG_STATE_HOME:-$HOME/.local/state}/caret"
|
|
105
|
+
sid=$(jq -rs --arg cwd "$PWD" '[.[] | select(.cwd == $cwd)] | sort_by(.updatedAt) | last | .sessionId // empty' "$dir"/reviews/*.json)
|
|
106
|
+
jq -s --arg sid "$sid" '[.[] | select(.sessionId == $sid)] | sort_by(.createdAt) | .[] | {id, title, status, versions: (.versions | length), decidedAt: .decision.decidedAt, feedback: .decision.feedback}' "$dir"/reviews/*.json
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
That field whitelist is deliberate: `versions[].plan` and `generalCommentDraft` hold full
|
|
110
|
+
plan and draft bodies — never select or echo them.
|
|
111
|
+
|
|
112
|
+
If `sid` comes back empty, no review matches the working directory. Say so, then fall back
|
|
113
|
+
to the most recently updated session across all reviews and re-run the listing with it:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
sid=$(jq -rs 'sort_by(.updatedAt) | last | .sessionId // empty' "$dir"/reviews/*.json)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
If `$dir/reviews` is missing or empty the glob won't match and these commands error (shell
|
|
120
|
+
or jq, depending on the shell) — that is "no reviews recorded", not a failure.
|
|
121
|
+
|
|
122
|
+
Present the result grouped by status, each review with its id, title, and version count
|
|
123
|
+
(the number of plan revisions):
|
|
124
|
+
|
|
125
|
+
- **pending** — awaiting a decision in the browser.
|
|
126
|
+
- **rejected** — changes requested; awaiting a revised plan. Include a short excerpt of
|
|
127
|
+
the decision `feedback`.
|
|
128
|
+
- **approved** — plan accepted; terminal success.
|
|
129
|
+
- **expired** — abandoned by its hook (timeout) or superseded by a resubmitted plan;
|
|
130
|
+
terminal, never reviewed.
|
|
131
|
+
|
|
132
|
+
## 6. Sharing the raw logs
|
|
133
|
+
|
|
134
|
+
If the report is not enough and the user wants to hand the raw material to a maintainer,
|
|
135
|
+
`caret doctor --bundle` writes a zip of the live logs and review records to caret's state
|
|
136
|
+
dir. Tell them plainly before suggesting it: that archive is **not** redacted — it holds
|
|
137
|
+
their logs and full plan bodies — so it is written only after they confirm, and it should
|
|
138
|
+
move over a channel they trust. caret asks at a terminal and your run has none, so carry
|
|
139
|
+
their answer with `--yes` — never before they have given it.
|
package/commands/plan.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Plan a change and route the plan through caret's review UI before implementing it
|
|
3
|
+
argument-hint: [what you want done]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Plan this, then implement it once caret approves the plan:
|
|
7
|
+
|
|
8
|
+
$ARGUMENTS
|
|
9
|
+
|
|
10
|
+
If that is empty, plan whatever the user asked for earlier in this session.
|
|
11
|
+
|
|
12
|
+
Call `EnterPlanMode` first: `ExitPlanMode` is refused outside plan mode. Research what the
|
|
13
|
+
change needs — read the relevant code, trace the real flow — then write the plan to the
|
|
14
|
+
file your plan-mode instructions name. Call `ExitPlanMode` with that same text as its
|
|
15
|
+
`plan` argument — caret reviews the argument, so a call without it reaches the review UI
|
|
16
|
+
empty.
|
|
17
|
+
|
|
18
|
+
This triggers caret's `PermissionRequest`/`ExitPlanMode` hook, which opens the plan in a
|
|
19
|
+
local browser UI for inline review. When the user approves or requests changes there, the
|
|
20
|
+
decision flows back to you:
|
|
21
|
+
|
|
22
|
+
- **Approved** → implement the plan.
|
|
23
|
+
- **Changes requested** → the feedback arrives as the denial reason. Re-read the plan file
|
|
24
|
+
(caret rewrites it in its canonical shape, so the feedback's line numbers match it),
|
|
25
|
+
revise it, and call `ExitPlanMode` again with the revised text as its `plan` argument.
|