@plosson/agentio 0.1.28 → 0.1.29

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plosson/agentio",
3
- "version": "0.1.28",
3
+ "version": "0.1.29",
4
4
  "description": "CLI for LLM agents to interact with communication and tracking services",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -94,6 +94,15 @@ async function createServiceClient(
94
94
  }
95
95
  }
96
96
 
97
+ interface ProfileStatus {
98
+ service: string;
99
+ profile: string;
100
+ isDefault: boolean;
101
+ status: 'ok' | 'invalid' | 'no-creds' | 'skipped';
102
+ info?: string;
103
+ error?: string;
104
+ }
105
+
97
106
  export function registerStatusCommand(program: Command): void {
98
107
  program
99
108
  .command('status')
@@ -107,28 +116,30 @@ export function registerStatusCommand(program: Command): void {
107
116
  console.log(`agentio v${version}`);
108
117
  console.log(`Config: ${CONFIG_DIR}\n`);
109
118
 
110
- let hasProfiles = false;
119
+ // Collect all profile statuses
120
+ const statuses: ProfileStatus[] = [];
111
121
 
112
122
  for (const { service, profiles, default: defaultProfile } of allProfiles) {
113
- if (profiles.length === 0) {
114
- continue;
115
- }
116
-
117
- hasProfiles = true;
118
- const displayName = service.charAt(0).toUpperCase() + service.slice(1);
119
- console.log(displayName);
120
-
121
123
  for (const name of profiles) {
122
- const marker = name === defaultProfile ? ' (default)' : '';
123
124
  const credentials = await getCredentials(service, name);
124
125
 
125
126
  if (!credentials) {
126
- console.log(` ${name}${marker} ? no credentials`);
127
+ statuses.push({
128
+ service,
129
+ profile: name,
130
+ isDefault: name === defaultProfile,
131
+ status: 'no-creds',
132
+ });
127
133
  continue;
128
134
  }
129
135
 
130
136
  if (options.test === false) {
131
- console.log(` ${name}${marker}`);
137
+ statuses.push({
138
+ service,
139
+ profile: name,
140
+ isDefault: name === defaultProfile,
141
+ status: 'skipped',
142
+ });
132
143
  continue;
133
144
  }
134
145
 
@@ -141,20 +152,56 @@ export function registerStatusCommand(program: Command): void {
141
152
  result = { valid: true, info: 'unknown service' };
142
153
  }
143
154
 
144
- const status = result.valid ? 'ok' : 'invalid';
145
- const statusMark = result.valid ? '+' : 'x';
146
- const info = result.info ? ` ${result.info}` : '';
147
- const error = result.error ? ` (${result.error})` : '';
148
-
149
- console.log(` ${name}${marker} ${statusMark} ${status}${info}${error}`);
155
+ statuses.push({
156
+ service,
157
+ profile: name,
158
+ isDefault: name === defaultProfile,
159
+ status: result.valid ? 'ok' : 'invalid',
160
+ info: result.info,
161
+ error: result.error,
162
+ });
150
163
  }
151
-
152
- console.log();
153
164
  }
154
165
 
155
- if (!hasProfiles) {
166
+ if (statuses.length === 0) {
156
167
  console.log('No profiles configured.');
157
168
  console.log('Run: agentio <service> profile add');
169
+ return;
170
+ }
171
+
172
+ // Calculate column widths
173
+ const serviceWidth = Math.max(...statuses.map((s) => s.service.length));
174
+ const profileWidth = Math.max(...statuses.map((s) => s.profile.length + (s.isDefault ? 1 : 0)));
175
+
176
+ // Print each profile on one line
177
+ for (const s of statuses) {
178
+ const servicePad = s.service.padEnd(serviceWidth);
179
+ const profileName = s.profile + (s.isDefault ? '*' : '');
180
+ const profilePad = profileName.padEnd(profileWidth);
181
+
182
+ let statusStr: string;
183
+ let details = '';
184
+
185
+ switch (s.status) {
186
+ case 'ok':
187
+ statusStr = 'ok';
188
+ details = s.info || '';
189
+ break;
190
+ case 'invalid':
191
+ statusStr = 'ERR';
192
+ details = s.error || '';
193
+ break;
194
+ case 'no-creds':
195
+ statusStr = 'ERR';
196
+ details = 'no credentials';
197
+ break;
198
+ case 'skipped':
199
+ statusStr = '-';
200
+ break;
201
+ }
202
+
203
+ const line = `${servicePad} ${profilePad} ${statusStr.padEnd(3)} ${details}`.trimEnd();
204
+ console.log(line);
158
205
  }
159
206
  } catch (error) {
160
207
  console.error('Error:', error instanceof Error ? error.message : 'Unknown error');
@@ -25,7 +25,7 @@ export class GChatClient implements ServiceClient {
25
25
  async validate(): Promise<ValidationResult> {
26
26
  if (this.credentials.type === 'webhook') {
27
27
  // Cannot validate webhooks without sending a message
28
- return { valid: true, info: 'webhook (not testable)' };
28
+ return { valid: true, info: 'webhook' };
29
29
  }
30
30
 
31
31
  try {
@@ -17,7 +17,7 @@ export class SlackClient implements ServiceClient {
17
17
  async validate(): Promise<ValidationResult> {
18
18
  // Webhooks cannot be validated without sending a message
19
19
  const webhookCreds = this.credentials as SlackWebhookCredentials;
20
- const info = webhookCreds.channelName ? `#${webhookCreds.channelName}` : 'webhook (not testable)';
20
+ const info = webhookCreds.channelName ? `#${webhookCreds.channelName}` : 'webhook';
21
21
  return { valid: true, info };
22
22
  }
23
23