@jimhoyd/urlcode 0.4.0-alpha.1 → 0.4.0-alpha.3

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 (232) hide show
  1. package/.claude/skills/urlcode-authoring/SKILL.md +36 -22
  2. package/.claude/skills/urlcode-operations/SKILL.md +16 -22
  3. package/.claude-plugin/marketplace.json +1 -1
  4. package/CONTRIBUTING.md +20 -16
  5. package/README.md +83 -80
  6. package/ROADMAP.md +61 -331
  7. package/SECURITY.md +23 -8
  8. package/dist/BUILD-MANIFEST.json +42 -47
  9. package/dist/agents-guide.js +18 -18
  10. package/dist/build-static.js +136 -0
  11. package/dist/capabilities.js +85 -31
  12. package/dist/capability-query.js +0 -1
  13. package/dist/cli.js +24 -32
  14. package/dist/compliance-rules/baseline.js +2 -10
  15. package/dist/compliance-rules/privacy.js +5 -16
  16. package/dist/compliance-rules/shared.js +0 -2
  17. package/dist/compliance.js +6 -8
  18. package/dist/config.js +15 -8
  19. package/dist/context.js +9 -10
  20. package/dist/examples.js +2 -2
  21. package/dist/explain-cli.js +7 -5
  22. package/dist/explain.js +10 -5
  23. package/dist/extensions.js +61 -2
  24. package/dist/function-sources.js +34 -2
  25. package/dist/function-worker.js +3 -1
  26. package/dist/functions.js +84 -13
  27. package/dist/guest-api.js +29 -3
  28. package/dist/index.js +3 -6
  29. package/dist/manifest.js +11 -7
  30. package/dist/mcp-authoring.js +2 -2
  31. package/dist/mcp.js +1 -1
  32. package/dist/observability.js +1 -21
  33. package/dist/policies/cache.js +8 -3
  34. package/dist/policies.js +3 -1
  35. package/dist/policy.js +28 -9
  36. package/dist/prerender.js +4 -0
  37. package/dist/project-tests.js +3 -3
  38. package/dist/readiness.js +35 -9
  39. package/dist/route-diff.js +12 -5
  40. package/dist/router.js +5 -7
  41. package/dist/runtime.js +77 -58
  42. package/dist/sandbox.js +48 -0
  43. package/dist/scaffold.js +0 -0
  44. package/dist/scripts/operational-drills.js +12 -54
  45. package/dist/server.js +3 -29
  46. package/dist/tooling.js +1 -1
  47. package/dist/trusted-functions.js +210 -0
  48. package/dist/types/build-static.d.ts +43 -0
  49. package/dist/types/capabilities.d.ts +14 -5
  50. package/dist/types/compliance-rules/shared.d.ts +0 -2
  51. package/dist/types/compliance.d.ts +0 -3
  52. package/dist/types/config.d.ts +2 -1
  53. package/dist/types/context.d.ts +2 -1
  54. package/dist/types/examples.d.ts +1 -1
  55. package/dist/types/explain.d.ts +6 -0
  56. package/dist/types/extensions.d.ts +55 -0
  57. package/dist/types/function-sources.d.ts +4 -0
  58. package/dist/types/functions.d.ts +48 -5
  59. package/dist/types/guest-api.d.ts +1 -0
  60. package/dist/types/index.d.ts +3 -6
  61. package/dist/types/manifest.d.ts +5 -3
  62. package/dist/types/observability.d.ts +1 -14
  63. package/dist/types/project-tests.d.ts +1 -2
  64. package/dist/types/readiness.d.ts +12 -3
  65. package/dist/types/router.d.ts +2 -1
  66. package/dist/types/runtime.d.ts +0 -27
  67. package/dist/types/sandbox.d.ts +12 -0
  68. package/dist/types/scaffold.d.ts +0 -2
  69. package/dist/types/server.d.ts +1 -4
  70. package/dist/types/tooling.d.ts +3 -3
  71. package/dist/types/trusted-functions.d.ts +29 -0
  72. package/dist/types/types.d.ts +22 -8
  73. package/dist/types/verify-deployment.d.ts +2 -2
  74. package/dist/types.js +25 -5
  75. package/dist/typescript-authoring.js +67 -18
  76. package/dist/verify-deployment.js +3 -3
  77. package/docs/AI-AUTHORING.md +109 -10
  78. package/docs/ASSETS.md +2 -1
  79. package/docs/AUTH-BACKUP.md +32 -0
  80. package/docs/AWS.md +4 -4
  81. package/docs/BEST-PRACTICES.md +17 -8
  82. package/docs/CAPABILITIES.md +30 -17
  83. package/docs/CAPACITY.md +128 -31
  84. package/docs/CI-FOLLOWUP-2026-09-19.md +97 -0
  85. package/docs/CI-RELEASE-AUDIT-2026-09-19.md +322 -0
  86. package/docs/CI.md +8 -3
  87. package/docs/CLOUDFLARE.md +1 -2
  88. package/docs/CODEBASE-AUDIT-2026-09-20.md +278 -0
  89. package/docs/COMPLIANCE.md +6 -9
  90. package/docs/DEPLOYMENT-CHECKS.md +1 -1
  91. package/docs/DEVELOPMENT-PIPELINE.md +181 -0
  92. package/docs/EXTENSIONS.md +193 -11
  93. package/docs/FRAMEWORK.md +53 -33
  94. package/docs/FUNCTION-SECURITY.md +173 -32
  95. package/docs/INSTALL.md +0 -5
  96. package/docs/LOAD-TESTING.md +4 -4
  97. package/docs/LOCAL-DEVELOPMENT.md +3 -0
  98. package/docs/MIDDLEWARE.md +27 -16
  99. package/docs/MONITORING.md +2 -19
  100. package/docs/OBSERVABILITY.md +7 -16
  101. package/docs/OPEN-DECISIONS.md +184 -0
  102. package/docs/OPERATIONAL-PROOF.md +26 -30
  103. package/docs/OPERATIONS.md +23 -32
  104. package/docs/POLICIES.md +27 -8
  105. package/docs/PRERENDER.md +25 -13
  106. package/docs/PROJECT-DIRECTION.md +35 -10
  107. package/docs/READINESS.md +6 -2
  108. package/docs/README.md +20 -41
  109. package/docs/RELEASE-0.4.0-alpha.3.md +50 -0
  110. package/docs/RELEASE-READINESS.md +50 -30
  111. package/docs/RELEASE-SECURITY.md +72 -86
  112. package/docs/RESILIENCE.md +16 -15
  113. package/docs/ROUTING.md +7 -10
  114. package/docs/SANDBOX-REVIEW.md +19 -6
  115. package/docs/SCAFFOLDING.md +0 -2
  116. package/docs/SECURITY-AUDIT.md +42 -2
  117. package/docs/SPECIFICATION.md +63 -27
  118. package/docs/SPIKE-AI-FRAMEWORK-BENCHMARK.md +288 -0
  119. package/docs/SPIKE-BUSINESS-SUITE.md +16 -0
  120. package/docs/SPIKE-CORE-LAYERING.md +368 -0
  121. package/docs/SPIKE-DEFAULT-TRUST-MODEL.md +211 -0
  122. package/docs/SPIKE-LAMBDA-COMPILE.md +12 -2
  123. package/docs/STARTERS.md +1 -1
  124. package/docs/STATIC.md +105 -0
  125. package/docs/TOOLING.md +17 -12
  126. package/docs/TUNNELS.md +0 -3
  127. package/docs/TYPESCRIPT-AUTHORING.md +32 -12
  128. package/docs/TYPESCRIPT.md +25 -4
  129. package/docs/VERCEL.md +4 -5
  130. package/docs/VERSION-ALIGNMENT.md +46 -0
  131. package/docs/YAML-GUIDE.md +0 -3
  132. package/docs/YAML-REFERENCE.md +16 -6
  133. package/docs/archive/2026-09-19/EXTENSION-IMPLEMENTATION.md +68 -0
  134. package/docs/{MANAGEMENT-SECURITY.md → archive/2026-09-19/MANAGEMENT-SECURITY.md} +20 -0
  135. package/docs/{NEXT-PHASE-PLAN.md → archive/2026-09-19/NEXT-PHASE-PLAN.md} +26 -8
  136. package/docs/{NEXT-STEPS.md → archive/2026-09-19/NEXT-STEPS.md} +274 -43
  137. package/docs/archive/2026-09-19/OPEN-DECISIONS.md +277 -0
  138. package/docs/archive/2026-09-19/RELEASE-SECURITY.md +186 -0
  139. package/docs/archive/2026-09-19/ROADMAP.md +386 -0
  140. package/docs/{SPIKE-EXTENSION-MODEL.md → archive/2026-09-19/SPIKE-EXTENSION-MODEL.md} +12 -2
  141. package/docs/{SPIKE-EXTENSIONS.md → archive/2026-09-19/SPIKE-EXTENSIONS.md} +28 -12
  142. package/docs/archive/2026-09-19/SPIKE-MONOREPO.md +776 -0
  143. package/docs/{USABILITY-REVIEW.md → archive/2026-09-19/USABILITY-REVIEW.md} +18 -2
  144. package/docs/archive/README.md +27 -0
  145. package/docs/policies/agents.md +1 -1
  146. package/docs/policies/cache.md +13 -0
  147. package/docs/policies/compression.md +3 -2
  148. package/docs/policies/security.md +3 -2
  149. package/examples/assets/example.yaml +2 -2
  150. package/examples/aws/example.yaml +1 -1
  151. package/examples/cloudflare/example.yaml +1 -1
  152. package/examples/conditions/example.yaml +1 -1
  153. package/examples/cookbook/example.yaml +1 -1
  154. package/examples/cookbook/middleware/bucket.mjs +12 -2
  155. package/examples/cookbook/middleware/locale.mjs +7 -3
  156. package/examples/cookbook/route-index.json +1 -1
  157. package/examples/cookbook/routes/middleware.yaml +1 -1
  158. package/examples/egress/example.yaml +1 -1
  159. package/examples/extensions/example.yaml +1 -1
  160. package/examples/prerender/README.md +14 -6
  161. package/examples/prerender/example.yaml +1 -1
  162. package/examples/prerender/functions/page.mjs +4 -2
  163. package/examples/prerender/middleware/template.mjs +1 -1
  164. package/examples/prerender/prerender.mjs +1 -1
  165. package/examples/prerender/urlcode.yaml +8 -4
  166. package/examples/provider-conformance/example.yaml +1 -1
  167. package/examples/vercel/example.yaml +1 -1
  168. package/llms-full.txt +686 -239
  169. package/llms.txt +27 -15
  170. package/package.json +32 -5
  171. package/packaging/claude-plugin/.claude-plugin/plugin.json +2 -2
  172. package/packaging/claude-plugin/skills/urlcode-authoring/SKILL.md +36 -22
  173. package/packaging/claude-plugin/skills/urlcode-operations/SKILL.md +16 -22
  174. package/recipes/authenticated-json-api/README.md +4 -3
  175. package/recipes/authenticated-json-api/functions/profile.mjs +2 -1
  176. package/recipes/authenticated-json-api/recipe.yaml +2 -2
  177. package/recipes/contact-form/functions/contact.mjs +2 -1
  178. package/recipes/contact-form/recipe.yaml +3 -3
  179. package/recipes/cors-api/README.md +2 -2
  180. package/recipes/cors-api/recipe.yaml +2 -2
  181. package/recipes/health-page/README.md +1 -1
  182. package/recipes/health-page/recipe.yaml +1 -1
  183. package/recipes/json-api/README.md +1 -1
  184. package/recipes/json-api/recipe.yaml +4 -4
  185. package/recipes/middleware/README.md +8 -4
  186. package/recipes/middleware/middleware/bucket.mjs +12 -2
  187. package/recipes/middleware/middleware/locale.mjs +7 -3
  188. package/recipes/middleware/recipe.yaml +1 -1
  189. package/recipes/protected-download/README.md +1 -1
  190. package/recipes/protected-download/recipe.yaml +2 -2
  191. package/recipes/redirect/recipe.yaml +1 -1
  192. package/recipes/static-plus-api/README.md +2 -2
  193. package/recipes/static-plus-api/public/index.html +1 -1
  194. package/recipes/static-plus-api/recipe.yaml +2 -2
  195. package/recipes/static-plus-api/urlcode.yaml +1 -1
  196. package/recipes/typescript/README.md +2 -1
  197. package/recipes/typescript/recipe.yaml +5 -5
  198. package/recipes/webhook-receiver/README.md +5 -1
  199. package/recipes/webhook-receiver/recipe.yaml +2 -1
  200. package/recipes/webhook-receiver/urlcode.yaml +7 -0
  201. package/schemas/recipe.schema.json +4 -3
  202. package/schemas/urlcode.schema.json +14 -41
  203. package/skills/urlcode/SKILL.md +32 -11
  204. package/starters/default/AGENTS.md +18 -18
  205. package/starters/default/urlcode.yaml +0 -1
  206. package/dist/link-api.js +0 -136
  207. package/dist/link-cli.js +0 -141
  208. package/dist/link-events.js +0 -76
  209. package/dist/link-records.js +0 -31
  210. package/dist/link-store-worker.js +0 -150
  211. package/dist/link-store.js +0 -250
  212. package/dist/management-policy.js +0 -40
  213. package/dist/sqlite-version.js +0 -6
  214. package/dist/types/link-api.d.ts +0 -30
  215. package/dist/types/link-cli.d.ts +0 -37
  216. package/dist/types/link-events.d.ts +0 -27
  217. package/dist/types/link-records.d.ts +0 -11
  218. package/dist/types/link-store-worker.d.ts +0 -1
  219. package/dist/types/link-store.d.ts +0 -130
  220. package/dist/types/management-policy.d.ts +0 -8
  221. package/dist/types/sqlite-version.d.ts +0 -1
  222. package/docs/DYNAMIC-LINKS.md +0 -61
  223. package/docs/links/cli.md +0 -110
  224. package/docs/links/limits.md +0 -175
  225. package/docs/links/management-api.md +0 -80
  226. package/docs/links/pools.md +0 -75
  227. package/docs/links/setup.md +0 -135
  228. package/docs/yaml/links.md +0 -30
  229. package/examples/live-links/README.md +0 -11
  230. package/examples/live-links/example.yaml +0 -21
  231. package/examples/live-links/tests/requests.json +0 -6
  232. package/examples/live-links/urlcode.yaml +0 -16
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: urlcode-authoring
3
- description: Author or modify a URLCode project — write and edit urlcode.yaml routes, function and middleware modules, pages, static assets, downloads and stored links, then validate and test them. Use whenever a urlcode.yaml file is present or referenced, when the user mentions URLCode, @jimhoyd/urlcode, urlcode routes/handlers/policies/site keys, or asks for redirects, short links or request functions in a URLCode project. Loads the implemented capability matrix so unsupported features are reported as gaps instead of invented.
3
+ description: Author or modify a URLCode project — write and edit urlcode.yaml routes, function and middleware modules, pages, static assets and downloads, then validate and test them. Use whenever a urlcode.yaml file is present or referenced, when the user mentions URLCode, @jimhoyd/urlcode, urlcode routes/handlers/policies/site keys, or asks for redirects or request functions in a URLCode project. Loads the implemented capability matrix so unsupported features are reported as gaps instead of invented.
4
4
  ---
