@agentuity/cli 2.0.9 → 2.0.11

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 (60) hide show
  1. package/dist/cmd/build/vite/agent-discovery.js +4 -4
  2. package/dist/cmd/build/vite/agent-discovery.js.map +1 -1
  3. package/dist/cmd/coder/archive.js +1 -1
  4. package/dist/cmd/coder/archive.js.map +1 -1
  5. package/dist/cmd/coder/create.d.ts.map +1 -1
  6. package/dist/cmd/coder/create.js +18 -0
  7. package/dist/cmd/coder/create.js.map +1 -1
  8. package/dist/cmd/coder/delete.js +1 -1
  9. package/dist/cmd/coder/delete.js.map +1 -1
  10. package/dist/cmd/coder/events.js +1 -1
  11. package/dist/cmd/coder/events.js.map +1 -1
  12. package/dist/cmd/coder/get.js +1 -1
  13. package/dist/cmd/coder/get.js.map +1 -1
  14. package/dist/cmd/coder/index.d.ts.map +1 -1
  15. package/dist/cmd/coder/index.js +8 -4
  16. package/dist/cmd/coder/index.js.map +1 -1
  17. package/dist/cmd/coder/list.js +2 -2
  18. package/dist/cmd/coder/list.js.map +1 -1
  19. package/dist/cmd/coder/loop.js +1 -1
  20. package/dist/cmd/coder/loop.js.map +1 -1
  21. package/dist/cmd/coder/participants.js +1 -1
  22. package/dist/cmd/coder/participants.js.map +1 -1
  23. package/dist/cmd/coder/replay.js +1 -1
  24. package/dist/cmd/coder/replay.js.map +1 -1
  25. package/dist/cmd/coder/start.d.ts.map +1 -1
  26. package/dist/cmd/coder/start.js +55 -6
  27. package/dist/cmd/coder/start.js.map +1 -1
  28. package/dist/cmd/coder/tui-init.d.ts +1 -0
  29. package/dist/cmd/coder/tui-init.d.ts.map +1 -1
  30. package/dist/cmd/coder/tui-init.js +9 -1
  31. package/dist/cmd/coder/tui-init.js.map +1 -1
  32. package/dist/cmd/coder/update.d.ts.map +1 -1
  33. package/dist/cmd/coder/update.js +21 -1
  34. package/dist/cmd/coder/update.js.map +1 -1
  35. package/dist/cmd/coder/users.js +1 -1
  36. package/dist/cmd/coder/users.js.map +1 -1
  37. package/dist/cmd/coder/workspace/create.d.ts.map +1 -1
  38. package/dist/cmd/coder/workspace/create.js +17 -1
  39. package/dist/cmd/coder/workspace/create.js.map +1 -1
  40. package/dist/cmd/coder/workspace/list.js +2 -2
  41. package/dist/cmd/coder/workspace/list.js.map +1 -1
  42. package/dist/types.d.ts +1 -1
  43. package/package.json +7 -7
  44. package/src/cmd/build/vite/agent-discovery.ts +4 -4
  45. package/src/cmd/coder/archive.ts +1 -1
  46. package/src/cmd/coder/create.ts +24 -1
  47. package/src/cmd/coder/delete.ts +1 -1
  48. package/src/cmd/coder/events.ts +1 -1
  49. package/src/cmd/coder/get.ts +1 -1
  50. package/src/cmd/coder/index.ts +8 -4
  51. package/src/cmd/coder/list.ts +2 -2
  52. package/src/cmd/coder/loop.ts +1 -1
  53. package/src/cmd/coder/participants.ts +1 -1
  54. package/src/cmd/coder/replay.ts +1 -1
  55. package/src/cmd/coder/start.ts +66 -6
  56. package/src/cmd/coder/tui-init.ts +9 -1
  57. package/src/cmd/coder/update.ts +18 -1
  58. package/src/cmd/coder/users.ts +1 -1
  59. package/src/cmd/coder/workspace/create.ts +20 -2
  60. package/src/cmd/coder/workspace/list.ts +2 -2
@@ -1,4 +1,6 @@
1
1
  import { dirname, resolve } from 'node:path';
2
+ import { stat } from 'node:fs/promises';
3
+ import { homedir } from 'node:os';
2
4
  import { z } from 'zod';
3
5
  import { CoderClient, type CoderSessionListItem } from '@agentuity/core/coder';
4
6
  import { ValidationOutputError } from '@agentuity/core';
@@ -54,9 +56,9 @@ function logValidationIssues(
54
56
  }
55
57
 
