Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
b46db19
chore(shared-copies): ship the medium resolver and one rendered-view …
kyle-sexton Nov 3, 2026
25f2ba1
fix(shared-copies): name the plugin root as a placeholder in the rend…
kyle-sexton Nov 3, 2026
b201dc6
feat(planning): planning views on the view registries with the shippe…
kyle-sexton Nov 3, 2026
4d05ab1
fix(planning): satisfy the markdown, portability and options-docs checks
kyle-sexton Nov 3, 2026
3b3b7d7
feat(rendered-views): register every view lane the per-plugin slices …
kyle-sexton Nov 3, 2026
0c9eb49
Merge remote-tracking branch 'origin/main' into feat/12667-shared-copies
kyle-sexton Nov 3, 2026
524566a
Merge remote-tracking branch 'origin/main' into feat/12667-shared-copies
kyle-sexton Nov 3, 2026
3fc0204
Merge remote-tracking branch 'origin/main' into feat/12650-planning-v…
kyle-sexton Nov 3, 2026
432bcf3
fix(planning): re-sync the publish-gate copy after the main merge
kyle-sexton Nov 3, 2026
e065522
docs(shared-copies): give plugin-root one reading and branch on migra…
kyle-sexton Nov 3, 2026
7899a74
Merge origin/main
kyle-sexton Nov 3, 2026
a74d6f8
Merge main into feat/12667-shared-copies
melodic-automation-lanes[bot] Nov 3, 2026
20e75cd
Merge main into feat/12667-shared-copies after batches A and B
kyle-sexton Nov 3, 2026
7ab0f94
Merge origin/main into feat/12650-planning-view-registry
kyle-sexton Nov 3, 2026
df95277
Merge origin/feat/12667-shared-copies into feat/12650-planning-view-r…
kyle-sexton Nov 3, 2026
ffb2874
chore(planning): add fragments for the plugins that now carry the syn…
kyle-sexton Nov 3, 2026
573bbfb
chore(planning): name only the synced copies in three plugins' fragments
kyle-sexton Nov 3, 2026
e0cf0fd
Merge main into feat/12650-planning-view-registry after S8
kyle-sexton Nov 3, 2026
247b57d
fix(planning): close design-record code fences by the CommonMark rule
kyle-sexton Nov 3, 2026
947270d
docs(planning): report session-written planning views as file
kyle-sexton Nov 3, 2026
4e91e0a
test(planning): pin the planning Artifact exception and the file repo…
kyle-sexton Nov 3, 2026
ebdcbd5
Merge remote-tracking branch 'origin/main' into feat/12650-planning-v…
kyle-sexton Nov 3, 2026
783dee3
test(planning): match the report-line strings as fixed text
kyle-sexton Nov 3, 2026
f4b5a11
docs(lib): keep step 4's failure rule for resolver lanes in rendered-…
kyle-sexton Nov 3, 2026
8284d2e
Merge remote-tracking branch 'origin/main' into feat/12650-planning-v…
kyle-sexton Nov 4, 2026
579a042
fix(planning): read an empty --option as unset and let the design vie…
kyle-sexton Nov 4, 2026
0853698
test(lib): pin the planning lane's artifact default yielding to a ret…
kyle-sexton Nov 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changes/adhd/feat-12650-planning-view-registry-3c8e1a52.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
bump: patch
---

### Changed

