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/LICENSE +661 -0
- package/app/main/index.js +769 -0
- package/app/preload/index.mjs +92 -0
- package/app/renderer/assets/index-BqLfQmz0.js +52343 -0
- package/app/renderer/assets/index-C67b7qA1.css +272 -0
- package/app/renderer/index.html +13 -0
- package/bin/cli.js +1409 -0
- package/package.json +29 -0
- package/skill/SKILL.md +149 -0
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.)
|