@hraness/wordcell 0.22.5 → 0.24.0

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 (78) hide show
  1. package/README.md +67 -18
  2. package/dist/authoring.js +2 -2
  3. package/dist/{authority-3ga47syb.js → authority-35cbvp1x.js} +2 -2
  4. package/dist/benchmark.js +3 -3
  5. package/dist/capture.js +6 -6
  6. package/dist/cli.js +26 -24
  7. package/dist/clip/acquire.js +3 -3
  8. package/dist/clip/args.js +1 -1
  9. package/dist/clip/cli.js +6 -6
  10. package/dist/clip/doctor.js +4 -4
  11. package/dist/evaluation-builder.js +10 -10
  12. package/dist/evaluation-kb.js +10 -10
  13. package/dist/graph-authority.js +4 -4
  14. package/dist/graph-percolation.js +6 -6
  15. package/dist/graph.js +3 -1
  16. package/dist/{index-bcknqxrq.js → index-0eacgvpv.js} +9 -1
  17. package/dist/{index-f75zmmdr.js → index-1er88ckw.js} +4 -4
  18. package/dist/{index-8v6k9h4r.js → index-1s8mc4hz.js} +1 -1
  19. package/dist/{index-n9kwenpt.js → index-1w0sp1q7.js} +1 -1
  20. package/dist/{index-de2w8crk.js → index-2fmnttca.js} +82 -15
  21. package/dist/{index-8bgnhjgq.js → index-44kw9tr8.js} +3867 -162
  22. package/dist/{index-42tb8qqp.js → index-5d1rd5v9.js} +444 -9
  23. package/dist/{index-aer0jdrq.js → index-ahyhryb8.js} +1 -1
  24. package/dist/{index-f7fnww7a.js → index-b0khj0h5.js} +164 -9
  25. package/dist/{index-qdb8f8va.js → index-bdwcjvr4.js} +1 -1
  26. package/dist/{index-dfag79p7.js → index-byz4kzww.js} +3 -0
  27. package/dist/{index-hgve9rh2.js → index-cd75vky9.js} +96 -1
  28. package/dist/{index-h2qn3y3f.js → index-f184qyh1.js} +4 -4
  29. package/dist/{index-n57tewfr.js → index-fp732bgg.js} +2 -2
  30. package/dist/{index-zy7an84p.js → index-jvb7w0gg.js} +5 -2
  31. package/dist/{index-f984hw45.js → index-k86wepd8.js} +1 -1
  32. package/dist/{index-1r5rnkfr.js → index-mvs6f7ne.js} +2 -2
  33. package/dist/{index-p96kb6t2.js → index-nn67kzwa.js} +1 -1
  34. package/dist/{index-fc4dr114.js → index-nwrehke7.js} +1 -1
  35. package/dist/{index-pz2b2x0y.js → index-pgtm2nhf.js} +1 -1
  36. package/dist/{index-054mb7d3.js → index-qfqjfxaa.js} +10 -9
  37. package/dist/{index-xzvcw9ga.js → index-r0m5taz2.js} +2 -2
  38. package/dist/{index-gtwqye5a.js → index-tcaq1c7f.js} +4 -4
  39. package/dist/{index-g5vsqmdy.js → index-xwxy71ew.js} +190 -4
  40. package/dist/index.js +15 -13
  41. package/dist/pdf.js +3 -3
  42. package/dist/percolate.js +2 -2
  43. package/dist/portfolio.js +10 -10
  44. package/dist/publish.js +3 -3
  45. package/dist/sdk.js +9 -9
  46. package/dist/search.js +2 -2
  47. package/dist/semantic.js +4 -4
  48. package/dist/{support-jf9v10j7.js → support-1yhv6vm6.js} +25 -23
  49. package/dist/url-intelligence.js +1 -1
  50. package/dist/workflows/decision-context.js +10 -10
  51. package/dist/workflows/index.js +10 -10
  52. package/package.json +12 -4
  53. package/skills/wordcell/AGENTS.md +1 -0
  54. package/skills/wordcell/SKILL.md +5 -3
  55. package/skills/wordcell/references/query.md +52 -4
  56. package/skills/wordcell/references/session-memory.md +207 -0
  57. package/src/authoring-import.ts +32 -0
  58. package/src/authoring-model.ts +185 -2
  59. package/src/authoring-program.ts +19 -7
  60. package/src/cli-help.ts +894 -0
  61. package/src/cli-intro.ts +1 -1
  62. package/src/cli-program.ts +612 -83
  63. package/src/cli-style.ts +132 -0
  64. package/src/clip/acquire.ts +20 -0
  65. package/src/clip/args.ts +3 -0
  66. package/src/clip/cli.ts +82 -5
  67. package/src/clip/cookie-permission.ts +241 -0
  68. package/src/clip/url-metadata-cli.ts +6 -5
  69. package/src/clip/url-metadata.ts +14 -0
  70. package/src/graph.ts +9 -4
  71. package/src/import-supermemory.ts +1629 -0
  72. package/src/mcp-server.ts +415 -0
  73. package/src/mcp-tools.ts +1138 -0
  74. package/src/pdf/cli.ts +5 -4
  75. package/src/sdk.ts +149 -1
  76. package/src/selected-passage.ts +409 -0
  77. package/src/support-profile.ts +1 -1
  78. package/src/support.ts +3 -0
