@cjhyy/code-shell 0.1.0-alpha.3 → 0.1.5

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.
Files changed (156) hide show
  1. package/CHANGELOG.md +77 -0
  2. package/dist/anthropic-IBTI4WL2.cjs +10 -0
  3. package/dist/anthropic-PRZZKHEZ.js +10 -0
  4. package/dist/arena/index.cjs +7 -6
  5. package/dist/arena/index.js +6 -5
  6. package/dist/arena/model-presets.d.ts +10 -1
  7. package/dist/{arena-HHDYYVHJ.cjs → arena-KBQOPLFV.cjs} +25 -23
  8. package/dist/{arena-ENHBHB2W.js → arena-O2L4TN6A.js} +9 -7
  9. package/dist/{chunk-SW3L7HIM.js → chunk-2EP3CLEN.js} +2 -2
  10. package/dist/{chunk-EL2RL5DG.cjs → chunk-2YW4FPFG.cjs} +2 -2
  11. package/dist/chunk-3OA5G4TM.js +47 -0
  12. package/dist/chunk-52LGZKT3.cjs +47 -0
  13. package/dist/{chunk-KOGV6PDQ.cjs → chunk-55XGPMAP.cjs} +44 -9
  14. package/dist/chunk-5ECBT4YA.js +450 -0
  15. package/dist/{chunk-YD7XTI7T.cjs → chunk-6QVAYW7C.cjs} +116 -28
  16. package/dist/{chunk-SCDKLTN3.js → chunk-6S4BJ65N.js} +5 -4
  17. package/dist/{chunk-ZLPJJZUW.js → chunk-76HYEPDM.js} +2 -2
  18. package/dist/{chunk-TDXBHD24.js → chunk-76W334S4.js} +2 -2
  19. package/dist/{chunk-GZBD6QRS.cjs → chunk-7EG3V4JY.cjs} +13 -12
  20. package/dist/{chunk-LMEKCQX4.js → chunk-7JVTYEEC.js} +6 -6
  21. package/dist/{chunk-ID6EJUHP.js → chunk-7K6SDRRF.js} +1262 -212
  22. package/dist/{chunk-5C5HIOML.js → chunk-7Y6S3OCX.js} +109 -21
  23. package/dist/{chunk-VIPLU4RY.cjs → chunk-A5LCRPDP.cjs} +4 -4
  24. package/dist/{chunk-F5BS3GUC.js → chunk-BSW22MPA.js} +39 -4
  25. package/dist/{chunk-VWFET3MG.cjs → chunk-BUU5PZK2.cjs} +1474 -423
  26. package/dist/{chunk-HOXQLX5R.cjs → chunk-BWTOS5BH.cjs} +444 -103
  27. package/dist/{chunk-ZRVPCXI7.js → chunk-BXCY2FSE.js} +2 -1
  28. package/dist/{chunk-Y7TSCDF6.js → chunk-C5YQBIRK.js} +347 -6
  29. package/dist/{chunk-C7C7ZZY4.cjs → chunk-HEKQCI7B.cjs} +10 -10
  30. package/dist/{chunk-JHXNOB5G.cjs → chunk-HS2MFNUC.cjs} +6 -6
  31. package/dist/{chunk-JHNCK7JP.cjs → chunk-IK4EWJBP.cjs} +4 -3
  32. package/dist/{chunk-M2QI5X3X.cjs → chunk-JMR33QVF.cjs} +2 -2
  33. package/dist/{chunk-YAFCN7ZW.cjs → chunk-KOVYSDHZ.cjs} +15 -15
  34. package/dist/{chunk-IJSHQGMP.cjs → chunk-KS3RYAYL.cjs} +4 -4
  35. package/dist/{chunk-DI7RDLOS.js → chunk-MD32R22I.js} +7 -4
  36. package/dist/chunk-MY5XHADU.cjs +216 -0
  37. package/dist/{chunk-OP57WUWQ.cjs → chunk-NUNC3VFB.cjs} +6 -6
  38. package/dist/{chunk-BF4LXLQV.cjs → chunk-QRM7IF2S.cjs} +133 -175
  39. package/dist/chunk-R47ROHGL.cjs +298 -0
  40. package/dist/{chunk-OUC2DFA7.js → chunk-RMYKO74M.js} +3 -3
  41. package/dist/{chunk-FUOKLKR2.js → chunk-SFXHZSRF.js} +1 -1
  42. package/dist/{chunk-2EUAE7AY.js → chunk-SIHHIQLO.js} +2 -2
  43. package/dist/{chunk-3CAZIWUA.cjs → chunk-SNT563K3.cjs} +9 -9
  44. package/dist/{chunk-SK62UVS6.js → chunk-T6VYG46N.js} +1 -1
  45. package/dist/{chunk-3QR52LL5.cjs → chunk-TUY2T5KP.cjs} +2 -2
  46. package/dist/{chunk-I57ZD5IQ.js → chunk-VIAGTYYW.js} +1 -1
  47. package/dist/{chunk-X2DNIMPC.cjs → chunk-VYL4EFRC.cjs} +32 -32
  48. package/dist/chunk-W22P377T.js +299 -0
  49. package/dist/chunk-WASS5YWB.js +215 -0
  50. package/dist/{chunk-FPFTIKEJ.js → chunk-XDIQWQJ4.js} +132 -174
  51. package/dist/{chunk-BUJ5KYCI.cjs → chunk-YIQBXAYU.cjs} +13 -13
  52. package/dist/{chunk-REFCCVDM.js → chunk-YJ77GQK5.js} +2 -2
  53. package/dist/chunk-YUI524OE.cjs +450 -0
  54. package/dist/{chunk-M2SVOKC6.js → chunk-ZBPSQCPU.js} +6 -6
  55. package/dist/cli/commands/builtin/export-md.d.ts +19 -0
  56. package/dist/cli/commands/builtin/init/detect.d.ts +25 -0
  57. package/dist/cli/commands/builtin/init/index.d.ts +19 -0
  58. package/dist/cli/main.cjs +2343 -1447
  59. package/dist/cli/main.js +2476 -1580
  60. package/dist/cli/migrate-models.d.ts +45 -0
  61. package/dist/cli/onboarding.d.ts +110 -5
  62. package/dist/cli/updater.d.ts +51 -4
  63. package/dist/client-base-HTF236ZD.cjs +9 -0
  64. package/dist/client-base-QKRKCOWB.js +9 -0
  65. package/dist/{compaction-YNWCEF7B.js → compaction-6VU2T643.js} +4 -2
  66. package/dist/compaction-OKUNTCA7.cjs +33 -0
  67. package/dist/context/compaction.d.ts +35 -3
  68. package/dist/context/manager.d.ts +40 -3
  69. package/dist/context/tool-result-storage.d.ts +96 -0
  70. package/dist/devtools-T2NIZBJK.cjs +6 -0
  71. package/dist/{devtools-IRQQPIRY.js → devtools-YXWHOVKR.js} +1 -1
  72. package/dist/engine/engine.d.ts +40 -0
  73. package/dist/engine/turn-loop.d.ts +6 -0
  74. package/dist/export-md-RXDW6F5W.cjs +135 -0
  75. package/dist/export-md-XXKZANW5.js +135 -0
  76. package/dist/file-history-KYPE3ECT.cjs +7 -0
  77. package/dist/file-history-LF4F7X26.js +7 -0
  78. package/dist/index.cjs +42 -22
  79. package/dist/index.d.ts +5 -2
  80. package/dist/index.js +40 -20
  81. package/dist/llm/client-base.d.ts +1 -1
  82. package/dist/llm/model-cache.d.ts +21 -0
  83. package/dist/llm/model-fetcher.d.ts +29 -0
  84. package/dist/llm/model-pool.d.ts +13 -0
  85. package/dist/llm/provider-catalog.d.ts +30 -0
  86. package/dist/llm/provider-kinds.d.ts +21 -0
  87. package/dist/llm/types.d.ts +8 -0
  88. package/dist/logging/session-recorder.d.ts +77 -0
  89. package/dist/manager-C2IUXKRC.js +7 -0
  90. package/dist/manager-YYKWYTRM.cjs +7 -0
  91. package/dist/mcp-manager-QMKWPBZ4.js +8 -0
  92. package/dist/mcp-manager-Z3OKI74O.cjs +8 -0
  93. package/dist/memory-5LWZ6FI2.cjs +9 -0
  94. package/dist/{memory-EPFDBPII.js → memory-VIJLBAMQ.js} +2 -2
  95. package/dist/model-cache-5KIYL5SL.js +13 -0
  96. package/dist/model-cache-OED3IM4R.cjs +13 -0
  97. package/dist/model-fetcher-HKGICACL.js +8 -0
  98. package/dist/model-fetcher-UR6WJOQP.cjs +8 -0
  99. package/dist/openai-JR2WEKOF.js +10 -0
  100. package/dist/openai-YBTOET4O.cjs +10 -0
  101. package/dist/openrouter-models-OU4GRZQY.cjs +15 -0
  102. package/dist/{openrouter-models-2FM3H4SQ.js → openrouter-models-TGKDKY52.js} +2 -2
  103. package/dist/openrouter-sync-BBHUM3R6.cjs +11 -0
  104. package/dist/{openrouter-sync-SO3AWEAM.js → openrouter-sync-UXUSJCIR.js} +3 -3
  105. package/dist/product/index.cjs +17 -15
  106. package/dist/product/index.js +16 -14
  107. package/dist/protocol/server.d.ts +3 -1
  108. package/dist/protocol/types.d.ts +36 -2
  109. package/dist/run/index.cjs +17 -15
  110. package/dist/run/index.js +16 -14
  111. package/dist/services/index.d.ts +0 -1
  112. package/dist/session-manager-Q22BBMD3.js +8 -0
  113. package/dist/session-manager-XODQVL3C.cjs +8 -0
  114. package/dist/settings/schema.d.ts +267 -42
  115. package/dist/{tool-summary-RYNR4DDB.cjs → tool-summary-63DPIS7G.cjs} +4 -4
  116. package/dist/{tool-summary-2RUFL5QK.js → tool-summary-NP5CDBKG.js} +2 -2
  117. package/dist/tool-system/builtin/ask-user.d.ts +9 -1
  118. package/dist/tool-system/context.d.ts +31 -2
  119. package/dist/tool-system/executor.d.ts +4 -0
  120. package/dist/tool-system/investigation-guard.d.ts +37 -0
  121. package/dist/types.d.ts +13 -2
  122. package/dist/ui/components/AskUserPrompt.d.ts +8 -1
  123. package/dist/ui/components/DiffLine.d.ts +33 -0
  124. package/dist/ui/components/ModelManager.d.ts +34 -1
  125. package/dist/ui/components/OnboardingPrompt.d.ts +10 -1
  126. package/dist/ui/components/ProviderModelFlow.d.ts +58 -0
  127. package/dist/ui/components/UpdateBanner.d.ts +1 -0
  128. package/dist/updater-QW473OF4.cjs +17 -0
  129. package/dist/updater-VFUAHCVY.js +17 -0
  130. package/dist/utils/semver.d.ts +1 -0
  131. package/dist/utils/task-sanitizer.d.ts +6 -0
  132. package/package.json +1 -1
  133. package/dist/anthropic-P5VETAFI.cjs +0 -10
  134. package/dist/anthropic-W2GU3D76.js +0 -10
  135. package/dist/chunk-75E4BBFC.js +0 -224
  136. package/dist/chunk-FV2ARONZ.cjs +0 -224
  137. package/dist/client-base-TOVE25FA.js +0 -9
  138. package/dist/client-base-VDDIADAC.cjs +0 -9
  139. package/dist/compaction-D3KV2NWY.cjs +0 -31
  140. package/dist/devtools-WTC3NFNE.cjs +0 -6
  141. package/dist/file-history-HZWO2WQ5.js +0 -7
  142. package/dist/file-history-UQQILIY7.cjs +0 -7
  143. package/dist/manager-FWLOVEEK.cjs +0 -7
  144. package/dist/manager-GEXJLOIS.js +0 -7
  145. package/dist/mcp-manager-37GQLFGX.js +0 -8
  146. package/dist/mcp-manager-U77NEXBY.cjs +0 -8
  147. package/dist/memory-ADGOWADP.cjs +0 -9
  148. package/dist/openai-RXU5URYI.js +0 -10
  149. package/dist/openai-SQW4H2K4.cjs +0 -10
  150. package/dist/openrouter-models-PLCWZZYE.cjs +0 -15
  151. package/dist/openrouter-sync-K2WK3A2A.cjs +0 -11
  152. package/dist/services/compact.d.ts +0 -56
  153. package/dist/session-manager-HRSKENKB.cjs +0 -8
  154. package/dist/session-manager-NEKFEHF3.js +0 -8
  155. package/dist/updater-J7L7R6BY.cjs +0 -185
  156. package/dist/updater-LDBNYCAO.js +0 -185
