pi-repl-py 0.1.1 → 0.2.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.
- package/README.md +22 -22
- package/docs/ARCHITECTURE.md +128 -88
- package/docs/helpers.md +110 -0
- package/docs/philosophy.md +67 -59
- package/index.ts +4 -22
- package/package.json +5 -6
- package/scripts/setup-venv.mjs +39 -17
- package/src/engine/index.ts +90 -424
- package/src/engine/kernel.ts +598 -0
- package/src/engine/session.ts +149 -0
- package/src/engine/zmtp.ts +251 -0
- package/src/extension/helpers.ts +46 -0
- package/src/extension/preview/candidates.ts +7 -53
- package/src/extension/preview/descriptor.ts +2 -2
- package/src/extension/preview/index.ts +3 -11
- package/src/extension/preview/shell.ts +4 -4
- package/src/extension/preview/types.ts +1 -1
- package/src/extension/prompt.ts +67 -45
- package/src/extension/render-core.ts +5 -9
- package/src/extension/render.ts +2 -11
- package/src/extension/session-engine.ts +9 -31
- package/src/extension/tool-meta.ts +6 -6
- package/docs/how-to-functions.md +0 -108
- package/src/engine/guest.py +0 -320
- package/src/engine/protocol.ts +0 -66
- package/src/engine/toolbox/bash.py +0 -72
- package/src/engine/toolbox/edit.py +0 -37
- package/src/engine/toolbox/read.py +0 -26
- package/src/engine/toolbox/write.py +0 -23
- package/src/extension/config.ts +0 -64
- package/src/extension/preview-core.ts +0 -2
- package/src/extension/toolbox.ts +0 -98
package/src/extension/toolbox.ts
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Loads the toolbox functions from the toolbox directory.
|
|
3
|
-
*
|
|
4
|
-
* The prompt-facing function map is derived from the real source, never
|
|
5
|
-
* hard-coded: each function's `def <name>(<args>)` line supplies the signature
|
|
6
|
-
* (authoritative) and the `function_description = """..."""` docstring supplies
|
|
7
|
-
* the one-line "what it does". Same contract the guest's `ls()`/`help()` uses,
|
|
8
|
-
* so what the prompt advertises always matches what the kernel loaded.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
12
|
-
import { homedir } from "node:os";
|
|
13
|
-
import { join } from "node:path";
|
|
14
|
-
|
|
15
|
-
interface ToolEntry {
|
|
16
|
-
name: string;
|
|
17
|
-
call: string; // e.g. "read(path, offset=1, limit=None)"
|
|
18
|
-
description: string; // first line of function_description, "" if absent
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/** Read a `function_description = """..."""` value; keep its first line. */
|
|
22
|
-
function parseDescription(source: string): string {
|
|
23
|
-
const m = source.match(/function_description\s*=\s*"""\s*([^\n]*)/);
|
|
24
|
-
if (!m) return "";
|
|
25
|
-
return m[1].replace(/"""\s*$/, "").trim();
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/** Regex the call signature from `def name(args):`. */
|
|
29
|
-
function parseDefCall(source: string): string | null {
|
|
30
|
-
const m = source.match(/def\s+([A-Za-z_]\w*)\s*\(([^)]*)\)/);
|
|
31
|
-
if (!m) return null;
|
|
32
|
-
const name = m[1];
|
|
33
|
-
const args = m[2].trim();
|
|
34
|
-
return args ? `${name}(${args})` : `${name}()`;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Default toolbox directory: the shipped src/engine/toolbox. Resolved at
|
|
39
|
-
* runtime via the module path so it stays correct after packaging.
|
|
40
|
-
*/
|
|
41
|
-
function defaultToolboxDir(): string {
|
|
42
|
-
return join(import.meta.dirname, "..", "..", "src", "engine", "toolbox");
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/** Expand a leading `~` to the user's home, matching the guest's expanduser. */
|
|
46
|
-
function expandTilde(p: string): string {
|
|
47
|
-
const home = homedir();
|
|
48
|
-
if (p === "~" || p === "~/") return home;
|
|
49
|
-
if (p.startsWith("~/") || p.startsWith("~\\")) return join(home, p.slice(2));
|
|
50
|
-
return p;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/** Resolve a toolbox dir the way the config intends (expand ~, missing → shipped default). */
|
|
54
|
-
function toolboxDir(dir: string | undefined): string {
|
|
55
|
-
return dir && dir.trim().length > 0 ? expandTilde(dir.trim()) : defaultToolboxDir();
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/** Load {function_name → entry} for each non-underscore *.py in `dir`. */
|
|
59
|
-
function loadToolboxEntries(dir: string | undefined): ToolEntry[] {
|
|
60
|
-
const d = toolboxDir(dir);
|
|
61
|
-
if (!existsSync(d)) return [];
|
|
62
|
-
const entries: ToolEntry[] = [];
|
|
63
|
-
for (const file of readdirSync(d).sort()) {
|
|
64
|
-
if (!file.endsWith(".py")) continue;
|
|
65
|
-
const name = file.slice(0, -3);
|
|
66
|
-
if (!/^[A-Za-z_]\w*$/.test(name)) continue;
|
|
67
|
-
// --- underscore-prefixed files are neither loaded nor advertised ---
|
|
68
|
-
if (name.startsWith("_")) continue;
|
|
69
|
-
try {
|
|
70
|
-
const source = readFileSync(join(d, file), "utf8");
|
|
71
|
-
const call = parseDefCall(source);
|
|
72
|
-
if (!call) continue;
|
|
73
|
-
entries.push({ name, call, description: parseDescription(source) });
|
|
74
|
-
} catch {}
|
|
75
|
-
}
|
|
76
|
-
return entries;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* The shipped built-in function set, always present (the canonical toolbox).
|
|
81
|
-
*/
|
|
82
|
-
function builtInEntries(): ToolEntry[] {
|
|
83
|
-
return loadToolboxEntries(undefined);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* The effective function map: the shipped built-ins are supreme (always
|
|
88
|
-
* present); the config `toolboxDir`, if set, adds any extra function and, when
|
|
89
|
-
* a name collides, overrides the built-in one. `~` is resolved like the guest.
|
|
90
|
-
*/
|
|
91
|
-
export function buildToolboxMap(dir: string | undefined): string[] {
|
|
92
|
-
const byName = new Map<string, ToolEntry>();
|
|
93
|
-
for (const e of builtInEntries()) byName.set(e.name, e);
|
|
94
|
-
if (dir && dir.trim().length > 0 && toolboxDir(dir) !== defaultToolboxDir()) {
|
|
95
|
-
for (const e of loadToolboxEntries(dir)) byName.set(e.name, e);
|
|
96
|
-
}
|
|
97
|
-
return [...byName.values()].map((t) => (t.description ? `- ${t.call}: ${t.description}` : `- ${t.call}`));
|
|
98
|
-
}
|