@jimhoyd/urlcode 0.3.0 → 0.4.0-alpha.1
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 +106 -0
- package/.claude/skills/urlcode-operations/SKILL.md +114 -0
- package/.claude-plugin/marketplace.json +18 -0
- package/CONTRIBUTING.md +30 -2
- package/README.md +157 -230
- package/ROADMAP.md +85 -2
- package/SECURITY.md +8 -1
- package/dist/BUILD-MANIFEST.json +62 -32
- 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/bulk.js +37 -0
- package/dist/capabilities.js +208 -0
- package/dist/capability-query.js +72 -0
- package/dist/catalog.js +105 -0
- package/dist/cli.js +154 -15
- package/dist/client-address.js +1 -1
- package/dist/compliance-rules/baseline.js +8 -8
- package/dist/compliance-rules/privacy.js +3 -3
- package/dist/compliance-rules/strict.js +5 -5
- package/dist/conditions.js +88 -0
- package/dist/config.js +60 -4
- package/dist/context.js +156 -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 +132 -0
- package/dist/extensions.js +172 -0
- package/dist/function-sources.js +15 -3
- package/dist/index.js +37 -0
- package/dist/init-with.js +165 -0
- package/dist/interchange-cli.js +42 -0
- package/dist/interchange.js +189 -0
- package/dist/link-cli.js +1 -1
- package/dist/management-policy.js +0 -1
- package/dist/manifest.js +111 -0
- package/dist/match.js +2 -2
- package/dist/mcp-authoring.js +147 -0
- package/dist/mcp.js +97 -0
- package/dist/observability.js +6 -0
- package/dist/operator-host.js +29 -0
- package/dist/plugins.js +12 -0
- package/dist/policies/agents.js +2 -2
- package/dist/policies/compression.js +2 -1
- package/dist/policies/security.js +0 -0
- package/dist/policies.js +1 -1
- package/dist/policy.js +29 -7
- 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 +5 -5
- package/dist/recipes.js +41 -0
- package/dist/route-diff.js +106 -0
- package/dist/router.js +42 -2
- package/dist/runtime.js +95 -14
- package/dist/schema-query.js +62 -0
- package/dist/signals.js +24 -0
- package/dist/site.js +0 -0
- package/dist/tooling.js +96 -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/bulk.d.ts +27 -0
- package/dist/types/capabilities.d.ts +55 -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/strict.d.ts +0 -5
- package/dist/types/conditions.d.ts +19 -0
- package/dist/types/config.d.ts +20 -2
- package/dist/types/context.d.ts +65 -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 +122 -0
- package/dist/types/function-sources.d.ts +5 -0
- package/dist/types/index.d.ts +33 -0
- 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/link-cli.d.ts +2 -1
- package/dist/types/management-policy.d.ts +0 -1
- package/dist/types/manifest.d.ts +81 -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 +2 -0
- 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 -1
- package/dist/types/provider-verification.d.ts +53 -0
- package/dist/types/proxy.d.ts +21 -0
- package/dist/types/readiness.d.ts +1 -1
- package/dist/types/recipes.d.ts +30 -0
- package/dist/types/route-diff.d.ts +27 -0
- package/dist/types/runtime.d.ts +11 -0
- package/dist/types/schema-query.d.ts +12 -0
- 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/types.d.ts +57 -0
- 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 +21 -2
- package/dist/typescript-authoring.js +104 -0
- package/dist/vercel.js +4 -3
- package/dist/verify-deployment.js +270 -0
- package/docs/AI-AUTHORING.md +130 -8
- package/docs/BULK.md +79 -0
- package/docs/CAPABILITIES.md +179 -0
- package/docs/CAPACITY.md +1 -1
- package/docs/CI.md +142 -0
- package/docs/CONDITIONS.md +74 -0
- package/docs/DEPLOYMENT-CHECKS.md +108 -0
- package/docs/DYNAMIC-LINKS.md +18 -518
- package/docs/EGRESS.md +125 -0
- package/docs/EXTENSIONS.md +226 -0
- package/docs/FRAMEWORK.md +182 -0
- package/docs/INSTALL.md +45 -7
- package/docs/INTERCHANGE.md +134 -0
- package/docs/MIDDLEWARE-EXAMPLES.md +75 -0
- package/docs/MIDDLEWARE.md +2 -0
- package/docs/NEXT-PHASE-PLAN.md +90 -0
- package/docs/NEXT-STEPS.md +415 -0
- package/docs/OBSERVABILITY.md +4 -2
- package/docs/OPERATIONAL-PROOF.md +4 -1
- package/docs/OPERATIONS.md +6 -3
- package/docs/PLUGINS.md +37 -0
- package/docs/POLICIES.md +12 -309
- package/docs/PRERENDER.md +40 -0
- package/docs/PROJECT-DIRECTION.md +42 -0
- package/docs/PROVIDER-VERIFICATION.md +84 -0
- package/docs/READINESS.md +21 -1
- package/docs/README.md +82 -31
- package/docs/RECIPES.md +99 -0
- package/docs/RELEASE-READINESS.md +11 -9
- package/docs/RELEASE-SECURITY.md +27 -4
- package/docs/SECURITY-AUDIT.md +1 -1
- package/docs/SPECIFICATION.md +95 -8
- package/docs/SPIKE-BUSINESS-SUITE.md +1013 -0
- package/docs/SPIKE-EXTENSION-MODEL.md +419 -0
- package/docs/SPIKE-EXTENSIONS.md +1 -0
- package/docs/SPIKE-LAMBDA-COMPILE.md +199 -0
- package/docs/STANDARDS.md +150 -142
- package/docs/STARTERS.md +21 -1
- package/docs/TOOLING.md +291 -0
- package/docs/TYPESCRIPT-AUTHORING.md +67 -0
- package/docs/TYPESCRIPT.md +1 -1
- package/docs/USABILITY-REVIEW.md +123 -0
- package/docs/YAML-GUIDE.md +18 -479
- package/docs/YAML-REFERENCE.md +127 -16
- package/docs/links/cli.md +110 -0
- package/docs/links/limits.md +175 -0
- package/docs/links/management-api.md +80 -0
- package/docs/links/pools.md +75 -0
- package/docs/links/setup.md +135 -0
- package/docs/policies/agents.md +1 -1
- 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/links.md +30 -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 +19 -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 +16 -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/live-links/example.yaml +21 -0
- package/examples/monitoring/example.yaml +8 -0
- 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 +2709 -0
- package/llms.txt +48 -19
- package/package.json +29 -7
- package/packaging/claude-plugin/.claude-plugin/plugin.json +19 -0
- package/packaging/claude-plugin/skills/urlcode-authoring/SKILL.md +106 -0
- package/packaging/claude-plugin/skills/urlcode-operations/SKILL.md +114 -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 +19 -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 +16 -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 +7 -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 +16 -0
- package/recipes/webhook-receiver/functions/receive.mjs +16 -0
- package/recipes/webhook-receiver/recipe.yaml +26 -0
- package/recipes/webhook-receiver/tests/requests.json +59 -0
- package/recipes/webhook-receiver/urlcode.yaml +16 -0
- package/schemas/recipe.schema.json +138 -0
- package/schemas/urlcode.schema.json +656 -80
- package/skills/urlcode/SKILL.md +98 -0
- package/starters/default/.github/workflows/urlcode.yml +23 -0
- package/starters/default/.mcp.json +12 -0
- package/starters/default/AGENTS.md +79 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: urlcode
|
|
3
|
+
description: Work on a URLCode project, recognized by a urlcode.yaml file with version "1" and served by the @jimhoyd/urlcode runtime. Use this skill whenever a task touches urlcode.yaml, its included route files, functions or middleware under a URLCode project, or asks to add, change, test or deploy URL behavior (redirects, responses, pages, files, functions, live links, policies) in such a project. It teaches the authoring loop and how to retrieve the minimum reference from the installed runtime instead of guessing fields.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# URLCode authoring loop
|
|
7
|
+
|
|
8
|
+
A URLCode project declares URL behavior in YAML; the installed runtime serves
|
|
9
|
+
it. Your job is to change the declaration and the minimal guest code it names,
|
|
10
|
+
then prove the change with the runtime's own checks. Never reimplement what the
|
|
11
|
+
runtime provides, and never invent fields.
|
|
12
|
+
|
|
13
|
+
## 1. Recognize the project
|
|
14
|
+
|
|
15
|
+
- The root has `urlcode.yaml` with `version: "1"`. Included route files are
|
|
16
|
+
listed under `includes`; functions, middleware and assets are referenced from
|
|
17
|
+
the project root.
|
|
18
|
+
- Read the project's `AGENTS.md` first if present; it lists the handlers,
|
|
19
|
+
policies and commands this runtime version supports.
|
|
20
|
+
- Find the runtime: `urlcode` on the PATH, or
|
|
21
|
+
`node node_modules/@jimhoyd/urlcode/dist/cli.js`, or
|
|
22
|
+
`node /path/to/urlcode/src/cli.ts` for a source checkout. Use one form for
|
|
23
|
+
every command below.
|
|
24
|
+
|
|
25
|
+
## 2. Retrieve the minimum, do not read everything
|
|
26
|
+
|
|
27
|
+
If the project carries `.mcp.json` (written by `urlcode init`) and your client
|
|
28
|
+
has registered the `urlcode` server, prefer its tools over reading documents:
|
|
29
|
+
`get_context` (project summary, constraints, exact commands), `get_capability`
|
|
30
|
+
and `get_schema` (one capability or YAML fragment), `search_recipes`,
|
|
31
|
+
`explain` (a route's effective behavior) and `get_manifest`. The server is
|
|
32
|
+
read-only; `--allow-authoring` is an operator opt-in you never add yourself.
|
|
33
|
+
Without the server, run the CLI equivalents and read only the output:
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
urlcode context --project DIR # get_context: summary, constraints, commands
|
|
37
|
+
urlcode capabilities # what this version implements, per target
|
|
38
|
+
urlcode capabilities --target NAME # before promising a provider deployment
|
|
39
|
+
urlcode capabilities NAME # get_capability: one capability's contract
|
|
40
|
+
urlcode schema PATH # get_schema: one YAML fragment
|
|
41
|
+
urlcode recipes search TEXT # search_recipes
|
|
42
|
+
urlcode explain PATH --project DIR # explain: a route's effective behavior
|
|
43
|
+
urlcode manifest --project DIR # get_manifest
|
|
44
|
+
urlcode recipes list # bundled starting points
|
|
45
|
+
urlcode recipes show NAME # one recipe's files, inline
|
|
46
|
+
urlcode routes --project DIR # the routes the project already has
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
When a field or handler is unclear, ask the runtime, not memory:
|
|
50
|
+
`urlcode validate --local` names the rejected field and the route. The
|
|
51
|
+
installed package also ships `docs/YAML-REFERENCE.md` (generated field
|
|
52
|
+
inventory) and `schemas/urlcode.schema.json`; search them for the one key you
|
|
53
|
+
need rather than reading them whole.
|
|
54
|
+
|
|
55
|
+
## 3. Prefer YAML, then a recipe, then a function
|
|
56
|
+
|
|
57
|
+
1. If a native handler expresses the behavior (`redirect`, `respond`, `page`,
|
|
58
|
+
`static`, `download`, `link`, `proxy`, `conditional`), write YAML only.
|
|
59
|
+
2. If a recipe from `recipes list` is close, `urlcode recipes add NAME --out DIR`
|
|
60
|
+
and adapt the copy into the project's layout.
|
|
61
|
+
3. Only then write a function or middleware: one exported handler, relative
|
|
62
|
+
ES-module imports inside the project only, inputs from validated `args`,
|
|
63
|
+
output as a `Response`. The sandbox has no `fetch`, Node, filesystem or
|
|
64
|
+
timers; a need for them is a `proxy` route, a binding, or a report.
|
|
65
|
+
4. Never build routing, validation, middleware chains, policies, static
|
|
66
|
+
serving, caching, throttling or authentication in code. Declare them.
|
|
67
|
+
|
|
68
|
+
Keep every route you were not asked to change. Match the file organization the
|
|
69
|
+
project already uses.
|
|
70
|
+
|
|
71
|
+
## 4. Prove it
|
|
72
|
+
|
|
73
|
+
```sh
|
|
74
|
+
urlcode validate --local --project DIR
|
|
75
|
+
urlcode test --project DIR
|
|
76
|
+
urlcode audit --project DIR --expect-routes N
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Add fixtures to `tests/requests.json` for each new route: positive and negative
|
|
80
|
+
cases, every active method, `HEAD`. Update `N` deliberately when routes are
|
|
81
|
+
added or removed, and update any `--expect-routes` in the project's README,
|
|
82
|
+
Makefile or CI workflow to match. A failing validation names the route; fix
|
|
83
|
+
the declaration rather than working around it.
|
|
84
|
+
|
|
85
|
+
## 5. Grants, secrets and what to report
|
|
86
|
+
|
|
87
|
+
- A function that needs a secret or environment value declares a named `env`
|
|
88
|
+
or `secrets` binding in YAML and stops there. The operator grants it outside
|
|
89
|
+
the project, pinned to the project revision. Never create, edit or approve a
|
|
90
|
+
grant, policy file or host file, and never put a value in the project.
|
|
91
|
+
- Secrets stay out of YAML, functions, fixtures, unignored `.env` files and
|
|
92
|
+
commit messages.
|
|
93
|
+
- When the runtime cannot express a requirement (the validator rejects it,
|
|
94
|
+
`capabilities` marks it refused for the target, or it needs guest network
|
|
95
|
+
or persistence), report exactly that with the route and capability named.
|
|
96
|
+
Do not invent fields, degrade silently or claim a workaround is equivalent.
|
|
97
|
+
- Report the three commands' results as the evidence. They are not a
|
|
98
|
+
deployment, a soak test or a security review.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Validates, tests and audits this project on every push and pull request, and
|
|
2
|
+
# comments a route-inventory diff on pull requests. See
|
|
3
|
+
# https://github.com/jimhoyd-com/urlcode/blob/main/docs/CI.md
|
|
4
|
+
name: urlcode
|
|
5
|
+
on:
|
|
6
|
+
push:
|
|
7
|
+
pull_request:
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
pull-requests: write # the sticky route-diff comment; drop it to only log the diff
|
|
11
|
+
jobs:
|
|
12
|
+
check:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
timeout-minutes: 10
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
17
|
+
with:
|
|
18
|
+
persist-credentials: false
|
|
19
|
+
# Pin to a release tag or commit of the runtime you depend on.
|
|
20
|
+
- uses: jimhoyd-com/urlcode/action@main
|
|
21
|
+
with:
|
|
22
|
+
expect-routes: 2 # update when adding or removing routes
|
|
23
|
+
compliance: baseline
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Working on this project
|
|
2
|
+
|
|
3
|
+
This project uses URLCode: URL behavior is declared in `urlcode.yaml`, and the
|
|
4
|
+
installed `@jimhoyd/urlcode` runtime serves it. There is no framework code to
|
|
5
|
+
write for routing, validation, middleware wiring, policies, static serving or
|
|
6
|
+
authentication; the runtime provides them. Read this file before changing anything.
|
|
7
|
+
|
|
8
|
+
## Before writing code
|
|
9
|
+
|
|
10
|
+
1. Inspect `urlcode.yaml` first, then every file its `includes` list names,
|
|
11
|
+
the referenced functions, middleware and `tests/requests.json`. Preserve the
|
|
12
|
+
existing organization and every route you were not asked to change.
|
|
13
|
+
2. Run `urlcode capabilities` to see what this runtime version implements and
|
|
14
|
+
which targets support it; `urlcode capabilities --target NAME` before
|
|
15
|
+
promising any provider deployment.
|
|
16
|
+
3. Run `urlcode recipes list` and `urlcode recipes show NAME` before writing a
|
|
17
|
+
route from scratch. If a recipe covers the need, add it with
|
|
18
|
+
`urlcode recipes add NAME --out DIR` and adapt the copy.
|
|
19
|
+
4. Prefer YAML over code. Prefer native handlers over functions.
|
|
20
|
+
|
|
21
|
+
## Ask the runtime through MCP first
|
|
22
|
+
|
|
23
|
+
`.mcp.json` registers the read-only `urlcode mcp` server. When it is
|
|
24
|
+
available, prefer its tools over reading documents: `get_context`,
|
|
25
|
+
`get_capability`, `get_schema`, `search_recipes`, `explain`, `get_manifest`.
|
|
26
|
+
The CLI equivalents are the fallback: `urlcode context`, `urlcode capabilities NAME`,
|
|
27
|
+
`urlcode schema PATH`, `urlcode recipes search TEXT`, `urlcode explain PATH`,
|
|
28
|
+
`urlcode manifest`. `--allow-authoring` is an operator opt-in; never add it yourself.
|
|
29
|
+
|
|
30
|
+
## What the runtime provides (this version)
|
|
31
|
+
|
|
32
|
+
- Handlers, exactly one per route: `redirect`, `respond`, `page`, `static`, `download`, `function`, `link`, `proxy`, `conditional`, `extension`.
|
|
33
|
+
- Ordered `middleware` around any handler, declared in YAML, run in the sandbox.
|
|
34
|
+
- Validated inputs: `parameters`, `request.body` and `methods` on the route;
|
|
35
|
+
functions receive validated `args`, never raw user input.
|
|
36
|
+
- Policies, host-enforced and off by default: `agents`, `throttle`, `cache`, `security`, `compression`.
|
|
37
|
+
- Site conventions under `site`, each generating one native route: `robots` (/robots.txt), `sitemap` (/sitemap.xml), `favicon` (/favicon.ico), `securityTxt` (/.well-known/security.txt), `llms` (/llms.txt).
|
|
38
|
+
- Bindings: named `env` and `secrets` references resolved by the operator, never values in YAML.
|
|
39
|
+
|
|
40
|
+
Never recreate any of these in a function. If a requirement seems to need one
|
|
41
|
+
of them and it is missing, that is a report, not an invitation to reimplement.
|
|
42
|
+
|
|
43
|
+
## Functions and middleware are sandboxed
|
|
44
|
+
|
|
45
|
+
Guest code runs in an isolated JavaScript engine with a fresh heap per call.
|
|
46
|
+
It sees a text/JSON `Request`/`Response` subset, validated `args` and granted
|
|
47
|
+
`env`. There is no `fetch`, no Node API, no filesystem, no timers and no
|
|
48
|
+
imports outside the project. Do not write code that needs them; declare a
|
|
49
|
+
`proxy` route or a binding instead and say why.
|
|
50
|
+
|
|
51
|
+
## Checks that count as evidence
|
|
52
|
+
|
|
53
|
+
```sh
|
|
54
|
+
urlcode validate --local
|
|
55
|
+
urlcode test
|
|
56
|
+
urlcode audit --expect-routes 2
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Run all three after every change. Update the expected route count deliberately
|
|
60
|
+
when you add or remove a route, and add fixtures to `tests/requests.json` for
|
|
61
|
+
every new route (positive and negative cases, every active method, HEAD).
|
|
62
|
+
Without a global install, invoke `node /path/to/urlcode/src/cli.ts` instead of `urlcode`.
|
|
63
|
+
|
|
64
|
+
## Rules
|
|
65
|
+
|
|
66
|
+
- Report unsupported requirements instead of inventing fields. The schema is
|
|
67
|
+
exact; a field the validator rejects does not exist. Say what is missing.
|
|
68
|
+
- Never create or approve operator grants. Request a named binding in YAML and
|
|
69
|
+
stop; the operator grants it outside this project, pinned to the revision.
|
|
70
|
+
- Secrets stay out of the project: no keys, tokens or credentials in YAML,
|
|
71
|
+
functions, fixtures, `.env` files that are not ignored, or commit messages.
|
|
72
|
+
- Authentication is host processing: declare `auth` on the route, never build
|
|
73
|
+
login forms, sessions or password checks in functions.
|
|
74
|
+
- Validation, tests and the audit are the evidence. Local checks are not a
|
|
75
|
+
deployment, a soak test or a security review; do not claim otherwise.
|
|
76
|
+
|
|
77
|
+
The installed package ships an agent skill with the same loop at
|
|
78
|
+
`skills/urlcode/SKILL.md` inside `@jimhoyd/urlcode` (for example
|
|
79
|
+
`node_modules/@jimhoyd/urlcode/skills/urlcode/SKILL.md`).
|