@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.
- package/dist/{chunk-22CM6ZM5.js → chunk-PPAFJ3LP.js} +221 -212
- package/dist/chunk-PPAFJ3LP.js.map +1 -0
- package/dist/{dist-MFRU63ZN.js → dist-2IBAWS6G.js} +2 -2
- package/dist/index.js +54 -7
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-22CM6ZM5.js.map +0 -1
- /package/dist/{dist-MFRU63ZN.js.map → dist-2IBAWS6G.js.map} +0 -0
|
@@ -56,7 +56,7 @@ function maskProviderKey(plaintext) {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
// ../../packages/core/dist/agent.js
|
|
59
|
-
import
|
|
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
|
|
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
|
|
14295
|
-
import
|
|
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
|
|
14300
|
-
import
|
|
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
|
|
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
|
|
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
|
|
14322
|
-
await
|
|
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
|
|
14421
|
+
if (!await fs4.pathExists(filePath)) {
|
|
14327
14422
|
return null;
|
|
14328
14423
|
}
|
|
14329
|
-
return
|
|
14424
|
+
return fs4.readJson(filePath);
|
|
14330
14425
|
}
|
|
14331
14426
|
async delete(id) {
|
|
14332
14427
|
const filePath = this.getFilePath(id);
|
|
14333
|
-
if (await
|
|
14334
|
-
await
|
|
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
|
|
14434
|
+
if (!await fs4.pathExists(objectsDir)) {
|
|
14340
14435
|
return [];
|
|
14341
14436
|
}
|
|
14342
|
-
const shards = await
|
|
14437
|
+
const shards = await fs4.readdir(objectsDir);
|
|
14343
14438
|
const ids = [];
|
|
14344
14439
|
for (const shard of shards) {
|
|
14345
|
-
const shardPath =
|
|
14346
|
-
const stat = await
|
|
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
|
|
14444
|
+
const files = await fs4.readdir(shardPath);
|
|
14350
14445
|
for (const file2 of files) {
|
|
14351
14446
|
if (file2.endsWith(".json")) {
|
|
14352
|
-
ids.push(
|
|
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 =
|
|
14468
|
+
this.indexPath = path4.join(baseDir, "index.json");
|
|
14374
14469
|
}
|
|
14375
14470
|
async load() {
|
|
14376
|
-
if (!await
|
|
14471
|
+
if (!await fs4.pathExists(this.indexPath)) {
|
|
14377
14472
|
return [];
|
|
14378
14473
|
}
|
|
14379
14474
|
try {
|
|
14380
|
-
const data = await
|
|
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
|
|
14388
|
-
await
|
|
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 =
|
|
14426
|
-
await
|
|
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 =
|
|
14445
|
-
if (!await
|
|
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
|
|
14545
|
+
const entries = await fs5.readdir(dir);
|
|
14451
14546
|
for (const entry of entries) {
|
|
14452
|
-
const fullPath =
|
|
14453
|
-
const stat = await
|
|
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
|
|
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 =
|
|
14484
|
-
if (!await
|
|
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
|
|
14584
|
+
const entries = await fs5.readdir(dir);
|
|
14490
14585
|
for (const entry of entries) {
|
|
14491
|
-
const fullPath =
|
|
14492
|
-
const stat = await
|
|
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 =
|
|
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 =
|
|
14883
|
-
const archiveBase =
|
|
14884
|
-
await
|
|
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 =
|
|
14892
|
-
await
|
|
14893
|
-
const destWithId =
|
|
14894
|
-
await
|
|
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 =
|
|
15309
|
+
const currentStatePath = path6.join(dir, CURRENT_STATE_FILE);
|
|
15206
15310
|
const next = value.trim().length > 0 ? `${value.trim()}
|
|
15207
15311
|
` : "";
|
|
15208
|
-
await
|
|
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 =
|
|
15319
|
+
const contextPath = path6.join(dir, CONTEXT_FILE);
|
|
15216
15320
|
const next = value.trim().length > 0 ? `${value.trim()}
|
|
15217
15321
|
` : "";
|
|
15218
|
-
await
|
|
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
|
|
15279
|
-
import
|
|
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
|
|
15388
|
+
return path7.join(dir, CONFIG_FILE);
|
|
15285
15389
|
}
|
|
15286
15390
|
getGlobalPath() {
|
|
15287
|
-
return
|
|
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
|
|
15396
|
+
if (!await fs7.pathExists(filePath))
|
|
15293
15397
|
return {};
|
|
15294
|
-
return
|
|
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
|
|
15406
|
+
if (!await fs7.pathExists(filePath))
|
|
15303
15407
|
return {};
|
|
15304
|
-
return
|
|
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
|
|
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
|
|
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
|
|
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
|
|
15540
|
+
if (!filePath || !await fs7.pathExists(filePath)) {
|
|
15437
15541
|
return "";
|
|
15438
15542
|
}
|
|
15439
|
-
return
|
|
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
|
|
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
|
|
15465
|
-
import
|
|
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 =
|
|
15476
|
-
const currentStateExists = await
|
|
15477
|
-
const currentStateContent = currentStateExists ? await
|
|
15478
|
-
const contextPath =
|
|
15479
|
-
const contextExists = await
|
|
15480
|
-
const contextContent = contextExists ? await
|
|
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
|
|
15515
|
-
import
|
|
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
|
|
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 =
|
|
15621
|
-
const decisionsDir =
|
|
15622
|
-
const changelogDir =
|
|
15623
|
-
const tasksDirExists = await
|
|
15624
|
-
const decisionsDirExists = await
|
|
15625
|
-
const changelogDirExists = await
|
|
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 =
|
|
15653
|
-
const currentStatePath =
|
|
15654
|
-
const contextExists = await
|
|
15655
|
-
const currentStateExists = await
|
|
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
|
|
16062
|
-
import
|
|
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 =
|
|
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 =
|
|
16171
|
-
await
|
|
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
|
|
16280
|
+
return path10.join(dir, CONTEXT_FILE);
|
|
16177
16281
|
}
|
|
16178
16282
|
async getCurrentStatePath() {
|
|
16179
16283
|
const dir = await getVemDir();
|
|
16180
|
-
return
|
|
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 =
|
|
16187
|
-
if (!await
|
|
16290
|
+
const absolutePath = path10.join(repoRoot, relativePath);
|
|
16291
|
+
if (!await fs10.pathExists(absolutePath))
|
|
16188
16292
|
continue;
|
|
16189
|
-
const stat = await
|
|
16293
|
+
const stat = await fs10.stat(absolutePath);
|
|
16190
16294
|
if (!stat.isFile())
|
|
16191
16295
|
continue;
|
|
16192
|
-
const content = await
|
|
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 =
|
|
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 =
|
|
16209
|
-
if (destination !== resolvedRoot && !destination.startsWith(`${resolvedRoot}${
|
|
16312
|
+
const destination = path10.resolve(repoRoot, normalizedPath);
|
|
16313
|
+
if (destination !== resolvedRoot && !destination.startsWith(`${resolvedRoot}${path10.sep}`)) {
|
|
16210
16314
|
continue;
|
|
16211
16315
|
}
|
|
16212
|
-
await
|
|
16213
|
-
await
|
|
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
|
|
16236
|
-
const raw = await
|
|
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
|
|
16243
|
-
const raw = await
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
16398
|
-
await
|
|
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
|
|
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
|
|
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 =
|
|
16420
|
-
if (await
|
|
16421
|
-
await
|
|
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-
|
|
17369
|
+
//# sourceMappingURL=chunk-PPAFJ3LP.js.map
|