@vemdev/cli 0.1.48 → 0.1.50

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.
@@ -56,7 +56,7 @@ function maskProviderKey(plaintext) {
56
56
  }
57
57
 
58
58
  // ../../packages/core/dist/agent.js
59
- import path5 from "path";
59
+ import path6 from "path";
60
60
 
61
61
  // ../../node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/external.js
62
62
  var external_exports = {};
@@ -14094,7 +14094,7 @@ var WebhookDeliverySchema = external_exports.object({
14094
14094
  });
14095
14095
 
14096
14096
  // ../../packages/core/dist/agent.js
14097
- import fs5 from "fs-extra";
14097
+ import fs6 from "fs-extra";
14098
14098
 
14099
14099
  // ../../packages/core/dist/fs.js
14100
14100
  import path from "path";
@@ -14290,14 +14290,109 @@ ${entry.content}`;
14290
14290
  }
14291
14291
  };
14292
14292
 
14293
+ // ../../packages/core/dist/cycles.js
14294
+ import path3 from "path";
14295
+ import fs3 from "fs-extra";
14296
+ var CycleService = class {
14297
+ async getCyclesDir() {
14298
+ const vemDir = await getVemDir();
14299
+ const dir = path3.join(vemDir, CYCLES_DIR);
14300
+ await fs3.ensureDir(dir);
14301
+ return dir;
14302
+ }
14303
+ cycleFilePath(dir, id) {
14304
+ return path3.join(dir, `${id}.json`);
14305
+ }
14306
+ async getNextCycleId(dir) {
14307
+ let maxNum = 0;
14308
+ const entries = await fs3.readdir(dir).catch(() => []);
14309
+ for (const entry of entries) {
14310
+ const match = entry.match(/^CYCLE-(\d{3,})\.json$/);
14311
+ if (match) {
14312
+ const num = parseInt(match[1], 10);
14313
+ if (!Number.isNaN(num) && num > maxNum) {
14314
+ maxNum = num;
14315
+ }
14316
+ }
14317
+ }
14318
+ return `CYCLE-${String(maxNum + 1).padStart(3, "0")}`;
14319
+ }
14320
+ async createCycle(input) {
14321
+ const dir = await this.getCyclesDir();
14322
+ const id = await this.getNextCycleId(dir);
14323
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
14324
+ const cycle = {
14325
+ id,
14326
+ name: input.name,
14327
+ goal: input.goal,
14328
+ appetite: input.appetite,
14329
+ status: "planned",
14330
+ start_at: input.start_at,
14331
+ created_at: timestamp,
14332
+ updated_at: timestamp
14333
+ };
14334
+ await fs3.writeJson(this.cycleFilePath(dir, id), cycle, { spaces: 2 });
14335
+ return cycle;
14336
+ }
14337
+ async getCycles() {
14338
+ const dir = await this.getCyclesDir();
14339
+ const entries = await fs3.readdir(dir).catch(() => []);
14340
+ const cycles = [];
14341
+ for (const entry of entries) {
14342
+ if (!entry.endsWith(".json"))
14343
+ continue;
14344
+ try {
14345
+ const cycle = await fs3.readJson(path3.join(dir, entry));
14346
+ if (cycle?.id)
14347
+ cycles.push(cycle);
14348
+ } catch {
14349
+ }
14350
+ }
14351
+ return cycles.sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
14352
+ }
14353
+ async getCycle(id) {
14354
+ const dir = await this.getCyclesDir();
14355
+ const filePath = this.cycleFilePath(dir, id);
14356
+ if (!await fs3.pathExists(filePath))
14357
+ return null;
14358
+ try {
14359
+ return await fs3.readJson(filePath);
14360
+ } catch {
14361
+ return null;
14362
+ }
14363
+ }
14364
+ async updateCycle(id, patch) {
14365
+ const dir = await this.getCyclesDir();
14366
+ const filePath = this.cycleFilePath(dir, id);
14367
+ const current = await this.getCycle(id);
14368
+ if (!current) {
14369
+ throw new Error(`Cycle ${id} not found`);
14370
+ }
14371
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
14372
+ const updated = { ...current, ...patch, id, updated_at: timestamp };
14373
+ if (patch.status === "active" && current.status !== "active") {
14374
+ updated.start_at = updated.start_at ?? timestamp;
14375
+ }
14376
+ if (patch.status === "closed" && current.status !== "closed") {
14377
+ updated.closed_at = updated.closed_at ?? timestamp;
14378
+ }
14379
+ await fs3.writeJson(filePath, updated, { spaces: 2 });
14380
+ return updated;
14381
+ }
14382
+ async getActiveCycle() {
14383
+ const cycles = await this.getCycles();
14384
+ return cycles.find((c) => c.status === "active") ?? null;
14385
+ }
14386
+ };
14387
+
14293
14388
  // ../../packages/core/dist/tasks.js
14294
- import path4 from "path";
14295
- import fs4 from "fs-extra";
14389
+ import path5 from "path";
14390
+ import fs5 from "fs-extra";
14296
14391
 
14297
14392
  // ../../packages/core/dist/sharded-fs.js
14298
14393
  import crypto from "crypto";
14299
- import path3 from "path";
14300
- import fs3 from "fs-extra";
14394
+ import path4 from "path";
14395
+ import fs4 from "fs-extra";
14301
14396
  var ShardedFileStorage = class {
14302
14397
  baseDir;
14303
14398
  objectsDirName;
@@ -14306,7 +14401,7 @@ var ShardedFileStorage = class {
14306
14401
  this.objectsDirName = objectsDirName;
14307
14402
  }
14308
14403
  getObjectsDir() {
14309
- return path3.join(this.baseDir, this.objectsDirName);
14404
+ return path4.join(this.baseDir, this.objectsDirName);
14310
14405
  }
14311
14406
  getShard(id) {
14312
14407
  const hash2 = crypto.createHash("sha1").update(id).digest("hex");
@@ -14314,42 +14409,42 @@ var ShardedFileStorage = class {
14314
14409
  }
14315
14410
  getFilePath(id) {
14316
14411
  const shard = this.getShard(id);
14317
- return path3.join(this.getObjectsDir(), shard, `${id}.json`);
14412
+ return path4.join(this.getObjectsDir(), shard, `${id}.json`);
14318
14413
  }
14319
14414
  async save(record2) {
14320
14415
  const filePath = this.getFilePath(record2.id);
14321
- await fs3.ensureDir(path3.dirname(filePath));
14322
- await fs3.writeJson(filePath, record2, { spaces: 2 });
14416
+ await fs4.ensureDir(path4.dirname(filePath));
14417
+ await fs4.writeJson(filePath, record2, { spaces: 2 });
14323
14418
  }
14324
14419
  async load(id) {
14325
14420
  const filePath = this.getFilePath(id);
14326
- if (!await fs3.pathExists(filePath)) {
14421
+ if (!await fs4.pathExists(filePath)) {
14327
14422
  return null;
14328
14423
  }
14329
- return fs3.readJson(filePath);
14424
+ return fs4.readJson(filePath);
14330
14425
  }
14331
14426
  async delete(id) {
14332
14427
  const filePath = this.getFilePath(id);
14333
- if (await fs3.pathExists(filePath)) {
14334
- await fs3.remove(filePath);
14428
+ if (await fs4.pathExists(filePath)) {
14429
+ await fs4.remove(filePath);
14335
14430
  }
14336
14431
  }
14337
14432
  async listIds() {
14338
14433
  const objectsDir = this.getObjectsDir();
14339
- if (!await fs3.pathExists(objectsDir)) {
14434
+ if (!await fs4.pathExists(objectsDir)) {
14340
14435
  return [];
14341
14436
  }
14342
- const shards = await fs3.readdir(objectsDir);
14437
+ const shards = await fs4.readdir(objectsDir);
14343
14438
  const ids = [];
14344
14439
  for (const shard of shards) {
14345
- const shardPath = path3.join(objectsDir, shard);
14346
- const stat = await fs3.stat(shardPath);
14440
+ const shardPath = path4.join(objectsDir, shard);
14441
+ const stat = await fs4.stat(shardPath);
14347
14442
  if (!stat.isDirectory())
14348
14443
  continue;
14349
- const files = await fs3.readdir(shardPath);
14444
+ const files = await fs4.readdir(shardPath);
14350
14445
  for (const file2 of files) {
14351
14446
  if (file2.endsWith(".json")) {
14352
- ids.push(path3.parse(file2).name);
14447
+ ids.push(path4.parse(file2).name);
14353
14448
  }
14354
14449
  }
14355
14450
  }
@@ -14370,22 +14465,22 @@ var ShardedFileStorage = class {
14370
14465
  var TaskIndex = class {
14371
14466
  indexPath;
14372
14467
  constructor(baseDir) {
14373
- this.indexPath = path3.join(baseDir, "index.json");
14468
+ this.indexPath = path4.join(baseDir, "index.json");
14374
14469
  }
14375
14470
  async load() {
14376
- if (!await fs3.pathExists(this.indexPath)) {
14471
+ if (!await fs4.pathExists(this.indexPath)) {
14377
14472
  return [];
14378
14473
  }
14379
14474
  try {
14380
- const data = await fs3.readJson(this.indexPath);
14475
+ const data = await fs4.readJson(this.indexPath);
14381
14476
  return data.entries || [];
14382
14477
  } catch {
14383
14478
  return [];
14384
14479
  }
14385
14480
  }
14386
14481
  async save(entries) {
14387
- await fs3.ensureDir(path3.dirname(this.indexPath));
14388
- await fs3.writeJson(this.indexPath, { entries }, { spaces: 2 });
14482
+ await fs4.ensureDir(path4.dirname(this.indexPath));
14483
+ await fs4.writeJson(this.indexPath, { entries }, { spaces: 2 });
14389
14484
  }
14390
14485
  async updateEntry(entry) {
14391
14486
  const entries = await this.load();
@@ -14422,8 +14517,8 @@ var TaskService = class {
14422
14517
  return { storage: this.storage, index: this.index };
14423
14518
  }
14424
14519
  const vemDir = await getVemDir();
14425
- const baseDir = path4.join(vemDir, TASKS_DIR);
14426
- await fs4.ensureDir(baseDir);
14520
+ const baseDir = path5.join(vemDir, TASKS_DIR);
14521
+ await fs5.ensureDir(baseDir);
14427
14522
  this.storage = new ShardedFileStorage(baseDir);
14428
14523
  this.index = new TaskIndex(baseDir);
14429
14524
  return { storage: this.storage, index: this.index };
@@ -14441,16 +14536,16 @@ var TaskService = class {
14441
14536
  }
14442
14537
  async loadRecentArchivedTasks(withinDays) {
14443
14538
  const vemDir = await getVemDir();
14444
- const archiveDir = path4.join(vemDir, TASKS_DIR, "archive");
14445
- if (!await fs4.pathExists(archiveDir))
14539
+ const archiveDir = path5.join(vemDir, TASKS_DIR, "archive");
14540
+ if (!await fs5.pathExists(archiveDir))
14446
14541
  return [];
14447
14542
  const cutoff = Date.now() - withinDays * 24 * 60 * 60 * 1e3;
14448
14543
  const result = [];
14449
14544
  const walk = async (dir) => {
14450
- const entries = await fs4.readdir(dir);
14545
+ const entries = await fs5.readdir(dir);
14451
14546
  for (const entry of entries) {
14452
- const fullPath = path4.join(dir, entry);
14453
- const stat = await fs4.stat(fullPath);
14547
+ const fullPath = path5.join(dir, entry);
14548
+ const stat = await fs5.stat(fullPath);
14454
14549
  if (stat.isDirectory()) {
14455
14550
  await walk(fullPath);
14456
14551
  continue;
@@ -14460,7 +14555,7 @@ var TaskService = class {
14460
14555
  if (stat.mtimeMs < cutoff)
14461
14556
  continue;
14462
14557
  try {
14463
- const task = await fs4.readJson(fullPath);
14558
+ const task = await fs5.readJson(fullPath);
14464
14559
  if (task?.id)
14465
14560
  result.push(task);
14466
14561
  } catch {
@@ -14480,23 +14575,23 @@ var TaskService = class {
14480
14575
  }
14481
14576
  async listArchivedTaskIds() {
14482
14577
  const vemDir = await getVemDir();
14483
- const archiveDir = path4.join(vemDir, TASKS_DIR, "archive");
14484
- if (!await fs4.pathExists(archiveDir)) {
14578
+ const archiveDir = path5.join(vemDir, TASKS_DIR, "archive");
14579
+ if (!await fs5.pathExists(archiveDir)) {
14485
14580
  return [];
14486
14581
  }
14487
14582
  const ids = [];
14488
14583
  const walk = async (dir) => {
14489
- const entries = await fs4.readdir(dir);
14584
+ const entries = await fs5.readdir(dir);
14490
14585
  for (const entry of entries) {
14491
- const fullPath = path4.join(dir, entry);
14492
- const stat = await fs4.stat(fullPath);
14586
+ const fullPath = path5.join(dir, entry);
14587
+ const stat = await fs5.stat(fullPath);
14493
14588
  if (stat.isDirectory()) {
14494
14589
  await walk(fullPath);
14495
14590
  continue;
14496
14591
  }
14497
14592
  if (!entry.endsWith(".json"))
14498
14593
  continue;
14499
- const id = path4.parse(entry).name;
14594
+ const id = path5.parse(entry).name;
14500
14595
  if (/^TASK-\d{3,}$/.test(id)) {
14501
14596
  ids.push(id);
14502
14597
  }
@@ -14879,19 +14974,19 @@ var TaskService = class {
14879
14974
  if (candidates.length === 0)
14880
14975
  return 0;
14881
14976
  const vemDir = await getVemDir();
14882
- const baseDir = path4.join(vemDir, TASKS_DIR);
14883
- const archiveBase = path4.join(baseDir, "archive");
14884
- await fs4.ensureDir(archiveBase);
14977
+ const baseDir = path5.join(vemDir, TASKS_DIR);
14978
+ const archiveBase = path5.join(baseDir, "archive");
14979
+ await fs5.ensureDir(archiveBase);
14885
14980
  let count = 0;
14886
14981
  for (const entry of candidates) {
14887
14982
  const task = await storage.load(entry.id);
14888
14983
  if (task) {
14889
14984
  const date5 = new Date(task.created_at || /* @__PURE__ */ new Date());
14890
14985
  const folder = `${date5.getFullYear()}-${String(date5.getMonth() + 1).padStart(2, "0")}`;
14891
- const targetDir = path4.join(archiveBase, folder);
14892
- await fs4.ensureDir(targetDir);
14893
- const destWithId = path4.join(targetDir, `${task.id}.json`);
14894
- await fs4.writeJson(destWithId, task, { spaces: 2 });
14986
+ const targetDir = path5.join(archiveBase, folder);
14987
+ await fs5.ensureDir(targetDir);
14988
+ const destWithId = path5.join(targetDir, `${task.id}.json`);
14989
+ await fs5.writeJson(destWithId, task, { spaces: 2 });
14895
14990
  await storage.delete(entry.id);
14896
14991
  await index.removeEntry(entry.id);
14897
14992
  count++;
@@ -15152,9 +15247,18 @@ async function applyVemUpdate(update) {
15152
15247
  }
15153
15248
  const currentStateUpdated = await writeCurrentState(update.current_state);
15154
15249
  const contextUpdated = await writeContext(update.context);
15250
+ const newCycles = [];
15251
+ if (update.new_cycles?.length) {
15252
+ const cycleService = new CycleService();
15253
+ for (const entry of update.new_cycles) {
15254
+ const created = await cycleService.createCycle(entry);
15255
+ newCycles.push(created);
15256
+ }
15257
+ }
15155
15258
  return {
15156
15259
  updatedTasks,
15157
15260
  newTasks,
15261
+ newCycles,
15158
15262
  changelogLines,
15159
15263
  decisionsAppended,
15160
15264
  decisionsAppendedRef,
@@ -15202,20 +15306,20 @@ async function writeCurrentState(value) {
15202
15306
  if (value === void 0)
15203
15307
  return false;
15204
15308
  const dir = await getVemDir();
15205
- const currentStatePath = path5.join(dir, CURRENT_STATE_FILE);
15309
+ const currentStatePath = path6.join(dir, CURRENT_STATE_FILE);
15206
15310
  const next = value.trim().length > 0 ? `${value.trim()}
