@hivelore/core 0.57.4 → 0.57.6
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/dist/index.d.ts +55 -3
- package/dist/index.js +140 -41
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -50,6 +50,14 @@ var SensorSchema = z.object({
|
|
|
50
50
|
absent: z.string().optional(),
|
|
51
51
|
/** Regex flags (e.g. "i", "m"). Ignored for non-regex kinds. */
|
|
52
52
|
flags: z.string().optional(),
|
|
53
|
+
/**
|
|
54
|
+
* kind=regex only: flip the sensor into a REQUIRED-PRESENCE invariant. `pattern` then names a line
|
|
55
|
+
* that must REMAIN present in the anchored file's final content; the sensor FIRES when a change
|
|
56
|
+
* removes it. A normal regex sensor scans ADDED lines and so structurally cannot see a deletion —
|
|
57
|
+
* this catches the "someone deleted the critical line" class (e.g. a `TimeZone.setDefault(UTC)`
|
|
58
|
+
* guard) that a diff-of-additions sensor misses (field report §3.5).
|
|
59
|
+
*/
|
|
60
|
+
require_present: z.boolean().optional(),
|
|
53
61
|
/** Shell/test command to run (for kind=shell|test). Executed by the CLI, never by core. */
|
|
54
62
|
command: z.string().optional(),
|
|
55
63
|
/** Max runtime for kind=shell|test commands (default 120000). The executor kills on expiry. */
|
|
@@ -135,7 +143,17 @@ var MemoryFrontmatterSchema = z.object({
|
|
|
135
143
|
* null when the memory is not yet validated, or on legacy memories written before this field.
|
|
136
144
|
* Lets a human distinguish reviewed knowledge from AI/auto-trusted knowledge.
|
|
137
145
|
*/
|
|
138
|
-
validated_by: z.enum(["human", "agent", "auto"]).nullable().default(null)
|
|
146
|
+
validated_by: z.enum(["human", "agent", "auto"]).nullable().default(null),
|
|
147
|
+
/**
|
|
148
|
+
* Does this memory describe code that EXISTS today, or a decision not yet built? Orthogonal to
|
|
149
|
+
* `confidence`/`status`: a `planned` decision can be fully trusted AS a decision while being false
|
|
150
|
+
* AS a description of the current code. Surfaced distinctly in briefings so an agent does not write
|
|
151
|
+
* code against a cookie/route/Node version that was only decided, never implemented (field report §3.3).
|
|
152
|
+
* applied — reflected in the code now (the default when omitted)
|
|
153
|
+
* planned — decided/intended, NOT yet implemented
|
|
154
|
+
* abandoned — considered and rejected; kept so it is not re-attempted
|
|
155
|
+
*/
|
|
156
|
+
lifecycle: z.enum(["applied", "planned", "abandoned"]).optional()
|
|
139
157
|
}).refine(
|
|
140
158
|
(data) => data.scope !== "module" || !!data.module,
|
|
141
159
|
{ message: "module name is required when scope is 'module'", path: ["module"] }
|
|
@@ -153,15 +171,30 @@ var CrossRepoProvenanceSchema = z.object({
|
|
|
153
171
|
|
|
154
172
|
// src/parser.ts
|
|
155
173
|
import matter from "gray-matter";
|
|
174
|
+
import "zod";
|
|
156
175
|
var PRIVATE_BLOCK_RE = /<private>[\s\S]*?<\/private>/g;
|
|
157
176
|
function stripPrivate(body) {
|
|
158
177
|
return body.replace(PRIVATE_BLOCK_RE, "").trimEnd();
|
|
159
178
|
}
|
|
179
|
+
function formatFrontmatterError(err) {
|
|
180
|
+
const issue = err.issues[0];
|
|
181
|
+
if (!issue) return "invalid frontmatter";
|
|
182
|
+
const field = issue.path.length > 0 ? issue.path.join(".") : "frontmatter";
|
|
183
|
+
if (issue.code === "invalid_enum_value") {
|
|
184
|
+
const got = JSON.stringify(issue.received);
|
|
185
|
+
const allowed = issue.options.join(" | ");
|
|
186
|
+
return `invalid ${field}: ${got} is not a supported value \u2014 expected one of: ${allowed}`;
|
|
187
|
+
}
|
|
188
|
+
return `invalid ${field}: ${issue.message}`;
|
|
189
|
+
}
|
|
160
190
|
function parseMemory(raw) {
|
|
161
191
|
const parsed = matter(raw);
|
|
162
|
-
const
|
|
192
|
+
const result = MemoryFrontmatterSchema.safeParse(parsed.data);
|
|
193
|
+
if (!result.success) {
|
|
194
|
+
throw new Error(formatFrontmatterError(result.error));
|
|
195
|
+
}
|
|
163
196
|
return {
|
|
164
|
-
frontmatter,
|
|
197
|
+
frontmatter: result.data,
|
|
165
198
|
body: stripPrivate(parsed.content.trim())
|
|
166
199
|
};
|
|
167
200
|
}
|
|
@@ -210,6 +243,7 @@ function buildFrontmatter(input) {
|
|
|
210
243
|
topic: input.topic,
|
|
211
244
|
sensor: input.sensor,
|
|
212
245
|
activation: input.activation,
|
|
246
|
+
lifecycle: input.lifecycle,
|
|
213
247
|
revision_count: 0,
|
|
214
248
|
related_ids: input.relatedIds ?? []
|
|
215
249
|
});
|
|
@@ -910,7 +944,7 @@ function applyFeedbackAdjustment(fm, adjustment, now = /* @__PURE__ */ new Date(
|
|
|
910
944
|
}
|
|
911
945
|
|
|
912
946
|
// src/prevention.ts
|
|
913
|
-
import { appendFile, mkdir as mkdir2, readFile as readFile4 } from "fs/promises";
|
|
947
|
+
import { appendFile, mkdir as mkdir2, readFile as readFile4, writeFile as writeFile2 } from "fs/promises";
|
|
914
948
|
import { existsSync as existsSync4 } from "fs";
|
|
915
949
|
import path6 from "path";
|
|
916
950
|
function preventionLogPath(paths) {
|
|
@@ -938,8 +972,22 @@ async function recordPreventionHits(paths, firedIds, source, now = /* @__PURE__
|
|
|
938
972
|
await appendPreventionEvent(paths, { at, id, source, ...details[id] }).catch(() => {
|
|
939
973
|
});
|
|
940
974
|
}
|
|
975
|
+
await stampSensorLastFired(paths, recordedIds, at).catch(() => {
|
|
976
|
+
});
|
|
941
977
|
return recordedIds;
|
|
942
978
|
}
|
|
979
|
+
async function stampSensorLastFired(paths, ids, at) {
|
|
980
|
+
if (ids.length === 0 || !existsSync4(paths.memoriesDir)) return;
|
|
981
|
+
const wanted = new Set(ids);
|
|
982
|
+
const loaded = await loadMemoriesFromDir(paths.memoriesDir);
|
|
983
|
+
for (const { memory, filePath } of loaded) {
|
|
984
|
+
const fm = memory.frontmatter;
|
|
985
|
+
if (!wanted.has(fm.id) || !fm.sensor || fm.sensor.last_fired === at) continue;
|
|
986
|
+
const next = { ...memory, frontmatter: { ...fm, sensor: { ...fm.sensor, last_fired: at } } };
|
|
987
|
+
await writeFile2(filePath, serializeMemory(next), "utf8").catch(() => {
|
|
988
|
+
});
|
|
989
|
+
}
|
|
990
|
+
}
|
|
943
991
|
function buildPreventionReceipt(events, memories, usage, options) {
|
|
944
992
|
const now = options.now ?? /* @__PURE__ */ new Date();
|
|
945
993
|
const sinceMs = options.since.getTime();
|
|
@@ -990,6 +1038,11 @@ function buildPreventionReceipt(events, memories, usage, options) {
|
|
|
990
1038
|
events: rows
|
|
991
1039
|
};
|
|
992
1040
|
}
|
|
1041
|
+
function trendClause(total, previous) {
|
|
1042
|
+
const counts = `${total} this window vs ${previous} previous window`;
|
|
1043
|
+
if (total + previous < 3) return counts;
|
|
1044
|
+
return `${counts} (${total <= previous ? "recurrences declining" : "recurrences rising"})`;
|
|
1045
|
+
}
|
|
993
1046
|
function renderPreventionReceipt(receipt) {
|
|
994
1047
|
const lines = [
|
|
995
1048
|
`Hivelore prevention receipt \u2014 last ${receipt.window_days} days`,
|
|
@@ -1007,9 +1060,7 @@ function renderPreventionReceipt(receipt) {
|
|
|
1007
1060
|
const red = row.red_proven ? " \u2713 RED-proven" : "";
|
|
1008
1061
|
lines.push(` \u2717\u2192\u2713 ${row.at.slice(0, 10)} ${row.id.padEnd(32)} (${kind}${exit}${stage})${incident}${red}`);
|
|
1009
1062
|
}
|
|
1010
|
-
lines.push(
|
|
1011
|
-
` Trend: ${receipt.total} this window vs ${receipt.previous_total} previous window (${receipt.total <= receipt.previous_total ? "recurrences declining" : "recurrences rising"}).`
|
|
1012
|
-
);
|
|
1063
|
+
lines.push(` Trend: ${trendClause(receipt.total, receipt.previous_total)}.`);
|
|
1013
1064
|
return lines.join("\n");
|
|
1014
1065
|
}
|
|
1015
1066
|
var HIVELORE_ATTRIBUTION = "\u{1F6E1}\uFE0F Generated by [Hivelore](https://github.com/Doucs91/hivelore) \u2014 the deterministic policy gate for agent-written code.";
|
|
@@ -1036,7 +1087,7 @@ function renderPreventionReceiptShare(receipt) {
|
|
|
1036
1087
|
}
|
|
1037
1088
|
lines.push(
|
|
1038
1089
|
"",
|
|
1039
|
-
`_Trend: ${
|
|
1090
|
+
`_Trend: ${trendClause(receipt.total, receipt.previous_total)}._`
|
|
1040
1091
|
);
|
|
1041
1092
|
}
|
|
1042
1093
|
lines.push("", `<sub>${HIVELORE_ATTRIBUTION}</sub>`);
|
|
@@ -1195,7 +1246,7 @@ function renderCaughtForYou(summary) {
|
|
|
1195
1246
|
|
|
1196
1247
|
// src/context-throttle.ts
|
|
1197
1248
|
import { createHash } from "crypto";
|
|
1198
|
-
import { mkdir as mkdir3, readFile as readFile5, writeFile as
|
|
1249
|
+
import { mkdir as mkdir3, readFile as readFile5, writeFile as writeFile3 } from "fs/promises";
|
|
1199
1250
|
import { existsSync as existsSync5 } from "fs";
|
|
1200
1251
|
import path7 from "path";
|
|
1201
1252
|
var PROJECT_CONTEXT_THROTTLE_MS = 8 * 60 * 1e3;
|
|
@@ -1220,12 +1271,12 @@ async function recordProjectContextEmission(paths, hash, now = Date.now()) {
|
|
|
1220
1271
|
const file = throttleMarkerPath(paths);
|
|
1221
1272
|
await mkdir3(path7.dirname(file), { recursive: true }).catch(() => {
|
|
1222
1273
|
});
|
|
1223
|
-
await
|
|
1274
|
+
await writeFile3(file, JSON.stringify({ hash, at: new Date(now).toISOString() }), "utf8").catch(() => {
|
|
1224
1275
|
});
|
|
1225
1276
|
}
|
|
1226
1277
|
|
|
1227
1278
|
// src/gate-reminder.ts
|
|
1228
|
-
import { mkdir as mkdir4, readFile as readFile6, writeFile as
|
|
1279
|
+
import { mkdir as mkdir4, readFile as readFile6, writeFile as writeFile4 } from "fs/promises";
|
|
1229
1280
|
import { existsSync as existsSync6 } from "fs";
|
|
1230
1281
|
import path8 from "path";
|
|
1231
1282
|
var GATE_REMINDER_WINDOW_MS = 24 * 60 * 60 * 1e3;
|
|
@@ -1254,7 +1305,7 @@ async function recordGateReminder(paths, key, now = Date.now()) {
|
|
|
1254
1305
|
markers[key] = new Date(now).toISOString();
|
|
1255
1306
|
await mkdir4(path8.dirname(file), { recursive: true }).catch(() => {
|
|
1256
1307
|
});
|
|
1257
|
-
await
|
|
1308
|
+
await writeFile4(file, JSON.stringify(markers, null, 2), "utf8").catch(() => {
|
|
1258
1309
|
});
|
|
1259
1310
|
}
|
|
1260
1311
|
|
|
@@ -1752,9 +1803,13 @@ function generateBridges(memories, sensors, opts) {
|
|
|
1752
1803
|
|
|
1753
1804
|
// src/sensors.ts
|
|
1754
1805
|
function sensorPatternBrittleness(pattern) {
|
|
1755
|
-
const literal = pattern.replace(/\[[^\]]*\]/g, "").replace(/\{[^}]*\}/g, "");
|
|
1756
|
-
|
|
1757
|
-
if (
|
|
1806
|
+
const literal = pattern.replace(/\\[a-zA-Z]/g, " ").replace(/\[[^\]]*\]/g, " ").replace(/\{[^}]*\}/g, " ").replace(/\b\d{1,3}(?:\s*\\?\.\s*\d{1,3}){2,3}\b/g, " ");
|
|
1807
|
+
const range = literal.match(/\d{2,}\s*-\s*\d{2,}/);
|
|
1808
|
+
if (range) return `hardcoded line/number range "${range[0].replace(/\s+/g, "")}" \u2014 rots when code shifts`;
|
|
1809
|
+
const numeric = literal.match(/\d{3,}/);
|
|
1810
|
+
if (numeric) {
|
|
1811
|
+
return `hardcoded numeric literal "${numeric[0]}" (likely a line number) \u2014 rots when code shifts; if it is a real constant, put it in a character class ([0-9]) or anchor it to a stable token`;
|
|
1812
|
+
}
|
|
1758
1813
|
return null;
|
|
1759
1814
|
}
|
|
1760
1815
|
function normalizeProjectPath(value) {
|
|
@@ -1824,6 +1879,7 @@ function runSensors(memories, targets) {
|
|
|
1824
1879
|
for (const memory of memories) {
|
|
1825
1880
|
const sensor = memory.frontmatter.sensor;
|
|
1826
1881
|
if (!sensor || sensor.kind !== "regex") continue;
|
|
1882
|
+
if (sensor.require_present) continue;
|
|
1827
1883
|
const anchorPaths = memory.frontmatter.anchor.paths;
|
|
1828
1884
|
for (const target of targets) {
|
|
1829
1885
|
if (!sensorAppliesToPath(sensor, anchorPaths, target.path)) continue;
|
|
@@ -1833,6 +1889,47 @@ function runSensors(memories, targets) {
|
|
|
1833
1889
|
}
|
|
1834
1890
|
return hits;
|
|
1835
1891
|
}
|
|
1892
|
+
function changedPathsFromDiff(diff) {
|
|
1893
|
+
const out = /* @__PURE__ */ new Set();
|
|
1894
|
+
for (const m of diff.matchAll(/^diff --git a\/(.+?) b\/(.+)$/gm)) {
|
|
1895
|
+
out.add((m[2] ?? m[1] ?? "").trim());
|
|
1896
|
+
}
|
|
1897
|
+
for (const m of diff.matchAll(/^\+\+\+ b\/(.+)$/gm)) {
|
|
1898
|
+
const p = (m[1] ?? "").trim();
|
|
1899
|
+
if (p && p !== "/dev/null") out.add(p);
|
|
1900
|
+
}
|
|
1901
|
+
return [...out];
|
|
1902
|
+
}
|
|
1903
|
+
function runPresenceSensors(memories, finalTargets) {
|
|
1904
|
+
const hits = [];
|
|
1905
|
+
for (const memory of memories) {
|
|
1906
|
+
const sensor = memory.frontmatter.sensor;
|
|
1907
|
+
if (!sensor || sensor.kind !== "regex" || !sensor.require_present || !sensor.pattern) continue;
|
|
1908
|
+
let re;
|
|
1909
|
+
try {
|
|
1910
|
+
const flags = new Set(["m", ...(sensor.flags ?? "").split("")].filter(Boolean));
|
|
1911
|
+
re = new RegExp(sensor.pattern, [...flags].join(""));
|
|
1912
|
+
} catch {
|
|
1913
|
+
continue;
|
|
1914
|
+
}
|
|
1915
|
+
const anchorPaths = memory.frontmatter.anchor.paths;
|
|
1916
|
+
for (const target of finalTargets) {
|
|
1917
|
+
if (!sensorAppliesToPath(sensor, anchorPaths, target.path)) continue;
|
|
1918
|
+
re.lastIndex = 0;
|
|
1919
|
+
if (!re.test(target.content)) {
|
|
1920
|
+
hits.push({
|
|
1921
|
+
memory_id: memory.frontmatter.id,
|
|
1922
|
+
sensor,
|
|
1923
|
+
file: target.path,
|
|
1924
|
+
message: sensor.message,
|
|
1925
|
+
severity: sensor.severity
|
|
1926
|
+
});
|
|
1927
|
+
break;
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
return hits;
|
|
1932
|
+
}
|
|
1836
1933
|
var COMMAND_ENV_EXACT = /* @__PURE__ */ new Set([
|
|
1837
1934
|
"PATH",
|
|
1838
1935
|
"HOME",
|
|
@@ -2074,14 +2171,14 @@ function sensorSelfCheck(sensor, input) {
|
|
|
2074
2171
|
function judgeProposedSensor(sensor, input) {
|
|
2075
2172
|
const brittle = sensor.kind === "regex" && sensor.pattern ? sensorPatternBrittleness(sensor.pattern) : null;
|
|
2076
2173
|
const self_check = sensorSelfCheck(sensor, input);
|
|
2174
|
+
if (self_check.fires_on_correct === true) {
|
|
2175
|
+
return { accepted: false, reason: "fires-on-correct", self_check, brittle };
|
|
2176
|
+
}
|
|
2077
2177
|
if (sensor.severity === "block") {
|
|
2078
2178
|
if (brittle) return { accepted: false, reason: "brittle", self_check, brittle };
|
|
2079
2179
|
if (input.currentTargets.length > 0 && !self_check.silent_on_current) {
|
|
2080
2180
|
return { accepted: false, reason: "fires-on-current", self_check, brittle };
|
|
2081
2181
|
}
|
|
2082
|
-
if (self_check.fires_on_correct === true) {
|
|
2083
|
-
return { accepted: false, reason: "fires-on-correct", self_check, brittle };
|
|
2084
|
-
}
|
|
2085
2182
|
if (self_check.fires_on_bad === false) {
|
|
2086
2183
|
return { accepted: false, reason: "missed-bad-example", self_check, brittle };
|
|
2087
2184
|
}
|
|
@@ -3069,7 +3166,7 @@ function allocateBudget(parts, maxTokens) {
|
|
|
3069
3166
|
}
|
|
3070
3167
|
|
|
3071
3168
|
// src/code-map.ts
|
|
3072
|
-
import { mkdir as mkdir5, readFile as readFile7, readdir as readdir3, stat as stat2, writeFile as
|
|
3169
|
+
import { mkdir as mkdir5, readFile as readFile7, readdir as readdir3, stat as stat2, writeFile as writeFile5 } from "fs/promises";
|
|
3073
3170
|
import { createHash as createHash2 } from "crypto";
|
|
3074
3171
|
import { existsSync as existsSync7 } from "fs";
|
|
3075
3172
|
import { spawnSync } from "child_process";
|
|
@@ -3512,10 +3609,10 @@ async function saveCodeMap(paths, map) {
|
|
|
3512
3609
|
const current = existsSync7(file) ? await readFile7(file, "utf8").catch(() => null) : null;
|
|
3513
3610
|
if (current === payload) return;
|
|
3514
3611
|
await mkdir5(path9.dirname(file), { recursive: true });
|
|
3515
|
-
await
|
|
3612
|
+
await writeFile5(file, payload, "utf8");
|
|
3516
3613
|
await mkdir5(paths.runtimeDir, { recursive: true }).catch(() => {
|
|
3517
3614
|
});
|
|
3518
|
-
await
|
|
3615
|
+
await writeFile5(
|
|
3519
3616
|
codeMapMetaPath(paths),
|
|
3520
3617
|
`${JSON.stringify({ generated_at: (/* @__PURE__ */ new Date()).toISOString(), content_hash: codeMapContentHash(map) }, null, 2)}
|
|
3521
3618
|
`,
|
|
@@ -3884,7 +3981,7 @@ function queryCodeMap(map, options) {
|
|
|
3884
3981
|
// src/config.ts
|
|
3885
3982
|
import { existsSync as existsSync8 } from "fs";
|
|
3886
3983
|
import { readFileSync } from "fs";
|
|
3887
|
-
import { readFile as readFile8, rm, writeFile as
|
|
3984
|
+
import { readFile as readFile8, rm, writeFile as writeFile6 } from "fs/promises";
|
|
3888
3985
|
import path10 from "path";
|
|
3889
3986
|
var CONFIG_FILE = "hivelore.config.json";
|
|
3890
3987
|
var LEGACY_CONFIG_FILE = "haive.config.json";
|
|
@@ -4016,7 +4113,7 @@ function loadConfigSync(paths) {
|
|
|
4016
4113
|
}
|
|
4017
4114
|
}
|
|
4018
4115
|
async function saveConfig(paths, config) {
|
|
4019
|
-
await
|
|
4116
|
+
await writeFile6(configPath(paths), JSON.stringify(config, null, 2) + "\n", "utf8");
|
|
4020
4117
|
const legacy = path10.join(paths.haiveDir, LEGACY_CONFIG_FILE);
|
|
4021
4118
|
if (existsSync8(legacy)) {
|
|
4022
4119
|
try {
|
|
@@ -4042,7 +4139,7 @@ function mergeConfig(base, override) {
|
|
|
4042
4139
|
|
|
4043
4140
|
// src/cross-repo.ts
|
|
4044
4141
|
import { existsSync as existsSync9 } from "fs";
|
|
4045
|
-
import { mkdir as mkdir6, readFile as readFile9, writeFile as
|
|
4142
|
+
import { mkdir as mkdir6, readFile as readFile9, writeFile as writeFile7 } from "fs/promises";
|
|
4046
4143
|
import path11 from "path";
|
|
4047
4144
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
4048
4145
|
async function loadImportMap(cacheDir) {
|
|
@@ -4055,7 +4152,7 @@ async function loadImportMap(cacheDir) {
|
|
|
4055
4152
|
}
|
|
4056
4153
|
}
|
|
4057
4154
|
async function saveImportMap(cacheDir, map) {
|
|
4058
|
-
await
|
|
4155
|
+
await writeFile7(path11.join(cacheDir, "import-map.json"), JSON.stringify(map, null, 2) + "\n", "utf8");
|
|
4059
4156
|
}
|
|
4060
4157
|
async function pullCrossRepoSources(paths, config, projectRoot) {
|
|
4061
4158
|
const sources = config.crossRepoSources ?? [];
|
|
@@ -4141,7 +4238,7 @@ async function pullFromSource(paths, source, projectRoot) {
|
|
|
4141
4238
|
}
|
|
4142
4239
|
const updatedBody = importedBodyPrefix + memory.body;
|
|
4143
4240
|
if (existingEntry) {
|
|
4144
|
-
await
|
|
4241
|
+
await writeFile7(
|
|
4145
4242
|
existingLocalPath,
|
|
4146
4243
|
serializeMemory({ frontmatter: existingEntry.memory.frontmatter, body: updatedBody }),
|
|
4147
4244
|
"utf8"
|
|
@@ -4166,7 +4263,7 @@ async function pullFromSource(paths, source, projectRoot) {
|
|
|
4166
4263
|
});
|
|
4167
4264
|
const body = importedBodyPrefix + memory.body;
|
|
4168
4265
|
const destPath = path11.join(destDir, `${newFm.id}.md`);
|
|
4169
|
-
await
|
|
4266
|
+
await writeFile7(destPath, serializeMemory({ frontmatter: newFm, body }), "utf8");
|
|
4170
4267
|
importMap[sourceId] = destPath;
|
|
4171
4268
|
dirty = true;
|
|
4172
4269
|
report.imported.push(sourceId);
|
|
@@ -4204,7 +4301,7 @@ async function cloneOrFetchGitSource(source, paths, report) {
|
|
|
4204
4301
|
|
|
4205
4302
|
// src/dep-tracker.ts
|
|
4206
4303
|
import { existsSync as existsSync10 } from "fs";
|
|
4207
|
-
import { readFile as readFile10, writeFile as
|
|
4304
|
+
import { readFile as readFile10, writeFile as writeFile8, mkdir as mkdir7 } from "fs/promises";
|
|
4208
4305
|
import path12 from "path";
|
|
4209
4306
|
function parsePackageJson(content) {
|
|
4210
4307
|
try {
|
|
@@ -4317,7 +4414,7 @@ async function trackDependencies(projectRoot, haiveDir, manifestFiles) {
|
|
|
4317
4414
|
captured_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4318
4415
|
deps: currentDeps
|
|
4319
4416
|
};
|
|
4320
|
-
await
|
|
4417
|
+
await writeFile8(lockPath, JSON.stringify(snapshot2, null, 2) + "\n", "utf8");
|
|
4321
4418
|
continue;
|
|
4322
4419
|
}
|
|
4323
4420
|
const snapshot = JSON.parse(await readFile10(lockPath, "utf8"));
|
|
@@ -4340,7 +4437,7 @@ async function trackDependencies(projectRoot, haiveDir, manifestFiles) {
|
|
|
4340
4437
|
captured_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4341
4438
|
deps: currentDeps
|
|
4342
4439
|
};
|
|
4343
|
-
await
|
|
4440
|
+
await writeFile8(lockPath, JSON.stringify(updated, null, 2) + "\n", "utf8");
|
|
4344
4441
|
}
|
|
4345
4442
|
}
|
|
4346
4443
|
return results;
|
|
@@ -4348,7 +4445,7 @@ async function trackDependencies(projectRoot, haiveDir, manifestFiles) {
|
|
|
4348
4445
|
|
|
4349
4446
|
// src/contract-watcher.ts
|
|
4350
4447
|
import { existsSync as existsSync11 } from "fs";
|
|
4351
|
-
import { readFile as readFile11, writeFile as
|
|
4448
|
+
import { readFile as readFile11, writeFile as writeFile9, mkdir as mkdir8 } from "fs/promises";
|
|
4352
4449
|
import path13 from "path";
|
|
4353
4450
|
import crypto from "crypto";
|
|
4354
4451
|
function sha256(content) {
|
|
@@ -4571,7 +4668,7 @@ async function snapshotContract(projectRoot, haiveDir, contract) {
|
|
|
4571
4668
|
};
|
|
4572
4669
|
const contractsDir = path13.join(haiveDir, "contracts");
|
|
4573
4670
|
await mkdir8(contractsDir, { recursive: true });
|
|
4574
|
-
await
|
|
4671
|
+
await writeFile9(contractLockPath(haiveDir, contract.name), JSON.stringify(snapshot, null, 2) + "\n", "utf8");
|
|
4575
4672
|
return snapshot;
|
|
4576
4673
|
}
|
|
4577
4674
|
async function diffContract(projectRoot, haiveDir, contract) {
|
|
@@ -4595,7 +4692,7 @@ async function diffContract(projectRoot, haiveDir, contract) {
|
|
|
4595
4692
|
};
|
|
4596
4693
|
const changes = diffSnapshots(beforeSnapshot, afterSnapshot);
|
|
4597
4694
|
if (changes.length > 0) {
|
|
4598
|
-
await
|
|
4695
|
+
await writeFile9(lockPath, JSON.stringify(afterSnapshot, null, 2) + "\n", "utf8");
|
|
4599
4696
|
}
|
|
4600
4697
|
return {
|
|
4601
4698
|
contract: contract.name,
|
|
@@ -4689,7 +4786,7 @@ async function usageLogSize(paths) {
|
|
|
4689
4786
|
}
|
|
4690
4787
|
|
|
4691
4788
|
// src/friction.ts
|
|
4692
|
-
import { appendFile as appendFile3, mkdir as mkdir10, readFile as readFile13, writeFile as
|
|
4789
|
+
import { appendFile as appendFile3, mkdir as mkdir10, readFile as readFile13, writeFile as writeFile10 } from "fs/promises";
|
|
4693
4790
|
import { existsSync as existsSync13 } from "fs";
|
|
4694
4791
|
import { createHash as createHash3 } from "crypto";
|
|
4695
4792
|
import path15 from "path";
|
|
@@ -4789,7 +4886,7 @@ async function loadFrictionState(paths) {
|
|
|
4789
4886
|
}
|
|
4790
4887
|
async function saveFrictionState(paths, state) {
|
|
4791
4888
|
if (!existsSync13(paths.runtimeDir)) await mkdir10(paths.runtimeDir, { recursive: true });
|
|
4792
|
-
await
|
|
4889
|
+
await writeFile10(frictionStatePath(paths), JSON.stringify(state, null, 2) + "\n", "utf8");
|
|
4793
4890
|
}
|
|
4794
4891
|
async function setFrictionStatus(paths, fingerprint, status, url) {
|
|
4795
4892
|
const state = await loadFrictionState(paths);
|
|
@@ -5249,7 +5346,7 @@ async function readRuntimeJournalTail(paths, limit) {
|
|
|
5249
5346
|
}
|
|
5250
5347
|
|
|
5251
5348
|
// src/enforcement.ts
|
|
5252
|
-
import { mkdir as mkdir12, readdir as readdir4, readFile as readFile15, writeFile as
|
|
5349
|
+
import { mkdir as mkdir12, readdir as readdir4, readFile as readFile15, writeFile as writeFile11 } from "fs/promises";
|
|
5253
5350
|
import { existsSync as existsSync16 } from "fs";
|
|
5254
5351
|
import path18 from "path";
|
|
5255
5352
|
var BRIEFING_MARKER_TTL_MS = 12 * 60 * 60 * 1e3;
|
|
@@ -5290,7 +5387,7 @@ async function writeBriefingMarker(paths, input) {
|
|
|
5290
5387
|
root: paths.root
|
|
5291
5388
|
};
|
|
5292
5389
|
await mkdir12(briefingMarkersDir(paths), { recursive: true });
|
|
5293
|
-
await
|
|
5390
|
+
await writeFile11(
|
|
5294
5391
|
briefingMarkerPath(paths, marker.session_id),
|
|
5295
5392
|
JSON.stringify(marker, null, 2) + "\n",
|
|
5296
5393
|
"utf8"
|
|
@@ -5401,7 +5498,7 @@ function isRetiredMemory(fm, body = "", now = /* @__PURE__ */ new Date()) {
|
|
|
5401
5498
|
// src/sensor-ledger.ts
|
|
5402
5499
|
import { createHash as createHash4 } from "crypto";
|
|
5403
5500
|
import { existsSync as existsSync17, readFileSync as readFileSync2 } from "fs";
|
|
5404
|
-
import { appendFile as appendFile5, mkdir as mkdir13, readFile as readFile16, rename, writeFile as
|
|
5501
|
+
import { appendFile as appendFile5, mkdir as mkdir13, readFile as readFile16, rename, writeFile as writeFile12 } from "fs/promises";
|
|
5405
5502
|
import path19 from "path";
|
|
5406
5503
|
var MAX_LINES = 1e4;
|
|
5407
5504
|
var RETAINED_LINES = 8e3;
|
|
@@ -5424,7 +5521,7 @@ async function appendSensorEvaluations(paths, evaluations) {
|
|
|
5424
5521
|
const lines = raw.split("\n").filter(Boolean);
|
|
5425
5522
|
if (lines.length > MAX_LINES) {
|
|
5426
5523
|
const temp = `${file}.${process.pid}.tmp`;
|
|
5427
|
-
await
|
|
5524
|
+
await writeFile12(temp, lines.slice(-RETAINED_LINES).join("\n") + "\n", "utf8");
|
|
5428
5525
|
await rename(temp, file);
|
|
5429
5526
|
}
|
|
5430
5527
|
} catch {
|
|
@@ -7125,7 +7222,7 @@ ${trimmed}`;
|
|
|
7125
7222
|
}
|
|
7126
7223
|
|
|
7127
7224
|
// src/handoff.ts
|
|
7128
|
-
import { writeFile as
|
|
7225
|
+
import { writeFile as writeFile13, readFile as readFile18, stat as stat4 } from "fs/promises";
|
|
7129
7226
|
import { existsSync as existsSync19 } from "fs";
|
|
7130
7227
|
import path21 from "path";
|
|
7131
7228
|
var HANDOFF_FILENAME = "NEXT.md";
|
|
@@ -7179,7 +7276,7 @@ function buildHandoffMarkdown(data) {
|
|
|
7179
7276
|
}
|
|
7180
7277
|
async function writeSessionHandoff(root, data) {
|
|
7181
7278
|
const file = handoffFilePath(root);
|
|
7182
|
-
await
|
|
7279
|
+
await writeFile13(file, buildHandoffMarkdown(data), "utf8");
|
|
7183
7280
|
return file;
|
|
7184
7281
|
}
|
|
7185
7282
|
async function readSessionHandoff(root) {
|
|
@@ -7404,6 +7501,7 @@ export {
|
|
|
7404
7501
|
buildProposeCommand,
|
|
7405
7502
|
buildReport,
|
|
7406
7503
|
bumpRead,
|
|
7504
|
+
changedPathsFromDiff,
|
|
7407
7505
|
churnForAnchors,
|
|
7408
7506
|
classifyGithubRelease,
|
|
7409
7507
|
classifyMemoryPriority,
|
|
@@ -7589,6 +7687,7 @@ export {
|
|
|
7589
7687
|
retirementSignal,
|
|
7590
7688
|
revertedShaFromCommit,
|
|
7591
7689
|
reviewLearningsToDrafts,
|
|
7690
|
+
runPresenceSensors,
|
|
7592
7691
|
runRegexSensor,
|
|
7593
7692
|
runSensors,
|
|
7594
7693
|
runTierContract,
|