pi-ghost-autocomplete 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +236 -0
  2. package/dist/bench-cli.d.ts +3 -0
  3. package/dist/bench-cli.d.ts.map +1 -0
  4. package/dist/bench-cli.js +48 -0
  5. package/dist/bench-cli.js.map +1 -0
  6. package/dist/bench.d.ts +93 -0
  7. package/dist/bench.d.ts.map +1 -0
  8. package/dist/bench.js +241 -0
  9. package/dist/bench.js.map +1 -0
  10. package/dist/config.d.ts +55 -0
  11. package/dist/config.d.ts.map +1 -0
  12. package/dist/config.js +187 -0
  13. package/dist/config.js.map +1 -0
  14. package/dist/context-aggregator.d.ts +14 -0
  15. package/dist/context-aggregator.d.ts.map +1 -0
  16. package/dist/context-aggregator.js +58 -0
  17. package/dist/context-aggregator.js.map +1 -0
  18. package/dist/fuzzy-matcher.d.ts +50 -0
  19. package/dist/fuzzy-matcher.d.ts.map +1 -0
  20. package/dist/fuzzy-matcher.js +160 -0
  21. package/dist/fuzzy-matcher.js.map +1 -0
  22. package/dist/ghost-editor.d.ts +65 -0
  23. package/dist/ghost-editor.d.ts.map +1 -0
  24. package/dist/ghost-editor.js +445 -0
  25. package/dist/ghost-editor.js.map +1 -0
  26. package/dist/index.d.ts +25 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +210 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/metrics.d.ts +56 -0
  31. package/dist/metrics.d.ts.map +1 -0
  32. package/dist/metrics.js +98 -0
  33. package/dist/metrics.js.map +1 -0
  34. package/dist/path-index.d.ts +20 -0
  35. package/dist/path-index.d.ts.map +1 -0
  36. package/dist/path-index.js +148 -0
  37. package/dist/path-index.js.map +1 -0
  38. package/dist/path-matcher.d.ts +32 -0
  39. package/dist/path-matcher.d.ts.map +1 -0
  40. package/dist/path-matcher.js +85 -0
  41. package/dist/path-matcher.js.map +1 -0
  42. package/dist/providers/cloud-provider.d.ts +10 -0
  43. package/dist/providers/cloud-provider.d.ts.map +1 -0
  44. package/dist/providers/cloud-provider.js +52 -0
  45. package/dist/providers/cloud-provider.js.map +1 -0
  46. package/dist/providers/local-provider.d.ts +11 -0
  47. package/dist/providers/local-provider.d.ts.map +1 -0
  48. package/dist/providers/local-provider.js +36 -0
  49. package/dist/providers/local-provider.js.map +1 -0
  50. package/dist/providers/openai-compat-provider.d.ts +29 -0
  51. package/dist/providers/openai-compat-provider.d.ts.map +1 -0
  52. package/dist/providers/openai-compat-provider.js +128 -0
  53. package/dist/providers/openai-compat-provider.js.map +1 -0
  54. package/dist/providers/openai-completions-runner.d.ts +28 -0
  55. package/dist/providers/openai-completions-runner.d.ts.map +1 -0
  56. package/dist/providers/openai-completions-runner.js +46 -0
  57. package/dist/providers/openai-completions-runner.js.map +1 -0
  58. package/dist/providers/race.d.ts +40 -0
  59. package/dist/providers/race.d.ts.map +1 -0
  60. package/dist/providers/race.js +128 -0
  61. package/dist/providers/race.js.map +1 -0
  62. package/dist/providers/truncate.d.ts +7 -0
  63. package/dist/providers/truncate.d.ts.map +1 -0
  64. package/dist/providers/truncate.js +39 -0
  65. package/dist/providers/truncate.js.map +1 -0
  66. package/dist/providers/types.d.ts +18 -0
  67. package/dist/providers/types.d.ts.map +1 -0
  68. package/dist/providers/types.js +2 -0
  69. package/dist/providers/types.js.map +1 -0
  70. package/dist/recent-paths.d.ts +25 -0
  71. package/dist/recent-paths.d.ts.map +1 -0
  72. package/dist/recent-paths.js +114 -0
  73. package/dist/recent-paths.js.map +1 -0
  74. package/package.json +79 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"race.js","sourceRoot":"","sources":["../../src/providers/race.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { GhostRequest } from "./types.js";
2
+ export declare function buildPromptMessages(req: GhostRequest, maxRecent: number): {
3
+ systemPrompt: string;
4
+ user: string;
5
+ };
6
+ export declare function sanitizeCompletion(raw: string, draft: string, maxLen: number): string | null;
7
+ //# sourceMappingURL=truncate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"truncate.d.ts","sourceRoot":"","sources":["../../src/providers/truncate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAQ/C,wBAAgB,mBAAmB,CAClC,GAAG,EAAE,YAAY,EACjB,SAAS,EAAE,MAAM,GACf;IAAE,YAAY,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAKxC;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAoB5F"}
@@ -0,0 +1,39 @@
1
+ const SYSTEM_PROMPT = "You are a terminal autocomplete engine. The user is typing a prompt for an AI coding agent. " +
2
+ "Predict the most likely continuation of the current line — at most one short phrase, no more than 12 words. " +
3
+ "Output ONLY the continuation text, with no quotes, no markdown, no leading whitespace, no explanation. " +
4
+ "If you cannot confidently continue, output an empty string.";
5
+ export function buildPromptMessages(req, maxRecent) {
6
+ const recent = req.recentMessages.slice(-maxRecent).map((m) => `${m.role}: ${truncate(m.text, 280)}`).join("\n");
7
+ const ctx = recent ? `Recent conversation:\n${recent}\n\n` : "";
8
+ const user = `${ctx}Current draft (cursor at end):\n${req.editorTextBeforeCursor}`;
9
+ return { systemPrompt: SYSTEM_PROMPT, user };
10
+ }
11
+ export function sanitizeCompletion(raw, draft, maxLen) {
12
+ let out = raw;
13
+ out = out.replace(/^[\s\r\n]+/, "");
14
+ const newlineIdx = out.indexOf("\n");
15
+ if (newlineIdx >= 0)
16
+ out = out.slice(0, newlineIdx);
17
+ out = out.replace(/^["'`](.*)["'`]$/, "$1");
18
+ if (!out)
19
+ return null;
20
+ const draftTail = draft.split(/\s+/).pop() ?? "";
21
+ if (draftTail) {
22
+ const lower = out.toLowerCase();
23
+ const tail = draftTail.toLowerCase();
24
+ if (lower === tail)
25
+ return null;
26
+ if (lower.startsWith(tail) && out.length > draftTail.length) {
27
+ out = out.slice(draftTail.length);
28
+ }
29
+ }
30
+ if (!out)
31
+ return null;
32
+ if (out.length > maxLen)
33
+ out = out.slice(0, maxLen);
34
+ return out;
35
+ }
36
+ function truncate(s, n) {
37
+ return s.length > n ? `${s.slice(0, n)}…` : s;
38
+ }
39
+ //# sourceMappingURL=truncate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"truncate.js","sourceRoot":"","sources":["../../src/providers/truncate.ts"],"names":[],"mappings":"AAEA,MAAM,aAAa,GAClB,8FAA8F;IAC9F,8GAA8G;IAC9G,yGAAyG;IACzG,6DAA6D,CAAC;AAE/D,MAAM,UAAU,mBAAmB,CAClC,GAAiB,EACjB,SAAiB;IAEjB,MAAM,MAAM,GAAG,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjH,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,yBAAyB,MAAM,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAChE,MAAM,IAAI,GAAG,GAAG,GAAG,mCAAmC,GAAG,CAAC,sBAAsB,EAAE,CAAC;IACnF,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAW,EAAE,KAAa,EAAE,MAAc;IAC5E,IAAI,GAAG,GAAG,GAAG,CAAC;IACd,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IACpC,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,UAAU,IAAI,CAAC;QAAE,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IACpD,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,CAAC;IAC5C,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IAEtB,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;IACjD,IAAI,SAAS,EAAE,CAAC;QACf,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC;QACrC,IAAI,KAAK,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QAChC,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC;YAC7D,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC;IACF,CAAC;IACD,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,IAAI,GAAG,CAAC,MAAM,GAAG,MAAM;QAAE,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACpD,OAAO,GAAG,CAAC;AACZ,CAAC;AAED,SAAS,QAAQ,CAAC,CAAS,EAAE,CAAS;IACrC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { PreflightResult } from "./openai-compat-provider.js";
2
+ export interface GhostRequest {
3
+ editorText: string;
4
+ editorTextBeforeCursor: string;
5
+ recentMessages: Array<{
6
+ role: "user" | "assistant";
7
+ text: string;
8
+ }>;
9
+ cwd: string;
10
+ signal: AbortSignal;
11
+ }
12
+ export interface GhostProvider {
13
+ readonly name: string;
14
+ readonly debounceMs: number;
15
+ predict(req: GhostRequest): Promise<string | null>;
16
+ preflight?(): Promise<boolean | PreflightResult>;
17
+ }
18
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAEnE,MAAM,WAAW,YAAY;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,cAAc,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpE,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,WAAW,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACnD,SAAS,CAAC,IAAI,OAAO,CAAC,OAAO,GAAG,eAAe,CAAC,CAAC;CACjD"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,25 @@
1
+ import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
2
+ import { type RecentMessage } from "./context-aggregator.js";
3
+ /**
4
+ * Extract path-like mentions from recent conversation messages. Returns a Set
5
+ * of distinct tokens — full paths (e.g. `src/foo.ts`) and bare filenames with
6
+ * code extensions (e.g. `foo.ts`).
7
+ *
8
+ * Conservative on purpose: triggers ranking boosts only, so noisy mentions
9
+ * just degrade to no-op rather than producing wrong completions.
10
+ */
11
+ export declare function extractRecentPaths(messages: RecentMessage[]): Set<string>;
12
+ /**
13
+ * Score boost for a matched path given the recent-mention set.
14
+ * - exact full-path hit: +10
15
+ * - basename hit: +7
16
+ * - otherwise: 0
17
+ */
18
+ export declare function recentBoost(matchPath: string, recent: Set<string> | null): number;
19
+ /**
20
+ * Read role-weighted recent messages tailored for path-mention extraction:
21
+ * up to `userMax` most-recent user messages and `assistantMax` most-recent
22
+ * assistant messages. Oldest-first.
23
+ */
24
+ export declare function getRoleWeightedRecent(ctx: ExtensionContext, userMax: number, assistantMax: number): RecentMessage[];
25
+ //# sourceMappingURL=recent-paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recent-paths.d.ts","sourceRoot":"","sources":["../src/recent-paths.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAgB,MAAM,iCAAiC,CAAC;AAEtF,OAAO,EAAe,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAkB1E;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAoBzE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,MAAM,CAOjF;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACpC,GAAG,EAAE,gBAAgB,EACrB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,GAClB,aAAa,EAAE,CAiCjB"}
@@ -0,0 +1,114 @@
1
+ import { extractText } from "./context-aggregator.js";
2
+ const PER_MESSAGE_CAP = 4000;
3
+ // A token containing at least one `/` that looks like a path: leading
4
+ // whitespace/quote/paren/bracket boundary, then path chars across one or more
5
+ // segments.
6
+ const SLASHED_PATH = /(?:^|[\s"'`(\[{])([A-Za-z0-9_.\-][A-Za-z0-9_.\-]*(?:\/[A-Za-z0-9_.\-]+)+)/g;
7
+ // Backticked single-token contents; we accept them as a path mention if they
8
+ // look path-like (slash or dot).
9
+ const BACKTICKED = /`([^`\n]{1,200})`/g;
10
+ // Bare filename with a known code extension. Conservative list to limit
11
+ // false positives during normal English writing.
12
+ const FILENAME_EXT = /\b([A-Za-z0-9_\-]+\.(?:ts|tsx|js|jsx|mjs|cjs|md|json|py|go|rs|java|kt|swift|c|h|cc|cpp|hpp|sh|bash|zsh|yml|yaml|toml|ini|css|scss|html|xml|sql|rb|php|lua))\b/g;
13
+ const PATHLIKE = /^[A-Za-z0-9_./@\-]+$/;
14
+ /**
15
+ * Extract path-like mentions from recent conversation messages. Returns a Set
16
+ * of distinct tokens — full paths (e.g. `src/foo.ts`) and bare filenames with
17
+ * code extensions (e.g. `foo.ts`).
18
+ *
19
+ * Conservative on purpose: triggers ranking boosts only, so noisy mentions
20
+ * just degrade to no-op rather than producing wrong completions.
21
+ */
22
+ export function extractRecentPaths(messages) {
23
+ const out = new Set();
24
+ for (const m of messages) {
25
+ const text = m.text.length > PER_MESSAGE_CAP ? m.text.slice(0, PER_MESSAGE_CAP) : m.text;
26
+ for (const match of text.matchAll(SLASHED_PATH)) {
27
+ const tok = match[1];
28
+ if (tok)
29
+ out.add(tok);
30
+ }
31
+ for (const match of text.matchAll(BACKTICKED)) {
32
+ const raw = match[1]?.trim();
33
+ if (raw && raw.length <= 200 && !raw.includes(" ") && PATHLIKE.test(raw) && /[/.]/.test(raw)) {
34
+ out.add(raw);
35
+ }
36
+ }
37
+ for (const match of text.matchAll(FILENAME_EXT)) {
38
+ const tok = match[1];
39
+ if (tok)
40
+ out.add(tok);
41
+ }
42
+ }
43
+ return out;
44
+ }
45
+ /**
46
+ * Score boost for a matched path given the recent-mention set.
47
+ * - exact full-path hit: +10
48
+ * - basename hit: +7
49
+ * - otherwise: 0
50
+ */
51
+ export function recentBoost(matchPath, recent) {
52
+ if (!recent || recent.size === 0)
53
+ return 0;
54
+ if (recent.has(matchPath))
55
+ return 10;
56
+ const i = matchPath.lastIndexOf("/");
57
+ const bn = i < 0 ? matchPath : matchPath.slice(i + 1);
58
+ if (recent.has(bn))
59
+ return 7;
60
+ return 0;
61
+ }
62
+ /**
63
+ * Read role-weighted recent messages tailored for path-mention extraction:
64
+ * up to `userMax` most-recent user messages and `assistantMax` most-recent
65
+ * assistant messages. Oldest-first.
66
+ */
67
+ export function getRoleWeightedRecent(ctx, userMax, assistantMax) {
68
+ if (userMax <= 0 && assistantMax <= 0)
69
+ return [];
70
+ let branch;
71
+ try {
72
+ branch = ctx.sessionManager.getBranch();
73
+ }
74
+ catch {
75
+ return [];
76
+ }
77
+ if (!branch)
78
+ return [];
79
+ const out = [];
80
+ let userTaken = 0;
81
+ let assistantTaken = 0;
82
+ for (let i = branch.length - 1; i >= 0; i--) {
83
+ if (userTaken >= userMax && assistantTaken >= assistantMax)
84
+ break;
85
+ const entry = branch[i];
86
+ if (!entry || entry.type !== "message")
87
+ continue;
88
+ const role = roleOf(entry.message);
89
+ if (role === "user" && userTaken < userMax) {
90
+ const text = extractText(entry.message);
91
+ if (text) {
92
+ out.push({ role, text });
93
+ userTaken++;
94
+ }
95
+ }
96
+ else if (role === "assistant" && assistantTaken < assistantMax) {
97
+ const text = extractText(entry.message);
98
+ if (text) {
99
+ out.push({ role, text });
100
+ assistantTaken++;
101
+ }
102
+ }
103
+ }
104
+ out.reverse();
105
+ return out;
106
+ }
107
+ function roleOf(msg) {
108
+ if (msg && typeof msg === "object" && "role" in msg && typeof msg.role === "string") {
109
+ if (msg.role === "user" || msg.role === "assistant")
110
+ return msg.role;
111
+ }
112
+ return undefined;
113
+ }
114
+ //# sourceMappingURL=recent-paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recent-paths.js","sourceRoot":"","sources":["../src/recent-paths.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,79 @@
1
+ {
2
+ "name": "pi-ghost-autocomplete",
3
+ "version": "0.3.1",
4
+ "description": "Inline ghost-text autocomplete extension for the Pi coding agent (pi.dev). Cloud and local LLM providers, zero-flicker rendering, no popup interference.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "bin": {
9
+ "pi-ghost-bench": "./dist/bench-cli.js"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js"
15
+ },
16
+ "./bench": {
17
+ "types": "./dist/bench.d.ts",
18
+ "import": "./dist/bench.js"
19
+ }
20
+ },
21
+ "files": [
22
+ "dist",
23
+ "README.md"
24
+ ],
25
+ "scripts": {
26
+ "clean": "node -e \"fs.rmSync('dist',{recursive:true,force:true})\"",
27
+ "build": "tsc -p tsconfig.json",
28
+ "typecheck": "tsc -p tsconfig.json --noEmit",
29
+ "test": "vitest run",
30
+ "test:watch": "vitest",
31
+ "prepublishOnly": "npm run clean && npm run build"
32
+ },
33
+ "engines": {
34
+ "node": ">=20.0.0"
35
+ },
36
+ "pi": {
37
+ "extensions": [
38
+ "./dist/index.js"
39
+ ]
40
+ },
41
+ "author": "Alessandro",
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "https://github.com/pungggi/pi-ghost-autocomplete"
45
+ },
46
+ "homepage": "https://github.com/pungggi/pi-ghost-autocomplete#readme",
47
+ "license": "MIT",
48
+ "keywords": [
49
+ "pi",
50
+ "pi.dev",
51
+ "pi-package",
52
+ "pi-extension",
53
+ "autocomplete",
54
+ "ghost-text",
55
+ "tui",
56
+ "llm",
57
+ "ollama",
58
+ "groq"
59
+ ],
60
+ "peerDependencies": {
61
+ "@earendil-works/pi-agent-core": "^0.74.0",
62
+ "@earendil-works/pi-ai": "^0.74.0",
63
+ "@earendil-works/pi-coding-agent": "^0.74.0",
64
+ "@earendil-works/pi-tui": "^0.74.0"
65
+ },
66
+ "devDependencies": {
67
+ "@earendil-works/pi-agent-core": "^0.74.0",
68
+ "@earendil-works/pi-ai": "^0.74.0",
69
+ "@earendil-works/pi-coding-agent": "^0.74.0",
70
+ "@earendil-works/pi-tui": "^0.74.0",
71
+ "@types/node": "^20.11.0",
72
+ "typescript": "^5.4.0",
73
+ "vitest": "^1.6.1"
74
+ },
75
+ "dependencies": {
76
+ "string-width": "^7.2.0",
77
+ "strip-ansi": "^7.2.0"
78
+ }
79
+ }