@bdsqqq/pi 0.0.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/dist/chunk-DsIazq42.js +26 -0
- package/dist/command-palette-B97yKqne.js +406 -0
- package/dist/core/agents-md.d.ts +22 -0
- package/dist/core/agents-md.js +174 -0
- package/dist/core/box-chrome.d.ts +56 -0
- package/dist/core/box-chrome.js +207 -0
- package/dist/core/box-format.d.ts +82 -0
- package/dist/core/box-format.js +381 -0
- package/dist/core/config.d.ts +14 -0
- package/dist/core/config.js +201 -0
- package/dist/core/file-tracker.d.ts +65 -0
- package/dist/core/file-tracker.js +439 -0
- package/dist/core/github-api.d.ts +45 -0
- package/dist/core/github-api.js +101 -0
- package/dist/core/html-to-md.d.ts +5 -0
- package/dist/core/html-to-md.js +289 -0
- package/dist/core/interpolate.d.ts +44 -0
- package/dist/core/interpolate.js +475 -0
- package/dist/core/mutex.d.ts +8 -0
- package/dist/core/mutex.js +142 -0
- package/dist/core/output-buffer.d.ts +80 -0
- package/dist/core/output-buffer.js +517 -0
- package/dist/core/permissions.d.ts +19 -0
- package/dist/core/permissions.js +140 -0
- package/dist/core/pi-spawn.d.ts +62 -0
- package/dist/core/pi-spawn.js +244 -0
- package/dist/core/prompt-patch.d.ts +11 -0
- package/dist/core/prompt-patch.js +16 -0
- package/dist/core/show-renderer.d.ts +10 -0
- package/dist/core/show-renderer.js +39 -0
- package/dist/core/show.d.ts +29 -0
- package/dist/core/show.js +288 -0
- package/dist/core/sub-agent-render.d.ts +56 -0
- package/dist/core/sub-agent-render.js +579 -0
- package/dist/core/tool-cost.d.ts +17 -0
- package/dist/core/tool-cost.js +58 -0
- package/dist/core/tui.d.ts +9 -0
- package/dist/core/tui.js +33 -0
- package/dist/editor-BljciPdx.js +537 -0
- package/dist/extensions/bash.d.ts +12 -0
- package/dist/extensions/bash.js +261 -0
- package/dist/extensions/code-review.d.ts +14 -0
- package/dist/extensions/code-review.js +175 -0
- package/dist/extensions/command-palette.d.ts +6 -0
- package/dist/extensions/command-palette.js +2 -0
- package/dist/extensions/create-file.d.ts +7 -0
- package/dist/extensions/create-file.js +88 -0
- package/dist/extensions/edit-file.d.ts +7 -0
- package/dist/extensions/edit-file.js +395 -0
- package/dist/extensions/editor.d.ts +6 -0
- package/dist/extensions/editor.js +2 -0
- package/dist/extensions/finder.d.ts +13 -0
- package/dist/extensions/finder.js +108 -0
- package/dist/extensions/format-file.d.ts +11 -0
- package/dist/extensions/format-file.js +145 -0
- package/dist/extensions/github.d.ts +13 -0
- package/dist/extensions/github.js +527 -0
- package/dist/extensions/glob.d.ts +10 -0
- package/dist/extensions/glob.js +163 -0
- package/dist/extensions/grep.d.ts +13 -0
- package/dist/extensions/grep.js +356 -0
- package/dist/extensions/handoff.d.ts +6 -0
- package/dist/extensions/handoff.js +277 -0
- package/dist/extensions/librarian.d.ts +13 -0
- package/dist/extensions/librarian.js +113 -0
- package/dist/extensions/look-at.d.ts +13 -0
- package/dist/extensions/look-at.js +121 -0
- package/dist/extensions/ls.d.ts +8 -0
- package/dist/extensions/ls.js +87 -0
- package/dist/extensions/mermaid.d.ts +20 -0
- package/dist/extensions/mermaid.js +2 -0
- package/dist/extensions/oracle.d.ts +13 -0
- package/dist/extensions/oracle.js +143 -0
- package/dist/extensions/read-session.d.ts +13 -0
- package/dist/extensions/read-session.js +265 -0
- package/dist/extensions/read-web-page.d.ts +11 -0
- package/dist/extensions/read-web-page.js +234 -0
- package/dist/extensions/read.d.ts +23 -0
- package/dist/extensions/read.js +323 -0
- package/dist/extensions/search-sessions.d.ts +29 -0
- package/dist/extensions/search-sessions.js +426 -0
- package/dist/extensions/session-name.d.ts +6 -0
- package/dist/extensions/session-name.js +54 -0
- package/dist/extensions/skill.d.ts +7 -0
- package/dist/extensions/skill.js +232 -0
- package/dist/extensions/system-prompt.d.ts +6 -0
- package/dist/extensions/system-prompt.js +31 -0
- package/dist/extensions/task.d.ts +11 -0
- package/dist/extensions/task.js +114 -0
- package/dist/extensions/tool-harness.d.ts +6 -0
- package/dist/extensions/tool-harness.js +37 -0
- package/dist/extensions/undo-edit.d.ts +7 -0
- package/dist/extensions/undo-edit.js +127 -0
- package/dist/extensions/web-search.d.ts +12 -0
- package/dist/extensions/web-search.js +254 -0
- package/dist/extensions.d.ts +29 -0
- package/dist/extensions.js +29 -0
- package/dist/mermaid-C7xCVBrw.js +95296 -0
- package/package.json +67 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import * as os from "node:os";
|
|
4
|
+
//#region packages/core/config/index.ts
|
|
5
|
+
/**
|
|
6
|
+
* shared config reader for pi extensions.
|
|
7
|
+
*
|
|
8
|
+
* reads per-extension configuration from pi's settings.json files,
|
|
9
|
+
* keyed by extension namespace (e.g. `"@bds_pi/librarian"`).
|
|
10
|
+
*
|
|
11
|
+
* merge order: defaults → global (~/.pi/agent/bds-pi.json) → project-local (.pi/settings.json).
|
|
12
|
+
* project-local is opt-in via `allowProjectConfig` to prevent malicious repo overrides.
|
|
13
|
+
*/
|
|
14
|
+
let _globalSettingsPath = null;
|
|
15
|
+
function setGlobalSettingsPath(p) {
|
|
16
|
+
_globalSettingsPath = p;
|
|
17
|
+
}
|
|
18
|
+
const _cache = /* @__PURE__ */ new Map();
|
|
19
|
+
function clearConfigCache() {
|
|
20
|
+
_cache.clear();
|
|
21
|
+
}
|
|
22
|
+
function resolveGlobalSettingsPath() {
|
|
23
|
+
return _globalSettingsPath ?? path.join(os.homedir(), ".pi", "agent", "bds-pi.json");
|
|
24
|
+
}
|
|
25
|
+
function readJsonFile(filePath) {
|
|
26
|
+
if (_cache.has(filePath)) return _cache.get(filePath);
|
|
27
|
+
try {
|
|
28
|
+
const raw = fs.readFileSync(filePath, "utf-8");
|
|
29
|
+
const parsed = JSON.parse(raw);
|
|
30
|
+
_cache.set(filePath, parsed);
|
|
31
|
+
return parsed;
|
|
32
|
+
} catch (err) {
|
|
33
|
+
if (err.code !== "ENOENT") console.error(`[@bds_pi/config] failed to read ${filePath}:`, err);
|
|
34
|
+
_cache.set(filePath, null);
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function isPlainObject(value) {
|
|
39
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
40
|
+
}
|
|
41
|
+
function deepMerge(base, override) {
|
|
42
|
+
const result = { ...base };
|
|
43
|
+
for (const key of Object.keys(override)) {
|
|
44
|
+
const baseVal = result[key];
|
|
45
|
+
const overVal = override[key];
|
|
46
|
+
if (isPlainObject(baseVal) && isPlainObject(overVal)) result[key] = deepMerge(baseVal, overVal);
|
|
47
|
+
else result[key] = overVal;
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
function getExtensionConfig(namespace, defaults, opts) {
|
|
52
|
+
let merged = { ...defaults };
|
|
53
|
+
const globalSettings = readJsonFile(resolveGlobalSettingsPath());
|
|
54
|
+
if (globalSettings && isPlainObject(globalSettings[namespace])) merged = deepMerge(merged, globalSettings[namespace]);
|
|
55
|
+
if (opts?.allowProjectConfig && opts.cwd) {
|
|
56
|
+
const projectSettings = readJsonFile(path.join(opts.cwd, ".pi", "settings.json"));
|
|
57
|
+
if (projectSettings && isPlainObject(projectSettings[namespace])) merged = deepMerge(merged, projectSettings[namespace]);
|
|
58
|
+
}
|
|
59
|
+
return merged;
|
|
60
|
+
}
|
|
61
|
+
/** read a top-level (non-namespaced) key from the global settings file. */
|
|
62
|
+
function getGlobalConfig(key) {
|
|
63
|
+
const settings = readJsonFile(resolveGlobalSettingsPath());
|
|
64
|
+
if (!settings || !(key in settings)) return void 0;
|
|
65
|
+
return settings[key];
|
|
66
|
+
}
|
|
67
|
+
/** directory containing the global settings file (e.g. ~/.pi/agent/). */
|
|
68
|
+
function resolveConfigDir() {
|
|
69
|
+
return path.dirname(resolveGlobalSettingsPath());
|
|
70
|
+
}
|
|
71
|
+
if (import.meta.vitest) {
|
|
72
|
+
const { afterEach, describe, expect, test } = import.meta.vitest;
|
|
73
|
+
const tmpdir = os.tmpdir();
|
|
74
|
+
function writeTmpJson(dir, filename, data) {
|
|
75
|
+
const filePath = path.join(dir, filename);
|
|
76
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
77
|
+
fs.writeFileSync(filePath, JSON.stringify(data));
|
|
78
|
+
return filePath;
|
|
79
|
+
}
|
|
80
|
+
afterEach(() => {
|
|
81
|
+
clearConfigCache();
|
|
82
|
+
_globalSettingsPath = null;
|
|
83
|
+
});
|
|
84
|
+
describe("getExtensionConfig", () => {
|
|
85
|
+
test("returns defaults when no settings file exists", () => {
|
|
86
|
+
setGlobalSettingsPath(path.join(tmpdir, `nonexistent-${Date.now()}.json`));
|
|
87
|
+
expect(getExtensionConfig("@bds_pi/test", {
|
|
88
|
+
foo: "bar",
|
|
89
|
+
n: 1
|
|
90
|
+
})).toEqual({
|
|
91
|
+
foo: "bar",
|
|
92
|
+
n: 1
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
test("reads namespaced config from global settings", () => {
|
|
96
|
+
setGlobalSettingsPath(writeTmpJson(fs.mkdtempSync(path.join(tmpdir, "pi-config-test-")), "settings.json", { "@bds_pi/test": { foo: "overridden" } }));
|
|
97
|
+
expect(getExtensionConfig("@bds_pi/test", {
|
|
98
|
+
foo: "default",
|
|
99
|
+
extra: true
|
|
100
|
+
})).toEqual({
|
|
101
|
+
foo: "overridden",
|
|
102
|
+
extra: true
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
test("deep merges nested objects", () => {
|
|
106
|
+
setGlobalSettingsPath(writeTmpJson(fs.mkdtempSync(path.join(tmpdir, "pi-config-test-")), "settings.json", { "@bds_pi/test": { nested: {
|
|
107
|
+
b: 2,
|
|
108
|
+
c: 3
|
|
109
|
+
} } }));
|
|
110
|
+
expect(getExtensionConfig("@bds_pi/test", { nested: {
|
|
111
|
+
a: 1,
|
|
112
|
+
b: 0
|
|
113
|
+
} })).toEqual({ nested: {
|
|
114
|
+
a: 1,
|
|
115
|
+
b: 2,
|
|
116
|
+
c: 3
|
|
117
|
+
} });
|
|
118
|
+
});
|
|
119
|
+
test("arrays replace rather than merge", () => {
|
|
120
|
+
setGlobalSettingsPath(writeTmpJson(fs.mkdtempSync(path.join(tmpdir, "pi-config-test-")), "settings.json", { "@bds_pi/test": { items: [3, 4] } }));
|
|
121
|
+
expect(getExtensionConfig("@bds_pi/test", { items: [1, 2] })).toEqual({ items: [3, 4] });
|
|
122
|
+
});
|
|
123
|
+
test("caches reads — second call does not re-read file", () => {
|
|
124
|
+
const settingsPath = writeTmpJson(fs.mkdtempSync(path.join(tmpdir, "pi-config-test-")), "settings.json", { "@bds_pi/test": { v: 1 } });
|
|
125
|
+
setGlobalSettingsPath(settingsPath);
|
|
126
|
+
getExtensionConfig("@bds_pi/test", { v: 0 });
|
|
127
|
+
fs.writeFileSync(settingsPath, JSON.stringify({ "@bds_pi/test": { v: 999 } }));
|
|
128
|
+
expect(getExtensionConfig("@bds_pi/test", { v: 0 })).toEqual({ v: 1 });
|
|
129
|
+
});
|
|
130
|
+
test("clearConfigCache resets cached reads", () => {
|
|
131
|
+
const settingsPath = writeTmpJson(fs.mkdtempSync(path.join(tmpdir, "pi-config-test-")), "settings.json", { "@bds_pi/test": { v: 1 } });
|
|
132
|
+
setGlobalSettingsPath(settingsPath);
|
|
133
|
+
getExtensionConfig("@bds_pi/test", { v: 0 });
|
|
134
|
+
fs.writeFileSync(settingsPath, JSON.stringify({ "@bds_pi/test": { v: 999 } }));
|
|
135
|
+
clearConfigCache();
|
|
136
|
+
expect(getExtensionConfig("@bds_pi/test", { v: 0 })).toEqual({ v: 999 });
|
|
137
|
+
});
|
|
138
|
+
test("handles malformed JSON gracefully", () => {
|
|
139
|
+
const dir = fs.mkdtempSync(path.join(tmpdir, "pi-config-test-"));
|
|
140
|
+
const settingsPath = path.join(dir, "settings.json");
|
|
141
|
+
fs.writeFileSync(settingsPath, "NOT VALID JSON {{{");
|
|
142
|
+
setGlobalSettingsPath(settingsPath);
|
|
143
|
+
expect(getExtensionConfig("@bds_pi/test", { ok: true })).toEqual({ ok: true });
|
|
144
|
+
});
|
|
145
|
+
test("returns defaults when namespace key is missing", () => {
|
|
146
|
+
setGlobalSettingsPath(writeTmpJson(fs.mkdtempSync(path.join(tmpdir, "pi-config-test-")), "settings.json", { "@bds_pi/other": { x: 1 } }));
|
|
147
|
+
expect(getExtensionConfig("@bds_pi/test", { y: 2 })).toEqual({ y: 2 });
|
|
148
|
+
});
|
|
149
|
+
test("project-local config merges on top of global", () => {
|
|
150
|
+
setGlobalSettingsPath(writeTmpJson(fs.mkdtempSync(path.join(tmpdir, "pi-config-global-")), "settings.json", { "@bds_pi/test": {
|
|
151
|
+
a: "global",
|
|
152
|
+
b: "global"
|
|
153
|
+
} }));
|
|
154
|
+
const projectDir = fs.mkdtempSync(path.join(tmpdir, "pi-config-project-"));
|
|
155
|
+
writeTmpJson(projectDir, ".pi/settings.json", { "@bds_pi/test": {
|
|
156
|
+
b: "project",
|
|
157
|
+
c: "project"
|
|
158
|
+
} });
|
|
159
|
+
expect(getExtensionConfig("@bds_pi/test", {
|
|
160
|
+
a: "default",
|
|
161
|
+
b: "default",
|
|
162
|
+
c: "default"
|
|
163
|
+
}, {
|
|
164
|
+
cwd: projectDir,
|
|
165
|
+
allowProjectConfig: true
|
|
166
|
+
})).toEqual({
|
|
167
|
+
a: "global",
|
|
168
|
+
b: "project",
|
|
169
|
+
c: "project"
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
test("project-local config is ignored when allowProjectConfig is false", () => {
|
|
173
|
+
setGlobalSettingsPath(writeTmpJson(fs.mkdtempSync(path.join(tmpdir, "pi-config-global-")), "settings.json", { "@bds_pi/test": { a: "global" } }));
|
|
174
|
+
const projectDir = fs.mkdtempSync(path.join(tmpdir, "pi-config-project-"));
|
|
175
|
+
writeTmpJson(projectDir, ".pi/settings.json", { "@bds_pi/test": { a: "project" } });
|
|
176
|
+
expect(getExtensionConfig("@bds_pi/test", { a: "default" }, { cwd: projectDir })).toEqual({ a: "global" });
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
describe("getGlobalConfig", () => {
|
|
180
|
+
test("returns undefined when no settings file exists", () => {
|
|
181
|
+
setGlobalSettingsPath(path.join(tmpdir, `nonexistent-${Date.now()}.json`));
|
|
182
|
+
expect(getGlobalConfig("missing")).toBeUndefined();
|
|
183
|
+
});
|
|
184
|
+
test("reads top-level key from global settings", () => {
|
|
185
|
+
setGlobalSettingsPath(writeTmpJson(fs.mkdtempSync(path.join(tmpdir, "pi-config-test-")), "settings.json", { promptVariables: { foo: { literal: "bar" } } }));
|
|
186
|
+
expect(getGlobalConfig("promptVariables")).toEqual({ foo: { literal: "bar" } });
|
|
187
|
+
});
|
|
188
|
+
test("returns undefined for missing key", () => {
|
|
189
|
+
setGlobalSettingsPath(writeTmpJson(fs.mkdtempSync(path.join(tmpdir, "pi-config-test-")), "settings.json", { other: 1 }));
|
|
190
|
+
expect(getGlobalConfig("promptVariables")).toBeUndefined();
|
|
191
|
+
});
|
|
192
|
+
});
|
|
193
|
+
describe("resolveConfigDir", () => {
|
|
194
|
+
test("returns dirname of global settings path", () => {
|
|
195
|
+
setGlobalSettingsPath("/fake/dir/settings.json");
|
|
196
|
+
expect(resolveConfigDir()).toBe("/fake/dir");
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
//#endregion
|
|
201
|
+
export { clearConfigCache, getExtensionConfig, getGlobalConfig, resolveConfigDir, setGlobalSettingsPath };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
//#region packages/core/file-tracker/index.d.ts
|
|
2
|
+
interface FileChange {
|
|
3
|
+
/** unique id for this change record */
|
|
4
|
+
id: string;
|
|
5
|
+
/** file:// URI of the changed file */
|
|
6
|
+
uri: string;
|
|
7
|
+
/** full content before the edit */
|
|
8
|
+
before: string;
|
|
9
|
+
/** full content after the edit */
|
|
10
|
+
after: string;
|
|
11
|
+
/** unified diff */
|
|
12
|
+
diff: string;
|
|
13
|
+
/** true if this was a newly created file */
|
|
14
|
+
isNewFile: boolean;
|
|
15
|
+
/** true if undo_edit has reverted this change */
|
|
16
|
+
reverted: boolean;
|
|
17
|
+
/** epoch ms when the edit occurred */
|
|
18
|
+
timestamp: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* record a file change to disk. call after performing the edit.
|
|
22
|
+
* the toolCallId comes from the execute() function's first argument.
|
|
23
|
+
* returns the change ID (UUID) for the written record.
|
|
24
|
+
*
|
|
25
|
+
* one tool call can produce multiple changes (e.g., Task sub-agent
|
|
26
|
+
* creating several files). each gets a unique UUID, stored as
|
|
27
|
+
* {toolCallId}.{uuid}.
|
|
28
|
+
*/
|
|
29
|
+
declare function saveChange(sessionId: string, toolCallId: string, change: Omit<FileChange, "id" | "reverted">): string;
|
|
30
|
+
/**
|
|
31
|
+
* load all change records for a tool call. one tool call can produce
|
|
32
|
+
* multiple changes (different files), each with its own UUID.
|
|
33
|
+
*/
|
|
34
|
+
declare function loadChanges(sessionId: string, toolCallId: string): FileChange[];
|
|
35
|
+
/**
|
|
36
|
+
* mark a specific change as reverted and restore the file.
|
|
37
|
+
* returns the change record, or null if not found / already reverted.
|
|
38
|
+
*/
|
|
39
|
+
declare function revertChange(sessionId: string, toolCallId: string, changeId: string): FileChange | null;
|
|
40
|
+
/**
|
|
41
|
+
* find the most recent non-reverted change for a file path,
|
|
42
|
+
* filtered to only the given tool call IDs (branch awareness).
|
|
43
|
+
*
|
|
44
|
+
* the caller gets activeToolCallIds by scanning the current
|
|
45
|
+
* session branch for edit_file/create_file tool calls.
|
|
46
|
+
*/
|
|
47
|
+
declare function findLatestChange(sessionId: string, filePath: string, activeToolCallIds: string[]): {
|
|
48
|
+
toolCallId: string;
|
|
49
|
+
change: FileChange;
|
|
50
|
+
} | null;
|
|
51
|
+
/**
|
|
52
|
+
* generate a unified diff between two strings.
|
|
53
|
+
*
|
|
54
|
+
* uses the `diff` npm package (Myers algorithm) when available for
|
|
55
|
+
* proper hunk-based output with context lines. context=3 matches
|
|
56
|
+
* git's default, producing gaps between distant changes that show()
|
|
57
|
+
* can elide in collapsed display.
|
|
58
|
+
*
|
|
59
|
+
* falls back to a naive line-by-line comparison when `diff` isn't
|
|
60
|
+
* installed (produces correct but less optimal output — every line
|
|
61
|
+
* is either +, -, or context with no hunk headers).
|
|
62
|
+
*/
|
|
63
|
+
declare function simpleDiff(filePath: string, before: string, after: string): string;
|
|
64
|
+
//#endregion
|
|
65
|
+
export { FileChange, findLatestChange, loadChanges, revertChange, saveChange, simpleDiff };
|