@zonko-ai/harbor 0.1.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.
Files changed (86) hide show
  1. package/README.md +15 -0
  2. package/dist/api.d.ts +53 -0
  3. package/dist/api.d.ts.map +1 -0
  4. package/dist/api.js +842 -0
  5. package/dist/api.js.map +1 -0
  6. package/dist/capabilities.d.ts +5 -0
  7. package/dist/capabilities.d.ts.map +1 -0
  8. package/dist/capabilities.js +308 -0
  9. package/dist/capabilities.js.map +1 -0
  10. package/dist/constants.d.ts +4 -0
  11. package/dist/constants.d.ts.map +1 -0
  12. package/dist/constants.js +4 -0
  13. package/dist/constants.js.map +1 -0
  14. package/dist/dev.d.ts +14 -0
  15. package/dist/dev.d.ts.map +1 -0
  16. package/dist/dev.js +203 -0
  17. package/dist/dev.js.map +1 -0
  18. package/dist/foreground.d.ts +13 -0
  19. package/dist/foreground.d.ts.map +1 -0
  20. package/dist/foreground.js +54 -0
  21. package/dist/foreground.js.map +1 -0
  22. package/dist/import-openapi.d.ts +12 -0
  23. package/dist/import-openapi.d.ts.map +1 -0
  24. package/dist/import-openapi.js +488 -0
  25. package/dist/import-openapi.js.map +1 -0
  26. package/dist/index.d.ts +3 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +941 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/local-config.d.ts +12 -0
  31. package/dist/local-config.d.ts.map +1 -0
  32. package/dist/local-config.js +93 -0
  33. package/dist/local-config.js.map +1 -0
  34. package/dist/local-daemon-entry.d.ts +2 -0
  35. package/dist/local-daemon-entry.d.ts.map +1 -0
  36. package/dist/local-daemon-entry.js +545 -0
  37. package/dist/local-daemon-entry.js.map +1 -0
  38. package/dist/local-daemon.d.ts +58 -0
  39. package/dist/local-daemon.d.ts.map +1 -0
  40. package/dist/local-daemon.js +385 -0
  41. package/dist/local-daemon.js.map +1 -0
  42. package/dist/mcp/api-client.d.ts +72 -0
  43. package/dist/mcp/api-client.d.ts.map +1 -0
  44. package/dist/mcp/api-client.js +210 -0
  45. package/dist/mcp/api-client.js.map +1 -0
  46. package/dist/mcp/index.d.ts +4 -0
  47. package/dist/mcp/index.d.ts.map +1 -0
  48. package/dist/mcp/index.js +18 -0
  49. package/dist/mcp/index.js.map +1 -0
  50. package/dist/mcp/schema.d.ts +3 -0
  51. package/dist/mcp/schema.d.ts.map +1 -0
  52. package/dist/mcp/schema.js +95 -0
  53. package/dist/mcp/schema.js.map +1 -0
  54. package/dist/mcp/server.d.ts +5 -0
  55. package/dist/mcp/server.d.ts.map +1 -0
  56. package/dist/mcp/server.js +57 -0
  57. package/dist/mcp/server.js.map +1 -0
  58. package/dist/mcp/tools.d.ts +12 -0
  59. package/dist/mcp/tools.d.ts.map +1 -0
  60. package/dist/mcp/tools.js +54 -0
  61. package/dist/mcp/tools.js.map +1 -0
  62. package/dist/output-download.d.ts +8 -0
  63. package/dist/output-download.d.ts.map +1 -0
  64. package/dist/output-download.js +210 -0
  65. package/dist/output-download.js.map +1 -0
  66. package/dist/output.d.ts +124 -0
  67. package/dist/output.d.ts.map +1 -0
  68. package/dist/output.js +752 -0
  69. package/dist/output.js.map +1 -0
  70. package/dist/passthrough.d.ts +15 -0
  71. package/dist/passthrough.d.ts.map +1 -0
  72. package/dist/passthrough.js +68 -0
  73. package/dist/passthrough.js.map +1 -0
  74. package/dist/runtime-attribution.d.ts +5 -0
  75. package/dist/runtime-attribution.d.ts.map +1 -0
  76. package/dist/runtime-attribution.js +86 -0
  77. package/dist/runtime-attribution.js.map +1 -0
  78. package/dist/state.d.ts +56 -0
  79. package/dist/state.d.ts.map +1 -0
  80. package/dist/state.js +374 -0
  81. package/dist/state.js.map +1 -0
  82. package/dist/types.d.ts +284 -0
  83. package/dist/types.d.ts.map +1 -0
  84. package/dist/types.js +2 -0
  85. package/dist/types.js.map +1 -0
  86. package/package.json +35 -0