@@ -5,9 +5,10 @@ import {
5
5
  import {
6
6
  isCanonicalNoteId,
7
7
  isCanonicalRelationPredicate,
8
+ isMetadataNumber,
8
9
  parseDocumentId,
9
10
  parseQualifiedDocumentUri
10
- } from "./index-zy7an84p.js";
11
+ } from "./index-jvb7w0gg.js";
11
12
 
12
13
  // src/authoring-model.ts
13
14
  import { createHash } from "crypto";
@@ -462,13 +463,159 @@ function renderUpdatedNoteBody(snapshot, parts, body) {
462
463
  const header = snapshot.content.slice(0, snapshot.content.length - parts.bodySuffix.length);
463
464
  return `${header}${parts.newline}${parts.newline}${normalized}`;
464
465
  }
465
- function renderCreatedNote(input, documentId) {
466
+ var MAX_FRONTMATTER_FIELDS = 64;
467
+ var MAX_FRONTMATTER_LIST_ITEMS = 256;
468
+ var FRONTMATTER_FIELD_KEY = /^[a-z][a-z0-9_]{0,63}$/u;
469
+ var FRONTMATTER_MAP_KEY = /^[A-Za-z0-9_.:-]{1,64}$/u;
470
+ var RESERVED_FRONTMATTER_FIELDS = new Set([
471
+ "document_id",
472
+ "type",
473
+ "title",
474
+ "tags",
475
+ "relations"
476
+ ]);
477
+ function validateFieldString(value, label) {
478
+ if (typeof value !== "string")
479
+ throw new TypeError(`frontmatter field ${label} must be a string`);
480
+ if (Buffer.from(value, "utf8").toString("utf8") !== value || /[\u0000-\u001f\u007f]/u.test(value)) {
481
+ throw new TypeError(`frontmatter field ${label} must be a single line of well-formed text`);
482
+ }
483
+ return value;
484
+ }
485
+ function validateFieldScalar(value, label) {
486
+ if (typeof value === "boolean")
487
+ return value;
488
+ if (typeof value === "number") {
489
+ if (!isMetadataNumber(value)) {
490
+ throw new TypeError(`frontmatter field ${label} must be a finite number and a safe integer when integral`);
491
+ }
492
+ return value;
493
+ }
494
+ return validateFieldString(value, label);
495
+ }
496
+ function validateFieldValue(value, key) {
497
+ if (Array.isArray(value)) {
498
+ if (value.length > MAX_FRONTMATTER_LIST_ITEMS) {
499
+ throw new TypeError(`frontmatter field ${key} has too many items`);
500
+ }
501
+ return value.map((item, index) => validateFieldString(item, `${key}[${index}]`));
502
+ }
503
+ if (typeof value === "object" && value !== null) {
504
+ if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) {
505
+ throw new TypeError(`frontmatter field ${key} must be a plain map`);
506
+ }
507
+ const entries = Object.entries(value);
508
+ if (entries.length > MAX_FRONTMATTER_FIELDS) {
509
+ throw new TypeError(`frontmatter field ${key} has too many keys`);
510
+ }
511
+ const result = {};
512
+ for (const [nested, item] of entries) {
513
+ if (!FRONTMATTER_MAP_KEY.test(nested) || nested === "__proto__") {
514
+ throw new TypeError(`frontmatter field ${key} has an invalid key: ${JSON.stringify(nested)}`);
515
+ }
516
+ result[nested] = validateFieldScalar(item, `${key}.${nested}`);
517
+ }
518
+ return result;
519
+ }
520
+ return validateFieldScalar(value, key);
521
+ }
522
+ function validateFieldKey(key, allowTitle) {
523
+ if (!FRONTMATTER_FIELD_KEY.test(key)) {
524
+ throw new TypeError(`not a valid frontmatter field name: ${JSON.stringify(key)}`);
525
+ }
526
+ if (RESERVED_FRONTMATTER_FIELDS.has(key) && !(allowTitle && key === "title")) {
527
+ throw new TypeError(`frontmatter field ${key} is reserved`);
528
+ }
529
+ }
530
+ function validateFrontmatterFields(fields) {
531
+ if (fields === undefined)
532
+ return {};
533
+ const entries = Object.entries(fields);
534
+ if (entries.length > MAX_FRONTMATTER_FIELDS)
535
+ throw new TypeError("too many frontmatter fields");
536
+ const result = {};
537
+ for (const [key, value] of entries) {
538
+ validateFieldKey(key, false);
539
+ result[key] = validateFieldValue(value, key);
540
+ }
541
+ return result;
542
+ }
543
+ function validateFrontmatterFieldUpdates(fields) {
544
+ if (fields === undefined)
545
+ return {};
546
+ const entries = Object.entries(fields);
547
+ if (entries.length > MAX_FRONTMATTER_FIELDS)
548
+ throw new TypeError("too many frontmatter fields");
549
+ const result = {};
550
+ for (const [key, value] of entries) {
551
+ validateFieldKey(key, true);
552
+ if (key === "title") {
553
+ if (typeof value !== "string")
554
+ throw new TypeError("frontmatter field title must be a string");
555
+ result[key] = validateTitle(value);
556
+ } else {
557
+ result[key] = value === null ? null : validateFieldValue(value, key);
558
+ }
559
+ }
560
+ return result;
561
+ }
562
+ function canonicalJson(value) {
563
+ if (Array.isArray(value))
564
+ return `[${value.map(canonicalJson).join(",")}]`;
565
+ if (typeof value === "object" && value !== null) {
566
+ const keys = Object.keys(value).sort();
567
+ return `{${keys.map((key) => `${JSON.stringify(key)}:${canonicalJson(value[key])}`).join(",")}}`;
568
+ }
569
+ return JSON.stringify(value) ?? "undefined";
570
+ }
571
+ function topLevelValue(parts, key) {
572
+ const contents = parts.document.contents;
573
+ if (!isMap(contents) || !contents.has(key))
574
+ return;
575
+ const node = contents.get(key, true);
576
+ if (typeof node === "object" && node !== null && "toJSON" in node && typeof node.toJSON === "function") {
577
+ return node.toJSON();
578
+ }
579
+ return node;
580
+ }
581
+ function sameFrontmatterValue(present, requested) {
582
+ return canonicalJson(present) === canonicalJson(requested);
583
+ }
584
+ function renderUpdatedNoteBodyAndFields(snapshot, parts, body, fields) {
585
+ const updates = validateFrontmatterFieldUpdates(fields);
586
+ const bodyOnly = renderUpdatedNoteBody(snapshot, parts, body);
587
+ if (Object.keys(updates).length === 0)
588
+ return bodyOnly;
589
+ if (!parts.hadFrontmatter || !isMap(parts.document.contents)) {
590
+ throw new TypeError("frontmatter fields require a note with a frontmatter map");
591
+ }
592
+ const contents = parts.document.contents;
593
+ for (const [key, value] of Object.entries(updates)) {
594
+ if (value === null) {
595
+ contents.delete(key);
596
+ } else if (!sameFrontmatterValue(topLevelValue(parts, key), value)) {
597
+ contents.set(key, parts.document.createNode(value));
598
+ }
599
+ }
600
+ const content = renderFrontmatter({
601
+ ...parts,
602
+ bodySuffix: `${parts.newline}${parts.newline}${normalizedRequestedBody(body)}`
603
+ });
604
+ if (Buffer.byteLength(content, "utf8") > MAX_NOTE_BYTES) {
605
+ throw new RangeError("the note is too large for bounded authoring");
606
+ }
607
+ return content;
608
+ }
609
+ function renderCreatedNote(input, documentId, fields) {
466
610
  const title = validateTitle(input.title);
467
611
  const type = validateType(input.type);
468
612
  const tags = validateTags(input.tags);
613
+ const extra = validateFrontmatterFields(fields);
469
614
  const metadata = { document_id: documentId, type, title };
470
615
  if (tags.length > 0)
471
616
  metadata["tags"] = tags;
617
+ for (const [key, value] of Object.entries(extra))
618
+ metadata[key] = value;
472
619
  const document = new Document(metadata, { schema: "core" });
473
620
  const body = normalizedRequestedBody(input.body ?? `# ${title}
474
621
  `);
@@ -517,8 +664,9 @@ function existingDocumentId(parts) {
517
664
  return { kind: "invalid" };
518
665
  }
519
666
  }
