@storystick/cli 0.0.0-stage → 0.2.0-rc.0
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/CONTENT-IMPORT.md +349 -0
- package/LICENSE +112 -0
- package/PUBLIC-API.md +30 -0
- package/README.md +263 -2
- package/assets/next-v1/app/[[...pathname]]/error.tsx +10 -0
- package/assets/next-v1/app/[[...pathname]]/not-found.tsx +8 -0
- package/assets/next-v1/app/[[...pathname]]/page.tsx +38 -0
- package/assets/next-v1/app/api/storystick/[...action]/route.ts +4 -0
- package/assets/next-v1/app/layout.tsx +28 -0
- package/assets/next-v1/app/sitemap.ts +3 -0
- package/assets/next-v1/env.local.example +13 -0
- package/assets/next-v1/globals.css +17 -0
- package/assets/next-v1/lib/site.ts +10 -0
- package/assets/next-v1/next.config.ts +4 -0
- package/assets/skills/storystick-development/SKILL.md +79 -0
- package/assets/skills/storystick-development/references/setup.md +152 -0
- package/assets/skills/storystick-development/references/story-and-next.md +49 -0
- package/dist/_backfill-recommendation.d.ts +12 -0
- package/dist/_backfill-recommendation.js +18 -0
- package/dist/asset-import.d.ts +50 -0
- package/dist/asset-import.js +160 -0
- package/dist/assistant-read-client.d.ts +3 -0
- package/dist/assistant-read-client.js +8 -0
- package/dist/auth-device.d.ts +153 -0
- package/dist/auth-device.js +390 -0
- package/dist/bootstrap-client.d.ts +52 -0
- package/dist/bootstrap-client.js +19 -0
- package/dist/cli-error.d.ts +54 -0
- package/dist/cli-error.js +107 -0
- package/dist/cli.d.ts +68 -0
- package/dist/cli.js +1520 -0
- package/dist/commands/archive.d.ts +17 -0
- package/dist/commands/archive.js +86 -0
- package/dist/commands/backfill-refs.d.ts +54 -0
- package/dist/commands/backfill-refs.js +217 -0
- package/dist/commands/connect.d.ts +11 -0
- package/dist/commands/connect.js +124 -0
- package/dist/commands/connection.d.ts +57 -0
- package/dist/commands/connection.js +83 -0
- package/dist/commands/content.d.ts +11 -0
- package/dist/commands/content.js +107 -0
- package/dist/commands/delivery.d.ts +22 -0
- package/dist/commands/delivery.js +99 -0
- package/dist/commands/info.d.ts +35 -0
- package/dist/commands/info.js +62 -0
- package/dist/commands/list.d.ts +28 -0
- package/dist/commands/list.js +116 -0
- package/dist/commands/migrate.d.ts +80 -0
- package/dist/commands/migrate.js +550 -0
- package/dist/commands/release.d.ts +8 -0
- package/dist/commands/release.js +60 -0
- package/dist/commands/setup.d.ts +6 -0
- package/dist/commands/setup.js +58 -0
- package/dist/commands/slice-previews.d.ts +17 -0
- package/dist/commands/slice-previews.js +233 -0
- package/dist/commands/source.d.ts +82 -0
- package/dist/commands/source.js +192 -0
- package/dist/content-import.d.ts +78 -0
- package/dist/content-import.js +210 -0
- package/dist/generated-transaction.d.ts +22 -0
- package/dist/generated-transaction.js +330 -0
- package/dist/hub-client.d.ts +72 -0
- package/dist/hub-client.js +178 -0
- package/dist/init-operation.d.ts +98 -0
- package/dist/init-operation.js +427 -0
- package/dist/init-readiness.d.ts +10 -0
- package/dist/init-readiness.js +50 -0
- package/dist/init-scaffold.d.ts +54 -0
- package/dist/init-scaffold.js +439 -0
- package/dist/init.d.ts +51 -0
- package/dist/init.js +789 -0
- package/dist/mcp-execution.d.ts +15 -0
- package/dist/mcp-execution.js +90 -0
- package/dist/mcp.d.ts +7 -0
- package/dist/mcp.js +41 -0
- package/dist/migration-artifact.d.ts +13 -0
- package/dist/migration-artifact.js +154 -0
- package/dist/operations-client.d.ts +137 -0
- package/dist/operations-client.js +130 -0
- package/dist/output.d.ts +347 -0
- package/dist/output.js +771 -0
- package/dist/project-access.d.ts +18 -0
- package/dist/project-access.js +1 -0
- package/dist/project-connection.d.ts +62 -0
- package/dist/project-connection.js +347 -0
- package/dist/project-execution-client.d.ts +2 -0
- package/dist/project-execution-client.js +33 -0
- package/dist/push-client.d.ts +100 -0
- package/dist/push-client.js +160 -0
- package/dist/release-context.d.ts +13 -0
- package/dist/release-context.js +39 -0
- package/dist/release-schema-client.d.ts +16 -0
- package/dist/release-schema-client.js +33 -0
- package/dist/release-sync.d.ts +36 -0
- package/dist/release-sync.js +31 -0
- package/dist/resolve.d.ts +15 -0
- package/dist/resolve.js +80 -0
- package/dist/runtime-config.d.ts +18 -0
- package/dist/runtime-config.js +86 -0
- package/dist/schema-export.d.ts +10 -0
- package/dist/schema-export.js +28 -0
- package/dist/setup.d.ts +65 -0
- package/dist/setup.js +135 -0
- package/dist/source-git.d.ts +36 -0
- package/dist/source-git.js +197 -0
- package/dist/starter-resolver.d.ts +82 -0
- package/dist/starter-resolver.js +495 -0
- package/dist/sync-transaction.d.ts +29 -0
- package/dist/sync-transaction.js +159 -0
- package/dist/transport.d.ts +8 -0
- package/dist/transport.js +73 -0
- package/examples/sanity/README.md +79 -0
- package/examples/sanity/convert.mjs +228 -0
- package/examples/sanity/fixture/data.ndjson +7 -0
- package/examples/sanity/fixture/mapping.json +44 -0
- package/examples/sanity/fixture/originals/mark.svg +1 -0
- package/examples/sanity/stories/articleBody.story +23 -0
- package/examples/sanity/stories/copy.story +7 -0
- package/examples/sanity/stories/page.story +19 -0
- package/examples/sanity/stories/picture.story +7 -0
- package/examples/sanity/stories/settings.story +9 -0
- package/examples/sanity/stories/stack.story +10 -0
- package/package.json +75 -3
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
# Content import (development implementation)
|
|
2
|
+
|
|
3
|
+
This interface imports Main drafts through the Storystick gateway. It never
|
|
4
|
+
publishes documents, deploys a website, or changes schema/locale configuration.
|
|
5
|
+
The path is qualified locally with release tarballs, an actual isolated backend,
|
|
6
|
+
Content Plane, workerd, real development R2 and manual Studio/site preview. It
|
|
7
|
+
is not publicly released; coordinated service/package rollout remains pending.
|
|
8
|
+
|
|
9
|
+
Authenticate with `storystick login`, select a project with `--project`, and
|
|
10
|
+
install Story Files and locales through the existing tools first. The expected
|
|
11
|
+
`schemaVersion` is the installed version returned by `push --json`.
|
|
12
|
+
|
|
13
|
+
## Input
|
|
14
|
+
|
|
15
|
+
A JSON manifest references local NDJSON files inside its directory:
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"version": 1,
|
|
20
|
+
"destination": "main",
|
|
21
|
+
"namespace": "sanity-production",
|
|
22
|
+
"sourceDigest": "sha256-of-the-authoritative-source-snapshot",
|
|
23
|
+
"converter": "diduenjoy-converter-v1",
|
|
24
|
+
"schemaVersion": "installed-schema-version",
|
|
25
|
+
"policy": "create-only",
|
|
26
|
+
"records": ["documents.ndjson"],
|
|
27
|
+
"assets": ["hero.asset.json"]
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Each NDJSON line is one document family. Fields use the native content contract.
|
|
32
|
+
The temporary marker `{"_importDocument":"source-key"}` resolves to a native ID
|
|
33
|
+
wherever that ID belongs (reference field, link or pathname segment).
|
|
34
|
+
Rich text uses the native serialized ProseMirror document contract: store
|
|
35
|
+
`JSON.stringify({ type: "doc", content: [...] })` in the rich-text field. Import
|
|
36
|
+
markers inside its link attributes are resolved too; literal prose is preserved.
|
|
37
|
+
This keeps nested lists editable without exceeding database nesting limits.
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{"key":"home","storyType":"page","primaryLocale":"en","fields":{"title":"Hello","related":{"_importDocument":"about"}},"locales":[{"locale":"fr","fields":{"title":"Bonjour"}},{"locale":"zh","fields":{},"clearedPaths":["title"],"ownedPaths":[]}]}
|
|
41
|
+
{"key":"about","storyType":"page","primaryLocale":"en","fields":{"title":"About"}}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Omitted locales stay absent. Omitted localized paths inherit; `clearedPaths`
|
|
45
|
+
masks fallback. Supplied paths are owned by default, including empty strings,
|
|
46
|
+
empty arrays, `false` and `0`. `ownedPaths` specifies native path ownership.
|
|
47
|
+
`richtextEmbedOrder` optionally preserves the native relative order of localized
|
|
48
|
+
rich-text sidecar blocks. The current input does not expose keyed-array overlays;
|
|
49
|
+
do not flatten those existing states into this format.
|
|
50
|
+
|
|
51
|
+
Document writes require ready Storystick assets. A native `assetId` may be
|
|
52
|
+
replaced in the input by `{"_importAsset":"image-hero-original"}`. The server
|
|
53
|
+
resolves that source key inside this project's manifest namespace; document and
|
|
54
|
+
asset keyspaces are distinct. List local asset manifests in `assets` to plan
|
|
55
|
+
files and documents together. The CLI checks every original locally before any
|
|
56
|
+
remote planning, then reserves source identities without creating media. The
|
|
57
|
+
server validates prospective media types against the target schema. Existing
|
|
58
|
+
ready assets can also be referenced without including local originals.
|
|
59
|
+
For example, `{"hero":{"assetId":{"_importAsset":"image-hero-original"},"alt":""}}`
|
|
60
|
+
preserves the decorative occurrence while resolving only its identity.
|
|
61
|
+
Crop, hotspot, caption and locale overrides remain native field data.
|
|
62
|
+
The corpus digest binds every declared original, including unused files. Before
|
|
63
|
+
writing any documents, apply requires native verified-ready receipts for the
|
|
64
|
+
entire media inventory. Imported originals retain their source identity across
|
|
65
|
+
first upload and explicit renewal; other native asset references pin a version.
|
|
66
|
+
Editor replacements and archive are conflicts. Source URLs, storage
|
|
67
|
+
credentials and server fetching of arbitrary URLs are not accepted here.
|
|
68
|
+
|
|
69
|
+
## Original-file imports
|
|
70
|
+
|
|
71
|
+
A combined corpus imports its listed originals automatically after the reviewed
|
|
72
|
+
plan digest is checked. Individual files can also be planned and uploaded with
|
|
73
|
+
`import-asset`, then referenced by source key or native `assetId`. The Node client is exported as
|
|
74
|
+
`@storystick/cli/asset-import`. No Convex or storage credentials are needed.
|
|
75
|
+
|
|
76
|
+
An asset manifest references a local file (inside the manifest directory):
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"namespace": "sanity-production",
|
|
81
|
+
"key": "image-hero-original",
|
|
82
|
+
"file": "originals/hero.png",
|
|
83
|
+
"displayName": "Hero",
|
|
84
|
+
"altDefault": "Description of the image"
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
```sh
|
|
89
|
+
storystick content import-asset asset.json --project 12345678 --dry-run --json
|
|
90
|
+
storystick content import-asset asset.json --project 12345678 --apply --plan <digest> --json
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The dry run hashes bytes locally and validates metadata remotely without creating
|
|
94
|
+
assets or upload sessions. It reserves `(project, namespace, key)` to a native
|
|
95
|
+
asset identity in protocol state. Apply creates that native asset/session before
|
|
96
|
+
returning a scoped upload URL. Retrying that key
|
|
97
|
+
with changed bytes or metadata is a conflict. Retrying identical input reuses
|
|
98
|
+
the session or its ready receipt, including after temporary session GC. An
|
|
99
|
+
editor's replacement or archive is never overwritten by this path.
|
|
100
|
+
|
|
101
|
+
The client transfers exact bytes; native finalization verifies them and may strip
|
|
102
|
+
invisible image metadata under the existing media policy. It does not resize or
|
|
103
|
+
re-encode pixels. A lost PUT response is resolved through checksum verification;
|
|
104
|
+
an existing object cannot be overwritten with the delegated URL. Sanitization
|
|
105
|
+
retries require a server-authenticated source proof, never client checksum metadata.
|
|
106
|
+
|
|
107
|
+
This interface covers JPEG, PNG, WebP, GIF, still AVIF, static SVG, video and supported file
|
|
108
|
+
formats. Videos and files larger than 8 MiB use the native multipart cycle.
|
|
109
|
+
The CLI hashes incrementally and uploads bounded parts, resumes from server
|
|
110
|
+
receipts, and finalizes only after the server verifies the complete SHA-256.
|
|
111
|
+
Part URLs bind the part number, byte length and MD5, and expire no later than the
|
|
112
|
+
native session. Concurrent initialization retains one provider upload identity;
|
|
113
|
+
known unused uploads are aborted. An unknown initialization outcome relies on
|
|
114
|
+
the bucket's incomplete-multipart lifecycle, which must be qualified at deployment.
|
|
115
|
+
|
|
116
|
+
An expired or failed upload returns a `renewable` receipt. Review the reported
|
|
117
|
+
failure, then renew explicitly with the session ID and the same source/plan:
|
|
118
|
+
|
|
119
|
+
```sh
|
|
120
|
+
storystick content import-asset asset.json --project 12345678 --apply --plan <digest> --renew <upload-session-id> --json
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Renewal retains the asset identity, allocates a new version/storage key, and
|
|
124
|
+
passes native admission again. Replaying the same renewal returns that attempt;
|
|
125
|
+
it never renews a second time implicitly. A pending upload must be resumed.
|
|
126
|
+
An editor's intervening upload or archive is a conflict. Failed import shells
|
|
127
|
+
remain owned by their source binding so session/version cleanup does not lose
|
|
128
|
+
the asset identity; explicit library archive still prevents renewal. Version
|
|
129
|
+
allocation stays monotonic even after failed-version cleanup. Old transferred
|
|
130
|
+
objects follow native GC. After standalone renewal, resume the combined corpus
|
|
131
|
+
with its original sealed plan. Asset acknowledgements are replayable receipts;
|
|
132
|
+
`verify` rechecks all media, including originals unused by documents.
|
|
133
|
+
|
|
134
|
+
### Project upload budgets
|
|
135
|
+
|
|
136
|
+
The hourly upload guard is not a commercial tariff. A team owner or administrator
|
|
137
|
+
can explicitly authorize a bounded project allowance through the gateway:
|
|
138
|
+
|
|
139
|
+
```json
|
|
140
|
+
{"requestId":"migration-2026-10","sessions":400,"bytes":1073741824,"reason":"Production snapshot originals"}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
```sh
|
|
144
|
+
storystick content upload-budget budget.json --project 12345678 --dry-run --json
|
|
145
|
+
storystick content upload-budget budget.json --project 12345678 --apply --plan <digest> --json
|
|
146
|
+
storystick content upload-budget --project 12345678 --json
|
|
147
|
+
storystick content upload-budget-cancel migration-2026-10 --project 12345678 --json
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
The pre-launch server policy admits at most one budget per rolling 24 hours,
|
|
151
|
+
capped at 5,000 new upload sessions and 10 GiB of declared bytes, expiring after
|
|
152
|
+
24 hours. It replaces only the 120-sessions/hour guard while active. The ten
|
|
153
|
+
simultaneous-upload guard, individual format limits and ready-storage quotas
|
|
154
|
+
still apply. This policy is separate from future commercial entitlements.
|
|
155
|
+
|
|
156
|
+
The project allowance covers **all native Media uploads**, including Studio and
|
|
157
|
+
CLI uploads. Each new attempt consumes a session and its declared bytes in the
|
|
158
|
+
allocation transaction. Resume/replay consumes nothing more; renewal is a new
|
|
159
|
+
attempt. Failure does not refund admission. Cancellation ends the allowance;
|
|
160
|
+
it does not stop already admitted transfers or allow another grant within the
|
|
161
|
+
same day. Exhaustion returns a structured `RATE_LIMITED` error and `Retry-After`.
|
|
162
|
+
|
|
163
|
+
Budget receipts and `assetUploadAdmissions` survive temporary-session cleanup
|
|
164
|
+
and content wipe. They record admission, not actual network traffic or invoices.
|
|
165
|
+
The public Node transport is `uploadBudgetTransport` from
|
|
166
|
+
`@storystick/cli/asset-import`, using the same gateway session as other imports.
|
|
167
|
+
|
|
168
|
+
### Static SVG originals
|
|
169
|
+
|
|
170
|
+
SVG is a native image format, capped at 8 MiB. The server parses the entire UTF-8
|
|
171
|
+
XML document and admits a bounded static profile: paths, basic shapes, groups,
|
|
172
|
+
text, local gradients/patterns, clips/masks, local `<use>` references, simple
|
|
173
|
+
presentation styles and bounded class/ID/element CSS rules. Embedded raster
|
|
174
|
+
data URLs admit PNG, JPEG and WebP only. `currentColor` stays intact. Scripts,
|
|
175
|
+
event handlers, custom DTDs/entities, external resources, links, CSS at-rules,
|
|
176
|
+
animation and nested viewports are rejected explicitly. Standard SVG 1.0/1.1
|
|
177
|
+
DOCTYPE declarations are recognized without fetching resources. Reference
|
|
178
|
+
cycles and ambiguous referenced IDs are rejected. Accepted bytes are preserved
|
|
179
|
+
exactly; rejected artwork is
|
|
180
|
+
never silently sanitized or rasterized. Export a compatible static original
|
|
181
|
+
when the error identifies an unsupported feature.
|
|
182
|
+
|
|
183
|
+
Dimensions come from positive pixel lengths and/or `viewBox`. Delivery adds
|
|
184
|
+
`nosniff` and an isolated CSP. The SDK and Studio display the vector original;
|
|
185
|
+
width, height and display density do not generate raster substitutes. Cropping
|
|
186
|
+
and explicit raster encoding are unsupported and return an error instead of
|
|
187
|
+
being ignored. An external SVG's `currentColor` does not inherit the HTML page's
|
|
188
|
+
color: preserve the original frontend's image/mask integration.
|
|
189
|
+
|
|
190
|
+
## Plan, apply, resume
|
|
191
|
+
|
|
192
|
+
```sh
|
|
193
|
+
storystick content import manifest.json --project 12345678 --dry-run --json
|
|
194
|
+
storystick content import manifest.json --project 12345678 --apply --plan <digest> --json
|
|
195
|
+
storystick content import manifest.json --project 12345678 --resume <run-id> --apply --plan <digest> --json
|
|
196
|
+
storystick content import-status <run-id> --project 12345678 --json
|
|
197
|
+
storystick content verify <run-id> --project 12345678 --json
|
|
198
|
+
storystick content import-cancel <run-id> --project 12345678 --json
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Dry run reserves source identities and stores resumable protocol records on the
|
|
202
|
+
server. It writes **no documents, assets, schema or locale configuration**. Only
|
|
203
|
+
authorized project editors can stage or inspect that private input.
|
|
204
|
+
`.storystick/imports/` stores a local run handle, not source content or credentials.
|
|
205
|
+
The server is authoritative if that local file is lost. Keep local handles out
|
|
206
|
+
of version control with the rest of `.storystick/` state.
|
|
207
|
+
|
|
208
|
+
At most ten imports can be active per project. Temporary source input expires
|
|
209
|
+
after 30 days and is pruned in bounded batches. Completed/cancelled runs are
|
|
210
|
+
eligible immediately. Plans, receipts and source bindings survive input cleanup;
|
|
211
|
+
an expired unfinished run must be prepared again with a new run ID.
|
|
212
|
+
|
|
213
|
+
All batches must be planned before sealing the digest. Apply requires that exact
|
|
214
|
+
digest and rechecks live permissions, schema generation, locale settings, draft
|
|
215
|
+
witnesses and media versions. Lost responses reuse the same run/batch identity.
|
|
216
|
+
Transient retries are bounded and honor Retry-After; longer waits are resumable.
|
|
217
|
+
Native writes, usage facts, receipts and Preview clocks commit atomically per batch.
|
|
218
|
+
|
|
219
|
+
- `create-only`: create new bindings; an identical unchanged prior import is a no-op.
|
|
220
|
+
- `missing-only`: preserve existing bound drafts, including editor modifications.
|
|
221
|
+
- `update-bound`: update only drafts matching the last imported witness. An
|
|
222
|
+
intervening editor change is a conflict even when requesting a fresh plan.
|
|
223
|
+
|
|
224
|
+
No policy deletes content, changes a story/primary locale, or removes a locale
|
|
225
|
+
implicitly. A new namespace does not take ownership of existing singletons.
|
|
226
|
+
Resolve editorial conflicts explicitly; `--dry-run --new-run` prepares a fresh
|
|
227
|
+
protocol run when appropriate. Cancel retains committed batches; it is not Undo.
|
|
228
|
+
|
|
229
|
+
`verify` compares native readback with receipts and checks the Content Plane
|
|
230
|
+
watermark separately. It exits nonzero for drift, incomplete imports or pending
|
|
231
|
+
projection. A ready watermark is not proof of browser rendering: SDK readback,
|
|
232
|
+
preview and visual acceptance remain separate.
|
|
233
|
+
|
|
234
|
+
## Bounds and architecture
|
|
235
|
+
|
|
236
|
+
The pure planner computes strongly connected components and orders dependencies
|
|
237
|
+
before consumers. Cycles stay within one transaction; there are no invalid
|
|
238
|
+
placeholder documents. Independent components are packed into batches of up to
|
|
239
|
+
five documents to leave native execution headroom. Larger cycles remain atomic.
|
|
240
|
+
Hard limits: 2,000 documents, 20 documents / 256 KiB per batch,
|
|
241
|
+
32 MiB of staged input per run. Asset inventories are capped at 2,000 entries
|
|
242
|
+
and the whole manifest at 384 KiB; acknowledgements/readback use groups of 20. Oversized cycles fail before staging. Native
|
|
243
|
+
transaction limits still apply with large schemas/locales; exceeding them rolls
|
|
244
|
+
back the batch rather than bypassing validation.
|
|
245
|
+
|
|
246
|
+
The Node-only client is `@storystick/cli/content-import`; the pure format/planner
|
|
247
|
+
is `@storystick/core/content-import`. Neither belongs in a rendering bundle.
|
|
248
|
+
For a scripted combined corpus, compose `readContentImport`,
|
|
249
|
+
`prepareContentImportAssets` and `prepareContentImport`, review the returned
|
|
250
|
+
digest, upload the returned asset plans using `applyAssetImport`, then call
|
|
251
|
+
`applyContentImport`. The latter acknowledges verified files before documents.
|
|
252
|
+
A cancellation stops future document batches; independent asset uploads already
|
|
253
|
+
admitted retain their normal native lifecycle.
|
|
254
|
+
|
|
255
|
+
## Sanity reference converter
|
|
256
|
+
|
|
257
|
+
The distributed [Sanity example](examples/sanity/README.md) is a local, explicit
|
|
258
|
+
project mapping with Story Files, a synthetic three-language snapshot and tests.
|
|
259
|
+
It preserves native rich text/embeds, container slices, cyclic references,
|
|
260
|
+
original files and sparse locale intent. Unknown editorial data fails with a
|
|
261
|
+
source path. Copy and adapt it to the actual source/frontend contract; it is not
|
|
262
|
+
a universal schema converter. The isolated tarball qualification also runs its
|
|
263
|
+
public Core/schema/client tests. A native component test checks its sidecar,
|
|
264
|
+
locale and SVG writes without publication.
|
|
265
|
+
|
|
266
|
+
## Gateway access boundary
|
|
267
|
+
|
|
268
|
+
The SDK's public token audience is no longer accepted by raw Convex RPC. The
|
|
269
|
+
WebSocket gateway exchanges it for a server-only, equally bounded credential;
|
|
270
|
+
Next Preview's control reads/commands use the Storystick HTTP gateway and the
|
|
271
|
+
existing native operations. This requires a coordinated Central/Worker/Next SDK
|
|
272
|
+
release and a paired Worker service secret. See
|
|
273
|
+
[`sub-gateway/README.md`](../../services/sub-gateway/README.md#gateway-only-sdk-authentication).
|
|
274
|
+
No infrastructure secret is part of the migration client setup.
|
|
275
|
+
|
|
276
|
+
## Qualification completed locally — 28 October 2026
|
|
277
|
+
|
|
278
|
+
The consumer was installed outside the monorepo from release tarballs, including
|
|
279
|
+
the CLI, Core and Next SDK. Its importer used ordinary Storystick credentials
|
|
280
|
+
and public HTTP contracts; it received no Convex administration or R2 keys.
|
|
281
|
+
An operator provisioned the isolated local Convex/Postgres/Content Plane/Workers
|
|
282
|
+
and their secrets separately, as platform operations would in a hosted service.
|
|
283
|
+
|
|
284
|
+
- The bundled Sanity example imported three document families, cyclic refs,
|
|
285
|
+
nested slices, a singleton, sparse `en/fr/zh`, native rich-text marks/lists and
|
|
286
|
+
embeds, and one original SVG. Native readback and projection matched receipts.
|
|
287
|
+
- Actual R2 accepted exact original bytes, refused a signed-length mismatch and
|
|
288
|
+
refused overwrite after finalize. A 9 MiB multipart file resumed after its
|
|
289
|
+
first part, without resending it; replay transferred no more parts. A small
|
|
290
|
+
video used the native multipart cycle too. Complete hashes were verified.
|
|
291
|
+
- The development bucket needed the already-tracked `If-None-Match` CORS header.
|
|
292
|
+
After applying that development CORS config, the real preflight returned 204.
|
|
293
|
+
Its incomplete multipart lifecycle was inspected: abort after seven days.
|
|
294
|
+
That configuration check does not claim an elapsed seven-day lifecycle test.
|
|
295
|
+
- A consumer-only routable Story exercised Next preview. Native Studio edits
|
|
296
|
+
appeared in English, French and Chinese without a manual reload. The SVG
|
|
297
|
+
rendered as a vector in both Studio and the site. False/zero/empty collections,
|
|
298
|
+
inheritance and a deliberately cleared Chinese hero stayed distinct.
|
|
299
|
+
- Final verification still matched the untouched Sanity corpus. The separately
|
|
300
|
+
edited route correctly reported a content conflict with a ready projection;
|
|
301
|
+
verification neither overwrote the editor's changes nor confused them with
|
|
302
|
+
delivery lag. CLI JSON classifies drift as a conflict and lag as retryable.
|
|
303
|
+
- The actual auth provider rejected direct SDK RPC, accepted the server relay
|
|
304
|
+
credential, and the Worker relayed subscriptions/refresh. Public credentials
|
|
305
|
+
alone could not exchange for an internal token or submit usage counters.
|
|
306
|
+
- HTTP attempt observations and sequential cumulative relay receipts were read
|
|
307
|
+
from the local backend. Unit/native-runtime cases cover unknown outcomes,
|
|
308
|
+
idempotent replay, producer authentication and bounded queues on meter failure.
|
|
309
|
+
|
|
310
|
+
The real exercise found and corrected inherited-rich-text materialization,
|
|
311
|
+
object rich-text embed composition, a Workers redirect-mode mismatch and the
|
|
312
|
+
Studio reader's remaining raster-only restriction. It used synthetic content;
|
|
313
|
+
it neither rewrote nor reimported the Diduenjoy website. All documents remained
|
|
314
|
+
drafts and no website was deployed.
|
|
315
|
+
|
|
316
|
+
Reproducible fast gates include `node scripts/content-import-qualification.mjs`
|
|
317
|
+
(after package builds), the CLI's bundled Sanity tests, the native
|
|
318
|
+
`content-import*.test.ts` component tests, targeted gateway authority/usage
|
|
319
|
+
suites, and `pnpm --filter @storystick/sub-gateway test:runtime`. Mock-gateway
|
|
320
|
+
packaging checks, local native infrastructure, and manual preview are separate
|
|
321
|
+
proofs. None establishes production capacity.
|
|
322
|
+
|
|
323
|
+
## Remaining release gates and limits
|
|
324
|
+
|
|
325
|
+
- Publish matching artifacts/docs and roll out Central, relay and SDK together;
|
|
326
|
+
qualify deployment-specific auth, CORS, storage lifecycle and capacity there.
|
|
327
|
+
- Choose commercial entitlements, aggregation/retention policy and accounting
|
|
328
|
+
export. The implementation provides durable facts, not a tariff or invoices.
|
|
329
|
+
`gatewayUsageAttempts` observes management and SDK HTTP attempts;
|
|
330
|
+
`gatewayRelayUsage` observes Worker-admitted payloads before forwarding.
|
|
331
|
+
Neither measures confirmed network delivery, repeated delegated R2 transfers
|
|
332
|
+
or provider egress. `contentUsageEvents` and upload admissions separately
|
|
333
|
+
describe native effects and admitted sessions/bytes. See the relay README.
|
|
334
|
+
- The migration skill is structurally validated and now points to these concrete
|
|
335
|
+
capabilities. Its controlled with/without-skill behavioral evaluation is still
|
|
336
|
+
unmeasured; no model-quality improvement is claimed from infrastructure tests.
|
|
337
|
+
- V1 imports Main drafts. Native `richtextEmbedOrder` is preserved on sparse
|
|
338
|
+
locale layers. Release destinations, keyed-array locale overlays and other
|
|
339
|
+
bundled CMS converters remain unsupported.
|
|
340
|
+
|
|
341
|
+
Local qualification is not a deployment or publication.
|
|
342
|
+
|
|
343
|
+
The image profile preserves GIF frame payloads, timing and loops. Still AVIF
|
|
344
|
+
accepts unrotated item-based images and erases Exif/XMP without changing encoded
|
|
345
|
+
image extents. Sequences and unsupported transforms fail explicitly. Static SVG
|
|
346
|
+
originals up to 8 MiB may contain simple presentation styles, bounded local
|
|
347
|
+
reuse, masks, gradients, color-matrix filters and embedded PNG/JPEG/WebP. Scripts,
|
|
348
|
+
external resources, arbitrary DTDs, recursive or excessive expansion remain
|
|
349
|
+
rejected. The delivery CSP allows only inline styles and embedded image data.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Functional Source License, Version 1.1, MIT Future License
|
|
2
|
+
|
|
3
|
+
## Abbreviation
|
|
4
|
+
|
|
5
|
+
FSL-1.1-MIT
|
|
6
|
+
|
|
7
|
+
## Notice
|
|
8
|
+
|
|
9
|
+
Copyright 2026 Tanguy Freycon
|
|
10
|
+
|
|
11
|
+
## Terms and Conditions
|
|
12
|
+
|
|
13
|
+
### Licensor ("We")
|
|
14
|
+
|
|
15
|
+
The party offering the Software under these Terms and Conditions.
|
|
16
|
+
|
|
17
|
+
### The Software
|
|
18
|
+
|
|
19
|
+
The "Software" is each version of the software that we make available under
|
|
20
|
+
these Terms and Conditions, as indicated by our inclusion of these Terms and
|
|
21
|
+
Conditions with the Software.
|
|
22
|
+
|
|
23
|
+
### License Grant
|
|
24
|
+
|
|
25
|
+
Subject to your compliance with this License Grant and the Patents,
|
|
26
|
+
Redistribution and Trademark clauses below, we hereby grant you the right to
|
|
27
|
+
use, copy, modify, create derivative works, publicly perform, publicly display
|
|
28
|
+
and redistribute the Software for any Permitted Purpose identified below.
|
|
29
|
+
|
|
30
|
+
### Permitted Purpose
|
|
31
|
+
|
|
32
|
+
A Permitted Purpose is any purpose other than a Competing Use. A Competing Use
|
|
33
|
+
means making the Software available to others in a commercial product or
|
|
34
|
+
service that:
|
|
35
|
+
|
|
36
|
+
1. substitutes for the Software;
|
|
37
|
+
|
|
38
|
+
2. substitutes for any other product or service we offer using the Software
|
|
39
|
+
that exists as of the date we make the Software available; or
|
|
40
|
+
|
|
41
|
+
3. offers the same or substantially similar functionality as the Software.
|
|
42
|
+
|
|
43
|
+
Permitted Purposes specifically include using the Software:
|
|
44
|
+
|
|
45
|
+
1. for your internal use and access;
|
|
46
|
+
|
|
47
|
+
2. for non-commercial education;
|
|
48
|
+
|
|
49
|
+
3. for non-commercial research; and
|
|
50
|
+
|
|
51
|
+
4. in connection with professional services that you provide to a licensee
|
|
52
|
+
using the Software in accordance with these Terms and Conditions.
|
|
53
|
+
|
|
54
|
+
### Patents
|
|
55
|
+
|
|
56
|
+
To the extent your use for a Permitted Purpose would necessarily infringe our
|
|
57
|
+
patents, the license grant above includes a license under our patents. If you
|
|
58
|
+
make a claim against any party that the Software infringes or contributes to
|
|
59
|
+
the infringement of any patent, then your patent license to the Software ends
|
|
60
|
+
immediately.
|
|
61
|
+
|
|
62
|
+
### Redistribution
|
|
63
|
+
|
|
64
|
+
The Terms and Conditions apply to all copies, modifications and derivatives of
|
|
65
|
+
the Software.
|
|
66
|
+
|
|
67
|
+
If you redistribute any copies, modifications or derivatives of the Software,
|
|
68
|
+
you must include a copy of or a link to these Terms and Conditions and not
|
|
69
|
+
remove any copyright notices provided in or with the Software.
|
|
70
|
+
|
|
71
|
+
### Disclaimer
|
|
72
|
+
|
|
73
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR
|
|
74
|
+
IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR
|
|
75
|
+
PURPOSE, MERCHANTABILITY, TITLE OR NON-INFRINGEMENT.
|
|
76
|
+
|
|
77
|
+
IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO THE
|
|
78
|
+
SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES,
|
|
79
|
+
EVEN IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.
|
|
80
|
+
|
|
81
|
+
### Trademarks
|
|
82
|
+
|
|
83
|
+
Except for displaying the License Details and identifying us as the origin of
|
|
84
|
+
the Software, you have no right under these Terms and Conditions to use our
|
|
85
|
+
trademarks, trade names, service marks or product names.
|
|
86
|
+
|
|
87
|
+
## Grant of Future License
|
|
88
|
+
|
|
89
|
+
We hereby irrevocably grant you an additional license to use the Software under
|
|
90
|
+
the MIT license that is effective on the second anniversary of the date we make
|
|
91
|
+
the Software available. On or after that date, you may use the Software under
|
|
92
|
+
the MIT license, in which case the following will apply:
|
|
93
|
+
|
|
94
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
95
|
+
this software and associated documentation files (the "Software"), to deal in
|
|
96
|
+
the Software without restriction, including without limitation the rights to
|
|
97
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
98
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
|
99
|
+
so, subject to the following conditions:
|
|
100
|
+
|
|
101
|
+
The above copyright notice and this permission notice shall be included in all
|
|
102
|
+
copies or substantial portions of the Software.
|
|
103
|
+
|
|
104
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
105
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
106
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
107
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
108
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
109
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
110
|
+
SOFTWARE.
|
|
111
|
+
|
|
112
|
+
This Agreement shall be governed by the laws of France.
|
package/PUBLIC-API.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# @storystick/cli API contract
|
|
2
|
+
|
|
3
|
+
Install this candidate explicitly with `@storystick/cli@0.2.0-rc.0` after registry bootstrap and publication. This repository alone does not make the candidate or beta channel available on npm.
|
|
4
|
+
|
|
5
|
+
Version 0.2.0-rc.0, cohort `sdk-0.2.0-rc.0`. ESM distribution; no CommonJS or universal Edge compatibility is promised.
|
|
6
|
+
|
|
7
|
+
This package is a product integration facade. Reserved contracts are required between SDK packages and must be upgraded with the same cohort. Their public export paths do not promise independent stability.
|
|
8
|
+
|
|
9
|
+
| Entry | Status |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| `./resolve` | Supported beta entry |
|
|
12
|
+
| `./content-import` | Supported beta entry |
|
|
13
|
+
| `./asset-import` | Supported beta entry |
|
|
14
|
+
|
|
15
|
+
## Command contract
|
|
16
|
+
|
|
17
|
+
| Commands | Status |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| `setup`, `schema`, `generate`, `guide` | Supported beta local tooling |
|
|
20
|
+
| `init`, `connect`, `login`, `logout`, `whoami`, `list`, `info`, `push`, `sync` | Supported beta onboarding/schema workflow; matching service and operator permissions required |
|
|
21
|
+
| `archive`, `content`, `migrate`, `backfill-refs`, `slice-previews sync` | Advanced beta operations; plans, receipts, authorization and readback remain command-specific |
|
|
22
|
+
| `source`, `release`, `connection`, `delivery`, `mcp` | Advanced matching-service contracts; server capability/permission checks apply, without independent protocol stability |
|
|
23
|
+
|
|
24
|
+
Library exports `resolve`, `content-import` and `asset-import` are advanced beta Node APIs. The MCP host owns its model loop. Commands never acquire effect authority from this support table. Use each command's `--help` and the README for its exact flags, JSON/exit contract, confirmation and resumability rules.
|
|
25
|
+
|
|
26
|
+
The qualified toolchain is Node 24.19.0 and pnpm 9.15.9. Next uses App Router 15.5.28, Sharp 0.35.5 and React/React DOM 19.2.8; Astro uses 7.4.4 with the Node adapter 11.1.9. Browser delivery is verified by bundling; hosted Preview activation and cross-browser behavior require the staging manual check. Source/CLI are Node tools, server entries belong on the server, and browser entries must never receive a server API key.
|
|
27
|
+
|
|
28
|
+
This is a support/tooling contract. It does not independently grant project access or permission to perform effects.
|
|
29
|
+
|
|
30
|
+
The repository is private. Public package availability does not make the monorepo public, and npm provenance from that repository is unavailable. Product and pilot support: [Storystick](https://storystick.app).
|