@deskwork/studio 0.13.0 → 0.14.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 (100) hide show
  1. package/dist/pages/content-detail.d.ts.map +1 -1
  2. package/dist/pages/content-detail.js +5 -4
  3. package/dist/pages/content-detail.js.map +1 -1
  4. package/dist/pages/content-detail.ts +5 -4
  5. package/dist/pages/content.d.ts.map +1 -1
  6. package/dist/pages/content.js +4 -6
  7. package/dist/pages/content.js.map +1 -1
  8. package/dist/pages/content.ts +4 -6
  9. package/dist/pages/dashboard/affordances.d.ts +6 -1
  10. package/dist/pages/dashboard/affordances.d.ts.map +1 -1
  11. package/dist/pages/dashboard/affordances.js +17 -2
  12. package/dist/pages/dashboard/affordances.js.map +1 -1
  13. package/dist/pages/dashboard/affordances.ts +18 -2
  14. package/dist/pages/dashboard/header.js +2 -2
  15. package/dist/pages/dashboard/header.ts +2 -2
  16. package/dist/pages/dashboard/section.d.ts +2 -2
  17. package/dist/pages/dashboard/section.d.ts.map +1 -1
  18. package/dist/pages/dashboard/section.js +5 -5
  19. package/dist/pages/dashboard/section.js.map +1 -1
  20. package/dist/pages/dashboard/section.ts +9 -5
  21. package/dist/pages/dashboard.d.ts.map +1 -1
  22. package/dist/pages/dashboard.js +3 -2
  23. package/dist/pages/dashboard.js.map +1 -1
  24. package/dist/pages/dashboard.ts +3 -2
  25. package/dist/pages/entry-review/data.d.ts +54 -0
  26. package/dist/pages/entry-review/data.d.ts.map +1 -0
  27. package/dist/pages/entry-review/data.js +116 -0
  28. package/dist/pages/entry-review/data.js.map +1 -0
  29. package/dist/pages/entry-review/decision-strip.d.ts +37 -0
  30. package/dist/pages/entry-review/decision-strip.d.ts.map +1 -0
  31. package/dist/pages/entry-review/decision-strip.js +137 -0
  32. package/dist/pages/entry-review/decision-strip.js.map +1 -0
  33. package/dist/pages/entry-review/edit-panes.d.ts +12 -0
  34. package/dist/pages/entry-review/edit-panes.d.ts.map +1 -0
  35. package/dist/pages/entry-review/edit-panes.js +28 -0
  36. package/dist/pages/entry-review/edit-panes.js.map +1 -0
  37. package/dist/pages/entry-review/edit-toolbar.d.ts +20 -0
  38. package/dist/pages/entry-review/edit-toolbar.d.ts.map +1 -0
  39. package/dist/pages/entry-review/edit-toolbar.js +46 -0
  40. package/dist/pages/entry-review/edit-toolbar.js.map +1 -0
  41. package/dist/pages/entry-review/index.d.ts +50 -0
  42. package/dist/pages/entry-review/index.d.ts.map +1 -0
  43. package/dist/pages/entry-review/index.js +219 -0
  44. package/dist/pages/entry-review/index.js.map +1 -0
  45. package/dist/pages/entry-review/marginalia.d.ts +28 -0
  46. package/dist/pages/entry-review/marginalia.d.ts.map +1 -0
  47. package/dist/pages/entry-review/marginalia.js +67 -0
  48. package/dist/pages/entry-review/marginalia.js.map +1 -0
  49. package/dist/pages/entry-review/not-found.d.ts +9 -0
  50. package/dist/pages/entry-review/not-found.d.ts.map +1 -0
  51. package/dist/pages/entry-review/not-found.js +34 -0
  52. package/dist/pages/entry-review/not-found.js.map +1 -0
  53. package/dist/pages/entry-review/outline-drawer.d.ts +12 -0
  54. package/dist/pages/entry-review/outline-drawer.d.ts.map +1 -0
  55. package/dist/pages/entry-review/outline-drawer.js +28 -0
  56. package/dist/pages/entry-review/outline-drawer.js.map +1 -0
  57. package/dist/pages/entry-review/shortcuts.d.ts +14 -0
  58. package/dist/pages/entry-review/shortcuts.d.ts.map +1 -0
  59. package/dist/pages/entry-review/shortcuts.js +36 -0
  60. package/dist/pages/entry-review/shortcuts.js.map +1 -0
  61. package/dist/pages/entry-review/version-strip.d.ts +33 -0
  62. package/dist/pages/entry-review/version-strip.d.ts.map +1 -0
  63. package/dist/pages/entry-review/version-strip.js +81 -0
  64. package/dist/pages/entry-review/version-strip.js.map +1 -0
  65. package/dist/pages/entry-review.d.ts +6 -21
  66. package/dist/pages/entry-review.d.ts.map +1 -1
  67. package/dist/pages/entry-review.js +6 -144
  68. package/dist/pages/entry-review.js.map +1 -1
  69. package/dist/pages/entry-review.ts +11 -181
  70. package/dist/pages/index.d.ts.map +1 -1
  71. package/dist/pages/index.js +6 -10
  72. package/dist/pages/index.js.map +1 -1
  73. package/dist/pages/index.ts +6 -10
  74. package/dist/pages/scrapbook.d.ts.map +1 -1
  75. package/dist/pages/scrapbook.js +208 -11
  76. package/dist/pages/scrapbook.js.map +1 -1
  77. package/dist/pages/scrapbook.ts +209 -10
  78. package/dist/pages/shortform-review.d.ts +32 -0
  79. package/dist/pages/shortform-review.d.ts.map +1 -0
  80. package/dist/pages/shortform-review.js +270 -0
  81. package/dist/pages/shortform-review.js.map +1 -0
  82. package/dist/pages/shortform-review.ts +342 -0
  83. package/dist/routes/api.d.ts +8 -0
  84. package/dist/routes/api.d.ts.map +1 -1
  85. package/dist/routes/api.js +115 -0
  86. package/dist/routes/api.js.map +1 -1
  87. package/dist/routes/entry-annotation-body.d.ts +26 -0
  88. package/dist/routes/entry-annotation-body.d.ts.map +1 -0
  89. package/dist/routes/entry-annotation-body.js +152 -0
  90. package/dist/routes/entry-annotation-body.js.map +1 -0
  91. package/dist/server.d.ts +1 -1
  92. package/dist/server.d.ts.map +1 -1
  93. package/dist/server.js +56 -193
  94. package/dist/server.js.map +1 -1
  95. package/package.json +2 -2
  96. package/dist/pages/review.d.ts +0 -68
  97. package/dist/pages/review.d.ts.map +0 -1
  98. package/dist/pages/review.js +0 -561
  99. package/dist/pages/review.js.map +0 -1
  100. package/dist/pages/review.ts +0 -710
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Data loader for the entry-keyed press-check surface (Phase 34a Layer 2).
3
+ *
4
+ * Resolves an entry UUID to:
5
+ * - the sidecar (`Entry`) + on-disk artifact body (via `resolveEntry`).
6
+ * - the iteration journal listing for the version strip (via Layer 1's
7
+ * `listEntryIterations`).
8
+ * - the entry-keyed annotation list for the marginalia column (via
9
+ * Layer 1's `listEntryAnnotations`).
10
+ * - which site the entry belongs to, by scanning configured calendars
11
+ * for a matching UUID. The scrapbook drawer + content index need the
12
+ * site to resolve filesystem paths and build URLs.
13
+ * - the matching `CalendarEntry` (when present) so the scrapbook drawer
14
+ * can use the index-driven binding rather than slug-template paths.
15
+ *
16
+ * The version-strip can optionally render historical content (when the
17
+ * `?v=<n>` query param is set). When that param is present and resolves
18
+ * to an iteration we have content for, the renderer swaps the on-disk
19
+ * artifact body for the historical markdown captured in the journal.
20
+ */
21
+ import { existsSync } from 'node:fs';
22
+ import { resolveEntry } from "../../lib/entry-resolver.js";
23
+ import { readCalendar } from '@deskwork/core/calendar';
24
+ import { findEntryById } from '@deskwork/core/calendar-mutations';
25
+ import { resolveCalendarPath } from '@deskwork/core/paths';
26
+ import { listEntryIterations, getEntryIteration, } from '@deskwork/core/iterate/history';
27
+ import { listEntryAnnotations } from '@deskwork/core/entry/annotations';
28
+ const VALID_STAGES = new Set([
29
+ 'Ideas', 'Planned', 'Outlining', 'Drafting', 'Final', 'Published', 'Blocked', 'Cancelled',
30
+ ]);
31
+ function parseStageParam(raw) {
32
+ if (raw === null || raw === undefined)
33
+ return undefined;
34
+ for (const stage of VALID_STAGES) {
35
+ if (stage === raw)
36
+ return stage;
37
+ }
38
+ return undefined;
39
+ }
40
+ /**
41
+ * Locate which configured site's calendar the entry belongs to. Returns
42
+ * the first match (entry UUIDs are globally unique). Falls back to
43
+ * `config.defaultSite` with a null `calendarEntry` when no calendar
44
+ * carries the entry.
45
+ *
46
+ * Failures (calendar absent, parse error) fall through to the default
47
+ * — the press-check surface should render even when calendar resolution
48
+ * is wonky for an unrelated reason.
49
+ */
50
+ function findEntrySite(ctx, entryId) {
51
+ for (const site of Object.keys(ctx.config.sites)) {
52
+ try {
53
+ const calendarPath = resolveCalendarPath(ctx.projectRoot, ctx.config, site);
54
+ if (!existsSync(calendarPath))
55
+ continue;
56
+ const cal = readCalendar(calendarPath);
57
+ const entry = findEntryById(cal, entryId);
58
+ if (entry !== undefined) {
59
+ return { site, calendarEntry: entry };
60
+ }
61
+ }
62
+ catch {
63
+ // Calendar unreadable for this site — try the next one.
64
+ continue;
65
+ }
66
+ }
67
+ return { site: ctx.config.defaultSite, calendarEntry: null };
68
+ }
69
+ function parseVersionParam(raw) {
70
+ if (raw === null || raw === undefined)
71
+ return null;
72
+ const parsed = Number.parseInt(raw, 10);
73
+ if (!Number.isFinite(parsed) || parsed <= 0)
74
+ return null;
75
+ return parsed;
76
+ }
77
+ export async function loadEntryReviewData(ctx, entryId, opts = {}) {
78
+ const resolved = await resolveEntry(ctx.projectRoot, entryId);
79
+ const iterations = await listEntryIterations(ctx.projectRoot, entryId);
80
+ const annotations = await listEntryAnnotations(ctx.projectRoot, entryId);
81
+ const { site, calendarEntry } = findEntrySite(ctx, entryId);
82
+ // Historical-version handling. Only swap the markdown when both the
83
+ // version param resolves and the journal has content for it. Stage
84
+ // qualification disambiguates the multi-stage case (Ideas v1 +
85
+ // Drafting v1); when missing, the reader falls back to the first
86
+ // chronological match (loud warn since this means the URL was
87
+ // emitted by something other than the current version-strip).
88
+ let historical = null;
89
+ let markdown = resolved.artifactBody;
90
+ const requested = parseVersionParam(opts.version ?? null);
91
+ const requestedStage = parseStageParam(opts.stage ?? null);
92
+ if (requested !== null) {
93
+ if (requestedStage === undefined && opts.stage !== null && opts.stage !== undefined) {
94
+ // Caller passed a non-empty ?stage= that didn't match any known
95
+ // stage — treat as a malformed query rather than silently
96
+ // dropping it.
97
+ console.warn(`entry-review: ignoring unknown stage param "${opts.stage}" for entry ${entryId}`);
98
+ }
99
+ const found = await getEntryIteration(ctx.projectRoot, entryId, requested, requestedStage);
100
+ if (found !== null) {
101
+ historical = found;
102
+ markdown = found.markdown;
103
+ }
104
+ }
105
+ return {
106
+ entry: resolved.entry,
107
+ artifactPath: resolved.artifactPath,
108
+ markdown,
109
+ historical,
110
+ iterations,
111
+ annotations,
112
+ site,
113
+ calendarEntry,
114
+ };
115
+ }
116
+ //# sourceMappingURL=data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data.js","sourceRoot":"","sources":["../../../src/pages/entry-review/data.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Decision strip for the entry-keyed press-check surface (Phase 34a — T13).
3
+ *
4
+ * Edit toggle + Approve / Iterate / Reject + shortcuts (?) trigger.
5
+ * Drives the press-check decision flow on the entry-centric model:
6
+ *
7
+ * - `Approve` → POST `/api/dev/editorial-review/entry/<uuid>/decision`
8
+ * with `{decision: 'approve'}` (graduates the entry to the next stage).
9
+ * - `Iterate` → POST `/api/dev/editorial-review/entry/<uuid>/version`
10
+ * (records a new iteration via `iterateEntry`).
11
+ * - `Reject` → DISABLED, tooltipped with the GitHub-issue link for the
12
+ * pending design decision (entry-centric reject semantics are
13
+ * undefined; see #173).
14
+ *
15
+ * Affordance set is gated by `getAffordances(entry)` so the strip
16
+ * automatically degrades to read-only / induct-to / fork shapes for
17
+ * Published / Blocked / Cancelled entries (T15-prep).
18
+ *
19
+ * Per `.claude/rules/affordance-placement.md`, the destructive buttons
20
+ * (Approve, Iterate, Reject) are wrapped in `.er-shortcut-chip-wrap`
21
+ * spans carrying small chord chips beneath each button — visual cue
22
+ * for the bare-letter double-tap shortcuts (`a`, `i`, `r`).
23
+ */
24
+ import type { Entry } from '@deskwork/core/schema/entry';
25
+ import type { Affordances } from '../../lib/stage-affordances.ts';
26
+ import { type RawHtml } from '../html.ts';
27
+ interface DecisionStripOptions {
28
+ readonly entry: Entry;
29
+ readonly affordances: Affordances;
30
+ /** Whether the page is rendering a historical version (`?v=<n>`).
31
+ * When true, mutation buttons (Approve / Iterate) render disabled
32
+ * with a tooltip explaining the read-only state. */
33
+ readonly historical: boolean;
34
+ }
35
+ export declare function renderDecisionStrip(opts: DecisionStripOptions): RawHtml;
36
+ export {};
37
+ //# sourceMappingURL=decision-strip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision-strip.d.ts","sourceRoot":"","sources":["../../../src/pages/entry-review/decision-strip.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,6BAA6B,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAClE,OAAO,EAAgB,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAyJxD,UAAU,oBAAoB;IAC5B,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC;IAClC;;yDAEqD;IACrD,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;CAC9B;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAMvE"}
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Decision strip for the entry-keyed press-check surface (Phase 34a — T13).
3
+ *
4
+ * Edit toggle + Approve / Iterate / Reject + shortcuts (?) trigger.
5
+ * Drives the press-check decision flow on the entry-centric model:
6
+ *
7
+ * - `Approve` → POST `/api/dev/editorial-review/entry/<uuid>/decision`
8
+ * with `{decision: 'approve'}` (graduates the entry to the next stage).
9
+ * - `Iterate` → POST `/api/dev/editorial-review/entry/<uuid>/version`
10
+ * (records a new iteration via `iterateEntry`).
11
+ * - `Reject` → DISABLED, tooltipped with the GitHub-issue link for the
12
+ * pending design decision (entry-centric reject semantics are
13
+ * undefined; see #173).
14
+ *
15
+ * Affordance set is gated by `getAffordances(entry)` so the strip
16
+ * automatically degrades to read-only / induct-to / fork shapes for
17
+ * Published / Blocked / Cancelled entries (T15-prep).
18
+ *
19
+ * Per `.claude/rules/affordance-placement.md`, the destructive buttons
20
+ * (Approve, Iterate, Reject) are wrapped in `.er-shortcut-chip-wrap`
21
+ * spans carrying small chord chips beneath each button — visual cue
22
+ * for the bare-letter double-tap shortcuts (`a`, `i`, `r`).
23
+ */
24
+ import { html, unsafe } from "../html.js";
25
+ const REJECT_ISSUE_URL = 'https://github.com/audiocontrol-org/deskwork/issues/173';
26
+ const REJECT_TOOLTIP = `reject semantics filed as #173 — see ${REJECT_ISSUE_URL}`;
27
+ const HISTORICAL_TOOLTIP = 'viewing historical version (read-only) — switch back to current to act';
28
+ const STAGE_PICKER_OPTIONS = [
29
+ 'Ideas',
30
+ 'Planned',
31
+ 'Outlining',
32
+ 'Drafting',
33
+ 'Final',
34
+ ];
35
+ /**
36
+ * Wrap an action button in a `.er-shortcut-chip-wrap` span carrying the
37
+ * chord chip. Mirrors the legacy surface verbatim — bare-letter double-
38
+ * tap with no Cmd/Ctrl modifier (#108).
39
+ */
40
+ function shortcutChipWrap(buttonHtml, letter) {
41
+ return html `<span class="er-shortcut-chip-wrap">${unsafe(buttonHtml)}<small class="er-shortcut-chip"><kbd>${letter}</kbd><kbd>${letter}</kbd></small></span>`;
42
+ }
43
+ function renderEditToggle() {
44
+ // Issue 7 — edit-mode disclosure label sits next to the Edit button.
45
+ // Initial state matches the surface's initial mode (preview).
46
+ return html `<button class="er-btn er-btn-small" data-action="toggle-edit" type="button">Edit</button><span class="er-edit-mode-label" data-mode="preview">preview</span>`;
47
+ }
48
+ function renderInductPicker(entry) {
49
+ const options = STAGE_PICKER_OPTIONS.map((s) => unsafe(html `<option value="${s}">${s}</option>`));
50
+ return html `
51
+ <label class="er-entry-control er-entry-control--induct">
52
+ <span class="er-entry-control-label">Induct to</span>
53
+ <select name="induct-to" data-entry-uuid="${entry.uuid}">
54
+ ${options}
55
+ </select>
56
+ </label>`;
57
+ }
58
+ function renderHistoricalStageDropdown(entry) {
59
+ const stages = Object.keys(entry.iterationByStage);
60
+ if (stages.length === 0)
61
+ return '';
62
+ const options = stages.map((s) => unsafe(html `<option value="${s}">${s}</option>`));
63
+ return html `
64
+ <label class="er-entry-control er-entry-control--history">
65
+ <span class="er-entry-control-label">Historical stage</span>
66
+ <select name="history-stage" data-entry-uuid="${entry.uuid}">
67
+ ${options}
68
+ </select>
69
+ </label>`;
70
+ }
71
+ function renderShortcutsBtn() {
72
+ return html `<button class="er-btn er-btn-small" data-action="shortcuts" type="button" aria-label="Show keyboard shortcuts" title="Keyboard shortcuts">?</button>`;
73
+ }
74
+ /**
75
+ * The full mutable affordance set: Edit + Approve + Iterate + Reject
76
+ * (disabled). Returned as a single concatenated HTML string so the
77
+ * caller can wrap it in `.er-strip-right`.
78
+ */
79
+ function renderMutableButtons({ entry, historical }) {
80
+ const buttons = [];
81
+ buttons.push(renderEditToggle());
82
+ // Phase 34a F2 remediation — Approve/Iterate disabled when viewing a
83
+ // historical version. The endpoints act against live sidecar state,
84
+ // not the historical snapshot; allowing the click while showing
85
+ // historical content is the same "surface lying about content"
86
+ // failure mode 34a was meant to fix. Defense-in-depth: client-side
87
+ // also short-circuits in entry-review/decision.ts.
88
+ const histDisabled = historical ? ' disabled aria-disabled="true"' : '';
89
+ const histTitle = historical ? ` title="${HISTORICAL_TOOLTIP}"` : '';
90
+ // Approve — wired to the entry-keyed decision endpoint.
91
+ buttons.push(shortcutChipWrap(html `<button class="er-btn er-btn-small er-btn-approve" data-action="approve" data-entry-uuid="${entry.uuid}" type="button"${unsafe(histDisabled)}${unsafe(histTitle)}>Approve</button>`, 'a'));
92
+ // Iterate — wired to the entry-keyed version endpoint.
93
+ buttons.push(shortcutChipWrap(html `<button class="er-btn er-btn-small" data-action="iterate" data-entry-uuid="${entry.uuid}" type="button"${unsafe(histDisabled)}${unsafe(histTitle)}>Iterate</button>`, 'i'));
94
+ // Reject — DISABLED pending the design decision in #173.
95
+ buttons.push(shortcutChipWrap(html `<button class="er-btn er-btn-small er-btn-reject" data-action="reject" data-entry-uuid="${entry.uuid}" type="button" disabled title="${REJECT_TOOLTIP}" aria-disabled="true">Reject</button>`, 'r'));
96
+ // Historical-stage dropdown — only useful when more than one stage
97
+ // has recorded iterations for this entry. The renderer returns an
98
+ // empty string when there are none; keep it conditional here so the
99
+ // strip doesn't carry an empty `<label>` for first-iteration entries.
100
+ const history = renderHistoricalStageDropdown(entry);
101
+ if (history)
102
+ buttons.push(history);
103
+ buttons.push(renderShortcutsBtn());
104
+ return buttons.join('');
105
+ }
106
+ function renderReadOnlyButtons(entry, affordances) {
107
+ const buttons = [];
108
+ for (const control of affordances.controls) {
109
+ if (control === 'view-only') {
110
+ buttons.push(html `<span class="er-entry-control er-entry-control--readonly">Read-only</span>`);
111
+ continue;
112
+ }
113
+ if (control === 'fork-placeholder') {
114
+ buttons.push(html `<button class="er-entry-control er-entry-control--button" type="button" disabled data-control="fork">Fork (coming)</button>`);
115
+ continue;
116
+ }
117
+ if (control === 'induct-to') {
118
+ buttons.push(renderInductPicker(entry));
119
+ continue;
120
+ }
121
+ // Unknown read-only control — render a label so the operator sees
122
+ // it in case a new affordance type ships without a renderer
123
+ // counterpart. Throwing here would tank the page; surfacing the
124
+ // raw control name is loud enough that the gap gets noticed.
125
+ buttons.push(html `<span class="er-entry-control">${control}</span>`);
126
+ }
127
+ buttons.push(renderShortcutsBtn());
128
+ return buttons.join('');
129
+ }
130
+ export function renderDecisionStrip(opts) {
131
+ const { entry, affordances, historical } = opts;
132
+ const inner = affordances.mutable
133
+ ? renderMutableButtons({ entry, historical })
134
+ : renderReadOnlyButtons(entry, affordances);
135
+ return unsafe(`<span class="er-strip-right">${inner}</span>`);
136
+ }
137
+ //# sourceMappingURL=decision-strip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decision-strip.js","sourceRoot":"","sources":["../../../src/pages/entry-review/decision-strip.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,EAAE,IAAI,EAAE,MAAM,EAAgB,MAAM,YAAY,CAAC;AAExD,MAAM,gBAAgB,GACpB,yDAAyD,CAAC;AAC5D,MAAM,cAAc,GAAG,wCAAwC,gBAAgB,EAAE,CAAC;AAElF,MAAM,kBAAkB,GACtB,wEAAwE,CAAC;AAE3E,MAAM,oBAAoB,GAAG;IAC3B,OAAO;IACP,SAAS;IACT,WAAW;IACX,UAAU;IACV,OAAO;CACC,CAAC;AAEX;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,UAAkB,EAAE,MAAuB;IACnE,OAAO,IAAI,CAAA,uCAAuC,MAAM,CAAC,UAAU,CAAC,wCAAwC,MAAM,cAAc,MAAM,uBAAuB,CAAC;AAChK,CAAC;AAED,SAAS,gBAAgB;IACvB,qEAAqE;IACrE,8DAA8D;IAC9D,OAAO,IAAI,CAAA,8JAA8J,CAAC;AAC5K,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAY;IACtC,MAAM,OAAO,GAAG,oBAAoB,CAAC,GAAG,CACtC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAA,kBAAkB,CAAC,KAAK,CAAC,WAAW,CAAC,CACxD,CAAC;IACF,OAAO,IAAI,CAAA;;;kDAGqC,KAAK,CAAC,IAAI;UAClD,OAAO;;aAEJ,CAAC;AACd,CAAC;AAED,SAAS,6BAA6B,CAAC,KAAY;IACjD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACnD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACnC,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CACxB,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAA,kBAAkB,CAAC,KAAK,CAAC,WAAW,CAAC,CACxD,CAAC;IACF,OAAO,IAAI,CAAA;;;sDAGyC,KAAK,CAAC,IAAI;UACtD,OAAO;;aAEJ,CAAC;AACd,CAAC;AAED,SAAS,kBAAkB;IACzB,OAAO,IAAI,CAAA,sJAAsJ,CAAC;AACpK,CAAC;AAWD;;;;GAIG;AACH,SAAS,oBAAoB,CAAC,EAAE,KAAK,EAAE,UAAU,EAAkB;IACjE,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,OAAO,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAEjC,qEAAqE;IACrE,oEAAoE;IACpE,gEAAgE;IAChE,+DAA+D;IAC/D,mEAAmE;IACnE,mDAAmD;IACnD,MAAM,YAAY,GAAG,UAAU,CAAC,CAAC,CAAC,gCAAgC,CAAC,CAAC,CAAC,EAAE,CAAC;IACxE,MAAM,SAAS,GAAG,UAAU,CAAC,CAAC,CAAC,WAAW,kBAAkB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAErE,wDAAwD;IACxD,OAAO,CAAC,IAAI,CACV,gBAAgB,CACd,IAAI,CAAA,6FAA6F,KAAK,CAAC,IAAI,kBAAkB,MAAM,CAAC,YAAY,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,mBAAmB,EACxL,GAAG,CACJ,CACF,CAAC;IAEF,uDAAuD;IACvD,OAAO,CAAC,IAAI,CACV,gBAAgB,CACd,IAAI,CAAA,8EAA8E,KAAK,CAAC,IAAI,kBAAkB,MAAM,CAAC,YAAY,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,mBAAmB,EACzK,GAAG,CACJ,CACF,CAAC;IAEF,yDAAyD;IACzD,OAAO,CAAC,IAAI,CACV,gBAAgB,CACd,IAAI,CAAA,2FAA2F,KAAK,CAAC,IAAI,mCAAmC,cAAc,wCAAwC,EAClM,GAAG,CACJ,CACF,CAAC;IAEF,mEAAmE;IACnE,kEAAkE;IAClE,oEAAoE;IACpE,sEAAsE;IACtE,MAAM,OAAO,GAAG,6BAA6B,CAAC,KAAK,CAAC,CAAC;IACrD,IAAI,OAAO;QAAE,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAEnC,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC;IACnC,OAAO,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,qBAAqB,CAAC,KAAY,EAAE,WAAwB;IACnE,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,OAAO,IAAI,WAAW,CAAC,QAAQ,EAAE,CAAC;QAC3C,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;YAC5B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAA,4EAA4E,CAAC,CAAC;YAC/F,SAAS;QACX,CAAC;QACD,IAAI,OAAO,KAAK,kBAAkB,EAAE,CAAC;YACnC,OAAO,CAAC,IAAI,CACV,IAAI,CAAA,6HAA6H,CAClI,CAAC;YACF,SAAS;QACX,CAAC;QACD,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;YAC5B,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC;YACxC,SAAS;QACX,CAAC;QACD,kEAAkE;QAClE,4DAA4D;QAC5D,gEAAgE;QAChE,6DAA6D;QAC7D,OAAO,CAAC,IAAI,CAAC,IAAI,CAAA,kCAAkC,OAAO,SAAS,CAAC,CAAC;IACvE,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC;IACnC,OAAO,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC1B,CAAC;AAWD,MAAM,UAAU,mBAAmB,CAAC,IAA0B;IAC5D,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IAChD,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO;QAC/B,CAAC,CAAC,oBAAoB,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;QAC7C,CAAC,CAAC,qBAAqB,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;IAC9C,OAAO,MAAM,CAAC,gCAAgC,KAAK,SAAS,CAAC,CAAC;AAChE,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Edit-mode panes for the entry-keyed press-check surface (Phase 34a — T8).
3
+ *
4
+ * Relocated from `pages/review.ts:renderEditPanes`. The panes-host lives
5
+ * inside the article column (replacing `#draft-body` when editing). The
6
+ * wrapper keeps the `er-edit-mode` class so existing CSS cascades
7
+ * unchanged. The client flips `[hidden]` on the panes wrapper independently
8
+ * of the toolbar.
9
+ */
10
+ import { type RawHtml } from '../html.ts';
11
+ export declare function renderEditPanes(): RawHtml;
12
+ //# sourceMappingURL=edit-panes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit-panes.d.ts","sourceRoot":"","sources":["../../../src/pages/entry-review/edit-panes.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAgB,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAExD,wBAAgB,eAAe,IAAI,OAAO,CAgBzC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Edit-mode panes for the entry-keyed press-check surface (Phase 34a — T8).
3
+ *
4
+ * Relocated from `pages/review.ts:renderEditPanes`. The panes-host lives
5
+ * inside the article column (replacing `#draft-body` when editing). The
6
+ * wrapper keeps the `er-edit-mode` class so existing CSS cascades
7
+ * unchanged. The client flips `[hidden]` on the panes wrapper independently
8
+ * of the toolbar.
9
+ */
10
+ import { html, unsafe } from "../html.js";
11
+ export function renderEditPanes() {
12
+ return unsafe(html `
13
+ <div class="er-edit-mode" data-edit-panes-host hidden>
14
+ <div class="er-edit-panes" data-edit-panes data-view="source">
15
+ <div class="er-edit-source" data-edit-source aria-label="Markdown source"></div>
16
+ <div class="er-edit-preview" data-edit-preview aria-label="Rendered preview"></div>
17
+ </div>
18
+ <textarea id="draft-edit" data-draft-edit hidden></textarea>
19
+ <div class="er-focus-exit" data-focus-exit aria-hidden="true">
20
+ <button type="button" data-action="exit-focus" title="Exit focus (Esc)">← exit focus</button>
21
+ </div>
22
+ <div class="er-focus-save" data-focus-save aria-hidden="true">
23
+ <button type="button" class="er-btn er-btn-small er-btn-primary" data-action="save-version">Save</button>
24
+ <span class="er-focus-save-hint" data-focus-save-hint></span>
25
+ </div>
26
+ </div>`);
27
+ }
28
+ //# sourceMappingURL=edit-panes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit-panes.js","sourceRoot":"","sources":["../../../src/pages/entry-review/edit-panes.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,EAAgB,MAAM,YAAY,CAAC;AAExD,MAAM,UAAU,eAAe;IAC7B,OAAO,MAAM,CAAC,IAAI,CAAA;;;;;;;;;;;;;;WAcT,CAAC,CAAC;AACb,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Edit-mode toolbar for the entry-keyed press-check surface (Phase 34a — T7).
3
+ *
4
+ * Relocated from `pages/review.ts:renderEditToolbar`. The toolbar lives
5
+ * ABOVE the page-grid; the client (`entry-review-client.ts`) flips its
6
+ * `[hidden]` attribute on enter/exit. Source / Split / Preview tabs +
7
+ * Outline / Focus / Save / Cancel actions. Consumes the existing
8
+ * `editorial-review.css` rules unchanged.
9
+ *
10
+ * Save semantics: the entry-keyed model's `iterateEntry` reads on-disk
11
+ * content, not a request body, so the legacy edit-in-browser-then-save
12
+ * flow has no entry-keyed equivalent. The Save button is rendered
13
+ * `disabled` with a tooltip pointing at issue #174 (operator decision
14
+ * needed on the save shape). Edit mode itself still works — the source
15
+ * pane and the rendered preview pane are functional — only the Save
16
+ * action is intentionally inert pending the design decision.
17
+ */
18
+ import { type RawHtml } from '../html.ts';
19
+ export declare function renderEditToolbar(outlineHasContent: boolean): RawHtml;
20
+ //# sourceMappingURL=edit-toolbar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit-toolbar.d.ts","sourceRoot":"","sources":["../../../src/pages/entry-review/edit-toolbar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAgB,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAOxD,wBAAgB,iBAAiB,CAAC,iBAAiB,EAAE,OAAO,GAAG,OAAO,CAwBrE"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Edit-mode toolbar for the entry-keyed press-check surface (Phase 34a — T7).
3
+ *
4
+ * Relocated from `pages/review.ts:renderEditToolbar`. The toolbar lives
5
+ * ABOVE the page-grid; the client (`entry-review-client.ts`) flips its
6
+ * `[hidden]` attribute on enter/exit. Source / Split / Preview tabs +
7
+ * Outline / Focus / Save / Cancel actions. Consumes the existing
8
+ * `editorial-review.css` rules unchanged.
9
+ *
10
+ * Save semantics: the entry-keyed model's `iterateEntry` reads on-disk
11
+ * content, not a request body, so the legacy edit-in-browser-then-save
12
+ * flow has no entry-keyed equivalent. The Save button is rendered
13
+ * `disabled` with a tooltip pointing at issue #174 (operator decision
14
+ * needed on the save shape). Edit mode itself still works — the source
15
+ * pane and the rendered preview pane are functional — only the Save
16
+ * action is intentionally inert pending the design decision.
17
+ */
18
+ import { html, unsafe } from "../html.js";
19
+ const SAVE_ISSUE_URL = 'https://github.com/audiocontrol-org/deskwork/issues/174';
20
+ const SAVE_TOOLTIP = `Save semantics for the entry-keyed surface are pending design — see ${SAVE_ISSUE_URL}`;
21
+ export function renderEditToolbar(outlineHasContent) {
22
+ const outlineBtnAttrs = outlineHasContent ? '' : ' hidden';
23
+ // #175 Phase 34b — every button carries a tooltip naming what it
24
+ // does + the keyboard shortcut where one exists. The mode tabs
25
+ // (Source / Split / Preview) had no `title` attrs pre-fix; an
26
+ // operator who hadn't memorized them got nothing on hover. The
27
+ // trailing `?` button opens the existing shortcuts overlay so the
28
+ // full keyboard reference is one click away from the toolbar.
29
+ return unsafe(html `
30
+ <div class="er-edit-toolbar" data-edit-toolbar hidden>
31
+ <div class="er-edit-modes" role="tablist" aria-label="Editor mode">
32
+ <button class="er-edit-mode-btn" data-edit-view="source" type="button" aria-pressed="true" title="Edit markdown source only">Source</button>
33
+ <button class="er-edit-mode-btn" data-edit-view="split" type="button" aria-pressed="false" title="Source on the left, rendered preview on the right">Split</button>
34
+ <button class="er-edit-mode-btn" data-edit-view="preview" type="button" aria-pressed="false" title="Rendered preview only">Preview</button>
35
+ </div>
36
+ <div class="er-edit-actions">
37
+ <button class="er-btn er-btn-small" data-action="outline-drawer" type="button" title="Show the outline for reference (O)" aria-pressed="false"${unsafe(outlineBtnAttrs)}>Outline ↗</button>
38
+ <button class="er-btn er-btn-small" data-action="focus-mode" type="button" title="Distraction-free full-viewport canvas (Shift+F)" aria-pressed="false">Focus ⛶</button>
39
+ <button class="er-btn er-btn-primary" data-action="save-version" type="button" disabled aria-disabled="true" title="${SAVE_TOOLTIP}">Save as new version</button>
40
+ <button class="er-btn" data-action="cancel-edit" type="button" title="Discard unsaved edits and exit edit mode">Cancel</button>
41
+ <button class="er-btn er-btn-small" data-action="shortcuts" type="button" aria-label="Show keyboard shortcuts" title="Show all keyboard shortcuts (?)">?</button>
42
+ <span class="er-edit-hint" data-edit-hint></span>
43
+ </div>
44
+ </div>`);
45
+ }
46
+ //# sourceMappingURL=edit-toolbar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"edit-toolbar.js","sourceRoot":"","sources":["../../../src/pages/entry-review/edit-toolbar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,EAAgB,MAAM,YAAY,CAAC;AAExD,MAAM,cAAc,GAClB,yDAAyD,CAAC;AAC5D,MAAM,YAAY,GAChB,uEAAuE,cAAc,EAAE,CAAC;AAE1F,MAAM,UAAU,iBAAiB,CAAC,iBAA0B;IAC1D,MAAM,eAAe,GAAG,iBAAiB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3D,iEAAiE;IACjE,+DAA+D;IAC/D,8DAA8D;IAC9D,+DAA+D;IAC/D,kEAAkE;IAClE,8DAA8D;IAC9D,OAAO,MAAM,CAAC,IAAI,CAAA;;;;;;;;wJAQoI,MAAM,CAAC,eAAe,CAAC;;8HAEjD,YAAY;;;;;WAK/H,CAAC,CAAC;AACb,CAAC"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Top-level renderer for the entry-keyed press-check surface
3
+ * (Phase 34a Layer 2 — `/dev/editorial-review/entry/<uuid>`).
4
+ *
5
+ * Wires every chrome component (folio, version strip, edit toolbar,
6
+ * edit panes, outline drawer, marginalia column + tab, decision strip,
7
+ * scrapbook drawer, shortcuts overlay, rendered preview) against the
8
+ * entry-keyed Layer 1 data layer (sidecar + history-journal iterations
9
+ * + entry-keyed annotations).
10
+ *
11
+ * The relocated chrome shares the existing `editorial-review.css`
12
+ * stylesheet with the legacy longform surface — the chrome IS the
13
+ * existing chrome being relocated. The body data attribute is
14
+ * `data-review-ui="longform"` so the existing `er-*` rules in
15
+ * editorial-review.css cascade correctly.
16
+ *
17
+ * `entry-review.css` (the existing per-stage controller stylesheet)
18
+ * stays linked because the 404 not-found variant + future per-entry
19
+ * affordance polish lives there. The two class families coexist —
20
+ * `.er-*` from the relocated chrome and `.er-entry-*` from the stage
21
+ * controller — without collision.
22
+ *
23
+ * The StudioContext threads through so the scrapbook drawer can
24
+ * resolve the entry's site + content index (per-request memoized via
25
+ * `getRequestContentIndex`).
26
+ */
27
+ import type { ContentIndex } from '@deskwork/core/content-index';
28
+ import type { StudioContext } from '../../routes/api.ts';
29
+ export type EntryReviewIndexGetter = (site: string) => ContentIndex;
30
+ export interface EntryReviewQuery {
31
+ /** `?v=<n>` from the request URL. When set + resolves, shows that
32
+ * iteration's historical content read-only. */
33
+ readonly version?: string | null;
34
+ /** `?stage=<Stage>` from the request URL. Disambiguates historical
35
+ * lookup when an entry has the same version number recorded under
36
+ * multiple stages. Optional; omitted falls back to the first
37
+ * chronological match (single-stage case). */
38
+ readonly stage?: string | null;
39
+ }
40
+ export interface EntryReviewResult {
41
+ status: 200 | 404;
42
+ html: string;
43
+ }
44
+ /**
45
+ * Render the entry-keyed press-check surface for `entryId`. Returns a
46
+ * 404 shell when the sidecar can't be resolved; otherwise renders the
47
+ * full press-check chrome backed by Layer 1's data layer.
48
+ */
49
+ export declare function renderEntryReviewPage(ctx: StudioContext, entryId: string, query?: EntryReviewQuery, getIndex?: EntryReviewIndexGetter): Promise<EntryReviewResult>;
50
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/pages/entry-review/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAQH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAMjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAezD,MAAM,MAAM,sBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,YAAY,CAAC;AAEpE,MAAM,WAAW,gBAAgB;IAC/B;oDACgD;IAChD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC;;;mDAG+C;IAC/C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,GAAG,GAAG,GAAG,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;CACd;AAkGD;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,GAAG,EAAE,aAAa,EAClB,OAAO,EAAE,MAAM,EACf,KAAK,GAAE,gBAAqB,EAC5B,QAAQ,CAAC,EAAE,sBAAsB,GAChC,OAAO,CAAC,iBAAiB,CAAC,CAuH5B"}