@cjhyy/code-shell 0.1.0-alpha.2 → 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.
- package/CHANGELOG.md +77 -0
- package/dist/anthropic-IBTI4WL2.cjs +10 -0
- package/dist/anthropic-PRZZKHEZ.js +10 -0
- package/dist/arena/index.cjs +7 -6
- package/dist/arena/index.js +6 -5
- package/dist/arena/model-presets.d.ts +10 -1
- package/dist/{arena-HHDYYVHJ.cjs → arena-KBQOPLFV.cjs} +25 -23
- package/dist/{arena-ENHBHB2W.js → arena-O2L4TN6A.js} +9 -7
- package/dist/{chunk-SW3L7HIM.js → chunk-2EP3CLEN.js} +2 -2
- package/dist/{chunk-EL2RL5DG.cjs → chunk-2YW4FPFG.cjs} +2 -2
- package/dist/chunk-3OA5G4TM.js +47 -0
- package/dist/chunk-52LGZKT3.cjs +47 -0
- package/dist/{chunk-KOGV6PDQ.cjs → chunk-55XGPMAP.cjs} +44 -9
- package/dist/chunk-5ECBT4YA.js +450 -0
- package/dist/{chunk-YD7XTI7T.cjs → chunk-6QVAYW7C.cjs} +116 -28
- package/dist/{chunk-SCDKLTN3.js → chunk-6S4BJ65N.js} +5 -4
- package/dist/{chunk-ZLPJJZUW.js → chunk-76HYEPDM.js} +2 -2
- package/dist/{chunk-FA5KD34T.js → chunk-76W334S4.js} +2 -2
- package/dist/{chunk-GZBD6QRS.cjs → chunk-7EG3V4JY.cjs} +13 -12
- package/dist/{chunk-LMEKCQX4.js → chunk-7JVTYEEC.js} +6 -6
- package/dist/{chunk-ID6EJUHP.js → chunk-7K6SDRRF.js} +1262 -212
- package/dist/{chunk-5C5HIOML.js → chunk-7Y6S3OCX.js} +109 -21
- package/dist/{chunk-G76E5FOB.cjs → chunk-A5LCRPDP.cjs} +4 -4
- package/dist/{chunk-F5BS3GUC.js → chunk-BSW22MPA.js} +39 -4
- package/dist/{chunk-VWFET3MG.cjs → chunk-BUU5PZK2.cjs} +1474 -423
- package/dist/{chunk-HOXQLX5R.cjs → chunk-BWTOS5BH.cjs} +444 -103
- package/dist/{chunk-ZRVPCXI7.js → chunk-BXCY2FSE.js} +2 -1
- package/dist/{chunk-Y7TSCDF6.js → chunk-C5YQBIRK.js} +347 -6
- package/dist/{chunk-C7C7ZZY4.cjs → chunk-HEKQCI7B.cjs} +10 -10
- package/dist/{chunk-JHXNOB5G.cjs → chunk-HS2MFNUC.cjs} +6 -6
- package/dist/{chunk-JHNCK7JP.cjs → chunk-IK4EWJBP.cjs} +4 -3
- package/dist/{chunk-M2QI5X3X.cjs → chunk-JMR33QVF.cjs} +2 -2
- package/dist/{chunk-YAFCN7ZW.cjs → chunk-KOVYSDHZ.cjs} +15 -15
- package/dist/{chunk-IJSHQGMP.cjs → chunk-KS3RYAYL.cjs} +4 -4
- package/dist/{chunk-DI7RDLOS.js → chunk-MD32R22I.js} +7 -4
- package/dist/chunk-MY5XHADU.cjs +216 -0
- package/dist/{chunk-OP57WUWQ.cjs → chunk-NUNC3VFB.cjs} +6 -6
- package/dist/{chunk-TATCTZSB.cjs → chunk-QRM7IF2S.cjs} +133 -175
- package/dist/chunk-R47ROHGL.cjs +298 -0
- package/dist/{chunk-OUC2DFA7.js → chunk-RMYKO74M.js} +3 -3
- package/dist/{chunk-FUOKLKR2.js → chunk-SFXHZSRF.js} +1 -1
- package/dist/{chunk-2EUAE7AY.js → chunk-SIHHIQLO.js} +2 -2
- package/dist/{chunk-3CAZIWUA.cjs → chunk-SNT563K3.cjs} +9 -9
- package/dist/{chunk-SK62UVS6.js → chunk-T6VYG46N.js} +1 -1
- package/dist/{chunk-3QR52LL5.cjs → chunk-TUY2T5KP.cjs} +2 -2
- package/dist/{chunk-I57ZD5IQ.js → chunk-VIAGTYYW.js} +1 -1
- package/dist/{chunk-X2DNIMPC.cjs → chunk-VYL4EFRC.cjs} +32 -32
- package/dist/chunk-W22P377T.js +299 -0
- package/dist/chunk-WASS5YWB.js +215 -0
- package/dist/{chunk-OMRGA6TI.js → chunk-XDIQWQJ4.js} +132 -174
- package/dist/{chunk-BUJ5KYCI.cjs → chunk-YIQBXAYU.cjs} +13 -13
- package/dist/{chunk-REFCCVDM.js → chunk-YJ77GQK5.js} +2 -2
- package/dist/chunk-YUI524OE.cjs +450 -0
- package/dist/{chunk-M2SVOKC6.js → chunk-ZBPSQCPU.js} +6 -6
- package/dist/cli/commands/builtin/export-md.d.ts +19 -0
- package/dist/cli/commands/builtin/init/detect.d.ts +25 -0
- package/dist/cli/commands/builtin/init/index.d.ts +19 -0
- package/dist/cli/main.cjs +2374 -1455
- package/dist/cli/main.js +2505 -1586
- package/dist/cli/migrate-models.d.ts +45 -0
- package/dist/cli/onboarding.d.ts +110 -5
- package/dist/cli/updater.d.ts +51 -4
- package/dist/client-base-HTF236ZD.cjs +9 -0
- package/dist/client-base-QKRKCOWB.js +9 -0
- package/dist/{compaction-YNWCEF7B.js → compaction-6VU2T643.js} +4 -2
- package/dist/compaction-OKUNTCA7.cjs +33 -0
- package/dist/context/compaction.d.ts +35 -3
- package/dist/context/manager.d.ts +40 -3
- package/dist/context/tool-result-storage.d.ts +96 -0
- package/dist/devtools-T2NIZBJK.cjs +6 -0
- package/dist/{devtools-IRQQPIRY.js → devtools-YXWHOVKR.js} +1 -1
- package/dist/engine/engine.d.ts +40 -0
- package/dist/engine/turn-loop.d.ts +6 -0
- package/dist/export-md-RXDW6F5W.cjs +135 -0
- package/dist/export-md-XXKZANW5.js +135 -0
- package/dist/file-history-KYPE3ECT.cjs +7 -0
- package/dist/file-history-LF4F7X26.js +7 -0
- package/dist/index.cjs +42 -22
- package/dist/index.d.ts +5 -2
- package/dist/index.js +40 -20
- package/dist/llm/client-base.d.ts +1 -1
- package/dist/llm/model-cache.d.ts +21 -0
- package/dist/llm/model-fetcher.d.ts +29 -0
- package/dist/llm/model-pool.d.ts +13 -0
- package/dist/llm/provider-catalog.d.ts +30 -0
- package/dist/llm/provider-kinds.d.ts +21 -0
- package/dist/llm/types.d.ts +8 -0
- package/dist/logging/session-recorder.d.ts +77 -0
- package/dist/manager-C2IUXKRC.js +7 -0
- package/dist/manager-YYKWYTRM.cjs +7 -0
- package/dist/mcp-manager-QMKWPBZ4.js +8 -0
- package/dist/mcp-manager-Z3OKI74O.cjs +8 -0
- package/dist/memory-5LWZ6FI2.cjs +9 -0
- package/dist/{memory-EPFDBPII.js → memory-VIJLBAMQ.js} +2 -2
- package/dist/model-cache-5KIYL5SL.js +13 -0
- package/dist/model-cache-OED3IM4R.cjs +13 -0
- package/dist/model-fetcher-HKGICACL.js +8 -0
- package/dist/model-fetcher-UR6WJOQP.cjs +8 -0
- package/dist/openai-JR2WEKOF.js +10 -0
- package/dist/openai-YBTOET4O.cjs +10 -0
- package/dist/openrouter-models-OU4GRZQY.cjs +15 -0
- package/dist/{openrouter-models-OL725CL6.js → openrouter-models-TGKDKY52.js} +2 -2
- package/dist/openrouter-sync-BBHUM3R6.cjs +11 -0
- package/dist/{openrouter-sync-CWD5VNW2.js → openrouter-sync-UXUSJCIR.js} +3 -3
- package/dist/product/index.cjs +17 -15
- package/dist/product/index.js +16 -14
- package/dist/protocol/server.d.ts +3 -1
- package/dist/protocol/types.d.ts +36 -2
- package/dist/run/index.cjs +17 -15
- package/dist/run/index.js +16 -14
- package/dist/services/index.d.ts +0 -1
- package/dist/session-manager-Q22BBMD3.js +8 -0
- package/dist/session-manager-XODQVL3C.cjs +8 -0
- package/dist/settings/schema.d.ts +267 -42
- package/dist/{tool-summary-RYNR4DDB.cjs → tool-summary-63DPIS7G.cjs} +4 -4
- package/dist/{tool-summary-2RUFL5QK.js → tool-summary-NP5CDBKG.js} +2 -2
- package/dist/tool-system/builtin/ask-user.d.ts +9 -1
- package/dist/tool-system/context.d.ts +31 -2
- package/dist/tool-system/executor.d.ts +4 -0
- package/dist/tool-system/investigation-guard.d.ts +37 -0
- package/dist/types.d.ts +13 -2
- package/dist/ui/components/AskUserPrompt.d.ts +8 -1
- package/dist/ui/components/DiffLine.d.ts +33 -0
- package/dist/ui/components/ModelManager.d.ts +34 -1
- package/dist/ui/components/OnboardingPrompt.d.ts +10 -1
- package/dist/ui/components/ProviderModelFlow.d.ts +58 -0
- package/dist/ui/components/UpdateBanner.d.ts +1 -0
- package/dist/updater-QW473OF4.cjs +17 -0
- package/dist/updater-VFUAHCVY.js +17 -0
- package/dist/utils/semver.d.ts +1 -0
- package/dist/utils/task-sanitizer.d.ts +6 -0
- package/package.json +4 -2
- package/scripts/check-node.cjs +21 -0
- package/dist/anthropic-P5VETAFI.cjs +0 -10
- package/dist/anthropic-W2GU3D76.js +0 -10
- package/dist/chunk-75E4BBFC.js +0 -224
- package/dist/chunk-FV2ARONZ.cjs +0 -224
- package/dist/client-base-TOVE25FA.js +0 -9
- package/dist/client-base-VDDIADAC.cjs +0 -9
- package/dist/compaction-D3KV2NWY.cjs +0 -31
- package/dist/devtools-WTC3NFNE.cjs +0 -6
- package/dist/file-history-HZWO2WQ5.js +0 -7
- package/dist/file-history-UQQILIY7.cjs +0 -7
- package/dist/manager-FWLOVEEK.cjs +0 -7
- package/dist/manager-GEXJLOIS.js +0 -7
- package/dist/mcp-manager-37GQLFGX.js +0 -8
- package/dist/mcp-manager-U77NEXBY.cjs +0 -8
- package/dist/memory-ADGOWADP.cjs +0 -9
- package/dist/openai-RXU5URYI.js +0 -10
- package/dist/openai-SQW4H2K4.cjs +0 -10
- package/dist/openrouter-models-UM3AOGZ4.cjs +0 -15
- package/dist/openrouter-sync-HYZZC6RX.cjs +0 -11
- package/dist/services/compact.d.ts +0 -56
- package/dist/session-manager-HRSKENKB.cjs +0 -8
- package/dist/session-manager-NEKFEHF3.js +0 -8
- package/dist/updater-M7L42ASZ.cjs +0 -183
- package/dist/updater-ZRTONIR4.js +0 -183
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } var _class;
|
|
2
|
+
|
|
3
|
+
var _chunkKS3RYAYLcjs = require('./chunk-KS3RYAYL.cjs');
|
|
4
|
+
|
|
5
|
+
// src/settings/manager.ts
|
|
6
|
+
_chunkKS3RYAYLcjs.init_cjs_shims.call(void 0, );
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
var _fs = require('fs');
|
|
15
|
+
var _path = require('path');
|
|
16
|
+
var _os = require('os');
|
|
17
|
+
|
|
18
|
+
// src/settings/schema.ts
|
|
19
|
+
_chunkKS3RYAYLcjs.init_cjs_shims.call(void 0, );
|
|
20
|
+
var _zod = require('zod');
|
|
21
|
+
var SettingsSchema = _zod.z.object({
|
|
22
|
+
agent: _zod.z.object({
|
|
23
|
+
// Use z.string() instead of z.enum() to allow custom presets registered via registerPreset()
|
|
24
|
+
preset: _zod.z.string().default("terminal-coding"),
|
|
25
|
+
enabledBuiltinTools: _zod.z.array(_zod.z.string()).default([]),
|
|
26
|
+
disabledBuiltinTools: _zod.z.array(_zod.z.string()).default([]),
|
|
27
|
+
customSystemPrompt: _zod.z.string().optional(),
|
|
28
|
+
appendSystemPrompt: _zod.z.string().optional()
|
|
29
|
+
}).default({}),
|
|
30
|
+
/**
|
|
31
|
+
* Primary source of truth for the active model is settings.activeKey
|
|
32
|
+
* (points at models[].key). settings.model is a derived mirror of that
|
|
33
|
+
* entry kept in sync for legacy boot paths (cli/main.ts, repl.ts, etc.)
|
|
34
|
+
* which read provider/name/apiKey/baseUrl directly. Writers must update
|
|
35
|
+
* both — appendOnboardingResult does this in one shot.
|
|
36
|
+
*/
|
|
37
|
+
activeKey: _zod.z.string().optional(),
|
|
38
|
+
/**
|
|
39
|
+
* Toggle background auto-update. When true (default), code-shell checks
|
|
40
|
+
* npm for newer versions and — if the npm global prefix is writable —
|
|
41
|
+
* installs the update in the background on process exit so the next
|
|
42
|
+
* launch picks it up.
|
|
43
|
+
* Can also be disabled via env var `DISABLE_AUTOUPDATER=1`.
|
|
44
|
+
*/
|
|
45
|
+
autoUpdates: _zod.z.boolean().default(true),
|
|
46
|
+
model: _zod.z.object({
|
|
47
|
+
provider: _zod.z.string().default("openai"),
|
|
48
|
+
name: _zod.z.string().default("anthropic/claude-opus-4-6"),
|
|
49
|
+
apiKey: _zod.z.string().optional(),
|
|
50
|
+
baseUrl: _zod.z.string().default("https://openrouter.ai/api/v1"),
|
|
51
|
+
temperature: _zod.z.number().min(0).max(2).default(0.3),
|
|
52
|
+
maxTokens: _zod.z.number().default(8192)
|
|
53
|
+
}).default({}),
|
|
54
|
+
providers: _zod.z.array(
|
|
55
|
+
_zod.z.object({
|
|
56
|
+
key: _zod.z.string(),
|
|
57
|
+
label: _zod.z.string().optional(),
|
|
58
|
+
kind: _zod.z.enum([
|
|
59
|
+
"openai",
|
|
60
|
+
"anthropic",
|
|
61
|
+
"deepseek",
|
|
62
|
+
"xai",
|
|
63
|
+
"mistral",
|
|
64
|
+
"groq",
|
|
65
|
+
"google",
|
|
66
|
+
"openrouter",
|
|
67
|
+
"ollama",
|
|
68
|
+
"custom"
|
|
69
|
+
]),
|
|
70
|
+
baseUrl: _zod.z.string(),
|
|
71
|
+
apiKey: _zod.z.string().optional(),
|
|
72
|
+
protocol: _zod.z.enum(["openai-compat", "anthropic-style"]).optional(),
|
|
73
|
+
modelsPath: _zod.z.string().optional()
|
|
74
|
+
})
|
|
75
|
+
).default([]),
|
|
76
|
+
models: _zod.z.array(
|
|
77
|
+
_zod.z.object({
|
|
78
|
+
key: _zod.z.string(),
|
|
79
|
+
label: _zod.z.string().optional(),
|
|
80
|
+
providerKey: _zod.z.string().optional(),
|
|
81
|
+
model: _zod.z.string(),
|
|
82
|
+
maxOutputTokens: _zod.z.number().optional(),
|
|
83
|
+
maxContextTokens: _zod.z.number().optional(),
|
|
84
|
+
/**
|
|
85
|
+
* Which LLM client to use ("openai" or "anthropic"). New name —
|
|
86
|
+
* the legacy field is `provider`, which we still accept and
|
|
87
|
+
* fold into `protocol` below so old configs keep working.
|
|
88
|
+
* NOT the brand/vendor — that's providerKey above.
|
|
89
|
+
*/
|
|
90
|
+
protocol: _zod.z.string().optional(),
|
|
91
|
+
provider: _zod.z.string().optional(),
|
|
92
|
+
baseUrl: _zod.z.string().optional(),
|
|
93
|
+
apiKey: _zod.z.string().optional()
|
|
94
|
+
}).transform((m) => {
|
|
95
|
+
const effective = _nullishCoalesce(m.protocol, () => ( m.provider));
|
|
96
|
+
return {
|
|
97
|
+
...m,
|
|
98
|
+
protocol: effective,
|
|
99
|
+
provider: effective
|
|
100
|
+
};
|
|
101
|
+
})
|
|
102
|
+
).default([]),
|
|
103
|
+
permissions: _zod.z.object({
|
|
104
|
+
defaultMode: _zod.z.enum(["default", "acceptEdits", "dontAsk", "bypassPermissions", "auto", "plan"]).default("default"),
|
|
105
|
+
rules: _zod.z.array(
|
|
106
|
+
_zod.z.object({
|
|
107
|
+
tool: _zod.z.string(),
|
|
108
|
+
argsPattern: _zod.z.record(_zod.z.string()).optional(),
|
|
109
|
+
decision: _zod.z.enum(["allow", "deny", "ask"]),
|
|
110
|
+
reason: _zod.z.string().optional()
|
|
111
|
+
})
|
|
112
|
+
).default([])
|
|
113
|
+
}).default({}),
|
|
114
|
+
context: _zod.z.object({
|
|
115
|
+
maxTokens: _zod.z.number().default(2e5),
|
|
116
|
+
compactAtRatio: _zod.z.number().default(0.6),
|
|
117
|
+
summarizeAtRatio: _zod.z.number().default(0.8)
|
|
118
|
+
}).default({}),
|
|
119
|
+
session: _zod.z.object({
|
|
120
|
+
storageDir: _zod.z.string().optional(),
|
|
121
|
+
maxHistory: _zod.z.number().default(100)
|
|
122
|
+
}).default({}),
|
|
123
|
+
mcpServers: _zod.z.record(
|
|
124
|
+
_zod.z.object({
|
|
125
|
+
name: _zod.z.string(),
|
|
126
|
+
command: _zod.z.string().optional(),
|
|
127
|
+
args: _zod.z.array(_zod.z.string()).optional(),
|
|
128
|
+
env: _zod.z.record(_zod.z.string()).optional(),
|
|
129
|
+
url: _zod.z.string().optional(),
|
|
130
|
+
transport: _zod.z.enum(["stdio", "sse", "streamable-http", "inprocess"]).optional(),
|
|
131
|
+
headers: _zod.z.record(_zod.z.string()).optional()
|
|
132
|
+
})
|
|
133
|
+
).default({}),
|
|
134
|
+
instructions: _zod.z.object({
|
|
135
|
+
fileName: _zod.z.string().default("CODESHELL.md"),
|
|
136
|
+
scanDirs: _zod.z.array(_zod.z.string()).default([]),
|
|
137
|
+
compatFileNames: _zod.z.array(_zod.z.string()).default(["CLAUDE.md", "AGENTS.md"]),
|
|
138
|
+
ignoreGitBoundary: _zod.z.boolean().default(false)
|
|
139
|
+
}).default({}),
|
|
140
|
+
arena: _zod.z.object({
|
|
141
|
+
participants: _zod.z.array(
|
|
142
|
+
_zod.z.union([
|
|
143
|
+
// Short form: just a model pool key
|
|
144
|
+
_zod.z.string(),
|
|
145
|
+
// Full form: explicit config (backward compat)
|
|
146
|
+
_zod.z.object({
|
|
147
|
+
name: _zod.z.string(),
|
|
148
|
+
model: _zod.z.string(),
|
|
149
|
+
provider: _zod.z.string().optional(),
|
|
150
|
+
apiKey: _zod.z.string().optional(),
|
|
151
|
+
baseUrl: _zod.z.string().optional()
|
|
152
|
+
})
|
|
153
|
+
])
|
|
154
|
+
).default([])
|
|
155
|
+
}).default({}),
|
|
156
|
+
search: _zod.z.object({
|
|
157
|
+
provider: _zod.z.enum(["serper", "tavily", "searxng"]).default("serper"),
|
|
158
|
+
apiKey: _zod.z.string().optional(),
|
|
159
|
+
baseUrl: _zod.z.string().optional()
|
|
160
|
+
}).default({}),
|
|
161
|
+
output: _zod.z.object({
|
|
162
|
+
format: _zod.z.enum(["text", "json", "jsonl", "stream-json"]).default("text")
|
|
163
|
+
}).default({})
|
|
164
|
+
}).passthrough();
|
|
165
|
+
function validateSettings(raw) {
|
|
166
|
+
return SettingsSchema.parse(raw);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// src/cli/migrate-models.ts
|
|
170
|
+
_chunkKS3RYAYLcjs.init_cjs_shims.call(void 0, );
|
|
171
|
+
var BASEURL_KIND_PATTERNS = [
|
|
172
|
+
[/deepseek\.com/i, "deepseek"],
|
|
173
|
+
[/anthropic\.com/i, "anthropic"],
|
|
174
|
+
[/openai\.com/i, "openai"],
|
|
175
|
+
[/x\.ai/i, "xai"],
|
|
176
|
+
[/mistral\.ai/i, "mistral"],
|
|
177
|
+
[/groq\.com/i, "groq"],
|
|
178
|
+
[/generativelanguage\.googleapis/i, "google"],
|
|
179
|
+
[/openrouter\.ai/i, "openrouter"],
|
|
180
|
+
[/localhost:11434|127\.0\.0\.1:11434/i, "ollama"]
|
|
181
|
+
];
|
|
182
|
+
function inferKind(baseUrl) {
|
|
183
|
+
if (!baseUrl) return "custom";
|
|
184
|
+
for (const [re, kind] of BASEURL_KIND_PATTERNS) {
|
|
185
|
+
if (re.test(baseUrl)) return kind;
|
|
186
|
+
}
|
|
187
|
+
return "custom";
|
|
188
|
+
}
|
|
189
|
+
function makeFingerprint(m) {
|
|
190
|
+
return `${_nullishCoalesce(m.provider, () => ( ""))}|${_nullishCoalesce(m.baseUrl, () => ( ""))}|${_nullishCoalesce(m.apiKey, () => ( ""))}`;
|
|
191
|
+
}
|
|
192
|
+
function deriveKey(base, used) {
|
|
193
|
+
if (!used.has(base)) return base;
|
|
194
|
+
for (let i = 2; ; i++) {
|
|
195
|
+
const candidate = `${base}-${i}`;
|
|
196
|
+
if (!used.has(candidate)) return candidate;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
function deriveProviderModelKey(providerKind, modelId, used) {
|
|
200
|
+
const slash = modelId.lastIndexOf("/");
|
|
201
|
+
const base = slash >= 0 ? modelId.slice(slash + 1) : modelId;
|
|
202
|
+
const prefix = providerKind.toLowerCase();
|
|
203
|
+
const candidate = base.toLowerCase().startsWith(`${prefix}-`) ? base : `${prefix}-${base}`;
|
|
204
|
+
if (!used.has(candidate)) return candidate;
|
|
205
|
+
for (let i = 2; ; i++) {
|
|
206
|
+
const k = `${candidate}-${i}`;
|
|
207
|
+
if (!used.has(k)) return k;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
function migrateModels(input) {
|
|
211
|
+
if (input.models.length === 0) {
|
|
212
|
+
return {
|
|
213
|
+
providers: input.providers,
|
|
214
|
+
models: [],
|
|
215
|
+
changed: false
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
const hasProvidersSection = input.providers.length > 0;
|
|
219
|
+
const keyCounts = /* @__PURE__ */ new Map();
|
|
220
|
+
for (const m of input.models) keyCounts.set(m.key, (_nullishCoalesce(keyCounts.get(m.key), () => ( 0))) + 1);
|
|
221
|
+
const needsMigration = input.models.some(
|
|
222
|
+
(m) => !m.providerKey || (_nullishCoalesce(keyCounts.get(m.key), () => ( 0))) > 1
|
|
223
|
+
);
|
|
224
|
+
if (!needsMigration) {
|
|
225
|
+
return {
|
|
226
|
+
providers: input.providers,
|
|
227
|
+
models: input.models.map((m) => ({
|
|
228
|
+
key: m.key,
|
|
229
|
+
label: m.label,
|
|
230
|
+
providerKey: _nullishCoalesce(m.providerKey, () => ( "")),
|
|
231
|
+
model: m.model,
|
|
232
|
+
maxOutputTokens: m.maxOutputTokens,
|
|
233
|
+
maxContextTokens: m.maxContextTokens,
|
|
234
|
+
provider: m.provider,
|
|
235
|
+
baseUrl: m.baseUrl,
|
|
236
|
+
apiKey: m.apiKey
|
|
237
|
+
})),
|
|
238
|
+
changed: false
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
const fingerprintToKey = /* @__PURE__ */ new Map();
|
|
242
|
+
const newProviders = [];
|
|
243
|
+
const usedProviderKeys = new Set(input.providers.map((p) => p.key));
|
|
244
|
+
for (const p of input.providers) {
|
|
245
|
+
const fp = `${""}|${p.baseUrl}|${_nullishCoalesce(p.apiKey, () => ( ""))}`;
|
|
246
|
+
fingerprintToKey.set(fp, p.key);
|
|
247
|
+
}
|
|
248
|
+
for (const m of input.models) {
|
|
249
|
+
const fp = makeFingerprint(m);
|
|
250
|
+
const existingByUrl = input.providers.find((p) => p.baseUrl === (_nullishCoalesce(m.baseUrl, () => ( ""))));
|
|
251
|
+
if (existingByUrl) {
|
|
252
|
+
fingerprintToKey.set(fp, existingByUrl.key);
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
if (fingerprintToKey.has(fp)) continue;
|
|
256
|
+
const kind = inferKind(m.baseUrl);
|
|
257
|
+
const key = deriveKey(kind, usedProviderKeys);
|
|
258
|
+
usedProviderKeys.add(key);
|
|
259
|
+
fingerprintToKey.set(fp, key);
|
|
260
|
+
newProviders.push({
|
|
261
|
+
key,
|
|
262
|
+
kind,
|
|
263
|
+
baseUrl: _nullishCoalesce(m.baseUrl, () => ( "")),
|
|
264
|
+
apiKey: m.apiKey
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
const usedModelKeys = /* @__PURE__ */ new Set();
|
|
268
|
+
const newModels = input.models.map((m) => {
|
|
269
|
+
const providerKey = fingerprintToKey.get(makeFingerprint(m));
|
|
270
|
+
const collides = (_nullishCoalesce(keyCounts.get(m.key), () => ( 0))) > 1;
|
|
271
|
+
let key = m.key;
|
|
272
|
+
if (collides) {
|
|
273
|
+
const kind = inferKind(m.baseUrl);
|
|
274
|
+
key = deriveProviderModelKey(kind, m.model, usedModelKeys);
|
|
275
|
+
}
|
|
276
|
+
if (usedModelKeys.has(key)) {
|
|
277
|
+
const kind = inferKind(m.baseUrl);
|
|
278
|
+
key = deriveProviderModelKey(kind, m.model, usedModelKeys);
|
|
279
|
+
}
|
|
280
|
+
usedModelKeys.add(key);
|
|
281
|
+
return {
|
|
282
|
+
key,
|
|
283
|
+
label: m.label,
|
|
284
|
+
providerKey,
|
|
285
|
+
provider: m.provider,
|
|
286
|
+
model: m.model,
|
|
287
|
+
baseUrl: m.baseUrl,
|
|
288
|
+
apiKey: m.apiKey,
|
|
289
|
+
maxOutputTokens: m.maxOutputTokens,
|
|
290
|
+
maxContextTokens: m.maxContextTokens
|
|
291
|
+
};
|
|
292
|
+
});
|
|
293
|
+
const seen = /* @__PURE__ */ new Set();
|
|
294
|
+
const deduped = newModels.filter((m) => {
|
|
295
|
+
const fp = `${m.key}|${m.model}`;
|
|
296
|
+
if (seen.has(fp)) return false;
|
|
297
|
+
seen.add(fp);
|
|
298
|
+
return true;
|
|
299
|
+
});
|
|
300
|
+
return {
|
|
301
|
+
providers: hasProvidersSection ? [...input.providers, ...newProviders] : newProviders,
|
|
302
|
+
models: deduped,
|
|
303
|
+
changed: true
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// src/settings/manager.ts
|
|
308
|
+
function userHome() {
|
|
309
|
+
return _nullishCoalesce(process.env.HOME, () => ( _os.homedir.call(void 0, )));
|
|
310
|
+
}
|
|
311
|
+
var SettingsManager = (_class = class {
|
|
312
|
+
constructor(cwd = process.cwd()) {;_class.prototype.__init.call(this);_class.prototype.__init2.call(this);
|
|
313
|
+
this.cwd = cwd;
|
|
314
|
+
}
|
|
315
|
+
__init() {this.sources = []}
|
|
316
|
+
__init2() {this.merged = null}
|
|
317
|
+
/**
|
|
318
|
+
* Load settings from all sources.
|
|
319
|
+
*/
|
|
320
|
+
load(flagOverrides) {
|
|
321
|
+
this.sources = [];
|
|
322
|
+
this.loadJsonFile(_path.join.call(void 0, userHome(), ".code-shell", "settings.managed.json"), "managed", 0);
|
|
323
|
+
this.loadJsonFile(_path.join.call(void 0, userHome(), ".code-shell", "settings.json"), "user", 1);
|
|
324
|
+
this.loadJsonFile(_path.join.call(void 0, userHome(), ".claude", "settings.json"), "user", 1);
|
|
325
|
+
this.loadJsonFile(_path.join.call(void 0, this.cwd, ".code-shell", "settings.json"), "project", 2);
|
|
326
|
+
this.loadJsonFile(_path.join.call(void 0, this.cwd, ".claude", "settings.json"), "project", 2);
|
|
327
|
+
this.loadJsonFile(_path.join.call(void 0, this.cwd, ".code-shell", "settings.local.json"), "local", 3);
|
|
328
|
+
this.loadJsonFile(_path.join.call(void 0, this.cwd, ".claude", "settings.local.json"), "local", 3);
|
|
329
|
+
if (flagOverrides && Object.keys(flagOverrides).length > 0) {
|
|
330
|
+
this.sources.push({ name: "flag", priority: 4, data: flagOverrides });
|
|
331
|
+
}
|
|
332
|
+
this.sources.sort((a, b) => a.priority - b.priority);
|
|
333
|
+
const raw = this.deepMerge();
|
|
334
|
+
const userPath = _path.join.call(void 0, userHome(), ".code-shell", "settings.json");
|
|
335
|
+
if (_fs.existsSync.call(void 0, userPath)) {
|
|
336
|
+
try {
|
|
337
|
+
const userRaw = JSON.parse(_fs.readFileSync.call(void 0, userPath, "utf-8"));
|
|
338
|
+
const result = migrateModels({
|
|
339
|
+
providers: _nullishCoalesce(userRaw.providers, () => ( [])),
|
|
340
|
+
models: _nullishCoalesce(userRaw.models, () => ( []))
|
|
341
|
+
});
|
|
342
|
+
if (result.changed) {
|
|
343
|
+
_fs.copyFileSync.call(void 0, userPath, `${userPath}.bak`);
|
|
344
|
+
const migrated = {
|
|
345
|
+
...userRaw,
|
|
346
|
+
providers: result.providers,
|
|
347
|
+
models: result.models
|
|
348
|
+
};
|
|
349
|
+
_fs.writeFileSync.call(void 0, userPath, JSON.stringify(migrated, null, 2), "utf-8");
|
|
350
|
+
const userSource = this.sources.find((s) => s.name === "user");
|
|
351
|
+
if (userSource) userSource.data = migrated;
|
|
352
|
+
const remerged = this.deepMerge();
|
|
353
|
+
this.merged = validateSettings(remerged);
|
|
354
|
+
return this.merged;
|
|
355
|
+
}
|
|
356
|
+
} catch (e) {
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
this.merged = validateSettings(raw);
|
|
360
|
+
return this.merged;
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Get current effective settings.
|
|
364
|
+
*/
|
|
365
|
+
get() {
|
|
366
|
+
if (!this.merged) return this.load();
|
|
367
|
+
return this.merged;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Invalidate cached merge.
|
|
371
|
+
*/
|
|
372
|
+
invalidate() {
|
|
373
|
+
this.merged = null;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Persist a single setting (dotted key path) to the user-level config file
|
|
377
|
+
* at ~/.code-shell/settings.json. Other sources (project / local /
|
|
378
|
+
* managed) are intentionally untouched: writing back to project/local
|
|
379
|
+
* would surprise version control, and managed is read-only.
|
|
380
|
+
*
|
|
381
|
+
* The merged cache is invalidated so the next get() picks up the change.
|
|
382
|
+
*/
|
|
383
|
+
saveUserSetting(key, value) {
|
|
384
|
+
const path = _path.join.call(void 0, userHome(), ".code-shell", "settings.json");
|
|
385
|
+
let current = {};
|
|
386
|
+
if (_fs.existsSync.call(void 0, path)) {
|
|
387
|
+
try {
|
|
388
|
+
const raw = _fs.readFileSync.call(void 0, path, "utf-8");
|
|
389
|
+
const parsed = JSON.parse(raw);
|
|
390
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
391
|
+
current = parsed;
|
|
392
|
+
}
|
|
393
|
+
} catch (e2) {
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
const parts = key.split(".");
|
|
397
|
+
let target = current;
|
|
398
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
399
|
+
const seg = parts[i];
|
|
400
|
+
const next = target[seg];
|
|
401
|
+
if (!next || typeof next !== "object" || Array.isArray(next)) {
|
|
402
|
+
target[seg] = {};
|
|
403
|
+
}
|
|
404
|
+
target = target[seg];
|
|
405
|
+
}
|
|
406
|
+
target[parts[parts.length - 1]] = value;
|
|
407
|
+
_fs.mkdirSync.call(void 0, _path.dirname.call(void 0, path), { recursive: true });
|
|
408
|
+
const tmp = `${path}.${process.pid}.${Date.now()}.tmp`;
|
|
409
|
+
_fs.writeFileSync.call(void 0, tmp, JSON.stringify(current, null, 2), "utf-8");
|
|
410
|
+
_fs.renameSync.call(void 0, tmp, path);
|
|
411
|
+
this.invalidate();
|
|
412
|
+
}
|
|
413
|
+
loadJsonFile(path, name, priority) {
|
|
414
|
+
if (!_fs.existsSync.call(void 0, path)) return;
|
|
415
|
+
try {
|
|
416
|
+
const content = _fs.readFileSync.call(void 0, path, "utf-8");
|
|
417
|
+
const data = JSON.parse(content);
|
|
418
|
+
if (typeof data === "object" && data !== null) {
|
|
419
|
+
this.sources.push({ name, priority, data });
|
|
420
|
+
}
|
|
421
|
+
} catch (e3) {
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
deepMerge() {
|
|
425
|
+
let result = {};
|
|
426
|
+
for (const source of this.sources) {
|
|
427
|
+
result = merge(result, source.data);
|
|
428
|
+
}
|
|
429
|
+
return result;
|
|
430
|
+
}
|
|
431
|
+
}, _class);
|
|
432
|
+
function merge(base, override) {
|
|
433
|
+
const result = { ...base };
|
|
434
|
+
for (const [key, value] of Object.entries(override)) {
|
|
435
|
+
if (value === null) {
|
|
436
|
+
delete result[key];
|
|
437
|
+
} else if (typeof value === "object" && !Array.isArray(value) && typeof result[key] === "object" && !Array.isArray(result[key]) && result[key] !== null) {
|
|
438
|
+
result[key] = merge(result[key], value);
|
|
439
|
+
} else {
|
|
440
|
+
result[key] = value;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
return result;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
|
|
450
|
+
exports.SettingsSchema = SettingsSchema; exports.validateSettings = validateSettings; exports.SettingsManager = SettingsManager;
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
LLMClientBase
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-6S4BJ65N.js";
|
|
4
4
|
import {
|
|
5
5
|
ContextLimitError,
|
|
6
6
|
LLMError,
|
|
7
7
|
LLMRateLimitError
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-SFXHZSRF.js";
|
|
9
9
|
import {
|
|
10
10
|
logger
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-BXCY2FSE.js";
|
|
12
12
|
import {
|
|
13
13
|
init_esm_shims
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-MD32R22I.js";
|
|
15
15
|
|
|
16
16
|
// src/llm/providers/anthropic.ts
|
|
17
17
|
init_esm_shims();
|
|
@@ -87,7 +87,7 @@ var AnthropicClient = class extends LLMClientBase {
|
|
|
87
87
|
cacheReadTokens: response.usage.cache_read_input_tokens,
|
|
88
88
|
cacheCreationTokens: response.usage.cache_creation_input_tokens
|
|
89
89
|
};
|
|
90
|
-
this.recordUsage(usage);
|
|
90
|
+
this.recordUsage(usage, options);
|
|
91
91
|
return this.processResponse(response, usage);
|
|
92
92
|
} catch (err) {
|
|
93
93
|
this.handleApiError(err);
|
|
@@ -164,7 +164,7 @@ var AnthropicClient = class extends LLMClientBase {
|
|
|
164
164
|
cacheReadTokens: finalMessage.usage.cache_read_input_tokens,
|
|
165
165
|
cacheCreationTokens: finalMessage.usage.cache_creation_input_tokens
|
|
166
166
|
};
|
|
167
|
-
this.recordUsage(usage);
|
|
167
|
+
this.recordUsage(usage, options);
|
|
168
168
|
options.onChunk?.({ type: "stop", stopReason: finalMessage.stop_reason ?? void 0 });
|
|
169
169
|
return this.processResponse(finalMessage, usage);
|
|
170
170
|
} catch (err) {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown renderer for `/export markdown`.
|
|
3
|
+
*
|
|
4
|
+
* Goals (versus the legacy one-JSON-line-per-turn dump):
|
|
5
|
+
* • Every turn is numbered and role-tagged
|
|
6
|
+
* • Reasoning blocks are collapsible (<details>) — present but not noisy
|
|
7
|
+
* • tool_use shows tool name + truncated args inline
|
|
8
|
+
* • tool_result over a threshold spills to a sidecar file alongside the md
|
|
9
|
+
* • Long lines never exceed ~2 KB inline so editors stay responsive
|
|
10
|
+
*/
|
|
11
|
+
export interface Sidecar {
|
|
12
|
+
path: string;
|
|
13
|
+
content: string;
|
|
14
|
+
}
|
|
15
|
+
export interface RenderedSession {
|
|
16
|
+
md: string;
|
|
17
|
+
sidecars: Sidecar[];
|
|
18
|
+
}
|
|
19
|
+
export declare function renderSessionMarkdown(sessionId: string, events: unknown[], cwd: string): RenderedSession;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detection — what does the cwd already contain?
|
|
3
|
+
*
|
|
4
|
+
* Drives the four-way intent decision in pickIntent. Synchronous and bounded
|
|
5
|
+
* (≤ a handful of stat calls + one capped directory walk) so /init can pick a
|
|
6
|
+
* mode without spawning an LLM turn just for classification.
|
|
7
|
+
*/
|
|
8
|
+
export interface Detection {
|
|
9
|
+
hasCodeshell: boolean;
|
|
10
|
+
hasClaude: boolean;
|
|
11
|
+
hasAgents: boolean;
|
|
12
|
+
hasCursorRules: boolean;
|
|
13
|
+
hasCursorRulesDir: boolean;
|
|
14
|
+
hasWindsurfRules: boolean;
|
|
15
|
+
hasClinerules: boolean;
|
|
16
|
+
hasCopilotInstructions: boolean;
|
|
17
|
+
hasCodeshellRulesDir: boolean;
|
|
18
|
+
hasManifest: boolean;
|
|
19
|
+
hasSourceFiles: boolean;
|
|
20
|
+
hasReadme: boolean;
|
|
21
|
+
}
|
|
22
|
+
export type Intent = "improve" | "migrate" | "create" | "empty";
|
|
23
|
+
export declare function detect(cwd: string): Detection;
|
|
24
|
+
export declare function pickIntent(d: Detection): Intent;
|
|
25
|
+
export declare function summarize(d: Detection): string;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `/init` — bootstrap CODESHELL.md for the current repo.
|
|
3
|
+
*
|
|
4
|
+
* Scope: documentation only. This command never writes to settings.json or
|
|
5
|
+
* settings.local.json — those belong to Code Shell's own onboarding/permission
|
|
6
|
+
* flows and must stay decoupled from arbitrary target repos.
|
|
7
|
+
*
|
|
8
|
+
* Four intents, picked from cwd state:
|
|
9
|
+
* improve — CODESHELL.md already exists; LLM edits in place with diffs.
|
|
10
|
+
* migrate — other AI configs (CLAUDE.md, .cursorrules, ...) exist; LLM
|
|
11
|
+
* treats them as investigation sources and synthesizes.
|
|
12
|
+
* create — code present (manifest/source/README) but no AI config; LLM
|
|
13
|
+
* surveys the repo and writes from scratch.
|
|
14
|
+
* empty — truly empty repo; LLM asks the user a few questions via the
|
|
15
|
+
* AskUserQuestion tool, then writes (with TODO placeholders as
|
|
16
|
+
* needed). Hard limit: ≤4 AskUserQuestion calls per prompt.
|
|
17
|
+
*/
|
|
18
|
+
import type { SlashCommand } from "../../registry.js";
|
|
19
|
+
export declare const initCommand: SlashCommand;
|