@primitive.ai/prim 0.1.0-alpha.79 → 0.1.0-alpha.80

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.
@@ -2,14 +2,14 @@
2
2
  import {
3
3
  commitAttributionFromEnvironment,
4
4
  toCommitMove
5
- } from "../chunk-H64F6QHV.js";
5
+ } from "../chunk-OUXH3UEP.js";
6
+ import {
7
+ getOrCreateWorkspaceId
8
+ } from "../chunk-EZXEWFDG.js";
6
9
  import {
7
10
  appendMove,
8
11
  resolveOrg
9
12
  } from "../chunk-YWO7O6QG.js";
10
- import {
11
- getOrCreateWorkspaceId
12
- } from "../chunk-UVIWZWM6.js";
13
13
  import "../chunk-FI3LIRCB.js";
14
14
  import "../chunk-LEMX3IOG.js";
15
15
  import {
@@ -2,14 +2,14 @@
2
2
  import {
3
3
  canonicalRewritePairs,
4
4
  toRewriteMove
5
- } from "../chunk-H64F6QHV.js";
5
+ } from "../chunk-OUXH3UEP.js";
6
+ import {
7
+ getOrCreateWorkspaceId
8
+ } from "../chunk-EZXEWFDG.js";
6
9
  import {
7
10
  appendMove,
8
11
  resolveOrg
9
12
  } from "../chunk-YWO7O6QG.js";
10
- import {
11
- getOrCreateWorkspaceId
12
- } from "../chunk-UVIWZWM6.js";
13
13
  import "../chunk-FI3LIRCB.js";
14
14
  import "../chunk-LEMX3IOG.js";
15
15
  import {
@@ -10,14 +10,14 @@ import {
10
10
  postToolInvocationId,
11
11
  toMove,
12
12
  toolOutcomeFor
13
- } from "../chunk-H64F6QHV.js";
13
+ } from "../chunk-OUXH3UEP.js";
14
+ import {
15
+ getOrCreateWorkspaceId
16
+ } from "../chunk-EZXEWFDG.js";
14
17
  import {
15
18
  appendMove,
16
19
  resolveOrg
17
20
  } from "../chunk-YWO7O6QG.js";
18
- import {
19
- getOrCreateWorkspaceId
20
- } from "../chunk-UVIWZWM6.js";
21
21
  import "../chunk-BQUJ4AFJ.js";
22
22
  import {
23
23
  appendCodexContext,
@@ -285,10 +285,7 @@ async function main() {
285
285
  return;
286
286
  }
287
287
  if (targets.paths.length === 0) {
288
- await emitUnverified(
289
- "mutation targets could not be determined; enforcement not verified",
290
- envelope
291
- );
288
+ await emit(failOpen());
292
289
  return;
293
290
  }
294
291
  const binding = repoSyncId(cwd);
@@ -17,14 +17,14 @@ import {
17
17
  postToolInvocationId,
18
18
  shouldFlushAfter,
19
19
  toMove
20
- } from "../chunk-H64F6QHV.js";
20
+ } from "../chunk-OUXH3UEP.js";
21
+ import {
22
+ getOrCreateWorkspaceId
23
+ } from "../chunk-EZXEWFDG.js";
21
24
  import {
22
25
  appendMove,
23
26
  resolveOrg
24
27
  } from "../chunk-YWO7O6QG.js";
25
- import {
26
- getOrCreateWorkspaceId
27
- } from "../chunk-UVIWZWM6.js";
28
28
  import "../chunk-BQUJ4AFJ.js";
