@monoes/monomindcli 2.14.1 → 2.15.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 (197) hide show
  1. package/.claude/helpers/control-start.cjs +10 -13
  2. package/.claude/skills/monodesign/scripts/context.mjs +4 -4
  3. package/.claude/skills/monodesign/scripts/critique-storage.mjs +1 -1
  4. package/.claude/skills/monodesign/scripts/detect-csp.mjs +1 -6
  5. package/.claude/skills/monodesign/scripts/detector/browser/injected/index.mjs +16 -18
  6. package/.claude/skills/monodesign/scripts/detector/cli/main.mjs +3 -3
  7. package/.claude/skills/monodesign/scripts/detector/detect-antipatterns-browser.js +67 -47
  8. package/.claude/skills/monodesign/scripts/detector/engines/regex/detect-text.mjs +6 -6
  9. package/.claude/skills/monodesign/scripts/detector/engines/static-html/css-cascade.mjs +6 -5
  10. package/.claude/skills/monodesign/scripts/detector/engines/static-html/detect-html.mjs +6 -6
  11. package/.claude/skills/monodesign/scripts/detector/fix/index.mjs +3 -3
  12. package/.claude/skills/monodesign/scripts/detector/node/file-system.mjs +1 -1
  13. package/.claude/skills/monodesign/scripts/detector/registry/antipatterns.mjs +1 -1
  14. package/.claude/skills/monodesign/scripts/detector/rules/checks.mjs +24 -25
  15. package/.claude/skills/monodesign/scripts/detector/shared/color.mjs +2 -2
  16. package/.claude/skills/monodesign/scripts/detector/shared/constants.mjs +1 -1
  17. package/.claude/skills/monodesign/scripts/detector/shared/inline-ignores.mjs +2 -2
  18. package/.claude/skills/monodesign/scripts/hook-admin.mjs +6 -6
  19. package/.claude/skills/monodesign/scripts/hook-before-edit.mjs +4 -4
  20. package/.claude/skills/monodesign/scripts/hook-lib.mjs +20 -11
  21. package/.claude/skills/monodesign/scripts/hook.mjs +1 -1
  22. package/.claude/skills/monodesign/scripts/lib/design-parser.mjs +9 -42
  23. package/.claude/skills/monodesign/scripts/lib/is-generated.mjs +1 -1
  24. package/.claude/skills/monodesign/scripts/lib/monodesign-config.mjs +5 -5
  25. package/.claude/skills/monodesign/scripts/lib/monodesign-paths.mjs +1 -1
  26. package/.claude/skills/monodesign/scripts/live/event-validation.mjs +13 -13
  27. package/.claude/skills/monodesign/scripts/live/manual-apply.mjs +4 -4
  28. package/.claude/skills/monodesign/scripts/live/manual-edits-buffer.mjs +1 -1
  29. package/.claude/skills/monodesign/scripts/live/session-store.mjs +5 -5
  30. package/.claude/skills/monodesign/scripts/live/svelte-component.mjs +13 -13
  31. package/.claude/skills/monodesign/scripts/live/sveltekit-adapter.mjs +4 -4
  32. package/.claude/skills/monodesign/scripts/live/ui-core.mjs +1 -1
  33. package/.claude/skills/monodesign/scripts/live-accept.mjs +24 -24
  34. package/.claude/skills/monodesign/scripts/live-browser-dom.js +8 -7
  35. package/.claude/skills/monodesign/scripts/live-browser-session.js +8 -7
  36. package/.claude/skills/monodesign/scripts/live-browser.js +405 -432
  37. package/.claude/skills/monodesign/scripts/live-commit-manual-edits.mjs +6 -6
  38. package/.claude/skills/monodesign/scripts/live-copy-edit-agent.mjs +2 -2
  39. package/.claude/skills/monodesign/scripts/live-discard-manual-edits.mjs +1 -1
  40. package/.claude/skills/monodesign/scripts/live-inject.mjs +7 -7
  41. package/.claude/skills/monodesign/scripts/live-insert.mjs +11 -11
  42. package/.claude/skills/monodesign/scripts/live-manual-edit-evidence.mjs +4 -4
  43. package/.claude/skills/monodesign/scripts/live-poll.mjs +5 -5
  44. package/.claude/skills/monodesign/scripts/live-server.mjs +10 -10
  45. package/.claude/skills/monodesign/scripts/live-wrap.mjs +31 -41
  46. package/.claude/skills/monodesign/scripts/live.mjs +5 -5
  47. package/.claude/skills/monodesign/scripts/palette.mjs +3 -1
  48. package/.claude/skills/monodesign/scripts/pin.mjs +1 -1
  49. package/dist/src/commands/doc-filters.d.ts.map +1 -1
  50. package/dist/src/commands/doc-filters.js +6 -0
  51. package/dist/src/commands/doc-filters.js.map +1 -1
  52. package/dist/src/commands/doc-library.d.ts +2 -1
  53. package/dist/src/commands/doc-library.d.ts.map +1 -1
  54. package/dist/src/commands/doc-library.js +66 -2
  55. package/dist/src/commands/doc-library.js.map +1 -1
  56. package/dist/src/commands/doc.d.ts.map +1 -1
  57. package/dist/src/commands/doc.js +2 -0
  58. package/dist/src/commands/doc.js.map +1 -1
  59. package/dist/src/commands/org.d.ts.map +1 -1
  60. package/dist/src/commands/org.js +42 -4
  61. package/dist/src/commands/org.js.map +1 -1
  62. package/dist/src/commands/ui.d.ts.map +1 -1
  63. package/dist/src/commands/ui.js +60 -0
  64. package/dist/src/commands/ui.js.map +1 -1
  65. package/dist/src/knowledge/capture-envelope.d.ts +5 -0
  66. package/dist/src/knowledge/capture-envelope.d.ts.map +1 -1
  67. package/dist/src/knowledge/capture-envelope.js +2 -0
  68. package/dist/src/knowledge/capture-envelope.js.map +1 -1
  69. package/dist/src/knowledge/document-chunking.d.ts +42 -0
  70. package/dist/src/knowledge/document-chunking.d.ts.map +1 -0
  71. package/dist/src/knowledge/document-chunking.js +288 -0
  72. package/dist/src/knowledge/document-chunking.js.map +1 -0
  73. package/dist/src/knowledge/document-index.d.ts +124 -0
  74. package/dist/src/knowledge/document-index.d.ts.map +1 -0
  75. package/dist/src/knowledge/document-index.js +314 -0
  76. package/dist/src/knowledge/document-index.js.map +1 -0
  77. package/dist/src/knowledge/document-ingest.d.ts +23 -0
  78. package/dist/src/knowledge/document-ingest.d.ts.map +1 -0
  79. package/dist/src/knowledge/document-ingest.js +368 -0
  80. package/dist/src/knowledge/document-ingest.js.map +1 -0
  81. package/dist/src/knowledge/document-pipeline.d.ts +26 -208
  82. package/dist/src/knowledge/document-pipeline.d.ts.map +1 -1
  83. package/dist/src/knowledge/document-pipeline.js +25 -1104
  84. package/dist/src/knowledge/document-pipeline.js.map +1 -1
  85. package/dist/src/knowledge/document-search.d.ts +27 -0
  86. package/dist/src/knowledge/document-search.d.ts.map +1 -0
  87. package/dist/src/knowledge/document-search.js +138 -0
  88. package/dist/src/knowledge/document-search.js.map +1 -0
  89. package/dist/src/knowledge/document-store.d.ts +28 -0
  90. package/dist/src/knowledge/document-store.d.ts.map +1 -0
  91. package/dist/src/knowledge/document-store.js +61 -0
  92. package/dist/src/knowledge/document-store.js.map +1 -0
  93. package/dist/src/knowledge/document-types.d.ts +103 -0
  94. package/dist/src/knowledge/document-types.d.ts.map +1 -0
  95. package/dist/src/knowledge/document-types.js +12 -0
  96. package/dist/src/knowledge/document-types.js.map +1 -0
  97. package/dist/src/knowledge/highlights.d.ts +168 -0
  98. package/dist/src/knowledge/highlights.d.ts.map +1 -0
  99. package/dist/src/knowledge/highlights.js +311 -0
  100. package/dist/src/knowledge/highlights.js.map +1 -0
  101. package/dist/src/knowledge/lookup.d.ts +80 -0
  102. package/dist/src/knowledge/lookup.d.ts.map +1 -0
  103. package/dist/src/knowledge/lookup.js +156 -0
  104. package/dist/src/knowledge/lookup.js.map +1 -0
  105. package/dist/src/knowledge/okf-bundle.d.ts +19 -0
  106. package/dist/src/knowledge/okf-bundle.d.ts.map +1 -0
  107. package/dist/src/knowledge/okf-bundle.js +106 -0
  108. package/dist/src/knowledge/okf-bundle.js.map +1 -0
  109. package/dist/src/knowledge/profile-store.d.ts +134 -0
  110. package/dist/src/knowledge/profile-store.d.ts.map +1 -0
  111. package/dist/src/knowledge/profile-store.js +237 -0
  112. package/dist/src/knowledge/profile-store.js.map +1 -0
  113. package/dist/src/orgrt/agent-runner.d.ts +4 -0
  114. package/dist/src/orgrt/agent-runner.d.ts.map +1 -1
  115. package/dist/src/orgrt/agent-runner.js +22 -0
  116. package/dist/src/orgrt/agent-runner.js.map +1 -1
  117. package/dist/src/orgrt/antigravity-runner.d.ts.map +1 -1
  118. package/dist/src/orgrt/antigravity-runner.js +2 -1
  119. package/dist/src/orgrt/antigravity-runner.js.map +1 -1
  120. package/dist/src/orgrt/authority-mask.d.ts +32 -0
  121. package/dist/src/orgrt/authority-mask.d.ts.map +1 -0
  122. package/dist/src/orgrt/authority-mask.js +135 -0
  123. package/dist/src/orgrt/authority-mask.js.map +1 -0
  124. package/dist/src/orgrt/codex-runner.d.ts.map +1 -1
  125. package/dist/src/orgrt/codex-runner.js +2 -1
  126. package/dist/src/orgrt/codex-runner.js.map +1 -1
  127. package/dist/src/orgrt/copilot-runner.d.ts.map +1 -1
  128. package/dist/src/orgrt/copilot-runner.js +2 -1
  129. package/dist/src/orgrt/copilot-runner.js.map +1 -1
  130. package/dist/src/orgrt/crush-runner.d.ts.map +1 -1
  131. package/dist/src/orgrt/crush-runner.js +6 -1
  132. package/dist/src/orgrt/crush-runner.js.map +1 -1
  133. package/dist/src/orgrt/daemon.d.ts +4 -0
  134. package/dist/src/orgrt/daemon.d.ts.map +1 -1
  135. package/dist/src/orgrt/daemon.js +13 -2
  136. package/dist/src/orgrt/daemon.js.map +1 -1
  137. package/dist/src/orgrt/decisions.d.ts +9 -0
  138. package/dist/src/orgrt/decisions.d.ts.map +1 -1
  139. package/dist/src/orgrt/decisions.js +32 -5
  140. package/dist/src/orgrt/decisions.js.map +1 -1
  141. package/dist/src/orgrt/file-roots.d.ts +2 -1
  142. package/dist/src/orgrt/file-roots.d.ts.map +1 -1
  143. package/dist/src/orgrt/file-roots.js +7 -3
  144. package/dist/src/orgrt/file-roots.js.map +1 -1
  145. package/dist/src/orgrt/grok-runner.d.ts.map +1 -1
  146. package/dist/src/orgrt/grok-runner.js +2 -1
  147. package/dist/src/orgrt/grok-runner.js.map +1 -1
  148. package/dist/src/orgrt/hermes-runner.d.ts.map +1 -1
  149. package/dist/src/orgrt/hermes-runner.js +2 -1
  150. package/dist/src/orgrt/hermes-runner.js.map +1 -1
  151. package/dist/src/orgrt/inbox.d.ts.map +1 -1
  152. package/dist/src/orgrt/inbox.js +70 -4
  153. package/dist/src/orgrt/inbox.js.map +1 -1
  154. package/dist/src/orgrt/kimicode-runner.d.ts.map +1 -1
  155. package/dist/src/orgrt/kimicode-runner.js +2 -1
  156. package/dist/src/orgrt/kimicode-runner.js.map +1 -1
  157. package/dist/src/orgrt/opencode-runner.d.ts.map +1 -1
  158. package/dist/src/orgrt/opencode-runner.js +3 -2
  159. package/dist/src/orgrt/opencode-runner.js.map +1 -1
  160. package/dist/src/orgrt/pi-rpc-runner.d.ts.map +1 -1
  161. package/dist/src/orgrt/pi-rpc-runner.js +3 -2
  162. package/dist/src/orgrt/pi-rpc-runner.js.map +1 -1
  163. package/dist/src/orgrt/pi-runner.d.ts.map +1 -1
  164. package/dist/src/orgrt/pi-runner.js +2 -1
  165. package/dist/src/orgrt/pi-runner.js.map +1 -1
  166. package/dist/src/orgrt/policy.d.ts.map +1 -1
  167. package/dist/src/orgrt/policy.js +3 -0
  168. package/dist/src/orgrt/policy.js.map +1 -1
  169. package/dist/src/orgrt/qwen-rpc-runner.d.ts.map +1 -1
  170. package/dist/src/orgrt/qwen-rpc-runner.js +3 -2
  171. package/dist/src/orgrt/qwen-rpc-runner.js.map +1 -1
  172. package/dist/src/orgrt/qwen-runner.d.ts.map +1 -1
  173. package/dist/src/orgrt/qwen-runner.js +2 -1
  174. package/dist/src/orgrt/qwen-runner.js.map +1 -1
  175. package/dist/src/orgrt/role-sandbox.d.ts +21 -0
  176. package/dist/src/orgrt/role-sandbox.d.ts.map +1 -1
  177. package/dist/src/orgrt/role-sandbox.js +31 -6
  178. package/dist/src/orgrt/role-sandbox.js.map +1 -1
  179. package/dist/src/orgrt/session.d.ts.map +1 -1
  180. package/dist/src/orgrt/session.js +21 -2
  181. package/dist/src/orgrt/session.js.map +1 -1
  182. package/dist/src/orgrt/task-dag.d.ts +3 -0
  183. package/dist/src/orgrt/task-dag.d.ts.map +1 -1
  184. package/dist/src/orgrt/task-dag.js +1 -0
  185. package/dist/src/orgrt/task-dag.js.map +1 -1
  186. package/dist/src/orgrt/types.d.ts +5 -0
  187. package/dist/src/orgrt/types.d.ts.map +1 -1
  188. package/dist/src/orgrt/types.js +23 -1
  189. package/dist/src/orgrt/types.js.map +1 -1
  190. package/dist/src/ui/dashboard.html +28 -848
  191. package/dist/src/ui/human-auth.mjs +103 -0
  192. package/dist/src/ui/org-hil.mjs +86 -37
  193. package/dist/src/ui/org-runtime.mjs +21 -13
  194. package/dist/src/ui/routes-org.mjs +49 -445
  195. package/dist/src/ui/server.mjs +103 -4
  196. package/dist/tsconfig.tsbuildinfo +1 -1
  197. package/package.json +6 -6