package/dist/output.js ADDED
@@ -0,0 +1,752 @@
1
+ import { ApiError } from './api.js';
2
+ const toPlainValue = (value) => {
3
+ if (value === null || value === undefined) {
4
+ return '';
5
+ }
6
+ if (typeof value === 'string') {
7
+ return /\s/.test(value) ? JSON.stringify(value) : value;
8
+ }
9
+ return String(value);
10
+ };
11
+ export const getOutputMode = (options) => {
12
+ if (options.json) {
13
+ return 'json';
14
+ }
15
+ if (options.plain) {
16
+ return 'plain';
17
+ }
18
+ return 'human';
19
+ };
20
+ export class CliInputError extends Error {
21
+ code = 'invalid_input';
22
+ invocation;
23
+ note;
24
+ constructor(message, invocation, note) {
25
+ super(message);
26
+ this.invocation = invocation;
27
+ this.note = note;
28
+ }
29
+ }
30
+ const writeJson = (payload) => {
31
+ console.log(JSON.stringify(payload, null, 2));
32
+ };
33
+ const writePlain = (lines) => {
34
+ console.log(lines.join('\n'));
35
+ };
36
+ const writeHuman = (text) => {
37
+ console.log(text.trimEnd());
38
+ };
39
+ const yesNoUnknown = (value) => {
40
+ if (value === true) {
41
+ return 'yes';
42
+ }
43
+ if (value === false) {
44
+ return 'no';
45
+ }
46
+ return 'unknown';
47
+ };
48
+ const writeJsonError = (payload) => {
49
+ console.error(JSON.stringify(payload, null, 2));
50
+ };
51
+ const writePlainError = (lines) => {
52
+ console.error(lines.join('\n'));
53
+ };
54
+ const writeHumanError = (text) => {
55
+ console.error(text.trimEnd());
56
+ };
57
+ const linesFromRecord = (entries) => entries
58
+ .filter(([, value]) => value !== undefined)
59
+ .map(([key, value]) => `${key}=${toPlainValue(value)}`);
60
+ const requiredLabel = (required) => (required ? 'required' : 'optional');
61
+ const schemaType = (value) => {
62
+ if (typeof value === 'string') {
63
+ return value;
64
+ }
65
+ if (Array.isArray(value)) {
66
+ const first = value.find((entry) => typeof entry === 'string' && entry !== 'null');
67
+ return first ?? 'unknown';
68
+ }
69
+ return 'unknown';
70
+ };
71
+ const summarizeRuntimeInjection = (runtimeInjection) => {
72
+ if (!runtimeInjection) {
73
+ return null;
74
+ }
75
+ const requirements = runtimeInjection.requirements.map((requirement) => ({
76
+ name: requirement.name,
77
+ kind: requirement.kind,
78
+ required: Boolean(requirement.required),
79
+ service: requirement.service,
80
+ lookup: requirement.lookup,
81
+ input_path: requirement.input_path,
82
+ fallback_order: requirement.fallback_order ?? [],
83
+ }));
84
+ const export_keys = Object.keys(runtimeInjection.exports ?? {});
85
+ const audit_context_keys = runtimeInjection.audit?.context_keys ?? [];
86
+ if (requirements.length === 0 && export_keys.length === 0 && audit_context_keys.length === 0) {
87
+ return null;
88
+ }
89
+ return {
90
+ requirements,
91
+ export_keys,
92
+ audit_context_keys,
93
+ };
94
+ };
95
+ const describeRuntimeInjectionRequirement = (requirement) => {
96
+ const details = [requirement.required ? 'required' : 'optional'];
97
+ if (requirement.service) {
98
+ details.push(`service=${requirement.service}`);
99
+ }
100
+ if (requirement.lookup) {
101
+ details.push(`lookup=${requirement.lookup}`);
102
+ }
103
+ if (requirement.input_path) {
104
+ details.push(`input_path=${requirement.input_path}`);
105
+ }
106
+ if (requirement.fallback_order.length > 0) {
107
+ details.push(`fallback=${requirement.fallback_order.join('>')}`);
108
+ }
109
+ return details.join(' ');
110
+ };
111
+ export const renderClaim = (mode, payload) => {
112
+ if (mode === 'json') {
113
+ writeJson(payload);
114
+ return;
115
+ }
116
+ if (mode === 'plain') {
117
+ writePlain(linesFromRecord([
118
+ ['status', payload.result],
119
+ ['agent_id', payload.agent_id],
120
+ ['profile', payload.profile],
121
+ ['owner', payload.owner],
122
+ ['approval_id', payload.approval_id],
123
+ ['approval_url', payload.approval_url],
124
+ ]));
125
+ return;
126
+ }
127
+ if (payload.result === 'approval_required') {
128
+ writeHuman(`status: ${payload.result}\napproval_id: ${payload.approval_id ?? 'unknown'}\napproval_url: ${payload.approval_url ?? 'unknown'}`);
129
+ return;
130
+ }
131
+ writeHuman(`status: ${payload.result}\nagent_id: ${payload.agent_id ?? 'unknown'}\nprofile: ${payload.profile}\nowner: ${payload.owner ?? 'unknown'}`);
132
+ };
133
+ export const renderWhoAmI = (mode, payload) => {
134
+ if (mode === 'json') {
135
+ writeJson(payload);
136
+ return;
137
+ }
138
+ if (mode === 'plain') {
139
+ writePlain(linesFromRecord([
140
+ ['profile', payload.profile],
141
+ ['owner_scope_id', payload.owner_scope_id],
142
+ ['owner', payload.owner],
143
+ ['agent_id', payload.agent_id],
144
+ ['agent_name', payload.agent_display_name],
145
+ ]));
146
+ return;
147
+ }
148
+ writeHuman(`profile: ${payload.profile}\nowner: ${payload.owner ?? 'unknown'}\nagent_id: ${payload.agent_id ?? 'unknown'}\nagent_name: ${payload.agent_display_name ?? 'unknown'}`);
149
+ };
150
+ export const renderProfileCurrent = (mode, payload) => {
151
+ if (mode === 'json') {
152
+ writeJson(payload);
153
+ return;
154
+ }
155
+ if (mode === 'plain') {
156
+ writePlain(linesFromRecord([
157
+ ['profile', payload.profile],
158
+ ['active_profile', payload.active_profile],
159
+ ['api_url', payload.api_url],
160
+ ['owner', payload.owner],
161
+ ['agent_id', payload.agent_id],
162
+ ]));
163
+ return;
164
+ }
165
+ writeHuman(`profile: ${payload.profile}\nactive_profile: ${payload.active_profile}\napi_url: ${payload.api_url ?? 'unset'}\nowner: ${payload.owner ?? 'unknown'}\nagent_id: ${payload.agent_id ?? 'unknown'}`);
166
+ };
167
+ export const renderProfileList = (mode, profiles) => {
168
+ if (mode === 'json') {
169
+ writeJson({ profiles });
170
+ return;
171
+ }
172
+ if (mode === 'plain') {
173
+ writePlain(profiles.map((profile) => linesFromRecord([
174
+ ['profile', profile.profile_slug],
175
+ ['active', profile.active ? 'yes' : 'no'],
176
+ ['selected', profile.selected ? 'yes' : 'no'],
177
+ ['api_url', profile.api_url],
178
+ ['owner', profile.owner],
179
+ ['agent_id', profile.agent_id],
180
+ ]).join(' ')));
181
+ return;
182
+ }
183
+ if (profiles.length === 0) {
184
+ writeHuman('No Harbor profiles.');
185
+ return;
186
+ }
187
+ const rows = profiles
188
+ .map((profile) => [
189
+ profile.profile_slug.padEnd(18),
190
+ (profile.active ? 'active' : '').padEnd(8),
191
+ (profile.selected ? 'selected' : '').padEnd(10),
192
+ (profile.api_url ?? 'unset').padEnd(28),
193
+ profile.agent_id ?? 'unknown',
194
+ ].join(' ').trimEnd())
195
+ .join('\n');
196
+ writeHuman(`PROFILE ACTIVE SELECTED API URL AGENT ID\n${rows}`);
197
+ };
198
+ export const renderDevUp = (mode, payload) => {
199
+ if (mode === 'json') {
200
+ writeJson(payload);
201
+ return;
202
+ }
203
+ if (mode === 'plain') {
204
+ writePlain(linesFromRecord([
205
+ ['status', payload.status],
206
+ ['profile', payload.profile],
207
+ ['api_url', payload.api_url],
208
+ ['auth_url', payload.auth_url],
209
+ ]));
210
+ return;
211
+ }
212
+ writeHuman(`status: ${payload.status}\nprofile: ${payload.profile}\napi_url: ${payload.api_url ?? 'unset'}\nauth_url: ${payload.auth_url ?? 'unset'}`);
213
+ };
214
+ export const renderDevDown = (mode, payload) => {
215
+ if (mode === 'json') {
216
+ writeJson(payload);
217
+ return;
218
+ }
219
+ if (mode === 'plain') {
220
+ writePlain(linesFromRecord([
221
+ ['status', payload.status],
222
+ ['profile', payload.profile],
223
+ ]));
224
+ return;
225
+ }
226
+ writeHuman(`status: ${payload.status}\nprofile: ${payload.profile}`);
227
+ };
228
+ export const renderLocalDaemonStatus = (mode, payload) => {
229
+ if (mode === 'json') {
230
+ writeJson(payload);
231
+ return;
232
+ }
233
+ if (mode === 'plain') {
234
+ writePlain(linesFromRecord([
235
+ ['profile', payload.profile],
236
+ ['ready_state', payload.ready_state],
237
+ ['api_url', payload.api_url],
238
+ ['auth_url', payload.auth_url],
239
+ ['daemon_package_version', payload.daemon_package_version],
240
+ ['daemon_protocol', payload.selected_daemon_protocol],
241
+ ['state_schema_version', payload.state_schema_version],
242
+ ['api_manifest_revision', payload.api_manifest_revision],
243
+ ['last_ready_at', payload.last_ready_at],
244
+ ['api_pid', payload.managed_children.api.pid],
245
+ ['api_running', payload.managed_children.api.running ? 'yes' : 'no'],
246
+ ['runner_pid', payload.managed_children.runner.pid],
247
+ ['runner_running', payload.managed_children.runner.running ? 'yes' : 'no'],
248
+ ['socket', payload.paths.socket],
249
+ ['state', payload.paths.state],
250
+ ['daemon_log', payload.paths.daemon_log],
251
+ ['api_log', payload.paths.api_log],
252
+ ['runner_log', payload.paths.runner_log],
253
+ ]));
254
+ return;
255
+ }
256
+ writeHuman(`profile: ${payload.profile}\nready_state: ${payload.ready_state}\napi_url: ${payload.api_url}\nauth_url: ${payload.auth_url}\ndaemon_package_version: ${payload.daemon_package_version}\ndaemon_protocol: ${payload.selected_daemon_protocol}\nstate_schema_version: ${payload.state_schema_version}\napi_manifest_revision: ${payload.api_manifest_revision ?? 'unknown'}\nlast_ready_at: ${payload.last_ready_at ?? 'unknown'}\napi: ${payload.managed_children.api.running ? 'running' : 'stopped'} (pid ${payload.managed_children.api.pid ?? 'unknown'})\nrunner: ${payload.managed_children.runner.running ? 'running' : 'stopped'} (pid ${payload.managed_children.runner.pid ?? 'unknown'})\nsocket: ${payload.paths.socket}\nstate: ${payload.paths.state}\ndaemon_log: ${payload.paths.daemon_log}\napi_log: ${payload.paths.api_log}\nrunner_log: ${payload.paths.runner_log}`);
257
+ };
258
+ export const renderLocalDaemonLog = (mode, payload) => {
259
+ if (mode === 'json') {
260
+ writeJson(payload);
261
+ return;
262
+ }
263
+ if (mode === 'plain') {
264
+ writePlain([
265
+ ...linesFromRecord([
266
+ ['component', payload.component],
267
+ ['path', payload.path],
268
+ ]),
269
+ ...payload.lines,
270
+ ]);
271
+ return;
272
+ }
273
+ writeHuman(`component: ${payload.component}\npath: ${payload.path}${payload.lines.length > 0 ? `\n\n${payload.lines.join('\n')}` : '\n\n(no log lines)'}`);
274
+ };
275
+ export const renderLs = (mode, capabilities) => {
276
+ if (mode === 'json') {
277
+ writeJson({ capabilities });
278
+ return;
279
+ }
280
+ if (mode === 'plain') {
281
+ writePlain(capabilities.map((capability) => `capability=${capability.slug} state=${toPlainValue(capability.state)}${capability.summary ? ` summary=${toPlainValue(capability.summary)}` : ''}`));
282
+ return;
283
+ }
284
+ const rows = capabilities.length === 0
285
+ ? 'No published capabilities.'
286
+ : capabilities
287
+ .map((capability) => `${capability.slug.padEnd(20)} ${capability.state.padEnd(17)} ${capability.summary}`.trimEnd())
288
+ .join('\n');
289
+ writeHuman(rows);
290
+ };
291
+ export const renderInspect = (mode, snapshot) => {
292
+ const args = snapshot.surface?.cli?.args ?? [];
293
+ const runtimeInjection = summarizeRuntimeInjection(snapshot.runtime_injection);
294
+ const payload = {
295
+ capability: snapshot.capability.slug,
296
+ summary: snapshot.surface?.cli?.summary ?? snapshot.capability.description ?? '',
297
+ input: args.map((arg) => ({
298
+ name: arg.name,
299
+ type: arg.type ?? schemaType(snapshot.contract?.input_schema?.properties?.[arg.name]?.type),
300
+ required: Boolean(arg.required),
301
+ positional: Boolean(arg.positional),
302
+ description: arg.description ?? snapshot.contract?.input_schema?.properties?.[arg.name]?.description ?? '',
303
+ })),
304
+ secret_requirements: (snapshot.secrets?.required_refs ?? []).map((secret) => ({
305
+ name: secret.name,
306
+ kind: secret.kind,
307
+ purpose: secret.purpose,
308
+ })),
309
+ runtime_injection: runtimeInjection,
310
+ execution_mode: snapshot.contract?.execution_mode ?? null,
311
+ adapter: snapshot.capability.category ?? snapshot.capability.slug.split('.')[0],
312
+ grant_required: Boolean(snapshot.policy?.grant_required),
313
+ approval_mode: snapshot.policy?.approval_mode ?? 'none',
314
+ };
315
+ if (mode === 'json') {
316
+ writeJson(payload);
317
+ return;
318
+ }
319
+ if (mode === 'plain') {
320
+ writePlain([
321
+ ...linesFromRecord([
322
+ ['capability', payload.capability],
323
+ ['summary', payload.summary],
324
+ ['execution_mode', payload.execution_mode],
325
+ ['adapter', payload.adapter],
326
+ ['grant_required', payload.grant_required ? 'yes' : 'no'],
327
+ ['approval_mode', payload.approval_mode],
328
+ ]),
329
+ ...payload.input.map((arg) => `input.${arg.name}=${arg.type}:${requiredLabel(arg.required)}`),
330
+ ...payload.secret_requirements.map((secret) => `secret_requirement.${secret.name}=${secret.kind}:${secret.purpose}`),
331
+ ...(payload.runtime_injection?.requirements ?? []).map((requirement) => `runtime_injection.${requirement.name}=${requirement.kind}:${describeRuntimeInjectionRequirement(requirement)}`),
332
+ ...(payload.runtime_injection?.export_keys ?? []).map((key) => `runtime_injection.export=${key}`),
333
+ ...(payload.runtime_injection?.audit_context_keys ?? []).map((key) => `runtime_injection.audit_context_key=${key}`),
334
+ ]);
335
+ return;
336
+ }
337
+ const inputLines = payload.input.length === 0
338
+ ? ' none'
339
+ : payload.input.map((arg) => ` ${arg.name.padEnd(14)} ${String(arg.type).padEnd(8)} ${requiredLabel(arg.required)}`).join('\n');
340
+ const secretLines = payload.secret_requirements.length === 0
341
+ ? ' none'
342
+ : payload.secret_requirements.map((secret) => ` ${secret.name.padEnd(18)} ${String(secret.kind).padEnd(14)} ${secret.purpose}`).join('\n');
343
+ const runtimeInjectionLines = payload.runtime_injection
344
+ ? [
345
+ payload.runtime_injection.requirements.length === 0
346
+ ? ' requirements: none'
347
+ : payload.runtime_injection.requirements.map((requirement) => ` ${requirement.name.padEnd(18)} ${requirement.kind.padEnd(20)} ${describeRuntimeInjectionRequirement(requirement)}`).join('\n'),
348
+ payload.runtime_injection.export_keys.length === 0
349
+ ? ' exports: none'
350
+ : ` exports: ${payload.runtime_injection.export_keys.join(', ')}`,
351
+ payload.runtime_injection.audit_context_keys.length === 0
352
+ ? ' audit_context: none'
353
+ : ` audit_context: ${payload.runtime_injection.audit_context_keys.join(', ')}`,
354
+ ].join('\n')
355
+ : ' none';
356
+ writeHuman(`${payload.capability}\n\n${payload.summary}\n\nInput:\n${inputLines}\n\nSecret requirements:\n${secretLines}\n\nRuntime injection:\n${runtimeInjectionLines}\n\nExecution: ${payload.execution_mode ?? 'unknown'}\nAdapter: ${payload.adapter}\nGrant: ${payload.grant_required ? 'required' : 'not required'}\nApproval: ${payload.approval_mode}`);
357
+ };
358
+ export const renderComposioLinkSession = (mode, payload) => {
359
+ if (mode === 'json') {
360
+ writeJson(payload);
361
+ return;
362
+ }
363
+ if (mode === 'plain') {
364
+ writePlain(linesFromRecord([
365
+ ['link_session_id', payload.link_session_id],
366
+ ['status', payload.status],
367
+ ['subject_kind', payload.subject_kind],
368
+ ['subject_id', payload.subject_id],
369
+ ['toolkit_slug', payload.toolkit_slug],
370
+ ['auth_config_id', payload.auth_config_id],
371
+ ['connected_account_id', payload.connected_account_id],
372
+ ['redirect_url', payload.redirect_url],
373
+ ['expires_at', payload.expires_at],
374
+ ['completed_at', payload.completed_at],
375
+ ]));
376
+ return;
377
+ }
378
+ writeHuman([
379
+ `link_session_id: ${payload.link_session_id}`,
380
+ `status: ${payload.status}`,
381
+ `subject: ${payload.subject_kind ?? 'unknown'}:${payload.subject_id ?? 'unknown'}`,
382
+ `toolkit: ${payload.toolkit_slug ?? 'unknown'}`,
383
+ `auth_config_id: ${payload.auth_config_id ?? 'unknown'}`,
384
+ `connected_account_id: ${payload.connected_account_id ?? 'pending'}`,
385
+ `redirect_url: ${payload.redirect_url ?? 'n/a'}`,
386
+ ].join('\n'));
387
+ };
388
+ export const renderComposioService = (mode, payload) => {
389
+ if (mode === 'json') {
390
+ writeJson(payload);
391
+ return;
392
+ }
393
+ if (mode === 'plain') {
394
+ const routeLines = payload.routes.map((route) => [
395
+ 'route',
396
+ route.route_id,
397
+ route.subject_kind,
398
+ route.subject_id,
399
+ route.toolkit_slug,
400
+ route.auth_config_id,
401
+ route.connected_account_id,
402
+ route.status,
403
+ ].join('='));
404
+ const linkLines = payload.link_sessions.map((session) => [
405
+ 'link_session',
406
+ session.link_session_id,
407
+ session.status,
408
+ session.subject_kind ?? '',
409
+ session.subject_id ?? '',
410
+ session.toolkit_slug ?? '',
411
+ session.auth_config_id ?? '',
412
+ session.connected_account_id ?? '',
413
+ ].join('='));
414
+ writePlain([
415
+ ...linesFromRecord([
416
+ ['principal_id', payload.principal?.principal_id],
417
+ ['owner_scope_id', payload.principal?.owner_scope_id],
418
+ ['composio_user_id', payload.principal?.composio_user_id],
419
+ ['principal_status', payload.principal?.status],
420
+ ]),
421
+ ...routeLines,
422
+ ...linkLines,
423
+ ]);
424
+ return;
425
+ }
426
+ const principal = payload.principal
427
+ ? [
428
+ `principal_id: ${payload.principal.principal_id}`,
429
+ `owner_scope_id: ${payload.principal.owner_scope_id}`,
430
+ `composio_user_id: ${payload.principal.composio_user_id}`,
431
+ `status: ${payload.principal.status}`,
432
+ ].join('\n')
433
+ : 'principal: not linked';
434
+ const routes = payload.routes.length === 0
435
+ ? ' none'
436
+ : payload.routes.map((route) => ` ${route.subject_kind}:${route.subject_id} -> ${route.toolkit_slug} (${route.auth_config_id}) => ${route.connected_account_id} [${route.status}]`).join('\n');
437
+ const links = payload.link_sessions.length === 0
438
+ ? ' none'
439
+ : payload.link_sessions.map((session) => ` ${session.link_session_id} ${session.status} ${session.subject_kind ?? 'unknown'}:${session.subject_id ?? 'unknown'} ${session.toolkit_slug ?? 'unknown'} ${session.connected_account_id ?? 'pending'}`).join('\n');
440
+ writeHuman(`${principal}\n\nRoutes:\n${routes}\n\nLink sessions:\n${links}`);
441
+ };
442
+ export const renderProfileCleanup = (mode, payload) => {
443
+ if (mode === 'json') {
444
+ writeJson(payload);
445
+ return;
446
+ }
447
+ if (mode === 'plain') {
448
+ writePlain(linesFromRecord([
449
+ ['profile', payload.profile],
450
+ ['deleted', payload.deleted ? 'true' : 'false'],
451
+ ['cleared_session', payload.cleared_session ? 'true' : 'false'],
452
+ ['active_profile', payload.active_profile],
453
+ ]));
454
+ return;
455
+ }
456
+ writeHuman([
457
+ `profile: ${payload.profile}`,
458
+ `deleted: ${payload.deleted ? 'yes' : 'no'}`,
459
+ `cleared_session: ${payload.cleared_session ? 'yes' : 'no'}`,
460
+ `active_profile: ${payload.active_profile}`,
461
+ ].join('\n'));
462
+ };
463
+ export const renderComposioRoute = (mode, payload) => {
464
+ if (mode === 'json') {
465
+ writeJson(payload);
466
+ return;
467
+ }
468
+ if (mode === 'plain') {
469
+ writePlain(linesFromRecord([
470
+ ['route_id', payload.route_id],
471
+ ['status', payload.status],
472
+ ['subject_kind', payload.subject_kind],
473
+ ['subject_id', payload.subject_id],
474
+ ['toolkit_slug', payload.toolkit_slug],
475
+ ['auth_config_id', payload.auth_config_id],
476
+ ['connected_account_id', payload.connected_account_id],
477
+ ]));
478
+ return;
479
+ }
480
+ writeHuman([
481
+ `route_id: ${payload.route_id}`,
482
+ `status: ${payload.status}`,
483
+ `subject: ${payload.subject_kind}:${payload.subject_id}`,
484
+ `toolkit: ${payload.toolkit_slug}`,
485
+ `auth_config_id: ${payload.auth_config_id}`,
486
+ `connected_account_id: ${payload.connected_account_id}`,
487
+ ].join('\n'));
488
+ };
489
+ export const renderSecretReferenceList = (mode, secretReferences) => {
490
+ if (mode === 'json') {
491
+ writeJson({ secret_references: secretReferences });
492
+ return;
493
+ }
494
+ if (mode === 'plain') {
495
+ writePlain(secretReferences.map((secretReference) => [
496
+ `name=${toPlainValue(secretReference.name)}`,
497
+ `kind=${toPlainValue(secretReference.kind)}`,
498
+ `managed_by=${toPlainValue(secretReference.managed_by)}`,
499
+ `status=${toPlainValue(secretReference.status)}`,
500
+ `updated_at=${toPlainValue(secretReference.updated_at)}`,
501
+ `stored_material_present=${toPlainValue(yesNoUnknown(secretReference.stored_material_present))}`,
502
+ ].join(' ')));
503
+ return;
504
+ }
505
+ if (secretReferences.length === 0) {
506
+ writeHuman('No secret references.');
507
+ return;
508
+ }
509
+ const rows = secretReferences
510
+ .map((secretReference) => [
511
+ secretReference.name.padEnd(28),
512
+ secretReference.kind.padEnd(20),
513
+ secretReference.managed_by.padEnd(14),
514
+ secretReference.status.padEnd(10),
515
+ yesNoUnknown(secretReference.stored_material_present).padEnd(8),
516
+ secretReference.updated_at,
517
+ ].join(' ').trimEnd())
518
+ .join('\n');
519
+ writeHuman(`NAME KIND MANAGED BY STATUS MATERIAL UPDATED AT\n${rows}`);
520
+ };
521
+ export const renderSecretReference = (mode, secretReference) => {
522
+ if (mode === 'json') {
523
+ writeJson(secretReference);
524
+ return;
525
+ }
526
+ const backendLocator = JSON.stringify(secretReference.backend_locator);
527
+ if (mode === 'plain') {
528
+ writePlain(linesFromRecord([
529
+ ['name', secretReference.name],
530
+ ['display_name', secretReference.display_name],
531
+ ['kind', secretReference.kind],
532
+ ['resolver_kind', secretReference.resolver_kind],
533
+ ['status', secretReference.status],
534
+ ['managed_by', secretReference.managed_by],
535
+ ['stored_material_present', yesNoUnknown(secretReference.stored_material_present)],
536
+ ['rotated_at', secretReference.rotated_at],
537
+ ['created_at', secretReference.created_at],
538
+ ['updated_at', secretReference.updated_at],
539
+ ['backend_locator', backendLocator],
540
+ ]));
541
+ return;
542
+ }
543
+ writeHuman([
544
+ `name: ${secretReference.name}`,
545
+ `display_name: ${secretReference.display_name}`,
546
+ `kind: ${secretReference.kind}`,
547
+ `resolver_kind: ${secretReference.resolver_kind}`,
548
+ `status: ${secretReference.status}`,
549
+ `managed_by: ${secretReference.managed_by}`,
550
+ `stored_material_present: ${yesNoUnknown(secretReference.stored_material_present)}`,
551
+ `rotated_at: ${secretReference.rotated_at ?? 'never'}`,
552
+ `created_at: ${secretReference.created_at}`,
553
+ `updated_at: ${secretReference.updated_at}`,
554
+ `backend_locator: ${backendLocator}`,
555
+ ].join('\n'));
556
+ };
557
+ export const renderSecretReferenceDeleted = (mode, payload) => {
558
+ if (mode === 'json') {
559
+ writeJson(payload);
560
+ return;
561
+ }
562
+ if (mode === 'plain') {
563
+ writePlain(linesFromRecord([
564
+ ['name', payload.name],
565
+ ['ok', payload.ok ? 'true' : 'false'],
566
+ ]));
567
+ return;
568
+ }
569
+ writeHuman(`name: ${payload.name}\nstatus: ${payload.ok ? 'deleted' : 'not_deleted'}`);
570
+ };
571
+ export const renderApprove = (mode, payload) => {
572
+ if (mode === 'json') {
573
+ writeJson(payload);
574
+ return;
575
+ }
576
+ if (mode === 'plain') {
577
+ writePlain(linesFromRecord([
578
+ ['approval_id', payload.approval_id],
579
+ ['status', payload.status],
580
+ ]));
581
+ return;
582
+ }
583
+ writeHuman(`approval_id: ${payload.approval_id}\nstatus: ${payload.status}`);
584
+ };
585
+ export const renderSetup = (mode, payload) => {
586
+ if (mode === 'json') {
587
+ writeJson(payload);
588
+ return;
589
+ }
590
+ if (mode === 'plain') {
591
+ writePlain(linesFromRecord([
592
+ ['profile', payload.profile],
593
+ ['api_url', payload.api_url],
594
+ ['status', payload.status],
595
+ ['owner', payload.owner],
596
+ ['agent_id', payload.agent_id],
597
+ ['agent_name', payload.agent_name],
598
+ ['approval_url', payload.approval_url],
599
+ ['health', payload.health],
600
+ ['capabilities', payload.capabilities],
601
+ ['pending_approvals', payload.pending_approvals],
602
+ ['recent_executions', payload.recent_executions],
603
+ ]));
604
+ return;
605
+ }
606
+ if (payload.status === 'approval_required') {
607
+ writeHuman(`profile: ${payload.profile}\napi_url: ${payload.api_url}\nstatus: ${payload.status}\nagent_name: ${payload.agent_name ?? 'unknown'}\napproval_url: ${payload.approval_url ?? 'unknown'}\n\nApprove this agent claim at the URL above, then rerun Harbor setup or \`harbor auth claim\`.`);
608
+ return;
609
+ }
610
+ writeHuman(`profile: ${payload.profile}\napi_url: ${payload.api_url}\nstatus: ${payload.status}\nowner: ${payload.owner ?? 'unknown'}\nagent_id: ${payload.agent_id ?? 'unknown'}\nagent_name: ${payload.agent_name ?? 'unknown'}\nhealth: ${payload.health ?? 'unknown'}\ncapabilities: ${payload.capabilities ?? 'unknown'}\npending_approvals: ${payload.pending_approvals ?? 'unknown'}\nrecent_executions: ${payload.recent_executions ?? 'unknown'}`);
611
+ };
612
+ export const renderStatus = (mode, payload) => {
613
+ const jsonPayload = {
614
+ profile: payload.profile,
615
+ agent_id: payload.whoami.agent_id,
616
+ health: payload.health.status,
617
+ capabilities: payload.capabilityCount,
618
+ pending_approvals: payload.health.pending_approvals,
619
+ recent_executions: payload.health.recent_executions,
620
+ };
621
+ if (mode === 'json') {
622
+ writeJson(jsonPayload);
623
+ return;
624
+ }
625
+ if (mode === 'plain') {
626
+ writePlain(linesFromRecord([
627
+ ['profile', payload.profile],
628
+ ['agent_id', payload.whoami.agent_id],
629
+ ['health', payload.health.status],
630
+ ['capabilities', payload.capabilityCount],
631
+ ['pending_approvals', payload.health.pending_approvals ?? ''],
632
+ ['recent_executions', payload.health.recent_executions ?? ''],
633
+ ]));
634
+ return;
635
+ }
636
+ writeHuman(`profile: ${payload.profile}\nagent_id: ${payload.whoami.agent_id ?? 'unknown'}\napi: ${payload.health.reachable ? 'reachable' : 'unreachable'}\ncapabilities: ${payload.capabilityCount}\npending_approvals: ${payload.health.pending_approvals ?? 'unknown'}\nrecent_executions: ${payload.health.recent_executions ?? 'unknown'}\nhealth: ${payload.health.status}`);
637
+ };
638
+ export const renderExecutionStart = (mode, payload) => {
639
+ if (mode === 'json') {
640
+ writeJson(payload);
641
+ return;
642
+ }
643
+ if (mode === 'plain') {
644
+ writePlain(linesFromRecord([
645
+ ['status', payload.status],
646
+ ['execution_id', payload.execution_id],
647
+ ['capability', payload.capability],
648
+ ['state', payload.state],
649
+ ['approval_id', payload.approval_id],
650
+ ['approval_url', payload.approval_url],
651
+ ['reason', payload.reason],
652
+ ]));
653
+ return;
654
+ }
655
+ if (payload.status === 'approval_required') {
656
+ const approvalHint = payload.approval_id
657
+ ? `\n\nThe owner must approve this request before it can proceed:\n harbor approve ${payload.approval_id} --yes\n\nThen retry with the approved escalation:\n harbor ${payload.capability ?? '<capability>'} ... --approval-id ${payload.approval_id}`
658
+ : '';
659
+ writeHuman(`status: ${payload.status}\napproval_id: ${payload.approval_id ?? 'unknown'}\ncapability: ${payload.capability ?? 'unknown'}\nreason: ${payload.reason ?? 'grant required'}${approvalHint}`);
660
+ return;
661
+ }
662
+ writeHuman(`status: ${payload.status}\nexecution_id: ${payload.execution_id ?? 'unknown'}\ncapability: ${payload.capability ?? 'unknown'}\nstate: ${payload.state ?? 'queued'}`);
663
+ };
664
+ export const renderError = (mode, error) => {
665
+ if (error instanceof CliInputError) {
666
+ const payload = {
667
+ code: error.code,
668
+ message: error.message,
669
+ invocation: error.invocation,
670
+ note: error.note,
671
+ };
672
+ if (mode === 'json') {
673
+ writeJsonError(payload);
674
+ return;
675
+ }
676
+ if (mode === 'plain') {
677
+ writePlainError(linesFromRecord([
678
+ ['error', error.code],
679
+ ['message', error.message],
680
+ ['invocation', error.invocation],
681
+ ['note', error.note],
682
+ ]));
683
+ return;
684
+ }
685
+ writeHumanError(`Error: ${error.message}\n ${error.invocation}${error.note ? `\n ${error.note}` : ''}`);
686
+ return;
687
+ }
688
+ if (error instanceof ApiError) {
689
+ const payload = {
690
+ code: error.code,
691
+ message: error.message,
692
+ status: error.status,
693
+ };
694
+ if (mode === 'json') {
695
+ writeJsonError(payload);
696
+ return;
697
+ }
698
+ if (mode === 'plain') {
699
+ writePlainError(linesFromRecord([
700
+ ['error', error.code],
701
+ ['message', error.message],
702
+ ['status', error.status],
703
+ ]));
704
+ return;
705
+ }
706
+ writeHumanError(`Error: ${error.message}`);
707
+ return;
708
+ }
709
+ if (error instanceof Error) {
710
+ const code = typeof error.code === 'string'
711
+ ? error.code
712
+ : null;
713
+ const status = typeof error.status === 'number'
714
+ ? error.status
715
+ : null;
716
+ if (code) {
717
+ if (mode === 'json') {
718
+ writeJsonError({ code, message: error.message, ...(status !== null ? { status } : {}) });
719
+ return;
720
+ }
721
+ if (mode === 'plain') {
722
+ writePlainError(linesFromRecord([
723
+ ['error', code],
724
+ ['message', error.message],
725
+ ['status', status ?? ''],
726
+ ]));
727
+ return;
728
+ }
729
+ writeHumanError(`Error: ${error.message}`);
730
+ return;
731
+ }
732
+ }
733
+ const message = error instanceof Error ? error.message : String(error);
734
+ if (mode === 'json') {
735
+ writeJsonError({ code: 'unexpected_error', message });
736
+ return;
737
+ }
738
+ if (mode === 'plain') {
739
+ writePlainError(linesFromRecord([
740
+ ['error', 'unexpected_error'],
741
+ ['message', message],
742
+ ]));
743
+ return;
744
+ }
745
+ writeHumanError(`Error: ${message}`);
746
+ };
747
+ export const withOwner = (claim, whoami, profile) => ({
748
+ ...claim,
749
+ owner: claim.owner ?? whoami?.owner ?? null,
750
+ profile: whoami?.profile_slug ?? claim.profile_slug ?? profile.profile_slug,
751
+ });
752
+ //# sourceMappingURL=output.js.map