i-plane 1.2.0 → 2.0.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.
@@ -27,6 +27,30 @@ The compatibility target uses the `issues/` routes. The current public
27
27
  documents `work-items/` instead. A route migration must be verified against the
28
28
  target server; do not change paths solely to match a newer documentation release.
29
29
 
30
+ ## Argument, selection and completeness contracts
31
+
32
+ Commands that address one resource reject extra positional tokens before
33
+ configuration or requests. Quote a multiword reference, such as
34
+ `i-plane project rm "Knowledge Base" --yes`. Create titles, comment/search text
35
+ and bulk cycle/module additions retain their intentional variadic inputs.
36
+
37
+ `done` preserves the selected completed-state UUID. Case-insensitive name ties
38
+ are errors for explicit state selection; a state group still selects its first
39
+ state. Use a state UUID when names collide.
40
+
41
+ `list --limit` accepts a nonnegative integer, including zero. `search --limit`
42
+ accepts integers from 1 to 1000 and defaults to 10. Search requests one additional
43
+ match from the supported endpoint to detect truncation, then returns
44
+ `{ rows, limit, hasMore }` in JSON. Text output explains when more matches exist;
45
+ raise the bound or narrow the query. No exact total is inferred. This replaces
46
+ the earlier bare search-results array and undocumented server-default cap.
47
+
48
+ Paged collections require a valid results array and a nonempty continuation
49
+ cursor when another page is advertised. Repeated cursors fail instead of
50
+ repeating requests or returning duplicated rows. A final bare array remains
51
+ supported. Calendar date fields accept valid dates in years 0001–9999; year zero
52
+ is rejected before mutations, as it is outside the backend's date range.
53
+
30
54
  ## What modules and intake are for
31
55
 
32
56
  A module groups work toward a feature, milestone or other goal and may span
@@ -102,9 +126,9 @@ API endpoints; the diagnostic points to `issueId` from an earlier JSON response.
102
126
 
103
127
  ## Project pages
104
128
 
105
- `pages` and `page show` use the internal session API. `page outline`, `page read`,
129
+ `pages` and `page show` automatically select API-key or native session page access. `page outline`, `page read`,
106
130
  `page stamp`, `page create`, `page set`, `page insert` and block removal use the
107
- live document protocol. Whole-page deletion uses the session API. See the
131
+ live document protocol. Whole-page deletion uses the selected page endpoint. See the
108
132
  [page workflow](pages.md) for credentials, fingerprints, formatting losses and
109
133
  asynchronous persistence. This internal API can change independently of Plane's
110
134
  public API; compatibility is covered by converter fixtures and live acceptance.
@@ -113,7 +137,7 @@ public API; compatibility is covered by converter fixtures and live acceptance.
113
137
 
114
138
  1. Add the command and all options to `src/registry.ts`. The parser gets value
115
139
  flags from the registry, including those of multiword commands.
116
- 2. Add an online handler to `src/dispatch.ts` or a session handler to `src/page-dispatch.ts`. Both missing handlers and handlers
140
+ 2. Add an online handler to `src/dispatch.ts` or a page handler to `src/page-dispatch.ts`. Both missing handlers and handlers
117
141
  absent from the registry fail the command-set test.
118
142
  3. Add a fixture invocation and valid option values to the registry suite. Test
119
143
  the requested method, path and body, and assert observable output. Merely
@@ -165,3 +189,60 @@ The page acceptance script creates and removes one page in the selected existing
165
189
  project. It exercises all nine commands and observes saved HTML within a bounded
166
190
  window; that window is a test limit, not a persistence guarantee. Run
167
191
  `node scripts/page-mutations.mjs` for isolated mutation checks.
