code-session-memory 0.11.0 → 0.12.1
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 +33 -30
- package/dist/mcp/index.js +2 -2
- package/dist/mcp/index.js.map +1 -1
- package/dist/src/cli-query.d.ts +1 -0
- package/dist/src/cli-query.d.ts.map +1 -1
- package/dist/src/cli-query.js +5 -3
- package/dist/src/cli-query.js.map +1 -1
- package/dist/src/cli-sessions.d.ts.map +1 -1
- package/dist/src/cli-sessions.js +4 -0
- package/dist/src/cli-sessions.js.map +1 -1
- package/dist/src/cli.js +288 -5
- package/dist/src/cli.js.map +1 -1
- package/dist/src/gemini-session-to-messages.d.ts +25 -0
- package/dist/src/gemini-session-to-messages.d.ts.map +1 -0
- package/dist/src/gemini-session-to-messages.js +205 -0
- package/dist/src/gemini-session-to-messages.js.map +1 -0
- package/dist/src/indexer-cli-gemini.d.ts +12 -0
- package/dist/src/indexer-cli-gemini.d.ts.map +1 -0
- package/dist/src/indexer-cli-gemini.js +148 -0
- package/dist/src/indexer-cli-gemini.js.map +1 -0
- package/dist/src/indexer.d.ts +1 -1
- package/dist/src/indexer.js +1 -1
- package/dist/src/types.d.ts +1 -1
- package/dist/src/types.d.ts.map +1 -1
- package/package.json +4 -3
- package/skill/memory.md +7 -4
package/dist/src/cli.js
CHANGED
|
@@ -127,6 +127,9 @@ function getIndexerCliVscodePath() {
|
|
|
127
127
|
function getIndexerCliCodexPath() {
|
|
128
128
|
return path_1.default.join(getPackageRoot(), "dist", "src", "indexer-cli-codex.js");
|
|
129
129
|
}
|
|
130
|
+
function getIndexerCliGeminiPath() {
|
|
131
|
+
return path_1.default.join(getPackageRoot(), "dist", "src", "indexer-cli-gemini.js");
|
|
132
|
+
}
|
|
130
133
|
// ---------------------------------------------------------------------------
|
|
131
134
|
// Paths — Cursor
|
|
132
135
|
// ---------------------------------------------------------------------------
|
|
@@ -186,6 +189,21 @@ function getCodexSkillDst() {
|
|
|
186
189
|
return path_1.default.join(getCodexConfigDir(), "skills", "code-session-memory", "SKILL.md");
|
|
187
190
|
}
|
|
188
191
|
// ---------------------------------------------------------------------------
|
|
192
|
+
// Paths — Gemini CLI
|
|
193
|
+
// ---------------------------------------------------------------------------
|
|
194
|
+
function getGeminiConfigDir() {
|
|
195
|
+
const envDir = process.env.GEMINI_CONFIG_DIR;
|
|
196
|
+
if (envDir)
|
|
197
|
+
return envDir;
|
|
198
|
+
return path_1.default.join(os_1.default.homedir(), ".gemini");
|
|
199
|
+
}
|
|
200
|
+
function getGeminiSettingsPath() {
|
|
201
|
+
return path_1.default.join(getGeminiConfigDir(), "settings.json");
|
|
202
|
+
}
|
|
203
|
+
function getGeminiSkillDst() {
|
|
204
|
+
return path_1.default.join(getGeminiConfigDir(), "skills", "code-session-memory", "SKILL.md");
|
|
205
|
+
}
|
|
206
|
+
// ---------------------------------------------------------------------------
|
|
189
207
|
// Helpers
|
|
190
208
|
// ---------------------------------------------------------------------------
|
|
191
209
|
/**
|
|
@@ -671,7 +689,7 @@ function installCursorSkill(skillSrc) {
|
|
|
671
689
|
const cursorFrontmatter = [
|
|
672
690
|
"---",
|
|
673
691
|
"name: code-session-memory",
|
|
674
|
-
"description: Search past AI coding sessions semantically across OpenCode, Claude Code, Cursor, VS Code, and
|
|
692
|
+
"description: Search past AI coding sessions semantically across OpenCode, Claude Code, Cursor, VS Code, Codex, and Gemini CLI. Use this when the user asks about past work, decisions, or implementations.",
|
|
675
693
|
"---",
|
|
676
694
|
"",
|
|
677
695
|
].join("\n");
|
|
@@ -1054,7 +1072,7 @@ function installCodexSkill(skillSrc) {
|
|
|
1054
1072
|
const codexFrontmatter = [
|
|
1055
1073
|
"---",
|
|
1056
1074
|
"name: code-session-memory",
|
|
1057
|
-
"description: Search past AI coding sessions semantically across OpenCode, Claude Code, Cursor, VS Code, and
|
|
1075
|
+
"description: Search past AI coding sessions semantically across OpenCode, Claude Code, Cursor, VS Code, Codex, and Gemini CLI.",
|
|
1058
1076
|
"---",
|
|
1059
1077
|
"",
|
|
1060
1078
|
].join("\n");
|
|
@@ -1076,6 +1094,226 @@ function uninstallCodexSkill() {
|
|
|
1076
1094
|
return "done";
|
|
1077
1095
|
}
|
|
1078
1096
|
// ---------------------------------------------------------------------------
|
|
1097
|
+
// Gemini CLI — settings.json
|
|
1098
|
+
// ---------------------------------------------------------------------------
|
|
1099
|
+
function parseGeminiSettingsOrEmpty(settingsPath) {
|
|
1100
|
+
if (!fs_1.default.existsSync(settingsPath))
|
|
1101
|
+
return {};
|
|
1102
|
+
try {
|
|
1103
|
+
return JSON.parse(fs_1.default.readFileSync(settingsPath, "utf8"));
|
|
1104
|
+
}
|
|
1105
|
+
catch {
|
|
1106
|
+
throw new Error(`Could not parse existing ${settingsPath} — please check it is valid JSON.`);
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
function installGeminiMcpConfig(mcpServerPath) {
|
|
1110
|
+
const settingsPath = getGeminiSettingsPath();
|
|
1111
|
+
const existed = fs_1.default.existsSync(settingsPath);
|
|
1112
|
+
const settings = parseGeminiSettingsOrEmpty(settingsPath);
|
|
1113
|
+
const mcpServersRaw = settings.mcpServers;
|
|
1114
|
+
const mcpServers = mcpServersRaw && typeof mcpServersRaw === "object"
|
|
1115
|
+
? mcpServersRaw
|
|
1116
|
+
: {};
|
|
1117
|
+
mcpServers["code-session-memory"] = {
|
|
1118
|
+
type: "stdio",
|
|
1119
|
+
command: "node",
|
|
1120
|
+
args: [mcpServerPath],
|
|
1121
|
+
};
|
|
1122
|
+
settings.mcpServers = mcpServers;
|
|
1123
|
+
ensureDir(path_1.default.dirname(settingsPath));
|
|
1124
|
+
fs_1.default.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
1125
|
+
return { settingsPath, existed };
|
|
1126
|
+
}
|
|
1127
|
+
function uninstallGeminiMcpConfig() {
|
|
1128
|
+
const settingsPath = getGeminiSettingsPath();
|
|
1129
|
+
if (!fs_1.default.existsSync(settingsPath))
|
|
1130
|
+
return "not_found";
|
|
1131
|
+
try {
|
|
1132
|
+
const settings = JSON.parse(fs_1.default.readFileSync(settingsPath, "utf8"));
|
|
1133
|
+
if (settings.mcpServers &&
|
|
1134
|
+
typeof settings.mcpServers === "object" &&
|
|
1135
|
+
"code-session-memory" in settings.mcpServers) {
|
|
1136
|
+
delete settings.mcpServers["code-session-memory"];
|
|
1137
|
+
fs_1.default.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
1138
|
+
return "done";
|
|
1139
|
+
}
|
|
1140
|
+
return "not_found";
|
|
1141
|
+
}
|
|
1142
|
+
catch {
|
|
1143
|
+
return "not_found";
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
function checkGeminiMcpConfigured() {
|
|
1147
|
+
const settingsPath = getGeminiSettingsPath();
|
|
1148
|
+
try {
|
|
1149
|
+
const settings = JSON.parse(fs_1.default.readFileSync(settingsPath, "utf8"));
|
|
1150
|
+
return !!(settings.mcpServers &&
|
|
1151
|
+
typeof settings.mcpServers === "object" &&
|
|
1152
|
+
"code-session-memory" in settings.mcpServers);
|
|
1153
|
+
}
|
|
1154
|
+
catch {
|
|
1155
|
+
return false;
|
|
1156
|
+
}
|
|
1157
|
+
}
|
|
1158
|
+
function installGeminiHook(indexerCliGeminiPath) {
|
|
1159
|
+
const settingsPath = getGeminiSettingsPath();
|
|
1160
|
+
const existed = fs_1.default.existsSync(settingsPath);
|
|
1161
|
+
const settings = parseGeminiSettingsOrEmpty(settingsPath);
|
|
1162
|
+
const hooksRaw = settings.hooks;
|
|
1163
|
+
const hooks = hooksRaw && typeof hooksRaw === "object"
|
|
1164
|
+
? hooksRaw
|
|
1165
|
+
: {};
|
|
1166
|
+
const afterAgentRaw = Array.isArray(hooks.AfterAgent) ? hooks.AfterAgent : [];
|
|
1167
|
+
const cleanedGroups = [];
|
|
1168
|
+
for (const entry of afterAgentRaw) {
|
|
1169
|
+
if (!entry || typeof entry !== "object")
|
|
1170
|
+
continue;
|
|
1171
|
+
const group = entry;
|
|
1172
|
+
if (!Array.isArray(group.hooks))
|
|
1173
|
+
continue;
|
|
1174
|
+
const filteredHooks = group.hooks.filter((h) => {
|
|
1175
|
+
if (!h || typeof h !== "object")
|
|
1176
|
+
return true;
|
|
1177
|
+
const hook = h;
|
|
1178
|
+
return typeof hook.command !== "string" || !hook.command.includes("indexer-cli-gemini");
|
|
1179
|
+
});
|
|
1180
|
+
if (filteredHooks.length > 0) {
|
|
1181
|
+
cleanedGroups.push({ ...group, hooks: filteredHooks });
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
cleanedGroups.push({
|
|
1185
|
+
hooks: [
|
|
1186
|
+
{
|
|
1187
|
+
type: "command",
|
|
1188
|
+
name: "code-session-memory-indexer",
|
|
1189
|
+
command: `node ${indexerCliGeminiPath}`,
|
|
1190
|
+
},
|
|
1191
|
+
],
|
|
1192
|
+
});
|
|
1193
|
+
hooks.AfterAgent = cleanedGroups;
|
|
1194
|
+
settings.hooks = hooks;
|
|
1195
|
+
ensureDir(path_1.default.dirname(settingsPath));
|
|
1196
|
+
fs_1.default.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
1197
|
+
return { settingsPath, existed };
|
|
1198
|
+
}
|
|
1199
|
+
function uninstallGeminiHook() {
|
|
1200
|
+
const settingsPath = getGeminiSettingsPath();
|
|
1201
|
+
if (!fs_1.default.existsSync(settingsPath))
|
|
1202
|
+
return "not_found";
|
|
1203
|
+
try {
|
|
1204
|
+
const settings = JSON.parse(fs_1.default.readFileSync(settingsPath, "utf8"));
|
|
1205
|
+
const hooks = settings.hooks;
|
|
1206
|
+
const afterAgent = hooks?.AfterAgent;
|
|
1207
|
+
if (!Array.isArray(afterAgent))
|
|
1208
|
+
return "not_found";
|
|
1209
|
+
let removed = false;
|
|
1210
|
+
const filteredGroups = [];
|
|
1211
|
+
for (const entry of afterAgent) {
|
|
1212
|
+
if (!entry || typeof entry !== "object")
|
|
1213
|
+
continue;
|
|
1214
|
+
const group = entry;
|
|
1215
|
+
// Legacy shape support: { command: "..." }
|
|
1216
|
+
if (typeof group.command === "string") {
|
|
1217
|
+
if (group.command.includes("indexer-cli-gemini")) {
|
|
1218
|
+
removed = true;
|
|
1219
|
+
continue;
|
|
1220
|
+
}
|
|
1221
|
+
filteredGroups.push(group);
|
|
1222
|
+
continue;
|
|
1223
|
+
}
|
|
1224
|
+
if (!Array.isArray(group.hooks)) {
|
|
1225
|
+
filteredGroups.push(group);
|
|
1226
|
+
continue;
|
|
1227
|
+
}
|
|
1228
|
+
const filteredHooks = group.hooks.filter((h) => {
|
|
1229
|
+
if (!h || typeof h !== "object")
|
|
1230
|
+
return true;
|
|
1231
|
+
const hook = h;
|
|
1232
|
+
const keep = typeof hook.command !== "string" || !hook.command.includes("indexer-cli-gemini");
|
|
1233
|
+
if (!keep)
|
|
1234
|
+
removed = true;
|
|
1235
|
+
return keep;
|
|
1236
|
+
});
|
|
1237
|
+
if (filteredHooks.length > 0) {
|
|
1238
|
+
filteredGroups.push({ ...group, hooks: filteredHooks });
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
if (!removed)
|
|
1242
|
+
return "not_found";
|
|
1243
|
+
hooks.AfterAgent = filteredGroups;
|
|
1244
|
+
settings.hooks = hooks;
|
|
1245
|
+
fs_1.default.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n", "utf8");
|
|
1246
|
+
return "done";
|
|
1247
|
+
}
|
|
1248
|
+
catch {
|
|
1249
|
+
return "not_found";
|
|
1250
|
+
}
|
|
1251
|
+
}
|
|
1252
|
+
function checkGeminiHookInstalled() {
|
|
1253
|
+
const settingsPath = getGeminiSettingsPath();
|
|
1254
|
+
try {
|
|
1255
|
+
const settings = JSON.parse(fs_1.default.readFileSync(settingsPath, "utf8"));
|
|
1256
|
+
const hooks = settings.hooks;
|
|
1257
|
+
const afterAgent = hooks?.AfterAgent;
|
|
1258
|
+
if (!Array.isArray(afterAgent))
|
|
1259
|
+
return false;
|
|
1260
|
+
return afterAgent.some((entry) => {
|
|
1261
|
+
if (!entry || typeof entry !== "object")
|
|
1262
|
+
return false;
|
|
1263
|
+
const group = entry;
|
|
1264
|
+
// Legacy shape support: { command: "..." }
|
|
1265
|
+
if (typeof group.command === "string" && group.command.includes("indexer-cli-gemini")) {
|
|
1266
|
+
return true;
|
|
1267
|
+
}
|
|
1268
|
+
if (!Array.isArray(group.hooks))
|
|
1269
|
+
return false;
|
|
1270
|
+
return group.hooks.some((h) => {
|
|
1271
|
+
if (!h || typeof h !== "object")
|
|
1272
|
+
return false;
|
|
1273
|
+
const hook = h;
|
|
1274
|
+
return typeof hook.command === "string" && hook.command.includes("indexer-cli-gemini");
|
|
1275
|
+
});
|
|
1276
|
+
});
|
|
1277
|
+
}
|
|
1278
|
+
catch {
|
|
1279
|
+
return false;
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
function installGeminiSkill(skillSrc) {
|
|
1283
|
+
const dstPath = getGeminiSkillDst();
|
|
1284
|
+
const existed = fs_1.default.existsSync(dstPath);
|
|
1285
|
+
if (!fs_1.default.existsSync(skillSrc)) {
|
|
1286
|
+
throw new Error(`Skill source not found: ${skillSrc}\nDid you run "npm run build" first?`);
|
|
1287
|
+
}
|
|
1288
|
+
const skillBody = fs_1.default.readFileSync(skillSrc, "utf8");
|
|
1289
|
+
const bodyWithoutFrontmatter = skillBody
|
|
1290
|
+
.replace(/^---[\s\S]*?---\s*\n?/, "")
|
|
1291
|
+
.trimStart();
|
|
1292
|
+
const geminiFrontmatter = [
|
|
1293
|
+
"---",
|
|
1294
|
+
"name: code-session-memory",
|
|
1295
|
+
"description: Search past AI coding sessions semantically across OpenCode, Claude Code, Cursor, VS Code, Codex, and Gemini CLI.",
|
|
1296
|
+
"---",
|
|
1297
|
+
"",
|
|
1298
|
+
].join("\n");
|
|
1299
|
+
ensureDir(path_1.default.dirname(dstPath));
|
|
1300
|
+
fs_1.default.writeFileSync(dstPath, geminiFrontmatter + bodyWithoutFrontmatter, "utf8");
|
|
1301
|
+
return { dstPath, existed };
|
|
1302
|
+
}
|
|
1303
|
+
function uninstallGeminiSkill() {
|
|
1304
|
+
const dstPath = getGeminiSkillDst();
|
|
1305
|
+
if (!fs_1.default.existsSync(dstPath))
|
|
1306
|
+
return "not_found";
|
|
1307
|
+
fs_1.default.unlinkSync(dstPath);
|
|
1308
|
+
try {
|
|
1309
|
+
const dir = path_1.default.dirname(dstPath);
|
|
1310
|
+
if (fs_1.default.readdirSync(dir).length === 0)
|
|
1311
|
+
fs_1.default.rmdirSync(dir);
|
|
1312
|
+
}
|
|
1313
|
+
catch { /* ignore */ }
|
|
1314
|
+
return "done";
|
|
1315
|
+
}
|
|
1316
|
+
// ---------------------------------------------------------------------------
|
|
1079
1317
|
// Formatting helpers
|
|
1080
1318
|
// ---------------------------------------------------------------------------
|
|
1081
1319
|
function bold(s) { return `\x1b[1m${s}\x1b[0m`; }
|
|
@@ -1101,6 +1339,9 @@ function isVscodeInstalled() {
|
|
|
1101
1339
|
function isCodexInstalled() {
|
|
1102
1340
|
return fs_1.default.existsSync(getCodexConfigDir());
|
|
1103
1341
|
}
|
|
1342
|
+
function isGeminiInstalled() {
|
|
1343
|
+
return fs_1.default.existsSync(getGeminiConfigDir());
|
|
1344
|
+
}
|
|
1104
1345
|
function step(label, fn) {
|
|
1105
1346
|
process.stdout.write(` ${label}... `);
|
|
1106
1347
|
try {
|
|
@@ -1131,11 +1372,13 @@ function install() {
|
|
|
1131
1372
|
const indexerCursorPath = getIndexerCliCursorPath();
|
|
1132
1373
|
const indexerVscodePath = getIndexerCliVscodePath();
|
|
1133
1374
|
const indexerCodexPath = getIndexerCliCodexPath();
|
|
1375
|
+
const indexerGeminiPath = getIndexerCliGeminiPath();
|
|
1134
1376
|
const openCodeInstalled = isOpenCodeInstalled();
|
|
1135
1377
|
const claudeInstalled = isClaudeCodeInstalled();
|
|
1136
1378
|
const cursorInstalled = isCursorInstalled();
|
|
1137
1379
|
const vscodeInstalled = isVscodeInstalled();
|
|
1138
1380
|
const codexInstalled = isCodexInstalled();
|
|
1381
|
+
const geminiInstalled = isGeminiInstalled();
|
|
1139
1382
|
// 1. DB
|
|
1140
1383
|
step("Initialising database", () => {
|
|
1141
1384
|
ensureDir(path_1.default.dirname(dbPath));
|
|
@@ -1210,6 +1453,19 @@ function install() {
|
|
|
1210
1453
|
const { dstPath, existed } = installCodexSkill(getSkillSrc());
|
|
1211
1454
|
return `${existed ? "updated" : "created"} ${dstPath}`;
|
|
1212
1455
|
});
|
|
1456
|
+
// Gemini CLI
|
|
1457
|
+
stepIf(geminiInstalled, "Configuring Gemini CLI MCP server", () => {
|
|
1458
|
+
const { settingsPath, existed } = installGeminiMcpConfig(mcpPath);
|
|
1459
|
+
return `${existed ? "updated" : "created"} ${settingsPath}`;
|
|
1460
|
+
});
|
|
1461
|
+
stepIf(geminiInstalled, "Installing Gemini CLI AfterAgent hook", () => {
|
|
1462
|
+
const { settingsPath, existed } = installGeminiHook(indexerGeminiPath);
|
|
1463
|
+
return `${existed ? "updated" : "created"} ${settingsPath}`;
|
|
1464
|
+
});
|
|
1465
|
+
stepIf(geminiInstalled, "Installing Gemini CLI skill", () => {
|
|
1466
|
+
const { dstPath, existed } = installGeminiSkill(getSkillSrc());
|
|
1467
|
+
return `${existed ? "updated" : "created"} ${dstPath}`;
|
|
1468
|
+
});
|
|
1213
1469
|
console.log(`
|
|
1214
1470
|
${bold("Installation complete!")}
|
|
1215
1471
|
|
|
@@ -1218,10 +1474,11 @@ ${bold("Required environment variable:")}
|
|
|
1218
1474
|
|
|
1219
1475
|
${bold("Default DB path:")} ${dbPath}
|
|
1220
1476
|
|
|
1221
|
-
Restart ${bold("OpenCode")}, ${bold("Claude Code")}, ${bold("Cursor")}, ${bold("VS Code")}, and ${bold("
|
|
1477
|
+
Restart ${bold("OpenCode")}, ${bold("Claude Code")}, ${bold("Cursor")}, ${bold("VS Code")}, ${bold("Codex")}, and ${bold("Gemini CLI")} to activate.
|
|
1222
1478
|
|
|
1223
1479
|
${bold("VS Code note:")} Ensure ${bold("Chat: Use Hooks")} is enabled in VS Code settings.
|
|
1224
1480
|
${bold("Codex note:")} The notify hook and OPENAI_API_KEY passthrough are set in ${dim(getCodexConfigPath())}.
|
|
1481
|
+
${bold("Gemini CLI note:")} The AfterAgent hook is configured in ${dim(getGeminiSettingsPath())}.
|
|
1225
1482
|
Run ${bold("npx code-session-memory status")} to verify.
|
|
1226
1483
|
`);
|
|
1227
1484
|
}
|
|
@@ -1234,6 +1491,7 @@ function status() {
|
|
|
1234
1491
|
const cursorInstalled = isCursorInstalled();
|
|
1235
1492
|
const vscodeInstalled = isVscodeInstalled();
|
|
1236
1493
|
const codexInstalled = isCodexInstalled();
|
|
1494
|
+
const geminiInstalled = isGeminiInstalled();
|
|
1237
1495
|
if (openCodeInstalled) {
|
|
1238
1496
|
console.log(bold(" OpenCode"));
|
|
1239
1497
|
console.log(` ${ok(fs_1.default.existsSync(getOpenCodePluginDst()))} Plugin ${dim(getOpenCodePluginDst())}`);
|
|
@@ -1280,6 +1538,15 @@ function status() {
|
|
|
1280
1538
|
else {
|
|
1281
1539
|
console.log(bold("\n Codex") + dim(" (not installed — skipped)"));
|
|
1282
1540
|
}
|
|
1541
|
+
if (geminiInstalled) {
|
|
1542
|
+
console.log(bold("\n Gemini CLI"));
|
|
1543
|
+
console.log(` ${ok(checkGeminiMcpConfigured())} MCP config ${dim(getGeminiSettingsPath())}`);
|
|
1544
|
+
console.log(` ${ok(checkGeminiHookInstalled())} AfterAgent ${dim(getGeminiSettingsPath())}`);
|
|
1545
|
+
console.log(` ${ok(fs_1.default.existsSync(getGeminiSkillDst()))} Skill ${dim(getGeminiSkillDst())}`);
|
|
1546
|
+
}
|
|
1547
|
+
else {
|
|
1548
|
+
console.log(bold("\n Gemini CLI") + dim(" (not installed — skipped)"));
|
|
1549
|
+
}
|
|
1283
1550
|
console.log(bold("\n Shared"));
|
|
1284
1551
|
console.log(` ${ok(fs_1.default.existsSync(mcpPath))} MCP server ${dim(mcpPath)}`);
|
|
1285
1552
|
console.log(` ${ok(fs_1.default.existsSync(dbPath))} Database ${dim(dbPath)}`);
|
|
@@ -1319,6 +1586,9 @@ function status() {
|
|
|
1319
1586
|
checkCodexOpenAiPassthroughConfigured() &&
|
|
1320
1587
|
checkCodexHookInstalled() &&
|
|
1321
1588
|
fs_1.default.existsSync(getCodexSkillDst()))) &&
|
|
1589
|
+
(!geminiInstalled || (checkGeminiMcpConfigured() &&
|
|
1590
|
+
checkGeminiHookInstalled() &&
|
|
1591
|
+
fs_1.default.existsSync(getGeminiSkillDst()))) &&
|
|
1322
1592
|
fs_1.default.existsSync(mcpPath) &&
|
|
1323
1593
|
fs_1.default.existsSync(dbPath);
|
|
1324
1594
|
console.log(`\n ${allOk
|
|
@@ -1394,6 +1664,18 @@ function uninstall() {
|
|
|
1394
1664
|
if (uninstallCodexSkill() === "not_found")
|
|
1395
1665
|
throw new Error("not found");
|
|
1396
1666
|
}],
|
|
1667
|
+
["Gemini CLI MCP config", () => {
|
|
1668
|
+
if (uninstallGeminiMcpConfig() === "not_found")
|
|
1669
|
+
throw new Error("not found");
|
|
1670
|
+
}],
|
|
1671
|
+
["Gemini CLI AfterAgent hook", () => {
|
|
1672
|
+
if (uninstallGeminiHook() === "not_found")
|
|
1673
|
+
throw new Error("not found");
|
|
1674
|
+
}],
|
|
1675
|
+
["Gemini CLI skill", () => {
|
|
1676
|
+
if (uninstallGeminiSkill() === "not_found")
|
|
1677
|
+
throw new Error("not found");
|
|
1678
|
+
}],
|
|
1397
1679
|
];
|
|
1398
1680
|
for (const [label, fn] of items) {
|
|
1399
1681
|
process.stdout.write(` Removing ${label}... `);
|
|
@@ -1448,7 +1730,7 @@ async function resetDb() {
|
|
|
1448
1730
|
}
|
|
1449
1731
|
function help() {
|
|
1450
1732
|
console.log(`
|
|
1451
|
-
${bold("code-session-memory")} — Shared vector memory for OpenCode, Claude Code, Cursor, VS Code, and
|
|
1733
|
+
${bold("code-session-memory")} — Shared vector memory for OpenCode, Claude Code, Cursor, VS Code, Codex, and Gemini CLI sessions
|
|
1452
1734
|
|
|
1453
1735
|
${bold("Usage:")}
|
|
1454
1736
|
npx code-session-memory install Install components for detected tools
|
|
@@ -1456,7 +1738,7 @@ ${bold("Usage:")}
|
|
|
1456
1738
|
npx code-session-memory uninstall Remove all installed components (keeps DB)
|
|
1457
1739
|
npx code-session-memory reset-db Delete all indexed data (keeps installation)
|
|
1458
1740
|
npx code-session-memory query <text> Semantic search across all indexed sessions
|
|
1459
|
-
npx code-session-memory query <text> --source <s> Filter by source (opencode, claude-code, cursor, vscode, codex)
|
|
1741
|
+
npx code-session-memory query <text> --source <s> Filter by source (opencode, claude-code, cursor, vscode, codex, gemini-cli)
|
|
1460
1742
|
npx code-session-memory query <text> --limit <n> Max results (default: 5)
|
|
1461
1743
|
npx code-session-memory query <text> --from <date> Results from date (e.g. 2026-02-01)
|
|
1462
1744
|
npx code-session-memory query <text> --to <date> Results up to date (e.g. 2026-02-20)
|
|
@@ -1475,6 +1757,7 @@ ${bold("Environment variables:")}
|
|
|
1475
1757
|
CURSOR_CONFIG_DIR Override the Cursor config directory (~/.cursor)
|
|
1476
1758
|
VSCODE_CONFIG_DIR Override the VS Code config directory
|
|
1477
1759
|
CODEX_HOME Override the Codex home directory (~/.codex)
|
|
1760
|
+
GEMINI_CONFIG_DIR Override the Gemini CLI config directory (~/.gemini)
|
|
1478
1761
|
`);
|
|
1479
1762
|
}
|
|
1480
1763
|
// ---------------------------------------------------------------------------
|