@a9n-shoji/rvw 0.2.0 → 0.2.2

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 (105) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +28 -7
  3. package/dist/cli.mjs +492 -307
  4. package/dist/cli.mjs.map +3 -3
  5. package/dist/web/assets/{DocumentViewer-CNgHpCuL.js → DocumentViewer-ADzspLC4.js} +32 -32
  6. package/dist/web/assets/{markdown-source-map-_dS1q5Dg.js → MarkdownTable-DVJ0_MIC.js} +2 -2
  7. package/dist/web/assets/WalkthroughViewer-yQibj2tK.js +1 -0
  8. package/dist/web/assets/{abnfDiagram-N423BO3Z-0v-ndtqQ.js → abnfDiagram-N423BO3Z-6dQzEuPV.js} +1 -1
  9. package/dist/web/assets/architecture-TIHT7OUA-DEoBuEnc.js +1 -0
  10. package/dist/web/assets/{architectureDiagram-T3A2C74G-WSNJ-tZE.js → architectureDiagram-T3A2C74G-DP7hHV7T.js} +1 -1
  11. package/dist/web/assets/{blockDiagram-VBNYF7ZC-lmMbEUwI.js → blockDiagram-VBNYF7ZC-ZbwzVKWP.js} +1 -1
  12. package/dist/web/assets/{c4Diagram-5PPSVZJV-BrN5YVV8.js → c4Diagram-5PPSVZJV-HVD9_uV4.js} +1 -1
  13. package/dist/web/assets/channel-DjgdV-zW.js +1 -0
  14. package/dist/web/assets/{chunk-2GRJ4B5K-gt2JPyrH.js → chunk-2GRJ4B5K-Bkxs2d4J.js} +1 -1
  15. package/dist/web/assets/{chunk-4I5QYGJK-Cg5GZ_-7.js → chunk-4I5QYGJK-BJHE6zC_.js} +1 -1
  16. package/dist/web/assets/{chunk-5RXB4S5H-BdhRGvxW.js → chunk-5RXB4S5H-B-52dfCQ.js} +1 -1
  17. package/dist/web/assets/{chunk-6Q2QTUOP-B1DYWNVJ.js → chunk-6Q2QTUOP-BpD0vQ66.js} +1 -1
  18. package/dist/web/assets/{chunk-7Z6QIM7H-D2YImamZ.js → chunk-7Z6QIM7H-BTI1qgAO.js} +1 -1
  19. package/dist/web/assets/{chunk-GF5L2VYU-CWtwL_CM.js → chunk-GF5L2VYU-B8BxoCCx.js} +1 -1
  20. package/dist/web/assets/{chunk-I66GZJ75-DdoGlxMt.js → chunk-I66GZJ75-zwi-Xf01.js} +1 -1
  21. package/dist/web/assets/{chunk-JQJVKLGR-CVWAp3XP.js → chunk-JQJVKLGR-D9mKBWUz.js} +1 -1
  22. package/dist/web/assets/{chunk-KBJHAD2P-BBacwg3J.js → chunk-KBJHAD2P-Qmtir3qc.js} +1 -1
  23. package/dist/web/assets/{chunk-NSK5VX7P-1AsXiBV3.js → chunk-NSK5VX7P-SP2vZdAo.js} +1 -1
  24. package/dist/web/assets/{chunk-QR6OTTB3-DL2s5pNp.js → chunk-QR6OTTB3-uVDCHurs.js} +1 -1
  25. package/dist/web/assets/{chunk-UBXNYLIW-mu3fkNQI.js → chunk-UBXNYLIW-CtNzBWOU.js} +1 -1
  26. package/dist/web/assets/{chunk-W5SLKNZC-BAwhMBBb.js → chunk-W5SLKNZC-BPfDqbmK.js} +1 -1
  27. package/dist/web/assets/{chunk-WRU74C26-C7IeXZaP.js → chunk-WRU74C26-BZkEOexq.js} +1 -1
  28. package/dist/web/assets/classDiagram-JCYQIIEL-B6Qjam7Y.js +1 -0
  29. package/dist/web/assets/classDiagram-v2-OCEON4UE-B6Qjam7Y.js +1 -0
  30. package/dist/web/assets/{cynefin-VYW2F7L2-DNisGvNv.js → cynefin-VYW2F7L2-BRisCyqC.js} +1 -1
  31. package/dist/web/assets/{cynefinDiagram-MW4NZA55-BA27gOTz.js → cynefinDiagram-MW4NZA55-ClIrmCkB.js} +1 -1
  32. package/dist/web/assets/{dagre-VZM6K2ZE-vo_1YAuM.js → dagre-VZM6K2ZE-X31uC_JB.js} +1 -1
  33. package/dist/web/assets/{diagram-7IWD3JNH-DLLdUj0_.js → diagram-7IWD3JNH-DBQFjl0i.js} +1 -1
  34. package/dist/web/assets/{diagram-B4RE2ZJO-BV0WyNA-.js → diagram-B4RE2ZJO-BZ7934Wg.js} +1 -1
  35. package/dist/web/assets/{diagram-LBJQPF4R-DXxKSx2U.js → diagram-LBJQPF4R-CcJqH9aY.js} +1 -1
  36. package/dist/web/assets/{diagram-Q27KOJAE-DsQ2GzIK.js → diagram-Q27KOJAE-DzM7eiil.js} +1 -1
  37. package/dist/web/assets/{diagram-UB23O5K3-DfjElFP1.js → diagram-UB23O5K3-CVCV-d3m.js} +1 -1
  38. package/dist/web/assets/{ebnfDiagram-BXEA7PRR-cYu0XV1a.js → ebnfDiagram-BXEA7PRR-D8xb9FBp.js} +1 -1
  39. package/dist/web/assets/{erDiagram-JOGREHBK-DnsLBHaV.js → erDiagram-JOGREHBK-1l-G_PMG.js} +1 -1
  40. package/dist/web/assets/eventmodeling-45OFAUF4-ndNeUBOZ.js +1 -0
  41. package/dist/web/assets/flowDiagram-UKHOOZJN-BVxK_6Tu.js +1 -0
  42. package/dist/web/assets/{ganttDiagram-PKOTCBZU-CVD5gq3E.js → ganttDiagram-PKOTCBZU-CDJ9a1tp.js} +1 -1
  43. package/dist/web/assets/{gitGraph-TEB2WS4Q-C_j0n-Kw.js → gitGraph-TEB2WS4Q-DOeTh5wB.js} +1 -1
  44. package/dist/web/assets/{gitGraphDiagram-DS77QQ5N-qACevJmW.js → gitGraphDiagram-DS77QQ5N-DYLxc8Nz.js} +1 -1
  45. package/dist/web/assets/index-9cOaPesh.js +384 -0
  46. package/dist/web/assets/index-kK3hngnz.css +1 -0
  47. package/dist/web/assets/{info-DKCQHKI2-Cmkbz3Yi.js → info-DKCQHKI2-B5u97QuQ.js} +1 -1
  48. package/dist/web/assets/{infoDiagram-6WML65LV-CDrAem7M.js → infoDiagram-6WML65LV-zosKW2OD.js} +1 -1
  49. package/dist/web/assets/{ishikawaDiagram-WSZJBQD7-DXgCnFqW.js → ishikawaDiagram-WSZJBQD7-VYcc_au8.js} +1 -1
  50. package/dist/web/assets/{journeyDiagram-NVQOT4AX-1KW-I7DV.js → journeyDiagram-NVQOT4AX-C_nU8kP4.js} +1 -1
  51. package/dist/web/assets/{kanban-definition-27J2QSJJ-CCt75OuF.js → kanban-definition-27J2QSJJ-DybKaWfx.js} +1 -1
  52. package/dist/web/assets/{line-DQfkDi_r.js → line-DWsGplGj.js} +1 -1
  53. package/dist/web/assets/{mermaid-parser.core-B7TMMtY0.js → mermaid-parser.core-D_T_3oIQ.js} +3 -3
  54. package/dist/web/assets/{mermaid.core-B93x-7Mk.js → mermaid.core-BoLGzxB5.js} +4 -4
  55. package/dist/web/assets/{mindmap-definition-FAOFIHXS-Dyt28V6S.js → mindmap-definition-FAOFIHXS-CsdpqPIa.js} +1 -1
  56. package/dist/web/assets/{packet-7NZHBO7P-zQ0u35s3.js → packet-7NZHBO7P-CReAEF1h.js} +1 -1
  57. package/dist/web/assets/{pegDiagram-VL7TDLO6-et0KHGIE.js → pegDiagram-VL7TDLO6-CE9-NPMu.js} +1 -1
  58. package/dist/web/assets/{pie-RZYD4A2V-uur86LkQ.js → pie-RZYD4A2V-GYixXUka.js} +1 -1
  59. package/dist/web/assets/{pieDiagram-7S7Q4E2Y-c027WPTB.js → pieDiagram-7S7Q4E2Y-CqaAKNg2.js} +1 -1
  60. package/dist/web/assets/{quadrantDiagram-CIZ2JOQS-BtSV4E-0.js → quadrantDiagram-CIZ2JOQS-eRMHJqfj.js} +1 -1
  61. package/dist/web/assets/{radar-I7S5WNFK-B_g0VZMF.js → radar-I7S5WNFK-BwHxP0iK.js} +1 -1
  62. package/dist/web/assets/{railroad-3IZDKUUU-VFLsM_Em.js → railroad-3IZDKUUU-AHc3O4Oz.js} +1 -1
  63. package/dist/web/assets/railroad-abnf-AHOZXSZD-ZKY5olmV.js +1 -0
  64. package/dist/web/assets/railroad-ebnf-EBAXGLYW-CrG1UCMo.js +1 -0
  65. package/dist/web/assets/railroad-peg-LSFZ7HO6-CoY6MIbj.js +1 -0
  66. package/dist/web/assets/{railroadDiagram-AXF67PYL-uOtnxRbQ.js → railroadDiagram-AXF67PYL-BhAxCokG.js} +1 -1
  67. package/dist/web/assets/{requirementDiagram-LRYGKXZP-DGSZAsj4.js → requirementDiagram-LRYGKXZP-BRW-kYhg.js} +1 -1
  68. package/dist/web/assets/{sankeyDiagram-W5VNT64P-CCDk8Vxt.js → sankeyDiagram-W5VNT64P-DfnYLbDJ.js} +1 -1
  69. package/dist/web/assets/{sequenceDiagram-SI44F4Z6-Ce-Jzdk5.js → sequenceDiagram-SI44F4Z6-WEkIPSg8.js} +1 -1
  70. package/dist/web/assets/{stateDiagram-OKZ733FA-BYpYzyEa.js → stateDiagram-OKZ733FA-CdN7veIN.js} +1 -1
  71. package/dist/web/assets/stateDiagram-v2-UEYNNEHI-0xn0gbpn.js +1 -0
  72. package/dist/web/assets/{swimlanes-SLNWSIFB-BL-CUc6d.js → swimlanes-SLNWSIFB-g9wWLf5Y.js} +1 -1
  73. package/dist/web/assets/swimlanesDiagram-ULZ7WXOC-YJ3yh_d3.js +8 -0
  74. package/dist/web/assets/{timeline-definition-Z64GVDOM-p9pkof_K.js → timeline-definition-Z64GVDOM-DjkKZIPE.js} +1 -1
  75. package/dist/web/assets/{treeView-QDETBFTQ-dRhXTU9p.js → treeView-QDETBFTQ-WARa9r09.js} +1 -1
  76. package/dist/web/assets/{treemap-6X3UGDF4-CZHe3dIh.js → treemap-6X3UGDF4-CTFjdb6k.js} +1 -1
  77. package/dist/web/assets/{vennDiagram-T6HMQDX7-ipODJegx.js → vennDiagram-T6HMQDX7-CI9QrBwu.js} +1 -1
  78. package/dist/web/assets/{wardley-OPB4EBWU-CxHlVjkF.js → wardley-OPB4EBWU-Cfo_Nnla.js} +1 -1
  79. package/dist/web/assets/{wardleyDiagram-T6FBY63Y-YarkIncH.js → wardleyDiagram-T6FBY63Y-CzGJ4fzZ.js} +1 -1
  80. package/dist/web/assets/{xychartDiagram-ELKLHX3M-Cw1M-7a4.js → xychartDiagram-ELKLHX3M-BXCiD7gJ.js} +1 -1
  81. package/dist/web/index.html +2 -2
  82. package/migrations/010_comment_post_references.sql +17 -0
  83. package/package.json +2 -1
  84. package/skills/rvw/SKILL.md +79 -6
  85. package/skills/rvw-walkthrough/SKILL.md +1 -1
  86. package/skills/rvw-watch-comments/SKILL.md +217 -67
  87. package/skills/rvw-watch-comments/scripts/auto-ack.mjs +211 -0
  88. package/skills/rvw-watch-comments/scripts/preflight.mjs +108 -0
  89. package/skills/rvw-watch-comments/scripts/rvw-command.mjs +80 -0
  90. package/skills/rvw-watch-comments/scripts/watch-driver.mjs +272 -0
  91. package/skills/rvw-watch-comments/scripts/watch-state.mjs +223 -70
  92. package/dist/web/assets/WalkthroughViewer-BVB3ETHG.js +0 -1
  93. package/dist/web/assets/architecture-TIHT7OUA-BjGWtjPU.js +0 -1
  94. package/dist/web/assets/channel-DkH22XO0.js +0 -1
  95. package/dist/web/assets/classDiagram-JCYQIIEL-C6Z4rmZR.js +0 -1
  96. package/dist/web/assets/classDiagram-v2-OCEON4UE-C6Z4rmZR.js +0 -1
  97. package/dist/web/assets/eventmodeling-45OFAUF4-BUAcQ5NU.js +0 -1
  98. package/dist/web/assets/flowDiagram-UKHOOZJN-hAe9ojjP.js +0 -1
  99. package/dist/web/assets/index-Coye1BY5.js +0 -384
  100. package/dist/web/assets/index-DFdYNMZE.css +0 -1
  101. package/dist/web/assets/railroad-abnf-AHOZXSZD-TVRi9_2L.js +0 -1
  102. package/dist/web/assets/railroad-ebnf-EBAXGLYW-B5B-JrS4.js +0 -1
  103. package/dist/web/assets/railroad-peg-LSFZ7HO6-CfIpa6ba.js +0 -1
  104. package/dist/web/assets/stateDiagram-v2-UEYNNEHI-BJFG9cb2.js +0 -1
  105. package/dist/web/assets/swimlanesDiagram-ULZ7WXOC-BS8L8fb1.js +0 -8