520
- function assertCompatibleCreate(snapshot, input, requestedDocumentId) {
667
+ function assertCompatibleCreate(snapshot, input, requestedDocumentId, fields) {
521
668
  const parts = frontmatter(snapshot.content, snapshot.relativePath);
669
+ const requestedFields = validateFrontmatterFields(fields);
522
670
  const requestedType = validateType(input.type);
523
671
  const requestedTitle = validateTitle(input.title);
524
672
  if (topLevelScalar(parts, "type") !== requestedType) {
@@ -535,6 +683,11 @@ function assertCompatibleCreate(snapshot, input, requestedDocumentId) {
535
683
  if (input.body !== undefined && parts.bodySuffix !== `${parts.newline}${parts.newline}${normalizedRequestedBody(input.body)}`) {
536
684
  throw new NoteAlreadyExistsError(snapshot.relativePath, "body differs");
537
685
  }
686
+ for (const [key, value] of Object.entries(requestedFields)) {
687
+ if (!sameFrontmatterValue(topLevelValue(parts, key), value)) {
688
+ throw new NoteAlreadyExistsError(snapshot.relativePath, `${key} differs`);
689
+ }
690
+ }
538
691
  const existingId = existingDocumentId(parts);
539
692
  if (requestedDocumentId !== undefined && (existingId.kind !== "valid" || existingId.documentId !== requestedDocumentId)) {
540
693
  throw new NoteAlreadyExistsError(snapshot.relativePath, existingId.kind === "missing" ? "document_id is missing" : "document_id differs");
@@ -1125,10 +1278,11 @@ function installNote(platform, vault, id, content, expected, lock, dependencies)
1125
1278
  }));
1126
1279
  });
