opencode-subagents-sidebar-plugin 0.1.2 → 0.1.3

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
@@ -4,9 +4,15 @@ An OpenCode 1.17.15+ TUI-only plugin that adds a **Subagents** section to the
4
4
  sidebar footer. It shows pending and running task subagents for the current
5
5
  parent session (or when viewing one of its child sessions).
6
6
 
7
- Each subagent uses a compact two-line card: status and role with its model,
8
- then its newest meaningful activity with elapsed runtime. Completed tasks are
9
- hidden.
7
+ Each subagent uses a compact two-line card: its role with model and raw
8
+ effort/reasoning variant, then its assigned task description with a
9
+ right-aligned elapsed runtime. Cards intentionally do not show status glyphs
10
+ or live transcript/activity text. Click anywhere on a card to open a live
11
+ details popup with status, foreground/background mode, child session ID, and
12
+ model details. The popup's **Open Session** action is available once the child
13
+ session exists (unless it is already open); **Close** dismisses the popup.
14
+ Completed tasks are hidden unless OpenCode still reports their background child
15
+ session as active.
10
16
 
11
17
  ## Install
12
18
 
@@ -1,6 +1,2 @@
1
- import type { Part } from "@opencode-ai/sdk/v2";
2
- export declare function normalizeActivity(value: string): string;
3
- export declare function normalizeMeaningful(value: unknown): string | undefined;
4
- export declare function activityForPart(part: Part): string | undefined;
5
1
  export declare function elapsedLabel(milliseconds: number): string;
6
2
  //# sourceMappingURL=activity.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../src/activity.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAM/C,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMvD;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAGtE;AASD,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,CAe9D;AAED,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAQzD"}
