@warlock.js/ai-cli 0.0.0-stage → 5.31.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 (139) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/LICENSE +21 -0
  3. package/README.md +69 -2
  4. package/cjs/index.cjs +4576 -0
  5. package/cjs/index.cjs.map +1 -0
  6. package/esm/adapters/aider.d.mts +41 -0
  7. package/esm/adapters/aider.d.mts.map +1 -0
  8. package/esm/adapters/aider.mjs +294 -0
  9. package/esm/adapters/aider.mjs.map +1 -0
  10. package/esm/adapters/amp.d.mts +33 -0
  11. package/esm/adapters/amp.d.mts.map +1 -0
  12. package/esm/adapters/amp.mjs +119 -0
  13. package/esm/adapters/amp.mjs.map +1 -0
  14. package/esm/adapters/antigravity.d.mts +37 -0
  15. package/esm/adapters/antigravity.d.mts.map +1 -0
  16. package/esm/adapters/antigravity.mjs +235 -0
  17. package/esm/adapters/antigravity.mjs.map +1 -0
  18. package/esm/adapters/claude-code.d.mts +30 -0
  19. package/esm/adapters/claude-code.d.mts.map +1 -0
  20. package/esm/adapters/claude-code.mjs +121 -0
  21. package/esm/adapters/claude-code.mjs.map +1 -0
  22. package/esm/adapters/claude-stream.d.mts +32 -0
  23. package/esm/adapters/claude-stream.d.mts.map +1 -0
  24. package/esm/adapters/claude-stream.mjs +140 -0
  25. package/esm/adapters/claude-stream.mjs.map +1 -0
  26. package/esm/adapters/codex.d.mts +37 -0
  27. package/esm/adapters/codex.d.mts.map +1 -0
  28. package/esm/adapters/codex.mjs +320 -0
  29. package/esm/adapters/codex.mjs.map +1 -0
  30. package/esm/adapters/copilot.d.mts +35 -0
  31. package/esm/adapters/copilot.d.mts.map +1 -0
  32. package/esm/adapters/copilot.mjs +244 -0
  33. package/esm/adapters/copilot.mjs.map +1 -0
  34. package/esm/adapters/cursor.d.mts +35 -0
  35. package/esm/adapters/cursor.d.mts.map +1 -0
  36. package/esm/adapters/cursor.mjs +203 -0
  37. package/esm/adapters/cursor.mjs.map +1 -0
  38. package/esm/adapters/droid.d.mts +32 -0
  39. package/esm/adapters/droid.d.mts.map +1 -0
  40. package/esm/adapters/droid.mjs +183 -0
  41. package/esm/adapters/droid.mjs.map +1 -0
  42. package/esm/adapters/grok.d.mts +32 -0
  43. package/esm/adapters/grok.d.mts.map +1 -0
  44. package/esm/adapters/grok.mjs +199 -0
  45. package/esm/adapters/grok.mjs.map +1 -0
  46. package/esm/adapters/index.d.mts +16 -0
  47. package/esm/adapters/index.mjs +18 -0
  48. package/esm/adapters/kimi.d.mts +34 -0
  49. package/esm/adapters/kimi.d.mts.map +1 -0
  50. package/esm/adapters/kimi.mjs +162 -0
  51. package/esm/adapters/kimi.mjs.map +1 -0
  52. package/esm/adapters/mistral-vibe.d.mts +32 -0
  53. package/esm/adapters/mistral-vibe.d.mts.map +1 -0
  54. package/esm/adapters/mistral-vibe.mjs +252 -0
  55. package/esm/adapters/mistral-vibe.mjs.map +1 -0
  56. package/esm/adapters/opencode.d.mts +36 -0
  57. package/esm/adapters/opencode.d.mts.map +1 -0
  58. package/esm/adapters/opencode.mjs +219 -0
  59. package/esm/adapters/opencode.mjs.map +1 -0
  60. package/esm/adapters/qwen-code.d.mts +30 -0
  61. package/esm/adapters/qwen-code.d.mts.map +1 -0
  62. package/esm/adapters/qwen-code.mjs +94 -0
  63. package/esm/adapters/qwen-code.mjs.map +1 -0
  64. package/esm/adapters/reasonix.d.mts +31 -0
  65. package/esm/adapters/reasonix.d.mts.map +1 -0
  66. package/esm/adapters/reasonix.mjs +250 -0
  67. package/esm/adapters/reasonix.mjs.map +1 -0
  68. package/esm/adapters/shared.d.mts +78 -0
  69. package/esm/adapters/shared.d.mts.map +1 -0
  70. package/esm/adapters/shared.mjs +161 -0
  71. package/esm/adapters/shared.mjs.map +1 -0
  72. package/esm/cli-agent.d.mts +40 -0
  73. package/esm/cli-agent.d.mts.map +1 -0
  74. package/esm/cli-agent.mjs +207 -0
  75. package/esm/cli-agent.mjs.map +1 -0
  76. package/esm/cli.d.mts +53 -0
  77. package/esm/cli.d.mts.map +1 -0
  78. package/esm/cli.mjs +61 -0
  79. package/esm/cli.mjs.map +1 -0
  80. package/esm/contracts/adapter.contract.d.mts +154 -0
  81. package/esm/contracts/adapter.contract.d.mts.map +1 -0
  82. package/esm/contracts/events.type.d.mts +111 -0
  83. package/esm/contracts/events.type.d.mts.map +1 -0
  84. package/esm/contracts/index.d.mts +4 -0
  85. package/esm/contracts/mcp.type.d.mts +29 -0
  86. package/esm/contracts/mcp.type.d.mts.map +1 -0
  87. package/esm/contracts/options.type.d.mts +87 -0
  88. package/esm/contracts/options.type.d.mts.map +1 -0
  89. package/esm/errors.d.mts +46 -0
  90. package/esm/errors.d.mts.map +1 -0
  91. package/esm/errors.mjs +32 -0
  92. package/esm/errors.mjs.map +1 -0
  93. package/esm/index.d.mts +31 -0
  94. package/esm/index.mjs +28 -0
  95. package/esm/model/cli-model.d.mts +48 -0
  96. package/esm/model/cli-model.d.mts.map +1 -0
  97. package/esm/model/cli-model.mjs +133 -0
  98. package/esm/model/cli-model.mjs.map +1 -0
  99. package/esm/probe/probe.d.mts +18 -0
  100. package/esm/probe/probe.d.mts.map +1 -0
  101. package/esm/probe/probe.mjs +148 -0
  102. package/esm/probe/probe.mjs.map +1 -0
  103. package/esm/session/aggregate.mjs +86 -0
  104. package/esm/session/aggregate.mjs.map +1 -0
  105. package/esm/session/environment.mjs +71 -0
  106. package/esm/session/environment.mjs.map +1 -0
  107. package/esm/session/run-directory.mjs +74 -0
  108. package/esm/session/run-directory.mjs.map +1 -0
  109. package/esm/session/session.mjs +188 -0
  110. package/esm/session/session.mjs.map +1 -0
  111. package/esm/spawn/invocation.d.mts +35 -0
  112. package/esm/spawn/invocation.d.mts.map +1 -0
  113. package/esm/spawn/invocation.mjs +76 -0
  114. package/esm/spawn/invocation.mjs.map +1 -0
  115. package/esm/spawn/process-tree.mjs +57 -0
  116. package/esm/spawn/process-tree.mjs.map +1 -0
  117. package/esm/spawn/resolve-command.d.mts +73 -0
  118. package/esm/spawn/resolve-command.d.mts.map +1 -0
  119. package/esm/spawn/resolve-command.mjs +109 -0
  120. package/esm/spawn/resolve-command.mjs.map +1 -0
  121. package/esm/stream/event-log.mjs +52 -0
  122. package/esm/stream/event-log.mjs.map +1 -0
  123. package/esm/stream/json-lines.d.mts +33 -0
  124. package/esm/stream/json-lines.d.mts.map +1 -0
  125. package/esm/stream/json-lines.mjs +65 -0
  126. package/esm/stream/json-lines.mjs.map +1 -0
  127. package/esm/stream/line-splitter.mjs +53 -0
  128. package/esm/stream/line-splitter.mjs.map +1 -0
  129. package/esm/utils/toml.d.mts +22 -0
  130. package/esm/utils/toml.d.mts.map +1 -0
  131. package/esm/utils/toml.mjs +53 -0
  132. package/esm/utils/toml.mjs.map +1 -0
  133. package/llms-full.txt +373 -0
  134. package/llms.txt +10 -0
  135. package/package.json +39 -4
  136. package/skills/README.md +13 -0
  137. package/skills/index.md +22 -0
  138. package/skills/run-cli-agents/SKILL.md +186 -0
  139. package/skills/write-a-cli-adapter/SKILL.md +173 -0
