incremnt 0.1.13 → 0.1.16

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/src/queries.js CHANGED
@@ -58,7 +58,8 @@ function sessionSummary(session) {
58
58
  recommendations: session.recommendations ?? {},
59
59
  historicalContext: session.historicalContext ?? null,
60
60
  prescriptionSnapshot: session.prescriptionSnapshot ?? null,
61
- aiCoachNotes: session.aiCoachNotes ?? null
61
+ aiCoachNotes: session.summary?.aiCoachNotes ?? null,
62
+ aiCoachModel: session.summary?.aiCoachModel ?? null
62
63
  };
63
64
  }
64
65
 
@@ -648,6 +649,39 @@ export function cycleSummaryContext(snapshot, programId) {
648
649
  ? { completed: matchingSummary.totalSetsCompleted ?? 0, planned: matchingSummary.totalSetsPlanned ?? 0 }
649
650
  : null;
650
651
 
652
+ // Health metrics spanning the cycle
653
+ const cycleStart = String(cycleSessions[0] ? completionDateForSession(cycleSessions[0]) : '');
654
+ const cycleEnd = String(cycleSessions[cycleSessions.length - 1]
655
+ ? completionDateForSession(cycleSessions[cycleSessions.length - 1]) : '');
656
+ const cycleCardio = (snapshot.healthMetrics?.otherWorkouts ?? [])
657
+ .filter((w) => w.date >= cycleStart && w.date <= cycleEnd);
658
+ const cycleRestingHR = (snapshot.healthMetrics?.restingHR ?? [])
659
+ .filter((m) => m.date >= cycleStart && m.date <= cycleEnd);
660
+ const cycleHRV = (snapshot.healthMetrics?.hrv ?? [])
661
+ .filter((m) => m.date >= cycleStart && m.date <= cycleEnd);
662
+ const cycleVO2Max = (snapshot.healthMetrics?.vo2Max ?? [])
663
+ .filter((m) => m.date >= cycleStart && m.date <= cycleEnd);
664
+ const cycleSleep = (snapshot.healthMetrics?.sleep ?? [])
665
+ .filter((m) => m.date >= cycleStart && m.date <= cycleEnd);
666
+
667
+ const avgRestingHR = cycleRestingHR.length > 0
668
+ ? Math.round(cycleRestingHR.reduce((s, m) => s + m.value, 0) / cycleRestingHR.length)
669
+ : null;
670
+ const avgHRV = cycleHRV.length > 0
671
+ ? Math.round(cycleHRV.reduce((s, m) => s + m.value, 0) / cycleHRV.length)
672
+ : null;
673
+ const latestVO2Max = cycleVO2Max.length > 0
674
+ ? Math.round(cycleVO2Max.at(-1).value * 10) / 10
675
+ : null;
676
+ const avgSleepMins = cycleSleep.length > 0
677
+ ? Math.round(cycleSleep.reduce((s, m) => s + m.durationMins, 0) / cycleSleep.length)
678
+ : null;
679
+ const cycleBodyWeight = (snapshot.healthMetrics?.bodyWeight ?? [])
680
+ .filter((m) => m.date >= cycleStart && m.date <= cycleEnd);
681
+ const latestBodyWeightKg = cycleBodyWeight.length > 0
682
+ ? Math.round(cycleBodyWeight.at(-1).value * 10) / 10
683
+ : null;
684
+
651
685
  return {
652
686
  programName: program.name,
653
687
  cycleNumber: cycleWeekNumber,
@@ -661,7 +695,13 @@ export function cycleSummaryContext(snapshot, programId) {
661
695
  cycleIntent,
662
696
  adaptationNote,
663
697
  previousCycles,
664
- exerciseTrends
698
+ exerciseTrends,
699
+ cycleCardio: cycleCardio.length > 0 ? cycleCardio : null,
700
+ avgRestingHR,
701
+ avgHRV,
702
+ latestVO2Max,
703
+ avgSleepMins,
704
+ latestBodyWeightKg
665
705
  };
666
706
  }
667
707
 
@@ -692,24 +732,26 @@ export function workoutSummaryContext(snapshot, sessionId) {
692
732
  };
693
733
  });
694
734
 
