@aman_asmuei/aman-agent 0.26.0 → 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1387,18 +1387,18 @@ var McpManager = class {
1387
1387
 
1388
1388
  // src/agent.ts
1389
1389
  import * as readline from "readline";
1390
- import fs19 from "fs";
1391
- import path19 from "path";
1392
- import os18 from "os";
1390
+ import fs20 from "fs";
1391
+ import path20 from "path";
1392
+ import os19 from "os";
1393
1393
  import pc7 from "picocolors";
1394
1394
  import { marked } from "marked";
1395
1395
  import { markedTerminal } from "marked-terminal";
1396
1396
  import logUpdate from "log-update";
1397
1397
 
1398
1398
  // src/commands.ts
1399
- import fs16 from "fs";
1400
- import path16 from "path";
1401
- import os15 from "os";
1399
+ import fs17 from "fs";
1400
+ import path17 from "path";
1401
+ import os16 from "os";
1402
1402
  import { execFileSync as execFileSync3 } from "child_process";
1403
1403
  import pc5 from "picocolors";
1404
1404
 
@@ -2361,9 +2361,9 @@ import pc3 from "picocolors";
2361
2361
  // src/hooks.ts
2362
2362
  import pc2 from "picocolors";
2363
2363
  import * as p2 from "@clack/prompts";
2364
- import fs13 from "fs";
2365
- import path13 from "path";
2366
- import os12 from "os";
2364
+ import fs14 from "fs";
2365
+ import path14 from "path";
2366
+ import os13 from "os";
2367
2367
 
2368
2368
  // src/personality.ts
2369
2369
  var FRUSTRATION_SIGNALS = [
@@ -2524,13 +2524,19 @@ function formatWellbeingNudge(state) {
2524
2524
  if (!state.wellbeingNudge) return null;
2525
2525
  return WELLBEING_NUDGES[state.wellbeingNudge] || null;
2526
2526
  }
2527
- async function syncPersonalityToCore(state, mcpManager) {
2527
+ async function syncPersonalityToCore(state, mcpManager, modelMetrics) {
2528
2528
  try {
2529
- await mcpManager.callTool("identity_update_dynamics", {
2529
+ const payload = {
2530
2530
  currentRead: state.currentRead,
2531
2531
  energy: state.energy,
2532
2532
  activeMode: state.activeMode
2533
- });
2533
+ };
2534
+ if (modelMetrics) {
2535
+ payload.trust = `${(modelMetrics.trustScore * 100).toFixed(0)}%`;
2536
+ payload.sessions = modelMetrics.totalSessions;
2537
+ payload.sentimentTrend = modelMetrics.sentimentTrend;
2538
+ }
2539
+ await mcpManager.callTool("identity_update_dynamics", payload);
2534
2540
  } catch (err) {
2535
2541
  log.debug("personality", "identity_update_dynamics failed", err);
2536
2542
  }
@@ -3200,6 +3206,258 @@ async function appendRejection(candidate, postmortemFilename, rejectionsPath) {
3200
3206
  }
3201
3207
  }
3202
3208
 
3209
+ // src/user-model.ts
3210
+ import fs13 from "fs/promises";
3211
+ import path13 from "path";
3212
+ import os12 from "os";
3213
+ var MAX_SESSIONS = 30;
3214
+ var TRUST_ALPHA = 0.3;
3215
+ var MIN_SESSIONS_FOR_FEED_FORWARD = 5;
3216
+ var MIN_SESSIONS_FOR_CORRELATIONS = 10;
3217
+ function defaultModelPath() {
3218
+ return path13.join(os12.homedir(), ".acore", "user-model.json");
3219
+ }
3220
+ function createEmptyModel() {
3221
+ const now = (/* @__PURE__ */ new Date()).toISOString();
3222
+ return {
3223
+ version: 1,
3224
+ sessions: [],
3225
+ profile: emptyProfile(),
3226
+ createdAt: now,
3227
+ updatedAt: now
3228
+ };
3229
+ }
3230
+ function emptyProfile() {
3231
+ return {
3232
+ trustScore: 0.5,
3233
+ trustTrajectory: "stable",
3234
+ totalSessions: 0,
3235
+ preferredTimePeriod: "afternoon",
3236
+ energyDistribution: {},
3237
+ avgSessionMinutes: 0,
3238
+ baselineFrustration: 0,
3239
+ baselineExcitement: 0,
3240
+ sentimentTrend: "stable",
3241
+ frustrationCorrelations: { toolErrors: 0, longSessions: 0, lateNight: 0 },
3242
+ avgTurnsPerSession: 0,
3243
+ engagementTrend: "stable",
3244
+ nudgeStats: {}
3245
+ };
3246
+ }
3247
+ async function loadUserModel(filePath) {
3248
+ const fp = filePath ?? defaultModelPath();
3249
+ try {
3250
+ const raw = await fs13.readFile(fp, "utf-8");
3251
+ const parsed = JSON.parse(raw);
3252
+ if (parsed?.version !== 1) return null;
3253
+ return parsed;
3254
+ } catch {
3255
+ return null;
3256
+ }
3257
+ }
3258
+ async function saveUserModel(model, filePath) {
3259
+ const fp = filePath ?? defaultModelPath();
3260
+ const dir = path13.dirname(fp);
3261
+ await fs13.mkdir(dir, { recursive: true });
3262
+ const tmp = fp + `.tmp-${Date.now()}`;
3263
+ await fs13.writeFile(tmp, JSON.stringify(model, null, 2), "utf-8");
3264
+ await fs13.rename(tmp, fp);
3265
+ }
3266
+ function aggregateSession(model, snapshot) {
3267
+ const sessions = [...model.sessions, snapshot];
3268
+ while (sessions.length > MAX_SESSIONS) {
3269
+ sessions.shift();
3270
+ }
3271
+ const totalSessions = model.profile.totalSessions + 1;
3272
+ const profile = computeProfile(sessions, totalSessions);
3273
+ return {
3274
+ ...model,
3275
+ sessions,
3276
+ profile,
3277
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
3278
+ };
3279
+ }
3280
+ function computeProfile(sessions, totalSessions) {
3281
+ if (sessions.length === 0) return { ...emptyProfile(), totalSessions };
3282
+ const n = sessions.length;
3283
+ let trustScore = 0.5;
3284
+ for (const s of sessions) {
3285
+ trustScore = TRUST_ALPHA * ratingSignal(s) + (1 - TRUST_ALPHA) * trustScore;
3286
+ }
3287
+ const trustTrajectory = computeTrustTrajectory(sessions);
3288
+ const baselineFrustration = avg(sessions.map((s) => s.avgFrustration));
3289
+ const baselineExcitement = avg(sessions.map((s) => s.avgExcitement));
3290
+ const sentimentTrend = computeSentimentTrend(sessions);
3291
+ const energyDistribution = {};
3292
+ for (const s of sessions) {
3293
+ energyDistribution[s.timePeriod] = (energyDistribution[s.timePeriod] || 0) + 1;
3294
+ }
3295
+ const preferredTimePeriod = Object.entries(energyDistribution).sort(
3296
+ (a, b) => b[1] - a[1]
3297
+ )[0]?.[0] ?? "afternoon";
3298
+ const avgSessionMinutes = avg(sessions.map((s) => s.durationMinutes));
3299
+ const avgTurnsPerSession = avg(sessions.map((s) => s.turnCount));
3300
+ const engagementTrend = computeLinearTrend(sessions.map((s) => s.turnCount));
3301
+ const frustrationCorrelations = n >= MIN_SESSIONS_FOR_CORRELATIONS ? {
3302
+ toolErrors: pearsonR(
3303
+ sessions.map((s) => s.avgFrustration),
3304
+ sessions.map((s) => s.toolErrors)
3305
+ ),
3306
+ longSessions: pearsonR(
3307
+ sessions.map((s) => s.avgFrustration),
3308
+ sessions.map((s) => s.durationMinutes)
3309
+ ),
3310
+ lateNight: pearsonR(
3311
+ sessions.map((s) => s.avgFrustration),
3312
+ sessions.map((s) => s.timePeriod === "late-night" || s.timePeriod === "night" ? 1 : 0)
3313
+ )
3314
+ } : { toolErrors: 0, longSessions: 0, lateNight: 0 };
3315
+ const nudgeStats = {};
3316
+ for (const s of sessions) {
3317
+ const ratingVal = ratingToNumber(s.rating);
3318
+ for (const nudge of s.wellbeingNudges) {
3319
+ if (!nudgeStats[nudge]) nudgeStats[nudge] = { fired: 0, sessionRatingAfter: 0 };
3320
+ nudgeStats[nudge].fired++;
3321
+ nudgeStats[nudge].sessionRatingAfter += ratingVal;
3322
+ }
3323
+ }
3324
+ for (const key of Object.keys(nudgeStats)) {
3325
+ if (nudgeStats[key].fired > 0) {
3326
+ nudgeStats[key].sessionRatingAfter /= nudgeStats[key].fired;
3327
+ }
3328
+ }
3329
+ return {
3330
+ trustScore,
3331
+ trustTrajectory,
3332
+ totalSessions,
3333
+ preferredTimePeriod,
3334
+ energyDistribution,
3335
+ avgSessionMinutes,
3336
+ baselineFrustration,
3337
+ baselineExcitement,
3338
+ sentimentTrend,
3339
+ frustrationCorrelations,
3340
+ avgTurnsPerSession,
3341
+ engagementTrend,
3342
+ nudgeStats
3343
+ };
3344
+ }
3345
+ function feedForward(model) {
3346
+ if (model.profile.totalSessions < MIN_SESSIONS_FOR_FEED_FORWARD) return null;
3347
+ const p4 = model.profile;
3348
+ const overrides = {
3349
+ compactGreeting: false,
3350
+ frustrationNudgeThreshold: 0.6,
3351
+ defaultToPersonalMode: false
3352
+ };
3353
+ const nightSessions = (p4.energyDistribution["late-night"] || 0) + (p4.energyDistribution["night"] || 0);
3354
+ const totalInWindow = model.sessions.length;
3355
+ if (totalInWindow > 0 && nightSessions / totalInWindow >= 0.7 && p4.baselineFrustration < 0.3) {
3356
+ overrides.energyOverride = "steady";
3357
+ }
3358
+ if (p4.trustScore > 0.8) {
3359
+ overrides.compactGreeting = true;
3360
+ }
3361
+ if (p4.frustrationCorrelations.toolErrors > 0.4) {
3362
+ overrides.frustrationNudgeThreshold = 0.4;
3363
+ }
3364
+ if (p4.sentimentTrend === "worsening") {
3365
+ overrides.defaultToPersonalMode = true;
3366
+ }
3367
+ return overrides;
3368
+ }
3369
+ function clamp(val, min, max) {
3370
+ return Math.max(min, Math.min(max, val));
3371
+ }
3372
+ function avg(values) {
3373
+ if (values.length === 0) return 0;
3374
+ return values.reduce((sum, v) => sum + v, 0) / values.length;
3375
+ }
3376
+ function ratingSignal(session) {
3377
+ if (session.rating === "great") return 1;
3378
+ if (session.rating === "good") return 0.75;
3379
+ if (session.rating === "okay") return 0.5;
3380
+ if (session.rating === "frustrating") return 0.25;
3381
+ let implicit = 1;
3382
+ implicit -= session.avgFrustration * 0.4;
3383
+ implicit -= session.toolErrors > 3 ? 0.2 : 0;
3384
+ implicit -= session.blockers > 2 ? 0.2 : 0;
3385
+ implicit += session.milestones > 0 ? 0.1 : 0;
3386
+ return clamp(implicit, 0, 1);
3387
+ }
3388
+ function ratingToNumber(rating) {
3389
+ if (rating === "great") return 1;
3390
+ if (rating === "good") return 0.75;
3391
+ if (rating === "okay") return 0.5;
3392
+ if (rating === "frustrating") return 0.25;
3393
+ return 0.5;
3394
+ }
3395
+ function pearsonR(x, y) {
3396
+ const n = x.length;
3397
+ if (n < 3) return 0;
3398
+ const mx = avg(x);
3399
+ const my = avg(y);
3400
+ let num = 0;
3401
+ let dx2 = 0;
3402
+ let dy2 = 0;
3403
+ for (let i = 0; i < n; i++) {
3404
+ const dx = x[i] - mx;
3405
+ const dy = y[i] - my;
3406
+ num += dx * dy;
3407
+ dx2 += dx * dx;
3408
+ dy2 += dy * dy;
3409
+ }
3410
+ const denom = Math.sqrt(dx2 * dy2);
3411
+ if (denom === 0) return 0;
3412
+ return num / denom;
3413
+ }
3414
+ function computeTrustTrajectory(sessions) {
3415
+ if (sessions.length < 10) return "stable";
3416
+ const recent5 = sessions.slice(-5).map(ratingSignal);
3417
+ const prev5 = sessions.slice(-10, -5).map(ratingSignal);
3418
+ const recentAvg = avg(recent5);
3419
+ const prevAvg = avg(prev5);
3420
+ const delta = recentAvg - prevAvg;
3421
+ if (delta > 0.1) return "ascending";
3422
+ if (delta < -0.1) return "declining";
3423
+ return "stable";
3424
+ }
3425
+ function computeSentimentTrend(sessions) {
3426
+ if (sessions.length < 5) return "stable";
3427
+ const frustrations = sessions.slice(-10).map((s) => s.avgFrustration);
3428
+ const slope = linearSlope(frustrations);
3429
+ if (slope > 0.02) return "worsening";
3430
+ if (slope < -0.02) return "improving";
3431
+ return "stable";
3432
+ }
3433
+ function computeLinearTrend(values) {
3434
+ if (values.length < 5) return "stable";
3435
+ const recent = values.slice(-10);
3436
+ const slope = linearSlope(recent);
3437
+ const mean = avg(recent);
3438
+ const relativeSlope = mean > 0 ? slope / mean : slope;
3439
+ if (relativeSlope > 0.03) return "increasing";
3440
+ if (relativeSlope < -0.03) return "decreasing";
3441
+ return "stable";
3442
+ }
3443
+ function linearSlope(values) {
3444
+ const n = values.length;
3445
+ if (n < 2) return 0;
3446
+ let sumX = 0;
3447
+ let sumY = 0;
3448
+ let sumXY = 0;
3449
+ let sumX2 = 0;
3450
+ for (let i = 0; i < n; i++) {
3451
+ sumX += i;
3452
+ sumY += values[i];
3453
+ sumXY += i * values[i];
3454
+ sumX2 += i * i;
3455
+ }
3456
+ const denom = n * sumX2 - sumX * sumX;
3457
+ if (denom === 0) return 0;
3458
+ return (n * sumXY - sumX * sumY) / denom;
3459
+ }
3460
+
3203
3461
  // src/hooks.ts
3204
3462
  function getTimeContext() {
3205
3463
  const now = /* @__PURE__ */ new Date();
@@ -3347,6 +3605,29 @@ ${contextInjection}`;
3347
3605
  sessionMinutes: 0,
3348
3606
  turnCount: 0
3349
3607
  });
3608
+ try {
3609
+ const model = await loadUserModel();
3610
+ if (model) {
3611
+ const overrides = feedForward(model);
3612
+ if (overrides) {
3613
+ log.debug("hooks", `Feed-forward active (trust=${model.profile.trustScore.toFixed(2)}, sessions=${model.profile.totalSessions})`);
3614
+ if (overrides.energyOverride && (period === "late-night" || period === "night")) {
3615
+ state.energy = overrides.energyOverride;
3616
+ }
3617
+ if (overrides.defaultToPersonalMode && state.activeMode === "Default") {
3618
+ state.activeMode = "Personal";
3619
+ }
3620
+ if (overrides.compactGreeting) {
3621
+ greeting += "\n<user-model-context>High trust user (score: " + model.profile.trustScore.toFixed(2) + ", " + model.profile.totalSessions + " sessions). Keep greeting compact \u2014 they know you well.</user-model-context>";
3622
+ }
3623
+ if (model.profile.sentimentTrend === "worsening") {
3624
+ greeting += "\n<user-model-context>Sentiment trend is worsening across recent sessions. Be more attentive and patient.</user-model-context>";
3625
+ }
3626
+ }
3627
+ }
3628
+ } catch (err) {
3629
+ log.debug("hooks", "user model feed-forward failed", err);
3630
+ }
3350
3631
  syncPersonalityToCore(state, ctx.mcpManager).catch(() => {
3351
3632
  });
3352
3633
  const nudge = formatWellbeingNudge(state);
@@ -3468,10 +3749,10 @@ async function onSessionEnd(ctx, messages, sessionId, observationSession) {
3468
3749
  }
3469
3750
  console.log(pc2.dim(` Saved ${textMessages.length} messages (session: ${sessionId})`));
3470
3751
  }
3471
- const projectContextPath = path13.join(process.cwd(), ".acore", "context.md");
3472
- if (fs13.existsSync(projectContextPath) && messages.length > 2) {
3752
+ const projectContextPath = path14.join(process.cwd(), ".acore", "context.md");
3753
+ if (fs14.existsSync(projectContextPath) && messages.length > 2) {
3473
3754
  try {
3474
- let contextContent = fs13.readFileSync(projectContextPath, "utf-8");
3755
+ let contextContent = fs14.readFileSync(projectContextPath, "utf-8");
3475
3756
  const now = (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
3476
3757
  let lastUserMsg = "";
3477
3758
  for (let i = messages.length - 1; i >= 0; i--) {
@@ -3489,28 +3770,28 @@ async function onSessionEnd(ctx, messages, sessionId, observationSession) {
3489
3770
  - Recent decisions: [see memory]
3490
3771
  - Temp notes: [cleared]`;
3491
3772
  contextContent = contextContent.replace(sessionPattern, newSession);
3492
- fs13.writeFileSync(projectContextPath, contextContent, "utf-8");
3773
+ fs14.writeFileSync(projectContextPath, contextContent, "utf-8");
3493
3774
  log.debug("hooks", `Updated project context: ${projectContextPath}`);
3494
3775
  }
3495
3776
  } catch (err) {
3496
3777
  log.debug("hooks", "project context update failed", err);
3497
3778
  }
3498
3779
  }
3780
+ const sessionMinutes = Math.round((Date.now() - sessionStartTime) / 6e4);
3781
+ const hour = (/* @__PURE__ */ new Date()).getHours();
3782
+ let period;
3783
+ if (hour < 6) period = "late-night";
3784
+ else if (hour < 12) period = "morning";
3785
+ else if (hour < 17) period = "afternoon";
3786
+ else if (hour < 21) period = "evening";
3787
+ else period = "night";
3788
+ const turnCount = messages.filter((m) => m.role === "user").length;
3789
+ const finalState = computePersonality({
3790
+ timePeriod: period,
3791
+ sessionMinutes,
3792
+ turnCount
3793
+ });
3499
3794
  if (ctx.config.personalityAdapt !== false) {
3500
- const sessionMinutes = Math.round((Date.now() - sessionStartTime) / 6e4);
3501
- const hour = (/* @__PURE__ */ new Date()).getHours();
3502
- let period;
3503
- if (hour < 6) period = "late-night";
3504
- else if (hour < 12) period = "morning";
3505
- else if (hour < 17) period = "afternoon";
3506
- else if (hour < 21) period = "evening";
3507
- else period = "night";
3508
- const turnCount = messages.filter((m) => m.role === "user").length;
3509
- const finalState = computePersonality({
3510
- timePeriod: period,
3511
- sessionMinutes,
3512
- turnCount
3513
- });
3514
3795
  try {
3515
3796
  isHookCall = true;
3516
3797
  await syncPersonalityToCore(finalState, ctx.mcpManager);
@@ -3518,6 +3799,7 @@ async function onSessionEnd(ctx, messages, sessionId, observationSession) {
3518
3799
  isHookCall = false;
3519
3800
  }
3520
3801
  }
3802
+ let sessionRating;
3521
3803
  if (ctx.config.evalPrompt) {
3522
3804
  const rating = await p2.select({
3523
3805
  message: "Quick rating for this session?",
@@ -3530,10 +3812,11 @@ async function onSessionEnd(ctx, messages, sessionId, observationSession) {
3530
3812
  initialValue: "skip"
3531
3813
  });
3532
3814
  if (!p2.isCancel(rating) && rating !== "skip") {
3815
+ sessionRating = rating;
3533
3816
  try {
3534
3817
  isHookCall = true;
3535
3818
  await ctx.mcpManager.callTool("eval_log", {
3536
- rating,
3819
+ rating: sessionRating,
3537
3820
  highlights: "Quick session rating",
3538
3821
  improvements: ""
3539
3822
  });
@@ -3542,6 +3825,51 @@ async function onSessionEnd(ctx, messages, sessionId, observationSession) {
3542
3825
  }
3543
3826
  }
3544
3827
  }
3828
+ if (turnCount >= 2 && sessionMinutes >= 1) {
3829
+ try {
3830
+ const snapshot = {
3831
+ sessionId,
3832
+ date: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
3833
+ durationMinutes: sessionMinutes,
3834
+ turnCount,
3835
+ dominantSentiment: finalState.sentiment.dominant,
3836
+ avgFrustration: finalState.sentiment.frustration,
3837
+ avgExcitement: finalState.sentiment.excitement,
3838
+ avgConfusion: finalState.sentiment.confusion,
3839
+ avgFatigue: finalState.sentiment.fatigue,
3840
+ toolCalls: observationSession?.stats.toolCalls ?? 0,
3841
+ toolErrors: observationSession?.stats.toolErrors ?? 0,
3842
+ blockers: observationSession?.stats.blockers ?? 0,
3843
+ milestones: observationSession?.stats.milestones ?? 0,
3844
+ topicShifts: observationSession?.stats.topicShifts ?? 0,
3845
+ peakEnergy: finalState.energy,
3846
+ primaryMode: finalState.activeMode,
3847
+ timePeriod: period,
3848
+ rating: sessionRating,
3849
+ hadPostmortem: false,
3850
+ // updated below if postmortem is generated
3851
+ wellbeingNudges: finalState.wellbeingNudge ? [finalState.wellbeingNudge] : []
3852
+ };
3853
+ const model = await loadUserModel() ?? createEmptyModel();
3854
+ const updated = aggregateSession(model, snapshot);
3855
+ await saveUserModel(updated);
3856
+ log.debug("hooks", `User model updated (session ${updated.profile.totalSessions})`);
3857
+ if (ctx.config.personalityAdapt !== false) {
3858
+ try {
3859
+ isHookCall = true;
3860
+ await syncPersonalityToCore(finalState, ctx.mcpManager, {
3861
+ trustScore: updated.profile.trustScore,
3862
+ totalSessions: updated.profile.totalSessions,
3863
+ sentimentTrend: updated.profile.sentimentTrend
3864
+ });
3865
+ } finally {
3866
+ isHookCall = false;
3867
+ }
3868
+ }
3869
+ } catch (err) {
3870
+ log.debug("hooks", "user model aggregation failed", err);
3871
+ }
3872
+ }
3545
3873
  if (ctx.config.autoPostmortem !== false && observationSession && shouldAutoPostmortem(observationSession, messages)) {
3546
3874
  try {
3547
3875
  const client = ctx.llmClient;
@@ -3568,14 +3896,14 @@ async function onSessionEnd(ctx, messages, sessionId, observationSession) {
3568
3896
  }
3569
3897
  }
3570
3898
  if (report.crystallizationCandidates && report.crystallizationCandidates.length > 0) {
3571
- const skillsMdPath = path13.join(os12.homedir(), ".askill", "skills.md");
3572
- const logPath = path13.join(
3573
- os12.homedir(),
3899
+ const skillsMdPath = path14.join(os13.homedir(), ".askill", "skills.md");
3900
+ const logPath = path14.join(
3901
+ os13.homedir(),
3574
3902
  ".aman-agent",
3575
3903
  "crystallization-log.json"
3576
3904
  );
3577
- const rejectionsPath = path13.join(
3578
- os12.homedir(),
3905
+ const rejectionsPath = path14.join(
3906
+ os13.homedir(),
3579
3907
  ".aman-agent",
3580
3908
  "crystallization-rejections.json"
3581
3909
  );
@@ -3795,43 +4123,43 @@ async function delegatePipeline(steps, initialInput, client, mcpManager, options
3795
4123
  }
3796
4124
 
3797
4125
  // src/teams.ts
3798
- import fs14 from "fs";
3799
- import path14 from "path";
3800
- import os13 from "os";
4126
+ import fs15 from "fs";
4127
+ import path15 from "path";
4128
+ import os14 from "os";
3801
4129
  import pc4 from "picocolors";
3802
4130
  function getTeamsDir() {
3803
- return path14.join(os13.homedir(), ".acore", "teams");
4131
+ return path15.join(os14.homedir(), ".acore", "teams");
3804
4132
  }
3805
4133
  function ensureTeamsDir() {
3806
4134
  const dir = getTeamsDir();
3807
- if (!fs14.existsSync(dir)) fs14.mkdirSync(dir, { recursive: true });
4135
+ if (!fs15.existsSync(dir)) fs15.mkdirSync(dir, { recursive: true });
3808
4136
  return dir;
3809
4137
  }
3810
4138
  function teamPath(name) {
3811
4139
  const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, "-");
3812
- return path14.join(ensureTeamsDir(), `${slug}.json`);
4140
+ return path15.join(ensureTeamsDir(), `${slug}.json`);
3813
4141
  }
3814
4142
  function createTeam(team) {
3815
4143
  const fp = teamPath(team.name);
3816
- fs14.writeFileSync(fp, JSON.stringify(team, null, 2), "utf-8");
4144
+ fs15.writeFileSync(fp, JSON.stringify(team, null, 2), "utf-8");
3817
4145
  }
3818
4146
  function loadTeam(name) {
3819
4147
  const fp = teamPath(name);
3820
- if (!fs14.existsSync(fp)) return null;
4148
+ if (!fs15.existsSync(fp)) return null;
3821
4149
  try {
3822
- return JSON.parse(fs14.readFileSync(fp, "utf-8"));
4150
+ return JSON.parse(fs15.readFileSync(fp, "utf-8"));
3823
4151
  } catch {
3824
4152
  return null;
3825
4153
  }
3826
4154
  }
3827
4155
  function listTeams() {
3828
4156
  const dir = getTeamsDir();
3829
- if (!fs14.existsSync(dir)) return [];
4157
+ if (!fs15.existsSync(dir)) return [];
3830
4158
  const teams = [];
3831
- for (const file of fs14.readdirSync(dir)) {
4159
+ for (const file of fs15.readdirSync(dir)) {
3832
4160
  if (!file.endsWith(".json")) continue;
3833
4161
  try {
3834
- const content = fs14.readFileSync(path14.join(dir, file), "utf-8");
4162
+ const content = fs15.readFileSync(path15.join(dir, file), "utf-8");
3835
4163
  teams.push(JSON.parse(content));
3836
4164
  } catch {
3837
4165
  }
@@ -3840,8 +4168,8 @@ function listTeams() {
3840
4168
  }
3841
4169
  function deleteTeam(name) {
3842
4170
  const fp = teamPath(name);
3843
- if (!fs14.existsSync(fp)) return false;
3844
- fs14.unlinkSync(fp);
4171
+ if (!fs15.existsSync(fp)) return false;
4172
+ fs15.unlinkSync(fp);
3845
4173
  return true;
3846
4174
  }
3847
4175
  async function runTeam(team, task, client, mcpManager, tools) {
@@ -4067,23 +4395,23 @@ var BUILT_IN_TEAMS = [
4067
4395
  ];
4068
4396
 
4069
4397
  // src/plans.ts
4070
- import fs15 from "fs";
4071
- import path15 from "path";
4072
- import os14 from "os";
4398
+ import fs16 from "fs";
4399
+ import path16 from "path";
4400
+ import os15 from "os";
4073
4401
  function getPlansDir() {
4074
- const localDir = path15.join(process.cwd(), ".acore", "plans");
4075
- const localAcore = path15.join(process.cwd(), ".acore");
4076
- if (fs15.existsSync(localAcore)) return localDir;
4077
- return path15.join(os14.homedir(), ".acore", "plans");
4402
+ const localDir = path16.join(process.cwd(), ".acore", "plans");
4403
+ const localAcore = path16.join(process.cwd(), ".acore");
4404
+ if (fs16.existsSync(localAcore)) return localDir;
4405
+ return path16.join(os15.homedir(), ".acore", "plans");
4078
4406
  }
4079
4407
  function ensurePlansDir() {
4080
4408
  const dir = getPlansDir();
4081
- if (!fs15.existsSync(dir)) fs15.mkdirSync(dir, { recursive: true });
4409
+ if (!fs16.existsSync(dir)) fs16.mkdirSync(dir, { recursive: true });
4082
4410
  return dir;
4083
4411
  }
4084
4412
  function planPath(name) {
4085
4413
  const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
4086
- return path15.join(ensurePlansDir(), `${slug}.md`);
4414
+ return path16.join(ensurePlansDir(), `${slug}.md`);
4087
4415
  }
4088
4416
  function serializePlan(plan) {
4089
4417
  const lines = [];
@@ -4109,7 +4437,7 @@ function parsePlan(content, filePath) {
4109
4437
  const createdMatch = content.match(/\*\*Created:\*\*\s*(.+)/);
4110
4438
  const updatedMatch = content.match(/\*\*Updated:\*\*\s*(.+)/);
4111
4439
  const activeMatch = content.match(/\*\*Active:\*\*\s*(.+)/);
4112
- const name = nameMatch?.[1]?.trim() || path15.basename(filePath, ".md");
4440
+ const name = nameMatch?.[1]?.trim() || path16.basename(filePath, ".md");
4113
4441
  const goal = goalMatch?.[1]?.trim() || "";
4114
4442
  const createdAt = createdMatch?.[1]?.trim() || "";
4115
4443
  const updatedAt = updatedMatch?.[1]?.trim() || "";
@@ -4151,22 +4479,22 @@ function createPlan(name, goal, steps) {
4151
4479
  }
4152
4480
  function savePlan(plan) {
4153
4481
  const fp = planPath(plan.name);
4154
- fs15.writeFileSync(fp, serializePlan(plan), "utf-8");
4482
+ fs16.writeFileSync(fp, serializePlan(plan), "utf-8");
4155
4483
  }
4156
4484
  function loadPlan(name) {
4157
4485
  const fp = planPath(name);
4158
- if (!fs15.existsSync(fp)) return null;
4159
- const content = fs15.readFileSync(fp, "utf-8");
4486
+ if (!fs16.existsSync(fp)) return null;
4487
+ const content = fs16.readFileSync(fp, "utf-8");
4160
4488
  return parsePlan(content, fp);
4161
4489
  }
4162
4490
  function listPlans() {
4163
4491
  const dir = getPlansDir();
4164
- if (!fs15.existsSync(dir)) return [];
4492
+ if (!fs16.existsSync(dir)) return [];
4165
4493
  const plans = [];
4166
- for (const file of fs15.readdirSync(dir)) {
4494
+ for (const file of fs16.readdirSync(dir)) {
4167
4495
  if (!file.endsWith(".md")) continue;
4168
- const fp = path15.join(dir, file);
4169
- const content = fs15.readFileSync(fp, "utf-8");
4496
+ const fp = path16.join(dir, file);
4497
+ const content = fs16.readFileSync(fp, "utf-8");
4170
4498
  const plan = parsePlan(content, fp);
4171
4499
  if (plan) plans.push(plan);
4172
4500
  }
@@ -4275,10 +4603,10 @@ import {
4275
4603
  } from "@aman_asmuei/arules-core";
4276
4604
  var AGENT_SCOPE = process.env.AMAN_AGENT_SCOPE ?? "dev:agent";
4277
4605
  function readEcosystemFile(filePath, label) {
4278
- if (!fs16.existsSync(filePath)) {
4606
+ if (!fs17.existsSync(filePath)) {
4279
4607
  return pc5.dim(`No ${label} file found at ${filePath}`);
4280
4608
  }
4281
- return fs16.readFileSync(filePath, "utf-8").trim();
4609
+ return fs17.readFileSync(filePath, "utf-8").trim();
4282
4610
  }
4283
4611
  function parseCommand(input) {
4284
4612
  const trimmed = input.trim();
@@ -4356,24 +4684,76 @@ async function handleIdentityCommand(action, args, _ctx) {
4356
4684
  }
4357
4685
  }
4358
4686
  if (action === "dynamics") {
4687
+ if (args.includes("--json")) {
4688
+ const model2 = await loadUserModel();
4689
+ if (!model2) return { handled: true, output: pc5.dim("No user model yet. Complete a few sessions first.") };
4690
+ return { handled: true, output: JSON.stringify(model2, null, 2) };
4691
+ }
4692
+ if (args.includes("--reset")) {
4693
+ const modelPath = defaultModelPath();
4694
+ if (fs17.existsSync(modelPath)) {
4695
+ fs17.unlinkSync(modelPath);
4696
+ return { handled: true, output: pc5.green("User model reset. Starting fresh.") };
4697
+ }
4698
+ return { handled: true, output: pc5.dim("No user model to reset.") };
4699
+ }
4359
4700
  const updates = {};
4360
4701
  for (const arg of args) {
4361
4702
  const eq = arg.indexOf("=");
4362
4703
  if (eq > 0) updates[arg.slice(0, eq)] = arg.slice(eq + 1);
4363
4704
  }
4364
- if (!Object.keys(updates).length) {
4365
- return { handled: true, output: pc5.yellow("Usage: /identity dynamics energy=high mode=focused read='Book Title'") };
4705
+ if (Object.keys(updates).length > 0) {
4706
+ try {
4707
+ await acoreUpdateDynamics({
4708
+ energy: updates.energy,
4709
+ activeMode: updates.mode,
4710
+ currentRead: updates.read
4711
+ }, AGENT_SCOPE);
4712
+ return { handled: true, output: `Dynamics updated: ${Object.entries(updates).map(([k, v]) => `${k}=${v}`).join(", ")}` };
4713
+ } catch (err) {
4714
+ return { handled: true, output: pc5.red(`Dynamics error: ${err instanceof Error ? err.message : String(err)}`) };
4715
+ }
4366
4716
  }
4367
- try {
4368
- await acoreUpdateDynamics({
4369
- energy: updates.energy,
4370
- activeMode: updates.mode,
4371
- currentRead: updates.read
4372
- }, AGENT_SCOPE);
4373
- return { handled: true, output: `Dynamics updated: ${Object.entries(updates).map(([k, v]) => `${k}=${v}`).join(", ")}` };
4374
- } catch (err) {
4375
- return { handled: true, output: pc5.red(`Dynamics error: ${err instanceof Error ? err.message : String(err)}`) };
4717
+ const model = await loadUserModel();
4718
+ if (!model) {
4719
+ return { handled: true, output: pc5.dim("No user model yet. Complete a few sessions to start building your profile.") };
4720
+ }
4721
+ const p4 = model.profile;
4722
+ const trustBar = "\u2588".repeat(Math.round(p4.trustScore * 10)) + "\u2591".repeat(10 - Math.round(p4.trustScore * 10));
4723
+ const frustBar = "\u2588".repeat(Math.round(p4.baselineFrustration * 10)) + "\u2591".repeat(10 - Math.round(p4.baselineFrustration * 10));
4724
+ const lines = [
4725
+ pc5.bold(" Dynamic User Model"),
4726
+ "",
4727
+ ` ${pc5.cyan("Trust")} ${trustBar} ${(p4.trustScore * 100).toFixed(0)}% ${p4.trustTrajectory === "ascending" ? pc5.green("\u2191") : p4.trustTrajectory === "declining" ? pc5.red("\u2193") : "\u2192"}`,
4728
+ ` ${pc5.cyan("Sessions")} ${p4.totalSessions} total (${model.sessions.length} in window)`,
4729
+ ` ${pc5.cyan("Sentiment")} ${frustBar} frustration baseline ${p4.sentimentTrend === "improving" ? pc5.green("improving") : p4.sentimentTrend === "worsening" ? pc5.red("worsening") : "stable"}`,
4730
+ "",
4731
+ ` ${pc5.cyan("Preferred")} ${p4.preferredTimePeriod} (${Object.entries(p4.energyDistribution).map(([k, v]) => `${k}: ${v}`).join(", ")})`,
4732
+ ` ${pc5.cyan("Avg session")} ${p4.avgSessionMinutes.toFixed(0)} min, ${p4.avgTurnsPerSession.toFixed(0)} turns ${p4.engagementTrend === "increasing" ? pc5.green("\u2191") : p4.engagementTrend === "decreasing" ? pc5.red("\u2193") : "\u2192"}`
4733
+ ];
4734
+ if (p4.totalSessions >= 10) {
4735
+ const corrs = [];
4736
+ if (Math.abs(p4.frustrationCorrelations.toolErrors) > 0.3) {
4737
+ corrs.push(`tool errors (${p4.frustrationCorrelations.toolErrors.toFixed(2)})`);
4738
+ }
4739
+ if (Math.abs(p4.frustrationCorrelations.longSessions) > 0.3) {
4740
+ corrs.push(`long sessions (${p4.frustrationCorrelations.longSessions.toFixed(2)})`);
4741
+ }
4742
+ if (Math.abs(p4.frustrationCorrelations.lateNight) > 0.3) {
4743
+ corrs.push(`late night (${p4.frustrationCorrelations.lateNight.toFixed(2)})`);
4744
+ }
4745
+ if (corrs.length > 0) {
4746
+ lines.push(` ${pc5.cyan("Frustration")} correlates with: ${corrs.join(", ")}`);
4747
+ }
4748
+ }
4749
+ const nudgeKeys = Object.keys(p4.nudgeStats);
4750
+ if (nudgeKeys.length > 0) {
4751
+ lines.push("");
4752
+ lines.push(` ${pc5.cyan("Nudges")} ${nudgeKeys.map((k) => `${k}: ${p4.nudgeStats[k].fired}\xD7`).join(", ")}`);
4376
4753
  }
4754
+ lines.push("");
4755
+ lines.push(pc5.dim(` Use --json for raw data, --reset to start fresh`));
4756
+ return { handled: true, output: lines.join("\n") };
4377
4757
  }
4378
4758
  if (action === "summary") {
4379
4759
  try {
@@ -4397,7 +4777,10 @@ async function handleIdentityCommand(action, args, _ctx) {
4397
4777
  pc5.bold("Identity commands:"),
4398
4778
  ` ${pc5.cyan("/identity")} View current identity`,
4399
4779
  ` ${pc5.cyan("/identity update")} <section> Update a section`,
4780
+ ` ${pc5.cyan("/identity dynamics")} View user model (trust, sentiment, patterns)`,
4400
4781
  ` ${pc5.cyan("/identity dynamics")} key=val Update dynamic fields (energy, mode, read)`,
4782
+ ` ${pc5.cyan("/identity dynamics")} --json Raw JSON user model`,
4783
+ ` ${pc5.cyan("/identity dynamics")} --reset Reset user model`,
4401
4784
  ` ${pc5.cyan("/identity summary")} Show structured identity summary`
4402
4785
  ].join("\n")
4403
4786
  };
@@ -4553,9 +4936,9 @@ ${result.violations.map((v) => ` - ${v}`).join("\n")}`)
4553
4936
  };
4554
4937
  }
4555
4938
  async function handleWorkflowsCommand(action, args, ctx) {
4556
- const home2 = os15.homedir();
4939
+ const home2 = os16.homedir();
4557
4940
  if (!action) {
4558
- const content = readEcosystemFile(path16.join(home2, ".aflow", "flow.md"), "workflows (aflow)");
4941
+ const content = readEcosystemFile(path17.join(home2, ".aflow", "flow.md"), "workflows (aflow)");
4559
4942
  return { handled: true, output: content };
4560
4943
  }
4561
4944
  if (action === "add") {
@@ -4577,7 +4960,7 @@ async function handleWorkflowsCommand(action, args, ctx) {
4577
4960
  return { handled: true, output: pc5.yellow("Usage: /workflows get <name>") };
4578
4961
  }
4579
4962
  const name = args.join(" ").toLowerCase();
4580
- const raw = readEcosystemFile(path16.join(home2, ".aflow", "flow.md"), "workflows (aflow)");
4963
+ const raw = readEcosystemFile(path17.join(home2, ".aflow", "flow.md"), "workflows (aflow)");
4581
4964
  if (raw.startsWith("No ")) {
4582
4965
  return { handled: true, output: raw };
4583
4966
  }
@@ -4636,12 +5019,12 @@ async function handleToolsCommand(action, args, _ctx) {
4636
5019
  return { handled: true, output: pc5.yellow("Usage: /tools search <query...>") };
4637
5020
  }
4638
5021
  const query = args.join(" ").toLowerCase();
4639
- const home2 = os15.homedir();
4640
- const toolsFile = path16.join(home2, ".akit", "tools.md");
4641
- if (!fs16.existsSync(toolsFile)) {
5022
+ const home2 = os16.homedir();
5023
+ const toolsFile = path17.join(home2, ".akit", "tools.md");
5024
+ if (!fs17.existsSync(toolsFile)) {
4642
5025
  return { handled: true, output: pc5.dim(`No tools file found. Use 'npx @aman_asmuei/akit search ${args.join(" ")}' to search the registry.`) };
4643
5026
  }
4644
- const raw = fs16.readFileSync(toolsFile, "utf-8").trim();
5027
+ const raw = fs17.readFileSync(toolsFile, "utf-8").trim();
4645
5028
  const lines = raw.split("\n");
4646
5029
  const matches = lines.filter((l) => l.toLowerCase().includes(query));
4647
5030
  if (matches.length === 0) {
@@ -4652,9 +5035,9 @@ async function handleToolsCommand(action, args, _ctx) {
4652
5035
  return handleAkitCommand(action, args);
4653
5036
  }
4654
5037
  async function handleSkillsCommand(action, args, ctx) {
4655
- const home2 = os15.homedir();
5038
+ const home2 = os16.homedir();
4656
5039
  if (!action) {
4657
- const content = readEcosystemFile(path16.join(home2, ".askill", "skills.md"), "skills (askill)");
5040
+ const content = readEcosystemFile(path17.join(home2, ".askill", "skills.md"), "skills (askill)");
4658
5041
  return { handled: true, output: content };
4659
5042
  }
4660
5043
  if (action === "install") {
@@ -4676,8 +5059,8 @@ async function handleSkillsCommand(action, args, ctx) {
4676
5059
  return { handled: true, output: pc5.yellow("Usage: /skills search <query...>") };
4677
5060
  }
4678
5061
  const query = args.join(" ").toLowerCase();
4679
- const home3 = os15.homedir();
4680
- const raw = readEcosystemFile(path16.join(home3, ".askill", "skills.md"), "skills (askill)");
5062
+ const home3 = os16.homedir();
5063
+ const raw = readEcosystemFile(path17.join(home3, ".askill", "skills.md"), "skills (askill)");
4681
5064
  if (raw.startsWith("No ")) {
4682
5065
  return { handled: true, output: raw };
4683
5066
  }
@@ -4691,9 +5074,9 @@ async function handleSkillsCommand(action, args, ctx) {
4691
5074
  if (action === "list") {
4692
5075
  const autoOnly = args.includes("--auto");
4693
5076
  if (autoOnly) {
4694
- const logPath = path16.join(os15.homedir(), ".aman-agent", "crystallization-log.json");
5077
+ const logPath = path17.join(os16.homedir(), ".aman-agent", "crystallization-log.json");
4695
5078
  try {
4696
- const content2 = fs16.readFileSync(logPath, "utf-8");
5079
+ const content2 = fs17.readFileSync(logPath, "utf-8");
4697
5080
  const entries = JSON.parse(content2);
4698
5081
  if (entries.length === 0) {
4699
5082
  return { handled: true, output: pc5.dim("No crystallized skills yet.") };
@@ -4709,13 +5092,13 @@ async function handleSkillsCommand(action, args, ctx) {
4709
5092
  return { handled: true, output: pc5.dim("No crystallized skills yet.") };
4710
5093
  }
4711
5094
  }
4712
- const content = readEcosystemFile(path16.join(home2, ".askill", "skills.md"), "skills (askill)");
5095
+ const content = readEcosystemFile(path17.join(home2, ".askill", "skills.md"), "skills (askill)");
4713
5096
  return { handled: true, output: content };
4714
5097
  }
4715
5098
  if (action === "crystallize") {
4716
- const pmDir = path16.join(os15.homedir(), ".acore", "postmortems");
5099
+ const pmDir = path17.join(os16.homedir(), ".acore", "postmortems");
4717
5100
  try {
4718
- const files = fs16.readdirSync(pmDir);
5101
+ const files = fs17.readdirSync(pmDir);
4719
5102
  const jsonFiles = files.filter((f) => f.endsWith(".json")).sort().reverse();
4720
5103
  if (jsonFiles.length === 0) {
4721
5104
  return {
@@ -4724,7 +5107,7 @@ async function handleSkillsCommand(action, args, ctx) {
4724
5107
  };
4725
5108
  }
4726
5109
  const latest = jsonFiles[0];
4727
- const content = fs16.readFileSync(path16.join(pmDir, latest), "utf-8");
5110
+ const content = fs17.readFileSync(path17.join(pmDir, latest), "utf-8");
4728
5111
  const report = JSON.parse(content);
4729
5112
  if (!report.crystallizationCandidates || report.crystallizationCandidates.length === 0) {
4730
5113
  return {
@@ -4732,8 +5115,8 @@ async function handleSkillsCommand(action, args, ctx) {
4732
5115
  output: pc5.dim(`No crystallization candidates in the most recent post-mortem (${latest}). Run a longer session or wait for the next auto-postmortem.`)
4733
5116
  };
4734
5117
  }
4735
- const skillsMdPath = path16.join(os15.homedir(), ".askill", "skills.md");
4736
- const logPath = path16.join(os15.homedir(), ".aman-agent", "crystallization-log.json");
5118
+ const skillsMdPath = path17.join(os16.homedir(), ".askill", "skills.md");
5119
+ const logPath = path17.join(os16.homedir(), ".aman-agent", "crystallization-log.json");
4737
5120
  const postmortemFilename = latest.replace(/\.json$/, ".md");
4738
5121
  const lines = [
4739
5122
  pc5.bold(`Found ${report.crystallizationCandidates.length} candidate(s) in ${latest}:`)
@@ -4790,9 +5173,9 @@ async function handleSkillsCommand(action, args, ctx) {
4790
5173
  return { handled: true, output: pc5.yellow(`Unknown action: /skills ${action}. Try /skills --help`) };
4791
5174
  }
4792
5175
  async function handleEvalCommand(action, args, ctx) {
4793
- const home2 = os15.homedir();
5176
+ const home2 = os16.homedir();
4794
5177
  if (!action) {
4795
- const content = readEcosystemFile(path16.join(home2, ".aeval", "eval.md"), "evaluation (aeval)");
5178
+ const content = readEcosystemFile(path17.join(home2, ".aeval", "eval.md"), "evaluation (aeval)");
4796
5179
  return { handled: true, output: content };
4797
5180
  }
4798
5181
  if (action === "milestone") {
@@ -4804,11 +5187,11 @@ async function handleEvalCommand(action, args, ctx) {
4804
5187
  return { handled: true, output };
4805
5188
  }
4806
5189
  if (action === "report") {
4807
- const evalFile = path16.join(home2, ".aeval", "eval.md");
4808
- if (!fs16.existsSync(evalFile)) {
5190
+ const evalFile = path17.join(home2, ".aeval", "eval.md");
5191
+ if (!fs17.existsSync(evalFile)) {
4809
5192
  return { handled: true, output: pc5.dim("No eval report found. Log milestones with /eval milestone <text>.") };
4810
5193
  }
4811
- const content = fs16.readFileSync(evalFile, "utf-8").trim();
5194
+ const content = fs17.readFileSync(evalFile, "utf-8").trim();
4812
5195
  return { handled: true, output: [pc5.bold("Eval Report"), "", content].join("\n") };
4813
5196
  }
4814
5197
  return { handled: true, output: pc5.yellow(`Unknown action: /eval ${action}. Use /eval, /eval report, or /eval milestone <text>.`) };
@@ -5332,10 +5715,10 @@ function handleSave() {
5332
5715
  }
5333
5716
  function handleReset(action) {
5334
5717
  const dirs = {
5335
- config: path16.join(os15.homedir(), ".aman-agent"),
5336
- memory: path16.join(os15.homedir(), ".amem"),
5337
- identity: path16.join(os15.homedir(), ".acore"),
5338
- rules: path16.join(os15.homedir(), ".arules")
5718
+ config: path17.join(os16.homedir(), ".aman-agent"),
5719
+ memory: path17.join(os16.homedir(), ".amem"),
5720
+ identity: path17.join(os16.homedir(), ".acore"),
5721
+ rules: path17.join(os16.homedir(), ".arules")
5339
5722
  };
5340
5723
  if (action === "help" || !action) {
5341
5724
  return {
@@ -5360,15 +5743,15 @@ function handleReset(action) {
5360
5743
  const removed = [];
5361
5744
  for (const target of targets) {
5362
5745
  const dir = dirs[target];
5363
- if (fs16.existsSync(dir)) {
5364
- fs16.rmSync(dir, { recursive: true, force: true });
5746
+ if (fs17.existsSync(dir)) {
5747
+ fs17.rmSync(dir, { recursive: true, force: true });
5365
5748
  removed.push(target);
5366
5749
  }
5367
5750
  }
5368
5751
  if (targets.includes("config")) {
5369
5752
  const configDir = dirs.config;
5370
- fs16.mkdirSync(configDir, { recursive: true });
5371
- fs16.writeFileSync(path16.join(configDir, ".reconfig"), "", "utf-8");
5753
+ fs17.mkdirSync(configDir, { recursive: true });
5754
+ fs17.writeFileSync(path17.join(configDir, ".reconfig"), "", "utf-8");
5372
5755
  }
5373
5756
  if (removed.length === 0) {
5374
5757
  return { handled: true, output: pc5.dim("Nothing to reset \u2014 directories don't exist.") };
@@ -5385,7 +5768,7 @@ function handleReset(action) {
5385
5768
  function handleUpdate() {
5386
5769
  try {
5387
5770
  const current = execFileSync3("npm", ["view", "@aman_asmuei/aman-agent", "version"], { encoding: "utf-8" }).trim();
5388
- const local = true ? "0.26.0" : "unknown";
5771
+ const local = true ? "0.27.0" : "unknown";
5389
5772
  if (current === local) {
5390
5773
  return { handled: true, output: `${pc5.green("Up to date")} \u2014 v${local}` };
5391
5774
  }
@@ -5429,11 +5812,11 @@ function handleExportCommand() {
5429
5812
  return { handled: true, exportConversation: true };
5430
5813
  }
5431
5814
  function handleDebugCommand() {
5432
- const logPath = path16.join(os15.homedir(), ".aman-agent", "debug.log");
5433
- if (!fs16.existsSync(logPath)) {
5815
+ const logPath = path17.join(os16.homedir(), ".aman-agent", "debug.log");
5816
+ if (!fs17.existsSync(logPath)) {
5434
5817
  return { handled: true, output: pc5.dim("No debug log found.") };
5435
5818
  }
5436
- const content = fs16.readFileSync(logPath, "utf-8");
5819
+ const content = fs17.readFileSync(logPath, "utf-8");
5437
5820
  const lines = content.trim().split("\n");
5438
5821
  const last20 = lines.slice(-20).join("\n");
5439
5822
  return { handled: true, output: pc5.bold("Debug Log (last 20 entries):\n") + pc5.dim(last20) };
@@ -5631,7 +6014,7 @@ ${result.response}`
5631
6014
  };
5632
6015
  }
5633
6016
  function handleProfileCommand(action, args) {
5634
- const profilesDir = path16.join(os15.homedir(), ".acore", "profiles");
6017
+ const profilesDir = path17.join(os16.homedir(), ".acore", "profiles");
5635
6018
  if (action === "me") {
5636
6019
  const user = loadUserIdentity();
5637
6020
  if (!user) {
@@ -5699,8 +6082,8 @@ ${pc5.dim("Edit with: /profile edit")}` };
5699
6082
  };
5700
6083
  }
5701
6084
  const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, "-");
5702
- const profileDir = path16.join(profilesDir, slug);
5703
- if (fs16.existsSync(profileDir)) {
6085
+ const profileDir = path17.join(profilesDir, slug);
6086
+ if (fs17.existsSync(profileDir)) {
5704
6087
  return { handled: true, output: pc5.yellow(`Profile already exists: ${slug}`) };
5705
6088
  }
5706
6089
  const builtIn = BUILT_IN_PROFILES.find((t) => t.name === slug);
@@ -5716,16 +6099,16 @@ ${pc5.dim("Edit with: /profile edit")}` };
5716
6099
  Use: aman-agent --profile ${slug}`
5717
6100
  };
5718
6101
  }
5719
- fs16.mkdirSync(profileDir, { recursive: true });
5720
- const globalCore = path16.join(os15.homedir(), ".acore", "core.md");
5721
- if (fs16.existsSync(globalCore)) {
5722
- let content = fs16.readFileSync(globalCore, "utf-8");
6102
+ fs17.mkdirSync(profileDir, { recursive: true });
6103
+ const globalCore = path17.join(os16.homedir(), ".acore", "core.md");
6104
+ if (fs17.existsSync(globalCore)) {
6105
+ let content = fs17.readFileSync(globalCore, "utf-8");
5723
6106
  const aiName = name.charAt(0).toUpperCase() + name.slice(1);
5724
6107
  content = content.replace(/^# .+$/m, `# ${aiName}`);
5725
- fs16.writeFileSync(path16.join(profileDir, "core.md"), content, "utf-8");
6108
+ fs17.writeFileSync(path17.join(profileDir, "core.md"), content, "utf-8");
5726
6109
  } else {
5727
6110
  const aiName = name.charAt(0).toUpperCase() + name.slice(1);
5728
- fs16.writeFileSync(path16.join(profileDir, "core.md"), `# ${aiName}
6111
+ fs17.writeFileSync(path17.join(profileDir, "core.md"), `# ${aiName}
5729
6112
 
5730
6113
  ## Identity
5731
6114
  - Role: ${aiName} is your AI companion
@@ -5738,7 +6121,7 @@ ${pc5.dim("Edit with: /profile edit")}` };
5738
6121
  return {
5739
6122
  handled: true,
5740
6123
  output: pc5.green(`Profile created: ${slug}`) + `
5741
- Edit: ${path16.join(profileDir, "core.md")}
6124
+ Edit: ${path17.join(profileDir, "core.md")}
5742
6125
  Use: aman-agent --profile ${slug}
5743
6126
 
5744
6127
  ${pc5.dim("Add rules.md or skills.md for profile-specific overrides.")}`
@@ -5747,9 +6130,9 @@ ${pc5.dim("Edit with: /profile edit")}` };
5747
6130
  case "show": {
5748
6131
  const name = args[0];
5749
6132
  if (!name) return { handled: true, output: pc5.yellow("Usage: /profile show <name>") };
5750
- const profileDir = path16.join(profilesDir, name);
5751
- if (!fs16.existsSync(profileDir)) return { handled: true, output: pc5.red(`Profile not found: ${name}`) };
5752
- const files = fs16.readdirSync(profileDir).filter((f) => f.endsWith(".md"));
6133
+ const profileDir = path17.join(profilesDir, name);
6134
+ if (!fs17.existsSync(profileDir)) return { handled: true, output: pc5.red(`Profile not found: ${name}`) };
6135
+ const files = fs17.readdirSync(profileDir).filter((f) => f.endsWith(".md"));
5753
6136
  const lines = files.map((f) => ` ${f}`);
5754
6137
  return { handled: true, output: `Profile: ${pc5.bold(name)}
5755
6138
  Files:
@@ -5758,9 +6141,9 @@ ${lines.join("\n")}` };
5758
6141
  case "delete": {
5759
6142
  const name = args[0];
5760
6143
  if (!name) return { handled: true, output: pc5.yellow("Usage: /profile delete <name>") };
5761
- const profileDir = path16.join(profilesDir, name);
5762
- if (!fs16.existsSync(profileDir)) return { handled: true, output: pc5.red(`Profile not found: ${name}`) };
5763
- fs16.rmSync(profileDir, { recursive: true });
6144
+ const profileDir = path17.join(profilesDir, name);
6145
+ if (!fs17.existsSync(profileDir)) return { handled: true, output: pc5.red(`Profile not found: ${name}`) };
6146
+ fs17.rmSync(profileDir, { recursive: true });
5764
6147
  return { handled: true, output: pc5.dim(`Profile deleted: ${name}`) };
5765
6148
  }
5766
6149
  case "help":
@@ -5978,10 +6361,10 @@ function handleShowcaseCommand(action, args) {
5978
6361
  Or place it as a sibling directory to aman-agent.`
5979
6362
  };
5980
6363
  }
5981
- const corePath = path16.join(os15.homedir(), ".acore", "core.md");
6364
+ const corePath = path17.join(os16.homedir(), ".acore", "core.md");
5982
6365
  let currentShowcase = null;
5983
- if (fs16.existsSync(corePath)) {
5984
- const content = fs16.readFileSync(corePath, "utf-8");
6366
+ if (fs17.existsSync(corePath)) {
6367
+ const content = fs17.readFileSync(corePath, "utf-8");
5985
6368
  const nameMatch = content.match(/^# (.+)/m);
5986
6369
  if (nameMatch) {
5987
6370
  const coreName = nameMatch[1].trim().toLowerCase();
@@ -6368,10 +6751,10 @@ ${summaryParts.slice(0, 20).join("\n")}
6368
6751
  }
6369
6752
 
6370
6753
  // src/skill-engine.ts
6371
- import fs17 from "fs";
6754
+ import fs18 from "fs";
6372
6755
  import fsp from "fs/promises";
6373
- import path17 from "path";
6374
- import os16 from "os";
6756
+ import path18 from "path";
6757
+ import os17 from "os";
6375
6758
  var SKILL_TRIGGERS = {
6376
6759
  testing: ["test", "spec", "coverage", "tdd", "jest", "vitest", "mocha", "assert", "mock", "stub", "fixture", "e2e", "integration test", "unit test"],
6377
6760
  "api-design": ["api", "endpoint", "rest", "graphql", "route", "controller", "middleware", "http", "request", "response", "status code", "pagination"],
@@ -6400,20 +6783,20 @@ async function loadRuntimeTriggers(skillsMdPath) {
6400
6783
  return /* @__PURE__ */ new Map();
6401
6784
  }
6402
6785
  }
6403
- var LEVEL_FILE = path17.join(os16.homedir(), ".aman-agent", "skill-levels.json");
6786
+ var LEVEL_FILE = path18.join(os17.homedir(), ".aman-agent", "skill-levels.json");
6404
6787
  function loadSkillLevels() {
6405
6788
  try {
6406
- if (fs17.existsSync(LEVEL_FILE)) {
6407
- return JSON.parse(fs17.readFileSync(LEVEL_FILE, "utf-8"));
6789
+ if (fs18.existsSync(LEVEL_FILE)) {
6790
+ return JSON.parse(fs18.readFileSync(LEVEL_FILE, "utf-8"));
6408
6791
  }
6409
6792
  } catch {
6410
6793
  }
6411
6794
  return {};
6412
6795
  }
6413
6796
  function saveSkillLevels(levels) {
6414
- const dir = path17.dirname(LEVEL_FILE);
6415
- if (!fs17.existsSync(dir)) fs17.mkdirSync(dir, { recursive: true });
6416
- fs17.writeFileSync(LEVEL_FILE, JSON.stringify(levels, null, 2), "utf-8");
6797
+ const dir = path18.dirname(LEVEL_FILE);
6798
+ if (!fs18.existsSync(dir)) fs18.mkdirSync(dir, { recursive: true });
6799
+ fs18.writeFileSync(LEVEL_FILE, JSON.stringify(levels, null, 2), "utf-8");
6417
6800
  }
6418
6801
  function computeLevel(activations) {
6419
6802
  if (activations >= 50) return { level: 5, label: "Expert" };
@@ -6477,7 +6860,7 @@ async function autoTriggerSkills(userInput, mcpManager) {
6477
6860
  const result = await mcpManager.callTool("skill_list", {});
6478
6861
  const skills = JSON.parse(result);
6479
6862
  const installed = skills.filter((s) => s.installed).map((s) => s.name);
6480
- const skillsMdPath = path17.join(os16.homedir(), ".askill", "skills.md");
6863
+ const skillsMdPath = path18.join(os17.homedir(), ".askill", "skills.md");
6481
6864
  const runtimeTriggers = await loadRuntimeTriggers(skillsMdPath);
6482
6865
  if (installed.length === 0 && runtimeTriggers.size === 0) return "";
6483
6866
  const matched = matchSkills(userInput, installed, runtimeTriggers);
@@ -7036,9 +7419,9 @@ function humanizeError(message) {
7036
7419
  }
7037
7420
 
7038
7421
  // src/hints.ts
7039
- import fs18 from "fs";
7040
- import path18 from "path";
7041
- import os17 from "os";
7422
+ import fs19 from "fs";
7423
+ import path19 from "path";
7424
+ import os18 from "os";
7042
7425
  var HINTS = [
7043
7426
  {
7044
7427
  id: "eval",
@@ -7076,11 +7459,11 @@ function getHint(state, ctx) {
7076
7459
  }
7077
7460
  return null;
7078
7461
  }
7079
- var HINTS_FILE = path18.join(os17.homedir(), ".aman-agent", "hints-seen.json");
7462
+ var HINTS_FILE = path19.join(os18.homedir(), ".aman-agent", "hints-seen.json");
7080
7463
  function loadShownHints() {
7081
7464
  try {
7082
- if (fs18.existsSync(HINTS_FILE)) {
7083
- const data = JSON.parse(fs18.readFileSync(HINTS_FILE, "utf-8"));
7465
+ if (fs19.existsSync(HINTS_FILE)) {
7466
+ const data = JSON.parse(fs19.readFileSync(HINTS_FILE, "utf-8"));
7084
7467
  return new Set(Array.isArray(data) ? data : []);
7085
7468
  }
7086
7469
  } catch {
@@ -7089,9 +7472,9 @@ function loadShownHints() {
7089
7472
  }
7090
7473
  function saveShownHints(shown) {
7091
7474
  try {
7092
- const dir = path18.dirname(HINTS_FILE);
7093
- fs18.mkdirSync(dir, { recursive: true });
7094
- fs18.writeFileSync(HINTS_FILE, JSON.stringify([...shown]), "utf-8");
7475
+ const dir = path19.dirname(HINTS_FILE);
7476
+ fs19.mkdirSync(dir, { recursive: true });
7477
+ fs19.writeFileSync(HINTS_FILE, JSON.stringify([...shown]), "utf-8");
7095
7478
  } catch {
7096
7479
  }
7097
7480
  }
@@ -7358,9 +7741,9 @@ ${task.result}`
7358
7741
  }
7359
7742
  if (cmdResult.exportConversation) {
7360
7743
  try {
7361
- const exportDir = path19.join(os18.homedir(), ".aman-agent", "exports");
7362
- fs19.mkdirSync(exportDir, { recursive: true });
7363
- const exportPath = path19.join(exportDir, `${sessionId}.md`);
7744
+ const exportDir = path20.join(os19.homedir(), ".aman-agent", "exports");
7745
+ fs20.mkdirSync(exportDir, { recursive: true });
7746
+ const exportPath = path20.join(exportDir, `${sessionId}.md`);
7364
7747
  const lines = [
7365
7748
  `# Conversation \u2014 ${(/* @__PURE__ */ new Date()).toLocaleString()}`,
7366
7749
  `**Model:** ${model}`,
@@ -7374,7 +7757,7 @@ ${task.result}`
7374
7757
  lines.push(`${label} ${msg.content}`, "");
7375
7758
  }
7376
7759
  }
7377
- fs19.writeFileSync(exportPath, lines.join("\n"), "utf-8");
7760
+ fs20.writeFileSync(exportPath, lines.join("\n"), "utf-8");
7378
7761
  console.log(pc7.green(`Exported to ${exportPath}`));
7379
7762
  } catch {
7380
7763
  console.log(pc7.red("Failed to export conversation."));
@@ -7500,25 +7883,25 @@ ${knowledgeItem.content}
7500
7883
  for (const match of filePathMatches) {
7501
7884
  let filePath = match[1];
7502
7885
  if (filePath.startsWith("~/")) {
7503
- filePath = path19.join(os18.homedir(), filePath.slice(2));
7886
+ filePath = path20.join(os19.homedir(), filePath.slice(2));
7504
7887
  }
7505
- if (!fs19.existsSync(filePath) || !fs19.statSync(filePath).isFile()) continue;
7506
- const ext = path19.extname(filePath).toLowerCase();
7888
+ if (!fs20.existsSync(filePath) || !fs20.statSync(filePath).isFile()) continue;
7889
+ const ext = path20.extname(filePath).toLowerCase();
7507
7890
  if (imageExts.has(ext)) {
7508
7891
  try {
7509
- const stat = fs19.statSync(filePath);
7892
+ const stat = fs20.statSync(filePath);
7510
7893
  if (stat.size > maxImageBytes) {
7511
- process.stdout.write(pc7.yellow(` [skipped: ${path19.basename(filePath)} \u2014 exceeds 20MB limit]
7894
+ process.stdout.write(pc7.yellow(` [skipped: ${path20.basename(filePath)} \u2014 exceeds 20MB limit]
7512
7895
  `));
7513
7896
  continue;
7514
7897
  }
7515
- const data = fs19.readFileSync(filePath).toString("base64");
7898
+ const data = fs20.readFileSync(filePath).toString("base64");
7516
7899
  const mediaType = mimeMap[ext] || "image/png";
7517
7900
  imageBlocks.push({
7518
7901
  type: "image",
7519
7902
  source: { type: "base64", media_type: mediaType, data }
7520
7903
  });
7521
- process.stdout.write(pc7.dim(` [attached image: ${path19.basename(filePath)} (${(stat.size / 1024).toFixed(1)}KB)]
7904
+ process.stdout.write(pc7.dim(` [attached image: ${path20.basename(filePath)} (${(stat.size / 1024).toFixed(1)}KB)]
7522
7905
  `));
7523
7906
  } catch {
7524
7907
  process.stdout.write(pc7.dim(` [could not read image: ${filePath}]
@@ -7526,7 +7909,7 @@ ${knowledgeItem.content}
7526
7909
  }
7527
7910
  } else if (textExts.has(ext) || ext === "") {
7528
7911
  try {
7529
- const content = fs19.readFileSync(filePath, "utf-8");
7912
+ const content = fs20.readFileSync(filePath, "utf-8");
7530
7913
  const maxChars = 5e4;
7531
7914
  const trimmed = content.length > maxChars ? content.slice(0, maxChars) + `
7532
7915
 
@@ -7536,7 +7919,7 @@ ${knowledgeItem.content}
7536
7919
  <file path="${filePath}" size="${content.length} chars">
7537
7920
  ${trimmed}
7538
7921
  </file>`;
7539
- process.stdout.write(pc7.dim(` [attached: ${path19.basename(filePath)} (${(content.length / 1024).toFixed(1)}KB)]
7922
+ process.stdout.write(pc7.dim(` [attached: ${path20.basename(filePath)} (${(content.length / 1024).toFixed(1)}KB)]
7540
7923
  `));
7541
7924
  } catch {
7542
7925
  process.stdout.write(pc7.dim(` [could not read: ${filePath}]
@@ -7545,7 +7928,7 @@ ${trimmed}
7545
7928
  } else if (docExts.has(ext)) {
7546
7929
  if (mcpManager) {
7547
7930
  try {
7548
- process.stdout.write(pc7.dim(` [converting: ${path19.basename(filePath)}...]
7931
+ process.stdout.write(pc7.dim(` [converting: ${path20.basename(filePath)}...]
7549
7932
  `));
7550
7933
  const converted = await mcpManager.callTool("doc_convert", { path: filePath });
7551
7934
  if (converted && !converted.startsWith("Error") && !converted.includes("Could not convert")) {
@@ -7554,7 +7937,7 @@ ${trimmed}
7554
7937
  <file path="${filePath}" format="${ext}">
7555
7938
  ${converted.slice(0, 5e4)}
7556
7939
  </file>`;
7557
- process.stdout.write(pc7.dim(` [attached: ${path19.basename(filePath)} (converted from ${ext})]
7940
+ process.stdout.write(pc7.dim(` [attached: ${path20.basename(filePath)} (converted from ${ext})]
7558
7941
  `));
7559
7942
  } else {
7560
7943
  textContent += `
@@ -7566,7 +7949,7 @@ ${converted}
7566
7949
  `));
7567
7950
  }
7568
7951
  } catch {
7569
- process.stdout.write(pc7.dim(` [could not convert: ${path19.basename(filePath)}]
7952
+ process.stdout.write(pc7.dim(` [could not convert: ${path20.basename(filePath)}]
7570
7953
  `));
7571
7954
  }
7572
7955
  } else {
@@ -7870,7 +8253,7 @@ ${result2.response}` : `[${input2.profile}] failed: ${result2.error}`;
7870
8253
  }
7871
8254
  if (hooksConfig?.featureHints) {
7872
8255
  hintState.turnCount++;
7873
- const hasWorkflows = fs19.existsSync(path19.join(os18.homedir(), ".aflow", "flow.md"));
8256
+ const hasWorkflows = fs20.existsSync(path20.join(os19.homedir(), ".aflow", "flow.md"));
7874
8257
  const memoryCount = memoryTokens > 0 ? Math.floor(memoryTokens / 5) : 0;
7875
8258
  const hint = getHint(hintState, { hasWorkflows, memoryCount });
7876
8259
  if (hint) {
@@ -7916,9 +8299,9 @@ async function saveConversationToMemory(messages, sessionId) {
7916
8299
  }
7917
8300
 
7918
8301
  // src/index.ts
7919
- import fs20 from "fs";
7920
- import path20 from "path";
7921
- import os19 from "os";
8302
+ import fs21 from "fs";
8303
+ import path21 from "path";
8304
+ import os20 from "os";
7922
8305
 
7923
8306
  // src/presets.ts
7924
8307
  var PRESETS = {
@@ -8027,9 +8410,9 @@ ${wfSections}`;
8027
8410
 
8028
8411
  // src/index.ts
8029
8412
  async function autoDetectConfig() {
8030
- const reconfigMarker = path20.join(os19.homedir(), ".aman-agent", ".reconfig");
8031
- if (fs20.existsSync(reconfigMarker)) {
8032
- fs20.unlinkSync(reconfigMarker);
8413
+ const reconfigMarker = path21.join(os20.homedir(), ".aman-agent", ".reconfig");
8414
+ if (fs21.existsSync(reconfigMarker)) {
8415
+ fs21.unlinkSync(reconfigMarker);
8033
8416
  return null;
8034
8417
  }
8035
8418
  const anthropicKey = process.env.ANTHROPIC_API_KEY;
@@ -8058,11 +8441,11 @@ async function autoDetectConfig() {
8058
8441
  return null;
8059
8442
  }
8060
8443
  function bootstrapEcosystem() {
8061
- const home2 = os19.homedir();
8062
- const corePath = path20.join(home2, ".acore", "core.md");
8063
- if (fs20.existsSync(corePath)) return false;
8064
- fs20.mkdirSync(path20.join(home2, ".acore"), { recursive: true });
8065
- fs20.writeFileSync(corePath, [
8444
+ const home2 = os20.homedir();
8445
+ const corePath = path21.join(home2, ".acore", "core.md");
8446
+ if (fs21.existsSync(corePath)) return false;
8447
+ fs21.mkdirSync(path21.join(home2, ".acore"), { recursive: true });
8448
+ fs21.writeFileSync(corePath, [
8066
8449
  "# Aman",
8067
8450
  "",
8068
8451
  "## Personality",
@@ -8074,11 +8457,11 @@ function bootstrapEcosystem() {
8074
8457
  "## Session",
8075
8458
  "_New companion \u2014 no prior sessions._"
8076
8459
  ].join("\n"), "utf-8");
8077
- const rulesDir = path20.join(home2, ".arules");
8078
- const rulesPath = path20.join(rulesDir, "rules.md");
8079
- if (!fs20.existsSync(rulesPath)) {
8080
- fs20.mkdirSync(rulesDir, { recursive: true });
8081
- fs20.writeFileSync(rulesPath, [
8460
+ const rulesDir = path21.join(home2, ".arules");
8461
+ const rulesPath = path21.join(rulesDir, "rules.md");
8462
+ if (!fs21.existsSync(rulesPath)) {
8463
+ fs21.mkdirSync(rulesDir, { recursive: true });
8464
+ fs21.writeFileSync(rulesPath, [
8082
8465
  "# Guardrails",
8083
8466
  "",
8084
8467
  "## safety",
@@ -8090,22 +8473,22 @@ function bootstrapEcosystem() {
8090
8473
  "- Respect the user's preferences stored in memory"
8091
8474
  ].join("\n"), "utf-8");
8092
8475
  }
8093
- const flowDir = path20.join(home2, ".aflow");
8094
- const flowPath = path20.join(flowDir, "flow.md");
8095
- if (!fs20.existsSync(flowPath)) {
8096
- fs20.mkdirSync(flowDir, { recursive: true });
8097
- fs20.writeFileSync(flowPath, "# Workflows\n\n_No workflows defined yet. Use /workflows add to create one._\n", "utf-8");
8476
+ const flowDir = path21.join(home2, ".aflow");
8477
+ const flowPath = path21.join(flowDir, "flow.md");
8478
+ if (!fs21.existsSync(flowPath)) {
8479
+ fs21.mkdirSync(flowDir, { recursive: true });
8480
+ fs21.writeFileSync(flowPath, "# Workflows\n\n_No workflows defined yet. Use /workflows add to create one._\n", "utf-8");
8098
8481
  }
8099
- const skillDir = path20.join(home2, ".askill");
8100
- const skillPath = path20.join(skillDir, "skills.md");
8101
- if (!fs20.existsSync(skillPath)) {
8102
- fs20.mkdirSync(skillDir, { recursive: true });
8103
- fs20.writeFileSync(skillPath, "# Skills\n\n_No skills installed yet. Use /skills install to add domain expertise._\n", "utf-8");
8482
+ const skillDir = path21.join(home2, ".askill");
8483
+ const skillPath = path21.join(skillDir, "skills.md");
8484
+ if (!fs21.existsSync(skillPath)) {
8485
+ fs21.mkdirSync(skillDir, { recursive: true });
8486
+ fs21.writeFileSync(skillPath, "# Skills\n\n_No skills installed yet. Use /skills install to add domain expertise._\n", "utf-8");
8104
8487
  }
8105
8488
  return true;
8106
8489
  }
8107
8490
  var program = new Command();
8108
- program.name("aman-agent").description("Your AI companion, running locally").version("0.26.0").option("--model <model>", "Override LLM model").option("--budget <tokens>", "Token budget for system prompt (default: 8000)", parseInt).option("--profile <name>", "Use a specific agent profile (e.g., coder, writer, researcher)").action(async (options) => {
8491
+ program.name("aman-agent").description("Your AI companion, running locally").version("0.27.0").option("--model <model>", "Override LLM model").option("--budget <tokens>", "Token budget for system prompt (default: 8000)", parseInt).option("--profile <name>", "Use a specific agent profile (e.g., coder, writer, researcher)").action(async (options) => {
8109
8492
  p3.intro(pc8.bold("aman agent") + pc8.dim(" \u2014 your AI companion"));
8110
8493
  let config = loadConfig();
8111
8494
  if (!config) {
@@ -8457,19 +8840,19 @@ program.command("init").description("Set up your AI companion with a guided wiza
8457
8840
  });
8458
8841
  if (p3.isCancel(preset)) process.exit(0);
8459
8842
  const result = applyPreset(preset, name || "Aman");
8460
- const home2 = os19.homedir();
8461
- fs20.mkdirSync(path20.join(home2, ".acore"), { recursive: true });
8462
- fs20.writeFileSync(path20.join(home2, ".acore", "core.md"), result.coreMd, "utf-8");
8843
+ const home2 = os20.homedir();
8844
+ fs21.mkdirSync(path21.join(home2, ".acore"), { recursive: true });
8845
+ fs21.writeFileSync(path21.join(home2, ".acore", "core.md"), result.coreMd, "utf-8");
8463
8846
  p3.log.success(`Identity created \u2014 ${PRESETS[preset].identity.personality.split(".")[0].toLowerCase()}`);
8464
8847
  if (result.rulesMd) {
8465
- fs20.mkdirSync(path20.join(home2, ".arules"), { recursive: true });
8466
- fs20.writeFileSync(path20.join(home2, ".arules", "rules.md"), result.rulesMd, "utf-8");
8848
+ fs21.mkdirSync(path21.join(home2, ".arules"), { recursive: true });
8849
+ fs21.writeFileSync(path21.join(home2, ".arules", "rules.md"), result.rulesMd, "utf-8");
8467
8850
  const ruleCount = (result.rulesMd.match(/^- /gm) || []).length;
8468
8851
  p3.log.success(`${ruleCount} rules set`);
8469
8852
  }
8470
8853
  if (result.flowMd) {
8471
- fs20.mkdirSync(path20.join(home2, ".aflow"), { recursive: true });
8472
- fs20.writeFileSync(path20.join(home2, ".aflow", "flow.md"), result.flowMd, "utf-8");
8854
+ fs21.mkdirSync(path21.join(home2, ".aflow"), { recursive: true });
8855
+ fs21.writeFileSync(path21.join(home2, ".aflow", "flow.md"), result.flowMd, "utf-8");
8473
8856
  const wfCount = (result.flowMd.match(/^## /gm) || []).length;
8474
8857
  p3.log.success(`${wfCount} workflow${wfCount > 1 ? "s" : ""} added`);
8475
8858
  }