29
29
  import {
30
30
  prepareCodexContext
@@ -5,6 +5,7 @@ import {
5
5
  ensureEffectivePostRewriteHook,
6
6
  hasUsableCodexGuidance,
7
7
  refreshClaudePlugins,
8
+ resolveRepositoryBinding,
8
9
  warmBinCache
9
10
  } from "../chunk-2KW7DVFJ.js";
10
11
  import {
@@ -19,7 +20,7 @@ import {
19
20
  } from "../chunk-LMRYZL3D.js";
20
21
  import {
21
22
  getOrCreateWorkspaceId
22
- } from "../chunk-UVIWZWM6.js";
23
+ } from "../chunk-EZXEWFDG.js";
23
24
  import {
24
25
  prepareCodexContext
25
26
  } from "../chunk-KKP2NYZ3.js";
@@ -28,6 +29,7 @@ import {
28
29
  } from "../chunk-4A2XB2PC.js";
29
30
  import {
30
31
  gitToplevel,
32
+ githubRepositoryFullName,
31
33
  isRepoActiveForCapture,
32
34
  repoActiveFlag,
33
35
  setRepoActive
@@ -110,17 +112,37 @@ async function activeProjectRoot(cwd) {
110
112
  }
111
113
  }
112
114
  try {
113
- await bindRepository(root, {
115
+ const binding = await bindRepository(root, {
114
116
  signal: AbortSignal.timeout(REPOSITORY_BIND_TIMEOUT_MS),
115
117
  quietRefresh: true
116
118
  });
119
+ return { root, binding };
117
120
  } catch {
118
121
  }
119
- return root;
122
+ return { root };
120
123
  } catch {
121
124
  return null;
122
125
  }
123
126
  }
127
+ function claudeBindingReminder(binding) {
128
+ if (binding.status === "connected") {
129
+ return `The current GitHub repository is connected to Primitive. In your first response, begin with exactly: "GitHub repository connected to Primitive: ${binding.repositoryFullName}." Then continue the user's request.`;
130
+ }
131
+ return `The current GitHub repository is not connected to Primitive. Before doing task work, ask exactly: "This GitHub repository isn't connected to Primitive yet. Would you like me to start the one-time GitHub connection now?" Wait for the user's answer. If they approve, run \`npx --yes @primitive.ai/prim github connect\`, drive the browser-based GitHub App workflow, report its actual outcome concisely, and resume work. If they decline or the connection does not complete, continue without asking again in this session. Do not use owner/admin escalation or capability-loss warnings.`;
132
+ }
133
+ async function claudeRepositoryBinding(cwd, activeProject) {
134
+ const root = activeProject?.root ?? gitToplevel(cwd);
135
+ if (!root || !githubRepositoryFullName(root)) return void 0;
136
+ if (activeProject) return activeProject.binding;
137
+ try {
138
+ return await resolveRepositoryBinding(root, {
139
+ signal: AbortSignal.timeout(REPOSITORY_BIND_TIMEOUT_MS),
140
+ quietRefresh: true
141
+ });
142
+ } catch {
143
+ return void 0;
144
+ }
145
+ }
124
146
  async function processSessionStart(raw, agent, feedbackSignal) {
125
147
  let envelope;
126
148
  try {
@@ -148,9 +170,12 @@ async function processSessionStart(raw, agent, feedbackSignal) {
148
170
  let projectRoot = null;
149
171
  let active = false;
150
172
  let skillState = { installed: 0, refreshed: 0 };
173
+ let claudeBinding;
151
174
  if (agent === "claude_code") {
152
- projectRoot = await activeProjectRoot(cwd);
175
+ const activeProject = await activeProjectRoot(cwd);
176
+ projectRoot = activeProject?.root ?? null;
153
177
  active = projectRoot !== null;
178
+ claudeBinding = await claudeRepositoryBinding(cwd, activeProject);
154
179
  try {
155
180
  skillState = await refreshClaudePlugins(
156
181
  cwd,
@@ -178,7 +203,7 @@ async function processSessionStart(raw, agent, feedbackSignal) {
178
203
  });
179
204
  } catch {
180
205
  }
181
- projectRoot = await activeProjectRoot(cwd);
206
+ projectRoot = (await activeProjectRoot(cwd))?.root ?? null;
182
207
  active = projectRoot !== null;
183
208
  let proactive = false;
184
209
  try {
@@ -194,7 +219,10 @@ async function processSessionStart(raw, agent, feedbackSignal) {
194
219
  };
195
220
  }
196
221
  if (agent === "claude_code") {
197
- const additionalContext = active && skillState.installed > 0 ? PRIM_SKILL_REMINDER : void 0;
222
+ const additionalContext = [
223
+ claudeBinding ? claudeBindingReminder(claudeBinding) : void 0,
224
+ active && skillState.installed > 0 ? PRIM_SKILL_REMINDER : void 0
225
+ ].filter((value) => value !== void 0).join("\n\n");
198
226
  const reloadSkills = skillState.refreshed > 0;
199
227
  if (active) {
200
228
  const identity = getOrCreateWorkspaceId(cwd);
package/dist/index.js CHANGED
@@ -38,9 +38,6 @@ import {
38
38
  pendingJournalStats,
39
39
  readMovesFromPath
40
40
  } from "./chunk-YWO7O6QG.js";
41
- import {
42
- inspectWorkspaceId
43
- } from "./chunk-UVIWZWM6.js";
44
41
  import {
45
42
  STABLE_HOOK_LAUNCHER_NAME,
46
43
  binFile,
@@ -13655,11 +13652,7 @@ async function applyActivation(active, globals = {}) {
13655
13652
  process.stderr.write(`[prim] Prim is enabled locally in ${root}
13656
13653
  `);
13657
13654
  process.stderr.write(
13658
- "[prim] repository is not connected to Primitive; Moves still ingest into the team graph without repository-specific file attribution, Conflict Gate verification, or commit correlation\n"
13659
- );
13660
- process.stderr.write(
13661
- `[prim] ask an organization owner or administrator to grant Primitive's GitHub App access to this repository through Primitive's GitHub App onboarding; binding retries automatically at the next agent SessionStart
13662
- `
13655
+ "[prim] GitHub repository binding is not connected \u2014 run `prim github connect` when you're ready\n"
13663
13656
  );
13664
13657
  } else {
13665
13658
  process.stderr.write(`[prim] prim ${active ? "enabled" : "disabled"} in ${root}
@@ -19306,37 +19299,6 @@ async function checkJournalOrganization() {
19306
19299
  const inspection = await inspectJournalDelivery(buckets);
19307
19300
  return classifyJournalOrganization(new Set(buckets).size, inspection.retainedBuckets);
19308
19301
  }
19309
- function checkWorkspaceIdentity() {
19310
- const identity = inspectWorkspaceId();
19311
- switch (identity.status) {
19312
- case "ready":
19313
- return { name: "feedback-id", status: "ok", detail: "stable worktree identity ready" };
19314
- case "missing":
19315
- return {
19316
- name: "feedback-id",
19317
- status: "warn",
19318
- detail: "not initialized \u2014 the next active hook will create it"
19319
- };
19320
- case "not_git":
19321
- return {
19322
- name: "feedback-id",
19323
- status: "warn",
19324
- detail: "not in a Git worktree \u2014 capture falls back to legacy V1"
19325
- };
19326
- case "corrupt":
19327
- return {
19328
- name: "feedback-id",
19329
- status: "warn",
19330
- detail: "identity is corrupt \u2014 not rotated; capture falls back to legacy V1"
19331
- };
19332
- case "unavailable":
19333
- return {
19334
- name: "feedback-id",
19335
- status: "warn",
19336
- detail: `identity unavailable during ${identity.operation} \u2014 capture falls back to legacy V1`
19337
- };
19338
- }
19339
- }
19340
19302
  function classifyRepositoryBinding(value, current, active) {
19341
19303
  if (current.status === "unbound") {
19342
19304
  if (!active) {
@@ -19350,7 +19312,7 @@ function classifyRepositoryBinding(value, current, active) {
19350
19312
  return {
19351
19313
  name: "repo-binding",
19352
19314
  status: "warn",
19353
- detail: `${localDetail} \u2014 local capture is active, but file scoping, Conflict Gate verification, and commit correlation are unavailable; ask an organization owner/admin to grant the Primitive GitHub App access (retried automatically next SessionStart)`
19315
+ detail: `${localDetail} \u2014 local capture is active; run \`prim github connect\` to connect this GitHub repository`
19354
19316
  };
19355
19317
  }
19356
19318
  if (!isValidRepoSyncId(value)) {
@@ -19705,7 +19667,6 @@ async function collectChecks() {
19705
19667
  checkFeedbackHooks(),
19706
19668
  ...checkAgentHooks(),
19707
19669
  checkHookRuntime(),
19708
- checkWorkspaceIdentity(),
19709
19670
  await checkRepositoryBinding(),
19710
19671
  checkManagedHook("post-commit", inspectEffectivePostCommitHook),
19711
19672
  checkManagedHook("post-rewrite", inspectEffectivePostRewriteHook),
@@ -19733,7 +19694,7 @@ async function runDoctor() {
19733
19694
  }
19734
19695
  function registerDoctorCommands(program2) {
19735
19696
  program2.command("doctor").description(
19736
- "Check capture and feedback health end to end (auth, supervisor, delivery, worktree, server)"
19697
+ "Check capture and feedback health end to end (auth, supervisor, delivery, server)"
19737
19698
  ).action(async () => {
19738
19699
  await runDoctor();
19739
19700
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primitive.ai/prim",
3
- "version": "0.1.0-alpha.79",
3
+ "version": "0.1.0-alpha.80",
4
4
  "description": "CLI for Primitive's decision graph — passive decision capture, conflict gate, and team presence",
5
5
  "type": "module",
6
6
  "license": "MIT",