@swttch/extend-kit 0.3.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.
Files changed (42) hide show
  1. package/README.ko.md +445 -0
  2. package/README.md +445 -0
  3. package/dist/battery/api/client.d.ts +12 -0
  4. package/dist/battery/api/client.js +54 -0
  5. package/dist/battery/api/client.js.map +1 -0
  6. package/dist/battery/api/index.d.ts +3 -0
  7. package/dist/battery/api/index.js +3 -0
  8. package/dist/battery/api/index.js.map +1 -0
  9. package/dist/battery/api/oauth.d.ts +8 -0
  10. package/dist/battery/api/oauth.js +22 -0
  11. package/dist/battery/api/oauth.js.map +1 -0
  12. package/dist/battery/api/types.d.ts +49 -0
  13. package/dist/battery/api/types.js +2 -0
  14. package/dist/battery/api/types.js.map +1 -0
  15. package/dist/battery/auth/file-store.d.ts +2 -0
  16. package/dist/battery/auth/file-store.js +21 -0
  17. package/dist/battery/auth/file-store.js.map +1 -0
  18. package/dist/battery/auth/index.d.ts +6 -0
  19. package/dist/battery/auth/index.js +23 -0
  20. package/dist/battery/auth/index.js.map +1 -0
  21. package/dist/battery/auth/keychain.d.ts +2 -0
  22. package/dist/battery/auth/keychain.js +21 -0
  23. package/dist/battery/auth/keychain.js.map +1 -0
  24. package/dist/battery/auth/types.d.ts +16 -0
  25. package/dist/battery/auth/types.js +2 -0
  26. package/dist/battery/auth/types.js.map +1 -0
  27. package/dist/battery/errors.d.ts +12 -0
  28. package/dist/battery/errors.js +20 -0
  29. package/dist/battery/errors.js.map +1 -0
  30. package/dist/battery/index.d.ts +14 -0
  31. package/dist/battery/index.js +13 -0
  32. package/dist/battery/index.js.map +1 -0
  33. package/dist/cli/index.d.ts +2 -0
  34. package/dist/cli/index.js +79 -0
  35. package/dist/cli/index.js.map +1 -0
  36. package/dist/cli/oauth.d.ts +2 -0
  37. package/dist/cli/oauth.js +63 -0
  38. package/dist/cli/oauth.js.map +1 -0
  39. package/dist/index.d.ts +15 -0
  40. package/dist/index.js +18 -0
  41. package/dist/index.js.map +1 -0
  42. package/package.json +57 -0
