catence 0.2.1-beta.19 → 0.2.1-beta.20

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.
@@ -3,7 +3,7 @@
3
3
  * Keep these values synchronized with release/manifest.json; release checks
4
4
  * deliberately reject drift before a package can be published.
5
5
  */
6
- export declare const CATENCE_RUNTIME_VERSION = "0.2.1-beta.19";
6
+ export declare const CATENCE_RUNTIME_VERSION = "0.2.1-beta.20";
7
7
  export declare const CATENCE_PROTOCOL_VERSION = 1;
8
8
  export type CatenceRuntimeCapabilities = {
9
9
  mcp: true;
@@ -3,7 +3,7 @@
3
3
  * Keep these values synchronized with release/manifest.json; release checks
4
4
  * deliberately reject drift before a package can be published.
5
5
  */
6
- export const CATENCE_RUNTIME_VERSION = '0.2.1-beta.19';
6
+ export const CATENCE_RUNTIME_VERSION = '0.2.1-beta.20';
7
7
  export const CATENCE_PROTOCOL_VERSION = 1;
8
8
  export function catenceRuntimeHealth() {
9
9
  return {
@@ -63,8 +63,12 @@ const cimdClientRecordSchema = z.object({
63
63
  client_id_issued_at: z.number().optional(),
64
64
  client_secret_expires_at: z.number().optional(),
65
65
  }).strict();
66
+ // Codes and tokens are keyed by a hashed secret, never by the client id, and
67
+ // can be issued to either kind of client: a DCR-registered client (UUID) or a
68
+ // client identified by a Client ID Metadata Document (an HTTPS URL). Both are
69
+ // persisted verbatim so the reader must accept both.
66
70
  const authorizationCodeRecordSchema = z.object({
67
- clientId: uuidSchema,
71
+ clientId: z.string().min(1),
68
72
  userId: z.string(),
69
73
  expiresAt: isoTimestampSchema,
70
74
  scopes: z.array(z.string()),
@@ -75,7 +79,7 @@ const authorizationCodeRecordSchema = z.object({
75
79
  grantId: uuidSchema.optional(),
76
80
  }).strict();
77
81
  const tokenRecordSchema = z.object({
78
- clientId: uuidSchema,
82
+ clientId: z.string().min(1),
79
83
  userId: z.string().optional(),
80
84
  expiresAt: isoTimestampSchema,
81
85
  scopes: z.array(z.string()),
@@ -30,6 +30,10 @@ import { asPublicClientMetadata, createFileOAuthServerModel, declaresPrivateKeyJ
30
30
  * validates and caches the document — PKCE still protects the flow. The
31
31
  * rewritten body drops content-length; the library's size guard reads the
32
32
  * actual stream anyway.
33
+ *
34
+ * Parsing happens on a clone: every passthrough path must hand the library a
35
+ * response whose body is still readable, and a consumed stream would surface
36
+ * as an opaque 500 instead of the library's proper OAuth error.
33
37
  */
34
38
  function sanitizingMetadataFetch(fetchImpl) {
35
39
  return async (input, init) => {
@@ -41,7 +45,7 @@ function sanitizingMetadataFetch(fetchImpl) {
41
45
  return response;
42
46
  let document;
43
47
  try {
44
- document = JSON.parse(await response.text());
48
+ document = JSON.parse(await response.clone().text());
45
49
  }
46
50
  catch {
47
51
  return response;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "catence",
3
- "version": "0.2.1-beta.19",
3
+ "version": "0.2.1-beta.20",
4
4
  "description": "Local MCP access to normalized Garmin, Intervals.icu, and targeted Strava fitness data.",
5
5
  "license": "AGPL-3.0-or-later",
6
6
  "repository": {