1127
1280
  }
1128
- function createNoteProgram(platform, root, input, options) {
1281
+ function createNoteProgram(platform, root, input, options, fields) {
1129
1282
  return Effect2.gen(function* () {
1130
1283
  const vault = yield* authoringNative(() => platform.resolveVault(root));
1131
1284
  const id = yield* authoringSync(() => canonicalNoteId(input.id));
1285
+ const extra = yield* authoringSync(() => validateFrontmatterFields(fields));
1132
1286
  const requestedDocumentId = yield* authoringSync(() => input.documentId === undefined ? undefined : parseDocumentId(input.documentId));
1133
1287
  const expected = yield* authoringSync(() => checkedExpectedRevision(options));
1134
1288
  const dependencies = yield* authoringSync(() => platform.dependenciesFor(options.dependencies));
@@ -1137,13 +1291,13 @@ function createNoteProgram(platform, root, input, options) {
1137
1291
  const existing = yield* authoringNative(() => platform.readOptionalSnapshot(vault, id));
1138
1292
  if (existing !== null) {
1139
1293
  yield* authoringSync(() => assertExpected(existing, expected));
1140
- const compatible = yield* authoringSync(() => assertCompatibleCreate(existing, input, requestedDocumentId));
1294
+ const compatible = yield* authoringSync(() => assertCompatibleCreate(existing, input, requestedDocumentId, extra));
1141
1295
  return yield* authoringSync(() => noteResult(existing, compatible.relations, false, compatible.documentId));
1142
1296
  }
1143
1297
  if (expected !== undefined)
1144
1298
  return yield* fail(new NoteRevisionConflictError(`${id}.md`, expected, null));
1145
1299
  const documentId = yield* authoringSync(() => requestedDocumentId ?? parseDocumentId(dependencies.documentId()));
1146
- const content = yield* authoringSync(() => renderCreatedNote(input, documentId));
1300
+ const content = yield* authoringSync(() => renderCreatedNote(input, documentId, extra));
1147
1301
  const revision = yield* installNote(platform, vault, id, content, null, lock, dependencies);
1148
1302
  return { changed: true, path: `${id}.md`, revision, relations: [], documentId };
1149
1303
  }), (lock) => authoringNative(() => lock.release()));
@@ -1177,9 +1331,10 @@ function editNoteRelationProgram(platform, operation, root, sourceIdInput, predi
1177
1331
  }), (lock) => authoringNative(() => lock.release()));
1178
1332
  });
1179
1333
  }