@@ -11,20 +11,37 @@ function fail(message) {
11
11
 
12
12
  function parseOptions(values) {
13
13
  const result = {};
14
+ const flags = new Set(["follow"]);
14
15
  for (let index = 0; index < values.length; index += 1) {
15
16
  const key = values[index];
16
17
  if (!key?.startsWith("--")) fail(`Unexpected argument: ${key ?? ""}`);
18
+ const name = key.slice(2);
17
19
  const value = values[index + 1];
18
- if (value === undefined || value.startsWith("--")) fail(`${key} requires a value`);
19
- result[key.slice(2)] = value;
20
- index += 1;
20
+ if (value === undefined || value.startsWith("--")) {
21
+ if (!flags.has(name)) fail(`${key} requires a value`);
22
+ result[name] = true;
23
+ } else {
24
+ result[name] = value;
25
+ index += 1;
26
+ }
21
27
  }
22
28
  return result;
23
29
  }
24
30
 
25
31
  function required(options, key) {
26
32
  const value = options[key];
27
- if (!value) fail(`--${key} is required`);
33
+ if (typeof value !== "string" || value.length === 0) fail(`--${key} is required`);
34
+ return value;
35
+ }
36
+
37
+ function positiveIntegerOption(options, key, defaultValue) {
38
+ const raw = options[key];
39
+ if (raw === undefined) return defaultValue;
40
+ if (typeof raw !== "string" || !/^\d+$/.test(raw)) {
41
+ fail(`--${key} must be a positive integer`);
42
+ }
43
+ const value = Number(raw);
44
+ if (!Number.isSafeInteger(value) || value < 1) fail(`--${key} must be a positive integer`);
28
45
  return value;
29
46
  }
30
47
 
@@ -39,6 +56,10 @@ function write(value) {
39
56
  process.stdout.write(`${JSON.stringify(value)}\n`);
40
57
  }
41
58
 
59
+ function waitFor(milliseconds) {
60
+ return new Promise((resolve) => setTimeout(resolve, milliseconds));
61
+ }
62
+
42
63
  function openState(statePath, create) {
43
64
  const absolute = path.resolve(statePath);
44
65
  if (create) {
@@ -77,17 +98,11 @@ function openState(statePath, create) {
77
98
  created_at TEXT NOT NULL,
78
99
  updated_at TEXT NOT NULL
79
100
  );
80
- CREATE TABLE IF NOT EXISTS comment_statuses (
81
- comment_ref TEXT PRIMARY KEY,
82
- idempotency_key TEXT NOT NULL UNIQUE,
83
- post_id TEXT UNIQUE,
84
- created_at TEXT NOT NULL,
85
- updated_at TEXT NOT NULL
86
- );
87
101
  CREATE TABLE IF NOT EXISTS operations (
88
102
  batch_id TEXT NOT NULL,
89
103
  comment_ref TEXT NOT NULL,
90
104
  idempotency_key TEXT NOT NULL UNIQUE,
105
+ post_id TEXT,
91
106
  PRIMARY KEY(batch_id, comment_ref)
92
107
  );
93
108
  CREATE TABLE IF NOT EXISTS suppressed_posts (
@@ -102,6 +117,7 @@ function openState(statePath, create) {
102
117
  CREATE INDEX IF NOT EXISTS batches_pending_pr
103
118
  ON batches(status, pull_request_url, next_attempt_at, created_at);
104
119
  `);
120
+ migrateStateSchema(database);
105
121
  if (create) chmodSync(absolute, 0o600);
106
122
  return { database, absolute };
107
123
  }
@@ -135,39 +151,102 @@ function setMeta(database, key, value) {
135
151
  .run(key, value);
136
152
  }
137
153
 
138
- function ensureCommentStatus(database, commentRef, now) {
139
- const existing = database
140
- .prepare("SELECT * FROM comment_statuses WHERE comment_ref = ?")
141
- .get(commentRef);
142
- if (existing) return existing;
143
- const legacyOperation = database
144
- .prepare(
145
- `SELECT o.idempotency_key
146
- FROM operations o
147
- JOIN batches b ON b.id = o.batch_id
148
- WHERE o.comment_ref = ? AND b.status IN ('pending', 'in_flight')
149
- ORDER BY b.created_at DESC LIMIT 1`,
150
- )
151
- .get(commentRef);
152
- const idempotencyKey =
153
- legacyOperation?.idempotency_key ?? `${getMeta(database, "task_id")}:status:${randomUUID()}`;
154
- database
155
- .prepare(
156
- `INSERT INTO comment_statuses(
157
- comment_ref, idempotency_key, post_id, created_at, updated_at
158
- ) VALUES (?, ?, NULL, ?, ?)`,
159
- )
160
- .run(commentRef, idempotencyKey, now, now);
161
- return database.prepare("SELECT * FROM comment_statuses WHERE comment_ref = ?").get(commentRef);
154
+ function tableExists(database, tableName) {
155
+ return Boolean(
156
+ database
157
+ .prepare("SELECT 1 AS present FROM sqlite_master WHERE type = 'table' AND name = ?")
158
+ .get(tableName),
159
+ );
160
+ }
161
+
162
+ function migrateStateSchema(database) {
163
+ const operationColumns = database.prepare("PRAGMA table_info(operations)").all();
164
+ if (
165
+ operationColumns.some((column) => column.name === "post_id") &&
166
+ getMeta(database, "batch_scoped_status_posts") === "1"
167
+ ) {
168
+ return;
169
+ }
170
+ transaction(database, () => {
171
+ const currentOperationColumns = database.prepare("PRAGMA table_info(operations)").all();
172
+ if (!currentOperationColumns.some((column) => column.name === "post_id")) {
173
+ database.exec("ALTER TABLE operations ADD COLUMN post_id TEXT;");
174
+ }
175
+ if (getMeta(database, "batch_scoped_status_posts") === "1") return;
176
+ if (tableExists(database, "comment_statuses")) {
177
+ const rows = database
178
+ .prepare(
179
+ `SELECT b.id AS batch_id, e.comment_ref,
180
+ b.created_at AS batch_created_at,
181
+ o.idempotency_key AS operation_key, o.post_id AS operation_post_id,
182
+ s.idempotency_key AS legacy_key, s.post_id AS legacy_post_id,
183
+ s.updated_at AS legacy_updated_at
184
+ FROM batches b
185
+ JOIN (
186
+ SELECT DISTINCT batch_id, comment_ref FROM events WHERE batch_id IS NOT NULL
187
+ ) e ON e.batch_id = b.id
188
+ LEFT JOIN operations o ON o.batch_id = b.id AND o.comment_ref = e.comment_ref
189
+ LEFT JOIN comment_statuses s ON s.comment_ref = e.comment_ref
190
+ WHERE b.status != 'completed' AND b.attempts > 0
191
+ ORDER BY e.comment_ref,
192
+ CASE b.status WHEN 'in_flight' THEN 0 WHEN 'pending' THEN 1 ELSE 2 END,
193
+ b.created_at DESC`,
194
+ )
195
+ .all();
196
+ const migratedCommentRefs = new Set();
197
+ for (const row of rows) {
198
+ const useLegacyStatus =
199
+ !migratedCommentRefs.has(row.comment_ref) &&
200
+ row.legacy_key &&
201
+ row.legacy_updated_at >= row.batch_created_at;
202
+ if (useLegacyStatus) migratedCommentRefs.add(row.comment_ref);
203
+ if (row.operation_key) {
204
+ if (useLegacyStatus && row.operation_post_id === null && row.legacy_post_id !== null) {
205
+ database
206
+ .prepare("UPDATE operations SET post_id = ? WHERE batch_id = ? AND comment_ref = ?")
207
+ .run(row.legacy_post_id, row.batch_id, row.comment_ref);
208
+ }
209
+ continue;
210
+ }
211
+ database
212
+ .prepare(
213
+ `INSERT INTO operations(batch_id, comment_ref, idempotency_key, post_id)
214
+ VALUES (?, ?, ?, ?)`,
215
+ )
216
+ .run(
217
+ row.batch_id,
218
+ row.comment_ref,
219
+ useLegacyStatus
220
+ ? row.legacy_key
221
+ : `${getMeta(database, "task_id") ?? "task"}:${row.batch_id}:${randomUUID()}`,
222
+ useLegacyStatus ? row.legacy_post_id : null,
223
+ );
224
+ }
225
+ }
226
+ setMeta(database, "batch_scoped_status_posts", "1");
227
+ });
228
+ }
229
+
230
+ function ensureBatchOperations(database, batchId) {
231
+ const commentRefs = database
232
+ .prepare("SELECT DISTINCT comment_ref FROM events WHERE batch_id = ? ORDER BY comment_ref")
233
+ .all(batchId)
234
+ .map((operation) => operation.comment_ref);
235
+ for (let index = 0; index < commentRefs.length; index += 1) {
236
+ database
237
+ .prepare(
238
+ `INSERT OR IGNORE INTO operations(batch_id, comment_ref, idempotency_key, post_id)
239
+ VALUES (?, ?, ?, NULL)`,
240
+ )
241
+ .run(batchId, commentRefs[index], `${getMeta(database, "task_id")}:${batchId}:${index + 1}`);
242
+ }
162
243
  }
163
244
 
164
245
  function batchStatusOperations(database, batchId) {
165
246
  return database
166
247
  .prepare(
167
- `SELECT DISTINCT e.comment_ref, s.post_id
168
- FROM events e
169
- LEFT JOIN comment_statuses s ON s.comment_ref = e.comment_ref
170
- WHERE e.batch_id = ? ORDER BY e.comment_ref`,
248
+ `SELECT comment_ref, post_id FROM operations
249
+ WHERE batch_id = ? ORDER BY comment_ref`,
171
250
  )
172
251
  .all(batchId)
173
252
  .map((operation) => ({
@@ -290,19 +369,19 @@ function ingestEvent(database, frame) {
290
369
  now,
291
370
  );
292
371
  if (event.deleted) {
293
- const commentStatus = database
294
- .prepare("SELECT comment_ref FROM comment_statuses WHERE post_id = ?")
295
- .get(event.postId);
296
- if (commentStatus) {
372
+ const operations = database
373
+ .prepare("SELECT batch_id, comment_ref FROM operations WHERE post_id = ?")
374
+ .all(event.postId);
375
+ for (const operation of operations) {
297
376
  database
298
377
  .prepare(
299
- `UPDATE comment_statuses SET post_id = NULL, idempotency_key = ?, updated_at = ?
300
- WHERE comment_ref = ?`,
378
+ `UPDATE operations SET post_id = NULL, idempotency_key = ?
379
+ WHERE batch_id = ? AND comment_ref = ?`,
301
380
  )
302
381
  .run(
303
- `${getMeta(database, "task_id")}:status:${randomUUID()}`,
304
- now,
305
- commentStatus.comment_ref,
382
+ `${getMeta(database, "task_id")}:${operation.batch_id}:${randomUUID()}`,
383
+ operation.batch_id,
384
+ operation.comment_ref,
306
385
  );
307
386
  }
308
387
  }
@@ -376,6 +455,34 @@ function listPending(database) {
376
455
  });
377
456
  }
378
457
 
458
+ async function waitForPending(database, options) {
459
+ const intervalMs = positiveIntegerOption(options, "interval-ms", 250);
460
+ const follow = options.follow === true;
461
+ let wasNonEmpty = false;
462
+ do {
463
+ const pending = listPending(database);
464
+ const isNonEmpty = pending.length > 0;
465
+ if (isNonEmpty && !wasNonEmpty) {
466
+ write({
467
+ ok: true,
468
+ type: "pending",
469
+ pullRequests: pending.map((batch) => batch.pullRequest),
470
+ pending,
471
+ });
472
+ if (!follow) return;
473
+ }
474
+ wasNonEmpty = isNonEmpty;
475
+ await waitFor(intervalMs);
476
+ } while (follow || !wasNonEmpty);
477
+ }
478
+
479
+ function normalizeWriteKey(writeKey) {
480
+ if (typeof writeKey !== "string" || !/^[^/\s]+\/[^/\s]+$/.test(writeKey)) {
481
+ fail("--write-key must be owner/repository");
482
+ }
483
+ return writeKey.toLowerCase();
484
+ }
485
+
379
486
  function createBatch(database, pullRequestUrl, now) {
380
487
  const batchId = randomUUID();
381
488
  const events = database
@@ -399,16 +506,12 @@ function createBatch(database, pullRequestUrl, now) {
399
506
  "UPDATE events SET batch_id = ?, updated_at = ? WHERE pull_request_url = ? AND status = 'pending' AND batch_id IS NULL",
400
507
  )
401
508
  .run(batchId, now, pullRequestUrl);
402
- const commentRefs = [...new Set(events.map((event) => event.comment_ref))];
403
- for (const commentRef of commentRefs) ensureCommentStatus(database, commentRef, now);
509
+ ensureBatchOperations(database, batchId);
404
510
  return batchId;
405
511
  }
406
512
 
407
513
  function claim(database, pullRequestUrl, writeKey) {
408
- if (writeKey !== undefined && !/^[^/\s]+\/[^/\s]+$/.test(writeKey)) {
409
- fail("--write-key must be owner/repository");
410
- }
411
- const canonicalWriteKey = writeKey?.toLowerCase();
514
+ const canonicalWriteKey = writeKey === undefined ? undefined : normalizeWriteKey(writeKey);
412
515
  return transaction(database, () => {
413
516
  const now = new Date().toISOString();
414
517
  const active = database
@@ -451,17 +554,11 @@ function claim(database, pullRequestUrl, writeKey) {
451
554
  commentRef: event.comment_ref,
452
555
  pullRequestUrl: event.pull_request_url,
453
556
  }));
454
- const commentRefs = database
455
- .prepare("SELECT DISTINCT comment_ref FROM events WHERE batch_id = ? ORDER BY comment_ref")
456
- .all(batchId)
457
- .map((operation) => operation.comment_ref);
458
- for (const commentRef of commentRefs) ensureCommentStatus(database, commentRef, now);
557
+ ensureBatchOperations(database, batchId);
459
558
  const operations = database
460
559
  .prepare(
461
- `SELECT DISTINCT e.comment_ref, s.idempotency_key, s.post_id
462
- FROM events e
463
- JOIN comment_statuses s ON s.comment_ref = e.comment_ref
464
- WHERE e.batch_id = ? ORDER BY e.comment_ref`,
560
+ `SELECT comment_ref, idempotency_key, post_id FROM operations
561
+ WHERE batch_id = ? ORDER BY comment_ref`,
465
562
  )
466
563
  .all(batchId)
467
564
  .map((operation) => ({
@@ -481,6 +578,36 @@ function claim(database, pullRequestUrl, writeKey) {
481
578
  });
482
579
  }
483
580
 
581
+ function reserveWrite(database, leaseId, writeKey) {
582
+ const canonicalWriteKey = normalizeWriteKey(writeKey);
583
+ return transaction(database, () => {
584
+ const batch = database
585
+ .prepare("SELECT * FROM batches WHERE lease_id = ? AND status = 'in_flight'")
586
+ .get(leaseId);
587
+ if (!batch) fail("Active lease was not found");
588
+ if (batch.write_key !== null && batch.write_key !== canonicalWriteKey) {
589
+ fail(`Active lease already owns repository ${batch.write_key}`);
590
+ }
591
+ try {
592
+ database
593
+ .prepare("UPDATE batches SET write_key = ?, updated_at = ? WHERE id = ?")
594
+ .run(canonicalWriteKey, new Date().toISOString(), batch.id);
595
+ } catch (error) {
596
+ if (String(error).includes("UNIQUE constraint failed")) {
597
+ fail(`Another write-capable batch owns repository ${canonicalWriteKey}`);
598
+ }
599
+ throw error;
600
+ }
601
+ return {
602
+ leaseId,
603
+ batchId: batch.id,
604
+ pullRequest: batch.pull_request_url,
605
+ writeKey: canonicalWriteKey,
606
+ status: batch.write_key === canonicalWriteKey ? "existing" : "reserved",
607
+ };
608
+ });
609
+ }
610
+
484
611
  function acknowledge(database, leaseId, input) {
485
612
  if (typeof input.commentRef !== "string" || input.commentRef.length === 0) {
486
613
  fail("commentRef is required");
@@ -492,17 +619,16 @@ function acknowledge(database, leaseId, input) {
492
619
  .get(leaseId);
493
620
  if (!batch) fail("Active lease was not found");
494
621
  const operation = database
495
- .prepare("SELECT 1 AS present FROM events WHERE batch_id = ? AND comment_ref = ? LIMIT 1")
622
+ .prepare("SELECT post_id FROM operations WHERE batch_id = ? AND comment_ref = ?")
496
623
  .get(batch.id, input.commentRef);
497
624
  if (!operation) fail("Comment is not part of the active lease");
498
625
  const now = new Date().toISOString();
499
- const status = ensureCommentStatus(database, input.commentRef, now);
500
- if (status.post_id !== null && status.post_id !== input.postId) {
501
- fail("Comment already has another status post");
626
+ if (operation.post_id !== null && operation.post_id !== input.postId) {
627
+ fail("Batch operation already has another status post");
502
628
  }
503
629
  database
504
- .prepare("UPDATE comment_statuses SET post_id = ?, updated_at = ? WHERE comment_ref = ?")
505
- .run(input.postId, now, input.commentRef);
630
+ .prepare("UPDATE operations SET post_id = ? WHERE batch_id = ? AND comment_ref = ?")
631
+ .run(input.postId, batch.id, input.commentRef);
506
632
  database
507
633
  .prepare("INSERT OR IGNORE INTO suppressed_posts(post_id, created_at) VALUES (?, ?)")
508
634
  .run(input.postId, now);
@@ -515,7 +641,7 @@ function acknowledge(database, leaseId, input) {
515
641
  batchId: batch.id,
516
642
  commentRef: input.commentRef,
517
643
  statusPostId: input.postId,
518
- status: status.post_id === null ? "recorded" : "existing",
644
+ status: operation.post_id === null ? "recorded" : "existing",
519
645
  };
520
646
  });
521
647
  }
@@ -635,6 +761,21 @@ function status(database) {
635
761
  const unbatched = database
636
762
  .prepare("SELECT count(*) AS count FROM events WHERE status = 'pending' AND batch_id IS NULL")
637
763
  .get();
764
+ const inFlightBatches = database
765
+ .prepare(
766
+ `SELECT id, pull_request_url, attempts, lease_id, write_key, updated_at
767
+ FROM batches WHERE status = 'in_flight' ORDER BY created_at`,
768
+ )
769
+ .all()
770
+ .map((batch) => ({
771
+ batchId: batch.id,
772
+ leaseId: batch.lease_id,
773
+ pullRequest: batch.pull_request_url,
774
+ attempts: Number(batch.attempts),
775
+ writeKey: batch.write_key,
776
+ updatedAt: batch.updated_at,
777
+ operations: batchStatusOperations(database, batch.id),
778
+ }));
638
779
  return {
639
780
  taskId: getMeta(database, "task_id"),
640
781
  databaseId: getMeta(database, "database_id"),
@@ -649,6 +790,7 @@ function status(database) {
649
790
  quarantined: batchCounts.quarantined ?? 0,
650
791
  unbatchedEvents: Number(unbatched.count),
651
792
  },
793
+ inFlightBatches,
652
794
  quarantinedBatches: quarantinedBatches(database),
653
795
  };
654
796
  }
@@ -683,6 +825,10 @@ async function main() {
683
825
  write({ ok: true, pending: listPending(database) });
684
826
  return;
685
827
  }
828
+ if (command === "wait") {
829
+ await waitForPending(database, options);
830
+ return;
831
+ }
686
832
  if (command === "claim") {
687
833
  write({
688
834
  ok: true,
@@ -690,6 +836,13 @@ async function main() {
690
836
  });
691
837
  return;
692
838
  }
839
+ if (command === "reserve-write") {
840
+ write({
841
+ ok: true,
842
+ ...reserveWrite(database, required(options, "lease"), required(options, "write-key")),
843
+ });
844
+ return;
845
+ }
693
846
  if (command === "complete") {
694
847
  write({ ok: true, ...complete(database, required(options, "lease"), await readInput()) });
695
848
  return;
@@ -1 +0,0 @@
1
- import{r as e}from"./rolldown-runtime-hePW80VL.js";import{B as t,F as n,H as r,L as i,M as a,N as o,P as s,T as c,U as l,V as u,b as d,c as f,d as p,g as m,l as h,o as g,s as _,w as v,x as y,y as b,z as x}from"./index-Coye1BY5.js";import{a as S,i as C,n as w,r as T,t as E}from"./markdown-source-map-_dS1q5Dg.js";var D=e(l(),1),O=r(),k=2400,A={...d,protocols:{...d.protocols,href:[...d.protocols?.href??[],`rvw-ref`]}};function j(e){return e?.startsWith(`rvw-ref:`)?e.slice(8):null}function M(e){return D.Children.toArray(e).map(e=>typeof e==`string`||typeof e==`number`?String(e):(0,D.isValidElement)(e)?M(e.props.children):``).join(``)}function N(e){return e.startLine===null||e.endLine===null?null:e.startLine===e.endLine?`L${e.startLine}`:`L${e.startLine}–${e.endLine}`}function P(e){let t=N(e);return t?`${e.path}:${t}`:e.path}function F(e,t){return!!(e&&t&&e.startLine===t.startLine&&e.endLine===t.endLine)}function I(){return(0,O.jsx)(`svg`,{"aria-hidden":`true`,viewBox:`0 0 16 16`,width:`16`,height:`16`,children:(0,O.jsx)(`path`,{fill:`currentColor`,d:`M5.5 1.75A1.75 1.75 0 0 1 7.25 0h1.5a1.75 1.75 0 0 1 1.75 1.75V2h3a.75.75 0 0 1 0 1.5h-.64l-.68 10.03A2.5 2.5 0 0 1 9.69 16H6.31a2.5 2.5 0 0 1-2.49-2.47L3.14 3.5H2.5a.75.75 0 0 1 0-1.5h3v-.25Zm1.5 0V2h2v-.25a.25.25 0 0 0-.25-.25h-1.5a.25.25 0 0 0-.25.25ZM4.65 3.5l.67 9.96c.02.58.46 1.04.99 1.04h3.38c.53 0 .97-.46.99-1.04l.67-9.96h-6.7Z`})})}function L({source:e,sourceRange:t,commented:n,bindings:r,references:i,themePreference:o,onOpenReference:s,onCommentRange:c,commentComposer:l}){let u=(0,D.useRef)(null),d=!!l;(0,D.useLayoutEffect)(()=>{if(!d)return;let e=window.requestAnimationFrame(()=>{u.current?.scrollIntoView({block:`nearest`,inline:`nearest`})});return()=>window.cancelAnimationFrame(e)},[d]);let f=(0,D.useCallback)(e=>{if(!(e instanceof Element))return;let t=e.closest(`[data-walkthrough-reference-id]`)?.dataset.walkthroughReferenceId;return t?i.get(t):void 0},[i]),p=(0,D.useCallback)(e=>{for(let t of e.querySelectorAll(`g.node, g.classGroup, g[data-id], g[id^='classId-']`)){let e=t.dataset.id??Object.keys(r).find(e=>t.id===e||t.id.includes(`-${e}`)||t.id.includes(`-${e}-`)||t.id.endsWith(`-${e}`));if(!e)continue;let n=r[e],a=n?i.get(n):void 0;a&&(t.classList.add(`walkthrough-diagram-node--linked`),t.setAttribute(`role`,`button`),t.setAttribute(`tabindex`,`0`),t.setAttribute(`aria-label`,`${a.label}をコードで開く`),t.dataset.walkthroughReferenceId=a.id)}},[r,i]);return(0,O.jsxs)(`div`,{className:`walkthrough-diagram-shell${n?` has-comment`:``}`,...t?{"data-rvw-navigation-start-line":t.startLine,"data-rvw-navigation-end-line":t.endLine}:{},children:[(0,O.jsxs)(`div`,{className:`walkthrough-diagram-toolbar`,children:[(0,O.jsx)(`span`,{children:`Mermaid diagram`}),(0,O.jsx)(`span`,{children:`nodeを選択して開く · Cmd/Ctrlで反対のペイン`}),t&&(0,O.jsxs)(`button`,{className:`button--quiet walkthrough-diagram-comment`,onPointerDown:e=>{e.button===0&&(e.preventDefault(),c(t))},onClick:e=>{e.detail===0&&c(t)},children:[(0,O.jsx)(a,{}),`図全体へコメント`]})]}),(0,O.jsx)(h,{className:`walkthrough-diagram`,source:e,themePreference:o,renderIdPrefix:`rvwWalkthrough`,errorClassName:`walkthrough-diagram-error`,onRendered:p,onPointerDown:e=>{let t=f(e.target);t&&(e.preventDefault(),e.stopPropagation(),s(t,e.metaKey||e.ctrlKey))},onKeyDown:e=>{if(e.key!==`Enter`&&e.key!==` `)return;let t=f(e.target);t&&(e.preventDefault(),s(t,!1))}}),l&&(0,O.jsx)(`div`,{className:`walkthrough-diagram-comment-composer`,ref:u,children:l})]})}var R=(0,D.createContext)(null);function z({range:e,pending:t,error:n,onCancel:r,onSubmit:i}){let[a,s]=(0,D.useState)(``),c=e.startLine===e.endLine?`L${e.startLine}へコメント`:`L${e.startLine}–${e.endLine}へコメント`;return(0,O.jsx)(o,{body:a,label:c,pending:t,error:n,validationError:void 0,placement:`line`,onBodyChange:s,onCancel:r,onSubmit:()=>i(a)})}var B=({children:e,node:t,...n})=>{let r=(0,D.useContext)(R),i=D.Children.count(e)===1?D.Children.only(e):null;if(!r||!(0,D.isValidElement)(i)||i.props.className!==`language-mermaid`)return(0,O.jsx)(`pre`,{...n,children:e});let a=T(t);return(0,O.jsx)(L,{source:M(i.props.children).trim(),sourceRange:a,commented:!!(a&&r.activeCommentId&&r.placedComments.some(({comment:e,placement:t})=>e.id===r.activeCommentId&&t.range&&t.range.startLine<=a.endLine&&t.range.endLine>=a.startLine)),bindings:r.diagramBindings,references:r.references,themePreference:r.themePreference,onOpenReference:r.onOpenReference,onCommentRange:r.onCommentRange,commentComposer:a&&F(a,r.diagramCommentRange)?(0,O.jsx)(z,{range:a,pending:r.diagramCommentPending,error:r.diagramCommentError,onCancel:r.onCancelDiagramComment,onSubmit:e=>r.onSubmitDiagramComment(a,e)},`${a.startLine}:${a.endLine}`):null})},V=(0,D.memo)(function({body:e,diagramBindings:t,references:n,placedComments:r,activeCommentId:i,selectedRange:a,selectionComposerOpen:o,diagramCommentRange:s,markdownSourceOid:l,themePreference:u,onOpenReference:d,onOpenRepositoryLink:h,onCommentActiveChange:g,onCommentRange:x,diagramCommentPending:T,diagramCommentError:E,onCancelDiagramComment:k,onSubmitDiagramComment:M}){let F=(0,D.useRef)(null),I=(0,D.useMemo)(()=>r.map(({comment:e,placement:t})=>({id:e.id,range:t.range})),[r]),L=(0,D.useMemo)(()=>new Map(r.map(({comment:e,placement:t})=>[e.id,{comment:e,placement:t}])),[r]),z=(0,D.useCallback)(({node:e,children:t,...n})=>{let r=w(e);return r.length===0?(0,O.jsx)(`div`,{...n,children:t}):(0,O.jsx)(`div`,{className:`markdown-inline-comments`,children:r.map(e=>{let t=L.get(e);return t?(0,O.jsx)(f,{comment:t.comment,variant:`inline`,placement:t.placement,markdownSourceOid:l,themePreference:u,onActiveChange:g,onOpenRepositoryLink:h},e):null})})},[L,l,g,h,u]);return(0,O.jsx)(R.Provider,{value:{diagramBindings:t,references:n,placedComments:r,activeCommentId:i,diagramCommentRange:s,themePreference:u,onOpenReference:d,onCommentRange:x,diagramCommentPending:T,diagramCommentError:E,onCancelDiagramComment:k,onSubmitDiagramComment:M},children:(0,O.jsx)(`article`,{className:`walkthrough-markdown`,children:(0,O.jsx)(v,{rehypePlugins:[y,[b,A],[S,{annotations:I,activeCommentId:i,selectedRange:a,composerOpen:o}]],remarkPlugins:[m],urlTransform:e=>e.startsWith(`rvw-ref:`)?e:c(e),components:{div:z,table:({children:e,node:t,...n})=>(0,O.jsx)(`div`,{className:`markdown-table-scroll`,children:(0,O.jsx)(`table`,{...C(t),...n,children:e})}),a:({href:e,children:t,node:r,...i})=>{let a=j(e),o=a?n.get(a):void 0;return o?(0,O.jsxs)(`button`,{className:`walkthrough-inline-reference`,title:P(o),onPointerDown:e=>{e.button===0&&(F.current={x:e.clientX,y:e.clientY})},onPointerUp:e=>{let t=F.current;F.current=null,t&&(Math.hypot(e.clientX-t.x,e.clientY-t.y)>4||(e.preventDefault(),e.stopPropagation(),d(o,e.metaKey||e.ctrlKey)))},onPointerCancel:()=>{F.current=null},onClick:e=>{e.preventDefault(),e.detail===0&&d(o,!1)},onContextMenu:e=>{(e.ctrlKey||e.metaKey)&&e.preventDefault()},children:[(0,O.jsx)(_,{path:o.path,kind:`file`}),(0,O.jsx)(`span`,{children:t}),(0,O.jsx)(`small`,{children:N(o)??`File`})]}):(0,O.jsx)(`a`,{...C(r),...i,href:e,children:t})},img:({alt:e,title:t,node:n})=>(0,O.jsx)(p,{alt:e,title:t,sourceAttributes:C(n)}),pre:B},children:e})})})});function H({walkthrough:e,comments:r,activeCommentId:c,navigationTarget:l,onNavigationApplied:d,themePreference:p,onCommentActiveChange:m,onOpenReference:h,onOpenRepositoryLink:_,onDeleted:v}){let y=u(),b=(0,D.useRef)(null),S=(0,D.useRef)(null),C=(0,D.useRef)(d);C.current=d;let[w,T]=(0,D.useState)(!1),[A,j]=(0,D.useState)(null),[M,N]=(0,D.useState)(null),[P,F]=(0,D.useState)(null),[L,R]=(0,D.useState)(``),[z,B]=(0,D.useState)(null),H=(0,D.useRef)(0),U=(0,D.useRef)(null),ee=(0,D.useMemo)(()=>new Map(e.references.map(e=>[e.id,e])),[e.references]);(0,D.useLayoutEffect)(()=>{if(!l||S.current===l.requestId)return;let e=l.requestId,t=window.requestAnimationFrame(()=>{let t=b.current;if(!t)return;if(l.line===null){t.scrollIntoView({behavior:`auto`,block:`start`,inline:`nearest`}),S.current=e,C.current(e);return}let n=String(l.line),r=t.querySelector(`[data-rvw-navigation-start-line="${n}"]`)??t.querySelector(`[data-rvw-source-start-line="${n}"]`),i=r?.closest(`details:not([open])`);i&&(i.open=!0),r&&(r.scrollIntoView({behavior:`auto`,block:`center`,inline:`nearest`}),S.current=e,C.current(e))});return()=>window.cancelAnimationFrame(t)},[l]);let W=(0,D.useCallback)((t,n)=>{H.current+=1;let r=H.current;U.current!==null&&(window.clearTimeout(U.current),U.current=null),B(null),h(e,t,n).then(e=>{r!==H.current||!e||(B(e),U.current=window.setTimeout(()=>{B(null),U.current=null},k))})},[h,e]);(0,D.useEffect)(()=>()=>{H.current+=1,U.current!==null&&window.clearTimeout(U.current)},[]);let G=r.filter(t=>t.target.kind===`walkthrough`&&t.target.walkthroughId===e.id),K=G.reduce((e,t)=>e+t.posts.length,0),q=t({queryKey:[`walkthrough-comment-placements`,e.id,e.body,G.map(e=>`${e.id}:${e.updatedAt}`)],queryFn:async()=>{let t=new URLSearchParams({kind:`walkthrough`,pullRequestId:e.pullRequestId,walkthroughId:e.id});return await Promise.all(G.map(async e=>({comment:e,placement:(await n(`/api/comments/${e.id}/placement?${t.toString()}`)).placement})))},enabled:G.length>0}),J=(0,D.useMemo)(()=>q.data??[],[q.data]),te=(0,D.useMemo)(()=>J.filter(({placement:e})=>!e.outdated&&e.range!==null),[J]),Y=(0,D.useMemo)(()=>J.filter(({comment:e,placement:t})=>e.target.kind===`walkthrough`&&e.target.startLine===null||t.outdated),[J]),X=x({mutationFn:async({range:t,body:r})=>await n(`/api/comments`,i({pullRequestId:e.pullRequestId,target:{kind:`walkthrough`,walkthroughId:e.id,startLine:t?.startLine??null,endLine:t?.endLine??null},body:r,authorLabel:`You`})),onSuccess:async()=>{window.getSelection()?.removeAllRanges(),R(``),T(!1),j(null),N(null),F(null),await y.invalidateQueries({queryKey:[`comments`]}),await y.invalidateQueries({queryKey:[`change-sequence`]})}}),Z=x({mutationFn:async()=>await n(`/api/pull-requests/${e.pullRequestId}/walkthroughs/${e.id}`,{...i({}),method:`DELETE`}),onSuccess:async()=>{v(e),await Promise.all([y.invalidateQueries({queryKey:[`walkthroughs`]}),y.invalidateQueries({queryKey:[`walkthrough`]}),y.invalidateQueries({queryKey:[`comments`]}),y.invalidateQueries({queryKey:[`change-sequence`]})])}}),Q=G.filter(e=>e.resolvedAt===null).length,ne=()=>{let e=G.length===0?`紐づくコメントはありません。`:`紐づくコメント ${G.length}件と投稿 ${K}件も削除されます。`;window.confirm(`このウォークスルーを削除します。\n${e}\nコピー済みの参照は無効になります。\n\nこの操作は元に戻せません。`)&&Z.mutate()},re=A?A.startLine===A.endLine?`L${A.startLine}`:`L${A.startLine}–${A.endLine}`:null,$=()=>{window.getSelection()?.removeAllRanges(),X.reset(),R(``),j(null),N(null),F(null)},ie=e=>{X.reset(),R(``),T(!1),j(null),N(e),F(`diagram`)},ae=A?(0,O.jsx)(o,{body:L,label:`${re??`選択範囲`}へコメント`,pending:X.isPending,error:X.error,validationError:void 0,placement:`line`,onBodyChange:R,onCancel:$,onSubmit:()=>X.mutate({range:A,body:L})}):null,oe=(0,O.jsx)(V,{body:e.body,diagramBindings:e.diagramBindings,references:ee,placedComments:te,activeCommentId:c,selectedRange:P===`selection`?A:null,selectionComposerOpen:P===`selection`,diagramCommentRange:M,markdownSourceOid:e.sourceOid,themePreference:p,onOpenReference:W,onOpenRepositoryLink:_,onCommentActiveChange:m,onCommentRange:ie,diagramCommentPending:X.isPending,diagramCommentError:X.error,onCancelDiagramComment:$,onSubmitDiagramComment:(e,t)=>X.mutate({range:e,body:t})});return(0,O.jsxs)(`div`,{className:`walkthrough-viewer`,ref:b,children:[(0,O.jsxs)(`header`,{className:`walkthrough-viewer-header`,children:[(0,O.jsxs)(`div`,{className:`walkthrough-viewer-title`,children:[(0,O.jsx)(`span`,{className:`walkthrough-viewer-icon`,children:(0,O.jsx)(g,{})}),(0,O.jsxs)(`div`,{className:`walkthrough-viewer-heading-copy`,children:[(0,O.jsx)(`span`,{className:`walkthrough-kicker`,children:`Agent-provided walkthrough`}),(0,O.jsx)(`h2`,{title:e.title,children:e.title})]})]}),(0,O.jsxs)(`div`,{className:`walkthrough-viewer-actions`,children:[(0,O.jsxs)(`button`,{className:`comment-icon-button walkthrough-comment-button`,"aria-label":`ウォークスルー全体へコメント`,title:`ウォークスルー全体へコメント`,"aria-pressed":w,onClick:()=>{X.reset(),R(``),j(null),N(null),F(null),T(e=>!e)},children:[(0,O.jsx)(a,{}),Q>0&&(0,O.jsx)(`span`,{children:Q})]}),(0,O.jsx)(`button`,{className:`comment-icon-button walkthrough-delete-button`,"aria-label":`ウォークスルーを削除`,title:`ウォークスルーを削除`,disabled:Z.isPending,onClick:ne,children:(0,O.jsx)(I,{})})]}),z&&(0,O.jsx)(`div`,{className:`walkthrough-reference-notice`,role:`status`,"aria-live":`polite`,children:z})]}),(0,O.jsx)(s,{error:Z.error}),(0,O.jsx)(s,{error:q.error}),(w||Y.length>0)&&(0,O.jsxs)(`div`,{className:`walkthrough-comment-area`,children:[w&&(0,O.jsx)(o,{body:L,label:`ウォークスルー全体へコメント`,pending:X.isPending,error:X.error,validationError:void 0,placement:`file`,onBodyChange:R,onCancel:()=>{X.reset(),R(``),T(!1)},onSubmit:()=>X.mutate({range:null,body:L})}),Y.map(({comment:t,placement:n})=>(0,O.jsx)(f,{comment:t,variant:`inline`,placement:n,markdownSourceOid:e.sourceOid,themePreference:p,onActiveChange:m,onOpenRepositoryLink:_},t.id))]}),(0,O.jsx)(E,{className:`walkthrough-markdown-surface`,selectedRange:A,composerOpen:P===`selection`,onSelection:e=>{if(!e){j(null),F(e=>e===`selection`?null:e);return}X.reset(),R(``),T(!1),j(e),N(null),F(null)},onOpenComposer:()=>F(`selection`),composer:ae,children:oe})]})}export{H as WalkthroughViewer};
@@ -1 +0,0 @@
1
- import"./chunk-KEIR6QF5-BICK3FdT.js";import{M as e}from"./mermaid-parser.core-B7TMMtY0.js";export{e as createArchitectureServices};
@@ -1 +0,0 @@
1
- import{at as e,ot as t}from"./chunk-I66GZJ75-DdoGlxMt.js";var n=(n,r)=>t.lang.round(e.parse(n)[r]);export{n as t};
@@ -1 +0,0 @@
1
- import{n as e}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import"./src-B6xuSHsQ.js";import"./chunk-I66GZJ75-DdoGlxMt.js";import"./chunk-NSK5VX7P-1AsXiBV3.js";import"./chunk-4I5QYGJK-Cg5GZ_-7.js";import"./chunk-WRU74C26-C7IeXZaP.js";import"./chunk-7BUUIJ7U-Bb538aSH.js";import"./chunk-UBXNYLIW-mu3fkNQI.js";import"./chunk-2GRJ4B5K-gt2JPyrH.js";import"./chunk-XXDRQBXY-DqAYeljN.js";import"./chunk-KBJHAD2P-BBacwg3J.js";import"./chunk-W5SLKNZC-BAwhMBBb.js";import"./chunk-QR6OTTB3-DL2s5pNp.js";import"./chunk-7Z6QIM7H-D2YImamZ.js";import{i as t,n,r,t as i}from"./chunk-GF5L2VYU-CWtwL_CM.js";import"./mermaid.core-B93x-7Mk.js";var a={parser:n,get db(){return new i},renderer:r,styles:t,init:e(e=>{e.class||={},e.class.arrowMarkerAbsolute=e.arrowMarkerAbsolute},`init`)};export{a as diagram};
@@ -1 +0,0 @@
1
- import{n as e}from"./chunk-Y2CYZVJY-DsF7k-Jl.js";import"./src-B6xuSHsQ.js";import"./chunk-I66GZJ75-DdoGlxMt.js";import"./chunk-NSK5VX7P-1AsXiBV3.js";import"./chunk-4I5QYGJK-Cg5GZ_-7.js";import"./chunk-WRU74C26-C7IeXZaP.js";import"./chunk-7BUUIJ7U-Bb538aSH.js";import"./chunk-UBXNYLIW-mu3fkNQI.js";import"./chunk-2GRJ4B5K-gt2JPyrH.js";import"./chunk-XXDRQBXY-DqAYeljN.js";import"./chunk-KBJHAD2P-BBacwg3J.js";import"./chunk-W5SLKNZC-BAwhMBBb.js";import"./chunk-QR6OTTB3-DL2s5pNp.js";import"./chunk-7Z6QIM7H-D2YImamZ.js";import{i as t,n,r,t as i}from"./chunk-GF5L2VYU-CWtwL_CM.js";import"./mermaid.core-B93x-7Mk.js";var a={parser:n,get db(){return new i},renderer:r,styles:t,init:e(e=>{e.class||={},e.class.arrowMarkerAbsolute=e.arrowMarkerAbsolute},`init`)};export{a as diagram};
@@ -1 +0,0 @@
1
- import"./chunk-KEIR6QF5-BICK3FdT.js";import{O as e}from"./mermaid-parser.core-B7TMMtY0.js";export{e as createEventModelingServices};
@@ -1 +0,0 @@
1
- import"./src-B6xuSHsQ.js";import"./chunk-I66GZJ75-DdoGlxMt.js";import"./chunk-NSK5VX7P-1AsXiBV3.js";import"./chunk-4I5QYGJK-Cg5GZ_-7.js";import"./chunk-WRU74C26-C7IeXZaP.js";import"./chunk-7BUUIJ7U-Bb538aSH.js";import"./chunk-UBXNYLIW-mu3fkNQI.js";import"./chunk-2GRJ4B5K-gt2JPyrH.js";import"./chunk-XXDRQBXY-DqAYeljN.js";import"./chunk-KBJHAD2P-BBacwg3J.js";import"./chunk-W5SLKNZC-BAwhMBBb.js";import"./chunk-QR6OTTB3-DL2s5pNp.js";import"./chunk-7Z6QIM7H-D2YImamZ.js";import{n as e}from"./chunk-JQJVKLGR-CVWAp3XP.js";import"./mermaid.core-B93x-7Mk.js";export{e as diagram};