@cjhyy/code-shell 0.1.7 → 0.2.0

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 (73) hide show
  1. package/dist/anthropic-OVRWAZRD.js +1 -0
  2. package/dist/arena/index.js +1 -1
  3. package/dist/{arena-OW55ZCHT.js → arena-64T2EQD4.js} +1 -1
  4. package/dist/{chunk-HIJ2XXGX.js → chunk-2EUIMKJA.js} +1 -1
  5. package/dist/{chunk-Y2NS6HPO.js → chunk-2GJ7H5NC.js} +17 -17
  6. package/dist/chunk-2OD6VR4N.js +2 -0
  7. package/dist/chunk-A4M2Y42L.js +2 -0
  8. package/dist/{chunk-WOP6MJKW.js → chunk-DEYFK6FP.js} +1 -1
  9. package/dist/chunk-DTPABBSV.js +2 -0
  10. package/dist/{chunk-RP26WO4R.js → chunk-EU3J7TBP.js} +1 -1
  11. package/dist/{chunk-XDOWC7EG.js → chunk-L7B2ORID.js} +1 -1
  12. package/dist/chunk-M7VU4YVY.js +49 -0
  13. package/dist/{chunk-NMBYBGC7.js → chunk-MGP35GKD.js} +87 -83
  14. package/dist/chunk-MLCTC53I.js +1 -0
  15. package/dist/{chunk-KCXSARAA.js → chunk-Q3RSX66I.js} +1 -1
  16. package/dist/{chunk-Q4O2HGWS.js → chunk-RERBX75D.js} +1 -1
  17. package/dist/chunk-VKKU4LOM.js +3 -0
  18. package/dist/{chunk-NFH3UQ3E.js → chunk-XXCZE2U2.js} +1 -1
  19. package/dist/chunk-ZSAONDT6.js +2 -0
  20. package/dist/cli/main.js +104 -104
  21. package/dist/cli/onboarding.d.ts +7 -2
  22. package/dist/client-base-F5FCRSB3.js +1 -0
  23. package/dist/compaction-L3Y6NG4N.js +1 -0
  24. package/dist/context/compaction.d.ts +2 -1
  25. package/dist/data/static-catalogs.d.ts +25 -0
  26. package/dist/engine/engine.d.ts +16 -0
  27. package/dist/engine/turn-loop.d.ts +20 -0
  28. package/dist/index.d.ts +1 -1
  29. package/dist/index.js +1 -1
  30. package/dist/llm/capabilities/index.d.ts +20 -0
  31. package/dist/llm/capabilities/rules.d.ts +26 -0
  32. package/dist/llm/capabilities/types.d.ts +108 -0
  33. package/dist/llm/model-pool.d.ts +7 -0
  34. package/dist/llm/provider-catalog.d.ts +2 -0
  35. package/dist/llm/provider-kinds.d.ts +1 -1
  36. package/dist/llm/providers/openai.d.ts +22 -0
  37. package/dist/llm/types.d.ts +8 -0
  38. package/dist/logging/logger.d.ts +10 -2
  39. package/dist/logging/session-recorder.d.ts +16 -3
  40. package/dist/manager-J6FXEUEK.js +1 -0
  41. package/dist/mcp-manager-27EVBKRT.js +1 -0
  42. package/dist/model-fetcher-X5W5EASG.js +1 -0
  43. package/dist/openai-3QEADSYL.js +1 -0
  44. package/dist/{openrouter-models-AM6M52D6.js → openrouter-models-GZVCRWD2.js} +1 -1
  45. package/dist/openrouter-sync-WG4AG5NC.js +1 -0
  46. package/dist/product/index.js +1 -1
  47. package/dist/protocol/client.d.ts +1 -1
  48. package/dist/run/index.js +1 -1
  49. package/dist/{seatbelt-WBYROQT6.js → seatbelt-L54CNI2Y.js} +5 -5
  50. package/dist/settings/schema.d.ts +75 -15
  51. package/dist/{tool-summary-5UE62VU4.js → tool-summary-V2B3MD5N.js} +1 -1
  52. package/dist/tool-system/executor.d.ts +4 -0
  53. package/dist/tool-system/sandbox/index.d.ts +7 -0
  54. package/dist/tool-system/task-guard.d.ts +30 -0
  55. package/dist/types.d.ts +13 -0
  56. package/dist/ui/components/SpinnerWithVerb.d.ts +5 -0
  57. package/dist/ui/components/StatusLine.d.ts +5 -1
  58. package/package.json +1 -1
  59. package/dist/anthropic-UBSB5AQH.js +0 -1
  60. package/dist/chunk-2NS3JMNK.js +0 -1
  61. package/dist/chunk-B7K2OWKC.js +0 -2
  62. package/dist/chunk-EWWK56K6.js +0 -2
  63. package/dist/chunk-NVAZJ5XS.js +0 -2
  64. package/dist/chunk-PGANL6F2.js +0 -3
  65. package/dist/chunk-UDPUTFQT.js +0 -2
  66. package/dist/chunk-W47Z7MGS.js +0 -33
  67. package/dist/client-base-6ZZJJYDY.js +0 -1
  68. package/dist/compaction-ECVQVOCT.js +0 -1
  69. package/dist/manager-C3TDN6MS.js +0 -1
  70. package/dist/mcp-manager-OP4XYV53.js +0 -1
  71. package/dist/model-fetcher-BJ64META.js +0 -1
  72. package/dist/openai-KEWQ54TM.js +0 -1
  73. package/dist/openrouter-sync-5JNBL3Z6.js +0 -1
