@xynogen/pix-core 0.4.0 → 0.4.2
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 +23 -0
- package/package.json +13 -2
- package/src/extension.ts +27 -2
- package/src/once.test.ts +29 -0
package/README.md
CHANGED
|
@@ -10,6 +10,8 @@ Pi activates extensions per installed package via each package's `pi.extensions`
|
|
|
10
10
|
|
|
11
11
|
## What's included
|
|
12
12
|
|
|
13
|
+
**UI / UX extensions**
|
|
14
|
+
|
|
13
15
|
| Package | Description |
|
|
14
16
|
|---|---|
|
|
15
17
|
| `pix-welcome` | ASCII π banner + startup health checks (version, auth, models, gitignore) |
|
|
@@ -22,6 +24,27 @@ Pi activates extensions per installed package via each package's `pi.extensions`
|
|
|
22
24
|
| `pix-skills` | Agent skill loader (`read_skills` tool + 23 bundled skills) |
|
|
23
25
|
| `pix-nudge` | Tool + capability nudge hooks |
|
|
24
26
|
|
|
27
|
+
**Tool suite** (drop-in replacements for Pi's built-in tools)
|
|
28
|
+
|
|
29
|
+
| Package | Description |
|
|
30
|
+
|---|---|
|
|
31
|
+
| `pix-read` | `read` — file read with syntax highlighting |
|
|
32
|
+
| `pix-write` | `write` — file write with split-diff rendering |
|
|
33
|
+
| `pix-edit` | `edit` — precise text replacement with per-edit diff |
|
|
34
|
+
| `pix-find` | `find` — glob search with FFF acceleration |
|
|
35
|
+
| `pix-grep` | `grep` — pattern search with FFF-prioritised results |
|
|
36
|
+
| `pix-ls` | `ls` — directory listing as an icon tree |
|
|
37
|
+
| `pix-bash` | `bash` — shell execution with framed output + exit-code summary |
|
|
38
|
+
| `pix-todo` | `todo` — durable execution checklist |
|
|
39
|
+
| `pix-ask` | `ask_user` — structured TUI questionnaire |
|
|
40
|
+
|
|
41
|
+
**Behaviour**
|
|
42
|
+
|
|
43
|
+
| Package | Description |
|
|
44
|
+
|---|---|
|
|
45
|
+
| `pix-optimizer` | Caveman mode + RTK tool rewriting + jq/TOON JSON compression (`/opt`) |
|
|
46
|
+
| `pix-gate` | Permission gate for dangerous bash commands |
|
|
47
|
+
|
|
25
48
|
## Install
|
|
26
49
|
|
|
27
50
|
```bash
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xynogen/pix-core",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Pi extension bundle — installs and activates all core pix-* extensions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/extension.ts",
|
|
@@ -46,7 +46,18 @@
|
|
|
46
46
|
"@xynogen/pix-models": "*",
|
|
47
47
|
"@xynogen/pix-update": "*",
|
|
48
48
|
"@xynogen/pix-commands": "*",
|
|
49
|
-
"@xynogen/pix-nudge": "*"
|
|
49
|
+
"@xynogen/pix-nudge": "*",
|
|
50
|
+
"@xynogen/pix-read": "*",
|
|
51
|
+
"@xynogen/pix-write": "*",
|
|
52
|
+
"@xynogen/pix-edit": "*",
|
|
53
|
+
"@xynogen/pix-find": "*",
|
|
54
|
+
"@xynogen/pix-grep": "*",
|
|
55
|
+
"@xynogen/pix-ls": "*",
|
|
56
|
+
"@xynogen/pix-bash": "*",
|
|
57
|
+
"@xynogen/pix-todo": "*",
|
|
58
|
+
"@xynogen/pix-ask": "*",
|
|
59
|
+
"@xynogen/pix-optimizer": "*",
|
|
60
|
+
"@xynogen/pix-gate": "*"
|
|
50
61
|
},
|
|
51
62
|
"peerDependencies": {
|
|
52
63
|
"@earendil-works/pi-coding-agent": "*",
|
package/src/extension.ts
CHANGED
|
@@ -12,17 +12,31 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
15
|
+
import registerAsk from "@xynogen/pix-ask/src/index.ts";
|
|
16
|
+
import registerBash from "@xynogen/pix-bash/src/extension.ts";
|
|
15
17
|
import registerCommands from "@xynogen/pix-commands/src/extension.ts";
|
|
16
18
|
import registerDiagnostics from "@xynogen/pix-diagnostics/src/extension.ts";
|
|
19
|
+
import registerEdit from "@xynogen/pix-edit/src/extension.ts";
|
|
20
|
+
import registerFind from "@xynogen/pix-find/src/extension.ts";
|
|
17
21
|
import registerFooter from "@xynogen/pix-footer/src/extension.ts";
|
|
22
|
+
import registerGate from "@xynogen/pix-gate/src/index.ts";
|
|
23
|
+
import registerGrep from "@xynogen/pix-grep/src/extension.ts";
|
|
24
|
+
import registerLs from "@xynogen/pix-ls/src/extension.ts";
|
|
18
25
|
import registerModels from "@xynogen/pix-models/src/extension.ts";
|
|
19
26
|
import registerNudge from "@xynogen/pix-nudge/src/extension.ts";
|
|
27
|
+
import registerOptimizer from "@xynogen/pix-optimizer/src/index.ts";
|
|
20
28
|
import registerPrompts from "@xynogen/pix-prompts/src/extension.ts";
|
|
29
|
+
import registerRead from "@xynogen/pix-read/src/extension.ts";
|
|
21
30
|
import registerSkills from "@xynogen/pix-skills/src/index.ts";
|
|
31
|
+
import registerTodo from "@xynogen/pix-todo/src/index.ts";
|
|
22
32
|
import registerUpdate from "@xynogen/pix-update/src/extension.ts";
|
|
23
33
|
import registerWelcome from "@xynogen/pix-welcome/src/extension.ts";
|
|
34
|
+
import registerWrite from "@xynogen/pix-write/src/extension.ts";
|
|
24
35
|
|
|
25
|
-
|
|
36
|
+
// Members accept either the full `ExtensionAPI` or pix-pretty's looser
|
|
37
|
+
// `PiPrettyApi` view of it. `ExtensionAPI` satisfies both, so we erase the
|
|
38
|
+
// param type at registration and pass the real host through unchanged.
|
|
39
|
+
type Factory = (pi: never) => void;
|
|
26
40
|
|
|
27
41
|
const MEMBERS: Factory[] = [
|
|
28
42
|
registerWelcome,
|
|
@@ -34,10 +48,21 @@ const MEMBERS: Factory[] = [
|
|
|
34
48
|
registerDiagnostics,
|
|
35
49
|
registerPrompts,
|
|
36
50
|
registerSkills,
|
|
51
|
+
registerRead,
|
|
52
|
+
registerWrite,
|
|
53
|
+
registerEdit,
|
|
54
|
+
registerFind,
|
|
55
|
+
registerGrep,
|
|
56
|
+
registerLs,
|
|
57
|
+
registerBash,
|
|
58
|
+
registerTodo,
|
|
59
|
+
registerAsk,
|
|
60
|
+
registerOptimizer,
|
|
61
|
+
registerGate,
|
|
37
62
|
];
|
|
38
63
|
|
|
39
64
|
export default function (pi: ExtensionAPI): void {
|
|
40
65
|
for (const register of MEMBERS) {
|
|
41
|
-
register(pi);
|
|
66
|
+
(register as (pi: ExtensionAPI) => void)(pi);
|
|
42
67
|
}
|
|
43
68
|
}
|
package/src/once.test.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { afterEach, describe, expect, it } from "bun:test";
|
|
2
|
+
import registerTodo from "@xynogen/pix-todo/src/todo.ts";
|
|
2
3
|
|
|
3
4
|
// Mirror of the per-member guard. pix-core does not own once.ts (each member
|
|
4
5
|
// duplicates it to stay cross-dep-free), so we re-declare the contract here and
|
|
@@ -60,3 +61,31 @@ describe("once", () => {
|
|
|
60
61
|
).toBe(true);
|
|
61
62
|
});
|
|
62
63
|
});
|
|
64
|
+
|
|
65
|
+
// Behavior pin: prove a REAL guarded member dedupes when its factory runs
|
|
66
|
+
// twice — the exact scenario the aggregator creates when a tool is installed
|
|
67
|
+
// both via pix-core (this boots it) and standalone (Pi boots it again). The
|
|
68
|
+
// member must register its tool only once or Pi reports a tool conflict.
|
|
69
|
+
describe("member factory dedupe (pix-todo)", () => {
|
|
70
|
+
function makeHost() {
|
|
71
|
+
const toolNames: string[] = [];
|
|
72
|
+
const pi = {
|
|
73
|
+
registerTool(def: { name: string }) {
|
|
74
|
+
toolNames.push(def.name);
|
|
75
|
+
},
|
|
76
|
+
appendEntry() {},
|
|
77
|
+
on() {},
|
|
78
|
+
} as never;
|
|
79
|
+
return { pi, toolNames };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
it("registers the tool once across core + standalone activation", () => {
|
|
83
|
+
const { pi, toolNames } = makeHost();
|
|
84
|
+
// First pass: pix-core's aggregator invokes the member factory.
|
|
85
|
+
registerTodo(pi);
|
|
86
|
+
// Second pass: standalone install loads the same module and invokes it
|
|
87
|
+
// again. The globalThis once() registry must suppress re-registration.
|
|
88
|
+
registerTodo(pi);
|
|
89
|
+
expect(toolNames).toEqual(["todo"]);
|
|
90
|
+
});
|
|
91
|
+
});
|