@myclaude-cli/cli 0.3.0-alpha
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/bin/dev.js +5 -0
- package/bin/myclaude.js +20 -0
- package/dist/commands/help.d.ts +11 -0
- package/dist/commands/help.js +221 -0
- package/dist/commands/help.js.map +1 -0
- package/dist/commands/info.d.ts +12 -0
- package/dist/commands/info.js +87 -0
- package/dist/commands/info.js.map +1 -0
- package/dist/commands/install.d.ts +14 -0
- package/dist/commands/install.js +113 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/list.d.ts +9 -0
- package/dist/commands/list.js +41 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/login.d.ts +9 -0
- package/dist/commands/login.js +83 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +9 -0
- package/dist/commands/logout.js +25 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/publish.d.ts +10 -0
- package/dist/commands/publish.js +229 -0
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/search.d.ts +18 -0
- package/dist/commands/search.js +108 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/status.d.ts +8 -0
- package/dist/commands/status.js +84 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/uninstall.d.ts +14 -0
- package/dist/commands/uninstall.js +98 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/commands/validate.d.ts +9 -0
- package/dist/commands/validate.js +144 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/commands/whoami.d.ts +9 -0
- package/dist/commands/whoami.js +52 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/constants.d.ts +9 -0
- package/dist/constants.js +10 -0
- package/dist/constants.js.map +1 -0
- package/dist/core/api.d.ts +18 -0
- package/dist/core/api.js +135 -0
- package/dist/core/api.js.map +1 -0
- package/dist/core/auth.d.ts +30 -0
- package/dist/core/auth.js +71 -0
- package/dist/core/auth.js.map +1 -0
- package/dist/core/browser-auth.d.ts +24 -0
- package/dist/core/browser-auth.js +155 -0
- package/dist/core/browser-auth.js.map +1 -0
- package/dist/core/install.d.ts +24 -0
- package/dist/core/install.js +191 -0
- package/dist/core/install.js.map +1 -0
- package/dist/core/lockfile.d.ts +18 -0
- package/dist/core/lockfile.js +41 -0
- package/dist/core/lockfile.js.map +1 -0
- package/dist/core/manifest.d.ts +41 -0
- package/dist/core/manifest.js +203 -0
- package/dist/core/manifest.js.map +1 -0
- package/dist/core/packer.d.ts +25 -0
- package/dist/core/packer.js +169 -0
- package/dist/core/packer.js.map +1 -0
- package/dist/core/paths.d.ts +2 -0
- package/dist/core/paths.js +50 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/secret-scan.d.ts +17 -0
- package/dist/core/secret-scan.js +73 -0
- package/dist/core/secret-scan.js.map +1 -0
- package/dist/ui/exit-codes.d.ts +91 -0
- package/dist/ui/exit-codes.js +51 -0
- package/dist/ui/exit-codes.js.map +1 -0
- package/dist/ui/format.d.ts +12 -0
- package/dist/ui/format.js +44 -0
- package/dist/ui/format.js.map +1 -0
- package/dist/ui/index.d.ts +13 -0
- package/dist/ui/index.js +11 -0
- package/dist/ui/index.js.map +1 -0
- package/dist/ui/layout.d.ts +28 -0
- package/dist/ui/layout.js +161 -0
- package/dist/ui/layout.js.map +1 -0
- package/dist/ui/table.d.ts +10 -0
- package/dist/ui/table.js +42 -0
- package/dist/ui/table.js.map +1 -0
- package/dist/ui/theme.d.ts +46 -0
- package/dist/ui/theme.js +180 -0
- package/dist/ui/theme.js.map +1 -0
- package/dist/utils/config.d.ts +11 -0
- package/dist/utils/config.js +44 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/keychain.d.ts +3 -0
- package/dist/utils/keychain.js +53 -0
- package/dist/utils/keychain.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
export default class Uninstall extends Command {
|
|
3
|
+
static args: {
|
|
4
|
+
slug: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
|
|
5
|
+
};
|
|
6
|
+
static description: string;
|
|
7
|
+
static examples: string[];
|
|
8
|
+
static flags: {
|
|
9
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
yes: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
11
|
+
};
|
|
12
|
+
run(): Promise<void>;
|
|
13
|
+
private confirm;
|
|
14
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { Args, Command, Flags } from '@oclif/core';
|
|
2
|
+
import { createInterface } from 'node:readline';
|
|
3
|
+
import { existsSync, rmSync } from 'node:fs';
|
|
4
|
+
import { resolve } from 'node:path';
|
|
5
|
+
import { homedir } from 'node:os';
|
|
6
|
+
import { isInstalled, removeEntry } from '../core/lockfile.js';
|
|
7
|
+
import { EXIT, color, icon } from '../ui/index.js';
|
|
8
|
+
/** Verify uninstall path is within expected roots before rmSync */
|
|
9
|
+
function isSafePath(location) {
|
|
10
|
+
const resolved = resolve(location);
|
|
11
|
+
const cwd = resolve('.');
|
|
12
|
+
const home = homedir();
|
|
13
|
+
const safePrefixes = [
|
|
14
|
+
resolve(cwd, '.claude'),
|
|
15
|
+
resolve(cwd, 'myclaude-products'),
|
|
16
|
+
resolve(home, '.claude'),
|
|
17
|
+
resolve(home, 'myclaude-products'),
|
|
18
|
+
];
|
|
19
|
+
return safePrefixes.some((prefix) => resolved.startsWith(prefix));
|
|
20
|
+
}
|
|
21
|
+
export default class Uninstall extends Command {
|
|
22
|
+
static args = {
|
|
23
|
+
slug: Args.string({ description: 'Product slug to uninstall', required: true }),
|
|
24
|
+
};
|
|
25
|
+
static description = 'Remove an installed product';
|
|
26
|
+
static examples = [
|
|
27
|
+
'<%= config.bin %> uninstall auth-guard-skill',
|
|
28
|
+
];
|
|
29
|
+
static flags = {
|
|
30
|
+
json: Flags.boolean({ description: 'Output as JSON' }),
|
|
31
|
+
yes: Flags.boolean({ char: 'y', default: false, description: 'Skip confirmation' }),
|
|
32
|
+
};
|
|
33
|
+
async run() {
|
|
34
|
+
const { args, flags } = await this.parse(Uninstall);
|
|
35
|
+
const entry = isInstalled(args.slug);
|
|
36
|
+
if (!entry) {
|
|
37
|
+
if (flags.json) {
|
|
38
|
+
this.log(JSON.stringify({ error: 'Not installed', uninstalled: false }));
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
this.log(` ${icon.info} ${args.slug} is not installed`);
|
|
42
|
+
}
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (!flags.yes && !flags.json) {
|
|
46
|
+
const confirmed = await this.confirm(`Remove ${args.slug} from ${entry.location}?`);
|
|
47
|
+
if (!confirmed) {
|
|
48
|
+
this.log('Aborted.');
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Security: validate path before deletion
|
|
53
|
+
if (!isSafePath(entry.location)) {
|
|
54
|
+
const msg = `Refusing to delete unsafe path: ${entry.location}`;
|
|
55
|
+
if (flags.json) {
|
|
56
|
+
this.log(JSON.stringify({ error: msg, uninstalled: false }));
|
|
57
|
+
this.exit(EXIT.ERROR);
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
this.error(msg);
|
|
61
|
+
}
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
if (existsSync(entry.location)) {
|
|
66
|
+
rmSync(entry.location, { force: true, recursive: true });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
const msg = error.message;
|
|
71
|
+
if (flags.json) {
|
|
72
|
+
this.log(JSON.stringify({ error: `Failed to remove files: ${msg}`, uninstalled: false }));
|
|
73
|
+
this.exit(EXIT.ERROR);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
this.error(`Failed to remove files: ${msg}`);
|
|
77
|
+
}
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
removeEntry(args.slug);
|
|
81
|
+
if (flags.json) {
|
|
82
|
+
this.log(JSON.stringify({ slug: args.slug, uninstalled: true }));
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
this.log(` ${icon.success} ${color.success(args.slug)} uninstalled`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
async confirm(question) {
|
|
89
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
90
|
+
return new Promise((resolve) => {
|
|
91
|
+
rl.question(` ${question} (y/N) `, (answer) => {
|
|
92
|
+
rl.close();
|
|
93
|
+
resolve(answer.trim().toLowerCase() === 'y');
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=uninstall.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uninstall.js","sourceRoot":"","sources":["../../src/commands/uninstall.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { readFileSync, statSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { Command, Flags } from '@oclif/core';
|
|
4
|
+
import { readManifest } from '../core/manifest.js';
|
|
5
|
+
import { collectFiles, formatBytes } from '../core/packer.js';
|
|
6
|
+
import { isEnvFile, scanForSecrets } from '../core/secret-scan.js';
|
|
7
|
+
import { EXIT, color, icon } from '../ui/index.js';
|
|
8
|
+
export default class Validate extends Command {
|
|
9
|
+
static description = 'Validate a product before publishing';
|
|
10
|
+
static examples = [
|
|
11
|
+
'<%= config.bin %> validate',
|
|
12
|
+
'<%= config.bin %> validate --json',
|
|
13
|
+
];
|
|
14
|
+
static flags = {
|
|
15
|
+
json: Flags.boolean({ description: 'Output as JSON' }),
|
|
16
|
+
};
|
|
17
|
+
async run() {
|
|
18
|
+
const { flags } = await this.parse(Validate);
|
|
19
|
+
const results = [];
|
|
20
|
+
let hasBlocker = false;
|
|
21
|
+
// 1. Parse vault.yaml
|
|
22
|
+
const { manifest, issues: manifestIssues } = readManifest();
|
|
23
|
+
if (!manifest) {
|
|
24
|
+
for (const issue of manifestIssues) {
|
|
25
|
+
results.push({ check: issue.field, message: issue.message, pass: false });
|
|
26
|
+
}
|
|
27
|
+
hasBlocker = true;
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
results.push({ check: 'vault.yaml', message: 'valid', pass: true });
|
|
31
|
+
// Add non-blocker warnings from manifest
|
|
32
|
+
for (const issue of manifestIssues) {
|
|
33
|
+
results.push({ check: issue.field, message: issue.message, pass: !issue.blocker });
|
|
34
|
+
if (issue.blocker)
|
|
35
|
+
hasBlocker = true;
|
|
36
|
+
}
|
|
37
|
+
// 2. Collect files
|
|
38
|
+
const { files, issues: packIssues } = collectFiles(process.cwd());
|
|
39
|
+
for (const issue of packIssues) {
|
|
40
|
+
results.push({ check: 'file size', message: `${issue.file}: ${issue.message}`, pass: false });
|
|
41
|
+
if (issue.blocker)
|
|
42
|
+
hasBlocker = true;
|
|
43
|
+
}
|
|
44
|
+
// Check for .env files in file list
|
|
45
|
+
const envFiles = files.filter(f => isEnvFile(f));
|
|
46
|
+
if (envFiles.length > 0) {
|
|
47
|
+
results.push({ check: '.env files', message: `Found ${envFiles.length} .env file(s) — excluded by default`, pass: true });
|
|
48
|
+
}
|
|
49
|
+
// Total size
|
|
50
|
+
let totalSize = 0;
|
|
51
|
+
for (const f of files) {
|
|
52
|
+
try {
|
|
53
|
+
totalSize += statSync(f).size;
|
|
54
|
+
}
|
|
55
|
+
catch { /* skip */ }
|
|
56
|
+
}
|
|
57
|
+
results.push({ check: 'files', message: `${files.length} files (${formatBytes(totalSize)})`, pass: true });
|
|
58
|
+
// 3. Secret scan
|
|
59
|
+
const findings = scanForSecrets(files, process.cwd());
|
|
60
|
+
if (findings.length > 0) {
|
|
61
|
+
hasBlocker = true;
|
|
62
|
+
for (const f of findings) {
|
|
63
|
+
results.push({
|
|
64
|
+
check: 'secret scan',
|
|
65
|
+
message: `${f.pattern} in ${f.file}:${f.line}`,
|
|
66
|
+
pass: false,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
results.push({ check: 'secret scan', message: 'no secrets detected', pass: true });
|
|
72
|
+
}
|
|
73
|
+
// 4. License
|
|
74
|
+
const KNOWN_SPDX = [
|
|
75
|
+
'MIT', 'Apache-2.0', 'GPL-3.0', 'GPL-2.0', 'BSD-3-Clause', 'BSD-2-Clause',
|
|
76
|
+
'ISC', 'CC-BY-4.0', 'CC-BY-SA-4.0', 'CC0-1.0', 'MPL-2.0', 'LGPL-3.0',
|
|
77
|
+
'AGPL-3.0', 'Unlicense', 'Proprietary', 'Custom',
|
|
78
|
+
];
|
|
79
|
+
if (KNOWN_SPDX.includes(manifest.license)) {
|
|
80
|
+
results.push({ check: 'license', message: `${manifest.license} (valid)`, pass: true });
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
results.push({ check: 'license', message: `${manifest.license} (unknown SPDX identifier)`, pass: true }); // warning, not blocker
|
|
84
|
+
}
|
|
85
|
+
// 5. Entry file type-specific checks
|
|
86
|
+
if (['skill', 'agent', 'squad'].includes(manifest.type)) {
|
|
87
|
+
const entryContent = await readEntryFile(manifest.entry);
|
|
88
|
+
if (entryContent && !entryContent.includes('---')) {
|
|
89
|
+
results.push({ check: 'frontmatter', message: `${manifest.entry} missing YAML frontmatter (---)`, pass: false });
|
|
90
|
+
hasBlocker = true;
|
|
91
|
+
}
|
|
92
|
+
else if (entryContent) {
|
|
93
|
+
results.push({ check: 'frontmatter', message: `${manifest.entry} has valid frontmatter`, pass: true });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Output
|
|
98
|
+
if (flags.json) {
|
|
99
|
+
this.log(JSON.stringify({
|
|
100
|
+
checks: results,
|
|
101
|
+
manifest: manifest ? {
|
|
102
|
+
category: manifest.category,
|
|
103
|
+
description: manifest.description,
|
|
104
|
+
license: manifest.license,
|
|
105
|
+
name: manifest.name,
|
|
106
|
+
price: manifest.price,
|
|
107
|
+
tags: manifest.tags,
|
|
108
|
+
type: manifest.type,
|
|
109
|
+
version: manifest.version,
|
|
110
|
+
} : null,
|
|
111
|
+
valid: !hasBlocker,
|
|
112
|
+
}));
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
const title = manifest?.name ?? 'unknown';
|
|
116
|
+
this.log(`\n Validating ${color.bold(title)}...\n`);
|
|
117
|
+
for (const r of results) {
|
|
118
|
+
const mark = r.pass ? icon.success : icon.error;
|
|
119
|
+
const msg = r.pass ? color.muted(r.message) : color.error(r.message);
|
|
120
|
+
this.log(` ${mark} ${color.muted(r.check + ':')} ${msg}`);
|
|
121
|
+
}
|
|
122
|
+
this.log('');
|
|
123
|
+
if (hasBlocker) {
|
|
124
|
+
this.log(` ${icon.error} ${color.error('Validation failed. Fix blockers above.')}`);
|
|
125
|
+
this.exit(EXIT.VALIDATION);
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
this.log(` ${icon.success} ${color.success('All checks passed.')} Run: ${color.bold('myclaude publish')}`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (hasBlocker) {
|
|
132
|
+
this.exit(EXIT.VALIDATION);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
function readEntryFile(entry) {
|
|
137
|
+
try {
|
|
138
|
+
return readFileSync(resolve(process.cwd(), entry), 'utf-8');
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Command, Flags } from '@oclif/core';
|
|
2
|
+
import { getValidToken } from '../core/auth.js';
|
|
3
|
+
import { readConfig } from '../utils/config.js';
|
|
4
|
+
import { action, color, icon } from '../ui/index.js';
|
|
5
|
+
export default class Whoami extends Command {
|
|
6
|
+
static description = 'Show current authenticated user';
|
|
7
|
+
static examples = [
|
|
8
|
+
'<%= config.bin %> whoami',
|
|
9
|
+
'<%= config.bin %> whoami --json',
|
|
10
|
+
];
|
|
11
|
+
static flags = {
|
|
12
|
+
json: Flags.boolean({ description: 'Output as JSON' }),
|
|
13
|
+
};
|
|
14
|
+
async run() {
|
|
15
|
+
const { flags } = await this.parse(Whoami);
|
|
16
|
+
const config = readConfig();
|
|
17
|
+
if (!config) {
|
|
18
|
+
if (flags.json) {
|
|
19
|
+
this.log(JSON.stringify({ loggedIn: false }));
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
this.log(` ${icon.warning} not logged in`);
|
|
23
|
+
this.log(action('myclaude login'));
|
|
24
|
+
}
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const token = await getValidToken(config.email);
|
|
28
|
+
if (!token) {
|
|
29
|
+
if (flags.json) {
|
|
30
|
+
this.log(JSON.stringify({ expired: true, loggedIn: false }));
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
this.log(` ${icon.warning} session expired`);
|
|
34
|
+
this.log(action('myclaude login'));
|
|
35
|
+
}
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (flags.json) {
|
|
39
|
+
this.log(JSON.stringify({
|
|
40
|
+
displayName: config.displayName,
|
|
41
|
+
email: config.email,
|
|
42
|
+
loggedIn: true,
|
|
43
|
+
uid: config.uid,
|
|
44
|
+
username: config.username,
|
|
45
|
+
}));
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
this.log(` ${color.primary('@' + config.username)} ${color.muted(`(${config.email})`)}`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=whoami.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,EAAE,KAAK,EAAC,MAAM,aAAa,CAAA;AAE1C,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAA;AAC7C,OAAO,EAAC,UAAU,EAAC,MAAM,oBAAoB,CAAA;AAC7C,OAAO,EAAC,MAAM,EAAE,KAAK,EAAE,IAAI,EAAC,MAAM,gBAAgB,CAAA;AAElD,MAAM,CAAC,OAAO,OAAO,MAAO,SAAQ,OAAO;IACzC,MAAM,CAAU,WAAW,GAAG,iCAAiC,CAAA;IAE/D,MAAM,CAAU,QAAQ,GAAG;QACzB,0BAA0B;QAC1B,iCAAiC;KAClC,CAAA;IAED,MAAM,CAAU,KAAK,GAAG;QACtB,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,EAAC,WAAW,EAAE,gBAAgB,EAAC,CAAC;KACrD,CAAA;IAED,KAAK,CAAC,GAAG;QACP,MAAM,EAAC,KAAK,EAAC,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;QAExC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAA;QAC3B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBACf,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAC,QAAQ,EAAE,KAAK,EAAC,CAAC,CAAC,CAAA;YAC7C,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,OAAO,gBAAgB,CAAC,CAAA;gBAC3C,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAA;YACpC,CAAC;YAED,OAAM;QACR,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAC/C,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;gBACf,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAC,CAAC,CAAC,CAAA;YAC5D,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,OAAO,kBAAkB,CAAC,CAAA;gBAC7C,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAA;YACpC,CAAC;YAED,OAAM;QACR,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;gBACtB,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,QAAQ,EAAE,IAAI;gBACd,GAAG,EAAE,MAAM,CAAC,GAAG;gBACf,QAAQ,EAAE,MAAM,CAAC,QAAQ;aAC1B,CAAC,CAAC,CAAA;QACL,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,OAAO,CAAC,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC,CAAA;QAC3F,CAAC;IACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Production constants for MyClaude CLI.
|
|
3
|
+
*
|
|
4
|
+
* The CLI talks ONLY to myclaude.sh — no Firebase API keys,
|
|
5
|
+
* no Google endpoints. All auth is proxied through the backend.
|
|
6
|
+
*/
|
|
7
|
+
export declare const MYCLAUDE_API_URL: string;
|
|
8
|
+
/** CLI version — injected from package.json at build time */
|
|
9
|
+
export declare const CLI_VERSION = "0.3.0-alpha";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Production constants for MyClaude CLI.
|
|
3
|
+
*
|
|
4
|
+
* The CLI talks ONLY to myclaude.sh — no Firebase API keys,
|
|
5
|
+
* no Google endpoints. All auth is proxied through the backend.
|
|
6
|
+
*/
|
|
7
|
+
export const MYCLAUDE_API_URL = process.env.NEXT_PUBLIC_APP_URL || 'https://myclaude.sh';
|
|
8
|
+
/** CLI version — injected from package.json at build time */
|
|
9
|
+
export const CLI_VERSION = '0.3.0-alpha';
|
|
10
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,qBAAqB,CAAA;AAExF,6DAA6D;AAC7D,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP client for myClaude API routes.
|
|
3
|
+
* Auto-attaches auth token when available.
|
|
4
|
+
* Uses native fetch (Node.js >= 20) with timeout and safe error handling.
|
|
5
|
+
*/
|
|
6
|
+
declare const DEFAULT_TIMEOUT_MS = 15000;
|
|
7
|
+
declare const MAX_TIMEOUT_MS = 60000;
|
|
8
|
+
export declare function getBaseUrl(): string;
|
|
9
|
+
export declare function apiGet(path: string, params?: Record<string, string>, options?: {
|
|
10
|
+
auth?: boolean;
|
|
11
|
+
timeout?: number;
|
|
12
|
+
}): Promise<Response>;
|
|
13
|
+
export declare function apiPost(path: string, body?: Record<string, unknown>, options?: {
|
|
14
|
+
auth?: boolean;
|
|
15
|
+
timeout?: number;
|
|
16
|
+
}): Promise<Response>;
|
|
17
|
+
export declare function requireAuth(): Promise<string>;
|
|
18
|
+
export { DEFAULT_TIMEOUT_MS, MAX_TIMEOUT_MS };
|
package/dist/core/api.js
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { MYCLAUDE_API_URL } from '../constants.js';
|
|
2
|
+
import { readConfig } from '../utils/config.js';
|
|
3
|
+
import { getValidToken } from './auth.js';
|
|
4
|
+
/**
|
|
5
|
+
* HTTP client for myClaude API routes.
|
|
6
|
+
* Auto-attaches auth token when available.
|
|
7
|
+
* Uses native fetch (Node.js >= 20) with timeout and safe error handling.
|
|
8
|
+
*/
|
|
9
|
+
const DEFAULT_TIMEOUT_MS = 15_000; // 15 seconds
|
|
10
|
+
const MAX_TIMEOUT_MS = 60_000; // 60 seconds for downloads
|
|
11
|
+
let httpsWarningShown = false;
|
|
12
|
+
export function getBaseUrl() {
|
|
13
|
+
const url = MYCLAUDE_API_URL;
|
|
14
|
+
if (!httpsWarningShown && !url.startsWith('https://') && !url.includes('localhost') && !url.includes('127.0.0.1')) {
|
|
15
|
+
httpsWarningShown = true;
|
|
16
|
+
process.stderr.write(`\x1b[33mWarning: API URL is not HTTPS: ${url}. Auth tokens may be exposed.\x1b[0m\n`);
|
|
17
|
+
}
|
|
18
|
+
return url;
|
|
19
|
+
}
|
|
20
|
+
/** Build a safe URL — validates base URL to prevent SSRF */
|
|
21
|
+
function buildUrl(path, params) {
|
|
22
|
+
const base = getBaseUrl();
|
|
23
|
+
const url = new URL(path, base);
|
|
24
|
+
// Ensure we're not being redirected to an unexpected host
|
|
25
|
+
const baseHost = new URL(base).host;
|
|
26
|
+
if (url.host !== baseHost) {
|
|
27
|
+
throw new Error('API URL host mismatch — possible redirect attack');
|
|
28
|
+
}
|
|
29
|
+
if (params) {
|
|
30
|
+
for (const [key, value] of Object.entries(params)) {
|
|
31
|
+
if (value !== undefined && value !== '') {
|
|
32
|
+
url.searchParams.set(key, value);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return url;
|
|
37
|
+
}
|
|
38
|
+
export async function apiGet(path, params, options) {
|
|
39
|
+
const url = buildUrl(path, params);
|
|
40
|
+
const timeout = options?.timeout ?? DEFAULT_TIMEOUT_MS;
|
|
41
|
+
const controller = new AbortController();
|
|
42
|
+
const timer = setTimeout(() => controller.abort(), timeout);
|
|
43
|
+
const headers = {
|
|
44
|
+
'Accept': 'application/json',
|
|
45
|
+
'X-Source': 'cli',
|
|
46
|
+
};
|
|
47
|
+
if (options?.auth !== false) {
|
|
48
|
+
const token = await getAuthToken();
|
|
49
|
+
if (token)
|
|
50
|
+
headers['Authorization'] = `Bearer ${token}`;
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
const res = await fetch(url.toString(), {
|
|
54
|
+
headers,
|
|
55
|
+
signal: controller.signal,
|
|
56
|
+
});
|
|
57
|
+
return res;
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
if (error.name === 'AbortError') {
|
|
61
|
+
throw new Error(`Request timed out after ${timeout / 1000}s — check your connection`);
|
|
62
|
+
}
|
|
63
|
+
throw wrapNetworkError(error);
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
clearTimeout(timer);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export async function apiPost(path, body, options) {
|
|
70
|
+
const url = buildUrl(path);
|
|
71
|
+
const timeout = options?.timeout ?? DEFAULT_TIMEOUT_MS;
|
|
72
|
+
const controller = new AbortController();
|
|
73
|
+
const timer = setTimeout(() => controller.abort(), timeout);
|
|
74
|
+
const headers = {
|
|
75
|
+
'Accept': 'application/json',
|
|
76
|
+
'Content-Type': 'application/json',
|
|
77
|
+
'X-Source': 'cli',
|
|
78
|
+
};
|
|
79
|
+
if (options?.auth !== false) {
|
|
80
|
+
const token = await getAuthToken();
|
|
81
|
+
if (token) {
|
|
82
|
+
headers['Authorization'] = `Bearer ${token}`;
|
|
83
|
+
}
|
|
84
|
+
else if (options?.auth === true) {
|
|
85
|
+
throw new Error('Authentication required. Run: myclaude login');
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
const res = await fetch(url.toString(), {
|
|
90
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
91
|
+
headers,
|
|
92
|
+
method: 'POST',
|
|
93
|
+
signal: controller.signal,
|
|
94
|
+
});
|
|
95
|
+
return res;
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
if (error.name === 'AbortError') {
|
|
99
|
+
throw new Error(`Request timed out after ${timeout / 1000}s — check your connection`);
|
|
100
|
+
}
|
|
101
|
+
throw wrapNetworkError(error);
|
|
102
|
+
}
|
|
103
|
+
finally {
|
|
104
|
+
clearTimeout(timer);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/** Convert raw network errors into human-readable messages */
|
|
108
|
+
function wrapNetworkError(error) {
|
|
109
|
+
const msg = error.message || '';
|
|
110
|
+
if (msg.includes('ECONNREFUSED')) {
|
|
111
|
+
return new Error('Cannot reach myClaude API — is the server running?');
|
|
112
|
+
}
|
|
113
|
+
if (msg.includes('ENOTFOUND') || msg.includes('getaddrinfo')) {
|
|
114
|
+
return new Error('DNS resolution failed — check your internet connection');
|
|
115
|
+
}
|
|
116
|
+
if (msg.includes('CERT') || msg.includes('SSL')) {
|
|
117
|
+
return new Error('SSL/TLS error — certificate verification failed');
|
|
118
|
+
}
|
|
119
|
+
return new Error(`Network error: ${msg}`);
|
|
120
|
+
}
|
|
121
|
+
async function getAuthToken() {
|
|
122
|
+
const config = readConfig();
|
|
123
|
+
if (!config?.email)
|
|
124
|
+
return null;
|
|
125
|
+
return getValidToken(config.email);
|
|
126
|
+
}
|
|
127
|
+
export async function requireAuth() {
|
|
128
|
+
const token = await getAuthToken();
|
|
129
|
+
if (!token) {
|
|
130
|
+
throw new Error('Authentication required. Run: myclaude login');
|
|
131
|
+
}
|
|
132
|
+
return token;
|
|
133
|
+
}
|
|
134
|
+
export { DEFAULT_TIMEOUT_MS, MAX_TIMEOUT_MS };
|
|
135
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/core/api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI authentication via myClaude backend.
|
|
3
|
+
*
|
|
4
|
+
* Token refresh goes through myclaude.sh/api/cli/auth/refresh
|
|
5
|
+
* so the Firebase API key NEVER leaves the server.
|
|
6
|
+
*
|
|
7
|
+
* The idToken is NEVER stored on disk (DC20) — only the
|
|
8
|
+
* refreshToken is persisted in the keychain/credentials file.
|
|
9
|
+
*/
|
|
10
|
+
export interface AuthResult {
|
|
11
|
+
idToken: string;
|
|
12
|
+
refreshToken: string;
|
|
13
|
+
uid: string;
|
|
14
|
+
email: string;
|
|
15
|
+
}
|
|
16
|
+
export interface TokenRefreshResult {
|
|
17
|
+
idToken: string;
|
|
18
|
+
refreshToken: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function refreshToken(refreshTkn: string): Promise<TokenRefreshResult>;
|
|
21
|
+
/**
|
|
22
|
+
* Get a valid idToken for API calls.
|
|
23
|
+
* Uses in-memory cache first, then refreshes from keychain.
|
|
24
|
+
* Returns null if not logged in.
|
|
25
|
+
*/
|
|
26
|
+
export declare function getValidToken(email: string): Promise<string | null>;
|
|
27
|
+
export declare function logout(): Promise<void>;
|
|
28
|
+
export declare class AuthError extends Error {
|
|
29
|
+
constructor(message: string);
|
|
30
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { deleteToken, getToken, storeToken } from '../utils/keychain.js';
|
|
2
|
+
import { getBaseUrl } from './api.js';
|
|
3
|
+
// FIX H1: In-memory token cache to avoid multiple refreshes per process
|
|
4
|
+
let cachedIdToken = null;
|
|
5
|
+
let cachedTokenExpiry = 0;
|
|
6
|
+
export async function refreshToken(refreshTkn) {
|
|
7
|
+
const baseUrl = getBaseUrl();
|
|
8
|
+
let response;
|
|
9
|
+
try {
|
|
10
|
+
response = await fetch(`${baseUrl}/api/cli/auth/refresh`, {
|
|
11
|
+
body: JSON.stringify({ refreshToken: refreshTkn }),
|
|
12
|
+
headers: {
|
|
13
|
+
'Content-Type': 'application/json',
|
|
14
|
+
'X-Source': 'cli',
|
|
15
|
+
},
|
|
16
|
+
method: 'POST',
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
// FIX M3: distinguish network errors from auth errors
|
|
21
|
+
throw new AuthError('Cannot reach myClaude servers. Check your internet connection.');
|
|
22
|
+
}
|
|
23
|
+
if (!response.ok) {
|
|
24
|
+
throw new AuthError('Session expired. Run: myclaude login');
|
|
25
|
+
}
|
|
26
|
+
const data = await response.json();
|
|
27
|
+
return {
|
|
28
|
+
idToken: data.idToken,
|
|
29
|
+
refreshToken: data.refreshToken,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get a valid idToken for API calls.
|
|
34
|
+
* Uses in-memory cache first, then refreshes from keychain.
|
|
35
|
+
* Returns null if not logged in.
|
|
36
|
+
*/
|
|
37
|
+
export async function getValidToken(email) {
|
|
38
|
+
// FIX H1: return cached token if still valid
|
|
39
|
+
if (cachedIdToken && Date.now() < cachedTokenExpiry) {
|
|
40
|
+
return cachedIdToken;
|
|
41
|
+
}
|
|
42
|
+
const stored = await getToken(email);
|
|
43
|
+
if (!stored)
|
|
44
|
+
return null;
|
|
45
|
+
try {
|
|
46
|
+
const result = await refreshToken(stored);
|
|
47
|
+
// Update the stored refresh token (rotation)
|
|
48
|
+
await storeToken(email, result.refreshToken);
|
|
49
|
+
// Cache the new token
|
|
50
|
+
cachedIdToken = result.idToken;
|
|
51
|
+
cachedTokenExpiry = Date.now() + 55 * 60 * 1000;
|
|
52
|
+
return result.idToken;
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
cachedIdToken = null;
|
|
56
|
+
cachedTokenExpiry = 0;
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export async function logout() {
|
|
61
|
+
cachedIdToken = null;
|
|
62
|
+
cachedTokenExpiry = 0;
|
|
63
|
+
await deleteToken();
|
|
64
|
+
}
|
|
65
|
+
export class AuthError extends Error {
|
|
66
|
+
constructor(message) {
|
|
67
|
+
super(message);
|
|
68
|
+
this.name = 'AuthError';
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/core/auth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAC,MAAM,sBAAsB,CAAA;AACtE,OAAO,EAAC,UAAU,EAAC,MAAM,UAAU,CAAA;AAwBnC,wEAAwE;AACxE,IAAI,aAAa,GAAkB,IAAI,CAAA;AACvC,IAAI,iBAAiB,GAAG,CAAC,CAAA;AAEzB,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,UAAkB;IACnD,MAAM,OAAO,GAAG,UAAU,EAAE,CAAA;IAE5B,IAAI,QAAkB,CAAA;IACtB,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,uBAAuB,EAAE;YACxD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAC,YAAY,EAAE,UAAU,EAAC,CAAC;YAChD,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,UAAU,EAAE,KAAK;aAClB;YACD,MAAM,EAAE,MAAM;SACf,CAAC,CAAA;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,sDAAsD;QACtD,MAAM,IAAI,SAAS,CACjB,gEAAgE,CACjE,CAAA;IACH,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,SAAS,CAAC,sCAAsC,CAAC,CAAA;IAC7D,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAA4B,CAAA;IAC5D,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,YAAY,EAAE,IAAI,CAAC,YAAY;KAChC,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAa;IAC/C,6CAA6C;IAC7C,IAAI,aAAa,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,iBAAiB,EAAE,CAAC;QACpD,OAAO,aAAa,CAAA;IACtB,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAA;IACpC,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IAExB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAA;QACzC,6CAA6C;QAC7C,MAAM,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,YAAY,CAAC,CAAA;QAC5C,sBAAsB;QACtB,aAAa,GAAG,MAAM,CAAC,OAAO,CAAA;QAC9B,iBAAiB,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;QAC/C,OAAO,MAAM,CAAC,OAAO,CAAA;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,aAAa,GAAG,IAAI,CAAA;QACpB,iBAAiB,GAAG,CAAC,CAAA;QACrB,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM;IAC1B,aAAa,GAAG,IAAI,CAAA;IACpB,iBAAiB,GAAG,CAAC,CAAA;IACrB,MAAM,WAAW,EAAE,CAAA;AACrB,CAAC;AAED,MAAM,OAAO,SAAU,SAAQ,KAAK;IAClC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,WAAW,CAAA;IACzB,CAAC;CACF"}
|