aiden-runtime 3.19.7 → 3.19.9

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.
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "gpu": "NVIDIA GeForce GTX 1060 6GB",
3
3
  "vramGB": 6,
4
- "ramGB": 16,
4
+ "ramGB": 32,
5
5
  "platform": "windows",
6
6
  "cudaAvailable": true,
7
7
  "appleSilicon": false,
8
- "detectedAt": "2026-05-01T19:50:20.289Z"
8
+ "detectedAt": "2026-05-03T13:08:55.885Z"
9
9
  }
@@ -358,6 +358,17 @@ function handleChatError(err, apiName, send) {
358
358
  }
359
359
  // Workspace root — AIDEN_USER_DATA in packaged Electron, cwd in dev
360
360
  const WORKSPACE_ROOT = process.env.AIDEN_USER_DATA || process.cwd();
361
+ // Package root — where workspace-templates/ ships inside the npm tarball.
362
+ // In esbuild bundle (dist-bundle/index.js): __dirname = <pkg>/dist-bundle/ → parent is <pkg>
363
+ // In tsc output (dist/api/server.js): __dirname = <pkg>/dist/api/ → grandparent is <pkg>
364
+ // C22: needed because WORKSPACE_ROOT may differ from the npm install dir.
365
+ const _pkgCandidate1 = path.join(__dirname, '..');
366
+ const _pkgCandidate2 = path.join(__dirname, '..', '..');
367
+ const PACKAGE_ROOT = fs.existsSync(path.join(_pkgCandidate1, 'workspace-templates'))
368
+ ? _pkgCandidate1
369
+ : fs.existsSync(path.join(_pkgCandidate2, 'workspace-templates'))
370
+ ? _pkgCandidate2
371
+ : WORKSPACE_ROOT; // dev mode: cwd has workspace-templates
361
372
  // Per-session soul hash for Option-B protected-context injection.
362
373
  // First turn: undefined → full SOUL inject. Subsequent turns: compare → emit
363
374
  // reference line when unchanged, re-inject when SOUL.md edited on disk.
@@ -395,19 +406,56 @@ function initWorkspaceDefaults() {
395
406
  }
396
407
  }
397
408
  // Copy permissions.yaml from template if not present
409
+ // C22: Source from PACKAGE_ROOT (npm install dir), dest to WORKSPACE_ROOT (user data)
398
410
  const permTarget = path.join(WORKSPACE_ROOT, 'workspace', 'permissions.yaml');
399
- const permTemplate = path.join(WORKSPACE_ROOT, 'workspace-templates', 'permissions.yaml');
411
+ const permTemplate = path.join(PACKAGE_ROOT, 'workspace-templates', 'permissions.yaml');
400
412
  if (!fs.existsSync(permTarget) && fs.existsSync(permTemplate)) {
401
413
  fs.copyFileSync(permTemplate, permTarget);
402
414
  console.log('[init] Created workspace/permissions.yaml from template');
403
415
  }
404
416
  // C21: Copy SOUL.md from template if not present (Ollama identity)
417
+ // C22: Source from PACKAGE_ROOT (npm install dir), dest to WORKSPACE_ROOT (user data)
405
418
  const soulTarget = path.join(WORKSPACE_ROOT, 'workspace', 'SOUL.md');
406
- const soulTemplate = path.join(WORKSPACE_ROOT, 'workspace-templates', 'SOUL.md');
419
+ const soulTemplate = path.join(PACKAGE_ROOT, 'workspace-templates', 'SOUL.md');
407
420
  if (!fs.existsSync(soulTarget) && fs.existsSync(soulTemplate)) {
408
421
  fs.copyFileSync(soulTemplate, soulTarget);
409
422
  console.log('[init] Created workspace/SOUL.md from template');
410
423
  }
