@gobing-ai/ts-ai-runner 0.4.27 → 0.4.30

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
@@ -287,10 +287,14 @@ Use `getGitContext()` to auto-detect the current branch and dirty state:
287
287
  ```ts
288
288
  import { getGitContext } from '@gobing-ai/ts-ai-runner';
289
289
 
290
- const gitBlock = getGitContext('/workspace/spur');
290
+ const gitBlock = await getGitContext('/workspace/spur');
291
291
  // "Git context:\nbranch: feat/team-mode\ndirty: 3 files"
292
292
  ```
293
293
 
294
+ > `getGitContext` is async (returns `Promise<string | null>`) and defaults to the canonical
295
+ > `ProcessExecutor` from `@gobing-ai/ts-runtime`. A deprecated sync escape hatch `getGitContextSync`
296
+ > remains for one release for sync callers.
297
+
294
298
  ## Session Affinity (run-scoped sessions)
295
299
 
296
300
  `PromptOptions` carries two additive fields for pinning or isolating sessions:
@@ -1 +1 @@
1
- {"version":3,"file":"auth-shims.d.ts","sourceRoot":"","sources":["../../src/agents/auth-shims.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAA2B,MAAM,uBAAuB,CAAC;AACjF,OAAO,KAAK,EAAmC,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EAAE,KAAK,SAAS,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvD;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,SAAS,GAAG,eAAe,GAAG,iBAAiB,GAAG,SAAS,CAAC;AAExE,qDAAqD;AACrD,MAAM,WAAW,WAAW;IACxB,0CAA0C;IAC1C,MAAM,EAAE,QAAQ,CAAC;IACjB,6EAA6E;IAC7E,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,0EAA0E;IAC1E,UAAU,EAAE,UAAU,CAAC;IACvB,0CAA0C;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AA6CD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAiB5F;AA+DD,OAAO,EAAE,YAAY,EAAE,CAAC"}
1
+ {"version":3,"file":"auth-shims.d.ts","sourceRoot":"","sources":["../../src/agents/auth-shims.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,UAAU,EAA2B,MAAM,uBAAuB,CAAC;AACjF,OAAO,KAAK,EAAmC,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EAAE,KAAK,SAAS,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvD;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,SAAS,GAAG,eAAe,GAAG,iBAAiB,GAAG,SAAS,CAAC;AAExE,qDAAqD;AACrD,MAAM,WAAW,WAAW;IACxB,0CAA0C;IAC1C,MAAM,EAAE,QAAQ,CAAC;IACjB,6EAA6E;IAC7E,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,0EAA0E;IAC1E,UAAU,EAAE,UAAU,CAAC;IACvB,0CAA0C;IAC1C,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AA6CD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAiB5F;AAkFD,OAAO,EAAE,YAAY,EAAE,CAAC"}
@@ -97,14 +97,38 @@ async function checkGrokAuth(fs, home, env) {
97
97
  return 'unknown';
98
98
  }
99
99
  async function geminiSettingsContainCredentials(fs, home) {
100
+ let content;
100
101
  try {
101
- const content = await fs.readFile(joinPath(home, '.gemini', 'settings.json'));
102
- return /auth|token|key/i.test(content) ? 'authenticated' : 'unauthenticated';
102
+ content = await fs.readFile(joinPath(home, '.gemini', 'settings.json'));
103
103
  }
104
104
  catch {
105
105
  // Missing or unreadable settings — auth state genuinely unknown.
106
106
  return 'unknown';
107
107
  }
108
+ // Credential-shaped fields only (task 0060 R14): a loose /auth|token|key/i substring
109
+ // match would mark a UI banner flag ({"ui":{"showAuthBanner":true}}) or an empty
110
+ // apiKey as authenticated.
111
+ let settings;
112
+ try {
113
+ settings = JSON.parse(content);
114
+ }
115
+ catch {
116
+ return 'unauthenticated'; // Not JSON — no usable credentials.
117
+ }
118
+ if (typeof settings !== 'object' || settings === null)
119
+ return 'unauthenticated';
120
+ const record = settings;
121
+ if (typeof record.apiKey === 'string' && record.apiKey.length > 0)
122
+ return 'authenticated';
123
+ if (typeof record.accessToken === 'string' && record.accessToken.length > 0)
124
+ return 'authenticated';
125
+ const tokens = record.tokens;
126
+ if (tokens !== null && typeof tokens === 'object') {
127
+ const accessToken = tokens.access_token;
128
+ if (typeof accessToken === 'string' && accessToken.length > 0)
129
+ return 'authenticated';
130
+ }
131
+ return 'unauthenticated';
108
132
  }
109
133
  async function probeAuthOutput(runner, agent, timeout) {
110
134
  const options = { timeout };
@@ -1 +1 @@
1
- {"version":3,"file":"ai-runner.d.ts","sourceRoot":"","sources":["../src/ai-runner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ai-runner.d.ts","sourceRoot":"","sources":["../src/ai-runner.ts"],"names":[],"mappings":"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"}
package/dist/ai-runner.js CHANGED
@@ -118,6 +118,7 @@ export class AiRunner {
118
118
  operation,
119
119
  label,
120
120
  ...(options.correlation !== undefined ? { correlation: options.correlation } : {}),
121
+ severity: 'info',
121
122
  });
122
123
  const correlationEnv = options.correlation === undefined ? undefined : buildCorrelationEnv(options.correlation);
123
124
  const result = await this.processExecutor.run({
@@ -147,6 +148,7 @@ export class AiRunner {
147
148
  ...(result.signal !== undefined ? { signal: result.signal } : {}),
148
149
  durationMs: result.durationMs,
149
150
  ...(options.correlation !== undefined ? { correlation: options.correlation } : {}),
151
+ severity: result.exitCode === 0 || result.exitCode === null ? 'info' : 'error',
150
152
  });
151
153
  return {
152
154
  exitCode: result.exitCode,
package/dist/events.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { EventSeverity } from '@gobing-ai/ts-infra';
1
2
  import type { ProcessEvents } from '@gobing-ai/ts-runtime';
2
3
  import type { AgentRunCorrelation } from './ai-runner';
3
4
  /** Typed event map for agent-runner observability. All events prefixed `agent.`. */
@@ -8,6 +9,7 @@ export type AgentEvents = {
8
9
  operation: string;
9
10
  label: string;
10
11
  correlation?: AgentRunCorrelation;
12
+ severity: EventSeverity;
11
13
  }) => void;
12
14
  /** Emitted after an agent CLI invocation exits. */
13
15
  'agent.invoke.exit': (data: {
@@ -18,22 +20,26 @@ export type AgentEvents = {
18
20
  signal?: string;
19
21
  durationMs: number;
20
22
  correlation?: AgentRunCorrelation;
23
+ severity: EventSeverity;
21
24
  }) => void;
22
25
  /** Emitted when a long-running team agent process starts. */
23
26
  'agent.started': (data: {
24
27
  agentId: string;
25
28
  agentType: string;
26
29
  pid: number | null;
30
+ severity: EventSeverity;
27
31
  }) => void;
28
32
  /** Emitted when a long-running team agent process stops. */
29
33
  'agent.stopped': (data: {
30
34
  agentId: string;
31
35
  exitCode: number | null;
36
+ severity: EventSeverity;
32
37
  }) => void;
33
38
  /** Emitted when a message is sent to a team agent process. */
34
39
  'agent.message.sent': (data: {
35
40
  agentId: string;
36
41
  ok: boolean;
42
+ severity: EventSeverity;
37
43
  }) => void;
38
44
  };
39
45
  /** Event map for process-level observability emitted by AiRunner-owned executors. */
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,oFAAoF;AACpF,MAAM,MAAM,WAAW,GAAG;IACtB,iEAAiE;IACjE,oBAAoB,EAAE,CAAC,IAAI,EAAE;QACzB,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,mBAAmB,CAAC;KACrC,KAAK,IAAI,CAAC;IACX,mDAAmD;IACnD,mBAAmB,EAAE,CAAC,IAAI,EAAE;QACxB,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,mBAAmB,CAAC;KACrC,KAAK,IAAI,CAAC;IACX,6DAA6D;IAC7D,eAAe,EAAE,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,KAAK,IAAI,CAAC;IAC5F,4DAA4D;IAC5D,eAAe,EAAE,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,KAAK,IAAI,CAAC;IAC9E,8DAA8D;IAC9D,oBAAoB,EAAE,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAA;KAAE,KAAK,IAAI,CAAC;CAC1E,CAAC;AAEF,qFAAqF;AACrF,MAAM,MAAM,qBAAqB,GAAG,aAAa,CAAC"}
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvD,oFAAoF;AACpF,MAAM,MAAM,WAAW,GAAG;IACtB,iEAAiE;IACjE,oBAAoB,EAAE,CAAC,IAAI,EAAE;QACzB,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,mBAAmB,CAAC;QAClC,QAAQ,EAAE,aAAa,CAAC;KAC3B,KAAK,IAAI,CAAC;IACX,mDAAmD;IACnD,mBAAmB,EAAE,CAAC,IAAI,EAAE;QACxB,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,WAAW,CAAC,EAAE,mBAAmB,CAAC;QAClC,QAAQ,EAAE,aAAa,CAAC;KAC3B,KAAK,IAAI,CAAC;IACX,6DAA6D;IAC7D,eAAe,EAAE,CAAC,IAAI,EAAE;QACpB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;QACnB,QAAQ,EAAE,aAAa,CAAC;KAC3B,KAAK,IAAI,CAAC;IACX,4DAA4D;IAC5D,eAAe,EAAE,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,EAAE,aAAa,CAAA;KAAE,KAAK,IAAI,CAAC;IACvG,8DAA8D;IAC9D,oBAAoB,EAAE,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,aAAa,CAAA;KAAE,KAAK,IAAI,CAAC;CACnG,CAAC;AAEF,qFAAqF;AACrF,MAAM,MAAM,qBAAqB,GAAG,aAAa,CAAC"}
@@ -1,4 +1,4 @@
1
- import { type SyncProcessExecutor } from '@gobing-ai/ts-runtime';
1
+ import { type ProcessExecutor, type SyncProcessExecutor } from '@gobing-ai/ts-runtime';
2
2
  /** Context used to construct the identity preamble injected into agent prompts. */
3
3
  export interface IdentityContext {
4
4
  agentId: string;
@@ -19,6 +19,20 @@ export interface IdentityContext {
19
19
  }
20
20
  /** Build a human-readable identity preamble string that describes the agent, its task, peers, guardrails, and git context. */
21
21
  export declare function buildIdentityPreamble(ctx: IdentityContext): string;
22
- /** Query git for the current branch name and dirty file count in `workspacePath`. Returns a pre-formatted "Git context" block, or `null` if git is unavailable or the directory is not a repo. */
23
- export declare function getGitContext(workspacePath: string, executor?: SyncProcessExecutor): string | null;
22
+ /**
23
+ * Query git for the current branch name and dirty file count in `workspacePath`.
24
+ *
25
+ * Returns a pre-formatted "Git context" block, or `null` if git is unavailable or the directory is
26
+ * not a repo. Uses the canonical async {@link ProcessExecutor} (defaulting to
27
+ * `nodeBunFactory.createProcessExecutor()`) per ADR-023 A2 — never the deprecated
28
+ * {@link BunSyncProcessExecutor}.
29
+ */
30
+ export declare function getGitContext(workspacePath: string, executor?: ProcessExecutor): Promise<string | null>;
31
+ /**
32
+ * Query git for the current branch name and dirty file count synchronously.
33
+ *
34
+ * @deprecated Use the async {@link getGitContext} instead. Kept for one release for sync callers.
35
+ * Defaults to the deprecated {@link BunSyncProcessExecutor}; new code must not rely on it.
36
+ */
37
+ export declare function getGitContextSync(workspacePath: string, executor?: SyncProcessExecutor): string | null;
24
38
  //# sourceMappingURL=identity.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,KAAK,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAEzF,mFAAmF;AACnF,MAAM,WAAW,eAAe;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,8HAA8H;AAC9H,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CA8ClE;AAED,kMAAkM;AAClM,wBAAgB,aAAa,CACzB,aAAa,EAAE,MAAM,EACrB,QAAQ,GAAE,mBAAkD,GAC7D,MAAM,GAAG,IAAI,CASf"}
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../src/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,KAAK,eAAe,EACpB,KAAK,mBAAmB,EAC3B,MAAM,uBAAuB,CAAC;AAE/B,mFAAmF;AACnF,MAAM,WAAW,eAAe;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,8HAA8H;AAC9H,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,CA8ClE;AAED;;;;;;;GAOG;AACH,wBAAsB,aAAa,CAC/B,aAAa,EAAE,MAAM,EACrB,QAAQ,GAAE,eAAwD,GACnE,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CASxB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC7B,aAAa,EAAE,MAAM,EACrB,QAAQ,GAAE,mBAAkD,GAC7D,MAAM,GAAG,IAAI,CASf"}
package/dist/identity.js CHANGED
@@ -1,4 +1,4 @@
1
- import { BunSyncProcessExecutor } from '@gobing-ai/ts-runtime';
1
+ import { BunSyncProcessExecutor, nodeBunFactory, } from '@gobing-ai/ts-runtime';
2
2
  /** Build a human-readable identity preamble string that describes the agent, its task, peers, guardrails, and git context. */
3
3
  export function buildIdentityPreamble(ctx) {
4
4
  const sections = [
@@ -32,16 +32,43 @@ export function buildIdentityPreamble(ctx) {
32
32
  }
33
33
  return `${sections.join('\n\n')}\n`;
34
34
  }
35
- /** Query git for the current branch name and dirty file count in `workspacePath`. Returns a pre-formatted "Git context" block, or `null` if git is unavailable or the directory is not a repo. */
36
- export function getGitContext(workspacePath, executor = new BunSyncProcessExecutor()) {
37
- const branch = runGit(executor, ['-C', workspacePath, 'branch', '--show-current']);
35
+ /**
36
+ * Query git for the current branch name and dirty file count in `workspacePath`.
37
+ *
38
+ * Returns a pre-formatted "Git context" block, or `null` if git is unavailable or the directory is
39
+ * not a repo. Uses the canonical async {@link ProcessExecutor} (defaulting to
40
+ * `nodeBunFactory.createProcessExecutor()`) per ADR-023 A2 — never the deprecated
41
+ * {@link BunSyncProcessExecutor}.
42
+ */
43
+ export async function getGitContext(workspacePath, executor = nodeBunFactory.createProcessExecutor()) {
44
+ const branch = await runGit(executor, ['-C', workspacePath, 'branch', '--show-current']);
38
45
  if (branch === null || branch === '')
39
46
  return null;
40
- const status = runGit(executor, ['-C', workspacePath, 'status', '--porcelain']);
47
+ const status = await runGit(executor, ['-C', workspacePath, 'status', '--porcelain']);
41
48
  const dirtyCount = status === null || status === '' ? 0 : status.split('\n').filter(Boolean).length;
42
49
  return ['Git context:', `branch: ${branch}`, `dirty: ${dirtyCount === 0 ? 'false' : `${dirtyCount} files`}`].join('\n');
43
50
  }
44
- function runGit(executor, args) {
51
+ /**
52
+ * Query git for the current branch name and dirty file count synchronously.
53
+ *
54
+ * @deprecated Use the async {@link getGitContext} instead. Kept for one release for sync callers.
55
+ * Defaults to the deprecated {@link BunSyncProcessExecutor}; new code must not rely on it.
56
+ */
57
+ export function getGitContextSync(workspacePath, executor = new BunSyncProcessExecutor()) {
58
+ const branch = runGitSync(executor, ['-C', workspacePath, 'branch', '--show-current']);
59
+ if (branch === null || branch === '')
60
+ return null;
61
+ const status = runGitSync(executor, ['-C', workspacePath, 'status', '--porcelain']);
62
+ const dirtyCount = status === null || status === '' ? 0 : status.split('\n').filter(Boolean).length;
63
+ return ['Git context:', `branch: ${branch}`, `dirty: ${dirtyCount === 0 ? 'false' : `${dirtyCount} files`}`].join('\n');
64
+ }
65
+ async function runGit(executor, args) {
66
+ const result = await executor.run({ command: 'git', args, rejectOnError: false, forceBuffered: true });
67
+ if (result.exitCode !== 0)
68
+ return null;
69
+ return result.stdout.trim();
70
+ }
71
+ function runGitSync(executor, args) {
45
72
  const result = executor.runSync({ command: 'git', args, rejectOnError: false, forceBuffered: true });
46
73
  if (result.exitCode !== 0)
47
74
  return null;
@@ -23,7 +23,9 @@ export interface DrainedMessage {
23
23
  */
24
24
  export interface MessageStore {
25
25
  enqueue(fromId: string | null, toId: string, body: string, inReplyTo?: string): Promise<string>;
26
- drainPending(toId: string): Promise<DrainedMessage[]>;
26
+ drainPending(toId: string, options?: {
27
+ limit?: number;
28
+ }): Promise<DrainedMessage[]>;
27
29
  markDelivered(msgId: string): Promise<void>;
28
30
  markFailed(msgId: string, error: string): Promise<void>;
29
31
  }
@@ -1 +1 @@
1
- {"version":3,"file":"message-store.d.ts","sourceRoot":"","sources":["../src/message-store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACzB;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IACzB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAChG,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IACtD,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3D"}
1
+ {"version":3,"file":"message-store.d.ts","sourceRoot":"","sources":["../src/message-store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACzB;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IACzB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAChG,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IACpF,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3D"}
@@ -1 +1 @@
1
- {"version":3,"file":"team-orchestrator.d.ts","sourceRoot":"","sources":["../src/team-orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,kBAAkB,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAI9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,KAAK,mBAAmB,GAAG,CAAC,OAAO,EAAE,qBAAqB,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC,KAAK,gBAAgB,CAAC;AAE5G,oDAAoD;AACpD,MAAM,WAAW,uBAAuB;IACpC,cAAc,CAAC,EAAE,mBAAmB,CAAC;IACrC,MAAM,CAAC,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC/B;;;;OAIG;IACH,YAAY,CAAC,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC;CAC/C;AAED;;;GAGG;AACH,qBAAa,gBAAgB;IAOrB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK;IAP1B,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAC/D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAsB;IACrD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;gBAG1B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,YAAY,EACpC,OAAO,GAAE,uBAA4B;IAUnC,SAAS,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAKjC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAKnD,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAiCjD,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAQpC,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAKnD,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQzG,gBAAgB,IAAI,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAI3C,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IAMlF,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAKzE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAI9B,EAAE,CAAC,CAAC,SAAS,MAAM,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;YAKjE,WAAW;IAMzB,OAAO,CAAC,gBAAgB;YAMV,qBAAqB;YAIrB,UAAU;CAa3B"}
1
+ {"version":3,"file":"team-orchestrator.d.ts","sourceRoot":"","sources":["../src/team-orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,kBAAkB,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAI9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAEpD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,KAAK,mBAAmB,GAAG,CAAC,OAAO,EAAE,qBAAqB,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAC,CAAC,KAAK,gBAAgB,CAAC;AAE5G,oDAAoD;AACpD,MAAM,WAAW,uBAAuB;IACpC,cAAc,CAAC,EAAE,mBAAmB,CAAC;IACrC,MAAM,CAAC,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC/B;;;;OAIG;IACH,YAAY,CAAC,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAAC;CAC/C;AAED;;;GAGG;AACH,qBAAa,gBAAgB;IAOrB,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,KAAK;IAP1B,OAAO,CAAC,KAAK,CAAmB;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAuC;IAC/D,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAsB;IACrD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;gBAG1B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,YAAY,EACpC,OAAO,GAAE,uBAA4B;IAUnC,SAAS,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAKjC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;IAKnD,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAkCjD,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAapC,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAKnD,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQzG,gBAAgB,IAAI,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAI3C,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IAMlF,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAKzE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAI9B,EAAE,CAAC,CAAC,SAAS,MAAM,WAAW,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI;YAKjE,WAAW;IAMzB,OAAO,CAAC,gBAAgB;YAMV,qBAAqB;YAIrB,UAAU;CAmB3B"}
@@ -59,6 +59,7 @@ export class TeamOrchestrator {
59
59
  agentId: spec.id,
60
60
  agentType: spec.type,
61
61
  pid: process.getPid(),
62
+ severity: 'info',
62
63
  });
63
64
  return process;
64
65
  }
@@ -68,7 +69,12 @@ export class TeamOrchestrator {
68
69
  return;
69
70
  await process.stop();
70
71
  this.running.delete(id);
71
- void this.events.emit('agent.stopped', { agentId: id, exitCode: process.getExitCode() });
72
+ const exitCode = process.getExitCode();
73
+ void this.events.emit('agent.stopped', {
74
+ agentId: id,
75
+ exitCode,
76
+ severity: exitCode === 0 || exitCode === null ? 'info' : 'warning',
77
+ });
72
78
  }
73
79
  async restartAgent(id) {
74
80
  await this.stopAgent(id);
@@ -78,7 +84,7 @@ export class TeamOrchestrator {
78
84
  const msgId = await this.inbox.enqueue(fromId, toId, body, inReplyTo);
79
85
  const process = this.running.get(toId);
80
86
  const ok = process !== undefined ? await this.flushInbox(process, 'live stdin injection failed') : false;
81
- void this.events.emit('agent.message.sent', { agentId: toId, ok });
87
+ void this.events.emit('agent.message.sent', { agentId: toId, ok, severity: ok ? 'info' : 'warning' });
82
88
  return msgId;
83
89
  }
84
90
  getRunningAgents() {
@@ -118,16 +124,24 @@ export class TeamOrchestrator {
118
124
  return this.flushInbox(process, 'startup stdin injection failed');
119
125
  }
120
126
  async flushInbox(process, failLabel) {
121
- const messages = await this.inbox.drainPending(process.agentId);
127
+ // Drain in pages (default 100 per drainPending — task 0060 F10) until a short page,
128
+ // so a backed-up inbox is fully flushed without one giant claim.
122
129
  let ok = true;
123
- for (const message of messages) {
124
- const result = await process.send(formatMessage(message));
125
- if (result.ok)
126
- await this.inbox.markDelivered(message.id);
127
- else {
128
- ok = false;
129
- await this.inbox.markFailed(message.id, failLabel);
130
+ for (;;) {
131
+ const messages = await this.inbox.drainPending(process.agentId);
132
+ if (messages.length === 0)
133
+ break;
134
+ for (const message of messages) {
135
+ const result = await process.send(formatMessage(message));
136
+ if (result.ok)
137
+ await this.inbox.markDelivered(message.id);
138
+ else {
139
+ ok = false;
140
+ await this.inbox.markFailed(message.id, failLabel);
141
+ }
130
142
  }
143
+ if (messages.length < 100)
144
+ break;
131
145
  }
132
146
  return ok;
133
147
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gobing-ai/ts-ai-runner",
3
- "version": "0.4.27",
3
+ "version": "0.4.30",
4
4
  "description": "@gobing-ai/ts-ai-runner — Coding-agent shims, detection, doctor checks, and prompt execution.",
5
5
  "keywords": [
6
6
  "typescript",
@@ -47,12 +47,12 @@
47
47
  "release": "echo 'Manual publish is disabled. Releases go through GitHub Actions via Trusted Publishing — push a tag: git tag @gobing-ai/ts-ai-runner-v<version> && git push --tags' && exit 1"
48
48
  },
49
49
  "dependencies": {
50
- "@gobing-ai/ts-infra": "^0.4.27",
51
- "@gobing-ai/ts-runtime": "^0.4.27"
50
+ "@gobing-ai/ts-infra": "^0.4.30",
51
+ "@gobing-ai/ts-runtime": "^0.4.30"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@types/bun": "1.3.14",
55
- "@gobing-ai/ts-db": "^0.4.27"
55
+ "@gobing-ai/ts-db": "^0.4.30"
56
56
  },
57
57
  "publishConfig": {
58
58
  "access": "public"
@@ -136,13 +136,32 @@ async function checkGrokAuth(
136
136
  }
137
137
 
138
138
  async function geminiSettingsContainCredentials(fs: FileSystem, home: string): Promise<AuthState> {
139
+ let content: string;
139
140
  try {
140
- const content = await fs.readFile(joinPath(home, '.gemini', 'settings.json'));
141
- return /auth|token|key/i.test(content) ? 'authenticated' : 'unauthenticated';
141
+ content = await fs.readFile(joinPath(home, '.gemini', 'settings.json'));
142
142
  } catch {
143
143
  // Missing or unreadable settings — auth state genuinely unknown.
144
144
  return 'unknown';
145
145
  }
146
+ // Credential-shaped fields only (task 0060 R14): a loose /auth|token|key/i substring
147
+ // match would mark a UI banner flag ({"ui":{"showAuthBanner":true}}) or an empty
148
+ // apiKey as authenticated.
149
+ let settings: unknown;
150
+ try {
151
+ settings = JSON.parse(content);
152
+ } catch {
153
+ return 'unauthenticated'; // Not JSON — no usable credentials.
154
+ }
155
+ if (typeof settings !== 'object' || settings === null) return 'unauthenticated';
156
+ const record = settings as Record<string, unknown>;
157
+ if (typeof record.apiKey === 'string' && record.apiKey.length > 0) return 'authenticated';
158
+ if (typeof record.accessToken === 'string' && record.accessToken.length > 0) return 'authenticated';
159
+ const tokens = record.tokens;
160
+ if (tokens !== null && typeof tokens === 'object') {
161
+ const accessToken = (tokens as Record<string, unknown>).access_token;
162
+ if (typeof accessToken === 'string' && accessToken.length > 0) return 'authenticated';
163
+ }
164
+ return 'unauthenticated';
146
165
  }
147
166
 
148
167
  async function probeAuthOutput(runner: AiRunner, agent: AgentName, timeout: number): Promise<AuthState> {
package/src/ai-runner.ts CHANGED
@@ -212,6 +212,7 @@ export class AiRunner {
212
212
  operation,
213
213
  label,
214
214
  ...(options.correlation !== undefined ? { correlation: options.correlation } : {}),
215
+ severity: 'info',
215
216
  });
216
217
  const correlationEnv = options.correlation === undefined ? undefined : buildCorrelationEnv(options.correlation);
217
218
  const result: ProcessResult = await this.processExecutor.run({
@@ -241,6 +242,7 @@ export class AiRunner {
241
242
  ...(result.signal !== undefined ? { signal: result.signal } : {}),
242
243
  durationMs: result.durationMs,
243
244
  ...(options.correlation !== undefined ? { correlation: options.correlation } : {}),
245
+ severity: result.exitCode === 0 || result.exitCode === null ? 'info' : 'error',
244
246
  });
245
247
  return {
246
248
  exitCode: result.exitCode,
package/src/events.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { EventSeverity } from '@gobing-ai/ts-infra';
1
2
  import type { ProcessEvents } from '@gobing-ai/ts-runtime';
2
3
  import type { AgentRunCorrelation } from './ai-runner';
3
4
 
@@ -9,6 +10,7 @@ export type AgentEvents = {
9
10
  operation: string;
10
11
  label: string;
11
12
  correlation?: AgentRunCorrelation;
13
+ severity: EventSeverity;
12
14
  }) => void;
13
15
  /** Emitted after an agent CLI invocation exits. */
14
16
  'agent.invoke.exit': (data: {
@@ -19,13 +21,19 @@ export type AgentEvents = {
19
21
  signal?: string;
20
22
  durationMs: number;
21
23
  correlation?: AgentRunCorrelation;
24
+ severity: EventSeverity;
22
25
  }) => void;
23
26
  /** Emitted when a long-running team agent process starts. */
24
- 'agent.started': (data: { agentId: string; agentType: string; pid: number | null }) => void;
27
+ 'agent.started': (data: {
28
+ agentId: string;
29
+ agentType: string;
30
+ pid: number | null;
31
+ severity: EventSeverity;
32
+ }) => void;
25
33
  /** Emitted when a long-running team agent process stops. */
26
- 'agent.stopped': (data: { agentId: string; exitCode: number | null }) => void;
34
+ 'agent.stopped': (data: { agentId: string; exitCode: number | null; severity: EventSeverity }) => void;
27
35
  /** Emitted when a message is sent to a team agent process. */
28
- 'agent.message.sent': (data: { agentId: string; ok: boolean }) => void;
36
+ 'agent.message.sent': (data: { agentId: string; ok: boolean; severity: EventSeverity }) => void;
29
37
  };
30
38
 
31
39
  /** Event map for process-level observability emitted by AiRunner-owned executors. */
package/src/identity.ts CHANGED
@@ -1,4 +1,9 @@
1
- import { BunSyncProcessExecutor, type SyncProcessExecutor } from '@gobing-ai/ts-runtime';
1
+ import {
2
+ BunSyncProcessExecutor,
3
+ nodeBunFactory,
4
+ type ProcessExecutor,
5
+ type SyncProcessExecutor,
6
+ } from '@gobing-ai/ts-runtime';
2
7
 
3
8
  /** Context used to construct the identity preamble injected into agent prompts. */
4
9
  export interface IdentityContext {
@@ -64,22 +69,55 @@ export function buildIdentityPreamble(ctx: IdentityContext): string {
64
69
  return `${sections.join('\n\n')}\n`;
65
70
  }
66
71
 
67
- /** Query git for the current branch name and dirty file count in `workspacePath`. Returns a pre-formatted "Git context" block, or `null` if git is unavailable or the directory is not a repo. */
68
- export function getGitContext(
72
+ /**
73
+ * Query git for the current branch name and dirty file count in `workspacePath`.
74
+ *
75
+ * Returns a pre-formatted "Git context" block, or `null` if git is unavailable or the directory is
76
+ * not a repo. Uses the canonical async {@link ProcessExecutor} (defaulting to
77
+ * `nodeBunFactory.createProcessExecutor()`) per ADR-023 A2 — never the deprecated
78
+ * {@link BunSyncProcessExecutor}.
79
+ */
80
+ export async function getGitContext(
81
+ workspacePath: string,
82
+ executor: ProcessExecutor = nodeBunFactory.createProcessExecutor(),
83
+ ): Promise<string | null> {
84
+ const branch = await runGit(executor, ['-C', workspacePath, 'branch', '--show-current']);
85
+ if (branch === null || branch === '') return null;
86
+
87
+ const status = await runGit(executor, ['-C', workspacePath, 'status', '--porcelain']);
88
+ const dirtyCount = status === null || status === '' ? 0 : status.split('\n').filter(Boolean).length;
89
+ return ['Git context:', `branch: ${branch}`, `dirty: ${dirtyCount === 0 ? 'false' : `${dirtyCount} files`}`].join(
90
+ '\n',
91
+ );
92
+ }
93
+
94
+ /**
95
+ * Query git for the current branch name and dirty file count synchronously.
96
+ *
97
+ * @deprecated Use the async {@link getGitContext} instead. Kept for one release for sync callers.
98
+ * Defaults to the deprecated {@link BunSyncProcessExecutor}; new code must not rely on it.
99
+ */
100
+ export function getGitContextSync(
69
101
  workspacePath: string,
70
102
  executor: SyncProcessExecutor = new BunSyncProcessExecutor(),
71
103
  ): string | null {
72
- const branch = runGit(executor, ['-C', workspacePath, 'branch', '--show-current']);
104
+ const branch = runGitSync(executor, ['-C', workspacePath, 'branch', '--show-current']);
73
105
  if (branch === null || branch === '') return null;
74
106
 
75
- const status = runGit(executor, ['-C', workspacePath, 'status', '--porcelain']);
107
+ const status = runGitSync(executor, ['-C', workspacePath, 'status', '--porcelain']);
76
108
  const dirtyCount = status === null || status === '' ? 0 : status.split('\n').filter(Boolean).length;
77
109
  return ['Git context:', `branch: ${branch}`, `dirty: ${dirtyCount === 0 ? 'false' : `${dirtyCount} files`}`].join(
78
110
  '\n',
79
111
  );
80
112
  }
81
113
 
82
- function runGit(executor: SyncProcessExecutor, args: string[]): string | null {
114
+ async function runGit(executor: ProcessExecutor, args: string[]): Promise<string | null> {
115
+ const result = await executor.run({ command: 'git', args, rejectOnError: false, forceBuffered: true });
116
+ if (result.exitCode !== 0) return null;
117
+ return result.stdout.trim();
118
+ }
119
+
120
+ function runGitSync(executor: SyncProcessExecutor, args: string[]): string | null {
83
121
  const result = executor.runSync({ command: 'git', args, rejectOnError: false, forceBuffered: true });
84
122
  if (result.exitCode !== 0) return null;
85
123
  return result.stdout.trim();
@@ -25,7 +25,7 @@ export interface DrainedMessage {
25
25
  */
26
26
  export interface MessageStore {
27
27
  enqueue(fromId: string | null, toId: string, body: string, inReplyTo?: string): Promise<string>;
28
- drainPending(toId: string): Promise<DrainedMessage[]>;
28
+ drainPending(toId: string, options?: { limit?: number }): Promise<DrainedMessage[]>;
29
29
  markDelivered(msgId: string): Promise<void>;
30
30
  markFailed(msgId: string, error: string): Promise<void>;
31
31
  }
@@ -84,6 +84,7 @@ export class TeamOrchestrator {
84
84
  agentId: spec.id,
85
85
  agentType: spec.type,
86
86
  pid: process.getPid(),
87
+ severity: 'info',
87
88
  });
88
89
  return process;
89
90
  }
@@ -93,7 +94,12 @@ export class TeamOrchestrator {
93
94
  if (process === undefined) return;
94
95
  await process.stop();
95
96
  this.running.delete(id);
96
- void this.events.emit('agent.stopped', { agentId: id, exitCode: process.getExitCode() });
97
+ const exitCode = process.getExitCode();
98
+ void this.events.emit('agent.stopped', {
99
+ agentId: id,
100
+ exitCode,
101
+ severity: exitCode === 0 || exitCode === null ? 'info' : 'warning',
102
+ });
97
103
  }
98
104
 
99
105
  async restartAgent(id: string): Promise<TeamAgentProcess> {
@@ -105,7 +111,7 @@ export class TeamOrchestrator {
105
111
  const msgId = await this.inbox.enqueue(fromId, toId, body, inReplyTo);
106
112
  const process = this.running.get(toId);
107
113
  const ok = process !== undefined ? await this.flushInbox(process, 'live stdin injection failed') : false;
108
- void this.events.emit('agent.message.sent', { agentId: toId, ok });
114
+ void this.events.emit('agent.message.sent', { agentId: toId, ok, severity: ok ? 'info' : 'warning' });
109
115
  return msgId;
110
116
  }
111
117
 
@@ -150,15 +156,21 @@ export class TeamOrchestrator {
150
156
  }
151
157
 
152
158
  private async flushInbox(process: TeamAgentProcess, failLabel: string): Promise<boolean> {
153
- const messages = await this.inbox.drainPending(process.agentId);
159
+ // Drain in pages (default 100 per drainPending — task 0060 F10) until a short page,
160
+ // so a backed-up inbox is fully flushed without one giant claim.
154
161
  let ok = true;
155
- for (const message of messages) {
156
- const result = await process.send(formatMessage(message));
157
- if (result.ok) await this.inbox.markDelivered(message.id);
158
- else {
159
- ok = false;
160
- await this.inbox.markFailed(message.id, failLabel);
162
+ for (;;) {
163
+ const messages = await this.inbox.drainPending(process.agentId);
164
+ if (messages.length === 0) break;
165
+ for (const message of messages) {
166
+ const result = await process.send(formatMessage(message));
167
+ if (result.ok) await this.inbox.markDelivered(message.id);
168
+ else {
169
+ ok = false;
170
+ await this.inbox.markFailed(message.id, failLabel);
171
+ }
161
172
  }
173
+ if (messages.length < 100) break;
162
174
  }
163
175
  return ok;
164
176
  }