5
5
 
6
6
  # Authoring URLCode projects
@@ -11,23 +11,27 @@ validates. Features outside that contract do not silently degrade — they fail
11
11
  validation. So the cost of guessing is a broken project, and the whole job here
12
12
  is to author only what the pinned revision implements and then prove it.
13
13
 
14
+ ## Declarative-first default
15
+
16
+ > Use URLCode's highest-level declarative features whenever possible. Generate custom code only when the framework cannot express the requirement.
17
+
18
+ Check the installed version's primitives, YAML configuration, policies, supported
19
+ extensions and recipes/templates before writing a custom function or middleware.
20
+ Keep necessary custom code focused and report the capability gap; never invent
21
+ fields or bypass target limits or operator grants. See `docs/PROJECT-DIRECTION.md` in the installed runtime.
22
+
14
23
  ## Read the contract before writing YAML
15
24
 
16
25
  Documentation, schema and runtime must come from the **same revision**. Read from
17
26
  the project's installed runtime (`node_modules/@jimhoyd/urlcode/`) or the
18
27
  checkout you are working in — never from memory of another version.
19
28
 
20
- 1. `docs/AI-AUTHORING.md` the authoring contract and the **capability matrix**
21
- of what is available versus unavailable. Read this first and in full.
22
- 2. `schemas/urlcode.schema.json` the exact accepted structure.
23
- 3. `docs/YAML-REFERENCE.md` and `docs/SPECIFICATION.md` every field, and the
24
- implemented semantics, defaults and sandbox API.
25
- 4. `docs/YAML-GUIDE.md` and `examples/cookbook/` recipes and runnable files.
26
- 5. `docs/ROUTING.md`, `docs/HTTP.md`, `docs/MIDDLEWARE.md`, `docs/ASSETS.md` —
27
- matching precedence, methods, composition, MIME and ranges.
28
- 6. `docs/FUNCTION-SECURITY.md` — the sandbox and operator binding policy.
29
-
30
- `llms.txt` at the repository root is a compact index of all of the above.
29
+ Start with `urlcode context --project <dir> --budget 4000`, then retrieve the
30
+ capability, schema fragment, recipe or example relevant to the change. Use the
31
+ read-only MCP equivalents when available. `llms.txt` is the index; read the
32
+ matching task guide from `docs/` when a query needs more explanation.
33
+ `docs/SPECIFICATION.md` and `schemas/urlcode.schema.json` resolve contract
34
+ questions. Archived plans are historical, not valid YAML guidance.
31
35
 
