@vortex-os/base 0.12.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-T53UWSTR.js → chunk-IZIAMK3L.js} +14 -3
- package/dist/chunk-IZIAMK3L.js.map +1 -0
- package/dist/{chunk-2FVNWW77.js → chunk-JKQAB5OK.js} +3 -3
- package/dist/{chunk-EAKDR5B2.js → chunk-OFID33QA.js} +3 -3
- package/dist/chunk-OFID33QA.js.map +1 -0
- package/dist/{chunk-UV76ZEDC.js → chunk-T4TJZUPP.js} +2 -2
- package/dist/{failures-PMURLMVB.js → failures-DBXJKFYX.js} +3 -3
- package/dist/{guard-IMJR6ET7.js → guard-S6NGMDXR.js} +3 -3
- package/dist/index.d.ts +188 -55
- package/dist/index.js +434 -106
- package/dist/index.js.map +1 -1
- package/dist/{statusline-6KSHISXO.js → statusline-6BGWOOLA.js} +4 -4
- package/package.json +1 -1
- package/templates/config/vortex.json +7 -1
- package/templates/manifest.json +3 -3
- package/templates/routers/AI-RULES.md +3 -2
- package/dist/chunk-EAKDR5B2.js.map +0 -1
- package/dist/chunk-T53UWSTR.js.map +0 -1
- /package/dist/{chunk-2FVNWW77.js.map → chunk-JKQAB5OK.js.map} +0 -0
- /package/dist/{chunk-UV76ZEDC.js.map → chunk-T4TJZUPP.js.map} +0 -0
- /package/dist/{failures-PMURLMVB.js.map → failures-DBXJKFYX.js.map} +0 -0
- /package/dist/{guard-IMJR6ET7.js.map → guard-S6NGMDXR.js.map} +0 -0
- /package/dist/{statusline-6KSHISXO.js.map → statusline-6BGWOOLA.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -8,7 +8,10 @@ import {
|
|
|
8
8
|
recordGuardDenial,
|
|
9
9
|
runFailureCli,
|
|
10
10
|
scanFailures
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-T4TJZUPP.js";
|
|
12
|
+
import {
|
|
13
|
+
catchUpSessions
|
|
14
|
+
} from "./chunk-3L5DLEGP.js";
|
|
12
15
|
import {
|
|
13
16
|
SESSION_END_COMMAND,
|
|
14
17
|
SESSION_START_COMMAND,
|
|
@@ -27,7 +30,7 @@ import {
|
|
|
27
30
|
serializeSettings,
|
|
28
31
|
sniffEffortFromTranscript,
|
|
29
32
|
statuslineCommand
|
|
30
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-OFID33QA.js";
|
|
31
34
|
import {
|
|
32
35
|
GUARD_WRITE_COMMAND,
|
|
33
36
|
GUARD_WRITE_MATCHER,
|
|
@@ -37,7 +40,7 @@ import {
|
|
|
37
40
|
resolveInstanceRoot,
|
|
38
41
|
runGuardCli,
|
|
39
42
|
scanToolInput
|
|
40
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-JKQAB5OK.js";
|
|
41
44
|
import {
|
|
42
45
|
atomicWriteFile,
|
|
43
46
|
dist_exports,
|
|
@@ -50,10 +53,7 @@ import {
|
|
|
50
53
|
resolveEnvironment,
|
|
51
54
|
serializeFrontmatter,
|
|
52
55
|
validateDataRelativePath
|
|
53
|
-
} from "./chunk-
|
|
54
|
-
import {
|
|
55
|
-
catchUpSessions
|
|
56
|
-
} from "./chunk-3L5DLEGP.js";
|
|
56
|
+
} from "./chunk-IZIAMK3L.js";
|
|
57
57
|
import {
|
|
58
58
|
__export
|
|
59
59
|
} from "./chunk-PZ5AY32C.js";
|
|
@@ -4024,6 +4024,7 @@ __export(dist_exports14, {
|
|
|
4024
4024
|
agendaCommand: () => agendaCommand,
|
|
4025
4025
|
aggregateHandoff: () => aggregateHandoff,
|
|
4026
4026
|
applyGlobalSetup: () => applyGlobalSetup,
|
|
4027
|
+
archiveRelPath: () => archiveRelPath,
|
|
4027
4028
|
argvToSlash: () => argvToSlash,
|
|
4028
4029
|
autoReindexMemory: () => autoReindexMemory,
|
|
4029
4030
|
buildDenyDecision: () => buildDenyDecision,
|
|
@@ -4057,6 +4058,7 @@ __export(dist_exports14, {
|
|
|
4057
4058
|
formatTokens: () => formatTokens,
|
|
4058
4059
|
formatWindow: () => formatWindow,
|
|
4059
4060
|
gapWindowSinceArg: () => gapWindowSinceArg,
|
|
4061
|
+
gitOut: () => gitOut,
|
|
4060
4062
|
globalMemoryPath: () => globalMemoryPath,
|
|
4061
4063
|
globalSettingsHasHook: () => globalSettingsHasHook,
|
|
4062
4064
|
globalSettingsPath: () => globalSettingsPath,
|
|
@@ -4092,6 +4094,7 @@ __export(dist_exports14, {
|
|
|
4092
4094
|
repairOwnershipManifest: () => repairOwnershipManifest,
|
|
4093
4095
|
resolveInstanceRoot: () => resolveInstanceRoot,
|
|
4094
4096
|
resolveRepoRoot: () => resolveRepoRoot,
|
|
4097
|
+
runArchiveSync: () => runArchiveSync,
|
|
4095
4098
|
runCurateAccept: () => runCurateAccept,
|
|
4096
4099
|
runCurateCandidates: () => runCurateCandidates,
|
|
4097
4100
|
runCurateDecline: () => runCurateDecline,
|
|
@@ -4109,6 +4112,8 @@ __export(dist_exports14, {
|
|
|
4109
4112
|
sessionStartCommand: () => sessionStartCommand,
|
|
4110
4113
|
sniffEffortFromTranscript: () => sniffEffortFromTranscript,
|
|
4111
4114
|
statuslineCommand: () => statuslineCommand,
|
|
4115
|
+
sweepOrphanTempFiles: () => sweepOrphanTempFiles,
|
|
4116
|
+
sweepRawArchive: () => sweepRawArchive,
|
|
4112
4117
|
templateDestRelPath: () => templateDestRelPath,
|
|
4113
4118
|
upsertGlobalBlock: () => upsertGlobalBlock,
|
|
4114
4119
|
validateCuratePayload: () => validateCuratePayload,
|
|
@@ -6009,9 +6014,13 @@ async function seedInstanceConfig(repoRoot, templatesDir) {
|
|
|
6009
6014
|
decision: true,
|
|
6010
6015
|
ambientRecall: true,
|
|
6011
6016
|
archive: true,
|
|
6017
|
+
archiveCommit: true,
|
|
6018
|
+
archiveAtEnd: true,
|
|
6019
|
+
archiveRawRetentionDays: 30,
|
|
6012
6020
|
vectorize: true
|
|
6013
6021
|
},
|
|
6014
6022
|
updates: { check: "session" },
|
|
6023
|
+
sync: { autoPush: false },
|
|
6015
6024
|
environments: []
|
|
6016
6025
|
}, null, 2) + "\n", "utf8");
|
|
6017
6026
|
}
|
|
@@ -6246,10 +6255,36 @@ async function runUpdate(input, tokens) {
|
|
|
6246
6255
|
const dryRun = tokens.includes("--dry-run");
|
|
6247
6256
|
const adopt = parseAdoptArgs(tokens);
|
|
6248
6257
|
const templatesDir = resolveTemplatesDir();
|
|
6249
|
-
|
|
6258
|
+
let result = await runTemplatesUpdate(input.context, templatesDir, {
|
|
6250
6259
|
dryRun,
|
|
6251
6260
|
adopt: adopt.size > 0 ? adopt : void 0
|
|
6252
6261
|
});
|
|
6262
|
+
if (!dryRun) {
|
|
6263
|
+
try {
|
|
6264
|
+
const settingsPath = join24(input.context.repoRoot, ".claude", "settings.json");
|
|
6265
|
+
const existingText = existsSync11(settingsPath) ? await readFile21(settingsPath, "utf8") : null;
|
|
6266
|
+
const { settings, added, alreadyWired } = ensureVortexHooks(parseSettings(existingText), { guard: true });
|
|
6267
|
+
if (!alreadyWired) {
|
|
6268
|
+
await mkdir9(join24(input.context.repoRoot, ".claude"), { recursive: true });
|
|
6269
|
+
await writeFile10(settingsPath, serializeSettings(settings), "utf8");
|
|
6270
|
+
result = {
|
|
6271
|
+
...result,
|
|
6272
|
+
nextActions: [
|
|
6273
|
+
...result.nextActions,
|
|
6274
|
+
`Wired missing ${added.join(" + ")} hook(s) into .claude/settings.json` + (added.includes("PreToolUse") ? " \u2014 the write guard now denies literal control bytes in file writes (remove the PreToolUse group to opt out)." : ".")
|
|
6275
|
+
]
|
|
6276
|
+
};
|
|
6277
|
+
}
|
|
6278
|
+
} catch (e) {
|
|
6279
|
+
result = {
|
|
6280
|
+
...result,
|
|
6281
|
+
nextActions: [
|
|
6282
|
+
...result.nextActions,
|
|
6283
|
+
`\u26A0\uFE0F Could not verify/wire session hooks: ${e.message}`
|
|
6284
|
+
]
|
|
6285
|
+
};
|
|
6286
|
+
}
|
|
6287
|
+
}
|
|
6253
6288
|
if (dryRun || result.status === "no-manifest" || result.status === "no-templates")
|
|
6254
6289
|
return result;
|
|
6255
6290
|
if (!loadVortexConfig(input.context).autoRecord.commitFrameworkChanges)
|
|
@@ -7585,23 +7620,280 @@ function createRitualRegistry(options) {
|
|
|
7585
7620
|
}
|
|
7586
7621
|
|
|
7587
7622
|
// ../plugins/session-rituals/dist/cli-dispatch.js
|
|
7588
|
-
import {
|
|
7589
|
-
import { existsSync as
|
|
7623
|
+
import { spawn as spawn2 } from "child_process";
|
|
7624
|
+
import { existsSync as existsSync16, readFileSync as readFileSync4, mkdirSync as mkdirSync2, openSync as openSync2, writeSync as writeSync2, closeSync as closeSync2, linkSync, rmSync as rmSync2, statSync as statSync2 } from "fs";
|
|
7590
7625
|
import { createRequire } from "module";
|
|
7591
7626
|
import { hostname } from "os";
|
|
7592
|
-
import {
|
|
7627
|
+
import { join as join29 } from "path";
|
|
7628
|
+
|
|
7629
|
+
// ../plugins/session-rituals/dist/archive-sync.js
|
|
7630
|
+
import { closeSync, existsSync as existsSync12, mkdirSync, openSync, readdirSync, readFileSync as readFileSync2, renameSync, rmSync, statSync, writeSync } from "fs";
|
|
7631
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
7632
|
+
import { isAbsolute as isAbsolute4, join as join25, relative as relative5, sep as sep4 } from "path";
|
|
7633
|
+
function gitOut(cwd, gitArgs) {
|
|
7634
|
+
return execFileSync2("git", [...gitArgs], {
|
|
7635
|
+
cwd,
|
|
7636
|
+
encoding: "utf8",
|
|
7637
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
7638
|
+
});
|
|
7639
|
+
}
|
|
7640
|
+
function detectInterruptedGitOp(repoRoot) {
|
|
7641
|
+
const markers = [
|
|
7642
|
+
"MERGE_HEAD",
|
|
7643
|
+
"rebase-merge",
|
|
7644
|
+
"rebase-apply",
|
|
7645
|
+
"CHERRY_PICK_HEAD",
|
|
7646
|
+
"REVERT_HEAD",
|
|
7647
|
+
"BISECT_LOG",
|
|
7648
|
+
"index.lock"
|
|
7649
|
+
];
|
|
7650
|
+
try {
|
|
7651
|
+
const args = ["rev-parse", ...markers.flatMap((m2) => ["--git-path", m2])];
|
|
7652
|
+
const resolved = gitOut(repoRoot, args).split(/\r?\n/).map((s) => s.trim());
|
|
7653
|
+
for (let i = 0; i < markers.length; i++) {
|
|
7654
|
+
const p = resolved[i];
|
|
7655
|
+
if (p && existsSync12(isAbsolute4(p) ? p : join25(repoRoot, p)))
|
|
7656
|
+
return markers[i];
|
|
7657
|
+
}
|
|
7658
|
+
} catch {
|
|
7659
|
+
}
|
|
7660
|
+
return null;
|
|
7661
|
+
}
|
|
7662
|
+
var NOTHING = {
|
|
7663
|
+
ran: false,
|
|
7664
|
+
lockSkipped: false,
|
|
7665
|
+
catchUp: null,
|
|
7666
|
+
rawPruned: 0,
|
|
7667
|
+
retentionDays: 0,
|
|
7668
|
+
committed: false,
|
|
7669
|
+
pushed: false
|
|
7670
|
+
};
|
|
7671
|
+
var ARCHIVE_SYNC_LOCK_TTL_MS = 10 * 60 * 1e3;
|
|
7672
|
+
function lockPath(dataDir) {
|
|
7673
|
+
return join25(dataDir, "_session-archive", ".sync.lock");
|
|
7674
|
+
}
|
|
7675
|
+
function archiveRelPath(ctx) {
|
|
7676
|
+
return relative5(ctx.repoRoot, join25(ctx.dataDir, "_session-archive")).split(sep4).join("/");
|
|
7677
|
+
}
|
|
7678
|
+
function sweepRawArchive(dataDir, retentionDays, nowMs = Date.now()) {
|
|
7679
|
+
if (!(retentionDays > 0))
|
|
7680
|
+
return 0;
|
|
7681
|
+
const rawDir = join25(dataDir, "_session-archive", "raw");
|
|
7682
|
+
const cutoff = nowMs - retentionDays * 864e5;
|
|
7683
|
+
let pruned = 0;
|
|
7684
|
+
const walk5 = (dir) => {
|
|
7685
|
+
let entries;
|
|
7686
|
+
try {
|
|
7687
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
7688
|
+
} catch {
|
|
7689
|
+
return;
|
|
7690
|
+
}
|
|
7691
|
+
for (const e of entries) {
|
|
7692
|
+
const p = join25(dir, e.name);
|
|
7693
|
+
if (e.isDirectory()) {
|
|
7694
|
+
walk5(p);
|
|
7695
|
+
} else if (e.isFile()) {
|
|
7696
|
+
try {
|
|
7697
|
+
if (statSync(p).mtimeMs < cutoff) {
|
|
7698
|
+
rmSync(p, { force: true });
|
|
7699
|
+
pruned++;
|
|
7700
|
+
}
|
|
7701
|
+
} catch {
|
|
7702
|
+
}
|
|
7703
|
+
}
|
|
7704
|
+
}
|
|
7705
|
+
};
|
|
7706
|
+
walk5(rawDir);
|
|
7707
|
+
return pruned;
|
|
7708
|
+
}
|
|
7709
|
+
function sweepOrphanTempFiles(dataDir, nowMs = Date.now()) {
|
|
7710
|
+
let removed = 0;
|
|
7711
|
+
const sweep = (dir, recurse, minAgeMs) => {
|
|
7712
|
+
let entries;
|
|
7713
|
+
try {
|
|
7714
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
7715
|
+
} catch {
|
|
7716
|
+
return;
|
|
7717
|
+
}
|
|
7718
|
+
for (const e of entries) {
|
|
7719
|
+
const p = join25(dir, e.name);
|
|
7720
|
+
if (e.isDirectory()) {
|
|
7721
|
+
if (recurse)
|
|
7722
|
+
sweep(p, recurse, minAgeMs);
|
|
7723
|
+
} else if (e.isFile() && /\.tmp-\d+$/.test(e.name)) {
|
|
7724
|
+
try {
|
|
7725
|
+
if (minAgeMs === 0 || nowMs - statSync(p).mtimeMs >= minAgeMs) {
|
|
7726
|
+
rmSync(p, { force: true });
|
|
7727
|
+
removed++;
|
|
7728
|
+
}
|
|
7729
|
+
} catch {
|
|
7730
|
+
}
|
|
7731
|
+
}
|
|
7732
|
+
}
|
|
7733
|
+
};
|
|
7734
|
+
sweep(join25(dataDir, "_session-archive", "raw"), true, 0);
|
|
7735
|
+
sweep(join25(dataDir, "_session-archive", "normalized"), true, 0);
|
|
7736
|
+
sweep(join25(dataDir, "_session-archive", ".tmp"), false, ARCHIVE_SYNC_LOCK_TTL_MS);
|
|
7737
|
+
return removed;
|
|
7738
|
+
}
|
|
7739
|
+
function isDetachedHead(repoRoot) {
|
|
7740
|
+
try {
|
|
7741
|
+
gitOut(repoRoot, ["symbolic-ref", "-q", "HEAD"]);
|
|
7742
|
+
return false;
|
|
7743
|
+
} catch {
|
|
7744
|
+
return true;
|
|
7745
|
+
}
|
|
7746
|
+
}
|
|
7747
|
+
function pushCurrentBranch(repoRoot) {
|
|
7748
|
+
try {
|
|
7749
|
+
if (!gitOut(repoRoot, ["remote"]).trim())
|
|
7750
|
+
return { pushed: false, skip: "no-remote" };
|
|
7751
|
+
} catch {
|
|
7752
|
+
return { pushed: false, skip: "git-error" };
|
|
7753
|
+
}
|
|
7754
|
+
try {
|
|
7755
|
+
gitOut(repoRoot, ["rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{upstream}"]);
|
|
7756
|
+
} catch {
|
|
7757
|
+
return { pushed: false, skip: "no-upstream" };
|
|
7758
|
+
}
|
|
7759
|
+
const counts = () => {
|
|
7760
|
+
const [a, b2] = gitOut(repoRoot, ["rev-list", "--left-right", "--count", "HEAD...@{upstream}"]).trim().split(/\s+/);
|
|
7761
|
+
return { ahead: Number(a ?? 0) || 0, behind: Number(b2 ?? 0) || 0 };
|
|
7762
|
+
};
|
|
7763
|
+
try {
|
|
7764
|
+
let { ahead, behind } = counts();
|
|
7765
|
+
if (behind > 0) {
|
|
7766
|
+
try {
|
|
7767
|
+
gitOut(repoRoot, ["pull", "--ff-only"]);
|
|
7768
|
+
} catch {
|
|
7769
|
+
return { pushed: false, skip: "diverged" };
|
|
7770
|
+
}
|
|
7771
|
+
({ ahead, behind } = counts());
|
|
7772
|
+
}
|
|
7773
|
+
if (ahead === 0)
|
|
7774
|
+
return { pushed: false, skip: "no-commit" };
|
|
7775
|
+
gitOut(repoRoot, ["push"]);
|
|
7776
|
+
return { pushed: true };
|
|
7777
|
+
} catch {
|
|
7778
|
+
return { pushed: false, skip: "git-error" };
|
|
7779
|
+
}
|
|
7780
|
+
}
|
|
7781
|
+
async function runArchiveSync(ctx, config, _phase, opts) {
|
|
7782
|
+
const lock = lockPath(ctx.dataDir);
|
|
7783
|
+
const token = `${process.pid}-${process.hrtime.bigint()}`;
|
|
7784
|
+
let lockFd;
|
|
7785
|
+
try {
|
|
7786
|
+
mkdirSync(join25(ctx.dataDir, "_session-archive"), { recursive: true });
|
|
7787
|
+
lockFd = openSync(lock, "wx");
|
|
7788
|
+
} catch (e) {
|
|
7789
|
+
if (e.code !== "EEXIST") {
|
|
7790
|
+
return { ...NOTHING, lockSkipped: true };
|
|
7791
|
+
}
|
|
7792
|
+
let stale = true;
|
|
7793
|
+
try {
|
|
7794
|
+
stale = Date.now() - statSync(lock).mtimeMs >= ARCHIVE_SYNC_LOCK_TTL_MS;
|
|
7795
|
+
} catch {
|
|
7796
|
+
stale = true;
|
|
7797
|
+
}
|
|
7798
|
+
if (!stale)
|
|
7799
|
+
return { ...NOTHING, lockSkipped: true };
|
|
7800
|
+
const claimed = `${lock}.stale-${process.pid}`;
|
|
7801
|
+
try {
|
|
7802
|
+
renameSync(lock, claimed);
|
|
7803
|
+
rmSync(claimed, { force: true });
|
|
7804
|
+
} catch {
|
|
7805
|
+
return { ...NOTHING, lockSkipped: true };
|
|
7806
|
+
}
|
|
7807
|
+
try {
|
|
7808
|
+
lockFd = openSync(lock, "wx");
|
|
7809
|
+
} catch {
|
|
7810
|
+
return { ...NOTHING, lockSkipped: true };
|
|
7811
|
+
}
|
|
7812
|
+
}
|
|
7813
|
+
let tokenWritten = false;
|
|
7814
|
+
const releaseLock = () => {
|
|
7815
|
+
try {
|
|
7816
|
+
const cur = existsSync12(lock) ? readFileSync2(lock, "utf8").trim() : "";
|
|
7817
|
+
if (cur === token || cur === "" && !tokenWritten)
|
|
7818
|
+
rmSync(lock, { force: true });
|
|
7819
|
+
} catch {
|
|
7820
|
+
}
|
|
7821
|
+
};
|
|
7822
|
+
try {
|
|
7823
|
+
try {
|
|
7824
|
+
writeSync(lockFd, token + "\n");
|
|
7825
|
+
tokenWritten = true;
|
|
7826
|
+
} finally {
|
|
7827
|
+
closeSync(lockFd);
|
|
7828
|
+
}
|
|
7829
|
+
let catchUp = null;
|
|
7830
|
+
try {
|
|
7831
|
+
const { catchUpSessions: catchUpSessions2 } = await import("./catch-up-GDDKPZHJ.js");
|
|
7832
|
+
catchUp = await catchUpSessions2(ctx, opts?.catchUp);
|
|
7833
|
+
} catch {
|
|
7834
|
+
}
|
|
7835
|
+
const retentionDays = config.autoRecord.archiveRawRetentionDays;
|
|
7836
|
+
let rawPruned = 0;
|
|
7837
|
+
try {
|
|
7838
|
+
rawPruned = sweepRawArchive(ctx.dataDir, retentionDays);
|
|
7839
|
+
} catch {
|
|
7840
|
+
}
|
|
7841
|
+
try {
|
|
7842
|
+
sweepOrphanTempFiles(ctx.dataDir);
|
|
7843
|
+
} catch {
|
|
7844
|
+
}
|
|
7845
|
+
let committed = false;
|
|
7846
|
+
let commitSkipped;
|
|
7847
|
+
if (!config.autoRecord.archiveCommit) {
|
|
7848
|
+
commitSkipped = "off";
|
|
7849
|
+
} else if (detectInterruptedGitOp(ctx.repoRoot)) {
|
|
7850
|
+
commitSkipped = "git-busy";
|
|
7851
|
+
} else if (isDetachedHead(ctx.repoRoot)) {
|
|
7852
|
+
commitSkipped = "detached-head";
|
|
7853
|
+
} else {
|
|
7854
|
+
const rel = archiveRelPath(ctx);
|
|
7855
|
+
const paths = [`${rel}/raw`, `${rel}/normalized`].filter((p) => existsSync12(join25(ctx.repoRoot, ...p.split("/"))));
|
|
7856
|
+
const ingested = catchUp?.ingestedLocal ?? 0;
|
|
7857
|
+
const result = commitFrameworkPaths(ctx.repoRoot, paths, `chore(vortex): session archive sync (${ingested} ingested, ${rawPruned} raw pruned)`);
|
|
7858
|
+
committed = result.committed;
|
|
7859
|
+
if (!result.committed) {
|
|
7860
|
+
commitSkipped = result.reason === "nothing-to-commit" || result.reason === "no-paths" ? "nothing-to-commit" : result.reason === "not-a-git-repo" ? "not-a-git-repo" : "git-error";
|
|
7861
|
+
}
|
|
7862
|
+
}
|
|
7863
|
+
let pushed = false;
|
|
7864
|
+
let pushSkipped;
|
|
7865
|
+
if (!config.sync.autoPush) {
|
|
7866
|
+
pushSkipped = "off";
|
|
7867
|
+
} else {
|
|
7868
|
+
({ pushed, skip: pushSkipped } = pushCurrentBranch(ctx.repoRoot));
|
|
7869
|
+
}
|
|
7870
|
+
return {
|
|
7871
|
+
ran: true,
|
|
7872
|
+
lockSkipped: false,
|
|
7873
|
+
catchUp,
|
|
7874
|
+
rawPruned,
|
|
7875
|
+
retentionDays,
|
|
7876
|
+
committed,
|
|
7877
|
+
...commitSkipped !== void 0 ? { commitSkipped } : {},
|
|
7878
|
+
pushed,
|
|
7879
|
+
...pushSkipped !== void 0 ? { pushSkipped } : {}
|
|
7880
|
+
};
|
|
7881
|
+
} finally {
|
|
7882
|
+
releaseLock();
|
|
7883
|
+
}
|
|
7884
|
+
}
|
|
7593
7885
|
|
|
7594
7886
|
// ../plugins/session-rituals/dist/update-check.js
|
|
7595
7887
|
import { execSync } from "child_process";
|
|
7596
|
-
import { existsSync as
|
|
7597
|
-
import { join as
|
|
7888
|
+
import { existsSync as existsSync13, readFileSync as readFileSync3 } from "fs";
|
|
7889
|
+
import { join as join26 } from "path";
|
|
7598
7890
|
var PKG = "@vortex-os/base";
|
|
7599
7891
|
var NPM_TIMEOUT_MS = 4e3;
|
|
7600
7892
|
function readInstalledBaseVersion(templatesDir = resolveTemplatesDir()) {
|
|
7601
7893
|
if (!templatesDir)
|
|
7602
7894
|
return null;
|
|
7603
7895
|
try {
|
|
7604
|
-
const m2 = JSON.parse(
|
|
7896
|
+
const m2 = JSON.parse(readFileSync3(join26(templatesDir, "manifest.json"), "utf8"));
|
|
7605
7897
|
return typeof m2.baseVersion === "string" && parseCore(m2.baseVersion) ? m2.baseVersion.trim() : null;
|
|
7606
7898
|
} catch {
|
|
7607
7899
|
return null;
|
|
@@ -7673,8 +7965,8 @@ function isStableUpdate(latest, installed) {
|
|
|
7673
7965
|
return compareSemver(latest, installed) === 1;
|
|
7674
7966
|
}
|
|
7675
7967
|
function buildInstallCommand(repoRoot) {
|
|
7676
|
-
const has = (f) =>
|
|
7677
|
-
const local =
|
|
7968
|
+
const has = (f) => existsSync13(join26(repoRoot, f));
|
|
7969
|
+
const local = existsSync13(join26(repoRoot, "node_modules", "@vortex-os", "base"));
|
|
7678
7970
|
let installPart;
|
|
7679
7971
|
if (!local) {
|
|
7680
7972
|
installPart = `npm i -g ${PKG}@latest`;
|
|
@@ -7702,9 +7994,9 @@ function checkBaseUpdate(ctx) {
|
|
|
7702
7994
|
}
|
|
7703
7995
|
|
|
7704
7996
|
// ../plugins/session-rituals/dist/session-start-report.js
|
|
7705
|
-
import { existsSync as
|
|
7997
|
+
import { existsSync as existsSync14 } from "fs";
|
|
7706
7998
|
import { readdir as readdir17, readFile as readFile22, stat as stat9 } from "fs/promises";
|
|
7707
|
-
import { join as
|
|
7999
|
+
import { join as join27 } from "path";
|
|
7708
8000
|
var COUNTED_DIRS2 = ["_memory", "worklog", "decision-log"];
|
|
7709
8001
|
var DEFAULT_GAP_WINDOW_DAYS = 30;
|
|
7710
8002
|
function gapWindowSinceArg() {
|
|
@@ -7721,8 +8013,8 @@ async function collectSessionStartReport(ctx, opts) {
|
|
|
7721
8013
|
const counts = {};
|
|
7722
8014
|
const missing = [];
|
|
7723
8015
|
for (const name of COUNTED_DIRS2) {
|
|
7724
|
-
const dir =
|
|
7725
|
-
if (!
|
|
8016
|
+
const dir = join27(ctx.dataDir, name);
|
|
8017
|
+
if (!existsSync14(dir)) {
|
|
7726
8018
|
missing.push(name);
|
|
7727
8019
|
counts[name] = 0;
|
|
7728
8020
|
continue;
|
|
@@ -7732,7 +8024,7 @@ async function collectSessionStartReport(ctx, opts) {
|
|
|
7732
8024
|
const { recent, recentGroup, recentWorklogsOmitted, dates, latestBodies } = await scanWorklog(ctx.dataDir);
|
|
7733
8025
|
const cutoff = isoDate2(addDays2(now, -(opts?.gapWindowDays ?? DEFAULT_GAP_WINDOW_DAYS)));
|
|
7734
8026
|
const recentWorklogDates = dates.filter((d2) => d2 >= cutoff);
|
|
7735
|
-
const mem = await scanMemoryTiers(
|
|
8027
|
+
const mem = await scanMemoryTiers(join27(ctx.dataDir, "_memory"));
|
|
7736
8028
|
const ho = await scanHandoffs(ctx.dataDir);
|
|
7737
8029
|
const handoffs = ho.active.map((h) => ({
|
|
7738
8030
|
date: h.date,
|
|
@@ -7799,7 +8091,7 @@ async function scanMemoryTiers(memoryDir) {
|
|
|
7799
8091
|
for (const e of entries) {
|
|
7800
8092
|
if (!e.isFile() || !e.name.endsWith(".md"))
|
|
7801
8093
|
continue;
|
|
7802
|
-
const full =
|
|
8094
|
+
const full = join27(memoryDir, e.name);
|
|
7803
8095
|
if (e.name === "_INDEX.md") {
|
|
7804
8096
|
indexExists = true;
|
|
7805
8097
|
try {
|
|
@@ -7970,6 +8262,7 @@ function renderSessionStartReport(report, extras) {
|
|
|
7970
8262
|
lines.push(` - \u2026(+${fl.omitted} more \u2014 \`vortex failure list\`)`);
|
|
7971
8263
|
}
|
|
7972
8264
|
const cu = extras?.catchUp;
|
|
8265
|
+
const as = extras?.archiveSync;
|
|
7973
8266
|
if (cu && (cu.ingestedLocal > 0 || cu.indexedPulled > 0 || cu.errors > 0)) {
|
|
7974
8267
|
const parts = [];
|
|
7975
8268
|
if (cu.ingestedLocal > 0)
|
|
@@ -7978,9 +8271,19 @@ function renderSessionStartReport(report, extras) {
|
|
|
7978
8271
|
parts.push(`${cu.indexedPulled} pulled`);
|
|
7979
8272
|
const n = cu.ingestedLocal + cu.indexedPulled;
|
|
7980
8273
|
let line = `- caught up: archived ${parts.join(" + ")} conversation${n === 1 ? "" : "s"}`;
|
|
8274
|
+
if (as?.committed)
|
|
8275
|
+
line += as.pushed ? " \xB7 committed & pushed" : " \xB7 committed";
|
|
7981
8276
|
if (cu.errors > 0)
|
|
7982
8277
|
line += ` (${cu.errors} error${cu.errors === 1 ? "" : "s"})`;
|
|
7983
8278
|
lines.push(line);
|
|
8279
|
+
} else if (as?.committed) {
|
|
8280
|
+
lines.push(`- archive: changes committed${as.pushed ? " & pushed" : ""}`);
|
|
8281
|
+
}
|
|
8282
|
+
if (as && as.rawPruned > 0) {
|
|
8283
|
+
lines.push(`- \u{1F9F9} archive: removed ${as.rawPruned} raw transcript cop${as.rawPruned === 1 ? "y" : "ies"} older than ${as.retentionDays}d (local duplicates; the normalized archive keeps everything)`);
|
|
8284
|
+
}
|
|
8285
|
+
if (as && !as.pushed && as.pushSkipped && as.pushSkipped !== "off" && as.pushSkipped !== "no-commit") {
|
|
8286
|
+
lines.push(`- \u26A0\uFE0F auto-push is on but could not push (${as.pushSkipped}) \u2014 push manually or check the remote.`);
|
|
7984
8287
|
}
|
|
7985
8288
|
const vec = extras?.vectorized;
|
|
7986
8289
|
if (vec && vec.sessionChunks > 0) {
|
|
@@ -8038,15 +8341,15 @@ async function countMarkdown3(dir, recursive) {
|
|
|
8038
8341
|
} else if (e.isDirectory() && recursive) {
|
|
8039
8342
|
if (e.name.startsWith(".") || e.name.startsWith("_"))
|
|
8040
8343
|
continue;
|
|
8041
|
-
total += await countMarkdown3(
|
|
8344
|
+
total += await countMarkdown3(join27(dir, e.name), recursive);
|
|
8042
8345
|
}
|
|
8043
8346
|
}
|
|
8044
8347
|
return total;
|
|
8045
8348
|
}
|
|
8046
8349
|
var MAX_GROUP_READ = 20;
|
|
8047
8350
|
async function scanWorklog(dataDir) {
|
|
8048
|
-
const root =
|
|
8049
|
-
if (!
|
|
8351
|
+
const root = join27(dataDir, "worklog");
|
|
8352
|
+
if (!existsSync14(root))
|
|
8050
8353
|
return { recent: null, recentGroup: [], recentWorklogsOmitted: 0, dates: [], latestBodies: [] };
|
|
8051
8354
|
const dates = /* @__PURE__ */ new Set();
|
|
8052
8355
|
const consistent = [];
|
|
@@ -8061,7 +8364,7 @@ async function scanWorklog(dataDir) {
|
|
|
8061
8364
|
for (const e of entries) {
|
|
8062
8365
|
const childRel = rel ? `${rel}/${e.name}` : e.name;
|
|
8063
8366
|
if (e.isDirectory()) {
|
|
8064
|
-
await walk5(
|
|
8367
|
+
await walk5(join27(absDir, e.name), childRel);
|
|
8065
8368
|
} else if (e.isFile()) {
|
|
8066
8369
|
const m2 = e.name.match(/^(\d{4})-(\d{2})-(\d{2})(?:_\d{4})?-.+\.md$/);
|
|
8067
8370
|
if (!m2)
|
|
@@ -8090,7 +8393,7 @@ async function scanWorklog(dataDir) {
|
|
|
8090
8393
|
const recentGroup = [];
|
|
8091
8394
|
const latestBodies = [];
|
|
8092
8395
|
for (const g of group) {
|
|
8093
|
-
const { title, body } = await readWorklogTitleAndBody(
|
|
8396
|
+
const { title, body } = await readWorklogTitleAndBody(join27(root, g.rel));
|
|
8094
8397
|
recentGroup.push({ path: defangReportPath(`worklog/${g.rel}`), title });
|
|
8095
8398
|
latestBodies.push(body);
|
|
8096
8399
|
}
|
|
@@ -8169,10 +8472,10 @@ function isoDate2(d2) {
|
|
|
8169
8472
|
}
|
|
8170
8473
|
|
|
8171
8474
|
// ../plugins/session-rituals/dist/curate-cli.js
|
|
8172
|
-
import { existsSync as
|
|
8475
|
+
import { existsSync as existsSync15 } from "fs";
|
|
8173
8476
|
import { createHash as createHash3 } from "crypto";
|
|
8174
8477
|
import { readFile as readFile23, readdir as readdir18 } from "fs/promises";
|
|
8175
|
-
import { join as
|
|
8478
|
+
import { join as join28 } from "path";
|
|
8176
8479
|
var SYSTEM_META_DIRS2 = /* @__PURE__ */ new Set([
|
|
8177
8480
|
"worklog",
|
|
8178
8481
|
"decision-log",
|
|
@@ -8252,10 +8555,10 @@ function joinRel(...parts) {
|
|
|
8252
8555
|
}
|
|
8253
8556
|
async function runCurateCandidates(repoRoot, options) {
|
|
8254
8557
|
const maxEntries = options?.maxEntries ?? 200;
|
|
8255
|
-
const dataDir =
|
|
8558
|
+
const dataDir = join28(repoRoot, "data");
|
|
8256
8559
|
const candidates = [];
|
|
8257
8560
|
let truncated = false;
|
|
8258
|
-
if (
|
|
8561
|
+
if (existsSync15(dataDir)) {
|
|
8259
8562
|
async function visit(absDir, relDir) {
|
|
8260
8563
|
if (candidates.length >= maxEntries) {
|
|
8261
8564
|
truncated = true;
|
|
@@ -8278,7 +8581,7 @@ async function runCurateCandidates(repoRoot, options) {
|
|
|
8278
8581
|
continue;
|
|
8279
8582
|
if (atRoot && (SYSTEM_META_DIRS2.has(e.name) || e.name.startsWith("_")))
|
|
8280
8583
|
continue;
|
|
8281
|
-
await visit(
|
|
8584
|
+
await visit(join28(absDir, e.name), joinRel(relDir, e.name));
|
|
8282
8585
|
} else if (e.isFile() && e.name.endsWith(".md")) {
|
|
8283
8586
|
if (NON_DOC_FILES.has(e.name))
|
|
8284
8587
|
continue;
|
|
@@ -8287,7 +8590,7 @@ async function runCurateCandidates(repoRoot, options) {
|
|
|
8287
8590
|
let topic = null;
|
|
8288
8591
|
let tags = [];
|
|
8289
8592
|
try {
|
|
8290
|
-
const raw = await readFile23(
|
|
8593
|
+
const raw = await readFile23(join28(absDir, e.name), "utf8");
|
|
8291
8594
|
const parsed = parseFrontmatter(raw);
|
|
8292
8595
|
if (typeof parsed.frontmatter.topic === "string") {
|
|
8293
8596
|
topic = parsed.frontmatter.topic.trim().toLowerCase();
|
|
@@ -8325,7 +8628,7 @@ async function runCuratePreview(repoRoot, payload, now = /* @__PURE__ */ new Dat
|
|
|
8325
8628
|
};
|
|
8326
8629
|
}
|
|
8327
8630
|
try {
|
|
8328
|
-
validateDataRelativePath(
|
|
8631
|
+
validateDataRelativePath(join28(repoRoot, "data"), v2.effectiveRelPath);
|
|
8329
8632
|
} catch (e) {
|
|
8330
8633
|
return {
|
|
8331
8634
|
subcommand: "curate-preview",
|
|
@@ -8342,10 +8645,10 @@ async function runCuratePreview(repoRoot, payload, now = /* @__PURE__ */ new Dat
|
|
|
8342
8645
|
let targetExists;
|
|
8343
8646
|
let wouldDo;
|
|
8344
8647
|
if (payload.action === "create-file") {
|
|
8345
|
-
targetExists =
|
|
8648
|
+
targetExists = existsSync15(join28(repoRoot, "data", v2.effectiveRelPath));
|
|
8346
8649
|
wouldDo = targetExists ? `create-file at ${v2.effectiveRelPath} \u2014 but the file already EXISTS, so accept would REFUSE (no overwrite).` : `create a new document at data/${v2.effectiveRelPath}.`;
|
|
8347
8650
|
} else {
|
|
8348
|
-
targetExists =
|
|
8651
|
+
targetExists = existsSync15(join28(repoRoot, "data", v2.effectiveRelPath));
|
|
8349
8652
|
wouldDo = targetExists ? `append a "## ${payload.sectionHeader}" section to data/${v2.effectiveRelPath}.` : `append-section to data/${v2.effectiveRelPath} \u2014 but the file does NOT exist, so accept would FAIL (append-section never creates).`;
|
|
8350
8653
|
}
|
|
8351
8654
|
const nextActions = [];
|
|
@@ -8490,13 +8793,13 @@ function readCuratePayload(args) {
|
|
|
8490
8793
|
break;
|
|
8491
8794
|
}
|
|
8492
8795
|
if (t === "--payload-file" && i + 1 < args.length) {
|
|
8493
|
-
raw =
|
|
8796
|
+
raw = readFileSync4(args[++i], "utf8");
|
|
8494
8797
|
break;
|
|
8495
8798
|
}
|
|
8496
8799
|
}
|
|
8497
8800
|
if (raw === null) {
|
|
8498
8801
|
try {
|
|
8499
|
-
raw =
|
|
8802
|
+
raw = readFileSync4(0, "utf8");
|
|
8500
8803
|
} catch {
|
|
8501
8804
|
raw = "";
|
|
8502
8805
|
}
|
|
@@ -8520,18 +8823,18 @@ async function runVortexCli(argv, io) {
|
|
|
8520
8823
|
const err = io?.stderr ?? ((s) => process.stderr.write(s));
|
|
8521
8824
|
try {
|
|
8522
8825
|
if (argv[0] === "statusline") {
|
|
8523
|
-
const { runStatuslineCli: runStatuslineCli2 } = await import("./statusline-
|
|
8826
|
+
const { runStatuslineCli: runStatuslineCli2 } = await import("./statusline-6BGWOOLA.js");
|
|
8524
8827
|
const statuslineRoot = process.env.VORTEX_REPO_ROOT?.trim() || process.cwd();
|
|
8525
8828
|
return runStatuslineCli2(argv.slice(1), statuslineRoot, out, err);
|
|
8526
8829
|
}
|
|
8527
8830
|
if (argv[0] === "guard") {
|
|
8528
|
-
const { runGuardCli: runGuardCli2 } = await import("./guard-
|
|
8831
|
+
const { runGuardCli: runGuardCli2 } = await import("./guard-S6NGMDXR.js");
|
|
8529
8832
|
return runGuardCli2(argv.slice(1), out, err);
|
|
8530
8833
|
}
|
|
8531
8834
|
const repoRoot = resolveRepoRoot();
|
|
8532
8835
|
if (argv[0] === "failure") {
|
|
8533
|
-
const { runFailureCli: runFailureCli2 } = await import("./failures-
|
|
8534
|
-
const { resolveInstanceRoot: resolveInstanceRoot2 } = await import("./guard-
|
|
8836
|
+
const { runFailureCli: runFailureCli2 } = await import("./failures-DBXJKFYX.js");
|
|
8837
|
+
const { resolveInstanceRoot: resolveInstanceRoot2 } = await import("./guard-S6NGMDXR.js");
|
|
8535
8838
|
const root = resolveInstanceRoot2(process.cwd()) ?? repoRoot;
|
|
8536
8839
|
const ctx = makeContext(root);
|
|
8537
8840
|
return runFailureCli2(argv.slice(1), ctx.dataDir, out, err);
|
|
@@ -8544,6 +8847,10 @@ async function runVortexCli(argv, io) {
|
|
|
8544
8847
|
await runSessionEnd(repoRoot, out);
|
|
8545
8848
|
return 0;
|
|
8546
8849
|
}
|
|
8850
|
+
if (argv[0] === "catch-up") {
|
|
8851
|
+
await runCatchUpCli(repoRoot, out);
|
|
8852
|
+
return 0;
|
|
8853
|
+
}
|
|
8547
8854
|
if (argv[0] === "check-updates") {
|
|
8548
8855
|
const result2 = checkBaseUpdate(makeContext(repoRoot));
|
|
8549
8856
|
out(JSON.stringify(result2, null, 2) + "\n");
|
|
@@ -8571,8 +8878,9 @@ async function runVortexCli(argv, io) {
|
|
|
8571
8878
|
|
|
8572
8879
|
Commands:
|
|
8573
8880
|
${names}
|
|
8574
|
-
session-start \u2014 emit the start-of-session boot report (git pull + data counts +
|
|
8575
|
-
session-end \u2014
|
|
8881
|
+
session-start \u2014 emit the start-of-session boot report (git pull + data counts + archive sync)
|
|
8882
|
+
session-end \u2014 best-effort archive sync at wind-down (ingest closed sessions + auto-commit; crash-safe \u2014 session-start repeats it)
|
|
8883
|
+
catch-up \u2014 explicit archive sync now (ingest closed sessions, sweep raw copies, auto-commit, opt-in push); run before a manual sync
|
|
8576
8884
|
check-updates \u2014 check the npm registry for a newer @vortex-os/base (read-only; prints the exact update command)
|
|
8577
8885
|
statusline \u2014 render the Claude Code status bar from stdin JSON (\`lite\` for 1-line; \`install [--lite]\` wires .claude/settings.json)
|
|
8578
8886
|
failure \u2014 failure ledger (\`record\` an occurrence by recurrence key / \`list\` open groups with their escalation stage)
|
|
@@ -8643,14 +8951,14 @@ function memoryExtendedPresent() {
|
|
|
8643
8951
|
}
|
|
8644
8952
|
var VECTORIZE_LOCK_TTL_MS = 6 * 60 * 60 * 1e3;
|
|
8645
8953
|
function vectorizeLockPath(ctx) {
|
|
8646
|
-
return
|
|
8954
|
+
return join29(ctx.dataDir, "_indexes", ".vectorize.lock");
|
|
8647
8955
|
}
|
|
8648
8956
|
function vectorizeSetupInProgress(ctx) {
|
|
8649
8957
|
const lock = vectorizeLockPath(ctx);
|
|
8650
8958
|
try {
|
|
8651
|
-
if (!
|
|
8959
|
+
if (!existsSync16(lock))
|
|
8652
8960
|
return false;
|
|
8653
|
-
return Date.now() -
|
|
8961
|
+
return Date.now() - statSync2(lock).mtimeMs < VECTORIZE_LOCK_TTL_MS;
|
|
8654
8962
|
} catch {
|
|
8655
8963
|
return false;
|
|
8656
8964
|
}
|
|
@@ -8669,24 +8977,24 @@ function spawnVectorizeSetup(repoRoot) {
|
|
|
8669
8977
|
}
|
|
8670
8978
|
async function runVectorizeSetup(repoRoot, out, err) {
|
|
8671
8979
|
const ctx = makeContext(repoRoot);
|
|
8672
|
-
const indexDir =
|
|
8673
|
-
const finalDb =
|
|
8674
|
-
if (
|
|
8980
|
+
const indexDir = join29(ctx.dataDir, "_indexes");
|
|
8981
|
+
const finalDb = join29(indexDir, "memory.sqlite");
|
|
8982
|
+
if (existsSync16(finalDb)) {
|
|
8675
8983
|
out("recall index already present \u2014 nothing to do\n");
|
|
8676
8984
|
return;
|
|
8677
8985
|
}
|
|
8678
|
-
|
|
8679
|
-
const
|
|
8986
|
+
mkdirSync2(indexDir, { recursive: true });
|
|
8987
|
+
const lockPath2 = vectorizeLockPath(ctx);
|
|
8680
8988
|
const token = `${process.pid}-${process.hrtime.bigint()}`;
|
|
8681
8989
|
let lockFd;
|
|
8682
8990
|
try {
|
|
8683
|
-
lockFd =
|
|
8991
|
+
lockFd = openSync2(lockPath2, "wx");
|
|
8684
8992
|
} catch (e) {
|
|
8685
8993
|
if (e.code !== "EEXIST")
|
|
8686
8994
|
throw e;
|
|
8687
8995
|
let stale = true;
|
|
8688
8996
|
try {
|
|
8689
|
-
stale = Date.now() -
|
|
8997
|
+
stale = Date.now() - statSync2(lockPath2).mtimeMs >= VECTORIZE_LOCK_TTL_MS;
|
|
8690
8998
|
} catch {
|
|
8691
8999
|
stale = true;
|
|
8692
9000
|
}
|
|
@@ -8694,38 +9002,38 @@ async function runVectorizeSetup(repoRoot, out, err) {
|
|
|
8694
9002
|
out("another recall setup is already in progress \u2014 skipping\n");
|
|
8695
9003
|
return;
|
|
8696
9004
|
}
|
|
8697
|
-
|
|
9005
|
+
rmSync2(lockPath2, { force: true });
|
|
8698
9006
|
try {
|
|
8699
|
-
lockFd =
|
|
9007
|
+
lockFd = openSync2(lockPath2, "wx");
|
|
8700
9008
|
} catch {
|
|
8701
9009
|
out("another recall setup just started \u2014 skipping\n");
|
|
8702
9010
|
return;
|
|
8703
9011
|
}
|
|
8704
9012
|
}
|
|
8705
|
-
const tmpDb =
|
|
9013
|
+
const tmpDb = join29(indexDir, `memory.sqlite.building-${process.pid}`);
|
|
8706
9014
|
const tmpSidecars = [tmpDb + "-wal", tmpDb + "-shm", tmpDb + "-journal"];
|
|
8707
9015
|
const cleanTmp = () => {
|
|
8708
|
-
|
|
9016
|
+
rmSync2(tmpDb, { force: true });
|
|
8709
9017
|
for (const s of tmpSidecars)
|
|
8710
|
-
|
|
9018
|
+
rmSync2(s, { force: true });
|
|
8711
9019
|
};
|
|
8712
9020
|
let tokenWritten = false;
|
|
8713
9021
|
const releaseLock = () => {
|
|
8714
9022
|
try {
|
|
8715
|
-
const cur =
|
|
9023
|
+
const cur = existsSync16(lockPath2) ? readFileSync4(lockPath2, "utf8").trim() : "";
|
|
8716
9024
|
if (cur === token || cur === "" && !tokenWritten)
|
|
8717
|
-
|
|
9025
|
+
rmSync2(lockPath2, { force: true });
|
|
8718
9026
|
} catch {
|
|
8719
9027
|
}
|
|
8720
9028
|
};
|
|
8721
9029
|
try {
|
|
8722
9030
|
try {
|
|
8723
|
-
|
|
9031
|
+
writeSync2(lockFd, token + "\n");
|
|
8724
9032
|
tokenWritten = true;
|
|
8725
9033
|
} finally {
|
|
8726
|
-
|
|
9034
|
+
closeSync2(lockFd);
|
|
8727
9035
|
}
|
|
8728
|
-
if (
|
|
9036
|
+
if (existsSync16(finalDb)) {
|
|
8729
9037
|
out("recall index already present \u2014 nothing to do\n");
|
|
8730
9038
|
return;
|
|
8731
9039
|
}
|
|
@@ -8741,7 +9049,7 @@ async function runVectorizeSetup(repoRoot, out, err) {
|
|
|
8741
9049
|
} finally {
|
|
8742
9050
|
db.close();
|
|
8743
9051
|
}
|
|
8744
|
-
if (
|
|
9052
|
+
if (existsSync16(tmpDb + "-wal")) {
|
|
8745
9053
|
throw new Error("temp index retained a WAL sidecar after consolidation; refusing to publish");
|
|
8746
9054
|
}
|
|
8747
9055
|
try {
|
|
@@ -8754,7 +9062,7 @@ async function runVectorizeSetup(repoRoot, out, err) {
|
|
|
8754
9062
|
}
|
|
8755
9063
|
throw e;
|
|
8756
9064
|
}
|
|
8757
|
-
|
|
9065
|
+
rmSync2(tmpDb, { force: true });
|
|
8758
9066
|
out(`recall index built \u2014 semantic search ready (memories: ${result.memories}, conversation chunks: ${result.sessionChunks})
|
|
8759
9067
|
`);
|
|
8760
9068
|
} catch (e) {
|
|
@@ -8790,7 +9098,8 @@ async function runSessionStart(repoRoot, out) {
|
|
|
8790
9098
|
} catch {
|
|
8791
9099
|
}
|
|
8792
9100
|
const bookkeepingPrefix = frameworkBookkeepingPrefix(ctx);
|
|
8793
|
-
const
|
|
9101
|
+
const archivePrefix = archiveRelPath(ctx) + "/";
|
|
9102
|
+
const carryover = collectCarryover(repoRoot, (p) => p.startsWith(bookkeepingPrefix) || p.startsWith(archivePrefix));
|
|
8794
9103
|
if (config.autoRecord.reindex && !git2?.conflict) {
|
|
8795
9104
|
await autoReindexMemory(ctx);
|
|
8796
9105
|
}
|
|
@@ -8804,14 +9113,14 @@ async function runSessionStart(repoRoot, out) {
|
|
|
8804
9113
|
} catch {
|
|
8805
9114
|
}
|
|
8806
9115
|
}
|
|
8807
|
-
let
|
|
9116
|
+
let archiveSync = null;
|
|
8808
9117
|
if (config.autoRecord.archive) {
|
|
8809
9118
|
try {
|
|
8810
|
-
|
|
8811
|
-
catchUp = await catchUpSessions2(ctx);
|
|
9119
|
+
archiveSync = await runArchiveSync(ctx, config, "start");
|
|
8812
9120
|
} catch {
|
|
8813
9121
|
}
|
|
8814
9122
|
}
|
|
9123
|
+
const catchUp = archiveSync?.catchUp ?? null;
|
|
8815
9124
|
let handoffPrune = null;
|
|
8816
9125
|
if (config.autoRecord.handoff) {
|
|
8817
9126
|
try {
|
|
@@ -8825,7 +9134,7 @@ async function runSessionStart(repoRoot, out) {
|
|
|
8825
9134
|
let vectorized = null;
|
|
8826
9135
|
let vectorizeSetupStarted = false;
|
|
8827
9136
|
if (config.autoRecord.vectorize) {
|
|
8828
|
-
const dbExists =
|
|
9137
|
+
const dbExists = existsSync16(join29(ctx.dataDir, "_indexes", "memory.sqlite"));
|
|
8829
9138
|
const action = decideVectorizeAction({
|
|
8830
9139
|
vectorizeOn: true,
|
|
8831
9140
|
dbExists,
|
|
@@ -8851,7 +9160,7 @@ async function runSessionStart(repoRoot, out) {
|
|
|
8851
9160
|
let failures = null;
|
|
8852
9161
|
if (config.autoRecord.failures) {
|
|
8853
9162
|
try {
|
|
8854
|
-
const { scanFailures: scanFailures2, failureReportSlice: failureReportSlice2 } = await import("./failures-
|
|
9163
|
+
const { scanFailures: scanFailures2, failureReportSlice: failureReportSlice2 } = await import("./failures-DBXJKFYX.js");
|
|
8855
9164
|
const slice = failureReportSlice2(await scanFailures2(ctx.dataDir));
|
|
8856
9165
|
if (slice.warnings.length > 0)
|
|
8857
9166
|
failures = slice;
|
|
@@ -8891,6 +9200,13 @@ async function runSessionStart(repoRoot, out) {
|
|
|
8891
9200
|
baseVersion,
|
|
8892
9201
|
missingWorklogDays,
|
|
8893
9202
|
catchUp: catchUp ?? void 0,
|
|
9203
|
+
archiveSync: archiveSync ? {
|
|
9204
|
+
committed: archiveSync.committed,
|
|
9205
|
+
pushed: archiveSync.pushed,
|
|
9206
|
+
pushSkipped: archiveSync.pushSkipped,
|
|
9207
|
+
rawPruned: archiveSync.rawPruned,
|
|
9208
|
+
retentionDays: archiveSync.retentionDays
|
|
9209
|
+
} : void 0,
|
|
8894
9210
|
vectorized: vectorized ?? void 0,
|
|
8895
9211
|
vectorizeSetup: vectorizeSetupStarted || void 0,
|
|
8896
9212
|
templateUpdate: templateUpdate ?? void 0,
|
|
@@ -8901,36 +9217,48 @@ async function runSessionStart(repoRoot, out) {
|
|
|
8901
9217
|
failures: failures ?? void 0
|
|
8902
9218
|
}));
|
|
8903
9219
|
}
|
|
8904
|
-
async function runSessionEnd(
|
|
8905
|
-
}
|
|
8906
|
-
function gitOut(cwd, gitArgs) {
|
|
8907
|
-
return execFileSync2("git", [...gitArgs], {
|
|
8908
|
-
cwd,
|
|
8909
|
-
encoding: "utf8",
|
|
8910
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
8911
|
-
});
|
|
8912
|
-
}
|
|
8913
|
-
function detectInterruptedGitOp(repoRoot) {
|
|
8914
|
-
const markers = [
|
|
8915
|
-
"MERGE_HEAD",
|
|
8916
|
-
"rebase-merge",
|
|
8917
|
-
"rebase-apply",
|
|
8918
|
-
"CHERRY_PICK_HEAD",
|
|
8919
|
-
"REVERT_HEAD",
|
|
8920
|
-
"BISECT_LOG",
|
|
8921
|
-
"index.lock"
|
|
8922
|
-
];
|
|
9220
|
+
async function runSessionEnd(repoRoot, out) {
|
|
8923
9221
|
try {
|
|
8924
|
-
const
|
|
8925
|
-
const
|
|
8926
|
-
|
|
8927
|
-
|
|
8928
|
-
|
|
8929
|
-
|
|
9222
|
+
const ctx = makeContext(repoRoot);
|
|
9223
|
+
const config = loadVortexConfig(ctx);
|
|
9224
|
+
if (!config.autoRecord.archive || !config.autoRecord.archiveAtEnd)
|
|
9225
|
+
return;
|
|
9226
|
+
const r = await runArchiveSync(ctx, config, "end");
|
|
9227
|
+
if (r.lockSkipped) {
|
|
9228
|
+
out("archive sync skipped (another session is syncing)\n");
|
|
9229
|
+
return;
|
|
8930
9230
|
}
|
|
9231
|
+
const parts = [];
|
|
9232
|
+
if (r.catchUp)
|
|
9233
|
+
parts.push(`${r.catchUp.ingestedLocal} archived`);
|
|
9234
|
+
if (r.rawPruned > 0)
|
|
9235
|
+
parts.push(`${r.rawPruned} raw pruned`);
|
|
9236
|
+
if (r.committed)
|
|
9237
|
+
parts.push("committed");
|
|
9238
|
+
if (r.pushed)
|
|
9239
|
+
parts.push("pushed");
|
|
9240
|
+
out(`session-end archive sync: ${parts.length ? parts.join(", ") : "nothing to do"}
|
|
9241
|
+
`);
|
|
8931
9242
|
} catch {
|
|
8932
9243
|
}
|
|
8933
|
-
|
|
9244
|
+
}
|
|
9245
|
+
async function runCatchUpCli(repoRoot, out) {
|
|
9246
|
+
const ctx = makeContext(repoRoot);
|
|
9247
|
+
const config = loadVortexConfig(ctx);
|
|
9248
|
+
const r = await runArchiveSync(ctx, config, "manual");
|
|
9249
|
+
out(JSON.stringify({
|
|
9250
|
+
ran: r.ran,
|
|
9251
|
+
lockSkipped: r.lockSkipped,
|
|
9252
|
+
ingested: r.catchUp?.ingestedLocal ?? 0,
|
|
9253
|
+
indexedPulled: r.catchUp?.indexedPulled ?? 0,
|
|
9254
|
+
ingestErrors: r.catchUp?.errors ?? 0,
|
|
9255
|
+
rawPruned: r.rawPruned,
|
|
9256
|
+
rawRetentionDays: r.retentionDays,
|
|
9257
|
+
committed: r.committed,
|
|
9258
|
+
...r.commitSkipped ? { commitSkipped: r.commitSkipped } : {},
|
|
9259
|
+
pushed: r.pushed,
|
|
9260
|
+
...r.pushSkipped ? { pushSkipped: r.pushSkipped } : {}
|
|
9261
|
+
}, null, 2) + "\n");
|
|
8934
9262
|
}
|
|
8935
9263
|
function collectCarryover(repoRoot, ignore) {
|
|
8936
9264
|
const interrupted = detectInterruptedGitOp(repoRoot);
|
|
@@ -8945,23 +9273,23 @@ function resolveSessionEnvironment(ctx, config) {
|
|
|
8945
9273
|
let environment = resolveEnvironment(config, {
|
|
8946
9274
|
hostname: hostname(),
|
|
8947
9275
|
env: process.env,
|
|
8948
|
-
pathExists:
|
|
9276
|
+
pathExists: existsSync16
|
|
8949
9277
|
});
|
|
8950
9278
|
if (!environment)
|
|
8951
9279
|
environment = process.env.VORTEX_ENV?.trim() || null;
|
|
8952
9280
|
if (!environment) {
|
|
8953
|
-
const envFile =
|
|
8954
|
-
if (
|
|
8955
|
-
environment =
|
|
9281
|
+
const envFile = join29(ctx.repoRoot, ".agent", "environment");
|
|
9282
|
+
if (existsSync16(envFile)) {
|
|
9283
|
+
environment = readFileSync4(envFile, "utf8").split(/\r?\n/)[0]?.trim() || null;
|
|
8956
9284
|
}
|
|
8957
9285
|
}
|
|
8958
9286
|
return environment;
|
|
8959
9287
|
}
|
|
8960
9288
|
|
|
8961
9289
|
// ../plugins/session-rituals/dist/ambient-recall.js
|
|
8962
|
-
import { join as
|
|
9290
|
+
import { join as join30 } from "path";
|
|
8963
9291
|
function defaultDbPath2(ctx) {
|
|
8964
|
-
return
|
|
9292
|
+
return join30(ctx.dataDir, "_indexes", "memory.sqlite");
|
|
8965
9293
|
}
|
|
8966
9294
|
function createAmbientRecaller(ctx, options) {
|
|
8967
9295
|
const resolveDb = options.dbPath ?? defaultDbPath2;
|
|
@@ -8999,13 +9327,13 @@ function createAmbientRecaller(ctx, options) {
|
|
|
8999
9327
|
|
|
9000
9328
|
// ../plugins/session-rituals/dist/worklog-write.js
|
|
9001
9329
|
import { mkdir as mkdir10, writeFile as writeFile11 } from "fs/promises";
|
|
9002
|
-
import { dirname as dirname6, join as
|
|
9330
|
+
import { dirname as dirname6, join as join31 } from "path";
|
|
9003
9331
|
async function ensureWorklogEntry(ctx, opts) {
|
|
9004
9332
|
const now = opts?.now ?? /* @__PURE__ */ new Date();
|
|
9005
9333
|
const date = isoDate3(now);
|
|
9006
9334
|
const time = isoTime2(now);
|
|
9007
9335
|
const keyword = (opts?.keyword ?? "worklog").trim() || "worklog";
|
|
9008
|
-
const store = new WorklogStore(
|
|
9336
|
+
const store = new WorklogStore(join31(ctx.dataDir, "worklog"));
|
|
9009
9337
|
const existing = await store.get(date);
|
|
9010
9338
|
if (existing) {
|
|
9011
9339
|
return { path: existing.path, date: existing.date, keyword: existing.keyword, created: false };
|