@linxiraos/pi-utils 1.1.9 → 1.1.11

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 (167) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/THIRD-PARTY-NOTICES.txt +22909 -0
  3. package/dist/types/abortable.d.ts +32 -0
  4. package/dist/types/acp/connection.d.ts +118 -0
  5. package/dist/types/acp/protocol.d.ts +526 -0
  6. package/dist/types/acp/schema.d.ts +41 -0
  7. package/dist/types/acp/stream.d.ts +8 -0
  8. package/dist/types/acp/transport.d.ts +88 -0
  9. package/dist/types/acp.d.ts +6 -0
  10. package/dist/types/ar/arj.d.ts +5 -0
  11. package/dist/types/ar/asar.d.ts +7 -0
  12. package/dist/types/ar/bytes.d.ts +20 -0
  13. package/dist/types/ar/cab.d.ts +5 -0
  14. package/dist/types/ar/checksums.d.ts +10 -0
  15. package/dist/types/ar/codecs/bzip2.d.ts +4 -0
  16. package/dist/types/ar/codecs/gzip.d.ts +6 -0
  17. package/dist/types/ar/codecs/lzma.d.ts +6 -0
  18. package/dist/types/ar/codecs/lzw.d.ts +4 -0
  19. package/dist/types/ar/codecs/lzx.d.ts +7 -0
  20. package/dist/types/ar/codecs/xz.d.ts +4 -0
  21. package/dist/types/ar/codecs/zstd.d.ts +6 -0
  22. package/dist/types/ar/cpio.d.ts +7 -0
  23. package/dist/types/ar/deb.d.ts +5 -0
  24. package/dist/types/ar/entries.d.ts +22 -0
  25. package/dist/types/ar/error.d.ts +8 -0
  26. package/dist/types/ar/index.d.ts +11 -0
  27. package/dist/types/ar/iso.d.ts +5 -0
  28. package/dist/types/ar/limits.d.ts +33 -0
  29. package/dist/types/ar/lzh.d.ts +7 -0
  30. package/dist/types/ar/open.d.ts +45 -0
  31. package/dist/types/ar/paths.d.ts +18 -0
  32. package/dist/types/ar/rar/rar4-decoder.d.ts +6 -0
  33. package/dist/types/ar/rar/rar5-decoder.d.ts +6 -0
  34. package/dist/types/ar/rar.d.ts +5 -0
  35. package/dist/types/ar/reader.d.ts +28 -0
  36. package/dist/types/ar/registry.d.ts +17 -0
  37. package/dist/types/ar/rpm.d.ts +5 -0
  38. package/dist/types/ar/sevenzip/decode.d.ts +33 -0
  39. package/dist/types/ar/sevenzip.d.ts +5 -0
  40. package/dist/types/ar/source.d.ts +54 -0
  41. package/dist/types/ar/tar.d.ts +9 -0
  42. package/dist/types/ar/types.d.ts +99 -0
  43. package/dist/types/ar/unix-ar.d.ts +7 -0
  44. package/dist/types/ar/write.d.ts +10 -0
  45. package/dist/types/ar/zip.d.ts +10 -0
  46. package/dist/types/async.d.ts +32 -0
  47. package/dist/types/binary.d.ts +23 -0
  48. package/dist/types/browsers.d.ts +68 -0
  49. package/dist/types/chalk.d.ts +125 -0
  50. package/dist/types/cli.d.ts +134 -0
  51. package/dist/types/color.d.ts +136 -0
  52. package/dist/types/dates.d.ts +7 -0
  53. package/dist/types/dirs.d.ts +323 -0
  54. package/dist/types/docx/converter.d.ts +46 -0
  55. package/dist/types/docx/xml.d.ts +26 -0
  56. package/dist/types/docx.d.ts +11 -0
  57. package/dist/types/dom/core.d.ts +431 -0
  58. package/dist/types/dom/parser.d.ts +7 -0
  59. package/dist/types/dom/selector.d.ts +5 -0
  60. package/dist/types/dom.d.ts +5 -0
  61. package/dist/types/env.d.ts +132 -0
  62. package/dist/types/fetch-retry.d.ts +98 -0
  63. package/dist/types/file-lock.d.ts +23 -0
  64. package/dist/types/format.d.ts +37 -0
  65. package/dist/types/frontmatter.d.ts +46 -0
  66. package/dist/types/fs-error.d.ts +31 -0
  67. package/dist/types/glob.d.ts +28 -0
  68. package/dist/types/headers.d.ts +34 -0
  69. package/dist/types/incoming-json.d.ts +232 -0
  70. package/dist/types/index.d.ts +43 -0
  71. package/dist/types/json-lexer.d.ts +116 -0
  72. package/dist/types/json-parse.d.ts +83 -0
  73. package/dist/types/json.d.ts +20 -0
  74. package/dist/types/logger/rotating-file.d.ts +18 -0
  75. package/dist/types/logger.d.ts +96 -0
  76. package/dist/types/loop-phase.d.ts +10 -0
  77. package/dist/types/lru.d.ts +46 -0
  78. package/dist/types/marked/core.d.ts +445 -0
  79. package/dist/types/marked.d.ts +2 -0
  80. package/dist/types/materialize-string.d.ts +7 -0
  81. package/dist/types/math-delimiters.d.ts +45 -0
  82. package/dist/types/mermaid-ascii.d.ts +11 -0
  83. package/dist/types/mime.d.ts +29 -0
  84. package/dist/types/module-timer.d.ts +1 -0
  85. package/dist/types/path-tree.d.ts +76 -0
  86. package/dist/types/path.d.ts +4 -0
  87. package/dist/types/peek-file.d.ts +29 -0
  88. package/dist/types/postmortem.d.ts +178 -0
  89. package/dist/types/process-name.d.ts +7 -0
  90. package/dist/types/procmgr.d.ts +76 -0
  91. package/dist/types/prompt.d.ts +18 -0
  92. package/dist/types/ptree.d.ts +124 -0
  93. package/dist/types/readability/readability.d.ts +9 -0
  94. package/dist/types/readability/readerable.d.ts +10 -0
  95. package/dist/types/readability/types.d.ts +70 -0
  96. package/dist/types/readability.d.ts +4 -0
  97. package/dist/types/ring.d.ts +93 -0
  98. package/dist/types/runtime-install.d.ts +85 -0
  99. package/dist/types/sanitize-text.d.ts +29 -0
  100. package/dist/types/snowflake.d.ts +25 -0
  101. package/dist/types/sqlite.d.ts +26 -0
  102. package/dist/types/stderr-guard.d.ts +22 -0
  103. package/dist/types/stream.d.ts +75 -0
  104. package/dist/types/tab-spacing.d.ts +24 -0
  105. package/dist/types/temp.d.ts +24 -0
  106. package/dist/types/template.d.ts +62 -0
  107. package/dist/types/timing-buffer.d.ts +22 -0
  108. package/dist/types/tls-fetch.d.ts +50 -0
  109. package/dist/types/turndown/gfm.d.ts +11 -0
  110. package/dist/types/turndown/html.d.ts +5 -0
  111. package/dist/types/turndown/service.d.ts +21 -0
  112. package/dist/types/turndown/types.d.ts +70 -0
  113. package/dist/types/turndown.d.ts +4 -0
  114. package/dist/types/type-guards.d.ts +5 -0
  115. package/dist/types/vendor/mermaid-ascii/ascii/ansi.d.ts +41 -0
  116. package/dist/types/vendor/mermaid-ascii/ascii/canvas.d.ts +89 -0
  117. package/dist/types/vendor/mermaid-ascii/ascii/class-diagram.d.ts +7 -0
  118. package/dist/types/vendor/mermaid-ascii/ascii/converter.d.ts +12 -0
  119. package/dist/types/vendor/mermaid-ascii/ascii/draw.d.ts +66 -0
  120. package/dist/types/vendor/mermaid-ascii/ascii/edge-bundling.d.ts +48 -0
  121. package/dist/types/vendor/mermaid-ascii/ascii/edge-routing.d.ts +43 -0
  122. package/dist/types/vendor/mermaid-ascii/ascii/er-diagram.d.ts +7 -0
  123. package/dist/types/vendor/mermaid-ascii/ascii/grid.d.ts +56 -0
  124. package/dist/types/vendor/mermaid-ascii/ascii/index.d.ts +65 -0
  125. package/dist/types/vendor/mermaid-ascii/ascii/multiline-utils.d.ts +27 -0
  126. package/dist/types/vendor/mermaid-ascii/ascii/pathfinder.d.ts +17 -0
  127. package/dist/types/vendor/mermaid-ascii/ascii/sequence.d.ts +7 -0
  128. package/dist/types/vendor/mermaid-ascii/ascii/shapes/circle.d.ts +11 -0
  129. package/dist/types/vendor/mermaid-ascii/ascii/shapes/corners.d.ts +34 -0
  130. package/dist/types/vendor/mermaid-ascii/ascii/shapes/diamond.d.ts +11 -0
  131. package/dist/types/vendor/mermaid-ascii/ascii/shapes/hexagon.d.ts +11 -0
  132. package/dist/types/vendor/mermaid-ascii/ascii/shapes/index.d.ts +26 -0
  133. package/dist/types/vendor/mermaid-ascii/ascii/shapes/rectangle.d.ts +31 -0
  134. package/dist/types/vendor/mermaid-ascii/ascii/shapes/rounded.d.ts +11 -0
  135. package/dist/types/vendor/mermaid-ascii/ascii/shapes/special.d.ts +59 -0
  136. package/dist/types/vendor/mermaid-ascii/ascii/shapes/stadium.d.ts +17 -0
  137. package/dist/types/vendor/mermaid-ascii/ascii/shapes/state.d.ts +30 -0
  138. package/dist/types/vendor/mermaid-ascii/ascii/shapes/types.d.ts +55 -0
  139. package/dist/types/vendor/mermaid-ascii/ascii/types.d.ts +206 -0
  140. package/dist/types/vendor/mermaid-ascii/ascii/validate.d.ts +51 -0
  141. package/dist/types/vendor/mermaid-ascii/ascii/xychart.d.ts +2 -0
  142. package/dist/types/vendor/mermaid-ascii/class/parser.d.ts +6 -0
  143. package/dist/types/vendor/mermaid-ascii/class/types.d.ts +102 -0
  144. package/dist/types/vendor/mermaid-ascii/er/parser.d.ts +6 -0
  145. package/dist/types/vendor/mermaid-ascii/er/types.d.ts +76 -0
  146. package/dist/types/vendor/mermaid-ascii/index.d.ts +1 -0
  147. package/dist/types/vendor/mermaid-ascii/multiline-utils.d.ts +9 -0
  148. package/dist/types/vendor/mermaid-ascii/parser.d.ts +7 -0
  149. package/dist/types/vendor/mermaid-ascii/sequence/parser.d.ts +6 -0
  150. package/dist/types/vendor/mermaid-ascii/sequence/types.d.ts +130 -0
  151. package/dist/types/vendor/mermaid-ascii/text-metrics.d.ts +23 -0
  152. package/dist/types/vendor/mermaid-ascii/types.d.ts +114 -0
  153. package/dist/types/vendor/mermaid-ascii/xychart/colors.d.ts +25 -0
  154. package/dist/types/vendor/mermaid-ascii/xychart/parser.d.ts +6 -0
  155. package/dist/types/vendor/mermaid-ascii/xychart/types.d.ts +145 -0
  156. package/dist/types/version.d.ts +18 -0
  157. package/dist/types/vterm/buffer.d.ts +99 -0
  158. package/dist/types/vterm/query-responder.d.ts +24 -0
  159. package/dist/types/vterm/terminal.d.ts +44 -0
  160. package/dist/types/vterm.d.ts +9 -0
  161. package/dist/types/which.d.ts +37 -0
  162. package/dist/types/worker-host.d.ts +51 -0
  163. package/dist/types/xml.d.ts +31 -0
  164. package/package.json +60 -57
  165. package/src/dirs.ts +40 -60
  166. package/src/env.ts +7 -14
  167. package/src/procmgr.ts +7 -0
