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.
Files changed (124) hide show
  1. package/.next/standalone/.next/BUILD_ID +1 -1
  2. package/.next/standalone/.next/build-manifest.json +3 -3
  3. package/.next/standalone/.next/prerender-manifest.json +3 -3
  4. package/.next/standalone/.next/required-server-files.json +4 -4
  5. package/.next/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  6. package/.next/standalone/.next/server/app/_global-error.html +1 -1
  7. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  8. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  9. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  10. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  11. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  12. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  13. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  14. package/.next/standalone/.next/server/app/api/agent/activity/route.js.nft.json +1 -1
  15. package/.next/standalone/.next/server/app/api/agent/events/[...path]/route.js.nft.json +1 -1
  16. package/.next/standalone/.next/server/app/api/agent/files/[...path]/route.js.nft.json +1 -1
  17. package/.next/standalone/.next/server/app/api/agent/fs/file/[...path]/route.js.nft.json +1 -1
  18. package/.next/standalone/.next/server/app/api/agent/fs/ls/[[...path]]/route.js.nft.json +1 -1
  19. package/.next/standalone/.next/server/app/api/agent/fs/move/route.js.nft.json +1 -1
  20. package/.next/standalone/.next/server/app/api/agent/fs/search/route.js.nft.json +1 -1
  21. package/.next/standalone/.next/server/app/api/agent/settings/route.js.nft.json +1 -1
  22. package/.next/standalone/.next/server/app/api/agent/sidecar/[...path]/route.js.nft.json +1 -1
  23. package/.next/standalone/.next/server/app/api/app-proxy/[...path]/route.js.nft.json +1 -1
  24. package/.next/standalone/.next/server/app/api/assets/[...path]/route.js.nft.json +1 -1
  25. package/.next/standalone/.next/server/app/api/pdf/save/route.js.nft.json +1 -1
  26. package/.next/standalone/.next/server/app/api/share/[token]/asset/route.js.nft.json +1 -1
  27. package/.next/standalone/.next/server/app/api/share/[token]/route.js.nft.json +1 -1
  28. package/.next/standalone/.next/server/app/api/share/route.js.nft.json +1 -1
  29. package/.next/standalone/.next/server/app/api/system/browse/route.js.nft.json +1 -1
  30. package/.next/standalone/.next/server/app/api/system/reveal/route.js.nft.json +1 -1
  31. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/branch/route.js.nft.json +1 -1
  32. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/open/route.js.nft.json +1 -1
  33. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/refresh/route.js.nft.json +1 -1
  34. package/.next/standalone/.next/server/app/api/system/workspaces/[id]/route.js.nft.json +1 -1
  35. package/.next/standalone/.next/server/app/api/system/workspaces/route.js.nft.json +1 -1
  36. package/.next/standalone/.next/server/app/api/upload/[...path]/route.js.nft.json +1 -1
  37. package/.next/standalone/.next/server/app/api/wiki/app/route.js.nft.json +1 -1
  38. package/.next/standalone/.next/server/app/api/wiki/backlinks/route.js.nft.json +1 -1
  39. package/.next/standalone/.next/server/app/api/wiki/content/route.js.nft.json +1 -1
  40. package/.next/standalone/.next/server/app/api/wiki/download/route.js.nft.json +1 -1
  41. package/.next/standalone/.next/server/app/api/wiki/folder/route.js.nft.json +1 -1
  42. package/.next/standalone/.next/server/app/api/wiki/git-branches/route.js.nft.json +1 -1
  43. package/.next/standalone/.next/server/app/api/wiki/git-checkout/route.js.nft.json +1 -1
  44. package/.next/standalone/.next/server/app/api/wiki/git-diff/route.js.nft.json +1 -1
  45. package/.next/standalone/.next/server/app/api/wiki/git-file-info/route.js.nft.json +1 -1
  46. package/.next/standalone/.next/server/app/api/wiki/git-history/route.js.nft.json +1 -1
  47. package/.next/standalone/.next/server/app/api/wiki/git-pull/route.js.nft.json +1 -1
  48. package/.next/standalone/.next/server/app/api/wiki/move/route.js.nft.json +1 -1
  49. package/.next/standalone/.next/server/app/api/wiki/new-file/route.js.nft.json +1 -1
  50. package/.next/standalone/.next/server/app/api/wiki/outlinks/route.js.nft.json +1 -1
  51. package/.next/standalone/.next/server/app/api/wiki/page/route.js.nft.json +1 -1
  52. package/.next/standalone/.next/server/app/api/wiki/presence/route.js.nft.json +1 -1
  53. package/.next/standalone/.next/server/app/api/wiki/route.js.nft.json +1 -1
  54. package/.next/standalone/.next/server/app/api/wiki/scratch/route.js.nft.json +1 -1
  55. package/.next/standalone/.next/server/app/api/wiki/search/route.js.nft.json +1 -1
  56. package/.next/standalone/.next/server/app/api/wiki/slugs/route.js.nft.json +1 -1
  57. package/.next/standalone/.next/server/app/api/wiki/upload/route.js.nft.json +1 -1
  58. package/.next/standalone/.next/server/app/api/wiki/watch/route.js.nft.json +1 -1
  59. package/.next/standalone/.next/server/app/page/react-loadable-manifest.json +4 -5
  60. package/.next/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  61. package/.next/standalone/.next/server/app/s/[token]/page_client-reference-manifest.js +1 -1
  62. package/.next/standalone/.next/server/app/signin/page_client-reference-manifest.js +1 -1
  63. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ltsov-._.js +1 -1
  64. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_system_workspaces_[id]_open_route_actions_1087xu7.js +1 -1
  65. package/.next/standalone/.next/server/chunks/ssr/0.u4_next_0kf.7hj._.js +1 -1
  66. package/.next/standalone/.next/server/chunks/ssr/0.u4_next_dist_0xugq-k._.js +1 -1
  67. package/.next/standalone/.next/server/chunks/ssr/12y~_mermaid_dist_chunks_mermaid_core_chunk-5ZQYHXKU_mjs_0z1.978._.js +1 -1
  68. package/.next/standalone/.next/server/chunks/ssr/12y~_mermaid_dist_chunks_mermaid_core_chunk-KSCS5N6A_mjs_0v4oeem._.js +1 -1
  69. package/.next/standalone/.next/server/chunks/ssr/_01eqklo._.js +1 -1
  70. package/.next/standalone/.next/server/chunks/ssr/_0858xdh._.js +1 -1
  71. package/.next/standalone/.next/server/chunks/ssr/_0k6g8yo._.js +3 -3
  72. package/.next/standalone/.next/server/chunks/ssr/_0sr4wj.._.js +1 -1
  73. package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_06613~i._.js +1 -1
  74. package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0o~d81.._.js +1 -1
  75. package/.next/standalone/.next/server/chunks/ssr/node_modules__pnpm_0szp2v0._.js +1 -1
  76. package/.next/standalone/.next/server/middleware-build-manifest.js +3 -3
  77. package/.next/standalone/.next/server/pages/500.html +1 -1
  78. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  79. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  80. package/.next/standalone/.next/static/chunks/0.5ywu7_j899v.js +12 -0
  81. package/.next/standalone/.next/static/chunks/{0tjcc1wg-57l1.js → 065s1_n.1k11t.js} +1 -1
  82. package/.next/standalone/.next/static/chunks/{0y~5s_skz1l9a.js → 0ccw-uc_3ao.w.js} +1 -1
  83. package/.next/standalone/.next/static/chunks/{0ii.akeq7k4pf.js → 0f8kfd9d6kq0b.js} +1 -1
  84. package/.next/standalone/.next/static/chunks/0lsw6lsaj7lby.js +1 -0
  85. package/.next/standalone/.next/static/chunks/0rpxacw15~o7k.js +12 -0
  86. package/.next/standalone/.next/static/chunks/{0r7d-1tq61fa1.js → 0s2h7kvkrtq~p.js} +1 -1
  87. package/.next/standalone/.next/static/chunks/{0enm-3xy21jcx.js → 0tzi1~wpigp2y.js} +2 -2
  88. package/.next/standalone/.next/static/chunks/117dkzyg4c~us.js +1 -0
  89. package/.next/standalone/.next/static/chunks/{0j7kp7w2oum68.js → 11pa_9ucyrzh9.js} +1 -1
  90. package/.next/standalone/.scratch/tweak-running-app/craft-checklist.md +52 -0
  91. package/.next/standalone/.scratch/tweak-running-app/issues/01-isolated-origin.md +108 -0
  92. package/.next/standalone/.scratch/tweak-running-app/issues/01-runtime-containment.md +18 -0
  93. package/.next/standalone/.scratch/tweak-running-app/issues/02-injection-transform.md +18 -0
  94. package/.next/standalone/.scratch/tweak-running-app/issues/02-tracer-bullet.md +48 -0
  95. package/.next/standalone/.scratch/tweak-running-app/issues/03-accept-carbonize-mutator.md +19 -0
  96. package/.next/standalone/.scratch/tweak-running-app/issues/03-run-robustness.md +37 -0
  97. package/.next/standalone/.scratch/tweak-running-app/issues/04-multifile-safety.md +37 -0
  98. package/.next/standalone/.scratch/tweak-running-app/issues/04-static-tracer-bullet.md +27 -0
  99. package/.next/standalone/.scratch/tweak-running-app/issues/05-batch-parity.md +43 -0
  100. package/.next/standalone/.scratch/tweak-running-app/issues/05-dynamic-node-app.md +22 -0
  101. package/.next/standalone/.scratch/tweak-running-app/issues/06-remote-transport-bridge.md +20 -0
  102. package/.next/standalone/.scratch/tweak-running-app/issues/07-retire-bespoke-web-tweak.md +17 -0
  103. package/.next/standalone/.scratch/tweak-running-app/keep-ticket.md +74 -0
  104. package/.next/standalone/.scratch/tweak-running-app/mockups.html +305 -0
  105. package/.next/standalone/.scratch/tweak-running-app/ops1-updated.md +215 -0
  106. package/.next/standalone/.scratch/tweak-running-app/ops12-continuation.md +44 -0
  107. package/.next/standalone/.scratch/tweak-running-app/ops22-context.md +84 -0
  108. package/.next/standalone/.scratch/tweak-running-app/pivot-note.md +25 -0
  109. package/.next/standalone/.scratch/tweak-running-app/qa-live-engine.ts +104 -0
  110. package/.next/standalone/.scratch/tweak-running-app/spike.md +256 -0
  111. package/.next/standalone/.scratch/tweak-running-app/suggest-current-assessment.md +39 -0
  112. package/.next/standalone/.scratch/tweak-running-app/suggest-inline-interaction-spec.md +320 -0
  113. package/.next/standalone/.scratch/tweak-running-app/tweak-interaction-spec.md +161 -0
  114. package/.next/standalone/.scratch/tweak-running-app/two-actions-interaction-spec.md +234 -0
  115. package/.next/standalone/.scratch/tweak-running-app/unified-live-spec.md +261 -0
  116. package/.next/standalone/package.json +1 -1
  117. package/.next/standalone/server.js +1 -1
  118. package/package.json +1 -1
  119. package/.next/standalone/.next/static/chunks/04jvwlttwa_sw.js +0 -12
  120. package/.next/standalone/.next/static/chunks/161kgz.8h.3iq.js +0 -1
  121. package/.next/standalone/.next/static/chunks/16kzqur8~yg6b.js +0 -12
  122. /package/.next/standalone/.next/static/{7EbGXTo8ObPhr7UobKARQ → zwUX5EOT_44n1RoB_W9Bo}/_buildManifest.js +0 -0
  123. /package/.next/standalone/.next/static/{7EbGXTo8ObPhr7UobKARQ → zwUX5EOT_44n1RoB_W9Bo}/_clientMiddlewareManifest.js +0 -0
  124. /package/.next/standalone/.next/static/{7EbGXTo8ObPhr7UobKARQ → zwUX5EOT_44n1RoB_W9Bo}/_ssgManifest.js +0 -0
