@agentuity/cli 2.0.5 → 2.0.7
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/README.md +11 -0
- package/dist/cmd/build/patch/otel-llm.js +2 -2
- package/dist/cmd/build/patch/otel-llm.js.map +1 -1
- package/dist/cmd/build/vite/bun-dev-server.d.ts.map +1 -1
- package/dist/cmd/build/vite/bun-dev-server.js +1 -0
- package/dist/cmd/build/vite/bun-dev-server.js.map +1 -1
- package/dist/cmd/build/vite/index.d.ts +0 -28
- package/dist/cmd/build/vite/index.d.ts.map +1 -1
- package/dist/cmd/build/vite/index.js +1 -104
- package/dist/cmd/build/vite/index.js.map +1 -1
- package/dist/cmd/build/vite/metadata-generator.d.ts.map +1 -1
- package/dist/cmd/build/vite/metadata-generator.js +8 -2
- package/dist/cmd/build/vite/metadata-generator.js.map +1 -1
- package/dist/cmd/build/vite/vite-asset-server-config.d.ts +2 -0
- package/dist/cmd/build/vite/vite-asset-server-config.d.ts.map +1 -1
- package/dist/cmd/build/vite/vite-asset-server-config.js +5 -1
- package/dist/cmd/build/vite/vite-asset-server-config.js.map +1 -1
- package/dist/cmd/build/vite/vite-asset-server.d.ts +2 -0
- package/dist/cmd/build/vite/vite-asset-server.d.ts.map +1 -1
- package/dist/cmd/build/vite/vite-asset-server.js +2 -1
- package/dist/cmd/build/vite/vite-asset-server.js.map +1 -1
- package/dist/cmd/build/vite/vite-builder.d.ts.map +1 -1
- package/dist/cmd/build/vite/vite-builder.js +143 -2
- package/dist/cmd/build/vite/vite-builder.js.map +1 -1
- package/dist/cmd/cloud/task/close.d.ts +3 -0
- package/dist/cmd/cloud/task/close.d.ts.map +1 -0
- package/dist/cmd/cloud/task/close.js +286 -0
- package/dist/cmd/cloud/task/close.js.map +1 -0
- package/dist/cmd/cloud/task/delete.d.ts +1 -5
- package/dist/cmd/cloud/task/delete.d.ts.map +1 -1
- package/dist/cmd/cloud/task/delete.js +15 -38
- package/dist/cmd/cloud/task/delete.js.map +1 -1
- package/dist/cmd/cloud/task/index.d.ts.map +1 -1
- package/dist/cmd/cloud/task/index.js +10 -0
- package/dist/cmd/cloud/task/index.js.map +1 -1
- package/dist/cmd/cloud/task/list.d.ts.map +1 -1
- package/dist/cmd/cloud/task/list.js +97 -3
- package/dist/cmd/cloud/task/list.js.map +1 -1
- package/dist/cmd/cloud/task/util.d.ts +10 -0
- package/dist/cmd/cloud/task/util.d.ts.map +1 -1
- package/dist/cmd/cloud/task/util.js +47 -3
- package/dist/cmd/cloud/task/util.js.map +1 -1
- package/dist/cmd/coder/config/index.d.ts +2 -0
- package/dist/cmd/coder/config/index.d.ts.map +1 -0
- package/dist/cmd/coder/config/index.js +20 -0
- package/dist/cmd/coder/config/index.js.map +1 -0
- package/dist/cmd/coder/config/set.d.ts +2 -0
- package/dist/cmd/coder/config/set.d.ts.map +1 -0
- package/dist/cmd/coder/config/set.js +100 -0
- package/dist/cmd/coder/config/set.js.map +1 -0
- package/dist/cmd/coder/hub-url.d.ts +21 -10
- package/dist/cmd/coder/hub-url.d.ts.map +1 -1
- package/dist/cmd/coder/hub-url.js +97 -55
- package/dist/cmd/coder/hub-url.js.map +1 -1
- package/dist/cmd/coder/index.d.ts.map +1 -1
- package/dist/cmd/coder/index.js +6 -1
- package/dist/cmd/coder/index.js.map +1 -1
- package/dist/cmd/coder/inspect.d.ts.map +1 -1
- package/dist/cmd/coder/inspect.js +15 -7
- package/dist/cmd/coder/inspect.js.map +1 -1
- package/dist/cmd/coder/list.d.ts.map +1 -1
- package/dist/cmd/coder/list.js +14 -7
- package/dist/cmd/coder/list.js.map +1 -1
- package/dist/cmd/coder/start.d.ts.map +1 -1
- package/dist/cmd/coder/start.js +38 -23
- package/dist/cmd/coder/start.js.map +1 -1
- package/dist/cmd/coder/tui-init.d.ts +4 -1
- package/dist/cmd/coder/tui-init.d.ts.map +1 -1
- package/dist/cmd/coder/tui-init.js +3 -2
- package/dist/cmd/coder/tui-init.js.map +1 -1
- package/dist/cmd/dev/index.d.ts.map +1 -1
- package/dist/cmd/dev/index.js +1 -0
- package/dist/cmd/dev/index.js.map +1 -1
- package/dist/cmd/dev/sync.js +5 -5
- package/dist/cmd/dev/sync.js.map +1 -1
- package/dist/coder-config.d.ts +14 -0
- package/dist/coder-config.d.ts.map +1 -0
- package/dist/coder-config.js +119 -0
- package/dist/coder-config.js.map +1 -0
- package/dist/coder-hub-url.d.ts +3 -0
- package/dist/coder-hub-url.d.ts.map +1 -0
- package/dist/coder-hub-url.js +32 -0
- package/dist/coder-hub-url.js.map +1 -0
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +11 -0
- package/dist/config.js.map +1 -1
- package/dist/internal-logger.d.ts +4 -0
- package/dist/internal-logger.d.ts.map +1 -1
- package/dist/internal-logger.js +64 -2
- package/dist/internal-logger.js.map +1 -1
- package/dist/keychain.d.ts +3 -0
- package/dist/keychain.d.ts.map +1 -1
- package/dist/keychain.js +47 -28
- package/dist/keychain.js.map +1 -1
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -1
- package/package.json +6 -6
- package/src/cmd/build/patch/otel-llm.ts +2 -2
- package/src/cmd/build/vite/bun-dev-server.ts +1 -0
- package/src/cmd/build/vite/index.ts +1 -148
- package/src/cmd/build/vite/metadata-generator.ts +8 -2
- package/src/cmd/build/vite/vite-asset-server-config.ts +16 -1
- package/src/cmd/build/vite/vite-asset-server.ts +4 -0
- package/src/cmd/build/vite/vite-builder.ts +171 -9
- package/src/cmd/cloud/task/close.ts +319 -0
- package/src/cmd/cloud/task/delete.ts +15 -43
- package/src/cmd/cloud/task/index.ts +10 -0
- package/src/cmd/cloud/task/list.ts +111 -4
- package/src/cmd/cloud/task/util.ts +59 -5
- package/src/cmd/coder/config/index.ts +20 -0
- package/src/cmd/coder/config/set.ts +112 -0
- package/src/cmd/coder/hub-url.ts +147 -53
- package/src/cmd/coder/index.ts +6 -1
- package/src/cmd/coder/inspect.ts +33 -10
- package/src/cmd/coder/list.ts +33 -10
- package/src/cmd/coder/start.ts +62 -26
- package/src/cmd/coder/tui-init.ts +7 -2
- package/src/cmd/dev/index.ts +1 -0
- package/src/cmd/dev/sync.ts +5 -5
- package/src/coder-config.ts +141 -0
- package/src/coder-hub-url.ts +32 -0
- package/src/config.ts +13 -0
- package/src/internal-logger.ts +83 -2
- package/src/keychain.ts +68 -39
- package/src/types.ts +10 -0
package/src/internal-logger.ts
CHANGED
|
@@ -43,6 +43,16 @@ const SENSITIVE_ENV_PATTERNS = [
|
|
|
43
43
|
/AUTH/i,
|
|
44
44
|
];
|
|
45
45
|
|
|
46
|
+
const MASKED_ARG_VALUE = '***MASKED***';
|
|
47
|
+
const SENSITIVE_ARG_PATTERNS = [
|
|
48
|
+
/^--?api[-_]?key$/i,
|
|
49
|
+
/^--?token$/i,
|
|
50
|
+
/^--?secret$/i,
|
|
51
|
+
/^--?password$/i,
|
|
52
|
+
/^--?client[-_]?secret$/i,
|
|
53
|
+
/^--?auth[-_]?value$/i,
|
|
54
|
+
];
|
|
55
|
+
|
|
46
56
|
interface SessionMetadata {
|
|
47
57
|
sessionId: string;
|
|
48
58
|
bucket: number;
|
|
@@ -102,6 +112,75 @@ function maskEnvironment(): Record<string, string> {
|
|
|
102
112
|
return masked;
|
|
103
113
|
}
|
|
104
114
|
|
|
115
|
+
function isSensitiveArgFlag(arg: string): boolean {
|
|
116
|
+
return SENSITIVE_ARG_PATTERNS.some((pattern) => pattern.test(arg));
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function sanitizeArgsForLogging(args: string[]): string[] {
|
|
120
|
+
const sanitized: string[] = [];
|
|
121
|
+
let maskNextValue = false;
|
|
122
|
+
|
|
123
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
124
|
+
const arg = args[i]!;
|
|
125
|
+
|
|
126
|
+
if (maskNextValue) {
|
|
127
|
+
if (!arg.startsWith('-')) {
|
|
128
|
+
sanitized.push(MASKED_ARG_VALUE);
|
|
129
|
+
maskNextValue = false;
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
sanitized.push(MASKED_ARG_VALUE);
|
|
134
|
+
maskNextValue = false;
|
|
135
|
+
i -= 1;
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (!arg.startsWith('-')) {
|
|
140
|
+
sanitized.push(arg);
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const equalsIndex = arg.indexOf('=');
|
|
145
|
+
if (equalsIndex > 0) {
|
|
146
|
+
const flag = arg.slice(0, equalsIndex);
|
|
147
|
+
if (isSensitiveArgFlag(flag)) {
|
|
148
|
+
sanitized.push(`${flag}=${MASKED_ARG_VALUE}`);
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
sanitized.push(arg);
|
|
154
|
+
if (isSensitiveArgFlag(arg)) {
|
|
155
|
+
maskNextValue = true;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return sanitized;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export function sanitizeCliCommandForLogging(
|
|
163
|
+
command: string,
|
|
164
|
+
args: string[]
|
|
165
|
+
): { command: string; args: string[] } {
|
|
166
|
+
const commandTokens = command ? command.split(' ') : [];
|
|
167
|
+
|
|
168
|
+
if (
|
|
169
|
+
commandTokens.length >= 5 &&
|
|
170
|
+
commandTokens[0] === 'coder' &&
|
|
171
|
+
commandTokens[1] === 'config' &&
|
|
172
|
+
commandTokens[2] === 'set' &&
|
|
173
|
+
commandTokens[3] === 'apikey'
|
|
174
|
+
) {
|
|
175
|
+
commandTokens[4] = MASKED_ARG_VALUE;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return {
|
|
179
|
+
command: commandTokens.join(' '),
|
|
180
|
+
args: sanitizeArgsForLogging(args),
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
105
184
|
/**
|
|
106
185
|
* Get the logs directory path
|
|
107
186
|
*/
|
|
@@ -266,14 +345,16 @@ export class InternalLogger implements Logger {
|
|
|
266
345
|
// Use workingDir as cwd in session metadata
|
|
267
346
|
const cwd = workingDir;
|
|
268
347
|
|
|
348
|
+
const sanitizedInvocation = sanitizeCliCommandForLogging(command, args);
|
|
349
|
+
|
|
269
350
|
// Gather session metadata
|
|
270
351
|
const sessionMetadata: SessionMetadata = {
|
|
271
352
|
sessionId: this.sessionId,
|
|
272
353
|
bucket: this.bucket,
|
|
273
354
|
pid: process.pid,
|
|
274
355
|
ppid: process.ppid,
|
|
275
|
-
command,
|
|
276
|
-
args,
|
|
356
|
+
command: sanitizedInvocation.command,
|
|
357
|
+
args: sanitizedInvocation.args,
|
|
277
358
|
timestamp: new Date().toISOString(),
|
|
278
359
|
cli: {
|
|
279
360
|
version: this.cliVersion,
|
package/src/keychain.ts
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
|
|
8
8
|
const SERVICE_PREFIX = 'com.agentuity.cli';
|
|
9
9
|
const KEY_ACCOUNT = 'aes-encryption-key';
|
|
10
|
+
const AUTH_ACCOUNT = 'auth-token';
|
|
11
|
+
const CODER_API_KEY_ACCOUNT = 'coder-hub-api-key';
|
|
10
12
|
|
|
11
13
|
/**
|
|
12
14
|
* Check if we're running on macOS
|
|
@@ -88,26 +90,15 @@ async function decrypt(combined: Uint8Array, keyBytes: Uint8Array): Promise<stri
|
|
|
88
90
|
return new TextDecoder().decode(plaintext);
|
|
89
91
|
}
|
|
90
92
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
profileName: string,
|
|
96
|
-
authData: { api_key: string; user_id: string; expires: number }
|
|
93
|
+
async function saveEncryptedValueToKeychain(
|
|
94
|
+
service: string,
|
|
95
|
+
account: string,
|
|
96
|
+
value: string
|
|
97
97
|
): Promise<void> {
|
|
98
|
-
const service = `${SERVICE_PREFIX}.${profileName}`;
|
|
99
|
-
const account = 'auth-token';
|
|
100
|
-
|
|
101
|
-
// Get or create encryption key
|
|
102
98
|
const key = await ensureEncryptionKey(service);
|
|
103
|
-
|
|
104
|
-
// Encrypt the auth data
|
|
105
|
-
const json = JSON.stringify(authData);
|
|
106
|
-
const encrypted = await encrypt(json, key);
|
|
99
|
+
const encrypted = await encrypt(value, key);
|
|
107
100
|
const b64 = Buffer.from(encrypted).toString('base64');
|
|
108
101
|
|
|
109
|
-
// Store encrypted auth in keychain
|
|
110
|
-
// First try to delete if exists, then add
|
|
111
102
|
const del = Bun.spawn(['security', 'delete-generic-password', '-s', service, '-a', account], {
|
|
112
103
|
stderr: 'ignore',
|
|
113
104
|
});
|
|
@@ -127,6 +118,43 @@ export async function saveAuthToKeychain(
|
|
|
127
118
|
await add.exited;
|
|
128
119
|
}
|
|
129
120
|
|
|
121
|
+
async function getEncryptedValueFromKeychain(
|
|
122
|
+
service: string,
|
|
123
|
+
account: string
|
|
124
|
+
): Promise<string | null> {
|
|
125
|
+
const find = Bun.spawn(
|
|
126
|
+
['security', 'find-generic-password', '-s', service, '-a', account, '-w'],
|
|
127
|
+
{ stderr: 'ignore' }
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
const stdout = await new Response(find.stdout).text();
|
|
131
|
+
if (stdout.length === 0) {
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const encrypted = Uint8Array.from(Buffer.from(stdout.trim(), 'base64'));
|
|
136
|
+
const key = await ensureEncryptionKey(service);
|
|
137
|
+
return decrypt(encrypted, key);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async function deleteValueFromKeychain(service: string, account: string): Promise<void> {
|
|
141
|
+
const del = Bun.spawn(['security', 'delete-generic-password', '-s', service, '-a', account], {
|
|
142
|
+
stderr: 'ignore',
|
|
143
|
+
});
|
|
144
|
+
await del.exited;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Store auth data in macOS Keychain
|
|
149
|
+
*/
|
|
150
|
+
export async function saveAuthToKeychain(
|
|
151
|
+
profileName: string,
|
|
152
|
+
authData: { api_key: string; user_id: string; expires: number }
|
|
153
|
+
): Promise<void> {
|
|
154
|
+
const service = `${SERVICE_PREFIX}.${profileName}`;
|
|
155
|
+
await saveEncryptedValueToKeychain(service, AUTH_ACCOUNT, JSON.stringify(authData));
|
|
156
|
+
}
|
|
157
|
+
|
|
130
158
|
/**
|
|
131
159
|
* Retrieve auth data from macOS Keychain
|
|
132
160
|
*/
|
|
@@ -134,28 +162,12 @@ export async function getAuthFromKeychain(
|
|
|
134
162
|
profileName: string
|
|
135
163
|
): Promise<{ api_key: string; user_id: string; expires: number } | null> {
|
|
136
164
|
const service = `${SERVICE_PREFIX}.${profileName}`;
|
|
137
|
-
const account = 'auth-token';
|
|
138
165
|
|
|
139
166
|
try {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
['security', 'find-generic-password', '-s', service, '-a', account, '-w'],
|
|
143
|
-
{ stderr: 'ignore' }
|
|
144
|
-
);
|
|
145
|
-
|
|
146
|
-
const stdout = await new Response(find.stdout).text();
|
|
147
|
-
if (stdout.length === 0) {
|
|
167
|
+
const json = await getEncryptedValueFromKeychain(service, AUTH_ACCOUNT);
|
|
168
|
+
if (!json) {
|
|
148
169
|
return null;
|
|
149
170
|
}
|
|
150
|
-
|
|
151
|
-
const b64 = stdout.trim();
|
|
152
|
-
const encrypted = Uint8Array.from(Buffer.from(b64, 'base64'));
|
|
153
|
-
|
|
154
|
-
// Get the encryption key
|
|
155
|
-
const key = await ensureEncryptionKey(service);
|
|
156
|
-
|
|
157
|
-
// Decrypt the auth data
|
|
158
|
-
const json = await decrypt(encrypted, key);
|
|
159
171
|
return JSON.parse(json);
|
|
160
172
|
} catch {
|
|
161
173
|
return null;
|
|
@@ -167,10 +179,27 @@ export async function getAuthFromKeychain(
|
|
|
167
179
|
*/
|
|
168
180
|
export async function deleteAuthFromKeychain(profileName: string): Promise<void> {
|
|
169
181
|
const service = `${SERVICE_PREFIX}.${profileName}`;
|
|
170
|
-
|
|
182
|
+
await deleteValueFromKeychain(service, AUTH_ACCOUNT);
|
|
183
|
+
}
|
|
171
184
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
185
|
+
export async function saveCoderApiKeyToKeychain(
|
|
186
|
+
profileName: string,
|
|
187
|
+
apiKey: string
|
|
188
|
+
): Promise<void> {
|
|
189
|
+
const service = `${SERVICE_PREFIX}.${profileName}`;
|
|
190
|
+
await saveEncryptedValueToKeychain(service, CODER_API_KEY_ACCOUNT, apiKey);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
export async function getCoderApiKeyFromKeychain(profileName: string): Promise<string | null> {
|
|
194
|
+
const service = `${SERVICE_PREFIX}.${profileName}`;
|
|
195
|
+
try {
|
|
196
|
+
return await getEncryptedValueFromKeychain(service, CODER_API_KEY_ACCOUNT);
|
|
197
|
+
} catch {
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export async function deleteCoderApiKeyFromKeychain(profileName: string): Promise<void> {
|
|
203
|
+
const service = `${SERVICE_PREFIX}.${profileName}`;
|
|
204
|
+
await deleteValueFromKeychain(service, CODER_API_KEY_ACCOUNT);
|
|
176
205
|
}
|
package/src/types.ts
CHANGED
|
@@ -61,6 +61,16 @@ 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'),
|
|
64
74
|
gravity: zod
|
|
65
75
|
.object({
|
|
66
76
|
version: zod.string().optional().describe('The current gravity version'),
|