pi-supernova 0.5.0 → 0.7.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 +97 -11
- package/docs/CHANGELOG.md +150 -0
- package/docs/TOKEN_COSTS.md +71 -29
- package/index.js +126 -82
- package/package.json +2 -2
- package/src/adapters/bash.js +73 -0
- package/src/adapters/edit.js +249 -0
- package/src/adapters/errors.js +31 -0
- package/src/adapters/index.js +31 -0
- package/src/adapters/list.js +102 -0
- package/src/adapters/read.js +805 -0
- package/src/adapters/refs.js +41 -0
- package/src/adapters/write.js +96 -0
- package/src/bridge/catalog.js +30 -220
- package/src/bridge/host-bridge.js +142 -1032
- package/src/bridge/invoke.js +35 -0
- package/src/bridge/native-tools.js +1 -188
- package/src/context/evidence.js +142 -70
- package/src/context/fuzzy.js +61 -22
- package/src/context/ledger.js +43 -24
- package/src/context/outline.js +26 -12
- package/src/context/repo-index.js +242 -71
- package/src/context/search.js +189 -56
- package/src/context/snap.js +306 -150
- package/src/context/spans.js +2 -1
- package/src/context/surface.js +29 -14
- package/src/contract/bash.js +31 -0
- package/src/contract/edit.js +95 -0
- package/src/contract/read.js +220 -0
- package/src/fs/check.js +19 -7
- package/src/fs/diff.js +18 -7
- package/src/fs/json-read.js +66 -35
- package/src/fs/patch.js +97 -51
- package/src/fs/source-window.js +82 -0
- package/src/fs/text-ops.js +512 -0
- package/src/fs/vfs.js +289 -162
- package/src/fs/workspace.js +122 -105
- package/src/output/bottleneck.js +211 -107
- package/src/output/format.js +112 -63
- package/src/runtime/guest-deny-imports.js +34 -0
- package/src/runtime/guest-worker.js +306 -213
- package/src/runtime/parallel.js +99 -63
- package/src/runtime/program-batch.js +189 -69
- package/src/runtime/program-file.js +6 -3
- package/src/runtime/reference.js +13 -12
- package/src/runtime/runtime.js +327 -176
- package/src/shared/decode.js +61 -27
- package/src/ui/omp-frame.js +70 -46
- package/src/ui/render-measure.js +51 -29
- package/src/ui/render.js +242 -146
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import * as fs from "node:fs/promises";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { resolveWorkspacePath, runCommand } from "../fs/workspace.js";
|
|
4
|
+
import { fuzzyFind, grepIndexed, listIndexed, listWithTools, rgGrepArgs } from "../context/search.js";
|
|
5
|
+
import { textResult, formatDirectoryEntry } from "../fs/text-ops.js";
|
|
6
|
+
|
|
7
|
+
function rawListPattern(op, params) {
|
|
8
|
+
if (op === "glob") return String(params?.pattern || "");
|
|
9
|
+
|
|
10
|
+
return params?.pattern || params?.glob;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function globPatternOf(op, params) {
|
|
14
|
+
const pattern = rawListPattern(op, params);
|
|
15
|
+
|
|
16
|
+
if (op === "glob" && !pattern) throw new Error("glob requires pattern");
|
|
17
|
+
|
|
18
|
+
return pattern ? String(pattern) : null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function resolveListDir(op, params, cwd) {
|
|
22
|
+
if (op === "find" && params?.path) return resolveWorkspacePath(cwd, params.path, op, true);
|
|
23
|
+
|
|
24
|
+
return cwd;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function fileListing(dirPath, size) {
|
|
28
|
+
const entry = formatDirectoryEntry(path.basename(dirPath), "file", size);
|
|
29
|
+
|
|
30
|
+
return textResult(entry, { path: dirPath, directory: false, count: 1, entries: [entry] });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function createList(ctx) {
|
|
34
|
+
const { getCwd, vfs, index } = ctx;
|
|
35
|
+
|
|
36
|
+
async function listFromCache(searchDir, cwd, globPattern, pending) {
|
|
37
|
+
const fuzzy = await fuzzyFind(index, searchDir, cwd, globPattern, 20, pending);
|
|
38
|
+
|
|
39
|
+
if (fuzzy !== null) return textResult(fuzzy, { via: "fuzzy" });
|
|
40
|
+
const indexed = await listIndexed(index, searchDir, cwd, globPattern, pending);
|
|
41
|
+
|
|
42
|
+
if (indexed !== null) return textResult(indexed, { via: "index" });
|
|
43
|
+
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function listFiles(params, signal, op, cwd) {
|
|
48
|
+
if (signal?.aborted) throw new Error("aborted");
|
|
49
|
+
const searchDir = await resolveListDir(op, params, cwd);
|
|
50
|
+
const globPattern = globPatternOf(op, params);
|
|
51
|
+
const pending = vfs.getOverlayPaths();
|
|
52
|
+
const cached = await listFromCache(searchDir, cwd, globPattern, pending);
|
|
53
|
+
|
|
54
|
+
if (cached !== null) return cached;
|
|
55
|
+
|
|
56
|
+
return listWithTools(searchDir, globPattern, cwd, signal, pending);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
async function grepWithRg(pattern, params, searchPath, cwd, signal) {
|
|
60
|
+
const res = await runCommand(["rg", ...rgGrepArgs(pattern, params, searchPath)], { cwd, timeoutMs: 30_000, signal });
|
|
61
|
+
|
|
62
|
+
if (res.exitCode !== 0 && res.exitCode !== 1) {
|
|
63
|
+
throw new Error(res.stderr.trim() || `rg exited ${res.exitCode}`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return textResult(res.stdout, { exitCode: res.exitCode });
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function grep(params, signal) {
|
|
70
|
+
const cwd = getCwd();
|
|
71
|
+
const pattern = String(params?.pattern || "");
|
|
72
|
+
|
|
73
|
+
if (!pattern) throw new Error("grep requires pattern");
|
|
74
|
+
const searchPath = params?.path ? await resolveWorkspacePath(cwd, params.path, "grep", true) : cwd;
|
|
75
|
+
const indexed = await grepIndexed(index, pattern, params, searchPath, cwd, file => vfs.getOverlay(file), vfs.getOverlayPaths());
|
|
76
|
+
|
|
77
|
+
if (indexed !== null) return textResult(indexed, { exitCode: indexed ? 0 : 1, via: "index" });
|
|
78
|
+
// Large tree: real rg keeps its own output format.
|
|
79
|
+
return grepWithRg(pattern, params, searchPath, cwd, signal);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async function glob(params, signal) {
|
|
83
|
+
return listFiles(params, signal, "glob", getCwd());
|
|
84
|
+
}
|
|
85
|
+
async function find(params, signal) {
|
|
86
|
+
return listFiles(params, signal, "find", getCwd());
|
|
87
|
+
}
|
|
88
|
+
async function ls(params, signal) {
|
|
89
|
+
const cwd = getCwd();
|
|
90
|
+
const dirPath = params?.path ? await resolveWorkspacePath(cwd, params.path, "ls", true) : cwd;
|
|
91
|
+
const pending = vfs.getOverlay(dirPath);
|
|
92
|
+
|
|
93
|
+
if (pending !== undefined) return fileListing(dirPath, Buffer.byteLength(pending, "utf8"));
|
|
94
|
+
const stat = await fs.stat(dirPath).catch(() => null);
|
|
95
|
+
|
|
96
|
+
if (stat?.isFile()) return fileListing(dirPath, stat.size);
|
|
97
|
+
|
|
98
|
+
return ctx.readDirectory(dirPath, signal);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return { grep, glob, find, ls };
|
|
102
|
+
}
|