@@ -0,0 +1,234 @@
1
+ > SUPERSEDED (2026-08-23): the "Ask agent" composer mode, the instruction-comment
2
+ > dispatch/lifecycle, and the pending/answered cards below are NO LONGER in scope.
3
+ > Per user direction there is NO agent-triggering. The re-home is: Comment +
4
+ > Suggest with better UX, plus a Copy-as-prompt surface that serializes EXISTING
5
+ > comments/suggestions. Authoritative current design: ../tweak-running-app/mockups.html
6
+ > + suggest-inline-interaction-spec.md + craft-checklist.md. Keep this file only
7
+ > for the parts still valid (two-actions framing, copy-as-prompt string format,
8
+ > dedup-by-reply reasoning).
9
+
10
+ # Tweak UX ported into Comment + Suggest — interaction spec (OPS-22, rev 2)
11
+
12
+ Reference-only design artifact. Supersedes `tweak-interaction-spec.md` decision A
13
+ (third button — REJECTED). Decisions B/C/D/E of that spec are carried forward and
14
+ re-attached to the two existing actions. Bubble menu stays exactly:
15
+
16
+ ```
17
+ [ B I U S <> | sup sub | link | 💬 Comment ✎ Suggest ]
18
+ ```
19
+
20
+ - **Comment** = talk about this target — to a human *or* to an agent (one-line semantics).
21
+ - **Suggest** = an edit to review — written by a human, *or* arrived from an agent.
22
+
23
+ Nothing in the chrome changes count. What changes is what Comment's composer can
24
+ produce and how Suggest's card can be reached.
25
+
26
+ ---
27
+
28
+ ## 1. The mapping — which ported affordance lives where
29
+
30
+ ### Comment absorbs (human → agent intent)
31
+
32
+ | Ported affordance | Where it lands in Comment |
33
+ |---|---|
34
+ | Targeting panel "What should change?" | The comment composer's **instruction mode** (see §2). Same anchor-to-block geometry. |
35
+ | "Ask agent" dispatch | Composer primary button when in instruction mode. Writes `comment.add {kind:"instruction", instructionState:"queued"}` immediately. No queue step. |
36
+ | Copy-as-prompt | Secondary button inside the composer footer, and on every pending/answered instruction card (§3, §7). |
37
+ | Connect-an-agent | Replaces primary-button label in instruction mode when no agent attached; opens AI panel; instruction already persisted so nothing is lost (§7 no-agent state). |
38
+ | Dedup / re-target | Re-targeting a block with a pending instruction opens its existing thread, not a new composer (§6). |
39
+ | Doc-level "N pending" chip | Toolbar chip counts pending **instruction-kind comments**; click jumps to first. Replaces the deleted queue bar's only real value. |
40
+
41
+ ### Suggest absorbs (agent → human review)
42
+
43
+ | Ported affordance | Where it lands in Suggest |
44
+ |---|---|
45
+ | The agent's rewrite | Arrives as ordinary `suggestion.add` (replace/insert/delete), reviewed in the existing `suggestion-card.tsx`. No UI change to the card's Accept/Reject mechanics. |
46
+ | Linkage to intent | Card header gains one optional line above the reason: `In response to: "<instruction text>"` when the suggestion carries `fromInstructionId` (open question 2 from prior spec — recommend the explicit field). |
47
+ | Settling the instruction | Accept **or** Reject of the linked suggestion flips the instruction to `answered`/resolved. Agent clarification without a suggestion lands as a reply on the instruction thread instead. |
48
+
49
+ ### Volunteered improvement over the "likely shape" in the brief
50
+
51
+ The brief's shape is confirmed, with one sharpening: **Suggest itself stays
52
+ human-only as an entry point.** The bubble-menu Suggest button keeps its current
53
+ meaning (human proposes an edit). The agent never needs an entry point — it
54
+ writes to the sidecar directly. So "Suggest absorbs the agent rewrite" means the
55
+ *suggestion surface* (card + review loop) absorbs it, not the Suggest button.
56
+ This keeps both buttons' semantics single-clause and avoids implying the user
57
+ can click Suggest to summon an agent.
58
+
59
+ Resulting one-liners:
60
+
61
+ - **Comment — "say something about this: discuss it, or tell your agent what to change."**
62
+ - **Suggest — "review a proposed edit: yours, or your agent's answer."**
63
+
64
+ ---
65
+
66
+ ## 2. One composer, two kinds — the kind picker
67
+
68
+ **Decision: ONE composer. A two-option segmented control at the top of the
69
+ composer, defaulting to the context-appropriate segment.**
70
+
71
+ Not two buttons, not a kind dropdown buried in a menu, not a magic prefix
72
+ ("@agent"). A segmented control because: the choice is binary, both options must
73
+ be visible before typing (the user's mental model of *who reads this* shapes
74
+ what they write), and it must be flippable mid-draft without losing text.
75
+
76
+ Default segment rule (resolves the open decision):
77
+
78
+ - **Selection has no agent attached and file is markdown → default "Ask agent" is NOT the default.** Default = **Discuss** (plain comment). Rationale: the dominant, established Comment path pays zero new friction; the instruction path is one click away and its controls (targeting placeholder, footer) teach it on hover.
79
+ - **If the user has used "Ask agent" before in this session** → remember last-used segment for the session. Sticky, not global.
80
+ - Text/code surfaces: same control, same default. Comment pip unchanged.
81
+
82
+ ```
83
+ ┌─ composer (anchored to block, existing comment geometry) ─────────┐
84
+ │ ┌─────────────┬─────────────┐ │
85
+ │ │ ● Discuss │ ○ Ask agent │ ← segmented, 44px hit, 11px type │
86
+ │ └─────────────┴─────────────┘ │
87
+ │ ┌──────────────────────────────────────────────────────────────┐ │
88
+ │ │ Add a comment… (Discuss placeholder) │ │
89
+ │ │ What should change? (Ask agent placeholder) │ │
90
+ │ └──────────────────────────────────────────────────────────────┘ │
91
+ │ [⎘ Copy as prompt]* ⏎ Comment / ⏎ Ask esc Cancel │
92
+ └───────────────────────────────────────────────────────────────────┘
93
+ * Copy as prompt visible only in Ask-agent mode (see §3).
94
+ ```
95
+
96
+ Behavioral rules:
97
+
98
+ - Flipping the segment swaps placeholder + primary button label + footer hints. Draft text survives the flip. Flipping Ask→Discuss with text present: keep text, no warning (a plain comment with imperative text is harmless).
99
+ - Flipping Discuss→Ask with text present: keep text, no warning. The text becomes the instruction.
100
+ - Cmd+Enter dispatches per active segment: `kind:"comment"` or `kind:"instruction", instructionState:"queued"`. Immediate persist. No queue, no batch.
101
+ - Outside-click with empty input = cancel (ported unchanged).
102
+ - Read-only mode: Discuss only. Ask-agent is hidden in read-only (writing an instruction implies the agent may later write the doc; surfaces that are read-only for the human should not queue machine edits — keeps one mental rule: read-only = discuss).
103
+
104
+ ---
105
+
106
+ ## 3. Copy-as-prompt placement
107
+
108
+ Reachable with and without an agent, in three places, always the same string
109
+ format (`Edit the file \`X\` (a Markdown document). Apply these changes:\n\n1. \`<snippet>\`: <instruction>`), always with clipboard-gate + "Show" textarea fallback:
110
+
111
+ 1. **Composer, Ask-agent mode** — footer secondary button `[⎘ Copy as prompt]`. Copies draft-as-instruction without persisting anything. This is the true no-agent escape hatch at authoring time. Hidden in Discuss mode (a discussion comment is not a prompt).
112
+ 2. **Pending instruction card** (§4) — `[Copy prompt]` button. Available even after dispatch; the durable artifact and the clipboard path coexist.
113
+ 3. **Answered/stale instruction card** — same `[Copy prompt]`, for re-asking elsewhere after drift.
114
+
115
+ Numbering: keep `1.` prefix always, one code path (carried from prior spec F.2).
116
+
117
+ **Connect-an-agent placement:** in Ask-agent mode with no agent attached, the
118
+ primary button reads `Connect an agent` and opens the AI panel. Dispatch has
119
+ *already happened on Cmd+Enter* if the user pressed it first — button relabel is
120
+ a CTA, not a gate. The instruction sits queued in the sidecar either way. Copy
121
+ as prompt stays visible beside it.
122
+
123
+ ---
124
+
125
+ ## 4. Chrome without the queue bar
126
+
127
+ No bottom bar. The sidecar is the store. Three pieces of chrome total:
128
+
129
+ **Composer** — as §2. Exists only while open.
130
+
131
+ **Pending instruction card** (block gutter / margin, pip exactly like a comment
132
+ pip, distinct glyph — reuse the instruction styling from `comment-thread.tsx`'s
133
+ "Turn into an instruction" output):
134
+
135
+ ```
136
+ ┌─ instruction card (pending) ──────────────────────────────────────┐
137
+ │ ✦ you · waiting for your agent │
138
+ │ "Tighten this paragraph, keep the citation." │
139
+ │ Your agent picks this up when it next reads this file. │
140
+ │ [Copy prompt] [Remove] │
141
+ └───────────────────────────────────────────────────────────────────┘
142
+ ```
143
+
144
+ No spinner. No fake progress. State line is a true statement about `queued`.
145
+ `sent` state (when lifecycle is driven) swaps the line to "sent to your agent —
146
+ waiting for answer"; chrome otherwise identical.
147
+
148
+ **Answered state** — markdown: the suggestion-card appears inline (existing);
149
+ the instruction card collapses to one line anchored above it:
150
+
151
+ ```
152
+ ┌─ instruction (answered) ──────────────────────────────────────────┐
153
+ │ ✦ answered — review the suggestion below [Copy prompt] │
154
+ └───────────────────────────────────────────────────────────────────┘
155
+ ┌─ suggestion-card (existing, unchanged) ───────────────────────────┐
156
+ │ agent suggests replacing this block │
157
+ │ In response to: "Tighten this paragraph…" │
158
+ │ ─ current ─ / ─ proposed ─ [Accept][Reject] │
159
+ └───────────────────────────────────────────────────────────────────┘
160
+ ```
161
+
162
+ Text/code answered: reply lands in the instruction thread with fenced code;
163
+ card gains `[Mark done]` (human-settles, no doc write) beside `[Copy prompt]`.
164
+
165
+ ---
166
+
167
+ ## 5. Review loop — confirmed
168
+
169
+ **Markdown (full loop):** agent reads queued instruction → writes
170
+ `suggestion.add` + flips instruction to `answered` → user reviews in
171
+ suggestion-card → Accept pushes block op with `baseRevision` (409 → one retry
172
+ with `getLatestRevision()`, existing behavior) → instruction resolves when the
173
+ suggestion settles. Clarifying questions arrive as thread replies, not
174
+ suggestions. **Confirmed as designed.**
175
+
176
+ **Text/code (degraded, honest):** instruction persists at the lineAnchor; agent
177
+ cannot suggest; answer arrives as a comment reply containing fenced replacement
178
+ lines; user hand-applies. Expectation set **at dispatch time** — footnote under
179
+ the composer's Ask button on non-md surfaces: *"On this file type the agent
180
+ replies with a comment; you apply the change."* **Confirmed.**
181
+
182
+ **HTML iframe:** nothing. Source view only. **Confirmed** (permanently dropped
183
+ with the old engine).
184
+
185
+ ---
186
+
187
+ ## 6. Re-targeting a block with a pending instruction (no `comment.update`)
188
+
189
+ Three options — picking **reuse the existing thread via a prefilled composer**, with an explicit cost note:
190
+
191
+ | Option | Verdict | Cost |
192
+ |---|---|---|
193
+ | **(a) Reuse thread: open the pending instruction's thread in place of a fresh composer; composer's Ask field prefilled with current instruction text; Cmd+Enter posts a `comment.reply`** | **PICK** | A "revised instruction" is a reply, not an edit — the instruction card needs latest-reply-wins display logic (show newest reply from the instruction author as the effective instruction). Small client-side rule, zero schema change, zero new op. |
194
+ | (b) Add `comment.update` op | Rejected for v1 | New op type, new revision/idempotency edge cases, server + tests, for one affordance. Disproportionate. |
195
+ | (c) Just create another instruction | Rejected | Two pending instructions on one block = agent sees contradictory intent; dedup was a named good-part of the old UX. |
196
+
197
+ Concretely (a): Comment button on a block whose only open thread is a pending
198
+ instruction **opens that thread directly** (skip the composer). The thread's own
199
+ reply box uses Ask-agent styling when replying on an instruction thread:
200
+ placeholder "Revise this instruction…", Cmd+Enter = reply. Card body renders the
201
+ latest author reply as the instruction text, with a subtle `edited` marker. The
202
+ agent reads the thread top-down; recency-semantics ("last instruction wins") is
203
+ a one-line note in the context doc, not new machinery.
204
+
205
+ ---
206
+
207
+ ## 7. States
208
+
209
+ | State | Chrome | Copy-as-prompt | Connect-an-agent |
210
+ |---|---|---|---|
211
+ | **Composing (Discuss)** | Composer, Discuss segment | hidden | hidden |
212
+ | **Composing (Ask agent)** | Composer, Ask segment, "What should change?" | footer secondary | visible only if no agent (as primary relabel) |
213
+ | **No agent** | Ask mode fully functional; instruction persists queued | present (composer + card) | primary CTA → AI panel; nothing lost |
214
+ | **Queued/pending** | Instruction card + gutter pip; toolbar "✦ N pending" chip if N>0 | card button | toolbar chip area / AI panel entry point |
215
+ | **Answered (md)** | Collapsed instruction + suggestion-card | card button | n/a |
216
+ | **Answered (text/code)** | Thread reply + `[Mark done]` | card button | n/a |
217
+ | **Drift / stale anchor** (ref/textHash miss) | Pip → `⚠ target changed`; actions: `[Re-anchor]` (re-open composer targeting best-effort match), `[Copy prompt]`, `[Remove]` | present — this is its most important state | hidden |
218
+ | **Empty** | Zero chrome. No bar, no placeholder | n/a | n/a |
219
+
220
+ Accept-collision drift (409 after retry, fingerprint mismatch) stays inside
221
+ suggestion-card: "Document changed since this suggestion — refresh review."
222
+ Unchanged from current implementation.
223
+
224
+ ---
225
+
226
+ ## Summary
227
+
228
+ 1. Two actions stay two. Comment = say something (discuss or instruct); Suggest = review an edit (human or agent).
229
+ 2. One composer with a Discuss / Ask-agent segmented control; defaults to Discuss; session-sticky; draft survives flips.
230
+ 3. Ask-agent dispatch writes `comment.add {kind:"instruction", queued}` immediately — no queue bar, sidecar is the store.
231
+ 4. Copy-as-prompt lives in the composer footer (Ask mode), on every instruction card, and in every drift state — the constant escape hatch; Connect-an-agent only appears when no agent is attached.
232
+ 5. Agent answers land in the existing suggestion-card (md, full Accept-writes-doc) or as thread replies (text/code, hand-apply, limitation stated at dispatch).
233
+ 6. Re-target dedup = open existing thread, revise via reply, latest-reply-wins display — no `comment.update` op in v1.
234
+ 7. **Riskiest assumption:** the agent actually consumes the sidecar and answers with a suggestion op. If it never integrates, every Ask-agent comment dead-ends at "queued + Copy prompt" — acceptable only because copy-as-prompt is one click away in every state, which is why its placement is non-negotiable.
@@ -0,0 +1,261 @@
1
+ # Spec: Unified live tweak for web surfaces (Impeccable-live model)
2
+
3
+ > Supersedes OPS-1 ("Tweak on a running app / proxied node-app runtime") and the
4
+ > canceled OPS-2..6 isolated-origin/grant/hardening line. Those described an
5
+ > embed-in-iframe architecture; this spec replaces the whole approach with the
6
+ > Impeccable `live` model. Feasibility confirmed by the B1 spike (see Further
7
+ > Notes).
8
+
9
+ ## Problem Statement
10
+
11
+ A user running wiki-viewer wants to point at any element on a rendered web page,
12
+ say what they want ("make this bolder", "try a different layout"), see a few live
13
+ design variants they can compare and tune, and Accept the one they like straight
14
+ into source. Today this only half-exists, in fragmented and inconsistent forms:
15
+
16
+ - **Static HTML** gets a bespoke tweak flow (opaque-origin sandbox, DOM ops,
17
+ "Iterate" variants) that is limited and SPA-hostile.
18
+ - **Running node apps / dynamic surfaces** get **no tweak surface at all** — the
19
+ picker is deliberately not injected into proxied apps. The one place the user
20
+ most wants to point-and-fix is the one place the feature is missing.
21
+ - The two surfaces behave differently, so there is no single mental model.
22
+
23
+ The user is forced to leave the rendered page, hunt for the right source by hand,
24
+ edit blind, and reload to check. The visual, direct-manipulation promise is
25
+ broken for exactly the surfaces where it matters most.
26
+
27
+ ## Solution
28
+
29
+ One unified live-tweak experience across all web/visual surfaces (static HTML,
30
+ dynamic/server-rendered HTML, running node apps), modeled on the Impeccable `live`
31
+ skill. The user opens a surface, points at an element, picks a design action or
32
+ types a freeform instruction, and hits Go. The system produces 2 to 5 full-element
33
+ variants, each with 0 to 4 tunable knobs (sliders, toggles, segmented controls).
34
+ The user cycles variants and drags knobs with instant feedback, then Accepts the
35
+ chosen variant, which lands in the real source file. Discard restores the
36
+ original. Nothing is written to disk until Accept.
37
+
38
+ The variants are generated by the user's existing attached agent (the same AI
39
+ channel that already powers markdown and static-HTML tweak today), so no new AI
40
+ plumbing is introduced. The Impeccable live engine (a local helper server plus
41
+ its browser overlay and source-mutation logic) is hosted and driven by the
42
+ wiki-viewer product itself, not by a chat agent running the skill by hand.
43
+
44
+ Because Impeccable injects its overlay into the app's own page (the user edits
45
+ their own app, in place), there is no parent frame to protect. That relocation of
46
+ trust deletes the isolated-origin security problem that the previous
47
+ (now-canceled) design was built to solve.
48
+
49
+ ### Surface-specific experience (user-facing)
50
+
51
+ The top-level flow (point, instruct, Go, compare variants, tune knobs, Accept or
52
+ Discard) is identical on every surface. The only user-visible difference is how
53
+ variants first appear on screen.
54
+
55
+ - **Static HTML file.** No dev server involved; the file is both served and
56
+ source. After Go, variants appear via an instant client-side swap: no reload, no
57
+ flicker, no lost state. Cycling variants and dragging knobs are instant. Accept
58
+ writes into the `.html` file directly. This is the flagship, flicker-free
59
+ experience and ships first.
60
+
61
+ - **Dynamic / server-rendered HTML that maps to editable templates.** Where the
62
+ served HTML corresponds to real editable source (raw templates, not compiled
63
+ component trees), the same fetch-source swap applies and the reload below is
64
+ usually avoided.
65
+
66
+ - **Running node apps (compiled frameworks: React, Vue, Next, etc.).** The app
67
+ must be running and viewed through the proxy. Variant markup is written into the
68
+ app's real component/template source. To render compiled source, the page
69
+ performs **one full reload per Go**; the overlay re-attaches automatically (it
70
+ remembers its session per page). After that single reload, all variants are
71
+ already present in the page, so cycling and knob-tuning are instant and
72
+ client-side, exactly like static. Accept bakes the choice into source and may
73
+ trigger one more brief reload for the clean final render.
74
+
75
+ The one felt cost on compiled apps: a full reload resets transient in-app state
76
+ (open modals, form input, deep scroll, SPA sub-route). Static HTML never has
77
+ this. Closing that gap (flicker-free, state-preserving hot-swap) is deferred
78
+ optional work; see Out of Scope.
79
+
80
+ ## User Stories
81
+
82
+ 1. As a wiki-viewer user, I want to point at any element on a rendered web page and have it highlight, so that I can target exactly what I want to change.
83
+ 2. As a user, I want to pick a named design action (bolder, quieter, distill, polish, typeset, colorize, layout, adapt, animate, delight) for the selected element, so that I can steer the direction without writing a prompt.
84
+ 3. As a user, I want to type a freeform instruction for the selected element, so that I can express intent the named actions do not cover.
85
+ 4. As a user, I want to scribble or annotate directly on the element before generating, so that I can point at sub-parts and give spatial direction.
86
+ 5. As a user, I want 2 to 5 distinct variants generated per request, so that I can compare real alternatives rather than accept the first idea.
87
+ 6. As a user, I want to cycle between the generated variants quickly, so that I can judge them side by side in the real page.
88
+ 7. As a user, I want each variant to expose a few tunable knobs (sliders, toggles, segmented controls), so that I can fine-tune a direction without regenerating.
89
+ 8. As a user, I want knob changes to update the preview instantly, so that tuning feels direct.
90
+ 9. As a user, I want to Accept a chosen variant and have it written into the real source file, so that the change persists in my project.
91
+ 10. As a user, I want Discard to restore the original exactly, so that experimenting is risk-free.
92
+ 11. As a user, I want nothing written to disk until I Accept, so that previews never corrupt my files.
93
+ 12. As a user, I want Accept refused if the underlying source changed since the preview began, so that a concurrent edit is never silently overwritten.
94
+ 13. As a user editing a static HTML file, I want variants to appear instantly with no reload or flicker, so that the experience feels live.
95
+ 14. As a user tweaking a running node app, I want the tweak overlay available on the proxied app page, so that I can point-and-fix without leaving the app.
96
+ 15. As a user tweaking a running node app, I want the overlay to re-attach itself after the post-generate reload, so that my session is not interrupted.
97
+ 16. As a user tweaking a compiled app, I want cycling and knob-tuning to stay instant after the initial reload, so that only the first render costs a reload.
98
+ 17. As a user, I want the accepted change written to the true source (template or component), never to a generated build output, so that my change is not wiped by the next build.
99
+ 18. As a user, I want a clear indication when a surface is generating variants versus ready to review, so that I know what the system is doing.
100
+ 19. As a user, I want to steer the whole page (a page-level instruction with no specific element), so that I can request broad direction.
101
+ 20. As a user, I want to start a tweak on a static HTML surface with no dev server or app launch required, so that the simplest case is frictionless.
102
+ 21. As an admin in authenticated mode, I want node-app launching to remain gated to me (or explicitly allowed runners), so that arbitrary users cannot start host processes just to tweak.
103
+ 22. As a user, I want the tweak overlay to only load where I am authorized for the workspace, so that the feature respects existing access boundaries.
104
+ 23. As a user, I want the tweak engine's runtime files kept out of my served pages, my file browser, and my commits, so that internal state never leaks into my project or repo.
105
+ 24. As a user, I want an interrupted tweak session (reload, crash, disconnect) to recover to a safe state, so that I never end up with half-applied variants.
106
+ 25. As a user, I want at most one outstanding generate request per surface session, so that rapid clicks do not stack conflicting generations.
107
+ 26. As a user, I want the accepted variant's knob values baked into the final source, so that what I tuned is what persists.
108
+ 27. As a user, I want the previous bespoke static-HTML tweak flow replaced by this unified one, so that I do not have to learn two different behaviors.
109
+ 28. As a user, I want the markdown prose tweak flow to keep working as it does today, so that this change does not regress non-visual editing.
110
+ 29. As a user, I want variants that respect my app's existing visual identity by default, so that I can actually accept them rather than getting off-brand results.
111
+ 30. As a user, I want a departure (redesign) direction only when I explicitly ask for it, so that "make it better" does not throw away my brand.
112
+ 31. As a user, I want a live indication when the overlay cannot reach the engine, so that I know to reconnect rather than assume it is working.
113
+ 32. As a user viewing a remotely-hosted wiki-viewer (not localhost), I want the tweak overlay to still function, so that the feature is not limited to local use.
114
+ 33. As a user, I want a failed variant render to surface as a recoverable error rather than a blank page, so that one bad generation does not break the session.
115
+ 34. As a developer, I want the accept/carbonize write path to go through wiki-viewer's own containment and locking, so that tweak writes obey the same safety as every other file write.
116
+
117
+ ## Implementation Decisions
118
+
119
+ - **Topology: product hosts the engine; the existing attached agent generates.**
120
+ wiki-viewer spawns and supervises the Impeccable live helper server (one per
121
+ served surface, keyed like the node-app runner keys apps), injects the overlay,
122
+ and runs the engine's poll loop **server-side**. On a generate event, wiki-viewer
123
+ translates it into a request on its existing attached-agent live channel, so the
124
+ user's current AI session produces the variants. wiki-viewer applies the variant
125
+ writes and replies to the engine; on Accept it runs the accept/carbonize
126
+ mutation through its own writer.
127
+
128
+ - **Primary new module: the live bridge.** A product-side bridge translates
129
+ Impeccable poll events (generate, steer, accept, discard, prefetch,
130
+ variant-mount-failed, manual-edit-apply) into the existing live-store request
131
+ kinds and back. It owns the reconciliation between the engine's poll/lease model
132
+ and wiki-viewer's one-outstanding-per-session, delivered/working/resolved state
133
+ machine, and idempotency keying. This is the single primary seam.
134
+
135
+ - **Injection as a shared pure transform.** A single string transform injects the
136
+ engine prelude globals plus the overlay `<script>`. It is reused by the app-proxy
137
+ serve-time HTML rewrite (for running apps) and the static-HTML viewer render (for
138
+ files). Serve-time injection means no source files are edited to enable tweak and
139
+ no removal step is needed. The stock live-inject source-file editor is not used.
140
+
141
+ - **Accept/carbonize as a pure mutator over wiki-viewer's writer.** The engine's
142
+ accept logic (locate markers, extract the chosen variant, carbonize/bake knob
143
+ values, produce clean final source) is hosted as a pure transform whose writes
144
+ go through `resolveWorkspacePath` containment plus wiki-viewer's existing write
145
+ lock and collab-state checks. The engine's own raw file write and separate
146
+ lockfile are not used for source mutation, so there is exactly one authoritative
147
+ write/lock spine.
148
+
149
+ - **Speculative-until-Accept invariant preserved.** Previews never write source.
150
+ Accept is the only operation that writes, and only if the base content hash still
151
+ matches (drift refuses the accept). This mirrors the current web-tweak accept
152
+ contract and the engine's accept-receipt idempotency.
153
+
154
+ - **Browser-to-helper transport must survive remote hosting.** Because the overlay
155
+ runs on wiki-viewer's origin and the browser may be remote, the engine endpoints
156
+ the overlay needs (overlay bundle, event downlink/SSE, uplink, source read,
157
+ design-system read, annotation upload) are exposed through wiki-viewer's own
158
+ origin, and the injected globals point the overlay at those proxied paths rather
159
+ than a hardcoded localhost helper port. Proxied endpoints inherit wiki-viewer
160
+ session/agent auth and CSRF Origin checks.
161
+
162
+ - **Dynamic-app rendering uses full-reload-through-proxy.** HMR WebSocket does not
163
+ pass through the app-proxy today (confirmed). For compiled apps, a post-generate
164
+ full page reload renders the written variants; the overlay re-attaches via its
165
+ durable per-origin session. Cycling and knobs remain client-side after that one
166
+ reload. Static and template-mapped surfaces use the instant client-side / fetch-
167
+ source swap and do not reload.
168
+
169
+ - **Engine runtime state is denied and ignored.** The engine's runtime directory
170
+ is added to path-containment denied segments (so it is never served, traversed,
171
+ or reachable via file routes) and to gitignore (so it is never committed),
172
+ consistent with the existing treatment of `.proof` and `.git`.
173
+
174
+ - **Node-app authorization unchanged.** Launching an app to tweak it obeys the
175
+ existing app-runner permission model (admin-only in auth mode unless the runner
176
+ allowance is set). Overlay availability follows workspace access.
177
+
178
+ - **Variant quality contract inherited from the engine.** Identity-preserving
179
+ "default" mode is the norm; a "departure" redesign direction is used only on
180
+ explicit user request. This is engine behavior wiki-viewer surfaces, not new
181
+ product logic.
182
+
183
+ - **Recovery via the engine journal.** Session state is the engine's append-only
184
+ per-session journal; interrupted sessions replay to a safe state on reconnect
185
+ rather than leaving half-applied variants.
186
+
187
+ ## Testing Decisions
188
+
189
+ - **Good tests assert external behavior, not internals.** Tests drive the feature
190
+ through its route handlers and pure transforms and assert the observable
191
+ contract: previews never write; Accept writes verbatim only on matching base
192
+ hash; one-outstanding-per-session; idempotent replay; original restored on
193
+ Discard; runtime dir denied. They do not assert internal call sequences.
194
+
195
+ - **Primary seam: the live bridge at the route-handler level.** Tested exactly
196
+ like the existing live-collab proof tests: a temp workspace and registered
197
+ agent, drive the poll/reply loop through the real route handlers, assert the
198
+ reconciled state machine, idempotency, and that source is written only on Accept.
199
+ Prior art: `live-collab.test.ts`, `live-md-batch.test.ts`.
200
+
201
+ - **Injection transform: pure-function test.** Assert the transform injects the
202
+ prelude globals and overlay script at the correct anchor, is idempotent, and does
203
+ not corrupt surrounding HTML. Prior art: the existing app-proxy HTML-rewrite
204
+ tests and `web-tweak-picker.test.ts`.
205
+
206
+ - **Accept/carbonize mutator: pure-function + verbatim-commit test.** Assert marker
207
+ location, variant extraction, knob-value baking, clean final output, and the
208
+ base-hash drift guard (accept refused when source drifted; committed verbatim
209
+ when unchanged). Prior art: `web-tweak-collab.test.ts`.
210
+
211
+ - **Authorization and containment.** Assert overlay/endpoints reject unauthorized
212
+ workspace access and that the runtime dir is unreachable through file routes and
213
+ path resolution. Prior art: `app-proxy-auth.test.ts`.
214
+
215
+ - **Helper-server process lifecycle is integration-only.** The live helper is a
216
+ spawned child process; its lifecycle is not part of the unit seam, mirroring how
217
+ `app-runner.test.ts` treats spawned apps. The bridge is tested against the
218
+ engine's HTTP/file contract, not a live child.
219
+
220
+ - **Test floor.** New proof tests are added under the proof suite and the floor is
221
+ updated only via the sanctioned `--update-floor` path.
222
+
223
+ ## Out of Scope
224
+
225
+ - **Flicker-free, state-preserving hot-swap for compiled node apps.** Requires
226
+ adding WebSocket-upgrade passthrough to the proxy (forwarding the app's HMR
227
+ socket). Deliberately deferred to a later ticket; compiled apps ship with
228
+ full-reload-through-proxy first. Not a blocker.
229
+ - **Markdown / prose tweak redesign.** The existing markdown variants-in-place flow
230
+ stays as is; this spec covers web/visual surfaces only.
231
+ - **Non-web surfaces** (PDFs, images, binary previews).
232
+ - **Re-implementing the Impeccable live engine natively.** The engine is reused,
233
+ not rebuilt. Rejected during the spike as large, duplicated, security-sensitive
234
+ work.
235
+ - **Multi-user concurrent tweaking of the same element.** Single-user-at-a-time per
236
+ surface session is assumed, consistent with the existing one-outstanding model.
237
+ - **Changing the node-app authorization model.** Existing app-runner permissions
238
+ are reused unchanged.
239
+
240
+ ## Further Notes
241
+
242
+ - **Feasibility is established.** The B1 spike confirmed the engine is HTTP plus
243
+ file-based state with no hard chat-agent dependency, that wiki-viewer's proxy and
244
+ static viewer are natural injection points, that the accept/carbonize logic can
245
+ be hosted over wiki-viewer's writer, and that the engine poll loop maps 1:1 onto
246
+ the existing attached-agent channel. The single confirmed constraint (HMR does
247
+ not traverse the proxy) is handled by full-reload-through-proxy and does not gate
248
+ shipping.
249
+ - **Highest remaining risk is the remote-hosting transport bridge** (proxying the
250
+ overlay's engine endpoints through wiki-viewer's origin). It is bounded and
251
+ defined, but it is real new code and should be an early ticket for any non-
252
+ localhost use.
253
+ - **Suggested tracer bullet** (for to-tickets): the static-HTML surface end to end
254
+ (spawn/host engine, inject overlay, run the product-side poll loop, wire one
255
+ generate through the existing agent channel, land one Accept through wiki-viewer's
256
+ writer). It proves the whole spine on the simplest surface; dynamic apps and the
257
+ transport bridge layer on top.
258
+ - **Repo conventions:** every implementing ticket must fold in the matching
259
+ `docs/ux-contracts.md` update (the unified flow replaces the current §1.4
260
+ HTML-tweak/Iterate behavior) and the isometric codebase-map update, in the same
261
+ change as the behavior.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wiki-viewer",
3
- "version": "2.16.0",
3
+ "version": "2.16.1",
4
4
  "description": "Local file viewer and wiki — view markdown, HTML, PDFs, notebooks, office docs, and more from any directory",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -15,7 +15,7 @@ const currentPort = parseInt(process.env.PORT, 10) || 3000
