@markjaquith/agency 2.68.0 → 2.69.1

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.
@@ -1,6 +1,6 @@
1
1
  import type { WorkbaseConfig } from "./schemas"
2
2
 
3
- export interface RunnerCommandVariables {
3
+ export interface AgentCommandVariables {
4
4
  readonly prompt: string
5
5
  readonly workbase: string
6
6
  readonly target: string
@@ -11,7 +11,7 @@ export interface RunnerCommandVariables {
11
11
  readonly claimRevision: string
12
12
  }
13
13
 
14
- interface RunnerDefinition {
14
+ interface AgentDefinition {
15
15
  readonly command: readonly string[]
16
16
  readonly autoCommand?: readonly string[]
17
17
  readonly resumeCommand?: readonly string[]
@@ -19,7 +19,7 @@ interface RunnerDefinition {
19
19
  readonly environment?: Readonly<Record<string, string>>
20
20
  }
21
21
 
22
- const PLACEHOLDERS = new Set<keyof RunnerCommandVariables>([
22
+ const PLACEHOLDERS = new Set<keyof AgentCommandVariables>([
23
23
  "prompt",
24
24
  "workbase",
25
25
  "target",
@@ -30,7 +30,7 @@ const PLACEHOLDERS = new Set<keyof RunnerCommandVariables>([
30
30
  "claimRevision",
31
31
  ])
32
32
 
33
- const BUILTIN_RUNNERS: Readonly<Record<string, RunnerDefinition>> = {
33
+ const BUILTIN_AGENTS: Readonly<Record<string, AgentDefinition>> = {
34
34
  opencode2: {
35
35
  command: ["opencode2"],
36
36
  autoCommand: ["opencode2", "--prompt", "{prompt}"],
@@ -43,6 +43,12 @@ const BUILTIN_RUNNERS: Readonly<Record<string, RunnerDefinition>> = {
43
43
  resumeCommand: ["opencode", "--continue"],
44
44
  autoResumeCommand: ["opencode", "--continue", "--prompt", "{prompt}"],
45
45
  },
46
+ pi: {
47
+ command: ["pi"],
48
+ autoCommand: ["pi", "{prompt}"],
49
+ resumeCommand: ["pi", "--continue"],
50
+ autoResumeCommand: ["pi", "--continue", "{prompt}"],
51
+ },
46
52
  claude: {
47
53
  command: ["claude"],
48
54
  autoCommand: ["claude", "{prompt}"],
@@ -51,48 +57,46 @@ const BUILTIN_RUNNERS: Readonly<Record<string, RunnerDefinition>> = {
51
57
  },
52
58
  }
53
59
 
54
- const validateTemplate = (runner: string, value: string) => {
60
+ const validateTemplate = (agent: string, value: string) => {
55
61
  for (const match of value.matchAll(/\{([^{}]+)\}/g)) {
56
62
  const placeholder = match[1]!
57
- if (!PLACEHOLDERS.has(placeholder as keyof RunnerCommandVariables)) {
58
- throw new Error(
59
- `Unknown runner '${runner}' placeholder: {${placeholder}}`,
60
- )
63
+ if (!PLACEHOLDERS.has(placeholder as keyof AgentCommandVariables)) {
64
+ throw new Error(`Unknown agent '${agent}' placeholder: {${placeholder}}`)
61
65
  }
62
66
  }
63
67
  }
64
68
 
65
- export const validateRunners = (runners: WorkbaseConfig["runners"]): void => {
66
- for (const [name, runner] of Object.entries(runners ?? {})) {
69
+ export const validateAgents = (agents: WorkbaseConfig["agents"]): void => {
70
+ for (const [name, agent] of Object.entries(agents ?? {})) {
67
71
  for (const value of [
68
- ...runner.command,
69
- ...(runner.autoCommand ?? []),
70
- ...(runner.resumeCommand ?? []),
71
- ...(runner.autoResumeCommand ?? []),
72
- ...Object.values(runner.environment ?? {}),
72
+ ...agent.command,
73
+ ...(agent.autoCommand ?? []),
74
+ ...(agent.resumeCommand ?? []),
75
+ ...(agent.autoResumeCommand ?? []),
76
+ ...Object.values(agent.environment ?? {}),
73
77
  ]) {
74
78
  validateTemplate(name, value)
75
79
  }
76
80
  }
77
81
  }
78
82
 
79
- const expand = (value: string, variables: RunnerCommandVariables) =>
83
+ const expand = (value: string, variables: AgentCommandVariables) =>
80
84
  value.replaceAll(
81
85
  /\{([^{}]+)\}/g,
82
86
  (match, placeholder: string) =>
83
- variables[placeholder as keyof RunnerCommandVariables] ?? match,
87
+ variables[placeholder as keyof AgentCommandVariables] ?? match,
84
88
  )
85
89
 
86
- export const resolveRunnerCommand = (
90
+ export const resolveAgentCommand = (
87
91
  name: string,
88
- configured: WorkbaseConfig["runners"],
89
- variables: RunnerCommandVariables,
92
+ configured: WorkbaseConfig["agents"],
93
+ variables: AgentCommandVariables,
90
94
  resume: boolean,
91
95
  auto = false,
92
96
  ) => {
93
- validateRunners(configured)
94
- const definition = configured?.[name] ?? BUILTIN_RUNNERS[name]
95
- if (!definition) throw new Error(`Unknown runner: ${name}`)
97
+ validateAgents(configured)
98
+ const definition = configured?.[name] ?? BUILTIN_AGENTS[name]
99
+ if (!definition) throw new Error(`Unknown agent: ${name}`)
96
100
  const template = auto
97
101
  ? resume
98
102
  ? (definition.autoResumeCommand ?? definition.autoCommand)
@@ -101,7 +105,7 @@ export const resolveRunnerCommand = (
101
105
  ? definition.resumeCommand
102
106
  : definition.command
103
107
  if (!template) {
104
- throw new Error(`Runner '${name}' does not support --auto`)
108
+ throw new Error(`Agent '${name}' does not support --auto`)
105
109
  }
106
110
  const argv = template.map((argument) => expand(argument, variables))
107
111
  const environment = Object.fromEntries(
@@ -113,11 +117,11 @@ export const resolveRunnerCommand = (
113
117
  return { argv, environment }
114
118
  }
115
119
 
116
- export const runnerEnvironment = (
117
- runner: string,
118
- variables: RunnerCommandVariables,
120
+ export const agentEnvironment = (
121
+ agent: string,
122
+ variables: AgentCommandVariables,
119
123
  ): Record<string, string> => ({
120
- AGENCY_RUNNER: runner,
124
+ AGENCY_AGENT: agent,
121
125
  AGENCY_CLAIMANT: variables.claimant,
122
126
  AGENCY_SESSION_ID: variables.sessionId,
123
127
  AGENCY_CLAIM_REVISION: variables.claimRevision,
@@ -325,11 +325,11 @@ export const buildKickoffPlan = (input: {
325
325
  recovery: "Reuse the existing split when present.",
326
326
  },
327
327
  {
328
- id: "runner-start",
328
+ id: "agent-start",
329
329
  cwd: taskDirectory,
330
330
  argv: ["agency", "work", ".", "--auto"],
331
331
  recovery:
332
- "Inspect the recorded tab before retrying; a working runner must not be duplicated.",
332
+ "Inspect the recorded tab before retrying; a working agent must not be duplicated.",
333
333
  },
334
334
  {
335
335
  id: "final-context-verification",
@@ -341,7 +341,7 @@ export const buildKickoffPlan = (input: {
341
341
  ],
342
342
  exactlyOnce: true,
343
343
  recovery:
344
- "If verification fails, inspect the existing tab; do not launch another runner.",
344
+ "If verification fails, inspect the existing tab; do not launch another agent.",
345
345
  },
346
346
  ],
347
347
  successFields: [
@@ -351,7 +351,7 @@ export const buildKickoffPlan = (input: {
351
351
  "preparedCheckout",
352
352
  "herdrWorkspace",
353
353
  "herdrTab",
354
- "runnerStart",
354
+ "agentStart",
355
355
  "contextVerification",
356
356
  ],
357
357
  }
@@ -31,7 +31,7 @@ const body = () =>
31
31
  "Handles Agency workbase orchestration and workflow operations with the Agency CLI",
32
32
  mode: "subagent",
33
33
  prompt:
34
- "You are the Agency workflow specialist. Use the Agency CLI to handle delegated workbase orchestration and workflow operations. Always start with `agency context . --json`, follow the managed Agency instructions and reported authority, use Agency commands for durable mutations, and report the resulting state concisely. When delegated to start or kick off work in another agent, launch it, verify that the runner started successfully, and return without waiting for the task to finish.",
34
+ "You are the Agency workflow specialist. Use the Agency CLI to handle delegated workbase orchestration and workflow operations. Always start with `agency context . --json`, follow the managed Agency instructions and reported authority, use Agency commands for durable mutations, and report the resulting state concisely. When delegated to start or kick off work in another agent, launch it, verify that the agent started successfully, and return without waiting for the task to finish.",
35
35
  },
36
36
  plan: {
37
37
  disable: true,
@@ -276,11 +276,11 @@ describe("workspace creation configuration", () => {
276
276
  })
277
277
  })
278
278
 
279
- describe("runner configuration", () => {
279
+ describe("agent configuration", () => {
280
280
  test("accepts named argv commands with resume commands and environment", () => {
281
281
  const config = Schema.decodeUnknownSync(WorkbaseConfig)({
282
282
  version: 2,
283
- runners: {
283
+ agents: {
284
284
  custom: {
285
285
  command: ["agent"],
286
286
  autoCommand: ["agent", "{prompt}"],
@@ -291,14 +291,14 @@ describe("runner configuration", () => {
291
291
  },
292
292
  })
293
293
 
294
- expect(config.runners?.custom?.autoCommand).toEqual(["agent", "{prompt}"])
294
+ expect(config.agents?.custom?.autoCommand).toEqual(["agent", "{prompt}"])
295
295
  })
296
296
 
297
297
  test("rejects shell strings in place of argv arrays", () => {
298
298
  expect(() =>
299
299
  Schema.decodeUnknownSync(WorkbaseConfig)({
300
300
  version: 2,
301
- runners: { custom: { command: "agent {prompt}" } },
301
+ agents: { custom: { command: "agent {prompt}" } },
302
302
  }),
303
303
  ).toThrow()
304
304
  })
@@ -423,7 +423,7 @@ describe("work status", () => {
423
423
  describe("claim records", () => {
424
424
  const record = {
425
425
  claimant: "orchestrator",
426
- runner: "agent",
426
+ agent: "agent",
427
427
  sessionId: "job-1",
428
428
  startedAt: "2026-07-17T12:00:00.000Z",
429
429
  targetRevision: "0".repeat(64),
@@ -52,7 +52,7 @@ export const DocumentRevision = Schema.String.pipe(
52
52
 
53
53
  export const ClaimRecord = Schema.Struct({
54
54
  claimant: NonEmptyString,
55
- runner: NonEmptyString,
55
+ agent: NonEmptyString,
56
56
  sessionId: NonEmptyString,
57
57
  startedAt: IsoTimestamp,
58
58
  targetRevision: DocumentRevision,
@@ -110,7 +110,7 @@ export const WorkbaseConfig = Schema.Struct({
110
110
  chooserCommand: Schema.optional(Schema.NonEmptyArray(NonEmptyString)),
111
111
  worktreeCreateCommand: Schema.optional(Schema.NonEmptyArray(NonEmptyString)),
112
112
  workspaceCreateCommand: Schema.optional(Schema.NonEmptyArray(NonEmptyString)),
113
- runners: Schema.optional(
113
+ agents: Schema.optional(
114
114
  Schema.Record({
115
115
  key: EntityId,
116
116
  value: Schema.Struct({
@@ -146,6 +146,12 @@ export const WorkbaseRegistry = Schema.Struct({
146
146
  defaultId: Schema.optional(EntityId),
147
147
  })
148
148
 
149
+ export const GlobalConfig = Schema.Struct({
150
+ agent: Schema.optional(
151
+ Schema.Literal("opencode2", "opencode", "pi", "claude"),
152
+ ),
153
+ })
154
+
149
155
  export const Dependency = Schema.Struct({
150
156
  id: EntityId,
151
157
  dependsOn: Schema.optional(Schema.Array(EntityId)),