@@ -0,0 +1,2 @@
1
+ import type { ClaudeCredentials } from './types.js';
2
+ export declare function readKeychainCredentials(): Promise<ClaudeCredentials>;
@@ -0,0 +1,21 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ const execFileAsync = promisify(execFile);
4
+ const SERVICE_NAME = 'Claude Code-credentials';
5
+ async function getOsUsername() {
6
+ const { stdout } = await execFileAsync('whoami');
7
+ return stdout.trim();
8
+ }
9
+ export async function readKeychainCredentials() {
10
+ const account = await getOsUsername();
11
+ const { stdout } = await execFileAsync('security', [
12
+ 'find-generic-password',
13
+ '-s', SERVICE_NAME,
14
+ '-a', account,
15
+ '-w',
16
+ ]);
17
+ const raw = stdout.trim();
18
+ const parsed = JSON.parse(raw);
19
+ return parsed;
20
+ }
21
+ //# sourceMappingURL=keychain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keychain.js","sourceRoot":"","sources":["../../../src/battery/auth/keychain.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAGtC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE1C,MAAM,YAAY,GAAG,yBAAyB,CAAC;AAE/C,KAAK,UAAU,aAAa;IAC1B,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC;IACjD,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;AACvB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB;IAC3C,MAAM,OAAO,GAAG,MAAM,aAAa,EAAE,CAAC;IACtC,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE;QACjD,uBAAuB;QACvB,IAAI,EAAE,YAAY;QAClB,IAAI,EAAE,OAAO;QACb,IAAI;KACL,CAAC,CAAC;IAEH,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAsB,CAAC;IACpD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,16 @@
1
+ export interface ClaudeOAuthCredentials {
2
+ accessToken: string;
3
+ refreshToken: string;
4
+ expiresAt: number;
5
+ scopes: string[];
6
+ subscriptionType: string;
7
+ rateLimitTier: string;
8
+ }
9
+ export interface ClaudeCredentials {
10
+ claudeAiOauth: ClaudeOAuthCredentials;
11
+ organizationUuid: string;
12
+ }
13
+ export interface ApiKeyAuth {
14
+ apiKey: string;
15
+ }
16
+ export type ClientAuth = string | ApiKeyAuth;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/battery/auth/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ export declare class CcbError extends Error {
2
+ readonly code: string;
3
+ readonly hint?: string | undefined;
4
+ constructor(message: string, code: string, hint?: string | undefined);
5
+ toJSON(): {
6
+ error: {
7
+ hint?: string | undefined;
8
+ code: string;
9
+ message: string;
10
+ };
11
+ };
12
+ }
@@ -0,0 +1,20 @@
1
+ export class CcbError extends Error {
2
+ code;
3
+ hint;
4
+ constructor(message, code, hint) {
5
+ super(message);
6
+ this.code = code;
7
+ this.hint = hint;
8
+ this.name = 'CcbError';
9
+ }
10
+ toJSON() {
11
+ return {
12
+ error: {
13
+ code: this.code,
14
+ message: this.message,
15
+ ...(this.hint && { hint: this.hint }),
16
+ },
17
+ };
18
+ }
19
+ }
20
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/battery/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,QAAS,SAAQ,KAAK;IAGf;IACA;IAHlB,YACE,OAAe,EACC,IAAY,EACZ,IAAa;QAE7B,KAAK,CAAC,OAAO,CAAC,CAAC;QAHC,SAAI,GAAJ,IAAI,CAAQ;QACZ,SAAI,GAAJ,IAAI,CAAS;QAG7B,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,CAAC;IAED,MAAM;QACJ,OAAO;YACL,KAAK,EAAE;gBACL,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;aACtC;SACF,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Battery — programmatic access to a locally logged-in Claude Code account.
3
+ *
4
+ * This is the original `claude-code-battery` package, folded into extend-kit.
5
+ * It reads the credentials Claude Code stores on this machine (keychain on
6
+ * macOS, a credentials file elsewhere) and calls Claude's account API with
7
+ * them, which is why it cannot be bundled into the plugin: it needs the
8
+ * user's own machine and their own login.
9
+ */
10
+ export { CcbError } from './errors.js';
11
+ export { getCredentials, getAccessToken, isTokenExpired, isApiKeyAuth } from './auth/index.js';
12
+ export type { ClaudeCredentials, ClaudeOAuthCredentials, ApiKeyAuth, ClientAuth } from './auth/index.js';
13
+ export { ClaudeCodeClient, OAuthApi } from './api/index.js';
14
+ export type { UsageResponse, UsageBucket, ExtraUsage, ProfileResponse, AccountInfo, OrganizationInfo, ApplicationInfo, } from './api/index.js';
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Battery — programmatic access to a locally logged-in Claude Code account.
3
+ *
4
+ * This is the original `claude-code-battery` package, folded into extend-kit.
5
+ * It reads the credentials Claude Code stores on this machine (keychain on
6
+ * macOS, a credentials file elsewhere) and calls Claude's account API with
7
+ * them, which is why it cannot be bundled into the plugin: it needs the
8
+ * user's own machine and their own login.
9
+ */
10
+ export { CcbError } from './errors.js';
11
+ export { getCredentials, getAccessToken, isTokenExpired, isApiKeyAuth } from './auth/index.js';
12
+ export { ClaudeCodeClient, OAuthApi } from './api/index.js';
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/battery/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG/F,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env node
2
+ import { getCredentials, getAccessToken } from '../battery/auth/index.js';
3
+ import { ClaudeCodeClient } from '../battery/api/index.js';
4
+ import { oauthCommand } from './oauth.js';
5
+ import { CcbError } from '../battery/errors.js';
6
+ import { readFileSync } from 'node:fs';
7
+ import { fileURLToPath } from 'node:url';
8
+ import { dirname, resolve } from 'node:path';
9
+ const __dirname = dirname(fileURLToPath(import.meta.url));
10
+ const pkg = JSON.parse(readFileSync(resolve(__dirname, '../../package.json'), 'utf-8'));
11
+ const VERSION = pkg.version;
12
+ const args = process.argv.slice(2);
13
+ const command = args.filter((a) => !a.startsWith('-'));
14
+ const flags = new Set(args.filter((a) => a.startsWith('-')));
15
+ const jsonOutput = flags.has('--json');
16
+ async function createClient() {
17
+ const credentials = await getCredentials();
18
+ const token = getAccessToken(credentials);
19
+ return new ClaudeCodeClient(token);
20
+ }
21
+ async function run() {
22
+ const [module, ...subcommand] = command;
23
+ if (flags.has('-v') || flags.has('--version')) {
24
+ console.log(VERSION);
25
+ return;
26
+ }
27
+ if (!module || flags.has('-h') || flags.has('--help')) {
28
+ console.log(`ccb v${VERSION} — Claude Code account CLI, from @swttch/extend-kit
29
+
30
+ Usage: ccb <command> [options]
31
+
32
+ Commands:
33
+ oauth usage Show usage limits
34
+ oauth profile Show account profile
35
+
36
+ Options:
37
+ --json Output as JSON
38
+ -h, --help Show help
39
+ -v, --version Show version`);
40
+ return;
41
+ }
42
+ const client = await createClient();
43
+ switch (module) {
44
+ case 'oauth':
45
+ await oauthCommand(client, subcommand, jsonOutput);
46
+ break;
47
+ default:
48
+ console.error(`Unknown module: ${module}`);
49
+ process.exit(1);
50
+ }
51
+ }
52
+ run().catch((err) => {
53
+ if (jsonOutput) {
54
+ if (err instanceof CcbError) {
55
+ console.error(JSON.stringify(err.toJSON(), null, 2));
56
+ }
57
+ else {
58
+ console.error(JSON.stringify({
59
+ error: {
60
+ code: 'unknown_error',
61
+ message: err instanceof Error ? err.message : String(err),
62
+ },
63
+ }, null, 2));
64
+ }
65
+ }
66
+ else {
67
+ if (err instanceof CcbError) {
68
+ console.error(`Error: ${err.message}`);
69
+ if (err.hint) {
70
+ console.error(`Hint: ${err.hint}`);
71
+ }
72
+ }
73
+ else {
74
+ console.error(err instanceof Error ? err.message : String(err));
75
+ }
76
+ }
77
+ process.exit(1);
78
+ });
79
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { ClaudeCodeClient } from '../battery/api/index.js';
2
+ export declare function oauthCommand(client: ClaudeCodeClient, subcommand: string[], jsonOutput: boolean): Promise<void>;
@@ -0,0 +1,63 @@
1
+ function printJson(data) {
2
+ console.log(JSON.stringify(data, null, 2));
3
+ }
4
+ function formatUsage(data) {
5
+ for (const [key, value] of Object.entries(data)) {
6
+ if (value === null)
7
+ continue;
8
+ if (key === 'extra_usage')
9
+ continue;
10
+ if (typeof value === 'object' && value !== null && 'utilization' in value) {
11
+ const bucket = value;
12
+ const label = key.replace(/_/g, ' ');
13
+ const resets = bucket.resets_at
14
+ ? ` (resets ${new Date(bucket.resets_at).toLocaleString()})`
15
+ : '';
16
+ console.log(` ${label}: ${bucket.utilization}%${resets}`);
17
+ }
18
+ }
19
+ const extra = data.extra_usage;
20
+ if (extra) {
21
+ console.log(` extra usage: ${extra.is_enabled ? 'enabled' : 'disabled'}`);
22
+ }
23
+ }
24
+ function formatProfile(data) {
25
+ const account = data.account;
26
+ const org = data.organization;
27
+ console.log(` name: ${account.display_name}`);
28
+ console.log(` email: ${account.email}`);
29
+ console.log(` plan: ${org.organization_type}`);
30
+ console.log(` org: ${org.name}`);
31
+ console.log(` status: ${org.subscription_status}`);
32
+ }
33
+ export async function oauthCommand(client, subcommand, jsonOutput) {
34
+ const endpoint = subcommand[0];
35
+ switch (endpoint) {
36
+ case 'usage': {
37
+ const usage = await client.oauth.getUsage();
38
+ if (jsonOutput) {
39
+ printJson(usage);
40
+ }
41
+ else {
42
+ console.log('Usage:');
43
+ formatUsage(usage);
44
+ }
45
+ break;
46
+ }
47
+ case 'profile': {
48
+ const profile = await client.oauth.getProfile();
49
+ if (jsonOutput) {
50
+ printJson(profile);
51
+ }
52
+ else {
53
+ console.log('Profile:');
54
+ formatProfile(profile);
55
+ }
56
+ break;
57
+ }
58
+ default:
59
+ console.error(`Unknown oauth command: ${endpoint}`);
60
+ process.exit(1);
61
+ }
62
+ }
63
+ //# sourceMappingURL=oauth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/cli/oauth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * @swttch/extend-kit — the tools Swttch needs that cannot ship inside the
3
+ * plugin bundle, and so are installed on the user's own machine instead.
4
+ *
5
+ * Two things force a tool out here: it needs the user's local credentials
6
+ * (battery reads the Claude Code login), or it needs native binaries the
7
+ * plugin cannot carry (speech-to-text). Both are usable on their own, from a
8
+ * terminal or as a library — the plugin is just one caller among others.
9
+ *
10
+ * Everything battery used to export is re-exported flat, unprefixed, so code
11
+ * written against `claude-code-battery` keeps compiling after switching the
12
+ * import to this package.
13
+ */
14
+ export * from './battery/index.js';
15
+ export * as battery from './battery/index.js';
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @swttch/extend-kit — the tools Swttch needs that cannot ship inside the
3
+ * plugin bundle, and so are installed on the user's own machine instead.
4
+ *
5
+ * Two things force a tool out here: it needs the user's local credentials
6
+ * (battery reads the Claude Code login), or it needs native binaries the
7
+ * plugin cannot carry (speech-to-text). Both are usable on their own, from a
8
+ * terminal or as a library — the plugin is just one caller among others.
9
+ *
10
+ * Everything battery used to export is re-exported flat, unprefixed, so code
11
+ * written against `claude-code-battery` keeps compiling after switching the
12
+ * import to this package.
13
+ */
14
+ export * from './battery/index.js';
15
+ // Namespaced access, for callers who would rather be explicit about which
16
+ // tool they are reaching for — `import { battery } from '@swttch/extend-kit'`.
17
+ export * as battery from './battery/index.js';
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,cAAc,oBAAoB,CAAC;AAEnC,0EAA0E;AAC1E,+EAA+E;AAC/E,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@swttch/extend-kit",
3
+ "version": "0.3.0",
4
+ "description": "Companion tools for Swttch that live outside the plugin bundle: Claude Code account/usage SDK and the ccb CLI.",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "default": "./dist/index.js"
12
+ },
13
+ "./battery": {
14
+ "types": "./dist/battery/index.d.ts",
15
+ "default": "./dist/battery/index.js"
16
+ },
17
+ "./cli": "./dist/cli/index.js"
18
+ },
19
+ "bin": {
20
+ "ccb": "dist/cli/index.js"
21
+ },
22
+ "scripts": {
23
+ "build": "tsc",
24
+ "dev": "tsc --watch",
25
+ "lint": "tsc --noEmit",
26
+ "test": "node --test dist/**/*.test.js"
27
+ },
28
+ "keywords": [
29
+ "claude",
30
+ "claude-code",
31
+ "swttch",
32
+ "sdk",
33
+ "cli"
34
+ ],
35
+ "license": "MIT",
36
+ "author": "yhk1038",
37
+ "repository": {
38
+ "type": "git",
39
+ "url": "git+https://github.com/Swttch/extend-kit.git"
40
+ },
41
+ "publishConfig": {
42
+ "access": "public"
43
+ },
44
+ "files": [
45
+ "dist",
46
+ "!dist/**/*.test.js",
47
+ "!dist/**/*.test.d.ts",
48
+ "!dist/**/*.test.js.map"
49
+ ],
50
+ "engines": {
51
+ "node": ">=20"
52
+ },
53
+ "devDependencies": {
54
+ "@types/node": "^25.5.0",
55
+ "typescript": "^6.0.2"
56
+ }
57
+ }