@vortex-os/base 0.9.0 → 0.11.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/README.md +20 -1
- package/dist/chunk-DWANI3LV.js +470 -0
- package/dist/chunk-DWANI3LV.js.map +1 -0
- package/dist/index.d.ts +183 -1
- package/dist/index.js +174 -177
- package/dist/index.js.map +1 -1
- package/dist/statusline-NQKJ3NWD.js +30 -0
- package/dist/statusline-NQKJ3NWD.js.map +1 -0
- package/package.json +1 -1
- package/templates/manifest.json +2 -2
- package/templates/routers/AI-RULES.md +2 -2
package/dist/index.js
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SESSION_END_COMMAND,
|
|
3
|
+
SESSION_START_COMMAND,
|
|
4
|
+
collectStatuslineProbes,
|
|
5
|
+
effortMeter,
|
|
6
|
+
ensureStatusline,
|
|
7
|
+
ensureVortexHooks,
|
|
8
|
+
formatTokens,
|
|
9
|
+
formatWindow,
|
|
10
|
+
makeBar,
|
|
11
|
+
parseSettings,
|
|
12
|
+
parseStatuslineInput,
|
|
13
|
+
renderStatusline,
|
|
14
|
+
runStatuslineCli,
|
|
15
|
+
safeSegment,
|
|
16
|
+
serializeSettings,
|
|
17
|
+
sniffEffortFromTranscript,
|
|
18
|
+
statuslineCommand
|
|
19
|
+
} from "./chunk-DWANI3LV.js";
|
|
1
20
|
import {
|
|
2
21
|
catchUpSessions
|
|
3
22
|
} from "./chunk-3L5DLEGP.js";
|
|
@@ -105,7 +124,7 @@ function moduleDir(ctx, moduleName) {
|
|
|
105
124
|
import { existsSync, readFileSync } from "fs";
|
|
106
125
|
import { join as join2 } from "path";
|
|
107
126
|
var DEFAULT_CONFIG = {
|
|
108
|
-
autoRecord: { sessionStart: true, worklog: true, decision: true, ambientRecall: true, archive: true, vectorize: true, vectorizeAutoDownload: true, commitFrameworkChanges: true, handoff: true, handoffRetentionDays: 7 },
|
|
127
|
+
autoRecord: { sessionStart: true, worklog: true, decision: true, ambientRecall: true, archive: true, vectorize: true, vectorizeAutoDownload: true, commitFrameworkChanges: true, handoff: true, handoffRetentionDays: 7, reindex: true, backfill: true },
|
|
109
128
|
updates: { check: "session" },
|
|
110
129
|
environments: []
|
|
111
130
|
};
|
|
@@ -149,6 +168,8 @@ function loadVortexConfig(ctx) {
|
|
|
149
168
|
const vectorizeAutoDownload = rawAuto.vectorizeAutoDownload === void 0 ? true : rawAuto.vectorizeAutoDownload === true;
|
|
150
169
|
const commitFrameworkChanges = rawAuto.commitFrameworkChanges === void 0 ? true : rawAuto.commitFrameworkChanges === true;
|
|
151
170
|
const handoff = rawAuto.handoff === void 0 ? true : rawAuto.handoff === true;
|
|
171
|
+
const reindex = rawAuto.reindex === void 0 ? true : rawAuto.reindex === true;
|
|
172
|
+
const backfill = rawAuto.backfill === void 0 ? true : rawAuto.backfill === true;
|
|
152
173
|
const rawDays = rawAuto.handoffRetentionDays;
|
|
153
174
|
const handoffRetentionDays = typeof rawDays === "number" && Number.isFinite(rawDays) && rawDays > 0 ? Math.floor(rawDays) : DEFAULT_CONFIG.autoRecord.handoffRetentionDays;
|
|
154
175
|
return {
|
|
@@ -158,7 +179,9 @@ function loadVortexConfig(ctx) {
|
|
|
158
179
|
vectorizeAutoDownload,
|
|
159
180
|
commitFrameworkChanges,
|
|
160
181
|
handoff,
|
|
161
|
-
handoffRetentionDays
|
|
182
|
+
handoffRetentionDays,
|
|
183
|
+
reindex,
|
|
184
|
+
backfill
|
|
162
185
|
},
|
|
163
186
|
updates: { check },
|
|
164
187
|
environments
|
|
@@ -4235,6 +4258,7 @@ var ClaudeDesktopLLMJudge = class extends InjectedLLMJudge {
|
|
|
4235
4258
|
// ../plugins/session-rituals/dist/index.js
|
|
4236
4259
|
var dist_exports14 = {};
|
|
4237
4260
|
__export(dist_exports14, {
|
|
4261
|
+
DEFAULT_GAP_WINDOW_DAYS: () => DEFAULT_GAP_WINDOW_DAYS,
|
|
4238
4262
|
HANDOFF_ARCHIVE_DIR: () => HANDOFF_ARCHIVE_DIR,
|
|
4239
4263
|
HANDOFF_DIR: () => HANDOFF_DIR,
|
|
4240
4264
|
OWNERSHIP_SCHEMA: () => OWNERSHIP_SCHEMA,
|
|
@@ -4244,6 +4268,7 @@ __export(dist_exports14, {
|
|
|
4244
4268
|
aggregateHandoff: () => aggregateHandoff,
|
|
4245
4269
|
applyGlobalSetup: () => applyGlobalSetup,
|
|
4246
4270
|
argvToSlash: () => argvToSlash,
|
|
4271
|
+
autoReindexMemory: () => autoReindexMemory,
|
|
4247
4272
|
buildInstallCommand: () => buildInstallCommand,
|
|
4248
4273
|
buildOwnershipManifest: () => buildOwnershipManifest,
|
|
4249
4274
|
buildRegistry: () => buildRegistry,
|
|
@@ -4252,6 +4277,7 @@ __export(dist_exports14, {
|
|
|
4252
4277
|
collectAgenda: () => collectAgenda,
|
|
4253
4278
|
collectCarryover: () => collectCarryover,
|
|
4254
4279
|
collectSessionStartReport: () => collectSessionStartReport,
|
|
4280
|
+
collectStatuslineProbes: () => collectStatuslineProbes,
|
|
4255
4281
|
compareSemver: () => compareSemver,
|
|
4256
4282
|
computeCurateFingerprint: () => computeCurateFingerprint,
|
|
4257
4283
|
countUncommitted: () => countUncommitted,
|
|
@@ -4262,10 +4288,15 @@ __export(dist_exports14, {
|
|
|
4262
4288
|
decisionCommand: () => decisionCommand,
|
|
4263
4289
|
detectInterruptedGitOp: () => detectInterruptedGitOp,
|
|
4264
4290
|
detectWorklogGaps: () => detectWorklogGaps,
|
|
4291
|
+
effortMeter: () => effortMeter,
|
|
4292
|
+
ensureStatusline: () => ensureStatusline,
|
|
4265
4293
|
ensureVortexHooks: () => ensureVortexHooks,
|
|
4266
4294
|
ensureWorklogEntry: () => ensureWorklogEntry,
|
|
4267
4295
|
extractNextUp: () => extractNextUp,
|
|
4268
4296
|
extractOpenTasks: () => extractOpenTasks,
|
|
4297
|
+
formatTokens: () => formatTokens,
|
|
4298
|
+
formatWindow: () => formatWindow,
|
|
4299
|
+
gapWindowSinceArg: () => gapWindowSinceArg,
|
|
4269
4300
|
globalMemoryPath: () => globalMemoryPath,
|
|
4270
4301
|
globalSettingsHasHook: () => globalSettingsHasHook,
|
|
4271
4302
|
globalSettingsPath: () => globalSettingsPath,
|
|
@@ -4277,9 +4308,11 @@ __export(dist_exports14, {
|
|
|
4277
4308
|
isNewer: () => isNewer,
|
|
4278
4309
|
isStableUpdate: () => isStableUpdate,
|
|
4279
4310
|
logCommand: () => logCommand,
|
|
4311
|
+
makeBar: () => makeBar,
|
|
4280
4312
|
ownershipManifestPath: () => ownershipManifestPath,
|
|
4281
4313
|
parseAdoptArgs: () => parseAdoptArgs,
|
|
4282
4314
|
parseSettings: () => parseSettings,
|
|
4315
|
+
parseStatuslineInput: () => parseStatuslineInput,
|
|
4283
4316
|
pruneHandoffs: () => pruneHandoffs,
|
|
4284
4317
|
queryNpmLatest: () => queryNpmLatest,
|
|
4285
4318
|
readGlobalInstancePointer: () => readGlobalInstancePointer,
|
|
@@ -4290,17 +4323,22 @@ __export(dist_exports14, {
|
|
|
4290
4323
|
renderAgenda: () => renderAgenda,
|
|
4291
4324
|
renderGlobalBlock: () => renderGlobalBlock,
|
|
4292
4325
|
renderSessionStartReport: () => renderSessionStartReport,
|
|
4326
|
+
renderStatusline: () => renderStatusline,
|
|
4293
4327
|
repairOwnershipManifest: () => repairOwnershipManifest,
|
|
4294
4328
|
resolveRepoRoot: () => resolveRepoRoot,
|
|
4295
4329
|
runCurateAccept: () => runCurateAccept,
|
|
4296
4330
|
runCurateCandidates: () => runCurateCandidates,
|
|
4297
4331
|
runCurateDecline: () => runCurateDecline,
|
|
4298
4332
|
runCuratePreview: () => runCuratePreview,
|
|
4333
|
+
runStatuslineCli: () => runStatuslineCli,
|
|
4299
4334
|
runTemplatesUpdate: () => runTemplatesUpdate,
|
|
4300
4335
|
runVortexCli: () => runVortexCli,
|
|
4336
|
+
safeSegment: () => safeSegment,
|
|
4301
4337
|
scanHandoffs: () => scanHandoffs,
|
|
4302
4338
|
serializeSettings: () => serializeSettings,
|
|
4303
4339
|
sessionStartCommand: () => sessionStartCommand,
|
|
4340
|
+
sniffEffortFromTranscript: () => sniffEffortFromTranscript,
|
|
4341
|
+
statuslineCommand: () => statuslineCommand,
|
|
4304
4342
|
templateDestRelPath: () => templateDestRelPath,
|
|
4305
4343
|
upsertGlobalBlock: () => upsertGlobalBlock,
|
|
4306
4344
|
validateCuratePayload: () => validateCuratePayload,
|
|
@@ -4552,7 +4590,7 @@ function todayIso() {
|
|
|
4552
4590
|
|
|
4553
4591
|
// ../plugins/session-rituals/dist/commands/reindex.js
|
|
4554
4592
|
import { existsSync as existsSync7 } from "fs";
|
|
4555
|
-
import { readFile as readFile17, writeFile as writeFile9 } from "fs/promises";
|
|
4593
|
+
import { readFile as readFile17, writeFile as writeFile9, utimes } from "fs/promises";
|
|
4556
4594
|
import { join as join21 } from "path";
|
|
4557
4595
|
var TARGETS = [
|
|
4558
4596
|
{
|
|
@@ -4706,6 +4744,52 @@ var reindexCommand = {
|
|
|
4706
4744
|
return results;
|
|
4707
4745
|
}
|
|
4708
4746
|
};
|
|
4747
|
+
async function autoReindexMemory(ctx) {
|
|
4748
|
+
try {
|
|
4749
|
+
const target = TARGETS.find((t) => t.dir === "_memory");
|
|
4750
|
+
if (!target)
|
|
4751
|
+
return "missing";
|
|
4752
|
+
const dir = join21(ctx.dataDir, target.dir);
|
|
4753
|
+
if (!existsSync7(dir))
|
|
4754
|
+
return "missing";
|
|
4755
|
+
const entries = await scanDirectory(dir, {
|
|
4756
|
+
recursive: target.recursive,
|
|
4757
|
+
skipPrefixes: target.skipPrefixes,
|
|
4758
|
+
skipFilenames: target.skipFilenames
|
|
4759
|
+
});
|
|
4760
|
+
const body = renderIndex({
|
|
4761
|
+
title: target.title,
|
|
4762
|
+
description: target.description,
|
|
4763
|
+
entries,
|
|
4764
|
+
privacy: target.privacy
|
|
4765
|
+
});
|
|
4766
|
+
const indexPath = join21(dir, "_INDEX.md");
|
|
4767
|
+
let existing;
|
|
4768
|
+
try {
|
|
4769
|
+
existing = await readFile17(indexPath, "utf8");
|
|
4770
|
+
} catch {
|
|
4771
|
+
existing = void 0;
|
|
4772
|
+
}
|
|
4773
|
+
const sameListing = existing !== void 0 && stripIndexDate(existing) === stripIndexDate(body);
|
|
4774
|
+
let status;
|
|
4775
|
+
if (sameListing) {
|
|
4776
|
+
status = "unchanged";
|
|
4777
|
+
} else {
|
|
4778
|
+
await writeFile9(indexPath, body, "utf8");
|
|
4779
|
+
status = "written";
|
|
4780
|
+
}
|
|
4781
|
+
if (existsSync7(indexPath)) {
|
|
4782
|
+
const now = /* @__PURE__ */ new Date();
|
|
4783
|
+
await utimes(indexPath, now, now);
|
|
4784
|
+
}
|
|
4785
|
+
return status;
|
|
4786
|
+
} catch {
|
|
4787
|
+
return "error";
|
|
4788
|
+
}
|
|
4789
|
+
}
|
|
4790
|
+
function stripIndexDate(body) {
|
|
4791
|
+
return body.replace(/^updated: .*$/m, "updated:");
|
|
4792
|
+
}
|
|
4709
4793
|
|
|
4710
4794
|
// ../plugins/session-rituals/dist/commands/session-start.js
|
|
4711
4795
|
import { existsSync as existsSync8 } from "fs";
|
|
@@ -5156,84 +5240,6 @@ import { copyFile as copyFile2, mkdir as mkdir9, readdir as readdir16, readFile
|
|
|
5156
5240
|
import { basename as basename7, dirname as dirname5, extname as extname11, join as join26, relative as relative5 } from "path";
|
|
5157
5241
|
import { fileURLToPath } from "url";
|
|
5158
5242
|
|
|
5159
|
-
// ../plugins/session-rituals/dist/ensure-hooks.js
|
|
5160
|
-
var SESSION_START_COMMAND = "npx --no-install vortex session-start || exit 0";
|
|
5161
|
-
var SESSION_END_COMMAND = "npx --no-install vortex session-end || exit 0";
|
|
5162
|
-
var LEGACY_COMMANDS = {
|
|
5163
|
-
SessionStart: [
|
|
5164
|
-
"npx --no-install -p @vortex-os/base vortex session-start || exit 0",
|
|
5165
|
-
"npx --no-install -p @vortex-os/base vortex session-start"
|
|
5166
|
-
],
|
|
5167
|
-
SessionEnd: [
|
|
5168
|
-
"npx --no-install -p @vortex-os/base vortex session-end || exit 0",
|
|
5169
|
-
"npx --no-install -p @vortex-os/base vortex session-end"
|
|
5170
|
-
]
|
|
5171
|
-
};
|
|
5172
|
-
function parseSettings(text) {
|
|
5173
|
-
const trimmed = (text ?? "").trim();
|
|
5174
|
-
if (trimmed.length === 0)
|
|
5175
|
-
return {};
|
|
5176
|
-
let parsed;
|
|
5177
|
-
try {
|
|
5178
|
-
parsed = JSON.parse(trimmed);
|
|
5179
|
-
} catch (e) {
|
|
5180
|
-
throw new Error(`.claude/settings.json is not valid JSON \u2014 refusing to overwrite. Fix or remove it first. (${e.message})`);
|
|
5181
|
-
}
|
|
5182
|
-
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
5183
|
-
throw new Error(".claude/settings.json is not a JSON object \u2014 refusing to overwrite.");
|
|
5184
|
-
}
|
|
5185
|
-
return parsed;
|
|
5186
|
-
}
|
|
5187
|
-
function ensureVortexHooks(existing) {
|
|
5188
|
-
const base = existing && typeof existing === "object" ? existing : {};
|
|
5189
|
-
const hooks = { ...base.hooks ?? {} };
|
|
5190
|
-
const added = [];
|
|
5191
|
-
const wire = (event, command) => {
|
|
5192
|
-
const legacy = LEGACY_COMMANDS[event];
|
|
5193
|
-
const src = hooks[event] ?? [];
|
|
5194
|
-
let changed = false;
|
|
5195
|
-
let kept = false;
|
|
5196
|
-
const groups = [];
|
|
5197
|
-
for (const g of src) {
|
|
5198
|
-
const hookList = [];
|
|
5199
|
-
for (const h of g.hooks ?? []) {
|
|
5200
|
-
const migrated = legacy.includes(h.command);
|
|
5201
|
-
const cmd = migrated ? command : h.command;
|
|
5202
|
-
if (cmd === command) {
|
|
5203
|
-
if (kept) {
|
|
5204
|
-
changed = true;
|
|
5205
|
-
continue;
|
|
5206
|
-
}
|
|
5207
|
-
kept = true;
|
|
5208
|
-
if (migrated)
|
|
5209
|
-
changed = true;
|
|
5210
|
-
hookList.push(migrated ? { ...h, command } : h);
|
|
5211
|
-
} else {
|
|
5212
|
-
hookList.push(h);
|
|
5213
|
-
}
|
|
5214
|
-
}
|
|
5215
|
-
if (hookList.length > 0)
|
|
5216
|
-
groups.push({ ...g, hooks: hookList });
|
|
5217
|
-
else
|
|
5218
|
-
changed = true;
|
|
5219
|
-
}
|
|
5220
|
-
if (!kept) {
|
|
5221
|
-
groups.push({ hooks: [{ type: "command", command }] });
|
|
5222
|
-
changed = true;
|
|
5223
|
-
}
|
|
5224
|
-
hooks[event] = groups;
|
|
5225
|
-
if (changed)
|
|
5226
|
-
added.push(event);
|
|
5227
|
-
};
|
|
5228
|
-
wire("SessionStart", SESSION_START_COMMAND);
|
|
5229
|
-
wire("SessionEnd", SESSION_END_COMMAND);
|
|
5230
|
-
const settings = { ...base, hooks };
|
|
5231
|
-
return { settings, added, alreadyWired: added.length === 0 };
|
|
5232
|
-
}
|
|
5233
|
-
function serializeSettings(settings) {
|
|
5234
|
-
return JSON.stringify(settings, null, 2) + "\n";
|
|
5235
|
-
}
|
|
5236
|
-
|
|
5237
5243
|
// ../plugins/session-rituals/dist/global-setup.js
|
|
5238
5244
|
import { homedir } from "os";
|
|
5239
5245
|
import { existsSync as existsSync10, readFileSync as readFileSync2 } from "fs";
|
|
@@ -7813,7 +7819,7 @@ import { execFileSync as execFileSync2, spawn as spawn2 } from "child_process";
|
|
|
7813
7819
|
import { existsSync as existsSync16, readFileSync as readFileSync4, mkdirSync, openSync, writeSync, closeSync, linkSync, rmSync, statSync } from "fs";
|
|
7814
7820
|
import { createRequire } from "module";
|
|
7815
7821
|
import { hostname } from "os";
|
|
7816
|
-
import { isAbsolute as isAbsolute5, join as
|
|
7822
|
+
import { isAbsolute as isAbsolute5, join as join30 } from "path";
|
|
7817
7823
|
|
|
7818
7824
|
// ../plugins/session-rituals/dist/update-check.js
|
|
7819
7825
|
import { execSync } from "child_process";
|
|
@@ -7931,6 +7937,9 @@ import { readdir as readdir17, readFile as readFile22, stat as stat9 } from "fs/
|
|
|
7931
7937
|
import { join as join28 } from "path";
|
|
7932
7938
|
var COUNTED_DIRS2 = ["_memory", "worklog", "decision-log"];
|
|
7933
7939
|
var DEFAULT_GAP_WINDOW_DAYS = 30;
|
|
7940
|
+
function gapWindowSinceArg() {
|
|
7941
|
+
return `${DEFAULT_GAP_WINDOW_DAYS} days ago`;
|
|
7942
|
+
}
|
|
7934
7943
|
var BOOT_BANNER = String.raw`
|
|
7935
7944
|
__ __ _ _____ __
|
|
7936
7945
|
\ \ / ___ _ _| |_| __\ \/ /
|
|
@@ -8131,7 +8140,7 @@ function renderSessionStartReport(report, extras) {
|
|
|
8131
8140
|
lines.push(`- always-on rules (loaded below): ${slugs}${over}`);
|
|
8132
8141
|
}
|
|
8133
8142
|
if (report.memoryIndexStale) {
|
|
8134
|
-
lines.push("- \
|
|
8143
|
+
lines.push("- \u2139\uFE0F memory index is stale (auto-reindex off or failed) \u2014 recent memories may be missing from the index.");
|
|
8135
8144
|
}
|
|
8136
8145
|
const handoffs = report.handoffs ?? [];
|
|
8137
8146
|
const nextUp = report.nextUp ?? [];
|
|
@@ -8171,14 +8180,14 @@ function renderSessionStartReport(report, extras) {
|
|
|
8171
8180
|
}
|
|
8172
8181
|
const gaps = extras?.missingWorklogDays ?? [];
|
|
8173
8182
|
if (gaps.length) {
|
|
8174
|
-
lines.push(`- \
|
|
8183
|
+
lines.push(`- \u21A9\uFE0F no worklog yet for: ${gaps.join(", ")} \u2014 backfill from that day's session archive or commits.`);
|
|
8175
8184
|
}
|
|
8176
8185
|
const carry = extras?.carryover;
|
|
8177
8186
|
if (carry?.interrupted) {
|
|
8178
8187
|
lines.push(carry.interrupted === "index.lock" ? `- \u26A0\uFE0F a git lock (\`index.lock\`) is present \u2014 another git process may be running, or it is stale from a crash; remove it if nothing is using git. \`/resume\` shows what stopped.` : `- \u26A0\uFE0F interrupted git op (\`${carry.interrupted}\`) \u2014 likely a crashed prior session; finish or abort it before new work. Run \`/resume\` to see what stopped.`);
|
|
8179
8188
|
}
|
|
8180
8189
|
if (carry && carry.uncommitted > 0) {
|
|
8181
|
-
lines.push(`- \u21A9\uFE0F ${carry.uncommitted} uncommitted change(s) carried over from a prior session \u2014
|
|
8190
|
+
lines.push(`- \u21A9\uFE0F ${carry.uncommitted} uncommitted change(s) carried over from a prior session \u2014 likely normal work in progress.`);
|
|
8182
8191
|
}
|
|
8183
8192
|
const cu = extras?.catchUp;
|
|
8184
8193
|
if (cu && (cu.ingestedLocal > 0 || cu.indexedPulled > 0 || cu.errors > 0)) {
|
|
@@ -8379,56 +8388,11 @@ function isoDate2(d2) {
|
|
|
8379
8388
|
return `${y2}-${m2}-${day}`;
|
|
8380
8389
|
}
|
|
8381
8390
|
|
|
8382
|
-
// ../plugins/session-rituals/dist/worklog-write.js
|
|
8383
|
-
import { mkdir as mkdir10, writeFile as writeFile12 } from "fs/promises";
|
|
8384
|
-
import { dirname as dirname6, join as join29 } from "path";
|
|
8385
|
-
async function ensureWorklogEntry(ctx, opts) {
|
|
8386
|
-
const now = opts?.now ?? /* @__PURE__ */ new Date();
|
|
8387
|
-
const date = isoDate3(now);
|
|
8388
|
-
const time = isoTime2(now);
|
|
8389
|
-
const keyword = (opts?.keyword ?? "worklog").trim() || "worklog";
|
|
8390
|
-
const store = new WorklogStore(join29(ctx.dataDir, "worklog"));
|
|
8391
|
-
const existing = await store.get(date);
|
|
8392
|
-
if (existing) {
|
|
8393
|
-
return { path: existing.path, date: existing.date, keyword: existing.keyword, created: false };
|
|
8394
|
-
}
|
|
8395
|
-
const path = store.pathFor(date, keyword, time);
|
|
8396
|
-
const title = opts?.title ?? `${date} worklog`;
|
|
8397
|
-
await mkdir10(dirname6(path), { recursive: true });
|
|
8398
|
-
await writeFile12(path, renderWorklogFile(date, title, opts?.body ?? ""), "utf8");
|
|
8399
|
-
return { path, date, keyword, created: true };
|
|
8400
|
-
}
|
|
8401
|
-
function renderWorklogFile(date, title, body) {
|
|
8402
|
-
const trimmed = body.trimEnd();
|
|
8403
|
-
return `---
|
|
8404
|
-
type: worklog
|
|
8405
|
-
created: ${date}
|
|
8406
|
-
updated: ${date}
|
|
8407
|
-
tags: [worklog]
|
|
8408
|
-
---
|
|
8409
|
-
|
|
8410
|
-
# ${title}
|
|
8411
|
-
` + (trimmed ? `
|
|
8412
|
-
${trimmed}
|
|
8413
|
-
` : ``);
|
|
8414
|
-
}
|
|
8415
|
-
function isoDate3(d2) {
|
|
8416
|
-
const y2 = d2.getFullYear();
|
|
8417
|
-
const m2 = String(d2.getMonth() + 1).padStart(2, "0");
|
|
8418
|
-
const day = String(d2.getDate()).padStart(2, "0");
|
|
8419
|
-
return `${y2}-${m2}-${day}`;
|
|
8420
|
-
}
|
|
8421
|
-
function isoTime2(d2) {
|
|
8422
|
-
const h = String(d2.getHours()).padStart(2, "0");
|
|
8423
|
-
const m2 = String(d2.getMinutes()).padStart(2, "0");
|
|
8424
|
-
return `${h}${m2}`;
|
|
8425
|
-
}
|
|
8426
|
-
|
|
8427
8391
|
// ../plugins/session-rituals/dist/curate-cli.js
|
|
8428
8392
|
import { existsSync as existsSync15 } from "fs";
|
|
8429
8393
|
import { createHash as createHash3 } from "crypto";
|
|
8430
8394
|
import { readFile as readFile23, readdir as readdir18 } from "fs/promises";
|
|
8431
|
-
import { join as
|
|
8395
|
+
import { join as join29 } from "path";
|
|
8432
8396
|
var SYSTEM_META_DIRS3 = /* @__PURE__ */ new Set([
|
|
8433
8397
|
"worklog",
|
|
8434
8398
|
"decision-log",
|
|
@@ -8508,7 +8472,7 @@ function joinRel(...parts) {
|
|
|
8508
8472
|
}
|
|
8509
8473
|
async function runCurateCandidates(repoRoot, options) {
|
|
8510
8474
|
const maxEntries = options?.maxEntries ?? 200;
|
|
8511
|
-
const dataDir =
|
|
8475
|
+
const dataDir = join29(repoRoot, "data");
|
|
8512
8476
|
const candidates = [];
|
|
8513
8477
|
let truncated = false;
|
|
8514
8478
|
if (existsSync15(dataDir)) {
|
|
@@ -8534,7 +8498,7 @@ async function runCurateCandidates(repoRoot, options) {
|
|
|
8534
8498
|
continue;
|
|
8535
8499
|
if (atRoot && (SYSTEM_META_DIRS3.has(e.name) || e.name.startsWith("_")))
|
|
8536
8500
|
continue;
|
|
8537
|
-
await visit(
|
|
8501
|
+
await visit(join29(absDir, e.name), joinRel(relDir, e.name));
|
|
8538
8502
|
} else if (e.isFile() && e.name.endsWith(".md")) {
|
|
8539
8503
|
if (NON_DOC_FILES.has(e.name))
|
|
8540
8504
|
continue;
|
|
@@ -8543,7 +8507,7 @@ async function runCurateCandidates(repoRoot, options) {
|
|
|
8543
8507
|
let topic = null;
|
|
8544
8508
|
let tags = [];
|
|
8545
8509
|
try {
|
|
8546
|
-
const raw = await readFile23(
|
|
8510
|
+
const raw = await readFile23(join29(absDir, e.name), "utf8");
|
|
8547
8511
|
const parsed = parseFrontmatter(raw);
|
|
8548
8512
|
if (typeof parsed.frontmatter.topic === "string") {
|
|
8549
8513
|
topic = parsed.frontmatter.topic.trim().toLowerCase();
|
|
@@ -8581,7 +8545,7 @@ async function runCuratePreview(repoRoot, payload, now = /* @__PURE__ */ new Dat
|
|
|
8581
8545
|
};
|
|
8582
8546
|
}
|
|
8583
8547
|
try {
|
|
8584
|
-
validateDataRelativePath(
|
|
8548
|
+
validateDataRelativePath(join29(repoRoot, "data"), v2.effectiveRelPath);
|
|
8585
8549
|
} catch (e) {
|
|
8586
8550
|
return {
|
|
8587
8551
|
subcommand: "curate-preview",
|
|
@@ -8598,10 +8562,10 @@ async function runCuratePreview(repoRoot, payload, now = /* @__PURE__ */ new Dat
|
|
|
8598
8562
|
let targetExists;
|
|
8599
8563
|
let wouldDo;
|
|
8600
8564
|
if (payload.action === "create-file") {
|
|
8601
|
-
targetExists = existsSync15(
|
|
8565
|
+
targetExists = existsSync15(join29(repoRoot, "data", v2.effectiveRelPath));
|
|
8602
8566
|
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}.`;
|
|
8603
8567
|
} else {
|
|
8604
|
-
targetExists = existsSync15(
|
|
8568
|
+
targetExists = existsSync15(join29(repoRoot, "data", v2.effectiveRelPath));
|
|
8605
8569
|
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).`;
|
|
8606
8570
|
}
|
|
8607
8571
|
const nextActions = [];
|
|
@@ -8774,8 +8738,13 @@ function readCuratePayload(args) {
|
|
|
8774
8738
|
async function runVortexCli(argv, io) {
|
|
8775
8739
|
const out = io?.stdout ?? ((s) => process.stdout.write(s));
|
|
8776
8740
|
const err = io?.stderr ?? ((s) => process.stderr.write(s));
|
|
8777
|
-
const repoRoot = resolveRepoRoot();
|
|
8778
8741
|
try {
|
|
8742
|
+
if (argv[0] === "statusline") {
|
|
8743
|
+
const { runStatuslineCli: runStatuslineCli2 } = await import("./statusline-NQKJ3NWD.js");
|
|
8744
|
+
const statuslineRoot = process.env.VORTEX_REPO_ROOT?.trim() || process.cwd();
|
|
8745
|
+
return runStatuslineCli2(argv.slice(1), statuslineRoot, out, err);
|
|
8746
|
+
}
|
|
8747
|
+
const repoRoot = resolveRepoRoot();
|
|
8779
8748
|
if (argv[0] === "session-start") {
|
|
8780
8749
|
await runSessionStart(repoRoot, out);
|
|
8781
8750
|
return 0;
|
|
@@ -8812,8 +8781,9 @@ async function runVortexCli(argv, io) {
|
|
|
8812
8781
|
Commands:
|
|
8813
8782
|
${names}
|
|
8814
8783
|
session-start \u2014 emit the start-of-session boot report (git pull + data counts + catch-up)
|
|
8815
|
-
session-end \u2014
|
|
8784
|
+
session-end \u2014 no-op (kept for hook compatibility; worklog gap handling is at session-start)
|
|
8816
8785
|
check-updates \u2014 check the npm registry for a newer @vortex-os/base (read-only; prints the exact update command)
|
|
8786
|
+
statusline \u2014 render the Claude Code status bar from stdin JSON (\`lite\` for 1-line; \`install [--lite]\` wires .claude/settings.json)
|
|
8817
8787
|
|
|
8818
8788
|
Instance shortcuts (also available as \`/vortex <sub>\`):
|
|
8819
8789
|
init \u2014 first-time setup: routers + data/ + hooks + slash-commands
|
|
@@ -8880,7 +8850,7 @@ function memoryExtendedPresent() {
|
|
|
8880
8850
|
}
|
|
8881
8851
|
var VECTORIZE_LOCK_TTL_MS = 6 * 60 * 60 * 1e3;
|
|
8882
8852
|
function vectorizeLockPath(ctx) {
|
|
8883
|
-
return
|
|
8853
|
+
return join30(ctx.dataDir, "_indexes", ".vectorize.lock");
|
|
8884
8854
|
}
|
|
8885
8855
|
function vectorizeSetupInProgress(ctx) {
|
|
8886
8856
|
const lock = vectorizeLockPath(ctx);
|
|
@@ -8906,8 +8876,8 @@ function spawnVectorizeSetup(repoRoot) {
|
|
|
8906
8876
|
}
|
|
8907
8877
|
async function runVectorizeSetup(repoRoot, out, err) {
|
|
8908
8878
|
const ctx = makeContext(repoRoot);
|
|
8909
|
-
const indexDir =
|
|
8910
|
-
const finalDb =
|
|
8879
|
+
const indexDir = join30(ctx.dataDir, "_indexes");
|
|
8880
|
+
const finalDb = join30(indexDir, "memory.sqlite");
|
|
8911
8881
|
if (existsSync16(finalDb)) {
|
|
8912
8882
|
out("recall index already present \u2014 nothing to do\n");
|
|
8913
8883
|
return;
|
|
@@ -8939,7 +8909,7 @@ async function runVectorizeSetup(repoRoot, out, err) {
|
|
|
8939
8909
|
return;
|
|
8940
8910
|
}
|
|
8941
8911
|
}
|
|
8942
|
-
const tmpDb =
|
|
8912
|
+
const tmpDb = join30(indexDir, `memory.sqlite.building-${process.pid}`);
|
|
8943
8913
|
const tmpSidecars = [tmpDb + "-wal", tmpDb + "-shm", tmpDb + "-journal"];
|
|
8944
8914
|
const cleanTmp = () => {
|
|
8945
8915
|
rmSync(tmpDb, { force: true });
|
|
@@ -9028,13 +8998,18 @@ async function runSessionStart(repoRoot, out) {
|
|
|
9028
8998
|
}
|
|
9029
8999
|
const bookkeepingPrefix = frameworkBookkeepingPrefix(ctx);
|
|
9030
9000
|
const carryover = collectCarryover(repoRoot, (p) => p.startsWith(bookkeepingPrefix));
|
|
9001
|
+
if (config.autoRecord.reindex && !git2?.conflict) {
|
|
9002
|
+
await autoReindexMemory(ctx);
|
|
9003
|
+
}
|
|
9031
9004
|
const report = await collectSessionStartReport(ctx, { environment });
|
|
9032
9005
|
let missingWorklogDays = [];
|
|
9033
|
-
|
|
9034
|
-
|
|
9035
|
-
|
|
9036
|
-
|
|
9037
|
-
|
|
9006
|
+
if (config.autoRecord.worklog && config.autoRecord.backfill && !git2?.conflict) {
|
|
9007
|
+
try {
|
|
9008
|
+
const log = gitOut(repoRoot, ["log", `--since=${gapWindowSinceArg()}`, "--pretty=%cd", "--date=short"]);
|
|
9009
|
+
const commitDays = log.split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
|
|
9010
|
+
missingWorklogDays = detectWorklogGaps(commitDays, report.recentWorklogDates);
|
|
9011
|
+
} catch {
|
|
9012
|
+
}
|
|
9038
9013
|
}
|
|
9039
9014
|
let catchUp = null;
|
|
9040
9015
|
if (config.autoRecord.archive) {
|
|
@@ -9057,7 +9032,7 @@ async function runSessionStart(repoRoot, out) {
|
|
|
9057
9032
|
let vectorized = null;
|
|
9058
9033
|
let vectorizeSetupStarted = false;
|
|
9059
9034
|
if (config.autoRecord.vectorize) {
|
|
9060
|
-
const dbExists = existsSync16(
|
|
9035
|
+
const dbExists = existsSync16(join30(ctx.dataDir, "_indexes", "memory.sqlite"));
|
|
9061
9036
|
const action = decideVectorizeAction({
|
|
9062
9037
|
vectorizeOn: true,
|
|
9063
9038
|
dbExists,
|
|
@@ -9122,17 +9097,7 @@ async function runSessionStart(repoRoot, out) {
|
|
|
9122
9097
|
handoffPrune: handoffPrune ?? void 0
|
|
9123
9098
|
}));
|
|
9124
9099
|
}
|
|
9125
|
-
async function runSessionEnd(
|
|
9126
|
-
const ctx = makeContext(repoRoot);
|
|
9127
|
-
const config = loadVortexConfig(ctx);
|
|
9128
|
-
if (config.autoRecord.worklog && hadActivityToday(repoRoot)) {
|
|
9129
|
-
const res = await ensureWorklogEntry(ctx, {
|
|
9130
|
-
body: "_Auto-created at session end (work detected but no worklog written). Enrich with the session's work, or remove if there is nothing to log._"
|
|
9131
|
-
});
|
|
9132
|
-
if (res.created)
|
|
9133
|
-
out(`VortEX: created worklog ${res.path}
|
|
9134
|
-
`);
|
|
9135
|
-
}
|
|
9100
|
+
async function runSessionEnd(_repoRoot, _out) {
|
|
9136
9101
|
}
|
|
9137
9102
|
function gitOut(cwd, gitArgs) {
|
|
9138
9103
|
return execFileSync2("git", [...gitArgs], {
|
|
@@ -9156,7 +9121,7 @@ function detectInterruptedGitOp(repoRoot) {
|
|
|
9156
9121
|
const resolved = gitOut(repoRoot, args).split(/\r?\n/).map((s) => s.trim());
|
|
9157
9122
|
for (let i = 0; i < markers.length; i++) {
|
|
9158
9123
|
const p = resolved[i];
|
|
9159
|
-
if (p && existsSync16(isAbsolute5(p) ? p :
|
|
9124
|
+
if (p && existsSync16(isAbsolute5(p) ? p : join30(repoRoot, p)))
|
|
9160
9125
|
return markers[i];
|
|
9161
9126
|
}
|
|
9162
9127
|
} catch {
|
|
@@ -9172,19 +9137,6 @@ function collectCarryover(repoRoot, ignore) {
|
|
|
9172
9137
|
}
|
|
9173
9138
|
return uncommitted > 0 || interrupted ? { uncommitted, interrupted } : null;
|
|
9174
9139
|
}
|
|
9175
|
-
function hadActivityToday(repoRoot) {
|
|
9176
|
-
try {
|
|
9177
|
-
const dirty = gitOut(repoRoot, ["status", "--porcelain"]).trim();
|
|
9178
|
-
if (dirty)
|
|
9179
|
-
return true;
|
|
9180
|
-
const since = /* @__PURE__ */ new Date();
|
|
9181
|
-
since.setHours(0, 0, 0, 0);
|
|
9182
|
-
const commits = gitOut(repoRoot, ["log", "--oneline", `--since=${since.toISOString()}`]).trim();
|
|
9183
|
-
return commits.length > 0;
|
|
9184
|
-
} catch {
|
|
9185
|
-
return false;
|
|
9186
|
-
}
|
|
9187
|
-
}
|
|
9188
9140
|
function resolveSessionEnvironment(ctx, config) {
|
|
9189
9141
|
let environment = resolveEnvironment(config, {
|
|
9190
9142
|
hostname: hostname(),
|
|
@@ -9194,7 +9146,7 @@ function resolveSessionEnvironment(ctx, config) {
|
|
|
9194
9146
|
if (!environment)
|
|
9195
9147
|
environment = process.env.VORTEX_ENV?.trim() || null;
|
|
9196
9148
|
if (!environment) {
|
|
9197
|
-
const envFile =
|
|
9149
|
+
const envFile = join30(ctx.repoRoot, ".agent", "environment");
|
|
9198
9150
|
if (existsSync16(envFile)) {
|
|
9199
9151
|
environment = readFileSync4(envFile, "utf8").split(/\r?\n/)[0]?.trim() || null;
|
|
9200
9152
|
}
|
|
@@ -9203,9 +9155,9 @@ function resolveSessionEnvironment(ctx, config) {
|
|
|
9203
9155
|
}
|
|
9204
9156
|
|
|
9205
9157
|
// ../plugins/session-rituals/dist/ambient-recall.js
|
|
9206
|
-
import { join as
|
|
9158
|
+
import { join as join31 } from "path";
|
|
9207
9159
|
function defaultDbPath2(ctx) {
|
|
9208
|
-
return
|
|
9160
|
+
return join31(ctx.dataDir, "_indexes", "memory.sqlite");
|
|
9209
9161
|
}
|
|
9210
9162
|
function createAmbientRecaller(ctx, options) {
|
|
9211
9163
|
const resolveDb = options.dbPath ?? defaultDbPath2;
|
|
@@ -9240,6 +9192,51 @@ function createAmbientRecaller(ctx, options) {
|
|
|
9240
9192
|
}
|
|
9241
9193
|
});
|
|
9242
9194
|
}
|
|
9195
|
+
|
|
9196
|
+
// ../plugins/session-rituals/dist/worklog-write.js
|
|
9197
|
+
import { mkdir as mkdir10, writeFile as writeFile12 } from "fs/promises";
|
|
9198
|
+
import { dirname as dirname6, join as join32 } from "path";
|
|
9199
|
+
async function ensureWorklogEntry(ctx, opts) {
|
|
9200
|
+
const now = opts?.now ?? /* @__PURE__ */ new Date();
|
|
9201
|
+
const date = isoDate3(now);
|
|
9202
|
+
const time = isoTime2(now);
|
|
9203
|
+
const keyword = (opts?.keyword ?? "worklog").trim() || "worklog";
|
|
9204
|
+
const store = new WorklogStore(join32(ctx.dataDir, "worklog"));
|
|
9205
|
+
const existing = await store.get(date);
|
|
9206
|
+
if (existing) {
|
|
9207
|
+
return { path: existing.path, date: existing.date, keyword: existing.keyword, created: false };
|
|
9208
|
+
}
|
|
9209
|
+
const path = store.pathFor(date, keyword, time);
|
|
9210
|
+
const title = opts?.title ?? `${date} worklog`;
|
|
9211
|
+
await mkdir10(dirname6(path), { recursive: true });
|
|
9212
|
+
await writeFile12(path, renderWorklogFile(date, title, opts?.body ?? ""), "utf8");
|
|
9213
|
+
return { path, date, keyword, created: true };
|
|
9214
|
+
}
|
|
9215
|
+
function renderWorklogFile(date, title, body) {
|
|
9216
|
+
const trimmed = body.trimEnd();
|
|
9217
|
+
return `---
|
|
9218
|
+
type: worklog
|
|
9219
|
+
created: ${date}
|
|
9220
|
+
updated: ${date}
|
|
9221
|
+
tags: [worklog]
|
|
9222
|
+
---
|
|
9223
|
+
|
|
9224
|
+
# ${title}
|
|
9225
|
+
` + (trimmed ? `
|
|
9226
|
+
${trimmed}
|
|
9227
|
+
` : ``);
|
|
9228
|
+
}
|
|
9229
|
+
function isoDate3(d2) {
|
|
9230
|
+
const y2 = d2.getFullYear();
|
|
9231
|
+
const m2 = String(d2.getMonth() + 1).padStart(2, "0");
|
|
9232
|
+
const day = String(d2.getDate()).padStart(2, "0");
|
|
9233
|
+
return `${y2}-${m2}-${day}`;
|
|
9234
|
+
}
|
|
9235
|
+
function isoTime2(d2) {
|
|
9236
|
+
const h = String(d2.getHours()).padStart(2, "0");
|
|
9237
|
+
const m2 = String(d2.getMinutes()).padStart(2, "0");
|
|
9238
|
+
return `${h}${m2}`;
|
|
9239
|
+
}
|
|
9243
9240
|
export {
|
|
9244
9241
|
dist_exports5 as aiCodingPitfalls,
|
|
9245
9242
|
dist_exports as core,
|