@n24q02m/hull 0.0.0-stage → 0.4.0-beta.9
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/LICENSE +201 -0
- package/README.md +166 -2
- package/build/auth/credential-form.d.ts +163 -0
- package/build/auth/credential-form.d.ts.map +1 -0
- package/build/auth/credential-form.js +1869 -0
- package/build/auth/credential-form.js.map +1 -0
- package/build/auth/delegated-oauth-app.d.ts +90 -0
- package/build/auth/delegated-oauth-app.d.ts.map +1 -0
- package/build/auth/delegated-oauth-app.js +881 -0
- package/build/auth/delegated-oauth-app.js.map +1 -0
- package/build/auth/index.d.ts +12 -0
- package/build/auth/index.d.ts.map +1 -0
- package/build/auth/index.js +12 -0
- package/build/auth/index.js.map +1 -0
- package/build/auth/local-oauth-app.d.ts +152 -0
- package/build/auth/local-oauth-app.d.ts.map +1 -0
- package/build/auth/local-oauth-app.js +975 -0
- package/build/auth/local-oauth-app.js.map +1 -0
- package/build/auth/relay-login.d.ts +46 -0
- package/build/auth/relay-login.d.ts.map +1 -0
- package/build/auth/relay-login.js +197 -0
- package/build/auth/relay-login.js.map +1 -0
- package/build/auth/router.d.ts +18 -0
- package/build/auth/router.d.ts.map +1 -0
- package/build/auth/router.js +62 -0
- package/build/auth/router.js.map +1 -0
- package/build/auth/session-store.d.ts +49 -0
- package/build/auth/session-store.d.ts.map +1 -0
- package/build/auth/session-store.js +94 -0
- package/build/auth/session-store.js.map +1 -0
- package/build/auth/stable-sub.d.ts +27 -0
- package/build/auth/stable-sub.d.ts.map +1 -0
- package/build/auth/stable-sub.js +38 -0
- package/build/auth/stable-sub.js.map +1 -0
- package/build/auth/well-known.d.ts +4 -0
- package/build/auth/well-known.d.ts.map +1 -0
- package/build/auth/well-known.js +26 -0
- package/build/auth/well-known.js.map +1 -0
- package/build/cli/build-cli.d.ts +97 -0
- package/build/cli/build-cli.d.ts.map +1 -0
- package/build/cli/build-cli.js +309 -0
- package/build/cli/build-cli.js.map +1 -0
- package/build/cli/index.d.ts +2 -0
- package/build/cli/index.d.ts.map +1 -0
- package/build/cli/index.js +2 -0
- package/build/cli/index.js.map +1 -0
- package/build/crypto/aes.d.ts +8 -0
- package/build/crypto/aes.d.ts.map +1 -0
- package/build/crypto/aes.js +27 -0
- package/build/crypto/aes.js.map +1 -0
- package/build/crypto/ecdh.d.ts +5 -0
- package/build/crypto/ecdh.d.ts.map +1 -0
- package/build/crypto/ecdh.js +16 -0
- package/build/crypto/ecdh.js.map +1 -0
- package/build/crypto/index.d.ts +4 -0
- package/build/crypto/index.d.ts.map +1 -0
- package/build/crypto/index.js +4 -0
- package/build/crypto/index.js.map +1 -0
- package/build/crypto/kdf.d.ts +15 -0
- package/build/crypto/kdf.d.ts.map +1 -0
- package/build/crypto/kdf.js +26 -0
- package/build/crypto/kdf.js.map +1 -0
- package/build/index.d.ts +19 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +28 -0
- package/build/index.js.map +1 -0
- package/build/lifecycle/lock.d.ts +68 -0
- package/build/lifecycle/lock.d.ts.map +1 -0
- package/build/lifecycle/lock.js +173 -0
- package/build/lifecycle/lock.js.map +1 -0
- package/build/oauth/cache.d.ts +22 -0
- package/build/oauth/cache.d.ts.map +1 -0
- package/build/oauth/cache.js +24 -0
- package/build/oauth/cache.js.map +1 -0
- package/build/oauth/index.d.ts +6 -0
- package/build/oauth/index.d.ts.map +1 -0
- package/build/oauth/index.js +6 -0
- package/build/oauth/index.js.map +1 -0
- package/build/oauth/jwt-issuer.d.ts +87 -0
- package/build/oauth/jwt-issuer.d.ts.map +1 -0
- package/build/oauth/jwt-issuer.js +205 -0
- package/build/oauth/jwt-issuer.js.map +1 -0
- package/build/oauth/pkce.d.ts +10 -0
- package/build/oauth/pkce.d.ts.map +1 -0
- package/build/oauth/pkce.js +34 -0
- package/build/oauth/pkce.js.map +1 -0
- package/build/oauth/provider.d.ts +52 -0
- package/build/oauth/provider.d.ts.map +1 -0
- package/build/oauth/provider.js +98 -0
- package/build/oauth/provider.js.map +1 -0
- package/build/oauth/user-store.d.ts +25 -0
- package/build/oauth/user-store.d.ts.map +1 -0
- package/build/oauth/user-store.js +85 -0
- package/build/oauth/user-store.js.map +1 -0
- package/build/relay/browser.d.ts +15 -0
- package/build/relay/browser.d.ts.map +1 -0
- package/build/relay/browser.js +121 -0
- package/build/relay/browser.js.map +1 -0
- package/build/relay/client.d.ts +36 -0
- package/build/relay/client.d.ts.map +1 -0
- package/build/relay/client.js +135 -0
- package/build/relay/client.js.map +1 -0
- package/build/relay/session.d.ts +12 -0
- package/build/relay/session.d.ts.map +1 -0
- package/build/relay/session.js +55 -0
- package/build/relay/session.js.map +1 -0
- package/build/relay/tool-helpers.d.ts +85 -0
- package/build/relay/tool-helpers.d.ts.map +1 -0
- package/build/relay/tool-helpers.js +103 -0
- package/build/relay/tool-helpers.js.map +1 -0
- package/build/relay/wordlist.d.ts +2 -0
- package/build/relay/wordlist.d.ts.map +1 -0
- package/build/relay/wordlist.js +7782 -0
- package/build/relay/wordlist.js.map +1 -0
- package/build/schema/types.d.ts +67 -0
- package/build/schema/types.d.ts.map +1 -0
- package/build/schema/types.js +2 -0
- package/build/schema/types.js.map +1 -0
- package/build/storage/atomic-write.d.ts +8 -0
- package/build/storage/atomic-write.d.ts.map +1 -0
- package/build/storage/atomic-write.js +26 -0
- package/build/storage/atomic-write.js.map +1 -0
- package/build/storage/backends.d.ts +74 -0
- package/build/storage/backends.d.ts.map +1 -0
- package/build/storage/backends.js +193 -0
- package/build/storage/backends.js.map +1 -0
- package/build/storage/config-file.d.ts +35 -0
- package/build/storage/config-file.d.ts.map +1 -0
- package/build/storage/config-file.js +259 -0
- package/build/storage/config-file.js.map +1 -0
- package/build/storage/credential-store.d.ts +71 -0
- package/build/storage/credential-store.d.ts.map +1 -0
- package/build/storage/credential-store.js +91 -0
- package/build/storage/credential-store.js.map +1 -0
- package/build/storage/data-dir.d.ts +58 -0
- package/build/storage/data-dir.d.ts.map +1 -0
- package/build/storage/data-dir.js +79 -0
- package/build/storage/data-dir.js.map +1 -0
- package/build/storage/encryption.d.ts +9 -0
- package/build/storage/encryption.d.ts.map +1 -0
- package/build/storage/encryption.js +27 -0
- package/build/storage/encryption.js.map +1 -0
- package/build/storage/home-dir.d.ts +11 -0
- package/build/storage/home-dir.d.ts.map +1 -0
- package/build/storage/home-dir.js +18 -0
- package/build/storage/home-dir.js.map +1 -0
- package/build/storage/index.d.ts +12 -0
- package/build/storage/index.d.ts.map +1 -0
- package/build/storage/index.js +15 -0
- package/build/storage/index.js.map +1 -0
- package/build/storage/machine-id.d.ts +4 -0
- package/build/storage/machine-id.d.ts.map +1 -0
- package/build/storage/machine-id.js +73 -0
- package/build/storage/machine-id.js.map +1 -0
- package/build/storage/mode.d.ts +23 -0
- package/build/storage/mode.d.ts.map +1 -0
- package/build/storage/mode.js +46 -0
- package/build/storage/mode.js.map +1 -0
- package/build/storage/per-plugin-store.d.ts +65 -0
- package/build/storage/per-plugin-store.d.ts.map +1 -0
- package/build/storage/per-plugin-store.js +194 -0
- package/build/storage/per-plugin-store.js.map +1 -0
- package/build/storage/resolver.d.ts +7 -0
- package/build/storage/resolver.d.ts.map +1 -0
- package/build/storage/resolver.js +38 -0
- package/build/storage/resolver.js.map +1 -0
- package/build/storage/session-lock.d.ts +19 -0
- package/build/storage/session-lock.d.ts.map +1 -0
- package/build/storage/session-lock.js +105 -0
- package/build/storage/session-lock.js.map +1 -0
- package/build/token-auth/authenticator.d.ts +70 -0
- package/build/token-auth/authenticator.d.ts.map +1 -0
- package/build/token-auth/authenticator.js +146 -0
- package/build/token-auth/authenticator.js.map +1 -0
- package/build/token-auth/cli.d.ts +38 -0
- package/build/token-auth/cli.d.ts.map +1 -0
- package/build/token-auth/cli.js +192 -0
- package/build/token-auth/cli.js.map +1 -0
- package/build/token-auth/context.d.ts +30 -0
- package/build/token-auth/context.d.ts.map +1 -0
- package/build/token-auth/context.js +32 -0
- package/build/token-auth/context.js.map +1 -0
- package/build/token-auth/http-guard.d.ts +26 -0
- package/build/token-auth/http-guard.d.ts.map +1 -0
- package/build/token-auth/http-guard.js +51 -0
- package/build/token-auth/http-guard.js.map +1 -0
- package/build/token-auth/index.d.ts +14 -0
- package/build/token-auth/index.d.ts.map +1 -0
- package/build/token-auth/index.js +14 -0
- package/build/token-auth/index.js.map +1 -0
- package/build/token-auth/limiter.d.ts +20 -0
- package/build/token-auth/limiter.d.ts.map +1 -0
- package/build/token-auth/limiter.js +41 -0
- package/build/token-auth/limiter.js.map +1 -0
- package/build/token-auth/loopback.d.ts +17 -0
- package/build/token-auth/loopback.d.ts.map +1 -0
- package/build/token-auth/loopback.js +62 -0
- package/build/token-auth/loopback.js.map +1 -0
- package/build/token-auth/py-compat.d.ts +24 -0
- package/build/token-auth/py-compat.d.ts.map +1 -0
- package/build/token-auth/py-compat.js +76 -0
- package/build/token-auth/py-compat.js.map +1 -0
- package/build/token-auth/tokens.d.ts +36 -0
- package/build/token-auth/tokens.d.ts.map +1 -0
- package/build/token-auth/tokens.js +115 -0
- package/build/token-auth/tokens.js.map +1 -0
- package/build/token-auth/users.d.ts +62 -0
- package/build/token-auth/users.d.ts.map +1 -0
- package/build/token-auth/users.js +174 -0
- package/build/token-auth/users.js.map +1 -0
- package/build/transport/cache.d.ts +19 -0
- package/build/transport/cache.d.ts.map +1 -0
- package/build/transport/cache.js +76 -0
- package/build/transport/cache.js.map +1 -0
- package/build/transport/index.d.ts +5 -0
- package/build/transport/index.d.ts.map +1 -0
- package/build/transport/index.js +4 -0
- package/build/transport/index.js.map +1 -0
- package/build/transport/local-server.d.ts +173 -0
- package/build/transport/local-server.d.ts.map +1 -0
- package/build/transport/local-server.js +457 -0
- package/build/transport/local-server.js.map +1 -0
- package/build/transport/oauth-middleware.d.ts +45 -0
- package/build/transport/oauth-middleware.d.ts.map +1 -0
- package/build/transport/oauth-middleware.js +86 -0
- package/build/transport/oauth-middleware.js.map +1 -0
- package/build/transport/streamable-http.d.ts +54 -0
- package/build/transport/streamable-http.d.ts.map +1 -0
- package/build/transport/streamable-http.js +57 -0
- package/build/transport/streamable-http.js.map +1 -0
- package/package.json +107 -4
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Derive a stable, opaque subject id from a workspace username.
|
|
3
|
+
*
|
|
4
|
+
* TypeScript port of core-py's ``stable_sub.py``. Output is byte-identical for
|
|
5
|
+
* ASCII usernames, locked by the shared ``crypto-vectors.json`` fixture.
|
|
6
|
+
*/
|
|
7
|
+
import { createHmac } from 'node:crypto';
|
|
8
|
+
// Used only when CREDENTIAL_SECRET is unset (single-user/dev): the sub stays
|
|
9
|
+
// stable, just predictable. Production multi-user always sets CREDENTIAL_SECRET.
|
|
10
|
+
const DEV_FALLBACK_KEY = Buffer.from('mcp-core-stable-sub-dev-salt', 'utf-8');
|
|
11
|
+
/**
|
|
12
|
+
* Derive a stable, opaque subject id from a workspace username.
|
|
13
|
+
*
|
|
14
|
+
* Same ``(serverName, normalized username)`` -> same ``sub``, so a returning
|
|
15
|
+
* user lands on the same per-``sub`` credential bucket instead of the random
|
|
16
|
+
* subject minted per ``/authorize``. The output shape (22 chars, urlsafe
|
|
17
|
+
* base64, no padding) matches ``randomBytes(16).toString('base64url')`` so
|
|
18
|
+
* downstream code cannot tell a stable sub from a random one.
|
|
19
|
+
*
|
|
20
|
+
* Normalization is ``trim().toLowerCase()``. Python's ``str.casefold()`` maps
|
|
21
|
+
* a few non-ASCII characters differently (``'ß'.casefold() == 'ss'``), so
|
|
22
|
+
* cross-language parity is guaranteed for ASCII usernames only; the divergence
|
|
23
|
+
* is asserted by a test in both languages.
|
|
24
|
+
*
|
|
25
|
+
* SECURITY: with a SHARED relay password the username is a PARTITION key, NOT a
|
|
26
|
+
* secret -- anyone who knows the password can submit any username and reach that
|
|
27
|
+
* bucket. Intentional for a trusted group; untrusted multi-tenant needs per-user
|
|
28
|
+
* secrets or delegated OAuth.
|
|
29
|
+
*/
|
|
30
|
+
export function deriveStableSub(username, serverName, credentialSecret) {
|
|
31
|
+
const normalized = username.trim().toLowerCase();
|
|
32
|
+
if (!normalized)
|
|
33
|
+
throw new Error('username must be non-empty');
|
|
34
|
+
const key = credentialSecret ? Buffer.from(credentialSecret, 'utf-8') : DEV_FALLBACK_KEY;
|
|
35
|
+
const digest = createHmac('sha256', key).update(`sub:${serverName}:${normalized}`, 'utf8').digest();
|
|
36
|
+
return digest.subarray(0, 16).toString('base64url');
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=stable-sub.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stable-sub.js","sourceRoot":"","sources":["../../src/auth/stable-sub.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,6EAA6E;AAC7E,iFAAiF;AACjF,MAAM,gBAAgB,GAAG,MAAM,CAAC,IAAI,CAAC,8BAA8B,EAAE,OAAO,CAAC,CAAA;AAE7E;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAgB,EAChB,UAAkB,EAClB,gBAA2C;IAE3C,MAAM,UAAU,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IAChD,IAAI,CAAC,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAA;IAC9D,MAAM,GAAG,GAAG,gBAAgB,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAA;IACxF,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,UAAU,IAAI,UAAU,EAAE,EAAE,MAAM,CAAC,CAAC,MAAM,EAAE,CAAA;IACnG,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;AACrD,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** OAuth 2.1 well-known metadata generators (RFC 8414 + RFC 9728). */
|
|
2
|
+
export declare function authorizationServerMetadata(issuerUrl: string): Record<string, unknown>;
|
|
3
|
+
export declare function protectedResourceMetadata(resource: string, authorizationServers: string[]): Record<string, unknown>;
|
|
4
|
+
//# sourceMappingURL=well-known.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"well-known.d.ts","sourceRoot":"","sources":["../../src/auth/well-known.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAgBtF;AAED,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,EAAE,oBAAoB,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAMnH"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** OAuth 2.1 well-known metadata generators (RFC 8414 + RFC 9728). */
|
|
2
|
+
export function authorizationServerMetadata(issuerUrl) {
|
|
3
|
+
return {
|
|
4
|
+
issuer: issuerUrl,
|
|
5
|
+
authorization_endpoint: `${issuerUrl}/authorize`,
|
|
6
|
+
token_endpoint: `${issuerUrl}/token`,
|
|
7
|
+
registration_endpoint: `${issuerUrl}/register`,
|
|
8
|
+
jwks_uri: `${issuerUrl}/.well-known/jwks.json`,
|
|
9
|
+
response_types_supported: ['code'],
|
|
10
|
+
grant_types_supported: ['authorization_code', 'refresh_token'],
|
|
11
|
+
code_challenge_methods_supported: ['S256'],
|
|
12
|
+
token_endpoint_auth_methods_supported: ['none'],
|
|
13
|
+
scopes_supported: ['offline_access'],
|
|
14
|
+
// RFC 9207 / SEP-2468: the AS returns the ``iss`` parameter in every
|
|
15
|
+
// authorization response so clients can defend against mix-up attacks.
|
|
16
|
+
authorization_response_iss_parameter_supported: true
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export function protectedResourceMetadata(resource, authorizationServers) {
|
|
20
|
+
return {
|
|
21
|
+
resource,
|
|
22
|
+
authorization_servers: authorizationServers,
|
|
23
|
+
bearer_methods_supported: ['header']
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=well-known.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"well-known.js","sourceRoot":"","sources":["../../src/auth/well-known.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,MAAM,UAAU,2BAA2B,CAAC,SAAiB;IAC3D,OAAO;QACL,MAAM,EAAE,SAAS;QACjB,sBAAsB,EAAE,GAAG,SAAS,YAAY;QAChD,cAAc,EAAE,GAAG,SAAS,QAAQ;QACpC,qBAAqB,EAAE,GAAG,SAAS,WAAW;QAC9C,QAAQ,EAAE,GAAG,SAAS,wBAAwB;QAC9C,wBAAwB,EAAE,CAAC,MAAM,CAAC;QAClC,qBAAqB,EAAE,CAAC,oBAAoB,EAAE,eAAe,CAAC;QAC9D,gCAAgC,EAAE,CAAC,MAAM,CAAC;QAC1C,qCAAqC,EAAE,CAAC,MAAM,CAAC;QAC/C,gBAAgB,EAAE,CAAC,gBAAgB,CAAC;QACpC,qEAAqE;QACrE,uEAAuE;QACvE,8CAA8C,EAAE,IAAI;KACrD,CAAA;AACH,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,QAAgB,EAAE,oBAA8B;IACxF,OAAO;QACL,QAAQ;QACR,qBAAqB,EAAE,oBAAoB;QAC3C,wBAAwB,EAAE,CAAC,QAAQ,CAAC;KACrC,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Console-script CLI builder shared by every TypeScript MCP server.
|
|
3
|
+
*
|
|
4
|
+
* TS counterpart of `mcp_core.build_cli` (core-py). `buildCli` wraps a
|
|
5
|
+
* server's existing `serve(argv) -> number | void` entry point with
|
|
6
|
+
* subcommand dispatch, without changing that entry point's behaviour for the
|
|
7
|
+
* two invocation shapes it already handles:
|
|
8
|
+
*
|
|
9
|
+
* - Bare invocation (`argv` empty) still means "start the server".
|
|
10
|
+
* - Any flag-prefixed argv (`--http` etc.) is passed through to `serve`
|
|
11
|
+
* byte-for-byte, so existing `--http` semantics are untouched -- except
|
|
12
|
+
* `-h`/`--help` (always) and `--version`/`-V` (only when `version` is set),
|
|
13
|
+
* which are intercepted here and never reach `serve`. Starting the server on
|
|
14
|
+
* those would hang in stdio mode instead of printing the requested output.
|
|
15
|
+
*
|
|
16
|
+
* A leading *positional* argv[0] is treated as a subcommand name -- either one
|
|
17
|
+
* of the reserved built-ins (`config`/`doctor`/`logout`/`relay`/`status`/`token`)
|
|
18
|
+
* or a server-specific one supplied via `extra` -- and is routed to its handler
|
|
19
|
+
* instead of `serve`. `status` and `logout` are top-level aliases of
|
|
20
|
+
* `config status` and `config delete` (same output and exit codes).
|
|
21
|
+
*
|
|
22
|
+
* `auth` is deliberately NOT a built-in: signing in is domain-specific (OAuth
|
|
23
|
+
* device code, bot token, API key paste, relay form, ...), so each server that
|
|
24
|
+
* needs it supplies its own `auth` handler via `extra`.
|
|
25
|
+
* STDOUT is the MCP protocol channel in stdio mode, so only this subcommand
|
|
26
|
+
* path prints to stdout; the `serve` path never touches stdout here.
|
|
27
|
+
*
|
|
28
|
+
* Built-in output convention: informational results (configured/not
|
|
29
|
+
* configured, session details, doctor's `[ok]`/`[warn]`/`[fail]` lines) go to
|
|
30
|
+
* stdout (`console.log`); failures and prompts (no active session, refused
|
|
31
|
+
* delete, corrupt config) go to stderr (`console.error`) alongside a non-zero
|
|
32
|
+
* return code. Credential *values* are never printed by any built-in -- only
|
|
33
|
+
* names/keys/status.
|
|
34
|
+
*/
|
|
35
|
+
/** A server's start entry point. Returns an exit code, or nothing for 0. */
|
|
36
|
+
export type ServeFn = (argv: string[]) => number | void | Promise<number | void>;
|
|
37
|
+
/**
|
|
38
|
+
* A subcommand handler. Receives the argv that follows the subcommand name
|
|
39
|
+
* (e.g. for `config status --yes` the handler gets `['status', '--yes']`) and
|
|
40
|
+
* returns the process exit code.
|
|
41
|
+
*/
|
|
42
|
+
export type CliHandler = (argv: string[]) => number | Promise<number>;
|
|
43
|
+
export interface BuildCliOptions {
|
|
44
|
+
/** The server's start entry point (bare/flag argv routes here). */
|
|
45
|
+
serve: ServeFn;
|
|
46
|
+
/**
|
|
47
|
+
* Server-specific subcommands. A name here overrides the reserved built-in
|
|
48
|
+
* of the same name (`config`/`doctor`/`logout`/`relay`/`status`/`token`), so a
|
|
49
|
+
* server can supply its own handler. This is also where a server provides
|
|
50
|
+
* `auth`, which is not a built-in because sign-in is domain-specific.
|
|
51
|
+
*/
|
|
52
|
+
extra?: Record<string, CliHandler>;
|
|
53
|
+
/** Powers `--version`/`-V`. When unset, those flags fall through to serve. */
|
|
54
|
+
version?: string;
|
|
55
|
+
/**
|
|
56
|
+
* Credential storage plugin slug (e.g. `"wet"`): decides where `config` and
|
|
57
|
+
* `doctor` read/write via `PerPluginStore`. Servers save credentials under
|
|
58
|
+
* this slug, not the console name, so the two must not be conflated. When
|
|
59
|
+
* omitted it defaults to `serverName` with a trailing `"-mcp"` stripped,
|
|
60
|
+
* which matches the wet/mnemo/crg convention; pass it explicitly when the
|
|
61
|
+
* slug differs (telegram saves under `"telegram"` though its console name
|
|
62
|
+
* is `"better-telegram-mcp"`).
|
|
63
|
+
*/
|
|
64
|
+
pluginName?: string;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Build the console-script entry point for one MCP server.
|
|
68
|
+
*
|
|
69
|
+
* `serverName` is the console/display name (e.g. `"wet-mcp"`): it names the
|
|
70
|
+
* program in help/usage and status lines, and keys relay session state and
|
|
71
|
+
* run mode (which servers store under their `SERVER_NAME`).
|
|
72
|
+
*
|
|
73
|
+
* `options.pluginName` is the credential storage slug that `PerPluginStore`
|
|
74
|
+
* keys on (e.g. `"wet"`): it decides where `config` and `doctor` read/write
|
|
75
|
+
* credentials. Servers save creds under this slug, not under the console
|
|
76
|
+
* name, so the two must not be conflated. When omitted it defaults to
|
|
77
|
+
* `serverName` with a trailing `"-mcp"` stripped, which matches the wet/
|
|
78
|
+
* mnemo/crg convention; pass it explicitly when the slug differs (telegram
|
|
79
|
+
* saves under `"telegram"` though its console name is `"better-telegram-mcp"`).
|
|
80
|
+
*
|
|
81
|
+
* Reserved built-ins: `config` (`status`/`delete`), `status` (= `config
|
|
82
|
+
* status`), `logout` (= `config delete`; non-interactive use needs `--yes`,
|
|
83
|
+
* otherwise exit 1), `relay`, `doctor` and `token`. `auth` is not a built-in:
|
|
84
|
+
* sign-in is domain-specific, so a server that needs it passes an `auth`
|
|
85
|
+
* handler in `extra`.
|
|
86
|
+
*
|
|
87
|
+
* `extra` subcommand names take precedence over the reserved built-ins, so a
|
|
88
|
+
* server (or a test) can supply its own handler for any of them.
|
|
89
|
+
* `version`, when set, powers `--version`/`-V` (handled before `serve` or any
|
|
90
|
+
* subcommand runs); when unset, `--version`/`-V` falls through to `serve` like
|
|
91
|
+
* any other flag.
|
|
92
|
+
*
|
|
93
|
+
* The returned `run(argv)` resolves to the process exit code. A server's entry
|
|
94
|
+
* point calls it and exits: `buildCli(name, opts)(process.argv.slice(2)).then((c) => process.exit(c))`.
|
|
95
|
+
*/
|
|
96
|
+
export declare function buildCli(serverName: string, options: BuildCliOptions): (argv?: string[] | null) => Promise<number>;
|
|
97
|
+
//# sourceMappingURL=build-cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-cli.d.ts","sourceRoot":"","sources":["../../src/cli/build-cli.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAmBH,4EAA4E;AAC5E,MAAM,MAAM,OAAO,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;AAEhF;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;AAErE,MAAM,WAAW,eAAe;IAC9B,mEAAmE;IACnE,KAAK,EAAE,OAAO,CAAA;IACd;;;;;OAKG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IAClC,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AA6LD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CAiDlH"}
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Console-script CLI builder shared by every TypeScript MCP server.
|
|
3
|
+
*
|
|
4
|
+
* TS counterpart of `mcp_core.build_cli` (core-py). `buildCli` wraps a
|
|
5
|
+
* server's existing `serve(argv) -> number | void` entry point with
|
|
6
|
+
* subcommand dispatch, without changing that entry point's behaviour for the
|
|
7
|
+
* two invocation shapes it already handles:
|
|
8
|
+
*
|
|
9
|
+
* - Bare invocation (`argv` empty) still means "start the server".
|
|
10
|
+
* - Any flag-prefixed argv (`--http` etc.) is passed through to `serve`
|
|
11
|
+
* byte-for-byte, so existing `--http` semantics are untouched -- except
|
|
12
|
+
* `-h`/`--help` (always) and `--version`/`-V` (only when `version` is set),
|
|
13
|
+
* which are intercepted here and never reach `serve`. Starting the server on
|
|
14
|
+
* those would hang in stdio mode instead of printing the requested output.
|
|
15
|
+
*
|
|
16
|
+
* A leading *positional* argv[0] is treated as a subcommand name -- either one
|
|
17
|
+
* of the reserved built-ins (`config`/`doctor`/`logout`/`relay`/`status`/`token`)
|
|
18
|
+
* or a server-specific one supplied via `extra` -- and is routed to its handler
|
|
19
|
+
* instead of `serve`. `status` and `logout` are top-level aliases of
|
|
20
|
+
* `config status` and `config delete` (same output and exit codes).
|
|
21
|
+
*
|
|
22
|
+
* `auth` is deliberately NOT a built-in: signing in is domain-specific (OAuth
|
|
23
|
+
* device code, bot token, API key paste, relay form, ...), so each server that
|
|
24
|
+
* needs it supplies its own `auth` handler via `extra`.
|
|
25
|
+
* STDOUT is the MCP protocol channel in stdio mode, so only this subcommand
|
|
26
|
+
* path prints to stdout; the `serve` path never touches stdout here.
|
|
27
|
+
*
|
|
28
|
+
* Built-in output convention: informational results (configured/not
|
|
29
|
+
* configured, session details, doctor's `[ok]`/`[warn]`/`[fail]` lines) go to
|
|
30
|
+
* stdout (`console.log`); failures and prompts (no active session, refused
|
|
31
|
+
* delete, corrupt config) go to stderr (`console.error`) alongside a non-zero
|
|
32
|
+
* return code. Credential *values* are never printed by any built-in -- only
|
|
33
|
+
* names/keys/status.
|
|
34
|
+
*/
|
|
35
|
+
import { accessSync, constants, existsSync } from 'node:fs';
|
|
36
|
+
import { createInterface } from 'node:readline';
|
|
37
|
+
import { tryOpenBrowser } from '../relay/browser.js';
|
|
38
|
+
import { backendFromEnv } from '../storage/backends.js';
|
|
39
|
+
import { pluginNameForServer } from '../storage/credential-store.js';
|
|
40
|
+
import { dataDir, legacyDataDirs } from '../storage/data-dir.js';
|
|
41
|
+
import { clearMode, getMode } from '../storage/mode.js';
|
|
42
|
+
import { PerPluginStore } from '../storage/per-plugin-store.js';
|
|
43
|
+
import { acquireSessionLock, releaseSessionLock } from '../storage/session-lock.js';
|
|
44
|
+
import { tokenCliHandler } from '../token-auth/cli.js';
|
|
45
|
+
// Minimum Node major the stack supports (mcp-core package.json `engines`
|
|
46
|
+
// pins `>=24.18.0`). Doctor's runtime check is the TS analogue of core-py's
|
|
47
|
+
// exact `python == 3.13` line; TS uses a floor because the package supports
|
|
48
|
+
// Node 24+ (its @types/node targets 26).
|
|
49
|
+
const MIN_NODE_MAJOR = 24;
|
|
50
|
+
function printCliHelp(serverName, handlers) {
|
|
51
|
+
const names = Object.keys(handlers).sort().join(', ');
|
|
52
|
+
console.log(`usage: ${serverName} [-h] [--version] [<subcommand> ...]`);
|
|
53
|
+
console.log('Any other flags/args are passed through to the MCP server (e.g. --http).');
|
|
54
|
+
console.log(`subcommands: ${names}`);
|
|
55
|
+
}
|
|
56
|
+
async function configStatus(serverName, pluginName) {
|
|
57
|
+
// Credentials are keyed by the plugin slug (what the server saves under),
|
|
58
|
+
// while `serverName` stays the display label in the printed status.
|
|
59
|
+
const store = new PerPluginStore(pluginName);
|
|
60
|
+
if ((await store.load()) !== null) {
|
|
61
|
+
console.log(`${serverName}: configured (source: file)`);
|
|
62
|
+
console.log(' (env overrides, if any, take precedence at server start)');
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
// load() returns null for both "absent" and "corrupt"; the raw backend read
|
|
66
|
+
// tells them apart without ever touching the plaintext.
|
|
67
|
+
if (await store.hasStoredBlob()) {
|
|
68
|
+
console.error(`${serverName}: config is corrupt (undecryptable) -- re-run setup to restore`);
|
|
69
|
+
return 1;
|
|
70
|
+
}
|
|
71
|
+
console.log(`${serverName}: not configured`);
|
|
72
|
+
console.log(' (env overrides, if any, take precedence at server start)');
|
|
73
|
+
return 0;
|
|
74
|
+
}
|
|
75
|
+
async function confirmDelete(serverName) {
|
|
76
|
+
process.stderr.write(`Delete stored config for ${serverName}? [y/N] `);
|
|
77
|
+
const rl = createInterface({ input: process.stdin });
|
|
78
|
+
try {
|
|
79
|
+
const line = await new Promise((resolve) => {
|
|
80
|
+
rl.once('line', resolve);
|
|
81
|
+
});
|
|
82
|
+
return ['y', 'yes'].includes(line.trim().toLowerCase());
|
|
83
|
+
}
|
|
84
|
+
finally {
|
|
85
|
+
rl.close();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
async function configDelete(serverName, pluginName, yes) {
|
|
89
|
+
if (!yes) {
|
|
90
|
+
if (!process.stdin.isTTY) {
|
|
91
|
+
console.error(`${serverName}: refusing to delete without --yes in non-interactive mode`);
|
|
92
|
+
return 1;
|
|
93
|
+
}
|
|
94
|
+
if (!(await confirmDelete(serverName))) {
|
|
95
|
+
console.error(`${serverName}: aborted`);
|
|
96
|
+
return 1;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
await new PerPluginStore(pluginName).clear();
|
|
100
|
+
console.log(`${serverName}: config deleted`);
|
|
101
|
+
return 0;
|
|
102
|
+
}
|
|
103
|
+
function configHandler(serverName, pluginName) {
|
|
104
|
+
return async (argv) => {
|
|
105
|
+
const action = argv[0];
|
|
106
|
+
if (action === 'status')
|
|
107
|
+
return configStatus(serverName, pluginName);
|
|
108
|
+
if (action === 'delete')
|
|
109
|
+
return configDelete(serverName, pluginName, argv.includes('--yes'));
|
|
110
|
+
console.error(`${serverName}: config expects 'status' or 'delete'`);
|
|
111
|
+
return 2;
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
function relayStatus(serverName, info) {
|
|
115
|
+
if (info === null) {
|
|
116
|
+
console.error(`${serverName}: no active relay session`);
|
|
117
|
+
return 1;
|
|
118
|
+
}
|
|
119
|
+
const ageS = (Date.now() - info.createdAt) / 1000;
|
|
120
|
+
console.log(`${serverName}: session ${info.sessionId.slice(0, 8)} relay_url=${info.relayUrl} age=${ageS.toFixed(0)}s`);
|
|
121
|
+
return 0;
|
|
122
|
+
}
|
|
123
|
+
function relayHandler(serverName) {
|
|
124
|
+
return async (argv) => {
|
|
125
|
+
const action = argv[0];
|
|
126
|
+
if (action === 'reset') {
|
|
127
|
+
await releaseSessionLock(serverName);
|
|
128
|
+
await clearMode(serverName);
|
|
129
|
+
console.log(`${serverName}: relay state cleared`);
|
|
130
|
+
return 0;
|
|
131
|
+
}
|
|
132
|
+
if (action !== 'status' && action !== 'open') {
|
|
133
|
+
console.error(`${serverName}: relay expects 'status', 'open', or 'reset'`);
|
|
134
|
+
return 2;
|
|
135
|
+
}
|
|
136
|
+
const info = await acquireSessionLock(serverName);
|
|
137
|
+
if (action === 'status')
|
|
138
|
+
return relayStatus(serverName, info);
|
|
139
|
+
// "open"
|
|
140
|
+
if (info === null) {
|
|
141
|
+
console.error(`${serverName}: no active relay session`);
|
|
142
|
+
return 1;
|
|
143
|
+
}
|
|
144
|
+
// Branch on the return value: `tryOpenBrowser` declines under headless / CI
|
|
145
|
+
// / the env-guard, and printing "opened" there is untrue in the very first
|
|
146
|
+
// line the user reads -- they wait for a tab that never appears. Failing to
|
|
147
|
+
// open is not a failure of the command (the URL is still correct and still
|
|
148
|
+
// usable), so the exit code stays 0.
|
|
149
|
+
if (await tryOpenBrowser(info.relayUrl)) {
|
|
150
|
+
console.log(`${serverName}: opened ${info.relayUrl}`);
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
console.log(`${serverName}: could not launch a browser here; visit ${info.relayUrl}`);
|
|
154
|
+
}
|
|
155
|
+
return 0;
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
async function runDoctor(serverName, pluginName) {
|
|
159
|
+
let ok = true;
|
|
160
|
+
const nodeVersion = process.versions.node;
|
|
161
|
+
if (Number(nodeVersion.split('.')[0]) >= MIN_NODE_MAJOR) {
|
|
162
|
+
console.log(`[ok] node ${nodeVersion}`);
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
console.log(`[fail] node ${nodeVersion} (expected >=${MIN_NODE_MAJOR})`);
|
|
166
|
+
ok = false;
|
|
167
|
+
}
|
|
168
|
+
let backendOk = true;
|
|
169
|
+
try {
|
|
170
|
+
backendFromEnv();
|
|
171
|
+
console.log('[ok] credential backend initializes');
|
|
172
|
+
}
|
|
173
|
+
catch (err) {
|
|
174
|
+
console.log(`[fail] credential backend: ${err.message}`);
|
|
175
|
+
backendOk = false;
|
|
176
|
+
ok = false;
|
|
177
|
+
}
|
|
178
|
+
// Only check writability if the dir already exists -- doctor must not create
|
|
179
|
+
// it as a side effect (mkdir-probing would leave stray dirs for servers that
|
|
180
|
+
// were never configured). The dir is keyed by the plugin slug (matching
|
|
181
|
+
// PerPluginStore's on-disk layout `~/.<plugin>/`), not the console name.
|
|
182
|
+
const storeDir = dataDir(pluginName);
|
|
183
|
+
if (existsSync(storeDir)) {
|
|
184
|
+
try {
|
|
185
|
+
accessSync(storeDir, constants.W_OK);
|
|
186
|
+
console.log(`[ok] store dir writable: ${storeDir}`);
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
console.log(`[fail] store dir not writable: ${storeDir}`);
|
|
190
|
+
ok = false;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
// Credentials from an older layout are still read, but only the next save
|
|
195
|
+
// moves them into the current dir -- surface that instead of "not yet".
|
|
196
|
+
const legacy = legacyDataDirs(pluginName).find((loc) => existsSync(loc.dir));
|
|
197
|
+
if (legacy !== undefined) {
|
|
198
|
+
console.log(`[warn] only legacy store dir found: ${legacy.dir} (credentials move to ${storeDir} on next save)`);
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
console.log(`[warn] store dir does not exist yet: ${storeDir}`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
// PerPluginStore builds its backend from the same env, so it would throw the
|
|
205
|
+
// error already reported above and abort the remaining checks.
|
|
206
|
+
if (!backendOk) {
|
|
207
|
+
console.log('[warn] config: not checked (credential backend unavailable)');
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
const store = new PerPluginStore(pluginName);
|
|
211
|
+
if ((await store.load()) !== null) {
|
|
212
|
+
console.log('[ok] config: configured');
|
|
213
|
+
}
|
|
214
|
+
else if (await store.hasStoredBlob()) {
|
|
215
|
+
console.log('[fail] config: corrupt');
|
|
216
|
+
ok = false;
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
console.log('[warn] config: not configured');
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
const info = await acquireSessionLock(serverName);
|
|
223
|
+
if (info !== null) {
|
|
224
|
+
console.log(`[ok] relay session active (${info.sessionId.slice(0, 8)})`);
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
console.log('[warn] no active relay session');
|
|
228
|
+
}
|
|
229
|
+
console.log(`[ok] mode: ${(await getMode(serverName)) ?? 'unset'}`);
|
|
230
|
+
return ok ? 0 : 1;
|
|
231
|
+
}
|
|
232
|
+
function doctorHandler(serverName, pluginName) {
|
|
233
|
+
return () => runDoctor(serverName, pluginName);
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Build the console-script entry point for one MCP server.
|
|
237
|
+
*
|
|
238
|
+
* `serverName` is the console/display name (e.g. `"wet-mcp"`): it names the
|
|
239
|
+
* program in help/usage and status lines, and keys relay session state and
|
|
240
|
+
* run mode (which servers store under their `SERVER_NAME`).
|
|
241
|
+
*
|
|
242
|
+
* `options.pluginName` is the credential storage slug that `PerPluginStore`
|
|
243
|
+
* keys on (e.g. `"wet"`): it decides where `config` and `doctor` read/write
|
|
244
|
+
* credentials. Servers save creds under this slug, not under the console
|
|
245
|
+
* name, so the two must not be conflated. When omitted it defaults to
|
|
246
|
+
* `serverName` with a trailing `"-mcp"` stripped, which matches the wet/
|
|
247
|
+
* mnemo/crg convention; pass it explicitly when the slug differs (telegram
|
|
248
|
+
* saves under `"telegram"` though its console name is `"better-telegram-mcp"`).
|
|
249
|
+
*
|
|
250
|
+
* Reserved built-ins: `config` (`status`/`delete`), `status` (= `config
|
|
251
|
+
* status`), `logout` (= `config delete`; non-interactive use needs `--yes`,
|
|
252
|
+
* otherwise exit 1), `relay`, `doctor` and `token`. `auth` is not a built-in:
|
|
253
|
+
* sign-in is domain-specific, so a server that needs it passes an `auth`
|
|
254
|
+
* handler in `extra`.
|
|
255
|
+
*
|
|
256
|
+
* `extra` subcommand names take precedence over the reserved built-ins, so a
|
|
257
|
+
* server (or a test) can supply its own handler for any of them.
|
|
258
|
+
* `version`, when set, powers `--version`/`-V` (handled before `serve` or any
|
|
259
|
+
* subcommand runs); when unset, `--version`/`-V` falls through to `serve` like
|
|
260
|
+
* any other flag.
|
|
261
|
+
*
|
|
262
|
+
* The returned `run(argv)` resolves to the process exit code. A server's entry
|
|
263
|
+
* point calls it and exits: `buildCli(name, opts)(process.argv.slice(2)).then((c) => process.exit(c))`.
|
|
264
|
+
*/
|
|
265
|
+
export function buildCli(serverName, options) {
|
|
266
|
+
const { serve, extra, version, pluginName = pluginNameForServer(serverName) } = options;
|
|
267
|
+
const handlers = {
|
|
268
|
+
config: configHandler(serverName, pluginName),
|
|
269
|
+
status: () => configStatus(serverName, pluginName),
|
|
270
|
+
logout: (argv) => configDelete(serverName, pluginName, argv.includes('--yes')),
|
|
271
|
+
relay: relayHandler(serverName),
|
|
272
|
+
doctor: doctorHandler(serverName, pluginName),
|
|
273
|
+
token: tokenCliHandler(),
|
|
274
|
+
...extra
|
|
275
|
+
};
|
|
276
|
+
return async (argv) => {
|
|
277
|
+
const args = argv ?? process.argv.slice(2);
|
|
278
|
+
if (args.length === 0) {
|
|
279
|
+
const rc = await serve([]);
|
|
280
|
+
return rc == null ? 0 : rc;
|
|
281
|
+
}
|
|
282
|
+
// Peek argv[0] before any subcommand routing: bare/flag argv must never
|
|
283
|
+
// reach a subcommand handler, or `--http` would be misread instead of
|
|
284
|
+
// passed through to `serve`. `-h`/`--help`/`--version` are intercepted
|
|
285
|
+
// here because starting the server on them would hang (stdio blocks on
|
|
286
|
+
// stdin) instead of printing the requested output.
|
|
287
|
+
if (args[0] === '-h' || args[0] === '--help') {
|
|
288
|
+
printCliHelp(serverName, handlers);
|
|
289
|
+
return 0;
|
|
290
|
+
}
|
|
291
|
+
if (version != null && (args[0] === '--version' || args[0] === '-V')) {
|
|
292
|
+
console.log(`${serverName} ${version}`);
|
|
293
|
+
return 0;
|
|
294
|
+
}
|
|
295
|
+
if (args[0].startsWith('-')) {
|
|
296
|
+
const rc = await serve(args);
|
|
297
|
+
return rc == null ? 0 : rc;
|
|
298
|
+
}
|
|
299
|
+
const subcommand = args[0];
|
|
300
|
+
const handler = handlers[subcommand];
|
|
301
|
+
if (handler === undefined) {
|
|
302
|
+
const names = Object.keys(handlers).sort().join(', ');
|
|
303
|
+
console.error(`${serverName}: unknown subcommand '${subcommand}' (expected one of: ${names})`);
|
|
304
|
+
return 2;
|
|
305
|
+
}
|
|
306
|
+
return handler(args.slice(1));
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
//# sourceMappingURL=build-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-cli.js","sourceRoot":"","sources":["../../src/cli/build-cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,eAAe,EAAE,QAAQ,EAAE,KAAK,UAAU,EAAE,KAAK,OAAO,EAAE,MAAM,gBAAgB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,QAAQ,EAAiC,MAAM,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface EncryptResult {
|
|
2
|
+
ciphertext: Uint8Array;
|
|
3
|
+
iv: Uint8Array;
|
|
4
|
+
tag: Uint8Array;
|
|
5
|
+
}
|
|
6
|
+
export declare function encrypt(key: CryptoKey, plaintext: string): Promise<EncryptResult>;
|
|
7
|
+
export declare function decrypt(key: CryptoKey, ciphertext: Uint8Array, iv: Uint8Array, tag?: Uint8Array): Promise<string>;
|
|
8
|
+
//# sourceMappingURL=aes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aes.d.ts","sourceRoot":"","sources":["../../src/crypto/aes.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,UAAU,CAAA;IACtB,EAAE,EAAE,UAAU,CAAA;IACd,GAAG,EAAE,UAAU,CAAA;CAChB;AAED,wBAAsB,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAWvF;AAED,wBAAsB,OAAO,CAC3B,GAAG,EAAE,SAAS,EACd,UAAU,EAAE,UAAU,EACtB,EAAE,EAAE,UAAU,EACd,GAAG,CAAC,EAAE,UAAU,GACf,OAAO,CAAC,MAAM,CAAC,CAYjB"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
const encoder = new TextEncoder();
|
|
2
|
+
const decoder = new TextDecoder();
|
|
3
|
+
export async function encrypt(key, plaintext) {
|
|
4
|
+
const iv = crypto.getRandomValues(new Uint8Array(12));
|
|
5
|
+
const encoded = encoder.encode(plaintext);
|
|
6
|
+
const encrypted = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, encoded);
|
|
7
|
+
// WebCrypto appends 16-byte GCM tag to ciphertext
|
|
8
|
+
const combined = new Uint8Array(encrypted);
|
|
9
|
+
const ciphertext = combined.slice(0, combined.length - 16);
|
|
10
|
+
const tag = combined.slice(combined.length - 16);
|
|
11
|
+
return { ciphertext, iv, tag };
|
|
12
|
+
}
|
|
13
|
+
export async function decrypt(key, ciphertext, iv, tag) {
|
|
14
|
+
let data;
|
|
15
|
+
if (tag) {
|
|
16
|
+
data = new Uint8Array(ciphertext.length + tag.length);
|
|
17
|
+
data.set(ciphertext, 0);
|
|
18
|
+
data.set(tag, ciphertext.length);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
data = new Uint8Array(ciphertext);
|
|
22
|
+
}
|
|
23
|
+
const ivCopy = new Uint8Array(iv);
|
|
24
|
+
const decrypted = await crypto.subtle.decrypt({ name: 'AES-GCM', iv: ivCopy }, key, data);
|
|
25
|
+
return decoder.decode(decrypted);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=aes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aes.js","sourceRoot":"","sources":["../../src/crypto/aes.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAA;AACjC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAA;AAQjC,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,GAAc,EAAE,SAAiB;IAC7D,MAAM,EAAE,GAAG,MAAM,CAAC,eAAe,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC,CAAA;IACrD,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;IACzC,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;IAEpF,kDAAkD;IAClD,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,CAAA;IAC1C,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;IAC1D,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,EAAE,CAAC,CAAA;IAEhD,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,GAAG,EAAE,CAAA;AAChC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,GAAc,EACd,UAAsB,EACtB,EAAc,EACd,GAAgB;IAEhB,IAAI,IAA6B,CAAA;IACjC,IAAI,GAAG,EAAE,CAAC;QACR,IAAI,GAAG,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAA;QACrD,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,CAAA;QACvB,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,MAAM,CAAC,CAAA;IAClC,CAAC;SAAM,CAAC;QACN,IAAI,GAAG,IAAI,UAAU,CAAC,UAAU,CAAC,CAAA;IACnC,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAA;IACjC,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IACzF,OAAO,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;AAClC,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function generateKeyPair(): Promise<CryptoKeyPair>;
|
|
2
|
+
export declare function exportPublicKey(key: CryptoKey): Promise<string>;
|
|
3
|
+
export declare function importPublicKey(base64url: string): Promise<CryptoKey>;
|
|
4
|
+
export declare function deriveSharedSecret(privateKey: CryptoKey, publicKey: CryptoKey): Promise<ArrayBuffer>;
|
|
5
|
+
//# sourceMappingURL=ecdh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ecdh.d.ts","sourceRoot":"","sources":["../../src/crypto/ecdh.ts"],"names":[],"mappings":"AAEA,wBAAsB,eAAe,IAAI,OAAO,CAAC,aAAa,CAAC,CAE9D;AAED,wBAAsB,eAAe,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAGrE;AAED,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAG3E;AAED,wBAAsB,kBAAkB,CAAC,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAE1G"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const ALGORITHM = { name: 'ECDH', namedCurve: 'P-256' };
|
|
2
|
+
export async function generateKeyPair() {
|
|
3
|
+
return crypto.subtle.generateKey(ALGORITHM, true, ['deriveKey', 'deriveBits']);
|
|
4
|
+
}
|
|
5
|
+
export async function exportPublicKey(key) {
|
|
6
|
+
const raw = await crypto.subtle.exportKey('raw', key);
|
|
7
|
+
return Buffer.from(raw).toString('base64url');
|
|
8
|
+
}
|
|
9
|
+
export async function importPublicKey(base64url) {
|
|
10
|
+
const raw = Buffer.from(base64url, 'base64url');
|
|
11
|
+
return crypto.subtle.importKey('raw', raw, ALGORITHM, true, []);
|
|
12
|
+
}
|
|
13
|
+
export async function deriveSharedSecret(privateKey, publicKey) {
|
|
14
|
+
return crypto.subtle.deriveBits({ name: 'ECDH', public: publicKey }, privateKey, 256);
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=ecdh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ecdh.js","sourceRoot":"","sources":["../../src/crypto/ecdh.ts"],"names":[],"mappings":"AAAA,MAAM,SAAS,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,CAAA;AAEvD,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,OAAO,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAA;AAChF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,GAAc;IAClD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,CAAA;IACrD,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAA;AAC/C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,SAAiB;IACrD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAA;IAC/C,OAAO,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,CAAA;AACjE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,UAAqB,EAAE,SAAoB;IAClF,OAAO,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,UAAU,EAAE,GAAG,CAAC,CAAA;AACvF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/crypto/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,aAAa,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAC/D,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AACjG,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/crypto/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAsB,OAAO,EAAE,MAAM,UAAU,CAAA;AAC/D,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AACjG,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA"}
|