192
+
193
+ ### Automatic page transport
194
+
195
+ `AutoPageClient` probes the public project-page list, prefers API-key access and
196
+ selects the native session API only when the route is absent and runtime
197
+ configuration does not advertise API-key pages. Permission failures and individual
198
+ page `404` responses never cause fallback. Capabilities are cached per instance
199
+ for five minutes, with `--refresh-pages` for immediate redetection. Config output
200
+ explains the cached selection without network access or loading session settings.
201
+
202
+ The session implementation and credentials load lazily. Session-only page access
203
+ remains supported; ordinary commands still require the public API key. A definite
204
+ HTTP `401` may refresh session authentication once; live may refresh once only
205
+ before synchronization. Live mutations are never replayed. API-key access never
206
+ refreshes through password sign-in. Both paths keep conversion on their selected
207
+ HTTP transport and reject redirects to avoid forwarding credentials.
208
+
209
+ Tests cover both identities, cache isolation/expiry/reset, installation transitions,
210
+ missing credentials, permission failures, redaction, session refresh and live
211
+ handshakes. See [pages.md](pages.md) for configuration and cache paths.
212
+
213
+ Run `node scripts/page-mutations.mjs` to check that the page tests detect intentional
214
+ regressions. `scripts/page-key-acceptance.mjs` exercises a built CLI against an
215
+ isolated deployment using a private test fixture and a browser. It creates a page,
216
+ checks both writers, stale fingerprints and deletion, then removes the test page.
217
+ The package ships command help and user documentation; repository-only contributor
218
+ instructions are excluded from the release archive.
219
+
220
+ ### Automatic transport verification
221
+
222
+ The built Node CLI passed all nine page commands against isolated Plane 1.4.2
223
+ instances both with API-key pages enabled and with the official, unmodified
224
+ backend/live images. Each run verified live editing, stale fingerprints, language
225
+ preservation, saved HTML and cleanup. The stock instance also passed session-only
226
+ access without an API key. No production rollout or npm publication was performed.
227
+
228
+ The release dry run passed 1,318 tests, TypeScript, formatting, Node smoke checks,
229
+ lazy dependency loading and package inventory checks. Nine deliberate mutations
230
+ were detected, including permission-triggered fallback and non-expiring capability
231
+ selection. These checks cover IPL-24; they do not resolve the separate PLX-11 review
232
+ findings in the extension layer and whole-page review conversion.
233
+
234
+ ### Review follow-up verification
235
+
236
+ Saved page reads preserve semantic review fences and can restore older sanitized
237
+ HTML from canonical JSON by block ID. Invalid or unmatched metadata, unsupported
238
+ wrappers, stale review order and malformed tables produce explicit losses.
239
+ A real built-CLI `page show` to file to `page set` round trip passed with exact
240
+ review date/source retained after browser reload. Unsupported underline content
241
+ reported a read loss and refused replacement without `--allow-loss`.
242
+
243
+ Late capability removal now repeats reference resolution before any mutation;
244
+ HTTP and live mutation markers prevent replay once a write has started. Targeted
245
+ independent reviews of formatting and command targeting found no remaining
246
+ confirmed issues. The complete release dry run passed 1,338 tests and twelve
247
+ intentional mutation checks. The aggregate extension review remains separately
248
+ tracked in PLX-12; these results do not claim production deployment or publication.
package/docs/pages.md CHANGED
@@ -1,27 +1,76 @@
1
1
  # Project pages
2
2
 
3
3
  Read project knowledge as Markdown, then change a section without rewriting the
4
- rest of the document. Pages use Plane's internal session API and live editor;
5
- they are available on instances exposing project pages and the live service.
4
+ rest of the document. Page metadata uses an automatically selected API-key or session endpoint; content
5
+ changes use the collaborative live editor.
6
6
 
7
7
  ## Connect
8
8
 
9
- Add these to your private credentials file alongside `PLANE_URL` and
10
- `PLANE_WORKSPACE`:
9
+ Configure the same settings used for work items:
11
10
 
12
11
  ```ini
13
- PLANE_LOGIN=you@example.com
12
+ PLANE_URL=https://plane.example.com
13
+ PLANE_WORKSPACE=workspace
14
+ PLANE_API_KEY=your-api-key
15
+ ```
16
+
17
+ The CLI first tries the public project-page list with the API key. With the
18
+ for-plane API-key pages extension enabled, HTTP and live use that key. Login,
19
+ password and session-cache settings are not resolved or loaded on this path.
20
+ The server derives identity and checks page permissions; read commands request
21
+ read-only live access. Both transports honor `HTTPS_PROXY`, `HTTP_PROXY` and
22
+ `NO_PROXY`.
23
+
24
+ On stock Plane, a missing public list route selects the native session API.
25
+ Configure these additional values in the credentials file or environment:
26
+
27
+ ```ini
28
+ PLANE_LOGIN=reader@example.com
14
29
  PLANE_PASSWORD=your-password
15
30
  ```
