@xynogen/pix-toolbox 0.2.0 → 0.2.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/README.md +1 -1
- package/package.json +4 -3
- package/src/toolbox.ts +25 -23
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ Registers a `/toolbox` slash command — a TUI fuzzy-search picker listing every
|
|
|
15
15
|
Keys: `tab` switch tab · `↑↓` navigate · `ctrl+e` enable · `ctrl+f` defer · `ctrl+d` disable · `space` cycle · any other key types into the search.
|
|
16
16
|
|
|
17
17
|
- Four tools (`bash`, `edit`, `read`, `write`) are protected and stay enabled.
|
|
18
|
-
- State persists to `~/.pi/agent/
|
|
18
|
+
- State persists to `~/.pi/agent/pix.json` under `toolbox`. Only changes from the default are saved: `disabledTools` (tools you disabled) and `loadedTools` (deferred tools you enabled). A newly installed tool keeps its default. A legacy `enabledTools` file is migrated on the next session start.
|
|
19
19
|
- Headless subcommands: `/toolbox enable|defer|disable <names>`, `/toolbox list [query]`.
|
|
20
20
|
|
|
21
21
|
## Install
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xynogen/pix-toolbox",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "Pi tool
|
|
3
|
+
"version": "0.2.1",
|
|
4
|
+
"description": "Pi tool \u2014 gated tool toggle UI (/toolbox)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"scripts": {
|
|
@@ -35,7 +35,8 @@
|
|
|
35
35
|
"access": "public"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@xynogen/pix-pretty": "^1.
|
|
38
|
+
"@xynogen/pix-pretty": "^1.30.0",
|
|
39
|
+
"@xynogen/pix-runtime": "^0.13.0"
|
|
39
40
|
},
|
|
40
41
|
"peerDependencies": {
|
|
41
42
|
"@earendil-works/pi-coding-agent": "*",
|
package/src/toolbox.ts
CHANGED
|
@@ -13,15 +13,12 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import { createHash } from "node:crypto";
|
|
16
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
17
|
-
import { dirname, join } from "node:path";
|
|
18
16
|
import type {
|
|
19
17
|
ExtensionAPI,
|
|
20
18
|
ExtensionContext,
|
|
21
19
|
Theme,
|
|
22
20
|
ToolInfo,
|
|
23
21
|
} from "@earendil-works/pi-coding-agent";
|
|
24
|
-
import { getAgentDir } from "@earendil-works/pi-coding-agent";
|
|
25
22
|
import {
|
|
26
23
|
fuzzyFilter,
|
|
27
24
|
Input,
|
|
@@ -41,6 +38,8 @@ import {
|
|
|
41
38
|
modalWidth,
|
|
42
39
|
terminalModalHeight,
|
|
43
40
|
} from "@xynogen/pix-pretty/modal-frame";
|
|
41
|
+
import { config, pixRuntime, updateConfig } from "@xynogen/pix-runtime/config";
|
|
42
|
+
import { toolboxSection } from "@xynogen/pix-runtime/sections";
|
|
44
43
|
|
|
45
44
|
// ─── Constants ──────────────────────────────────────────────────────────────
|
|
46
45
|
|
|
@@ -196,10 +195,6 @@ interface ToolboxState {
|
|
|
196
195
|
enabledTools?: string[];
|
|
197
196
|
}
|
|
198
197
|
|
|
199
|
-
function getStatePath(): string {
|
|
200
|
-
return join(getAgentDir(), "toolbox.json");
|
|
201
|
-
}
|
|
202
|
-
|
|
203
198
|
const isStringArray = (v: unknown): v is string[] =>
|
|
204
199
|
Array.isArray(v) && v.every((x) => typeof x === "string");
|
|
205
200
|
|
|
@@ -286,26 +281,32 @@ function createState(pi: ExtensionAPI) {
|
|
|
286
281
|
console.warn("toolbox: persist failed:", err);
|
|
287
282
|
}
|
|
288
283
|
// Write to disk so state survives across completely new sessions
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
284
|
+
void updateConfig(toolboxSection, { ...data, loadedTools: data.loadedTools ?? [] })
|
|
285
|
+
.then((change) => {
|
|
286
|
+
if (
|
|
287
|
+
!change &&
|
|
288
|
+
JSON.stringify(config(toolboxSection).disabledTools) !==
|
|
289
|
+
JSON.stringify(data.disabledTools)
|
|
290
|
+
)
|
|
291
|
+
pi.sendMessage({
|
|
292
|
+
customType: "toolbox-error",
|
|
293
|
+
content: "Failed to save toolbox settings to pix.json",
|
|
294
|
+
display: true,
|
|
295
|
+
});
|
|
296
|
+
})
|
|
297
|
+
.catch((err) =>
|
|
298
|
+
pi.sendMessage({
|
|
299
|
+
customType: "toolbox-error",
|
|
300
|
+
content: `Failed to save toolbox settings: ${String(err)}`,
|
|
301
|
+
display: true,
|
|
302
|
+
}),
|
|
303
|
+
);
|
|
296
304
|
}
|
|
297
305
|
|
|
298
306
|
/** Raw persisted state from disk, or undefined when absent/corrupt. */
|
|
299
307
|
function loadFromFile(): { raw: unknown; legacy: boolean } | undefined {
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
if (!existsSync(sp)) return undefined;
|
|
303
|
-
const raw = JSON.parse(readFileSync(sp, "utf-8")) as ToolboxState;
|
|
304
|
-
return { raw, legacy: !isStringArray(raw?.disabledTools) };
|
|
305
|
-
} catch {
|
|
306
|
-
// corrupt, or a test env without getAgentDir
|
|
307
|
-
return undefined;
|
|
308
|
-
}
|
|
308
|
+
const raw = config(toolboxSection);
|
|
309
|
+
return Object.keys(raw).length ? { raw, legacy: !isStringArray(raw.disabledTools) } : undefined;
|
|
309
310
|
}
|
|
310
311
|
|
|
311
312
|
/** Latest toolbox-config entry in the session, or undefined. */
|
|
@@ -397,6 +398,7 @@ export default function registerToolbox(pi: ExtensionAPI): void {
|
|
|
397
398
|
// Defer init until tools are registered — session_start fires after all extensions load.
|
|
398
399
|
// Try to restore persisted state; fall back to full init if no config found.
|
|
399
400
|
pi.on("session_start", async (_event, ctx) => {
|
|
401
|
+
await pixRuntime().init();
|
|
400
402
|
state.restoreFromBranch(ctx);
|
|
401
403
|
});
|
|
402
404
|
|