695
- // Find recent sessions with same dayName for comparison (up to 3, excluding current)
735
+ // Find recent sessions with same dayName for comparison (up to 3, excluding current).
736
+ // Match across programs so context survives program switches.
696
737
  const recentComparisons = sessions
697
738
  .filter(
698
739
  (s) =>
699
740
  s.id !== sessionId &&
700
- s.dayName === dayName &&
701
- s.programId === session.programId
741
+ s.dayName === dayName
702
742
  )
703
743
  .sort((a, b) => String(completionDateForSession(b)).localeCompare(String(completionDateForSession(a))))
704
744
  .slice(0, 3)
705
745
  .map((s) => ({
706
746
  date: completionDateForSession(s),
707
747
  totalVolume: s.summary?.totalVolume ?? s.volume ?? 0,
708
- effortScore: s.summary?.effortScore ?? null
748
+ effortScore: s.summary?.effortScore ?? null,
749
+ programName: s.programName ?? null
709
750
  }));
710
751
 
711
- // Detect PRs compare each exercise's best e1RM against all prior sessions
752
+ // Count prior sessions per exercise and track best e1RM scores
712
753
  const priorBests = new Map();
754
+ const exerciseSessionCounts = new Map();
713
755
  for (const s of sessions) {
714
756
  if (s.id === sessionId) continue;
715
757
  const sDate = String(completionDateForSession(s));
@@ -717,9 +759,10 @@ export function workoutSummaryContext(snapshot, sessionId) {
717
759
  if (sDate >= currentDate) continue;
718
760
 
719
761
  for (const exercise of s.exercises ?? []) {
762
+ const key = normalizeExerciseName(exercise.name);
763
+ exerciseSessionCounts.set(key, (exerciseSessionCounts.get(key) ?? 0) + 1);
720
764
  for (const set of exercise.sets ?? []) {
721
765
  if (!set.isComplete) continue;
722
- const key = normalizeExerciseName(exercise.name);
723
766
  const score = Number(set.weight) * (1 + Number(set.reps) / 30);
724
767
  const current = priorBests.get(key);
725
768
  if (!current || score > current) priorBests.set(key, score);
@@ -727,14 +770,22 @@ export function workoutSummaryContext(snapshot, sessionId) {
727
770
  }
728
771
  }
729
772
 
773
+ // Attach prior session count to each exercise
774
+ for (const ex of exercises) {
775
+ const key = normalizeExerciseName(ex.exerciseName);
776
+ ex.priorSessions = exerciseSessionCounts.get(key) ?? 0;
777
+ }
778
+
779
+ // Detect PRs — skip first-time exercises (every set is trivially a "PR")
730
780
  const prs = [];
731
781
  for (const exercise of session.exercises ?? []) {
732
782
  const key = normalizeExerciseName(exercise.name);
783
+ if (!priorBests.has(key)) continue;
733
784
  for (const set of exercise.sets ?? []) {
734
785
  if (!set.isComplete) continue;
735
786
  const score = Number(set.weight) * (1 + Number(set.reps) / 30);
736
787
  const prior = priorBests.get(key);
737
- if (!prior || score > prior) {
788
+ if (score > prior) {
738
789
  prs.push({
739
790
  exerciseName: exercise.name,
740
791
  weight: set.weight,
@@ -760,19 +811,246 @@ export function workoutSummaryContext(snapshot, sessionId) {
760
811
  }
761
812
  }
762
813
 
814
+ const isAdhoc = !session.programId;
815
+
816
+ // Include other workouts from the 7 days before this session for coach context
817
+ const sessionDateStr = String(sessionDate);
818
+ const weekBefore = new Date(new Date(sessionDateStr).getTime() - 7 * 24 * 60 * 60 * 1000)
819
+ .toISOString().slice(0, 10);
820
+ const nearbyCardio = (snapshot.healthMetrics?.otherWorkouts ?? [])
821
+ .filter((w) => w.date >= weekBefore && w.date <= sessionDateStr);
822
+
823
+ const restingHROnDay = (snapshot.healthMetrics?.restingHR ?? [])
824
+ .find((m) => m.date === sessionDateStr);
825
+ const hrvOnDay = (snapshot.healthMetrics?.hrv ?? [])
826
+ .find((m) => m.date === sessionDateStr);
827
+ const sleepNight = (snapshot.healthMetrics?.sleep ?? [])
828
+ .find((m) => m.date === sessionDateStr);
829
+ const vo2MaxRecent = (snapshot.healthMetrics?.vo2Max ?? [])
830
+ .filter((m) => m.date >= weekBefore && m.date <= sessionDateStr);
831
+ const vo2MaxLatest = vo2MaxRecent.length > 0
832
+ ? Math.round(vo2MaxRecent.at(-1).value * 10) / 10
833
+ : null;
834
+ const bodyWeightOnDay = (snapshot.healthMetrics?.bodyWeight ?? [])
835
+ .find((m) => m.date === sessionDateStr);
836
+ const bodyWeightKg = bodyWeightOnDay
837
+ ? Math.round(bodyWeightOnDay.value * 10) / 10
838
+ : null;
839
+
763
840
  const result = {
764
841
  sessionDate,
765
842
  dayName,
843
+ programName: session.programName ?? null,
844
+ isAdhoc,
766
845
  totalVolume: session.summary?.totalVolume ?? session.volume ?? 0,
767
846
  effortScore: session.summary?.effortScore ?? null,
768
847
  exercises,
769
848
  recentComparisons,
770
- prs
849
+ prs,
850
+ nearbyCardio: nearbyCardio.length > 0 ? nearbyCardio : null,
851
+ restingHROnDay: restingHROnDay?.value ?? null,
852
+ hrvOnDay: hrvOnDay?.value ?? null,
853
+ vo2MaxLatest,
854
+ sleepNight: sleepNight ?? null,
855
+ bodyWeightKg
771
856
  };
772
857
  if (planComparison) result.planComparison = planComparison;
773
858
  return result;
774
859
  }
775
860
 
861
+ export function askContext(snapshot) {
862
+ const sessions = snapshot.sessions ?? [];
863
+ const lines = [];
864
+
865
+ lines.push(`Training overview: ${sessions.length} total workouts logged.`);
866
+
867
+ // Training frequency (last 4 weeks)
868
+ const fourWeeksAgo = new Date(Date.now() - 28 * 24 * 60 * 60 * 1000).toISOString();
869
+ const recentCount = sessions.filter((s) => String(completionDateForSession(s)) >= fourWeeksAgo).length;
870
+ if (recentCount > 0) {
871
+ const perWeek = (recentCount / 4).toFixed(1);
872
+ lines.push(`Recent frequency: ${perWeek} sessions/week (last 4 weeks).`);
873
+ }
874
+
875
+ // Current program
876
+ const program = activeProgram(snapshot);
877
+ if (program) {
878
+ lines.push(`Current program: ${program.name}, ${program.daysPerWeek} days/week, equipment: ${program.equipmentTier ?? 'unknown'}.`);
879
+ }
880
+
881
+ // Best e1RM records (top 15)
882
+ const bestByExercise = new Map();
883
+ for (const session of sessions) {
884
+ for (const exercise of session.exercises ?? []) {
885
+ const key = normalizeExerciseName(exercise.name);
886
+ for (const set of exercise.sets ?? []) {
887
+ if (!set.isComplete) continue;
888
+ const e1rm = Number(set.weight) * (1 + Number(set.reps) / 30);
889
+ const current = bestByExercise.get(key);
890
+ if (!current || e1rm > current.e1rm) {
891
+ bestByExercise.set(key, { name: exercise.name, e1rm });
892
+ }
893
+ }
894
+ }
895
+ }
896
+
897
+ const records = [...bestByExercise.values()]
898
+ .filter((r) => r.e1rm > 0)
899
+ .sort((a, b) => b.e1rm - a.e1rm)
900
+ .slice(0, 15);
901
+
902
+ if (records.length > 0) {
903
+ lines.push('');
904
+ lines.push('Best estimated 1RM records:');
905
+ for (const r of records) {
906
+ lines.push(` ${r.name}: ${r.e1rm.toFixed(1)} kg`);
907
+ }
908
+ }
909
+
910
+ // Recent sessions (last 10)
911
+ const recentSessions = sessions.slice(-10);
912
+ if (recentSessions.length > 0) {
913
+ lines.push('');
914
+ lines.push('Recent sessions (newest last):');
915
+ for (const session of recentSessions) {
916
+ const dateStr = completionDateForSession(session);
917
+ const dayLabel = session.dayName ?? session.programName ?? 'Workout';
918
+ const exerciseNames = (session.exercises ?? []).map((e) => e.name).join(', ');
919
+ const volume = session.summary?.totalVolume ?? session.volume ?? 0;
920
+ let line = ` ${dateStr} - ${dayLabel}: ${exerciseNames}`;
921
+ if (volume > 0) line += ` (${volume} kg volume)`;
922
+ lines.push(line);
923
+
924
+ for (const exercise of session.exercises ?? []) {
925
+ const completedSets = (exercise.sets ?? []).filter((s) => s.isComplete);
926
+ if (completedSets.length === 0) continue;
927
+ const topSet = completedSets.reduce((best, s) => {
928
+ const score = Number(s.weight) * Number(s.reps);
929
+ const bestScore = Number(best.weight) * Number(best.reps);
930
+ return score > bestScore ? s : best;
931
+ });
932
+ lines.push(` ${exercise.name}: ${completedSets.length} sets, top ${Number(topSet.weight).toFixed(1)}x${topSet.reps}`);
933
+ }
934
+ }
935
+ }
936
+
937
+ appendHealthMetricsContext(lines, snapshot.healthMetrics, { recentDays: 14 });
938
+
939
+ return lines.join('\n');
940
+ }
941
+
942
+ function appendHealthMetricsContext(lines, metrics, { recentDays = 14 } = {}) {
943
+ if (!metrics) return;
944
+
945
+ const cutoff = new Date(Date.now() - recentDays * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
946
+
947
+ const recentWorkouts = (metrics.otherWorkouts ?? []).filter((w) => w.date >= cutoff);
948
+ if (recentWorkouts.length > 0) {
949
+ lines.push('');
950
+ lines.push(`Other workouts (last ${recentDays} days):`);
951
+ for (const w of recentWorkouts) {
952
+ const parts = [`${w.durationSecs ? Math.round(w.durationSecs / 60) : '?'} min`];
953
+ if (w.distanceKm) parts.push(`${w.distanceKm.toFixed(1)} km`);
954
+ if (w.avgHR) parts.push(`avg HR ${w.avgHR} bpm`);
955
+ if (w.calories) parts.push(`${w.calories} kcal`);
956
+ if (w.effortScore) parts.push(`effort ${w.effortScore}/10`);
957
+ lines.push(` ${w.date} ${w.workoutType}: ${parts.join(', ')}`);
958
+ }
959
+ }
960
+
961
+ const recentRestingHR = (metrics.restingHR ?? []).filter((m) => m.date >= cutoff);
962
+ if (recentRestingHR.length > 0) {
963
+ const avg = Math.round(recentRestingHR.reduce((s, m) => s + m.value, 0) / recentRestingHR.length);
964
+ const latest = recentRestingHR[recentRestingHR.length - 1];
965
+ lines.push('');
966
+ lines.push(`Resting HR (last ${recentDays} days): avg ${avg} bpm, latest ${Math.round(latest.value)} bpm (${latest.date})`);
967
+ }
968
+
969
+ const recentHRV = (metrics.hrv ?? []).filter((m) => m.date >= cutoff);
970
+ if (recentHRV.length > 0) {
971
+ const avg = Math.round(recentHRV.reduce((s, m) => s + m.value, 0) / recentHRV.length);
972
+ const latest = recentHRV[recentHRV.length - 1];
973
+ lines.push(`HRV (last ${recentDays} days): avg ${avg} ms, latest ${Math.round(latest.value)} ms (${latest.date})`);
974
+ }
975
+
976
+ const recentVO2Max = (metrics.vo2Max ?? []).filter((m) => m.date >= cutoff);
977
+ if (recentVO2Max.length > 0) {
978
+ const latest = recentVO2Max[recentVO2Max.length - 1];
979
+ lines.push(`VO2 Max: ${Math.round(latest.value * 10) / 10} ml/kg/min (${latest.date})`);
980
+ }
981
+
982
+ const recentSleep = (metrics.sleep ?? []).filter((m) => m.date >= cutoff);
983
+ if (recentSleep.length > 0) {
984
+ const avgMins = Math.round(recentSleep.reduce((s, m) => s + m.durationMins, 0) / recentSleep.length);
985
+ const avgHours = (avgMins / 60).toFixed(1);
986
+ lines.push(`Sleep (last ${recentDays} days): avg ${avgHours}h/night`);
987
+ }
988
+
989
+ const recentBodyWeight = (metrics.bodyWeight ?? []).filter((m) => m.date >= cutoff);
990
+ if (recentBodyWeight.length > 0) {
991
+ const latest = recentBodyWeight[recentBodyWeight.length - 1];
992
+ const earliest = recentBodyWeight[0];
993
+ const delta = (latest.value - earliest.value).toFixed(1);
994
+ const trend = delta > 0 ? `+${delta}` : delta;
995
+ lines.push(`Body weight (last ${recentDays} days): latest ${latest.value.toFixed(1)} kg (${latest.date}), ${recentBodyWeight.length} readings, trend ${trend} kg`);
996
+ }
997
+ }
998
+
999
+ function healthSummary(snapshot, days = 14) {
1000
+ const metrics = snapshot.healthMetrics;
1001
+ if (!metrics) return { available: false };
1002
+
1003
+ const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
1004
+
1005
+ const recentWorkouts = (metrics.otherWorkouts ?? []).filter((w) => w.date >= cutoff);
1006
+ const recentRestingHR = (metrics.restingHR ?? []).filter((m) => m.date >= cutoff);
1007
+ const recentHRV = (metrics.hrv ?? []).filter((m) => m.date >= cutoff);
1008
+ const recentVO2Max = (metrics.vo2Max ?? []).filter((m) => m.date >= cutoff);
1009
+ const recentSleep = (metrics.sleep ?? []).filter((m) => m.date >= cutoff);
1010
+
1011
+ const avg = (arr) => arr.length > 0 ? arr.reduce((s, m) => s + m.value, 0) / arr.length : null;
1012
+
1013
+ return {
1014
+ available: true,
1015
+ days,
1016
+ cardio: recentWorkouts.map((w) => ({
1017
+ date: w.date,
1018
+ workoutType: w.workoutType,
1019
+ durationMins: w.durationSecs ? Math.round(w.durationSecs / 60) : null,
1020
+ distanceKm: w.distanceKm ?? null,
1021
+ avgHR: w.avgHR ?? null,
1022
+ calories: w.calories ?? null
1023
+ })),
1024
+ restingHR: {
1025
+ avg: recentRestingHR.length > 0 ? Math.round(avg(recentRestingHR)) : null,
1026
+ latest: recentRestingHR.length > 0 ? { value: Math.round(recentRestingHR.at(-1).value), date: recentRestingHR.at(-1).date } : null,
1027
+ readings: recentRestingHR.length
1028
+ },
1029
+ hrv: {
1030
+ avg: recentHRV.length > 0 ? Math.round(avg(recentHRV)) : null,
1031
+ latest: recentHRV.length > 0 ? { value: Math.round(recentHRV.at(-1).value), date: recentHRV.at(-1).date } : null,
1032
+ readings: recentHRV.length
1033
+ },
1034
+ vo2Max: {
1035
+ latest: recentVO2Max.length > 0 ? { value: Math.round(recentVO2Max.at(-1).value * 10) / 10, date: recentVO2Max.at(-1).date } : null,
1036
+ readings: recentVO2Max.length
1037
+ },
1038
+ sleep: {
1039
+ avgHours: recentSleep.length > 0 ? Math.round(recentSleep.reduce((s, m) => s + m.durationMins, 0) / recentSleep.length / 60 * 10) / 10 : null,
1040
+ nights: recentSleep.length
1041
+ },
1042
+ bodyWeight: (() => {
1043
+ const recent = (metrics.bodyWeight ?? []).filter((m) => m.date >= cutoff);
1044
+ if (recent.length === 0) return { latest: null, readings: 0 };
1045
+ return {
1046
+ latest: { value: Math.round(recent.at(-1).value * 10) / 10, date: recent.at(-1).date },
1047
+ trend: Math.round((recent.at(-1).value - recent[0].value) * 10) / 10,
1048
+ readings: recent.length
1049
+ };
1050
+ })()
1051
+ };
1052
+ }
1053
+
776
1054
  function requiredOption(options, primaryKey, legacyKey = null) {
777
1055
  return options[primaryKey] ?? (legacyKey ? options[legacyKey] : undefined);
778
1056
  }
@@ -894,5 +1172,10 @@ export function executeReadCommand(snapshot, normalizedCommand, options = {}) {
894
1172
  return { ok: true, payload };
895
1173
  }
896
1174
 
1175
+ if (normalizedCommand === 'health-summary') {
1176
+ const days = Number.parseInt(options.days ?? '14', 10);
1177
+ return { ok: true, payload: healthSummary(snapshot, Number.isNaN(days) ? 14 : days) };
1178
+ }
1179
+
897
1180
  return { ok: false, error: `Unknown read command: ${normalizedCommand}` };
898
1181
  }
package/src/remote.js CHANGED
@@ -29,10 +29,15 @@ const remoteCommandHandlers = {
29
29
  'program-list': executeRemoteRead,
30
30
  'program-summary': executeRemoteRead,
31
31
  'program-detail': executeRemoteRead,
32
+ 'cycle-summary-list': executeRemoteRead,
33
+ 'cycle-summary-show': executeRemoteRead,
32
34
  'planned-vs-actual': executeRemoteRead,
33
35
  'why-did-this-change': executeRemoteRead,
34
36
  'goals-list': executeRemoteRead,
35
- 'goals-show': executeRemoteRead
37
+ 'goals-show': executeRemoteRead,
38
+ 'health-summary': executeRemoteRead,
39
+ 'ask-history': executeRemoteRead,
40
+ 'ask-show': executeRemoteRead
36
41
  };
37
42
 
38
43
  async function executeRemoteRead(options, sessionState, normalizedCommand) {
@@ -111,6 +116,15 @@ function endpointForCommand(baseUrl, normalizedCommand, options) {
111
116
  return resolveServiceUrl(baseUrl, '/cli/programs/current');
112
117
  case 'program-detail':
113
118
  return resolveServiceUrl(baseUrl, options.id ? `/cli/programs/${options.id}` : '/cli/programs/active');
119
+ case 'cycle-summary-list': {
120
+ const cyclesUrl = resolveServiceUrl(baseUrl, '/cli/cycles');
121
+ if (options['program-id']) {
122
+ cyclesUrl.searchParams.set('program-id', options['program-id']);
123
+ }
124
+ return cyclesUrl;
125
+ }
126
+ case 'cycle-summary-show':
127
+ return resolveServiceUrl(baseUrl, `/cli/cycles/${options.id}`);
114
128
  case 'exercise-history': {
115
129
  const historyUrl = resolveServiceUrl(baseUrl, '/cli/exercises/history');
116
130
  historyUrl.searchParams.set('name', options.name ?? options.exercise);
@@ -122,6 +136,22 @@ function endpointForCommand(baseUrl, normalizedCommand, options) {
122
136
  return resolveServiceUrl(baseUrl, '/cli/goals');
123
137
  case 'goals-show':
124
138
  return resolveServiceUrl(baseUrl, options.id ? `/cli/goals/${options.id}` : '/cli/goals');
139
+ case 'health-summary': {
140
+ const healthUrl = resolveServiceUrl(baseUrl, '/cli/health/summary');
141
+ if (options.days) {
142
+ healthUrl.searchParams.set('days', options.days);
143
+ }
144
+ return healthUrl;
145
+ }
146
+ case 'ask-history': {
147
+ const askUrl = resolveServiceUrl(baseUrl, '/cli/ask/history');
148
+ if (options.limit) {
149
+ askUrl.searchParams.set('limit', options.limit);
150
+ }
151
+ return askUrl;
152
+ }
153
+ case 'ask-show':
154
+ return resolveServiceUrl(baseUrl, `/cli/ask/history/${options.id}`);
125
155
  default:
126
156
  return resolveServiceUrl(baseUrl, '/');
127
157
  }
@@ -136,6 +166,14 @@ function resourceNotFoundMessage(normalizedCommand, options) {
136
166
  return `Session not found: ${options['session-id']}`;
137
167
  }
138
168
 
169
+ if (normalizedCommand === 'cycle-summary-show') {
170
+ return `Cycle summary not found: ${options.id}`;
171
+ }
172
+
173
+ if (normalizedCommand === 'ask-show') {
174
+ return `Conversation not found: ${options.id}`;
175
+ }
176
+
139
177
  return 'Requested resource was not found.';
140
178
  }
141
179