32
36
  ## Workflow
33
37
 
@@ -35,15 +39,16 @@ checkout you are working in — never from memory of another version.
35
39
  tests and the pinned runtime version. Preserve the user's organization,
36
40
  naming and unrelated routes.
37
41
  - Choose exactly one handler per route — `function`, `redirect`, `respond`,
38
- `page`, `static`, `download` or `link` plus optional ordered middleware.
39
- Prefer a native handler when code is unnecessary.
42
+ `page`, `static`, `download`, `conditional`, `proxy` or an `extension` mount
43
+ — plus optional ordered middleware. Prefer a native handler when code is
44
+ unnecessary.
40
45
  - Declare each path placeholder as a required string. Paths match whole
41
46
  segments: no regex, no greedy captures, no wildcard handlers.
42
47
  - Bind typed inputs through `args` or context. There is no `${...}`
43
48
  interpolation anywhere in the format.
44
49
  - Create every referenced module, page and asset **before** validating. All
45
- paths resolve from the project root; functions and middleware use relative
46
- ES-module imports only.
50
+ source paths resolve from the project root. Trusted modules can import Node built-ins and npm packages;
51
+ only `sandbox: true` modules are restricted to the relative snapshotted graph.
47
52
  - Write exact response fixtures for success and failure, covering every active
