@codemem/core 0.22.0-alpha.4 → 0.22.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 (36) hide show
  1. package/dist/api-types.d.ts +7 -0
  2. package/dist/api-types.d.ts.map +1 -1
  3. package/dist/better-sqlite-coordinator-store.d.ts +3 -1
  4. package/dist/better-sqlite-coordinator-store.d.ts.map +1 -1
  5. package/dist/{coordinator-api-By9BNOCL.js → coordinator-api-CimbM4rk.js} +149 -64
  6. package/dist/coordinator-api-CimbM4rk.js.map +1 -0
  7. package/dist/coordinator-api.d.ts.map +1 -1
  8. package/dist/coordinator-runtime.d.ts +9 -0
  9. package/dist/coordinator-runtime.d.ts.map +1 -1
  10. package/dist/coordinator-store-contract.d.ts +23 -0
  11. package/dist/coordinator-store-contract.d.ts.map +1 -1
  12. package/dist/coordinator-store-test-harness.d.ts.map +1 -1
  13. package/dist/coordinator-store.d.ts +1 -1
  14. package/dist/coordinator-store.d.ts.map +1 -1
  15. package/dist/d1-coordinator-store.d.ts +3 -1
  16. package/dist/d1-coordinator-store.d.ts.map +1 -1
  17. package/dist/db.d.ts.map +1 -1
  18. package/dist/index.d.ts +3 -3
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +1710 -1573
  21. package/dist/index.js.map +1 -1
  22. package/dist/internal/cloudflare-coordinator.js +76 -29
  23. package/dist/internal/cloudflare-coordinator.js.map +1 -1
  24. package/dist/maintenance.d.ts.map +1 -1
  25. package/dist/raw-event-flush.d.ts.map +1 -1
  26. package/dist/schema.d.ts +152 -0
  27. package/dist/schema.d.ts.map +1 -1
  28. package/dist/store.d.ts +5 -0
  29. package/dist/store.d.ts.map +1 -1
  30. package/dist/sync-replication.d.ts.map +1 -1
  31. package/dist/test-schema.generated.d.ts +1 -1
  32. package/dist/test-schema.generated.d.ts.map +1 -1
  33. package/dist/types.d.ts +4 -0
  34. package/dist/types.d.ts.map +1 -1
  35. package/package.json +1 -1
  36. package/dist/coordinator-api-By9BNOCL.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coordinator-api-CimbM4rk.js","names":["#matchResult","#validatedData","#getDecodedParam","#getAllDecodedParams","#getParamValue","#cachedBody","#rawRequest","#executionCtx","#notFoundHandler","#path","#matchResult","#req","#res","#preparedHeaders","#renderer","#layout","#status","#var","#newResponse","Hono","#path","#addRoute","#notFoundHandler","#clone","#dispatch","#handleError","Node","#index","#children","#varIndex","Node","#root","#context","#middleware","#routes","#buildMatcher","#routers","#routes","#children","#methods","#patterns","#order","#params","#pushHandlerSets","#node","HonoBase"],"sources":["../../../node_modules/.pnpm/hono@4.12.8/node_modules/hono/dist/compose.js","../../../node_modules/.pnpm/hono@4.12.8/node_modules/hono/dist/request/constants.js","../../../node_modules/.pnpm/hono@4.12.8/node_modules/hono/dist/utils/body.js","../../../node_modules/.pnpm/hono@4.12.8/node_modules/hono/dist/utils/url.js","../../../node_modules/.pnpm/hono@4.12.8/node_modules/hono/dist/request.js","../../../node_modules/.pnpm/hono@4.12.8/node_modules/hono/dist/utils/html.js","../../../node_modules/.pnpm/hono@4.12.8/node_modules/hono/dist/context.js","../../../node_modules/.pnpm/hono@4.12.8/node_modules/hono/dist/router.js","../../../node_modules/.pnpm/hono@4.12.8/node_modules/hono/dist/utils/constants.js","../../../node_modules/.pnpm/hono@4.12.8/node_modules/hono/dist/hono-base.js","../../../node_modules/.pnpm/hono@4.12.8/node_modules/hono/dist/router/reg-exp-router/matcher.js","../../../node_modules/.pnpm/hono@4.12.8/node_modules/hono/dist/router/reg-exp-router/node.js","../../../node_modules/.pnpm/hono@4.12.8/node_modules/hono/dist/router/reg-exp-router/trie.js","../../../node_modules/.pnpm/hono@4.12.8/node_modules/hono/dist/router/reg-exp-router/router.js","../../../node_modules/.pnpm/hono@4.12.8/node_modules/hono/dist/router/smart-router/router.js","../../../node_modules/.pnpm/hono@4.12.8/node_modules/hono/dist/router/trie-router/node.js","../../../node_modules/.pnpm/hono@4.12.8/node_modules/hono/dist/router/trie-router/router.js","../../../node_modules/.pnpm/hono@4.12.8/node_modules/hono/dist/hono.js","../src/coordinator-invites.ts","../src/schema.ts","../src/observer-config.ts","../src/db.ts","../src/sync-identity.ts","../src/sync-auth.ts","../src/coordinator-api.ts"],"sourcesContent":["// src/compose.ts\nvar compose = (middleware, onError, onNotFound) => {\n return (context, next) => {\n let index = -1;\n return dispatch(0);\n async function dispatch(i) {\n if (i <= index) {\n throw new Error(\"next() called multiple times\");\n }\n index = i;\n let res;\n let isError = false;\n let handler;\n if (middleware[i]) {\n handler = middleware[i][0][0];\n context.req.routeIndex = i;\n } else {\n handler = i === middleware.length && next || void 0;\n }\n if (handler) {\n try {\n res = await handler(context, () => dispatch(i + 1));\n } catch (err) {\n if (err instanceof Error && onError) {\n context.error = err;\n res = await onError(err, context);\n isError = true;\n } else {\n throw err;\n }\n }\n } else {\n if (context.finalized === false && onNotFound) {\n res = await onNotFound(context);\n }\n }\n if (res && (context.finalized === false || isError)) {\n context.res = res;\n }\n return context;\n }\n };\n};\nexport {\n compose\n};\n","// src/request/constants.ts\nvar GET_MATCH_RESULT = /* @__PURE__ */ Symbol();\nexport {\n GET_MATCH_RESULT\n};\n","// src/utils/body.ts\nimport { HonoRequest } from \"../request.js\";\nvar parseBody = async (request, options = /* @__PURE__ */ Object.create(null)) => {\n const { all = false, dot = false } = options;\n const headers = request instanceof HonoRequest ? request.raw.headers : request.headers;\n const contentType = headers.get(\"Content-Type\");\n if (contentType?.startsWith(\"multipart/form-data\") || contentType?.startsWith(\"application/x-www-form-urlencoded\")) {\n return parseFormData(request, { all, dot });\n }\n return {};\n};\nasync function parseFormData(request, options) {\n const formData = await request.formData();\n if (formData) {\n return convertFormDataToBodyData(formData, options);\n }\n return {};\n}\nfunction convertFormDataToBodyData(formData, options) {\n const form = /* @__PURE__ */ Object.create(null);\n formData.forEach((value, key) => {\n const shouldParseAllValues = options.all || key.endsWith(\"[]\");\n if (!shouldParseAllValues) {\n form[key] = value;\n } else {\n handleParsingAllValues(form, key, value);\n }\n });\n if (options.dot) {\n Object.entries(form).forEach(([key, value]) => {\n const shouldParseDotValues = key.includes(\".\");\n if (shouldParseDotValues) {\n handleParsingNestedValues(form, key, value);\n delete form[key];\n }\n });\n }\n return form;\n}\nvar handleParsingAllValues = (form, key, value) => {\n if (form[key] !== void 0) {\n if (Array.isArray(form[key])) {\n ;\n form[key].push(value);\n } else {\n form[key] = [form[key], value];\n }\n } else {\n if (!key.endsWith(\"[]\")) {\n form[key] = value;\n } else {\n form[key] = [value];\n }\n }\n};\nvar handleParsingNestedValues = (form, key, value) => {\n if (/(?:^|\\.)__proto__\\./.test(key)) {\n return;\n }\n let nestedForm = form;\n const keys = key.split(\".\");\n keys.forEach((key2, index) => {\n if (index === keys.length - 1) {\n nestedForm[key2] = value;\n } else {\n if (!nestedForm[key2] || typeof nestedForm[key2] !== \"object\" || Array.isArray(nestedForm[key2]) || nestedForm[key2] instanceof File) {\n nestedForm[key2] = /* @__PURE__ */ Object.create(null);\n }\n nestedForm = nestedForm[key2];\n }\n });\n};\nexport {\n parseBody\n};\n","// src/utils/url.ts\nvar splitPath = (path) => {\n const paths = path.split(\"/\");\n if (paths[0] === \"\") {\n paths.shift();\n }\n return paths;\n};\nvar splitRoutingPath = (routePath) => {\n const { groups, path } = extractGroupsFromPath(routePath);\n const paths = splitPath(path);\n return replaceGroupMarks(paths, groups);\n};\nvar extractGroupsFromPath = (path) => {\n const groups = [];\n path = path.replace(/\\{[^}]+\\}/g, (match, index) => {\n const mark = `@${index}`;\n groups.push([mark, match]);\n return mark;\n });\n return { groups, path };\n};\nvar replaceGroupMarks = (paths, groups) => {\n for (let i = groups.length - 1; i >= 0; i--) {\n const [mark] = groups[i];\n for (let j = paths.length - 1; j >= 0; j--) {\n if (paths[j].includes(mark)) {\n paths[j] = paths[j].replace(mark, groups[i][1]);\n break;\n }\n }\n }\n return paths;\n};\nvar patternCache = {};\nvar getPattern = (label, next) => {\n if (label === \"*\") {\n return \"*\";\n }\n const match = label.match(/^\\:([^\\{\\}]+)(?:\\{(.+)\\})?$/);\n if (match) {\n const cacheKey = `${label}#${next}`;\n if (!patternCache[cacheKey]) {\n if (match[2]) {\n patternCache[cacheKey] = next && next[0] !== \":\" && next[0] !== \"*\" ? [cacheKey, match[1], new RegExp(`^${match[2]}(?=/${next})`)] : [label, match[1], new RegExp(`^${match[2]}$`)];\n } else {\n patternCache[cacheKey] = [label, match[1], true];\n }\n }\n return patternCache[cacheKey];\n }\n return null;\n};\nvar tryDecode = (str, decoder) => {\n try {\n return decoder(str);\n } catch {\n return str.replace(/(?:%[0-9A-Fa-f]{2})+/g, (match) => {\n try {\n return decoder(match);\n } catch {\n return match;\n }\n });\n }\n};\nvar tryDecodeURI = (str) => tryDecode(str, decodeURI);\nvar getPath = (request) => {\n const url = request.url;\n const start = url.indexOf(\"/\", url.indexOf(\":\") + 4);\n let i = start;\n for (; i < url.length; i++) {\n const charCode = url.charCodeAt(i);\n if (charCode === 37) {\n const queryIndex = url.indexOf(\"?\", i);\n const hashIndex = url.indexOf(\"#\", i);\n const end = queryIndex === -1 ? hashIndex === -1 ? void 0 : hashIndex : hashIndex === -1 ? queryIndex : Math.min(queryIndex, hashIndex);\n const path = url.slice(start, end);\n return tryDecodeURI(path.includes(\"%25\") ? path.replace(/%25/g, \"%2525\") : path);\n } else if (charCode === 63 || charCode === 35) {\n break;\n }\n }\n return url.slice(start, i);\n};\nvar getQueryStrings = (url) => {\n const queryIndex = url.indexOf(\"?\", 8);\n return queryIndex === -1 ? \"\" : \"?\" + url.slice(queryIndex + 1);\n};\nvar getPathNoStrict = (request) => {\n const result = getPath(request);\n return result.length > 1 && result.at(-1) === \"/\" ? result.slice(0, -1) : result;\n};\nvar mergePath = (base, sub, ...rest) => {\n if (rest.length) {\n sub = mergePath(sub, ...rest);\n }\n return `${base?.[0] === \"/\" ? \"\" : \"/\"}${base}${sub === \"/\" ? \"\" : `${base?.at(-1) === \"/\" ? \"\" : \"/\"}${sub?.[0] === \"/\" ? sub.slice(1) : sub}`}`;\n};\nvar checkOptionalParameter = (path) => {\n if (path.charCodeAt(path.length - 1) !== 63 || !path.includes(\":\")) {\n return null;\n }\n const segments = path.split(\"/\");\n const results = [];\n let basePath = \"\";\n segments.forEach((segment) => {\n if (segment !== \"\" && !/\\:/.test(segment)) {\n basePath += \"/\" + segment;\n } else if (/\\:/.test(segment)) {\n if (/\\?/.test(segment)) {\n if (results.length === 0 && basePath === \"\") {\n results.push(\"/\");\n } else {\n results.push(basePath);\n }\n const optionalSegment = segment.replace(\"?\", \"\");\n basePath += \"/\" + optionalSegment;\n results.push(basePath);\n } else {\n basePath += \"/\" + segment;\n }\n }\n });\n return results.filter((v, i, a) => a.indexOf(v) === i);\n};\nvar _decodeURI = (value) => {\n if (!/[%+]/.test(value)) {\n return value;\n }\n if (value.indexOf(\"+\") !== -1) {\n value = value.replace(/\\+/g, \" \");\n }\n return value.indexOf(\"%\") !== -1 ? tryDecode(value, decodeURIComponent_) : value;\n};\nvar _getQueryParam = (url, key, multiple) => {\n let encoded;\n if (!multiple && key && !/[%+]/.test(key)) {\n let keyIndex2 = url.indexOf(\"?\", 8);\n if (keyIndex2 === -1) {\n return void 0;\n }\n if (!url.startsWith(key, keyIndex2 + 1)) {\n keyIndex2 = url.indexOf(`&${key}`, keyIndex2 + 1);\n }\n while (keyIndex2 !== -1) {\n const trailingKeyCode = url.charCodeAt(keyIndex2 + key.length + 1);\n if (trailingKeyCode === 61) {\n const valueIndex = keyIndex2 + key.length + 2;\n const endIndex = url.indexOf(\"&\", valueIndex);\n return _decodeURI(url.slice(valueIndex, endIndex === -1 ? void 0 : endIndex));\n } else if (trailingKeyCode == 38 || isNaN(trailingKeyCode)) {\n return \"\";\n }\n keyIndex2 = url.indexOf(`&${key}`, keyIndex2 + 1);\n }\n encoded = /[%+]/.test(url);\n if (!encoded) {\n return void 0;\n }\n }\n const results = {};\n encoded ??= /[%+]/.test(url);\n let keyIndex = url.indexOf(\"?\", 8);\n while (keyIndex !== -1) {\n const nextKeyIndex = url.indexOf(\"&\", keyIndex + 1);\n let valueIndex = url.indexOf(\"=\", keyIndex);\n if (valueIndex > nextKeyIndex && nextKeyIndex !== -1) {\n valueIndex = -1;\n }\n let name = url.slice(\n keyIndex + 1,\n valueIndex === -1 ? nextKeyIndex === -1 ? void 0 : nextKeyIndex : valueIndex\n );\n if (encoded) {\n name = _decodeURI(name);\n }\n keyIndex = nextKeyIndex;\n if (name === \"\") {\n continue;\n }\n let value;\n if (valueIndex === -1) {\n value = \"\";\n } else {\n value = url.slice(valueIndex + 1, nextKeyIndex === -1 ? void 0 : nextKeyIndex);\n if (encoded) {\n value = _decodeURI(value);\n }\n }\n if (multiple) {\n if (!(results[name] && Array.isArray(results[name]))) {\n results[name] = [];\n }\n ;\n results[name].push(value);\n } else {\n results[name] ??= value;\n }\n }\n return key ? results[key] : results;\n};\nvar getQueryParam = _getQueryParam;\nvar getQueryParams = (url, key) => {\n return _getQueryParam(url, key, true);\n};\nvar decodeURIComponent_ = decodeURIComponent;\nexport {\n checkOptionalParameter,\n decodeURIComponent_,\n getPath,\n getPathNoStrict,\n getPattern,\n getQueryParam,\n getQueryParams,\n getQueryStrings,\n mergePath,\n splitPath,\n splitRoutingPath,\n tryDecode,\n tryDecodeURI\n};\n","// src/request.ts\nimport { HTTPException } from \"./http-exception.js\";\nimport { GET_MATCH_RESULT } from \"./request/constants.js\";\nimport { parseBody } from \"./utils/body.js\";\nimport { decodeURIComponent_, getQueryParam, getQueryParams, tryDecode } from \"./utils/url.js\";\nvar tryDecodeURIComponent = (str) => tryDecode(str, decodeURIComponent_);\nvar HonoRequest = class {\n /**\n * `.raw` can get the raw Request object.\n *\n * @see {@link https://hono.dev/docs/api/request#raw}\n *\n * @example\n * ```ts\n * // For Cloudflare Workers\n * app.post('/', async (c) => {\n * const metadata = c.req.raw.cf?.hostMetadata?\n * ...\n * })\n * ```\n */\n raw;\n #validatedData;\n // Short name of validatedData\n #matchResult;\n routeIndex = 0;\n /**\n * `.path` can get the pathname of the request.\n *\n * @see {@link https://hono.dev/docs/api/request#path}\n *\n * @example\n * ```ts\n * app.get('/about/me', (c) => {\n * const pathname = c.req.path // `/about/me`\n * })\n * ```\n */\n path;\n bodyCache = {};\n constructor(request, path = \"/\", matchResult = [[]]) {\n this.raw = request;\n this.path = path;\n this.#matchResult = matchResult;\n this.#validatedData = {};\n }\n param(key) {\n return key ? this.#getDecodedParam(key) : this.#getAllDecodedParams();\n }\n #getDecodedParam(key) {\n const paramKey = this.#matchResult[0][this.routeIndex][1][key];\n const param = this.#getParamValue(paramKey);\n return param && /\\%/.test(param) ? tryDecodeURIComponent(param) : param;\n }\n #getAllDecodedParams() {\n const decoded = {};\n const keys = Object.keys(this.#matchResult[0][this.routeIndex][1]);\n for (const key of keys) {\n const value = this.#getParamValue(this.#matchResult[0][this.routeIndex][1][key]);\n if (value !== void 0) {\n decoded[key] = /\\%/.test(value) ? tryDecodeURIComponent(value) : value;\n }\n }\n return decoded;\n }\n #getParamValue(paramKey) {\n return this.#matchResult[1] ? this.#matchResult[1][paramKey] : paramKey;\n }\n query(key) {\n return getQueryParam(this.url, key);\n }\n queries(key) {\n return getQueryParams(this.url, key);\n }\n header(name) {\n if (name) {\n return this.raw.headers.get(name) ?? void 0;\n }\n const headerData = {};\n this.raw.headers.forEach((value, key) => {\n headerData[key] = value;\n });\n return headerData;\n }\n async parseBody(options) {\n return this.bodyCache.parsedBody ??= await parseBody(this, options);\n }\n #cachedBody = (key) => {\n const { bodyCache, raw } = this;\n const cachedBody = bodyCache[key];\n if (cachedBody) {\n return cachedBody;\n }\n const anyCachedKey = Object.keys(bodyCache)[0];\n if (anyCachedKey) {\n return bodyCache[anyCachedKey].then((body) => {\n if (anyCachedKey === \"json\") {\n body = JSON.stringify(body);\n }\n return new Response(body)[key]();\n });\n }\n return bodyCache[key] = raw[key]();\n };\n /**\n * `.json()` can parse Request body of type `application/json`\n *\n * @see {@link https://hono.dev/docs/api/request#json}\n *\n * @example\n * ```ts\n * app.post('/entry', async (c) => {\n * const body = await c.req.json()\n * })\n * ```\n */\n json() {\n return this.#cachedBody(\"text\").then((text) => JSON.parse(text));\n }\n /**\n * `.text()` can parse Request body of type `text/plain`\n *\n * @see {@link https://hono.dev/docs/api/request#text}\n *\n * @example\n * ```ts\n * app.post('/entry', async (c) => {\n * const body = await c.req.text()\n * })\n * ```\n */\n text() {\n return this.#cachedBody(\"text\");\n }\n /**\n * `.arrayBuffer()` parse Request body as an `ArrayBuffer`\n *\n * @see {@link https://hono.dev/docs/api/request#arraybuffer}\n *\n * @example\n * ```ts\n * app.post('/entry', async (c) => {\n * const body = await c.req.arrayBuffer()\n * })\n * ```\n */\n arrayBuffer() {\n return this.#cachedBody(\"arrayBuffer\");\n }\n /**\n * Parses the request body as a `Blob`.\n * @example\n * ```ts\n * app.post('/entry', async (c) => {\n * const body = await c.req.blob();\n * });\n * ```\n * @see https://hono.dev/docs/api/request#blob\n */\n blob() {\n return this.#cachedBody(\"blob\");\n }\n /**\n * Parses the request body as `FormData`.\n * @example\n * ```ts\n * app.post('/entry', async (c) => {\n * const body = await c.req.formData();\n * });\n * ```\n * @see https://hono.dev/docs/api/request#formdata\n */\n formData() {\n return this.#cachedBody(\"formData\");\n }\n /**\n * Adds validated data to the request.\n *\n * @param target - The target of the validation.\n * @param data - The validated data to add.\n */\n addValidatedData(target, data) {\n this.#validatedData[target] = data;\n }\n valid(target) {\n return this.#validatedData[target];\n }\n /**\n * `.url()` can get the request url strings.\n *\n * @see {@link https://hono.dev/docs/api/request#url}\n *\n * @example\n * ```ts\n * app.get('/about/me', (c) => {\n * const url = c.req.url // `http://localhost:8787/about/me`\n * ...\n * })\n * ```\n */\n get url() {\n return this.raw.url;\n }\n /**\n * `.method()` can get the method name of the request.\n *\n * @see {@link https://hono.dev/docs/api/request#method}\n *\n * @example\n * ```ts\n * app.get('/about/me', (c) => {\n * const method = c.req.method // `GET`\n * })\n * ```\n */\n get method() {\n return this.raw.method;\n }\n get [GET_MATCH_RESULT]() {\n return this.#matchResult;\n }\n /**\n * `.matchedRoutes()` can return a matched route in the handler\n *\n * @deprecated\n *\n * Use matchedRoutes helper defined in \"hono/route\" instead.\n *\n * @see {@link https://hono.dev/docs/api/request#matchedroutes}\n *\n * @example\n * ```ts\n * app.use('*', async function logger(c, next) {\n * await next()\n * c.req.matchedRoutes.forEach(({ handler, method, path }, i) => {\n * const name = handler.name || (handler.length < 2 ? '[handler]' : '[middleware]')\n * console.log(\n * method,\n * ' ',\n * path,\n * ' '.repeat(Math.max(10 - path.length, 0)),\n * name,\n * i === c.req.routeIndex ? '<- respond from here' : ''\n * )\n * })\n * })\n * ```\n */\n get matchedRoutes() {\n return this.#matchResult[0].map(([[, route]]) => route);\n }\n /**\n * `routePath()` can retrieve the path registered within the handler\n *\n * @deprecated\n *\n * Use routePath helper defined in \"hono/route\" instead.\n *\n * @see {@link https://hono.dev/docs/api/request#routepath}\n *\n * @example\n * ```ts\n * app.get('/posts/:id', (c) => {\n * return c.json({ path: c.req.routePath })\n * })\n * ```\n */\n get routePath() {\n return this.#matchResult[0].map(([[, route]]) => route)[this.routeIndex].path;\n }\n};\nvar cloneRawRequest = async (req) => {\n if (!req.raw.bodyUsed) {\n return req.raw.clone();\n }\n const cacheKey = Object.keys(req.bodyCache)[0];\n if (!cacheKey) {\n throw new HTTPException(500, {\n message: \"Cannot clone request: body was already consumed and not cached. Please use HonoRequest methods (e.g., req.json(), req.text()) instead of consuming req.raw directly.\"\n });\n }\n const requestInit = {\n body: await req[cacheKey](),\n cache: req.raw.cache,\n credentials: req.raw.credentials,\n headers: req.header(),\n integrity: req.raw.integrity,\n keepalive: req.raw.keepalive,\n method: req.method,\n mode: req.raw.mode,\n redirect: req.raw.redirect,\n referrer: req.raw.referrer,\n referrerPolicy: req.raw.referrerPolicy,\n signal: req.raw.signal\n };\n return new Request(req.url, requestInit);\n};\nexport {\n HonoRequest,\n cloneRawRequest\n};\n","// src/utils/html.ts\nvar HtmlEscapedCallbackPhase = {\n Stringify: 1,\n BeforeStream: 2,\n Stream: 3\n};\nvar raw = (value, callbacks) => {\n const escapedString = new String(value);\n escapedString.isEscaped = true;\n escapedString.callbacks = callbacks;\n return escapedString;\n};\nvar escapeRe = /[&<>'\"]/;\nvar stringBufferToString = async (buffer, callbacks) => {\n let str = \"\";\n callbacks ||= [];\n const resolvedBuffer = await Promise.all(buffer);\n for (let i = resolvedBuffer.length - 1; ; i--) {\n str += resolvedBuffer[i];\n i--;\n if (i < 0) {\n break;\n }\n let r = resolvedBuffer[i];\n if (typeof r === \"object\") {\n callbacks.push(...r.callbacks || []);\n }\n const isEscaped = r.isEscaped;\n r = await (typeof r === \"object\" ? r.toString() : r);\n if (typeof r === \"object\") {\n callbacks.push(...r.callbacks || []);\n }\n if (r.isEscaped ?? isEscaped) {\n str += r;\n } else {\n const buf = [str];\n escapeToBuffer(r, buf);\n str = buf[0];\n }\n }\n return raw(str, callbacks);\n};\nvar escapeToBuffer = (str, buffer) => {\n const match = str.search(escapeRe);\n if (match === -1) {\n buffer[0] += str;\n return;\n }\n let escape;\n let index;\n let lastIndex = 0;\n for (index = match; index < str.length; index++) {\n switch (str.charCodeAt(index)) {\n case 34:\n escape = \"&quot;\";\n break;\n case 39:\n escape = \"&#39;\";\n break;\n case 38:\n escape = \"&amp;\";\n break;\n case 60:\n escape = \"&lt;\";\n break;\n case 62:\n escape = \"&gt;\";\n break;\n default:\n continue;\n }\n buffer[0] += str.substring(lastIndex, index) + escape;\n lastIndex = index + 1;\n }\n buffer[0] += str.substring(lastIndex, index);\n};\nvar resolveCallbackSync = (str) => {\n const callbacks = str.callbacks;\n if (!callbacks?.length) {\n return str;\n }\n const buffer = [str];\n const context = {};\n callbacks.forEach((c) => c({ phase: HtmlEscapedCallbackPhase.Stringify, buffer, context }));\n return buffer[0];\n};\nvar resolveCallback = async (str, phase, preserveCallbacks, context, buffer) => {\n if (typeof str === \"object\" && !(str instanceof String)) {\n if (!(str instanceof Promise)) {\n str = str.toString();\n }\n if (str instanceof Promise) {\n str = await str;\n }\n }\n const callbacks = str.callbacks;\n if (!callbacks?.length) {\n return Promise.resolve(str);\n }\n if (buffer) {\n buffer[0] += str;\n } else {\n buffer = [str];\n }\n const resStr = Promise.all(callbacks.map((c) => c({ phase, buffer, context }))).then(\n (res) => Promise.all(\n res.filter(Boolean).map((str2) => resolveCallback(str2, phase, false, context, buffer))\n ).then(() => buffer[0])\n );\n if (preserveCallbacks) {\n return raw(await resStr, callbacks);\n } else {\n return resStr;\n }\n};\nexport {\n HtmlEscapedCallbackPhase,\n escapeToBuffer,\n raw,\n resolveCallback,\n resolveCallbackSync,\n stringBufferToString\n};\n","// src/context.ts\nimport { HonoRequest } from \"./request.js\";\nimport { HtmlEscapedCallbackPhase, resolveCallback } from \"./utils/html.js\";\nvar TEXT_PLAIN = \"text/plain; charset=UTF-8\";\nvar setDefaultContentType = (contentType, headers) => {\n return {\n \"Content-Type\": contentType,\n ...headers\n };\n};\nvar createResponseInstance = (body, init) => new Response(body, init);\nvar Context = class {\n #rawRequest;\n #req;\n /**\n * `.env` can get bindings (environment variables, secrets, KV namespaces, D1 database, R2 bucket etc.) in Cloudflare Workers.\n *\n * @see {@link https://hono.dev/docs/api/context#env}\n *\n * @example\n * ```ts\n * // Environment object for Cloudflare Workers\n * app.get('*', async c => {\n * const counter = c.env.COUNTER\n * })\n * ```\n */\n env = {};\n #var;\n finalized = false;\n /**\n * `.error` can get the error object from the middleware if the Handler throws an error.\n *\n * @see {@link https://hono.dev/docs/api/context#error}\n *\n * @example\n * ```ts\n * app.use('*', async (c, next) => {\n * await next()\n * if (c.error) {\n * // do something...\n * }\n * })\n * ```\n */\n error;\n #status;\n #executionCtx;\n #res;\n #layout;\n #renderer;\n #notFoundHandler;\n #preparedHeaders;\n #matchResult;\n #path;\n /**\n * Creates an instance of the Context class.\n *\n * @param req - The Request object.\n * @param options - Optional configuration options for the context.\n */\n constructor(req, options) {\n this.#rawRequest = req;\n if (options) {\n this.#executionCtx = options.executionCtx;\n this.env = options.env;\n this.#notFoundHandler = options.notFoundHandler;\n this.#path = options.path;\n this.#matchResult = options.matchResult;\n }\n }\n /**\n * `.req` is the instance of {@link HonoRequest}.\n */\n get req() {\n this.#req ??= new HonoRequest(this.#rawRequest, this.#path, this.#matchResult);\n return this.#req;\n }\n /**\n * @see {@link https://hono.dev/docs/api/context#event}\n * The FetchEvent associated with the current request.\n *\n * @throws Will throw an error if the context does not have a FetchEvent.\n */\n get event() {\n if (this.#executionCtx && \"respondWith\" in this.#executionCtx) {\n return this.#executionCtx;\n } else {\n throw Error(\"This context has no FetchEvent\");\n }\n }\n /**\n * @see {@link https://hono.dev/docs/api/context#executionctx}\n * The ExecutionContext associated with the current request.\n *\n * @throws Will throw an error if the context does not have an ExecutionContext.\n */\n get executionCtx() {\n if (this.#executionCtx) {\n return this.#executionCtx;\n } else {\n throw Error(\"This context has no ExecutionContext\");\n }\n }\n /**\n * @see {@link https://hono.dev/docs/api/context#res}\n * The Response object for the current request.\n */\n get res() {\n return this.#res ||= createResponseInstance(null, {\n headers: this.#preparedHeaders ??= new Headers()\n });\n }\n /**\n * Sets the Response object for the current request.\n *\n * @param _res - The Response object to set.\n */\n set res(_res) {\n if (this.#res && _res) {\n _res = createResponseInstance(_res.body, _res);\n for (const [k, v] of this.#res.headers.entries()) {\n if (k === \"content-type\") {\n continue;\n }\n if (k === \"set-cookie\") {\n const cookies = this.#res.headers.getSetCookie();\n _res.headers.delete(\"set-cookie\");\n for (const cookie of cookies) {\n _res.headers.append(\"set-cookie\", cookie);\n }\n } else {\n _res.headers.set(k, v);\n }\n }\n }\n this.#res = _res;\n this.finalized = true;\n }\n /**\n * `.render()` can create a response within a layout.\n *\n * @see {@link https://hono.dev/docs/api/context#render-setrenderer}\n *\n * @example\n * ```ts\n * app.get('/', (c) => {\n * return c.render('Hello!')\n * })\n * ```\n */\n render = (...args) => {\n this.#renderer ??= (content) => this.html(content);\n return this.#renderer(...args);\n };\n /**\n * Sets the layout for the response.\n *\n * @param layout - The layout to set.\n * @returns The layout function.\n */\n setLayout = (layout) => this.#layout = layout;\n /**\n * Gets the current layout for the response.\n *\n * @returns The current layout function.\n */\n getLayout = () => this.#layout;\n /**\n * `.setRenderer()` can set the layout in the custom middleware.\n *\n * @see {@link https://hono.dev/docs/api/context#render-setrenderer}\n *\n * @example\n * ```tsx\n * app.use('*', async (c, next) => {\n * c.setRenderer((content) => {\n * return c.html(\n * <html>\n * <body>\n * <p>{content}</p>\n * </body>\n * </html>\n * )\n * })\n * await next()\n * })\n * ```\n */\n setRenderer = (renderer) => {\n this.#renderer = renderer;\n };\n /**\n * `.header()` can set headers.\n *\n * @see {@link https://hono.dev/docs/api/context#header}\n *\n * @example\n * ```ts\n * app.get('/welcome', (c) => {\n * // Set headers\n * c.header('X-Message', 'Hello!')\n * c.header('Content-Type', 'text/plain')\n *\n * return c.body('Thank you for coming')\n * })\n * ```\n */\n header = (name, value, options) => {\n if (this.finalized) {\n this.#res = createResponseInstance(this.#res.body, this.#res);\n }\n const headers = this.#res ? this.#res.headers : this.#preparedHeaders ??= new Headers();\n if (value === void 0) {\n headers.delete(name);\n } else if (options?.append) {\n headers.append(name, value);\n } else {\n headers.set(name, value);\n }\n };\n status = (status) => {\n this.#status = status;\n };\n /**\n * `.set()` can set the value specified by the key.\n *\n * @see {@link https://hono.dev/docs/api/context#set-get}\n *\n * @example\n * ```ts\n * app.use('*', async (c, next) => {\n * c.set('message', 'Hono is hot!!')\n * await next()\n * })\n * ```\n */\n set = (key, value) => {\n this.#var ??= /* @__PURE__ */ new Map();\n this.#var.set(key, value);\n };\n /**\n * `.get()` can use the value specified by the key.\n *\n * @see {@link https://hono.dev/docs/api/context#set-get}\n *\n * @example\n * ```ts\n * app.get('/', (c) => {\n * const message = c.get('message')\n * return c.text(`The message is \"${message}\"`)\n * })\n * ```\n */\n get = (key) => {\n return this.#var ? this.#var.get(key) : void 0;\n };\n /**\n * `.var` can access the value of a variable.\n *\n * @see {@link https://hono.dev/docs/api/context#var}\n *\n * @example\n * ```ts\n * const result = c.var.client.oneMethod()\n * ```\n */\n // c.var.propName is a read-only\n get var() {\n if (!this.#var) {\n return {};\n }\n return Object.fromEntries(this.#var);\n }\n #newResponse(data, arg, headers) {\n const responseHeaders = this.#res ? new Headers(this.#res.headers) : this.#preparedHeaders ?? new Headers();\n if (typeof arg === \"object\" && \"headers\" in arg) {\n const argHeaders = arg.headers instanceof Headers ? arg.headers : new Headers(arg.headers);\n for (const [key, value] of argHeaders) {\n if (key.toLowerCase() === \"set-cookie\") {\n responseHeaders.append(key, value);\n } else {\n responseHeaders.set(key, value);\n }\n }\n }\n if (headers) {\n for (const [k, v] of Object.entries(headers)) {\n if (typeof v === \"string\") {\n responseHeaders.set(k, v);\n } else {\n responseHeaders.delete(k);\n for (const v2 of v) {\n responseHeaders.append(k, v2);\n }\n }\n }\n }\n const status = typeof arg === \"number\" ? arg : arg?.status ?? this.#status;\n return createResponseInstance(data, { status, headers: responseHeaders });\n }\n newResponse = (...args) => this.#newResponse(...args);\n /**\n * `.body()` can return the HTTP response.\n * You can set headers with `.header()` and set HTTP status code with `.status`.\n * This can also be set in `.text()`, `.json()` and so on.\n *\n * @see {@link https://hono.dev/docs/api/context#body}\n *\n * @example\n * ```ts\n * app.get('/welcome', (c) => {\n * // Set headers\n * c.header('X-Message', 'Hello!')\n * c.header('Content-Type', 'text/plain')\n * // Set HTTP status code\n * c.status(201)\n *\n * // Return the response body\n * return c.body('Thank you for coming')\n * })\n * ```\n */\n body = (data, arg, headers) => this.#newResponse(data, arg, headers);\n /**\n * `.text()` can render text as `Content-Type:text/plain`.\n *\n * @see {@link https://hono.dev/docs/api/context#text}\n *\n * @example\n * ```ts\n * app.get('/say', (c) => {\n * return c.text('Hello!')\n * })\n * ```\n */\n text = (text, arg, headers) => {\n return !this.#preparedHeaders && !this.#status && !arg && !headers && !this.finalized ? new Response(text) : this.#newResponse(\n text,\n arg,\n setDefaultContentType(TEXT_PLAIN, headers)\n );\n };\n /**\n * `.json()` can render JSON as `Content-Type:application/json`.\n *\n * @see {@link https://hono.dev/docs/api/context#json}\n *\n * @example\n * ```ts\n * app.get('/api', (c) => {\n * return c.json({ message: 'Hello!' })\n * })\n * ```\n */\n json = (object, arg, headers) => {\n return this.#newResponse(\n JSON.stringify(object),\n arg,\n setDefaultContentType(\"application/json\", headers)\n );\n };\n html = (html, arg, headers) => {\n const res = (html2) => this.#newResponse(html2, arg, setDefaultContentType(\"text/html; charset=UTF-8\", headers));\n return typeof html === \"object\" ? resolveCallback(html, HtmlEscapedCallbackPhase.Stringify, false, {}).then(res) : res(html);\n };\n /**\n * `.redirect()` can Redirect, default status code is 302.\n *\n * @see {@link https://hono.dev/docs/api/context#redirect}\n *\n * @example\n * ```ts\n * app.get('/redirect', (c) => {\n * return c.redirect('/')\n * })\n * app.get('/redirect-permanently', (c) => {\n * return c.redirect('/', 301)\n * })\n * ```\n */\n redirect = (location, status) => {\n const locationString = String(location);\n this.header(\n \"Location\",\n // Multibyes should be encoded\n // eslint-disable-next-line no-control-regex\n !/[^\\x00-\\xFF]/.test(locationString) ? locationString : encodeURI(locationString)\n );\n return this.newResponse(null, status ?? 302);\n };\n /**\n * `.notFound()` can return the Not Found Response.\n *\n * @see {@link https://hono.dev/docs/api/context#notfound}\n *\n * @example\n * ```ts\n * app.get('/notfound', (c) => {\n * return c.notFound()\n * })\n * ```\n */\n notFound = () => {\n this.#notFoundHandler ??= () => createResponseInstance();\n return this.#notFoundHandler(this);\n };\n};\nexport {\n Context,\n TEXT_PLAIN\n};\n","// src/router.ts\nvar METHOD_NAME_ALL = \"ALL\";\nvar METHOD_NAME_ALL_LOWERCASE = \"all\";\nvar METHODS = [\"get\", \"post\", \"put\", \"delete\", \"options\", \"patch\"];\nvar MESSAGE_MATCHER_IS_ALREADY_BUILT = \"Can not add a route since the matcher is already built.\";\nvar UnsupportedPathError = class extends Error {\n};\nexport {\n MESSAGE_MATCHER_IS_ALREADY_BUILT,\n METHODS,\n METHOD_NAME_ALL,\n METHOD_NAME_ALL_LOWERCASE,\n UnsupportedPathError\n};\n","// src/utils/constants.ts\nvar COMPOSED_HANDLER = \"__COMPOSED_HANDLER\";\nexport {\n COMPOSED_HANDLER\n};\n","// src/hono-base.ts\nimport { compose } from \"./compose.js\";\nimport { Context } from \"./context.js\";\nimport { METHODS, METHOD_NAME_ALL, METHOD_NAME_ALL_LOWERCASE } from \"./router.js\";\nimport { COMPOSED_HANDLER } from \"./utils/constants.js\";\nimport { getPath, getPathNoStrict, mergePath } from \"./utils/url.js\";\nvar notFoundHandler = (c) => {\n return c.text(\"404 Not Found\", 404);\n};\nvar errorHandler = (err, c) => {\n if (\"getResponse\" in err) {\n const res = err.getResponse();\n return c.newResponse(res.body, res);\n }\n console.error(err);\n return c.text(\"Internal Server Error\", 500);\n};\nvar Hono = class _Hono {\n get;\n post;\n put;\n delete;\n options;\n patch;\n all;\n on;\n use;\n /*\n This class is like an abstract class and does not have a router.\n To use it, inherit the class and implement router in the constructor.\n */\n router;\n getPath;\n // Cannot use `#` because it requires visibility at JavaScript runtime.\n _basePath = \"/\";\n #path = \"/\";\n routes = [];\n constructor(options = {}) {\n const allMethods = [...METHODS, METHOD_NAME_ALL_LOWERCASE];\n allMethods.forEach((method) => {\n this[method] = (args1, ...args) => {\n if (typeof args1 === \"string\") {\n this.#path = args1;\n } else {\n this.#addRoute(method, this.#path, args1);\n }\n args.forEach((handler) => {\n this.#addRoute(method, this.#path, handler);\n });\n return this;\n };\n });\n this.on = (method, path, ...handlers) => {\n for (const p of [path].flat()) {\n this.#path = p;\n for (const m of [method].flat()) {\n handlers.map((handler) => {\n this.#addRoute(m.toUpperCase(), this.#path, handler);\n });\n }\n }\n return this;\n };\n this.use = (arg1, ...handlers) => {\n if (typeof arg1 === \"string\") {\n this.#path = arg1;\n } else {\n this.#path = \"*\";\n handlers.unshift(arg1);\n }\n handlers.forEach((handler) => {\n this.#addRoute(METHOD_NAME_ALL, this.#path, handler);\n });\n return this;\n };\n const { strict, ...optionsWithoutStrict } = options;\n Object.assign(this, optionsWithoutStrict);\n this.getPath = strict ?? true ? options.getPath ?? getPath : getPathNoStrict;\n }\n #clone() {\n const clone = new _Hono({\n router: this.router,\n getPath: this.getPath\n });\n clone.errorHandler = this.errorHandler;\n clone.#notFoundHandler = this.#notFoundHandler;\n clone.routes = this.routes;\n return clone;\n }\n #notFoundHandler = notFoundHandler;\n // Cannot use `#` because it requires visibility at JavaScript runtime.\n errorHandler = errorHandler;\n /**\n * `.route()` allows grouping other Hono instance in routes.\n *\n * @see {@link https://hono.dev/docs/api/routing#grouping}\n *\n * @param {string} path - base Path\n * @param {Hono} app - other Hono instance\n * @returns {Hono} routed Hono instance\n *\n * @example\n * ```ts\n * const app = new Hono()\n * const app2 = new Hono()\n *\n * app2.get(\"/user\", (c) => c.text(\"user\"))\n * app.route(\"/api\", app2) // GET /api/user\n * ```\n */\n route(path, app) {\n const subApp = this.basePath(path);\n app.routes.map((r) => {\n let handler;\n if (app.errorHandler === errorHandler) {\n handler = r.handler;\n } else {\n handler = async (c, next) => (await compose([], app.errorHandler)(c, () => r.handler(c, next))).res;\n handler[COMPOSED_HANDLER] = r.handler;\n }\n subApp.#addRoute(r.method, r.path, handler);\n });\n return this;\n }\n /**\n * `.basePath()` allows base paths to be specified.\n *\n * @see {@link https://hono.dev/docs/api/routing#base-path}\n *\n * @param {string} path - base Path\n * @returns {Hono} changed Hono instance\n *\n * @example\n * ```ts\n * const api = new Hono().basePath('/api')\n * ```\n */\n basePath(path) {\n const subApp = this.#clone();\n subApp._basePath = mergePath(this._basePath, path);\n return subApp;\n }\n /**\n * `.onError()` handles an error and returns a customized Response.\n *\n * @see {@link https://hono.dev/docs/api/hono#error-handling}\n *\n * @param {ErrorHandler} handler - request Handler for error\n * @returns {Hono} changed Hono instance\n *\n * @example\n * ```ts\n * app.onError((err, c) => {\n * console.error(`${err}`)\n * return c.text('Custom Error Message', 500)\n * })\n * ```\n */\n onError = (handler) => {\n this.errorHandler = handler;\n return this;\n };\n /**\n * `.notFound()` allows you to customize a Not Found Response.\n *\n * @see {@link https://hono.dev/docs/api/hono#not-found}\n *\n * @param {NotFoundHandler} handler - request handler for not-found\n * @returns {Hono} changed Hono instance\n *\n * @example\n * ```ts\n * app.notFound((c) => {\n * return c.text('Custom 404 Message', 404)\n * })\n * ```\n */\n notFound = (handler) => {\n this.#notFoundHandler = handler;\n return this;\n };\n /**\n * `.mount()` allows you to mount applications built with other frameworks into your Hono application.\n *\n * @see {@link https://hono.dev/docs/api/hono#mount}\n *\n * @param {string} path - base Path\n * @param {Function} applicationHandler - other Request Handler\n * @param {MountOptions} [options] - options of `.mount()`\n * @returns {Hono} mounted Hono instance\n *\n * @example\n * ```ts\n * import { Router as IttyRouter } from 'itty-router'\n * import { Hono } from 'hono'\n * // Create itty-router application\n * const ittyRouter = IttyRouter()\n * // GET /itty-router/hello\n * ittyRouter.get('/hello', () => new Response('Hello from itty-router'))\n *\n * const app = new Hono()\n * app.mount('/itty-router', ittyRouter.handle)\n * ```\n *\n * @example\n * ```ts\n * const app = new Hono()\n * // Send the request to another application without modification.\n * app.mount('/app', anotherApp, {\n * replaceRequest: (req) => req,\n * })\n * ```\n */\n mount(path, applicationHandler, options) {\n let replaceRequest;\n let optionHandler;\n if (options) {\n if (typeof options === \"function\") {\n optionHandler = options;\n } else {\n optionHandler = options.optionHandler;\n if (options.replaceRequest === false) {\n replaceRequest = (request) => request;\n } else {\n replaceRequest = options.replaceRequest;\n }\n }\n }\n const getOptions = optionHandler ? (c) => {\n const options2 = optionHandler(c);\n return Array.isArray(options2) ? options2 : [options2];\n } : (c) => {\n let executionContext = void 0;\n try {\n executionContext = c.executionCtx;\n } catch {\n }\n return [c.env, executionContext];\n };\n replaceRequest ||= (() => {\n const mergedPath = mergePath(this._basePath, path);\n const pathPrefixLength = mergedPath === \"/\" ? 0 : mergedPath.length;\n return (request) => {\n const url = new URL(request.url);\n url.pathname = url.pathname.slice(pathPrefixLength) || \"/\";\n return new Request(url, request);\n };\n })();\n const handler = async (c, next) => {\n const res = await applicationHandler(replaceRequest(c.req.raw), ...getOptions(c));\n if (res) {\n return res;\n }\n await next();\n };\n this.#addRoute(METHOD_NAME_ALL, mergePath(path, \"*\"), handler);\n return this;\n }\n #addRoute(method, path, handler) {\n method = method.toUpperCase();\n path = mergePath(this._basePath, path);\n const r = { basePath: this._basePath, path, method, handler };\n this.router.add(method, path, [handler, r]);\n this.routes.push(r);\n }\n #handleError(err, c) {\n if (err instanceof Error) {\n return this.errorHandler(err, c);\n }\n throw err;\n }\n #dispatch(request, executionCtx, env, method) {\n if (method === \"HEAD\") {\n return (async () => new Response(null, await this.#dispatch(request, executionCtx, env, \"GET\")))();\n }\n const path = this.getPath(request, { env });\n const matchResult = this.router.match(method, path);\n const c = new Context(request, {\n path,\n matchResult,\n env,\n executionCtx,\n notFoundHandler: this.#notFoundHandler\n });\n if (matchResult[0].length === 1) {\n let res;\n try {\n res = matchResult[0][0][0][0](c, async () => {\n c.res = await this.#notFoundHandler(c);\n });\n } catch (err) {\n return this.#handleError(err, c);\n }\n return res instanceof Promise ? res.then(\n (resolved) => resolved || (c.finalized ? c.res : this.#notFoundHandler(c))\n ).catch((err) => this.#handleError(err, c)) : res ?? this.#notFoundHandler(c);\n }\n const composed = compose(matchResult[0], this.errorHandler, this.#notFoundHandler);\n return (async () => {\n try {\n const context = await composed(c);\n if (!context.finalized) {\n throw new Error(\n \"Context is not finalized. Did you forget to return a Response object or `await next()`?\"\n );\n }\n return context.res;\n } catch (err) {\n return this.#handleError(err, c);\n }\n })();\n }\n /**\n * `.fetch()` will be entry point of your app.\n *\n * @see {@link https://hono.dev/docs/api/hono#fetch}\n *\n * @param {Request} request - request Object of request\n * @param {Env} Env - env Object\n * @param {ExecutionContext} - context of execution\n * @returns {Response | Promise<Response>} response of request\n *\n */\n fetch = (request, ...rest) => {\n return this.#dispatch(request, rest[1], rest[0], request.method);\n };\n /**\n * `.request()` is a useful method for testing.\n * You can pass a URL or pathname to send a GET request.\n * app will return a Response object.\n * ```ts\n * test('GET /hello is ok', async () => {\n * const res = await app.request('/hello')\n * expect(res.status).toBe(200)\n * })\n * ```\n * @see https://hono.dev/docs/api/hono#request\n */\n request = (input, requestInit, Env, executionCtx) => {\n if (input instanceof Request) {\n return this.fetch(requestInit ? new Request(input, requestInit) : input, Env, executionCtx);\n }\n input = input.toString();\n return this.fetch(\n new Request(\n /^https?:\\/\\//.test(input) ? input : `http://localhost${mergePath(\"/\", input)}`,\n requestInit\n ),\n Env,\n executionCtx\n );\n };\n /**\n * `.fire()` automatically adds a global fetch event listener.\n * This can be useful for environments that adhere to the Service Worker API, such as non-ES module Cloudflare Workers.\n * @deprecated\n * Use `fire` from `hono/service-worker` instead.\n * ```ts\n * import { Hono } from 'hono'\n * import { fire } from 'hono/service-worker'\n *\n * const app = new Hono()\n * // ...\n * fire(app)\n * ```\n * @see https://hono.dev/docs/api/hono#fire\n * @see https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API\n * @see https://developers.cloudflare.com/workers/reference/migrate-to-module-workers/\n */\n fire = () => {\n addEventListener(\"fetch\", (event) => {\n event.respondWith(this.#dispatch(event.request, event, void 0, event.request.method));\n });\n };\n};\nexport {\n Hono as HonoBase\n};\n","// src/router/reg-exp-router/matcher.ts\nimport { METHOD_NAME_ALL } from \"../../router.js\";\nvar emptyParam = [];\nfunction match(method, path) {\n const matchers = this.buildAllMatchers();\n const match2 = ((method2, path2) => {\n const matcher = matchers[method2] || matchers[METHOD_NAME_ALL];\n const staticMatch = matcher[2][path2];\n if (staticMatch) {\n return staticMatch;\n }\n const match3 = path2.match(matcher[0]);\n if (!match3) {\n return [[], emptyParam];\n }\n const index = match3.indexOf(\"\", 1);\n return [matcher[1][index], match3];\n });\n this.match = match2;\n return match2(method, path);\n}\nexport {\n emptyParam,\n match\n};\n","// src/router/reg-exp-router/node.ts\nvar LABEL_REG_EXP_STR = \"[^/]+\";\nvar ONLY_WILDCARD_REG_EXP_STR = \".*\";\nvar TAIL_WILDCARD_REG_EXP_STR = \"(?:|/.*)\";\nvar PATH_ERROR = /* @__PURE__ */ Symbol();\nvar regExpMetaChars = new Set(\".\\\\+*[^]$()\");\nfunction compareKey(a, b) {\n if (a.length === 1) {\n return b.length === 1 ? a < b ? -1 : 1 : -1;\n }\n if (b.length === 1) {\n return 1;\n }\n if (a === ONLY_WILDCARD_REG_EXP_STR || a === TAIL_WILDCARD_REG_EXP_STR) {\n return 1;\n } else if (b === ONLY_WILDCARD_REG_EXP_STR || b === TAIL_WILDCARD_REG_EXP_STR) {\n return -1;\n }\n if (a === LABEL_REG_EXP_STR) {\n return 1;\n } else if (b === LABEL_REG_EXP_STR) {\n return -1;\n }\n return a.length === b.length ? a < b ? -1 : 1 : b.length - a.length;\n}\nvar Node = class _Node {\n #index;\n #varIndex;\n #children = /* @__PURE__ */ Object.create(null);\n insert(tokens, index, paramMap, context, pathErrorCheckOnly) {\n if (tokens.length === 0) {\n if (this.#index !== void 0) {\n throw PATH_ERROR;\n }\n if (pathErrorCheckOnly) {\n return;\n }\n this.#index = index;\n return;\n }\n const [token, ...restTokens] = tokens;\n const pattern = token === \"*\" ? restTokens.length === 0 ? [\"\", \"\", ONLY_WILDCARD_REG_EXP_STR] : [\"\", \"\", LABEL_REG_EXP_STR] : token === \"/*\" ? [\"\", \"\", TAIL_WILDCARD_REG_EXP_STR] : token.match(/^\\:([^\\{\\}]+)(?:\\{(.+)\\})?$/);\n let node;\n if (pattern) {\n const name = pattern[1];\n let regexpStr = pattern[2] || LABEL_REG_EXP_STR;\n if (name && pattern[2]) {\n if (regexpStr === \".*\") {\n throw PATH_ERROR;\n }\n regexpStr = regexpStr.replace(/^\\((?!\\?:)(?=[^)]+\\)$)/, \"(?:\");\n if (/\\((?!\\?:)/.test(regexpStr)) {\n throw PATH_ERROR;\n }\n }\n node = this.#children[regexpStr];\n if (!node) {\n if (Object.keys(this.#children).some(\n (k) => k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR\n )) {\n throw PATH_ERROR;\n }\n if (pathErrorCheckOnly) {\n return;\n }\n node = this.#children[regexpStr] = new _Node();\n if (name !== \"\") {\n node.#varIndex = context.varIndex++;\n }\n }\n if (!pathErrorCheckOnly && name !== \"\") {\n paramMap.push([name, node.#varIndex]);\n }\n } else {\n node = this.#children[token];\n if (!node) {\n if (Object.keys(this.#children).some(\n (k) => k.length > 1 && k !== ONLY_WILDCARD_REG_EXP_STR && k !== TAIL_WILDCARD_REG_EXP_STR\n )) {\n throw PATH_ERROR;\n }\n if (pathErrorCheckOnly) {\n return;\n }\n node = this.#children[token] = new _Node();\n }\n }\n node.insert(restTokens, index, paramMap, context, pathErrorCheckOnly);\n }\n buildRegExpStr() {\n const childKeys = Object.keys(this.#children).sort(compareKey);\n const strList = childKeys.map((k) => {\n const c = this.#children[k];\n return (typeof c.#varIndex === \"number\" ? `(${k})@${c.#varIndex}` : regExpMetaChars.has(k) ? `\\\\${k}` : k) + c.buildRegExpStr();\n });\n if (typeof this.#index === \"number\") {\n strList.unshift(`#${this.#index}`);\n }\n if (strList.length === 0) {\n return \"\";\n }\n if (strList.length === 1) {\n return strList[0];\n }\n return \"(?:\" + strList.join(\"|\") + \")\";\n }\n};\nexport {\n Node,\n PATH_ERROR\n};\n","// src/router/reg-exp-router/trie.ts\nimport { Node } from \"./node.js\";\nvar Trie = class {\n #context = { varIndex: 0 };\n #root = new Node();\n insert(path, index, pathErrorCheckOnly) {\n const paramAssoc = [];\n const groups = [];\n for (let i = 0; ; ) {\n let replaced = false;\n path = path.replace(/\\{[^}]+\\}/g, (m) => {\n const mark = `@\\\\${i}`;\n groups[i] = [mark, m];\n i++;\n replaced = true;\n return mark;\n });\n if (!replaced) {\n break;\n }\n }\n const tokens = path.match(/(?::[^\\/]+)|(?:\\/\\*$)|./g) || [];\n for (let i = groups.length - 1; i >= 0; i--) {\n const [mark] = groups[i];\n for (let j = tokens.length - 1; j >= 0; j--) {\n if (tokens[j].indexOf(mark) !== -1) {\n tokens[j] = tokens[j].replace(mark, groups[i][1]);\n break;\n }\n }\n }\n this.#root.insert(tokens, index, paramAssoc, this.#context, pathErrorCheckOnly);\n return paramAssoc;\n }\n buildRegExp() {\n let regexp = this.#root.buildRegExpStr();\n if (regexp === \"\") {\n return [/^$/, [], []];\n }\n let captureIndex = 0;\n const indexReplacementMap = [];\n const paramReplacementMap = [];\n regexp = regexp.replace(/#(\\d+)|@(\\d+)|\\.\\*\\$/g, (_, handlerIndex, paramIndex) => {\n if (handlerIndex !== void 0) {\n indexReplacementMap[++captureIndex] = Number(handlerIndex);\n return \"$()\";\n }\n if (paramIndex !== void 0) {\n paramReplacementMap[Number(paramIndex)] = ++captureIndex;\n return \"\";\n }\n return \"\";\n });\n return [new RegExp(`^${regexp}`), indexReplacementMap, paramReplacementMap];\n }\n};\nexport {\n Trie\n};\n","// src/router/reg-exp-router/router.ts\nimport {\n MESSAGE_MATCHER_IS_ALREADY_BUILT,\n METHOD_NAME_ALL,\n UnsupportedPathError\n} from \"../../router.js\";\nimport { checkOptionalParameter } from \"../../utils/url.js\";\nimport { match, emptyParam } from \"./matcher.js\";\nimport { PATH_ERROR } from \"./node.js\";\nimport { Trie } from \"./trie.js\";\nvar nullMatcher = [/^$/, [], /* @__PURE__ */ Object.create(null)];\nvar wildcardRegExpCache = /* @__PURE__ */ Object.create(null);\nfunction buildWildcardRegExp(path) {\n return wildcardRegExpCache[path] ??= new RegExp(\n path === \"*\" ? \"\" : `^${path.replace(\n /\\/\\*$|([.\\\\+*[^\\]$()])/g,\n (_, metaChar) => metaChar ? `\\\\${metaChar}` : \"(?:|/.*)\"\n )}$`\n );\n}\nfunction clearWildcardRegExpCache() {\n wildcardRegExpCache = /* @__PURE__ */ Object.create(null);\n}\nfunction buildMatcherFromPreprocessedRoutes(routes) {\n const trie = new Trie();\n const handlerData = [];\n if (routes.length === 0) {\n return nullMatcher;\n }\n const routesWithStaticPathFlag = routes.map(\n (route) => [!/\\*|\\/:/.test(route[0]), ...route]\n ).sort(\n ([isStaticA, pathA], [isStaticB, pathB]) => isStaticA ? 1 : isStaticB ? -1 : pathA.length - pathB.length\n );\n const staticMap = /* @__PURE__ */ Object.create(null);\n for (let i = 0, j = -1, len = routesWithStaticPathFlag.length; i < len; i++) {\n const [pathErrorCheckOnly, path, handlers] = routesWithStaticPathFlag[i];\n if (pathErrorCheckOnly) {\n staticMap[path] = [handlers.map(([h]) => [h, /* @__PURE__ */ Object.create(null)]), emptyParam];\n } else {\n j++;\n }\n let paramAssoc;\n try {\n paramAssoc = trie.insert(path, j, pathErrorCheckOnly);\n } catch (e) {\n throw e === PATH_ERROR ? new UnsupportedPathError(path) : e;\n }\n if (pathErrorCheckOnly) {\n continue;\n }\n handlerData[j] = handlers.map(([h, paramCount]) => {\n const paramIndexMap = /* @__PURE__ */ Object.create(null);\n paramCount -= 1;\n for (; paramCount >= 0; paramCount--) {\n const [key, value] = paramAssoc[paramCount];\n paramIndexMap[key] = value;\n }\n return [h, paramIndexMap];\n });\n }\n const [regexp, indexReplacementMap, paramReplacementMap] = trie.buildRegExp();\n for (let i = 0, len = handlerData.length; i < len; i++) {\n for (let j = 0, len2 = handlerData[i].length; j < len2; j++) {\n const map = handlerData[i][j]?.[1];\n if (!map) {\n continue;\n }\n const keys = Object.keys(map);\n for (let k = 0, len3 = keys.length; k < len3; k++) {\n map[keys[k]] = paramReplacementMap[map[keys[k]]];\n }\n }\n }\n const handlerMap = [];\n for (const i in indexReplacementMap) {\n handlerMap[i] = handlerData[indexReplacementMap[i]];\n }\n return [regexp, handlerMap, staticMap];\n}\nfunction findMiddleware(middleware, path) {\n if (!middleware) {\n return void 0;\n }\n for (const k of Object.keys(middleware).sort((a, b) => b.length - a.length)) {\n if (buildWildcardRegExp(k).test(path)) {\n return [...middleware[k]];\n }\n }\n return void 0;\n}\nvar RegExpRouter = class {\n name = \"RegExpRouter\";\n #middleware;\n #routes;\n constructor() {\n this.#middleware = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) };\n this.#routes = { [METHOD_NAME_ALL]: /* @__PURE__ */ Object.create(null) };\n }\n add(method, path, handler) {\n const middleware = this.#middleware;\n const routes = this.#routes;\n if (!middleware || !routes) {\n throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);\n }\n if (!middleware[method]) {\n ;\n [middleware, routes].forEach((handlerMap) => {\n handlerMap[method] = /* @__PURE__ */ Object.create(null);\n Object.keys(handlerMap[METHOD_NAME_ALL]).forEach((p) => {\n handlerMap[method][p] = [...handlerMap[METHOD_NAME_ALL][p]];\n });\n });\n }\n if (path === \"/*\") {\n path = \"*\";\n }\n const paramCount = (path.match(/\\/:/g) || []).length;\n if (/\\*$/.test(path)) {\n const re = buildWildcardRegExp(path);\n if (method === METHOD_NAME_ALL) {\n Object.keys(middleware).forEach((m) => {\n middleware[m][path] ||= findMiddleware(middleware[m], path) || findMiddleware(middleware[METHOD_NAME_ALL], path) || [];\n });\n } else {\n middleware[method][path] ||= findMiddleware(middleware[method], path) || findMiddleware(middleware[METHOD_NAME_ALL], path) || [];\n }\n Object.keys(middleware).forEach((m) => {\n if (method === METHOD_NAME_ALL || method === m) {\n Object.keys(middleware[m]).forEach((p) => {\n re.test(p) && middleware[m][p].push([handler, paramCount]);\n });\n }\n });\n Object.keys(routes).forEach((m) => {\n if (method === METHOD_NAME_ALL || method === m) {\n Object.keys(routes[m]).forEach(\n (p) => re.test(p) && routes[m][p].push([handler, paramCount])\n );\n }\n });\n return;\n }\n const paths = checkOptionalParameter(path) || [path];\n for (let i = 0, len = paths.length; i < len; i++) {\n const path2 = paths[i];\n Object.keys(routes).forEach((m) => {\n if (method === METHOD_NAME_ALL || method === m) {\n routes[m][path2] ||= [\n ...findMiddleware(middleware[m], path2) || findMiddleware(middleware[METHOD_NAME_ALL], path2) || []\n ];\n routes[m][path2].push([handler, paramCount - len + i + 1]);\n }\n });\n }\n }\n match = match;\n buildAllMatchers() {\n const matchers = /* @__PURE__ */ Object.create(null);\n Object.keys(this.#routes).concat(Object.keys(this.#middleware)).forEach((method) => {\n matchers[method] ||= this.#buildMatcher(method);\n });\n this.#middleware = this.#routes = void 0;\n clearWildcardRegExpCache();\n return matchers;\n }\n #buildMatcher(method) {\n const routes = [];\n let hasOwnRoute = method === METHOD_NAME_ALL;\n [this.#middleware, this.#routes].forEach((r) => {\n const ownRoute = r[method] ? Object.keys(r[method]).map((path) => [path, r[method][path]]) : [];\n if (ownRoute.length !== 0) {\n hasOwnRoute ||= true;\n routes.push(...ownRoute);\n } else if (method !== METHOD_NAME_ALL) {\n routes.push(\n ...Object.keys(r[METHOD_NAME_ALL]).map((path) => [path, r[METHOD_NAME_ALL][path]])\n );\n }\n });\n if (!hasOwnRoute) {\n return null;\n } else {\n return buildMatcherFromPreprocessedRoutes(routes);\n }\n }\n};\nexport {\n RegExpRouter\n};\n","// src/router/smart-router/router.ts\nimport { MESSAGE_MATCHER_IS_ALREADY_BUILT, UnsupportedPathError } from \"../../router.js\";\nvar SmartRouter = class {\n name = \"SmartRouter\";\n #routers = [];\n #routes = [];\n constructor(init) {\n this.#routers = init.routers;\n }\n add(method, path, handler) {\n if (!this.#routes) {\n throw new Error(MESSAGE_MATCHER_IS_ALREADY_BUILT);\n }\n this.#routes.push([method, path, handler]);\n }\n match(method, path) {\n if (!this.#routes) {\n throw new Error(\"Fatal error\");\n }\n const routers = this.#routers;\n const routes = this.#routes;\n const len = routers.length;\n let i = 0;\n let res;\n for (; i < len; i++) {\n const router = routers[i];\n try {\n for (let i2 = 0, len2 = routes.length; i2 < len2; i2++) {\n router.add(...routes[i2]);\n }\n res = router.match(method, path);\n } catch (e) {\n if (e instanceof UnsupportedPathError) {\n continue;\n }\n throw e;\n }\n this.match = router.match.bind(router);\n this.#routers = [router];\n this.#routes = void 0;\n break;\n }\n if (i === len) {\n throw new Error(\"Fatal error\");\n }\n this.name = `SmartRouter + ${this.activeRouter.name}`;\n return res;\n }\n get activeRouter() {\n if (this.#routes || this.#routers.length !== 1) {\n throw new Error(\"No active router has been determined yet.\");\n }\n return this.#routers[0];\n }\n};\nexport {\n SmartRouter\n};\n","// src/router/trie-router/node.ts\nimport { METHOD_NAME_ALL } from \"../../router.js\";\nimport { getPattern, splitPath, splitRoutingPath } from \"../../utils/url.js\";\nvar emptyParams = /* @__PURE__ */ Object.create(null);\nvar hasChildren = (children) => {\n for (const _ in children) {\n return true;\n }\n return false;\n};\nvar Node = class _Node {\n #methods;\n #children;\n #patterns;\n #order = 0;\n #params = emptyParams;\n constructor(method, handler, children) {\n this.#children = children || /* @__PURE__ */ Object.create(null);\n this.#methods = [];\n if (method && handler) {\n const m = /* @__PURE__ */ Object.create(null);\n m[method] = { handler, possibleKeys: [], score: 0 };\n this.#methods = [m];\n }\n this.#patterns = [];\n }\n insert(method, path, handler) {\n this.#order = ++this.#order;\n let curNode = this;\n const parts = splitRoutingPath(path);\n const possibleKeys = [];\n for (let i = 0, len = parts.length; i < len; i++) {\n const p = parts[i];\n const nextP = parts[i + 1];\n const pattern = getPattern(p, nextP);\n const key = Array.isArray(pattern) ? pattern[0] : p;\n if (key in curNode.#children) {\n curNode = curNode.#children[key];\n if (pattern) {\n possibleKeys.push(pattern[1]);\n }\n continue;\n }\n curNode.#children[key] = new _Node();\n if (pattern) {\n curNode.#patterns.push(pattern);\n possibleKeys.push(pattern[1]);\n }\n curNode = curNode.#children[key];\n }\n curNode.#methods.push({\n [method]: {\n handler,\n possibleKeys: possibleKeys.filter((v, i, a) => a.indexOf(v) === i),\n score: this.#order\n }\n });\n return curNode;\n }\n #pushHandlerSets(handlerSets, node, method, nodeParams, params) {\n for (let i = 0, len = node.#methods.length; i < len; i++) {\n const m = node.#methods[i];\n const handlerSet = m[method] || m[METHOD_NAME_ALL];\n const processedSet = {};\n if (handlerSet !== void 0) {\n handlerSet.params = /* @__PURE__ */ Object.create(null);\n handlerSets.push(handlerSet);\n if (nodeParams !== emptyParams || params && params !== emptyParams) {\n for (let i2 = 0, len2 = handlerSet.possibleKeys.length; i2 < len2; i2++) {\n const key = handlerSet.possibleKeys[i2];\n const processed = processedSet[handlerSet.score];\n handlerSet.params[key] = params?.[key] && !processed ? params[key] : nodeParams[key] ?? params?.[key];\n processedSet[handlerSet.score] = true;\n }\n }\n }\n }\n }\n search(method, path) {\n const handlerSets = [];\n this.#params = emptyParams;\n const curNode = this;\n let curNodes = [curNode];\n const parts = splitPath(path);\n const curNodesQueue = [];\n const len = parts.length;\n let partOffsets = null;\n for (let i = 0; i < len; i++) {\n const part = parts[i];\n const isLast = i === len - 1;\n const tempNodes = [];\n for (let j = 0, len2 = curNodes.length; j < len2; j++) {\n const node = curNodes[j];\n const nextNode = node.#children[part];\n if (nextNode) {\n nextNode.#params = node.#params;\n if (isLast) {\n if (nextNode.#children[\"*\"]) {\n this.#pushHandlerSets(handlerSets, nextNode.#children[\"*\"], method, node.#params);\n }\n this.#pushHandlerSets(handlerSets, nextNode, method, node.#params);\n } else {\n tempNodes.push(nextNode);\n }\n }\n for (let k = 0, len3 = node.#patterns.length; k < len3; k++) {\n const pattern = node.#patterns[k];\n const params = node.#params === emptyParams ? {} : { ...node.#params };\n if (pattern === \"*\") {\n const astNode = node.#children[\"*\"];\n if (astNode) {\n this.#pushHandlerSets(handlerSets, astNode, method, node.#params);\n astNode.#params = params;\n tempNodes.push(astNode);\n }\n continue;\n }\n const [key, name, matcher] = pattern;\n if (!part && !(matcher instanceof RegExp)) {\n continue;\n }\n const child = node.#children[key];\n if (matcher instanceof RegExp) {\n if (partOffsets === null) {\n partOffsets = new Array(len);\n let offset = path[0] === \"/\" ? 1 : 0;\n for (let p = 0; p < len; p++) {\n partOffsets[p] = offset;\n offset += parts[p].length + 1;\n }\n }\n const restPathString = path.substring(partOffsets[i]);\n const m = matcher.exec(restPathString);\n if (m) {\n params[name] = m[0];\n this.#pushHandlerSets(handlerSets, child, method, node.#params, params);\n if (hasChildren(child.#children)) {\n child.#params = params;\n const componentCount = m[0].match(/\\//)?.length ?? 0;\n const targetCurNodes = curNodesQueue[componentCount] ||= [];\n targetCurNodes.push(child);\n }\n continue;\n }\n }\n if (matcher === true || matcher.test(part)) {\n params[name] = part;\n if (isLast) {\n this.#pushHandlerSets(handlerSets, child, method, params, node.#params);\n if (child.#children[\"*\"]) {\n this.#pushHandlerSets(\n handlerSets,\n child.#children[\"*\"],\n method,\n params,\n node.#params\n );\n }\n } else {\n child.#params = params;\n tempNodes.push(child);\n }\n }\n }\n }\n const shifted = curNodesQueue.shift();\n curNodes = shifted ? tempNodes.concat(shifted) : tempNodes;\n }\n if (handlerSets.length > 1) {\n handlerSets.sort((a, b) => {\n return a.score - b.score;\n });\n }\n return [handlerSets.map(({ handler, params }) => [handler, params])];\n }\n};\nexport {\n Node\n};\n","// src/router/trie-router/router.ts\nimport { checkOptionalParameter } from \"../../utils/url.js\";\nimport { Node } from \"./node.js\";\nvar TrieRouter = class {\n name = \"TrieRouter\";\n #node;\n constructor() {\n this.#node = new Node();\n }\n add(method, path, handler) {\n const results = checkOptionalParameter(path);\n if (results) {\n for (let i = 0, len = results.length; i < len; i++) {\n this.#node.insert(method, results[i], handler);\n }\n return;\n }\n this.#node.insert(method, path, handler);\n }\n match(method, path) {\n return this.#node.search(method, path);\n }\n};\nexport {\n TrieRouter\n};\n","// src/hono.ts\nimport { HonoBase } from \"./hono-base.js\";\nimport { RegExpRouter } from \"./router/reg-exp-router/index.js\";\nimport { SmartRouter } from \"./router/smart-router/index.js\";\nimport { TrieRouter } from \"./router/trie-router/index.js\";\nvar Hono = class extends HonoBase {\n /**\n * Creates an instance of the Hono class.\n *\n * @param options - Optional configuration options for the Hono instance.\n */\n constructor(options = {}) {\n super(options);\n this.router = options.router ?? new SmartRouter({\n routers: [new RegExpRouter(), new TrieRouter()]\n });\n }\n};\nexport {\n Hono\n};\n","/**\n * Invite link encoding/decoding for the coordinator join flow.\n *\n * Ported from codemem/coordinator_invites.py.\n */\n\nexport interface InvitePayload {\n\tv: number;\n\tkind: string;\n\tcoordinator_url: string;\n\tgroup_id: string;\n\tpolicy: string;\n\ttoken: string;\n\texpires_at: string;\n\tteam_name: string | null;\n}\n\n/** Encode an invite payload as a compact base64url string (no padding). */\nexport function encodeInvitePayload(payload: InvitePayload): string {\n\tconst json = JSON.stringify(payload);\n\tconst bytes = new TextEncoder().encode(json);\n\tconst base64 = Buffer.from(bytes).toString(\"base64url\");\n\t// base64url from Buffer already omits padding — strip defensively\n\treturn base64.replace(/=+$/, \"\");\n}\n\n/** Decode a base64url invite payload string back to an InvitePayload. */\nexport function decodeInvitePayload(value: string): InvitePayload {\n\t// Re-add padding that was stripped\n\tconst padded = value + \"=\".repeat((4 - (value.length % 4)) % 4);\n\tconst json = Buffer.from(padded, \"base64url\").toString(\"utf-8\");\n\tconst data: unknown = JSON.parse(json);\n\tif (typeof data !== \"object\" || data === null) {\n\t\tthrow new Error(\"invalid invite payload\");\n\t}\n\treturn data as InvitePayload;\n}\n\n/** Build a `codemem://join?invite=...` link from an encoded payload. */\nexport function inviteLink(encodedPayload: string): string {\n\treturn `codemem://join?invite=${encodeURIComponent(encodedPayload)}`;\n}\n\n/**\n * Extract the raw encoded payload from either a `codemem://` link or a raw value.\n *\n * Throws if a `codemem://` link is provided but has no `invite` query parameter.\n */\nexport function extractInvitePayload(value: string): string {\n\tconst raw = value.trim();\n\tif (raw.startsWith(\"codemem://\")) {\n\t\tconst url = new URL(raw);\n\t\tconst invite = url.searchParams.get(\"invite\") ?? \"\";\n\t\tif (!invite) {\n\t\t\tthrow new Error(\"invite payload missing from link\");\n\t\t}\n\t\treturn invite;\n\t}\n\treturn raw;\n}\n","/**\n * Drizzle ORM schema for the codemem SQLite database.\n */\n\nimport {\n\tindex,\n\tinteger,\n\tprimaryKey,\n\treal,\n\tsqliteTable,\n\ttext,\n\tuniqueIndex,\n} from \"drizzle-orm/sqlite-core\";\n\nexport const sessions = sqliteTable(\"sessions\", {\n\tid: integer(\"id\").primaryKey(),\n\tstarted_at: text(\"started_at\").notNull(),\n\tended_at: text(\"ended_at\"),\n\tcwd: text(\"cwd\"),\n\tproject: text(\"project\"),\n\tgit_remote: text(\"git_remote\"),\n\tgit_branch: text(\"git_branch\"),\n\tuser: text(\"user\"),\n\ttool_version: text(\"tool_version\"),\n\tmetadata_json: text(\"metadata_json\"),\n\timport_key: text(\"import_key\"),\n});\n\nexport type Session = typeof sessions.$inferSelect;\nexport type NewSession = typeof sessions.$inferInsert;\n\nexport const artifacts = sqliteTable(\n\t\"artifacts\",\n\t{\n\t\tid: integer(\"id\").primaryKey(),\n\t\tsession_id: integer(\"session_id\")\n\t\t\t.notNull()\n\t\t\t.references(() => sessions.id, { onDelete: \"cascade\" }),\n\t\tkind: text(\"kind\").notNull(),\n\t\tpath: text(\"path\"),\n\t\tcontent_text: text(\"content_text\"),\n\t\tcontent_hash: text(\"content_hash\"),\n\t\tcreated_at: text(\"created_at\").notNull(),\n\t\tmetadata_json: text(\"metadata_json\"),\n\t},\n\t(table) => [index(\"idx_artifacts_session_kind\").on(table.session_id, table.kind)],\n);\n\nexport type Artifact = typeof artifacts.$inferSelect;\nexport type NewArtifact = typeof artifacts.$inferInsert;\n\nexport const memoryItems = sqliteTable(\n\t\"memory_items\",\n\t{\n\t\tid: integer(\"id\").primaryKey(),\n\t\tsession_id: integer(\"session_id\")\n\t\t\t.notNull()\n\t\t\t.references(() => sessions.id, { onDelete: \"cascade\" }),\n\t\tkind: text(\"kind\").notNull(),\n\t\ttitle: text(\"title\").notNull(),\n\t\tsubtitle: text(\"subtitle\"),\n\t\tbody_text: text(\"body_text\").notNull(),\n\t\tconfidence: real(\"confidence\").default(0.5),\n\t\ttags_text: text(\"tags_text\").default(\"\"),\n\t\tactive: integer(\"active\").default(1),\n\t\tcreated_at: text(\"created_at\").notNull(),\n\t\tupdated_at: text(\"updated_at\").notNull(),\n\t\tmetadata_json: text(\"metadata_json\"),\n\t\tactor_id: text(\"actor_id\"),\n\t\tactor_display_name: text(\"actor_display_name\"),\n\t\tvisibility: text(\"visibility\"),\n\t\tworkspace_id: text(\"workspace_id\"),\n\t\tworkspace_kind: text(\"workspace_kind\"),\n\t\torigin_device_id: text(\"origin_device_id\"),\n\t\torigin_source: text(\"origin_source\"),\n\t\ttrust_state: text(\"trust_state\"),\n\t\tfacts: text(\"facts\"),\n\t\tnarrative: text(\"narrative\"),\n\t\tconcepts: text(\"concepts\"),\n\t\tfiles_read: text(\"files_read\"),\n\t\tfiles_modified: text(\"files_modified\"),\n\t\tuser_prompt_id: integer(\"user_prompt_id\"),\n\t\tprompt_number: integer(\"prompt_number\"),\n\t\tdeleted_at: text(\"deleted_at\"),\n\t\trev: integer(\"rev\").default(0),\n\t\timport_key: text(\"import_key\"),\n\t},\n\t(table) => [\n\t\tindex(\"idx_memory_items_active_created\").on(table.active, table.created_at),\n\t\tindex(\"idx_memory_items_session\").on(table.session_id),\n\t],\n);\n\nexport type MemoryItem = typeof memoryItems.$inferSelect;\nexport type NewMemoryItem = typeof memoryItems.$inferInsert;\n\nexport const usageEvents = sqliteTable(\n\t\"usage_events\",\n\t{\n\t\tid: integer(\"id\").primaryKey(),\n\t\tsession_id: integer(\"session_id\").references(() => sessions.id, {\n\t\t\tonDelete: \"set null\",\n\t\t}),\n\t\tevent: text(\"event\").notNull(),\n\t\ttokens_read: integer(\"tokens_read\").default(0),\n\t\ttokens_written: integer(\"tokens_written\").default(0),\n\t\ttokens_saved: integer(\"tokens_saved\").default(0),\n\t\tcreated_at: text(\"created_at\").notNull(),\n\t\tmetadata_json: text(\"metadata_json\"),\n\t},\n\t(table) => [\n\t\tindex(\"idx_usage_events_event_created\").on(table.event, table.created_at),\n\t\tindex(\"idx_usage_events_session\").on(table.session_id),\n\t],\n);\n\nexport type UsageEvent = typeof usageEvents.$inferSelect;\nexport type NewUsageEvent = typeof usageEvents.$inferInsert;\n\nexport const rawEvents = sqliteTable(\n\t\"raw_events\",\n\t{\n\t\tid: integer(\"id\").primaryKey(),\n\t\tsource: text(\"source\").notNull().default(\"opencode\"),\n\t\tstream_id: text(\"stream_id\").notNull().default(\"\"),\n\t\topencode_session_id: text(\"opencode_session_id\").notNull(),\n\t\tevent_id: text(\"event_id\"),\n\t\tevent_seq: integer(\"event_seq\").notNull(),\n\t\tevent_type: text(\"event_type\").notNull(),\n\t\tts_wall_ms: integer(\"ts_wall_ms\"),\n\t\tts_mono_ms: real(\"ts_mono_ms\"),\n\t\tpayload_json: text(\"payload_json\").notNull(),\n\t\tcreated_at: text(\"created_at\").notNull(),\n\t},\n\t(table) => [\n\t\tuniqueIndex(\"idx_raw_events_source_stream_seq\").on(\n\t\t\ttable.source,\n\t\t\ttable.stream_id,\n\t\t\ttable.event_seq,\n\t\t),\n\t\tuniqueIndex(\"idx_raw_events_source_stream_event_id\").on(\n\t\t\ttable.source,\n\t\t\ttable.stream_id,\n\t\t\ttable.event_id,\n\t\t),\n\t\tindex(\"idx_raw_events_session_seq\").on(table.opencode_session_id, table.event_seq),\n\t\tindex(\"idx_raw_events_created\").on(table.created_at),\n\t],\n);\n\nexport type RawEvent = typeof rawEvents.$inferSelect;\nexport type NewRawEvent = typeof rawEvents.$inferInsert;\n\nexport const rawEventSessions = sqliteTable(\n\t\"raw_event_sessions\",\n\t{\n\t\tsource: text(\"source\").notNull().default(\"opencode\"),\n\t\tstream_id: text(\"stream_id\").notNull().default(\"\"),\n\t\topencode_session_id: text(\"opencode_session_id\").notNull(),\n\t\tcwd: text(\"cwd\"),\n\t\tproject: text(\"project\"),\n\t\tstarted_at: text(\"started_at\"),\n\t\tlast_seen_ts_wall_ms: integer(\"last_seen_ts_wall_ms\"),\n\t\tlast_received_event_seq: integer(\"last_received_event_seq\").notNull().default(-1),\n\t\tlast_flushed_event_seq: integer(\"last_flushed_event_seq\").notNull().default(-1),\n\t\tupdated_at: text(\"updated_at\").notNull(),\n\t},\n\t(table) => [primaryKey({ columns: [table.source, table.stream_id] })],\n);\n\nexport type RawEventSession = typeof rawEventSessions.$inferSelect;\nexport type NewRawEventSession = typeof rawEventSessions.$inferInsert;\n\nexport const opencodeSessions = sqliteTable(\n\t\"opencode_sessions\",\n\t{\n\t\tsource: text(\"source\").notNull().default(\"opencode\"),\n\t\tstream_id: text(\"stream_id\").notNull().default(\"\"),\n\t\topencode_session_id: text(\"opencode_session_id\").notNull(),\n\t\tsession_id: integer(\"session_id\").references(() => sessions.id, {\n\t\t\tonDelete: \"cascade\",\n\t\t}),\n\t\tcreated_at: text(\"created_at\").notNull(),\n\t},\n\t(table) => [\n\t\tprimaryKey({ columns: [table.source, table.stream_id] }),\n\t\tindex(\"idx_opencode_sessions_session\").on(table.session_id),\n\t],\n);\n\nexport type OpencodeSession = typeof opencodeSessions.$inferSelect;\nexport type NewOpencodeSession = typeof opencodeSessions.$inferInsert;\n\nexport const rawEventFlushBatches = sqliteTable(\n\t\"raw_event_flush_batches\",\n\t{\n\t\tid: integer(\"id\").primaryKey(),\n\t\tsource: text(\"source\").notNull().default(\"opencode\"),\n\t\tstream_id: text(\"stream_id\").notNull().default(\"\"),\n\t\topencode_session_id: text(\"opencode_session_id\").notNull(),\n\t\tstart_event_seq: integer(\"start_event_seq\").notNull(),\n\t\tend_event_seq: integer(\"end_event_seq\").notNull(),\n\t\textractor_version: text(\"extractor_version\").notNull(),\n\t\tstatus: text(\"status\").notNull(),\n\t\terror_message: text(\"error_message\"),\n\t\terror_type: text(\"error_type\"),\n\t\tobserver_provider: text(\"observer_provider\"),\n\t\tobserver_model: text(\"observer_model\"),\n\t\tobserver_runtime: text(\"observer_runtime\"),\n\t\tobserver_auth_source: text(\"observer_auth_source\"),\n\t\tobserver_auth_type: text(\"observer_auth_type\"),\n\t\tobserver_error_code: text(\"observer_error_code\"),\n\t\tobserver_error_message: text(\"observer_error_message\"),\n\t\tattempt_count: integer(\"attempt_count\").notNull().default(0),\n\t\tcreated_at: text(\"created_at\").notNull(),\n\t\tupdated_at: text(\"updated_at\").notNull(),\n\t},\n\t(table) => [\n\t\tuniqueIndex(\"idx_flush_batches_source_stream_seq_ver\").on(\n\t\t\ttable.source,\n\t\t\ttable.stream_id,\n\t\t\ttable.start_event_seq,\n\t\t\ttable.end_event_seq,\n\t\t\ttable.extractor_version,\n\t\t),\n\t\tindex(\"idx_flush_batches_session_created\").on(table.opencode_session_id, table.created_at),\n\t\tindex(\"idx_flush_batches_status_updated\").on(table.status, table.updated_at),\n\t],\n);\n\nexport type RawEventFlushBatch = typeof rawEventFlushBatches.$inferSelect;\nexport type NewRawEventFlushBatch = typeof rawEventFlushBatches.$inferInsert;\n\nexport const userPrompts = sqliteTable(\n\t\"user_prompts\",\n\t{\n\t\tid: integer(\"id\").primaryKey(),\n\t\tsession_id: integer(\"session_id\").references(() => sessions.id, {\n\t\t\tonDelete: \"cascade\",\n\t\t}),\n\t\tproject: text(\"project\"),\n\t\tprompt_text: text(\"prompt_text\").notNull(),\n\t\tprompt_number: integer(\"prompt_number\"),\n\t\tcreated_at: text(\"created_at\").notNull(),\n\t\tcreated_at_epoch: integer(\"created_at_epoch\").notNull(),\n\t\tmetadata_json: text(\"metadata_json\"),\n\t\timport_key: text(\"import_key\"),\n\t},\n\t(table) => [\n\t\tindex(\"idx_user_prompts_session\").on(table.session_id),\n\t\tindex(\"idx_user_prompts_project\").on(table.project),\n\t\tindex(\"idx_user_prompts_epoch\").on(table.created_at_epoch),\n\t],\n);\n\nexport type UserPrompt = typeof userPrompts.$inferSelect;\nexport type NewUserPrompt = typeof userPrompts.$inferInsert;\n\nexport const sessionSummaries = sqliteTable(\n\t\"session_summaries\",\n\t{\n\t\tid: integer(\"id\").primaryKey(),\n\t\tsession_id: integer(\"session_id\").references(() => sessions.id, {\n\t\t\tonDelete: \"cascade\",\n\t\t}),\n\t\tproject: text(\"project\"),\n\t\trequest: text(\"request\"),\n\t\tinvestigated: text(\"investigated\"),\n\t\tlearned: text(\"learned\"),\n\t\tcompleted: text(\"completed\"),\n\t\tnext_steps: text(\"next_steps\"),\n\t\tnotes: text(\"notes\"),\n\t\tfiles_read: text(\"files_read\"),\n\t\tfiles_edited: text(\"files_edited\"),\n\t\tprompt_number: integer(\"prompt_number\"),\n\t\tcreated_at: text(\"created_at\").notNull(),\n\t\tcreated_at_epoch: integer(\"created_at_epoch\").notNull(),\n\t\tmetadata_json: text(\"metadata_json\"),\n\t\timport_key: text(\"import_key\"),\n\t},\n\t(table) => [\n\t\tindex(\"idx_session_summaries_session\").on(table.session_id),\n\t\tindex(\"idx_session_summaries_project\").on(table.project),\n\t\tindex(\"idx_session_summaries_epoch\").on(table.created_at_epoch),\n\t],\n);\n\nexport type SessionSummary = typeof sessionSummaries.$inferSelect;\nexport type NewSessionSummary = typeof sessionSummaries.$inferInsert;\n\nexport const replicationOps = sqliteTable(\n\t\"replication_ops\",\n\t{\n\t\top_id: text(\"op_id\").primaryKey(),\n\t\tentity_type: text(\"entity_type\").notNull(),\n\t\tentity_id: text(\"entity_id\").notNull(),\n\t\top_type: text(\"op_type\").notNull(),\n\t\tpayload_json: text(\"payload_json\"),\n\t\tclock_rev: integer(\"clock_rev\").notNull(),\n\t\tclock_updated_at: text(\"clock_updated_at\").notNull(),\n\t\tclock_device_id: text(\"clock_device_id\").notNull(),\n\t\tdevice_id: text(\"device_id\").notNull(),\n\t\tcreated_at: text(\"created_at\").notNull(),\n\t},\n\t(table) => [\n\t\tindex(\"idx_replication_ops_created\").on(table.created_at, table.op_id),\n\t\tindex(\"idx_replication_ops_entity\").on(table.entity_type, table.entity_id),\n\t],\n);\n\nexport type ReplicationOp = typeof replicationOps.$inferSelect;\nexport type NewReplicationOp = typeof replicationOps.$inferInsert;\n\nexport const replicationCursors = sqliteTable(\"replication_cursors\", {\n\tpeer_device_id: text(\"peer_device_id\").primaryKey(),\n\tlast_applied_cursor: text(\"last_applied_cursor\"),\n\tlast_acked_cursor: text(\"last_acked_cursor\"),\n\tupdated_at: text(\"updated_at\").notNull(),\n});\n\nexport type ReplicationCursor = typeof replicationCursors.$inferSelect;\nexport type NewReplicationCursor = typeof replicationCursors.$inferInsert;\n\nexport const syncPeers = sqliteTable(\"sync_peers\", {\n\tpeer_device_id: text(\"peer_device_id\").primaryKey(),\n\tname: text(\"name\"),\n\tpinned_fingerprint: text(\"pinned_fingerprint\"),\n\tpublic_key: text(\"public_key\"),\n\taddresses_json: text(\"addresses_json\"),\n\tclaimed_local_actor: integer(\"claimed_local_actor\").notNull().default(0),\n\tactor_id: text(\"actor_id\"),\n\tprojects_include_json: text(\"projects_include_json\"),\n\tprojects_exclude_json: text(\"projects_exclude_json\"),\n\tcreated_at: text(\"created_at\").notNull(),\n\tlast_seen_at: text(\"last_seen_at\"),\n\tlast_sync_at: text(\"last_sync_at\"),\n\tlast_error: text(\"last_error\"),\n});\n\nexport type SyncPeer = typeof syncPeers.$inferSelect;\nexport type NewSyncPeer = typeof syncPeers.$inferInsert;\n\nexport const syncNonces = sqliteTable(\"sync_nonces\", {\n\tnonce: text(\"nonce\").primaryKey(),\n\tdevice_id: text(\"device_id\").notNull(),\n\tcreated_at: text(\"created_at\").notNull(),\n});\n\nexport type SyncNonce = typeof syncNonces.$inferSelect;\nexport type NewSyncNonce = typeof syncNonces.$inferInsert;\n\nexport const syncDevice = sqliteTable(\"sync_device\", {\n\tdevice_id: text(\"device_id\").primaryKey(),\n\tpublic_key: text(\"public_key\").notNull(),\n\tfingerprint: text(\"fingerprint\").notNull(),\n\tcreated_at: text(\"created_at\").notNull(),\n});\n\nexport type SyncDevice = typeof syncDevice.$inferSelect;\nexport type NewSyncDevice = typeof syncDevice.$inferInsert;\n\nexport const syncAttempts = sqliteTable(\n\t\"sync_attempts\",\n\t{\n\t\tid: integer(\"id\").primaryKey({ autoIncrement: true }),\n\t\tpeer_device_id: text(\"peer_device_id\").notNull(),\n\t\tstarted_at: text(\"started_at\").notNull(),\n\t\tfinished_at: text(\"finished_at\"),\n\t\tok: integer(\"ok\").notNull(),\n\t\tops_in: integer(\"ops_in\").notNull(),\n\t\tops_out: integer(\"ops_out\").notNull(),\n\t\terror: text(\"error\"),\n\t},\n\t(table) => [index(\"idx_sync_attempts_peer_started\").on(table.peer_device_id, table.started_at)],\n);\n\nexport type SyncAttempt = typeof syncAttempts.$inferSelect;\nexport type NewSyncAttempt = typeof syncAttempts.$inferInsert;\n\nexport const syncDaemonState = sqliteTable(\"sync_daemon_state\", {\n\tid: integer(\"id\").primaryKey(),\n\tlast_error: text(\"last_error\"),\n\tlast_traceback: text(\"last_traceback\"),\n\tlast_error_at: text(\"last_error_at\"),\n\tlast_ok_at: text(\"last_ok_at\"),\n\tphase: text(\"phase\"),\n});\n\nexport type SyncDaemonState = typeof syncDaemonState.$inferSelect;\nexport type NewSyncDaemonState = typeof syncDaemonState.$inferInsert;\n\nexport const syncResetState = sqliteTable(\"sync_reset_state\", {\n\tid: integer(\"id\").primaryKey(),\n\tgeneration: integer(\"generation\").notNull(),\n\tsnapshot_id: text(\"snapshot_id\").notNull(),\n\tbaseline_cursor: text(\"baseline_cursor\"),\n\tretained_floor_cursor: text(\"retained_floor_cursor\"),\n\tupdated_at: text(\"updated_at\").notNull(),\n});\n\nexport type SyncResetState = typeof syncResetState.$inferSelect;\nexport type NewSyncResetState = typeof syncResetState.$inferInsert;\n\nexport const syncRetentionState = sqliteTable(\"sync_retention_state\", {\n\tid: integer(\"id\").primaryKey(),\n\tlast_run_at: text(\"last_run_at\"),\n\tlast_duration_ms: integer(\"last_duration_ms\"),\n\tlast_deleted_ops: integer(\"last_deleted_ops\").notNull().default(0),\n\tlast_estimated_bytes_before: integer(\"last_estimated_bytes_before\"),\n\tlast_estimated_bytes_after: integer(\"last_estimated_bytes_after\"),\n\tretained_floor_cursor: text(\"retained_floor_cursor\"),\n\tlast_error: text(\"last_error\"),\n\tlast_error_at: text(\"last_error_at\"),\n});\n\nexport type SyncRetentionState = typeof syncRetentionState.$inferSelect;\nexport type NewSyncRetentionState = typeof syncRetentionState.$inferInsert;\n\nexport const rawEventIngestSamples = sqliteTable(\"raw_event_ingest_samples\", {\n\tid: integer(\"id\").primaryKey({ autoIncrement: true }),\n\tcreated_at: text(\"created_at\").notNull(),\n\tinserted_events: integer(\"inserted_events\").notNull().default(0),\n\tskipped_invalid: integer(\"skipped_invalid\").notNull().default(0),\n\tskipped_duplicate: integer(\"skipped_duplicate\").notNull().default(0),\n\tskipped_conflict: integer(\"skipped_conflict\").notNull().default(0),\n});\n\nexport type RawEventIngestSample = typeof rawEventIngestSamples.$inferSelect;\nexport type NewRawEventIngestSample = typeof rawEventIngestSamples.$inferInsert;\n\nexport const rawEventIngestStats = sqliteTable(\"raw_event_ingest_stats\", {\n\tid: integer(\"id\").primaryKey(),\n\tinserted_events: integer(\"inserted_events\").notNull().default(0),\n\tskipped_events: integer(\"skipped_events\").notNull().default(0),\n\tskipped_invalid: integer(\"skipped_invalid\").notNull().default(0),\n\tskipped_duplicate: integer(\"skipped_duplicate\").notNull().default(0),\n\tskipped_conflict: integer(\"skipped_conflict\").notNull().default(0),\n\tupdated_at: text(\"updated_at\").notNull(),\n});\n\nexport type RawEventIngestStat = typeof rawEventIngestStats.$inferSelect;\nexport type NewRawEventIngestStat = typeof rawEventIngestStats.$inferInsert;\n\nexport const actors = sqliteTable(\n\t\"actors\",\n\t{\n\t\tactor_id: text(\"actor_id\").primaryKey(),\n\t\tdisplay_name: text(\"display_name\").notNull(),\n\t\tis_local: integer(\"is_local\").notNull().default(0),\n\t\tstatus: text(\"status\").notNull().default(\"active\"),\n\t\tmerged_into_actor_id: text(\"merged_into_actor_id\"),\n\t\tcreated_at: text(\"created_at\").notNull(),\n\t\tupdated_at: text(\"updated_at\").notNull(),\n\t},\n\t(table) => ({\n\t\tisLocalIdx: index(\"idx_actors_is_local\").on(table.is_local),\n\t\tstatusIdx: index(\"idx_actors_status\").on(table.status),\n\t}),\n);\n\nexport type Actor = typeof actors.$inferSelect;\nexport type NewActor = typeof actors.$inferInsert;\n\nexport const schema = {\n\tsessions,\n\tartifacts,\n\tmemoryItems,\n\tusageEvents,\n\trawEvents,\n\trawEventSessions,\n\topencodeSessions,\n\trawEventFlushBatches,\n\tuserPrompts,\n\tsessionSummaries,\n\treplicationOps,\n\treplicationCursors,\n\tsyncPeers,\n\tsyncNonces,\n\tsyncDevice,\n\tsyncAttempts,\n\tsyncDaemonState,\n\tsyncResetState,\n\trawEventIngestSamples,\n\trawEventIngestStats,\n\tactors,\n};\n","/**\n * OpenCode provider configuration loading and resolution.\n *\n * Mirrors codemem/observer_config.py — reads ~/.config/opencode/opencode.json{c},\n * resolves custom provider settings (base URL, headers, API keys), and expands\n * environment variable / file placeholders in config values.\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\n// ---------------------------------------------------------------------------\n// JSONC helpers\n// ---------------------------------------------------------------------------\n\n/** Strip JavaScript-style `//` line comments and `/* ... *​/` block comments from JSONC text. */\nexport function stripJsonComments(text: string): string {\n\tconst result: string[] = [];\n\tlet inString = false;\n\tlet escapeNext = false;\n\tfor (let i = 0; i < text.length; i++) {\n\t\tconst char = text.charAt(i);\n\t\tif (escapeNext) {\n\t\t\tresult.push(char);\n\t\t\tescapeNext = false;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"\\\\\" && inString) {\n\t\t\tresult.push(char);\n\t\t\tescapeNext = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === '\"') {\n\t\t\tinString = !inString;\n\t\t\tresult.push(char);\n\t\t\tcontinue;\n\t\t}\n\t\tif (!inString && char === \"/\" && i + 1 < text.length) {\n\t\t\tconst next = text.charAt(i + 1);\n\t\t\tif (next === \"/\") {\n\t\t\t\t// Line comment — skip until newline\n\t\t\t\tlet j = i + 2;\n\t\t\t\twhile (j < text.length && text.charAt(j) !== \"\\n\") j++;\n\t\t\t\ti = j - 1; // outer loop will increment\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (next === \"*\") {\n\t\t\t\t// Block comment — skip until */\n\t\t\t\tlet j = i + 2;\n\t\t\t\twhile (j < text.length - 1) {\n\t\t\t\t\tif (text.charAt(j) === \"*\" && text.charAt(j + 1) === \"/\") {\n\t\t\t\t\t\tj += 2;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tj++;\n\t\t\t\t}\n\t\t\t\ti = j - 1; // outer loop will increment\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t\tresult.push(char);\n\t}\n\treturn result.join(\"\");\n}\n\n/** Remove trailing commas before `]` or `}` (outside strings). */\nexport function stripTrailingCommas(text: string): string {\n\tconst result: string[] = [];\n\tlet inString = false;\n\tlet escapeNext = false;\n\tfor (let i = 0; i < text.length; i++) {\n\t\tconst char = text.charAt(i);\n\t\tif (escapeNext) {\n\t\t\tresult.push(char);\n\t\t\tescapeNext = false;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === \"\\\\\" && inString) {\n\t\t\tresult.push(char);\n\t\t\tescapeNext = true;\n\t\t\tcontinue;\n\t\t}\n\t\tif (char === '\"') {\n\t\t\tinString = !inString;\n\t\t\tresult.push(char);\n\t\t\tcontinue;\n\t\t}\n\t\tif (!inString && char === \",\") {\n\t\t\t// Look ahead past whitespace for a closing bracket/brace\n\t\t\tlet j = i + 1;\n\t\t\twhile (j < text.length && /\\s/.test(text.charAt(j))) j++;\n\t\t\tif (j < text.length && (text.charAt(j) === \"]\" || text.charAt(j) === \"}\")) {\n\t\t\t\tcontinue; // skip the trailing comma\n\t\t\t}\n\t\t}\n\t\tresult.push(char);\n\t}\n\treturn result.join(\"\");\n}\n\n// ---------------------------------------------------------------------------\n// Config loading\n// ---------------------------------------------------------------------------\n\n/** Load OpenCode config from `~/.config/opencode/opencode.json{c}`. */\nexport function loadOpenCodeConfig(): Record<string, unknown> {\n\tconst configDir = join(homedir(), \".config\", \"opencode\");\n\tconst candidates = [join(configDir, \"opencode.json\"), join(configDir, \"opencode.jsonc\")];\n\n\tconst configPath = candidates.find((p) => existsSync(p));\n\tif (!configPath) return {};\n\n\tlet text: string;\n\ttry {\n\t\ttext = readFileSync(configPath, \"utf-8\");\n\t} catch {\n\t\treturn {};\n\t}\n\n\t// Try plain JSON first\n\ttry {\n\t\treturn JSON.parse(text) as Record<string, unknown>;\n\t} catch {\n\t\t// fall through to JSONC\n\t}\n\n\ttry {\n\t\tconst cleaned = stripTrailingCommas(stripJsonComments(text));\n\t\treturn JSON.parse(cleaned) as Record<string, unknown>;\n\t} catch {\n\t\treturn {};\n\t}\n}\n\n/** Expand `~/...` paths like Python's `Path(...).expanduser()`. */\nexport function expandUserPath(value: string): string {\n\treturn value.startsWith(\"~/\") ? join(homedir(), value.slice(2)) : value;\n}\n\n/** Env var overrides matching Python's CONFIG_ENV_OVERRIDES. */\nexport const CODEMEM_CONFIG_ENV_OVERRIDES: Record<string, string> = {\n\tactor_id: \"CODEMEM_ACTOR_ID\",\n\tactor_display_name: \"CODEMEM_ACTOR_DISPLAY_NAME\",\n\tclaude_command: \"CODEMEM_CLAUDE_COMMAND\",\n\tobserver_provider: \"CODEMEM_OBSERVER_PROVIDER\",\n\tobserver_model: \"CODEMEM_OBSERVER_MODEL\",\n\tobserver_base_url: \"CODEMEM_OBSERVER_BASE_URL\",\n\tobserver_runtime: \"CODEMEM_OBSERVER_RUNTIME\",\n\tobserver_auth_source: \"CODEMEM_OBSERVER_AUTH_SOURCE\",\n\tobserver_auth_file: \"CODEMEM_OBSERVER_AUTH_FILE\",\n\tobserver_auth_command: \"CODEMEM_OBSERVER_AUTH_COMMAND\",\n\tobserver_auth_timeout_ms: \"CODEMEM_OBSERVER_AUTH_TIMEOUT_MS\",\n\tobserver_auth_cache_ttl_s: \"CODEMEM_OBSERVER_AUTH_CACHE_TTL_S\",\n\tobserver_headers: \"CODEMEM_OBSERVER_HEADERS\",\n\tobserver_max_chars: \"CODEMEM_OBSERVER_MAX_CHARS\",\n\tpack_observation_limit: \"CODEMEM_PACK_OBSERVATION_LIMIT\",\n\tpack_session_limit: \"CODEMEM_PACK_SESSION_LIMIT\",\n\tsync_enabled: \"CODEMEM_SYNC_ENABLED\",\n\tsync_host: \"CODEMEM_SYNC_HOST\",\n\tsync_port: \"CODEMEM_SYNC_PORT\",\n\tsync_interval_s: \"CODEMEM_SYNC_INTERVAL_S\",\n\tsync_mdns: \"CODEMEM_SYNC_MDNS\",\n\tsync_advertise: \"CODEMEM_SYNC_ADVERTISE\",\n\tsync_coordinator_url: \"CODEMEM_SYNC_COORDINATOR_URL\",\n\tsync_coordinator_group: \"CODEMEM_SYNC_COORDINATOR_GROUP\",\n\tsync_coordinator_groups: \"CODEMEM_SYNC_COORDINATOR_GROUPS\",\n\tsync_coordinator_timeout_s: \"CODEMEM_SYNC_COORDINATOR_TIMEOUT_S\",\n\tsync_coordinator_presence_ttl_s: \"CODEMEM_SYNC_COORDINATOR_PRESENCE_TTL_S\",\n\tsync_coordinator_admin_secret: \"CODEMEM_SYNC_COORDINATOR_ADMIN_SECRET\",\n\tsync_retention_enabled: \"CODEMEM_SYNC_RETENTION_ENABLED\",\n\tsync_retention_max_age_days: \"CODEMEM_SYNC_RETENTION_MAX_AGE_DAYS\",\n\tsync_retention_max_size_mb: \"CODEMEM_SYNC_RETENTION_MAX_SIZE_MB\",\n\tsync_retention_interval_s: \"CODEMEM_SYNC_RETENTION_INTERVAL_S\",\n\tsync_retention_max_runtime_ms: \"CODEMEM_SYNC_RETENTION_MAX_RUNTIME_MS\",\n\tsync_retention_max_ops_per_pass: \"CODEMEM_SYNC_RETENTION_MAX_OPS_PER_PASS\",\n\tsync_projects_include: \"CODEMEM_SYNC_PROJECTS_INCLUDE\",\n\tsync_projects_exclude: \"CODEMEM_SYNC_PROJECTS_EXCLUDE\",\n\traw_events_sweeper_interval_s: \"CODEMEM_RAW_EVENTS_SWEEPER_INTERVAL_S\",\n};\n\n/** Resolve codemem config path with CODEMEM_CONFIG override. */\nexport function getCodememConfigPath(): string {\n\tconst envPath = process.env.CODEMEM_CONFIG?.trim();\n\tif (envPath) return expandUserPath(envPath);\n\tconst configDir = join(homedir(), \".config\", \"codemem\");\n\tconst candidates = [join(configDir, \"config.json\"), join(configDir, \"config.jsonc\")];\n\treturn candidates.find((p) => existsSync(p)) ?? join(configDir, \"config.json\");\n}\n\n/** Read codemem config file with the same JSON/JSONC behavior as Python. */\nexport function readCodememConfigFile(): Record<string, unknown> {\n\tconst configPath = getCodememConfigPath();\n\tif (!existsSync(configPath)) return {};\n\n\tlet text: string;\n\ttry {\n\t\ttext = readFileSync(configPath, \"utf-8\");\n\t} catch {\n\t\treturn {};\n\t}\n\n\tif (!text.trim()) return {};\n\n\ttry {\n\t\tconst parsed = JSON.parse(text) as unknown;\n\t\treturn parsed != null && typeof parsed === \"object\" && !Array.isArray(parsed)\n\t\t\t? (parsed as Record<string, unknown>)\n\t\t\t: {};\n\t} catch {\n\t\t// fall through to JSONC\n\t}\n\n\ttry {\n\t\tconst cleaned = stripTrailingCommas(stripJsonComments(text));\n\t\tconst parsed = JSON.parse(cleaned) as unknown;\n\t\treturn parsed != null && typeof parsed === \"object\" && !Array.isArray(parsed)\n\t\t\t? (parsed as Record<string, unknown>)\n\t\t\t: {};\n\t} catch {\n\t\treturn {};\n\t}\n}\n\n/** Persist the codemem config file as normalized JSON. */\nexport function writeCodememConfigFile(data: Record<string, unknown>, configPath?: string): string {\n\tconst targetPath = configPath ? expandUserPath(configPath) : getCodememConfigPath();\n\tmkdirSync(dirname(targetPath), { recursive: true });\n\twriteFileSync(targetPath, `${JSON.stringify(data, null, 2)}\\n`, \"utf8\");\n\treturn targetPath;\n}\n\n/** Return active env overrides for codemem config keys. */\nexport function getCodememEnvOverrides(): Record<string, string> {\n\tconst overrides: Record<string, string> = {};\n\tfor (const [key, envVar] of Object.entries(CODEMEM_CONFIG_ENV_OVERRIDES)) {\n\t\tconst val = process.env[envVar];\n\t\tif (val != null && val !== \"\") overrides[key] = envVar;\n\t}\n\treturn overrides;\n}\n\n// ---------------------------------------------------------------------------\n// Provider helpers\n// ---------------------------------------------------------------------------\n\ntype AnyRecord = Record<string, unknown>;\n\nfunction asRecord(value: unknown): AnyRecord | null {\n\treturn value != null && typeof value === \"object\" && !Array.isArray(value)\n\t\t? (value as AnyRecord)\n\t\t: null;\n}\n\n/** Get provider-specific config block from the opencode config. */\nexport function getOpenCodeProviderConfig(provider: string): AnyRecord {\n\tconst config = loadOpenCodeConfig();\n\tconst providerConfig = asRecord(config.provider);\n\tif (!providerConfig) return {};\n\tconst data = asRecord(providerConfig[provider]);\n\treturn data ?? {};\n}\n\n/** List all custom provider keys from the opencode config. */\nexport function listCustomProviders(): Set<string> {\n\tconst config = loadOpenCodeConfig();\n\tconst providerConfig = asRecord(config.provider);\n\tif (!providerConfig) return new Set();\n\treturn new Set(Object.keys(providerConfig));\n}\n\nconst BUILTIN_MODEL_PREFIX_PROVIDERS = new Set([\"openai\", \"anthropic\", \"opencode\"]);\n\nfunction extractProviderPrefix(value: unknown): string | null {\n\tif (typeof value !== \"string\" || !value.includes(\"/\")) return null;\n\tconst prefix = value.split(\"/\")[0]?.trim().toLowerCase();\n\treturn prefix ? prefix : null;\n}\n\nexport function listConfiguredOpenCodeProviders(): Set<string> {\n\tconst providers = listCustomProviders();\n\tconst config = loadOpenCodeConfig();\n\tfor (const key of [\"model\", \"small_model\"]) {\n\t\tconst prefix = extractProviderPrefix(config[key]);\n\t\tif (prefix) providers.add(prefix);\n\t}\n\treturn providers;\n}\n\nexport function listObserverProviderOptions(): string[] {\n\tconst providers = listConfiguredOpenCodeProviders();\n\tfor (const provider of BUILTIN_MODEL_PREFIX_PROVIDERS) providers.add(provider);\n\treturn Array.from(providers).sort((a, b) => a.localeCompare(b));\n}\n\nexport function resolveBuiltInProviderFromModel(model: string): string | null {\n\tconst prefix = extractProviderPrefix(model);\n\treturn prefix && BUILTIN_MODEL_PREFIX_PROVIDERS.has(prefix) ? prefix : null;\n}\n\nexport function resolveBuiltInProviderDefaultModel(provider: string): string | null {\n\tif (provider === \"openai\") return \"gpt-5.1-codex-mini\";\n\tif (provider === \"anthropic\") return \"claude-sonnet-4-20250514\";\n\tif (provider === \"opencode\") return \"opencode/gpt-5.1-codex-mini\";\n\treturn null;\n}\n\nexport function resolveBuiltInProviderModel(\n\tprovider: string,\n\tmodelName: string,\n): [baseUrl: string | null, modelId: string | null, headers: Record<string, string>] {\n\tif (provider !== \"opencode\") {\n\t\treturn [null, modelName || resolveBuiltInProviderDefaultModel(provider), {}];\n\t}\n\tconst name = modelName || resolveBuiltInProviderDefaultModel(provider) || \"\";\n\tconst prefix = `${provider}/`;\n\tconst shortName = name.startsWith(prefix) ? name.slice(prefix.length) : name;\n\treturn [\"https://opencode.ai/zen/v1\", shortName || null, {}];\n}\n\n/** Extract provider prefix from a model string like `\"myprovider/model-name\"`. */\nexport function resolveCustomProviderFromModel(\n\tmodel: string,\n\tproviders: Set<string>,\n): string | null {\n\tif (!model || !model.includes(\"/\")) return null;\n\tconst prefix = model.split(\"/\")[0] ?? \"\";\n\treturn prefix && providers.has(prefix) ? prefix : null;\n}\n\n// ---------------------------------------------------------------------------\n// Placeholder resolution\n// ---------------------------------------------------------------------------\n\n/**\n * Expand `$ENV_VAR` / `${ENV_VAR}` references and `{file:/path}` placeholders.\n *\n * Environment variable expansion mirrors Python's `os.path.expandvars`.\n * File placeholders read the file content and substitute it inline.\n */\nexport function resolvePlaceholder(value: string): string {\n\tconst expanded = expandEnvVars(value);\n\treturn resolveFilePlaceholder(expanded);\n}\n\n/** Expand `$VAR` and `${VAR}` environment variable references. */\nfunction expandEnvVars(value: string): string {\n\treturn value.replace(/\\$\\{([^}]+)\\}|\\$([A-Za-z_][A-Za-z0-9_]*)/g, (match, braced, bare) => {\n\t\tconst name = braced ?? bare;\n\t\treturn process.env[name] ?? match;\n\t});\n}\n\n/** Expand `{file:path}` placeholders by reading the referenced file. */\nfunction resolveFilePlaceholder(value: string): string {\n\tif (!value.includes(\"{file:\")) return value;\n\treturn value.replace(/\\{file:([^}]+)\\}/g, (match, rawPath: string) => {\n\t\tconst trimmed = rawPath.trim();\n\t\tif (!trimmed) return match;\n\t\tconst resolved = expandEnvVars(trimmed).replace(/^~/, homedir());\n\t\ttry {\n\t\t\treturn readFileSync(resolved, \"utf-8\").trim();\n\t\t} catch {\n\t\t\treturn match;\n\t\t}\n\t});\n}\n\n// ---------------------------------------------------------------------------\n// Provider option extraction\n// ---------------------------------------------------------------------------\n\n/** Extract the `options` sub-object from a provider config block. */\nexport function getProviderOptions(providerConfig: AnyRecord): AnyRecord {\n\tconst options = asRecord(providerConfig.options);\n\treturn options ?? {};\n}\n\n/** Extract `baseURL` / `baseUrl` / `base_url` from provider config. */\nexport function getProviderBaseUrl(providerConfig: AnyRecord): string | null {\n\tconst options = getProviderOptions(providerConfig);\n\t// Use || (not ??) so empty strings fall through to the next candidate (matches Python's `or`)\n\tconst baseUrl = options.baseURL || options.baseUrl || options.base_url || providerConfig.base_url;\n\treturn typeof baseUrl === \"string\" && baseUrl ? baseUrl : null;\n}\n\n/** Extract and resolve headers (with placeholder expansion) from provider config. */\nexport function getProviderHeaders(providerConfig: AnyRecord): Record<string, string> {\n\tconst options = getProviderOptions(providerConfig);\n\tconst headers = asRecord(options.headers);\n\tif (!headers) return {};\n\tconst parsed: Record<string, string> = {};\n\tfor (const [key, value] of Object.entries(headers)) {\n\t\tif (typeof key !== \"string\" || typeof value !== \"string\") continue;\n\t\tparsed[key] = resolvePlaceholder(value);\n\t}\n\treturn parsed;\n}\n\n/** Extract API key from provider config (direct value or env-var reference). */\nexport function getProviderApiKey(providerConfig: AnyRecord): string | null {\n\tconst options = getProviderOptions(providerConfig);\n\t// Use || (not ??) so empty strings fall through (matches Python's `or`)\n\tconst apiKey = options.apiKey || providerConfig.apiKey;\n\tif (typeof apiKey === \"string\" && apiKey) {\n\t\treturn resolvePlaceholder(apiKey);\n\t}\n\tconst apiKeyEnv = (options.apiKeyEnv ?? options.api_key_env) as string | undefined;\n\tif (typeof apiKeyEnv === \"string\" && apiKeyEnv) {\n\t\tconst value = process.env[apiKeyEnv];\n\t\tif (value) return value;\n\t}\n\treturn null;\n}\n\n// ---------------------------------------------------------------------------\n// Custom provider model resolution\n// ---------------------------------------------------------------------------\n\n/** Find the default model for a custom provider. */\nexport function resolveCustomProviderDefaultModel(provider: string): string | null {\n\tconst providerConfig = getOpenCodeProviderConfig(provider);\n\tconst options = getProviderOptions(providerConfig);\n\tconst defaultModel =\n\t\toptions.defaultModel ??\n\t\toptions.default_model ??\n\t\tproviderConfig.defaultModel ??\n\t\tproviderConfig.default_model;\n\tif (typeof defaultModel === \"string\" && defaultModel) {\n\t\treturn defaultModel.startsWith(`${provider}/`) ? defaultModel : `${provider}/${defaultModel}`;\n\t}\n\tconst models = asRecord(providerConfig.models);\n\tif (models) {\n\t\tconst firstKey = Object.keys(models)[0];\n\t\tif (typeof firstKey === \"string\" && firstKey) {\n\t\t\treturn `${provider}/${firstKey}`;\n\t\t}\n\t}\n\treturn null;\n}\n\n/**\n * Resolve base_url, model_id, and headers for a custom provider model.\n *\n * Returns `[baseUrl, modelId, headers]`.\n */\nexport function resolveCustomProviderModel(\n\tprovider: string,\n\tmodelName: string,\n): [baseUrl: string | null, modelId: string | null, headers: Record<string, string>] {\n\tconst providerConfig = getOpenCodeProviderConfig(provider);\n\tconst baseUrl = getProviderBaseUrl(providerConfig);\n\tconst headers = getProviderHeaders(providerConfig);\n\n\tlet name = modelName;\n\tif (!name) {\n\t\tname = resolveCustomProviderDefaultModel(provider) ?? \"\";\n\t}\n\n\tconst prefix = `${provider}/`;\n\tconst shortName = name.startsWith(prefix) ? name.slice(prefix.length) : name;\n\n\tconst models = asRecord(providerConfig.models);\n\tlet modelId: string | null = shortName;\n\tif (models) {\n\t\tconst modelConfig = asRecord(models[shortName]);\n\t\tif (modelConfig && typeof modelConfig.id === \"string\") {\n\t\t\tmodelId = modelConfig.id;\n\t\t}\n\t}\n\n\tif (typeof modelId !== \"string\" || !modelId) {\n\t\tmodelId = null;\n\t}\n\n\treturn [baseUrl, modelId, headers];\n}\n","/**\n * Database connection and schema initialization for the codemem TS backend.\n *\n * Mirrors codemem/db.py — same pragmas, same WAL mode, same sqlite-vec loading.\n * During Phase 1 of the migration, Python owns DDL (schema migrations).\n * The TS runtime validates the schema version but does NOT run migrations.\n */\n\nimport {\n\tcloseSync,\n\tcopyFileSync,\n\texistsSync,\n\tmkdirSync,\n\topenSync,\n\treaddirSync,\n\trenameSync,\n\tstatSync,\n\tunlinkSync,\n\twriteFileSync,\n} from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { basename, dirname, join } from \"node:path\";\nimport type { Database as DatabaseType } from \"better-sqlite3\";\nimport Database from \"better-sqlite3\";\nimport * as sqliteVec from \"sqlite-vec\";\nimport { expandUserPath } from \"./observer-config.js\";\n\n// Re-export the Database type for consumers\nexport type { DatabaseType as Database };\n\n/** Current schema version this TS runtime was built against. */\nexport const SCHEMA_VERSION = 6;\n\n/**\n * Minimum schema version the TS runtime can operate with.\n * Per the coexistence contract (docs/plans/2026-03-15-db-coexistence-contract.md),\n * TS must tolerate additive newer schemas. It only hard-fails if the schema is\n * too old to have the tables/columns it needs.\n */\nexport const MIN_COMPATIBLE_SCHEMA = 6;\n\n/** Required tables the TS runtime needs to function. */\nconst REQUIRED_TABLES = [\n\t\"memory_items\",\n\t\"sessions\",\n\t\"artifacts\",\n\t\"raw_events\",\n\t\"raw_event_sessions\",\n\t\"usage_events\",\n] as const;\n\n/** Marker file written after the first successful TS access to a DB. */\nconst TS_MARKER = \".codemem-ts-accessed\";\n\n/** Lock file to avoid concurrent first-access backups. */\nconst TS_BACKUP_LOCK = \".codemem-ts-backup.lock\";\n\n/** Consider a backup lock stale after 15 minutes. */\nconst TS_BACKUP_LOCK_STALE_MS = 15 * 60 * 1000;\n\ninterface BackupLockAcquireResult {\n\tfd: number | null;\n\tcontention: boolean;\n}\n\nfunction acquireBackupLock(lockPath: string): BackupLockAcquireResult {\n\tmkdirSync(dirname(lockPath), { recursive: true });\n\ttry {\n\t\treturn { fd: openSync(lockPath, \"wx\"), contention: false };\n\t} catch (err) {\n\t\tconst code = err && typeof err === \"object\" ? (err as NodeJS.ErrnoException).code : undefined;\n\t\tif (code === \"EEXIST\") {\n\t\t\tlet stale = false;\n\t\t\ttry {\n\t\t\t\tconst ageMs = Date.now() - statSync(lockPath).mtimeMs;\n\t\t\t\tstale = Number.isFinite(ageMs) && ageMs > TS_BACKUP_LOCK_STALE_MS;\n\t\t\t} catch {\n\t\t\t\t// If we can't read lock metadata, treat as live contention.\n\t\t\t}\n\n\t\t\tif (!stale) {\n\t\t\t\treturn { fd: null, contention: true };\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tunlinkSync(lockPath);\n\t\t\t} catch (unlinkErr) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`[codemem] Warning: failed to clear stale backup lock at ${lockPath}:`,\n\t\t\t\t\tunlinkErr,\n\t\t\t\t);\n\t\t\t\treturn { fd: null, contention: false };\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\treturn { fd: openSync(lockPath, \"wx\"), contention: false };\n\t\t\t} catch (retryErr) {\n\t\t\t\tconst retryCode =\n\t\t\t\t\tretryErr && typeof retryErr === \"object\"\n\t\t\t\t\t\t? (retryErr as NodeJS.ErrnoException).code\n\t\t\t\t\t\t: undefined;\n\t\t\t\tif (retryCode === \"EEXIST\") {\n\t\t\t\t\treturn { fd: null, contention: true };\n\t\t\t\t}\n\t\t\t\tconsole.error(`[codemem] Warning: failed to acquire backup lock at ${lockPath}:`, retryErr);\n\t\t\t\treturn { fd: null, contention: false };\n\t\t\t}\n\t\t}\n\n\t\tconsole.error(`[codemem] Warning: failed to acquire backup lock at ${lockPath}:`, err);\n\t\treturn { fd: null, contention: false };\n\t}\n}\n\n/** Default database path — matches Python's DEFAULT_DB_PATH. */\nexport const DEFAULT_DB_PATH = join(homedir(), \".codemem\", \"mem.sqlite\");\n\n/**\n * Resolve the database path from explicit arg → CODEMEM_DB env → default.\n * All TS entry points should use this instead of hardcoding fallback logic.\n */\nexport function resolveDbPath(explicit?: string): string {\n\tif (explicit) return expandUserPath(explicit);\n\tconst envPath = process.env.CODEMEM_DB;\n\tif (envPath) return expandUserPath(envPath);\n\treturn DEFAULT_DB_PATH;\n}\n\n/** Legacy database paths that may exist from older installs. */\nconst LEGACY_DB_PATHS = [\n\tjoin(homedir(), \".codemem.sqlite\"),\n\tjoin(homedir(), \".opencode-mem.sqlite\"),\n];\n\n/** WAL sidecar extensions for a SQLite database file. */\nconst SIDECAR_EXTENSIONS = [\"-wal\", \"-shm\"];\n\n/**\n * Move a file and its WAL sidecars to a new location.\n * Falls back to copy+delete if rename fails (cross-device).\n */\nfunction moveWithSidecars(src: string, dst: string): void {\n\tmkdirSync(dirname(dst), { recursive: true });\n\tconst pairs: [string, string][] = [\n\t\t[src, dst],\n\t\t...SIDECAR_EXTENSIONS.map((ext): [string, string] => [src + ext, dst + ext]),\n\t];\n\tfor (const [srcPath, dstPath] of pairs) {\n\t\tif (!existsSync(srcPath)) continue;\n\t\ttry {\n\t\t\trenameSync(srcPath, dstPath);\n\t\t} catch {\n\t\t\ttry {\n\t\t\t\tcopyFileSync(srcPath, dstPath);\n\t\t\t\ttry {\n\t\t\t\t\tunlinkSync(srcPath);\n\t\t\t\t} catch {\n\t\t\t\t\t// Best effort — original left in place\n\t\t\t\t}\n\t\t\t} catch (copyErr) {\n\t\t\t\t// TOCTOU: source vanished between existsSync and copy (concurrent migration).\n\t\t\t\t// If target now exists, another process already migrated — that's fine.\n\t\t\t\tif (existsSync(dstPath)) continue;\n\t\t\t\tthrow copyErr;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Migrate legacy database paths to the current default location.\n *\n * Only runs when dbPath is the DEFAULT_DB_PATH and doesn't already exist.\n * Matches Python's migrate_legacy_default_db in db.py.\n */\nexport function migrateLegacyDbPath(dbPath: string): void {\n\tif (dbPath !== DEFAULT_DB_PATH) return;\n\tif (existsSync(dbPath)) return;\n\n\tfor (const legacyPath of LEGACY_DB_PATHS) {\n\t\tif (!existsSync(legacyPath)) continue;\n\t\tmoveWithSidecars(legacyPath, dbPath);\n\t\treturn;\n\t}\n}\n\n/**\n * Open a better-sqlite3 connection with the standard codemem pragmas.\n *\n * Migrates legacy DB paths if needed, creates parent directories,\n * sets WAL mode, busy timeout, foreign keys.\n * Does NOT initialize or migrate the schema — during Phase 1, Python owns DDL.\n */\nexport function connect(dbPath: string = DEFAULT_DB_PATH): DatabaseType {\n\tmigrateLegacyDbPath(dbPath);\n\tmkdirSync(dirname(dbPath), { recursive: true });\n\tconst db = new Database(dbPath);\n\n\t// Match Python's connect() pragmas exactly\n\tdb.pragma(\"foreign_keys = ON\");\n\tdb.pragma(\"busy_timeout = 5000\");\n\n\tconst journalMode = db.pragma(\"journal_mode = WAL\", { simple: true }) as string;\n\tif (journalMode.toLowerCase() !== \"wal\") {\n\t\tconsole.warn(\n\t\t\t`Failed to enable WAL mode (got ${journalMode}). Concurrent access may not work correctly.`,\n\t\t);\n\t}\n\n\tdb.pragma(\"synchronous = NORMAL\");\n\n\treturn db;\n}\n\nfunction hasPlannerStats(db: DatabaseType): boolean {\n\ttry {\n\t\treturn !!db.prepare(\"SELECT 1 FROM sqlite_stat1 LIMIT 1\").pluck().get();\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Keep SQLite planner statistics healthy for FTS-heavy queries.\n *\n * We always run PRAGMA optimize as a cheap maintenance hint. If planner\n * statistics have never been collected and the core search tables exist,\n * bootstrap them with ANALYZE so Node SQLite picks stable FTS query plans.\n */\nexport function ensurePlannerStats(db: DatabaseType): void {\n\tdb.pragma(\"optimize\");\n\n\tif (hasPlannerStats(db)) return;\n\tif (!tableExists(db, \"memory_items\") || !tableExists(db, \"memory_fts\")) return;\n\n\tdb.exec(\"ANALYZE\");\n\tdb.pragma(\"optimize\");\n}\n\n/**\n * Load the sqlite-vec extension into an open database connection.\n *\n * Call this after connect() when vector operations are needed.\n * Skipped when CODEMEM_EMBEDDING_DISABLED=1.\n */\nexport function loadSqliteVec(db: DatabaseType): void {\n\tif (isEmbeddingDisabled()) {\n\t\treturn;\n\t}\n\n\tsqliteVec.load(db);\n\n\tconst row = db.prepare(\"SELECT vec_version() AS v\").get() as { v: string } | undefined;\n\tif (!row?.v) {\n\t\tthrow new Error(\"sqlite-vec loaded but version check failed\");\n\t}\n}\n\n/** Check if embeddings are disabled via environment variable. */\nexport function isEmbeddingDisabled(): boolean {\n\tconst val = process.env.CODEMEM_EMBEDDING_DISABLED?.toLowerCase();\n\treturn val === \"1\" || val === \"true\" || val === \"yes\";\n}\n\n/**\n * Read the schema user_version from the database.\n *\n * During Phase 1, the TS runtime uses this to verify the schema is initialized\n * (by Python) before operating. It does NOT set or bump the version.\n */\nexport function getSchemaVersion(db: DatabaseType): number {\n\tconst row = db.pragma(\"user_version\", { simple: true });\n\treturn typeof row === \"number\" ? row : 0;\n}\n\n/**\n * Create a timestamped backup of the database on first TS access.\n *\n * The backup file is named `mem.sqlite.pre-ts-YYYYMMDDTHHMMSS.bak` and placed\n * next to the original. A marker file prevents repeated backups. This ensures\n * users can recover if the TS runtime introduces bugs that corrupt the DB\n * during the migration period.\n */\nexport function backupOnFirstAccess(dbPath: string): void {\n\tconst markerPath = join(dirname(dbPath), TS_MARKER);\n\tif (existsSync(markerPath)) return;\n\n\t// Find the actual DB file to back up. It may be at the target path already,\n\t// or at a legacy location that migrateLegacyDbPath() will move later.\n\t// Back up whichever exists BEFORE migration runs.\n\tlet sourceDbPath = dbPath;\n\tif (!existsSync(dbPath)) {\n\t\t// Check legacy locations — same order as migrateLegacyDbPath()\n\t\tconst legacyPaths = [\n\t\t\tjoin(dirname(dbPath), \"..\", \".codemem.sqlite\"),\n\t\t\tjoin(dirname(dbPath), \"..\", \".opencode-mem.sqlite\"),\n\t\t];\n\t\tconst legacyPath = legacyPaths.find((p) => existsSync(p));\n\t\tif (legacyPath) {\n\t\t\tsourceDbPath = legacyPath;\n\t\t} else {\n\t\t\treturn; // Fresh DB, nothing to back up\n\t\t}\n\t}\n\n\tconst lockPath = join(dirname(dbPath), TS_BACKUP_LOCK);\n\tconst { fd: lockFd, contention } = acquireBackupLock(lockPath);\n\tif (contention) {\n\t\t// Another process is handling first-access backup.\n\t\treturn;\n\t}\n\n\tconst writeMarker = (): void => {\n\t\ttry {\n\t\t\tmkdirSync(dirname(markerPath), { recursive: true });\n\t\t\twriteFileSync(markerPath, new Date().toISOString(), \"utf-8\");\n\t\t} catch {\n\t\t\t// Non-fatal — worst case we attempt backup again later.\n\t\t}\n\t};\n\n\tconst hasViableExistingBackup = (): boolean => {\n\t\tlet sourceSize = 0;\n\t\ttry {\n\t\t\tsourceSize = statSync(sourceDbPath).size;\n\t\t} catch {\n\t\t\tsourceSize = 0;\n\t\t}\n\t\tconst minViableSize = sourceSize > 0 ? Math.floor(sourceSize * 0.9) : 1;\n\t\tconst prefix = `${basename(sourceDbPath)}.pre-ts-`;\n\t\ttry {\n\t\t\tconst entries = readdirSync(dirname(sourceDbPath));\n\t\t\tfor (const entry of entries) {\n\t\t\t\tif (!entry.startsWith(prefix) || !entry.endsWith(\".bak\")) continue;\n\t\t\t\tconst fullPath = join(dirname(sourceDbPath), entry);\n\t\t\t\ttry {\n\t\t\t\t\tif (statSync(fullPath).size >= minViableSize) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Ignore races while inspecting backup candidates.\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {\n\t\t\t// Ignore directory read errors — proceed with normal backup path.\n\t\t}\n\t\treturn false;\n\t};\n\n\tconst ts = new Date().toISOString().replace(/[:.]/g, \"\").slice(0, 15);\n\tconst backupPath = `${sourceDbPath}.pre-ts-${ts}.bak`;\n\tlet backupSucceeded = false;\n\ttry {\n\t\tif (existsSync(markerPath)) return;\n\t\tif (hasViableExistingBackup()) {\n\t\t\twriteMarker();\n\t\t\treturn;\n\t\t}\n\n\t\tcopyFileSync(sourceDbPath, backupPath);\n\t\t// Also back up WAL/SHM if present (they contain uncommitted data)\n\t\tconst walPath = `${sourceDbPath}-wal`;\n\t\tconst shmPath = `${sourceDbPath}-shm`;\n\t\tif (existsSync(walPath)) copyFileSync(walPath, `${backupPath}-wal`);\n\t\tif (existsSync(shmPath)) copyFileSync(shmPath, `${backupPath}-shm`);\n\t\tconsole.error(`[codemem] First TS access — backed up database to ${backupPath}`);\n\t\tbackupSucceeded = true;\n\t} catch (err) {\n\t\tconsole.error(`[codemem] Warning: failed to create backup at ${backupPath}:`, err);\n\t\t// Continue — backup failure shouldn't prevent operation, but don't write marker\n\t} finally {\n\t\tif (lockFd != null) {\n\t\t\ttry {\n\t\t\t\tcloseSync(lockFd);\n\t\t\t} catch {\n\t\t\t\t// Ignore close errors.\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tunlinkSync(lockPath);\n\t\t\t} catch {\n\t\t\t\t// Ignore lock cleanup errors.\n\t\t\t}\n\t\t}\n\t}\n\n\t// Only write marker after backup succeeds — a transient failure should\n\t// retry on next access, not permanently suppress the safety net.\n\tif (backupSucceeded) {\n\t\twriteMarker();\n\t}\n}\n\n/**\n * Verify the database schema is initialized and compatible.\n *\n * Per the coexistence contract: TS tolerates additive newer schemas (Python may\n * have run migrations that add tables/columns the TS runtime doesn't know about).\n * TS only hard-fails if:\n * - Schema is uninitialized (version 0)\n * - Schema is too old (below MIN_COMPATIBLE_SCHEMA)\n * - Required tables are missing\n * - FTS5 index is missing (needed for search)\n *\n * Warns (but continues) if schema is newer than SCHEMA_VERSION — the additive\n * changes are assumed safe per the coexistence contract.\n */\nexport function assertSchemaReady(db: DatabaseType): void {\n\tconst version = getSchemaVersion(db);\n\tif (version === 0) {\n\t\tthrow new Error(\n\t\t\t\"Database schema is not initialized. \" +\n\t\t\t\t\"Initialize the SQLite database with the current TypeScript runtime before retrying.\",\n\t\t);\n\t}\n\tif (version < MIN_COMPATIBLE_SCHEMA) {\n\t\tthrow new Error(\n\t\t\t`Database schema version ${version} is older than minimum compatible (${MIN_COMPATIBLE_SCHEMA}). ` +\n\t\t\t\t\"Upgrade the database schema with the current TypeScript runtime before retrying.\",\n\t\t);\n\t}\n\tif (version > SCHEMA_VERSION) {\n\t\tconsole.warn(\n\t\t\t`Database schema version ${version} is newer than this TS runtime (${SCHEMA_VERSION}). ` +\n\t\t\t\t\"Running in compatibility mode — additive schema changes are tolerated.\",\n\t\t);\n\t}\n\n\t// Validate required tables exist (catches corrupt or partially migrated DBs)\n\tconst missing = REQUIRED_TABLES.filter((t) => !tableExists(db, t));\n\tif (missing.length > 0) {\n\t\tthrow new Error(\n\t\t\t`Required tables missing: ${missing.join(\", \")}. ` +\n\t\t\t\t\"The database may be corrupt or from an incompatible version.\",\n\t\t);\n\t}\n\n\t// FTS5 index is required for search\n\tif (!tableExists(db, \"memory_fts\")) {\n\t\tthrow new Error(\n\t\t\t\"FTS5 index (memory_fts) is missing. \" +\n\t\t\t\t\"Rebuild the database schema with the current TypeScript runtime before retrying.\",\n\t\t);\n\t}\n}\n\n/** Check if a table exists in the database. */\nexport function tableExists(db: DatabaseType, table: string): boolean {\n\tconst row = db\n\t\t.prepare(\"SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = ?\")\n\t\t.get(table);\n\treturn row !== undefined;\n}\n\n/** Check if a column exists in a table. */\nexport function columnExists(db: DatabaseType, table: string, column: string): boolean {\n\tif (!tableExists(db, table)) return false;\n\tconst row = db\n\t\t.prepare(\"SELECT 1 FROM pragma_table_info(?) WHERE name = ? LIMIT 1\")\n\t\t.get(table, column);\n\treturn row !== undefined;\n}\n\n/**\n * Apply additive compatibility fixes for legacy TS-era schemas.\n *\n * These are safe, one-way `ALTER TABLE ... ADD COLUMN` updates used to\n * prevent runtime failures when older local databases are missing columns\n * introduced in later releases.\n */\nexport function ensureAdditiveSchemaCompatibility(db: DatabaseType): void {\n\ttry {\n\t\tdb.exec(`\n\t\t\tCREATE TABLE IF NOT EXISTS sync_reset_state (\n\t\t\t\tid INTEGER PRIMARY KEY,\n\t\t\t\tgeneration INTEGER NOT NULL,\n\t\t\t\tsnapshot_id TEXT NOT NULL,\n\t\t\t\tbaseline_cursor TEXT,\n\t\t\t\tretained_floor_cursor TEXT,\n\t\t\t\tupdated_at TEXT NOT NULL\n\t\t\t)\n\t\t`);\n\t} catch {\n\t\t// Keep compatibility shim fail-open for optional additive tables.\n\t}\n\n\t// Add phase column to sync_daemon_state for rebootstrap safety gate.\n\tif (tableExists(db, \"sync_daemon_state\") && !columnExists(db, \"sync_daemon_state\", \"phase\")) {\n\t\ttry {\n\t\t\tdb.exec(\"ALTER TABLE sync_daemon_state ADD COLUMN phase TEXT\");\n\t\t} catch {\n\t\t\t// Race-safe: another process may have added it first.\n\t\t}\n\t}\n\n\tif (!tableExists(db, \"raw_event_flush_batches\")) return;\n\n\tconst additiveColumns: Array<{ name: string; ddl: string }> = [\n\t\t{ name: \"error_message\", ddl: \"TEXT\" },\n\t\t{ name: \"error_type\", ddl: \"TEXT\" },\n\t\t{ name: \"observer_provider\", ddl: \"TEXT\" },\n\t\t{ name: \"observer_model\", ddl: \"TEXT\" },\n\t\t{ name: \"observer_runtime\", ddl: \"TEXT\" },\n\t\t{ name: \"observer_auth_source\", ddl: \"TEXT\" },\n\t\t{ name: \"observer_auth_type\", ddl: \"TEXT\" },\n\t\t{ name: \"observer_error_code\", ddl: \"TEXT\" },\n\t\t{ name: \"observer_error_message\", ddl: \"TEXT\" },\n\t\t{ name: \"attempt_count\", ddl: \"INTEGER NOT NULL DEFAULT 0\" },\n\t];\n\n\tfor (const { name, ddl } of additiveColumns) {\n\t\tif (columnExists(db, \"raw_event_flush_batches\", name)) continue;\n\t\ttry {\n\t\t\tdb.exec(`ALTER TABLE raw_event_flush_batches ADD COLUMN ${name} ${ddl}`);\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message.toLowerCase() : \"\";\n\t\t\tconst duplicateColumn = message.includes(\"duplicate column name\");\n\t\t\tif (duplicateColumn && columnExists(db, \"raw_event_flush_batches\", name)) {\n\t\t\t\t// Another process may have raced and added the column first.\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthrow err;\n\t\t}\n\t}\n}\n\n/** Safely parse a JSON string, returning {} on failure. */\nexport function fromJson(text: string | null | undefined): Record<string, unknown> {\n\tif (!text) return {};\n\ttry {\n\t\tconst parsed = JSON.parse(text);\n\t\tif (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n\t\t\treturn {};\n\t\t}\n\t\treturn parsed as Record<string, unknown>;\n\t} catch {\n\t\tconsole.warn(`[codemem] fromJson: invalid JSON (${text.slice(0, 80)}...)`);\n\t\treturn {};\n\t}\n}\n\n/**\n * Parse a JSON string strictly — throws on invalid input.\n *\n * Use in mutation paths (replication apply, import) where silently\n * returning {} would mask data corruption. Read paths should use\n * fromJson() which is forgiving.\n */\nexport function fromJsonStrict(text: string | null | undefined): Record<string, unknown> {\n\tif (!text) return {};\n\tconst parsed = JSON.parse(text);\n\tif (typeof parsed !== \"object\" || parsed === null || Array.isArray(parsed)) {\n\t\tthrow new Error(\n\t\t\t`fromJsonStrict: expected object, got ${Array.isArray(parsed) ? \"array\" : typeof parsed}`,\n\t\t);\n\t}\n\treturn parsed as Record<string, unknown>;\n}\n\n/** Serialize a value to JSON, defaulting null/undefined to \"{}\". */\nexport function toJson(data: unknown): string {\n\tif (data == null) return \"{}\";\n\treturn JSON.stringify(data);\n}\n\n/**\n * Serialize a value to JSON, preserving null as SQL NULL.\n *\n * Use this for columns that store JSON arrays (facts, concepts, files_read,\n * files_modified) where NULL means \"no data\" and \"{}\" would be corruption.\n * Also normalizes empty objects ({}) to null — Python's from_json returns {}\n * for empty DB values, so imported exports carry {} instead of null.\n * Use `toJson` for metadata_json where \"{}\" is the correct empty default.\n */\nexport function toJsonNullable(data: unknown): string | null {\n\tif (data == null) return null;\n\t// Normalize empty objects to null — these are never valid array column values\n\tif (\n\t\ttypeof data === \"object\" &&\n\t\t!Array.isArray(data) &&\n\t\tObject.keys(data as object).length === 0\n\t) {\n\t\treturn null;\n\t}\n\treturn JSON.stringify(data);\n}\n","/**\n * Device identity management for the codemem sync system.\n *\n * Handles Ed25519 keypair generation, fingerprinting, and optional\n * keychain storage. Ported from codemem/sync_identity.py.\n */\n\nimport { execFileSync } from \"node:child_process\";\nimport {\n\tcreateHash,\n\tcreatePrivateKey,\n\tcreatePublicKey,\n\tgenerateKeyPairSync,\n\trandomUUID,\n} from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { eq } from \"drizzle-orm\";\nimport { drizzle } from \"drizzle-orm/better-sqlite3\";\nimport type { Database } from \"./db.js\";\nimport { connect as connectDb, resolveDbPath } from \"./db.js\";\nimport * as schema from \"./schema.js\";\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_KEYS_DIR = join(homedir(), \".config\", \"codemem\", \"keys\");\nconst PRIVATE_KEY_NAME = \"device.key\";\nconst PUBLIC_KEY_NAME = \"device.key.pub\";\nconst KEYCHAIN_SERVICE = \"codemem-sync\";\n\n// ---------------------------------------------------------------------------\n// Fingerprint\n// ---------------------------------------------------------------------------\n\n/** SHA-256 hex digest of a public key string. */\nexport function fingerprintPublicKey(publicKey: string): string {\n\treturn createHash(\"sha256\").update(publicKey, \"utf-8\").digest(\"hex\");\n}\n\n// ---------------------------------------------------------------------------\n// Key store mode\n// ---------------------------------------------------------------------------\n\nfunction keyStoreMode(): \"file\" | \"keychain\" {\n\tconst env = process.env.CODEMEM_SYNC_KEY_STORE?.toLowerCase();\n\tif (env === \"keychain\") return \"keychain\";\n\treturn \"file\";\n}\n\n// ---------------------------------------------------------------------------\n// CLI availability helpers\n// ---------------------------------------------------------------------------\n\nfunction cliAvailable(cmd: string): boolean {\n\ttry {\n\t\texecFileSync(\"which\", [cmd], { stdio: \"pipe\" });\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Keychain storage (platform-specific)\n// ---------------------------------------------------------------------------\n\nfunction warnKeychainLimitations(): void {\n\tif (process.platform !== \"darwin\") return;\n\tif (keyStoreMode() !== \"keychain\") return;\n\tif (process.env.CODEMEM_SYNC_KEYCHAIN_WARN === \"0\") return;\n\tconsole.warn(\n\t\t\"[codemem] keychain storage on macOS uses the `security` CLI and may expose the key in process arguments.\",\n\t);\n}\n\n/** Store a private key in the OS keychain. Returns true on success. */\nexport function storePrivateKeyKeychain(privateKey: Buffer, deviceId: string): boolean {\n\tif (process.platform === \"linux\") {\n\t\tif (!cliAvailable(\"secret-tool\")) return false;\n\t\ttry {\n\t\t\texecFileSync(\n\t\t\t\t\"secret-tool\",\n\t\t\t\t[\"store\", \"--label\", \"codemem sync key\", \"service\", KEYCHAIN_SERVICE, \"account\", deviceId],\n\t\t\t\t{ input: privateKey, stdio: [\"pipe\", \"pipe\", \"pipe\"] },\n\t\t\t);\n\t\t\treturn true;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\tif (process.platform === \"darwin\") {\n\t\tif (!cliAvailable(\"security\")) return false;\n\t\ttry {\n\t\t\texecFileSync(\n\t\t\t\t\"security\",\n\t\t\t\t[\n\t\t\t\t\t\"add-generic-password\",\n\t\t\t\t\t\"-a\",\n\t\t\t\t\tdeviceId,\n\t\t\t\t\t\"-s\",\n\t\t\t\t\tKEYCHAIN_SERVICE,\n\t\t\t\t\t\"-w\",\n\t\t\t\t\tprivateKey.toString(\"utf-8\"),\n\t\t\t\t\t\"-U\",\n\t\t\t\t],\n\t\t\t\t{ stdio: [\"pipe\", \"pipe\", \"pipe\"] },\n\t\t\t);\n\t\t\treturn true;\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn false;\n}\n\n/** Load a private key from the OS keychain. Returns null if unavailable. */\nexport function loadPrivateKeyKeychain(deviceId: string): Buffer | null {\n\tif (process.platform === \"linux\") {\n\t\tif (!cliAvailable(\"secret-tool\")) return null;\n\t\ttry {\n\t\t\tconst out = execFileSync(\n\t\t\t\t\"secret-tool\",\n\t\t\t\t[\"lookup\", \"service\", KEYCHAIN_SERVICE, \"account\", deviceId],\n\t\t\t\t{ stdio: [\"pipe\", \"pipe\", \"pipe\"] },\n\t\t\t);\n\t\t\treturn Buffer.from(out);\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\tif (process.platform === \"darwin\") {\n\t\tif (!cliAvailable(\"security\")) return null;\n\t\ttry {\n\t\t\tconst out = execFileSync(\n\t\t\t\t\"security\",\n\t\t\t\t[\"find-generic-password\", \"-a\", deviceId, \"-s\", KEYCHAIN_SERVICE, \"-w\"],\n\t\t\t\t{ stdio: [\"pipe\", \"pipe\", \"pipe\"] },\n\t\t\t);\n\t\t\treturn Buffer.from(out);\n\t\t} catch {\n\t\t\treturn null;\n\t\t}\n\t}\n\treturn null;\n}\n\n// ---------------------------------------------------------------------------\n// Key path resolution\n// ---------------------------------------------------------------------------\n\n/** Resolve private and public key file paths. */\nexport function resolveKeyPaths(keysDir?: string): [string, string] {\n\tconst dir = keysDir ?? DEFAULT_KEYS_DIR;\n\treturn [join(dir, PRIVATE_KEY_NAME), join(dir, PUBLIC_KEY_NAME)];\n}\n\n// ---------------------------------------------------------------------------\n// Key file I/O\n// ---------------------------------------------------------------------------\n\n/** Read the public key from disk. Returns null if missing or empty. */\nexport function loadPublicKey(keysDir?: string): string | null {\n\tconst [, publicPath] = resolveKeyPaths(keysDir);\n\tif (!existsSync(publicPath)) return null;\n\tconst content = readFileSync(publicPath, \"utf-8\").trim();\n\treturn content || null;\n}\n\n/** Read the private key from disk (with keychain fallback). Returns null if unavailable. */\nexport function loadPrivateKey(keysDir?: string, dbPath?: string): Buffer | null {\n\tif (keyStoreMode() === \"keychain\") {\n\t\tconst deviceId = loadDeviceId(dbPath);\n\t\tif (deviceId) {\n\t\t\tconst keychainValue = loadPrivateKeyKeychain(deviceId);\n\t\t\tif (keychainValue) return keychainValue;\n\t\t}\n\t}\n\tconst [privatePath] = resolveKeyPaths(keysDir);\n\tif (!existsSync(privatePath)) return null;\n\treturn readFileSync(privatePath);\n}\n\n/** Load device_id from the database (for keychain lookups). */\nfunction loadDeviceId(dbPath?: string): string | null {\n\tconst path = resolveDbPath(dbPath);\n\tif (!existsSync(path)) return null;\n\tconst conn = connectDb(path);\n\ttry {\n\t\tconst d = drizzle(conn, { schema });\n\t\tconst row = d\n\t\t\t.select({ device_id: schema.syncDevice.device_id })\n\t\t\t.from(schema.syncDevice)\n\t\t\t.limit(1)\n\t\t\t.get();\n\t\treturn row?.device_id ?? null;\n\t} finally {\n\t\tconn.close();\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Key generation & validation\n// ---------------------------------------------------------------------------\n\nfunction publicKeyLooksValid(publicKey: string): boolean {\n\tconst value = publicKey.trim();\n\treturn (\n\t\tvalue.startsWith(\"ssh-ed25519 \") || value.startsWith(\"ssh-rsa \") || value.startsWith(\"ecdsa-\")\n\t);\n}\n\nfunction backupInvalidKeyFile(path: string, stamp: string): void {\n\tif (!existsSync(path)) return;\n\tconst backupPath = path.replace(/([^/]+)$/, `$1.invalid-${stamp}`);\n\trenameSync(path, backupPath);\n}\n\n/**\n * Generate an Ed25519 keypair using Node's native crypto.\n * Stores private key as PEM (PKCS8), public key as SSH format for compatibility.\n */\nexport function generateKeypair(privatePath: string, publicPath: string): void {\n\tmkdirSync(dirname(privatePath), { recursive: true });\n\tif (existsSync(privatePath) && existsSync(publicPath)) return;\n\n\tif (existsSync(privatePath) && !existsSync(publicPath)) {\n\t\t// Private key exists but public is missing — derive public from private\n\t\ttry {\n\t\t\tconst privKeyObj = loadPrivateKeyObject(privatePath);\n\t\t\tconst pubKeyObj = createPublicKey(privKeyObj);\n\t\t\tconst sshPub = pubKeyObj.export({ type: \"spki\", format: \"der\" });\n\t\t\tconst sshPubStr = derToSshEd25519(sshPub);\n\t\t\tif (sshPubStr && publicKeyLooksValid(sshPubStr)) {\n\t\t\t\twriteFileSync(publicPath, `${sshPubStr}\\n`, { mode: 0o644 });\n\t\t\t\treturn;\n\t\t\t}\n\t\t} catch {\n\t\t\t// Derivation failed — fall through to full regeneration with backup\n\t\t}\n\t\t// Back up the orphaned private key before regenerating\n\t\tconst stamp = new Date().toISOString().replace(/[:.]/g, \"\");\n\t\trenameSync(privatePath, `${privatePath}.orphan-${stamp}`);\n\t}\n\n\tconst { publicKey, privateKey } = generateKeyPairSync(\"ed25519\");\n\n\t// Export private key as PEM (PKCS8)\n\tconst privatePem = privateKey.export({ type: \"pkcs8\", format: \"pem\" }) as string;\n\twriteFileSync(privatePath, privatePem, { mode: 0o600 });\n\n\t// Export public key as SSH wire format: \"ssh-ed25519 <base64>\"\n\tconst pubDer = publicKey.export({ type: \"spki\", format: \"der\" });\n\tconst sshPub = derToSshEd25519(pubDer);\n\tif (!sshPub) {\n\t\tthrow new Error(\"failed to convert public key to SSH format\");\n\t}\n\twriteFileSync(publicPath, `${sshPub}\\n`, { mode: 0o644 });\n}\n\n/**\n * Convert a DER-encoded SPKI Ed25519 public key to SSH wire format.\n * The last 32 bytes of the DER are the raw Ed25519 public key.\n */\nfunction derToSshEd25519(spkiDer: Buffer): string | null {\n\t// Ed25519 SPKI DER is 44 bytes: 12-byte header + 32-byte key\n\tif (spkiDer.length < 32) return null;\n\tconst rawKey = spkiDer.subarray(spkiDer.length - 32);\n\n\t// SSH wire format: string \"ssh-ed25519\" + string <32-byte key>\n\tconst keyType = Buffer.from(\"ssh-ed25519\");\n\tconst buf = Buffer.alloc(4 + keyType.length + 4 + rawKey.length);\n\tlet offset = 0;\n\tbuf.writeUInt32BE(keyType.length, offset);\n\toffset += 4;\n\tkeyType.copy(buf, offset);\n\toffset += keyType.length;\n\tbuf.writeUInt32BE(rawKey.length, offset);\n\toffset += 4;\n\trawKey.copy(buf, offset);\n\n\treturn `ssh-ed25519 ${buf.toString(\"base64\")}`;\n}\n\n/**\n * Load a private key that may be in OpenSSH format (existing keys) or\n * PKCS8 PEM format (newly generated keys). Node's createPrivateKey\n * handles both transparently.\n */\nfunction loadPrivateKeyObject(privatePath: string): ReturnType<typeof createPrivateKey> {\n\tconst raw = readFileSync(privatePath);\n\t// Try PKCS8 PEM first (our generated format), then OpenSSH\n\ttry {\n\t\treturn createPrivateKey(raw);\n\t} catch {\n\t\treturn createPrivateKey({ key: raw, format: \"pem\", type: \"pkcs8\" });\n\t}\n}\n\n/** Validate that an existing keypair is consistent. */\nexport function validateExistingKeypair(privatePath: string, publicPath: string): boolean {\n\tif (!existsSync(privatePath) || !existsSync(publicPath)) return false;\n\tconst publicKey = readFileSync(publicPath, \"utf-8\").trim();\n\tif (!publicKey || !publicKeyLooksValid(publicKey)) return false;\n\ttry {\n\t\tconst privKeyObj = loadPrivateKeyObject(privatePath);\n\t\tconst pubKeyObj = createPublicKey(privKeyObj);\n\t\tconst pubDer = pubKeyObj.export({ type: \"spki\", format: \"der\" });\n\t\tconst derived = derToSshEd25519(pubDer);\n\t\tif (!derived || !publicKeyLooksValid(derived)) return false;\n\t\t// Auto-fix mismatched public key file\n\t\tif (derived !== publicKey) {\n\t\t\twriteFileSync(publicPath, `${derived}\\n`, \"utf-8\");\n\t\t}\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Main entry: ensure device identity\n// ---------------------------------------------------------------------------\n\nexport interface EnsureDeviceIdentityOptions {\n\tkeysDir?: string;\n\tdeviceId?: string;\n}\n\n/**\n * Ensure this device has a keypair and a row in the sync_device table.\n *\n * Returns [deviceId, fingerprint]. Creates keys and DB row if missing,\n * validates and repairs if existing.\n */\nexport function ensureDeviceIdentity(\n\tdb: Database,\n\toptions?: EnsureDeviceIdentityOptions,\n): [string, string] {\n\tconst keysDir = options?.keysDir ?? DEFAULT_KEYS_DIR;\n\tconst [privatePath, publicPath] = resolveKeyPaths(keysDir);\n\twarnKeychainLimitations();\n\n\t// Check for existing device row\n\tconst d = drizzle(db, { schema });\n\tconst row = d\n\t\t.select({\n\t\t\tdevice_id: schema.syncDevice.device_id,\n\t\t\tpublic_key: schema.syncDevice.public_key,\n\t\t\tfingerprint: schema.syncDevice.fingerprint,\n\t\t})\n\t\t.from(schema.syncDevice)\n\t\t.limit(1)\n\t\t.get();\n\tconst existingDeviceId = row?.device_id ?? \"\";\n\tconst existingPublicKey = row?.public_key ?? \"\";\n\tconst existingFingerprint = row?.fingerprint ?? \"\";\n\n\t// Validate or regenerate keys\n\tlet keysReady = existsSync(privatePath) && existsSync(publicPath);\n\tif (keysReady && !validateExistingKeypair(privatePath, publicPath)) {\n\t\tconst stamp = new Date()\n\t\t\t.toISOString()\n\t\t\t.replace(/[-:T.Z]/g, \"\")\n\t\t\t.slice(0, 20);\n\t\tbackupInvalidKeyFile(privatePath, stamp);\n\t\tbackupInvalidKeyFile(publicPath, stamp);\n\t\tkeysReady = false;\n\t}\n\tif (!keysReady) {\n\t\tgenerateKeypair(privatePath, publicPath);\n\t}\n\n\tconst publicKey = readFileSync(publicPath, \"utf-8\").trim();\n\tif (!publicKey) {\n\t\tthrow new Error(\"public key missing\");\n\t}\n\tconst fingerprint = fingerprintPublicKey(publicKey);\n\tconst now = new Date().toISOString();\n\n\t// Update existing device row if keys changed\n\tif (existingDeviceId) {\n\t\tif (existingPublicKey !== publicKey || existingFingerprint !== fingerprint) {\n\t\t\td.update(schema.syncDevice)\n\t\t\t\t.set({ public_key: publicKey, fingerprint })\n\t\t\t\t.where(eq(schema.syncDevice.device_id, existingDeviceId))\n\t\t\t\t.run();\n\t\t}\n\t\tif (keyStoreMode() === \"keychain\") {\n\t\t\t// Read key from file directly — don't go through loadPrivateKey\n\t\t\t// which would resolve device ID from the default DB\n\t\t\tconst privateKey = existsSync(privatePath)\n\t\t\t\t? readFileSync(privatePath)\n\t\t\t\t: loadPrivateKeyKeychain(existingDeviceId);\n\t\t\tif (privateKey) {\n\t\t\t\tstorePrivateKeyKeychain(privateKey, existingDeviceId);\n\t\t\t}\n\t\t}\n\t\treturn [existingDeviceId, fingerprint];\n\t}\n\n\t// Insert new device row\n\tconst resolvedDeviceId = options?.deviceId ?? randomUUID();\n\td.insert(schema.syncDevice)\n\t\t.values({ device_id: resolvedDeviceId, public_key: publicKey, fingerprint, created_at: now })\n\t\t.run();\n\tif (keyStoreMode() === \"keychain\") {\n\t\tconst privateKey = existsSync(privatePath) ? readFileSync(privatePath) : null;\n\t\tif (privateKey) {\n\t\t\tstorePrivateKeyKeychain(privateKey, resolvedDeviceId);\n\t\t}\n\t}\n\treturn [resolvedDeviceId, fingerprint];\n}\n","/**\n * Sync authentication: request signing, verification, and nonce management.\n *\n * Uses Node's native Ed25519 crypto for sign/verify and SHA-256 canonical\n * request hashing. No ssh-keygen shelling.\n */\n\nimport {\n\tcreateHash,\n\tcreatePrivateKey,\n\tcreatePublicKey,\n\trandomBytes,\n\tsign,\n\tverify,\n} from \"node:crypto\";\nimport { lt } from \"drizzle-orm\";\nimport { drizzle } from \"drizzle-orm/better-sqlite3\";\nimport type { Database } from \"./db.js\";\nimport * as schema from \"./schema.js\";\nimport { loadPrivateKey } from \"./sync-identity.js\";\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/**\n * Signature version. v1 = SSHSIG format (ssh-keygen era), v2 = raw Ed25519.\n *\n * v2 is a breaking change: Python peers using `ssh-keygen -Y verify` cannot\n * verify v2 signatures. Once all peers run the TS runtime, v1 support can\n * be removed. During migration, the verifier accepts both versions.\n */\nexport const SIGNATURE_VERSION = \"v2\";\nexport const DEFAULT_TIME_WINDOW_S = 300;\n\n// ---------------------------------------------------------------------------\n// Canonical request\n// ---------------------------------------------------------------------------\n\n/**\n * Build a canonical request buffer for signing/verification.\n *\n * SHA-256 hashes the body, then joins method/path/timestamp/nonce/bodyHash\n * with newlines and returns the UTF-8 encoded result.\n */\nexport function buildCanonicalRequest(\n\tmethod: string,\n\tpathWithQuery: string,\n\ttimestamp: string,\n\tnonce: string,\n\tbodyBytes: Buffer,\n): Buffer {\n\tconst bodyHash = createHash(\"sha256\").update(bodyBytes).digest(\"hex\");\n\tconst canonical = [method.toUpperCase(), pathWithQuery, timestamp, nonce, bodyHash].join(\"\\n\");\n\treturn Buffer.from(canonical, \"utf-8\");\n}\n\n// ---------------------------------------------------------------------------\n// Sign\n// ---------------------------------------------------------------------------\n\nexport interface SignRequestOptions {\n\tmethod: string;\n\turl: string;\n\tbodyBytes: Buffer;\n\tkeysDir?: string;\n\ttimestamp?: string;\n\tnonce?: string;\n}\n\n/**\n * Sign an HTTP request and return the auth headers.\n *\n * Uses Node's native Ed25519 crypto.sign() — no ssh-keygen shelling.\n * Returns X-Opencode-Timestamp, X-Opencode-Nonce, X-Opencode-Signature headers.\n */\nexport function signRequest(options: SignRequestOptions): Record<string, string> {\n\tconst ts = options.timestamp ?? String(Math.floor(Date.now() / 1000));\n\tconst nonceValue = options.nonce ?? randomBytes(16).toString(\"hex\");\n\n\tconst parsed = new URL(options.url);\n\tlet path = parsed.pathname || \"/\";\n\tif (parsed.search) {\n\t\tpath = `${path}${parsed.search}`;\n\t}\n\n\tconst canonical = buildCanonicalRequest(options.method, path, ts, nonceValue, options.bodyBytes);\n\n\tconst keyData = loadPrivateKey(options.keysDir);\n\tif (!keyData) {\n\t\tthrow new Error(\"private key missing\");\n\t}\n\n\t// Handle both OpenSSH format (existing keys) and PKCS8 PEM (newly generated)\n\tlet privateKeyObj: ReturnType<typeof createPrivateKey>;\n\ttry {\n\t\tprivateKeyObj = createPrivateKey(keyData);\n\t} catch {\n\t\tprivateKeyObj = createPrivateKey({ key: keyData, format: \"pem\", type: \"pkcs8\" });\n\t}\n\tconst signatureBytes = sign(null, canonical, privateKeyObj);\n\tconst signature = signatureBytes.toString(\"base64\");\n\n\treturn {\n\t\t\"X-Opencode-Timestamp\": ts,\n\t\t\"X-Opencode-Nonce\": nonceValue,\n\t\t\"X-Opencode-Signature\": `${SIGNATURE_VERSION}:${signature}`,\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Verify\n// ---------------------------------------------------------------------------\n\nexport interface VerifySignatureOptions {\n\tmethod: string;\n\tpathWithQuery: string;\n\tbodyBytes: Buffer;\n\ttimestamp: string;\n\tnonce: string;\n\tsignature: string;\n\tpublicKey: string;\n\tdeviceId: string;\n\ttimeWindowS?: number;\n}\n\n/**\n * Verify a signed request.\n *\n * Checks timestamp freshness, signature version prefix, then uses\n * Node's native crypto.verify() with the sender's Ed25519 public key.\n */\nexport function verifySignature(options: VerifySignatureOptions): boolean {\n\tconst timeWindow = options.timeWindowS ?? DEFAULT_TIME_WINDOW_S;\n\n\t// Parse and validate timestamp — reject non-numeric strings (matches Python's int())\n\tif (!/^\\d+$/.test(options.timestamp)) return false;\n\tconst tsInt = Number.parseInt(options.timestamp, 10);\n\tif (Number.isNaN(tsInt)) return false;\n\n\tconst now = Math.floor(Date.now() / 1000);\n\tif (Math.abs(now - tsInt) > timeWindow) return false;\n\n\t// Validate signature version prefix — accept both v1 and v2 during migration\n\tconst ACCEPTED_VERSIONS = [\"v1\", \"v2\"];\n\tconst colonIdx = options.signature.indexOf(\":\");\n\tif (colonIdx < 1) return false;\n\tconst sigVersion = options.signature.slice(0, colonIdx);\n\tif (!ACCEPTED_VERSIONS.includes(sigVersion)) return false;\n\n\tconst encoded = options.signature.slice(colonIdx + 1);\n\tif (!encoded) return false;\n\n\tlet signatureBytes: Buffer;\n\ttry {\n\t\tsignatureBytes = Buffer.from(encoded, \"base64\");\n\t\t// Verify it was valid base64 by round-tripping\n\t\tif (signatureBytes.toString(\"base64\") !== encoded) return false;\n\t} catch {\n\t\treturn false;\n\t}\n\n\tconst canonical = buildCanonicalRequest(\n\t\toptions.method,\n\t\toptions.pathWithQuery,\n\t\toptions.timestamp,\n\t\toptions.nonce,\n\t\toptions.bodyBytes,\n\t);\n\n\ttry {\n\t\tconst publicKeyObj = sshEd25519ToPublicKey(options.publicKey);\n\t\treturn verify(null, canonical, publicKeyObj, signatureBytes);\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Parse an SSH ed25519 public key string into a Node crypto KeyObject.\n *\n * SSH format: \"ssh-ed25519 <base64-wire-format>\"\n * Wire format: uint32 key-type-len + key-type + uint32 key-data-len + key-data\n */\nfunction sshEd25519ToPublicKey(sshPub: string): ReturnType<typeof createPublicKey> {\n\tconst parts = sshPub.trim().split(/\\s+/);\n\tif (parts.length < 2 || parts[0] !== \"ssh-ed25519\") {\n\t\tthrow new Error(\"not an ssh-ed25519 key\");\n\t}\n\tconst wireFormat = Buffer.from(parts[1]!, \"base64\");\n\n\t// Read key type length\n\tif (wireFormat.length < 4) throw new Error(\"truncated wire format\");\n\tconst typeLen = wireFormat.readUInt32BE(0);\n\tconst typeEnd = 4 + typeLen;\n\tif (wireFormat.length < typeEnd + 4) throw new Error(\"truncated wire format\");\n\n\t// Read key data length\n\tconst keyLen = wireFormat.readUInt32BE(typeEnd);\n\tconst keyStart = typeEnd + 4;\n\tif (wireFormat.length < keyStart + keyLen) throw new Error(\"truncated wire format\");\n\tconst rawKey = wireFormat.subarray(keyStart, keyStart + keyLen);\n\n\tif (rawKey.length !== 32) throw new Error(`unexpected Ed25519 key length: ${rawKey.length}`);\n\n\t// Wrap raw 32-byte key in SPKI DER: 12-byte Ed25519 header + 32-byte key\n\tconst ed25519SpkiPrefix = Buffer.from(\"302a300506032b6570032100\", \"hex\");\n\tconst spkiDer = Buffer.concat([ed25519SpkiPrefix, rawKey]);\n\n\treturn createPublicKey({ key: spkiDer, format: \"der\", type: \"spki\" });\n}\n\n// ---------------------------------------------------------------------------\n// Auth headers (convenience)\n// ---------------------------------------------------------------------------\n\nexport interface BuildAuthHeadersOptions {\n\tdeviceId: string;\n\tmethod: string;\n\turl: string;\n\tbodyBytes: Buffer;\n\tkeysDir?: string;\n\ttimestamp?: string;\n\tnonce?: string;\n}\n\n/**\n * Build full auth headers including device ID and request signature.\n */\nexport function buildAuthHeaders(options: BuildAuthHeadersOptions): Record<string, string> {\n\treturn {\n\t\t\"X-Opencode-Device\": options.deviceId,\n\t\t...signRequest({\n\t\t\tmethod: options.method,\n\t\t\turl: options.url,\n\t\t\tbodyBytes: options.bodyBytes,\n\t\t\tkeysDir: options.keysDir,\n\t\t\ttimestamp: options.timestamp,\n\t\t\tnonce: options.nonce,\n\t\t}),\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Nonce management\n// ---------------------------------------------------------------------------\n\n/**\n * Record a nonce to prevent replay attacks.\n *\n * Returns true on success, false if the nonce was already recorded\n * (duplicate = potential replay).\n */\nexport function recordNonce(\n\tdb: Database,\n\tdeviceId: string,\n\tnonce: string,\n\tcreatedAt: string,\n): boolean {\n\tconst d = drizzle(db, { schema });\n\ttry {\n\t\td.insert(schema.syncNonces).values({ nonce, device_id: deviceId, created_at: createdAt }).run();\n\t\treturn true;\n\t} catch (err: unknown) {\n\t\tif (err instanceof Error && err.message.includes(\"UNIQUE constraint failed\")) {\n\t\t\treturn false;\n\t\t}\n\t\tthrow err;\n\t}\n}\n\n/**\n * Remove nonces older than the given cutoff timestamp.\n */\nexport function cleanupNonces(db: Database, cutoff: string): void {\n\tconst d = drizzle(db, { schema });\n\td.delete(schema.syncNonces).where(lt(schema.syncNonces.created_at, cutoff)).run();\n}\n","/**\n * Coordinator API — Hono-based HTTP server for the coordinator relay.\n *\n * Manages device enrollment, presence, invites, and join requests.\n * Ported from codemem/coordinator_api.py.\n */\n\nimport type { Context } from \"hono\";\nimport { Hono } from \"hono\";\nimport type { InvitePayload } from \"./coordinator-invites.js\";\nimport { encodeInvitePayload, inviteLink } from \"./coordinator-invites.js\";\nimport type { CoordinatorEnrollment, CoordinatorStore } from \"./coordinator-store-contract.js\";\nimport { DEFAULT_TIME_WINDOW_S, verifySignature } from \"./sync-auth.js\";\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst MAX_BODY_BYTES = 64 * 1024;\nconst ADMIN_HEADER = \"X-Codemem-Coordinator-Admin\";\n\nexport interface CoordinatorRuntimeDeps {\n\tadminSecret(): string | null;\n\tnow(): string;\n}\n\nexport interface CreateCoordinatorAppOptions {\n\tstoreFactory?: () => CoordinatorStore;\n\truntime?: CoordinatorRuntimeDeps;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction defaultAdminSecret(): string | null {\n\tconst value = (process.env.CODEMEM_SYNC_COORDINATOR_ADMIN_SECRET ?? \"\").trim();\n\treturn value || null;\n}\n\nfunction authorizeAdmin(\n\theaderValue: string | null | undefined,\n\truntime: CoordinatorRuntimeDeps,\n): { ok: boolean; error: string } {\n\tconst expected = runtime.adminSecret();\n\tif (!expected) return { ok: false, error: \"admin_not_configured\" };\n\tconst provided = (headerValue ?? \"\").trim();\n\tif (!provided) return { ok: false, error: \"missing_admin_header\" };\n\tif (provided !== expected) return { ok: false, error: \"invalid_admin_secret\" };\n\treturn { ok: true, error: \"ok\" };\n}\n\n/** Extract path + query string from a full URL for signature verification. */\nfunction pathWithQuery(url: string): string {\n\tconst parsed = new URL(url);\n\treturn parsed.search ? `${parsed.pathname}${parsed.search}` : parsed.pathname;\n}\n\nasync function recordNonce(\n\tstore: CoordinatorStore,\n\tdeviceId: string,\n\tnonce: string,\n\tcreatedAt: string,\n): Promise<boolean> {\n\treturn await store.recordNonce(deviceId, nonce, createdAt);\n}\n\nasync function cleanupNonces(store: CoordinatorStore, cutoff: string): Promise<void> {\n\tawait store.cleanupNonces(cutoff);\n}\n\ninterface AuthResult {\n\tok: boolean;\n\terror: string;\n\tenrollment: CoordinatorEnrollment | null;\n}\n\nasync function authorizeRequest(\n\tstore: CoordinatorStore,\n\truntime: CoordinatorRuntimeDeps,\n\topts: {\n\t\tmethod: string;\n\t\turl: string;\n\t\tgroupId: string;\n\t\tbody: Buffer;\n\t\tdeviceId: string | null;\n\t\tsignature: string | null;\n\t\ttimestamp: string | null;\n\t\tnonce: string | null;\n\t},\n): Promise<AuthResult> {\n\tconst { deviceId, signature, timestamp, nonce } = opts;\n\tif (!deviceId || !signature || !timestamp || !nonce) {\n\t\treturn { ok: false, error: \"missing_headers\", enrollment: null };\n\t}\n\n\tconst enrollment = await store.getEnrollment(opts.groupId, deviceId);\n\tif (!enrollment) {\n\t\treturn { ok: false, error: \"unknown_device\", enrollment: null };\n\t}\n\n\tlet valid: boolean;\n\ttry {\n\t\tvalid = verifySignature({\n\t\t\tmethod: opts.method,\n\t\t\tpathWithQuery: pathWithQuery(opts.url),\n\t\t\tbodyBytes: opts.body,\n\t\t\ttimestamp,\n\t\t\tnonce,\n\t\t\tsignature,\n\t\t\tpublicKey: String(enrollment.public_key),\n\t\t\tdeviceId,\n\t\t});\n\t} catch {\n\t\treturn { ok: false, error: \"signature_verification_error\", enrollment: null };\n\t}\n\n\tif (!valid) {\n\t\treturn { ok: false, error: \"invalid_signature\", enrollment: null };\n\t}\n\n\tconst createdAt = runtime.now();\n\tif (!(await recordNonce(store, deviceId, nonce, createdAt))) {\n\t\treturn { ok: false, error: \"nonce_replay\", enrollment: null };\n\t}\n\n\tconst cutoff = new Date(\n\t\tnew Date(createdAt).getTime() - DEFAULT_TIME_WINDOW_S * 2 * 1000,\n\t).toISOString();\n\tawait cleanupNonces(store, cutoff);\n\n\treturn { ok: true, error: \"ok\", enrollment };\n}\n\n// ---------------------------------------------------------------------------\n// App factory\n// ---------------------------------------------------------------------------\n\nexport function createCoordinatorApp(\n\topts?: CreateCoordinatorAppOptions,\n): InstanceType<typeof Hono> {\n\tconst runtime: CoordinatorRuntimeDeps = opts?.runtime ?? {\n\t\tadminSecret: defaultAdminSecret,\n\t\tnow: () => new Date().toISOString(),\n\t};\n\tif (!opts?.storeFactory) {\n\t\tthrow new Error(\"createCoordinatorApp requires a storeFactory.\");\n\t}\n\tconst createStore = opts.storeFactory;\n\tconst app = new Hono();\n\n\t// -----------------------------------------------------------------------\n\t// POST /v1/presence — upsert device presence (authenticated)\n\t// -----------------------------------------------------------------------\n\n\tapp.post(\"/v1/presence\", async (c) => {\n\t\tconst raw = Buffer.from(await c.req.arrayBuffer());\n\t\tif (raw.length > MAX_BODY_BYTES) {\n\t\t\treturn c.json({ error: \"body_too_large\" }, 413);\n\t\t}\n\n\t\tlet data: Record<string, unknown>;\n\t\ttry {\n\t\t\tdata = JSON.parse(raw.toString(\"utf-8\"));\n\t\t\tif (typeof data !== \"object\" || data === null || Array.isArray(data)) {\n\t\t\t\treturn c.json({ error: \"invalid_json\" }, 400);\n\t\t\t}\n\t\t} catch {\n\t\t\treturn c.json({ error: \"invalid_json\" }, 400);\n\t\t}\n\n\t\tconst groupId = String(data.group_id ?? \"\").trim();\n\t\tif (!groupId) {\n\t\t\treturn c.json({ error: \"group_id_required\" }, 400);\n\t\t}\n\n\t\tconst store = createStore();\n\t\ttry {\n\t\t\tconst auth = await authorizeRequest(store, runtime, {\n\t\t\t\tmethod: c.req.method,\n\t\t\t\turl: c.req.url,\n\t\t\t\tgroupId,\n\t\t\t\tbody: raw,\n\t\t\t\tdeviceId: c.req.header(\"X-Opencode-Device\") ?? null,\n\t\t\t\tsignature: c.req.header(\"X-Opencode-Signature\") ?? null,\n\t\t\t\ttimestamp: c.req.header(\"X-Opencode-Timestamp\") ?? null,\n\t\t\t\tnonce: c.req.header(\"X-Opencode-Nonce\") ?? null,\n\t\t\t});\n\t\t\tif (!auth.ok || !auth.enrollment) {\n\t\t\t\treturn c.json({ error: auth.error }, 401);\n\t\t\t}\n\n\t\t\tif (data.fingerprint && String(data.fingerprint) !== String(auth.enrollment.fingerprint)) {\n\t\t\t\treturn c.json({ error: \"fingerprint_mismatch\" }, 401);\n\t\t\t}\n\n\t\t\tconst rawAddresses = data.addresses ?? [];\n\t\t\tif (!Array.isArray(rawAddresses) || !rawAddresses.every((item) => typeof item === \"string\")) {\n\t\t\t\treturn c.json({ error: \"addresses_must_be_list_of_strings\" }, 400);\n\t\t\t}\n\n\t\t\tlet ttlS: number;\n\t\t\ttry {\n\t\t\t\tttlS = Math.max(1, Number.parseInt(String(data.ttl_s ?? 180), 10));\n\t\t\t\tif (Number.isNaN(ttlS)) {\n\t\t\t\t\treturn c.json({ error: \"ttl_s_must_be_int\" }, 400);\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\treturn c.json({ error: \"ttl_s_must_be_int\" }, 400);\n\t\t\t}\n\n\t\t\tconst response = await store.upsertPresence({\n\t\t\t\tgroupId,\n\t\t\t\tdeviceId: String(auth.enrollment.device_id),\n\t\t\t\taddresses: rawAddresses as string[],\n\t\t\t\tttlS,\n\t\t\t\tcapabilities:\n\t\t\t\t\ttypeof data.capabilities === \"object\" &&\n\t\t\t\t\tdata.capabilities !== null &&\n\t\t\t\t\t!Array.isArray(data.capabilities)\n\t\t\t\t\t\t? (data.capabilities as Record<string, unknown>)\n\t\t\t\t\t\t: undefined,\n\t\t\t});\n\n\t\t\treturn c.json({ ok: true, ...response });\n\t\t} finally {\n\t\t\tawait store.close();\n\t\t}\n\t});\n\n\t// -----------------------------------------------------------------------\n\t// GET /v1/peers — list group peers (authenticated)\n\t// -----------------------------------------------------------------------\n\n\tapp.get(\"/v1/peers\", async (c) => {\n\t\tconst groupId = (c.req.query(\"group_id\") ?? \"\").trim();\n\t\tif (!groupId) {\n\t\t\treturn c.json({ error: \"group_id_required\" }, 400);\n\t\t}\n\n\t\tconst store = createStore();\n\t\ttry {\n\t\t\tconst auth = await authorizeRequest(store, runtime, {\n\t\t\t\tmethod: c.req.method,\n\t\t\t\turl: c.req.url,\n\t\t\t\tgroupId,\n\t\t\t\tbody: Buffer.alloc(0),\n\t\t\t\tdeviceId: c.req.header(\"X-Opencode-Device\") ?? null,\n\t\t\t\tsignature: c.req.header(\"X-Opencode-Signature\") ?? null,\n\t\t\t\ttimestamp: c.req.header(\"X-Opencode-Timestamp\") ?? null,\n\t\t\t\tnonce: c.req.header(\"X-Opencode-Nonce\") ?? null,\n\t\t\t});\n\t\t\tif (!auth.ok || !auth.enrollment) {\n\t\t\t\treturn c.json({ error: auth.error }, 401);\n\t\t\t}\n\n\t\t\tconst items = await store.listGroupPeers(groupId, String(auth.enrollment.device_id));\n\t\t\treturn c.json({ items });\n\t\t} finally {\n\t\t\tawait store.close();\n\t\t}\n\t});\n\n\t// -----------------------------------------------------------------------\n\t// GET /v1/reciprocal-approvals — list pending local approval state\n\t// -----------------------------------------------------------------------\n\n\tapp.get(\"/v1/reciprocal-approvals\", async (c) => {\n\t\tconst groupId = (c.req.query(\"group_id\") ?? \"\").trim();\n\t\tconst direction = (c.req.query(\"direction\") ?? \"incoming\").trim();\n\t\tconst status = (c.req.query(\"status\") ?? \"pending\").trim() || \"pending\";\n\t\tif (!groupId) {\n\t\t\treturn c.json({ error: \"group_id_required\" }, 400);\n\t\t}\n\t\tif (![\"incoming\", \"outgoing\"].includes(direction)) {\n\t\t\treturn c.json({ error: \"direction_must_be_incoming_or_outgoing\" }, 400);\n\t\t}\n\n\t\tconst store = createStore();\n\t\ttry {\n\t\t\tconst auth = await authorizeRequest(store, runtime, {\n\t\t\t\tmethod: c.req.method,\n\t\t\t\turl: c.req.url,\n\t\t\t\tgroupId,\n\t\t\t\tbody: Buffer.alloc(0),\n\t\t\t\tdeviceId: c.req.header(\"X-Opencode-Device\") ?? null,\n\t\t\t\tsignature: c.req.header(\"X-Opencode-Signature\") ?? null,\n\t\t\t\ttimestamp: c.req.header(\"X-Opencode-Timestamp\") ?? null,\n\t\t\t\tnonce: c.req.header(\"X-Opencode-Nonce\") ?? null,\n\t\t\t});\n\t\t\tif (!auth.ok || !auth.enrollment) {\n\t\t\t\treturn c.json({ error: auth.error }, 401);\n\t\t\t}\n\t\t\tconst items = await store.listReciprocalApprovals({\n\t\t\t\tgroupId,\n\t\t\t\tdeviceId: String(auth.enrollment.device_id),\n\t\t\t\tdirection: direction as \"incoming\" | \"outgoing\",\n\t\t\t\tstatus,\n\t\t\t});\n\t\t\treturn c.json({ items });\n\t\t} finally {\n\t\t\tawait store.close();\n\t\t}\n\t});\n\n\t// -----------------------------------------------------------------------\n\t// POST /v1/reciprocal-approvals — register a local trust action\n\t// -----------------------------------------------------------------------\n\n\tapp.post(\"/v1/reciprocal-approvals\", async (c) => {\n\t\tconst raw = Buffer.from(await c.req.arrayBuffer());\n\t\tif (raw.length > MAX_BODY_BYTES) {\n\t\t\treturn c.json({ error: \"body_too_large\" }, 413);\n\t\t}\n\n\t\tlet data: Record<string, unknown>;\n\t\ttry {\n\t\t\tdata = JSON.parse(raw.toString(\"utf-8\"));\n\t\t\tif (typeof data !== \"object\" || data === null || Array.isArray(data)) {\n\t\t\t\treturn c.json({ error: \"invalid_json\" }, 400);\n\t\t\t}\n\t\t} catch {\n\t\t\treturn c.json({ error: \"invalid_json\" }, 400);\n\t\t}\n\n\t\tconst groupId = String(data.group_id ?? \"\").trim();\n\t\tconst requestedDeviceId = String(data.requested_device_id ?? \"\").trim();\n\t\tif (!groupId || !requestedDeviceId) {\n\t\t\treturn c.json({ error: \"group_id_and_requested_device_id_required\" }, 400);\n\t\t}\n\n\t\tconst store = createStore();\n\t\ttry {\n\t\t\tconst auth = await authorizeRequest(store, runtime, {\n\t\t\t\tmethod: c.req.method,\n\t\t\t\turl: c.req.url,\n\t\t\t\tgroupId,\n\t\t\t\tbody: raw,\n\t\t\t\tdeviceId: c.req.header(\"X-Opencode-Device\") ?? null,\n\t\t\t\tsignature: c.req.header(\"X-Opencode-Signature\") ?? null,\n\t\t\t\ttimestamp: c.req.header(\"X-Opencode-Timestamp\") ?? null,\n\t\t\t\tnonce: c.req.header(\"X-Opencode-Nonce\") ?? null,\n\t\t\t});\n\t\t\tif (!auth.ok || !auth.enrollment) {\n\t\t\t\treturn c.json({ error: auth.error }, 401);\n\t\t\t}\n\t\t\tif (requestedDeviceId === String(auth.enrollment.device_id)) {\n\t\t\t\treturn c.json({ error: \"requested_device_must_differ\" }, 400);\n\t\t\t}\n\t\t\tconst targetEnrollment = await store.getEnrollment(groupId, requestedDeviceId);\n\t\t\tif (!targetEnrollment) {\n\t\t\t\treturn c.json({ error: \"requested_device_not_found\" }, 404);\n\t\t\t}\n\t\t\tconst request = await store.createReciprocalApproval({\n\t\t\t\tgroupId,\n\t\t\t\trequestingDeviceId: String(auth.enrollment.device_id),\n\t\t\t\trequestedDeviceId,\n\t\t\t});\n\t\t\treturn c.json({ ok: true, request });\n\t\t} finally {\n\t\t\tawait store.close();\n\t\t}\n\t});\n\n\t// -----------------------------------------------------------------------\n\t// Admin routes\n\t// -----------------------------------------------------------------------\n\n\t// POST /v1/admin/devices — enroll a device\n\tapp.post(\"/v1/admin/devices\", async (c) => {\n\t\tconst adminAuth = authorizeAdmin(c.req.header(ADMIN_HEADER), runtime);\n\t\tif (!adminAuth.ok) return c.json({ error: adminAuth.error }, 401);\n\n\t\tconst raw = Buffer.from(await c.req.arrayBuffer());\n\t\tif (raw.length > MAX_BODY_BYTES) return c.json({ error: \"body_too_large\" }, 413);\n\n\t\tlet data: Record<string, unknown>;\n\t\ttry {\n\t\t\tdata = JSON.parse(raw.toString(\"utf-8\"));\n\t\t\tif (typeof data !== \"object\" || data === null || Array.isArray(data)) {\n\t\t\t\treturn c.json({ error: \"invalid_json\" }, 400);\n\t\t\t}\n\t\t} catch {\n\t\t\treturn c.json({ error: \"invalid_json\" }, 400);\n\t\t}\n\n\t\tconst groupId = String(data.group_id ?? \"\").trim();\n\t\tconst deviceId = String(data.device_id ?? \"\").trim();\n\t\tconst fingerprint = String(data.fingerprint ?? \"\").trim();\n\t\tconst publicKey = String(data.public_key ?? \"\").trim();\n\t\tconst displayName = String(data.display_name ?? \"\").trim() || null;\n\n\t\tif (!groupId || !deviceId || !fingerprint || !publicKey) {\n\t\t\treturn c.json({ error: \"group_id_device_id_fingerprint_public_key_required\" }, 400);\n\t\t}\n\n\t\tconst store = createStore();\n\t\ttry {\n\t\t\tawait store.createGroup(groupId);\n\t\t\tawait store.enrollDevice(groupId, {\n\t\t\t\tdeviceId,\n\t\t\t\tfingerprint,\n\t\t\t\tpublicKey,\n\t\t\t\tdisplayName,\n\t\t\t});\n\t\t} finally {\n\t\t\tawait store.close();\n\t\t}\n\n\t\treturn c.json({ ok: true });\n\t});\n\n\t// GET /v1/admin/devices — list enrolled devices\n\tapp.get(\"/v1/admin/devices\", async (c) => {\n\t\tconst adminAuth = authorizeAdmin(c.req.header(ADMIN_HEADER), runtime);\n\t\tif (!adminAuth.ok) return c.json({ error: adminAuth.error }, 401);\n\n\t\tconst groupId = (c.req.query(\"group_id\") ?? \"\").trim();\n\t\tif (!groupId) return c.json({ error: \"group_id_required\" }, 400);\n\n\t\tconst includeDisabled = [\"1\", \"true\", \"yes\"].includes(\n\t\t\t(c.req.query(\"include_disabled\") ?? \"0\").trim().toLowerCase(),\n\t\t);\n\n\t\tconst store = createStore();\n\t\ttry {\n\t\t\treturn c.json({ items: await store.listEnrolledDevices(groupId, includeDisabled) });\n\t\t} finally {\n\t\t\tawait store.close();\n\t\t}\n\t});\n\n\t// POST /v1/admin/devices/rename\n\tapp.post(\"/v1/admin/devices/rename\", async (c) => {\n\t\tconst adminAuth = authorizeAdmin(c.req.header(ADMIN_HEADER), runtime);\n\t\tif (!adminAuth.ok) return c.json({ error: adminAuth.error }, 401);\n\n\t\tconst raw = Buffer.from(await c.req.arrayBuffer());\n\t\tif (raw.length > MAX_BODY_BYTES) return c.json({ error: \"body_too_large\" }, 413);\n\n\t\tlet data: Record<string, unknown>;\n\t\ttry {\n\t\t\tdata = JSON.parse(raw.toString(\"utf-8\"));\n\t\t\tif (typeof data !== \"object\" || data === null || Array.isArray(data)) {\n\t\t\t\treturn c.json({ error: \"invalid_json\" }, 400);\n\t\t\t}\n\t\t} catch {\n\t\t\treturn c.json({ error: \"invalid_json\" }, 400);\n\t\t}\n\n\t\tconst groupId = String(data.group_id ?? \"\").trim();\n\t\tconst deviceId = String(data.device_id ?? \"\").trim();\n\t\tconst displayName = String(data.display_name ?? \"\").trim();\n\n\t\tif (!groupId || !deviceId) {\n\t\t\treturn c.json({ error: \"group_id_and_device_id_required\" }, 400);\n\t\t}\n\t\tif (!displayName) {\n\t\t\treturn c.json({ error: \"display_name_required\" }, 400);\n\t\t}\n\n\t\tconst store = createStore();\n\t\ttry {\n\t\t\tconst ok = await store.renameDevice(groupId, deviceId, displayName);\n\t\t\tif (!ok) return c.json({ error: \"device_not_found\" }, 404);\n\t\t\treturn c.json({ ok: true });\n\t\t} finally {\n\t\t\tawait store.close();\n\t\t}\n\t});\n\n\t// POST /v1/admin/devices/disable\n\tapp.post(\"/v1/admin/devices/disable\", async (c) => {\n\t\tconst adminAuth = authorizeAdmin(c.req.header(ADMIN_HEADER), runtime);\n\t\tif (!adminAuth.ok) return c.json({ error: adminAuth.error }, 401);\n\n\t\tconst raw = Buffer.from(await c.req.arrayBuffer());\n\t\tif (raw.length > MAX_BODY_BYTES) return c.json({ error: \"body_too_large\" }, 413);\n\n\t\tlet data: Record<string, unknown>;\n\t\ttry {\n\t\t\tdata = JSON.parse(raw.toString(\"utf-8\"));\n\t\t\tif (typeof data !== \"object\" || data === null || Array.isArray(data)) {\n\t\t\t\treturn c.json({ error: \"invalid_json\" }, 400);\n\t\t\t}\n\t\t} catch {\n\t\t\treturn c.json({ error: \"invalid_json\" }, 400);\n\t\t}\n\n\t\tconst groupId = String(data.group_id ?? \"\").trim();\n\t\tconst deviceId = String(data.device_id ?? \"\").trim();\n\n\t\tif (!groupId || !deviceId) {\n\t\t\treturn c.json({ error: \"group_id_and_device_id_required\" }, 400);\n\t\t}\n\n\t\tconst store = createStore();\n\t\ttry {\n\t\t\tconst ok = await store.setDeviceEnabled(groupId, deviceId, false);\n\t\t\tif (!ok) return c.json({ error: \"device_not_found\" }, 404);\n\t\t\treturn c.json({ ok: true });\n\t\t} finally {\n\t\t\tawait store.close();\n\t\t}\n\t});\n\n\t// POST /v1/admin/devices/remove\n\tapp.post(\"/v1/admin/devices/remove\", async (c) => {\n\t\tconst adminAuth = authorizeAdmin(c.req.header(ADMIN_HEADER), runtime);\n\t\tif (!adminAuth.ok) return c.json({ error: adminAuth.error }, 401);\n\n\t\tconst raw = Buffer.from(await c.req.arrayBuffer());\n\t\tif (raw.length > MAX_BODY_BYTES) return c.json({ error: \"body_too_large\" }, 413);\n\n\t\tlet data: Record<string, unknown>;\n\t\ttry {\n\t\t\tdata = JSON.parse(raw.toString(\"utf-8\"));\n\t\t\tif (typeof data !== \"object\" || data === null || Array.isArray(data)) {\n\t\t\t\treturn c.json({ error: \"invalid_json\" }, 400);\n\t\t\t}\n\t\t} catch {\n\t\t\treturn c.json({ error: \"invalid_json\" }, 400);\n\t\t}\n\n\t\tconst groupId = String(data.group_id ?? \"\").trim();\n\t\tconst deviceId = String(data.device_id ?? \"\").trim();\n\n\t\tif (!groupId || !deviceId) {\n\t\t\treturn c.json({ error: \"group_id_and_device_id_required\" }, 400);\n\t\t}\n\n\t\tconst store = createStore();\n\t\ttry {\n\t\t\tconst ok = await store.removeDevice(groupId, deviceId);\n\t\t\tif (!ok) return c.json({ error: \"device_not_found\" }, 404);\n\t\t\treturn c.json({ ok: true });\n\t\t} finally {\n\t\t\tawait store.close();\n\t\t}\n\t});\n\n\t// POST /v1/admin/invites — create an invite\n\tapp.post(\"/v1/admin/invites\", async (c) => {\n\t\tconst adminAuth = authorizeAdmin(c.req.header(ADMIN_HEADER), runtime);\n\t\tif (!adminAuth.ok) return c.json({ error: adminAuth.error }, 401);\n\n\t\tconst raw = Buffer.from(await c.req.arrayBuffer());\n\t\tif (raw.length > MAX_BODY_BYTES) return c.json({ error: \"body_too_large\" }, 413);\n\n\t\tlet data: Record<string, unknown>;\n\t\ttry {\n\t\t\tdata = JSON.parse(raw.toString(\"utf-8\"));\n\t\t\tif (typeof data !== \"object\" || data === null || Array.isArray(data)) {\n\t\t\t\treturn c.json({ error: \"invalid_json\" }, 400);\n\t\t\t}\n\t\t} catch {\n\t\t\treturn c.json({ error: \"invalid_json\" }, 400);\n\t\t}\n\n\t\tconst groupId = String(data.group_id ?? \"\").trim();\n\t\tconst policy = String(data.policy ?? \"auto_admit\").trim();\n\t\tconst expiresAt = String(data.expires_at ?? \"\").trim();\n\t\tconst createdBy = String(data.created_by ?? \"\").trim() || null;\n\n\t\tif (!groupId || ![\"auto_admit\", \"approval_required\"].includes(policy) || !expiresAt) {\n\t\t\treturn c.json({ error: \"group_id_policy_and_expires_at_required\" }, 400);\n\t\t}\n\n\t\tconst store = createStore();\n\t\ttry {\n\t\t\tconst group = await store.getGroup(groupId);\n\t\t\tif (!group) return c.json({ error: \"group_not_found\" }, 404);\n\n\t\t\tconst invite = await store.createInvite({\n\t\t\t\tgroupId,\n\t\t\t\tpolicy,\n\t\t\t\texpiresAt,\n\t\t\t\tcreatedBy,\n\t\t\t});\n\n\t\t\tconst payload: InvitePayload = {\n\t\t\t\tv: 1,\n\t\t\t\tkind: \"coordinator_team_invite\",\n\t\t\t\tcoordinator_url: String(data.coordinator_url ?? \"\").trim(),\n\t\t\t\tgroup_id: groupId,\n\t\t\t\tpolicy,\n\t\t\t\ttoken: String(invite.token ?? \"\"),\n\t\t\t\texpires_at: expiresAt,\n\t\t\t\tteam_name: (invite.team_name_snapshot as string) ?? null,\n\t\t\t};\n\t\t\tconst encoded = encodeInvitePayload(payload);\n\n\t\t\t// Omit token from the returned invite object (matches Python)\n\t\t\tconst { token: _token, ...inviteWithoutToken } = invite;\n\n\t\t\treturn c.json({\n\t\t\t\tok: true,\n\t\t\t\tinvite: inviteWithoutToken,\n\t\t\t\tpayload,\n\t\t\t\tencoded,\n\t\t\t\tlink: inviteLink(encoded),\n\t\t\t});\n\t\t} finally {\n\t\t\tawait store.close();\n\t\t}\n\t});\n\n\t// GET /v1/admin/invites — list invites\n\tapp.get(\"/v1/admin/invites\", async (c) => {\n\t\tconst adminAuth = authorizeAdmin(c.req.header(ADMIN_HEADER), runtime);\n\t\tif (!adminAuth.ok) return c.json({ error: adminAuth.error }, 401);\n\n\t\tconst groupId = (c.req.query(\"group_id\") ?? \"\").trim();\n\t\tif (!groupId) return c.json({ error: \"group_id_required\" }, 400);\n\n\t\tconst store = createStore();\n\t\ttry {\n\t\t\tconst rows = (await store.listInvites(groupId)).map(\n\t\t\t\t({ token: _token, ...inviteWithoutToken }) => inviteWithoutToken,\n\t\t\t);\n\t\t\treturn c.json({ items: rows });\n\t\t} finally {\n\t\t\tawait store.close();\n\t\t}\n\t});\n\n\t// POST /v1/admin/join-requests/approve\n\tapp.post(\"/v1/admin/join-requests/approve\", async (c) => {\n\t\treturn handleJoinRequestReview(c, true, { createStore, runtime });\n\t});\n\n\t// POST /v1/admin/join-requests/deny\n\tapp.post(\"/v1/admin/join-requests/deny\", async (c) => {\n\t\treturn handleJoinRequestReview(c, false, { createStore, runtime });\n\t});\n\n\t// GET /v1/admin/join-requests — list join requests\n\tapp.get(\"/v1/admin/join-requests\", async (c) => {\n\t\tconst adminAuth = authorizeAdmin(c.req.header(ADMIN_HEADER), runtime);\n\t\tif (!adminAuth.ok) return c.json({ error: adminAuth.error }, 401);\n\n\t\tconst groupId = (c.req.query(\"group_id\") ?? \"\").trim();\n\t\tif (!groupId) return c.json({ error: \"group_id_required\" }, 400);\n\n\t\tconst store = createStore();\n\t\ttry {\n\t\t\treturn c.json({ items: await store.listJoinRequests(groupId) });\n\t\t} finally {\n\t\t\tawait store.close();\n\t\t}\n\t});\n\n\t// -----------------------------------------------------------------------\n\t// POST /v1/join — join via invite token (unauthenticated)\n\t// -----------------------------------------------------------------------\n\n\tapp.post(\"/v1/join\", async (c) => {\n\t\tconst raw = Buffer.from(await c.req.arrayBuffer());\n\t\tif (raw.length > MAX_BODY_BYTES) return c.json({ error: \"body_too_large\" }, 413);\n\n\t\tlet data: Record<string, unknown>;\n\t\ttry {\n\t\t\tdata = JSON.parse(raw.toString(\"utf-8\"));\n\t\t\tif (typeof data !== \"object\" || data === null || Array.isArray(data)) {\n\t\t\t\treturn c.json({ error: \"invalid_json\" }, 400);\n\t\t\t}\n\t\t} catch {\n\t\t\treturn c.json({ error: \"invalid_json\" }, 400);\n\t\t}\n\n\t\tconst token = String(data.token ?? \"\").trim();\n\t\tconst deviceId = String(data.device_id ?? \"\").trim();\n\t\tconst fingerprint = String(data.fingerprint ?? \"\").trim();\n\t\tconst publicKey = String(data.public_key ?? \"\").trim();\n\t\tconst displayName = String(data.display_name ?? \"\").trim() || null;\n\n\t\tif (!token || !deviceId || !fingerprint || !publicKey) {\n\t\t\treturn c.json({ error: \"token_device_id_fingerprint_public_key_required\" }, 400);\n\t\t}\n\n\t\tconst store = createStore();\n\t\ttry {\n\t\t\tconst invite = await store.getInviteByToken(token);\n\t\t\tif (!invite) return c.json({ error: \"invalid_token\" }, 404);\n\n\t\t\tif (invite.revoked_at) return c.json({ error: \"revoked_token\" }, 400);\n\n\t\t\tconst expiresAtStr = String(invite.expires_at ?? \"\");\n\t\t\tif (expiresAtStr) {\n\t\t\t\tconst expiresAt = new Date(expiresAtStr.replace(\"Z\", \"+00:00\"));\n\t\t\t\tif (expiresAt <= new Date(runtime.now())) {\n\t\t\t\t\treturn c.json({ error: \"expired_token\" }, 400);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst inviteGroupId = String(invite.group_id);\n\t\t\tconst existing = await store.getEnrollment(inviteGroupId, deviceId);\n\t\t\tif (existing) {\n\t\t\t\treturn c.json({\n\t\t\t\t\tok: true,\n\t\t\t\t\tstatus: \"already_enrolled\",\n\t\t\t\t\tgroup_id: invite.group_id,\n\t\t\t\t\tpolicy: invite.policy,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst invitePolicy = String(invite.policy);\n\t\t\tif (![\"auto_admit\", \"approval_required\"].includes(invitePolicy)) {\n\t\t\t\treturn c.json({ error: `unknown invite policy: ${invitePolicy}` }, 400);\n\t\t\t}\n\n\t\t\tif (invitePolicy === \"approval_required\") {\n\t\t\t\tconst request = await store.createJoinRequest({\n\t\t\t\t\tgroupId: inviteGroupId,\n\t\t\t\t\tdeviceId,\n\t\t\t\t\tpublicKey,\n\t\t\t\t\tfingerprint,\n\t\t\t\t\tdisplayName,\n\t\t\t\t\ttoken,\n\t\t\t\t});\n\t\t\t\treturn c.json({\n\t\t\t\t\tok: true,\n\t\t\t\t\tstatus: \"pending\",\n\t\t\t\t\tgroup_id: invite.group_id,\n\t\t\t\t\tpolicy: invite.policy,\n\t\t\t\t\trequest_id: request.request_id,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tawait store.enrollDevice(inviteGroupId, {\n\t\t\t\tdeviceId,\n\t\t\t\tfingerprint,\n\t\t\t\tpublicKey,\n\t\t\t\tdisplayName,\n\t\t\t});\n\n\t\t\treturn c.json({\n\t\t\t\tok: true,\n\t\t\t\tstatus: \"enrolled\",\n\t\t\t\tgroup_id: invite.group_id,\n\t\t\t\tpolicy: invite.policy,\n\t\t\t});\n\t\t} finally {\n\t\t\tawait store.close();\n\t\t}\n\t});\n\n\treturn app;\n}\n\n// ---------------------------------------------------------------------------\n// Shared handler for approve/deny\n// ---------------------------------------------------------------------------\n\nasync function handleJoinRequestReview(\n\tc: Context,\n\tapproved: boolean,\n\tdeps: { createStore: () => CoordinatorStore; runtime: CoordinatorRuntimeDeps },\n) {\n\tconst adminAuth = authorizeAdmin(c.req.header(ADMIN_HEADER), deps.runtime);\n\tif (!adminAuth.ok) return c.json({ error: adminAuth.error }, 401);\n\n\tconst raw = Buffer.from(await c.req.arrayBuffer());\n\tif (raw.length > MAX_BODY_BYTES) return c.json({ error: \"body_too_large\" }, 413);\n\n\tlet data: Record<string, unknown>;\n\ttry {\n\t\tdata = JSON.parse(raw.toString(\"utf-8\"));\n\t\tif (typeof data !== \"object\" || data === null || Array.isArray(data)) {\n\t\t\treturn c.json({ error: \"invalid_json\" }, 400);\n\t\t}\n\t} catch {\n\t\treturn c.json({ error: \"invalid_json\" }, 400);\n\t}\n\n\tconst requestId = String(data.request_id ?? \"\").trim();\n\tconst reviewedBy = String(data.reviewed_by ?? \"\").trim() || null;\n\n\tif (!requestId) return c.json({ error: \"request_id_required\" }, 400);\n\n\tconst store = deps.createStore();\n\ttry {\n\t\tconst request = await store.reviewJoinRequest({\n\t\t\trequestId,\n\t\t\tapproved,\n\t\t\treviewedBy,\n\t\t});\n\n\t\tif (!request) return c.json({ error: \"request_not_found\" }, 404);\n\n\t\tif (request._no_transition) {\n\t\t\treturn c.json({ error: \"request_not_pending\", status: request.status }, 409);\n\t\t}\n\n\t\treturn c.json({ ok: true, request });\n\t} finally {\n\t\tawait store.close();\n\t}\n}\n"],"x_google_ignoreList":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17],"mappings":"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"}