@@ -16,8 +16,37 @@ import type { LLMConfig, StreamCallback } 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";
19
- /** Function the host UI / server uses to ask the user a question. */
20
- export type AskUserFn = (question: string) => Promise<string>;
19
+ /** One choice in a multiple-choice AskUserQuestion. */
20
+ export interface AskUserChoice {
21
+ label: string;
22
+ description: string;
23
+ }
24
+ /**
25
+ * Optional rendering hints / multiple-choice options carried alongside the
26
+ * question. Implementations may ignore unknown fields — they're additive.
27
+ */
28
+ export interface AskUserOptions {
29
+ /** Short chip-style label (≤12 chars) shown above the question. */
30
+ header?: string;
31
+ /** Multiple-choice options. When omitted, the UI falls back to free-text. */
32
+ options?: AskUserChoice[];
33
+ /** Allow the user to pick more than one option. Defaults to false. */
34
+ multiSelect?: boolean;
35
+ }
36
+ /**
37
+ * Function the host UI / server uses to ask the user a question.
38
+ *
39
+ * Second argument is optional for backwards compatibility — callers that
40
+ * only need free text can omit it; backends that don't support options
41
+ * should ignore the field and prompt for free text.
42
+ *
43
+ * Return value:
44
+ * - Free-text mode: the user's typed answer (or "(user declined to answer)").
45
+ * - Multiple-choice mode: the selected label, or comma-separated labels for
46
+ * multiSelect, or "Other: <typed>" when the user picks the implicit
47
+ * Other... entry.
48
+ */
49
+ export type AskUserFn = (question: string, opts?: AskUserOptions) => Promise<string>;
21
50
  /** Spawn a sub-agent. Returns the produced text or throws. */
