@jimhoyd/urlcode 0.3.0 → 0.4.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/skills/urlcode-authoring/SKILL.md +122 -0
- package/.claude/skills/urlcode-operations/SKILL.md +108 -0
- package/.claude-plugin/marketplace.json +18 -0
- package/CONTRIBUTING.md +30 -2
- package/README.md +195 -255
- package/ROADMAP.md +143 -15
- package/SECURITY.md +31 -9
- package/dist/BUILD-MANIFEST.json +72 -47
- package/dist/adapters.js +4 -23
- package/dist/agent-lists.js +1 -1
- package/dist/agents-guide.js +113 -0
- package/dist/authoring-files.js +60 -0
- package/dist/authoring.js +11 -1
- package/dist/aws.js +4 -3
- package/dist/build-cloudflare.js +11 -24
- package/dist/build-static.js +134 -0
- package/dist/bulk.js +37 -0
- package/dist/capabilities.js +262 -0
- package/dist/capability-query.js +71 -0
- package/dist/catalog.js +105 -0
- package/dist/cli.js +165 -34
- package/dist/client-address.js +1 -1
- package/dist/compliance-rules/baseline.js +9 -17
- package/dist/compliance-rules/privacy.js +7 -18
- package/dist/compliance-rules/shared.js +0 -2
- package/dist/compliance-rules/strict.js +5 -5
- package/dist/compliance.js +6 -8
- package/dist/conditions.js +88 -0
- package/dist/config.js +69 -6
- package/dist/context.js +155 -0
- package/dist/ecosystem-cli.js +88 -0
- package/dist/egress.js +98 -0
- package/dist/examples.js +92 -0
- package/dist/explain-cli.js +64 -0
- package/dist/explain.js +131 -0
- package/dist/extensions.js +231 -0
- package/dist/function-sources.js +49 -5
- package/dist/function-worker.js +3 -1
- package/dist/functions.js +84 -13
- package/dist/guest-api.js +29 -3
- package/dist/index.js +40 -6
- package/dist/init-with.js +165 -0
- package/dist/interchange-cli.js +42 -0
- package/dist/interchange.js +189 -0
- package/dist/manifest.js +109 -0
- package/dist/match.js +2 -2
- package/dist/mcp-authoring.js +147 -0
- package/dist/mcp.js +97 -0
- package/dist/observability.js +7 -21
- package/dist/operator-host.js +29 -0
- package/dist/plugins.js +12 -0
- package/dist/policies/agents.js +2 -2
- package/dist/policies/cache.js +8 -3
- package/dist/policies/compression.js +2 -1
- package/dist/policies/security.js +0 -0
- package/dist/policies.js +1 -1
- package/dist/policy.js +56 -15
- package/dist/prerender.js +100 -41
- package/dist/project-tests.js +3 -3
- package/dist/provider-verification.js +92 -0
- package/dist/proxy.js +44 -0
- package/dist/readiness.js +34 -11
- package/dist/recipes.js +41 -0
- package/dist/route-diff.js +106 -0
- package/dist/router.js +45 -7
- package/dist/runtime.js +164 -64
- package/dist/sandbox.js +48 -0
- package/dist/scaffold.js +0 -0
- package/dist/schema-query.js +62 -0
- package/dist/scripts/operational-drills.js +12 -54
- package/dist/server.js +3 -29
- package/dist/signals.js +24 -0
- package/dist/site.js +0 -0
- package/dist/tooling.js +96 -0
- package/dist/trusted-functions.js +210 -0
- package/dist/types/adapters.d.ts +7 -4
- package/dist/types/agent-lists.d.ts +0 -1
- package/dist/types/agents-guide.d.ts +17 -0
- package/dist/types/authoring-files.d.ts +10 -0
- package/dist/types/aws.d.ts +3 -1
- package/dist/types/build-cloudflare.d.ts +1 -0
- package/dist/types/build-static.d.ts +43 -0
- package/dist/types/bulk.d.ts +27 -0
- package/dist/types/capabilities.d.ts +64 -0
- package/dist/types/capability-query.d.ts +24 -0
- package/dist/types/catalog.d.ts +65 -0
- package/dist/types/client-address.d.ts +0 -1
- package/dist/types/compliance-rules/baseline.d.ts +1 -9
- package/dist/types/compliance-rules/privacy.d.ts +1 -4
- package/dist/types/compliance-rules/shared.d.ts +0 -2
- package/dist/types/compliance-rules/strict.d.ts +0 -5
- package/dist/types/compliance.d.ts +0 -3
- package/dist/types/conditions.d.ts +19 -0
- package/dist/types/config.d.ts +21 -2
- package/dist/types/context.d.ts +66 -0
- package/dist/types/ecosystem-cli.d.ts +17 -0
- package/dist/types/egress.d.ts +46 -0
- package/dist/types/examples.d.ts +50 -0
- package/dist/types/explain-cli.d.ts +11 -0
- package/dist/types/explain.d.ts +95 -0
- package/dist/types/extensions.d.ts +177 -0
- package/dist/types/function-sources.d.ts +9 -0
- package/dist/types/functions.d.ts +48 -5
- package/dist/types/guest-api.d.ts +1 -0
- package/dist/types/index.d.ts +36 -6
- package/dist/types/init-with.d.ts +30 -0
- package/dist/types/interchange-cli.d.ts +16 -0
- package/dist/types/interchange.d.ts +42 -0
- package/dist/types/manifest.d.ts +79 -0
- package/dist/types/match.d.ts +1 -0
- package/dist/types/mcp-authoring.d.ts +92 -0
- package/dist/types/mcp.d.ts +12 -0
- package/dist/types/observability.d.ts +3 -14
- package/dist/types/operator-host.d.ts +8 -0
- package/dist/types/plugins.d.ts +2 -0
- package/dist/types/policies/agents.d.ts +0 -2
- package/dist/types/policies/compression.d.ts +2 -0
- package/dist/types/policies/security.d.ts +0 -1
- package/dist/types/policy.d.ts +15 -4
- package/dist/types/project-tests.d.ts +3 -2
- package/dist/types/provider-verification.d.ts +53 -0
- package/dist/types/proxy.d.ts +21 -0
- package/dist/types/readiness.d.ts +10 -3
- package/dist/types/recipes.d.ts +30 -0
- package/dist/types/route-diff.d.ts +27 -0
- package/dist/types/router.d.ts +2 -1
- package/dist/types/runtime.d.ts +11 -27
- package/dist/types/sandbox.d.ts +12 -0
- package/dist/types/scaffold.d.ts +0 -2
- package/dist/types/schema-query.d.ts +12 -0
- package/dist/types/server.d.ts +1 -4
- package/dist/types/signals.d.ts +25 -0
- package/dist/types/site.d.ts +0 -1
- package/dist/types/tooling.d.ts +115 -0
- package/dist/types/trusted-functions.d.ts +29 -0
- package/dist/types/types.d.ts +71 -7
- package/dist/types/typescript-authoring.d.ts +12 -0
- package/dist/types/vercel.d.ts +3 -1
- package/dist/types/verify-deployment.d.ts +47 -0
- package/dist/types.js +37 -5
- package/dist/typescript-authoring.js +142 -0
- package/dist/vercel.js +4 -3
- package/dist/verify-deployment.js +270 -0
- package/docs/AI-AUTHORING.md +232 -15
- package/docs/AWS.md +4 -4
- package/docs/BEST-PRACTICES.md +3 -2
- package/docs/BULK.md +79 -0
- package/docs/CAPABILITIES.md +192 -0
- package/docs/CAPACITY.md +129 -32
- package/docs/CI.md +142 -0
- package/docs/CLOUDFLARE.md +1 -2
- package/docs/COMPLIANCE.md +6 -9
- package/docs/CONDITIONS.md +74 -0
- package/docs/DEPLOYMENT-CHECKS.md +108 -0
- package/docs/EGRESS.md +125 -0
- package/docs/EXTENSIONS.md +398 -0
- package/docs/FRAMEWORK.md +198 -0
- package/docs/FUNCTION-SECURITY.md +129 -32
- package/docs/INSTALL.md +45 -12
- package/docs/INTERCHANGE.md +134 -0
- package/docs/LOAD-TESTING.md +4 -4
- package/docs/MIDDLEWARE-EXAMPLES.md +75 -0
- package/docs/MIDDLEWARE.md +29 -16
- package/docs/MONITORING.md +2 -19
- package/docs/NEXT-PHASE-PLAN.md +98 -0
- package/docs/NEXT-STEPS.md +634 -0
- package/docs/OBSERVABILITY.md +11 -18
- package/docs/OPEN-DECISIONS.md +212 -0
- package/docs/OPERATIONAL-PROOF.md +30 -31
- package/docs/OPERATIONS.md +29 -35
- package/docs/PLUGINS.md +37 -0
- package/docs/POLICIES.md +23 -309
- package/docs/PRERENDER.md +41 -1
- package/docs/PROJECT-DIRECTION.md +75 -8
- package/docs/PROVIDER-VERIFICATION.md +84 -0
- package/docs/READINESS.md +21 -1
- package/docs/README.md +87 -34
- package/docs/RECIPES.md +99 -0
- package/docs/RELEASE-READINESS.md +57 -35
- package/docs/RELEASE-SECURITY.md +116 -7
- package/docs/RESILIENCE.md +16 -15
- package/docs/ROUTING.md +8 -10
- package/docs/SANDBOX-REVIEW.md +19 -6
- package/docs/SCAFFOLDING.md +0 -2
- package/docs/SECURITY-AUDIT.md +41 -1
- package/docs/SPECIFICATION.md +150 -29
- package/docs/SPIKE-AI-FRAMEWORK-BENCHMARK.md +287 -0
- package/docs/SPIKE-BUSINESS-SUITE.md +1021 -0
- package/docs/SPIKE-CORE-LAYERING.md +337 -0
- package/docs/SPIKE-DEFAULT-TRUST-MODEL.md +209 -0
- package/docs/SPIKE-EXTENSION-MODEL.md +419 -0
- package/docs/SPIKE-EXTENSIONS.md +6 -0
- package/docs/SPIKE-LAMBDA-COMPILE.md +201 -0
- package/docs/SPIKE-MONOREPO.md +322 -0
- package/docs/STANDARDS.md +150 -142
- package/docs/STARTERS.md +21 -1
- package/docs/STATIC.md +94 -0
- package/docs/TOOLING.md +295 -0
- package/docs/TUNNELS.md +0 -3
- package/docs/TYPESCRIPT-AUTHORING.md +82 -0
- package/docs/TYPESCRIPT.md +25 -4
- package/docs/USABILITY-REVIEW.md +129 -0
- package/docs/VERCEL.md +4 -5
- package/docs/VERSION-ALIGNMENT.md +205 -0
- package/docs/YAML-GUIDE.md +15 -479
- package/docs/YAML-REFERENCE.md +143 -22
- package/docs/policies/agents.md +1 -1
- package/docs/policies/cache.md +13 -0
- package/docs/policies/contract.md +52 -0
- package/docs/policies/hardened.md +56 -0
- package/docs/policies/interoperability.md +169 -0
- package/docs/policies/operations.md +45 -0
- package/docs/yaml/assets.md +36 -0
- package/docs/yaml/conditions.md +20 -0
- package/docs/yaml/functions.md +160 -0
- package/docs/yaml/middleware.md +29 -0
- package/docs/yaml/organization.md +74 -0
- package/docs/yaml/policies.md +37 -0
- package/docs/yaml/redirects.md +64 -0
- package/docs/yaml/responses.md +57 -0
- package/docs/yaml/site.md +24 -0
- package/examples/assets/example.yaml +17 -0
- package/examples/aws/example.yaml +20 -0
- package/examples/cloudflare/example.yaml +19 -0
- package/examples/compliance/example.yaml +11 -0
- package/examples/conditions/README.md +12 -0
- package/examples/conditions/example.yaml +19 -0
- package/examples/conditions/tests/requests.json +13 -0
- package/examples/conditions/urlcode.yaml +24 -0
- package/examples/cookbook/README.md +8 -4
- package/examples/cookbook/example.yaml +17 -0
- package/examples/cookbook/functions/catalog.mjs +3 -0
- package/examples/cookbook/functions/fail.mjs +4 -0
- package/examples/cookbook/functions/items.mjs +3 -0
- package/examples/cookbook/functions/profile.mjs +3 -0
- package/examples/cookbook/functions/resource.mjs +3 -0
- package/examples/cookbook/functions/status.mjs +3 -0
- package/examples/cookbook/middleware/auth.mjs +48 -0
- package/examples/cookbook/middleware/body.mjs +15 -0
- package/examples/cookbook/middleware/bucket.mjs +29 -0
- package/examples/cookbook/middleware/cors.mjs +21 -0
- package/examples/cookbook/middleware/debug.mjs +13 -0
- package/examples/cookbook/middleware/envelope.mjs +11 -0
- package/examples/cookbook/middleware/errors.mjs +11 -0
- package/examples/cookbook/middleware/etag.mjs +18 -0
- package/examples/cookbook/middleware/locale.mjs +20 -0
- package/examples/cookbook/middleware/maintenance.mjs +10 -0
- package/examples/cookbook/middleware/methods.mjs +15 -0
- package/examples/cookbook/middleware/negotiate.mjs +20 -0
- package/examples/cookbook/middleware/referer.mjs +12 -0
- package/examples/cookbook/middleware/request-id.mjs +16 -0
- package/examples/cookbook/route-index.json +676 -0
- package/examples/cookbook/routes/middleware.yaml +126 -0
- package/examples/cookbook/tests/requests.json +526 -0
- package/examples/cookbook/urlcode.yaml +1 -0
- package/examples/egress/README.md +22 -0
- package/examples/egress/example.yaml +19 -0
- package/examples/egress/urlcode.yaml +19 -0
- package/examples/extensions/README.md +7 -0
- package/examples/extensions/example.yaml +21 -0
- package/examples/extensions/urlcode.yaml +25 -0
- package/examples/monitoring/example.yaml +8 -0
- package/examples/prerender/README.md +2 -2
- package/examples/prerender/example.yaml +16 -0
- package/examples/provider-conformance/README.md +12 -0
- package/examples/provider-conformance/example.yaml +14 -0
- package/examples/provider-conformance/urlcode.yaml +34 -0
- package/examples/tunnel/example.yaml +8 -0
- package/examples/vercel/example.yaml +19 -0
- package/llms-full.txt +3084 -0
- package/llms.txt +61 -21
- package/package.json +36 -7
- package/packaging/claude-plugin/.claude-plugin/plugin.json +19 -0
- package/packaging/claude-plugin/skills/urlcode-authoring/SKILL.md +122 -0
- package/packaging/claude-plugin/skills/urlcode-operations/SKILL.md +108 -0
- package/recipes/authenticated-json-api/README.md +51 -0
- package/recipes/authenticated-json-api/functions/profile.mjs +5 -0
- package/recipes/authenticated-json-api/recipe.yaml +34 -0
- package/recipes/authenticated-json-api/tests/requests.json +39 -0
- package/recipes/authenticated-json-api/urlcode.yaml +12 -0
- package/recipes/contact-form/README.md +25 -0
- package/recipes/contact-form/functions/contact.mjs +17 -0
- package/recipes/contact-form/recipe.yaml +33 -0
- package/recipes/contact-form/tests/requests.json +47 -0
- package/recipes/contact-form/urlcode.yaml +18 -0
- package/recipes/cors-api/README.md +16 -0
- package/recipes/cors-api/functions/items.mjs +3 -0
- package/recipes/cors-api/middleware/cors.mjs +21 -0
- package/recipes/cors-api/recipe.yaml +26 -0
- package/recipes/cors-api/tests/requests.json +65 -0
- package/recipes/cors-api/urlcode.yaml +12 -0
- package/recipes/health-page/README.md +13 -0
- package/recipes/health-page/recipe.yaml +23 -0
- package/recipes/health-page/tests/requests.json +36 -0
- package/recipes/health-page/urlcode.yaml +19 -0
- package/recipes/json-api/README.md +6 -0
- package/recipes/json-api/functions/echo.mjs +3 -0
- package/recipes/json-api/recipe.yaml +25 -0
- package/recipes/json-api/tests/requests.json +34 -0
- package/recipes/json-api/urlcode.yaml +12 -0
- package/recipes/middleware/README.md +34 -0
- package/recipes/middleware/functions/catalog.mjs +3 -0
- package/recipes/middleware/functions/fail.mjs +4 -0
- package/recipes/middleware/functions/items.mjs +3 -0
- package/recipes/middleware/functions/profile.mjs +3 -0
- package/recipes/middleware/functions/resource.mjs +3 -0
- package/recipes/middleware/functions/status.mjs +3 -0
- package/recipes/middleware/middleware/auth.mjs +48 -0
- package/recipes/middleware/middleware/body.mjs +15 -0
- package/recipes/middleware/middleware/bucket.mjs +29 -0
- package/recipes/middleware/middleware/cors.mjs +21 -0
- package/recipes/middleware/middleware/debug.mjs +13 -0
- package/recipes/middleware/middleware/envelope.mjs +11 -0
- package/recipes/middleware/middleware/errors.mjs +11 -0
- package/recipes/middleware/middleware/etag.mjs +18 -0
- package/recipes/middleware/middleware/locale.mjs +20 -0
- package/recipes/middleware/middleware/maintenance.mjs +10 -0
- package/recipes/middleware/middleware/methods.mjs +15 -0
- package/recipes/middleware/middleware/negotiate.mjs +20 -0
- package/recipes/middleware/middleware/referer.mjs +12 -0
- package/recipes/middleware/middleware/request-id.mjs +16 -0
- package/recipes/middleware/public/guide.txt +1 -0
- package/recipes/middleware/recipe.yaml +50 -0
- package/recipes/middleware/tests/requests.json +528 -0
- package/recipes/middleware/urlcode.yaml +127 -0
- package/recipes/protected-download/README.md +22 -0
- package/recipes/protected-download/files/report.txt +1 -0
- package/recipes/protected-download/recipe.yaml +31 -0
- package/recipes/protected-download/tests/requests.json +32 -0
- package/recipes/protected-download/urlcode.yaml +15 -0
- package/recipes/redirect/README.md +7 -0
- package/recipes/redirect/recipe.yaml +25 -0
- package/recipes/redirect/tests/requests.json +19 -0
- package/recipes/redirect/urlcode.yaml +9 -0
- package/recipes/static-plus-api/README.md +15 -0
- package/recipes/static-plus-api/functions/info.mjs +3 -0
- package/recipes/static-plus-api/public/assets/index.html +3 -0
- package/recipes/static-plus-api/public/assets/site.css +1 -0
- package/recipes/static-plus-api/public/index.html +8 -0
- package/recipes/static-plus-api/recipe.yaml +29 -0
- package/recipes/static-plus-api/tests/requests.json +56 -0
- package/recipes/static-plus-api/urlcode.yaml +23 -0
- package/recipes/typescript/README.md +8 -0
- package/recipes/typescript/functions/hello.ts +5 -0
- package/recipes/typescript/recipe.yaml +23 -0
- package/recipes/typescript/tests/requests.json +18 -0
- package/recipes/typescript/urlcode.yaml +5 -0
- package/recipes/webhook-receiver/README.md +20 -0
- package/recipes/webhook-receiver/functions/receive.mjs +16 -0
- package/recipes/webhook-receiver/recipe.yaml +27 -0
- package/recipes/webhook-receiver/tests/requests.json +59 -0
- package/recipes/webhook-receiver/urlcode.yaml +23 -0
- package/schemas/recipe.schema.json +139 -0
- package/schemas/urlcode.schema.json +659 -110
- package/skills/urlcode/SKILL.md +119 -0
- package/starters/default/.github/workflows/urlcode.yml +23 -0
- package/starters/default/.mcp.json +12 -0
- package/starters/default/AGENTS.md +79 -0
- package/starters/default/urlcode.yaml +0 -1
- package/dist/link-api.js +0 -136
- package/dist/link-cli.js +0 -141
- package/dist/link-events.js +0 -76
- package/dist/link-records.js +0 -31
- package/dist/link-store-worker.js +0 -150
- package/dist/link-store.js +0 -250
- package/dist/management-policy.js +0 -41
- package/dist/sqlite-version.js +0 -6
- package/dist/types/link-api.d.ts +0 -30
- package/dist/types/link-cli.d.ts +0 -36
- package/dist/types/link-events.d.ts +0 -27
- package/dist/types/link-records.d.ts +0 -11
- package/dist/types/link-store-worker.d.ts +0 -1
- package/dist/types/link-store.d.ts +0 -130
- package/dist/types/management-policy.d.ts +0 -9
- package/dist/types/sqlite-version.d.ts +0 -1
- package/docs/DYNAMIC-LINKS.md +0 -561
- package/docs/MANAGEMENT-SECURITY.md +0 -82
- package/examples/live-links/README.md +0 -11
- package/examples/live-links/tests/requests.json +0 -6
- package/examples/live-links/urlcode.yaml +0 -16
package/ROADMAP.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# Public roadmap
|
|
2
2
|
|
|
3
3
|
URLCode is a portable runtime for programmable URL behavior, not a URL
|
|
4
|
-
shortener.
|
|
4
|
+
shortener. Stored short links are an operator-installed extension, not a core
|
|
5
|
+
handler. The
|
|
5
6
|
[project direction](docs/PROJECT-DIRECTION.md) explains how application
|
|
6
7
|
projects and provider adapters fit without redefining or restricting the free
|
|
7
8
|
runtime.
|
|
@@ -11,6 +12,121 @@ separate late phase. The stable 0.1 self-hosted release covers much of M0/M1 plu
|
|
|
11
12
|
process/container packaging and benchmarks. Provider adapters and the remaining
|
|
12
13
|
production-readiness gates remain open.
|
|
13
14
|
|
|
15
|
+
## 0.4.0-alpha.2 — current alpha
|
|
16
|
+
|
|
17
|
+
`0.4.0-alpha.2` is a behavior-changing release on top of `0.4.0-alpha.1`:
|
|
18
|
+
**`function` and `middleware` routes now run trusted and unsandboxed by
|
|
19
|
+
default** — in the host process, with full Node/filesystem/network access,
|
|
20
|
+
exactly like any other project code — instead of always dispatching through
|
|
21
|
+
the QuickJS/WebAssembly worker pool. Sandboxing is now an explicit per-route
|
|
22
|
+
opt-in via `sandbox: true`; a route that declares it gets exactly the
|
|
23
|
+
isolation every earlier alpha provided, unchanged. See
|
|
24
|
+
[docs/SPIKE-DEFAULT-TRUST-MODEL.md](docs/SPIKE-DEFAULT-TRUST-MODEL.md) for
|
|
25
|
+
the maintainer's decision and rationale, and
|
|
26
|
+
[docs/FUNCTION-SECURITY.md](docs/FUNCTION-SECURITY.md) for the resulting
|
|
27
|
+
contract of both execution modes.
|
|
28
|
+
|
|
29
|
+
**This changes existing projects with no YAML edit.** Every `function`/
|
|
30
|
+
`middleware` route that does not declare `sandbox` — which, before this
|
|
31
|
+
release, meant every such route in every existing project — now runs trusted
|
|
32
|
+
instead of sandboxed the moment the runtime is upgraded to `0.4.0-alpha.2` or
|
|
33
|
+
later. Binding grants (`env`/`secrets`) are unaffected: a route still
|
|
34
|
+
receives only what it declares and an operator policy pins to the project
|
|
35
|
+
revision, whether trusted or sandboxed. Review which of your project's
|
|
36
|
+
`function`/`middleware` routes handle input or code you would not otherwise
|
|
37
|
+
trust with full Node/filesystem/network access, and add `sandbox: true` to
|
|
38
|
+
those specifically (docs/AI-AUTHORING.md's "Deciding when a route needs
|
|
39
|
+
`sandbox: true`") before upgrading a project that relies on the old,
|
|
40
|
+
always-sandboxed behavior. An operator policy pinned to a project's revision
|
|
41
|
+
is invalidated by this upgrade regardless of whether the project's own YAML
|
|
42
|
+
changed, since the project hash includes the trust-model-affecting change;
|
|
43
|
+
re-derive and re-approve it (`urlcode permissions`) after upgrading.
|
|
44
|
+
|
|
45
|
+
## 0.4.0-alpha.1
|
|
46
|
+
|
|
47
|
+
`0.4.0-alpha.1` is the first alpha of the extension contract and the agent
|
|
48
|
+
tooling on top of the `0.3.0` self-hosted release. It carries: the
|
|
49
|
+
revision-pinned extension contract, capabilities and provider conformance,
|
|
50
|
+
strict redirect interchange, bulk import, recipes and search, TypeScript
|
|
51
|
+
guests, conditions, bounded proxy and signals, MCP read and authoring modes,
|
|
52
|
+
the `context`, `explain`, `manifest` and `schema` queries, short forms,
|
|
53
|
+
route-level auth, `init --with`, the agent benchmark harness, `llms-full`,
|
|
54
|
+
and the generated `AGENTS.md` and skill. It is an alpha: provider
|
|
55
|
+
deployments, soak and independent security review remain open. The
|
|
56
|
+
extension packages declare `@jimhoyd/urlcode >=0.4.0-alpha.1 <0.5.0` and
|
|
57
|
+
are published after core.
|
|
58
|
+
|
|
59
|
+
## Extensions: accounts, administration and presentation — implemented, unreleased
|
|
60
|
+
|
|
61
|
+
The runtime now carries a generic, revision-pinned extension contract
|
|
62
|
+
(`@jimhoyd/urlcode/extensions`, [extensions](docs/EXTENSIONS.md)): a project
|
|
63
|
+
declares versioned `extensions.<name>` blocks, exclusive `extension` mounts and
|
|
64
|
+
`policies.extensions` requirements; the operator supplies the implementations
|
|
65
|
+
in a host file loaded with `--host-file`, outside the project. Guest requests
|
|
66
|
+
never see `Cookie`, `Authorization` or declared credential headers. Cloudflare
|
|
67
|
+
refuses extensions until its artifact format can run them.
|
|
68
|
+
|
|
69
|
+
The implementations live in their own repositories, each with an
|
|
70
|
+
implementation-status file that is the authoritative feature list:
|
|
71
|
+
[urlcode-auth](https://github.com/jimhoyd-com/urlcode-auth) (accounts, sessions,
|
|
72
|
+
MFA, roles, account page, operator CLI), [urlcode-admin](https://github.com/jimhoyd-com/urlcode-admin)
|
|
73
|
+
(users, sessions, roles, audit, approvals, cases, impersonation) and
|
|
74
|
+
[urlcode-ui](https://github.com/jimhoyd-com/urlcode-ui) (escaped templates,
|
|
75
|
+
partials, themes, translations). All three are Apache-2.0 and published to
|
|
76
|
+
npm as `0.1.0-alpha.1` while first-release acceptance is reviewed; see
|
|
77
|
+
[issue 58](https://github.com/jimhoyd-com/urlcode/issues/58) for what remains:
|
|
78
|
+
browser and device WebAuthn coverage, accessibility assessment, soak, backup
|
|
79
|
+
and recovery drills on a deployment, live provider senders and independent
|
|
80
|
+
security review. [The framework](docs/FRAMEWORK.md) describes how the four
|
|
81
|
+
packages compose, and [next steps](docs/NEXT-STEPS.md) is the phased plan to
|
|
82
|
+
close the remaining gaps.
|
|
83
|
+
|
|
84
|
+
## Capability foundation — implemented, unreleased
|
|
85
|
+
|
|
86
|
+
`urlcode capabilities [--target self-hosted|cloudflare|aws|vercel] [--json]`
|
|
87
|
+
and the public capability API centralize target support for handlers, bindings
|
|
88
|
+
and effective policies. Runtime activation and Cloudflare builds use the shared
|
|
89
|
+
preflight; unknown targets fail closed and unsupported requirements identify the
|
|
90
|
+
route and capability before resources or artifacts are created. The existing
|
|
91
|
+
compiled route IR is documented, not replaced. Configuration-dependent and
|
|
92
|
+
delegated behavior remain explicit; all provider deployments remain unverified.
|
|
93
|
+
See [capabilities](docs/CAPABILITIES.md) and the
|
|
94
|
+
[next-phase review and implementation status](docs/NEXT-PHASE-PLAN.md).
|
|
95
|
+
|
|
96
|
+
## Portability and URL behavior — implemented, unreleased
|
|
97
|
+
|
|
98
|
+
Strict redirect interchange supports CSV/JSON/YAML, Netlify and Cloudflare
|
|
99
|
+
`_redirects`, a bounded Netlify TOML subset and Vercel redirects. Conversion
|
|
100
|
+
reports refuse unsupported semantics; provider differences require explicit
|
|
101
|
+
acknowledgment and are never called lossless. A synthetic conformance fixture
|
|
102
|
+
and bounded HTTPS runner distinguish local adapter tests from observed
|
|
103
|
+
provider deployments. Actual Cloudflare/AWS/Vercel deployment evidence remains
|
|
104
|
+
pending; this does not complete M4.
|
|
105
|
+
|
|
106
|
+
Exact query/header/cookie/origin/method conditions and disjoint conditional
|
|
107
|
+
redirect/response cases run in the self-hosted, AWS and Vercel runtimes.
|
|
108
|
+
Cloudflare refuses these until its compiler can preserve their semantics.
|
|
109
|
+
Self-hosted proxy and webhook signals use explicit revision-pinned operator
|
|
110
|
+
origin grants, connection-pinned public DNS and bounded transport. Signals
|
|
111
|
+
have no durable delivery or retry guarantee. Other targets refuse proxy and
|
|
112
|
+
signals. See [conditions](docs/CONDITIONS.md), [egress](docs/EGRESS.md),
|
|
113
|
+
[interchange](docs/INTERCHANGE.md) and
|
|
114
|
+
[provider verification](docs/PROVIDER-VERIFICATION.md).
|
|
115
|
+
|
|
116
|
+
## Developer ecosystem — implemented, unreleased
|
|
117
|
+
|
|
118
|
+
Bundled Git-owned recipes, safe bulk imports into route includes, build-time
|
|
119
|
+
TypeScript guest transpilation, read-only inspection APIs and optional stdio
|
|
120
|
+
MCP tooling are available. The runtime still executes only JavaScript, and
|
|
121
|
+
TypeScript authoring adds no execution mode: transpilation happens at build
|
|
122
|
+
time, is not type checking, and a `sandbox: true` route's emitted JavaScript
|
|
123
|
+
runs inside QuickJS/WASM exactly as before. Bulk benchmarks
|
|
124
|
+
successfully cover 1,000, 10,000 and 100,000 routes without relaxing parser
|
|
125
|
+
limits. See [recipes](docs/RECIPES.md), [bulk evidence](docs/BULK.md),
|
|
126
|
+
[TypeScript authoring](docs/TYPESCRIPT-AUTHORING.md) and
|
|
127
|
+
[SDK/MCP](docs/TOOLING.md). These features do not supply durable signals,
|
|
128
|
+
protected downloads, a remote marketplace or provider deployment proof.
|
|
129
|
+
|
|
14
130
|
## TypeScript source and shipped declarations — implemented, unreleased
|
|
15
131
|
|
|
16
132
|
The runtime, scripts, tests and benchmarks are TypeScript under a strict
|
|
@@ -57,9 +173,10 @@ deployment returns byte-identical status, body and headers to the self-hosted
|
|
|
57
173
|
server. Bindings arrive through a `URLCODE_POLICY` environment variable holding
|
|
58
174
|
the same revision-pinned grant document the operator policy file carries.
|
|
59
175
|
|
|
60
|
-
Native handlers only:
|
|
61
|
-
|
|
62
|
-
|
|
176
|
+
Native handlers only: `function` and `middleware` routes are refused at
|
|
177
|
+
activation, trusted or sandboxed alike, because they need the self-hosted Node
|
|
178
|
+
lifecycle and a sandboxed one would pay worker and WASM startup on every cold
|
|
179
|
+
start. The
|
|
63
180
|
`@jimhoyd/urlcode/aws` does the same for a Lambda Function URL or API Gateway HTTP API.
|
|
64
181
|
Payload format 2.0 only: format 1.0 supplies an already-decoded path and query,
|
|
65
182
|
and this runtime rejects ambiguous encoding deliberately, so rebuilding a target
|
|
@@ -78,7 +195,7 @@ generation, so it gets a compiler rather than an adapter: `urlcode build
|
|
|
78
195
|
validators, and `@jimhoyd/urlcode/cloudflare` serves them with the same matching, request
|
|
79
196
|
policy and response policy as every other host. Declarative routes only —
|
|
80
197
|
redirects and declared responses with parameters, defaults, validation, response
|
|
81
|
-
headers, `enabled` and `expires`. Functions, middleware,
|
|
198
|
+
headers, `enabled` and `expires`. Functions, middleware, assets and
|
|
82
199
|
bindings are refused at build time with the route named, so an unsupported
|
|
83
200
|
project fails the build instead of the deployment. Bindings are refused even as
|
|
84
201
|
literals, because a build artifact must never carry a secret.
|
|
@@ -119,18 +236,25 @@ does not cover.
|
|
|
119
236
|
|
|
120
237
|
## Hardening checkpoint — alpha.8
|
|
121
238
|
|
|
122
|
-
Bound HTTP admission and inactive sockets,
|
|
123
|
-
|
|
239
|
+
Bound HTTP admission and inactive sockets, and correct management
|
|
240
|
+
defaults/method responses.
|
|
124
241
|
The [readiness register](docs/RELEASE-READINESS.md) distinguishes tested safeguards
|
|
125
242
|
from deployment and stable-release gates. Feature breadth does not imply stability.
|
|
126
243
|
|
|
127
|
-
## Live short links — alpha.8
|
|
244
|
+
## Live short links — alpha.8 (removed from core, superseded)
|
|
128
245
|
|
|
129
246
|
Implemented an optional native `link` handler, local SQLite persistence, CLI CRUD
|
|
130
|
-
and a separate authenticated management API. Links
|
|
131
|
-
changes/reloads; versioned writes
|
|
132
|
-
or network access
|
|
133
|
-
user accounts and provider adapters
|
|
247
|
+
and a separate authenticated management API. Links became visible without YAML
|
|
248
|
+
changes/reloads; versioned writes prevented silent lost updates. No guest storage
|
|
249
|
+
or network access was added. Same-host only; distributed storage, general state,
|
|
250
|
+
user accounts and provider adapters remained open.
|
|
251
|
+
|
|
252
|
+
This native `link` handler, its SQLite store, CLI and management API were
|
|
253
|
+
removed from core in the layering work that followed: stored short links are
|
|
254
|
+
moving to a future `urlcode-dynamic-link` extension package (mount-based, like
|
|
255
|
+
`auth`/`admin`, not yet published). A project that used `link`/`dynamicLinks`
|
|
256
|
+
needs that extension once it ships; there is no in-core replacement or
|
|
257
|
+
deprecation shim.
|
|
134
258
|
|
|
135
259
|
## Middleware — alpha.7
|
|
136
260
|
|
|
@@ -167,17 +291,21 @@ Implemented the page/static/download portion of M2: project-contained asset
|
|
|
167
291
|
snapshots, automatic MIME types, attachment names, HEAD, cache validators and
|
|
168
292
|
single byte ranges. Dedicated public directories, symlink/hardlink rejection and
|
|
169
293
|
bounded memory are part of the contract. [Asset guide](docs/ASSETS.md).
|
|
170
|
-
Bulk tools,
|
|
294
|
+
Bulk tools, recipes and best-effort signals were added in the unreleased next-phase work above; they were not part of alpha.3.
|
|
171
295
|
|
|
172
296
|
## Security correction — 0.1.0-alpha.2
|
|
173
297
|
|
|
298
|
+
<!-- trust-model-prose: historical -->
|
|
174
299
|
All function code is untrusted. Node host execution has been replaced by
|
|
175
300
|
QuickJS/WebAssembly isolation with fresh invocation state, no ambient host or
|
|
176
301
|
network APIs, bounded resources, restricted module graphs and revision-pinned
|
|
177
302
|
operator binding policy. This protection is part of the free product. See the
|
|
178
303
|
[security model](docs/FUNCTION-SECURITY.md). Full Fetch/Node
|
|
179
304
|
API compatibility and network integrations were not part of that alpha and
|
|
180
|
-
remain outside the 0.1 contract.
|
|
305
|
+
remain outside the 0.1 contract. That default was superseded in
|
|
306
|
+
`0.4.0-alpha.2`, which made this isolation the per-route `sandbox: true`
|
|
307
|
+
opt-in instead (see
|
|
308
|
+
[docs/SPIKE-DEFAULT-TRUST-MODEL.md](docs/SPIKE-DEFAULT-TRUST-MODEL.md)).
|
|
181
309
|
|
|
182
310
|
## Earlier implementation checkpoint — 0.1.0-alpha.1
|
|
183
311
|
|
|
@@ -190,7 +318,7 @@ CI and a non-root container build are included. See the [contract](docs/SPECIFIC
|
|
|
190
318
|
and [operations guide](docs/OPERATIONS.md) for exact support and evidence limits.
|
|
191
319
|
|
|
192
320
|
Still open in the early contract: host namespaces, stable identity beyond paths,
|
|
193
|
-
|
|
321
|
+
fuller parameter vocabulary. Build-time TypeScript authoring and capability planning are now implemented in the unreleased work above.
|
|
194
322
|
No claims of complete M0/M1 or stable production readiness. M2–M4 work continues
|
|
195
323
|
in the order below; a few independently useful operational foundations shipped early.
|
|
196
324
|
|
package/SECURITY.md
CHANGED
|
@@ -1,13 +1,28 @@
|
|
|
1
1
|
# Security
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
Project `function`/`middleware` code is **trusted and unsandboxed by default**:
|
|
4
|
+
it runs directly in the host process, exactly like any other project code,
|
|
5
|
+
with full Node, filesystem and network access (docs/SPIKE-DEFAULT-TRUST-MODEL.md).
|
|
6
|
+
A route opts into isolation explicitly with `sandbox: true`, which dispatches
|
|
7
|
+
that route through the QuickJS/WebAssembly worker pool instead — unchanged
|
|
8
|
+
from the isolation this project has always provided, still the boundary to
|
|
9
|
+
reach for when a route's code specifically warrants it (input from a source
|
|
10
|
+
the project doesn't fully trust, a contribution nobody has reviewed, logic
|
|
11
|
+
handling an especially sensitive secret).
|
|
12
|
+
|
|
13
|
+
A `sandbox: true` guest has no Node, filesystem, shell, network or ambient
|
|
14
|
+
process-environment access. Each invocation gets fresh state and bounded
|
|
15
|
+
resources. Imports stay inside a snapshotted project module graph. Binding
|
|
16
|
+
grants — for a trusted route as much as a sandboxed one — come from operator
|
|
17
|
+
policy outside the project and are pinned to the configuration/code revision;
|
|
18
|
+
trusting a route's code by default does not grant it any `env`/`secrets` it
|
|
19
|
+
was not explicitly declared and pinned to receive. This is a claim about what
|
|
20
|
+
URLCode injects into `context.env`/`context.secrets` for a route, not an
|
|
21
|
+
access-control boundary on trusted code itself: a trusted (non-`sandbox`)
|
|
22
|
+
route runs with full Node access by design, so its own code can read
|
|
23
|
+
`process.env`, the filesystem or the network independently of anything the
|
|
24
|
+
binding grant declared or withheld. The grant only governs what URLCode hands
|
|
25
|
+
that code through `context`; it is not a restriction the code is confined to.
|
|
11
26
|
See the [security model and policy instructions](docs/FUNCTION-SECURITY.md).
|
|
12
27
|
|
|
13
28
|
The host/runtime and sandbox engine still require patching, independent review
|
|
@@ -16,6 +31,13 @@ execution platform. Authorized inputs/secrets can be exposed
|
|
|
16
31
|
by code receiving them; grant the minimum required authority. Do not deploy
|
|
17
32
|
older snapshots for untrusted functions; review and upgrade to the current revision.
|
|
18
33
|
|
|
34
|
+
Declarative proxy and signal handlers run in a separate bounded host transport;
|
|
35
|
+
they do not grant guest networking. They require per-route, per-purpose HTTPS
|
|
36
|
+
origin grants pinned to the project revision. Every connection checks public
|
|
37
|
+
addresses and pins DNS, refuses redirects, filters headers and limits resources.
|
|
38
|
+
See [egress semantics and limitations](docs/EGRESS.md). Build-time TypeScript
|
|
39
|
+
transpilation and read-only MCP do not execute project code in the host.
|
|
40
|
+
|
|
19
41
|
## Report a vulnerability privately
|
|
20
42
|
|
|
21
43
|
Use [GitHub private vulnerability reporting](https://github.com/jimhoyd-com/urlcode/security/advisories/new).
|
|
@@ -36,5 +58,5 @@ Bind loopback by default; protect public deployments with HTTPS, rate limits,
|
|
|
36
58
|
network controls and restricted operational endpoints. See [operations](docs/OPERATIONS.md).
|
|
37
59
|
|
|
38
60
|
See the [internal security reviews](docs/SECURITY-AUDIT.md) — most recently
|
|
39
|
-
2026-09-17 — for fixed findings and remaining gates. Use a current reviewed commit: the shared 0.
|
|
61
|
+
2026-09-17 — for fixed findings and remaining gates. Use a current reviewed commit: the shared 0.3.0
|
|
40
62
|
version label alone does not identify which hardening patches are present.
|
package/dist/BUILD-MANIFEST.json
CHANGED
|
@@ -1,60 +1,85 @@
|
|
|
1
1
|
{
|
|
2
|
-
"node": "v26.
|
|
2
|
+
"node": "v26.9.0",
|
|
3
3
|
"files": {
|
|
4
|
-
"dist/adapters.js": "
|
|
5
|
-
"dist/agent-lists.js": "
|
|
4
|
+
"dist/adapters.js": "a7153ec52f2ed7e0cdd8ed7d433504815f402ec53b2b1c3d38d0cf0e2fcf6509",
|
|
5
|
+
"dist/agent-lists.js": "35ab484198897501d011cb6cc00b5a6787192e19df29c97646e8c118fcc19eef",
|
|
6
|
+
"dist/agents-guide.js": "a76e9818ec995a349085a53e8badd3ef49734275557b50bc7dcbe995ce3d0e9f",
|
|
6
7
|
"dist/assets.js": "0833b093d2fe457ce68281110dc07d47914992753607741c13b339d92c76cf5c",
|
|
7
|
-
"dist/authoring.js": "
|
|
8
|
-
"dist/
|
|
9
|
-
"dist/
|
|
10
|
-
"dist/
|
|
11
|
-
"dist/
|
|
8
|
+
"dist/authoring-files.js": "ad32814f9ae9c549c6247396f982aa700d13a293cc0a589609eccc68f8965550",
|
|
9
|
+
"dist/authoring.js": "ec5240e8686c124f4601229b45f89ce112d9eeb9d35e3059fe55e93056c45209",
|
|
10
|
+
"dist/aws.js": "7d8e3a97b4f6dbefbd68da058f05192469d1efcaed5458b284863ebe462e060e",
|
|
11
|
+
"dist/build-cloudflare.js": "af4f49ad45287d7c4105bb84b1592b5b8e76c930f7159505338298f7c5fd5651",
|
|
12
|
+
"dist/build-static.js": "a2d2fcef3099805392da9140096d9843226bfb582dc046acf9a77f37b8a0d528",
|
|
13
|
+
"dist/bulk.js": "aac88d422bd9a7a341a421fb4e29ff5580b28d39250b7f1f5315ba20ae92da8a",
|
|
14
|
+
"dist/capabilities.js": "28dba05b3851b8b12b3c1b809af87b732f84d601c737afe9225abe429886e691",
|
|
15
|
+
"dist/capability-query.js": "ba148b27c6a60f8c895f13f26468b16c18ae0a5cddea26b602965c8efbba90ae",
|
|
16
|
+
"dist/catalog.js": "ab1c01c9296cc277d2bd4fd682aeb053656a7d9f91c61974f4b78feea0211de8",
|
|
17
|
+
"dist/cli.js": "f6097c246c6b9006df58e3463648013ec8837ab3296a8c294809313503be167a",
|
|
18
|
+
"dist/client-address.js": "9d0d01466aab23124330605c5a0e0f981f87c897858acfad909f546a63df165b",
|
|
12
19
|
"dist/cloudflare.js": "17b43b0a6b6a0ef8a893415c989e4ae3976d97cc966adbf897b785f9adc472e3",
|
|
13
|
-
"dist/compliance-rules/baseline.js": "
|
|
14
|
-
"dist/compliance-rules/privacy.js": "
|
|
15
|
-
"dist/compliance-rules/shared.js": "
|
|
16
|
-
"dist/compliance-rules/strict.js": "
|
|
17
|
-
"dist/compliance.js": "
|
|
20
|
+
"dist/compliance-rules/baseline.js": "6296dea6bcb9f9bb80ed6ed5ab2f456e7f74e6de2be5d2d98ca8c983fb4df3ab",
|
|
21
|
+
"dist/compliance-rules/privacy.js": "4cfb1c07d7df698c362dfc8761cd3bba893769e92d7fb0a3901e1c2d25e801f1",
|
|
22
|
+
"dist/compliance-rules/shared.js": "86fd6db6a93375689acc64975cbc394ce9452dea21ae5941e743f99822515995",
|
|
23
|
+
"dist/compliance-rules/strict.js": "73ee13c2f893acf20cc3d44bf054e58c1474dec52eafe0cf2ce7f4eb96a3bc53",
|
|
24
|
+
"dist/compliance.js": "29a18da3cefea94802ac7d817d1ab4e3674abd5c3ac4ef893cb8b01c6a23fb61",
|
|
25
|
+
"dist/conditions.js": "ff25e97da550a3bdd80af55522045669438aa31a77d2bc83ad602bcefdee0475",
|
|
18
26
|
"dist/config-worker.js": "bc2170d60c35f8d5de227cbfc4c5067dc61d7cbc5b98aed88e68a11797072da5",
|
|
19
|
-
"dist/config.js": "
|
|
27
|
+
"dist/config.js": "0cd82b4c407848f9c66e804a6dd4bf9a8a8503264e51584456578073e0f01921",
|
|
28
|
+
"dist/context.js": "549a53e4738b9c20a1ec55614027f758026fb5860bf4ac962ce22d7029e48df0",
|
|
29
|
+
"dist/ecosystem-cli.js": "1e71bacd53d6fa8c7857cfcce3c3012ce054771a434b78d1f39e892e32642edd",
|
|
30
|
+
"dist/egress.js": "2ae29fe2cb4590fd2f715abe6817db47fed2f50dd31f37946ecf42eafbb0dd9e",
|
|
20
31
|
"dist/errors.js": "a908e66496afebbdd632a8c159a6e14d23f8f38798a0b4342ca122f2511c6cde",
|
|
21
|
-
"dist/
|
|
22
|
-
"dist/
|
|
23
|
-
"dist/
|
|
24
|
-
"dist/
|
|
32
|
+
"dist/examples.js": "89ae2b764a688fe52acfb9b94d3d262d7742401ebd0ef10c9ebfc76edfa5631c",
|
|
33
|
+
"dist/explain-cli.js": "dd342b21a96fc97a11488ac3528793ba0f5d4744b74a1d99085e142c4737b69a",
|
|
34
|
+
"dist/explain.js": "9450d2699cbe65e5c078c443ba7a6cba95c748e75d455e05264083b3c93c92a2",
|
|
35
|
+
"dist/extensions.js": "fed2b394466a7d406f9edeaedb71d9da81e50e3150eb7d01f2e7659104afeac7",
|
|
36
|
+
"dist/function-sources.js": "16fad4abc81c7ee07b6cbcef2d23a9fc50e97a17cb4dde1db53469bbb555c96f",
|
|
37
|
+
"dist/function-worker.js": "35771790ada4e1b36d447d4967a5e6cf0b543f32944e4c904f5fbf8998e824a5",
|
|
38
|
+
"dist/functions.js": "0f09d1bd27eb655ceb5900a4a5e2b760d2028b02cb637a6a89a4eb5940828008",
|
|
39
|
+
"dist/guest-api.js": "49aec9ed72733ad119e63bcfcee18158dcc8ceb951e1823b8947f6407ff24afc",
|
|
25
40
|
"dist/header-validation.js": "465181dbb08ff05f52defdd29fda025c0c64589bf319fa87fa6d3ab4b68216d5",
|
|
26
41
|
"dist/http-policy.js": "4cb187642269078ddf3460a3f1813dc57878a616a6f8132ef8f8d3b4b91ebb56",
|
|
27
42
|
"dist/http-response.js": "5fc3bb9eb932a3fd2fbc72c361416a5f1439b8bf45b2be37baca1c6446abf40c",
|
|
28
|
-
"dist/index.js": "
|
|
29
|
-
"dist/
|
|
30
|
-
"dist/
|
|
31
|
-
"dist/
|
|
32
|
-
"dist/link-records.js": "ef67a58cd107db0c3ac1c0ffd7b32817553606cf69bb3002da4ca0138c272f69",
|
|
33
|
-
"dist/link-store-worker.js": "0080452bbada2154b923449cd14596579bde94ad5f8dab94ecc84aa0d59c089b",
|
|
34
|
-
"dist/link-store.js": "526cdbe1b917cc7a74fb6edbbf13717d823ace5b5d6a5f89bc91438056a10b37",
|
|
43
|
+
"dist/index.js": "7e9f6ec8a125e2dfd4230b2ecd17ac513c0153d778a57bbcee7a1a9cd9681f81",
|
|
44
|
+
"dist/init-with.js": "8371f568867ebdc6ab8e9aa762234ae2aa015865f46aa901254528e20d69b791",
|
|
45
|
+
"dist/interchange-cli.js": "35bd70ba8077af5c3e39404ff0e5d28707632090a59a90645141252449fd3f04",
|
|
46
|
+
"dist/interchange.js": "26789420af33344d9a08c00fe6b2708aa71994224df527b3075295be2151611e",
|
|
35
47
|
"dist/logging.js": "8ec57fea26983aa071b05fe15d680d6550b03488101163ed9666da674118cf31",
|
|
36
|
-
"dist/
|
|
37
|
-
"dist/match.js": "
|
|
38
|
-
"dist/
|
|
39
|
-
"dist/
|
|
40
|
-
"dist/
|
|
41
|
-
"dist/
|
|
42
|
-
"dist/
|
|
43
|
-
"dist/policies/
|
|
48
|
+
"dist/manifest.js": "977f0f1cbe4466f7fbd9f2a0745e016cb9ebae640bc264fba04b4d02f4dbaca9",
|
|
49
|
+
"dist/match.js": "53ebcc2cda529a8d07fb83f8cb69a1446036ffc1641af3c4bd45a55851bded28",
|
|
50
|
+
"dist/mcp-authoring.js": "5030f52ef9c7ebc7b97305fcce687eb0a0d6164e34fda87f8278135a1e6f3d65",
|
|
51
|
+
"dist/mcp.js": "e2d70f63481dc40aae60f7c27128e6a09ec370b69fd68aee8890bcc990f4f304",
|
|
52
|
+
"dist/observability.js": "f4b1ab496f051fe3ef2ed36b2b2e469c63a8940700e2df852e6ff2d9cccdd5ae",
|
|
53
|
+
"dist/operator-host.js": "e3dac9d43a83beb775202b4ab9eeeba7ac63cebfc5dcc669be38d825be587bd0",
|
|
54
|
+
"dist/plugins.js": "a61aa933cd9e1b41020b86fae78aa3a7f45f5313124aa11b50cb57898722385e",
|
|
55
|
+
"dist/policies/agents.js": "c1dbc1e90339f472eeeb2372f7f4637f59a5d210797ea680ac8120a02aa20c10",
|
|
56
|
+
"dist/policies/cache.js": "03f79b91694bb78a98de4473384e5110e1ae1c3c83d46f929495d03af04d9da1",
|
|
57
|
+
"dist/policies/compression.js": "800f3ae3b1a4c1fe58c3d9908364ea9d78f655ff50c7f7589f584378e7f194b0",
|
|
58
|
+
"dist/policies/security.js": "2b3bfdf82140156fea4b162adc28ee43ccd85c402fb200680dbb8d8706417420",
|
|
44
59
|
"dist/policies/throttle.js": "bbb0cb1c24cf70d0a1ac32fc0618efb6c44e5b5d42564842f9c585ff7e501603",
|
|
45
|
-
"dist/policies.js": "
|
|
46
|
-
"dist/policy.js": "
|
|
47
|
-
"dist/prerender.js": "
|
|
48
|
-
"dist/project-tests.js": "
|
|
49
|
-
"dist/
|
|
50
|
-
"dist/
|
|
51
|
-
"dist/
|
|
52
|
-
"dist/
|
|
53
|
-
"dist/
|
|
54
|
-
"dist/
|
|
55
|
-
"dist/
|
|
56
|
-
"dist/
|
|
57
|
-
"dist/
|
|
58
|
-
"dist/
|
|
60
|
+
"dist/policies.js": "23fa019b7bf1cdedcc5f7772d2f157e4b381a554bce9e84594c2be4a0f8f76b8",
|
|
61
|
+
"dist/policy.js": "33c527008fafe4af18243ba668d069517c20659150f9f1d1a5a1d076e8724f89",
|
|
62
|
+
"dist/prerender.js": "0386ea2411e00b9563b5349133f1d723947b01f837fa92d4c61a699c9cfb5cdb",
|
|
63
|
+
"dist/project-tests.js": "445eaa139d2f1a2534369cfdeef081ef518de03218a467e7c5c2059caf840270",
|
|
64
|
+
"dist/provider-verification.js": "ffcf9f05e8cb5f71ea46a97e279e8a613fdfdf9435ab02bd57af11e2680a9107",
|
|
65
|
+
"dist/proxy.js": "34107e59ac0dbbea090efa3cf5badf3226c5302ba25e8f8ff9b2b5596ed80e50",
|
|
66
|
+
"dist/readiness.js": "6ce69a005d7c45cf0ef97fa5eaba34279d43ebf28124eca18359d9db4f599808",
|
|
67
|
+
"dist/recipes.js": "11853f23e63c3c65c5bed03a278cde0349d28c9fa23266c9907a2df318bb5fc3",
|
|
68
|
+
"dist/route-diff.js": "eebac076a886ddfb2bf5b97ea09d81f888e7bb0063d482eddb8e5fef9acea107",
|
|
69
|
+
"dist/router.js": "cf831025d5ed6778d1d6a0e541177799794e76766c82084ded81d3e87317ca1e",
|
|
70
|
+
"dist/runtime.js": "0470dcab0774d2da3336e9ce76a4853757bf96081e52bd741f6b44c1bdd4161f",
|
|
71
|
+
"dist/sandbox.js": "c88c5aa5dd95b4f55f1ba62da7969ad66dbd97c30f72e5b5f2817a2098ac1c65",
|
|
72
|
+
"dist/scaffold.js": "3ef243aceca7ddf2780aa2c8c04ae17edd07682d3a418fd5d65ba00f5c762f14",
|
|
73
|
+
"dist/schema-query.js": "bfd1844acd8d54ac361115191fcfbaf828a67e223b9ec6e9c22f158761af149b",
|
|
74
|
+
"dist/server.js": "d878bc8f0d6a05f8fd25997cace3150e2ff4d44ee9c8f4b5530e29601e164be1",
|
|
75
|
+
"dist/signals.js": "b55e54efc8fb6703e08f2a1e808ec8e011bda67738db8ceadf1b248f695795be",
|
|
76
|
+
"dist/site.js": "c40a06a6f9e2d6d3bea94727783c115fed4309bb0190787f58434eed64cbde84",
|
|
77
|
+
"dist/tooling.js": "7409db98422325cd4181d073d645ea57debca0e54cb151123474b85f4d4ed7dc",
|
|
78
|
+
"dist/trusted-functions.js": "befd256848be786f97e372c6af0e05ac08a0c93baed38bf2470ea49bc00dd3e4",
|
|
79
|
+
"dist/types.js": "a1213d033b6a347c63e94685ab9056d8cd7a301d9c83150142afe0f3ab2c6536",
|
|
80
|
+
"dist/typescript-authoring.js": "27829098603029ab565174e540fb1d5ef68c1a923272b7186f64a362f5244872",
|
|
81
|
+
"dist/vercel.js": "a0da20c095d0c7fa8f579ed4dd5951e7a34191f8a72a57c5e782c9eab39f6f08",
|
|
82
|
+
"dist/verify-deployment.js": "0c2e68f3cf258a364728c801411df5284343bc01b75a64fe275ff84e397e998b",
|
|
83
|
+
"dist/scripts/operational-drills.js": "c26c406d28013cc554b25a5b6bf8baf4e71d5e67e50d866fae546f538a192317"
|
|
59
84
|
}
|
|
60
85
|
}
|
package/dist/adapters.js
CHANGED
|
@@ -1,19 +1,12 @@
|
|
|
1
|
+
|
|
1
2
|
import { createRuntime } from './runtime.js';
|
|
2
3
|
|
|
3
4
|
import { validatePolicy } from './policy.js';
|
|
4
5
|
import { ConfigError } from './errors.js';
|
|
5
|
-
|
|
6
6
|
|
|
7
7
|
/** The subset of process.env a hosted adapter reads. */
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
// Handlers a stateless per-request invocation cannot honour. Functions and
|
|
12
|
-
// middleware need worker threads and the WASM engine on every cold start;
|
|
13
|
-
// stored links need a durable writable file that instances share. Adapters
|
|
14
|
-
// refuse them identically, so a project's supported surface does not depend on
|
|
15
|
-
// which provider is serving it.
|
|
16
|
-
const unsupported = { function:'isolated functions', link:'stored live links' };
|
|
9
|
+
|
|
17
10
|
|
|
18
11
|
export function readPolicyFromEnvironment(environment ) {
|
|
19
12
|
if (!environment.URLCODE_POLICY) return undefined;
|
|
@@ -27,20 +20,8 @@ export function readPolicyFromEnvironment(environment )
|
|
|
27
20
|
|
|
28
21
|
// Activates a project for a native-handler-only host, refusing the whole
|
|
29
22
|
// deployment rather than letting individual routes fail at request time.
|
|
30
|
-
export async function activateNativeOnly(project , environment , { target
|
|
31
|
-
|
|
32
|
-
const refused = runtime.testPlan().inventory.flatMap(route => {
|
|
33
|
-
const reason = route.handler === undefined ? undefined : unsupported[route.handler];
|
|
34
|
-
return [
|
|
35
|
-
...(reason ? [`${route.path} uses ${reason}`] : []),
|
|
36
|
-
...(route.middleware ? [`${route.path} declares middleware`] : []),
|
|
37
|
-
];
|
|
38
|
-
});
|
|
39
|
-
if (refused.length) {
|
|
40
|
-
await runtime.close();
|
|
41
|
-
throw new ConfigError(`This adapter serves native handlers only: ${refused.join('; ')}`);
|
|
42
|
-
}
|
|
43
|
-
return runtime;
|
|
23
|
+
export async function activateNativeOnly(project , environment , { target, plugins, extensions, origin } ) {
|
|
24
|
+
return createRuntime(project, { permissions: readPolicyFromEnvironment(environment), environment, target, plugins, extensions, origin });
|
|
44
25
|
}
|
|
45
26
|
|
|
46
27
|
// Caches a successful activation for the life of the instance. A failure is not
|
package/dist/agent-lists.js
CHANGED
|
@@ -10,7 +10,7 @@ import { isListFile, isBundled, validatePattern } from './policies/agents.js';
|
|
|
10
10
|
//
|
|
11
11
|
// A list file is the schema data/agents/*.json uses: either an array of
|
|
12
12
|
// entries or `{ entries: [...] }`, each entry `{ name?, pattern, ... }`.
|
|
13
|
-
|
|
13
|
+
const MAX_LIST_ENTRIES = 4096;
|
|
14
14
|
|
|
15
15
|
function listPath(root , reference , routePattern ) {
|
|
16
16
|
assert(isListFile(reference) && !isAbsolute(reference), `${routePattern}: policies.agents list ${JSON.stringify(reference)} must be a project-relative path ending in .json`);
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { getCapabilities } from './capabilities.js';
|
|
2
|
+
|
|
3
|
+
import { registry } from './policies.js';
|
|
4
|
+
import { generatedPaths } from './site.js';
|
|
5
|
+
import { assert } from './errors.js';
|
|
6
|
+
|
|
7
|
+
/** Where the packaged agent skill lives, relative to the installed @jimhoyd/urlcode package. */
|
|
8
|
+
export const skillPath = 'skills/urlcode/SKILL.md';
|
|
9
|
+
/** The MCP registration file `urlcode init` writes beside the project (Claude Code and Codex read this shape). */
|
|
10
|
+
export const mcpConfigFile = '.mcp.json';
|
|
11
|
+
/**
|
|
12
|
+
* Renders `.mcp.json` registering the read-only `urlcode mcp` server for the project at `project`, relative
|
|
13
|
+
* to the file. `--allow-authoring` is deliberately absent: the operator adds it by hand when they want it.
|
|
14
|
+
*/
|
|
15
|
+
export function renderMcpConfig(project = '.') {
|
|
16
|
+
assert(/^[A-Za-z0-9_.-]+(?:\/[A-Za-z0-9_.-]+)*$/.test(project) && !project.split('/').includes('..'), 'MCP project path must be a relative path without ..');
|
|
17
|
+
return JSON.stringify({ mcpServers: { urlcode: { command: 'urlcode', args: ['mcp', '--project', project] } } }, null, 2) + '\n';
|
|
18
|
+
}
|
|
19
|
+
const handlerNames = ['redirect','respond','page','static','download','function','proxy','conditional','extension'];
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* The application-level AGENTS.md written by `urlcode init`. Built from the
|
|
23
|
+
* installed runtime's capability catalog, so it names only the handlers,
|
|
24
|
+
* policies and site keys this version implements. Under 80 lines by design.
|
|
25
|
+
*/
|
|
26
|
+
export function renderAgentsGuide({ routes } ) {
|
|
27
|
+
assert(Number.isInteger(routes) && routes >= 0 && routes <= 100000, 'Route count must be a non-negative integer');
|
|
28
|
+
const catalog = getCapabilities('self-hosted');
|
|
29
|
+
const native = new Set(catalog.capabilities.filter(row => row.targets['self-hosted']?.support === 'native').map(row => row.capability));
|
|
30
|
+
const handlers = handlerNames.filter(name => native.has(name));
|
|
31
|
+
const policies = Object.keys(registry).filter(name => native.has(`policies.${name}` ));
|
|
32
|
+
const site = Object.entries(generatedPaths).map(([key, path]) => `\`${key}\` (${path})`);
|
|
33
|
+
return `# Working on this project
|
|
34
|
+
|
|
35
|
+
This project uses URLCode: URL behavior is declared in \`urlcode.yaml\`, and the
|
|
36
|
+
installed \`@jimhoyd/urlcode\` runtime serves it. There is no framework code to
|
|
37
|
+
write for routing, validation, middleware wiring, policies, static serving or
|
|
38
|
+
authentication; the runtime provides them. Read this file before changing anything.
|
|
39
|
+
|
|
40
|
+
## Before writing code
|
|
41
|
+
|
|
42
|
+
1. Inspect \`urlcode.yaml\` first, then every file its \`includes\` list names,
|
|
43
|
+
the referenced functions, middleware and \`tests/requests.json\`. Preserve the
|
|
44
|
+
existing organization and every route you were not asked to change.
|
|
45
|
+
2. Run \`urlcode capabilities\` to see what this runtime version implements and
|
|
46
|
+
which targets support it; \`urlcode capabilities --target NAME\` before
|
|
47
|
+
promising any provider deployment.
|
|
48
|
+
3. Run \`urlcode recipes list\` and \`urlcode recipes show NAME\` before writing a
|
|
49
|
+
route from scratch. If a recipe covers the need, add it with
|
|
50
|
+
\`urlcode recipes add NAME --out DIR\` and adapt the copy.
|
|
51
|
+
4. Use URLCode's highest-level declarative features whenever possible. Generate custom code only when the framework cannot express the requirement. Check supported extensions and recipes first; explain any capability gap.
|
|
52
|
+
|
|
53
|
+
## Ask the runtime through MCP first
|
|
54
|
+
|
|
55
|
+
When present, \`${mcpConfigFile}\` registers the read-only \`urlcode mcp\` server. When it is
|
|
56
|
+
available, prefer its tools over reading documents: \`get_context\`,
|
|
57
|
+
\`get_capability\`, \`get_schema\`, \`search_recipes\`, \`explain\`, \`get_manifest\`.
|
|
58
|
+
The CLI equivalents are the fallback: \`urlcode context\`, \`urlcode capabilities NAME\`,
|
|
59
|
+
\`urlcode schema PATH\`, \`urlcode recipes search TEXT\`, \`urlcode explain PATH\`,
|
|
60
|
+
\`urlcode manifest\`. \`--allow-authoring\` is an operator opt-in; never add it yourself.
|
|
61
|
+
|
|
62
|
+
## What the runtime provides (this version)
|
|
63
|
+
|
|
64
|
+
- Handlers, exactly one per route: ${handlers.map(name => `\`${name}\``).join(', ')}.
|
|
65
|
+
- Ordered \`middleware\` around any handler, declared in YAML, trusted by default.
|
|
66
|
+
- Validated inputs: \`parameters\`, \`request.body\` and \`methods\` on the route;
|
|
67
|
+
functions receive validated \`args\`, never raw user input.
|
|
68
|
+
- Policies, host-enforced and off by default: ${policies.map(name => `\`${name}\``).join(', ')}.
|
|
69
|
+
- Site conventions under \`site\`, each generating one native route: ${site.join(', ')}.
|
|
70
|
+
- Bindings: named \`env\` and \`secrets\` references resolved by the operator, never values in YAML.
|
|
71
|
+
|
|
72
|
+
Never recreate any of these in a function; a missing one is a report, not an
|
|
73
|
+
invitation to reimplement it.
|
|
74
|
+
|
|
75
|
+
## Functions and middleware are trusted by default; sandbox is opt-in
|
|
76
|
+
|
|
77
|
+
A route's \`function\`/\`middleware\` code runs trusted, in-process, with full
|
|
78
|
+
Node/filesystem/\`fetch\` access, receiving only the declared/granted \`args\`
|
|
79
|
+
and \`env\`/\`secrets\`. Add \`sandbox: true\` when code warrants isolation
|
|
80
|
+
(untrusted input, an unreviewed contribution, an especially sensitive
|
|
81
|
+
secret): that route then gets a text/JSON subset only, no Node/filesystem/
|
|
82
|
+
outside imports — use \`proxy\`/a binding instead, and say why in \`description\`.
|
|
83
|
+
|
|
84
|
+
## Checks that count as evidence
|
|
85
|
+
|
|
86
|
+
\`\`\`sh
|
|
87
|
+
urlcode validate --local
|
|
88
|
+
urlcode test
|
|
89
|
+
urlcode audit --expect-routes ${routes}
|
|
90
|
+
\`\`\`
|
|
91
|
+
|
|
92
|
+
Run all three after every change, updating the route count deliberately and
|
|
93
|
+
adding \`tests/requests.json\` fixtures for every new route (positive/negative,
|
|
94
|
+
every active method, HEAD). No global install: use \`node /path/to/urlcode/src/cli.ts\`.
|
|
95
|
+
|
|
96
|
+
## Rules
|
|
97
|
+
|
|
98
|
+
- Report unsupported requirements instead of inventing fields. The schema is
|
|
99
|
+
exact; a field the validator rejects does not exist. Say what is missing.
|
|
100
|
+
- Never create or approve operator grants. Request a named binding in YAML and
|
|
101
|
+
stop; the operator grants it outside this project, pinned to the revision.
|
|
102
|
+
- Secrets stay out of the project: no keys, tokens or credentials in YAML,
|
|
103
|
+
functions, fixtures, \`.env\` files that are not ignored, or commit messages.
|
|
104
|
+
- Protect a route with \`auth: true\`/\`auth: { role: admin }\` where an \`auth\`
|
|
105
|
+
extension is declared; \`cache\` likewise expands to \`policies.cache\`.
|
|
106
|
+
- Validation, tests and the audit are the evidence. Local checks are not a
|
|
107
|
+
deployment, a soak test or a security review; do not claim otherwise.
|
|
108
|
+
|
|
109
|
+
The installed package ships an agent skill with the same loop at
|
|
110
|
+
\`${skillPath}\` inside \`@jimhoyd/urlcode\` (for example
|
|
111
|
+
\`node_modules/@jimhoyd/urlcode/${skillPath}\`).
|
|
112
|
+
`;
|
|
113
|
+
}
|