@primitive.ai/prim 0.1.0-alpha.35 → 0.1.0-alpha.36
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 +15 -6
- package/SKILL.md +16 -12
- package/dist/index.js +6 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
# @primitive.ai/prim
|
|
2
2
|
|
|
3
3
|
The official CLI for [Primitive](https://getprimitive.ai)'s **decision graph**. It
|
|
4
|
-
passively captures the decisions your team makes while coding
|
|
5
|
-
|
|
6
|
-
line and via session + git hooks.
|
|
4
|
+
passively captures the decisions your team makes while coding and reports team
|
|
5
|
+
presence — from the command line and via session + git hooks.
|
|
7
6
|
|
|
8
7
|
> [!WARNING]
|
|
9
8
|
> This project is in **alpha**. Commands and APIs may change between releases.
|
|
10
9
|
|
|
10
|
+
> [!NOTE]
|
|
11
|
+
> **Conflict Gates** check each edit against the decision graph and surface any
|
|
12
|
+
> load-bearing decision it conflicts with; their **Enforcement** tier blocks or pauses
|
|
13
|
+
> a conflicting edit until you reconcile and retry. Conflict Gates are **not currently
|
|
14
|
+
> enabled** — automatic decision capture runs regardless. To enable them for your team,
|
|
15
|
+
> contact **support@getprimitive.ai**.
|
|
16
|
+
|
|
11
17
|
## Installation
|
|
12
18
|
|
|
13
19
|
Requires Node.js 20+.
|
|
@@ -37,7 +43,7 @@ Or run the steps individually:
|
|
|
37
43
|
# 1. Authenticate via browser (WorkOS OAuth)
|
|
38
44
|
prim auth login
|
|
39
45
|
|
|
40
|
-
# 2. Wire the session hooks (decision capture +
|
|
46
|
+
# 2. Wire the session hooks (decision capture + presence)
|
|
41
47
|
prim claude install # or: prim codex install / prim hermes install
|
|
42
48
|
|
|
43
49
|
# 3. Start the companion daemon (latency + team presence)
|
|
@@ -94,7 +100,7 @@ prim auth status # Check authentication status
|
|
|
94
100
|
### Session integration
|
|
95
101
|
|
|
96
102
|
Wires the agent's session hooks so the decisions you make are captured into the
|
|
97
|
-
graph,
|
|
103
|
+
graph, and presence is reported. Each hook
|
|
98
104
|
self-resolves the CLI at run time (PATH, then a local install, then
|
|
99
105
|
`npx --yes @latest`), so it keeps working with no global install.
|
|
100
106
|
|
|
@@ -147,9 +153,12 @@ would create a cycle (exit 2); an unresolved id exits 4.
|
|
|
147
153
|
### Reconcile
|
|
148
154
|
|
|
149
155
|
```bash
|
|
150
|
-
prim reconcile <id> # Mint a single-use bypass for a decision
|
|
156
|
+
prim reconcile <id> # Mint a single-use bypass for a decision Conflict Gates flagged
|
|
151
157
|
```
|
|
152
158
|
|
|
159
|
+
Part of Conflict Gates **Enforcement**, which is not currently enabled (see the note
|
|
160
|
+
at the top). Contact support@getprimitive.ai to enable it.
|
|
161
|
+
|
|
153
162
|
### Hooks
|
|
154
163
|
|
|
155
164
|
```bash
|
package/SKILL.md
CHANGED
|
@@ -9,9 +9,9 @@ description: Use the prim CLI for Primitive's decision graph — passive decisio
|
|
|
9
9
|
|
|
10
10
|
## Mental model
|
|
11
11
|
|
|
12
|
-
As your team codes, prim passively captures the **decisions** you make -- which library, which pattern, which config value -- into a queryable graph, and links them: a decision can depend on earlier decisions (auto-linked from shared files, or related by hand — see *Relate decisions*) and reference the files it touched.
|
|
12
|
+
As your team codes, prim passively captures the **decisions** you make -- which library, which pattern, which config value -- into a queryable graph, and links them: a decision can depend on earlier decisions (auto-linked from shared files, or related by hand — see *Relate decisions*) and reference the files it touched. **Conflict Gates** can check a later change against that graph and surface any load-bearing decision it conflicts with; with **Enforcement**, prim blocks the edit until you reconcile the decision and retry. Conflict Gates are **not currently enabled** — capture runs regardless. To enable them for your team, contact support@getprimitive.ai.
|
|
13
13
|
|
|
14
|
-
You never invoke capture. It runs automatically through the session hooks installed by `npx --yes @primitive.ai/prim claude install` (Claude Code), `npx --yes @primitive.ai/prim codex install` (Codex), or `npx --yes @primitive.ai/prim hermes install` (Hermes). Your job is to **
|
|
14
|
+
You never invoke capture. It runs automatically through the session hooks installed by `npx --yes @primitive.ai/prim claude install` (Claude Code), `npx --yes @primitive.ai/prim codex install` (Codex), or `npx --yes @primitive.ai/prim hermes install` (Hermes). Your job is to **read** the graph before load-bearing edits and **answer** the occasional rationale confirmation. (Responding to Conflict Gates applies only once Enforcement is enabled — see below.)
|
|
15
15
|
|
|
16
16
|
## Auth
|
|
17
17
|
|
|
@@ -29,17 +29,19 @@ The CLI auto-refreshes a still-valid session from the stored refresh token (proa
|
|
|
29
29
|
|
|
30
30
|
1. Every command accepts `--help`. When unsure of flags, run `npx --yes @primitive.ai/prim <cmd> --help` rather than guessing.
|
|
31
31
|
2. The CLI prints API errors as one-liners to stderr and exits non-zero. Treat any non-zero exit as actionable. If auth-related, re-check `auth status`.
|
|
32
|
-
3. `<idOrShortId>` arguments accept either a full decision ID or the short ID shown in feeds and gate reasons.
|
|
32
|
+
3. `<idOrShortId>` arguments accept either a full decision ID or the short ID shown in feeds (and gate reasons, when Conflict Gates are enabled).
|
|
33
33
|
|
|
34
|
-
##
|
|
34
|
+
## Conflict Gates & Enforcement (not currently enabled)
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
**Conflict Gates** check each edit against the decision graph before it lands and surface any load-bearing decision it conflicts with. Their **Enforcement** tier goes further -- a conflicting edit is blocked (or paused for confirmation) until you reconcile the decision and retry. **Conflict Gates are not currently enabled** — automatic decision capture (above) runs regardless. To enable Conflict Gates and Enforcement for your team, contact support@getprimitive.ai.
|
|
37
|
+
|
|
38
|
+
When Enforcement is enabled, before an edit (Claude Code: Edit/Write/MultiEdit; Codex: apply_patch; Hermes: write_file/patch) a PreToolUse hook scores the target file against the graph:
|
|
37
39
|
|
|
38
40
|
- **deny** -- the edit is blocked: it conflicts with a load-bearing prior decision. Don't fight it. Read the reason line; it names the decision id. If you genuinely intend to override that decision, run `npx --yes @primitive.ai/prim reconcile dec_<shortId>`, then retry the edit once. Otherwise choose an approach that respects the decision.
|
|
39
41
|
- **warn / additional context** -- the edit proceeds, but a relevant prior decision is surfaced. Read it. On Codex a would-be `ask` is delivered as allow-plus-context (Codex can't pause mid-tool), so that context is your only signal -- read it before continuing. Hermes has no soft-confirm tier, so a would-be `ask` arrives as a **deny** carrying the same reconcile directive: reconcile and retry, or set `PRIM_HOOK_MODE=warn` to downgrade it to context-only.
|
|
40
42
|
- **"decision check skipped / not verified" or "... partial / truncated"** -- the check could not fully run. Treat constraints as UNKNOWN, not clear; never read silence as approval.
|
|
41
43
|
|
|
42
|
-
|
|
44
|
+
When enabled, the gate fail-opens on its *own* infrastructure errors (no daemon, network blip, org-unbound token) -- a setup problem would not block your edit. That is why an "unavailable" note would matter: it is the honest signal that the check, not your edit, is what failed.
|
|
43
45
|
|
|
44
46
|
## Read the graph before large or load-bearing edits
|
|
45
47
|
|
|
@@ -49,6 +51,8 @@ The gate fail-opens on its *own* infrastructure errors (no daemon, network blip,
|
|
|
49
51
|
|
|
50
52
|
## Reconcile and the verdict footer
|
|
51
53
|
|
|
54
|
+
Reconcile and the verdict footer are part of Conflict Gates **Enforcement**, which is **not currently enabled** (contact support@getprimitive.ai to turn it on); the `reconcile` command stays available regardless. When Enforcement is on:
|
|
55
|
+
|
|
52
56
|
`npx --yes @primitive.ai/prim reconcile <idOrShortId>` mints a single-use bypass for the named decision -- it prints `[prim] reconcile bypass issued for dec_<short> (expires in ...)` to STDERR, with the bypass JSON on STDOUT. Your *next* edit to the governed file then goes through, and on that edit prim prints a verdict footer to STDERR -- confirmation the override was recorded, not silently dropped:
|
|
53
57
|
|
|
54
58
|
```
|
|
@@ -75,7 +79,7 @@ Capture is automatic for the decisions you *make while coding*. When the user in
|
|
|
75
79
|
npx --yes @primitive.ai/prim decisions create --intent "Adopt prosemirror-collab over Yjs" --area data --rationale "Server-authoritative ordering" --alternatives "Yjs,Automerge"
|
|
76
80
|
```
|
|
77
81
|
|
|
78
|
-
Only `--intent` is required. Optional: `--kind` (change|exploration|task_execution|unclear, default change), `--rationale`, `--area`, `--decided`, `--alternatives` (comma-separated), `--confidence` (high|medium|low, default high), `--reversibility` (high|low, default high), and `--files` (comma-separated repo-relative paths the decision governs —
|
|
82
|
+
Only `--intent` is required. Optional: `--kind` (change|exploration|task_execution|unclear, default change), `--rationale`, `--area`, `--decided`, `--alternatives` (comma-separated), `--confidence` (high|medium|low, default high), `--reversibility` (high|low, default high), and `--files` (comma-separated repo-relative paths the decision governs — these are the files Conflict Gates would check on later edits, same path form as `decisions check`; Conflict Gates are not currently enabled). STDOUT is the created identity `{ decisionId, shortId, createdAt }`; STDERR prints `[prim] created dec_<short>.` — pass that `dec_<short>` straight into `decisions show` / `cascade` / `confirm`. Author on the user's behalf only when they ask for a decision to be recorded; don't narrate your own routine edits into the graph (the hooks already do that).
|
|
79
83
|
|
|
80
84
|
## Relate decisions (link / unlink)
|
|
81
85
|
|
|
@@ -116,14 +120,14 @@ npx --yes @primitive.ai/prim hooks uninstall
|
|
|
116
120
|
|
|
117
121
|
Under `CI=1` (or with `--non-interactive`), `hooks install` fails fast in a Husky repo unless `--yes` or `--target` is set; the error names both escapes. `hooks uninstall` only removes the `.git/hooks` copies — if a hook was installed into `.husky/`, remove the prim block from that file manually. To suppress the hooks for one commit, use `git commit --no-verify`.
|
|
118
122
|
|
|
119
|
-
These git hooks are separate from the **session hooks** (`claude install` / `codex install` / `hermes install`) that drive in-session capture and
|
|
123
|
+
These git hooks are separate from the **session hooks** (`claude install` / `codex install` / `hermes install`) that drive in-session capture (and Conflict Gates, when enabled).
|
|
120
124
|
|
|
121
125
|
## Output formats
|
|
122
126
|
|
|
123
127
|
The CLI keeps STDOUT machine-readable and STDERR human-readable. The `decisions` and `reconcile` commands **always** emit a single JSON document on STDOUT — no flag needed; pipe straight to `jq`. The `decisions` commands have **no** `--json` flag and reject one; `reconcile` accepts a reserved no-op `--json`. `auth status` and `skill status` default to human-readable STDOUT and take `--json` to switch to JSON.
|
|
124
128
|
|
|
125
129
|
- **STDOUT is machine-readable** — JSON (one document per invocation). `decisions` reads project lean shapes, not raw rows.
|
|
126
|
-
- **STDERR is human-readable** — a verdict-first line, plus the gate/verdict-footer
|
|
130
|
+
- **STDERR is human-readable** — a verdict-first line, plus presence notes (and, when Conflict Gates are enabled, the gate/verdict-footer notes).
|
|
127
131
|
- **Exit code is authoritative** where it carries meaning — `auth status` exits 0 when authenticated; `decisions show`/`cascade`/`confirm` exit non-zero (e.g. 4 not-found) on a missing or unauthorized id.
|
|
128
132
|
|
|
129
133
|
Examples:
|
|
@@ -135,12 +139,12 @@ Examples:
|
|
|
135
139
|
|
|
136
140
|
## Pitfalls
|
|
137
141
|
|
|
138
|
-
- **An "unavailable" / "not verified"
|
|
139
|
-
- **
|
|
142
|
+
- **An "unavailable" / "not verified" decision check is not an all-clear.** Treat constraints as UNKNOWN and proceed deliberately; never read the silence as approval — the same holds for Conflict Gates once enabled.
|
|
143
|
+
- **When Enforcement is enabled, a `deny` means a real prior decision conflicts.** Reconcile only when you genuinely intend to override it; otherwise pick an approach that respects it.
|
|
140
144
|
- **Reconcile bypasses are single-use and short-lived.** One bypass clears your *next* edit to the governed file; it is not a standing override.
|
|
141
145
|
- **Capture of your coding activity is automatic, never manual.** If decisions aren't showing up, check that the session hooks are installed (`claude status` / `codex status` / `hermes status`) and the daemon is running — don't try to inject moves by hand. (Deliberately *authoring* a decision the user asks you to record is a separate, supported path — `decisions create`, above.)
|
|
142
146
|
- **Don't fabricate rationale on a confirmation.** If you don't know why a decision was made, say so rather than guessing.
|
|
143
147
|
|
|
144
148
|
## After each task
|
|
145
149
|
|
|
146
|
-
If
|
|
150
|
+
If Conflict Gates are enabled and one denied or warned you, report which decision(s) it named and whether you reconciled. If you read the graph before a load-bearing change, note what you found so the user can verify in the dashboard.
|
package/dist/index.js
CHANGED
|
@@ -2105,7 +2105,7 @@ function registerDecisionsCommands(program2) {
|
|
|
2105
2105
|
"Functional area (auth, data, infra, ui, api, billing, mobile, docs, testing)"
|
|
2106
2106
|
).option("--decided <items>", "Comma-separated option(s) chosen").option("--alternatives <items>", "Comma-separated options considered but rejected").option("--confidence <level>", "high | medium | low (default high)").option("--reversibility <level>", "high | low (default high)").option(
|
|
2107
2107
|
"--files <paths>",
|
|
2108
|
-
"Comma-separated repo-relative paths this decision governs (
|
|
2108
|
+
"Comma-separated repo-relative paths this decision governs (the files Conflict Gates would check \u2014 not currently enabled)"
|
|
2109
2109
|
).action(async (opts) => {
|
|
2110
2110
|
const request = {
|
|
2111
2111
|
intent: opts.intent,
|
|
@@ -3265,7 +3265,7 @@ async function performReconcile(idOrShortId, opts = {}) {
|
|
|
3265
3265
|
}
|
|
3266
3266
|
function registerReconcileCommands(program2) {
|
|
3267
3267
|
program2.command("reconcile <idOrShortId>").description(
|
|
3268
|
-
"Issue a single-use bypass for a
|
|
3268
|
+
"Issue a single-use bypass for a decision flagged by Conflict Gates Enforcement (not currently enabled)"
|
|
3269
3269
|
).option(
|
|
3270
3270
|
"--flag <conflictFlagId>",
|
|
3271
3271
|
"Specific flag id to bind the bypass to (default: the decision's latest unack'd flag)"
|
|
@@ -3925,14 +3925,13 @@ function formatWelcome(state) {
|
|
|
3925
3925
|
bold(color("Welcome to Primitive", "green")),
|
|
3926
3926
|
"",
|
|
3927
3927
|
"Primitive captures the decisions your team makes while coding into a",
|
|
3928
|
-
"shared graph \u2014
|
|
3929
|
-
"they land.",
|
|
3928
|
+
"shared graph \u2014 automatically, as you work.",
|
|
3930
3929
|
"",
|
|
3931
3930
|
bold("How it works"),
|
|
3932
3931
|
bullet("Capture is automatic \u2014 keep coding; your decisions are recorded for you."),
|
|
3933
|
-
bullet("
|
|
3934
|
-
" load-bearing decision
|
|
3935
|
-
"
|
|
3932
|
+
bullet("Conflict Gates (with Enforcement) flag or block edits that conflict"),
|
|
3933
|
+
" with a load-bearing decision \u2014 not currently enabled. Contact",
|
|
3934
|
+
" support@getprimitive.ai to turn them on for your team.",
|
|
3936
3935
|
bullet('Occasional yes/no prompts confirm the "why" behind a decision \u2014'),
|
|
3937
3936
|
" answering keeps the graph trustworthy.",
|
|
3938
3937
|
""
|
package/package.json
CHANGED