- Shared `view-settings.mjs` and `view-registry.mjs` synced where this plugin carries them: the planning lane's design kind and shipped `artifact` default, and the resolver output's `page` and `publishes` fields (#12650); no other change to this plugin.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
bump: patch
---

### Changed

- Shared `view-settings.mjs` and `view-registry.mjs` synced where this plugin carries them: the planning lane's design kind and shipped `artifact` default, and the resolver output's `page` and `publishes` fields (#12650); no other change to this plugin.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
bump: patch
---

### Changed

- Shared `view-builder.mjs`, `view-settings.mjs` and `view-registry.mjs` synced where this plugin carries them: the view-kind registry and `render(laneId, kind, record)`, the planning lane's design kind and shipped `artifact` default, and the resolver output's `page` and `publishes` fields (#12650). The shared `reference/rendered-view.md` copy carries the planning section's one-call build and design view; no other change to this plugin.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
bump: patch
---

### Changed

- Shared `view-settings.mjs` and `view-registry.mjs` synced where this plugin carries them: the planning lane's design kind and shipped `artifact` default, and the resolver output's `page` and `publishes` fields (#12650); no other change to this plugin.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
bump: patch
---

### Changed

- Shared `view-builder.mjs`, `view-settings.mjs` and `view-registry.mjs` synced where this plugin carries them: the view-kind registry and `render(laneId, kind, record)`, the planning lane's design kind and shipped `artifact` default, and the resolver output's `page` and `publishes` fields (#12650). The shared `skills/debug/reference/rendered-view.md` copy carries the planning section's one-call build and design view; no other change to this plugin.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
bump: patch
---

### Changed

- Shared `view-builder.mjs`, `view-settings.mjs` and `view-registry.mjs` synced where this plugin carries them: the view-kind registry and `render(laneId, kind, record)`, the planning lane's design kind and shipped `artifact` default, and the resolver output's `page` and `publishes` fields (#12650). The shared `reference/rendered-view.md` copy carries the planning section's one-call build and design view; no other change to this plugin.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
bump: patch
---

### Changed

- Shared `view-builder.mjs`, `view-settings.mjs` and `view-registry.mjs` synced where this plugin carries them: the view-kind registry and `render(laneId, kind, record)`, the planning lane's design kind and shipped `artifact` default, and the resolver output's `page` and `publishes` fields (#12650); no other change to this plugin.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
bump: patch
---

### Changed

- Shared `view-settings.mjs` and `view-registry.mjs` synced where this plugin carries them: the planning lane's design kind and shipped `artifact` default, and the resolver output's `page` and `publishes` fields (#12650); no other change to this plugin.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
bump: patch
---

### Changed

- Shared `view-builder.mjs`, `view-settings.mjs` and `view-registry.mjs` synced where this plugin carries them: the view-kind registry and `render(laneId, kind, record)`, the planning lane's design kind and shipped `artifact` default, and the resolver output's `page` and `publishes` fields (#12650); no other change to this plugin.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
bump: patch
---

### Changed

- Shared `view-settings.mjs` and `view-registry.mjs` synced where this plugin carries them: the planning lane's design kind and shipped `artifact` default, and the resolver output's `page` and `publishes` fields (#12650); no other change to this plugin.
14 changes: 14 additions & 0 deletions .changes/planning/feat-12650-planning-view-registry-a09f740d.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
bump: minor
---

### Added

- `/planning:design` offers a design view of PLAN.md's `## Design` section after the handoff gate passes, built by `scripts/build-view.mjs design --record <PLAN.md>` from a checked-in template (#12650).
- `scripts/build-view.mjs --option <medium option>` resolves the medium through the shared resolver, runs the publish gate over a publishing medium, builds the page and hands it to the medium's registry entry, then prints the delivery and the `view: <medium> (<what decided it>)` report line. A new medium needs no edit to the planning skills.

### Changed

- The plan, brainstorm and design views ship a private Artifact as their default medium. The publish gate keeps the view a local file for a repository that is not public or a record with anything credential-shaped in it, unless the `medium` option or the request says to publish; set the `medium` option to `file` to keep them local. The PRD and interview views stay local files.
- The plan and brainstorm views render as entries of the shared view-kind registry; their JSON shapes are unchanged.
- The design view reads code fences by the CommonMark rule: a fence closes only on a run of its own character at least as long as the one that opened it, so a shorter fence line or a `##` line inside a longer fence no longer ends the `## Design` section.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
bump: patch
---

### Changed

- Shared `view-settings.mjs` and `view-registry.mjs` synced where this plugin carries them: the planning lane's design kind and shipped `artifact` default, and the resolver output's `page` and `publishes` fields (#12650); no other change to this plugin.
7 changes: 7 additions & 0 deletions .changes/review/feat-12650-planning-view-registry-b1516ec7.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
bump: patch
---

### Changed

- Shared `view-builder.mjs`, `view-settings.mjs` and `view-registry.mjs` synced where this plugin carries them: the view-kind registry and `render(laneId, kind, record)`, the planning lane's design kind and shipped `artifact` default, and the resolver output's `page` and `publishes` fields (#12650); no other change to this plugin.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
bump: patch
---

### Changed

- Shared `view-settings.mjs` and `view-registry.mjs` synced where this plugin carries them: the planning lane's design kind and shipped `artifact` default, and the resolver output's `page` and `publishes` fields (#12650); no other change to this plugin.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
bump: patch
---

### Changed

- Shared `view-settings.mjs` and `view-registry.mjs` synced where this plugin carries them: the planning lane's design kind and shipped `artifact` default, and the resolver output's `page` and `publishes` fields (#12650); no other change to this plugin.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
bump: patch
---

### Changed

- Shared `view-builder.mjs`, `view-settings.mjs` and `view-registry.mjs` synced where this plugin carries them: the view-kind registry and `render(laneId, kind, record)`, the planning lane's design kind and shipped `artifact` default, and the resolver output's `page` and `publishes` fields (#12650); no other change to this plugin.
15 changes: 13 additions & 2 deletions docs/contracts/rendered-views/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -398,8 +398,17 @@ The deck lane (`/visualization:present`) is the second exception: a deck exists
Artifact made from the account's Slides type, so it publishes behind the same gate (see
Artifact types), and anything the gate keeps local stays the markdown outline.

The planning views are the third exception: the brainstorm, design and plan views
(`/planning:brainstorm`, `/planning:design`, `/planning:plan`) ship `medium: artifact` as the
planning lane's default. Each page is built only by the shared builder from a checked-in template
(`plugins/planning/scripts/build-view.mjs`), and it publishes behind the same gate as the digest:
the default publishes only a public repository's record with nothing credential-shaped in it, and
any other record falls back to `file` with the reader told how to publish it anyway. The planning
plugin's PRD and interview views are not part of this exception and stay local files.

Rendered views are untracked by default; publishing anywhere else is optional and
configured, never the default, except for the digest's and the deck's `artifact` default. A
configured, never the default, except for the digest's, the deck's and the planning views'
`artifact` default. A
shared page host is one such configured place: `medium: hosted`, honored only by the digest lane
(see The `hosted` medium).

Expand Down Expand Up @@ -620,7 +629,9 @@ Emitters on the shared builder (`lib/view-builder.mjs`, interactive profile): `e
(`plugins/education/skills/illustrate/scripts/build-explainer.mjs`), which has left the grandfathered
set and defaults to a local `file`, then `terminal`, publishing an artifact only when an argument or
a layer asks for one; `planning:plan` and
`planning:brainstorm`, each offering its view from a checked-in template plus the session's JSON as data
`planning:brainstorm`, each offering its view from a checked-in template plus the session's JSON as data,
and `planning:design`, offering a view of PLAN.md's `## Design` section, each kind an entry in the
builder's view-kind registry rendered through `render(laneId, kind, record)`
(`plugins/planning/scripts/build-view.mjs`); `debugging:debug` (post-mortem) and `discovery:blindspot`, built
the same way (`plugins/debugging/scripts/build-view.mjs`, `plugins/discovery/scripts/build-view.mjs`); and the
`architecture` `map-*` skills, each offering a view of its JSON record from one checked-in template
Expand Down
100 changes: 63 additions & 37 deletions lib/rendered-view.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Rendered views of a skill's record

How a view lane offers an interactive view of the record its skill wrote. The lanes that carry this file:
planning (`/planning:plan`, `/planning:brainstorm`), architecture (the `map-*` skills), discovery
planning (`/planning:plan`, `/planning:brainstorm`, `/planning:design`), architecture (the `map-*` skills), discovery
(`/discovery:blindspot`) and debugging (`/debugging:debug`). Each lane's section below names its record,
build command and data shape. `<plugin-root>` is the plugin's root directory, the one that holds
`.claude-plugin/`: the path the calling skill gave for this file, cut before its first `skills/` or
Expand All @@ -25,17 +25,9 @@ script written in the session.
resolver, not on whether the resolver registers the lane. Only `planning` has migrated today;
architecture, discovery and debugging are registered but read the cascade themselves until their own
change migrates them.
- **Resolver lanes** (`planning`). Run the resolver. `--option` takes this plugin's `medium` option as the
calling skill states it; add `--argument` only when the reader named a medium in the request:

```bash
node "<plugin-root>/lib/view-settings.mjs" resolve --lane <lane> --option "<medium option>" [--argument terminal|file|artifact]
```

It prints one JSON line, then the report line naming the medium and what decided it, then any notice;
print those lines as they stand. The JSON's `medium` is the one to use: `terminal`, `file` or `artifact`.
Do not read the rendered-views convention files yourself. When `node` is missing, the builder cannot run
either: deliver the record.
- **Resolver lanes** (`planning`). The lane's build command runs the resolver, the publish gate and
delivery in one call: follow its section in place of steps 3 and 5, and step 4's rule for a missing
`node` or a non-zero exit still applies. Do not read the rendered-views convention files yourself.
- **Other lanes.** Read the `rendered-views` cascade surface: `~/.claude/rendered-views.md`, then
`<repo root>/.claude/rendered-views.md`, then `<repo root>/.claude/rendered-views.local.md`, whichever
exist. The last layer that states `medium:` wins (`auto`, `terminal`, `file`, `artifact`). A team layer
Expand Down Expand Up @@ -66,31 +58,54 @@ script written in the session.

## Planning

`/planning:plan` records `PLAN.md`; `/planning:brainstorm` records the conversation list or `brainstorm.md`.
Genre: plans presented for approval, and option spreads. Resolver lane: `--lane planning`.
`/planning:plan` records `PLAN.md`; `/planning:brainstorm` records the conversation list or `brainstorm.md`;
`/planning:design` records `PLAN.md`'s `## Design` section. Genre: plans presented for approval, option
spreads, and designs handed to the plan. Resolver lane: `--lane planning`.

Build: pipe one JSON object (shapes under "Data shapes") to the builder; use `brainstorm` in place of `plan`
for the brainstorm view:
Resolve, build and deliver in one call. The builder runs the shared medium resolver
(`lib/view-settings.mjs`, the same resolution as its `resolve` command), runs the publish gate over a
publishing medium, builds the page unless the medium shows none, and hands it to the medium's entry in the
registry (`lib/view-registry.mjs`). Pipe one JSON object (shapes under "Data shapes") for the plan or
brainstorm view:

```bash
node "<plugin-root>/scripts/build-view.mjs" plan <<'JSON'
node "<plugin-root>/scripts/build-view.mjs" plan --option "<medium option>" --visibility "<visibility>" <<'JSON'
{"title": "...", "goal": "...", "blast": "...", "phases": [{"status": "TODO", "name": "...", "what": "...", "needs": "none", "criteria": ["..."]}]}
JSON
```

A plan or brainstorm session reads repository files, issue text and fetched pages, which is why the builder
is the only way to the page.
- `plan` names the view: `brainstorm` for the brainstorm view; `design --record "<PLAN.md path>"` for the
design view, which reads the record's `## Design` section and takes no stdin.
- `--option` takes this plugin's `medium` option as the calling skill states it. Add
`--argument "<medium>"` only when the reader named a medium in the request.
- `--visibility` is the visibility of the repository the record draws on
(`gh repo view --json visibility -q .visibility`), or `NONE` when it draws on none. Left out, the
shipped default stays local.

A planning session reads repository files, issue text and fetched pages, which is why the builder is the
only way to the page.

The builder prints one JSON line, then the report line naming the medium and what decided it, then one line
per notice. Print the report and notice lines as they stand, then deliver what the JSON names:

- `publish` set: publish that file with the Artifact tool and give the link, as step 5 says for `artifact`.
When the Artifact tool is unavailable, hand back `page` and say why in one line.
- Otherwise `page` set: hand back that path.
- Neither: no page was built, and the record stands.

Reply ids: `phases-2` is the second phase in `PLAN.md`; `candidates-3` is the third candidate in the list.
Approval of a plan is stated in the conversation, at the approval gate.
Reply ids: `phases-2` is the second phase in `PLAN.md`; `candidates-3` is the third candidate in the list;
`sections-2` is the second `###` subsection of `## Design`. Approval of a plan is stated in the conversation,
at the approval gate.

### Connect a view to the session

Planning only: it ships the view server. Either view's reply can reach this session instead of being
pasted. In the plan view the reader ticks phases, picks a verdict (`change`, `question`, `approve`), adds a
note, and sends. In the brainstorm view the reader ticks the candidates that resonate, adds a note, and
sends. Only for `file` (or `auto`) with the reader at this machine: the page is served from `127.0.0.1`.
Skip it for `artifact`, and when python3 or curl is missing; the copied reply still closes the loop.
Planning only: it ships the view server. A view's reply can reach this session instead of being pasted. In
the plan view the reader ticks phases, picks a verdict (`change`, `question`, `approve`), adds a note, and
sends. In the brainstorm view the reader ticks the candidates that resonate, adds a note, and sends. In the
design view the reader ticks the sections they question, adds a note, and sends. Only when the delivery was
a local page (`page` set, no `publish`) with the reader at this machine: the page is served from
`127.0.0.1`. Skip it for a published view, and when python3 or curl is missing; the copied reply still
closes the loop.

1. Start the view server on a new data dir under the OS temp directory, never beside the record
(`ensure-running` creates it private):
Expand All @@ -100,7 +115,8 @@ Skip it for `artifact`, and when python3 or curl is missing; the copied reply st
```

It prints one JSON line: `url`, `origin`, `page` and `watch`.
2. Build the page into `page`, naming `origin` (`brainstorm` in place of `plan` for the brainstorm view):
2. Build the page into `page`, naming `origin` (`brainstorm`, or `design --record "<PLAN.md path>"`, in
place of `plan` for the other views):

```bash
node "<plugin-root>/scripts/build-view.mjs" plan --connect "<origin>" --out "<page>" <<'JSON'
Expand All @@ -121,6 +137,8 @@ Skip it for `artifact`, and when python3 or curl is missing; the copied reply st
- Brainstorm view: resolve `candidates-N` against the candidate list. The ticks are the reader's
reaction, not a locked scope: reply with the scope you would propose and its route (brainstorm step 5),
and lock nothing until the reader confirms it in the conversation.
- Design view: resolve `sections-N` against `## Design`. A change to a contract, boundary or verdict
routes back through `/planning:design`; the view edits nothing.
6. Write `<data_dir>/ops.json` with the Write tool,
`{"replies": [{"seq": 1, "text": "..."}], "handled": [2]}`, a reply of at most 4000 characters per event
you answer and `handled` for the rest, then run the event line's `next` as a background Bash task. It
Expand All @@ -137,18 +155,22 @@ With no session listening, the page says so and its copy and save controls still
### Other optional views

The interview's read-only decision table, the PRD pitch view and the design topology view are written
by the session, not the builder, and are only ever local files. Before writing one, resolve `medium` as
step 3 above does, passing a medium the reader names in the request as `--argument`. Then:
by the session, not the builder, and are only ever local files. Before writing one, run the shared medium
resolver, passing a medium the reader names in the request as `--argument`, and print its notice lines:

- `terminal`: write no file. The interview renders the same table inline as a fenced markdown table;
the PRD and design steps skip the view.
- `file`, `artifact` or `hosted`: write the local file. These views are never published, so say that a
publishing value was read as `file`.
- `auto`, an empty value or no value: the skill's shipped default. Any other value is reported and read
as `auto`.
```bash
node "<plugin-root>/lib/view-settings.mjs" resolve --lane planning --option "<medium option>" [--argument "<medium>"]
```

Its JSON line then decides:

Name the source of `medium` with the view or its absence: the request, the layer's path, or "shipped
default". The interview's `page` surface follows the `surface` option, not `medium`.
- `page` false: write no file, and print the report line as it stands. The interview renders the same
table inline as a fenced markdown table; the PRD and design steps skip the view.
- `page` true: write the local file. These views are never published, so when `publishes` is true, print
the report line with `file` in place of the medium and keep what decided it, as in
`view: file (plugin default)`; otherwise print it as it stands.

The interview's `page` surface follows the `surface` option, not `medium`.

### Data shapes

Expand All @@ -161,6 +183,10 @@ Every field is plain text. List order is the numbering in the record.
`brainstorm`: `title`, `problem`, and `candidates` ordered cheapest first, each with `effort`, `name`, `what`,
`where` (the files or mechanisms it touches), and `impact`.

`design`: no JSON. The builder reads the `PLAN.md` that `--record` names: its level-one heading as the title,
the text before the first `###` subsection of `## Design`, and each subsection's lines as written. A record
with no `## Design` section exits 1.

## Architecture

The `map-*` skills record a markdown file and a JSON record; both stay authoritative. A record holds
Expand Down
Loading
Loading