424
+ // C22: Copy bundled starter skills from workspace-templates/ on first boot.
425
+ // Source from PACKAGE_ROOT (npm install dir), dest to WORKSPACE_ROOT (user data).
426
+ // Idempotent — skips if skills already exist.
427
+ const skillTemplateSrc = path.join(PACKAGE_ROOT, 'workspace-templates', 'skills');
428
+ const skillDst = path.join(WORKSPACE_ROOT, 'workspace', 'skills', 'learned');
429
+ if (fs.existsSync(skillTemplateSrc)) {
430
+ const hasExisting = (() => {
431
+ try {
432
+ return fs.readdirSync(skillDst, { withFileTypes: true })
433
+ .some(e => e.isDirectory() && fs.existsSync(path.join(skillDst, e.name, 'SKILL.md')));
434
+ }
435
+ catch {
436
+ return false;
437
+ }
438
+ })();
439
+ if (!hasExisting) {
440
+ let copied = 0;
441
+ try {
442
+ const entries = fs.readdirSync(skillTemplateSrc, { withFileTypes: true }).filter(e => e.isDirectory());
443
+ for (const entry of entries) {
444
+ const from = path.join(skillTemplateSrc, entry.name);
445
+ const to = path.join(skillDst, entry.name);
446
+ if (!fs.existsSync(to)) {
447
+ fs.cpSync(from, to, { recursive: true });
448
+ copied++;
449
+ }
450
+ }
451
+ }
452
+ catch (e) {
453
+ console.warn(`[init] Skill template copy error: ${e.message}`);
454
+ }
455
+ if (copied > 0)
456
+ console.log(`[init] Copied ${copied} starter skills from templates`);
457
+ }
458
+ }
411
459
  }
412
460
  initWorkspaceDefaults();
413
461
  // ── Knowledge upload — multer + progress tracking ─────────────
