@brainervirus/workit-pi 8.29.1 → 8.29.2

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.
Files changed (2) hide show
  1. package/dist/workit.js +70 -24
  2. package/package.json +1 -1
package/dist/workit.js CHANGED
@@ -15987,13 +15987,13 @@ Autonomy contract:
15987
15987
  or an unresolved blocker; report open gaps and uncertain workers.
15988
15988
  - No endpoint named: stop at a local commit on a policy-compliant branch and
15989
15989
  state the next command. If the request implies delivery (fix, implement,
15990
- ship), go to the effective endpoint in \`workit grant show\`: \`pr\` opens
15991
- the PR; \`green\` babysits it without asking (workit-ship) to merge-ready,
15992
- never merging; \`merged\` also lands it with \`workit pr merge\`.
15993
- Merge and release need a workspace grant only the user raises from their
15994
- own terminal (a blocked verb names how); never edit workspaces.json or route
15995
- around grant_required. Release: \`workit release start <v>\`, commits,
15996
- \`finish\`; \`publish\` if asked.
15990
+ ship), go to the effective endpoint in \`workit grant show\`: \`pr\` stops
15991
+ at the PR even with merge granted; \`green\` babysits it (workit-ship) to
15992
+ merge-ready, never merging; \`merged\` lands it with \`workit pr merge\`.
15993
+ Only the user raises a grant or the endpoint, in a terminal outside the agent
15994
+ host (\`workit grant set <ws> defaultEndpoint=merged\`); never edit
15995
+ workspaces.json or route around grant_required. Release: \`workit release
15996
+ start <v>\`, commits, \`finish\`; \`publish\` if asked.
15997
15997
  - Ask only for a product or preference choice, or for authority you lack, with
15998
15998
  your recommended answer. Facts are yours: read, run or prototype.
15999
15999
  - Label claims measured (run and seen this session), inferred, or guess.
@@ -16007,9 +16007,8 @@ Autonomy contract:
16007
16007
  is not evidence of a requested remote push. Before reporting delivery,
16008
16008
  reconcile every requested item and observe it (\`workit verify-delivery\`).
16009
16009
 
16010
- CLI first: if a step has one right answer, use the \`workit\` verb instead of
16011
- hand-running git, gh or glab (\`workit git|pr|ci|check|help\`;
16012
- else \`npx -y @brainervirus/workit-cli\`).
16010
+ Read-only git and gh run raw; mutations go through workit verbs
16011
+ (\`workit git|pr|ci|check|help\`; else \`npx -y @brainervirus/workit-cli\`).
16013
16012
  Other checkout: \`workit <verb> --cwd <dir> …\` (verb first: host rules match it); one workit
16014
16013
  verb per shell call, never \`cd <dir> && workit\`. zsh-safe: no \`echo =====\`
16015
16014
  (\`printf '%s\\n' ---\`), quote globs and URLs, no variable named \`status\` or \`path\`.
@@ -17980,7 +17979,6 @@ var nudgeFor = (action, host, session) => {
17980
17979
  case "pr-create":
17981
17980
  return `workit: prefer ${quote("workit pr create --fill")} (or --title/--body): it records the PR the merge gate checks.`;
17982
17981
  case "pr-read":
17983
- return `workit: ${quote("workit pr status")} shows the PR, its checks and the verdict state; ${quote("workit ci wait")} waits for checks.`;
17984
17982
  case "merge":
17985
17983
  return null;
17986
17984
  }
@@ -21639,12 +21637,38 @@ ${offer}` : ""}${options.addendum ? `
21639
21637
  ${options.addendum}` : ""}