22
51
  export interface SubAgentSpawnRequest {
23
52
  agentId: string;
@@ -7,6 +7,7 @@ import { ToolRegistry } from "./registry.js";
7
7
  import { PermissionClassifier } from "./permission.js";
8
8
  import { logger as rootLogger } from "../logging/logger.js";
9
9
  import type { ToolContext } from "./context.js";
10
+ import type { InvestigationGuard } from "./investigation-guard.js";
10
11
  type Logger = typeof rootLogger;
11
12
  export declare class ToolExecutor {
12
13
  private readonly registry;
@@ -21,7 +22,10 @@ export declare class ToolExecutor {
21
22
  * (tests, ad-hoc tool runs) still write log lines, just without turn tags.
22
23
  */
23
24
  private log;
25
+ private guard?;
24
26
  constructor(registry: ToolRegistry, permission: PermissionClassifier, hooks: HookRegistry);
27
+ setInvestigationGuard(guard: InvestigationGuard | undefined): void;
28
+ getInvestigationGuard(): InvestigationGuard | undefined;
25
29
  /** Set the abort signal for cascading cancellation. */
26
30
  setSignal(signal?: AbortSignal): void;
27
31
  /** Set the per-Engine ToolContext (askUser, llmConfig, modelPool, etc.). */
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Investigation Guard — runtime enforcement of read budgets.
3
+ *
4
+ * Background: prompt rules in coding.md ("never re-read the same file",
5
+ * "after ~3 read-only calls, change strategy") describe a behavior the model
6
+ * frequently violates under context pressure. This module turns those soft
7
+ * rules into in-loop reminders/blocks delivered through tool results.
8
+ *
9
+ * Three independent counters share one guard instance per Engine:
10
+ * A) dedupe — same Read offset hit ≥2 times → reminder; ≥3 times → block
11
+ * B) read-budget — N consecutive read-only tools with no side-effecting
12
+ * tool in between → reminder on the next read
13
+ * C) silent turns — N consecutive turns of only read-only tools with no
14
+ * text output → injected into the *next* turn's user
15
+ * message by turn-loop (the guard just tracks state).
16
+ *
17
+ * Everything decays naturally on any write/Bash/AskUser tool (state reset).
18
+ */
19
+ import type { ToolCall, ToolResult } from "../types.js";
20
+ export interface GuardDecision {
21
+ block?: string;
22
+ prepend?: string;
23
+ }
24
+ export declare class InvestigationGuard {
25
+ private readHistory;
26
+ private consecutiveReads;
27
+ private silentTurns;
28
+ private turnHasText;
29
+ private turnHasSideEffect;
30
+ private lastReminderSilent;
31
+ preToolCheck(call: ToolCall): GuardDecision | undefined;
32
+ noteText(text: string | undefined): void;
33
+ noteToolResult(_call: ToolCall, _result: ToolResult): void;
34
+ turnEnded(turnNumber: number): string | undefined;
35
+ private isMutatingTool;
36
+ private buildKey;
37
+ }
package/dist/types.d.ts CHANGED
@@ -65,7 +65,14 @@ export interface TranscriptEvent {
65
65
  turnNumber: number;
66
66
  data: Record<string, unknown>;
67
67
  }
