@pellux/goodvibes-agent 0.1.51 → 0.1.52

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/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  All notable changes to GoodVibes Agent will be recorded here.
4
4
 
5
+ ## 0.1.52 - 2026-05-31
6
+
7
+ - e543fa5 Add selected local library actions
8
+
5
9
  ## 0.1.51 - 2026-05-31
6
10
 
7
11
  - 6a8e8a6 Add local library workspace editors
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pellux/goodvibes-agent",
3
- "version": "0.1.51",
3
+ "version": "0.1.52",
4
4
  "private": false,
5
5
  "description": "Near-fork GoodVibes operator assistant with the GoodVibes TUI shell, renderer, input, fullscreen workspace, and daemon-connected Agent product brain.",
6
6
  "type": "module",
@@ -20,10 +20,22 @@ export const AGENT_WORKSPACE_MODAL_NAME = 'agentWorkspace';
20
20
 
21
21
  export type AgentWorkspaceFocusPane = 'categories' | 'actions';
22
22
 
23
- export type AgentWorkspaceActionKind = 'command' | 'guidance' | 'workspace' | 'editor';
23
+ export type AgentWorkspaceActionKind = 'command' | 'guidance' | 'workspace' | 'editor' | 'local-selection' | 'local-operation';
24
24
 
25
25
  export type AgentWorkspaceLocalEditorKind = 'persona' | 'skill' | 'routine';
26
26
 
27
+ export type AgentWorkspaceLocalOperation =
28
+ | 'persona-use'
29
+ | 'persona-review'
30
+ | 'persona-clear'
31
+ | 'skill-enable'
32
+ | 'skill-disable'
33
+ | 'skill-review'
34
+ | 'routine-start'
35
+ | 'routine-enable'
36
+ | 'routine-disable'
37
+ | 'routine-review';
38
+
27
39
  export interface AgentWorkspaceEditorField {
28
40
  readonly id: string;
29
41
  readonly label: string;
@@ -48,6 +60,9 @@ export interface AgentWorkspaceAction {
48
60
  readonly command?: string;
49
61
  readonly targetCategoryId?: string;
50
62
  readonly editorKind?: AgentWorkspaceLocalEditorKind;
63
+ readonly localKind?: AgentWorkspaceLocalEditorKind;
64
+ readonly selectionDelta?: number;
65
+ readonly localOperation?: AgentWorkspaceLocalOperation;
51
66
  readonly kind: AgentWorkspaceActionKind;
52
67
  readonly safety: 'safe' | 'read-only' | 'delegates' | 'blocked';
53
68
  }
@@ -515,10 +530,12 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
515
530
  actions: [
516
531
  { id: 'personas-list', label: 'List personas', detail: 'Print the full local persona library.', command: '/personas list', kind: 'command', safety: 'read-only' },
517
532
  { id: 'personas-active', label: 'Show active persona', detail: 'Inspect the active local persona applied to new turns.', command: '/personas active', kind: 'command', safety: 'read-only' },
533
+ { id: 'personas-prev', label: 'Previous persona', detail: 'Move the local persona selection up without changing active state.', localKind: 'persona', selectionDelta: -1, kind: 'local-selection', safety: 'safe' },
534
+ { id: 'personas-next', label: 'Next persona', detail: 'Move the local persona selection down without changing active state.', localKind: 'persona', selectionDelta: 1, kind: 'local-selection', safety: 'safe' },
518
535
  { id: 'personas-create', label: 'Create persona', detail: 'Open an in-workspace form for a local persona. No placeholder command is dispatched.', editorKind: 'persona', kind: 'editor', safety: 'safe' },
519
- { id: 'personas-use', label: 'Use persona', detail: 'Activate a local persona by id or name.', command: '/personas use <id>', kind: 'command', safety: 'safe' },
520
- { id: 'personas-review', label: 'Review persona', detail: 'Mark a local persona reviewed after inspecting it.', command: '/personas review <id>', kind: 'command', safety: 'safe' },
521
- { id: 'personas-clear', label: 'Clear active persona', detail: 'Return to the default Agent policy without deleting any persona.', command: '/personas clear', kind: 'command', safety: 'safe' },
536
+ { id: 'personas-use', label: 'Use selected', detail: 'Activate the selected local persona for future main-conversation turns.', localKind: 'persona', localOperation: 'persona-use', kind: 'local-operation', safety: 'safe' },
537
+ { id: 'personas-review', label: 'Review selected', detail: 'Mark the selected local persona reviewed after inspecting it.', localKind: 'persona', localOperation: 'persona-review', kind: 'local-operation', safety: 'safe' },
538
+ { id: 'personas-clear', label: 'Clear active persona', detail: 'Return to the default Agent policy without deleting any persona.', localKind: 'persona', localOperation: 'persona-clear', kind: 'local-operation', safety: 'safe' },
522
539
  ],
523
540
  },