1
+ {"version":3,"file":"activity.d.ts","sourceRoot":"","sources":["../src/activity.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAQzD"}
package/dist/activity.js CHANGED
@@ -1,31 +1,3 @@
1
- function stringValue(value) {
2
- return typeof value === "string" && value.trim() ? value.trim() : undefined;
3
- }
4
- export function normalizeActivity(value) {
5
- return value.replace(/\s+/g, " ").replace(/^[#>*_`\-\s]+/, "").replace(/[*_`]/g, "").trim();
6
- }
7
- export function normalizeMeaningful(value) {
8
- const text = stringValue(value);
9
- return text ? stringValue(normalizeActivity(text)) : undefined;
10
- }
11
- function toolName(value) {
12
- return value.replace(/^multi_tool_use\./, "").replace(/[._-]+/g, " ").replace(/\b\w/g, character => character.toUpperCase());
13
- }
14
- export function activityForPart(part) {
15
- if (part.type === "text" || part.type === "reasoning") return normalizeMeaningful(part.text);
16
- if (part.type === "subtask") {
17
- const description = normalizeMeaningful(part.description);
18
- return description ? `Delegating · ${description}` : "Delegating";
19
- }
20
- if (part.type === "retry") return `Retrying · attempt ${part.attempt}`;
21
- if (part.type === "compaction") return "Compacting context…";
22
- if (part.type !== "tool") return undefined;
23
- const name = toolName(part.tool);
24
- if (part.state.status === "pending") return `${name}…`;
25
- if (part.state.status === "error") return `${name} failed`;
26
- const title = normalizeMeaningful(part.state.title);
27
- return title ? `${name} · ${title}` : `${name}…`;
28
- }
29
1
  export function elapsedLabel(milliseconds) {
30
2
  const seconds = Math.max(0, Math.floor(milliseconds / 1_000));
31
3
  if (seconds < 60) return `${seconds}s`;
@@ -1 +1 @@
1
- {"version":3,"file":"activity.js","names":["stringValue","value","trim","undefined","normalizeActivity","replace","normalizeMeaningful","text","toolName","character","toUpperCase","activityForPart","part","type","description","attempt","name","tool","state","status","title","elapsedLabel","milliseconds","seconds","Math","max","floor","minutes","hours"],"sources":["../src/activity.ts"],"sourcesContent":["import type { Part } from \"@opencode-ai/sdk/v2\"\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined\n}\n\nexport function normalizeActivity(value: string): string {\n return value\n .replace(/\\s+/g, \" \")\n .replace(/^[#>*_`\\-\\s]+/, \"\")\n .replace(/[*_`]/g, \"\")\n .trim()\n}\n\nexport function normalizeMeaningful(value: unknown): string | undefined {\n const text = stringValue(value)\n return text ? stringValue(normalizeActivity(text)) : undefined\n}\n\nfunction toolName(value: string): string {\n return value\n .replace(/^multi_tool_use\\./, \"\")\n .replace(/[._-]+/g, \" \")\n .replace(/\\b\\w/g, (character) => character.toUpperCase())\n}\n\nexport function activityForPart(part: Part): string | undefined {\n if (part.type === \"text\" || part.type === \"reasoning\") return normalizeMeaningful(part.text)\n if (part.type === \"subtask\") {\n const description = normalizeMeaningful(part.description)\n return description ? `Delegating · ${description}` : \"Delegating\"\n }\n if (part.type === \"retry\") return `Retrying · attempt ${part.attempt}`\n if (part.type === \"compaction\") return \"Compacting context…\"\n if (part.type !== \"tool\") return undefined\n\n const name = toolName(part.tool)\n if (part.state.status === \"pending\") return `${name}…`\n if (part.state.status === \"error\") return `${name} failed`\n const title = normalizeMeaningful(part.state.title)\n return title ? `${name} · ${title}` : `${name}…`\n}\n\nexport function elapsedLabel(milliseconds: number): string {\n const seconds = Math.max(0, Math.floor(milliseconds / 1_000))\n if (seconds < 60) return `${seconds}s`\n const minutes = Math.floor(seconds / 60)\n if (minutes < 60) return `${minutes}m ${seconds % 60}s`\n const hours = Math.floor(minutes / 60)\n if (hours < 24) return `${hours}h ${minutes % 60}m`\n return `${Math.floor(hours / 24)}d ${hours % 24}h`\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"activity.js","names":["elapsedLabel","milliseconds","seconds","Math","max","floor","minutes","hours"],"sources":["../src/activity.ts"],"sourcesContent":["export function elapsedLabel(milliseconds: number): string {\n const seconds = Math.max(0, Math.floor(milliseconds / 1_000))\n if (seconds < 60) return `${seconds}s`\n const minutes = Math.floor(seconds / 60)\n if (minutes < 60) return `${minutes}m ${seconds % 60}s`\n const hours = Math.floor(minutes / 60)\n if (hours < 24) return `${hours}h ${minutes % 60}m`\n return `${Math.floor(hours / 24)}d ${hours % 24}h`\n}\n"],"mappings":"AAAA,OAAO,SAASA,YAAYA,CAACC,YAAoB,EAAU;EACzD,MAAMC,OAAO,GAAGC,IAAI,CAACC,GAAG,CAAC,CAAC,EAAED,IAAI,CAACE,KAAK,CAACJ,YAAY,GAAG,KAAK,CAAC,CAAC;EAC7D,IAAIC,OAAO,GAAG,EAAE,EAAE,OAAO,GAAGA,OAAO,GAAG;EACtC,MAAMI,OAAO,GAAGH,IAAI,CAACE,KAAK,CAACH,OAAO,GAAG,EAAE,CAAC;EACxC,IAAII,OAAO,GAAG,EAAE,EAAE,OAAO,GAAGA,OAAO,KAAKJ,OAAO,GAAG,EAAE,GAAG;EACvD,MAAMK,KAAK,GAAGJ,IAAI,CAACE,KAAK,CAACC,OAAO,GAAG,EAAE,CAAC;EACtC,IAAIC,KAAK,GAAG,EAAE,EAAE,OAAO,GAAGA,KAAK,KAAKD,OAAO,GAAG,EAAE,GAAG;EACnD,OAAO,GAAGH,IAAI,CAACE,KAAK,CAACE,KAAK,GAAG,EAAE,CAAC,KAAKA,KAAK,GAAG,EAAE,GAAG;AACpD","ignoreList":[]}
package/dist/tasks.d.ts CHANGED
@@ -1,5 +1,20 @@
1
- import type { Part, SessionStatus, ToolPart } from "@opencode-ai/sdk/v2";
1
+ import type { Message, Part, Session, SessionStatus, ToolPart } from "@opencode-ai/sdk/v2";
2
2
  export type VisibleTaskPart = ToolPart;
3
+ export type TaskModel = {
4
+ providerID: string;
5
+ modelID: string;
6
+ variant?: string;
7
+ };
8
+ export declare function normalizeTaskDescription(value: unknown): string | undefined;
3
9
  export declare function taskSessionID(part: ToolPart): string | undefined;
10
+ export declare function taskAgent(part: VisibleTaskPart): string;
11
+ export declare function taskDescription(part: VisibleTaskPart): string;
12
+ export declare function resolveTaskModel(part: VisibleTaskPart, childSession: Session | undefined, childMessages: ReadonlyArray<Message>): TaskModel | undefined;
13
+ export declare function taskModelLabel(model: TaskModel | undefined, displayName?: string): string;
14
+ export declare function taskVariantLabel(model: TaskModel | undefined): string | undefined;
15
+ export declare function taskStatusLabel(part: VisibleTaskPart, childStatus?: SessionStatus): string;
16
+ export declare function taskModeLabel(part: VisibleTaskPart): "Foreground" | "Background";
17
+ export declare function canOpenTaskSession(sessionID: string | undefined, currentSessionID: string): boolean;
18
+ export declare function isTaskPart(part: Part): part is VisibleTaskPart;
4
19
  export declare function isVisibleTask(part: Part, sessionStatus: (sessionID: string) => SessionStatus | undefined): part is VisibleTaskPart;
5
20
  //# sourceMappingURL=tasks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../src/tasks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAExE,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAA;AAUtC,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,SAAS,CAGhE;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,aAAa,GAAG,SAAS,GAC9D,IAAI,IAAI,eAAe,CASzB"}
1
+ {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../src/tasks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AAE1F,MAAM,MAAM,eAAe,GAAG,QAAQ,CAAA;AAEtC,MAAM,MAAM,SAAS,GAAG;IACtB,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AAcD,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAO3E;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,SAAS,CAGhE;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,CAEvD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,CAE7D;AAgCD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,eAAe,EACrB,YAAY,EAAE,OAAO,GAAG,SAAS,EACjC,aAAa,EAAE,aAAa,CAAC,OAAO,CAAC,GACpC,SAAS,GAAG,SAAS,CAYvB;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAGzF;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAEjF;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,EAAE,WAAW,CAAC,EAAE,aAAa,GAAG,MAAM,CAM1F;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,eAAe,GAAG,YAAY,GAAG,YAAY,CAEhF;AAED,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,EAAE,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAEnG;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,IAAI,eAAe,CAE9D;AAED,wBAAgB,aAAa,CAC3B,IAAI,EAAE,IAAI,EACV,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,aAAa,GAAG,SAAS,GAC9D,IAAI,IAAI,eAAe,CASzB"}
package/dist/tasks.js CHANGED
@@ -1,18 +1,106 @@
1
1
  function objectValue(value) {
2
2
  return value && typeof value === "object" && !Array.isArray(value) ? value : {};
3
3
  }
4
+ function stringValue(value) {
5
+ return typeof value === "string" && value.trim() ? value.trim() : undefined;
6
+ }
4
7
  function taskMetadata(part) {
5
8
  return {
6
9
  ...objectValue(part.metadata),
7
10
  ...objectValue(objectValue(part.state).metadata)
8
11
  };
9
12
  }
13
+ export function normalizeTaskDescription(value) {
14
+ const text = stringValue(value);
15
+ return text?.replace(/\s+/g, " ").replace(/^[#>*_`\-\s]+/, "").replace(/[*_`]/g, "").trim() || undefined;
16
+ }
10
17
  export function taskSessionID(part) {
11
18
  const sessionID = taskMetadata(part).sessionId;
12
- return typeof sessionID === "string" && sessionID.trim() ? sessionID.trim() : undefined;
19
+ return stringValue(sessionID);
20
+ }
21
+ export function taskAgent(part) {
22
+ return stringValue(part.state.input.subagent_type) ?? "subagent";
23
+ }
24
+ export function taskDescription(part) {
25
+ return normalizeTaskDescription(part.state.input.description) ?? normalizeTaskDescription(objectValue(part.state).title) ?? "Working";
26
+ }
27
+ function taskMetadataModel(part) {
28
+ const model = objectValue(taskMetadata(part).model);
29
+ const providerID = stringValue(model.providerID);
30
+ const modelID = stringValue(model.modelID);
31
+ // Task metadata is created before the child chooses a model variant. Do not
32
+ // invent or retain a variant from this startup-only fallback.
33
+ return providerID && modelID ? {
34
+ providerID,
35
+ modelID
36
+ } : undefined;
37
+ }
38
+ function childSessionModel(session) {
39
+ const providerID = stringValue(session?.model?.providerID);
40
+ const modelID = stringValue(session?.model?.id);
41
+ const variant = stringValue(session?.model?.variant);
42
+ return providerID && modelID ? {
43
+ providerID,
44
+ modelID,
45
+ variant: variant ?? "default"
46
+ } : undefined;
47
+ }
48
+ function childMessageModel(message) {
49
+ if (message.role === "user") {
50
+ const providerID = stringValue(message.model.providerID);
51
+ const modelID = stringValue(message.model.modelID);
52
+ const variant = stringValue(message.model.variant);
53
+ return providerID && modelID ? {
54
+ providerID,
55
+ modelID,
56
+ variant: variant ?? "default"
57
+ } : undefined;
58
+ }
59
+ const providerID = stringValue(message.providerID);
60
+ const modelID = stringValue(message.modelID);
61
+ const variant = stringValue(message.variant);
62
+ return providerID && modelID ? {
63
+ providerID,
64
+ modelID,
65
+ variant: variant ?? "default"
66
+ } : undefined;
67
+ }
68
+ export function resolveTaskModel(part, childSession, childMessages) {
69
+ const sessionModel = childSessionModel(childSession);
70
+ if (sessionModel) return sessionModel;
71
+ for (let index = childMessages.length - 1; index >= 0; index -= 1) {
72
+ const message = childMessages[index];
73
+ if (!message) continue;
74
+ const messageModel = childMessageModel(message);
75
+ if (messageModel) return messageModel;
76
+ }
77
+ return taskMetadataModel(part);
78
+ }
79
+ export function taskModelLabel(model, displayName) {
80
+ if (!model) return "starting…";
81
+ return stringValue(displayName) ?? model.modelID;
82
+ }
83
+ export function taskVariantLabel(model) {
84
+ return model?.variant;
85
+ }
86
+ export function taskStatusLabel(part, childStatus) {
87
+ if (part.state.status === "completed" && childStatus && childStatus.type !== "idle") return "Running";
88
+ if (part.state.status === "pending") return "Pending";
89
+ if (part.state.status === "running") return "Running";
90
+ if (part.state.status === "completed") return "Completed";
91
+ return "Failed";
92
+ }
93
+ export function taskModeLabel(part) {
94
+ return taskMetadata(part).background === true ? "Background" : "Foreground";
95
+ }
96
+ export function canOpenTaskSession(sessionID, currentSessionID) {
97
+ return Boolean(sessionID && sessionID !== currentSessionID);
98
+ }
99
+ export function isTaskPart(part) {
100
+ return part.type === "tool" && part.tool === "task";
13
101
  }
14
102
  export function isVisibleTask(part, sessionStatus) {
15
- if (part.type !== "tool" || part.tool !== "task") return false;
103
+ if (!isTaskPart(part)) return false;
16
104
  if (part.state.status === "pending" || part.state.status === "running") return true;
17
105
  if (part.state.status !== "completed" || taskMetadata(part).background !== true) return false;
18
106
  const childSessionID = taskSessionID(part);
package/dist/tasks.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"tasks.js","names":["objectValue","value","Array","isArray","taskMetadata","part","metadata","state","taskSessionID","sessionID","sessionId","trim","undefined","isVisibleTask","sessionStatus","type","tool","status","background","childSessionID"],"sources":["../src/tasks.ts"],"sourcesContent":["import type { Part, SessionStatus, ToolPart } from \"@opencode-ai/sdk/v2\"\n\nexport type VisibleTaskPart = ToolPart\n\nfunction objectValue(value: unknown): Record<string, unknown> {\n return value && typeof value === \"object\" && !Array.isArray(value) ? (value as Record<string, unknown>) : {}\n}\n\nfunction taskMetadata(part: ToolPart): Record<string, unknown> {\n return { ...objectValue(part.metadata), ...objectValue(objectValue(part.state).metadata) }\n}\n\nexport function taskSessionID(part: ToolPart): string | undefined {\n const sessionID = taskMetadata(part).sessionId\n return typeof sessionID === \"string\" && sessionID.trim() ? sessionID.trim() : undefined\n}\n\nexport function isVisibleTask(\n part: Part,\n sessionStatus: (sessionID: string) => SessionStatus | undefined,\n): part is VisibleTaskPart {\n if (part.type !== \"tool\" || part.tool !== \"task\") return false\n if (part.state.status === \"pending\" || part.state.status === \"running\") return true\n if (part.state.status !== \"completed\" || taskMetadata(part).background !== true) return false\n\n const childSessionID = taskSessionID(part)\n if (!childSessionID) return false\n const status = sessionStatus(childSessionID)\n return status !== undefined && status.type !== \"idle\"\n}\n"],"mappings":"AAIA,SAASA,WAAWA,CAACC,KAAc,EAA2B;EAC5D,OAAOA,KAAK,IAAI,OAAOA,KAAK,KAAK,QAAQ,IAAI,CAACC,KAAK,CAACC,OAAO,CAACF,KAAK,CAAC,GAAIA,KAAK,GAA+B,CAAC,CAAC;AAC9G;AAEA,SAASG,YAAYA,CAACC,IAAc,EAA2B;EAC7D,OAAO;IAAE,GAAGL,WAAW,CAACK,IAAI,CAACC,QAAQ,CAAC;IAAE,GAAGN,WAAW,CAACA,WAAW,CAACK,IAAI,CAACE,KAAK,CAAC,CAACD,QAAQ;EAAE,CAAC;AAC5F;AAEA,OAAO,SAASE,aAAaA,CAACH,IAAc,EAAsB;EAChE,MAAMI,SAAS,GAAGL,YAAY,CAACC,IAAI,CAAC,CAACK,SAAS;EAC9C,OAAO,OAAOD,SAAS,KAAK,QAAQ,IAAIA,SAAS,CAACE,IAAI,CAAC,CAAC,GAAGF,SAAS,CAACE,IAAI,CAAC,CAAC,GAAGC,SAAS;AACzF;AAEA,OAAO,SAASC,aAAaA,CAC3BR,IAAU,EACVS,aAA+D,EACtC;EACzB,IAAIT,IAAI,CAACU,IAAI,KAAK,MAAM,IAAIV,IAAI,CAACW,IAAI,KAAK,MAAM,EAAE,OAAO,KAAK;EAC9D,IAAIX,IAAI,CAACE,KAAK,CAACU,MAAM,KAAK,SAAS,IAAIZ,IAAI,CAACE,KAAK,CAACU,MAAM,KAAK,SAAS,EAAE,OAAO,IAAI;EACnF,IAAIZ,IAAI,CAACE,KAAK,CAACU,MAAM,KAAK,WAAW,IAAIb,YAAY,CAACC,IAAI,CAAC,CAACa,UAAU,KAAK,IAAI,EAAE,OAAO,KAAK;EAE7F,MAAMC,cAAc,GAAGX,aAAa,CAACH,IAAI,CAAC;EAC1C,IAAI,CAACc,cAAc,EAAE,OAAO,KAAK;EACjC,MAAMF,MAAM,GAAGH,aAAa,CAACK,cAAc,CAAC;EAC5C,OAAOF,MAAM,KAAKL,SAAS,IAAIK,MAAM,CAACF,IAAI,KAAK,MAAM;AACvD","ignoreList":[]}
1
+ {"version":3,"file":"tasks.js","names":["objectValue","value","Array","isArray","stringValue","trim","undefined","taskMetadata","part","metadata","state","normalizeTaskDescription","text","replace","taskSessionID","sessionID","sessionId","taskAgent","input","subagent_type","taskDescription","description","title","taskMetadataModel","model","providerID","modelID","childSessionModel","session","id","variant","childMessageModel","message","role","resolveTaskModel","childSession","childMessages","sessionModel","index","length","messageModel","taskModelLabel","displayName","taskVariantLabel","taskStatusLabel","childStatus","status","type","taskModeLabel","background","canOpenTaskSession","currentSessionID","Boolean","isTaskPart","tool","isVisibleTask","sessionStatus","childSessionID"],"sources":["../src/tasks.ts"],"sourcesContent":["import type { Message, Part, Session, SessionStatus, ToolPart } from \"@opencode-ai/sdk/v2\"\n\nexport type VisibleTaskPart = ToolPart\n\nexport type TaskModel = {\n providerID: string\n modelID: string\n variant?: string\n}\n\nfunction objectValue(value: unknown): Record<string, unknown> {\n return value && typeof value === \"object\" && !Array.isArray(value) ? (value as Record<string, unknown>) : {}\n}\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined\n}\n\nfunction taskMetadata(part: ToolPart): Record<string, unknown> {\n return { ...objectValue(part.metadata), ...objectValue(objectValue(part.state).metadata) }\n}\n\nexport function normalizeTaskDescription(value: unknown): string | undefined {\n const text = stringValue(value)\n return text\n ?.replace(/\\s+/g, \" \")\n .replace(/^[#>*_`\\-\\s]+/, \"\")\n .replace(/[*_`]/g, \"\")\n .trim() || undefined\n}\n\nexport function taskSessionID(part: ToolPart): string | undefined {\n const sessionID = taskMetadata(part).sessionId\n return stringValue(sessionID)\n}\n\nexport function taskAgent(part: VisibleTaskPart): string {\n return stringValue(part.state.input.subagent_type) ?? \"subagent\"\n}\n\nexport function taskDescription(part: VisibleTaskPart): string {\n return normalizeTaskDescription(part.state.input.description) ?? normalizeTaskDescription(objectValue(part.state).title) ?? \"Working\"\n}\n\nfunction taskMetadataModel(part: VisibleTaskPart): TaskModel | undefined {\n const model = objectValue(taskMetadata(part).model)\n const providerID = stringValue(model.providerID)\n const modelID = stringValue(model.modelID)\n // Task metadata is created before the child chooses a model variant. Do not\n // invent or retain a variant from this startup-only fallback.\n return providerID && modelID ? { providerID, modelID } : undefined\n}\n\nfunction childSessionModel(session: Session | undefined): TaskModel | undefined {\n const providerID = stringValue(session?.model?.providerID)\n const modelID = stringValue(session?.model?.id)\n const variant = stringValue(session?.model?.variant)\n return providerID && modelID ? { providerID, modelID, variant: variant ?? \"default\" } : undefined\n}\n\nfunction childMessageModel(message: Message): TaskModel | undefined {\n if (message.role === \"user\") {\n const providerID = stringValue(message.model.providerID)\n const modelID = stringValue(message.model.modelID)\n const variant = stringValue(message.model.variant)\n return providerID && modelID ? { providerID, modelID, variant: variant ?? \"default\" } : undefined\n }\n\n const providerID = stringValue(message.providerID)\n const modelID = stringValue(message.modelID)\n const variant = stringValue(message.variant)\n return providerID && modelID ? { providerID, modelID, variant: variant ?? \"default\" } : undefined\n}\n\nexport function resolveTaskModel(\n part: VisibleTaskPart,\n childSession: Session | undefined,\n childMessages: ReadonlyArray<Message>,\n): TaskModel | undefined {\n const sessionModel = childSessionModel(childSession)\n if (sessionModel) return sessionModel\n\n for (let index = childMessages.length - 1; index >= 0; index -= 1) {\n const message = childMessages[index]\n if (!message) continue\n const messageModel = childMessageModel(message)\n if (messageModel) return messageModel\n }\n\n return taskMetadataModel(part)\n}\n\nexport function taskModelLabel(model: TaskModel | undefined, displayName?: string): string {\n if (!model) return \"starting…\"\n return stringValue(displayName) ?? model.modelID\n}\n\nexport function taskVariantLabel(model: TaskModel | undefined): string | undefined {\n return model?.variant\n}\n\nexport function taskStatusLabel(part: VisibleTaskPart, childStatus?: SessionStatus): string {\n if (part.state.status === \"completed\" && childStatus && childStatus.type !== \"idle\") return \"Running\"\n if (part.state.status === \"pending\") return \"Pending\"\n if (part.state.status === \"running\") return \"Running\"\n if (part.state.status === \"completed\") return \"Completed\"\n return \"Failed\"\n}\n\nexport function taskModeLabel(part: VisibleTaskPart): \"Foreground\" | \"Background\" {\n return taskMetadata(part).background === true ? \"Background\" : \"Foreground\"\n}\n\nexport function canOpenTaskSession(sessionID: string | undefined, currentSessionID: string): boolean {\n return Boolean(sessionID && sessionID !== currentSessionID)\n}\n\nexport function isTaskPart(part: Part): part is VisibleTaskPart {\n return part.type === \"tool\" && part.tool === \"task\"\n}\n\nexport function isVisibleTask(\n part: Part,\n sessionStatus: (sessionID: string) => SessionStatus | undefined,\n): part is VisibleTaskPart {\n if (!isTaskPart(part)) return false\n if (part.state.status === \"pending\" || part.state.status === \"running\") return true\n if (part.state.status !== \"completed\" || taskMetadata(part).background !== true) return false\n\n const childSessionID = taskSessionID(part)\n if (!childSessionID) return false\n const status = sessionStatus(childSessionID)\n return status !== undefined && status.type !== \"idle\"\n}\n"],"mappings":"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","ignoreList":[]}
package/dist/tui.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"tui.d.ts","sourceRoot":"","sources":["../src/tui.tsx"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC,OAAO,KAAK,EAAE,SAAS,EAAiC,MAAM,yBAAyB,CAAA;AA4SvF,QAAA,MAAM,MAAM;;;CAGe,CAAA;AAE3B,eAAe,MAAM,CAAA"}
1
+ {"version":3,"file":"tui.d.ts","sourceRoot":"","sources":["../src/tui.tsx"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC,OAAO,KAAK,EAAE,SAAS,EAAiC,MAAM,yBAAyB,CAAA;AA2avF,QAAA,MAAM,MAAM;;;CAGe,CAAA;AAE3B,eAAe,MAAM,CAAA"}
package/dist/tui.js CHANGED
@@ -1,181 +1,331 @@
1
1
  import { createComponent as _$createComponent } from "@opentui/solid";
2
2
  import { effect as _$effect } from "@opentui/solid";
3
+ import { memo as _$memo } from "@opentui/solid";
4
+ import { insert as _$insert } from "@opentui/solid";
3
5
  import { createTextNode as _$createTextNode } from "@opentui/solid";
4
6
  import { insertNode as _$insertNode } from "@opentui/solid";
5
- import { insert as _$insert } from "@opentui/solid";
6
- import { memo as _$memo } from "@opentui/solid";
7
7
  import { setProp as _$setProp } from "@opentui/solid";
8
8
  import { createElement as _$createElement } from "@opentui/solid";
9
9
  /** @jsxImportSource @opentui/solid */
10
10
 
11
- import { activityForPart, elapsedLabel, normalizeMeaningful } from "./activity.js";
12
- import { isVisibleTask, taskSessionID } from "./tasks.js";
11
+ import { elapsedLabel } from "./activity.js";
12
+ import { canOpenTaskSession, isTaskPart, isVisibleTask, resolveTaskModel, taskAgent, taskDescription, taskModeLabel, taskModelLabel, taskSessionID, taskStatusLabel, taskVariantLabel } from "./tasks.js";
13
13
  import { createEffect, createMemo, createSignal, For, on, onCleanup, onMount, Show } from "solid-js";
14
- function stringValue(value) {
15
- return typeof value === "string" && value.trim() ? value.trim() : undefined;
16
- }
17
- function objectValue(value) {
18
- return value && typeof value === "object" && !Array.isArray(value) ? value : {};
19
- }
20
- function taskAgent(part) {
21
- return stringValue(part.state.input.subagent_type) ?? "subagent";
22
- }
23
- function taskDescription(part) {
24
- return normalizeMeaningful(part.state.input.description) ?? normalizeMeaningful(objectValue(part.state).title) ?? "Working";
25
- }
26
- function taskModel(part) {
27
- const metadata = objectValue(objectValue(part.state).metadata);
28
- const model = objectValue(metadata.model);
29
- const providerID = stringValue(model.providerID);
30
- const modelID = stringValue(model.modelID);
31
- return providerID && modelID ? {
32
- providerID,
33
- modelID
34
- } : undefined;
35
- }
36
- function latestActivity(api, sessionID, fallback) {
37
- if (!sessionID) return fallback;
38
- const messages = api.state.session.messages(sessionID);
39
- for (let messageIndex = messages.length - 1; messageIndex >= 0; messageIndex -= 1) {
40
- const message = messages[messageIndex];
41
- if (message?.role !== "assistant") continue;
42
- const parts = api.state.part(message.id);
43
- for (let partIndex = parts.length - 1; partIndex >= 0; partIndex -= 1) {
44
- const candidate = parts[partIndex];
45
- if (!candidate) continue;
46
- const activity = activityForPart(candidate);
47
- if (activity) return activity;
48
- }
49
- }
50
- return fallback;
14
+ function resolvedModel(api, part, session, sessionID) {
15
+ return resolveTaskModel(part, session, sessionID ? api.state.session.messages(sessionID) : []);
51
16
  }
52
- function modelLabel(api, part) {
53
- let model = taskModel(part);
54
- const childSessionID = taskSessionID(part);
55
- if (!model && childSessionID) {
56
- const messages = api.state.session.messages(childSessionID);
57
- for (let index = messages.length - 1; index >= 0; index -= 1) {
58
- const message = messages[index];
59
- if (message?.role === "assistant") {
60
- model = {
61
- providerID: message.providerID,
62
- modelID: message.modelID
63
- };
64
- break;
65
- }
66
- }
67
- }
68
- if (!model) return "starting…";
69
- return api.state.provider.find(provider => provider.id === model.providerID)?.models[model.modelID]?.name ?? model.modelID;
17
+ function modelName(api, model) {
18
+ const name = model ? api.state.provider.find(provider => provider.id === model.providerID)?.models[model.modelID]?.name : undefined;
19
+ return taskModelLabel(model, name);
70
20
  }
71
- function TaskCard(props) {
72
- // The call ID is stable, while the actual ToolPart is re-read after each event.
73
- // This prevents cards from retaining a stale part object after a state update.
74
- const livePart = createMemo(() => props.tasksByCallID().get(props.callID));
75
- const childSessionID = () => taskSessionID(livePart());
76
- const isCurrent = () => childSessionID() === props.currentSessionID;
77
- const model = () => {
21
+ function TaskDetails(props) {
22
+ const fallback = () => {
23
+ const known = props.fallbackFor(props.callID);
24
+ if (known) return known;
25
+ const sessionID = taskSessionID(props.fallbackPart);
26
+ return {
27
+ part: props.fallbackPart,
28
+ ...(sessionID ? {
29
+ sessionID
30
+ } : {})
31
+ };
32
+ };
33
+ const part = createMemo(() => {
78
34
  props.revision();
79
- return modelLabel(props.api, livePart());
35
+ return props.tasksByCallID().get(props.callID) ?? fallback().part;
36
+ });
37
+ const childSessionID = () => taskSessionID(part() ?? fallback().part) ?? fallback().sessionID;
38
+ const childSession = () => {
39
+ props.revision();
40
+ const sessionID = childSessionID();
41
+ return (sessionID ? props.api.state.session.get(sessionID) : undefined) ?? fallback().session;
80
42
  };
81
- const activity = () => {
43
+ const model = createMemo(() => {
82
44
  props.revision();
83
- return latestActivity(props.api, childSessionID(), taskDescription(livePart()));
45
+ return resolvedModel(props.api, part() ?? fallback().part, childSession(), childSessionID());
46
+ });
47
+ const canOpen = () => canOpenTaskSession(childSessionID(), props.currentSessionID);
48
+ const openSession = () => {
49
+ const sessionID = childSessionID();
50
+ if (!canOpen() || !sessionID) return;
51
+ props.api.route.navigate("session", {
52
+ sessionID
53
+ });
54
+ props.close();
84
55
  };
85
- const elapsed = () => elapsedLabel(props.now() - props.startedAt(livePart()));
86
56
  return (() => {
87
57
  var _el$ = _$createElement("box"),
88
- _el$2 = _$createElement("box"),
89
- _el$3 = _$createElement("text"),
90
- _el$4 = _$createElement("span"),
91
- _el$5 = _$createElement("span"),
92
- _el$6 = _$createTextNode(` `),
93
- _el$7 = _$createElement("b"),
58
+ _el$2 = _$createElement("text"),
59
+ _el$3 = _$createElement("b"),
60
+ _el$5 = _$createElement("box"),
61
+ _el$6 = _$createElement("text"),
62
+ _el$7 = _$createTextNode(`Agent: `),
94
63
  _el$8 = _$createElement("text"),
95
- _el$9 = _$createElement("box"),
64
+ _el$9 = _$createTextNode(`Assigned task: `),
96
65
  _el$0 = _$createElement("text"),
97
- _el$1 = _$createElement("text");
66
+ _el$1 = _$createTextNode(`Status: `),
67
+ _el$10 = _$createElement("text"),
68
+ _el$11 = _$createTextNode(`Model: `),
69
+ _el$12 = _$createElement("text"),
70
+ _el$13 = _$createTextNode(`Effort/variant: `),
71
+ _el$14 = _$createElement("text"),
72
+ _el$15 = _$createTextNode(`Elapsed: `),
73
+ _el$16 = _$createElement("text"),
74
+ _el$17 = _$createTextNode(`Child session ID: `),
75
+ _el$18 = _$createElement("text"),
76
+ _el$19 = _$createTextNode(`Mode: `),
77
+ _el$20 = _$createElement("box"),
78
+ _el$21 = _$createElement("box"),
79
+ _el$22 = _$createElement("text"),
80
+ _el$23 = _$createElement("b"),
81
+ _el$25 = _$createElement("box"),
82
+ _el$26 = _$createElement("text"),
83
+ _el$27 = _$createElement("b");
98
84
  _$insertNode(_el$, _el$2);
99
- _$insertNode(_el$, _el$9);
85
+ _$insertNode(_el$, _el$5);
86
+ _$insertNode(_el$, _el$20);
100
87
  _$setProp(_el$, "width", "100%");
101
- _$setProp(_el$, "height", 2);
102
- _$setProp(_el$, "overflow", "hidden");
88
+ _$setProp(_el$, "flexDirection", "column");
89
+ _$setProp(_el$, "padding", 1);
90
+ _$setProp(_el$, "gap", 1);
103
91
  _$insertNode(_el$2, _el$3);
104
- _$insertNode(_el$2, _el$8);
105
- _$setProp(_el$2, "width", "100%");
106
- _$setProp(_el$2, "height", 1);
107
- _$setProp(_el$2, "flexDirection", "row");
108
- _$setProp(_el$2, "overflow", "hidden");
109
- _$insertNode(_el$3, _el$4);
110
- _$insertNode(_el$3, _el$5);
111
- _$setProp(_el$3, "flexGrow", 1);
112
- _$setProp(_el$3, "flexShrink", 1);
113
- _$setProp(_el$3, "minWidth", 0);
114
- _$setProp(_el$3, "wrapMode", "none");
115
- _$setProp(_el$3, "truncate", true);
116
- _$insert(_el$4, (() => {
117
- var _c$ = _$memo(() => !!isCurrent());
118
- return () => _c$() ? "›" : livePart().state.status === "pending" ? "…" : "●";
119
- })());
92
+ _$insertNode(_el$3, _$createTextNode(`Subagent details`));
120
93
  _$insertNode(_el$5, _el$6);
121
- _$insertNode(_el$5, _el$7);
122
- _$insert(_el$7, () => taskAgent(livePart()));
123
- _$setProp(_el$8, "flexShrink", 0);
124
- _$setProp(_el$8, "maxWidth", 20);
125
- _$setProp(_el$8, "marginLeft", 1);
126
- _$setProp(_el$8, "wrapMode", "none");
127
- _$setProp(_el$8, "truncate", true);
128
- _$insert(_el$8, model);
129
- _$insertNode(_el$9, _el$0);
130
- _$insertNode(_el$9, _el$1);
131
- _$setProp(_el$9, "width", "100%");
132
- _$setProp(_el$9, "height", 1);
133
- _$setProp(_el$9, "flexDirection", "row");
134
- _$setProp(_el$9, "overflow", "hidden");
135
- _$setProp(_el$0, "flexGrow", 1);
136
- _$setProp(_el$0, "flexShrink", 1);
137
- _$setProp(_el$0, "minWidth", 0);
138
- _$setProp(_el$0, "wrapMode", "none");
139
- _$setProp(_el$0, "truncate", true);
140
- _$insert(_el$0, activity);
141
- _$setProp(_el$1, "width", 8);
142
- _$setProp(_el$1, "flexShrink", 0);
143
- _$setProp(_el$1, "marginLeft", 1);
144
- _$setProp(_el$1, "wrapMode", "none");
145
- _$setProp(_el$1, "truncate", true);
146
- _$insert(_el$1, elapsed);
94
+ _$insertNode(_el$5, _el$8);
95
+ _$insertNode(_el$5, _el$0);
96
+ _$insertNode(_el$5, _el$10);
97
+ _$insertNode(_el$5, _el$12);
98
+ _$insertNode(_el$5, _el$14);
99
+ _$insertNode(_el$5, _el$16);
100
+ _$insertNode(_el$5, _el$18);
101
+ _$setProp(_el$5, "flexDirection", "column");
102
+ _$insertNode(_el$6, _el$7);
103
+ _$insert(_el$6, () => taskAgent(part() ?? fallback().part), null);
104
+ _$insertNode(_el$8, _el$9);
105
+ _$setProp(_el$8, "wrapMode", "word");
106
+ _$insert(_el$8, () => taskDescription(part() ?? fallback().part), null);
107
+ _$insertNode(_el$0, _el$1);
108
+ _$insert(_el$0, () => taskStatusLabel(part() ?? fallback().part, childSessionID() ? props.api.state.session.status(childSessionID()) : undefined), null);
109
+ _$insertNode(_el$10, _el$11);
110
+ _$insert(_el$10, () => modelName(props.api, model()), null);
111
+ _$insertNode(_el$12, _el$13);
112
+ _$insert(_el$12, () => taskVariantLabel(model()) ?? "pending", null);
113
+ _$insertNode(_el$14, _el$15);
114
+ _$insert(_el$14, () => elapsedLabel(props.now() - props.startedAt(part() ?? fallback().part)), null);
115
+ _$insertNode(_el$16, _el$17);
116
+ _$insert(_el$16, () => childSessionID() ?? "Waiting for child session", null);
117
+ _$insertNode(_el$18, _el$19);
118
+ _$insert(_el$18, () => taskModeLabel(part() ?? fallback().part), null);
119
+ _$insertNode(_el$20, _el$21);
120
+ _$insertNode(_el$20, _el$25);
121
+ _$setProp(_el$20, "flexDirection", "row");
122
+ _$setProp(_el$20, "gap", 2);
123
+ _$insertNode(_el$21, _el$22);
124
+ _$setProp(_el$21, "onMouseUp", openSession);
125
+ _$insertNode(_el$22, _el$23);
126
+ _$insertNode(_el$23, _$createTextNode(`Open Session`));
127
+ _$insertNode(_el$25, _el$26);
128
+ _$insertNode(_el$26, _el$27);
129
+ _$insertNode(_el$27, _$createTextNode(`Close`));
147
130
  _$effect(_p$ => {
148
- var _v$ = {
149
- fg: livePart().state.status === "pending" ? props.api.theme.current.warning : props.api.theme.current.success
150
- },
151
- _v$2 = {
152
- fg: props.api.theme.current.text
153
- },
131
+ var _v$ = props.api.theme.current.text,
132
+ _v$2 = props.api.theme.current.text,
154
133
  _v$3 = props.api.theme.current.textMuted,
155
134
  _v$4 = props.api.theme.current.textMuted,
156
- _v$5 = props.api.theme.current.textMuted;
157
- _v$ !== _p$.e && (_p$.e = _$setProp(_el$4, "style", _v$, _p$.e));
158
- _v$2 !== _p$.t && (_p$.t = _$setProp(_el$5, "style", _v$2, _p$.t));
135
+ _v$5 = props.api.theme.current.textMuted,
136
+ _v$6 = props.api.theme.current.textMuted,
137
+ _v$7 = props.api.theme.current.textMuted,
138
+ _v$8 = props.api.theme.current.textMuted,
139
+ _v$9 = props.api.theme.current.textMuted,
140
+ _v$0 = canOpen() ? props.api.theme.current.primary : props.api.theme.current.textMuted,
141
+ _v$1 = props.close,
142
+ _v$10 = props.api.theme.current.primary;
143
+ _v$ !== _p$.e && (_p$.e = _$setProp(_el$2, "fg", _v$, _p$.e));
144
+ _v$2 !== _p$.t && (_p$.t = _$setProp(_el$6, "fg", _v$2, _p$.t));
159
145
  _v$3 !== _p$.a && (_p$.a = _$setProp(_el$8, "fg", _v$3, _p$.a));
160
146
  _v$4 !== _p$.o && (_p$.o = _$setProp(_el$0, "fg", _v$4, _p$.o));
161
- _v$5 !== _p$.i && (_p$.i = _$setProp(_el$1, "fg", _v$5, _p$.i));
147
+ _v$5 !== _p$.i && (_p$.i = _$setProp(_el$10, "fg", _v$5, _p$.i));
148
+ _v$6 !== _p$.n && (_p$.n = _$setProp(_el$12, "fg", _v$6, _p$.n));
149
+ _v$7 !== _p$.s && (_p$.s = _$setProp(_el$14, "fg", _v$7, _p$.s));
150
+ _v$8 !== _p$.h && (_p$.h = _$setProp(_el$16, "fg", _v$8, _p$.h));
151
+ _v$9 !== _p$.r && (_p$.r = _$setProp(_el$18, "fg", _v$9, _p$.r));
152
+ _v$0 !== _p$.d && (_p$.d = _$setProp(_el$22, "fg", _v$0, _p$.d));
153
+ _v$1 !== _p$.l && (_p$.l = _$setProp(_el$25, "onMouseUp", _v$1, _p$.l));
154
+ _v$10 !== _p$.u && (_p$.u = _$setProp(_el$26, "fg", _v$10, _p$.u));
162
155
  return _p$;
163
156
  }, {
164
157
  e: undefined,
165
158
  t: undefined,
166
159
  a: undefined,
167
160
  o: undefined,
168
- i: undefined
161
+ i: undefined,
162
+ n: undefined,
163
+ s: undefined,
164
+ h: undefined,
165
+ r: undefined,
166
+ d: undefined,
167
+ l: undefined,
168
+ u: undefined
169
169
  });
170
170
  return _el$;
171
171
  })();
172
172
  }
173
+ function TaskCard(props) {
174
+ // The call ID is stable, while the actual ToolPart is re-read after each event.
175
+ // This prevents cards from retaining a stale part object after a state update.
176
+ const livePart = createMemo(() => props.tasksByCallID().get(props.callID));
177
+ const part = () => livePart() ?? props.fallbackFor(props.callID)?.part;
178
+ const childSession = () => {
179
+ props.revision();
180
+ const current = part();
181
+ if (!current) return undefined;
182
+ const sessionID = taskSessionID(current);
183
+ return sessionID ? props.api.state.session.get(sessionID) : undefined;
184
+ };
185
+ const model = () => {
186
+ props.revision();
187
+ const current = part();
188
+ return current ? resolvedModel(props.api, current, childSession(), taskSessionID(current)) : undefined;
189
+ };
190
+ const elapsed = () => {
191
+ const current = part();
192
+ return current ? elapsedLabel(props.now() - props.startedAt(current)) : "";
193
+ };
194
+ const openDetails = () => {
195
+ if (props.api.renderer.getSelection()?.getSelectedText()) return;
196
+ const part = livePart();
197
+ if (!part) return;
198
+ props.remember(part);
199
+ props.openPopup(props.callID, part);
200
+ };
201
+ return (() => {
202
+ var _el$29 = _$createElement("box"),
203
+ _el$30 = _$createElement("box"),
204
+ _el$31 = _$createElement("text"),
205
+ _el$32 = _$createElement("b"),
206
+ _el$33 = _$createElement("box"),
207
+ _el$34 = _$createElement("text"),
208
+ _el$35 = _$createElement("box"),
209
+ _el$36 = _$createElement("text"),
210
+ _el$37 = _$createElement("box"),
211
+ _el$38 = _$createElement("text");
212
+ _$insertNode(_el$29, _el$30);
213
+ _$insertNode(_el$29, _el$35);
214
+ _$setProp(_el$29, "width", "100%");
215
+ _$setProp(_el$29, "height", 2);
216
+ _$setProp(_el$29, "overflow", "hidden");
217
+ _$setProp(_el$29, "onMouseUp", openDetails);
218
+ _$insertNode(_el$30, _el$31);
219
+ _$insertNode(_el$30, _el$33);
220
+ _$setProp(_el$30, "width", "100%");
221
+ _$setProp(_el$30, "height", 1);
222
+ _$setProp(_el$30, "flexDirection", "row");
223
+ _$setProp(_el$30, "overflow", "hidden");
224
+ _$insertNode(_el$31, _el$32);
225
+ _$setProp(_el$31, "flexGrow", 1);
226
+ _$setProp(_el$31, "flexShrink", 1);
227
+ _$setProp(_el$31, "minWidth", 0);
228
+ _$setProp(_el$31, "wrapMode", "none");
229
+ _$setProp(_el$31, "truncate", true);
230
+ _$insert(_el$32, (() => {
231
+ var _c$ = _$memo(() => !!part());
232
+ return () => _c$() ? taskAgent(part()) : "subagent";
233
+ })());
234
+ _$insertNode(_el$33, _el$34);
235
+ _$setProp(_el$33, "flexShrink", 1);
236
+ _$setProp(_el$33, "minWidth", 0);
237
+ _$setProp(_el$33, "maxWidth", 28);
238
+ _$setProp(_el$33, "marginLeft", 1);
239
+ _$setProp(_el$33, "flexDirection", "row");
240
+ _$setProp(_el$34, "flexGrow", 1);
241
+ _$setProp(_el$34, "flexShrink", 1);
242
+ _$setProp(_el$34, "minWidth", 0);
243
+ _$setProp(_el$34, "wrapMode", "none");
244
+ _$setProp(_el$34, "truncate", true);
245
+ _$insert(_el$34, () => modelName(props.api, model()));
246
+ _$insert(_el$33, _$createComponent(Show, {
247
+ get when() {
248
+ return taskVariantLabel(model());
249
+ },
250
+ get fallback() {
251
+ return _$createComponent(Show, {
252
+ get when() {
253
+ return model();
254
+ },
255
+ get children() {
256
+ var _el$39 = _$createElement("text");
257
+ _$insertNode(_el$39, _$createTextNode(`· pending`));
258
+ _$setProp(_el$39, "flexShrink", 0);
259
+ _$setProp(_el$39, "marginLeft", 1);
260
+ _$setProp(_el$39, "wrapMode", "none");
261
+ _$setProp(_el$39, "truncate", true);
262
+ _$effect(_$p => _$setProp(_el$39, "fg", props.api.theme.current.textMuted, _$p));
263
+ return _el$39;
264
+ }
265
+ });
266
+ },
267
+ children: variant => (() => {
268
+ var _el$41 = _$createElement("text"),
269
+ _el$42 = _$createTextNode(`· `);
270
+ _$insertNode(_el$41, _el$42);
271
+ _$setProp(_el$41, "flexShrink", 0);
272
+ _$setProp(_el$41, "marginLeft", 1);
273
+ _$setProp(_el$41, "wrapMode", "none");
274
+ _$setProp(_el$41, "truncate", true);
275
+ _$insert(_el$41, variant, null);
276
+ _$effect(_$p => _$setProp(_el$41, "fg", props.api.theme.current.textMuted, _$p));
277
+ return _el$41;
278
+ })()
279
+ }), null);
280
+ _$insertNode(_el$35, _el$36);
281
+ _$insertNode(_el$35, _el$37);
282
+ _$setProp(_el$35, "width", "100%");
283
+ _$setProp(_el$35, "height", 1);
284
+ _$setProp(_el$35, "flexDirection", "row");
285
+ _$setProp(_el$35, "overflow", "hidden");
286
+ _$setProp(_el$36, "flexGrow", 1);
287
+ _$setProp(_el$36, "flexShrink", 1);
288
+ _$setProp(_el$36, "minWidth", 0);
289
+ _$setProp(_el$36, "wrapMode", "none");
290
+ _$setProp(_el$36, "truncate", true);
291
+ _$insert(_el$36, (() => {
292
+ var _c$2 = _$memo(() => !!part());
293
+ return () => _c$2() ? taskDescription(part()) : "Working";
294
+ })());
295
+ _$insertNode(_el$37, _el$38);
296
+ _$setProp(_el$37, "width", 8);
297
+ _$setProp(_el$37, "flexShrink", 0);
298
+ _$setProp(_el$37, "justifyContent", "flex-end");
299
+ _$setProp(_el$38, "wrapMode", "none");
300
+ _$setProp(_el$38, "truncate", true);
301
+ _$insert(_el$38, elapsed);
302
+ _$effect(_p$ => {
303
+ var _v$11 = props.api.theme.current.text,
304
+ _v$12 = props.api.theme.current.textMuted,
305
+ _v$13 = props.api.theme.current.textMuted,
306
+ _v$14 = props.api.theme.current.textMuted;
307
+ _v$11 !== _p$.e && (_p$.e = _$setProp(_el$31, "fg", _v$11, _p$.e));
308
+ _v$12 !== _p$.t && (_p$.t = _$setProp(_el$34, "fg", _v$12, _p$.t));
309
+ _v$13 !== _p$.a && (_p$.a = _$setProp(_el$36, "fg", _v$13, _p$.a));
310
+ _v$14 !== _p$.o && (_p$.o = _$setProp(_el$38, "fg", _v$14, _p$.o));
311
+ return _p$;
312
+ }, {
313
+ e: undefined,
314
+ t: undefined,
315
+ a: undefined,
316
+ o: undefined
317
+ });
318
+ return _el$29;
319
+ })();
320
+ }
173
321
  function RunningSubagents(props) {
174
322
  const [scopeSessionID, setScopeSessionID] = createSignal();
175
323
  const [hydratedMessages, setHydratedMessages] = createSignal([]);
176
324
  const [revision, setRevision] = createSignal(0);
177
325
  const [now, setNow] = createSignal(Date.now());
178
326
  const firstSeen = new Map();
327
+ const fallbacks = new Map();
328
+ const [openPopup, setOpenPopup] = createSignal();
179
329
  let sessionRequest = 0;
180
330
  const loadMessages = async (sessionID, request) => {
181
331
  if (props.api.state.session.messages(sessionID).length) return;
@@ -220,17 +370,48 @@ function RunningSubagents(props) {
220
370
  void loadMessages(parentSessionID, currentRequest);
221
371
  };
222
372
  createEffect(on(() => props.sessionID, sessionID => void selectSession(sessionID)));
223
- const running = createMemo(() => {
373
+ const allTaskParts = createMemo(() => {
224
374
  revision();
225
375
  const sessionID = scopeSessionID();
226
376
  if (!sessionID) return [];
227
377
  const messages = props.api.state.session.messages(sessionID);
228
378
  const parts = messages.length ? messages.flatMap(message => props.api.state.part(message.id)) : hydratedMessages().flatMap(message => message.parts);
229
- return parts.filter(part => isVisibleTask(part, props.api.state.session.status));
379
+ return parts.filter(isTaskPart);
380
+ });
381
+ const visibleTaskParts = createMemo(() => allTaskParts().filter(part => isVisibleTask(part, props.api.state.session.status)));
382
+ // Popups need the direct parent's complete/error parts too, even after their
383
+ // visible card has gone away.
384
+ const tasksByCallID = createMemo(() => new Map(allTaskParts().map(part => [part.callID, part])));
385
+ const taskCallIDs = createMemo(() => visibleTaskParts().map(part => part.callID));
386
+ const activeChildSessions = createMemo(() => new Set(visibleTaskParts().map(taskSessionID).filter(sessionID => Boolean(sessionID))));
387
+ const remember = part => {
388
+ const sessionID = taskSessionID(part);
389
+ const session = sessionID ? props.api.state.session.get(sessionID) : undefined;
390
+ fallbacks.set(part.callID, {
391
+ part,
392
+ ...(sessionID ? {
393
+ sessionID
394
+ } : {}),
395
+ ...(session ? {
396
+ session
397
+ } : {})
398
+ });
399
+ };
400
+ const rememberLiveTasks = () => {
401
+ revision();
402
+ for (const part of allTaskParts()) remember(part);
403
+ };
404
+ createEffect(rememberLiveTasks);
405
+ const popupPart = createMemo(() => {
406
+ revision();
407
+ const callID = openPopup()?.callID;
408
+ return callID ? tasksByCallID().get(callID) ?? fallbacks.get(callID)?.part : undefined;
409
+ });
410
+ const popupSessionID = createMemo(() => {
411
+ const callID = openPopup()?.callID;
412
+ const part = popupPart();
413
+ return (part ? taskSessionID(part) : undefined) ?? (callID ? fallbacks.get(callID)?.sessionID : undefined);
230
414
  });
231
- const tasksByCallID = createMemo(() => new Map(running().map(part => [part.callID, part])));
232
- const taskCallIDs = createMemo(() => running().map(part => part.callID));
233
- const activeChildSessions = createMemo(() => new Set(running().map(taskSessionID).filter(sessionID => Boolean(sessionID))));
234
415
  const startedAt = part => {
235
416
  if (part.state.status !== "pending") return part.state.time.start;
236
417
  const existing = firstSeen.get(part.callID);
@@ -239,17 +420,48 @@ function RunningSubagents(props) {
239
420
  firstSeen.set(part.callID, value);
240
421
  return value;
241
422
  };
423
+ const releasePopup = ownership => {
424
+ if (openPopup()?.token === ownership.token) setOpenPopup(undefined);
425
+ };
426
+ const closePopup = ownership => {
427
+ if (openPopup()?.token !== ownership.token) return;
428
+ setOpenPopup(undefined);
429
+ props.api.ui.dialog.clear();
430
+ };
431
+ const showPopup = (callID, part) => {
432
+ const ownership = {
433
+ callID,
434
+ token: Symbol(callID)
435
+ };
436
+ setOpenPopup(ownership);
437
+ props.api.ui.dialog.replace(() => _$createComponent(TaskDetails, {
438
+ get api() {
439
+ return props.api;
440
+ },
441
+ callID: callID,
442
+ get currentSessionID() {
443
+ return props.sessionID;
444
+ },
445
+ fallbackPart: part,
446
+ tasksByCallID: tasksByCallID,
447
+ fallbackFor: id => fallbacks.get(id),
448
+ revision: revision,
449
+ now: now,
450
+ startedAt: startedAt,
451
+ close: () => closePopup(ownership)
452
+ }), () => releasePopup(ownership));
453
+ };
242
454
  const unregister = [];
243
455
  let timer;
244
456
  onMount(() => {
245
457
  const syncCurrentSession = session => {
246
458
  if (session.id === props.sessionID) void selectSession(session.id, session);
247
- if (session.parentID === scopeSessionID() || activeChildSessions().has(session.id)) {
459
+ if (session.parentID === scopeSessionID() || activeChildSessions().has(session.id) || session.id === popupSessionID()) {
248
460
  setRevision(value => value + 1);
249
461
  }
250
462
  };
251
463
  const refreshSession = sessionID => {
252
- if (sessionID === scopeSessionID() || activeChildSessions().has(sessionID)) {
464
+ if (sessionID === scopeSessionID() || activeChildSessions().has(sessionID) || sessionID === popupSessionID()) {
253
465
  setRevision(value => value + 1);
254
466
  }
255
467
  };
@@ -260,31 +472,33 @@ function RunningSubagents(props) {
260
472
  sessionRequest += 1;
261
473
  if (timer) clearInterval(timer);
262
474
  for (const dispose of unregister) dispose();
475
+ const ownership = openPopup();
476
+ if (ownership) closePopup(ownership);
263
477
  });
264
478
  return (() => {
265
- var _el$10 = _$createElement("box"),
266
- _el$11 = _$createElement("text"),
267
- _el$12 = _$createElement("b"),
268
- _el$14 = _$createElement("span");
269
- _$insertNode(_el$10, _el$11);
270
- _$setProp(_el$10, "overflow", "hidden");
271
- _$insertNode(_el$11, _el$12);
272
- _$insertNode(_el$11, _el$14);
273
- _$insertNode(_el$12, _$createTextNode(`Subagents`));
274
- _$insert(_el$14, (() => {
275
- var _c$2 = _$memo(() => !!running().length);
276
- return () => _c$2() ? ` (${running().length} running)` : "";
479
+ var _el$43 = _$createElement("box"),
480
+ _el$44 = _$createElement("text"),
481
+ _el$45 = _$createElement("b"),
482
+ _el$47 = _$createElement("span");
483
+ _$insertNode(_el$43, _el$44);
484
+ _$setProp(_el$43, "overflow", "hidden");
485
+ _$insertNode(_el$44, _el$45);
486
+ _$insertNode(_el$44, _el$47);
487
+ _$insertNode(_el$45, _$createTextNode(`Subagents`));
488
+ _$insert(_el$47, (() => {
489
+ var _c$3 = _$memo(() => !!visibleTaskParts().length);
490
+ return () => _c$3() ? ` (${visibleTaskParts().length} running)` : "";
277
491
  })());
278
- _$insert(_el$10, _$createComponent(Show, {
492
+ _$insert(_el$43, _$createComponent(Show, {
279
493
  get when() {
280
494
  return taskCallIDs().length > 0;
281
495
  },
282
496
  get fallback() {
283
497
  return (() => {
284
- var _el$15 = _$createElement("text");
285
- _$insertNode(_el$15, _$createTextNode(`No subagent running`));
286
- _$effect(_$p => _$setProp(_el$15, "fg", props.api.theme.current.textMuted, _$p));
287
- return _el$15;
498
+ var _el$48 = _$createElement("text");
499
+ _$insertNode(_el$48, _$createTextNode(`No subagent running`));
500
+ _$effect(_$p => _$setProp(_el$48, "fg", props.api.theme.current.textMuted, _$p));
501
+ return _el$48;
288
502
  })();
289
503
  },
290
504
  get children() {
@@ -297,30 +511,30 @@ function RunningSubagents(props) {
297
511
  return props.api;
298
512
  },
299
513
  callID: callID,
300
- get currentSessionID() {
301
- return props.sessionID;
302
- },
303
514
  tasksByCallID: tasksByCallID,
515
+ fallbackFor: id => fallbacks.get(id),
516
+ remember: remember,
304
517
  revision: revision,
305
518
  now: now,
306
- startedAt: startedAt
519
+ startedAt: startedAt,
520
+ openPopup: showPopup
307
521
  })
308
522
  });
309
523
  }
310
524
  }), null);
311
525
  _$effect(_p$ => {
312
- var _v$6 = props.api.theme.current.text,
313
- _v$7 = {
526
+ var _v$15 = props.api.theme.current.text,
527
+ _v$16 = {
314
528
  fg: props.api.theme.current.textMuted
315
529
  };
316
- _v$6 !== _p$.e && (_p$.e = _$setProp(_el$11, "fg", _v$6, _p$.e));
317
- _v$7 !== _p$.t && (_p$.t = _$setProp(_el$14, "style", _v$7, _p$.t));
530
+ _v$15 !== _p$.e && (_p$.e = _$setProp(_el$44, "fg", _v$15, _p$.e));
531
+ _v$16 !== _p$.t && (_p$.t = _$setProp(_el$47, "style", _v$16, _p$.t));
318
532
  return _p$;
319
533
  }, {
320
534
  e: undefined,
321
535
  t: undefined
322
536
  });
323
- return _el$10;
537
+ return _el$43;
324
538
  })();
325
539
  }
326
540
  const tui = async api => {
package/dist/tui.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"tui.js","names":["activityForPart","elapsedLabel","normalizeMeaningful","isVisibleTask","taskSessionID","createEffect","createMemo","createSignal","For","on","onCleanup","onMount","Show","stringValue","value","trim","undefined","objectValue","Array","isArray","taskAgent","part","state","input","subagent_type","taskDescription","description","title","taskModel","metadata","model","providerID","modelID","latestActivity","api","sessionID","fallback","messages","session","messageIndex","length","message","role","parts","id","partIndex","candidate","activity","modelLabel","childSessionID","index","provider","find","models","name","TaskCard","props","livePart","tasksByCallID","get","callID","isCurrent","currentSessionID","revision","elapsed","now","startedAt","_el$","_$createElement","_el$2","_el$3","_el$4","_el$5","_el$6","_$createTextNode","_el$7","_el$8","_el$9","_el$0","_el$1","_$insertNode","_$setProp","_$insert","_c$","_$memo","status","_$effect","_p$","_v$","fg","theme","current","warning","success","_v$2","text","_v$3","textMuted","_v$4","_v$5","e","t","a","o","i","RunningSubagents","scopeSessionID","setScopeSessionID","hydratedMessages","setHydratedMessages","setRevision","setNow","Date","firstSeen","Map","sessionRequest","loadMessages","request","result","client","directory","path","throwOnError","lifecycle","signal","aborted","data","selectSession","known","currentRequest","parentSessionID","parentID","running","flatMap","filter","map","taskCallIDs","activeChildSessions","Set","Boolean","time","start","existing","set","unregister","timer","syncCurrentSession","has","refreshSession","push","event","properties","info","setInterval","clearInterval","dispose","_el$10","_el$11","_el$12","_el$14","_c$2","_$createComponent","when","_el$15","_$p","children","each","_v$6","_v$7","tui","slots","register","order","sidebar_footer","_ctx","session_id","plugin"],"sources":["../src/tui.tsx"],"sourcesContent":["/** @jsxImportSource @opentui/solid */\n\nimport type { TuiPlugin, TuiPluginApi, TuiPluginModule } from \"@opencode-ai/plugin/tui\"\nimport type { Message, Part, Session } from \"@opencode-ai/sdk/v2\"\nimport { activityForPart, elapsedLabel, normalizeMeaningful } from \"./activity.js\"\nimport { isVisibleTask, taskSessionID, type VisibleTaskPart } from \"./tasks.js\"\nimport { createEffect, createMemo, createSignal, For, on, onCleanup, onMount, Show } from \"solid-js\"\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined\n}\n\nfunction objectValue(value: unknown): Record<string, unknown> {\n return value && typeof value === \"object\" && !Array.isArray(value) ? (value as Record<string, unknown>) : {}\n}\n\nfunction taskAgent(part: VisibleTaskPart): string {\n return stringValue(part.state.input.subagent_type) ?? \"subagent\"\n}\n\nfunction taskDescription(part: VisibleTaskPart): string {\n return normalizeMeaningful(part.state.input.description) ?? normalizeMeaningful(objectValue(part.state).title) ?? \"Working\"\n}\n\nfunction taskModel(part: VisibleTaskPart): { providerID: string; modelID: string } | undefined {\n const metadata = objectValue(objectValue(part.state).metadata)\n const model = objectValue(metadata.model)\n const providerID = stringValue(model.providerID)\n const modelID = stringValue(model.modelID)\n return providerID && modelID ? { providerID, modelID } : undefined\n}\n\nfunction latestActivity(api: TuiPluginApi, sessionID: string | undefined, fallback: string): string {\n if (!sessionID) return fallback\n\n const messages = api.state.session.messages(sessionID)\n for (let messageIndex = messages.length - 1; messageIndex >= 0; messageIndex -= 1) {\n const message = messages[messageIndex]\n if (message?.role !== \"assistant\") continue\n\n const parts = api.state.part(message.id)\n for (let partIndex = parts.length - 1; partIndex >= 0; partIndex -= 1) {\n const candidate = parts[partIndex]\n if (!candidate) continue\n const activity = activityForPart(candidate)\n if (activity) return activity\n }\n }\n return fallback\n}\n\nfunction modelLabel(api: TuiPluginApi, part: VisibleTaskPart): string {\n let model = taskModel(part)\n const childSessionID = taskSessionID(part)\n if (!model && childSessionID) {\n const messages = api.state.session.messages(childSessionID)\n for (let index = messages.length - 1; index >= 0; index -= 1) {\n const message = messages[index]\n if (message?.role === \"assistant\") {\n model = { providerID: message.providerID, modelID: message.modelID }\n break\n }\n }\n }\n\n if (!model) return \"starting…\"\n return api.state.provider.find((provider) => provider.id === model.providerID)?.models[model.modelID]?.name ?? model.modelID\n}\n\nfunction TaskCard(props: {\n api: TuiPluginApi\n callID: string\n currentSessionID: string\n tasksByCallID: () => Map<string, VisibleTaskPart>\n revision: () => number\n now: () => number\n startedAt: (part: VisibleTaskPart) => number\n}) {\n // The call ID is stable, while the actual ToolPart is re-read after each event.\n // This prevents cards from retaining a stale part object after a state update.\n const livePart = createMemo(() => props.tasksByCallID().get(props.callID))\n const childSessionID = () => taskSessionID(livePart()!)\n const isCurrent = () => childSessionID() === props.currentSessionID\n const model = () => {\n props.revision()\n return modelLabel(props.api, livePart()!)\n }\n const activity = () => {\n props.revision()\n return latestActivity(props.api, childSessionID(), taskDescription(livePart()!))\n }\n const elapsed = () => elapsedLabel(props.now() - props.startedAt(livePart()!))\n\n return (\n <box width=\"100%\" height={2} overflow=\"hidden\">\n <box width=\"100%\" height={1} flexDirection=\"row\" overflow=\"hidden\">\n <text flexGrow={1} flexShrink={1} minWidth={0} wrapMode=\"none\" truncate>\n <span\n style={{\n fg:\n livePart()!.state.status === \"pending\"\n ? props.api.theme.current.warning\n : props.api.theme.current.success,\n }}\n >\n {isCurrent() ? \"›\" : livePart()!.state.status === \"pending\" ? \"…\" : \"●\"}\n </span>\n <span style={{ fg: props.api.theme.current.text }}>\n {\" \"}\n <b>{taskAgent(livePart()!)}</b>\n </span>\n </text>\n <text\n flexShrink={0}\n maxWidth={20}\n marginLeft={1}\n wrapMode=\"none\"\n truncate\n fg={props.api.theme.current.textMuted}\n >\n {model()}\n </text>\n </box>\n <box width=\"100%\" height={1} flexDirection=\"row\" overflow=\"hidden\">\n <text\n flexGrow={1}\n flexShrink={1}\n minWidth={0}\n wrapMode=\"none\"\n truncate\n fg={props.api.theme.current.textMuted}\n >\n {activity()}\n </text>\n <text\n width={8}\n flexShrink={0}\n marginLeft={1}\n wrapMode=\"none\"\n truncate\n fg={props.api.theme.current.textMuted}\n >\n {elapsed()}\n </text>\n </box>\n </box>\n )\n}\n\nfunction RunningSubagents(props: { api: TuiPluginApi; sessionID: string }) {\n const [scopeSessionID, setScopeSessionID] = createSignal<string>()\n const [hydratedMessages, setHydratedMessages] = createSignal<ReadonlyArray<{ info: Message; parts: ReadonlyArray<Part> }>>([])\n const [revision, setRevision] = createSignal(0)\n const [now, setNow] = createSignal(Date.now())\n const firstSeen = new Map<string, number>()\n let sessionRequest = 0\n\n const loadMessages = async (sessionID: string, request: number): Promise<void> => {\n if (props.api.state.session.messages(sessionID).length) return\n\n try {\n const result = await props.api.client.session.messages(\n { sessionID, directory: props.api.state.path.directory },\n { throwOnError: true },\n )\n if (props.api.lifecycle.signal.aborted || request !== sessionRequest || scopeSessionID() !== sessionID) return\n setHydratedMessages(result.data)\n setRevision((value) => value + 1)\n } catch {\n // Live session events can populate the public TUI state after a failed hydration.\n }\n }\n\n const selectSession = async (sessionID: string, known?: Session): Promise<void> => {\n const currentRequest = ++sessionRequest\n setScopeSessionID(undefined)\n setHydratedMessages([])\n let session = known ?? props.api.state.session.get(sessionID)\n\n if (!session) {\n try {\n const result = await props.api.client.session.get(\n { sessionID, directory: props.api.state.path.directory },\n { throwOnError: true },\n )\n session = result.data\n } catch {\n // Leave the scope unset so a failed child lookup cannot show its own tasks.\n // A later session event retries after local state is populated.\n return\n }\n }\n\n if (props.api.lifecycle.signal.aborted || currentRequest !== sessionRequest) return\n const parentSessionID = session.parentID ?? session.id\n setScopeSessionID(parentSessionID)\n setRevision((value) => value + 1)\n void loadMessages(parentSessionID, currentRequest)\n }\n\n createEffect(on(() => props.sessionID, (sessionID) => void selectSession(sessionID)))\n\n const running = createMemo(() => {\n revision()\n const sessionID = scopeSessionID()\n if (!sessionID) return []\n\n const messages = props.api.state.session.messages(sessionID)\n const parts = messages.length\n ? messages.flatMap((message) => props.api.state.part(message.id))\n : hydratedMessages().flatMap((message) => message.parts)\n return parts.filter((part) => isVisibleTask(part, props.api.state.session.status))\n })\n const tasksByCallID = createMemo(() => new Map(running().map((part) => [part.callID, part])))\n const taskCallIDs = createMemo(() => running().map((part) => part.callID))\n const activeChildSessions = createMemo(\n () => new Set(running().map(taskSessionID).filter((sessionID): sessionID is string => Boolean(sessionID))),\n )\n\n const startedAt = (part: VisibleTaskPart): number => {\n if (part.state.status !== \"pending\") return part.state.time.start\n const existing = firstSeen.get(part.callID)\n if (existing !== undefined) return existing\n const value = now()\n firstSeen.set(part.callID, value)\n return value\n }\n\n const unregister: Array<() => void> = []\n let timer: ReturnType<typeof setInterval> | undefined\n\n onMount(() => {\n const syncCurrentSession = (session: Session) => {\n if (session.id === props.sessionID) void selectSession(session.id, session)\n if (session.parentID === scopeSessionID() || activeChildSessions().has(session.id)) {\n setRevision((value) => value + 1)\n }\n }\n const refreshSession = (sessionID: string) => {\n if (sessionID === scopeSessionID() || activeChildSessions().has(sessionID)) {\n setRevision((value) => value + 1)\n }\n }\n\n unregister.push(\n props.api.event.on(\"session.created\", (event) => syncCurrentSession(event.properties.info)),\n props.api.event.on(\"session.updated\", (event) => syncCurrentSession(event.properties.info)),\n props.api.event.on(\"message.updated\", (event) => refreshSession(event.properties.sessionID)),\n props.api.event.on(\"message.part.updated\", (event) => refreshSession(event.properties.sessionID)),\n props.api.event.on(\"message.part.removed\", (event) => refreshSession(event.properties.sessionID)),\n )\n timer = setInterval(() => setNow(Date.now()), 1_000)\n })\n\n onCleanup(() => {\n sessionRequest += 1\n if (timer) clearInterval(timer)\n for (const dispose of unregister) dispose()\n })\n\n return (\n <box overflow=\"hidden\">\n <text fg={props.api.theme.current.text}>\n <b>Subagents</b>\n <span style={{ fg: props.api.theme.current.textMuted }}>\n {running().length ? ` (${running().length} running)` : \"\"}\n </span>\n </text>\n\n <Show\n when={taskCallIDs().length > 0}\n fallback={<text fg={props.api.theme.current.textMuted}>No subagent running</text>}\n >\n <For each={taskCallIDs()}>\n {(callID) => (\n <TaskCard\n api={props.api}\n callID={callID}\n currentSessionID={props.sessionID}\n tasksByCallID={tasksByCallID}\n revision={revision}\n now={now}\n startedAt={startedAt}\n />\n )}\n </For>\n </Show>\n </box>\n )\n}\n\nconst tui: TuiPlugin = async (api) => {\n api.slots.register({\n order: 90,\n slots: {\n sidebar_footer(_ctx, props) {\n return <RunningSubagents api={api} sessionID={props.session_id} />\n },\n },\n })\n}\n\nconst plugin = {\n id: \"opencode-subagents-sidebar-plugin\",\n tui,\n} satisfies TuiPluginModule\n\nexport default plugin\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"tui.js","names":["elapsedLabel","canOpenTaskSession","isTaskPart","isVisibleTask","resolveTaskModel","taskAgent","taskDescription","taskModeLabel","taskModelLabel","taskSessionID","taskStatusLabel","taskVariantLabel","createEffect","createMemo","createSignal","For","on","onCleanup","onMount","Show","resolvedModel","api","part","session","sessionID","state","messages","modelName","model","name","provider","find","id","providerID","models","modelID","undefined","TaskDetails","props","fallback","known","fallbackFor","callID","fallbackPart","revision","tasksByCallID","get","childSessionID","childSession","canOpen","currentSessionID","openSession","route","navigate","close","_el$","_$createElement","_el$2","_el$3","_el$5","_el$6","_el$7","_$createTextNode","_el$8","_el$9","_el$0","_el$1","_el$10","_el$11","_el$12","_el$13","_el$14","_el$15","_el$16","_el$17","_el$18","_el$19","_el$20","_el$21","_el$22","_el$23","_el$25","_el$26","_el$27","_$insertNode","_$setProp","_$insert","status","now","startedAt","_$effect","_p$","_v$","theme","current","text","_v$2","_v$3","textMuted","_v$4","_v$5","_v$6","_v$7","_v$8","_v$9","_v$0","primary","_v$1","_v$10","e","t","a","o","i","n","s","h","r","d","l","u","TaskCard","livePart","elapsed","openDetails","renderer","getSelection","getSelectedText","remember","openPopup","_el$29","_el$30","_el$31","_el$32","_el$33","_el$34","_el$35","_el$36","_el$37","_el$38","_c$","_$memo","_$createComponent","when","children","_el$39","_$p","variant","_el$41","_el$42","_c$2","_v$11","_v$12","_v$13","_v$14","RunningSubagents","scopeSessionID","setScopeSessionID","hydratedMessages","setHydratedMessages","setRevision","setNow","Date","firstSeen","Map","fallbacks","setOpenPopup","sessionRequest","loadMessages","request","length","result","client","directory","path","throwOnError","lifecycle","signal","aborted","data","value","selectSession","currentRequest","parentSessionID","parentID","allTaskParts","parts","flatMap","message","filter","visibleTaskParts","map","taskCallIDs","activeChildSessions","Set","Boolean","set","rememberLiveTasks","popupPart","popupSessionID","time","start","existing","releasePopup","ownership","token","closePopup","ui","dialog","clear","showPopup","Symbol","replace","unregister","timer","syncCurrentSession","has","refreshSession","push","event","properties","info","setInterval","clearInterval","dispose","_el$43","_el$44","_el$45","_el$47","_c$3","_el$48","each","_v$15","_v$16","fg","tui","slots","register","order","sidebar_footer","_ctx","session_id","plugin"],"sources":["../src/tui.tsx"],"sourcesContent":["/** @jsxImportSource @opentui/solid */\n\nimport type { TuiPlugin, TuiPluginApi, TuiPluginModule } from \"@opencode-ai/plugin/tui\"\nimport type { Message, Part, Session } from \"@opencode-ai/sdk/v2\"\nimport { elapsedLabel } from \"./activity.js\"\nimport {\n canOpenTaskSession,\n isTaskPart,\n isVisibleTask,\n resolveTaskModel,\n taskAgent,\n taskDescription,\n taskModeLabel,\n taskModelLabel,\n taskSessionID,\n taskStatusLabel,\n taskVariantLabel,\n type VisibleTaskPart,\n} from \"./tasks.js\"\nimport { createEffect, createMemo, createSignal, For, on, onCleanup, onMount, Show } from \"solid-js\"\n\ntype TaskFallback = {\n part: VisibleTaskPart\n sessionID?: string\n session?: Session\n}\n\ntype PopupOwnership = {\n callID: string\n token: symbol\n}\n\nfunction resolvedModel(api: TuiPluginApi, part: VisibleTaskPart, session: Session | undefined, sessionID?: string) {\n return resolveTaskModel(part, session, sessionID ? api.state.session.messages(sessionID) : [])\n}\n\nfunction modelName(api: TuiPluginApi, model: ReturnType<typeof resolvedModel>): string {\n const name = model\n ? api.state.provider.find((provider) => provider.id === model.providerID)?.models[model.modelID]?.name\n : undefined\n return taskModelLabel(model, name)\n}\n\nfunction TaskDetails(props: {\n api: TuiPluginApi\n callID: string\n currentSessionID: string\n fallbackPart: VisibleTaskPart\n tasksByCallID: () => Map<string, VisibleTaskPart>\n fallbackFor: (callID: string) => TaskFallback | undefined\n revision: () => number\n now: () => number\n startedAt: (part: VisibleTaskPart) => number\n close: () => void\n}) {\n const fallback = (): TaskFallback => {\n const known = props.fallbackFor(props.callID)\n if (known) return known\n const sessionID = taskSessionID(props.fallbackPart)\n return { part: props.fallbackPart, ...(sessionID ? { sessionID } : {}) }\n }\n const part = createMemo(() => {\n props.revision()\n return props.tasksByCallID().get(props.callID) ?? fallback().part\n })\n const childSessionID = () => taskSessionID(part() ?? fallback().part) ?? fallback().sessionID\n const childSession = () => {\n props.revision()\n const sessionID = childSessionID()\n return (sessionID ? props.api.state.session.get(sessionID) : undefined) ?? fallback().session\n }\n const model = createMemo(() => {\n props.revision()\n return resolvedModel(props.api, part() ?? fallback().part, childSession(), childSessionID())\n })\n const canOpen = () => canOpenTaskSession(childSessionID(), props.currentSessionID)\n const openSession = () => {\n const sessionID = childSessionID()\n if (!canOpen() || !sessionID) return\n props.api.route.navigate(\"session\", { sessionID })\n props.close()\n }\n\n return (\n <box width=\"100%\" flexDirection=\"column\" padding={1} gap={1}>\n <text fg={props.api.theme.current.text}>\n <b>Subagent details</b>\n </text>\n <box flexDirection=\"column\">\n <text fg={props.api.theme.current.text}>Agent: {taskAgent(part() ?? fallback().part)}</text>\n <text fg={props.api.theme.current.textMuted} wrapMode=\"word\">\n Assigned task: {taskDescription(part() ?? fallback().part)}\n </text>\n <text fg={props.api.theme.current.textMuted}>\n Status: {taskStatusLabel(part() ?? fallback().part, childSessionID() ? props.api.state.session.status(childSessionID()!) : undefined)}\n </text>\n <text fg={props.api.theme.current.textMuted}>\n Model: {modelName(props.api, model())}\n </text>\n <text fg={props.api.theme.current.textMuted}>\n Effort/variant: {taskVariantLabel(model()) ?? \"pending\"}\n </text>\n <text fg={props.api.theme.current.textMuted}>\n Elapsed: {elapsedLabel(props.now() - props.startedAt(part() ?? fallback().part))}\n </text>\n <text fg={props.api.theme.current.textMuted}>Child session ID: {childSessionID() ?? \"Waiting for child session\"}</text>\n <text fg={props.api.theme.current.textMuted}>Mode: {taskModeLabel(part() ?? fallback().part)}</text>\n </box>\n <box flexDirection=\"row\" gap={2}>\n <box onMouseUp={openSession}>\n <text fg={canOpen() ? props.api.theme.current.primary : props.api.theme.current.textMuted}>\n <b>Open Session</b>\n </text>\n </box>\n <box onMouseUp={props.close}>\n <text fg={props.api.theme.current.primary}>\n <b>Close</b>\n </text>\n </box>\n </box>\n </box>\n )\n}\n\nfunction TaskCard(props: {\n api: TuiPluginApi\n callID: string\n tasksByCallID: () => Map<string, VisibleTaskPart>\n fallbackFor: (callID: string) => TaskFallback | undefined\n remember: (part: VisibleTaskPart) => void\n revision: () => number\n now: () => number\n startedAt: (part: VisibleTaskPart) => number\n openPopup: (callID: string, part: VisibleTaskPart) => void\n}) {\n // The call ID is stable, while the actual ToolPart is re-read after each event.\n // This prevents cards from retaining a stale part object after a state update.\n const livePart = createMemo(() => props.tasksByCallID().get(props.callID))\n const part = () => livePart() ?? props.fallbackFor(props.callID)?.part\n const childSession = () => {\n props.revision()\n const current = part()\n if (!current) return undefined\n const sessionID = taskSessionID(current)\n return sessionID ? props.api.state.session.get(sessionID) : undefined\n }\n const model = () => {\n props.revision()\n const current = part()\n return current ? resolvedModel(props.api, current, childSession(), taskSessionID(current)) : undefined\n }\n const elapsed = () => {\n const current = part()\n return current ? elapsedLabel(props.now() - props.startedAt(current)) : \"\"\n }\n const openDetails = () => {\n if (props.api.renderer.getSelection()?.getSelectedText()) return\n const part = livePart()\n if (!part) return\n props.remember(part)\n props.openPopup(props.callID, part)\n }\n\n return (\n <box width=\"100%\" height={2} overflow=\"hidden\" onMouseUp={openDetails}>\n <box width=\"100%\" height={1} flexDirection=\"row\" overflow=\"hidden\">\n <text flexGrow={1} flexShrink={1} minWidth={0} wrapMode=\"none\" truncate fg={props.api.theme.current.text}>\n <b>{part() ? taskAgent(part()!) : \"subagent\"}</b>\n </text>\n <box\n flexShrink={1}\n minWidth={0}\n maxWidth={28}\n marginLeft={1}\n flexDirection=\"row\"\n >\n <text flexGrow={1} flexShrink={1} minWidth={0} wrapMode=\"none\" truncate fg={props.api.theme.current.textMuted}>\n {modelName(props.api, model())}\n </text>\n <Show\n when={taskVariantLabel(model())}\n fallback={\n <Show when={model()}>\n <text flexShrink={0} marginLeft={1} wrapMode=\"none\" truncate fg={props.api.theme.current.textMuted}>\n · pending\n </text>\n </Show>\n }\n >\n {(variant) => (\n <text flexShrink={0} marginLeft={1} wrapMode=\"none\" truncate fg={props.api.theme.current.textMuted}>\n · {variant()}\n </text>\n )}\n </Show>\n </box>\n </box>\n <box width=\"100%\" height={1} flexDirection=\"row\" overflow=\"hidden\">\n <text\n flexGrow={1}\n flexShrink={1}\n minWidth={0}\n wrapMode=\"none\"\n truncate\n fg={props.api.theme.current.textMuted}\n >\n {part() ? taskDescription(part()!) : \"Working\"}\n </text>\n <box width={8} flexShrink={0} justifyContent=\"flex-end\">\n <text wrapMode=\"none\" truncate fg={props.api.theme.current.textMuted}>\n {elapsed()}\n </text>\n </box>\n </box>\n </box>\n )\n}\n\nfunction RunningSubagents(props: { api: TuiPluginApi; sessionID: string }) {\n const [scopeSessionID, setScopeSessionID] = createSignal<string>()\n const [hydratedMessages, setHydratedMessages] = createSignal<ReadonlyArray<{ info: Message; parts: ReadonlyArray<Part> }>>([])\n const [revision, setRevision] = createSignal(0)\n const [now, setNow] = createSignal(Date.now())\n const firstSeen = new Map<string, number>()\n const fallbacks = new Map<string, TaskFallback>()\n const [openPopup, setOpenPopup] = createSignal<PopupOwnership>()\n let sessionRequest = 0\n\n const loadMessages = async (sessionID: string, request: number): Promise<void> => {\n if (props.api.state.session.messages(sessionID).length) return\n\n try {\n const result = await props.api.client.session.messages(\n { sessionID, directory: props.api.state.path.directory },\n { throwOnError: true },\n )\n if (props.api.lifecycle.signal.aborted || request !== sessionRequest || scopeSessionID() !== sessionID) return\n setHydratedMessages(result.data)\n setRevision((value) => value + 1)\n } catch {\n // Live session events can populate the public TUI state after a failed hydration.\n }\n }\n\n const selectSession = async (sessionID: string, known?: Session): Promise<void> => {\n const currentRequest = ++sessionRequest\n setScopeSessionID(undefined)\n setHydratedMessages([])\n let session = known ?? props.api.state.session.get(sessionID)\n\n if (!session) {\n try {\n const result = await props.api.client.session.get(\n { sessionID, directory: props.api.state.path.directory },\n { throwOnError: true },\n )\n session = result.data\n } catch {\n // Leave the scope unset so a failed child lookup cannot show its own tasks.\n // A later session event retries after local state is populated.\n return\n }\n }\n\n if (props.api.lifecycle.signal.aborted || currentRequest !== sessionRequest) return\n const parentSessionID = session.parentID ?? session.id\n setScopeSessionID(parentSessionID)\n setRevision((value) => value + 1)\n void loadMessages(parentSessionID, currentRequest)\n }\n\n createEffect(on(() => props.sessionID, (sessionID) => void selectSession(sessionID)))\n\n const allTaskParts = createMemo(() => {\n revision()\n const sessionID = scopeSessionID()\n if (!sessionID) return []\n\n const messages = props.api.state.session.messages(sessionID)\n const parts = messages.length\n ? messages.flatMap((message) => props.api.state.part(message.id))\n : hydratedMessages().flatMap((message) => message.parts)\n return parts.filter(isTaskPart)\n })\n const visibleTaskParts = createMemo(() => allTaskParts().filter((part) => isVisibleTask(part, props.api.state.session.status)))\n // Popups need the direct parent's complete/error parts too, even after their\n // visible card has gone away.\n const tasksByCallID = createMemo(() => new Map(allTaskParts().map((part) => [part.callID, part])))\n const taskCallIDs = createMemo(() => visibleTaskParts().map((part) => part.callID))\n const activeChildSessions = createMemo(\n () => new Set(visibleTaskParts().map(taskSessionID).filter((sessionID): sessionID is string => Boolean(sessionID))),\n )\n\n const remember = (part: VisibleTaskPart): void => {\n const sessionID = taskSessionID(part)\n const session = sessionID ? props.api.state.session.get(sessionID) : undefined\n fallbacks.set(part.callID, { part, ...(sessionID ? { sessionID } : {}), ...(session ? { session } : {}) })\n }\n const rememberLiveTasks = () => {\n revision()\n for (const part of allTaskParts()) remember(part)\n }\n createEffect(rememberLiveTasks)\n\n const popupPart = createMemo(() => {\n revision()\n const callID = openPopup()?.callID\n return callID ? tasksByCallID().get(callID) ?? fallbacks.get(callID)?.part : undefined\n })\n const popupSessionID = createMemo(() => {\n const callID = openPopup()?.callID\n const part = popupPart()\n return (part ? taskSessionID(part) : undefined) ?? (callID ? fallbacks.get(callID)?.sessionID : undefined)\n })\n\n const startedAt = (part: VisibleTaskPart): number => {\n if (part.state.status !== \"pending\") return part.state.time.start\n const existing = firstSeen.get(part.callID)\n if (existing !== undefined) return existing\n const value = now()\n firstSeen.set(part.callID, value)\n return value\n }\n\n const releasePopup = (ownership: PopupOwnership): void => {\n if (openPopup()?.token === ownership.token) setOpenPopup(undefined)\n }\n const closePopup = (ownership: PopupOwnership): void => {\n if (openPopup()?.token !== ownership.token) return\n setOpenPopup(undefined)\n props.api.ui.dialog.clear()\n }\n const showPopup = (callID: string, part: VisibleTaskPart): void => {\n const ownership = { callID, token: Symbol(callID) }\n setOpenPopup(ownership)\n props.api.ui.dialog.replace(() => (\n <TaskDetails\n api={props.api}\n callID={callID}\n currentSessionID={props.sessionID}\n fallbackPart={part}\n tasksByCallID={tasksByCallID}\n fallbackFor={(id) => fallbacks.get(id)}\n revision={revision}\n now={now}\n startedAt={startedAt}\n close={() => closePopup(ownership)}\n />\n ), () => releasePopup(ownership))\n }\n\n const unregister: Array<() => void> = []\n let timer: ReturnType<typeof setInterval> | undefined\n\n onMount(() => {\n const syncCurrentSession = (session: Session) => {\n if (session.id === props.sessionID) void selectSession(session.id, session)\n if (session.parentID === scopeSessionID() || activeChildSessions().has(session.id) || session.id === popupSessionID()) {\n setRevision((value) => value + 1)\n }\n }\n const refreshSession = (sessionID: string) => {\n if (sessionID === scopeSessionID() || activeChildSessions().has(sessionID) || sessionID === popupSessionID()) {\n setRevision((value) => value + 1)\n }\n }\n\n unregister.push(\n props.api.event.on(\"session.created\", (event) => syncCurrentSession(event.properties.info)),\n props.api.event.on(\"session.updated\", (event) => syncCurrentSession(event.properties.info)),\n props.api.event.on(\"message.updated\", (event) => refreshSession(event.properties.sessionID)),\n props.api.event.on(\"message.part.updated\", (event) => refreshSession(event.properties.sessionID)),\n props.api.event.on(\"message.part.removed\", (event) => refreshSession(event.properties.sessionID)),\n )\n timer = setInterval(() => setNow(Date.now()), 1_000)\n })\n\n onCleanup(() => {\n sessionRequest += 1\n if (timer) clearInterval(timer)\n for (const dispose of unregister) dispose()\n const ownership = openPopup()\n if (ownership) closePopup(ownership)\n })\n\n return (\n <box overflow=\"hidden\">\n <text fg={props.api.theme.current.text}>\n <b>Subagents</b>\n <span style={{ fg: props.api.theme.current.textMuted }}>\n {visibleTaskParts().length ? ` (${visibleTaskParts().length} running)` : \"\"}\n </span>\n </text>\n\n <Show\n when={taskCallIDs().length > 0}\n fallback={<text fg={props.api.theme.current.textMuted}>No subagent running</text>}\n >\n <For each={taskCallIDs()}>\n {(callID) => (\n <TaskCard\n api={props.api}\n callID={callID}\n tasksByCallID={tasksByCallID}\n fallbackFor={(id) => fallbacks.get(id)}\n remember={remember}\n revision={revision}\n now={now}\n startedAt={startedAt}\n openPopup={showPopup}\n />\n )}\n </For>\n </Show>\n </box>\n )\n}\n\nconst tui: TuiPlugin = async (api) => {\n api.slots.register({\n order: 90,\n slots: {\n sidebar_footer(_ctx, props) {\n return <RunningSubagents api={api} sessionID={props.session_id} />\n },\n },\n })\n}\n\nconst plugin = {\n id: \"opencode-subagents-sidebar-plugin\",\n tui,\n} satisfies TuiPluginModule\n\nexport default plugin\n"],"mappings":"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","ignoreList":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-subagents-sidebar-plugin",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "OpenCode TUI sidebar footer for active subagents.",
5
5
  "keywords": [
6
6
  "opencode",