@freesyntax/notch-cli 0.5.21 → 0.5.22
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/dist/{apply-patch-D5PDUXUC.js → apply-patch-U6K67CMT.js} +1 -0
- package/dist/auth-UAMMP5IJ.js +29 -0
- package/dist/{chunk-OSWUX6TC.js → chunk-4HPRBCSY.js} +1 -1
- package/dist/{chunk-QKM27RHS.js → chunk-6NKRMZTX.js} +1 -1
- package/dist/{chunk-TU465P2P.js → chunk-EPSOOCNB.js} +4 -2
- package/dist/{chunk-MMBFNIKE.js → chunk-FZVPGJJW.js} +5 -3
- package/dist/chunk-J66N6AFH.js +137 -0
- package/dist/{chunk-443G6HCC.js → chunk-JXQ4HZ47.js} +56 -55
- package/dist/chunk-KCAR5DOB.js +52 -0
- package/dist/chunk-KFQGP6VL.js +33 -0
- package/dist/chunk-O6AKZ4OH.js +0 -0
- package/dist/{chunk-FIFC4V2R.js → chunk-PPEBWOMJ.js} +91 -7
- package/dist/{compression-SQAIQ2UU.js → compression-YJLWEHCC.js} +1 -0
- package/dist/config-set-3IWEVZQ4.js +110 -0
- package/dist/{edit-JEFEK43H.js → edit-6QYAXVNU.js} +1 -0
- package/dist/{git-5T5TSQTX.js → git-DNQ5EELH.js} +1 -0
- package/dist/{github-DWRGWX6U.js → github-34T4QQIH.js} +1 -0
- package/dist/{glob-BI3P4C7Q.js → glob-XT43LEJ4.js} +1 -0
- package/dist/{grep-VZ3I5GNW.js → grep-T2CXYNRI.js} +1 -0
- package/dist/index.js +420 -298
- package/dist/{lsp-UPY6I3L7.js → lsp-JXQVU7NP.js} +1 -0
- package/dist/model-download-3NDKS3VM.js +176 -0
- package/dist/{notebook-FXJBTSPA.js → notebook-MFODW345.js} +1 -0
- package/dist/{ollama-bench-QQHBIG2D.js → ollama-bench-5V5CCOCQ.js} +6 -2
- package/dist/{ollama-launch-2ASVER3S.js → ollama-launch-P5KBK7AJ.js} +6 -2
- package/dist/{ollama-usage-2WPCZJJI.js → ollama-usage-3PROM2WC.js} +1 -0
- package/dist/{plugins-OG2P75K5.js → plugins-PNGRZLFW.js} +1 -0
- package/dist/{read-OVJG2XKW.js → read-B64XE7N3.js} +1 -0
- package/dist/{server-7UQKCB2Z.js → server-IGOZHW52.js} +17 -15
- package/dist/{session-index-SSGOOZXK.js → session-index-7FWEVP6E.js} +3 -2
- package/dist/{shell-4X545EVN.js → shell-BOZTHQUT.js} +1 -0
- package/dist/{task-OS3E5F3X.js → task-67G4KLYC.js} +1 -0
- package/dist/{tools-7WAWS6V4.js → tools-XWKCW4RN.js} +4 -3
- package/dist/{web-fetch-KNIV3Z3W.js → web-fetch-OTNDICGJ.js} +1 -0
- package/dist/{write-NNHLOTYK.js → write-ZOSB7I4J.js} +1 -0
- package/package.json +1 -1
- package/dist/auth-JQX6MHJG.js +0 -16
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {
|
|
2
|
+
clearCredentials,
|
|
3
|
+
getByokSyncPath,
|
|
4
|
+
getConfigDir,
|
|
5
|
+
getCredentialsPath,
|
|
6
|
+
init_auth,
|
|
7
|
+
invalidateSyncedKeysCache,
|
|
8
|
+
loadCredentials,
|
|
9
|
+
loadSyncedByokKeys,
|
|
10
|
+
loadSyncedByokKeysSync,
|
|
11
|
+
login,
|
|
12
|
+
saveCredentials,
|
|
13
|
+
syncByokKeys
|
|
14
|
+
} from "./chunk-PPEBWOMJ.js";
|
|
15
|
+
import "./chunk-KFQGP6VL.js";
|
|
16
|
+
init_auth();
|
|
17
|
+
export {
|
|
18
|
+
clearCredentials,
|
|
19
|
+
getByokSyncPath,
|
|
20
|
+
getConfigDir,
|
|
21
|
+
getCredentialsPath,
|
|
22
|
+
invalidateSyncedKeysCache,
|
|
23
|
+
loadCredentials,
|
|
24
|
+
loadSyncedByokKeys,
|
|
25
|
+
loadSyncedByokKeysSync,
|
|
26
|
+
login,
|
|
27
|
+
saveCredentials,
|
|
28
|
+
syncByokKeys
|
|
29
|
+
};
|
|
@@ -53,7 +53,7 @@ var Rollout = class {
|
|
|
53
53
|
this.fd = null;
|
|
54
54
|
}
|
|
55
55
|
try {
|
|
56
|
-
const { upsertSessionIndexEntry } = await import("./session-index-
|
|
56
|
+
const { upsertSessionIndexEntry } = await import("./session-index-7FWEVP6E.js");
|
|
57
57
|
await upsertSessionIndexEntry(this.id);
|
|
58
58
|
} catch {
|
|
59
59
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Rollout
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-6NKRMZTX.js";
|
|
4
4
|
import {
|
|
5
5
|
grepTool
|
|
6
6
|
} from "./chunk-6CZCFY6H.js";
|
|
@@ -26,8 +26,9 @@ import {
|
|
|
26
26
|
pluginManager
|
|
27
27
|
} from "./chunk-3QUV4JEX.js";
|
|
28
28
|
import {
|
|
29
|
+
init_auth,
|
|
29
30
|
loadCredentials
|
|
30
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-PPEBWOMJ.js";
|
|
31
32
|
import {
|
|
32
33
|
readTool
|
|
33
34
|
} from "./chunk-CQMAVWLJ.js";
|
|
@@ -501,6 +502,7 @@ error: no running cell with that id (it may have already completed)`,
|
|
|
501
502
|
};
|
|
502
503
|
|
|
503
504
|
// src/tools/skill-manage.ts
|
|
505
|
+
init_auth();
|
|
504
506
|
import { z as z2 } from "zod";
|
|
505
507
|
var API_BASE_ENV = "NOTCH_API_URL";
|
|
506
508
|
var DEFAULT_API_BASE = "https://freesyntax.dev";
|
|
@@ -11,11 +11,13 @@ import {
|
|
|
11
11
|
} from "./chunk-GFVLHUSS.js";
|
|
12
12
|
import {
|
|
13
13
|
clearOllamaCreds,
|
|
14
|
-
findByokProvider,
|
|
15
14
|
ollamaCredsPath,
|
|
16
15
|
readOllamaCreds,
|
|
17
16
|
writeOllamaCreds
|
|
18
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-KCAR5DOB.js";
|
|
18
|
+
import {
|
|
19
|
+
findByokProvider
|
|
20
|
+
} from "./chunk-JXQ4HZ47.js";
|
|
19
21
|
|
|
20
22
|
// src/commands/ollama-launch.ts
|
|
21
23
|
import fs from "fs/promises";
|
|
@@ -486,7 +488,7 @@ async function runOllamaCli(argv, cwd) {
|
|
|
486
488
|
case "logout":
|
|
487
489
|
return cmdLogout(subFlags);
|
|
488
490
|
case "bench": {
|
|
489
|
-
const { runOllamaBench } = await import("./ollama-bench-
|
|
491
|
+
const { runOllamaBench } = await import("./ollama-bench-5V5CCOCQ.js");
|
|
490
492
|
return runOllamaBench(subFlags, { projectRoot: cwd });
|
|
491
493
|
}
|
|
492
494
|
case "help":
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import {
|
|
2
|
+
readOllamaCreds
|
|
3
|
+
} from "./chunk-KCAR5DOB.js";
|
|
4
|
+
import {
|
|
5
|
+
findByokProvider,
|
|
6
|
+
isByokRef,
|
|
7
|
+
isValidModel
|
|
8
|
+
} from "./chunk-JXQ4HZ47.js";
|
|
9
|
+
import {
|
|
10
|
+
init_auth,
|
|
11
|
+
loadCredentials
|
|
12
|
+
} from "./chunk-PPEBWOMJ.js";
|
|
13
|
+
|
|
14
|
+
// src/config.ts
|
|
15
|
+
import fs from "fs/promises";
|
|
16
|
+
import path from "path";
|
|
17
|
+
init_auth();
|
|
18
|
+
var DEFAULT_MODEL = {
|
|
19
|
+
model: "notch-pyre",
|
|
20
|
+
temperature: 0.3
|
|
21
|
+
};
|
|
22
|
+
var DEFAULTS = {
|
|
23
|
+
models: { chat: DEFAULT_MODEL },
|
|
24
|
+
projectRoot: process.cwd(),
|
|
25
|
+
autoConfirm: false,
|
|
26
|
+
maxIterations: 25,
|
|
27
|
+
useRepoMap: true,
|
|
28
|
+
renderMarkdown: true,
|
|
29
|
+
enableMemory: true,
|
|
30
|
+
enableHooks: true,
|
|
31
|
+
permissionMode: "auto",
|
|
32
|
+
theme: "default"
|
|
33
|
+
};
|
|
34
|
+
async function loadConfig(overrides = {}) {
|
|
35
|
+
const config = { ...DEFAULTS, models: { chat: { ...DEFAULT_MODEL } } };
|
|
36
|
+
const configPath = path.resolve(config.projectRoot, ".notch.json");
|
|
37
|
+
try {
|
|
38
|
+
const raw = await fs.readFile(configPath, "utf-8");
|
|
39
|
+
const fileConfig = JSON.parse(raw);
|
|
40
|
+
if (fileConfig.model && (isValidModel(fileConfig.model) || isByokRef(fileConfig.model))) {
|
|
41
|
+
config.models.chat.model = fileConfig.model;
|
|
42
|
+
}
|
|
43
|
+
if (fileConfig.baseUrl) config.models.chat.baseUrl = fileConfig.baseUrl;
|
|
44
|
+
if (fileConfig.apiKey) config.models.chat.apiKey = fileConfig.apiKey;
|
|
45
|
+
if (fileConfig.byok && typeof fileConfig.byok === "object") {
|
|
46
|
+
const byok = fileConfig.byok;
|
|
47
|
+
config.byok = { ...byok };
|
|
48
|
+
if (byok.provider && findByokProvider(byok.provider === "custom" ? "__custom__" : byok.provider)) {
|
|
49
|
+
config.models.chat.byokProvider = byok.provider === "custom" ? "__custom__" : byok.provider;
|
|
50
|
+
if (byok.model) config.models.chat.model = byok.model;
|
|
51
|
+
if (byok.baseUrl) config.models.chat.baseUrl = byok.baseUrl;
|
|
52
|
+
if (byok.headers) {
|
|
53
|
+
config.models.chat.byokHeaders = { ...config.models.chat.byokHeaders, ...byok.headers };
|
|
54
|
+
}
|
|
55
|
+
if (byok.apiShape === "openai" || byok.apiShape === "anthropic") {
|
|
56
|
+
config.models.chat.byokApiShape = byok.apiShape;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (fileConfig.hybrid && typeof fileConfig.hybrid === "object") {
|
|
61
|
+
const hybrid = fileConfig.hybrid;
|
|
62
|
+
config.hybrid = hybrid;
|
|
63
|
+
}
|
|
64
|
+
if (fileConfig.maxIterations) config.maxIterations = fileConfig.maxIterations;
|
|
65
|
+
if (fileConfig.useRepoMap !== void 0) config.useRepoMap = fileConfig.useRepoMap;
|
|
66
|
+
if (fileConfig.temperature !== void 0) config.models.chat.temperature = fileConfig.temperature;
|
|
67
|
+
if (fileConfig.renderMarkdown !== void 0) config.renderMarkdown = fileConfig.renderMarkdown;
|
|
68
|
+
if (fileConfig.enableMemory !== void 0) config.enableMemory = fileConfig.enableMemory;
|
|
69
|
+
if (fileConfig.enableHooks !== void 0) config.enableHooks = fileConfig.enableHooks;
|
|
70
|
+
if (fileConfig.permissionMode) config.permissionMode = fileConfig.permissionMode;
|
|
71
|
+
if (fileConfig.shellTimeout) config.shellTimeout = fileConfig.shellTimeout;
|
|
72
|
+
if (fileConfig.theme) config.theme = fileConfig.theme;
|
|
73
|
+
} catch {
|
|
74
|
+
}
|
|
75
|
+
const activeProviderId = config.models.chat.byokProvider ?? (typeof config.models.chat.model === "string" && isByokRef(config.models.chat.model) ? config.models.chat.model.split(":", 1)[0] : void 0);
|
|
76
|
+
const isOllamaProvider = activeProviderId === "ollama" || activeProviderId === "ollama-cloud" || activeProviderId === "ollama-anthropic";
|
|
77
|
+
if (isOllamaProvider) {
|
|
78
|
+
if (!config.models.chat.apiKey && !process.env.OLLAMA_API_KEY) {
|
|
79
|
+
const ollamaCreds = await readOllamaCreds();
|
|
80
|
+
if (ollamaCreds?.apiKey) {
|
|
81
|
+
config.models.chat.apiKey = ollamaCreds.apiKey;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
} else {
|
|
85
|
+
const creds = await loadCredentials();
|
|
86
|
+
if (creds?.token) {
|
|
87
|
+
config.models.chat.apiKey = creds.token;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (process.env.NOTCH_MODEL) {
|
|
91
|
+
const envModel = process.env.NOTCH_MODEL;
|
|
92
|
+
if (isValidModel(envModel)) {
|
|
93
|
+
config.models.chat.model = envModel;
|
|
94
|
+
} else if (isByokRef(envModel)) {
|
|
95
|
+
config.models.chat.model = envModel;
|
|
96
|
+
config.models.chat.byokProvider = void 0;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (process.env.NOTCH_BASE_URL) {
|
|
100
|
+
config.models.chat.baseUrl = process.env.NOTCH_BASE_URL;
|
|
101
|
+
}
|
|
102
|
+
if (process.env.NOTCH_API_KEY) {
|
|
103
|
+
config.models.chat.apiKey = process.env.NOTCH_API_KEY;
|
|
104
|
+
}
|
|
105
|
+
if (config.models.chat.temperature !== void 0) {
|
|
106
|
+
config.models.chat.temperature = Math.max(0, Math.min(2, config.models.chat.temperature));
|
|
107
|
+
}
|
|
108
|
+
config.maxIterations = Math.max(1, Math.min(100, config.maxIterations));
|
|
109
|
+
return { ...config, ...overrides };
|
|
110
|
+
}
|
|
111
|
+
async function persistConfigPatch(projectRoot, patch) {
|
|
112
|
+
const configPath = path.resolve(projectRoot, ".notch.json");
|
|
113
|
+
let current = {};
|
|
114
|
+
try {
|
|
115
|
+
const raw = await fs.readFile(configPath, "utf-8");
|
|
116
|
+
const parsed = JSON.parse(raw);
|
|
117
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
118
|
+
current = parsed;
|
|
119
|
+
}
|
|
120
|
+
} catch {
|
|
121
|
+
}
|
|
122
|
+
const merged = { ...current };
|
|
123
|
+
for (const [k, v] of Object.entries(patch)) {
|
|
124
|
+
if (v === void 0) delete merged[k];
|
|
125
|
+
else merged[k] = v;
|
|
126
|
+
}
|
|
127
|
+
const serialised = JSON.stringify(merged, null, 2) + "\n";
|
|
128
|
+
const tmpPath = `${configPath}.tmp`;
|
|
129
|
+
await fs.writeFile(tmpPath, serialised, "utf-8");
|
|
130
|
+
await fs.rename(tmpPath, configPath);
|
|
131
|
+
return merged;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export {
|
|
135
|
+
loadConfig,
|
|
136
|
+
persistConfigPatch
|
|
137
|
+
};
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
import {
|
|
2
|
+
auth_exports,
|
|
3
|
+
init_auth
|
|
4
|
+
} from "./chunk-PPEBWOMJ.js";
|
|
5
|
+
import {
|
|
6
|
+
__toCommonJS
|
|
7
|
+
} from "./chunk-KFQGP6VL.js";
|
|
8
|
+
|
|
1
9
|
// src/providers/byok.ts
|
|
2
10
|
import { createOpenAI } from "@ai-sdk/openai";
|
|
3
11
|
import { createAnthropic } from "@ai-sdk/anthropic";
|
|
@@ -243,6 +251,14 @@ function resolveByokModel(spec) {
|
|
|
243
251
|
if (!apiKey && providerInfo.apiKeyEnv) {
|
|
244
252
|
apiKey = process.env[providerInfo.apiKeyEnv];
|
|
245
253
|
}
|
|
254
|
+
if (!apiKey) {
|
|
255
|
+
const { loadSyncedByokKeysSync } = (init_auth(), __toCommonJS(auth_exports));
|
|
256
|
+
const synced = loadSyncedByokKeysSync();
|
|
257
|
+
if (synced) {
|
|
258
|
+
const fromSync = synced.keys[providerInfo.id];
|
|
259
|
+
if (typeof fromSync === "string" && fromSync.length > 0) apiKey = fromSync;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
246
262
|
if (!apiKey && providerInfo.fallbackApiKey) {
|
|
247
263
|
apiKey = providerInfo.fallbackApiKey;
|
|
248
264
|
}
|
|
@@ -334,7 +350,18 @@ var MODEL_CATALOG = {
|
|
|
334
350
|
gpu: "L40S",
|
|
335
351
|
contextWindow: 131072,
|
|
336
352
|
maxOutputTokens: 16384,
|
|
337
|
-
baseUrl: "https://acemagnifique--notch-serve-pyre-notchpyreserver-serve.modal.run/v1"
|
|
353
|
+
baseUrl: "https://acemagnifique--notch-serve-pyre-notchpyreserver-serve.modal.run/v1",
|
|
354
|
+
hardware: {
|
|
355
|
+
vramGb: 10,
|
|
356
|
+
ramGb: 16,
|
|
357
|
+
diskGb: 6,
|
|
358
|
+
recommendedGpu: "RTX 3090 / 4070 Ti+ \xB7 12GB+ VRAM",
|
|
359
|
+
tier: "light"
|
|
360
|
+
},
|
|
361
|
+
// null until we push Q4 merged weights to the public Hub. The CLI
|
|
362
|
+
// surfaces this as "hosted-only" in the /model picker so users know
|
|
363
|
+
// local download isn't wired yet — no fake error, no mock repo.
|
|
364
|
+
hfRepo: null
|
|
338
365
|
},
|
|
339
366
|
"notch-ignis": {
|
|
340
367
|
id: "notch-ignis",
|
|
@@ -343,7 +370,15 @@ var MODEL_CATALOG = {
|
|
|
343
370
|
gpu: "A100-80GB",
|
|
344
371
|
contextWindow: 131072,
|
|
345
372
|
maxOutputTokens: 16384,
|
|
346
|
-
baseUrl: "https://acemagnifique--notch-serve-ignis-notchignisserver-serve.modal.run/v1"
|
|
373
|
+
baseUrl: "https://acemagnifique--notch-serve-ignis-notchignisserver-serve.modal.run/v1",
|
|
374
|
+
hardware: {
|
|
375
|
+
vramGb: 20,
|
|
376
|
+
ramGb: 32,
|
|
377
|
+
diskGb: 18,
|
|
378
|
+
recommendedGpu: "RTX 4090 / A6000+ \xB7 24GB+ VRAM",
|
|
379
|
+
tier: "standard"
|
|
380
|
+
},
|
|
381
|
+
hfRepo: null
|
|
347
382
|
},
|
|
348
383
|
"notch-solace": {
|
|
349
384
|
id: "notch-solace",
|
|
@@ -352,7 +387,15 @@ var MODEL_CATALOG = {
|
|
|
352
387
|
gpu: "A100-80GB",
|
|
353
388
|
contextWindow: 131072,
|
|
354
389
|
maxOutputTokens: 16384,
|
|
355
|
-
baseUrl: "https://acemagnifique--notch-serve-solace-notchsolaceserver-serve.modal.run/v1"
|
|
390
|
+
baseUrl: "https://acemagnifique--notch-serve-solace-notchsolaceserver-serve.modal.run/v1",
|
|
391
|
+
hardware: {
|
|
392
|
+
vramGb: 24,
|
|
393
|
+
ramGb: 64,
|
|
394
|
+
diskGb: 22,
|
|
395
|
+
recommendedGpu: "RTX 4090 + offload / A100-40GB+",
|
|
396
|
+
tier: "heavy"
|
|
397
|
+
},
|
|
398
|
+
hfRepo: null
|
|
356
399
|
},
|
|
357
400
|
"notch-solace-lite": {
|
|
358
401
|
id: "notch-solace-lite",
|
|
@@ -361,7 +404,15 @@ var MODEL_CATALOG = {
|
|
|
361
404
|
gpu: "L4",
|
|
362
405
|
contextWindow: 65536,
|
|
363
406
|
maxOutputTokens: 8192,
|
|
364
|
-
baseUrl: "https://acemagnifique--notch-serve-solace-lite-notchsolacelitese-0e4da6.modal.run/v1"
|
|
407
|
+
baseUrl: "https://acemagnifique--notch-serve-solace-lite-notchsolacelitese-0e4da6.modal.run/v1",
|
|
408
|
+
hardware: {
|
|
409
|
+
vramGb: 6,
|
|
410
|
+
ramGb: 8,
|
|
411
|
+
diskGb: 3,
|
|
412
|
+
recommendedGpu: "RTX 3060 / M2 Pro+ \xB7 8GB+ VRAM",
|
|
413
|
+
tier: "light"
|
|
414
|
+
},
|
|
415
|
+
hfRepo: null
|
|
365
416
|
}
|
|
366
417
|
};
|
|
367
418
|
var MODEL_IDS = Object.keys(MODEL_CATALOG);
|
|
@@ -475,52 +526,6 @@ async function validateConfig(config) {
|
|
|
475
526
|
}
|
|
476
527
|
}
|
|
477
528
|
|
|
478
|
-
// src/providers/ollama-credentials.ts
|
|
479
|
-
import fs from "fs/promises";
|
|
480
|
-
import path from "path";
|
|
481
|
-
function notchConfigDir() {
|
|
482
|
-
const xdg = process.env.XDG_CONFIG_HOME;
|
|
483
|
-
if (xdg) return path.join(xdg, "notch");
|
|
484
|
-
const appdata = process.env.APPDATA;
|
|
485
|
-
if (appdata && process.platform === "win32") return path.join(appdata, "notch");
|
|
486
|
-
const home = process.env.HOME ?? process.env.USERPROFILE;
|
|
487
|
-
if (!home) {
|
|
488
|
-
throw new Error("Cannot determine home directory for credential storage.");
|
|
489
|
-
}
|
|
490
|
-
return path.join(home, ".config", "notch");
|
|
491
|
-
}
|
|
492
|
-
function ollamaCredsPath() {
|
|
493
|
-
return path.join(notchConfigDir(), "ollama.json");
|
|
494
|
-
}
|
|
495
|
-
async function readOllamaCreds() {
|
|
496
|
-
try {
|
|
497
|
-
const raw = await fs.readFile(ollamaCredsPath(), "utf-8");
|
|
498
|
-
const parsed = JSON.parse(raw);
|
|
499
|
-
if (typeof parsed.apiKey !== "string" || typeof parsed.endpoint !== "string") return null;
|
|
500
|
-
return {
|
|
501
|
-
apiKey: parsed.apiKey,
|
|
502
|
-
endpoint: parsed.endpoint,
|
|
503
|
-
createdAt: typeof parsed.createdAt === "number" ? parsed.createdAt : Date.now()
|
|
504
|
-
};
|
|
505
|
-
} catch {
|
|
506
|
-
return null;
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
async function writeOllamaCreds(creds) {
|
|
510
|
-
const dir = notchConfigDir();
|
|
511
|
-
await fs.mkdir(dir, { recursive: true, mode: 448 });
|
|
512
|
-
const file = ollamaCredsPath();
|
|
513
|
-
await fs.writeFile(file, JSON.stringify(creds, null, 2) + "\n", { mode: 384 });
|
|
514
|
-
}
|
|
515
|
-
async function clearOllamaCreds() {
|
|
516
|
-
try {
|
|
517
|
-
await fs.unlink(ollamaCredsPath());
|
|
518
|
-
} catch (err) {
|
|
519
|
-
const code = err.code;
|
|
520
|
-
if (code !== "ENOENT") throw err;
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
|
|
524
529
|
export {
|
|
525
530
|
findByokProvider,
|
|
526
531
|
listByokProviders,
|
|
@@ -535,9 +540,5 @@ export {
|
|
|
535
540
|
isValidModel,
|
|
536
541
|
modelSupportsImages,
|
|
537
542
|
resolveModel,
|
|
538
|
-
validateConfig
|
|
539
|
-
ollamaCredsPath,
|
|
540
|
-
readOllamaCreds,
|
|
541
|
-
writeOllamaCreds,
|
|
542
|
-
clearOllamaCreds
|
|
543
|
+
validateConfig
|
|
543
544
|
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// src/providers/ollama-credentials.ts
|
|
2
|
+
import fs from "fs/promises";
|
|
3
|
+
import path from "path";
|
|
4
|
+
function notchConfigDir() {
|
|
5
|
+
const xdg = process.env.XDG_CONFIG_HOME;
|
|
6
|
+
if (xdg) return path.join(xdg, "notch");
|
|
7
|
+
const appdata = process.env.APPDATA;
|
|
8
|
+
if (appdata && process.platform === "win32") return path.join(appdata, "notch");
|
|
9
|
+
const home = process.env.HOME ?? process.env.USERPROFILE;
|
|
10
|
+
if (!home) {
|
|
11
|
+
throw new Error("Cannot determine home directory for credential storage.");
|
|
12
|
+
}
|
|
13
|
+
return path.join(home, ".config", "notch");
|
|
14
|
+
}
|
|
15
|
+
function ollamaCredsPath() {
|
|
16
|
+
return path.join(notchConfigDir(), "ollama.json");
|
|
17
|
+
}
|
|
18
|
+
async function readOllamaCreds() {
|
|
19
|
+
try {
|
|
20
|
+
const raw = await fs.readFile(ollamaCredsPath(), "utf-8");
|
|
21
|
+
const parsed = JSON.parse(raw);
|
|
22
|
+
if (typeof parsed.apiKey !== "string" || typeof parsed.endpoint !== "string") return null;
|
|
23
|
+
return {
|
|
24
|
+
apiKey: parsed.apiKey,
|
|
25
|
+
endpoint: parsed.endpoint,
|
|
26
|
+
createdAt: typeof parsed.createdAt === "number" ? parsed.createdAt : Date.now()
|
|
27
|
+
};
|
|
28
|
+
} catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async function writeOllamaCreds(creds) {
|
|
33
|
+
const dir = notchConfigDir();
|
|
34
|
+
await fs.mkdir(dir, { recursive: true, mode: 448 });
|
|
35
|
+
const file = ollamaCredsPath();
|
|
36
|
+
await fs.writeFile(file, JSON.stringify(creds, null, 2) + "\n", { mode: 384 });
|
|
37
|
+
}
|
|
38
|
+
async function clearOllamaCreds() {
|
|
39
|
+
try {
|
|
40
|
+
await fs.unlink(ollamaCredsPath());
|
|
41
|
+
} catch (err) {
|
|
42
|
+
const code = err.code;
|
|
43
|
+
if (code !== "ENOENT") throw err;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export {
|
|
48
|
+
ollamaCredsPath,
|
|
49
|
+
readOllamaCreds,
|
|
50
|
+
writeOllamaCreds,
|
|
51
|
+
clearOllamaCreds
|
|
52
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
6
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
7
|
+
}) : x)(function(x) {
|
|
8
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
9
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
10
|
+
});
|
|
11
|
+
var __esm = (fn, res) => function __init() {
|
|
12
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
13
|
+
};
|
|
14
|
+
var __export = (target, all) => {
|
|
15
|
+
for (var name in all)
|
|
16
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
17
|
+
};
|
|
18
|
+
var __copyProps = (to, from, except, desc) => {
|
|
19
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
20
|
+
for (let key of __getOwnPropNames(from))
|
|
21
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
22
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
23
|
+
}
|
|
24
|
+
return to;
|
|
25
|
+
};
|
|
26
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
|
+
|
|
28
|
+
export {
|
|
29
|
+
__require,
|
|
30
|
+
__esm,
|
|
31
|
+
__export,
|
|
32
|
+
__toCommonJS
|
|
33
|
+
};
|
|
File without changes
|
|
@@ -1,12 +1,29 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__esm,
|
|
3
|
+
__export,
|
|
4
|
+
__require
|
|
5
|
+
} from "./chunk-KFQGP6VL.js";
|
|
6
|
+
|
|
1
7
|
// src/auth.ts
|
|
8
|
+
var auth_exports = {};
|
|
9
|
+
__export(auth_exports, {
|
|
10
|
+
clearCredentials: () => clearCredentials,
|
|
11
|
+
getByokSyncPath: () => getByokSyncPath,
|
|
12
|
+
getConfigDir: () => getConfigDir,
|
|
13
|
+
getCredentialsPath: () => getCredentialsPath,
|
|
14
|
+
invalidateSyncedKeysCache: () => invalidateSyncedKeysCache,
|
|
15
|
+
loadCredentials: () => loadCredentials,
|
|
16
|
+
loadSyncedByokKeys: () => loadSyncedByokKeys,
|
|
17
|
+
loadSyncedByokKeysSync: () => loadSyncedByokKeysSync,
|
|
18
|
+
login: () => login,
|
|
19
|
+
saveCredentials: () => saveCredentials,
|
|
20
|
+
syncByokKeys: () => syncByokKeys
|
|
21
|
+
});
|
|
2
22
|
import http from "http";
|
|
3
23
|
import { exec } from "child_process";
|
|
4
24
|
import os from "os";
|
|
5
25
|
import path from "path";
|
|
6
26
|
import fs from "fs/promises";
|
|
7
|
-
var FREESYNTAX_URL = "https://freesyntax.dev";
|
|
8
|
-
var PREFERRED_PORT = 9721;
|
|
9
|
-
var AUTH_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
10
27
|
function getConfigDir() {
|
|
11
28
|
if (process.platform === "win32") {
|
|
12
29
|
return path.join(process.env["APPDATA"] ?? os.homedir(), "notch");
|
|
@@ -45,6 +62,58 @@ async function clearCredentials() {
|
|
|
45
62
|
} catch {
|
|
46
63
|
}
|
|
47
64
|
}
|
|
65
|
+
function getByokSyncPath() {
|
|
66
|
+
return path.join(getConfigDir(), "byok-sync.json");
|
|
67
|
+
}
|
|
68
|
+
async function syncByokKeys(token, baseUrl = FREESYNTAX_URL) {
|
|
69
|
+
const url = `${baseUrl.replace(/\/$/, "")}/api/cli/keys`;
|
|
70
|
+
const res = await fetch(url, {
|
|
71
|
+
method: "GET",
|
|
72
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
73
|
+
});
|
|
74
|
+
if (!res.ok) {
|
|
75
|
+
const body = await res.text().catch(() => "");
|
|
76
|
+
throw new Error(`Key sync failed (${res.status}): ${body.slice(0, 200) || res.statusText}`);
|
|
77
|
+
}
|
|
78
|
+
const data = await res.json();
|
|
79
|
+
const dir = getConfigDir();
|
|
80
|
+
await fs.mkdir(dir, { recursive: true });
|
|
81
|
+
await fs.writeFile(
|
|
82
|
+
getByokSyncPath(),
|
|
83
|
+
JSON.stringify({ ...data, syncedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2),
|
|
84
|
+
{ encoding: "utf-8", mode: 384 }
|
|
85
|
+
);
|
|
86
|
+
return data;
|
|
87
|
+
}
|
|
88
|
+
async function loadSyncedByokKeys() {
|
|
89
|
+
try {
|
|
90
|
+
const raw = await fs.readFile(getByokSyncPath(), "utf-8");
|
|
91
|
+
const parsed = JSON.parse(raw);
|
|
92
|
+
if (parsed && typeof parsed === "object" && parsed.keys) return parsed;
|
|
93
|
+
return null;
|
|
94
|
+
} catch {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function loadSyncedByokKeysSync() {
|
|
99
|
+
if (syncedKeysCache !== void 0) return syncedKeysCache;
|
|
100
|
+
try {
|
|
101
|
+
const fsSync = __require("fs");
|
|
102
|
+
const raw = fsSync.readFileSync(getByokSyncPath(), "utf-8");
|
|
103
|
+
const parsed = JSON.parse(raw);
|
|
104
|
+
if (parsed && typeof parsed === "object" && parsed.keys) {
|
|
105
|
+
syncedKeysCache = parsed;
|
|
106
|
+
} else {
|
|
107
|
+
syncedKeysCache = null;
|
|
108
|
+
}
|
|
109
|
+
} catch {
|
|
110
|
+
syncedKeysCache = null;
|
|
111
|
+
}
|
|
112
|
+
return syncedKeysCache;
|
|
113
|
+
}
|
|
114
|
+
function invalidateSyncedKeysCache() {
|
|
115
|
+
syncedKeysCache = void 0;
|
|
116
|
+
}
|
|
48
117
|
function openBrowser(url) {
|
|
49
118
|
let cmd;
|
|
50
119
|
if (process.platform === "win32") {
|
|
@@ -130,7 +199,13 @@ async function login() {
|
|
|
130
199
|
}, AUTH_TIMEOUT_MS);
|
|
131
200
|
});
|
|
132
201
|
}
|
|
133
|
-
var
|
|
202
|
+
var FREESYNTAX_URL, PREFERRED_PORT, AUTH_TIMEOUT_MS, syncedKeysCache, HTML_BASE, HTML_SUCCESS, HTML_ERROR;
|
|
203
|
+
var init_auth = __esm({
|
|
204
|
+
"src/auth.ts"() {
|
|
205
|
+
FREESYNTAX_URL = "https://freesyntax.dev";
|
|
206
|
+
PREFERRED_PORT = 9721;
|
|
207
|
+
AUTH_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
208
|
+
HTML_BASE = (body) => `<!DOCTYPE html>
|
|
134
209
|
<html lang="en">
|
|
135
210
|
<head>
|
|
136
211
|
<meta charset="utf-8">
|
|
@@ -157,16 +232,18 @@ var HTML_BASE = (body) => `<!DOCTYPE html>
|
|
|
157
232
|
</head>
|
|
158
233
|
<body><div class="card">${body}</div></body>
|
|
159
234
|
</html>`;
|
|
160
|
-
|
|
235
|
+
HTML_SUCCESS = HTML_BASE(`
|
|
161
236
|
<div class="brand">notch_</div>
|
|
162
237
|
<h1>CLI authorized</h1>
|
|
163
238
|
<p>You can close this tab and return to your terminal.</p>
|
|
164
239
|
`);
|
|
165
|
-
|
|
240
|
+
HTML_ERROR = HTML_BASE(`
|
|
166
241
|
<div class="brand">notch_</div>
|
|
167
242
|
<h1>Authorization failed</h1>
|
|
168
243
|
<p style="color:#CE2127">Run <code>notch login</code> again to retry.</p>
|
|
169
244
|
`);
|
|
245
|
+
}
|
|
246
|
+
});
|
|
170
247
|
|
|
171
248
|
export {
|
|
172
249
|
getConfigDir,
|
|
@@ -174,5 +251,12 @@ export {
|
|
|
174
251
|
loadCredentials,
|
|
175
252
|
saveCredentials,
|
|
176
253
|
clearCredentials,
|
|
177
|
-
|
|
254
|
+
getByokSyncPath,
|
|
255
|
+
syncByokKeys,
|
|
256
|
+
loadSyncedByokKeys,
|
|
257
|
+
loadSyncedByokKeysSync,
|
|
258
|
+
invalidateSyncedKeysCache,
|
|
259
|
+
login,
|
|
260
|
+
auth_exports,
|
|
261
|
+
init_auth
|
|
178
262
|
};
|