48
53
  method, middleware behavior, HEAD, and any range or cache semantics.
49
54
  - Follow `docs/BEST-PRACTICES.md` for layout and readability as the project grows.
@@ -56,11 +61,20 @@ mistakes that recur:
56
61
  - No YAML anchors, aliases, template interpolation or remote includes.
57
62
  - No recursive includes or glob discovery; includes are explicit.
58
63
  - No regex, optional or greedy route segments, and no host-based routing.
59
- - The sandbox is text/JSON `Request`/`Response` only: **no** `fetch`, Node or
60
- npm APIs, filesystem, WebSocket, streaming or crypto API.
64
+ - `function`/`middleware` routes run trusted and unsandboxed by default: full
65
+ Node, npm, filesystem and `fetch` access, in-process, like any other project
66
+ code. `sandbox: true` opts a route into isolation — reach for it when that
67
+ route's own code warrants it (unreviewed or third-party code, a secret whose
68
+ blast radius matters, complex logic), not reflexively on every route and
69
+ never merely because it handles request data -- that is untrusted in both
70
+ modes and must be validated either way. A
71
+ `sandbox: true` route gets a text/JSON `Request`/`Response` sandbox only:
72
+ **no** `fetch`, Node or npm APIs, filesystem, WebSocket, streaming or crypto
73
+ API.
61
74
  - No global middleware, Express compatibility or automatic auth.
62
75
  - `policies` accepts only `throttle`, `agents`, `security`, `compression` and
63
- `cache`, every key off unless declared; `hardened` is the only built-in
76
+ `cache`, plus registered extension requirements under `extensions`;
77
+ the built-in policies are off unless declared; `hardened` is the only built-in
64
78
  profile. Check the per-target table in `docs/POLICIES.md` before declaring
65
79
  one for a serverless or Cloudflare deployment — an unsupported policy refuses
66
80
  activation rather than degrading.
@@ -68,9 +82,9 @@ mistakes that recur:
68
82
  only and off unless declared; a declared route at the same path wins. Its
69
83
  generated routes count toward `--expect-routes`, and `site.sitemap` needs
70
84
  `--origin` on every command that activates the project.
71
- - `dynamicLinks: true` belongs in the entry `urlcode.yaml` only, and only for
72
- live `link` handlers not for includes, and not for parameterized redirects
73
- or functions.
85
+ - There is no native `link` handler or `dynamicLinks` project flag, and no
86
+ supported extension package provides one; report stored short links as a gap,
87
+ never invent a `link` field.
74
88
  - Infrastructure (proxy ranges, storage URLs, vendor rule identifiers) is an
75
89
  operator flag, never route YAML.
76
90
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: urlcode-operations
3
- description: Deploy, verify, monitor and operate a URLCode project — process/container deployment, release readiness, verifying a live deployment against the project, capacity/audit/benchmark, observability, DDoS/overload resilience, and private management (grants, live-link credentials). Use when the user asks to deploy, check readiness, verify a running deployment, size/benchmark a project, monitor it, plan for overload, or manage live links/bindings. Reports operational limits and unimplemented capabilities as gaps instead of inventing mitigations.
3
+ description: Deploy, verify, monitor and operate a URLCode project — process/container deployment, release readiness, verifying a live deployment against the project, capacity/audit/benchmark, observability, DDoS/overload resilience, and operator binding grants. Use when the user asks to deploy, check readiness, verify a running deployment, size/benchmark a project, monitor it, plan for overload, or manage bindings. Reports operational limits and unimplemented capabilities as gaps instead of inventing mitigations.
4
4
  ---
5
5
 
6
6
  # Operating a URLCode deployment
@@ -30,9 +30,7 @@ another version.
30
30
  overload and DDoS; what layer each defense belongs to.
31
31
  6. `docs/MONITORING.md` and `docs/OBSERVABILITY.md` — health/ready probes,
32
32
  logs, metrics format, what is and is not exported.
33
- 7. `docs/MANAGEMENT-SECURITY.md` — the private management API: credential
34
- policy shape, scope, loopback-only binding.
35
- 8. `docs/POLICIES.md` and `docs/FUNCTION-SECURITY.md` — per-target policy
33
+ 7. `docs/POLICIES.md` and `docs/FUNCTION-SECURITY.md` — per-target policy
36
34
  support and the operator binding-grant process, needed whenever a
37
35
  deployment or verification step touches either.
38
36
 
@@ -71,28 +69,25 @@ urlcode verify-deployment --project ./my-links --target https://links.example \
71
69
  Run the actual commands and report actual results, never "should work" or
