Skip to content

Commit e78747a

Browse files
committed
fix(cli-plugin-copilot): narrow JsonValue before reading tool-call arg properties
@github/copilot-sdk's tool-call arguments are typed JsonValue (a union including primitives/arrays), so accessing .url/.path/.load/.selector directly no longer type-checks and was breaking the build on main.
1 parent 02d88e6 commit e78747a

2 files changed

Lines changed: 22 additions & 2 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@equinor/fusion-framework-cli-plugin-copilot": patch
3+
---
4+
5+
Fix a build failure caused by `@github/copilot-sdk`'s stricter `JsonValue` typing on tool-call `arguments`. Tool-call detail extraction (`url`/`path`/`load`/`selector`) now narrows the union type before reading properties instead of relying on unchecked optional chaining.

packages/cli-plugins/copilot/src/commands/app/attach-session-logger.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,25 @@
11
import chalk from 'chalk';
22
import ora from 'ora';
33

4-
import type { CopilotSession } from '@github/copilot-sdk';
4+
import type { CopilotSession, JsonValue } from '@github/copilot-sdk';
55

66
import { tryFormatMessage } from './try-format-message.js';
77

8+
// Tool arguments are untyped JSON; narrow to the object branch before reading known keys.
9+
function firstStringProp(value: JsonValue | undefined, keys: string[]): string | undefined {
10+
// Primitives and arrays have no named properties to read
11+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
12+
return undefined;
13+
}
14+
// Return the first key present with a string value, in caller-specified priority order
15+
for (const key of keys) {
16+
const prop = value[key];
17+
// Skip non-string values (numbers, nested objects, etc.) rather than stringifying them
18+
if (typeof prop === 'string') return prop;
19+
}
20+
return undefined;
21+
}
22+
823
const TOOL_ICONS: Record<string, string> = {
924
browser_screenshot: '📷',
1025
browser_navigate: '🌐',
@@ -69,7 +84,7 @@ export function attachSessionLogger(
6984
switch (event.type) {
7085
case 'tool.execution_start': {
7186
const { toolCallId, toolName, arguments: args } = event.data;
72-
const detail = args?.url ?? args?.path ?? args?.load ?? args?.selector;
87+
const detail = firstStringProp(args, ['url', 'path', 'load', 'selector']);
7388
const icon = TOOL_ICONS[toolName] ?? '🔧';
7489
const label =
7590
typeof detail === 'string' ? `${icon} ${toolName} (${detail})` : `${icon} ${toolName}`;

0 commit comments

Comments
 (0)