aiden-runtime 3.19.4 → 3.19.6

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.
Files changed (108) hide show
  1. package/config/devos.config.backup.json +224 -224
  2. package/config/devos.config.json +1 -1
  3. package/dist/api/server.js +7 -1
  4. package/dist/core/agentLoop.js +8 -3
  5. package/dist/core/skillLoader.js +2 -0
  6. package/dist/core/slashAsTool.js +2 -0
  7. package/dist/core/toolRegistry.js +16 -0
  8. package/dist/core/version.js +1 -1
  9. package/dist/providers/router.js +46 -6
  10. package/dist-bundle/cli.js +911 -557
  11. package/dist-bundle/index.js +758 -658
  12. package/package.json +268 -266
  13. package/scripts/postinstall.js +58 -1
  14. package/workspace-templates/HEARTBEAT.md +16 -0
  15. package/workspace-templates/SOUL.md +267 -0
  16. package/workspace-templates/STANDING_ORDERS.md +21 -0
  17. package/workspace-templates/permissions.yaml +180 -0
  18. package/workspace-templates/skills/architecture-diagram/SKILL.md +126 -0
  19. package/workspace-templates/skills/architecture-diagram/skill.json +25 -0
  20. package/workspace-templates/skills/arxiv/SKILL.md +124 -0
  21. package/workspace-templates/skills/arxiv/skill.json +26 -0
  22. package/workspace-templates/skills/ascii-art/SKILL.md +142 -0
  23. package/workspace-templates/skills/ascii-art/skill.json +26 -0
  24. package/workspace-templates/skills/blogwatcher/SKILL.md +147 -0
  25. package/workspace-templates/skills/blogwatcher/skill.json +26 -0
  26. package/workspace-templates/skills/censys/SKILL.md +104 -0
  27. package/workspace-templates/skills/censys/index.ts +133 -0
  28. package/workspace-templates/skills/censys/skill.json +25 -0
  29. package/workspace-templates/skills/clipboard-history/SKILL.md +101 -0
  30. package/workspace-templates/skills/clipboard-history/skill.json +23 -0
  31. package/workspace-templates/skills/crt-sh/SKILL.md +102 -0
  32. package/workspace-templates/skills/crt-sh/index.ts +59 -0
  33. package/workspace-templates/skills/crt-sh/skill.json +25 -0
  34. package/workspace-templates/skills/cveapi/SKILL.md +114 -0
  35. package/workspace-templates/skills/cveapi/index.ts +249 -0
  36. package/workspace-templates/skills/cveapi/skill.json +25 -0
  37. package/workspace-templates/skills/docker-management/SKILL.md +156 -0
  38. package/workspace-templates/skills/docker-management/skill.json +25 -0
  39. package/workspace-templates/skills/excalidraw/SKILL.md +148 -0
  40. package/workspace-templates/skills/excalidraw/skill.json +25 -0
  41. package/workspace-templates/skills/explainshell/SKILL.md +93 -0
  42. package/workspace-templates/skills/explainshell/index.ts +132 -0
  43. package/workspace-templates/skills/explainshell/skill.json +25 -0
  44. package/workspace-templates/skills/financial_research/SKILL.md +21 -0
  45. package/workspace-templates/skills/financial_research/skill.json +24 -0
  46. package/workspace-templates/skills/gif-search/SKILL.md +122 -0
  47. package/workspace-templates/skills/gif-search/skill.json +25 -0
  48. package/workspace-templates/skills/github-auth/SKILL.md +134 -0
  49. package/workspace-templates/skills/github-auth/skill.json +26 -0
  50. package/workspace-templates/skills/github-issues/SKILL.md +130 -0
  51. package/workspace-templates/skills/github-issues/skill.json +25 -0
  52. package/workspace-templates/skills/github-pr-workflow/SKILL.md +143 -0
  53. package/workspace-templates/skills/github-pr-workflow/skill.json +26 -0
  54. package/workspace-templates/skills/github-repo-management/SKILL.md +147 -0
  55. package/workspace-templates/skills/github-repo-management/skill.json +26 -0
  56. package/workspace-templates/skills/google-workspace/SKILL.md +110 -0
  57. package/workspace-templates/skills/google-workspace/skill.json +26 -0
  58. package/workspace-templates/skills/greynoise/SKILL.md +96 -0
  59. package/workspace-templates/skills/greynoise/index.ts +107 -0
  60. package/workspace-templates/skills/greynoise/skill.json +25 -0
  61. package/workspace-templates/skills/haveibeenpwned/SKILL.md +100 -0
  62. package/workspace-templates/skills/haveibeenpwned/index.ts +72 -0
  63. package/workspace-templates/skills/haveibeenpwned/skill.json +24 -0
  64. package/workspace-templates/skills/jupyter-live-kernel/SKILL.md +116 -0
  65. package/workspace-templates/skills/jupyter-live-kernel/skill.json +25 -0
  66. package/workspace-templates/skills/linear/SKILL.md +107 -0
  67. package/workspace-templates/skills/linear/skill.json +25 -0
  68. package/workspace-templates/skills/nano-pdf/SKILL.md +113 -0
  69. package/workspace-templates/skills/nano-pdf/skill.json +26 -0
  70. package/workspace-templates/skills/notion/SKILL.md +108 -0
  71. package/workspace-templates/skills/notion/skill.json +24 -0
  72. package/workspace-templates/skills/obsidian/SKILL.md +115 -0
  73. package/workspace-templates/skills/obsidian/skill.json +24 -0
  74. package/workspace-templates/skills/ocr-and-documents/SKILL.md +125 -0
  75. package/workspace-templates/skills/ocr-and-documents/skill.json +26 -0
  76. package/workspace-templates/skills/p5js/SKILL.md +163 -0
  77. package/workspace-templates/skills/p5js/skill.json +24 -0
  78. package/workspace-templates/skills/research-paper-writing/SKILL.md +158 -0
  79. package/workspace-templates/skills/research-paper-writing/skill.json +26 -0
  80. package/workspace-templates/skills/securityheaders/SKILL.md +99 -0
  81. package/workspace-templates/skills/securityheaders/index.ts +213 -0
  82. package/workspace-templates/skills/securityheaders/skill.json +26 -0
  83. package/workspace-templates/skills/shodan/SKILL.md +113 -0
  84. package/workspace-templates/skills/shodan/index.ts +94 -0
  85. package/workspace-templates/skills/shodan/skill.json +26 -0
  86. package/workspace-templates/skills/songsee/SKILL.md +152 -0
  87. package/workspace-templates/skills/songsee/skill.json +25 -0
  88. package/workspace-templates/skills/ssllabs/SKILL.md +107 -0
  89. package/workspace-templates/skills/ssllabs/index.ts +208 -0
  90. package/workspace-templates/skills/ssllabs/skill.json +27 -0
  91. package/workspace-templates/skills/stable-diffusion-image-generation/SKILL.md +136 -0
  92. package/workspace-templates/skills/stable-diffusion-image-generation/skill.json +24 -0
  93. package/workspace-templates/skills/systematic-debugging/SKILL.md +131 -0
  94. package/workspace-templates/skills/systematic-debugging/skill.json +25 -0
  95. package/workspace-templates/skills/test-driven-development/SKILL.md +164 -0
  96. package/workspace-templates/skills/test-driven-development/skill.json +25 -0
  97. package/workspace-templates/skills/urlscan/SKILL.md +118 -0
  98. package/workspace-templates/skills/urlscan/index.ts +94 -0
  99. package/workspace-templates/skills/urlscan/skill.json +24 -0
  100. package/workspace-templates/skills/virustotal/SKILL.md +120 -0
  101. package/workspace-templates/skills/virustotal/index.ts +124 -0
  102. package/workspace-templates/skills/virustotal/skill.json +26 -0
  103. package/workspace-templates/skills/web_research/SKILL.md +18 -0
  104. package/workspace-templates/skills/web_research/skill.json +20 -0
  105. package/workspace-templates/skills/xitter/SKILL.md +148 -0
  106. package/workspace-templates/skills/xitter/skill.json +26 -0
  107. package/workspace-templates/skills/youtube-content/SKILL.md +121 -0
  108. package/workspace-templates/skills/youtube-content/skill.json +25 -0