@@ -0,0 +1,23 @@
1
+ import { FileLock as NativeFileLock } from "@linxiraos/pi-natives";
2
+ /** Controls bounded waiting when an advisory file lock is contended. */
3
+ export interface FileLockOptions {
4
+ /** Maximum acquisition attempts, including the initial attempt. */
5
+ retries?: number;
6
+ /** Delay between acquisition attempts. */
7
+ retryDelayMs?: number;
8
+ /** Maximum age of the lock before it is considered stale and can be broken. */
9
+ staleMs?: number;
10
+ }
11
+ declare function getLockPath(filePath: string): string;
12
+ declare function tryAcquireLock(lockPath: string): NativeFileLock | null;
13
+ /** Run `fn` while holding an OS-backed exclusive lock for `filePath`. */
14
+ export declare function withFileLock<T>(filePath: string, fn: () => Promise<T>, options?: FileLockOptions): Promise<T>;
15
+ /**
16
+ * Test-only acquisition handle for forcing ownership handoffs. This is not
17
+ * part of the supported package API.
18
+ */
19
+ export declare const __internalsForTesting: {
20
+ tryAcquireLock: typeof tryAcquireLock;
21
+ getLockPath: typeof getLockPath;
22
+ };
23
+ export {};
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Format a duration in milliseconds to a short human-readable string.
3
+ * Examples: "123ms", "1.5s", "30m15s", "2h30m", "3d2h"
4
+ */
5
+ export declare function formatDuration(ms: number): string;
6
+ /**
7
+ * Format a number with K/M/B suffix for compact display.
8
+ * Uses 1 decimal for small leading digits when non-zero, rounded otherwise.
9
+ * Examples: "999", "1K", "1.5K", "25K", "1M", "1.5M", "25M", "1.5B"
10
+ */
11
+ export declare function formatNumber(n: number): string;
12
+ /**
13
+ * Format a byte count to a human-readable string.
14
+ * Examples: "512B", "1.5KB", "2.3MB", "1.2GB"
15
+ */
16
+ export declare function formatBytes(bytes: number): string;
17
+ /**
18
+ * Truncate a string to maxLen characters, appending an ellipsis if truncated.
19
+ * For display-width-aware truncation (terminals), use truncateToWidth from @linxiraos/pi-tui.
20
+ */
21
+ export declare function truncate(str: string, maxLen: number, ellipsis?: string): string;
22
+ /**
23
+ * Format count with pluralized label (e.g., "3 files", "1 error").
24
+ */
25
+ export declare function formatCount(label: string, count: number): string;
26
+ /**
27
+ * Format age from seconds to human-readable string.
28
+ */
29
+ export declare function formatAge(ageSeconds: number | null | undefined): string;
30
+ /**
31
+ * Pluralize a label based on the count.
32
+ */
33
+ export declare function pluralize(label: string, count: number): string;
34
+ /**
35
+ * Format a ratio as a percentage.
36
+ */
37
+ export declare function formatPercent(ratio: number): string;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Recursively normalize object keys from kebab-case to camelCase — the
3
+ * representation convention for frontmatter consumed inside this codebase.
4
+ * Exported for loaders that parse with `rawKeys: true` to validate exact
5
+ * spec-defined keys, then normalize for storage.
6
+ */
7
+ export declare function normalizeFrontmatterKeys<T>(obj: T): T;
8
+ export declare class FrontmatterError extends Error {
9
+ readonly source?: unknown;
10
+ constructor(error: Error, source?: unknown);
11
+ toString(): string;
12
+ }
13
+ export interface FrontmatterOptions {
14
+ /** Source of the content (alias: source) */
15
+ location?: unknown;
16
+ /** Source of the content (alias for location) */
17
+ source?: unknown;
18
+ /** Fallback frontmatter values */
19
+ fallback?: Record<string, unknown>;
20
+ /** Normalize the content */
21
+ normalize?: boolean;
22
+ /** Level of error handling */
23
+ level?: "off" | "warn" | "fatal";
24
+ /**
25
+ * Attempt lenient recovery of near-miss input before failing: quote
26
+ * ambiguous plain scalars, replace tabs with spaces, and strip leading HTML
27
+ * comments ahead of the opening delimiter. Default `true`. Spec-conformant
28
+ * loaders set `false` so malformed input is rejected instead of silently
29
+ * repaired (CRLF newline normalization still applies).
30
+ */
31
+ repair?: boolean;
32
+ /**
33
+ * Preserve frontmatter keys verbatim instead of normalizing kebab-case to
34
+ * camelCase. Default `false`. Strict spec loaders use this so a standard
35
+ * key (e.g. `allowed-tools`) is never aliased with its camelCase form.
36
+ */
37
+ rawKeys?: boolean;
38
+ }
39
+ /**
40
+ * Parse YAML frontmatter from markdown content
41
+ * Returns { frontmatter, body } where body has frontmatter stripped
42
+ */
43
+ export declare function parseFrontmatter(content: string, options?: FrontmatterOptions): {
44
+ frontmatter: Record<string, unknown>;
45
+ body: string;
46
+ };
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Type-safe filesystem error handling utilities.
3
+ *
4
+ * Use these to check error codes without string matching on messages:
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * import { isEnoent, isFsError } from "@linxiraos/pi-utils";
9
+ *
10
+ * try {
11
+ * return await Bun.file(path).text();
12
+ * } catch (err) {
13
+ * if (isEnoent(err)) return null;
14
+ * throw err;
15
+ * }
16
+ * ```
17
+ */
18
+ export interface FsError extends Error {
19
+ code: string;
20
+ errno?: number;
21
+ syscall?: string;
22
+ path?: string;
23
+ }
24
+ export declare function isFsError(err: unknown): err is FsError;
25
+ export declare function isEnoent(err: unknown): err is FsError;
26
+ export declare function isEacces(err: unknown): err is FsError;
27
+ export declare function isEisdir(err: unknown): err is FsError;
28
+ export declare function isEnotdir(err: unknown): err is FsError;
29
+ export declare function isEexist(err: unknown): err is FsError;
30
+ export declare function isEnotempty(err: unknown): err is FsError;
31
+ export declare function hasFsCode(err: unknown, code: string): err is FsError;
@@ -0,0 +1,28 @@
1
+ export interface GlobPathsOptions {
2
+ /** Base directory for glob patterns. Defaults to getProjectDir(). */
3
+ cwd?: string;
4
+ /** Glob exclusion patterns. */
5
+ exclude?: string[];
6
+ /** Abort signal to cancel the glob. */
7
+ signal?: AbortSignal;
8
+ /** Timeout in milliseconds for the glob operation. */
9
+ timeoutMs?: number;
10
+ /** Include dotfiles when true. */
11
+ dot?: boolean;
12
+ /** Only return files (skip directories). Default: true. */
13
+ onlyFiles?: boolean;
14
+ /** Respect .gitignore files when true. Walks up directory tree to find all applicable .gitignore files. */
15
+ gitignore?: boolean;
16
+ }
17
+ /**
18
+ * Load .gitignore patterns from a directory and its parents.
19
+ * Walks up the directory tree to find all applicable .gitignore files.
20
+ * Returns glob-compatible exclude patterns.
21
+ */
22
+ export declare function loadGitignorePatterns(baseDir: string): Promise<string[]>;
23
+ /**
24
+ * Resolve filesystem paths matching glob patterns with optional exclude filters.
25
+ * Returns paths relative to the provided cwd (or getProjectDir()).
26
+ * Errors and abort/timeouts are surfaced to the caller.
27
+ */
28
+ export declare function globPaths(patterns: string | string[], options?: GlobPathsOptions): Promise<string[]>;
@@ -0,0 +1,34 @@
1
+ /** Behavior-compatible reimplementation of header-generator's used surface. */
2
+ /** A browser family supported by the curated header profiles. */
3
+ export type BrowserName = "chrome" | "firefox" | "safari";
4
+ /** A desktop operating system supported by the curated header profiles. */
5
+ export type OperatingSystem = "windows" | "macos" | "linux";
6
+ /** Constructor and per-call constraints for header generation. */
7
+ export interface HeaderGeneratorOptions {
8
+ /** Browser families eligible for a draw. */
9
+ browsers: BrowserName[];
10
+ /** Browser selection query; the supported `last 3 versions` query uses the curated versions. */
11
+ browserListQuery: string;
12
+ /** Desktop operating systems eligible for a draw. */
13
+ operatingSystems: OperatingSystem[];
14
+ /** Device classes eligible for a draw. */
15
+ devices: "desktop"[];
16
+ /** Ordered locales for the Accept-Language value. */
17
+ locales: string[];
18
+ /** HTTP protocol generation mode. */
19
+ httpVersion: "1" | "2";
20
+ /** Whether impossible constraints throw instead of relaxing to a coherent profile. */
21
+ strict: boolean;
22
+ /** Random source returning a value in the range from zero (inclusive) to one (exclusive). */
23
+ rng: () => number;
24
+ }
25
+ /** A generated HTTP request header map. */
26
+ export type Headers = Record<string, string>;
27
+ /** Generates coherent modern desktop browser navigation headers. */
28
+ export declare class HeaderGenerator {
29
+ #private;
30
+ /** Creates a generator with reusable constraints and an optionally injectable RNG. */
31
+ constructor(options?: Partial<HeaderGeneratorOptions>);
32
+ /** Generates one header set, applying per-call constraints and request overrides. */
33
+ getHeaders(options?: Partial<HeaderGeneratorOptions>, overrides?: Headers): Headers;
34
+ }
@@ -0,0 +1,232 @@
1
+ /**
2
+ * Typed cursors over a JSON document while its text is still arriving.
3
+ *
4
+ * {@link IncomingDoc.channel} returns a push-side {@link IncomingFeed} and a
5
+ * read-side {@link IncomingDoc}. The producer appends text fragments, then
6
+ * explicitly calls {@link IncomingFeed.finish} or {@link IncomingFeed.abort};
7
+ * a feed that is never closed leaves every pending pull waiting forever.
8
+ * There is one shared append-only buffer; cursors are cheap, immutable
9
+ * path handles over it, and every pull is an ordinary promise that
10
+ * re-scans the buffer whenever the feed changes. There are no snapshots,
11
+ * per-field events, or fan-out channels.
12
+ *
13
+ * A scalar completes at its closing quote/delimiter, and a container
14
+ * completes only when its closing delimiter arrives. Finished-but-truncated
15
+ * input rejects with kind `incomplete`; abandoned input rejects with
16
+ * `aborted`. String chunks contain only decoded text whose meaning is
17
+ * stable, so an escape or Unicode escape may span any number of fragments.
18
+ *
19
+ * Pulling an {@link IncomingObject.key} makes that key required: a missing
20
+ * or mistyped value is a structured {@link IncomingJsonError}. Object members
21
+ * never pulled are skipped without validation. {@link IncomingDoc.whole} is
22
+ * the explicit whole-document pull and runs only after successful input
23
+ * completion.
24
+ *
25
+ * Object cursors bind the first occurrence of a duplicate key, whereas
26
+ * complete-value pulls (`value()`, `collect()`, `whole()`) go through the
27
+ * final parser (`parseJsonWithRepair`), whose objects are last-write-wins.
28
+ *
29
+ * Mid-stream cursors tolerate incomplete tokens but read double-quoted
30
+ * strings with the final parser's strict closing rule: an unescaped inner
31
+ * `"` can never swallow a sibling key or value. A pulled scalar completes
32
+ * only once a value terminator follows it, like numbers, so structural
33
+ * garbage after a value surfaces as `incomplete` rather than a silently
34
+ * misparsed pull. Single-quote recovery (`'it's'`) is shared with the final
35
+ * parser and passes both.
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * const { feed, doc } = IncomingDoc.channel();
40
+ * const args = doc.root().object();
41
+ * const content = args.key("content").string();
42
+ * feed.push('{"path":"a.ts","content":"hel');
43
+ * await content.nextChunk(); // "hel"
44
+ * feed.push('lo"}');
45
+ * feed.finish();
46
+ * await content.nextChunk(); // "lo"
47
+ * await content.nextChunk(); // undefined
48
+ * await args.key("path").value<string>(); // "a.ts"
49
+ * ```
50
+ */
51
+ /** Location component in a pulled JSON path: an object member name or an array index. */
52
+ export type PullPathSegment = string | number;
53
+ /** JSON shape observed by a started pull. */
54
+ export type IncomingValueKind = "null" | "boolean" | "number" | "string" | "array" | "object";
55
+ /** Why a pull could not produce the requested shape. */
56
+ export type PullIssueKind =
57
+ /** The requested member was absent when its container completed. */
58
+ "missing"
59
+ /** The producer finished before the pulled value's closing token. */
60
+ | "incomplete"
61
+ /** The producer abandoned the input before the pull completed. */
62
+ | "aborted"
63
+ /** A complete pulled value could not be parsed. */
64
+ | "malformed"
65
+ /** A value was present with a different JSON shape (see `found`). */
66
+ | "mismatch";
67
+ /** Structured failure while awaiting an incoming JSON value. */
68
+ export declare class IncomingJsonError extends Error {
69
+ /** Full key/index path pulled by the consumer. */
70
+ readonly path: readonly PullPathSegment[];
71
+ /** Shape requested by the typed cursor. */
72
+ readonly expected: string;
73
+ /** Why the pull could not produce that shape. */
74
+ readonly kind: PullIssueKind;
75
+ /** Shape observed in the input when `kind` is `mismatch`. */
76
+ readonly found?: string;
77
+ constructor(path: readonly PullPathSegment[], expected: string, kind: PullIssueKind, options?: {
78
+ found?: string;
79
+ cause?: unknown;
80
+ });
81
+ }
82
+ type Shape = {
83
+ kind: "null" | "array" | "object";
84
+ } | {
85
+ kind: "boolean";
86
+ value: boolean;
87
+ } | {
88
+ kind: "number";
89
+ value: number;
90
+ } | {
91
+ kind: "string";
92
+ value: string;
93
+ stableLen: number;
94
+ };
95
+ interface Located {
96
+ tag: "located";
97
+ /** Source offset of the value's first char. */
98
+ start: number;
99
+ /** Source offset just past the value's closing token; `undefined` while it is still open. */
100
+ end: number | undefined;
101
+ shape: Shape;
102
+ }
103
+ /** Readiness predicate a pull waits for once its value has been located. */
104
+ type Ready = (located: Located) => boolean;
105
+ /** Append-only buffer, terminal state, and change notification shared by one feed and its cursors. */
106
+ declare class Shared {
107
+ #private;
108
+ text: string;
109
+ end: "open" | "finished" | "aborted";
110
+ /** Resolves once the buffer or terminal state changes after this call. */
111
+ get changed(): Promise<void>;
112
+ notify(): void;
113
+ /** Await input completion; rejects with `aborted` when the feed was abandoned. */
114
+ finished(): Promise<void>;
115
+ /**
116
+ * Await the value at `path` until `ready` accepts it. Resolves `undefined`
117
+ * when the value's container completed without it.
118
+ */
119
+ pull(path: readonly PullPathSegment[], expected: string, ready: Ready): Promise<Located | undefined>;
120
+ }
121
+ /**
122
+ * Push side of an {@link IncomingDoc} channel. Call {@link finish} to mark
123
+ * the document complete or {@link abort} to abandon it; both are idempotent
124
+ * and every pending pull settles on the first one.
125
+ */
126
+ export declare class IncomingFeed {
127
+ #private;
128
+ constructor(shared: Shared);
129
+ /** Append one text fragment and wake every pending cursor. Throws once the feed is closed. */
130
+ push(fragment: string): void;
131
+ /** Mark the input complete. */
132
+ finish(): void;
133
+ /** Abandon the input; pending and future pulls reject with kind `aborted`. */
134
+ abort(): void;
135
+ }
136
+ /** Read side of one growing JSON document. */
137
+ export declare class IncomingDoc {
138
+ #private;
139
+ constructor(shared: Shared);
140
+ /** Create a push feed and its read-side document. */
141
+ static channel(): {
142
+ feed: IncomingFeed;
143
+ doc: IncomingDoc;
144
+ };
145
+ /** Text received so far. */
146
+ get text(): string;
147
+ /** Await explicit input completion; rejects with kind `aborted` if the feed was abandoned. */
148
+ finished(): Promise<void>;
149
+ /**
150
+ * Parse the entire finished document with the final tolerant parser.
151
+ * Waits for {@link IncomingFeed.finish}; aborted input is not decoded and a
152
+ * document that fails the final parse rejects with kind `malformed`.
153
+ */
154
+ whole<T = unknown>(): Promise<T>;
155
+ /** Cursor for the root JSON value. */
156
+ root(): IncomingJson;
157
+ }
158
+ /** Cursor for one JSON value in the incoming document, addressed by path. */
159
+ export declare class IncomingJson {
160
+ #private;
161
+ readonly path: readonly PullPathSegment[];
162
+ constructor(shared: Shared, path: readonly PullPathSegment[]);
163
+ /** Await the value's first token and report its JSON shape. */
164
+ kind(): Promise<IncomingValueKind>;
165
+ /** Await and parse the complete value. Containers go through the final tolerant parser. */
166
+ value<T = unknown>(): Promise<T>;
167
+ /** Await a complete number. */
168
+ number(): Promise<number>;
169
+ /** Await a complete boolean. */
170
+ boolean(): Promise<boolean>;
171
+ /** Await a complete `null`. */
172
+ null(): Promise<null>;
173
+ /** View this value as an incremental decoded string. */
174
+ string(): IncomingString;
175
+ /** View this value as an array of element cursors. */
176
+ array(): IncomingArray;
177
+ /** View this value as an object with keyed cursors. */
178
+ object(): IncomingObject;
179
+ }
180
+ /**
181
+ * Incremental decoded string consumer. Chunks are emitted in order without
182
+ * overlap and are always prefixes of the final decoded string;
183
+ * {@link text} returns the complete string independently of whether chunks
184
+ * were consumed. Async iteration yields chunks. Concurrent `nextChunk` /
185
+ * `nextLine` calls are served in call order, like a stream reader: a call
186
+ * whose result is abandoned still consumes its chunk.
187
+ */
188
+ export declare class IncomingString implements AsyncIterable<string> {
189
+ #private;
190
+ constructor(shared: Shared, path: readonly PullPathSegment[]);
191
+ /** Await the next stable decoded chunk, or `undefined` after the closing quote. */
192
+ nextChunk(): Promise<string | undefined>;
193
+ /**
194
+ * Await the next complete decoded line, retaining its trailing newline.
195
+ * A final unterminated line is returned once the closing quote arrives.
196
+ */
197
+ nextLine(): Promise<string | undefined>;
198
+ /** Iterate complete decoded lines. */
199
+ lines(): AsyncGenerator<string, void, undefined>;
200
+ [Symbol.asyncIterator](): AsyncGenerator<string, void, undefined>;
201
+ /** Await the closing quote and return the complete decoded string. */
202
+ text(): Promise<string>;
203
+ }
204
+ /**
205
+ * Linear cursor over elements of an incoming array. Async iteration yields
206
+ * element cursors. Concurrent `next` calls are served in call order.
207
+ */
208
+ export declare class IncomingArray implements AsyncIterable<IncomingJson> {
209
+ #private;
210
+ constructor(shared: Shared, path: readonly PullPathSegment[]);
211
+ /** Await the start of the next element; `undefined` only after the closing bracket. */
212
+ next(): Promise<IncomingJson | undefined>;
213
+ [Symbol.asyncIterator](): AsyncGenerator<IncomingJson, void, undefined>;
214
+ /** Await the closing bracket and collect the fully parsed elements. */
215
+ collect<T = unknown>(): Promise<T[]>;
216
+ }
217
+ /** Keyed cursor and final collection for an incoming object. */
218
+ export declare class IncomingObject {
219
+ #private;
220
+ constructor(shared: Shared, path: readonly PullPathSegment[]);
221
+ /**
222
+ * Cursor bound to the first occurrence of `name`. Pulling it makes the
223
+ * key required: a missing member rejects with kind `missing`.
224
+ */
225
+ key(name: string): IncomingJson;
226
+ /**
227
+ * Await the closing brace and collect the object through the final parser,
228
+ * whose duplicate keys are last-write-wins unlike {@link key}.
229
+ */
230
+ collect<T = Record<string, unknown>>(): Promise<T>;
231
+ }
232
+ export {};
@@ -0,0 +1,43 @@
1
+ export { once, untilAborted } from "./abortable.js";
2
+ export * from "./async.js";
3
+ export * from "./binary.js";
4
+ export * from "./color.js";
5
+ export * from "./dirs.js";
6
+ export * from "./env.js";
7
+ export * from "./fetch-retry.js";
8
+ export * from "./file-lock.js";
9
+ export * from "./format.js";
10
+ export * from "./frontmatter.js";
11
+ export * from "./fs-error.js";
12
+ export * from "./glob.js";
13
+ export * from "./incoming-json.js";
14
+ export * from "./json.js";
15
+ export * from "./json-parse.js";
16
+ export * as logger from "./logger.js";
17
+ export * from "./loop-phase.js";
18
+ export * from "./materialize-string.js";
19
+ export * from "./math-delimiters.js";
20
+ export * from "./mermaid-ascii.js";
21
+ export * from "./mime.js";
22
+ export * from "./path.js";
23
+ export * from "./path-tree.js";
24
+ export * from "./peek-file.js";
25
+ export * as postmortem from "./postmortem.js";
26
+ export * from "./process-name.js";
27
+ export * as procmgr from "./procmgr.js";
28
+ export * as prompt from "./prompt.js";
29
+ export * as ptree from "./ptree.js";
30
+ export { AbortError, ChildProcess, Exception, NonZeroExitError } from "./ptree.js";
31
+ export * from "./runtime-install.js";
32
+ export * from "./sanitize-text.js";
33
+ export * from "./snowflake.js";
34
+ export * from "./sqlite.js";
35
+ export * from "./stderr-guard.js";
36
+ export * from "./stream.js";
37
+ export * from "./tab-spacing.js";
38
+ export * from "./temp.js";
39
+ export * from "./tls-fetch.js";
40
+ export * from "./type-guards.js";
41
+ export * from "./version.js";
42
+ export * from "./which.js";
43
+ export declare function structuredCloneJSON<T>(value: T): T;
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Tolerant JSON lexer shared by the final parser (`parseJsonWithRepair`), the
3
+ * streaming partial builder (`parseStreamingJson`), and the incoming cursors
4
+ * (`IncomingDoc`). {@link JsonLexerMode} selects how truncation and unescaped
5
+ * inner double quotes are treated.
6
+ *
7
+ * The grammar is a forgiving superset of JSON covering malformations commonly
8
+ * produced by language models:
9
+ *
10
+ * - single-quoted strings and unquoted object keys (JSON5);
11
+ * - trailing / stray commas, and `//` + block comments;
12
+ * - Python literals `True` / `False` / `None`, plus `0x` / `0b` numbers;
13
+ * - raw control characters and invalid `\x` escapes inside strings (kept literally);
14
+ * - unescaped quotes inside strings — a single quote only closes a string when
15
+ * followed by a value terminator, recovering apostrophes such as `'it's'`;
16
+ * the same recovery applies to double quotes in `streaming` mode only,
17
+ * everywhere else they close strictly;
18
+ * - unquoted string values in value position — an unrecognized bareword such
19
+ * as `{"paths": packages/foo/*}` is recovered as a string up to the next
20
+ * `,` / `}` / `]` / newline.
21
+ */
22
+ export declare const QUOTE = 34;
23
+ export declare const SQUOTE = 39;
24
+ export declare const BACKSLASH = 92;
25
+ export declare const SLASH = 47;
26
+ export declare const COLON = 58;
27
+ export declare const COMMA = 44;
28
+ export declare const LBRACE = 123;
29
+ export declare const RBRACE = 125;
30
+ export declare const LBRACKET = 91;
31
+ export declare const RBRACKET = 93;
32
+ /** Valid chars after `\` in a strict JSON escape: `" \ / b f n r t u`. */
33
+ export declare const VALID_ESCAPE_CHAR: Uint8Array<ArrayBuffer>;
34
+ export declare function isHexDigit(cp: number): boolean;
35
+ /** JSON insignificant whitespace (RFC 8259 §2). */
36
+ export declare function isWhitespace(cp: number): boolean;
37
+ /** First char of a numeric token: sign, dot, or digit. */
38
+ export declare function isNumberStart(cp: number): boolean;
39
+ /**
40
+ * Grammar tolerance selected by the lexer's consumer.
41
+ *
42
+ * - `strict`: final parse — complete input required, double quotes close strictly.
43
+ * - `streaming`: mid-stream snapshot — incomplete tokens tolerated and unescaped
44
+ * inner double quotes recovered for display.
45
+ * - `incoming`: incremental typed pulls — incomplete tokens tolerated, but double
46
+ * quotes close strictly so pulled values match the final parse.
47
+ */
48
+ export type JsonLexerMode = "strict" | "streaming" | "incoming";
49
+ /** Decoded state of a string token at the current streaming edge. */
50
+ export interface JsonStringProgress {
51
+ /** Decoded content so far (complete when `complete` is true). */
52
+ value: string;
53
+ /**
54
+ * Length of the prefix of `value` whose meaning cannot change when more
55
+ * input arrives. Excludes a trailing split escape, a high surrogate whose
56
+ * low half may still follow, and everything from a quote whose close/inner
57
+ * reading is still undecidable at the buffer edge.
58
+ */
59
+ stableLen: number;
60
+ /** Whether the closing quote was consumed. */
61
+ complete: boolean;
62
+ }
63
+ /**
64
+ * Cursor over the input with the tolerant token readers. `pos` is the current
65
+ * offset; readers advance it. In `strict` mode a truncated or malformed token
66
+ * throws `SyntaxError`; the lenient modes report progress or return
67
+ * `undefined` so the caller can roll back.
68
+ */
69
+ export declare class JsonLexer {
70
+ #private;
71
+ readonly src: string;
72
+ readonly mode: JsonLexerMode;
73
+ pos: number;
74
+ constructor(src: string, mode: JsonLexerMode, pos?: number);
75
+ get atEnd(): boolean;
76
+ /** Char code at the cursor; `NaN` at end of input (so every comparison is false). */
77
+ peek(): number;
78
+ /** Skip whitespace plus `//` line and `/* *\/` block comments. */
79
+ ws(): void;
80
+ /**
81
+ * Read a string starting at the opening `quote`, retaining the information
82
+ * an incremental consumer needs. Strict mode throws on an unterminated
83
+ * string; lenient modes consume to the end of input and report progress.
84
+ */
85
+ string(quote: number): JsonStringProgress;
86
+ /**
87
+ * Read a numeric token with JS `Number()` semantics (decimal with optional
88
+ * sign / leading or trailing dot / exponent, plus `0x` hex and `0b` binary).
89
+ * Non-finite or malformed tokens throw in strict mode and return
90
+ * `undefined` in lenient modes; the cursor is left past the token either way.
91
+ */
92
+ number(): number | undefined;
93
+ /**
94
+ * Match a keyword literal at the cursor; consumes only on success and
95
+ * returns `undefined` otherwise. Requires a non-identifier boundary so
96
+ * `Truex` / `nullish` are not misread as the keyword followed by junk.
97
+ */
98
+ keyword(): boolean | null | undefined;
99
+ /** Read an unquoted object key: everything up to `:` / `,` / `}` / whitespace. May be empty. */
100
+ unquotedKey(): string;
101
+ /**
102
+ * Recover an unquoted string value, e.g. `{"paths": packages/foo/*}`:
103
+ * consume until `,` / `}` / `]` / newline and trim trailing whitespace.
104
+ * Recovery still fails — so a final parse never accepts a half-formed or
105
+ * non-finite argument — when the token:
106
+ * - hits end-of-input before a delimiter (truncated value);
107
+ * - contains a `"`, `{`, `[`, or a key-like `:` — this grammar accepts
108
+ * unquoted keys, so a missed comma (`{"a": foo "b": 1}`) would otherwise
109
+ * silently swallow the following field. A colon followed by `/` or `\`
110
+ * stays literal so URL and Windows-path values recover;
111
+ * - is a non-finite atom ({@link NON_RECOVERABLE_BAREWORDS}).
112
+ *
113
+ * Failure throws in strict mode and returns `undefined` in lenient modes.
114
+ */
115
+ bareword(): string | undefined;
116
+ }