16
31
 
17
- An API token is optional for page commands and still required for work items.
18
- `i-plane config` reports whether credentials are configured and where they came
19
- from, without printing the login password or cookies. Sessions persist under
20
- `$XDG_CACHE_HOME/i-plane/sessions` or `~/.cache/i-plane/sessions`; the directory
21
- has mode 700 and files have mode 600. A restricted environment can select a
22
- private writable directory with `PLANE_SESSION_CACHE` or `--session-cache`.
23
- An expired session receives one refresh. HTTP and WebSocket connections honor
24
- `HTTPS_PROXY`, `HTTP_PROXY` and `NO_PROXY`.
32
+ Password sign-in must be enabled on the server. Session-only page access also
33
+ works without an API key; other commands still require one. The CLI reports
34
+ missing session settings before attempting sign-in. Session cookies are cached
35
+ privately (directory mode 700, file mode 600), keyed by instance URL and login.
36
+ `PLANE_SESSION_CACHE` or `--session-cache <directory>` changes their location;
37
+ the default is `$XDG_CACHE_HOME/i-plane/sessions` or `~/.cache/i-plane/sessions`.
38
+ Passwords are never stored in the cookie cache.
39
+
40
+ ### Detection and diagnostics
41
+
42
+ `i-plane config` is offline: it reports settings, masks the API key and shows the
43
+ cached page access path, its reason and expiry. Before the first page command,
44
+ or after expiry, it reports `unknown` rather than claiming a network check.
45
+
46
+ Capability detection is cached per instance URL for **five minutes**, independently
47
+ of the cookie cache. The cache contains no credentials. It defaults to
48
+ `$XDG_CACHE_HOME/i-plane/page-transports` or `~/.cache/i-plane/page-transports`;
49
+ `PLANE_PAGE_CACHE` can override the directory. Missing, expired, invalid or
50
+ unwritable cache files do not prevent detection. After installing extensions,
51
+ force immediate discovery with `i-plane pages APP --refresh-pages`, or clear the
52
+ selection with `i-plane config --refresh-pages`. No manual transport switch is needed.
53
+ A newly configured key rechecks a selection previously made without a key.
54
+
55
+ A `401`, `403`, network failure or server error never selects session fallback.
56
+ Only a page **list** `404` triggers a capability check; a missing individual page
57
+ stays a missing page. If the runtime reports API-key pages enabled, even a list
58
+ `404` remains an access/project error. An absent runtime route or explicitly
59
+ unavailable API-key feature permits the session path. Cached choices can remain
60
+ stale within the five-minute window; use `--refresh-pages` after server changes.
61
+
62
+ The session path refreshes authentication once on an HTTP `401` or a definite
63
+ live authentication refusal **before synchronization**. Other errors do not retry.
64
+ Live content changes and uncertain writes are never replayed automatically.
65
+ Stock Plane determines the permissions of session live connections; the CLI's
66
+ read commands do not mutate documents. API-key connections require the current
67
+ runtime release; session live connections negotiate it too when present. An adapter
68
+ with no installed runtime package retains stock session live access. When detection
69
+ changes the identity to a session user, project references are resolved again under
70
+ that user before reading or writing pages, so cold and cached commands target the
71
+ same project. If a cached API-key route disappears during a list read, the command
72
+ resolves its original references again before any mutation. An HTTP or live
73
+ mutation that has started is never replayed.
25
74
 
26
75
  ## Read, inspect, edit
27
76
 
@@ -74,12 +123,13 @@ clears a whole page, but empty block replacement or insertion is refused. Use
74
123
  `page rm --block` for a block deletion. Page deletion always requires `--yes`. Plane requires archiving first; the CLI
75
124
  archives and then deletes the page. If deletion fails, the error reports the
76
125
  archived page UUID so you can inspect and recover it.
