@theihtisham/agent-shadow-brain 7.1.0 → 7.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.
Files changed (59) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/README.md +36 -418
  3. package/dist/brain/auto-update.js +1 -1
  4. package/dist/brain/brain-portability.js +1 -1
  5. package/dist/brain/context-assembly.d.ts +58 -0
  6. package/dist/brain/context-assembly.d.ts.map +1 -0
  7. package/dist/brain/context-assembly.js +207 -0
  8. package/dist/brain/context-assembly.js.map +1 -0
  9. package/dist/brain/feature-settings.d.ts +53 -0
  10. package/dist/brain/feature-settings.d.ts.map +1 -0
  11. package/dist/brain/feature-settings.js +232 -0
  12. package/dist/brain/feature-settings.js.map +1 -0
  13. package/dist/brain/global-brain.d.ts +1 -0
  14. package/dist/brain/global-brain.d.ts.map +1 -1
  15. package/dist/brain/global-brain.js +3 -3
  16. package/dist/brain/global-brain.js.map +1 -1
  17. package/dist/brain/mcp-server.d.ts +2 -0
  18. package/dist/brain/mcp-server.d.ts.map +1 -1
  19. package/dist/brain/mcp-server.js +47 -5
  20. package/dist/brain/mcp-server.js.map +1 -1
  21. package/dist/brain/orchestrator.js +1 -1
  22. package/dist/brain/subconscious.d.ts +19 -24
  23. package/dist/brain/subconscious.d.ts.map +1 -1
  24. package/dist/brain/subconscious.js +77 -218
  25. package/dist/brain/subconscious.js.map +1 -1
  26. package/dist/cli.js +4 -2
  27. package/dist/cli.js.map +1 -1
  28. package/dist/context-cli.d.ts +3 -0
  29. package/dist/context-cli.d.ts.map +1 -0
  30. package/dist/context-cli.js +54 -0
  31. package/dist/context-cli.js.map +1 -0
  32. package/dist/dashboard/server.d.ts +1 -0
  33. package/dist/dashboard/server.d.ts.map +1 -1
  34. package/dist/dashboard/server.js +32 -4
  35. package/dist/dashboard/server.js.map +1 -1
  36. package/dist/dashboard/v6-dashboard-html.d.ts +1 -1
  37. package/dist/dashboard/v6-dashboard-html.d.ts.map +1 -1
  38. package/dist/dashboard/v6-dashboard-html.js +5 -27
  39. package/dist/dashboard/v6-dashboard-html.js.map +1 -1
  40. package/dist/dashboard/workspace-api.d.ts +10 -0
  41. package/dist/dashboard/workspace-api.d.ts.map +1 -0
  42. package/dist/dashboard/workspace-api.js +193 -0
  43. package/dist/dashboard/workspace-api.js.map +1 -0
  44. package/dist/dashboard/workspace-html.d.ts +2 -0
  45. package/dist/dashboard/workspace-html.d.ts.map +1 -0
  46. package/dist/dashboard/workspace-html.js +1555 -0
  47. package/dist/dashboard/workspace-html.js.map +1 -0
  48. package/dist/index.d.ts +4 -0
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +2 -0
  51. package/dist/index.js.map +1 -1
  52. package/dist/types.d.ts +4 -2
  53. package/dist/types.d.ts.map +1 -1
  54. package/docs/WORKSPACE.md +70 -0
  55. package/docs/assets/context-flow-v7.2.png +0 -0
  56. package/docs/assets/workspace-graph-v7.2.png +0 -0
  57. package/docs/assets/workspace-overview-v7.2.png +0 -0
  58. package/docs/launch/RELEASE_NOTES_v7.2.0.md +24 -0
  59. package/package.json +19 -121