21640
21638
  </workit-contract>`;
21641
21639
  };
21640
+ var checkoutAt = (cwd) => {
21641
+ for (let dir = path27.resolve(cwd);; dir = path27.dirname(dir)) {
21642
+ const dotGit = path27.join(dir, ".git");
21643
+ if (fs19.existsSync(dotGit)) {
21644
+ const admin = fs19.statSync(dotGit).isFile() ? path27.resolve(dir, /^gitdir:\s*(.+)$/mu.exec(fs19.readFileSync(dotGit, "utf8"))?.[1]?.trim() ?? "") : dotGit;
21645
+ const head = fs19.readFileSync(path27.join(admin, "HEAD"), "utf8").trim();
21646
+ return { root: dir, branch: /^ref: refs\/heads\/(.+)$/u.exec(head)?.[1] ?? null };
21647
+ }
21648
+ if (path27.dirname(dir) === dir)
21649
+ return null;
21650
+ }
21651
+ };
21652
+ var whereLine = (cwd) => {
21653
+ try {
21654
+ const checkout = checkoutAt(cwd);
21655
+ if (!checkout)
21656
+ return null;
21657
+ const allowed = branchPolicySnapshotFor(cwd).namePolicy.allowed;
21658
+ const kinds = allowed.some((pattern) => pattern.source === "^.*$") ? "any" : allowedKinds(allowed).join(", ") || "see `workit help git`";
21659
+ const place = checkout.root === path27.resolve(cwd) ? "" : ` in ${checkout.root}`;
21660
+ return `cwd ${cwd}${place} on ${checkout.branch ?? "detached HEAD"}; branch kinds: ${kinds}`;
21661
+ } catch {
21662
+ return null;
21663
+ }
21664
+ };
21642
21665
  var turnContextText = (input, descriptor) => {
21643
21666
  try {
21644
21667
  const text = sessionCompactContext(new TaskStore(input.cwd), { host: input.host, handle: input.session.id }, hookOperationContext(input, descriptor), descriptor.context.task);
21645
21668
  if (text === MIGRATION_PENDING_NOTE)
21646
21669
  return text;
21647
- return text ? `<workit-task-context>${text}</workit-task-context>` : null;
21670
+ return text ? `<workit-task-context>${[whereLine(input.cwd), text].filter(Boolean).join(`
21671
+ `)}</workit-task-context>` : null;
21648
21672
  } catch {
21649
21673
  return null;
21650
21674
  }
@@ -24392,11 +24416,7 @@ function confineImplementerShell(input, command, dialect = "posix") {
24392
24416
  return confineImplementer(input, shellMutationTargets(input.cwd, command, dialect, true));
24393
24417
  }
24394
24418
 
24395
- // packages/workit-core/src/hooks/handle.ts
24396
- var usable2 = (value) => value === "native" || value === "partial";
24397
- var NONE6 = { kind: "none" };
24398
- var resendsOnChange = (descriptor) => descriptor.context.turnResend === "on-change" && usable2(descriptor.context.perTurn);
24399
- var offered = new Set;
24419
+ // packages/workit-core/src/hooks/steering.ts
24400
24420
  var ROLES = {
24401
24421
  implementer: "implementer",
24402
24422
  verifier: "judge",
@@ -24407,22 +24427,41 @@ var workitRole = (descriptor, agentType) => {
24407
24427
  const name = agentType.startsWith(prefix) ? agentType.slice(prefix.length) : "";
24408
24428
  return Object.hasOwn(ROLES, name) ? ROLES[name] : null;
24409
24429
  };
24430
+ var CLAUDE_WORKTREE = /[\\/]\.claude[\\/]worktrees[\\/]/;
24431
+ var roleSteering = (role, isolated) => ({
24432
+ role,
24433
+ isolated,
24434
+ git: role === "implementer" ? isolated ? "plain" : "workit" : null,
24435
+ nudges: role === null
24436
+ });
24437
+ var agentSteering = (descriptor, cwd, agent) => {
24438
+ const role = agent.type ? workitRole(descriptor, agent.type) : null;
24439
+ const isolated = descriptor.subagents.worktreeIsolation === "native" && (role === "implementer" ? hostIsolated(cwd, agent.id) : CLAUDE_WORKTREE.test(cwd));
24440
+ return roleSteering(role, isolated);
24441
+ };
24442
+
24443
+ // packages/workit-core/src/hooks/handle.ts
24444
+ var usable2 = (value) => value === "native" || value === "partial";
24445
+ var NONE6 = { kind: "none" };
24446
+ var resendsOnChange = (descriptor) => descriptor.context.turnResend === "on-change" && usable2(descriptor.context.perTurn);
24447
+ var offered = new Set;
24410
24448
  var implementerAgent = (input, descriptor) => Boolean(input.session.agentId) && input.session.agentType !== null && workitRole(descriptor, input.session.agentType) === "implementer";
24411
24449
  var subagentSession = (session, agentId) => [session, agentId].filter((part) => Boolean(part)).join(":").replace(/[^A-Za-z0-9_.:@/+-]/g, "-").slice(0, 128);
24412
- var CLAUDE_WORKTREE = /[\\/]\.claude[\\/]worktrees[\\/]/;
24413
24450
  var isolatedGit = (cwd) => `Run git as plain, separate commands inside your worktree (\`git switch -c <branch> <base>\`, ${workspaceTrailers(cwd).enabled ? '`git commit --trailer "Workit-Session=<your session>"`, `git push`; `workit doctor --fix` can install a prepare-commit-msg hook that adds the trailer' : "`git commit` (this workspace sets trailers: false: add no Workit-Session trailer), `git push`"}; add Co-Authored-By with \`git commit --trailer\` in the same commit, never by amending), never \`workit git …\`: Claude Code's worktree isolation refuses a command that wraps git and cannot be turned off (https://code.claude.com/docs/en/worktrees#how-claude-code-enforces-isolation). Never dodge that check by renaming or re-wrapping git. Use workit for the non-git verbs (\`workit check\`, \`workit ledger\`, \`workit pr\`).`;
24414
24451
  var subagentStartText = (input, descriptor, event) => {
24415
24452
  const session = input.session.id ?? null;
24416
- const role = workitRole(descriptor, event.agentType);
24453
+ const { role, isolated, git } = agentSteering(descriptor, input.cwd, {
24454
+ type: event.agentType,
24455
+ id: event.agentId
24456
+ });
24417
24457
  const who = `${descriptor.label} subagent ${event.agentId} (${event.agentType})`;
24418
- const isolated = descriptor.subagents.worktreeIsolation === "native" && (role === "implementer" ? hostIsolated(input.cwd, event.agentId) : CLAUDE_WORKTREE.test(input.cwd));
24419
24458
  const guide = role === "implementer" ? branchGuidance(input.cwd) : null;
24420
- if (role === "implementer" && isolated)
24459
+ if (git === "plain")
24421
24460
  return `Workit observed ${who} working in its own git worktree: it may edit and commit there, within its brief's scope. ${isolatedGit(input.cwd)} Plain git is expected here, and the branch name is still policy-checked: a raw \`git switch -c\`, \`git checkout -b\`, \`git branch\` or \`git worktree add -b\` onto a protected or non-compliant name is denied, so use a policy-compliant branch.${guide ? ` ${guide}` : " (e.g. feature/<slug>)"} Never record a verdict on your own work. Never push, open a PR, or merge unless the brief asks for it.`;
24422
24461
  if (isolated)
24423
24462
  return `${isolatedGit(input.cwd)}
24424
24463
  ${subagentStartText({ ...input, cwd: "" }, descriptor, event)}`;
24425
- if (role === "implementer")
24464
+ if (git === "workit")
24426
24465
  return `Workit observed ${who} as an implementer: it edits and commits only in its own git worktree, the one its brief names (the lead makes it with \`workit fanout worktree create <slice>\` before spawning), never in the lead's checkout, within its brief's scope. Workit binds it to the first Workit worktree it changes: from then on an edit or a mutating git command outside that worktree is denied, and before then so is one outside every Workit worktree. Run Workit against the worktree one verb per call, never \`cd … &&\` chains or \`$VAR\` paths: \`workit git --cwd <worktree> commit -m "<message>" -- <paths>\`, \`workit check --cwd <worktree> <name>\` (verb first, so host allow rules match). The worktree is on the brief's branch once the lead made it; otherwise switch with \`workit git --cwd <worktree> branch <branch> --base <base>\` (or \`--kind <kind> --slug <slug>\`, which picks the base); branch policy hooks still deny protected or non-compliant branches, raw git included.${guide ? ` ${guide}` : " (e.g. feature/<slug>)"} Never record a verdict on your own work. Never push, open a PR, or merge unless the brief asks for it.`;
24427
24466
  const readOnly = `Workit observed ${who} as read-only/agent-guided.`;
24428
24467
  if (role !== "judge" || !event.agentId)
@@ -24525,7 +24564,12 @@ function decide(input, deps) {
24525
24564
  } : NONE6;
24526
24565
  if (descriptor.transport !== "hook-process")
24527
24566
  return rewritten(null);
24528
- const nudged = withContextLine(withContextLine(canDeny ? rawGitPre(input, event.command) : NONE6, aside), shipNudge(input, event.command));
24567
+ const { nudges } = agentSteering(descriptor, input.cwd, {
24568
+ type: input.session.agentType,
24569
+ id: input.session.agentId
24570
+ });
24571
+ const nudge = canDeny ? rawGitPre(input, event.command, { nudge: nudges }) : NONE6;
24572
+ const nudged = withContextLine(withContextLine(nudge, aside), shipNudge(input, event.command));
24529
24573
  if (!lease)
24530
24574
  return cwdCommand && nudged.kind !== "deny" ? rewritten(nudged.kind === "context" ? nudged.text : null) : nudged;
24531
24575
  return rewritten([rewriteNote(lease), nudged.kind === "context" ? nudged.text : null].filter(Boolean).join(`
@@ -24868,7 +24912,9 @@ var observeToolResult = (event, ctx) => {
24868
24912
  toolUseId: event.toolCallId
24869
24913
  });
24870
24914
  handleHook(post, { descriptor: PI_DESCRIPTOR, addendum: null });
24871
- const nudge = process.env.WORKIT_PI_WORKER_SESSION ? rawGitPre(post, command) : shellNudge(post, command);
24915
+ const named = process.env.WORKIT_PI_WORKER_ROLE;
24916
+ const role = named === "implementer" ? "implementer" : named ? "judge" : null;
24917
+ const nudge = process.env.WORKIT_PI_WORKER_SESSION ? rawGitPre(post, command, { nudge: roleSteering(role, false).nudges }) : shellNudge(post, command);
24872
24918
  return nudge.kind === "context" ? { content: [...event.content, { type: "text", text: nudge.text }] } : undefined;
24873
24919
  } catch {
24874
24920
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainervirus/workit-pi",
3
- "version": "8.29.1",
3
+ "version": "8.29.2",
4
4
  "description": "Workit native extension for Pi — tools, method skills, and session continuity",
5
5
  "keywords": [
6
6
  "agentic-coding",