@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.
package/README.md CHANGED
@@ -205,8 +205,7 @@ metadata (equivalent to `git rev-parse --git-path prim/workspace-id`), never an
205
205
  absolute repository path. Linked worktrees receive distinct IDs, moving a
206
206
  worktree preserves its ID, and a clone creates a new one. A corrupt or
207
207
  unwritable identity is never silently replaced: capture falls back to the
208
- legacy envelope and `prim doctor` reports the limitation. Disable/uninstall
209
- does not delete the identity.
208
+ legacy envelope. Disable/uninstall does not delete the identity.
210
209
 
211
210
  Feedback uses the invoking CLI's credentials for direct HTTPS calls rather
212
211
  than the daemon, avoiding cross-organization token ambiguity. One absolute
@@ -228,7 +227,7 @@ Alternatives considered:
228
227
  | Detached delivery | Does not block Stop | Cannot return the current hook's `systemMessage` |
229
228
 
230
229
  Run `prim claude status` to verify both existing feedback handlers are installed
231
- and `prim doctor` to inspect the worktree identity and server capability. No new
230
+ and `prim doctor` to inspect server capability. No new
232
231
  hook registration or binary is required when upgrading an existing correct
233
232
  installation.
234
233
 
@@ -206,6 +206,5 @@ function errorCode(error) {
206
206
 
207
207
  export {
208
208
  isCanonicalWorkspaceId,
209
- inspectWorkspaceId,
210
209
  getOrCreateWorkspaceId
211
210
  };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  isCanonicalWorkspaceId
3
- } from "./chunk-UVIWZWM6.js";
3
+ } from "./chunk-EZXEWFDG.js";
4
4
  import {
5
5
  scrubEnvironmentPaths
6
6
  } from "./chunk-FI3LIRCB.js";
@@ -7036,10 +7036,7 @@ async function main() {
7036
7036
  return;
7037
7037
  }
7038
7038
  if (targets.paths.length === 0) {
7039
- await emitUnverified(
7040
- "mutation targets could not be determined; enforcement not verified",
7041
- envelope
7042
- );
7039
+ await emit(failOpen());
7043
7040
  return;
7044
7041
  }
7045
7042
  const binding = repoSyncId(cwd);
@@ -10261,6 +10261,9 @@ async function resolveRepositoryBindingWithClient(root, client, options) {
10261
10261
  }
10262
10262
  return { status: "connected", repoSyncId: response.repoSyncId, repositoryFullName };
10263
10263
  }
10264
+ async function resolveRepositoryBinding(root, options) {
10265
+ return resolveRepositoryBindingWithClient(root, getClient(), options);
10266
+ }
10264
10267
  function persistRepositoryBinding(root, binding) {
10265
10268
  if (binding.status === "connected") {
10266
10269
  setRepoSyncId(root, binding.repoSyncId, binding.repositoryFullName);
@@ -11123,17 +11126,37 @@ async function activeProjectRoot(cwd) {
11123
11126
  }
11124
11127
  }
11125
11128
  try {
11126
- await bindRepository(root, {
11129
+ const binding = await bindRepository(root, {
11127
11130
  signal: AbortSignal.timeout(REPOSITORY_BIND_TIMEOUT_MS),
11128
11131
  quietRefresh: true
11129
11132
  });
11133
+ return { root, binding };
11130
11134
  } catch {
11131
11135
  }
11132
- return root;
11136
+ return { root };
11133
11137
  } catch {
11134
11138
  return null;
11135
11139
  }
11136
11140
  }
11141
+ function claudeBindingReminder(binding) {
11142
+ if (binding.status === "connected") {
11143
+ 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.`;
11144
+ }
11145
+ 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.`;
11146
+ }
11147
+ async function claudeRepositoryBinding(cwd, activeProject) {
11148
+ const root = activeProject?.root ?? gitToplevel(cwd);
11149
+ if (!root || !githubRepositoryFullName(root)) return void 0;
11150
+ if (activeProject) return activeProject.binding;
11151
+ try {
11152
+ return await resolveRepositoryBinding(root, {
11153
+ signal: AbortSignal.timeout(REPOSITORY_BIND_TIMEOUT_MS),
11154
+ quietRefresh: true
11155
+ });
11156
+ } catch {
11157
+ return void 0;
11158
+ }
11159
+ }
11137
11160
  async function processSessionStart(raw, agent, feedbackSignal) {
11138
11161
  let envelope;
11139
11162
  try {
@@ -11161,9 +11184,12 @@ async function processSessionStart(raw, agent, feedbackSignal) {
11161
11184
  let projectRoot = null;
11162
11185
  let active = false;
11163
11186
  let skillState = { installed: 0, refreshed: 0 };
11187
+ let claudeBinding;
11164
11188
  if (agent === "claude_code") {
11165
- projectRoot = await activeProjectRoot(cwd);
11189
+ const activeProject = await activeProjectRoot(cwd);
11190
+ projectRoot = activeProject?.root ?? null;
11166
11191
  active = projectRoot !== null;
11192
+ claudeBinding = await claudeRepositoryBinding(cwd, activeProject);
11167
11193
  try {
11168
11194
  skillState = await refreshClaudePlugins(
11169
11195
  cwd,
@@ -11191,7 +11217,7 @@ async function processSessionStart(raw, agent, feedbackSignal) {
11191
11217
  });
11192
11218
  } catch {
11193
11219
  }
11194
- projectRoot = await activeProjectRoot(cwd);
11220
+ projectRoot = (await activeProjectRoot(cwd))?.root ?? null;
11195
11221
  active = projectRoot !== null;
11196
11222
  let proactive = false;
11197
11223
  try {
@@ -11207,7 +11233,10 @@ async function processSessionStart(raw, agent, feedbackSignal) {
11207
11233
  };
11208
11234
  }
11209
11235
  if (agent === "claude_code") {
11210
- const additionalContext = active && skillState.installed > 0 ? PRIM_SKILL_REMINDER : void 0;
11236
+ const additionalContext = [
11237
+ claudeBinding ? claudeBindingReminder(claudeBinding) : void 0,
11238
+ active && skillState.installed > 0 ? PRIM_SKILL_REMINDER : void 0
11239
+ ].filter((value) => value !== void 0).join("\n\n");
11211
11240
  const reloadSkills = skillState.refreshed > 0;
11212
11241
  if (active) {
11213
11242
  const identity = getOrCreateWorkspaceId(cwd);