pi-supernova 0.0.4 → 0.0.6
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/CHANGELOG.md +23 -0
- package/README.md +17 -6
- package/catalog.js +4 -1
- package/diff.js +60 -46
- package/host-bridge.js +76 -28
- package/index.js +39 -5
- package/omp-frame.js +20 -27
- package/package.json +2 -11
- package/render-measure.js +15 -9
- package/render.js +210 -436
- package/runtime.js +38 -19
- package/snap.js +29 -3
package/runtime.js
CHANGED
|
@@ -59,23 +59,32 @@ export async function runGuestProgram(options) {
|
|
|
59
59
|
|
|
60
60
|
let compiled = compiledCache.get(body);
|
|
61
61
|
if (!compiled) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
62
|
+
try {
|
|
63
|
+
compiled = new AsyncFunction(
|
|
64
|
+
"nova",
|
|
65
|
+
"tools",
|
|
66
|
+
"console",
|
|
67
|
+
"parallel",
|
|
68
|
+
"pipeline",
|
|
69
|
+
"read",
|
|
70
|
+
"write",
|
|
71
|
+
"edit",
|
|
72
|
+
"patch",
|
|
73
|
+
"surface",
|
|
74
|
+
"snap",
|
|
75
|
+
"bash",
|
|
76
|
+
"exec",
|
|
77
|
+
"speculate",
|
|
78
|
+
body,
|
|
79
|
+
);
|
|
80
|
+
} catch (err) {
|
|
81
|
+
return {
|
|
82
|
+
ok: false,
|
|
83
|
+
error: err instanceof Error ? err.message : String(err),
|
|
84
|
+
logs,
|
|
85
|
+
wallMs: Math.round(performance.now() - started),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
79
88
|
if (compiledCache.size >= COMPILED_CACHE_MAX) {
|
|
80
89
|
const first = compiledCache.keys().next().value;
|
|
81
90
|
if (first !== undefined) compiledCache.delete(first);
|
|
@@ -108,6 +117,16 @@ export async function runGuestProgram(options) {
|
|
|
108
117
|
return res;
|
|
109
118
|
};
|
|
110
119
|
|
|
120
|
+
const unwrapJsonValue = (res) => {
|
|
121
|
+
const value = unwrapValue(res);
|
|
122
|
+
if (!isString(value)) return value;
|
|
123
|
+
try {
|
|
124
|
+
return JSON.parse(value);
|
|
125
|
+
} catch {
|
|
126
|
+
return value;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
|
|
111
130
|
const guestRead = async (p, off, lim) => {
|
|
112
131
|
if (Array.isArray(p)) {
|
|
113
132
|
return await Promise.all(p.map((item) => guestRead(item, off, lim)));
|
|
@@ -123,11 +142,11 @@ export async function runGuestProgram(options) {
|
|
|
123
142
|
const guestPatch = async (p, d) => unwrapValue(await nova.call("apply_patch", { path: p, patch: d }));
|
|
124
143
|
const guestSurface = async (p) => {
|
|
125
144
|
const res = await (isFunction(nova.surface) ? nova.surface(p) : nova.call("surface", { path: p }));
|
|
126
|
-
return
|
|
145
|
+
return unwrapJsonValue(res);
|
|
127
146
|
};
|
|
128
147
|
const guestSnap = async (q, p) => {
|
|
129
148
|
const res = await (isFunction(nova.snap) ? nova.snap(q, p) : nova.call("snap", { query: q, path: p }));
|
|
130
|
-
return
|
|
149
|
+
return unwrapJsonValue(res);
|
|
131
150
|
};
|
|
132
151
|
const guestBash = async (cmd, opts) => {
|
|
133
152
|
const res = await nova.call("bash", { command: cmd, ...opts });
|
package/snap.js
CHANGED
|
@@ -94,21 +94,46 @@ function scoreContentDefinitions(content, tokens) {
|
|
|
94
94
|
return { totalScore: score, bestLine, bestLineScore };
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
function relativeHasSegment(relativePath, segmentName) {
|
|
98
|
+
return relativePath.split(path.sep).includes(segmentName);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function relativeHasHiddenSegment(relativePath) {
|
|
102
|
+
return relativePath.split(path.sep).some((segment) => segment.startsWith(".") && segment.length > 1);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export async function executeSnap({ query, searchDir, includeHidden = false, vfs, runCommand, pendingPaths = [] }) {
|
|
98
106
|
const { tokens, wantsTest, wantsType, wantsDoc } = tokenizeQuery(query);
|
|
99
107
|
if (tokens.length === 0) {
|
|
100
108
|
throw new Error("snap requires at least one searchable concept keyword");
|
|
101
109
|
}
|
|
102
110
|
|
|
103
111
|
const dir = searchDir || process.cwd();
|
|
112
|
+
if (path.resolve(dir).split(path.sep).includes(".git")) {
|
|
113
|
+
throw new Error("snap cannot search Git metadata");
|
|
114
|
+
}
|
|
104
115
|
let fileList = [];
|
|
105
116
|
try {
|
|
106
|
-
const
|
|
117
|
+
const rgArgs = ["rg", "--files"];
|
|
118
|
+
if (includeHidden) rgArgs.push("--hidden");
|
|
119
|
+
rgArgs.push("-g", "!.git/**", "-g", "!**/.git/**", dir);
|
|
120
|
+
const res = await runCommand(rgArgs, { timeoutMs: 15_000 });
|
|
107
121
|
fileList = res.stdout.split("\n").map((f) => f.trim()).filter(Boolean);
|
|
108
122
|
} catch {
|
|
109
123
|
fileList = [];
|
|
110
124
|
}
|
|
111
125
|
|
|
126
|
+
const seenPaths = new Set(fileList.map((filePath) => path.resolve(filePath)));
|
|
127
|
+
for (const pendingPath of pendingPaths) {
|
|
128
|
+
const absolutePath = path.resolve(pendingPath);
|
|
129
|
+
const relativePath = path.relative(path.resolve(dir), absolutePath);
|
|
130
|
+
const escapesDir = relativePath === ".." || relativePath.startsWith(`..${path.sep}`) || path.isAbsolute(relativePath);
|
|
131
|
+
const hiddenRelativePath = relativeHasHiddenSegment(relativePath);
|
|
132
|
+
if (escapesDir || relativeHasSegment(relativePath, ".git") || (!includeHidden && hiddenRelativePath) || seenPaths.has(absolutePath)) continue;
|
|
133
|
+
seenPaths.add(absolutePath);
|
|
134
|
+
fileList.push(absolutePath);
|
|
135
|
+
}
|
|
136
|
+
|
|
112
137
|
if (fileList.length === 0) {
|
|
113
138
|
throw new Error(`no files found to search in ${dir}`);
|
|
114
139
|
}
|
|
@@ -125,7 +150,8 @@ export async function executeSnap({ query, searchDir, vfs, runCommand }) {
|
|
|
125
150
|
|
|
126
151
|
if (candidates.length < 5) {
|
|
127
152
|
try {
|
|
128
|
-
const grepArgs = ["-l", "--max-count=1"];
|
|
153
|
+
const grepArgs = ["-l", "--max-count=1", "-g", "!.git/**", "-g", "!**/.git/**"];
|
|
154
|
+
if (includeHidden) grepArgs.push("--hidden");
|
|
129
155
|
if (!wantsTest) {
|
|
130
156
|
grepArgs.push("-g", "!test/**", "-g", "!tests/**", "-g", "!*.test.*", "-g", "!*.spec.*");
|
|
131
157
|
}
|