@oh-my-pi/pi-utils 17.2.8 → 17.2.10

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 (89) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/dist/types/acp/connection.d.ts +118 -0
  3. package/dist/types/acp/protocol.d.ts +526 -0
  4. package/dist/types/acp/schema.d.ts +41 -0
  5. package/dist/types/acp/stream.d.ts +8 -0
  6. package/dist/types/acp/transport.d.ts +81 -0
  7. package/dist/types/acp.d.ts +6 -0
  8. package/dist/types/browsers.d.ts +68 -0
  9. package/dist/types/chalk.d.ts +125 -0
  10. package/dist/types/dates.d.ts +7 -0
  11. package/dist/types/docx/converter.d.ts +46 -0
  12. package/dist/types/docx/xml.d.ts +26 -0
  13. package/dist/types/docx/zip.d.ts +6 -0
  14. package/dist/types/docx.d.ts +11 -0
  15. package/dist/types/dom/core.d.ts +431 -0
  16. package/dist/types/dom/parser.d.ts +7 -0
  17. package/dist/types/dom/selector.d.ts +5 -0
  18. package/dist/types/dom.d.ts +5 -0
  19. package/dist/types/headers.d.ts +34 -0
  20. package/dist/types/index.d.ts +1 -0
  21. package/dist/types/logger/rotating-file.d.ts +18 -0
  22. package/dist/types/lru.d.ts +46 -0
  23. package/dist/types/marked/core.d.ts +445 -0
  24. package/dist/types/marked.d.ts +2 -0
  25. package/dist/types/postmortem.d.ts +14 -0
  26. package/dist/types/procmgr.d.ts +16 -0
  27. package/dist/types/prompt.d.ts +2 -2
  28. package/dist/types/readability/readability.d.ts +9 -0
  29. package/dist/types/readability/readerable.d.ts +10 -0
  30. package/dist/types/readability/types.d.ts +70 -0
  31. package/dist/types/readability.d.ts +4 -0
  32. package/dist/types/template.d.ts +62 -0
  33. package/dist/types/turndown/gfm.d.ts +11 -0
  34. package/dist/types/turndown/html.d.ts +5 -0
  35. package/dist/types/turndown/service.d.ts +21 -0
  36. package/dist/types/turndown/types.d.ts +70 -0
  37. package/dist/types/turndown.d.ts +4 -0
  38. package/dist/types/version.d.ts +18 -0
  39. package/dist/types/vterm/buffer.d.ts +99 -0
  40. package/dist/types/vterm/terminal.d.ts +44 -0
  41. package/dist/types/vterm.d.ts +8 -0
  42. package/dist/types/xml.d.ts +31 -0
  43. package/package.json +2 -5
  44. package/src/acp/connection.ts +344 -0
  45. package/src/acp/protocol.ts +466 -0
  46. package/src/acp/schema.ts +160 -0
  47. package/src/acp/stream.ts +82 -0
  48. package/src/acp/transport.ts +213 -0
  49. package/src/acp.ts +6 -0
  50. package/src/browsers.ts +501 -0
  51. package/src/chalk.ts +312 -0
  52. package/src/dates.ts +194 -0
  53. package/src/docx/converter.ts +681 -0
  54. package/src/docx/xml.ts +166 -0
  55. package/src/docx/zip.ts +87 -0
  56. package/src/docx.ts +20 -0
  57. package/src/dom/core.ts +1254 -0
  58. package/src/dom/parser.ts +370 -0
  59. package/src/dom/selector.ts +290 -0
  60. package/src/dom.ts +33 -0
  61. package/src/fetch-retry.ts +7 -1
  62. package/src/frontmatter.ts +1 -1
  63. package/src/headers.ts +167 -0
  64. package/src/index.ts +1 -0
  65. package/src/logger/rotating-file.ts +149 -0
  66. package/src/logger.ts +12 -28
  67. package/src/lru.ts +185 -0
  68. package/src/marked/core.ts +1576 -0
  69. package/src/marked.ts +2 -0
  70. package/src/postmortem.ts +44 -1
  71. package/src/procmgr.ts +21 -4
  72. package/src/prompt.ts +5 -22
  73. package/src/readability/readability.ts +533 -0
  74. package/src/readability/readerable.ts +51 -0
  75. package/src/readability/types.ts +72 -0
  76. package/src/readability.ts +11 -0
  77. package/src/template.ts +586 -0
  78. package/src/turndown/gfm.ts +106 -0
  79. package/src/turndown/html.ts +257 -0
  80. package/src/turndown/service.ts +334 -0
  81. package/src/turndown/types.ts +81 -0
  82. package/src/turndown.ts +5 -0
  83. package/src/version.ts +99 -0
  84. package/src/vterm/buffer.ts +218 -0
  85. package/src/vterm/terminal.ts +773 -0
  86. package/src/vterm.ts +8 -0
  87. package/src/which.ts +6 -4
  88. package/src/xml.ts +313 -0
  89. package/src/winston-daily-rotate-file.d.ts +0 -6