1180
- function updateNoteBodyProgram(platform, root, idInput, body, options) {
1334
+ function updateNoteBodyProgram(platform, root, idInput, body, options, fields) {
1181
1335
  return Effect2.gen(function* () {
1182
1336
  const id = yield* authoringSync(() => canonicalNoteId(idInput));
1337
+ const updates = yield* authoringSync(() => validateFrontmatterFieldUpdates(fields));
1183
1338
  const expected = yield* authoringSync(() => {
1184
1339
  if (typeof options?.expectedRevision !== "string") {
1185
1340
  throw new TypeError("expectedRevision is required for a note body update");
@@ -1198,7 +1353,7 @@ function updateNoteBodyProgram(platform, root, idInput, body, options) {
1198
1353
  return yield* fail(new TypeError("the note has an invalid document_id"));
1199
1354
  const documentId = identity.kind === "valid" ? identity.documentId : undefined;
1200
1355
  const relations = yield* authoringSync(() => relationsFromParts(parts, source.relativePath));
1201
- const content = yield* authoringSync(() => renderUpdatedNoteBody(source, parts, body));
1356
+ const content = yield* authoringSync(() => renderUpdatedNoteBodyAndFields(source, parts, body, updates));
1202
1357
  if (content === source.content)
1203
1358
  return yield* authoringSync(() => noteResult(source, relations, false, documentId));
1204
1359
  const revision = yield* installNote(platform, vault, id, content, source, lock, dependencies);
@@ -1237,4 +1392,4 @@ async function removeNoteRelation(root, sourceId, predicate, targetId, options =
1237
1392
  return runAuthoring(editNoteRelationProgram(nativeAuthoringPlatform, "remove", root, sourceId, predicate, targetId, options));
1238
1393
  }
1239
1394
 
1240
- export { InvalidCanonicalNoteIdError, NoteRevisionConflictError, NoteAlreadyExistsError, NoteRecoveryRequiredError, canonicalNoteId, canonicalRelationTarget, normalizeRelationPredicate, noteRevision, listNoteRelations, createNote, createConceptNote, updateNoteBody, addNoteRelation, removeNoteRelation };
1395
+ export { MAX_NOTE_BYTES, NOTE_REVISION_PATTERN, InvalidCanonicalNoteIdError, NoteRevisionConflictError, NoteAlreadyExistsError, NoteRecoveryRequiredError, isErrno, sha256, revisionFor, canonicalNoteId, canonicalRelationTarget, normalizeRelationPredicate, frontmatter, relationsFromParts, renderUpdatedNoteBodyAndFields, renderCreatedNote, resolveVault, assertExactDirectoryEntry, assertSafeParent, nativeAuthoringPlatform, runAuthoring, createNoteProgram, updateNoteBodyProgram, noteRevision, listNoteRelations, createNote, createConceptNote, updateNoteBody, addNoteRelation, removeNoteRelation };
@@ -5,7 +5,7 @@ import {
5
5
  isCanonicalNoteId,
6
6
  isCanonicalRelationPredicate,
7
7
  lookupNote
8
- } from "./index-zy7an84p.js";
8
+ } from "./index-jvb7w0gg.js";
9
9
 
10
10
  // src/percolate.ts
11
11
  import { createHash } from "crypto";
@@ -345,9 +345,12 @@ Capture options:
345
345
  --scope auto|page|thread|comments Content scope (default: platform-aware)
346
346
  --html <path|-> Parse saved/rendered HTML; - reads stdin
347
347
  --browser-profile <name|path> Use a signed-in or persistent Chrome profile
348
+ (downloads read its cookies from the keychain)
348
349
  --browser-live Attach to a live Chrome session
349
350
  --cdp <loopback-port> Attach to a local CDP-capable browser
350
351
  --cookie-source <browser> chrome|arc|brave|chromium|edge|firefox|safari
352
+ On a Mac, Chromium browsers ask for keychain
353
+ access; Safari needs Full Disk Access
351
354
  --cookie-profile <name|path> Browser profile; Safari expects a Cookies.binarycookies path
352
355
  --cookies-file <path> Cookie-Editor JSON/base64, Netscape, Cookie header, or cURL input
353
356
  --media none|images|all Localize images or all supported media
@@ -3,6 +3,101 @@ import {
3
3
  sanitizeTerminalText
4
4
  } from "./index-1xxnjn0d.js";
5
5
 
6
+ // src/cli-style.ts
7
+ var UNICODE_SYMBOLS = {
8
+ ok: "\u2713",
9
+ fail: "\u2717",
10
+ warn: "\u26A0",
11
+ next: "\u2192",
12
+ on: "\u25CF",
13
+ off: "\u25CB",
14
+ skip: "\u2013",
15
+ progress: "\u21BB",
16
+ notice: "\uD83D\uDD10"
17
+ };
18
+ var ASCII_SYMBOLS = {
19
+ ok: "OK",
20
+ fail: "FAIL",
21
+ warn: "WARN",
22
+ next: "->",
23
+ on: "*",
24
+ off: "o",
25
+ skip: "-",
26
+ progress: "...",
27
+ notice: "NOTE"
28
+ };
29
+ var SYMBOL_COLORS = {
30
+ ok: "32",
31
+ fail: "31",
32
+ warn: "33",
33
+ next: "2",
34
+ on: "32",
35
+ skip: "2"
36
+ };
37
+ function nonEmpty(value) {
38
+ return value !== undefined && value !== "";
39
+ }
40
+ function prefersAscii(env) {
41
+ if (env.TERM === "dumb" || env.HRANESS_ASCII === "1")
42
+ return true;
43
+ const locale = [env.LC_ALL, env.LC_CTYPE, env.LANG].find(nonEmpty);
44
+ return locale === undefined || !/utf-?8/iu.test(locale);
45
+ }
46
+ function prefersColor(env, isTTY) {
47
+ if (env.FORCE_COLOR === "1")
48
+ return true;
49
+ if (nonEmpty(env.NO_COLOR))
50
+ return false;
51
+ return isTTY && env.TERM !== "dumb";
52
+ }
53
+ function terminalStyle(env, isTTY) {
54
+ return { ascii: prefersAscii(env), color: prefersColor(env, isTTY) };
55
+ }
56
+ function symbol(name, style) {
57
+ const glyph = style.ascii ? ASCII_SYMBOLS[name] : UNICODE_SYMBOLS[name];
58
+ const color = SYMBOL_COLORS[name];
59
+ return style.color && color !== undefined ? `\x1B[${color}m${glyph}\x1B[0m` : glyph;
60
+ }
61
+ var AGENT_MARKERS = [
62
+ "AI_AGENT",
63
+ "CLAUDECODE",
64
+ "CODEX_SANDBOX",
65
+ "CODEX_SANDBOX_NETWORK_DISABLED",
66
+ "CURSOR_AGENT",
67
+ "GEMINI_CLI"
68
+ ];
69
+ function detectAudience(env, stderrIsTTY) {
70
+ const explicit = env.HRANESS_AUDIENCE;
71
+ if (explicit === "human" || explicit === "agent" || explicit === "quiet")
72
+ return explicit;
73
+ if (explicit === "off")
74
+ return "quiet";
75
+ if (AGENT_MARKERS.some((marker) => nonEmpty(env[marker])))
76
+ return "agent";
77
+ return stderrIsTTY ? "human" : "quiet";
78
+ }
79
+ function renderFailure(text, next, style) {
80
+ return `${symbol("fail", style)} ${text}
81
+ ${symbol("next", style)} ${next}
82
+ `;
83
+ }
84
+ function sentence(message) {
85
+ const trimmed = message.trim();
86
+ const capitalized = /^[a-z]/u.test(trimmed) ? `${trimmed[0]?.toUpperCase() ?? ""}${trimmed.slice(1)}` : trimmed;
87
+ return /[.!?]$/u.test(capitalized) ? capitalized : `${capitalized}.`;
88
+ }
89
+ var terminalOutputs = new WeakSet;
90
+ function terminalOutput(output) {
91
+ terminalOutputs.add(output);
92
+ return output;
93
+ }
94
+ function stderrStyle(env, output) {
95
+ return terminalStyle(env, terminalOutputs.has(output) && process.stderr.isTTY === true);
96
+ }
97
+ function writesToTerminal(output) {
98
+ return terminalOutputs.has(output) && process.stderr.isTTY === true;
99
+ }
100
+
6
101
  // src/clip/lib.ts
7
102
  var articleMetadataLimits = {
8
103
  title: 2048,
@@ -2043,4 +2138,4 @@ function renderCapturedDocument(document) {
2043
2138
  return rewriteContent(markdown, new URL(document.sourceUrl), new Map, { remoteImages: "embed" });
2044
2139
  }
2045
2140
 
2046
- export { articleMetadataLimits, slugify, yamlString, resolveRemote, scanImageSources, CONTENT_REWRITE_TRUNCATION_WARNING, rewriteContentWithStatus, buildClipMarkdown, classifyPlatformUrl, parseHackerNewsCapture, parseRedditCapture, parseBlueskyCapture, renderCapturedDocument };
2141
+ export { terminalStyle, symbol, detectAudience, renderFailure, sentence, terminalOutput, stderrStyle, writesToTerminal, articleMetadataLimits, slugify, yamlString, resolveRemote, scanImageSources, CONTENT_REWRITE_TRUNCATION_WARNING, rewriteContentWithStatus, buildClipMarkdown, classifyPlatformUrl, parseHackerNewsCapture, parseRedditCapture, parseBlueskyCapture, renderCapturedDocument };
@@ -5,7 +5,7 @@ import {
5
5
  MAX_SEARCH_RESULTS,
6
6
  openKnowledgeBase,
7
7
  validateKnowledgeBaseSearchHistory
8
- } from "./index-42tb8qqp.js";
8
+ } from "./index-5d1rd5v9.js";
9
9
  import {
10
10
  expandSearchRequest,
11
11
  parseSearchRules
@@ -15,10 +15,10 @@ import {
15
15
  } from "./index-1gwbassd.js";
16
16
  import {
17
17
  validateSearchQuery
18
- } from "./index-aer0jdrq.js";
18
+ } from "./index-ahyhryb8.js";
19
19
  import {
20
20
  scanVault
21
- } from "./index-8v6k9h4r.js";
21
+ } from "./index-1s8mc4hz.js";
22
22
  import {
23
23
  validateQueryOptions
24
24
  } from "./index-48pz4jpc.js";
@@ -32,7 +32,7 @@ import {
32
32
  parseVaultKey,
33
33
  portfolioDocumentIdentity,
34
34
  portfolioVaultIdentity
35
- } from "./index-zy7an84p.js";
35
+ } from "./index-jvb7w0gg.js";
36
36
 
37
37
  // src/portfolio.ts
38
38
  import { createHash as createHash2 } from "crypto";
@@ -2,14 +2,14 @@
2
2
  import {
3
3
  fuseRankedCandidates,
4
4
  validateSearchQuery
5
- } from "./index-aer0jdrq.js";
5
+ } from "./index-ahyhryb8.js";
6
6
  import {
7
7
  MAX_NOTE_UTF8_BYTES,
8
8
  MAX_SCANNED_NOTES,
9
9
  MAX_VAULT_UTF8_BYTES,
10
10
  VaultScanBudgetError,
11
11
  scanVault
12
- } from "./index-8v6k9h4r.js";
12
+ } from "./index-1s8mc4hz.js";
13
13
 
14
14
  // src/semantic.ts
15
15
  import { createHash as createHash2 } from "crypto";
@@ -303,12 +303,15 @@ class VaultAnalysisBudgetError extends RangeError {
303
303
  function isMetadataObject(value) {
304
304
  return value !== null && typeof value === "object" && !Array.isArray(value);
305
305
  }
306
+ function isMetadataNumber(value) {
307
+ return Number.isFinite(value) && (!Number.isInteger(value) || Number.isSafeInteger(value));
308
+ }
306
309
  function parsedMetadataValue(value, ancestors) {
307
310
  if (value === null || typeof value === "string" || typeof value === "boolean") {
308
311
  return { ok: true, value };
309
312
  }
310
313
  if (typeof value === "number") {
311
- return Number.isFinite(value) && (!Number.isInteger(value) || Number.isSafeInteger(value)) ? { ok: true, value } : { ok: false };
314
+ return isMetadataNumber(value) ? { ok: true, value } : { ok: false };
312
315
  }
313
316
  if (typeof value !== "object" || ancestors.has(value))
314
317
  return { ok: false };
@@ -1281,4 +1284,4 @@ function replaceCatalog(indexContent, catalog) {
1281
1284
  return indexContent.slice(0, start) + catalog + indexContent.slice(end + catalogEnd.length);
1282
1285
  }
1283
1286
 
1284
- export { MAX_PORTFOLIO_NAME_BYTES, MAX_DOCUMENT_ID_BYTES, portfolioVaultIdentity, parseVaultKey, parseDocumentId, documentIdState, formatQualifiedDocumentUri, parseQualifiedDocumentUri, portfolioDocumentIdentity, catalogStart, catalogEnd, MAX_ANALYZED_NOTES, MAX_CONNECTION_OBSERVATIONS, MAX_MENTION_PAIRS, MAX_MENTIONS, VaultAnalysisBudgetError, metadataValueFromUnknown, isCanonicalRelationPredicate, isCanonicalNoteId, normalizeVaultPath, searchableMarkdown, wikiLinks, parseNote, lookupNote, analyzeVault, analyzeVaultComplete, renderCatalog, replaceCatalog };
1287
+ export { MAX_PORTFOLIO_NAME_BYTES, MAX_DOCUMENT_ID_BYTES, portfolioVaultIdentity, parseVaultKey, parseDocumentId, documentIdState, formatQualifiedDocumentUri, parseQualifiedDocumentUri, portfolioDocumentIdentity, catalogStart, catalogEnd, MAX_ANALYZED_NOTES, MAX_CONNECTION_OBSERVATIONS, MAX_MENTION_PAIRS, MAX_MENTIONS, VaultAnalysisBudgetError, isMetadataNumber, metadataValueFromUnknown, isCanonicalRelationPredicate, isCanonicalNoteId, normalizeVaultPath, searchableMarkdown, wikiLinks, parseNote, lookupNote, analyzeVault, analyzeVaultComplete, renderCatalog, replaceCatalog };
@@ -6,7 +6,7 @@ import {
6
6
  resolveRemote,
7
7
  rewriteContentWithStatus,
8
8
  scanImageSources
9
- } from "./index-hgve9rh2.js";
9
+ } from "./index-cd75vky9.js";
10
10
  import {
11
11
  FetchFailure,
12
12
  safeFetch
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  MAX_SEARCH_RESULTS,
4
4
  openKnowledgeBase
5
- } from "./index-42tb8qqp.js";
5
+ } from "./index-5d1rd5v9.js";
6
6
  import {
7
7
  MAX_EVALUATION_EVIDENCE_BYTES,
8
8
  redactEvaluationMachinePaths
@@ -12,7 +12,7 @@ import {
12
12
  } from "./index-1gwbassd.js";
13
13
  import {
14
14
  scanVault
15
- } from "./index-8v6k9h4r.js";
15
+ } from "./index-1s8mc4hz.js";
16
16
  import {
17
17
  MAX_REPOSITORY_MEMORY_DETAIL_LIMIT,
18
18
  MAX_REPOSITORY_MEMORY_GROUP_LIMIT,
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  fuseRankedCandidates
4
- } from "./index-aer0jdrq.js";
4
+ } from "./index-ahyhryb8.js";
5
5
 
6
6
  // src/benchmark.ts
7
7
  var MAX_BENCHMARK_CASES = 500;
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  isolatedAgentBrowserEnvironment
4
- } from "./index-g5vsqmdy.js";
4
+ } from "./index-xwxy71ew.js";
5
5
  import {
6
6
  BoundedByteBuffer
7
7
  } from "./index-gh719d91.js";
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  isCanonicalNoteId,
7
7
  isCanonicalRelationPredicate