15207
15311
  ` : "";
15208
- await fs5.writeFile(currentStatePath, next, "utf-8");
15312
+ await fs6.writeFile(currentStatePath, next, "utf-8");
15209
15313
  return true;
15210
15314
  }
15211
15315
  async function writeContext(value) {
15212
15316
  if (value === void 0)
15213
15317
  return false;
15214
15318
  const dir = await getVemDir();
15215
- const contextPath = path5.join(dir, CONTEXT_FILE);
15319
+ const contextPath = path6.join(dir, CONTEXT_FILE);
15216
15320
  const next = value.trim().length > 0 ? `${value.trim()}
15217
15321
  ` : "";
15218
- await fs5.writeFile(contextPath, next, "utf-8");
15322
+ await fs6.writeFile(contextPath, next, "utf-8");
15219
15323
  return true;
15220
15324
  }
15221
15325
 
@@ -15275,23 +15379,23 @@ async function computeSessionStats(sessionId, source) {
15275
15379
  // ../../packages/core/dist/config.js
15276
15380
  import { randomUUID } from "crypto";
15277
15381
  import { homedir, hostname as hostname3 } from "os";
15278
- import path6 from "path";
15279
- import fs6 from "fs-extra";
15382
+ import path7 from "path";
15383
+ import fs7 from "fs-extra";
15280
15384
  var CONFIG_FILE = "config.json";
15281
15385
  var ConfigService = class {
15282
15386
  async getLocalPath() {
15283
15387
  const dir = await getVemDir();
15284
- return path6.join(dir, CONFIG_FILE);
15388
+ return path7.join(dir, CONFIG_FILE);
15285
15389
  }
15286
15390
  getGlobalPath() {
15287
- return path6.join(homedir(), ".vem", CONFIG_FILE);
15391
+ return path7.join(homedir(), ".vem", CONFIG_FILE);
15288
15392
  }
15289
15393
  async readLocalConfig() {
15290
15394
  try {
15291
15395
  const filePath = await this.getLocalPath();
15292
- if (!await fs6.pathExists(filePath))
15396
+ if (!await fs7.pathExists(filePath))
15293
15397
  return {};
15294
- return fs6.readJson(filePath);
15398
+ return fs7.readJson(filePath);
15295
15399
  } catch {
15296
15400
  return {};
15297
15401
  }
@@ -15299,9 +15403,9 @@ var ConfigService = class {
15299
15403
  async readGlobalConfig() {
15300
15404
  try {
15301
15405
  const filePath = this.getGlobalPath();
15302
- if (!await fs6.pathExists(filePath))
15406
+ if (!await fs7.pathExists(filePath))
15303
15407
  return {};
15304
- return fs6.readJson(filePath);
15408
+ return fs7.readJson(filePath);
15305
15409
  } catch {
15306
15410
  return {};
15307
15411
  }
@@ -15320,7 +15424,7 @@ var ConfigService = class {
15320
15424
  last_push_vem_hash: next.last_push_vem_hash,
15321
15425
  last_synced_vem_hash: next.last_synced_vem_hash
15322
15426
  };
15323
- await fs6.outputJson(filePath, clean, { spaces: 2 });
15427
+ await fs7.outputJson(filePath, clean, { spaces: 2 });
15324
15428
  }
15325
15429
  async writeGlobalConfig(update) {
15326
15430
  const filePath = this.getGlobalPath();
@@ -15331,7 +15435,7 @@ var ConfigService = class {
15331
15435
  device_id: next.device_id,
15332
15436
  device_name: next.device_name
15333
15437
  };
15334
- await fs6.outputJson(filePath, clean, { spaces: 2 });
15438
+ await fs7.outputJson(filePath, clean, { spaces: 2 });
15335
15439
  }
15336
15440
  // --- Global Scoped ---
15337
15441
  async getApiKey() {
@@ -15426,23 +15530,23 @@ var ConfigService = class {
15426
15530
  async getContextPath() {
15427
15531
  try {
15428
15532
  const dir = await getVemDir();
15429
- return path6.join(dir, CONTEXT_FILE);
15533
+ return path7.join(dir, CONTEXT_FILE);
15430
15534
  } catch {
15431
15535
  return "";
15432
15536
  }
15433
15537
  }
15434
15538
  async getContext() {
15435
15539
  const filePath = await this.getContextPath();
15436
- if (!filePath || !await fs6.pathExists(filePath)) {
15540
+ if (!filePath || !await fs7.pathExists(filePath)) {
15437
15541
  return "";
15438
15542
  }
15439
- return fs6.readFile(filePath, "utf-8");
15543
+ return fs7.readFile(filePath, "utf-8");
15440
15544
  }
15441
15545
  async updateContext(content) {
15442
15546
  const filePath = await this.getContextPath();
15443
15547
  if (!filePath)
15444
15548
  throw new Error("Cannot update context: Not in a git repository.");
15445
- await fs6.writeFile(filePath, content, "utf-8");
15549
+ await fs7.writeFile(filePath, content, "utf-8");
15446
15550
  }
15447
15551
  async recordDecision(title, context, decision, relatedTasks) {
15448
15552
  const decisionsLog = new ScalableLogService(DECISIONS_DIR);
@@ -15461,8 +15565,8 @@ ${entry}`;
15461
15565
 
