@burtson-labs/host-kit 0.3.2 → 0.4.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 +5 -3
- package/dist/hooks.d.ts +9 -1
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +19 -1
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -2
- package/dist/index.js.map +1 -1
- package/dist/memory.d.ts +64 -1
- package/dist/memory.d.ts.map +1 -1
- package/dist/memory.js +179 -3
- package/dist/memory.js.map +1 -1
- package/dist/memoryIndex.d.ts +35 -1
- package/dist/memoryIndex.d.ts.map +1 -1
- package/dist/memoryIndex.js +207 -23
- package/dist/memoryIndex.js.map +1 -1
- package/dist/securityGuard.d.ts +29 -0
- package/dist/securityGuard.d.ts.map +1 -0
- package/dist/securityGuard.js +164 -0
- package/dist/securityGuard.js.map +1 -0
- package/dist/tools/readMemoryTool.d.ts.map +1 -1
- package/dist/tools/readMemoryTool.js +11 -9
- package/dist/tools/readMemoryTool.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
<a href="https://burtson.ai">
|
|
3
3
|
<picture>
|
|
4
|
-
<img src="https://cdn.burtson.ai/logos/
|
|
4
|
+
<img src="https://cdn.burtson.ai/logos/burtson-labs-logo.png" alt="Burtson Labs" width="200" style="width: 200px !important; max-width: 200px !important; height: auto; display: inline-block;" />
|
|
5
5
|
</picture>
|
|
6
6
|
</a>
|
|
7
7
|
|
|
@@ -22,9 +22,11 @@ pnpm add @burtson-labs/host-kit
|
|
|
22
22
|
|
|
23
23
|
## <img src="https://api.iconify.design/lucide/puzzle.svg?color=%23a60ee5&width=22" align="absmiddle"> What's in the box
|
|
24
24
|
|
|
25
|
-
- **Memory loader** — discovers and merges `BANDIT.md` / `CLAUDE.md` / `AGENTS.md` files across workspace + global locations
|
|
25
|
+
- **Memory loader** — discovers and merges `BANDIT.md` / `CLAUDE.md` / `AGENTS.md` files across workspace + global locations; deduplicates overlapping content at load time; `consolidateMemory()` unifies multiple entry files into a single canonical `BANDIT.md` (symlink on macOS/Linux, copy-with-drift-warning on Windows)
|
|
26
|
+
- **Topic memory** — lazy-load index at `.bandit/memory/MEMORY.md` (preferred) with back-compat reads from legacy root `MEMORY.md`; writes always go to `.bandit/memory/`; `migrateMemoryToBanditDir()` moves an existing root `memory/` layout into `.bandit/memory/` idempotently
|
|
26
27
|
- **`@-mention` expansion** — detects `@path/to/file` in user input and inlines file contents (with secret redaction) or attaches images as base64
|
|
27
|
-
- **Hook runner** — executes PreToolUse / PostToolUse / Stop / UserPromptSubmit hooks
|
|
28
|
+
- **Hook runner** — executes PreToolUse / PostToolUse / Stop / UserPromptSubmit hooks; `loadHookSettings` merges the **global** `~/.bandit/settings.json` under the workspace `.bandit/settings.json` so hooks + permissions + the guard apply across every repo
|
|
29
|
+
- **Pre-tool security guard** — `evaluateSecurityGuard(call, settings, ctx)`: an opt-in, in-process safety net (no shell spawn) that blocks catastrophic tool calls (`rm -rf /`, `curl … | sh`, disk wipes, credential exfil, writes to system/credential paths) before they run. Wired into `beforeToolExecute` in both hosts
|
|
28
30
|
- **MCP loader** — reads `mcp-servers.json` (global + workspace, workspace wins), auto-injects `BANDIT_API_KEY`, registers servers with the pool
|
|
29
31
|
- **Turn trace reader** — parses workspace and global `.bandit/turns/*.jsonl` into summaries and markdown timelines for CLI `/trace`, IDE `/trace`, tests, and future bug-bundle export
|
|
30
32
|
- **Insights** — usage analytics aggregator (CLI sessions → human report)
|
package/dist/hooks.d.ts
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* PreToolUse / PostToolUse provide: name, primary (first param value), duration (ms, Post only).
|
|
16
16
|
* - A non-zero exit code from a PreToolUse hook aborts the tool call.
|
|
17
17
|
*/
|
|
18
|
+
import type { SecurityGuardSettings } from './securityGuard';
|
|
18
19
|
export type HookEvent = 'PreToolUse' | 'PostToolUse' | 'Stop';
|
|
19
20
|
export interface HookRule {
|
|
20
21
|
match?: string;
|
|
@@ -29,8 +30,15 @@ export interface PermissionsBlock {
|
|
|
29
30
|
export interface HookSettings {
|
|
30
31
|
hooks?: Partial<Record<HookEvent, HookRule[]>>;
|
|
31
32
|
permissions?: PermissionsBlock;
|
|
33
|
+
/** Built-in pre-tool security guard (opt-in, off by default). Read under
|
|
34
|
+
* `security.guard`. See securityGuard.ts. */
|
|
35
|
+
security?: {
|
|
36
|
+
guard?: SecurityGuardSettings;
|
|
37
|
+
};
|
|
32
38
|
}
|
|
33
|
-
export declare function loadHookSettings(cwd: string
|
|
39
|
+
export declare function loadHookSettings(cwd: string, opts?: {
|
|
40
|
+
homeDir?: string;
|
|
41
|
+
}): Promise<HookSettings>;
|
|
34
42
|
/**
|
|
35
43
|
* Persist an entry in the workspace settings.json permissions.allow list.
|
|
36
44
|
* Called when the user picks "Always allow" in a permission prompt and wants
|
package/dist/hooks.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,aAAa,GAAG,MAAM,CAAC;AAE9D,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;IAC/C,WAAW,CAAC,EAAE,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAMH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAE7D,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,aAAa,GAAG,MAAM,CAAC;AAE9D,MAAM,WAAW,QAAQ;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;IAC/C,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAC/B;kDAC8C;IAC9C,QAAQ,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,qBAAqB,CAAA;KAAE,CAAC;CAC9C;AAID,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CA0CtG;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBjF;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,YAAY,EACtB,GAAG,EAAE,WAAW,EAChB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,UAAU,EAAE,CAAC,CAYvB"}
|
package/dist/hooks.js
CHANGED
|
@@ -56,9 +56,16 @@ exports.runHooks = runHooks;
|
|
|
56
56
|
const cp = __importStar(require("child_process"));
|
|
57
57
|
const fs = __importStar(require("fs"));
|
|
58
58
|
const path = __importStar(require("path"));
|
|
59
|
+
const os = __importStar(require("os"));
|
|
59
60
|
const DEFAULT_TIMEOUT_MS = 10000;
|
|
60
|
-
async function loadHookSettings(cwd) {
|
|
61
|
+
async function loadHookSettings(cwd, opts) {
|
|
62
|
+
// Global (~/.bandit) first, then workspace, then workspace .local — later
|
|
63
|
+
// files extend the earlier ones (hook/permission arrays concatenate; the
|
|
64
|
+
// security guard's scalar fields take the last value defined). This is what
|
|
65
|
+
// makes a user's GLOBAL hooks + guard apply to every repo, with per-project
|
|
66
|
+
// overrides on top. `opts.homeDir` overrides the global location (tests).
|
|
61
67
|
const candidates = [
|
|
68
|
+
path.join(opts?.homeDir ?? os.homedir(), '.bandit', 'settings.json'),
|
|
62
69
|
path.resolve(cwd, '.bandit/settings.json'),
|
|
63
70
|
path.resolve(cwd, '.bandit/settings.local.json')
|
|
64
71
|
];
|
|
@@ -77,6 +84,17 @@ async function loadHookSettings(cwd) {
|
|
|
77
84
|
merged.permissions.deny = [...(merged.permissions.deny ?? []), ...(parsed.permissions.deny ?? [])];
|
|
78
85
|
merged.permissions.ask = [...(merged.permissions.ask ?? []), ...(parsed.permissions.ask ?? [])];
|
|
79
86
|
}
|
|
87
|
+
if (parsed.security?.guard) {
|
|
88
|
+
const g = parsed.security.guard;
|
|
89
|
+
const cur = merged.security?.guard ?? {};
|
|
90
|
+
merged.security = {
|
|
91
|
+
guard: {
|
|
92
|
+
enabled: g.enabled ?? cur.enabled,
|
|
93
|
+
blockCommands: [...(cur.blockCommands ?? []), ...(g.blockCommands ?? [])],
|
|
94
|
+
protectPaths: [...(cur.protectPaths ?? []), ...(g.protectPaths ?? [])]
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
}
|
|
80
98
|
}
|
|
81
99
|
catch {
|
|
82
100
|
// Missing / invalid — skip silently.
|
package/dist/hooks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;GAgBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
export { loadMemory, loadCombinedMemory, appendMemory, type MemoryBundle } from './memory';
|
|
2
|
-
export { loadMemoryIndex, renderMemoryIndexBlock, MAX_INDEX_BYTES, MAX_MEMORY_FILE_BYTES, MEMORY_DIR, MEMORY_INDEX_FILE, type MemoryIndex, type MemoryIndexEntry, type MemoryWarnFn } from './memoryIndex';
|
|
1
|
+
export { loadMemory, loadCombinedMemory, appendMemory, consolidateMemory, type MemoryBundle, type ConsolidationStrategy, type ConsolidationResult } from './memory';
|
|
2
|
+
export { loadMemoryIndex, renderMemoryIndexBlock, writeMemoryTopic, migrateMemoryToBanditDir, MAX_INDEX_BYTES, MAX_MEMORY_FILE_BYTES, MEMORY_DIR, MEMORY_INDEX_FILE, BANDIT_DIR, BANDIT_MEMORY_DIR, BANDIT_MEMORY_INDEX_FILE, type MemoryIndex, type MemoryIndexEntry, type MemoryWarnFn } from './memoryIndex';
|
|
3
3
|
export { buildReadMemoryTool } from './tools/readMemoryTool';
|
|
4
4
|
export { loadMcpServersConfig, registerMcpServersFromDisk, globalMcpServersPath, persistMcpActivation, addMcpServerToConfig } from './mcp';
|
|
5
5
|
export { buildGitHubServerConfig, looksLikeGitHubToken, buildSlackServerConfig, looksLikeSlackToken, looksLikeSlackTeamId, buildGitLabServerConfig, looksLikeGitLabToken, buildGmailServerConfig, looksLikeGmailCredentialsPath, buildCustomServerConfig } from './mcpConnectors';
|
|
6
6
|
export { loadApprovedMcpFingerprints, approveMcpFingerprint, revokeMcpFingerprint, mcpTrustPath } from './mcpTrust';
|
|
7
7
|
export { loadMcpToolCache, saveMcpToolEntry, pruneMcpToolCache, mcpToolCachePath } from './mcpToolCache';
|
|
8
8
|
export { loadHookSettings, persistAllowEntry, runHooks, type HookEvent, type HookRule, type HookSettings, type HookContext, type HookResult, type PermissionsBlock } from './hooks';
|
|
9
|
+
export { evaluateSecurityGuard, type SecurityGuardSettings, type SecurityGuardContext, type SecurityGuardDecision } from './securityGuard';
|
|
9
10
|
export { expandMentions, type ExpandedPrompt } from './mentions';
|
|
10
11
|
export { TodoStore, buildTodoWriteTool, buildWebFetchTool, buildWebSearchTool, type WebSearchToolOptions, buildRememberTool } from './tools/extraTools';
|
|
11
12
|
export { buildTaskTool, buildCheckTaskTool, buildListTasksTool, type TaskToolOptions } from './tools/taskTool';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.CheckpointStore = exports.isChatCapable = exports.suggestOllamaMatch = exports.listInstalledOllamaModels = exports.formatTurnTraceMarkdown = exports.summarizeTurnTrace = exports.parseTurnLog = exports.readTurnTraceById = exports.readTurnTrace = exports.listTurnTraces = exports.listTurnTraceFiles = exports.previewText = exports.openTurnLog = exports.SessionPermissionStore = exports.mergePolicies = exports.emptyPolicy = exports.evaluatePermission = exports.InMemoryBackgroundTaskStore = exports.buildInsightsAiCallback = exports.buildAiInput = exports.writeInsightsReport = exports.renderInsightsHtml = void 0;
|
|
3
|
+
exports.buildTaskTool = exports.buildRememberTool = exports.buildWebSearchTool = exports.buildWebFetchTool = exports.buildTodoWriteTool = exports.TodoStore = exports.expandMentions = exports.evaluateSecurityGuard = exports.runHooks = exports.persistAllowEntry = exports.loadHookSettings = exports.mcpToolCachePath = exports.pruneMcpToolCache = exports.saveMcpToolEntry = exports.loadMcpToolCache = exports.mcpTrustPath = exports.revokeMcpFingerprint = exports.approveMcpFingerprint = exports.loadApprovedMcpFingerprints = exports.buildCustomServerConfig = exports.looksLikeGmailCredentialsPath = exports.buildGmailServerConfig = exports.looksLikeGitLabToken = exports.buildGitLabServerConfig = exports.looksLikeSlackTeamId = exports.looksLikeSlackToken = exports.buildSlackServerConfig = exports.looksLikeGitHubToken = exports.buildGitHubServerConfig = exports.addMcpServerToConfig = exports.persistMcpActivation = exports.globalMcpServersPath = exports.registerMcpServersFromDisk = exports.loadMcpServersConfig = exports.buildReadMemoryTool = exports.BANDIT_MEMORY_INDEX_FILE = exports.BANDIT_MEMORY_DIR = exports.BANDIT_DIR = exports.MEMORY_INDEX_FILE = exports.MEMORY_DIR = exports.MAX_MEMORY_FILE_BYTES = exports.MAX_INDEX_BYTES = exports.migrateMemoryToBanditDir = exports.writeMemoryTopic = exports.renderMemoryIndexBlock = exports.loadMemoryIndex = exports.consolidateMemory = exports.appendMemory = exports.loadCombinedMemory = exports.loadMemory = void 0;
|
|
4
|
+
exports.CheckpointStore = exports.isChatCapable = exports.suggestOllamaMatch = exports.listInstalledOllamaModels = exports.formatTurnTraceMarkdown = exports.summarizeTurnTrace = exports.parseTurnLog = exports.readTurnTraceById = exports.readTurnTrace = exports.listTurnTraces = exports.listTurnTraceFiles = exports.previewText = exports.openTurnLog = exports.SessionPermissionStore = exports.mergePolicies = exports.emptyPolicy = exports.evaluatePermission = exports.InMemoryBackgroundTaskStore = exports.buildInsightsAiCallback = exports.buildAiInput = exports.writeInsightsReport = exports.renderInsightsHtml = exports.computeInsights = exports.parseTestOutput = exports.buildTestCommand = exports.detectTestFramework = exports.buildTestRunTool = exports.buildListTasksTool = exports.buildCheckTaskTool = void 0;
|
|
5
5
|
var memory_1 = require("./memory");
|
|
6
6
|
Object.defineProperty(exports, "loadMemory", { enumerable: true, get: function () { return memory_1.loadMemory; } });
|
|
7
7
|
Object.defineProperty(exports, "loadCombinedMemory", { enumerable: true, get: function () { return memory_1.loadCombinedMemory; } });
|
|
8
8
|
Object.defineProperty(exports, "appendMemory", { enumerable: true, get: function () { return memory_1.appendMemory; } });
|
|
9
|
+
Object.defineProperty(exports, "consolidateMemory", { enumerable: true, get: function () { return memory_1.consolidateMemory; } });
|
|
9
10
|
var memoryIndex_1 = require("./memoryIndex");
|
|
10
11
|
Object.defineProperty(exports, "loadMemoryIndex", { enumerable: true, get: function () { return memoryIndex_1.loadMemoryIndex; } });
|
|
11
12
|
Object.defineProperty(exports, "renderMemoryIndexBlock", { enumerable: true, get: function () { return memoryIndex_1.renderMemoryIndexBlock; } });
|
|
13
|
+
Object.defineProperty(exports, "writeMemoryTopic", { enumerable: true, get: function () { return memoryIndex_1.writeMemoryTopic; } });
|
|
14
|
+
Object.defineProperty(exports, "migrateMemoryToBanditDir", { enumerable: true, get: function () { return memoryIndex_1.migrateMemoryToBanditDir; } });
|
|
12
15
|
Object.defineProperty(exports, "MAX_INDEX_BYTES", { enumerable: true, get: function () { return memoryIndex_1.MAX_INDEX_BYTES; } });
|
|
13
16
|
Object.defineProperty(exports, "MAX_MEMORY_FILE_BYTES", { enumerable: true, get: function () { return memoryIndex_1.MAX_MEMORY_FILE_BYTES; } });
|
|
14
17
|
Object.defineProperty(exports, "MEMORY_DIR", { enumerable: true, get: function () { return memoryIndex_1.MEMORY_DIR; } });
|
|
15
18
|
Object.defineProperty(exports, "MEMORY_INDEX_FILE", { enumerable: true, get: function () { return memoryIndex_1.MEMORY_INDEX_FILE; } });
|
|
19
|
+
Object.defineProperty(exports, "BANDIT_DIR", { enumerable: true, get: function () { return memoryIndex_1.BANDIT_DIR; } });
|
|
20
|
+
Object.defineProperty(exports, "BANDIT_MEMORY_DIR", { enumerable: true, get: function () { return memoryIndex_1.BANDIT_MEMORY_DIR; } });
|
|
21
|
+
Object.defineProperty(exports, "BANDIT_MEMORY_INDEX_FILE", { enumerable: true, get: function () { return memoryIndex_1.BANDIT_MEMORY_INDEX_FILE; } });
|
|
16
22
|
var readMemoryTool_1 = require("./tools/readMemoryTool");
|
|
17
23
|
Object.defineProperty(exports, "buildReadMemoryTool", { enumerable: true, get: function () { return readMemoryTool_1.buildReadMemoryTool; } });
|
|
18
24
|
var mcp_1 = require("./mcp");
|
|
@@ -46,6 +52,8 @@ var hooks_1 = require("./hooks");
|
|
|
46
52
|
Object.defineProperty(exports, "loadHookSettings", { enumerable: true, get: function () { return hooks_1.loadHookSettings; } });
|
|
47
53
|
Object.defineProperty(exports, "persistAllowEntry", { enumerable: true, get: function () { return hooks_1.persistAllowEntry; } });
|
|
48
54
|
Object.defineProperty(exports, "runHooks", { enumerable: true, get: function () { return hooks_1.runHooks; } });
|
|
55
|
+
var securityGuard_1 = require("./securityGuard");
|
|
56
|
+
Object.defineProperty(exports, "evaluateSecurityGuard", { enumerable: true, get: function () { return securityGuard_1.evaluateSecurityGuard; } });
|
|
49
57
|
var mentions_1 = require("./mentions");
|
|
50
58
|
Object.defineProperty(exports, "expandMentions", { enumerable: true, get: function () { return mentions_1.expandMentions; } });
|
|
51
59
|
var extraTools_1 = require("./tools/extraTools");
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AAAA,mCAQkB;AAPhB,oGAAA,UAAU,OAAA;AACV,4GAAA,kBAAkB,OAAA;AAClB,sGAAA,YAAY,OAAA;AACZ,2GAAA,iBAAiB,OAAA;AAKnB,6CAeuB;AAdrB,8GAAA,eAAe,OAAA;AACf,qHAAA,sBAAsB,OAAA;AACtB,+GAAA,gBAAgB,OAAA;AAChB,uHAAA,wBAAwB,OAAA;AACxB,8GAAA,eAAe,OAAA;AACf,oHAAA,qBAAqB,OAAA;AACrB,yGAAA,UAAU,OAAA;AACV,gHAAA,iBAAiB,OAAA;AACjB,yGAAA,UAAU,OAAA;AACV,gHAAA,iBAAiB,OAAA;AACjB,uHAAA,wBAAwB,OAAA;AAK1B,yDAA6D;AAApD,qHAAA,mBAAmB,OAAA;AAC5B,6BAMe;AALb,2GAAA,oBAAoB,OAAA;AACpB,iHAAA,0BAA0B,OAAA;AAC1B,2GAAA,oBAAoB,OAAA;AACpB,2GAAA,oBAAoB,OAAA;AACpB,2GAAA,oBAAoB,OAAA;AAEtB,iDAWyB;AAVvB,wHAAA,uBAAuB,OAAA;AACvB,qHAAA,oBAAoB,OAAA;AACpB,uHAAA,sBAAsB,OAAA;AACtB,oHAAA,mBAAmB,OAAA;AACnB,qHAAA,oBAAoB,OAAA;AACpB,wHAAA,uBAAuB,OAAA;AACvB,qHAAA,oBAAoB,OAAA;AACpB,uHAAA,sBAAsB,OAAA;AACtB,8HAAA,6BAA6B,OAAA;AAC7B,wHAAA,uBAAuB,OAAA;AAEzB,uCAKoB;AAJlB,uHAAA,2BAA2B,OAAA;AAC3B,iHAAA,qBAAqB,OAAA;AACrB,gHAAA,oBAAoB,OAAA;AACpB,wGAAA,YAAY,OAAA;AAEd,+CAKwB;AAJtB,gHAAA,gBAAgB,OAAA;AAChB,gHAAA,gBAAgB,OAAA;AAChB,iHAAA,iBAAiB,OAAA;AACjB,gHAAA,gBAAgB,OAAA;AAElB,iCAUiB;AATf,yGAAA,gBAAgB,OAAA;AAChB,0GAAA,iBAAiB,OAAA;AACjB,iGAAA,QAAQ,OAAA;AAQV,iDAKyB;AAJvB,sHAAA,qBAAqB,OAAA;AAKvB,uCAAiE;AAAxD,0GAAA,cAAc,OAAA;AACvB,iDAO4B;AAN1B,uGAAA,SAAS,OAAA;AACT,gHAAA,kBAAkB,OAAA;AAClB,+GAAA,iBAAiB,OAAA;AACjB,gHAAA,kBAAkB,OAAA;AAElB,+GAAA,iBAAiB,OAAA;AAEnB,6CAA+G;AAAtG,yGAAA,aAAa,OAAA;AAAE,8GAAA,kBAAkB,OAAA;AAAE,8GAAA,kBAAkB,OAAA;AAC9D,mDAO6B;AAN3B,+GAAA,gBAAgB,OAAA;AAChB,kHAAA,mBAAmB,OAAA;AACnB,+GAAA,gBAAgB,OAAA;AAChB,8GAAA,eAAe,OAAA;AAIjB,uCAaoB;AAZlB,2GAAA,eAAe,OAAA;AACf,8GAAA,kBAAkB,OAAA;AAClB,+GAAA,mBAAmB,OAAA;AACnB,wGAAA,YAAY,OAAA;AACZ,mHAAA,uBAAuB,OAAA;AASzB,qDAM2B;AALzB,8HAAA,2BAA2B,OAAA;AAM7B,6CAOuB;AANrB,iHAAA,kBAAkB,OAAA;AAClB,0GAAA,WAAW,OAAA;AACX,4GAAA,aAAa,OAAA;AACb,qHAAA,sBAAsB,OAAA;AAIxB,qCAgBmB;AAfjB,sGAAA,WAAW,OAAA;AACX,sGAAA,WAAW,OAAA;AACX,6GAAA,kBAAkB,OAAA;AAClB,yGAAA,cAAc,OAAA;AACd,wGAAA,aAAa,OAAA;AACb,4GAAA,iBAAiB,OAAA;AACjB,uGAAA,YAAY,OAAA;AACZ,6GAAA,kBAAkB,OAAA;AAClB,kHAAA,uBAAuB,OAAA;AAQzB,+CAKwB;AAJtB,yHAAA,yBAAyB,OAAA;AACzB,kHAAA,kBAAkB,OAAA;AAClB,6GAAA,aAAa,OAAA;AAGf,6CAKuB;AAJrB,8GAAA,eAAe,OAAA"}
|
package/dist/memory.d.ts
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
* Memory — auto-load workspace-local context files (BANDIT.md / CLAUDE.md)
|
|
3
3
|
* and inline them into the system prompt so the agent follows project rules
|
|
4
4
|
* without being re-told on every turn.
|
|
5
|
+
*
|
|
6
|
+
* ## Deduplication (v0.4)
|
|
7
|
+
*
|
|
8
|
+
* When a repo has more than one of BANDIT.md / CLAUDE.md / AGENTS.md (e.g.
|
|
9
|
+
* a migration-in-progress state), loadMemory will skip files whose content
|
|
10
|
+
* is identical — or whose entire text is already present inside a
|
|
11
|
+
* previously-loaded file — so the model doesn't see duplicated context.
|
|
12
|
+
*
|
|
13
|
+
* ## Consolidation
|
|
14
|
+
*
|
|
15
|
+
* `consolidateMemory(cwd)` merges all found entry files into a single
|
|
16
|
+
* canonical BANDIT.md and makes the others point at it. On macOS/Linux a
|
|
17
|
+
* symlink is preferred; on Windows (or when the symlink attempt fails) it
|
|
18
|
+
* writes an exact copy with a drift warning header.
|
|
5
19
|
*/
|
|
6
20
|
import { type MemoryWarnFn } from './memoryIndex';
|
|
7
21
|
export interface MemoryBundle {
|
|
@@ -10,7 +24,7 @@ export interface MemoryBundle {
|
|
|
10
24
|
sources: string[];
|
|
11
25
|
}
|
|
12
26
|
/**
|
|
13
|
-
* loadMemory +
|
|
27
|
+
* loadMemory + topic-memory index, fused into a single bundle the host can
|
|
14
28
|
* inject as the system-prompt memory block. Always-loaded files come
|
|
15
29
|
* first; the index follows under its own source marker so the model
|
|
16
30
|
* knows which entries are full content vs. on-demand topic pointers.
|
|
@@ -19,6 +33,19 @@ export interface MemoryBundle {
|
|
|
19
33
|
* the `/memory` slash command and boot-status output.
|
|
20
34
|
*/
|
|
21
35
|
export declare function loadCombinedMemory(cwd: string, warn?: MemoryWarnFn): Promise<MemoryBundle>;
|
|
36
|
+
/**
|
|
37
|
+
* Read and deduplicate memory candidate files.
|
|
38
|
+
*
|
|
39
|
+
* Dedup strategy: after normalising whitespace, if the trimmed content of a
|
|
40
|
+
* candidate is entirely contained within the already-accumulated text (or is
|
|
41
|
+
* byte-identical to a previously loaded file) we skip it. This handles the
|
|
42
|
+
* common case where CLAUDE.md was copied verbatim into BANDIT.md during a
|
|
43
|
+
* migration, or where .bandit/memory.md echoes the root BANDIT.md.
|
|
44
|
+
*
|
|
45
|
+
* We do NOT try to dedupe at the paragraph/section level — that would require
|
|
46
|
+
* NLP and is overkill. The simple containment check catches >90% of real-world
|
|
47
|
+
* cases.
|
|
48
|
+
*/
|
|
22
49
|
export declare function loadMemory(cwd: string): Promise<MemoryBundle>;
|
|
23
50
|
/**
|
|
24
51
|
* Append a single fact to project memory so it survives across sessions.
|
|
@@ -35,4 +62,40 @@ export declare function loadMemory(cwd: string): Promise<MemoryBundle>;
|
|
|
35
62
|
* and needs to see WHERE the fact landed.
|
|
36
63
|
*/
|
|
37
64
|
export declare function appendMemory(cwd: string, fact: string): Promise<string>;
|
|
65
|
+
export type ConsolidationStrategy = 'symlink-or-copy' | 'copy';
|
|
66
|
+
export interface ConsolidationResult {
|
|
67
|
+
/** Absolute path of the canonical file (root BANDIT.md). */
|
|
68
|
+
canonical: string;
|
|
69
|
+
/** Files that were made to point at the canonical (symlinked or copied). */
|
|
70
|
+
redirected: string[];
|
|
71
|
+
/** 'symlink' when the OS supports it, 'copy' as fallback. */
|
|
72
|
+
method: 'symlink' | 'copy';
|
|
73
|
+
/** Files that were already identical/symlinked (skipped). */
|
|
74
|
+
skipped: string[];
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Consolidate multiple memory entry files (BANDIT.md / CLAUDE.md / AGENTS.md)
|
|
78
|
+
* into a single canonical `BANDIT.md`. The canonical file gets the merged
|
|
79
|
+
* content; each other file that previously had unique content becomes a
|
|
80
|
+
* pointer (symlink or copy) to BANDIT.md.
|
|
81
|
+
*
|
|
82
|
+
* ## Symlink vs copy decision
|
|
83
|
+
*
|
|
84
|
+
* - macOS / Linux: the function attempts `fs.symlink(canonical, other)`. If
|
|
85
|
+
* it succeeds, method === 'symlink'.
|
|
86
|
+
* - Windows (or when symlink creation fails with EPERM / ENOTSUP): falls back
|
|
87
|
+
* to writing an exact copy of BANDIT.md into the other file, prefixed with a
|
|
88
|
+
* comment warning that it can drift. method === 'copy'.
|
|
89
|
+
* - Callers can force 'copy' via the `strategy` option to skip the symlink
|
|
90
|
+
* attempt entirely.
|
|
91
|
+
*
|
|
92
|
+
* **Tradeoff**: symlinks are invisible to tools that `cat` the file, so editors
|
|
93
|
+
* show the canonical content transparently. Copies can drift if BANDIT.md is
|
|
94
|
+
* updated without running consolidateMemory again. There is no perfect answer;
|
|
95
|
+
* symlinks are preferred wherever supported.
|
|
96
|
+
*
|
|
97
|
+
* @param cwd Workspace root
|
|
98
|
+
* @param strategy 'symlink-or-copy' (default) | 'copy'
|
|
99
|
+
*/
|
|
100
|
+
export declare function consolidateMemory(cwd: string, strategy?: ConsolidationStrategy): Promise<ConsolidationResult>;
|
|
38
101
|
//# sourceMappingURL=memory.d.ts.map
|
package/dist/memory.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,OAAO,EAIL,KAAK,YAAY,EAClB,MAAM,eAAe,CAAC;AAWvB,MAAM,WAAW,YAAY;IAC3B,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAUhG;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CA+BnE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkC7E;AAID,MAAM,MAAM,qBAAqB,GAAG,iBAAiB,GAAG,MAAM,CAAC;AAE/D,MAAM,WAAW,mBAAmB;IAClC,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAC;IAClB,4EAA4E;IAC5E,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,6DAA6D;IAC7D,MAAM,EAAE,SAAS,GAAG,MAAM,CAAC;IAC3B,6DAA6D;IAC7D,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,QAAQ,GAAE,qBAAyC,GAClD,OAAO,CAAC,mBAAmB,CAAC,CAkG9B"}
|
package/dist/memory.js
CHANGED
|
@@ -3,6 +3,20 @@
|
|
|
3
3
|
* Memory — auto-load workspace-local context files (BANDIT.md / CLAUDE.md)
|
|
4
4
|
* and inline them into the system prompt so the agent follows project rules
|
|
5
5
|
* without being re-told on every turn.
|
|
6
|
+
*
|
|
7
|
+
* ## Deduplication (v0.4)
|
|
8
|
+
*
|
|
9
|
+
* When a repo has more than one of BANDIT.md / CLAUDE.md / AGENTS.md (e.g.
|
|
10
|
+
* a migration-in-progress state), loadMemory will skip files whose content
|
|
11
|
+
* is identical — or whose entire text is already present inside a
|
|
12
|
+
* previously-loaded file — so the model doesn't see duplicated context.
|
|
13
|
+
*
|
|
14
|
+
* ## Consolidation
|
|
15
|
+
*
|
|
16
|
+
* `consolidateMemory(cwd)` merges all found entry files into a single
|
|
17
|
+
* canonical BANDIT.md and makes the others point at it. On macOS/Linux a
|
|
18
|
+
* symlink is preferred; on Windows (or when the symlink attempt fails) it
|
|
19
|
+
* writes an exact copy with a drift warning header.
|
|
6
20
|
*/
|
|
7
21
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
22
|
if (k2 === undefined) k2 = k;
|
|
@@ -41,7 +55,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
41
55
|
exports.loadCombinedMemory = loadCombinedMemory;
|
|
42
56
|
exports.loadMemory = loadMemory;
|
|
43
57
|
exports.appendMemory = appendMemory;
|
|
58
|
+
exports.consolidateMemory = consolidateMemory;
|
|
44
59
|
const fs = __importStar(require("fs"));
|
|
60
|
+
const os = __importStar(require("os"));
|
|
45
61
|
const path = __importStar(require("path"));
|
|
46
62
|
const memoryIndex_1 = require("./memoryIndex");
|
|
47
63
|
const CANDIDATES = [
|
|
@@ -53,7 +69,7 @@ const CANDIDATES = [
|
|
|
53
69
|
];
|
|
54
70
|
const MAX_BYTES = 32 * 1024;
|
|
55
71
|
/**
|
|
56
|
-
* loadMemory +
|
|
72
|
+
* loadMemory + topic-memory index, fused into a single bundle the host can
|
|
57
73
|
* inject as the system-prompt memory block. Always-loaded files come
|
|
58
74
|
* first; the index follows under its own source marker so the model
|
|
59
75
|
* knows which entries are full content vs. on-demand topic pointers.
|
|
@@ -67,15 +83,30 @@ async function loadCombinedMemory(cwd, warn) {
|
|
|
67
83
|
const indexBlock = (0, memoryIndex_1.renderMemoryIndexBlock)(index);
|
|
68
84
|
if (!indexBlock)
|
|
69
85
|
return base;
|
|
70
|
-
const headed = `<!-- source: ${memoryIndex_1.
|
|
86
|
+
const headed = `<!-- source: ${memoryIndex_1.BANDIT_MEMORY_INDEX_FILE} -->\n${indexBlock}`;
|
|
71
87
|
return {
|
|
72
88
|
content: base.content ? `${base.content}\n\n${headed}` : headed,
|
|
73
|
-
sources: index.source ? [...base.sources, memoryIndex_1.
|
|
89
|
+
sources: index.source ? [...base.sources, memoryIndex_1.BANDIT_MEMORY_INDEX_FILE] : base.sources
|
|
74
90
|
};
|
|
75
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Read and deduplicate memory candidate files.
|
|
94
|
+
*
|
|
95
|
+
* Dedup strategy: after normalising whitespace, if the trimmed content of a
|
|
96
|
+
* candidate is entirely contained within the already-accumulated text (or is
|
|
97
|
+
* byte-identical to a previously loaded file) we skip it. This handles the
|
|
98
|
+
* common case where CLAUDE.md was copied verbatim into BANDIT.md during a
|
|
99
|
+
* migration, or where .bandit/memory.md echoes the root BANDIT.md.
|
|
100
|
+
*
|
|
101
|
+
* We do NOT try to dedupe at the paragraph/section level — that would require
|
|
102
|
+
* NLP and is overkill. The simple containment check catches >90% of real-world
|
|
103
|
+
* cases.
|
|
104
|
+
*/
|
|
76
105
|
async function loadMemory(cwd) {
|
|
77
106
|
const sections = [];
|
|
78
107
|
const sources = [];
|
|
108
|
+
// Accumulated normalised text for containment checks
|
|
109
|
+
const seen = [];
|
|
79
110
|
for (const rel of CANDIDATES) {
|
|
80
111
|
const abs = path.resolve(cwd, rel);
|
|
81
112
|
try {
|
|
@@ -84,8 +115,14 @@ async function loadMemory(cwd) {
|
|
|
84
115
|
continue;
|
|
85
116
|
const truncated = raw.byteLength > MAX_BYTES;
|
|
86
117
|
const text = raw.subarray(0, MAX_BYTES).toString('utf-8');
|
|
118
|
+
// Dedup: skip if trimmed content is identical to or fully contained
|
|
119
|
+
// within something we've already loaded.
|
|
120
|
+
const normalised = text.trim();
|
|
121
|
+
if (normalised && isDuplicate(normalised, seen))
|
|
122
|
+
continue;
|
|
87
123
|
sections.push(`<!-- source: ${rel} -->\n${text}${truncated ? '\n… (truncated)' : ''}`);
|
|
88
124
|
sources.push(rel);
|
|
125
|
+
seen.push(normalised);
|
|
89
126
|
}
|
|
90
127
|
catch {
|
|
91
128
|
// Not present — that's fine.
|
|
@@ -148,4 +185,143 @@ async function appendMemory(cwd, fact) {
|
|
|
148
185
|
await fs.promises.writeFile(abs, next, 'utf-8');
|
|
149
186
|
return abs;
|
|
150
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* Consolidate multiple memory entry files (BANDIT.md / CLAUDE.md / AGENTS.md)
|
|
190
|
+
* into a single canonical `BANDIT.md`. The canonical file gets the merged
|
|
191
|
+
* content; each other file that previously had unique content becomes a
|
|
192
|
+
* pointer (symlink or copy) to BANDIT.md.
|
|
193
|
+
*
|
|
194
|
+
* ## Symlink vs copy decision
|
|
195
|
+
*
|
|
196
|
+
* - macOS / Linux: the function attempts `fs.symlink(canonical, other)`. If
|
|
197
|
+
* it succeeds, method === 'symlink'.
|
|
198
|
+
* - Windows (or when symlink creation fails with EPERM / ENOTSUP): falls back
|
|
199
|
+
* to writing an exact copy of BANDIT.md into the other file, prefixed with a
|
|
200
|
+
* comment warning that it can drift. method === 'copy'.
|
|
201
|
+
* - Callers can force 'copy' via the `strategy` option to skip the symlink
|
|
202
|
+
* attempt entirely.
|
|
203
|
+
*
|
|
204
|
+
* **Tradeoff**: symlinks are invisible to tools that `cat` the file, so editors
|
|
205
|
+
* show the canonical content transparently. Copies can drift if BANDIT.md is
|
|
206
|
+
* updated without running consolidateMemory again. There is no perfect answer;
|
|
207
|
+
* symlinks are preferred wherever supported.
|
|
208
|
+
*
|
|
209
|
+
* @param cwd Workspace root
|
|
210
|
+
* @param strategy 'symlink-or-copy' (default) | 'copy'
|
|
211
|
+
*/
|
|
212
|
+
async function consolidateMemory(cwd, strategy = 'symlink-or-copy') {
|
|
213
|
+
const ENTRY_FILES = ['BANDIT.md', 'CLAUDE.md', 'AGENTS.md'];
|
|
214
|
+
const canonical = path.resolve(cwd, 'BANDIT.md');
|
|
215
|
+
// Gather unique content from all present files
|
|
216
|
+
const present = [];
|
|
217
|
+
for (const rel of ENTRY_FILES) {
|
|
218
|
+
const abs = path.resolve(cwd, rel);
|
|
219
|
+
try {
|
|
220
|
+
const content = await fs.promises.readFile(abs, 'utf-8');
|
|
221
|
+
if (content.trim())
|
|
222
|
+
present.push({ rel, abs, content });
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
// Not present
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (present.length === 0) {
|
|
229
|
+
// Nothing to consolidate — return an empty result
|
|
230
|
+
return { canonical, redirected: [], method: 'copy', skipped: [] };
|
|
231
|
+
}
|
|
232
|
+
// Check if all non-canonical files are already symlinks pointing at canonical
|
|
233
|
+
const canonicalEntry = present.find((f) => f.rel === 'BANDIT.md');
|
|
234
|
+
// Build merged content: deduplicate sections from all sources
|
|
235
|
+
const mergedParts = [];
|
|
236
|
+
const mergedSeen = [];
|
|
237
|
+
for (const { rel, content } of present) {
|
|
238
|
+
const normalised = content.trim();
|
|
239
|
+
if (!normalised || isDuplicate(normalised, mergedSeen))
|
|
240
|
+
continue;
|
|
241
|
+
mergedParts.push(content.trimEnd());
|
|
242
|
+
mergedSeen.push(normalised);
|
|
243
|
+
if (rel !== 'BANDIT.md') {
|
|
244
|
+
// Add a provenance comment when merging in content from another file
|
|
245
|
+
mergedParts[mergedParts.length - 1] =
|
|
246
|
+
`<!-- merged from ${rel} -->\n${mergedParts[mergedParts.length - 1]}`;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
// If BANDIT.md doesn't exist yet, provide scaffold
|
|
250
|
+
if (!canonicalEntry) {
|
|
251
|
+
mergedParts.unshift('# Project Memory\n');
|
|
252
|
+
}
|
|
253
|
+
const merged = mergedParts.join('\n\n') + '\n';
|
|
254
|
+
await fs.promises.writeFile(canonical, merged, 'utf-8');
|
|
255
|
+
// Redirect other files to the canonical
|
|
256
|
+
const redirected = [];
|
|
257
|
+
const skipped = [];
|
|
258
|
+
let method = 'copy';
|
|
259
|
+
const useSymlink = strategy === 'symlink-or-copy' && !isWindows();
|
|
260
|
+
for (const { rel, abs } of present) {
|
|
261
|
+
if (rel === 'BANDIT.md')
|
|
262
|
+
continue;
|
|
263
|
+
// Check if already a symlink pointing at canonical
|
|
264
|
+
try {
|
|
265
|
+
const lstat = await fs.promises.lstat(abs);
|
|
266
|
+
if (lstat.isSymbolicLink()) {
|
|
267
|
+
const target = await fs.promises.readlink(abs);
|
|
268
|
+
const resolvedTarget = path.resolve(path.dirname(abs), target);
|
|
269
|
+
if (resolvedTarget === canonical) {
|
|
270
|
+
skipped.push(abs);
|
|
271
|
+
continue;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
catch {
|
|
276
|
+
// Not a symlink — fall through
|
|
277
|
+
}
|
|
278
|
+
if (useSymlink) {
|
|
279
|
+
try {
|
|
280
|
+
// Remove the old file first, then create symlink
|
|
281
|
+
await fs.promises.unlink(abs);
|
|
282
|
+
// Use a relative symlink so the repo is portable
|
|
283
|
+
const rel_target = path.relative(path.dirname(abs), canonical);
|
|
284
|
+
await fs.promises.symlink(rel_target, abs);
|
|
285
|
+
method = 'symlink';
|
|
286
|
+
redirected.push(abs);
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
289
|
+
catch {
|
|
290
|
+
// Symlink failed — fall through to copy
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
// Copy: write a copy with a drift-warning header
|
|
294
|
+
const driftWarning = `<!-- COPY of BANDIT.md — generated by consolidateMemory.\n` +
|
|
295
|
+
` This file may drift if BANDIT.md is updated without re-running consolidation.\n` +
|
|
296
|
+
` On macOS/Linux prefer symlinks (strategy: 'symlink-or-copy'). -->\n\n`;
|
|
297
|
+
const copy = await fs.promises.readFile(canonical, 'utf-8');
|
|
298
|
+
await fs.promises.writeFile(abs, driftWarning + copy, 'utf-8');
|
|
299
|
+
redirected.push(abs);
|
|
300
|
+
}
|
|
301
|
+
return { canonical, redirected, method, skipped };
|
|
302
|
+
}
|
|
303
|
+
// ── Internal helpers ────────────────────────────────────────────────────────
|
|
304
|
+
/**
|
|
305
|
+
* Returns true when `candidate` is already represented in `seen`:
|
|
306
|
+
* either as an exact match, or as a substring of an already-loaded block.
|
|
307
|
+
*
|
|
308
|
+
* Normalises runs of whitespace before comparing so minor formatting
|
|
309
|
+
* differences (trailing newlines, blank-line count) don't prevent dedup.
|
|
310
|
+
*/
|
|
311
|
+
function normaliseWS(s) {
|
|
312
|
+
return s.replace(/\s+/g, ' ').trim();
|
|
313
|
+
}
|
|
314
|
+
function isDuplicate(candidate, seen) {
|
|
315
|
+
const normCandidate = normaliseWS(candidate);
|
|
316
|
+
for (const s of seen) {
|
|
317
|
+
const normS = normaliseWS(s);
|
|
318
|
+
if (normS === normCandidate || normS.includes(normCandidate)) {
|
|
319
|
+
return true;
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return false;
|
|
323
|
+
}
|
|
324
|
+
function isWindows() {
|
|
325
|
+
return os.platform() === 'win32';
|
|
326
|
+
}
|
|
151
327
|
//# sourceMappingURL=memory.js.map
|
package/dist/memory.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"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"}
|
package/dist/memoryIndex.d.ts
CHANGED
|
@@ -2,6 +2,9 @@ export declare const MAX_INDEX_BYTES: number;
|
|
|
2
2
|
export declare const MAX_MEMORY_FILE_BYTES: number;
|
|
3
3
|
export declare const MEMORY_DIR = "memory";
|
|
4
4
|
export declare const MEMORY_INDEX_FILE = "MEMORY.md";
|
|
5
|
+
export declare const BANDIT_DIR = ".bandit";
|
|
6
|
+
export declare const BANDIT_MEMORY_DIR = ".bandit/memory";
|
|
7
|
+
export declare const BANDIT_MEMORY_INDEX_FILE = ".bandit/memory/MEMORY.md";
|
|
5
8
|
export interface MemoryIndexEntry {
|
|
6
9
|
/** Slug derived from filename (e.g. "auth-conventions"). Used as the `name` arg to read_memory. */
|
|
7
10
|
name: string;
|
|
@@ -19,7 +22,7 @@ export interface MemoryIndex {
|
|
|
19
22
|
indexContent: string;
|
|
20
23
|
/** Parsed entries; dangling links are dropped (with a warning). */
|
|
21
24
|
entries: MemoryIndexEntry[];
|
|
22
|
-
/** Absolute path of MEMORY.md if found, else null. */
|
|
25
|
+
/** Absolute path of MEMORY.md if found, else null. Prefers .bandit/memory/MEMORY.md. */
|
|
23
26
|
source: string | null;
|
|
24
27
|
}
|
|
25
28
|
/**
|
|
@@ -34,5 +37,36 @@ export type MemoryWarnFn = (msg: string) => void;
|
|
|
34
37
|
* entries so the caller can `if (block) ...` without a null check.
|
|
35
38
|
*/
|
|
36
39
|
export declare function renderMemoryIndexBlock(index: MemoryIndex): string;
|
|
40
|
+
/**
|
|
41
|
+
* Load the memory index, searching both `.bandit/memory/MEMORY.md` (preferred)
|
|
42
|
+
* and the legacy root `MEMORY.md`. Entries from `.bandit/memory/` win on slug
|
|
43
|
+
* collisions. Returns a merged MemoryIndex.
|
|
44
|
+
*/
|
|
37
45
|
export declare function loadMemoryIndex(cwd: string, warn?: MemoryWarnFn): Promise<MemoryIndex>;
|
|
46
|
+
/**
|
|
47
|
+
* Write a new topic file + update the index. Always writes to `.bandit/memory/`.
|
|
48
|
+
*
|
|
49
|
+
* @param cwd Workspace root
|
|
50
|
+
* @param slug Plain slug, e.g. "auth-conventions"
|
|
51
|
+
* @param title Human label for the index entry
|
|
52
|
+
* @param hook One-line hook (when is this relevant?)
|
|
53
|
+
* @param body Full markdown body for the topic file
|
|
54
|
+
* @returns The absolute path of the written topic file
|
|
55
|
+
*/
|
|
56
|
+
export declare function writeMemoryTopic(cwd: string, slug: string, title: string, hook: string, body: string): Promise<string>;
|
|
57
|
+
/**
|
|
58
|
+
* One-time, idempotent migration: moves root `MEMORY.md` + `memory/` into
|
|
59
|
+
* `.bandit/memory/`. Safe to call on every startup — bails out early if:
|
|
60
|
+
* - the target `.bandit/memory/MEMORY.md` already exists, OR
|
|
61
|
+
* - the source root `MEMORY.md` does not exist.
|
|
62
|
+
*
|
|
63
|
+
* Steps:
|
|
64
|
+
* 1. Creates `.bandit/memory/` if needed.
|
|
65
|
+
* 2. Copies each `memory/<slug>.md` to `.bandit/memory/<slug>.md`.
|
|
66
|
+
* 3. Copies (rewrites) `MEMORY.md` to `.bandit/memory/MEMORY.md`.
|
|
67
|
+
* 4. Does NOT delete the originals (safe — caller can clean up if desired).
|
|
68
|
+
*
|
|
69
|
+
* @returns Array of absolute paths written (empty when migration is skipped).
|
|
70
|
+
*/
|
|
71
|
+
export declare function migrateMemoryToBanditDir(cwd: string): Promise<string[]>;
|
|
38
72
|
//# sourceMappingURL=memoryIndex.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memoryIndex.d.ts","sourceRoot":"","sources":["../src/memoryIndex.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"memoryIndex.d.ts","sourceRoot":"","sources":["../src/memoryIndex.ts"],"names":[],"mappings":"AA+BA,eAAO,MAAM,eAAe,QAAW,CAAC;AACxC,eAAO,MAAM,qBAAqB,QAAY,CAAC;AAG/C,eAAO,MAAM,UAAU,WAAW,CAAC;AACnC,eAAO,MAAM,iBAAiB,cAAc,CAAC;AAG7C,eAAO,MAAM,UAAU,YAAY,CAAC;AACpC,eAAO,MAAM,iBAAiB,mBAAmB,CAAC;AAClD,eAAO,MAAM,wBAAwB,6BAA6B,CAAC;AAEnE,MAAM,WAAW,gBAAgB;IAC/B,mGAAmG;IACnG,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,OAAO,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,0FAA0F;IAC1F,YAAY,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,wFAAwF;IACxF,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAUD;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;AAMjD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAWjE;AAuED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,YAA0B,GAAG,OAAO,CAAC,WAAW,CAAC,CA2DzG;AAID;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,CAAC,CA+BjB;AAID;;;;;;;;;;;;;GAaG;AACH,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAkD7E"}
|