@pikiloom/kernel 0.2.16 → 0.2.17
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/dist/drivers/claude.d.ts +1 -0
- package/dist/drivers/claude.js +56 -7
- package/package.json +1 -1
package/dist/drivers/claude.d.ts
CHANGED
|
@@ -57,6 +57,7 @@ export declare function emitClaudeImages(blocks: any[], s: any, emit: (e: Driver
|
|
|
57
57
|
export declare function todoWriteToPlan(input: any): UniversalPlan | null;
|
|
58
58
|
export declare function readClaudeTaskCreateId(ev: any, block: any): string | null;
|
|
59
59
|
export declare function rebuildClaudeTaskPlan(s: any): UniversalPlan | null;
|
|
60
|
+
export declare function applyTaskUpdateToTodoPlan(plan: UniversalPlan | null | undefined, taskId: string, rawStatus: string): UniversalPlan | null;
|
|
60
61
|
export declare function shortToolValue(value: unknown, max?: number): string;
|
|
61
62
|
export declare function summarizeToolUse(name: string, input: any): string;
|
|
62
63
|
export declare function firstResultLine(content: any): string;
|
package/dist/drivers/claude.js
CHANGED
|
@@ -531,29 +531,41 @@ export function handleClaudeEvent(ev, s, emit) {
|
|
|
531
531
|
const name = String(b.name || 'Tool');
|
|
532
532
|
if (name === 'TodoWrite') {
|
|
533
533
|
const plan = todoWriteToPlan(b.input);
|
|
534
|
-
if (plan)
|
|
534
|
+
if (plan) {
|
|
535
|
+
s.todoPlan = plan;
|
|
535
536
|
emit({ type: 'plan', plan });
|
|
537
|
+
}
|
|
538
|
+
const summary = 'Update plan';
|
|
539
|
+
(s.tools ||= new Map()).set(id, { name, summary });
|
|
540
|
+
emit({ type: 'tool', call: { id, name, summary, input: null, status: 'running' } });
|
|
536
541
|
continue;
|
|
537
542
|
}
|
|
538
543
|
// Task list (current Claude mechanism): stash the subject; the tool_result assigns the id.
|
|
539
|
-
//
|
|
544
|
+
// The command surfaces as an Activity row (matching the CLI's own transcript); the
|
|
545
|
+
// structured task state still flows through plan events.
|
|
540
546
|
if (name === 'TaskCreate') {
|
|
541
547
|
const subject = typeof b.input?.subject === 'string' ? b.input.subject.trim() : '';
|
|
542
548
|
if (subject)
|
|
543
549
|
(s.pendingTaskCreates ||= new Map()).set(id, { subject });
|
|
550
|
+
const summary = subject ? `Create task: ${subject}` : 'Create task';
|
|
551
|
+
(s.tools ||= new Map()).set(id, { name, summary });
|
|
552
|
+
emit({ type: 'tool', call: { id, name, summary, input: null, status: 'running' } });
|
|
544
553
|
continue;
|
|
545
554
|
}
|
|
546
555
|
if (name === 'TaskUpdate') {
|
|
547
556
|
const taskId = String(b.input?.taskId ?? '').trim();
|
|
548
557
|
const rawStatus = String(b.input?.status ?? '').trim().toLowerCase();
|
|
549
|
-
|
|
558
|
+
// Chronological: the plan reflects the state AFTER this update. An id known to the
|
|
559
|
+
// TaskCreate store lands there; otherwise it lands positionally on the latest
|
|
560
|
+
// TodoWrite list (ids are 1-based positions when the todo panel owns the list).
|
|
561
|
+
if (taskId && s.taskList?.has(taskId)) {
|
|
550
562
|
if (rawStatus === 'deleted') {
|
|
551
|
-
s.taskList
|
|
563
|
+
s.taskList.delete(taskId);
|
|
552
564
|
if (Array.isArray(s.taskOrder))
|
|
553
565
|
s.taskOrder = s.taskOrder.filter((x) => x !== taskId);
|
|
554
566
|
}
|
|
555
567
|
else if (rawStatus) {
|
|
556
|
-
const existing = s.taskList
|
|
568
|
+
const existing = s.taskList.get(taskId);
|
|
557
569
|
if (existing)
|
|
558
570
|
existing.status = rawStatus;
|
|
559
571
|
}
|
|
@@ -561,6 +573,16 @@ export function handleClaudeEvent(ev, s, emit) {
|
|
|
561
573
|
if (plan)
|
|
562
574
|
emit({ type: 'plan', plan });
|
|
563
575
|
}
|
|
576
|
+
else if (taskId) {
|
|
577
|
+
const updated = applyTaskUpdateToTodoPlan(s.todoPlan, taskId, rawStatus);
|
|
578
|
+
if (updated) {
|
|
579
|
+
s.todoPlan = updated;
|
|
580
|
+
emit({ type: 'plan', plan: updated });
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
const summary = `Update task ${taskId || '?'} → ${rawStatus || 'unknown'}`;
|
|
584
|
+
(s.tools ||= new Map()).set(id, { name, summary });
|
|
585
|
+
emit({ type: 'tool', call: { id, name, summary, input: null, status: 'running' } });
|
|
564
586
|
continue;
|
|
565
587
|
}
|
|
566
588
|
if (name === 'Task' || name === 'Agent') {
|
|
@@ -641,13 +663,16 @@ export function handleClaudeEvent(ev, s, emit) {
|
|
|
641
663
|
if (plan)
|
|
642
664
|
emit({ type: 'plan', plan });
|
|
643
665
|
}
|
|
666
|
+
if (tool)
|
|
667
|
+
emit({ type: 'tool', call: { id, name: tool.name, summary: tool.summary, status: b.is_error ? 'failed' : 'done', result: null } });
|
|
644
668
|
continue;
|
|
645
669
|
}
|
|
646
670
|
if (!tool)
|
|
647
671
|
continue;
|
|
648
672
|
const isError = !!b.is_error;
|
|
649
|
-
// File-shaped tools have no useful result detail (mirrors pikiloom): just mark done.
|
|
650
|
-
const fileTool = tool.name === 'Read' || tool.name === 'Edit' || tool.name === 'Write'
|
|
673
|
+
// File-shaped and task-list tools have no useful result detail (mirrors pikiloom): just mark done.
|
|
674
|
+
const fileTool = tool.name === 'Read' || tool.name === 'Edit' || tool.name === 'Write'
|
|
675
|
+
|| tool.name === 'TodoWrite' || tool.name === 'TaskCreate' || tool.name === 'TaskUpdate';
|
|
651
676
|
const detail = (isError || !fileTool) ? firstResultLine(b.content) : null;
|
|
652
677
|
emit({ type: 'tool', call: { id, name: tool.name, summary: tool.summary, status: isError ? 'failed' : 'done', result: detail || null } });
|
|
653
678
|
}
|
|
@@ -960,6 +985,30 @@ export function rebuildClaudeTaskPlan(s) {
|
|
|
960
985
|
}
|
|
961
986
|
return steps.length ? { explanation: null, steps } : null;
|
|
962
987
|
}
|
|
988
|
+
// Apply a TaskUpdate to a TodoWrite-produced plan positionally (taskId = 1-based item index).
|
|
989
|
+
// Used when the id isn't in the TaskCreate store, so an update issued AFTER a TodoWrite still
|
|
990
|
+
// lands on the displayed list — the plan reflects the state after the LAST change, whichever
|
|
991
|
+
// mechanism wrote it. Returns a fresh plan (never mutates) or null when inapplicable.
|
|
992
|
+
export function applyTaskUpdateToTodoPlan(plan, taskId, rawStatus) {
|
|
993
|
+
if (!plan || !Array.isArray(plan.steps) || !plan.steps.length)
|
|
994
|
+
return null;
|
|
995
|
+
if (!/^\d+$/.test(taskId))
|
|
996
|
+
return null;
|
|
997
|
+
const idx = Number(taskId) - 1;
|
|
998
|
+
if (idx < 0 || idx >= plan.steps.length)
|
|
999
|
+
return null;
|
|
1000
|
+
if (rawStatus === 'deleted') {
|
|
1001
|
+
const steps = plan.steps.filter((_, i) => i !== idx);
|
|
1002
|
+
return steps.length ? { explanation: plan.explanation ?? null, steps } : null;
|
|
1003
|
+
}
|
|
1004
|
+
const status = rawStatus === 'completed' ? 'completed'
|
|
1005
|
+
: (rawStatus === 'in_progress' || rawStatus === 'inprogress') ? 'inProgress'
|
|
1006
|
+
: rawStatus === 'pending' ? 'pending' : null;
|
|
1007
|
+
if (!status)
|
|
1008
|
+
return null;
|
|
1009
|
+
const steps = plan.steps.map((step, i) => i === idx ? { ...step, status } : step);
|
|
1010
|
+
return { explanation: plan.explanation ?? null, steps };
|
|
1011
|
+
}
|
|
963
1012
|
// ── Tool-call summarization (ported from pikiloom's summarizeClaudeToolUse) ──────────
|
|
964
1013
|
// Turns a Claude tool_use {name,input} into a one-line human summary. The runtime's
|
|
965
1014
|
// activity projector joins these into snapshot.activity; the structured form lives in
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pikiloom/kernel",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.17",
|
|
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",
|