ai-cred 1.0.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.
- package/dist/cli/commands/add.d.ts +8 -0
- package/dist/cli/commands/add.js +145 -0
- package/dist/cli/commands/add.js.map +1 -0
- package/dist/cli/commands/get.d.ts +7 -0
- package/dist/cli/commands/get.js +53 -0
- package/dist/cli/commands/get.js.map +1 -0
- package/dist/cli/commands/list.d.ts +7 -0
- package/dist/cli/commands/list.js +118 -0
- package/dist/cli/commands/list.js.map +1 -0
- package/dist/cli/commands/remove.d.ts +7 -0
- package/dist/cli/commands/remove.js +53 -0
- package/dist/cli/commands/remove.js.map +1 -0
- package/dist/cli/commands/update.d.ts +8 -0
- package/dist/cli/commands/update.js +140 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.js +25 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/utils/display.d.ts +14 -0
- package/dist/cli/utils/display.js +31 -0
- package/dist/cli/utils/display.js.map +1 -0
- package/dist/cli/utils/prompt.d.ts +6 -0
- package/dist/cli/utils/prompt.js +66 -0
- package/dist/cli/utils/prompt.js.map +1 -0
- package/dist/core/audit-logger.d.ts +25 -0
- package/dist/core/audit-logger.js +41 -0
- package/dist/core/audit-logger.js.map +1 -0
- package/dist/core/audit-logger.test.d.ts +1 -0
- package/dist/core/audit-logger.test.js +89 -0
- package/dist/core/audit-logger.test.js.map +1 -0
- package/dist/core/errors.d.ts +23 -0
- package/dist/core/errors.js +78 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/keychain-adapter.d.ts +65 -0
- package/dist/core/keychain-adapter.js +221 -0
- package/dist/core/keychain-adapter.js.map +1 -0
- package/dist/core/keychain-adapter.test.d.ts +1 -0
- package/dist/core/keychain-adapter.test.js +331 -0
- package/dist/core/keychain-adapter.test.js.map +1 -0
- package/dist/e2e/environment-isolation.test.d.ts +1 -0
- package/dist/e2e/environment-isolation.test.js +112 -0
- package/dist/e2e/environment-isolation.test.js.map +1 -0
- package/dist/server/index.d.ts +7 -0
- package/dist/server/index.js +26 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/tools.d.ts +10 -0
- package/dist/server/tools.js +230 -0
- package/dist/server/tools.js.map +1 -0
- package/dist/server/tools.test.d.ts +7 -0
- package/dist/server/tools.test.js +606 -0
- package/dist/server/tools.test.js.map +1 -0
- package/dist/types/credential.d.ts +77 -0
- package/dist/types/credential.js +46 -0
- package/dist/types/credential.js.map +1 -0
- package/dist/types/credential.test.d.ts +1 -0
- package/dist/types/credential.test.js +316 -0
- package/dist/types/credential.test.js.map +1 -0
- package/dist/utils/validation.d.ts +15 -0
- package/dist/utils/validation.js +34 -0
- package/dist/utils/validation.js.map +1 -0
- package/dist/utils/validation.test.d.ts +1 -0
- package/dist/utils/validation.test.js +139 -0
- package/dist/utils/validation.test.js.map +1 -0
- package/package.json +35 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI subcommand: ai-cred add <service>
|
|
3
|
+
*
|
|
4
|
+
* Stores a new credential in the macOS Keychain.
|
|
5
|
+
* Prompts interactively for secret fields not provided via flags.
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from 'commander';
|
|
8
|
+
import { KeychainAdapter, KeychainError } from '../../core/keychain-adapter.js';
|
|
9
|
+
import { CredentialSchema, EnvironmentSchema } from '../../types/credential.js';
|
|
10
|
+
import { ServiceNameSchema } from '../../utils/validation.js';
|
|
11
|
+
import { promptSecret } from '../utils/prompt.js';
|
|
12
|
+
import { auditLog } from '../../core/audit-logger.js';
|
|
13
|
+
async function withAdapter() {
|
|
14
|
+
const adapter = new KeychainAdapter();
|
|
15
|
+
await adapter.initialize();
|
|
16
|
+
return adapter;
|
|
17
|
+
}
|
|
18
|
+
export function makeAddCommand() {
|
|
19
|
+
return new Command('add')
|
|
20
|
+
.description('Store a new credential')
|
|
21
|
+
.argument('<service>', 'Service name')
|
|
22
|
+
.requiredOption('-t, --type <type>', 'Credential type (ssh|jenkins|portainer|aws|api-key)')
|
|
23
|
+
.option('-e, --env <environment>', 'Environment', 'global')
|
|
24
|
+
.option('--notes <text>', 'Optional notes')
|
|
25
|
+
// SSH options
|
|
26
|
+
.option('--host <host>', 'SSH host')
|
|
27
|
+
.option('--port <port>', 'SSH port')
|
|
28
|
+
.option('--username <user>', 'Username')
|
|
29
|
+
.option('--password <pass>', 'Password')
|
|
30
|
+
.option('--key-path <path>', 'SSH key path')
|
|
31
|
+
// Jenkins/Portainer options
|
|
32
|
+
.option('--url <url>', 'Service URL')
|
|
33
|
+
.option('--api-token <token>', 'API token')
|
|
34
|
+
// AWS options
|
|
35
|
+
.option('--access-key-id <id>', 'AWS access key ID')
|
|
36
|
+
.option('--secret-access-key <key>', 'AWS secret access key')
|
|
37
|
+
.option('--region <region>', 'AWS region')
|
|
38
|
+
.option('--profile <name>', 'AWS profile name')
|
|
39
|
+
// API key options
|
|
40
|
+
.option('--key <key>', 'API key value')
|
|
41
|
+
.action(async (service, opts) => {
|
|
42
|
+
// Validate service name
|
|
43
|
+
const svcResult = ServiceNameSchema.safeParse(service);
|
|
44
|
+
if (!svcResult.success) {
|
|
45
|
+
process.stderr.write(`Error: ${svcResult.error.issues[0]?.message ?? 'Invalid service name'}\n`);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
// Validate environment
|
|
49
|
+
const envResult = EnvironmentSchema.safeParse(opts.env);
|
|
50
|
+
if (!envResult.success) {
|
|
51
|
+
process.stderr.write(`Error: ${envResult.error.issues[0]?.message ?? 'Invalid environment'}\n`);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
const env = envResult.data;
|
|
55
|
+
// Build credential object based on type
|
|
56
|
+
const credential = await buildCredential(opts);
|
|
57
|
+
if (!credential)
|
|
58
|
+
return; // buildCredential handles errors
|
|
59
|
+
// Validate through Zod schema
|
|
60
|
+
const credResult = CredentialSchema.safeParse(credential);
|
|
61
|
+
if (!credResult.success) {
|
|
62
|
+
const issues = credResult.error.issues.map((i) => i.message).join(', ');
|
|
63
|
+
process.stderr.write(`Validation error: ${issues}\n`);
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
const adapter = await withAdapter();
|
|
68
|
+
await adapter.store(env, service, credResult.data);
|
|
69
|
+
await auditLog({ operation: 'store', service, environment: env });
|
|
70
|
+
console.log(`Stored credential '${service}' in ${env}`);
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
if (err instanceof KeychainError) {
|
|
74
|
+
process.stderr.write(`Error: ${err.message}\n`);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
process.stderr.write(`Error: Failed to store credential\n`);
|
|
78
|
+
}
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
async function buildCredential(opts) {
|
|
84
|
+
const type = opts.type;
|
|
85
|
+
const notes = opts.notes;
|
|
86
|
+
switch (type) {
|
|
87
|
+
case 'ssh': {
|
|
88
|
+
const password = opts.password ?? (await promptSecret('Password (or press Enter to skip): ') || undefined);
|
|
89
|
+
const cred = {
|
|
90
|
+
type: 'ssh',
|
|
91
|
+
host: opts.host ?? '',
|
|
92
|
+
port: opts.port ? parseInt(opts.port, 10) : 22,
|
|
93
|
+
username: opts.username ?? '',
|
|
94
|
+
...(password && { password }),
|
|
95
|
+
...(opts.keyPath && { keyPath: opts.keyPath }),
|
|
96
|
+
...(notes && { notes }),
|
|
97
|
+
};
|
|
98
|
+
return cred;
|
|
99
|
+
}
|
|
100
|
+
case 'jenkins': {
|
|
101
|
+
const apiToken = opts.apiToken ?? await promptSecret('API Token: ');
|
|
102
|
+
return {
|
|
103
|
+
type: 'jenkins',
|
|
104
|
+
url: opts.url ?? '',
|
|
105
|
+
username: opts.username ?? '',
|
|
106
|
+
apiToken,
|
|
107
|
+
...(notes && { notes }),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
case 'portainer': {
|
|
111
|
+
const apiToken = opts.apiToken ?? await promptSecret('API Token: ');
|
|
112
|
+
return {
|
|
113
|
+
type: 'portainer',
|
|
114
|
+
url: opts.url ?? '',
|
|
115
|
+
apiToken,
|
|
116
|
+
...(notes && { notes }),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
case 'aws': {
|
|
120
|
+
const secretAccessKey = opts.secretAccessKey ?? await promptSecret('Secret Access Key: ');
|
|
121
|
+
return {
|
|
122
|
+
type: 'aws',
|
|
123
|
+
accessKeyId: opts.accessKeyId ?? '',
|
|
124
|
+
secretAccessKey,
|
|
125
|
+
region: opts.region ?? '',
|
|
126
|
+
...(opts.profile && { profile: opts.profile }),
|
|
127
|
+
...(notes && { notes }),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
case 'api-key': {
|
|
131
|
+
const key = opts.key ?? await promptSecret('API Key: ');
|
|
132
|
+
return {
|
|
133
|
+
type: 'api-key',
|
|
134
|
+
key,
|
|
135
|
+
...(opts.url && { url: opts.url }),
|
|
136
|
+
...(notes && { notes }),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
default:
|
|
140
|
+
process.stderr.write(`Error: Unknown credential type '${type}'. Must be ssh|jenkins|portainer|aws|api-key.\n`);
|
|
141
|
+
process.exit(1);
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=add.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add.js","sourceRoot":"","sources":["../../../src/cli/commands/add.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI subcommand: ai-cred get <service>
|
|
3
|
+
*
|
|
4
|
+
* Retrieves and prints a credential as JSON.
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from 'commander';
|
|
7
|
+
import { KeychainAdapter, KeychainError } from '../../core/keychain-adapter.js';
|
|
8
|
+
import { EnvironmentSchema } from '../../types/credential.js';
|
|
9
|
+
import { ServiceNameSchema } from '../../utils/validation.js';
|
|
10
|
+
import { auditLog } from '../../core/audit-logger.js';
|
|
11
|
+
async function withAdapter() {
|
|
12
|
+
const adapter = new KeychainAdapter();
|
|
13
|
+
await adapter.initialize();
|
|
14
|
+
return adapter;
|
|
15
|
+
}
|
|
16
|
+
export function makeGetCommand() {
|
|
17
|
+
return new Command('get')
|
|
18
|
+
.description('Retrieve a credential')
|
|
19
|
+
.argument('<service>', 'Service name')
|
|
20
|
+
.option('-e, --env <environment>', 'Environment', 'global')
|
|
21
|
+
.action(async (service, opts) => {
|
|
22
|
+
const svcResult = ServiceNameSchema.safeParse(service);
|
|
23
|
+
if (!svcResult.success) {
|
|
24
|
+
process.stderr.write(`Error: ${svcResult.error.issues[0]?.message ?? 'Invalid service name'}\n`);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
const envResult = EnvironmentSchema.safeParse(opts.env);
|
|
28
|
+
if (!envResult.success) {
|
|
29
|
+
process.stderr.write(`Error: ${envResult.error.issues[0]?.message ?? 'Invalid environment'}\n`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
const env = envResult.data;
|
|
33
|
+
try {
|
|
34
|
+
const adapter = await withAdapter();
|
|
35
|
+
const credential = await adapter.get(env, service);
|
|
36
|
+
await auditLog({ operation: 'get', service, environment: env });
|
|
37
|
+
console.log(JSON.stringify(credential, null, 2));
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
if (err instanceof KeychainError && err.exitCode === 44) {
|
|
41
|
+
process.stderr.write(`No credential found for '${service}' in ${env}\n`);
|
|
42
|
+
}
|
|
43
|
+
else if (err instanceof KeychainError) {
|
|
44
|
+
process.stderr.write(`Error: ${err.message}\n`);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
process.stderr.write(`Error: Failed to retrieve credential\n`);
|
|
48
|
+
}
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=get.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get.js","sourceRoot":"","sources":["../../../src/cli/commands/get.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAEtD,KAAK,UAAU,WAAW;IACxB,MAAM,OAAO,GAAG,IAAI,eAAe,EAAE,CAAC;IACtC,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;IAC3B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC;SACtB,WAAW,CAAC,uBAAuB,CAAC;SACpC,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAC;SACrC,MAAM,CAAC,yBAAyB,EAAE,aAAa,EAAE,QAAQ,CAAC;SAC1D,MAAM,CAAC,KAAK,EAAE,OAAe,EAAE,IAAqB,EAAE,EAAE;QACvD,MAAM,SAAS,GAAG,iBAAiB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACvD,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;YACvB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,sBAAsB,IAAI,CAAC,CAAC;YACjG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,SAAS,GAAG,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxD,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;YACvB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,qBAAqB,IAAI,CAAC,CAAC;YAChG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC;QAE3B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,WAAW,EAAE,CAAC;YACpC,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YACnD,MAAM,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC;YAChE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACnD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,aAAa,IAAI,GAAG,CAAC,QAAQ,KAAK,EAAE,EAAE,CAAC;gBACxD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4B,OAAO,QAAQ,GAAG,IAAI,CAAC,CAAC;YAC3E,CAAC;iBAAM,IAAI,GAAG,YAAY,aAAa,EAAE,CAAC;gBACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;YAClD,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;YACjE,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI subcommand: ai-cred list
|
|
3
|
+
*
|
|
4
|
+
* Lists all credentials with masked secret preview in a formatted table.
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from 'commander';
|
|
7
|
+
import { KeychainAdapter, KeychainError } from '../../core/keychain-adapter.js';
|
|
8
|
+
import { EnvironmentSchema } from '../../types/credential.js';
|
|
9
|
+
import { maskSecret, getPrimarySecret } from '../utils/display.js';
|
|
10
|
+
async function withAdapter() {
|
|
11
|
+
const adapter = new KeychainAdapter();
|
|
12
|
+
await adapter.initialize();
|
|
13
|
+
return adapter;
|
|
14
|
+
}
|
|
15
|
+
export function makeListCommand() {
|
|
16
|
+
return new Command('list')
|
|
17
|
+
.description('List all credentials')
|
|
18
|
+
.option('-e, --env <environment>', 'Filter by environment')
|
|
19
|
+
.action(async (opts) => {
|
|
20
|
+
// Validate environment filter if provided
|
|
21
|
+
let envFilter;
|
|
22
|
+
if (opts.env) {
|
|
23
|
+
const envResult = EnvironmentSchema.safeParse(opts.env);
|
|
24
|
+
if (!envResult.success) {
|
|
25
|
+
process.stderr.write(`Error: ${envResult.error.issues[0]?.message ?? 'Invalid environment'}\n`);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
envFilter = envResult.data;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const adapter = await withAdapter();
|
|
32
|
+
let items = await adapter.list();
|
|
33
|
+
if (envFilter) {
|
|
34
|
+
items = items.filter((item) => item.environment === envFilter);
|
|
35
|
+
}
|
|
36
|
+
if (items.length === 0) {
|
|
37
|
+
console.log('No credentials found.');
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
// Fetch full credentials for masked secret preview (N+1 acceptable for <100 items)
|
|
41
|
+
const rows = [];
|
|
42
|
+
for (const item of items) {
|
|
43
|
+
try {
|
|
44
|
+
const credential = await adapter.get(item.environment, item.service);
|
|
45
|
+
const primarySecret = getPrimarySecret(credential);
|
|
46
|
+
const masked = maskSecret(primarySecret);
|
|
47
|
+
const notes = ('notes' in credential && typeof credential.notes === 'string')
|
|
48
|
+
? (credential.notes.length > 30 ? credential.notes.slice(0, 27) + '...' : credential.notes)
|
|
49
|
+
: '';
|
|
50
|
+
rows.push({
|
|
51
|
+
service: item.service,
|
|
52
|
+
environment: item.environment,
|
|
53
|
+
type: item.type,
|
|
54
|
+
secret: masked,
|
|
55
|
+
notes,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// If we can't fetch a credential, show what we have
|
|
60
|
+
rows.push({
|
|
61
|
+
service: item.service,
|
|
62
|
+
environment: item.environment,
|
|
63
|
+
type: item.type,
|
|
64
|
+
secret: '(error)',
|
|
65
|
+
notes: '',
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// Calculate column widths
|
|
70
|
+
const headers = { service: 'Service', environment: 'Environment', type: 'Type', secret: 'Secret', notes: 'Notes' };
|
|
71
|
+
const colWidths = {
|
|
72
|
+
service: Math.max(headers.service.length, ...rows.map((r) => r.service.length)),
|
|
73
|
+
environment: Math.max(headers.environment.length, ...rows.map((r) => r.environment.length)),
|
|
74
|
+
type: Math.max(headers.type.length, ...rows.map((r) => r.type.length)),
|
|
75
|
+
secret: Math.max(headers.secret.length, ...rows.map((r) => r.secret.length)),
|
|
76
|
+
notes: Math.max(headers.notes.length, ...rows.map((r) => r.notes.length)),
|
|
77
|
+
};
|
|
78
|
+
// Print header
|
|
79
|
+
const headerLine = [
|
|
80
|
+
headers.service.padEnd(colWidths.service),
|
|
81
|
+
headers.environment.padEnd(colWidths.environment),
|
|
82
|
+
headers.type.padEnd(colWidths.type),
|
|
83
|
+
headers.secret.padEnd(colWidths.secret),
|
|
84
|
+
headers.notes.padEnd(colWidths.notes),
|
|
85
|
+
].join(' ');
|
|
86
|
+
console.log(headerLine);
|
|
87
|
+
const separator = [
|
|
88
|
+
'-'.repeat(colWidths.service),
|
|
89
|
+
'-'.repeat(colWidths.environment),
|
|
90
|
+
'-'.repeat(colWidths.type),
|
|
91
|
+
'-'.repeat(colWidths.secret),
|
|
92
|
+
'-'.repeat(colWidths.notes),
|
|
93
|
+
].join(' ');
|
|
94
|
+
console.log(separator);
|
|
95
|
+
// Print rows
|
|
96
|
+
for (const row of rows) {
|
|
97
|
+
const line = [
|
|
98
|
+
row.service.padEnd(colWidths.service),
|
|
99
|
+
row.environment.padEnd(colWidths.environment),
|
|
100
|
+
row.type.padEnd(colWidths.type),
|
|
101
|
+
row.secret.padEnd(colWidths.secret),
|
|
102
|
+
row.notes.padEnd(colWidths.notes),
|
|
103
|
+
].join(' ');
|
|
104
|
+
console.log(line);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
if (err instanceof KeychainError) {
|
|
109
|
+
process.stderr.write(`Error: ${err.message}\n`);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
process.stderr.write(`Error: Failed to list credentials\n`);
|
|
113
|
+
}
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/cli/commands/list.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAEhF,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEnE,KAAK,UAAU,WAAW;IACxB,MAAM,OAAO,GAAG,IAAI,eAAe,EAAE,CAAC;IACtC,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;IAC3B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;SACvB,WAAW,CAAC,sBAAsB,CAAC;SACnC,MAAM,CAAC,yBAAyB,EAAE,uBAAuB,CAAC;SAC1D,MAAM,CAAC,KAAK,EAAE,IAAsB,EAAE,EAAE;QACvC,0CAA0C;QAC1C,IAAI,SAAkC,CAAC;QACvC,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACb,MAAM,SAAS,GAAG,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACxD,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;gBACvB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,qBAAqB,IAAI,CAAC,CAAC;gBAChG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC;QAC7B,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,WAAW,EAAE,CAAC;YACpC,IAAI,KAAK,GAAyB,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;YAEvD,IAAI,SAAS,EAAE,CAAC;gBACd,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC;YACjE,CAAC;YAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;gBACrC,OAAO;YACT,CAAC;YAED,mFAAmF;YACnF,MAAM,IAAI,GAA4F,EAAE,CAAC;YAEzG,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,CAAC;oBACH,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;oBACrE,MAAM,aAAa,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAC;oBACnD,MAAM,MAAM,GAAG,UAAU,CAAC,aAAa,CAAC,CAAC;oBACzC,MAAM,KAAK,GAAG,CAAC,OAAO,IAAI,UAAU,IAAI,OAAO,UAAU,CAAC,KAAK,KAAK,QAAQ,CAAC;wBAC3E,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC;wBAC3F,CAAC,CAAC,EAAE,CAAC;oBACP,IAAI,CAAC,IAAI,CAAC;wBACR,OAAO,EAAE,IAAI,CAAC,OAAO;wBACrB,WAAW,EAAE,IAAI,CAAC,WAAW;wBAC7B,IAAI,EAAE,IAAI,CAAC,IAAI;wBACf,MAAM,EAAE,MAAM;wBACd,KAAK;qBACN,CAAC,CAAC;gBACL,CAAC;gBAAC,MAAM,CAAC;oBACP,oDAAoD;oBACpD,IAAI,CAAC,IAAI,CAAC;wBACR,OAAO,EAAE,IAAI,CAAC,OAAO;wBACrB,WAAW,EAAE,IAAI,CAAC,WAAW;wBAC7B,IAAI,EAAE,IAAI,CAAC,IAAI;wBACf,MAAM,EAAE,SAAS;wBACjB,KAAK,EAAE,EAAE;qBACV,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAED,0BAA0B;YAC1B,MAAM,OAAO,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;YACnH,MAAM,SAAS,GAAG;gBAChB,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBAC/E,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;gBAC3F,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACtE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC5E,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;aAC1E,CAAC;YAEF,eAAe;YACf,MAAM,UAAU,GAAG;gBACjB,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC;gBACzC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC;gBACjD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC;gBACnC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC;gBACvC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC;aACtC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAExB,MAAM,SAAS,GAAG;gBAChB,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC;gBAC7B,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC;gBACjC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC;gBAC1B,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC;gBAC5B,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC;aAC5B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAEvB,aAAa;YACb,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,MAAM,IAAI,GAAG;oBACX,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC;oBACrC,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC;oBAC7C,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC;oBAC/B,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC;oBACnC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC;iBAClC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACb,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACpB,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,aAAa,EAAE,CAAC;gBACjC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;YAClD,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;YAC9D,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI subcommand: ai-cred remove <service>
|
|
3
|
+
*
|
|
4
|
+
* Deletes a credential from the macOS Keychain.
|
|
5
|
+
*/
|
|
6
|
+
import { Command } from 'commander';
|
|
7
|
+
import { KeychainAdapter, KeychainError } from '../../core/keychain-adapter.js';
|
|
8
|
+
import { EnvironmentSchema } from '../../types/credential.js';
|
|
9
|
+
import { ServiceNameSchema } from '../../utils/validation.js';
|
|
10
|
+
import { auditLog } from '../../core/audit-logger.js';
|
|
11
|
+
async function withAdapter() {
|
|
12
|
+
const adapter = new KeychainAdapter();
|
|
13
|
+
await adapter.initialize();
|
|
14
|
+
return adapter;
|
|
15
|
+
}
|
|
16
|
+
export function makeRemoveCommand() {
|
|
17
|
+
return new Command('remove')
|
|
18
|
+
.description('Delete a credential')
|
|
19
|
+
.argument('<service>', 'Service name')
|
|
20
|
+
.option('-e, --env <environment>', 'Environment', 'global')
|
|
21
|
+
.action(async (service, opts) => {
|
|
22
|
+
const svcResult = ServiceNameSchema.safeParse(service);
|
|
23
|
+
if (!svcResult.success) {
|
|
24
|
+
process.stderr.write(`Error: ${svcResult.error.issues[0]?.message ?? 'Invalid service name'}\n`);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
const envResult = EnvironmentSchema.safeParse(opts.env);
|
|
28
|
+
if (!envResult.success) {
|
|
29
|
+
process.stderr.write(`Error: ${envResult.error.issues[0]?.message ?? 'Invalid environment'}\n`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
const env = envResult.data;
|
|
33
|
+
try {
|
|
34
|
+
const adapter = await withAdapter();
|
|
35
|
+
await adapter.delete(env, service);
|
|
36
|
+
await auditLog({ operation: 'delete', service, environment: env });
|
|
37
|
+
console.log(`Removed credential '${service}' from ${env}`);
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
if (err instanceof KeychainError && err.exitCode === 44) {
|
|
41
|
+
process.stderr.write(`No credential found for '${service}' in ${env}\n`);
|
|
42
|
+
}
|
|
43
|
+
else if (err instanceof KeychainError) {
|
|
44
|
+
process.stderr.write(`Error: ${err.message}\n`);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
process.stderr.write(`Error: Failed to remove credential\n`);
|
|
48
|
+
}
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=remove.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remove.js","sourceRoot":"","sources":["../../../src/cli/commands/remove.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAEtD,KAAK,UAAU,WAAW;IACxB,MAAM,OAAO,GAAG,IAAI,eAAe,EAAE,CAAC;IACtC,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;IAC3B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC;SACzB,WAAW,CAAC,qBAAqB,CAAC;SAClC,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAC;SACrC,MAAM,CAAC,yBAAyB,EAAE,aAAa,EAAE,QAAQ,CAAC;SAC1D,MAAM,CAAC,KAAK,EAAE,OAAe,EAAE,IAAqB,EAAE,EAAE;QACvD,MAAM,SAAS,GAAG,iBAAiB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACvD,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;YACvB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,sBAAsB,IAAI,CAAC,CAAC;YACjG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,SAAS,GAAG,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxD,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;YACvB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,qBAAqB,IAAI,CAAC,CAAC;YAChG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC;QAE3B,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,WAAW,EAAE,CAAC;YACpC,MAAM,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YACnC,MAAM,QAAQ,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC;YACnE,OAAO,CAAC,GAAG,CAAC,uBAAuB,OAAO,UAAU,GAAG,EAAE,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,aAAa,IAAI,GAAG,CAAC,QAAQ,KAAK,EAAE,EAAE,CAAC;gBACxD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4B,OAAO,QAAQ,GAAG,IAAI,CAAC,CAAC;YAC3E,CAAC;iBAAM,IAAI,GAAG,YAAY,aAAa,EAAE,CAAC;gBACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;YAClD,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;YAC/D,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI subcommand: ai-cred update <service>
|
|
3
|
+
*
|
|
4
|
+
* Replaces a credential via upsert (-U flag on add-generic-password).
|
|
5
|
+
* Full replacement: all fields must be provided.
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from 'commander';
|
|
8
|
+
export declare function makeUpdateCommand(): Command;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI subcommand: ai-cred update <service>
|
|
3
|
+
*
|
|
4
|
+
* Replaces a credential via upsert (-U flag on add-generic-password).
|
|
5
|
+
* Full replacement: all fields must be provided.
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from 'commander';
|
|
8
|
+
import { KeychainAdapter, KeychainError } from '../../core/keychain-adapter.js';
|
|
9
|
+
import { CredentialSchema, EnvironmentSchema } from '../../types/credential.js';
|
|
10
|
+
import { ServiceNameSchema } from '../../utils/validation.js';
|
|
11
|
+
import { promptSecret } from '../utils/prompt.js';
|
|
12
|
+
import { auditLog } from '../../core/audit-logger.js';
|
|
13
|
+
async function withAdapter() {
|
|
14
|
+
const adapter = new KeychainAdapter();
|
|
15
|
+
await adapter.initialize();
|
|
16
|
+
return adapter;
|
|
17
|
+
}
|
|
18
|
+
export function makeUpdateCommand() {
|
|
19
|
+
return new Command('update')
|
|
20
|
+
.description('Update (replace) a credential')
|
|
21
|
+
.argument('<service>', 'Service name')
|
|
22
|
+
.requiredOption('-t, --type <type>', 'Credential type (ssh|jenkins|portainer|aws|api-key)')
|
|
23
|
+
.option('-e, --env <environment>', 'Environment', 'global')
|
|
24
|
+
.option('--notes <text>', 'Optional notes')
|
|
25
|
+
// SSH options
|
|
26
|
+
.option('--host <host>', 'SSH host')
|
|
27
|
+
.option('--port <port>', 'SSH port')
|
|
28
|
+
.option('--username <user>', 'Username')
|
|
29
|
+
.option('--password <pass>', 'Password')
|
|
30
|
+
.option('--key-path <path>', 'SSH key path')
|
|
31
|
+
// Jenkins/Portainer options
|
|
32
|
+
.option('--url <url>', 'Service URL')
|
|
33
|
+
.option('--api-token <token>', 'API token')
|
|
34
|
+
// AWS options
|
|
35
|
+
.option('--access-key-id <id>', 'AWS access key ID')
|
|
36
|
+
.option('--secret-access-key <key>', 'AWS secret access key')
|
|
37
|
+
.option('--region <region>', 'AWS region')
|
|
38
|
+
.option('--profile <name>', 'AWS profile name')
|
|
39
|
+
// API key options
|
|
40
|
+
.option('--key <key>', 'API key value')
|
|
41
|
+
.action(async (service, opts) => {
|
|
42
|
+
const svcResult = ServiceNameSchema.safeParse(service);
|
|
43
|
+
if (!svcResult.success) {
|
|
44
|
+
process.stderr.write(`Error: ${svcResult.error.issues[0]?.message ?? 'Invalid service name'}\n`);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
const envResult = EnvironmentSchema.safeParse(opts.env);
|
|
48
|
+
if (!envResult.success) {
|
|
49
|
+
process.stderr.write(`Error: ${envResult.error.issues[0]?.message ?? 'Invalid environment'}\n`);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
const env = envResult.data;
|
|
53
|
+
const credential = await buildCredential(opts);
|
|
54
|
+
if (!credential)
|
|
55
|
+
return;
|
|
56
|
+
const credResult = CredentialSchema.safeParse(credential);
|
|
57
|
+
if (!credResult.success) {
|
|
58
|
+
const issues = credResult.error.issues.map((i) => i.message).join(', ');
|
|
59
|
+
process.stderr.write(`Validation error: ${issues}\n`);
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
const adapter = await withAdapter();
|
|
64
|
+
await adapter.store(env, service, credResult.data);
|
|
65
|
+
await auditLog({ operation: 'update', service, environment: env });
|
|
66
|
+
console.log(`Updated credential '${service}' in ${env}`);
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
if (err instanceof KeychainError) {
|
|
70
|
+
process.stderr.write(`Error: ${err.message}\n`);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
process.stderr.write(`Error: Failed to update credential\n`);
|
|
74
|
+
}
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
async function buildCredential(opts) {
|
|
80
|
+
const type = opts.type;
|
|
81
|
+
const notes = opts.notes;
|
|
82
|
+
switch (type) {
|
|
83
|
+
case 'ssh': {
|
|
84
|
+
const password = opts.password ?? (await promptSecret('Password (or press Enter to skip): ') || undefined);
|
|
85
|
+
return {
|
|
86
|
+
type: 'ssh',
|
|
87
|
+
host: opts.host ?? '',
|
|
88
|
+
port: opts.port ? parseInt(opts.port, 10) : 22,
|
|
89
|
+
username: opts.username ?? '',
|
|
90
|
+
...(password && { password }),
|
|
91
|
+
...(opts.keyPath && { keyPath: opts.keyPath }),
|
|
92
|
+
...(notes && { notes }),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
case 'jenkins': {
|
|
96
|
+
const apiToken = opts.apiToken ?? await promptSecret('API Token: ');
|
|
97
|
+
return {
|
|
98
|
+
type: 'jenkins',
|
|
99
|
+
url: opts.url ?? '',
|
|
100
|
+
username: opts.username ?? '',
|
|
101
|
+
apiToken,
|
|
102
|
+
...(notes && { notes }),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
case 'portainer': {
|
|
106
|
+
const apiToken = opts.apiToken ?? await promptSecret('API Token: ');
|
|
107
|
+
return {
|
|
108
|
+
type: 'portainer',
|
|
109
|
+
url: opts.url ?? '',
|
|
110
|
+
apiToken,
|
|
111
|
+
...(notes && { notes }),
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
case 'aws': {
|
|
115
|
+
const secretAccessKey = opts.secretAccessKey ?? await promptSecret('Secret Access Key: ');
|
|
116
|
+
return {
|
|
117
|
+
type: 'aws',
|
|
118
|
+
accessKeyId: opts.accessKeyId ?? '',
|
|
119
|
+
secretAccessKey,
|
|
120
|
+
region: opts.region ?? '',
|
|
121
|
+
...(opts.profile && { profile: opts.profile }),
|
|
122
|
+
...(notes && { notes }),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
case 'api-key': {
|
|
126
|
+
const key = opts.key ?? await promptSecret('API Key: ');
|
|
127
|
+
return {
|
|
128
|
+
type: 'api-key',
|
|
129
|
+
key,
|
|
130
|
+
...(opts.url && { url: opts.url }),
|
|
131
|
+
...(notes && { notes }),
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
default:
|
|
135
|
+
process.stderr.write(`Error: Unknown credential type '${type}'. Must be ssh|jenkins|portainer|aws|api-key.\n`);
|
|
136
|
+
process.exit(1);
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/cli/commands/update.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAChF,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAChF,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAEtD,KAAK,UAAU,WAAW;IACxB,MAAM,OAAO,GAAG,IAAI,eAAe,EAAE,CAAC;IACtC,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;IAC3B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC;SACzB,WAAW,CAAC,+BAA+B,CAAC;SAC5C,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAC;SACrC,cAAc,CAAC,mBAAmB,EAAE,qDAAqD,CAAC;SAC1F,MAAM,CAAC,yBAAyB,EAAE,aAAa,EAAE,QAAQ,CAAC;SAC1D,MAAM,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;QAC3C,cAAc;SACb,MAAM,CAAC,eAAe,EAAE,UAAU,CAAC;SACnC,MAAM,CAAC,eAAe,EAAE,UAAU,CAAC;SACnC,MAAM,CAAC,mBAAmB,EAAE,UAAU,CAAC;SACvC,MAAM,CAAC,mBAAmB,EAAE,UAAU,CAAC;SACvC,MAAM,CAAC,mBAAmB,EAAE,cAAc,CAAC;QAC5C,4BAA4B;SAC3B,MAAM,CAAC,aAAa,EAAE,aAAa,CAAC;SACpC,MAAM,CAAC,qBAAqB,EAAE,WAAW,CAAC;QAC3C,cAAc;SACb,MAAM,CAAC,sBAAsB,EAAE,mBAAmB,CAAC;SACnD,MAAM,CAAC,2BAA2B,EAAE,uBAAuB,CAAC;SAC5D,MAAM,CAAC,mBAAmB,EAAE,YAAY,CAAC;SACzC,MAAM,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;QAC/C,kBAAkB;SACjB,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC;SACtC,MAAM,CAAC,KAAK,EAAE,OAAe,EAAE,IAAwC,EAAE,EAAE;QAC1E,MAAM,SAAS,GAAG,iBAAiB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACvD,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;YACvB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,sBAAsB,IAAI,CAAC,CAAC;YACjG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,SAAS,GAAG,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxD,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;YACvB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,qBAAqB,IAAI,CAAC,CAAC;YAChG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,CAAC;QAE3B,MAAM,UAAU,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,CAAC,UAAU;YAAE,OAAO;QAExB,MAAM,UAAU,GAAG,gBAAgB,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAC1D,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;YACxB,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,MAAM,IAAI,CAAC,CAAC;YACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,WAAW,EAAE,CAAC;YACpC,MAAM,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;YACnD,MAAM,QAAQ,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,CAAC;YACnE,OAAO,CAAC,GAAG,CAAC,uBAAuB,OAAO,QAAQ,GAAG,EAAE,CAAC,CAAC;QAC3D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,aAAa,EAAE,CAAC;gBACjC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;YAClD,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;YAC/D,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC;AAED,KAAK,UAAU,eAAe,CAC5B,IAAwC;IAExC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;IACvB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IAEzB,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM,YAAY,CAAC,qCAAqC,CAAC,IAAI,SAAS,CAAC,CAAC;YAC3G,OAAO;gBACL,IAAI,EAAE,KAAK;gBACX,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;gBACrB,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE;gBAC9C,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,EAAE;gBAC7B,GAAG,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,CAAC;gBAC7B,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;gBAC9C,GAAG,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE,CAAC;aACxB,CAAC;QACJ,CAAC;QACD,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,MAAM,YAAY,CAAC,aAAa,CAAC,CAAC;YACpE,OAAO;gBACL,IAAI,EAAE,SAAS;gBACf,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,EAAE;gBACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,EAAE;gBAC7B,QAAQ;gBACR,GAAG,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE,CAAC;aACxB,CAAC;QACJ,CAAC;QACD,KAAK,WAAW,CAAC,CAAC,CAAC;YACjB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,MAAM,YAAY,CAAC,aAAa,CAAC,CAAC;YACpE,OAAO;gBACL,IAAI,EAAE,WAAW;gBACjB,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,EAAE;gBACnB,QAAQ;gBACR,GAAG,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE,CAAC;aACxB,CAAC;QACJ,CAAC;QACD,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe,IAAI,MAAM,YAAY,CAAC,qBAAqB,CAAC,CAAC;YAC1F,OAAO;gBACL,IAAI,EAAE,KAAK;gBACX,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE;gBACnC,eAAe;gBACf,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,EAAE;gBACzB,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;gBAC9C,GAAG,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE,CAAC;aACxB,CAAC;QACJ,CAAC;QACD,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,MAAM,YAAY,CAAC,WAAW,CAAC,CAAC;YACxD,OAAO;gBACL,IAAI,EAAE,SAAS;gBACf,GAAG;gBACH,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;gBAClC,GAAG,CAAC,KAAK,IAAI,EAAE,KAAK,EAAE,CAAC;aACxB,CAAC;QACJ,CAAC;QACD;YACE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mCAAmC,IAAI,iDAAiD,CAAC,CAAC;YAC/G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAChB,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* ai-cred CLI entry point.
|
|
4
|
+
*
|
|
5
|
+
* Provides terminal-based credential management backed by the macOS Keychain.
|
|
6
|
+
* Development usage: npx tsx src/cli/index.ts <command>
|
|
7
|
+
*/
|
|
8
|
+
import { Command } from 'commander';
|
|
9
|
+
import { makeAddCommand } from './commands/add.js';
|
|
10
|
+
import { makeGetCommand } from './commands/get.js';
|
|
11
|
+
import { makeListCommand } from './commands/list.js';
|
|
12
|
+
import { makeRemoveCommand } from './commands/remove.js';
|
|
13
|
+
import { makeUpdateCommand } from './commands/update.js';
|
|
14
|
+
const program = new Command();
|
|
15
|
+
program
|
|
16
|
+
.name('ai-cred')
|
|
17
|
+
.description('Manage credentials stored in macOS Keychain')
|
|
18
|
+
.version('1.0.0');
|
|
19
|
+
program.addCommand(makeAddCommand());
|
|
20
|
+
program.addCommand(makeGetCommand());
|
|
21
|
+
program.addCommand(makeListCommand());
|
|
22
|
+
program.addCommand(makeRemoveCommand());
|
|
23
|
+
program.addCommand(makeUpdateCommand());
|
|
24
|
+
program.parse();
|
|
25
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAEzD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CAAC,6CAA6C,CAAC;KAC1D,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC,CAAC;AACrC,OAAO,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC,CAAC;AACrC,OAAO,CAAC,UAAU,CAAC,eAAe,EAAE,CAAC,CAAC;AACtC,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;AACxC,OAAO,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;AAExC,OAAO,CAAC,KAAK,EAAE,CAAC"}
|