72
70
  "should be reachable". `verify-deployment` needs a real target; do not
73
71
  simulate its output. In a runtime checkout, substitute `node src/cli.ts` for
74
- `urlcode`. Pass `--policy`/`--link-store` where a snapshot needs bindings
75
- already reviewed by the operator.
72
+ `urlcode`. Pass `--policy` where a snapshot needs bindings already reviewed
73
+ by the operator.
76
74
 
77
75
  ## Hard limits — report these as gaps, never invent around them
78
76
 
79
- - No provider adapters, automatic TLS/DNS, distributed rate limiting, metrics
80
- exporters or durable event delivery are included; these remain the
81
- operator's own infrastructure.
77
+ - Provider adapters exist with different capability limits; query
78
+ `urlcode capabilities --target NAME`. Automatic TLS/DNS, distributed rate
79
+ limiting, metrics exporters and durable delivery require operator infrastructure.
82
80
  - No orchestration, traffic switching or automated rollback; recovery is an
83
81
  explicit snapshot reload from a known-good artifact.
84
82
  - `verify-deployment` has no infrastructure access, uses no credential,
85
83
  follows no redirect and offers no `--insecure`. It cannot check anything a
86
84
  read-only HTTP probe cannot observe.
87
- - The private management API binds only `127.0.0.1`/`::1`; it is never meant
88
- to be exposed through a public proxy or container port mapping, and browser
89
- Origin requests are rejected regardless.
90
- - A management credentials policy is operator-owned, outside the application,
91
- never in YAML or Git, at most 64 KiB, mode 600, at most 128 credentials with
92
- explicit collection/action allowlists no wildcards.
93
- - Sandbox concurrency, worker slots and execution deadlines are shared across
94
- every programmable route in a snapshot; there is no per-route fairness or
95
- reserved capacity, and awaiting a guest timer still occupies a slot.
85
+ - Core has no durable store and no private management API of its own, and no
86
+ supported extension package provides stored short links.
87
+ - Only `sandbox: true` routes share the sandbox worker slots and forced
88
+ execution deadlines. Trusted routes run in Node under HTTP admission limits;
89
+ their cooperative timeout cannot stop blocking JavaScript. A guest timer still
90
+ occupies a sandbox slot. Size both modes from `docs/CAPACITY.md`.
96
91
  - `throttle` and `agents` policy counters are per instance, not distributed;
97
92
  they are a second layer behind the edge, never a replacement for it.
98
93
 
@@ -102,10 +97,9 @@ responsibility that covers it instead of inventing a flag.
102
97
 
103
98
  ## Boundaries
104
99
 
105
- - Never generate or approve an operator binding grant, or a management
106
- credentials policy, on the user's behalf. Both are the operator's own
107
- reviewed decision; produce the shape and let them fill in and store the
108
- real secret.
100
+ - Never generate or approve an operator binding grant on the user's behalf.
101
+ That is the operator's own reviewed decision; produce the shape and let
102
+ them fill in and store the real secret.
109
103
  - Keep every credential, token and policy file out of source, examples and
110
104
  Git. A synthetic example value is fine; a real one is never committed.
111
105
  - Do not deploy, expose a service, rotate a credential, or run
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "Claude plugins published from the URLCode repository.",
9
- "version": "0.4.0-alpha.1"
9
+ "version": "0.4.0-alpha.3"
10
10
  },
