@drael/code 0.4.0 → 0.5.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.
- package/package.json +1 -1
- package/src/code.js +114 -26
package/package.json
CHANGED
package/src/code.js
CHANGED
|
@@ -105,12 +105,12 @@ const clients = {
|
|
|
105
105
|
merges: true,
|
|
106
106
|
file: () => KILO_CONFIG,
|
|
107
107
|
contents: (host, key, model) => {
|
|
108
|
-
const
|
|
108
|
+
const kept = existing(KILO_CONFIG).value
|
|
109
109
|
return json({
|
|
110
|
-
...
|
|
110
|
+
...kept,
|
|
111
111
|
$schema: 'https://app.kilo.ai/config.json',
|
|
112
112
|
provider: {
|
|
113
|
-
...
|
|
113
|
+
...kept.provider,
|
|
114
114
|
drael: {
|
|
115
115
|
options: { baseURL: `${host}/v1`, apiKey: key },
|
|
116
116
|
models: { [model]: { name: 'Drael' } },
|
|
@@ -121,6 +121,40 @@ const clients = {
|
|
|
121
121
|
},
|
|
122
122
|
},
|
|
123
123
|
|
|
124
|
+
continue: {
|
|
125
|
+
label: 'Continue',
|
|
126
|
+
file: () => join(homedir(), '.continue', 'config.yaml'),
|
|
127
|
+
contents: (host, key, model) =>
|
|
128
|
+
[
|
|
129
|
+
'name: Drael',
|
|
130
|
+
'version: 1.0.0',
|
|
131
|
+
'schema: v1',
|
|
132
|
+
'models:',
|
|
133
|
+
' - name: Drael',
|
|
134
|
+
' provider: openai',
|
|
135
|
+
` model: ${scalar(model)}`,
|
|
136
|
+
` apiBase: ${scalar(`${host}/v1`)}`,
|
|
137
|
+
` apiKey: ${scalar(key)}`,
|
|
138
|
+
'',
|
|
139
|
+
].join('\n'),
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
aider: {
|
|
143
|
+
label: 'Aider',
|
|
144
|
+
// A dotfile at the root of home, so its own presence is the only sign of it: the
|
|
145
|
+
// directory the others are found by would be the home directory, which is always there.
|
|
146
|
+
at: () => join(homedir(), '.aider.conf.yml'),
|
|
147
|
+
file: () => join(homedir(), '.aider.conf.yml'),
|
|
148
|
+
contents: (host, key, model) =>
|
|
149
|
+
[
|
|
150
|
+
'# Drael.',
|
|
151
|
+
`model: ${scalar(`openai/${model}`)}`,
|
|
152
|
+
`openai-api-base: ${scalar(`${host}/v1`)}`,
|
|
153
|
+
`openai-api-key: ${scalar(key)}`,
|
|
154
|
+
'',
|
|
155
|
+
].join('\n'),
|
|
156
|
+
},
|
|
157
|
+
|
|
124
158
|
env: {
|
|
125
159
|
label: 'anything reading OPENAI_BASE_URL',
|
|
126
160
|
file: () => join(CONFIG_HOME, 'drael', 'env.sh'),
|
|
@@ -140,30 +174,80 @@ const clients = {
|
|
|
140
174
|
const json = (value) => `${JSON.stringify(value, null, 2)}\n`
|
|
141
175
|
|
|
142
176
|
/**
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
*
|
|
146
|
-
* mangled config. The copy under BACKUPS still holds the original, and `parses` below
|
|
147
|
-
* is what lets the frame say so before it writes.
|
|
177
|
+
* A YAML scalar, for the two files that are YAML. YAML 1.2 is a superset of JSON, so a
|
|
178
|
+
* JSON string is already a correctly quoted and escaped one, and quoting every value is
|
|
179
|
+
* what keeps the `https://` in a URL from reading as a key with a comment after it.
|
|
148
180
|
*/
|
|
149
|
-
|
|
150
|
-
try {
|
|
151
|
-
return JSON.parse(readFileSync(file, 'utf8'))
|
|
152
|
-
} catch {
|
|
153
|
-
return {}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
181
|
+
const scalar = (value) => JSON.stringify(String(value))
|
|
156
182
|
|
|
157
|
-
|
|
183
|
+
/**
|
|
184
|
+
* Kilo's file is the whole extension's configuration and not ours, so ours is merged into
|
|
185
|
+
* what is already there. It is a `.jsonc`, and a file that names itself that has comments
|
|
186
|
+
* in it, so reading it with `JSON.parse` alone meant every commented config was replaced
|
|
187
|
+
* whole: the other providers, the keys and the settings in it, gone but for the copy under
|
|
188
|
+
* BACKUPS.
|
|
189
|
+
*
|
|
190
|
+
* What cannot be kept is the comments themselves, because what goes back is JSON. The
|
|
191
|
+
* frame says so when that is what happened.
|
|
192
|
+
*/
|
|
193
|
+
function existing(file) {
|
|
158
194
|
if (!existsSync(file)) {
|
|
159
|
-
return
|
|
195
|
+
return { value: {} }
|
|
160
196
|
}
|
|
197
|
+
const text = readFileSync(file, 'utf8')
|
|
161
198
|
try {
|
|
162
|
-
JSON.parse(
|
|
163
|
-
return true
|
|
199
|
+
return { value: JSON.parse(text) }
|
|
164
200
|
} catch {
|
|
165
|
-
|
|
201
|
+
// Not plain JSON, so it is either JSONC or damaged, and those are different answers.
|
|
202
|
+
}
|
|
203
|
+
try {
|
|
204
|
+
return { value: JSON.parse(uncommented(text)), stripped: true }
|
|
205
|
+
} catch {
|
|
206
|
+
return { value: {}, replaced: true }
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* JSON with the comments and the trailing commas taken out, which is what JSONC is. A
|
|
212
|
+
* scanner rather than a pattern, because a `//` inside a string value is not a comment and
|
|
213
|
+
* a pattern cannot tell the difference; the same goes for the comma in `"a, }"`, which a
|
|
214
|
+
* pattern for trailing commas would eat.
|
|
215
|
+
*/
|
|
216
|
+
function uncommented(text) {
|
|
217
|
+
let out = ''
|
|
218
|
+
let comma = -1
|
|
219
|
+
let i = 0
|
|
220
|
+
while (i < text.length) {
|
|
221
|
+
const here = text[i]
|
|
222
|
+
|
|
223
|
+
if (here === '"') {
|
|
224
|
+
let end = i + 1
|
|
225
|
+
while (end < text.length && text[end] !== '"') {
|
|
226
|
+
end += text[end] === '\\' ? 2 : 1
|
|
227
|
+
}
|
|
228
|
+
out += text.slice(i, end + 1)
|
|
229
|
+
i = end + 1
|
|
230
|
+
continue
|
|
231
|
+
}
|
|
232
|
+
if (here === '/' && text[i + 1] === '/') {
|
|
233
|
+
while (i < text.length && text[i] !== '\n') i++
|
|
234
|
+
continue
|
|
235
|
+
}
|
|
236
|
+
if (here === '/' && text[i + 1] === '*') {
|
|
237
|
+
const closed = text.indexOf('*/', i + 2)
|
|
238
|
+
i = closed === -1 ? text.length : closed + 2
|
|
239
|
+
continue
|
|
240
|
+
}
|
|
241
|
+
if (here === ',') {
|
|
242
|
+
comma = out.length
|
|
243
|
+
} else if ((here === '}' || here === ']') && comma >= 0 && !out.slice(comma + 1).trim()) {
|
|
244
|
+
out = out.slice(0, comma) + out.slice(comma + 1)
|
|
245
|
+
comma = -1
|
|
246
|
+
}
|
|
247
|
+
out += here
|
|
248
|
+
i++
|
|
166
249
|
}
|
|
250
|
+
return out
|
|
167
251
|
}
|
|
168
252
|
|
|
169
253
|
/* ────────────────────────────────────────────────────────────────── the drawing ── */
|
|
@@ -309,7 +393,7 @@ async function askHost(host, key) {
|
|
|
309
393
|
* list and detection only decides which one the cursor starts on.
|
|
310
394
|
*/
|
|
311
395
|
function found(client) {
|
|
312
|
-
return existsSync(dirname(client.file()))
|
|
396
|
+
return existsSync(client.at?.() ?? dirname(client.file()))
|
|
313
397
|
}
|
|
314
398
|
|
|
315
399
|
function detected() {
|
|
@@ -357,8 +441,8 @@ async function install(args) {
|
|
|
357
441
|
return
|
|
358
442
|
}
|
|
359
443
|
|
|
360
|
-
// Asked before the write, or it inspects the
|
|
361
|
-
const
|
|
444
|
+
// Asked before the write, or it inspects the JSON we are about to put there.
|
|
445
|
+
const was = client.merges ? existing(file) : {}
|
|
362
446
|
|
|
363
447
|
const kept = backup(file)
|
|
364
448
|
mkdirSync(dirname(file), { recursive: true })
|
|
@@ -366,8 +450,11 @@ async function install(args) {
|
|
|
366
450
|
chmodSync(file, 0o600)
|
|
367
451
|
|
|
368
452
|
console.log(row(client.merges ? 'merged' : 'wrote', tilde(file)))
|
|
369
|
-
if (replaced) {
|
|
370
|
-
console.log(under(dim('it
|
|
453
|
+
if (was.replaced) {
|
|
454
|
+
console.log(under(dim('it did not parse at all, so it was replaced rather than merged')))
|
|
455
|
+
}
|
|
456
|
+
if (was.stripped) {
|
|
457
|
+
console.log(under(dim('everything in it was kept; its comments were not, because JSON')))
|
|
371
458
|
}
|
|
372
459
|
console.log(row(kept.label, dim(kept.detail)))
|
|
373
460
|
if (client.after) {
|
|
@@ -491,7 +578,8 @@ function help() {
|
|
|
491
578
|
function list() {
|
|
492
579
|
console.log()
|
|
493
580
|
for (const [name, client] of Object.entries(clients)) {
|
|
494
|
-
|
|
581
|
+
const said = `${client.label}${found(client) ? ' · on this machine' : ''}`
|
|
582
|
+
console.log(row(name, `${dim(tilde(client.file()).padEnd(34))} ${said}`))
|
|
495
583
|
}
|
|
496
584
|
console.log()
|
|
497
585
|
}
|