@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.
- package/.claude/helpers/control-start.cjs +10 -13
- package/.claude/skills/monodesign/scripts/context.mjs +4 -4
- package/.claude/skills/monodesign/scripts/critique-storage.mjs +1 -1
- package/.claude/skills/monodesign/scripts/detect-csp.mjs +1 -6
- package/.claude/skills/monodesign/scripts/detector/browser/injected/index.mjs +16 -18
- package/.claude/skills/monodesign/scripts/detector/cli/main.mjs +3 -3
- package/.claude/skills/monodesign/scripts/detector/detect-antipatterns-browser.js +67 -47
- package/.claude/skills/monodesign/scripts/detector/engines/regex/detect-text.mjs +6 -6
- package/.claude/skills/monodesign/scripts/detector/engines/static-html/css-cascade.mjs +6 -5
- package/.claude/skills/monodesign/scripts/detector/engines/static-html/detect-html.mjs +6 -6
- package/.claude/skills/monodesign/scripts/detector/fix/index.mjs +3 -3
- package/.claude/skills/monodesign/scripts/detector/node/file-system.mjs +1 -1
- package/.claude/skills/monodesign/scripts/detector/registry/antipatterns.mjs +1 -1
- package/.claude/skills/monodesign/scripts/detector/rules/checks.mjs +24 -25
- package/.claude/skills/monodesign/scripts/detector/shared/color.mjs +2 -2
- package/.claude/skills/monodesign/scripts/detector/shared/constants.mjs +1 -1
- package/.claude/skills/monodesign/scripts/detector/shared/inline-ignores.mjs +2 -2
- package/.claude/skills/monodesign/scripts/hook-admin.mjs +6 -6
- package/.claude/skills/monodesign/scripts/hook-before-edit.mjs +4 -4
- package/.claude/skills/monodesign/scripts/hook-lib.mjs +20 -11
- package/.claude/skills/monodesign/scripts/hook.mjs +1 -1
- package/.claude/skills/monodesign/scripts/lib/design-parser.mjs +9 -42
- package/.claude/skills/monodesign/scripts/lib/is-generated.mjs +1 -1
- package/.claude/skills/monodesign/scripts/lib/monodesign-config.mjs +5 -5
- package/.claude/skills/monodesign/scripts/lib/monodesign-paths.mjs +1 -1
- package/.claude/skills/monodesign/scripts/live/event-validation.mjs +13 -13
- package/.claude/skills/monodesign/scripts/live/manual-apply.mjs +4 -4
- package/.claude/skills/monodesign/scripts/live/manual-edits-buffer.mjs +1 -1
- package/.claude/skills/monodesign/scripts/live/session-store.mjs +5 -5
- package/.claude/skills/monodesign/scripts/live/svelte-component.mjs +13 -13
- package/.claude/skills/monodesign/scripts/live/sveltekit-adapter.mjs +4 -4
- package/.claude/skills/monodesign/scripts/live/ui-core.mjs +1 -1
- package/.claude/skills/monodesign/scripts/live-accept.mjs +24 -24
- package/.claude/skills/monodesign/scripts/live-browser-dom.js +8 -7
- package/.claude/skills/monodesign/scripts/live-browser-session.js +8 -7
- package/.claude/skills/monodesign/scripts/live-browser.js +405 -432
- package/.claude/skills/monodesign/scripts/live-commit-manual-edits.mjs +6 -6
- package/.claude/skills/monodesign/scripts/live-copy-edit-agent.mjs +2 -2
- package/.claude/skills/monodesign/scripts/live-discard-manual-edits.mjs +1 -1
- package/.claude/skills/monodesign/scripts/live-inject.mjs +7 -7
- package/.claude/skills/monodesign/scripts/live-insert.mjs +11 -11
- package/.claude/skills/monodesign/scripts/live-manual-edit-evidence.mjs +4 -4
- package/.claude/skills/monodesign/scripts/live-poll.mjs +5 -5
- package/.claude/skills/monodesign/scripts/live-server.mjs +10 -10
- package/.claude/skills/monodesign/scripts/live-wrap.mjs +31 -41
- package/.claude/skills/monodesign/scripts/live.mjs +5 -5
- package/.claude/skills/monodesign/scripts/palette.mjs +3 -1
- package/.claude/skills/monodesign/scripts/pin.mjs +1 -1
- package/dist/src/commands/doc-filters.d.ts.map +1 -1
- package/dist/src/commands/doc-filters.js +6 -0
- package/dist/src/commands/doc-filters.js.map +1 -1
- package/dist/src/commands/doc-library.d.ts +2 -1
- package/dist/src/commands/doc-library.d.ts.map +1 -1
- package/dist/src/commands/doc-library.js +66 -2
- package/dist/src/commands/doc-library.js.map +1 -1
- package/dist/src/commands/doc.d.ts.map +1 -1
- package/dist/src/commands/doc.js +2 -0
- package/dist/src/commands/doc.js.map +1 -1
- package/dist/src/commands/org.d.ts.map +1 -1
- package/dist/src/commands/org.js +42 -4
- package/dist/src/commands/org.js.map +1 -1
- package/dist/src/commands/ui.d.ts.map +1 -1
- package/dist/src/commands/ui.js +60 -0
- package/dist/src/commands/ui.js.map +1 -1
- package/dist/src/knowledge/capture-envelope.d.ts +5 -0
- package/dist/src/knowledge/capture-envelope.d.ts.map +1 -1
- package/dist/src/knowledge/capture-envelope.js +2 -0
- package/dist/src/knowledge/capture-envelope.js.map +1 -1
- package/dist/src/knowledge/document-chunking.d.ts +42 -0
- package/dist/src/knowledge/document-chunking.d.ts.map +1 -0
- package/dist/src/knowledge/document-chunking.js +288 -0
- package/dist/src/knowledge/document-chunking.js.map +1 -0
- package/dist/src/knowledge/document-index.d.ts +124 -0
- package/dist/src/knowledge/document-index.d.ts.map +1 -0
- package/dist/src/knowledge/document-index.js +314 -0
- package/dist/src/knowledge/document-index.js.map +1 -0
- package/dist/src/knowledge/document-ingest.d.ts +23 -0
- package/dist/src/knowledge/document-ingest.d.ts.map +1 -0
- package/dist/src/knowledge/document-ingest.js +368 -0
- package/dist/src/knowledge/document-ingest.js.map +1 -0
- package/dist/src/knowledge/document-pipeline.d.ts +26 -208
- package/dist/src/knowledge/document-pipeline.d.ts.map +1 -1
- package/dist/src/knowledge/document-pipeline.js +25 -1104
- package/dist/src/knowledge/document-pipeline.js.map +1 -1
- package/dist/src/knowledge/document-search.d.ts +27 -0
- package/dist/src/knowledge/document-search.d.ts.map +1 -0
- package/dist/src/knowledge/document-search.js +138 -0
- package/dist/src/knowledge/document-search.js.map +1 -0
- package/dist/src/knowledge/document-store.d.ts +28 -0
- package/dist/src/knowledge/document-store.d.ts.map +1 -0
- package/dist/src/knowledge/document-store.js +61 -0
- package/dist/src/knowledge/document-store.js.map +1 -0
- package/dist/src/knowledge/document-types.d.ts +103 -0
- package/dist/src/knowledge/document-types.d.ts.map +1 -0
- package/dist/src/knowledge/document-types.js +12 -0
- package/dist/src/knowledge/document-types.js.map +1 -0
- package/dist/src/knowledge/highlights.d.ts +168 -0
- package/dist/src/knowledge/highlights.d.ts.map +1 -0
- package/dist/src/knowledge/highlights.js +311 -0
- package/dist/src/knowledge/highlights.js.map +1 -0
- package/dist/src/knowledge/lookup.d.ts +80 -0
- package/dist/src/knowledge/lookup.d.ts.map +1 -0
- package/dist/src/knowledge/lookup.js +156 -0
- package/dist/src/knowledge/lookup.js.map +1 -0
- package/dist/src/knowledge/okf-bundle.d.ts +19 -0
- package/dist/src/knowledge/okf-bundle.d.ts.map +1 -0
- package/dist/src/knowledge/okf-bundle.js +106 -0
- package/dist/src/knowledge/okf-bundle.js.map +1 -0
- package/dist/src/knowledge/profile-store.d.ts +134 -0
- package/dist/src/knowledge/profile-store.d.ts.map +1 -0
- package/dist/src/knowledge/profile-store.js +237 -0
- package/dist/src/knowledge/profile-store.js.map +1 -0
- package/dist/src/orgrt/agent-runner.d.ts +4 -0
- package/dist/src/orgrt/agent-runner.d.ts.map +1 -1
- package/dist/src/orgrt/agent-runner.js +22 -0
- package/dist/src/orgrt/agent-runner.js.map +1 -1
- package/dist/src/orgrt/antigravity-runner.d.ts.map +1 -1
- package/dist/src/orgrt/antigravity-runner.js +2 -1
- package/dist/src/orgrt/antigravity-runner.js.map +1 -1
- package/dist/src/orgrt/authority-mask.d.ts +32 -0
- package/dist/src/orgrt/authority-mask.d.ts.map +1 -0
- package/dist/src/orgrt/authority-mask.js +135 -0
- package/dist/src/orgrt/authority-mask.js.map +1 -0
- package/dist/src/orgrt/codex-runner.d.ts.map +1 -1
- package/dist/src/orgrt/codex-runner.js +2 -1
- package/dist/src/orgrt/codex-runner.js.map +1 -1
- package/dist/src/orgrt/copilot-runner.d.ts.map +1 -1
- package/dist/src/orgrt/copilot-runner.js +2 -1
- package/dist/src/orgrt/copilot-runner.js.map +1 -1
- package/dist/src/orgrt/crush-runner.d.ts.map +1 -1
- package/dist/src/orgrt/crush-runner.js +6 -1
- package/dist/src/orgrt/crush-runner.js.map +1 -1
- package/dist/src/orgrt/daemon.d.ts +4 -0
- package/dist/src/orgrt/daemon.d.ts.map +1 -1
- package/dist/src/orgrt/daemon.js +13 -2
- package/dist/src/orgrt/daemon.js.map +1 -1
- package/dist/src/orgrt/decisions.d.ts +9 -0
- package/dist/src/orgrt/decisions.d.ts.map +1 -1
- package/dist/src/orgrt/decisions.js +32 -5
- package/dist/src/orgrt/decisions.js.map +1 -1
- package/dist/src/orgrt/file-roots.d.ts +2 -1
- package/dist/src/orgrt/file-roots.d.ts.map +1 -1
- package/dist/src/orgrt/file-roots.js +7 -3
- package/dist/src/orgrt/file-roots.js.map +1 -1
- package/dist/src/orgrt/grok-runner.d.ts.map +1 -1
- package/dist/src/orgrt/grok-runner.js +2 -1
- package/dist/src/orgrt/grok-runner.js.map +1 -1
- package/dist/src/orgrt/hermes-runner.d.ts.map +1 -1
- package/dist/src/orgrt/hermes-runner.js +2 -1
- package/dist/src/orgrt/hermes-runner.js.map +1 -1
- package/dist/src/orgrt/inbox.d.ts.map +1 -1
- package/dist/src/orgrt/inbox.js +70 -4
- package/dist/src/orgrt/inbox.js.map +1 -1
- package/dist/src/orgrt/kimicode-runner.d.ts.map +1 -1
- package/dist/src/orgrt/kimicode-runner.js +2 -1
- package/dist/src/orgrt/kimicode-runner.js.map +1 -1
- package/dist/src/orgrt/opencode-runner.d.ts.map +1 -1
- package/dist/src/orgrt/opencode-runner.js +3 -2
- package/dist/src/orgrt/opencode-runner.js.map +1 -1
- package/dist/src/orgrt/pi-rpc-runner.d.ts.map +1 -1
- package/dist/src/orgrt/pi-rpc-runner.js +3 -2
- package/dist/src/orgrt/pi-rpc-runner.js.map +1 -1
- package/dist/src/orgrt/pi-runner.d.ts.map +1 -1
- package/dist/src/orgrt/pi-runner.js +2 -1
- package/dist/src/orgrt/pi-runner.js.map +1 -1
- package/dist/src/orgrt/policy.d.ts.map +1 -1
- package/dist/src/orgrt/policy.js +3 -0
- package/dist/src/orgrt/policy.js.map +1 -1
- package/dist/src/orgrt/qwen-rpc-runner.d.ts.map +1 -1
- package/dist/src/orgrt/qwen-rpc-runner.js +3 -2
- package/dist/src/orgrt/qwen-rpc-runner.js.map +1 -1
- package/dist/src/orgrt/qwen-runner.d.ts.map +1 -1
- package/dist/src/orgrt/qwen-runner.js +2 -1
- package/dist/src/orgrt/qwen-runner.js.map +1 -1
- package/dist/src/orgrt/role-sandbox.d.ts +21 -0
- package/dist/src/orgrt/role-sandbox.d.ts.map +1 -1
- package/dist/src/orgrt/role-sandbox.js +31 -6
- package/dist/src/orgrt/role-sandbox.js.map +1 -1
- package/dist/src/orgrt/session.d.ts.map +1 -1
- package/dist/src/orgrt/session.js +21 -2
- package/dist/src/orgrt/session.js.map +1 -1
- package/dist/src/orgrt/task-dag.d.ts +3 -0
- package/dist/src/orgrt/task-dag.d.ts.map +1 -1
- package/dist/src/orgrt/task-dag.js +1 -0
- package/dist/src/orgrt/task-dag.js.map +1 -1
- package/dist/src/orgrt/types.d.ts +5 -0
- package/dist/src/orgrt/types.d.ts.map +1 -1
- package/dist/src/orgrt/types.js +23 -1
- package/dist/src/orgrt/types.js.map +1 -1
- package/dist/src/ui/dashboard.html +28 -848
- package/dist/src/ui/human-auth.mjs +103 -0
- package/dist/src/ui/org-hil.mjs +86 -37
- package/dist/src/ui/org-runtime.mjs +21 -13
- package/dist/src/ui/routes-org.mjs +49 -445
- package/dist/src/ui/server.mjs +103 -4
- package/dist/tsconfig.tsbuildinfo +1 -1
- 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
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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)
|
|
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
|
|
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
|
|
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
|
|
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 +=
|
|
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(
|
|
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*$/, '')
|
|
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)
|
|
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
|
|
51
|
-
indent
|
|
52
|
-
indent
|
|
53
|
-
indent
|
|
54
|
-
indent
|
|
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
|
|
60
|
-
indent
|
|
61
|
-
indent
|
|
62
|
-
indent
|
|
63
|
-
indent + commentSyntax.open
|
|
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(
|
|
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(
|
|
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:
|
|
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
|
|
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
|
|
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')
|
|
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(
|
|
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(
|
|
237
|
+
process.stderr.write(`\n${manualApplyPollBanner(event)}\n`);
|
|
238
238
|
}
|
|
239
239
|
if (event._acceptResult?.carbonize === true) {
|
|
240
|
-
process.stderr.write(
|
|
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 =
|
|
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)
|
|
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(
|
|
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(
|
|
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
|
|
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:
|
|
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 =
|
|
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(
|
|
665
|
+
res.write(`data: ${JSON.stringify({
|
|
666
666
|
type: 'connected',
|
|
667
667
|
hasProjectContext: hasProjectContext(),
|
|
668
668
|
agentPolling: agentPollingConnected(),
|
|
669
669
|
activeSessions: activeSessionSummaries(),
|
|
670
|
-
})
|
|
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(
|
|
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)
|
|
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:
|
|
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:
|
|
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
|
|
292
|
-
indent
|
|
293
|
-
indent
|
|
294
|
-
indent
|
|
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
|
|
297
|
-
indent
|
|
298
|
-
indent
|
|
299
|
-
indent
|
|
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
|
|
302
|
-
indent
|
|
303
|
-
indent
|
|
304
|
-
indent
|
|
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
|
|
307
|
-
indent
|
|
308
|
-
indent
|
|
309
|
-
indent + commentSyntax.open
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
545
|
-
queries.push(
|
|
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(
|
|
559
|
-
queries.push(
|
|
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, '&')
|
|
577
|
-
.replace(/"/g, '"')
|
|
578
|
-
.replace(/</g, '<')
|
|
579
|
-
.replace(/>/g, '>');
|
|
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(
|
|
858
|
-
const selfCloseRe = new RegExp(
|
|
859
|
-
const closeRe = new RegExp(
|
|
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
|
|
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
|
|
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 +=
|
|
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(
|
|
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
|
|
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 [
|
|
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
|
|
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,
|
|
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":"AAAA;;;;;;;GAOG;AAKH;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAoB;IAC7C;QACE,IAAI,EAAE,MAAM;QACZ,WAAW,EAAE,sDAAsD;QACnE,IAAI,EAAE,OAAO;KACd;IACD,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,oCAAoC,EAAE,IAAI,EAAE,OAAO,EAAE;IACjF,EAAE,IAAI,EAAE,YAAY,EAAE,WAAW,EAAE,sBAAsB,EAAE,IAAI,EAAE,OAAO,EAAE;IAC1E;QACE,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,0DAA0D;QACvE,IAAI,EAAE,OAAO;KACd;IACD;QACE,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,qDAAqD;QAClE,IAAI,EAAE,QAAQ;KACf;IACD;QACE,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,sDAAsD;QACnE,IAAI,EAAE,QAAQ;KACf;IACD,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,kCAAkC,EAAE,IAAI,EAAE,SAAS,EAAE;
|
|
1
|
+
{"version":3,"file":"doc-filters.js","sourceRoot":"","sources":["../../../src/commands/doc-filters.ts"],"names":[],"mappings":"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"}
|