chron-mcp 0.1.28 → 0.1.29
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/cli/index.js +117 -6
- package/dist/index.js +121 -9
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -16615,6 +16615,14 @@ async function initDb(dbPath3) {
|
|
|
16615
16615
|
if (!sessCols.includes("metadata")) {
|
|
16616
16616
|
await client.execute("ALTER TABLE sessions ADD COLUMN metadata TEXT");
|
|
16617
16617
|
}
|
|
16618
|
+
const ftsCount = await client.execute("SELECT count(*) as n FROM messages_fts");
|
|
16619
|
+
const msgCount = await client.execute("SELECT count(*) as n FROM messages");
|
|
16620
|
+
if (Number(ftsCount.rows[0][0]) < Number(msgCount.rows[0][0])) {
|
|
16621
|
+
await client.execute("DELETE FROM messages_fts");
|
|
16622
|
+
await client.execute(
|
|
16623
|
+
"INSERT INTO messages_fts(rowid, content, session_id) SELECT rowid, content, session_id FROM messages"
|
|
16624
|
+
);
|
|
16625
|
+
}
|
|
16618
16626
|
return drizzle(client, { schema: schema_exports });
|
|
16619
16627
|
}
|
|
16620
16628
|
var import_os, import_fs, import_path, CREATE_SQL;
|
|
@@ -16664,11 +16672,81 @@ var init_db2 = __esm({
|
|
|
16664
16672
|
`CREATE UNIQUE INDEX IF NOT EXISTS idx_sessions_title ON sessions(title)`,
|
|
16665
16673
|
`CREATE INDEX IF NOT EXISTS idx_messages_session_id ON messages(session_id)`,
|
|
16666
16674
|
`CREATE INDEX IF NOT EXISTS idx_secrets_detected_session_id ON secrets_detected(session_id)`,
|
|
16667
|
-
`CREATE INDEX IF NOT EXISTS idx_secrets_detected_message_id ON secrets_detected(message_id)
|
|
16675
|
+
`CREATE INDEX IF NOT EXISTS idx_secrets_detected_message_id ON secrets_detected(message_id)`,
|
|
16676
|
+
`CREATE VIRTUAL TABLE IF NOT EXISTS messages_fts USING fts5(
|
|
16677
|
+
content,
|
|
16678
|
+
session_id UNINDEXED,
|
|
16679
|
+
tokenize = 'porter unicode61'
|
|
16680
|
+
)`,
|
|
16681
|
+
`CREATE TRIGGER IF NOT EXISTS messages_fts_ai
|
|
16682
|
+
AFTER INSERT ON messages BEGIN
|
|
16683
|
+
INSERT INTO messages_fts(rowid, content, session_id)
|
|
16684
|
+
VALUES (new.rowid, new.content, new.session_id);
|
|
16685
|
+
END`,
|
|
16686
|
+
`CREATE TRIGGER IF NOT EXISTS messages_fts_ad
|
|
16687
|
+
AFTER DELETE ON messages BEGIN
|
|
16688
|
+
DELETE FROM messages_fts WHERE rowid = old.rowid;
|
|
16689
|
+
END`
|
|
16668
16690
|
];
|
|
16669
16691
|
}
|
|
16670
16692
|
});
|
|
16671
16693
|
|
|
16694
|
+
// src/tools/search.ts
|
|
16695
|
+
async function runSearch(db, query, limit = 10) {
|
|
16696
|
+
const client = db.$client;
|
|
16697
|
+
let rows;
|
|
16698
|
+
try {
|
|
16699
|
+
const result = await client.execute({
|
|
16700
|
+
sql: `
|
|
16701
|
+
SELECT
|
|
16702
|
+
messages_fts.session_id AS session_id,
|
|
16703
|
+
snippet(messages_fts, 0, '>>>', '<<<', '\u2026', 24) AS excerpt,
|
|
16704
|
+
s.title AS title,
|
|
16705
|
+
s.ai_tool AS ai_tool,
|
|
16706
|
+
s.updated_at AS updated_at
|
|
16707
|
+
FROM messages_fts
|
|
16708
|
+
JOIN sessions s ON s.id = messages_fts.session_id
|
|
16709
|
+
WHERE messages_fts MATCH ?
|
|
16710
|
+
ORDER BY rank
|
|
16711
|
+
LIMIT ?
|
|
16712
|
+
`,
|
|
16713
|
+
args: [query, limit * 5]
|
|
16714
|
+
// over-fetch so we can group into limit distinct sessions
|
|
16715
|
+
});
|
|
16716
|
+
rows = result.rows;
|
|
16717
|
+
} catch {
|
|
16718
|
+
return [];
|
|
16719
|
+
}
|
|
16720
|
+
const map = /* @__PURE__ */ new Map();
|
|
16721
|
+
for (const r of rows) {
|
|
16722
|
+
const sid = String(r.session_id ?? "");
|
|
16723
|
+
if (!sid)
|
|
16724
|
+
continue;
|
|
16725
|
+
if (!map.has(sid)) {
|
|
16726
|
+
map.set(sid, {
|
|
16727
|
+
session_id: sid,
|
|
16728
|
+
title: String(r.title ?? ""),
|
|
16729
|
+
ai_tool: r.ai_tool != null ? String(r.ai_tool) : null,
|
|
16730
|
+
updated_at: String(r.updated_at ?? ""),
|
|
16731
|
+
match_count: 0,
|
|
16732
|
+
excerpts: []
|
|
16733
|
+
});
|
|
16734
|
+
}
|
|
16735
|
+
const entry = map.get(sid);
|
|
16736
|
+
entry.match_count++;
|
|
16737
|
+
if (entry.excerpts.length < 3)
|
|
16738
|
+
entry.excerpts.push(String(r.excerpt ?? ""));
|
|
16739
|
+
if (map.size >= limit && entry.match_count > 1)
|
|
16740
|
+
break;
|
|
16741
|
+
}
|
|
16742
|
+
return Array.from(map.values()).slice(0, limit);
|
|
16743
|
+
}
|
|
16744
|
+
var init_search = __esm({
|
|
16745
|
+
"src/tools/search.ts"() {
|
|
16746
|
+
"use strict";
|
|
16747
|
+
}
|
|
16748
|
+
});
|
|
16749
|
+
|
|
16672
16750
|
// src/cli/history.ts
|
|
16673
16751
|
var history_exports = {};
|
|
16674
16752
|
__export(history_exports, {
|
|
@@ -16788,12 +16866,43 @@ ${msg.content}
|
|
|
16788
16866
|
}
|
|
16789
16867
|
}
|
|
16790
16868
|
}
|
|
16869
|
+
async function printSearch(query, limit) {
|
|
16870
|
+
const db = await initDb();
|
|
16871
|
+
const results = await runSearch(db, query, limit);
|
|
16872
|
+
if (results.length === 0) {
|
|
16873
|
+
process.stdout.write(`No sessions match: ${query}
|
|
16874
|
+
`);
|
|
16875
|
+
return;
|
|
16876
|
+
}
|
|
16877
|
+
process.stdout.write(`
|
|
16878
|
+
${BOLD}Search: ${query}${RESET} ${DIM}(${results.length} session${results.length === 1 ? "" : "s"})${RESET}
|
|
16879
|
+
|
|
16880
|
+
`);
|
|
16881
|
+
for (const r of results) {
|
|
16882
|
+
const date = fmtDate(r.updated_at);
|
|
16883
|
+
const prefix = r.session_id.slice(0, 8);
|
|
16884
|
+
const hits = `${r.match_count} hit${r.match_count === 1 ? "" : "s"}`;
|
|
16885
|
+
process.stdout.write(
|
|
16886
|
+
` ${DIM}${date}${RESET} ${CYAN}${prefix}${RESET} ${BOLD}${hits}${RESET} ${r.title}
|
|
16887
|
+
`
|
|
16888
|
+
);
|
|
16889
|
+
for (const excerpt of r.excerpts) {
|
|
16890
|
+
const highlighted = excerpt.replace(/>>>/g, YELLOW).replace(/<<</g, RESET);
|
|
16891
|
+
process.stdout.write(` ${DIM}\u2026${RESET} ${highlighted}
|
|
16892
|
+
`);
|
|
16893
|
+
}
|
|
16894
|
+
process.stdout.write("\n");
|
|
16895
|
+
}
|
|
16896
|
+
}
|
|
16791
16897
|
async function runHistory(args2) {
|
|
16792
16898
|
const limitArg = args2.find((a) => a.startsWith("--limit="));
|
|
16793
16899
|
const limit = limitArg ? parseInt(limitArg.split("=")[1], 10) : 20;
|
|
16794
16900
|
const refArg = args2.find((a) => a.startsWith("--ref="))?.split("=").slice(1).join("=");
|
|
16901
|
+
const searchArg = args2.find((a) => a.startsWith("--search="))?.split("=").slice(1).join("=");
|
|
16795
16902
|
const positional = args2.filter((a) => !a.startsWith("--"));
|
|
16796
|
-
if (
|
|
16903
|
+
if (searchArg) {
|
|
16904
|
+
await printSearch(searchArg, limit);
|
|
16905
|
+
} else if (positional.length === 0) {
|
|
16797
16906
|
await printList(limit, refArg);
|
|
16798
16907
|
} else {
|
|
16799
16908
|
await printDetail(positional[0]);
|
|
@@ -16806,6 +16915,7 @@ var init_history = __esm({
|
|
|
16806
16915
|
init_drizzle_orm();
|
|
16807
16916
|
init_db2();
|
|
16808
16917
|
init_schema();
|
|
16918
|
+
init_search();
|
|
16809
16919
|
RESET = "\x1B[0m";
|
|
16810
16920
|
BOLD = "\x1B[1m";
|
|
16811
16921
|
DIM = "\x1B[2m";
|
|
@@ -17376,7 +17486,7 @@ var require_package = __commonJS({
|
|
|
17376
17486
|
"package.json"(exports2, module2) {
|
|
17377
17487
|
module2.exports = {
|
|
17378
17488
|
name: "chron-mcp",
|
|
17379
|
-
version: "0.1.
|
|
17489
|
+
version: "0.1.29",
|
|
17380
17490
|
mcpName: "io.github.sirinivask/chron",
|
|
17381
17491
|
description: "Audit-grade timestamped logs for every AI conversation",
|
|
17382
17492
|
repository: {
|
|
@@ -19986,9 +20096,10 @@ Commands:
|
|
|
19986
20096
|
import Import conversations from external AI tools
|
|
19987
20097
|
|
|
19988
20098
|
Options (history):
|
|
19989
|
-
--limit=<n>
|
|
19990
|
-
--
|
|
19991
|
-
|
|
20099
|
+
--limit=<n> Max sessions to show (default: 20)
|
|
20100
|
+
--search=<query> Full-text search across all sessions (FTS5: phrases, boolean, prefix*)
|
|
20101
|
+
--ref=<value> Filter by external_ref prefix
|
|
20102
|
+
<id-prefix> Show full log for the session with this ID prefix
|
|
19992
20103
|
|
|
19993
20104
|
Options (report):
|
|
19994
20105
|
--since=<range> Filter by date: 7d, 30d, or YYYY-MM-DD (default: all time)
|
package/dist/index.js
CHANGED
|
@@ -22825,6 +22825,14 @@ async function initDb(dbPath) {
|
|
|
22825
22825
|
if (!sessCols.includes("metadata")) {
|
|
22826
22826
|
await client.execute("ALTER TABLE sessions ADD COLUMN metadata TEXT");
|
|
22827
22827
|
}
|
|
22828
|
+
const ftsCount = await client.execute("SELECT count(*) as n FROM messages_fts");
|
|
22829
|
+
const msgCount = await client.execute("SELECT count(*) as n FROM messages");
|
|
22830
|
+
if (Number(ftsCount.rows[0][0]) < Number(msgCount.rows[0][0])) {
|
|
22831
|
+
await client.execute("DELETE FROM messages_fts");
|
|
22832
|
+
await client.execute(
|
|
22833
|
+
"INSERT INTO messages_fts(rowid, content, session_id) SELECT rowid, content, session_id FROM messages"
|
|
22834
|
+
);
|
|
22835
|
+
}
|
|
22828
22836
|
return drizzle(client, { schema: schema_exports });
|
|
22829
22837
|
}
|
|
22830
22838
|
var import_os, import_fs, import_path, CREATE_SQL;
|
|
@@ -22874,7 +22882,21 @@ var init_db2 = __esm({
|
|
|
22874
22882
|
`CREATE UNIQUE INDEX IF NOT EXISTS idx_sessions_title ON sessions(title)`,
|
|
22875
22883
|
`CREATE INDEX IF NOT EXISTS idx_messages_session_id ON messages(session_id)`,
|
|
22876
22884
|
`CREATE INDEX IF NOT EXISTS idx_secrets_detected_session_id ON secrets_detected(session_id)`,
|
|
22877
|
-
`CREATE INDEX IF NOT EXISTS idx_secrets_detected_message_id ON secrets_detected(message_id)
|
|
22885
|
+
`CREATE INDEX IF NOT EXISTS idx_secrets_detected_message_id ON secrets_detected(message_id)`,
|
|
22886
|
+
`CREATE VIRTUAL TABLE IF NOT EXISTS messages_fts USING fts5(
|
|
22887
|
+
content,
|
|
22888
|
+
session_id UNINDEXED,
|
|
22889
|
+
tokenize = 'porter unicode61'
|
|
22890
|
+
)`,
|
|
22891
|
+
`CREATE TRIGGER IF NOT EXISTS messages_fts_ai
|
|
22892
|
+
AFTER INSERT ON messages BEGIN
|
|
22893
|
+
INSERT INTO messages_fts(rowid, content, session_id)
|
|
22894
|
+
VALUES (new.rowid, new.content, new.session_id);
|
|
22895
|
+
END`,
|
|
22896
|
+
`CREATE TRIGGER IF NOT EXISTS messages_fts_ad
|
|
22897
|
+
AFTER DELETE ON messages BEGIN
|
|
22898
|
+
DELETE FROM messages_fts WHERE rowid = old.rowid;
|
|
22899
|
+
END`
|
|
22878
22900
|
];
|
|
22879
22901
|
}
|
|
22880
22902
|
});
|
|
@@ -38480,7 +38502,7 @@ var init_time = __esm({
|
|
|
38480
38502
|
var version4;
|
|
38481
38503
|
var init_package = __esm({
|
|
38482
38504
|
"package.json"() {
|
|
38483
|
-
version4 = "0.1.
|
|
38505
|
+
version4 = "0.1.29";
|
|
38484
38506
|
}
|
|
38485
38507
|
});
|
|
38486
38508
|
|
|
@@ -38839,9 +38861,22 @@ var init_ntp = __esm({
|
|
|
38839
38861
|
});
|
|
38840
38862
|
|
|
38841
38863
|
// src/utils/terminal.ts
|
|
38842
|
-
function
|
|
38843
|
-
const
|
|
38844
|
-
if (
|
|
38864
|
+
function resolvedLevel() {
|
|
38865
|
+
const raw = (process.env.CHRON_LOG_LEVEL ?? "").toLowerCase();
|
|
38866
|
+
if (raw === "off" || raw === "false" || raw === "0")
|
|
38867
|
+
return "off";
|
|
38868
|
+
if (raw === "summary")
|
|
38869
|
+
return "summary";
|
|
38870
|
+
const legacy = process.env.CHRON_TERMINAL_AUDIT;
|
|
38871
|
+
if (legacy && DISABLE_VALUES.has(legacy.toLowerCase()))
|
|
38872
|
+
return "off";
|
|
38873
|
+
return "verbose";
|
|
38874
|
+
}
|
|
38875
|
+
function terminalAudit(message, level = "message") {
|
|
38876
|
+
const mode = resolvedLevel();
|
|
38877
|
+
if (mode === "off")
|
|
38878
|
+
return;
|
|
38879
|
+
if (mode === "summary" && level === "message")
|
|
38845
38880
|
return;
|
|
38846
38881
|
process.stderr.write(`[chron] ${message}
|
|
38847
38882
|
`);
|
|
@@ -38893,7 +38928,7 @@ function startSession(db) {
|
|
|
38893
38928
|
});
|
|
38894
38929
|
attachNtpMetadata(db, id);
|
|
38895
38930
|
emitEvent({ event_type: "session_started", timestamp: now, session: { id_prefix: id.slice(0, 8), ai_tool: args.ai_tool ?? null } });
|
|
38896
|
-
terminalAudit(`session ${id.slice(0, 8)} started at ${now} (${args.ai_tool ?? "unknown"}: ${args.title})
|
|
38931
|
+
terminalAudit(`session ${id.slice(0, 8)} started at ${now} (${args.ai_tool ?? "unknown"}: ${args.title})`, "session");
|
|
38897
38932
|
return {
|
|
38898
38933
|
content: [{
|
|
38899
38934
|
type: "text",
|
|
@@ -38909,7 +38944,7 @@ function startSession(db) {
|
|
|
38909
38944
|
const [countRow] = await db.select({ count: sql`count(*)` }).from(messages).where(eq(messages.session_id, session.id));
|
|
38910
38945
|
await db.update(sessions).set({ updated_at: now }).where(eq(sessions.id, session.id));
|
|
38911
38946
|
emitEvent({ event_type: "session_started", timestamp: now, session: { id_prefix: session.id.slice(0, 8), ai_tool: session.ai_tool } });
|
|
38912
|
-
terminalAudit(`session ${session.id.slice(0, 8)} resumed at ${now} (${session.ai_tool ?? "unknown"}: ${session.title})
|
|
38947
|
+
terminalAudit(`session ${session.id.slice(0, 8)} resumed at ${now} (${session.ai_tool ?? "unknown"}: ${session.title})`, "session");
|
|
38913
38948
|
return {
|
|
38914
38949
|
content: [{
|
|
38915
38950
|
type: "text",
|
|
@@ -38946,7 +38981,7 @@ function initSession(db) {
|
|
|
38946
38981
|
created = true;
|
|
38947
38982
|
ai_tool = args.ai_tool ?? null;
|
|
38948
38983
|
attachNtpMetadata(db, id);
|
|
38949
|
-
terminalAudit(`session ${id.slice(0, 8)} started at ${now} (${ai_tool ?? "unknown"}: ${args.title})
|
|
38984
|
+
terminalAudit(`session ${id.slice(0, 8)} started at ${now} (${ai_tool ?? "unknown"}: ${args.title})`, "session");
|
|
38950
38985
|
} catch (e) {
|
|
38951
38986
|
const isUnique = e?.message?.includes("UNIQUE constraint failed") || e?.code === "SQLITE_CONSTRAINT_UNIQUE" || e?.cause?.message?.includes("UNIQUE constraint failed") || e?.cause?.extendedCode === "SQLITE_CONSTRAINT_UNIQUE";
|
|
38952
38987
|
if (!isUnique)
|
|
@@ -38957,7 +38992,7 @@ function initSession(db) {
|
|
|
38957
38992
|
session_id = session.id;
|
|
38958
38993
|
created = false;
|
|
38959
38994
|
ai_tool = session.ai_tool;
|
|
38960
|
-
terminalAudit(`session ${session.id.slice(0, 8)} resumed at ${now} (${ai_tool ?? "unknown"}: ${session.title})
|
|
38995
|
+
terminalAudit(`session ${session.id.slice(0, 8)} resumed at ${now} (${ai_tool ?? "unknown"}: ${session.title})`, "session");
|
|
38961
38996
|
}
|
|
38962
38997
|
emitEvent({ event_type: "session_started", timestamp: now, session: { id_prefix: session_id.slice(0, 8), ai_tool } });
|
|
38963
38998
|
const limit = args.limit ?? 10;
|
|
@@ -39872,6 +39907,73 @@ var init_summary2 = __esm({
|
|
|
39872
39907
|
}
|
|
39873
39908
|
});
|
|
39874
39909
|
|
|
39910
|
+
// src/tools/search.ts
|
|
39911
|
+
async function runSearch(db, query, limit = 10) {
|
|
39912
|
+
const client = db.$client;
|
|
39913
|
+
let rows;
|
|
39914
|
+
try {
|
|
39915
|
+
const result = await client.execute({
|
|
39916
|
+
sql: `
|
|
39917
|
+
SELECT
|
|
39918
|
+
messages_fts.session_id AS session_id,
|
|
39919
|
+
snippet(messages_fts, 0, '>>>', '<<<', '\u2026', 24) AS excerpt,
|
|
39920
|
+
s.title AS title,
|
|
39921
|
+
s.ai_tool AS ai_tool,
|
|
39922
|
+
s.updated_at AS updated_at
|
|
39923
|
+
FROM messages_fts
|
|
39924
|
+
JOIN sessions s ON s.id = messages_fts.session_id
|
|
39925
|
+
WHERE messages_fts MATCH ?
|
|
39926
|
+
ORDER BY rank
|
|
39927
|
+
LIMIT ?
|
|
39928
|
+
`,
|
|
39929
|
+
args: [query, limit * 5]
|
|
39930
|
+
// over-fetch so we can group into limit distinct sessions
|
|
39931
|
+
});
|
|
39932
|
+
rows = result.rows;
|
|
39933
|
+
} catch {
|
|
39934
|
+
return [];
|
|
39935
|
+
}
|
|
39936
|
+
const map = /* @__PURE__ */ new Map();
|
|
39937
|
+
for (const r of rows) {
|
|
39938
|
+
const sid = String(r.session_id ?? "");
|
|
39939
|
+
if (!sid)
|
|
39940
|
+
continue;
|
|
39941
|
+
if (!map.has(sid)) {
|
|
39942
|
+
map.set(sid, {
|
|
39943
|
+
session_id: sid,
|
|
39944
|
+
title: String(r.title ?? ""),
|
|
39945
|
+
ai_tool: r.ai_tool != null ? String(r.ai_tool) : null,
|
|
39946
|
+
updated_at: String(r.updated_at ?? ""),
|
|
39947
|
+
match_count: 0,
|
|
39948
|
+
excerpts: []
|
|
39949
|
+
});
|
|
39950
|
+
}
|
|
39951
|
+
const entry = map.get(sid);
|
|
39952
|
+
entry.match_count++;
|
|
39953
|
+
if (entry.excerpts.length < 3)
|
|
39954
|
+
entry.excerpts.push(String(r.excerpt ?? ""));
|
|
39955
|
+
if (map.size >= limit && entry.match_count > 1)
|
|
39956
|
+
break;
|
|
39957
|
+
}
|
|
39958
|
+
return Array.from(map.values()).slice(0, limit);
|
|
39959
|
+
}
|
|
39960
|
+
function searchSessions(db) {
|
|
39961
|
+
return async (args) => {
|
|
39962
|
+
const results = await runSearch(db, args.query, args.limit ?? 10);
|
|
39963
|
+
return {
|
|
39964
|
+
content: [{
|
|
39965
|
+
type: "text",
|
|
39966
|
+
text: JSON.stringify({ query: args.query, total: results.length, results })
|
|
39967
|
+
}]
|
|
39968
|
+
};
|
|
39969
|
+
};
|
|
39970
|
+
}
|
|
39971
|
+
var init_search = __esm({
|
|
39972
|
+
"src/tools/search.ts"() {
|
|
39973
|
+
"use strict";
|
|
39974
|
+
}
|
|
39975
|
+
});
|
|
39976
|
+
|
|
39875
39977
|
// src/server.ts
|
|
39876
39978
|
function createServer(db) {
|
|
39877
39979
|
const server = new McpServer({
|
|
@@ -39995,6 +40097,15 @@ function createServer(db) {
|
|
|
39995
40097
|
},
|
|
39996
40098
|
deleteSession(db)
|
|
39997
40099
|
);
|
|
40100
|
+
server.tool(
|
|
40101
|
+
"search_sessions",
|
|
40102
|
+
'Full-text search across all logged AI conversations. Returns matching sessions with excerpts. Uses SQLite FTS5 with porter stemming \u2014 supports phrases ("exact match"), boolean (term1 OR term2), and prefix (migrat*).',
|
|
40103
|
+
{
|
|
40104
|
+
query: external_exports.string().describe('FTS5 search query, e.g. "database migration" or "auth bug" or "deploy OR release"'),
|
|
40105
|
+
limit: external_exports.number().int().positive().optional().describe("Max sessions to return (default: 10)")
|
|
40106
|
+
},
|
|
40107
|
+
searchSessions(db)
|
|
40108
|
+
);
|
|
39998
40109
|
server.tool(
|
|
39999
40110
|
"summarize_session",
|
|
40000
40111
|
"Return a structured summary of a session: timeline with latencies, mutations detected, secrets touched, and possible prod-account references. Useful for compliance review and change-control evidence.",
|
|
@@ -40025,6 +40136,7 @@ var init_server3 = __esm({
|
|
|
40025
40136
|
init_verify();
|
|
40026
40137
|
init_detect2();
|
|
40027
40138
|
init_summary2();
|
|
40139
|
+
init_search();
|
|
40028
40140
|
init_package();
|
|
40029
40141
|
roleEnum = external_exports.enum(["user", "assistant"]);
|
|
40030
40142
|
}
|