@cjhyy/code-shell-core 0.8.1 → 0.8.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.
@@ -118,14 +118,47 @@ export declare const SettingsSchema: z.ZodObject<{
118
118
  * Default on.
119
119
  */
120
120
  memoryAutoExtract: z.ZodDefault<z.ZodBoolean>;
121
+ /**
122
+ * Mimi-only presentation and standing preferences. These are injected
123
+ * only into Pet manager turns; ordinary work Sessions continue to use
124
+ * the separate agent.* personalization fields above.
125
+ */
126
+ personalization: z.ZodOptional<z.ZodObject<{
127
+ responseLanguage: z.ZodOptional<z.ZodString>;
128
+ userProfile: z.ZodOptional<z.ZodString>;
129
+ communicationStyle: z.ZodOptional<z.ZodString>;
130
+ customInstructions: z.ZodOptional<z.ZodString>;
131
+ }, "strip", z.ZodTypeAny, {
132
+ responseLanguage?: string | undefined;
133
+ userProfile?: string | undefined;
134
+ communicationStyle?: string | undefined;
135
+ customInstructions?: string | undefined;
136
+ }, {
137
+ responseLanguage?: string | undefined;
138
+ userProfile?: string | undefined;
139
+ communicationStyle?: string | undefined;
140
+ customInstructions?: string | undefined;
141
+ }>>;
121
142
  }, "strip", z.ZodTypeAny, {
122
143
  showExternalCodexSessions: boolean;
123
144
  showExternalClaudeSessions: boolean;
124
145
  memoryAutoExtract: boolean;
146
+ personalization?: {
147
+ responseLanguage?: string | undefined;
148
+ userProfile?: string | undefined;
149
+ communicationStyle?: string | undefined;
150
+ customInstructions?: string | undefined;
151
+ } | undefined;
125
152
  }, {
126
153
  showExternalCodexSessions?: boolean | undefined;
127
154
  showExternalClaudeSessions?: boolean | undefined;
128
155
  memoryAutoExtract?: boolean | undefined;
156
+ personalization?: {
157
+ responseLanguage?: string | undefined;
158
+ userProfile?: string | undefined;
159
+ communicationStyle?: string | undefined;
160
+ customInstructions?: string | undefined;
161
+ } | undefined;
129
162
  }>>;
130
163
  /**
131
164
  * Image generation is a general capability, decoupled from LLM providers
@@ -1109,14 +1142,47 @@ export declare const SettingsSchema: z.ZodObject<{
1109
1142
  * Default on.
1110
1143
  */
1111
1144
  memoryAutoExtract: z.ZodDefault<z.ZodBoolean>;
1145
+ /**
1146
+ * Mimi-only presentation and standing preferences. These are injected
1147
+ * only into Pet manager turns; ordinary work Sessions continue to use
1148
+ * the separate agent.* personalization fields above.
1149
+ */
1150
+ personalization: z.ZodOptional<z.ZodObject<{
1151
+ responseLanguage: z.ZodOptional<z.ZodString>;
1152
+ userProfile: z.ZodOptional<z.ZodString>;
1153
+ communicationStyle: z.ZodOptional<z.ZodString>;
1154
+ customInstructions: z.ZodOptional<z.ZodString>;
1155
+ }, "strip", z.ZodTypeAny, {
1156
+ responseLanguage?: string | undefined;
1157
+ userProfile?: string | undefined;
1158
+ communicationStyle?: string | undefined;
1159
+ customInstructions?: string | undefined;
1160
+ }, {
1161
+ responseLanguage?: string | undefined;
1162
+ userProfile?: string | undefined;
1163
+ communicationStyle?: string | undefined;
1164
+ customInstructions?: string | undefined;
1165
+ }>>;
1112
1166
  }, "strip", z.ZodTypeAny, {
1113
1167
  showExternalCodexSessions: boolean;
1114
1168
  showExternalClaudeSessions: boolean;
1115
1169
  memoryAutoExtract: boolean;
1170
+ personalization?: {
1171
+ responseLanguage?: string | undefined;
1172
+ userProfile?: string | undefined;
1173
+ communicationStyle?: string | undefined;
1174
+ customInstructions?: string | undefined;
1175
+ } | undefined;
1116
1176
  }, {
1117
1177
  showExternalCodexSessions?: boolean | undefined;
1118
1178
  showExternalClaudeSessions?: boolean | undefined;
1119
1179
  memoryAutoExtract?: boolean | undefined;
1180
+ personalization?: {
1181
+ responseLanguage?: string | undefined;
1182
+ userProfile?: string | undefined;
1183
+ communicationStyle?: string | undefined;
1184
+ customInstructions?: string | undefined;
1185
+ } | undefined;
1120
1186
  }>>;