15
15
  const hostname = process.env.HOSTNAME || '0.0.0.0'
16
16
 
17
17
  let keepAliveTimeout = parseInt(process.env.KEEP_ALIVE_TIMEOUT, 10)
18
- const nextConfig = {"env":{"NEXT_PUBLIC_APP_VERSION":"2.16.0"},"webpack":null,"typescript":{"ignoreBuildErrors":false},"typedRoutes":false,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.ts","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":true,"customCacheHandler":false},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{"serverFunctions":true,"browserToTerminal":"warn"},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/home/runner/work/wiki-viewer/wiki-viewer","allowedDevOrigins":["localhost"],"cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"appNewScrollHandler":false,"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"cachedNavigations":false,"partialFallbacks":false,"dynamicOnHover":false,"varyParams":false,"prefetchInlining":false,"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":3,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"imgOptSkipMetadata":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"strictRouteTypes":false,"viewTransition":false,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":false,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":true,"serverComponentsHmrCache":true,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"gestureTransition":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":"warn","lockDistDir":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":false,"turbopackInferModuleSideEffects":true,"turbopackPluginRuntimeStrategy":"childProcesses","optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.ts","turbopack":{"root":"/home/runner/work/wiki-viewer/wiki-viewer"},"distDirRoot":".next"}
18
+ const nextConfig = {"env":{"NEXT_PUBLIC_APP_VERSION":"2.16.1"},"webpack":null,"typescript":{"ignoreBuildErrors":false},"typedRoutes":false,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.ts","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":true,"customCacheHandler":false},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{"serverFunctions":true,"browserToTerminal":"warn"},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/home/sil/wiki-viewer","allowedDevOrigins":["localhost"],"cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"appNewScrollHandler":false,"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"cachedNavigations":false,"partialFallbacks":false,"dynamicOnHover":false,"varyParams":false,"prefetchInlining":false,"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":3,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"imgOptSkipMetadata":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"strictRouteTypes":false,"viewTransition":false,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":false,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":true,"serverComponentsHmrCache":true,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"gestureTransition":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":"warn","lockDistDir":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":false,"turbopackInferModuleSideEffects":true,"turbopackPluginRuntimeStrategy":"childProcesses","optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.ts","turbopack":{"root":"/home/sil/wiki-viewer"},"distDirRoot":".next"}
19
19
 
20
20
  process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig)
21
21
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wiki-viewer",
3
- "version": "2.16.0",
3
+ "version": "2.16.1",
4
4
  "description": "Local file viewer and wiki — view markdown, HTML, PDFs, notebooks, office docs, and more from any directory",
5
5
  "license": "MIT",
6
6
  "type": "module",