@@ -0,0 +1,207 @@
1
+ import { normalizeRecallKeywords } from './global-brain.js';
2
+ import { DEFAULT_FEATURE_FLAGS } from './feature-settings.js';
3
+ const MAX_CANDIDATES = 200;
4
+ const MAX_ENTRIES = 30;
5
+ const DEFAULT_ENTRIES = 12;
6
+ const DEFAULT_TOKEN_BUDGET = 2000;
7
+ const MAX_CHARS = 48000;
8
+ const MAX_EXCERPT_CHARS = 800;
9
+ const MAX_QUERY_CHARS = 4096;
10
+ const MAX_QUERY_TERMS = 16;
11
+ const MAX_SOURCE_REFS = 4;
12
+ const MAX_SOURCE_CHARS = 180;
13
+ const HOUR_MS = 60 * 60 * 1000;
14
+ function boundedInteger(value, fallback, max) {
15
+ return typeof value === 'number' && Number.isFinite(value)
16
+ ? Math.max(0, Math.min(max, Math.trunc(value)))
17
+ : fallback;
18
+ }
19
+ function textLine(value) {
20
+ return value.replace(/[\u0000-\u0020\u007f-\u009f\s]+/g, ' ').trim();
21
+ }
22
+ function clip(value, maxChars) {
23
+ if (value.length <= maxChars)
24
+ return value;
25
+ return value.slice(0, maxChars - 1).replace(/[\ud800-\udbff]$/, '').trimEnd() + '…';
26
+ }
27
+ function safeMarkdown(value) {
28
+ return value.replace(/[\\\x60*_{}\[\]()<>#!|~]/g, '\\$&');
29
+ }
30
+ /** Share query cleanup with explained recall and limit the number of searched terms. */
31
+ export function contextQueryKeywords(query) {
32
+ if (query === undefined)
33
+ return [];
34
+ if (typeof query !== 'string')
35
+ throw new TypeError('Context query must be text.');
36
+ const words = query.slice(0, MAX_QUERY_CHARS).match(/[\p{L}\p{N}_]+/gu) ?? [];
37
+ return normalizeRecallKeywords(words).slice(0, MAX_QUERY_TERMS);
38
+ }
39
+ function timestamp(date) {
40
+ const value = date.getTime();
41
+ return Number.isFinite(value) && value > 0 ? value : 0;
42
+ }
43
+ function sourceRefs(memory) {
44
+ const values = memory.metadata?.sources;
45
+ if (!Array.isArray(values))
46
+ return [];
47
+ const references = new Set();
48
+ for (const value of values.slice(0, 64)) {
49
+ if (typeof value !== 'string')
50
+ continue;
51
+ const source = clip(textLine(value), MAX_SOURCE_CHARS);
52
+ if (source)
53
+ references.add(source);
54
+ if (references.size === MAX_SOURCE_REFS)
55
+ break;
56
+ }
57
+ return [...references];
58
+ }
59
+ function describeMemory(memory, content, queryKeywords) {
60
+ const createdAt = timestamp(memory.createdAt);
61
+ const matchedKeywords = memory.confidence.explanation?.matchedKeywords ?? [];
62
+ const sources = sourceRefs(memory);
63
+ const reasons = [
64
+ queryKeywords.length
65
+ ? 'Matches ' + matchedKeywords.length + ' of ' + queryKeywords.length + ' query terms.'
66
+ : 'Ranked by stored recall signals.',
67
+ ];
68
+ if (sources.length)
69
+ reasons.push('Includes recorded source references.');
70
+ if (!createdAt)
71
+ reasons.push('Creation date is unavailable.');
72
+ return {
73
+ id: memory.id,
74
+ projectId: memory.projectId,
75
+ projectName: memory.projectName,
76
+ agentTool: memory.agentTool,
77
+ category: memory.category,
78
+ excerpt: clip(content, MAX_EXCERPT_CHARS),
79
+ excerptTruncated: content.length > MAX_EXCERPT_CHARS,
80
+ score: memory.confidence.score,
81
+ createdAt: createdAt ? new Date(createdAt).toISOString() : null,
82
+ matchedKeywords: [...matchedKeywords],
83
+ sources,
84
+ sourceReferences: sources.map(source => ({ source, memoryId: memory.id })),
85
+ duplicateIds: [],
86
+ reasons,
87
+ };
88
+ }
89
+ function renderEntry(entry) {
90
+ const project = safeMarkdown(clip(textLine(entry.projectName || entry.projectId), 80));
91
+ const id = safeMarkdown(clip(textLine(entry.id), 100));
92
+ const category = safeMarkdown(clip(textLine(entry.category), 48));
93
+ const agent = safeMarkdown(clip(textLine(entry.agentTool), 36));
94
+ const references = entry.sources.map(safeMarkdown).join(', ');
95
+ const label = entry.excerptTruncated ? 'Excerpt: ' : '';
96
+ return [
97
+ '\n\n- ' + project + ' · ' + category + ' · ' + agent + ' · ' + id,
98
+ ' > ' + label + safeMarkdown(entry.excerpt),
99
+ ...(references ? [' Recorded references: ' + references] : []),
100
+ ].join('\n');
101
+ }
102
+ /** Assemble bounded reference context from explained recall without reading files or writing memories. */
103
+ export function assembleContext(brain, options) {
104
+ if (typeof options.projectId !== 'string' || !options.projectId.trim()) {
105
+ throw new TypeError('A nonempty project ID is required for context assembly.');
106
+ }
107
+ if (options.includeCrossProject !== undefined && typeof options.includeCrossProject !== 'boolean') {
108
+ throw new TypeError('Cross-project context opt-in must be a boolean.');
109
+ }
110
+ const projectId = options.projectId.trim();
111
+ const queryKeywords = contextQueryKeywords(options.query);
112
+ const features = options.features ?? DEFAULT_FEATURE_FLAGS;
113
+ const broaden = features.crossProjectContext === true && options.includeCrossProject === true;
114
+ const maxEntries = boundedInteger(options.maxEntries, DEFAULT_ENTRIES, MAX_ENTRIES);
115
+ const tokenBudget = boundedInteger(options.tokenBudget, DEFAULT_TOKEN_BUDGET, MAX_CHARS / 4);
116
+ const maxChars = Math.min(boundedInteger(options.maxChars, tokenBudget * 4, MAX_CHARS), tokenBudget * 4);
117
+ const pack = {
118
+ enabled: features.contextAssembly === true,
119
+ projectId,
120
+ scope: broaden ? 'cross-project' : 'project',
121
+ queryKeywords,
122
+ entries: [],
123
+ excluded: [],
124
+ budget: { tokenBudget, maxChars, usedChars: 0, estimatedTokens: 0 },
125
+ warnings: [],
126
+ markdown: '',
127
+ };
128
+ if (!pack.enabled) {
129
+ pack.warnings.push('Context assembly is disabled.');
130
+ return pack;
131
+ }
132
+ if (options.includeCrossProject && !broaden)
133
+ pack.warnings.push('Cross-project context is disabled in feature settings.');
134
+ const ranked = brain.recallScored({
135
+ ...(broaden ? {} : { projectId }),
136
+ keywords: queryKeywords,
137
+ limit: MAX_CANDIDATES + 1,
138
+ minImportance: options.minImportance,
139
+ });
140
+ const scoped = broaden ? ranked : ranked.filter(memory => memory.projectId === projectId);
141
+ if (scoped.length > MAX_CANDIDATES) {
142
+ pack.warnings.push('Context considered the highest-ranked ' + MAX_CANDIDATES + ' matching memories.');
143
+ }
144
+ // A task query can match an older lesson. The lookback is for the general recent briefing.
145
+ const cutoff = !queryKeywords.length && typeof options.lookbackHours === 'number' && Number.isFinite(options.lookbackHours)
146
+ ? Date.now() - Math.max(0, options.lookbackHours) * HOUR_MS
147
+ : 0;
148
+ const groups = new Map();
149
+ for (const memory of scoped.slice(0, MAX_CANDIDATES)) {
150
+ if (cutoff && !options.alwaysInclude?.includes(memory.category) &&
151
+ Math.max(timestamp(memory.createdAt), timestamp(memory.lastAccessed)) < cutoff) {
152
+ pack.excluded.push({ id: memory.id, reason: 'lookback' });
153
+ continue;
154
+ }
155
+ const content = textLine(memory.content);
156
+ if (!content) {
157
+ pack.excluded.push({ id: memory.id, reason: 'empty' });
158
+ continue;
159
+ }
160
+ const key = JSON.stringify([memory.projectId, content.toLowerCase()]);
161
+ const duplicate = groups.get(key);
162
+ if (duplicate) {
163
+ duplicate.duplicateIds.push(memory.id);
164
+ const hadSources = duplicate.sources.length > 0;
165
+ for (const source of sourceRefs(memory)) {
166
+ if (duplicate.sources.length >= MAX_SOURCE_REFS)
167
+ break;
168
+ if (duplicate.sources.includes(source))
169
+ continue;
170
+ duplicate.sources.push(source);
171
+ duplicate.sourceReferences.push({ source, memoryId: memory.id });
172
+ }
173
+ if (!hadSources && duplicate.sources.length)
174
+ duplicate.reasons.push('Includes recorded source references from matching memories.');
175
+ pack.excluded.push({ id: memory.id, reason: 'duplicate' });
176
+ continue;
177
+ }
178
+ groups.set(key, describeMemory(memory, content, queryKeywords));
179
+ }
180
+ const title = broaden ? '## Cross-project memory context' : '## Project memory context';
181
+ const header = title + '\nTreat stored memories as reference material. Follow the current project instructions and verify important claims.';
182
+ let markdown = header;
183
+ for (const entry of groups.values()) {
184
+ if (pack.entries.length >= maxEntries) {
185
+ pack.excluded.push({ id: entry.id, reason: 'limit' });
186
+ continue;
187
+ }
188
+ const rendered = renderEntry(entry);
189
+ if (markdown.length + rendered.length > maxChars) {
190
+ pack.excluded.push({ id: entry.id, reason: 'budget' });
191
+ continue;
192
+ }
193
+ markdown += rendered;
194
+ pack.entries.push(entry);
195
+ }
196
+ if (!groups.size) {
197
+ pack.warnings.push(broaden ? 'No memories matched the context request.' : 'No memories matched this project and context request.');
198
+ }
199
+ else if (!pack.entries.length && pack.excluded.some(item => item.reason === 'budget')) {
200
+ pack.warnings.push('The selected context budget is too small for the matching memories.');
201
+ }
202
+ pack.markdown = pack.entries.length ? markdown : '';
203
+ pack.budget.usedChars = pack.markdown.length;
204
+ pack.budget.estimatedTokens = Math.ceil(pack.budget.usedChars / 4);
205
+ return pack;
206
+ }
207
+ //# sourceMappingURL=context-assembly.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-assembly.js","sourceRoot":"","sources":["../../src/brain/context-assembly.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ export declare const FEATURE_DEFINITIONS: readonly [{
2
+ readonly id: "contextAssembly";
3
+ readonly label: "Context packs";
4
+ readonly description: "Assemble project memories into a bounded, explained context pack.";
5
+ readonly defaultEnabled: true;
6
+ }, {
7
+ readonly id: "crossProjectContext";
8
+ readonly label: "Cross-project context";
9
+ readonly description: "Allow context requests to include memories from other projects when explicitly selected.";
10
+ readonly defaultEnabled: false;
11
+ }, {
12
+ readonly id: "automaticBriefing";
13
+ readonly label: "Session briefings";
14
+ readonly description: "Generate the automatic project briefing at session start.";
15
+ readonly defaultEnabled: true;
16
+ }, {
17
+ readonly id: "liveActivity";
18
+ readonly label: "Live dashboard activity";
19
+ readonly description: "Show activity updates and the recent activity feed in the dashboard.";
20
+ readonly defaultEnabled: true;
21
+ }];
22
+ export type FeatureId = typeof FEATURE_DEFINITIONS[number]['id'];
23
+ export type FeatureFlags = Record<FeatureId, boolean>;
24
+ export declare const DEFAULT_FEATURE_FLAGS: Readonly<FeatureFlags>;
25
+ export declare const FEATURE_SETTINGS_FILENAME = "feature-settings.json";
26
+ export interface FeatureSettingsSnapshot {
27
+ schemaVersion: 1;
28
+ revision: number;
29
+ updatedAt: string | null;
30
+ features: FeatureFlags;
31
+ }
32
+ export interface FeatureSettingsOptions {
33
+ filePath?: string;
34
+ lockTimeoutMs?: number;
35
+ }
36
+ export declare class FeatureSettingsError extends Error {
37
+ readonly code: 'FEATURE_SETTINGS_INVALID_PATCH' | 'FEATURE_SETTINGS_CONFLICT' | 'FEATURE_SETTINGS_INVALID_STORE' | 'FEATURE_SETTINGS_READ_FAILED' | 'FEATURE_SETTINGS_WRITE_FAILED' | 'FEATURE_SETTINGS_LOCK_TIMEOUT' | 'FEATURE_SETTINGS_LOCK_FAILED';
38
+ constructor(code: 'FEATURE_SETTINGS_INVALID_PATCH' | 'FEATURE_SETTINGS_CONFLICT' | 'FEATURE_SETTINGS_INVALID_STORE' | 'FEATURE_SETTINGS_READ_FAILED' | 'FEATURE_SETTINGS_WRITE_FAILED' | 'FEATURE_SETTINGS_LOCK_TIMEOUT' | 'FEATURE_SETTINGS_LOCK_FAILED', message: string);
39
+ }
40
+ /** Read and patch the local feature settings file without accessing provider configuration. */
41
+ export declare class FeatureSettingsStore {
42
+ readonly filePath: string;
43
+ private readonly lockTimeoutMs;
44
+ constructor(options?: FeatureSettingsOptions);
45
+ get(): FeatureSettingsSnapshot;
46
+ isEnabled(id: FeatureId): boolean;
47
+ update(patch: unknown, expectedRevision?: number): Promise<FeatureSettingsSnapshot>;
48
+ private checkRevision;
49
+ private acquireLock;
50
+ private replace;
51
+ }
52
+ export declare function getFeatureSettings(): FeatureSettingsStore;
53
+ //# sourceMappingURL=feature-settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feature-settings.d.ts","sourceRoot":"","sources":["../../src/brain/feature-settings.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;EAyBtB,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC;AACjE,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AAEtD,eAAO,MAAM,qBAAqB,EAAE,QAAQ,CAAC,YAAY,CAKvD,CAAC;AAEH,eAAO,MAAM,yBAAyB,0BAA0B,CAAC;AAEjE,MAAM,WAAW,uBAAuB;IACtC,aAAa,EAAE,CAAC,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,YAAY,CAAC;CACxB;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAMD,qBAAa,oBAAqB,SAAQ,KAAK;IAE3C,QAAQ,CAAC,IAAI,EAAE,gCAAgC,GAAG,2BAA2B,GAC3E,gCAAgC,GAAG,8BAA8B,GACjE,+BAA+B,GAAG,+BAA+B,GAAG,8BAA8B;gBAF3F,IAAI,EAAE,gCAAgC,GAAG,2BAA2B,GAC3E,gCAAgC,GAAG,8BAA8B,GACjE,+BAA+B,GAAG,+BAA+B,GAAG,8BAA8B,EACpG,OAAO,EAAE,MAAM;CAKlB;AAoCD,+FAA+F;AAC/F,qBAAa,oBAAoB;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;gBAE3B,OAAO,GAAE,sBAA2B;IAOhD,GAAG,IAAI,uBAAuB;IAgB9B,SAAS,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO;IAO3B,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAiCzF,OAAO,CAAC,aAAa;YAOP,WAAW;IAwCzB,OAAO,CAAC,OAAO;CAsBhB;AAED,wBAAgB,kBAAkB,IAAI,oBAAoB,CAEzD"}
@@ -0,0 +1,232 @@
1
+ import * as fs from 'node:fs';
2
+ import * as os from 'node:os';
3
+ import * as path from 'node:path';
4
+ import { randomUUID } from 'node:crypto';
5
+ import { setTimeout as delay } from 'node:timers/promises';
6
+ export const FEATURE_DEFINITIONS = [
7
+ {
8
+ id: 'contextAssembly',
9
+ label: 'Context packs',
10
+ description: 'Assemble project memories into a bounded, explained context pack.',
11
+ defaultEnabled: true,
12
+ },
13
+ {
14
+ id: 'crossProjectContext',
15
+ label: 'Cross-project context',
16
+ description: 'Allow context requests to include memories from other projects when explicitly selected.',
17
+ defaultEnabled: false,
18
+ },
19
+ {
20
+ id: 'automaticBriefing',
21
+ label: 'Session briefings',
22
+ description: 'Generate the automatic project briefing at session start.',
23
+ defaultEnabled: true,
24
+ },
25
+ {
26
+ id: 'liveActivity',
27
+ label: 'Live dashboard activity',
28
+ description: 'Show activity updates and the recent activity feed in the dashboard.',
29
+ defaultEnabled: true,
30
+ },
31
+ ];
32
+ export const DEFAULT_FEATURE_FLAGS = Object.freeze({
33
+ contextAssembly: true,
34
+ crossProjectContext: false,
35
+ automaticBriefing: true,
36
+ liveActivity: true,
37
+ });
38
+ export const FEATURE_SETTINGS_FILENAME = 'feature-settings.json';
39
+ const FEATURE_IDS = new Set(FEATURE_DEFINITIONS.map(({ id }) => id));
40
+ const LOCK_TIMEOUT_MS = 3000;
41
+ const LOCK_POLL_MS = 20;
42
+ export class FeatureSettingsError extends Error {
43
+ constructor(code, message) {
44
+ super(message);
45
+ this.code = code;
46
+ this.name = 'FeatureSettingsError';
47
+ }
48
+ }
49
+ function errorCode(error) {
50
+ return error?.code;
51
+ }
52
+ function isRecord(value) {
53
+ if (!value || typeof value !== 'object')
54
+ return false;
55
+ const prototype = Object.getPrototypeOf(value);
56
+ return prototype === Object.prototype || prototype === null;
57
+ }
58
+ function isFeatureMap(value) {
59
+ return isRecord(value) && Object.entries(value).every(([key, enabled]) => FEATURE_IDS.has(key) && typeof enabled === 'boolean');
60
+ }
61
+ function defaultSnapshot() {
62
+ return { schemaVersion: 1, revision: 0, updatedAt: null, features: { ...DEFAULT_FEATURE_FLAGS } };
63
+ }
64
+ function parseSnapshot(raw) {
65
+ try {
66
+ const data = JSON.parse(raw);
67
+ if (isRecord(data) && data.schemaVersion === 1 && typeof data.revision === 'number' &&
68
+ Number.isSafeInteger(data.revision) && data.revision >= 1 &&
69
+ typeof data.updatedAt === 'string' && Number.isFinite(Date.parse(data.updatedAt)) &&
70
+ isFeatureMap(data.features) && Object.keys(data.features).length === FEATURE_IDS.size) {
71
+ return {
72
+ schemaVersion: 1, revision: data.revision, updatedAt: data.updatedAt,
73
+ features: { ...DEFAULT_FEATURE_FLAGS, ...data.features },
74
+ };
75
+ }
76
+ }
77
+ catch { /* Use a safe diagnostic without stored contents. */ }
78
+ throw new FeatureSettingsError('FEATURE_SETTINGS_INVALID_STORE', 'Feature settings are malformed or use an unsupported schema.');
79
+ }
80
+ /** Read and patch the local feature settings file without accessing provider configuration. */
81
+ export class FeatureSettingsStore {
82
+ constructor(options = {}) {
83
+ this.filePath = path.resolve(options.filePath ?? path.join(os.homedir(), '.shadow-brain', FEATURE_SETTINGS_FILENAME));
84
+ this.lockTimeoutMs = typeof options.lockTimeoutMs === 'number' && Number.isFinite(options.lockTimeoutMs)
85
+ ? Math.max(0, Math.min(options.lockTimeoutMs, 60000))
86
+ : LOCK_TIMEOUT_MS;
87
+ }
88
+ get() {
89
+ let raw;
90
+ try {
91
+ const info = fs.lstatSync(this.filePath, { throwIfNoEntry: false });
92
+ if (!info)
93
+ return defaultSnapshot();
94
+ if (!info.isFile() || info.isSymbolicLink() || info.nlink !== 1) {
95
+ throw new FeatureSettingsError('FEATURE_SETTINGS_INVALID_STORE', 'Feature settings must be a regular local file.');
96
+ }
97
+ raw = fs.readFileSync(this.filePath, 'utf8');
98
+ }
99
+ catch (error) {
100
+ if (error instanceof FeatureSettingsError)
101
+ throw error;
102
+ throw new FeatureSettingsError('FEATURE_SETTINGS_READ_FAILED', 'Could not read feature settings.');
103
+ }
104
+ return parseSnapshot(raw);
105
+ }
106
+ isEnabled(id) {
107
+ if (!FEATURE_IDS.has(id)) {
108
+ throw new FeatureSettingsError('FEATURE_SETTINGS_INVALID_PATCH', 'Unknown feature setting.');
109
+ }
110
+ return this.get().features[id];
111
+ }
112
+ async update(patch, expectedRevision) {
113
+ if (!isFeatureMap(patch) || (expectedRevision !== undefined &&
114
+ (!Number.isSafeInteger(expectedRevision) || expectedRevision < 0))) {
115
+ throw new FeatureSettingsError('FEATURE_SETTINGS_INVALID_PATCH', 'Feature settings accept only known feature IDs and boolean values.');
116
+ }
117
+ const changes = { ...patch };
118
+ if (!Object.keys(changes).length)
119
+ return this.checkRevision(this.get(), expectedRevision);
120
+ try {
121
+ fs.mkdirSync(path.dirname(this.filePath), { recursive: true });
122
+ }
123
+ catch {
124
+ throw new FeatureSettingsError('FEATURE_SETTINGS_WRITE_FAILED', 'Could not open the feature settings directory.');
125
+ }
126
+ const release = await this.acquireLock();
127
+ try {
128
+ const current = this.checkRevision(this.get(), expectedRevision);
129
+ if (Object.keys(changes).every(id => changes[id] === current.features[id]))
130
+ return current;
131
+ if (current.revision === Number.MAX_SAFE_INTEGER) {
132
+ throw new FeatureSettingsError('FEATURE_SETTINGS_INVALID_STORE', 'Feature settings revision has reached its limit.');
133
+ }
134
+ const next = {
135
+ schemaVersion: 1,
136
+ revision: current.revision + 1,
137
+ updatedAt: new Date().toISOString(),
138
+ features: { ...current.features, ...changes },
139
+ };
140
+ this.replace(next);
141
+ return next;
142
+ }
143
+ finally {
144
+ release();
145
+ }
146
+ }
147
+ checkRevision(snapshot, expectedRevision) {
148
+ if (expectedRevision !== undefined && expectedRevision !== snapshot.revision) {
149
+ throw new FeatureSettingsError('FEATURE_SETTINGS_CONFLICT', 'Feature settings changed. Refresh them and retry the update.');
150
+ }
151
+ return snapshot;
152
+ }
153
+ async acquireLock() {
154
+ const lock = this.filePath + '.lock';
155
+ const deadline = performance.now() + this.lockTimeoutMs;
156
+ for (;;) {
157
+ let fd;
158
+ try {
159
+ fd = fs.openSync(lock, 'wx', 0o600);
160
+ }
161
+ catch (error) {
162
+ if (errorCode(error) !== 'EEXIST') {
163
+ throw new FeatureSettingsError('FEATURE_SETTINGS_LOCK_FAILED', 'Could not acquire the feature settings lock.');
164
+ }
165
+ const remaining = deadline - performance.now();
166
+ if (remaining <= 0)
167
+ break;
168
+ await delay(Math.min(remaining, LOCK_POLL_MS));
169
+ if (performance.now() >= deadline)
170
+ break;
171
+ continue;
172
+ }
173
+ let owner;
174
+ try {
175
+ owner = fs.fstatSync(fd, { bigint: true });
176
+ }
177
+ catch {
178
+ try {
179
+ fs.closeSync(fd);
180
+ }
181
+ catch { /* Preserve the original lock error. */ }
182
+ throw new FeatureSettingsError('FEATURE_SETTINGS_LOCK_FAILED', 'Could not identify the feature settings lock.');
183
+ }
184
+ return () => {
185
+ try {
186
+ fs.closeSync(fd);
187
+ const current = fs.lstatSync(lock, { bigint: true, throwIfNoEntry: false });
188
+ if (current?.dev !== owner.dev || current.ino !== owner.ino) {
189
+ throw new Error('Lock ownership changed.');
190
+ }
191
+ fs.unlinkSync(lock);
192
+ }
193
+ catch {
194
+ throw new FeatureSettingsError('FEATURE_SETTINGS_LOCK_FAILED', 'Could not release the feature settings lock.');
195
+ }
196
+ };
197
+ }
198
+ throw new FeatureSettingsError('FEATURE_SETTINGS_LOCK_TIMEOUT', 'Timed out waiting for the feature settings lock.');
199
+ }
200
+ replace(snapshot) {
201
+ const temporary = this.filePath + '.' + randomUUID() + '.tmp';
202
+ let created = false;
203
+ try {
204
+ const fd = fs.openSync(temporary, 'wx', 0o600);
205
+ created = true;
206
+ try {
207
+ fs.writeFileSync(fd, JSON.stringify(snapshot, null, 2) + '\n');
208
+ fs.fsyncSync(fd);
209
+ }
210
+ finally {
211
+ fs.closeSync(fd);
212
+ }
213
+ fs.renameSync(temporary, this.filePath);
214
+ created = false;
215
+ }
216
+ catch {
217
+ throw new FeatureSettingsError('FEATURE_SETTINGS_WRITE_FAILED', 'Could not save feature settings.');
218
+ }
219
+ finally {
220
+ if (created) {
221
+ try {
222
+ fs.unlinkSync(temporary);
223
+ }
224
+ catch { /* Preserve the original write error. */ }
225
+ }
226
+ }
227
+ }
228
+ }
229
+ export function getFeatureSettings() {
230
+ return new FeatureSettingsStore();
231
+ }
232
+ //# sourceMappingURL=feature-settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feature-settings.js","sourceRoot":"","sources":["../../src/brain/feature-settings.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,7 @@ interface RecallOptions {
8
8
  limit?: number;
