@pikiloom/kernel 0.2.9 → 0.2.10

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.
@@ -137,6 +137,9 @@ function codexFileChangeSummary(item) {
137
137
  // fallback to `item.type` wrongly turned every item (incl. agentMessage/reasoning) into a bogus
138
138
  // "tool" in the Activity card. Mirrors the legacy driver's isCodexToolCallItem whitelist.
139
139
  const CODEX_TOOL_CALL_TYPES = new Set(['dynamicToolCall', 'mcpToolCall', 'collabAgentToolCall']);
140
+ // Field-less placeholder summaries — a completed item with only one of these never overrides
141
+ // a more specific summary cached at item/started.
142
+ const CODEX_GENERIC_TOOL_SUMMARIES = new Set(['Search web', 'Run shell command', 'Edit files', 'Use tool']);
140
143
  export function codexToolSummary(item) {
141
144
  const id = String(item?.id || '');
142
145
  if (!id)
@@ -147,6 +150,20 @@ export function codexToolSummary(item) {
147
150
  }
148
151
  if (item.type === 'fileChange' || item.type === 'patch')
149
152
  return { id, name: 'edit', summary: codexFileChangeSummary(item) };
153
+ if (item.type === 'webSearch') {
154
+ // v2 webSearch items carry the query at top level and (on newer servers) an action
155
+ // (search / openPage / findInPage, snake_case on older ones). The query is often only
156
+ // known at item/completed — item/started may arrive query-less.
157
+ const action = item.action || {};
158
+ const kind = String(action.type || '');
159
+ const url = codexCommandPreview(action.url);
160
+ if ((kind === 'openPage' || kind === 'open_page') && url)
161
+ return { id, name: 'web_search', summary: `Open ${url}` };
162
+ if ((kind === 'findInPage' || kind === 'find_in_page') && url)
163
+ return { id, name: 'web_search', summary: `Find in ${url}` };
164
+ const query = codexCommandPreview(typeof item.query === 'string' && item.query.trim() ? item.query : action.query);
165
+ return { id, name: 'web_search', summary: query ? `Search web: ${query}` : 'Search web' };
166
+ }
150
167
  if (CODEX_TOOL_CALL_TYPES.has(item.type)) {
151
168
  const raw = typeof item.tool === 'string' && item.tool.trim() ? item.tool.trim()
152
169
  : typeof item.name === 'string' && item.name.trim() ? item.name.trim() : '';
@@ -343,8 +360,14 @@ export class CodexDriver {
343
360
  else if (item.type === 'reasoning')
344
361
  captureCodexReasoning(codexReasoningItemText(item), state, ctx.emit);
345
362
  const t = codexToolSummary(item);
346
- if (t && toolSummaries.has(t.id))
347
- ctx.emit({ type: 'tool', call: { id: t.id, name: t.name, summary: toolSummaries.get(t.id) || t.summary, status: item.status === 'failed' ? 'failed' : 'done' } });
363
+ if (t) {
364
+ // Prefer the completed item's summary when it is specific webSearch carries its
365
+ // query only at completion (item/started may be query-less or absent entirely,
366
+ // so no `toolSummaries.has` gate: a completed-only tool still gets its row).
367
+ const summary = !CODEX_GENERIC_TOOL_SUMMARIES.has(t.summary) ? t.summary : (toolSummaries.get(t.id) || t.summary);
368
+ toolSummaries.set(t.id, summary);
369
+ ctx.emit({ type: 'tool', call: { id: t.id, name: t.name, summary, status: item.status === 'failed' ? 'failed' : 'done' } });
370
+ }
348
371
  break;
349
372
  }
350
373
  case 'rawResponseItem/completed': {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pikiloom/kernel",
3
- "version": "0.2.9",
3
+ "version": "0.2.10",
4
4
  "description": "Heterogeneous coding agents (Claude / Codex / Gemini / ACP) -> an interaction-friendly, accumulating session snapshot + control handle, over pluggable surfaces (IM, Web, tunnel, TUI). The reusable core pikiloom itself is built on.",
5
5
  "type": "module",
6
6
  "license": "MIT",