@askexenow/exe-os 0.9.102 → 0.9.104
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/bin/agentic-ontology-backfill.js +334 -100
- package/dist/bin/agentic-reflection-backfill.js +328 -97
- package/dist/bin/agentic-semantic-label.js +328 -97
- package/dist/bin/backfill-conversations.js +332 -97
- package/dist/bin/backfill-responses.js +332 -97
- package/dist/bin/backfill-vectors.js +337 -106
- package/dist/bin/bulk-sync-postgres.js +335 -101
- package/dist/bin/cleanup-stale-review-tasks.js +356 -108
- package/dist/bin/cli.js +653 -405
- package/dist/bin/exe-agent.js +21 -3
- package/dist/bin/exe-assign.js +338 -94
- package/dist/bin/exe-boot.js +472 -239
- package/dist/bin/exe-call.js +22 -5
- package/dist/bin/exe-cloud.js +404 -158
- package/dist/bin/exe-dispatch.js +390 -142
- package/dist/bin/exe-doctor.js +349 -103
- package/dist/bin/exe-export-behaviors.js +351 -105
- package/dist/bin/exe-forget.js +352 -103
- package/dist/bin/exe-gateway.js +420 -172
- package/dist/bin/exe-heartbeat.js +361 -113
- package/dist/bin/exe-kill.js +344 -98
- package/dist/bin/exe-launch-agent.js +375 -129
- package/dist/bin/exe-new-employee.js +83 -67
- package/dist/bin/exe-pending-messages.js +356 -108
- package/dist/bin/exe-pending-notifications.js +358 -110
- package/dist/bin/exe-pending-reviews.js +359 -111
- package/dist/bin/exe-rename.js +354 -108
- package/dist/bin/exe-review.js +343 -97
- package/dist/bin/exe-search.js +363 -113
- package/dist/bin/exe-session-cleanup.js +403 -155
- package/dist/bin/exe-settings.js +14 -9
- package/dist/bin/exe-start-codex.js +365 -131
- package/dist/bin/exe-start-opencode.js +359 -125
- package/dist/bin/exe-status.js +356 -108
- package/dist/bin/exe-team.js +343 -97
- package/dist/bin/git-sweep.js +390 -142
- package/dist/bin/graph-backfill.js +334 -100
- package/dist/bin/graph-export.js +346 -100
- package/dist/bin/install.js +1 -0
- package/dist/bin/intercom-check.js +403 -155
- package/dist/bin/pre-publish.js +12 -0
- package/dist/bin/scan-tasks.js +393 -145
- package/dist/bin/setup.js +331 -159
- package/dist/bin/shard-migrate.js +328 -94
- package/dist/gateway/index.js +406 -158
- package/dist/hooks/bug-report-worker.js +396 -148
- package/dist/hooks/codex-stop-task-finalizer.js +374 -126
- package/dist/hooks/commit-complete.js +390 -142
- package/dist/hooks/error-recall.js +365 -115
- package/dist/hooks/ingest.js +357 -111
- package/dist/hooks/instructions-loaded.js +351 -105
- package/dist/hooks/notification.js +343 -97
- package/dist/hooks/post-compact.js +358 -110
- package/dist/hooks/post-tool-combined.js +384 -132
- package/dist/hooks/pre-compact.js +391 -143
- package/dist/hooks/pre-tool-use.js +362 -114
- package/dist/hooks/prompt-submit.js +422 -170
- package/dist/hooks/session-end.js +393 -145
- package/dist/hooks/session-start.js +390 -138
- package/dist/hooks/stop.js +361 -113
- package/dist/hooks/subagent-stop.js +354 -106
- package/dist/hooks/summary-worker.js +418 -185
- package/dist/index.js +400 -152
- package/dist/lib/cloud-sync.js +291 -131
- package/dist/lib/consolidation.js +8 -2
- package/dist/lib/database.js +233 -73
- package/dist/lib/db.js +233 -73
- package/dist/lib/device-registry.js +237 -77
- package/dist/lib/employee-templates.js +19 -1
- package/dist/lib/exe-daemon.js +705 -409
- package/dist/lib/hybrid-search.js +363 -113
- package/dist/lib/identity.js +9 -5
- package/dist/lib/messaging.js +26 -20
- package/dist/lib/reminders.js +5 -1
- package/dist/lib/schedules.js +320 -89
- package/dist/lib/skill-learning.js +28 -24
- package/dist/lib/store.js +342 -96
- package/dist/lib/tasks.js +82 -76
- package/dist/lib/tmux-routing.js +74 -68
- package/dist/lib/token-spend.js +5 -1
- package/dist/mcp/server.js +628 -355
- package/dist/mcp/tools/complete-reminder.js +5 -1
- package/dist/mcp/tools/create-reminder.js +5 -1
- package/dist/mcp/tools/create-task.js +89 -83
- package/dist/mcp/tools/deactivate-behavior.js +7 -3
- package/dist/mcp/tools/list-reminders.js +5 -1
- package/dist/mcp/tools/list-tasks.js +28 -21
- package/dist/mcp/tools/send-message.js +28 -22
- package/dist/mcp/tools/update-task.js +89 -83
- package/dist/runtime/index.js +390 -142
- package/dist/tui/App.js +437 -189
- package/package.json +1 -1
package/dist/bin/cli.js
CHANGED
|
@@ -4339,9 +4339,79 @@ __export(database_exports, {
|
|
|
4339
4339
|
isInitialized: () => isInitialized,
|
|
4340
4340
|
setExternalClient: () => setExternalClient
|
|
4341
4341
|
});
|
|
4342
|
-
import { chmodSync as chmodSync3 } from "fs";
|
|
4342
|
+
import { chmodSync as chmodSync3, existsSync as existsSync13, statSync as statSync3, copyFileSync as copyFileSync2, unlinkSync as unlinkSync4, openSync as openSync2, closeSync as closeSync2, mkdirSync as mkdirSync6 } from "fs";
|
|
4343
4343
|
import { createClient } from "@libsql/client";
|
|
4344
|
+
import { homedir } from "os";
|
|
4345
|
+
import { join } from "path";
|
|
4346
|
+
function logCatchDebug(context, err) {
|
|
4347
|
+
if (_debugDb) {
|
|
4348
|
+
process.stderr.write(
|
|
4349
|
+
`[database] ${context}: ${err instanceof Error ? err.message : String(err)}
|
|
4350
|
+
`
|
|
4351
|
+
);
|
|
4352
|
+
}
|
|
4353
|
+
}
|
|
4354
|
+
function acquireDbLock() {
|
|
4355
|
+
mkdirSync6(join(homedir(), ".exe-os"), { recursive: true });
|
|
4356
|
+
try {
|
|
4357
|
+
_lockFd = openSync2(DB_LOCK_PATH, "wx");
|
|
4358
|
+
} catch (err) {
|
|
4359
|
+
if (err && typeof err === "object" && "code" in err && err.code === "EEXIST") {
|
|
4360
|
+
try {
|
|
4361
|
+
const lockStat = statSync3(DB_LOCK_PATH);
|
|
4362
|
+
if (Date.now() - lockStat.mtimeMs > 6e4) {
|
|
4363
|
+
unlinkSync4(DB_LOCK_PATH);
|
|
4364
|
+
_lockFd = openSync2(DB_LOCK_PATH, "wx");
|
|
4365
|
+
return;
|
|
4366
|
+
}
|
|
4367
|
+
} catch (e) {
|
|
4368
|
+
logCatchDebug("stale lock check", e);
|
|
4369
|
+
}
|
|
4370
|
+
process.stderr.write(
|
|
4371
|
+
"[database] WARN: Another process holds db.lock \u2014 waiting briefly then proceeding.\n"
|
|
4372
|
+
);
|
|
4373
|
+
return;
|
|
4374
|
+
}
|
|
4375
|
+
throw err;
|
|
4376
|
+
}
|
|
4377
|
+
}
|
|
4378
|
+
function releaseDbLock() {
|
|
4379
|
+
if (_lockFd !== null) {
|
|
4380
|
+
try {
|
|
4381
|
+
closeSync2(_lockFd);
|
|
4382
|
+
} catch (e) {
|
|
4383
|
+
logCatchDebug("lock close", e);
|
|
4384
|
+
}
|
|
4385
|
+
_lockFd = null;
|
|
4386
|
+
}
|
|
4387
|
+
try {
|
|
4388
|
+
unlinkSync4(DB_LOCK_PATH);
|
|
4389
|
+
} catch (e) {
|
|
4390
|
+
logCatchDebug("lock unlink", e);
|
|
4391
|
+
}
|
|
4392
|
+
}
|
|
4344
4393
|
async function initDatabase(config) {
|
|
4394
|
+
acquireDbLock();
|
|
4395
|
+
if (existsSync13(config.dbPath)) {
|
|
4396
|
+
const dbStat = statSync3(config.dbPath);
|
|
4397
|
+
if (dbStat.size === 0) {
|
|
4398
|
+
const walPath = config.dbPath + "-wal";
|
|
4399
|
+
if (existsSync13(walPath) && statSync3(walPath).size > 0) {
|
|
4400
|
+
const backupPath = config.dbPath + ".zeroed-" + Date.now();
|
|
4401
|
+
copyFileSync2(config.dbPath, backupPath);
|
|
4402
|
+
unlinkSync4(config.dbPath);
|
|
4403
|
+
process.stderr.write(
|
|
4404
|
+
`[database] CRITICAL: DB was 0 bytes. Moved to ${backupPath}, attempting WAL recovery.
|
|
4405
|
+
`
|
|
4406
|
+
);
|
|
4407
|
+
} else {
|
|
4408
|
+
process.stderr.write(
|
|
4409
|
+
`[database] CRITICAL: DB is 0 bytes and no WAL available for recovery. Data may be lost. Check backups at ${config.dbPath}.bak
|
|
4410
|
+
`
|
|
4411
|
+
);
|
|
4412
|
+
}
|
|
4413
|
+
}
|
|
4414
|
+
}
|
|
4345
4415
|
if (_walCheckpointTimer) {
|
|
4346
4416
|
clearInterval(_walCheckpointTimer);
|
|
4347
4417
|
_walCheckpointTimer = null;
|
|
@@ -4368,10 +4438,8 @@ async function initDatabase(config) {
|
|
|
4368
4438
|
_client = createClient(opts);
|
|
4369
4439
|
_resilientClient = wrapWithRetry(_client);
|
|
4370
4440
|
_adapterClient = _resilientClient;
|
|
4371
|
-
_client.execute("PRAGMA busy_timeout = 30000")
|
|
4372
|
-
|
|
4373
|
-
_client.execute("PRAGMA journal_mode = WAL").catch(() => {
|
|
4374
|
-
});
|
|
4441
|
+
await _client.execute("PRAGMA busy_timeout = 30000");
|
|
4442
|
+
await _client.execute("PRAGMA journal_mode = WAL");
|
|
4375
4443
|
if (_walCheckpointTimer) clearInterval(_walCheckpointTimer);
|
|
4376
4444
|
_walCheckpointTimer = setInterval(() => {
|
|
4377
4445
|
_client?.execute("PRAGMA wal_checkpoint(PASSIVE)").catch(() => {
|
|
@@ -4386,11 +4454,16 @@ async function initDatabase(config) {
|
|
|
4386
4454
|
for (const suffix of ["-wal", "-shm"]) {
|
|
4387
4455
|
try {
|
|
4388
4456
|
chmodSync3(config.dbPath + suffix, 384);
|
|
4389
|
-
} catch {
|
|
4457
|
+
} catch (chmodErr) {
|
|
4458
|
+
process.stderr.write(`[database] chmod ${suffix} failed: ${chmodErr instanceof Error ? chmodErr.message : String(chmodErr)}
|
|
4459
|
+
`);
|
|
4390
4460
|
}
|
|
4391
4461
|
}
|
|
4392
|
-
} catch {
|
|
4462
|
+
} catch (chmodErr) {
|
|
4463
|
+
process.stderr.write(`[database] chmod db failed: ${chmodErr instanceof Error ? chmodErr.message : String(chmodErr)}
|
|
4464
|
+
`);
|
|
4393
4465
|
}
|
|
4466
|
+
releaseDbLock();
|
|
4394
4467
|
}
|
|
4395
4468
|
function isInitialized() {
|
|
4396
4469
|
return _adapterClient !== null || _client !== null;
|
|
@@ -4445,7 +4518,8 @@ async function ensureSchema() {
|
|
|
4445
4518
|
await client.execute("PRAGMA wal_autocheckpoint = 1000");
|
|
4446
4519
|
try {
|
|
4447
4520
|
await client.execute("PRAGMA libsql_vector_search_ef = 128");
|
|
4448
|
-
} catch {
|
|
4521
|
+
} catch (e) {
|
|
4522
|
+
logCatchDebug("migration", e);
|
|
4449
4523
|
}
|
|
4450
4524
|
await client.executeMultiple(`
|
|
4451
4525
|
CREATE TABLE IF NOT EXISTS memories (
|
|
@@ -4510,6 +4584,23 @@ async function ensureSchema() {
|
|
|
4510
4584
|
INSERT INTO memories_fts(memories_fts, rowid, raw_text) VALUES('delete', old.rowid, old.raw_text);
|
|
4511
4585
|
END;
|
|
4512
4586
|
`);
|
|
4587
|
+
try {
|
|
4588
|
+
await client.execute("SELECT COUNT(*) FROM memories_fts LIMIT 1");
|
|
4589
|
+
} catch (ftsErr) {
|
|
4590
|
+
process.stderr.write(
|
|
4591
|
+
`[database] WARN: memories_fts corrupted (${ftsErr instanceof Error ? ftsErr.message : String(ftsErr)}) \u2014 rebuilding FTS index.
|
|
4592
|
+
`
|
|
4593
|
+
);
|
|
4594
|
+
try {
|
|
4595
|
+
await client.execute("INSERT INTO memories_fts(memories_fts) VALUES('rebuild')");
|
|
4596
|
+
process.stderr.write("[database] FTS index rebuilt successfully.\n");
|
|
4597
|
+
} catch (rebuildErr) {
|
|
4598
|
+
process.stderr.write(
|
|
4599
|
+
`[database] ERROR: FTS rebuild failed: ${rebuildErr instanceof Error ? rebuildErr.message : String(rebuildErr)}
|
|
4600
|
+
`
|
|
4601
|
+
);
|
|
4602
|
+
}
|
|
4603
|
+
}
|
|
4513
4604
|
await client.executeMultiple(`
|
|
4514
4605
|
CREATE TABLE IF NOT EXISTS sync_meta (
|
|
4515
4606
|
key TEXT PRIMARY KEY,
|
|
@@ -4568,35 +4659,40 @@ async function ensureSchema() {
|
|
|
4568
4659
|
});
|
|
4569
4660
|
}
|
|
4570
4661
|
}
|
|
4571
|
-
} catch {
|
|
4662
|
+
} catch (seedErr) {
|
|
4663
|
+
logCatchDebug("behavior seed", seedErr);
|
|
4572
4664
|
}
|
|
4573
4665
|
try {
|
|
4574
4666
|
await client.execute({
|
|
4575
4667
|
sql: `ALTER TABLE behaviors ADD COLUMN priority TEXT DEFAULT 'p1'`,
|
|
4576
4668
|
args: []
|
|
4577
4669
|
});
|
|
4578
|
-
} catch {
|
|
4670
|
+
} catch (e) {
|
|
4671
|
+
logCatchDebug("migration", e);
|
|
4579
4672
|
}
|
|
4580
4673
|
try {
|
|
4581
4674
|
await client.execute({
|
|
4582
4675
|
sql: `ALTER TABLE behaviors ADD COLUMN vector F32_BLOB(${EMBEDDING_DIM})`,
|
|
4583
4676
|
args: []
|
|
4584
4677
|
});
|
|
4585
|
-
} catch {
|
|
4678
|
+
} catch (e) {
|
|
4679
|
+
logCatchDebug("migration", e);
|
|
4586
4680
|
}
|
|
4587
4681
|
try {
|
|
4588
4682
|
await client.execute({
|
|
4589
4683
|
sql: `ALTER TABLE tasks ADD COLUMN blocked_by TEXT`,
|
|
4590
4684
|
args: []
|
|
4591
4685
|
});
|
|
4592
|
-
} catch {
|
|
4686
|
+
} catch (e) {
|
|
4687
|
+
logCatchDebug("migration", e);
|
|
4593
4688
|
}
|
|
4594
4689
|
try {
|
|
4595
4690
|
await client.execute({
|
|
4596
4691
|
sql: `ALTER TABLE tasks ADD COLUMN parent_task_id TEXT`,
|
|
4597
4692
|
args: []
|
|
4598
4693
|
});
|
|
4599
|
-
} catch {
|
|
4694
|
+
} catch (e) {
|
|
4695
|
+
logCatchDebug("migration", e);
|
|
4600
4696
|
}
|
|
4601
4697
|
try {
|
|
4602
4698
|
await client.execute({
|
|
@@ -4605,98 +4701,112 @@ async function ensureSchema() {
|
|
|
4605
4701
|
WHERE parent_task_id IS NOT NULL`,
|
|
4606
4702
|
args: []
|
|
4607
4703
|
});
|
|
4608
|
-
} catch {
|
|
4704
|
+
} catch (e) {
|
|
4705
|
+
logCatchDebug("migration", e);
|
|
4609
4706
|
}
|
|
4610
4707
|
try {
|
|
4611
4708
|
await client.execute({
|
|
4612
4709
|
sql: `UPDATE tasks SET status = 'done' WHERE status = 'completed'`,
|
|
4613
4710
|
args: []
|
|
4614
4711
|
});
|
|
4615
|
-
} catch {
|
|
4712
|
+
} catch (e) {
|
|
4713
|
+
logCatchDebug("migration", e);
|
|
4616
4714
|
}
|
|
4617
4715
|
try {
|
|
4618
4716
|
await client.execute({
|
|
4619
4717
|
sql: `ALTER TABLE tasks ADD COLUMN reviewer TEXT`,
|
|
4620
4718
|
args: []
|
|
4621
4719
|
});
|
|
4622
|
-
} catch {
|
|
4720
|
+
} catch (e) {
|
|
4721
|
+
logCatchDebug("migration", e);
|
|
4623
4722
|
}
|
|
4624
4723
|
try {
|
|
4625
4724
|
await client.execute({
|
|
4626
4725
|
sql: `ALTER TABLE tasks ADD COLUMN context TEXT`,
|
|
4627
4726
|
args: []
|
|
4628
4727
|
});
|
|
4629
|
-
} catch {
|
|
4728
|
+
} catch (e) {
|
|
4729
|
+
logCatchDebug("migration", e);
|
|
4630
4730
|
}
|
|
4631
4731
|
try {
|
|
4632
4732
|
await client.execute({
|
|
4633
4733
|
sql: `ALTER TABLE tasks ADD COLUMN result TEXT`,
|
|
4634
4734
|
args: []
|
|
4635
4735
|
});
|
|
4636
|
-
} catch {
|
|
4736
|
+
} catch (e) {
|
|
4737
|
+
logCatchDebug("migration", e);
|
|
4637
4738
|
}
|
|
4638
4739
|
try {
|
|
4639
4740
|
await client.execute({
|
|
4640
4741
|
sql: `ALTER TABLE tasks ADD COLUMN assigned_tmux TEXT`,
|
|
4641
4742
|
args: []
|
|
4642
4743
|
});
|
|
4643
|
-
} catch {
|
|
4744
|
+
} catch (e) {
|
|
4745
|
+
logCatchDebug("migration", e);
|
|
4644
4746
|
}
|
|
4645
4747
|
try {
|
|
4646
4748
|
await client.execute({
|
|
4647
4749
|
sql: `ALTER TABLE tasks ADD COLUMN checkpoint TEXT`,
|
|
4648
4750
|
args: []
|
|
4649
4751
|
});
|
|
4650
|
-
} catch {
|
|
4752
|
+
} catch (e) {
|
|
4753
|
+
logCatchDebug("migration", e);
|
|
4651
4754
|
}
|
|
4652
4755
|
try {
|
|
4653
4756
|
await client.execute({
|
|
4654
4757
|
sql: `ALTER TABLE tasks ADD COLUMN checkpoint_count INTEGER NOT NULL DEFAULT 0`,
|
|
4655
4758
|
args: []
|
|
4656
4759
|
});
|
|
4657
|
-
} catch {
|
|
4760
|
+
} catch (e) {
|
|
4761
|
+
logCatchDebug("migration", e);
|
|
4658
4762
|
}
|
|
4659
4763
|
try {
|
|
4660
4764
|
await client.execute({
|
|
4661
4765
|
sql: `ALTER TABLE tasks ADD COLUMN complexity TEXT NOT NULL DEFAULT 'standard'`,
|
|
4662
4766
|
args: []
|
|
4663
4767
|
});
|
|
4664
|
-
} catch {
|
|
4768
|
+
} catch (e) {
|
|
4769
|
+
logCatchDebug("migration", e);
|
|
4665
4770
|
}
|
|
4666
4771
|
try {
|
|
4667
4772
|
await client.execute({
|
|
4668
4773
|
sql: `ALTER TABLE tasks ADD COLUMN session_scope TEXT`,
|
|
4669
4774
|
args: []
|
|
4670
4775
|
});
|
|
4671
|
-
} catch {
|
|
4776
|
+
} catch (e) {
|
|
4777
|
+
logCatchDebug("migration", e);
|
|
4672
4778
|
}
|
|
4673
4779
|
try {
|
|
4674
4780
|
await client.execute({
|
|
4675
4781
|
sql: `ALTER TABLE memories ADD COLUMN task_id TEXT`,
|
|
4676
4782
|
args: []
|
|
4677
4783
|
});
|
|
4678
|
-
} catch {
|
|
4784
|
+
} catch (e) {
|
|
4785
|
+
logCatchDebug("migration", e);
|
|
4679
4786
|
}
|
|
4680
4787
|
try {
|
|
4681
4788
|
await client.execute({
|
|
4682
4789
|
sql: `ALTER TABLE memories ADD COLUMN consolidated INTEGER NOT NULL DEFAULT 0`,
|
|
4683
4790
|
args: []
|
|
4684
4791
|
});
|
|
4685
|
-
} catch {
|
|
4792
|
+
} catch (e) {
|
|
4793
|
+
logCatchDebug("migration", e);
|
|
4686
4794
|
}
|
|
4687
4795
|
try {
|
|
4688
4796
|
await client.execute({
|
|
4689
4797
|
sql: `ALTER TABLE memories ADD COLUMN author_device_id TEXT`,
|
|
4690
4798
|
args: []
|
|
4691
4799
|
});
|
|
4692
|
-
} catch {
|
|
4800
|
+
} catch (e) {
|
|
4801
|
+
logCatchDebug("migration", e);
|
|
4693
4802
|
}
|
|
4694
4803
|
try {
|
|
4695
4804
|
await client.execute({
|
|
4696
4805
|
sql: `ALTER TABLE memories ADD COLUMN scope TEXT NOT NULL DEFAULT 'business'`,
|
|
4697
4806
|
args: []
|
|
4698
4807
|
});
|
|
4699
|
-
} catch {
|
|
4808
|
+
} catch (e) {
|
|
4809
|
+
logCatchDebug("migration", e);
|
|
4700
4810
|
}
|
|
4701
4811
|
await client.executeMultiple(`
|
|
4702
4812
|
CREATE TABLE IF NOT EXISTS consolidations (
|
|
@@ -4801,14 +4911,16 @@ async function ensureSchema() {
|
|
|
4801
4911
|
sql: `ALTER TABLE notifications ADD COLUMN session_scope TEXT`,
|
|
4802
4912
|
args: []
|
|
4803
4913
|
});
|
|
4804
|
-
} catch {
|
|
4914
|
+
} catch (e) {
|
|
4915
|
+
logCatchDebug("migration", e);
|
|
4805
4916
|
}
|
|
4806
4917
|
try {
|
|
4807
4918
|
await client.execute({
|
|
4808
4919
|
sql: `ALTER TABLE messages ADD COLUMN session_scope TEXT`,
|
|
4809
4920
|
args: []
|
|
4810
4921
|
});
|
|
4811
|
-
} catch {
|
|
4922
|
+
} catch (e) {
|
|
4923
|
+
logCatchDebug("migration", e);
|
|
4812
4924
|
}
|
|
4813
4925
|
await client.executeMultiple(`
|
|
4814
4926
|
CREATE INDEX IF NOT EXISTS idx_notifications_agent_scope_read
|
|
@@ -4834,7 +4946,8 @@ async function ensureSchema() {
|
|
|
4834
4946
|
sql: `UPDATE tasks SET project_name = 'exe-os' WHERE project_name = 'worker'`,
|
|
4835
4947
|
args: []
|
|
4836
4948
|
});
|
|
4837
|
-
} catch {
|
|
4949
|
+
} catch (e) {
|
|
4950
|
+
logCatchDebug("migration", e);
|
|
4838
4951
|
}
|
|
4839
4952
|
await client.executeMultiple(`
|
|
4840
4953
|
CREATE TABLE IF NOT EXISTS trajectories (
|
|
@@ -4858,7 +4971,8 @@ async function ensureSchema() {
|
|
|
4858
4971
|
`);
|
|
4859
4972
|
try {
|
|
4860
4973
|
await client.execute("ALTER TABLE trajectories ADD COLUMN skill_id TEXT");
|
|
4861
|
-
} catch {
|
|
4974
|
+
} catch (e) {
|
|
4975
|
+
logCatchDebug("migration", e);
|
|
4862
4976
|
}
|
|
4863
4977
|
await client.executeMultiple(`
|
|
4864
4978
|
CREATE TABLE IF NOT EXISTS consolidations (
|
|
@@ -4895,63 +5009,72 @@ async function ensureSchema() {
|
|
|
4895
5009
|
sql: `ALTER TABLE memories ADD COLUMN consolidated INTEGER NOT NULL DEFAULT 0`,
|
|
4896
5010
|
args: []
|
|
4897
5011
|
});
|
|
4898
|
-
} catch {
|
|
5012
|
+
} catch (e) {
|
|
5013
|
+
logCatchDebug("migration", e);
|
|
4899
5014
|
}
|
|
4900
5015
|
try {
|
|
4901
5016
|
await client.execute({
|
|
4902
5017
|
sql: `ALTER TABLE memories ADD COLUMN importance INTEGER DEFAULT 5`,
|
|
4903
5018
|
args: []
|
|
4904
5019
|
});
|
|
4905
|
-
} catch {
|
|
5020
|
+
} catch (e) {
|
|
5021
|
+
logCatchDebug("migration", e);
|
|
4906
5022
|
}
|
|
4907
5023
|
try {
|
|
4908
5024
|
await client.execute({
|
|
4909
5025
|
sql: `ALTER TABLE memories ADD COLUMN status TEXT DEFAULT 'active'`,
|
|
4910
5026
|
args: []
|
|
4911
5027
|
});
|
|
4912
|
-
} catch {
|
|
5028
|
+
} catch (e) {
|
|
5029
|
+
logCatchDebug("migration", e);
|
|
4913
5030
|
}
|
|
4914
5031
|
try {
|
|
4915
5032
|
await client.execute({
|
|
4916
5033
|
sql: `ALTER TABLE memories ADD COLUMN deleted_at TEXT`,
|
|
4917
5034
|
args: []
|
|
4918
5035
|
});
|
|
4919
|
-
} catch {
|
|
5036
|
+
} catch (e) {
|
|
5037
|
+
logCatchDebug("migration", e);
|
|
4920
5038
|
}
|
|
4921
5039
|
try {
|
|
4922
5040
|
await client.execute({
|
|
4923
5041
|
sql: `ALTER TABLE memories ADD COLUMN confidence REAL DEFAULT 0.7`,
|
|
4924
5042
|
args: []
|
|
4925
5043
|
});
|
|
4926
|
-
} catch {
|
|
5044
|
+
} catch (e) {
|
|
5045
|
+
logCatchDebug("migration", e);
|
|
4927
5046
|
}
|
|
4928
5047
|
try {
|
|
4929
5048
|
await client.execute({
|
|
4930
5049
|
sql: `ALTER TABLE memories ADD COLUMN last_accessed TEXT`,
|
|
4931
5050
|
args: []
|
|
4932
5051
|
});
|
|
4933
|
-
} catch {
|
|
5052
|
+
} catch (e) {
|
|
5053
|
+
logCatchDebug("migration", e);
|
|
4934
5054
|
}
|
|
4935
5055
|
try {
|
|
4936
5056
|
await client.execute({
|
|
4937
5057
|
sql: `UPDATE memories SET last_accessed = timestamp WHERE last_accessed IS NULL`,
|
|
4938
5058
|
args: []
|
|
4939
5059
|
});
|
|
4940
|
-
} catch {
|
|
5060
|
+
} catch (e) {
|
|
5061
|
+
logCatchDebug("migration", e);
|
|
4941
5062
|
}
|
|
4942
5063
|
try {
|
|
4943
5064
|
await client.execute({
|
|
4944
5065
|
sql: `ALTER TABLE memories ADD COLUMN wiki_synced INTEGER DEFAULT 0`,
|
|
4945
5066
|
args: []
|
|
4946
5067
|
});
|
|
4947
|
-
} catch {
|
|
5068
|
+
} catch (e) {
|
|
5069
|
+
logCatchDebug("migration", e);
|
|
4948
5070
|
}
|
|
4949
5071
|
try {
|
|
4950
5072
|
await client.execute({
|
|
4951
5073
|
sql: `ALTER TABLE memories ADD COLUMN graph_extracted INTEGER DEFAULT 0`,
|
|
4952
5074
|
args: []
|
|
4953
5075
|
});
|
|
4954
|
-
} catch {
|
|
5076
|
+
} catch (e) {
|
|
5077
|
+
logCatchDebug("migration", e);
|
|
4955
5078
|
}
|
|
4956
5079
|
for (const col of [
|
|
4957
5080
|
"ALTER TABLE memories ADD COLUMN content_hash TEXT",
|
|
@@ -4959,14 +5082,16 @@ async function ensureSchema() {
|
|
|
4959
5082
|
]) {
|
|
4960
5083
|
try {
|
|
4961
5084
|
await client.execute(col);
|
|
4962
|
-
} catch {
|
|
5085
|
+
} catch (e) {
|
|
5086
|
+
logCatchDebug("migration", e);
|
|
4963
5087
|
}
|
|
4964
5088
|
}
|
|
4965
5089
|
try {
|
|
4966
5090
|
await client.execute(
|
|
4967
5091
|
`CREATE INDEX IF NOT EXISTS idx_memories_content_hash ON memories(content_hash, agent_id)`
|
|
4968
5092
|
);
|
|
4969
|
-
} catch {
|
|
5093
|
+
} catch (e) {
|
|
5094
|
+
logCatchDebug("migration", e);
|
|
4970
5095
|
}
|
|
4971
5096
|
try {
|
|
4972
5097
|
await client.execute(
|
|
@@ -4974,7 +5099,8 @@ async function ensureSchema() {
|
|
|
4974
5099
|
ON memories(content_hash, agent_id, project_name, memory_type)
|
|
4975
5100
|
WHERE content_hash IS NOT NULL`
|
|
4976
5101
|
);
|
|
4977
|
-
} catch {
|
|
5102
|
+
} catch (e) {
|
|
5103
|
+
logCatchDebug("migration", e);
|
|
4978
5104
|
}
|
|
4979
5105
|
await client.executeMultiple(`
|
|
4980
5106
|
CREATE TABLE IF NOT EXISTS entities (
|
|
@@ -5050,7 +5176,8 @@ async function ensureSchema() {
|
|
|
5050
5176
|
`);
|
|
5051
5177
|
try {
|
|
5052
5178
|
await client.execute("INSERT INTO entities_fts(entities_fts) VALUES('rebuild')");
|
|
5053
|
-
} catch {
|
|
5179
|
+
} catch (e) {
|
|
5180
|
+
logCatchDebug("migration", e);
|
|
5054
5181
|
}
|
|
5055
5182
|
await client.executeMultiple(`
|
|
5056
5183
|
CREATE TABLE IF NOT EXISTS entity_aliases (
|
|
@@ -5065,14 +5192,16 @@ async function ensureSchema() {
|
|
|
5065
5192
|
]) {
|
|
5066
5193
|
try {
|
|
5067
5194
|
await client.execute(col);
|
|
5068
|
-
} catch {
|
|
5195
|
+
} catch (e) {
|
|
5196
|
+
logCatchDebug("migration", e);
|
|
5069
5197
|
}
|
|
5070
5198
|
}
|
|
5071
5199
|
try {
|
|
5072
5200
|
await client.execute(
|
|
5073
5201
|
`CREATE INDEX IF NOT EXISTS idx_memories_status ON memories(status)`
|
|
5074
5202
|
);
|
|
5075
|
-
} catch {
|
|
5203
|
+
} catch (e) {
|
|
5204
|
+
logCatchDebug("migration", e);
|
|
5076
5205
|
}
|
|
5077
5206
|
await client.executeMultiple(`
|
|
5078
5207
|
CREATE TABLE IF NOT EXISTS identity (
|
|
@@ -5171,7 +5300,8 @@ async function ensureSchema() {
|
|
|
5171
5300
|
sql: `ALTER TABLE memories ADD COLUMN ${column}`,
|
|
5172
5301
|
args: []
|
|
5173
5302
|
});
|
|
5174
|
-
} catch {
|
|
5303
|
+
} catch (e) {
|
|
5304
|
+
logCatchDebug("migration", e);
|
|
5175
5305
|
}
|
|
5176
5306
|
}
|
|
5177
5307
|
for (const col of [
|
|
@@ -5180,7 +5310,8 @@ async function ensureSchema() {
|
|
|
5180
5310
|
]) {
|
|
5181
5311
|
try {
|
|
5182
5312
|
await client.execute(col);
|
|
5183
|
-
} catch {
|
|
5313
|
+
} catch (e) {
|
|
5314
|
+
logCatchDebug("migration", e);
|
|
5184
5315
|
}
|
|
5185
5316
|
}
|
|
5186
5317
|
await client.executeMultiple(`
|
|
@@ -5365,56 +5496,64 @@ async function ensureSchema() {
|
|
|
5365
5496
|
args: []
|
|
5366
5497
|
});
|
|
5367
5498
|
}
|
|
5368
|
-
} catch {
|
|
5499
|
+
} catch (e) {
|
|
5500
|
+
logCatchDebug("session_agent_map backfill", e);
|
|
5369
5501
|
}
|
|
5370
5502
|
try {
|
|
5371
5503
|
await client.execute({
|
|
5372
5504
|
sql: `ALTER TABLE session_agent_map ADD COLUMN cache_cold_count INTEGER NOT NULL DEFAULT 0`,
|
|
5373
5505
|
args: []
|
|
5374
5506
|
});
|
|
5375
|
-
} catch {
|
|
5507
|
+
} catch (e) {
|
|
5508
|
+
logCatchDebug("migration", e);
|
|
5376
5509
|
}
|
|
5377
5510
|
try {
|
|
5378
5511
|
await client.execute({
|
|
5379
5512
|
sql: `ALTER TABLE tasks ADD COLUMN budget_tokens INTEGER`,
|
|
5380
5513
|
args: []
|
|
5381
5514
|
});
|
|
5382
|
-
} catch {
|
|
5515
|
+
} catch (e) {
|
|
5516
|
+
logCatchDebug("migration", e);
|
|
5383
5517
|
}
|
|
5384
5518
|
try {
|
|
5385
5519
|
await client.execute({
|
|
5386
5520
|
sql: `ALTER TABLE tasks ADD COLUMN budget_fallback_model TEXT`,
|
|
5387
5521
|
args: []
|
|
5388
5522
|
});
|
|
5389
|
-
} catch {
|
|
5523
|
+
} catch (e) {
|
|
5524
|
+
logCatchDebug("migration", e);
|
|
5390
5525
|
}
|
|
5391
5526
|
try {
|
|
5392
5527
|
await client.execute({
|
|
5393
5528
|
sql: `ALTER TABLE tasks ADD COLUMN tokens_used INTEGER DEFAULT 0`,
|
|
5394
5529
|
args: []
|
|
5395
5530
|
});
|
|
5396
|
-
} catch {
|
|
5531
|
+
} catch (e) {
|
|
5532
|
+
logCatchDebug("migration", e);
|
|
5397
5533
|
}
|
|
5398
5534
|
try {
|
|
5399
5535
|
await client.execute({
|
|
5400
5536
|
sql: `ALTER TABLE tasks ADD COLUMN tokens_warned_at INTEGER`,
|
|
5401
5537
|
args: []
|
|
5402
5538
|
});
|
|
5403
|
-
} catch {
|
|
5539
|
+
} catch (e) {
|
|
5540
|
+
logCatchDebug("migration", e);
|
|
5404
5541
|
}
|
|
5405
5542
|
try {
|
|
5406
5543
|
await client.execute({
|
|
5407
5544
|
sql: `ALTER TABLE tasks ADD COLUMN spawn_runtime TEXT`,
|
|
5408
5545
|
args: []
|
|
5409
5546
|
});
|
|
5410
|
-
} catch {
|
|
5547
|
+
} catch (e) {
|
|
5548
|
+
logCatchDebug("migration", e);
|
|
5411
5549
|
}
|
|
5412
5550
|
try {
|
|
5413
5551
|
await client.execute({
|
|
5414
5552
|
sql: `ALTER TABLE tasks ADD COLUMN spawn_model TEXT`,
|
|
5415
5553
|
args: []
|
|
5416
5554
|
});
|
|
5417
|
-
} catch {
|
|
5555
|
+
} catch (e) {
|
|
5556
|
+
logCatchDebug("migration", e);
|
|
5418
5557
|
}
|
|
5419
5558
|
await client.executeMultiple(`
|
|
5420
5559
|
CREATE VIRTUAL TABLE IF NOT EXISTS conversations_fts USING fts5(
|
|
@@ -5613,13 +5752,15 @@ async function ensureSchema() {
|
|
|
5613
5752
|
sql: `ALTER TABLE memories ADD COLUMN tier INTEGER DEFAULT 3`,
|
|
5614
5753
|
args: []
|
|
5615
5754
|
});
|
|
5616
|
-
} catch {
|
|
5755
|
+
} catch (e) {
|
|
5756
|
+
logCatchDebug("migration", e);
|
|
5617
5757
|
}
|
|
5618
5758
|
try {
|
|
5619
5759
|
await client.execute(
|
|
5620
5760
|
`CREATE INDEX IF NOT EXISTS idx_memories_tier ON memories(tier)`
|
|
5621
5761
|
);
|
|
5622
|
-
} catch {
|
|
5762
|
+
} catch (e) {
|
|
5763
|
+
logCatchDebug("migration", e);
|
|
5623
5764
|
}
|
|
5624
5765
|
try {
|
|
5625
5766
|
await client.execute({
|
|
@@ -5630,20 +5771,23 @@ async function ensureSchema() {
|
|
|
5630
5771
|
sql: `UPDATE memories SET tier = 2 WHERE tool_name IN ('store_memory', 'manual') AND importance >= 5 AND tier = 3`,
|
|
5631
5772
|
args: []
|
|
5632
5773
|
});
|
|
5633
|
-
} catch {
|
|
5774
|
+
} catch (e) {
|
|
5775
|
+
logCatchDebug("migration", e);
|
|
5634
5776
|
}
|
|
5635
5777
|
try {
|
|
5636
5778
|
await client.execute({
|
|
5637
5779
|
sql: `ALTER TABLE memories ADD COLUMN supersedes_id TEXT`,
|
|
5638
5780
|
args: []
|
|
5639
5781
|
});
|
|
5640
|
-
} catch {
|
|
5782
|
+
} catch (e) {
|
|
5783
|
+
logCatchDebug("migration", e);
|
|
5641
5784
|
}
|
|
5642
5785
|
try {
|
|
5643
5786
|
await client.execute(
|
|
5644
5787
|
`CREATE INDEX IF NOT EXISTS idx_memories_supersedes ON memories(supersedes_id) WHERE supersedes_id IS NOT NULL`
|
|
5645
5788
|
);
|
|
5646
|
-
} catch {
|
|
5789
|
+
} catch (e) {
|
|
5790
|
+
logCatchDebug("migration", e);
|
|
5647
5791
|
}
|
|
5648
5792
|
for (const col of [
|
|
5649
5793
|
"ALTER TABLE tasks ADD COLUMN checkpoint TEXT",
|
|
@@ -5651,7 +5795,8 @@ async function ensureSchema() {
|
|
|
5651
5795
|
]) {
|
|
5652
5796
|
try {
|
|
5653
5797
|
await client.execute(col);
|
|
5654
|
-
} catch {
|
|
5798
|
+
} catch (e) {
|
|
5799
|
+
logCatchDebug("migration", e);
|
|
5655
5800
|
}
|
|
5656
5801
|
}
|
|
5657
5802
|
try {
|
|
@@ -5659,13 +5804,15 @@ async function ensureSchema() {
|
|
|
5659
5804
|
sql: `ALTER TABLE memories ADD COLUMN draft INTEGER DEFAULT 0`,
|
|
5660
5805
|
args: []
|
|
5661
5806
|
});
|
|
5662
|
-
} catch {
|
|
5807
|
+
} catch (e) {
|
|
5808
|
+
logCatchDebug("migration", e);
|
|
5663
5809
|
}
|
|
5664
5810
|
try {
|
|
5665
5811
|
await client.execute(
|
|
5666
5812
|
`CREATE INDEX IF NOT EXISTS idx_memories_draft ON memories(draft) WHERE draft = 1`
|
|
5667
5813
|
);
|
|
5668
|
-
} catch {
|
|
5814
|
+
} catch (e) {
|
|
5815
|
+
logCatchDebug("migration", e);
|
|
5669
5816
|
}
|
|
5670
5817
|
for (const col of [
|
|
5671
5818
|
"ALTER TABLE memories ADD COLUMN valid_from TEXT",
|
|
@@ -5673,7 +5820,8 @@ async function ensureSchema() {
|
|
|
5673
5820
|
]) {
|
|
5674
5821
|
try {
|
|
5675
5822
|
await client.execute(col);
|
|
5676
|
-
} catch {
|
|
5823
|
+
} catch (e) {
|
|
5824
|
+
logCatchDebug("migration", e);
|
|
5677
5825
|
}
|
|
5678
5826
|
}
|
|
5679
5827
|
try {
|
|
@@ -5681,27 +5829,31 @@ async function ensureSchema() {
|
|
|
5681
5829
|
sql: `UPDATE memories SET valid_from = timestamp WHERE valid_from IS NULL`,
|
|
5682
5830
|
args: []
|
|
5683
5831
|
});
|
|
5684
|
-
} catch {
|
|
5832
|
+
} catch (e) {
|
|
5833
|
+
logCatchDebug("migration", e);
|
|
5685
5834
|
}
|
|
5686
5835
|
try {
|
|
5687
5836
|
await client.execute({
|
|
5688
5837
|
sql: `ALTER TABLE memories ADD COLUMN memory_type TEXT DEFAULT 'raw'`,
|
|
5689
5838
|
args: []
|
|
5690
5839
|
});
|
|
5691
|
-
} catch {
|
|
5840
|
+
} catch (e) {
|
|
5841
|
+
logCatchDebug("migration", e);
|
|
5692
5842
|
}
|
|
5693
5843
|
try {
|
|
5694
5844
|
await client.execute(
|
|
5695
5845
|
`CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(memory_type)`
|
|
5696
5846
|
);
|
|
5697
|
-
} catch {
|
|
5847
|
+
} catch (e) {
|
|
5848
|
+
logCatchDebug("migration", e);
|
|
5698
5849
|
}
|
|
5699
5850
|
try {
|
|
5700
5851
|
await client.execute({
|
|
5701
5852
|
sql: `ALTER TABLE memories ADD COLUMN trajectory TEXT`,
|
|
5702
5853
|
args: []
|
|
5703
5854
|
});
|
|
5704
|
-
} catch {
|
|
5855
|
+
} catch (e) {
|
|
5856
|
+
logCatchDebug("migration", e);
|
|
5705
5857
|
}
|
|
5706
5858
|
for (const col of [
|
|
5707
5859
|
"ALTER TABLE memories ADD COLUMN intent TEXT",
|
|
@@ -5722,7 +5874,8 @@ async function ensureSchema() {
|
|
|
5722
5874
|
]) {
|
|
5723
5875
|
try {
|
|
5724
5876
|
await client.execute(col);
|
|
5725
|
-
} catch {
|
|
5877
|
+
} catch (e) {
|
|
5878
|
+
logCatchDebug("migration", e);
|
|
5726
5879
|
}
|
|
5727
5880
|
}
|
|
5728
5881
|
try {
|
|
@@ -5730,14 +5883,16 @@ async function ensureSchema() {
|
|
|
5730
5883
|
sql: `ALTER TABLE memories ADD COLUMN procedure_for TEXT`,
|
|
5731
5884
|
args: []
|
|
5732
5885
|
});
|
|
5733
|
-
} catch {
|
|
5886
|
+
} catch (e) {
|
|
5887
|
+
logCatchDebug("migration", e);
|
|
5734
5888
|
}
|
|
5735
5889
|
try {
|
|
5736
5890
|
await client.execute({
|
|
5737
5891
|
sql: `UPDATE tasks SET status = 'closed' WHERE status = 'done' AND result IS NOT NULL`,
|
|
5738
5892
|
args: []
|
|
5739
5893
|
});
|
|
5740
|
-
} catch {
|
|
5894
|
+
} catch (e) {
|
|
5895
|
+
logCatchDebug("migration", e);
|
|
5741
5896
|
}
|
|
5742
5897
|
}
|
|
5743
5898
|
async function disposeDatabase() {
|
|
@@ -5748,7 +5903,8 @@ async function disposeDatabase() {
|
|
|
5748
5903
|
if (_client) {
|
|
5749
5904
|
try {
|
|
5750
5905
|
await _client.execute("PRAGMA wal_checkpoint(PASSIVE)");
|
|
5751
|
-
} catch {
|
|
5906
|
+
} catch (e) {
|
|
5907
|
+
logCatchDebug("WAL checkpoint", e);
|
|
5752
5908
|
}
|
|
5753
5909
|
}
|
|
5754
5910
|
if (_daemonClient) {
|
|
@@ -5764,8 +5920,9 @@ async function disposeDatabase() {
|
|
|
5764
5920
|
_client = null;
|
|
5765
5921
|
_resilientClient = null;
|
|
5766
5922
|
}
|
|
5923
|
+
releaseDbLock();
|
|
5767
5924
|
}
|
|
5768
|
-
var _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
|
|
5925
|
+
var _debugDb, _client, _resilientClient, _walCheckpointTimer, _daemonClient, _adapterClient, _lockFd, DB_LOCK_PATH, initTurso, SOFT_DELETE_RETENTION_DAYS, disposeTurso;
|
|
5769
5926
|
var init_database = __esm({
|
|
5770
5927
|
"src/lib/database.ts"() {
|
|
5771
5928
|
"use strict";
|
|
@@ -5773,11 +5930,14 @@ var init_database = __esm({
|
|
|
5773
5930
|
init_employees();
|
|
5774
5931
|
init_database_adapter();
|
|
5775
5932
|
init_memory();
|
|
5933
|
+
_debugDb = process.env.EXE_DEBUG === "1";
|
|
5776
5934
|
_client = null;
|
|
5777
5935
|
_resilientClient = null;
|
|
5778
5936
|
_walCheckpointTimer = null;
|
|
5779
5937
|
_daemonClient = null;
|
|
5780
5938
|
_adapterClient = null;
|
|
5939
|
+
_lockFd = null;
|
|
5940
|
+
DB_LOCK_PATH = join(homedir(), ".exe-os", "db.lock");
|
|
5781
5941
|
initTurso = initDatabase;
|
|
5782
5942
|
SOFT_DELETE_RETENTION_DAYS = 7;
|
|
5783
5943
|
disposeTurso = disposeDatabase;
|
|
@@ -5929,7 +6089,7 @@ __export(license_exports, {
|
|
|
5929
6089
|
stopLicenseRevalidation: () => stopLicenseRevalidation,
|
|
5930
6090
|
validateLicense: () => validateLicense
|
|
5931
6091
|
});
|
|
5932
|
-
import { readFileSync as readFileSync10, writeFileSync as writeFileSync8, existsSync as
|
|
6092
|
+
import { readFileSync as readFileSync10, writeFileSync as writeFileSync8, existsSync as existsSync14, mkdirSync as mkdirSync7 } from "fs";
|
|
5933
6093
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
5934
6094
|
import { createRequire as createRequire2 } from "module";
|
|
5935
6095
|
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
@@ -5947,34 +6107,34 @@ async function fetchRetry(url, init) {
|
|
|
5947
6107
|
function loadDeviceId() {
|
|
5948
6108
|
const deviceJsonPath = path13.join(EXE_AI_DIR, "device.json");
|
|
5949
6109
|
try {
|
|
5950
|
-
if (
|
|
6110
|
+
if (existsSync14(deviceJsonPath)) {
|
|
5951
6111
|
const data = JSON.parse(readFileSync10(deviceJsonPath, "utf8"));
|
|
5952
6112
|
if (data.deviceId) return data.deviceId;
|
|
5953
6113
|
}
|
|
5954
6114
|
} catch {
|
|
5955
6115
|
}
|
|
5956
6116
|
try {
|
|
5957
|
-
if (
|
|
6117
|
+
if (existsSync14(DEVICE_ID_PATH)) {
|
|
5958
6118
|
const id2 = readFileSync10(DEVICE_ID_PATH, "utf8").trim();
|
|
5959
6119
|
if (id2) return id2;
|
|
5960
6120
|
}
|
|
5961
6121
|
} catch {
|
|
5962
6122
|
}
|
|
5963
6123
|
const id = randomUUID2();
|
|
5964
|
-
|
|
6124
|
+
mkdirSync7(EXE_AI_DIR, { recursive: true });
|
|
5965
6125
|
writeFileSync8(DEVICE_ID_PATH, id, "utf8");
|
|
5966
6126
|
return id;
|
|
5967
6127
|
}
|
|
5968
6128
|
function loadLicense() {
|
|
5969
6129
|
try {
|
|
5970
|
-
if (!
|
|
6130
|
+
if (!existsSync14(LICENSE_PATH)) return null;
|
|
5971
6131
|
return readFileSync10(LICENSE_PATH, "utf8").trim();
|
|
5972
6132
|
} catch {
|
|
5973
6133
|
return null;
|
|
5974
6134
|
}
|
|
5975
6135
|
}
|
|
5976
6136
|
function saveLicense(apiKey) {
|
|
5977
|
-
|
|
6137
|
+
mkdirSync7(EXE_AI_DIR, { recursive: true });
|
|
5978
6138
|
writeFileSync8(LICENSE_PATH, apiKey.trim(), { encoding: "utf8", mode: 384 });
|
|
5979
6139
|
}
|
|
5980
6140
|
async function verifyLicenseJwt(token) {
|
|
@@ -6001,7 +6161,7 @@ async function verifyLicenseJwt(token) {
|
|
|
6001
6161
|
}
|
|
6002
6162
|
async function getCachedLicense() {
|
|
6003
6163
|
try {
|
|
6004
|
-
if (!
|
|
6164
|
+
if (!existsSync14(CACHE_PATH)) return null;
|
|
6005
6165
|
const raw = JSON.parse(readFileSync10(CACHE_PATH, "utf8"));
|
|
6006
6166
|
if (!raw.token || typeof raw.token !== "string") return null;
|
|
6007
6167
|
return await verifyLicenseJwt(raw.token);
|
|
@@ -6011,7 +6171,7 @@ async function getCachedLicense() {
|
|
|
6011
6171
|
}
|
|
6012
6172
|
function readCachedLicenseToken() {
|
|
6013
6173
|
try {
|
|
6014
|
-
if (!
|
|
6174
|
+
if (!existsSync14(CACHE_PATH)) return null;
|
|
6015
6175
|
const raw = JSON.parse(readFileSync10(CACHE_PATH, "utf8"));
|
|
6016
6176
|
return typeof raw.token === "string" ? raw.token : null;
|
|
6017
6177
|
} catch {
|
|
@@ -6055,7 +6215,7 @@ function loadPrismaForLicense() {
|
|
|
6055
6215
|
const dbUrl = process.env.DATABASE_URL;
|
|
6056
6216
|
if (!dbUrl) {
|
|
6057
6217
|
const exeDbRoot = process.env.EXE_DB_ROOT ?? path13.join(os11.homedir(), "exe-db");
|
|
6058
|
-
if (!
|
|
6218
|
+
if (!existsSync14(path13.join(exeDbRoot, "package.json"))) {
|
|
6059
6219
|
_prismaFailed = true;
|
|
6060
6220
|
return null;
|
|
6061
6221
|
}
|
|
@@ -6159,7 +6319,7 @@ async function validateLicense(apiKey, deviceId) {
|
|
|
6159
6319
|
const cached = await getCachedLicense();
|
|
6160
6320
|
if (cached) return cached;
|
|
6161
6321
|
try {
|
|
6162
|
-
if (
|
|
6322
|
+
if (existsSync14(CACHE_PATH)) {
|
|
6163
6323
|
const raw = JSON.parse(readFileSync10(CACHE_PATH, "utf8"));
|
|
6164
6324
|
if (raw.pgLicense && raw.ts && Date.now() - raw.ts < 7 * 24 * 60 * 60 * 1e3) {
|
|
6165
6325
|
return raw.pgLicense;
|
|
@@ -6173,8 +6333,8 @@ async function validateLicense(apiKey, deviceId) {
|
|
|
6173
6333
|
}
|
|
6174
6334
|
function getCacheAgeMs() {
|
|
6175
6335
|
try {
|
|
6176
|
-
const { statSync:
|
|
6177
|
-
const s =
|
|
6336
|
+
const { statSync: statSync10 } = __require("fs");
|
|
6337
|
+
const s = statSync10(CACHE_PATH);
|
|
6178
6338
|
return Date.now() - s.mtimeMs;
|
|
6179
6339
|
} catch {
|
|
6180
6340
|
return Infinity;
|
|
@@ -6185,7 +6345,7 @@ async function checkLicense() {
|
|
|
6185
6345
|
if (!key) {
|
|
6186
6346
|
try {
|
|
6187
6347
|
const configPath = path13.join(EXE_AI_DIR, "config.json");
|
|
6188
|
-
if (
|
|
6348
|
+
if (existsSync14(configPath)) {
|
|
6189
6349
|
const raw = JSON.parse(readFileSync10(configPath, "utf8"));
|
|
6190
6350
|
const cloud = raw.cloud;
|
|
6191
6351
|
if (cloud?.apiKey) {
|
|
@@ -6397,9 +6557,9 @@ __export(crdt_sync_exports, {
|
|
|
6397
6557
|
rebuildFromDb: () => rebuildFromDb
|
|
6398
6558
|
});
|
|
6399
6559
|
import * as Y from "yjs";
|
|
6400
|
-
import { readFileSync as readFileSync11, writeFileSync as writeFileSync9, existsSync as
|
|
6560
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync9, existsSync as existsSync15, mkdirSync as mkdirSync8, unlinkSync as unlinkSync5 } from "fs";
|
|
6401
6561
|
import path14 from "path";
|
|
6402
|
-
import { homedir } from "os";
|
|
6562
|
+
import { homedir as homedir2 } from "os";
|
|
6403
6563
|
function getStatePath() {
|
|
6404
6564
|
return _statePathOverride ?? DEFAULT_STATE_PATH;
|
|
6405
6565
|
}
|
|
@@ -6410,14 +6570,14 @@ function initCrdtDoc() {
|
|
|
6410
6570
|
if (doc) return doc;
|
|
6411
6571
|
doc = new Y.Doc();
|
|
6412
6572
|
const sp = getStatePath();
|
|
6413
|
-
if (
|
|
6573
|
+
if (existsSync15(sp)) {
|
|
6414
6574
|
try {
|
|
6415
6575
|
const state = readFileSync11(sp);
|
|
6416
6576
|
Y.applyUpdate(doc, new Uint8Array(state));
|
|
6417
6577
|
} catch {
|
|
6418
6578
|
console.warn("[crdt-sync] WARN: corrupted state file, rebuilding from DB");
|
|
6419
6579
|
try {
|
|
6420
|
-
|
|
6580
|
+
unlinkSync5(sp);
|
|
6421
6581
|
} catch {
|
|
6422
6582
|
}
|
|
6423
6583
|
rebuildFromDb().catch((err) => {
|
|
@@ -6555,7 +6715,7 @@ function persistState() {
|
|
|
6555
6715
|
try {
|
|
6556
6716
|
const sp = getStatePath();
|
|
6557
6717
|
const dir = path14.dirname(sp);
|
|
6558
|
-
if (!
|
|
6718
|
+
if (!existsSync15(dir)) mkdirSync8(dir, { recursive: true });
|
|
6559
6719
|
const state = Y.encodeStateAsUpdate(doc);
|
|
6560
6720
|
writeFileSync9(sp, Buffer.from(state));
|
|
6561
6721
|
} catch {
|
|
@@ -6598,7 +6758,7 @@ var DEFAULT_STATE_PATH, _statePathOverride, doc;
|
|
|
6598
6758
|
var init_crdt_sync = __esm({
|
|
6599
6759
|
"src/lib/crdt-sync.ts"() {
|
|
6600
6760
|
"use strict";
|
|
6601
|
-
DEFAULT_STATE_PATH = path14.join(
|
|
6761
|
+
DEFAULT_STATE_PATH = path14.join(homedir2(), ".exe-os", "crdt-state.bin");
|
|
6602
6762
|
_statePathOverride = null;
|
|
6603
6763
|
doc = null;
|
|
6604
6764
|
}
|
|
@@ -6630,42 +6790,42 @@ __export(db_backup_exports, {
|
|
|
6630
6790
|
listBackups: () => listBackups,
|
|
6631
6791
|
rotateBackups: () => rotateBackups
|
|
6632
6792
|
});
|
|
6633
|
-
import { copyFileSync as
|
|
6793
|
+
import { copyFileSync as copyFileSync3, existsSync as existsSync16, mkdirSync as mkdirSync9, readdirSync, unlinkSync as unlinkSync6, statSync as statSync4 } from "fs";
|
|
6634
6794
|
import path15 from "path";
|
|
6635
6795
|
function findActiveDb() {
|
|
6636
6796
|
for (const name of DB_NAMES) {
|
|
6637
6797
|
const p = path15.join(EXE_AI_DIR, name);
|
|
6638
|
-
if (
|
|
6798
|
+
if (existsSync16(p)) return p;
|
|
6639
6799
|
}
|
|
6640
6800
|
return null;
|
|
6641
6801
|
}
|
|
6642
6802
|
function createBackup(reason = "manual") {
|
|
6643
6803
|
const dbPath = findActiveDb();
|
|
6644
6804
|
if (!dbPath) return null;
|
|
6645
|
-
|
|
6805
|
+
mkdirSync9(BACKUP_DIR, { recursive: true });
|
|
6646
6806
|
const dbName = path15.basename(dbPath, ".db");
|
|
6647
6807
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
6648
6808
|
const backupName = `${dbName}-${reason}-${timestamp}.db`;
|
|
6649
6809
|
const backupPath = path15.join(BACKUP_DIR, backupName);
|
|
6650
|
-
|
|
6810
|
+
copyFileSync3(dbPath, backupPath);
|
|
6651
6811
|
const walPath = dbPath + "-wal";
|
|
6652
|
-
if (
|
|
6812
|
+
if (existsSync16(walPath)) {
|
|
6653
6813
|
try {
|
|
6654
|
-
|
|
6814
|
+
copyFileSync3(walPath, backupPath + "-wal");
|
|
6655
6815
|
} catch {
|
|
6656
6816
|
}
|
|
6657
6817
|
}
|
|
6658
6818
|
const shmPath = dbPath + "-shm";
|
|
6659
|
-
if (
|
|
6819
|
+
if (existsSync16(shmPath)) {
|
|
6660
6820
|
try {
|
|
6661
|
-
|
|
6821
|
+
copyFileSync3(shmPath, backupPath + "-shm");
|
|
6662
6822
|
} catch {
|
|
6663
6823
|
}
|
|
6664
6824
|
}
|
|
6665
6825
|
return backupPath;
|
|
6666
6826
|
}
|
|
6667
6827
|
function rotateBackups(keepDays = DEFAULT_KEEP_DAYS) {
|
|
6668
|
-
if (!
|
|
6828
|
+
if (!existsSync16(BACKUP_DIR)) return 0;
|
|
6669
6829
|
const cutoff = Date.now() - keepDays * 24 * 60 * 60 * 1e3;
|
|
6670
6830
|
let deleted = 0;
|
|
6671
6831
|
try {
|
|
@@ -6674,9 +6834,9 @@ function rotateBackups(keepDays = DEFAULT_KEEP_DAYS) {
|
|
|
6674
6834
|
if (!file.endsWith(".db") && !file.endsWith(".db-wal") && !file.endsWith(".db-shm")) continue;
|
|
6675
6835
|
const filePath = path15.join(BACKUP_DIR, file);
|
|
6676
6836
|
try {
|
|
6677
|
-
const stat2 =
|
|
6837
|
+
const stat2 = statSync4(filePath);
|
|
6678
6838
|
if (stat2.mtimeMs < cutoff) {
|
|
6679
|
-
|
|
6839
|
+
unlinkSync6(filePath);
|
|
6680
6840
|
deleted++;
|
|
6681
6841
|
}
|
|
6682
6842
|
} catch {
|
|
@@ -6687,12 +6847,12 @@ function rotateBackups(keepDays = DEFAULT_KEEP_DAYS) {
|
|
|
6687
6847
|
return deleted;
|
|
6688
6848
|
}
|
|
6689
6849
|
function listBackups() {
|
|
6690
|
-
if (!
|
|
6850
|
+
if (!existsSync16(BACKUP_DIR)) return [];
|
|
6691
6851
|
try {
|
|
6692
6852
|
const files = readdirSync(BACKUP_DIR).filter((f) => f.endsWith(".db") && !f.endsWith("-wal") && !f.endsWith("-shm"));
|
|
6693
6853
|
return files.map((name) => {
|
|
6694
6854
|
const p = path15.join(BACKUP_DIR, name);
|
|
6695
|
-
const stat2 =
|
|
6855
|
+
const stat2 = statSync4(p);
|
|
6696
6856
|
return { path: p, name, size: stat2.size, date: stat2.mtime };
|
|
6697
6857
|
}).sort((a, b) => b.date.getTime() - a.date.getTime());
|
|
6698
6858
|
} catch {
|
|
@@ -6758,16 +6918,16 @@ __export(cloud_sync_exports, {
|
|
|
6758
6918
|
pushToPostgres: () => pushToPostgres,
|
|
6759
6919
|
recordRosterDeletion: () => recordRosterDeletion
|
|
6760
6920
|
});
|
|
6761
|
-
import { readFileSync as readFileSync12, writeFileSync as writeFileSync10, existsSync as
|
|
6921
|
+
import { readFileSync as readFileSync12, writeFileSync as writeFileSync10, existsSync as existsSync17, readdirSync as readdirSync2, mkdirSync as mkdirSync10, appendFileSync, unlinkSync as unlinkSync7, openSync as openSync3, closeSync as closeSync3, statSync as statSync5 } from "fs";
|
|
6762
6922
|
import crypto4 from "crypto";
|
|
6763
6923
|
import path16 from "path";
|
|
6764
|
-
import { homedir as
|
|
6924
|
+
import { homedir as homedir3 } from "os";
|
|
6765
6925
|
function sqlSafe(v) {
|
|
6766
6926
|
return v === void 0 ? null : v;
|
|
6767
6927
|
}
|
|
6768
6928
|
function logError(msg) {
|
|
6769
6929
|
try {
|
|
6770
|
-
const logPath = path16.join(
|
|
6930
|
+
const logPath = path16.join(homedir3(), ".exe-os", "workers.log");
|
|
6771
6931
|
appendFileSync(logPath, `${(/* @__PURE__ */ new Date()).toISOString()} ${msg}
|
|
6772
6932
|
`);
|
|
6773
6933
|
} catch {
|
|
@@ -6782,7 +6942,7 @@ function loadPgClient() {
|
|
|
6782
6942
|
let cloudPostgresUrl;
|
|
6783
6943
|
let configEnabled = false;
|
|
6784
6944
|
try {
|
|
6785
|
-
if (
|
|
6945
|
+
if (existsSync17(configPath)) {
|
|
6786
6946
|
const cfg = JSON.parse(readFileSync12(configPath, "utf8"));
|
|
6787
6947
|
cloudPostgresUrl = cfg.cloud?.postgresUrl;
|
|
6788
6948
|
configEnabled = cfg.cloud?.syncToPostgres === true;
|
|
@@ -6810,9 +6970,9 @@ function loadPgClient() {
|
|
|
6810
6970
|
if (!Ctor) throw new Error(`No PrismaClient at ${explicitPath}`);
|
|
6811
6971
|
return new Ctor();
|
|
6812
6972
|
}
|
|
6813
|
-
const exeDbRoot = process.env.EXE_DB_ROOT ?? path16.join(
|
|
6973
|
+
const exeDbRoot = process.env.EXE_DB_ROOT ?? path16.join(homedir3(), "exe-db");
|
|
6814
6974
|
const packagePath = path16.join(exeDbRoot, "package.json");
|
|
6815
|
-
if (
|
|
6975
|
+
if (existsSync17(packagePath)) {
|
|
6816
6976
|
const req = createRequire3(packagePath);
|
|
6817
6977
|
const entry = req.resolve("@prisma/client");
|
|
6818
6978
|
const mod = await import(pathToFileURL3(entry).href);
|
|
@@ -6873,8 +7033,8 @@ async function pushToPostgres(records) {
|
|
|
6873
7033
|
}
|
|
6874
7034
|
async function withRosterLock(fn) {
|
|
6875
7035
|
try {
|
|
6876
|
-
const fd =
|
|
6877
|
-
|
|
7036
|
+
const fd = openSync3(ROSTER_LOCK_PATH, "wx");
|
|
7037
|
+
closeSync3(fd);
|
|
6878
7038
|
writeFileSync10(ROSTER_LOCK_PATH, String(Date.now()));
|
|
6879
7039
|
} catch (err) {
|
|
6880
7040
|
if (err.code === "EEXIST") {
|
|
@@ -6883,9 +7043,9 @@ async function withRosterLock(fn) {
|
|
|
6883
7043
|
if (Date.now() - ts2 < LOCK_STALE_MS) {
|
|
6884
7044
|
throw new Error("Roster merge already in progress \u2014 another sync is running");
|
|
6885
7045
|
}
|
|
6886
|
-
|
|
6887
|
-
const fd =
|
|
6888
|
-
|
|
7046
|
+
unlinkSync7(ROSTER_LOCK_PATH);
|
|
7047
|
+
const fd = openSync3(ROSTER_LOCK_PATH, "wx");
|
|
7048
|
+
closeSync3(fd);
|
|
6889
7049
|
writeFileSync10(ROSTER_LOCK_PATH, String(Date.now()));
|
|
6890
7050
|
} catch (retryErr) {
|
|
6891
7051
|
if (retryErr instanceof Error && retryErr.message.includes("already in progress")) throw retryErr;
|
|
@@ -6899,7 +7059,7 @@ async function withRosterLock(fn) {
|
|
|
6899
7059
|
return await fn();
|
|
6900
7060
|
} finally {
|
|
6901
7061
|
try {
|
|
6902
|
-
|
|
7062
|
+
unlinkSync7(ROSTER_LOCK_PATH);
|
|
6903
7063
|
} catch {
|
|
6904
7064
|
}
|
|
6905
7065
|
}
|
|
@@ -7333,7 +7493,7 @@ async function cloudSync(config) {
|
|
|
7333
7493
|
const employees = await loadEmployees();
|
|
7334
7494
|
rosterResult.employees = employees.length;
|
|
7335
7495
|
const idDir = path16.join(EXE_AI_DIR, "identity");
|
|
7336
|
-
if (
|
|
7496
|
+
if (existsSync17(idDir)) {
|
|
7337
7497
|
rosterResult.identities = readdirSync2(idDir).filter((f) => f.endsWith(".md")).length;
|
|
7338
7498
|
}
|
|
7339
7499
|
} catch {
|
|
@@ -7343,7 +7503,7 @@ async function cloudSync(config) {
|
|
|
7343
7503
|
const { getLatestBackup: getLatestBackup2 } = await Promise.resolve().then(() => (init_db_backup(), db_backup_exports));
|
|
7344
7504
|
const latestBackup = getLatestBackup2();
|
|
7345
7505
|
if (latestBackup) {
|
|
7346
|
-
const backupSize =
|
|
7506
|
+
const backupSize = statSync5(latestBackup).size;
|
|
7347
7507
|
const MAX_CLOUD_BACKUP_BYTES = 50 * 1024 * 1024;
|
|
7348
7508
|
if (backupSize <= MAX_CLOUD_BACKUP_BYTES) {
|
|
7349
7509
|
const backupData = readFileSync12(latestBackup);
|
|
@@ -7394,7 +7554,7 @@ async function cloudSync(config) {
|
|
|
7394
7554
|
function recordRosterDeletion(name) {
|
|
7395
7555
|
let deletions = [];
|
|
7396
7556
|
try {
|
|
7397
|
-
if (
|
|
7557
|
+
if (existsSync17(ROSTER_DELETIONS_PATH)) {
|
|
7398
7558
|
deletions = JSON.parse(readFileSync12(ROSTER_DELETIONS_PATH, "utf-8"));
|
|
7399
7559
|
}
|
|
7400
7560
|
} catch {
|
|
@@ -7404,7 +7564,7 @@ function recordRosterDeletion(name) {
|
|
|
7404
7564
|
}
|
|
7405
7565
|
function consumeRosterDeletions() {
|
|
7406
7566
|
try {
|
|
7407
|
-
if (!
|
|
7567
|
+
if (!existsSync17(ROSTER_DELETIONS_PATH)) return [];
|
|
7408
7568
|
const deletions = JSON.parse(readFileSync12(ROSTER_DELETIONS_PATH, "utf-8"));
|
|
7409
7569
|
writeFileSync10(ROSTER_DELETIONS_PATH, "[]");
|
|
7410
7570
|
return deletions;
|
|
@@ -7417,14 +7577,14 @@ function buildRosterBlob(paths) {
|
|
|
7417
7577
|
const identityDir = paths?.identityDir ?? path16.join(EXE_AI_DIR, "identity");
|
|
7418
7578
|
const configPath = paths?.configPath ?? path16.join(EXE_AI_DIR, "config.json");
|
|
7419
7579
|
let roster = [];
|
|
7420
|
-
if (
|
|
7580
|
+
if (existsSync17(rosterPath)) {
|
|
7421
7581
|
try {
|
|
7422
7582
|
roster = JSON.parse(readFileSync12(rosterPath, "utf-8"));
|
|
7423
7583
|
} catch {
|
|
7424
7584
|
}
|
|
7425
7585
|
}
|
|
7426
7586
|
const identities = {};
|
|
7427
|
-
if (
|
|
7587
|
+
if (existsSync17(identityDir)) {
|
|
7428
7588
|
for (const file of readdirSync2(identityDir).filter((f) => f.endsWith(".md"))) {
|
|
7429
7589
|
try {
|
|
7430
7590
|
identities[file] = readFileSync12(path16.join(identityDir, file), "utf-8");
|
|
@@ -7433,7 +7593,7 @@ function buildRosterBlob(paths) {
|
|
|
7433
7593
|
}
|
|
7434
7594
|
}
|
|
7435
7595
|
let config;
|
|
7436
|
-
if (
|
|
7596
|
+
if (existsSync17(configPath)) {
|
|
7437
7597
|
try {
|
|
7438
7598
|
config = JSON.parse(readFileSync12(configPath, "utf-8"));
|
|
7439
7599
|
} catch {
|
|
@@ -7441,7 +7601,7 @@ function buildRosterBlob(paths) {
|
|
|
7441
7601
|
}
|
|
7442
7602
|
let agentConfig;
|
|
7443
7603
|
const agentConfigPath = path16.join(EXE_AI_DIR, "agent-config.json");
|
|
7444
|
-
if (
|
|
7604
|
+
if (existsSync17(agentConfigPath)) {
|
|
7445
7605
|
try {
|
|
7446
7606
|
agentConfig = JSON.parse(readFileSync12(agentConfigPath, "utf-8"));
|
|
7447
7607
|
} catch {
|
|
@@ -7521,7 +7681,7 @@ async function cloudPullRoster(config) {
|
|
|
7521
7681
|
function mergeConfig(remoteConfig, configPath) {
|
|
7522
7682
|
const cfgPath = configPath ?? path16.join(EXE_AI_DIR, "config.json");
|
|
7523
7683
|
let local = {};
|
|
7524
|
-
if (
|
|
7684
|
+
if (existsSync17(cfgPath)) {
|
|
7525
7685
|
try {
|
|
7526
7686
|
local = JSON.parse(readFileSync12(cfgPath, "utf-8"));
|
|
7527
7687
|
} catch {
|
|
@@ -7557,11 +7717,11 @@ async function mergeRosterFromRemote(remote, paths) {
|
|
|
7557
7717
|
) ?? lookupKey;
|
|
7558
7718
|
const remoteIdentity = remote.identities[matchedKey];
|
|
7559
7719
|
if (remoteIdentity) {
|
|
7560
|
-
if (!
|
|
7720
|
+
if (!existsSync17(identityDir)) mkdirSync10(identityDir, { recursive: true });
|
|
7561
7721
|
const idPath = path16.join(identityDir, `${remoteEmp.name}.md`);
|
|
7562
7722
|
let localIdentity = null;
|
|
7563
7723
|
try {
|
|
7564
|
-
localIdentity =
|
|
7724
|
+
localIdentity = existsSync17(idPath) ? readFileSync12(idPath, "utf-8") : null;
|
|
7565
7725
|
} catch {
|
|
7566
7726
|
}
|
|
7567
7727
|
if (localIdentity !== remoteIdentity) {
|
|
@@ -7593,7 +7753,7 @@ async function mergeRosterFromRemote(remote, paths) {
|
|
|
7593
7753
|
try {
|
|
7594
7754
|
const agentConfigPath = path16.join(EXE_AI_DIR, "agent-config.json");
|
|
7595
7755
|
let local = {};
|
|
7596
|
-
if (
|
|
7756
|
+
if (existsSync17(agentConfigPath)) {
|
|
7597
7757
|
try {
|
|
7598
7758
|
local = JSON.parse(readFileSync12(agentConfigPath, "utf-8"));
|
|
7599
7759
|
} catch {
|
|
@@ -8028,14 +8188,14 @@ async function cloudPullDocuments(config) {
|
|
|
8028
8188
|
}
|
|
8029
8189
|
async function cloudPushCodeContext(config) {
|
|
8030
8190
|
assertSecureEndpoint(config.endpoint);
|
|
8031
|
-
if (!
|
|
8191
|
+
if (!existsSync17(CODE_CONTEXT_DIR)) return 0;
|
|
8032
8192
|
const files = readdirSync2(CODE_CONTEXT_DIR).filter(
|
|
8033
8193
|
(f) => f.endsWith(".json") && !f.endsWith(".vectors.json") && !f.startsWith(".")
|
|
8034
8194
|
);
|
|
8035
8195
|
if (files.length === 0) return 0;
|
|
8036
8196
|
const metaPath = path16.join(CODE_CONTEXT_DIR, ".sync-meta.json");
|
|
8037
8197
|
let syncMeta = {};
|
|
8038
|
-
if (
|
|
8198
|
+
if (existsSync17(metaPath)) {
|
|
8039
8199
|
try {
|
|
8040
8200
|
syncMeta = JSON.parse(readFileSync12(metaPath, "utf-8"));
|
|
8041
8201
|
} catch {
|
|
@@ -8045,7 +8205,7 @@ async function cloudPushCodeContext(config) {
|
|
|
8045
8205
|
for (const file of files) {
|
|
8046
8206
|
const filePath = path16.join(CODE_CONTEXT_DIR, file);
|
|
8047
8207
|
try {
|
|
8048
|
-
const stat2 =
|
|
8208
|
+
const stat2 = statSync5(filePath);
|
|
8049
8209
|
const lastPushed = syncMeta[file] ?? 0;
|
|
8050
8210
|
if (stat2.mtimeMs <= lastPushed) continue;
|
|
8051
8211
|
const content = readFileSync12(filePath, "utf-8");
|
|
@@ -8090,7 +8250,7 @@ async function cloudPullCodeContext(config) {
|
|
|
8090
8250
|
if (!resp.ok) return 0;
|
|
8091
8251
|
const data = await resp.json();
|
|
8092
8252
|
if (!data.indexes || data.indexes.length === 0) return 0;
|
|
8093
|
-
|
|
8253
|
+
mkdirSync10(CODE_CONTEXT_DIR, { recursive: true });
|
|
8094
8254
|
let pulled = 0;
|
|
8095
8255
|
for (const { key, blob } of data.indexes) {
|
|
8096
8256
|
try {
|
|
@@ -8098,7 +8258,7 @@ async function cloudPullCodeContext(config) {
|
|
|
8098
8258
|
const localPath = path16.join(CODE_CONTEXT_DIR, key);
|
|
8099
8259
|
const compressed = decryptSyncBlob(blob);
|
|
8100
8260
|
const content = decompress(compressed).toString("utf8");
|
|
8101
|
-
if (!
|
|
8261
|
+
if (!existsSync17(localPath)) {
|
|
8102
8262
|
writeFileSync10(localPath, content, "utf-8");
|
|
8103
8263
|
pulled++;
|
|
8104
8264
|
} else {
|
|
@@ -8408,18 +8568,54 @@ __export(shard_manager_exports, {
|
|
|
8408
8568
|
shardExists: () => shardExists
|
|
8409
8569
|
});
|
|
8410
8570
|
import path17 from "path";
|
|
8411
|
-
import { existsSync as
|
|
8571
|
+
import { existsSync as existsSync18, mkdirSync as mkdirSync11, readdirSync as readdirSync3, renameSync as renameSync3, statSync as statSync6 } from "fs";
|
|
8412
8572
|
import { createClient as createClient2 } from "@libsql/client";
|
|
8413
8573
|
function initShardManager(encryptionKey) {
|
|
8414
8574
|
_encryptionKey = encryptionKey;
|
|
8415
|
-
|
|
8416
|
-
|
|
8575
|
+
_keyValidated = false;
|
|
8576
|
+
_keyValidationPromise = null;
|
|
8577
|
+
if (!existsSync18(SHARDS_DIR)) {
|
|
8578
|
+
mkdirSync11(SHARDS_DIR, { recursive: true });
|
|
8579
|
+
}
|
|
8580
|
+
const existingShards = readdirSync3(SHARDS_DIR).filter((f) => f.endsWith(".db"));
|
|
8581
|
+
if (existingShards.length === 0) {
|
|
8582
|
+
_keyValidated = true;
|
|
8417
8583
|
}
|
|
8418
8584
|
_shardingEnabled = true;
|
|
8419
8585
|
if (_evictionTimer) clearInterval(_evictionTimer);
|
|
8420
8586
|
_evictionTimer = setInterval(evictIdleShards, EVICTION_INTERVAL_MS);
|
|
8421
8587
|
_evictionTimer.unref();
|
|
8422
8588
|
}
|
|
8589
|
+
async function validateEncryptionKey() {
|
|
8590
|
+
if (_keyValidated) return true;
|
|
8591
|
+
if (!_encryptionKey) return false;
|
|
8592
|
+
const existingShards = readdirSync3(SHARDS_DIR).filter((f) => f.endsWith(".db"));
|
|
8593
|
+
if (existingShards.length === 0) {
|
|
8594
|
+
_keyValidated = true;
|
|
8595
|
+
return true;
|
|
8596
|
+
}
|
|
8597
|
+
for (const shardFile of existingShards.slice(0, 3)) {
|
|
8598
|
+
const dbPath = path17.join(SHARDS_DIR, shardFile);
|
|
8599
|
+
const testClient = createClient2({ url: `file:${dbPath}`, encryptionKey: _encryptionKey });
|
|
8600
|
+
try {
|
|
8601
|
+
await testClient.execute("SELECT COUNT(*) FROM sqlite_schema");
|
|
8602
|
+
testClient.close();
|
|
8603
|
+
_keyValidated = true;
|
|
8604
|
+
return true;
|
|
8605
|
+
} catch {
|
|
8606
|
+
try {
|
|
8607
|
+
testClient.close();
|
|
8608
|
+
} catch {
|
|
8609
|
+
}
|
|
8610
|
+
}
|
|
8611
|
+
}
|
|
8612
|
+
process.stderr.write(
|
|
8613
|
+
`[shard-manager] WARNING: encryption key cannot read any existing shards (${existingShards.length} found). New shard creation disabled to prevent stranded files. Run /exe-doctor to audit.
|
|
8614
|
+
`
|
|
8615
|
+
);
|
|
8616
|
+
_shardingEnabled = false;
|
|
8617
|
+
return false;
|
|
8618
|
+
}
|
|
8423
8619
|
function isShardingEnabled() {
|
|
8424
8620
|
return _shardingEnabled;
|
|
8425
8621
|
}
|
|
@@ -8453,13 +8649,13 @@ function getShardClient(projectName) {
|
|
|
8453
8649
|
}
|
|
8454
8650
|
function shardExists(projectName) {
|
|
8455
8651
|
const safeName = safeShardName(projectName);
|
|
8456
|
-
return
|
|
8652
|
+
return existsSync18(path17.join(SHARDS_DIR, `${safeName}.db`));
|
|
8457
8653
|
}
|
|
8458
8654
|
function safeShardName(projectName) {
|
|
8459
8655
|
return projectName.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
8460
8656
|
}
|
|
8461
8657
|
function listShards() {
|
|
8462
|
-
if (!
|
|
8658
|
+
if (!existsSync18(SHARDS_DIR)) return [];
|
|
8463
8659
|
return readdirSync3(SHARDS_DIR).filter((f) => f.endsWith(".db")).map((f) => f.replace(".db", ""));
|
|
8464
8660
|
}
|
|
8465
8661
|
async function auditShardHealth(options = {}) {
|
|
@@ -8472,7 +8668,7 @@ async function auditShardHealth(options = {}) {
|
|
|
8472
8668
|
const shards = [];
|
|
8473
8669
|
for (const name of names) {
|
|
8474
8670
|
const dbPath = path17.join(SHARDS_DIR, `${name}.db`);
|
|
8475
|
-
const stat2 =
|
|
8671
|
+
const stat2 = statSync6(dbPath);
|
|
8476
8672
|
const item = {
|
|
8477
8673
|
name,
|
|
8478
8674
|
path: dbPath,
|
|
@@ -8712,6 +8908,17 @@ async function ensureShardSchema(client) {
|
|
|
8712
8908
|
}
|
|
8713
8909
|
}
|
|
8714
8910
|
async function getReadyShardClient(projectName) {
|
|
8911
|
+
if (!_keyValidated) {
|
|
8912
|
+
if (!_keyValidationPromise) {
|
|
8913
|
+
_keyValidationPromise = validateEncryptionKey();
|
|
8914
|
+
}
|
|
8915
|
+
const valid = await _keyValidationPromise;
|
|
8916
|
+
if (!valid) {
|
|
8917
|
+
throw new Error(
|
|
8918
|
+
`Shard creation blocked: encryption key mismatch with existing shards. Run /exe-doctor to audit.`
|
|
8919
|
+
);
|
|
8920
|
+
}
|
|
8921
|
+
}
|
|
8715
8922
|
const safeName = safeShardName(projectName);
|
|
8716
8923
|
let client = getShardClient(projectName);
|
|
8717
8924
|
try {
|
|
@@ -8724,8 +8931,8 @@ async function getReadyShardClient(projectName) {
|
|
|
8724
8931
|
_shards.delete(safeName);
|
|
8725
8932
|
_shardLastAccess.delete(safeName);
|
|
8726
8933
|
const dbPath = path17.join(SHARDS_DIR, `${safeName}.db`);
|
|
8727
|
-
if (
|
|
8728
|
-
const stat2 =
|
|
8934
|
+
if (existsSync18(dbPath)) {
|
|
8935
|
+
const stat2 = statSync6(dbPath);
|
|
8729
8936
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
8730
8937
|
const archivedPath = path17.join(SHARDS_DIR, `${safeName}.db.broken-${stamp}`);
|
|
8731
8938
|
renameSync3(dbPath, archivedPath);
|
|
@@ -8790,7 +8997,7 @@ function disposeShards() {
|
|
|
8790
8997
|
_shardingEnabled = false;
|
|
8791
8998
|
_encryptionKey = null;
|
|
8792
8999
|
}
|
|
8793
|
-
var SHARDS_DIR, SHARD_IDLE_MS, MAX_OPEN_SHARDS, EVICTION_INTERVAL_MS, _shards, _shardLastAccess, _evictionTimer, _encryptionKey, _shardingEnabled;
|
|
9000
|
+
var SHARDS_DIR, SHARD_IDLE_MS, MAX_OPEN_SHARDS, EVICTION_INTERVAL_MS, _shards, _shardLastAccess, _evictionTimer, _encryptionKey, _shardingEnabled, _keyValidated, _keyValidationPromise;
|
|
8794
9001
|
var init_shard_manager = __esm({
|
|
8795
9002
|
"src/lib/shard-manager.ts"() {
|
|
8796
9003
|
"use strict";
|
|
@@ -8804,6 +9011,8 @@ var init_shard_manager = __esm({
|
|
|
8804
9011
|
_evictionTimer = null;
|
|
8805
9012
|
_encryptionKey = null;
|
|
8806
9013
|
_shardingEnabled = false;
|
|
9014
|
+
_keyValidated = false;
|
|
9015
|
+
_keyValidationPromise = null;
|
|
8807
9016
|
}
|
|
8808
9017
|
});
|
|
8809
9018
|
|
|
@@ -8999,6 +9208,18 @@ var init_platform_procedures = __esm({
|
|
|
8999
9208
|
priority: "p0",
|
|
9000
9209
|
content: "create_task is dispatch + delivery. Task lifecycle: open \u2192 in_progress (you start) \u2192 done (update_task when finished) \u2192 needs_review (reviewer nudged) \u2192 closed (COO only via close_task). DB is the reliable delivery \u2014 intercom is just a speedup nudge. If you finish a task, self-chain: check for next task immediately (step 7). Never wait for a nudge. Never say 'standing by.'"
|
|
9001
9210
|
},
|
|
9211
|
+
{
|
|
9212
|
+
title: "Review chain \u2014 managers must actively pull completed work, never wait for nudges",
|
|
9213
|
+
domain: "workflow",
|
|
9214
|
+
priority: "p0",
|
|
9215
|
+
content: "When you dispatch work, you OWN the review. Check list_tasks(status='needs_review') on EVERY prompt \u2014 don't wait for intercom nudges (they're unreliable). When a task shows needs_review: (1) read the deliverable (git diff in worktree, exe/output/ files, or task result summary), (2) verify it works (tsc, build, run), (3) close_task if good or create a fix task if not. Reviews sitting >30 minutes is a pipeline stall. The whole chain: worker calls update_task(done) \u2192 system flags needs_review \u2192 manager pulls and verifies \u2192 close_task \u2192 COO reviews manager's work \u2192 merge to main. Every level actively pulls \u2014 nobody waits."
|
|
9216
|
+
},
|
|
9217
|
+
{
|
|
9218
|
+
title: "Bug fix lifecycle \u2014 triage upstream after every verified fix so customers see the status",
|
|
9219
|
+
domain: "workflow",
|
|
9220
|
+
priority: "p0",
|
|
9221
|
+
content: "When a bug from support(action='list_bugs') is fixed and verified, the reviewer MUST triage it upstream: support(action='triage_bug', id='<bug-id>', notes='<what was fixed>', fixed_version='<version>', linked_commit='<hash>'). This closes the bug in the customer's view \u2014 their COO checks list_my_bugs and sees status change from open \u2192 closed with the fix version. Without triage, customers see 'open' forever even after the fix ships. Same for feature requests: support(action='triage_feature', ..., shipped_version='<version>'). Triage is part of the review gate \u2014 a fix is not done until the upstream report is closed."
|
|
9222
|
+
},
|
|
9002
9223
|
{
|
|
9003
9224
|
title: "Intercom is a speedup, not delivery \u2014 DB is the source of truth",
|
|
9004
9225
|
domain: "architecture",
|
|
@@ -9596,6 +9817,20 @@ __export(store_exports, {
|
|
|
9596
9817
|
vectorToBlob: () => vectorToBlob,
|
|
9597
9818
|
writeMemory: () => writeMemory
|
|
9598
9819
|
});
|
|
9820
|
+
function logStoreDebug(context, err) {
|
|
9821
|
+
if (_debugStore) {
|
|
9822
|
+
process.stderr.write(
|
|
9823
|
+
`[store] ${context}: ${err instanceof Error ? err.message : String(err)}
|
|
9824
|
+
`
|
|
9825
|
+
);
|
|
9826
|
+
}
|
|
9827
|
+
}
|
|
9828
|
+
function logStoreWarn(context, err) {
|
|
9829
|
+
process.stderr.write(
|
|
9830
|
+
`[store] WARN ${context}: ${err instanceof Error ? err.message : String(err)}
|
|
9831
|
+
`
|
|
9832
|
+
);
|
|
9833
|
+
}
|
|
9599
9834
|
function isBusyError2(err) {
|
|
9600
9835
|
if (err instanceof Error) {
|
|
9601
9836
|
const msg = err.message.toLowerCase();
|
|
@@ -9650,13 +9885,15 @@ async function initStore(options) {
|
|
|
9650
9885
|
try {
|
|
9651
9886
|
const { initDaemonClient: initDaemonClient2 } = await Promise.resolve().then(() => (init_database(), database_exports));
|
|
9652
9887
|
await initDaemonClient2();
|
|
9653
|
-
} catch {
|
|
9888
|
+
} catch (e) {
|
|
9889
|
+
logStoreWarn("catch", e);
|
|
9654
9890
|
}
|
|
9655
9891
|
if (!options?.lightweight) {
|
|
9656
9892
|
try {
|
|
9657
9893
|
const { initShardManager: initShardManager2 } = await Promise.resolve().then(() => (init_shard_manager(), shard_manager_exports));
|
|
9658
9894
|
initShardManager2(hexKey);
|
|
9659
|
-
} catch {
|
|
9895
|
+
} catch (e) {
|
|
9896
|
+
logStoreWarn("catch", e);
|
|
9660
9897
|
}
|
|
9661
9898
|
const client = getClient();
|
|
9662
9899
|
const vResult = await retryOnBusy2(
|
|
@@ -9667,7 +9904,8 @@ async function initStore(options) {
|
|
|
9667
9904
|
try {
|
|
9668
9905
|
const { loadGlobalProcedures: loadGlobalProcedures2 } = await Promise.resolve().then(() => (init_global_procedures(), global_procedures_exports));
|
|
9669
9906
|
await loadGlobalProcedures2();
|
|
9670
|
-
} catch {
|
|
9907
|
+
} catch (e) {
|
|
9908
|
+
logStoreWarn("catch", e);
|
|
9671
9909
|
}
|
|
9672
9910
|
}
|
|
9673
9911
|
}
|
|
@@ -9727,7 +9965,8 @@ async function writeMemory(record) {
|
|
|
9727
9965
|
memoryType
|
|
9728
9966
|
});
|
|
9729
9967
|
if (existing) return;
|
|
9730
|
-
} catch {
|
|
9968
|
+
} catch (e) {
|
|
9969
|
+
logStoreWarn("catch", e);
|
|
9731
9970
|
}
|
|
9732
9971
|
const dbRow = {
|
|
9733
9972
|
id: record.id,
|
|
@@ -9928,12 +10167,14 @@ async function flushBatch() {
|
|
|
9928
10167
|
try {
|
|
9929
10168
|
const { insertMemoryCardsForBatch: insertMemoryCardsForBatch2 } = await Promise.resolve().then(() => (init_memory_cards(), memory_cards_exports));
|
|
9930
10169
|
await insertMemoryCardsForBatch2(batch);
|
|
9931
|
-
} catch {
|
|
10170
|
+
} catch (e) {
|
|
10171
|
+
logStoreWarn("catch", e);
|
|
9932
10172
|
}
|
|
9933
10173
|
try {
|
|
9934
10174
|
const { insertOntologyForBatch: insertOntologyForBatch2 } = await Promise.resolve().then(() => (init_agentic_ontology(), agentic_ontology_exports));
|
|
9935
10175
|
await insertOntologyForBatch2(batch);
|
|
9936
|
-
} catch {
|
|
10176
|
+
} catch (e) {
|
|
10177
|
+
logStoreWarn("catch", e);
|
|
9937
10178
|
}
|
|
9938
10179
|
schedulePostWriteMemoryHygiene(batch.map((row) => row.id));
|
|
9939
10180
|
_pendingRecords.splice(0, batch.length);
|
|
@@ -9972,7 +10213,8 @@ ${err.stack.split("\n").slice(1, 3).join("\n")}` : ""}` : String(err);
|
|
|
9972
10213
|
}
|
|
9973
10214
|
}
|
|
9974
10215
|
}
|
|
9975
|
-
} catch {
|
|
10216
|
+
} catch (e) {
|
|
10217
|
+
logStoreWarn("catch", e);
|
|
9976
10218
|
}
|
|
9977
10219
|
return batch.length;
|
|
9978
10220
|
} finally {
|
|
@@ -10014,7 +10256,8 @@ async function searchMemories(queryVector, agentId, options) {
|
|
|
10014
10256
|
} else {
|
|
10015
10257
|
client = getClient();
|
|
10016
10258
|
}
|
|
10017
|
-
} catch {
|
|
10259
|
+
} catch (e) {
|
|
10260
|
+
logStoreDebug("shard routing fallback", e);
|
|
10018
10261
|
client = getClient();
|
|
10019
10262
|
}
|
|
10020
10263
|
const limit = options?.limit ?? 10;
|
|
@@ -10130,7 +10373,8 @@ async function attachDocumentMetadata(records) {
|
|
|
10130
10373
|
if (!record.document_id) continue;
|
|
10131
10374
|
record.document_metadata = byId.get(record.document_id) ?? null;
|
|
10132
10375
|
}
|
|
10133
|
-
} catch {
|
|
10376
|
+
} catch (e) {
|
|
10377
|
+
logStoreWarn("catch", e);
|
|
10134
10378
|
}
|
|
10135
10379
|
return records;
|
|
10136
10380
|
}
|
|
@@ -10191,11 +10435,12 @@ async function getMemoryCardinality(agentId) {
|
|
|
10191
10435
|
args: [agentId]
|
|
10192
10436
|
});
|
|
10193
10437
|
return Number(result.rows[0]?.cnt) || 0;
|
|
10194
|
-
} catch {
|
|
10438
|
+
} catch (e) {
|
|
10439
|
+
logStoreWarn("getMemoryCardinality", e);
|
|
10195
10440
|
return 0;
|
|
10196
10441
|
}
|
|
10197
10442
|
}
|
|
10198
|
-
var INIT_MAX_RETRIES, INIT_RETRY_DELAY_MS, _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
10443
|
+
var _debugStore, INIT_MAX_RETRIES, INIT_RETRY_DELAY_MS, _pendingRecords, _batchSize, _flushIntervalMs, _flushTimer, _flushing, _nextVersion;
|
|
10199
10444
|
var init_store = __esm({
|
|
10200
10445
|
"src/lib/store.ts"() {
|
|
10201
10446
|
"use strict";
|
|
@@ -10205,6 +10450,7 @@ var init_store = __esm({
|
|
|
10205
10450
|
init_config();
|
|
10206
10451
|
init_state_bus();
|
|
10207
10452
|
init_memory_write_governor();
|
|
10453
|
+
_debugStore = process.env.EXE_DEBUG === "1";
|
|
10208
10454
|
INIT_MAX_RETRIES = 3;
|
|
10209
10455
|
INIT_RETRY_DELAY_MS = 1e3;
|
|
10210
10456
|
_pendingRecords = [];
|
|
@@ -10223,14 +10469,14 @@ __export(key_backup_status_exports, {
|
|
|
10223
10469
|
keyBackupMarkerPath: () => keyBackupMarkerPath,
|
|
10224
10470
|
markKeyBackupConfirmed: () => markKeyBackupConfirmed
|
|
10225
10471
|
});
|
|
10226
|
-
import { existsSync as
|
|
10472
|
+
import { existsSync as existsSync19, mkdirSync as mkdirSync12, readFileSync as readFileSync13, writeFileSync as writeFileSync11 } from "fs";
|
|
10227
10473
|
import path18 from "path";
|
|
10228
10474
|
function keyBackupMarkerPath() {
|
|
10229
10475
|
return path18.join(EXE_AI_DIR, "key-backup-confirmed.json");
|
|
10230
10476
|
}
|
|
10231
10477
|
function getKeyBackupStatus() {
|
|
10232
10478
|
const marker = keyBackupMarkerPath();
|
|
10233
|
-
if (!
|
|
10479
|
+
if (!existsSync19(marker)) return { exists: false };
|
|
10234
10480
|
try {
|
|
10235
10481
|
const parsed = JSON.parse(readFileSync13(marker, "utf8"));
|
|
10236
10482
|
return {
|
|
@@ -10243,7 +10489,7 @@ function getKeyBackupStatus() {
|
|
|
10243
10489
|
}
|
|
10244
10490
|
}
|
|
10245
10491
|
function markKeyBackupConfirmed(source) {
|
|
10246
|
-
|
|
10492
|
+
mkdirSync12(EXE_AI_DIR, { recursive: true, mode: 448 });
|
|
10247
10493
|
writeFileSync11(
|
|
10248
10494
|
keyBackupMarkerPath(),
|
|
10249
10495
|
JSON.stringify({ confirmedAt: (/* @__PURE__ */ new Date()).toISOString(), source }, null, 2) + "\n",
|
|
@@ -10709,7 +10955,7 @@ __export(exe_key_exports, {
|
|
|
10709
10955
|
});
|
|
10710
10956
|
import crypto5 from "crypto";
|
|
10711
10957
|
import { createInterface as createInterface2 } from "readline";
|
|
10712
|
-
import { existsSync as
|
|
10958
|
+
import { existsSync as existsSync20, statSync as statSync7, mkdirSync as mkdirSync13, copyFileSync as copyFileSync4, renameSync as renameSync4, rmSync, writeFileSync as writeFileSync12 } from "fs";
|
|
10713
10959
|
import path19 from "path";
|
|
10714
10960
|
import os12 from "os";
|
|
10715
10961
|
import { execSync as execSync5 } from "child_process";
|
|
@@ -10742,7 +10988,7 @@ function dbSidecarPaths(dbPath) {
|
|
|
10742
10988
|
}
|
|
10743
10989
|
function daemonStatus() {
|
|
10744
10990
|
const pidPath = path19.join(dataDir(), "exed.pid");
|
|
10745
|
-
if (!
|
|
10991
|
+
if (!existsSync20(pidPath)) return { pid: null, alive: false };
|
|
10746
10992
|
const pid = execSync5(`cat ${JSON.stringify(pidPath)}`, { encoding: "utf8" }).trim();
|
|
10747
10993
|
if (!pid) return { pid: null, alive: false };
|
|
10748
10994
|
try {
|
|
@@ -10801,8 +11047,8 @@ async function preflight() {
|
|
|
10801
11047
|
console.log("\u2713 Memory encryption key found");
|
|
10802
11048
|
const config = await loadConfig();
|
|
10803
11049
|
const dbPath = expandHome(config.dbPath);
|
|
10804
|
-
if (!
|
|
10805
|
-
const dbSize =
|
|
11050
|
+
if (!existsSync20(dbPath)) throw new Error(`DB not found at ${dbPath}`);
|
|
11051
|
+
const dbSize = statSync7(dbPath).size;
|
|
10806
11052
|
console.log(`\u2713 DB exists: ${dbPath} (${humanBytes(dbSize)})`);
|
|
10807
11053
|
await initDatabase({ dbPath: config.dbPath, encryptionKey: key.toString("hex") });
|
|
10808
11054
|
const client = getClient();
|
|
@@ -10923,9 +11169,9 @@ async function rotateWizard(argv) {
|
|
|
10923
11169
|
}
|
|
10924
11170
|
const rotationId = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
10925
11171
|
const baseDir = path19.join(dataDir(), "key-rotation", rotationId);
|
|
10926
|
-
|
|
11172
|
+
mkdirSync13(baseDir, { recursive: true, mode: 448 });
|
|
10927
11173
|
const backupDir = path19.join(baseDir, "pre-rotation-encrypted-backup");
|
|
10928
|
-
|
|
11174
|
+
mkdirSync13(backupDir, { recursive: true, mode: 448 });
|
|
10929
11175
|
const newDbPath = path19.join(baseDir, "new-memories.db");
|
|
10930
11176
|
const newKey = crypto5.randomBytes(32);
|
|
10931
11177
|
const newKeyTempPath = path19.join(baseDir, "NEW_KEY_DO_NOT_SHARE.base64");
|
|
@@ -10938,7 +11184,7 @@ async function rotateWizard(argv) {
|
|
|
10938
11184
|
const dbDir = path19.dirname(pf.dbPath);
|
|
10939
11185
|
for (const name of ["memories.db", "memories.db-wal", "memories.db-shm"]) {
|
|
10940
11186
|
const src = path19.join(dbDir, name);
|
|
10941
|
-
if (
|
|
11187
|
+
if (existsSync20(src)) copyFileSync4(src, path19.join(backupDir, name));
|
|
10942
11188
|
}
|
|
10943
11189
|
console.log("Creating fresh encrypted DB with new key...");
|
|
10944
11190
|
await initDatabase({ dbPath: newDbPath, encryptionKey: newKey.toString("hex") });
|
|
@@ -10976,9 +11222,9 @@ async function rotateWizard(argv) {
|
|
|
10976
11222
|
console.log("Swapping DB files...");
|
|
10977
11223
|
for (const name of ["memories.db", "memories.db-wal", "memories.db-shm"]) {
|
|
10978
11224
|
const current = path19.join(dbDir, name);
|
|
10979
|
-
if (
|
|
11225
|
+
if (existsSync20(current)) renameSync4(current, path19.join(backupDir, `moved-${name}`));
|
|
10980
11226
|
}
|
|
10981
|
-
|
|
11227
|
+
copyFileSync4(newDbPath, pf.dbPath);
|
|
10982
11228
|
rmSync(path19.join(dbDir, "memories.db-wal"), { force: true });
|
|
10983
11229
|
rmSync(path19.join(dbDir, "memories.db-shm"), { force: true });
|
|
10984
11230
|
console.log("Installing new key into OS keychain...");
|
|
@@ -11111,7 +11357,7 @@ async function acceptRotationWizard(argv) {
|
|
|
11111
11357
|
console.error("Configure cloud first, or use `exe-os cloud` if this is a new device setup.");
|
|
11112
11358
|
return 1;
|
|
11113
11359
|
}
|
|
11114
|
-
const existingDbFiles = dbSidecarPaths(dbPath).filter(
|
|
11360
|
+
const existingDbFiles = dbSidecarPaths(dbPath).filter(existsSync20);
|
|
11115
11361
|
if (existingDbFiles.length > 0) {
|
|
11116
11362
|
console.log(`Existing DB files: ${existingDbFiles.map((p) => path19.basename(p)).join(", ")}`);
|
|
11117
11363
|
} else {
|
|
@@ -11145,7 +11391,7 @@ async function acceptRotationWizard(argv) {
|
|
|
11145
11391
|
const acceptId = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
11146
11392
|
const baseDir = path19.join(dataDir(), "key-acceptance", acceptId);
|
|
11147
11393
|
const backupDir = path19.join(baseDir, "pre-acceptance-encrypted-db");
|
|
11148
|
-
|
|
11394
|
+
mkdirSync13(backupDir, { recursive: true, mode: 448 });
|
|
11149
11395
|
if (existingKey) {
|
|
11150
11396
|
writeFileSync12(path19.join(baseDir, "OLD_KEY_BACKUP_DELETE_AFTER_VERIFICATION.base64"), `${existingKey.toString("base64")}
|
|
11151
11397
|
`, { mode: 384 });
|
|
@@ -11156,7 +11402,7 @@ async function acceptRotationWizard(argv) {
|
|
|
11156
11402
|
for (const file of dbSidecarPaths(dbPath)) {
|
|
11157
11403
|
rmSync(file, { force: true });
|
|
11158
11404
|
const backup = path19.join(backupDir, path19.basename(file));
|
|
11159
|
-
if (
|
|
11405
|
+
if (existsSync20(backup)) copyFileSync4(backup, file);
|
|
11160
11406
|
}
|
|
11161
11407
|
};
|
|
11162
11408
|
console.log(`Acceptance workspace: ${baseDir}`);
|
|
@@ -11165,11 +11411,11 @@ async function acceptRotationWizard(argv) {
|
|
|
11165
11411
|
await disposeDatabase();
|
|
11166
11412
|
console.log("Backing up/moving old local DB files...");
|
|
11167
11413
|
const dbDir = path19.dirname(dbPath);
|
|
11168
|
-
|
|
11414
|
+
mkdirSync13(dbDir, { recursive: true, mode: 448 });
|
|
11169
11415
|
for (const file of dbSidecarPaths(dbPath)) {
|
|
11170
|
-
if (!
|
|
11416
|
+
if (!existsSync20(file)) continue;
|
|
11171
11417
|
const dest = path19.join(backupDir, path19.basename(file));
|
|
11172
|
-
|
|
11418
|
+
copyFileSync4(file, dest);
|
|
11173
11419
|
renameSync4(file, path19.join(backupDir, `moved-${path19.basename(file)}`));
|
|
11174
11420
|
console.log(`\u2713 moved ${path19.basename(file)}`);
|
|
11175
11421
|
}
|
|
@@ -11261,7 +11507,7 @@ __export(exe_support_exports, {
|
|
|
11261
11507
|
runHealth: () => runHealth,
|
|
11262
11508
|
runTest: () => runTest
|
|
11263
11509
|
});
|
|
11264
|
-
import { mkdirSync as
|
|
11510
|
+
import { mkdirSync as mkdirSync14, readFileSync as readFileSync14, unlinkSync as unlinkSync8, writeFileSync as writeFileSync13 } from "fs";
|
|
11265
11511
|
import path20 from "path";
|
|
11266
11512
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
11267
11513
|
async function main4(argv = process.argv.slice(2)) {
|
|
@@ -11407,9 +11653,9 @@ function checkLocalWrite() {
|
|
|
11407
11653
|
const dir = path20.join(EXE_AI_DIR, "bug-reports");
|
|
11408
11654
|
const testPath = path20.join(dir, ".support-write-test");
|
|
11409
11655
|
try {
|
|
11410
|
-
|
|
11656
|
+
mkdirSync14(dir, { recursive: true, mode: 448 });
|
|
11411
11657
|
writeFileSync13(testPath, "ok\n", { mode: 384 });
|
|
11412
|
-
|
|
11658
|
+
unlinkSync8(testPath);
|
|
11413
11659
|
return { check: "local_bug_report_dir_writable", level: "pass", detail: dir };
|
|
11414
11660
|
} catch (err) {
|
|
11415
11661
|
return {
|
|
@@ -11422,7 +11668,7 @@ function checkLocalWrite() {
|
|
|
11422
11668
|
}
|
|
11423
11669
|
function writeLocalTestReport(id, project, version) {
|
|
11424
11670
|
const dir = path20.join(EXE_AI_DIR, "bug-reports");
|
|
11425
|
-
|
|
11671
|
+
mkdirSync14(dir, { recursive: true, mode: 448 });
|
|
11426
11672
|
const date = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
11427
11673
|
const filePath = path20.join(dir, `${date}-support-intake-test-${id.slice(0, 8)}.md`);
|
|
11428
11674
|
writeFileSync13(filePath, `# TEST \u2014 ${project} support intake
|
|
@@ -11641,10 +11887,10 @@ import { createReadStream } from "fs";
|
|
|
11641
11887
|
import { readdir as readdir2, stat } from "fs/promises";
|
|
11642
11888
|
import path21 from "path";
|
|
11643
11889
|
import { createInterface as createInterface3 } from "readline";
|
|
11644
|
-
import { homedir as
|
|
11890
|
+
import { homedir as homedir4 } from "os";
|
|
11645
11891
|
import { parseArgs } from "util";
|
|
11646
11892
|
async function findJsonlFiles(sinceDate, projectFilter) {
|
|
11647
|
-
const projectsDir = path21.join(
|
|
11893
|
+
const projectsDir = path21.join(homedir4(), ".claude", "projects");
|
|
11648
11894
|
const files = [];
|
|
11649
11895
|
async function walk(dir, depth = 0) {
|
|
11650
11896
|
if (depth > MAX_WALK_DEPTH) return;
|
|
@@ -11689,7 +11935,7 @@ async function findJsonlFiles(sinceDate, projectFilter) {
|
|
|
11689
11935
|
return files;
|
|
11690
11936
|
}
|
|
11691
11937
|
function decodeProjectDir(dirName) {
|
|
11692
|
-
const homeEncoded =
|
|
11938
|
+
const homeEncoded = homedir4().replaceAll("/", "-");
|
|
11693
11939
|
if (dirName.startsWith(homeEncoded + "-")) {
|
|
11694
11940
|
return dirName.slice(homeEncoded.length + 1);
|
|
11695
11941
|
}
|
|
@@ -11697,7 +11943,7 @@ function decodeProjectDir(dirName) {
|
|
|
11697
11943
|
return dirName;
|
|
11698
11944
|
}
|
|
11699
11945
|
function projectNameFromPath(filePath) {
|
|
11700
|
-
const projectsDir = path21.join(
|
|
11946
|
+
const projectsDir = path21.join(homedir4(), ".claude", "projects");
|
|
11701
11947
|
const relative = path21.relative(projectsDir, filePath);
|
|
11702
11948
|
const projectDir = relative.split(path21.sep)[0] ?? "unknown";
|
|
11703
11949
|
return decodeProjectDir(projectDir);
|
|
@@ -12611,13 +12857,13 @@ __export(identity_exports, {
|
|
|
12611
12857
|
listIdentities: () => listIdentities,
|
|
12612
12858
|
updateIdentity: () => updateIdentity
|
|
12613
12859
|
});
|
|
12614
|
-
import { existsSync as
|
|
12860
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync15, readFileSync as readFileSync15, writeFileSync as writeFileSync14 } from "fs";
|
|
12615
12861
|
import { readdirSync as readdirSync4 } from "fs";
|
|
12616
12862
|
import path22 from "path";
|
|
12617
12863
|
import { createHash as createHash5 } from "crypto";
|
|
12618
12864
|
function ensureDir() {
|
|
12619
|
-
if (!
|
|
12620
|
-
|
|
12865
|
+
if (!existsSync21(IDENTITY_DIR2)) {
|
|
12866
|
+
mkdirSync15(IDENTITY_DIR2, { recursive: true });
|
|
12621
12867
|
}
|
|
12622
12868
|
}
|
|
12623
12869
|
function identityPath(agentId) {
|
|
@@ -12665,7 +12911,7 @@ function contentHash(content) {
|
|
|
12665
12911
|
}
|
|
12666
12912
|
function getIdentity(agentId) {
|
|
12667
12913
|
const filePath = identityPath(agentId);
|
|
12668
|
-
if (!
|
|
12914
|
+
if (!existsSync21(filePath)) return null;
|
|
12669
12915
|
const raw = readFileSync15(filePath, "utf-8");
|
|
12670
12916
|
const { frontmatter, body } = parseFrontmatter(raw);
|
|
12671
12917
|
return {
|
|
@@ -12744,7 +12990,7 @@ var init_identity = __esm({
|
|
|
12744
12990
|
|
|
12745
12991
|
// src/lib/orchestration-package.ts
|
|
12746
12992
|
import { randomUUID as randomUUID5 } from "crypto";
|
|
12747
|
-
import { copyFileSync as
|
|
12993
|
+
import { copyFileSync as copyFileSync5, existsSync as existsSync22, mkdirSync as mkdirSync16, readFileSync as readFileSync16, writeFileSync as writeFileSync15 } from "fs";
|
|
12748
12994
|
import os13 from "os";
|
|
12749
12995
|
import path23 from "path";
|
|
12750
12996
|
function ensureObject(value, label) {
|
|
@@ -12812,7 +13058,7 @@ function getBackupPath() {
|
|
|
12812
13058
|
}
|
|
12813
13059
|
function readRosterFile() {
|
|
12814
13060
|
const rosterPath = getRosterPath();
|
|
12815
|
-
if (!
|
|
13061
|
+
if (!existsSync22(rosterPath)) return [];
|
|
12816
13062
|
const raw = readFileSync16(rosterPath, "utf-8");
|
|
12817
13063
|
const parsed = JSON.parse(raw);
|
|
12818
13064
|
if (!Array.isArray(parsed)) {
|
|
@@ -12825,15 +13071,15 @@ function writeRosterFile(roster) {
|
|
|
12825
13071
|
throw new Error("Refusing to write empty roster \u2014 this would delete all employees");
|
|
12826
13072
|
}
|
|
12827
13073
|
const rosterPath = getRosterPath();
|
|
12828
|
-
|
|
12829
|
-
if (
|
|
13074
|
+
mkdirSync16(path23.dirname(rosterPath), { recursive: true });
|
|
13075
|
+
if (existsSync22(rosterPath)) {
|
|
12830
13076
|
const currentRoster = readRosterFile();
|
|
12831
13077
|
if (roster.length < currentRoster.length) {
|
|
12832
13078
|
throw new Error(
|
|
12833
13079
|
`Refusing to write roster with ${roster.length} entries \u2014 current roster has ${currentRoster.length}. Import would delete ${currentRoster.length - roster.length} employee(s). Use merge strategy instead, or add the missing entries to the package.`
|
|
12834
13080
|
);
|
|
12835
13081
|
}
|
|
12836
|
-
|
|
13082
|
+
copyFileSync5(rosterPath, getBackupPath());
|
|
12837
13083
|
}
|
|
12838
13084
|
writeFileSync15(rosterPath, `${JSON.stringify(roster, null, 2)}
|
|
12839
13085
|
`, "utf-8");
|
|
@@ -13102,7 +13348,7 @@ var exe_export_exports = {};
|
|
|
13102
13348
|
__export(exe_export_exports, {
|
|
13103
13349
|
runExeExport: () => runExeExport
|
|
13104
13350
|
});
|
|
13105
|
-
import { mkdirSync as
|
|
13351
|
+
import { mkdirSync as mkdirSync17, writeFileSync as writeFileSync16 } from "fs";
|
|
13106
13352
|
import path24 from "path";
|
|
13107
13353
|
function printUsage() {
|
|
13108
13354
|
process.stdout.write("Usage: exe-os export --output <path>\n");
|
|
@@ -13124,7 +13370,7 @@ async function runExeExport(argv = process.argv.slice(2)) {
|
|
|
13124
13370
|
await initStore();
|
|
13125
13371
|
try {
|
|
13126
13372
|
const pkg = await exportOrchestration("cli");
|
|
13127
|
-
|
|
13373
|
+
mkdirSync17(path24.dirname(outputPath), { recursive: true });
|
|
13128
13374
|
writeFileSync16(outputPath, `${JSON.stringify(pkg, null, 2)}
|
|
13129
13375
|
`, "utf-8");
|
|
13130
13376
|
process.stdout.write(
|
|
@@ -13225,14 +13471,14 @@ __export(session_registry_exports, {
|
|
|
13225
13471
|
refreshSessionProject: () => refreshSessionProject,
|
|
13226
13472
|
registerSession: () => registerSession
|
|
13227
13473
|
});
|
|
13228
|
-
import { readFileSync as readFileSync18, writeFileSync as writeFileSync17, mkdirSync as
|
|
13474
|
+
import { readFileSync as readFileSync18, writeFileSync as writeFileSync17, mkdirSync as mkdirSync18, existsSync as existsSync23 } from "fs";
|
|
13229
13475
|
import { execSync as execSync6 } from "child_process";
|
|
13230
13476
|
import path25 from "path";
|
|
13231
13477
|
import os14 from "os";
|
|
13232
13478
|
function registerSession(entry) {
|
|
13233
13479
|
const dir = path25.dirname(REGISTRY_PATH);
|
|
13234
|
-
if (!
|
|
13235
|
-
|
|
13480
|
+
if (!existsSync23(dir)) {
|
|
13481
|
+
mkdirSync18(dir, { recursive: true });
|
|
13236
13482
|
}
|
|
13237
13483
|
const sessions = listSessions();
|
|
13238
13484
|
const idx = sessions.findIndex((s) => s.windowName === entry.windowName);
|
|
@@ -13540,16 +13786,16 @@ __export(intercom_queue_exports, {
|
|
|
13540
13786
|
queueIntercom: () => queueIntercom,
|
|
13541
13787
|
readQueue: () => readQueue
|
|
13542
13788
|
});
|
|
13543
|
-
import { readFileSync as readFileSync19, writeFileSync as writeFileSync18, renameSync as renameSync5, existsSync as
|
|
13789
|
+
import { readFileSync as readFileSync19, writeFileSync as writeFileSync18, renameSync as renameSync5, existsSync as existsSync24, mkdirSync as mkdirSync19 } from "fs";
|
|
13544
13790
|
import path26 from "path";
|
|
13545
13791
|
import os15 from "os";
|
|
13546
13792
|
function ensureDir2() {
|
|
13547
13793
|
const dir = path26.dirname(QUEUE_PATH);
|
|
13548
|
-
if (!
|
|
13794
|
+
if (!existsSync24(dir)) mkdirSync19(dir, { recursive: true });
|
|
13549
13795
|
}
|
|
13550
13796
|
function readQueue() {
|
|
13551
13797
|
try {
|
|
13552
|
-
if (!
|
|
13798
|
+
if (!existsSync24(QUEUE_PATH)) return [];
|
|
13553
13799
|
return JSON.parse(readFileSync19(QUEUE_PATH, "utf8"));
|
|
13554
13800
|
} catch {
|
|
13555
13801
|
return [];
|
|
@@ -13658,11 +13904,11 @@ var init_intercom_queue = __esm({
|
|
|
13658
13904
|
});
|
|
13659
13905
|
|
|
13660
13906
|
// src/lib/plan-limits.ts
|
|
13661
|
-
import { readFileSync as readFileSync20, existsSync as
|
|
13907
|
+
import { readFileSync as readFileSync20, existsSync as existsSync25 } from "fs";
|
|
13662
13908
|
import path27 from "path";
|
|
13663
13909
|
function getLicenseSync() {
|
|
13664
13910
|
try {
|
|
13665
|
-
if (!
|
|
13911
|
+
if (!existsSync25(CACHE_PATH2)) return freeLicense();
|
|
13666
13912
|
const raw = JSON.parse(readFileSync20(CACHE_PATH2, "utf8"));
|
|
13667
13913
|
if (!raw.token || typeof raw.token !== "string") return freeLicense();
|
|
13668
13914
|
const parts = raw.token.split(".");
|
|
@@ -13701,7 +13947,7 @@ function assertEmployeeLimitSync(rosterPath) {
|
|
|
13701
13947
|
const filePath = rosterPath ?? EMPLOYEES_PATH;
|
|
13702
13948
|
let count = 0;
|
|
13703
13949
|
try {
|
|
13704
|
-
if (
|
|
13950
|
+
if (existsSync25(filePath)) {
|
|
13705
13951
|
const raw = readFileSync20(filePath, "utf8");
|
|
13706
13952
|
const employees = JSON.parse(raw);
|
|
13707
13953
|
count = Array.isArray(employees) ? employees.length : 0;
|
|
@@ -13781,8 +14027,8 @@ import os16 from "os";
|
|
|
13781
14027
|
import {
|
|
13782
14028
|
readFileSync as readFileSync21,
|
|
13783
14029
|
readdirSync as readdirSync5,
|
|
13784
|
-
unlinkSync as
|
|
13785
|
-
existsSync as
|
|
14030
|
+
unlinkSync as unlinkSync9,
|
|
14031
|
+
existsSync as existsSync26,
|
|
13786
14032
|
rmdirSync
|
|
13787
14033
|
} from "fs";
|
|
13788
14034
|
async function writeNotification(notification) {
|
|
@@ -13991,7 +14237,7 @@ import path30 from "path";
|
|
|
13991
14237
|
import os17 from "os";
|
|
13992
14238
|
import { execSync as execSync10 } from "child_process";
|
|
13993
14239
|
import { mkdir as mkdir5, writeFile as writeFile5, appendFile } from "fs/promises";
|
|
13994
|
-
import { existsSync as
|
|
14240
|
+
import { existsSync as existsSync27, readFileSync as readFileSync22 } from "fs";
|
|
13995
14241
|
async function writeCheckpoint(input) {
|
|
13996
14242
|
const client = getClient();
|
|
13997
14243
|
const row = await resolveTask(client, input.taskId);
|
|
@@ -14232,7 +14478,7 @@ ${scopeMismatchWarning}` : scopeMismatchWarning;
|
|
|
14232
14478
|
const EXE_OS_DIR = path30.join(os17.homedir(), ".exe-os");
|
|
14233
14479
|
const mdPath = path30.join(EXE_OS_DIR, taskFile);
|
|
14234
14480
|
const mdDir = path30.dirname(mdPath);
|
|
14235
|
-
if (!
|
|
14481
|
+
if (!existsSync27(mdDir)) await mkdir5(mdDir, { recursive: true });
|
|
14236
14482
|
const reviewer = input.reviewer ?? input.assignedBy;
|
|
14237
14483
|
const mdContent = `# ${input.title}
|
|
14238
14484
|
|
|
@@ -14538,7 +14784,7 @@ async function deleteTaskCore(taskId, _baseDir) {
|
|
|
14538
14784
|
async function ensureArchitectureDoc(baseDir, projectName) {
|
|
14539
14785
|
const archPath = path30.join(baseDir, "exe", "ARCHITECTURE.md");
|
|
14540
14786
|
try {
|
|
14541
|
-
if (
|
|
14787
|
+
if (existsSync27(archPath)) return;
|
|
14542
14788
|
const template = [
|
|
14543
14789
|
`# ${projectName} \u2014 System Architecture`,
|
|
14544
14790
|
"",
|
|
@@ -14573,7 +14819,7 @@ async function ensureArchitectureDoc(baseDir, projectName) {
|
|
|
14573
14819
|
async function ensureGitignoreExe(baseDir) {
|
|
14574
14820
|
const gitignorePath = path30.join(baseDir, ".gitignore");
|
|
14575
14821
|
try {
|
|
14576
|
-
if (
|
|
14822
|
+
if (existsSync27(gitignorePath)) {
|
|
14577
14823
|
const content = readFileSync22(gitignorePath, "utf-8");
|
|
14578
14824
|
if (/^\/?exe\/?$/m.test(content)) return;
|
|
14579
14825
|
await appendFile(gitignorePath, "\n# Employee task assignments (private)\n/exe/\n");
|
|
@@ -14618,7 +14864,7 @@ __export(tasks_review_exports, {
|
|
|
14618
14864
|
listPendingReviews: () => listPendingReviews
|
|
14619
14865
|
});
|
|
14620
14866
|
import path31 from "path";
|
|
14621
|
-
import { existsSync as
|
|
14867
|
+
import { existsSync as existsSync28, readdirSync as readdirSync6, unlinkSync as unlinkSync10 } from "fs";
|
|
14622
14868
|
function formatAge(isoTimestamp) {
|
|
14623
14869
|
if (!isoTimestamp) return "";
|
|
14624
14870
|
const ms = Date.now() - new Date(isoTimestamp).getTime();
|
|
@@ -14888,10 +15134,10 @@ async function cleanupReviewFile(row, taskFile, _baseDir) {
|
|
|
14888
15134
|
}
|
|
14889
15135
|
try {
|
|
14890
15136
|
const cacheDir = path31.join(EXE_AI_DIR, "session-cache");
|
|
14891
|
-
if (
|
|
15137
|
+
if (existsSync28(cacheDir)) {
|
|
14892
15138
|
for (const f of readdirSync6(cacheDir)) {
|
|
14893
15139
|
if (f.startsWith("review-notified-")) {
|
|
14894
|
-
|
|
15140
|
+
unlinkSync10(path31.join(cacheDir, f));
|
|
14895
15141
|
}
|
|
14896
15142
|
}
|
|
14897
15143
|
}
|
|
@@ -15114,10 +15360,10 @@ async function disposeEmbedder() {
|
|
|
15114
15360
|
async function embedDirect(text) {
|
|
15115
15361
|
const llamaCpp = await import("node-llama-cpp");
|
|
15116
15362
|
const { MODELS_DIR: MODELS_DIR2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
15117
|
-
const { existsSync:
|
|
15363
|
+
const { existsSync: existsSync44 } = await import("fs");
|
|
15118
15364
|
const path58 = await import("path");
|
|
15119
15365
|
const modelPath = path58.join(MODELS_DIR2, "jina-embeddings-v5-small-q4_k_m.gguf");
|
|
15120
|
-
if (!
|
|
15366
|
+
if (!existsSync44(modelPath)) {
|
|
15121
15367
|
throw new Error(`Embedding model not found at ${modelPath}. Run '/exe-setup' to download it.`);
|
|
15122
15368
|
}
|
|
15123
15369
|
const llama = await llamaCpp.getLlama();
|
|
@@ -15484,7 +15730,7 @@ __export(tasks_exports, {
|
|
|
15484
15730
|
writeCheckpoint: () => writeCheckpoint
|
|
15485
15731
|
});
|
|
15486
15732
|
import path33 from "path";
|
|
15487
|
-
import { writeFileSync as writeFileSync19, mkdirSync as
|
|
15733
|
+
import { writeFileSync as writeFileSync19, mkdirSync as mkdirSync20, unlinkSync as unlinkSync11 } from "fs";
|
|
15488
15734
|
async function createTask(input) {
|
|
15489
15735
|
const result = await createTaskCore(input);
|
|
15490
15736
|
if (!input.skipDispatch && result.status !== "blocked" && !process.env.VITEST) {
|
|
@@ -15506,11 +15752,11 @@ async function updateTask(input) {
|
|
|
15506
15752
|
const cacheDir = path33.join(EXE_AI_DIR, "session-cache");
|
|
15507
15753
|
const cachePath = path33.join(cacheDir, `current-task-${agent}.json`);
|
|
15508
15754
|
if (input.status === "in_progress") {
|
|
15509
|
-
|
|
15755
|
+
mkdirSync20(cacheDir, { recursive: true });
|
|
15510
15756
|
writeFileSync19(cachePath, JSON.stringify({ taskId, title: String(row.title) }));
|
|
15511
15757
|
} else if (input.status === "done" || input.status === "blocked" || input.status === "cancelled" || input.status === "closed") {
|
|
15512
15758
|
try {
|
|
15513
|
-
|
|
15759
|
+
unlinkSync11(cachePath);
|
|
15514
15760
|
} catch {
|
|
15515
15761
|
}
|
|
15516
15762
|
}
|
|
@@ -15978,11 +16224,11 @@ __export(tmux_routing_exports, {
|
|
|
15978
16224
|
verifyPaneAtCapacity: () => verifyPaneAtCapacity
|
|
15979
16225
|
});
|
|
15980
16226
|
import { execFileSync as execFileSync3, execSync as execSync11 } from "child_process";
|
|
15981
|
-
import { readFileSync as readFileSync23, writeFileSync as writeFileSync20, mkdirSync as
|
|
16227
|
+
import { readFileSync as readFileSync23, writeFileSync as writeFileSync20, mkdirSync as mkdirSync21, existsSync as existsSync29, appendFileSync as appendFileSync2, readdirSync as readdirSync7 } from "fs";
|
|
15982
16228
|
import path34 from "path";
|
|
15983
16229
|
import os18 from "os";
|
|
15984
16230
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
15985
|
-
import { unlinkSync as
|
|
16231
|
+
import { unlinkSync as unlinkSync12 } from "fs";
|
|
15986
16232
|
function spawnLockPath(sessionName) {
|
|
15987
16233
|
return path34.join(SPAWN_LOCK_DIR, `${sessionName}.lock`);
|
|
15988
16234
|
}
|
|
@@ -15995,11 +16241,11 @@ function isProcessAlive(pid) {
|
|
|
15995
16241
|
}
|
|
15996
16242
|
}
|
|
15997
16243
|
function acquireSpawnLock2(sessionName) {
|
|
15998
|
-
if (!
|
|
15999
|
-
|
|
16244
|
+
if (!existsSync29(SPAWN_LOCK_DIR)) {
|
|
16245
|
+
mkdirSync21(SPAWN_LOCK_DIR, { recursive: true });
|
|
16000
16246
|
}
|
|
16001
16247
|
const lockFile = spawnLockPath(sessionName);
|
|
16002
|
-
if (
|
|
16248
|
+
if (existsSync29(lockFile)) {
|
|
16003
16249
|
try {
|
|
16004
16250
|
const lock = JSON.parse(readFileSync23(lockFile, "utf8"));
|
|
16005
16251
|
const age = Date.now() - lock.timestamp;
|
|
@@ -16014,7 +16260,7 @@ function acquireSpawnLock2(sessionName) {
|
|
|
16014
16260
|
}
|
|
16015
16261
|
function releaseSpawnLock2(sessionName) {
|
|
16016
16262
|
try {
|
|
16017
|
-
|
|
16263
|
+
unlinkSync12(spawnLockPath(sessionName));
|
|
16018
16264
|
} catch {
|
|
16019
16265
|
}
|
|
16020
16266
|
}
|
|
@@ -16027,7 +16273,7 @@ function resolveBehaviorsExporterScript() {
|
|
|
16027
16273
|
"bin",
|
|
16028
16274
|
"exe-export-behaviors.js"
|
|
16029
16275
|
);
|
|
16030
|
-
return
|
|
16276
|
+
return existsSync29(scriptPath) ? scriptPath : null;
|
|
16031
16277
|
} catch {
|
|
16032
16278
|
return null;
|
|
16033
16279
|
}
|
|
@@ -16093,8 +16339,8 @@ function extractRootExe(name) {
|
|
|
16093
16339
|
return parts.length > 0 ? parts[parts.length - 1] : null;
|
|
16094
16340
|
}
|
|
16095
16341
|
function registerParentExe(sessionKey, parentExe, dispatchedBy) {
|
|
16096
|
-
if (!
|
|
16097
|
-
|
|
16342
|
+
if (!existsSync29(SESSION_CACHE)) {
|
|
16343
|
+
mkdirSync21(SESSION_CACHE, { recursive: true });
|
|
16098
16344
|
}
|
|
16099
16345
|
const rootExe = extractRootExe(parentExe) ?? parentExe;
|
|
16100
16346
|
const filePath = path34.join(SESSION_CACHE, `parent-exe-${sessionKey}.json`);
|
|
@@ -16124,11 +16370,13 @@ function getDispatchedBy(sessionKey) {
|
|
|
16124
16370
|
}
|
|
16125
16371
|
}
|
|
16126
16372
|
function resolveExeSession() {
|
|
16127
|
-
if (process.env.EXE_SESSION_NAME) {
|
|
16128
|
-
return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
16129
|
-
}
|
|
16130
16373
|
const mySession = getMySession();
|
|
16131
|
-
if (!mySession)
|
|
16374
|
+
if (!mySession) {
|
|
16375
|
+
if (process.env.EXE_SESSION_NAME) {
|
|
16376
|
+
return extractRootExe(process.env.EXE_SESSION_NAME) ?? process.env.EXE_SESSION_NAME;
|
|
16377
|
+
}
|
|
16378
|
+
return null;
|
|
16379
|
+
}
|
|
16132
16380
|
const fromSessionName = extractRootExe(mySession);
|
|
16133
16381
|
let candidate = null;
|
|
16134
16382
|
try {
|
|
@@ -16223,7 +16471,7 @@ async function verifyPaneAtCapacity(sessionName) {
|
|
|
16223
16471
|
}
|
|
16224
16472
|
function readDebounceState() {
|
|
16225
16473
|
try {
|
|
16226
|
-
if (!
|
|
16474
|
+
if (!existsSync29(DEBOUNCE_FILE)) return {};
|
|
16227
16475
|
const raw = JSON.parse(readFileSync23(DEBOUNCE_FILE, "utf8"));
|
|
16228
16476
|
const state = {};
|
|
16229
16477
|
for (const [key, val] of Object.entries(raw)) {
|
|
@@ -16240,7 +16488,7 @@ function readDebounceState() {
|
|
|
16240
16488
|
}
|
|
16241
16489
|
function writeDebounceState(state) {
|
|
16242
16490
|
try {
|
|
16243
|
-
if (!
|
|
16491
|
+
if (!existsSync29(SESSION_CACHE)) mkdirSync21(SESSION_CACHE, { recursive: true });
|
|
16244
16492
|
writeFileSync20(DEBOUNCE_FILE, JSON.stringify(state));
|
|
16245
16493
|
} catch {
|
|
16246
16494
|
}
|
|
@@ -16341,7 +16589,7 @@ function sendIntercom(targetSession) {
|
|
|
16341
16589
|
const rawAgent = targetSession.split("-")[0] ?? targetSession;
|
|
16342
16590
|
const agent = baseAgentName(rawAgent);
|
|
16343
16591
|
const markerPath = path34.join(SESSION_CACHE, `current-task-${agent}.json`);
|
|
16344
|
-
if (
|
|
16592
|
+
if (existsSync29(markerPath)) {
|
|
16345
16593
|
logIntercom(`SKIP \u2192 ${targetSession} (has in_progress task marker + not idle \u2014 will auto-chain)`);
|
|
16346
16594
|
return "debounced";
|
|
16347
16595
|
}
|
|
@@ -16352,7 +16600,7 @@ function sendIntercom(targetSession) {
|
|
|
16352
16600
|
const rawAgent = targetSession.split("-")[0] ?? targetSession;
|
|
16353
16601
|
const agent = baseAgentName(rawAgent);
|
|
16354
16602
|
const taskDir = path34.join(process.cwd(), "exe", agent);
|
|
16355
|
-
if (
|
|
16603
|
+
if (existsSync29(taskDir)) {
|
|
16356
16604
|
const files = readdirSync7(taskDir).filter(
|
|
16357
16605
|
(f) => f.endsWith(".md") && f !== "DONE.txt"
|
|
16358
16606
|
);
|
|
@@ -16513,15 +16761,15 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
16513
16761
|
const instanceLabel = opts?.instance != null && opts.instance > 0 ? `${employeeName}${opts.instance}` : employeeName;
|
|
16514
16762
|
const logDir = path34.join(os18.homedir(), ".exe-os", "session-logs");
|
|
16515
16763
|
const logFile = path34.join(logDir, `${instanceLabel}-${Date.now()}.log`);
|
|
16516
|
-
if (!
|
|
16517
|
-
|
|
16764
|
+
if (!existsSync29(logDir)) {
|
|
16765
|
+
mkdirSync21(logDir, { recursive: true });
|
|
16518
16766
|
}
|
|
16519
16767
|
transport.kill(sessionName);
|
|
16520
16768
|
let cleanupSuffix = "";
|
|
16521
16769
|
try {
|
|
16522
16770
|
const thisFile = fileURLToPath4(import.meta.url);
|
|
16523
16771
|
const cleanupScript = path34.join(path34.dirname(thisFile), "..", "bin", "exe-session-cleanup.js");
|
|
16524
|
-
if (
|
|
16772
|
+
if (existsSync29(cleanupScript)) {
|
|
16525
16773
|
cleanupSuffix = `; ${process.execPath} "${cleanupScript}" "${employeeName}" "${exeSession}"`;
|
|
16526
16774
|
}
|
|
16527
16775
|
} catch {
|
|
@@ -16576,7 +16824,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
16576
16824
|
if (changed) {
|
|
16577
16825
|
perms.allow = allow;
|
|
16578
16826
|
settings.permissions = perms;
|
|
16579
|
-
|
|
16827
|
+
mkdirSync21(projSettingsDir, { recursive: true });
|
|
16580
16828
|
writeFileSync20(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
16581
16829
|
}
|
|
16582
16830
|
} catch {
|
|
@@ -16614,7 +16862,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
16614
16862
|
`
|
|
16615
16863
|
);
|
|
16616
16864
|
}
|
|
16617
|
-
} else if (
|
|
16865
|
+
} else if (existsSync29(identityPath2)) {
|
|
16618
16866
|
identityFlag = ` --append-system-prompt-file ${identityPath2}`;
|
|
16619
16867
|
legacyFallbackWarned = true;
|
|
16620
16868
|
}
|
|
@@ -16636,7 +16884,7 @@ function spawnEmployee(employeeName, exeSession, projectDir, opts) {
|
|
|
16636
16884
|
let sessionContextFlag = "";
|
|
16637
16885
|
try {
|
|
16638
16886
|
const ctxDir = path34.join(os18.homedir(), ".exe-os", "session-cache");
|
|
16639
|
-
|
|
16887
|
+
mkdirSync21(ctxDir, { recursive: true });
|
|
16640
16888
|
const ctxFile = path34.join(ctxDir, `session-context-${sessionName}.md`);
|
|
16641
16889
|
const ctxContent = [
|
|
16642
16890
|
`## Session Context`,
|
|
@@ -17113,7 +17361,7 @@ __export(active_agent_exports, {
|
|
|
17113
17361
|
resolveActiveAgentFromTmuxSession: () => resolveActiveAgentFromTmuxSession,
|
|
17114
17362
|
writeActiveAgent: () => writeActiveAgent
|
|
17115
17363
|
});
|
|
17116
|
-
import { readFileSync as readFileSync24, writeFileSync as writeFileSync21, mkdirSync as
|
|
17364
|
+
import { readFileSync as readFileSync24, writeFileSync as writeFileSync21, mkdirSync as mkdirSync22, unlinkSync as unlinkSync13, readdirSync as readdirSync8 } from "fs";
|
|
17117
17365
|
import { execSync as execSync12 } from "child_process";
|
|
17118
17366
|
import path35 from "path";
|
|
17119
17367
|
function isNameWithOptionalInstance(candidate, baseName) {
|
|
@@ -17163,7 +17411,7 @@ function getMarkerPath() {
|
|
|
17163
17411
|
}
|
|
17164
17412
|
function writeActiveAgent(agentId, agentRole) {
|
|
17165
17413
|
try {
|
|
17166
|
-
|
|
17414
|
+
mkdirSync22(CACHE_DIR, { recursive: true });
|
|
17167
17415
|
writeFileSync21(
|
|
17168
17416
|
getMarkerPath(),
|
|
17169
17417
|
JSON.stringify({ agentId, agentRole, startedAt: (/* @__PURE__ */ new Date()).toISOString() })
|
|
@@ -17173,7 +17421,7 @@ function writeActiveAgent(agentId, agentRole) {
|
|
|
17173
17421
|
}
|
|
17174
17422
|
function clearActiveAgent() {
|
|
17175
17423
|
try {
|
|
17176
|
-
|
|
17424
|
+
unlinkSync13(getMarkerPath());
|
|
17177
17425
|
} catch {
|
|
17178
17426
|
}
|
|
17179
17427
|
}
|
|
@@ -17189,7 +17437,7 @@ function getActiveAgent() {
|
|
|
17189
17437
|
const age = Date.now() - new Date(data.startedAt).getTime();
|
|
17190
17438
|
if (age > STALE_MS) {
|
|
17191
17439
|
try {
|
|
17192
|
-
|
|
17440
|
+
unlinkSync13(markerPath);
|
|
17193
17441
|
} catch {
|
|
17194
17442
|
}
|
|
17195
17443
|
} else {
|
|
@@ -17237,7 +17485,7 @@ function getAllActiveAgents() {
|
|
|
17237
17485
|
const age = Date.now() - new Date(data.startedAt).getTime();
|
|
17238
17486
|
if (age > STALE_MS) {
|
|
17239
17487
|
try {
|
|
17240
|
-
|
|
17488
|
+
unlinkSync13(path35.join(CACHE_DIR, file));
|
|
17241
17489
|
} catch {
|
|
17242
17490
|
}
|
|
17243
17491
|
continue;
|
|
@@ -17260,11 +17508,11 @@ function getAllActiveAgents() {
|
|
|
17260
17508
|
function cleanupSessionMarkers() {
|
|
17261
17509
|
const key = getSessionKey();
|
|
17262
17510
|
try {
|
|
17263
|
-
|
|
17511
|
+
unlinkSync13(path35.join(CACHE_DIR, `active-agent-${key}.json`));
|
|
17264
17512
|
} catch {
|
|
17265
17513
|
}
|
|
17266
17514
|
try {
|
|
17267
|
-
|
|
17515
|
+
unlinkSync13(path35.join(CACHE_DIR, "active-agent-undefined.json"));
|
|
17268
17516
|
} catch {
|
|
17269
17517
|
}
|
|
17270
17518
|
}
|
|
@@ -17932,14 +18180,14 @@ __export(exe_rename_exports, {
|
|
|
17932
18180
|
main: () => main6,
|
|
17933
18181
|
renameEmployee: () => renameEmployee
|
|
17934
18182
|
});
|
|
17935
|
-
import { readFileSync as readFileSync25, writeFileSync as writeFileSync22, renameSync as renameSync6, unlinkSync as
|
|
18183
|
+
import { readFileSync as readFileSync25, writeFileSync as writeFileSync22, renameSync as renameSync6, unlinkSync as unlinkSync14, existsSync as existsSync30 } from "fs";
|
|
17936
18184
|
import { execSync as execSync13 } from "child_process";
|
|
17937
18185
|
import path36 from "path";
|
|
17938
|
-
import { homedir as
|
|
18186
|
+
import { homedir as homedir5 } from "os";
|
|
17939
18187
|
async function renameEmployee(oldName, newName, opts = {}) {
|
|
17940
|
-
const rosterPath = opts.rosterPath ?? path36.join(
|
|
17941
|
-
const identityDir = opts.identityDir ?? path36.join(
|
|
17942
|
-
const agentsDir = opts.agentsDir ?? path36.join(
|
|
18188
|
+
const rosterPath = opts.rosterPath ?? path36.join(homedir5(), ".exe-os", "exe-employees.json");
|
|
18189
|
+
const identityDir = opts.identityDir ?? path36.join(homedir5(), ".exe-os", "identity");
|
|
18190
|
+
const agentsDir = opts.agentsDir ?? path36.join(homedir5(), ".claude", "agents");
|
|
17943
18191
|
const validation = validateEmployeeName(newName);
|
|
17944
18192
|
if (!validation.valid) {
|
|
17945
18193
|
return { success: false, error: validation.error };
|
|
@@ -17974,7 +18222,7 @@ async function renameEmployee(oldName, newName, opts = {}) {
|
|
|
17974
18222
|
});
|
|
17975
18223
|
const oldIdentityPath = path36.join(identityDir, `${rosterOldName}.md`);
|
|
17976
18224
|
const newIdentityPath = path36.join(identityDir, `${newName}.md`);
|
|
17977
|
-
if (
|
|
18225
|
+
if (existsSync30(oldIdentityPath)) {
|
|
17978
18226
|
const content = readFileSync25(oldIdentityPath, "utf-8");
|
|
17979
18227
|
const updatedContent = rewriteRenamedEmployeeContent(content, rosterOldName, newName);
|
|
17980
18228
|
renameSync6(oldIdentityPath, newIdentityPath);
|
|
@@ -17982,7 +18230,7 @@ async function renameEmployee(oldName, newName, opts = {}) {
|
|
|
17982
18230
|
rollbackStack.push({
|
|
17983
18231
|
description: "restore identity file",
|
|
17984
18232
|
undo: () => {
|
|
17985
|
-
if (
|
|
18233
|
+
if (existsSync30(newIdentityPath)) {
|
|
17986
18234
|
writeFileSync22(newIdentityPath, content, "utf-8");
|
|
17987
18235
|
renameSync6(newIdentityPath, oldIdentityPath);
|
|
17988
18236
|
}
|
|
@@ -17991,7 +18239,7 @@ async function renameEmployee(oldName, newName, opts = {}) {
|
|
|
17991
18239
|
}
|
|
17992
18240
|
const oldAgentPath = path36.join(agentsDir, `${rosterOldName}.md`);
|
|
17993
18241
|
const newAgentPath = path36.join(agentsDir, `${newName}.md`);
|
|
17994
|
-
if (
|
|
18242
|
+
if (existsSync30(oldAgentPath)) {
|
|
17995
18243
|
const agentContent = readFileSync25(oldAgentPath, "utf-8");
|
|
17996
18244
|
const updatedAgentContent = rewriteRenamedEmployeeContent(agentContent, rosterOldName, newName);
|
|
17997
18245
|
renameSync6(oldAgentPath, newAgentPath);
|
|
@@ -17999,7 +18247,7 @@ async function renameEmployee(oldName, newName, opts = {}) {
|
|
|
17999
18247
|
rollbackStack.push({
|
|
18000
18248
|
description: "restore agent file",
|
|
18001
18249
|
undo: () => {
|
|
18002
|
-
if (
|
|
18250
|
+
if (existsSync30(newAgentPath)) {
|
|
18003
18251
|
renameSync6(newAgentPath, oldAgentPath);
|
|
18004
18252
|
writeFileSync22(oldAgentPath, agentContent, "utf-8");
|
|
18005
18253
|
}
|
|
@@ -18086,9 +18334,9 @@ function removeOldSymlinks(name) {
|
|
|
18086
18334
|
const binDir = path36.dirname(exeBinPath);
|
|
18087
18335
|
for (const suffix of ["", "-opencode"]) {
|
|
18088
18336
|
const linkPath = path36.join(binDir, `${name}${suffix}`);
|
|
18089
|
-
if (
|
|
18337
|
+
if (existsSync30(linkPath)) {
|
|
18090
18338
|
try {
|
|
18091
|
-
|
|
18339
|
+
unlinkSync14(linkPath);
|
|
18092
18340
|
} catch {
|
|
18093
18341
|
}
|
|
18094
18342
|
}
|
|
@@ -18546,7 +18794,7 @@ var init_exe_drift = __esm({
|
|
|
18546
18794
|
});
|
|
18547
18795
|
|
|
18548
18796
|
// src/lib/mcp-transport-health.ts
|
|
18549
|
-
import { appendFileSync as appendFileSync3, closeSync as
|
|
18797
|
+
import { appendFileSync as appendFileSync3, closeSync as closeSync4, existsSync as existsSync31, mkdirSync as mkdirSync23, openSync as openSync4, readFileSync as readFileSync26, readSync, statSync as statSync8, writeFileSync as writeFileSync23 } from "fs";
|
|
18550
18798
|
import path37 from "path";
|
|
18551
18799
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
18552
18800
|
function parsePositiveInt(value, fallback) {
|
|
@@ -18555,9 +18803,9 @@ function parsePositiveInt(value, fallback) {
|
|
|
18555
18803
|
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
18556
18804
|
}
|
|
18557
18805
|
function readTailText(filePath, maxBytes) {
|
|
18558
|
-
const stats =
|
|
18806
|
+
const stats = statSync8(filePath);
|
|
18559
18807
|
if (stats.size <= maxBytes) return readFileSync26(filePath, "utf8");
|
|
18560
|
-
const fd =
|
|
18808
|
+
const fd = openSync4(filePath, "r");
|
|
18561
18809
|
try {
|
|
18562
18810
|
const buffer = Buffer.allocUnsafe(maxBytes);
|
|
18563
18811
|
readSync(fd, buffer, 0, maxBytes, stats.size - maxBytes);
|
|
@@ -18565,7 +18813,7 @@ function readTailText(filePath, maxBytes) {
|
|
|
18565
18813
|
const firstNewline = text.indexOf("\n");
|
|
18566
18814
|
return firstNewline >= 0 ? text.slice(firstNewline + 1) : text;
|
|
18567
18815
|
} finally {
|
|
18568
|
-
|
|
18816
|
+
closeSync4(fd);
|
|
18569
18817
|
}
|
|
18570
18818
|
}
|
|
18571
18819
|
function readPackageVersion2() {
|
|
@@ -18573,7 +18821,7 @@ function readPackageVersion2() {
|
|
|
18573
18821
|
const { root } = path37.parse(dir);
|
|
18574
18822
|
while (dir !== root) {
|
|
18575
18823
|
const pkgPath = path37.join(dir, "package.json");
|
|
18576
|
-
if (
|
|
18824
|
+
if (existsSync31(pkgPath)) {
|
|
18577
18825
|
try {
|
|
18578
18826
|
const parsed = JSON.parse(readFileSync26(pkgPath, "utf8"));
|
|
18579
18827
|
return parsed.version ?? "unknown";
|
|
@@ -18597,7 +18845,7 @@ function parseMcpHttpEventLines(raw, limit = 200) {
|
|
|
18597
18845
|
return events;
|
|
18598
18846
|
}
|
|
18599
18847
|
function readMcpHttpEvents(limit = 200) {
|
|
18600
|
-
if (!
|
|
18848
|
+
if (!existsSync31(MCP_HTTP_EVENTS_PATH)) return [];
|
|
18601
18849
|
const raw = readTailText(MCP_HTTP_EVENTS_PATH, EVENT_READ_BYTES);
|
|
18602
18850
|
return parseMcpHttpEventLines(raw, limit);
|
|
18603
18851
|
}
|
|
@@ -18666,7 +18914,7 @@ var init_mcp_transport_health = __esm({
|
|
|
18666
18914
|
});
|
|
18667
18915
|
|
|
18668
18916
|
// src/bin/exe-healthcheck.ts
|
|
18669
|
-
import { existsSync as
|
|
18917
|
+
import { existsSync as existsSync32, readFileSync as readFileSync27, readdirSync as readdirSync9 } from "fs";
|
|
18670
18918
|
import path38 from "path";
|
|
18671
18919
|
import { execSync as execSync14 } from "child_process";
|
|
18672
18920
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
@@ -18674,7 +18922,7 @@ function findPackageRoot2() {
|
|
|
18674
18922
|
let dir = path38.dirname(fileURLToPath6(import.meta.url));
|
|
18675
18923
|
const { root } = path38.parse(dir);
|
|
18676
18924
|
while (dir !== root) {
|
|
18677
|
-
if (
|
|
18925
|
+
if (existsSync32(path38.join(dir, "package.json"))) return dir;
|
|
18678
18926
|
dir = path38.dirname(dir);
|
|
18679
18927
|
}
|
|
18680
18928
|
throw new Error("Cannot find package root");
|
|
@@ -18682,7 +18930,7 @@ function findPackageRoot2() {
|
|
|
18682
18930
|
function checkBuildIntegrity(pkgRoot) {
|
|
18683
18931
|
const results = [];
|
|
18684
18932
|
const tsupConfig = path38.join(pkgRoot, "tsup.config.ts");
|
|
18685
|
-
if (!
|
|
18933
|
+
if (!existsSync32(tsupConfig)) {
|
|
18686
18934
|
return [{ name: "build/tsup-config", pass: false, detail: "tsup.config.ts not found" }];
|
|
18687
18935
|
}
|
|
18688
18936
|
const configContent = readFileSync27(tsupConfig, "utf-8");
|
|
@@ -18693,7 +18941,7 @@ function checkBuildIntegrity(pkgRoot) {
|
|
|
18693
18941
|
const outputKey = match[1];
|
|
18694
18942
|
const expectedPath = path38.join(pkgRoot, "dist", `${outputKey}.js`);
|
|
18695
18943
|
total++;
|
|
18696
|
-
if (!
|
|
18944
|
+
if (!existsSync32(expectedPath)) {
|
|
18697
18945
|
missing.push(`dist/${outputKey}.js`);
|
|
18698
18946
|
}
|
|
18699
18947
|
}
|
|
@@ -18716,7 +18964,7 @@ function checkBuildIntegrity(pkgRoot) {
|
|
|
18716
18964
|
function checkEmbedPipeline(pkgRoot) {
|
|
18717
18965
|
const results = [];
|
|
18718
18966
|
const daemonPath = path38.join(pkgRoot, "dist", "lib", "exe-daemon.js");
|
|
18719
|
-
if (!
|
|
18967
|
+
if (!existsSync32(daemonPath)) {
|
|
18720
18968
|
results.push({
|
|
18721
18969
|
name: "exed/daemon-exists",
|
|
18722
18970
|
pass: false,
|
|
@@ -18728,12 +18976,12 @@ function checkEmbedPipeline(pkgRoot) {
|
|
|
18728
18976
|
const entryDirs = ["dist/hooks", "dist/bin", "dist/mcp"];
|
|
18729
18977
|
for (const dir of entryDirs) {
|
|
18730
18978
|
const fullDir = path38.join(pkgRoot, dir);
|
|
18731
|
-
if (!
|
|
18979
|
+
if (!existsSync32(fullDir)) continue;
|
|
18732
18980
|
let walkDir2 = fullDir;
|
|
18733
18981
|
const { root } = path38.parse(walkDir2);
|
|
18734
18982
|
let foundRoot = null;
|
|
18735
18983
|
while (walkDir2 !== root) {
|
|
18736
|
-
if (
|
|
18984
|
+
if (existsSync32(path38.join(walkDir2, "package.json"))) {
|
|
18737
18985
|
foundRoot = walkDir2;
|
|
18738
18986
|
break;
|
|
18739
18987
|
}
|
|
@@ -18748,7 +18996,7 @@ function checkEmbedPipeline(pkgRoot) {
|
|
|
18748
18996
|
continue;
|
|
18749
18997
|
}
|
|
18750
18998
|
const resolvedDaemon = path38.join(foundRoot, "dist", "lib", "exe-daemon.js");
|
|
18751
|
-
const reachable =
|
|
18999
|
+
const reachable = existsSync32(resolvedDaemon);
|
|
18752
19000
|
results.push({
|
|
18753
19001
|
name: `exed/reachable-from-${dir}`,
|
|
18754
19002
|
pass: reachable,
|
|
@@ -18760,7 +19008,7 @@ function checkEmbedPipeline(pkgRoot) {
|
|
|
18760
19008
|
function checkTaskSystem(pkgRoot) {
|
|
18761
19009
|
const results = [];
|
|
18762
19010
|
const scannerPath = path38.join(pkgRoot, "dist", "bin", "scan-tasks.js");
|
|
18763
|
-
if (!
|
|
19011
|
+
if (!existsSync32(scannerPath)) {
|
|
18764
19012
|
results.push({ name: "tasks/scanner", pass: false, detail: "scan-tasks.js not found" });
|
|
18765
19013
|
return results;
|
|
18766
19014
|
}
|
|
@@ -18783,7 +19031,7 @@ function checkTaskSystem(pkgRoot) {
|
|
|
18783
19031
|
function checkWorkerSpawning(pkgRoot) {
|
|
18784
19032
|
const results = [];
|
|
18785
19033
|
const workerPath = path38.join(pkgRoot, "dist", "hooks", "ingest-worker.js");
|
|
18786
|
-
if (!
|
|
19034
|
+
if (!existsSync32(workerPath)) {
|
|
18787
19035
|
results.push({ name: "workers/ingest-worker", pass: false, detail: "ingest-worker.js not found" });
|
|
18788
19036
|
return results;
|
|
18789
19037
|
}
|
|
@@ -18798,7 +19046,7 @@ function checkWorkerSpawning(pkgRoot) {
|
|
|
18798
19046
|
});
|
|
18799
19047
|
}
|
|
18800
19048
|
const hooksDir = path38.join(pkgRoot, "dist", "hooks");
|
|
18801
|
-
if (
|
|
19049
|
+
if (existsSync32(hooksDir)) {
|
|
18802
19050
|
const hookFiles = readdirSync9(hooksDir).filter((f) => f.endsWith(".js") && !f.endsWith(".js.map"));
|
|
18803
19051
|
let hooksPassed = 0;
|
|
18804
19052
|
const hooksFailed = [];
|
|
@@ -18831,7 +19079,7 @@ function checkMcpTransport() {
|
|
|
18831
19079
|
const pidPath = path38.join(EXE_AI_DIR, "exed.pid");
|
|
18832
19080
|
const tokenPath = path38.join(EXE_AI_DIR, "exed.token");
|
|
18833
19081
|
let daemonAlive = false;
|
|
18834
|
-
if (
|
|
19082
|
+
if (existsSync32(pidPath)) {
|
|
18835
19083
|
try {
|
|
18836
19084
|
const pid = parseInt(readFileSync27(pidPath, "utf8").trim(), 10);
|
|
18837
19085
|
process.kill(pid, 0);
|
|
@@ -18843,7 +19091,7 @@ function checkMcpTransport() {
|
|
|
18843
19091
|
} else {
|
|
18844
19092
|
results.push({ name: "mcp/daemon-process", pass: false, detail: "No exed.pid found; daemon is not running" });
|
|
18845
19093
|
}
|
|
18846
|
-
if (daemonAlive &&
|
|
19094
|
+
if (daemonAlive && existsSync32(tokenPath)) {
|
|
18847
19095
|
try {
|
|
18848
19096
|
const token = readFileSync27(tokenPath, "utf8").trim();
|
|
18849
19097
|
const response = execSync14(
|
|
@@ -18941,7 +19189,7 @@ function checkClaudeCodeInstall() {
|
|
|
18941
19189
|
"claude",
|
|
18942
19190
|
"versions"
|
|
18943
19191
|
);
|
|
18944
|
-
if (
|
|
19192
|
+
if (existsSync32(versionsDir)) {
|
|
18945
19193
|
try {
|
|
18946
19194
|
const entries = readdirSync9(versionsDir);
|
|
18947
19195
|
if (entries.length > 0) {
|
|
@@ -19096,7 +19344,7 @@ var init_cc_doctor = __esm({
|
|
|
19096
19344
|
});
|
|
19097
19345
|
|
|
19098
19346
|
// src/lib/model-downloader.ts
|
|
19099
|
-
import { createWriteStream, createReadStream as createReadStream2, existsSync as
|
|
19347
|
+
import { createWriteStream, createReadStream as createReadStream2, existsSync as existsSync33, unlinkSync as unlinkSync15, renameSync as renameSync7 } from "fs";
|
|
19100
19348
|
import { mkdir as mkdir6 } from "fs/promises";
|
|
19101
19349
|
import { createHash as createHash6 } from "crypto";
|
|
19102
19350
|
import path39 from "path";
|
|
@@ -19105,7 +19353,7 @@ async function downloadModel(opts) {
|
|
|
19105
19353
|
const destPath = path39.join(destDir, LOCAL_FILENAME);
|
|
19106
19354
|
const tmpPath = destPath + ".tmp";
|
|
19107
19355
|
await mkdir6(destDir, { recursive: true });
|
|
19108
|
-
if (
|
|
19356
|
+
if (existsSync33(destPath)) {
|
|
19109
19357
|
const hash = await fileHash(destPath);
|
|
19110
19358
|
if (hash === EXPECTED_SHA256) {
|
|
19111
19359
|
return destPath;
|
|
@@ -19117,7 +19365,7 @@ async function downloadModel(opts) {
|
|
|
19117
19365
|
let downloaded = 0;
|
|
19118
19366
|
for (let attempt = 1; attempt <= MAX_RETRIES4; attempt++) {
|
|
19119
19367
|
try {
|
|
19120
|
-
if (
|
|
19368
|
+
if (existsSync33(tmpPath)) unlinkSync15(tmpPath);
|
|
19121
19369
|
const response = await fetchFn(GGUF_URL, {
|
|
19122
19370
|
redirect: "follow",
|
|
19123
19371
|
signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS)
|
|
@@ -19149,7 +19397,7 @@ async function downloadModel(opts) {
|
|
|
19149
19397
|
}
|
|
19150
19398
|
const actualHash = hash.digest("hex");
|
|
19151
19399
|
if (actualHash !== EXPECTED_SHA256) {
|
|
19152
|
-
|
|
19400
|
+
unlinkSync15(tmpPath);
|
|
19153
19401
|
throw new Error(
|
|
19154
19402
|
`SHA256 mismatch: expected ${EXPECTED_SHA256}, got ${actualHash}`
|
|
19155
19403
|
);
|
|
@@ -19162,7 +19410,7 @@ async function downloadModel(opts) {
|
|
|
19162
19410
|
process.stderr.write(`
|
|
19163
19411
|
Download attempt ${attempt} failed, retrying...
|
|
19164
19412
|
`);
|
|
19165
|
-
if (
|
|
19413
|
+
if (existsSync33(tmpPath)) unlinkSync15(tmpPath);
|
|
19166
19414
|
}
|
|
19167
19415
|
}
|
|
19168
19416
|
}
|
|
@@ -19739,30 +19987,30 @@ __export(session_wrappers_exports, {
|
|
|
19739
19987
|
generateSessionWrappers: () => generateSessionWrappers
|
|
19740
19988
|
});
|
|
19741
19989
|
import {
|
|
19742
|
-
existsSync as
|
|
19990
|
+
existsSync as existsSync34,
|
|
19743
19991
|
readFileSync as readFileSync28,
|
|
19744
19992
|
writeFileSync as writeFileSync24,
|
|
19745
|
-
mkdirSync as
|
|
19993
|
+
mkdirSync as mkdirSync24,
|
|
19746
19994
|
chmodSync as chmodSync4,
|
|
19747
19995
|
readdirSync as readdirSync10,
|
|
19748
|
-
unlinkSync as
|
|
19996
|
+
unlinkSync as unlinkSync16
|
|
19749
19997
|
} from "fs";
|
|
19750
19998
|
import { execSync as execSync15 } from "child_process";
|
|
19751
19999
|
import path40 from "path";
|
|
19752
|
-
import { homedir as
|
|
20000
|
+
import { homedir as homedir6 } from "os";
|
|
19753
20001
|
function generateSessionWrappers(packageRoot, homeDir) {
|
|
19754
|
-
const home = homeDir ??
|
|
20002
|
+
const home = homeDir ?? homedir6();
|
|
19755
20003
|
const binDir = path40.join(home, ".exe-os", "bin");
|
|
19756
20004
|
const rosterPath = path40.join(home, ".exe-os", "exe-employees.json");
|
|
19757
20005
|
const shouldMirrorToGlobalBin = homeDir === void 0;
|
|
19758
|
-
|
|
20006
|
+
mkdirSync24(binDir, { recursive: true });
|
|
19759
20007
|
const exeStartDst = path40.join(binDir, "exe-start");
|
|
19760
20008
|
const candidates = [
|
|
19761
20009
|
path40.join(packageRoot, "dist", "bin", "exe-start.sh"),
|
|
19762
20010
|
path40.join(packageRoot, "src", "bin", "exe-start.sh")
|
|
19763
20011
|
];
|
|
19764
20012
|
for (const src of candidates) {
|
|
19765
|
-
if (
|
|
20013
|
+
if (existsSync34(src)) {
|
|
19766
20014
|
writeFileSync24(exeStartDst, readFileSync28(src));
|
|
19767
20015
|
chmodSync4(exeStartDst, 493);
|
|
19768
20016
|
break;
|
|
@@ -19784,7 +20032,7 @@ function generateSessionWrappers(packageRoot, homeDir) {
|
|
|
19784
20032
|
try {
|
|
19785
20033
|
const content = readFileSync28(fPath, "utf8");
|
|
19786
20034
|
if (content.includes("exe-start")) {
|
|
19787
|
-
|
|
20035
|
+
unlinkSync16(fPath);
|
|
19788
20036
|
}
|
|
19789
20037
|
} catch {
|
|
19790
20038
|
}
|
|
@@ -19816,7 +20064,7 @@ exec "${exeStartDst}" "$0" "$@"
|
|
|
19816
20064
|
];
|
|
19817
20065
|
let codexLauncher = null;
|
|
19818
20066
|
for (const c of codexLauncherCandidates) {
|
|
19819
|
-
if (
|
|
20067
|
+
if (existsSync34(c)) {
|
|
19820
20068
|
codexLauncher = c;
|
|
19821
20069
|
break;
|
|
19822
20070
|
}
|
|
@@ -19906,7 +20154,7 @@ __export(setup_wizard_exports, {
|
|
|
19906
20154
|
validateModel: () => validateModel
|
|
19907
20155
|
});
|
|
19908
20156
|
import crypto13 from "crypto";
|
|
19909
|
-
import { existsSync as
|
|
20157
|
+
import { existsSync as existsSync35, mkdirSync as mkdirSync25, readFileSync as readFileSync29, writeFileSync as writeFileSync25, unlinkSync as unlinkSync17 } from "fs";
|
|
19910
20158
|
import os19 from "os";
|
|
19911
20159
|
import path41 from "path";
|
|
19912
20160
|
import { createInterface as createInterface4 } from "readline";
|
|
@@ -19915,7 +20163,7 @@ function findPackageRoot3() {
|
|
|
19915
20163
|
const root = path41.parse(dir).root;
|
|
19916
20164
|
while (dir !== root) {
|
|
19917
20165
|
const pkgPath = path41.join(dir, "package.json");
|
|
19918
|
-
if (
|
|
20166
|
+
if (existsSync35(pkgPath)) {
|
|
19919
20167
|
try {
|
|
19920
20168
|
const pkg = JSON.parse(readFileSync29(pkgPath, "utf-8"));
|
|
19921
20169
|
if (pkg.name === "@askexenow/exe-os" || pkg.name === "exe-os") return dir;
|
|
@@ -19934,12 +20182,12 @@ function loadSetupState() {
|
|
|
19934
20182
|
}
|
|
19935
20183
|
}
|
|
19936
20184
|
function saveSetupState(state) {
|
|
19937
|
-
|
|
20185
|
+
mkdirSync25(path41.dirname(SETUP_STATE_PATH), { recursive: true });
|
|
19938
20186
|
writeFileSync25(SETUP_STATE_PATH, JSON.stringify(state, null, 2));
|
|
19939
20187
|
}
|
|
19940
20188
|
function clearSetupState() {
|
|
19941
20189
|
try {
|
|
19942
|
-
|
|
20190
|
+
unlinkSync17(SETUP_STATE_PATH);
|
|
19943
20191
|
} catch {
|
|
19944
20192
|
}
|
|
19945
20193
|
}
|
|
@@ -19986,9 +20234,9 @@ async function validateModel(log) {
|
|
|
19986
20234
|
log(`System memory: ${totalGB.toFixed(0)}GB total, ${freeGB.toFixed(1)}GB free`);
|
|
19987
20235
|
log("Skipping in-memory model validation (low memory \u2014 will validate on first use).");
|
|
19988
20236
|
const modelPath = path41.join(MODELS_DIR, LOCAL_FILENAME);
|
|
19989
|
-
if (
|
|
19990
|
-
const { statSync:
|
|
19991
|
-
const size =
|
|
20237
|
+
if (existsSync35(modelPath)) {
|
|
20238
|
+
const { statSync: statSync10 } = await import("fs");
|
|
20239
|
+
const size = statSync10(modelPath).size;
|
|
19992
20240
|
if (size > 300 * 1e6) {
|
|
19993
20241
|
log(`Model file verified (${(size / 1e6).toFixed(0)} MB).`);
|
|
19994
20242
|
return;
|
|
@@ -20081,7 +20329,7 @@ async function runSetupWizard(opts = {}) {
|
|
|
20081
20329
|
if (state.completedSteps.length > 0) {
|
|
20082
20330
|
log(`Resuming setup from step ${Math.max(...state.completedSteps) + 1}...`);
|
|
20083
20331
|
}
|
|
20084
|
-
if (
|
|
20332
|
+
if (existsSync35(LEGACY_LANCE_PATH)) {
|
|
20085
20333
|
log("\u26A0 Found v1.0 LanceDB at ~/.exe-os/local.lance");
|
|
20086
20334
|
log(" v1.1 uses libSQL (SQLite). Your existing memories are not automatically migrated.");
|
|
20087
20335
|
log(" The old directory will not be modified or deleted.");
|
|
@@ -20298,7 +20546,7 @@ async function runSetupWizard(opts = {}) {
|
|
|
20298
20546
|
const prefs = { ...existingPrefs };
|
|
20299
20547
|
log("=== Config Defaults ===");
|
|
20300
20548
|
log("");
|
|
20301
|
-
const ghosttyDetected =
|
|
20549
|
+
const ghosttyDetected = existsSync35(path41.join(os19.homedir(), ".config", "ghostty")) || existsSync35(path41.join(os19.homedir(), "Library", "Application Support", "com.mitchellh.ghostty"));
|
|
20302
20550
|
if (ghosttyDetected) {
|
|
20303
20551
|
const ghosttyAnswer = await ask3(rl, "Detected Ghostty terminal. Use exe-os Ghostty defaults? (Y/n) ");
|
|
20304
20552
|
prefs.ghostty = ghosttyAnswer.toLowerCase() !== "n";
|
|
@@ -20345,7 +20593,7 @@ async function runSetupWizard(opts = {}) {
|
|
|
20345
20593
|
let missingIdentities = [];
|
|
20346
20594
|
for (const emp of roster) {
|
|
20347
20595
|
const idPath = identityPath2(emp.name);
|
|
20348
|
-
if (!
|
|
20596
|
+
if (!existsSync35(idPath)) {
|
|
20349
20597
|
missingIdentities.push(emp.name);
|
|
20350
20598
|
}
|
|
20351
20599
|
}
|
|
@@ -20377,7 +20625,7 @@ async function runSetupWizard(opts = {}) {
|
|
|
20377
20625
|
}
|
|
20378
20626
|
missingIdentities = [];
|
|
20379
20627
|
for (const emp of roster) {
|
|
20380
|
-
if (!
|
|
20628
|
+
if (!existsSync35(identityPath2(emp.name))) {
|
|
20381
20629
|
missingIdentities.push(emp.name);
|
|
20382
20630
|
}
|
|
20383
20631
|
}
|
|
@@ -20436,7 +20684,7 @@ async function runSetupWizard(opts = {}) {
|
|
|
20436
20684
|
const cooIdentityContent = getIdentityTemplate("coo");
|
|
20437
20685
|
if (cooIdentityContent) {
|
|
20438
20686
|
const cooIdPath = identityPath2(cooName);
|
|
20439
|
-
|
|
20687
|
+
mkdirSync25(path41.dirname(cooIdPath), { recursive: true });
|
|
20440
20688
|
const replaced = cooIdentityContent.replace(/agent_id:\s*exe/g, `agent_id: ${cooName}`).replace(/\$\{agent_id\}/g, cooName);
|
|
20441
20689
|
writeFileSync25(cooIdPath, replaced, "utf-8");
|
|
20442
20690
|
}
|
|
@@ -20554,7 +20802,7 @@ async function runSetupWizard(opts = {}) {
|
|
|
20554
20802
|
const ctoIdentityContent = getIdentityTemplate("cto");
|
|
20555
20803
|
if (ctoIdentityContent) {
|
|
20556
20804
|
const ctoIdPath = identityPath2(ctoName);
|
|
20557
|
-
|
|
20805
|
+
mkdirSync25(path41.dirname(ctoIdPath), { recursive: true });
|
|
20558
20806
|
const replaced = ctoIdentityContent.replace(/agent_id:\s*\w+/g, `agent_id: ${ctoName}`).replace(/\$\{agent_id\}/g, ctoName);
|
|
20559
20807
|
writeFileSync25(ctoIdPath, replaced, "utf-8");
|
|
20560
20808
|
}
|
|
@@ -20577,7 +20825,7 @@ async function runSetupWizard(opts = {}) {
|
|
|
20577
20825
|
const cmoIdentityContent = getIdentityTemplate("cmo");
|
|
20578
20826
|
if (cmoIdentityContent) {
|
|
20579
20827
|
const cmoIdPath = identityPath2(cmoName);
|
|
20580
|
-
|
|
20828
|
+
mkdirSync25(path41.dirname(cmoIdPath), { recursive: true });
|
|
20581
20829
|
const replaced = cmoIdentityContent.replace(/agent_id:\s*\w+/g, `agent_id: ${cmoName}`).replace(/\$\{agent_id\}/g, cmoName);
|
|
20582
20830
|
writeFileSync25(cmoIdPath, replaced, "utf-8");
|
|
20583
20831
|
}
|
|
@@ -20690,7 +20938,7 @@ var init_setup_wizard = __esm({
|
|
|
20690
20938
|
|
|
20691
20939
|
// src/lib/update-backup.ts
|
|
20692
20940
|
import { copyFile, readFile as readFile6, readdir as readdir3, writeFile as writeFile7, rm as rm2, mkdir as mkdir7, cp } from "fs/promises";
|
|
20693
|
-
import { existsSync as
|
|
20941
|
+
import { existsSync as existsSync36 } from "fs";
|
|
20694
20942
|
import path42 from "path";
|
|
20695
20943
|
import os20 from "os";
|
|
20696
20944
|
function resolveDataDir2() {
|
|
@@ -20715,14 +20963,14 @@ function externalBackupTargets(homeDir) {
|
|
|
20715
20963
|
async function createUpdateBackup(currentVersion, dataDir2, homeDir = os20.homedir()) {
|
|
20716
20964
|
const dir = dataDir2 ?? resolveDataDir2();
|
|
20717
20965
|
const backupDir = path42.join(dir, BACKUP_DIR_NAME);
|
|
20718
|
-
if (
|
|
20966
|
+
if (existsSync36(backupDir)) {
|
|
20719
20967
|
await rm2(backupDir, { recursive: true, force: true });
|
|
20720
20968
|
}
|
|
20721
20969
|
await mkdir7(backupDir, { recursive: true });
|
|
20722
20970
|
const backedUpFiles = [];
|
|
20723
20971
|
for (const target of BACKUP_TARGETS) {
|
|
20724
20972
|
const src = path42.join(dir, target.name);
|
|
20725
|
-
if (!
|
|
20973
|
+
if (!existsSync36(src)) continue;
|
|
20726
20974
|
const dest = path42.join(backupDir, target.name);
|
|
20727
20975
|
if (target.type === "file") {
|
|
20728
20976
|
await copyFile(src, dest);
|
|
@@ -20743,7 +20991,7 @@ async function createUpdateBackup(currentVersion, dataDir2, homeDir = os20.homed
|
|
|
20743
20991
|
const externalFiles = [];
|
|
20744
20992
|
const externalDir = path42.join(backupDir, "external");
|
|
20745
20993
|
for (const target of externalBackupTargets(homeDir)) {
|
|
20746
|
-
if (!
|
|
20994
|
+
if (!existsSync36(target.path)) continue;
|
|
20747
20995
|
await mkdir7(externalDir, { recursive: true });
|
|
20748
20996
|
await copyFile(target.path, path42.join(externalDir, target.name));
|
|
20749
20997
|
externalFiles.push(target);
|
|
@@ -20764,7 +21012,7 @@ async function restoreFromBackup(dataDir2) {
|
|
|
20764
21012
|
const dir = dataDir2 ?? resolveDataDir2();
|
|
20765
21013
|
const backupDir = path42.join(dir, BACKUP_DIR_NAME);
|
|
20766
21014
|
const manifestPath = path42.join(backupDir, "manifest.json");
|
|
20767
|
-
if (!
|
|
21015
|
+
if (!existsSync36(manifestPath)) {
|
|
20768
21016
|
throw new Error(
|
|
20769
21017
|
`No backup found at ${backupDir}. Nothing to restore.`
|
|
20770
21018
|
);
|
|
@@ -20775,7 +21023,7 @@ async function restoreFromBackup(dataDir2) {
|
|
|
20775
21023
|
for (const fileName of manifest.files) {
|
|
20776
21024
|
const src = path42.join(backupDir, fileName);
|
|
20777
21025
|
const dest = path42.join(dir, fileName);
|
|
20778
|
-
if (!
|
|
21026
|
+
if (!existsSync36(src)) continue;
|
|
20779
21027
|
const stat2 = await import("fs/promises").then((m) => m.stat(src));
|
|
20780
21028
|
if (stat2.isDirectory()) {
|
|
20781
21029
|
await cp(src, dest, { recursive: true, force: true });
|
|
@@ -20785,7 +21033,7 @@ async function restoreFromBackup(dataDir2) {
|
|
|
20785
21033
|
}
|
|
20786
21034
|
for (const external of manifest.externalFiles ?? []) {
|
|
20787
21035
|
const src = path42.join(backupDir, "external", external.name);
|
|
20788
|
-
if (!
|
|
21036
|
+
if (!existsSync36(src)) continue;
|
|
20789
21037
|
await mkdir7(path42.dirname(external.path), { recursive: true });
|
|
20790
21038
|
await copyFile(src, external.path);
|
|
20791
21039
|
}
|
|
@@ -20794,7 +21042,7 @@ async function restoreFromBackup(dataDir2) {
|
|
|
20794
21042
|
async function deleteBackup(dataDir2) {
|
|
20795
21043
|
const dir = dataDir2 ?? resolveDataDir2();
|
|
20796
21044
|
const backupDir = path42.join(dir, BACKUP_DIR_NAME);
|
|
20797
|
-
if (
|
|
21045
|
+
if (existsSync36(backupDir)) {
|
|
20798
21046
|
await rm2(backupDir, { recursive: true, force: true });
|
|
20799
21047
|
}
|
|
20800
21048
|
}
|
|
@@ -21077,7 +21325,7 @@ var init_update = __esm({
|
|
|
21077
21325
|
// src/lib/stack-update.ts
|
|
21078
21326
|
import { execFileSync as execFileSync4, spawnSync } from "child_process";
|
|
21079
21327
|
import { createVerify, randomBytes as randomBytes2, verify as verifySignature } from "crypto";
|
|
21080
|
-
import { copyFileSync as
|
|
21328
|
+
import { copyFileSync as copyFileSync6, existsSync as existsSync37, mkdirSync as mkdirSync26, readdirSync as readdirSync11, readFileSync as readFileSync31, renameSync as renameSync8, writeFileSync as writeFileSync26 } from "fs";
|
|
21081
21329
|
import http from "http";
|
|
21082
21330
|
import https from "https";
|
|
21083
21331
|
import path44 from "path";
|
|
@@ -21116,15 +21364,15 @@ function stableJson(value) {
|
|
|
21116
21364
|
}
|
|
21117
21365
|
function findLatestBackupEnvFile(envFile) {
|
|
21118
21366
|
const backupDir = path44.join(path44.dirname(envFile), ".exe-stack-backups");
|
|
21119
|
-
if (!
|
|
21367
|
+
if (!existsSync37(backupDir)) return null;
|
|
21120
21368
|
const backups = readdirSync11(backupDir).filter((name) => name.startsWith("env-") && name.endsWith(".bak")).sort();
|
|
21121
21369
|
const latest = backups.at(-1);
|
|
21122
21370
|
return latest ? path44.join(backupDir, latest) : null;
|
|
21123
21371
|
}
|
|
21124
21372
|
async function rollbackStackUpdate(options) {
|
|
21125
21373
|
const exec2 = options.exec ?? defaultExec;
|
|
21126
|
-
const backupEnvFile = options.lockFile &&
|
|
21127
|
-
const rollbackEnv = backupEnvFile &&
|
|
21374
|
+
const backupEnvFile = options.lockFile && existsSync37(options.lockFile) ? JSON.parse(readFileSync31(options.lockFile, "utf8")).backupEnvFile : void 0;
|
|
21375
|
+
const rollbackEnv = backupEnvFile && existsSync37(backupEnvFile) ? backupEnvFile : findLatestBackupEnvFile(options.envFile);
|
|
21128
21376
|
if (!rollbackEnv) throw new Error(`No stack backup env found beside ${options.envFile}`);
|
|
21129
21377
|
writeFileSync26(options.envFile, readFileSync31(rollbackEnv), { mode: 384 });
|
|
21130
21378
|
const composeArgs = ["compose", "--file", options.composeFile, "--env-file", options.envFile];
|
|
@@ -21283,9 +21531,9 @@ Emergency override requires --break-glass <reason> and writes an audit file.`
|
|
|
21283
21531
|
function writeBreakGlassAudit(plan, issues, options) {
|
|
21284
21532
|
const now2 = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
21285
21533
|
const stamp = now2().toISOString().replace(/[:.]/g, "-");
|
|
21286
|
-
const defaultDir =
|
|
21534
|
+
const defaultDir = existsSync37("exe/output") ? "exe/output" : path44.dirname(options.envFile ?? ".");
|
|
21287
21535
|
const auditFile = options.breakGlassAuditFile ?? path44.join(defaultDir, `stack-update-break-glass-${stamp}.md`);
|
|
21288
|
-
|
|
21536
|
+
mkdirSync26(path44.dirname(auditFile), { recursive: true });
|
|
21289
21537
|
const body = [
|
|
21290
21538
|
`# Stack Update Break-Glass Audit \u2014 ${now2().toISOString()}`,
|
|
21291
21539
|
"",
|
|
@@ -21332,16 +21580,16 @@ function resolvePackageRoot2() {
|
|
|
21332
21580
|
process.cwd()
|
|
21333
21581
|
];
|
|
21334
21582
|
for (const c of candidates) {
|
|
21335
|
-
if (
|
|
21583
|
+
if (existsSync37(path44.join(c, "package.json")) && existsSync37(path44.join(c, "deploy", "compose", "docker-compose.yml"))) return c;
|
|
21336
21584
|
}
|
|
21337
21585
|
return process.cwd();
|
|
21338
21586
|
}
|
|
21339
21587
|
function copyTemplateIfMissing(srcRel, dest, created) {
|
|
21340
|
-
if (
|
|
21588
|
+
if (existsSync37(dest)) return;
|
|
21341
21589
|
const src = path44.join(resolvePackageRoot2(), srcRel);
|
|
21342
|
-
if (!
|
|
21590
|
+
if (!existsSync37(src)) throw new Error(`Missing packaged stack template: ${srcRel}. Reinstall/update exe-os and retry.`);
|
|
21343
21591
|
try {
|
|
21344
|
-
|
|
21592
|
+
mkdirSync26(path44.dirname(dest), { recursive: true });
|
|
21345
21593
|
} catch (err) {
|
|
21346
21594
|
if (err.code === "EACCES") {
|
|
21347
21595
|
const dir = path44.dirname(dest);
|
|
@@ -21355,12 +21603,12 @@ Then re-run stack-update.`
|
|
|
21355
21603
|
}
|
|
21356
21604
|
throw err;
|
|
21357
21605
|
}
|
|
21358
|
-
|
|
21606
|
+
copyFileSync6(src, dest);
|
|
21359
21607
|
created.push(dest);
|
|
21360
21608
|
}
|
|
21361
21609
|
function installDockerUbuntu(exec2) {
|
|
21362
21610
|
if (process.platform !== "linux") throw new Error("Docker auto-install is only supported on Linux. Install Docker manually, then retry.");
|
|
21363
|
-
if (!
|
|
21611
|
+
if (!existsSync37("/etc/os-release")) throw new Error("Cannot detect Linux distro; install Docker manually, then retry.");
|
|
21364
21612
|
const osRelease = readFileSync31("/etc/os-release", "utf8");
|
|
21365
21613
|
if (!/ID=(ubuntu|debian)|ID_LIKE=.*debian/.test(osRelease)) {
|
|
21366
21614
|
throw new Error("Docker auto-install currently supports Ubuntu/Debian only. Install Docker manually, then retry.");
|
|
@@ -21433,7 +21681,7 @@ async function pairMonitorAgent(hubUrl, licenseKey, domain, envFile) {
|
|
|
21433
21681
|
if (!data.token || !data.key) {
|
|
21434
21682
|
return { paired: false, error: "Monitor hub response missing token or key" };
|
|
21435
21683
|
}
|
|
21436
|
-
if (
|
|
21684
|
+
if (existsSync37(envFile)) {
|
|
21437
21685
|
const envRaw = readFileSync31(envFile, "utf8");
|
|
21438
21686
|
const patched = patchEnv(envRaw, {
|
|
21439
21687
|
MONITOR_AGENT_TOKEN: data.token,
|
|
@@ -21465,10 +21713,10 @@ function bootstrapStackHost(options) {
|
|
|
21465
21713
|
copyTemplateIfMissing("deploy/compose/.env.customer.example", options.envFile, createdFiles);
|
|
21466
21714
|
const brandingDest = path44.join(path44.dirname(options.envFile), "branding.json");
|
|
21467
21715
|
copyTemplateIfMissing("deploy/compose/gateway.json", path44.join(path44.dirname(options.envFile), "gateway.json"), createdFiles);
|
|
21468
|
-
if (!
|
|
21716
|
+
if (!existsSync37(brandingDest)) writeFileSync26(brandingDest, JSON.stringify({ brandName: "Hygo", productName: "Hygo OS" }, null, 2) + "\n", { mode: 384 });
|
|
21469
21717
|
let envHadPlaceholders = false;
|
|
21470
21718
|
let envRemainingPlaceholders = [];
|
|
21471
|
-
if (
|
|
21719
|
+
if (existsSync37(options.envFile)) {
|
|
21472
21720
|
const envRaw = readFileSync31(options.envFile, "utf8");
|
|
21473
21721
|
const hydrated = hydrateEnv(envRaw, options);
|
|
21474
21722
|
envHadPlaceholders = hydrated.hadPlaceholders;
|
|
@@ -21481,8 +21729,8 @@ function bootstrapStackHost(options) {
|
|
|
21481
21729
|
return {
|
|
21482
21730
|
dockerInstalled,
|
|
21483
21731
|
dockerComposeInstalled,
|
|
21484
|
-
composeFileExists:
|
|
21485
|
-
envFileExists:
|
|
21732
|
+
composeFileExists: existsSync37(options.composeFile),
|
|
21733
|
+
envFileExists: existsSync37(options.envFile),
|
|
21486
21734
|
envHadPlaceholders,
|
|
21487
21735
|
envRemainingPlaceholders,
|
|
21488
21736
|
licensePresent: !!(options.licenseKey || process.env.EXE_LICENSE_KEY || loadLicense()),
|
|
@@ -21558,7 +21806,7 @@ async function runStackUpdate(options) {
|
|
|
21558
21806
|
}
|
|
21559
21807
|
await postDeployAudit(options, "started", plan.targetVersion, previousVersion);
|
|
21560
21808
|
const backupDir = path44.join(path44.dirname(options.envFile), ".exe-stack-backups");
|
|
21561
|
-
|
|
21809
|
+
mkdirSync26(backupDir, { recursive: true });
|
|
21562
21810
|
const stamp = now2().toISOString().replace(/[:.]/g, "-");
|
|
21563
21811
|
const backupEnvFile = path44.join(backupDir, `env-${stamp}.bak`);
|
|
21564
21812
|
writeFileSync26(backupEnvFile, envRaw, { mode: 384 });
|
|
@@ -21613,7 +21861,7 @@ async function fetchImageCredentials(options) {
|
|
|
21613
21861
|
return await res.json();
|
|
21614
21862
|
}
|
|
21615
21863
|
function readCurrentStackVersion(lockFile) {
|
|
21616
|
-
if (!
|
|
21864
|
+
if (!existsSync37(lockFile)) return void 0;
|
|
21617
21865
|
try {
|
|
21618
21866
|
const parsed = JSON.parse(readFileSync31(lockFile, "utf8"));
|
|
21619
21867
|
return parsed.stackVersion;
|
|
@@ -21706,10 +21954,10 @@ function defaultStackPaths() {
|
|
|
21706
21954
|
const cwdCompose = path44.resolve("docker-compose.yml");
|
|
21707
21955
|
const cwdEnv = path44.resolve(".env");
|
|
21708
21956
|
const packagedManifest = path44.join(resolvePackageRoot2(), "deploy", "stack-manifests", "v0.9.json");
|
|
21709
|
-
const manifestRef = process.env.EXE_STACK_MANIFEST || (
|
|
21957
|
+
const manifestRef = process.env.EXE_STACK_MANIFEST || (existsSync37(packagedManifest) ? packagedManifest : "https://update.askexe.com/stack-manifest.json");
|
|
21710
21958
|
return {
|
|
21711
|
-
composeFile: process.env.EXE_STACK_COMPOSE_FILE || (
|
|
21712
|
-
envFile: process.env.EXE_STACK_ENV_FILE || (
|
|
21959
|
+
composeFile: process.env.EXE_STACK_COMPOSE_FILE || (existsSync37(cwdCompose) ? cwdCompose : "/opt/exe-stack/docker-compose.yml"),
|
|
21960
|
+
envFile: process.env.EXE_STACK_ENV_FILE || (existsSync37(cwdEnv) ? cwdEnv : "/opt/exe-stack/.env"),
|
|
21713
21961
|
manifestRef,
|
|
21714
21962
|
// Only call update.askexe.com if explicitly configured or if a remote manifest was requested.
|
|
21715
21963
|
// Packaged manifests keep cold-start installs unblocked even before update-service entitlements are provisioned.
|
|
@@ -21723,7 +21971,7 @@ function defaultStackPaths() {
|
|
|
21723
21971
|
}
|
|
21724
21972
|
function loadDefaultPublicKey() {
|
|
21725
21973
|
if (process.env.EXE_STACK_PUBLIC_KEY) return process.env.EXE_STACK_PUBLIC_KEY;
|
|
21726
|
-
if (process.env.EXE_STACK_PUBLIC_KEY_FILE &&
|
|
21974
|
+
if (process.env.EXE_STACK_PUBLIC_KEY_FILE && existsSync37(process.env.EXE_STACK_PUBLIC_KEY_FILE)) {
|
|
21727
21975
|
return readFileSync31(process.env.EXE_STACK_PUBLIC_KEY_FILE, "utf8");
|
|
21728
21976
|
}
|
|
21729
21977
|
return void 0;
|
|
@@ -28997,11 +29245,11 @@ function Footer() {
|
|
|
28997
29245
|
} catch {
|
|
28998
29246
|
}
|
|
28999
29247
|
try {
|
|
29000
|
-
const { existsSync:
|
|
29001
|
-
const { join } = await import("path");
|
|
29248
|
+
const { existsSync: existsSync44 } = await import("fs");
|
|
29249
|
+
const { join: join2 } = await import("path");
|
|
29002
29250
|
const home = process.env.HOME ?? "";
|
|
29003
|
-
const pidPath =
|
|
29004
|
-
setDaemon(
|
|
29251
|
+
const pidPath = join2(home, ".exe-os", "exed.pid");
|
|
29252
|
+
setDaemon(existsSync44(pidPath) ? "running" : "stopped");
|
|
29005
29253
|
} catch {
|
|
29006
29254
|
setDaemon("unknown");
|
|
29007
29255
|
}
|
|
@@ -31751,7 +31999,7 @@ var init_bash = __esm({
|
|
|
31751
31999
|
import { useState as useState6, useEffect as useEffect8, useMemo as useMemo4, useCallback as useCallback4, useRef as useRef4 } from "react";
|
|
31752
32000
|
import TextInput from "ink-text-input";
|
|
31753
32001
|
import path51 from "path";
|
|
31754
|
-
import { homedir as
|
|
32002
|
+
import { homedir as homedir7 } from "os";
|
|
31755
32003
|
import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
31756
32004
|
function CommandCenterView({
|
|
31757
32005
|
onSelectProject,
|
|
@@ -31785,13 +32033,13 @@ function CommandCenterView({
|
|
|
31785
32033
|
const { createPermissionsFromPreset: createPermissionsFromPreset2, EMPLOYEE_PERMISSIONS: EMPLOYEE_PERMISSIONS2 } = await Promise.resolve().then(() => (init_permissions(), permissions_exports));
|
|
31786
32034
|
const { getPresetByRole: getPresetByRole2 } = await Promise.resolve().then(() => (init_permission_presets(), permission_presets_exports));
|
|
31787
32035
|
const { createDefaultHooks: createDefaultHooks2 } = await Promise.resolve().then(() => (init_hooks(), hooks_exports));
|
|
31788
|
-
const { readFileSync: readFileSync39, existsSync:
|
|
31789
|
-
const { join } = await import("path");
|
|
31790
|
-
const { homedir:
|
|
31791
|
-
const configPath =
|
|
32036
|
+
const { readFileSync: readFileSync39, existsSync: existsSync44 } = await import("fs");
|
|
32037
|
+
const { join: join2 } = await import("path");
|
|
32038
|
+
const { homedir: homedir9 } = await import("os");
|
|
32039
|
+
const configPath = join2(homedir9(), ".exe-os", "config.json");
|
|
31792
32040
|
let failoverChain = ["anthropic", "opencode", "gemini", "openai"];
|
|
31793
32041
|
let providerConfigs = {};
|
|
31794
|
-
if (
|
|
32042
|
+
if (existsSync44(configPath)) {
|
|
31795
32043
|
try {
|
|
31796
32044
|
const raw = JSON.parse(readFileSync39(configPath, "utf8"));
|
|
31797
32045
|
if (Array.isArray(raw.failoverChain)) failoverChain = raw.failoverChain;
|
|
@@ -31851,10 +32099,10 @@ function CommandCenterView({
|
|
|
31851
32099
|
registry.register(BashTool2);
|
|
31852
32100
|
let agentRole = "CTO";
|
|
31853
32101
|
try {
|
|
31854
|
-
const markerDir =
|
|
32102
|
+
const markerDir = join2(homedir9(), ".exe-os", "session-cache");
|
|
31855
32103
|
const agentFiles = (await import("fs")).readdirSync(markerDir).filter((f) => f.startsWith("active-agent-"));
|
|
31856
32104
|
for (const f of agentFiles) {
|
|
31857
|
-
const data = JSON.parse(readFileSync39(
|
|
32105
|
+
const data = JSON.parse(readFileSync39(join2(markerDir, f), "utf8"));
|
|
31858
32106
|
if (data.agentRole) {
|
|
31859
32107
|
agentRole = data.agentRole;
|
|
31860
32108
|
break;
|
|
@@ -31999,7 +32247,7 @@ function CommandCenterView({
|
|
|
31999
32247
|
const demoEntries = DEMO_PROJECTS.map((p) => ({
|
|
32000
32248
|
projectName: p.projectName,
|
|
32001
32249
|
exeSession: p.exeSession,
|
|
32002
|
-
projectDir: path51.join(
|
|
32250
|
+
projectDir: path51.join(homedir7(), p.projectName),
|
|
32003
32251
|
employeeCount: p.employees.length,
|
|
32004
32252
|
activeCount: p.employees.filter((e) => e.status === "active").length,
|
|
32005
32253
|
memoryCount: p.employees.length * 4e3,
|
|
@@ -32037,8 +32285,8 @@ function CommandCenterView({
|
|
|
32037
32285
|
const { listSessions: listSessions2 } = await Promise.resolve().then(() => (init_session_registry(), session_registry_exports));
|
|
32038
32286
|
const { listTmuxSessions: listTmuxSessions2, inTmux: inTmux2 } = await Promise.resolve().then(() => (init_tmux_status(), tmux_status_exports));
|
|
32039
32287
|
const { loadEmployees: loadEmployees2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
|
|
32040
|
-
const { existsSync:
|
|
32041
|
-
const { join } = await import("path");
|
|
32288
|
+
const { existsSync: existsSync44 } = await import("fs");
|
|
32289
|
+
const { join: join2 } = await import("path");
|
|
32042
32290
|
const client = getClient2();
|
|
32043
32291
|
if (!client) {
|
|
32044
32292
|
setDbError(true);
|
|
@@ -32108,7 +32356,7 @@ function CommandCenterView({
|
|
|
32108
32356
|
}
|
|
32109
32357
|
const memoryCount = memoryCounts.get(name) ?? 0;
|
|
32110
32358
|
const openTaskCount = openTaskCounts.get(name) ?? 0;
|
|
32111
|
-
const hasGit = projectDir ?
|
|
32359
|
+
const hasGit = projectDir ? existsSync44(join2(projectDir, ".git")) : false;
|
|
32112
32360
|
const type = hasGit ? "code" : memoryCount > 0 ? "code" : "automation";
|
|
32113
32361
|
projectList.push({
|
|
32114
32362
|
projectName: name,
|
|
@@ -32132,8 +32380,8 @@ function CommandCenterView({
|
|
|
32132
32380
|
const totalResult = await client.execute("SELECT COUNT(*) as cnt FROM memories");
|
|
32133
32381
|
setHealth((h) => ({ ...h, memories: Number(totalResult.rows[0]?.cnt ?? 0) }));
|
|
32134
32382
|
try {
|
|
32135
|
-
const pidPath =
|
|
32136
|
-
setHealth((h) => ({ ...h, daemon:
|
|
32383
|
+
const pidPath = join2(process.env.HOME ?? "", ".exe-os", "exed.pid");
|
|
32384
|
+
setHealth((h) => ({ ...h, daemon: existsSync44(pidPath) ? "running" : "stopped" }));
|
|
32137
32385
|
} catch {
|
|
32138
32386
|
}
|
|
32139
32387
|
const activityResult = await client.execute(
|
|
@@ -33004,7 +33252,7 @@ var init_useOrchestrator = __esm({
|
|
|
33004
33252
|
// src/tui/views/Sessions.tsx
|
|
33005
33253
|
import React19, { useState as useState9, useEffect as useEffect11, useCallback as useCallback6 } from "react";
|
|
33006
33254
|
import path52 from "path";
|
|
33007
|
-
import { homedir as
|
|
33255
|
+
import { homedir as homedir8 } from "os";
|
|
33008
33256
|
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
33009
33257
|
function isCoordinatorEntry(entry) {
|
|
33010
33258
|
return entry.role.toLowerCase() === "coo" || isCoordinatorName(entry.name);
|
|
@@ -33041,7 +33289,7 @@ function SessionsView({
|
|
|
33041
33289
|
if (demo) {
|
|
33042
33290
|
setProjects(DEMO_PROJECTS.map((p) => ({
|
|
33043
33291
|
...p,
|
|
33044
|
-
projectDir: path52.join(
|
|
33292
|
+
projectDir: path52.join(homedir8(), p.projectName),
|
|
33045
33293
|
employees: p.employees.map((e) => ({ ...e, attached: e.status === "active" }))
|
|
33046
33294
|
})));
|
|
33047
33295
|
return;
|
|
@@ -34256,11 +34504,11 @@ async function loadGatewayConfig() {
|
|
|
34256
34504
|
state.running = false;
|
|
34257
34505
|
}
|
|
34258
34506
|
try {
|
|
34259
|
-
const { existsSync:
|
|
34260
|
-
const { join } = await import("path");
|
|
34507
|
+
const { existsSync: existsSync44, readFileSync: readFileSync39 } = await import("fs");
|
|
34508
|
+
const { join: join2 } = await import("path");
|
|
34261
34509
|
const home = process.env.HOME ?? "";
|
|
34262
|
-
const configPath =
|
|
34263
|
-
if (
|
|
34510
|
+
const configPath = join2(home, ".exe-os", "gateway.json");
|
|
34511
|
+
if (existsSync44(configPath)) {
|
|
34264
34512
|
const raw = JSON.parse(readFileSync39(configPath, "utf8"));
|
|
34265
34513
|
state.port = raw.port ?? 3100;
|
|
34266
34514
|
state.gatewayUrl = raw.gatewayUrl ?? "";
|
|
@@ -34859,11 +35107,11 @@ function TeamView({ onBack, onViewSessions }) {
|
|
|
34859
35107
|
setMembers(teamData);
|
|
34860
35108
|
setDbError(null);
|
|
34861
35109
|
try {
|
|
34862
|
-
const { existsSync:
|
|
34863
|
-
const { join } = await import("path");
|
|
35110
|
+
const { existsSync: existsSync44, readFileSync: readFileSync39 } = await import("fs");
|
|
35111
|
+
const { join: join2 } = await import("path");
|
|
34864
35112
|
const home = process.env.HOME ?? "";
|
|
34865
|
-
const gatewayConfig =
|
|
34866
|
-
if (
|
|
35113
|
+
const gatewayConfig = join2(home, ".exe-os", "gateway.json");
|
|
35114
|
+
if (existsSync44(gatewayConfig)) {
|
|
34867
35115
|
const raw = JSON.parse(readFileSync39(gatewayConfig, "utf8"));
|
|
34868
35116
|
if (raw.agents && raw.agents.length > 0) {
|
|
34869
35117
|
setExternals(raw.agents.map((a) => ({
|
|
@@ -35672,12 +35920,12 @@ function SettingsView({ onBack }) {
|
|
|
35672
35920
|
}
|
|
35673
35921
|
setProviders(providerList);
|
|
35674
35922
|
try {
|
|
35675
|
-
const { existsSync:
|
|
35676
|
-
const { join } = await import("path");
|
|
35923
|
+
const { existsSync: existsSync44 } = await import("fs");
|
|
35924
|
+
const { join: join2 } = await import("path");
|
|
35677
35925
|
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
35678
35926
|
const cfg = await loadConfig2();
|
|
35679
35927
|
const home = process.env.HOME ?? "";
|
|
35680
|
-
const hasKey =
|
|
35928
|
+
const hasKey = existsSync44(join2(home, ".exe-os", "master.key"));
|
|
35681
35929
|
if (cfg.cloud) {
|
|
35682
35930
|
setCloud({
|
|
35683
35931
|
configured: true,
|
|
@@ -35687,10 +35935,10 @@ function SettingsView({ onBack }) {
|
|
|
35687
35935
|
} else {
|
|
35688
35936
|
setCloud({ configured: false, endpoint: "", apiKey: "" });
|
|
35689
35937
|
}
|
|
35690
|
-
const pidPath =
|
|
35938
|
+
const pidPath = join2(home, ".exe-os", "exed.pid");
|
|
35691
35939
|
let daemon = "unknown";
|
|
35692
35940
|
try {
|
|
35693
|
-
daemon =
|
|
35941
|
+
daemon = existsSync44(pidPath) ? "running" : "stopped";
|
|
35694
35942
|
} catch {
|
|
35695
35943
|
}
|
|
35696
35944
|
let version = "unknown";
|
|
@@ -36565,7 +36813,7 @@ __export(code_context_index_exports, {
|
|
|
36565
36813
|
});
|
|
36566
36814
|
import crypto14 from "crypto";
|
|
36567
36815
|
import path53 from "path";
|
|
36568
|
-
import { existsSync as
|
|
36816
|
+
import { existsSync as existsSync39, mkdirSync as mkdirSync27, readFileSync as readFileSync34, readdirSync as readdirSync12, statSync as statSync9, writeFileSync as writeFileSync27 } from "fs";
|
|
36569
36817
|
import { spawnSync as spawnSync3 } from "child_process";
|
|
36570
36818
|
function vectorStorePath(projectRoot) {
|
|
36571
36819
|
const rootHash = hashText(projectRoot).slice(0, 16);
|
|
@@ -36573,7 +36821,7 @@ function vectorStorePath(projectRoot) {
|
|
|
36573
36821
|
}
|
|
36574
36822
|
function loadVectorStore(projectRoot) {
|
|
36575
36823
|
const file = vectorStorePath(projectRoot);
|
|
36576
|
-
if (!
|
|
36824
|
+
if (!existsSync39(file)) return null;
|
|
36577
36825
|
try {
|
|
36578
36826
|
const parsed = JSON.parse(readFileSync34(file, "utf8"));
|
|
36579
36827
|
if (parsed.version !== VECTOR_STORE_VERSION) return null;
|
|
@@ -36646,7 +36894,7 @@ function hashText(text) {
|
|
|
36646
36894
|
}
|
|
36647
36895
|
function indexDir() {
|
|
36648
36896
|
const dir = path53.join(EXE_AI_DIR, "code-context");
|
|
36649
|
-
|
|
36897
|
+
mkdirSync27(dir, { recursive: true });
|
|
36650
36898
|
return dir;
|
|
36651
36899
|
}
|
|
36652
36900
|
function getCodeContextIndexPath(projectRoot) {
|
|
@@ -36709,7 +36957,7 @@ function symbolId(filePath, chunk) {
|
|
|
36709
36957
|
}
|
|
36710
36958
|
function loadIndex(projectRoot) {
|
|
36711
36959
|
const file = getCodeContextIndexPath(projectRoot);
|
|
36712
|
-
if (!
|
|
36960
|
+
if (!existsSync39(file)) return null;
|
|
36713
36961
|
try {
|
|
36714
36962
|
const parsed = JSON.parse(readFileSync34(file, "utf8"));
|
|
36715
36963
|
if (parsed.version !== INDEX_VERSION || parsed.projectRoot !== projectRoot) return null;
|
|
@@ -36725,7 +36973,7 @@ function buildFileRecord(projectRoot, relPath, allFiles, previous) {
|
|
|
36725
36973
|
const absPath = path53.join(projectRoot, relPath);
|
|
36726
36974
|
let stat2;
|
|
36727
36975
|
try {
|
|
36728
|
-
stat2 =
|
|
36976
|
+
stat2 = statSync9(absPath);
|
|
36729
36977
|
} catch {
|
|
36730
36978
|
return { record: null, reused: false };
|
|
36731
36979
|
}
|
|
@@ -36799,7 +37047,7 @@ function loadOrBuildCodeContextIndex(options = {}) {
|
|
|
36799
37047
|
const existing = loaded.files[normalized];
|
|
36800
37048
|
if (!existing) return false;
|
|
36801
37049
|
try {
|
|
36802
|
-
const stat2 =
|
|
37050
|
+
const stat2 = statSync9(path53.join(projectRoot, normalized));
|
|
36803
37051
|
return stat2.mtimeMs === existing.mtimeMs && stat2.size === existing.size;
|
|
36804
37052
|
} catch {
|
|
36805
37053
|
return false;
|
|
@@ -37314,7 +37562,7 @@ __export(installer_exports2, {
|
|
|
37314
37562
|
verifyOpenCodeHooks: () => verifyOpenCodeHooks
|
|
37315
37563
|
});
|
|
37316
37564
|
import { readFile as readFile7, writeFile as writeFile8, mkdir as mkdir8 } from "fs/promises";
|
|
37317
|
-
import { existsSync as
|
|
37565
|
+
import { existsSync as existsSync40, readFileSync as readFileSync35 } from "fs";
|
|
37318
37566
|
import path54 from "path";
|
|
37319
37567
|
import os22 from "os";
|
|
37320
37568
|
async function registerOpenCodeMcp(packageRoot, homeDir = os22.homedir()) {
|
|
@@ -37323,7 +37571,7 @@ async function registerOpenCodeMcp(packageRoot, homeDir = os22.homedir()) {
|
|
|
37323
37571
|
const configPath = path54.join(configDir, "opencode.json");
|
|
37324
37572
|
await mkdir8(configDir, { recursive: true });
|
|
37325
37573
|
let config = {};
|
|
37326
|
-
if (
|
|
37574
|
+
if (existsSync40(configPath)) {
|
|
37327
37575
|
try {
|
|
37328
37576
|
config = JSON.parse(await readFile7(configPath, "utf-8"));
|
|
37329
37577
|
} catch {
|
|
@@ -37358,7 +37606,7 @@ async function installOpenCodePlugin(packageRoot, homeDir = os22.homedir()) {
|
|
|
37358
37606
|
/__PACKAGE_ROOT__/g,
|
|
37359
37607
|
packageRoot.replace(/\\/g, "\\\\")
|
|
37360
37608
|
);
|
|
37361
|
-
if (
|
|
37609
|
+
if (existsSync40(pluginPath)) {
|
|
37362
37610
|
const existing = await readFile7(pluginPath, "utf-8");
|
|
37363
37611
|
if (existing === pluginContent) {
|
|
37364
37612
|
return false;
|
|
@@ -37370,14 +37618,14 @@ async function installOpenCodePlugin(packageRoot, homeDir = os22.homedir()) {
|
|
|
37370
37618
|
function verifyOpenCodeHooks(homeDir = os22.homedir()) {
|
|
37371
37619
|
const configPath = path54.join(homeDir, ".config", "opencode", "opencode.json");
|
|
37372
37620
|
const pluginPath = path54.join(homeDir, ".config", "opencode", "plugins", "exe-os.mjs");
|
|
37373
|
-
if (!
|
|
37621
|
+
if (!existsSync40(configPath)) return false;
|
|
37374
37622
|
try {
|
|
37375
37623
|
const config = JSON.parse(readFileSync35(configPath, "utf-8"));
|
|
37376
37624
|
if (!config.mcp?.["exe-os"]?.enabled) return false;
|
|
37377
37625
|
} catch {
|
|
37378
37626
|
return false;
|
|
37379
37627
|
}
|
|
37380
|
-
if (!
|
|
37628
|
+
if (!existsSync40(pluginPath)) return false;
|
|
37381
37629
|
try {
|
|
37382
37630
|
const plugin = readFileSync35(pluginPath, "utf-8");
|
|
37383
37631
|
if (!plugin.includes(EXE_HOOK_FILES.postToolCombined)) return false;
|
|
@@ -37421,7 +37669,7 @@ __export(installer_exports3, {
|
|
|
37421
37669
|
verifyCodexHooks: () => verifyCodexHooks
|
|
37422
37670
|
});
|
|
37423
37671
|
import { readFile as readFile8, writeFile as writeFile9, mkdir as mkdir9 } from "fs/promises";
|
|
37424
|
-
import { existsSync as
|
|
37672
|
+
import { existsSync as existsSync41, readFileSync as readFileSync36 } from "fs";
|
|
37425
37673
|
import path55 from "path";
|
|
37426
37674
|
import os23 from "os";
|
|
37427
37675
|
async function mergeCodexHooks(packageRoot, homeDir = os23.homedir()) {
|
|
@@ -37433,7 +37681,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os23.homedir()) {
|
|
|
37433
37681
|
await mkdir9(codexDir, { recursive: true });
|
|
37434
37682
|
await mkdir9(logsDir, { recursive: true });
|
|
37435
37683
|
let hooksJson = {};
|
|
37436
|
-
if (
|
|
37684
|
+
if (existsSync41(hooksPath)) {
|
|
37437
37685
|
try {
|
|
37438
37686
|
hooksJson = JSON.parse(await readFile8(hooksPath, "utf-8"));
|
|
37439
37687
|
} catch {
|
|
@@ -37542,7 +37790,7 @@ async function mergeCodexHooks(packageRoot, homeDir = os23.homedir()) {
|
|
|
37542
37790
|
}
|
|
37543
37791
|
function verifyCodexHooks(homeDir = os23.homedir()) {
|
|
37544
37792
|
const hooksPath = path55.join(homeDir, ".codex", "hooks.json");
|
|
37545
|
-
if (!
|
|
37793
|
+
if (!existsSync41(hooksPath)) return false;
|
|
37546
37794
|
try {
|
|
37547
37795
|
const hooksJson = JSON.parse(readFileSync36(hooksPath, "utf-8"));
|
|
37548
37796
|
if (!hooksJson.hooks) return false;
|
|
@@ -37580,7 +37828,7 @@ async function installCodexStatusLine(homeDir = os23.homedir()) {
|
|
|
37580
37828
|
const configPath = path55.join(codexDir, "config.toml");
|
|
37581
37829
|
await mkdir9(codexDir, { recursive: true });
|
|
37582
37830
|
let content = "";
|
|
37583
|
-
if (
|
|
37831
|
+
if (existsSync41(configPath)) {
|
|
37584
37832
|
content = await readFile8(configPath, "utf-8");
|
|
37585
37833
|
if (/\[tui\][\s\S]*?status_line\s*=/.test(content)) {
|
|
37586
37834
|
return "already-configured";
|
|
@@ -37637,7 +37885,7 @@ async function registerCodexMcpServer(packageRoot, homeDir = os23.homedir()) {
|
|
|
37637
37885
|
void packageRoot;
|
|
37638
37886
|
await mkdir9(codexDir, { recursive: true });
|
|
37639
37887
|
let content = "";
|
|
37640
|
-
if (
|
|
37888
|
+
if (existsSync41(configPath)) {
|
|
37641
37889
|
content = await readFile8(configPath, "utf-8");
|
|
37642
37890
|
}
|
|
37643
37891
|
const sectionHeader = "[mcp_servers.exe-os]";
|
|
@@ -37665,7 +37913,7 @@ async function ensureCodexHooksFeature(homeDir = os23.homedir()) {
|
|
|
37665
37913
|
const configPath = path55.join(homeDir, ".codex", "config.toml");
|
|
37666
37914
|
await mkdir9(path55.join(homeDir, ".codex"), { recursive: true });
|
|
37667
37915
|
let content = "";
|
|
37668
|
-
if (
|
|
37916
|
+
if (existsSync41(configPath)) {
|
|
37669
37917
|
content = await readFile8(configPath, "utf-8");
|
|
37670
37918
|
}
|
|
37671
37919
|
if (/\[features\][\s\S]*?codex_hooks\s*=\s*true/.test(content)) {
|
|
@@ -37740,11 +37988,11 @@ __export(mcp_diagnostics_exports, {
|
|
|
37740
37988
|
diagnoseClaudeMcpConfig: () => diagnoseClaudeMcpConfig,
|
|
37741
37989
|
formatMcpDiagnosticReport: () => formatMcpDiagnosticReport
|
|
37742
37990
|
});
|
|
37743
|
-
import { existsSync as
|
|
37991
|
+
import { existsSync as existsSync42, readFileSync as readFileSync37 } from "fs";
|
|
37744
37992
|
import path56 from "path";
|
|
37745
37993
|
import os24 from "os";
|
|
37746
37994
|
function readJson(filePath) {
|
|
37747
|
-
if (!
|
|
37995
|
+
if (!existsSync42(filePath)) return null;
|
|
37748
37996
|
try {
|
|
37749
37997
|
return JSON.parse(readFileSync37(filePath, "utf8"));
|
|
37750
37998
|
} catch {
|
|
@@ -37763,7 +38011,7 @@ function findAncestorMcpJsons2(cwd2, homeDir) {
|
|
|
37763
38011
|
const stop = path56.resolve(homeDir);
|
|
37764
38012
|
while (dir !== root) {
|
|
37765
38013
|
const candidate = path56.join(dir, ".mcp.json");
|
|
37766
|
-
if (
|
|
38014
|
+
if (existsSync42(candidate)) files.push(candidate);
|
|
37767
38015
|
if (dir === stop) break;
|
|
37768
38016
|
dir = path56.dirname(dir);
|
|
37769
38017
|
}
|
|
@@ -37940,7 +38188,7 @@ var init_mcp_diagnostics = __esm({
|
|
|
37940
38188
|
});
|
|
37941
38189
|
|
|
37942
38190
|
// src/bin/cli.ts
|
|
37943
|
-
import { existsSync as
|
|
38191
|
+
import { existsSync as existsSync43, readFileSync as readFileSync38, writeFileSync as writeFileSync28, readdirSync as readdirSync13, rmSync as rmSync2 } from "fs";
|
|
37944
38192
|
import path57 from "path";
|
|
37945
38193
|
import os25 from "os";
|
|
37946
38194
|
var args = process.argv.slice(2);
|
|
@@ -38194,7 +38442,7 @@ ID: ${result.id}`);
|
|
|
38194
38442
|
} else {
|
|
38195
38443
|
const claudeDir = path57.join(os25.homedir(), ".claude");
|
|
38196
38444
|
const settingsPath = path57.join(claudeDir, "settings.json");
|
|
38197
|
-
const hasClaudeCode =
|
|
38445
|
+
const hasClaudeCode = existsSync43(settingsPath) && (() => {
|
|
38198
38446
|
try {
|
|
38199
38447
|
const raw = readFileSync38(settingsPath, "utf8");
|
|
38200
38448
|
return raw.includes("exe-os") || raw.includes("exe-mem");
|
|
@@ -38207,7 +38455,7 @@ ID: ${result.id}`);
|
|
|
38207
38455
|
let cooName = DEFAULT_COORDINATOR_TEMPLATE_NAME2;
|
|
38208
38456
|
try {
|
|
38209
38457
|
const rosterPath = path57.join(os25.homedir(), ".exe-os", "exe-employees.json");
|
|
38210
|
-
if (
|
|
38458
|
+
if (existsSync43(rosterPath)) {
|
|
38211
38459
|
const roster = JSON.parse(readFileSync38(rosterPath, "utf8"));
|
|
38212
38460
|
const coo = roster.find((e) => e.role === "COO");
|
|
38213
38461
|
if (coo) cooName = coo.name;
|
|
@@ -38365,7 +38613,7 @@ async function runClaudeCheck() {
|
|
|
38365
38613
|
const settingsPath = path57.join(claudeDir, "settings.json");
|
|
38366
38614
|
const claudeJsonPath = path57.join(os25.homedir(), ".claude.json");
|
|
38367
38615
|
let ok = true;
|
|
38368
|
-
if (
|
|
38616
|
+
if (existsSync43(settingsPath)) {
|
|
38369
38617
|
let settings;
|
|
38370
38618
|
try {
|
|
38371
38619
|
settings = JSON.parse(readFileSync38(settingsPath, "utf8"));
|
|
@@ -38394,7 +38642,7 @@ async function runClaudeCheck() {
|
|
|
38394
38642
|
console.log("\x1B[31m\u2717\x1B[0m settings.json not found");
|
|
38395
38643
|
ok = false;
|
|
38396
38644
|
}
|
|
38397
|
-
if (
|
|
38645
|
+
if (existsSync43(claudeJsonPath)) {
|
|
38398
38646
|
let claudeJson;
|
|
38399
38647
|
try {
|
|
38400
38648
|
claudeJson = JSON.parse(readFileSync38(claudeJsonPath, "utf8"));
|
|
@@ -38431,7 +38679,7 @@ async function runClaudeCheck() {
|
|
|
38431
38679
|
console.log("\x1B[32m\u2713\x1B[0m No .mcp.json/project MCP name collisions detected");
|
|
38432
38680
|
}
|
|
38433
38681
|
const skillsDir = path57.join(claudeDir, "skills");
|
|
38434
|
-
if (
|
|
38682
|
+
if (existsSync43(skillsDir)) {
|
|
38435
38683
|
console.log("\x1B[32m\u2713\x1B[0m Slash skills directory exists");
|
|
38436
38684
|
} else {
|
|
38437
38685
|
console.log("\x1B[31m\u2717\x1B[0m Slash skills directory missing");
|
|
@@ -38462,7 +38710,7 @@ async function runClaudeUninstall(flags = []) {
|
|
|
38462
38710
|
let removed = 0;
|
|
38463
38711
|
const log = (msg) => console.log(dryRun ? `[dry-run] ${msg}` : msg);
|
|
38464
38712
|
let settings = {};
|
|
38465
|
-
if (
|
|
38713
|
+
if (existsSync43(settingsPath)) {
|
|
38466
38714
|
try {
|
|
38467
38715
|
settings = JSON.parse(readFileSync38(settingsPath, "utf8"));
|
|
38468
38716
|
} catch {
|
|
@@ -38509,7 +38757,7 @@ async function runClaudeUninstall(flags = []) {
|
|
|
38509
38757
|
removed++;
|
|
38510
38758
|
}
|
|
38511
38759
|
}
|
|
38512
|
-
if (
|
|
38760
|
+
if (existsSync43(claudeJsonPath)) {
|
|
38513
38761
|
const raw = readFileSync38(claudeJsonPath, "utf8");
|
|
38514
38762
|
if (raw.length > 1e6) {
|
|
38515
38763
|
console.error("claude.json exceeds 1 MB \u2014 skipping parse.");
|
|
@@ -38540,7 +38788,7 @@ async function runClaudeUninstall(flags = []) {
|
|
|
38540
38788
|
}
|
|
38541
38789
|
}
|
|
38542
38790
|
const skillsDir = path57.join(claudeDir, "skills");
|
|
38543
|
-
if (
|
|
38791
|
+
if (existsSync43(skillsDir)) {
|
|
38544
38792
|
let skillCount = 0;
|
|
38545
38793
|
try {
|
|
38546
38794
|
const entries = readdirSync13(skillsDir);
|
|
@@ -38559,7 +38807,7 @@ async function runClaudeUninstall(flags = []) {
|
|
|
38559
38807
|
}
|
|
38560
38808
|
}
|
|
38561
38809
|
const claudeMdPath = path57.join(claudeDir, "CLAUDE.md");
|
|
38562
|
-
if (
|
|
38810
|
+
if (existsSync43(claudeMdPath)) {
|
|
38563
38811
|
const content = readFileSync38(claudeMdPath, "utf8");
|
|
38564
38812
|
const startMarker = "<!-- exe-os:orchestration-start -->";
|
|
38565
38813
|
const endMarker = "<!-- exe-os:orchestration-end -->";
|
|
@@ -38573,13 +38821,13 @@ async function runClaudeUninstall(flags = []) {
|
|
|
38573
38821
|
}
|
|
38574
38822
|
}
|
|
38575
38823
|
const agentsDir = path57.join(claudeDir, "agents");
|
|
38576
|
-
if (
|
|
38824
|
+
if (existsSync43(agentsDir)) {
|
|
38577
38825
|
let agentCount = 0;
|
|
38578
38826
|
try {
|
|
38579
38827
|
const entries = readdirSync13(agentsDir).filter((f) => f.endsWith(".md"));
|
|
38580
38828
|
let knownNames = /* @__PURE__ */ new Set();
|
|
38581
38829
|
const rosterPath = path57.join(exeOsDir, "exe-employees.json");
|
|
38582
|
-
if (
|
|
38830
|
+
if (existsSync43(rosterPath)) {
|
|
38583
38831
|
try {
|
|
38584
38832
|
const roster = JSON.parse(readFileSync38(rosterPath, "utf8"));
|
|
38585
38833
|
knownNames = new Set(roster.map((e) => e.name));
|
|
@@ -38601,13 +38849,13 @@ async function runClaudeUninstall(flags = []) {
|
|
|
38601
38849
|
}
|
|
38602
38850
|
}
|
|
38603
38851
|
const projectsDir = path57.join(claudeDir, "projects");
|
|
38604
|
-
if (
|
|
38852
|
+
if (existsSync43(projectsDir)) {
|
|
38605
38853
|
let projectCount = 0;
|
|
38606
38854
|
try {
|
|
38607
38855
|
const projects = readdirSync13(projectsDir);
|
|
38608
38856
|
for (const proj of projects) {
|
|
38609
38857
|
const projSettings = path57.join(projectsDir, proj, "settings.json");
|
|
38610
|
-
if (!
|
|
38858
|
+
if (!existsSync43(projSettings)) continue;
|
|
38611
38859
|
try {
|
|
38612
38860
|
const pSettings = JSON.parse(readFileSync38(projSettings, "utf8"));
|
|
38613
38861
|
let changed = false;
|
|
@@ -38646,7 +38894,7 @@ async function runClaudeUninstall(flags = []) {
|
|
|
38646
38894
|
const binDir = path57.dirname(exeBinPath);
|
|
38647
38895
|
let symlinkCount = 0;
|
|
38648
38896
|
const rosterPath = path57.join(exeOsDir, "exe-employees.json");
|
|
38649
|
-
if (
|
|
38897
|
+
if (existsSync43(rosterPath)) {
|
|
38650
38898
|
const roster = JSON.parse(readFileSync38(rosterPath, "utf8"));
|
|
38651
38899
|
const { DEFAULT_COORDINATOR_TEMPLATE_NAME: DEFAULT_COORDINATOR_TEMPLATE_NAME2 } = await Promise.resolve().then(() => (init_employees(), employees_exports));
|
|
38652
38900
|
const coordinatorName = roster.find((e) => e.role?.toLowerCase() === "coo")?.name ?? DEFAULT_COORDINATOR_TEMPLATE_NAME2;
|
|
@@ -38654,7 +38902,7 @@ async function runClaudeUninstall(flags = []) {
|
|
|
38654
38902
|
if (emp.name === coordinatorName) continue;
|
|
38655
38903
|
for (const suffix of ["", "-opencode"]) {
|
|
38656
38904
|
const linkPath = path57.join(binDir, `${emp.name}${suffix}`);
|
|
38657
|
-
if (
|
|
38905
|
+
if (existsSync43(linkPath)) {
|
|
38658
38906
|
if (!dryRun) rmSync2(linkPath, { force: true });
|
|
38659
38907
|
symlinkCount++;
|
|
38660
38908
|
}
|
|
@@ -38667,7 +38915,7 @@ async function runClaudeUninstall(flags = []) {
|
|
|
38667
38915
|
}
|
|
38668
38916
|
} catch {
|
|
38669
38917
|
}
|
|
38670
|
-
if (purge &&
|
|
38918
|
+
if (purge && existsSync43(exeOsDir)) {
|
|
38671
38919
|
if (!dryRun) {
|
|
38672
38920
|
process.stdout.write("\x1B[33m\u26A0 This will delete all memories, identities, and agent data.\x1B[0m\n");
|
|
38673
38921
|
process.stdout.write(" Removing ~/.exe-os...\n");
|