@cjhyy/code-shell-core 0.6.0-rc.7 → 0.6.0-rc.9

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.
@@ -0,0 +1,93 @@
1
+ import { constants } from "node:fs";
2
+ import { access } from "node:fs/promises";
3
+ import { delimiter, isAbsolute, join } from "node:path";
4
+ const COMMON_POSIX_BIN_DIRS = [
5
+ "/opt/homebrew/bin",
6
+ "/usr/local/bin",
7
+ "/home/linuxbrew/.linuxbrew/bin",
8
+ "/usr/bin",
9
+ "/bin",
10
+ ];
11
+ function unique(entries) {
12
+ const seen = new Set();
13
+ const out = [];
14
+ for (const entry of entries) {
15
+ const trimmed = entry.trim();
16
+ if (!trimmed || seen.has(trimmed))
17
+ continue;
18
+ seen.add(trimmed);
19
+ out.push(trimmed);
20
+ }
21
+ return out;
22
+ }
23
+ function commonExecutableDirs(env = process.env) {
24
+ const home = env.HOME?.trim();
25
+ return unique([
26
+ ...COMMON_POSIX_BIN_DIRS,
27
+ ...(home
28
+ ? [join(home, ".bun", "bin"), join(home, ".local", "bin"), join(home, ".npm-global", "bin")]
29
+ : []),
30
+ ]);
31
+ }
32
+ export function isBareCommand(command) {
33
+ const trimmed = command.trim();
34
+ return !!trimmed && !trimmed.includes("/") && !trimmed.includes("\\") && !isAbsolute(trimmed);
35
+ }
36
+ export function isMissingCommandError(error) {
37
+ const err = error;
38
+ const message = typeof err.message === "string" ? err.message : String(error);
39
+ return err.code === "ENOENT" || /\bENOENT\b/i.test(message) || /command not found/i.test(message);
40
+ }
41
+ async function isExecutable(filePath) {
42
+ try {
43
+ await access(filePath, constants.X_OK);
44
+ return true;
45
+ }
46
+ catch {
47
+ return false;
48
+ }
49
+ }
50
+ export async function probeCommonExecutableLocations(command, env = process.env) {
51
+ if (!isBareCommand(command) || process.platform === "win32")
52
+ return [];
53
+ const found = [];
54
+ for (const dir of commonExecutableDirs(env)) {
55
+ const candidate = join(dir, command);
56
+ if (await isExecutable(candidate))
57
+ found.push(candidate);
58
+ }
59
+ return found;
60
+ }
61
+ function installGuidance(command) {
62
+ if (command === "node" || command === "npx")
63
+ return "Please install Node.js and restart CodeShell.";
64
+ if (command === "bun" || command === "bunx")
65
+ return "Please install Bun and restart CodeShell.";
66
+ return `Please install "${command}" and restart CodeShell.`;
67
+ }
68
+ export function classifyMcpStdioMissingCommand(command, foundPaths) {
69
+ const trimmed = command.trim();
70
+ if (foundPaths.length > 0) {
71
+ return [
72
+ `MCP stdio command "${trimmed}" failed to start: detected ${trimmed} at ${foundPaths[0]},`,
73
+ "but that directory was not available on PATH.",
74
+ "Login-shell PATH injection may have failed; restart CodeShell or configure this MCP command as an absolute path.",
75
+ ].join(" ");
76
+ }
77
+ return [
78
+ `MCP stdio command "${trimmed}" failed to start: ${trimmed} was not found on PATH or in common install locations.`,
79
+ installGuidance(trimmed),
80
+ ].join(" ");
81
+ }
82
+ export async function diagnoseMcpStdioMissingCommand(command, error, env = process.env) {
83
+ if (!isBareCommand(command) || !isMissingCommandError(error))
84
+ return null;
85
+ const foundPaths = await probeCommonExecutableLocations(command, env);
86
+ return {
87
+ message: classifyMcpStdioMissingCommand(command, foundPaths),
88
+ foundPaths,
89
+ };
90
+ }
91
+ export function previewPath(env = process.env) {
92
+ return (env.PATH ?? "").split(delimiter).filter(Boolean).join(delimiter);
93
+ }
package/dist/types.d.ts CHANGED
@@ -145,7 +145,19 @@ export interface SessionState {
145
145
  startedAt: number;
146
146
  model: string;
147
147
  provider: string;
148
+ /**
149
+ * Legacy/model-scoped usage summary. Some flows reset this accounting window
150
+ * (for example model switches), so it must not drive whole-session metrics.
151
+ */
148
152
  tokenUsage: TokenUsage;
153
+ /**
154
+ * Monotonic prompt-cache counters for the whole session. These only increase
155
+ * from session start and are separate from the resettable tokenUsage window.
156
+ * Optional on legacy state.json files; SessionManager normalizes them on load.
157
+ */
158
+ cumulativePromptTokens?: number;
159
+ cumulativeCacheReadTokens?: number;
160
+ cumulativeCacheCreationTokens?: number;
149
161
  turnCount: number;
150
162
  /**
151
163
  * Conversation-turn counter where ONE user message = one turn (incremented in
@@ -391,7 +403,7 @@ export type StreamEvent = {
391
403
  summary: string;
392
404
  } | {
393
405
  type: "context_compact";
394
- strategy: "micro" | "summary" | "window" | "snip" | "emergency";
406
+ strategy: "micro" | "summary" | "window" | "snip" | "emergency" | "compacted";
395
407
  before: number;
396
408
  after: number;
397
409
  agentId?: string;
@@ -407,6 +419,24 @@ export type StreamEvent = {
407
419
  */
408
420
  cacheReadTokens?: number;
409
421
  cacheCreationTokens?: number;
422
+ /**
423
+ * Prompt-cache metrics for the current turn only. These are reset at the
424
+ * start of each turn-loop iteration and sum every LLM response in that
425
+ * turn, including max-token continuations.
426
+ */
427
+ singleTurnPromptTokens?: number;
428
+ singleTurnCacheReadTokens?: number;
429
+ singleTurnCacheCreationTokens?: number;
430
+ singleTurnCacheHitRate?: number;
431
+ /**
432
+ * Whole-session monotonic prompt-cache counters/rate. Unlike the legacy
433
+ * session* fields below, these are not derived from the resettable
434
+ * tokenUsage accounting window.
435
+ */
436
+ cumulativePromptTokens?: number;
437
+ cumulativeCacheReadTokens?: number;
438
+ cumulativeCacheCreationTokens?: number;
439
+ cumulativeCacheHitRate?: number;
410
440
  /**
411
441
  * SESSION-CUMULATIVE cache counts (sum across every LLM response this
412
442
  * session, across runs and turns), emitted from the engine's turn
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cjhyy/code-shell-core",
3
- "version": "0.6.0-rc.7",
3
+ "version": "0.6.0-rc.9",
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",