inplan 0.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/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "inplan",
3
+ "version": "0.1.0",
4
+ "description": "inplan — a Markdown editor for human ⇄ coding-agent planning. CLI + desktop editor.",
5
+ "license": "AGPL-3.0-or-later",
6
+ "type": "module",
7
+ "bin": {
8
+ "inplan": "bin/cli.js"
9
+ },
10
+ "files": [
11
+ "bin",
12
+ "app",
13
+ "skill",
14
+ "LICENSE"
15
+ ],
16
+ "engines": {
17
+ "node": ">=20"
18
+ },
19
+ "scripts": {
20
+ "postinstall": "node bin/cli.js install-skill --quiet || true"
21
+ },
22
+ "dependencies": {
23
+ "electron": "^31.4.0",
24
+ "@hocuspocus/provider": "^2.13.0",
25
+ "@supabase/supabase-js": "^2.45.0",
26
+ "ws": "^8.18.0",
27
+ "yjs": "^13.6.31"
28
+ }
29
+ }
package/skill/SKILL.md ADDED
@@ -0,0 +1,149 @@
1
+ ---
2
+ name: inplan
3
+ description: Use when drafting a planning, PRD, or design document that a human should review interactively. Saves the plan as *.plan.md and opens it in the inplan editor for inline-comment collaboration — the agent drafts and poses questions as comments, the human comments/answers, the agent revises — looping until the human completes the session.
4
+ ---
5
+
6
+ # inplan
7
+
8
+ Collaborate with the human on a planning document through inline comments, like
9
+ two people on a shared doc. You draft the plan and pose open questions as
10
+ comments; the human reviews, edits, and answers; you revise. Repeat until the
11
+ human completes the session.
12
+
13
+ ## Install (once)
14
+
15
+ Check for the CLI and install it if missing:
16
+
17
+ inplan --version || npm install -g inplan
18
+
19
+ (If the unscoped name is unavailable, install `@cis/inplan`.)
20
+
21
+ ## File convention
22
+
23
+ Save plans as `<name>.plan.md`. The editor keeps its sidecars in an
24
+ `.inplan/` directory next to the file (control log, canonical base,
25
+ backups) — never edit those by hand.
26
+
27
+ ## Document format
28
+
29
+ Comments live in a single trailing HTML-comment block holding a JSON array. An
30
+ anchored comment is an inline Markdown link whose href is the comment id:
31
+
32
+ The plan should [use Postgres](#cmt-abfdb1) for storage.
33
+
34
+ <!--inplan
35
+ [
36
+ { "id": "cmt-abfdb1", "author": "Agent <agent@inplan>",
37
+ "date": "2026-05-29T00:00:00Z", "resolved": false,
38
+ "text": "Confirm the datastore?",
39
+ "question": { "multiSelect": false, "choices": [
40
+ { "label": "Postgres", "description": "JSONB + scale" },
41
+ { "label": "SQLite", "description": "simplest" } ] } }
42
+ ]
43
+ -->
44
+
45
+ - **Span comment**: exactly one in-body `[text](#cmt-id)` link; no `parentId`/`anchor`.
46
+ - **Reply / answer**: `parentId` set, no link. An answer carries `selected: [labels]`.
47
+ - **Document-level**: `anchor: "doc"`, no link.
48
+ - **Question**: `question.multiSelect` false = pick one (radio), true = pick many
49
+ (checkbox); the human may also answer with free text.
50
+ - Generate ids as `cmt-` + 6 base36 characters.
51
+
52
+ ## Turn-taking & control — read this first
53
+
54
+ This is **turn-based**. The turn belongs to exactly one party at a time:
55
+
56
+ - After you (the agent) `open` or revise and call `wait`, the turn is the
57
+ **human's** — the editor is theirs to use.
58
+ - When the human clicks **Finish turn**, the turn becomes **yours**. In Turn mode
59
+ the human's editor **locks** ("Agent is thinking…"); they **cannot edit** until
60
+ you take your turn and hand control back.
61
+
62
+ Therefore, when `wait` returns `actions`, **it is your turn and the human is
63
+ blocked, waiting for you.** Do not idle and never tell the human to act. Promptly
64
+ take your turn, then call `wait` again. **Calling `wait` is how you hand control
65
+ back** — it logs an `agent_revised` event that unlocks the human's editor. You
66
+ must call `wait` after *every* turn, **even if you changed nothing**; otherwise
67
+ the human stays locked out.
68
+
69
+ `wait` owns the cursor, diffs, and control-log writes. **Your only jobs are: edit
70
+ the plan, then call `wait`.** Do not pass `--cursor` and do not hand-manage it.
71
+
72
+ ## The loop
73
+
74
+ 1. Write `<name>.plan.md` with the plan body and a comment block. Pre-populate
75
+ your open questions as comments (use `question` + `choices` where the answer
76
+ is a choice).
77
+ 2. Launch the editor **in the background, with no timeout** — do not foreground
78
+ it, do not poll:
79
+
80
+ inplan open <name>.plan.md
81
+
82
+ It opens the editor and blocks until the human acts, then prints one JSON
83
+ line to stdout and exits. Re-invoke yourself when it returns.
84
+
85
+ **Pass `--model <your-model-name>`** on `open`/`wait` (e.g. `--model "Opus 4.8"`)
86
+ so the editor shows which model is attached and stamps your comments with a
87
+ model-qualified author. Use the same value every turn.
88
+ 3. Read the printed JSON `status` (it also carries `mode`, `humanLocked`, and
89
+ `settings` — the current materialized user settings, e.g. `autoResolve`):
90
+ - `your_turn` — **Turn mode**: the human finished their turn and their editor
91
+ is **locked**; the turn is yours. Re-read the `.md`, act, then **call `wait`
92
+ to hand control back** (this unlocks them). `humanLocked: true`.
93
+ - `activity` — **Instant mode**: the human acted but is **editing live and is
94
+ not blocked**. React by **appending to comment threads only** (reply/resolve/
95
+ answer) — do **not** rewrite the body — then call `wait` again to keep
96
+ listening. `humanLocked: false`.
97
+ - `confirm_required` — your edit removed an anchored comment (`lost`). If
98
+ intentional, re-run with `--confirmed-comment-deletion=<ids>`; otherwise
99
+ restore the anchor link and try again.
100
+ - `integrity_error` — the document violates the comment grammar (`errors`).
101
+ Fix it and wait again.
102
+ - `closed` — the session is over; **stop**. `reason` tells you how it ended:
103
+ `completed` (Complete & quit), `window_closed` (window closed), or
104
+ `crashed_or_killed` (editor vanished with no close log — surface this to the human).
105
+ - `superseded` — a newer `wait` took over this document (only one waiter runs at
106
+ a time). This one stepped down; **do nothing** — the live waiter is in charge.
107
+ - `navigated` — the human followed an in-window link to a **different document**;
108
+ `path` is the new file. This `wait` stepped down. **Follow them:** call
109
+ `wait <path>` (pass your `--model`) to re-attach there and resume the loop —
110
+ you move with the human to the linked doc.
111
+ **Run only one `wait` per document.** Launch `open` / `wait` as their **own
112
+ long-lived background process** — do **not** background them with a shell `&`
113
+ inside a short-lived wrapper command, or the wrapper exits and its process tree
114
+ (including your waiter) is reaped. If your `wait` ever exits **without** a
115
+ `closed` status while the editor is still open — e.g. it was `superseded`, or the
116
+ process was terminated by the environment — simply **call `wait` again** to resume
117
+ monitoring; don't treat it as the session ending.
118
+ 4. Act on what changed (`your_turn` → the human is locked and waiting; `activity`
119
+ → they're still editing live), **respecting the mode**:
120
+ - **Turn mode**: you may revise the document body and reply/resolve comments.
121
+ - **Instant mode**: only add to comment threads (reply/resolve/answer); do
122
+ **not** rewrite the body.
123
+ Reply by appending a comment with `parentId`. Read `selected` on the human's
124
+ answers. If nothing needs changing, that's fine — you still take your (empty)
125
+ turn and proceed to step 5.
126
+ **Resolving:** by default, set `"resolved": true` once you've incorporated a
127
+ comment. But honor `settings.autoResolve` from the wait result (it is always
128
+ present — the current value, no log-scanning needed): if it's `false`, do
129
+ **not** auto-resolve — instead reply that the thread can be resolved and leave
130
+ it `resolved: false` for the human to resolve.
131
+ 5. **Hand control back: call `wait` again** (no `--cursor` — it self-manages),
132
+ then loop to step 3. This unlocks the human's editor and blocks until their
133
+ next turn. Do this after *every* turn, even an empty one:
134
+
135
+ inplan wait <name>.plan.md
136
+
137
+ `your_turn` and `activity` are **not** stop conditions — you always loop back
138
+ and keep waiting. The **only** thing that ends the loop is `status: closed`.
139
+
140
+ 6. When you believe the plan is ready, signal it (the human still decides):
141
+
142
+ inplan signal <name>.plan.md --done
143
+
144
+ Then wait again. Stop only on `status: closed`.
145
+
146
+ ## Authorship
147
+
148
+ Never add AI attribution to the document, commit messages, code, or anything
149
+ committed — always use the human's identity. (See AGENT.md.)