@primitive.ai/prim 0.1.0-alpha.34 → 0.1.0-alpha.35
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 +16 -7
- package/dist/{chunk-4QJOQIY6.js → chunk-AAGJFO7C.js} +11 -0
- package/dist/chunk-LUPD2JSH.js +78 -0
- package/dist/hooks/post-tool-use.js +8 -1
- package/dist/hooks/pre-tool-use.js +7 -0
- package/dist/hooks/prim-hook.js +11 -6
- package/dist/index.js +797 -161
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -192,13 +192,22 @@ prim moves flush # Drain the local journals to the server (also runs fr
|
|
|
192
192
|
### Skill
|
|
193
193
|
|
|
194
194
|
```bash
|
|
195
|
-
prim skill install
|
|
196
|
-
prim skill
|
|
197
|
-
prim skill
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
195
|
+
prim skill install --agent claude # Install the decision-graph guide for Claude Code
|
|
196
|
+
prim skill install --agent codex # …or write the guide into another agent's rules file
|
|
197
|
+
prim skill uninstall --agent claude # Remove it
|
|
198
|
+
prim skill status --agent claude # Report whether it's installed
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Teaches your agent how to work with the decision graph. For **Claude Code**
|
|
202
|
+
(`--agent claude`) this installs a skills-directory plugin at
|
|
203
|
+
`<repo>/.claude/skills/prim/` (or `~/.claude/skills/prim/` with `--scope user`)
|
|
204
|
+
— a `.claude-plugin/plugin.json` + `SKILL.md` that auto-loads as the model-invoked
|
|
205
|
+
`prim@skills-dir` skill, no marketplace step; restart Claude Code or run
|
|
206
|
+
`/reload-plugins` after installing. For every other agent it writes a managed
|
|
207
|
+
block into the rules file that agent reads (`--agent codex` → AGENTS.md,
|
|
208
|
+
`--agent hermes` → .hermes.md, or an auto-detected .cursor/rules, …). A bare
|
|
209
|
+
`prim skill install` (no `--agent`) auto-detects a rules file and writes the
|
|
210
|
+
block; pass `--target <path>` for an explicit file.
|
|
202
211
|
|
|
203
212
|
## Development
|
|
204
213
|
|
|
@@ -54,6 +54,16 @@ function colorForArea(area) {
|
|
|
54
54
|
}
|
|
55
55
|
return AREA_COLORS[area] ?? "gray";
|
|
56
56
|
}
|
|
57
|
+
function stripControlChars(text) {
|
|
58
|
+
let out = "";
|
|
59
|
+
for (const ch of text) {
|
|
60
|
+
const code = ch.codePointAt(0) ?? 0;
|
|
61
|
+
if (code > 31 && !(code >= 127 && code <= 159)) {
|
|
62
|
+
out += ch;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return out;
|
|
66
|
+
}
|
|
57
67
|
function stripAnsi(text) {
|
|
58
68
|
return text.replace(/\u001b\[[0-9;]*m/g, "");
|
|
59
69
|
}
|
|
@@ -63,5 +73,6 @@ export {
|
|
|
63
73
|
dim,
|
|
64
74
|
bold,
|
|
65
75
|
colorForArea,
|
|
76
|
+
stripControlChars,
|
|
66
77
|
stripAnsi
|
|
67
78
|
};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// src/lib/activation.ts
|
|
2
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
3
|
+
import { existsSync, readFileSync } from "fs";
|
|
4
|
+
import { homedir } from "os";
|
|
5
|
+
import { join } from "path";
|
|
6
|
+
|
|
7
|
+
// src/lib/git.ts
|
|
8
|
+
import { execFileSync } from "child_process";
|
|
9
|
+
function gitToplevel(cwd) {
|
|
10
|
+
try {
|
|
11
|
+
return execFileSync("git", ["rev-parse", "--show-toplevel"], {
|
|
12
|
+
cwd,
|
|
13
|
+
encoding: "utf-8",
|
|
14
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
15
|
+
}).trim();
|
|
16
|
+
} catch {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// src/lib/activation.ts
|
|
22
|
+
var PRIM_ACTIVE_KEY = "prim.active";
|
|
23
|
+
var PROJECT_INSTALL_FILES = [".claude/settings.json", ".codex/hooks.json"];
|
|
24
|
+
var PRIM_HOOK_BINS = ["prim-hook", "prim-pre-tool-use", "prim-post-tool-use"];
|
|
25
|
+
function repoActiveFlag(cwd) {
|
|
26
|
+
try {
|
|
27
|
+
const value = execFileSync2("git", ["config", "--get", PRIM_ACTIVE_KEY], {
|
|
28
|
+
cwd,
|
|
29
|
+
encoding: "utf-8",
|
|
30
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
31
|
+
}).trim();
|
|
32
|
+
if (value === "true") return "true";
|
|
33
|
+
if (value === "false") return "false";
|
|
34
|
+
return void 0;
|
|
35
|
+
} catch {
|
|
36
|
+
return void 0;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function setRepoActive(cwd, active) {
|
|
40
|
+
execFileSync2("git", ["config", "--local", PRIM_ACTIVE_KEY, active ? "true" : "false"], {
|
|
41
|
+
cwd,
|
|
42
|
+
stdio: ["ignore", "ignore", "pipe"]
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
function activateRepoBestEffort(cwd) {
|
|
46
|
+
try {
|
|
47
|
+
setRepoActive(cwd, true);
|
|
48
|
+
} catch {
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function hasProjectPrimInstall(cwd) {
|
|
52
|
+
const root = gitToplevel(cwd);
|
|
53
|
+
if (root === null || root === homedir()) return false;
|
|
54
|
+
for (const rel of PROJECT_INSTALL_FILES) {
|
|
55
|
+
const path = join(root, rel);
|
|
56
|
+
if (existsSync(path)) {
|
|
57
|
+
try {
|
|
58
|
+
const content = readFileSync(path, "utf-8");
|
|
59
|
+
if (PRIM_HOOK_BINS.some((bin) => content.includes(bin))) return true;
|
|
60
|
+
} catch {
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
function isRepoActiveForCapture(cwd) {
|
|
67
|
+
const flag = repoActiveFlag(cwd);
|
|
68
|
+
if (flag === "true") return true;
|
|
69
|
+
if (flag === "false") return false;
|
|
70
|
+
return hasProjectPrimInstall(cwd);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export {
|
|
74
|
+
gitToplevel,
|
|
75
|
+
setRepoActive,
|
|
76
|
+
activateRepoBestEffort,
|
|
77
|
+
isRepoActiveForCapture
|
|
78
|
+
};
|
|
@@ -2,13 +2,16 @@
|
|
|
2
2
|
import {
|
|
3
3
|
bold,
|
|
4
4
|
color
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-AAGJFO7C.js";
|
|
6
6
|
import {
|
|
7
7
|
scrubFromCwd
|
|
8
8
|
} from "../chunk-6LAQVM26.js";
|
|
9
9
|
import {
|
|
10
10
|
toMove
|
|
11
11
|
} from "../chunk-S2O4P4A3.js";
|
|
12
|
+
import {
|
|
13
|
+
isRepoActiveForCapture
|
|
14
|
+
} from "../chunk-LUPD2JSH.js";
|
|
12
15
|
import {
|
|
13
16
|
getClient
|
|
14
17
|
} from "../chunk-26VA3ADF.js";
|
|
@@ -128,6 +131,10 @@ async function main() {
|
|
|
128
131
|
return;
|
|
129
132
|
}
|
|
130
133
|
const cwd = parsed.cwd ?? process.cwd();
|
|
134
|
+
if (!isRepoActiveForCapture(cwd)) {
|
|
135
|
+
emit();
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
131
138
|
const base = toMove(parsed, resolveCliVersion(), agent);
|
|
132
139
|
const move = { ...base, payload: scrubFromCwd(parsed, cwd) };
|
|
133
140
|
try {
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
isRepoActiveForCapture
|
|
4
|
+
} from "../chunk-LUPD2JSH.js";
|
|
2
5
|
import {
|
|
3
6
|
getClient,
|
|
4
7
|
getSiteUrl
|
|
@@ -295,6 +298,10 @@ async function main() {
|
|
|
295
298
|
emit(failOpen());
|
|
296
299
|
return;
|
|
297
300
|
}
|
|
301
|
+
if (!isRepoActiveForCapture(cwd)) {
|
|
302
|
+
emit(failOpen());
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
298
305
|
let results;
|
|
299
306
|
try {
|
|
300
307
|
results = await Promise.all(files.map((f) => checkOneFile(f)));
|
package/dist/hooks/prim-hook.js
CHANGED
|
@@ -10,6 +10,9 @@ import {
|
|
|
10
10
|
shouldFlushAfter,
|
|
11
11
|
toMove
|
|
12
12
|
} from "../chunk-S2O4P4A3.js";
|
|
13
|
+
import {
|
|
14
|
+
isRepoActiveForCapture
|
|
15
|
+
} from "../chunk-LUPD2JSH.js";
|
|
13
16
|
import "../chunk-26VA3ADF.js";
|
|
14
17
|
import {
|
|
15
18
|
normalizeEnvelope,
|
|
@@ -42,12 +45,14 @@ try {
|
|
|
42
45
|
const raw = readFileSync(0, "utf-8");
|
|
43
46
|
const parsed = normalizeEnvelope(JSON.parse(raw), agent);
|
|
44
47
|
const cwd = parsed.cwd ?? process.cwd();
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
if (isRepoActiveForCapture(cwd)) {
|
|
49
|
+
const base = toMove(parsed, resolveCliVersion(), agent);
|
|
50
|
+
const move = { ...base, payload: scrubFromCwd(parsed, cwd) };
|
|
51
|
+
const { orgId } = resolveOrg({ sessionId: move.sessionId, cwd: move.env.cwd });
|
|
52
|
+
appendMove(move, orgId);
|
|
53
|
+
if (shouldFlushAfter(move.eventType)) {
|
|
54
|
+
spawnBackgroundFlush();
|
|
55
|
+
}
|
|
51
56
|
}
|
|
52
57
|
} catch (err) {
|
|
53
58
|
if (process.env.PRIM_HOOK_DEBUG) {
|