77
- Nested pages and `--parent` are unsupported by the project-page API.
126
+ Nested pages can be read and edited by UUID. Listing returns root pages; name
127
+ resolution uses that list. The CLI does not expose a `--parent` option.
78
128
 
79
129
  ## Delivery and formatting
80
130
 
81
131
  Successful editing means **the live server acknowledged delivery**. It does not
82
- confirm a database commit. `page show` reads saved HTML and can immediately show
132
+ confirm a database commit. `page show` reads saved HTML, preserves semantic review fences and reports unsupported rich content in JSON `losses` and stderr warnings. It can immediately show
83
133
  the previous content: persistence usually takes about ten seconds, with no
84
134
  guaranteed upper bound. Use `page outline` and `page read` to check the immediate
85
135
  live result. An interrupted write without an acknowledgement reports uncertain
@@ -96,3 +146,33 @@ Replacement checks the affected document and converted input. Reported losses
96
146
  require `--allow-loss`; `--force` does not approve them. A block edit leaves other
97
147
  blocks intact. None of these commands prompts for input, and every command
98
148
  supports `--json`. Run `i-plane page set --help` for flags and examples.
149
+
150
+ ## Knowledge review marks
151
+
152
+ Saved detail responses from the matching extension include canonical JSON for
153
+ review restoration. If older HTML lost review attributes, `page show` can recover
154
+ them by the retained block ID. Missing or ambiguous IDs, invalid canonical fields,
155
+ stale review order and unsupported wrappers produce explicit losses. Canonical
156
+ JSON is used internally and omitted from the CLI output.
157
+
158
+ With the knowledge-review extension installed, a `knowledgeReview` block reads as
159
+ an ordinary fenced code block containing JSON:
160
+
161
+ ````markdown
162
+ ```knowledge-review
163
+ {
164
+ "date": "2026-09-11",
165
+ "source": "Release notes and a manual check"
166
+ }
167
+ ```
168
+ ````
169
+
170
+ `page read --block` returns this representation with no losses. Include it in a
171
+ Markdown file passed to `page set --file`, or use it for a block replacement, to
172
+ restore the same date and source as a semantic review node. `page outline` shows
173
+ `knowledgeReview` and a preview of both fields. Review dates use `YYYY-MM-DD` and
174
+ must be valid calendar dates; sources are nonempty strings. JSON escaping preserves
175
+ quotes and newlines. Unknown fields are rejected instead of silently discarded.
176
+
177
+ The fence language is reserved for review metadata. Raw HTML remains escaped.
178
+ Other unknown editor nodes still produce loss warnings and readable XML output.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "i-plane",
3
- "version": "1.2.0",
3
+ "version": "2.0.0",
4
4
  "description": "Compact Plane CLI for coding agents: tasks, projects, live pages, cycles, modules and intake.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -15,9 +15,7 @@
15
15
  "files": [
16
16
  "dist",
17
17
  "docs/api-coverage.md",
18
- "docs/pages.md",
19
- "AGENTS.md",
20
- "CLAUDE.md"
18
+ "docs/pages.md"
21
19
  ],
