@synth1s/cloak 1.5.0 → 1.6.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/package.json +1 -1
- package/src/cli.js +4 -4
- package/src/commands/rename.js +20 -1
- package/src/commands/whoami.js +2 -1
- package/src/lib/messages.js +26 -25
- package/src/lib/tip.js +2 -1
package/package.json
CHANGED
package/src/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { program } from 'commander'
|
|
3
|
+
import { program, Option } from 'commander'
|
|
4
4
|
import { readFileSync } from 'fs'
|
|
5
5
|
import { fileURLToPath } from 'url'
|
|
6
6
|
import { dirname, join } from 'path'
|
|
@@ -33,7 +33,7 @@ program
|
|
|
33
33
|
.command('switch <name>')
|
|
34
34
|
.alias('use')
|
|
35
35
|
.description('Wear a different cloak')
|
|
36
|
-
.
|
|
36
|
+
.addOption(new Option('--print-env').hideHelp())
|
|
37
37
|
.action((name, opts) => switchAccount(name, { printEnv: opts.printEnv }))
|
|
38
38
|
|
|
39
39
|
program
|
|
@@ -56,11 +56,11 @@ program
|
|
|
56
56
|
program
|
|
57
57
|
.command('rename <old> <new>')
|
|
58
58
|
.description('Rename a cloak')
|
|
59
|
-
.action(renameAccount)
|
|
59
|
+
.action((oldName, newName) => renameAccount(oldName, newName))
|
|
60
60
|
|
|
61
61
|
program
|
|
62
62
|
.command('init')
|
|
63
|
-
.description('Output shell integration code')
|
|
63
|
+
.description('Output shell integration code (use with eval)')
|
|
64
64
|
.action(initShell)
|
|
65
65
|
|
|
66
66
|
program.parse()
|
package/src/commands/rename.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { renameSync } from 'fs'
|
|
2
|
+
import inquirer from 'inquirer'
|
|
2
3
|
import { profileDir, profileExists, getActiveProfile } from '../lib/paths.js'
|
|
3
4
|
import { validateAccountName } from '../lib/validate.js'
|
|
4
5
|
import * as msg from '../lib/messages.js'
|
|
5
6
|
|
|
6
|
-
export async function renameAccount(oldName, newName) {
|
|
7
|
+
export async function renameAccount(oldName, newName, options = {}) {
|
|
7
8
|
const oldValidation = validateAccountName(oldName)
|
|
8
9
|
if (!oldValidation.valid) {
|
|
9
10
|
console.error(msg.validationError(oldValidation.error))
|
|
@@ -30,6 +31,24 @@ export async function renameAccount(oldName, newName) {
|
|
|
30
31
|
return
|
|
31
32
|
}
|
|
32
33
|
|
|
34
|
+
if (options.confirm === false) {
|
|
35
|
+
console.log(msg.cancelled())
|
|
36
|
+
return
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (options.confirm === undefined) {
|
|
40
|
+
const { confirm } = await inquirer.prompt([{
|
|
41
|
+
type: 'confirm',
|
|
42
|
+
name: 'confirm',
|
|
43
|
+
message: msg.prompts.renameConfirm(oldName, newName),
|
|
44
|
+
default: true,
|
|
45
|
+
}])
|
|
46
|
+
if (!confirm) {
|
|
47
|
+
console.log(msg.cancelled())
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
33
52
|
renameSync(profileDir(oldName), profileDir(newName))
|
|
34
53
|
|
|
35
54
|
if (getActiveProfile() === oldName) {
|
package/src/commands/whoami.js
CHANGED
|
@@ -4,7 +4,8 @@ import * as msg from '../lib/messages.js'
|
|
|
4
4
|
export function whoami() {
|
|
5
5
|
const active = getActiveProfile()
|
|
6
6
|
if (!active) {
|
|
7
|
-
|
|
7
|
+
// stderr for info messages, so piping `cloak whoami` gives clean output
|
|
8
|
+
console.error(msg.noCloak())
|
|
8
9
|
return null
|
|
9
10
|
}
|
|
10
11
|
console.log(active)
|
package/src/lib/messages.js
CHANGED
|
@@ -5,7 +5,6 @@ const icon = {
|
|
|
5
5
|
success: chalk.green('✔'),
|
|
6
6
|
error: chalk.red('✖'),
|
|
7
7
|
warning: chalk.yellow('⚠'),
|
|
8
|
-
info: chalk.blue('ℹ'),
|
|
9
8
|
tip: '💡',
|
|
10
9
|
active: chalk.green('●'),
|
|
11
10
|
inactive: chalk.dim('○'),
|
|
@@ -14,7 +13,7 @@ const icon = {
|
|
|
14
13
|
// --- Success messages ---
|
|
15
14
|
|
|
16
15
|
export function cloakCreated(name) {
|
|
17
|
-
return `${icon.success} Cloak ${chalk.bold(`"${name}"`)} created
|
|
16
|
+
return `${icon.success} Cloak ${chalk.bold(`"${name}"`)} created. Ready to wear!`
|
|
18
17
|
}
|
|
19
18
|
|
|
20
19
|
export function cloakSwitched(name) {
|
|
@@ -26,11 +25,11 @@ export function cloakDiscarded(name) {
|
|
|
26
25
|
}
|
|
27
26
|
|
|
28
27
|
export function cloakRenamed(oldName, newName) {
|
|
29
|
-
return `${icon.success} Cloak ${chalk.bold(`"${oldName}"`)}
|
|
28
|
+
return `${icon.success} Cloak ${chalk.bold(`"${oldName}"`)} is now ${chalk.bold(`"${newName}"`)}.`
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
export function shellIntegrationAdded(rcFile) {
|
|
33
|
-
return `${icon.success} Shell integration added to ${chalk.bold(rcFile)}
|
|
32
|
+
return `${icon.success} All set! Shell integration added to ${chalk.bold(rcFile)}.`
|
|
34
33
|
}
|
|
35
34
|
|
|
36
35
|
// --- Error messages ---
|
|
@@ -40,7 +39,7 @@ export function validationError(error) {
|
|
|
40
39
|
}
|
|
41
40
|
|
|
42
41
|
export function accountNotFound(name) {
|
|
43
|
-
return `${icon.error}
|
|
42
|
+
return `${icon.error} Couldn't find a cloak named ${chalk.bold(`"${name}"`)}.`
|
|
44
43
|
}
|
|
45
44
|
|
|
46
45
|
export function noActiveSession() {
|
|
@@ -48,35 +47,35 @@ export function noActiveSession() {
|
|
|
48
47
|
}
|
|
49
48
|
|
|
50
49
|
export function cannotDiscardActive() {
|
|
51
|
-
return `${icon.error}
|
|
50
|
+
return `${icon.error} You're currently wearing this cloak.`
|
|
52
51
|
}
|
|
53
52
|
|
|
54
53
|
export function accountAlreadyInUse(name) {
|
|
55
|
-
return `${icon.error}
|
|
54
|
+
return `${icon.error} A cloak named ${chalk.bold(`"${name}"`)} already exists.`
|
|
56
55
|
}
|
|
57
56
|
|
|
58
57
|
// --- Warning messages ---
|
|
59
58
|
|
|
60
59
|
export function alreadyWearing(name) {
|
|
61
|
-
return `${icon.warning}
|
|
60
|
+
return `${icon.warning} You're already wearing cloak ${chalk.bold(`"${name}"`)}.`
|
|
62
61
|
}
|
|
63
62
|
|
|
64
63
|
export function switchRequired() {
|
|
65
|
-
return `${icon.warning}
|
|
64
|
+
return `${icon.warning} Quick setup needed to enable switching.`
|
|
66
65
|
}
|
|
67
66
|
|
|
68
67
|
export function updateSessionAfterRename(newName) {
|
|
69
|
-
return `${icon.warning}
|
|
68
|
+
return `${icon.warning} To keep using this cloak, run: ${chalk.white(`claude account switch ${newName}`)}`
|
|
70
69
|
}
|
|
71
70
|
|
|
72
71
|
// --- Info / hints ---
|
|
73
72
|
|
|
74
73
|
export function suggestCreate(name) {
|
|
75
|
-
return chalk.dim(`
|
|
74
|
+
return chalk.dim(` Try: cloak create ${name || '<name>'}`)
|
|
76
75
|
}
|
|
77
76
|
|
|
78
77
|
export function suggestSwitchFirst() {
|
|
79
|
-
return chalk.dim(' Switch to
|
|
78
|
+
return chalk.dim(' Switch to a different cloak first, then try again.')
|
|
80
79
|
}
|
|
81
80
|
|
|
82
81
|
export function loginFirst() {
|
|
@@ -84,11 +83,11 @@ export function loginFirst() {
|
|
|
84
83
|
}
|
|
85
84
|
|
|
86
85
|
export function cancelled() {
|
|
87
|
-
return chalk.dim('
|
|
86
|
+
return chalk.dim('No changes made.')
|
|
88
87
|
}
|
|
89
88
|
|
|
90
89
|
export function noCloak() {
|
|
91
|
-
return chalk.dim('No cloak
|
|
90
|
+
return chalk.dim('No cloak active — using default Claude Code config.')
|
|
92
91
|
}
|
|
93
92
|
|
|
94
93
|
export function noCloaksYet() {
|
|
@@ -96,7 +95,7 @@ export function noCloaksYet() {
|
|
|
96
95
|
}
|
|
97
96
|
|
|
98
97
|
export function accountListHeader() {
|
|
99
|
-
return chalk.bold('\
|
|
98
|
+
return chalk.bold('\nYour Cloaks\n')
|
|
100
99
|
}
|
|
101
100
|
|
|
102
101
|
export function accountListItem(name, isActive) {
|
|
@@ -107,13 +106,13 @@ export function accountListItem(name, isActive) {
|
|
|
107
106
|
}
|
|
108
107
|
|
|
109
108
|
export function alreadyInstalled(rcFile) {
|
|
110
|
-
return chalk.dim(` Already
|
|
109
|
+
return chalk.dim(` Already set up in ${rcFile} — you're good!`)
|
|
111
110
|
}
|
|
112
111
|
|
|
113
112
|
// --- Setup instructions ---
|
|
114
113
|
|
|
115
114
|
export function setupRunCommand(rcFile, name) {
|
|
116
|
-
return chalk.dim('\n Run: ') + chalk.white(`source ${rcFile} && cloak switch ${name}\n`)
|
|
115
|
+
return chalk.dim('\n Almost there! Run: ') + chalk.white(`source ${rcFile} && cloak switch ${name}\n`)
|
|
117
116
|
}
|
|
118
117
|
|
|
119
118
|
export function setupManualCommand(rcFile, name) {
|
|
@@ -122,9 +121,10 @@ export function setupManualCommand(rcFile, name) {
|
|
|
122
121
|
|
|
123
122
|
// --- Tip ---
|
|
124
123
|
|
|
125
|
-
export function shellIntegrationTip() {
|
|
126
|
-
|
|
127
|
-
|
|
124
|
+
export function shellIntegrationTip(rcFile) {
|
|
125
|
+
const file = rcFile || '~/.bashrc'
|
|
126
|
+
return chalk.dim(`\n${icon.tip} Tip: Enable "claude -a" and "claude account" with:\n`) +
|
|
127
|
+
chalk.dim(` echo 'eval "$(cloak init)"' >> ${file} && source ${file}\n\n`)
|
|
128
128
|
}
|
|
129
129
|
|
|
130
130
|
// --- Print-env (stdout, no chalk — evaluated by shell) ---
|
|
@@ -134,16 +134,17 @@ export function printEnvExport(dir) {
|
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
export function printEnvEcho(name) {
|
|
137
|
-
return `echo "${
|
|
137
|
+
return `echo "Now wearing cloak ${name}."\n`
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
// --- Prompt messages ---
|
|
141
141
|
|
|
142
142
|
export const prompts = {
|
|
143
|
-
accountName: '
|
|
144
|
-
overwriteConfirm: (name) => `Cloak "${name}" already exists.
|
|
145
|
-
deleteConfirm: (name) => `
|
|
143
|
+
accountName: 'Name your cloak:',
|
|
144
|
+
overwriteConfirm: (name) => `Cloak "${name}" already exists. Replace it?`,
|
|
145
|
+
deleteConfirm: (name) => `Remove cloak "${name}"? This can't be undone.`,
|
|
146
|
+
renameConfirm: (oldName, newName) => `Rename cloak "${oldName}" to "${newName}"?`,
|
|
146
147
|
setupChoice: 'How would you like to proceed?',
|
|
147
148
|
setupAuto: 'Set it up now (recommended)',
|
|
148
|
-
setupManual: 'Show manual
|
|
149
|
+
setupManual: 'Show me the manual steps',
|
|
149
150
|
}
|
package/src/lib/tip.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { shellIntegrationTip } from './messages.js'
|
|
2
|
+
import { getRcFilePath } from './setup.js'
|
|
2
3
|
|
|
3
4
|
export function showTipIfNeeded() {
|
|
4
5
|
if (process.env.CLOAK_SHELL_INTEGRATION === '1') return
|
|
5
6
|
if (process.env.CLOAK_TIP_SHOWN === '1') return
|
|
6
7
|
if (!process.stdout.isTTY) return
|
|
7
8
|
|
|
8
|
-
process.stderr.write(shellIntegrationTip())
|
|
9
|
+
process.stderr.write(shellIntegrationTip(getRcFilePath()))
|
|
9
10
|
|
|
10
11
|
process.env.CLOAK_TIP_SHOWN = '1'
|
|
11
12
|
}
|