8
- } from "./index-zy7an84p.js";
8
+ } from "./index-jvb7w0gg.js";
9
9
 
10
10
  // src/graph-authority-model.ts
11
11
  var GRAPH_LIMITS = Object.freeze({
@@ -2,11 +2,15 @@
2
2
  import {
3
3
  countWords,
4
4
  sniffImage
5
- } from "./index-f984hw45.js";
5
+ } from "./index-k86wepd8.js";
6
6
  import {
7
+ renderFailure,
8
+ sentence,
7
9
  slugify,
10
+ stderrStyle,
11
+ terminalOutput,
8
12
  yamlString
9
- } from "./index-hgve9rh2.js";
13
+ } from "./index-cd75vky9.js";
10
14
  import {
11
15
  safeFetch
12
16
  } from "./index-e5fbsywq.js";
@@ -1858,10 +1862,10 @@ async function preparePdfSource(input, options = {}, dependencies = {}) {
1858
1862
  }
1859
1863
 
1860
1864
  // src/pdf/cli.ts
1861
- var defaultOutput = {
1865
+ var defaultOutput = terminalOutput({
1862
1866
  stdout: (value) => process.stdout.write(value),
1863
1867
  stderr: (value) => process.stderr.write(value)
1864
- };
1868
+ });
1865
1869
  function safe(value) {
1866
1870
  return sanitizeTerminalLine(redactSensitiveText(value));
1867
1871
  }
