pi-supernova 0.9.0 → 0.10.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.
- package/README.md +191 -14
- package/index.js +30 -9
- package/package.json +1 -1
- package/src/adapters/bash.js +40 -0
- package/src/adapters/read.js +24 -3
- package/src/bridge/host-bridge.js +50 -7
- package/src/bridge/invoke.js +6 -1
- package/src/bridge/trace.js +4 -1
- package/src/context/evidence.js +10 -1
- package/src/context/fuzzy.js +116 -43
- package/src/context/query.js +14 -5
- package/src/context/repo-index.js +15 -4
- package/src/context/snap-search.js +14 -13
- package/src/context/snap.js +11 -2
- package/src/contract/bash.js +43 -11
- package/src/contract/read.js +19 -5
- package/src/fs/background.js +304 -0
- package/src/fs/commit.js +6 -0
- package/src/fs/file-io.js +17 -2
- package/src/fs/process-tree.js +92 -0
- package/src/fs/read-window.js +18 -1
- package/src/fs/vfs.js +17 -4
- package/src/fs/workspace.js +51 -46
- package/src/output/bottleneck.js +14 -1
- package/src/runtime/guest-api.js +36 -20
- package/src/runtime/reference.js +11 -14
- package/src/shared/syntax-context.js +28 -7
package/src/runtime/reference.js
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
// Standing tool description: sent on every request. No result or history compression.
|
|
2
|
-
export const REFERENCE = `JS body/async arrow
|
|
3
|
-
read(path|paths,offset=1,limit?) →
|
|
4
|
-
Text ≤64 MiB internally; complete:true requires
|
|
5
|
-
read({path,json:selector}) →
|
|
6
|
-
read("symbol or question") = read({query,resolve:true}) → view; check status; view.text is a span,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
programs:[{code?,file?,data?}] inherits source/data; entries override. mergeData:true shallow object merge (entry keys win).
|
|
14
|
-
Promise.all: ≤8 reads or disjoint-file mutations; same-file serial; bash/checkpoint barriers.
|
|
15
|
-
Fresh guests/separate commits. Sequential failure stops; prior commits stay. parallel:true for disjoint entries. ONE call for known work; split for new decisions.
|
|
2
|
+
export const REFERENCE = `JS body/async arrow; read/write/edit/bash, no fs/import/require. file: workspace JS; data: literals ≤48000 JSON chars.
|
|
3
|
+
read(path|paths,offset=1,limit?) → text/text[]; dirs→entries; PNG/JPEG/GIF/WebP ≤16/20MiB.
|
|
4
|
+
Text ≤64 MiB internally; complete:true requires whole file. Display capped: summarize or read(path,{offset:1,limit:80}); larger files via bash.
|
|
5
|
+
read({path,json:true|selector}) → JSON, no jq (16MiB input/64MiB selection). Values retain their types.
|
|
6
|
+
read("symbol or question") = read({query,resolve:true}) → view; check status; view.text is a span. read(path,{about}) windows; read({query,evidence:true}) evidence; read({path,outline:true}) declarations.
|
|
7
|
+
write/edit workspace-only; external changes need separately authorized command. write(path,text) or {path,content,append:true}; after read edit or replace:true.
|
|
8
|
+
edit(path,oldText,newText) or {path,edits:[{oldText,newText}]}; unique exact match; numbered windows. edit(view,text) or edit(view,old,new). edit(async()=>{...}) checkpoint: no bash; merge/rollback+rethrow.
|
|
9
|
+
bash(command,{cwd?,timeoutMs?}) or {command,args}; nonzero throws. Outer timeout bounds foreground; bash inherits. Shell mutations flush edits.
|
|
10
|
+
bash({command,background:true,pty?:true,timeoutMs?:1800000})→sessionId. bash({action:"list"}) or {sessionId,action:"poll"|"write"|"stop",cursor?,waitMs?,input?}→status/output/cursor/exitCode. PTY macOS/Linux; jobs end at shutdown.
|
|
11
|
+
programs:[{code?,file?,data?}] inherit defaults; mergeData:true shallow. Fresh guests/commits; sequential failure stops, prior commits stay; parallel:true disjoint work.
|
|
12
|
+
Promise.all ≤8 disjoint reads/mutations; same-file serial; bash/checkpoints barriers. Optional reads: Promise.allSettled retains successes. ONE call for known work.
|
|
16
13
|
`;
|
|
@@ -1,12 +1,26 @@
|
|
|
1
|
+
import stringWidth from "string-width";
|
|
2
|
+
|
|
1
3
|
/** Bounded source context for parse and syntax diagnostics. */
|
|
4
|
+
const JS_LINES = /\r\n|[\n\r\u2028\u2029]/;
|
|
5
|
+
|
|
6
|
+
const JSON_LINES = /\r\n|[\n\r]/;
|
|
7
|
+
|
|
8
|
+
// Source columns are UTF-16 offsets; expand controls identically before the
|
|
9
|
+
// source token and the caret. JSON strings can contain literal Unicode LS/PS.
|
|
10
|
+
const displaySource = text => text.replaceAll("\t"," ").replaceAll("\u2028","\\u2028").replaceAll("\u2029","\\u2029");
|
|
2
11
|
|
|
3
|
-
export function sourceContext(source, line, column) {
|
|
12
|
+
export function sourceContext(source, line, column, lineBreaks = JS_LINES) {
|
|
4
13
|
if (!Number.isInteger(line) || line < 1) return "";
|
|
5
|
-
const text = String(source).split(
|
|
14
|
+
const text = String(source).split(lineBreaks)[line - 1];
|
|
6
15
|
|
|
7
16
|
if (text === undefined) return "";
|
|
8
|
-
const
|
|
9
|
-
const
|
|
17
|
+
const located = Number.isInteger(column) && column >= 0;
|
|
18
|
+
const position = located ? Math.min(column, text.length) : 0;
|
|
19
|
+
const start = Math.max(0, Math.min(position - 80, text.length - 160));
|
|
20
|
+
const end = Math.min(text.length, start + 160);
|
|
21
|
+
const prefix = start > 0 ? "…" : "";
|
|
22
|
+
const shown = prefix + displaySource(text.slice(start, end)) + (end < text.length ? "…" : "");
|
|
23
|
+
const caret = located ? " ".repeat(stringWidth(prefix + displaySource(text.slice(start, position)))) + "^" : "";
|
|
10
24
|
|
|
11
25
|
return "\n " + shown + (caret ? "\n " + caret : "");
|
|
12
26
|
}
|
|
@@ -24,11 +38,12 @@ export function parsePosition(message, source) {
|
|
|
24
38
|
const offsetMatch = /at position (\d+)/.exec(String(message));
|
|
25
39
|
|
|
26
40
|
if (!offsetMatch) return null;
|
|
41
|
+
|
|
27
42
|
return offsetPosition(source, Number(offsetMatch[1]));
|
|
28
43
|
}
|
|
29
44
|
|
|
30
45
|
function offsetPosition(source, offset) {
|
|
31
|
-
const lines = String(source).slice(0, offset).split(
|
|
46
|
+
const lines = String(source).slice(0, offset).split(JSON_LINES);
|
|
32
47
|
|
|
33
48
|
return { line: lines.length, column: lines.at(-1).length };
|
|
34
49
|
}
|
|
@@ -37,6 +52,7 @@ function offsetPosition(source, offset) {
|
|
|
37
52
|
// offsets. JSON.parse remains the authority; cap extra work at 65,536 characters.
|
|
38
53
|
// eslint-disable-next-line no-control-regex -- RFC 8259 excludes unescaped control characters from strings.
|
|
39
54
|
const JSON_TOKEN = /("(?:[^"\\\u0000-\u001f]|\\(?:["\\/bfnrt]|u[\da-fA-F]{4}))*")|(-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?)|(true|false|null)|[{}[\]:,]/y;
|
|
55
|
+
|
|
40
56
|
const JSON_NEXT = {
|
|
41
57
|
end: { eof: [] },
|
|
42
58
|
value: { string: [], number: [], literal: [], "{": ["object"], "[": ["array"] },
|
|
@@ -67,9 +83,12 @@ function invalidJsonOffset(source) {
|
|
|
67
83
|
while (stack.length) {
|
|
68
84
|
const token = jsonTokenAt(source, offset);
|
|
69
85
|
let state = stack.pop();
|
|
86
|
+
|
|
70
87
|
if (state === "array" && token.kind !== "]") { stack.push("arrayNext"); state = "value"; }
|
|
88
|
+
|
|
71
89
|
if (state === "object" && token.kind !== "}") state = "key";
|
|
72
90
|
const next = JSON_NEXT[state][token.kind];
|
|
91
|
+
|
|
73
92
|
if (!next) return token.start;
|
|
74
93
|
stack.push(...next);
|
|
75
94
|
offset = token.end;
|
|
@@ -80,10 +99,12 @@ function invalidJsonOffset(source) {
|
|
|
80
99
|
|
|
81
100
|
export function jsonErrorContext(message, source) {
|
|
82
101
|
const native = parsePosition(message, source);
|
|
83
|
-
|
|
102
|
+
|
|
103
|
+
if (native) return sourceContext(source, native.line, native.column, JSON_LINES);
|
|
84
104
|
const offset = invalidJsonOffset(source);
|
|
105
|
+
|
|
85
106
|
if (offset === null) return "";
|
|
86
107
|
const { line, column } = offsetPosition(source, offset);
|
|
87
108
|
|
|
88
|
-
return " (near line " + line + " column " + (column + 1) + ")" + sourceContext(source, line, column);
|
|
109
|
+
return " (near line " + line + " column " + (column + 1) + ")" + sourceContext(source, line, column, JSON_LINES);
|
|
89
110
|
}
|