sandstream-kit 1.0.1 → 1.2.0
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 +18 -0
- package/dist/check-web-search.js +37 -6
- package/dist/check-web-search.js.map +1 -1
- package/dist/cli.js +520 -2
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/database.d.ts +2 -2
- package/dist/database.js +9 -14
- package/dist/database.js.map +1 -1
- package/dist/lock.js +5 -3
- package/dist/lock.js.map +1 -1
- package/dist/memory/backup 2.d.ts +6 -0
- package/dist/memory/backup 2.js +80 -0
- package/dist/memory/backup 2.js.map +1 -0
- package/dist/memory/backup.d.ts +6 -0
- package/dist/memory/backup.js +80 -0
- package/dist/memory/backup.js.map +1 -0
- package/dist/memory/codex.d.ts +5 -0
- package/dist/memory/codex.js +150 -0
- package/dist/memory/codex.js.map +1 -0
- package/dist/memory/continue.d.ts +5 -0
- package/dist/memory/continue.js +116 -0
- package/dist/memory/continue.js.map +1 -0
- package/dist/memory/db 2.d.ts +40 -0
- package/dist/memory/db 2.js +233 -0
- package/dist/memory/db 2.js.map +1 -0
- package/dist/memory/db.d.ts +51 -0
- package/dist/memory/db.js +275 -0
- package/dist/memory/db.js.map +1 -0
- package/dist/memory/gemini.d.ts +5 -0
- package/dist/memory/gemini.js +176 -0
- package/dist/memory/gemini.js.map +1 -0
- package/dist/memory/hook 2.d.ts +6 -0
- package/dist/memory/hook 2.js +51 -0
- package/dist/memory/hook 2.js.map +1 -0
- package/dist/memory/hook.d.ts +15 -0
- package/dist/memory/hook.js +84 -0
- package/dist/memory/hook.js.map +1 -0
- package/dist/memory/hook.test 2.d.ts +1 -0
- package/dist/memory/hook.test 2.js +35 -0
- package/dist/memory/hook.test 2.js.map +1 -0
- package/dist/memory/install 2.d.ts +8 -0
- package/dist/memory/install 2.js +72 -0
- package/dist/memory/install 2.js.map +1 -0
- package/dist/memory/install.d.ts +8 -0
- package/dist/memory/install.js +73 -0
- package/dist/memory/install.js.map +1 -0
- package/dist/memory/install.test 2.d.ts +1 -0
- package/dist/memory/install.test 2.js +59 -0
- package/dist/memory/install.test 2.js.map +1 -0
- package/dist/memory/merge.d.ts +18 -0
- package/dist/memory/merge.js +109 -0
- package/dist/memory/merge.js.map +1 -0
- package/dist/memory/pal 2.d.ts +47 -0
- package/dist/memory/pal 2.js +154 -0
- package/dist/memory/pal 2.js.map +1 -0
- package/dist/memory/pal.d.ts +47 -0
- package/dist/memory/pal.js +154 -0
- package/dist/memory/pal.js.map +1 -0
- package/dist/memory/parser.d.ts +34 -0
- package/dist/memory/parser.js +195 -0
- package/dist/memory/parser.js.map +1 -0
- package/dist/memory/project 2.d.ts +1 -0
- package/dist/memory/project 2.js +24 -0
- package/dist/memory/project 2.js.map +1 -0
- package/dist/memory/project.d.ts +1 -0
- package/dist/memory/project.js +24 -0
- package/dist/memory/project.js.map +1 -0
- package/dist/memory/scan 2.d.ts +15 -0
- package/dist/memory/scan 2.js +94 -0
- package/dist/memory/scan 2.js.map +1 -0
- package/dist/memory/scan.d.ts +15 -0
- package/dist/memory/scan.js +94 -0
- package/dist/memory/scan.js.map +1 -0
- package/dist/memory/scan.test 2.d.ts +1 -0
- package/dist/memory/scan.test 2.js +55 -0
- package/dist/memory/scan.test 2.js.map +1 -0
- package/dist/memory/shared 2.d.ts +33 -0
- package/dist/memory/shared 2.js +120 -0
- package/dist/memory/shared 2.js.map +1 -0
- package/dist/memory/shared.d.ts +33 -0
- package/dist/memory/shared.js +120 -0
- package/dist/memory/shared.js.map +1 -0
- package/dist/memory/threads 2.d.ts +37 -0
- package/dist/memory/threads 2.js +50 -0
- package/dist/memory/threads 2.js.map +1 -0
- package/dist/memory/threads.d.ts +37 -0
- package/dist/memory/threads.js +50 -0
- package/dist/memory/threads.js.map +1 -0
- package/dist/memory/threads.test 2.d.ts +1 -0
- package/dist/memory/threads.test 2.js +66 -0
- package/dist/memory/threads.test 2.js.map +1 -0
- package/dist/memory/types 2.d.ts +52 -0
- package/dist/memory/types 2.js +5 -0
- package/dist/memory/types 2.js.map +1 -0
- package/dist/memory/types.d.ts +52 -0
- package/dist/memory/types.js +5 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/status.d.ts +9 -0
- package/dist/status.js +119 -0
- package/dist/status.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -252,6 +252,24 @@ Production credentials are gated behind explicit env-switching and short-lived e
|
|
|
252
252
|
- Supply-chain findings auto-append to `.kit-audit.jsonl` (one JSON line per finding) for SIEM ingest
|
|
253
253
|
- Releases ship with SLSA provenance (`npm publish --provenance`), CycloneDX + SPDX SBOMs on every GitHub release, cosign-signed Docker images, and weekly OpenSSF Scorecard
|
|
254
254
|
|
|
255
|
+
## Memory
|
|
256
|
+
|
|
257
|
+
`kit memory` gives an agent a local-first, deterministic second brain — it stores
|
|
258
|
+
your raw conversation history and searches it *before answering*, so it pulls
|
|
259
|
+
receipts instead of guessing. SQLite + FTS5, two hooks, no vectors, no model calls.
|
|
260
|
+
A private personal tier (encrypted backup so a stolen laptop doesn't lose your
|
|
261
|
+
context) plus a curated, area-organized **shared** tier that travels with the repo
|
|
262
|
+
and is reviewed like code.
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
kit memory install && kit memory index
|
|
266
|
+
kit memory search "what did we decide about X" # project-scoped recall
|
|
267
|
+
kit memory area stripe # shared: how we built it, status, security
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
Full reference: [`docs/MEMORY.md`](docs/MEMORY.md). Schema + two-hook design
|
|
271
|
+
credited to [cloudctx](https://github.com/chadptk1238/cloudctx) (MIT).
|
|
272
|
+
|
|
255
273
|
## Lock Files
|
|
256
274
|
|
|
257
275
|
kit uses lock files in `.kit/` to track exact versions of skills and tools:
|
package/dist/check-web-search.js
CHANGED
|
@@ -113,12 +113,43 @@ export async function checkWebSearch(config) {
|
|
|
113
113
|
};
|
|
114
114
|
}
|
|
115
115
|
case "google":
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
116
|
+
if (!config.apiKey || !config.cx) {
|
|
117
|
+
return {
|
|
118
|
+
provider,
|
|
119
|
+
configured: false,
|
|
120
|
+
healthy: false,
|
|
121
|
+
error: "Google Custom Search needs web.search.apiKey + web.search.cx (Programmable Search engine id)",
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
try {
|
|
125
|
+
// Custom Search JSON API — key + cx are query params by design.
|
|
126
|
+
const response = await fetchWithTimeout(`https://www.googleapis.com/customsearch/v1?key=${encodeURIComponent(config.apiKey)}&cx=${encodeURIComponent(config.cx)}&q=test&num=1`);
|
|
127
|
+
if (response.ok) {
|
|
128
|
+
return { provider, configured: true, healthy: true };
|
|
129
|
+
}
|
|
130
|
+
if (response.status === 400 || response.status === 401 || response.status === 403) {
|
|
131
|
+
return {
|
|
132
|
+
provider,
|
|
133
|
+
configured: true,
|
|
134
|
+
healthy: false,
|
|
135
|
+
error: "Invalid Google API key or cx (request rejected)",
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
return {
|
|
139
|
+
provider,
|
|
140
|
+
configured: true,
|
|
141
|
+
healthy: false,
|
|
142
|
+
error: `API returned status ${response.status}`,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
catch (err) {
|
|
146
|
+
return {
|
|
147
|
+
provider,
|
|
148
|
+
configured: true,
|
|
149
|
+
healthy: false,
|
|
150
|
+
error: err instanceof Error ? err.message : "API check failed",
|
|
151
|
+
};
|
|
152
|
+
}
|
|
122
153
|
case "custom":
|
|
123
154
|
if (!url) {
|
|
124
155
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-web-search.js","sourceRoot":"","sources":["../src/check-web-search.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"check-web-search.js","sourceRoot":"","sources":["../src/check-web-search.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { readFileSync } from "node:fs";
|
|
2
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
3
3
|
import { writeFile, access, mkdir } from "node:fs/promises";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
|
-
import { resolve, dirname, join } from "node:path";
|
|
5
|
+
import { resolve, dirname, join, basename } from "node:path";
|
|
6
6
|
import { loadConfig, resolveActiveEnvironment } from "./config.js";
|
|
7
7
|
import { checkTools } from "./check-tools.js";
|
|
8
8
|
import { checkServices } from "./check-services.js";
|
|
@@ -56,6 +56,7 @@ import { cmdFix } from "./fix.js";
|
|
|
56
56
|
import { promptConfirm } from "./utils/prompt.js";
|
|
57
57
|
import { startMcpServer } from "./mcp-server.js";
|
|
58
58
|
import { c } from "./utils/colors.js";
|
|
59
|
+
import { gatherStatus } from "./status.js";
|
|
59
60
|
import { runDoctor } from "./doctor.js";
|
|
60
61
|
import { inspectEnv } from "./env-inspect.js";
|
|
61
62
|
import { detectStack } from "./stack-detector.js";
|
|
@@ -68,6 +69,17 @@ import { listServices, openService } from "./open.js";
|
|
|
68
69
|
import { gatherProjectContext } from "./context.js";
|
|
69
70
|
import { runTriage, listTriageTools } from "./triage.js";
|
|
70
71
|
import { parsePkgSpec, installPkg } from "./pkg.js";
|
|
72
|
+
import { openMemoryDb, getStats, getMemoryDbPath, searchMessages } from "./memory/db.js";
|
|
73
|
+
import { indexAllHarnesses } from "./memory/parser.js";
|
|
74
|
+
import { mergeDb } from "./memory/merge.js";
|
|
75
|
+
import { getCurrentProjectRoot } from "./memory/project.js";
|
|
76
|
+
import { scanDbForSecrets } from "./memory/scan.js";
|
|
77
|
+
import { backupEncrypted, restoreEncrypted } from "./memory/backup.js";
|
|
78
|
+
import { shareEntry, listAreas, queryArea, getSharedPath, } from "./memory/shared.js";
|
|
79
|
+
import { userPromptSubmitReminder, runSessionEndIndex, sessionStartRecovery } from "./memory/hook.js";
|
|
80
|
+
import { installMemoryHooks, uninstallMemoryHooks, getClaudeSettingsPath, } from "./memory/install.js";
|
|
81
|
+
import { palAdd, palList, palDone, palSnooze, palAutoVerify, importLegacyLedger, } from "./memory/pal.js";
|
|
82
|
+
import { saveThread, listThreads, removeThread, latestSessionId, resolveThread, } from "./memory/threads.js";
|
|
71
83
|
const KIT_FILE = ".kit.toml";
|
|
72
84
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
73
85
|
const KIT_VERSION = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8")).version;
|
|
@@ -3319,6 +3331,21 @@ async function cmdContext() {
|
|
|
3319
3331
|
return false;
|
|
3320
3332
|
}
|
|
3321
3333
|
}
|
|
3334
|
+
async function cmdStatus() {
|
|
3335
|
+
const items = await gatherStatus();
|
|
3336
|
+
if (hasFlag(process.argv, "--json")) {
|
|
3337
|
+
console.log(JSON.stringify(items, null, 2));
|
|
3338
|
+
return true;
|
|
3339
|
+
}
|
|
3340
|
+
const done = items.filter((i) => i.ok).length;
|
|
3341
|
+
console.log(`${c.bold}kit status${c.reset} ${c.dim}${done}/${items.length} set up${c.reset}`);
|
|
3342
|
+
for (const item of items) {
|
|
3343
|
+
const mark = item.ok ? `${c.green}✓${c.reset}` : `${c.yellow}○${c.reset}`;
|
|
3344
|
+
const hint = !item.ok && item.hint ? ` ${c.dim}→ ${item.hint}${c.reset}` : "";
|
|
3345
|
+
console.log(` ${mark} ${item.label} ${c.dim}${item.detail}${c.reset}${hint}`);
|
|
3346
|
+
}
|
|
3347
|
+
return true;
|
|
3348
|
+
}
|
|
3322
3349
|
async function cmdWhoami() {
|
|
3323
3350
|
const jsonMode = hasFlag(process.argv, "--json");
|
|
3324
3351
|
let config = {};
|
|
@@ -3390,7 +3417,24 @@ function cmdVersion() {
|
|
|
3390
3417
|
return true;
|
|
3391
3418
|
}
|
|
3392
3419
|
const COMMAND_HELP = {
|
|
3420
|
+
status: "Adoption checklist — what's set up across kit + the next step for each gap",
|
|
3393
3421
|
check: "Check status of all tools, services, secrets, and lock files",
|
|
3422
|
+
memory: "Local conversation memory — index transcripts + show stats",
|
|
3423
|
+
"memory index": "Index ~/.claude transcripts into the SQLite memory store",
|
|
3424
|
+
"memory search": "Full-text search memory (current project; --global for all)",
|
|
3425
|
+
"memory stats": "Show what the local memory store contains",
|
|
3426
|
+
"memory merge": "Merge another machine's memory.db into this one (dedup by uuid)",
|
|
3427
|
+
"memory install": "Wire UserPromptSubmit + SessionEnd + SessionStart (recovery) hooks into ~/.claude/settings.json",
|
|
3428
|
+
"memory scan": "Scan the memory store for stored secrets (exit 1 if any found)",
|
|
3429
|
+
"memory backup": "Encrypted backup of the memory store (AES-256-GCM; KIT_MEMORY_PASSPHRASE)",
|
|
3430
|
+
"memory restore": "Restore an encrypted memory backup (e.g. on a new machine)",
|
|
3431
|
+
"memory share": "Promote a curated, secret-scanned entry to the shared (team) memory",
|
|
3432
|
+
"memory areas": "List shared responsibility areas (stripe, whatsapp, …)",
|
|
3433
|
+
"memory area": "Show shared entries for one area (decisions, how-built, status, security)",
|
|
3434
|
+
"memory pal": "Pending action ledger — list/add/done/snooze/verify/import 'blocked-on-you' items",
|
|
3435
|
+
"memory save": "Bookmark the current session as a named copilot",
|
|
3436
|
+
"memory threads": "List saved copilots (current project; --global for all)",
|
|
3437
|
+
"memory resume": "Print the resume command for a saved copilot (by name or number)",
|
|
3394
3438
|
init: "Detect stack, generate .kit.toml, and run full setup",
|
|
3395
3439
|
upgrade: "Update lock files from .kit.toml",
|
|
3396
3440
|
install: "Install missing tools via mise",
|
|
@@ -3858,6 +3902,474 @@ async function showSkippedCommitBanner() {
|
|
|
3858
3902
|
/* banner is best-effort — never break the CLI */
|
|
3859
3903
|
}
|
|
3860
3904
|
}
|
|
3905
|
+
/**
|
|
3906
|
+
* `kit memory` — local conversation memory (SQLite + FTS5). Deterministic and
|
|
3907
|
+
* zero-LLM: it stores raw transcripts and searches them; it never calls a model.
|
|
3908
|
+
*/
|
|
3909
|
+
async function cmdMemory() {
|
|
3910
|
+
const subcommand = process.argv[3];
|
|
3911
|
+
const jsonMode = hasFlag(process.argv, "--json");
|
|
3912
|
+
if (!subcommand || subcommand === "--help" || subcommand === "-h") {
|
|
3913
|
+
console.log("kit memory — local conversation memory (SQLite + FTS5)");
|
|
3914
|
+
console.log("\nUsage:");
|
|
3915
|
+
console.log(" kit memory index Index ~/.claude transcripts into the memory store");
|
|
3916
|
+
console.log(" kit memory search <query> Search memory (current project; --global for all)");
|
|
3917
|
+
console.log(" kit memory stats Show what the memory store contains");
|
|
3918
|
+
console.log(" kit memory merge <file> Merge another machine's memory.db into this one");
|
|
3919
|
+
console.log(" kit memory install Wire the 2 hooks into ~/.claude/settings.json");
|
|
3920
|
+
console.log(" kit memory uninstall Remove the hooks");
|
|
3921
|
+
console.log(" kit memory pal [list|add|done|snooze|verify|import] Pending action ledger");
|
|
3922
|
+
console.log(" kit memory save <name> Bookmark the current session as a named copilot");
|
|
3923
|
+
console.log(" kit memory threads List saved copilots (--global for all)");
|
|
3924
|
+
console.log(" kit memory resume <name|n> Print the resume command for a saved copilot");
|
|
3925
|
+
console.log(" kit memory forget <name> Remove a saved copilot");
|
|
3926
|
+
console.log(" kit memory scan Scan the store for stored secrets");
|
|
3927
|
+
console.log(" kit memory backup <file> Encrypted backup (set KIT_MEMORY_PASSPHRASE)");
|
|
3928
|
+
console.log(" kit memory restore <file> Restore an encrypted backup (new machine)");
|
|
3929
|
+
console.log(" kit memory share … Promote a curated entry to shared (team) memory");
|
|
3930
|
+
console.log(" kit memory areas List shared responsibility areas");
|
|
3931
|
+
console.log(" kit memory area <name> Show shared entries for one area");
|
|
3932
|
+
return true;
|
|
3933
|
+
}
|
|
3934
|
+
if (subcommand === "index") {
|
|
3935
|
+
const db = openMemoryDb();
|
|
3936
|
+
const t0 = Date.now();
|
|
3937
|
+
const byHarness = indexAllHarnesses(db);
|
|
3938
|
+
const ms = Date.now() - t0;
|
|
3939
|
+
db.close();
|
|
3940
|
+
if (jsonMode) {
|
|
3941
|
+
console.log(JSON.stringify({ byHarness, ms }));
|
|
3942
|
+
return true;
|
|
3943
|
+
}
|
|
3944
|
+
let messages = 0;
|
|
3945
|
+
let toolUses = 0;
|
|
3946
|
+
let files = 0;
|
|
3947
|
+
let skipped = 0;
|
|
3948
|
+
for (const r of Object.values(byHarness)) {
|
|
3949
|
+
messages += r.messages;
|
|
3950
|
+
toolUses += r.toolUses;
|
|
3951
|
+
files += r.files;
|
|
3952
|
+
skipped += r.filesSkipped;
|
|
3953
|
+
}
|
|
3954
|
+
console.log(`${c.green}✓${c.reset} indexed ${c.bold}${messages}${c.reset} messages + ${toolUses} tool-uses from ${files} sessions${skipped ? `, ${skipped} unchanged` : ""} ${c.dim}(${ms}ms)${c.reset}`);
|
|
3955
|
+
for (const [harness, r] of Object.entries(byHarness)) {
|
|
3956
|
+
if (r.files || r.messages) {
|
|
3957
|
+
console.log(` ${c.dim}${harness}: ${r.messages} msg · ${r.files} sessions${r.filesSkipped ? ` · ${r.filesSkipped} unchanged` : ""}${c.reset}`);
|
|
3958
|
+
}
|
|
3959
|
+
}
|
|
3960
|
+
return true;
|
|
3961
|
+
}
|
|
3962
|
+
if (subcommand === "merge") {
|
|
3963
|
+
const sourcePath = process.argv[4];
|
|
3964
|
+
if (!sourcePath) {
|
|
3965
|
+
console.error(`${c.red}usage: kit memory merge <other-machine-memory.db>${c.reset}`);
|
|
3966
|
+
return false;
|
|
3967
|
+
}
|
|
3968
|
+
const db = openMemoryDb();
|
|
3969
|
+
try {
|
|
3970
|
+
const r = mergeDb(db, sourcePath);
|
|
3971
|
+
console.log(`${c.green}✓${c.reset} merged ${c.bold}${r.messages}${c.reset} messages + ${r.toolUses} tool-uses · ${r.sessions} sessions · ${r.pending} pending · ${r.threads} copilots ${c.dim}from ${sourcePath}${c.reset}`);
|
|
3972
|
+
}
|
|
3973
|
+
catch (err) {
|
|
3974
|
+
db.close();
|
|
3975
|
+
console.error(`${c.red}${err.message}${c.reset}`);
|
|
3976
|
+
return false;
|
|
3977
|
+
}
|
|
3978
|
+
db.close();
|
|
3979
|
+
return true;
|
|
3980
|
+
}
|
|
3981
|
+
if (subcommand === "stats") {
|
|
3982
|
+
const db = openMemoryDb();
|
|
3983
|
+
const s = getStats(db);
|
|
3984
|
+
db.close();
|
|
3985
|
+
if (jsonMode) {
|
|
3986
|
+
console.log(JSON.stringify(s));
|
|
3987
|
+
return true;
|
|
3988
|
+
}
|
|
3989
|
+
console.log(`${c.bold}kit memory${c.reset} ${c.dim}${s.dbPath}${c.reset}`);
|
|
3990
|
+
console.log(` sessions ${s.sessions}`);
|
|
3991
|
+
console.log(` messages ${s.messages}`);
|
|
3992
|
+
console.log(` tool-uses ${s.toolUses}`);
|
|
3993
|
+
console.log(` pending ${s.pendingOpen} ${c.dim}(open action items)${c.reset}`);
|
|
3994
|
+
console.log(` size ${Math.round(s.sizeBytes / 1024)} KB`);
|
|
3995
|
+
return true;
|
|
3996
|
+
}
|
|
3997
|
+
if (subcommand === "search") {
|
|
3998
|
+
const terms = process.argv.slice(4).filter((a) => !a.startsWith("--"));
|
|
3999
|
+
const query = terms.join(" ").trim();
|
|
4000
|
+
if (!query) {
|
|
4001
|
+
console.error(`${c.red}usage: kit memory search <query> [--global] [--project=<path>] [--limit=N]${c.reset}`);
|
|
4002
|
+
return false;
|
|
4003
|
+
}
|
|
4004
|
+
const limit = Number(flagValue(process.argv, "--limit") ?? "20") || 20;
|
|
4005
|
+
const projectPath = hasFlag(process.argv, "--global")
|
|
4006
|
+
? undefined
|
|
4007
|
+
: (flagValue(process.argv, "--project") ?? getCurrentProjectRoot());
|
|
4008
|
+
const db = openMemoryDb();
|
|
4009
|
+
const hits = searchMessages(db, query, { limit, projectPath });
|
|
4010
|
+
db.close();
|
|
4011
|
+
if (jsonMode) {
|
|
4012
|
+
console.log(JSON.stringify(hits));
|
|
4013
|
+
return true;
|
|
4014
|
+
}
|
|
4015
|
+
const scope = projectPath ? `${c.dim}in ${projectPath}${c.reset}` : `${c.dim}(global)${c.reset}`;
|
|
4016
|
+
if (!hits.length) {
|
|
4017
|
+
console.log(`${c.dim}no matches for "${query}" ${projectPath ?? "(global)"}${c.reset}`);
|
|
4018
|
+
return true;
|
|
4019
|
+
}
|
|
4020
|
+
console.log(`${c.bold}${hits.length}${c.reset} match(es) ${scope}`);
|
|
4021
|
+
for (const h of hits) {
|
|
4022
|
+
const snippet = (h.content ?? "").replace(/\s+/g, " ").slice(0, 120);
|
|
4023
|
+
console.log(` ${c.dim}${h.timestamp ?? "?"}${c.reset} ${c.bold}${h.role ?? h.uuid ?? ""}${c.reset} ${snippet}`);
|
|
4024
|
+
}
|
|
4025
|
+
return true;
|
|
4026
|
+
}
|
|
4027
|
+
if (subcommand === "hook") {
|
|
4028
|
+
// Internal: invoked by Claude Code hooks. Fail-open — never block.
|
|
4029
|
+
const event = process.argv[4];
|
|
4030
|
+
if (event === "user-prompt-submit") {
|
|
4031
|
+
const text = userPromptSubmitReminder();
|
|
4032
|
+
if (text)
|
|
4033
|
+
console.log(text);
|
|
4034
|
+
return true;
|
|
4035
|
+
}
|
|
4036
|
+
if (event === "session-end") {
|
|
4037
|
+
runSessionEndIndex();
|
|
4038
|
+
return true;
|
|
4039
|
+
}
|
|
4040
|
+
if (event === "session-start") {
|
|
4041
|
+
const text = sessionStartRecovery();
|
|
4042
|
+
if (text)
|
|
4043
|
+
console.log(text);
|
|
4044
|
+
return true;
|
|
4045
|
+
}
|
|
4046
|
+
console.error(`${c.red}Unknown hook event: ${event ?? "(none)"}${c.reset}`);
|
|
4047
|
+
return false;
|
|
4048
|
+
}
|
|
4049
|
+
if (subcommand === "install") {
|
|
4050
|
+
const { added, alreadyPresent } = installMemoryHooks();
|
|
4051
|
+
for (const e of added)
|
|
4052
|
+
console.log(`${c.green}✓${c.reset} installed ${e} hook`);
|
|
4053
|
+
for (const e of alreadyPresent)
|
|
4054
|
+
console.log(`${c.dim}• ${e} hook already present${c.reset}`);
|
|
4055
|
+
console.log(`${c.dim}settings: ${getClaudeSettingsPath()}${c.reset}`);
|
|
4056
|
+
return true;
|
|
4057
|
+
}
|
|
4058
|
+
if (subcommand === "uninstall") {
|
|
4059
|
+
const { removed } = uninstallMemoryHooks();
|
|
4060
|
+
if (removed.length) {
|
|
4061
|
+
for (const e of removed)
|
|
4062
|
+
console.log(`${c.green}✓${c.reset} removed ${e} hook`);
|
|
4063
|
+
}
|
|
4064
|
+
else {
|
|
4065
|
+
console.log(`${c.dim}no kit memory hooks were installed${c.reset}`);
|
|
4066
|
+
}
|
|
4067
|
+
return true;
|
|
4068
|
+
}
|
|
4069
|
+
if (subcommand === "share") {
|
|
4070
|
+
const area = flagValue(process.argv, "--area");
|
|
4071
|
+
const title = flagValue(process.argv, "--title");
|
|
4072
|
+
const kind = (flagValue(process.argv, "--kind") ?? "note");
|
|
4073
|
+
const body = flagValue(process.argv, "--body") ?? "";
|
|
4074
|
+
const ref = flagValue(process.argv, "--ref");
|
|
4075
|
+
if (!area || !title) {
|
|
4076
|
+
console.error(`${c.red}usage: kit memory share --area <a> --title <t> [--kind decision|convention|how-built|status|security|note] [--body <b>] [--ref <r>]${c.reset}`);
|
|
4077
|
+
return false;
|
|
4078
|
+
}
|
|
4079
|
+
const root = getCurrentProjectRoot();
|
|
4080
|
+
try {
|
|
4081
|
+
const e = shareEntry(root, { area, kind, title, body, refs: ref ? [ref] : [] }, new Date().toISOString());
|
|
4082
|
+
console.log(`${c.green}✓${c.reset} shared ${c.bold}${e.id}${c.reset} to area ${c.bold}${area}${c.reset} ${c.dim}(${getSharedPath(root)})${c.reset}`);
|
|
4083
|
+
console.log(`${c.dim}commit .kit/shared/memory.jsonl + open a PR — shared memory is reviewed like code${c.reset}`);
|
|
4084
|
+
}
|
|
4085
|
+
catch (err) {
|
|
4086
|
+
console.error(`${c.red}${err.message}${c.reset}`);
|
|
4087
|
+
return false;
|
|
4088
|
+
}
|
|
4089
|
+
return true;
|
|
4090
|
+
}
|
|
4091
|
+
if (subcommand === "areas") {
|
|
4092
|
+
const areas = listAreas(getCurrentProjectRoot());
|
|
4093
|
+
if (jsonMode) {
|
|
4094
|
+
console.log(JSON.stringify(areas));
|
|
4095
|
+
return true;
|
|
4096
|
+
}
|
|
4097
|
+
if (!areas.length) {
|
|
4098
|
+
console.log(`${c.dim}no shared areas yet — add one with kit memory share${c.reset}`);
|
|
4099
|
+
return true;
|
|
4100
|
+
}
|
|
4101
|
+
console.log(`${c.bold}${areas.length}${c.reset} responsibility area(s):`);
|
|
4102
|
+
for (const a of areas) {
|
|
4103
|
+
console.log(` ${c.bold}${a.area}${c.reset} ${c.dim}· ${a.count} entr${a.count === 1 ? "y" : "ies"}${c.reset}`);
|
|
4104
|
+
}
|
|
4105
|
+
return true;
|
|
4106
|
+
}
|
|
4107
|
+
if (subcommand === "area") {
|
|
4108
|
+
const name = process.argv[4];
|
|
4109
|
+
if (!name) {
|
|
4110
|
+
console.error(`${c.red}usage: kit memory area <name>${c.reset}`);
|
|
4111
|
+
return false;
|
|
4112
|
+
}
|
|
4113
|
+
const entries = queryArea(getCurrentProjectRoot(), name);
|
|
4114
|
+
if (jsonMode) {
|
|
4115
|
+
console.log(JSON.stringify(entries));
|
|
4116
|
+
return true;
|
|
4117
|
+
}
|
|
4118
|
+
if (!entries.length) {
|
|
4119
|
+
console.log(`${c.dim}no shared memory for area '${name}'${c.reset}`);
|
|
4120
|
+
return true;
|
|
4121
|
+
}
|
|
4122
|
+
console.log(`${c.bold}${name}${c.reset} ${c.dim}· ${entries.length} entr${entries.length === 1 ? "y" : "ies"}${c.reset}`);
|
|
4123
|
+
for (const e of entries) {
|
|
4124
|
+
const prov = `${e.author}${e.source_ref ? ` @${e.source_ref}` : ""}`;
|
|
4125
|
+
console.log(` ${c.bold}[${e.kind}]${c.reset} ${e.title} ${c.dim}— ${prov}${c.reset}`);
|
|
4126
|
+
if (e.body)
|
|
4127
|
+
console.log(` ${e.body}`);
|
|
4128
|
+
if (e.refs.length)
|
|
4129
|
+
console.log(` ${c.dim}refs: ${e.refs.join(", ")}${c.reset}`);
|
|
4130
|
+
}
|
|
4131
|
+
return true;
|
|
4132
|
+
}
|
|
4133
|
+
if (subcommand === "scan") {
|
|
4134
|
+
const db = openMemoryDb();
|
|
4135
|
+
const findings = scanDbForSecrets(db);
|
|
4136
|
+
db.close();
|
|
4137
|
+
if (jsonMode) {
|
|
4138
|
+
console.log(JSON.stringify(findings));
|
|
4139
|
+
return !findings.some((f) => f.confidence === "high");
|
|
4140
|
+
}
|
|
4141
|
+
if (!findings.length) {
|
|
4142
|
+
console.log(`${c.green}✓${c.reset} no stored secrets found in the memory store`);
|
|
4143
|
+
return true;
|
|
4144
|
+
}
|
|
4145
|
+
const high = findings.filter((f) => f.confidence === "high");
|
|
4146
|
+
const heuristic = findings.filter((f) => f.confidence === "heuristic");
|
|
4147
|
+
const times = (n) => (n > 1 ? ` ×${n}` : "");
|
|
4148
|
+
if (high.length) {
|
|
4149
|
+
console.log(`${c.red}⚠ ${high.length} high-confidence secret(s):${c.reset}`);
|
|
4150
|
+
for (const f of high) {
|
|
4151
|
+
const proj = f.projects.length ? `${c.bold}[${f.projects.join(", ")}]${c.reset}${c.dim} · ` : "";
|
|
4152
|
+
console.log(` ${c.bold}${f.label}${c.reset} ${c.dim}${f.preview}${times(f.count)} · ${proj}${f.sample}${c.reset}`);
|
|
4153
|
+
}
|
|
4154
|
+
}
|
|
4155
|
+
else {
|
|
4156
|
+
console.log(`${c.green}✓${c.reset} no high-confidence secrets`);
|
|
4157
|
+
}
|
|
4158
|
+
if (heuristic.length) {
|
|
4159
|
+
const showAll = hasFlag(process.argv, "--all");
|
|
4160
|
+
if (showAll) {
|
|
4161
|
+
console.log(`${c.dim}${heuristic.length} heuristic match(es) (KEY=value patterns — usually env vars / paths):${c.reset}`);
|
|
4162
|
+
for (const f of heuristic) {
|
|
4163
|
+
console.log(` ${c.dim}${f.label} ${f.preview}${times(f.count)} · ${f.sample}${c.reset}`);
|
|
4164
|
+
}
|
|
4165
|
+
}
|
|
4166
|
+
else {
|
|
4167
|
+
console.log(`${c.dim}+ ${heuristic.length} heuristic match(es) (likely env vars / paths) — run with --all to see${c.reset}`);
|
|
4168
|
+
}
|
|
4169
|
+
}
|
|
4170
|
+
return high.length === 0; // exit non-zero only on high-confidence findings
|
|
4171
|
+
}
|
|
4172
|
+
if (subcommand === "backup") {
|
|
4173
|
+
const out = process.argv[4];
|
|
4174
|
+
const pass = process.env.KIT_MEMORY_PASSPHRASE ?? flagValue(process.argv, "--passphrase");
|
|
4175
|
+
if (!out) {
|
|
4176
|
+
console.error(`${c.red}usage: kit memory backup <file> (set KIT_MEMORY_PASSPHRASE)${c.reset}`);
|
|
4177
|
+
return false;
|
|
4178
|
+
}
|
|
4179
|
+
if (!pass) {
|
|
4180
|
+
console.error(`${c.red}set KIT_MEMORY_PASSPHRASE (or --passphrase) — the key is never stored${c.reset}`);
|
|
4181
|
+
return false;
|
|
4182
|
+
}
|
|
4183
|
+
try {
|
|
4184
|
+
backupEncrypted(pass, getMemoryDbPath(), out);
|
|
4185
|
+
}
|
|
4186
|
+
catch (err) {
|
|
4187
|
+
console.error(`${c.red}${err.message}${c.reset}`);
|
|
4188
|
+
return false;
|
|
4189
|
+
}
|
|
4190
|
+
console.log(`${c.green}✓${c.reset} encrypted backup → ${out} ${c.dim}(AES-256-GCM · scrypt)${c.reset}`);
|
|
4191
|
+
return true;
|
|
4192
|
+
}
|
|
4193
|
+
if (subcommand === "restore") {
|
|
4194
|
+
const inFile = process.argv[4];
|
|
4195
|
+
const pass = process.env.KIT_MEMORY_PASSPHRASE ?? flagValue(process.argv, "--passphrase");
|
|
4196
|
+
if (!inFile) {
|
|
4197
|
+
console.error(`${c.red}usage: kit memory restore <file> [--to <path>] [--force]${c.reset}`);
|
|
4198
|
+
return false;
|
|
4199
|
+
}
|
|
4200
|
+
if (!pass) {
|
|
4201
|
+
console.error(`${c.red}set KIT_MEMORY_PASSPHRASE (or --passphrase)${c.reset}`);
|
|
4202
|
+
return false;
|
|
4203
|
+
}
|
|
4204
|
+
const dest = flagValue(process.argv, "--to") ?? getMemoryDbPath();
|
|
4205
|
+
if (existsSync(dest) && !hasFlag(process.argv, "--force")) {
|
|
4206
|
+
console.error(`${c.red}${dest} exists — pass --force to overwrite${c.reset}`);
|
|
4207
|
+
return false;
|
|
4208
|
+
}
|
|
4209
|
+
try {
|
|
4210
|
+
restoreEncrypted(pass, inFile, dest);
|
|
4211
|
+
}
|
|
4212
|
+
catch {
|
|
4213
|
+
console.error(`${c.red}restore failed — wrong passphrase or corrupt backup${c.reset}`);
|
|
4214
|
+
return false;
|
|
4215
|
+
}
|
|
4216
|
+
console.log(`${c.green}✓${c.reset} restored → ${dest}`);
|
|
4217
|
+
return true;
|
|
4218
|
+
}
|
|
4219
|
+
if (subcommand === "save") {
|
|
4220
|
+
const name = process.argv.slice(4).filter((a) => !a.startsWith("--")).join(" ").trim();
|
|
4221
|
+
if (!name) {
|
|
4222
|
+
console.error(`${c.red}usage: kit memory save <name> [--session=<id>]${c.reset}`);
|
|
4223
|
+
return false;
|
|
4224
|
+
}
|
|
4225
|
+
const root = getCurrentProjectRoot();
|
|
4226
|
+
const db = openMemoryDb();
|
|
4227
|
+
const sessionId = flagValue(process.argv, "--session") ?? latestSessionId(db, { projectPath: root });
|
|
4228
|
+
if (!sessionId) {
|
|
4229
|
+
db.close();
|
|
4230
|
+
console.error(`${c.red}no session found for ${root} — index first or pass --session=<id>${c.reset}`);
|
|
4231
|
+
return false;
|
|
4232
|
+
}
|
|
4233
|
+
saveThread(db, { name, sessionId, projectPath: root });
|
|
4234
|
+
db.close();
|
|
4235
|
+
console.log(`${c.green}✓${c.reset} saved copilot ${c.bold}${name}${c.reset} ${c.dim}→ ${sessionId}${c.reset}`);
|
|
4236
|
+
return true;
|
|
4237
|
+
}
|
|
4238
|
+
if (subcommand === "threads") {
|
|
4239
|
+
const projectPath = hasFlag(process.argv, "--global") ? undefined : getCurrentProjectRoot();
|
|
4240
|
+
const db = openMemoryDb();
|
|
4241
|
+
const list = listThreads(db, { projectPath });
|
|
4242
|
+
db.close();
|
|
4243
|
+
if (jsonMode) {
|
|
4244
|
+
console.log(JSON.stringify(list));
|
|
4245
|
+
return true;
|
|
4246
|
+
}
|
|
4247
|
+
if (!list.length) {
|
|
4248
|
+
console.log(`${c.dim}no saved copilots${projectPath ? ` in ${projectPath}` : ""}${c.reset}`);
|
|
4249
|
+
return true;
|
|
4250
|
+
}
|
|
4251
|
+
const scope = projectPath ? `${c.dim}in ${projectPath}${c.reset}` : `${c.dim}(global)${c.reset}`;
|
|
4252
|
+
console.log(`${c.bold}${list.length}${c.reset} saved copilot(s) ${scope}:`);
|
|
4253
|
+
list.forEach((t, i) => {
|
|
4254
|
+
console.log(` ${c.bold}${i + 1}${c.reset}. ${t.name} ${c.dim}${t.session_id}${c.reset}`);
|
|
4255
|
+
});
|
|
4256
|
+
console.log(`${c.dim}resume with: kit memory resume <name|number>${c.reset}`);
|
|
4257
|
+
return true;
|
|
4258
|
+
}
|
|
4259
|
+
if (subcommand === "resume") {
|
|
4260
|
+
const ref = process.argv[4];
|
|
4261
|
+
if (!ref) {
|
|
4262
|
+
console.error(`${c.red}usage: kit memory resume <name|number>${c.reset}`);
|
|
4263
|
+
return false;
|
|
4264
|
+
}
|
|
4265
|
+
const projectPath = hasFlag(process.argv, "--global") ? undefined : getCurrentProjectRoot();
|
|
4266
|
+
const db = openMemoryDb();
|
|
4267
|
+
const t = resolveThread(db, ref, { projectPath });
|
|
4268
|
+
db.close();
|
|
4269
|
+
if (!t) {
|
|
4270
|
+
console.error(`${c.red}no saved copilot '${ref}'${c.reset}`);
|
|
4271
|
+
return false;
|
|
4272
|
+
}
|
|
4273
|
+
console.log(`${c.bold}${t.name}${c.reset} — run:`);
|
|
4274
|
+
console.log(` claude --resume ${t.session_id}`);
|
|
4275
|
+
return true;
|
|
4276
|
+
}
|
|
4277
|
+
if (subcommand === "forget") {
|
|
4278
|
+
const name = process.argv.slice(4).filter((a) => !a.startsWith("--")).join(" ").trim();
|
|
4279
|
+
if (!name) {
|
|
4280
|
+
console.error(`${c.red}usage: kit memory forget <name>${c.reset}`);
|
|
4281
|
+
return false;
|
|
4282
|
+
}
|
|
4283
|
+
const db = openMemoryDb();
|
|
4284
|
+
const ok = removeThread(db, name);
|
|
4285
|
+
db.close();
|
|
4286
|
+
console.log(ok ? `${c.green}✓${c.reset} forgot ${name}` : `${c.dim}no copilot '${name}'${c.reset}`);
|
|
4287
|
+
return true;
|
|
4288
|
+
}
|
|
4289
|
+
if (subcommand === "pal") {
|
|
4290
|
+
const action = process.argv[4] && !process.argv[4].startsWith("--") ? process.argv[4] : "list";
|
|
4291
|
+
const db = openMemoryDb();
|
|
4292
|
+
try {
|
|
4293
|
+
if (action === "list") {
|
|
4294
|
+
const scope = hasFlag(process.argv, "--global")
|
|
4295
|
+
? undefined
|
|
4296
|
+
: basename(getCurrentProjectRoot());
|
|
4297
|
+
const items = palList(db, { scope });
|
|
4298
|
+
if (jsonMode) {
|
|
4299
|
+
console.log(JSON.stringify(items));
|
|
4300
|
+
return true;
|
|
4301
|
+
}
|
|
4302
|
+
if (!items.length) {
|
|
4303
|
+
console.log(`${c.dim}no open action items${c.reset}`);
|
|
4304
|
+
return true;
|
|
4305
|
+
}
|
|
4306
|
+
console.log(`${c.bold}${items.length}${c.reset} open action item(s):`);
|
|
4307
|
+
for (const p of items) {
|
|
4308
|
+
const tag = p.kind === "auto" ? ` ${c.dim}· auto${c.reset}` : "";
|
|
4309
|
+
const scope = p.scope ? ` ${c.dim}[${p.scope}]${c.reset}` : "";
|
|
4310
|
+
console.log(` ${c.bold}${p.id}${c.reset} ${p.title}${scope}${tag}`);
|
|
4311
|
+
}
|
|
4312
|
+
return true;
|
|
4313
|
+
}
|
|
4314
|
+
if (action === "add") {
|
|
4315
|
+
const title = process.argv.slice(5).filter((a) => !a.startsWith("--")).join(" ").trim();
|
|
4316
|
+
if (!title) {
|
|
4317
|
+
console.error(`${c.red}usage: kit memory pal add <title> [--verify=<cmd>] [--scope=<s>]${c.reset}`);
|
|
4318
|
+
return false;
|
|
4319
|
+
}
|
|
4320
|
+
const id = palAdd(db, {
|
|
4321
|
+
title,
|
|
4322
|
+
verifyCmd: flagValue(process.argv, "--verify"),
|
|
4323
|
+
scope: flagValue(process.argv, "--scope") ?? basename(getCurrentProjectRoot()),
|
|
4324
|
+
});
|
|
4325
|
+
console.log(`${c.green}✓${c.reset} added ${c.bold}${id}${c.reset}`);
|
|
4326
|
+
return true;
|
|
4327
|
+
}
|
|
4328
|
+
if (action === "done") {
|
|
4329
|
+
const id = process.argv[5];
|
|
4330
|
+
if (!id) {
|
|
4331
|
+
console.error(`${c.red}usage: kit memory pal done <id>${c.reset}`);
|
|
4332
|
+
return false;
|
|
4333
|
+
}
|
|
4334
|
+
console.log(palDone(db, id)
|
|
4335
|
+
? `${c.green}✓${c.reset} closed ${id}`
|
|
4336
|
+
: `${c.dim}${id} not found or already closed${c.reset}`);
|
|
4337
|
+
return true;
|
|
4338
|
+
}
|
|
4339
|
+
if (action === "snooze") {
|
|
4340
|
+
const id = process.argv[5];
|
|
4341
|
+
const days = Number(process.argv[6] ?? "7") || 7;
|
|
4342
|
+
if (!id) {
|
|
4343
|
+
console.error(`${c.red}usage: kit memory pal snooze <id> [days]${c.reset}`);
|
|
4344
|
+
return false;
|
|
4345
|
+
}
|
|
4346
|
+
console.log(palSnooze(db, id, days)
|
|
4347
|
+
? `${c.green}✓${c.reset} snoozed ${id} for ${days}d`
|
|
4348
|
+
: `${c.dim}${id} not found${c.reset}`);
|
|
4349
|
+
return true;
|
|
4350
|
+
}
|
|
4351
|
+
if (action === "verify") {
|
|
4352
|
+
const r = palAutoVerify(db);
|
|
4353
|
+
console.log(`${c.dim}checked ${r.checked} · closed ${r.closed.length} · reopened ${r.reopened.length}${c.reset}`);
|
|
4354
|
+
return true;
|
|
4355
|
+
}
|
|
4356
|
+
if (action === "import") {
|
|
4357
|
+
const r = importLegacyLedger(db);
|
|
4358
|
+
console.log(`${c.green}✓${c.reset} imported ${r.imported} item(s) from the legacy ledger`);
|
|
4359
|
+
return true;
|
|
4360
|
+
}
|
|
4361
|
+
console.error(`${c.red}Unknown pal action: ${action}${c.reset}`);
|
|
4362
|
+
console.error("Use: kit memory pal [list|add|done|snooze|verify|import]");
|
|
4363
|
+
return false;
|
|
4364
|
+
}
|
|
4365
|
+
finally {
|
|
4366
|
+
db.close();
|
|
4367
|
+
}
|
|
4368
|
+
}
|
|
4369
|
+
console.error(`${c.red}Unknown memory subcommand: ${subcommand}${c.reset}`);
|
|
4370
|
+
console.error("Use: kit memory index | search <query> | stats | install | uninstall | pal");
|
|
4371
|
+
return false;
|
|
4372
|
+
}
|
|
3861
4373
|
async function main() {
|
|
3862
4374
|
const args = process.argv.slice(2);
|
|
3863
4375
|
const command = args[0];
|
|
@@ -3926,6 +4438,9 @@ async function main() {
|
|
|
3926
4438
|
ok = true;
|
|
3927
4439
|
break;
|
|
3928
4440
|
}
|
|
4441
|
+
case "status":
|
|
4442
|
+
ok = await cmdStatus();
|
|
4443
|
+
break;
|
|
3929
4444
|
case "whoami":
|
|
3930
4445
|
ok = await cmdWhoami();
|
|
3931
4446
|
break;
|
|
@@ -4032,6 +4547,9 @@ async function main() {
|
|
|
4032
4547
|
case "team":
|
|
4033
4548
|
ok = await cmdTeam();
|
|
4034
4549
|
break;
|
|
4550
|
+
case "memory":
|
|
4551
|
+
ok = await cmdMemory();
|
|
4552
|
+
break;
|
|
4035
4553
|
default: {
|
|
4036
4554
|
console.error(`Unknown command: ${command}`);
|
|
4037
4555
|
const { didYouMean } = await import("./utils/didYouMean.js");
|