jinzd-ai-cli 0.4.241 → 0.4.243
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/README.md +2 -2
- package/dist/{batch-K66BLTLJ.js → batch-CUVZUPRK.js} +2 -2
- package/dist/{chat-index-7HXBWQFH.js → chat-index-ALUHFJKI.js} +3 -2
- package/dist/{chat-index-WYXYD7YP.js → chat-index-ML5FF5L6.js} +2 -1
- package/dist/{chunk-SMQHEJSH.js → chunk-66CE3E6X.js} +1 -1
- package/dist/chunk-B5TYJO7V.js +123 -0
- package/dist/{chunk-PGHTAKIA.js → chunk-DJGCG7SF.js} +1 -1
- package/dist/{chunk-2QQKS56X.js → chunk-DT77O33T.js} +1 -1
- package/dist/{chunk-2LLQOMMW.js → chunk-EMFCHE2B.js} +1 -1
- package/dist/chunk-GEWPLNKA.js +164 -0
- package/dist/{chunk-LXSUPLCK.js → chunk-H3ARWBYR.js} +2 -2
- package/dist/{chunk-3AIR7N5M.js → chunk-HNJX3N2V.js} +5 -5
- package/dist/{chunk-5MYPIQ3Y.js → chunk-IGPFYNZA.js} +4 -2
- package/dist/{chunk-GORPFFV4.js → chunk-KILKF2VN.js} +97 -254
- package/dist/{chunk-JMP3LJC2.js → chunk-KWQKQVPH.js} +4 -2
- package/dist/{chunk-NAQPP3GZ.js → chunk-L5IRDRWG.js} +1 -1
- package/dist/{chunk-UO3XWZFE.js → chunk-NV63EYFL.js} +3 -119
- package/dist/{chunk-KCEO2XJ4.js → chunk-PJ3ONBWZ.js} +0 -119
- package/dist/{chunk-ZPXMT2B6.js → chunk-PLEXBFCR.js} +4 -163
- package/dist/chunk-PNNZRJ67.js +523 -0
- package/dist/{chunk-CHFFEVVT.js → chunk-QNK7GUUB.js} +3 -3
- package/dist/chunk-TY4FSEZS.js +432 -0
- package/dist/{chunk-IV6GCDVR.js → chunk-X73Y4JZI.js} +7 -1
- package/dist/chunk-YVTASHS5.js +121 -0
- package/dist/{ci-T2ABDMMQ.js → ci-3O3JR6FX.js} +4 -4
- package/dist/{ci-format-S2PPU27O.js → ci-format-KGWF6KOU.js} +2 -2
- package/dist/{constants-RS7OUU7X.js → constants-NMFRZ5LW.js} +1 -1
- package/dist/{doctor-cli-TGAW6RAP.js → doctor-cli-4QUHTJZ4.js} +4 -4
- package/dist/electron-server.js +446 -579
- package/dist/{hub-GL5ZU6WS.js → hub-2GXFPWOR.js} +2 -2
- package/dist/index.js +273 -62
- package/dist/{persist-AMH5SQ4W.js → persist-WGIJ6RXY.js} +4 -3
- package/dist/persistent-memory-VFBRMKGG.js +65 -0
- package/dist/persistent-memory-ZCQKLIC5.js +63 -0
- package/dist/{pr-TJFKUZ4B.js → pr-GIDFO4KP.js} +5 -5
- package/dist/{run-tests-KEI7IXTB.js → run-tests-BMH6QJN2.js} +2 -2
- package/dist/{run-tests-EWMU34A4.js → run-tests-WCZBWQFS.js} +2 -1
- package/dist/{server-UVS2D4M6.js → server-A5NGGDMP.js} +130 -47
- package/dist/{server-E545UIX7.js → server-FEFIFJDA.js} +8 -6
- package/dist/{task-orchestrator-PWXV2EBN.js → task-orchestrator-J2H6OV6R.js} +8 -6
- package/dist/{usage-EDJ6QOWB.js → usage-7WJC234G.js} +2 -2
- package/package.json +1 -1
|
@@ -1,4 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
addMemoryEntry,
|
|
4
|
+
findSimilarMemory,
|
|
5
|
+
loadMemoryEntries,
|
|
6
|
+
parseWritableScope,
|
|
7
|
+
searchPersistentMemories,
|
|
8
|
+
touchMemoryReferences,
|
|
9
|
+
updateMemoryEntry
|
|
10
|
+
} from "./chunk-TY4FSEZS.js";
|
|
2
11
|
import {
|
|
3
12
|
indexProject
|
|
4
13
|
} from "./chunk-K3CF65QH.js";
|
|
@@ -14,7 +23,7 @@ import {
|
|
|
14
23
|
runHook,
|
|
15
24
|
runLifecycleHooks,
|
|
16
25
|
runTool
|
|
17
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-EMFCHE2B.js";
|
|
18
27
|
import {
|
|
19
28
|
getDangerLevel,
|
|
20
29
|
isFileWriteTool,
|
|
@@ -25,33 +34,23 @@ import {
|
|
|
25
34
|
NetworkError,
|
|
26
35
|
ToolError
|
|
27
36
|
} from "./chunk-5ULLIOVC.js";
|
|
28
|
-
import {
|
|
29
|
-
getGitRoot
|
|
30
|
-
} from "./chunk-HOSJZMQS.js";
|
|
31
37
|
import {
|
|
32
38
|
fileCheckpoints
|
|
33
39
|
} from "./chunk-4BKXL7SM.js";
|
|
34
40
|
import {
|
|
35
41
|
runTestsTool
|
|
36
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-L5IRDRWG.js";
|
|
37
43
|
import {
|
|
38
44
|
CONFIG_DIR_NAME,
|
|
39
45
|
DEFAULT_MAX_TOOL_OUTPUT_CHARS_CAP,
|
|
40
|
-
MEMORY_FILE_NAME,
|
|
41
|
-
MEMORY_MAX_CHARS,
|
|
42
|
-
MEMORY_STORE_FILE_NAME,
|
|
43
46
|
SUBAGENT_ALLOWED_TOOLS,
|
|
44
47
|
SUBAGENT_DEFAULT_MAX_ROUNDS,
|
|
45
48
|
SUBAGENT_MAX_ROUNDS_LIMIT
|
|
46
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-66CE3E6X.js";
|
|
47
50
|
import {
|
|
48
51
|
loadChatIndex,
|
|
49
52
|
searchChatMemory
|
|
50
|
-
} from "./chunk-
|
|
51
|
-
import {
|
|
52
|
-
DEFAULT_PATTERNS,
|
|
53
|
-
redactString
|
|
54
|
-
} from "./chunk-KCEO2XJ4.js";
|
|
53
|
+
} from "./chunk-IGPFYNZA.js";
|
|
55
54
|
import {
|
|
56
55
|
atomicWriteFileSync
|
|
57
56
|
} from "./chunk-IW3Q7AE5.js";
|
|
@@ -140,7 +139,7 @@ async function execInPool(sessionKey, command, timeout, cwd, abortSignal) {
|
|
|
140
139
|
const markerStart = `AICLI_MARKER_START:${id}`;
|
|
141
140
|
const markerEnd = `AICLI_MARKER_END:${id}`;
|
|
142
141
|
const wrappedCmd = IS_WINDOWS2 ? `${WIN_UTF8_PREAMBLE} echo "${markerStart}"; ${command}; echo "${markerEnd}:0"` : `echo "${markerStart}"; ${command}; echo "${markerEnd}:$?"`;
|
|
143
|
-
return new Promise((
|
|
142
|
+
return new Promise((resolve7) => {
|
|
144
143
|
let stdout = "";
|
|
145
144
|
let stderr = "";
|
|
146
145
|
let timedOut = false;
|
|
@@ -156,7 +155,7 @@ async function execInPool(sessionKey, command, timeout, cwd, abortSignal) {
|
|
|
156
155
|
stdout = stripMarkerOutput(stdout, markerStartPattern, markerEndPattern);
|
|
157
156
|
resolved = true;
|
|
158
157
|
cleanup();
|
|
159
|
-
|
|
158
|
+
resolve7({ stdout, stderr, exitCode, timedOut, aborted });
|
|
160
159
|
}
|
|
161
160
|
};
|
|
162
161
|
const onErr = (chunk) => {
|
|
@@ -171,7 +170,7 @@ async function execInPool(sessionKey, command, timeout, cwd, abortSignal) {
|
|
|
171
170
|
resolved = true;
|
|
172
171
|
stdout = stripMarkerOutput(stdout, markerStartPattern, markerEndPattern);
|
|
173
172
|
cleanup();
|
|
174
|
-
|
|
173
|
+
resolve7({ stdout, stderr, exitCode: null, timedOut, aborted });
|
|
175
174
|
try {
|
|
176
175
|
proc.kill();
|
|
177
176
|
} catch {
|
|
@@ -184,7 +183,7 @@ async function execInPool(sessionKey, command, timeout, cwd, abortSignal) {
|
|
|
184
183
|
resolved = true;
|
|
185
184
|
cleanup();
|
|
186
185
|
stdout = stripMarkerOutput(stdout, markerStartPattern, markerEndPattern);
|
|
187
|
-
|
|
186
|
+
resolve7({ stdout, stderr, exitCode: null, timedOut, aborted });
|
|
188
187
|
try {
|
|
189
188
|
proc.kill();
|
|
190
189
|
} catch {
|
|
@@ -202,7 +201,7 @@ async function execInPool(sessionKey, command, timeout, cwd, abortSignal) {
|
|
|
202
201
|
stderr += `
|
|
203
202
|
[pool error] ${err.message}`;
|
|
204
203
|
cleanup();
|
|
205
|
-
|
|
204
|
+
resolve7({ stdout, stderr, exitCode: null, timedOut, aborted });
|
|
206
205
|
pool.delete(sessionKey);
|
|
207
206
|
};
|
|
208
207
|
proc.on("error", onError);
|
|
@@ -2540,7 +2539,7 @@ var ToolExecutor = class {
|
|
|
2540
2539
|
rl.resume();
|
|
2541
2540
|
process.stdout.write(prompt);
|
|
2542
2541
|
this.confirming = true;
|
|
2543
|
-
return new Promise((
|
|
2542
|
+
return new Promise((resolve7) => {
|
|
2544
2543
|
let completed = false;
|
|
2545
2544
|
const cleanup = (result) => {
|
|
2546
2545
|
if (completed) return;
|
|
@@ -2550,7 +2549,7 @@ var ToolExecutor = class {
|
|
|
2550
2549
|
rl.pause();
|
|
2551
2550
|
rlAny.output = savedOutput;
|
|
2552
2551
|
this.confirming = false;
|
|
2553
|
-
|
|
2552
|
+
resolve7(result);
|
|
2554
2553
|
};
|
|
2555
2554
|
const onLine = (line) => {
|
|
2556
2555
|
const trimmed = line.trim();
|
|
@@ -2724,7 +2723,7 @@ var ToolExecutor = class {
|
|
|
2724
2723
|
rl.resume();
|
|
2725
2724
|
process.stdout.write(color("Proceed? [y/N] (type y + Enter to confirm) "));
|
|
2726
2725
|
this.confirming = true;
|
|
2727
|
-
return new Promise((
|
|
2726
|
+
return new Promise((resolve7) => {
|
|
2728
2727
|
let completed = false;
|
|
2729
2728
|
const cleanup = (answer) => {
|
|
2730
2729
|
if (completed) return;
|
|
@@ -2734,7 +2733,7 @@ var ToolExecutor = class {
|
|
|
2734
2733
|
rl.pause();
|
|
2735
2734
|
rlAny.output = savedOutput;
|
|
2736
2735
|
this.confirming = false;
|
|
2737
|
-
|
|
2736
|
+
resolve7(answer === "y");
|
|
2738
2737
|
};
|
|
2739
2738
|
const onLine = (line) => {
|
|
2740
2739
|
const trimmed = line.trim();
|
|
@@ -3983,7 +3982,7 @@ var runInteractiveTool = {
|
|
|
3983
3982
|
PYTHONDONTWRITEBYTECODE: "1"
|
|
3984
3983
|
};
|
|
3985
3984
|
const prefixWarnings = [argsTypeWarning, stdinTypeWarning].filter(Boolean).join("");
|
|
3986
|
-
return new Promise((
|
|
3985
|
+
return new Promise((resolve7) => {
|
|
3987
3986
|
const child = spawn3(executable, cmdArgs.map(String), {
|
|
3988
3987
|
cwd: process.cwd(),
|
|
3989
3988
|
env,
|
|
@@ -4016,22 +4015,22 @@ var runInteractiveTool = {
|
|
|
4016
4015
|
setTimeout(writeNextLine, 400);
|
|
4017
4016
|
const timer = setTimeout(() => {
|
|
4018
4017
|
child.kill();
|
|
4019
|
-
|
|
4018
|
+
resolve7(`${prefixWarnings}[Timeout after ${timeout}ms]
|
|
4020
4019
|
${buildOutput(stdout, stderr)}`);
|
|
4021
4020
|
}, timeout);
|
|
4022
4021
|
child.on("close", (code) => {
|
|
4023
4022
|
clearTimeout(timer);
|
|
4024
4023
|
const output = buildOutput(stdout, stderr);
|
|
4025
4024
|
if (code !== 0 && code !== null) {
|
|
4026
|
-
|
|
4025
|
+
resolve7(`${prefixWarnings}Exit code ${code}:
|
|
4027
4026
|
${output}`);
|
|
4028
4027
|
} else {
|
|
4029
|
-
|
|
4028
|
+
resolve7(`${prefixWarnings}${output || "(no output)"}`);
|
|
4030
4029
|
}
|
|
4031
4030
|
});
|
|
4032
4031
|
child.on("error", (err) => {
|
|
4033
4032
|
clearTimeout(timer);
|
|
4034
|
-
|
|
4033
|
+
resolve7(
|
|
4035
4034
|
`${prefixWarnings}Failed to start process "${executable}": ${err.message}
|
|
4036
4035
|
Hint: On Windows, use the full path to the executable, e.g.:
|
|
4037
4036
|
C:\\Users\\Jinzd\\anaconda3\\envs\\python312\\python.exe`
|
|
@@ -4743,188 +4742,10 @@ Any of these triggers means use save_last_response, NOT write_file:
|
|
|
4743
4742
|
};
|
|
4744
4743
|
|
|
4745
4744
|
// src/tools/builtin/save-memory.ts
|
|
4746
|
-
import { join as
|
|
4745
|
+
import { join as join5 } from "path";
|
|
4747
4746
|
import { homedir as homedir3 } from "os";
|
|
4748
|
-
|
|
4749
|
-
// src/memory/persistent-memory.ts
|
|
4750
|
-
import { existsSync as existsSync11, mkdirSync as mkdirSync3, readFileSync as readFileSync7 } from "fs";
|
|
4751
|
-
import { randomUUID, createHash } from "crypto";
|
|
4752
|
-
import { dirname as dirname5, join as join5, resolve as resolve6 } from "path";
|
|
4753
|
-
function memoryStorePath(configDir) {
|
|
4754
|
-
return join5(configDir, MEMORY_STORE_FILE_NAME);
|
|
4755
|
-
}
|
|
4756
|
-
function memoryMarkdownPath(configDir) {
|
|
4757
|
-
return join5(configDir, MEMORY_FILE_NAME);
|
|
4758
|
-
}
|
|
4759
|
-
function getProjectKey(cwd = process.cwd()) {
|
|
4760
|
-
return resolve6(getGitRoot(cwd) ?? cwd);
|
|
4761
|
-
}
|
|
4762
|
-
function nowIso() {
|
|
4763
|
-
return (/* @__PURE__ */ new Date()).toISOString();
|
|
4764
|
-
}
|
|
4765
|
-
function isValidScope(value) {
|
|
4766
|
-
return value === "personal" || value === "project" || value === "session" || value === "team";
|
|
4767
|
-
}
|
|
4768
|
-
function isValidSensitivity(value) {
|
|
4769
|
-
return value === "low" || value === "medium" || value === "high";
|
|
4770
|
-
}
|
|
4771
|
-
function normalizeEntry(value) {
|
|
4772
|
-
if (!value || typeof value !== "object") return null;
|
|
4773
|
-
const raw = value;
|
|
4774
|
-
const content = typeof raw.content === "string" ? raw.content.trim() : "";
|
|
4775
|
-
if (!content) return null;
|
|
4776
|
-
const createdAt = typeof raw.createdAt === "string" ? raw.createdAt : nowIso();
|
|
4777
|
-
return {
|
|
4778
|
-
id: typeof raw.id === "string" && raw.id ? raw.id : randomUUID(),
|
|
4779
|
-
content,
|
|
4780
|
-
scope: isValidScope(raw.scope) ? raw.scope : "personal",
|
|
4781
|
-
sourceSession: typeof raw.sourceSession === "string" && raw.sourceSession ? raw.sourceSession : void 0,
|
|
4782
|
-
sourceProject: typeof raw.sourceProject === "string" && raw.sourceProject ? raw.sourceProject : void 0,
|
|
4783
|
-
createdAt,
|
|
4784
|
-
updatedAt: typeof raw.updatedAt === "string" ? raw.updatedAt : createdAt,
|
|
4785
|
-
expiresAt: typeof raw.expiresAt === "string" && raw.expiresAt ? raw.expiresAt : void 0,
|
|
4786
|
-
sensitivity: isValidSensitivity(raw.sensitivity) ? raw.sensitivity : "low",
|
|
4787
|
-
approved: raw.approved === true,
|
|
4788
|
-
redactedKinds: Array.isArray(raw.redactedKinds) ? raw.redactedKinds.filter((x) => typeof x === "string") : void 0
|
|
4789
|
-
};
|
|
4790
|
-
}
|
|
4791
|
-
function legacyEntriesFromMarkdown(configDir) {
|
|
4792
|
-
const file = memoryMarkdownPath(configDir);
|
|
4793
|
-
if (!existsSync11(file)) return [];
|
|
4794
|
-
const content = readFileSync7(file, "utf-8").trim();
|
|
4795
|
-
if (!content) return [];
|
|
4796
|
-
const parts = content.split(/\n(?=##\s+\d{4}-\d{2}-\d{2})/g);
|
|
4797
|
-
const chunks = parts.length > 1 ? parts : [content];
|
|
4798
|
-
return chunks.map((chunk, index) => {
|
|
4799
|
-
const match = chunk.match(/^##\s+([^\n]+)\n([\s\S]*)$/);
|
|
4800
|
-
const body = (match ? match[2] : chunk).trim();
|
|
4801
|
-
const parsed = match ? Date.parse(match[1].replace(" ", "T")) : NaN;
|
|
4802
|
-
const createdAt = Number.isFinite(parsed) ? new Date(parsed).toISOString() : nowIso();
|
|
4803
|
-
const id = "legacy-" + createHash("sha1").update(`${index}
|
|
4804
|
-
${chunk}`).digest("hex").slice(0, 12);
|
|
4805
|
-
return normalizeEntry({ id, content: body, scope: "personal", createdAt, updatedAt: createdAt, sensitivity: "low", approved: true });
|
|
4806
|
-
}).filter((entry) => Boolean(entry));
|
|
4807
|
-
}
|
|
4808
|
-
function loadMemoryEntries(configDir) {
|
|
4809
|
-
const file = memoryStorePath(configDir);
|
|
4810
|
-
if (!existsSync11(file)) return legacyEntriesFromMarkdown(configDir);
|
|
4811
|
-
const text = readFileSync7(file, "utf-8").trim();
|
|
4812
|
-
if (!text) return [];
|
|
4813
|
-
const entries = [];
|
|
4814
|
-
for (const line of text.split("\n")) {
|
|
4815
|
-
const trimmed = line.trim();
|
|
4816
|
-
if (!trimmed) continue;
|
|
4817
|
-
try {
|
|
4818
|
-
const entry = normalizeEntry(JSON.parse(trimmed));
|
|
4819
|
-
if (entry) entries.push(entry);
|
|
4820
|
-
} catch {
|
|
4821
|
-
}
|
|
4822
|
-
}
|
|
4823
|
-
return entries;
|
|
4824
|
-
}
|
|
4825
|
-
function saveMemoryEntries(configDir, entries) {
|
|
4826
|
-
mkdirSync3(configDir, { recursive: true });
|
|
4827
|
-
const jsonl = entries.map((entry) => JSON.stringify(entry)).join("\n");
|
|
4828
|
-
atomicWriteFileSync(memoryStorePath(configDir), jsonl ? jsonl + "\n" : "");
|
|
4829
|
-
}
|
|
4830
|
-
function isMemoryExpired(entry, at = /* @__PURE__ */ new Date()) {
|
|
4831
|
-
return Boolean(entry.expiresAt && Date.parse(entry.expiresAt) <= at.getTime());
|
|
4832
|
-
}
|
|
4833
|
-
function isMemoryVisibleInProject(entry, cwd = process.cwd()) {
|
|
4834
|
-
if (entry.scope !== "project") return true;
|
|
4835
|
-
return entry.sourceProject === getProjectKey(cwd);
|
|
4836
|
-
}
|
|
4837
|
-
function listMemoryEntries(configDir, options = {}) {
|
|
4838
|
-
const cwd = options.cwd ?? process.cwd();
|
|
4839
|
-
return loadMemoryEntries(configDir).filter((entry) => options.includeRejected || entry.approved).filter((entry) => options.includeExpired || !isMemoryExpired(entry)).filter((entry) => isMemoryVisibleInProject(entry, cwd));
|
|
4840
|
-
}
|
|
4841
|
-
function addMemoryEntry(configDir, content, options = {}) {
|
|
4842
|
-
const original = content.trim();
|
|
4843
|
-
if (!original) throw new Error("memory content is required");
|
|
4844
|
-
const redact = options.redact ?? true;
|
|
4845
|
-
const redacted = redact ? redactString(original, { enabled: true, patterns: options.patterns ?? DEFAULT_PATTERNS, customRegexes: options.customPatterns }) : { redacted: original, hits: [] };
|
|
4846
|
-
const sensitivity = options.sensitivity ?? (redacted.hits.length > 0 ? "high" : "low");
|
|
4847
|
-
const approved = options.approved ?? (sensitivity === "low" && redacted.hits.length === 0);
|
|
4848
|
-
const scope = options.scope ?? "personal";
|
|
4849
|
-
const timestamp = nowIso();
|
|
4850
|
-
const entry = {
|
|
4851
|
-
id: randomUUID(),
|
|
4852
|
-
content: redacted.redacted.trim(),
|
|
4853
|
-
scope,
|
|
4854
|
-
sourceSession: options.sourceSession,
|
|
4855
|
-
sourceProject: scope === "project" ? getProjectKey(options.cwd) : void 0,
|
|
4856
|
-
createdAt: timestamp,
|
|
4857
|
-
updatedAt: timestamp,
|
|
4858
|
-
expiresAt: options.expiresAt,
|
|
4859
|
-
sensitivity,
|
|
4860
|
-
approved,
|
|
4861
|
-
redactedKinds: [...new Set(redacted.hits.map((hit) => hit.kind))]
|
|
4862
|
-
};
|
|
4863
|
-
const entries = loadMemoryEntries(configDir);
|
|
4864
|
-
entries.push(entry);
|
|
4865
|
-
saveMemoryEntries(configDir, entries);
|
|
4866
|
-
return entry;
|
|
4867
|
-
}
|
|
4868
|
-
function updateMemoryApproval(configDir, idPrefix, approved) {
|
|
4869
|
-
const entries = loadMemoryEntries(configDir);
|
|
4870
|
-
const entry = findUnique(entries, idPrefix);
|
|
4871
|
-
entry.approved = approved;
|
|
4872
|
-
entry.updatedAt = nowIso();
|
|
4873
|
-
saveMemoryEntries(configDir, entries);
|
|
4874
|
-
return entry;
|
|
4875
|
-
}
|
|
4876
|
-
function deleteMemoryEntry(configDir, idPrefix) {
|
|
4877
|
-
const entries = loadMemoryEntries(configDir);
|
|
4878
|
-
const entry = findUnique(entries, idPrefix);
|
|
4879
|
-
saveMemoryEntries(configDir, entries.filter((candidate) => candidate.id !== entry.id));
|
|
4880
|
-
return entry;
|
|
4881
|
-
}
|
|
4882
|
-
function expireMemoryEntry(configDir, idPrefix, expiresAt = nowIso()) {
|
|
4883
|
-
const entries = loadMemoryEntries(configDir);
|
|
4884
|
-
const entry = findUnique(entries, idPrefix);
|
|
4885
|
-
entry.expiresAt = expiresAt;
|
|
4886
|
-
entry.updatedAt = nowIso();
|
|
4887
|
-
saveMemoryEntries(configDir, entries);
|
|
4888
|
-
return entry;
|
|
4889
|
-
}
|
|
4890
|
-
function exportMemoryEntries(configDir, cwd = process.cwd()) {
|
|
4891
|
-
return JSON.stringify(listMemoryEntries(configDir, { cwd, includeExpired: true, includeRejected: true }), null, 2);
|
|
4892
|
-
}
|
|
4893
|
-
function findUnique(entries, idPrefix) {
|
|
4894
|
-
const matches = entries.filter((entry) => entry.id.startsWith(idPrefix));
|
|
4895
|
-
if (matches.length === 0) throw new Error(`memory id not found: ${idPrefix}`);
|
|
4896
|
-
if (matches.length > 1) throw new Error(`memory id is ambiguous: ${idPrefix}`);
|
|
4897
|
-
return matches[0];
|
|
4898
|
-
}
|
|
4899
|
-
function formatMemoryForPrompt(configDir, cwd = process.cwd()) {
|
|
4900
|
-
const entries = listMemoryEntries(configDir, { cwd }).filter((entry) => entry.approved && !isMemoryExpired(entry));
|
|
4901
|
-
if (entries.length === 0) return null;
|
|
4902
|
-
let content = entries.map((entry) => {
|
|
4903
|
-
const source = [
|
|
4904
|
-
`id ${entry.id.slice(0, 8)}`,
|
|
4905
|
-
`scope ${entry.scope}`,
|
|
4906
|
-
entry.sourceSession ? `source session ${entry.sourceSession.slice(0, 8)}` : "source manual/tool",
|
|
4907
|
-
entry.sourceProject ? `project ${entry.sourceProject}` : "",
|
|
4908
|
-
`sensitivity ${entry.sensitivity}`
|
|
4909
|
-
].filter(Boolean).join(" \xB7 ");
|
|
4910
|
-
return `## ${entry.createdAt.replace("T", " ").slice(0, 19)}
|
|
4911
|
-
Source: ${source}
|
|
4912
|
-
${entry.content}`;
|
|
4913
|
-
}).join("\n\n");
|
|
4914
|
-
if (content.length > MEMORY_MAX_CHARS) {
|
|
4915
|
-
content = content.slice(-MEMORY_MAX_CHARS);
|
|
4916
|
-
const firstEntry = content.indexOf("\n## ");
|
|
4917
|
-
if (firstEntry !== -1) content = content.slice(firstEntry + 1);
|
|
4918
|
-
}
|
|
4919
|
-
return { content, entryCount: entries.length };
|
|
4920
|
-
}
|
|
4921
|
-
|
|
4922
|
-
// src/tools/builtin/save-memory.ts
|
|
4923
4747
|
function getConfigDir() {
|
|
4924
|
-
return
|
|
4925
|
-
}
|
|
4926
|
-
function parseScope(value) {
|
|
4927
|
-
return value === "personal" || value === "project" || value === "session" || value === "team" ? value : void 0;
|
|
4748
|
+
return join5(homedir3(), CONFIG_DIR_NAME);
|
|
4928
4749
|
}
|
|
4929
4750
|
function parseSensitivity(value) {
|
|
4930
4751
|
return value === "low" || value === "medium" || value === "high" ? value : void 0;
|
|
@@ -4932,7 +4753,7 @@ function parseSensitivity(value) {
|
|
|
4932
4753
|
var saveMemoryTool = {
|
|
4933
4754
|
definition: {
|
|
4934
4755
|
name: "save_memory",
|
|
4935
|
-
description: "Save important information to governed persistent memory.
|
|
4756
|
+
description: "Save important information to governed persistent memory. Entries saved by this tool are stored as PENDING and only take effect after the user runs /memory approve <id> \u2014 tell the user the returned id so they can approve it. Use concise entries for user preferences, project decisions, recurring patterns, and key findings.",
|
|
4936
4757
|
parameters: {
|
|
4937
4758
|
content: {
|
|
4938
4759
|
type: "string",
|
|
@@ -4941,7 +4762,7 @@ var saveMemoryTool = {
|
|
|
4941
4762
|
},
|
|
4942
4763
|
scope: {
|
|
4943
4764
|
type: "string",
|
|
4944
|
-
description: "Memory scope: personal
|
|
4765
|
+
description: "Memory scope: personal (default, injected everywhere) or project (only injected inside the current project).",
|
|
4945
4766
|
required: false
|
|
4946
4767
|
},
|
|
4947
4768
|
sensitivity: {
|
|
@@ -4953,6 +4774,11 @@ var saveMemoryTool = {
|
|
|
4953
4774
|
type: "string",
|
|
4954
4775
|
description: "Optional ISO timestamp after which this memory should no longer be injected.",
|
|
4955
4776
|
required: false
|
|
4777
|
+
},
|
|
4778
|
+
updateId: {
|
|
4779
|
+
type: "string",
|
|
4780
|
+
description: "Optional id (or unique id prefix) of an existing memory entry to update in place instead of creating a new one. Use this when a previously saved memory is outdated \u2014 do not save a contradicting duplicate. Updated entries go back to pending and need user re-approval.",
|
|
4781
|
+
required: false
|
|
4956
4782
|
}
|
|
4957
4783
|
},
|
|
4958
4784
|
dangerous: false
|
|
@@ -4960,16 +4786,29 @@ var saveMemoryTool = {
|
|
|
4960
4786
|
async execute(args) {
|
|
4961
4787
|
const content = String(args["content"] ?? "").trim();
|
|
4962
4788
|
if (!content) throw new ToolError("save_memory", "content is required");
|
|
4789
|
+
const updateId = typeof args["updateId"] === "string" ? args["updateId"].trim() : "";
|
|
4790
|
+
if (updateId) {
|
|
4791
|
+
try {
|
|
4792
|
+
const updated = updateMemoryEntry(getConfigDir(), updateId, content, { source: "tool", redact: true });
|
|
4793
|
+
const redactedNote = updated.redactedKinds?.length ? ` Redacted: ${updated.redactedKinds.join(", ")}.` : "";
|
|
4794
|
+
return `Memory ${updated.id.slice(0, 8)} updated (pending approval \u2014 the user must run \`/memory approve ${updated.id.slice(0, 8)}\` before the new content is injected; mention this to the user). scope=${updated.scope} sensitivity=${updated.sensitivity}.${redactedNote}`;
|
|
4795
|
+
} catch (err) {
|
|
4796
|
+
throw new ToolError("save_memory", err instanceof Error ? err.message : String(err));
|
|
4797
|
+
}
|
|
4798
|
+
}
|
|
4799
|
+
const similar = findSimilarMemory(loadMemoryEntries(getConfigDir()), content);
|
|
4963
4800
|
const entry = addMemoryEntry(getConfigDir(), content, {
|
|
4964
|
-
scope:
|
|
4801
|
+
scope: parseWritableScope(args["scope"]) ?? "personal",
|
|
4802
|
+
source: "tool",
|
|
4965
4803
|
sensitivity: parseSensitivity(args["sensitivity"]),
|
|
4966
4804
|
expiresAt: typeof args["expiresAt"] === "string" ? args["expiresAt"] : void 0,
|
|
4967
4805
|
cwd: process.cwd(),
|
|
4968
4806
|
redact: true
|
|
4969
4807
|
});
|
|
4970
|
-
const status = entry.approved ? "approved and active" :
|
|
4808
|
+
const status = entry.approved ? "approved and active" : `pending approval \u2014 the user must run \`/memory approve ${entry.id.slice(0, 8)}\` before it is injected; mention this to the user`;
|
|
4971
4809
|
const redacted = entry.redactedKinds?.length ? ` Redacted: ${entry.redactedKinds.join(", ")}.` : "";
|
|
4972
|
-
|
|
4810
|
+
const similarNote = similar ? ` Warning: a similar entry already exists (id=${similar.id.slice(0, 8)}) \u2014 next time pass updateId to revise it instead of duplicating.` : "";
|
|
4811
|
+
return `Memory saved (${status}). id=${entry.id.slice(0, 8)} scope=${entry.scope} sensitivity=${entry.sensitivity}.${redacted}${similarNote}`;
|
|
4973
4812
|
}
|
|
4974
4813
|
};
|
|
4975
4814
|
|
|
@@ -5013,7 +4852,7 @@ function promptUser(rl, question) {
|
|
|
5013
4852
|
console.log();
|
|
5014
4853
|
console.log(chalk4.cyan("\u2753 ") + chalk4.bold(question));
|
|
5015
4854
|
process.stdout.write(chalk4.cyan("> "));
|
|
5016
|
-
return new Promise((
|
|
4855
|
+
return new Promise((resolve7) => {
|
|
5017
4856
|
let completed = false;
|
|
5018
4857
|
const cleanup = (answer) => {
|
|
5019
4858
|
if (completed) return;
|
|
@@ -5023,7 +4862,7 @@ function promptUser(rl, question) {
|
|
|
5023
4862
|
rl.pause();
|
|
5024
4863
|
rlAny.output = savedOutput;
|
|
5025
4864
|
askUserContext.prompting = false;
|
|
5026
|
-
|
|
4865
|
+
resolve7(answer);
|
|
5027
4866
|
};
|
|
5028
4867
|
const onLine = (line) => {
|
|
5029
4868
|
cleanup(line);
|
|
@@ -5255,8 +5094,8 @@ function formatResults2(query, data, _requested) {
|
|
|
5255
5094
|
}
|
|
5256
5095
|
|
|
5257
5096
|
// src/agents/agent-config.ts
|
|
5258
|
-
import { existsSync as
|
|
5259
|
-
import { join as
|
|
5097
|
+
import { existsSync as existsSync11, readdirSync as readdirSync6, readFileSync as readFileSync7 } from "fs";
|
|
5098
|
+
import { join as join6 } from "path";
|
|
5260
5099
|
import { homedir as homedir4 } from "os";
|
|
5261
5100
|
var READ_ONLY_TOOLS2 = /* @__PURE__ */ new Set([
|
|
5262
5101
|
"read_file",
|
|
@@ -5351,13 +5190,13 @@ function parseAgentConfig(raw, source, path3) {
|
|
|
5351
5190
|
return cfg;
|
|
5352
5191
|
}
|
|
5353
5192
|
function loadAgentDir(dir, source) {
|
|
5354
|
-
if (!
|
|
5193
|
+
if (!existsSync11(dir)) return [];
|
|
5355
5194
|
const out = [];
|
|
5356
5195
|
for (const file of readdirSync6(dir)) {
|
|
5357
5196
|
if (!file.endsWith(".json")) continue;
|
|
5358
|
-
const path3 =
|
|
5197
|
+
const path3 = join6(dir, file);
|
|
5359
5198
|
try {
|
|
5360
|
-
const parsed = JSON.parse(
|
|
5199
|
+
const parsed = JSON.parse(readFileSync7(path3, "utf-8"));
|
|
5361
5200
|
const cfg = parseAgentConfig(parsed, source, path3);
|
|
5362
5201
|
if (cfg) out.push(cfg);
|
|
5363
5202
|
} catch {
|
|
@@ -5367,8 +5206,8 @@ function loadAgentDir(dir, source) {
|
|
|
5367
5206
|
}
|
|
5368
5207
|
function getAgentDirs(configDir, cwd = process.cwd()) {
|
|
5369
5208
|
return {
|
|
5370
|
-
user:
|
|
5371
|
-
project:
|
|
5209
|
+
user: join6(configDir ?? join6(homedir4(), CONFIG_DIR_NAME), "agents"),
|
|
5210
|
+
project: join6(cwd, CONFIG_DIR_NAME, "agents")
|
|
5372
5211
|
};
|
|
5373
5212
|
}
|
|
5374
5213
|
function listAgentConfigs(configDir, cwd = process.cwd()) {
|
|
@@ -5415,7 +5254,7 @@ var nextId = 1;
|
|
|
5415
5254
|
var preferredAgentName = "worker";
|
|
5416
5255
|
var runs = [];
|
|
5417
5256
|
var MAX_RUNS = 50;
|
|
5418
|
-
function
|
|
5257
|
+
function nowIso() {
|
|
5419
5258
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
5420
5259
|
}
|
|
5421
5260
|
function startAgentRun(input) {
|
|
@@ -5424,7 +5263,7 @@ function startAgentRun(input) {
|
|
|
5424
5263
|
agentName: input.agentName,
|
|
5425
5264
|
task: input.task,
|
|
5426
5265
|
status: "running",
|
|
5427
|
-
startedAt:
|
|
5266
|
+
startedAt: nowIso(),
|
|
5428
5267
|
toolNames: [],
|
|
5429
5268
|
agentIndex: input.agentIndex,
|
|
5430
5269
|
stopRequested: false
|
|
@@ -5442,7 +5281,7 @@ function finishAgentRun(runId, status, summary, error) {
|
|
|
5442
5281
|
const run = runs.find((r) => r.id === runId);
|
|
5443
5282
|
if (!run) return;
|
|
5444
5283
|
run.status = status;
|
|
5445
|
-
run.finishedAt =
|
|
5284
|
+
run.finishedAt = nowIso();
|
|
5446
5285
|
if (summary) run.summary = summary;
|
|
5447
5286
|
if (error) run.error = error;
|
|
5448
5287
|
}
|
|
@@ -5868,7 +5707,7 @@ var spawnAgentTool = {
|
|
|
5868
5707
|
|
|
5869
5708
|
// src/tools/builtin/task-manager.ts
|
|
5870
5709
|
import { spawn as spawn4 } from "child_process";
|
|
5871
|
-
import { randomUUID
|
|
5710
|
+
import { randomUUID } from "crypto";
|
|
5872
5711
|
import { platform as platform5 } from "os";
|
|
5873
5712
|
var MAX_OUTPUT_CHARS = 1e4;
|
|
5874
5713
|
var MAX_OUTPUT_BYTES = 64 * 1024;
|
|
@@ -5901,7 +5740,7 @@ function createTask(command, description) {
|
|
|
5901
5740
|
}
|
|
5902
5741
|
}
|
|
5903
5742
|
}
|
|
5904
|
-
const id =
|
|
5743
|
+
const id = randomUUID().slice(0, 8);
|
|
5905
5744
|
const { shell, args } = shellInvocation(command);
|
|
5906
5745
|
const proc = spawn4(shell, args, {
|
|
5907
5746
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -6083,14 +5922,14 @@ var taskStopTool = {
|
|
|
6083
5922
|
|
|
6084
5923
|
// src/tools/builtin/git-tools.ts
|
|
6085
5924
|
import { execFileSync as execFileSync2 } from "child_process";
|
|
6086
|
-
import { existsSync as
|
|
6087
|
-
import { join as
|
|
5925
|
+
import { existsSync as existsSync12 } from "fs";
|
|
5926
|
+
import { join as join7 } from "path";
|
|
6088
5927
|
function assertGitRepo(cwd) {
|
|
6089
5928
|
let dir = cwd;
|
|
6090
5929
|
const root = dir.split(/[\\/]/)[0] + (dir.includes("\\") ? "\\" : "/");
|
|
6091
5930
|
while (dir && dir !== root) {
|
|
6092
|
-
if (
|
|
6093
|
-
const parent =
|
|
5931
|
+
if (existsSync12(join7(dir, ".git"))) return;
|
|
5932
|
+
const parent = join7(dir, "..");
|
|
6094
5933
|
if (parent === dir) break;
|
|
6095
5934
|
dir = parent;
|
|
6096
5935
|
}
|
|
@@ -6355,9 +6194,9 @@ ${commitOutput.trim()}`;
|
|
|
6355
6194
|
};
|
|
6356
6195
|
|
|
6357
6196
|
// src/tools/builtin/notebook-edit.ts
|
|
6358
|
-
import { readFileSync as
|
|
6197
|
+
import { readFileSync as readFileSync8, existsSync as existsSync13 } from "fs";
|
|
6359
6198
|
import { writeFile } from "fs/promises";
|
|
6360
|
-
import { resolve as
|
|
6199
|
+
import { resolve as resolve6, extname as extname2 } from "path";
|
|
6361
6200
|
var notebookEditTool = {
|
|
6362
6201
|
definition: {
|
|
6363
6202
|
name: "notebook_edit",
|
|
@@ -6406,14 +6245,14 @@ var notebookEditTool = {
|
|
|
6406
6245
|
if (!Number.isInteger(cellIndexRaw) || cellIndexRaw < 1) {
|
|
6407
6246
|
throw new ToolError("notebook_edit", "cell_index must be a positive integer (1-based)");
|
|
6408
6247
|
}
|
|
6409
|
-
const absPath =
|
|
6248
|
+
const absPath = resolve6(filePath);
|
|
6410
6249
|
if (extname2(absPath).toLowerCase() !== ".ipynb") {
|
|
6411
6250
|
throw new ToolError("notebook_edit", "path must point to a .ipynb file");
|
|
6412
6251
|
}
|
|
6413
|
-
if (!
|
|
6252
|
+
if (!existsSync13(absPath)) {
|
|
6414
6253
|
throw new ToolError("notebook_edit", `Notebook not found: ${filePath}`);
|
|
6415
6254
|
}
|
|
6416
|
-
const raw =
|
|
6255
|
+
const raw = readFileSync8(absPath, "utf-8");
|
|
6417
6256
|
const nb = parseNotebook(raw);
|
|
6418
6257
|
const cellIdx0 = cellIndexRaw - 1;
|
|
6419
6258
|
undoStack.push(absPath, `notebook_edit (${action}): ${filePath}`);
|
|
@@ -6739,6 +6578,8 @@ ${lines.join("\n")}`;
|
|
|
6739
6578
|
};
|
|
6740
6579
|
|
|
6741
6580
|
// src/tools/builtin/recall-memory.ts
|
|
6581
|
+
import { join as join8 } from "path";
|
|
6582
|
+
import { homedir as homedir5 } from "os";
|
|
6742
6583
|
function formatHit(h, i) {
|
|
6743
6584
|
const ts = h.chunk.timestamp.slice(0, 16).replace("T", " ");
|
|
6744
6585
|
const title = h.chunk.sessionTitle ? ` \xB7 ${h.chunk.sessionTitle}` : "";
|
|
@@ -6751,7 +6592,7 @@ function formatHit(h, i) {
|
|
|
6751
6592
|
var recallMemoryTool = {
|
|
6752
6593
|
definition: {
|
|
6753
6594
|
name: "recall_memory",
|
|
6754
|
-
description: '
|
|
6595
|
+
description: 'Search long-term memory: governed persistent memory entries (keyword match) plus semantic search over past chat sessions. Call this whenever the user references something that may have been discussed before ("last time", "remember", "\u4E4B\u524D", "\u4E0A\u6B21"), when context is ambiguous and continuity matters, or when you want to check what decisions or preferences have been established across prior conversations \u2014 including memories that were dropped from the injected system prompt by the size budget. Returns persistent-memory hits first, then up to `topK` chat snippets with session id, timestamp, and cosine similarity score. Prefer this over asking the user "can you remind me".',
|
|
6755
6596
|
parameters: {
|
|
6756
6597
|
query: {
|
|
6757
6598
|
type: "string",
|
|
@@ -6788,9 +6629,21 @@ var recallMemoryTool = {
|
|
|
6788
6629
|
const excludeCurrent = Boolean(args["excludeCurrentSession"]);
|
|
6789
6630
|
const currentId = args["currentSessionId"] ? String(args["currentSessionId"]) : void 0;
|
|
6790
6631
|
const minScore = args["minScore"] !== void 0 ? Number(args["minScore"]) : 0.25;
|
|
6632
|
+
const configDir = join8(homedir5(), CONFIG_DIR_NAME);
|
|
6633
|
+
let persistentSection = "";
|
|
6634
|
+
try {
|
|
6635
|
+
const persistentHits = searchPersistentMemories(configDir, query, process.cwd(), 3);
|
|
6636
|
+
if (persistentHits.length > 0) {
|
|
6637
|
+
touchMemoryReferences(configDir, persistentHits.map((h) => h.entry.id));
|
|
6638
|
+
persistentSection = `\u2500\u2500 Persistent memory (${persistentHits.length} hit(s)) \u2500\u2500
|
|
6639
|
+
` + persistentHits.map((h) => `[id ${h.entry.id.slice(0, 8)} \xB7 ${h.entry.scope} \xB7 coverage ${h.score.toFixed(2)}]
|
|
6640
|
+
${h.entry.content}`).join("\n\n") + "\n\n";
|
|
6641
|
+
}
|
|
6642
|
+
} catch {
|
|
6643
|
+
}
|
|
6791
6644
|
const status = loadChatIndex();
|
|
6792
6645
|
if (!status) {
|
|
6793
|
-
return "No chat memory index found. The index is built on REPL startup, or run `/memory rebuild` manually. If you have no past sessions yet, this is expected.";
|
|
6646
|
+
return persistentSection + "No chat memory index found. The index is built on REPL startup, or run `/memory rebuild` manually. If you have no past sessions yet, this is expected.";
|
|
6794
6647
|
}
|
|
6795
6648
|
const hits = await searchChatMemory(query, {
|
|
6796
6649
|
topK,
|
|
@@ -6798,11 +6651,11 @@ var recallMemoryTool = {
|
|
|
6798
6651
|
excludeSessionId: excludeCurrent ? currentId : void 0
|
|
6799
6652
|
});
|
|
6800
6653
|
if (hits.length === 0) {
|
|
6801
|
-
return `No memories matched "${query}" above score ${minScore}. Index has ${status.idx.chunks.length} chunks across ${Object.keys(status.idx.sessionMtimes).length} sessions. Consider lowering minScore to 0.15 or rephrasing the query.`;
|
|
6654
|
+
return persistentSection + `No chat-history memories matched "${query}" above score ${minScore}. Index has ${status.idx.chunks.length} chunks across ${Object.keys(status.idx.sessionMtimes).length} sessions. Consider lowering minScore to 0.15 or rephrasing the query.`;
|
|
6802
6655
|
}
|
|
6803
|
-
const header = `Found ${hits.length}
|
|
6656
|
+
const header = `Found ${hits.length} chat-history hit(s) for "${query}" (min-score ${minScore}):
|
|
6804
6657
|
`;
|
|
6805
|
-
return header + "\n" + hits.map(formatHit).join("\n\n");
|
|
6658
|
+
return persistentSection + header + "\n" + hits.map(formatHit).join("\n\n");
|
|
6806
6659
|
}
|
|
6807
6660
|
};
|
|
6808
6661
|
|
|
@@ -6830,7 +6683,7 @@ function estimateToolDefinitionTokens(def) {
|
|
|
6830
6683
|
|
|
6831
6684
|
// src/tools/registry.ts
|
|
6832
6685
|
import { pathToFileURL } from "url";
|
|
6833
|
-
import { existsSync as
|
|
6686
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync3, readdirSync as readdirSync7 } from "fs";
|
|
6834
6687
|
import { join as join9 } from "path";
|
|
6835
6688
|
var ToolRegistry = class {
|
|
6836
6689
|
tools = /* @__PURE__ */ new Map();
|
|
@@ -6992,9 +6845,9 @@ var ToolRegistry = class {
|
|
|
6992
6845
|
* Returns the number of successfully loaded plugins.
|
|
6993
6846
|
*/
|
|
6994
6847
|
async loadPlugins(pluginsDir, allowPlugins = false) {
|
|
6995
|
-
if (!
|
|
6848
|
+
if (!existsSync14(pluginsDir)) {
|
|
6996
6849
|
try {
|
|
6997
|
-
|
|
6850
|
+
mkdirSync3(pluginsDir, { recursive: true });
|
|
6998
6851
|
} catch {
|
|
6999
6852
|
}
|
|
7000
6853
|
return 0;
|
|
@@ -7056,16 +6909,6 @@ export {
|
|
|
7056
6909
|
theme,
|
|
7057
6910
|
undoStack,
|
|
7058
6911
|
renderDiff,
|
|
7059
|
-
memoryStorePath,
|
|
7060
|
-
memoryMarkdownPath,
|
|
7061
|
-
isMemoryExpired,
|
|
7062
|
-
listMemoryEntries,
|
|
7063
|
-
addMemoryEntry,
|
|
7064
|
-
updateMemoryApproval,
|
|
7065
|
-
deleteMemoryEntry,
|
|
7066
|
-
expireMemoryEntry,
|
|
7067
|
-
exportMemoryEntries,
|
|
7068
|
-
formatMemoryForPrompt,
|
|
7069
6912
|
recordRecentlyDeniedAutoAction,
|
|
7070
6913
|
getRecentlyDeniedAutoActions,
|
|
7071
6914
|
clearRecentlyDeniedAutoActions,
|
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
import {
|
|
3
3
|
listFromIndex,
|
|
4
4
|
readSessionMeta,
|
|
5
|
-
redactJson,
|
|
6
5
|
removeSessionFromIndex,
|
|
7
6
|
safeDate,
|
|
8
7
|
searchCandidates,
|
|
9
8
|
updateSessionInIndex
|
|
10
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-PJ3ONBWZ.js";
|
|
10
|
+
import {
|
|
11
|
+
redactJson
|
|
12
|
+
} from "./chunk-B5TYJO7V.js";
|
|
11
13
|
import {
|
|
12
14
|
atomicWriteFileSync
|
|
13
15
|
} from "./chunk-IW3Q7AE5.js";
|