@freesyntax/notch-cli 0.5.20 → 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.
Files changed (40) hide show
  1. package/dist/{apply-patch-D5PDUXUC.js → apply-patch-U6K67CMT.js} +1 -0
  2. package/dist/auth-UAMMP5IJ.js +29 -0
  3. package/dist/chunk-4HPRBCSY.js +167 -0
  4. package/dist/chunk-6NKRMZTX.js +198 -0
  5. package/dist/{chunk-YBYF7L4A.js → chunk-EPSOOCNB.js} +1832 -1331
  6. package/dist/chunk-FZVPGJJW.js +511 -0
  7. package/dist/chunk-GFVLHUSS.js +155 -0
  8. package/dist/chunk-J66N6AFH.js +137 -0
  9. package/dist/chunk-JXQ4HZ47.js +544 -0
  10. package/dist/chunk-KCAR5DOB.js +52 -0
  11. package/dist/chunk-KFQGP6VL.js +33 -0
  12. package/dist/chunk-O6AKZ4OH.js +0 -0
  13. package/dist/{chunk-6M6CXXWR.js → chunk-PKZKVOAN.js} +209 -1
  14. package/dist/{chunk-FIFC4V2R.js → chunk-PPEBWOMJ.js} +91 -7
  15. package/dist/compression-YJLWEHCC.js +33 -0
  16. package/dist/config-set-3IWEVZQ4.js +110 -0
  17. package/dist/{edit-JEFEK43H.js → edit-6QYAXVNU.js} +1 -0
  18. package/dist/{git-5T5TSQTX.js → git-DNQ5EELH.js} +1 -0
  19. package/dist/{github-DWRGWX6U.js → github-34T4QQIH.js} +1 -0
  20. package/dist/{glob-BI3P4C7Q.js → glob-XT43LEJ4.js} +1 -0
  21. package/dist/{grep-VZ3I5GNW.js → grep-T2CXYNRI.js} +1 -0
  22. package/dist/index.js +2606 -960
  23. package/dist/{lsp-UPY6I3L7.js → lsp-JXQVU7NP.js} +1 -0
  24. package/dist/model-download-3NDKS3VM.js +176 -0
  25. package/dist/{notebook-FXJBTSPA.js → notebook-MFODW345.js} +1 -0
  26. package/dist/ollama-bench-5V5CCOCQ.js +194 -0
  27. package/dist/ollama-launch-P5KBK7AJ.js +22 -0
  28. package/dist/ollama-usage-3PROM2WC.js +70 -0
  29. package/dist/{plugins-OG2P75K5.js → plugins-PNGRZLFW.js} +1 -0
  30. package/dist/{read-OVJG2XKW.js → read-B64XE7N3.js} +1 -0
  31. package/dist/{server-W7FRCVRZ.js → server-IGOZHW52.js} +17 -15
  32. package/dist/session-index-7FWEVP6E.js +22 -0
  33. package/dist/{shell-4X545EVN.js → shell-BOZTHQUT.js} +1 -0
  34. package/dist/{task-OS3E5F3X.js → task-67G4KLYC.js} +1 -0
  35. package/dist/{tools-Q7CDHB4K.js → tools-XWKCW4RN.js} +4 -1
  36. package/dist/{web-fetch-KNIV3Z3W.js → web-fetch-OTNDICGJ.js} +1 -0
  37. package/dist/{write-NNHLOTYK.js → write-ZOSB7I4J.js} +1 -0
  38. package/package.json +2 -1
  39. package/dist/auth-JQX6MHJG.js +0 -16
  40. package/dist/compression-UTB2Y4BB.js +0 -16
@@ -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,5 +1,6 @@
1
1
  // src/agent/compression.ts
2
2
  import { generateText } from "ai";
