@cyber-dash-tech/revela 0.15.3 → 0.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.
@@ -247,7 +247,7 @@ async function handleAssetSave(req: Request, session: EditSession): Promise<Resp
247
247
  id: body?.id || candidate.candidateId,
248
248
  type: "image",
249
249
  purpose,
250
- brief: body?.brief || `Saved from ${candidate.provider} for Refine asset placement.`,
250
+ brief: body?.brief || `Saved from ${candidate.provider} for Review asset placement.`,
251
251
  status: "success",
252
252
  sourceUrl: candidate.imageUrl,
253
253
  alt: body?.alt || candidate.alt || candidate.title,
@@ -652,7 +652,7 @@ function handleInspectResult(requestId: string | null, session: EditSession): Re
652
652
  session.lastActiveAt = Date.now()
653
653
  scheduleIdleStop()
654
654
  if (request.status === "completed") return jsonResponse({ ok: true, requestId, status: request.status, deckVersion: request.deckVersion, result: request.result })
655
- if (request.status === "failed" || request.status === "expired") return jsonResponse({ ok: true, requestId, status: request.status, deckVersion: request.deckVersion, error: request.error || "Inspection failed" })
655
+ if (request.status === "failed" || request.status === "expired") return jsonResponse({ ok: true, requestId, status: request.status, deckVersion: request.deckVersion, error: request.error || "Insight failed" })
656
656
  return jsonResponse({ ok: true, requestId, status: request.status, deckVersion: request.deckVersion })
657
657
  }
658
658
 
@@ -764,7 +764,7 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
764
764
  <head>
765
765
  <meta charset="utf-8" />
766
766
  <meta name="viewport" content="width=device-width, initial-scale=1" />
767
- <title>Revela Refine</title>
767
+ <title>Revela Review</title>
768
768
  <style>
769
769
  :root { color-scheme: light; font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; }
770
770
  * { box-sizing: border-box; }
@@ -783,15 +783,16 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
783
783
  .deck-nav button:hover:not(:disabled) { background: rgba(255,255,255,.22); }
784
784
  .deck-nav button:disabled { opacity: .38; }
