engrm 0.4.38 → 0.4.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +53 -2
- package/dist/cli.js +446 -62
- package/dist/hooks/elicitation-result.js +57 -1
- package/dist/hooks/post-tool-use.js +57 -1
- package/dist/hooks/pre-compact.js +57 -1
- package/dist/hooks/sentinel.js +20 -0
- package/dist/hooks/session-start.js +82 -12
- package/dist/hooks/stop.js +305 -186
- package/dist/hooks/user-prompt-submit.js +57 -1
- package/dist/server.js +339 -76
- package/opencode/README.md +70 -0
- package/opencode/install-or-update-opencode-plugin.sh +46 -0
- package/opencode/opencode.example.json +14 -0
- package/opencode/plugin/engrm-opencode.js +61 -0
- package/package.json +10 -4
|
@@ -137,6 +137,12 @@ function containsSecrets(text, customPatterns = []) {
|
|
|
137
137
|
}
|
|
138
138
|
return false;
|
|
139
139
|
}
|
|
140
|
+
var FLEET_HOSTNAME_PATTERN = /\b(?=.{1,253}\b)(?!-)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}\b/gi;
|
|
141
|
+
var FLEET_IP_PATTERN = /\b(?:\d{1,3}\.){3}\d{1,3}\b/g;
|
|
142
|
+
var FLEET_MAC_PATTERN = /\b(?:[0-9a-f]{2}[:-]){5}[0-9a-f]{2}\b/gi;
|
|
143
|
+
function scrubFleetIdentifiers(text) {
|
|
144
|
+
return text.replace(FLEET_MAC_PATTERN, "[REDACTED_MAC]").replace(FLEET_IP_PATTERN, "[REDACTED_IP]").replace(FLEET_HOSTNAME_PATTERN, "[REDACTED_HOSTNAME]");
|
|
145
|
+
}
|
|
140
146
|
|
|
141
147
|
// src/capture/quality.ts
|
|
142
148
|
var QUALITY_THRESHOLD = 0.1;
|
|
@@ -713,6 +719,35 @@ function narrativesConflict(narrative1, narrative2) {
|
|
|
713
719
|
return null;
|
|
714
720
|
}
|
|
715
721
|
|
|
722
|
+
// src/sync/targets.ts
|
|
723
|
+
function isFleetProjectName(projectName, config) {
|
|
724
|
+
const fleetProjectName = config.fleet?.project_name ?? "shared-experience";
|
|
725
|
+
if (!projectName || !fleetProjectName)
|
|
726
|
+
return false;
|
|
727
|
+
return projectName.trim().toLowerCase() === fleetProjectName.trim().toLowerCase();
|
|
728
|
+
}
|
|
729
|
+
function hasFleetTarget(config) {
|
|
730
|
+
return Boolean(config.fleet?.namespace?.trim() && config.fleet?.api_key?.trim() && (config.fleet?.project_name ?? "shared-experience").trim());
|
|
731
|
+
}
|
|
732
|
+
function resolveSyncTarget(config, projectName) {
|
|
733
|
+
if (isFleetProjectName(projectName, config) && hasFleetTarget(config)) {
|
|
734
|
+
return {
|
|
735
|
+
key: `fleet:${config.fleet.namespace}`,
|
|
736
|
+
apiKey: config.fleet.api_key,
|
|
737
|
+
namespace: config.fleet.namespace,
|
|
738
|
+
siteId: config.site_id,
|
|
739
|
+
isFleet: true
|
|
740
|
+
};
|
|
741
|
+
}
|
|
742
|
+
return {
|
|
743
|
+
key: `default:${config.namespace}`,
|
|
744
|
+
apiKey: config.candengo_api_key,
|
|
745
|
+
namespace: config.namespace,
|
|
746
|
+
siteId: config.site_id,
|
|
747
|
+
isFleet: false
|
|
748
|
+
};
|
|
749
|
+
}
|
|
750
|
+
|
|
716
751
|
// src/tools/save.ts
|
|
717
752
|
var VALID_TYPES = [
|
|
718
753
|
"bugfix",
|
|
@@ -761,7 +796,8 @@ async function saveObservation(db, config, input) {
|
|
|
761
796
|
const factsJson = structuredFacts.length > 0 ? config.scrubbing.enabled ? scrubSecrets(JSON.stringify(structuredFacts), customPatterns) : JSON.stringify(structuredFacts) : null;
|
|
762
797
|
const filesReadJson = filesRead ? JSON.stringify(filesRead) : null;
|
|
763
798
|
const filesModifiedJson = filesModified ? JSON.stringify(filesModified) : null;
|
|
764
|
-
|
|
799
|
+
const fleetProject = isFleetProjectName(project.name, config);
|
|
800
|
+
let sensitivity = input.sensitivity ?? (fleetProject ? "shared" : config.scrubbing.default_sensitivity);
|
|
765
801
|
if (config.scrubbing.enabled && containsSecrets([input.title, input.narrative, JSON.stringify(input.facts)].filter(Boolean).join(" "), customPatterns)) {
|
|
766
802
|
if (sensitivity === "shared") {
|
|
767
803
|
sensitivity = "personal";
|
|
@@ -940,6 +976,16 @@ function createDefaultConfig() {
|
|
|
940
976
|
},
|
|
941
977
|
transcript_analysis: {
|
|
942
978
|
enabled: false
|
|
979
|
+
},
|
|
980
|
+
http: {
|
|
981
|
+
enabled: false,
|
|
982
|
+
port: 3767,
|
|
983
|
+
bearer_tokens: []
|
|
984
|
+
},
|
|
985
|
+
fleet: {
|
|
986
|
+
project_name: "shared-experience",
|
|
987
|
+
namespace: "",
|
|
988
|
+
api_key: ""
|
|
943
989
|
}
|
|
944
990
|
};
|
|
945
991
|
}
|
|
@@ -1001,6 +1047,16 @@ function loadConfig() {
|
|
|
1001
1047
|
},
|
|
1002
1048
|
transcript_analysis: {
|
|
1003
1049
|
enabled: asBool(config["transcript_analysis"]?.["enabled"], defaults.transcript_analysis.enabled)
|
|
1050
|
+
},
|
|
1051
|
+
http: {
|
|
1052
|
+
enabled: asBool(config["http"]?.["enabled"], defaults.http.enabled),
|
|
1053
|
+
port: asNumber(config["http"]?.["port"], defaults.http.port),
|
|
1054
|
+
bearer_tokens: asStringArray(config["http"]?.["bearer_tokens"], defaults.http.bearer_tokens)
|
|
1055
|
+
},
|
|
1056
|
+
fleet: {
|
|
1057
|
+
project_name: asString(config["fleet"]?.["project_name"], defaults.fleet.project_name),
|
|
1058
|
+
namespace: asString(config["fleet"]?.["namespace"], defaults.fleet.namespace),
|
|
1059
|
+
api_key: asString(config["fleet"]?.["api_key"], defaults.fleet.api_key)
|
|
1004
1060
|
}
|
|
1005
1061
|
};
|
|
1006
1062
|
}
|
|
@@ -282,6 +282,16 @@ function createDefaultConfig() {
|
|
|
282
282
|
},
|
|
283
283
|
transcript_analysis: {
|
|
284
284
|
enabled: false
|
|
285
|
+
},
|
|
286
|
+
http: {
|
|
287
|
+
enabled: false,
|
|
288
|
+
port: 3767,
|
|
289
|
+
bearer_tokens: []
|
|
290
|
+
},
|
|
291
|
+
fleet: {
|
|
292
|
+
project_name: "shared-experience",
|
|
293
|
+
namespace: "",
|
|
294
|
+
api_key: ""
|
|
285
295
|
}
|
|
286
296
|
};
|
|
287
297
|
}
|
|
@@ -343,6 +353,16 @@ function loadConfig() {
|
|
|
343
353
|
},
|
|
344
354
|
transcript_analysis: {
|
|
345
355
|
enabled: asBool(config["transcript_analysis"]?.["enabled"], defaults.transcript_analysis.enabled)
|
|
356
|
+
},
|
|
357
|
+
http: {
|
|
358
|
+
enabled: asBool(config["http"]?.["enabled"], defaults.http.enabled),
|
|
359
|
+
port: asNumber(config["http"]?.["port"], defaults.http.port),
|
|
360
|
+
bearer_tokens: asStringArray(config["http"]?.["bearer_tokens"], defaults.http.bearer_tokens)
|
|
361
|
+
},
|
|
362
|
+
fleet: {
|
|
363
|
+
project_name: asString(config["fleet"]?.["project_name"], defaults.fleet.project_name),
|
|
364
|
+
namespace: asString(config["fleet"]?.["namespace"], defaults.fleet.namespace),
|
|
365
|
+
api_key: asString(config["fleet"]?.["api_key"], defaults.fleet.api_key)
|
|
346
366
|
}
|
|
347
367
|
};
|
|
348
368
|
}
|
|
@@ -2216,6 +2236,12 @@ function containsSecrets(text, customPatterns = []) {
|
|
|
2216
2236
|
}
|
|
2217
2237
|
return false;
|
|
2218
2238
|
}
|
|
2239
|
+
var FLEET_HOSTNAME_PATTERN = /\b(?=.{1,253}\b)(?!-)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}\b/gi;
|
|
2240
|
+
var FLEET_IP_PATTERN = /\b(?:\d{1,3}\.){3}\d{1,3}\b/g;
|
|
2241
|
+
var FLEET_MAC_PATTERN = /\b(?:[0-9a-f]{2}[:-]){5}[0-9a-f]{2}\b/gi;
|
|
2242
|
+
function scrubFleetIdentifiers(text) {
|
|
2243
|
+
return text.replace(FLEET_MAC_PATTERN, "[REDACTED_MAC]").replace(FLEET_IP_PATTERN, "[REDACTED_IP]").replace(FLEET_HOSTNAME_PATTERN, "[REDACTED_HOSTNAME]");
|
|
2244
|
+
}
|
|
2219
2245
|
|
|
2220
2246
|
// src/capture/quality.ts
|
|
2221
2247
|
var QUALITY_THRESHOLD = 0.1;
|
|
@@ -2792,6 +2818,35 @@ function narrativesConflict(narrative1, narrative2) {
|
|
|
2792
2818
|
return null;
|
|
2793
2819
|
}
|
|
2794
2820
|
|
|
2821
|
+
// src/sync/targets.ts
|
|
2822
|
+
function isFleetProjectName(projectName, config) {
|
|
2823
|
+
const fleetProjectName = config.fleet?.project_name ?? "shared-experience";
|
|
2824
|
+
if (!projectName || !fleetProjectName)
|
|
2825
|
+
return false;
|
|
2826
|
+
return projectName.trim().toLowerCase() === fleetProjectName.trim().toLowerCase();
|
|
2827
|
+
}
|
|
2828
|
+
function hasFleetTarget(config) {
|
|
2829
|
+
return Boolean(config.fleet?.namespace?.trim() && config.fleet?.api_key?.trim() && (config.fleet?.project_name ?? "shared-experience").trim());
|
|
2830
|
+
}
|
|
2831
|
+
function resolveSyncTarget(config, projectName) {
|
|
2832
|
+
if (isFleetProjectName(projectName, config) && hasFleetTarget(config)) {
|
|
2833
|
+
return {
|
|
2834
|
+
key: `fleet:${config.fleet.namespace}`,
|
|
2835
|
+
apiKey: config.fleet.api_key,
|
|
2836
|
+
namespace: config.fleet.namespace,
|
|
2837
|
+
siteId: config.site_id,
|
|
2838
|
+
isFleet: true
|
|
2839
|
+
};
|
|
2840
|
+
}
|
|
2841
|
+
return {
|
|
2842
|
+
key: `default:${config.namespace}`,
|
|
2843
|
+
apiKey: config.candengo_api_key,
|
|
2844
|
+
namespace: config.namespace,
|
|
2845
|
+
siteId: config.site_id,
|
|
2846
|
+
isFleet: false
|
|
2847
|
+
};
|
|
2848
|
+
}
|
|
2849
|
+
|
|
2795
2850
|
// src/tools/save.ts
|
|
2796
2851
|
var VALID_TYPES = [
|
|
2797
2852
|
"bugfix",
|
|
@@ -2840,7 +2895,8 @@ async function saveObservation(db, config, input) {
|
|
|
2840
2895
|
const factsJson = structuredFacts.length > 0 ? config.scrubbing.enabled ? scrubSecrets(JSON.stringify(structuredFacts), customPatterns) : JSON.stringify(structuredFacts) : null;
|
|
2841
2896
|
const filesReadJson = filesRead ? JSON.stringify(filesRead) : null;
|
|
2842
2897
|
const filesModifiedJson = filesModified ? JSON.stringify(filesModified) : null;
|
|
2843
|
-
|
|
2898
|
+
const fleetProject = isFleetProjectName(project.name, config);
|
|
2899
|
+
let sensitivity = input.sensitivity ?? (fleetProject ? "shared" : config.scrubbing.default_sensitivity);
|
|
2844
2900
|
if (config.scrubbing.enabled && containsSecrets([input.title, input.narrative, JSON.stringify(input.facts)].filter(Boolean).join(" "), customPatterns)) {
|
|
2845
2901
|
if (sensitivity === "shared") {
|
|
2846
2902
|
sensitivity = "personal";
|
|
@@ -76,6 +76,16 @@ function createDefaultConfig() {
|
|
|
76
76
|
},
|
|
77
77
|
transcript_analysis: {
|
|
78
78
|
enabled: false
|
|
79
|
+
},
|
|
80
|
+
http: {
|
|
81
|
+
enabled: false,
|
|
82
|
+
port: 3767,
|
|
83
|
+
bearer_tokens: []
|
|
84
|
+
},
|
|
85
|
+
fleet: {
|
|
86
|
+
project_name: "shared-experience",
|
|
87
|
+
namespace: "",
|
|
88
|
+
api_key: ""
|
|
79
89
|
}
|
|
80
90
|
};
|
|
81
91
|
}
|
|
@@ -137,6 +147,16 @@ function loadConfig() {
|
|
|
137
147
|
},
|
|
138
148
|
transcript_analysis: {
|
|
139
149
|
enabled: asBool(config["transcript_analysis"]?.["enabled"], defaults.transcript_analysis.enabled)
|
|
150
|
+
},
|
|
151
|
+
http: {
|
|
152
|
+
enabled: asBool(config["http"]?.["enabled"], defaults.http.enabled),
|
|
153
|
+
port: asNumber(config["http"]?.["port"], defaults.http.port),
|
|
154
|
+
bearer_tokens: asStringArray(config["http"]?.["bearer_tokens"], defaults.http.bearer_tokens)
|
|
155
|
+
},
|
|
156
|
+
fleet: {
|
|
157
|
+
project_name: asString(config["fleet"]?.["project_name"], defaults.fleet.project_name),
|
|
158
|
+
namespace: asString(config["fleet"]?.["namespace"], defaults.fleet.namespace),
|
|
159
|
+
api_key: asString(config["fleet"]?.["api_key"], defaults.fleet.api_key)
|
|
140
160
|
}
|
|
141
161
|
};
|
|
142
162
|
}
|
|
@@ -2490,6 +2510,12 @@ function containsSecrets(text, customPatterns = []) {
|
|
|
2490
2510
|
}
|
|
2491
2511
|
return false;
|
|
2492
2512
|
}
|
|
2513
|
+
var FLEET_HOSTNAME_PATTERN = /\b(?=.{1,253}\b)(?!-)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}\b/gi;
|
|
2514
|
+
var FLEET_IP_PATTERN = /\b(?:\d{1,3}\.){3}\d{1,3}\b/g;
|
|
2515
|
+
var FLEET_MAC_PATTERN = /\b(?:[0-9a-f]{2}[:-]){5}[0-9a-f]{2}\b/gi;
|
|
2516
|
+
function scrubFleetIdentifiers(text) {
|
|
2517
|
+
return text.replace(FLEET_MAC_PATTERN, "[REDACTED_MAC]").replace(FLEET_IP_PATTERN, "[REDACTED_IP]").replace(FLEET_HOSTNAME_PATTERN, "[REDACTED_HOSTNAME]");
|
|
2518
|
+
}
|
|
2493
2519
|
|
|
2494
2520
|
// src/capture/quality.ts
|
|
2495
2521
|
var QUALITY_THRESHOLD = 0.1;
|
|
@@ -2885,6 +2911,35 @@ function narrativesConflict(narrative1, narrative2) {
|
|
|
2885
2911
|
return null;
|
|
2886
2912
|
}
|
|
2887
2913
|
|
|
2914
|
+
// src/sync/targets.ts
|
|
2915
|
+
function isFleetProjectName(projectName, config) {
|
|
2916
|
+
const fleetProjectName = config.fleet?.project_name ?? "shared-experience";
|
|
2917
|
+
if (!projectName || !fleetProjectName)
|
|
2918
|
+
return false;
|
|
2919
|
+
return projectName.trim().toLowerCase() === fleetProjectName.trim().toLowerCase();
|
|
2920
|
+
}
|
|
2921
|
+
function hasFleetTarget(config) {
|
|
2922
|
+
return Boolean(config.fleet?.namespace?.trim() && config.fleet?.api_key?.trim() && (config.fleet?.project_name ?? "shared-experience").trim());
|
|
2923
|
+
}
|
|
2924
|
+
function resolveSyncTarget(config, projectName) {
|
|
2925
|
+
if (isFleetProjectName(projectName, config) && hasFleetTarget(config)) {
|
|
2926
|
+
return {
|
|
2927
|
+
key: `fleet:${config.fleet.namespace}`,
|
|
2928
|
+
apiKey: config.fleet.api_key,
|
|
2929
|
+
namespace: config.fleet.namespace,
|
|
2930
|
+
siteId: config.site_id,
|
|
2931
|
+
isFleet: true
|
|
2932
|
+
};
|
|
2933
|
+
}
|
|
2934
|
+
return {
|
|
2935
|
+
key: `default:${config.namespace}`,
|
|
2936
|
+
apiKey: config.candengo_api_key,
|
|
2937
|
+
namespace: config.namespace,
|
|
2938
|
+
siteId: config.site_id,
|
|
2939
|
+
isFleet: false
|
|
2940
|
+
};
|
|
2941
|
+
}
|
|
2942
|
+
|
|
2888
2943
|
// src/tools/save.ts
|
|
2889
2944
|
var VALID_TYPES = [
|
|
2890
2945
|
"bugfix",
|
|
@@ -2933,7 +2988,8 @@ async function saveObservation(db, config, input) {
|
|
|
2933
2988
|
const factsJson = structuredFacts.length > 0 ? config.scrubbing.enabled ? scrubSecrets(JSON.stringify(structuredFacts), customPatterns) : JSON.stringify(structuredFacts) : null;
|
|
2934
2989
|
const filesReadJson = filesRead ? JSON.stringify(filesRead) : null;
|
|
2935
2990
|
const filesModifiedJson = filesModified ? JSON.stringify(filesModified) : null;
|
|
2936
|
-
|
|
2991
|
+
const fleetProject = isFleetProjectName(project.name, config);
|
|
2992
|
+
let sensitivity = input.sensitivity ?? (fleetProject ? "shared" : config.scrubbing.default_sensitivity);
|
|
2937
2993
|
if (config.scrubbing.enabled && containsSecrets([input.title, input.narrative, JSON.stringify(input.facts)].filter(Boolean).join(" "), customPatterns)) {
|
|
2938
2994
|
if (sensitivity === "shared") {
|
|
2939
2995
|
sensitivity = "personal";
|
package/dist/hooks/sentinel.js
CHANGED
|
@@ -152,6 +152,16 @@ function createDefaultConfig() {
|
|
|
152
152
|
},
|
|
153
153
|
transcript_analysis: {
|
|
154
154
|
enabled: false
|
|
155
|
+
},
|
|
156
|
+
http: {
|
|
157
|
+
enabled: false,
|
|
158
|
+
port: 3767,
|
|
159
|
+
bearer_tokens: []
|
|
160
|
+
},
|
|
161
|
+
fleet: {
|
|
162
|
+
project_name: "shared-experience",
|
|
163
|
+
namespace: "",
|
|
164
|
+
api_key: ""
|
|
155
165
|
}
|
|
156
166
|
};
|
|
157
167
|
}
|
|
@@ -213,6 +223,16 @@ function loadConfig() {
|
|
|
213
223
|
},
|
|
214
224
|
transcript_analysis: {
|
|
215
225
|
enabled: asBool(config["transcript_analysis"]?.["enabled"], defaults.transcript_analysis.enabled)
|
|
226
|
+
},
|
|
227
|
+
http: {
|
|
228
|
+
enabled: asBool(config["http"]?.["enabled"], defaults.http.enabled),
|
|
229
|
+
port: asNumber(config["http"]?.["port"], defaults.http.port),
|
|
230
|
+
bearer_tokens: asStringArray(config["http"]?.["bearer_tokens"], defaults.http.bearer_tokens)
|
|
231
|
+
},
|
|
232
|
+
fleet: {
|
|
233
|
+
project_name: asString(config["fleet"]?.["project_name"], defaults.fleet.project_name),
|
|
234
|
+
namespace: asString(config["fleet"]?.["namespace"], defaults.fleet.namespace),
|
|
235
|
+
api_key: asString(config["fleet"]?.["api_key"], defaults.fleet.api_key)
|
|
216
236
|
}
|
|
217
237
|
};
|
|
218
238
|
}
|
|
@@ -755,6 +755,12 @@ function containsSecrets(text, customPatterns = []) {
|
|
|
755
755
|
}
|
|
756
756
|
return false;
|
|
757
757
|
}
|
|
758
|
+
var FLEET_HOSTNAME_PATTERN = /\b(?=.{1,253}\b)(?!-)(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,63}\b/gi;
|
|
759
|
+
var FLEET_IP_PATTERN = /\b(?:\d{1,3}\.){3}\d{1,3}\b/g;
|
|
760
|
+
var FLEET_MAC_PATTERN = /\b(?:[0-9a-f]{2}[:-]){5}[0-9a-f]{2}\b/gi;
|
|
761
|
+
function scrubFleetIdentifiers(text) {
|
|
762
|
+
return text.replace(FLEET_MAC_PATTERN, "[REDACTED_MAC]").replace(FLEET_IP_PATTERN, "[REDACTED_IP]").replace(FLEET_HOSTNAME_PATTERN, "[REDACTED_HOSTNAME]");
|
|
763
|
+
}
|
|
758
764
|
|
|
759
765
|
// src/capture/quality.ts
|
|
760
766
|
var QUALITY_THRESHOLD = 0.1;
|
|
@@ -1150,6 +1156,35 @@ function narrativesConflict(narrative1, narrative2) {
|
|
|
1150
1156
|
return null;
|
|
1151
1157
|
}
|
|
1152
1158
|
|
|
1159
|
+
// src/sync/targets.ts
|
|
1160
|
+
function isFleetProjectName(projectName, config) {
|
|
1161
|
+
const fleetProjectName = config.fleet?.project_name ?? "shared-experience";
|
|
1162
|
+
if (!projectName || !fleetProjectName)
|
|
1163
|
+
return false;
|
|
1164
|
+
return projectName.trim().toLowerCase() === fleetProjectName.trim().toLowerCase();
|
|
1165
|
+
}
|
|
1166
|
+
function hasFleetTarget(config) {
|
|
1167
|
+
return Boolean(config.fleet?.namespace?.trim() && config.fleet?.api_key?.trim() && (config.fleet?.project_name ?? "shared-experience").trim());
|
|
1168
|
+
}
|
|
1169
|
+
function resolveSyncTarget(config, projectName) {
|
|
1170
|
+
if (isFleetProjectName(projectName, config) && hasFleetTarget(config)) {
|
|
1171
|
+
return {
|
|
1172
|
+
key: `fleet:${config.fleet.namespace}`,
|
|
1173
|
+
apiKey: config.fleet.api_key,
|
|
1174
|
+
namespace: config.fleet.namespace,
|
|
1175
|
+
siteId: config.site_id,
|
|
1176
|
+
isFleet: true
|
|
1177
|
+
};
|
|
1178
|
+
}
|
|
1179
|
+
return {
|
|
1180
|
+
key: `default:${config.namespace}`,
|
|
1181
|
+
apiKey: config.candengo_api_key,
|
|
1182
|
+
namespace: config.namespace,
|
|
1183
|
+
siteId: config.site_id,
|
|
1184
|
+
isFleet: false
|
|
1185
|
+
};
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1153
1188
|
// src/tools/save.ts
|
|
1154
1189
|
var VALID_TYPES = [
|
|
1155
1190
|
"bugfix",
|
|
@@ -1198,7 +1233,8 @@ async function saveObservation(db, config, input) {
|
|
|
1198
1233
|
const factsJson = structuredFacts.length > 0 ? config.scrubbing.enabled ? scrubSecrets(JSON.stringify(structuredFacts), customPatterns) : JSON.stringify(structuredFacts) : null;
|
|
1199
1234
|
const filesReadJson = filesRead ? JSON.stringify(filesRead) : null;
|
|
1200
1235
|
const filesModifiedJson = filesModified ? JSON.stringify(filesModified) : null;
|
|
1201
|
-
|
|
1236
|
+
const fleetProject = isFleetProjectName(project.name, config);
|
|
1237
|
+
let sensitivity = input.sensitivity ?? (fleetProject ? "shared" : config.scrubbing.default_sensitivity);
|
|
1202
1238
|
if (config.scrubbing.enabled && containsSecrets([input.title, input.narrative, JSON.stringify(input.facts)].filter(Boolean).join(" "), customPatterns)) {
|
|
1203
1239
|
if (sensitivity === "shared") {
|
|
1204
1240
|
sensitivity = "personal";
|
|
@@ -3104,6 +3140,11 @@ function describeContinuityState(state) {
|
|
|
3104
3140
|
return "No fresh repo-local continuity yet; older memory should be treated cautiously.";
|
|
3105
3141
|
}
|
|
3106
3142
|
}
|
|
3143
|
+
function pickPreferredAgent(activeAgents, latestAgent) {
|
|
3144
|
+
if (activeAgents.includes("claude-code"))
|
|
3145
|
+
return "claude-code";
|
|
3146
|
+
return latestAgent && activeAgents.includes(latestAgent) ? latestAgent : activeAgents[0] ?? null;
|
|
3147
|
+
}
|
|
3107
3148
|
|
|
3108
3149
|
// src/telemetry/stack-detect.ts
|
|
3109
3150
|
import { existsSync as existsSync2 } from "node:fs";
|
|
@@ -3225,7 +3266,7 @@ import { existsSync as existsSync3, readFileSync as readFileSync2, writeFileSync
|
|
|
3225
3266
|
import { join as join3 } from "node:path";
|
|
3226
3267
|
import { homedir } from "node:os";
|
|
3227
3268
|
var STATE_PATH = join3(homedir(), ".engrm", "config-fingerprint.json");
|
|
3228
|
-
var CLIENT_VERSION = "0.4.
|
|
3269
|
+
var CLIENT_VERSION = "0.4.39";
|
|
3229
3270
|
function hashFile(filePath) {
|
|
3230
3271
|
try {
|
|
3231
3272
|
if (!existsSync3(filePath))
|
|
@@ -3429,6 +3470,16 @@ function createDefaultConfig() {
|
|
|
3429
3470
|
},
|
|
3430
3471
|
transcript_analysis: {
|
|
3431
3472
|
enabled: false
|
|
3473
|
+
},
|
|
3474
|
+
http: {
|
|
3475
|
+
enabled: false,
|
|
3476
|
+
port: 3767,
|
|
3477
|
+
bearer_tokens: []
|
|
3478
|
+
},
|
|
3479
|
+
fleet: {
|
|
3480
|
+
project_name: "shared-experience",
|
|
3481
|
+
namespace: "",
|
|
3482
|
+
api_key: ""
|
|
3432
3483
|
}
|
|
3433
3484
|
};
|
|
3434
3485
|
}
|
|
@@ -3490,6 +3541,16 @@ function loadConfig() {
|
|
|
3490
3541
|
},
|
|
3491
3542
|
transcript_analysis: {
|
|
3492
3543
|
enabled: asBool(config["transcript_analysis"]?.["enabled"], defaults.transcript_analysis.enabled)
|
|
3544
|
+
},
|
|
3545
|
+
http: {
|
|
3546
|
+
enabled: asBool(config["http"]?.["enabled"], defaults.http.enabled),
|
|
3547
|
+
port: asNumber(config["http"]?.["port"], defaults.http.port),
|
|
3548
|
+
bearer_tokens: asStringArray(config["http"]?.["bearer_tokens"], defaults.http.bearer_tokens)
|
|
3549
|
+
},
|
|
3550
|
+
fleet: {
|
|
3551
|
+
project_name: asString(config["fleet"]?.["project_name"], defaults.fleet.project_name),
|
|
3552
|
+
namespace: asString(config["fleet"]?.["namespace"], defaults.fleet.namespace),
|
|
3553
|
+
api_key: asString(config["fleet"]?.["api_key"], defaults.fleet.api_key)
|
|
3493
3554
|
}
|
|
3494
3555
|
};
|
|
3495
3556
|
}
|
|
@@ -3610,10 +3671,13 @@ function parseSourceId(sourceId) {
|
|
|
3610
3671
|
}
|
|
3611
3672
|
|
|
3612
3673
|
// src/sync/pull.ts
|
|
3613
|
-
|
|
3674
|
+
function pullCursorKey(namespace) {
|
|
3675
|
+
return namespace === "default" ? "pull_cursor" : `pull_cursor:${namespace}`;
|
|
3676
|
+
}
|
|
3614
3677
|
var MAX_PAGES = 20;
|
|
3615
3678
|
async function pullFromVector(db, client, config, limit = 50) {
|
|
3616
|
-
|
|
3679
|
+
const cursorKey = pullCursorKey(client.namespace || "default");
|
|
3680
|
+
let cursor = db.getSyncState(cursorKey) ?? undefined;
|
|
3617
3681
|
let totalReceived = 0;
|
|
3618
3682
|
let totalMerged = 0;
|
|
3619
3683
|
let totalSkipped = 0;
|
|
@@ -3624,7 +3688,7 @@ async function pullFromVector(db, client, config, limit = 50) {
|
|
|
3624
3688
|
totalMerged += merged;
|
|
3625
3689
|
totalSkipped += skipped;
|
|
3626
3690
|
if (response.cursor) {
|
|
3627
|
-
db.setSyncState(
|
|
3691
|
+
db.setSyncState(cursorKey, response.cursor);
|
|
3628
3692
|
cursor = response.cursor;
|
|
3629
3693
|
}
|
|
3630
3694
|
if (!response.has_more || response.changes.length === 0)
|
|
@@ -3841,16 +3905,16 @@ class VectorClient {
|
|
|
3841
3905
|
apiKey;
|
|
3842
3906
|
siteId;
|
|
3843
3907
|
namespace;
|
|
3844
|
-
constructor(config) {
|
|
3908
|
+
constructor(config, overrides = {}) {
|
|
3845
3909
|
const baseUrl = getBaseUrl(config);
|
|
3846
|
-
const apiKey = getApiKey(config);
|
|
3910
|
+
const apiKey = overrides.apiKey ?? getApiKey(config);
|
|
3847
3911
|
if (!baseUrl || !apiKey) {
|
|
3848
3912
|
throw new Error("VectorClient requires candengo_url and candengo_api_key");
|
|
3849
3913
|
}
|
|
3850
3914
|
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
3851
3915
|
this.apiKey = apiKey;
|
|
3852
|
-
this.siteId = config.site_id;
|
|
3853
|
-
this.namespace = config.namespace;
|
|
3916
|
+
this.siteId = overrides.siteId ?? config.site_id;
|
|
3917
|
+
this.namespace = overrides.namespace ?? config.namespace;
|
|
3854
3918
|
}
|
|
3855
3919
|
static isConfigured(config) {
|
|
3856
3920
|
return getApiKey(config) !== null && getBaseUrl(config) !== null;
|
|
@@ -5980,8 +6044,9 @@ function formatInspectHints(context, visibleObservationIds = [], recallItems = [
|
|
|
5980
6044
|
if (unique.length === 0)
|
|
5981
6045
|
return [];
|
|
5982
6046
|
const ids = visibleObservationIds.slice(0, 5);
|
|
5983
|
-
const
|
|
5984
|
-
const
|
|
6047
|
+
const preferredAgent = pickPreferredAgent(activeAgents, context.recentSessions?.[0]?.agent ?? null);
|
|
6048
|
+
const openNowItem = (preferredAgent ? recallItems.find((item) => item.source_agent === preferredAgent && item.kind !== "memory") ?? recallItems.find((item) => item.source_agent === preferredAgent) : null) ?? recallItems.find((item) => item.kind !== "memory") ?? null;
|
|
6049
|
+
const resumeAgent = activeAgents.length > 1 ? preferredAgent : null;
|
|
5985
6050
|
const fetchHint = ids.length > 0 ? `get_observations([${ids.join(", ")}])` : null;
|
|
5986
6051
|
return [
|
|
5987
6052
|
`${c2.dim}Next look:${c2.reset} ${unique.join(" \xB7 ")}`,
|
|
@@ -6058,7 +6123,12 @@ function buildStartupRecallItems(context) {
|
|
|
6058
6123
|
});
|
|
6059
6124
|
}
|
|
6060
6125
|
const seen = new Set;
|
|
6061
|
-
|
|
6126
|
+
const preferredAgent = pickPreferredAgent(collectStartupAgents(context), context.recentSessions?.[0]?.agent ?? null);
|
|
6127
|
+
return items.sort((a, b) => {
|
|
6128
|
+
const aBoost = preferredAgent && a.source_agent === preferredAgent ? 1 : 0;
|
|
6129
|
+
const bBoost = preferredAgent && b.source_agent === preferredAgent ? 1 : 0;
|
|
6130
|
+
return b.score + bBoost - (a.score + aBoost) || a.key.localeCompare(b.key);
|
|
6131
|
+
}).filter((item) => {
|
|
6062
6132
|
if (seen.has(item.key))
|
|
6063
6133
|
return false;
|
|
6064
6134
|
seen.add(item.key);
|