1121
1187
  /**
1122
1188
  * Image generation is a general capability, decoupled from LLM providers
@@ -2100,14 +2166,47 @@ export declare const SettingsSchema: z.ZodObject<{
2100
2166
  * Default on.
2101
2167
  */
2102
2168
  memoryAutoExtract: z.ZodDefault<z.ZodBoolean>;
2169
+ /**
2170
+ * Mimi-only presentation and standing preferences. These are injected
2171
+ * only into Pet manager turns; ordinary work Sessions continue to use
2172
+ * the separate agent.* personalization fields above.
2173
+ */
2174
+ personalization: z.ZodOptional<z.ZodObject<{
2175
+ responseLanguage: z.ZodOptional<z.ZodString>;
2176
+ userProfile: z.ZodOptional<z.ZodString>;
2177
+ communicationStyle: z.ZodOptional<z.ZodString>;
2178
+ customInstructions: z.ZodOptional<z.ZodString>;
2179
+ }, "strip", z.ZodTypeAny, {
2180
+ responseLanguage?: string | undefined;
2181
+ userProfile?: string | undefined;
2182
+ communicationStyle?: string | undefined;
2183
+ customInstructions?: string | undefined;
2184
+ }, {
2185
+ responseLanguage?: string | undefined;
2186
+ userProfile?: string | undefined;
2187
+ communicationStyle?: string | undefined;
2188
+ customInstructions?: string | undefined;
2189
+ }>>;
2103
2190
  }, "strip", z.ZodTypeAny, {
2104
2191
  showExternalCodexSessions: boolean;
2105
2192
  showExternalClaudeSessions: boolean;
2106
2193
  memoryAutoExtract: boolean;
2194
+ personalization?: {
2195
+ responseLanguage?: string | undefined;
2196
+ userProfile?: string | undefined;
2197
+ communicationStyle?: string | undefined;
2198
+ customInstructions?: string | undefined;
2199
+ } | undefined;
2107
2200
  }, {
2108
2201
  showExternalCodexSessions?: boolean | undefined;
2109
2202
  showExternalClaudeSessions?: boolean | undefined;
2110
2203
  memoryAutoExtract?: boolean | undefined;
2204
+ personalization?: {
2205
+ responseLanguage?: string | undefined;
2206
+ userProfile?: string | undefined;
2207
+ communicationStyle?: string | undefined;
2208
+ customInstructions?: string | undefined;
2209
+ } | undefined;
2111
2210
  }>>;
2112
2211
  /**
2113
2212
  * Image generation is a general capability, decoupled from LLM providers
@@ -116,6 +116,19 @@ export const SettingsSchema = z
116
116
  * Default on.
117
117
  */
118
118
  memoryAutoExtract: z.boolean().default(true),
