@synth1s/cloak 1.5.1 → 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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@synth1s/cloak",
3
- "version": "1.5.1",
3
+ "version": "1.6.0",
4
4
  "description": "Cloak your Claude. Switch identities in seconds.",
5
5
  "type": "module",
6
6
  "bin": {
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
- .option('--print-env', 'Output export command for eval (used by shell integration)')
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()
@@ -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) {
@@ -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
- console.log(msg.noCloak())
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)
@@ -71,7 +71,7 @@ export function updateSessionAfterRename(newName) {
71
71
  // --- Info / hints ---
72
72
 
73
73
  export function suggestCreate(name) {
74
- return chalk.dim(` Try: claude account create ${name || '<name>'}`)
74
+ return chalk.dim(` Try: cloak create ${name || '<name>'}`)
75
75
  }
76
76
 
77
77
  export function suggestSwitchFirst() {
@@ -121,9 +121,10 @@ export function setupManualCommand(rcFile, name) {
121
121
 
122
122
  // --- Tip ---
123
123
 
124
- export function shellIntegrationTip() {
124
+ export function shellIntegrationTip(rcFile) {
125
+ const file = rcFile || '~/.bashrc'
125
126
  return chalk.dim(`\n${icon.tip} Tip: Enable "claude -a" and "claude account" with:\n`) +
126
- chalk.dim(' echo \'eval "$(cloak init)"\' >> ~/.bashrc && source ~/.bashrc\n\n')
127
+ chalk.dim(` echo 'eval "$(cloak init)"' >> ${file} && source ${file}\n\n`)
127
128
  }
128
129
 
129
130
  // --- Print-env (stdout, no chalk — evaluated by shell) ---
@@ -133,7 +134,7 @@ export function printEnvExport(dir) {
133
134
  }
134
135
 
135
136
  export function printEnvEcho(name) {
136
- return `echo "${cloakSwitched(name)}"\n`
137
+ return `echo "Now wearing cloak ${name}."\n`
137
138
  }
138
139
 
139
140
  // --- Prompt messages ---
@@ -142,6 +143,7 @@ export const prompts = {
142
143
  accountName: 'Name your cloak:',
143
144
  overwriteConfirm: (name) => `Cloak "${name}" already exists. Replace it?`,
144
145
  deleteConfirm: (name) => `Remove cloak "${name}"? This can't be undone.`,
146
+ renameConfirm: (oldName, newName) => `Rename cloak "${oldName}" to "${newName}"?`,
145
147
  setupChoice: 'How would you like to proceed?',
146
148
  setupAuto: 'Set it up now (recommended)',
147
149
  setupManual: 'Show me the manual steps',
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
  }