@nteract/pi 0.1.6 → 0.1.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.
- package/extensions/repl.ts +53 -22
- package/package.json +8 -6
package/extensions/repl.ts
CHANGED
|
@@ -16,11 +16,13 @@
|
|
|
16
16
|
* After editing, run `/reload` in pi.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
import type {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
19
|
+
import type { ImageContent, TextContent } from "@earendil-works/pi-ai";
|
|
20
|
+
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
21
|
+
import { highlightCode } from "@earendil-works/pi-coding-agent";
|
|
22
|
+
import { Text, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
|
|
22
23
|
import { existsSync } from "node:fs";
|
|
23
24
|
import { createRequire } from "node:module";
|
|
25
|
+
import { homedir } from "node:os";
|
|
24
26
|
import path from "node:path";
|
|
25
27
|
import { fileURLToPath } from "node:url";
|
|
26
28
|
import { Type } from "typebox";
|
|
@@ -208,13 +210,26 @@ function formatStat(stats: ColumnStats | null): string {
|
|
|
208
210
|
}
|
|
209
211
|
}
|
|
210
212
|
|
|
213
|
+
function resolvePath(userPath: string, workingDir = process.cwd()): string {
|
|
214
|
+
const expanded = expandHome(userPath);
|
|
215
|
+
return path.isAbsolute(expanded) ? expanded : path.resolve(workingDir, expanded);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function expandHome(userPath: string): string {
|
|
219
|
+
if (userPath === "~") return homedir();
|
|
220
|
+
if (userPath.startsWith("~/") || userPath.startsWith("~\\")) {
|
|
221
|
+
return path.join(homedir(), userPath.slice(2));
|
|
222
|
+
}
|
|
223
|
+
return userPath;
|
|
224
|
+
}
|
|
225
|
+
|
|
211
226
|
const SPARK_CHARS = "▁▂▃▄▅▆▇█";
|
|
212
227
|
|
|
213
228
|
function sparkline(values: number[], width: number): string {
|
|
214
229
|
if (values.length === 0 || width <= 0) return "";
|
|
215
230
|
const min = Math.min(...values);
|
|
216
231
|
const max = Math.max(...values);
|
|
217
|
-
const bins =
|
|
232
|
+
const bins = Array.from({ length: Math.min(width, 8) }, () => 0);
|
|
218
233
|
if (min === max) {
|
|
219
234
|
return SPARK_CHARS[3].repeat(bins.length);
|
|
220
235
|
}
|
|
@@ -576,6 +591,31 @@ const PYTHON_PARAMS = Type.Object({
|
|
|
576
591
|
),
|
|
577
592
|
});
|
|
578
593
|
|
|
594
|
+
const ADD_DEPENDENCIES_PARAMS = Type.Object({
|
|
595
|
+
packages: Type.Array(Type.String(), {
|
|
596
|
+
description: "Package specs (e.g. ['matplotlib', 'pandas>=2']).",
|
|
597
|
+
}),
|
|
598
|
+
});
|
|
599
|
+
|
|
600
|
+
type AddDependenciesDetails = {
|
|
601
|
+
notebook_id?: string;
|
|
602
|
+
packages?: string[];
|
|
603
|
+
};
|
|
604
|
+
|
|
605
|
+
const SAVE_NOTEBOOK_PARAMS = Type.Object({
|
|
606
|
+
path: Type.Optional(
|
|
607
|
+
Type.String({
|
|
608
|
+
description:
|
|
609
|
+
"File path to save to (e.g. './analysis.ipynb'). If omitted, saves to the original location.",
|
|
610
|
+
}),
|
|
611
|
+
),
|
|
612
|
+
});
|
|
613
|
+
|
|
614
|
+
type SaveNotebookDetails = {
|
|
615
|
+
notebook_id: string;
|
|
616
|
+
path?: string;
|
|
617
|
+
};
|
|
618
|
+
|
|
579
619
|
export default function nteractReplExtension(pi: ExtensionAPI) {
|
|
580
620
|
const bootstrap = detectBootstrap();
|
|
581
621
|
if (bootstrap.kind === "missing") {
|
|
@@ -644,6 +684,7 @@ export default function nteractReplExtension(pi: ExtensionAPI) {
|
|
|
644
684
|
// channel auto-detect.
|
|
645
685
|
session = await rn.createNotebook({
|
|
646
686
|
runtime: "python",
|
|
687
|
+
workingDir: process.cwd(),
|
|
647
688
|
peerLabel: "pi",
|
|
648
689
|
description: "pi Python REPL",
|
|
649
690
|
dependencies,
|
|
@@ -856,18 +897,14 @@ export default function nteractReplExtension(pi: ExtensionAPI) {
|
|
|
856
897
|
},
|
|
857
898
|
});
|
|
858
899
|
|
|
859
|
-
pi.registerTool({
|
|
900
|
+
pi.registerTool<typeof ADD_DEPENDENCIES_PARAMS, AddDependenciesDetails>({
|
|
860
901
|
name: "python_add_dependencies",
|
|
861
902
|
label: "Add Dependencies",
|
|
862
903
|
description:
|
|
863
904
|
"Install packages into the running Python environment without restarting. Accepts pip-style specs like 'matplotlib', 'numpy>=2', 'requests'. The kernel stays hot.",
|
|
864
905
|
promptSnippet:
|
|
865
906
|
"python_add_dependencies: install packages into the running Python session (no restart needed).",
|
|
866
|
-
parameters:
|
|
867
|
-
packages: Type.Array(Type.String(), {
|
|
868
|
-
description: "Package specs (e.g. ['matplotlib', 'pandas>=2']).",
|
|
869
|
-
}),
|
|
870
|
-
}),
|
|
907
|
+
parameters: ADD_DEPENDENCIES_PARAMS,
|
|
871
908
|
async execute(_toolCallId, params, signal) {
|
|
872
909
|
if (signal?.aborted) throw new Error("aborted");
|
|
873
910
|
if (!params.packages.length) {
|
|
@@ -887,28 +924,22 @@ export default function nteractReplExtension(pi: ExtensionAPI) {
|
|
|
887
924
|
},
|
|
888
925
|
});
|
|
889
926
|
|
|
890
|
-
pi.registerTool({
|
|
927
|
+
pi.registerTool<typeof SAVE_NOTEBOOK_PARAMS, SaveNotebookDetails>({
|
|
891
928
|
name: "python_save_notebook",
|
|
892
929
|
label: "Save Notebook",
|
|
893
930
|
description:
|
|
894
931
|
"Save the current Python session as an .ipynb file. If no path is given, saves to the original location (if it was opened from a file). Provide a path to save elsewhere.",
|
|
895
932
|
promptSnippet: "python_save_notebook: save the current session as an .ipynb file.",
|
|
896
|
-
parameters:
|
|
897
|
-
path: Type.Optional(
|
|
898
|
-
Type.String({
|
|
899
|
-
description:
|
|
900
|
-
"File path to save to (e.g. './analysis.ipynb'). If omitted, saves to the original location.",
|
|
901
|
-
}),
|
|
902
|
-
),
|
|
903
|
-
}),
|
|
933
|
+
parameters: SAVE_NOTEBOOK_PARAMS,
|
|
904
934
|
async execute(_toolCallId, params, signal) {
|
|
905
935
|
if (signal?.aborted) throw new Error("aborted");
|
|
906
936
|
const sess = await ensureSession();
|
|
907
|
-
|
|
908
|
-
|
|
937
|
+
const savePath = params.path ? resolvePath(params.path) : undefined;
|
|
938
|
+
await sess.saveNotebook(savePath);
|
|
939
|
+
const where = savePath ?? "original location";
|
|
909
940
|
return {
|
|
910
941
|
content: [{ type: "text", text: `Notebook saved to ${where}` }],
|
|
911
|
-
details: { notebook_id: sess.notebookId, path:
|
|
942
|
+
details: { notebook_id: sess.notebookId, path: savePath },
|
|
912
943
|
};
|
|
913
944
|
},
|
|
914
945
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nteract/pi",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"description": "Persistent notebook-backed Python REPL for Pi coding agents. Stateful execution, hot dependency sync, zero cold starts.",
|
|
5
5
|
"author": "nteract contributors",
|
|
6
6
|
"icon": "icon.png",
|
|
@@ -36,19 +36,21 @@
|
|
|
36
36
|
"extensions"
|
|
37
37
|
],
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@runtimed/node": "0.2.
|
|
39
|
+
"@runtimed/node": "0.2.7"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
|
-
"@
|
|
43
|
-
"@
|
|
42
|
+
"@earendil-works/pi-ai": "*",
|
|
43
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
44
|
+
"@earendil-works/pi-tui": "*",
|
|
44
45
|
"typebox": "*"
|
|
45
46
|
},
|
|
46
47
|
"publishConfig": {
|
|
47
48
|
"access": "public"
|
|
48
49
|
},
|
|
49
50
|
"devDependencies": {
|
|
50
|
-
"@
|
|
51
|
-
"@
|
|
51
|
+
"@earendil-works/pi-ai": "^0.74.0",
|
|
52
|
+
"@earendil-works/pi-coding-agent": "^0.74.0",
|
|
53
|
+
"@earendil-works/pi-tui": "^0.74.0"
|
|
52
54
|
},
|
|
53
55
|
"scripts": {
|
|
54
56
|
"pack:dry-run": "pnpm pack --dry-run"
|