@@ -1905,9 +1909,7 @@ function pdfCaptureSummary(outcome) {
1905
1909
  async function main(rawArguments = process.argv.slice(2), environment = process.env, output = defaultOutput, dependencies = {}) {
1906
1910
  const parsed = parsePdfArguments(rawArguments, environment);
1907
1911
  if (!parsed.ok) {
1908
- output.stderr(`error: ${safe(parsed.message)}
1909
-
1910
- ${sanitizeTerminalText(pdfUsage)}`);
1912
+ output.stderr(renderFailure(sentence(safe(parsed.message)), "wordcell pdf --help", stderrStyle(environment, output)));
1911
1913
  return 2;
1912
1914
  }
1913
1915
  const arguments_ = parsed.value;
@@ -1961,8 +1963,7 @@ ${sanitizeTerminalText(pdfUsage)}`);
1961
1963
  if (arguments_.json)
1962
1964
  output.stdout(terminalSafeJson({ ok: false, error: message }));
1963
1965
  else
1964
- output.stderr(`error: ${message}
1965
- `);
1966
+ output.stderr(renderFailure(message, "wordcell doctor", stderrStyle(environment, output)));
1966
1967
  return 1;
1967
1968
  } finally {
1968
1969
  preparedSource?.dispose();
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  scanVault
4
- } from "./index-8v6k9h4r.js";
4
+ } from "./index-1s8mc4hz.js";
5
5
  import {
6
6
  navigateLinks
7
7
  } from "./index-d13v9ckt.js";
@@ -39,7 +39,7 @@ import {
39
39
  import {
40
40
  lookupNote,
41
41
  normalizeVaultPath
42
- } from "./index-zy7an84p.js";
42
+ } from "./index-jvb7w0gg.js";
43
43
 
44
44
  // src/publish.ts
45
45
  import { createHash } from "crypto";
@@ -1,20 +1,20 @@
1
1
  // @bun
2
2
  import {
3
3
  percolateVault
4
- } from "./index-qdb8f8va.js";
4
+ } from "./index-bdwcjvr4.js";
5
5
  import {
6
6
  createGraphSnapshot,
7
7
  openGraphAuthority
8
- } from "./index-f75zmmdr.js";
8
+ } from "./index-1er88ckw.js";
9
9
  import {
10
10
  GraphAuthorityError,
11
11
  validateGraphPercolationOptions
12
- } from "./index-pz2b2x0y.js";
12
+ } from "./index-pgtm2nhf.js";
13
13
  import {
14
14
  analyzeVault,
15
15
  lookupNote,
16
16
  parseNote
17
- } from "./index-zy7an84p.js";
17
+ } from "./index-jvb7w0gg.js";
18
18
 
19
19
  // src/graph-percolation.ts
20
20
  async function percolateWithGraph(snapshot, options) {