opendoor-plugin 0.1.0 → 0.4.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/README.md +155 -22
- package/dist/browser/pi-web-plugin.js +1918 -1395
- package/dist/package.json +6 -27
- package/dist/pi-extension/index.js +136 -0
- package/dist/server-plugin.js +32 -21
- package/package.json +20 -9
package/README.md
CHANGED
|
@@ -19,15 +19,33 @@ Full feature spec: [`docs/feature-doorstop-plugin.md`](docs/feature-doorstop-plu
|
|
|
19
19
|
|
|
20
20
|
## Status
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
Requires **pi-web 1.202609.1 or newer** (browser plugin API v4 / server
|
|
23
|
+
plugin API v3). Tested through **pi-web 1.202610.8**, which remains
|
|
24
|
+
**additive** for this plugin — its browser v4/server v3 entries still load,
|
|
25
|
+
with once-per-plugin deprecation diagnostics expected (see **Rollout** below
|
|
26
|
+
for the upgrade order and the 1.202610.x sessiond-restart note). The Phase 3 pairing
|
|
27
|
+
on top of that migration (public session metadata + session-list row
|
|
28
|
+
labels, plan §2.1) stays on the same v4/v3 contracts. The package is one npm
|
|
29
|
+
package (`opendoor-plugin`) that ships a PI WEB plugin AND a Pi extension:
|
|
30
|
+
the plugin's browser/server halves below, plus the review-dispatch extension
|
|
31
|
+
that starts labeled review conversations (`/opendoor-review`, see **Review
|
|
32
|
+
dispatch (Pi extension)** below). The plugin loads on older hosts unchanged;
|
|
33
|
+
only the extension's dispatch bridge, the public metadata, and the row
|
|
34
|
+
labels need a 1.202610.x session daemon (see **Rollout**). The plugin is
|
|
35
|
+
fully wired and green:
|
|
23
36
|
|
|
24
|
-
- **Browser entry** (`src/pi-web-plugin.ts`, apiVersion
|
|
37
|
+
- **Browser entry** (`src/browser/pi-web-plugin.ts`, apiVersion 4, name `Opendoor`)
|
|
25
38
|
delegates to `createOpendoorBrowserContributions` in
|
|
26
|
-
`src/doorstop-contributions.ts`, which contributes:
|
|
39
|
+
`src/browser/doorstop-contributions.ts`, which contributes:
|
|
27
40
|
|
|
28
|
-
- **panel** `workspace.doorstop` (title **Requirements**, order
|
|
41
|
+
- **panel** `workspace.doorstop` (title **Requirements**, order 5 — deliberately
|
|
42
|
+
below the bundled Files panel's order 10, which answers every chat file link
|
|
43
|
+
unconditionally in the host's first-accepting-panel dispatch; this is what
|
|
44
|
+
makes the `fileOpenQuery` claim — chat links to doorstop item files open the
|
|
45
|
+
item's detail view in this panel instead of Files — reachable, at the cost
|
|
46
|
+
of the Requirements tab preceding Files) — the Lit
|
|
29
47
|
body element `<pi-web-opendoor-panel-body>`, driven by the per-workspace
|
|
30
|
-
controller registry (`src/doorstop-panel.ts`): five vertical sections —
|
|
48
|
+
controller registry (`src/browser/doorstop-panel.ts`): five vertical sections —
|
|
31
49
|
`project-actions` (title, Items/Findings toggle, Refresh / Run validation
|
|
32
50
|
/ Publish HTML), `item-list` (filters row + item rows with state chips),
|
|
33
51
|
`item-details` (links in/out, references, extended attributes,
|
|
@@ -40,9 +58,14 @@ The plugin is fully wired and green, in two halves:
|
|
|
40
58
|
- **actions** `view.doorstop` (mod+7) and `workspace.refresh-doorstop`
|
|
41
59
|
(mod+shift+d);
|
|
42
60
|
- **label** `doorstop-status` — the informational requirement-health counts
|
|
43
|
-
(async-cache idiom, feature spec §7.4)
|
|
61
|
+
(async-cache idiom, feature spec §7.4);
|
|
62
|
+
- **session-row label** `doorstop.review` — a compact indicator on session
|
|
63
|
+
rows carrying public `opendoor` metadata; clicking it reopens the
|
|
64
|
+
Requirements tab on the row's machine/workspace (works for unselected and
|
|
65
|
+
archived rows, no live Pi connection needed). See **Session metadata and
|
|
66
|
+
session-list row labels** below.
|
|
44
67
|
|
|
45
|
-
- **Server entry** (`src/server-plugin.ts`, default export `PiWebServerPlugin`)
|
|
68
|
+
- **Server entry** (`src/server-plugin.ts`, apiVersion 3, default export `PiWebServerPlugin`)
|
|
46
69
|
contributes a workspace provider that claims only projects whose root
|
|
47
70
|
contains a `.doorstop.yml` (cheap `fs.access` probe — everything else stays
|
|
48
71
|
with the bundled Git provider) and serves a six-operation backend:
|
|
@@ -57,24 +80,42 @@ The plugin is fully wired and green, in two halves:
|
|
|
57
80
|
server-side (the browser never sends shell strings), and runs through the
|
|
58
81
|
host's `execFile()` helper with `cwd` = the workspace path, timeouts
|
|
59
82
|
clamped to 8.5 s (the review+git pipeline shares one deadline budget under
|
|
60
|
-
the host's 10 s callback bound), and per-workspace run serialization.
|
|
83
|
+
the host's 10 s callback bound), and per-workspace run serialization. The
|
|
84
|
+
server entry permanently declares no `requires` and no `start()`: the
|
|
85
|
+
capability-driven `doorstop.ask-agent` dispatch it once carried was
|
|
86
|
+
unreachable by construction on a workspace-provider-contributing entry
|
|
87
|
+
(PI WEB rejects the provider-dependency capability cycle) and has been
|
|
88
|
+
retired. The review dispatch now runs in the Pi extension below.
|
|
89
|
+
- **Pi extension** (`src/pi-extension/opendoor-review.ts`, bundled to
|
|
90
|
+
`dist/pi-extension/index.js` and declared by `pi.extensions`) registers
|
|
91
|
+
`/opendoor-review <UID> [instruction…]`. It publishes the shipped public
|
|
92
|
+
`opendoor` session metadata (`{ schema: 1, op: "review", uids }`) and asks
|
|
93
|
+
PI WEB's own per-session dispatch bridge to start an independent
|
|
94
|
+
conversation in the same registered project — the same spawn semantics and
|
|
95
|
+
delegation restrictions as `spawn_session`, with model/thinking inherited
|
|
96
|
+
from the initiating conversation. Every outcome (started / refused / no
|
|
97
|
+
bridge) is reported as a message in the initiating conversation. This is
|
|
98
|
+
the pathway the panel's **Start review session** entry drives (see **Review
|
|
99
|
+
dispatch (Pi extension)** below).
|
|
61
100
|
|
|
62
|
-
Dispatch (per action, in `src/doorstop-panel-
|
|
101
|
+
Dispatch (per action, in `src/browser/doorstop-panel-element.ts`): when the workspace
|
|
63
102
|
is opendoor-owned with an active backend, the action sends a structured
|
|
64
|
-
request via `context.
|
|
103
|
+
request via `context.peer.request("doorstop.run", …)` (the review-commit
|
|
65
104
|
flag rides along when the setting is enabled; the "Changes since review"
|
|
66
|
-
section fetches via `context.
|
|
105
|
+
section fetches via `context.peer.request("doorstop.item-baseline", …)`)
|
|
67
106
|
and the captured output appears in the panel's status bar (auto-expanded);
|
|
68
107
|
the panel auto-rescans on completion. When the backend is absent (unpaired
|
|
69
108
|
install, or a workspace the provider does not own), the action falls back to
|
|
70
109
|
`terminal.runCommand()` with the same shell command, so output stays visible
|
|
71
110
|
and auditable in the terminal.
|
|
72
111
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
112
|
+
The shared types + function-signature contracts live in
|
|
113
|
+
`src/doorstop-contract.ts`; the two backend operation contracts
|
|
114
|
+
(`doorstop.run` and `doorstop.item-baseline`) shared by both halves, plus
|
|
115
|
+
the four git-action contracts (`doorstop.git-status`, `doorstop.git-stage`,
|
|
116
|
+
`doorstop.git-unstage`, `doorstop.git-commit`), live in
|
|
117
|
+
`src/doorstop-backend-contract.ts`. Later modules import these and must not
|
|
118
|
+
redefine them.
|
|
78
119
|
|
|
79
120
|
## Workspace settings (`.pi-web/opendoor.json`)
|
|
80
121
|
|
|
@@ -92,6 +133,7 @@ bundled workspace-tasks plugin. The *server* entry's host-scoped knobs
|
|
|
92
133
|
"version": 1,
|
|
93
134
|
"publish": { "target": "./public" },
|
|
94
135
|
"discovery": { "excludedDirectories": ["published", "vendor"] },
|
|
136
|
+
"showAdditionalAttribute": ["text", "component"],
|
|
95
137
|
"commitAfterReview": false
|
|
96
138
|
}
|
|
97
139
|
```
|
|
@@ -104,6 +146,18 @@ bundled workspace-tasks plugin. The *server* entry's host-scoped knobs
|
|
|
104
146
|
- `discovery.excludedDirectories` — additional directory names the
|
|
105
147
|
`.doorstop.yml` walk never enters (merged with the built-in
|
|
106
148
|
`.git`/`node_modules` skips, max 16 names).
|
|
149
|
+
- `showAdditionalAttribute` — array of attribute NAMES rendered in every
|
|
150
|
+
item-list row as `key: value` (values jsonish-quoted, joined with ` · `, in
|
|
151
|
+
the configured order). Entries may be any extended attribute key; an
|
|
152
|
+
attribute an item does not have is skipped for that row, and no unconfigured
|
|
153
|
+
attribute ever appears. The modeled `text` is special-cased: instead of a
|
|
154
|
+
`text: "…"` pair in the attribute column, the item body renders raw and
|
|
155
|
+
unquoted on its own indented second line below the row, clamped to two lines
|
|
156
|
+
with an ellipsis (the full body lives in the detail pane); it is skipped when
|
|
157
|
+
the item body is empty. Default `[]` leaves today's rows unchanged. Invalid
|
|
158
|
+
entries are dropped with a warning each, duplicates are deduplicated, the
|
|
159
|
+
list is capped at 16 names, and unknown keys are accepted (they simply match
|
|
160
|
+
nothing).
|
|
107
161
|
- `commitAfterReview` — opt-in boolean (default `false`): when enabled on a
|
|
108
162
|
paired workspace, the **Review** action's `doorstop review <uid>` is
|
|
109
163
|
followed by a pathspec-limited git commit of the item file with the
|
|
@@ -150,12 +204,13 @@ bottom:
|
|
|
150
204
|
all** button, and the **Git commit** control (message input + button); see
|
|
151
205
|
**Git actions** below.
|
|
152
206
|
2. **`item-list`** — a filters row (document chips, state filter, search)
|
|
153
|
-
above the item rows
|
|
207
|
+
above the item rows; each row shows its level, UID, excerpt, any attributes
|
|
208
|
+
configured through `showAdditionalAttribute`, and its state chips.
|
|
154
209
|
3. **`item-details`** — the selected item's full detail pane (unchanged).
|
|
155
210
|
4. **`item-action-palette`** — the item actions (**Review**, **Clear suspect
|
|
156
|
-
links**, **
|
|
157
|
-
|
|
158
|
-
|
|
211
|
+
links**, **Link** + target UID input, **Ask agent** menu), moved out of
|
|
212
|
+
the detail pane so the row spans the panel at the same height as the
|
|
213
|
+
center-panel chat prompt footer. A muted "Select an item…"
|
|
159
214
|
placeholder keeps the palette at constant height while nothing is
|
|
160
215
|
selected; the palette is hidden in the Findings view.
|
|
161
216
|
5. **`status-bar`** — the run status row (badge, duration, **Dismiss**),
|
|
@@ -258,7 +313,18 @@ bottom:
|
|
|
258
313
|
expanded status bar body.
|
|
259
314
|
- **Ask the agent** menu: inserts ready-made prompts (explain, fix suspect
|
|
260
315
|
links, draft child requirement, review readiness) into the session prompt
|
|
261
|
-
editor using the item's paths and state (feature spec §7.3).
|
|
316
|
+
editor using the item's paths and state (feature spec §7.3). **Start
|
|
317
|
+
review session** composes `/opendoor-review <UID>` plus the item context
|
|
318
|
+
into that same editor and needs no paired backend: sending it lets the
|
|
319
|
+
opendoor Pi extension start an independent review conversation whose list
|
|
320
|
+
row carries a **`firstUid +n` label** that reopens the Requirements tab on
|
|
321
|
+
the row's workspace — including for unselected and archived rows and with
|
|
322
|
+
no live Pi connection — landing on the item detail pane. After the insert
|
|
323
|
+
the panel's status bar shows a quiet `ok` **review dispatch** run row.
|
|
324
|
+
Without the extension installed the inserted text is still a
|
|
325
|
+
self-sufficient review instruction, so the review happens in the current
|
|
326
|
+
conversation; a refused dispatch is reported in the chat by the extension.
|
|
327
|
+
See **Session metadata and session-list row labels** in the feature spec.
|
|
262
328
|
- Fingerprints and the requirement state are recomputed in the browser from
|
|
263
329
|
the YAML files; everything mutating goes through the visible `doorstop`
|
|
264
330
|
CLI — paired, headlessly via the server entry (output captured in the
|
|
@@ -271,14 +337,30 @@ bottom:
|
|
|
271
337
|
```sh
|
|
272
338
|
npm install # install dependencies
|
|
273
339
|
npm test # vitest (unit tests under src/**/*.test.ts)
|
|
340
|
+
npm run test:coverage # v8 coverage report
|
|
274
341
|
npm run typecheck # tsc --noEmit (strict)
|
|
275
342
|
npm run build # esbuild: dist/browser/pi-web-plugin.js + dist/server-plugin.js
|
|
276
|
-
#
|
|
343
|
+
# + dist/pi-extension/index.js, then the dist-root
|
|
344
|
+
# package.json plugin manifest (see the build script header)
|
|
277
345
|
npm run dev # watch mode build
|
|
278
346
|
```
|
|
279
347
|
|
|
280
348
|
## Installing the plugin locally (id `opendoor`)
|
|
281
349
|
|
|
350
|
+
The package carries two independently enabled halves: the **PI WEB plugin**
|
|
351
|
+
(browser + server entries) and the **Pi extension** (`/opendoor-review`).
|
|
352
|
+
The repository-root `package.json` is the npm-package-root manifest, so both
|
|
353
|
+
halves come from ONE install through **Settings → Pi packages** (npm name,
|
|
354
|
+
git/URL, or a local package source). The `ln -s dist` route below remains
|
|
355
|
+
available for plugin-only development.
|
|
356
|
+
|
|
357
|
+
### PI WEB plugin (browser + server entries)
|
|
358
|
+
|
|
359
|
+
Install the package once — **Settings → Pi packages** with source
|
|
360
|
+
`opendoor-plugin` (or this repository's path / git URL) — then enable
|
|
361
|
+
**Opendoor** under **Settings → PI WEB plugins**. For a plugin-only local
|
|
362
|
+
build the symlink route still works:
|
|
363
|
+
|
|
282
364
|
```sh
|
|
283
365
|
npm run build
|
|
284
366
|
ln -s "$(pwd)/dist" ~/.pi-web/plugins/opendoor
|
|
@@ -297,3 +379,54 @@ The manifest should list an `opendoor` plugin entry **with a
|
|
|
297
379
|
`backendRevision`** (signing the paired server module). If `backendRevision`
|
|
298
380
|
is missing, the server module failed to load — check the sessiond log; the
|
|
299
381
|
plugin still works fully via the terminal fallback.
|
|
382
|
+
|
|
383
|
+
### Review dispatch (Pi extension)
|
|
384
|
+
|
|
385
|
+
Installing the package is what loads the extension; enabling the PI WEB
|
|
386
|
+
plugin is a separate decision. After installing or updating the package on a
|
|
387
|
+
machine, run `/reload` in each idle conversation so the `/opendoor-review`
|
|
388
|
+
command is registered there (an ordinary Pi-resource change — no provider
|
|
389
|
+
restart involved). The extension needs PI WEB **1.202610.x** for the
|
|
390
|
+
session-dispatch bridge; on an older host it reports "requires PI WEB's
|
|
391
|
+
session dispatch bridge" in the conversation and starts nothing. The panel's
|
|
392
|
+
**Start review session** entry needs no paired backend — it only composes the
|
|
393
|
+
command into the prompt editor.
|
|
394
|
+
|
|
395
|
+
## Rollout (pi-web 1.202609.1)
|
|
396
|
+
|
|
397
|
+
pi-web 1.202609.1 is a **hard break** for plugins — there is no
|
|
398
|
+
compatibility shim in either direction: a v4/v3 host rejects v2/v1 plugin
|
|
399
|
+
modules, and a v2/v1 host rejects the migrated v4/v3 modules. Upgrade the
|
|
400
|
+
opendoor package and pi-web **together**, then restart
|
|
401
|
+
`pi-web-sessiond.service` and reload the PI WEB page. During the transition
|
|
402
|
+
the opendoor panel is **entirely absent** (both plugin entries rejected), not
|
|
403
|
+
degraded. Federated gateways/targets must be upgraded in lockstep.
|
|
404
|
+
|
|
405
|
+
### pi-web 1.202610.3 (and later 1.202610.x)
|
|
406
|
+
|
|
407
|
+
Unlike 1.202609.1, release **1.202610.3** is **additive** for opendoor: the
|
|
408
|
+
untouched v4/v3 plugin keeps loading on a v1.202610.3 host, with a
|
|
409
|
+
once-per-plugin deprecation diagnostic (no removal date). No source changes
|
|
410
|
+
were needed — the only mindful adaptation was a no-op `navigate` stub in the
|
|
411
|
+
test fixtures (`src/test-fixtures.ts`, `src/browser/pi-web-plugin.test.ts`),
|
|
412
|
+
because 1.202610.x made `navigate` a required member of
|
|
413
|
+
`PluginRuntimeContext` / `WorkspacePanelContext`.
|
|
414
|
+
|
|
415
|
+
Host upgrade order for 1.202610.x: refresh the pi-web checkout, then
|
|
416
|
+
**manually restart `pi-web-sessiond.service`** — a UI/API autoreload alone
|
|
417
|
+
is **not sufficient** (the release touched the session-serving paths
|
|
418
|
+
heavily). The restart interrupts active sessions and terminals; reload the
|
|
419
|
+
PI WEB page afterwards and confirm the manifest shows the opendoor entry
|
|
420
|
+
with a `backendRevision`.
|
|
421
|
+
|
|
422
|
+
#### Review dispatch and session-row labels (1.202610.x floor)
|
|
423
|
+
|
|
424
|
+
The **Start review session** dispatch and the session-list row labels require
|
|
425
|
+
a **1.202610.x** session daemon: that release introduced the public session
|
|
426
|
+
metadata, the session-list label contribution, and the per-session dispatch
|
|
427
|
+
bridge the extension emits on. The opendoor **server** entry declares no
|
|
428
|
+
capabilities and loads across the whole supported range. `opendoor-plugin`
|
|
429
|
+
**0.4.0** is the first release carrying the extension. Restart
|
|
430
|
+
`pi-web-sessiond.service` once to load the server-side change, then run
|
|
431
|
+
`/reload` in each idle conversation to load the extension's
|
|
432
|
+
`/opendoor-review` command; the browser side only needs a page reload.
|