@rubytech/create-sitedesk-code 0.1.524 → 0.1.526
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/dist/__tests__/samba-provision.test.js +46 -1
- package/dist/__tests__/websockify-bind-wiring.test.js +47 -0
- package/dist/index.js +39 -1
- package/dist/samba-provision.js +37 -0
- package/package.json +1 -1
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +8 -7
- package/payload/platform/plugins/admin/skills/superpowers-sprint/SKILL.md +26 -0
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +12 -0
- package/payload/platform/plugins/memory/PLUGIN.md +10 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/compiled-truth-revision.test.js +5 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/compiled-truth-revision.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/temporal-type-preserve.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/temporal-type-preserve.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/temporal-type-preserve.test.js +141 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/__tests__/temporal-type-preserve.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.d.ts +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.js +6 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/log-ingest.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/lib/temporal-type-preserve.d.ts +45 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/temporal-type-preserve.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/temporal-type-preserve.js +122 -0
- package/payload/platform/plugins/memory/mcp/dist/lib/temporal-type-preserve.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-by-name.test.js +26 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-by-name.test.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-type-preserve.test.d.ts +2 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-type-preserve.test.d.ts.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-type-preserve.test.js +201 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/__tests__/memory-update-type-preserve.test.js.map +1 -0
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.js +89 -33
- package/payload/platform/plugins/memory/mcp/dist/tools/memory-update.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/vitest.config.ts +2 -0
- package/payload/platform/plugins/scheduling/PLUGIN.md +6 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/meeting-retype.test.d.ts +2 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/meeting-retype.test.d.ts.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/meeting-retype.test.js +148 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/meeting-retype.test.js.map +1 -0
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.d.ts +83 -6
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.js +90 -5
- package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/routine-roster-audit.test.js +173 -2
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/__tests__/routine-roster-audit.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts +73 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js +194 -0
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/agent-turn-dispatch.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +25 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js +81 -8
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-event-agent.test.js +39 -0
- package/payload/platform/plugins/scheduling/mcp/dist/tools/__tests__/schedule-event-agent.test.js.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js +9 -1
- package/payload/platform/plugins/scheduling/mcp/dist/tools/schedule-event.js.map +1 -1
- package/payload/platform/scripts/__tests__/check-canonical-tool-names.test.sh +162 -0
- package/payload/platform/scripts/__tests__/check-no-task-id-leaks.test.sh +53 -0
- package/payload/platform/scripts/__tests__/task-id-citation.test.sh +72 -0
- package/payload/platform/scripts/check-canonical-tool-names.mjs +36 -4
- package/payload/platform/scripts/check-no-task-id-leaks.mjs +80 -62
- package/payload/platform/scripts/lib/canonical-tool-names.mjs +130 -26
- package/payload/platform/scripts/lib/task-id-citation.mjs +67 -0
- package/payload/platform/scripts/vnc.sh +45 -1
- package/payload/server/{chunk-VUXKXOJU.js → chunk-7MGR5M6G.js} +4 -2
- package/payload/server/{manager-4TJK3YOY.js → manager-6XOWHREK.js} +1 -1
- package/payload/server/server.js +10 -4
- package/payload/platform/.docs/search-surface-contract.md +0 -58
- package/payload/platform/docs/superpowers/plans/2026-06-02-task-610-follower-202-retry.md +0 -372
- package/payload/platform/docs/superpowers/plans/2026-06-04-public-agent-knowledge-delivery.md +0 -230
- package/payload/platform/docs/superpowers/plans/2026-06-23-account-filesystem-schema.md +0 -544
- package/payload/platform/docs/superpowers/plans/2026-07-11-task-1557-operator-on-behalf-preference-attribution.md +0 -542
- package/payload/platform/docs/superpowers/plans/2026-07-13-account-schema-ontology-projection.md +0 -547
- package/payload/platform/docs/superpowers/plans/2026-07-14-graph-top-level-labels-ontology-single-source.md +0 -458
- package/payload/platform/docs/superpowers/plans/2026-07-17-task-1736-retire-mcp-stderr-tee.md +0 -397
- package/payload/platform/docs/superpowers/plans/2026-07-18-graph-native-ledger.md +0 -807
- package/payload/platform/docs/superpowers/plans/2026-07-18-ledger-write-path-fix.md +0 -109
- package/payload/platform/docs/superpowers/plans/2026-07-20-storage-pages-create.md +0 -82
- package/payload/platform/docs/superpowers/plans/2026-07-20-task-1704-data-portal-standing-audit.md +0 -673
- package/payload/platform/docs/superpowers/plans/2026-07-20-task-1789-reseat-channel-row-fork.md +0 -1244
- package/payload/platform/docs/superpowers/plans/2026-07-20-task-1818-loop-gate-app-routes.md +0 -462
- package/payload/platform/docs/superpowers/plans/2026-07-20-task-1819-top-level-label-allowlist.md +0 -321
- package/payload/platform/docs/superpowers/plans/2026-07-20-task-1829-platform-ui-typecheck.md +0 -830
- package/payload/platform/docs/superpowers/plans/2026-07-20-task-1831-data-portal-class-derived-allowlist.md +0 -2177
- package/payload/platform/docs/superpowers/plans/2026-07-21-graph-caption-resolver.md +0 -124
- package/payload/platform/docs/superpowers/plans/2026-07-21-task-1877-bash-schema-enforcement.md +0 -107
- package/payload/platform/docs/superpowers/plans/2026-07-21-task-1887-reconcile-allowed-top-level.md +0 -205
- package/payload/platform/docs/superpowers/plans/2026-07-22-task-1899-reconcile-report-only.md +0 -748
- package/payload/platform/docs/superpowers/plans/2026-07-22-task-1910-two-way-portal-exchange.md +0 -1716
- package/payload/platform/docs/superpowers/plans/2026-07-23-task-1930-adherence-enforcement.md +0 -422
- package/payload/platform/docs/superpowers/plans/2026-07-24-task-1942-subaccount-switcher-brand-head.md +0 -327
- package/payload/platform/docs/superpowers/plans/2026-07-25-task-1974-uploads-intake-inbox.md +0 -235
- package/payload/platform/docs/superpowers/plans/2026-07-25-task-1976-intra-folder-hygiene.md +0 -215
- package/payload/platform/docs/superpowers/plans/2026-07-26-task-1902-account-owned-entry-declarations.md +0 -555
- package/payload/platform/docs/superpowers/plans/2026-07-26-task-1926-portal-push-concurrency-guard.md +0 -482
- package/payload/platform/docs/superpowers/plans/2026-07-26-task-2023-sidebar-sessions-async-reads.md +0 -394
- package/payload/platform/docs/superpowers/plans/2026-07-27-task-2016-disabled-agent-routing.md +0 -624
- package/payload/platform/docs/superpowers/plans/2026-07-27-task-2028-declared-file-write-deny.md +0 -303
- package/payload/platform/docs/superpowers/plans/2026-07-27-task-2052-account-machinery-write-fence.md +0 -250
- package/payload/platform/docs/superpowers/plans/2026-07-28-task-2097-email-signature-set.md +0 -65
- package/payload/platform/docs/superpowers/specs/2026-06-02-task-610-follower-202-retry-design.md +0 -116
- package/payload/platform/docs/superpowers/specs/2026-06-23-account-filesystem-schema-design.md +0 -170
- package/payload/platform/docs/superpowers/specs/2026-07-11-task-1557-operator-on-behalf-preference-attribution-design.md +0 -90
- package/payload/platform/docs/superpowers/specs/2026-07-13-account-schema-ontology-projection-design.md +0 -178
- package/payload/platform/docs/superpowers/specs/2026-07-14-graph-top-level-labels-ontology-single-source-design.md +0 -119
- package/payload/platform/docs/superpowers/specs/2026-07-17-task-1736-retire-mcp-stderr-tee-design.md +0 -128
- package/payload/platform/docs/superpowers/specs/2026-07-18-graph-native-ledger-design.md +0 -241
- package/payload/platform/docs/superpowers/specs/2026-07-20-task-1704-data-portal-standing-audit-design.md +0 -177
- package/payload/platform/docs/superpowers/specs/2026-07-20-task-1789-reseat-channel-row-fork-design.md +0 -201
- package/payload/platform/docs/superpowers/specs/2026-07-20-task-1818-loop-gate-app-routes-design.md +0 -217
- package/payload/platform/docs/superpowers/specs/2026-07-20-task-1819-top-level-label-allowlist-design.md +0 -80
- package/payload/platform/docs/superpowers/specs/2026-07-20-task-1820-cpu-triage-admin-tools-design.md +0 -97
- package/payload/platform/docs/superpowers/specs/2026-07-20-task-1829-platform-ui-typecheck-design.md +0 -163
- package/payload/platform/docs/superpowers/specs/2026-07-20-task-1831-data-portal-class-derived-allowlist-design.md +0 -163
- package/payload/platform/docs/superpowers/specs/2026-07-22-task-1899-reconcile-report-only-design.md +0 -121
- package/payload/platform/docs/superpowers/specs/2026-07-22-task-1910-two-way-portal-exchange-design.md +0 -103
- package/payload/platform/docs/superpowers/specs/2026-07-23-task-1930-adherence-enforcement-design.md +0 -81
- package/payload/platform/docs/superpowers/specs/2026-07-24-task-1942-subaccount-switcher-brand-head-design.md +0 -35
- package/payload/platform/docs/superpowers/specs/2026-07-26-task-1902-account-owned-entry-declarations-design.md +0 -232
- package/payload/platform/docs/superpowers/specs/2026-07-26-task-1926-portal-push-concurrency-guard-design.md +0 -200
- package/payload/platform/docs/superpowers/specs/2026-07-26-task-2014-ui-suite-nondeterminism-design.md +0 -169
- package/payload/platform/docs/superpowers/specs/2026-07-27-task-2016-disabled-agent-routing-design.md +0 -139
- package/payload/platform/docs/superpowers/specs/2026-07-27-task-2028-declared-file-write-deny-design.md +0 -127
- package/payload/platform/docs/superpowers/specs/2026-07-27-task-2052-account-machinery-write-fence-design.md +0 -150
- package/payload/platform/docs/superpowers/specs/2026-07-28-task-2097-email-signature-set-design.md +0 -155
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
# Ledger write path fix — implementation plan
|
|
2
|
-
|
|
3
|
-
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax.
|
|
4
|
-
|
|
5
|
-
**Goal:** Every ledger write tool successfully creates its node, because relationships carry the element id `writeNodeWithEdges` actually requires.
|
|
6
|
-
|
|
7
|
-
**Architecture:** Delete the ledger's invented `GraphRelationship` and the cast that forced it past the type checker; import the real type so the shape becomes a compile-time constraint. Resolve each relationship target to an element id before writing. Add a census counter so a dead write path can no longer read as a healthy empty ledger.
|
|
8
|
-
|
|
9
|
-
**Spec:** [`.tasks/1788-...md`](../../../../.tasks/1788-ledger-write-tools-pass-an-invented-relationship-shape-so-every-write-is-rejected.md). No separate design doc; the task carries the decisions.
|
|
10
|
-
|
|
11
|
-
## Global constraints
|
|
12
|
-
|
|
13
|
-
- Node 22. Never `npm install` in this worktree; deps are symlinked from the parent.
|
|
14
|
-
- Build and test from `maxy-code/platform`.
|
|
15
|
-
- The four write tools must not be tested with a stubbed `write`. That stub is why the bug shipped.
|
|
16
|
-
- Do not touch `lib/ledger-core`'s arithmetic (money, balance, ageing) — only `reconcile.ts` gains a counter.
|
|
17
|
-
- Baseline before changes: 56 ledger tests, 508 memory-plugin tests.
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
### Task 1: Make the wrong shape a compile error
|
|
22
|
-
|
|
23
|
-
**Files:** `plugins/ledger/mcp/src/lib/types.ts`, `plugins/ledger/mcp/src/index.ts`
|
|
24
|
-
|
|
25
|
-
**Produces:** the real `GraphRelationship { type, direction, targetNodeId }` in scope for every tool.
|
|
26
|
-
|
|
27
|
-
- [ ] **Step 1: Prove the current code is wrong at the type level.** In `types.ts`, delete the local `GraphRelationship` and re-export the real one:
|
|
28
|
-
|
|
29
|
-
```ts
|
|
30
|
-
export type { GraphRelationship } from "../../../../../lib/graph-write/dist/index.js";
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
- [ ] **Step 2: Delete the cast in `index.ts`.** Replace the `writeNodeWithEdges as unknown as (...)` wrapper with a direct reference. Run `tsc -p plugins/ledger/mcp/tsconfig.json` and record every error. Expect failures in `invoice-record.ts`, `payment-record.ts`, `cash-record.ts` on `targetLabel`/`targetProps`. **Those errors are the bug** — they are what the cast was hiding.
|
|
34
|
-
|
|
35
|
-
- [ ] **Step 3: Fix the attribution while here.** `createdBy` becomes `{ agent: agentSlug, session: sessionId, tool, source: "ledger" }` with no `?? ""`, so `graph-write:254`'s `agent ?? source ?? "unknown"` chain can work.
|
|
36
|
-
|
|
37
|
-
- [ ] **Step 4: Commit** once the remaining errors are only the three tool files.
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
### Task 2: Resolve targets to element ids
|
|
42
|
-
|
|
43
|
-
**Files:** `plugins/ledger/mcp/src/lib/read.ts`, `tools/{invoice-record,payment-record,cash-record}.ts`, `index.ts`, `PLUGIN.md`
|
|
44
|
-
|
|
45
|
-
**Consumes:** the real type from Task 1.
|
|
46
|
-
|
|
47
|
-
- [ ] **Step 1: `readInvoice` returns the node's id.** Add `nodeId: string` to `InvoiceRead`; add `elementId(i) AS nodeId` to the Cypher and map it.
|
|
48
|
-
|
|
49
|
-
- [ ] **Step 2: Write the failing tests first.** For each of the three tools, assert the relationship carries a `targetNodeId` equal to the id supplied or resolved, and that no relationship carries `targetLabel`:
|
|
50
|
-
|
|
51
|
-
```ts
|
|
52
|
-
it('targets the counterparty by element id', async () => {
|
|
53
|
-
const write = okWrite()
|
|
54
|
-
await invoiceRecord({ ...base, counterpartyNodeId: '4:abc:12', session: {} as never, write })
|
|
55
|
-
const rel = write.mock.calls[0]![0].relationships[0]
|
|
56
|
-
expect(rel.targetNodeId).toBe('4:abc:12')
|
|
57
|
-
expect(rel).not.toHaveProperty('targetLabel')
|
|
58
|
-
})
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
- [ ] **Step 3: Implement.** `invoice-record` and `cash-record` take a required `counterpartyNodeId`. `payment-record` and `credit-record` use `invoice.nodeId` from the read. Each `zod` schema gains the field with a description telling the agent to look the organisation up first.
|
|
62
|
-
|
|
63
|
-
- [ ] **Step 4: Reject a blank id** before writing, with `op=reject reason=missing-counterparty`, so the failure names the cause rather than surfacing as `unresolved-target`.
|
|
64
|
-
|
|
65
|
-
- [ ] **Step 5: `tsc` clean, ledger tests green, commit.**
|
|
66
|
-
|
|
67
|
-
---
|
|
68
|
-
|
|
69
|
-
### Task 3: The test that would have caught it
|
|
70
|
-
|
|
71
|
-
**Files:** `plugins/ledger/mcp/src/tools/__tests__/write-contract.test.ts` (new)
|
|
72
|
-
|
|
73
|
-
One integration test per write tool that calls the **real** `writeNodeWithEdges` against a fake `Session` (`run` + `close`), asserting the issued Cypher carries the resolved target id and that no `unresolved-target` rejection occurs.
|
|
74
|
-
|
|
75
|
-
- [ ] **Step 1: Write it against the current code and watch it fail** if Tasks 1 and 2 were somehow incomplete.
|
|
76
|
-
- [ ] **Step 2: Confirm it passes.**
|
|
77
|
-
- [ ] **Step 3: Prove it is load-bearing.** Temporarily reintroduce `targetLabel` in one tool; the build must fail. Revert.
|
|
78
|
-
- [ ] **Step 4: Commit.**
|
|
79
|
-
|
|
80
|
-
---
|
|
81
|
-
|
|
82
|
-
### Task 4: Make a dead write path visible
|
|
83
|
-
|
|
84
|
-
**Files:** `lib/ledger-core/src/reconcile.ts`, `plugins/ledger/mcp/src/lib/read.ts`, `tools/reconcile.ts`, `ui/app/lib/ledger-census.ts`, tests
|
|
85
|
-
|
|
86
|
-
`[ledger-census]` currently prints `invoices=0 payments=0` identically whether the ledger is healthy-and-empty or wholly broken. That is why this bug ran all day unseen.
|
|
87
|
-
|
|
88
|
-
- [ ] **Step 1: Failing test.** `reconcileLedger` alarms when `writeRejects24h > 0`.
|
|
89
|
-
- [ ] **Step 2: Implement.** Add `writeRejects24h` to `LedgerCensusRows`, `LedgerCensusFinding`, the alarm condition, and `formatCensusLine`.
|
|
90
|
-
- [ ] **Step 3: Source the count.** Both the census and the reconcile tool count `[graph-write] reject` lines in `<LOG_DIR>/mcp-ledger-*.log` with a timestamp inside the trailing 24 hours.
|
|
91
|
-
- [ ] **Step 4: Tests green, commit.**
|
|
92
|
-
|
|
93
|
-
---
|
|
94
|
-
|
|
95
|
-
### Task 5: Docs
|
|
96
|
-
|
|
97
|
-
**Files:** `plugins/ledger/PLUGIN.md`, `plugins/docs/references/ledger.md`
|
|
98
|
-
|
|
99
|
-
State that the counterparty must be looked up first and passed by id, that the ledger never creates organisations, and what `writeRejects24h` means. Keep the shipped reference free of em-dashes.
|
|
100
|
-
|
|
101
|
-
- [ ] Commit.
|
|
102
|
-
|
|
103
|
-
---
|
|
104
|
-
|
|
105
|
-
## Self-review
|
|
106
|
-
|
|
107
|
-
**Spec coverage.** Type import and cast removal: Task 1. Attribution: Task 1 step 3. Element-id resolution for all four write tools: Task 2. The banned-stub integration test: Task 3. Census counter: Task 4. Docs: Task 5. Out-of-scope items (duplicate-org matching, `:InvoiceLine`, read tools, ledger-core arithmetic) are untouched.
|
|
108
|
-
|
|
109
|
-
**Risk.** Task 2 changes the tool signatures, so any agent prompt or skill that calls `ledger-invoice-record` with a bare counterparty name breaks. Nothing calls these tools yet except live agent turns, and they have never succeeded, so there is no working caller to regress.
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
# storage-pages-create Implementation Plan
|
|
2
|
-
|
|
3
|
-
> **For agentic workers:** Implement task-by-task, TDD, commit at the end. Spec: `.tasks/1852-storage-broker-has-no-client-callable-pages-create-so-a-sub-account-cannot-stand-up-a-new-booking-page.md`.
|
|
4
|
-
|
|
5
|
-
**Goal:** Add a client-callable `storage-pages-create` (MCP tool + `POST /api/storage/pages/create` route) that creates a brand-new Cloudflare Pages project and records the caller as its owner in one operation, mirroring `storage-d1-create`.
|
|
6
|
-
|
|
7
|
-
**Architecture:** New Hono route in the storage-broker route file, modelled on `/d1/create` with an added Cloudflare-existence check so a pre-existing name is refused (`exists-unregistered`) rather than self-claimed. New thin MCP client tool forwarding to it. Ownership recorded via the existing takeover-safe `registerResource` MERGE. Deploy and adopt contracts unchanged.
|
|
8
|
-
|
|
9
|
-
**Tech Stack:** TypeScript, Hono, Neo4j (registry), vitest.
|
|
10
|
-
|
|
11
|
-
## Global Constraints
|
|
12
|
-
|
|
13
|
-
- Production branch is hard-fixed to `'main'`, never a parameter (a create/deploy branch split would create on one branch and publish on another). State this in a code comment.
|
|
14
|
-
- `registerResource` is takeover-safe (MERGE on `(kind,name)`, `accountId` ON CREATE only). Pages `cfResourceId` is the project name.
|
|
15
|
-
- Deny before the house Pages credential is constructed: `cross-account` and idempotent-owner cases must return before `makeHousePagesExec` is called (tripwire).
|
|
16
|
-
- Correlated `[pages-broker] op=request` / `op=create` log lines (caller, project, existedOnCf, created, decision) — a create must be diagnosable from the log alone, same idiom as deploy.
|
|
17
|
-
- Registration surfaces in the same commit: MCP `index.ts`, `PLUGIN.md`, regenerated `canonical-tool-names.generated.ts`. `storage-pages-deploy` is in no `ADMIN_CORE_TOOLS` or specialist template, so neither is touched.
|
|
18
|
-
- `mcp/dist/` is gitignored (build artifact, not a committed twin): build + grep at verify time, do not commit dist.
|
|
19
|
-
- Shipped skill markdown: zero em-dashes; outcome statements, not command recipes.
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
### Task 1: `POST /pages/create` route + route tests
|
|
24
|
-
|
|
25
|
-
**Files:**
|
|
26
|
-
- Modify: `platform/ui/server/routes/storage-broker.ts` (add route after `/pages/adopt`)
|
|
27
|
-
- Test: `platform/ui/server/__tests__/storage-broker-pages-routes.test.ts` (extend the Neo4j mock to reflect a MERGE; add a `describe('POST /pages/create')` block)
|
|
28
|
-
|
|
29
|
-
**Interfaces:**
|
|
30
|
-
- Consumes: `caller`, `readJsonBody`, `nameBodyLimit('pages')`, `resolveOwner`, `registerResource`, `makeHousePagesExec(platformRoot())` → `{ pagesProjectList, pagesProjectCreate }`, `log`.
|
|
31
|
-
- Produces: `POST /pages/create` accepting `{project}`; responses `{project,created:true|false}` 200, `{error:'no-caller'}` 403, `{error:'project-required'}` 400, `{error:'cross-account'}` 403, `{error:'exists-unregistered'}` 409, `{error:<str>}` 500.
|
|
32
|
-
|
|
33
|
-
Route behaviour (ordering preserves the deny-before-credential tripwire):
|
|
34
|
-
1. `account = caller(c)`; null → log deny `no-caller`, 403.
|
|
35
|
-
2. `readJsonBody`; require `project` non-empty string → 400 `project-required`.
|
|
36
|
-
3. `op=request` log line (caller, project).
|
|
37
|
-
4. open session; `resolveOwner(session,'pages',project)`:
|
|
38
|
-
- owner !== null && owner !== account → `log('write','pages',account,project,owner,'deny')`, 403 `cross-account`.
|
|
39
|
-
- owner === account → `op=create existedOnCf=? created=false` is not applicable; return `{project,created:false}` 200 (before building exec).
|
|
40
|
-
- owner === null → continue.
|
|
41
|
-
5. build `exec = await makeHousePagesExec(platformRoot())`; `existed = (await exec.pagesProjectList()).some(p=>p.name===project)`.
|
|
42
|
-
- existed → `log('write','pages',account,project,null,'deny','exists-unregistered')`, `op=create existedOnCf=true created=false`, 409 `exists-unregistered`.
|
|
43
|
-
- else → `pagesProjectCreate(project,'main')`, `registerResource(session,{accountId:account,kind:'pages',name:project,cfResourceId:project})`, `log('write','pages',account,project,account,'allow')`, `op=create existedOnCf=false created=true`, 200 `{project,created:true}`.
|
|
44
|
-
6. catch → `{error:String(err)}` 500; finally → `session.close()`.
|
|
45
|
-
|
|
46
|
-
Test-mock change (backward compatible): add a per-test `registered = new Map()` cleared in `beforeEach`. In `sessionRun`: if cypher includes `'MERGE'`, set `registered.set(\`${params.kind}:${params.name}\`, params.accountId)`, return `{records:[]}`. If cypher includes `'RETURN r.accountId'` (resolveOwner), return the merged owner when present else the `ownerAnswer` behaviour. Existing tests resolve owner before any merge, so behaviour is unchanged.
|
|
47
|
-
|
|
48
|
-
- [ ] Step 1: Write the five failing route tests (created:true; idempotent created:false; cross-account 403; exists-unregistered 409; create→deploy handoff allow).
|
|
49
|
-
- [ ] Step 2: Run — expect FAIL (route 404s / handler absent).
|
|
50
|
-
- [ ] Step 3: Implement the route.
|
|
51
|
-
- [ ] Step 4: Run — expect PASS, plus the pre-existing 23 still pass.
|
|
52
|
-
|
|
53
|
-
### Task 2: `storage-pages-create` MCP tool
|
|
54
|
-
|
|
55
|
-
**Files:**
|
|
56
|
-
- Modify: `platform/plugins/storage-broker/mcp/src/index.ts` (add tool after `storage-pages-deploy`)
|
|
57
|
-
|
|
58
|
-
Mirror `storage-d1-create`. Description: "Create a new Cloudflare Pages project owned by your account, so you can publish a site to it." Arg `project`. Call `callApi("storage-pages-create","/api/storage/pages/create","POST",{project})`. Map errors:
|
|
59
|
-
- `cross-account` → `Creating the Pages project failed: "<project>" belongs to another account.`
|
|
60
|
-
- `exists-unregistered` → `The Pages project "<project>" already exists on Cloudflare but has no owner on record. A pre-existing project cannot be self-claimed; ask the house admin to record it to your account.`
|
|
61
|
-
- other → `Creating the Pages project failed: <err>`
|
|
62
|
-
- success `created===false` → `The Pages project <project> is already yours.`
|
|
63
|
-
- success else → `Created Pages project <project>. You can now publish to it.`
|
|
64
|
-
|
|
65
|
-
- [ ] Verify with an ephemeral message-mapping check (discarded after).
|
|
66
|
-
|
|
67
|
-
### Task 3: Registration surfaces (same commit)
|
|
68
|
-
|
|
69
|
-
**Files:**
|
|
70
|
-
- Modify: `platform/plugins/storage-broker/PLUGIN.md` — add `storage-pages-create` to the `tools:` block (publicAllowlist:false, adminAllowlist:true) and the `## Tools` list; correct the line-72 sentence so a client-created brand-new project is distinguished from house-recorded ownership of a pre-existing project.
|
|
71
|
-
- Regenerate: `platform/services/claude-session-manager/src/canonical-tool-names.generated.ts` via `cd platform && npm run gen:canonical-tools`.
|
|
72
|
-
- Build + grep (verify only, not committed): `platform/plugins/storage-broker/mcp/dist/index.js` carries `storage-pages-create`.
|
|
73
|
-
|
|
74
|
-
### Task 4: Skill docs (same commit)
|
|
75
|
-
|
|
76
|
-
**Files:**
|
|
77
|
-
- Modify: `platform/plugins/cloudflare/skills/site-deploy/SKILL.md:36` — after the `storage-pages-deploy`/`storage-pages-adopt` sentence, add that for a brand-new project the client first creates and claims it with `storage-pages-create`, then deploys; adopt remains only for a project that already exists on Cloudflare the client did not create.
|
|
78
|
-
- Modify: `platform/plugins/cloudflare/skills/calendar-site/SKILL.md:59` — add one sentence naming the client new-project path (`storage-pages-create` then `storage-pages-deploy`), outcome register, no command recipe.
|
|
79
|
-
|
|
80
|
-
### Verify (Phase 4)
|
|
81
|
-
|
|
82
|
-
- Route test file passes (28 tests). Ephemeral MCP message check. `check-canonical-tool-names.mjs` and typecheck pass. Build MCP dist, grep for the tool. Full `vitest run` for the ui package (no regressions in the changed area).
|