wiki-viewer 2.16.0 → 2.16.1
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/.next/standalone/.next/BUILD_ID +1 -1
- package/.next/standalone/.next/build-manifest.json +3 -3
- package/.next/standalone/.next/prerender-manifest.json +3 -3
- package/.next/standalone/.next/required-server-files.json +4 -4
- package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/api/agent/activity/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/events/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/files/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/fs/file/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/fs/ls/[[...path]]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/fs/move/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/fs/search/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/settings/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/agent/sidecar/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/app-proxy/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/assets/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/pdf/save/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/share/[token]/asset/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/share/[token]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/share/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/browse/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/reveal/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/branch/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/refresh/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/system/workspaces/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/upload/[...path]/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/app/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/backlinks/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/content/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/download/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/folder/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/git-branches/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/git-checkout/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/git-diff/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/git-file-info/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/git-history/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/git-pull/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/move/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/new-file/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/outlinks/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/page/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/presence/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/scratch/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/search/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/slugs/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/upload/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/api/wiki/watch/route.js.nft.json +1 -1
- package/.next/standalone/.next/server/app/page/react-loadable-manifest.json +4 -5
- package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/s/[token]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/app/signin/page_client-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ltsov-._.js +1 -1
- package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_system_workspaces_[id]_open_route_actions_1087xu7.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/0.u4_next_0kf.7hj._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/0.u4_next_dist_0xugq-k._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/12y~_mermaid_dist_chunks_mermaid_core_chunk-5ZQYHXKU_mjs_0z1.978._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/12y~_mermaid_dist_chunks_mermaid_core_chunk-KSCS5N6A_mjs_0v4oeem._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_01eqklo._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0858xdh._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/_0k6g8yo._.js +3 -3
- package/.next/standalone/.next/server/chunks/ssr/_0sr4wj.._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_06613~i._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0o~d81.._.js +1 -1
- package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0szp2v0._.js +1 -1
- package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
- package/.next/standalone/.next/server/pages/500.html +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/.next/static/chunks/0.5ywu7_j899v.js +12 -0
- package/.next/standalone/.next/static/chunks/{0tjcc1wg-57l1.js → 065s1_n.1k11t.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0y~5s_skz1l9a.js → 0ccw-uc_3ao.w.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0ii.akeq7k4pf.js → 0f8kfd9d6kq0b.js} +1 -1
- package/.next/standalone/.next/static/chunks/0lsw6lsaj7lby.js +1 -0
- package/.next/standalone/.next/static/chunks/0rpxacw15~o7k.js +12 -0
- package/.next/standalone/.next/static/chunks/{0r7d-1tq61fa1.js → 0s2h7kvkrtq~p.js} +1 -1
- package/.next/standalone/.next/static/chunks/{0enm-3xy21jcx.js → 0tzi1~wpigp2y.js} +2 -2
- package/.next/standalone/.next/static/chunks/117dkzyg4c~us.js +1 -0
- package/.next/standalone/.next/static/chunks/{0j7kp7w2oum68.js → 11pa_9ucyrzh9.js} +1 -1
- package/.next/standalone/.scratch/tweak-running-app/craft-checklist.md +52 -0
- package/.next/standalone/.scratch/tweak-running-app/issues/01-isolated-origin.md +108 -0
- package/.next/standalone/.scratch/tweak-running-app/issues/01-runtime-containment.md +18 -0
- package/.next/standalone/.scratch/tweak-running-app/issues/02-injection-transform.md +18 -0
- package/.next/standalone/.scratch/tweak-running-app/issues/02-tracer-bullet.md +48 -0
- package/.next/standalone/.scratch/tweak-running-app/issues/03-accept-carbonize-mutator.md +19 -0
- package/.next/standalone/.scratch/tweak-running-app/issues/03-run-robustness.md +37 -0
- package/.next/standalone/.scratch/tweak-running-app/issues/04-multifile-safety.md +37 -0
- package/.next/standalone/.scratch/tweak-running-app/issues/04-static-tracer-bullet.md +27 -0
- package/.next/standalone/.scratch/tweak-running-app/issues/05-batch-parity.md +43 -0
- package/.next/standalone/.scratch/tweak-running-app/issues/05-dynamic-node-app.md +22 -0
- package/.next/standalone/.scratch/tweak-running-app/issues/06-remote-transport-bridge.md +20 -0
- package/.next/standalone/.scratch/tweak-running-app/issues/07-retire-bespoke-web-tweak.md +17 -0
- package/.next/standalone/.scratch/tweak-running-app/keep-ticket.md +74 -0
- package/.next/standalone/.scratch/tweak-running-app/mockups.html +305 -0
- package/.next/standalone/.scratch/tweak-running-app/ops1-updated.md +215 -0
- package/.next/standalone/.scratch/tweak-running-app/ops12-continuation.md +44 -0
- package/.next/standalone/.scratch/tweak-running-app/ops22-context.md +84 -0
- package/.next/standalone/.scratch/tweak-running-app/pivot-note.md +25 -0
- package/.next/standalone/.scratch/tweak-running-app/qa-live-engine.ts +104 -0
- package/.next/standalone/.scratch/tweak-running-app/spike.md +256 -0
- package/.next/standalone/.scratch/tweak-running-app/suggest-current-assessment.md +39 -0
- package/.next/standalone/.scratch/tweak-running-app/suggest-inline-interaction-spec.md +320 -0
- package/.next/standalone/.scratch/tweak-running-app/tweak-interaction-spec.md +161 -0
- package/.next/standalone/.scratch/tweak-running-app/two-actions-interaction-spec.md +234 -0
- package/.next/standalone/.scratch/tweak-running-app/unified-live-spec.md +261 -0
- package/.next/standalone/package.json +1 -1
- package/.next/standalone/server.js +1 -1
- package/package.json +1 -1
- package/.next/standalone/.next/static/chunks/04jvwlttwa_sw.js +0 -12
- package/.next/standalone/.next/static/chunks/161kgz.8h.3iq.js +0 -1
- package/.next/standalone/.next/static/chunks/16kzqur8~yg6b.js +0 -12
- /package/.next/standalone/.next/static/{7EbGXTo8ObPhr7UobKARQ → zwUX5EOT_44n1RoB_W9Bo}/_buildManifest.js +0 -0
- /package/.next/standalone/.next/static/{7EbGXTo8ObPhr7UobKARQ → zwUX5EOT_44n1RoB_W9Bo}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/.next/static/{7EbGXTo8ObPhr7UobKARQ → zwUX5EOT_44n1RoB_W9Bo}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Design-fidelity / craft checklist (acceptance-level)
|
|
2
|
+
|
|
3
|
+
Purpose: the old Tweak UX was loved for its *craft* — the elements, interactions,
|
|
4
|
+
and polish, not just that it worked. This checklist carries that craft into the
|
|
5
|
+
re-home (Comment + Suggest better UX + Copy-as-prompt). Treat each line as an
|
|
6
|
+
acceptance item a reviewer verifies by hand, not just "the feature works."
|
|
7
|
+
|
|
8
|
+
Applies to: the Suggest inline-redline surface, its review popover, the
|
|
9
|
+
Copy-as-prompt surface, and any composer/popover added. Retire only the
|
|
10
|
+
engine-bound widgets (see bottom); keep everything else.
|
|
11
|
+
|
|
12
|
+
## Keyboard & input
|
|
13
|
+
- [ ] Primary commit on **Cmd/Ctrl+Enter** in every text input (composer, note, reply).
|
|
14
|
+
- [ ] **esc** cancels; **outside-click while the input is empty** = cancel (never a silent commit).
|
|
15
|
+
- [ ] Inputs **autofocus** on open; focus returns sensibly on close.
|
|
16
|
+
- [ ] Full keyboard path through review: open popover, cycle overlap (◂/▸), Accept/Reject without the mouse.
|
|
17
|
+
|
|
18
|
+
## Anchoring & layout
|
|
19
|
+
- [ ] Popovers anchor to their target and are **viewport-clamped** (min ~8px margin, never off-screen).
|
|
20
|
+
- [ ] Scroll containment: long content scrolls inside the popover/panel (max-height viewport-safe), page doesn't jump.
|
|
21
|
+
- [ ] Tap targets meet **44px** touch slop on coarse pointers (badges use a 16px glyph with 44px hit area).
|
|
22
|
+
|
|
23
|
+
## Motion (use existing tokens)
|
|
24
|
+
- [ ] Transitions use `--motion-fast 100ms` / `--motion-base 150ms`; nothing janky or instant-pop.
|
|
25
|
+
- [ ] Suggesting-mode flush **crossfades** typed text into posted redline in place (no flash-revert).
|
|
26
|
+
- [ ] Respect `prefers-reduced-motion`.
|
|
27
|
+
|
|
28
|
+
## Visual language (existing tokens only — no new palette)
|
|
29
|
+
- [ ] Redline uses `--success` (insert, underline) / `--destructive` (delete, strike); block changes get left-bar + `*-soft` wash.
|
|
30
|
+
- [ ] Agent-authored ranges: 45° hatched texture + `✦` glyph, visibly distinct from human.
|
|
31
|
+
- [ ] **Mono snippet chips** for block/selector references; `pre` snippet blocks for quoted source; tag chips where a kind is shown.
|
|
32
|
+
- [ ] Tight editorial type scale (~10.5–13px on chrome, serif for prose/diff), warm-paper surfaces, soft `--shadow-*` elevation.
|
|
33
|
+
|
|
34
|
+
## Feedback & states
|
|
35
|
+
- [ ] Copy actions show a **"Copied" flip for ~1500ms**, then revert.
|
|
36
|
+
- [ ] Clipboard-blocked (non-secure context) falls back to a **"Show text"** manual-copy box; one code path, always numbered `1.`.
|
|
37
|
+
- [ ] Hover-reveal for secondary row controls (remove/copy) on fine pointers; always visible on touch.
|
|
38
|
+
- [ ] Honest empty state = **zero chrome** (no stray bars/placeholders).
|
|
39
|
+
- [ ] Overlap switcher shows **N of M** and live-swaps the prose redline as you cycle.
|
|
40
|
+
- [ ] Drift / stale-anchor never silently drops: explicit `⚠ target changed` with Re-anchor / Remove.
|
|
41
|
+
- [ ] Author + kind attribution visible on every comment/suggestion (`by`, human vs agent).
|
|
42
|
+
|
|
43
|
+
## Copy-as-prompt surface specifics
|
|
44
|
+
- [ ] Reads only persisted comments/suggestions; creates/writes nothing.
|
|
45
|
+
- [ ] Per-item ⎘ copy **and** Copy-all; default scope = open/unresolved items.
|
|
46
|
+
- [ ] Emits the established string: ``Edit the file `X` (a Markdown document). Apply these changes:\n\n1. `snippet`: text`` .
|
|
47
|
+
|
|
48
|
+
## Retire (engine-bound widgets — do NOT resurrect)
|
|
49
|
+
- Bottom-center queue bar (existed only to batch the live engine's single round-trip).
|
|
50
|
+
- Variant apply/revert-into-iframe live preview + variant pills as a *generation* device.
|
|
51
|
+
- The "Apply with the agent?" confirm modal and the live poll/waiting panels.
|
|
52
|
+
Their *feel* (cycling, in-place feedback, keyboard-first, tactile chips) transfers to the new surfaces; the widgets themselves do not.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
## Parent
|
|
2
|
+
|
|
3
|
+
OPS-1 — Spec: Tweak on a running app (proxied node-app runtime).
|
|
4
|
+
|
|
5
|
+
## What to build
|
|
6
|
+
|
|
7
|
+
Serve proxied running node-apps from a dedicated **isolated origin** so a
|
|
8
|
+
sandboxed, opaque-origin Tweak preview can talk to the wiki-viewer parent only
|
|
9
|
+
through the postMessage boundary, and page JS inside the proxied app can never
|
|
10
|
+
reach `parent.document` to forge an Accept.
|
|
11
|
+
|
|
12
|
+
Today the proxied app iframe is served from the wiki-viewer origin and keeps
|
|
13
|
+
`allow-same-origin` (required for the app to function), so hostile page script
|
|
14
|
+
could reach the parent and click Accept, bypassing the postMessage boundary.
|
|
15
|
+
The static-HTML Tweak surface avoids this by rendering into an opaque origin
|
|
16
|
+
(`srcDoc` + `sandbox="allow-scripts"`). A running app cannot use that trick
|
|
17
|
+
because it must stay same-origin to work. The only fix is a separate origin.
|
|
18
|
+
|
|
19
|
+
This ticket is the security foundation for the whole feature. It introduces the
|
|
20
|
+
isolated origin, the grant-based authorization for it, and the wiki-origin
|
|
21
|
+
hardening that becomes load-bearing once the app moves to a sibling origin. It
|
|
22
|
+
does **not** add any Tweak UI yet.
|
|
23
|
+
|
|
24
|
+
**Critical design fact (do not skip): a different origin is still the same
|
|
25
|
+
_site_.** Browser origin includes the port, but *site* does not, so serving the
|
|
26
|
+
app from `host:PORT2` (or a same-registrable-domain subdomain) is a different
|
|
27
|
+
origin yet the **same site** as the wiki UI. Consequences that this ticket MUST
|
|
28
|
+
handle, because they are the real boundary now:
|
|
29
|
+
|
|
30
|
+
- `SameSite` cookies do not stop the app's JS from issuing same-site
|
|
31
|
+
`fetch(..., {credentials:'include'})` against wiki mutating routes. CORS blocks
|
|
32
|
+
reading the response, not the state change. So **every** mutating wiki route
|
|
33
|
+
must enforce an Origin check (`checkOrigin`), and the app-proxy route (which
|
|
34
|
+
does not today) is included.
|
|
35
|
+
- The app page can nest an iframe of the wiki UI itself (session cookie is
|
|
36
|
+
delivered, same-site) and overlay/click the real Accept. So all wiki HTML must
|
|
37
|
+
send `frame-ancestors 'self'` (CSP) / `X-Frame-Options`.
|
|
38
|
+
|
|
39
|
+
The app is served from a sibling **same-site** origin only. A truly cross-site
|
|
40
|
+
`WIKI_APP_ORIGIN` is rejected at boot in v1 (so a `SameSite=Strict` grant cookie
|
|
41
|
+
is still delivered inside the iframe).
|
|
42
|
+
|
|
43
|
+
The origin and injection wiring must be **surface-agnostic**: keyed on "a
|
|
44
|
+
proxied live surface," not hard-wired to node-app-only assumptions, so a future
|
|
45
|
+
proxied surface (for example a dynamic HTML file served through the proxy)
|
|
46
|
+
reuses this path with no new mechanism. The running node app is the first and
|
|
47
|
+
driving consumer, not the only conceivable one.
|
|
48
|
+
|
|
49
|
+
## Acceptance criteria
|
|
50
|
+
|
|
51
|
+
Origin + serving:
|
|
52
|
+
- [ ] Proxied node-apps are served from a dedicated **same-site** origin distinct
|
|
53
|
+
from the wiki-viewer app origin (default: same host, dedicated port;
|
|
54
|
+
overridable via `WIKI_APP_ORIGIN`), and the running app still functions end
|
|
55
|
+
to end (assets, forms, popups, navigation as before).
|
|
56
|
+
- [ ] A cross-site `WIKI_APP_ORIGIN` is rejected at boot with a clear error (v1
|
|
57
|
+
supports same-site sibling origins only).
|
|
58
|
+
- [ ] The isolated-origin listener serves ONLY the app proxy and the grant
|
|
59
|
+
exchange; every other path on that origin 404s (no wiki UI, no `/api/wiki/*`,
|
|
60
|
+
no auth routes reachable there). https mode reuses the existing cert.
|
|
61
|
+
- [ ] When no isolated origin is configured (e.g. `next dev` single-port), Tweak
|
|
62
|
+
on proxied apps is hard-disabled; the code never falls back to injecting the
|
|
63
|
+
picker on the same origin as the wiki UI.
|
|
64
|
+
|
|
65
|
+
Authorization (grant-only on the isolated origin):
|
|
66
|
+
- [ ] The isolated-origin proxy authorizes via a short-lived HMAC grant only; it
|
|
67
|
+
rejects wiki session-cookie and Bearer-API-key auth (ambient credentials
|
|
68
|
+
must not reach it). Cookies continue to be stripped before forwarding
|
|
69
|
+
upstream.
|
|
70
|
+
- [ ] The grant is scoped to `{userId, workspaceId, appRelPath, exp, jti}` and the
|
|
71
|
+
server enforces the requested `?ws` matches the grant workspace and the
|
|
72
|
+
requested path is under `appRelPath` (a grant for app A cannot drive app B).
|
|
73
|
+
- [ ] The grant HMAC key is derived from the server auth secret with a distinct
|
|
74
|
+
label (not reused from another subsystem). The exchange token is one-time
|
|
75
|
+
(server-side jti seen-set) with a short TTL (~60s); it swaps for a
|
|
76
|
+
path-scoped `HttpOnly` cookie on the isolated origin and is never left in a
|
|
77
|
+
logged URL.
|
|
78
|
+
- [ ] Existing workspace access + app-runner permission checks still gate before
|
|
79
|
+
the child process is reached (no regression to path containment or
|
|
80
|
+
workspace isolation).
|
|
81
|
+
|
|
82
|
+
Wiki-origin hardening (load-bearing once the app is a same-site sibling):
|
|
83
|
+
- [ ] Every mutating wiki route enforces `checkOrigin`; the app-proxy route gains
|
|
84
|
+
an Origin check. Verified by an audit test that fails if a mutating
|
|
85
|
+
`/api/wiki/*` or `/api/system/*` route omits it.
|
|
86
|
+
- [ ] All wiki HTML responses send `frame-ancestors 'self'` (CSP) and
|
|
87
|
+
`X-Frame-Options`, so the proxied app cannot frame-and-overlay the wiki UI.
|
|
88
|
+
- [ ] Both the wiki and isolated origins send `Origin-Agent-Cluster: ?1` (closes
|
|
89
|
+
the `document.domain` same-site bridge).
|
|
90
|
+
|
|
91
|
+
Surface-agnostic + docs:
|
|
92
|
+
- [ ] The isolated-origin serving and picker-injection point are surface-agnostic
|
|
93
|
+
(not coupled to node-app-only keying), so another proxied live surface could
|
|
94
|
+
be served through the same path without changing the origin layer.
|
|
95
|
+
- [ ] Tests: grant mint/verify + scope/replay rejection (unit, mirroring the
|
|
96
|
+
shared-docs access-grant tests); isolated listener refuses wiki API/UI;
|
|
97
|
+
proxy rejects missing/expired/mis-scoped grant and rejects session/Bearer;
|
|
98
|
+
the mutating-route Origin-check audit. In-process tests assert these
|
|
99
|
+
server-side contracts; the browser DOM cross-origin guarantee holds by
|
|
100
|
+
construction and is documented as a manual verification step (it cannot be
|
|
101
|
+
asserted in-process).
|
|
102
|
+
- [ ] `docs/ux-contracts.md` and the isometric map (`isometric-codebase-map.json`
|
|
103
|
+
+ `.html`) updated in this same change to describe the isolated proxy origin,
|
|
104
|
+
the grant flow, and the hardening.
|
|
105
|
+
|
|
106
|
+
## Blocked by
|
|
107
|
+
|
|
108
|
+
- None — can start immediately.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
## Parent
|
|
2
|
+
OPS-8 — Spec: Unified live tweak for web surfaces (Impeccable-live model)
|
|
3
|
+
|
|
4
|
+
## What to build
|
|
5
|
+
The live engine's runtime directory is treated as internal runtime state, never as
|
|
6
|
+
user content: it cannot be resolved through path containment, cannot be reached
|
|
7
|
+
through any browser or agent file route, and is never committed. This is the safety
|
|
8
|
+
floor the rest of the feature builds on.
|
|
9
|
+
|
|
10
|
+
## Acceptance criteria
|
|
11
|
+
- [ ] The engine runtime directory segment is denied by the canonical path-containment primitive, alongside the existing denied segments.
|
|
12
|
+
- [ ] File-browser and agent file routes cannot read, list, or write anything inside the engine runtime directory (verified by tests).
|
|
13
|
+
- [ ] The engine runtime directory is gitignored so it is never committed.
|
|
14
|
+
- [ ] Proof tests assert the directory is denied by path resolution and unreachable via file routes. Prior art: app-proxy-auth.test.ts, containment tests.
|
|
15
|
+
- [ ] docs/ux-contracts.md and the isometric codebase map are updated in this same change if this introduces any user-facing or subsystem change.
|
|
16
|
+
|
|
17
|
+
## Blocked by
|
|
18
|
+
None — can start immediately.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
## Parent
|
|
2
|
+
OPS-8 — Spec: Unified live tweak for web surfaces (Impeccable-live model)
|
|
3
|
+
|
|
4
|
+
## What to build
|
|
5
|
+
A single pure string transform that injects the live engine prelude globals plus
|
|
6
|
+
the overlay script tag into a page's HTML at the correct anchor. It is the shared
|
|
7
|
+
mechanism both the static-HTML viewer render and the app-proxy serve-time rewrite
|
|
8
|
+
will reuse, so tweak is enabled without editing any source file.
|
|
9
|
+
|
|
10
|
+
## Acceptance criteria
|
|
11
|
+
- [ ] A pure function injects the prelude globals and the overlay script tag at the correct HTML anchor.
|
|
12
|
+
- [ ] The transform is idempotent (injecting twice yields the same result as once) and does not corrupt surrounding HTML.
|
|
13
|
+
- [ ] The injected globals are parameterized (engine endpoints/token) so callers can point the overlay at either a direct helper or proxied paths later.
|
|
14
|
+
- [ ] Unit-tested as a pure function. Prior art: app-proxy HTML-rewrite tests, web-tweak-picker.test.ts.
|
|
15
|
+
- [ ] docs/ux-contracts.md and the isometric codebase map are updated in this same change if this introduces any user-facing or subsystem change.
|
|
16
|
+
|
|
17
|
+
## Blocked by
|
|
18
|
+
None — can start immediately.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
## Parent
|
|
2
|
+
|
|
3
|
+
OPS-1 — Spec: Tweak on a running app (proxied node-app runtime).
|
|
4
|
+
|
|
5
|
+
## What to build
|
|
6
|
+
|
|
7
|
+
The first complete, demoable Tweak round-trip on a running app: happy path,
|
|
8
|
+
one element, one file.
|
|
9
|
+
|
|
10
|
+
The user opens their running app in the proxied view, enters Tweak mode, points
|
|
11
|
+
at one real element on the live page, types one instruction, and dispatches. The
|
|
12
|
+
attached agent receives the request through the existing poll/reply channel and
|
|
13
|
+
returns one reviewable proposal. The user reviews and Accepts. On Accept,
|
|
14
|
+
wiki-viewer sends an approval to the agent (carrying the proposal identity and
|
|
15
|
+
the base hash captured at proposal time); the agent writes the single source
|
|
16
|
+
file, triggers the app rebuild/reload, and returns a success receipt.
|
|
17
|
+
wiki-viewer records the receipt and the user sees the running app reflect the
|
|
18
|
+
change.
|
|
19
|
+
|
|
20
|
+
Scope is the tracer bullet only: exactly one queued element, one written file,
|
|
21
|
+
success path. Failure/cancel/discard, multi-file, drift refusal, and full batch
|
|
22
|
+
+ parity affordances are separate tickets.
|
|
23
|
+
|
|
24
|
+
The running node app is the concrete driver for this round-trip, but the Tweak
|
|
25
|
+
surface wiring should sit on the surface-agnostic proxied-live-surface
|
|
26
|
+
foundation from ticket 1, not bake in node-app-only assumptions beyond what this
|
|
27
|
+
slice needs.
|
|
28
|
+
|
|
29
|
+
## Acceptance criteria
|
|
30
|
+
|
|
31
|
+
- [ ] The proxied running-app view exposes a Tweak entry point (picker injected
|
|
32
|
+
into the proxied app via the isolated origin from ticket 1).
|
|
33
|
+
- [ ] Selecting one element highlights it as the Tweak target and lets the user
|
|
34
|
+
type an instruction.
|
|
35
|
+
- [ ] Dispatch sends the request over the existing human→agent request channel;
|
|
36
|
+
the agent replies with one reviewable proposal over the existing poll/reply
|
|
37
|
+
channel (no new transport).
|
|
38
|
+
- [ ] Accept transitions the proposal to approval-sent and hands the agent an
|
|
39
|
+
approval carrying the proposal identity and the per-file base hash.
|
|
40
|
+
- [ ] The agent write of a single file, followed by app reload, is reflected in
|
|
41
|
+
the running app; wiki-viewer records a success receipt and shows success.
|
|
42
|
+
- [ ] Route-level proof test in `src/tests/proof/` exercises the full
|
|
43
|
+
dispatch → propose → accept → approval → receipt-success path in process.
|
|
44
|
+
- [ ] `docs/ux-contracts.md` and the isometric map updated in this same change.
|
|
45
|
+
|
|
46
|
+
## Blocked by
|
|
47
|
+
|
|
48
|
+
- Ticket 1 (isolated proxy origin).
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
## Parent
|
|
2
|
+
OPS-8 — Spec: Unified live tweak for web surfaces (Impeccable-live model)
|
|
3
|
+
|
|
4
|
+
## What to build
|
|
5
|
+
A pure transform that turns an accepted variant into clean permanent source:
|
|
6
|
+
locate the engine markers, extract the chosen variant, bake in the tuned knob
|
|
7
|
+
values, and emit the final source with all live-mode scaffolding removed. It
|
|
8
|
+
enforces the speculative-until-Accept invariant by refusing when the base content
|
|
9
|
+
has drifted since the preview began.
|
|
10
|
+
|
|
11
|
+
## Acceptance criteria
|
|
12
|
+
- [ ] A pure function locates markers, extracts the chosen variant, bakes knob values, and produces clean final source with no live-mode leftovers.
|
|
13
|
+
- [ ] Accept is refused when the base content hash no longer matches (drift), and commits verbatim when it matches.
|
|
14
|
+
- [ ] Non-accepted variants and their scaffolding are fully removed from the output.
|
|
15
|
+
- [ ] Unit-tested as a pure function including the drift-refusal and verbatim-commit paths. Prior art: web-tweak-collab.test.ts.
|
|
16
|
+
- [ ] docs/ux-contracts.md and the isometric codebase map are updated in this same change if this introduces any user-facing or subsystem change.
|
|
17
|
+
|
|
18
|
+
## Blocked by
|
|
19
|
+
None — can start immediately.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
## Parent
|
|
2
|
+
|
|
3
|
+
OPS-1 — Spec: Tweak on a running app (proxied node-app runtime).
|
|
4
|
+
|
|
5
|
+
## What to build
|
|
6
|
+
|
|
7
|
+
Make the running-app Tweak run survive the unhappy paths, reusing the same
|
|
8
|
+
recovery discipline the markdown/HTML surfaces already have (core parity).
|
|
9
|
+
|
|
10
|
+
Covers the failure and control transitions layered on the tracer bullet:
|
|
11
|
+
|
|
12
|
+
- **Receipt-failed**: when the agent's write receipt reports failure, the user
|
|
13
|
+
sees a clear reason, the queue is preserved, and the same proposal can be
|
|
14
|
+
retried without re-describing it.
|
|
15
|
+
- **Cancel run**: while a run waits on the agent, the user can cancel it, which
|
|
16
|
+
frees the single outstanding slot and writes nothing.
|
|
17
|
+
- **Discard proposal**: the user can discard a returned proposal; the app source
|
|
18
|
+
is left byte-identical.
|
|
19
|
+
- **Single-outstanding enforcement**: dispatching while a run is already
|
|
20
|
+
outstanding is cleanly rejected and the queued work is not lost.
|
|
21
|
+
|
|
22
|
+
## Acceptance criteria
|
|
23
|
+
|
|
24
|
+
- [ ] A failure receipt surfaces a clear reason, preserves the queue, and allows
|
|
25
|
+
retry of the same proposal (state returns to a retryable point, not lost).
|
|
26
|
+
- [ ] Cancel while waiting on the agent frees the outstanding slot and performs
|
|
27
|
+
no write.
|
|
28
|
+
- [ ] Discard leaves the app source byte-identical (verified by hash/no-op).
|
|
29
|
+
- [ ] A second dispatch while one run is outstanding is rejected with a clear
|
|
30
|
+
message and the queue is preserved.
|
|
31
|
+
- [ ] Route-level proof tests cover receipt-failure retry, cancel, discard, and
|
|
32
|
+
the outstanding-run rejection.
|
|
33
|
+
- [ ] `docs/ux-contracts.md` and the isometric map updated in this same change.
|
|
34
|
+
|
|
35
|
+
## Blocked by
|
|
36
|
+
|
|
37
|
+
- Ticket 2 (tracer bullet round-trip).
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
## Parent
|
|
2
|
+
|
|
3
|
+
OPS-1 — Spec: Tweak on a running app (proxied node-app runtime).
|
|
4
|
+
|
|
5
|
+
## What to build
|
|
6
|
+
|
|
7
|
+
Let a single accepted running-app tweak span multiple source files, and enforce
|
|
8
|
+
the write-safety guarantees every other wiki-viewer write already honors.
|
|
9
|
+
|
|
10
|
+
- **Multi-file write**: lift the v1 "candidate must edit exactly one file" cap
|
|
11
|
+
for this flow. Because the agent owns the write, an accepted tweak may
|
|
12
|
+
legitimately touch several files; the approval carries per-file base hashes.
|
|
13
|
+
- **Drift / stale refusal**: if any underlying source file changed since the
|
|
14
|
+
proposal was made (base-hash mismatch at approval time), the write is refused
|
|
15
|
+
(invalidated) rather than silently clobbering a concurrent edit.
|
|
16
|
+
- **Containment + isolation**: every written path is validated through the
|
|
17
|
+
canonical path-containment primitive and stays inside the target workspace.
|
|
18
|
+
- **File-vs-collab safety**: a `.md` file a human currently has open (`active`
|
|
19
|
+
collab state) is never overwritten by a proxied-app tweak write.
|
|
20
|
+
|
|
21
|
+
## Acceptance criteria
|
|
22
|
+
|
|
23
|
+
- [ ] An accepted tweak can write more than one file in a single approval, with
|
|
24
|
+
per-file base hashes carried on the approval.
|
|
25
|
+
- [ ] A base-hash mismatch on any file at approval time refuses the whole write
|
|
26
|
+
(invalidated, no partial write) and reports it to the user.
|
|
27
|
+
- [ ] Every written path is resolved through `resolveWorkspacePath` and cannot
|
|
28
|
+
escape the workspace (traversal / symlink / absolute path rejected).
|
|
29
|
+
- [ ] A write targeting a `.md` file in `active` collab state is rejected in
|
|
30
|
+
honor of file-vs-collab authority.
|
|
31
|
+
- [ ] Route-level proof tests cover multi-file success, drift refusal, a
|
|
32
|
+
containment escape attempt, and the collab-active rejection.
|
|
33
|
+
- [ ] `docs/ux-contracts.md` and the isometric map updated in this same change.
|
|
34
|
+
|
|
35
|
+
## Blocked by
|
|
36
|
+
|
|
37
|
+
- Ticket 2 (tracer bullet round-trip).
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
## Parent
|
|
2
|
+
OPS-8 — Spec: Unified live tweak for web surfaces (Impeccable-live model)
|
|
3
|
+
|
|
4
|
+
## What to build
|
|
5
|
+
The complete unified live-tweak spine, proven end to end on the simplest surface:
|
|
6
|
+
a static HTML file, localhost. The user opens a static `.html` in wiki-viewer,
|
|
7
|
+
points at an element, picks an action or types an instruction, hits Go, gets 2 to 5
|
|
8
|
+
variants with tunable knobs, cycles and tunes them with instant client-side
|
|
9
|
+
feedback, and Accepts the chosen variant into the file (or Discards to restore the
|
|
10
|
+
original). This is the tracer bullet: it wires together the engine helper
|
|
11
|
+
lifecycle, the overlay injection (02), the product-side poll loop / live bridge,
|
|
12
|
+
the existing attached-agent channel for variant generation, and the accept mutator
|
|
13
|
+
(03) through wiki-viewer's own writer. It is a deliberate serialization point; the
|
|
14
|
+
wider surfaces build on it.
|
|
15
|
+
|
|
16
|
+
## Acceptance criteria
|
|
17
|
+
- [ ] wiki-viewer spawns, supervises (health, stop), and tears down the engine helper for a static-file tweak session, keyed per surface like the node-app runner keys apps.
|
|
18
|
+
- [ ] The overlay is injected into the static-file render via the transform from ticket 02; the picker highlights elements and offers named actions plus freeform.
|
|
19
|
+
- [ ] A product-side poll loop (the live bridge) translates engine generate/steer/accept/discard events into the existing live-store request kinds and back, honoring one-outstanding-per-session and idempotent replay.
|
|
20
|
+
- [ ] A generate request is fulfilled by the user's existing attached agent; 2 to 5 variants with 0 to 4 knobs each appear via instant client-side swap (no reload).
|
|
21
|
+
- [ ] Accept writes the chosen variant (with baked knob values) into the file through wiki-viewer's writer + path containment + write lock, only on matching base hash; Discard restores the original exactly; nothing writes before Accept.
|
|
22
|
+
- [ ] An interrupted session (reload/disconnect) recovers to a safe state via the engine journal rather than leaving half-applied variants.
|
|
23
|
+
- [ ] Proof tests drive the bridge at the route-handler level asserting the reconciled state machine, write-on-accept-only, and drift refusal. Prior art: live-collab.test.ts, web-tweak-collab.test.ts.
|
|
24
|
+
- [ ] docs/ux-contracts.md (§1.4 area) and the isometric codebase map are updated in this same change to describe the unified static-HTML flow.
|
|
25
|
+
|
|
26
|
+
## Blocked by
|
|
27
|
+
01, 02, 03.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
## Parent
|
|
2
|
+
|
|
3
|
+
OPS-1 — Spec: Tweak on a running app (proxied node-app runtime).
|
|
4
|
+
|
|
5
|
+
## What to build
|
|
6
|
+
|
|
7
|
+
Bring the running-app Tweak surface to full **core parity** with the existing
|
|
8
|
+
markdown and HTML surfaces: batch queueing and the shared affordances.
|
|
9
|
+
|
|
10
|
+
- **Batch queue**: queue several element tweaks before dispatching and send them
|
|
11
|
+
as one batch; the agent returns one reviewable proposal per queued item.
|
|
12
|
+
- **Select-again-to-update**: re-selecting an already-queued element updates its
|
|
13
|
+
instruction in place rather than inflating the queued count.
|
|
14
|
+
- **Remove one**: drop a single queued tweak without losing the rest; Cancel-all
|
|
15
|
+
clears the whole queue without dispatching.
|
|
16
|
+
- **Presence indicator**: show whether an agent is listening.
|
|
17
|
+
- **Connect-an-agent**: with queued tweaks but no attached agent, the dispatch
|
|
18
|
+
button becomes "Connect an agent" and opens the agent panel without losing the
|
|
19
|
+
queue.
|
|
20
|
+
- **Surface-specific dispatch label**: the dispatch button carries a label that
|
|
21
|
+
reads naturally on the running-app surface (parity with markdown "Rewrite" /
|
|
22
|
+
HTML "Apply").
|
|
23
|
+
- **Per-item review**: the user reviews and Accepts/Discards each item's proposal
|
|
24
|
+
independently.
|
|
25
|
+
|
|
26
|
+
## Acceptance criteria
|
|
27
|
+
|
|
28
|
+
- [ ] Multiple element tweaks can be queued and dispatched as one batch; the
|
|
29
|
+
agent returns one proposal per item, each independently reviewable.
|
|
30
|
+
- [ ] Re-selecting a queued element updates its instruction in place (queued
|
|
31
|
+
count unchanged); a single queued tweak can be removed; Cancel-all clears
|
|
32
|
+
the queue without dispatching.
|
|
33
|
+
- [ ] Presence indicator reflects agent-listening state; with no agent the
|
|
34
|
+
dispatch button becomes "Connect an agent" and opens the panel, queue
|
|
35
|
+
intact.
|
|
36
|
+
- [ ] The dispatch button shows the surface-specific label.
|
|
37
|
+
- [ ] Route-level / component proof tests cover batch dispatch, in-place update,
|
|
38
|
+
remove-one, and the no-agent Connect affordance.
|
|
39
|
+
- [ ] `docs/ux-contracts.md` and the isometric map updated in this same change.
|
|
40
|
+
|
|
41
|
+
## Blocked by
|
|
42
|
+
|
|
43
|
+
- Ticket 2 (tracer bullet round-trip).
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
## Parent
|
|
2
|
+
OPS-8 — Spec: Unified live tweak for web surfaces (Impeccable-live model)
|
|
3
|
+
|
|
4
|
+
## What to build
|
|
5
|
+
Extend the unified live tweak to running node apps viewed through the proxy. The
|
|
6
|
+
overlay is injected at proxy serve time so the tweak surface is available on the
|
|
7
|
+
app's own page. After Go, the page performs one full reload through the proxy to
|
|
8
|
+
render the freshly written variants; the overlay re-attaches automatically. After
|
|
9
|
+
that single reload, cycling and knob-tuning stay instant and client-side. Accept
|
|
10
|
+
writes to the true template/component source, never a generated build output.
|
|
11
|
+
|
|
12
|
+
## Acceptance criteria
|
|
13
|
+
- [ ] The overlay is injected into proxied app HTML at serve time (reusing ticket 02), only where the user is authorized for the workspace and app-runner permissions allow.
|
|
14
|
+
- [ ] After a generate on a compiled app, a single full-reload-through-proxy renders the variants and the overlay re-attaches via its durable per-origin session.
|
|
15
|
+
- [ ] Cycling variants and tuning knobs after the reload are instant and client-side (variants already present in the page).
|
|
16
|
+
- [ ] Accept writes to true source; generated/build-output files are guarded and routed to the real template/component via the fallback path.
|
|
17
|
+
- [ ] Node-app launching remains gated by the existing app-runner permission model (no change to who may start apps).
|
|
18
|
+
- [ ] Proof tests cover injection authorization and the accept-to-true-source path. Prior art: app-proxy-auth.test.ts, web-tweak-collab.test.ts.
|
|
19
|
+
- [ ] docs/ux-contracts.md and the isometric codebase map are updated in this same change to describe the dynamic/node-app flow, including the one-reload behavior.
|
|
20
|
+
|
|
21
|
+
## Blocked by
|
|
22
|
+
04.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
## Parent
|
|
2
|
+
OPS-8 — Spec: Unified live tweak for web surfaces (Impeccable-live model)
|
|
3
|
+
|
|
4
|
+
## What to build
|
|
5
|
+
Make the tweak overlay work when wiki-viewer is served remotely, not just on
|
|
6
|
+
localhost. The overlay runs on wiki-viewer's origin but the browser may be on a
|
|
7
|
+
different machine than the engine helper, so the engine endpoints the overlay
|
|
8
|
+
needs are exposed through wiki-viewer's own origin, and the injected globals point
|
|
9
|
+
the overlay at those proxied paths instead of a hardcoded local helper port.
|
|
10
|
+
|
|
11
|
+
## Acceptance criteria
|
|
12
|
+
- [ ] The overlay bundle, event downlink (SSE), event uplink, source read, design-system read, and annotation upload are all reachable through wiki-viewer's own origin.
|
|
13
|
+
- [ ] The injected globals (ticket 02) point the overlay at the proxied paths so it never depends on the browser reaching the helper's local port directly.
|
|
14
|
+
- [ ] The proxied endpoints enforce wiki-viewer session/agent authorization and the existing CSRF Origin checks; unauthorized access is rejected.
|
|
15
|
+
- [ ] Both static-HTML and node-app tweak sessions function with wiki-viewer served on a non-localhost origin.
|
|
16
|
+
- [ ] Proof tests assert auth/CSRF enforcement on the proxied engine endpoints. Prior art: app-proxy-auth.test.ts.
|
|
17
|
+
- [ ] docs/ux-contracts.md and the isometric codebase map are updated in this same change.
|
|
18
|
+
|
|
19
|
+
## Blocked by
|
|
20
|
+
04.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
## Parent
|
|
2
|
+
OPS-8 — Spec: Unified live tweak for web surfaces (Impeccable-live model)
|
|
3
|
+
|
|
4
|
+
## What to build
|
|
5
|
+
Remove the previous bespoke static-HTML tweak flow (opaque-origin sandbox, DOM-ops
|
|
6
|
+
picker, "Iterate" variants) and its supporting code and tests, so there is a single
|
|
7
|
+
unified tweak behavior rather than two. The unified flow from ticket 04 fully covers
|
|
8
|
+
the static-HTML case before this deletion lands.
|
|
9
|
+
|
|
10
|
+
## Acceptance criteria
|
|
11
|
+
- [ ] The bespoke web-tweak request/resolve/picker/preview/accept paths that the unified flow replaces are removed, along with their now-dead tests.
|
|
12
|
+
- [ ] No user-facing static-HTML tweak capability regresses relative to the unified flow.
|
|
13
|
+
- [ ] The full test suite passes and the test floor is updated only via the sanctioned path.
|
|
14
|
+
- [ ] docs/ux-contracts.md is updated to remove the retired §1.4 bespoke behavior and reflect only the unified flow; the isometric codebase map is updated to drop the retired subsystem.
|
|
15
|
+
|
|
16
|
+
## Blocked by
|
|
17
|
+
04.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
## Purpose
|
|
2
|
+
|
|
3
|
+
The live "tweak" collaboration engine (web + markdown live-instruct) is being
|
|
4
|
+
**removed** (see the tweak-engine removal commits). The tweak *interaction* was
|
|
5
|
+
genuinely pleasant and should be rebuilt later on top of the existing
|
|
6
|
+
comments/suggestions (sidecar "proof") engine, so there is exactly one
|
|
7
|
+
collaboration engine underneath. This ticket captures everything needed to
|
|
8
|
+
resurrect the UX. **No design work is scoped here yet.**
|
|
9
|
+
|
|
10
|
+
## Recovery pointer
|
|
11
|
+
|
|
12
|
+
- git tag **`pre-tweak-removal`** = commit `056fd01` — the last commit where the
|
|
13
|
+
tweak UX exists in full. Recover any file via
|
|
14
|
+
`git show pre-tweak-removal:<path>`.
|
|
15
|
+
|
|
16
|
+
## Reusable chrome to resurrect (surface-agnostic)
|
|
17
|
+
|
|
18
|
+
- `src/components/editor/tweak/tweak-overlay.tsx` — thin shell (targeting + queue bar + run panel)
|
|
19
|
+
- `src/components/editor/tweak/tweak-queue-bar.tsx` — fixed bottom-center queue bar, per-item remove, Cancel-clears-all, dispatch label, extras slot
|
|
20
|
+
- `src/components/editor/tweak/tweak-queue.ts` — queue model (dedup by targetKey)
|
|
21
|
+
- `src/components/editor/tweak/use-tweak-session.ts` — session/phase state, add/update-in-place, presence gate
|
|
22
|
+
- `src/components/editor/tweak/tweak-types.ts` — the `ContentKindAdapter` pattern (contentKind, dispatchLabel, items, onDispatch, renderTargeting, renderRunPanel, renderQueueBarExtras)
|
|
23
|
+
- **Copy-as-prompt** (already built): `buildPrompt()` / `handleCopyPrompt` in
|
|
24
|
+
`adapters/markdown-adapter.tsx:218` and `adapters/html-adapter.tsx:388`
|
|
25
|
+
("Edit the file X … Apply these changes: 1. <snippet>: <instruction> …"),
|
|
26
|
+
secure-context clipboard gate + textarea fallback.
|
|
27
|
+
|
|
28
|
+
## UX contract (verbatim extraction from docs/ux-contracts.md pre-removal)
|
|
29
|
+
|
|
30
|
+
### Tweak queue (shared across surfaces) — §1.2
|
|
31
|
+
|
|
32
|
+
The user-facing feature is **Tweak**. In the editor action menu, **Comment**
|
|
33
|
+
starts a discussion/annotation, **Suggest** proposes a human edit for review, and
|
|
34
|
+
**Tweak** asks the AI to rewrite the selected target. A Tweak is first added to a
|
|
35
|
+
queue. Selecting the same target again updates its queued instruction and snippet
|
|
36
|
+
in place, so the count does not increase. Users can remove one queued item or
|
|
37
|
+
choose **Cancel** to clear all queued selections without dispatching. Clicking
|
|
38
|
+
outside while an instruction input is empty equals **Cancel**. The dispatch button
|
|
39
|
+
label is surface-specific. Queue bars also offer **Copy as prompt** and **Show**
|
|
40
|
+
fallback controls. When no agent is attached, dispatch becomes **Connect an
|
|
41
|
+
agent**.
|
|
42
|
+
|
|
43
|
+
### Markdown targets — §1.3 (interaction only; the live-dispatch mechanics are being removed)
|
|
44
|
+
|
|
45
|
+
Target is a rendered **block** (paragraph, heading, list item), with an optional
|
|
46
|
+
in-block text selection carried only as context. Markdown/text gather queued
|
|
47
|
+
targets before dispatch (batch, no immediate single-target dispatch). Previews
|
|
48
|
+
are ephemeral; **Accept** is the only write (write-on-accept), gated on the
|
|
49
|
+
block's base hash with drift refusal. Cancel discards without writing.
|
|
50
|
+
|
|
51
|
+
### Web targets — §1.4 (interaction only; the live engine is being removed)
|
|
52
|
+
|
|
53
|
+
Point at an element, say what you want, see a few variants to compare and tune
|
|
54
|
+
(knobs), Accept one into source. Previews speculative; Accept is the only write,
|
|
55
|
+
with containment + base-drift protection.
|
|
56
|
+
|
|
57
|
+
## Design direction (deferred — do NOT implement without a fresh spec)
|
|
58
|
+
|
|
59
|
+
Fold the above UX onto the sidecar comments/suggestions engine: the dispatch
|
|
60
|
+
button persists each queued item as an instruction-comment
|
|
61
|
+
(`comment.add {kind:"instruction"}`) via `POST /api/agent/files`, which the user's
|
|
62
|
+
agent picks up through its normal snapshot/activity flow and answers with
|
|
63
|
+
suggestions (reviewed in the existing `suggestion-card`). Copy-as-prompt stays as
|
|
64
|
+
the no-agent escape hatch.
|
|
65
|
+
|
|
66
|
+
**Open default (undecided):** does the tweak action default to creating an
|
|
67
|
+
instruction-comment (durable, agent picks up on its own schedule) or copy-as-prompt
|
|
68
|
+
only? PM leaned copy-as-prompt for simplicity; implementer leaned instruction-comment
|
|
69
|
+
default with copy-as-prompt as the escape hatch. Decide when this is specced.
|
|
70
|
+
|
|
71
|
+
## Out of scope
|
|
72
|
+
|
|
73
|
+
Any code here. This is a capture-only ticket. Removal of the live tweak engine
|
|
74
|
+
lands separately; this ticket is picked up later for the re-home design.
|