119
+ /**
120
+ * Mimi-only presentation and standing preferences. These are injected
121
+ * only into Pet manager turns; ordinary work Sessions continue to use
122
+ * the separate agent.* personalization fields above.
123
+ */
124
+ personalization: z
125
+ .object({
126
+ responseLanguage: z.string().max(120).optional(),
127
+ userProfile: z.string().max(2_000).optional(),
128
+ communicationStyle: z.string().max(2_000).optional(),
129
+ customInstructions: z.string().max(6_000).optional(),
130
+ })
131
+ .optional(),
119
132
  })
120
133
  .default({}),
121
134
  /**
@@ -8,9 +8,10 @@
8
8
  import { isRegisteredMcpToolAllowed } from "../mcp-tool-policy.js";
9
9
  export const toolSearchToolDef = {
10
10
  name: "ToolSearch",
11
- description: "Search for and discover available tools by name or keyword. " +
11
+ description: "Search only the tools available in the current Session context by name or keyword. " +
12
12
  "Some tools (especially from MCP servers) are deferred — their full schemas " +
13
- "are only loaded when you search for them. Use this to find the right tool.",
13
+ "are only loaded when you search for them. If an exact tool is reported unavailable, " +
14
+ "do not retry unless the Session context changes.",
14
15
  inputSchema: {
15
16
  type: "object",
16
17
  properties: {
@@ -37,6 +38,18 @@ export async function toolSearchTool(args, ctx) {
37
38
  // returning the wrong tool set. `|| 5` only caught 0/NaN, not negatives.
38
39
  const rawMax = args.max_results;
39
40
  const maxResults = Math.min(typeof rawMax === "number" && rawMax > 0 ? rawMax : 5, 20);
41
+ const currentDefinitions = ctx.searchableToolDefinitions;
42
+ if (currentDefinitions) {
43
+ const currentTools = currentDefinitions.map((definition) => definitionToSearchableTool(definition, ctx.toolRegistry));
44
+ if (query.startsWith("select:")) {
45
+ const names = query
46
+ .slice(7)
47
+ .split(",")
48
+ .map((name) => name.trim());
49
+ return matchCurrentExact(currentTools, names);
50
+ }
51
+ return searchCurrentByKeyword(currentTools, query, maxResults);
52
+ }
40
53
  // The tool registry is worker-SHARED (B1): it holds MCP tools registered by
41
54
  // every session, including servers another project enabled. ToolSearch is a
42
55
  // side door around the per-turn toolDefs filter — without this gate it would
@@ -63,6 +76,32 @@ export async function toolSearchTool(args, ctx) {
63
76
  // Keyword search
64
77
  return searchByKeyword(ctx.toolRegistry, query, maxResults, visible);
65
78
  }
79
+ function definitionToSearchableTool(definition, registry) {
80
+ const registered = registry.getTool(definition.name);
81
+ return {
82
+ name: definition.name,
83
+ description: definition.description,
84
+ inputSchema: definition.inputSchema,
85
+ source: registered?.source ?? "builtin",
86
+ ...(registered?.serverName ? { serverName: registered.serverName } : {}),
87
+ ...(registered?.mcpToolName ? { mcpToolName: registered.mcpToolName } : {}),
88
+ permissionDefault: registered?.permissionDefault ?? "ask",
89
+ };
90
+ }
91
+ function matchCurrentExact(tools, names) {
92
+ const byName = new Map(tools.map((tool) => [tool.name, tool]));
93
+ return names
94
+ .map((name) => {
95
+ const tool = byName.get(name);
96
+ return tool
97
+ ? formatTool(tool)
98
+ : `Tool "${name}" is not available in the current Session context. Do not retry unless the Session context changes.`;
99
+ })
100
+ .join("\n\n---\n\n");
101
+ }
102
+ function searchCurrentByKeyword(tools, query, maxResults) {
103
+ return searchDetailedTools(tools, query, maxResults);
104
+ }
66
105
  function matchExact(registry, names, visible) {
67
106
  const results = [];
68
107
  for (const name of names) {
@@ -78,6 +117,9 @@ function matchExact(registry, names, visible) {
78
117
  }
79
118
  function searchByKeyword(registry, query, maxResults, visible) {
80
119
  const allTools = registry.listToolsDetailed().filter(visible);
120
+ return searchDetailedTools(allTools, query, maxResults);
121
+ }
122
+ function searchDetailedTools(allTools, query, maxResults) {
81
123
  const queryLower = query.toLowerCase();
82
124
  const keywords = queryLower.split(/\s+/);
83
125
  // Score each tool
@@ -12,7 +12,7 @@
12
12
  * Tools that don't need any context (Read/Write/Bash/...) just ignore
13
13
  * the second argument; the type is purely additive.
14
14
  */
