@vortex-os/base 0.9.0 → 0.10.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/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  catchUpSessions
3
- } from "./chunk-3L5DLEGP.js";
3
+ } from "./chunk-7SNLVGBO.js";
4
4
  import {
5
5
  __export
6
6
  } from "./chunk-PZ5AY32C.js";
@@ -105,7 +105,7 @@ function moduleDir(ctx, moduleName) {
105
105
  import { existsSync, readFileSync } from "fs";
106
106
  import { join as join2 } from "path";
107
107
  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 },
108
+ 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
109
  updates: { check: "session" },
110
110
  environments: []
111
111
  };
@@ -149,6 +149,8 @@ function loadVortexConfig(ctx) {
149
149
  const vectorizeAutoDownload = rawAuto.vectorizeAutoDownload === void 0 ? true : rawAuto.vectorizeAutoDownload === true;
150
150
  const commitFrameworkChanges = rawAuto.commitFrameworkChanges === void 0 ? true : rawAuto.commitFrameworkChanges === true;
151
151
  const handoff = rawAuto.handoff === void 0 ? true : rawAuto.handoff === true;
152
+ const reindex = rawAuto.reindex === void 0 ? true : rawAuto.reindex === true;
153
+ const backfill = rawAuto.backfill === void 0 ? true : rawAuto.backfill === true;
152
154
  const rawDays = rawAuto.handoffRetentionDays;
153
155
  const handoffRetentionDays = typeof rawDays === "number" && Number.isFinite(rawDays) && rawDays > 0 ? Math.floor(rawDays) : DEFAULT_CONFIG.autoRecord.handoffRetentionDays;
154
156
  return {
@@ -158,7 +160,9 @@ function loadVortexConfig(ctx) {
158
160
  vectorizeAutoDownload,
159
161
  commitFrameworkChanges,
160
162
  handoff,
161
- handoffRetentionDays
163
+ handoffRetentionDays,
164
+ reindex,
165
+ backfill
162
166
  },
163
167
  updates: { check },
164
168
  environments
@@ -4235,6 +4239,7 @@ var ClaudeDesktopLLMJudge = class extends InjectedLLMJudge {
4235
4239
  // ../plugins/session-rituals/dist/index.js
4236
4240
  var dist_exports14 = {};
4237
4241
  __export(dist_exports14, {
4242
+ DEFAULT_GAP_WINDOW_DAYS: () => DEFAULT_GAP_WINDOW_DAYS,
4238
4243
  HANDOFF_ARCHIVE_DIR: () => HANDOFF_ARCHIVE_DIR,
4239
4244
  HANDOFF_DIR: () => HANDOFF_DIR,
4240
4245
  OWNERSHIP_SCHEMA: () => OWNERSHIP_SCHEMA,
@@ -4244,6 +4249,7 @@ __export(dist_exports14, {
4244
4249
  aggregateHandoff: () => aggregateHandoff,
4245
4250
  applyGlobalSetup: () => applyGlobalSetup,
4246
4251
  argvToSlash: () => argvToSlash,
4252
+ autoReindexMemory: () => autoReindexMemory,
4247
4253
  buildInstallCommand: () => buildInstallCommand,
4248
4254
  buildOwnershipManifest: () => buildOwnershipManifest,
4249
4255
  buildRegistry: () => buildRegistry,
@@ -4266,6 +4272,7 @@ __export(dist_exports14, {
4266
4272
  ensureWorklogEntry: () => ensureWorklogEntry,
4267
4273
  extractNextUp: () => extractNextUp,
4268
4274
  extractOpenTasks: () => extractOpenTasks,
4275
+ gapWindowSinceArg: () => gapWindowSinceArg,
4269
4276
  globalMemoryPath: () => globalMemoryPath,
4270
4277
  globalSettingsHasHook: () => globalSettingsHasHook,
4271
4278
  globalSettingsPath: () => globalSettingsPath,
@@ -4552,7 +4559,7 @@ function todayIso() {
4552
4559
 
4553
4560
  // ../plugins/session-rituals/dist/commands/reindex.js
4554
4561
  import { existsSync as existsSync7 } from "fs";
4555
- import { readFile as readFile17, writeFile as writeFile9 } from "fs/promises";
4562
+ import { readFile as readFile17, writeFile as writeFile9, utimes } from "fs/promises";
4556
4563
  import { join as join21 } from "path";
4557
4564
  var TARGETS = [
4558
4565
  {
@@ -4706,6 +4713,52 @@ var reindexCommand = {
4706
4713
  return results;
4707
4714
  }
4708
4715
  };
4716
+ async function autoReindexMemory(ctx) {
4717
+ try {
4718
+ const target = TARGETS.find((t) => t.dir === "_memory");
4719
+ if (!target)
4720
+ return "missing";
4721
+ const dir = join21(ctx.dataDir, target.dir);
4722
+ if (!existsSync7(dir))
4723
+ return "missing";
4724
+ const entries = await scanDirectory(dir, {
4725
+ recursive: target.recursive,
4726
+ skipPrefixes: target.skipPrefixes,
4727
+ skipFilenames: target.skipFilenames
4728
+ });
4729
+ const body = renderIndex({
4730
+ title: target.title,
4731
+ description: target.description,
4732
+ entries,
4733
+ privacy: target.privacy
4734
+ });
4735
+ const indexPath = join21(dir, "_INDEX.md");
4736
+ let existing;
4737
+ try {
4738
+ existing = await readFile17(indexPath, "utf8");
4739
+ } catch {
4740
+ existing = void 0;
4741
+ }
4742
+ const sameListing = existing !== void 0 && stripIndexDate(existing) === stripIndexDate(body);
4743
+ let status;
4744
+ if (sameListing) {
4745
+ status = "unchanged";
4746
+ } else {
4747
+ await writeFile9(indexPath, body, "utf8");
4748
+ status = "written";
4749
+ }
4750
+ if (existsSync7(indexPath)) {
4751
+ const now = /* @__PURE__ */ new Date();
4752
+ await utimes(indexPath, now, now);
4753
+ }
4754
+ return status;
4755
+ } catch {
4756
+ return "error";
4757
+ }
4758
+ }
4759
+ function stripIndexDate(body) {
4760
+ return body.replace(/^updated: .*$/m, "updated:");
4761
+ }
4709
4762
 
4710
4763
  // ../plugins/session-rituals/dist/commands/session-start.js
4711
4764
  import { existsSync as existsSync8 } from "fs";
@@ -7813,7 +7866,7 @@ import { execFileSync as execFileSync2, spawn as spawn2 } from "child_process";
7813
7866
  import { existsSync as existsSync16, readFileSync as readFileSync4, mkdirSync, openSync, writeSync, closeSync, linkSync, rmSync, statSync } from "fs";
7814
7867
  import { createRequire } from "module";
7815
7868
  import { hostname } from "os";
7816
- import { isAbsolute as isAbsolute5, join as join31 } from "path";
7869
+ import { isAbsolute as isAbsolute5, join as join30 } from "path";
7817
7870
 
7818
7871
  // ../plugins/session-rituals/dist/update-check.js
7819
7872
  import { execSync } from "child_process";
@@ -7931,6 +7984,9 @@ import { readdir as readdir17, readFile as readFile22, stat as stat9 } from "fs/
7931
7984
  import { join as join28 } from "path";
7932
7985
  var COUNTED_DIRS2 = ["_memory", "worklog", "decision-log"];
7933
7986
  var DEFAULT_GAP_WINDOW_DAYS = 30;
7987
+ function gapWindowSinceArg() {
7988
+ return `${DEFAULT_GAP_WINDOW_DAYS} days ago`;
7989
+ }
7934
7990
  var BOOT_BANNER = String.raw`
7935
7991
  __ __ _ _____ __
7936
7992
  \ \ / ___ _ _| |_| __\ \/ /
@@ -8131,7 +8187,7 @@ function renderSessionStartReport(report, extras) {
8131
8187
  lines.push(`- always-on rules (loaded below): ${slugs}${over}`);
8132
8188
  }
8133
8189
  if (report.memoryIndexStale) {
8134
- lines.push("- \u26A0\uFE0F memory index may be stale \u2014 run `npx vortex reindex _memory`");
8190
+ lines.push("- \u2139\uFE0F memory index is stale (auto-reindex off or failed) \u2014 recent memories may be missing from the index.");
8135
8191
  }
8136
8192
  const handoffs = report.handoffs ?? [];
8137
8193
  const nextUp = report.nextUp ?? [];
@@ -8171,14 +8227,14 @@ function renderSessionStartReport(report, extras) {
8171
8227
  }
8172
8228
  const gaps = extras?.missingWorklogDays ?? [];
8173
8229
  if (gaps.length) {
8174
- lines.push(`- \u26A0\uFE0F work without a worklog: ${gaps.join(", ")} \u2014 backfill from that day's commits`);
8230
+ lines.push(`- \u21A9\uFE0F no worklog yet for: ${gaps.join(", ")} \u2014 backfill from that day's session archive or commits.`);
8175
8231
  }
8176
8232
  const carry = extras?.carryover;
8177
8233
  if (carry?.interrupted) {
8178
8234
  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
8235
  }
8180
8236
  if (carry && carry.uncommitted > 0) {
8181
- lines.push(`- \u21A9\uFE0F ${carry.uncommitted} uncommitted change(s) carried over from a prior session \u2014 run \`/resume\` if you're unsure they were meant to stay.`);
8237
+ lines.push(`- \u21A9\uFE0F ${carry.uncommitted} uncommitted change(s) carried over from a prior session \u2014 likely normal work in progress.`);
8182
8238
  }
8183
8239
  const cu = extras?.catchUp;
8184
8240
  if (cu && (cu.ingestedLocal > 0 || cu.indexedPulled > 0 || cu.errors > 0)) {
@@ -8379,56 +8435,11 @@ function isoDate2(d2) {
8379
8435
  return `${y2}-${m2}-${day}`;
8380
8436
  }
8381
8437
 
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
8438
  // ../plugins/session-rituals/dist/curate-cli.js
8428
8439
  import { existsSync as existsSync15 } from "fs";
8429
8440
  import { createHash as createHash3 } from "crypto";
8430
8441
  import { readFile as readFile23, readdir as readdir18 } from "fs/promises";
8431
- import { join as join30 } from "path";
8442
+ import { join as join29 } from "path";
8432
8443
  var SYSTEM_META_DIRS3 = /* @__PURE__ */ new Set([
8433
8444
  "worklog",
8434
8445
  "decision-log",
@@ -8508,7 +8519,7 @@ function joinRel(...parts) {
8508
8519
  }
8509
8520
  async function runCurateCandidates(repoRoot, options) {
8510
8521
  const maxEntries = options?.maxEntries ?? 200;
8511
- const dataDir = join30(repoRoot, "data");
8522
+ const dataDir = join29(repoRoot, "data");
8512
8523
  const candidates = [];
8513
8524
  let truncated = false;
8514
8525
  if (existsSync15(dataDir)) {
@@ -8534,7 +8545,7 @@ async function runCurateCandidates(repoRoot, options) {
8534
8545
  continue;
8535
8546
  if (atRoot && (SYSTEM_META_DIRS3.has(e.name) || e.name.startsWith("_")))
8536
8547
  continue;
8537
- await visit(join30(absDir, e.name), joinRel(relDir, e.name));
8548
+ await visit(join29(absDir, e.name), joinRel(relDir, e.name));
8538
8549
  } else if (e.isFile() && e.name.endsWith(".md")) {
8539
8550
  if (NON_DOC_FILES.has(e.name))
8540
8551
  continue;
@@ -8543,7 +8554,7 @@ async function runCurateCandidates(repoRoot, options) {
8543
8554
  let topic = null;
8544
8555
  let tags = [];
8545
8556
  try {
8546
- const raw = await readFile23(join30(absDir, e.name), "utf8");
8557
+ const raw = await readFile23(join29(absDir, e.name), "utf8");
8547
8558
  const parsed = parseFrontmatter(raw);
8548
8559
  if (typeof parsed.frontmatter.topic === "string") {
8549
8560
  topic = parsed.frontmatter.topic.trim().toLowerCase();
@@ -8581,7 +8592,7 @@ async function runCuratePreview(repoRoot, payload, now = /* @__PURE__ */ new Dat
8581
8592
  };
8582
8593
  }
8583
8594
  try {
8584
- validateDataRelativePath(join30(repoRoot, "data"), v2.effectiveRelPath);
8595
+ validateDataRelativePath(join29(repoRoot, "data"), v2.effectiveRelPath);
8585
8596
  } catch (e) {
8586
8597
  return {
8587
8598
  subcommand: "curate-preview",
@@ -8598,10 +8609,10 @@ async function runCuratePreview(repoRoot, payload, now = /* @__PURE__ */ new Dat
8598
8609
  let targetExists;
8599
8610
  let wouldDo;
8600
8611
  if (payload.action === "create-file") {
8601
- targetExists = existsSync15(join30(repoRoot, "data", v2.effectiveRelPath));
8612
+ targetExists = existsSync15(join29(repoRoot, "data", v2.effectiveRelPath));
8602
8613
  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
8614
  } else {
8604
- targetExists = existsSync15(join30(repoRoot, "data", v2.effectiveRelPath));
8615
+ targetExists = existsSync15(join29(repoRoot, "data", v2.effectiveRelPath));
8605
8616
  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
8617
  }
8607
8618
  const nextActions = [];
@@ -8812,7 +8823,7 @@ async function runVortexCli(argv, io) {
8812
8823
  Commands:
8813
8824
  ${names}
8814
8825
  session-start \u2014 emit the start-of-session boot report (git pull + data counts + catch-up)
8815
- session-end \u2014 worklog safety net (create today's worklog if work happened and none exists)
8826
+ session-end \u2014 no-op (kept for hook compatibility; worklog gap handling is at session-start)
8816
8827
  check-updates \u2014 check the npm registry for a newer @vortex-os/base (read-only; prints the exact update command)
8817
8828
 
8818
8829
  Instance shortcuts (also available as \`/vortex <sub>\`):
@@ -8880,7 +8891,7 @@ function memoryExtendedPresent() {
8880
8891
  }
8881
8892
  var VECTORIZE_LOCK_TTL_MS = 6 * 60 * 60 * 1e3;
8882
8893
  function vectorizeLockPath(ctx) {
8883
- return join31(ctx.dataDir, "_indexes", ".vectorize.lock");
8894
+ return join30(ctx.dataDir, "_indexes", ".vectorize.lock");
8884
8895
  }
8885
8896
  function vectorizeSetupInProgress(ctx) {
8886
8897
  const lock = vectorizeLockPath(ctx);
@@ -8906,8 +8917,8 @@ function spawnVectorizeSetup(repoRoot) {
8906
8917
  }
8907
8918
  async function runVectorizeSetup(repoRoot, out, err) {
8908
8919
  const ctx = makeContext(repoRoot);
8909
- const indexDir = join31(ctx.dataDir, "_indexes");
8910
- const finalDb = join31(indexDir, "memory.sqlite");
8920
+ const indexDir = join30(ctx.dataDir, "_indexes");
8921
+ const finalDb = join30(indexDir, "memory.sqlite");
8911
8922
  if (existsSync16(finalDb)) {
8912
8923
  out("recall index already present \u2014 nothing to do\n");
8913
8924
  return;
@@ -8939,7 +8950,7 @@ async function runVectorizeSetup(repoRoot, out, err) {
8939
8950
  return;
8940
8951
  }
8941
8952
  }
8942
- const tmpDb = join31(indexDir, `memory.sqlite.building-${process.pid}`);
8953
+ const tmpDb = join30(indexDir, `memory.sqlite.building-${process.pid}`);
8943
8954
  const tmpSidecars = [tmpDb + "-wal", tmpDb + "-shm", tmpDb + "-journal"];
8944
8955
  const cleanTmp = () => {
8945
8956
  rmSync(tmpDb, { force: true });
@@ -8967,7 +8978,7 @@ async function runVectorizeSetup(repoRoot, out, err) {
8967
8978
  return;
8968
8979
  }
8969
8980
  cleanTmp();
8970
- const { vectorizeIndex } = await import("./vectorize-PN4Y7XMO.js");
8981
+ const { vectorizeIndex } = await import("./vectorize-RBDBTSTW.js");
8971
8982
  const result = await vectorizeIndex(ctx, { dbPath: tmpDb, allowDownload: true });
8972
8983
  const sqliteSpecifier = "better-sqlite3";
8973
8984
  const mod = await import(sqliteSpecifier);
@@ -9028,18 +9039,23 @@ async function runSessionStart(repoRoot, out) {
9028
9039
  }
9029
9040
  const bookkeepingPrefix = frameworkBookkeepingPrefix(ctx);
9030
9041
  const carryover = collectCarryover(repoRoot, (p) => p.startsWith(bookkeepingPrefix));
9042
+ if (config.autoRecord.reindex && !git2?.conflict) {
9043
+ await autoReindexMemory(ctx);
9044
+ }
9031
9045
  const report = await collectSessionStartReport(ctx, { environment });
9032
9046
  let missingWorklogDays = [];
9033
- try {
9034
- const log = gitOut(repoRoot, ["log", "--since=7 days ago", "--pretty=%cd", "--date=short"]);
9035
- const commitDays = log.split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
9036
- missingWorklogDays = detectWorklogGaps(commitDays, report.recentWorklogDates);
9037
- } catch {
9047
+ if (config.autoRecord.worklog && config.autoRecord.backfill && !git2?.conflict) {
9048
+ try {
9049
+ const log = gitOut(repoRoot, ["log", `--since=${gapWindowSinceArg()}`, "--pretty=%cd", "--date=short"]);
9050
+ const commitDays = log.split(/\r?\n/).map((s) => s.trim()).filter(Boolean);
9051
+ missingWorklogDays = detectWorklogGaps(commitDays, report.recentWorklogDates);
9052
+ } catch {
9053
+ }
9038
9054
  }
9039
9055
  let catchUp = null;
9040
9056
  if (config.autoRecord.archive) {
9041
9057
  try {
9042
- const { catchUpSessions: catchUpSessions2 } = await import("./catch-up-GDDKPZHJ.js");
9058
+ const { catchUpSessions: catchUpSessions2 } = await import("./catch-up-KIHTAUPX.js");
9043
9059
  catchUp = await catchUpSessions2(ctx);
9044
9060
  } catch {
9045
9061
  }
@@ -9057,7 +9073,7 @@ async function runSessionStart(repoRoot, out) {
9057
9073
  let vectorized = null;
9058
9074
  let vectorizeSetupStarted = false;
9059
9075
  if (config.autoRecord.vectorize) {
9060
- const dbExists = existsSync16(join31(ctx.dataDir, "_indexes", "memory.sqlite"));
9076
+ const dbExists = existsSync16(join30(ctx.dataDir, "_indexes", "memory.sqlite"));
9061
9077
  const action = decideVectorizeAction({
9062
9078
  vectorizeOn: true,
9063
9079
  dbExists,
@@ -9068,7 +9084,7 @@ async function runSessionStart(repoRoot, out) {
9068
9084
  });
9069
9085
  if (action === "inline") {
9070
9086
  try {
9071
- const { vectorizeIndex } = await import("./vectorize-PN4Y7XMO.js");
9087
+ const { vectorizeIndex } = await import("./vectorize-RBDBTSTW.js");
9072
9088
  vectorized = await vectorizeIndex(ctx);
9073
9089
  } catch {
9074
9090
  }
@@ -9122,17 +9138,7 @@ async function runSessionStart(repoRoot, out) {
9122
9138
  handoffPrune: handoffPrune ?? void 0
9123
9139
  }));
9124
9140
  }
9125
- async function runSessionEnd(repoRoot, out) {
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
- }
9141
+ async function runSessionEnd(_repoRoot, _out) {
9136
9142
  }
9137
9143
  function gitOut(cwd, gitArgs) {
9138
9144
  return execFileSync2("git", [...gitArgs], {
@@ -9156,7 +9162,7 @@ function detectInterruptedGitOp(repoRoot) {
9156
9162
  const resolved = gitOut(repoRoot, args).split(/\r?\n/).map((s) => s.trim());
9157
9163
  for (let i = 0; i < markers.length; i++) {
9158
9164
  const p = resolved[i];
9159
- if (p && existsSync16(isAbsolute5(p) ? p : join31(repoRoot, p)))
9165
+ if (p && existsSync16(isAbsolute5(p) ? p : join30(repoRoot, p)))
9160
9166
  return markers[i];
9161
9167
  }
9162
9168
  } catch {
@@ -9172,19 +9178,6 @@ function collectCarryover(repoRoot, ignore) {
9172
9178
  }
9173
9179
  return uncommitted > 0 || interrupted ? { uncommitted, interrupted } : null;
9174
9180
  }
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
9181
  function resolveSessionEnvironment(ctx, config) {
9189
9182
  let environment = resolveEnvironment(config, {
9190
9183
  hostname: hostname(),
@@ -9194,7 +9187,7 @@ function resolveSessionEnvironment(ctx, config) {
9194
9187
  if (!environment)
9195
9188
  environment = process.env.VORTEX_ENV?.trim() || null;
9196
9189
  if (!environment) {
9197
- const envFile = join31(ctx.repoRoot, ".agent", "environment");
9190
+ const envFile = join30(ctx.repoRoot, ".agent", "environment");
9198
9191
  if (existsSync16(envFile)) {
9199
9192
  environment = readFileSync4(envFile, "utf8").split(/\r?\n/)[0]?.trim() || null;
9200
9193
  }
@@ -9203,9 +9196,9 @@ function resolveSessionEnvironment(ctx, config) {
9203
9196
  }
9204
9197
 
9205
9198
  // ../plugins/session-rituals/dist/ambient-recall.js
9206
- import { join as join32 } from "path";
9199
+ import { join as join31 } from "path";
9207
9200
  function defaultDbPath2(ctx) {
9208
- return join32(ctx.dataDir, "_indexes", "memory.sqlite");
9201
+ return join31(ctx.dataDir, "_indexes", "memory.sqlite");
9209
9202
  }
9210
9203
  function createAmbientRecaller(ctx, options) {
9211
9204
  const resolveDb = options.dbPath ?? defaultDbPath2;
@@ -9240,6 +9233,51 @@ function createAmbientRecaller(ctx, options) {
9240
9233
  }
9241
9234
  });
9242
9235
  }
9236
+
9237
+ // ../plugins/session-rituals/dist/worklog-write.js
9238
+ import { mkdir as mkdir10, writeFile as writeFile12 } from "fs/promises";
9239
+ import { dirname as dirname6, join as join32 } from "path";
9240
+ async function ensureWorklogEntry(ctx, opts) {
9241
+ const now = opts?.now ?? /* @__PURE__ */ new Date();
9242
+ const date = isoDate3(now);
9243
+ const time = isoTime2(now);
9244
+ const keyword = (opts?.keyword ?? "worklog").trim() || "worklog";
9245
+ const store = new WorklogStore(join32(ctx.dataDir, "worklog"));
9246
+ const existing = await store.get(date);
9247
+ if (existing) {
9248
+ return { path: existing.path, date: existing.date, keyword: existing.keyword, created: false };
9249
+ }
9250
+ const path = store.pathFor(date, keyword, time);
9251
+ const title = opts?.title ?? `${date} worklog`;
9252
+ await mkdir10(dirname6(path), { recursive: true });
9253
+ await writeFile12(path, renderWorklogFile(date, title, opts?.body ?? ""), "utf8");
9254
+ return { path, date, keyword, created: true };
9255
+ }
9256
+ function renderWorklogFile(date, title, body) {
9257
+ const trimmed = body.trimEnd();
9258
+ return `---
9259
+ type: worklog
9260
+ created: ${date}
9261
+ updated: ${date}
9262
+ tags: [worklog]
9263
+ ---
9264
+
9265
+ # ${title}
9266
+ ` + (trimmed ? `
9267
+ ${trimmed}
9268
+ ` : ``);
9269
+ }
9270
+ function isoDate3(d2) {
9271
+ const y2 = d2.getFullYear();
9272
+ const m2 = String(d2.getMonth() + 1).padStart(2, "0");
9273
+ const day = String(d2.getDate()).padStart(2, "0");
9274
+ return `${y2}-${m2}-${day}`;
9275
+ }
9276
+ function isoTime2(d2) {
9277
+ const h = String(d2.getHours()).padStart(2, "0");
9278
+ const m2 = String(d2.getMinutes()).padStart(2, "0");
9279
+ return `${h}${m2}`;
9280
+ }
9243
9281
  export {
9244
9282
  dist_exports5 as aiCodingPitfalls,
9245
9283
  dist_exports as core,