3
+ import { createHash } from "crypto";
3
4
  function estimateTokens(messages) {
4
5
  let chars = 0;
5
6
  for (const msg of messages) {
@@ -15,6 +16,112 @@ function estimateTokens(messages) {
15
16
  }
16
17
  return Math.ceil(chars / 4);
17
18
  }
19
+ var InMemoryArtifactStore = class {
20
+ map = /* @__PURE__ */ new Map();
21
+ put(key, value) {
22
+ this.map.set(key, value);
23
+ }
24
+ get(key) {
25
+ return this.map.get(key);
26
+ }
27
+ has(key) {
28
+ return this.map.has(key);
29
+ }
30
+ };
31
+ var globalArtifactStore = new InMemoryArtifactStore();
32
+ function setArtifactStore(store) {
33
+ const prev = globalArtifactStore;
34
+ globalArtifactStore = store;
35
+ return () => {
36
+ globalArtifactStore = prev;
37
+ };
38
+ }
39
+ function getArtifactStore() {
40
+ return globalArtifactStore;
41
+ }
42
+ var ARTIFACT_URI_PREFIX = "notch-artifact://";
43
+ function artifactKey(content) {
44
+ return createHash("sha1").update(content).digest("hex").slice(0, 16);
45
+ }
46
+ function makeArtifactUri(key) {
47
+ return `${ARTIFACT_URI_PREFIX}${key}`;
48
+ }
49
+ function parseArtifactUri(text) {
50
+ const match = text.match(/notch-artifact:\/\/([a-f0-9]{8,64})/);
51
+ return match ? match[1] : null;
52
+ }
53
+ var BUDGET_TOOL_RESULT_MAX = 3e3;
54
+ var BUDGET_PREVIEW_CHARS = 400;
55
+ function budgetReduce(messages, opts = {}) {
56
+ const maxChars = opts.maxToolResultChars ?? BUDGET_TOOL_RESULT_MAX;
57
+ const previewChars = opts.previewChars ?? BUDGET_PREVIEW_CHARS;
58
+ const keepLastN = opts.keepLastN ?? 4;
59
+ const store = opts.store ?? globalArtifactStore;
60
+ const toolIdx = [];
61
+ for (let i = 0; i < messages.length; i++) {
62
+ if (messages[i].role === "tool") toolIdx.push(i);
63
+ }
64
+ const eligibleUpTo = toolIdx.length - keepLastN;
65
+ if (eligibleUpTo <= 0) return { messages, stashed: 0, savedChars: 0 };
66
+ const eligible = new Set(toolIdx.slice(0, eligibleUpTo));
67
+ let stashed = 0;
68
+ let savedChars = 0;
69
+ const out = messages.map((msg, idx) => {
70
+ if (msg.role !== "tool" || !eligible.has(idx)) return msg;
71
+ if (!Array.isArray(msg.content)) return msg;
72
+ let touched = false;
73
+ const newContent = msg.content.map((block) => {
74
+ const b = block;
75
+ if (b.type !== "tool-result") return block;
76
+ const resultStr = typeof b.result === "string" ? b.result : JSON.stringify(b.result ?? "");
77
+ if (resultStr.length <= maxChars) return block;
78
+ const key = artifactKey(resultStr);
79
+ try {
80
+ void store.put(key, resultStr);
81
+ } catch {
82
+ return block;
83
+ }
84
+ const preview = resultStr.slice(0, previewChars);
85
+ const replacement = `${preview}
86
+ ... [+${resultStr.length - previewChars} chars stashed at ${makeArtifactUri(key)}]`;
87
+ savedChars += resultStr.length - replacement.length;
88
+ stashed++;
89
+ touched = true;
90
+ return {
91
+ ...b,
92
+ result: replacement
93
+ };
94
+ });
95
+ if (!touched) return msg;
96
+ return { ...msg, content: newContent };
97
+ });
98
+ return { messages: out, stashed, savedChars };
99
+ }
100
+ function snip(messages, opts = {}) {
101
+ const keepStart = opts.keepStart ?? 1;
102
+ const keepRecent = opts.keepRecent ?? 6;
103
+ const trigger = opts.triggerMiddleCount ?? 40;
104
+ const snipCount = opts.snipCount ?? 10;
105
+ if (messages.length < keepStart + keepRecent + trigger) {
106
+ return { messages, snipped: 0 };
107
+ }
108
+ const head = messages.slice(0, keepStart);
109
+ const tail = messages.slice(-keepRecent);
110
+ const middle = messages.slice(keepStart, messages.length - keepRecent);
111
+ let cut = Math.min(snipCount, middle.length);
112
+ while (cut < middle.length && middle[cut].role === "tool") cut++;
113
+ const dropped = middle.slice(0, cut);
114
+ const kept = middle.slice(cut);
115
+ if (dropped.length === 0) return { messages, snipped: 0 };
116
+ const marker = {
117
+ role: "user",
118
+ content: `[snip: ${dropped.length} older messages removed by age]`
119
+ };
120
+ return {
121
+ messages: [...head, marker, ...kept, ...tail],
122
+ snipped: dropped.length
123
+ };
124
+ }
18
125
  var TEXT_BLOCK_MAX = 8e3;
19
126
  function microCompact(messages) {
20
127
  const result = [];
@@ -35,6 +142,48 @@ function microCompact(messages) {
35
142
  }
36
143
  return result;
37
144
  }
145
+ function contextCollapse(messages, opts = {}) {
146
+ const keepStart = opts.keepStart ?? 1;
147
+ const keepRecent = opts.keepRecent ?? 4;
148
+ const trigger = opts.triggerMiddleCount ?? 12;
149
+ const store = opts.store ?? globalArtifactStore;
150
+ if (messages.length < keepStart + keepRecent + trigger) {
151
+ return { messages, collapsed: false };
152
+ }
153
+ const head = messages.slice(0, keepStart);
154
+ const middle = messages.slice(keepStart, messages.length - keepRecent);
155
+ const tail = messages.slice(-keepRecent);
156
+ if (middle.length === 0) return { messages, collapsed: false };
157
+ let key;
158
+ try {
159
+ const serialized = JSON.stringify(middle);
160
+ key = artifactKey(serialized);
161
+ void store.put(key, serialized);
162
+ } catch {
163
+ }
164
+ const summaryText = buildDeterministicSummary(middle);
165
+ const ref = key ? ` (originals at ${makeArtifactUri(key)})` : "";
166
+ const summaryMarker = {
167
+ role: "user",
168
+ content: `[Context collapsed \u2014 ${middle.length} messages summarized${ref}]
169
+ ${summaryText}`
170
+ };
171
+ return {
172
+ messages: [...head, summaryMarker, ...tail],
173
+ collapsed: true,
174
+ artifactKey: key
175
+ };
176
+ }
177
+ async function restoreCollapsedSpan(artifactKeyOrUri, store = globalArtifactStore) {
178
+ const key = artifactKeyOrUri.startsWith(ARTIFACT_URI_PREFIX) ? artifactKeyOrUri.slice(ARTIFACT_URI_PREFIX.length) : artifactKeyOrUri;
179
+ const raw = await store.get(key);
180
+ if (!raw) return null;
181
+ try {
182
+ return JSON.parse(raw);
183
+ } catch {
184
+ return null;
185
+ }
186
+ }
38
187
  var RESERVE_BUFFER_TOKENS = 13e3;
39
188
  var MAX_SUMMARY_TOKENS = 2e4;
40
189
  var MAX_COMPRESSION_FAILURES = 3;
@@ -180,10 +329,19 @@ ${firstContent}`
180
329
  return { messages: compressed, compressed: true };
181
330
  }
182
331
  async function autoCompress(messages, model, contextWindow, onCompress) {
183
- let result = microCompact(messages);
184
332
  const threshold = (contextWindow - RESERVE_BUFFER_TOKENS) * 0.75;
333
+ let result = budgetReduce(messages).messages;
334
+ result = snip(result).messages;
335
+ result = microCompact(result);
185
336
  let tokens = estimateTokens(result);
186
337
  if (tokens < threshold) return result;
338
+ const collapsed = contextCollapse(result);
339
+ if (collapsed.collapsed) {
340
+ onCompress?.();
341
+ result = collapsed.messages;
342
+ tokens = estimateTokens(result);
343
+ }
344
+ if (tokens < threshold) return result;
187
345
  const auto = await autoCompactSummarize(result, { model, contextWindow });
188
346
  if (auto.compressed) {
189
347
  onCompress?.();
@@ -198,6 +356,48 @@ async function autoCompress(messages, model, contextWindow, onCompress) {
198
356
  }
199
357
  return result;
200
358
  }
359
+ async function autoCompressWithStats(messages, model, contextWindow) {
360
+ const stats = {
361
+ budgetStashed: 0,
362
+ snipped: 0,
363
+ collapsed: false,
364
+ autoCompacted: false,
365
+ fullCompacted: false
366
+ };
367
+ const threshold = (contextWindow - RESERVE_BUFFER_TOKENS) * 0.75;
368
+ const br = budgetReduce(messages);
369
+ let result = br.messages;
370
+ stats.budgetStashed = br.stashed;
371
+ const sn = snip(result);
372
+ result = sn.messages;
373
+ stats.snipped = sn.snipped;
374
+ result = microCompact(result);
375
+ let tokens = estimateTokens(result);
376
+ if (tokens >= threshold) {
377
+ const collapsed = contextCollapse(result);
378
+ if (collapsed.collapsed) {
379
+ result = collapsed.messages;
380
+ stats.collapsed = true;
381
+ tokens = estimateTokens(result);
382
+ }
383
+ }
384
+ if (tokens >= threshold) {
385
+ const auto = await autoCompactSummarize(result, { model, contextWindow });
386
+ if (auto.compressed) {
387
+ result = auto.messages;
388
+ stats.autoCompacted = true;
389
+ tokens = estimateTokens(result);
390
+ }
391
+ }
392
+ if (tokens >= threshold) {
393
+ const full = await fullCompact(result, model);
394
+ if (full.compressed) {
395
+ result = full.messages;
396
+ stats.fullCompacted = true;
397
+ }
398
+ }
399
+ return { messages: result, stats };
400
+ }
201
401
  async function compressHistory(messages, opts) {
202
402
  const result = await autoCompactSummarize(messages, opts);
203
403
  return result;
@@ -205,9 +405,17 @@ async function compressHistory(messages, opts) {
205
405
 
206
406
  export {
207
407
  estimateTokens,
408
+ setArtifactStore,
409
+ getArtifactStore,
410
+ parseArtifactUri,
411
+ budgetReduce,
412
+ snip,
208
413
  microCompact,
414
+ contextCollapse,
415
+ restoreCollapsedSpan,
209
416
  autoCompactSummarize,
210
417
  fullCompact,
211
418
  autoCompress,
419
+ autoCompressWithStats,
212
420
  compressHistory
213
421
  };
@@ -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 HTML_BASE = (body) => `<!DOCTYPE html>
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
- var HTML_SUCCESS = HTML_BASE(`
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
- var HTML_ERROR = HTML_BASE(`
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
- login
254
+ getByokSyncPath,
255
+ syncByokKeys,
256
+ loadSyncedByokKeys,
257
+ loadSyncedByokKeysSync,
258
+ invalidateSyncedKeysCache,
259
+ login,
260
+ auth_exports,
261
+ init_auth
178
262
  };
@@ -0,0 +1,33 @@
1
+ import {
2
+ autoCompactSummarize,
3
+ autoCompress,
4
+ autoCompressWithStats,
5
+ budgetReduce,
6
+ compressHistory,
7
+ contextCollapse,
8
+ estimateTokens,
9
+ fullCompact,
10
+ getArtifactStore,
11
+ microCompact,
12
+ parseArtifactUri,
13
+ restoreCollapsedSpan,
14
+ setArtifactStore,
15
+ snip
16
+ } from "./chunk-PKZKVOAN.js";
17
+ import "./chunk-KFQGP6VL.js";
18
+ export {
19
+ autoCompactSummarize,
20
+ autoCompress,
21
+ autoCompressWithStats,
22
+ budgetReduce,
23
+ compressHistory,
24
+ contextCollapse,
25
+ estimateTokens,
26
+ fullCompact,
27
+ getArtifactStore,
28
+ microCompact,
29
+ parseArtifactUri,
30
+ restoreCollapsedSpan,
31
+ setArtifactStore,
32
+ snip
33
+ };
@@ -0,0 +1,110 @@
1
+ import {
2
+ persistConfigPatch
3
+ } from "./chunk-J66N6AFH.js";
4
+ import "./chunk-KCAR5DOB.js";
5
+ import "./chunk-JXQ4HZ47.js";
6
+ import "./chunk-PPEBWOMJ.js";
7
+ import "./chunk-KFQGP6VL.js";
8
+
9
+ // src/commands/config-set.ts
10
+ import fs from "fs/promises";
11
+ import path from "path";
12
+ var HELP = `notch config \u2014 manage .notch.json settings
13
+
14
+ Usage:
15
+ notch config get [key]
16
+ notch config set <key> <value>
17
+ notch config unset <key>
18
+ notch config yolo [on|off] # auto-allow every tool call (sticks)
19
+
20
+ Examples:
21
+ notch config set permissionMode trust
22
+ notch config set autoConfirm true
23
+ notch config set model pyre
24
+ notch config yolo on
25
+ notch config yolo off
26
+ `;
27
+ function parseValue(raw) {
28
+ try {
29
+ return JSON.parse(raw);
30
+ } catch {
31
+ return raw;
32
+ }
33
+ }
34
+ async function readCurrent(projectRoot) {
35
+ const p = path.resolve(projectRoot, ".notch.json");
36
+ try {
37
+ const raw = await fs.readFile(p, "utf-8");
38
+ const parsed = JSON.parse(raw);
39
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
40
+ return parsed;
41
+ }
42
+ } catch {
43
+ }
44
+ return {};
45
+ }
46
+ async function runConfigCli(argv, projectRoot) {
47
+ const sub = argv[0];
48
+ if (!sub || sub === "-h" || sub === "--help" || sub === "help") {
49
+ process.stdout.write(HELP);
50
+ return 0;
51
+ }
52
+ if (sub === "get") {
53
+ const key = argv[1];
54
+ const cur = await readCurrent(projectRoot);
55
+ if (!key) {
56
+ process.stdout.write(JSON.stringify(cur, null, 2) + "\n");
57
+ return 0;
58
+ }
59
+ if (key in cur) {
60
+ process.stdout.write(JSON.stringify(cur[key]) + "\n");
61
+ return 0;
62
+ }
63
+ process.stderr.write(`notch: no such key: ${key}
64
+ `);
65
+ return 1;
66
+ }
67
+ if (sub === "set") {
68
+ const key = argv[1];
69
+ const value = argv.slice(2).join(" ");
70
+ if (!key || value.length === 0) {
71
+ process.stderr.write("usage: notch config set <key> <value>\n");
72
+ return 2;
73
+ }
74
+ const parsed = parseValue(value);
75
+ const merged = await persistConfigPatch(projectRoot, { [key]: parsed });
76
+ process.stdout.write(`${key} = ${JSON.stringify(merged[key])}
77
+ `);
78
+ return 0;
79
+ }
80
+ if (sub === "unset") {
81
+ const key = argv[1];
82
+ if (!key) {
83
+ process.stderr.write("usage: notch config unset <key>\n");
84
+ return 2;
85
+ }
86
+ await persistConfigPatch(projectRoot, { [key]: void 0 });
87
+ process.stdout.write(`removed ${key}
88
+ `);
89
+ return 0;
90
+ }
91
+ if (sub === "yolo") {
92
+ const arg = (argv[1] ?? "").toLowerCase();
93
+ const cur = await readCurrent(projectRoot);
94
+ const currentlyOn = cur.permissionMode === "trust";
95
+ const turnOn = arg === "" ? !currentlyOn : arg === "on" || arg === "true" || arg === "1" || arg === "yes";
96
+ await persistConfigPatch(projectRoot, {
97
+ permissionMode: turnOn ? "trust" : "auto",
98
+ autoConfirm: turnOn ? true : void 0
99
+ });
100
+ process.stdout.write(turnOn ? "YOLO mode ON \u2014 every tool call auto-allowed. Saved to .notch.json.\n" : "YOLO mode OFF \u2014 prompts restored. Saved to .notch.json.\n");
101
+ return 0;
102
+ }
103
+ process.stderr.write(`notch: unknown config subcommand: ${sub}
104
+ `);
105
+ process.stderr.write(HELP);
106
+ return 2;
107
+ }
108
+ export {
109
+ runConfigCli
110
+ };
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  editTool
3
3
  } from "./chunk-YAYPQTOU.js";
4
+ import "./chunk-KFQGP6VL.js";
4
5
  export {
5
6
  editTool
6
7
  };
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  gitTool
3
3
  } from "./chunk-FAULT7VE.js";
4
+ import "./chunk-KFQGP6VL.js";
4
5
  export {
5
6
  gitTool
6
7
  };
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  githubTool
3
3
  } from "./chunk-GBZGR6ID.js";
4
+ import "./chunk-KFQGP6VL.js";
4
5
  export {
5
6
  githubTool
6
7
  };
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  globTool
3
3
  } from "./chunk-6U3ZAGYA.js";
4
+ import "./chunk-KFQGP6VL.js";
4
5
  export {
5
6
  globTool
6
7
  };
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  grepTool
3
3
  } from "./chunk-6CZCFY6H.js";
4
+ import "./chunk-KFQGP6VL.js";
4
5
  export {
5
6
  grepTool
6
7
  };