@synth1s/cloak 2.0.2 → 2.1.2
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/.github/dependabot.yml +7 -0
- package/.github/workflows/ci.yml +30 -0
- package/.github/workflows/publish.yml +23 -0
- package/CONTRIBUTING.md +48 -0
- package/README.md +4 -0
- package/SECURITY.md +31 -0
- package/package.json +1 -1
- package/src/commands/create.js +4 -2
- package/src/lib/messages.js +1 -1
- package/src/lib/paths.js +1 -1
- package/src/lib/setup.js +14 -6
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [master]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [master]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
test:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
strategy:
|
|
13
|
+
matrix:
|
|
14
|
+
node-version: [18, 20]
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
- uses: actions/setup-node@v4
|
|
18
|
+
with:
|
|
19
|
+
node-version: ${{ matrix.node-version }}
|
|
20
|
+
- run: npm ci
|
|
21
|
+
- run: node --test tests/*.test.js
|
|
22
|
+
|
|
23
|
+
audit:
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@v4
|
|
27
|
+
- uses: actions/setup-node@v4
|
|
28
|
+
with:
|
|
29
|
+
node-version: 20
|
|
30
|
+
- run: npm audit --audit-level=high
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
name: Publish to npm
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
publish:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
id-token: write
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
- uses: actions/setup-node@v4
|
|
16
|
+
with:
|
|
17
|
+
node-version: 20
|
|
18
|
+
registry-url: https://registry.npmjs.org
|
|
19
|
+
- run: npm ci
|
|
20
|
+
- run: node --test tests/*.test.js
|
|
21
|
+
- run: npm publish --access public --provenance
|
|
22
|
+
env:
|
|
23
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Contributing to @synth1s/cloak
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in contributing!
|
|
4
|
+
|
|
5
|
+
## Development
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git clone https://github.com/synth1s/cloak.git
|
|
9
|
+
cd cloak
|
|
10
|
+
npm install
|
|
11
|
+
npm test
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Methodology
|
|
15
|
+
|
|
16
|
+
This project follows **strict TDD**. Every change must follow:
|
|
17
|
+
|
|
18
|
+
1. Write the test first (it must fail)
|
|
19
|
+
2. Implement the minimum code to make it pass
|
|
20
|
+
3. Refactor if needed
|
|
21
|
+
|
|
22
|
+
## Running tests
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm test # run all tests
|
|
26
|
+
node --test tests/ # same thing
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Tests use `node:test` (native Node.js test runner). No external test frameworks.
|
|
30
|
+
|
|
31
|
+
## Code style
|
|
32
|
+
|
|
33
|
+
- Node.js ESM (`type: "module"`)
|
|
34
|
+
- All user-facing strings in `src/lib/messages.js`
|
|
35
|
+
- All paths in `src/lib/paths.js`
|
|
36
|
+
- One file per command in `src/commands/`
|
|
37
|
+
- stderr for errors/warnings, stdout for data/success
|
|
38
|
+
|
|
39
|
+
## Pull requests
|
|
40
|
+
|
|
41
|
+
- One feature or fix per PR
|
|
42
|
+
- Include tests for new behavior
|
|
43
|
+
- Update documentation if the change affects user-facing behavior
|
|
44
|
+
- Run `npm test` before submitting
|
|
45
|
+
|
|
46
|
+
## Security
|
|
47
|
+
|
|
48
|
+
See [SECURITY.md](SECURITY.md) for reporting vulnerabilities.
|
package/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# @synth1s/cloak
|
|
2
2
|
|
|
3
|
+
[](https://github.com/synth1s/cloak/actions/workflows/ci.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/@synth1s/cloak)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
3
7
|
> Cloak your Claude. Switch identities in seconds.
|
|
4
8
|
|
|
5
9
|
Every developer wears a different cloak. One for work, one for personal projects, one for that freelance gig. **Cloak** lets you dress your Claude Code in the right identity — and switch between them without breaking a sweat.
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Reporting a Vulnerability
|
|
4
|
+
|
|
5
|
+
If you discover a security vulnerability in @synth1s/cloak, please report it responsibly.
|
|
6
|
+
|
|
7
|
+
**Do NOT open a public issue.** Instead, email:
|
|
8
|
+
|
|
9
|
+
**cloak@synth1s.com.br**
|
|
10
|
+
|
|
11
|
+
Include:
|
|
12
|
+
- Description of the vulnerability
|
|
13
|
+
- Steps to reproduce
|
|
14
|
+
- Potential impact
|
|
15
|
+
|
|
16
|
+
You will receive a response within 48 hours. Once confirmed, a fix will be released as a patch version and credited in the changelog (unless you prefer anonymity).
|
|
17
|
+
|
|
18
|
+
## Scope
|
|
19
|
+
|
|
20
|
+
This policy covers:
|
|
21
|
+
- The `@synth1s/cloak` npm package
|
|
22
|
+
- The shell integration code emitted by `cloak init`
|
|
23
|
+
- File operations on `~/.cloak/` and shell rc files
|
|
24
|
+
|
|
25
|
+
## Security Measures
|
|
26
|
+
|
|
27
|
+
- Account names are validated against `^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$` to prevent path traversal
|
|
28
|
+
- Credential files are created with restrictive permissions (0o700 dirs, 0o600 files)
|
|
29
|
+
- Shell eval output is quoted to prevent injection
|
|
30
|
+
- OAuth tokens are never read, logged, or transmitted — only copied as files
|
|
31
|
+
- `.bashrc` modifications include a backup (`.cloak-backup`) and a marker comment
|
package/package.json
CHANGED
package/src/commands/create.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync, copyFileSync, mkdirSync } from 'fs'
|
|
1
|
+
import { existsSync, copyFileSync, mkdirSync, chmodSync } from 'fs'
|
|
2
2
|
import inquirer from 'inquirer'
|
|
3
3
|
import {
|
|
4
4
|
claudeAuthPath,
|
|
@@ -62,13 +62,15 @@ export async function createAccount(name, options = {}) {
|
|
|
62
62
|
|
|
63
63
|
ensureProfilesDir()
|
|
64
64
|
const dir = profileDir(name)
|
|
65
|
-
mkdirSync(dir, { recursive: true })
|
|
65
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 })
|
|
66
66
|
|
|
67
67
|
copyFileSync(authSource, profileAuthPath(name))
|
|
68
|
+
chmodSync(profileAuthPath(name), 0o600)
|
|
68
69
|
|
|
69
70
|
const settingsSource = claudeSettingsPath()
|
|
70
71
|
if (existsSync(settingsSource)) {
|
|
71
72
|
copyFileSync(settingsSource, profileSettingsPath(name))
|
|
73
|
+
chmodSync(profileSettingsPath(name), 0o600)
|
|
72
74
|
}
|
|
73
75
|
|
|
74
76
|
console.log(msg.cloakCreated(name))
|
package/src/lib/messages.js
CHANGED
|
@@ -137,7 +137,7 @@ export function wearingCloak(name) {
|
|
|
137
137
|
// --- Print-env (stdout, no chalk — evaluated by shell) ---
|
|
138
138
|
|
|
139
139
|
export function printEnvExport(dir) {
|
|
140
|
-
return `export CLAUDE_CONFIG_DIR
|
|
140
|
+
return `export CLAUDE_CONFIG_DIR="${dir}"\n`
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
export function printEnvEcho(name) {
|
package/src/lib/paths.js
CHANGED
package/src/lib/setup.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
-
import { readFileSync, writeFileSync, existsSync } from 'fs'
|
|
1
|
+
import { readFileSync, writeFileSync, copyFileSync, existsSync } from 'fs'
|
|
2
2
|
import { join } from 'path'
|
|
3
3
|
import { homedir } from 'os'
|
|
4
4
|
|
|
5
|
+
const MARKER = '# Added by @synth1s/cloak'
|
|
6
|
+
const INIT_LINE = 'eval "$(cloak init)"'
|
|
7
|
+
|
|
5
8
|
function getHome() {
|
|
6
9
|
return process.env.HOME || homedir()
|
|
7
10
|
}
|
|
@@ -22,16 +25,21 @@ export function isAlreadyInstalled(rcFilePath) {
|
|
|
22
25
|
|
|
23
26
|
export function installToRcFile(rcFilePath) {
|
|
24
27
|
if (!existsSync(rcFilePath)) {
|
|
25
|
-
writeFileSync(rcFilePath,
|
|
28
|
+
writeFileSync(rcFilePath, `${MARKER}\n${INIT_LINE}\n`)
|
|
26
29
|
return
|
|
27
30
|
}
|
|
28
31
|
|
|
29
|
-
//
|
|
32
|
+
// Backup before modifying
|
|
33
|
+
copyFileSync(rcFilePath, rcFilePath + '.cloak-backup')
|
|
34
|
+
|
|
35
|
+
// Remove ALL lines containing 'cloak init' or the marker
|
|
30
36
|
const content = readFileSync(rcFilePath, 'utf8')
|
|
31
37
|
const lines = content.split('\n')
|
|
32
|
-
const cleaned = lines.filter(line =>
|
|
38
|
+
const cleaned = lines.filter(line =>
|
|
39
|
+
!line.includes('cloak init') && line !== MARKER
|
|
40
|
+
)
|
|
33
41
|
const cleanedContent = cleaned.join('\n').replace(/\n{3,}/g, '\n\n')
|
|
34
42
|
|
|
35
|
-
//
|
|
36
|
-
writeFileSync(rcFilePath, cleanedContent.trimEnd() +
|
|
43
|
+
// Append fresh marker + init line
|
|
44
|
+
writeFileSync(rcFilePath, cleanedContent.trimEnd() + `\n${MARKER}\n${INIT_LINE}\n`)
|
|
37
45
|
}
|