@agentuity/cli 2.0.7 → 2.0.8

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 (176) hide show
  1. package/dist/cli.d.ts.map +1 -1
  2. package/dist/cli.js +4 -2
  3. package/dist/cli.js.map +1 -1
  4. package/dist/cmd/build/vite/route-discovery.d.ts.map +1 -1
  5. package/dist/cmd/build/vite/route-discovery.js +6 -0
  6. package/dist/cmd/build/vite/route-discovery.js.map +1 -1
  7. package/dist/cmd/cloud/sandbox/fs/rm.d.ts.map +1 -1
  8. package/dist/cmd/cloud/sandbox/fs/rm.js +9 -3
  9. package/dist/cmd/cloud/sandbox/fs/rm.js.map +1 -1
  10. package/dist/cmd/cloud/sandbox/fs/rmdir.d.ts.map +1 -1
  11. package/dist/cmd/cloud/sandbox/fs/rmdir.js +9 -3
  12. package/dist/cmd/cloud/sandbox/fs/rmdir.js.map +1 -1
  13. package/dist/cmd/coder/archive.d.ts +2 -0
  14. package/dist/cmd/coder/archive.d.ts.map +1 -0
  15. package/dist/cmd/coder/archive.js +57 -0
  16. package/dist/cmd/coder/archive.js.map +1 -0
  17. package/dist/cmd/coder/create.d.ts +2 -0
  18. package/dist/cmd/coder/create.d.ts.map +1 -0
  19. package/dist/cmd/coder/create.js +245 -0
  20. package/dist/cmd/coder/create.js.map +1 -0
  21. package/dist/cmd/coder/delete.d.ts +2 -0
  22. package/dist/cmd/coder/delete.d.ts.map +1 -0
  23. package/dist/cmd/coder/delete.js +64 -0
  24. package/dist/cmd/coder/delete.js.map +1 -0
  25. package/dist/cmd/coder/events.d.ts +2 -0
  26. package/dist/cmd/coder/events.d.ts.map +1 -0
  27. package/dist/cmd/coder/events.js +99 -0
  28. package/dist/cmd/coder/events.js.map +1 -0
  29. package/dist/cmd/coder/extension-path.d.ts +8 -0
  30. package/dist/cmd/coder/extension-path.d.ts.map +1 -0
  31. package/dist/cmd/coder/extension-path.js +59 -0
  32. package/dist/cmd/coder/extension-path.js.map +1 -0
  33. package/dist/cmd/coder/get.d.ts +2 -0
  34. package/dist/cmd/coder/get.d.ts.map +1 -0
  35. package/dist/cmd/coder/{inspect.js → get.js} +38 -42
  36. package/dist/cmd/coder/get.js.map +1 -0
  37. package/dist/cmd/coder/index.d.ts.map +1 -1
  38. package/dist/cmd/coder/index.js +52 -7
  39. package/dist/cmd/coder/index.js.map +1 -1
  40. package/dist/cmd/coder/list.d.ts.map +1 -1
  41. package/dist/cmd/coder/list.js +26 -42
  42. package/dist/cmd/coder/list.js.map +1 -1
  43. package/dist/cmd/coder/loop.d.ts +2 -0
  44. package/dist/cmd/coder/loop.d.ts.map +1 -0
  45. package/dist/cmd/coder/loop.js +78 -0
  46. package/dist/cmd/coder/loop.js.map +1 -0
  47. package/dist/cmd/coder/participants.d.ts +2 -0
  48. package/dist/cmd/coder/participants.d.ts.map +1 -0
  49. package/dist/cmd/coder/participants.js +93 -0
  50. package/dist/cmd/coder/participants.js.map +1 -0
  51. package/dist/cmd/coder/replay.d.ts +2 -0
  52. package/dist/cmd/coder/replay.d.ts.map +1 -0
  53. package/dist/cmd/coder/replay.js +53 -0
  54. package/dist/cmd/coder/replay.js.map +1 -0
  55. package/dist/cmd/coder/resolve-repo.d.ts +27 -0
  56. package/dist/cmd/coder/resolve-repo.d.ts.map +1 -0
  57. package/dist/cmd/coder/resolve-repo.js +97 -0
  58. package/dist/cmd/coder/resolve-repo.js.map +1 -0
  59. package/dist/cmd/coder/skill/buckets.d.ts +2 -0
  60. package/dist/cmd/coder/skill/buckets.d.ts.map +1 -0
  61. package/dist/cmd/coder/skill/buckets.js +174 -0
  62. package/dist/cmd/coder/skill/buckets.js.map +1 -0
  63. package/dist/cmd/coder/skill/delete.d.ts +2 -0
  64. package/dist/cmd/coder/skill/delete.d.ts.map +1 -0
  65. package/dist/cmd/coder/skill/delete.js +64 -0
  66. package/dist/cmd/coder/skill/delete.js.map +1 -0
  67. package/dist/cmd/coder/skill/index.d.ts +2 -0
  68. package/dist/cmd/coder/skill/index.d.ts.map +1 -0
  69. package/dist/cmd/coder/skill/index.js +33 -0
  70. package/dist/cmd/coder/skill/index.js.map +1 -0
  71. package/dist/cmd/coder/skill/list.d.ts +2 -0
  72. package/dist/cmd/coder/skill/list.d.ts.map +1 -0
  73. package/dist/cmd/coder/skill/list.js +93 -0
  74. package/dist/cmd/coder/skill/list.js.map +1 -0
  75. package/dist/cmd/coder/skill/save.d.ts +2 -0
  76. package/dist/cmd/coder/skill/save.d.ts.map +1 -0
  77. package/dist/cmd/coder/skill/save.js +77 -0
  78. package/dist/cmd/coder/skill/save.js.map +1 -0
  79. package/dist/cmd/coder/start.d.ts.map +1 -1
  80. package/dist/cmd/coder/start.js +87 -131
  81. package/dist/cmd/coder/start.js.map +1 -1
  82. package/dist/cmd/coder/tui-init.d.ts.map +1 -1
  83. package/dist/cmd/coder/tui-init.js +7 -2
  84. package/dist/cmd/coder/tui-init.js.map +1 -1
  85. package/dist/cmd/coder/update.d.ts +2 -0
  86. package/dist/cmd/coder/update.d.ts.map +1 -0
  87. package/dist/cmd/coder/update.js +126 -0
  88. package/dist/cmd/coder/update.js.map +1 -0
  89. package/dist/cmd/coder/users.d.ts +2 -0
  90. package/dist/cmd/coder/users.d.ts.map +1 -0
  91. package/dist/cmd/coder/users.js +97 -0
  92. package/dist/cmd/coder/users.js.map +1 -0
  93. package/dist/cmd/coder/workspace/create.d.ts +2 -0
  94. package/dist/cmd/coder/workspace/create.d.ts.map +1 -0
  95. package/dist/cmd/coder/workspace/create.js +97 -0
  96. package/dist/cmd/coder/workspace/create.js.map +1 -0
  97. package/dist/cmd/coder/workspace/delete.d.ts +2 -0
  98. package/dist/cmd/coder/workspace/delete.d.ts.map +1 -0
  99. package/dist/cmd/coder/workspace/delete.js +64 -0
  100. package/dist/cmd/coder/workspace/delete.js.map +1 -0
  101. package/dist/cmd/coder/workspace/get.d.ts +2 -0
  102. package/dist/cmd/coder/workspace/get.d.ts.map +1 -0
  103. package/dist/cmd/coder/workspace/get.js +109 -0
  104. package/dist/cmd/coder/workspace/get.js.map +1 -0
  105. package/dist/cmd/coder/workspace/index.d.ts +2 -0
  106. package/dist/cmd/coder/workspace/index.d.ts.map +1 -0
  107. package/dist/cmd/coder/workspace/index.js +38 -0
  108. package/dist/cmd/coder/workspace/index.js.map +1 -0
  109. package/dist/cmd/coder/workspace/list.d.ts +2 -0
  110. package/dist/cmd/coder/workspace/list.d.ts.map +1 -0
  111. package/dist/cmd/coder/workspace/list.js +93 -0
  112. package/dist/cmd/coder/workspace/list.js.map +1 -0
  113. package/dist/config.d.ts.map +1 -1
  114. package/dist/config.js +3 -3
  115. package/dist/config.js.map +1 -1
  116. package/dist/types.d.ts +1 -5
  117. package/dist/types.d.ts.map +1 -1
  118. package/dist/types.js +0 -10
  119. package/dist/types.js.map +1 -1
  120. package/package.json +7 -6
  121. package/src/cli.ts +4 -2
  122. package/src/cmd/ai/prompt/agent.md +6 -6
  123. package/src/cmd/build/vite/route-discovery.ts +8 -0
  124. package/src/cmd/cloud/sandbox/fs/rm.ts +8 -3
  125. package/src/cmd/cloud/sandbox/fs/rmdir.ts +8 -3
  126. package/src/cmd/coder/archive.ts +59 -0
  127. package/src/cmd/coder/create.ts +268 -0
  128. package/src/cmd/coder/delete.ts +67 -0
  129. package/src/cmd/coder/events.ts +106 -0
  130. package/src/cmd/coder/extension-path.ts +71 -0
  131. package/src/cmd/coder/{inspect.ts → get.ts} +45 -69
  132. package/src/cmd/coder/index.ts +52 -7
  133. package/src/cmd/coder/list.ts +29 -89
  134. package/src/cmd/coder/loop.ts +85 -0
  135. package/src/cmd/coder/participants.ts +100 -0
  136. package/src/cmd/coder/replay.ts +58 -0
  137. package/src/cmd/coder/resolve-repo.ts +119 -0
  138. package/src/cmd/coder/skill/buckets.ts +191 -0
  139. package/src/cmd/coder/skill/delete.ts +67 -0
  140. package/src/cmd/coder/skill/index.ts +35 -0
  141. package/src/cmd/coder/skill/list.ts +97 -0
  142. package/src/cmd/coder/skill/save.ts +84 -0
  143. package/src/cmd/coder/start.ts +101 -174
  144. package/src/cmd/coder/tui-init.ts +7 -3
  145. package/src/cmd/coder/update.ts +128 -0
  146. package/src/cmd/coder/users.ts +101 -0
  147. package/src/cmd/coder/workspace/create.ts +104 -0
  148. package/src/cmd/coder/workspace/delete.ts +70 -0
  149. package/src/cmd/coder/workspace/get.ts +112 -0
  150. package/src/cmd/coder/workspace/index.ts +38 -0
  151. package/src/cmd/coder/workspace/list.ts +101 -0
  152. package/src/config.ts +4 -3
  153. package/src/types.ts +0 -10
  154. package/dist/cmd/coder/config/index.d.ts +0 -2
  155. package/dist/cmd/coder/config/index.d.ts.map +0 -1
  156. package/dist/cmd/coder/config/index.js +0 -20
  157. package/dist/cmd/coder/config/index.js.map +0 -1
  158. package/dist/cmd/coder/config/set.d.ts +0 -2
  159. package/dist/cmd/coder/config/set.d.ts.map +0 -1
  160. package/dist/cmd/coder/config/set.js +0 -100
  161. package/dist/cmd/coder/config/set.js.map +0 -1
  162. package/dist/cmd/coder/hub-url.d.ts +0 -47
  163. package/dist/cmd/coder/hub-url.d.ts.map +0 -1
  164. package/dist/cmd/coder/hub-url.js +0 -148
  165. package/dist/cmd/coder/hub-url.js.map +0 -1
  166. package/dist/cmd/coder/inspect.d.ts +0 -2
  167. package/dist/cmd/coder/inspect.d.ts.map +0 -1
  168. package/dist/cmd/coder/inspect.js.map +0 -1
  169. package/dist/coder-config.d.ts +0 -14
  170. package/dist/coder-config.d.ts.map +0 -1
  171. package/dist/coder-config.js +0 -119
  172. package/dist/coder-config.js.map +0 -1
  173. package/src/cmd/coder/config/index.ts +0 -20
  174. package/src/cmd/coder/config/set.ts +0 -112
  175. package/src/cmd/coder/hub-url.ts +0 -205
  176. package/src/coder-config.ts +0 -141