package/src/vterm.ts ADDED
@@ -0,0 +1,8 @@
1
+ /** Behavior-compatible reimplementation of @xterm/headless's used surface. */
2
+ export * from "./vterm/buffer";
3
+ export * from "./vterm/terminal";
4
+
5
+ import { Terminal } from "./vterm/terminal";
6
+
7
+ const vterm = { Terminal };
8
+ export default vterm;
package/src/which.ts CHANGED
@@ -183,8 +183,8 @@ export interface WhichOptions extends Bun.WhichOptions {
183
183
 
184
184
  // Darwin-specific "which" shim: consult Xcode/CLT toolchain directories after $PATH.
185
185
  // Uses cached directory listings instead of per-command existsSync or xcrun subprocesses.
186
- function darwinWhich(command: string, _options?: Bun.WhichOptions): string | null {
187
- const regular = Bun.which(command);
186
+ function darwinWhich(command: string, options?: Bun.WhichOptions): string | null {
187
+ const regular = Bun.which(command, options);
188
188
  if (regular) return regular;
189
189
  if (isXcodeBin(command)) {
190
190
  return getMacosToolPaths().get(command) ?? null;
@@ -214,17 +214,19 @@ function cacheKey(command: string, options?: Bun.WhichOptions): CacheKey {
214
214
  */
215
215
  export function $which(command: string, options?: WhichOptions): string | null {
216
216
  const cachePolicy = options?.cache ?? WhichCachePolicy.Cached;
217
+ const lookupOptions =
218
+ options?.PATH !== undefined || process.env.PATH === undefined ? options : { ...options, PATH: process.env.PATH };
217
219
  let key: CacheKey | undefined;
218
220
 
219
221
  if (cachePolicy !== WhichCachePolicy.Bypass) {
220
- key = cacheKey(command, options);
222
+ key = cacheKey(command, lookupOptions);
221
223
  if (cachePolicy !== WhichCachePolicy.Fresh) {
222
224
  const cached = toolCache.get(key);
223
225
  if (cached !== undefined) return cached;
224
226
  }
225
227
  }
226
228
 
227
- const result = whichFresh(command, options);
229
+ const result = whichFresh(command, lookupOptions);
228
230
  if (key != null && cachePolicy !== WhichCachePolicy.ReadOnly) {
229
231
  toolCache.set(key, result);
230
232
  }
package/src/xml.ts ADDED
@@ -0,0 +1,313 @@
1
+ /** Behavior-compatible reimplementation of fast-xml-parser's used surface. */
2
+
3
+ /** Context supplied to an array-selection callback. */
4
+ export type XMLArraySelector = (
5
+ tagName: string,
6
+ jPath: string,
7
+ isLeafNode: boolean,
8
+ isAttribute: boolean | null,
9
+ ) => boolean;
10
+
11
+ /** Options supported by {@link XMLParser}. */
12
+ export interface XMLParserOptions {
13
+ /** Omits attributes when true (default). */
14
+ ignoreAttributes?: boolean;
15
+ /** Prefix applied to attribute property names. */
16
+ attributeNamePrefix?: string;
17
+ /** Property used for text alongside children or attributes. */
18
+ textNodeName?: string;
19
+ /** Trims ordinary text and attribute values. */
20
+ trimValues?: boolean;
21
+ /** Coerces numeric and boolean element text. */
22
+ parseTagValue?: boolean;
23
+ /** Coerces numeric and boolean attribute values. */
24
+ parseAttributeValue?: boolean;
25
+ /** Controls entity processing and its expansion ceiling. */
26
+ processEntities?: boolean | { maxTotalExpansions?: number };
27
+ /** Selects element or attribute properties that must always be arrays. */
28
+ isArray?: XMLArraySelector;
29
+ }
30
+
31
+ type XmlObject = Record<string, unknown>;
32
+
33
+ const STANDARD_ENTITIES: Record<string, string> = { amp: "&", apos: "'", gt: ">", lt: "<", quot: '"' };
34
+
35
+ interface ParsedElement {
36
+ name: string;
37
+ value: unknown;
38
+ leaf: boolean;
39
+ }
40
+
41
+ interface ParserSettings {
42
+ ignoreAttributes: boolean;
43
+ attributeNamePrefix: string;
44
+ textNodeName: string;
45
+ trimValues: boolean;
46
+ parseTagValue: boolean;
47
+ parseAttributeValue: boolean;
48
+ processEntities: boolean;
49
+ maxTotalExpansions: number;
50
+ isArray?: XMLArraySelector;
51
+ }
52
+
53
+ /** Parses XML into the object shape used by the document converters. */
54
+ export class XMLParser {
55
+ readonly #settings: ParserSettings;
56
+
57
+ constructor(options: XMLParserOptions = {}) {
58
+ this.#settings = {
59
+ ignoreAttributes: options.ignoreAttributes ?? true,
60
+ attributeNamePrefix: options.attributeNamePrefix ?? "@_",
61
+ textNodeName: options.textNodeName ?? "#text",
62
+ trimValues: options.trimValues ?? true,
63
+ parseTagValue: options.parseTagValue ?? true,
64
+ parseAttributeValue: options.parseAttributeValue ?? false,
65
+ processEntities: options.processEntities !== false,
66
+ maxTotalExpansions:
67
+ typeof options.processEntities === "object"
68
+ ? (options.processEntities.maxTotalExpansions ?? 100_000)
69
+ : 100_000,
70
+ isArray: options.isArray,
71
+ };
72
+ }
73
+
74
+ /** Parses one XML document. */
75
+ parse(xml: string): unknown {
76
+ return new XmlReader(xml, this.#settings).parseDocument();
77
+ }
78
+ }
79
+
80
+ class XmlReader {
81
+ readonly #xml: string;
82
+ readonly #settings: ParserSettings;
83
+ readonly #entities = new Map<string, string>();
84
+ #position = 0;
85
+ #expansions = 0;
86
+
87
+ constructor(xml: string, settings: ParserSettings) {
88
+ this.#xml = xml.charCodeAt(0) === 0xfeff ? xml.slice(1) : xml;
89
+ this.#settings = settings;
90
+ }
91
+
92
+ parseDocument(): XmlObject {
93
+ const document: XmlObject = {};
94
+ while (this.#position < this.#xml.length) {
95
+ if (this.#xml.startsWith("<!--", this.#position)) {
96
+ this.#skipThrough("-->");
97
+ continue;
98
+ }
99
+ if (this.#xml.startsWith("<!DOCTYPE", this.#position)) {
100
+ this.#readDoctype();
101
+ continue;
102
+ }
103
+ if (this.#xml.startsWith("<?", this.#position)) {
104
+ this.#readProcessingInstruction(document);
105
+ continue;
106
+ }
107
+ if (this.#xml[this.#position] === "<") {
108
+ const element = this.#readElement("");
109
+ this.#addValue(document, element.name, element.name, element.value, element.leaf, null);
110
+ continue;
111
+ }
112
+ this.#position++;
113
+ }
114
+ return document;
115
+ }
116
+
117
+ #readElement(parentPath: string): ParsedElement {
118
+ this.#position++;
119
+ const name = this.#readName();
120
+ const path = parentPath ? `${parentPath}.${name}` : name;
121
+ const attributes: [string, string][] = [];
122
+ let selfClosing = false;
123
+ while (this.#position < this.#xml.length) {
124
+ this.#skipWhitespace();
125
+ if (this.#xml.startsWith("/>", this.#position)) {
126
+ this.#position += 2;
127
+ selfClosing = true;
128
+ break;
129
+ }
130
+ if (this.#xml[this.#position] === ">") {
131
+ this.#position++;
132
+ break;
133
+ }
134
+ const attributeName = this.#readName();
135
+ this.#skipWhitespace();
136
+ let value = "true";
137
+ if (this.#xml[this.#position] === "=") {
138
+ this.#position++;
139
+ this.#skipWhitespace();
140
+ value = this.#readAttributeValue();
141
+ }
142
+ attributes.push([attributeName, value]);
143
+ }
144
+
145
+ const children: XmlObject = {};
146
+ let text = "";
147
+ let hasChildren = false;
148
+ if (!selfClosing) {
149
+ while (this.#position < this.#xml.length) {
150
+ if (this.#xml.startsWith(`</${name}`, this.#position)) {
151
+ this.#position += name.length + 2;
152
+ const close = this.#xml.indexOf(">", this.#position);
153
+ this.#position = close < 0 ? this.#xml.length : close + 1;
154
+ break;
155
+ }
156
+ if (this.#xml.startsWith("<![CDATA[", this.#position)) {
157
+ const end = this.#xml.indexOf("]]>", this.#position + 9);
158
+ const raw = this.#xml.slice(this.#position + 9, end < 0 ? this.#xml.length : end);
159
+ const normalized = raw;
160
+ text += this.#settings.parseTagValue ? String(coerceValue(normalized)) : normalized;
161
+ this.#position = end < 0 ? this.#xml.length : end + 3;
162
+ continue;
163
+ }
164
+ if (this.#xml.startsWith("<!--", this.#position)) {
165
+ this.#skipThrough("-->");
166
+ continue;
167
+ }
168
+ if (this.#xml.startsWith("<?", this.#position)) {
169
+ this.#skipThrough("?>");
170
+ continue;
171
+ }
172
+ if (this.#xml[this.#position] === "<") {
173
+ const child = this.#readElement(path);
174
+ hasChildren = true;
175
+ this.#addValue(children, child.name, `${path}.${child.name}`, child.value, child.leaf, null);
176
+ continue;
177
+ }
178
+ const next = this.#xml.indexOf("<", this.#position);
179
+ const end = next < 0 ? this.#xml.length : next;
180
+ const normalized = this.#normalizeText(this.#xml.slice(this.#position, end), true);
181
+ text += this.#settings.parseTagValue ? String(coerceValue(normalized)) : normalized;
182
+ this.#position = end;
183
+ }
184
+ }
185
+
186
+ const hasAttributes = !this.#settings.ignoreAttributes && attributes.length > 0;
187
+ const parsedText = this.#settings.parseTagValue ? coerceValue(text) : text;
188
+ if (!hasChildren && !hasAttributes) return { name, value: parsedText, leaf: true };
189
+ if (text !== "") children[this.#settings.textNodeName] = parsedText;
190
+ if (hasAttributes) {
191
+ for (const [attributeName, raw] of attributes) {
192
+ const key = `${this.#settings.attributeNamePrefix}${attributeName}`;
193
+ const value = this.#settings.parseAttributeValue ? coerceValue(raw) : raw;
194
+ this.#addValue(children, key, `${path}.${attributeName}`, value, true, true);
195
+ }
196
+ }
197
+ return { name, value: children, leaf: !hasChildren };
198
+ }
199
+
200
+ #readAttributeValue(): string {
201
+ const quote = this.#xml[this.#position];
202
+ if (quote === '"' || quote === "'") {
203
+ const start = ++this.#position;
204
+ const end = this.#xml.indexOf(quote, start);
205
+ this.#position = end < 0 ? this.#xml.length : end + 1;
206
+ return this.#normalizeText(this.#xml.slice(start, end < 0 ? this.#xml.length : end), true);
207
+ }
208
+ const start = this.#position;
209
+ while (this.#position < this.#xml.length && !/[\s>]/.test(this.#xml[this.#position])) this.#position++;
210
+ return this.#normalizeText(this.#xml.slice(start, this.#position), true);
211
+ }
212
+
213
+ #readProcessingInstruction(target: XmlObject): void {
214
+ this.#position += 2;
215
+ const name = this.#readName();
216
+ const bodyStart = this.#position;
217
+ const end = this.#xml.indexOf("?>", bodyStart);
218
+ const body = this.#xml.slice(bodyStart, end < 0 ? this.#xml.length : end);
219
+ this.#position = end < 0 ? this.#xml.length : end + 2;
220
+ const value: XmlObject = {};
221
+ let hasAttribute = false;
222
+ const attributePattern = /([^\s=]+)\s*=\s*(["'])(.*?)\2/g;
223
+ for (const match of body.matchAll(attributePattern)) {
224
+ if (!this.#settings.ignoreAttributes) {
225
+ value[`${this.#settings.attributeNamePrefix}${match[1]}`] = this.#normalizeText(match[3]!, true);
226
+ hasAttribute = true;
227
+ }
228
+ }
229
+ target[`?${name}`] = hasAttribute ? value : "";
230
+ }
231
+
232
+ #readDoctype(): void {
233
+ const start = this.#position;
234
+ let bracketDepth = 0;
235
+ let quote = "";
236
+ while (this.#position < this.#xml.length) {
237
+ const char = this.#xml[this.#position++];
238
+ if (quote) {
239
+ if (char === quote) quote = "";
240
+ } else if (char === '"' || char === "'") quote = char;
241
+ else if (char === "[") bracketDepth++;
242
+ else if (char === "]") bracketDepth--;
243
+ else if (char === ">" && bracketDepth === 0) break;
244
+ }
245
+ const declaration = this.#xml.slice(start, this.#position);
246
+ const entityPattern = /<!ENTITY\s+([^\s]+)\s+(["'])(.*?)\2\s*>/gs;
247
+ for (const match of declaration.matchAll(entityPattern)) this.#entities.set(match[1]!, match[3]!);
248
+ }
249
+
250
+ #normalizeText(value: string, entities: boolean): string {
251
+ let normalized = this.#settings.trimValues ? value.trim() : value;
252
+ if (entities && this.#settings.processEntities && normalized.includes("&"))
253
+ normalized = this.#expandEntities(normalized);
254
+ return normalized;
255
+ }
256
+
257
+ #expandEntities(value: string, stack?: ReadonlySet<string>): string {
258
+ return value.replace(/&([A-Za-z_:][\w.:-]*);/g, (whole, name: string) => {
259
+ const standard = STANDARD_ENTITIES[name];
260
+ if (standard !== undefined) return standard;
261
+ const replacement = this.#entities.get(name);
262
+ if (replacement === undefined || stack?.has(name)) return whole;
263
+ this.#expansions++;
264
+ if (this.#expansions > this.#settings.maxTotalExpansions) throw new Error("Entity expansion limit exceeded");
265
+ const nextStack = new Set(stack);
266
+ nextStack.add(name);
267
+ return this.#expandEntities(replacement, nextStack);
268
+ });
269
+ }
270
+
271
+ #addValue(
272
+ target: XmlObject,
273
+ name: string,
274
+ path: string,
275
+ value: unknown,
276
+ leaf: boolean,
277
+ attribute: boolean | null,
278
+ ): void {
279
+ const present = Object.hasOwn(target, name);
280
+ if (present) {
281
+ const current = target[name];
282
+ if (Array.isArray(current)) current.push(value);
283
+ else target[name] = [current, value];
284
+ return;
285
+ }
286
+ const forceArray = this.#settings.isArray?.(name, path, leaf, attribute) ?? false;
287
+ target[name] = forceArray ? [value] : value;
288
+ }
289
+
290
+ #readName(): string {
291
+ const start = this.#position;
292
+ while (this.#position < this.#xml.length && !/[\s/>=]/.test(this.#xml[this.#position])) this.#position++;
293
+ return this.#xml.slice(start, this.#position);
294
+ }
295
+
296
+ #skipWhitespace(): void {
297
+ while (this.#position < this.#xml.length && /\s/.test(this.#xml[this.#position])) this.#position++;
298
+ }
299
+
300
+ #skipThrough(marker: string): void {
301
+ const end = this.#xml.indexOf(marker, this.#position + marker.length);
302
+ this.#position = end < 0 ? this.#xml.length : end + marker.length;
303
+ }
304
+ }
305
+
306
+ function coerceValue(value: string): unknown {
307
+ if (value === "true") return true;
308
+ if (value === "false") return false;
309
+ if (value !== "" && /^[+-]?(?:0[xX][\da-fA-F]+|(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][+-]?\d+)?)$/.test(value)) {
310
+ return Number(value);
311
+ }
312
+ return value;
313
+ }
@@ -1,6 +0,0 @@
1
- declare module "winston-daily-rotate-file/daily-rotate-file.js" {
2
- import type DailyRotateFile from "winston-daily-rotate-file";
3
-
4
- const DailyRotateFileImplementation: typeof DailyRotateFile;
5
- export default DailyRotateFileImplementation;
6
- }