@@ -26650,7 +26650,7 @@ var require_websocket_server = __commonJS({
26650
26650
  var VERSION;
26651
26651
  var init_version = __esm({
26652
26652
  "core/version.ts"() {
26653
- VERSION = "3.19.4";
26653
+ VERSION = "3.19.6";
26654
26654
  }
26655
26655
  });
26656
26656
 
@@ -99142,6 +99142,8 @@ var init_skillLoader = __esm({
99142
99142
  import_path15.default.join(process.cwd(), "workspace", "skills"),
99143
99143
  import_path15.default.join(process.cwd(), "workspace", "skills", "learned"),
99144
99144
  import_path15.default.join(process.cwd(), "workspace", "skills", "approved"),
99145
+ // Workspace-level installed skills (written by skillRegistry.ts)
99146
+ import_path15.default.join(process.cwd(), "workspace", "skills", "installed"),
99145
99147
  // A2/A3 approved drafts
99146
99148
  import_path15.default.join(process.cwd(), "skills", "learned", "approved"),
99147
99149
  // A4 library-installed skills
@@ -99759,6 +99761,7 @@ var init_modelRegistry = __esm({
99759
99761
  var router_exports = {};
99760
99762
  __export(router_exports, {
99761
99763
  assessComplexity: () => assessComplexity,
99764
+ diagnoseProviderPool: () => diagnoseProviderPool,
99762
99765
  enterDegradedMode: () => enterDegradedMode,
99763
99766
  exitDegradedMode: () => exitDegradedMode,
99764
99767
  getLocalModels: () => getLocalModels,
@@ -99873,6 +99876,51 @@ function autoResetExpiredLimits() {
99873
99876
  if (changed) saveConfig(config2);
99874
99877
  return changed;
99875
99878
  }
99879
+ function diagnoseProviderPool() {
99880
+ const config2 = loadConfig();
99881
+ const allApis = mergeCustomProviders(config2.providers.apis);
99882
+ const enabled = allApis.filter((a) => a.enabled);
99883
+ const disabledCount = allApis.length - enabled.length;
99884
+ let noKey = 0, rateLimited = 0;
99885
+ for (const a of enabled) {
99886
+ if (a.rateLimited) {
99887
+ rateLimited++;
99888
+ continue;
99889
+ }
99890
+ if (a.provider === "custom") continue;
99891
+ const k = a.key.startsWith("env:") ? process.env[a.key.replace("env:", "")] || "" : a.key;
99892
+ if (k.length === 0) noKey++;
99893
+ }
99894
+ const active = enabled.length - noKey - rateLimited;
99895
+ if (active > 0)
99896
+ return { state: "ok", noKeyCount: noKey, rateLimitedCount: rateLimited, disabledCount, enabledCount: enabled.length, message: "" };
99897
+ if (noKey > 0 && rateLimited === 0)
99898
+ return {
99899
+ state: "unconfigured",
99900
+ noKeyCount: noKey,
99901
+ rateLimitedCount: 0,
99902
+ disabledCount,
99903
+ enabledCount: enabled.length,
99904
+ message: "No API keys configured - add keys in Settings > API Keys or set env vars"
99905
+ };
99906
+ if (rateLimited > 0 && noKey === 0)
99907
+ return {
99908
+ state: "rate-limited",
99909
+ noKeyCount: 0,
99910
+ rateLimitedCount: rateLimited,
99911
+ disabledCount,
99912
+ enabledCount: enabled.length,
99913
+ message: `All ${rateLimited} cloud provider(s) rate-limited - retrying automatically`
99914
+ };
99915
+ return {
99916
+ state: "mixed",
99917
+ noKeyCount: noKey,
99918
+ rateLimitedCount: rateLimited,
99919
+ disabledCount,
99920
+ enabledCount: enabled.length,
99921
+ message: `${noKey} provider(s) have no key, ${rateLimited} rate-limited`
99922
+ };
99923
+ }
99876
99924
  function getNextAvailableAPI() {
99877
99925
  autoResetExpiredLimits();
99878
99926
  const config2 = loadConfig();
@@ -99883,7 +99931,11 @@ function getNextAvailableAPI() {
99883
99931
  const resolvedKey = api.key.startsWith("env:") ? process.env[api.key.replace("env:", "")] || "" : api.key;
99884
99932
  return resolvedKey.length > 0;
99885
99933
  });
99886
- if (!available.length) return null;
99934
+ if (!available.length) {
99935
+ const diag = diagnoseProviderPool();
99936
+ if (diag.message) console.log(`[Router] ${diag.message}`);
99937
+ return null;
99938
+ }
99887
99939
  const primary = config2.primaryProvider;
99888
99940
  const scored = available.map((api) => {
99889
99941
  const avgMs = responseTimesMs.get(api.name) ?? 2e3;
@@ -100036,7 +100088,8 @@ function getModelForTask(task, message) {
100036
100088
  return resolveKey(chosen);
100037
100089
  }
100038
100090
  const model = getOllamaModelForTask(task === "planner" ? "planner" : "responder");
100039
- console.log(`[Router] ${task}: all cloud providers rate-limited - using Ollama ${model}`);
100091
+ const diag = diagnoseProviderPool();
100092
+ console.log(`[Router] ${task}: ${diag.message || "all cloud providers unavailable"} - using Ollama ${model}`);
100040
100093
  return { apiKey: "", model, providerName: "ollama", apiName: "ollama" };
100041
100094
  }
100042
100095
  if (task === "executor") {
@@ -100045,7 +100098,8 @@ function getModelForTask(task, message) {
100045
100098
  if (api) return resolveKey(api);
100046
100099
  }
100047
100100
  const model = getOllamaModelForTask("executor");
100048
- console.log(`[Router] Executor: all cloud providers unavailable - falling back to Ollama ${model}`);
100101
+ const diag = diagnoseProviderPool();
100102
+ console.log(`[Router] Executor: ${diag.message || "all cloud providers unavailable"} - falling back to Ollama ${model}`);
100049
100103
  return { apiKey: "", model, providerName: "ollama", apiName: "ollama" };
100050
100104
  }
100051
100105
  if (available.length > 0) return resolveKey(available[0]);
@@ -100069,7 +100123,8 @@ function getSmartProvider() {
100069
100123
  }
100070
100124
  if (config2.routing?.fallbackToOllama !== false) {
100071
100125
  const model2 = getOllamaModelForTask("responder");
100072
- console.log(`[Router] All APIs unavailable \u2014 falling back to Ollama ${model2}`);
100126
+ const diag = diagnoseProviderPool();
100127
+ console.log(`[Router] ${diag.message || "All APIs unavailable"} - falling back to Ollama ${model2}`);
100073
100128
  return { provider: ollamaProvider, model: model2, userName, apiName: "ollama" };
100074
100129
  }
100075
100130
  const model = getOllamaModelForTask("responder");
@@ -100111,7 +100166,7 @@ function enterDegradedMode(reason) {
100111
100166
  }
100112
100167
  return {
100113
100168
  mode: "degraded",
100114
- message: `I'm temporarily running in limited mode \u2014 my AI providers are at capacity. I can still:
100169
+ message: `I'm temporarily running in limited mode \u2014 ${diagnoseProviderPool().state === "unconfigured" ? "no API keys are configured" : "my AI providers are at capacity"}. I can still:
100115
100170
  \u2022 Search your files and memory
100116
100171
  \u2022 Run scheduled tasks
100117
100172
  \u2022 Execute shell commands and scripts
@@ -365359,7 +365414,7 @@ ${summaryInput}`,
365359
365414
  if (!parsed) {
365360
365415
  console.warn("[Planner] All LLM attempts failed \u2014 respond fallback (going through guard)");
365361
365416
  parsed = {
365362
- plan: [{ step: 1, tool: "respond", input: { message: buildDiagnostic({ tool: "planner", error: "All LLM attempts failed", retries: 3, suggestion: "Provider chain may be rate-limited. Try again in 1\u20132 minutes or rephrase your request." }) }, description: "Fallback response" }],
365417
+ plan: [{ step: 1, tool: "respond", input: { message: buildDiagnostic({ tool: "planner", error: "All LLM attempts failed", retries: 3, suggestion: diagnoseProviderPool().state === "unconfigured" ? "No API keys configured. Add keys in Settings > API Keys, or start Ollama for local inference." : "Provider chain is rate-limited. Try again in 1-2 minutes or rephrase your request." }) }, description: "Fallback response" }],
365363
365418
  requires_execution: true,
365364
365419
  goal: message
365365
365420
  };
@@ -365491,7 +365546,7 @@ Fix these issues and output a corrected JSON plan.`
365491
365546
  tool: "planner",
365492
365547
  error: "Could not generate tool plan for action intent",
365493
365548
  retries: 1,
365494
- suggestion: "Provider chain may be rate-limited. Try again in 1\u20132 minutes or use a more specific instruction."
365549
+ suggestion: diagnoseProviderPool().state === "unconfigured" ? "No API keys configured. Add keys in Settings > API Keys, or start Ollama for local inference." : "Provider chain is rate-limited. Try again in 1-2 minutes or use a more specific instruction."
365495
365550
  });
365496
365551
  }
365497
365552
  if (guardMatch) {
@@ -366599,7 +366654,8 @@ Respond naturally based on these real results only. Show the actual output, not
366599
366654
  parts.push(
366600
366655
  `Failed: ${failures.map((r) => `${r.tool} \u2014 ${r.error || "unknown error"}`).join("; ")}.`
366601
366656
  );
366602
- parts.push("(All language providers are currently unavailable \u2014 full response cannot be generated.)");
366657
+ const poolDiag = diagnoseProviderPool();
366658
+ parts.push(`(${poolDiag.state === "unconfigured" ? "No API keys configured - add keys in Settings > API Keys" : "All language providers are currently unavailable"} - full response cannot be generated.)`);
366603
366659
  onToken(parts.join(" "));
366604
366660
  return;
366605
366661
  }
@@ -390371,6 +390427,368 @@ var init_hybridSearch = __esm({
390371
390427
  }
390372
390428
  });
390373
390429
 
390430
+ // core/memoryIds.ts
390431
+ function _ensureDir() {
390432
+ fs45.mkdirSync(MEM_DIR, { recursive: true });
390433
+ }
390434
+ function _readSeq() {
390435
+ try {
390436
+ if (!fs45.existsSync(SEQUENCE_FILE)) return 0;
390437
+ const d = JSON.parse(fs45.readFileSync(SEQUENCE_FILE, "utf-8"));
390438
+ return typeof d.next === "number" ? d.next : 0;
390439
+ } catch {
390440
+ return 0;
390441
+ }
390442
+ }
390443
+ function _writeSeq(n) {
390444
+ _ensureDir();
390445
+ fs45.writeFileSync(SEQUENCE_FILE, JSON.stringify({ next: n }), "utf-8");
390446
+ }
390447
+ function nextId() {
390448
+ const n = _readSeq();
390449
+ _writeSeq(n + 1);
390450
+ return `mem_${String(n + 1).padStart(6, "0")}`;
390451
+ }
390452
+ function appendRecord(record2) {
390453
+ _ensureDir();
390454
+ fs45.appendFileSync(RECORDS_FILE, JSON.stringify(record2) + "\n", "utf-8");
390455
+ }
390456
+ function loadAllRecords() {
390457
+ try {
390458
+ if (!fs45.existsSync(RECORDS_FILE)) return [];
390459
+ return fs45.readFileSync(RECORDS_FILE, "utf-8").split("\n").filter((l2) => l2.trim()).map((l2) => {
390460
+ try {
390461
+ return JSON.parse(l2);
390462
+ } catch {
390463
+ return null;
390464
+ }
390465
+ }).filter((r) => r !== null);
390466
+ } catch {
390467
+ return [];
390468
+ }
390469
+ }
390470
+ function loadRecordById(id) {
390471
+ const all3 = loadAllRecords();
390472
+ return all3.find((r) => r.id === id) ?? null;
390473
+ }
390474
+ function removeRecords(predicate) {
390475
+ const all3 = loadAllRecords();
390476
+ const kept = all3.filter((r) => !predicate(r));
390477
+ const removed = all3.length - kept.length;
390478
+ if (removed > 0) {
390479
+ _ensureDir();
390480
+ fs45.writeFileSync(
390481
+ RECORDS_FILE,
390482
+ kept.map((r) => JSON.stringify(r)).join("\n") + (kept.length ? "\n" : ""),
390483
+ "utf-8"
390484
+ );
390485
+ }
390486
+ return removed;
390487
+ }
390488
+ function assignId(partial2) {
390489
+ const record2 = {
390490
+ id: partial2.id ?? nextId(),
390491
+ timestamp: partial2.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(),
390492
+ type: partial2.type ?? "observation",
390493
+ content: partial2.content ?? "",
390494
+ summary: partial2.summary ?? _autoSummary(partial2.content ?? ""),
390495
+ sessionId: partial2.sessionId,
390496
+ tags: partial2.tags,
390497
+ entityRefs: partial2.entityRefs
390498
+ };
390499
+ appendRecord(record2);
390500
+ return record2;
390501
+ }
390502
+ function _autoSummary(content) {
390503
+ const first = content.split("\n").find((l2) => l2.trim()) ?? content;
390504
+ return first.slice(0, 100).trim();
390505
+ }
390506
+ function runMigrationIfNeeded() {
390507
+ if (fs45.existsSync(RECORDS_FILE)) return 0;
390508
+ _ensureDir();
390509
+ const records = [];
390510
+ try {
390511
+ const raw = fs45.readFileSync(path47.join(MEM_DIR, "memory.json"), "utf-8");
390512
+ const parsed = JSON.parse(raw);
390513
+ const items = Array.isArray(parsed) ? parsed : parsed.value ?? [];
390514
+ for (const item of items) {
390515
+ const v = item.value ?? {};
390516
+ const content = [
390517
+ v.goal ? `Goal: ${v.goal}` : "",
390518
+ v.result ? `Result: ${String(v.result).slice(0, 800)}` : "",
390519
+ v.role ? `Role: ${v.role}` : ""
390520
+ ].filter(Boolean).join("\n");
390521
+ if (!content) continue;
390522
+ records.push({
390523
+ timestamp: item.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
390524
+ type: item.tags?.includes("task") ? "interaction" : "observation",
390525
+ content,
390526
+ summary: _autoSummary(v.goal ?? v.result ?? content),
390527
+ tags: item.tags ?? []
390528
+ });
390529
+ }
390530
+ } catch {
390531
+ }
390532
+ try {
390533
+ const raw = fs45.readFileSync(
390534
+ path47.join(process.cwd(), "workspace", "conversation-memory.json"),
390535
+ "utf-8"
390536
+ );
390537
+ const parsed = JSON.parse(raw);
390538
+ const msgs = parsed.messages ?? [];
390539
+ for (const msg of msgs) {
390540
+ if (msg.role !== "assistant") continue;
390541
+ const content = String(msg.content ?? "").trim();
390542
+ if (content.length < 20) continue;
390543
+ records.push({
390544
+ timestamp: msg.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(),
390545
+ type: "interaction",
390546
+ content: content.slice(0, 1e3),
390547
+ summary: _autoSummary(content),
390548
+ sessionId: msg.sessionId,
390549
+ tags: ["conversation"]
390550
+ });
390551
+ }
390552
+ } catch {
390553
+ }
390554
+ try {
390555
+ const raw = fs45.readFileSync(path47.join(MEM_DIR, "MEMORY_INDEX.md"), "utf-8");
390556
+ const lines = raw.split("\n").filter((l2) => l2.startsWith("- "));
390557
+ for (const line of lines) {
390558
+ const cleaned = line.replace(/^-\s*/, "").trim();
390559
+ if (cleaned.length < 10) continue;
390560
+ records.push({
390561
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
390562
+ type: "fact",
390563
+ content: cleaned,
390564
+ summary: cleaned.slice(0, 100),
390565
+ tags: ["index"]
390566
+ });
390567
+ }
390568
+ } catch {
390569
+ }
390570
+ records.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
390571
+ let count = 0;
390572
+ for (const rec of records) {
390573
+ const id = nextId();
390574
+ const record2 = { id, ...rec };
390575
+ appendRecord(record2);
390576
+ count++;
390577
+ }
390578
+ return count;
390579
+ }
390580
+ var fs45, path47, MEM_DIR, SEQUENCE_FILE, RECORDS_FILE;
390581
+ var init_memoryIds = __esm({
390582
+ "core/memoryIds.ts"() {
390583
+ fs45 = __toESM(require("fs"));
390584
+ path47 = __toESM(require("path"));
390585
+ MEM_DIR = path47.join(process.cwd(), "workspace", "memory");
390586
+ SEQUENCE_FILE = path47.join(MEM_DIR, "sequence.json");
390587
+ RECORDS_FILE = path47.join(MEM_DIR, "records.jsonl");
390588
+ }
390589
+ });
390590
+
390591
+ // core/slashAsTool.ts
390592
+ var slashAsTool_exports = {};
390593
+ __export(slashAsTool_exports, {
390594
+ SLASH_MIRROR_TOOL_NAMES: () => SLASH_MIRROR_TOOL_NAMES,
390595
+ registerSlashMirrorTools: () => registerSlashMirrorTools,
390596
+ toolMemoryForget: () => toolMemoryForget,
390597
+ toolMemoryStore: () => toolMemoryStore
390598
+ });
390599
+ function loadLessonsText() {
390600
+ try {
390601
+ if (import_fs40.default.existsSync(LESSONS_PATH2)) return import_fs40.default.readFileSync(LESSONS_PATH2, "utf-8").trim();
390602
+ } catch {
390603
+ }
390604
+ return "";
390605
+ }
390606
+ async function toolStatus(_2) {
390607
+ const uptimeSec = Math.floor(process.uptime());
390608
+ const ramMB = Math.round(process.memoryUsage().heapUsed / 1024 / 1024);
390609
+ const sessions = conversationMemory.getSessions().length;
390610
+ const lines = [
390611
+ "SYSTEM STATUS",
390612
+ `Uptime ${Math.floor(uptimeSec / 60)}m ${uptimeSec % 60}s`,
390613
+ `RAM ${ramMB} MB`,
390614
+ `Sessions ${sessions}`,
390615
+ `Platform ${import_os4.default.platform()} ${import_os4.default.arch()}`,
390616
+ `Node ${process.version}`
390617
+ ];
390618
+ return { success: true, output: lines.join("\n") };
390619
+ }
390620
+ async function toolAnalytics(_2) {
390621
+ const stats = learningMemory.getStats();
390622
+ const lines = [
390623
+ "LEARNING ANALYTICS",
390624
+ `Total tasks ${stats.total}`,
390625
+ `Success rate ${stats.successRate}%`,
390626
+ `Avg duration ${stats.avgDuration}ms`
390627
+ ];
390628
+ return { success: true, output: lines.join("\n") };
390629
+ }
390630
+ async function toolSpend(_2) {
390631
+ try {
390632
+ const summary = costTracker.getDailySummary();
390633
+ const byProvider = Object.entries(summary.byProvider || {}).map(([p, c]) => ` ${p}: $${c.toFixed(4)}`).join("\n");
390634
+ const lines = [
390635
+ `SPEND \u2014 ${summary.date}`,
390636
+ `Total $${summary.totalUSD.toFixed(4)}`,
390637
+ `User $${summary.userUSD.toFixed(4)}`,
390638
+ `System $${summary.systemUSD.toFixed(4)}`,
390639
+ byProvider ? `By provider:
390640
+ ${byProvider}` : ""
390641
+ ].filter(Boolean);
390642
+ return { success: true, output: lines.join("\n") };
390643
+ } catch {
390644
+ return { success: true, output: "Spend data unavailable." };
390645
+ }
390646
+ }
390647
+ async function toolMemoryShow(_2) {
390648
+ const facts = conversationMemory.getFacts();
390649
+ const history2 = conversationMemory.getRecentHistory();
390650
+ const lines = [
390651
+ "MEMORY FACTS",
390652
+ facts.lastFilesCreated.length ? `Files created : ${facts.lastFilesCreated.join(", ")}` : "",
390653
+ facts.lastSearchQueries.length ? `Last searches : ${facts.lastSearchQueries.join(", ")}` : "",
390654
+ facts.lastToolsUsed.length ? `Last tools : ${facts.lastToolsUsed.join(", ")}` : "",
390655
+ facts.mentionedEntities.length ? `Topics : ${facts.mentionedEntities.slice(-10).join(", ")}` : "",
390656
+ "",
390657
+ `Recent exchanges: ${history2.length}`,
390658
+ ...history2.slice(-3).map(
390659
+ (e) => e.userMessage ? ` User: ${e.userMessage.slice(0, 80)}` : ""
390660
+ ).filter(Boolean)
390661
+ ].filter((l2) => l2 !== void 0);
390662
+ return { success: true, output: lines.join("\n") };
390663
+ }
390664
+ async function toolLessons(_2) {
390665
+ const lessons = loadLessonsText();
390666
+ if (!lessons) return { success: true, output: "No lessons recorded yet." };
390667
+ return { success: true, output: `LESSONS (permanent failure rules):
390668
+ ${lessons}` };
390669
+ }
390670
+ async function toolSkillsList(_2) {
390671
+ const skills = skillLoader.loadAll();
390672
+ if (skills.length === 0) return { success: true, output: "No skills loaded." };
390673
+ const lines = [
390674
+ `SKILLS (${skills.length} loaded)`,
390675
+ ...skills.map((s) => ` ${s.name.padEnd(20)} ${s.description || ""}`)
390676
+ ];
390677
+ return { success: true, output: lines.join("\n") };
390678
+ }
390679
+ async function toolToolsList(_2) {
390680
+ const { TOOLS: TOOLS3 } = await Promise.resolve().then(() => (init_toolRegistry(), toolRegistry_exports));
390681
+ const names = Object.keys(TOOLS3).sort();
390682
+ return { success: true, output: `TOOLS (${names.length}):
390683
+ ${names.join(", ")}` };
390684
+ }
390685
+ async function toolWhoami(_2) {
390686
+ const cfg = loadConfig();
390687
+ const userName = cfg.userName || process.env.USERNAME || import_os4.default.userInfo().username || "User";
390688
+ const homeDir = import_os4.default.homedir();
390689
+ const lines = [
390690
+ "USER PROFILE",
390691
+ `Name ${userName}`,
390692
+ `Home ${homeDir}`,
390693
+ `Platform ${import_os4.default.platform()}`
390694
+ ];
390695
+ return { success: true, output: lines.join("\n") };
390696
+ }
390697
+ async function toolChannelsStatus(_2) {
390698
+ try {
390699
+ const cfg = loadConfig();
390700
+ const apis = cfg?.providers?.apis || [];
390701
+ const lines = [
390702
+ "PROVIDER CHANNELS",
390703
+ ...apis.map((api) => {
390704
+ const key2 = String(api.key || "");
390705
+ const hasKey = key2.startsWith("env:") ? !!(process.env[key2.replace("env:", "")] || "").trim() : key2.trim().length > 0;
390706
+ const status = !api.enabled ? "disabled" : api.rateLimited ? "rate-limited" : hasKey ? "active" : "no key";
390707
+ return ` ${(api.name || api.provider || "").padEnd(20)} ${api.model || ""} [${status}]`;
390708
+ })
390709
+ ];
390710
+ return { success: true, output: lines.join("\n") };
390711
+ } catch {
390712
+ return { success: true, output: "Provider status unavailable." };
390713
+ }
390714
+ }
390715
+ async function toolMemoryStore(input) {
390716
+ const fact = String(
390717
+ input?.fact || input?.content || input?.text || input?.preference || input?.value || input?.memory || input?.note || input?.data || input?.information || input?.detail || input?.message || input?.entry || input?.record || (input && typeof input === "object" ? Object.values(input).find((v) => typeof v === "string" && v.trim().length > 0) : "") || ""
390718
+ ).trim();
390719
+ if (!fact) return { success: false, output: 'No fact provided. Pass { fact: "the thing to remember" }' };
390720
+ const record2 = assignId({
390721
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
390722
+ type: input?.type ?? "fact",
390723
+ content: fact,
390724
+ summary: fact.slice(0, 100),
390725
+ tags: Array.isArray(input?.tags) ? input.tags : []
390726
+ });
390727
+ return { success: true, output: `Stored as ${record2.id}: ${record2.summary}` };
390728
+ }
390729
+ async function toolMemoryForget(input) {
390730
+ const keyword = String(
390731
+ input?.fact || input?.keyword || input?.content || input?.text || input?.query || input?.topic || input?.subject || (input && typeof input === "object" ? Object.values(input).find((v) => typeof v === "string" && v.trim().length > 0) : "") || ""
390732
+ ).trim().toLowerCase();
390733
+ if (!keyword)
390734
+ return { success: false, output: 'No keyword provided. Pass { fact: "thing to forget" }' };
390735
+ const removed = removeRecords(
390736
+ (r) => r.content.toLowerCase().includes(keyword) || r.summary.toLowerCase().includes(keyword)
390737
+ );
390738
+ if (removed === 0)
390739
+ return { success: true, output: `No memory entries matched "${keyword}".` };
390740
+ return { success: true, output: `Removed ${removed} memory entry(s) matching "${keyword}".` };
390741
+ }
390742
+ async function toolGoals(_2) {
390743
+ const summary = getActiveGoalsSummary();
390744
+ return { success: true, output: summary ? `ACTIVE GOALS:
390745
+ ${summary}` : "No active goals." };
390746
+ }
390747
+ function registerSlashMirrorTools() {
390748
+ const isDebug = (process.env.AIDEN_LOG_LEVEL || "info") === "debug";
390749
+ for (const { name, description, fn } of MIRROR_TOOLS) {
390750
+ registerExternalTool(name, fn, "slash-mirror");
390751
+ if (isDebug) {
390752
+ console.log("[SlashAsTool] Registered mirror tool: " + name + " \u2014 " + description);
390753
+ }
390754
+ }
390755
+ if (!isDebug) {
390756
+ console.log("[SlashAsTool] Registered " + MIRROR_TOOLS.length + " mirror tools (AIDEN_LOG_LEVEL=debug for detail)");
390757
+ }
390758
+ }
390759
+ var import_fs40, import_path42, import_os4, LESSONS_PATH2, MIRROR_TOOLS, SLASH_MIRROR_TOOL_NAMES;
390760
+ var init_slashAsTool = __esm({
390761
+ "core/slashAsTool.ts"() {
390762
+ import_fs40 = __toESM(require("fs"));
390763
+ import_path42 = __toESM(require("path"));
390764
+ import_os4 = __toESM(require("os"));
390765
+ init_toolRegistry();
390766
+ init_memoryIds();
390767
+ init_conversationMemory();
390768
+ init_learningMemory();
390769
+ init_skillLoader();
390770
+ init_costTracker();
390771
+ init_goalTracker();
390772
+ init_providers();
390773
+ LESSONS_PATH2 = import_path42.default.join(process.cwd(), "workspace", "LESSONS.md");
390774
+ MIRROR_TOOLS = [
390775
+ { name: "status", description: "Show system status: uptime, RAM, session count", fn: toolStatus },
390776
+ { name: "analytics", description: "Show learning analytics: task count, success rate", fn: toolAnalytics },
390777
+ { name: "spend", description: "Show today's token cost and spend by provider", fn: toolSpend },
390778
+ { name: "memory_show", description: "Show conversation memory facts and recent history", fn: toolMemoryShow },
390779
+ { name: "memory_store", description: 'Persist a fact or preference to permanent memory (records.jsonl) right now. Pass { fact: "..." }', fn: toolMemoryStore },
390780
+ { name: "memory_forget", description: 'Remove a fact or preference from permanent memory (records.jsonl). Pass { fact: "thing to forget" }', fn: toolMemoryForget },
390781
+ { name: "lessons", description: "Show permanent failure rules learned from past tasks", fn: toolLessons },
390782
+ { name: "skills_list", description: "List all loaded skills with descriptions", fn: toolSkillsList },
390783
+ { name: "tools_list", description: "List all registered tool names", fn: toolToolsList },
390784
+ { name: "whoami", description: "Show current user profile: name, home dir, platform", fn: toolWhoami },
390785
+ { name: "channels_status", description: "Show provider channel status: active, disabled, no-key", fn: toolChannelsStatus },
390786
+ { name: "goals", description: "Show currently active goals", fn: toolGoals }
390787
+ ];
390788
+ SLASH_MIRROR_TOOL_NAMES = MIRROR_TOOLS.map((t) => t.name);
390789
+ }
390790
+ });
390791
+
390374
390792
  // core/clarifyBus.ts
390375
390793
  var clarifyBus_exports = {};
390376
390794
  __export(clarifyBus_exports, {
@@ -390500,15 +390918,15 @@ __export(cronManager_exports, {
390500
390918
  });
390501
390919
  function save() {
390502
390920
  try {
390503
- if (!fs45.existsSync(DATA_DIR)) fs45.mkdirSync(DATA_DIR, { recursive: true });
390504
- fs45.writeFileSync(DATA_FILE, JSON.stringify(Array.from(jobs.values()), null, 2), "utf8");
390921
+ if (!fs47.existsSync(DATA_DIR)) fs47.mkdirSync(DATA_DIR, { recursive: true });
390922
+ fs47.writeFileSync(DATA_FILE, JSON.stringify(Array.from(jobs.values()), null, 2), "utf8");
390505
390923
  } catch {
390506
390924
  }
390507
390925
  }
390508
390926
  function loadJobs() {
390509
390927
  try {
390510
- if (!fs45.existsSync(DATA_FILE)) return;
390511
- const data = JSON.parse(fs45.readFileSync(DATA_FILE, "utf8"));
390928
+ if (!fs47.existsSync(DATA_FILE)) return;
390929
+ const data = JSON.parse(fs47.readFileSync(DATA_FILE, "utf8"));
390512
390930
  for (const job of data) {
390513
390931
  jobs.set(job.id, job);
390514
390932
  const num = parseInt(job.id, 10);
@@ -390626,17 +391044,17 @@ async function triggerJob(id) {
390626
391044
  return false;
390627
391045
  }
390628
391046
  }
390629
- var fs45, path47, os4, jobs, timers, jobSeq, DATA_DIR, DATA_FILE;
391047
+ var fs47, path49, os5, jobs, timers, jobSeq, DATA_DIR, DATA_FILE;
390630
391048
  var init_cronManager = __esm({
390631
391049
  "core/cronManager.ts"() {
390632
- fs45 = __toESM(require("fs"));
390633
- path47 = __toESM(require("path"));
390634
- os4 = __toESM(require("os"));
391050
+ fs47 = __toESM(require("fs"));
391051
+ path49 = __toESM(require("path"));
391052
+ os5 = __toESM(require("os"));
390635
391053
  jobs = /* @__PURE__ */ new Map();
390636
391054
  timers = /* @__PURE__ */ new Map();
390637
391055
  jobSeq = 1;
390638
- DATA_DIR = path47.join(os4.homedir(), ".aiden");
390639
- DATA_FILE = path47.join(DATA_DIR, "cron_jobs.json");
391056
+ DATA_DIR = path49.join(os5.homedir(), ".aiden");
391057
+ DATA_FILE = path49.join(DATA_DIR, "cron_jobs.json");
390640
391058
  }
390641
391059
  });
390642
391060
 
@@ -390662,10 +391080,10 @@ async function analyzeImage(imageSource, prompt = "Describe this image in detail
390662
391080
  let base64Data = "";
390663
391081
  let mediaType = "image/jpeg";
390664
391082
  if (!isUrl) {
390665
- const absPath = path48.isAbsolute(imageSource) ? imageSource : path48.resolve(process.cwd(), imageSource);
390666
- const buf = fs46.readFileSync(absPath);
391083
+ const absPath = path50.isAbsolute(imageSource) ? imageSource : path50.resolve(process.cwd(), imageSource);
391084
+ const buf = fs48.readFileSync(absPath);
390667
391085
  base64Data = buf.toString("base64");
390668
- mediaType = extToMediaType(path48.extname(absPath));
391086
+ mediaType = extToMediaType(path50.extname(absPath));
390669
391087
  }
390670
391088
  const anthropicKey = process.env.ANTHROPIC_API_KEY;
390671
391089
  if (anthropicKey) {
@@ -390745,11 +391163,11 @@ async function analyzeImage(imageSource, prompt = "Describe this image in detail
390745
391163
  throw new Error(`vision_analyze: all providers exhausted. ${e.message}`);
390746
391164
  }
390747
391165
  }
390748
- var fs46, path48;
391166
+ var fs48, path50;
390749
391167
  var init_visionAnalyze = __esm({
390750
391168
  "core/visionAnalyze.ts"() {
390751
- fs46 = __toESM(require("fs"));
390752
- path48 = __toESM(require("path"));
391169
+ fs48 = __toESM(require("fs"));
391170
+ path50 = __toESM(require("path"));
390753
391171
  init_axios2();
390754
391172
  }
390755
391173
  });
@@ -390757,9 +391175,9 @@ var init_visionAnalyze = __esm({
390757
391175
  // core/dreamEngine.ts
390758
391176
  function acquireLock() {
390759
391177
  try {
390760
- import_fs40.default.mkdirSync(import_path42.default.dirname(LOCK_FILE), { recursive: true });
390761
- if (import_fs40.default.existsSync(LOCK_FILE)) {
390762
- const raw = JSON.parse(import_fs40.default.readFileSync(LOCK_FILE, "utf-8"));
391178
+ import_fs41.default.mkdirSync(import_path43.default.dirname(LOCK_FILE), { recursive: true });
391179
+ if (import_fs41.default.existsSync(LOCK_FILE)) {
391180
+ const raw = JSON.parse(import_fs41.default.readFileSync(LOCK_FILE, "utf-8"));
390763
391181
  const alive = isPidAlive(raw.pid);
390764
391182
  if (alive) {
390765
391183
  console.log(`[DreamEngine] Lock held by PID ${raw.pid} \u2014 skipping`);
@@ -390768,7 +391186,7 @@ function acquireLock() {
390768
391186
  console.log(`[DreamEngine] Stale lock (PID ${raw.pid} dead) \u2014 stealing`);
390769
391187
  }
390770
391188
  const data = { pid: process.pid, startedAt: (/* @__PURE__ */ new Date()).toISOString() };
390771
- import_fs40.default.writeFileSync(LOCK_FILE, JSON.stringify(data));
391189
+ import_fs41.default.writeFileSync(LOCK_FILE, JSON.stringify(data));
390772
391190
  return true;
390773
391191
  } catch {
390774
391192
  return false;
@@ -390778,9 +391196,9 @@ function releaseLock(prevMtime) {
390778
391196
  try {
390779
391197
  if (prevMtime !== void 0) {
390780
391198
  const now = Date.now() / 1e3;
390781
- import_fs40.default.utimesSync(LOCK_FILE, now, now);
391199
+ import_fs41.default.utimesSync(LOCK_FILE, now, now);
390782
391200
  } else {
390783
- import_fs40.default.unlinkSync(LOCK_FILE);
391201
+ import_fs41.default.unlinkSync(LOCK_FILE);
390784
391202
  }
390785
391203
  } catch {
390786
391204
  }
@@ -390795,8 +391213,8 @@ function isPidAlive(pid) {
390795
391213
  }
390796
391214
  function getLockMtime() {
390797
391215
  try {
390798
- if (!import_fs40.default.existsSync(LOCK_FILE)) return 0;
390799
- return import_fs40.default.statSync(LOCK_FILE).mtimeMs;
391216
+ if (!import_fs41.default.existsSync(LOCK_FILE)) return 0;
391217
+ return import_fs41.default.statSync(LOCK_FILE).mtimeMs;
390800
391218
  } catch {
390801
391219
  return 0;
390802
391220
  }
@@ -390808,11 +391226,11 @@ function checkTimeGate(lockMtime) {
390808
391226
  }
390809
391227
  function checkSessionGate(lockMtime) {
390810
391228
  try {
390811
- if (!import_fs40.default.existsSync(SESSIONS_DIR3)) return false;
391229
+ if (!import_fs41.default.existsSync(SESSIONS_DIR3)) return false;
390812
391230
  const cutoff = lockMtime || 0;
390813
- const newSessions = import_fs40.default.readdirSync(SESSIONS_DIR3).filter((f) => f.endsWith(".md")).filter((f) => {
391231
+ const newSessions = import_fs41.default.readdirSync(SESSIONS_DIR3).filter((f) => f.endsWith(".md")).filter((f) => {
390814
391232
  try {
390815
- return import_fs40.default.statSync(import_path42.default.join(SESSIONS_DIR3, f)).mtimeMs > cutoff;
391233
+ return import_fs41.default.statSync(import_path43.default.join(SESSIONS_DIR3, f)).mtimeMs > cutoff;
390816
391234
  } catch {
390817
391235
  return false;
390818
391236
  }
@@ -390828,8 +391246,8 @@ function allGatesPass() {
390828
391246
  }
390829
391247
  async function phaseOrient() {
390830
391248
  try {
390831
- const indexContent = import_fs40.default.existsSync(INDEX_PATH2) ? import_fs40.default.readFileSync(INDEX_PATH2, "utf-8") : "(empty)";
390832
- const memFiles = import_fs40.default.existsSync(MEMORY_DIR3) ? import_fs40.default.readdirSync(MEMORY_DIR3).filter((f) => f.endsWith(".md") && f !== "MEMORY_INDEX.md") : [];
391249
+ const indexContent = import_fs41.default.existsSync(INDEX_PATH2) ? import_fs41.default.readFileSync(INDEX_PATH2, "utf-8") : "(empty)";
391250
+ const memFiles = import_fs41.default.existsSync(MEMORY_DIR3) ? import_fs41.default.readdirSync(MEMORY_DIR3).filter((f) => f.endsWith(".md") && f !== "MEMORY_INDEX.md") : [];
390833
391251
  return `MEMORY DIRECTORY (${memFiles.length} files):
390834
391252
  ${memFiles.join("\n")}
390835
391253
 
@@ -390841,10 +391259,10 @@ ${indexContent.slice(0, 2e3)}`;
390841
391259
  }
390842
391260
  async function phaseGather(lockMtime) {
390843
391261
  try {
390844
- if (!import_fs40.default.existsSync(SESSIONS_DIR3)) return "(no sessions)";
390845
- const recentSessions = import_fs40.default.readdirSync(SESSIONS_DIR3).filter((f) => f.endsWith(".md")).filter((f) => {
391262
+ if (!import_fs41.default.existsSync(SESSIONS_DIR3)) return "(no sessions)";
391263
+ const recentSessions = import_fs41.default.readdirSync(SESSIONS_DIR3).filter((f) => f.endsWith(".md")).filter((f) => {
390846
391264
  try {
390847
- return import_fs40.default.statSync(import_path42.default.join(SESSIONS_DIR3, f)).mtimeMs > lockMtime;
391265
+ return import_fs41.default.statSync(import_path43.default.join(SESSIONS_DIR3, f)).mtimeMs > lockMtime;
390848
391266
  } catch {
390849
391267
  return false;
390850
391268
  }
@@ -390852,7 +391270,7 @@ async function phaseGather(lockMtime) {
390852
391270
  if (recentSessions.length === 0) return "(no new sessions)";
390853
391271
  const excerpts = recentSessions.map((f) => {
390854
391272
  try {
390855
- const content = import_fs40.default.readFileSync(import_path42.default.join(SESSIONS_DIR3, f), "utf-8");
391273
+ const content = import_fs41.default.readFileSync(import_path43.default.join(SESSIONS_DIR3, f), "utf-8");
390856
391274
  return `=== ${f} ===
390857
391275
  ${content.slice(0, 800)}`;
390858
391276
  } catch {
@@ -390902,11 +391320,11 @@ Rules:
390902
391320
  const now = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
390903
391321
  for (const item of items) {
390904
391322
  if (!item.filename || !item.content) continue;
390905
- const filePath = import_path42.default.join(MEMORY_DIR3, item.filename);
391323
+ const filePath = import_path43.default.join(MEMORY_DIR3, item.filename);
390906
391324
  let created = now;
390907
- if (import_fs40.default.existsSync(filePath)) {
391325
+ if (import_fs41.default.existsSync(filePath)) {
390908
391326
  try {
390909
- const existing = import_fs40.default.readFileSync(filePath, "utf-8");
391327
+ const existing = import_fs41.default.readFileSync(filePath, "utf-8");
390910
391328
  const m2 = existing.match(/^created:\s*(.+)$/m);
390911
391329
  if (m2) created = m2[1].trim();
390912
391330
  } catch {
@@ -390922,7 +391340,7 @@ updated: ${now}
390922
391340
  ${item.content.trim()}
390923
391341
  `;
390924
391342
  try {
390925
- import_fs40.default.writeFileSync(filePath, fileContent, "utf-8");
391343
+ import_fs41.default.writeFileSync(filePath, fileContent, "utf-8");
390926
391344
  filesUpdated++;
390927
391345
  } catch {
390928
391346
  }
@@ -390935,10 +391353,10 @@ ${item.content.trim()}
390935
391353
  }
390936
391354
  async function phasePrune(filesUpdated) {
390937
391355
  try {
390938
- if (!import_fs40.default.existsSync(MEMORY_DIR3)) return;
390939
- const files = import_fs40.default.readdirSync(MEMORY_DIR3).filter((f) => f.endsWith(".md") && f !== "MEMORY_INDEX.md").map((f) => {
391356
+ if (!import_fs41.default.existsSync(MEMORY_DIR3)) return;
391357
+ const files = import_fs41.default.readdirSync(MEMORY_DIR3).filter((f) => f.endsWith(".md") && f !== "MEMORY_INDEX.md").map((f) => {
390940
391358
  try {
390941
- const content = import_fs40.default.readFileSync(import_path42.default.join(MEMORY_DIR3, f), "utf-8");
391359
+ const content = import_fs41.default.readFileSync(import_path43.default.join(MEMORY_DIR3, f), "utf-8");
390942
391360
  const titleM = content.match(/^title:\s*(.+)$/m);
390943
391361
  const sumM = content.match(/---\n+([\s\S]+?)(?:\n\n|$)/);
390944
391362
  const title = titleM ? titleM[1].trim() : f.replace(".md", "");
@@ -390948,7 +391366,7 @@ async function phasePrune(filesUpdated) {
390948
391366
  return null;
390949
391367
  }
390950
391368
  }).filter((l2) => l2 !== null).slice(0, 100);
390951
- import_fs40.default.writeFileSync(INDEX_PATH2, files.join("\n") + "\n", "utf-8");
391369
+ import_fs41.default.writeFileSync(INDEX_PATH2, files.join("\n") + "\n", "utf-8");
390952
391370
  console.log(`[DreamEngine] Pruned index to ${files.length} entries (${filesUpdated} files updated)`);
390953
391371
  } catch (e) {
390954
391372
  console.error("[DreamEngine] Prune phase failed:", e.message);
@@ -390966,7 +391384,7 @@ async function runDream() {
390966
391384
  let sessionsReviewed = 0;
390967
391385
  let filesUpdated = 0;
390968
391386
  try {
390969
- import_fs40.default.mkdirSync(MEMORY_DIR3, { recursive: true });
391387
+ import_fs41.default.mkdirSync(MEMORY_DIR3, { recursive: true });
390970
391388
  console.log("[DreamEngine] Phase 1: Orient");
390971
391389
  const orientData = await phaseOrient();
390972
391390
  console.log("[DreamEngine] Phase 2: Gather");
@@ -390996,9 +391414,9 @@ async function runDream() {
390996
391414
  try {
390997
391415
  if (prevMtime > 0) {
390998
391416
  const t = prevMtime / 1e3;
390999
- import_fs40.default.utimesSync(LOCK_FILE, t, t);
391417
+ import_fs41.default.utimesSync(LOCK_FILE, t, t);
391000
391418
  } else {
391001
- import_fs40.default.unlinkSync(LOCK_FILE);
391419
+ import_fs41.default.unlinkSync(LOCK_FILE);
391002
391420
  }
391003
391421
  } catch {
391004
391422
  }
@@ -391008,17 +391426,17 @@ function checkAndRunDream() {
391008
391426
  if (!allGatesPass()) return;
391009
391427
  runDream().catch((e) => console.error("[DreamEngine] Unhandled error:", e.message));
391010
391428
  }
391011
- var import_fs40, import_path42, LOCK_FILE, MEMORY_DIR3, SESSIONS_DIR3, INDEX_PATH2, GATE_HOURS, GATE_SESSIONS;
391429
+ var import_fs41, import_path43, LOCK_FILE, MEMORY_DIR3, SESSIONS_DIR3, INDEX_PATH2, GATE_HOURS, GATE_SESSIONS;
391012
391430
  var init_dreamEngine = __esm({
391013
391431
  "core/dreamEngine.ts"() {
391014
- import_fs40 = __toESM(require("fs"));
391015
- import_path42 = __toESM(require("path"));
391432
+ import_fs41 = __toESM(require("fs"));
391433
+ import_path43 = __toESM(require("path"));
391016
391434
  init_auxiliaryClient();
391017
391435
  init_auditTrail();
391018
- LOCK_FILE = import_path42.default.join(process.cwd(), "workspace", "dream.lock");
391019
- MEMORY_DIR3 = import_path42.default.join(process.cwd(), "workspace", "memory");
391020
- SESSIONS_DIR3 = import_path42.default.join(process.cwd(), "workspace", "sessions");
391021
- INDEX_PATH2 = import_path42.default.join(MEMORY_DIR3, "MEMORY_INDEX.md");
391436
+ LOCK_FILE = import_path43.default.join(process.cwd(), "workspace", "dream.lock");
391437
+ MEMORY_DIR3 = import_path43.default.join(process.cwd(), "workspace", "memory");
391438
+ SESSIONS_DIR3 = import_path43.default.join(process.cwd(), "workspace", "sessions");
391439
+ INDEX_PATH2 = import_path43.default.join(MEMORY_DIR3, "MEMORY_INDEX.md");
391022
391440
  GATE_HOURS = 24;
391023
391441
  GATE_SESSIONS = 5;
391024
391442
  }
@@ -391031,11 +391449,11 @@ __export(patternDetector_exports, {
391031
391449
  getPatternSummary: () => getPatternSummary
391032
391450
  });
391033
391451
  async function detectPatterns() {
391034
- if (!(0, import_fs41.existsSync)(SESSION_DIR)) return [];
391452
+ if (!(0, import_fs42.existsSync)(SESSION_DIR)) return [];
391035
391453
  const messages = [];
391036
- for (const file of (0, import_fs41.readdirSync)(SESSION_DIR).slice(-30)) {
391454
+ for (const file of (0, import_fs42.readdirSync)(SESSION_DIR).slice(-30)) {
391037
391455
  try {
391038
- const content = (0, import_fs41.readFileSync)((0, import_path43.join)(SESSION_DIR, file), "utf8");
391456
+ const content = (0, import_fs42.readFileSync)((0, import_path44.join)(SESSION_DIR, file), "utf8");
391039
391457
  if (file.endsWith(".json")) {
391040
391458
  const session = JSON.parse(content);
391041
391459
  (session.messages ?? []).filter((m2) => m2.role === "user").forEach((m2) => messages.push({
@@ -391071,12 +391489,12 @@ function getPatternSummary(patterns) {
391071
391489
  if (patterns.length === 0) return "";
391072
391490
  return "Detected usage patterns:\n" + patterns.slice(0, 3).map((p) => `- ${p.description} (${p.frequency})`).join("\n");
391073
391491
  }
391074
- var import_fs41, import_path43, SESSION_DIR;
391492
+ var import_fs42, import_path44, SESSION_DIR;
391075
391493
  var init_patternDetector = __esm({
391076
391494
  "core/patternDetector.ts"() {
391077
- import_fs41 = require("fs");
391078
- import_path43 = require("path");
391079
- SESSION_DIR = (0, import_path43.join)(process.cwd(), "workspace", "sessions");
391495
+ import_fs42 = require("fs");
391496
+ import_path44 = require("path");
391497
+ SESSION_DIR = (0, import_path44.join)(process.cwd(), "workspace", "sessions");
391080
391498
  }
391081
391499
  });
391082
391500
 
@@ -391094,8 +391512,8 @@ __export(scheduler_exports, {
391094
391512
  function loadHeartbeatConfig() {
391095
391513
  const isDebug = (process.env.AIDEN_LOG_LEVEL || "info") === "debug";
391096
391514
  try {
391097
- if (!import_fs42.default.existsSync(HEARTBEAT_PATH)) return;
391098
- const content = import_fs42.default.readFileSync(HEARTBEAT_PATH, "utf-8");
391515
+ if (!import_fs43.default.existsSync(HEARTBEAT_PATH)) return;
391516
+ const content = import_fs43.default.readFileSync(HEARTBEAT_PATH, "utf-8");
391099
391517
  const sections = content.split(/^## /m).slice(1);
391100
391518
  let loaded = 0;
391101
391519
  for (const section of sections) {
@@ -391190,8 +391608,8 @@ function cronMatchesNow(cronExpr) {
391190
391608
  }
391191
391609
  function _rsave() {
391192
391610
  try {
391193
- if (!import_fs42.default.existsSync(_RDATA_DIR)) import_fs42.default.mkdirSync(_RDATA_DIR, { recursive: true });
391194
- import_fs42.default.writeFileSync(_RDATA_FILE, JSON.stringify(Array.from(_reminders.values()), null, 2), "utf8");
391611
+ if (!import_fs43.default.existsSync(_RDATA_DIR)) import_fs43.default.mkdirSync(_RDATA_DIR, { recursive: true });
391612
+ import_fs43.default.writeFileSync(_RDATA_FILE, JSON.stringify(Array.from(_reminders.values()), null, 2), "utf8");
391195
391613
  } catch {
391196
391614
  }
391197
391615
  }
@@ -391249,11 +391667,11 @@ function cancelReminder(id) {
391249
391667
  }
391250
391668
  function initReminderScheduler() {
391251
391669
  try {
391252
- if (!import_fs42.default.existsSync(_RDATA_FILE)) {
391670
+ if (!import_fs43.default.existsSync(_RDATA_FILE)) {
391253
391671
  console.log("[Reminders] No saved reminders");
391254
391672
  return;
391255
391673
  }
391256
- const stored = JSON.parse(import_fs42.default.readFileSync(_RDATA_FILE, "utf8"));
391674
+ const stored = JSON.parse(import_fs43.default.readFileSync(_RDATA_FILE, "utf8"));
391257
391675
  const now = Date.now();
391258
391676
  let loaded = 0;
391259
391677
  for (const r of stored) {
@@ -391273,18 +391691,18 @@ function initReminderScheduler() {
391273
391691
  console.error("[Reminders] Init error:", e.message);
391274
391692
  }
391275
391693
  }
391276
- var import_fs42, import_path44, os5, TASKS_PATH, HEARTBEAT_PATH, Scheduler, scheduler, _reminders, _rtimers, _rseq, _RDATA_DIR, _RDATA_FILE;
391694
+ var import_fs43, import_path45, os6, TASKS_PATH, HEARTBEAT_PATH, Scheduler, scheduler, _reminders, _rtimers, _rseq, _RDATA_DIR, _RDATA_FILE;
391277
391695
  var init_scheduler = __esm({
391278
391696
  "core/scheduler.ts"() {
391279
- import_fs42 = __toESM(require("fs"));
391280
- import_path44 = __toESM(require("path"));
391697
+ import_fs43 = __toESM(require("fs"));
391698
+ import_path45 = __toESM(require("path"));
391281
391699
  init_morningBriefing();
391282
391700
  init_dreamEngine();
391283
391701
  init_goalTracker();
391284
391702
  init_patternDetector();
391285
- os5 = __toESM(require("os"));
391286
- TASKS_PATH = import_path44.default.join(process.cwd(), "workspace", "scheduled-tasks.json");
391287
- HEARTBEAT_PATH = import_path44.default.join(process.cwd(), "workspace", "HEARTBEAT.md");
391703
+ os6 = __toESM(require("os"));
391704
+ TASKS_PATH = import_path45.default.join(process.cwd(), "workspace", "scheduled-tasks.json");
391705
+ HEARTBEAT_PATH = import_path45.default.join(process.cwd(), "workspace", "HEARTBEAT.md");
391288
391706
  Scheduler = class _Scheduler {
391289
391707
  constructor() {
391290
391708
  this.tasks = [];
@@ -391351,8 +391769,8 @@ var init_scheduler = __esm({
391351
391769
  const ACTIVE_START = 8;
391352
391770
  const ACTIVE_END = 23;
391353
391771
  if (hour < ACTIVE_START || hour >= ACTIVE_END) return;
391354
- if (!import_fs42.default.existsSync(HEARTBEAT_PATH)) return;
391355
- const checklist = import_fs42.default.readFileSync(HEARTBEAT_PATH, "utf-8").trim();
391772
+ if (!import_fs43.default.existsSync(HEARTBEAT_PATH)) return;
391773
+ const checklist = import_fs43.default.readFileSync(HEARTBEAT_PATH, "utf-8").trim();
391356
391774
  if (!checklist) return;
391357
391775
  let heartbeatPrompt = checklist;
391358
391776
  const goalsSummary = getActiveGoalsSummary();
@@ -391493,8 +391911,8 @@ var init_scheduler = __esm({
391493
391911
  }
391494
391912
  load() {
391495
391913
  try {
391496
- if (!import_fs42.default.existsSync(TASKS_PATH)) return;
391497
- const raw = import_fs42.default.readFileSync(TASKS_PATH, "utf-8");
391914
+ if (!import_fs43.default.existsSync(TASKS_PATH)) return;
391915
+ const raw = import_fs43.default.readFileSync(TASKS_PATH, "utf-8");
391498
391916
  this.tasks = JSON.parse(raw);
391499
391917
  const enabled = this.tasks.filter((t) => t.enabled);
391500
391918
  enabled.forEach((t) => this.scheduleTask(t));
@@ -391508,8 +391926,8 @@ var init_scheduler = __esm({
391508
391926
  }
391509
391927
  save() {
391510
391928
  try {
391511
- import_fs42.default.mkdirSync(import_path44.default.dirname(TASKS_PATH), { recursive: true });
391512
- import_fs42.default.writeFileSync(TASKS_PATH, JSON.stringify(this.tasks, null, 2));
391929
+ import_fs43.default.mkdirSync(import_path45.default.dirname(TASKS_PATH), { recursive: true });
391930
+ import_fs43.default.writeFileSync(TASKS_PATH, JSON.stringify(this.tasks, null, 2));
391513
391931
  } catch (e) {
391514
391932
  console.warn(`[Scheduler] Failed to save tasks: ${e.message}`);
391515
391933
  }
@@ -391519,8 +391937,8 @@ var init_scheduler = __esm({
391519
391937
  _reminders = /* @__PURE__ */ new Map();
391520
391938
  _rtimers = /* @__PURE__ */ new Map();
391521
391939
  _rseq = 1;
391522
- _RDATA_DIR = import_path44.default.join(os5.homedir(), ".aiden");
391523
- _RDATA_FILE = import_path44.default.join(_RDATA_DIR, "scheduled.json");
391940
+ _RDATA_DIR = import_path45.default.join(os6.homedir(), ".aiden");
391941
+ _RDATA_FILE = import_path45.default.join(_RDATA_DIR, "scheduled.json");
391524
391942
  }
391525
391943
  });
391526
391944
 
@@ -391601,15 +392019,15 @@ function isCommandAllowed(cmd) {
391601
392019
  return { allowed: false, needsApproval: true };
391602
392020
  }
391603
392021
  function cleanOldBrowserProfiles() {
391604
- if (!import_fs43.default.existsSync(BROWSER_DATA_DIR)) return;
392022
+ if (!import_fs44.default.existsSync(BROWSER_DATA_DIR)) return;
391605
392023
  const cutoff = Date.now() - 24 * 60 * 60 * 1e3;
391606
392024
  try {
391607
- for (const entry of import_fs43.default.readdirSync(BROWSER_DATA_DIR)) {
391608
- const fullPath = import_path45.default.join(BROWSER_DATA_DIR, entry);
392025
+ for (const entry of import_fs44.default.readdirSync(BROWSER_DATA_DIR)) {
392026
+ const fullPath = import_path46.default.join(BROWSER_DATA_DIR, entry);
391609
392027
  try {
391610
- const stat = import_fs43.default.statSync(fullPath);
392028
+ const stat = import_fs44.default.statSync(fullPath);
391611
392029
  if (stat.mtimeMs < cutoff) {
391612
- import_fs43.default.rmSync(fullPath, { recursive: true, force: true });
392030
+ import_fs44.default.rmSync(fullPath, { recursive: true, force: true });
391613
392031
  console.log(`[Browser] Cleaned old profile: ${entry}`);
391614
392032
  }
391615
392033
  } catch {
@@ -391639,15 +392057,15 @@ function setProgressEmitter(fn) {
391639
392057
  _emitProgress = fn;
391640
392058
  }
391641
392059
  function resolveWritePath(rawPath, opts) {
391642
- const home = opts?.home ?? import_os4.default.homedir();
392060
+ const home = opts?.home ?? import_os5.default.homedir();
391643
392061
  const cwd = opts?.cwd ?? process.cwd();
391644
- const user = process.env.USERNAME || process.env.USER || import_os4.default.userInfo().username || "User";
391645
- let p = rawPath.replace(/^~[\/\\]/, home + import_path45.default.sep).replace(/^Desktop[\/\\]/i, import_path45.default.join(home, "Desktop") + import_path45.default.sep).replace(/^C:\\Users\\Aiden\\/i, `C:\\Users\\${user}\\`).replace(/^C:\/Users\/Aiden\//i, `C:/Users/${user}/`);
391646
- const resolved = /^[A-Za-z]:[/\\]/.test(p) || p.startsWith("/") ? p : import_path45.default.join(cwd, p);
392062
+ const user = process.env.USERNAME || process.env.USER || import_os5.default.userInfo().username || "User";
392063
+ let p = rawPath.replace(/^~[\/\\]/, home + import_path46.default.sep).replace(/^Desktop[\/\\]/i, import_path46.default.join(home, "Desktop") + import_path46.default.sep).replace(/^C:\\Users\\Aiden\\/i, `C:\\Users\\${user}\\`).replace(/^C:\/Users\/Aiden\//i, `C:/Users/${user}/`);
392064
+ const resolved = /^[A-Za-z]:[/\\]/.test(p) || p.startsWith("/") ? p : import_path46.default.join(cwd, p);
391647
392065
  const allowedRoots = [
391648
392066
  cwd,
391649
- import_path45.default.join(home, "Desktop"),
391650
- import_path45.default.join(home, "Documents")
392067
+ import_path46.default.join(home, "Desktop"),
392068
+ import_path46.default.join(home, "Documents")
391651
392069
  ];
391652
392070
  const norm = (s) => s.toLowerCase().replace(/\//g, "\\").replace(/\\$/, "");
391653
392071
  const nr = norm(resolved);
@@ -391882,14 +392300,14 @@ function getToolsForCategories(categories) {
391882
392300
  }
391883
392301
  return Array.from(tools);
391884
392302
  }
391885
- var import_child_process13, import_util10, import_fs43, import_path45, import_os4, import_minimatch2, execAsync8, PROTECTED_FILES2, DENIED_PATHS, DENIED_COMMANDS, activeWatchers, SHELL_DANGEROUS_PATTERNS, PROTECTED_PATH_PATTERNS, CODE_DESTRUCTIVE_NODE, CODE_DESTRUCTIVE_PYTHON, SHELL_ALLOWLIST, BROWSER_DATA_DIR, TOOL_TIMEOUTS, _emitProgress, APP_ALIASES, DISPLAY_ALIASES, TOOLS, externalTools, externalToolsMeta, _generation, TOOL_DESCRIPTIONS, TOOL_NAMES_ONLY, TOOL_TIERS, TOOL_CATEGORIES, TOOL_REGISTRY, registryNames, registryDescriptions, registryTiers, registryCategories, registryTimeouts, registryAllowedTools, registryValidTools, registryNoRetrySet, registryParallelSafeSet, registrySequentialOnlySet, registryMcpSafeList, registryMcpDestructiveList;
392303
+ var import_child_process13, import_util10, import_fs44, import_path46, import_os5, import_minimatch2, execAsync8, PROTECTED_FILES2, DENIED_PATHS, DENIED_COMMANDS, activeWatchers, SHELL_DANGEROUS_PATTERNS, PROTECTED_PATH_PATTERNS, CODE_DESTRUCTIVE_NODE, CODE_DESTRUCTIVE_PYTHON, SHELL_ALLOWLIST, BROWSER_DATA_DIR, TOOL_TIMEOUTS, _emitProgress, APP_ALIASES, DISPLAY_ALIASES, TOOLS, externalTools, externalToolsMeta, _generation, TOOL_DESCRIPTIONS, TOOL_NAMES_ONLY, TOOL_TIERS, TOOL_CATEGORIES, TOOL_REGISTRY, registryNames, registryDescriptions, registryTiers, registryCategories, registryTimeouts, registryAllowedTools, registryValidTools, registryNoRetrySet, registryParallelSafeSet, registrySequentialOnlySet, registryMcpSafeList, registryMcpDestructiveList;
391886
392304
  var init_toolRegistry = __esm({
391887
392305
  "core/toolRegistry.ts"() {
391888
392306
  import_child_process13 = require("child_process");
391889
392307
  import_util10 = require("util");
391890
- import_fs43 = __toESM(require("fs"));
391891
- import_path45 = __toESM(require("path"));
391892
- import_os4 = __toESM(require("os"));
392308
+ import_fs44 = __toESM(require("fs"));
392309
+ import_path46 = __toESM(require("path"));
392310
+ import_os5 = __toESM(require("os"));
391893
392311
  init_paths();
391894
392312
  init_computerControl();
391895
392313
  init_webSearch();
@@ -392061,7 +392479,7 @@ var init_toolRegistry = __esm({
392061
392479
  // 16. Windows window management
392062
392480
  /^(start|explorer)\b/i
392063
392481
  ];
392064
- BROWSER_DATA_DIR = import_path45.default.join(getUserDataDir(), "browser-profiles");
392482
+ BROWSER_DATA_DIR = import_path46.default.join(getUserDataDir(), "browser-profiles");
392065
392483
  try {
392066
392484
  cleanOldBrowserProfiles();
392067
392485
  } catch {
@@ -392404,9 +392822,9 @@ stderr: ${sr.stderr}` : "")).trim() || "(completed)";
392404
392822
  return { success: false, output: "", error: "Blocked: this command pattern is not allowed. Dangerous operations require explicit user approval." };
392405
392823
  }
392406
392824
  }
392407
- const tmpFile = import_path45.default.join(process.cwd(), "workspace", `tmp_${Date.now()}.ps1`);
392408
- import_fs43.default.mkdirSync(import_path45.default.dirname(tmpFile), { recursive: true });
392409
- import_fs43.default.writeFileSync(tmpFile, script2);
392825
+ const tmpFile = import_path46.default.join(process.cwd(), "workspace", `tmp_${Date.now()}.ps1`);
392826
+ import_fs44.default.mkdirSync(import_path46.default.dirname(tmpFile), { recursive: true });
392827
+ import_fs44.default.writeFileSync(tmpFile, script2);
392410
392828
  try {
392411
392829
  const { stdout, stderr } = await execAsync8(
392412
392830
  `powershell.exe -ExecutionPolicy Bypass -File "${tmpFile}"`,
@@ -392417,7 +392835,7 @@ stderr: ${sr.stderr}` : "")).trim() || "(completed)";
392417
392835
  return { success: false, output: "", error: e.message };
392418
392836
  } finally {
392419
392837
  try {
392420
- import_fs43.default.unlinkSync(tmpFile);
392838
+ import_fs44.default.unlinkSync(tmpFile);
392421
392839
  } catch {
392422
392840
  }
392423
392841
  }
@@ -392521,9 +392939,9 @@ stderr: ${sr.stderr}` : "")).trim() || "(completed)";
392521
392939
  }
392522
392940
  try {
392523
392941
  const resolved = resolveWritePath(filePath);
392524
- import_fs43.default.mkdirSync(import_path45.default.dirname(resolved), { recursive: true });
392525
- import_fs43.default.writeFileSync(resolved, content, "utf-8");
392526
- const written = import_fs43.default.existsSync(resolved);
392942
+ import_fs44.default.mkdirSync(import_path46.default.dirname(resolved), { recursive: true });
392943
+ import_fs44.default.writeFileSync(resolved, content, "utf-8");
392944
+ const written = import_fs44.default.existsSync(resolved);
392527
392945
  return {
392528
392946
  success: written,
392529
392947
  output: written ? `Written and verified: ${resolved} (${content.length} chars)` : "Write failed"
@@ -392547,10 +392965,10 @@ stderr: ${sr.stderr}` : "")).trim() || "(completed)";
392547
392965
  try {
392548
392966
  const _user = process.env.USERNAME || process.env.USER || require("os").userInfo().username || "User";
392549
392967
  const _home = require("os").homedir();
392550
- filePath = filePath.replace(/^~[\/\\]/i, _home + import_path45.default.sep).replace(/^Desktop[\/\\]/i, import_path45.default.join(_home, "Desktop") + import_path45.default.sep).replace(/^C:\\Users\\Aiden\\/i, `C:\\Users\\${_user}\\`).replace(/^C:\/Users\/Aiden\//i, `C:/Users/${_user}/`);
392551
- const resolved = filePath.match(/^[A-Z]:/i) || filePath.startsWith("/") ? filePath : import_path45.default.join(process.cwd(), filePath);
392552
- if (!import_fs43.default.existsSync(resolved)) return { success: false, output: "", error: `Not found: ${resolved}` };
392553
- return { success: true, output: import_fs43.default.readFileSync(resolved, "utf-8").slice(0, 5e3) };
392968
+ filePath = filePath.replace(/^~[\/\\]/i, _home + import_path46.default.sep).replace(/^Desktop[\/\\]/i, import_path46.default.join(_home, "Desktop") + import_path46.default.sep).replace(/^C:\\Users\\Aiden\\/i, `C:\\Users\\${_user}\\`).replace(/^C:\/Users\/Aiden\//i, `C:/Users/${_user}/`);
392969
+ const resolved = filePath.match(/^[A-Z]:/i) || filePath.startsWith("/") ? filePath : import_path46.default.join(process.cwd(), filePath);
392970
+ if (!import_fs44.default.existsSync(resolved)) return { success: false, output: "", error: `Not found: ${resolved}` };
392971
+ return { success: true, output: import_fs44.default.readFileSync(resolved, "utf-8").slice(0, 5e3) };
392554
392972
  } catch (e) {
392555
392973
  return { success: false, output: "", error: e.message };
392556
392974
  }
@@ -392560,9 +392978,9 @@ stderr: ${sr.stderr}` : "")).trim() || "(completed)";
392560
392978
  try {
392561
392979
  const _user = process.env.USERNAME || process.env.USER || require("os").userInfo().username || "User";
392562
392980
  const _home = require("os").homedir();
392563
- dirPath = dirPath.replace(/^~[\/\\]/i, _home + import_path45.default.sep).replace(/^Desktop[\/\\]?$/i, import_path45.default.join(_home, "Desktop")).replace(/^Desktop[\/\\]/i, import_path45.default.join(_home, "Desktop") + import_path45.default.sep).replace(/^C:\\Users\\Aiden\\/i, `C:\\Users\\${_user}\\`).replace(/^C:\/Users\/Aiden\//i, `C:/Users/${_user}/`);
392564
- const resolved = dirPath.match(/^[A-Z]:/i) ? dirPath : import_path45.default.join(process.cwd(), dirPath);
392565
- return { success: true, output: import_fs43.default.readdirSync(resolved).join("\n") };
392981
+ dirPath = dirPath.replace(/^~[\/\\]/i, _home + import_path46.default.sep).replace(/^Desktop[\/\\]?$/i, import_path46.default.join(_home, "Desktop")).replace(/^Desktop[\/\\]/i, import_path46.default.join(_home, "Desktop") + import_path46.default.sep).replace(/^C:\\Users\\Aiden\\/i, `C:\\Users\\${_user}\\`).replace(/^C:\/Users\/Aiden\//i, `C:/Users/${_user}/`);
392982
+ const resolved = dirPath.match(/^[A-Z]:/i) ? dirPath : import_path46.default.join(process.cwd(), dirPath);
392983
+ return { success: true, output: import_fs44.default.readdirSync(resolved).join("\n") };
392566
392984
  } catch (e) {
392567
392985
  return { success: false, output: "", error: e.message };
392568
392986
  }
@@ -392584,9 +393002,9 @@ stderr: ${sr.stderr}` : "")).trim() || "Script completed with no output";
392584
393002
  console.warn("[Sandbox] auto-mode fell back to host:", sandboxErr.message);
392585
393003
  }
392586
393004
  }
392587
- const tmp = import_path45.default.join(process.cwd(), "workspace", `py_${Date.now()}.py`);
392588
- import_fs43.default.mkdirSync(import_path45.default.dirname(tmp), { recursive: true });
392589
- import_fs43.default.writeFileSync(tmp, script2);
393005
+ const tmp = import_path46.default.join(process.cwd(), "workspace", `py_${Date.now()}.py`);
393006
+ import_fs44.default.mkdirSync(import_path46.default.dirname(tmp), { recursive: true });
393007
+ import_fs44.default.writeFileSync(tmp, script2);
392590
393008
  const showProgress = process.env.AIDEN_SHOW_TOOL_OUTPUT !== "false";
392591
393009
  return new Promise((resolve8) => {
392592
393010
  let stdout = "";
@@ -392612,7 +393030,7 @@ stderr: ${sr.stderr}` : "")).trim() || "Script completed with no output";
392612
393030
  proc.on("close", (code) => {
392613
393031
  clearTimeout(timer);
392614
393032
  try {
392615
- import_fs43.default.unlinkSync(tmp);
393033
+ import_fs44.default.unlinkSync(tmp);
392616
393034
  } catch {
392617
393035
  }
392618
393036
  const output = (stdout || stderr || "").trim() || "Script completed with no output";
@@ -392625,9 +393043,9 @@ stderr: ${sr.stderr}` : "")).trim() || "Script completed with no output";
392625
393043
  if (!script2) return { success: false, output: "", error: "No script" };
392626
393044
  const nodeGuard = scanCodeForDestructivePaths(script2, "node");
392627
393045
  if (nodeGuard.denied) return { success: false, output: "", error: nodeGuard.reason };
392628
- const tmp = import_path45.default.join(process.cwd(), "workspace", `js_${Date.now()}.js`);
392629
- import_fs43.default.mkdirSync(import_path45.default.dirname(tmp), { recursive: true });
392630
- import_fs43.default.writeFileSync(tmp, script2);
393046
+ const tmp = import_path46.default.join(process.cwd(), "workspace", `js_${Date.now()}.js`);
393047
+ import_fs44.default.mkdirSync(import_path46.default.dirname(tmp), { recursive: true });
393048
+ import_fs44.default.writeFileSync(tmp, script2);
392631
393049
  try {
392632
393050
  const { stdout, stderr } = await execAsync8(`node "${tmp}"`, {
392633
393051
  timeout: 6e4,
@@ -392638,7 +393056,7 @@ stderr: ${sr.stderr}` : "")).trim() || "Script completed with no output";
392638
393056
  return { success: false, output: e.stdout || "", error: `Node error: ${e.message}` };
392639
393057
  } finally {
392640
393058
  try {
392641
- import_fs43.default.unlinkSync(tmp);
393059
+ import_fs44.default.unlinkSync(tmp);
392642
393060
  } catch {
392643
393061
  }
392644
393062
  }
@@ -393455,7 +393873,7 @@ public class AidenVolSet {
393455
393873
  const stop = !!p.stop;
393456
393874
  if (!rawFolder) return { success: false, output: "", error: "No folder specified" };
393457
393875
  const userName = process.env.USERPROFILE || process.env.HOME || "";
393458
- const folderPath = rawFolder.replace(/%USERPROFILE%/gi, userName).replace(/^~[\/\\]/, userName + import_path45.default.sep);
393876
+ const folderPath = rawFolder.replace(/%USERPROFILE%/gi, userName).replace(/^~[\/\\]/, userName + import_path46.default.sep);
393459
393877
  if (stop) {
393460
393878
  const watcher2 = activeWatchers.get(folderPath);
393461
393879
  if (watcher2) {
@@ -393466,20 +393884,20 @@ public class AidenVolSet {
393466
393884
  return { success: false, output: `No active watcher for: ${folderPath}` };
393467
393885
  }
393468
393886
  if (!goal) return { success: false, output: "", error: "No goal specified" };
393469
- if (!import_fs43.default.existsSync(folderPath)) return { success: false, output: "", error: `Folder not found: ${folderPath}` };
393887
+ if (!import_fs44.default.existsSync(folderPath)) return { success: false, output: "", error: `Folder not found: ${folderPath}` };
393470
393888
  const existing = activeWatchers.get(folderPath);
393471
393889
  if (existing) {
393472
393890
  existing.close();
393473
393891
  activeWatchers.delete(folderPath);
393474
393892
  }
393475
- const watcher = import_fs43.default.watch(folderPath, async (eventType, filename) => {
393893
+ const watcher = import_fs44.default.watch(folderPath, async (eventType, filename) => {
393476
393894
  if (eventType !== "rename" || !filename) return;
393477
- const fullPath = import_path45.default.join(folderPath, filename);
393895
+ const fullPath = import_path46.default.join(folderPath, filename);
393478
393896
  await new Promise((r) => setTimeout(r, 500));
393479
- if (!import_fs43.default.existsSync(fullPath)) return;
393897
+ if (!import_fs44.default.existsSync(fullPath)) return;
393480
393898
  let isFile2 = false;
393481
393899
  try {
393482
- isFile2 = import_fs43.default.statSync(fullPath).isFile();
393900
+ isFile2 = import_fs44.default.statSync(fullPath).isFile();
393483
393901
  } catch {
393484
393902
  return;
393485
393903
  }
@@ -393750,28 +394168,28 @@ ${formatted}` };
393750
394168
  });
393751
394169
  return 2 * n / (sa.size + sb.size + 1e-3);
393752
394170
  };
393753
- const skillFolders = ["learned", "approved", "installed"].map((f) => import_path45.default.join(cwd, "workspace", "skills", f)).filter((d) => import_fs43.default.existsSync(d));
394171
+ const skillFolders = ["learned", "approved", "installed"].map((f) => import_path46.default.join(cwd, "workspace", "skills", f)).filter((d) => import_fs44.default.existsSync(d));
393754
394172
  if (skillFolders.length === 0) return { success: false, output: "", error: "No skills yet" };
393755
394173
  let best = { score: 0, dir: "", name: "" };
393756
394174
  for (const folder of skillFolders) {
393757
- for (const entry of import_fs43.default.readdirSync(folder, { withFileTypes: true })) {
394175
+ for (const entry of import_fs44.default.readdirSync(folder, { withFileTypes: true })) {
393758
394176
  if (!entry.isDirectory()) continue;
393759
- const metaPath2 = import_path45.default.join(folder, entry.name, "meta.json");
394177
+ const metaPath2 = import_path46.default.join(folder, entry.name, "meta.json");
393760
394178
  let taskPattern = entry.name;
393761
394179
  try {
393762
- const meta = JSON.parse(import_fs43.default.readFileSync(metaPath2, "utf-8"));
394180
+ const meta = JSON.parse(import_fs44.default.readFileSync(metaPath2, "utf-8"));
393763
394181
  taskPattern = meta.taskPattern || meta.description || entry.name;
393764
394182
  } catch {
393765
394183
  }
393766
394184
  const score = Math.max(dice(query, entry.name), dice(query, taskPattern));
393767
- if (score > best.score) best = { score, dir: import_path45.default.join(folder, entry.name), name: entry.name };
394185
+ if (score > best.score) best = { score, dir: import_path46.default.join(folder, entry.name), name: entry.name };
393768
394186
  }
393769
394187
  }
393770
394188
  const THRESHOLD = 0.25;
393771
394189
  if (best.score < THRESHOLD) return { success: false, output: "", error: `No matching skill found (best: ${best.name} @ ${best.score.toFixed(2)})` };
393772
- const skillPath = import_path45.default.join(best.dir, "SKILL.md");
393773
- if (!import_fs43.default.existsSync(skillPath)) return { success: false, output: "", error: `Skill "${best.name}" has no SKILL.md` };
393774
- const content = import_fs43.default.readFileSync(skillPath, "utf-8");
394190
+ const skillPath = import_path46.default.join(best.dir, "SKILL.md");
394191
+ if (!import_fs44.default.existsSync(skillPath)) return { success: false, output: "", error: `Skill "${best.name}" has no SKILL.md` };
394192
+ const content = import_fs44.default.readFileSync(skillPath, "utf-8");
393775
394193
  return { success: true, output: `[Skill: ${best.name} \u2014 match score ${best.score.toFixed(2)}]
393776
394194
 
393777
394195
  ${content}` };
@@ -393878,6 +394296,20 @@ ${content}` };
393878
394296
  return { success: false, output: "", error: e.message };
393879
394297
  }
393880
394298
  },
394299
+ // ── memory_store — persist a fact to permanent memory ──
394300
+ memory_store: async (p) => {
394301
+ const fact = p.fact || p.text || p.content || "";
394302
+ if (!fact) return { success: false, output: "", error: "No fact provided" };
394303
+ const { toolMemoryStore: toolMemoryStore2 } = await Promise.resolve().then(() => (init_slashAsTool(), slashAsTool_exports));
394304
+ return toolMemoryStore2(p);
394305
+ },
394306
+ // ── memory_forget — remove a fact from permanent memory ──
394307
+ memory_forget: async (p) => {
394308
+ const fact = p.fact || p.keyword || p.text || "";
394309
+ if (!fact) return { success: false, output: "", error: "No fact provided" };
394310
+ const { toolMemoryForget: toolMemoryForget2 } = await Promise.resolve().then(() => (init_slashAsTool(), slashAsTool_exports));
394311
+ return toolMemoryForget2(p);
394312
+ },
393881
394313
  // ── clarify — ask the user a multi-choice or free-text question mid-task ──
393882
394314
  clarify: async (p) => {
393883
394315
  const question = p.question || p.q || "";
@@ -402514,12 +402946,12 @@ function buildFrontmatter(meta) {
402514
402946
  async function writeSkillDraft(draft, targetDir) {
402515
402947
  const cwd = process.cwd();
402516
402948
  const id = sanitizeSkillId(draft.name);
402517
- const baseDir = targetDir === "installed" ? import_path52.default.join(cwd, "skills", "installed") : import_path52.default.join(cwd, "skills", "learned", "pending");
402518
- const dir = import_path52.default.join(baseDir, id);
402519
- if (import_fs50.default.existsSync(dir)) {
402949
+ const baseDir = targetDir === "installed" ? import_path53.default.join(cwd, "skills", "installed") : import_path53.default.join(cwd, "skills", "learned", "pending");
402950
+ const dir = import_path53.default.join(baseDir, id);
402951
+ if (import_fs51.default.existsSync(dir)) {
402520
402952
  throw new Error(`Skill "${id}" already exists at ${dir}. Use a different name or delete the existing draft.`);
402521
402953
  }
402522
- import_fs50.default.mkdirSync(dir, { recursive: true });
402954
+ import_fs51.default.mkdirSync(dir, { recursive: true });
402523
402955
  const frontmatter = buildFrontmatter({
402524
402956
  name: draft.name,
402525
402957
  description: draft.description,
@@ -402539,8 +402971,8 @@ async function writeSkillDraft(draft, targetDir) {
402539
402971
 
402540
402972
  ${header}${body}
402541
402973
  `;
402542
- const filePath = import_path52.default.join(dir, "SKILL.md");
402543
- import_fs50.default.writeFileSync(filePath, fileContent, "utf-8");
402974
+ const filePath = import_path53.default.join(dir, "SKILL.md");
402975
+ import_fs51.default.writeFileSync(filePath, fileContent, "utf-8");
402544
402976
  const meta = {
402545
402977
  id,
402546
402978
  name: draft.name,
@@ -402550,7 +402982,7 @@ ${header}${body}
402550
402982
  createdAt: timestamp2,
402551
402983
  enabled: false
402552
402984
  };
402553
- import_fs50.default.writeFileSync(import_path52.default.join(dir, "meta.json"), JSON.stringify(meta, null, 2) + "\n", "utf-8");
402985
+ import_fs51.default.writeFileSync(import_path53.default.join(dir, "meta.json"), JSON.stringify(meta, null, 2) + "\n", "utf-8");
402554
402986
  const toolCalls = draft.sourceDetails?.toolCalls ?? [];
402555
402987
  const toolNames = Array.isArray(toolCalls) ? toolCalls.map((t) => t.tool ?? t).filter(Boolean) : [];
402556
402988
  const skillJson = {
@@ -402566,54 +402998,54 @@ ${header}${body}
402566
402998
  tags: draft.tags?.length ? draft.tags : inferTags(toolNames, draft.content),
402567
402999
  created: timestamp2
402568
403000
  };
402569
- import_fs50.default.writeFileSync(import_path52.default.join(dir, "skill.json"), JSON.stringify(skillJson, null, 2) + "\n", "utf-8");
403001
+ import_fs51.default.writeFileSync(import_path53.default.join(dir, "skill.json"), JSON.stringify(skillJson, null, 2) + "\n", "utf-8");
402570
403002
  return { id, filePath, dir };
402571
403003
  }
402572
403004
  function approveDraft(id) {
402573
403005
  const cwd = process.cwd();
402574
- const pendDir = import_path52.default.join(cwd, "skills", "learned", "pending", id);
402575
- const approDir = import_path52.default.join(cwd, "skills", "learned", "approved", id);
402576
- if (!import_fs50.default.existsSync(pendDir)) throw new Error(`Pending skill "${id}" not found`);
402577
- if (import_fs50.default.existsSync(approDir)) throw new Error(`Approved skill "${id}" already exists`);
402578
- const skillFile = import_path52.default.join(pendDir, "SKILL.md");
402579
- if (import_fs50.default.existsSync(skillFile)) {
402580
- let content = import_fs50.default.readFileSync(skillFile, "utf-8");
403006
+ const pendDir = import_path53.default.join(cwd, "skills", "learned", "pending", id);
403007
+ const approDir = import_path53.default.join(cwd, "skills", "learned", "approved", id);
403008
+ if (!import_fs51.default.existsSync(pendDir)) throw new Error(`Pending skill "${id}" not found`);
403009
+ if (import_fs51.default.existsSync(approDir)) throw new Error(`Approved skill "${id}" already exists`);
403010
+ const skillFile = import_path53.default.join(pendDir, "SKILL.md");
403011
+ if (import_fs51.default.existsSync(skillFile)) {
403012
+ let content = import_fs51.default.readFileSync(skillFile, "utf-8");
402581
403013
  content = content.replace(/^enabled:\s*false/m, "enabled: true");
402582
- import_fs50.default.writeFileSync(skillFile, content, "utf-8");
403014
+ import_fs51.default.writeFileSync(skillFile, content, "utf-8");
402583
403015
  }
402584
- import_fs50.default.mkdirSync(import_path52.default.join(cwd, "skills", "learned", "approved"), { recursive: true });
402585
- import_fs50.default.renameSync(pendDir, approDir);
403016
+ import_fs51.default.mkdirSync(import_path53.default.join(cwd, "skills", "learned", "approved"), { recursive: true });
403017
+ import_fs51.default.renameSync(pendDir, approDir);
402586
403018
  return approDir;
402587
403019
  }
402588
403020
  function rejectDraft(id) {
402589
403021
  const cwd = process.cwd();
402590
- const pendDir = import_path52.default.join(cwd, "skills", "learned", "pending", id);
402591
- if (!import_fs50.default.existsSync(pendDir)) throw new Error(`Pending skill "${id}" not found`);
403022
+ const pendDir = import_path53.default.join(cwd, "skills", "learned", "pending", id);
403023
+ if (!import_fs51.default.existsSync(pendDir)) throw new Error(`Pending skill "${id}" not found`);
402592
403024
  let meta = { id };
402593
403025
  try {
402594
- meta = JSON.parse(import_fs50.default.readFileSync(import_path52.default.join(pendDir, "meta.json"), "utf-8"));
403026
+ meta = JSON.parse(import_fs51.default.readFileSync(import_path53.default.join(pendDir, "meta.json"), "utf-8"));
402595
403027
  } catch {
402596
403028
  }
402597
- import_fs50.default.rmSync(pendDir, { recursive: true, force: true });
402598
- const rejLog = import_path52.default.join(cwd, "skills", "learned", ".rejected.json");
403029
+ import_fs51.default.rmSync(pendDir, { recursive: true, force: true });
403030
+ const rejLog = import_path53.default.join(cwd, "skills", "learned", ".rejected.json");
402599
403031
  let log = [];
402600
403032
  try {
402601
- log = JSON.parse(import_fs50.default.readFileSync(rejLog, "utf-8"));
403033
+ log = JSON.parse(import_fs51.default.readFileSync(rejLog, "utf-8"));
402602
403034
  } catch {
402603
403035
  }
402604
403036
  log.push({ ...meta, rejectedAt: (/* @__PURE__ */ new Date()).toISOString() });
402605
- import_fs50.default.writeFileSync(rejLog, JSON.stringify(log, null, 2) + "\n", "utf-8");
403037
+ import_fs51.default.writeFileSync(rejLog, JSON.stringify(log, null, 2) + "\n", "utf-8");
402606
403038
  }
402607
403039
  function setSkillEnabled(filePath, enabled) {
402608
- if (!import_fs50.default.existsSync(filePath)) throw new Error(`Skill file not found: ${filePath}`);
402609
- let content = import_fs50.default.readFileSync(filePath, "utf-8");
403040
+ if (!import_fs51.default.existsSync(filePath)) throw new Error(`Skill file not found: ${filePath}`);
403041
+ let content = import_fs51.default.readFileSync(filePath, "utf-8");
402610
403042
  if (/^enabled:/m.test(content)) {
402611
403043
  content = content.replace(/^enabled:\s*(true|false)/m, `enabled: ${enabled}`);
402612
403044
  } else {
402613
403045
  content = content.replace(/^(version:.+)$/m, `$1
402614
403046
  enabled: ${enabled}`);
402615
403047
  }
402616
- import_fs50.default.writeFileSync(filePath, content, "utf-8");
403048
+ import_fs51.default.writeFileSync(filePath, content, "utf-8");
402617
403049
  }
402618
403050
  function tokenSimilarity(a, b) {
402619
403051
  const tok = (s) => new Set(
@@ -402639,22 +403071,22 @@ async function writeSkillFromTask(args) {
402639
403071
  if (!success || toolsUsed.length < 2) return null;
402640
403072
  try {
402641
403073
  const cwd = process.cwd();
402642
- const learnedDir = import_path52.default.join(cwd, "workspace", "skills", "learned");
402643
- import_fs50.default.mkdirSync(learnedDir, { recursive: true });
403074
+ const learnedDir = import_path53.default.join(cwd, "workspace", "skills", "learned");
403075
+ import_fs51.default.mkdirSync(learnedDir, { recursive: true });
402644
403076
  const skillName = skillNameFromMessage(userMessage);
402645
- if (import_fs50.default.existsSync(learnedDir)) {
402646
- for (const entry of import_fs50.default.readdirSync(learnedDir, { withFileTypes: true })) {
403077
+ if (import_fs51.default.existsSync(learnedDir)) {
403078
+ for (const entry of import_fs51.default.readdirSync(learnedDir, { withFileTypes: true })) {
402647
403079
  if (!entry.isDirectory()) continue;
402648
403080
  const existingName = entry.name.replace(/_/g, " ");
402649
403081
  if (tokenSimilarity(skillName.replace(/_/g, " "), existingName) > 0.8) {
402650
- const metaPath2 = import_path52.default.join(learnedDir, entry.name, "meta.json");
402651
- if (import_fs50.default.existsSync(metaPath2)) {
403082
+ const metaPath2 = import_path53.default.join(learnedDir, entry.name, "meta.json");
403083
+ if (import_fs51.default.existsSync(metaPath2)) {
402652
403084
  try {
402653
- const meta = JSON.parse(import_fs50.default.readFileSync(metaPath2, "utf-8"));
403085
+ const meta = JSON.parse(import_fs51.default.readFileSync(metaPath2, "utf-8"));
402654
403086
  meta.successCount = (meta.successCount || 1) + 1;
402655
403087
  meta.lastUsed = Date.now();
402656
403088
  meta.confidence = Math.min(0.99, meta.successCount / (meta.successCount + (meta.failCount || 0) + 1));
402657
- import_fs50.default.writeFileSync(metaPath2, JSON.stringify(meta, null, 2) + "\n", "utf-8");
403089
+ import_fs51.default.writeFileSync(metaPath2, JSON.stringify(meta, null, 2) + "\n", "utf-8");
402658
403090
  } catch {
402659
403091
  }
402660
403092
  }
@@ -402662,22 +403094,22 @@ async function writeSkillFromTask(args) {
402662
403094
  }
402663
403095
  }
402664
403096
  }
402665
- const skillDir = import_path52.default.join(learnedDir, skillName);
402666
- if (import_fs50.default.existsSync(skillDir)) {
402667
- const metaPath2 = import_path52.default.join(skillDir, "meta.json");
402668
- if (import_fs50.default.existsSync(metaPath2)) {
403097
+ const skillDir = import_path53.default.join(learnedDir, skillName);
403098
+ if (import_fs51.default.existsSync(skillDir)) {
403099
+ const metaPath2 = import_path53.default.join(skillDir, "meta.json");
403100
+ if (import_fs51.default.existsSync(metaPath2)) {
402669
403101
  try {
402670
- const meta = JSON.parse(import_fs50.default.readFileSync(metaPath2, "utf-8"));
403102
+ const meta = JSON.parse(import_fs51.default.readFileSync(metaPath2, "utf-8"));
402671
403103
  meta.successCount = (meta.successCount || 1) + 1;
402672
403104
  meta.lastUsed = Date.now();
402673
403105
  meta.confidence = Math.min(0.99, meta.successCount / (meta.successCount + (meta.failCount || 0) + 1));
402674
- import_fs50.default.writeFileSync(metaPath2, JSON.stringify(meta, null, 2) + "\n", "utf-8");
403106
+ import_fs51.default.writeFileSync(metaPath2, JSON.stringify(meta, null, 2) + "\n", "utf-8");
402675
403107
  } catch {
402676
403108
  }
402677
403109
  }
402678
403110
  return null;
402679
403111
  }
402680
- import_fs50.default.mkdirSync(skillDir, { recursive: true });
403112
+ import_fs51.default.mkdirSync(skillDir, { recursive: true });
402681
403113
  const title = toTitleCase(skillName);
402682
403114
  const descSnippet = userMessage.slice(0, 100).replace(/\n/g, " ");
402683
403115
  const toolList = toolsUsed.join(", ");
@@ -402733,9 +403165,9 @@ async function writeSkillFromTask(args) {
402733
403165
  tags: inferTags(toolsUsed, userMessage),
402734
403166
  created: (/* @__PURE__ */ new Date()).toISOString()
402735
403167
  };
402736
- import_fs50.default.writeFileSync(import_path52.default.join(skillDir, "SKILL.md"), skillMd, "utf-8");
402737
- import_fs50.default.writeFileSync(import_path52.default.join(skillDir, "meta.json"), JSON.stringify(metaJson, null, 2) + "\n", "utf-8");
402738
- import_fs50.default.writeFileSync(import_path52.default.join(skillDir, "skill.json"), JSON.stringify(taskSkillJson, null, 2) + "\n", "utf-8");
403168
+ import_fs51.default.writeFileSync(import_path53.default.join(skillDir, "SKILL.md"), skillMd, "utf-8");
403169
+ import_fs51.default.writeFileSync(import_path53.default.join(skillDir, "meta.json"), JSON.stringify(metaJson, null, 2) + "\n", "utf-8");
403170
+ import_fs51.default.writeFileSync(import_path53.default.join(skillDir, "skill.json"), JSON.stringify(taskSkillJson, null, 2) + "\n", "utf-8");
402739
403171
  console.log(`[SkillWriter] Wrote skill "${skillName}" \u2192 ${skillDir}`);
402740
403172
  return { skillName, path: skillDir };
402741
403173
  } catch (err) {
@@ -402745,22 +403177,22 @@ async function writeSkillFromTask(args) {
402745
403177
  }
402746
403178
  function listPending() {
402747
403179
  const cwd = process.cwd();
402748
- const pendDir = import_path52.default.join(cwd, "skills", "learned", "pending");
402749
- if (!import_fs50.default.existsSync(pendDir)) return [];
402750
- return import_fs50.default.readdirSync(pendDir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => {
403180
+ const pendDir = import_path53.default.join(cwd, "skills", "learned", "pending");
403181
+ if (!import_fs51.default.existsSync(pendDir)) return [];
403182
+ return import_fs51.default.readdirSync(pendDir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => {
402751
403183
  try {
402752
- const meta = JSON.parse(import_fs50.default.readFileSync(import_path52.default.join(pendDir, e.name, "meta.json"), "utf-8"));
403184
+ const meta = JSON.parse(import_fs51.default.readFileSync(import_path53.default.join(pendDir, e.name, "meta.json"), "utf-8"));
402753
403185
  return { id: e.name, name: meta.name || e.name, description: meta.description || "", source: meta.source || "", createdAt: meta.createdAt || "" };
402754
403186
  } catch {
402755
403187
  return { id: e.name, name: e.name, description: "", source: "unknown", createdAt: "" };
402756
403188
  }
402757
403189
  });
402758
403190
  }
402759
- var import_fs50, import_path52, STOP_WORDS2;
403191
+ var import_fs51, import_path53, STOP_WORDS2;
402760
403192
  var init_skillWriter = __esm({
402761
403193
  "core/skillWriter.ts"() {
402762
- import_fs50 = __toESM(require("fs"));
402763
- import_path52 = __toESM(require("path"));
403194
+ import_fs51 = __toESM(require("fs"));
403195
+ import_path53 = __toESM(require("path"));
402764
403196
  STOP_WORDS2 = /* @__PURE__ */ new Set([
402765
403197
  "a",
402766
403198
  "an",
@@ -1048654,12 +1049086,12 @@ init_contextHandoff();
1048654
1049086
  // core/voiceInput.ts
1048655
1049087
  var import_child_process14 = require("child_process");
1048656
1049088
  var import_util11 = require("util");
1048657
- var import_fs44 = __toESM(require("fs"));
1048658
- var import_path46 = __toESM(require("path"));
1049089
+ var import_fs45 = __toESM(require("fs"));
1049090
+ var import_path47 = __toESM(require("path"));
1048659
1049091
  var execAsync9 = (0, import_util11.promisify)(import_child_process14.exec);
1048660
- var WORKSPACE5 = import_path46.default.join(process.cwd(), "workspace");
1049092
+ var WORKSPACE5 = import_path47.default.join(process.cwd(), "workspace");
1048661
1049093
  function ensureWorkspace4() {
1048662
- if (!import_fs44.default.existsSync(WORKSPACE5)) import_fs44.default.mkdirSync(WORKSPACE5, { recursive: true });
1049094
+ if (!import_fs45.default.existsSync(WORKSPACE5)) import_fs45.default.mkdirSync(WORKSPACE5, { recursive: true });
1048663
1049095
  }
1048664
1049096
  async function checkVoiceAvailable() {
1048665
1049097
  try {
@@ -1048682,8 +1049114,8 @@ segments, info = model.transcribe("${normalizedPath}", beam_size=5)
1048682
1049114
  text = " ".join([segment.text for segment in segments])
1048683
1049115
  print(text.strip())
1048684
1049116
  `.trim();
1048685
- const tmpScript = import_path46.default.join(WORKSPACE5, `whisper_${Date.now()}.py`);
1048686
- import_fs44.default.writeFileSync(tmpScript, pythonScript);
1049117
+ const tmpScript = import_path47.default.join(WORKSPACE5, `whisper_${Date.now()}.py`);
1049118
+ import_fs45.default.writeFileSync(tmpScript, pythonScript);
1048687
1049119
  try {
1048688
1049120
  const { stdout } = await execAsync9(`python "${tmpScript}"`, { timeout: 3e4 });
1048689
1049121
  return stdout.trim();
@@ -1048691,14 +1049123,14 @@ print(text.strip())
1048691
1049123
  throw new Error(`Transcription failed: ${e.message}`);
1048692
1049124
  } finally {
1048693
1049125
  try {
1048694
- import_fs44.default.unlinkSync(tmpScript);
1049126
+ import_fs45.default.unlinkSync(tmpScript);
1048695
1049127
  } catch {
1048696
1049128
  }
1048697
1049129
  }
1048698
1049130
  }
1048699
1049131
  async function recordAudio2(durationMs = 5e3) {
1048700
1049132
  ensureWorkspace4();
1048701
- const outputPath = import_path46.default.join(WORKSPACE5, `recording_${Date.now()}.wav`);
1049133
+ const outputPath = import_path47.default.join(WORKSPACE5, `recording_${Date.now()}.wav`);
1048702
1049134
  const outputPathFwd = outputPath.replace(/\\/g, "\\\\");
1048703
1049135
  const psScript = `
1048704
1049136
  Add-Type -TypeDefinition @"
@@ -1048729,8 +1049161,8 @@ public class AudioRecorder {
1048729
1049161
  [AudioRecorder]::Record("${outputPathFwd}", ${durationMs})
1048730
1049162
  Write-Output "${outputPath}"
1048731
1049163
  `.trim();
1048732
- const psFile2 = import_path46.default.join(WORKSPACE5, `record_${Date.now()}.ps1`);
1048733
- import_fs44.default.writeFileSync(psFile2, psScript);
1049164
+ const psFile2 = import_path47.default.join(WORKSPACE5, `record_${Date.now()}.ps1`);
1049165
+ import_fs45.default.writeFileSync(psFile2, psScript);
1048734
1049166
  try {
1048735
1049167
  await execAsync9(
1048736
1049168
  `powershell.exe -ExecutionPolicy Bypass -File "${psFile2}"`,
@@ -1048741,7 +1049173,7 @@ Write-Output "${outputPath}"
1048741
1049173
  throw new Error(`Recording failed: ${e.message}`);
1048742
1049174
  } finally {
1048743
1049175
  try {
1048744
- import_fs44.default.unlinkSync(psFile2);
1049176
+ import_fs45.default.unlinkSync(psFile2);
1048745
1049177
  } catch {
1048746
1049178
  }
1048747
1049179
  }
@@ -1048750,13 +1049182,13 @@ Write-Output "${outputPath}"
1048750
1049182
  // core/voiceOutput.ts
1048751
1049183
  var import_child_process15 = require("child_process");
1048752
1049184
  var import_util12 = require("util");
1048753
- var import_fs45 = __toESM(require("fs"));
1048754
- var import_path47 = __toESM(require("path"));
1049185
+ var import_fs46 = __toESM(require("fs"));
1049186
+ var import_path48 = __toESM(require("path"));
1048755
1049187
  var execAsync10 = (0, import_util12.promisify)(import_child_process15.exec);
1048756
- var WORKSPACE6 = import_path47.default.join(process.cwd(), "workspace");
1049188
+ var WORKSPACE6 = import_path48.default.join(process.cwd(), "workspace");
1048757
1049189
  var DEFAULT_VOICE2 = "en-US-AriaNeural";
1048758
1049190
  function ensureWorkspace5() {
1048759
- if (!import_fs45.default.existsSync(WORKSPACE6)) import_fs45.default.mkdirSync(WORKSPACE6, { recursive: true });
1049191
+ if (!import_fs46.default.existsSync(WORKSPACE6)) import_fs46.default.mkdirSync(WORKSPACE6, { recursive: true });
1048760
1049192
  }
1048761
1049193
  async function checkTTSAvailable() {
1048762
1049194
  try {
@@ -1048782,7 +1049214,7 @@ function cleanForTTS2(text) {
1048782
1049214
  }
1048783
1049215
  async function speakEdgeTTS(text, voice) {
1048784
1049216
  ensureWorkspace5();
1048785
- const audioPath = import_path47.default.join(WORKSPACE6, `tts_${Date.now()}.mp3`);
1049217
+ const audioPath = import_path48.default.join(WORKSPACE6, `tts_${Date.now()}.mp3`);
1048786
1049218
  const audioFwd = audioPath.replace(/\\/g, "/");
1048787
1049219
  const escapedText = text.replace(/"/g, '\\"').replace(/'/g, "\\'");
1048788
1049220
  const scriptContent = `
@@ -1048794,11 +1049226,11 @@ async def main():
1048794
1049226
  await communicate.save("${audioFwd}")
1048795
1049227
  asyncio.run(main())
1048796
1049228
  `.trim();
1048797
- const tmpScript = import_path47.default.join(WORKSPACE6, `tts_gen_${Date.now()}.py`);
1048798
- import_fs45.default.writeFileSync(tmpScript, scriptContent);
1049229
+ const tmpScript = import_path48.default.join(WORKSPACE6, `tts_gen_${Date.now()}.py`);
1049230
+ import_fs46.default.writeFileSync(tmpScript, scriptContent);
1048799
1049231
  try {
1048800
1049232
  await execAsync10(`python "${tmpScript}"`, { timeout: 15e3 });
1048801
- if (!import_fs45.default.existsSync(audioPath)) return false;
1049233
+ if (!import_fs46.default.existsSync(audioPath)) return false;
1048802
1049234
  execAsync10(
1048803
1049235
  `powershell -Command "Add-Type -AssemblyName presentationCore; $mp = New-Object System.Windows.Media.MediaPlayer; $mp.Open([uri]'${audioPath.replace(/\\/g, "\\\\")}'); $mp.Play(); Start-Sleep -Seconds 6; $mp.Stop(); $mp.Close()"`,
1048804
1049236
  { timeout: 15e3 }
@@ -1048808,7 +1049240,7 @@ asyncio.run(main())
1048808
1049240
  });
1048809
1049241
  setTimeout(() => {
1048810
1049242
  try {
1048811
- import_fs45.default.unlinkSync(audioPath);
1049243
+ import_fs46.default.unlinkSync(audioPath);
1048812
1049244
  } catch {
1048813
1049245
  }
1048814
1049246
  }, 12e3);
@@ -1048817,7 +1049249,7 @@ asyncio.run(main())
1048817
1049249
  return false;
1048818
1049250
  } finally {
1048819
1049251
  try {
1048820
- import_fs45.default.unlinkSync(tmpScript);
1049252
+ import_fs46.default.unlinkSync(tmpScript);
1048821
1049253
  } catch {
1048822
1049254
  }
1048823
1049255
  }
@@ -1048847,13 +1049279,13 @@ init_planTool();
1048847
1049279
  init_taskState();
1048848
1049280
 
1048849
1049281
  // core/taskQueue.ts
1048850
- var import_fs46 = require("fs");
1048851
- var import_path48 = require("path");
1049282
+ var import_fs47 = require("fs");
1049283
+ var import_path49 = require("path");
1048852
1049284
  var TaskQueue = class {
1048853
1049285
  constructor(workspaceDir, chatEndpoint) {
1048854
1049286
  this.queue = [];
1048855
1049287
  this.isProcessing = false;
1048856
- this.savePath = (0, import_path48.join)(workspaceDir, "task_queue.json");
1049288
+ this.savePath = (0, import_path49.join)(workspaceDir, "task_queue.json");
1048857
1049289
  this.chatEndpoint = chatEndpoint;
1048858
1049290
  this.load();
1048859
1049291
  for (const task of this.queue) {
@@ -1048930,8 +1049362,8 @@ var TaskQueue = class {
1048930
1049362
  // ── Persistence ───────────────────────────────────────────
1048931
1049363
  load() {
1048932
1049364
  try {
1048933
- if ((0, import_fs46.existsSync)(this.savePath)) {
1048934
- this.queue = JSON.parse((0, import_fs46.readFileSync)(this.savePath, "utf8"));
1049365
+ if ((0, import_fs47.existsSync)(this.savePath)) {
1049366
+ this.queue = JSON.parse((0, import_fs47.readFileSync)(this.savePath, "utf8"));
1048935
1049367
  }
1048936
1049368
  } catch {
1048937
1049369
  this.queue = [];
@@ -1048939,32 +1049371,32 @@ var TaskQueue = class {
1048939
1049371
  }
1048940
1049372
  save() {
1048941
1049373
  try {
1048942
- (0, import_fs46.mkdirSync)((0, import_path48.dirname)(this.savePath), { recursive: true });
1048943
- (0, import_fs46.writeFileSync)(this.savePath, JSON.stringify(this.queue, null, 2));
1049374
+ (0, import_fs47.mkdirSync)((0, import_path49.dirname)(this.savePath), { recursive: true });
1049375
+ (0, import_fs47.writeFileSync)(this.savePath, JSON.stringify(this.queue, null, 2));
1048944
1049376
  } catch {
1048945
1049377
  }
1048946
1049378
  }
1048947
1049379
  };
1048948
1049380
  var taskQueue = new TaskQueue(
1048949
- (0, import_path48.join)(process.cwd(), "workspace"),
1049381
+ (0, import_path49.join)(process.cwd(), "workspace"),
1048950
1049382
  "http://localhost:4200/api/chat"
1048951
1049383
  );
1048952
1049384
 
1048953
1049385
  // core/taskRecovery.ts
1048954
- var import_path49 = __toESM(require("path"));
1048955
- var import_fs47 = __toESM(require("fs"));
1048956
- var TASKS_DIR2 = import_path49.default.join(process.cwd(), "workspace", "tasks");
1049386
+ var import_path50 = __toESM(require("path"));
1049387
+ var import_fs48 = __toESM(require("fs"));
1049388
+ var TASKS_DIR2 = import_path50.default.join(process.cwd(), "workspace", "tasks");
1048957
1049389
  var MAX_TASK_AGE_MS = 2 * 60 * 60 * 1e3;
1048958
1049390
  async function recoverTasks() {
1048959
- if (!import_fs47.default.existsSync(TASKS_DIR2)) {
1049391
+ if (!import_fs48.default.existsSync(TASKS_DIR2)) {
1048960
1049392
  console.log("[Recovery] No task directory found \u2014 skipping");
1048961
1049393
  return;
1048962
1049394
  }
1048963
1049395
  let taskDirs;
1048964
1049396
  try {
1048965
- taskDirs = import_fs47.default.readdirSync(TASKS_DIR2).filter((d) => {
1049397
+ taskDirs = import_fs48.default.readdirSync(TASKS_DIR2).filter((d) => {
1048966
1049398
  try {
1048967
- return import_fs47.default.statSync(import_path49.default.join(TASKS_DIR2, d)).isDirectory();
1049399
+ return import_fs48.default.statSync(import_path50.default.join(TASKS_DIR2, d)).isDirectory();
1048968
1049400
  } catch {
1048969
1049401
  return false;
1048970
1049402
  }
@@ -1048977,16 +1049409,16 @@ async function recoverTasks() {
1048977
1049409
  let cleaned = 0;
1048978
1049410
  let corrupted = 0;
1048979
1049411
  for (const taskId of taskDirs) {
1048980
- const statePath = import_path49.default.join(TASKS_DIR2, taskId, "state.json");
1048981
- if (!import_fs47.default.existsSync(statePath)) continue;
1049412
+ const statePath = import_path50.default.join(TASKS_DIR2, taskId, "state.json");
1049413
+ if (!import_fs48.default.existsSync(statePath)) continue;
1048982
1049414
  let state;
1048983
1049415
  try {
1048984
- state = JSON.parse(import_fs47.default.readFileSync(statePath, "utf-8"));
1049416
+ state = JSON.parse(import_fs48.default.readFileSync(statePath, "utf-8"));
1048985
1049417
  } catch {
1048986
1049418
  corrupted++;
1048987
1049419
  try {
1048988
1049420
  const tmp = statePath + ".tmp";
1048989
- import_fs47.default.writeFileSync(tmp, JSON.stringify({
1049421
+ import_fs48.default.writeFileSync(tmp, JSON.stringify({
1048990
1049422
  id: taskId,
1048991
1049423
  status: "failed",
1048992
1049424
  error: "Corrupt state file \u2014 overwritten on startup",
@@ -1048994,11 +1049426,11 @@ async function recoverTasks() {
1048994
1049426
  updatedAt: Date.now()
1048995
1049427
  }, null, 2));
1048996
1049428
  try {
1048997
- import_fs47.default.renameSync(tmp, statePath);
1049429
+ import_fs48.default.renameSync(tmp, statePath);
1048998
1049430
  } catch {
1048999
- import_fs47.default.writeFileSync(statePath, import_fs47.default.readFileSync(tmp, "utf-8"));
1049431
+ import_fs48.default.writeFileSync(statePath, import_fs48.default.readFileSync(tmp, "utf-8"));
1049000
1049432
  try {
1049001
- import_fs47.default.unlinkSync(tmp);
1049433
+ import_fs48.default.unlinkSync(tmp);
1049002
1049434
  } catch {
1049003
1049435
  }
1049004
1049436
  }
@@ -1049016,13 +1049448,13 @@ async function recoverTasks() {
1049016
1049448
  cleaned++;
1049017
1049449
  try {
1049018
1049450
  const tmp = statePath + ".tmp";
1049019
- import_fs47.default.writeFileSync(tmp, JSON.stringify(state, null, 2));
1049451
+ import_fs48.default.writeFileSync(tmp, JSON.stringify(state, null, 2));
1049020
1049452
  try {
1049021
- import_fs47.default.renameSync(tmp, statePath);
1049453
+ import_fs48.default.renameSync(tmp, statePath);
1049022
1049454
  } catch {
1049023
- import_fs47.default.writeFileSync(statePath, JSON.stringify(state, null, 2));
1049455
+ import_fs48.default.writeFileSync(statePath, JSON.stringify(state, null, 2));
1049024
1049456
  try {
1049025
- import_fs47.default.unlinkSync(tmp);
1049457
+ import_fs48.default.unlinkSync(tmp);
1049026
1049458
  } catch {
1049027
1049459
  }
1049028
1049460
  }
@@ -1049055,164 +1049487,10 @@ async function recoverTasks() {
1049055
1049487
 
1049056
1049488
  // api/server.ts
1049057
1049489
  init_skillLoader();
1049058
-
1049059
- // core/memoryIds.ts
1049060
- var fs53 = __toESM(require("fs"));
1049061
- var path55 = __toESM(require("path"));
1049062
- var MEM_DIR = path55.join(process.cwd(), "workspace", "memory");
1049063
- var SEQUENCE_FILE = path55.join(MEM_DIR, "sequence.json");
1049064
- var RECORDS_FILE = path55.join(MEM_DIR, "records.jsonl");
1049065
- function _ensureDir() {
1049066
- fs53.mkdirSync(MEM_DIR, { recursive: true });
1049067
- }
1049068
- function _readSeq() {
1049069
- try {
1049070
- if (!fs53.existsSync(SEQUENCE_FILE)) return 0;
1049071
- const d = JSON.parse(fs53.readFileSync(SEQUENCE_FILE, "utf-8"));
1049072
- return typeof d.next === "number" ? d.next : 0;
1049073
- } catch {
1049074
- return 0;
1049075
- }
1049076
- }
1049077
- function _writeSeq(n) {
1049078
- _ensureDir();
1049079
- fs53.writeFileSync(SEQUENCE_FILE, JSON.stringify({ next: n }), "utf-8");
1049080
- }
1049081
- function nextId() {
1049082
- const n = _readSeq();
1049083
- _writeSeq(n + 1);
1049084
- return `mem_${String(n + 1).padStart(6, "0")}`;
1049085
- }
1049086
- function appendRecord(record2) {
1049087
- _ensureDir();
1049088
- fs53.appendFileSync(RECORDS_FILE, JSON.stringify(record2) + "\n", "utf-8");
1049089
- }
1049090
- function loadAllRecords() {
1049091
- try {
1049092
- if (!fs53.existsSync(RECORDS_FILE)) return [];
1049093
- return fs53.readFileSync(RECORDS_FILE, "utf-8").split("\n").filter((l2) => l2.trim()).map((l2) => {
1049094
- try {
1049095
- return JSON.parse(l2);
1049096
- } catch {
1049097
- return null;
1049098
- }
1049099
- }).filter((r) => r !== null);
1049100
- } catch {
1049101
- return [];
1049102
- }
1049103
- }
1049104
- function loadRecordById(id) {
1049105
- const all3 = loadAllRecords();
1049106
- return all3.find((r) => r.id === id) ?? null;
1049107
- }
1049108
- function removeRecords(predicate) {
1049109
- const all3 = loadAllRecords();
1049110
- const kept = all3.filter((r) => !predicate(r));
1049111
- const removed = all3.length - kept.length;
1049112
- if (removed > 0) {
1049113
- _ensureDir();
1049114
- fs53.writeFileSync(
1049115
- RECORDS_FILE,
1049116
- kept.map((r) => JSON.stringify(r)).join("\n") + (kept.length ? "\n" : ""),
1049117
- "utf-8"
1049118
- );
1049119
- }
1049120
- return removed;
1049121
- }
1049122
- function assignId(partial2) {
1049123
- const record2 = {
1049124
- id: partial2.id ?? nextId(),
1049125
- timestamp: partial2.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(),
1049126
- type: partial2.type ?? "observation",
1049127
- content: partial2.content ?? "",
1049128
- summary: partial2.summary ?? _autoSummary(partial2.content ?? ""),
1049129
- sessionId: partial2.sessionId,
1049130
- tags: partial2.tags,
1049131
- entityRefs: partial2.entityRefs
1049132
- };
1049133
- appendRecord(record2);
1049134
- return record2;
1049135
- }
1049136
- function _autoSummary(content) {
1049137
- const first = content.split("\n").find((l2) => l2.trim()) ?? content;
1049138
- return first.slice(0, 100).trim();
1049139
- }
1049140
- function runMigrationIfNeeded() {
1049141
- if (fs53.existsSync(RECORDS_FILE)) return 0;
1049142
- _ensureDir();
1049143
- const records = [];
1049144
- try {
1049145
- const raw = fs53.readFileSync(path55.join(MEM_DIR, "memory.json"), "utf-8");
1049146
- const parsed = JSON.parse(raw);
1049147
- const items = Array.isArray(parsed) ? parsed : parsed.value ?? [];
1049148
- for (const item of items) {
1049149
- const v = item.value ?? {};
1049150
- const content = [
1049151
- v.goal ? `Goal: ${v.goal}` : "",
1049152
- v.result ? `Result: ${String(v.result).slice(0, 800)}` : "",
1049153
- v.role ? `Role: ${v.role}` : ""
1049154
- ].filter(Boolean).join("\n");
1049155
- if (!content) continue;
1049156
- records.push({
1049157
- timestamp: item.createdAt ?? (/* @__PURE__ */ new Date()).toISOString(),
1049158
- type: item.tags?.includes("task") ? "interaction" : "observation",
1049159
- content,
1049160
- summary: _autoSummary(v.goal ?? v.result ?? content),
1049161
- tags: item.tags ?? []
1049162
- });
1049163
- }
1049164
- } catch {
1049165
- }
1049166
- try {
1049167
- const raw = fs53.readFileSync(
1049168
- path55.join(process.cwd(), "workspace", "conversation-memory.json"),
1049169
- "utf-8"
1049170
- );
1049171
- const parsed = JSON.parse(raw);
1049172
- const msgs = parsed.messages ?? [];
1049173
- for (const msg of msgs) {
1049174
- if (msg.role !== "assistant") continue;
1049175
- const content = String(msg.content ?? "").trim();
1049176
- if (content.length < 20) continue;
1049177
- records.push({
1049178
- timestamp: msg.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(),
1049179
- type: "interaction",
1049180
- content: content.slice(0, 1e3),
1049181
- summary: _autoSummary(content),
1049182
- sessionId: msg.sessionId,
1049183
- tags: ["conversation"]
1049184
- });
1049185
- }
1049186
- } catch {
1049187
- }
1049188
- try {
1049189
- const raw = fs53.readFileSync(path55.join(MEM_DIR, "MEMORY_INDEX.md"), "utf-8");
1049190
- const lines = raw.split("\n").filter((l2) => l2.startsWith("- "));
1049191
- for (const line of lines) {
1049192
- const cleaned = line.replace(/^-\s*/, "").trim();
1049193
- if (cleaned.length < 10) continue;
1049194
- records.push({
1049195
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1049196
- type: "fact",
1049197
- content: cleaned,
1049198
- summary: cleaned.slice(0, 100),
1049199
- tags: ["index"]
1049200
- });
1049201
- }
1049202
- } catch {
1049203
- }
1049204
- records.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
1049205
- let count = 0;
1049206
- for (const rec of records) {
1049207
- const id = nextId();
1049208
- const record2 = { id, ...rec };
1049209
- appendRecord(record2);
1049210
- count++;
1049211
- }
1049212
- return count;
1049213
- }
1049490
+ init_memoryIds();
1049214
1049491
 
1049215
1049492
  // core/memoryQuery.ts
1049493
+ init_memoryIds();
1049216
1049494
  var _sessionCitations = /* @__PURE__ */ new Map();
1049217
1049495
  function trackCitation(id, summary) {
1049218
1049496
  const c = _sessionCitations.get(id);
@@ -1049310,11 +1049588,11 @@ init_knowledgeBase();
1049310
1049588
  init_youtubeTranscript();
1049311
1049589
 
1049312
1049590
  // core/importers.ts
1049313
- var import_fs48 = __toESM(require("fs"));
1049314
- var import_path50 = __toESM(require("path"));
1049591
+ var import_fs49 = __toESM(require("fs"));
1049592
+ var import_path51 = __toESM(require("path"));
1049315
1049593
  init_knowledgeBase();
1049316
1049594
  var WORKSPACE_ROOT2 = process.env.AIDEN_USER_DATA || process.cwd();
1049317
- var MEMORY_DIR4 = import_path50.default.join(WORKSPACE_ROOT2, "workspace", "memory");
1049595
+ var MEMORY_DIR4 = import_path51.default.join(WORKSPACE_ROOT2, "workspace", "memory");
1049318
1049596
  async function importChatGPT(filePath) {
1049319
1049597
  const result = {
1049320
1049598
  source: "chatgpt",
@@ -1049323,7 +1049601,7 @@ async function importChatGPT(filePath) {
1049323
1049601
  errors: []
1049324
1049602
  };
1049325
1049603
  try {
1049326
- const raw = import_fs48.default.readFileSync(filePath, "utf8");
1049604
+ const raw = import_fs49.default.readFileSync(filePath, "utf8");
1049327
1049605
  const conversations = JSON.parse(raw);
1049328
1049606
  if (!Array.isArray(conversations)) {
1049329
1049607
  result.errors.push("Invalid format: expected array of conversations");
@@ -1049373,9 +1049651,9 @@ async function importChatGPT(filePath) {
1049373
1049651
  function findMdFiles(dir) {
1049374
1049652
  const files = [];
1049375
1049653
  try {
1049376
- const entries = import_fs48.default.readdirSync(dir, { withFileTypes: true });
1049654
+ const entries = import_fs49.default.readdirSync(dir, { withFileTypes: true });
1049377
1049655
  for (const entry of entries) {
1049378
- const fullPath = import_path50.default.join(dir, entry.name);
1049656
+ const fullPath = import_path51.default.join(dir, entry.name);
1049379
1049657
  if (entry.isDirectory() && !entry.name.startsWith(".")) {
1049380
1049658
  files.push(...findMdFiles(fullPath));
1049381
1049659
  } else if (entry.name.endsWith(".md")) {
@@ -1049393,16 +1049671,16 @@ async function importOpenClaw(directoryPath) {
1049393
1049671
  memoriesExtracted: 0,
1049394
1049672
  errors: []
1049395
1049673
  };
1049396
- if (!import_fs48.default.existsSync(directoryPath)) {
1049674
+ if (!import_fs49.default.existsSync(directoryPath)) {
1049397
1049675
  result.errors.push(`Directory not found: ${directoryPath}`);
1049398
1049676
  return result;
1049399
1049677
  }
1049400
1049678
  const mdFiles = findMdFiles(directoryPath);
1049401
1049679
  for (const file of mdFiles) {
1049402
1049680
  try {
1049403
- const content = import_fs48.default.readFileSync(file, "utf8");
1049681
+ const content = import_fs49.default.readFileSync(file, "utf8");
1049404
1049682
  if (content.trim().length < 50) continue;
1049405
- const basename5 = import_path50.default.basename(file, ".md");
1049683
+ const basename5 = import_path51.default.basename(file, ".md");
1049406
1049684
  const lower = file.toLowerCase();
1049407
1049685
  const isMemory = lower.includes("memory");
1049408
1049686
  const isLesson = lower.includes("lesson");
@@ -1049423,11 +1049701,11 @@ async function importOpenClaw(directoryPath) {
1049423
1049701
  }
1049424
1049702
  if (isMemory || isLesson) {
1049425
1049703
  try {
1049426
- import_fs48.default.mkdirSync(MEMORY_DIR4, { recursive: true });
1049704
+ import_fs49.default.mkdirSync(MEMORY_DIR4, { recursive: true });
1049427
1049705
  const destName = `imported_${basename5.replace(/[^a-zA-Z0-9._-]/g, "_").slice(0, 60)}.md`;
1049428
- const destPath = import_path50.default.join(MEMORY_DIR4, destName);
1049429
- if (!import_fs48.default.existsSync(destPath)) {
1049430
- import_fs48.default.writeFileSync(
1049706
+ const destPath = import_path51.default.join(MEMORY_DIR4, destName);
1049707
+ if (!import_fs49.default.existsSync(destPath)) {
1049708
+ import_fs49.default.writeFileSync(
1049431
1049709
  destPath,
1049432
1049710
  `<!-- source: openclaw_import | confidence: 0.7 -->
1049433
1049711
  ${content}`,
@@ -1049440,7 +1049718,7 @@ ${content}`,
1049440
1049718
  }
1049441
1049719
  }
1049442
1049720
  } catch (err) {
1049443
- result.errors.push(`Failed: ${import_path50.default.basename(file)}`);
1049721
+ result.errors.push(`Failed: ${import_path51.default.basename(file)}`);
1049444
1049722
  }
1049445
1049723
  }
1049446
1049724
  console.log(
@@ -1049524,9 +1049802,9 @@ init_morningBriefing();
1049524
1049802
  init_memoryRecall();
1049525
1049803
 
1049526
1049804
  // core/lessonsBrowser.ts
1049527
- var import_fs49 = __toESM(require("fs"));
1049528
- var import_path51 = __toESM(require("path"));
1049529
- var LESSONS_PATH2 = import_path51.default.join(process.cwd(), "workspace", "LESSONS.md");
1049805
+ var import_fs50 = __toESM(require("fs"));
1049806
+ var import_path52 = __toESM(require("path"));
1049807
+ var LESSONS_PATH3 = import_path52.default.join(process.cwd(), "workspace", "LESSONS.md");
1049530
1049808
  var CATEGORY_RULES = [
1049531
1049809
  [/web_search|search|query|url/i, "web"],
1049532
1049810
  [/shell_exec|run_python|command|bash/i, "shell"],
@@ -1049546,7 +1049824,7 @@ function inferCategory(text) {
1049546
1049824
  function parseLessons() {
1049547
1049825
  let raw = "";
1049548
1049826
  try {
1049549
- raw = import_fs49.default.readFileSync(LESSONS_PATH2, "utf-8");
1049827
+ raw = import_fs50.default.readFileSync(LESSONS_PATH3, "utf-8");
1049550
1049828
  } catch {
1049551
1049829
  return [];
1049552
1049830
  }
@@ -1049585,12 +1049863,12 @@ function appendLesson2(text) {
1049585
1049863
  const entry = `${id}. [${date3}] ${text}
1049586
1049864
  `;
1049587
1049865
  try {
1049588
- if (!import_fs49.default.existsSync(LESSONS_PATH2)) {
1049866
+ if (!import_fs50.default.existsSync(LESSONS_PATH3)) {
1049589
1049867
  const header = "# LESSONS.md \u2014 Permanent Failure Rules\n# Auto-appended after task failures.\n\n## Rules\n\n";
1049590
- import_fs49.default.mkdirSync(import_path51.default.dirname(LESSONS_PATH2), { recursive: true });
1049591
- import_fs49.default.writeFileSync(LESSONS_PATH2, header + entry, "utf-8");
1049868
+ import_fs50.default.mkdirSync(import_path52.default.dirname(LESSONS_PATH3), { recursive: true });
1049869
+ import_fs50.default.writeFileSync(LESSONS_PATH3, header + entry, "utf-8");
1049592
1049870
  } else {
1049593
- import_fs49.default.appendFileSync(LESSONS_PATH2, entry, "utf-8");
1049871
+ import_fs50.default.appendFileSync(LESSONS_PATH3, entry, "utf-8");
1049594
1049872
  }
1049595
1049873
  } catch {
1049596
1049874
  }
@@ -1050148,13 +1050426,13 @@ function getCatalog() {
1050148
1050426
  init_permissionSystem();
1050149
1050427
 
1050150
1050428
  // core/aidenIdentity.ts
1050151
- var import_fs51 = __toESM(require("fs"));
1050152
- var import_path53 = __toESM(require("path"));
1050429
+ var import_fs52 = __toESM(require("fs"));
1050430
+ var import_path54 = __toESM(require("path"));
1050153
1050431
  init_skillTeacher();
1050154
1050432
  init_eventBus();
1050155
- var IDENTITY_PATH = import_path53.default.join(process.cwd(), "workspace", "identity.json");
1050156
- var AUDIT_PATH2 = import_path53.default.join(process.cwd(), "workspace", "audit", "audit.jsonl");
1050157
- var SESSIONS_DIR4 = import_path53.default.join(process.cwd(), "workspace", "sessions");
1050433
+ var IDENTITY_PATH = import_path54.default.join(process.cwd(), "workspace", "identity.json");
1050434
+ var AUDIT_PATH2 = import_path54.default.join(process.cwd(), "workspace", "audit", "audit.jsonl");
1050435
+ var SESSIONS_DIR4 = import_path54.default.join(process.cwd(), "workspace", "sessions");
1050158
1050436
  var LEVEL_THRESHOLDS = [0, 10, 50, 200, 500];
1050159
1050437
  var TITLES = ["Apprentice", "Assistant", "Specialist", "Expert", "Architect"];
1050160
1050438
  function computeLevel(xp) {
@@ -1050177,8 +1050455,8 @@ function computeProgress(xp, level) {
1050177
1050455
  }
1050178
1050456
  function computeXP() {
1050179
1050457
  try {
1050180
- if (!import_fs51.default.existsSync(AUDIT_PATH2)) return 0;
1050181
- return import_fs51.default.readFileSync(AUDIT_PATH2, "utf-8").trim().split("\n").filter(Boolean).map((l2) => {
1050458
+ if (!import_fs52.default.existsSync(AUDIT_PATH2)) return 0;
1050459
+ return import_fs52.default.readFileSync(AUDIT_PATH2, "utf-8").trim().split("\n").filter(Boolean).map((l2) => {
1050182
1050460
  try {
1050183
1050461
  return JSON.parse(l2);
1050184
1050462
  } catch {
@@ -1050191,8 +1050469,8 @@ function computeXP() {
1050191
1050469
  }
1050192
1050470
  function computeTopStrength() {
1050193
1050471
  try {
1050194
- if (!import_fs51.default.existsSync(AUDIT_PATH2)) return "Research";
1050195
- const entries = import_fs51.default.readFileSync(AUDIT_PATH2, "utf-8").trim().split("\n").filter(Boolean).map((l2) => {
1050472
+ if (!import_fs52.default.existsSync(AUDIT_PATH2)) return "Research";
1050473
+ const entries = import_fs52.default.readFileSync(AUDIT_PATH2, "utf-8").trim().split("\n").filter(Boolean).map((l2) => {
1050196
1050474
  try {
1050197
1050475
  return JSON.parse(l2);
1050198
1050476
  } catch {
@@ -1050219,20 +1050497,20 @@ function computeTopStrength() {
1050219
1050497
  }
1050220
1050498
  function computeStreakDays() {
1050221
1050499
  try {
1050222
- if (!import_fs51.default.existsSync(SESSIONS_DIR4)) return 0;
1050500
+ if (!import_fs52.default.existsSync(SESSIONS_DIR4)) return 0;
1050223
1050501
  const sessionDates = /* @__PURE__ */ new Set();
1050224
- for (const f of import_fs51.default.readdirSync(SESSIONS_DIR4)) {
1050502
+ for (const f of import_fs52.default.readdirSync(SESSIONS_DIR4)) {
1050225
1050503
  if (!f.endsWith(".md")) continue;
1050226
1050504
  try {
1050227
- const mtime = import_fs51.default.statSync(import_path53.default.join(SESSIONS_DIR4, f)).mtime;
1050505
+ const mtime = import_fs52.default.statSync(import_path54.default.join(SESSIONS_DIR4, f)).mtime;
1050228
1050506
  sessionDates.add(mtime.toISOString().slice(0, 10));
1050229
1050507
  } catch {
1050230
1050508
  }
1050231
1050509
  }
1050232
1050510
  if (sessionDates.size === 0) return 0;
1050233
1050511
  const auditDates = /* @__PURE__ */ new Set();
1050234
- if (import_fs51.default.existsSync(AUDIT_PATH2)) {
1050235
- for (const line of import_fs51.default.readFileSync(AUDIT_PATH2, "utf-8").trim().split("\n").filter(Boolean)) {
1050512
+ if (import_fs52.default.existsSync(AUDIT_PATH2)) {
1050513
+ for (const line of import_fs52.default.readFileSync(AUDIT_PATH2, "utf-8").trim().split("\n").filter(Boolean)) {
1050236
1050514
  try {
1050237
1050515
  const e = JSON.parse(line);
1050238
1050516
  if (e.ts) auditDates.add(new Date(e.ts).toISOString().slice(0, 10));
@@ -1050282,8 +1050560,8 @@ function computeIdentity() {
1050282
1050560
  function refreshIdentity() {
1050283
1050561
  const identity = computeIdentity();
1050284
1050562
  try {
1050285
- import_fs51.default.mkdirSync(import_path53.default.dirname(IDENTITY_PATH), { recursive: true });
1050286
- import_fs51.default.writeFileSync(IDENTITY_PATH, JSON.stringify(identity, null, 2));
1050563
+ import_fs52.default.mkdirSync(import_path54.default.dirname(IDENTITY_PATH), { recursive: true });
1050564
+ import_fs52.default.writeFileSync(IDENTITY_PATH, JSON.stringify(identity, null, 2));
1050287
1050565
  } catch (e) {
1050288
1050566
  console.error("[AidenIdentity] Write failed:", e.message);
1050289
1050567
  }
@@ -1050295,8 +1050573,8 @@ function refreshIdentity() {
1050295
1050573
  }
1050296
1050574
  function loadIdentity() {
1050297
1050575
  try {
1050298
- if (!import_fs51.default.existsSync(IDENTITY_PATH)) return null;
1050299
- return JSON.parse(import_fs51.default.readFileSync(IDENTITY_PATH, "utf-8"));
1050576
+ if (!import_fs52.default.existsSync(IDENTITY_PATH)) return null;
1050577
+ return JSON.parse(import_fs52.default.readFileSync(IDENTITY_PATH, "utf-8"));
1050300
1050578
  } catch {
1050301
1050579
  return null;
1050302
1050580
  }
@@ -1050305,7 +1050583,7 @@ function getIdentity() {
1050305
1050583
  return loadIdentity() ?? refreshIdentity();
1050306
1050584
  }
1050307
1050585
  try {
1050308
- import_fs51.default.mkdirSync(import_path53.default.dirname(IDENTITY_PATH), { recursive: true });
1050586
+ import_fs52.default.mkdirSync(import_path54.default.dirname(IDENTITY_PATH), { recursive: true });
1050309
1050587
  } catch {
1050310
1050588
  }
1050311
1050589
 
@@ -1050497,8 +1050775,8 @@ function registerTelegramCallbacks(bot) {
1050497
1050775
  }
1050498
1050776
 
1050499
1050777
  // core/memoryDistiller.ts
1050500
- var import_fs52 = __toESM(require("fs"));
1050501
- var import_path54 = __toESM(require("path"));
1050778
+ var import_fs53 = __toESM(require("fs"));
1050779
+ var import_path55 = __toESM(require("path"));
1050502
1050780
  init_conversationMemory();
1050503
1050781
  init_semanticMemory();
1050504
1050782
  init_agentLoop();
@@ -1050518,7 +1050796,7 @@ No headings, no explanations, no blank lines between facts.
1050518
1050796
  Facts must be self-contained (understandable without the conversation).
1050519
1050797
  Maximum 15 facts. Minimum 5 facts if the conversation has meaningful content.`;
1050520
1050798
  var MAX_TRANSCRIPT_CHARS = 32e3;
1050521
- var DISTILL_MARKER_PATH = import_path54.default.join(process.cwd(), "workspace", "distilled_sessions.json");
1050799
+ var DISTILL_MARKER_PATH = import_path55.default.join(process.cwd(), "workspace", "distilled_sessions.json");
1050522
1050800
  async function distillSession(sessionId, timeoutMs = 15e3) {
1050523
1050801
  try {
1050524
1050802
  conversationMemory.setSession(sessionId);
@@ -1050581,8 +1050859,8 @@ async function distillAllActiveSessions(timeoutMs = 8e3) {
1050581
1050859
  }
1050582
1050860
  function loadDistilledSet() {
1050583
1050861
  try {
1050584
- if (import_fs52.default.existsSync(DISTILL_MARKER_PATH)) {
1050585
- return new Set(JSON.parse(import_fs52.default.readFileSync(DISTILL_MARKER_PATH, "utf-8")));
1050862
+ if (import_fs53.default.existsSync(DISTILL_MARKER_PATH)) {
1050863
+ return new Set(JSON.parse(import_fs53.default.readFileSync(DISTILL_MARKER_PATH, "utf-8")));
1050586
1050864
  }
1050587
1050865
  } catch {
1050588
1050866
  }
@@ -1050595,15 +1050873,15 @@ function markDistilled(sessionId) {
1050595
1050873
  try {
1050596
1050874
  const set2 = loadDistilledSet();
1050597
1050875
  set2.add(sessionId);
1050598
- import_fs52.default.mkdirSync(import_path54.default.dirname(DISTILL_MARKER_PATH), { recursive: true });
1050599
- import_fs52.default.writeFileSync(DISTILL_MARKER_PATH, JSON.stringify([...set2], null, 2) + "\n", "utf-8");
1050876
+ import_fs53.default.mkdirSync(import_path55.default.dirname(DISTILL_MARKER_PATH), { recursive: true });
1050877
+ import_fs53.default.writeFileSync(DISTILL_MARKER_PATH, JSON.stringify([...set2], null, 2) + "\n", "utf-8");
1050600
1050878
  } catch {
1050601
1050879
  }
1050602
1050880
  }
1050603
1050881
 
1050604
1050882
  // core/failureAnalyzer.ts
1050605
- var import_fs53 = __toESM(require("fs"));
1050606
- var import_path55 = __toESM(require("path"));
1050883
+ var import_fs54 = __toESM(require("fs"));
1050884
+ var import_path56 = __toESM(require("path"));
1050607
1050885
  var FAILURE_KEYWORDS = [
1050608
1050886
  "that's wrong",
1050609
1050887
  "thats wrong",
@@ -1050686,10 +1050964,10 @@ function _degradeSkill(skillName, rootCause) {
1050686
1050964
  const cwd = process.cwd();
1050687
1050965
  const folders = ["learned", "approved", "installed"];
1050688
1050966
  for (const folder of folders) {
1050689
- const metaPath2 = import_path55.default.join(cwd, "workspace", "skills", folder, skillName, "meta.json");
1050690
- if (!import_fs53.default.existsSync(metaPath2)) continue;
1050967
+ const metaPath2 = import_path56.default.join(cwd, "workspace", "skills", folder, skillName, "meta.json");
1050968
+ if (!import_fs54.default.existsSync(metaPath2)) continue;
1050691
1050969
  try {
1050692
- const meta = JSON.parse(import_fs53.default.readFileSync(metaPath2, "utf-8"));
1050970
+ const meta = JSON.parse(import_fs54.default.readFileSync(metaPath2, "utf-8"));
1050693
1050971
  meta.failCount = (meta.failCount ?? 0) + 1;
1050694
1050972
  meta.lastFailureReason = rootCause;
1050695
1050973
  meta.confidence = Math.max(0.1, (meta.confidence ?? 1) - 0.15);
@@ -1050697,7 +1050975,7 @@ function _degradeSkill(skillName, rootCause) {
1050697
1050975
  meta.deprecated = true;
1050698
1050976
  console.warn(`[failureAnalyzer] skill "${skillName}" auto-deprecated after ${meta.failCount} failures`);
1050699
1050977
  }
1050700
- import_fs53.default.writeFileSync(metaPath2, JSON.stringify(meta, null, 2) + "\n", "utf-8");
1050978
+ import_fs54.default.writeFileSync(metaPath2, JSON.stringify(meta, null, 2) + "\n", "utf-8");
1050701
1050979
  console.log(`[failureAnalyzer] degraded skill "${skillName}" \u2192 confidence ${meta.confidence.toFixed(2)}, failCount ${meta.failCount}`);
1050702
1050980
  } catch (e) {
1050703
1050981
  console.warn(`[failureAnalyzer] could not update meta for "${skillName}":`, e.message);
@@ -1050707,8 +1050985,8 @@ function _degradeSkill(skillName, rootCause) {
1050707
1050985
  }
1050708
1050986
 
1050709
1050987
  // core/sessionRouter.ts
1050710
- var import_fs54 = __toESM(require("fs"));
1050711
- var import_path56 = __toESM(require("path"));
1050988
+ var import_fs55 = __toESM(require("fs"));
1050989
+ var import_path57 = __toESM(require("path"));
1050712
1050990
  var SessionRouter = class {
1050713
1050991
  constructor() {
1050714
1050992
  this.sessions = /* @__PURE__ */ new Map();
@@ -1050749,15 +1051027,15 @@ var SessionRouter = class {
1050749
1051027
  getHistory(userId) {
1050750
1051028
  const sessionId = this.userToSession.get(userId);
1050751
1051029
  if (!sessionId) return [];
1050752
- const sessionFile = import_path56.default.join(
1051030
+ const sessionFile = import_path57.default.join(
1050753
1051031
  process.cwd(),
1050754
1051032
  "workspace",
1050755
1051033
  "sessions",
1050756
1051034
  `${sessionId}.json`
1050757
1051035
  );
1050758
- if (import_fs54.default.existsSync(sessionFile)) {
1051036
+ if (import_fs55.default.existsSync(sessionFile)) {
1050759
1051037
  try {
1050760
- const data = JSON.parse(import_fs54.default.readFileSync(sessionFile, "utf8"));
1051038
+ const data = JSON.parse(import_fs55.default.readFileSync(sessionFile, "utf8"));
1050761
1051039
  return data.messages || [];
1050762
1051040
  } catch {
1050763
1051041
  }
@@ -1050883,8 +1051161,8 @@ var Gateway = class {
1050883
1051161
  var gateway = new Gateway();
1050884
1051162
 
1050885
1051163
  // core/agentShield.ts
1050886
- var import_fs55 = __toESM(require("fs"));
1050887
- var import_path57 = __toESM(require("path"));
1051164
+ var import_fs56 = __toESM(require("fs"));
1051165
+ var import_path58 = __toESM(require("path"));
1050888
1051166
  var WORKSPACE_ROOT3 = process.env.AIDEN_USER_DATA || process.cwd();
1050889
1051167
  var INJECTION_PATTERNS2 = [
1050890
1051168
  { pattern: /ignore\s+(all\s+)?(previous|above|prior)/i, desc: "Prompt injection: ignore previous instructions" },
@@ -1050924,26 +1051202,26 @@ async function runSecurityScan() {
1050924
1051202
  let toolsScanned = 0;
1050925
1051203
  let configsScanned = 0;
1050926
1051204
  const skillDirs = [
1050927
- import_path57.default.join(WORKSPACE_ROOT3, "skills"),
1050928
- import_path57.default.join(WORKSPACE_ROOT3, "workspace", "skills"),
1050929
- import_path57.default.join(WORKSPACE_ROOT3, "workspace", "skills", "learned"),
1050930
- import_path57.default.join(WORKSPACE_ROOT3, "workspace", "skills", "approved")
1051205
+ import_path58.default.join(WORKSPACE_ROOT3, "skills"),
1051206
+ import_path58.default.join(WORKSPACE_ROOT3, "workspace", "skills"),
1051207
+ import_path58.default.join(WORKSPACE_ROOT3, "workspace", "skills", "learned"),
1051208
+ import_path58.default.join(WORKSPACE_ROOT3, "workspace", "skills", "approved")
1050931
1051209
  ];
1050932
1051210
  for (const dir of skillDirs) {
1050933
- if (!import_fs55.default.existsSync(dir)) continue;
1051211
+ if (!import_fs56.default.existsSync(dir)) continue;
1050934
1051212
  let entries;
1050935
1051213
  try {
1050936
- entries = import_fs55.default.readdirSync(dir, { withFileTypes: true });
1051214
+ entries = import_fs56.default.readdirSync(dir, { withFileTypes: true });
1050937
1051215
  } catch {
1050938
1051216
  continue;
1050939
1051217
  }
1050940
1051218
  for (const entry of entries) {
1050941
- const skillPath = entry.isDirectory() ? import_path57.default.join(dir, entry.name, "SKILL.md") : entry.name.endsWith(".md") ? import_path57.default.join(dir, entry.name) : "";
1050942
- if (!skillPath || !import_fs55.default.existsSync(skillPath)) continue;
1051219
+ const skillPath = entry.isDirectory() ? import_path58.default.join(dir, entry.name, "SKILL.md") : entry.name.endsWith(".md") ? import_path58.default.join(dir, entry.name) : "";
1051220
+ if (!skillPath || !import_fs56.default.existsSync(skillPath)) continue;
1050943
1051221
  const relPath = `skills/${entry.name}${entry.isDirectory() ? "/SKILL.md" : ""}`;
1050944
1051222
  let content;
1050945
1051223
  try {
1050946
- content = import_fs55.default.readFileSync(skillPath, "utf8");
1051224
+ content = import_fs56.default.readFileSync(skillPath, "utf8");
1050947
1051225
  } catch {
1050948
1051226
  continue;
1050949
1051227
  }
@@ -1050980,11 +1051258,11 @@ async function runSecurityScan() {
1050980
1051258
  }
1050981
1051259
  }
1050982
1051260
  configsScanned++;
1050983
- const configPath = import_path57.default.join(WORKSPACE_ROOT3, "config", "devos.config.json");
1050984
- if (import_fs55.default.existsSync(configPath)) {
1051261
+ const configPath = import_path58.default.join(WORKSPACE_ROOT3, "config", "devos.config.json");
1051262
+ if (import_fs56.default.existsSync(configPath)) {
1050985
1051263
  let config2 = "";
1050986
1051264
  try {
1050987
- config2 = import_fs55.default.readFileSync(configPath, "utf8");
1051265
+ config2 = import_fs56.default.readFileSync(configPath, "utf8");
1050988
1051266
  } catch {
1050989
1051267
  }
1050990
1051268
  if (config2 && RAW_KEY_PATTERN.test(config2)) {
@@ -1051004,11 +1051282,11 @@ async function runSecurityScan() {
1051004
1051282
  { name: "LESSONS.md", critical: false }
1051005
1051283
  ];
1051006
1051284
  for (const { name, critical } of sensitiveFiles) {
1051007
- const filePath = import_path57.default.join(WORKSPACE_ROOT3, "workspace", name);
1051008
- if (!import_fs55.default.existsSync(filePath)) continue;
1051285
+ const filePath = import_path58.default.join(WORKSPACE_ROOT3, "workspace", name);
1051286
+ if (!import_fs56.default.existsSync(filePath)) continue;
1051009
1051287
  let content = "";
1051010
1051288
  try {
1051011
- content = import_fs55.default.readFileSync(filePath, "utf8");
1051289
+ content = import_fs56.default.readFileSync(filePath, "utf8");
1051012
1051290
  } catch {
1051013
1051291
  continue;
1051014
1051292
  }
@@ -1051142,193 +1051420,8 @@ var AsyncTaskManager = class {
1051142
1051420
  };
1051143
1051421
  var asyncTasks = new AsyncTaskManager();
1051144
1051422
 
1051145
- // core/slashAsTool.ts
1051146
- var import_fs56 = __toESM(require("fs"));
1051147
- var import_path58 = __toESM(require("path"));
1051148
- var import_os5 = __toESM(require("os"));
1051149
- init_toolRegistry();
1051150
- init_conversationMemory();
1051151
- init_learningMemory();
1051152
- init_skillLoader();
1051153
- init_costTracker();
1051154
- init_goalTracker();
1051155
- init_providers();
1051156
- var LESSONS_PATH3 = import_path58.default.join(process.cwd(), "workspace", "LESSONS.md");
1051157
- function loadLessonsText() {
1051158
- try {
1051159
- if (import_fs56.default.existsSync(LESSONS_PATH3)) return import_fs56.default.readFileSync(LESSONS_PATH3, "utf-8").trim();
1051160
- } catch {
1051161
- }
1051162
- return "";
1051163
- }
1051164
- async function toolStatus(_2) {
1051165
- const uptimeSec = Math.floor(process.uptime());
1051166
- const ramMB = Math.round(process.memoryUsage().heapUsed / 1024 / 1024);
1051167
- const sessions = conversationMemory.getSessions().length;
1051168
- const lines = [
1051169
- "SYSTEM STATUS",
1051170
- `Uptime ${Math.floor(uptimeSec / 60)}m ${uptimeSec % 60}s`,
1051171
- `RAM ${ramMB} MB`,
1051172
- `Sessions ${sessions}`,
1051173
- `Platform ${import_os5.default.platform()} ${import_os5.default.arch()}`,
1051174
- `Node ${process.version}`
1051175
- ];
1051176
- return { success: true, output: lines.join("\n") };
1051177
- }
1051178
- async function toolAnalytics(_2) {
1051179
- const stats = learningMemory.getStats();
1051180
- const lines = [
1051181
- "LEARNING ANALYTICS",
1051182
- `Total tasks ${stats.total}`,
1051183
- `Success rate ${stats.successRate}%`,
1051184
- `Avg duration ${stats.avgDuration}ms`
1051185
- ];
1051186
- return { success: true, output: lines.join("\n") };
1051187
- }
1051188
- async function toolSpend(_2) {
1051189
- try {
1051190
- const summary = costTracker.getDailySummary();
1051191
- const byProvider = Object.entries(summary.byProvider || {}).map(([p, c]) => ` ${p}: $${c.toFixed(4)}`).join("\n");
1051192
- const lines = [
1051193
- `SPEND \u2014 ${summary.date}`,
1051194
- `Total $${summary.totalUSD.toFixed(4)}`,
1051195
- `User $${summary.userUSD.toFixed(4)}`,
1051196
- `System $${summary.systemUSD.toFixed(4)}`,
1051197
- byProvider ? `By provider:
1051198
- ${byProvider}` : ""
1051199
- ].filter(Boolean);
1051200
- return { success: true, output: lines.join("\n") };
1051201
- } catch {
1051202
- return { success: true, output: "Spend data unavailable." };
1051203
- }
1051204
- }
1051205
- async function toolMemoryShow(_2) {
1051206
- const facts = conversationMemory.getFacts();
1051207
- const history2 = conversationMemory.getRecentHistory();
1051208
- const lines = [
1051209
- "MEMORY FACTS",
1051210
- facts.lastFilesCreated.length ? `Files created : ${facts.lastFilesCreated.join(", ")}` : "",
1051211
- facts.lastSearchQueries.length ? `Last searches : ${facts.lastSearchQueries.join(", ")}` : "",
1051212
- facts.lastToolsUsed.length ? `Last tools : ${facts.lastToolsUsed.join(", ")}` : "",
1051213
- facts.mentionedEntities.length ? `Topics : ${facts.mentionedEntities.slice(-10).join(", ")}` : "",
1051214
- "",
1051215
- `Recent exchanges: ${history2.length}`,
1051216
- ...history2.slice(-3).map(
1051217
- (e) => e.userMessage ? ` User: ${e.userMessage.slice(0, 80)}` : ""
1051218
- ).filter(Boolean)
1051219
- ].filter((l2) => l2 !== void 0);
1051220
- return { success: true, output: lines.join("\n") };
1051221
- }
1051222
- async function toolLessons(_2) {
1051223
- const lessons = loadLessonsText();
1051224
- if (!lessons) return { success: true, output: "No lessons recorded yet." };
1051225
- return { success: true, output: `LESSONS (permanent failure rules):
1051226
- ${lessons}` };
1051227
- }
1051228
- async function toolSkillsList(_2) {
1051229
- const skills = skillLoader.loadAll();
1051230
- if (skills.length === 0) return { success: true, output: "No skills loaded." };
1051231
- const lines = [
1051232
- `SKILLS (${skills.length} loaded)`,
1051233
- ...skills.map((s) => ` ${s.name.padEnd(20)} ${s.description || ""}`)
1051234
- ];
1051235
- return { success: true, output: lines.join("\n") };
1051236
- }
1051237
- async function toolToolsList(_2) {
1051238
- const { TOOLS: TOOLS3 } = await Promise.resolve().then(() => (init_toolRegistry(), toolRegistry_exports));
1051239
- const names = Object.keys(TOOLS3).sort();
1051240
- return { success: true, output: `TOOLS (${names.length}):
1051241
- ${names.join(", ")}` };
1051242
- }
1051243
- async function toolWhoami(_2) {
1051244
- const cfg = loadConfig();
1051245
- const userName = cfg.userName || process.env.USERNAME || import_os5.default.userInfo().username || "User";
1051246
- const homeDir = import_os5.default.homedir();
1051247
- const lines = [
1051248
- "USER PROFILE",
1051249
- `Name ${userName}`,
1051250
- `Home ${homeDir}`,
1051251
- `Platform ${import_os5.default.platform()}`
1051252
- ];
1051253
- return { success: true, output: lines.join("\n") };
1051254
- }
1051255
- async function toolChannelsStatus(_2) {
1051256
- try {
1051257
- const cfg = loadConfig();
1051258
- const apis = cfg?.providers?.apis || [];
1051259
- const lines = [
1051260
- "PROVIDER CHANNELS",
1051261
- ...apis.map((api) => {
1051262
- const key2 = String(api.key || "");
1051263
- const hasKey = key2.startsWith("env:") ? !!(process.env[key2.replace("env:", "")] || "").trim() : key2.trim().length > 0;
1051264
- const status = !api.enabled ? "disabled" : api.rateLimited ? "rate-limited" : hasKey ? "active" : "no key";
1051265
- return ` ${(api.name || api.provider || "").padEnd(20)} ${api.model || ""} [${status}]`;
1051266
- })
1051267
- ];
1051268
- return { success: true, output: lines.join("\n") };
1051269
- } catch {
1051270
- return { success: true, output: "Provider status unavailable." };
1051271
- }
1051272
- }
1051273
- async function toolMemoryStore(input) {
1051274
- const fact = String(
1051275
- input?.fact || input?.content || input?.text || input?.preference || input?.value || input?.memory || input?.note || input?.data || input?.information || input?.detail || input?.message || input?.entry || input?.record || (input && typeof input === "object" ? Object.values(input).find((v) => typeof v === "string" && v.trim().length > 0) : "") || ""
1051276
- ).trim();
1051277
- if (!fact) return { success: false, output: 'No fact provided. Pass { fact: "the thing to remember" }' };
1051278
- const record2 = assignId({
1051279
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1051280
- type: input?.type ?? "fact",
1051281
- content: fact,
1051282
- summary: fact.slice(0, 100),
1051283
- tags: Array.isArray(input?.tags) ? input.tags : []
1051284
- });
1051285
- return { success: true, output: `Stored as ${record2.id}: ${record2.summary}` };
1051286
- }
1051287
- async function toolMemoryForget(input) {
1051288
- const keyword = String(
1051289
- input?.fact || input?.keyword || input?.content || input?.text || input?.query || input?.topic || input?.subject || (input && typeof input === "object" ? Object.values(input).find((v) => typeof v === "string" && v.trim().length > 0) : "") || ""
1051290
- ).trim().toLowerCase();
1051291
- if (!keyword)
1051292
- return { success: false, output: 'No keyword provided. Pass { fact: "thing to forget" }' };
1051293
- const removed = removeRecords(
1051294
- (r) => r.content.toLowerCase().includes(keyword) || r.summary.toLowerCase().includes(keyword)
1051295
- );
1051296
- if (removed === 0)
1051297
- return { success: true, output: `No memory entries matched "${keyword}".` };
1051298
- return { success: true, output: `Removed ${removed} memory entry(s) matching "${keyword}".` };
1051299
- }
1051300
- async function toolGoals(_2) {
1051301
- const summary = getActiveGoalsSummary();
1051302
- return { success: true, output: summary ? `ACTIVE GOALS:
1051303
- ${summary}` : "No active goals." };
1051304
- }
1051305
- var MIRROR_TOOLS = [
1051306
- { name: "status", description: "Show system status: uptime, RAM, session count", fn: toolStatus },
1051307
- { name: "analytics", description: "Show learning analytics: task count, success rate", fn: toolAnalytics },
1051308
- { name: "spend", description: "Show today's token cost and spend by provider", fn: toolSpend },
1051309
- { name: "memory_show", description: "Show conversation memory facts and recent history", fn: toolMemoryShow },
1051310
- { name: "memory_store", description: 'Persist a fact or preference to permanent memory (records.jsonl) right now. Pass { fact: "..." }', fn: toolMemoryStore },
1051311
- { name: "memory_forget", description: 'Remove a fact or preference from permanent memory (records.jsonl). Pass { fact: "thing to forget" }', fn: toolMemoryForget },
1051312
- { name: "lessons", description: "Show permanent failure rules learned from past tasks", fn: toolLessons },
1051313
- { name: "skills_list", description: "List all loaded skills with descriptions", fn: toolSkillsList },
1051314
- { name: "tools_list", description: "List all registered tool names", fn: toolToolsList },
1051315
- { name: "whoami", description: "Show current user profile: name, home dir, platform", fn: toolWhoami },
1051316
- { name: "channels_status", description: "Show provider channel status: active, disabled, no-key", fn: toolChannelsStatus },
1051317
- { name: "goals", description: "Show currently active goals", fn: toolGoals }
1051318
- ];
1051319
- var SLASH_MIRROR_TOOL_NAMES = MIRROR_TOOLS.map((t) => t.name);
1051320
- function registerSlashMirrorTools() {
1051321
- const isDebug = (process.env.AIDEN_LOG_LEVEL || "info") === "debug";
1051322
- for (const { name, description, fn } of MIRROR_TOOLS) {
1051323
- registerExternalTool(name, fn, "slash-mirror");
1051324
- if (isDebug) {
1051325
- console.log("[SlashAsTool] Registered mirror tool: " + name + " \u2014 " + description);
1051326
- }
1051327
- }
1051328
- if (!isDebug) {
1051329
- console.log("[SlashAsTool] Registered " + MIRROR_TOOLS.length + " mirror tools (AIDEN_LOG_LEVEL=debug for detail)");
1051330
- }
1051331
- }
1051423
+ // api/server.ts
1051424
+ init_slashAsTool();
1051332
1051425
 
1051333
1051426
  // core/memoryPreamble.ts
1051334
1051427
  var import_fs57 = __toESM(require("fs"));
@@ -1058877,7 +1058970,14 @@ ${cognitionHint}${memoryContext}${greetingPreamble}${sessionContext}${memoryInde
1058877
1058970
  }
1058878
1058971
  }
1058879
1058972
  console.error("[Router] All providers failed. Last error:", err?.message ?? "unknown");
1058880
- send({ token: buildDiagnostic({ tool: "respond", provider: "all", retries: 2, error: "All AI providers failed or are at capacity", suggestion: "Try again in a few minutes, or add more API keys in Settings \u2192 API Keys." }), done: false, provider: "error" });
1058973
+ const poolDiag = diagnoseProviderPool();
1058974
+ send({ token: buildDiagnostic({
1058975
+ tool: "respond",
1058976
+ provider: "all",
1058977
+ retries: 2,
1058978
+ error: poolDiag.state === "unconfigured" ? "No API keys configured" : "All AI providers failed or are at capacity",
1058979
+ suggestion: poolDiag.state === "unconfigured" ? "Add API keys in Settings > API Keys, or start Ollama for local inference." : "Try again in a few minutes, or add more API keys in Settings > API Keys."
1058980
+ }), done: false, provider: "error" });
1058881
1058981
  }
1058882
1058982
  streamEnded = true;
1058883
1058983
  clearTimeout(timeout);