@@ -0,0 +1,104 @@
1
+ import { z } from 'zod';
2
+ import { CoderClient, type CoderCreateWorkspaceRequest } from '@agentuity/core/coder';
3
+ import { ValidationOutputError } from '@agentuity/core';
4
+ import { createSubcommand } from '../../../types';
5
+ import * as tui from '../../../tui';
6
+ import { getCommand } from '../../../command-prefix';
7
+ import { ErrorCode } from '../../../errors';
8
+ import { resolveGitHubRepo } from '../resolve-repo';
9
+
10
+ export const createWorkspaceSubcommand = createSubcommand({
11
+ name: 'create',
12
+ aliases: ['new', 'add'],
13
+ description: 'Create a new Coder workspace',
14
+ tags: ['mutating', 'requires-auth'],
15
+ requires: { auth: true, org: true },
16
+ examples: [
17
+ {
18
+ command: getCommand('coder workspace create "My Workspace"'),
19
+ description: 'Create a workspace with a name',
20
+ },
21
+ {
22
+ command: getCommand(
23
+ 'coder workspace create "My Workspace" --description "For frontend work" --scope org'
24
+ ),
25
+ description: 'Create an org-scoped workspace with description',
26
+ },
27
+ {
28
+ command: getCommand(
29
+ 'coder workspace create "My Workspace" --repo https://github.com/org/repo --repo-branch main'
30
+ ),
31
+ description: 'Create a workspace with a repository',
32
+ },
33
+ {
34
+ command: getCommand('coder workspace create "My Workspace" --json'),
35
+ description: 'Create a workspace and return JSON output',
36
+ },
37
+ ],
38
+ schema: {
39
+ args: z.object({
40
+ name: z.string().describe('Workspace name'),
41
+ }),
42
+ options: z.object({
43
+ url: z.string().optional().describe('Coder API URL override'),
44
+ description: z.string().optional().describe('Workspace description'),
45
+ scope: z.string().optional().describe('Workspace scope: user or org'),
46
+ repo: z.string().optional().describe('Repository URL to add'),
47
+ repoBranch: z.string().optional().describe('Branch for the repository'),
48
+ }),
49
+ },
50
+ async handler(ctx) {
51
+ const { args, opts, options } = ctx;
52
+ const client = new CoderClient({
53
+ apiKey: ctx.auth.apiKey,
54
+ url: opts?.url,
55
+ orgId: ctx.orgId,
56
+ });
57
+
58
+ const body: CoderCreateWorkspaceRequest = {
59
+ name: args.name,
60
+ ...(opts?.description && { description: opts.description }),
61
+ ...(opts?.scope && { scope: opts.scope as 'user' | 'org' }),
62
+ };
63
+
64
+ if (opts?.repo) {
65
+ if (!options.json) tui.output('Resolving repository...');
66
+ try {
67
+ const resolved = await resolveGitHubRepo(client, opts.repo, opts?.repoBranch);
68
+ body.repos = [resolved];
69
+ } catch (err) {
70
+ const msg = err instanceof Error ? err.message : String(err);
71
+ tui.fatal(`Failed to resolve repository: ${msg}`, ErrorCode.VALIDATION_FAILED);
72
+ return;
73
+ }
74
+ }
75
+
76
+ try {
77
+ const created = await client.createWorkspace(body);
78
+
79
+ if (options.json) {
80
+ return created;
81
+ }
82
+
83
+ tui.success(`Workspace ${created.id} created.`);
84
+ tui.newline();
85
+ tui.output(` Name: ${tui.bold(created.name)}`);
86
+ if (created.description) {
87
+ tui.output(` Description: ${created.description}`);
88
+ }
89
+ tui.output(` Scope: ${created.scope}`);
90
+ tui.output(` Repos: ${created.repoCount}`);
91
+ tui.output(` Skills: ${created.selectionCount}`);
92
+
93
+ return created;
94
+ } catch (err) {
95
+ if (err instanceof ValidationOutputError) {
96
+ ctx.logger.trace('Validation response URL: %s', err.url ?? 'unknown');
97
+ ctx.logger.trace('Validation issues: %s', JSON.stringify(err.issues, null, 2));
98
+ tui.fatal(`Failed to create workspace: ${err.message}`, ErrorCode.VALIDATION_FAILED);
99
+ }
100
+ const msg = err instanceof Error ? err.message : String(err);
101
+ tui.fatal(`Failed to create workspace: ${msg}`, ErrorCode.NETWORK_ERROR);
102
+ }
103
+ },
104
+ });
@@ -0,0 +1,70 @@
1
+ import { z } from 'zod';
2
+ import { CoderClient } from '@agentuity/core/coder';
3
+ import { ValidationOutputError } from '@agentuity/core';
4
+ import { createSubcommand } from '../../../types';
5
+ import * as tui from '../../../tui';
6
+ import { getCommand } from '../../../command-prefix';
7
+ import { ErrorCode } from '../../../errors';
8
+
9
+ export const deleteWorkspaceSubcommand = createSubcommand({
10
+ name: 'delete',
11
+ aliases: ['rm', 'del', 'remove'],
12
+ description: 'Delete a Coder workspace',
13
+ tags: ['destructive', 'deletes-resource', 'requires-auth'],
14
+ requires: { auth: true, org: true },
15
+ examples: [
16
+ {
17
+ command: getCommand('coder workspace delete ws_abc123'),
18
+ description: 'Delete a workspace',
19
+ },
20
+ {
21
+ command: getCommand('coder workspace delete ws_abc123 --json'),
22
+ description: 'Delete a workspace and return JSON output',
23
+ },
24
+ ],
25
+ schema: {
26
+ args: z.object({
27
+ workspaceId: z.string().describe('Workspace ID to delete'),
28
+ }),
29
+ options: z.object({
30
+ url: z.string().optional().describe('Coder API URL override'),
31
+ }),
32
+ },
33
+ async handler(ctx) {
34
+ const { args, opts, options } = ctx;
35
+ const client = new CoderClient({
36
+ apiKey: ctx.auth.apiKey,
37
+ url: opts?.url,
38
+ orgId: ctx.orgId,
39
+ });
40
+
41
+ if (!options.json) {
42
+ const confirmed = await tui.confirm(`Delete workspace ${args.workspaceId}?`, false);
43
+ if (!confirmed) {
44
+ tui.info('Cancelled.');
45
+ return { deleted: false, workspaceId: args.workspaceId };
46
+ }
47
+ }
48
+
49
+ try {
50
+ await client.deleteWorkspace(args.workspaceId);
51
+ } catch (err) {
52
+ if (err instanceof ValidationOutputError) {
53
+ ctx.logger.trace('Validation response URL: %s', err.url ?? 'unknown');
54
+ ctx.logger.trace('Validation issues: %s', JSON.stringify(err.issues, null, 2));
55
+ }
56
+ const msg = err instanceof Error ? err.message : String(err);
57
+ tui.fatal(
58
+ `Failed to delete workspace ${args.workspaceId}: ${msg}`,
59
+ ErrorCode.NETWORK_ERROR
60
+ );
61
+ }
62
+
63
+ if (options.json) {
64
+ return { deleted: true, workspaceId: args.workspaceId };
65
+ }
66
+
67
+ tui.success(`Workspace ${args.workspaceId} deleted.`);
68
+ return { deleted: true, workspaceId: args.workspaceId };
69
+ },
70
+ });
@@ -0,0 +1,112 @@
1
+ import { z } from 'zod';
2
+ import { CoderClient } from '@agentuity/core/coder';
3
+ import { ValidationOutputError } from '@agentuity/core';
4
+ import { createSubcommand } from '../../../types';
5
+ import * as tui from '../../../tui';
6
+ import { getCommand } from '../../../command-prefix';
7
+ import { ErrorCode } from '../../../errors';
8
+
9
+ function formatRelativeTime(isoDate: string): string {
10
+ const parsed = new Date(isoDate).getTime();
11
+ if (Number.isNaN(parsed)) return 'unknown';
12
+ const diffMs = Math.max(0, Date.now() - parsed);
13
+ const seconds = Math.floor(diffMs / 1000);
14
+ if (seconds < 60) return `${seconds}s ago`;
15
+ const minutes = Math.floor(seconds / 60);
16
+ if (minutes < 60) return `${minutes}m ago`;
17
+ const hours = Math.floor(minutes / 60);
18
+ if (hours < 24) return `${hours}h ago`;
19
+ const days = Math.floor(hours / 24);
20
+ return `${days}d ago`;
21
+ }
22
+
23
+ export const getWorkspaceSubcommand = createSubcommand({
24
+ name: 'get',
25
+ aliases: ['show', 'inspect'],
26
+ description: 'Show detailed information about a Coder workspace',
27
+ tags: ['read-only', 'fast', 'requires-auth'],
28
+ idempotent: true,
29
+ requires: { auth: true, org: true },
30
+ examples: [
31
+ {
32
+ command: getCommand('coder workspace get ws_abc123'),
33
+ description: 'Get a workspace by ID',
34
+ },
35
+ {
36
+ command: getCommand('coder workspace get ws_abc123 --json'),
37
+ description: 'Get workspace details as JSON',
38
+ },
39
+ ],
40
+ schema: {
41
+ args: z.object({
42
+ workspaceId: z.string().describe('Workspace ID to inspect'),
43
+ }),
44
+ options: z.object({
45
+ url: z.string().optional().describe('Coder API URL override'),
46
+ }),
47
+ },
48
+ async handler(ctx) {
49
+ const { args, opts, options } = ctx;
50
+ const client = new CoderClient({
51
+ apiKey: ctx.auth.apiKey,
52
+ url: opts?.url,
53
+ orgId: ctx.orgId,
54
+ });
55
+
56
+ try {
57
+ const workspace = await client.getWorkspace(args.workspaceId);
58
+
59
+ if (options.json) {
60
+ return workspace;
61
+ }
62
+
63
+ tui.header(`Workspace: ${workspace.name}`);
64
+ tui.newline();
65
+ tui.output(` ID: ${workspace.id}`);
66
+ tui.output(` Name: ${tui.bold(workspace.name)}`);
67
+ if (workspace.description) {
68
+ tui.output(` Description: ${workspace.description}`);
69
+ }
70
+ tui.output(` Scope: ${workspace.scope}`);
71
+ tui.output(` Owner: ${workspace.ownerUserId}`);
72
+ tui.output(` Created: ${formatRelativeTime(workspace.createdAt)}`);
73
+ tui.output(` Updated: ${formatRelativeTime(workspace.updatedAt)}`);
74
+ tui.newline();
75
+
76
+ if (workspace.repos.length > 0) {
77
+ tui.output(` Repositories (${workspace.repoCount}):`);
78
+ for (const repo of workspace.repos) {
79
+ const name = repo.fullName || repo.name || repo.url || repo.cloneUrl || 'unknown';
80
+ const branch = repo.branch || repo.defaultBranch || '';
81
+ tui.output(` - ${name}${branch ? ` (${branch})` : ''}`);
82
+ }
83
+ tui.newline();
84
+ }
85
+
86
+ if (workspace.savedSkillIds.length > 0) {
87
+ tui.output(` Saved Skill IDs (${workspace.savedSkillIds.length}):`);
88
+ for (const id of workspace.savedSkillIds) {
89
+ tui.output(` - ${id}`);
90
+ }
91
+ tui.newline();
92
+ }
93
+
94
+ if (workspace.skillBucketIds.length > 0) {
95
+ tui.output(` Skill Bucket IDs (${workspace.skillBucketIds.length}):`);
96
+ for (const id of workspace.skillBucketIds) {
97
+ tui.output(` - ${id}`);
98
+ }
99
+ tui.newline();
100
+ }
101
+
102
+ return workspace;
103
+ } catch (err) {
104
+ if (err instanceof ValidationOutputError) {
105
+ ctx.logger.trace('Validation response URL: %s', err.url ?? 'unknown');
106
+ ctx.logger.trace('Validation issues: %s', JSON.stringify(err.issues, null, 2));
107
+ }
108
+ const msg = err instanceof Error ? err.message : String(err);
109
+ tui.fatal(`Failed to get workspace ${args.workspaceId}: ${msg}`, ErrorCode.NETWORK_ERROR);
110
+ }
111
+ },
112
+ });
@@ -0,0 +1,38 @@
1
+ import { createCommand } from '../../../types';
2
+ import { listSubcommand } from './list';
3
+ import { createWorkspaceSubcommand } from './create';
4
+ import { getWorkspaceSubcommand } from './get';
5
+ import { deleteWorkspaceSubcommand } from './delete';
6
+ import { getCommand } from '../../../command-prefix';
7
+
8
+ export const workspaceCommand = createCommand({
9
+ name: 'workspace',
10
+ aliases: ['workspaces', 'ws'],
11
+ description: 'Manage Coder workspaces',
12
+ tags: ['requires-auth'],
13
+ requires: { auth: true, org: true },
14
+ examples: [
15
+ {
16
+ command: getCommand('coder workspace list'),
17
+ description: 'List all workspaces',
18
+ },
19
+ {
20
+ command: getCommand('coder workspace create "My Workspace"'),
21
+ description: 'Create a new workspace',
22
+ },
23
+ {
24
+ command: getCommand('coder workspace get ws_abc123'),
25
+ description: 'Show workspace details',
26
+ },
27
+ {
28
+ command: getCommand('coder workspace delete ws_abc123'),
29
+ description: 'Delete a workspace',
30
+ },
31
+ ],
32
+ subcommands: [
33
+ listSubcommand,
34
+ createWorkspaceSubcommand,
35
+ getWorkspaceSubcommand,
36
+ deleteWorkspaceSubcommand,
37
+ ],
38
+ });
@@ -0,0 +1,101 @@
1
+ import { z } from 'zod';
2
+ import {
3
+ CoderClient,
4
+ type CoderWorkspaceDetail,
5
+ CoderWorkspaceDetailSchema,
6
+ } from '@agentuity/core/coder';
7
+ import { ValidationOutputError } from '@agentuity/core';
8
+ import { createSubcommand } from '../../../types';
9
+ import * as tui from '../../../tui';
10
+ import { getCommand } from '../../../command-prefix';
11
+ import { ErrorCode } from '../../../errors';
12
+
13
+ function formatRelativeTime(isoDate: string): string {
14
+ const parsed = new Date(isoDate).getTime();
15
+ if (Number.isNaN(parsed)) return 'unknown';
16
+ const diffMs = Math.max(0, Date.now() - parsed);
17
+ const seconds = Math.floor(diffMs / 1000);
18
+ if (seconds < 60) return `${seconds}s ago`;
19
+ const minutes = Math.floor(seconds / 60);
20
+ if (minutes < 60) return `${minutes}m ago`;
21
+ const hours = Math.floor(minutes / 60);
22
+ if (hours < 24) return `${hours}h ago`;
23
+ const days = Math.floor(hours / 24);
24
+ return `${days}d ago`;
25
+ }
26
+
27
+ export const listSubcommand = createSubcommand({
28
+ name: 'list',
29
+ aliases: ['ls'],
30
+ description: 'List Coder workspaces',
31
+ tags: ['read-only', 'fast', 'requires-auth'],
32
+ idempotent: true,
33
+ requires: { auth: true, org: true },
34
+ examples: [
35
+ {
36
+ command: getCommand('coder workspace list'),
37
+ description: 'List Coder workspaces',
38
+ },
39
+ {
40
+ command: getCommand('coder workspace list --json'),
41
+ description: 'Return workspaces as JSON',
42
+ },
43
+ ],
44
+ schema: {
45
+ options: z.object({
46
+ url: z.string().optional().describe('Coder API URL override'),
47
+ }),
48
+ response: z.array(CoderWorkspaceDetailSchema),
49
+ },
50
+ async handler(ctx) {
51
+ const { options, opts } = ctx;
52
+ const client = new CoderClient({
53
+ apiKey: ctx.auth.apiKey,
54
+ url: opts?.url,
55
+ orgId: ctx.orgId,
56
+ });
57
+
58
+ let workspaces: CoderWorkspaceDetail[] = [];
59
+ try {
60
+ const response = await client.listWorkspaces();
61
+ workspaces = response.workspaces;
62
+ } catch (err) {
63
+ if (err instanceof ValidationOutputError) {
64
+ ctx.logger.trace('Validation response URL: %s', err.url ?? 'unknown');
65
+ ctx.logger.trace('Validation issues: %s', JSON.stringify(err.issues, null, 2));
66
+ }
67
+ const msg = err instanceof Error ? err.message : String(err);
68
+ tui.fatal(`Failed to list Coder workspaces: ${msg}`, ErrorCode.NETWORK_ERROR);
69
+ }
70
+
71
+ if (options.json) {
72
+ return workspaces;
73
+ }
74
+
75
+ if (workspaces.length === 0) {
76
+ tui.info('No Coder workspaces found.');
77
+ return [];
78
+ }
79
+
80
+ tui.table(
81
+ workspaces.map((w) => ({
82
+ ID: w.id,
83
+ Name: w.name,
84
+ Scope: w.scope,
85
+ Repos: String(w.repoCount),
86
+ Skills: String(w.selectionCount),
87
+ Created: formatRelativeTime(w.createdAt),
88
+ })),
89
+ [
90
+ { name: 'ID', alignment: 'left' },
91
+ { name: 'Name', alignment: 'left' },
92
+ { name: 'Scope', alignment: 'center' },
93
+ { name: 'Repos', alignment: 'right' },
94
+ { name: 'Skills', alignment: 'right' },
95
+ { name: 'Created', alignment: 'right' },
96
+ ]
97
+ );
98
+
99
+ return workspaces;
100
+ },
101
+ });
package/src/config.ts CHANGED
@@ -162,11 +162,12 @@ export async function loadConfig(
162
162
  skipCache = false,
163
163
  profileFromFlag?: string
164
164
  ): Promise<Config | null> {
165
- // Use cache if available and not skipped
166
- if (!skipCache && cachedConfig !== undefined) {
165
+ const configPath = customPath ? expandTilde(customPath) : await getProfile(profileFromFlag);
166
+
167
+ // Use cache if available and not skipped, but only if the path matches
168
+ if (!skipCache && cachedConfig !== undefined && cachedConfigPath === configPath) {
167
169
  return cachedConfig;
168
170
  }
169
- const configPath = customPath ? expandTilde(customPath) : await getProfile(profileFromFlag);
170
171
 
171
172
  try {
172
173
  const file = Bun.file(configPath);
package/src/types.ts CHANGED
@@ -61,16 +61,6 @@ export const ConfigSchema = zod.object({
61
61
  })
62
62
  .optional()
63
63
  .describe('User preferences'),
64
- coder: zod
65
- .object({
66
- hubUrl: zod.string().optional().describe('Default Coder Hub URL'),
67
- apiKey: zod
68
- .string()
69
- .optional()
70
- .describe('Stored Coder Hub API key when secure keychain storage is unavailable'),
71
- })
72
- .optional()
73
- .describe('Coder Hub configuration managed by coder config commands'),
74
64
  gravity: zod
75
65
  .object({
76
66
  version: zod.string().optional().describe('The current gravity version'),
@@ -1,2 +0,0 @@
1
- export declare const configSubcommand: import("../../..").CommandDefinition;
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/cmd/coder/config/index.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,gBAAgB,sCAe3B,CAAC"}
@@ -1,20 +0,0 @@
1
- import { createCommand } from '../../../types';
2
- import { getCommand } from '../../../command-prefix';
3
- import { setSubcommand } from './set';
4
- export const configSubcommand = createCommand({
5
- name: 'config',
6
- description: 'Manage stored Coder Hub configuration',
7
- tags: ['fast'],
8
- examples: [
9
- {
10
- command: getCommand('coder config set url https://hub.example.com'),
11
- description: 'Set the default Coder Hub URL for the active profile',
12
- },
13
- {
14
- command: getCommand('coder config set apikey agc_...'),
15
- description: 'Set the default Coder Hub API key for the active profile',
16
- },
17
- ],
18
- subcommands: [setSubcommand],
19
- });
20
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/cmd/coder/config/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAEtC,MAAM,CAAC,MAAM,gBAAgB,GAAG,aAAa,CAAC;IAC7C,IAAI,EAAE,QAAQ;IACd,WAAW,EAAE,uCAAuC;IACpD,IAAI,EAAE,CAAC,MAAM,CAAC;IACd,QAAQ,EAAE;QACT;YACC,OAAO,EAAE,UAAU,CAAC,8CAA8C,CAAC;YACnE,WAAW,EAAE,sDAAsD;SACnE;QACD;YACC,OAAO,EAAE,UAAU,CAAC,iCAAiC,CAAC;YACtD,WAAW,EAAE,0DAA0D;SACvE;KACD;IACD,WAAW,EAAE,CAAC,aAAa,CAAC;CAC5B,CAAC,CAAC"}
@@ -1,2 +0,0 @@
1
- export declare const setSubcommand: import("../../..").CommandDefinition;
2
- //# sourceMappingURL=set.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"set.d.ts","sourceRoot":"","sources":["../../../../src/cmd/coder/config/set.ts"],"names":[],"mappings":"AAgGA,eAAO,MAAM,aAAa,sCAexB,CAAC"}
@@ -1,100 +0,0 @@
1
- import { z } from 'zod';
2
- import { saveCoderApiKey, saveCoderHubUrl } from '../../../coder-config';
3
- import { normalizeCoderHubHttpUrl } from '../../../coder-hub-url';
4
- import { getCommand } from '../../../command-prefix';
5
- import * as tui from '../../../tui';
6
- import { createCommand, createSubcommand } from '../../../types';
7
- const setUrlSubcommand = createSubcommand({
8
- name: 'url',
9
- description: 'Set the default Coder Hub URL for the active profile',
10
- tags: ['mutating', 'fast'],
11
- examples: [
12
- {
13
- command: getCommand('coder config set url https://hub.example.com'),
14
- description: 'Set the default Coder Hub URL',
15
- },
16
- {
17
- command: getCommand('coder config set url ws://127.0.0.1:3650/api/ws'),
18
- description: 'Store a local dev Hub URL using a WebSocket input',
19
- },
20
- ],
21
- schema: {
22
- args: z.object({
23
- url: z.string().min(1).describe('Hub URL to store for the active profile'),
24
- }),
25
- response: z.object({
26
- profile: z.string().describe('Active CLI profile name'),
27
- hubUrl: z.string().describe('Normalized stored Hub HTTP URL'),
28
- }),
29
- },
30
- async handler(ctx) {
31
- const { args, options } = ctx;
32
- const normalized = normalizeCoderHubHttpUrl(args.url);
33
- try {
34
- new URL(normalized);
35
- }
36
- catch {
37
- tui.fatal(`Invalid Hub URL: ${args.url}\n\nExpected a full URL such as https://hub.example.com or ws://127.0.0.1:3650/api/ws`);
38
- }
39
- const result = await saveCoderHubUrl(normalized);
40
- if (!options.json) {
41
- tui.success(`Default Coder Hub URL set to ${tui.bold(result.hubUrl)} for profile ${tui.bold(result.profileName)}`);
42
- }
43
- return {
44
- profile: result.profileName,
45
- hubUrl: result.hubUrl,
46
- };
47
- },
48
- });
49
- const setApiKeySubcommand = createSubcommand({
50
- name: 'apikey',
51
- description: 'Set the default Coder Hub API key for the active profile',
52
- tags: ['mutating', 'fast'],
53
- examples: [
54
- {
55
- command: getCommand('coder config set apikey agc_...'),
56
- description: 'Set the default Coder Hub API key',
57
- },
58
- ],
59
- schema: {
60
- args: z.object({
61
- apikey: z.string().min(1).describe('Hub API key to store for the active profile'),
62
- }),
63
- response: z.object({
64
- profile: z.string().describe('Active CLI profile name'),
65
- stored: z.boolean().describe('Whether the API key was stored successfully'),
66
- }),
67
- },
68
- async handler(ctx) {
69
- const { args, options } = ctx;
70
- const trimmed = args.apikey.trim();
71
- if (!trimmed) {
72
- tui.fatal('Hub API key cannot be empty');
73
- }
74
- const result = await saveCoderApiKey(trimmed);
75
- if (!options.json) {
76
- tui.success(`Coder Hub API key stored for profile ${tui.bold(result.profileName)}`);
77
- }
78
- return {
79
- profile: result.profileName,
80
- stored: true,
81
- };
82
- },
83
- });
84
- export const setSubcommand = createCommand({
85
- name: 'set',
86
- description: 'Set stored Coder Hub configuration values',
87
- tags: ['mutating', 'fast'],
88
- examples: [
89
- {
90
- command: getCommand('coder config set url https://hub.example.com'),
91
- description: 'Store the default Hub URL',
92
- },
93
- {
94
- command: getCommand('coder config set apikey agc_...'),
95
- description: 'Store the default Hub API key',
96
- },
97
- ],
98
- subcommands: [setUrlSubcommand, setApiKeySubcommand],
99
- });
100
- //# sourceMappingURL=set.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"set.js","sourceRoot":"","sources":["../../../../src/cmd/coder/config/set.ts"],"names":[],"mappings":"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"}
@@ -1,47 +0,0 @@
1
- /**
2
- * Hub URL resolution for Coder CLI commands.
3
- *
4
- * Resolution priority:
5
- * 1. --hub-url flag (explicit per-command override)
6
- * 2. AGENTUITY_CODER_HUB_URL env var
7
- * 3. Stored per-profile Hub URL
8
- * 4. AGENTUITY_DEVMODE_URL env var (dev tunnel URL)
9
- */
10
- import type { Config } from '../../types';
11
- export type HubApiKeySource = 'env' | 'stored' | 'none';
12
- export interface ResolvedHubApiKey {
13
- apiKey: string | null;
14
- source: HubApiKeySource;
15
- }
16
- /**
17
- * Resolve the Hub HTTP base URL for REST API calls.
18
- * Converts ws:// URLs to http:// automatically.
19
- *
20
- * @param flagUrl Optional --hub-url flag value
21
- * @returns HTTP base URL (e.g. "http://localhost:3500") or null if Hub is unreachable
22
- */
23
- export declare function resolveHubUrl(flagUrl?: string, config?: Config | null): Promise<string | null>;
24
- /**
25
- * Resolve the Hub WebSocket URL for Pi extension connections.
26
- * Converts http:// URLs to ws:// automatically and ensures /api/ws path.
27
- *
28
- * @param flagUrl Optional --hub-url flag value
29
- * @returns WebSocket URL (e.g. "ws://127.0.0.1:3500/api/ws") or null
30
- */
31
- export declare function resolveHubWsUrl(flagUrl?: string, config?: Config | null): Promise<string | null>;
32
- export declare function toHubWsUrl(hubHttpUrl: string): string;
33
- export declare function resolveHubApiKey(config?: Config | null): Promise<ResolvedHubApiKey>;
34
- /**
35
- * Build headers object with API key if available.
36
- */
37
- export declare function hubFetchHeaders(extra?: Record<string, string>, apiKey?: string | null): Record<string, string>;
38
- export declare function isHubUnauthorizedStatus(status: number): boolean;
39
- export declare function clearStoredHubApiKeyOnUnauthorized(status: number, resolvedApiKey: ResolvedHubApiKey, config?: Config | null, clearStoredApiKey?: (config?: Config | null) => Promise<unknown>): Promise<boolean>;
40
- export declare function getHubUrlSetupGuidance(): string;
41
- export declare function getHubApiKeySetupGuidance(): string;
42
- export declare function formatMissingHubUrlMessage(): string;
43
- export declare function formatHubUnauthorizedMessage(hubUrl: string, serverMessage: string, options?: {
44
- clearedStoredKey?: boolean;
45
- }): string;
46
- export declare function getHubResponseErrorMessage(response: Response): Promise<string>;
47
- //# sourceMappingURL=hub-url.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hub-url.d.ts","sourceRoot":"","sources":["../../../src/cmd/coder/hub-url.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AASH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAG1C,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;AAExD,MAAM,WAAW,iBAAiB;IACjC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,eAAe,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CAClC,OAAO,CAAC,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GACpB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiBxB;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACpC,OAAO,CAAC,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GACpB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAIxB;AAED,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAErD;AASD,wBAAsB,gBAAgB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAqBzF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC9B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GACpB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMxB;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED,wBAAsB,kCAAkC,CACvD,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,iBAAiB,EACjC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,EACtB,iBAAiB,GAAE,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,KAAK,OAAO,CAAC,OAAO,CAA0B,GACtF,OAAO,CAAC,OAAO,CAAC,CAOlB;AAED,wBAAgB,sBAAsB,IAAI,MAAM,CAM/C;AAED,wBAAgB,yBAAyB,IAAI,MAAM,CAMlD;AAED,wBAAgB,0BAA0B,IAAI,MAAM,CAEnD;AAED,wBAAgB,4BAA4B,CAC3C,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE;IACT,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC3B,GACC,MAAM,CAQR;AAED,wBAAsB,0BAA0B,CAAC,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CA8BpF"}