@pcircle/memesh 4.10.1 → 4.10.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 +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/AGENTS.md +44 -13
- package/README.de.md +3 -3
- package/README.md +3 -3
- package/README.zh-TW.md +3 -3
- package/dashboard/dist/index.html +1 -1
- package/dist/core/agent-message-inbox.d.ts +6 -0
- package/dist/core/agent-message-inbox.d.ts.map +1 -1
- package/dist/core/agent-message-inbox.js +28 -1
- package/dist/core/agent-message-inbox.js.map +1 -1
- package/dist/core/briefing-level.d.ts +22 -0
- package/dist/core/briefing-level.d.ts.map +1 -0
- package/dist/core/briefing-level.js +75 -0
- package/dist/core/briefing-level.js.map +1 -0
- package/dist/core/briefing.d.ts +3 -0
- package/dist/core/briefing.d.ts.map +1 -1
- package/dist/core/briefing.js +33 -11
- package/dist/core/briefing.js.map +1 -1
- package/dist/core/capture-liveness.d.ts +1 -0
- package/dist/core/capture-liveness.d.ts.map +1 -1
- package/dist/core/capture-liveness.js +1 -0
- package/dist/core/capture-liveness.js.map +1 -1
- package/dist/core/config.d.ts +1 -0
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +3 -1
- package/dist/core/config.js.map +1 -1
- package/dist/core/paths.d.ts +1 -0
- package/dist/core/paths.d.ts.map +1 -1
- package/dist/core/paths.js +4 -0
- package/dist/core/paths.js.map +1 -1
- package/dist/core/schema-export.d.ts.map +1 -1
- package/dist/core/schema-export.js +5 -1
- package/dist/core/schema-export.js.map +1 -1
- package/dist/core/serializer.d.ts +2 -0
- package/dist/core/serializer.d.ts.map +1 -1
- package/dist/core/serializer.js +119 -6
- package/dist/core/serializer.js.map +1 -1
- package/dist/core/task-state.d.ts +5 -0
- package/dist/core/task-state.d.ts.map +1 -1
- package/dist/core/task-state.js +70 -0
- package/dist/core/task-state.js.map +1 -1
- package/dist/core/types.d.ts +2 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/work-topology.d.ts +1 -0
- package/dist/core/work-topology.d.ts.map +1 -1
- package/dist/core/work-topology.js +3 -0
- package/dist/core/work-topology.js.map +1 -1
- package/dist/mcp/THIRD_PARTY_NOTICES.txt +2 -2
- package/dist/mcp/server.js +448 -121
- package/dist/mcp/server.js.map +3 -3
- package/dist/skills-manifest.json +29 -24
- package/dist/storage/fts-index.d.ts +1 -0
- package/dist/storage/fts-index.d.ts.map +1 -1
- package/dist/storage/fts-index.js +5 -0
- package/dist/storage/fts-index.js.map +1 -1
- package/dist/transports/cli/cli.d.ts.map +1 -1
- package/dist/transports/cli/cli.js +348 -53
- package/dist/transports/cli/cli.js.map +3 -3
- package/dist/transports/http/server.d.ts.map +1 -1
- package/dist/transports/http/server.js +10 -1
- package/dist/transports/http/server.js.map +1 -1
- package/dist/transports/mcp/handlers.d.ts +7 -3
- package/dist/transports/mcp/handlers.d.ts.map +1 -1
- package/dist/transports/mcp/handlers.js +7 -3
- package/dist/transports/mcp/handlers.js.map +1 -1
- package/dist/transports/schemas.d.ts +1 -0
- package/dist/transports/schemas.d.ts.map +1 -1
- package/dist/transports/schemas.js +1 -0
- package/dist/transports/schemas.js.map +1 -1
- package/docs/platforms/agent-messaging.md +17 -3
- package/package.json +4 -9
- package/scripts/hooks/_generated/agent-message-inbox.js +28 -1
- package/scripts/hooks/_generated/briefing-level.js +82 -0
- package/scripts/hooks/_generated/capture-liveness.js +1 -0
- package/scripts/hooks/_generated/core-paths.js +4 -0
- package/scripts/hooks/_generated/fts-index.js +5 -0
- package/scripts/hooks/_generated/task-state.js +70 -0
- package/scripts/hooks/_generated/work-topology.js +3 -0
- package/scripts/hooks/_shared.js +623 -15
- package/scripts/hooks/pre-edit-recall.js +386 -65
- package/scripts/hooks/session-start.js +261 -77
- package/scripts/hooks/user-prompt-intent.js +38 -6
- package/scripts/upgrade-plugin.sh +3 -4
- package/skills/memesh/SKILL.md +26 -16
|
@@ -5890,13 +5890,66 @@ var init_types = __esm({
|
|
|
5890
5890
|
});
|
|
5891
5891
|
|
|
5892
5892
|
// dist/core/serializer.js
|
|
5893
|
+
function validateFreshForgottenHashes(value) {
|
|
5894
|
+
if (!Array.isArray(value) || value.length === 0)
|
|
5895
|
+
return null;
|
|
5896
|
+
const deduped = [...new Set(value)];
|
|
5897
|
+
if (!deduped.every((h) => typeof h === "string" && FORGOTTEN_HASH_RE.test(h)))
|
|
5898
|
+
return null;
|
|
5899
|
+
return deduped.length <= MAX_IMPORTED_FORGOTTEN_HASHES ? deduped : null;
|
|
5900
|
+
}
|
|
5901
|
+
function validateFreshSignalScore(value) {
|
|
5902
|
+
return typeof value === "number" && value >= 0 && value <= 1 ? value : null;
|
|
5903
|
+
}
|
|
5904
|
+
function isPlainObject(value) {
|
|
5905
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5906
|
+
}
|
|
5907
|
+
function isValidReplacedHistoryEntry(entry) {
|
|
5908
|
+
if (!isPlainObject(entry))
|
|
5909
|
+
return false;
|
|
5910
|
+
for (const key of Object.keys(entry)) {
|
|
5911
|
+
if (!REPLACED_HISTORY_ENTRY_KEYS.has(key))
|
|
5912
|
+
return false;
|
|
5913
|
+
}
|
|
5914
|
+
if (typeof entry.replaced_at !== "string" || entry.replaced_at.length > 64)
|
|
5915
|
+
return false;
|
|
5916
|
+
if (!(entry.title === null || typeof entry.title === "string" && entry.title.length <= 500))
|
|
5917
|
+
return false;
|
|
5918
|
+
if (!Array.isArray(entry.observations) || !entry.observations.every((o) => typeof o === "string"))
|
|
5919
|
+
return false;
|
|
5920
|
+
if (!Array.isArray(entry.tags) || !entry.tags.every((t) => typeof t === "string"))
|
|
5921
|
+
return false;
|
|
5922
|
+
if ("truncated" in entry && typeof entry.truncated !== "boolean")
|
|
5923
|
+
return false;
|
|
5924
|
+
return true;
|
|
5925
|
+
}
|
|
5926
|
+
function validateFreshReplacedHistory(value) {
|
|
5927
|
+
if (!Array.isArray(value) || value.length === 0)
|
|
5928
|
+
return null;
|
|
5929
|
+
if (value.length > MAX_IMPORTED_REPLACED_HISTORY_ENTRIES)
|
|
5930
|
+
return null;
|
|
5931
|
+
if (!value.every(isValidReplacedHistoryEntry))
|
|
5932
|
+
return null;
|
|
5933
|
+
return jsonBytesOf(value) <= MAX_IMPORTED_REPLACED_HISTORY_TOTAL_BYTES ? value : null;
|
|
5934
|
+
}
|
|
5893
5935
|
function buildImportedMetadata(existingMetadata, args) {
|
|
5894
|
-
const
|
|
5895
|
-
|
|
5936
|
+
const bundled = args.bundled ?? {};
|
|
5937
|
+
const bundledSafe = {};
|
|
5938
|
+
for (const [key, value] of Object.entries(bundled)) {
|
|
5939
|
+
if (IMPORTABLE_METADATA_KEYS.has(key))
|
|
5940
|
+
bundledSafe[key] = value;
|
|
5941
|
+
}
|
|
5942
|
+
const freshForgottenHashes = args.isNewEntity ? validateFreshForgottenHashes(bundled.forgotten_observation_hashes) : null;
|
|
5943
|
+
const freshPin = args.isNewEntity && bundled.pin === true;
|
|
5944
|
+
const freshSignalScore = args.isNewEntity ? validateFreshSignalScore(bundled.signal_score) : null;
|
|
5945
|
+
const freshReplacedHistory = args.isNewEntity ? validateFreshReplacedHistory(bundled.replaced_history) : null;
|
|
5896
5946
|
return {
|
|
5897
5947
|
...existingMetadata ?? {},
|
|
5898
5948
|
...bundledSafe,
|
|
5899
|
-
...
|
|
5949
|
+
...freshForgottenHashes ? { forgotten_observation_hashes: freshForgottenHashes } : {},
|
|
5950
|
+
...freshSignalScore !== null ? { signal_score: freshSignalScore } : {},
|
|
5951
|
+
...freshPin ? { pin: true } : {},
|
|
5952
|
+
...freshReplacedHistory ? { replaced_history: freshReplacedHistory } : {},
|
|
5900
5953
|
trust: "untrusted",
|
|
5901
5954
|
provenance: {
|
|
5902
5955
|
...existingMetadata?.provenance ?? {},
|
|
@@ -5965,6 +6018,12 @@ function importMemories(args) {
|
|
|
5965
6018
|
if (!MERGE_STRATEGIES.includes(args.merge_strategy)) {
|
|
5966
6019
|
throw new Error(`Unknown merge strategy "${args.merge_strategy}". Use one of: ${MERGE_STRATEGIES.join(", ")}. Nothing was imported \u2014 refusing rather than guessing, because the wrong guess overwrites existing memories.`);
|
|
5967
6020
|
}
|
|
6021
|
+
if (args.restore_archived !== void 0 && typeof args.restore_archived !== "boolean") {
|
|
6022
|
+
throw new Error('restore_archived must be the boolean true or false. Nothing was imported \u2014 refusing rather than guessing, because "yes" brings back memories the user forgot.');
|
|
6023
|
+
}
|
|
6024
|
+
if (args.restore_archived === true && args.merge_strategy === "skip") {
|
|
6025
|
+
throw new Error('restore_archived (--restore-archived) only applies with merge strategy "append" or "overwrite"; "skip" leaves every existing entity untouched, so there is nothing to restore. Nothing was imported.');
|
|
6026
|
+
}
|
|
5968
6027
|
if (args.namespace !== void 0 && !NAMESPACES.includes(args.namespace)) {
|
|
5969
6028
|
throw new Error(`Unknown namespace "${args.namespace}". Use one of: ${NAMESPACES.join(", ")}. Nothing was imported \u2014 an unrecognised namespace would move existing memories somewhere nothing queries.`);
|
|
5970
6029
|
}
|
|
@@ -5979,6 +6038,7 @@ function importMemories(args) {
|
|
|
5979
6038
|
const pendingRelations = [];
|
|
5980
6039
|
let skipped = 0;
|
|
5981
6040
|
let appended = 0;
|
|
6041
|
+
let keptArchived = 0;
|
|
5982
6042
|
const errors = [];
|
|
5983
6043
|
const skippedRelations = [];
|
|
5984
6044
|
const setCreatedAt = db2.prepare("UPDATE entities SET created_at = ? WHERE name = ?");
|
|
@@ -5999,11 +6059,14 @@ function importMemories(args) {
|
|
|
5999
6059
|
bundled: entity.metadata,
|
|
6000
6060
|
exportedAt: args.data.exported_at,
|
|
6001
6061
|
importVersion: args.data.version,
|
|
6002
|
-
mergeStrategy: args.merge_strategy
|
|
6062
|
+
mergeStrategy: args.merge_strategy,
|
|
6063
|
+
isNewEntity: !existing
|
|
6003
6064
|
});
|
|
6004
6065
|
if (existing) {
|
|
6005
6066
|
if (args.merge_strategy === "skip")
|
|
6006
6067
|
return { kind: "skipped" };
|
|
6068
|
+
if (existing.archived && args.restore_archived !== true)
|
|
6069
|
+
return { kind: "keptArchived" };
|
|
6007
6070
|
if (args.merge_strategy === "append") {
|
|
6008
6071
|
const existingText = new Set(existing.observations);
|
|
6009
6072
|
const newObservations = (entity.observations ?? []).filter((o) => !existingText.has(o));
|
|
@@ -6052,6 +6115,8 @@ function importMemories(args) {
|
|
|
6052
6115
|
}).immediate();
|
|
6053
6116
|
if (outcome.kind === "skipped")
|
|
6054
6117
|
skipped++;
|
|
6118
|
+
else if (outcome.kind === "keptArchived")
|
|
6119
|
+
keptArchived++;
|
|
6055
6120
|
else if (outcome.kind === "appended")
|
|
6056
6121
|
appended++;
|
|
6057
6122
|
else {
|
|
@@ -6075,9 +6140,9 @@ function importMemories(args) {
|
|
|
6075
6140
|
errors.push(`${rel.from} -${rel.type}-> ${rel.to}: relation not restored (${err instanceof Error ? err.message : String(err)})`);
|
|
6076
6141
|
}
|
|
6077
6142
|
}
|
|
6078
|
-
return { imported, overwritten, skipped, appended, errors, skipped_relations: skippedRelations };
|
|
6143
|
+
return { imported, overwritten, skipped, appended, kept_archived: keptArchived, errors, skipped_relations: skippedRelations };
|
|
6079
6144
|
}
|
|
6080
|
-
var MERGE_STRATEGIES;
|
|
6145
|
+
var IMPORTABLE_METADATA_KEYS, FORGOTTEN_HASH_RE, MAX_IMPORTED_FORGOTTEN_HASHES, MAX_IMPORTED_REPLACED_HISTORY_ENTRIES, MAX_IMPORTED_REPLACED_HISTORY_TOTAL_BYTES, REPLACED_HISTORY_ENTRY_KEYS, jsonBytesOf, MERGE_STRATEGIES;
|
|
6081
6146
|
var init_serializer = __esm({
|
|
6082
6147
|
"dist/core/serializer.js"() {
|
|
6083
6148
|
"use strict";
|
|
@@ -6086,6 +6151,38 @@ var init_serializer = __esm({
|
|
|
6086
6151
|
init_title();
|
|
6087
6152
|
init_time_utils();
|
|
6088
6153
|
init_types();
|
|
6154
|
+
IMPORTABLE_METADATA_KEYS = /* @__PURE__ */ new Set([
|
|
6155
|
+
"title_source",
|
|
6156
|
+
"source_kind",
|
|
6157
|
+
"source",
|
|
6158
|
+
"cluster_key",
|
|
6159
|
+
"dreamed_at",
|
|
6160
|
+
"kind",
|
|
6161
|
+
"project",
|
|
6162
|
+
"previous_namespace",
|
|
6163
|
+
"namespace_moved_at",
|
|
6164
|
+
"split_from",
|
|
6165
|
+
"retired_recall",
|
|
6166
|
+
"priority",
|
|
6167
|
+
"success_criteria",
|
|
6168
|
+
"verification_scenario",
|
|
6169
|
+
"implementation_state",
|
|
6170
|
+
"outcome_state",
|
|
6171
|
+
"accepted_at",
|
|
6172
|
+
"source_ids"
|
|
6173
|
+
]);
|
|
6174
|
+
FORGOTTEN_HASH_RE = /^[a-f0-9]{64}$/;
|
|
6175
|
+
MAX_IMPORTED_FORGOTTEN_HASHES = 1e3;
|
|
6176
|
+
MAX_IMPORTED_REPLACED_HISTORY_ENTRIES = 50;
|
|
6177
|
+
MAX_IMPORTED_REPLACED_HISTORY_TOTAL_BYTES = 4 * 64 * 1024;
|
|
6178
|
+
REPLACED_HISTORY_ENTRY_KEYS = /* @__PURE__ */ new Set([
|
|
6179
|
+
"replaced_at",
|
|
6180
|
+
"title",
|
|
6181
|
+
"observations",
|
|
6182
|
+
"tags",
|
|
6183
|
+
"truncated"
|
|
6184
|
+
]);
|
|
6185
|
+
jsonBytesOf = (v) => Buffer.byteLength(JSON.stringify(v), "utf8");
|
|
6089
6186
|
MERGE_STRATEGIES = ["skip", "overwrite", "append"];
|
|
6090
6187
|
}
|
|
6091
6188
|
});
|
|
@@ -6417,6 +6514,8 @@ function selectConfig(raw) {
|
|
|
6417
6514
|
config2.updateCheck = raw.updateCheck;
|
|
6418
6515
|
if (typeof raw.setupCompleted === "boolean")
|
|
6419
6516
|
config2.setupCompleted = raw.setupCompleted;
|
|
6517
|
+
if (raw.briefing !== void 0)
|
|
6518
|
+
config2.briefing = raw.briefing;
|
|
6420
6519
|
return config2;
|
|
6421
6520
|
}
|
|
6422
6521
|
function findRetiredConfigKeys(raw) {
|
|
@@ -6469,7 +6568,7 @@ var init_config = __esm({
|
|
|
6469
6568
|
"dist/core/config.js"() {
|
|
6470
6569
|
"use strict";
|
|
6471
6570
|
init_paths();
|
|
6472
|
-
CONFIG_KEYS = ["autoCapture", "sessionLimit", "autoUpdate", "updateCheck", "setupCompleted"];
|
|
6571
|
+
CONFIG_KEYS = ["autoCapture", "sessionLimit", "autoUpdate", "updateCheck", "setupCompleted", "briefing"];
|
|
6473
6572
|
RETIRED_CONFIG_KEYS = [
|
|
6474
6573
|
"llm",
|
|
6475
6574
|
"llmFallbacks",
|
|
@@ -7365,7 +7464,7 @@ __export(util_exports, {
|
|
|
7365
7464
|
getSizableOrigin: () => getSizableOrigin,
|
|
7366
7465
|
hexToUint8Array: () => hexToUint8Array,
|
|
7367
7466
|
isObject: () => isObject,
|
|
7368
|
-
isPlainObject: () =>
|
|
7467
|
+
isPlainObject: () => isPlainObject2,
|
|
7369
7468
|
issue: () => issue,
|
|
7370
7469
|
joinValues: () => joinValues,
|
|
7371
7470
|
jsonStringifyReplacer: () => jsonStringifyReplacer,
|
|
@@ -7527,7 +7626,7 @@ function slugify2(input) {
|
|
|
7527
7626
|
function isObject(data) {
|
|
7528
7627
|
return typeof data === "object" && data !== null && !Array.isArray(data);
|
|
7529
7628
|
}
|
|
7530
|
-
function
|
|
7629
|
+
function isPlainObject2(o) {
|
|
7531
7630
|
if (isObject(o) === false)
|
|
7532
7631
|
return false;
|
|
7533
7632
|
const ctor = o.constructor;
|
|
@@ -7544,7 +7643,7 @@ function isPlainObject(o) {
|
|
|
7544
7643
|
return true;
|
|
7545
7644
|
}
|
|
7546
7645
|
function shallowClone(o) {
|
|
7547
|
-
if (
|
|
7646
|
+
if (isPlainObject2(o))
|
|
7548
7647
|
return { ...o };
|
|
7549
7648
|
if (Array.isArray(o))
|
|
7550
7649
|
return [...o];
|
|
@@ -7684,7 +7783,7 @@ function omit(schema, mask) {
|
|
|
7684
7783
|
return clone(schema, def);
|
|
7685
7784
|
}
|
|
7686
7785
|
function extend(schema, shape) {
|
|
7687
|
-
if (!
|
|
7786
|
+
if (!isPlainObject2(shape)) {
|
|
7688
7787
|
throw new Error("Invalid input to extend: expected a plain object");
|
|
7689
7788
|
}
|
|
7690
7789
|
const checks = schema._zod.def.checks;
|
|
@@ -7707,7 +7806,7 @@ function extend(schema, shape) {
|
|
|
7707
7806
|
return clone(schema, def);
|
|
7708
7807
|
}
|
|
7709
7808
|
function safeExtend(schema, shape) {
|
|
7710
|
-
if (!
|
|
7809
|
+
if (!isPlainObject2(shape)) {
|
|
7711
7810
|
throw new Error("Invalid input to safeExtend: expected a plain object");
|
|
7712
7811
|
}
|
|
7713
7812
|
const def = mergeDefs(schema._zod.def, {
|
|
@@ -9225,7 +9324,7 @@ function mergeValues(a, b) {
|
|
|
9225
9324
|
if (a instanceof Date && b instanceof Date && +a === +b) {
|
|
9226
9325
|
return { valid: true, data: a };
|
|
9227
9326
|
}
|
|
9228
|
-
if (
|
|
9327
|
+
if (isPlainObject2(a) && isPlainObject2(b)) {
|
|
9229
9328
|
const bKeys = Object.keys(b);
|
|
9230
9329
|
const sharedKeys = Object.keys(a).filter((key) => bKeys.indexOf(key) !== -1);
|
|
9231
9330
|
const newObj = { ...a, ...b };
|
|
@@ -10492,7 +10591,7 @@ var init_schemas = __esm({
|
|
|
10492
10591
|
$ZodType.init(inst, def);
|
|
10493
10592
|
inst._zod.parse = (payload, ctx) => {
|
|
10494
10593
|
const input = payload.value;
|
|
10495
|
-
if (!
|
|
10594
|
+
if (!isPlainObject2(input)) {
|
|
10496
10595
|
payload.issues.push({
|
|
10497
10596
|
expected: "record",
|
|
10498
10597
|
code: "invalid_type",
|
|
@@ -23254,7 +23353,7 @@ function parseTargetKind(value) {
|
|
|
23254
23353
|
}
|
|
23255
23354
|
function parseJsonObject(json2, label) {
|
|
23256
23355
|
const parsed = parseJsonObjectOrValue(json2);
|
|
23257
|
-
if (!
|
|
23356
|
+
if (!isPlainObject3(parsed))
|
|
23258
23357
|
throw new AgentMessagingError(`${label} must contain a JSON object.`);
|
|
23259
23358
|
return parsed;
|
|
23260
23359
|
}
|
|
@@ -23304,7 +23403,7 @@ function assertJsonValue(value, label) {
|
|
|
23304
23403
|
value.forEach((entry, index) => assertJsonValue(entry, `${label}[${index}]`));
|
|
23305
23404
|
return;
|
|
23306
23405
|
}
|
|
23307
|
-
if (
|
|
23406
|
+
if (isPlainObject3(value)) {
|
|
23308
23407
|
for (const [key, entry] of Object.entries(value)) {
|
|
23309
23408
|
assertJsonValue(entry, `${label}.${key}`);
|
|
23310
23409
|
}
|
|
@@ -23316,7 +23415,7 @@ function normalizeObject(value) {
|
|
|
23316
23415
|
assertJsonValue(value, "object");
|
|
23317
23416
|
return value;
|
|
23318
23417
|
}
|
|
23319
|
-
function
|
|
23418
|
+
function isPlainObject3(value) {
|
|
23320
23419
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23321
23420
|
}
|
|
23322
23421
|
function requireText(label, value, maxLength) {
|
|
@@ -23527,7 +23626,8 @@ var init_schemas3 = __esm({
|
|
|
23527
23626
|
ImportSchema = external_exports.object({
|
|
23528
23627
|
data: ExportResultSchema,
|
|
23529
23628
|
namespace: external_exports.enum(NAMESPACES).optional(),
|
|
23530
|
-
merge_strategy: external_exports.enum(["skip", "overwrite", "append"])
|
|
23629
|
+
merge_strategy: external_exports.enum(["skip", "overwrite", "append"]),
|
|
23630
|
+
restore_archived: external_exports.boolean().optional()
|
|
23531
23631
|
}).strict();
|
|
23532
23632
|
LearnSchema = external_exports.object({
|
|
23533
23633
|
error: external_exports.string().min(1).max(5e3),
|
|
@@ -23808,7 +23908,73 @@ function taskStateLines(state, project, now = /* @__PURE__ */ new Date()) {
|
|
|
23808
23908
|
}
|
|
23809
23909
|
return lines;
|
|
23810
23910
|
}
|
|
23811
|
-
|
|
23911
|
+
function isLeapYear(year) {
|
|
23912
|
+
return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
|
|
23913
|
+
}
|
|
23914
|
+
function daysInMonth(year, month) {
|
|
23915
|
+
return month === 2 && isLeapYear(year) ? 29 : DAYS_IN_MONTH[month - 1];
|
|
23916
|
+
}
|
|
23917
|
+
function isRealInstant(groups) {
|
|
23918
|
+
const year = Number(groups.year);
|
|
23919
|
+
const month = Number(groups.month);
|
|
23920
|
+
const day = Number(groups.day);
|
|
23921
|
+
const hour = Number(groups.hour);
|
|
23922
|
+
const minute = Number(groups.minute);
|
|
23923
|
+
const second = groups.second === void 0 ? 0 : Number(groups.second);
|
|
23924
|
+
if (month < 1 || month > 12)
|
|
23925
|
+
return false;
|
|
23926
|
+
if (day < 1 || day > daysInMonth(year, month))
|
|
23927
|
+
return false;
|
|
23928
|
+
if (hour > 23)
|
|
23929
|
+
return false;
|
|
23930
|
+
if (minute > 59)
|
|
23931
|
+
return false;
|
|
23932
|
+
if (second > 59)
|
|
23933
|
+
return false;
|
|
23934
|
+
if (groups.zulu === void 0) {
|
|
23935
|
+
const offHour = Number(groups.offHour);
|
|
23936
|
+
const offMinute = Number(groups.offMinute);
|
|
23937
|
+
if (offHour > 23 || offMinute > 59)
|
|
23938
|
+
return false;
|
|
23939
|
+
if (groups.offSign === "-" && offHour === 0 && offMinute === 0)
|
|
23940
|
+
return false;
|
|
23941
|
+
}
|
|
23942
|
+
return true;
|
|
23943
|
+
}
|
|
23944
|
+
function resolveTaskStateAge(updatedAt, now) {
|
|
23945
|
+
if (!updatedAt)
|
|
23946
|
+
return { known: false };
|
|
23947
|
+
const match = ZONED_INSTANT.exec(updatedAt);
|
|
23948
|
+
if (!match?.groups || !isRealInstant(match.groups))
|
|
23949
|
+
return { known: false };
|
|
23950
|
+
const then = Date.parse(updatedAt);
|
|
23951
|
+
if (Number.isNaN(then))
|
|
23952
|
+
return { known: false };
|
|
23953
|
+
const hours = (now.getTime() - then) / 36e5;
|
|
23954
|
+
if (hours < -(CLOCK_SKEW_ALLOWANCE_MINUTES / 60))
|
|
23955
|
+
return { known: false };
|
|
23956
|
+
return { known: true, hours: Math.max(0, hours) };
|
|
23957
|
+
}
|
|
23958
|
+
function staleTaskStateLine(project, hours) {
|
|
23959
|
+
const days = Math.floor(hours / 24);
|
|
23960
|
+
const age = days >= 1 ? `${days} day${days === 1 ? "" : "s"} ago` : `${Math.floor(hours)} hour${Math.floor(hours) === 1 ? "" : "s"} ago`;
|
|
23961
|
+
return `Task state for "${project}" was last stated ${age} \u2014 older than ${STALE_TASK_STATE_HOURS}h, so it is not shown as current. Run \`memesh task\` to see or update it.`;
|
|
23962
|
+
}
|
|
23963
|
+
function taskStateAgeUnknownLine(project) {
|
|
23964
|
+
return `Task state for "${project}" has a missing, unreadable, or future-dated timestamp, so its age could not be established \u2014 not shown as current. Run \`memesh task\` to see or update it.`;
|
|
23965
|
+
}
|
|
23966
|
+
function briefingTaskStateLines(state, project, now = /* @__PURE__ */ new Date(), { includeFresh = true } = {}) {
|
|
23967
|
+
if (isEmptyTaskState(state))
|
|
23968
|
+
return [];
|
|
23969
|
+
const age = resolveTaskStateAge(state.updated_at, now);
|
|
23970
|
+
if (!age.known)
|
|
23971
|
+
return [taskStateAgeUnknownLine(project)];
|
|
23972
|
+
if (age.hours > STALE_TASK_STATE_HOURS) {
|
|
23973
|
+
return [staleTaskStateLine(project, age.hours)];
|
|
23974
|
+
}
|
|
23975
|
+
return includeFresh ? taskStateLines(state, project, now) : [];
|
|
23976
|
+
}
|
|
23977
|
+
var TASK_STATE_TYPE, TASK_STATE_FIELDS, MAX_FIELD_CHARS, FIELD_LABELS, STALE_TASK_STATE_HOURS, CLOCK_SKEW_ALLOWANCE_MINUTES, ZONED_INSTANT, DAYS_IN_MONTH;
|
|
23812
23978
|
var init_task_state = __esm({
|
|
23813
23979
|
"dist/core/task-state.js"() {
|
|
23814
23980
|
"use strict";
|
|
@@ -23821,6 +23987,10 @@ var init_task_state = __esm({
|
|
|
23821
23987
|
blocked: "Blocked",
|
|
23822
23988
|
done: "Had just finished"
|
|
23823
23989
|
};
|
|
23990
|
+
STALE_TASK_STATE_HOURS = 72;
|
|
23991
|
+
CLOCK_SKEW_ALLOWANCE_MINUTES = 5;
|
|
23992
|
+
ZONED_INSTANT = /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})[Tt](?<hour>\d{2}):(?<minute>\d{2})(?::(?<second>\d{2})(?:\.\d+)?)?(?:(?<zulu>[Zz])|(?<offSign>[+-])(?<offHour>\d{2}):?(?<offMinute>\d{2}))$/;
|
|
23993
|
+
DAYS_IN_MONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
23824
23994
|
}
|
|
23825
23995
|
});
|
|
23826
23996
|
|
|
@@ -23927,7 +24097,7 @@ function unreadInboxLines(count, project, recipient, everSeen) {
|
|
|
23927
24097
|
const displayRecipient = JSON.stringify(recipient);
|
|
23928
24098
|
if (count > 0) {
|
|
23929
24099
|
const noun = count === 1 ? "message" : "messages";
|
|
23930
|
-
return [`${count} ${noun} waiting for ${displayRecipient} in project ${displayProject} \u2014 poll the message tool with project ${displayProject} and recipient ${displayRecipient}, then fetch each message_id
|
|
24100
|
+
return [`${count} ${noun} waiting for ${displayRecipient} in project ${displayProject} \u2014 poll the message tool with project ${displayProject} and recipient ${displayRecipient}, then fetch each message_id and record the intake action for it: fetching alone does not acknowledge, and only intake ends this line.`];
|
|
23931
24101
|
}
|
|
23932
24102
|
if (everSeen === false) {
|
|
23933
24103
|
return [`No messages waiting for ${displayRecipient} in project ${displayProject} \u2014 and this recipient id has never been seen in this project (check for a typo).`];
|
|
@@ -24090,6 +24260,9 @@ function assembleTopologyBlock(stateLines, pools, projectName, budget = DEFAULT_
|
|
|
24090
24260
|
lines.push(...globalLines);
|
|
24091
24261
|
return lines;
|
|
24092
24262
|
}
|
|
24263
|
+
function hasBriefingContent(lines) {
|
|
24264
|
+
return lines.length > 0;
|
|
24265
|
+
}
|
|
24093
24266
|
function buildReferenceContext(memoryLines) {
|
|
24094
24267
|
const safeLines = memoryLines.map((line) => String(line ?? "").replace(/[\s\u0085\u001c-\u001e]+/g, " ").trim());
|
|
24095
24268
|
let longestRun = 0;
|
|
@@ -24293,6 +24466,85 @@ var init_briefing_index = __esm({
|
|
|
24293
24466
|
}
|
|
24294
24467
|
});
|
|
24295
24468
|
|
|
24469
|
+
// dist/core/briefing-level.js
|
|
24470
|
+
function isBriefingLevel(value) {
|
|
24471
|
+
return typeof value === "string" && BRIEFING_LEVELS.includes(value);
|
|
24472
|
+
}
|
|
24473
|
+
function safeRawPreSlice(value, maxUnits) {
|
|
24474
|
+
if (value.length <= maxUnits)
|
|
24475
|
+
return value;
|
|
24476
|
+
let end = maxUnits;
|
|
24477
|
+
const lastKept = value.charCodeAt(end - 1);
|
|
24478
|
+
const nextUnit = value.charCodeAt(end);
|
|
24479
|
+
const lastKeptIsHighSurrogate = lastKept >= 55296 && lastKept <= 56319;
|
|
24480
|
+
const nextUnitIsLowSurrogate = nextUnit >= 56320 && nextUnit <= 57343;
|
|
24481
|
+
if (lastKeptIsHighSurrogate && nextUnitIsLowSurrogate)
|
|
24482
|
+
end -= 1;
|
|
24483
|
+
return value.slice(0, end);
|
|
24484
|
+
}
|
|
24485
|
+
function truncateToSerializedBound(codePoints) {
|
|
24486
|
+
let kept = 0;
|
|
24487
|
+
for (; kept < codePoints.length; kept++) {
|
|
24488
|
+
const candidate = JSON.stringify(`${codePoints.slice(0, kept + 1).join("")}\u2026`);
|
|
24489
|
+
if (candidate.length > INVALID_VALUE_SERIALIZED_MAX)
|
|
24490
|
+
break;
|
|
24491
|
+
}
|
|
24492
|
+
return JSON.stringify(`${codePoints.slice(0, kept).join("")}\u2026`);
|
|
24493
|
+
}
|
|
24494
|
+
function describeInvalidValue(value) {
|
|
24495
|
+
if (typeof value === "string") {
|
|
24496
|
+
if (value.length <= INVALID_VALUE_SERIALIZED_MAX) {
|
|
24497
|
+
const whole = JSON.stringify(value);
|
|
24498
|
+
if (whole.length <= INVALID_VALUE_SERIALIZED_MAX)
|
|
24499
|
+
return whole;
|
|
24500
|
+
return truncateToSerializedBound(Array.from(value));
|
|
24501
|
+
}
|
|
24502
|
+
return truncateToSerializedBound(Array.from(safeRawPreSlice(value, PRE_SLICE_RAW_MAX)));
|
|
24503
|
+
}
|
|
24504
|
+
if (Array.isArray(value))
|
|
24505
|
+
return "[array]";
|
|
24506
|
+
if (value !== null && typeof value === "object")
|
|
24507
|
+
return "[object]";
|
|
24508
|
+
if (typeof value === "bigint")
|
|
24509
|
+
return "[bigint]";
|
|
24510
|
+
if (typeof value === "symbol")
|
|
24511
|
+
return "[symbol]";
|
|
24512
|
+
if (typeof value === "function")
|
|
24513
|
+
return "[function]";
|
|
24514
|
+
return JSON.stringify(value) ?? String(value);
|
|
24515
|
+
}
|
|
24516
|
+
function resolveBriefingLevel(envValue, configValue) {
|
|
24517
|
+
if (envValue !== void 0) {
|
|
24518
|
+
if (isBriefingLevel(envValue))
|
|
24519
|
+
return { level: envValue, invalid: null };
|
|
24520
|
+
return { level: DEFAULT_BRIEFING_LEVEL, invalid: { source: "env", value: describeInvalidValue(envValue) } };
|
|
24521
|
+
}
|
|
24522
|
+
if (configValue !== void 0) {
|
|
24523
|
+
if (isBriefingLevel(configValue))
|
|
24524
|
+
return { level: configValue, invalid: null };
|
|
24525
|
+
return { level: DEFAULT_BRIEFING_LEVEL, invalid: { source: "config", value: describeInvalidValue(configValue) } };
|
|
24526
|
+
}
|
|
24527
|
+
return { level: DEFAULT_BRIEFING_LEVEL, invalid: null };
|
|
24528
|
+
}
|
|
24529
|
+
function briefingLevelPolicy(level) {
|
|
24530
|
+
return POLICIES[level];
|
|
24531
|
+
}
|
|
24532
|
+
var BRIEFING_LEVELS, DEFAULT_BRIEFING_LEVEL, INVALID_VALUE_SERIALIZED_MAX, PRE_SLICE_RAW_MAX, POLICIES;
|
|
24533
|
+
var init_briefing_level = __esm({
|
|
24534
|
+
"dist/core/briefing-level.js"() {
|
|
24535
|
+
"use strict";
|
|
24536
|
+
BRIEFING_LEVELS = ["minimal", "standard", "full"];
|
|
24537
|
+
DEFAULT_BRIEFING_LEVEL = "standard";
|
|
24538
|
+
INVALID_VALUE_SERIALIZED_MAX = 100;
|
|
24539
|
+
PRE_SLICE_RAW_MAX = 256;
|
|
24540
|
+
POLICIES = {
|
|
24541
|
+
minimal: { global: false, foreign: false, taskState: false, index: false, workPackageNotice: false },
|
|
24542
|
+
standard: { global: false, foreign: false, taskState: true, index: true, workPackageNotice: false },
|
|
24543
|
+
full: { global: true, foreign: true, taskState: true, index: true, workPackageNotice: true }
|
|
24544
|
+
};
|
|
24545
|
+
}
|
|
24546
|
+
});
|
|
24547
|
+
|
|
24296
24548
|
// dist/core/briefing.js
|
|
24297
24549
|
function parseMetadata(raw) {
|
|
24298
24550
|
if (!raw)
|
|
@@ -24358,10 +24610,23 @@ function readBriefingIndex(db2, projectName, now = Date.now()) {
|
|
|
24358
24610
|
function assembleBriefing(project, recipient) {
|
|
24359
24611
|
const projectName = project ?? getProjectName();
|
|
24360
24612
|
const db2 = getDatabase();
|
|
24613
|
+
const resolvedLevel = resolveBriefingLevel(process.env.MEMESH_BRIEFING, readConfig().briefing);
|
|
24614
|
+
if (resolvedLevel.invalid) {
|
|
24615
|
+
const { source, value } = resolvedLevel.invalid;
|
|
24616
|
+
try {
|
|
24617
|
+
process.stderr.write(`[memesh briefing] invalid ${source} briefing level ${value} \u2014 using "${resolvedLevel.level}"
|
|
24618
|
+
`);
|
|
24619
|
+
} catch {
|
|
24620
|
+
}
|
|
24621
|
+
}
|
|
24622
|
+
const level = resolvedLevel.level;
|
|
24623
|
+
const policy = briefingLevelPolicy(level);
|
|
24361
24624
|
const repoLines = project === void 0 || project === getProjectName() ? repoStateLines(readRepoState()) : [];
|
|
24362
24625
|
let taskLines;
|
|
24363
24626
|
try {
|
|
24364
|
-
taskLines =
|
|
24627
|
+
taskLines = briefingTaskStateLines(getTaskState(projectName).state, projectName, /* @__PURE__ */ new Date(), {
|
|
24628
|
+
includeFresh: policy.taskState
|
|
24629
|
+
});
|
|
24365
24630
|
} catch (err) {
|
|
24366
24631
|
if (!(err instanceof TaskStateUnreadableError))
|
|
24367
24632
|
throw err;
|
|
@@ -24382,17 +24647,17 @@ function assembleBriefing(project, recipient) {
|
|
|
24382
24647
|
ORDER BY e.id DESC
|
|
24383
24648
|
LIMIT ?`).all(`project:${projectName}`, TOPOLOGY_CANDIDATE_CAP);
|
|
24384
24649
|
const projectPool = selectPool(projectRows, PROJECT_LIMIT);
|
|
24385
|
-
const globalRows = hasNamespace ? db2.prepare(`SELECT ${CANDIDATE_COLUMNS}
|
|
24650
|
+
const globalRows = policy.global && hasNamespace ? db2.prepare(`SELECT ${CANDIDATE_COLUMNS}
|
|
24386
24651
|
FROM entities e
|
|
24387
24652
|
WHERE e.namespace = 'global' AND e.status = 'active'
|
|
24388
24653
|
ORDER BY e.id DESC
|
|
24389
24654
|
LIMIT ?`).all(TOPOLOGY_CANDIDATE_CAP) : [];
|
|
24390
24655
|
const globalPool = selectPool(globalRows, GLOBAL_TOPOLOGY_LIMIT);
|
|
24391
|
-
const recentRows = db2.prepare(`SELECT ${CANDIDATE_COLUMNS}
|
|
24392
|
-
|
|
24393
|
-
|
|
24394
|
-
|
|
24395
|
-
|
|
24656
|
+
const recentRows = policy.foreign ? db2.prepare(`SELECT ${CANDIDATE_COLUMNS}
|
|
24657
|
+
FROM entities e
|
|
24658
|
+
WHERE e.status = 'active'${nonGlobal}
|
|
24659
|
+
ORDER BY e.id DESC
|
|
24660
|
+
LIMIT ?`).all(TOPOLOGY_CANDIDATE_CAP) : [];
|
|
24396
24661
|
const recentPool = selectPool(recentRows, RECENT_LIMIT);
|
|
24397
24662
|
const survivorIds = [...new Set([...projectPool, ...globalPool, ...recentPool].map((row) => row.id))];
|
|
24398
24663
|
const snippets = /* @__PURE__ */ new Map();
|
|
@@ -24417,13 +24682,17 @@ function assembleBriefing(project, recipient) {
|
|
|
24417
24682
|
], projectName);
|
|
24418
24683
|
const withRepo = lines.length > 0 && repoLines.length > 0 ? [...repoLines, "", ...lines] : lines;
|
|
24419
24684
|
const index = readBriefingIndex(db2, projectName);
|
|
24420
|
-
const
|
|
24685
|
+
const indexLines = policy.index ? index.lines : [];
|
|
24686
|
+
const block = withRepo.length > 0 && indexLines.length > 0 ? [...withRepo, "", ...indexLines] : [...withRepo, ...indexLines];
|
|
24687
|
+
const empty = !hasBriefingContent(block);
|
|
24421
24688
|
return {
|
|
24422
24689
|
project: projectName,
|
|
24423
|
-
text: buildReferenceContext(block),
|
|
24690
|
+
text: empty ? "" : buildReferenceContext(block),
|
|
24424
24691
|
entityCount: lines.filter((l) => l.startsWith("- [")).length,
|
|
24425
24692
|
hasTaskState: stateLines.length > 0,
|
|
24426
|
-
index
|
|
24693
|
+
index,
|
|
24694
|
+
level,
|
|
24695
|
+
empty
|
|
24427
24696
|
};
|
|
24428
24697
|
}
|
|
24429
24698
|
var PROJECT_LIMIT, RECENT_LIMIT, CANDIDATE_COLUMNS;
|
|
@@ -24432,6 +24701,7 @@ var init_briefing = __esm({
|
|
|
24432
24701
|
"use strict";
|
|
24433
24702
|
init_db();
|
|
24434
24703
|
init_paths();
|
|
24704
|
+
init_config();
|
|
24435
24705
|
init_repo_state();
|
|
24436
24706
|
init_scoring();
|
|
24437
24707
|
init_task_state_store();
|
|
@@ -24440,6 +24710,7 @@ var init_briefing = __esm({
|
|
|
24440
24710
|
init_task_state();
|
|
24441
24711
|
init_briefing_index();
|
|
24442
24712
|
init_work_topology();
|
|
24713
|
+
init_briefing_level();
|
|
24443
24714
|
PROJECT_LIMIT = 30;
|
|
24444
24715
|
RECENT_LIMIT = 5;
|
|
24445
24716
|
CANDIDATE_COLUMNS = "e.id, e.name, e.type, e.title, e.metadata, e.access_count, e.last_accessed_at, e.confidence, e.recall_hits, e.recall_misses";
|
|
@@ -24791,9 +25062,9 @@ import fs15 from "node:fs";
|
|
|
24791
25062
|
import net from "node:net";
|
|
24792
25063
|
import path14 from "node:path";
|
|
24793
25064
|
function isLegacyAgentRouterVersionMismatchResponse(value) {
|
|
24794
|
-
if (!
|
|
25065
|
+
if (!isPlainObject4(value) || value.version !== 1 || value.request_id !== "" || value.ok !== false)
|
|
24795
25066
|
return false;
|
|
24796
|
-
if (!
|
|
25067
|
+
if (!isPlainObject4(value.error))
|
|
24797
25068
|
return false;
|
|
24798
25069
|
return value.error.code === "unsupported_type" || value.error.code === "unsupported_version";
|
|
24799
25070
|
}
|
|
@@ -24852,7 +25123,7 @@ async function sendAgentRouterRequest(socketPath, request, timeoutMs = DEFAULT_C
|
|
|
24852
25123
|
if (isLegacyAgentRouterVersionMismatchResponse(response)) {
|
|
24853
25124
|
throw new AgentRouterProtocolError("router_version_mismatch", "router_version_mismatch: the configured router endpoint uses a stale protocol; restart that router with the current MeMesh version.");
|
|
24854
25125
|
}
|
|
24855
|
-
const uncorrelatedError = response.request_id === "" && response.ok === false &&
|
|
25126
|
+
const uncorrelatedError = response.request_id === "" && response.ok === false && isPlainObject4(response.error) && typeof response.error.code === "string" && typeof response.error.message === "string";
|
|
24856
25127
|
if (response.version !== AGENT_ROUTER_PROTOCOL_VERSION || response.request_id !== request.request_id && !uncorrelatedError) {
|
|
24857
25128
|
throw new AgentRouterProtocolError("invalid_response", "Router response identity does not match.");
|
|
24858
25129
|
}
|
|
@@ -24871,7 +25142,7 @@ async function sendAgentRouterRequest(socketPath, request, timeoutMs = DEFAULT_C
|
|
|
24871
25142
|
});
|
|
24872
25143
|
}
|
|
24873
25144
|
function validateRouterSuccessResult(request, value) {
|
|
24874
|
-
if (!
|
|
25145
|
+
if (!isPlainObject4(value)) {
|
|
24875
25146
|
throw new AgentRouterProtocolError("invalid_response", "Router response result must be an object.");
|
|
24876
25147
|
}
|
|
24877
25148
|
const requireResultString = (field) => {
|
|
@@ -24929,7 +25200,7 @@ function validateRouterSuccessResult(request, value) {
|
|
|
24929
25200
|
return value;
|
|
24930
25201
|
}
|
|
24931
25202
|
function isSelectionCard(value, project) {
|
|
24932
|
-
if (!
|
|
25203
|
+
if (!isPlainObject4(value))
|
|
24933
25204
|
return false;
|
|
24934
25205
|
return typeof value.session_id === "string" && typeof value.principal_id === "string" && ["codex", "claude", "gemini", "other"].includes(String(value.host_kind)) && value.project === project && (value.model === null || typeof value.model === "string") && (value.work_summary === null || typeof value.work_summary === "string") && value.active === true && Number.isSafeInteger(value.generation) && value.generation >= 1 && Number.isSafeInteger(value.lease_expires_at_ms) && value.lease_expires_at_ms >= 0;
|
|
24935
25206
|
}
|
|
@@ -24939,7 +25210,7 @@ function validateSocketPath(socketPath) {
|
|
|
24939
25210
|
}
|
|
24940
25211
|
return socketPath;
|
|
24941
25212
|
}
|
|
24942
|
-
function
|
|
25213
|
+
function isPlainObject4(value) {
|
|
24943
25214
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
24944
25215
|
}
|
|
24945
25216
|
var AGENT_ROUTER_PROTOCOL_VERSION, AGENT_ROUTER_MAX_FRAME_BYTES, MAX_LEASE_MS, DEFAULT_CLIENT_TIMEOUT_MS, MAX_FIELD_LENGTH, MAX_ADAPTER_RECEIPT_BYTES, AgentRouterError, AgentRouterProtocolError;
|
|
@@ -25710,6 +25981,10 @@ function exportOpenAITools() {
|
|
|
25710
25981
|
type: "string",
|
|
25711
25982
|
enum: ["skip", "overwrite", "append"],
|
|
25712
25983
|
description: "Required. How to handle existing entities: skip, overwrite (replace), or append (merge observations)."
|
|
25984
|
+
},
|
|
25985
|
+
restore_archived: {
|
|
25986
|
+
type: "boolean",
|
|
25987
|
+
description: "Optional, default false. With append or overwrite, an archived (forgotten) local entity is left untouched and counted in kept_archived; true brings it back to active and merges or overwrites it, and requires append or overwrite (an error with skip)."
|
|
25713
25988
|
}
|
|
25714
25989
|
},
|
|
25715
25990
|
required: ["data", "merge_strategy"]
|
|
@@ -25755,7 +26030,7 @@ function exportOpenAITools() {
|
|
|
25755
26030
|
type: "function",
|
|
25756
26031
|
function: {
|
|
25757
26032
|
name: "memesh_briefing",
|
|
25758
|
-
description: "The assembled work topology for a project: where the work was left off, decisions, lessons, knowledge, recent activity. Call once at the start of a session to load project context.",
|
|
26033
|
+
description: "The assembled work topology for a project: where the work was left off (by default), decisions, lessons, knowledge, recent activity. Call once at the start of a session to load project context.",
|
|
25759
26034
|
parameters: {
|
|
25760
26035
|
type: "object",
|
|
25761
26036
|
properties: {
|
|
@@ -42232,10 +42507,10 @@ var require_object_inspect = __commonJS({
|
|
|
42232
42507
|
}
|
|
42233
42508
|
if (!isDate(obj) && !isRegExp(obj)) {
|
|
42234
42509
|
var ys = arrObjKeys(obj, inspect);
|
|
42235
|
-
var
|
|
42510
|
+
var isPlainObject5 = gPO ? gPO(obj) === Object.prototype : obj instanceof Object || obj.constructor === Object;
|
|
42236
42511
|
var protoTag = obj instanceof Object ? "" : "null prototype";
|
|
42237
|
-
var stringTag = !
|
|
42238
|
-
var constructorTag =
|
|
42512
|
+
var stringTag = !isPlainObject5 && toStringTag && Object(obj) === obj && toStringTag in obj ? $slice.call(toStr(obj), 8, -1) : protoTag ? "Object" : "";
|
|
42513
|
+
var constructorTag = isPlainObject5 || typeof obj.constructor !== "function" ? "" : obj.constructor.name ? obj.constructor.name + " " : "";
|
|
42239
42514
|
var tag = constructorTag + (stringTag || protoTag ? "[" + $join.call($concat.call([], stringTag || [], protoTag || []), ": ") + "] " : "");
|
|
42240
42515
|
if (ys.length === 0) {
|
|
42241
42516
|
return tag + "{}";
|
|
@@ -55352,6 +55627,7 @@ var init_capture_liveness = __esm({
|
|
|
55352
55627
|
noFilePath: "no file_path in the tool input",
|
|
55353
55628
|
noDatabaseForRecall: "no database yet \u2014 nothing to recall",
|
|
55354
55629
|
nothingToRecall: "no guard matched and nothing to recall for this file",
|
|
55630
|
+
candidateWindowTruncated: "more candidates may exist than the search window examined",
|
|
55355
55631
|
noPromptIntent: "the prompt carried no remember intent and no update decision",
|
|
55356
55632
|
noMemoryDir: "no Claude Code memory directory for this project",
|
|
55357
55633
|
noNoteChanged: "no note file changed since the last ingestion",
|
|
@@ -58343,7 +58619,7 @@ MeMesh HTTP: bearer token generated for remote access.
|
|
|
58343
58619
|
function __setRemoteTokenForTest(value) {
|
|
58344
58620
|
remoteToken = value;
|
|
58345
58621
|
}
|
|
58346
|
-
var import_express, packageJsonPath, packageRoot, packageVersion, app, apiLimiter, remoteToken, serverAuthRequired, CROSS_SITE_REFUSAL, DoctorFixBody, HttpError, ConfigBody, TaskStateQuerySchema, DreamProposalsQuerySchema, RejectBodySchema, EntitiesQuerySchema, HOST, PORT, ALLOW_REMOTE_BY_ENV, isMain, shutdown;
|
|
58622
|
+
var import_express, packageJsonPath, packageRoot, packageVersion, app, apiLimiter, remoteToken, serverAuthRequired, CROSS_SITE_REFUSAL, DoctorFixBody, HttpError, ConfigReadBody, ConfigBody, TaskStateQuerySchema, DreamProposalsQuerySchema, RejectBodySchema, EntitiesQuerySchema, HOST, PORT, ALLOW_REMOTE_BY_ENV, isMain, shutdown;
|
|
58347
58623
|
var init_server = __esm({
|
|
58348
58624
|
"dist/transports/http/server.js"() {
|
|
58349
58625
|
"use strict";
|
|
@@ -58354,6 +58630,7 @@ var init_server = __esm({
|
|
|
58354
58630
|
init_operations();
|
|
58355
58631
|
init_knowledge_graph();
|
|
58356
58632
|
init_config();
|
|
58633
|
+
init_briefing_level();
|
|
58357
58634
|
init_doctor_fixes();
|
|
58358
58635
|
init_patterns();
|
|
58359
58636
|
init_analytics();
|
|
@@ -58553,14 +58830,22 @@ var init_server = __esm({
|
|
|
58553
58830
|
limit: data.limit
|
|
58554
58831
|
});
|
|
58555
58832
|
}));
|
|
58833
|
+
ConfigReadBody = external_exports.object({
|
|
58834
|
+
autoCapture: external_exports.boolean().optional(),
|
|
58835
|
+
sessionLimit: external_exports.number().int().min(1).max(100).optional(),
|
|
58836
|
+
autoUpdate: external_exports.enum(["off", "patch", "minor", "major"]).optional(),
|
|
58837
|
+
setupCompleted: external_exports.boolean().optional(),
|
|
58838
|
+
briefing: external_exports.unknown().optional()
|
|
58839
|
+
}).strip();
|
|
58556
58840
|
app.get("/v1/config", (_req, res) => handleGet(res, () => ({
|
|
58557
|
-
config:
|
|
58841
|
+
config: ConfigReadBody.parse(readConfig())
|
|
58558
58842
|
})));
|
|
58559
58843
|
ConfigBody = external_exports.object({
|
|
58560
58844
|
autoCapture: external_exports.boolean().optional(),
|
|
58561
58845
|
sessionLimit: external_exports.number().int().min(1).max(100).optional(),
|
|
58562
58846
|
autoUpdate: external_exports.enum(["off", "patch", "minor", "major"]).optional(),
|
|
58563
|
-
setupCompleted: external_exports.boolean().optional()
|
|
58847
|
+
setupCompleted: external_exports.boolean().optional(),
|
|
58848
|
+
briefing: external_exports.enum(BRIEFING_LEVELS).optional()
|
|
58564
58849
|
}).strict();
|
|
58565
58850
|
app.post("/v1/config", (req, res) => handlePost(ConfigBody, req, res, (data) => ConfigBody.strip().parse(updateConfig(data))));
|
|
58566
58851
|
app.get("/v1/update-status", (req, res) => handleGet(res, async () => {
|
|
@@ -60344,6 +60629,7 @@ function summarizeNoteIngest(r) {
|
|
|
60344
60629
|
|
|
60345
60630
|
// dist/transports/cli/cli.js
|
|
60346
60631
|
init_briefing();
|
|
60632
|
+
init_briefing_level();
|
|
60347
60633
|
init_work_topology();
|
|
60348
60634
|
|
|
60349
60635
|
// dist/core/session-insight.js
|
|
@@ -61290,15 +61576,15 @@ program2.command("export").description("Export memories as JSON. Defaults to std
|
|
|
61290
61576
|
}
|
|
61291
61577
|
});
|
|
61292
61578
|
});
|
|
61293
|
-
program2.command("import").description("Import memories from a JSON export file, or a directory of note files (--notes)").argument("[file]", "Path to JSON export file").option("--namespace <ns>", "Override namespace for all imported entities").option("--merge <strategy>", "Merge strategy: skip | overwrite | append", "skip").option("--notes <dir>", "Ingest every frontmatter note file (*.md with name/description/metadata.type) under <dir>: one memory per file, tagged source:note-file; a changed file replaces its memory, a vanished one is tagged source:note-file:missing. Read-only on the directory.").option("--project <name>", "With --notes: the project tag for ingested memories (default: the current directory's project)").option("--json", "With --notes: output the ingestion result as JSON").action(async (file2, opts, cmd) => {
|
|
61579
|
+
program2.command("import").description("Import memories from a JSON export file, or a directory of note files (--notes)").argument("[file]", "Path to JSON export file").option("--namespace <ns>", "Override namespace for all imported entities").option("--merge <strategy>", "Merge strategy: skip | overwrite | append", "skip").option("--restore-archived", "Requires --merge append or overwrite (an error with skip, the default): bring back a local memory you archived (forgot) when the file names it. Without this it stays archived and untouched.").option("--notes <dir>", "Ingest every frontmatter note file (*.md with name/description/metadata.type) under <dir>: one memory per file, tagged source:note-file; a changed file replaces its memory, a vanished one is tagged source:note-file:missing. Read-only on the directory.").option("--project <name>", "With --notes: the project tag for ingested memories (default: the current directory's project)").option("--json", "With --notes: output the ingestion result as JSON").action(async (file2, opts, cmd) => {
|
|
61294
61580
|
if (opts.notes !== void 0) {
|
|
61295
61581
|
if (file2) {
|
|
61296
61582
|
console.error("Error: pass either a JSON export file or --notes <dir>, not both.");
|
|
61297
61583
|
process.exit(1);
|
|
61298
61584
|
}
|
|
61299
|
-
const ignored = ["namespace", "merge"].filter((k) => cmd.getOptionValueSource(k) === "cli");
|
|
61585
|
+
const ignored = ["namespace", "merge", "restoreArchived"].filter((k) => cmd.getOptionValueSource(k) === "cli");
|
|
61300
61586
|
if (ignored.length > 0) {
|
|
61301
|
-
console.error(`Error: --notes does not take ${ignored.map((k) => `--${k}`).join(" or ")}. Note files always go to the personal namespace and a changed file replaces its memory.`);
|
|
61587
|
+
console.error(`Error: --notes does not take ${ignored.map((k) => `--${k.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`)}`).join(" or ")}. Note files always go to the personal namespace and a changed file replaces its memory.`);
|
|
61302
61588
|
process.exit(1);
|
|
61303
61589
|
}
|
|
61304
61590
|
await withDatabase(() => {
|
|
@@ -61330,7 +61616,7 @@ program2.command("import").description("Import memories from a JSON export file,
|
|
|
61330
61616
|
}
|
|
61331
61617
|
const notesOnly = ["project", "json"].filter((k) => cmd.getOptionValueSource(k) === "cli");
|
|
61332
61618
|
if (notesOnly.length > 0) {
|
|
61333
|
-
console.error(`Error: ${notesOnly.map((k) => `--${k}`).join(" and ")} only appl${notesOnly.length > 1 ? "y" : "ies"} to --notes. A JSON export file is imported with --namespace and --
|
|
61619
|
+
console.error(`Error: ${notesOnly.map((k) => `--${k}`).join(" and ")} only appl${notesOnly.length > 1 ? "y" : "ies"} to --notes. A JSON export file is imported with --namespace, --merge and --restore-archived.`);
|
|
61334
61620
|
process.exit(1);
|
|
61335
61621
|
}
|
|
61336
61622
|
requireOneOf(opts.merge, ["skip", "overwrite", "append"], "--merge");
|
|
@@ -61369,7 +61655,8 @@ program2.command("import").description("Import memories from a JSON export file,
|
|
|
61369
61655
|
result = importMemories({
|
|
61370
61656
|
data,
|
|
61371
61657
|
namespace: opts.namespace,
|
|
61372
|
-
merge_strategy: opts.merge
|
|
61658
|
+
merge_strategy: opts.merge,
|
|
61659
|
+
restore_archived: opts.restoreArchived === true
|
|
61373
61660
|
});
|
|
61374
61661
|
} catch (err) {
|
|
61375
61662
|
console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -61377,6 +61664,9 @@ program2.command("import").description("Import memories from a JSON export file,
|
|
|
61377
61664
|
}
|
|
61378
61665
|
const overwriteNote = result.overwritten > 0 ? ` (${result.overwritten} overwritten)` : "";
|
|
61379
61666
|
console.log(`Imported: ${result.imported}${overwriteNote}, Skipped: ${result.skipped}, Appended: ${result.appended}`);
|
|
61667
|
+
if (result.kept_archived > 0) {
|
|
61668
|
+
console.log(`Kept archived: ${result.kept_archived} (you archived these; the file names them, so they were left untouched). Add --restore-archived to bring them back.`);
|
|
61669
|
+
}
|
|
61380
61670
|
if (result.skipped_relations.length > 0) {
|
|
61381
61671
|
console.error(`Note: ${result.skipped_relations.length} relation(s) not restored \u2014 the target is not in this bundle:
|
|
61382
61672
|
${result.skipped_relations.join("\n ")}`);
|
|
@@ -61663,7 +61953,7 @@ agentCmd.command("setup").argument("<host>", "codex-session | codex | claude | g
|
|
|
61663
61953
|
]
|
|
61664
61954
|
].join("\n"));
|
|
61665
61955
|
});
|
|
61666
|
-
program2.command("briefing").description("The assembled work topology for a project \u2014
|
|
61956
|
+
program2.command("briefing").description("The assembled work topology for a project \u2014 decisions, lessons, knowledge and recent activity; task state and the durable-memory index are included at standard/full (the `briefing` setting)").option("--project <name>", "Project name (default: the current directory\u2019s project)").option("--recipient <id>", "Exact recipient; enables recipient-scoped unread message guidance").option("--index", "Only the index of durable memories (decisions, lessons, patterns, references), newest first").option("--json", "Output as JSON").action(async (opts) => {
|
|
61667
61957
|
await withDatabase(() => {
|
|
61668
61958
|
if (opts.index) {
|
|
61669
61959
|
const project = opts.project ?? getProjectName();
|
|
@@ -61680,6 +61970,10 @@ program2.command("briefing").description("The assembled work topology for a proj
|
|
|
61680
61970
|
console.log(JSON.stringify(result));
|
|
61681
61971
|
return;
|
|
61682
61972
|
}
|
|
61973
|
+
if (result.empty) {
|
|
61974
|
+
console.log(`Nothing to brief at level ${result.level} \u2014 no project memories yet.`);
|
|
61975
|
+
return;
|
|
61976
|
+
}
|
|
61683
61977
|
console.log(result.text);
|
|
61684
61978
|
if (result.entityCount === 0 && !result.hasTaskState && result.index.shown === 0 && result.index.older === 0) {
|
|
61685
61979
|
console.log(`
|
|
@@ -61905,23 +62199,24 @@ configCmd.command("list").description("Show current configuration").action(() =>
|
|
|
61905
62199
|
console.log(` ${key}: ${value}`);
|
|
61906
62200
|
}
|
|
61907
62201
|
});
|
|
61908
|
-
var ALLOWED_KEYS = /* @__PURE__ */ new Set(["autoUpdate", "sessionLimit", "autoCapture", "updateCheck"]);
|
|
62202
|
+
var ALLOWED_KEYS = /* @__PURE__ */ new Set(["autoUpdate", "sessionLimit", "autoCapture", "updateCheck", "briefing"]);
|
|
61909
62203
|
var KEY_VALIDATORS = {
|
|
61910
62204
|
autoUpdate: (v) => ["off", "patch", "minor", "major"].includes(v) ? null : "must be one of: off, patch, minor, major",
|
|
61911
62205
|
autoCapture: (v) => ["true", "false", "1", "0"].includes(v) ? null : "must be one of: true, false, 1, 0",
|
|
61912
|
-
updateCheck: (v) => ["true", "false", "1", "0"].includes(v) ? null : "must be one of: true, false, 1, 0"
|
|
62206
|
+
updateCheck: (v) => ["true", "false", "1", "0"].includes(v) ? null : "must be one of: true, false, 1, 0",
|
|
62207
|
+
briefing: (v) => BRIEFING_LEVELS.includes(v) ? null : `must be one of: ${BRIEFING_LEVELS.join(", ")}`
|
|
61913
62208
|
};
|
|
61914
62209
|
function buildConfigListing(config2) {
|
|
61915
62210
|
const rows = [];
|
|
61916
62211
|
for (const key of Array.from(ALLOWED_KEYS).sort()) {
|
|
61917
62212
|
const raw = config2[key];
|
|
61918
|
-
if (raw === void 0
|
|
62213
|
+
if (raw === void 0)
|
|
61919
62214
|
continue;
|
|
61920
62215
|
rows.push({ key, value: String(raw) });
|
|
61921
62216
|
}
|
|
61922
62217
|
return rows;
|
|
61923
62218
|
}
|
|
61924
|
-
configCmd.command("set").description("Set an ordinary config value (autoCapture, sessionLimit, autoUpdate, updateCheck)").argument("<key>", "Config key \u2014 see `memesh config list` for valid keys").argument("<value>", "Config value").action((key, value) => {
|
|
62219
|
+
configCmd.command("set").description("Set an ordinary config value (autoCapture, sessionLimit, autoUpdate, updateCheck, briefing)").argument("<key>", "Config key \u2014 see `memesh config list` for valid keys").argument("<value>", "Config value").action((key, value) => {
|
|
61925
62220
|
const canonical = key;
|
|
61926
62221
|
if (!ALLOWED_KEYS.has(canonical)) {
|
|
61927
62222
|
console.error(`Unknown key: ${key}`);
|