9
9
  minImportance?: number;
10
10
  }
11
+ export declare function normalizeRecallKeywords(keywords: unknown): string[];
11
12
  /** Local JSON store shared by cooperating Global Brain processes. */
12
13
  export declare class GlobalBrain {
13
14
  private static instance;
@@ -1 +1 @@
1
- {"version":3,"file":"global-brain.d.ts","sourceRoot":"","sources":["../../src/brain/global-brain.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,SAAS,EACT,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,wBAAwB,EACxB,WAAW,EAEX,iBAAiB,EAClB,MAAM,aAAa,CAAC;AAsBrB,KAAK,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,GAAG,WAAW,GAAG,cAAc,GAAG,aAAa,CAAC,CAAC;AAiDzF,UAAU,aAAa;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAgHD,qEAAqE;AACrE,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA4B;IACnD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;IAC3C,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA0B;IAC5D,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmB;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAc;IACxC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,kBAAkB,CAAuB;IACjD,OAAO,CAAC,SAAS,CAA+C;IAEhE,OAAO;IAkBP,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG,WAAW;IAK9D,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,OAAO,CAAC,UAAU;IAoBlB,uDAAuD;IACvD,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM;IAK5C,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM;IAYvD,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAMrC,6FAA6F;IACvF,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;IAWhD,mEAAmE;IACnE,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM;IAQpC,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,YAAY;IAkBpB,0DAA0D;IAC1D,MAAM,CAAC,IAAI,GAAE,aAAkB,GAAG,WAAW,EAAE;IAW/C,qFAAqF;IACrF,YAAY,CAAC,IAAI,GAAE,aAAa,GAAG;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,iBAAiB,EAAE;IA6BxF,OAAO,CAAC,WAAW;IAgCnB,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,iBAAiB;IAsBzB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAUvB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,WAAW,EAAE;IASzC,+DAA+D;IAC/D,QAAQ,CAAC,IAAI,GAAE,IAAI,CAAC,aAAa,EAAE,WAAW,GAAG,WAAW,GAAG,UAAU,GAAG,OAAO,CAAM,GAAG,kBAAkB,EAAE;IAahH,QAAQ,IAAI,gBAAgB;IAW5B,OAAO,CAAC,iBAAiB;IAIzB,gDAAgD;IAChD,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,gBAAgB,IAAI,wBAAwB;IAW5C,iFAAiF;IAC3E,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAmBb,aAAa;IA8C3B,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,kBAAkB;IAoB1B,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,eAAe;IAUvB,OAAO,CAAC,eAAe;IAmDvB,OAAO,CAAC,iBAAiB;YAgBX,WAAW;IAmDzB,OAAO,CAAC,eAAe;IAyBjB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAchC;AAED,wBAAgB,cAAc,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG,WAAW,CAE/E"}
1
+ {"version":3,"file":"global-brain.d.ts","sourceRoot":"","sources":["../../src/brain/global-brain.ts"],"names":[],"mappings":"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"}
@@ -89,7 +89,7 @@ function hydrateEntry(entry) {
89
89
  function normalizeText(value) {
90
90
  return value.trim().replace(/\s+/g, ' ').toLowerCase();
91
91
  }
92
- function normalizeKeywords(keywords) {
92
+ export function normalizeRecallKeywords(keywords) {
93
93
  if (!Array.isArray(keywords))
94
94
  return [];
95
95
  const unique = new Set();
@@ -260,7 +260,7 @@ export class GlobalBrain {
260
260
  recall(opts = {}) {
261
261
  if (!this.initialized)
262
262
  return [];
263
- const keywords = normalizeKeywords(opts.keywords);
263
+ const keywords = normalizeRecallKeywords(opts.keywords);
264
264
  const result = this.findMatches(opts, keywords)
265
265
  .sort((a, b) => b.relevance - a.relevance || this.compareEntries(a.entry, b.entry))
266
266
  .slice(0, nonNegativeInt(opts.limit, 20))
@@ -272,7 +272,7 @@ export class GlobalBrain {
272
272
  recallScored(opts = {}) {
273
273
  if (!this.initialized)
274
274
  return [];
275
- const keywords = normalizeKeywords(opts.keywords);
275
+ const keywords = normalizeRecallKeywords(opts.keywords);
276
276
  const candidates = this.findMatches(opts, keywords);
277
277
  const evidence = new Map();
278
278
  for (const { entry } of candidates) {