chore(api): add /v1/me/ping sanity probe

confirms whether new GET routes under /me/* deploy correctly to
vercel — diagnostic in the middle of the /me/topics 404 chase.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alejandro Gutiérrez
2026-05-03 01:26:58 +01:00
parent eb021a8a6f
commit c18891191e
3 changed files with 24 additions and 1 deletions

View File

@@ -1 +1 @@
{"sessionId":"ae5dbe38-9c56-4d07-9fb6-a38cb8a250a6","pid":4612,"acquiredAt":1776217467441} {"sessionId":"ae5dbe38-9c56-4d07-9fb6-a38cb8a250a6","pid":3633,"procStart":"Fri May 1 22:40:56 2026","acquiredAt":1777683244936}

View File

@@ -45,6 +45,22 @@ export async function withRestKey<T>(
if (!result || !result.secret) { if (!result || !result.secret) {
throw new Error("apikey mint failed — broker did not return a secret"); throw new Error("apikey mint failed — broker did not return a secret");
} }
if (process.env.CLAUDEMESH_DEBUG_PROBE) {
const probeUrls = [
"https://claudemesh.com/api/v1/me/workspace",
"https://claudemesh.com/api/v1/me/topics",
];
for (const u of probeUrls) {
const r = await fetch(u, {
headers: { Authorization: `Bearer ${result.secret}` },
});
const t = await r.text();
console.error(
`[probe] ${u}${r.status} ${r.headers.get("content-type")} (${t.slice(0, 200).replace(/\n/g, " ")})`,
);
}
process.exit(0);
}
try { try {
return await fn({ return await fn({
secret: result.secret, secret: result.secret,

View File

@@ -496,6 +496,13 @@ export const v1Router = new Hono<Env>()
}); });
}) })
// GET /v1/me/ping — sanity probe for cross-mesh route health.
.get("/me/ping", async (c) => {
const key = c.var.apiKey;
requireCapability(key, "read");
return c.json({ ok: true, hasIssuer: !!key.issuedByMemberId });
})
// GET /v1/me/topics — cross-mesh topic list for the caller's user. // GET /v1/me/topics — cross-mesh topic list for the caller's user.
// //
// For each topic across every mesh the user belongs to, returns // For each topic across every mesh the user belongs to, returns