524
541
  {
@@ -530,9 +547,12 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
530
547
  actions: [
531
548
  { id: 'skills-list', label: 'List skills', detail: 'Print the full local Agent skill library.', command: '/agent-skills list', kind: 'command', safety: 'read-only' },
532
549
  { id: 'skills-enabled', label: 'Enabled skills', detail: 'Show only skills currently injected into Agent guidance.', command: '/agent-skills enabled', kind: 'command', safety: 'read-only' },
550
+ { id: 'skills-prev', label: 'Previous skill', detail: 'Move the local skill selection up without changing enabled state.', localKind: 'skill', selectionDelta: -1, kind: 'local-selection', safety: 'safe' },
551
+ { id: 'skills-next', label: 'Next skill', detail: 'Move the local skill selection down without changing enabled state.', localKind: 'skill', selectionDelta: 1, kind: 'local-selection', safety: 'safe' },
533
552
  { id: 'skills-create', label: 'Create skill', detail: 'Open an in-workspace form for a reusable local procedure. No placeholder command is dispatched.', editorKind: 'skill', kind: 'editor', safety: 'safe' },
534
- { id: 'skills-enable', label: 'Enable skill', detail: 'Enable a local Agent skill by id or name.', command: '/agent-skills enable <id>', kind: 'command', safety: 'safe' },
535
- { id: 'skills-review', label: 'Review skill', detail: 'Mark a local skill reviewed after inspecting it.', command: '/agent-skills review <id>', kind: 'command', safety: 'safe' },
553
+ { id: 'skills-enable', label: 'Enable selected', detail: 'Enable the selected local Agent skill for future main-conversation guidance.', localKind: 'skill', localOperation: 'skill-enable', kind: 'local-operation', safety: 'safe' },
554
+ { id: 'skills-disable', label: 'Disable selected', detail: 'Disable the selected local Agent skill without deleting it.', localKind: 'skill', localOperation: 'skill-disable', kind: 'local-operation', safety: 'safe' },
555
+ { id: 'skills-review', label: 'Review selected', detail: 'Mark the selected local skill reviewed after inspecting it.', localKind: 'skill', localOperation: 'skill-review', kind: 'local-operation', safety: 'safe' },
536
556
  ],
537
557
  },