15
- import type { LLMConfig, StreamCallback, TokenUsage } from "../types.js";
15
+ import type { LLMConfig, StreamCallback, TokenUsage, ToolDefinition } from "../types.js";
16
16
  import type { ModelPool } from "../llm/model-pool.js";
17
17
  import type { ToolRegistry } from "./registry.js";
18
18
  import type { AgentPresetName } from "../preset/index.js";
@@ -225,6 +225,12 @@ export interface ToolRunYieldController {
225
225
  export interface ToolContext {
226
226
  /** Active working directory for this Engine. */
227
227
  cwd: string;
228
+ /**
229
+ * True when this call belongs to an external Agent Runtime rather than the
230
+ * native Engine loop. Async handoff tools use this to keep their result on
231
+ * the current turn instead of queueing a wake-up only the Engine can consume.
232
+ */
233
+ externalRuntime?: boolean;
228
234
  /**
229
235
  * Active digital-human profile's portable memory root. Present only when
230
236
  * the resolved WorkspaceProfile enables portableMemory for this run.
@@ -242,6 +248,13 @@ export interface ToolContext {
242
248
  modelPool?: ModelPool;
243
249
  /** Tool registry (ToolSearch reads this to enumerate available tools). */
244
250
  toolRegistry: ToolRegistry;
251
+ /**
252
+ * Final per-turn tool surface after availability guards, feature flags,
253
+ * behavior-profile allowlists, plan-mode filtering, and definition rewrites.
254
+ * ToolSearch must prefer this list over the worker-shared registry so it
255
+ * cannot advertise a tool the current Session cannot actually call.
256
+ */
257
+ searchableToolDefinitions?: readonly ToolDefinition[];
245
258
  /** Opaque services contributed by capability modules, keyed by capability id. */
246
259
  capabilityServices?: Readonly<Record<string, unknown>>;
247
260
  /**
@@ -9,15 +9,10 @@ export const FIRST_PHASE_EXPOSURE_RATIONALE = [
9
9
  tool: "Panel",
10
10
  kind: "host-loopback",
11
11
  status: "exposed",
12
- reason: "Only list/open/tools. These are read-or-focus, and they have a broadcast " +
13
- "fallback, so they work without an owning window. invoke stays out for now " +
14
- "for a DIFFERENT reason than originally recorded: the owner claim it was " +
15
- "waiting on now exists and is wired (ExternalRuntimeService claims before " +
16
- "the runtime starts), so the blocker is no longer technical. What is still " +
17
- "missing is a per-Panel-App risk review — invoke runs third-party Panel App " +
18
- "code with whatever arguments the model supplies, and argsPatterns cannot " +
19
- "constrain a nested payload. Enabling it is a policy decision, not a wiring " +
20
- "one, and it belongs to whoever reviews the first Panel App to be trusted.",
12
+ reason: "list/open/tools plus invoke for the reviewed job-hunt-hq tool catalog. The " +
13
+ "invoke exception is constrained by panel id and exact tool name; the Panel " +
14
+ "App manifest validates the nested payload. Other Panel Apps remain " +
15
+ "discovery/focus-only until they receive their own review.",
21
16
  },
22
17
  {
23
18
  // NOTE the names: there is no tool called "Browser". The registry exposes
@@ -65,11 +60,10 @@ export const FIRST_PHASE_EXPOSURE_RATIONALE = [
65
60
  "external runtime. If that approval is ever made skippable, this entry must " +
66
61
  "go back to excluded.",
67
62
  },
68
- // ── Still excluded, and for a different KIND of reason ───────────
69
- // The four below are not held back out of caution — widening the allowlist
70
- // does not make them work. Each is excluded by a structural property that
71
- // would have to be designed away first, so listing them would produce a tool
72
- // that is advertised and then fails or misbehaves.
63
+ // ── Delegation and state-machine exceptions ──────────────────────
64
+ // Agent and the two plan-state tools remain structurally excluded. DriveAgent
65
+ // is the reviewed exception because the external host forces it into a
66
+ // foreground, one-level handoff with an observable result.
73
67
  {
74
68
  tool: "Agent",
75
69
  kind: "self-contained",
@@ -82,8 +76,21 @@ export const FIRST_PHASE_EXPOSURE_RATIONALE = [
82
76
  {
83
77
  tool: "DriveAgent",
84
78
  kind: "self-contained",
85
- status: "excluded",
86
- reason: "Same recursion hazard as Agent (§12.5).",
79
+ status: "exposed",
80
+ reason: "Delegates one bounded task to an installed Codex/Claude CLI. External " +
81
+ "sessions force foreground execution and disable automatic background " +
82
+ "handoff, so the parent turn receives the result instead of losing a wake-up " +
83
+ "inside the native Engine queue. The child CLI does not inherit this host " +
84
+ "bridge, which bounds nesting at one level; the outer call still requires " +
85
+ "the normal DriveAgent approval.",
86
+ },
87
+ {
88
+ tool: "DriveAgentJobs",
89
+ kind: "self-contained",
90
+ status: "exposed",
91
+ reason: "Lets the runtime inspect or cancel retained DriveAgent jobs. New external " +
92
+ "delegations run in the foreground, but retained jobs from the same Session " +
93
+ "still need an observable cleanup surface.",
87
94
  },
88
95
  {
89
96
  tool: "EnterPlanMode",
@@ -218,17 +225,32 @@ export const FIRST_PHASE_EXPOSURE_RATIONALE = [
218
225
  * This is a second, independent layer from the tool's own
219
226
  * `defaultPermissionRules`: those decide allow/ask for a call that IS permitted,
220
227
  * while this decides whether the action is reachable from an external runtime at
221
- * all. Both are narrowed to read-only actions in phase one, and `Panel.invoke`
222
- * additionally fails closed on owner routing three independent barriers, by
223
- * design.
228
+ * all. `Panel.invoke` additionally fails closed on owner routing. Its exception
229
+ * here is limited to the reviewed job-hunt-hq panel and exact tool names; write
230
+ * operations still pass through Panel's schema, owner routing, permission rules,
231
+ * and approval handling.
224
232
  */
233
+ const JOB_HUNT_TOOL_NAMES = [
234
+ "get_job_search_context",
235
+ "save_candidate_context",
236
+ "save_job_opportunities",
237
+ "save_workflow_progress",
238
+ "save_job_research",
239
+ "save_interview_question_set",
240
+ "save_preparation_plan",
241
+ "save_interview_debrief",
242
+ "save_resume_draft",
243
+ ].join("|");
244
+ const PANEL_ARGUMENT_PATTERNS = [
245
+ { action: "list|open|tools" },
246
+ {
247
+ action: "invoke",
248
+ panel_id: "panel-app:job-hunt-hq",
249
+ tool_name: JOB_HUNT_TOOL_NAMES,
250
+ },
251
+ ];
225
252
  const FIRST_PHASE_ARGS_PATTERNS = new Map([
226
- // Panel.invoke remains the one action-level restriction. It runs third-party
227
- // Panel App code with whatever arguments the model supplies, and argsPatterns
228
- // cannot constrain a nested payload — so unlike every tool widened above, the
229
- // authorization layer genuinely cannot see what is being authorized. Enabling
230
- // it belongs to whoever reviews the first Panel App to be trusted.
231
- ["Panel", { action: "list|open|tools" }],
253
+ ["Panel", PANEL_ARGUMENT_PATTERNS],
232
254
  ]);
233
255
  /**
234
256
  * `ReadonlySet` / `ReadonlyMap` are compile-time only — the underlying `Set` and
@@ -299,6 +321,8 @@ export const FIRST_PHASE_EXPOSURE = Object.freeze({
299
321
  toolNames: frozenSet(FIRST_PHASE_EXPOSURE_RATIONALE.filter((entry) => entry.status === "exposed").map((entry) => entry.tool)),
300
322
  argsPatterns: frozenMap([...FIRST_PHASE_ARGS_PATTERNS].map(([tool, patterns]) => [
301
323
  tool,
302
- Object.freeze({ ...patterns }),
324
+ Array.isArray(patterns)
325
+ ? Object.freeze(patterns.map((pattern) => Object.freeze({ ...pattern })))
326
+ : Object.freeze({ ...patterns }),
303
327
  ])),
304
328
  });
@@ -61,7 +61,7 @@ export interface ExternalToolExposurePolicy {
61
61
  * Panel App) is the tool's own schema validation, not this. Do not treat an
62
62
  * `argsPatterns` entry as a sandbox for everything a tool might accept.
63
63
  */
64
- argsPatterns?: ReadonlyMap<string, Readonly<Record<string, string>>>;
64
+ argsPatterns?: ReadonlyMap<string, Readonly<Record<string, string>> | readonly Readonly<Record<string, string>>[]>;
65
65
  }
66
66
  export interface SessionToolHost {
67
67
  readonly businessSessionId: string;
@@ -3,6 +3,7 @@ import { PermissionClassifier } from "./permission.js";
3
3
  import { HookRegistry } from "../hooks/registry.js";
4
4
  import { buildToolVisibility } from "../engine/run-tooling.js";
5
5
  import { composePermissionRules } from "../engine/permission-controller.js";
6
+ import { PLAN_MODE_ALLOWED_TOOLS } from "./plan-mode-allowlist.js";
6
7
  const FORBIDDEN_MODES = new Set(["bypassPermissions", "dontAsk"]);
7
8
  /**
8
9
  * Whole-string match for an exposure pattern.
@@ -27,6 +28,10 @@ function matchesWholeValue(source, value) {
27
28
  function argsMatch(patterns, input) {
28
29
  if (!patterns)
29
30
  return true;
31
+ const alternatives = Array.isArray(patterns) ? patterns : [patterns];
32
+ return alternatives.some((alternative) => argsPatternMatches(alternative, input));
33
+ }
34
+ function argsPatternMatches(patterns, input) {
30
35
  for (const [key, source] of Object.entries(patterns)) {
31
36
  // Read own properties only: a model-supplied JSON body cannot smuggle a
32
37
  // match through the prototype chain.
@@ -81,6 +86,7 @@ export function createSessionToolHost(options) {
81
86
  // just rejected.
82
87
  ...options.contextOverrides,
83
88
  sessionId: options.businessSessionId,
89
+ externalRuntime: true,
84
90
  planMode: options.planMode,
85
91
  permissionMode: options.permissionMode,
86
92
  toolVisibility: buildToolVisibility(options.visibility),
@@ -106,7 +112,12 @@ export function createSessionToolHost(options) {
106
112
  return [];
107
113
  return registry
108
114
  .getToolDefinitions()
109
- .filter((definition) => exposure.toolNames.has(definition.name));
115
+ .filter((definition) => exposure.toolNames.has(definition.name))
116
+ .filter((definition) => !options.planMode || PLAN_MODE_ALLOWED_TOOLS.has(definition.name))
117
+ .filter((definition) => {
118
+ const guard = registry.getAvailabilityGuard(definition.name);
119
+ return !guard || guard(toolCtx.toolVisibility);
120
+ });
110
121
  },
111
122
  async execute(call, callSignal) {
112
123
  if (disposed) {
@@ -129,6 +140,19 @@ export function createSessionToolHost(options) {
129
140
  if (sessionSignal.aborted || callSignal?.aborted) {
130
141
  return failClosed(call.id, call.name, `Tool aborted before execution: ${call.name}`);
131
142
  }
143
+ const emit = async (event) => {
144
+ try {
145
+ await toolCtx.streamCallback?.(event);
146
+ }
147
+ catch {
148
+ // Stream projection is observational; a broken renderer/recorder must
149
+ // not turn an authorized tool execution into an unrelated failure.
150
+ }
151
+ };
152
+ await emit({
153
+ type: "tool_use_start",
154
+ toolCall: { id: call.id, toolName: call.name, args: input },
155
+ });
132
156
  // Forward the per-call signal rather than only checking it at entry: an MCP
133
157
  // cancellation arriving mid-flight has to actually stop the work.
134
158
  //
@@ -139,20 +163,24 @@ export function createSessionToolHost(options) {
139
163
  // state. Calls without one use the shared executor unchanged.
140
164
  if (!callSignal) {
141
165
  // The one authorized path. Everything above only NARROWS what may reach it.
142
- return await executor.executeSingle({
166
+ const result = await executor.executeSingle({
143
167
  id: call.id,
144
168
  toolName: call.name,
145
169
  args: input,
146
170
  });
171
+ await emit({ type: "tool_result", result });
172
+ return result;
147
173
  }
148
174
  const scoped = new ToolExecutor(registry, permission, hooks);
149
175
  scoped.setContext(toolCtx);
150
176
  scoped.setSignal(AbortSignal.any([sessionSignal, callSignal]));
151
- return await scoped.executeSingle({
177
+ const result = await scoped.executeSingle({
152
178
  id: call.id,
153
179
  toolName: call.name,
154
180
  args: input,
155
181
  });
182
+ await emit({ type: "tool_result", result });
183
+ return result;
156
184
  },
157
185
  async dispose() {
158
186
  // Order matters (§13.4): stop accepting new calls, THEN abort in-flight
package/dist/types.d.ts CHANGED
@@ -298,9 +298,10 @@ export interface SessionState {
298
298
  /** User-fork lineage; deliberately separate from sub-agent ownership. */
299
299
  forkedFrom?: SessionForkLineage;
300
300
  /**
301
- * Temporary child sessions are persisted only while their owning surface is
302
- * alive. Ordinary resume/session pickers must omit them. Absent on legacy
303
- * sessions; desktop also recognizes its historical `qchat-*` namespace.
301
+ * Temporary child sessions live only in process memory. Ordinary
302
+ * resume/session pickers omit them, and closing/expiry forgets them instead
303
+ * of publishing state or transcript files. Absent on legacy sessions;
304
+ * desktop also recognizes its historical `qchat-*` namespace.
304
305
  */
305
306
  ephemeral?: boolean;
306
307
  /**
@@ -636,6 +637,9 @@ export type StreamEvent = {
636
637
  sessionCacheReadTokens?: number;
637
638
  sessionCacheCreationTokens?: number;
638
639
  sessionPromptTokens?: number;
640
+ /** Provider-reported completion tokens for the latest and whole thread. */
641
+ completionTokens?: number;
642
+ cumulativeCompletionTokens?: number;
639
643
  agentId?: string;
640
644
  } | {
641
645
  type: "background_agent_completed";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cjhyy/code-shell-core",
3
- "version": "0.8.1",
3
+ "version": "0.8.3",
4
4
  "description": "Core engine for code-shell — agent orchestration, tool execution, hooks, protocol. UI-agnostic.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",