56
58
  export const startSubcommand = createSubcommand({
57
- name: 'start',
58
- aliases: ['run'],
59
- description: 'Start a Pi coding session connected to the Coder Hub',
59
+ name: 'tui',
60
+ aliases: ['run', 'start'],
61
+ description: 'Start a coding session connected to Coder',
60
62
  tags: ['fast', 'requires-auth'],
61
63
  requires: { auth: true, org: true },
62
64
  examples: [
@@ -64,9 +66,13 @@ export const startSubcommand = createSubcommand({
64
66
  command: getCommand('coder start'),
65
67
  description: 'Start Pi with auto-detected Hub and extension',
66
68
  },
69
+ {
70
+ command: getCommand('coder start --dir ~/path/to/my/project'),
71
+ description: 'Start from a specific local project directory',
72
+ },
67
73
  {
68
74
  command: getCommand('coder start --url ws://127.0.0.1:3500/api/ws'),
69
- description: 'Start with explicit Hub URL',
75
+ description: 'Start with explicit Coder URL',
70
76
  },
71
77
  {
72
78
  command: getCommand('coder start --extension ~/repos/agentuity/sdk/packages/coder-tui'),
@@ -97,6 +103,7 @@ export const startSubcommand = createSubcommand({
97
103
  ],
98
104
  schema: {
99
105
  options: z.object({
106
+ dir: z.string().optional().describe('Local project directory to start from'),
100
107
  url: z.string().optional().describe('Coder API URL override'),
101
108
  extension: z.string().optional().describe('Coder extension path override'),
102
109
  pi: z.string().optional().describe('Path to pi binary'),
@@ -121,6 +128,30 @@ export const startSubcommand = createSubcommand({
121
128
  },
122
129
  async handler(ctx) {
123
130
  const { opts, options } = ctx;
131
+
132
+ // Resolve working directory from optional --dir option
133
+ let cwd = process.cwd();
134
+ if (opts?.dir) {
135
+ // Warn if --dir is provided with --remote or --sandbox (dir is ignored in those modes)
136
+ if (opts?.remote !== undefined || opts?.sandbox !== undefined) {
137
+ tui.warning('--dir is ignored in remote/sandbox mode');
138
+ } else {
139
+ const raw = opts.dir.trim();
140
+ cwd =
141
+ raw === '~' || raw.startsWith('~/')
142
+ ? resolve(homedir(), raw.slice(2))
143
+ : resolve(raw);
144
+
145
+ const st = await stat(cwd).catch(() => null);
146
+ if (!st?.isDirectory()) {
147
+ tui.fatal(
148
+ `The specified path is not a valid directory: ${cwd}`,
149
+ ErrorCode.CONFIG_INVALID
150
+ );
151
+ return;
152
+ }
153
+ }
154
+ }
124
155
  const client = new CoderClient({
125
156
  apiKey: ctx.auth.apiKey,
126
157
  url: opts?.url,
@@ -132,10 +163,11 @@ export const startSubcommand = createSubcommand({
132
163
 
133
164
  const initProbe = await probeHubInitAccess(hubHttpUrl, {
134
165
  apiKey: ctx.auth.apiKey,
166
+ orgId: ctx.orgId,
135
167
  });
136
168
  if (!initProbe.ok) {
137
169
  tui.fatal(
138
- `Could not bootstrap the Coder Hub at ${hubHttpUrl}: ${initProbe.message}`,
170
+ `Could not bootstrap the Coder at ${hubHttpUrl}: ${initProbe.message}`,
139
171
  ErrorCode.NETWORK_ERROR
140
172
  );
141
173
  return;
@@ -215,6 +247,33 @@ export const startSubcommand = createSubcommand({
215
247
  // with the coder extension loaded for Hub UI (footer, /hub, commands).
216
248
  // Agent.emit() drives native rendering — no [remote_message] blocks.
217
249
  if (remoteSessionId) {
250
+ try {
251
+ const session = await tui.spinner({
252
+ message: 'Preparing remote session…',
253
+ callback: async () => client.prepareSessionForRemoteAttach(remoteSessionId!),
254
+ });
255
+
256
+ if (session.historyOnly === true) {
257
+ tui.fatal(
258
+ `Session ${remoteSessionId} is history-only and cannot be attached remotely.`,
259
+ ErrorCode.CONFIG_INVALID
260
+ );
261
+ return;
262
+ }
263
+
264
+ if (session.runtimeAvailable === false) {
265
+ tui.fatal(
266
+ `Session ${remoteSessionId} is offline and could not be resumed for remote attach.`,
267
+ ErrorCode.NETWORK_ERROR
268
+ );
269
+ return;
270
+ }
271
+ } catch (err) {
272
+ const msg = err instanceof Error ? err.message : String(err);
273
+ tui.fatal(`Failed to prepare remote session: ${msg}`, ErrorCode.NETWORK_ERROR);
274
+ return;
275
+ }
276
+
218
277
  if (!options.json) {
219
278
  tui.newline();
220
279
  tui.output(` Hub: ${tui.bold(hubWsUrl)}`);
@@ -342,6 +401,7 @@ export const startSubcommand = createSubcommand({
342
401
  tui.output(` Hub: ${tui.bold(hubWsUrl)}`);
343
402
  tui.output(` Extension: ${tui.bold(extensionPath)}`);
344
403
  tui.output(` Pi: ${tui.bold(piBinary)}`);
404
+ if (opts?.dir) tui.output(` Dir: ${tui.bold(cwd)}`);
345
405
  if (opts?.agent) tui.output(` Agent: ${tui.bold(opts.agent)}`);
346
406
  tui.newline();
347
407
  }
@@ -350,7 +410,7 @@ export const startSubcommand = createSubcommand({
350
410
  try {
351
411
  const proc = Bun.spawn([piBinary, ...piArgs], {
352
412
  env,
353
- cwd: process.cwd(),
413
+ cwd,
354
414
  stdin: 'inherit',
355
415
  stdout: 'inherit',
356
416
  stderr: 'inherit',
@@ -21,6 +21,7 @@ export async function probeHubInitAccess(
21
21
  hubHttpUrl: string,
22
22
  options?: {
23
23
  apiKey?: string | null;
24
+ orgId?: string | null;
24
25
  fetchImpl?: typeof fetch;
25
26
  }
26
27
  ): Promise<HubInitProbeResult> {
@@ -29,7 +30,14 @@ export async function probeHubInitAccess(
29
30
  accept: 'application/json',
30
31
  };
31
32
  if (options?.apiKey) {
32
- headers['x-agentuity-auth-api-key'] = options.apiKey;
33
+ if (options.apiKey.startsWith('agc_')) {
34
+ headers['x-agentuity-auth-api-key'] = options.apiKey;
35
+ } else {
36
+ headers['authorization'] = `Bearer ${options.apiKey}`;
37
+ }
38
+ }
39
+ if (options?.orgId) {
40
+ headers['x-agentuity-orgid'] = options.orgId;
33
41
  }
34
42
 
35
43
  try {
@@ -40,6 +40,10 @@ export const updateSubcommand = createSubcommand({
40
40
  url: z.string().optional().describe('Coder API URL override'),
41
41
  label: z.string().optional().describe('Updated session label'),
42
42
  agent: z.string().optional().describe('Updated default agent role'),
43
+ defaultAgent: z
44
+ .string()
45
+ .optional()
46
+ .describe('Updated preferred default agent slug or built-in route target'),
43
47
  visibility: z
44
48
  .string()
45
49
  .optional()
@@ -50,6 +54,10 @@ export const updateSubcommand = createSubcommand({
50
54
  loopAutoContinue: z.boolean().optional().describe('Auto-continue loop'),
51
55
  loopAllowDetached: z.boolean().optional().describe('Allow detached loop execution'),
52
56
  tags: z.string().optional().describe('Comma-separated tags (replaces existing)'),
57
+ agentSlugs: z
58
+ .string()
59
+ .optional()
60
+ .describe('Comma-separated published custom agent slugs (replaces existing)'),
53
61
  }),
54
62
  },
55
63
  async handler(ctx) {
@@ -64,6 +72,7 @@ export const updateSubcommand = createSubcommand({
64
72
 
65
73
  if (opts?.label) body.label = opts.label;
66
74
  if (opts?.agent) body.agent = opts.agent;
75
+ if (opts?.defaultAgent) body.defaultAgent = opts.defaultAgent;
67
76
  if (opts?.visibility) body.visibility = normalizeVisibility(opts.visibility);
68
77
  if (opts?.workflowMode) body.workflowMode = opts.workflowMode;
69
78
  if (opts?.tags) {
@@ -72,6 +81,12 @@ export const updateSubcommand = createSubcommand({
72
81
  .map((t) => t.trim())
73
82
  .filter(Boolean);
74
83
  }
84
+ if (opts?.agentSlugs) {
85
+ body.agentSlugs = opts.agentSlugs
86
+ .split(',')
87
+ .map((slug) => slug.trim())
88
+ .filter(Boolean);
89
+ }
75
90
 
76
91
  if (
77
92
  opts?.loopGoal ||
@@ -90,7 +105,7 @@ export const updateSubcommand = createSubcommand({
90
105
 
91
106
  if (Object.keys(body).length === 0) {
92
107
  tui.fatal(
93
- 'No update fields provided. Use --label, --visibility, --tags, --agent, --workflow-mode, or loop options.',
108
+ 'No update fields provided. Use --label, --visibility, --tags, --agent, --default-agent, --agent-slugs, --workflow-mode, or loop options.',
94
109
  ErrorCode.VALIDATION_FAILED
95
110
  );
96
111
  }
@@ -109,6 +124,8 @@ export const updateSubcommand = createSubcommand({
109
124
  if (opts?.visibility) fields.push(`Visibility: ${body.visibility}`);
110
125
  if (opts?.tags) fields.push(`Tags: ${(body.tags as string[]).join(', ')}`);
111
126
  if (opts?.agent) fields.push(`Agent: ${opts.agent}`);
127
+ if (opts?.defaultAgent) fields.push(`Default agent: ${opts.defaultAgent}`);
128
+ if (opts?.agentSlugs) fields.push(`Custom agents: ${opts.agentSlugs}`);
112
129
  if (opts?.workflowMode || body.loop) fields.push(`Workflow: ${body.workflowMode}`);
113
130
 
114
131
  for (const f of fields) {
@@ -23,7 +23,7 @@ function formatRelativeTime(isoDate: string): string {
23
23
  export const usersSubcommand = createSubcommand({
24
24
  name: 'users',
25
25
  aliases: ['user'],
26
- description: 'List known Coder Hub users',
26
+ description: 'List known Coder users',
27
27
  tags: ['read-only', 'fast', 'requires-auth'],
28
28
  idempotent: true,
29
29
  requires: { auth: true, org: true },
@@ -45,6 +45,10 @@ export const createWorkspaceSubcommand = createSubcommand({
45
45
  scope: z.string().optional().describe('Workspace scope: user or org'),
46
46
  repo: z.string().optional().describe('Repository URL to add'),
47
47
  repoBranch: z.string().optional().describe('Branch for the repository'),
48
+ agentSlugs: z
49
+ .string()
50
+ .optional()
51
+ .describe('Comma-separated published custom agent slugs to add'),
48
52
  }),
49
53
  },
50
54
  async handler(ctx) {
@@ -55,7 +59,9 @@ export const createWorkspaceSubcommand = createSubcommand({
55
59
  orgId: ctx.orgId,
56
60
  });
57
61
 
58
- const body: CoderCreateWorkspaceRequest = {
62
+ const body: CoderCreateWorkspaceRequest & {
63
+ agentSlugs?: string[];
64
+ } = {
59
65
  name: args.name,
60
66
  ...(opts?.description && { description: opts.description }),
61
67
  ...(opts?.scope && { scope: opts.scope as 'user' | 'org' }),
@@ -72,9 +78,18 @@ export const createWorkspaceSubcommand = createSubcommand({
72
78
  return;
73
79
  }
74
80
  }
81
+ if (opts?.agentSlugs) {
82
+ body.agentSlugs = opts.agentSlugs
83
+ .split(',')
84
+ .map((slug) => slug.trim())
85
+ .filter(Boolean);
86
+ }
75
87
 
76
88
  try {
77
89
  const created = await client.createWorkspace(body);
90
+ const createdAgentSlugs = Array.isArray(created.agentSlugs)
91
+ ? created.agentSlugs.filter((slug): slug is string => typeof slug === 'string')
92
+ : [];
78
93
 
79
94
  if (options.json) {
80
95
  return created;
@@ -88,7 +103,10 @@ export const createWorkspaceSubcommand = createSubcommand({
88
103
  }
89
104
  tui.output(` Scope: ${created.scope}`);
90
105
  tui.output(` Repos: ${created.repoCount}`);
91
- tui.output(` Skills: ${created.selectionCount}`);
106
+ tui.output(` Selections: ${created.selectionCount}`);
107
+ if (createdAgentSlugs.length > 0) {
108
+ tui.output(` Agents: ${createdAgentSlugs.join(', ')}`);
109
+ }
92
110
 
93
111
  return created;
94
112
  } catch (err) {
@@ -83,7 +83,7 @@ export const listSubcommand = createSubcommand({
83
83
  Name: w.name,
84
84
  Scope: w.scope,
85
85
  Repos: String(w.repoCount),
86
- Skills: String(w.selectionCount),
86
+ Selections: String(w.selectionCount),
87
87
  Created: formatRelativeTime(w.createdAt),
88
88
  })),
89
89
  [
@@ -91,7 +91,7 @@ export const listSubcommand = createSubcommand({
91
91
  { name: 'Name', alignment: 'left' },
92
92
  { name: 'Scope', alignment: 'center' },
93
93
  { name: 'Repos', alignment: 'right' },
94
- { name: 'Skills', alignment: 'right' },
94
+ { name: 'Selections', alignment: 'right' },
95
95
  { name: 'Created', alignment: 'right' },
96
96
  ]
97
97
  );