claude-access-for-all 0.1.0 → 0.1.1
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 +1 -1
- package/bin/claude-access.js +4 -3
- package/package.json +1 -1
- package/tools/access.py +6 -2
- package/tools/privacy.py +6 -2
- package/tools/report.py +85 -0
package/README.md
CHANGED
|
@@ -65,7 +65,7 @@ claude-access reminder --renewal 2026-12-01 --days-before 3 > renewal.ics
|
|
|
65
65
|
open renewal.ics
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
-
To install directly from GitHub, use `npm install -g github:AMark-CS/claude-access-for-all`. Use `claude-access help` to see the complete command list. `inspect` opens the local graphical browser inspector in your default browser. To check a separate browser profile, open its local file in that profile instead; see the [privacy inspector guide](docs/privacy-inspector.md).
|
|
68
|
+
To install directly from GitHub, use `npm install -g github:AMark-CS/claude-access-for-all`. Use `claude-access help` to see the complete command list. Diagnostics display a readable summary by default; use `claude-access doctor --json` or `claude-access audit --json` for machine-readable output. `inspect` opens the local graphical browser inspector in your default browser. To check a separate browser profile, open its local file in that profile instead; see the [privacy inspector guide](docs/privacy-inspector.md).
|
|
69
69
|
|
|
70
70
|
For the calendar reminder, replace the example date with the next billing date shown by your billing provider. The file contains one all-day review event with an alert; import it into Apple Calendar and check your notification settings. It neither cancels nor renews anything, and must be regenerated when the billing date changes.
|
|
71
71
|
|
package/bin/claude-access.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { readFileSync } from 'node:fs';
|
|
3
4
|
import { createInterface } from 'node:readline/promises';
|
|
4
5
|
import { fileURLToPath } from 'node:url';
|
|
5
6
|
import { dirname, join } from 'node:path';
|
|
@@ -10,8 +11,8 @@ const help = `Claude Access for All
|
|
|
10
11
|
Usage: claude-access [command] [options]
|
|
11
12
|
|
|
12
13
|
menu Open the interactive menu (default)
|
|
13
|
-
doctor
|
|
14
|
-
audit
|
|
14
|
+
doctor [--json] Check local installation and configuration presence
|
|
15
|
+
audit [--json] Inspect CLI environment signals locally
|
|
15
16
|
cli [options] [-- ...] Launch Claude Code with scoped locale settings
|
|
16
17
|
app [options] Launch Claude Desktop with scoped locale settings
|
|
17
18
|
web [options] Launch Claude in a separate browser profile
|
|
@@ -56,7 +57,7 @@ function dispatch(command, args = []) {
|
|
|
56
57
|
if (process.platform !== 'darwin') { console.error('The guide launcher requires macOS.'); return 1; }
|
|
57
58
|
return run('/usr/bin/open', ['https://github.com/AMark-CS/claude-access-for-all/blob/main/docs/privacy-inspector.md']);
|
|
58
59
|
case 'help': case '--help': case '-h': console.log(help); return 0;
|
|
59
|
-
case 'version': case '--version': case '-v': console.log('
|
|
60
|
+
case 'version': case '--version': case '-v': console.log(JSON.parse(readFileSync(join(root, 'package.json'), 'utf8')).version); return 0;
|
|
60
61
|
default: console.error(`Unknown command: ${command}\n\n${help}`); return 2;
|
|
61
62
|
}
|
|
62
63
|
}
|
package/package.json
CHANGED
package/tools/access.py
CHANGED
|
@@ -9,6 +9,8 @@ import shutil
|
|
|
9
9
|
import sys
|
|
10
10
|
import uuid
|
|
11
11
|
|
|
12
|
+
from report import render_doctor
|
|
13
|
+
|
|
12
14
|
VARIABLES = (
|
|
13
15
|
'ANTHROPIC_API_KEY', 'ANTHROPIC_AUTH_TOKEN', 'ANTHROPIC_BASE_URL',
|
|
14
16
|
'CLAUDE_CODE_USE_BEDROCK', 'CLAUDE_CODE_USE_VERTEX', 'CLAUDE_CODE_USE_FOUNDRY',
|
|
@@ -92,13 +94,15 @@ def reminder(renewal, lead, today=None):
|
|
|
92
94
|
def main():
|
|
93
95
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
94
96
|
commands = parser.add_subparsers(dest='command', required=True)
|
|
95
|
-
commands.add_parser('doctor', help='Print an offline
|
|
97
|
+
diagnostic = commands.add_parser('doctor', help='Print an offline environment report.')
|
|
98
|
+
diagnostic.add_argument('--json', action='store_true', help='Output machine-readable JSON.')
|
|
96
99
|
calendar = commands.add_parser('reminder', help='Print a one-time .ics calendar to stdout.')
|
|
97
100
|
calendar.add_argument('--renewal', type=parse_date, required=True)
|
|
98
101
|
calendar.add_argument('--days-before', type=days_before, default=3)
|
|
99
102
|
args = parser.parse_args()
|
|
100
103
|
if args.command == 'doctor':
|
|
101
|
-
|
|
104
|
+
result = doctor()
|
|
105
|
+
print(json.dumps(result, indent=2) if args.json else render_doctor(result))
|
|
102
106
|
else:
|
|
103
107
|
try:
|
|
104
108
|
content = reminder(args.renewal, args.days_before)
|
package/tools/privacy.py
CHANGED
|
@@ -12,6 +12,8 @@ import sys
|
|
|
12
12
|
import tempfile
|
|
13
13
|
import time
|
|
14
14
|
|
|
15
|
+
from report import render_audit
|
|
16
|
+
|
|
15
17
|
ROUTING = ('ANTHROPIC_BASE_URL', 'HTTP_PROXY', 'HTTPS_PROXY', 'ALL_PROXY', 'NO_PROXY',
|
|
16
18
|
'http_proxy', 'https_proxy', 'all_proxy', 'no_proxy')
|
|
17
19
|
AUTH = ('ANTHROPIC_API_KEY', 'ANTHROPIC_AUTH_TOKEN')
|
|
@@ -65,7 +67,8 @@ def browser_command(browser, profile, language, timezone, locale):
|
|
|
65
67
|
def main():
|
|
66
68
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
67
69
|
sub = parser.add_subparsers(dest='command', required=True)
|
|
68
|
-
sub.add_parser('audit', help='Show local
|
|
70
|
+
diagnostic = sub.add_parser('audit', help='Show local signals without exposing secret values.')
|
|
71
|
+
diagnostic.add_argument('--json', action='store_true', help='Output machine-readable JSON.')
|
|
69
72
|
for name in ('cli', 'app', 'web'):
|
|
70
73
|
command = sub.add_parser(name, help='Launch ' + name + ' with process-scoped settings.')
|
|
71
74
|
command.add_argument('--timezone', type=validate_timezone, default='UTC')
|
|
@@ -80,7 +83,8 @@ def main():
|
|
|
80
83
|
command.add_argument('--language', default='en-US', type=validate_locale)
|
|
81
84
|
args = parser.parse_args()
|
|
82
85
|
if args.command == 'audit':
|
|
83
|
-
|
|
86
|
+
result = audit()
|
|
87
|
+
print(json.dumps(result, indent=2) if args.json else render_audit(result))
|
|
84
88
|
return
|
|
85
89
|
if sys.platform != 'darwin':
|
|
86
90
|
parser.error('Launch commands require macOS.')
|
package/tools/report.py
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"""Readable, privacy-conscious CLI reports. JSON remains available via --json."""
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def style(text, code):
|
|
7
|
+
if sys.stdout.isatty() and not os.environ.get('NO_COLOR') and os.environ.get('TERM') != 'dumb':
|
|
8
|
+
return f'\033[{code}m{text}\033[0m'
|
|
9
|
+
return text
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def title(name, subtitle):
|
|
13
|
+
return [
|
|
14
|
+
'',
|
|
15
|
+
' ' + style('CLAUDE ACCESS', '1;36') + style(' / ' + name.upper(), '1'),
|
|
16
|
+
' ' + style(subtitle, '2'),
|
|
17
|
+
'',
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def row(label, value):
|
|
22
|
+
return f' {label:<20} {value}'
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def section(name):
|
|
26
|
+
return '\n ' + style(name, '1')
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def group(label, names, values):
|
|
30
|
+
active = [name for name in names if values.get(name)]
|
|
31
|
+
if active:
|
|
32
|
+
return row(label, style('Set', '33') + ' ' + ', '.join(active))
|
|
33
|
+
return row(label, style('Not set', '2'))
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def render_doctor(report):
|
|
37
|
+
env = report['environment_set']
|
|
38
|
+
system = report['system']
|
|
39
|
+
if system == 'Darwin':
|
|
40
|
+
system = 'macOS ' + (report['macos_version'] or '(version unavailable)')
|
|
41
|
+
lines = title('Environment check', 'Local diagnostic · no network requests')
|
|
42
|
+
lines += [
|
|
43
|
+
row('System', system + ' · ' + report['architecture']),
|
|
44
|
+
row('Claude Code', style('Found on PATH', '32') if report['claude_on_path'] else style('Not found on PATH', '33')),
|
|
45
|
+
section('Environment variables'),
|
|
46
|
+
group('Authentication', ('ANTHROPIC_API_KEY', 'ANTHROPIC_AUTH_TOKEN'), env),
|
|
47
|
+
group('Service endpoint', ('ANTHROPIC_BASE_URL',), env),
|
|
48
|
+
group('Cloud providers', ('CLAUDE_CODE_USE_BEDROCK', 'CLAUDE_CODE_USE_VERTEX', 'CLAUDE_CODE_USE_FOUNDRY'), env),
|
|
49
|
+
group('Proxy variables', ('HTTP_PROXY', 'HTTPS_PROXY', 'ALL_PROXY', 'NO_PROXY', 'http_proxy', 'https_proxy', 'all_proxy', 'no_proxy'), env),
|
|
50
|
+
group('TLS settings', ('NODE_EXTRA_CA_CERTS', 'NODE_TLS_REJECT_UNAUTHORIZED'), env),
|
|
51
|
+
'',
|
|
52
|
+
]
|
|
53
|
+
if report['warnings']:
|
|
54
|
+
lines.append(' ' + style('Things to review', '1;33'))
|
|
55
|
+
lines.extend(' • ' + warning for warning in report['warnings'])
|
|
56
|
+
else:
|
|
57
|
+
lines.append(' ' + style('No local configuration warnings.', '32'))
|
|
58
|
+
lines += ['', ' Values are never shown. System proxies, app settings, credentials,',
|
|
59
|
+
' billing, account eligibility and network access were not checked.', '']
|
|
60
|
+
return '\n'.join(lines)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def render_audit(report):
|
|
64
|
+
names = list(dict.fromkeys(name for name in report['process_timezone_names'] if name))
|
|
65
|
+
tz = ' / '.join(names) if names else 'Unavailable'
|
|
66
|
+
lines = title('CLI signal audit', 'Current terminal process · offline')
|
|
67
|
+
lines += [
|
|
68
|
+
row('System', report['system']),
|
|
69
|
+
row('Claude Code', style('Found on PATH', '32') if report['claude_on_path'] else style('Not found on PATH', '33')),
|
|
70
|
+
section('Locale & time'),
|
|
71
|
+
row('Timezone names', tz),
|
|
72
|
+
row('TZ override', style('Set', '33') if report['timezone_override_set'] else style('Not set', '2')),
|
|
73
|
+
group('Locale variables', ('LANG', 'LC_ALL', 'LC_TIME'), report['locale_overrides_set']),
|
|
74
|
+
section('Connection & authentication'),
|
|
75
|
+
group('Endpoint & proxies', report['routing_overrides_set'].keys(), report['routing_overrides_set']),
|
|
76
|
+
group('Credentials', report['credential_overrides_set'].keys(), report['credential_overrides_set']),
|
|
77
|
+
'',
|
|
78
|
+
' Values are never shown. HKT and other abbreviations are timezone names,',
|
|
79
|
+
' not proof of an exact location. Browser, Desktop, network, IP and',
|
|
80
|
+
' account status were not checked.',
|
|
81
|
+
'',
|
|
82
|
+
' Next: run ' + style('claude-access inspect', '1') + ' to inspect your default browser.',
|
|
83
|
+
'',
|
|
84
|
+
]
|
|
85
|
+
return '\n'.join(lines)
|