22
20
  "engines": {
23
21
  "node": "^22.21.0 || >=24.0.0"
package/AGENTS.md DELETED
@@ -1,173 +0,0 @@
1
- # Working on this repository
2
-
3
- Read this before changing the CLI. README.md is the short package introduction;
4
- `i-plane guide` and command help explain usage. `docs/api-coverage.md` records the
5
- supported API surface, compatibility details and development checks.
6
-
7
- ## Purpose
8
-
9
- A Plane CLI for coding agents and automation. Compact, predictable output is a
10
- product requirement: callers should not need large REST responses or an
11
- interactive terminal to understand and update their work.
12
-
13
- ## Invariants
14
-
15
- **Nothing prompts.** Missing arguments and invalid values raise `UsageError`
16
- with an actionable hint. Never wait for interactive input.
17
-
18
- **Exit codes are a contract.** Use `2` for an invalid call and `1` for an API or
19
- connection failure. Do not classify a transport failure as invalid user input.
20
-
21
- **Every command supports JSON.** Build an output model and pass it through
22
- `printValue` in `src/output.ts`. Text and JSON must describe the same result.
23
- Guide/help models include global options and usage notes as well as commands.
24
-
25
- **The registry owns the CLI contract.** `src/registry.ts` declares command names,
26
- aliases, arguments, options, required markers, examples, usage notes and next
27
- steps. The parser derives value flags from it. Online handlers live in
28
- `src/dispatch.ts`; the registry and handler table must agree in both directions.
29
- Required markers document the contract; handlers still validate the arguments.
30
-
31
- **Help is part of the implementation.** A new command needs a purpose, supported
32
- fields, requirements, realistic examples and follow-up calls. Keep summaries
33
- short; put decisions and limitations in usage notes. All example flags must be
34
- accepted by that command. Do not advertise API/UI fields that the CLI cannot set.
35
- Keep README concise and point readers to `guide` and `--help` for workflows.
36
-
37
- **Never trust a server-side filter without checking it.** Use `fields`, `expand`
38
- and pagination to limit wire size while collecting all pages. The work item
39
- endpoint can accept state, priority and ordering filters without applying them;
40
- those filters are handled in the client. Check behavior, not only HTTP status.
41
-
42
- **Never let a token escape.** Register `guardSecret` before diagnostics. All
43
- output goes through the guards in `src/output.ts`; client errors are redacted,
44
- and config output uses `maskToken`. Redact before truncating or formatting.
45
- A server response or a native error can echo credentials back.
46
-
47
- **A successful write stays successful.** Resolve and validate inputs before
48
- writing. Do not report a successful mutation as failed because an optional
49
- follow-up read or setup step failed. Return the created identifier and a clear
50
- warning with a recovery command. Do not automatically retry uncertain writes.
51
-
52
- **Markdown has a defined scope.** Work item and intake descriptions, and comment
53
- bodies, use Markdown converted at the API boundary. Project, label, state, cycle
54
- and module descriptions are plain text. Keep the established `markdown-it` and
55
- `turndown` conversion; raw HTML must remain escaped in Markdown input.
56
-
57
- **Runtime and dependency claims must agree.** Support Node 22.21+ on the 22.x
58
- line or Node 24+. Keep README and `package.json` engines consistent. Undici 8.x
59
- requires Node 22.19+; the native proxy fallback requires Node 22.21 or Node 24.
60
- Pin dependencies exactly and keep optional `undici` external to the bundle.
61
- Do not infer minimum-version compatibility from a build on a newer runtime.
62
-
63
- ## API behavior that must survive changes
64
-
65
- - Project names reject special characters, including hyphens. Validate before
66
- the creation request. API routes and defaults must be checked on the target
67
- server; newer UI documentation can describe different behavior.
68
- - `--label` merges with existing labels; `--labels` replaces them. Plane replaces
69
- the whole labels array. Read-modify-write can still race with another editor.
70
- - Resolve readable work item references and names before writes. Reject ambiguous
71
- matches, and validate project membership for bulk cycle/module assignment.
72
- - `project create --intake` must initialize the queue with a project PATCH.
73
- Setting the creation flag alone can leave a missing queue and cause HTTP 500.
74
- - Cycle updates preserve the existing owner when `--owner` is absent. Some
75
- servers otherwise default ownership to the requesting user.
76
- - Cycle dates must be supplied or cleared together, including `none`. Format
77
- their timestamps in the project timezone; retain raw timestamps in JSON.
78
- - A work item has one cycle but can belong to several modules. Cycle transfer
79
- moves unfinished work and leaves completed/cancelled work in the source.
80
- - Expired snoozes may disappear from intake GET and normal triage lookup.
81
- Intake update/delete by work item UUID must not require a preliminary GET.
82
- If a readable reference cannot resolve, explain how to use saved `issueId`.
83
- - Intake status is separate from work item state. Acceptance moves triage work
84
- to the project default state on the supported API path. Removing an accepted
85
- intake entry keeps the work item; removing an unaccepted entry deletes it too.
86
-
87
- Regression history also includes infinite Markdown fence parsing, lost inline
88
- HTML inside code, ignored unknown flags, and `--yes=false` confirming deletion.
89
- Preserve coverage for these cases when refactoring.
90
-
91
- ## Checks
92
-
93
- ```bash
94
- bun test
95
- ./node_modules/.bin/tsc --noEmit
96
- ./node_modules/.bin/biome check .
97
- node scripts/release.mjs
98
- ```
99
-
100
- Tests cover regressions, registry/handler agreement, executable help examples,
101
- request payloads, output and errors. A test that only accepts any exception or
102
- checks that a function was called does not establish correct behavior.
103
-
104
- TypeScript checks `src` and `types`; tests run under Bun. Do not add `bun-types`
105
- to the project's TypeScript compilation just to include tests: its declarations
106
- can conflict with `@types/node`. Exercise the built Node entry point too.
107
-
108
- ## Live checks
109
-
110
- The CLI reads `~/.config/plane/credentials` itself. Keep secrets out of command
111
- arguments and logs where possible. Use the local build when checking new code:
112
-
113
- ```bash
114
- bun run build
115
- node dist/cli.js list CLOUD
116
- ```
117
-
118
- Prefer a short, targeted scenario for the behavior changed. Use a temporary
119
- project for writes and remove it afterwards. Do not change working project data
120
- as test fixtures. Preserve a created project's identifier if cleanup fails.
121
-
122
- The full scripts `scripts/acceptance.mjs --live` and
123
- `scripts/planning-acceptance.mjs --live` use real CLI commands and clean up their
124
- projects in `finally`. They take several minutes because they space requests.
125
- Do not repeat both scripts for a documentation edit or a narrow fix that can be
126
- verified with a focused check. Respect the API request budget and use bounded,
127
- observable waits. A forced termination can interrupt cleanup.
128
-
129
- `EPERM`/`EACCES` before an HTTP response indicates an operating-system permission
130
- failure. Check the selected proxy route and sandbox network access before
131
- changing credentials or application code. An installed CLI can also differ from
132
- the local build: check its version before diagnosing missing commands.
133
-
134
- ## Releases and tracking
135
-
136
- Keep `package.json` and `src/cli.ts` versions in sync. The release gate empties
137
- `dist`, runs checks, builds, smoke-tests the command, validates the exact package
138
- contents and size, and checks registry availability. Changes to shipped files
139
- must update both `package.json` files and the gate's allowlist.
140
-
141
- Publishing is irreversible. `node scripts/release.mjs` does not publish;
142
- `--publish` is the publishing path. Obtain authorization for publication and
143
- reuse it within the authorized release rather than asking repeatedly.
144
-
145
- A successful npm upload can return HTTP 202 while registry processing continues.
146
- Do not republish the same version or treat a transient post-upload 404 as a
147
- failed upload. Distinguish submission from public availability, use short bounded
148
- checks, and verify the published version and `latest` tag before claiming both
149
- are available.
150
-
151
- Keep project task statuses aligned with the work. Move a task into progress when
152
- starting, close it after its checks, and reopen it when a confirmed review finding
153
- invalidates completion. Report whether a change is local, installed or published;
154
- these are separate states. Keep commits and public metadata provider-agnostic.
155
-
156
- ## Page command invariants
157
-
158
- Page commands use SessionClient, never the API-key client. Load Yjs, the live
159
- provider and WebSocket dependencies lazily; keep their exact versions external
160
- in both build paths. Session cookies and passwords join the API token in the
161
- secret guard, including old cookies after a refresh.
162
-
163
- Live success means acknowledged delivery, not a database commit. Never replay a
164
- mutation automatically. Complete asynchronous conversion before resolving a
165
- block anchor and checking its content fingerprint inside one transaction. Read
166
- commands never stamp. Only page stamp assigns missing top-level anchors.
167
-
168
- --yes confirms deletion; --force bypasses a stale fingerprint; --allow-loss
169
- accepts reported conversion losses. These decisions must stay separate. Empty
170
- --block must fail before a whole-page mutation can be selected.
171
-
172
- Page fixtures and wire tests live under tests/page*. Unsupported rich content
173
- must remain visible or produce an explicit loss warning.
package/CLAUDE.md DELETED
@@ -1 +0,0 @@
1
- @AGENTS.md