@jimhoyd/urlcode 0.4.2 → 0.4.6
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 +57 -14
- package/.claude/skills/urlcode-operations/SKILL.md +4 -0
- package/README.md +19 -15
- package/SECURITY.md +5 -3
- package/dist/BUILD-MANIFEST.json +30 -27
- package/dist/agent-context.js +82 -0
- package/dist/agents-guide.js +42 -42
- package/dist/authoring.js +12 -2
- package/dist/body-schema.js +159 -0
- package/dist/build-cloudflare.js +2 -0
- package/dist/capabilities.js +1 -1
- package/dist/cli.js +28 -12
- package/dist/config.js +74 -6
- package/dist/context.js +4 -6
- package/dist/errors.js +3 -1
- package/dist/examples.js +1 -1
- package/dist/extensions.js +60 -2
- package/dist/http-policy.js +19 -4
- package/dist/http-response.js +2 -2
- package/dist/init-with.js +71 -9
- package/dist/mcp.js +15 -2
- package/dist/pattern-guard.js +32 -0
- package/dist/policies/security.js +0 -0
- package/dist/project-tests.js +35 -11
- package/dist/readiness.js +184 -32
- package/dist/recipes.js +1 -1
- package/dist/router.js +17 -0
- package/dist/runtime.js +26 -3
- package/dist/scaffold.js +0 -0
- package/dist/server.js +26 -3
- package/dist/site.js +0 -0
- package/dist/tooling.js +2 -1
- package/dist/types/agent-context.d.ts +44 -0
- package/dist/types/authoring.d.ts +3 -1
- package/dist/types/body-schema.d.ts +58 -0
- package/dist/types/config.d.ts +10 -2
- package/dist/types/context.d.ts +1 -1
- package/dist/types/errors.d.ts +9 -1
- package/dist/types/examples.d.ts +1 -1
- package/dist/types/extensions.d.ts +47 -2
- package/dist/types/http-policy.d.ts +3 -0
- package/dist/types/init-with.d.ts +10 -1
- package/dist/types/pattern-guard.d.ts +10 -0
- package/dist/types/project-tests.d.ts +9 -0
- package/dist/types/readiness.d.ts +68 -0
- package/dist/types/recipes.d.ts +1 -1
- package/dist/types/runtime.d.ts +4 -0
- package/dist/types/server.d.ts +9 -1
- package/dist/types/tooling.d.ts +1 -0
- package/dist/types/types.d.ts +13 -0
- package/dist/types.js +10 -2
- package/dist/typescript-authoring.js +5 -3
- package/dist/verify-deployment.js +16 -10
- package/examples/body-validation/README.md +16 -0
- package/examples/body-validation/example.yaml +17 -0
- package/examples/body-validation/tests/requests.json +15 -0
- package/examples/body-validation/urlcode.yaml +34 -0
- package/examples/coverage-waiver/README.md +8 -0
- package/examples/coverage-waiver/example.yaml +16 -0
- package/examples/coverage-waiver/functions/notes.mjs +2 -0
- package/examples/coverage-waiver/tests/requests.json +3 -0
- package/examples/coverage-waiver/urlcode.yaml +10 -0
- package/examples/data-dir/README.md +39 -0
- package/examples/data-dir/data/welcome.txt +1 -0
- package/examples/data-dir/example.yaml +22 -0
- package/examples/data-dir/functions/note.mjs +18 -0
- package/examples/data-dir/tests/requests.json +6 -0
- package/examples/data-dir/urlcode.yaml +6 -0
- package/examples/lifecycle/README.md +15 -0
- package/examples/lifecycle/example.yaml +19 -0
- package/examples/lifecycle/functions/notes.mjs +29 -0
- package/examples/lifecycle/tests/requests.json +12 -0
- package/examples/lifecycle/urlcode.yaml +29 -0
- package/examples/not-found/README.md +10 -0
- package/examples/not-found/example.yaml +17 -0
- package/examples/not-found/public/404.html +3 -0
- package/examples/not-found/public/index.html +3 -0
- package/examples/not-found/tests/requests.json +7 -0
- package/examples/not-found/urlcode.yaml +7 -0
- package/examples/shared-blocks/README.md +11 -0
- package/examples/shared-blocks/example.yaml +17 -0
- package/examples/shared-blocks/tests/requests.json +7 -0
- package/examples/shared-blocks/urlcode.yaml +37 -0
- package/llms-full.txt +364 -49
- package/llms.txt +43 -5
- package/package.json +15 -22
- package/recipes/static-page/README.md +9 -0
- package/recipes/static-page/public/index.html +11 -0
- package/recipes/static-page/recipe.yaml +21 -0
- package/recipes/static-page/tests/requests.json +22 -0
- package/recipes/static-page/urlcode.yaml +7 -0
- package/recipes/static-plus-api/README.md +6 -0
- package/recipes/static-plus-api/urlcode.yaml +4 -0
- package/recipes/store-crud/README.md +53 -0
- package/recipes/store-crud/recipe.yaml +31 -0
- package/recipes/store-crud/tests/requests.json +18 -0
- package/recipes/store-crud/urlcode.yaml +18 -0
- package/schemas/urlcode.schema.json +125 -60
- package/skills/urlcode/SKILL.md +47 -27
- package/starters/default/AGENTS.md +43 -43
- package/starters/page/README.md +14 -0
- package/starters/page/public/index.html +12 -0
- package/starters/page/tests/requests.json +17 -0
- package/starters/page/urlcode.yaml +6 -0
- package/.claude-plugin/marketplace.json +0 -18
- package/CONTRIBUTING.md +0 -148
- package/ROADMAP.md +0 -70
- package/docs/AI-AUTHORING.md +0 -339
- package/docs/ASSETS.md +0 -107
- package/docs/AUTH-BACKUP.md +0 -32
- package/docs/AWS.md +0 -86
- package/docs/BEST-PRACTICES.md +0 -276
- package/docs/BULK.md +0 -79
- package/docs/CAPABILITIES.md +0 -192
- package/docs/CAPACITY.md +0 -305
- package/docs/CI-FOLLOWUP-2026-09-19.md +0 -97
- package/docs/CI-RELEASE-AUDIT-2026-09-19.md +0 -322
- package/docs/CI.md +0 -147
- package/docs/CLOUDFLARE.md +0 -109
- package/docs/CODEBASE-AUDIT-2026-09-20.md +0 -284
- package/docs/COMPLIANCE.md +0 -239
- package/docs/COMPOSING-A-SITE.md +0 -287
- package/docs/CONDITIONS.md +0 -74
- package/docs/CONTAINER-PROMOTION.md +0 -74
- package/docs/DEPLOYMENT-CHECKS.md +0 -108
- package/docs/DEVELOPMENT-PIPELINE.md +0 -304
- package/docs/EGRESS.md +0 -125
- package/docs/EXTENSIONS.md +0 -403
- package/docs/FRAMEWORK.md +0 -217
- package/docs/FUNCTION-SECURITY.md +0 -251
- package/docs/HTTP.md +0 -129
- package/docs/INSTALL.md +0 -128
- package/docs/INTERCHANGE.md +0 -134
- package/docs/LOAD-TESTING.md +0 -91
- package/docs/LOCAL-DEVELOPMENT.md +0 -102
- package/docs/MIDDLEWARE-EXAMPLES.md +0 -75
- package/docs/MIDDLEWARE.md +0 -102
- package/docs/MONITORING.md +0 -115
- package/docs/OBSERVABILITY.md +0 -222
- package/docs/OPEN-DECISIONS.md +0 -149
- package/docs/OPERATIONAL-PROOF.md +0 -41
- package/docs/OPERATIONS.md +0 -201
- package/docs/ORGANIZATION.md +0 -135
- package/docs/PERFORMANCE.md +0 -72
- package/docs/PLUGINS.md +0 -271
- package/docs/POLICIES.md +0 -211
- package/docs/PRERENDER.md +0 -245
- package/docs/PROJECT-DIRECTION.md +0 -118
- package/docs/PROVIDER-VERIFICATION.md +0 -84
- package/docs/READINESS.md +0 -153
- package/docs/README.md +0 -93
- package/docs/RECIPES.md +0 -99
- package/docs/RELEASE-0.4.0-alpha.3.md +0 -50
- package/docs/RELEASE-0.4.1.md +0 -73
- package/docs/RELEASE-0.4.2.md +0 -30
- package/docs/RELEASE-READINESS.md +0 -146
- package/docs/RELEASE-SECURITY.md +0 -100
- package/docs/RESILIENCE.md +0 -161
- package/docs/ROUTING.md +0 -92
- package/docs/SANDBOX-REVIEW.md +0 -72
- package/docs/SCAFFOLDING.md +0 -70
- package/docs/SECURITY-AUDIT.md +0 -164
- package/docs/SITE.md +0 -150
- package/docs/SPECIFICATION.md +0 -359
- package/docs/SPIKE-AI-FRAMEWORK-BENCHMARK.md +0 -288
- package/docs/SPIKE-BUSINESS-SUITE.md +0 -1029
- package/docs/SPIKE-CORE-LAYERING.md +0 -368
- package/docs/SPIKE-DEFAULT-TRUST-MODEL.md +0 -207
- package/docs/STANDARDS.md +0 -311
- package/docs/STARTERS.md +0 -83
- package/docs/STATIC.md +0 -105
- package/docs/TOOLING.md +0 -298
- package/docs/TUNNELS.md +0 -72
- package/docs/TYPESCRIPT-AUTHORING.md +0 -87
- package/docs/TYPESCRIPT.md +0 -123
- package/docs/VERCEL.md +0 -114
- package/docs/VERSION-ALIGNMENT.md +0 -88
- package/docs/YAML-GUIDE.md +0 -57
- package/docs/YAML-REFERENCE.md +0 -449
- package/docs/archive/2026-09-19/EXTENSION-IMPLEMENTATION.md +0 -68
- package/docs/archive/2026-09-19/MANAGEMENT-SECURITY.md +0 -102
- package/docs/archive/2026-09-19/NEXT-PHASE-PLAN.md +0 -108
- package/docs/archive/2026-09-19/NEXT-STEPS.md +0 -646
- package/docs/archive/2026-09-19/OPEN-DECISIONS.md +0 -277
- package/docs/archive/2026-09-19/RELEASE-SECURITY.md +0 -186
- package/docs/archive/2026-09-19/ROADMAP.md +0 -387
- package/docs/archive/2026-09-19/SPIKE-EXTENSION-MODEL.md +0 -430
- package/docs/archive/2026-09-19/SPIKE-EXTENSIONS.md +0 -492
- package/docs/archive/2026-09-19/SPIKE-LAMBDA-COMPILE.md +0 -365
- package/docs/archive/2026-09-19/SPIKE-MONOREPO.md +0 -778
- package/docs/archive/2026-09-19/USABILITY-REVIEW.md +0 -139
- package/docs/archive/2026-09-20/OPEN-DECISIONS-COMPLETED.md +0 -116
- package/docs/archive/README.md +0 -29
- package/docs/policies/agents.md +0 -182
- package/docs/policies/cache.md +0 -152
- package/docs/policies/compression.md +0 -169
- package/docs/policies/contract.md +0 -52
- package/docs/policies/hardened.md +0 -56
- package/docs/policies/interoperability.md +0 -169
- package/docs/policies/operations.md +0 -45
- package/docs/policies/security.md +0 -161
- package/docs/policies/throttle.md +0 -103
- package/docs/yaml/assets.md +0 -36
- package/docs/yaml/conditions.md +0 -20
- package/docs/yaml/functions.md +0 -168
- package/docs/yaml/middleware.md +0 -31
- package/docs/yaml/organization.md +0 -74
- package/docs/yaml/policies.md +0 -37
- package/docs/yaml/redirects.md +0 -64
- package/docs/yaml/responses.md +0 -57
- package/docs/yaml/site.md +0 -24
- package/packaging/claude-plugin/.claude-plugin/plugin.json +0 -19
- package/packaging/claude-plugin/skills/urlcode-authoring/SKILL.md +0 -130
- package/packaging/claude-plugin/skills/urlcode-operations/SKILL.md +0 -108
|
@@ -18,7 +18,9 @@ is to author only what the pinned revision implements and then prove it.
|
|
|
18
18
|
Check the installed version's primitives, YAML configuration, policies, supported
|
|
19
19
|
extensions and recipes/templates before writing a custom function or middleware.
|
|
20
20
|
Keep necessary custom code focused and report the capability gap; never invent
|
|
21
|
-
fields or bypass target limits or operator grants.
|
|
21
|
+
fields or bypass target limits or operator grants. In a source checkout, see
|
|
22
|
+
`docs/PROJECT-DIRECTION.md`; in an npm installation, search the matching heading
|
|
23
|
+
in `llms-full.txt`.
|
|
22
24
|
|
|
23
25
|
## Read the contract before writing YAML
|
|
24
26
|
|
|
@@ -26,17 +28,25 @@ Documentation, schema and runtime must come from the **same revision**. Read fro
|
|
|
26
28
|
the project's installed runtime (`node_modules/@jimhoyd/urlcode/`) or the
|
|
27
29
|
checkout you are working in — never from memory of another version.
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
Make one bounded query first: MCP `get_context` when the `urlcode` server is
|
|
32
|
+
registered, otherwise `urlcode context --project <dir>` (add `--budget 4000`
|
|
33
|
+
when the project is large). It is a compact summary, constraints and exact
|
|
34
|
+
commands, not a schema dump. Then retrieve only what the change needs:
|
|
35
|
+
`urlcode capabilities NAME` (`get_capability`, for its limits), `get_schema`,
|
|
36
|
+
`recipes search TEXT` (`search_recipes`), `explain` and, when the operator
|
|
37
|
+
supplies a host file, `get_extensions`. Bare `urlcode capabilities`, `recipes
|
|
38
|
+
list`, the compact `llms.txt` index and `llms-full.txt` remain deliberate
|
|
39
|
+
fallback/reference: in a source checkout read the matching task guide from
|
|
40
|
+
`docs/`; in an npm installation search the heading in `llms-full.txt`.
|
|
33
41
|
When the project has an operator host file, inspect `urlcode extensions
|
|
34
42
|
--project <dir> --host-file <absolute-file> --json` (MCP: `get_extensions`)
|
|
35
43
|
before writing extension configuration or project hooks. The report is the
|
|
36
|
-
machine-readable source for config/policy schemas
|
|
37
|
-
|
|
38
|
-
`
|
|
39
|
-
|
|
44
|
+
machine-readable source for config/policy schemas, hook contracts, supported
|
|
45
|
+
project-owned authoring surfaces and fast checks.
|
|
46
|
+
The `SPECIFICATION` section of `llms-full.txt` and
|
|
47
|
+
`schemas/urlcode.schema.json` resolve contract questions in an installed
|
|
48
|
+
package. A source checkout also has `docs/SPECIFICATION.md`. Archived plans are
|
|
49
|
+
historical, not valid YAML guidance.
|
|
40
50
|
|
|
41
51
|
## Workflow
|
|
42
52
|
|
|
@@ -54,11 +64,24 @@ questions. Archived plans are historical, not valid YAML guidance.
|
|
|
54
64
|
- Create every referenced module, page and asset **before** validating. All
|
|
55
65
|
source paths resolve from the project root. Trusted modules can import Node built-ins and npm packages;
|
|
56
66
|
only `sandbox: true` modules are restricted to the relative snapshotted graph.
|
|
57
|
-
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
67
|
+
- Treat core, installed extensions and product UI as one application with
|
|
68
|
+
different owners. Follow an extension's published `authoring` surfaces in
|
|
69
|
+
this order: configuration; theme and copy; component or template override;
|
|
70
|
+
project CSS; declared trusted hook. Keep auth/admin security and workflow
|
|
71
|
+
behavior in their packages and keep only the product-specific difference in
|
|
72
|
+
the project. Build a new extension only for a reusable capability the
|
|
73
|
+
installed contracts cannot express. Extension hooks run trusted in-process
|
|
74
|
+
and reject `sandbox: true` in contract v1.
|
|
75
|
+
- When a React frontend has `components.json`, follow the installed official
|
|
76
|
+
shadcn/ui skill for component discovery, composition, accessibility and
|
|
77
|
+
semantic Tailwind styling. Start with `shadcn info --json`, then use its
|
|
78
|
+
`shadcn docs`/`search` flow or configured MCP registry before generating a
|
|
79
|
+
component. Do not put React components in URLCode's server template renderer
|
|
80
|
+
merely because it uses shadcn-compatible tokens.
|
|
81
|
+
- Run the extension's published `fastChecks` while iterating, then the full
|
|
82
|
+
project checks before handoff. Theme and copy changes should not rebuild the
|
|
83
|
+
framework packages. Full workspace/package checks may take several minutes;
|
|
84
|
+
give them enough time to finish instead of repeatedly rebuilding.
|
|
62
85
|
- Write exact response fixtures for success and failure, covering every active
|
|
63
86
|
method, middleware behavior, HEAD, and any range or cache semantics.
|
|
64
87
|
- Follow `docs/BEST-PRACTICES.md` for layout and readability as the project grows.
|
|
@@ -118,6 +141,26 @@ runtime checkout, substitute `node src/cli.ts` for `urlcode`; in a project made
|
|
|
118
141
|
from `urlcode-template`, the equivalent npm scripts work. External bindings
|
|
119
142
|
require an already reviewed policy — add `--policy` where needed.
|
|
120
143
|
|
|
144
|
+
## Feedback after a real attempt
|
|
145
|
+
|
|
146
|
+
After a task, give feedback only when a real attempt exposed one of these:
|
|
147
|
+
|
|
148
|
+
- a **capability gap**: a requirement the current contract cannot express;
|
|
149
|
+
- a **repeated-workaround**: custom code recreating framework plumbing likely
|
|
150
|
+
to recur across applications;
|
|
151
|
+
- a **documentation/discovery gap**: the supported path was hard to find or
|
|
152
|
+
distinguish from an unsupported one; or
|
|
153
|
+
- a **suspected defect**: observed behavior contradicts the installed contract
|
|
154
|
+
or its fixture.
|
|
155
|
+
|
|
156
|
+
Produce a compact draft, not an issue: category, installed runtime/target,
|
|
157
|
+
sanitized route or YAML fragment, the exact validation/test observation, the
|
|
158
|
+
smallest expected behavior, and a proposed fixture. Do not include secrets,
|
|
159
|
+
customer URLs, raw source, or one-off product logic. Search existing URLCode
|
|
160
|
+
issues first and name a likely duplicate when found. You may propose a new
|
|
161
|
+
issue or comment, but never create or update a GitHub issue without the user's
|
|
162
|
+
explicit approval.
|
|
163
|
+
|
|
121
164
|
## Boundaries
|
|
122
165
|
|
|
123
166
|
- Keep secrets out of source, examples and Git. Request named bindings, but
|
|
@@ -18,6 +18,10 @@ another version.
|
|
|
18
18
|
|
|
19
19
|
## Read before advising
|
|
20
20
|
|
|
21
|
+
In a source checkout, use the `docs/` paths below. In an npm installation,
|
|
22
|
+
search the same document headings in `llms-full.txt`; the archive deliberately
|
|
23
|
+
does not duplicate the repository's authored documentation tree.
|
|
24
|
+
|
|
21
25
|
1. `docs/OPERATIONS.md` — process and container deployment, shutdown, exposure.
|
|
22
26
|
2. `docs/DEPLOYMENT-CHECKS.md` — `verify-deployment`: what it checks against a
|
|
23
27
|
live target and what it deliberately does not.
|
package/README.md
CHANGED
|
@@ -53,19 +53,22 @@ application by adding YAML; the operator wires trusted packages in one host
|
|
|
53
53
|
file outside the project. The full map, the composition contract and the rules
|
|
54
54
|
an AI agent must follow are in [the framework](docs/FRAMEWORK.md).
|
|
55
55
|
|
|
56
|
-
| Package | Adds |
|
|
56
|
+
| Package | Adds | Stable npm channel |
|
|
57
57
|
|---|---|---|
|
|
58
|
-
| [urlcode](https://github.com/jimhoyd-com/urlcode) (this repository) | Runtime, CLI, policies, provider adapters, extension contract |
|
|
59
|
-
| [urlcode-ui](packages/ui) (in this repository) | Shared presentation: escaped templates, shadcn/ui partials, themes, translations |
|
|
60
|
-
| [urlcode-auth](packages/auth) (in this repository) | Accounts: password, passkeys, OIDC, email codes, TOTP, sessions, roles, account page |
|
|
61
|
-
| [urlcode-admin](packages/admin) (in this repository) | Administration: users, sessions, roles, audit, approvals, cases, impersonation |
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
58
|
+
| [urlcode](https://github.com/jimhoyd-com/urlcode) (this repository) | Runtime, CLI, policies, provider adapters, extension contract | [](https://www.npmjs.com/package/@jimhoyd/urlcode) |
|
|
59
|
+
| [urlcode-ui](packages/ui) (in this repository) | Shared presentation: escaped templates, shadcn/ui partials, themes, translations | [](https://www.npmjs.com/package/@jimhoyd/urlcode-ui) |
|
|
60
|
+
| [urlcode-auth](packages/auth) (in this repository) | Accounts: password, passkeys, OIDC, email codes, TOTP, sessions, roles, account page | [](https://www.npmjs.com/package/@jimhoyd/urlcode-auth) |
|
|
61
|
+
| [urlcode-admin](packages/admin) (in this repository) | Administration: users, sessions, roles, audit, approvals, cases, impersonation | [](https://www.npmjs.com/package/@jimhoyd/urlcode-admin) |
|
|
62
|
+
|
|
63
|
+
The badges report each package's live npm `latest` channel, which is the stable
|
|
64
|
+
version of that package. Stability is independent: matching version numbers are
|
|
65
|
+
not required. Releases created by the current [GitHub release
|
|
66
|
+
publisher](https://github.com/jimhoyd-com/urlcode/releases) show the exact
|
|
67
|
+
four-package combination tested together, its declared peer
|
|
68
|
+
requirements and a copyable exact-version install command; the signed
|
|
69
|
+
`train.json` asset is the machine-readable receipt. Peer ranges, channel rules
|
|
70
|
+
and generated application pins are documented in [package and channel
|
|
71
|
+
alignment](docs/VERSION-ALIGNMENT.md).
|
|
69
72
|
|
|
70
73
|
`urlcode-dynamic-link` and `urlcode-short` were published once as
|
|
71
74
|
`0.1.0-alpha.1` and have since been retired: both were unpublished from npm and
|
|
@@ -106,7 +109,8 @@ it. Cross-repository acceptance is tracked in
|
|
|
106
109
|
|
|
107
110
|
## Status
|
|
108
111
|
|
|
109
|
-
|
|
112
|
+
<!-- urlcode-current-version:start -->
|
|
113
|
+
The `0.4.6` release line brings core, UI, auth and admin to matching stable
|
|
110
114
|
versions. A stable version selects the npm `latest` channel; it does not close
|
|
111
115
|
the review and deployment evidence gaps below. `0.4.0-alpha.1`
|
|
112
116
|
added the extension contract, capabilities and provider conformance, strict
|
|
@@ -118,6 +122,7 @@ opt-in, and removed the native `link:`/`dynamicLinks:` YAML shape. That is a
|
|
|
118
122
|
behaviour change for existing projects with no YAML edit; read
|
|
119
123
|
[the roadmap entry](ROADMAP.md) before upgrading. Use the schema and docs from
|
|
120
124
|
the runtime revision you run.
|
|
125
|
+
<!-- urlcode-current-version:end -->
|
|
121
126
|
The [roadmap](ROADMAP.md) separates implemented from planned, and
|
|
122
127
|
[release readiness](docs/RELEASE-READINESS.md) records what is proven and
|
|
123
128
|
what is not: provider deployments, soak and independent security review
|
|
@@ -178,8 +183,7 @@ SQLite build requirement, unverified from this repository.
|
|
|
178
183
|
## Try it
|
|
179
184
|
|
|
180
185
|
```sh
|
|
181
|
-
|
|
182
|
-
npm install --global @jimhoyd/urlcode@0.4.1
|
|
186
|
+
npm install --global @jimhoyd/urlcode@latest
|
|
183
187
|
urlcode init my-urls && cd my-urls
|
|
184
188
|
urlcode dev
|
|
185
189
|
```
|
package/SECURITY.md
CHANGED
|
@@ -57,6 +57,8 @@ confirmed issues use private coordination and a public advisory when appropriate
|
|
|
57
57
|
Bind loopback by default; protect public deployments with HTTPS, rate limits,
|
|
58
58
|
network controls and restricted operational endpoints. See [operations](docs/OPERATIONS.md).
|
|
59
59
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
Use a current reviewed commit: the shared 0.3.0 version label alone does not
|
|
61
|
+
identify which hardening patches are present. Internal source-review details are
|
|
62
|
+
maintainer material, not an independent assessment; the public security model,
|
|
63
|
+
reporting path and outstanding assessment gate are the authoritative claims on
|
|
64
|
+
this page and in [the sandbox review](docs/SANDBOX-REVIEW.md).
|
package/dist/BUILD-MANIFEST.json
CHANGED
|
@@ -2,19 +2,21 @@
|
|
|
2
2
|
"node": "v26.9.0",
|
|
3
3
|
"files": {
|
|
4
4
|
"dist/adapters.js": "a7153ec52f2ed7e0cdd8ed7d433504815f402ec53b2b1c3d38d0cf0e2fcf6509",
|
|
5
|
+
"dist/agent-context.js": "1e4e9c7b85d155c06d99d8b70f625bd7ab31330a0207aef6ed1803243b759611",
|
|
5
6
|
"dist/agent-lists.js": "35ab484198897501d011cb6cc00b5a6787192e19df29c97646e8c118fcc19eef",
|
|
6
|
-
"dist/agents-guide.js": "
|
|
7
|
+
"dist/agents-guide.js": "14684bf514cabbe7c9bb1ad6b6b2c479f8aaf3feb299b64655fd9fba218268d6",
|
|
7
8
|
"dist/assets.js": "0833b093d2fe457ce68281110dc07d47914992753607741c13b339d92c76cf5c",
|
|
8
9
|
"dist/authoring-files.js": "ad32814f9ae9c549c6247396f982aa700d13a293cc0a589609eccc68f8965550",
|
|
9
|
-
"dist/authoring.js": "
|
|
10
|
+
"dist/authoring.js": "bb3d4e7c6c982c4a1985a7663f960d05a08459d935e2609d404f4001b7ea767f",
|
|
10
11
|
"dist/aws.js": "7d8e3a97b4f6dbefbd68da058f05192469d1efcaed5458b284863ebe462e060e",
|
|
11
|
-
"dist/
|
|
12
|
+
"dist/body-schema.js": "0227ef8cf2b380e3ef65a358533aa0e0f4a119c94e63747b8eb03fe65a6b9193",
|
|
13
|
+
"dist/build-cloudflare.js": "e552dbf3c08036f02b0e5eb4bfd1309229bbba41d021ac15051e3f6fb165d8b4",
|
|
12
14
|
"dist/build-static.js": "fe01ef4fcc66d83d8be7a787538b55974e84fd3d7c89e26f0a2f1a152762d565",
|
|
13
15
|
"dist/bulk.js": "aac88d422bd9a7a341a421fb4e29ff5580b28d39250b7f1f5315ba20ae92da8a",
|
|
14
|
-
"dist/capabilities.js": "
|
|
16
|
+
"dist/capabilities.js": "bb98f5bbf54cc4e82fa197f999a621ad815273176f02692c35566886e2bb8777",
|
|
15
17
|
"dist/capability-query.js": "9f68bc94901451d7b9ecdd3aee8c3376dca7f0b890e31d8205306cf8120dea86",
|
|
16
18
|
"dist/catalog.js": "c378ef9bfd63b940790f6975f7db54557c2459722b65a7c170b97df24184bc52",
|
|
17
|
-
"dist/cli.js": "
|
|
19
|
+
"dist/cli.js": "c155fc50b1750dd0eda78ec3860f8855f6726e563d6d28632a6e54891e09b768",
|
|
18
20
|
"dist/client-address.js": "9d0d01466aab23124330605c5a0e0f981f87c897858acfad909f546a63df165b",
|
|
19
21
|
"dist/cloudflare.js": "17b43b0a6b6a0ef8a893415c989e4ae3976d97cc966adbf897b785f9adc472e3",
|
|
20
22
|
"dist/compliance-rules/baseline.js": "6296dea6bcb9f9bb80ed6ed5ab2f456e7f74e6de2be5d2d98ca8c983fb4df3ab",
|
|
@@ -24,63 +26,64 @@
|
|
|
24
26
|
"dist/compliance.js": "29a18da3cefea94802ac7d817d1ab4e3674abd5c3ac4ef893cb8b01c6a23fb61",
|
|
25
27
|
"dist/conditions.js": "ff25e97da550a3bdd80af55522045669438aa31a77d2bc83ad602bcefdee0475",
|
|
26
28
|
"dist/config-worker.js": "bc2170d60c35f8d5de227cbfc4c5067dc61d7cbc5b98aed88e68a11797072da5",
|
|
27
|
-
"dist/config.js": "
|
|
28
|
-
"dist/context.js": "
|
|
29
|
+
"dist/config.js": "33c8d1f80aa7f1ce25eab12644f6cbef961a897b72b1585d4bfa6424985f0d16",
|
|
30
|
+
"dist/context.js": "f0de473b1e13649b0778fe2d5e7a65d4d6ac82614b47a1f86b453b73a85cb166",
|
|
29
31
|
"dist/ecosystem-cli.js": "1e71bacd53d6fa8c7857cfcce3c3012ce054771a434b78d1f39e892e32642edd",
|
|
30
32
|
"dist/egress.js": "2ae29fe2cb4590fd2f715abe6817db47fed2f50dd31f37946ecf42eafbb0dd9e",
|
|
31
|
-
"dist/errors.js": "
|
|
32
|
-
"dist/examples.js": "
|
|
33
|
+
"dist/errors.js": "fef26eb834dd61b8b5f587eb7ab265d216122d182545f0a1c5b19c20840dffb0",
|
|
34
|
+
"dist/examples.js": "8523799797d2530fe48ec5e96c34970bdba03c49afb31fdaab6a9c162a17dfa9",
|
|
33
35
|
"dist/explain-cli.js": "f0f8f3b5046430d03c6abb629b38651c9c734b03456040735ce9d7e582b2bcd5",
|
|
34
36
|
"dist/explain.js": "7fb632036cc68280701dd512c74d27d6e0f97b4848e9024b284d7c5393b35eb5",
|
|
35
|
-
"dist/extensions.js": "
|
|
37
|
+
"dist/extensions.js": "966441cca677b0d88683d29d89d36c61cf487ae2b70d94eaa0c71c50730a4212",
|
|
36
38
|
"dist/function-sources.js": "16fad4abc81c7ee07b6cbcef2d23a9fc50e97a17cb4dde1db53469bbb555c96f",
|
|
37
39
|
"dist/function-worker.js": "35771790ada4e1b36d447d4967a5e6cf0b543f32944e4c904f5fbf8998e824a5",
|
|
38
40
|
"dist/functions.js": "0f09d1bd27eb655ceb5900a4a5e2b760d2028b02cb637a6a89a4eb5940828008",
|
|
39
41
|
"dist/guest-api.js": "49aec9ed72733ad119e63bcfcee18158dcc8ceb951e1823b8947f6407ff24afc",
|
|
40
42
|
"dist/header-validation.js": "465181dbb08ff05f52defdd29fda025c0c64589bf319fa87fa6d3ab4b68216d5",
|
|
41
|
-
"dist/http-policy.js": "
|
|
42
|
-
"dist/http-response.js": "
|
|
43
|
+
"dist/http-policy.js": "393a6383bdf9e05597c98721b3a4c4207a9bbe359883babcbfa06b696c70f56c",
|
|
44
|
+
"dist/http-response.js": "565826d1ece4bd30dfc1150c75800acec1fef584f732e964409aa92958fc8550",
|
|
43
45
|
"dist/index.js": "8d7532ae0a31f9439ebb62e7b01a2748aee00f350262ff55d1226121d206c1ed",
|
|
44
|
-
"dist/init-with.js": "
|
|
46
|
+
"dist/init-with.js": "0d2dccb83f0ad53181c6f5c95a4c663ce06ee9a1fa9074facac9a1aee7599a96",
|
|
45
47
|
"dist/interchange-cli.js": "35bd70ba8077af5c3e39404ff0e5d28707632090a59a90645141252449fd3f04",
|
|
46
48
|
"dist/interchange.js": "26789420af33344d9a08c00fe6b2708aa71994224df527b3075295be2151611e",
|
|
47
49
|
"dist/logging.js": "8ec57fea26983aa071b05fe15d680d6550b03488101163ed9666da674118cf31",
|
|
48
50
|
"dist/manifest.js": "83eed0d59621039ef364cf6e7b54c5bd47e0d8cf0a5abe7b07344bfc1db56ed8",
|
|
49
51
|
"dist/match.js": "53ebcc2cda529a8d07fb83f8cb69a1446036ffc1641af3c4bd45a55851bded28",
|
|
50
52
|
"dist/mcp-authoring.js": "1183a56c5decb99ecb67a5da7bd91d1b494bc17a2965051aa63c4a7e291462b5",
|
|
51
|
-
"dist/mcp.js": "
|
|
53
|
+
"dist/mcp.js": "28e6b98a394ae330d4310abc89e0e5a5210d2b892c9ecb3ac97345e765e584f8",
|
|
52
54
|
"dist/observability.js": "f4b1ab496f051fe3ef2ed36b2b2e469c63a8940700e2df852e6ff2d9cccdd5ae",
|
|
53
55
|
"dist/operator-host.js": "e3dac9d43a83beb775202b4ab9eeeba7ac63cebfc5dcc669be38d825be587bd0",
|
|
56
|
+
"dist/pattern-guard.js": "6f157ced99666a89ca5af1418f5a14568d850985042dea309bf9ec0c19dbaca5",
|
|
54
57
|
"dist/plugins.js": "a61aa933cd9e1b41020b86fae78aa3a7f45f5313124aa11b50cb57898722385e",
|
|
55
58
|
"dist/policies/agents.js": "c1dbc1e90339f472eeeb2372f7f4637f59a5d210797ea680ac8120a02aa20c10",
|
|
56
59
|
"dist/policies/cache.js": "d08184e50b0ecb7331b29e4145aaefacb23b64ddaf3555d579743762f90c1629",
|
|
57
60
|
"dist/policies/compression.js": "800f3ae3b1a4c1fe58c3d9908364ea9d78f655ff50c7f7589f584378e7f194b0",
|
|
58
|
-
"dist/policies/security.js": "
|
|
61
|
+
"dist/policies/security.js": "c68d39f5fa2d7d16f5bfb3dcff2ac71428cc41814970eecf8b931debd40c0f3e",
|
|
59
62
|
"dist/policies/throttle.js": "bbb0cb1c24cf70d0a1ac32fc0618efb6c44e5b5d42564842f9c585ff7e501603",
|
|
60
63
|
"dist/policies.js": "3750a7032ec7326aa544f4808683ad9eb91d4f2c5afe79904420cd8a355710a9",
|
|
61
64
|
"dist/policy.js": "2da95b3f1f77249b1e9f399a06b88909b68594fdbc958176075e91ff23104a7c",
|
|
62
65
|
"dist/prerender.js": "6210999e848ab86c87f265943960ef63716896da7a40e248221a6a30425c56b8",
|
|
63
66
|
"dist/project-dependencies.js": "b43a8f3125f62d38f0e71237b7813a785ef0613a83fcdec3fa8314f33758a534",
|
|
64
|
-
"dist/project-tests.js": "
|
|
67
|
+
"dist/project-tests.js": "63562978411ee94a69dcf45d4d47e84fba009d8654ac421c2a02a418cd80b4db",
|
|
65
68
|
"dist/provider-verification.js": "ffcf9f05e8cb5f71ea46a97e279e8a613fdfdf9435ab02bd57af11e2680a9107",
|
|
66
69
|
"dist/proxy.js": "34107e59ac0dbbea090efa3cf5badf3226c5302ba25e8f8ff9b2b5596ed80e50",
|
|
67
|
-
"dist/readiness.js": "
|
|
68
|
-
"dist/recipes.js": "
|
|
70
|
+
"dist/readiness.js": "2b67bc86c0c73528f3f798b6a0ee1bd5aec5ac6f4a0998c45443c903a622af4f",
|
|
71
|
+
"dist/recipes.js": "7af62ea9f612c82ea21e97e9d14451f05e0b509d6e420fb99fec96b22e3533f1",
|
|
69
72
|
"dist/route-diff.js": "8d71d50d332ffaaed588656bd32aa36763260d1ad87bb62d7ea1c8fb23383969",
|
|
70
|
-
"dist/router.js": "
|
|
71
|
-
"dist/runtime.js": "
|
|
73
|
+
"dist/router.js": "b2b26409321c5d119ac54793efe6bb6a2f9bbf2f36db251c68337c25b9d836b9",
|
|
74
|
+
"dist/runtime.js": "e36153ab250b566ea778584a447ce603cf283274d9f8ac54a22aa9969c2284e8",
|
|
72
75
|
"dist/sandbox.js": "c88c5aa5dd95b4f55f1ba62da7969ad66dbd97c30f72e5b5f2817a2098ac1c65",
|
|
73
|
-
"dist/scaffold.js": "
|
|
76
|
+
"dist/scaffold.js": "0f936cabd20b609c7ebfebd7895710ce6c30882c3088a2356ac75bb4e0d10c55",
|
|
74
77
|
"dist/schema-query.js": "bfd1844acd8d54ac361115191fcfbaf828a67e223b9ec6e9c22f158761af149b",
|
|
75
|
-
"dist/server.js": "
|
|
78
|
+
"dist/server.js": "165b66fc4ed3b8e7c46ae4402ef66a5bc988c0910fb3e11556b040781e09d03c",
|
|
76
79
|
"dist/signals.js": "b55e54efc8fb6703e08f2a1e808ec8e011bda67738db8ceadf1b248f695795be",
|
|
77
|
-
"dist/site.js": "
|
|
78
|
-
"dist/tooling.js": "
|
|
80
|
+
"dist/site.js": "38176ac4d1970ebf73e3f96094f39900724ce96b29d6de892b8baae01e183aa5",
|
|
81
|
+
"dist/tooling.js": "3d2848aba0a374ef980328c6924d4b314c53094efc2cc94638f1a58b726f8161",
|
|
79
82
|
"dist/trusted-functions.js": "f3800c75f45ce90faf85ba6664398ad9031c5a9ac51d5ce42bdcff08a497d48e",
|
|
80
|
-
"dist/types.js": "
|
|
81
|
-
"dist/typescript-authoring.js": "
|
|
83
|
+
"dist/types.js": "827f1afde90d19715e79500515ecaa80f5b65ce552f0ef24d2fc561ef77e6e40",
|
|
84
|
+
"dist/typescript-authoring.js": "df3d9c82e6b545cae5caae04c443ed4d2feae96def5e5cde250c0a90d83ae98c",
|
|
82
85
|
"dist/vercel.js": "a0da20c095d0c7fa8f579ed4dd5951e7a34191f8a72a57c5e782c9eab39f6f08",
|
|
83
|
-
"dist/verify-deployment.js": "
|
|
86
|
+
"dist/verify-deployment.js": "2d3b6301b70684abfccea669f7901afda7fae9d9d66902809ecdef65f22aea16",
|
|
84
87
|
"dist/scripts/operational-drills.js": "c26c406d28013cc554b25a5b6bf8baf4e71d5e67e50d866fae546f538a192317"
|
|
85
88
|
}
|
|
86
89
|
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import {readFile} from 'node:fs/promises';
|
|
2
|
+
import {fileURLToPath} from 'node:url';
|
|
3
|
+
import {parseYaml,validateDocument} from './config.js';
|
|
4
|
+
import {listExamples} from './examples.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Fixed, package-owned agent material. This is intentionally a manifest rather
|
|
8
|
+
* than an arbitrary file reader: MCP clients cannot use it to enumerate or
|
|
9
|
+
* exfiltrate a local project.
|
|
10
|
+
*/
|
|
11
|
+
const packageRoot=fileURLToPath(new URL('../',import.meta.url));
|
|
12
|
+
const docs=[
|
|
13
|
+
{id:'llms',title:'URLCode agent index',file:'llms.txt',summary:'Compact map of the framework, its declarative primitives and the minimum reference to load next.'},
|
|
14
|
+
{id:'authoring',title:'AI authoring',file:'docs/AI-AUTHORING.md',summary:'Declarative-first authoring workflow, retrieval order and framework constraints.'},
|
|
15
|
+
{id:'yaml-reference',title:'YAML reference',file:'docs/YAML-REFERENCE.md',summary:'Generated inventory of accepted URLCode YAML fields.'},
|
|
16
|
+
{id:'tooling',title:'Tooling and local MCP',file:'docs/TOOLING.md',summary:'Bounded local project inspection, validation and MCP tool behavior.'},
|
|
17
|
+
{id:'security',title:'Function security',file:'docs/FUNCTION-SECURITY.md',summary:'Trusted versus sandboxed function behavior, bindings and operator grants.'},
|
|
18
|
+
] ;
|
|
19
|
+
const skills=[
|
|
20
|
+
{name:'urlcode',description:'Author URLCode projects declaratively, retrieve only the required contract, and validate the result.',file:'skills/urlcode/SKILL.md'},
|
|
21
|
+
] ;
|
|
22
|
+
const maxExcerpt=1800;
|
|
23
|
+
|
|
24
|
+
function terms(query ) {return [...new Set(query.toLowerCase().split(/[^a-z0-9]+/).filter(term=>term.length>1))].slice(0,16);}
|
|
25
|
+
function excerpt(text , query ) {
|
|
26
|
+
const words=terms(query),lower=text.toLowerCase();
|
|
27
|
+
const positions=words.map(word=>lower.indexOf(word)).filter(position=>position>=0);
|
|
28
|
+
const start=Math.max(0,(positions.length?Math.min(...positions):0)-300);
|
|
29
|
+
return text.slice(start,start+maxExcerpt);
|
|
30
|
+
}
|
|
31
|
+
async function content(file ) {return readFile(packageRoot+file,'utf8');}
|
|
32
|
+
|
|
33
|
+
export function listSkills() {return skills.map(({name,description})=>({name,description}));}
|
|
34
|
+
export async function getSkill(name ) {
|
|
35
|
+
const skill=skills.find(candidate=>candidate.name===name);
|
|
36
|
+
if(!skill)throw new Error('Unknown bundled skill');
|
|
37
|
+
return {name:skill.name,description:skill.description,content:await content(skill.file)};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Deterministic lexical search over a deliberately small, agent-facing corpus. */
|
|
41
|
+
export async function searchDocs(query ) {
|
|
42
|
+
const words=terms(query);
|
|
43
|
+
if(!words.length)throw new Error('Search text must contain a word');
|
|
44
|
+
const hits=(await Promise.all(docs.map(async doc=>{
|
|
45
|
+
const text=await content(doc.file),haystack=`${doc.title} ${doc.summary} ${text}`.toLowerCase();
|
|
46
|
+
const matched=words.filter(word=>haystack.includes(word));
|
|
47
|
+
return {doc,text,matched,score:matched.length};
|
|
48
|
+
}))).filter(hit=>hit.score>0).sort((a,b)=>b.score-a.score||a.doc.id.localeCompare(b.doc.id)).slice(0,3);
|
|
49
|
+
return {query,results:hits.map(({doc,text,matched})=>({id:doc.id,title:doc.title,summary:doc.summary,matched,excerpt:excerpt(text,query)}))};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Returns the two smallest high-value files of a fixed packaged example. */
|
|
53
|
+
export async function getExample(name ) {
|
|
54
|
+
const example=(await listExamples()).find(candidate=>candidate.name===name);
|
|
55
|
+
if(!example)throw new Error('Unknown bundled example');
|
|
56
|
+
const files=example.files.filter(file=>file==='urlcode.yaml'||file==='README.md');
|
|
57
|
+
const content =Object.create(null);
|
|
58
|
+
for(const file of files)content[file]=await readFile(`${packageRoot}examples/${name}/${file}`,'utf8');
|
|
59
|
+
return {metadata:example,content};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Validates only supplied YAML syntax and the versioned document schema. It never resolves includes or reads source files. */
|
|
63
|
+
export function validateYaml(text ) {
|
|
64
|
+
try {
|
|
65
|
+
const document=validateDocument(parseYaml(text));
|
|
66
|
+
return {valid:true,scope:'syntax-and-schema-only',version:document.version,routeCount:Object.keys(document.routes).length};
|
|
67
|
+
}catch(error){
|
|
68
|
+
return {valid:false,scope:'syntax-and-schema-only',error:error instanceof Error?error.message:'Invalid URLCode YAML'};
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Short deterministic remediation for common validator output; no model call or project read occurs. */
|
|
73
|
+
export function explainError(error ) {
|
|
74
|
+
const lower=error.toLowerCase();
|
|
75
|
+
let guidance='Use validate_yaml for YAML syntax/schema feedback, then use local validate for project files, includes and route semantics.';
|
|
76
|
+
if(lower.includes('duplicate yaml')||lower.includes('duplicate key'))guidance='Give every mapping key one value. URLCode rejects duplicate YAML keys rather than choosing one silently.';
|
|
77
|
+
else if(lower.includes('aliases')||lower.includes('anchors')||lower.includes('explicit tags'))guidance='Rewrite YAML anchors, aliases and tags as ordinary repeated YAML values; URLCode accepts a JSON-compatible YAML subset.';
|
|
78
|
+
else if(lower.includes('invalid configuration at'))guidance='The named location does not match the versioned URLCode schema. Ask get_schema for that field or get_capability for the handler before editing it.';
|
|
79
|
+
else if(lower.includes('project file')||lower.includes('referenced'))guidance='This needs local project validation: confirm the referenced path is project-relative, exists, and is allowed by the selected route type.';
|
|
80
|
+
else if(lower.includes('sandbox'))guidance='Sandboxed routes cannot use Node or network APIs. Prefer a declarative handler or proxy; otherwise remove sandboxing only after a deliberate trust review.';
|
|
81
|
+
return {guidance,nextTools:['get_schema','get_capability','validate']};
|
|
82
|
+
}
|
package/dist/agents-guide.js
CHANGED
|
@@ -33,53 +33,55 @@ export function renderAgentsGuide({ routes } ) {
|
|
|
33
33
|
return `# Working on this project
|
|
34
34
|
|
|
35
35
|
This project uses URLCode: URL behavior is declared in \`urlcode.yaml\`, and the
|
|
36
|
-
installed
|
|
37
|
-
|
|
38
|
-
authentication; the runtime provides them. Read this file before changing anything.
|
|
36
|
+
installed runtime supplies routing, validation, middleware wiring, policies,
|
|
37
|
+
static serving and authentication. Read this file before changing anything.
|
|
39
38
|
|
|
40
39
|
## Before writing code
|
|
41
40
|
|
|
42
41
|
1. Inspect \`urlcode.yaml\` first, then every file its \`includes\` list names,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
\`
|
|
42
|
+
referenced code and \`tests/requests.json\`. Preserve unrelated routes.
|
|
43
|
+
2. Make one bounded query first: MCP \`get_context\` when the \`urlcode\` server is
|
|
44
|
+
registered, else \`urlcode context --project DIR\` (add \`--budget N\` to cap
|
|
45
|
+
it). It returns a compact summary, constraints and exact commands.
|
|
46
|
+
3. Then retrieve only what the task needs: \`capabilities NAME\`/\`get_capability\`
|
|
47
|
+
(limits; \`--target NAME\` before promising a provider), \`get_schema\`,
|
|
48
|
+
\`recipes search TEXT\`/\`search_recipes\` then \`recipes add NAME --out DIR\`,
|
|
49
|
+
\`explain\` and, with an operator host file, \`get_extensions\`. Bare
|
|
50
|
+
\`capabilities\` and \`recipes list\` are complete catalogs: fallback, not step one.
|
|
51
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
52
|
|
|
53
|
-
##
|
|
53
|
+
## MCP
|
|
54
54
|
|
|
55
|
-
When present, \`${mcpConfigFile}\` registers the read-only \`urlcode mcp\` server
|
|
56
|
-
|
|
57
|
-
|
|
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.
|
|
55
|
+
When present, \`${mcpConfigFile}\` registers the read-only \`urlcode mcp\` server; prefer its
|
|
56
|
+
tools (also \`get_manifest\`) to reading documents. Inspect \`get_extensions\` before
|
|
57
|
+
replacing extension behavior. \`--allow-authoring\` is an operator opt-in; never add it.
|
|
61
58
|
|
|
62
59
|
## What the runtime provides (this version)
|
|
63
60
|
|
|
64
61
|
- Handlers, exactly one per route: ${handlers.map(name => `\`${name}\``).join(', ')}.
|
|
65
62
|
- Ordered \`middleware\` around any handler, declared in YAML, trusted by default.
|
|
66
|
-
- Validated
|
|
67
|
-
functions receive validated \`args\`, never raw user input.
|
|
63
|
+
- Validated route \`parameters\`, \`request.body\`, \`methods\` and function \`args\`.
|
|
68
64
|
- Policies, host-enforced and off by default: ${policies.map(name => `\`${name}\``).join(', ')}.
|
|
69
65
|
- Site conventions under \`site\`, each generating one native route: ${site.join(', ')}.
|
|
70
66
|
- Bindings: named \`env\` and \`secrets\` references resolved by the operator, never values in YAML.
|
|
71
67
|
|
|
72
|
-
Never recreate
|
|
73
|
-
|
|
68
|
+
Never recreate these in a function; report a missing capability.
|
|
69
|
+
|
|
70
|
+
## Build one application
|
|
71
|
+
|
|
72
|
+
Treat routes, extensions and UI as one application with different owners. Use
|
|
73
|
+
published surfaces in order: configuration/theme/copy, smallest template, CSS,
|
|
74
|
+
then a declared hook. Keep auth/admin security and workflows package-owned; add
|
|
75
|
+
an extension only for a reusable missing capability. Use the official shadcn/ui
|
|
76
|
+
skill only in a React frontend with \`components.json\`; start with \`shadcn info
|
|
77
|
+
--json\`. Do not put React components in the server renderer.
|
|
74
78
|
|
|
75
79
|
## Functions and middleware are trusted by default; sandbox is opt-in
|
|
76
80
|
|
|
77
|
-
A
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
A \`sandbox: true\` route gets a text/JSON subset only: use \`proxy\`/a binding, and
|
|
82
|
-
say why in \`sandboxReason\`.
|
|
81
|
+
A \`function\`/\`middleware\` is trusted, in-process Node with only declared
|
|
82
|
+
\`args\`/\`env\`/\`secrets\`. Add \`sandbox: true\` for code needing isolation, not
|
|
83
|
+
merely untrusted input. The sandbox is text/JSON-only; use \`proxy\`/a binding and
|
|
84
|
+
record the reason in \`sandboxReason\`.
|
|
83
85
|
|
|
84
86
|
## Checks that count as evidence
|
|
85
87
|
|
|
@@ -89,25 +91,23 @@ urlcode test
|
|
|
89
91
|
urlcode audit --expect-routes ${routes}
|
|
90
92
|
\`\`\`
|
|
91
93
|
|
|
92
|
-
Run all three after every change, updating the route count deliberately and
|
|
93
|
-
|
|
94
|
-
|
|
94
|
+
Run all three after every change, updating the route count deliberately and adding \`tests/requests.json\` fixtures for every new route (positive/negative, every active method, HEAD). No global install: use \`node /path/to/urlcode/src/cli.ts\`.
|
|
95
|
+
|
|
96
|
+
## Feedback
|
|
97
|
+
|
|
98
|
+
After a real attempt, draft evidence-backed feedback: category, sanitized YAML, observed validation/test result, expected behavior and fixture. Ignore one-off product logic; search existing URLCode issues first; never publish or comment without the user's explicit approval.
|
|
95
99
|
|
|
96
100
|
## Rules
|
|
97
101
|
|
|
98
|
-
- Report unsupported requirements
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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.
|
|
102
|
+
- Report unsupported requirements; a field the exact schema rejects does not exist.
|
|
103
|
+
- Never create operator grants. Request a named binding; the operator grants it
|
|
104
|
+
outside the project, pinned to the revision.
|
|
105
|
+
- Keep keys, tokens and credentials out of project files and commit messages.
|
|
104
106
|
- Protect a route with \`auth: true\`/\`auth: { role: admin }\` where an \`auth\`
|
|
105
107
|
extension is declared; \`cache\` likewise expands to \`policies.cache\`.
|
|
106
|
-
-
|
|
107
|
-
deployment, a soak test or a security review; do not claim otherwise.
|
|
108
|
+
- Local checks are not deployment, soak or independent security evidence.
|
|
108
109
|
|
|
109
|
-
The installed package ships
|
|
110
|
-
|
|
111
|
-
\`node_modules/@jimhoyd/urlcode/${skillPath}\`).
|
|
110
|
+
The installed package ships the same loop at \`${skillPath}\` inside
|
|
111
|
+
\`@jimhoyd/urlcode\` (for example \`node_modules/@jimhoyd/urlcode/${skillPath}\`).
|
|
112
112
|
`;
|
|
113
113
|
}
|
package/dist/authoring.js
CHANGED
|
@@ -18,18 +18,28 @@ import { renderPackageManifest } from './project-dependencies.js';
|
|
|
18
18
|
|
|
19
19
|
|
|
20
20
|
|
|
21
|
+
|
|
22
|
+
|
|
21
23
|
|
|
22
|
-
export async function initProject(destination , { manifest } = {}) {
|
|
24
|
+
export async function initProject(destination , { manifest, template = 'default' } = {}) {
|
|
23
25
|
const target = resolve(destination);
|
|
24
26
|
await mkdir(dirname(target), { recursive: true });
|
|
25
27
|
// Reserve destination before copying; never merge into existing user files.
|
|
26
28
|
await mkdir(target);
|
|
27
29
|
try {
|
|
28
|
-
const source = fileURLToPath(new URL('
|
|
30
|
+
const source = fileURLToPath(new URL(`../starters/${template === 'page' ? 'page' : 'default'}/`, import.meta.url));
|
|
29
31
|
for (const file of await readdir(source)) {
|
|
30
32
|
if (file === '.gitignore' || file === 'AGENTS.md' || file === mcpConfigFile) continue;
|
|
31
33
|
await cp(join(source,file), join(target,file === 'gitignore.template' ? '.gitignore' : file), { recursive: true, force: false, errorOnExist: true });
|
|
32
34
|
}
|
|
35
|
+
if (template === 'page') {
|
|
36
|
+
await loadDocument(target);
|
|
37
|
+
if (manifest) {
|
|
38
|
+
const pkg = await open(join(target,'package.json'), 'wx', 0o644);
|
|
39
|
+
try { await pkg.writeFile(renderPackageManifest(target, manifest)); } finally { await pkg.close(); }
|
|
40
|
+
}
|
|
41
|
+
return target;
|
|
42
|
+
}
|
|
33
43
|
// AGENTS.md is generated from the installed runtime's capability catalog so
|
|
34
44
|
// it names only what this version implements; the starter carries a
|
|
35
45
|
// committed copy for clones, kept identical by test.
|