@@ -5700,16 +5748,36 @@ function startupCheck() {
5700
5748
  function startApiServer(portArg) {
5701
5749
  // ── Redirect all diagnostic output to stderr ─────────────────────────────
5702
5750
  // The CLI writes the streaming response to process.stdout character-by-character.
5703
- // If console.log also writes to stdout (the default), server logs physically
5704
- // interleave with rendered tokens in the same terminal, producing output like:
5705
- // "I'm back. What's up, sh[Router] planner: groq-1...iva?"
5706
- // Sending ALL diagnostic output to stderr prevents this regardless of how the
5707
- // user runs the server (same terminal, background process, pipe, etc.).
5708
- // console.error already targets stderr — leave it alone.
5709
- const _toStderr = (...args) => process.stderr.write(args.map(String).join(' ') + '\n');
5710
- console.log = _toStderr;
5711
- console.info = _toStderr;
5712
- console.warn = _toStderr;
5751
+ // ── C23: Level-aware log gate ──────────────────────────────────
5752
+ // Levels: debug=0, info=1, warn=2, error=3, silent=4
5753
+ // Default: 'warn' in CLI mode (AIDEN_CLI_MODE=1), 'info' otherwise.
5754
+ // Users opt in to verbose: AIDEN_LOG_LEVEL=debug npx aiden-os
5755
+ // Full logger rewrite is v3.20 Investigation C scope.
5756
+ const _LOG_LEVELS = {
5757
+ debug: 0, info: 1, warn: 2, error: 3, silent: 4,
5758
+ };
5759
+ const _cliMode = process.env.AIDEN_CLI_MODE === '1';
5760
+ const _defaultLvl = _cliMode ? 'warn' : 'info';
5761
+ const _envLvl = (process.env.AIDEN_LOG_LEVEL || _defaultLvl).toLowerCase();
5762
+ const _minLevel = _LOG_LEVELS[_envLvl] ?? _LOG_LEVELS.warn;
5763
+ const _bracketRe = /^\[[\w$:]+\]/;
5764
+ function _gatedLog(level, ...args) {
5765
+ if (level >= _minLevel) {
5766
+ process.stderr.write(args.map(String).join(' ') + '\n');
5767
+ return;
5768
+ }
5769
+ // Below threshold: suppress bracket-prefixed diagnostic lines.
5770
+ // Non-prefixed console.log (user-facing output) passes through.
5771
+ const first = typeof args[0] === 'string' ? args[0] : '';
5772
+ if (_bracketRe.test(first))
5773
+ return;
5774
+ process.stderr.write(args.map(String).join(' ') + '\n');
5775
+ }
5776
+ console.log = (...args) => _gatedLog(_LOG_LEVELS.info, ...args);
5777
+ console.info = (...args) => _gatedLog(_LOG_LEVELS.info, ...args);
5778
+ // console.warn always writes — warnings indicate real issues users should see.
5779
+ console.warn = (...args) => process.stderr.write(args.map(String).join(' ') + '\n');
5780
+ // console.error left untouched — already targets stderr
5713
5781
  // Read port from config/api.json with sensible fallback.
5714
5782
  // Host defaults to 127.0.0.1 (loopback only) for security.
5715
5783
  // Set AIDEN_HOST=0.0.0.0 to expose on all interfaces (e.g. headless/WSL2).
@@ -43,7 +43,6 @@ class LivePulse extends events_1.EventEmitter {
43
43
  // ── Public methods — all wrapped in try-catch so they NEVER throw ──
44
44
  act(agent, message, missionId) {
45
45
  try {
46
- console.log(`[${agent}] ${message}`);
47
46
  this.emit_event({ type: 'act', agent, message, timestamp: Date.now(), missionId });
48
47
  }
49
48
  catch {
@@ -52,7 +51,6 @@ class LivePulse extends events_1.EventEmitter {
52
51
  }
53
52
  done(agent, message, missionId) {
54
53
  try {
55
- console.log(`[${agent}] ✓ ${message}`);
56
54
  this.emit_event({ type: 'done', agent, message, timestamp: Date.now(), missionId });
57
55
  }
58
56
  catch {
@@ -71,7 +69,6 @@ class LivePulse extends events_1.EventEmitter {
71
69
  }
72
70
  warn(agent, message, missionId) {
73
71
  try {
74
- console.warn(`[${agent}] ⚠ ${message}`);
75
72
  this.emit_event({ type: 'warn', agent, message, timestamp: Date.now(), missionId });
76
73
  }
77
74
  catch {
@@ -80,7 +77,6 @@ class LivePulse extends events_1.EventEmitter {
80
77
  }
81
78
  info(agent, message, missionId) {
82
79
  try {
83
- console.log(`[${agent}] ℹ ${message}`);
84
80
  this.emit_event({ type: 'info', agent, message, timestamp: Date.now(), missionId });
85
81
  }
86
82
  catch {
@@ -89,7 +85,6 @@ class LivePulse extends events_1.EventEmitter {
89
85
  }
90
86
  thinking(agent, message, missionId) {
91
87
  try {
92
- console.log(`[${agent}] 💭 ${message}`);
93
88
  this.emit_event({ type: 'thinking', agent, message, timestamp: Date.now(), missionId });
94
89
  }
95
90
  catch {
@@ -101,7 +96,6 @@ class LivePulse extends events_1.EventEmitter {
101
96
  const message = output
102
97
  ? `${toolName}: ${command} → ${output.slice(0, 120)}`
103
98
  : `${toolName}: ${command}`;
104
- console.log(`[${agent}] 🔧 ${message}`);
105
99
  this.emit_event({
106
100
  type: 'tool',
107
101
  agent,
@@ -192,25 +192,24 @@ class SkillLoader {
192
192
  // Check built-in skills, workspace skills, and self-learned/promoted skills.
193
193
  // NOTE: skills/learned/pending/ is intentionally excluded — pending skills
194
194
  // are never auto-loaded; they require explicit /skills approve first.
195
+ // C22: Use AIDEN_USER_DATA (set by npx launcher) so SkillLoader reads
196
+ // from the same workspace root that initWorkspaceDefaults() writes to.
197
+ const root = process.env.AIDEN_USER_DATA || process.cwd();
198
+ // C24: Do NOT filter by existsSync here — the singleton is created at
199
+ // import time, before initWorkspaceDefaults() copies templates. loadAll()
200
+ // wraps readdirSync in try/catch, so non-existent dirs are safe.
195
201
  this.skillsDirs = [
196
- path_1.default.join(process.cwd(), 'skills'),
197
- path_1.default.join(process.cwd(), 'workspace', 'skills'),
198
- path_1.default.join(process.cwd(), 'workspace', 'skills', 'learned'),
199
- path_1.default.join(process.cwd(), 'workspace', 'skills', 'approved'),
202
+ path_1.default.join(root, 'skills'),
203
+ path_1.default.join(root, 'workspace', 'skills'),
204
+ path_1.default.join(root, 'workspace', 'skills', 'learned'),
205
+ path_1.default.join(root, 'workspace', 'skills', 'approved'),
200
206
  // Workspace-level installed skills (written by skillRegistry.ts)
201
- path_1.default.join(process.cwd(), 'workspace', 'skills', 'installed'),
207
+ path_1.default.join(root, 'workspace', 'skills', 'installed'),
202
208
  // A2/A3 approved drafts
203
- path_1.default.join(process.cwd(), 'skills', 'learned', 'approved'),
209
+ path_1.default.join(root, 'skills', 'learned', 'approved'),
204
210
  // A4 library-installed skills
205
- path_1.default.join(process.cwd(), 'skills', 'installed'),
206
- ].filter(d => {
207
- try {
208
- return fs_1.default.existsSync(d);
209
- }
210
- catch {
211
- return false;
212
- }
213
- });
211
+ path_1.default.join(root, 'skills', 'installed'),
212
+ ];
214
213
  }
215
214
  // loadAllRaw — bypasses the disabled-skills filter
216
215
  // Used by GET /api/skills so the UI can show disabled skills too
@@ -2,4 +2,4 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VERSION = void 0;
4
4
  // AUTO-GENERATED by scripts/inject-version.js — do not edit by hand
5
- exports.VERSION = '3.19.7';
5
+ exports.VERSION = '3.19.9';
@@ -208,7 +208,7 @@ var init_updateCheck = __esm({
208
208
  var VERSION;
209
209
  var init_version = __esm({
210
210
  "core/version.ts"() {
211
- VERSION = "3.19.7";
211
+ VERSION = "3.19.9";
212
212
  }
213
213
  });
214
214
 
@@ -23684,14 +23684,12 @@ var init_livePulse = __esm({
23684
23684
  // ── Public methods — all wrapped in try-catch so they NEVER throw ──
23685
23685
  act(agent, message, missionId) {
23686
23686
  try {
23687
- console.log(`[${agent}] ${message}`);
23688
23687
  this.emit_event({ type: "act", agent, message, timestamp: Date.now(), missionId });
23689
23688
  } catch {
23690
23689
  }
23691
23690
  }
23692
23691
  done(agent, message, missionId) {
23693
23692
  try {
23694
- console.log(`[${agent}] \u2713 ${message}`);
23695
23693
  this.emit_event({ type: "done", agent, message, timestamp: Date.now(), missionId });
23696
23694
  } catch {
23697
23695
  }
@@ -23706,21 +23704,18 @@ var init_livePulse = __esm({
23706
23704
  }
23707
23705
  warn(agent, message, missionId) {
23708
23706
  try {
23709
- console.warn(`[${agent}] \u26A0 ${message}`);
23710
23707
  this.emit_event({ type: "warn", agent, message, timestamp: Date.now(), missionId });
23711
23708
  } catch {
23712
23709
  }
23713
23710
  }
23714
23711
  info(agent, message, missionId) {
23715
23712
  try {
23716
- console.log(`[${agent}] \u2139 ${message}`);
23717
23713
  this.emit_event({ type: "info", agent, message, timestamp: Date.now(), missionId });
23718
23714
  } catch {
23719
23715
  }
23720
23716
  }
23721
23717
  thinking(agent, message, missionId) {
23722
23718
  try {
23723
- console.log(`[${agent}] \u{1F4AD} ${message}`);
23724
23719
  this.emit_event({ type: "thinking", agent, message, timestamp: Date.now(), missionId });
23725
23720
  } catch {
23726
23721
  }
@@ -23728,7 +23723,6 @@ var init_livePulse = __esm({
23728
23723
  tool(agent, toolName, command, output) {
23729
23724
  try {
23730
23725
  const message = output ? `${toolName}: ${command} \u2192 ${output.slice(0, 120)}` : `${toolName}: ${command}`;
23731
- console.log(`[${agent}] \u{1F527} ${message}`);
23732
23726
  this.emit_event({
23733
23727
  type: "tool",
23734
23728
  agent,
@@ -24903,24 +24897,19 @@ var init_skillLoader = __esm({
24903
24897
  SkillLoader = class {
24904
24898
  constructor() {
24905
24899
  this.cache = null;
24900
+ const root = process.env.AIDEN_USER_DATA || process.cwd();
24906
24901
  this.skillsDirs = [
24907
- import_path12.default.join(process.cwd(), "skills"),
24908
- import_path12.default.join(process.cwd(), "workspace", "skills"),
24909
- import_path12.default.join(process.cwd(), "workspace", "skills", "learned"),
24910
- import_path12.default.join(process.cwd(), "workspace", "skills", "approved"),
24902
+ import_path12.default.join(root, "skills"),
24903
+ import_path12.default.join(root, "workspace", "skills"),
24904
+ import_path12.default.join(root, "workspace", "skills", "learned"),
24905
+ import_path12.default.join(root, "workspace", "skills", "approved"),
24911
24906
  // Workspace-level installed skills (written by skillRegistry.ts)
24912
- import_path12.default.join(process.cwd(), "workspace", "skills", "installed"),
24907
+ import_path12.default.join(root, "workspace", "skills", "installed"),
24913
24908
  // A2/A3 approved drafts
24914
- import_path12.default.join(process.cwd(), "skills", "learned", "approved"),
24909
+ import_path12.default.join(root, "skills", "learned", "approved"),
24915
24910
  // A4 library-installed skills
24916
- import_path12.default.join(process.cwd(), "skills", "installed")
24917
- ].filter((d) => {
24918
- try {
24919
- return import_fs11.default.existsSync(d);
24920
- } catch {
24921
- return false;
24922
- }
24923
- });
24911
+ import_path12.default.join(root, "skills", "installed")
24912
+ ];
24924
24913
  }
24925
24914
  // loadAllRaw — bypasses the disabled-skills filter
24926
24915
  // Used by GET /api/skills so the UI can show disabled skills too
@@ -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.7";
26653
+ VERSION = "3.19.9";
26654
26654
  }
26655
26655
  });
26656
26656
 
@@ -26781,14 +26781,12 @@ var init_livePulse = __esm({
26781
26781
  // ── Public methods — all wrapped in try-catch so they NEVER throw ──
26782
26782
  act(agent, message, missionId) {
26783
26783
  try {
26784
- console.log(`[${agent}] ${message}`);
26785
26784
  this.emit_event({ type: "act", agent, message, timestamp: Date.now(), missionId });
26786
26785
  } catch {
26787
26786
  }
26788
26787
  }
26789
26788
  done(agent, message, missionId) {
26790
26789
  try {
26791
- console.log(`[${agent}] \u2713 ${message}`);
26792
26790
  this.emit_event({ type: "done", agent, message, timestamp: Date.now(), missionId });
26793
26791
  } catch {
26794
26792
  }
@@ -26803,21 +26801,18 @@ var init_livePulse = __esm({
26803
26801
  }
26804
26802
  warn(agent, message, missionId) {
26805
26803
  try {
26806
- console.warn(`[${agent}] \u26A0 ${message}`);
26807
26804
  this.emit_event({ type: "warn", agent, message, timestamp: Date.now(), missionId });
26808
26805
  } catch {
26809
26806
  }
26810
26807
  }
26811
26808
  info(agent, message, missionId) {
26812
26809
  try {
26813
- console.log(`[${agent}] \u2139 ${message}`);
26814
26810
  this.emit_event({ type: "info", agent, message, timestamp: Date.now(), missionId });
26815
26811
  } catch {
26816
26812
  }
26817
26813
  }
26818
26814
  thinking(agent, message, missionId) {
26819
26815
  try {
26820
- console.log(`[${agent}] \u{1F4AD} ${message}`);
26821
26816
  this.emit_event({ type: "thinking", agent, message, timestamp: Date.now(), missionId });
26822
26817
  } catch {
26823
26818
  }
@@ -26825,7 +26820,6 @@ var init_livePulse = __esm({
26825
26820
  tool(agent, toolName, command2, output) {
26826
26821
  try {
26827
26822
  const message = output ? `${toolName}: ${command2} \u2192 ${output.slice(0, 120)}` : `${toolName}: ${command2}`;
26828
- console.log(`[${agent}] \u{1F527} ${message}`);
26829
26823
  this.emit_event({
26830
26824
  type: "tool",
26831
26825
  agent,
@@ -99137,24 +99131,19 @@ var init_skillLoader = __esm({
99137
99131
  SkillLoader = class {
99138
99132
  constructor() {
99139
99133
  this.cache = null;
99134
+ const root = process.env.AIDEN_USER_DATA || process.cwd();
99140
99135
  this.skillsDirs = [
99141
- import_path15.default.join(process.cwd(), "skills"),
99142
- import_path15.default.join(process.cwd(), "workspace", "skills"),
99143
- import_path15.default.join(process.cwd(), "workspace", "skills", "learned"),
99144
- import_path15.default.join(process.cwd(), "workspace", "skills", "approved"),
99136
+ import_path15.default.join(root, "skills"),
99137
+ import_path15.default.join(root, "workspace", "skills"),
99138
+ import_path15.default.join(root, "workspace", "skills", "learned"),
99139
+ import_path15.default.join(root, "workspace", "skills", "approved"),
99145
99140
  // Workspace-level installed skills (written by skillRegistry.ts)
99146
- import_path15.default.join(process.cwd(), "workspace", "skills", "installed"),
99141
+ import_path15.default.join(root, "workspace", "skills", "installed"),
99147
99142
  // A2/A3 approved drafts
99148
- import_path15.default.join(process.cwd(), "skills", "learned", "approved"),
99143
+ import_path15.default.join(root, "skills", "learned", "approved"),
99149
99144
  // A4 library-installed skills
99150
- import_path15.default.join(process.cwd(), "skills", "installed")
99151
- ].filter((d) => {
99152
- try {
99153
- return import_fs14.default.existsSync(d);
99154
- } catch {
99155
- return false;
99156
- }
99157
- });
99145
+ import_path15.default.join(root, "skills", "installed")
99146
+ ];
99158
99147
  }
99159
99148
  // loadAllRaw — bypasses the disabled-skills filter
99160
99149
  // Used by GET /api/skills so the UI can show disabled skills too
@@ -1053403,6 +1053392,9 @@ function handleChatError(err, apiName, send) {
1053403
1053392
  send({ done: true });
1053404
1053393
  }
1053405
1053394
  var WORKSPACE_ROOT4 = process.env.AIDEN_USER_DATA || process.cwd();
1053395
+ var _pkgCandidate1 = path73.join(__dirname, "..");
1053396
+ var _pkgCandidate2 = path73.join(__dirname, "..", "..");
1053397
+ var PACKAGE_ROOT = fs70.existsSync(path73.join(_pkgCandidate1, "workspace-templates")) ? _pkgCandidate1 : fs70.existsSync(path73.join(_pkgCandidate2, "workspace-templates")) ? _pkgCandidate2 : WORKSPACE_ROOT4;
1053406
1053398
  var soulHashBySession2 = /* @__PURE__ */ new Map();
1053407
1053399
  function initWorkspaceDefaults() {
1053408
1053400
  const dirs = [
@@ -1053441,17 +1053433,45 @@ function initWorkspaceDefaults() {
1053441
1053433
  }
1053442
1053434
  }
1053443
1053435
  const permTarget = path73.join(WORKSPACE_ROOT4, "workspace", "permissions.yaml");
1053444
- const permTemplate = path73.join(WORKSPACE_ROOT4, "workspace-templates", "permissions.yaml");
1053436
+ const permTemplate = path73.join(PACKAGE_ROOT, "workspace-templates", "permissions.yaml");
1053445
1053437
  if (!fs70.existsSync(permTarget) && fs70.existsSync(permTemplate)) {
1053446
1053438
  fs70.copyFileSync(permTemplate, permTarget);
1053447
1053439
  console.log("[init] Created workspace/permissions.yaml from template");
1053448
1053440
  }
1053449
1053441
  const soulTarget = path73.join(WORKSPACE_ROOT4, "workspace", "SOUL.md");
1053450
- const soulTemplate = path73.join(WORKSPACE_ROOT4, "workspace-templates", "SOUL.md");
1053442
+ const soulTemplate = path73.join(PACKAGE_ROOT, "workspace-templates", "SOUL.md");
1053451
1053443
  if (!fs70.existsSync(soulTarget) && fs70.existsSync(soulTemplate)) {
1053452
1053444
  fs70.copyFileSync(soulTemplate, soulTarget);
1053453
1053445
  console.log("[init] Created workspace/SOUL.md from template");
1053454
1053446
  }
1053447
+ const skillTemplateSrc = path73.join(PACKAGE_ROOT, "workspace-templates", "skills");
1053448
+ const skillDst = path73.join(WORKSPACE_ROOT4, "workspace", "skills", "learned");
1053449
+ if (fs70.existsSync(skillTemplateSrc)) {
1053450
+ const hasExisting = (() => {
1053451
+ try {
1053452
+ return fs70.readdirSync(skillDst, { withFileTypes: true }).some((e) => e.isDirectory() && fs70.existsSync(path73.join(skillDst, e.name, "SKILL.md")));
1053453
+ } catch {
1053454
+ return false;
1053455
+ }
1053456
+ })();
1053457
+ if (!hasExisting) {
1053458
+ let copied = 0;
1053459
+ try {
1053460
+ const entries = fs70.readdirSync(skillTemplateSrc, { withFileTypes: true }).filter((e) => e.isDirectory());
1053461
+ for (const entry of entries) {
1053462
+ const from = path73.join(skillTemplateSrc, entry.name);
1053463
+ const to = path73.join(skillDst, entry.name);
1053464
+ if (!fs70.existsSync(to)) {
1053465
+ fs70.cpSync(from, to, { recursive: true });
1053466
+ copied++;
1053467
+ }
1053468
+ }
1053469
+ } catch (e) {
1053470
+ console.warn(`[init] Skill template copy error: ${e.message}`);
1053471
+ }
1053472
+ if (copied > 0) console.log(`[init] Copied ${copied} starter skills from templates`);
1053473
+ }
1053474
+ }
1053455
1053475
  }
1053456
1053476
  initWorkspaceDefaults();
1053457
1053477
  var KB_UPLOAD_DIR = path73.join(WORKSPACE_ROOT4, "workspace", "knowledge", "uploads");
@@ -1058197,10 +1058217,30 @@ function startupCheck() {
1058197
1058217
  }
1058198
1058218
  }
1058199
1058219
  function startApiServer(portArg) {
1058200
- const _toStderr = (...args) => process.stderr.write(args.map(String).join(" ") + "\n");
1058201
- console.log = _toStderr;
1058202
- console.info = _toStderr;
1058203
- console.warn = _toStderr;
1058220
+ const _LOG_LEVELS = {
1058221
+ debug: 0,
1058222
+ info: 1,
1058223
+ warn: 2,
1058224
+ error: 3,
1058225
+ silent: 4
1058226
+ };
1058227
+ const _cliMode = process.env.AIDEN_CLI_MODE === "1";
1058228
+ const _defaultLvl = _cliMode ? "warn" : "info";
1058229
+ const _envLvl = (process.env.AIDEN_LOG_LEVEL || _defaultLvl).toLowerCase();
1058230
+ const _minLevel = _LOG_LEVELS[_envLvl] ?? _LOG_LEVELS.warn;
1058231
+ const _bracketRe = /^\[[\w$:]+\]/;
1058232
+ function _gatedLog(level, ...args) {
1058233
+ if (level >= _minLevel) {
1058234
+ process.stderr.write(args.map(String).join(" ") + "\n");
1058235
+ return;
1058236
+ }
1058237
+ const first = typeof args[0] === "string" ? args[0] : "";
1058238
+ if (_bracketRe.test(first)) return;
1058239
+ process.stderr.write(args.map(String).join(" ") + "\n");
1058240
+ }
1058241
+ console.log = (...args) => _gatedLog(_LOG_LEVELS.info, ...args);
1058242
+ console.info = (...args) => _gatedLog(_LOG_LEVELS.info, ...args);
1058243
+ console.warn = (...args) => process.stderr.write(args.map(String).join(" ") + "\n");
1058204
1058244
  let port = portArg ?? 4200;
1058205
1058245
  const isHeadless = process.env.AIDEN_HEADLESS === "true";
1058206
1058246
  let host = process.env.AIDEN_HOST || (isHeadless ? "0.0.0.0" : "127.0.0.1");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aiden-runtime",
3
- "version": "3.19.7",
3
+ "version": "3.19.9",
4
4
  "description": "Autonomous AI Operating System — Local, Private, Free. Runs on your machine with Ollama.",
5
5
  "author": "Taracod <hello@taracod.com>",
6
6
  "license": "AGPL-3.0-only",