68
- export type SessionStatus = "active" | "paused" | "completed" | "errored";
68
+ /**
69
+ * Session lifecycle state persisted in state.json. `"active"` means a run is
70
+ * currently in flight (or was, at the moment of the last heartbeat). All other
71
+ * values match the {@link TerminalReason} the last run returned, so callers
72
+ * can distinguish a user-cancelled session (`"aborted_streaming"`) from an
73
+ * actual error (`"model_error"`, `"prompt_too_long"`, ...).
74
+ */
75
+ export type SessionStatus = "active" | "paused" | TerminalReason;
69
76
  export interface SessionState {
70
77
  sessionId: string;
71
78
  cwd: string;
@@ -219,10 +226,14 @@ export type StreamEvent = {
219
226
  summary: string;
220
227
  } | {
221
228
  type: "context_compact";
222
- strategy: "summary" | "window" | "snip" | "emergency";
229
+ strategy: "micro" | "summary" | "window" | "snip" | "emergency";
223
230
  before: number;
224
231
  after: number;
225
232
  agentId?: string;
233
+ } | {
234
+ type: "usage_update";
235
+ promptTokens: number;
236
+ agentId?: string;
226
237
  };
227
238
  export type StreamCallback = (event: StreamEvent) => void | Promise<void>;
228
239
  export interface LLMConfig {
@@ -1,7 +1,14 @@
1
+ interface Choice {
2
+ label: string;
3
+ description: string;
4
+ }
1
5
  interface AskUserPromptProps {
2
6
  question: string;
7
+ header?: string;
8
+ options?: Choice[];
9
+ multiSelect?: boolean;
3
10
  onAnswer: (answer: string) => void;
4
11
  onCancel: () => void;
5
12
  }
6
- export declare function AskUserPrompt({ question, onAnswer, onCancel }: AskUserPromptProps): import("react/jsx-runtime").JSX.Element;
13
+ export declare function AskUserPrompt({ question, header, options, multiSelect, onAnswer, onCancel, }: AskUserPromptProps): import("react/jsx-runtime").JSX.Element;
7
14
  export {};
@@ -0,0 +1,33 @@
1
+ export type DiffKind = "add" | "remove" | "hunk" | "context";
2
+ interface DiffLineProps {
3
+ kind: DiffKind;
4
+ /** Raw text WITHOUT the `+ ` / `- ` prefix — DiffLine renders the marker. */
5
+ text: string;
6
+ /**
7
+ * Left indent applied before the marker (and before the gutter, if any).
8
+ * Defaults to 0; ToolCallResult passes its own padding so diff blocks
9
+ * line up under the `✓ ToolName` header.
10
+ */
11
+ indent?: number;
12
+ /**
13
+ * Optional dim leading glyph rendered before the colored band (e.g. the
14
+ * `⎿ ` connector ToolCallResult uses to group output under its header).
15
+ * Padding to terminal width accounts for the glyph so the band still
16
+ * extends to the right edge.
17
+ */
18
+ gutter?: string;
19
+ }
20
+ export declare function DiffLine({ kind, text, indent, gutter }: DiffLineProps): import("react/jsx-runtime").JSX.Element;
21
+ /**
22
+ * Classify a raw diff text line. Matches `+\s` / `-\s` (so `+x` identifiers
23
+ * and `+++ / ---` file headers don't trip it), `@@` hunk markers, and falls
24
+ * through to context.
25
+ *
26
+ * Returns the kind and the text with its marker stripped (since `<DiffLine>`
27
+ * re-renders the marker itself).
28
+ */
29
+ export declare function classifyDiffLine(raw: string): {
30
+ kind: DiffKind;
31
+ text: string;
32
+ };
33
+ export {};
@@ -15,10 +15,29 @@ export type ArenaParticipantEntry = {
15
15
  kind: "object";
16
16
  label: string;
17
17
  };
18
+ /**
19
+ * Row data shown in the Providers tab. Counts/timestamps are derived by the
20
+ * parent from settings.providers[] + the model cache so this component stays
21
+ * presentational.
22
+ */
23
+ export interface ProviderManagerEntry {
24
+ key: string;
25
+ label: string;
26
+ kind: string;
27
+ modelCount: number;
28
+ cachedModels?: number;
29
+ cachedAt?: string;
30
+ baseUrl?: string;
31
+ apiKey?: string;
32
+ protocol?: string;
33
+ modelsPath?: string;
34
+ }
18
35
  interface ModelManagerProps {
19
36
  entries: ProtocolModelEntry[];
20
37
  snapshot: SnapshotInfo;
21
38
  arenaParticipants: ArenaParticipantEntry[];
39
+ /** Providers configured in settings.providers[] (Task 11+). */
40
+ providers?: ProviderManagerEntry[];
22
41
  /** Activate a model. */
23
42
  onSwitch: (key: string) => Promise<void>;
24
43
  /** Trigger an OpenRouter snapshot refresh. */
@@ -29,7 +48,21 @@ interface ModelManagerProps {
29
48
  }>;
30
49
  /** Persist updated participant list (string[]) to settings. */
31
50
  onSaveArena: (participants: string[]) => Promise<void>;
51
+ /** Open the parent-rendered ProviderModelFlow (covers both add-provider and add-model). */
52
+ onOpenFlow?: () => void;
53
+ /** Force-refresh a provider's cached model list. */
54
+ onRefreshProvider?: (key: string) => Promise<{
55
+ count: number;
56
+ error?: string;
57
+ }>;
58
+ /** Delete a provider (blocked if any model references it). */
59
+ onDeleteProvider?: (key: string) => Promise<{
60
+ ok: boolean;
61
+ error?: string;
62
+ }>;
63
+ /** Delete a model entry. */
64
+ onDeleteModel?: (key: string) => Promise<void>;
32
65
  onClose: () => void;
33
66
  }
34
- export declare function ModelManager({ entries, snapshot, arenaParticipants, onSwitch, onSync, onSaveArena, onClose, }: ModelManagerProps): import("react/jsx-runtime").JSX.Element;
67
+ export declare function ModelManager({ entries, snapshot, arenaParticipants, providers, onSwitch, onSync, onSaveArena, onOpenFlow, onRefreshProvider, onDeleteProvider, onDeleteModel, onClose, }: ModelManagerProps): import("react/jsx-runtime").JSX.Element;
35
68
  export {};
@@ -1,7 +1,16 @@
1
1
  import { type OnboardingResult } from "../../cli/onboarding.js";
2
+ import type { ProviderConfig } from "../../llm/provider-catalog.js";
2
3
  interface OnboardingPromptProps {
3
4
  onComplete: (result: OnboardingResult) => void;
4
5
  onCancel: () => void;
6
+ /** Existing providers — surfaces "Use existing" in the flow's first step.
7
+ * Optional: empty by default (first-run case). */
8
+ existingProviders?: ProviderConfig[];
9
+ /** Existing model aliases — used by the flow to derive unique aliases. */
10
+ existingModelKeys?: string[];
11
+ /** Model ids already in settings.models[] — used by the flow to disable
12
+ * rows for models the user has already added. */
13
+ existingModelIds?: string[];
5
14
  }
6
- export declare function OnboardingPrompt({ onComplete, onCancel }: OnboardingPromptProps): import("react/jsx-runtime").JSX.Element | null;
15
+ export declare function OnboardingPrompt({ onComplete, onCancel, existingProviders, existingModelKeys, existingModelIds, }: OnboardingPromptProps): import("react/jsx-runtime").JSX.Element | null;
7
16
  export {};
@@ -0,0 +1,58 @@
1
+ import { type ProviderKindName } from "../../llm/provider-kinds.js";
2
+ import type { ProviderConfig } from "../../llm/provider-catalog.js";
3
+ export interface EnvKeyHint {
4
+ envKey: string;
5
+ apiKey: string;
6
+ kindHint: ProviderKindName;
7
+ }
8
+ export interface FlowResult {
9
+ addedProvider?: ProviderConfig;
10
+ /**
11
+ * Self-describing model entries — credentials are duplicated from the
12
+ * provider on purpose. The engine reads these without a ProviderCatalog
13
+ * round-trip; providers[] is kept only as a credential source for the
14
+ * wizard's future "add model to existing provider" flow.
15
+ */
16
+ addedModels: Array<{
17
+ key: string;
18
+ label?: string;
19
+ providerKey: string;
20
+ /** LLM client/protocol ("openai"/"anthropic"). */
21
+ protocol: string;
22
+ /** Legacy mirror of `protocol` for downstream readers that still query it. */
23
+ provider: string;
24
+ model: string;
25
+ baseUrl: string;
26
+ apiKey?: string;
27
+ maxContextTokens?: number;
28
+ maxOutputTokens?: number;
29
+ }>;
30
+ activeModelKey?: string;
31
+ }
32
+ export interface ProviderModelFlowProps {
33
+ existingProviders: ProviderConfig[];
34
+ existingModelKeys: string[];
35
+ /**
36
+ * Model ids (e.g. "deepseek-v4-pro") already present in settings.models[]
37
+ * under SOME provider. The fetch step uses this to disable rows for
38
+ * models the user has already added — keeps the menu informative (shows
39
+ * the full catalog) without letting the user re-add duplicates that
40
+ * appendOnboardingResult would silently drop.
41
+ */
42
+ existingModelIds?: string[];
43
+ detectedEnvKeys?: EnvKeyHint[];
44
+ switchToNewModelOnFinish: boolean;
45
+ onFinish: (r: FlowResult) => void;
46
+ onCancel: () => void;
47
+ }
48
+ /**
49
+ * Pool-key generator for wizard-added models. Format is `provider-model` so
50
+ * the alias self-identifies (e.g. "deepseek-v4-pro", not just "v4-pro" or
51
+ * "deepseek"). Collisions get a numeric suffix.
52
+ *
53
+ * If the model id already starts with `<provider>-`, we don't duplicate.
54
+ */
55
+ export declare function deriveModelAlias(modelId: string, used: string[], providerKind?: string): string;
56
+ export declare function deriveProviderKey(kindOrUrl: string, used: string[]): string;
57
+ export declare function validateAlias(alias: string, used: string[]): string | null;
58
+ export declare function ProviderModelFlow({ existingProviders, existingModelKeys, existingModelIds, detectedEnvKeys, switchToNewModelOnFinish, onFinish, onCancel, }: ProviderModelFlowProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export declare function UpdateBanner(): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,17 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+
5
+
6
+
7
+
8
+ var _chunkR47ROHGLcjs = require('./chunk-R47ROHGL.cjs');
9
+ require('./chunk-KS3RYAYL.cjs');
10
+
11
+
12
+
13
+
14
+
15
+
16
+
17
+ exports.__internal = _chunkR47ROHGLcjs.__internal; exports.checkForUpdate = _chunkR47ROHGLcjs.checkForUpdate; exports.getAutoUpdateDisabledReason = _chunkR47ROHGLcjs.getAutoUpdateDisabledReason; exports.getCurrentVersion = _chunkR47ROHGLcjs.getCurrentVersion; exports.getUpdateAvailable = _chunkR47ROHGLcjs.getUpdateAvailable; exports.scheduleAutoInstallOnExit = _chunkR47ROHGLcjs.scheduleAutoInstallOnExit;
@@ -0,0 +1,17 @@
1
+ import {
2
+ __internal,
3
+ checkForUpdate,
4
+ getAutoUpdateDisabledReason,
5
+ getCurrentVersion,
6
+ getUpdateAvailable,
7
+ scheduleAutoInstallOnExit
8
+ } from "./chunk-W22P377T.js";
9
+ import "./chunk-MD32R22I.js";
10
+ export {
11
+ __internal,
12
+ checkForUpdate,
13
+ getAutoUpdateDisabledReason,
14
+ getCurrentVersion,
15
+ getUpdateAvailable,
16
+ scheduleAutoInstallOnExit
17
+ };
@@ -2,4 +2,5 @@
2
2
  * Shim for CC's utils/semver — re-exports semver comparison helpers.
3
3
  */
4
4
  export declare function gte(a: string, b: string): boolean;
5
+ export declare function gt(a: string, b: string): boolean;
5
6
  export declare function lt(a: string, b: string): boolean;
@@ -0,0 +1,6 @@
1
+ export interface NoiseResult {
2
+ isNoise: boolean;
3
+ reason: string;
4
+ cleaned: string;
5
+ }
6
+ export declare function detectPastedNoise(task: string): NoiseResult;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cjhyy/code-shell",
3
- "version": "0.1.0-alpha.3",
3
+ "version": "0.1.5",
4
4
  "description": "Code Shell — general-purpose agent orchestration framework with a terminal coding preset",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -1,10 +0,0 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
-
3
- var _chunkBUJ5KYCIcjs = require('./chunk-BUJ5KYCI.cjs');
4
- require('./chunk-GZBD6QRS.cjs');
5
- require('./chunk-EL2RL5DG.cjs');
6
- require('./chunk-JHNCK7JP.cjs');
7
- require('./chunk-IJSHQGMP.cjs');
8
-
9
-
10
- exports.AnthropicClient = _chunkBUJ5KYCIcjs.AnthropicClient;
@@ -1,10 +0,0 @@
1
- import {
2
- AnthropicClient
3
- } from "./chunk-M2SVOKC6.js";
4
- import "./chunk-SCDKLTN3.js";
5
- import "./chunk-FUOKLKR2.js";
6
- import "./chunk-ZRVPCXI7.js";
7
- import "./chunk-DI7RDLOS.js";
8
- export {
9
- AnthropicClient
10
- };
@@ -1,224 +0,0 @@
1
- import {
2
- init_esm_shims
3
- } from "./chunk-DI7RDLOS.js";
4
-
5
- // src/settings/manager.ts
6
- init_esm_shims();
7
- import { readFileSync, existsSync, mkdirSync, writeFileSync, renameSync } from "fs";
8
- import { join, dirname } from "path";
9
- import { homedir } from "os";
10
-
11
- // src/settings/schema.ts
12
- init_esm_shims();
13
- import { z } from "zod";
14
- var SettingsSchema = z.object({
15
- agent: z.object({
16
- // Use z.string() instead of z.enum() to allow custom presets registered via registerPreset()
17
- preset: z.string().default("terminal-coding"),
18
- enabledBuiltinTools: z.array(z.string()).default([]),
19
- disabledBuiltinTools: z.array(z.string()).default([]),
20
- customSystemPrompt: z.string().optional(),
21
- appendSystemPrompt: z.string().optional()
22
- }).default({}),
23
- model: z.object({
24
- provider: z.string().default("openai"),
25
- name: z.string().default("anthropic/claude-opus-4-6"),
26
- apiKey: z.string().optional(),
27
- baseUrl: z.string().default("https://openrouter.ai/api/v1"),
28
- temperature: z.number().min(0).max(2).default(0.3),
29
- maxTokens: z.number().default(8192)
30
- }).default({}),
31
- models: z.array(
32
- z.object({
33
- key: z.string(),
34
- label: z.string().optional(),
35
- provider: z.string(),
36
- model: z.string(),
37
- baseUrl: z.string().optional(),
38
- apiKey: z.string().optional(),
39
- maxOutputTokens: z.number().optional(),
40
- maxContextTokens: z.number().optional()
41
- })
42
- ).default([]),
43
- permissions: z.object({
44
- defaultMode: z.enum(["default", "acceptEdits", "dontAsk", "bypassPermissions", "auto", "plan"]).default("default"),
45
- rules: z.array(
46
- z.object({
47
- tool: z.string(),
48
- argsPattern: z.record(z.string()).optional(),
49
- decision: z.enum(["allow", "deny", "ask"]),
50
- reason: z.string().optional()
51
- })
52
- ).default([])
53
- }).default({}),
54
- context: z.object({
55
- maxTokens: z.number().default(2e5),
56
- compactAtRatio: z.number().default(0.6),
57
- summarizeAtRatio: z.number().default(0.8)
58
- }).default({}),
59
- session: z.object({
60
- storageDir: z.string().optional(),
61
- maxHistory: z.number().default(100)
62
- }).default({}),
63
- mcpServers: z.record(
64
- z.object({
65
- name: z.string(),
66
- command: z.string().optional(),
67
- args: z.array(z.string()).optional(),
68
- env: z.record(z.string()).optional(),
69
- url: z.string().optional(),
70
- transport: z.enum(["stdio", "sse", "streamable-http", "inprocess"]).optional(),
71
- headers: z.record(z.string()).optional()
72
- })
73
- ).default({}),
74
- instructions: z.object({
75
- fileName: z.string().default("CODESHELL.md"),
76
- scanDirs: z.array(z.string()).default([]),
77
- compatFileNames: z.array(z.string()).default(["CLAUDE.md", "AGENTS.md"]),
78
- ignoreGitBoundary: z.boolean().default(false)
79
- }).default({}),
80
- arena: z.object({
81
- participants: z.array(
82
- z.union([
83
- // Short form: just a model pool key
84
- z.string(),
85
- // Full form: explicit config (backward compat)
86
- z.object({
87
- name: z.string(),
88
- model: z.string(),
89
- provider: z.string().optional(),
90
- apiKey: z.string().optional(),
91
- baseUrl: z.string().optional()
92
- })
93
- ])
94
- ).default([])
95
- }).default({}),
96
- search: z.object({
97
- provider: z.enum(["serper", "tavily", "searxng"]).default("serper"),
98
- apiKey: z.string().optional(),
99
- baseUrl: z.string().optional()
100
- }).default({}),
101
- output: z.object({
102
- format: z.enum(["text", "json", "jsonl", "stream-json"]).default("text")
103
- }).default({})
104
- }).passthrough();
105
- function validateSettings(raw) {
106
- return SettingsSchema.parse(raw);
107
- }
108
-
109
- // src/settings/manager.ts
110
- var SettingsManager = class {
111
- constructor(cwd = process.cwd()) {
112
- this.cwd = cwd;
113
- }
114
- sources = [];
115
- merged = null;
116
- /**
117
- * Load settings from all sources.
118
- */
119
- load(flagOverrides) {
120
- this.sources = [];
121
- this.loadJsonFile(join(homedir(), ".code-shell", "settings.managed.json"), "managed", 0);
122
- this.loadJsonFile(join(homedir(), ".code-shell", "settings.json"), "user", 1);
123
- this.loadJsonFile(join(homedir(), ".claude", "settings.json"), "user", 1);
124
- this.loadJsonFile(join(this.cwd, ".code-shell", "settings.json"), "project", 2);
125
- this.loadJsonFile(join(this.cwd, ".claude", "settings.json"), "project", 2);
126
- this.loadJsonFile(join(this.cwd, ".code-shell", "settings.local.json"), "local", 3);
127
- this.loadJsonFile(join(this.cwd, ".claude", "settings.local.json"), "local", 3);
128
- if (flagOverrides && Object.keys(flagOverrides).length > 0) {
129
- this.sources.push({ name: "flag", priority: 4, data: flagOverrides });
130
- }
131
- this.sources.sort((a, b) => a.priority - b.priority);
132
- const raw = this.deepMerge();
133
- this.merged = validateSettings(raw);
134
- return this.merged;
135
- }
136
- /**
137
- * Get current effective settings.
138
- */
139
- get() {
140
- if (!this.merged) return this.load();
141
- return this.merged;
142
- }
143
- /**
144
- * Invalidate cached merge.
145
- */
146
- invalidate() {
147
- this.merged = null;
148
- }
149
- /**
150
- * Persist a single setting (dotted key path) to the user-level config file
151
- * at ~/.code-shell/settings.json. Other sources (project / local /
152
- * managed) are intentionally untouched: writing back to project/local
153
- * would surprise version control, and managed is read-only.
154
- *
155
- * The merged cache is invalidated so the next get() picks up the change.
156
- */
157
- saveUserSetting(key, value) {
158
- const path = join(homedir(), ".code-shell", "settings.json");
159
- let current = {};
160
- if (existsSync(path)) {
161
- try {
162
- const raw = readFileSync(path, "utf-8");
163
- const parsed = JSON.parse(raw);
164
- if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
165
- current = parsed;
166
- }
167
- } catch {
168
- }
169
- }
170
- const parts = key.split(".");
171
- let target = current;
172
- for (let i = 0; i < parts.length - 1; i++) {
173
- const seg = parts[i];
174
- const next = target[seg];
175
- if (!next || typeof next !== "object" || Array.isArray(next)) {
176
- target[seg] = {};
177
- }
178
- target = target[seg];
179
- }
180
- target[parts[parts.length - 1]] = value;
181
- mkdirSync(dirname(path), { recursive: true });
182
- const tmp = `${path}.${process.pid}.${Date.now()}.tmp`;
183
- writeFileSync(tmp, JSON.stringify(current, null, 2), "utf-8");
184
- renameSync(tmp, path);
185
- this.invalidate();
186
- }
187
- loadJsonFile(path, name, priority) {
188
- if (!existsSync(path)) return;
189
- try {
190
- const content = readFileSync(path, "utf-8");
191
- const data = JSON.parse(content);
192
- if (typeof data === "object" && data !== null) {
193
- this.sources.push({ name, priority, data });
194
- }
195
- } catch {
196
- }
197
- }
198
- deepMerge() {
199
- let result = {};
200
- for (const source of this.sources) {
201
- result = merge(result, source.data);
202
- }
203
- return result;
204
- }
205
- };
206
- function merge(base, override) {
207
- const result = { ...base };
208
- for (const [key, value] of Object.entries(override)) {
209
- if (value === null) {
210
- delete result[key];
211
- } else if (typeof value === "object" && !Array.isArray(value) && typeof result[key] === "object" && !Array.isArray(result[key]) && result[key] !== null) {
212
- result[key] = merge(result[key], value);
213
- } else {
214
- result[key] = value;
215
- }
216
- }
217
- return result;
218
- }
219
-
220
- export {
221
- SettingsSchema,
222
- validateSettings,
223
- SettingsManager
224
- };