@@ -0,0 +1,52 @@
1
+ //#region ../../packages/ai-cli/src/stream/event-log.ts
2
+ /**
3
+ * An append-only event log that any number of async iterators can read.
4
+ * Each iterator starts at the first event and ends once the log is closed
5
+ * and drained, so a late consumer still sees the whole session.
6
+ */
7
+ var EventLog = class {
8
+ constructor() {
9
+ this.items = [];
10
+ this.closed = false;
11
+ this.waiters = [];
12
+ }
13
+ push(item) {
14
+ if (this.closed) return;
15
+ this.items.push(item);
16
+ this.wake();
17
+ }
18
+ close() {
19
+ this.closed = true;
20
+ this.wake();
21
+ }
22
+ get size() {
23
+ return this.items.length;
24
+ }
25
+ [Symbol.asyncIterator]() {
26
+ let index = 0;
27
+ return { next: async () => {
28
+ while (index >= this.items.length && !this.closed) await new Promise((resolve) => this.waiters.push(resolve));
29
+ if (index < this.items.length) {
30
+ const value = this.items[index];
31
+ index += 1;
32
+ return {
33
+ value,
34
+ done: false
35
+ };
36
+ }
37
+ return {
38
+ value: void 0,
39
+ done: true
40
+ };
41
+ } };
42
+ }
43
+ wake() {
44
+ const waiters = this.waiters;
45
+ this.waiters = [];
46
+ for (const waiter of waiters) waiter();
47
+ }
48
+ };
49
+
50
+ //#endregion
51
+ export { EventLog };
52
+ //# sourceMappingURL=event-log.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-log.mjs","names":[],"sources":["../../../../../../../../packages/ai-cli/src/stream/event-log.ts"],"sourcesContent":["/**\n * An append-only event log that any number of async iterators can read.\n * Each iterator starts at the first event and ends once the log is closed\n * and drained, so a late consumer still sees the whole session.\n */\nexport class EventLog<T> implements AsyncIterable<T> {\n private readonly items: T[] = [];\n private closed = false;\n private waiters: Array<() => void> = [];\n\n public push(item: T): void {\n if (this.closed) {\n return;\n }\n\n this.items.push(item);\n this.wake();\n }\n\n public close(): void {\n this.closed = true;\n this.wake();\n }\n\n public get size(): number {\n return this.items.length;\n }\n\n public [Symbol.asyncIterator](): AsyncIterator<T> {\n let index = 0;\n\n return {\n next: async (): Promise<IteratorResult<T>> => {\n while (index >= this.items.length && !this.closed) {\n await new Promise<void>((resolve) => this.waiters.push(resolve));\n }\n\n if (index < this.items.length) {\n const value = this.items[index] as T;\n\n index += 1;\n\n return { value, done: false };\n }\n\n return { value: undefined, done: true };\n },\n };\n }\n\n private wake(): void {\n const waiters = this.waiters;\n\n this.waiters = [];\n\n for (const waiter of waiters) {\n waiter();\n }\n }\n}\n"],"mappings":";;;;;;AAKA,IAAa,WAAb,MAAqD;;eACrB,CAAC;gBACd;iBACoB,CAAC;;CAEtC,AAAO,KAAK,MAAe;EACzB,IAAI,KAAK,QACP;EAGF,KAAK,MAAM,KAAK,IAAI;EACpB,KAAK,KAAK;CACZ;CAEA,AAAO,QAAc;EACnB,KAAK,SAAS;EACd,KAAK,KAAK;CACZ;CAEA,IAAW,OAAe;EACxB,OAAO,KAAK,MAAM;CACpB;CAEA,CAAQ,OAAO,iBAAmC;EAChD,IAAI,QAAQ;EAEZ,OAAO,EACL,MAAM,YAAwC;GAC5C,OAAO,SAAS,KAAK,MAAM,UAAU,CAAC,KAAK,QACzC,MAAM,IAAI,SAAe,YAAY,KAAK,QAAQ,KAAK,OAAO,CAAC;GAGjE,IAAI,QAAQ,KAAK,MAAM,QAAQ;IAC7B,MAAM,QAAQ,KAAK,MAAM;IAEzB,SAAS;IAET,OAAO;KAAE;KAAO,MAAM;IAAM;GAC9B;GAEA,OAAO;IAAE,OAAO;IAAW,MAAM;GAAK;EACxC,EACF;CACF;CAEA,AAAQ,OAAa;EACnB,MAAM,UAAU,KAAK;EAErB,KAAK,UAAU,CAAC;EAEhB,KAAK,MAAM,UAAU,SACnB,OAAO;CAEX;AACF"}
@@ -0,0 +1,33 @@
1
+ import { CliParsedEvent } from "../contracts/events.type.mjs";
2
+ import { CliStreamParser } from "../contracts/adapter.contract.mjs";
3
+ //#region ../../packages/ai-cli/src/stream/json-lines.d.ts
4
+ /** A plain JSON object. */
5
+ type JsonRecord = Record<string, unknown>;
6
+ /** `value` as a JSON object, or `undefined`. */
7
+ declare function asRecord(value: unknown): JsonRecord | undefined;
8
+ /** `value` as an array, or an empty array. */
9
+ declare function asArray(value: unknown): unknown[];
10
+ /** A string field, or `undefined`. */
11
+ declare function stringField(record: JsonRecord | undefined, key: string): string | undefined;
12
+ /** A finite number field, or `undefined`. */
13
+ declare function numberField(record: JsonRecord | undefined, key: string): number | undefined;
14
+ /** A nested object field, or `undefined`. */
15
+ declare function recordField(record: JsonRecord | undefined, key: string): JsonRecord | undefined;
16
+ /** Tool output as text: strings verbatim, text-block arrays joined, anything else as JSON. */
17
+ declare function outputText(value: unknown): string;
18
+ /** Parse one line as a JSON object; anything else (banners, blank lines) is `undefined`. */
19
+ declare function parseJsonLine(line: string): JsonRecord | undefined;
20
+ /**
21
+ * Build a parser for a JSONL/NDJSON stream. Non-JSON lines (progress
22
+ * banners, warnings) are skipped; each JSON object goes to `onRecord`.
23
+ * `onEnd` may flush buffered state when stdout closes.
24
+ *
25
+ * @example
26
+ * const parser = jsonLinesParser((record) =>
27
+ * record.type === "text" ? [{ type: "message", text: String(record.text), delta: false }] : [],
28
+ * );
29
+ */
30
+ declare function jsonLinesParser(onRecord: (record: JsonRecord) => CliParsedEvent[], onEnd?: () => CliParsedEvent[]): CliStreamParser;
31
+ //#endregion
32
+ export { JsonRecord, asArray, asRecord, jsonLinesParser, numberField, outputText, parseJsonLine, recordField, stringField };
33
+ //# sourceMappingURL=json-lines.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-lines.d.mts","names":[],"sources":["../../../../../../../../packages/ai-cli/src/stream/json-lines.ts"],"mappings":";;;;KAGY,UAAA,GAAa,MAAM;;iBAGf,QAAA,CAAS,KAAA,YAAiB,UAAU;AAHpD;AAAA,iBAUgB,OAAA,CAAQ,KAAc;;iBAKtB,WAAA,CAAY,MAAA,EAAQ,UAAU,cAAc,GAAA;AAf7B;AAAA,iBAsBf,WAAA,CAAY,MAAA,EAAQ,UAAU,cAAc,GAAA;;iBAO5C,WAAA,CAAY,MAAA,EAAQ,UAAA,cAAwB,GAAA,WAAc,UAAU;;iBAKpE,UAAA,CAAW,KAAc;AAxBzC;AAAA,iBAgDgB,aAAA,CAAc,IAAA,WAAe,UAAU;;;AAhDjB;AAKtC;;;;;;;iBAmEgB,eAAA,CACd,QAAA,GAAW,MAAA,EAAQ,UAAA,KAAe,cAAA,IAClC,KAAA,SAAa,cAAA,KACZ,eAAA"}
@@ -0,0 +1,65 @@
1
+ //#region ../../packages/ai-cli/src/stream/json-lines.ts
2
+ /** `value` as a JSON object, or `undefined`. */
3
+ function asRecord(value) {
4
+ return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
5
+ }
6
+ /** `value` as an array, or an empty array. */
7
+ function asArray(value) {
8
+ return Array.isArray(value) ? value : [];
9
+ }
10
+ /** A string field, or `undefined`. */
11
+ function stringField(record, key) {
12
+ const value = record?.[key];
13
+ return typeof value === "string" ? value : void 0;
14
+ }
15
+ /** A finite number field, or `undefined`. */
16
+ function numberField(record, key) {
17
+ const value = record?.[key];
18
+ return typeof value === "number" && Number.isFinite(value) ? value : void 0;
19
+ }
20
+ /** A nested object field, or `undefined`. */
21
+ function recordField(record, key) {
22
+ return asRecord(record?.[key]);
23
+ }
24
+ /** Tool output as text: strings verbatim, text-block arrays joined, anything else as JSON. */
25
+ function outputText(value) {
26
+ if (typeof value === "string") return value;
27
+ if (value === void 0 || value === null) return "";
28
+ if (Array.isArray(value)) return value.map((item) => {
29
+ return stringField(asRecord(item), "text") ?? (typeof item === "string" ? item : JSON.stringify(item));
30
+ }).join("\n");
31
+ return JSON.stringify(value);
32
+ }
33
+ /** Parse one line as a JSON object; anything else (banners, blank lines) is `undefined`. */
34
+ function parseJsonLine(line) {
35
+ const trimmed = line.trim();
36
+ if (!trimmed.startsWith("{")) return;
37
+ try {
38
+ return asRecord(JSON.parse(trimmed));
39
+ } catch {
40
+ return;
41
+ }
42
+ }
43
+ /**
44
+ * Build a parser for a JSONL/NDJSON stream. Non-JSON lines (progress
45
+ * banners, warnings) are skipped; each JSON object goes to `onRecord`.
46
+ * `onEnd` may flush buffered state when stdout closes.
47
+ *
48
+ * @example
49
+ * const parser = jsonLinesParser((record) =>
50
+ * record.type === "text" ? [{ type: "message", text: String(record.text), delta: false }] : [],
51
+ * );
52
+ */
53
+ function jsonLinesParser(onRecord, onEnd = () => []) {
54
+ return {
55
+ line(line) {
56
+ const record = parseJsonLine(line);
57
+ return record === void 0 ? [] : onRecord(record);
58
+ },
59
+ end: onEnd
60
+ };
61
+ }
62
+
63
+ //#endregion
64
+ export { asArray, asRecord, jsonLinesParser, numberField, outputText, parseJsonLine, recordField, stringField };
65
+ //# sourceMappingURL=json-lines.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-lines.mjs","names":[],"sources":["../../../../../../../../packages/ai-cli/src/stream/json-lines.ts"],"sourcesContent":["import type { CliParsedEvent, CliStreamParser } from \"../contracts\";\n\n/** A plain JSON object. */\nexport type JsonRecord = Record<string, unknown>;\n\n/** `value` as a JSON object, or `undefined`. */\nexport function asRecord(value: unknown): JsonRecord | undefined {\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n ? (value as JsonRecord)\n : undefined;\n}\n\n/** `value` as an array, or an empty array. */\nexport function asArray(value: unknown): unknown[] {\n return Array.isArray(value) ? value : [];\n}\n\n/** A string field, or `undefined`. */\nexport function stringField(record: JsonRecord | undefined, key: string): string | undefined {\n const value = record?.[key];\n\n return typeof value === \"string\" ? value : undefined;\n}\n\n/** A finite number field, or `undefined`. */\nexport function numberField(record: JsonRecord | undefined, key: string): number | undefined {\n const value = record?.[key];\n\n return typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\n/** A nested object field, or `undefined`. */\nexport function recordField(record: JsonRecord | undefined, key: string): JsonRecord | undefined {\n return asRecord(record?.[key]);\n}\n\n/** Tool output as text: strings verbatim, text-block arrays joined, anything else as JSON. */\nexport function outputText(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n\n if (value === undefined || value === null) {\n return \"\";\n }\n\n if (Array.isArray(value)) {\n const texts = value.map((item) => {\n const block = asRecord(item);\n const text = stringField(block, \"text\");\n\n return text ?? (typeof item === \"string\" ? item : JSON.stringify(item));\n });\n\n return texts.join(\"\\n\");\n }\n\n return JSON.stringify(value);\n}\n\n/** Parse one line as a JSON object; anything else (banners, blank lines) is `undefined`. */\nexport function parseJsonLine(line: string): JsonRecord | undefined {\n const trimmed = line.trim();\n\n if (!trimmed.startsWith(\"{\")) {\n return undefined;\n }\n\n try {\n return asRecord(JSON.parse(trimmed));\n } catch {\n return undefined;\n }\n}\n\n/**\n * Build a parser for a JSONL/NDJSON stream. Non-JSON lines (progress\n * banners, warnings) are skipped; each JSON object goes to `onRecord`.\n * `onEnd` may flush buffered state when stdout closes.\n *\n * @example\n * const parser = jsonLinesParser((record) =>\n * record.type === \"text\" ? [{ type: \"message\", text: String(record.text), delta: false }] : [],\n * );\n */\nexport function jsonLinesParser(\n onRecord: (record: JsonRecord) => CliParsedEvent[],\n onEnd: () => CliParsedEvent[] = () => [],\n): CliStreamParser {\n return {\n line(line: string): CliParsedEvent[] {\n const record = parseJsonLine(line);\n\n return record === undefined ? [] : onRecord(record);\n },\n end: onEnd,\n };\n}\n"],"mappings":";;AAMA,SAAgB,SAAS,OAAwC;CAC/D,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK,IACrE,QACD;AACN;;AAGA,SAAgB,QAAQ,OAA2B;CACjD,OAAO,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC;AACzC;;AAGA,SAAgB,YAAY,QAAgC,KAAiC;CAC3F,MAAM,QAAQ,SAAS;CAEvB,OAAO,OAAO,UAAU,WAAW,QAAQ;AAC7C;;AAGA,SAAgB,YAAY,QAAgC,KAAiC;CAC3F,MAAM,QAAQ,SAAS;CAEvB,OAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,IAAI,QAAQ;AACvE;;AAGA,SAAgB,YAAY,QAAgC,KAAqC;CAC/F,OAAO,SAAS,SAAS,IAAI;AAC/B;;AAGA,SAAgB,WAAW,OAAwB;CACjD,IAAI,OAAO,UAAU,UACnB,OAAO;CAGT,IAAI,UAAU,UAAa,UAAU,MACnC,OAAO;CAGT,IAAI,MAAM,QAAQ,KAAK,GAQrB,OAPc,MAAM,KAAK,SAAS;EAIhC,OAFa,YADC,SAAS,IACM,GAAG,MAEtB,MAAM,OAAO,SAAS,WAAW,OAAO,KAAK,UAAU,IAAI;CACvE,CAEW,CAAC,CAAC,KAAK,IAAI;CAGxB,OAAO,KAAK,UAAU,KAAK;AAC7B;;AAGA,SAAgB,cAAc,MAAsC;CAClE,MAAM,UAAU,KAAK,KAAK;CAE1B,IAAI,CAAC,QAAQ,WAAW,GAAG,GACzB;CAGF,IAAI;EACF,OAAO,SAAS,KAAK,MAAM,OAAO,CAAC;CACrC,QAAQ;EACN;CACF;AACF;;;;;;;;;;;AAYA,SAAgB,gBACd,UACA,cAAsC,CAAC,GACtB;CACjB,OAAO;EACL,KAAK,MAAgC;GACnC,MAAM,SAAS,cAAc,IAAI;GAEjC,OAAO,WAAW,SAAY,CAAC,IAAI,SAAS,MAAM;EACpD;EACA,KAAK;CACP;AACF"}
@@ -0,0 +1,53 @@
1
+ import { StringDecoder } from "node:string_decoder";
2
+
3
+ //#region ../../packages/ai-cli/src/stream/line-splitter.ts
4
+ /** Longest line kept in memory; a longer one is dropped (reported via `onOverflow`). */
5
+ const MAX_LINE_BYTES = 32 * 1024 * 1024;
6
+ /**
7
+ * Split a byte stream into lines. Multi-byte UTF-8 characters split across
8
+ * chunks are decoded correctly, `\r\n` and `\n` both end a line, and a final
9
+ * line without a newline is flushed by `end()`.
10
+ *
11
+ * @example
12
+ * const splitter = createLineSplitter((line) => console.log(line));
13
+ * splitter.write(Buffer.from('{"a":1}\n{"b"'));
14
+ * splitter.write(Buffer.from(":2}\n"));
15
+ * splitter.end();
16
+ */
17
+ function createLineSplitter(onLine, onOverflow = () => void 0) {
18
+ const decoder = new StringDecoder("utf8");
19
+ let pending = "";
20
+ let overflowed = false;
21
+ const consume = (text) => {
22
+ pending += text;
23
+ let newline = pending.indexOf("\n");
24
+ while (newline !== -1) {
25
+ const line = pending.slice(0, newline).replace(/\r$/, "");
26
+ pending = pending.slice(newline + 1);
27
+ if (overflowed) overflowed = false;
28
+ else onLine(line);
29
+ newline = pending.indexOf("\n");
30
+ }
31
+ if (pending.length > 33554432) {
32
+ pending = "";
33
+ if (!overflowed) {
34
+ overflowed = true;
35
+ onOverflow();
36
+ }
37
+ }
38
+ };
39
+ return {
40
+ write(chunk) {
41
+ consume(decoder.write(chunk));
42
+ },
43
+ end() {
44
+ consume(decoder.end());
45
+ if (pending.length > 0 && !overflowed) onLine(pending.replace(/\r$/, ""));
46
+ pending = "";
47
+ }
48
+ };
49
+ }
50
+
51
+ //#endregion
52
+ export { createLineSplitter };
53
+ //# sourceMappingURL=line-splitter.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"line-splitter.mjs","names":[],"sources":["../../../../../../../../packages/ai-cli/src/stream/line-splitter.ts"],"sourcesContent":["import { StringDecoder } from \"node:string_decoder\";\n\n/** Longest line kept in memory; a longer one is dropped (reported via `onOverflow`). */\nexport const MAX_LINE_BYTES = 32 * 1024 * 1024;\n\n/**\n * Split a byte stream into lines. Multi-byte UTF-8 characters split across\n * chunks are decoded correctly, `\\r\\n` and `\\n` both end a line, and a final\n * line without a newline is flushed by `end()`.\n *\n * @example\n * const splitter = createLineSplitter((line) => console.log(line));\n * splitter.write(Buffer.from('{\"a\":1}\\n{\"b\"'));\n * splitter.write(Buffer.from(\":2}\\n\"));\n * splitter.end();\n */\nexport function createLineSplitter(\n onLine: (line: string) => void,\n onOverflow: () => void = () => undefined,\n): { write(chunk: Buffer): void; end(): void } {\n const decoder = new StringDecoder(\"utf8\");\n let pending = \"\";\n let overflowed = false;\n\n const consume = (text: string): void => {\n pending += text;\n\n let newline = pending.indexOf(\"\\n\");\n\n while (newline !== -1) {\n const line = pending.slice(0, newline).replace(/\\r$/, \"\");\n\n pending = pending.slice(newline + 1);\n\n if (overflowed) {\n overflowed = false;\n } else {\n onLine(line);\n }\n\n newline = pending.indexOf(\"\\n\");\n }\n\n if (pending.length > MAX_LINE_BYTES) {\n pending = \"\";\n\n if (!overflowed) {\n overflowed = true;\n onOverflow();\n }\n }\n };\n\n return {\n write(chunk: Buffer): void {\n consume(decoder.write(chunk));\n },\n end(): void {\n consume(decoder.end());\n\n if (pending.length > 0 && !overflowed) {\n onLine(pending.replace(/\\r$/, \"\"));\n }\n\n pending = \"\";\n },\n };\n}\n"],"mappings":";;;;AAGA,MAAa,iBAAiB,KAAK,OAAO;;;;;;;;;;;;AAa1C,SAAgB,mBACd,QACA,mBAA+B,QACc;CAC7C,MAAM,UAAU,IAAI,cAAc,MAAM;CACxC,IAAI,UAAU;CACd,IAAI,aAAa;CAEjB,MAAM,WAAW,SAAuB;EACtC,WAAW;EAEX,IAAI,UAAU,QAAQ,QAAQ,IAAI;EAElC,OAAO,YAAY,IAAI;GACrB,MAAM,OAAO,QAAQ,MAAM,GAAG,OAAO,CAAC,CAAC,QAAQ,OAAO,EAAE;GAExD,UAAU,QAAQ,MAAM,UAAU,CAAC;GAEnC,IAAI,YACF,aAAa;QAEb,OAAO,IAAI;GAGb,UAAU,QAAQ,QAAQ,IAAI;EAChC;EAEA,IAAI,QAAQ,mBAAyB;GACnC,UAAU;GAEV,IAAI,CAAC,YAAY;IACf,aAAa;IACb,WAAW;GACb;EACF;CACF;CAEA,OAAO;EACL,MAAM,OAAqB;GACzB,QAAQ,QAAQ,MAAM,KAAK,CAAC;EAC9B;EACA,MAAY;GACV,QAAQ,QAAQ,IAAI,CAAC;GAErB,IAAI,QAAQ,SAAS,KAAK,CAAC,YACzB,OAAO,QAAQ,QAAQ,OAAO,EAAE,CAAC;GAGnC,UAAU;EACZ;CACF;AACF"}
@@ -0,0 +1,22 @@
1
+ //#region ../../packages/ai-cli/src/utils/toml.d.ts
2
+ /** A TOML value this writer supports. */
3
+ type TomlValue = string | number | boolean | TomlValue[] | TomlTable;
4
+ /** A TOML table. */
5
+ type TomlTable = {
6
+ [key: string]: TomlValue | undefined;
7
+ };
8
+ /**
9
+ * Serialize a table to TOML: scalars and arrays first, then each nested
10
+ * table as a `[dotted.header]` section. Enough for the CLI config files
11
+ * this package writes (Codex and Mistral Vibe MCP sections).
12
+ *
13
+ * @example
14
+ * toToml({ mcp_servers: { docs: { command: "npx", args: ["-y", "docs-mcp"] } } });
15
+ * // [mcp_servers.docs]
16
+ * // command = "npx"
17
+ * // args = ["-y", "docs-mcp"]
18
+ */
19
+ declare function toToml(table: TomlTable, prefix?: string[]): string;
20
+ //#endregion
21
+ export { TomlTable, TomlValue, toToml };
22
+ //# sourceMappingURL=toml.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toml.d.mts","names":[],"sources":["../../../../../../../../packages/ai-cli/src/utils/toml.ts"],"mappings":";;KACY,SAAA,+BAAwC,SAAA,KAAc,SAAS;;KAG/D,SAAA;EAAA,CAAe,GAAA,WAAc,SAAS;AAAA;;;AAAA;AAmDlD;;;;;;;;iBAAgB,MAAA,CAAO,KAAA,EAAO,SAAS,EAAE,MAAA"}
@@ -0,0 +1,53 @@
1
+ //#region ../../packages/ai-cli/src/utils/toml.ts
2
+ function isTable(value) {
3
+ return typeof value === "object" && !Array.isArray(value);
4
+ }
5
+ /** A bare key when possible, else a quoted one. */
6
+ function tomlKey(key) {
7
+ return /^[A-Za-z0-9_-]+$/.test(key) ? key : JSON.stringify(key);
8
+ }
9
+ /** A TOML scalar or inline value. JSON string escapes are valid TOML basic-string escapes. */
10
+ function inlineValue(value) {
11
+ if (typeof value === "string") return JSON.stringify(value);
12
+ if (typeof value === "number") {
13
+ if (!Number.isFinite(value)) throw new Error("TOML cannot encode a non-finite number");
14
+ return String(value);
15
+ }
16
+ if (typeof value === "boolean") return value ? "true" : "false";
17
+ if (Array.isArray(value)) return `[${value.map(inlineValue).join(", ")}]`;
18
+ return `{ ${Object.entries(value).filter((entry) => entry[1] !== void 0).map(([key, item]) => `${tomlKey(key)} = ${inlineValue(item)}`).join(", ")} }`;
19
+ }
20
+ /**
21
+ * Serialize a table to TOML: scalars and arrays first, then each nested
22
+ * table as a `[dotted.header]` section. Enough for the CLI config files
23
+ * this package writes (Codex and Mistral Vibe MCP sections).
24
+ *
25
+ * @example
26
+ * toToml({ mcp_servers: { docs: { command: "npx", args: ["-y", "docs-mcp"] } } });
27
+ * // [mcp_servers.docs]
28
+ * // command = "npx"
29
+ * // args = ["-y", "docs-mcp"]
30
+ */
31
+ function toToml(table, prefix = []) {
32
+ const lines = [];
33
+ const nested = [];
34
+ for (const [key, value] of Object.entries(table)) {
35
+ if (value === void 0) continue;
36
+ if (isTable(value)) {
37
+ nested.push([key, value]);
38
+ continue;
39
+ }
40
+ lines.push(`${tomlKey(key)} = ${inlineValue(value)}`);
41
+ }
42
+ const sections = [];
43
+ if (lines.length > 0) sections.push((prefix.length > 0 ? `[${prefix.map(tomlKey).join(".")}]\n` : "") + lines.join("\n"));
44
+ for (const [key, value] of nested) {
45
+ const section = toToml(value, [...prefix, key]);
46
+ if (section.length > 0) sections.push(section.trimEnd());
47
+ }
48
+ return sections.length > 0 ? `${sections.join("\n\n")}\n` : "";
49
+ }
50
+
51
+ //#endregion
52
+ export { toToml, tomlKey };
53
+ //# sourceMappingURL=toml.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toml.mjs","names":[],"sources":["../../../../../../../../packages/ai-cli/src/utils/toml.ts"],"sourcesContent":["/** A TOML value this writer supports. */\nexport type TomlValue = string | number | boolean | TomlValue[] | TomlTable;\n\n/** A TOML table. */\nexport type TomlTable = { [key: string]: TomlValue | undefined };\n\nfunction isTable(value: TomlValue): value is TomlTable {\n return typeof value === \"object\" && !Array.isArray(value);\n}\n\n/** A bare key when possible, else a quoted one. */\nexport function tomlKey(key: string): string {\n return /^[A-Za-z0-9_-]+$/.test(key) ? key : JSON.stringify(key);\n}\n\n/** A TOML scalar or inline value. JSON string escapes are valid TOML basic-string escapes. */\nfunction inlineValue(value: TomlValue): string {\n if (typeof value === \"string\") {\n return JSON.stringify(value);\n }\n\n if (typeof value === \"number\") {\n if (!Number.isFinite(value)) {\n throw new Error(\"TOML cannot encode a non-finite number\");\n }\n\n return String(value);\n }\n\n if (typeof value === \"boolean\") {\n return value ? \"true\" : \"false\";\n }\n\n if (Array.isArray(value)) {\n return `[${value.map(inlineValue).join(\", \")}]`;\n }\n\n const entries = Object.entries(value).filter(\n (entry): entry is [string, TomlValue] => entry[1] !== undefined,\n );\n\n return `{ ${entries.map(([key, item]) => `${tomlKey(key)} = ${inlineValue(item)}`).join(\", \")} }`;\n}\n\n/**\n * Serialize a table to TOML: scalars and arrays first, then each nested\n * table as a `[dotted.header]` section. Enough for the CLI config files\n * this package writes (Codex and Mistral Vibe MCP sections).\n *\n * @example\n * toToml({ mcp_servers: { docs: { command: \"npx\", args: [\"-y\", \"docs-mcp\"] } } });\n * // [mcp_servers.docs]\n * // command = \"npx\"\n * // args = [\"-y\", \"docs-mcp\"]\n */\nexport function toToml(table: TomlTable, prefix: string[] = []): string {\n const lines: string[] = [];\n const nested: Array<[string, TomlTable]> = [];\n\n for (const [key, value] of Object.entries(table)) {\n if (value === undefined) {\n continue;\n }\n\n if (isTable(value)) {\n nested.push([key, value]);\n continue;\n }\n\n lines.push(`${tomlKey(key)} = ${inlineValue(value)}`);\n }\n\n const sections: string[] = [];\n\n if (lines.length > 0) {\n sections.push(\n (prefix.length > 0 ? `[${prefix.map(tomlKey).join(\".\")}]\\n` : \"\") + lines.join(\"\\n\"),\n );\n }\n\n for (const [key, value] of nested) {\n const section = toToml(value, [...prefix, key]);\n\n if (section.length > 0) {\n sections.push(section.trimEnd());\n }\n }\n\n return sections.length > 0 ? `${sections.join(\"\\n\\n\")}\\n` : \"\";\n}\n"],"mappings":";AAMA,SAAS,QAAQ,OAAsC;CACrD,OAAO,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAC1D;;AAGA,SAAgB,QAAQ,KAAqB;CAC3C,OAAO,mBAAmB,KAAK,GAAG,IAAI,MAAM,KAAK,UAAU,GAAG;AAChE;;AAGA,SAAS,YAAY,OAA0B;CAC7C,IAAI,OAAO,UAAU,UACnB,OAAO,KAAK,UAAU,KAAK;CAG7B,IAAI,OAAO,UAAU,UAAU;EAC7B,IAAI,CAAC,OAAO,SAAS,KAAK,GACxB,MAAM,IAAI,MAAM,wCAAwC;EAG1D,OAAO,OAAO,KAAK;CACrB;CAEA,IAAI,OAAO,UAAU,WACnB,OAAO,QAAQ,SAAS;CAG1B,IAAI,MAAM,QAAQ,KAAK,GACrB,OAAO,IAAI,MAAM,IAAI,WAAW,CAAC,CAAC,KAAK,IAAI,EAAE;CAO/C,OAAO,KAJS,OAAO,QAAQ,KAAK,CAAC,CAAC,QACnC,UAAwC,MAAM,OAAO,MAGtC,CAAC,CAAC,KAAK,CAAC,KAAK,UAAU,GAAG,QAAQ,GAAG,EAAE,KAAK,YAAY,IAAI,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE;AAChG;;;;;;;;;;;;AAaA,SAAgB,OAAO,OAAkB,SAAmB,CAAC,GAAW;CACtE,MAAM,QAAkB,CAAC;CACzB,MAAM,SAAqC,CAAC;CAE5C,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,KAAK,GAAG;EAChD,IAAI,UAAU,QACZ;EAGF,IAAI,QAAQ,KAAK,GAAG;GAClB,OAAO,KAAK,CAAC,KAAK,KAAK,CAAC;GACxB;EACF;EAEA,MAAM,KAAK,GAAG,QAAQ,GAAG,EAAE,KAAK,YAAY,KAAK,GAAG;CACtD;CAEA,MAAM,WAAqB,CAAC;CAE5B,IAAI,MAAM,SAAS,GACjB,SAAS,MACN,OAAO,SAAS,IAAI,IAAI,OAAO,IAAI,OAAO,CAAC,CAAC,KAAK,GAAG,EAAE,OAAO,MAAM,MAAM,KAAK,IAAI,CACrF;CAGF,KAAK,MAAM,CAAC,KAAK,UAAU,QAAQ;EACjC,MAAM,UAAU,OAAO,OAAO,CAAC,GAAG,QAAQ,GAAG,CAAC;EAE9C,IAAI,QAAQ,SAAS,GACnB,SAAS,KAAK,QAAQ,QAAQ,CAAC;CAEnC;CAEA,OAAO,SAAS,SAAS,IAAI,GAAG,SAAS,KAAK,MAAM,EAAE,MAAM;AAC9D"}