@@ -48,38 +48,47 @@ export declare const SettingsSchema: z.ZodObject<{
48
48
  }, "strip", z.ZodTypeAny, {
49
49
  provider: string;
50
50
  name: string;
51
+ temperature: number;
51
52
  maxTokens: number;
52
53
  baseUrl: string;
53
- temperature: number;
54
54
  apiKey?: string | undefined;
55
55
  }, {
56
56
  provider?: string | undefined;
57
57
  name?: string | undefined;
58
+ temperature?: number | undefined;
58
59
  maxTokens?: number | undefined;
59
60
  baseUrl?: string | undefined;
60
61
  apiKey?: string | undefined;
61
- temperature?: number | undefined;
62
62
  }>>;
63
63
  providers: z.ZodDefault<z.ZodArray<z.ZodObject<{
64
64
  key: z.ZodString;
65
65
  label: z.ZodOptional<z.ZodString>;
66
- kind: z.ZodEnum<["openai", "anthropic", "deepseek", "xai", "mistral", "groq", "google", "openrouter", "ollama", "custom"]>;
66
+ kind: z.ZodEnum<["openai", "anthropic", "deepseek", "zai", "xai", "mistral", "groq", "google", "openrouter", "ollama", "custom"]>;
67
67
  baseUrl: z.ZodString;
68
68
  apiKey: z.ZodOptional<z.ZodString>;
69
69
  protocol: z.ZodOptional<z.ZodEnum<["openai-compat", "anthropic-style"]>>;
70
70
  modelsPath: z.ZodOptional<z.ZodString>;
71
+ /**
72
+ * DeepSeek V4 thinking-mode default for this provider. "enabled"
73
+ * matches endpoint default; "disabled" makes V4 calls run in
74
+ * non-thinking mode (faster, cheaper). Ignored by every provider
75
+ * other than DeepSeek V4. Per-call overrides still win.
76
+ */
77
+ thinking: z.ZodOptional<z.ZodEnum<["enabled", "disabled"]>>;
71
78
  }, "strip", z.ZodTypeAny, {
72
- kind: "anthropic" | "openai" | "openrouter" | "deepseek" | "ollama" | "mistral" | "custom" | "xai" | "groq" | "google";
79
+ kind: "anthropic" | "openai" | "deepseek" | "zai" | "xai" | "mistral" | "groq" | "google" | "openrouter" | "ollama" | "custom";
73
80
  key: string;
74
81
  baseUrl: string;
82
+ thinking?: "enabled" | "disabled" | undefined;
75
83
  label?: string | undefined;
76
84
  apiKey?: string | undefined;
77
85
  protocol?: "openai-compat" | "anthropic-style" | undefined;
78
86
  modelsPath?: string | undefined;
79
87
  }, {
80
- kind: "anthropic" | "openai" | "openrouter" | "deepseek" | "ollama" | "mistral" | "custom" | "xai" | "groq" | "google";
88
+ kind: "anthropic" | "openai" | "deepseek" | "zai" | "xai" | "mistral" | "groq" | "google" | "openrouter" | "ollama" | "custom";
81
89
  key: string;
82
90
  baseUrl: string;
91
+ thinking?: "enabled" | "disabled" | undefined;
83
92
  label?: string | undefined;
84
93
  apiKey?: string | undefined;
85
94
  protocol?: "openai-compat" | "anthropic-style" | undefined;
@@ -102,10 +111,18 @@ export declare const SettingsSchema: z.ZodObject<{
102
111
  provider: z.ZodOptional<z.ZodString>;
103
112
  baseUrl: z.ZodOptional<z.ZodString>;
104
113
  apiKey: z.ZodOptional<z.ZodString>;
114
+ /**
115
+ * Per-model thinking override. Wins over the provider-level
116
+ * setting (settings.providers[].thinking). Use this when
117
+ * different models under the same provider need different
118
+ * defaults — e.g. DeepSeek V4 Pro off (faster) but V4 Flash on.
119
+ */
120
+ thinking: z.ZodOptional<z.ZodEnum<["enabled", "disabled"]>>;
105
121
  }, "strip", z.ZodTypeAny, {
106
122
  model: string;
107
123
  key: string;
108
124
  provider?: string | undefined;
125
+ thinking?: "enabled" | "disabled" | undefined;
109
126
  baseUrl?: string | undefined;
110
127
  label?: string | undefined;
111
128
  apiKey?: string | undefined;
@@ -117,6 +134,7 @@ export declare const SettingsSchema: z.ZodObject<{
117
134
  model: string;
118
135
  key: string;
119
136
  provider?: string | undefined;
137
+ thinking?: "enabled" | "disabled" | undefined;
120
138
  baseUrl?: string | undefined;
121
139
  label?: string | undefined;
122
140
  apiKey?: string | undefined;
@@ -129,6 +147,7 @@ export declare const SettingsSchema: z.ZodObject<{
129
147
  provider: string | undefined;
130
148
  model: string;
131
149
  key: string;
150
+ thinking?: "enabled" | "disabled" | undefined;
132
151
  baseUrl?: string | undefined;
133
152
  label?: string | undefined;
134
153
  apiKey?: string | undefined;
@@ -139,6 +158,7 @@ export declare const SettingsSchema: z.ZodObject<{
139
158
  model: string;
140
159
  key: string;
141
160
  provider?: string | undefined;
161
+ thinking?: "enabled" | "disabled" | undefined;
142
162
  baseUrl?: string | undefined;
143
163
  label?: string | undefined;
144
164
  apiKey?: string | undefined;
@@ -371,38 +391,47 @@ export declare const SettingsSchema: z.ZodObject<{
371
391
  }, "strip", z.ZodTypeAny, {
372
392
  provider: string;
373
393
  name: string;
394
+ temperature: number;
374
395
  maxTokens: number;
375
396
  baseUrl: string;
376
- temperature: number;
377
397
  apiKey?: string | undefined;
378
398
  }, {
379
399
  provider?: string | undefined;
380
400
  name?: string | undefined;
401
+ temperature?: number | undefined;
381
402
  maxTokens?: number | undefined;
382
403
  baseUrl?: string | undefined;
383
404
  apiKey?: string | undefined;
384
- temperature?: number | undefined;
385
405
  }>>;
386
406
  providers: z.ZodDefault<z.ZodArray<z.ZodObject<{
387
407
  key: z.ZodString;
388
408
  label: z.ZodOptional<z.ZodString>;
389
- kind: z.ZodEnum<["openai", "anthropic", "deepseek", "xai", "mistral", "groq", "google", "openrouter", "ollama", "custom"]>;
409
+ kind: z.ZodEnum<["openai", "anthropic", "deepseek", "zai", "xai", "mistral", "groq", "google", "openrouter", "ollama", "custom"]>;
390
410
  baseUrl: z.ZodString;
391
411
  apiKey: z.ZodOptional<z.ZodString>;
392
412
  protocol: z.ZodOptional<z.ZodEnum<["openai-compat", "anthropic-style"]>>;
393
413
  modelsPath: z.ZodOptional<z.ZodString>;
414
+ /**
415
+ * DeepSeek V4 thinking-mode default for this provider. "enabled"
416
+ * matches endpoint default; "disabled" makes V4 calls run in
417
+ * non-thinking mode (faster, cheaper). Ignored by every provider
418
+ * other than DeepSeek V4. Per-call overrides still win.
419
+ */
420
+ thinking: z.ZodOptional<z.ZodEnum<["enabled", "disabled"]>>;
394
421
  }, "strip", z.ZodTypeAny, {
395
- kind: "anthropic" | "openai" | "openrouter" | "deepseek" | "ollama" | "mistral" | "custom" | "xai" | "groq" | "google";
422
+ kind: "anthropic" | "openai" | "deepseek" | "zai" | "xai" | "mistral" | "groq" | "google" | "openrouter" | "ollama" | "custom";
396
423
  key: string;
397
424
  baseUrl: string;
425
+ thinking?: "enabled" | "disabled" | undefined;
398
426
  label?: string | undefined;
399
427
  apiKey?: string | undefined;
400
428
  protocol?: "openai-compat" | "anthropic-style" | undefined;
401
429
  modelsPath?: string | undefined;
402
430
  }, {
403
- kind: "anthropic" | "openai" | "openrouter" | "deepseek" | "ollama" | "mistral" | "custom" | "xai" | "groq" | "google";
431
+ kind: "anthropic" | "openai" | "deepseek" | "zai" | "xai" | "mistral" | "groq" | "google" | "openrouter" | "ollama" | "custom";
404
432
  key: string;
405
433
  baseUrl: string;
434
+ thinking?: "enabled" | "disabled" | undefined;
406
435
  label?: string | undefined;
407
436
  apiKey?: string | undefined;
408
437
  protocol?: "openai-compat" | "anthropic-style" | undefined;
@@ -425,10 +454,18 @@ export declare const SettingsSchema: z.ZodObject<{
425
454
  provider: z.ZodOptional<z.ZodString>;
426
455
  baseUrl: z.ZodOptional<z.ZodString>;
427
456
  apiKey: z.ZodOptional<z.ZodString>;
457
+ /**
458
+ * Per-model thinking override. Wins over the provider-level
459
+ * setting (settings.providers[].thinking). Use this when
460
+ * different models under the same provider need different
461
+ * defaults — e.g. DeepSeek V4 Pro off (faster) but V4 Flash on.
462
+ */
463
+ thinking: z.ZodOptional<z.ZodEnum<["enabled", "disabled"]>>;
428
464
  }, "strip", z.ZodTypeAny, {
429
465
  model: string;
430
466
  key: string;
431
467
  provider?: string | undefined;
468
+ thinking?: "enabled" | "disabled" | undefined;
432
469
  baseUrl?: string | undefined;
433
470
  label?: string | undefined;
434
471
  apiKey?: string | undefined;
@@ -440,6 +477,7 @@ export declare const SettingsSchema: z.ZodObject<{
440
477
  model: string;
441
478
  key: string;
442
479
  provider?: string | undefined;
480
+ thinking?: "enabled" | "disabled" | undefined;
443
481
  baseUrl?: string | undefined;
444
482
  label?: string | undefined;
445
483
  apiKey?: string | undefined;
@@ -452,6 +490,7 @@ export declare const SettingsSchema: z.ZodObject<{
452
490
  provider: string | undefined;
453
491
  model: string;
454
492
  key: string;
493
+ thinking?: "enabled" | "disabled" | undefined;
455
494
  baseUrl?: string | undefined;
456
495
  label?: string | undefined;
457
496
  apiKey?: string | undefined;
@@ -462,6 +501,7 @@ export declare const SettingsSchema: z.ZodObject<{
462
501
  model: string;
463
502
  key: string;
464
503
  provider?: string | undefined;
504
+ thinking?: "enabled" | "disabled" | undefined;
465
505
  baseUrl?: string | undefined;
466
506
  label?: string | undefined;
467
507
  apiKey?: string | undefined;
@@ -694,38 +734,47 @@ export declare const SettingsSchema: z.ZodObject<{
694
734
  }, "strip", z.ZodTypeAny, {
695
735
  provider: string;
696
736
  name: string;
737
+ temperature: number;
697
738
  maxTokens: number;
698
739
  baseUrl: string;
699
- temperature: number;
700
740
  apiKey?: string | undefined;
701
741
  }, {
702
742
  provider?: string | undefined;
703
743
  name?: string | undefined;
744
+ temperature?: number | undefined;
704
745
  maxTokens?: number | undefined;
705
746
  baseUrl?: string | undefined;
706
747
  apiKey?: string | undefined;
707
- temperature?: number | undefined;
708
748
  }>>;
709
749
  providers: z.ZodDefault<z.ZodArray<z.ZodObject<{
710
750
  key: z.ZodString;
711
751
  label: z.ZodOptional<z.ZodString>;
712
- kind: z.ZodEnum<["openai", "anthropic", "deepseek", "xai", "mistral", "groq", "google", "openrouter", "ollama", "custom"]>;
752
+ kind: z.ZodEnum<["openai", "anthropic", "deepseek", "zai", "xai", "mistral", "groq", "google", "openrouter", "ollama", "custom"]>;
713
753
  baseUrl: z.ZodString;
714
754
  apiKey: z.ZodOptional<z.ZodString>;
715
755
  protocol: z.ZodOptional<z.ZodEnum<["openai-compat", "anthropic-style"]>>;
716
756
  modelsPath: z.ZodOptional<z.ZodString>;
757
+ /**
758
+ * DeepSeek V4 thinking-mode default for this provider. "enabled"
759
+ * matches endpoint default; "disabled" makes V4 calls run in
760
+ * non-thinking mode (faster, cheaper). Ignored by every provider
761
+ * other than DeepSeek V4. Per-call overrides still win.
762
+ */
763
+ thinking: z.ZodOptional<z.ZodEnum<["enabled", "disabled"]>>;
717
764
  }, "strip", z.ZodTypeAny, {
718
- kind: "anthropic" | "openai" | "openrouter" | "deepseek" | "ollama" | "mistral" | "custom" | "xai" | "groq" | "google";
765
+ kind: "anthropic" | "openai" | "deepseek" | "zai" | "xai" | "mistral" | "groq" | "google" | "openrouter" | "ollama" | "custom";
719
766
  key: string;
720
767
  baseUrl: string;
768
+ thinking?: "enabled" | "disabled" | undefined;
721
769
  label?: string | undefined;
722
770
  apiKey?: string | undefined;
723
771
  protocol?: "openai-compat" | "anthropic-style" | undefined;
724
772
  modelsPath?: string | undefined;
725
773
  }, {
726
- kind: "anthropic" | "openai" | "openrouter" | "deepseek" | "ollama" | "mistral" | "custom" | "xai" | "groq" | "google";
774
+ kind: "anthropic" | "openai" | "deepseek" | "zai" | "xai" | "mistral" | "groq" | "google" | "openrouter" | "ollama" | "custom";
727
775
  key: string;
728
776
  baseUrl: string;
777
+ thinking?: "enabled" | "disabled" | undefined;
729
778
  label?: string | undefined;
730
779
  apiKey?: string | undefined;
731
780
  protocol?: "openai-compat" | "anthropic-style" | undefined;
@@ -748,10 +797,18 @@ export declare const SettingsSchema: z.ZodObject<{
748
797
  provider: z.ZodOptional<z.ZodString>;
749
798
  baseUrl: z.ZodOptional<z.ZodString>;
750
799
  apiKey: z.ZodOptional<z.ZodString>;
800
+ /**
801
+ * Per-model thinking override. Wins over the provider-level
802
+ * setting (settings.providers[].thinking). Use this when
803
+ * different models under the same provider need different
804
+ * defaults — e.g. DeepSeek V4 Pro off (faster) but V4 Flash on.
805
+ */
806
+ thinking: z.ZodOptional<z.ZodEnum<["enabled", "disabled"]>>;
751
807
  }, "strip", z.ZodTypeAny, {
752
808
  model: string;
753
809
  key: string;
754
810
  provider?: string | undefined;
811
+ thinking?: "enabled" | "disabled" | undefined;
755
812
  baseUrl?: string | undefined;
756
813
  label?: string | undefined;
757
814
  apiKey?: string | undefined;
@@ -763,6 +820,7 @@ export declare const SettingsSchema: z.ZodObject<{
763
820
  model: string;
764
821
  key: string;
765
822
  provider?: string | undefined;
823
+ thinking?: "enabled" | "disabled" | undefined;
766
824
  baseUrl?: string | undefined;
767
825
  label?: string | undefined;
768
826
  apiKey?: string | undefined;
@@ -775,6 +833,7 @@ export declare const SettingsSchema: z.ZodObject<{
775
833
  provider: string | undefined;
776
834
  model: string;
777
835
  key: string;
836
+ thinking?: "enabled" | "disabled" | undefined;
778
837
  baseUrl?: string | undefined;
779
838
  label?: string | undefined;
780
839
  apiKey?: string | undefined;
@@ -785,6 +844,7 @@ export declare const SettingsSchema: z.ZodObject<{
785
844
  model: string;
786
845
  key: string;
787
846
  provider?: string | undefined;
847
+ thinking?: "enabled" | "disabled" | undefined;
788
848
  baseUrl?: string | undefined;
789
849
  label?: string | undefined;
790
850
  apiKey?: string | undefined;
@@ -1,2 +1,2 @@
1
- import {b}from'./chunk-B7K2OWKC.js';import {h,a}from'./chunk-3QP5BQ3L.js';h();var p='Generate a very brief (under 40 chars) summary of what these tools did. Use past tense, commit-subject style. Examples: "Read 3 config files", "Fixed import in auth.ts", "Searched for API endpoints". Respond with ONLY the summary text, nothing else.';async function d(r,a,l){if(r.length===0)return null;try{let e=[];for(let t=0;t<r.length;t++){let s=r[t],o=a[t],u=JSON.stringify(s.args).slice(0,200),c=(o?.result??o?.error??"").slice(0,300);e.push(`Tool: ${s.toolName}(${u}) \u2192 ${c}`);}return (await l(p,e.join(`
1
+ import {b}from'./chunk-ZSAONDT6.js';import {h,a}from'./chunk-3QP5BQ3L.js';h();var p='Generate a very brief (under 40 chars) summary of what these tools did. Use past tense, commit-subject style. Examples: "Read 3 config files", "Fixed import in auth.ts", "Searched for API endpoints". Respond with ONLY the summary text, nothing else.';async function d(r,a,l){if(r.length===0)return null;try{let e=[];for(let t=0;t<r.length;t++){let s=r[t],o=a[t],u=JSON.stringify(s.args).slice(0,200),c=(o?.result??o?.error??"").slice(0,300);e.push(`Tool: ${s.toolName}(${u}) \u2192 ${c}`);}return (await l(p,e.join(`
2
2
  `)))?.trim()||null}catch(e){return b.warn("tool_summary.failed",{error:e.message}),null}}a(d,"generateToolUseSummary");export{d as generateToolUseSummary};
@@ -8,6 +8,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
10
  import type { InvestigationGuard } from "./investigation-guard.js";
11
+ import type { TaskGuard } from "./task-guard.js";
11
12
  type Logger = typeof rootLogger;
12
13
  export declare class ToolExecutor {
13
14
  private readonly registry;
@@ -23,9 +24,12 @@ export declare class ToolExecutor {
23
24
  */
24
25
  private log;
25
26
  private guard?;
27
+ private taskGuard?;
26
28
  constructor(registry: ToolRegistry, permission: PermissionClassifier, hooks: HookRegistry);
27
29
  setInvestigationGuard(guard: InvestigationGuard | undefined): void;
28
30
  getInvestigationGuard(): InvestigationGuard | undefined;
31
+ setTaskGuard(guard: TaskGuard | undefined): void;
32
+ getTaskGuard(): TaskGuard | undefined;
29
33
  /** Set the abort signal for cascading cancellation. */
30
34
  setSignal(signal?: AbortSignal): void;
31
35
  /** Set the per-Engine ToolContext (askUser, llmConfig, modelPool, etc.). */
@@ -38,6 +38,13 @@ export interface SandboxBackend {
38
38
  }): {
39
39
  file: string;
40
40
  args: string[];
41
+ /**
42
+ * Optional callback the Bash tool calls after the child process exits.
43
+ * Backends that allocate per-command resources (e.g. seatbelt writes a
44
+ * profile file to a fresh temp dir) hang their cleanup here so a long
45
+ * session doesn't leak hundreds of temp dirs in /tmp.
46
+ */
47
+ cleanup?: () => void;
41
48
  };
42
49
  /**
43
50
  * If `stderr` looks like a sandbox denial, return a short hint string that
@@ -0,0 +1,30 @@
1
+ /**
2
+ * TaskGuard — nudges the model to update stale in_progress tasks.
3
+ *
4
+ * Background: TaskCreate is sticky in the model's working memory only for the
5
+ * first few turns. After enough intervening tool_results (Read/Edit/Bash) the
6
+ * "I have an open task" signal gets diluted and the model finishes its work
7
+ * without ever calling TaskUpdate(status="completed") — so the UI spinner runs
8
+ * forever on a task that the model considers done.
9
+ *
10
+ * Same shape as InvestigationGuard.turnEnded: turn-loop polls at the end of
11
+ * each turn; if anything is in_progress and hasn't been touched in N turns,
12
+ * we emit a <system-reminder> that lands at the top of the next turn.
13
+ *
14
+ * Re-nag policy: don't fire more than once per (task, threshold) pair. A task
15
+ * stale at turn 5 fires once; if the model still ignores it, we wait for it
16
+ * to cross the next threshold (8, 11, …) before firing again. This keeps the
17
+ * reminder from drowning out everything else when the model is genuinely
18
+ * stuck on something unrelated.
19
+ */
20
+ import type { Task } from "./builtin/task.js";
21
+ export declare class TaskGuard {
22
+ private taskListSource;
23
+ /** Last turn we nagged about a given task id. */
24
+ private lastNagTurn;
25
+ /** Turn the task was first observed in_progress (model-time, not wall-clock). */
26
+ private inProgressSince;
27
+ constructor(taskListSource: () => Task[]);
28
+ turnEnded(turnNumber: number): string | undefined;
29
+ reset(): void;
30
+ }
package/dist/types.d.ts CHANGED
@@ -249,6 +249,19 @@ export interface LLMConfig {
249
249
  timeout?: number;
250
250
  retryMaxAttempts?: number;
251
251
  enableStreaming?: boolean;
252
+ /**
253
+ * Default thinking-mode for DeepSeek V4. Per-call `options.thinking`
254
+ * (e.g. summarize sub-calls) overrides this. Ignored on other providers.
255
+ */
256
+ thinking?: "enabled" | "disabled";
257
+ /**
258
+ * The provider's `kind` (deepseek/openai/zai/openrouter/...). Used by
259
+ * the capability layer to look up per-(kind, model) request-shape rules
260
+ * (token-limit field, rejected sampling params, thinking shape, etc.).
261
+ * Distinct from `provider` above, which is the protocol family
262
+ * ("openai" or "anthropic") that picks which client class to use.
263
+ */
264
+ providerKind?: string;
252
265
  }
253
266
  export interface LLMResponse {
254
267
  text: string;
@@ -5,6 +5,11 @@ import { type MutableRefObject } from "react";
5
5
  export type SpinnerMode = "responding" | "tool-use" | "thinking";
6
6
  interface SpinnerWithVerbProps {
7
7
  mode: SpinnerMode;
8
+ /**
9
+ * Per-turn streamed token count — used purely as a "still alive" signal so
10
+ * the user sees activity. NOT a measure of context size; that's in the
11
+ * StatusLine ctx bar.
12
+ */
8
13
  streamingTokensRef?: MutableRefObject<number>;
9
14
  runStartRef?: MutableRefObject<number>;
10
15
  thinkingContent?: string;
@@ -12,7 +12,11 @@ interface StatusLineProps {
12
12
  tokens: number;
13
13
  cost: number;
14
14
  sessionId?: string;
15
- /** Last known prompt tokens from completed turn. Live streaming is added on top. */
15
+ /**
16
+ * Authoritative live context size. The engine emits `usage_update` at every
17
+ * message-array mutation (post-tool-result, post-compact, post-LLM), so this
18
+ * tracks the real prompt token count without UI-side accumulation.
19
+ */
16
20
  baseContextTokens?: number;
17
21
  maxContextTokens?: number;
18
22
  gitBranch?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cjhyy/code-shell",
3
- "version": "0.1.7",
3
+ "version": "0.2.0",
4
4
  "description": "Code Shell — general-purpose agent orchestration framework with a terminal coding preset",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1 +0,0 @@
1
- export{a as AnthropicClient}from'./chunk-WOP6MJKW.js';import'./chunk-O5HFCH2U.js';import'./chunk-HIJ2XXGX.js';import'./chunk-FU7AHZNN.js';import'./chunk-B7K2OWKC.js';import'./chunk-3QP5BQ3L.js';
@@ -1 +0,0 @@
1
- import {a as a$1}from'./chunk-P6JSTIFM.js';import {h,a}from'./chunk-3QP5BQ3L.js';h();var u=[[/^deepseek-v4(?:-|$)/i,1e6],[/(?:^|\/)deepseek-v4(?:-|$)/i,1e6]];function f(s){for(let[e,t]of u)if(e.test(s))return t}a(f,"lookupBuiltinContextWindow");var l=class{static{a(this,"ModelPool");}models=new Map;activeKey;providerCatalog;cacheDir;setProviderCatalog(e){this.providerCatalog=e;}setCacheDir(e){this.cacheDir=e;}reloadCachedContextWindows(){if(this.cacheDir)for(let[e,t]of this.models){if(t.maxContextTokens!=null||!t.providerKey)continue;let i=a$1(this.cacheDir,t.providerKey);if(!i)continue;let r=i.models.find(n=>n.id===t.model);r?.contextLength&&this.models.set(e,{...t,maxContextTokens:r.contextLength});}}constructor(e,t){if(e)for(let i of e)this.models.set(i.key,this.withBuiltinDefaults(i));t&&this.models.has(t)?this.activeKey=t:e?.length&&(this.activeKey=e[0].key);}register(e){this.models.set(e.key,this.withBuiltinDefaults(e)),this.activeKey||(this.activeKey=e.key);}withBuiltinDefaults(e){if(e.maxContextTokens!=null)return e;let t=f(e.model);return t==null?e:{...e,maxContextTokens:t}}switch(e){let t=this.models.get(e);if(!t){let i=[...this.models.keys()].join(", ");throw new Error(`Model "${e}" not found. Available: ${i}`)}return this.activeKey=e,t}get(e){if(e)return this.models.get(e);if(this.activeKey)return this.models.get(this.activeKey)}getActiveKey(){return this.activeKey}list(){return [...this.models.values()]}get size(){return this.models.size}has(e){return this.models.has(e)}toLLMConfig(e,t){let i=e.providerKey&&this.providerCatalog?this.providerCatalog.get(e.providerKey):void 0,r=a(n=>n&&n==="anthropic"?"anthropic":"openai","kindToClientProvider");return {provider:e.provider||r(i?.kind)||"openai",model:e.model,apiKey:e.apiKey??i?.apiKey??t?.apiKey,baseUrl:e.baseUrl??i?.baseUrl??t?.baseUrl,temperature:t?.temperature??.3,maxTokens:e.maxOutputTokens??t?.maxTokens??8192,enableStreaming:t?.enableStreaming??true}}resolveLLMConfig(e,t){let i=this.get(e);if(i)return this.toLLMConfig(i,t)}};export{l as a};
@@ -1,2 +0,0 @@
1
- import {h as h$1,a}from'./chunk-3QP5BQ3L.js';import {existsSync,mkdirSync,appendFileSync,readdirSync,unlinkSync}from'fs';import {join}from'path';import {homedir}from'os';h$1();var u={debug:0,info:1,warn:2,error:3},g=join(homedir(),".code-shell","logs"),h=7,R=100;function b(){return process.env.CODE_SHELL_DEV==="1"||process.argv.includes("--debug")||process.argv.includes("-d")||process.argv.some(r=>r.startsWith("--debug="))?true:process.env.NODE_ENV==="test"||process.env.BUN_TEST==="1"||process.argv.some(r=>r.includes("/tests/")||r.endsWith(".test.ts"))?false:!!(process.argv[1]??"").includes("/src/")}a(b,"isLocalDev");function x(){let o=process.env.CODE_SHELL_LOG_LEVEL?.toLowerCase().trim();return o&&Object.hasOwn(u,o)?o:b()?"debug":"info"}a(x,"resolveDefaultLevel");function D(){let o=process.argv.find(t=>t.startsWith("--debug=")),r;if(o)r=o.slice(8);else {let t=process.env.CODE_SHELL_DEBUG;t&&t!=="1"&&t!=="true"&&(r=t);}if(!r)return null;let e=new Set(r.split(",").map(t=>t.trim().toLowerCase()).filter(Boolean));return e.size>0?e:null}a(D,"resolveCategoryFilter");var v=`${Date.now()}-${Math.random().toString(36).slice(2,8)}`;function _(o){v=o;}a(_,"setCurrentSid");function C(){return v}a(C,"getCurrentSid");var l=[];var d=class o{constructor(r={}){this.context=r;this.enabled=process.env.CODE_SHELL_LOG!=="0",this.minLevel=x(),this.categoryFilter=D(),this.stderrEcho=process.env.CODE_SHELL_DEBUG==="1"||process.argv.includes("--debug-to-stderr")||process.argv.includes("-d2e");}static{a(this,"Logger");}enabled;minLevel;categoryFilter;stderrEcho;dirReady=false;child(r){return new o({...this.context,...r})}setSid(r){_(r);}getSid(){return C()}debug(r,e){this.write("debug",r,e);}info(r,e){this.write("info",r,e);}warn(r,e){this.write("warn",r,e);}error(r,e){let t,n;typeof r=="string"?(t=r,e instanceof Error?(n={error:e.message,stack:e.stack}):n=e):r instanceof Error?(t=r.message,n={stack:r.stack}):t=String(r),this.recordError(t,n),this.write("error",t,n);}recordError(r,e){l.length>=R&&l.shift(),l.push({msg:r,t:new Date().toISOString(),data:e});}write(r,e,t){if(!this.enabled||u[r]<u[this.minLevel])return;let n=t?.cat??this.context.cat;if(r==="debug"&&this.categoryFilter&&(!n||!this.categoryFilter.has(n.toLowerCase())))return;let i=new Date().toISOString(),c={t:i,l:r,msg:e,...this.context};n&&!c.cat&&(c.cat=n),c.sid===void 0&&(c.sid=v),t&&(c.d=t);let a=JSON.stringify(c)+`
2
- `;if(this.stderrEcho){process.stderr.write(a);return}try{this.dirReady||(existsSync(g)||mkdirSync(g,{recursive:!0}),this.dirReady=!0);let w=i.slice(0,10);appendFileSync(join(g,`${w}.log`),a,"utf-8");}catch{}}getMinLevel(){return this.minLevel}isCategoryActive(r){return !this.categoryFilter||this.categoryFilter.has(r.toLowerCase())}span(r,e){let t=Date.now();return this.write("debug",`${r}.begin`,e),{end:a(n=>{let i=Date.now()-t;this.write("info",`${r}.end`,{...e,...n,duration_ms:i});},"end"),fail:a((n,i)=>{let c=Date.now()-t,a=n instanceof Error?n.message:String(n);this.write("error",`${r}.fail`,{...e,...i,duration_ms:c,error:a});},"fail")}}},B=new d;function H(){try{if(!existsSync(g))return;let o=readdirSync(g).filter(r=>r.endsWith(".log")).sort();if(o.length<=h)return;for(let r of o.slice(0,o.length-h))try{unlinkSync(join(g,r));}catch{}}catch{}}a(H,"rotateLogs");export{C as a,B as b,H as c};
@@ -1,2 +0,0 @@
1
- import {a as a$1,c as c$1,b}from'./chunk-P6JSTIFM.js';import {h,a}from'./chunk-3QP5BQ3L.js';import {existsSync,readFileSync}from'fs';import {fileURLToPath}from'url';import {dirname,join}from'path';h();h();var S=/(?:^|[-_/])(?:embed(?:ding)?|whisper|tts|audio|image|dall-?e|moderation|rerank|guard|vision-only)(?:$|[-_/])/i,i=a(e=>!S.test(e),"isChatLike"),s=a(e=>e?{Authorization:`Bearer ${e}`}:{},"bearer"),g={openai:{label:"OpenAI",defaultBaseUrl:"https://api.openai.com/v1",modelsPath:"/models",protocol:"openai-compat",authHeader:s,chatFilter:i},anthropic:{label:"Anthropic",defaultBaseUrl:"https://api.anthropic.com/v1",modelsPath:"/models",protocol:"anthropic-style",authHeader:a(e=>e?{"x-api-key":e,"anthropic-version":"2023-06-01"}:{"anthropic-version":"2023-06-01"},"authHeader"),chatFilter:i},deepseek:{label:"DeepSeek",defaultBaseUrl:"https://api.deepseek.com/v1",modelsPath:"/models",protocol:"openai-compat",authHeader:s,chatFilter:i},xai:{label:"xAI (Grok)",defaultBaseUrl:"https://api.x.ai/v1",modelsPath:"/models",protocol:"openai-compat",authHeader:s,chatFilter:i},mistral:{label:"Mistral",defaultBaseUrl:"https://api.mistral.ai/v1",modelsPath:"/models",protocol:"openai-compat",authHeader:s,chatFilter:i},groq:{label:"Groq",defaultBaseUrl:"https://api.groq.com/openai/v1",modelsPath:"/models",protocol:"openai-compat",authHeader:s,chatFilter:i},google:{label:"Google Gemini",defaultBaseUrl:"https://generativelanguage.googleapis.com/v1beta",modelsPath:"/models",protocol:"gemini",authHeader:a(()=>({}),"authHeader"),authQuery:a(e=>e?{key:e}:{},"authQuery"),chatFilter:a(e=>i(e)&&/gemini/i.test(e),"chatFilter")},openrouter:{label:"OpenRouter",defaultBaseUrl:"https://openrouter.ai/api/v1",modelsPath:"/models",protocol:"openai-compat",authHeader:s,chatFilter:i},ollama:{label:"Ollama (local)",defaultBaseUrl:"http://localhost:11434",modelsPath:"/api/tags",protocol:"ollama",authHeader:a(()=>({}),"authHeader"),chatFilter:i},custom:{label:"Custom",defaultBaseUrl:"",modelsPath:"/models",protocol:"openai-compat",authHeader:s,chatFilter:i}};function f(e){return g[e]??g.custom}a(f,"getKindMeta");var U=dirname(fileURLToPath(import.meta.url)),x=join(U,"..","data","openrouter-models.json");async function q(e,a){let n=f(e.kind);if(!a.refresh){let o=a$1(a.cacheDir,e.key);if(o&&!c$1(o))return {...o,fromCache:true}}if(e.kind==="openrouter")return L(e.key,a.cacheDir);try{let o=e.modelsPath??n.modelsPath,t=new URL(M(e.baseUrl,o)),P=n.authHeader(e.apiKey??"");if(n.authQuery){let m=n.authQuery(e.apiKey??"");for(let[R,b]of Object.entries(m))t.searchParams.set(R,b);}let p=await fetch(t.toString(),{headers:{Accept:"application/json",...P},signal:AbortSignal.timeout(a.timeoutMs??2e4)});if(!p.ok)return c(e.key,a.cacheDir,`HTTP ${p.status}`);let k=await p.json(),y=H(k,n.protocol).filter(m=>n.chatFilter(m.id));return b(a.cacheDir,e.key,y)}catch(o){let t=o.message||String(o);return c(e.key,a.cacheDir,t)}}a(q,"fetchModelList");function H(e,a){switch(a){case "ollama":return (e.models??[]).map(t=>({id:t.name,contextLength:0,maxOutputTokens:0}));case "anthropic-style":return (e.data??[]).map(t=>({id:t.id,contextLength:t.context_window??2e5,maxOutputTokens:t.max_output_tokens??0}));case "gemini":return (e.models??[]).map(t=>({id:t.name.replace(/^models\//,""),contextLength:t.inputTokenLimit??0,maxOutputTokens:t.outputTokenLimit??0}));case "openai-compat":return (e.data??[]).map(t=>({id:t.id,contextLength:t.context_window??t.context_length??0,maxOutputTokens:t.max_completion_tokens??0}))}return a}a(H,"normalize");function L(e,a){if(!existsSync(x))return c(e,a,"openrouter snapshot missing");try{let o=(JSON.parse(readFileSync(x,"utf-8")).models??[]).map(t=>({id:t.id,contextLength:t.contextLength??0,maxOutputTokens:t.maxOutputTokens??0}));return b(a,e,o)}catch(n){return c(e,a,n.message)}}a(L,"loadOpenRouterSnapshot");function c(e,a,n){let o=a$1(a,e);return o?{...o,error:n,fromCache:true}:{fetchedAt:new Date().toISOString(),providerKey:e,models:[],error:n}}a(c,"errorResult");function M(e,a){return e?`${e.replace(/\/$/,"")}${a.startsWith("/")?"":"/"}${a}`:a}a(M,"joinUrl");
2
- export{g as a,q as b};