538
558
  {
@@ -544,8 +564,13 @@ export const AGENT_WORKSPACE_CATEGORIES: readonly AgentWorkspaceCategory[] = [
544
564
  actions: [
545
565
  { id: 'routines-list', label: 'List routines', detail: 'Print the full local Agent routine library.', command: '/routines list', kind: 'command', safety: 'read-only' },
546
566
  { id: 'routines-enabled', label: 'Enabled routines', detail: 'Show routines available for direct use.', command: '/routines enabled', kind: 'command', safety: 'read-only' },
567
+ { id: 'routines-prev', label: 'Previous routine', detail: 'Move the local routine selection up without changing enabled state.', localKind: 'routine', selectionDelta: -1, kind: 'local-selection', safety: 'safe' },
568
+ { id: 'routines-next', label: 'Next routine', detail: 'Move the local routine selection down without changing enabled state.', localKind: 'routine', selectionDelta: 1, kind: 'local-selection', safety: 'safe' },
547
569
  { id: 'routines-create', label: 'Create routine', detail: 'Open an in-workspace form for a repeatable local workflow. No placeholder command is dispatched.', editorKind: 'routine', kind: 'editor', safety: 'safe' },
548
- { id: 'routines-start', label: 'Start routine', detail: 'Start a local routine in the main conversation without creating a hidden job.', command: '/routines start <id>', kind: 'command', safety: 'safe' },
570
+ { id: 'routines-start', label: 'Start selected', detail: 'Mark the selected routine started and show it as a main-conversation workflow. This creates no hidden job.', localKind: 'routine', localOperation: 'routine-start', kind: 'local-operation', safety: 'safe' },
571
+ { id: 'routines-enable', label: 'Enable selected', detail: 'Enable the selected routine for future main-conversation guidance.', localKind: 'routine', localOperation: 'routine-enable', kind: 'local-operation', safety: 'safe' },
572
+ { id: 'routines-disable', label: 'Disable selected', detail: 'Disable the selected routine without deleting it.', localKind: 'routine', localOperation: 'routine-disable', kind: 'local-operation', safety: 'safe' },
573
+ { id: 'routines-review', label: 'Review selected', detail: 'Mark the selected local routine reviewed after inspecting it.', localKind: 'routine', localOperation: 'routine-review', kind: 'local-operation', safety: 'safe' },
549
574
  { id: 'routines-promote', label: 'Promote to schedule', detail: 'Create an external daemon schedule from a reviewed routine only with real timing and --yes.', command: '/routines promote <id> --cron <expr> --yes', kind: 'command', safety: 'safe' },
550
575
  { id: 'routines-receipts', label: 'Promotion receipts', detail: 'Inspect local redacted routine schedule promotion receipts.', command: '/routines receipts', kind: 'command', safety: 'read-only' },
551
576
  ],
@@ -671,6 +696,11 @@ export class AgentWorkspace {
671
696
  public runtimeSnapshot: AgentWorkspaceRuntimeSnapshot | null = null;
672
697
  public lastActionResult: AgentWorkspaceActionResult | null = null;
673
698
  public localEditor: AgentWorkspaceLocalEditor | null = null;
699
+ private readonly selectedLibraryItemIndexes: Record<AgentWorkspaceLocalEditorKind, number> = {
700
+ persona: 0,
701
+ skill: 0,
702
+ routine: 0,
703
+ };
674
704
  private context: CommandContext | null = null;
675
705
  private dispatchCommand: AgentWorkspaceCommandDispatcher | null = null;
676
706
 
@@ -712,6 +742,13 @@ export class AgentWorkspace {
712
742
  return this.actions[this.selectedActionIndex] ?? null;
713
743
  }
714
744
 
745
+ selectedLocalLibraryItem(kind: AgentWorkspaceLocalEditorKind): AgentWorkspaceLocalLibraryItem | null {
746
+ const items = this.localLibraryItems(kind);
747
+ if (items.length === 0) return null;
748
+ const index = Math.max(0, Math.min(this.selectedLibraryItemIndexes[kind], items.length - 1));
749
+ return items[index] ?? null;
750
+ }
751
+
715
752
  focusCategories(): void {
716
753
  this.focusPane = 'categories';
717
754
  }
@@ -855,6 +892,14 @@ export class AgentWorkspace {
855
892
  };
856
893
  return;
857
894
  }
895
+ if (action.kind === 'local-selection' && action.localKind) {
896
+ this.moveLocalLibraryItemSelection(action.localKind, action.selectionDelta ?? 0);
897
+ return;
898
+ }
899
+ if (action.kind === 'local-operation' && action.localOperation) {
900
+ this.applyLocalLibraryOperation(action.localOperation);
901
+ return;
902
+ }
858
903
  if (action.kind === 'guidance' || !action.command) {
859
904
  if (action.kind === 'workspace' && action.targetCategoryId) {
860
905
  const targetIndex = this.categories.findIndex((category) => category.id === action.targetCategoryId);
@@ -948,6 +993,130 @@ export class AgentWorkspace {
948
993
  private clampSelection(): void {
949
994
  this.selectedCategoryIndex = Math.max(0, Math.min(this.selectedCategoryIndex, this.categories.length - 1));
950
995
  this.selectedActionIndex = Math.max(0, Math.min(this.selectedActionIndex, this.actions.length - 1));
996
+ this.clampLocalLibrarySelection('persona');
997
+ this.clampLocalLibrarySelection('skill');
998
+ this.clampLocalLibrarySelection('routine');
999
+ }
1000
+
1001
+ private localLibraryItems(kind: AgentWorkspaceLocalEditorKind): readonly AgentWorkspaceLocalLibraryItem[] {
1002
+ if (kind === 'persona') return this.runtimeSnapshot?.localPersonas ?? [];
1003
+ if (kind === 'skill') return this.runtimeSnapshot?.localSkills ?? [];
1004
+ return this.runtimeSnapshot?.localRoutines ?? [];
1005
+ }
1006
+
1007
+ private clampLocalLibrarySelection(kind: AgentWorkspaceLocalEditorKind): void {
1008
+ const length = this.localLibraryItems(kind).length;
1009
+ this.selectedLibraryItemIndexes[kind] = length === 0
1010
+ ? 0
1011
+ : Math.max(0, Math.min(this.selectedLibraryItemIndexes[kind], length - 1));
1012
+ }
1013
+
1014
+ private moveLocalLibraryItemSelection(kind: AgentWorkspaceLocalEditorKind, delta: number): void {
1015
+ const items = this.localLibraryItems(kind);
1016
+ if (items.length === 0) {
1017
+ this.status = `No local ${kind} records to select.`;
1018
+ this.lastActionResult = {
1019
+ kind: 'guidance',
1020
+ title: `No ${kind} records`,
1021
+ detail: `Create a local ${kind} before using selection actions.`,
1022
+ safety: 'safe',
1023
+ };
1024
+ return;
1025
+ }
1026
+ this.selectedLibraryItemIndexes[kind] = Math.max(0, Math.min(items.length - 1, this.selectedLibraryItemIndexes[kind] + delta));
1027
+ const selected = this.selectedLocalLibraryItem(kind);
1028
+ this.status = selected ? `Selected ${kind}: ${selected.name}.` : `Selected ${kind} updated.`;
1029
+ this.lastActionResult = {
1030
+ kind: 'guidance',
1031
+ title: selected ? `Selected ${selected.name}` : `Selected ${kind}`,
1032
+ detail: selected ? `${selected.name} (${selected.id}) is now the selected local ${kind}.` : `Selection changed for ${kind}.`,
1033
+ safety: 'safe',
1034
+ };
1035
+ }
1036
+
1037
+ private applyLocalLibraryOperation(operation: AgentWorkspaceLocalOperation): void {
1038
+ const shellPaths = this.context?.workspace?.shellPaths;
1039
+ if (!shellPaths) {
1040
+ this.status = 'Local Agent registry files are unavailable.';
1041
+ this.lastActionResult = {
1042
+ kind: 'error',
1043
+ title: 'Local registry unavailable',
1044
+ detail: 'The Agent workspace cannot locate the Agent-local registry files for this runtime.',
1045
+ };
1046
+ return;
1047
+ }
1048
+ try {
1049
+ if (operation === 'persona-clear') {
1050
+ AgentPersonaRegistry.fromShellPaths(shellPaths).clearActive();
1051
+ this.finishLocalOperation('persona', 'Cleared active persona', 'The default Agent policy will apply to future turns.');
1052
+ return;
1053
+ }
1054
+ const selected = this.selectedItemForOperation(operation);
1055
+ if (!selected) {
1056
+ this.status = 'No selected local registry item.';
1057
+ this.lastActionResult = {
1058
+ kind: 'guidance',
1059
+ title: 'Nothing selected',
1060
+ detail: 'Create or select a local library item before running this action.',
1061
+ safety: 'safe',
1062
+ };
1063
+ return;
1064
+ }
1065
+ if (operation === 'persona-use') {
1066
+ AgentPersonaRegistry.fromShellPaths(shellPaths).setActive(selected.id);
1067
+ this.finishLocalOperation('persona', `Using persona ${selected.name}`, `${selected.name} will shape future main-conversation turns.`);
1068
+ } else if (operation === 'persona-review') {
1069
+ AgentPersonaRegistry.fromShellPaths(shellPaths).markReviewed(selected.id);
1070
+ this.finishLocalOperation('persona', `Reviewed persona ${selected.name}`, `${selected.name} is marked reviewed.`);
1071
+ } else if (operation === 'skill-enable') {
1072
+ AgentSkillRegistry.fromShellPaths(shellPaths).setEnabled(selected.id, true);
1073
+ this.finishLocalOperation('skill', `Enabled skill ${selected.name}`, `${selected.name} can now inform main-conversation turns.`);
1074
+ } else if (operation === 'skill-disable') {
1075
+ AgentSkillRegistry.fromShellPaths(shellPaths).setEnabled(selected.id, false);
1076
+ this.finishLocalOperation('skill', `Disabled skill ${selected.name}`, `${selected.name} remains saved but is no longer injected into guidance.`);
1077
+ } else if (operation === 'skill-review') {
1078
+ AgentSkillRegistry.fromShellPaths(shellPaths).markReviewed(selected.id);
1079
+ this.finishLocalOperation('skill', `Reviewed skill ${selected.name}`, `${selected.name} is marked reviewed.`);
1080
+ } else if (operation === 'routine-start') {
1081
+ AgentRoutineRegistry.fromShellPaths(shellPaths).markStarted(selected.id);
1082
+ this.finishLocalOperation('routine', `Started routine ${selected.name}`, `${selected.name} was marked started for this main-conversation workflow. No hidden job was created.`);
1083
+ } else if (operation === 'routine-enable') {
1084
+ AgentRoutineRegistry.fromShellPaths(shellPaths).setEnabled(selected.id, true);
1085
+ this.finishLocalOperation('routine', `Enabled routine ${selected.name}`, `${selected.name} can now inform main-conversation turns.`);
1086
+ } else if (operation === 'routine-disable') {
1087
+ AgentRoutineRegistry.fromShellPaths(shellPaths).setEnabled(selected.id, false);
1088
+ this.finishLocalOperation('routine', `Disabled routine ${selected.name}`, `${selected.name} remains saved but is no longer injected into guidance.`);
1089
+ } else {
1090
+ AgentRoutineRegistry.fromShellPaths(shellPaths).markReviewed(selected.id);
1091
+ this.finishLocalOperation('routine', `Reviewed routine ${selected.name}`, `${selected.name} is marked reviewed.`);
1092
+ }
1093
+ } catch (error) {
1094
+ const detail = error instanceof Error ? error.message : String(error);
1095
+ this.status = detail;
1096
+ this.lastActionResult = {
1097
+ kind: 'error',
1098
+ title: 'Local registry action failed',
1099
+ detail,
1100
+ };
1101
+ }
1102
+ }
1103
+
1104
+ private selectedItemForOperation(operation: AgentWorkspaceLocalOperation): AgentWorkspaceLocalLibraryItem | null {
1105
+ if (operation.startsWith('persona-')) return this.selectedLocalLibraryItem('persona');
1106
+ if (operation.startsWith('skill-')) return this.selectedLocalLibraryItem('skill');
1107
+ return this.selectedLocalLibraryItem('routine');
1108
+ }
1109
+
1110
+ private finishLocalOperation(kind: AgentWorkspaceLocalEditorKind, title: string, detail: string): void {
1111
+ this.runtimeSnapshot = this.context ? buildAgentWorkspaceRuntimeSnapshot(this.context) : this.runtimeSnapshot;
1112
+ this.clampLocalLibrarySelection(kind);
1113
+ this.status = title;
1114
+ this.lastActionResult = {
1115
+ kind: 'refreshed',
1116
+ title,
1117
+ detail,
1118
+ safety: 'safe',
1119
+ };
951
1120
  }
952
1121
 
953
1122
  private replaceEditorField(index: number, value: string, message: string): void {
@@ -70,6 +70,8 @@ function buildLeftRows(workspace: AgentWorkspace, height: number): WorkspaceRow[
70
70
  function actionCommand(action: AgentWorkspaceAction): string {
71
71
  if (action.kind === 'workspace') return action.targetCategoryId ? `open ${action.targetCategoryId}` : '(workspace)';
72
72
  if (action.kind === 'editor') return action.editorKind ? `edit ${action.editorKind}` : '(editor)';
73
+ if (action.kind === 'local-selection') return action.selectionDelta && action.selectionDelta < 0 ? 'select previous' : 'select next';
74
+ if (action.kind === 'local-operation') return action.localOperation ?? '(local action)';
73
75
  return action.command ?? '(guidance)';
74
76
  }
75
77
 
@@ -106,6 +108,7 @@ function localLibraryLines(
106
108
  title: string,
107
109
  items: readonly AgentWorkspaceRuntimeSnapshot['localPersonas'][number][],
108
110
  emptyText: string,
111
+ selectedId: string | null,
109
112
  ): ContextLine[] {
110
113
  const lines: ContextLine[] = [
111
114
  { text: title, fg: PALETTE.title, bold: true },
@@ -115,7 +118,9 @@ function localLibraryLines(
115
118
  return lines;
116
119
  }
117
120
  for (const item of items.slice(0, 8)) {
121
+ const selected = item.id === selectedId;
118
122
  const status = [
123
+ selected ? 'selected' : '',
119
124
  item.active ? 'active' : '',
120
125
  item.enabled === true ? 'enabled' : item.enabled === false ? 'disabled' : '',
121
126
  item.reviewState,
@@ -123,10 +128,11 @@ function localLibraryLines(
123
128
  ].filter(Boolean).join(' / ');
124
129
  const tags = item.tags.length > 0 ? ` tags=${item.tags.join(',')}` : '';
125
130
  const triggers = item.triggers.length > 0 ? ` triggers=${item.triggers.join(',')}` : '';
131
+ const marker = selected ? `${GLYPHS.navigation.selected} ` : '';
126
132
  lines.push({
127
- text: `${item.id}: ${item.name} (${status})`,
133
+ text: `${marker}${item.id}: ${item.name} (${status})`,
128
134
  fg: item.reviewState === 'stale' ? PALETTE.warn : PALETTE.info,
129
- bold: item.active === true,
135
+ bold: selected || item.active === true,
130
136
  });
131
137
  lines.push({ text: ` ${item.description}${tags}${triggers}`, fg: PALETTE.muted });
132
138
  }
@@ -136,7 +142,7 @@ function localLibraryLines(
136
142
  return lines;
137
143
  }
138
144
 
139
- function snapshotLines(category: AgentWorkspaceCategory, snapshot: AgentWorkspaceRuntimeSnapshot | null): ContextLine[] {
145
+ function snapshotLines(workspace: AgentWorkspace, category: AgentWorkspaceCategory, snapshot: AgentWorkspaceRuntimeSnapshot | null): ContextLine[] {
140
146
  if (!snapshot) return [{ text: 'Runtime context is not loaded yet.', fg: PALETTE.warn }];
141
147
  const base: ContextLine[] = [{ text: 'Live Agent Context', fg: PALETTE.title, bold: true }];
142
148
  if (category.id === 'home') {
@@ -220,7 +226,7 @@ function snapshotLines(category: AgentWorkspaceCategory, snapshot: AgentWorkspac
220
226
  { text: 'Personas are local behavior profiles for the serial main-conversation assistant, not spawned agents.', fg: PALETTE.good },
221
227
  { text: 'Use them for tone, role, domain constraints, tool posture, and repeatable operating preferences.', fg: PALETTE.muted },
222
228
  { text: '' },
223
- ...localLibraryLines('Persona Library', snapshot.localPersonas, 'No local personas yet. Create one with /personas create ...'),
229
+ ...localLibraryLines('Persona Library', snapshot.localPersonas, 'No local personas yet. Create one here with Create persona.', workspace.selectedLocalLibraryItem('persona')?.id ?? null),
224
230
  );
225
231
  } else if (category.id === 'skills') {
226
232
  base.push(
@@ -228,7 +234,7 @@ function snapshotLines(category: AgentWorkspaceCategory, snapshot: AgentWorkspac
228
234
  { text: 'Skills are reusable local procedures the assistant can apply from the main conversation.', fg: PALETTE.good },
229
235
  { text: 'Enabled skills are injected as operating guidance; secret-looking content is rejected.', fg: PALETTE.warn },
230
236
  { text: '' },
231
- ...localLibraryLines('Skill Library', snapshot.localSkills, 'No local skills yet. Create one with /agent-skills create ...'),
237
+ ...localLibraryLines('Skill Library', snapshot.localSkills, 'No local skills yet. Create one here with Create skill.', workspace.selectedLocalLibraryItem('skill')?.id ?? null),
232
238
  );
233
239
  } else if (category.id === 'routines') {
234
240
  base.push(
@@ -236,7 +242,7 @@ function snapshotLines(category: AgentWorkspaceCategory, snapshot: AgentWorkspac
236
242
  { text: 'Routines are repeatable main-conversation workflows. Starting one does not create hidden jobs.', fg: PALETTE.good },
237
243
  { text: 'Scheduling a reviewed routine is explicit and writes to the externally owned daemon only with --yes.', fg: PALETTE.warn },
238
244
  { text: '' },
239
- ...localLibraryLines('Routine Library', snapshot.localRoutines, 'No local routines yet. Create one with /routines create ...'),
245
+ ...localLibraryLines('Routine Library', snapshot.localRoutines, 'No local routines yet. Create one here with Create routine.', workspace.selectedLocalLibraryItem('routine')?.id ?? null),
240
246
  );
241
247
  } else if (category.id === 'work') {
242
248
  base.push(
@@ -288,7 +294,7 @@ function buildContextRows(workspace: AgentWorkspace, category: AgentWorkspaceCat
288
294
  { text: '' },
289
295
  ...(workspace.localEditor ? editorContextLines(workspace.localEditor) : []),
290
296
  ...(workspace.localEditor ? [{ text: '' }] : []),
291
- ...snapshotLines(category, workspace.runtimeSnapshot),
297
+ ...snapshotLines(workspace, category, workspace.runtimeSnapshot),
292
298
  ];
293
299
 
294
300
  if (action) {
package/src/version.ts CHANGED
@@ -6,7 +6,7 @@ import { join } from 'node:path';
6
6
  // The prebuild script updates the fallback value before compilation.
7
7
  // Uses import.meta.dir (Bun) to locate package.json relative to this file,
8
8
  // which is correct regardless of the process working directory.
9
- let _version = '0.1.51';
9
+ let _version = '0.1.52';
10
10
  let _sdkVersion = '0.33.35';
11
11
  try {
12
12
  const pkg = JSON.parse(readFileSync(join(import.meta.dir, '..', 'package.json'), 'utf-8')) as {