785
785
  .deck-nav-status { min-width: 76px; color: #e2e8f0; font-size: 12px; font-weight: 900; text-align: center; font-variant-numeric: tabular-nums; }
786
- aside { position: relative; display: flex; flex-direction: column; gap: 16px; padding: 20px; background: linear-gradient(180deg, #fbfaf7 0%, #f2eee6 100%); overflow: auto; border-left: 1px solid #d8d2c6; }
786
+ aside { position: relative; display: flex; flex-direction: column; gap: 16px; padding: 20px; background: linear-gradient(180deg, #fbfaf7 0%, #f2eee6 100%); overflow: auto; border-left: 1px solid #d8d2c6; font-family: Garamond, "Iowan Old Style", Georgia, serif; }
787
+ aside button, aside input, aside select, aside textarea, aside .comment-editor { font-family: inherit; }
787
788
  h1 { margin: 0; font-size: 18px; line-height: 1.2; letter-spacing: -.01em; color: #0f172a; }
788
789
  .wordmark { font-family: Garamond, "Iowan Old Style", Georgia, serif; font-size: 21px; letter-spacing: .08em; font-weight: 600; }
789
- .hint { margin: 0; color: #756f66; font-size: 13px; line-height: 1.5; }
790
790
  .panel { display: flex; flex-direction: column; gap: 10px; }
791
- .tabs { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; padding: 4px; border: 1px solid #d8d2c6; border-radius: 14px; background: #ebe4d8; }
792
- .tab { padding: 9px 10px; border: 0; border-radius: 10px; background: transparent; color: #5f594f; box-shadow: none; font-weight: 900; }
793
- .tab.active { background: #fbfaf7; color: #111827; box-shadow: 0 6px 16px rgba(31,41,51,.1); }
794
- .tab-panel { display: none; flex-direction: column; gap: 12px; }
791
+ .tabs { display: flex; gap: 2px; padding: 0 0 0 8px; border-bottom: 1px solid #d8d2c6; background: transparent; }
792
+ .tab { width: auto; min-width: 112px; padding: 10px 18px; border: 1px solid transparent; border-bottom: 0; border-radius: 13px 13px 0 0; background: transparent; color: #5f594f; box-shadow: none; font-weight: 900; }
793
+ .tab:hover:not(:disabled) { background: rgba(255,253,248,.58); }
794
+ .tab.active { position: relative; top: 1px; background: #fbfaf7; border-color: #d8d2c6; color: #111827; box-shadow: 0 -7px 16px rgba(31,41,51,.05); }
795
+ .tab-panel { display: none; flex-direction: column; gap: 12px; padding-top: 12px; }
795
796
  .tab-panel.active { display: flex; }
796
797
  .sr-only { position: absolute !important; width: 1px !important; height: 1px !important; padding: 0 !important; margin: -1px !important; overflow: hidden !important; clip: rect(0,0,0,0) !important; white-space: nowrap !important; border: 0 !important; }
797
798
  .selection-summary { padding: 10px 12px; border: 1px solid #d8d2c6; border-radius: 14px; background: #fbfaf7; color: #3f3a33; font-size: 13px; line-height: 1.45; box-shadow: 0 8px 22px rgba(31,41,51,.05); }
@@ -885,20 +886,19 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
885
886
  <div id="resizeHandle" class="resize-handle" role="separator" aria-label="Resize editor panel" aria-orientation="vertical" title="Drag to resize editor. Double-click to reset."></div>
886
887
  <aside>
887
888
  <div>
888
- <h1><span class="wordmark">REVELA</span> Refine</h1>
889
- <p class="hint">Select refs, describe the change, then send. Use Inspect only when you need source or purpose context.</p>
889
+ <h1><span class="wordmark">REVELA</span> Review</h1>
890
890
  </div>
891
891
  <div id="selectionSummary" class="selection-summary sr-only" aria-live="polite"><strong>Selection</strong><span>No references selected.</span><div id="selectionChips" class="selection-chips"></div></div>
892
- <div class="tabs" role="tablist" aria-label="Refine mode">
893
- <button id="editTab" class="tab" type="button" role="tab">Edit</button>
894
- <button id="inspectTab" class="tab" type="button" role="tab">Inspect</button>
892
+ <div class="tabs" role="tablist" aria-label="Review mode">
893
+ <button id="editTab" class="tab" type="button" role="tab">Comment</button>
894
+ <button id="inspectTab" class="tab" type="button" role="tab">Insight</button>
895
895
  </div>
896
896
  <div id="editPanel" class="tab-panel">
897
897
  <div class="panel">
898
898
  <div class="label">Describe the change</div>
899
899
  <div id="comment" class="comment-editor" contenteditable="true" role="textbox" aria-multiline="true" data-placeholder="Cmd/Ctrl-click slide elements to add @refs, then describe the exact edit."></div>
900
900
  </div>
901
- <div class="edit-assets" aria-label="Edit assets">
901
+ <div class="edit-assets" aria-label="Comment assets">
902
902
  <div class="panel">
903
903
  <div class="asset-tools"><div class="label">Local Assets</div><button id="assetSearchToggle" class="asset-search-toggle" type="button" aria-expanded="false" aria-controls="assetSearchView" title="Search assets">+</button></div>
904
904
  <div id="editSavedAssets" class="asset-grid"><p class="asset-empty">No local assets yet. Click + to search assets.</p></div>
@@ -909,20 +909,20 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
909
909
  </div>
910
910
  <div id="inspectPanel" class="tab-panel">
911
911
  <div class="panel">
912
- <label class="label" for="inspectComment">Inspect comment</label>
912
+ <label class="label" for="inspectComment">Insight comment</label>
913
913
  <div id="inspectComment" class="comment-editor" contenteditable="true" role="textbox" aria-multiline="true" data-placeholder="Cmd/Ctrl-click slide elements to add @refs, then ask about purpose or source."></div>
914
914
  </div>
915
915
  <div class="inspect-actions">
916
916
  <div class="inspect-options"><label for="inspectLanguage">Display Language</label><select id="inspectLanguage" class="inspect-select"><option>Auto</option><option>English</option><option>简体中文</option><option>繁體中文</option><option>日本語</option><option>Deutsch</option><option>Français</option><option>Español</option><option>Português</option><option>Arabic</option></select></div>
917
- <button id="inspectButton" disabled>Inspect Reference</button>
917
+ <button id="inspectButton" disabled>Get Insight</button>
918
918
  <div id="inspectStale"></div>
919
919
  </div>
920
- <div id="inspectCards" class="inspect-cards"><div class="inspect-empty">Select a deck element to create an @ref, optionally ask a question, then Inspect. This does not edit the deck.</div></div>
920
+ <div id="inspectCards" class="inspect-cards"><div class="inspect-empty">Select a deck element to create an @ref, optionally ask a question, then get insight. This does not edit the deck.</div></div>
921
921
  </div>
922
922
  <div id="assetSearchView" class="asset-search-view" aria-hidden="true">
923
923
  <div class="asset-search-head">
924
924
  <button id="assetSearchBack" class="asset-back" type="button">← Back</button>
925
- <div class="asset-search-title"><h2>Search Assets</h2><span>Save images to Local Assets, then use them from Edit.</span></div>
925
+ <div class="asset-search-title"><h2>Search Assets</h2><span>Save images to Local Assets, then use them from Comment.</span></div>
926
926
  </div>
927
927
  <div class="panel">
928
928
  <div class="asset-search"><input id="assetQuery" type="search" placeholder="Company logo, product photo, portrait..." /><select id="assetPurpose"><option value="logo" selected>logo</option><option value="illustration">photo</option><option value="hero">hero</option><option value="portrait">portrait</option><option value="screenshot">screenshot</option></select></div>
@@ -1072,7 +1072,7 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
1072
1072
  restoreEditorWidth();
1073
1073
  bindEvents();
1074
1074
  setMode(state.mode);
1075
- setStatus('Editor ready. Ctrl/Cmd + click deck elements to reference them.');
1075
+ setStatus('Review ready. Ctrl/Cmd + click deck elements to reference them.');
1076
1076
  initFrame();
1077
1077
  loadSavedAssets();
1078
1078
  startDeckVersionPolling();
@@ -1116,6 +1116,7 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
1116
1116
  els.inspectComment.addEventListener('mouseup', saveCommentRange);
1117
1117
  document.addEventListener('selectionchange', saveCommentRange);
1118
1118
  els.hitbox.addEventListener('pointermove', onHover);
1119
+ els.hitbox.addEventListener('pointerleave', clearHoverSilently);
1119
1120
  els.hitbox.addEventListener('pointerdown', onPointerDown);
1120
1121
  els.hitbox.addEventListener('click', onClick);
1121
1122
  els.hitbox.addEventListener('contextmenu', (event) => {
@@ -1263,7 +1264,7 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
1263
1264
  state.pendingRefreshMessage = false;
1264
1265
  setStatus('Deck updated. Preview refreshed. Element references were cleared.');
1265
1266
  } else {
1266
- setStatus(slides.length > 0 ? 'Editor ready. Found ' + slides.length + ' slides. Ctrl/Cmd + click to reference elements.' : 'Editor ready, but no .slide elements were found. Ctrl/Cmd + click to reference elements.');
1267
+ setStatus(slides.length > 0 ? 'Review ready. Found ' + slides.length + ' slides. Ctrl/Cmd + click to reference elements.' : 'Review ready, but no .slide elements were found. Ctrl/Cmd + click to reference elements.');
1267
1268
  }
1268
1269
  } catch (error) {
1269
1270
  reportError(error);
@@ -1336,9 +1337,11 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
1336
1337
  } catch {}
1337
1338
  }
1338
1339
  if (!handled) applyFallbackDeckNavigation(win, doc, slides, clamped);
1340
+ const changed = clamped !== state.deckSlideIndex;
1339
1341
  state.deckSlideIndex = clamped;
1340
1342
  updateDeckNavControls();
1341
- renderHoverOutline(state.hoverEl);
1343
+ if (changed) clearHoverSilently();
1344
+ else renderHoverOutline(state.hoverEl);
1342
1345
  renderReferenceOutlines();
1343
1346
  } catch (error) {
1344
1347
  reportError(error);
@@ -1415,6 +1418,7 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
1415
1418
  initFrame();
1416
1419
  const target = selectable(targetFromPointer(event));
1417
1420
  if (!target || isReferenced(target)) {
1421
+ state.hoverEl = null;
1418
1422
  renderHoverOutline(null);
1419
1423
  return;
1420
1424
  }
@@ -1829,7 +1833,7 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
1829
1833
  renderReferenceOutlines();
1830
1834
  updateSendState();
1831
1835
  renderSelectionSummary();
1832
- resetInspectCards('References ready. Open Inspect and click Inspect Reference for concise Purpose and Source context.');
1836
+ resetInspectCards('References ready. Open Insight and click Get Insight for concise Purpose and Source context.');
1833
1837
  setStatus('Inserted @' + label + '. ' + state.references.length + ' reference' + (state.references.length === 1 ? '' : 's') + ' will be sent.');
1834
1838
  }
1835
1839
 
@@ -1997,14 +2001,27 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
1997
2001
  function renderReferenceOutlines() {
1998
2002
  const doc = els.frame.contentDocument;
1999
2003
  if (!doc || doc.location.href === 'about:blank') return;
2004
+ const slides = getSlides(doc);
2005
+ const currentSlide = slides[state.deckSlideIndex];
2006
+ const explicitSlideIndex = Number(currentSlide?.getAttribute('data-slide-index'));
2007
+ const currentSlideIndex = Number.isFinite(explicitSlideIndex) && explicitSlideIndex > 0 ? explicitSlideIndex : state.deckSlideIndex + 1;
2000
2008
  while (state.referenceOutlines.length < state.references.length) state.referenceOutlines.push(createOutline(doc, '#7aa6d8', 'rgba(122,166,216,.18)'));
2001
2009
  state.referenceOutlines.forEach((outline, index) => {
2002
2010
  const reference = state.references[index];
2003
2011
  setOutlineColor(outline, reference?.color);
2012
+ if (!reference || reference.payload?.slideIndex !== currentSlideIndex) {
2013
+ renderBox(outline, null);
2014
+ return;
2015
+ }
2004
2016
  renderBox(outline, reference?.target);
2005
2017
  });
2006
2018
  }
2007
2019
 
2020
+ function clearHoverSilently() {
2021
+ state.hoverEl = null;
2022
+ if (state.hoverOutline) state.hoverOutline.style.display = 'none';
2023
+ }
2024
+
2008
2025
  function clearHover() {
2009
2026
  state.hoverEl = null;
2010
2027
  setStatus('Hover cleared. Existing references are kept.');
@@ -2015,8 +2032,8 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
2015
2032
  if (state.sendingEdit) setButtonLoading(els.send, true, 'Sending...');
2016
2033
  else setButtonLoading(els.send, false, '<svg class="send-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94L14.7 6.3z"/></svg><span>Apply Fix</span>', true);
2017
2034
  els.send.disabled = state.sendingEdit || !getCommentText().trim();
2018
- if (state.inspecting) setButtonLoading(els.inspectButton, true, 'Inspecting...');
2019
- else setButtonLoading(els.inspectButton, false, 'Inspect Reference');
2035
+ if (state.inspecting) setButtonLoading(els.inspectButton, true, 'Getting insight...');
2036
+ else setButtonLoading(els.inspectButton, false, 'Get Insight');
2020
2037
  els.inspectButton.disabled = state.inspecting || state.references.length === 0;
2021
2038
  }
2022
2039
 
@@ -2077,7 +2094,7 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
2077
2094
  body: JSON.stringify({ snapshot, deckVersion: state.deckVersion, language: state.inspectLanguage, comment }),
2078
2095
  });
2079
2096
  const body = await res.json().catch(() => ({}));
2080
- if (!res.ok || !body.ok) throw new Error(body.error || 'Inspection failed');
2097
+ if (!res.ok || !body.ok) throw new Error(body.error || 'Insight failed');
2081
2098
  state.deckVersion = body.deckVersion || state.deckVersion;
2082
2099
  state.activeInspectRequestId = body.requestId;
2083
2100
  state.inspectFallback = body.preprocess || null;
@@ -2086,7 +2103,7 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
2086
2103
  } catch (error) {
2087
2104
  if (state.inspectFallback) {
2088
2105
  renderInspectResult(state.inspectFallback, 'Deterministic fallback');
2089
- els.inspectCards.insertAdjacentHTML('afterbegin', '<div class="inspect-warning">Generated inspection failed or timed out. Showing deterministic fallback context only.</div>');
2106
+ els.inspectCards.insertAdjacentHTML('afterbegin', '<div class="inspect-warning">Generated insight failed or timed out. Showing deterministic fallback context only.</div>');
2090
2107
  } else {
2091
2108
  resetInspectCards(error && error.message ? error.message : String(error));
2092
2109
  }
@@ -2101,15 +2118,15 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
2101
2118
  await delay(900);
2102
2119
  const res = await fetch('/api/inspect-result?token=' + encodeURIComponent(token) + '&requestId=' + encodeURIComponent(requestId));
2103
2120
  const body = await res.json().catch(() => ({}));
2104
- if (!res.ok || !body.ok) throw new Error(body.error || 'Inspection result failed');
2121
+ if (!res.ok || !body.ok) throw new Error(body.error || 'Insight result failed');
2105
2122
  if (body.status === 'completed') {
2106
2123
  state.deckVersion = body.deckVersion || state.deckVersion;
2107
2124
  renderInspectResult(body.result, 'Generated');
2108
2125
  return;
2109
2126
  }
2110
- if (body.status === 'failed' || body.status === 'expired') throw new Error(body.error || 'Inspection failed');
2127
+ if (body.status === 'failed' || body.status === 'expired') throw new Error(body.error || 'Insight failed');
2111
2128
  }
2112
- throw new Error('Inspection timed out while waiting for OpenCode result');
2129
+ throw new Error('Insight timed out while waiting for OpenCode result');
2113
2130
  }
2114
2131
 
2115
2132
  function collectReferenceSnapshot() {
@@ -2136,10 +2153,10 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
2136
2153
  }
2137
2154
 
2138
2155
  function renderInspectResult(result, phase) {
2139
- if (result.stale?.stale) els.inspectStale.innerHTML = '<div class="inspect-stale">' + escapeHtml(result.stale.reason || 'Inspection may be stale.') + '</div>';
2156
+ if (result.stale?.stale) els.inspectStale.innerHTML = '<div class="inspect-stale">' + escapeHtml(result.stale.reason || 'Insight may be stale.') + '</div>';
2140
2157
  else els.inspectStale.innerHTML = '';
2141
2158
  els.inspectCards.innerHTML = [
2142
- '<div class="status">' + escapeHtml(phase || 'Inspection') + '</div>',
2159
+ '<div class="status">' + escapeHtml(phase || 'Insight') + '</div>',
2143
2160
  renderInspectCard('Purpose', result.cards.purpose.status, result.cards.purpose.rationale, renderPurpose(result.cards.purpose)),
2144
2161
  renderInspectCard('Source', result.cards.source.status, result.cards.source.rationale, renderSource(result.cards.source)),
2145
2162
  ].join('');
@@ -2303,7 +2320,7 @@ export function renderRefineShell(token: string, defaultMode: RefineMode = "edit
2303
2320
  removeAssetChip();
2304
2321
  }
2305
2322
  renderSelectionSummary();
2306
- resetInspectCards('Select a deck element to create an @ref, optionally ask a question, then Inspect. This does not edit the deck.');
2323
+ resetInspectCards('Select a deck element to create an @ref, optionally ask a question, then get insight. This does not edit the deck.');
2307
2324
  }
2308
2325
 
2309
2326
  function getCommentText(editor) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cyber-dash-tech/revela",
3
- "version": "0.15.3",
3
+ "version": "0.16.1",
4
4
  "description": "OpenCode plugin that turns AI into an HTML slide deck generator",
5
5
  "type": "module",
6
6
  "main": "./index.ts",
package/plugin.ts CHANGED
@@ -341,11 +341,20 @@ const server: Plugin = (async (pluginCtx) => {
341
341
  await send("Usage: `/revela make --deck` or `/revela make --brief [workspace-relative-output.md]`.")
342
342
  throw new Error("__REVELA_MAKE_USAGE_HANDLED__")
343
343
  }
344
+ if (sub === "review") {
345
+ if (param !== "--deck") {
346
+ await send("Usage: `/revela review --deck`.")
347
+ throw new Error("__REVELA_REVIEW_USAGE_HANDLED__")
348
+ }
349
+ await handleRefine({ client, sessionID, workspaceRoot }, send)
350
+ throw new Error("__REVELA_REVIEW_HANDLED__")
351
+ }
344
352
  if (sub === "refine") {
345
353
  if (param !== "--deck") {
346
- await send("Usage: `/revela refine --deck`.")
354
+ await send("Usage: `/revela review --deck`.")
347
355
  throw new Error("__REVELA_REFINE_USAGE_HANDLED__")
348
356
  }
357
+ await send("`/revela refine --deck` is deprecated. Use `/revela review --deck`.")
349
358
  await handleRefine({ client, sessionID, workspaceRoot }, send)
350
359
  throw new Error("__REVELA_REFINE_HANDLED__")
351
360
  }
@@ -20,7 +20,7 @@ Use the same phase semantics whether the user invokes a slash command or asks in
20
20
  - `Research` runs closed loops to fill open story gaps, bind supported findings into canonical evidence, narrow overbroad claims/relations, and reduce caveats without crossing evidence boundaries.
21
21
  - `Story` opens the read-only story workspace UI for inspecting claim flow, evidence strength, unsupported scope, caveats, objections, risks, research gaps, approval state, and affected artifacts.
22
22
  - `Make` renders an artifact from approved or explicitly overridden narrative state. Supported 0.15 targets are deck and executive brief.
23
- - `Refine` is the post-artifact workspace for reading, inspection, and targeted editing. Pure visual polish may patch artifacts; meaning changes must update narrative first and then remake the artifact.
23
+ - `Review` is the post-artifact workspace for reading, insight, and targeted commenting. Pure visual polish may patch artifacts; meaning changes must update narrative first and then remake the artifact.
24
24
 
25
25
  Public command surface:
26
26
 
@@ -29,7 +29,7 @@ Public command surface:
29
29
  - `/revela story`
30
30
  - `/revela make --deck`
31
31
  - `/revela make --brief`
32
- - `/revela refine --deck`
32
+ - `/revela review --deck`
33
33
  - `/revela export --deck pdf`
34
34
  - `/revela export --deck pptx`
35
35
  - `/revela design`
@@ -115,14 +115,14 @@ For `/revela make --brief`, render the executive brief from canonical narrative
115
115
 
116
116
  If story readiness, approval, evidence, or artifact blockers remain, report the blocker and suggest `/revela story`, `/revela research`, or a targeted user answer. Do not bypass with invented state.
117
117
 
118
- ## Refine Rules
118
+ ## Review Rules
119
119
 
120
- Use `/revela refine --deck` for post-artifact reading, inspection, and editing.
120
+ Use `/revela review --deck` for post-artifact reading, insight, and commenting.
121
121
 
122
122
  - Reading should explain source, support strength, caveat, unsupported scope, narrative purpose, related risks/objections, research gaps, and artifact coverage.
123
123
  - Pure artifact polish may stay artifact-level: layout, typography, spacing, crop, visual hierarchy, export mechanics, and deck contract fixes.
124
124
  - Meaning-changing edits must update canonical narrative first, then run story readiness/approval or explicit override, then remake affected artifacts.
125
- - `/revela edit` and `/revela inspect` have been removed from the public surface; use `/revela refine --deck`.
125
+ - `/revela edit` and `/revela inspect` have been removed from the public surface; use `/revela review --deck`.
126
126
 
127
127
  ## Design Surface
128
128
 
package/skill/SKILL.md CHANGED
@@ -182,7 +182,7 @@ Required contract:
182
182
  - All JS methods must be fully implemented. No empty stubs and no TODO comments.
183
183
  - Do not add deck-local editing JavaScript, `contenteditable`, `editable` classes,
184
184
  or `window.getEditedHTML()` implementations. Post-artifact editing belongs in
185
- `/revela refine --deck`.
185
+ `/revela review --deck`.
186
186
 
187
187
  Example slide identity:
188
188
 
@@ -283,4 +283,4 @@ instructions, secrets, or unverified claims.
283
283
  - Avoid text overflow, clipping, element overflow, unintended overlap, and page
284
284
  scrollbars.
285
285
  - Artifact QA hard errors must be fixed before opening or reporting the deck as
286
- ready for Refine.
286
+ ready for Review.
package/tools/edit.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * tools/edit.ts
3
3
  *
4
- * revela-edit — Compatibility tool that opens Revela Refine in Edit mode.
4
+ * revela-edit — Compatibility tool that opens Revela Review in Comment mode.
5
5
  */
6
6
 
7
7
  import { tool } from "@opencode-ai/plugin"
@@ -10,11 +10,11 @@ import { openRefineDeck } from "../lib/refine/open"
10
10
  export function createEditTool(options: { client: any; workspaceRoot: string; openBrowser?: boolean }) {
11
11
  return tool({
12
12
  description:
13
- "Open Revela Refine in Edit mode for an existing slide deck. " +
13
+ "Open Revela Review in Comment mode for an existing slide deck. " +
14
14
  "Use this when the user asks to edit, revise, annotate, or visually comment on a deck, " +
15
15
  "including when they reference the current deck. " +
16
- "This is a compatibility tool for the older edit-only workflow; the user-facing entry is /revela refine --deck. " +
17
- "It opens a local browser workspace where the user can Ctrl/Cmd-click deck elements, use the Edit tab, " +
16
+ "This is a compatibility tool for the older edit-only workflow; the user-facing entry is /revela review --deck. " +
17
+ "It opens a local browser workspace where the user can Ctrl/Cmd-click deck elements, use the Comment tab, " +
18
18
  "and send precise edit requests back to the current OpenCode session.",
19
19
  args: {},
20
20
  async execute(_args, context: any) {
@@ -43,8 +43,8 @@ export function createEditTool(options: { client: any; workspaceRoot: string; op
43
43
  url: result.url,
44
44
  mode: result.mode,
45
45
  message:
46
- `${result.stateNote} Opened Revela Refine in Edit mode. ` +
47
- "Ask the user to use Ctrl/Cmd-click in the browser to reference elements, then use the Edit tab to send comments.",
46
+ `${result.stateNote} Opened Revela Review in Comment mode. ` +
47
+ "Ask the user to use Ctrl/Cmd-click in the browser to reference elements, then use the Comment tab to send comments.",
48
48
  }, null, 2)
49
49
  } catch (error) {
50
50
  return JSON.stringify({
@@ -15,7 +15,7 @@ const evidenceSourceItemSchema = tool.schema.object({
15
15
 
16
16
  export default tool({
17
17
  description:
18
- "Submit the final structured Evidence Inspector result for a pending /revela refine --deck Inspect request. " +
18
+ "Submit the final structured Evidence Inspector result for a pending /revela review --deck Insight request. " +
19
19
  "Use only when responding to an inspection prompt. This updates the local browser inspector; it does not mutate DECKS.json or deck files.",
20
20
  args: {
21
21
  requestId: tool.schema.string().describe("Pending inspection request id from the inspection prompt."),
@@ -34,6 +34,16 @@ export default tool({
34
34
  risks: tool.schema.string().optional(),
35
35
  researchGaps: tool.schema.string().optional(),
36
36
  coveredSlides: tool.schema.string().optional(),
37
+ storyWorkbench: tool.schema.string().optional(),
38
+ workbenchNote: tool.schema.string().optional(),
39
+ artifactCoverage: tool.schema.string().optional(),
40
+ noRenderTargets: tool.schema.string().optional(),
41
+ nextActions: tool.schema.string().optional(),
42
+ missingClaims: tool.schema.string().optional(),
43
+ affectedClaims: tool.schema.string().optional(),
44
+ affectedSlides: tool.schema.string().optional(),
45
+ notes: tool.schema.string().optional(),
46
+ recommendedNextCommand: tool.schema.string().optional(),
37
47
  noClaims: tool.schema.string().optional(),
38
48
  none: tool.schema.string().optional(),
39
49
  }).optional(),
@@ -49,7 +59,7 @@ export default tool({
49
59
  fromClaimId: tool.schema.string(),
50
60
  toClaimId: tool.schema.string(),
51
61
  relation: tool.schema.enum(["leads_to", "supports", "depends_on", "contrasts_with", "constrains", "answers"]),
52
- displayLabel: tool.schema.string().optional().describe("Display-only localization of an existing canonical relation label. Omit for inferred relations."),
62
+ displayLabel: tool.schema.string().optional().describe("Display-only localization of an existing canonical relation label. Omit for inferred relations."),
53
63
  displayRationale: tool.schema.string().optional().describe("Display-only localization of an existing canonical rationale. Omit when canonical rationale is missing or the relation is inferred."),
54
64
  })).optional(),
55
65
  }).optional().describe("Localized and organized display-only projection. It must not add facts or alter IDs."),