15462
15566
  // ../../packages/core/dist/diff.js
15463
15567
  import { createHash } from "crypto";
15464
- import path7 from "path";
15465
- import fs7 from "fs-extra";
15568
+ import path8 from "path";
15569
+ import fs8 from "fs-extra";
15466
15570
  var DiffService = class {
15467
15571
  async compareWithLastPush(_lastPushData) {
15468
15572
  const vemDir = await getVemDir();
@@ -15472,12 +15576,12 @@ var DiffService = class {
15472
15576
  const decisions = await decisionsService.getAllEntries();
15473
15577
  const changelogService = new ScalableLogService(CHANGELOG_DIR);
15474
15578
  const changelog = await changelogService.getAllEntries();
15475
- const currentStatePath = path7.join(vemDir, CURRENT_STATE_FILE);
15476
- const currentStateExists = await fs7.pathExists(currentStatePath);
15477
- const currentStateContent = currentStateExists ? await fs7.readFile(currentStatePath, "utf-8") : "";
15478
- const contextPath = path7.join(vemDir, CONTEXT_FILE);
15479
- const contextExists = await fs7.pathExists(contextPath);
15480
- const contextContent = contextExists ? await fs7.readFile(contextPath, "utf-8") : "";
15579
+ const currentStatePath = path8.join(vemDir, CURRENT_STATE_FILE);
15580
+ const currentStateExists = await fs8.pathExists(currentStatePath);
15581
+ const currentStateContent = currentStateExists ? await fs8.readFile(currentStatePath, "utf-8") : "";
15582
+ const contextPath = path8.join(vemDir, CONTEXT_FILE);
15583
+ const contextExists = await fs8.pathExists(contextPath);
15584
+ const contextContent = contextExists ? await fs8.readFile(contextPath, "utf-8") : "";
15481
15585
  const result = {
15482
15586
  tasks: {
15483
15587
  added: tasks.filter((t) => t.status !== "done").map((t) => t.id),
@@ -15511,8 +15615,8 @@ var DiffService = class {
15511
15615
  };
15512
15616
 
15513
15617
  // ../../packages/core/dist/doctor.js
15514
- import path8 from "path";
15515
- import fs8 from "fs-extra";
15618
+ import path9 from "path";
15619
+ import fs9 from "fs-extra";
15516
15620
  var DoctorService = class {
15517
15621
  configService = new ConfigService();
15518
15622
  taskService = new TaskService();
@@ -15607,7 +15711,7 @@ var DoctorService = class {
15607
15711
  async checkVemDirectory() {
15608
15712
  try {
15609
15713
  const vemDir = await getVemDir();
15610
- const exists = await fs8.pathExists(vemDir);
15714
+ const exists = await fs9.pathExists(vemDir);
15611
15715
  if (!exists) {
15612
15716
  return {
15613
15717
  name: ".vem Directory",
@@ -15617,12 +15721,12 @@ var DoctorService = class {
15617
15721
  autoFixable: true
15618
15722
  };
15619
15723
  }
15620
- const tasksDir = path8.join(vemDir, TASKS_DIR);
15621
- const decisionsDir = path8.join(vemDir, DECISIONS_DIR);
15622
- const changelogDir = path8.join(vemDir, CHANGELOG_DIR);
15623
- const tasksDirExists = await fs8.pathExists(tasksDir);
15624
- const decisionsDirExists = await fs8.pathExists(decisionsDir);
15625
- const changelogDirExists = await fs8.pathExists(changelogDir);
15724
+ const tasksDir = path9.join(vemDir, TASKS_DIR);
15725
+ const decisionsDir = path9.join(vemDir, DECISIONS_DIR);
15726
+ const changelogDir = path9.join(vemDir, CHANGELOG_DIR);
15727
+ const tasksDirExists = await fs9.pathExists(tasksDir);
15728
+ const decisionsDirExists = await fs9.pathExists(decisionsDir);
15729
+ const changelogDirExists = await fs9.pathExists(changelogDir);
15626
15730
  if (!tasksDirExists || !decisionsDirExists || !changelogDirExists) {
15627
15731
  return {
15628
15732
  name: ".vem Directory",
@@ -15649,10 +15753,10 @@ var DoctorService = class {
15649
15753
  async checkRequiredFiles() {
15650
15754
  try {
15651
15755
  const vemDir = await getVemDir();
15652
- const contextPath = path8.join(vemDir, CONTEXT_FILE);
15653
- const currentStatePath = path8.join(vemDir, CURRENT_STATE_FILE);
15654
- const contextExists = await fs8.pathExists(contextPath);
15655
- const currentStateExists = await fs8.pathExists(currentStatePath);
15756
+ const contextPath = path9.join(vemDir, CONTEXT_FILE);
15757
+ const currentStatePath = path9.join(vemDir, CURRENT_STATE_FILE);
15758
+ const contextExists = await fs9.pathExists(contextPath);
15759
+ const currentStateExists = await fs9.pathExists(currentStatePath);
15656
15760
  if (!contextExists || !currentStateExists) {
15657
15761
  return {
15658
15762
  name: "Required Files",
@@ -16058,8 +16162,8 @@ function detectSecrets(input) {
16058
16162
 
16059
16163
  // ../../packages/core/dist/sync.js
16060
16164
  import { createHash as createHash3 } from "crypto";
16061
- import path9 from "path";
16062
- import fs9 from "fs-extra";
16165
+ import path10 from "path";
16166
+ import fs10 from "fs-extra";
16063
16167
  var KNOWN_AGENT_INSTRUCTION_FILES = [
16064
16168
  "AGENTS.md",
16065
16169
  "CLAUDE.md",
@@ -16076,7 +16180,7 @@ function normalizeInstructionPath(value) {
16076
16180
  const normalized = value.trim().replace(/\\/g, "/");
16077
16181
  if (!normalized)
16078
16182
  return null;
16079
- const collapsed = path9.posix.normalize(normalized);
16183
+ const collapsed = path10.posix.normalize(normalized);
16080
16184
  if (collapsed === "." || collapsed === ".." || collapsed.startsWith("../") || collapsed.startsWith("/")) {
16081
16185
  return null;
16082
16186
  }
@@ -16167,29 +16271,29 @@ var SyncService = class {
16167
16271
  changelogLog = new ScalableLogService(CHANGELOG_DIR);
16168
16272
  async getQueueDir() {
16169
16273
  const dir = await getVemDir();
16170
- const queueDir = path9.join(dir, "queue");
16171
- await fs9.ensureDir(queueDir);
16274
+ const queueDir = path10.join(dir, "queue");
16275
+ await fs10.ensureDir(queueDir);
16172
16276
  return queueDir;
16173
16277
  }
16174
16278
  async getContextPath() {
16175
16279
  const dir = await getVemDir();
16176
- return path9.join(dir, CONTEXT_FILE);
16280
+ return path10.join(dir, CONTEXT_FILE);
16177
16281
  }
16178
16282
  async getCurrentStatePath() {
16179
16283
  const dir = await getVemDir();
16180
- return path9.join(dir, CURRENT_STATE_FILE);
16284
+ return path10.join(dir, CURRENT_STATE_FILE);
16181
16285
  }
16182
16286
  async collectAgentInstructionFiles() {
16183
16287
  const repoRoot = await getRepoRoot();
16184
16288
  const files = [];
16185
16289
  for (const relativePath of KNOWN_AGENT_INSTRUCTION_FILES) {
16186
- const absolutePath = path9.join(repoRoot, relativePath);
16187
- if (!await fs9.pathExists(absolutePath))
16290
+ const absolutePath = path10.join(repoRoot, relativePath);
16291
+ if (!await fs10.pathExists(absolutePath))
16188
16292
  continue;
16189
- const stat = await fs9.stat(absolutePath);
16293
+ const stat = await fs10.stat(absolutePath);
16190
16294
  if (!stat.isFile())
16191
16295
  continue;
16192
- const content = await fs9.readFile(absolutePath, "utf-8");
16296
+ const content = await fs10.readFile(absolutePath, "utf-8");
16193
16297
  files.push({ path: relativePath, content });
16194
16298
  }
16195
16299
  return files;
@@ -16198,19 +16302,19 @@ var SyncService = class {
16198
16302
  if (!Array.isArray(entries) || entries.length === 0)
16199
16303
  return;
16200
16304
  const repoRoot = await getRepoRoot();
16201
- const resolvedRoot = path9.resolve(repoRoot);
16305
+ const resolvedRoot = path10.resolve(repoRoot);
16202
16306
  for (const entry of entries) {
16203
16307
  const normalizedPath = normalizeInstructionPath(entry?.path);
16204
16308
  if (!normalizedPath)
16205
16309
  continue;
16206
16310
  if (typeof entry.content !== "string")
16207
16311
  continue;
16208
- const destination = path9.resolve(repoRoot, normalizedPath);
16209
- if (destination !== resolvedRoot && !destination.startsWith(`${resolvedRoot}${path9.sep}`)) {
16312
+ const destination = path10.resolve(repoRoot, normalizedPath);
16313
+ if (destination !== resolvedRoot && !destination.startsWith(`${resolvedRoot}${path10.sep}`)) {
16210
16314
  continue;
16211
16315
  }
16212
- await fs9.ensureDir(path9.dirname(destination));
16213
- await fs9.writeFile(destination, entry.content, "utf-8");
16316
+ await fs10.ensureDir(path10.dirname(destination));
16317
+ await fs10.writeFile(destination, entry.content, "utf-8");
16214
16318
  }
16215
16319
  }
16216
16320
  async pack() {
@@ -16232,15 +16336,15 @@ var SyncService = class {
16232
16336
  };
16233
16337
  const contextPath = await this.getContextPath();
16234
16338
  let context = "";
16235
- if (await fs9.pathExists(contextPath)) {
16236
- const raw = await fs9.readFile(contextPath, "utf-8");
16339
+ if (await fs10.pathExists(contextPath)) {
16340
+ const raw = await fs10.readFile(contextPath, "utf-8");
16237
16341
  addSecretMatch(".vem/CONTEXT.md", raw);
16238
16342
  context = redactSecrets(raw);
16239
16343
  }
16240
16344
  const currentStatePath = await this.getCurrentStatePath();
16241
16345
  let currentState = "";
16242
- if (await fs9.pathExists(currentStatePath)) {
16243
- const raw = await fs9.readFile(currentStatePath, "utf-8");
16346
+ if (await fs10.pathExists(currentStatePath)) {
16347
+ const raw = await fs10.readFile(currentStatePath, "utf-8");
16244
16348
  addSecretMatch(".vem/CURRENT_STATE.md", raw);
16245
16349
  currentState = redactSecrets(raw);
16246
16350
  }
@@ -16360,7 +16464,7 @@ ${body}`;
16360
16464
  }
16361
16465
  async unpack(payload) {
16362
16466
  const vemDir = await getVemDir();
16363
- await fs9.ensureDir(vemDir);
16467
+ await fs10.ensureDir(vemDir);
16364
16468
  const { storage, index } = await this.taskService.init();
16365
16469
  const taskIds = await storage.listIds();
16366
16470
  for (const id of taskIds) {
@@ -16380,7 +16484,7 @@ ${body}`;
16380
16484
  }
16381
16485
  await index.save(newIndexEntries);
16382
16486
  const contextPath = await this.getContextPath();
16383
- await fs9.writeFile(contextPath, payload.context, "utf-8");
16487
+ await fs10.writeFile(contextPath, payload.context, "utf-8");
16384
16488
  if (payload.decisions) {
16385
16489
  await this.decisionsLog.addEntry("Imported from Sync", payload.decisions);
16386
16490
  }
@@ -16388,24 +16492,24 @@ ${body}`;
16388
16492
  await this.changelogLog.addEntry("Imported from Sync", payload.changelog);
16389
16493
  }
16390
16494
  const currentStatePath = await this.getCurrentStatePath();
16391
- await fs9.writeFile(currentStatePath, payload.current_state ?? "", "utf-8");
16495
+ await fs10.writeFile(currentStatePath, payload.current_state ?? "", "utf-8");
16392
16496
  await this.unpackAgentInstructionFiles(payload.agent_instructions);
16393
16497
  }
16394
16498
  async enqueue(payload) {
16395
16499
  const queueDir = await this.getQueueDir();
16396
16500
  const id = `${Date.now()}-${Math.random().toString(36).substring(2, 9)}.json`;
16397
- const filePath = path9.join(queueDir, id);
16398
- await fs9.writeJson(filePath, payload, { spaces: 2 });
16501
+ const filePath = path10.join(queueDir, id);
16502
+ await fs10.writeJson(filePath, payload, { spaces: 2 });
16399
16503
  return id;
16400
16504
  }
16401
16505
  async getQueue() {
16402
16506
  const queueDir = await this.getQueueDir();
16403
- const files = await fs9.readdir(queueDir);
16507
+ const files = await fs10.readdir(queueDir);
16404
16508
  const queue = [];
16405
16509
  for (const file2 of files) {
16406
16510
  if (file2.endsWith(".json")) {
16407
16511
  try {
16408
- const payload = await fs9.readJson(path9.join(queueDir, file2));
16512
+ const payload = await fs10.readJson(path10.join(queueDir, file2));
16409
16513
  queue.push({ id: file2, payload });
16410
16514
  } catch (error48) {
16411
16515
  console.error(`Error reading queued snapshot ${file2}:`, error48);
@@ -16416,108 +16520,13 @@ ${body}`;
16416
16520
  }
16417
16521
  async removeFromQueue(id) {
16418
16522
  const queueDir = await this.getQueueDir();
16419
- const filePath = path9.join(queueDir, id);
16420
- if (await fs9.pathExists(filePath)) {
16421
- await fs9.remove(filePath);
16523
+ const filePath = path10.join(queueDir, id);
16524
+ if (await fs10.pathExists(filePath)) {
16525
+ await fs10.remove(filePath);
16422
16526
  }
16423
16527
  }
16424
16528
  };
16425
16529
 
16426
- // ../../packages/core/dist/cycles.js
16427
- import path10 from "path";
16428
- import fs10 from "fs-extra";
16429
- var CycleService = class {
16430
- async getCyclesDir() {
16431
- const vemDir = await getVemDir();
16432
- const dir = path10.join(vemDir, CYCLES_DIR);
16433
- await fs10.ensureDir(dir);
16434
- return dir;
16435
- }
16436
- cycleFilePath(dir, id) {
16437
- return path10.join(dir, `${id}.json`);
16438
- }
16439
- async getNextCycleId(dir) {
16440
- let maxNum = 0;
16441
- const entries = await fs10.readdir(dir).catch(() => []);
16442
- for (const entry of entries) {
16443
- const match = entry.match(/^CYCLE-(\d{3,})\.json$/);
16444
- if (match) {
16445
- const num = parseInt(match[1], 10);
16446
- if (!Number.isNaN(num) && num > maxNum) {
16447
- maxNum = num;
16448
- }
16449
- }
16450
- }
16451
- return `CYCLE-${String(maxNum + 1).padStart(3, "0")}`;
16452
- }
16453
- async createCycle(input) {
16454
- const dir = await this.getCyclesDir();
16455
- const id = await this.getNextCycleId(dir);
16456
- const timestamp = (/* @__PURE__ */ new Date()).toISOString();
16457
- const cycle = {
16458
- id,
16459
- name: input.name,
16460
- goal: input.goal,
16461
- appetite: input.appetite,
16462
- status: "planned",
16463
- start_at: input.start_at,
16464
- created_at: timestamp,
16465
- updated_at: timestamp
16466
- };
16467
- await fs10.writeJson(this.cycleFilePath(dir, id), cycle, { spaces: 2 });
16468
- return cycle;
16469
- }
16470
- async getCycles() {
16471
- const dir = await this.getCyclesDir();
16472
- const entries = await fs10.readdir(dir).catch(() => []);
16473
- const cycles = [];
16474
- for (const entry of entries) {
16475
- if (!entry.endsWith(".json"))
16476
- continue;
16477
- try {
16478
- const cycle = await fs10.readJson(path10.join(dir, entry));
16479
- if (cycle?.id)
16480
- cycles.push(cycle);
16481
- } catch {
16482
- }
16483
- }
16484
- return cycles.sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
16485
- }
16486
- async getCycle(id) {
16487
- const dir = await this.getCyclesDir();
16488
- const filePath = this.cycleFilePath(dir, id);
16489
- if (!await fs10.pathExists(filePath))
16490
- return null;
16491
- try {
16492
- return await fs10.readJson(filePath);
16493
- } catch {
16494
- return null;
16495
- }
16496
- }
16497
- async updateCycle(id, patch) {
16498
- const dir = await this.getCyclesDir();
16499
- const filePath = this.cycleFilePath(dir, id);
16500
- const current = await this.getCycle(id);
16501
- if (!current) {
16502
- throw new Error(`Cycle ${id} not found`);
16503
- }
16504
- const timestamp = (/* @__PURE__ */ new Date()).toISOString();
16505
- const updated = { ...current, ...patch, id, updated_at: timestamp };
16506
- if (patch.status === "active" && current.status !== "active") {
16507
- updated.start_at = updated.start_at ?? timestamp;
16508
- }
16509
- if (patch.status === "closed" && current.status !== "closed") {
16510
- updated.closed_at = updated.closed_at ?? timestamp;
16511
- }
16512
- await fs10.writeJson(filePath, updated, { spaces: 2 });
16513
- return updated;
16514
- }
16515
- async getActiveCycle() {
16516
- const cycles = await this.getCycles();
16517
- return cycles.find((c) => c.status === "active") ?? null;
16518
- }
16519
- };
16520
-
16521
16530
  // ../../packages/core/dist/telegram.js
16522
16531
  async function sendTelegramAlert(botToken, chatId, message) {
16523
16532
  if (!botToken || !chatId)
@@ -17320,6 +17329,7 @@ export {
17320
17329
  getGitHeadHash,
17321
17330
  getGitLastCommitForPath,
17322
17331
  ScalableLogService,
17332
+ CycleService,
17323
17333
  TaskService,
17324
17334
  formatVemPack,
17325
17335
  parseVemUpdateBlock,
@@ -17349,7 +17359,6 @@ export {
17349
17359
  KNOWN_AGENT_INSTRUCTION_FILES,
17350
17360
  computeSnapshotHash,
17351
17361
  SyncService,
17352
- CycleService,
17353
17362
  sendTelegramAlert,
17354
17363
  UsageMetricsService,
17355
17364
  validatePasswordStrength,
@@ -17357,4 +17366,4 @@ export {
17357
17366
  WebhookService,
17358
17367
  WorkflowGuideService
17359
17368
  };
17360
- //# sourceMappingURL=chunk-22CM6ZM5.js.map
17369
+ //# sourceMappingURL=chunk-PPAFJ3LP.js.map