@pcircle/memesh 4.6.2 → 4.7.2
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +2 -2
- package/AGENTS.md +9 -2
- package/README.de.md +80 -17
- package/README.md +22 -11
- package/README.zh-TW.md +79 -17
- package/dashboard/dist/index.html +6 -6
- package/dist/core/analytics.d.ts.map +1 -1
- package/dist/core/analytics.js +1 -1
- package/dist/core/analytics.js.map +1 -1
- package/dist/core/briefing.d.ts.map +1 -1
- package/dist/core/briefing.js +1 -0
- package/dist/core/briefing.js.map +1 -1
- package/dist/core/citation-rule.d.ts +24 -0
- package/dist/core/citation-rule.d.ts.map +1 -0
- package/dist/core/citation-rule.js +71 -0
- package/dist/core/citation-rule.js.map +1 -0
- package/dist/core/conflict-candidates.d.ts.map +1 -1
- package/dist/core/conflict-candidates.js +4 -12
- package/dist/core/conflict-candidates.js.map +1 -1
- package/dist/core/conflict-judge.d.ts +11 -0
- package/dist/core/conflict-judge.d.ts.map +1 -1
- package/dist/core/conflict-judge.js +1 -1
- package/dist/core/conflict-judge.js.map +1 -1
- package/dist/core/demo.d.ts.map +1 -1
- package/dist/core/demo.js +22 -3
- package/dist/core/demo.js.map +1 -1
- package/dist/core/digest-validator.d.ts.map +1 -1
- package/dist/core/digest-validator.js +3 -3
- package/dist/core/digest-validator.js.map +1 -1
- package/dist/core/doctor.d.ts.map +1 -1
- package/dist/core/doctor.js +130 -22
- package/dist/core/doctor.js.map +1 -1
- package/dist/core/dreamer.d.ts.map +1 -1
- package/dist/core/dreamer.js +10 -6
- package/dist/core/dreamer.js.map +1 -1
- package/dist/core/install-channel.d.ts +7 -2
- package/dist/core/install-channel.d.ts.map +1 -1
- package/dist/core/install-channel.js +44 -7
- package/dist/core/install-channel.js.map +1 -1
- package/dist/core/install-hooks.d.ts +6 -0
- package/dist/core/install-hooks.d.ts.map +1 -1
- package/dist/core/install-hooks.js +0 -0
- package/dist/core/install-hooks.js.map +1 -1
- package/dist/core/kg-backfill.d.ts.map +1 -1
- package/dist/core/kg-backfill.js +1 -1
- package/dist/core/kg-backfill.js.map +1 -1
- package/dist/core/lesson-engine.d.ts.map +1 -1
- package/dist/core/lesson-engine.js +3 -3
- package/dist/core/lesson-engine.js.map +1 -1
- package/dist/core/lifecycle.js +2 -2
- package/dist/core/llm-client.d.ts.map +1 -1
- package/dist/core/llm-client.js +7 -3
- package/dist/core/llm-client.js.map +1 -1
- package/dist/core/llm-telemetry.d.ts.map +1 -1
- package/dist/core/llm-telemetry.js +5 -2
- package/dist/core/llm-telemetry.js.map +1 -1
- package/dist/core/operations.d.ts +2 -0
- package/dist/core/operations.d.ts.map +1 -1
- package/dist/core/operations.js +2 -2
- package/dist/core/operations.js.map +1 -1
- package/dist/core/paths.d.ts.map +1 -1
- package/dist/core/paths.js +3 -2
- package/dist/core/paths.js.map +1 -1
- package/dist/core/patterns.d.ts +0 -5
- package/dist/core/patterns.d.ts.map +1 -1
- package/dist/core/patterns.js +1 -43
- package/dist/core/patterns.js.map +1 -1
- package/dist/core/schema-export.js +1 -1
- package/dist/core/schema-export.js.map +1 -1
- package/dist/core/serializer.d.ts.map +1 -1
- package/dist/core/serializer.js +53 -10
- package/dist/core/serializer.js.map +1 -1
- package/dist/core/signal-scorer.d.ts +0 -1
- package/dist/core/signal-scorer.d.ts.map +1 -1
- package/dist/core/signal-scorer.js +12 -8
- package/dist/core/signal-scorer.js.map +1 -1
- package/dist/core/transcript-extractor.d.ts +2 -0
- package/dist/core/transcript-extractor.d.ts.map +1 -1
- package/dist/core/transcript-extractor.js +10 -5
- package/dist/core/transcript-extractor.js.map +1 -1
- package/dist/core/types.d.ts +11 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/updater.d.ts.map +1 -1
- package/dist/core/updater.js +1 -1
- package/dist/core/updater.js.map +1 -1
- package/dist/core/why.d.ts +1 -1
- package/dist/core/why.d.ts.map +1 -1
- package/dist/core/why.js +5 -0
- package/dist/core/why.js.map +1 -1
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +20 -27
- package/dist/db.js.map +1 -1
- package/dist/knowledge-graph.d.ts +3 -1
- package/dist/knowledge-graph.d.ts.map +1 -1
- package/dist/knowledge-graph.js +44 -28
- package/dist/knowledge-graph.js.map +1 -1
- package/dist/skills-manifest.json +25 -20
- package/dist/storage/fts-index.d.ts.map +1 -1
- package/dist/storage/fts-index.js.map +1 -1
- package/dist/storage/schema.d.ts.map +1 -1
- package/dist/storage/schema.js +18 -22
- package/dist/storage/schema.js.map +1 -1
- package/dist/storage/vector-index.d.ts.map +1 -1
- package/dist/storage/vector-index.js +10 -4
- package/dist/storage/vector-index.js.map +1 -1
- package/dist/transports/cli/cli.js +131 -49
- package/dist/transports/cli/cli.js.map +1 -1
- package/dist/transports/http/server.d.ts.map +1 -1
- package/dist/transports/http/server.js +58 -3
- package/dist/transports/http/server.js.map +1 -1
- package/dist/transports/mcp/handlers.d.ts +5 -3
- package/dist/transports/mcp/handlers.d.ts.map +1 -1
- package/dist/transports/mcp/handlers.js +27 -18
- package/dist/transports/mcp/handlers.js.map +1 -1
- package/dist/transports/schemas.d.ts +0 -1
- package/dist/transports/schemas.d.ts.map +1 -1
- package/dist/transports/schemas.js +4 -3
- package/dist/transports/schemas.js.map +1 -1
- package/hooks/hooks.json +4 -2
- package/llms-install.md +28 -0
- package/package.json +2 -2
- package/scripts/hooks/_generated/citation-rule.js +78 -0
- package/scripts/hooks/_generated/core-paths.js +3 -2
- package/scripts/hooks/_generated/schema.js +18 -22
- package/scripts/hooks/_shared.js +75 -4
- package/scripts/hooks/guard-check.js +5 -0
- package/scripts/hooks/pre-compact.js +14 -7
- package/scripts/hooks/pre-edit-recall.js +22 -0
- package/scripts/hooks/session-start.js +106 -3
- package/scripts/hooks/session-summary.js +41 -4
- package/scripts/upgrade-plugin.sh +9 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/storage/schema.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAIlD,eAAO,MAAM,UAAU,gwJAkGtB,CAAC;AAGF,eAAO,MAAM,OAAO,ieAUnB,CAAC;AAYF,wBAAgB,SAAS,CAAC,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAO/D;AASD,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,cAAc,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/storage/schema.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAIlD,eAAO,MAAM,UAAU,gwJAkGtB,CAAC;AAGF,eAAO,MAAM,OAAO,ieAUnB,CAAC;AAYF,wBAAgB,SAAS,CAAC,EAAE,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAO/D;AASD,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,cAAc,GAAG,IAAI,CAwD9D;AAYD,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,cAAc,GAAG,IAAI,CA6B9D;AAeD,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,cAAc,GAAG,IAAI,CAgC5D;AAQD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAOxD;AAGD,eAAO,MAAM,0BAA0B,QAAsB,CAAC;AA+B9D,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,cAAc,EAClB,IAAI,EAAE;IACJ,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,CAAC,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5D,GACA,OAAO,CAoET;AAWD,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAG1C,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAuBzC,wBAAgB,eAAe,CAAC,EAAE,EAAE,cAAc,GAAG,IAAI,CAsDxD;AAkBD,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,cAAc,GAAG,IAAI,CAO9D"}
|
package/dist/storage/schema.js
CHANGED
|
@@ -122,28 +122,24 @@ export function safeAlter(db, sql) {
|
|
|
122
122
|
}
|
|
123
123
|
export function migrateEntitiesSchema(db) {
|
|
124
124
|
const entityColumns = new Set(db.prepare("PRAGMA table_info(entities)").all().map((c) => c.name));
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
if (!entityColumns.has('title')) {
|
|
145
|
-
safeAlter(db, "ALTER TABLE entities ADD COLUMN title TEXT");
|
|
146
|
-
}
|
|
125
|
+
const addColumn = (column, sql) => {
|
|
126
|
+
if (entityColumns.has(column))
|
|
127
|
+
return;
|
|
128
|
+
safeAlter(db, sql);
|
|
129
|
+
entityColumns.add(column);
|
|
130
|
+
};
|
|
131
|
+
addColumn('status', "ALTER TABLE entities ADD COLUMN status TEXT NOT NULL DEFAULT 'active'");
|
|
132
|
+
addColumn('access_count', "ALTER TABLE entities ADD COLUMN access_count INTEGER DEFAULT 0");
|
|
133
|
+
addColumn('last_accessed_at', "ALTER TABLE entities ADD COLUMN last_accessed_at TIMESTAMP");
|
|
134
|
+
addColumn('confidence', "ALTER TABLE entities ADD COLUMN confidence REAL DEFAULT 1.0");
|
|
135
|
+
addColumn('valid_from', "ALTER TABLE entities ADD COLUMN valid_from TIMESTAMP");
|
|
136
|
+
addColumn('valid_until', "ALTER TABLE entities ADD COLUMN valid_until TIMESTAMP");
|
|
137
|
+
addColumn('namespace', "ALTER TABLE entities ADD COLUMN namespace TEXT DEFAULT 'personal'");
|
|
138
|
+
addColumn('recall_hits', "ALTER TABLE entities ADD COLUMN recall_hits INTEGER DEFAULT 0");
|
|
139
|
+
addColumn('recall_misses', "ALTER TABLE entities ADD COLUMN recall_misses INTEGER DEFAULT 0");
|
|
140
|
+
addColumn('title', "ALTER TABLE entities ADD COLUMN title TEXT");
|
|
141
|
+
db.exec(`CREATE INDEX IF NOT EXISTS idx_entities_status ON entities(status);
|
|
142
|
+
CREATE INDEX IF NOT EXISTS idx_entities_namespace ON entities(namespace);`);
|
|
147
143
|
}
|
|
148
144
|
export function ensureTagsUniqueIndex(db) {
|
|
149
145
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/storage/schema.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,MAAM,CAAC,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkGzB,CAAC;AAGF,MAAM,CAAC,MAAM,OAAO,GAAG;;;;;;;;;;CAUtB,CAAC;AAYF,MAAM,UAAU,SAAS,CAAC,EAAkB,EAAE,GAAW;IACvD,IAAI,CAAC;QACH,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACf,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,GAAG,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACvD,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,GAAG,CAAC;YAAE,MAAM,CAAC,CAAC;IACnD,CAAC;AACH,CAAC;AASD,MAAM,UAAU,qBAAqB,CAAC,EAAkB;IACtD,MAAM,aAAa,GAAG,IAAI,GAAG,CAC1B,EAAE,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC,GAAG,EAA8B,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAChG,CAAC;
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/storage/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vector-index.d.ts","sourceRoot":"","sources":["../../src/storage/vector-index.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"vector-index.d.ts","sourceRoot":"","sources":["../../src/storage/vector-index.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAyBlD,wBAAgB,cAAc,CAAC,EAAE,EAAE,cAAc,GAAG,OAAO,CAS1D"}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
export function hasVectorIndex(db) {
|
|
2
|
-
|
|
3
|
-
.prepare(
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
try {
|
|
3
|
+
db.prepare('SELECT 1 FROM entities_vec LIMIT 1').get();
|
|
4
|
+
return true;
|
|
5
|
+
}
|
|
6
|
+
catch (err) {
|
|
7
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
8
|
+
if (/no such module: vec0|no such table/i.test(message))
|
|
9
|
+
return false;
|
|
10
|
+
throw err;
|
|
11
|
+
}
|
|
6
12
|
}
|
|
7
13
|
//# sourceMappingURL=vector-index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vector-index.js","sourceRoot":"","sources":["../../src/storage/vector-index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vector-index.js","sourceRoot":"","sources":["../../src/storage/vector-index.ts"],"names":[],"mappings":"AAqDA,MAAM,UAAU,cAAc,CAAC,EAAkB;IAC/C,IAAI,CAAC;QACH,EAAE,CAAC,OAAO,CAAC,oCAAoC,CAAC,CAAC,GAAG,EAAE,CAAC;QACvD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,IAAI,qCAAqC,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,OAAO,KAAK,CAAC;QACtE,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
|
|
@@ -17,14 +17,56 @@ import { installHooks } from '../../core/install-hooks.js';
|
|
|
17
17
|
import { getTaskState, setTaskState } from '../../core/task-state-store.js';
|
|
18
18
|
import { TASK_STATE_FIELDS, taskStateLines } from '../../core/task-state.js';
|
|
19
19
|
async function withDatabase(fn) {
|
|
20
|
-
|
|
20
|
+
try {
|
|
21
|
+
openDatabase();
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
25
|
+
console.error(`Error: memesh cannot open its database.`);
|
|
26
|
+
console.error(` ${message}`);
|
|
27
|
+
console.error(` Run \`memesh doctor\` — it names the file, the likely cause and the way back.`);
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
21
30
|
try {
|
|
22
31
|
return await fn();
|
|
23
32
|
}
|
|
24
33
|
finally {
|
|
34
|
+
await flushPendingEmbeddings();
|
|
25
35
|
closeDatabase();
|
|
26
36
|
}
|
|
27
37
|
}
|
|
38
|
+
function unitFraction(flag) {
|
|
39
|
+
return (value) => {
|
|
40
|
+
const parsed = Number(value);
|
|
41
|
+
if (!Number.isFinite(parsed) || parsed < 0 || parsed > 1) {
|
|
42
|
+
console.error(`Error: ${flag} needs a number between 0 and 1, not "${value}".`);
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
return parsed;
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function nonEmpty(flag) {
|
|
49
|
+
return (value) => {
|
|
50
|
+
if (value.trim() === '') {
|
|
51
|
+
console.error(`Error: ${flag} needs some text. An empty value is not a selector.`);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
return value;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
function proposalId(raw) {
|
|
58
|
+
return wholeNumber('<id>')(raw);
|
|
59
|
+
}
|
|
60
|
+
function wholeNumber(flag, min = 1) {
|
|
61
|
+
return (value) => {
|
|
62
|
+
const parsed = Number(value);
|
|
63
|
+
if (!Number.isInteger(parsed) || parsed < min) {
|
|
64
|
+
console.error(`Error: ${flag} needs a whole number of ${min} or more, not "${value}".`);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
return parsed;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
28
70
|
function requireOneOf(value, allowed, flag) {
|
|
29
71
|
if (value === undefined || allowed.includes(value))
|
|
30
72
|
return;
|
|
@@ -106,6 +148,10 @@ program
|
|
|
106
148
|
' memesh remember "Use OAuth 2.0 with PKCE"');
|
|
107
149
|
process.exit(1);
|
|
108
150
|
}
|
|
151
|
+
if (opts.obs?.some((o) => o.trim() === '')) {
|
|
152
|
+
console.error('Error: --obs needs some text. An empty or whitespace-only observation is not a memory.');
|
|
153
|
+
process.exit(1);
|
|
154
|
+
}
|
|
109
155
|
const relations = [
|
|
110
156
|
...(opts.supersedes ?? []).map(to => ({ to, type: 'supersedes' })),
|
|
111
157
|
...(opts.contradicts ?? []).map(to => ({ to, type: 'contradicts' })),
|
|
@@ -143,7 +189,6 @@ program
|
|
|
143
189
|
}
|
|
144
190
|
if (result.relationErrors?.length)
|
|
145
191
|
process.exitCode = 1;
|
|
146
|
-
await flushPendingEmbeddings();
|
|
147
192
|
});
|
|
148
193
|
});
|
|
149
194
|
program
|
|
@@ -151,7 +196,7 @@ program
|
|
|
151
196
|
.description('Search stored knowledge')
|
|
152
197
|
.argument('[query]', 'Search query')
|
|
153
198
|
.option('--tag <tag>', 'Filter by tag')
|
|
154
|
-
.option('--limit <n>', 'Max results', '
|
|
199
|
+
.option('--limit <n>', 'Max results', wholeNumber('--limit'), 20)
|
|
155
200
|
.option('--include-archived', 'Include archived entities')
|
|
156
201
|
.option('--namespace <namespace>', 'Filter by namespace: personal, team, or global')
|
|
157
202
|
.option('--cross-project', 'Search across all project tags (ignores --tag filter)')
|
|
@@ -162,7 +207,7 @@ program
|
|
|
162
207
|
const { entities, conflicts, retrieval } = await recallWithConflicts({
|
|
163
208
|
query: query || undefined,
|
|
164
209
|
tag: opts.tag,
|
|
165
|
-
limit:
|
|
210
|
+
limit: opts.limit,
|
|
166
211
|
include_archived: opts.includeArchived,
|
|
167
212
|
namespace: opts.namespace,
|
|
168
213
|
cross_project: opts.crossProject,
|
|
@@ -171,7 +216,15 @@ program
|
|
|
171
216
|
console.log(JSON.stringify(conflicts.length > 0 ? { entities, retrieval, conflicts } : { entities, retrieval }));
|
|
172
217
|
}
|
|
173
218
|
else if (entities.length === 0) {
|
|
174
|
-
|
|
219
|
+
if (query && retrieval.degraded) {
|
|
220
|
+
console.log('No results found. Semantic search is configured but could not run for this query (provider or index issue) — this was keyword-only. Run `memesh doctor` to check.');
|
|
221
|
+
}
|
|
222
|
+
else if (query && retrieval.mode === 'fts') {
|
|
223
|
+
console.log('No results found. This was a keyword-only search — no semantic search is configured. See `memesh doctor` for Smart Mode.');
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
console.log('No results found.');
|
|
227
|
+
}
|
|
175
228
|
}
|
|
176
229
|
else {
|
|
177
230
|
const allSemantic = query && entities.every((e) => e.match?.source === 'semantic');
|
|
@@ -216,7 +269,7 @@ program
|
|
|
216
269
|
.command('forget')
|
|
217
270
|
.description('Archive an entity or remove an observation (soft-delete, recoverable)')
|
|
218
271
|
.requiredOption('--name <name>', 'Entity name')
|
|
219
|
-
.option('--observation <text>', 'Remove specific observation only')
|
|
272
|
+
.option('--observation <text>', 'Remove specific observation only', nonEmpty('--observation'))
|
|
220
273
|
.option('--json', 'Output as JSON')
|
|
221
274
|
.option('--confirm', '[deprecated, no-op] forget is a soft archive — no confirmation needed')
|
|
222
275
|
.action(async (opts) => {
|
|
@@ -234,7 +287,7 @@ program
|
|
|
234
287
|
else if (result.observation_removed) {
|
|
235
288
|
console.log(`✂️ Removed observation (${result.remaining_observations} remaining)`);
|
|
236
289
|
}
|
|
237
|
-
else if (opts.observation && result.entity_found) {
|
|
290
|
+
else if (opts.observation !== undefined && result.entity_found) {
|
|
238
291
|
console.log(`Entity "${opts.name}" has no observation matching that text (${result.remaining_observations} observation(s) present).`);
|
|
239
292
|
console.log(`See them with: memesh recall "${opts.name}" --json`);
|
|
240
293
|
process.exitCode = 1;
|
|
@@ -316,7 +369,7 @@ program
|
|
|
316
369
|
.description('Export memories as JSON. Defaults to stdout (pipe-friendly); use `-o <file>` to write directly.')
|
|
317
370
|
.option('--tag <tag>', 'Export only entities with this tag')
|
|
318
371
|
.option('--namespace <ns>', 'Export only from this namespace (personal, team, global)')
|
|
319
|
-
.option('--limit <n>', 'Max entities to export', '
|
|
372
|
+
.option('--limit <n>', 'Max entities to export', wholeNumber('--limit'), 1000)
|
|
320
373
|
.option('-o, --out <file>', 'Write JSON to <file> instead of stdout. Parent directory must exist.')
|
|
321
374
|
.action(async (opts) => {
|
|
322
375
|
requireOneOf(opts.namespace, NAMESPACES, '--namespace');
|
|
@@ -324,7 +377,7 @@ program
|
|
|
324
377
|
const result = exportMemories({
|
|
325
378
|
tag: opts.tag,
|
|
326
379
|
namespace: opts.namespace,
|
|
327
|
-
limit:
|
|
380
|
+
limit: opts.limit,
|
|
328
381
|
});
|
|
329
382
|
const json = JSON.stringify(result, null, 2);
|
|
330
383
|
if (opts.out) {
|
|
@@ -340,6 +393,10 @@ program
|
|
|
340
393
|
else {
|
|
341
394
|
console.log(json);
|
|
342
395
|
}
|
|
396
|
+
if (result.truncated) {
|
|
397
|
+
process.stderr.write(`⚠️ This is NOT the whole graph — ${result.entity_count} entities is the --limit, and there are more.\n`
|
|
398
|
+
+ ` For a full backup, raise it: memesh export --limit 100000${opts.out ? ` -o ${opts.out}` : ''}\n`);
|
|
399
|
+
}
|
|
343
400
|
});
|
|
344
401
|
});
|
|
345
402
|
program
|
|
@@ -394,7 +451,13 @@ program
|
|
|
394
451
|
console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
395
452
|
process.exit(1);
|
|
396
453
|
}
|
|
397
|
-
|
|
454
|
+
const overwriteNote = result.overwritten > 0 ? ` (${result.overwritten} overwritten)` : '';
|
|
455
|
+
console.log(`Imported: ${result.imported}${overwriteNote}, Skipped: ${result.skipped}, Appended: ${result.appended}`);
|
|
456
|
+
if (result.skipped_relations.length > 0) {
|
|
457
|
+
console.error(`Note: ${result.skipped_relations.length} relation(s) not restored — the target is not in this bundle:\n `
|
|
458
|
+
+ `${result.skipped_relations.join('\n ')}`);
|
|
459
|
+
console.error(` Export those entities too (widen --limit, or drop --tag/--namespace) to keep the links.`);
|
|
460
|
+
}
|
|
398
461
|
if (result.errors.length > 0) {
|
|
399
462
|
console.error(`Errors:\n ${result.errors.join('\n ')}`);
|
|
400
463
|
process.exitCode = 1;
|
|
@@ -452,6 +515,7 @@ program
|
|
|
452
515
|
const WHY_ABSTENTION_TEXT = {
|
|
453
516
|
git_unavailable: 'git is not installed or not on PATH — commit attribution unavailable.',
|
|
454
517
|
not_a_git_repo: 'Not inside a git repository — commit attribution unavailable.',
|
|
518
|
+
file_not_found: 'No such file.',
|
|
455
519
|
file_not_tracked: 'File is not tracked by git — commit attribution unavailable.',
|
|
456
520
|
history_unreadable: "git could not read this file's history (too much output, too slow, or the repository has no commits yet) — nothing is listed because the question went unanswered, not because no commit touched the file.",
|
|
457
521
|
no_commits_supplied: 'No commit hashes were supplied — only the file-tag half of this answer ran.',
|
|
@@ -464,21 +528,15 @@ program
|
|
|
464
528
|
.command('why')
|
|
465
529
|
.description('Explain a file: commits memesh remembers touching it, their sessions, and related memories')
|
|
466
530
|
.argument('<file>', 'File path (relative to the current directory or absolute)')
|
|
467
|
-
.option('--line <n>', 'Attribute one line via git blame instead of file history')
|
|
468
|
-
.option('--limit <n>', 'Max commits to inspect', '
|
|
531
|
+
.option('--line <n>', 'Attribute one line via git blame instead of file history', wholeNumber('--line'))
|
|
532
|
+
.option('--limit <n>', 'Max commits to inspect', wholeNumber('--limit'), 10)
|
|
469
533
|
.option('--json', 'Output as JSON')
|
|
470
534
|
.action(async (file, opts) => {
|
|
471
535
|
await withDatabase(async () => {
|
|
472
536
|
const { resolveFileCommits, explainCommits } = await import('../../core/why.js');
|
|
473
537
|
const cwd = process.cwd();
|
|
474
|
-
const limit =
|
|
475
|
-
const line = opts.line
|
|
476
|
-
for (const [flag, value] of [['--limit', limit], ['--line', line]]) {
|
|
477
|
-
if (value !== undefined && (!Number.isInteger(value) || value < 1)) {
|
|
478
|
-
console.error(`Error: ${flag} needs a whole number of 1 or more.`);
|
|
479
|
-
process.exit(1);
|
|
480
|
-
}
|
|
481
|
-
}
|
|
538
|
+
const limit = opts.limit;
|
|
539
|
+
const line = opts.line;
|
|
482
540
|
const resolved = resolveFileCommits(cwd, file, { line, limit });
|
|
483
541
|
const result = explainCommits(getDatabase(), {
|
|
484
542
|
file,
|
|
@@ -487,6 +545,8 @@ program
|
|
|
487
545
|
limit,
|
|
488
546
|
abstentions: resolved.abstention ? [resolved.abstention] : [],
|
|
489
547
|
});
|
|
548
|
+
if (result.abstentions.includes('file_not_found'))
|
|
549
|
+
process.exitCode = 1;
|
|
490
550
|
if (opts.json) {
|
|
491
551
|
console.log(JSON.stringify(result, null, 2));
|
|
492
552
|
return;
|
|
@@ -631,7 +691,7 @@ program
|
|
|
631
691
|
.option('--done <text>', 'What was just finished')
|
|
632
692
|
.option('--json', 'Output as JSON')
|
|
633
693
|
.action(async (opts) => {
|
|
634
|
-
await withDatabase(() => {
|
|
694
|
+
await withDatabase(async () => {
|
|
635
695
|
const patch = {};
|
|
636
696
|
for (const field of TASK_STATE_FIELDS) {
|
|
637
697
|
if (opts[field] !== undefined)
|
|
@@ -709,6 +769,8 @@ const KEY_VALIDATORS = {
|
|
|
709
769
|
},
|
|
710
770
|
'embedder.provider': (v) => ['openai', 'ollama'].includes(v) ? null : `must be one of: openai, ollama`,
|
|
711
771
|
'autoUpdate': (v) => ['off', 'patch', 'minor', 'major'].includes(v) ? null : `must be one of: off, patch, minor, major`,
|
|
772
|
+
'autoCapture': (v) => ['true', 'false', '1', '0'].includes(v) ? null : `must be one of: true, false, 1, 0`,
|
|
773
|
+
'transcriptMining': (v) => ['true', 'false', '1', '0'].includes(v) ? null : `must be one of: true, false, 1, 0`,
|
|
712
774
|
'llmFallbacks': (v) => {
|
|
713
775
|
let parsed;
|
|
714
776
|
try {
|
|
@@ -813,8 +875,9 @@ configCmd
|
|
|
813
875
|
}
|
|
814
876
|
}
|
|
815
877
|
let coerced = value;
|
|
816
|
-
if (canonical === 'sessionLimit')
|
|
817
|
-
coerced =
|
|
878
|
+
if (canonical === 'sessionLimit') {
|
|
879
|
+
coerced = wholeNumber('sessionLimit')(value);
|
|
880
|
+
}
|
|
818
881
|
if (canonical === 'llmFallbacks')
|
|
819
882
|
coerced = JSON.parse(value);
|
|
820
883
|
if (canonical === 'autoCapture') {
|
|
@@ -898,13 +961,13 @@ program
|
|
|
898
961
|
program
|
|
899
962
|
.command('serve')
|
|
900
963
|
.description('Start the HTTP API server and web dashboard')
|
|
901
|
-
.option('--port <port>', 'Port number', '
|
|
964
|
+
.option('--port <port>', 'Port number', wholeNumber('--port', 0), 3737)
|
|
902
965
|
.option('--host <host>', 'Host to bind', '127.0.0.1')
|
|
903
966
|
.option('--allow-remote', 'Permit binding to a non-loopback host. Pair it with --host; on a non-loopback bind a bearer token is generated and REQUIRED for every /v1 request, and the startup output says where it lives. On the default loopback host this flag changes nothing.')
|
|
904
967
|
.action(async (opts) => {
|
|
905
968
|
const { startServer } = await import('../http/server.js');
|
|
906
969
|
try {
|
|
907
|
-
startServer(opts.host,
|
|
970
|
+
startServer(opts.host, opts.port, { allowRemote: opts.allowRemote, autoUpdateCheck: true });
|
|
908
971
|
}
|
|
909
972
|
catch (err) {
|
|
910
973
|
console.error(`MeMesh: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -917,7 +980,7 @@ program
|
|
|
917
980
|
.action(async () => {
|
|
918
981
|
const { getCurrentInstallChannel, getInstallChannelSupport } = await import('../../core/install-channel.js');
|
|
919
982
|
const install = getCurrentInstallChannel({ packageRoot });
|
|
920
|
-
const installSupport = getInstallChannelSupport(install);
|
|
983
|
+
const installSupport = getInstallChannelSupport(install, packageRoot);
|
|
921
984
|
if (!installSupport.canSelfUpdate) {
|
|
922
985
|
console.error(`❌ memesh update does not support this install method (${installSupport.label}).`);
|
|
923
986
|
console.error(` ${installSupport.guidance}`);
|
|
@@ -998,16 +1061,10 @@ program
|
|
|
998
1061
|
program
|
|
999
1062
|
.command('telemetry')
|
|
1000
1063
|
.description('Show LLM call telemetry (per-flow scorecard for the last N days)')
|
|
1001
|
-
.option('--window <days>', 'Look-back window in days (default 30)', (
|
|
1002
|
-
.option('--prune <days>', 'Delete rows older than N days BEFORE rendering (closes v4.2.0 retention gap)', (
|
|
1064
|
+
.option('--window <days>', 'Look-back window in days (default 30)', wholeNumber('--window'), 30)
|
|
1065
|
+
.option('--prune <days>', 'Delete rows older than N days BEFORE rendering (closes v4.2.0 retention gap)', wholeNumber('--prune', 0))
|
|
1003
1066
|
.option('--json', 'Output as JSON')
|
|
1004
1067
|
.action(async (opts) => {
|
|
1005
|
-
for (const [flag, value] of [['--window', opts.window], ['--prune', opts.prune]]) {
|
|
1006
|
-
if (value !== undefined && !Number.isFinite(value)) {
|
|
1007
|
-
console.error(`Error: ${flag} needs a number of days.`);
|
|
1008
|
-
process.exit(1);
|
|
1009
|
-
}
|
|
1010
|
-
}
|
|
1011
1068
|
await withDatabase(async () => {
|
|
1012
1069
|
const { summariseTelemetry, pruneTelemetry } = await import('../../core/llm-telemetry.js');
|
|
1013
1070
|
let pruneResult = null;
|
|
@@ -1074,12 +1131,12 @@ kgCmd
|
|
|
1074
1131
|
.description('Propose / apply heuristic relations to connect orphan entities (no LLM)')
|
|
1075
1132
|
.option('--project <name>', 'Restrict to one project')
|
|
1076
1133
|
.option('--dry-run', 'Show proposals without writing (default off — use to preview)')
|
|
1077
|
-
.option('--max-per-source <n>', 'Max edges per orphan (default 3)', (
|
|
1078
|
-
.option('--min-shared-tags <n>', 'Min shared topical tags to gate co-occurrence rule (default 2)', (
|
|
1134
|
+
.option('--max-per-source <n>', 'Max edges per orphan (default 3)', wholeNumber('--max-per-source'), 3)
|
|
1135
|
+
.option('--min-shared-tags <n>', 'Min shared topical tags to gate co-occurrence rule (default 2)', wholeNumber('--min-shared-tags'), 2)
|
|
1079
1136
|
.option('--include-archived', 'Also process archived entities')
|
|
1080
1137
|
.option('--session-cooccurrence', 'Rule 3: link high-signal orphans co-created in the same session')
|
|
1081
1138
|
.option('--name-tokens', 'Rule 4: link orphans sharing ≥3 name content tokens (or Jaccard ≥ 0.50)')
|
|
1082
|
-
.option('--min-jaccard <n>', 'Jaccard threshold for name similarity (default 0.50)',
|
|
1139
|
+
.option('--min-jaccard <n>', 'Jaccard threshold for name similarity (default 0.50)', unitFraction('--min-jaccard'))
|
|
1083
1140
|
.option('--all-rules', 'Enable all heuristic rules (Rules 1–5)')
|
|
1084
1141
|
.option('--no-evidence-links', 'Disable Rule 5: evidence → work-item links via shared session id (on by default — these edges feed the graph\'s evidence badges)')
|
|
1085
1142
|
.option('--reset-idempotency', 'Clear the persistent "already-attempted" orphan cache before running (use after schema changes or to reconsider every orphan)')
|
|
@@ -1324,12 +1381,12 @@ dreamCmd
|
|
|
1324
1381
|
.description('Run a dream pass — propose digests for clusters of compactable entities')
|
|
1325
1382
|
.option('--project <name>', 'Restrict to one project')
|
|
1326
1383
|
.option('--dry-run', 'Compute proposals without writing to dream_proposals')
|
|
1327
|
-
.option('--max-llm-calls <n>', 'Hard cap on LLM calls (default 100)', (
|
|
1328
|
-
.option('--window-days <n>', 'Look-back window in days (default 56 = 8 weeks)', (
|
|
1384
|
+
.option('--max-llm-calls <n>', 'Hard cap on LLM calls (default 100)', wholeNumber('--max-llm-calls'))
|
|
1385
|
+
.option('--window-days <n>', 'Look-back window in days (default 56 = 8 weeks)', wholeNumber('--window-days'))
|
|
1329
1386
|
.option('--validate', 'Run a second LLM pass to cross-check each digest against its sources (doubles LLM calls per proposal; surfaces under flow=digest_validator in `memesh telemetry`)')
|
|
1330
1387
|
.option('--from-transcripts', 'EXPERIMENTAL: mine Claude Code session transcripts for this project (decisions/lessons/facts hidden in the conversation) and STAGE them as proposals for `dream accept`, instead of clustering existing entities. Scoped to the current project only — --project does not apply here. With --dry-run, lists sessions and conversation-turn counts without calling an LLM.')
|
|
1331
1388
|
.option('--if-due', 'For a scheduler (cron/launchd): only mine if `transcriptMining` is enabled in config AND at least --min-interval-hours have passed since this project was last mined; otherwise exit 0 doing nothing. Lets one frequently-firing entry self-throttle. Only meaningful with --from-transcripts.')
|
|
1332
|
-
.option('--min-interval-hours <n>', 'With --if-due: minimum hours between mined runs for this project (default 24).', (
|
|
1389
|
+
.option('--min-interval-hours <n>', 'With --if-due: minimum hours between mined runs for this project (default 24).', wholeNumber('--min-interval-hours'))
|
|
1333
1390
|
.action(async (opts) => {
|
|
1334
1391
|
if (opts.fromTranscripts) {
|
|
1335
1392
|
const windowDays = typeof opts.windowDays === 'number' && !Number.isNaN(opts.windowDays) ? opts.windowDays : 3;
|
|
@@ -1406,6 +1463,10 @@ dreamCmd
|
|
|
1406
1463
|
console.log(` LLM call failures: ${result.llmFailures} (sessions not mined — retry when the provider is reachable)`);
|
|
1407
1464
|
if (result.parseFailures > 0)
|
|
1408
1465
|
console.log(` unparsable replies: ${result.parseFailures} (chunk reply not valid JSON — likely truncated; those candidates were lost, retry)`);
|
|
1466
|
+
if (result.cappedTurns > 0) {
|
|
1467
|
+
console.log(` per-turn cap: ${result.cappedTurns} turn(s) were analysed only in part `
|
|
1468
|
+
+ `(the first 4,000 characters); the rest of each was not sent`);
|
|
1469
|
+
}
|
|
1409
1470
|
if (result.truncatedTurns > 0) {
|
|
1410
1471
|
console.log(` size-cap truncation: ${result.truncatedTurns} conversation turn(s) beyond the cap were NOT analysed`);
|
|
1411
1472
|
for (const t of result.truncatedSessions) {
|
|
@@ -1477,9 +1538,9 @@ dreamCmd
|
|
|
1477
1538
|
.description('Run pattern detector — surface emerging patterns/conventions/repeated mistakes per project (Phase 3)')
|
|
1478
1539
|
.option('--project <name>', 'Restrict to one project (default: all projects)')
|
|
1479
1540
|
.option('--dry-run', 'Compute proposals without writing to dream_proposals')
|
|
1480
|
-
.option('--max-llm-calls <n>', 'Hard cap on LLM calls (default 10)', (
|
|
1481
|
-
.option('--window-days <n>', 'Look-back window in days (default 30)', (
|
|
1482
|
-
.option('--min-signal <n>', 'Minimum signal_score to include in scan (default 0.3)', (
|
|
1541
|
+
.option('--max-llm-calls <n>', 'Hard cap on LLM calls (default 10)', wholeNumber('--max-llm-calls'))
|
|
1542
|
+
.option('--window-days <n>', 'Look-back window in days (default 30)', wholeNumber('--window-days'))
|
|
1543
|
+
.option('--min-signal <n>', 'Minimum signal_score to include in scan (default 0.3)', unitFraction('--min-signal'))
|
|
1483
1544
|
.action(async (opts) => {
|
|
1484
1545
|
await withDatabase(async () => {
|
|
1485
1546
|
const { runPatternDetector } = await import('../../core/dreamer.js');
|
|
@@ -1551,7 +1612,7 @@ dreamCmd
|
|
|
1551
1612
|
dreamCmd
|
|
1552
1613
|
.command('conflicts')
|
|
1553
1614
|
.description('Judge semantically-close memory pairs for contradiction / supersession / duplication (LLM) and stage relation proposals for review')
|
|
1554
|
-
.option('--max-pairs <n>', 'Judge at most N of the tightest candidate pairs this run (default 20)', (
|
|
1615
|
+
.option('--max-pairs <n>', 'Judge at most N of the tightest candidate pairs this run (default 20)', wholeNumber('--max-pairs'))
|
|
1555
1616
|
.option('--dry-run', 'Show how many candidates are queued without calling an LLM or writing anything')
|
|
1556
1617
|
.action(async (opts) => {
|
|
1557
1618
|
await withDatabase(async () => {
|
|
@@ -1599,7 +1660,7 @@ dreamCmd
|
|
|
1599
1660
|
await withDatabase(async () => {
|
|
1600
1661
|
const { getProposalDetail } = await import('../../core/dreamer.js');
|
|
1601
1662
|
const { getDatabase } = await import('../../db.js');
|
|
1602
|
-
const detail = getProposalDetail(getDatabase(),
|
|
1663
|
+
const detail = getProposalDetail(getDatabase(), proposalId(id));
|
|
1603
1664
|
if (!detail) {
|
|
1604
1665
|
console.error(`proposal #${id} not found`);
|
|
1605
1666
|
console.error('See ids with: memesh dream list');
|
|
@@ -1660,14 +1721,13 @@ dreamCmd
|
|
|
1660
1721
|
const kg = new KnowledgeGraph(getDatabase());
|
|
1661
1722
|
let result;
|
|
1662
1723
|
try {
|
|
1663
|
-
result = applyProposal(getDatabase(),
|
|
1724
|
+
result = applyProposal(getDatabase(), proposalId(id), kg);
|
|
1664
1725
|
}
|
|
1665
1726
|
catch (err) {
|
|
1666
1727
|
console.error(err instanceof Error ? err.message : String(err));
|
|
1667
1728
|
console.error('See pending ids with: memesh dream list');
|
|
1668
1729
|
process.exit(1);
|
|
1669
1730
|
}
|
|
1670
|
-
await flushPendingEmbeddings();
|
|
1671
1731
|
console.log(`Applied proposal #${result.proposalId}`);
|
|
1672
1732
|
console.log(` digest entity: ${result.digestEntityName}`);
|
|
1673
1733
|
console.log(` sources archived: ${result.sourcesArchived}`);
|
|
@@ -1682,7 +1742,7 @@ dreamCmd
|
|
|
1682
1742
|
const { rejectProposal } = await import('../../core/dreamer.js');
|
|
1683
1743
|
const { getDatabase } = await import('../../db.js');
|
|
1684
1744
|
try {
|
|
1685
|
-
rejectProposal(getDatabase(),
|
|
1745
|
+
rejectProposal(getDatabase(), proposalId(id), opts.reason);
|
|
1686
1746
|
}
|
|
1687
1747
|
catch (err) {
|
|
1688
1748
|
console.error(err instanceof Error ? err.message : String(err));
|
|
@@ -1716,6 +1776,15 @@ program
|
|
|
1716
1776
|
console.log('Hooks are active. Verify with: memesh doctor');
|
|
1717
1777
|
console.log('');
|
|
1718
1778
|
console.log('If you really want a second copy in ~/.claude/settings.json on top of the plugin, re-run with --force-over-plugin. (Not recommended — every session-start / Stop / PreToolUse event will fire memesh\'s hooks twice.)');
|
|
1779
|
+
if (result.citationRule.action === 'foreign-file') {
|
|
1780
|
+
console.log('');
|
|
1781
|
+
console.log(`WARNING: the citation contract was NOT installed — a file memesh did not write already exists at ${result.citationRule.path}.`);
|
|
1782
|
+
console.log(' memesh will not overwrite it. Move or rename that file and re-run, or add the contract to it by hand.');
|
|
1783
|
+
console.log(' Until then, memesh cannot tell whether the memories it injects are ever used.');
|
|
1784
|
+
}
|
|
1785
|
+
else if (result.citationRule.action !== 'unchanged') {
|
|
1786
|
+
console.log(`Citation contract ${result.citationRule.action}: ${result.citationRule.path}`);
|
|
1787
|
+
}
|
|
1719
1788
|
return;
|
|
1720
1789
|
}
|
|
1721
1790
|
console.log(`${opts.dryRun ? '[dry-run] ' : ''}Settings: ${result.settingsPath}`);
|
|
@@ -1725,6 +1794,18 @@ program
|
|
|
1725
1794
|
}
|
|
1726
1795
|
if (result.backupPath)
|
|
1727
1796
|
console.log(`Backup: ${result.backupPath}`);
|
|
1797
|
+
if (!opts.dryRun && (result.added > 0 || result.skipped > 0)) {
|
|
1798
|
+
console.log(`Marker: ${result.markerPath}`);
|
|
1799
|
+
}
|
|
1800
|
+
if (result.citationRule.action === 'foreign-file') {
|
|
1801
|
+
console.log('');
|
|
1802
|
+
console.log(`WARNING: the citation contract was NOT installed — a file memesh did not write already exists at ${result.citationRule.path}.`);
|
|
1803
|
+
console.log(' memesh will not overwrite it. Move or rename that file and re-run, or add the contract to it by hand.');
|
|
1804
|
+
console.log(' Until then, memesh cannot tell whether the memories it injects are ever used.');
|
|
1805
|
+
}
|
|
1806
|
+
else if (result.citationRule.action !== 'unchanged') {
|
|
1807
|
+
console.log(`Citation contract ${result.citationRule.action}: ${result.citationRule.path}`);
|
|
1808
|
+
}
|
|
1728
1809
|
if (result.conflicts.length > 0) {
|
|
1729
1810
|
console.log('');
|
|
1730
1811
|
console.log('Note: memesh hooks now coexist with the following pre-existing entries:');
|
|
@@ -1990,10 +2071,11 @@ program
|
|
|
1990
2071
|
.description('Show MeMesh status and capabilities')
|
|
1991
2072
|
.option('--cached', 'Use cached update info only (skip fresh npm lookup)')
|
|
1992
2073
|
.action(async (opts) => {
|
|
2074
|
+
await withDatabase(() => { });
|
|
1993
2075
|
const caps = detectCapabilities();
|
|
1994
2076
|
const { getCurrentInstallChannel, getInstallChannelSupport } = await import('../../core/install-channel.js');
|
|
1995
2077
|
const install = getCurrentInstallChannel({ packageRoot });
|
|
1996
|
-
const installSupport = getInstallChannelSupport(install);
|
|
2078
|
+
const installSupport = getInstallChannelSupport(install, packageRoot);
|
|
1997
2079
|
const { getUpdateCheck, formatUpdateCheckStatus } = await import('../../core/version-check.js');
|
|
1998
2080
|
const update = await getUpdateCheck(pkg.version, { preferFresh: !opts.cached });
|
|
1999
2081
|
console.log(`MeMesh v${pkg.version}`);
|