@@ -63,7 +63,7 @@ const ROLLBACK_SKIP_DIRS = new Set([
63
63
  const DEFAULT_REPAIR_ATTEMPTS = 3;
64
64
 
65
65
  function argVal(args, name) {
66
- const prefix = name + '=';
66
+ const prefix = `${name}=`;
67
67
  for (const arg of args) {
68
68
  if (arg === name) return true;
69
69
  if (arg.startsWith(prefix)) return arg.slice(prefix.length);
@@ -300,7 +300,7 @@ function verificationTargetsForOp(batch, op, reportedFiles, cwd) {
300
300
 
301
301
  const seen = new Set();
302
302
  return out.filter((target) => {
303
- const key = target.file + ':' + target.line + ':' + target.kind;
303
+ const key = `${target.file}:${target.line}:${target.kind}`;
304
304
  if (seen.has(key)) return false;
305
305
  seen.add(key);
306
306
  return true;
@@ -315,11 +315,11 @@ function objectKeyCandidatesForOp(batch, op) {
315
315
 
316
316
  function lineHasObjectKey(line, text) {
317
317
  if (typeof text !== 'string' || text.length === 0) return false;
318
- const quotedKey = new RegExp('(^|[\\s,{])([\'"`])' + escapeRegExp(text) + '\\2\\s*:');
318
+ const quotedKey = new RegExp(`(^|[\\s,{])(['"\`])${escapeRegExp(text)}\\2\\s*:`);
319
319
  if (quotedKey.test(line)) return true;
320
320
  const identifierSafe = /^[A-Za-z_$][\w$]*$/.test(text);
321
321
  if (!identifierSafe) return false;
322
- const bareKey = new RegExp('(^|[\\s,{])' + escapeRegExp(text) + '\\s*:');
322
+ const bareKey = new RegExp(`(^|[\\s,{])${escapeRegExp(text)}\\s*:`);
323
323
  return bareKey.test(line);
324
324
  }
325
325
 
@@ -438,12 +438,12 @@ function opHasLocator(op) {
438
438
 
439
439
  function lineMatchesManualEditLocator(line, op) {
440
440
  if (op.tag) {
441
- const tagRe = new RegExp('<\\s*' + escapeRegExp(op.tag) + '(?=[\\s>/]|$)', 'i');
441
+ const tagRe = new RegExp(`<\\s*${escapeRegExp(op.tag)}(?=[\\s>/]|$)`, 'i');
442
442
  if (!tagRe.test(line)) return false;
443
443
  }
444
444
 
445
445
  if (op.elementId) {
446
- const idRe = new RegExp('\\bid\\s*=\\s*["\']' + escapeRegExp(op.elementId) + '["\']');
446
+ const idRe = new RegExp(`\\bid\\s*=\\s*["']${escapeRegExp(op.elementId)}["']`);
447
447
  if (!idRe.test(line)) return false;
448
448
  }
449
449
 
@@ -131,7 +131,7 @@ export async function runCopyEditBatchAgent(batch, opts = {}) {
131
131
  if (parsed) return parsed;
132
132
 
133
133
  const tail = fs.existsSync(logPath) ? fs.readFileSync(logPath, 'utf-8').slice(-1200) : output.slice(-1200);
134
- throw new Error('AI copy-edit batch did not return a valid completion payload. ' + tail.trim());
134
+ throw new Error(`AI copy-edit batch did not return a valid completion payload. ${tail.trim()}`);
135
135
  }
136
136
 
137
137
  export function runCopyEditPostApplyChecks({ cwd = process.cwd(), files = [] } = {}) {
@@ -545,7 +545,7 @@ function tryParseJson(text) {
545
545
  function truncate(value, max) {
546
546
  if (typeof value !== 'string') return value;
547
547
  if (value.length <= max) return value;
548
- return value.slice(0, max) + `... [truncated ${value.length - max} chars]`;
548
+ return `${value.slice(0, max)}... [truncated ${value.length - max} chars]`;
549
549
  }
550
550
 
551
551
  function commandExists(command) {
@@ -19,7 +19,7 @@
19
19
  import { readBuffer, removeEntries, truncateBuffer } from './live/manual-edits-buffer.mjs';
20
20
 
21
21
  function argVal(args, name) {
22
- const prefix = name + '=';
22
+ const prefix = `${name}=`;
23
23
  for (const a of args) {
24
24
  if (a === name) return true;
25
25
  if (a.startsWith(prefix)) return a.slice(prefix.length);
@@ -151,7 +151,7 @@ Output (JSON):
151
151
  // read the per-process credential live-server.mjs persisted at startup.
152
152
  const liveInfo = readLiveServerInfo(process.cwd());
153
153
  const credentialFields = liveInfo?.info ?? {};
154
- const authCred = credentialFields['token'];
154
+ const authCred = credentialFields.token;
155
155
  if (!authCred) {
156
156
  console.error(JSON.stringify({ ok: false, error: 'missing_auth_credential', detail: 'no running live server info found for this project — start it before injecting' }));
157
157
  process.exit(1);
@@ -200,7 +200,7 @@ export function ensureLiveGitIgnores(cwd = process.cwd()) {
200
200
  if (markerRe.test(existing)) {
201
201
  updated = existing.replace(markerRe, block);
202
202
  } else {
203
- const prefix = existing.length === 0 ? '' : existing.endsWith('\n') ? existing : existing + '\n';
203
+ const prefix = existing.length === 0 ? '' : existing.endsWith('\n') ? existing : `${existing}\n`;
204
204
  updated = `${prefix}${prefix.endsWith('\n\n') || prefix === '' ? '' : '\n'}${block}\n`;
205
205
  }
206
206
 
@@ -280,7 +280,7 @@ export function resolveFiles(rootDir, config) {
280
280
  continue;
281
281
  }
282
282
  for (const ent of matches) {
283
- if (!ent.isFile || !ent.isFile()) continue;
283
+ if (!ent.isFile?.()) continue;
284
284
  const abs = path.join(ent.parentPath || ent.path || rootDir, ent.name);
285
285
  const rel = path.relative(rootDir, abs).split(path.sep).join('/');
286
286
  if (isExcluded(rel)) continue;
@@ -323,14 +323,14 @@ function globToRegex(pattern) {
323
323
  re += '[^/]';
324
324
  i += 1;
325
325
  } else if (/[.+^${}()|[\]\\]/.test(c)) {
326
- re += '\\' + c;
326
+ re += `\\${c}`;
327
327
  i += 1;
328
328
  } else {
329
329
  re += c;
330
330
  i += 1;
331
331
  }
332
332
  }
333
- return new RegExp('^' + re + '$');
333
+ return new RegExp(`^${re}$`);
334
334
  }
335
335
 
336
336
  // ---------------------------------------------------------------------------
@@ -510,7 +510,7 @@ function appendOriginToDirective(csp, directive, origin) {
510
510
  // Directive missing — add it. Use 'self' + origin so we don't inadvertently
511
511
  // narrow the policy compared to the default-src fallback (most users with
512
512
  // an explicit CSP have 'self' there).
513
- return csp.trim().replace(/;?\s*$/, '') + `; ${directive} 'self' ${origin}`;
513
+ return `${csp.trim().replace(/;?\s*$/, '')}; ${directive} 'self' ${origin}`;
514
514
  }
515
515
 
516
516
  export function patchCspMeta(content, port) {
@@ -548,7 +548,7 @@ export function patchCspMeta(content, port) {
548
548
  // `<meta … />` round-trips byte-for-byte.
549
549
  const trailingWs = (attrs.match(/[ \t]*$/) || [''])[0];
550
550
  const attrsBody = attrs.slice(0, attrs.length - trailingWs.length);
551
- const newAttrs = attrsBody.replace(contentAttr.full, newContentAttr) + ' ' + marker + trailingWs;
551
+ const newAttrs = `${attrsBody.replace(contentAttr.full, newContentAttr)} ${marker}${trailingWs}`;
552
552
  const newTag = tag.full.replace(attrs, newAttrs);
553
553
 
554
554
  result = result.slice(0, tag.start) + newTag + result.slice(tag.end);
@@ -47,20 +47,20 @@ export function buildInsertWrapperLines({ id, count, indent, commentSyntax, isJs
47
47
 
48
48
  if (isJsx) {
49
49
  return [
50
- indent + '<div ' + attrs + '>',
51
- indent + ' ' + commentSyntax.open + ' monodesign-variants-start ' + id + ' ' + commentSyntax.close,
52
- indent + ' ' + commentSyntax.open + ' Variants: insert below this line ' + commentSyntax.close,
53
- indent + ' ' + commentSyntax.open + ' monodesign-variants-end ' + id + ' ' + commentSyntax.close,
54
- indent + '</div>',
50
+ `${indent}<div ${attrs}>`,
51
+ `${indent} ${commentSyntax.open} monodesign-variants-start ${id} ${commentSyntax.close}`,
52
+ `${indent} ${commentSyntax.open} Variants: insert below this line ${commentSyntax.close}`,
53
+ `${indent} ${commentSyntax.open} monodesign-variants-end ${id} ${commentSyntax.close}`,
54
+ `${indent}</div>`,
55
55
  ];
56
56
  }
57
57
 
58
58
  return [
59
- indent + commentSyntax.open + ' monodesign-variants-start ' + id + ' ' + commentSyntax.close,
60
- indent + '<div ' + attrs + '>',
61
- indent + ' ' + commentSyntax.open + ' Variants: insert below this line ' + commentSyntax.close,
62
- indent + '</div>',
63
- indent + commentSyntax.open + ' monodesign-variants-end ' + id + ' ' + commentSyntax.close,
59
+ `${indent + commentSyntax.open} monodesign-variants-start ${id} ${commentSyntax.close}`,
60
+ `${indent}<div ${attrs}>`,
61
+ `${indent} ${commentSyntax.open} Variants: insert below this line ${commentSyntax.close}`,
62
+ `${indent}</div>`,
63
+ `${indent + commentSyntax.open} monodesign-variants-end ${id} ${commentSyntax.close}`,
64
64
  ];
65
65
  }
66
66
 
@@ -134,7 +134,7 @@ Output (JSON):
134
134
 
135
135
  if (!id) { console.error('Missing --id'); process.exit(1); }
136
136
  if (!position) { console.error('Missing --position (before | after)'); process.exit(1); }
137
- if (!isInsertPosition(position)) { console.error('Invalid --position: ' + position); process.exit(1); }
137
+ if (!isInsertPosition(position)) { console.error(`Invalid --position: ${position}`); process.exit(1); }
138
138
  if (!elementId && !classes && !query) {
139
139
  console.error('Need at least one of: --element-id, --classes, --query');
140
140
  process.exit(1);
@@ -262,7 +262,7 @@ function findLiteralMatches(searchFiles, needle, { max }) {
262
262
  }
263
263
 
264
264
  function findObjectKeyMatches(searchFiles, text, { max }) {
265
- const re = new RegExp('(["\\\'`])' + escapeRegExp(text) + '\\1(?=\\s*:)', 'g');
265
+ const re = new RegExp(`(["\\'\`])${escapeRegExp(text)}\\1(?=\\s*:)`, 'g');
266
266
  const out = [];
267
267
  for (const file of searchFiles) {
268
268
  for (const match of file.content.matchAll(re)) {
@@ -279,13 +279,13 @@ function findLocatorMatches(searchFiles, op, { max }) {
279
279
  for (const cls of op.classes || []) {
280
280
  if (cls) needles.push({ kind: 'class', needle: cls });
281
281
  }
282
- if (op.tag) needles.push({ kind: 'tag', needle: '<' + op.tag });
282
+ if (op.tag) needles.push({ kind: 'tag', needle: `<${op.tag}` });
283
283
 
284
284
  const out = [];
285
285
  const seen = new Set();
286
286
  for (const { kind, needle } of needles) {
287
287
  for (const match of findMatches(searchFiles, needle, { kind, max })) {
288
- const key = match.file + ':' + match.line + ':' + kind + ':' + needle;
288
+ const key = `${match.file}:${match.line}:${kind}:${needle}`;
289
289
  if (seen.has(key)) continue;
290
290
  seen.add(key);
291
291
  out.push({ ...match, needle });
@@ -300,7 +300,7 @@ function findContextMatches(searchFiles, hints, { maxPerHint, max }) {
300
300
  const seen = new Set();
301
301
  for (const hint of hints || []) {
302
302
  for (const match of findMatches(searchFiles, hint, { kind: 'context', max: maxPerHint })) {
303
- const key = match.file + ':' + match.line + ':' + hint;
303
+ const key = `${match.file}:${match.line}:${hint}`;
304
304
  if (seen.has(key)) continue;
305
305
  seen.add(key);
306
306
  out.push({ ...match, needle: hint });
@@ -44,12 +44,12 @@ export function buildPollReplyPayload(token, { id, type, message, file, data })
44
44
 
45
45
  export function manualApplyPollBanner(event = {}) {
46
46
  const id = event.id || 'EVENT_ID';
47
- return [
47
+ return `${[
48
48
  `Manual Apply action required: edit source, then reply with \`live-poll.mjs --reply ${id} done --data '<json>'\`.`,
49
49
  'The JSON data must include status, appliedEntryIds, failed, files, and notes; summary counters are only a recovery fallback.',
50
50
  'Do not run live-commit-manual-edits.mjs for this leased event.',
51
51
  'Do not poll again before replying.',
52
- ].join('\n') + '\n';
52
+ ].join('\n')}\n`;
53
53
  }
54
54
 
55
55
  /**
@@ -72,7 +72,7 @@ export function parseReplyArgs(args) {
72
72
  try {
73
73
  data = JSON.parse(args[dataIdx + 1]);
74
74
  } catch (err) {
75
- const wrapped = new Error('--data must be valid JSON: ' + err.message);
75
+ const wrapped = new Error(`--data must be valid JSON: ${err.message}`);
76
76
  wrapped.code = 'INVALID_DATA_JSON';
77
77
  throw wrapped;
78
78
  }
@@ -234,10 +234,10 @@ export function buildAcceptScriptArgs(event) {
234
234
 
235
235
  export function writeCarbonizeBanner(event) {
236
236
  if (event.type === 'manual_edit_apply') {
237
- process.stderr.write('\n' + manualApplyPollBanner(event) + '\n');
237
+ process.stderr.write(`\n${manualApplyPollBanner(event)}\n`);
238
238
  }
239
239
  if (event._acceptResult?.carbonize === true) {
240
- process.stderr.write('\n⚠ Carbonize cleanup REQUIRED before next poll. After cleanup, run live-complete.mjs --id ' + event.id + '. See reference/live.md "Required after accept".\n\n');
240
+ process.stderr.write(`\n⚠ Carbonize cleanup REQUIRED before next poll. After cleanup, run live-complete.mjs --id ${event.id}. See reference/live.md "Required after accept".\n\n`);
241
241
  }
242
242
  }
243
243
 
@@ -300,7 +300,7 @@ function broadcastAgentPollingIfChanged() {
300
300
 
301
301
  /** Push a message to all connected SSE clients. */
302
302
  function broadcast(msg) {
303
- const data = 'data: ' + JSON.stringify(msg) + '\n\n';
303
+ const data = `data: ${JSON.stringify(msg)}\n\n`;
304
304
  for (const res of state.sseClients) {
305
305
  try { res.write(data); } catch { /* client gone */ }
306
306
  }
@@ -318,7 +318,7 @@ function recordManualEditActivity(type, details = {}) {
318
318
  try {
319
319
  const filePath = path.join(getLiveDir(process.cwd()), 'manual-edit-events.jsonl');
320
320
  fs.mkdirSync(path.dirname(filePath), { recursive: true });
321
- fs.appendFileSync(filePath, JSON.stringify(entry) + '\n');
321
+ fs.appendFileSync(filePath, `${JSON.stringify(entry)}\n`);
322
322
  } catch {
323
323
  /* diagnostics are best-effort; never block live mode on observability */
324
324
  }
@@ -367,7 +367,7 @@ function loadBrowserScripts() {
367
367
  try {
368
368
  assertLiveBrowserScriptParts(liveScriptParts);
369
369
  } catch (err) {
370
- process.stderr.write('Error: ' + err.message + '\n');
370
+ process.stderr.write(`Error: ${err.message}\n`);
371
371
  process.exit(1);
372
372
  }
373
373
 
@@ -432,7 +432,7 @@ function createRequestHandler({ detectScript, liveScriptParts }) {
432
432
  parts = readLiveBrowserScriptParts(liveScriptParts);
433
433
  } catch (err) {
434
434
  res.writeHead(500, { 'Content-Type': 'text/plain' });
435
- res.end('Error reading live browser scripts: ' + err.message);
435
+ res.end(`Error reading live browser scripts: ${err.message}`);
436
436
  return;
437
437
  }
438
438
  const body = assembleLiveBrowserScript({
@@ -514,12 +514,12 @@ function createRequestHandler({ detectScript, liveScriptParts }) {
514
514
  });
515
515
  req.on('end', () => {
516
516
  if (aborted) return;
517
- const absPath = path.join(state.sessionDir, eventId + '.png');
517
+ const absPath = path.join(state.sessionDir, `${eventId}.png`);
518
518
  try {
519
519
  fs.writeFileSync(absPath, Buffer.concat(chunks));
520
520
  } catch (err) {
521
521
  res.writeHead(500, { 'Content-Type': 'application/json' });
522
- res.end(JSON.stringify({ error: 'Write failed: ' + err.message }));
522
+ res.end(JSON.stringify({ error: `Write failed: ${err.message}` }));
523
523
  return;
524
524
  }
525
525
  res.writeHead(200, { 'Content-Type': 'application/json' });
@@ -614,7 +614,7 @@ function createRequestHandler({ detectScript, liveScriptParts }) {
614
614
  try {
615
615
  response.sidecar = JSON.parse(fs.readFileSync(jsonPath, 'utf-8'));
616
616
  } catch (err) {
617
- response.sidecarError = 'Failed to parse .monodesign/design.json: ' + err.message;
617
+ response.sidecarError = `Failed to parse .monodesign/design.json: ${err.message}`;
618
618
  }
619
619
  }
620
620
 
@@ -662,12 +662,12 @@ function createRequestHandler({ detectScript, liveScriptParts }) {
662
662
  'Cache-Control': 'no-cache',
663
663
  'Connection': 'keep-alive',
664
664
  });
665
- res.write('data: ' + JSON.stringify({
665
+ res.write(`data: ${JSON.stringify({
666
666
  type: 'connected',
667
667
  hasProjectContext: hasProjectContext(),
668
668
  agentPolling: agentPollingConnected(),
669
669
  activeSessions: activeSessionSummaries(),
670
- }) + '\n\n');
670
+ })}\n\n`);
671
671
 
672
672
  state.sseClients.add(res);
673
673
 
@@ -1132,7 +1132,7 @@ if (existingRecord?.info) {
1132
1132
  try {
1133
1133
  process.kill(existing.pid, 0);
1134
1134
  console.error(`Live server already running on port ${existing.port} (pid ${existing.pid}).`);
1135
- console.error('Stop it first with: node ' + path.basename(fileURLToPath(import.meta.url)) + ' stop');
1135
+ console.error(`Stop it first with: node ${path.basename(fileURLToPath(import.meta.url))} stop`);
1136
1136
  process.exit(1);
1137
1137
  } catch {
1138
1138
  try { fs.unlinkSync(existingRecord.path); } catch {}
@@ -60,6 +60,7 @@ The agent should insert variant HTML at insertLine.`);
60
60
  }
61
61
 
62
62
  const id = argVal(args, '--id');
63
+ // biome-ignore lint/correctness/useParseIntRadix: --count is caller-supplied CLI input; radix 10 would change how a 0x value parses
63
64
  const count = parseInt(argVal(args, '--count') || '3');
64
65
  const elementId = argVal(args, '--element-id');
65
66
  const classes = argVal(args, '--classes');
@@ -83,11 +84,10 @@ The agent should insert variant HTML at insertLine.`);
83
84
  // Find the source file. Generated files are excluded from auto-search so we
84
85
  // don't silently write variants into a file the next build will wipe.
85
86
  let targetFile = filePath;
86
- let matchedQuery = null;
87
87
  if (!targetFile) {
88
88
  for (const q of queries) {
89
89
  targetFile = findFileWithQuery(q, process.cwd(), genOpts);
90
- if (targetFile) { matchedQuery = q; break; }
90
+ if (targetFile) break;
91
91
  }
92
92
  if (!targetFile) {
93
93
  // Nothing in source. Did the element show up in a generated file? That
@@ -124,7 +124,6 @@ The agent should insert variant HTML at insertLine.`);
124
124
  }));
125
125
  process.exit(1);
126
126
  }
127
- matchedQuery = queries[0];
128
127
  }
129
128
 
130
129
  const content = fs.readFileSync(targetFile, 'utf-8');
@@ -150,7 +149,7 @@ The agent should insert variant HTML at insertLine.`);
150
149
  if (candidates.length === 1) break;
151
150
  }
152
151
  if (candidates.length === 0) {
153
- console.error(JSON.stringify({ error: 'Found file but could not locate element in ' + targetFile + '. Searched for: ' + queries.join(', ') }));
152
+ console.error(JSON.stringify({ error: `Found file but could not locate element in ${targetFile}. Searched for: ${queries.join(', ')}` }));
154
153
  process.exit(1);
155
154
  }
156
155
  if (candidates.length === 1) {
@@ -188,7 +187,7 @@ The agent should insert variant HTML at insertLine.`);
188
187
  if (match) break;
189
188
  }
190
189
  if (!match) {
191
- console.error(JSON.stringify({ error: 'Found file but could not locate element in ' + targetFile + '. Searched for: ' + queries.join(', ') }));
190
+ console.error(JSON.stringify({ error: `Found file but could not locate element in ${targetFile}. Searched for: ${queries.join(', ')}` }));
192
191
  process.exit(1);
193
192
  }
194
193
  }
@@ -288,29 +287,28 @@ The agent should insert variant HTML at insertLine.`);
288
287
  // replacement range to include the wrapper's `<div>` open / close lines
289
288
  // so the entire scaffold gets removed cleanly.
290
289
  const wrapperLines = isJsx ? [
291
- indent + '<div data-monodesign-variants="' + id + '" data-monodesign-variant-count="' + count + '" ' + styleContents + '>',
292
- indent + ' ' + commentSyntax.open + ' monodesign-variants-start ' + id + ' ' + commentSyntax.close,
293
- indent + ' ' + commentSyntax.open + ' Original ' + commentSyntax.close,
294
- indent + ' <div data-monodesign-variant="original">',
290
+ `${indent}<div data-monodesign-variants="${id}" data-monodesign-variant-count="${count}" ${styleContents}>`,
291
+ `${indent} ${commentSyntax.open} monodesign-variants-start ${id} ${commentSyntax.close}`,
292
+ `${indent} ${commentSyntax.open} Original ${commentSyntax.close}`,
293
+ `${indent} <div data-monodesign-variant="original">`,
295
294
  reindentOriginal(' '),
296
- indent + ' </div>',
297
- indent + ' ' + commentSyntax.open + ' Variants: insert below this line ' + commentSyntax.close,
298
- indent + ' ' + commentSyntax.open + ' monodesign-variants-end ' + id + ' ' + commentSyntax.close,
299
- indent + '</div>',
295
+ `${indent} </div>`,
296
+ `${indent} ${commentSyntax.open} Variants: insert below this line ${commentSyntax.close}`,
297
+ `${indent} ${commentSyntax.open} monodesign-variants-end ${id} ${commentSyntax.close}`,
298
+ `${indent}</div>`,
300
299
  ] : [
301
- indent + commentSyntax.open + ' monodesign-variants-start ' + id + ' ' + commentSyntax.close,
302
- indent + '<div data-monodesign-variants="' + id + '" data-monodesign-variant-count="' + count + '" ' + styleContents + '>',
303
- indent + ' ' + commentSyntax.open + ' Original ' + commentSyntax.close,
304
- indent + ' <div data-monodesign-variant="original">',
300
+ `${indent + commentSyntax.open} monodesign-variants-start ${id} ${commentSyntax.close}`,
301
+ `${indent}<div data-monodesign-variants="${id}" data-monodesign-variant-count="${count}" ${styleContents}>`,
302
+ `${indent} ${commentSyntax.open} Original ${commentSyntax.close}`,
303
+ `${indent} <div data-monodesign-variant="original">`,
305
304
  originalIndented,
306
- indent + ' </div>',
307
- indent + ' ' + commentSyntax.open + ' Variants: insert below this line ' + commentSyntax.close,
308
- indent + '</div>',
309
- indent + commentSyntax.open + ' monodesign-variants-end ' + id + ' ' + commentSyntax.close,
305
+ `${indent} </div>`,
306
+ `${indent} ${commentSyntax.open} Variants: insert below this line ${commentSyntax.close}`,
307
+ `${indent}</div>`,
308
+ `${indent + commentSyntax.open} monodesign-variants-end ${id} ${commentSyntax.close}`,
310
309
  ];
311
310
 
312
311
  let outputFile = targetFile;
313
- let outputLines;
314
312
  let outputStartLine = startLine + 1;
315
313
  let outputEndLine = startLine + wrapperLines.length + (originalLines.length - 1);
316
314
  let insertLine;
@@ -387,7 +385,7 @@ The agent should insert variant HTML at insertLine.`);
387
385
  // ---------------------------------------------------------------------------
388
386
 
389
387
  function argVal(args, flag) {
390
- const prefix = flag + '=';
388
+ const prefix = `${flag}=`;
391
389
  for (const arg of args) {
392
390
  if (arg.startsWith(prefix)) return arg.slice(prefix.length);
393
391
  }
@@ -481,13 +479,13 @@ function applyBufferedManualEditToLines(originalLines, selectionStartLine, op) {
481
479
 
482
480
  function lineMatchesManualEditLocator(line, op) {
483
481
  if (op.tag) {
484
- const tagRe = new RegExp('<\\s*' + escapeRegExp(op.tag) + '(?=[\\s>/]|$)', 'i');
482
+ const tagRe = new RegExp(`<\\s*${escapeRegExp(op.tag)}(?=[\\s>/]|$)`, 'i');
485
483
  if (!tagRe.test(line)) return false;
486
484
  }
487
485
 
488
486
  if (op.elementId) {
489
487
  const id = escapeRegExp(op.elementId);
490
- const idRe = new RegExp('\\bid\\s*=\\s*["\']' + id + '["\']');
488
+ const idRe = new RegExp(`\\bid\\s*=\\s*["']${id}["']`);
491
489
  if (!idRe.test(line)) return false;
492
490
  }
493
491
 
@@ -530,7 +528,7 @@ function buildSearchQueries(elementId, classes, tag, query) {
530
528
 
531
529
  // 1. ID is the most specific
532
530
  if (elementId) {
533
- queries.push('id="' + elementId + '"');
531
+ queries.push(`id="${elementId}"`);
534
532
  }
535
533
 
536
534
  // 2. Full class attribute match (for elements with distinctive multi-class combos).
@@ -541,8 +539,8 @@ function buildSearchQueries(elementId, classes, tag, query) {
541
539
  if (classList.length > 1) {
542
540
  const joined = classList.join(' ');
543
541
  const sorted = [...classList].sort((a, b) => b.length - a.length);
544
- queries.push('class="' + joined + '"');
545
- queries.push('className="' + joined + '"');
542
+ queries.push(`class="${joined}"`);
543
+ queries.push(`className="${joined}"`);
546
544
  for (const className of sorted) {
547
545
  queries.push(className);
548
546
  }
@@ -555,8 +553,8 @@ function buildSearchQueries(elementId, classes, tag, query) {
555
553
  // Same dual-emit for JSX compatibility.
556
554
  if (tag && classes) {
557
555
  const firstClass = splitClassList(classes)[0];
558
- queries.push('<' + tag + ' class="' + firstClass);
559
- queries.push('<' + tag + ' className="' + firstClass);
556
+ queries.push(`<${tag} class="${firstClass}`);
557
+ queries.push(`<${tag} className="${firstClass}`);
560
558
  }
561
559
 
562
560
  // 4. Raw fallback query
@@ -571,14 +569,6 @@ function splitClassList(classes) {
571
569
  return String(classes).split(/[,\s]+/).map(c => c.trim()).filter(Boolean);
572
570
  }
573
571
 
574
- function attrEscapeDouble(str) {
575
- return String(str)
576
- .replace(/&/g, '&amp;')
577
- .replace(/"/g, '&quot;')
578
- .replace(/</g, '&lt;')
579
- .replace(/>/g, '&gt;');
580
- }
581
-
582
572
  function detectCommentSyntax(filePath) {
583
573
  const ext = path.extname(filePath).toLowerCase();
584
574
  if (ext === '.jsx' || ext === '.tsx') {
@@ -854,9 +844,9 @@ function findClosingLine(lines, start) {
854
844
 
855
845
  const tagName = openMatch[1];
856
846
  let depth = 0;
857
- const openRe = new RegExp('<' + tagName + '(?=[\\s/>]|$)', 'g');
858
- const selfCloseRe = new RegExp('<' + tagName + '[^>]*/>', 'g');
859
- const closeRe = new RegExp('</' + tagName + '\\s*>', 'g');
847
+ const openRe = new RegExp(`<${tagName}(?=[\\s/>]|$)`, 'g');
848
+ const selfCloseRe = new RegExp(`<${tagName}[^>]*/>`, 'g');
849
+ const closeRe = new RegExp(`</${tagName}\\s*>`, 'g');
860
850
 
861
851
  for (let i = start; i < lines.length; i++) {
862
852
  const line = lines[i];
@@ -93,7 +93,7 @@ The agent should then:
93
93
  // 1. Check config (fail fast if missing — no point starting anything else)
94
94
  const checkOut = runScript('live-inject.mjs', ['--check'], { cwd: activeCwd });
95
95
  const checkResult = safeParse(checkOut);
96
- if (!checkResult || !checkResult.ok) {
96
+ if (!checkResult?.ok) {
97
97
  console.log(JSON.stringify({
98
98
  ...(checkResult || { ok: false, error: 'check_failed', raw: checkOut }),
99
99
  targetPath: outputTargetPath,
@@ -113,7 +113,7 @@ The agent should then:
113
113
  // 3. Inject the script tag at the current port
114
114
  const injectOut = runScript('live-inject.mjs', ['--port', String(serverInfo.port)], { cwd: activeCwd });
115
115
  const injectResult = safeParse(injectOut);
116
- if (!injectResult || !injectResult.ok) {
116
+ if (!injectResult?.ok) {
117
117
  console.log(JSON.stringify({
118
118
  ok: false,
119
119
  error: 'inject_failed',
@@ -238,14 +238,14 @@ function globToRegex(pattern) {
238
238
  re += '[^/]';
239
239
  i += 1;
240
240
  } else if (/[.+^${}()|[\]\\]/.test(c)) {
241
- re += '\\' + c;
241
+ re += `\\${c}`;
242
242
  i += 1;
243
243
  } else {
244
244
  re += c;
245
245
  i += 1;
246
246
  }
247
247
  }
248
- return new RegExp('^' + re + '$');
248
+ return new RegExp(`^${re}$`);
249
249
  }
250
250
 
251
251
  // ---------------------------------------------------------------------------
@@ -274,7 +274,7 @@ function ensureServerRunning(cwd = process.cwd()) {
274
274
  // Try to reuse an existing server
275
275
  try {
276
276
  const existing = readLiveServerInfo(cwd)?.info;
277
- if (existing && existing.pid) {
277
+ if (existing?.pid) {
278
278
  try {
279
279
  process.kill(existing.pid, 0); // throws if dead
280
280
  return existing;
@@ -32,6 +32,7 @@ import crypto from 'node:crypto';
32
32
  // ~400 candidates from ColorHunt + synthesis + Radix/brand/Pantone anchors).
33
33
  // Each carries a mood + strategy the judging model produced — surfaced as
34
34
  // hints, not commands; the brief still drives composition.
35
+ // biome-ignore-start lint/suspicious/noApproximativeNumericConstant: OKLCH lightness values (e.g. 0.400, 0.700) that merely resemble Math.LOG10E/LOG2E; they are curated colour data, not those constants
35
36
  const SEEDS = [
36
37
  { id: "seed-200", oklch: [0.360, 0.137, 0.0],
37
38
  mood: "Aesop apothecary shelf — oxblood bottle glass against linen, considered and unhurried",
@@ -421,6 +422,7 @@ const SEEDS = [
421
422
  mood: "modern beauty brand DTC — Glossier-adjacent pink, confident and current without being saccharine",
422
423
  strategy: "Pure white surface so the rose-pink primary carries all the brand warmth, paired with a near-black ink and a desaturated mauve accent for editorial restraint." },
423
424
  ];
425
+ // biome-ignore-end lint/suspicious/noApproximativeNumericConstant: end of curated seed data
424
426
 
425
427
  function parseArgs(argv) {
426
428
  const args = { id: null, from: null };
@@ -499,7 +501,7 @@ function hueWord(H) {
499
501
 
500
502
  const args = parseArgs(process.argv.slice(2));
501
503
  const seed = pickSeed(SEEDS, args);
502
- const [L, C, H] = seed.oklch;
504
+ const [, , H] = seed.oklch;
503
505
 
504
506
  // The mood + strategy on each seed were derived by the model that
505
507
  // originally judged it. We surface them as *hints*, not commands —
@@ -13,7 +13,7 @@
13
13
  * in the project root and creates/removes the pin in all of them.
14
14
  */
15
15
 
16
- import { existsSync, readFileSync, writeFileSync, mkdirSync, rmSync, readdirSync } from 'node:fs';
16
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, rmSync } from 'node:fs';
17
17
  import { basename, join, resolve, dirname } from 'node:path';
18
18
  import { fileURLToPath } from 'node:url';
19
19
 
@@ -1 +1 @@
1
- {"version":3,"file":"doc-filters.d.ts","sourceRoot":"","sources":["../../../src/commands/doc-filters.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjE;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,aAAa,EAwBzC,CAAC;AAEF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,GAAG,SAAS,CAO7D;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,cAAc,GAAG,aAAa,CAUzE;AAED,eAAO,MAAM,SAAS,MAAO,aAAa,KAAG,OAAoC,CAAC"}
1
+ {"version":3,"file":"doc-filters.d.ts","sourceRoot":"","sources":["../../../src/commands/doc-filters.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjE;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,aAAa,EA6BzC,CAAC;AAEF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,GAAG,SAAS,CAO7D;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,cAAc,GAAG,aAAa,CAWzE;AAED,eAAO,MAAM,SAAS,MAAO,aAAa,KAAG,OAAoC,CAAC"}
@@ -34,6 +34,11 @@ export const FILTER_OPTIONS = [
34
34
  type: 'string',
35
35
  },
36
36
  { name: 'captured', description: 'Only pages captured from the web', type: 'boolean' },
37
+ // A substring filter over title, URL, path and note — for finding a shelf of
38
+ // the library by name. It is NOT a URL lookup: an exact "is this page
39
+ // saved?" is `doc lookup`, which matches on capture identity rather than on
40
+ // a substring, and answers with the note as well.
41
+ { name: 'text', description: 'Substring match over title, URL, path and note', type: 'string' },
37
42
  ];
38
43
  export function flagList(value) {
39
44
  const raw = Array.isArray(value) ? value : value === undefined ? [] : [value];
@@ -52,6 +57,7 @@ export function libraryFilterFromFlags(ctx) {
52
57
  ...(ctx.flags.since ? { since: String(ctx.flags.since) } : {}),
53
58
  ...(ctx.flags.until ? { until: String(ctx.flags.until) } : {}),
54
59
  ...(ctx.flags.captured === true ? { capturedOnly: true } : {}),
60
+ ...(ctx.flags.text ? { text: String(ctx.flags.text) } : {}),
55
61
  };
56
62
  }
57
63
  export const hasFilter = (f) => Object.keys(f).length > 0;
@@ -1 +1 @@
1
- {"version":3,"file":"doc-filters.js","sourceRoot":"","sources":["../../../src/commands/doc-filters.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"doc-filters.js","sourceRoot":"","sources":["../../../src/commands/doc-filters.ts"],"names":[],"mappings":"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"}