11
11
  "plugins": [
12
12
  {
package/CONTRIBUTING.md CHANGED
@@ -37,9 +37,11 @@ update docs when support changes. Do not claim a provider or OS is supported
37
37
  without a passing test run. Preserve portable behavior and useful self-hosting.
38
38
 
39
39
  Use synthetic data. Never commit secrets, customer URL collections or local
40
- environment files. Treat all application function code as untrusted. Never import it into Node or
41
- add an unsafe fallback. Capability grants must come from operator policy outside
42
- the project. Extend adversarial tests with every new guest/host bridge. See the
40
+ environment files. Project function and middleware code runs trusted in Node by default. Preserve
41
+ explicit `sandbox: true` isolation: never add a host-execution fallback for that
42
+ mode. Binding grants come from operator policy outside the project and govern
43
+ what URLCode injects, not ambient access by trusted code. Extend adversarial
44
+ tests with every new sandbox guest/host bridge. See the
43
45
  [security model](docs/FUNCTION-SECURITY.md).
44
46
 
45
47
  ## Maintaining the starter
@@ -68,19 +70,19 @@ explicit in `docs/AI-AUTHORING.md`; never present future roadmap fields as valid
68
70
 
69
71
  ## Documentation
70
72
 
71
- Public documentation lives in
72
- [urlcode-docs](https://github.com/jimhoyd-com/urlcode-docs) and is authored
73
- there. It is not generated from this repository and must not be mirrored into
74
- it. Write new guides, references and recipes as a pull request against
75
- urlcode-docs.
76
-
77
- `docs/` here is contributor and maintainer material: local development, CI,
78
- the release process, internal reviews, spikes, plans and the generated
79
- `YAML-REFERENCE.md`. Reader-facing pages still under `docs/` are being
80
- migrated to urlcode-docs; edit them in place and do not add new ones.
73
+ Documentation lives in `docs/` in this repository. Write new guides,
74
+ references and recipes here, alongside the contributor and maintainer material
75
+ already there: local development, CI, the release process, internal reviews,
76
+ spikes, plans and the generated `YAML-REFERENCE.md`.
81
77
 
82
78
  A behavior change that a reader depends on is not finished until the matching
83
- urlcode-docs pull request exists. Link the two so review can see both halves.
79
+ page in `docs/` is updated. Put both in the **same** pull request so review can
80
+ see both halves and neither can land alone.
81
+
82
+ `urlcode-docs` was deleted on 2026-09-19. It held its own copy of most of these
83
+ pages and had drifted from them; the content that was ahead has been brought
84
+ across, and the repository was retired rather than reconciled page by page.
85
+ Links to it no longer resolve.
84
86
 
85
87
  If you find a gap you cannot close, file it as an issue on the repository that
86
88
  owns the code rather than leaving it undocumented. Feature requests are wanted:
@@ -93,8 +95,10 @@ Work on a branch and open a focused pull request. Explain the problem, resulting
93
95
  behavior, validation and compatibility/security implications. Never include real
94
96
  credentials or customer data. Use the PR template and keep unrelated changes out.
95
97
 
96
- `main` requires a pull request, an up-to-date branch, the required Node/OS verification
97
- jobs, container verification, CodeQL results and resolved conversations. High/critical
98
+ `main` requires a pull request, the `verify-complete` and `container` checks,
99
+ CodeQL results and resolved conversations. The current ruleset does not require
100
+ an up-to-date branch. The [development pipeline](docs/DEVELOPMENT-PIPELINE.md)
101
+ describes the fast prose lane, full code lane and exact-commit release gate. High/critical
98
102
  security findings and error-level CodeQL alerts block merging. Force pushes and branch
99
103
  deletion are blocked; squash merging keeps a linear history. Administrators have
100
104
  no configured ruleset bypass. Automation cannot approve pull requests.
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # URLCode
2
2
 
3
3
  **A portable runtime for programmable URL behavior, and the framework that grows
4
- from it.** Declare an application's public URL surface in YAML, add isolated
5
- JavaScript only where declarative handlers are not enough, and run the same
4
+ from it.** Declare an application's public URL surface in YAML, add JavaScript
5
+ only where declarative handlers are not enough, and run the same
6
6
  project locally, in a container, on your own infrastructure or on a provider
7
7
  adapter. When the project gets serious, add accounts and an administration
8
8
  console as operator-installed extensions instead of building them again.
@@ -20,22 +20,28 @@ and agents can read: the agent describes what, the runtime owns how, and
20
20
  generated code goes to the part that is actually the application. It is
21
21
  infrastructure for AI-built software, not a framework for building AI models.
22
22
  [Why](docs/PROJECT-DIRECTION.md#why-your-ai-should-build-your-application-not-your-framework) ·
23
- [next steps](docs/NEXT-STEPS.md).
23
+ [roadmap](ROADMAP.md).
24
24
 
25
25
  ## What it is
26
26
 
27
27
  A project is a `urlcode.yaml` with `version: "1"`. Each route has exactly one
28
28
  handler: `redirect`, `respond`, `page`, `static`, `download`, `function`,
29
- `link`, `proxy`, `conditional` or an `extension` mount, with optional ordered
29
+ `proxy`, `conditional` or an `extension` mount, with optional ordered
30
30
  `middleware`. The runtime validates the whole project before serving it,
31
31
  compiles it once, and refuses anything a target cannot enforce with the route
32
- named. Functions run in a QuickJS/WebAssembly sandbox with a fresh heap per
33
- call and no Node, filesystem or network; secrets reach them only through
34
- operator grants pinned to the project revision.
35
-
36
- URLCode is not a URL shortener: short links are one handler. It is not a
37
- general Node web framework: guest code cannot reach the host. It is not a
38
- provider configuration format: infrastructure settings stay out of route YAML.
32
+ named. Functions and middleware run trusted, in-process, with full Node
33
+ access by default; a route opts into an isolated QuickJS/WebAssembly sandbox
34
+ with a fresh heap per call and no Node, filesystem or network by declaring
35
+ `sandbox: true`. Either way, secrets reach them only through operator grants
36
+ pinned to the project revision.
37
+
38
+ URLCode is not a URL shortener: stored short links are an operator-installed
39
+ extension, not core's job. It is not a
40
+ general Node web framework: routing, validation, middleware wiring and
41
+ policies are declared in YAML, not hand-wired; isolating a specific route's
42
+ code from the host is an explicit `sandbox: true` opt-in, not something every
43
+ route gets by writing a handler. It is not a provider configuration format:
44
+ infrastructure settings stay out of route YAML.
39
45
  See [project direction](docs/PROJECT-DIRECTION.md).
40
46
 
41
47
  ## The framework
@@ -47,10 +53,33 @@ an AI agent must follow are in [the framework](docs/FRAMEWORK.md).
47
53
 
48
54
  | Package | Adds | Status |
49
55
  |---|---|---|
50
- | [urlcode](https://github.com/jimhoyd-com/urlcode) (this repository) | Runtime, CLI, policies, live links, provider adapters, extension contract | `0.4.0-alpha.1` (alpha) on top of the `0.3.0` release, Apache-2.0 |
51
- | [urlcode-ui](https://github.com/jimhoyd-com/urlcode-ui) | Shared presentation: escaped templates, shadcn/ui partials, themes, translations | `0.1.0-alpha.1` on npm, alpha: review pending |
52
- | [urlcode-auth](https://github.com/jimhoyd-com/urlcode-auth) | Accounts: password, passkeys, OIDC, email codes, TOTP, sessions, roles, account page | `0.1.0-alpha.1` on npm, alpha: review pending |
53
- | [urlcode-admin](https://github.com/jimhoyd-com/urlcode-admin) | Administration: users, sessions, roles, audit, approvals, cases, impersonation | `0.1.0-alpha.1` on npm, alpha: review pending |
56
+ | [urlcode](https://github.com/jimhoyd-com/urlcode) (this repository) | Runtime, CLI, policies, provider adapters, extension contract | `0.4.0-alpha.2` (alpha) on top of the `0.3.0` release, Apache-2.0 |
57
+ | [urlcode-ui](packages/ui) (in this repository) | Shared presentation: escaped templates, shadcn/ui partials, themes, translations | `0.1.0-alpha.5` on npm, alpha: review pending |
58
+ | [urlcode-auth](packages/auth) (in this repository) | Accounts: password, passkeys, OIDC, email codes, TOTP, sessions, roles, account page | `0.1.0-alpha.3` on npm, alpha: review pending |
59
+ | [urlcode-admin](packages/admin) (in this repository) | Administration: users, sessions, roles, audit, approvals, cases, impersonation | `0.1.0-alpha.3` on npm, alpha: review pending |
60
+
61
+ Every version in this table is the one published to npm under the `alpha`
62
+ dist-tag, and they are released together in the order core → ui → auth →
63
+ admin. The authoritative cross-repository register, including each
64
+ package's declared peer ranges and the rules that keep them consistent, is
65
+ [docs/VERSION-ALIGNMENT.md](docs/VERSION-ALIGNMENT.md).
66
+
67
+ `urlcode-dynamic-link` and `urlcode-short` were published once as
68
+ `0.1.0-alpha.1` and have since been retired: both were unpublished from npm and
69
+ their repositories deleted, and neither has a successor. Nothing supported
70
+ provides stored short links today — a project that needs them owns that storage
71
+ itself. Anything still pinned to `@jimhoyd/urlcode-dynamic-link@0.1.0-alpha.1`
72
+ also has to deal with its exact declared peer `@jimhoyd/urlcode: 0.4.0-alpha.1`,
73
+ which cannot be installed beside core `0.4.0-alpha.2` and never will be.
74
+
75
+ `urlcode-middleware` was retired the same way on 2026-09-19 —
76
+ `@jimhoyd/urlcode-middleware` was unpublished from npm at `0.1.0-alpha.2` and
77
+ its repository deleted. Unlike the two above, its capability did not go away
78
+ with it: **per-route middleware is native to core**, through the
79
+ `middleware:` array documented in [docs/MIDDLEWARE.md](docs/MIDDLEWARE.md).
80
+ The deleted package only ever offered the same behavior through the extension
81
+ seam. A project using it moves its entries to the native array; there is no
82
+ gap to report here.
54
83
 
55
84
  ```yaml
56
85
  version: "1"
@@ -74,23 +103,25 @@ it. Cross-repository acceptance is tracked in
74
103
 
75
104
  ## Status
76
105
 
77
- `0.4.0-alpha.1` is the current release of the extension contract and the
78
- agent tooling, on top of the `0.3.0` self-hosted release. It adds the
79
- extension contract, capabilities and provider conformance, strict redirect
80
- interchange, bulk import, recipes and search, TypeScript guest authoring,
81
- conditions, bounded proxy and signals, and the MCP read and authoring modes;
82
- use the schema and docs from the runtime revision you run.
106
+ `0.4.0-alpha.2` is the current release of the extension contract and the
107
+ agent tooling, on top of the `0.3.0` self-hosted release. `0.4.0-alpha.1`
108
+ added the extension contract, capabilities and provider conformance, strict
109
+ redirect interchange, bulk import, recipes and search, TypeScript guest
110
+ authoring, conditions, bounded proxy and signals, and the MCP read and
111
+ authoring modes. `0.4.0-alpha.2` then made `function` and `middleware` routes
112
+ run trusted and unsandboxed by default, with `sandbox: true` as a per-route
113
+ opt-in, and removed the native `link:`/`dynamicLinks:` YAML shape. That is a
114
+ behaviour change for existing projects with no YAML edit; read
115
+ [the roadmap entry](ROADMAP.md) before upgrading. Use the schema and docs from
116
+ the runtime revision you run.
83
117
  The [roadmap](ROADMAP.md) separates implemented from planned, and
84
118
  [release readiness](docs/RELEASE-READINESS.md) records what is proven and
85
119
  what is not: provider deployments, soak and independent security review
86
120
  remain open.
87
121
 
88
- Live-link storage uses separate bounded reader/writer pools. It requires a Node
89
- build containing a patched SQLite version 3.51.3 or newer, 3.50.7, or 3.44.6 —
90
- which some current releases on a supported Node line do not carry. Run
91
- `urlcode doctor` and check `liveLinks` before relying on it; everything else
92
- runs on any supported Node.
93
- See [pool controls and scaling limits](docs/DYNAMIC-LINKS.md#separate-reader-and-writer-pools).
122
+ Core has no native `link` handler. Stored short links moved out to a
123
+ mount-based `urlcode-dynamic-link` extension, which has since been retired and
124
+ unpublished; no supported package provides them.
94
125
 
95
126
  URLCode is free and open-source software licensed under the
96
127
  [Apache License 2.0](LICENSE). Commercial use, modification, redistribution and
@@ -109,6 +140,14 @@ project grows. Operators should read [capacity/concurrency](docs/CAPACITY.md) an
109
140
  [DDoS and recovery playbook](docs/RESILIENCE.md). Embedding the runtime from
110
141
  TypeScript is covered in [TypeScript](docs/TYPESCRIPT.md). [All documentation](docs/README.md).
111
142
 
143
+ All of it lives in [`docs/`](docs/README.md) in this repository — guides,
144
+ references and recipes alongside the contributor and maintainer material: local
145
+ development, CI, the release process, reviews and the generated field
146
+ reference. New pages belong here, in the same pull request as the change they
147
+ describe. `urlcode-docs`, a private repository that served a documentation site
148
+ from its own copy of these pages, is being retired; the content that was ahead
149
+ of this repository has been brought across.
150
+
112
151
  ## Start your own project
113
152
 
114
153
  Use [urlcode-template](https://github.com/jimhoyd-com/urlcode-template) for a small
@@ -123,42 +162,14 @@ npm ci
123
162
  npm run dev
124
163
  ```
125
164
 
126
- Live stored-link routes require **`dynamicLinks: true`** in the entry `urlcode.yaml`;
127
- the starter explicitly sets false. Ordinary functions and parameterized redirects
128
- do not need it. [Live-link setup](docs/DYNAMIC-LINKS.md).
129
-
130
- ## Built with URLCode
131
-
132
- [urlcode-shortener](https://github.com/jimhoyd-com/urlcode-shortener) is a
133
- standalone, account-free demo built on URLCode's public runtime and storage APIs.
134
- It combines short links that expire after one hour or less, QR downloads, and a
135
- shadcn/ui + Tailwind frontend. URLCode handles the page/assets and stored-link
136
- redirects; the application adds anonymous creation and its own limits.
137
-
138
- Read its [build retrospective](https://github.com/jimhoyd-com/urlcode-shortener/blob/main/docs/BUILD-RETROSPECTIVE.md)
139
- for what the runtime supplied, what the application still needed, and proposed
140
- improvements. The demo's license, hosting and production validation remain open;
141
- it does not change URLCode's Apache-2.0 license or guest isolation model.
142
-
143
- [urlcode-docs](https://github.com/jimhoyd-com/urlcode-docs) demonstrates URLCode
144
- hosting a static documentation site with shadcn/ui and Tailwind. It syncs this
145
- repository’s Markdown and examples at a pinned revision, applies templates through
146
- sandboxed middleware during the build, and serves the output through native
147
- page/static/download routes. This repository remains the documentation source of
148
- truth. See the [docs-site retrospective](https://github.com/jimhoyd-com/urlcode-docs/blob/main/docs/BUILD-RETROSPECTIVE.md)
149
- for reuse, integration work and upstream improvements. Hosting and a public domain
150
- are not yet selected; the original site-code license is pending.
151
-
152
165
  ## Start from YAML
153
166
 
154
167
  Already wrote `urlcode.yaml`? Run `urlcode scaffold --project ./my-links --dry-run`,
155
168
  then remove `--dry-run` to create missing modules, pages and directories. Existing
156
169
  files are preserved; code placeholders return 501 until implemented.
157
- [Scaffolding guide](docs/SCAFFOLDING.md).
158
- Live-link storage and the auth extension need a Node build whose SQLite is
159
- 3.51.3 or newer, 3.50.7 or 3.44.6. `urlcode doctor` reports `liveLinks`;
160
- everything else runs on any supported Node (22.13+ installed, 22.18+ to run
161
- the TypeScript source).
170
+ [Scaffolding guide](docs/SCAFFOLDING.md). Node 22.13+ installed, 22.18+ to run
171
+ the TypeScript source; the separate `urlcode-auth` extension may have its own
172
+ SQLite build requirement, unverified from this repository.
162
173
 
163
174
  ## Try it
164
175
 
@@ -204,9 +215,6 @@ and [middleware](docs/MIDDLEWARE.md).
204
215
 
205
216
  - **Pages, files, downloads:** `page`, `static`, `download` with MIME detection,
206
217
  ETags, ranges and safety limits. [Assets](docs/ASSETS.md).
207
- - **Live short links:** a `link` route on an optional SQLite store; create,
208
- update and delete without reloads through the CLI or the private management
209
- API. [Dynamic links](docs/DYNAMIC-LINKS.md).
210
218
  - **HTTP:** methods, validated path/query/header inputs, body limits, response
211
219
  headers and cookies. [HTTP](docs/HTTP.md).
212
220
  - **Policies and site conventions:** throttle, agents, security headers,
@@ -227,11 +235,13 @@ and [middleware](docs/MIDDLEWARE.md).
227
235
  Self-hosted Node process or container first. `@jimhoyd/urlcode/vercel` and
228
236
  `@jimhoyd/urlcode/aws` serve declarative projects as native handlers;
229
237
  `urlcode build --target cloudflare` compiles redirects and declared responses
230
- into a Worker. Each target refuses at activation or build time what it cannot
238
+ into a Worker; `urlcode build --target static` compiles redirects and static
239
+ files into plain objects and redirect metadata for S3 + CloudFront, with no
240
+ server at all. Each target refuses at activation or build time what it cannot
231
241
  run, with the route named. None has been exercised on its provider yet; the
232
242
  adapters have local conformance tests only. [Operations](docs/OPERATIONS.md),
233
243
  [capabilities](docs/CAPABILITIES.md), [Vercel](docs/VERCEL.md), [AWS](docs/AWS.md),
234
- [Cloudflare](docs/CLOUDFLARE.md).
244
+ [Cloudflare](docs/CLOUDFLARE.md), [static hosting](docs/STATIC.md).
235
245
 
236
246
  ## For AI agents
237
247
 
@@ -242,25 +252,18 @@ inspection, validation and conversion previews over stdio, and
242
252
  `--allow-authoring` adds project-confined authoring tools
243
253
  ([tooling](docs/TOOLING.md)).
244
254
 
245
- ## Documentation
246
-
247
- Full documentation lives in
248
- [urlcode-docs](https://github.com/jimhoyd-com/urlcode-docs). It is authored
249
- there directly, not generated from this repository, and it is where new guides,
250
- references and recipes belong.
251
-
252
- `docs/` in this repository is contributor and maintainer material — local
253
- development, CI, the release process, reviews and the generated field
254
- reference. Reader-facing pages still under `docs/` are being migrated.
255
-
256
255
  ## Built with URLCode
257
256
 
258
- [urlcode-short](https://github.com/jimhoyd-com/urlcode-short), an
259
- account-free short-link demo with a shadcn/ui front end, and
260
- [urlcode-docs](https://github.com/jimhoyd-com/urlcode-docs), a static
261
- documentation site rendered through sandboxed middleware at build time. Both are
262
- ordinary consumers of the public runtime; their retrospectives list what the
263
- runtime supplied and what they still had to build.
257
+ Two applications were built on the public runtime as ordinary consumers, and
258
+ both have since been retired: `urlcode-docs`, a static documentation site
259
+ rendered through its own middleware at build time and served through native
260
+ page/static/download routes, and `urlcode-short`, an account-free short-link
261
+ demo combining expiring links, QR downloads and a shadcn/ui frontend — URLCode
262
+ supplied the pages, assets and routing, the application supplied anonymous
263
+ creation, link storage and its own limits. `urlcode-short`'s repository is
264
+ deleted, so its build retrospective is no longer reachable; what it recorded
265
+ about the gap between the runtime and a real application is carried in
266
+ [principles and open decisions](docs/OPEN-DECISIONS.md) and [roadmap](ROADMAP.md).
264
267
 
265
268
  ## License and contributing
266
269