ai-foreman 1.7.14 → 1.7.16

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.
@@ -827,6 +827,8 @@ function activityPhase(phase) {
827
827
  return "planning uninstall";
828
828
  if (phase === "manager")
829
829
  return "analyzing diagnostics";
830
+ if (phase === "discovery")
831
+ return "discovering project context";
830
832
  return "building";
831
833
  }
832
834
  function formatClaudeFailure(failure) {
@@ -694,6 +694,8 @@ function activityPhase(phase) {
694
694
  return "planning uninstall";
695
695
  if (phase === "manager")
696
696
  return "analyzing diagnostics";
697
+ if (phase === "discovery")
698
+ return "discovering project context";
697
699
  return "building";
698
700
  }
699
701
  function codexItemActivity(item, completed = false) {
package/dist/agentRun.js CHANGED
@@ -262,6 +262,8 @@ function phaseForRole(role) {
262
262
  return "uninstaller";
263
263
  if (role === "manager")
264
264
  return "manager";
265
+ if (role === "discovery")
266
+ return "discovery";
265
267
  return "builder";
266
268
  }
267
269
  export function readRoleDefaultsForExecution(projectDir, role) {
@@ -357,7 +359,7 @@ export async function runRoleInstruction(opts) {
357
359
  }
358
360
  }
359
361
  function configurableRole(role) {
360
- return ["builder", "qa", "planner", "ticket-maker", "uninstaller", "manager"].includes(role)
362
+ return ["builder", "qa", "planner", "ticket-maker", "uninstaller", "manager", "discovery"].includes(role)
361
363
  ? role
362
364
  : "builder";
363
365
  }
@@ -19,15 +19,15 @@ export class LegacyQaRecoveryPacketError extends Error {
19
19
  }
20
20
  export function loadQaRecoveryPacket(directory) {
21
21
  const root = resolve(directory);
22
- if (!existsSync(root) || realpathSync(root) !== root)
23
- throw new Error(`symlink is not allowed in recovery path: ${root}`);
24
- assertNoSymlinkComponents(root, root);
25
22
  const manifestPath = join(root, "manifest.json");
26
23
  if (!existsSync(manifestPath) || lstatSync(manifestPath).isSymbolicLink())
27
24
  throw new Error("missing or unsafe QA recovery manifest");
28
25
  let raw = JSON.parse(readFileSync(manifestPath, "utf8"));
29
26
  if (raw.version === 1)
30
27
  throw new LegacyQaRecoveryPacketError(root, raw);
28
+ if (!existsSync(root) || realpathSync(root) !== root)
29
+ throw new Error(`symlink is not allowed in recovery path: ${root}`);
30
+ assertNoSymlinkComponents(root, root);
31
31
  assertPrivateTree(root);
32
32
  assertManifestShape(raw);
33
33
  for (const resource of raw.resources)
@@ -478,7 +478,7 @@ export function ensureQaRecoveryExcluded(projectDir) {
478
478
  exclude = resolve(exclude);
479
479
  common = resolve(common);
480
480
  if (exclude !== common && !exclude.startsWith(`${common}${sep}`))
481
- throw new Error(`git exclude path escapes the target repository: ${exclude}`);
481
+ return;
482
482
  const entries = [`/${QA_RECOVERY_ROOT}/`, `/${QA_CONTEXT_ROOT}/`];
483
483
  const current = existsSync(exclude) ? readFileSync(exclude, "utf8") : "";
484
484
  const missing = entries.filter((entry) => !current.split(/\r?\n/).includes(entry));
package/dist/roles.js CHANGED
@@ -19,6 +19,7 @@ export const AGENT_ROLE_REGISTRY = [
19
19
  { id: "ticket-maker", label: "Ticket maker", consumers: ["ticket population"], configurable: true, manifest: "ticket-maker", commands: ["rafi tickets populate"] },
20
20
  { id: "uninstaller", label: "Uninstaller", consumers: ["non-empty uninstall instructions only"], configurable: true, manifest: "uninstaller", commands: ["rafi uninstall"] },
21
21
  { id: "manager", label: "Manager (read-only diagnostics)", consumers: ["build diagnostics"], configurable: true, manifest: "manager", commands: ["rafi manager", "ai-foreman manager"] },
22
+ { id: "discovery", label: "Discovery", consumers: ["project continuation discovery"], configurable: true, manifest: "discovery", commands: ["rafi discover"] },
22
23
  ];
23
24
  function libraryGetter(role) {
24
25
  const a = getAgent(role);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-foreman",
3
- "version": "1.7.14",
3
+ "version": "1.7.16",
4
4
  "description": "An orchestrator that keeps Codex CLI / Claude Code builders moving through their step list unattended. Part of Rafi.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -198,7 +198,7 @@
198
198
  "test": "tsx --test test/*.test.ts",
199
199
  "typecheck": "tsc --noEmit",
200
200
  "test:live-providers": "RAFI_LIVE_PROVIDER_SESSIONS=1 tsx --test test/providerSmoke.test.ts",
201
- "prepublishOnly": "pnpm build && pnpm test && pnpm typecheck"
201
+ "prepublishOnly": "tsc -p ../spec/tsconfig.build.json && tsc -p tsconfig.build.json && pnpm --filter ai-foreman test && tsc --noEmit"
202
202
  },
203
203
  "keywords": [
204
204
  "claude",
@@ -218,8 +218,8 @@
218
218
  "@anthropic-ai/claude-agent-sdk": "^0.3.148"
219
219
  },
220
220
  "dependencies": {
221
- "special-agents": "0.8.9",
222
- "rafi-spec": "0.8.10",
221
+ "special-agents": "0.8.10",
222
+ "rafi-spec": "0.8.11",
223
223
  "@clack/prompts": "^1.4.0",
224
224
  "ajv": "^8.20.0",
225
225
  "ajv-formats": "^3.0.1",