@primitive.ai/prim 0.1.0-alpha.53 → 0.1.0-alpha.55
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 +11 -4
- package/SKILL.md +12 -6
- package/dist/index.js +15 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,8 +31,8 @@ npx @primitive.ai/prim
|
|
|
31
31
|
In commands such as `npx --yes @primitive.ai/prim@latest ...`, the first `--yes`
|
|
32
32
|
belongs to **npm**: it skips npm's package-install confirmation. It does not approve a
|
|
33
33
|
Primitive action. Prim's own global `--yes` comes after the package name, for example
|
|
34
|
-
`npx --yes @primitive.ai/prim@latest --yes decisions create
|
|
35
|
-
that Prim invocation.
|
|
34
|
+
`npx --yes @primitive.ai/prim@latest --yes decisions create ... --attribution user`,
|
|
35
|
+
and applies only to that Prim invocation.
|
|
36
36
|
|
|
37
37
|
## Quick Start
|
|
38
38
|
|
|
@@ -215,7 +215,7 @@ prim decisions show <id> # Drill into one decision
|
|
|
215
215
|
prim decisions cascade <id> # Blast radius of a decision
|
|
216
216
|
prim decisions check --files <…> # Active decisions referencing files (warn-only)
|
|
217
217
|
prim decisions confirm <id> # Answer a rationale-confirmation prompt
|
|
218
|
-
prim decisions create --intent <…>
|
|
218
|
+
prim decisions create --intent <…> --attribution <user|agent> # Record with explicit origin
|
|
219
219
|
prim decisions link <child> --on <parent> # Relate: <child> depends on <parent>
|
|
220
220
|
prim decisions unlink <child> --on <parent> # Remove that dependency
|
|
221
221
|
```
|
|
@@ -226,12 +226,19 @@ JSON; human-readable status goes to STDERR.
|
|
|
226
226
|
When passive capture is inactive in the current repo, an approved one-time create is:
|
|
227
227
|
|
|
228
228
|
```bash
|
|
229
|
-
npx --yes @primitive.ai/prim@latest --yes decisions create --intent "…"
|
|
229
|
+
npx --yes @primitive.ai/prim@latest --yes decisions create --intent "…" --attribution user
|
|
230
230
|
```
|
|
231
231
|
|
|
232
232
|
Here npm's first `--yes` only permits package resolution; Prim's second `--yes`
|
|
233
233
|
confirms this create. It does not enable the repo or authorize a later create.
|
|
234
234
|
|
|
235
|
+
Every create requires `--attribution user|agent`. Use `user` only when the person
|
|
236
|
+
directly stated, selected, or confirmed the exact recorded choice. Use `agent` when
|
|
237
|
+
the agent introduced that exact choice while pursuing a broader request. A broad task
|
|
238
|
+
prompt or permission to implement does not make the resulting agent choice a user
|
|
239
|
+
Decision. If the origin is ambiguous, confirm the exact choice with the person before
|
|
240
|
+
creating it; do not guess.
|
|
241
|
+
|
|
235
242
|
`link` / `unlink` curate the dependency edges the automatic linker would otherwise
|
|
236
243
|
own — `<child>` depends on `<parent>`. Both are idempotent and refuse any link that
|
|
237
244
|
would create a cycle (exit 2); an unresolved id exits 4.
|
package/SKILL.md
CHANGED
|
@@ -80,7 +80,7 @@ Confirmations are author-targeted and rare by design; answering keeps the graph'
|
|
|
80
80
|
|
|
81
81
|
Capture is automatic for low-level choices made while coding in an active repo. Use the deliberate CLI path for higher-order decisions that emerge in conversation: goals, priorities, principles, invariants, constraints, defaults, commitments, durable tradeoffs, and exceptions.
|
|
82
82
|
|
|
83
|
-
A decision worth deliberately recording is a genuine **fork in the road**: the user or agent encountered multiple plausible paths, selected one, and that selection should inform future work. Record the chosen behavior, direction, constraint, or tradeoff—not routine implementation needed to finish the task or follow an existing convention. Small design choices made in-flight while implementing—such as edge-case handling, parameter defaults, retry or timeout values, log levels, naming, or the shape of an internal data structure—are implementation details even when you chose between alternatives: never deliberately record them or spend a rationale question on them; passive capture already covers coding activity. A teammate working elsewhere should benefit from knowing it.
|
|
83
|
+
A decision worth deliberately recording is a genuine **fork in the road**: the user or agent encountered multiple plausible paths, selected one, and that selection should inform future work. The litmus: does the selection govern future work, or did it merely happen once? A release-scoped choice — what is in or out of one release — reverses at the next release; it is ephemeral, not a decision. Record the chosen behavior, direction, constraint, or tradeoff—not routine implementation needed to finish the task or follow an existing convention. Small design choices made in-flight while implementing—such as edge-case handling, parameter defaults, retry or timeout values, log levels, naming, or the shape of an internal data structure—are implementation details even when you chose between alternatives: never deliberately record them or spend a rationale question on them; passive capture already covers coding activity. A teammate working elsewhere should benefit from knowing it.
|
|
84
84
|
|
|
85
85
|
### Ground the rationale in real sources
|
|
86
86
|
|
|
@@ -111,8 +111,10 @@ an explicit local `prim.active=false` is always inactive. Every
|
|
|
111
111
|
rationale, then wait for approval before creating it. A previous approval never
|
|
112
112
|
carries forward to another Decision.
|
|
113
113
|
- After approval, pass Prim's global `--yes` for that invocation:
|
|
114
|
-
`npx --yes @primitive.ai/prim --yes decisions create
|
|
115
|
-
|
|
114
|
+
`npx --yes @primitive.ai/prim --yes decisions create ... --attribution user`.
|
|
115
|
+
The person's approval of the exact proposed choice is user ratification. The
|
|
116
|
+
first `--yes` is npm's package-install flag; the second is Prim's one-time
|
|
117
|
+
confirmation.
|
|
116
118
|
- Do not run `prim enable` merely to bypass this boundary or infer permission to
|
|
117
119
|
activate the repo. Activation requires a separate user request (a requested
|
|
118
120
|
`prim setup` counts because setup explicitly activates its current repo). A
|
|
@@ -168,16 +170,20 @@ npx --yes @primitive.ai/prim decisions recent --limit 20
|
|
|
168
170
|
If an equivalent decision is already present, do not create or suggest it again. After this duplicate check—or after the user confirms an onboarding proposal—author the decision directly. If the repo is inactive, that confirmation authorizes Prim's `--yes` only for the approved create:
|
|
169
171
|
|
|
170
172
|
```
|
|
171
|
-
npx --yes @primitive.ai/prim decisions create --intent "Adopt prosemirror-collab over Yjs" --area data --rationale "Server-authoritative ordering" --alternatives "Yjs,Automerge"
|
|
173
|
+
npx --yes @primitive.ai/prim decisions create --intent "Adopt prosemirror-collab over Yjs" --attribution user --area data --rationale "Server-authoritative ordering" --alternatives "Yjs,Automerge"
|
|
172
174
|
```
|
|
173
175
|
|
|
174
176
|
Inactive-repo form after approval:
|
|
175
177
|
|
|
176
178
|
```
|
|
177
|
-
npx --yes @primitive.ai/prim --yes decisions create --intent "Adopt prosemirror-collab over Yjs" --area data --rationale "Server-authoritative ordering" --alternatives "Yjs,Automerge"
|
|
179
|
+
npx --yes @primitive.ai/prim --yes decisions create --intent "Adopt prosemirror-collab over Yjs" --attribution user --area data --rationale "Server-authoritative ordering" --alternatives "Yjs,Automerge"
|
|
178
180
|
```
|
|
179
181
|
|
|
180
|
-
|
|
182
|
+
Both `--intent` and `--attribution` are required. Set `--attribution user` only when the person directly stated, selected, or confirmed the exact recorded choice. Set `--attribution agent` when you introduced that exact choice while pursuing a broader request. A broad task prompt, implementation permission, or assignment of responsibility does not turn your implementation choice into a user Decision. If the origin is ambiguous, ask the person to confirm the exact choice before creating it; after confirmation, use `user`. Never guess attribution.
|
|
183
|
+
|
|
184
|
+
Word `--intent` normatively — the standing constraint future work must follow, not a report of the action taken: "Consume AADT and safety data from street_export, not gps_probes_osm", never "Migrate AADT and safety data managers off gps_probes_osm". A one-time-action verb (Migrate, Backfill, Publish) headlines a task execution: restate the ongoing constraint the action implies, and when none exists, do not record a decision at all. Make the intent self-contained for a reader who wasn't in the session — name the release, artifact, or system explicitly, and state what a referenced change does rather than citing a PR or ticket number, which is itself session context; "limit this release" and "keep the GitHub surface (PR 1102)" are failures. Carry one governing decision per intent and put component or schema specifics in `--decided`.
|
|
185
|
+
|
|
186
|
+
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). Omit `--files` for broad directions that should not immediately participate in file-based Conflict Gates. STDOUT is the created identity `{ decisionId, shortId, createdAt }`; STDERR prints `[prim] created dec_<short>.` — pass that `dec_<short>` straight into `decisions show` / `cascade` / `confirm`.
|
|
181
187
|
|
|
182
188
|
### Inferred decisions: finish first, then optionally ask once
|
|
183
189
|
|
package/dist/index.js
CHANGED
|
@@ -2309,6 +2309,9 @@ function registerDaemonCommands(program2) {
|
|
|
2309
2309
|
});
|
|
2310
2310
|
}
|
|
2311
2311
|
|
|
2312
|
+
// src/commands/decisions.ts
|
|
2313
|
+
import { Option } from "commander";
|
|
2314
|
+
|
|
2312
2315
|
// src/decisions/cascade-renderer.ts
|
|
2313
2316
|
var DEPENDENTS_INLINE_LIMIT = 5;
|
|
2314
2317
|
var KNOWLEDGE_INLINE_LIMIT = 4;
|
|
@@ -2764,6 +2767,7 @@ var defaultDeps4 = { getClient };
|
|
|
2764
2767
|
function toRequestBody(request) {
|
|
2765
2768
|
const candidate = {
|
|
2766
2769
|
intent: request.intent,
|
|
2770
|
+
attribution: request.attribution,
|
|
2767
2771
|
kind: request.kind,
|
|
2768
2772
|
rationale: request.rationale,
|
|
2769
2773
|
area: request.area,
|
|
@@ -3103,7 +3107,12 @@ function registerDecisionsCommands(program2) {
|
|
|
3103
3107
|
throw err;
|
|
3104
3108
|
}
|
|
3105
3109
|
});
|
|
3106
|
-
decisions.command("create").description("
|
|
3110
|
+
decisions.command("create").description("Record a decision directly with its explicit user or agent origin").requiredOption("--intent <text>", "What was decided (required)").addOption(
|
|
3111
|
+
new Option(
|
|
3112
|
+
"--attribution <origin>",
|
|
3113
|
+
"Who originated the exact choice: user | agent (required)"
|
|
3114
|
+
).choices(["user", "agent"]).makeOptionMandatory()
|
|
3115
|
+
).option("--kind <kind>", "change | exploration | task_execution | unclear (default change)").option("--rationale <text>", "Why the decision was made").option(
|
|
3107
3116
|
"--area <area>",
|
|
3108
3117
|
"Functional area (auth, data, infra, ui, api, billing, mobile, docs, testing)"
|
|
3109
3118
|
).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(
|
|
@@ -3124,6 +3133,7 @@ function registerDecisionsCommands(program2) {
|
|
|
3124
3133
|
}
|
|
3125
3134
|
const request = {
|
|
3126
3135
|
intent: opts.intent,
|
|
3136
|
+
attribution: opts.attribution,
|
|
3127
3137
|
kind: opts.kind,
|
|
3128
3138
|
rationale: opts.rationale,
|
|
3129
3139
|
area: opts.area,
|
|
@@ -3874,7 +3884,7 @@ import { execFileSync } from "child_process";
|
|
|
3874
3884
|
import { existsSync as existsSync7, mkdirSync as mkdirSync5, readFileSync as readFileSync6, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "fs";
|
|
3875
3885
|
import { homedir as homedir6 } from "os";
|
|
3876
3886
|
import { dirname as dirname4, join as join6, resolve as resolve2 } from "path";
|
|
3877
|
-
import { Option } from "commander";
|
|
3887
|
+
import { Option as Option2 } from "commander";
|
|
3878
3888
|
var PRE_COMMIT = { hookName: "pre-commit", binName: "prim-pre-commit" };
|
|
3879
3889
|
var POST_COMMIT = { hookName: "post-commit", binName: "prim-post-commit" };
|
|
3880
3890
|
var HOOKS = [PRE_COMMIT, POST_COMMIT];
|
|
@@ -4167,12 +4177,12 @@ function registerHooksCommands(program2) {
|
|
|
4167
4177
|
hooks.command("install").description(
|
|
4168
4178
|
"Install the prim git hooks \u2014 pre-commit + post-commit (auto-detects Husky; use --target to override)"
|
|
4169
4179
|
).addOption(
|
|
4170
|
-
new
|
|
4180
|
+
new Option2("--target <where>", "install destination; bypasses Husky detection").choices([
|
|
4171
4181
|
"husky",
|
|
4172
4182
|
"git-hooks"
|
|
4173
4183
|
])
|
|
4174
4184
|
).addOption(
|
|
4175
|
-
new
|
|
4185
|
+
new Option2(
|
|
4176
4186
|
"--scope <scope>",
|
|
4177
4187
|
"project (default, this repo) or user (a global core.hooksPath capturing every repo)"
|
|
4178
4188
|
).choices(["project", "user"])
|
|
@@ -4212,7 +4222,7 @@ function registerHooksCommands(program2) {
|
|
|
4212
4222
|
hooks.command("uninstall").description(
|
|
4213
4223
|
"Remove the prim git hooks (.git/hooks, or the global core.hooksPath with --scope user)"
|
|
4214
4224
|
).addOption(
|
|
4215
|
-
new
|
|
4225
|
+
new Option2(
|
|
4216
4226
|
"--scope <scope>",
|
|
4217
4227
|
"project (default, this repo) or user (global core.hooksPath)"
|
|
4218
4228
|
).choices(["project", "user"])
|
package/package.json
CHANGED