@owlmeans/viable-common 0.0.33 → 0.0.34

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.
Files changed (80) hide show
  1. package/README.md +3 -3
  2. package/agent-meta/manifest.json +2 -2
  3. package/agent-meta/skills/agent-presentation/SKILL.md +1 -1
  4. package/agent-meta/skills/viable-common/SKILL.md +93 -62
  5. package/build/ba/index.d.ts +0 -1
  6. package/build/ba/index.d.ts.map +1 -1
  7. package/build/ba/index.js +0 -1
  8. package/build/ba/index.js.map +1 -1
  9. package/build/blueprint/consts.d.ts +38 -0
  10. package/build/blueprint/consts.d.ts.map +1 -1
  11. package/build/blueprint/consts.js +40 -0
  12. package/build/blueprint/consts.js.map +1 -1
  13. package/build/blueprint/index.d.ts +0 -3
  14. package/build/blueprint/index.d.ts.map +1 -1
  15. package/build/blueprint/index.js +0 -3
  16. package/build/blueprint/index.js.map +1 -1
  17. package/build/blueprint/types.d.ts +5 -5
  18. package/build/intent/consts.d.ts +57 -0
  19. package/build/intent/consts.d.ts.map +1 -0
  20. package/build/intent/consts.js +58 -0
  21. package/build/intent/consts.js.map +1 -0
  22. package/build/intent/entrypoints.d.ts +27 -0
  23. package/build/intent/entrypoints.d.ts.map +1 -0
  24. package/build/intent/entrypoints.js +28 -0
  25. package/build/intent/entrypoints.js.map +1 -0
  26. package/build/intent/errors.d.ts +20 -0
  27. package/build/intent/errors.d.ts.map +1 -0
  28. package/build/intent/errors.js +28 -0
  29. package/build/intent/errors.js.map +1 -0
  30. package/build/intent/flow.d.ts +17 -0
  31. package/build/intent/flow.d.ts.map +1 -0
  32. package/build/intent/flow.js +65 -0
  33. package/build/intent/flow.js.map +1 -0
  34. package/build/intent/index.d.ts +7 -0
  35. package/build/intent/index.d.ts.map +1 -0
  36. package/build/intent/index.js +6 -0
  37. package/build/intent/index.js.map +1 -0
  38. package/build/intent/schemas.d.ts +10 -0
  39. package/build/intent/schemas.d.ts.map +1 -0
  40. package/build/intent/schemas.js +24 -0
  41. package/build/intent/schemas.js.map +1 -0
  42. package/build/intent/types.d.ts +40 -0
  43. package/build/intent/types.d.ts.map +1 -0
  44. package/build/intent/types.js +2 -0
  45. package/build/intent/types.js.map +1 -0
  46. package/build/skills/consts.d.ts +0 -34
  47. package/build/skills/consts.d.ts.map +1 -1
  48. package/build/skills/consts.js +0 -106
  49. package/build/skills/consts.js.map +1 -1
  50. package/build/skills/index.d.ts +0 -1
  51. package/build/skills/index.d.ts.map +1 -1
  52. package/build/skills/index.js +0 -1
  53. package/build/skills/index.js.map +1 -1
  54. package/build/skills/roles.d.ts +0 -9
  55. package/build/skills/roles.d.ts.map +1 -1
  56. package/build/skills/roles.js +0 -226
  57. package/build/skills/roles.js.map +1 -1
  58. package/package.json +17 -7
  59. package/src/ba/index.ts +0 -1
  60. package/src/blueprint/consts.ts +40 -0
  61. package/src/blueprint/index.ts +0 -3
  62. package/src/blueprint/types.ts +5 -5
  63. package/src/intent/consts.ts +66 -0
  64. package/src/intent/entrypoints.ts +43 -0
  65. package/src/intent/errors.ts +33 -0
  66. package/src/intent/flow.ts +67 -0
  67. package/src/intent/index.ts +6 -0
  68. package/src/intent/schemas.ts +27 -0
  69. package/src/intent/types.ts +45 -0
  70. package/src/skills/consts.ts +0 -112
  71. package/src/skills/index.ts +0 -1
  72. package/src/skills/roles.ts +0 -267
  73. package/tests/blueprint.spec.ts +2 -66
  74. package/tests/intent.spec.ts +121 -0
  75. package/src/ba/schemas.ts +0 -196
  76. package/src/blueprint/case.ts +0 -320
  77. package/src/blueprint/resolve.ts +0 -136
  78. package/src/blueprint/schemas.ts +0 -44
  79. package/src/skills/catalogue.ts +0 -1864
  80. package/tests/skills.spec.ts +0 -125
package/README.md CHANGED
@@ -21,7 +21,7 @@ filesystem, no inference SDK. It is safe to import from a browser bundle.
21
21
  ## Installation
22
22
 
23
23
  ```bash
24
- bun add @owlmeans/viable-common@^0.0.33
24
+ bun add @owlmeans/viable-common@^0.0.34
25
25
  ```
26
26
 
27
27
  ## Rules worth knowing before you change something
@@ -39,7 +39,7 @@ means "inherit" has no other spelling. `tests/convert.spec.ts` walks every expor
39
39
  both faults, and for draft-04 tuple `items`.
40
40
 
41
41
  **A field that crosses a version skew carries no `enum`.** A connector is installed with
42
- `npx -y @owlmeans/viable-mcp@^0.1.18-rc.30` and talks to a separately deployed platform, so an executor kind it
42
+ `npx -y @owlmeans/viable-mcp@^0.1.18-rc.31` and talks to a separately deployed platform, so an executor kind it
43
43
  sends must remain an unused capability on an older platform rather than a refused session.
44
44
 
45
45
  **A ceiling exists once.** The inquiry answer cap here equals `DEFAULT_INQUIRY_ANSWER_CHARS` in
@@ -59,7 +59,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
59
59
  your project's skill store (`.agents/skills/`):
60
60
 
61
61
  ```sh
62
- npx @owlmeans/agent-skills@^0.1.18-rc.38
62
+ npx @owlmeans/agent-skills@^0.1.18-rc.39
63
63
  ```
64
64
 
65
65
  The embedded files are version-matched to this package release. Do not edit them
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "package": "@owlmeans/viable-common",
4
- "version": "0.0.33",
5
- "generatedAt": "2026-09-23T19:57:40.697Z",
4
+ "version": "0.0.34",
5
+ "generatedAt": "2026-09-24T14:00:40.411Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -6,7 +6,7 @@ description: Shared, runtime-free taxonomy for presenting OwlMeans Viable agent
6
6
 
7
7
  # Agent output presentation
8
8
 
9
- **Install:** `"@owlmeans/viable-common": "^0.0.33"` in `dependencies`
9
+ **Install:** `"@owlmeans/viable-common": "^0.0.34"` in `dependencies`
10
10
 
11
11
  `@owlmeans/viable-common`'s `agent/presentation.ts` owns the browser-safe vocabulary for agent
12
12
  output. Keep the server and every client on `classifyAgentMessage()`; consumers may refine a
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: viable-common
3
- description: How to use @owlmeans/viable-common — the runtime-free contract package of the OwlMeans Viable platform. Covers planning cards and flows (including the landing-gate fields), project/story refusals, slot commands and layouts, slot metadata keys, target integrity, connector domain statuses and routes, conversion vocabulary, blueprint layers and cases, the persona/skill catalogue and its design house style, generated-project analysis/design/scaffold/metadata shapes, StoryDesignPort, schema conventions, and wire-version rules. Auto-invoked when importing a viable card type or flow, a slot command, a connector or conversion type, a target-integrity helper, or any *Schema this package exports.
3
+ description: How to use @owlmeans/viable-common — the runtime-free contract package of the OwlMeans Viable platform. Covers planning cards and flows (including the landing-gate fields), project/story refusals, slot commands and layouts, slot metadata keys, target integrity, connector domain statuses and routes, the intent-first hand-off (`./intent`), conversion vocabulary, blueprint layer types and the case vocabulary, the ViableSkill/ViablePersona names (never the catalogue behind them), what belongs here versus in @owlmeans/viable, generated-project analysis/design/scaffold/metadata shapes, StoryDesignPort, schema conventions, and wire-version rules. Auto-invoked when importing a viable card type or flow, a slot command, a connector or conversion type, a target-integrity helper, or any *Schema this package exports.
4
4
  user-invocable: false
5
5
  ---
6
6
  <!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
@@ -8,12 +8,13 @@ user-invocable: false
8
8
  # @owlmeans/viable-common
9
9
 
10
10
  **Layer:** Cross-cutting domain (contracts only)
11
- **Install:** `"@owlmeans/viable-common": "^0.0.33"` in `dependencies`
12
- **Subpaths:** `.` · `./slot` · `./connect` · `./convert` · `./integrity`
11
+ **Install:** `"@owlmeans/viable-common": "^0.0.34"` in `dependencies`
12
+ **Subpaths:** `.` · `./slot` · `./connect` · `./convert` · `./integrity` · `./intent`
13
13
  **Runtime-free:** no `@langchain/*`, no filesystem, no Ajv at run time (a devDependency, for the
14
14
  tests that compile the schemas). It depends on `@owlmeans/planning`, `@owlmeans/resource`,
15
- `@owlmeans/entrypoint`, `@owlmeans/route`, `@owlmeans/error`, `@owlmeans/agent-common` and
16
- `@owlmeans/llm-common` and on nothing else.
15
+ `@owlmeans/entrypoint`, `@owlmeans/route`, `@owlmeans/error`, `@owlmeans/agent-common`,
16
+ `@owlmeans/llm-common` and — for `./intent` alone — `@owlmeans/flow`, `@owlmeans/auth` and
17
+ `@owlmeans/context`, and on nothing else.
17
18
 
18
19
  Every name the OwlMeans Viable platform puts on a wire, on a volume or in a prompt is declared
19
20
  here once, and the four runtimes that must agree about it — the manager API, the agent, the
@@ -21,15 +22,24 @@ publisher/production runtime, and the connector SDK on somebody's laptop — all
21
22
  declaration. A vocabulary copied instead of imported is how one tree gets two totals, one
22
23
  refusal two spellings, and one ceiling two values.
23
24
 
25
+ **Names, not agent-only data.** This package is imported by the BROWSER too, so everything in it
26
+ ships in every visitor's bundle. Prompt, persona and blueprint-case DATA that only the AI agent
27
+ library ever reads — never the browser or another server package — belongs in `@owlmeans/viable`
28
+ instead: the skill bodies and their order, the persona prompt
29
+ policies, the blueprint case table and resolution, the BA model-answer schemas. What stays here is
30
+ what another package's contract references by type — the `ViableSkill` / `ViablePersona` enums and
31
+ the `Blueprint` types and vocabulary that execution state and card fields name.
32
+
24
33
  ## Key Exports
25
34
 
26
35
  | Subpath | What it declares |
27
36
  |---|---|
28
- | `.` (barrel) | The planning module (`VIABLE_*_TYPE`, `VIABLE_TYPE_SCHEMAS`, `VIABLE_FLOW_SCHEMAS`, `ViableStoryStatus`/`ViableProjectStatus` and their transitions, `ViableSpecCategory`, `ViableRelationship`, `ViableChannel`, `ViableProjectCard`/`ViableStoryCard`, the card helpers, the landing sentence helpers, the `Project*` refusals); `SlotMetadata` and the three metadata vocabularies (`metadataConfigs`, `metadataLists`, `metadataSecrets`), `BRANDING_ENV_KEYS` / `brandingEnv`; `ProjectArea` / `AREA_PATHS` / `AREA_ACCESS` / `AREA_TIER`; `ModelRole` and the viable `ExecutionState`; `ViableSkill` / `ViablePersona` / `VIABLE_SKILLS`; the blueprint, its cases and `landingGatePreferenceOf`; the BA, dev, UX, design and scaffold shapes and their schemas, `StoryDesignPort`; `ModerationCategory` / `ModerationSubject` / `decideModeration`; the `docs/` metadata paths; `PreviewEventType` |
37
+ | `.` (barrel) | The planning module (`VIABLE_*_TYPE`, `VIABLE_TYPE_SCHEMAS`, `VIABLE_FLOW_SCHEMAS`, `ViableStoryStatus`/`ViableProjectStatus` and their transitions, `ViableSpecCategory`, `ViableRelationship`, `ViableChannel`, `ViableProjectCard`/`ViableStoryCard`, the card helpers, the landing sentence helpers, the `Project*` refusals); `SlotMetadata` and the three metadata vocabularies (`metadataConfigs`, `metadataLists`, `metadataSecrets`), `BRANDING_ENV_KEYS` / `brandingEnv`; `ProjectArea` / `AREA_PATHS` / `AREA_ACCESS` / `AREA_TIER`; `ModelRole` and the viable `ExecutionState`; the `ViableSkill` / `ViablePersona` enums (names only); the `Blueprint` layer types, `BlueprintRef` / `BlueprintPatch`, `BlueprintCase` / `GameKind`, `DEFAULT_BLUEPRINT_ID` / `BLUEPRINT_META_KEY` and `landingGatePreferenceOf`; the BA shapes and helpers (`mergeConnectingStories`), the dev, UX, design and scaffold shapes and their schemas, `StoryDesignPort`; `ModerationCategory` / `ModerationSubject` / `decideModeration`; the `docs/` metadata paths; `PreviewEventType` |
29
38
  | `./slot` | `SlotCommandType` and the `SlotFileCommand` / `SlotShellCommand` / `SlotGitCommand` sets, `SubProject`, `WorkloadKind`, the target ports and process markers, `slotOrigin` / `targetRedirectUrisForOrigin` |
30
39
  | `./connect` | `ConnectTarget`, `ConnectLlm`, `ConnectHarness`, `ConnectExecutor`, `ConnectOpKind`, `ConnectProjectStatus`, `ConnectStoryStatus`, `ConnectPipelineState`, `ConnectWaitReason`, `ConnectProjectBranding` / `ConnectProjectBrandingSave`, `ModelTier` + `tierOfRole`/`clampTier`, `ModelTask*`, `InquiryPayload` + `ConnectInquiryKind`, the session and domain-status views, the `Connect*` error family, `connectProtocols(opts)` and every `*Schema` behind them |
31
40
  | `./convert` | `ConversionStage`/`Status`/`Decision` and the `stageAfter`/`decisionFor`/`canEnter` transitions, `OriginKind`/`Shape`/`State`, `StackId` + `STACK_FAMILY`, `ArchitectureCase`, `ConvertibilityVerdict`/`Reason`, the census classifiers (`fileClassOf`, `sizeClassOf`, `entropyClassOf`, `binaryByExtension`), the `docs/conversion/` paths, `CONVERTED_ORIGIN_DIR`, `SOURCE_LIST_EXCLUSIONS`, `CENSUS_SKIP_DIRS`, `RELOCATE_ALWAYS_KEEP`, and the model-answer schemas the conversion asks with |
32
41
  | `./integrity` | `TargetLayout` + `TARGET_LAYOUTS`, `detectTargetLayout`, `verifyTargetShape`, `TARGET_INTEGRITY_FILES`, `TARGET_PROTECTED_FILES`, `isLegacyLayout`, `targetPackageName` |
42
+ | `./intent` | The intent-first hand-off from the public site to the platform: `intent` (the four aliases), `makeIntentProtocols(opts?)` (two GUEST API routes + the `/start` landing screen), `intentFlow` + `IntentFlowStep` + `INTENT_PAYLOAD_REF`, `IntentStashBodySchema` / `IntentPickupBodySchema`, the `INTENT_*` constants (TTL, prompt cap, reference pattern, draft and suspend windows), `IntentDraft`, `IntentExpired` (404) / `IntentThrottled` (429) |
33
43
 
34
44
  ## The planning module
35
45
 
@@ -253,7 +263,7 @@ code, never as `minItems`/`maxItems`. The descriptions are what the planning mod
253
263
  state each field's purpose and bounds; `gate.target` is filled by code and described as such.
254
264
 
255
265
  **A field that crosses a version skew carries no `enum`.** Users run
256
- `npx -y @owlmeans/viable-mcp@^0.1.18-rc.30` (the moving prerelease tag) against a separately deployed
266
+ `npx -y @owlmeans/viable-mcp@^0.1.18-rc.31` (the moving prerelease tag) against a separately deployed
257
267
  platform, so `ConnectCapabilitiesSchema.executors.items`
258
268
  is a bare string: a newer executor kind must stay an unused capability on an older platform, never
259
269
  a refused session. Apply the same reasoning to anything else a newer connector may send an older
@@ -295,6 +305,45 @@ pending inquiry and `waitingFor` reason; none exposes a generic technical operat
295
305
  new long-running domain by extending its status view and endpoint, not by adding a parallel polling
296
306
  vocabulary.
297
307
 
308
+ ## The intent-first hand-off (`./intent`)
309
+
310
+ A prompt typed on the PUBLIC site (owlmeans.com, a static Astro app that cannot import the platform
311
+ repo) reaches the platform through this one subpath, which is why it lives here and not in viable:
312
+ the site, the manager API and the manager web must agree on every address, schema and step.
313
+
314
+ - **Two guest routes and one screen, no guard, no gate, no service.** `makeIntentProtocols()` declares
315
+ `stash` (POST `/public/intent`, body `{ prompt 1..8192, consent: const true }` → `{ ref, expiresAt }`),
316
+ `pickup` (POST `/public/intent/pickup`, body `{ ref }` where `ref` is exactly `createIdOfLength(24)`
317
+ Base58 → `{ prompt }`) and `landing` (`frontend()` at `/start`, `sticky`). A consumer mounts the
318
+ tree OUTSIDE any guarded parent — a route inherits every ancestor's guard, so under the account
319
+ base a visitor with no account would be refused — and fills `service` itself (the site binds
320
+ `landing` with `{ routeOptions: { overrides: { service } } }`, which is also what makes its `url()`
321
+ absolute). `consent` is a schema constant so a request without the data-processing confirmation
322
+ cannot exist on the wire.
323
+ - **The prompt never travels in a URL or a flow token.** The server keeps it `INTENT_TTL_SECONDS`
324
+ (120) under the unguessable `ref`, and collects it with one `GETDEL` (`pickup`); only `?ref=`
325
+ crosses. The flow payload is CSV-joined without escaping and the token is unsigned, so the flow
326
+ carries the reference or nothing.
327
+ - **`intentFlow` is walked on both sides and never becomes the live flow model.** `compose`
328
+ (initial, the site) →`handoff`→ `land` (initial, module = the landing) →`review`→ `review`
329
+ (module `HOME`), plus the EXPLICIT `land` →`sign-in`→ `sign-in` (module `DISPATCHER`) →`next`→
330
+ `review`. The site does `transit('handoff', true, { ref })` and redirects to `land`'s module URL
331
+ with the payload as query; the landing enters at `land` fresh, and a signed-out visitor is parked
332
+ with `suspendFlow` at `sign-in`, whose `next()` is the home screen. The parameter is `?ref=` —
333
+ never `?flow=`, which `web-flow`'s `lazyInit` parses on every page load of an app that registered
334
+ the flow service, and never `?intent=`, which the login surrogate window owns.
335
+ - **CORS is not declared here.** The routes ride the framework's global `origin: '*'` (no
336
+ credentials); `makeIntentProtocols` carries a `TODO(cors)` naming the origins to keep allowed if a
337
+ deployment ever restricts them globally.
338
+ - **The browser draft is IndexedDB, per origin.** `IntentDraft` (`id`, `ref`, `prompt`, `expiresAt`) is
339
+ what the platform's own browser keeps between pickup and the decision (`INTENT_DRAFT_TTL_MS`, 24 h,
340
+ checked on read — a client resource has no TTL). The public site cannot write it; that is the whole
341
+ reason for the server detour.
342
+
343
+ Tests: `tests/intent.spec.ts` (the four declarations and their absence of guards, the schema
344
+ accept/reject cases including crafted references, the flow walk both sides and what `suspendFlow`
345
+ would persist, the error statuses).
346
+
298
347
  ## Slot metadata keys: optional means omitted
299
348
 
300
349
  `SlotMetadata` is what the platform signs and pushes into a slot, and a slot publisher validates it
@@ -311,55 +360,36 @@ an owner setting, so it is declared on the type and kept out of them. The Google
311
360
  never travel in it: the publisher derives them from `brandingGoogleTag` itself (and from the record a
312
361
  production build writes), so the tag and the hosts it needs cannot disagree.
313
362
 
314
- ## Blueprint layers and the case table
315
-
316
- A `Blueprint` has five REQUIRED build layers (`technology`, `stack`, `template`, `createApp`,
317
- `packages`) and one OPTIONAL `experience` layer — what the product should do for its users,
318
- changing no dependency and no coder prompt. Read it only through a helper that answers the default
319
- for an absent layer: `landingGatePreferenceOf(blueprint)` answers `LandingGatePreference.Allow` for
320
- no layer, no key or a value this deploy does not know. `freezeBlueprint` freezes the layer when
321
- present and never adds it when absent.
322
-
323
- The preference is a PRIOR for the model that decides the landing gate, never the decision:
324
-
325
- | Case | `experience.landingGate` | `ViableSkill.LandingGate` added to |
326
- |---|---|---|
327
- | `web`, `ai-pipeline`, `ai-agent` | `encourage` | `BusinessAnalyst`, `UxDesigner`, `LayoutArchitect`, `ComponentArchitect`, `UiViewCoder`, `UiNavCoder` |
328
- | `scalable` | `allow` | — |
329
- | `game` | `discourage` | — |
330
-
331
- A case's `personaSkills` are composed with `joinPersonaSkills`, which UNIONS a persona two maps
332
- both name — an object spread keeps only the last list and silently drops the other case's skill.
333
- `applyBlueprintCase` then unions the case's persona skills with the base blueprint's.
334
-
335
- ## The design house style in the catalogue
336
-
337
- The `VisualDesigner` persona and the `ShadcnUi` skill teach one house style, and the template seed
338
- ships the same values: a white ground (black in dark mode) on `bg-background`; colour from ONE
339
- product accent, never from a background; depth only from a hairline, the neutral tile (`bg-muted`)
340
- and one `shadow-floating`; a heavy grotesk display face with tight tracking; motion that belongs
341
- to the illustration. The older classes (`gradient-heading`, `glass-card`, `eyebrow`, `glow-orb`,
342
- the soft/raised/glow shadows, `pulse-soft`, `spin-slow`) stay DEFINED because existing targets use
343
- them, are repainted flat, and are never taught as decoration. Any of it changes only when the
344
- customer's specification explicitly asks — a named background colour, a dark-only or coloured
345
- theme, a brand palette, gradients; the product's subject matter is not a request.
346
- `tests/skills.spec.ts` pins both texts against drifting back.
347
-
348
- `ViableSkill.LandingGate` teaches the gate-worthy story, the gate card, the synchronous handoff
349
- (`useLandingStart(target)` from the seed's `@/lib/handoff`: write, then navigate when signed in or
350
- start the plain sign-in; the guest home's `useLandingContinuation` sends the visitor on after
351
- sign-in — never `useLogin(target)`, whose continuation lands on the guarded screen) and the
352
- full-scale screen that reads and clears it. Every `ViableSkill` member has a body in `VIABLE_SKILLS` and a weight in
353
- `SKILL_ORDER`: the prompt service skips an alias it cannot resolve, so a missing body is a rule no
354
- model ever receives.
355
-
356
- `OwlMeansServer` and `FixerHeuristics` teach one rule from both ends: the PROTOCOL decides a
357
- handler's types. A handler's parameter and return types are exactly what its declaration in the
358
- target's shared entrypoints module names, imported from the shared package — never an input or
359
- record type declared in the api or backend package, which the shared package cannot import. The
360
- example handler therefore takes the shared `Task`, never an invented `…Payload`/`…Input` type
361
- (an example wins over the rule beside it), and a `TS2345` function-vs-function mismatch at a binding
362
- line is repaired in the HANDLER, never by bending the declaration toward it.
363
+ ## Blueprint types and the case vocabulary
364
+
365
+ `src/blueprint/` holds only types and constants. A `Blueprint` has five REQUIRED build layers
366
+ (`technology`, `stack`, `template`, `createApp`, `packages`) and one OPTIONAL `experience` layer —
367
+ what the product should do for its users, changing no dependency and no coder prompt. Read it only
368
+ through a helper that answers the default for an absent layer: `landingGatePreferenceOf(blueprint)`
369
+ answers `LandingGatePreference.Allow` for no layer, no key or a value this deploy does not know.
370
+ An execution carries a `BlueprintRef` — an id, an optional `case` and an override patch — never a
371
+ resolved blueprint.
372
+
373
+ `BlueprintCase` (`web`, `scalable`, `ai-pipeline`, `ai-agent`, `game`) and `GameKind` are the
374
+ vocabulary a project card's `fields.blueprintCase` / `fields.gameKind` carry. What a case MEANS —
375
+ the `BLUEPRINT_CASES` table with each case's patch, landing-gate prior and persona skills,
376
+ `applyBlueprintCase`, `applyBlueprintPatch` / `freezeBlueprint`, `joinPersonaSkills` and the
377
+ classification schema — lives in `@owlmeans/viable` (its `blueprints` / `blueprint-cases` skills).
378
+ That table is typed `Record<BlueprintCase, …>`, so a member added here fails to compile there until
379
+ it has a row.
380
+
381
+ ## Skill and persona names
382
+
383
+ `src/skills/` holds two enums and nothing else: `ViableSkill` (prompt-skill aliases) and
384
+ `ViablePersona` (who a helper's model is told it is). They are here because a `Blueprint`'s
385
+ `stack.skills` / `packages.skills` / `personaSkills` name them. The catalogue behind them — every
386
+ skill body (`VIABLE_SKILLS`) and weight (`SKILL_ORDER`), `FRAMEWORK_OWNED_SKILLS` /
387
+ `skillsForBlueprint`, each persona's prompt policy (`VIABLE_PERSONAS`), the design house style and
388
+ the landing-gate teaching — lives in `@owlmeans/viable` `src/skills/` (its `personas-and-skills`
389
+ skill). Adding a member here is half a change: `SKILL_ORDER` and `VIABLE_PERSONAS` are total records
390
+ and fail to compile until the new member has a weight or a policy, but `VIABLE_SKILLS` is a list,
391
+ and the prompt service skips an alias it cannot resolve — a missing body is a rule no model ever
392
+ receives.
363
393
 
364
394
  ## Closed sets that mean something
365
395
 
@@ -463,10 +493,8 @@ the field schemas accepting `null` and refusing an undeclared field or a value o
463
493
  set, the landing fields and the landing sentence, the card helpers, the `follows` anchor, and the
464
494
  refusals' type names surviving a marshal), `scaffold.spec.ts` (an old-shape and a new-shape plan
465
495
  both passing the schema and the `scaffold` slot, `null` optionals accepted, no `minItems`),
466
- `blueprint.spec.ts` (each case's gate preference, the default, and the persona-skill unions),
467
- `branding.spec.ts` (the build env and the metadata vocabulary), `skills.spec.ts` (every skill has a
468
- body and a weight, the handler wrap-once teaching, handler types taken from the protocol and the
469
- mismatch repaired in the handler, the house style and the landing-gate skill),
496
+ `blueprint.spec.ts` (`landingGatePreferenceOf` — the default for an absent layer or an unknown
497
+ value), `branding.spec.ts` (the build env and the metadata vocabulary),
470
498
  `connect-entrypoints.spec.ts` (the tree's protocol count, no story route, the job-id round trip,
471
499
  the branding routes and their save body),
472
500
  `convert.spec.ts` (the three structural walks over the barrel, the
@@ -486,14 +514,17 @@ marshal round trip), `connect-errors.spec.ts` (the packed fields of `ConnectOutO
486
514
  - `@owlmeans/resource` — the `ResourceError` base of the project refusals
487
515
  - `@owlmeans/entrypoint`, `@owlmeans/route` — the entrypoint declarations
488
516
  - `@owlmeans/error` — the `Connect*` error family
489
- - `@owlmeans/llm-common` — `ExecutionEffort`/`ExecutionLevel`, `PromptPolicy`, `LlmPurpose`, and the
490
- inquiry ceilings this package's copies are pinned to
517
+ - `@owlmeans/llm-common` — `ExecutionEffort`/`ExecutionLevel`, `LlmPurpose`, the spectator
518
+ contracts, and the inquiry ceilings this package's copies are pinned to
491
519
  - `@owlmeans/agent-common` — the run and pipeline contracts a conversion's runs are declared against
520
+ - `@owlmeans/flow`, `@owlmeans/auth`, `@owlmeans/context` — `./intent` only: `ShallowFlow`/`UnknownFlow`,
521
+ the `DISPATCHER` alias and the `HOME` alias its flow steps address
492
522
 
493
523
  ## Related
494
524
 
495
525
  - [[viable-sdk]] — the connector SDK written entirely against these contracts
496
526
  - [[viable-mcp]] — the npx stdio server built on that SDK
527
+ - [[flow]] · [[client-flow]] — the model `intentFlow` is walked with, and `suspendFlow`, which parks it across sign-in
497
528
  - [[inquiry]] — the primitive `InquiryPayload` mirrors, and the one answer ceiling
498
529
  - [[llm-common]] — the contracts half of the model runtime
499
530
  - [[planning]] — the workcard model, flows, fold and protocol tree the planning module builds on
@@ -1,4 +1,3 @@
1
- export * from './schemas.js';
2
1
  export * from './helpers.js';
3
2
  export * from './consts.js';
4
3
  export type * from './types.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ba/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,mBAAmB,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ba/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,mBAAmB,YAAY,CAAA"}
package/build/ba/index.js CHANGED
@@ -1,4 +1,3 @@
1
- export * from './schemas.js';
2
1
  export * from './helpers.js';
3
2
  export * from './consts.js';
4
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ba/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ba/index.ts"],"names":[],"mappings":"AACA,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA"}
@@ -8,4 +8,42 @@
8
8
  export declare const DEFAULT_BLUEPRINT_ID = "owlmeans-fullstack-ts";
9
9
  /** Recorded on a project so a later run knows which blueprint drew it. */
10
10
  export declare const BLUEPRINT_META_KEY = "blueprint";
11
+ /**
12
+ * WHICH KIND of product is being built on a blueprint.
13
+ *
14
+ * A blueprint says what the STACK is — the language, the framework, the topology, the seeds. A
15
+ * case says what is being built ON it, and that is a different question with different consumers:
16
+ * the analyst framing the brief, the architect deciding whether a story needs a queue, the coder
17
+ * choosing which packages it may import.
18
+ *
19
+ * Deliberately NOT a second blueprint. Everything a case has to say is already a blueprint field,
20
+ * so a case is a PATCH and the resolution order stays base → case → per-run overrides. That is
21
+ * also why adding one is a data change: nothing reads `BlueprintCase` except the case table
22
+ * (`BLUEPRINT_CASES` in `@owlmeans/viable`) and the prompt that classifies a project into it.
23
+ */
24
+ export declare enum BlueprintCase {
25
+ /** A web application whose every feature fits inside a request. No queue, no worker, no agents. */
26
+ Web = "web",
27
+ /** A web application with work that genuinely belongs off the request path. */
28
+ Scalable = "scalable",
29
+ /** The product's value comes from ordered, deterministic model-driven steps. */
30
+ AiPipeline = "ai-pipeline",
31
+ /** The product's value comes from an agent that decides its own path through tools. */
32
+ AiAgent = "ai-agent",
33
+ /** A browser game: a three.js scene with an ordinary React interface over it. */
34
+ Game = "game"
35
+ }
36
+ /**
37
+ * How a game is played, which decides who owns its state.
38
+ *
39
+ * Recorded beside the case rather than folded into it, because it changes nothing about the
40
+ * dependencies and everything about where the logic goes. `OnlineTurn` is the default for
41
+ * anything multiplayer unless the brief plainly asks for live play — it is the shape that
42
+ * actually builds, and it needs no socket, no tick loop and no reconciliation.
43
+ */
44
+ export declare enum GameKind {
45
+ Casual = "casual",
46
+ OnlineTurn = "online-turn",
47
+ OnlineLive = "online-live"
48
+ }
11
49
  //# sourceMappingURL=consts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../../src/blueprint/consts.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,0BAA0B,CAAA;AAE3D,0EAA0E;AAC1E,eAAO,MAAM,kBAAkB,cAAc,CAAA"}
1
+ {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../../src/blueprint/consts.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,0BAA0B,CAAA;AAE3D,0EAA0E;AAC1E,eAAO,MAAM,kBAAkB,cAAc,CAAA;AAE7C;;;;;;;;;;;;GAYG;AACH,oBAAY,aAAa;IACvB,mGAAmG;IACnG,GAAG,QAAQ;IACX,+EAA+E;IAC/E,QAAQ,aAAa;IACrB,gFAAgF;IAChF,UAAU,gBAAgB;IAC1B,uFAAuF;IACvF,OAAO,aAAa;IACpB,iFAAiF;IACjF,IAAI,SAAS;CACd;AAED;;;;;;;GAOG;AACH,oBAAY,QAAQ;IAClB,MAAM,WAAW;IACjB,UAAU,gBAAgB;IAC1B,UAAU,gBAAgB;CAC3B"}
@@ -8,4 +8,44 @@
8
8
  export const DEFAULT_BLUEPRINT_ID = 'owlmeans-fullstack-ts';
9
9
  /** Recorded on a project so a later run knows which blueprint drew it. */
10
10
  export const BLUEPRINT_META_KEY = 'blueprint';
11
+ /**
12
+ * WHICH KIND of product is being built on a blueprint.
13
+ *
14
+ * A blueprint says what the STACK is — the language, the framework, the topology, the seeds. A
15
+ * case says what is being built ON it, and that is a different question with different consumers:
16
+ * the analyst framing the brief, the architect deciding whether a story needs a queue, the coder
17
+ * choosing which packages it may import.
18
+ *
19
+ * Deliberately NOT a second blueprint. Everything a case has to say is already a blueprint field,
20
+ * so a case is a PATCH and the resolution order stays base → case → per-run overrides. That is
21
+ * also why adding one is a data change: nothing reads `BlueprintCase` except the case table
22
+ * (`BLUEPRINT_CASES` in `@owlmeans/viable`) and the prompt that classifies a project into it.
23
+ */
24
+ export var BlueprintCase;
25
+ (function (BlueprintCase) {
26
+ /** A web application whose every feature fits inside a request. No queue, no worker, no agents. */
27
+ BlueprintCase["Web"] = "web";
28
+ /** A web application with work that genuinely belongs off the request path. */
29
+ BlueprintCase["Scalable"] = "scalable";
30
+ /** The product's value comes from ordered, deterministic model-driven steps. */
31
+ BlueprintCase["AiPipeline"] = "ai-pipeline";
32
+ /** The product's value comes from an agent that decides its own path through tools. */
33
+ BlueprintCase["AiAgent"] = "ai-agent";
34
+ /** A browser game: a three.js scene with an ordinary React interface over it. */
35
+ BlueprintCase["Game"] = "game";
36
+ })(BlueprintCase || (BlueprintCase = {}));
37
+ /**
38
+ * How a game is played, which decides who owns its state.
39
+ *
40
+ * Recorded beside the case rather than folded into it, because it changes nothing about the
41
+ * dependencies and everything about where the logic goes. `OnlineTurn` is the default for
42
+ * anything multiplayer unless the brief plainly asks for live play — it is the shape that
43
+ * actually builds, and it needs no socket, no tick loop and no reconciliation.
44
+ */
45
+ export var GameKind;
46
+ (function (GameKind) {
47
+ GameKind["Casual"] = "casual";
48
+ GameKind["OnlineTurn"] = "online-turn";
49
+ GameKind["OnlineLive"] = "online-live";
50
+ })(GameKind || (GameKind = {}));
11
51
  //# sourceMappingURL=consts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"consts.js","sourceRoot":"","sources":["../../src/blueprint/consts.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,uBAAuB,CAAA;AAE3D,0EAA0E;AAC1E,MAAM,CAAC,MAAM,kBAAkB,GAAG,WAAW,CAAA"}
1
+ {"version":3,"file":"consts.js","sourceRoot":"","sources":["../../src/blueprint/consts.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,uBAAuB,CAAA;AAE3D,0EAA0E;AAC1E,MAAM,CAAC,MAAM,kBAAkB,GAAG,WAAW,CAAA;AAE7C;;;;;;;;;;;;GAYG;AACH,MAAM,CAAN,IAAY,aAWX;AAXD,WAAY,aAAa;IACvB,mGAAmG;IACnG,4BAAW,CAAA;IACX,+EAA+E;IAC/E,sCAAqB,CAAA;IACrB,gFAAgF;IAChF,2CAA0B,CAAA;IAC1B,uFAAuF;IACvF,qCAAoB,CAAA;IACpB,iFAAiF;IACjF,8BAAa,CAAA;AACf,CAAC,EAXW,aAAa,KAAb,aAAa,QAWxB;AAED;;;;;;;GAOG;AACH,MAAM,CAAN,IAAY,QAIX;AAJD,WAAY,QAAQ;IAClB,6BAAiB,CAAA;IACjB,sCAA0B,CAAA;IAC1B,sCAA0B,CAAA;AAC5B,CAAC,EAJW,QAAQ,KAAR,QAAQ,QAInB"}
@@ -1,6 +1,3 @@
1
1
  export * from './types.js';
2
2
  export * from './consts.js';
3
- export * from './case.js';
4
- export * from './schemas.js';
5
- export * from './resolve.js';
6
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/blueprint/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAE1B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/blueprint/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAE1B,cAAc,aAAa,CAAA"}
@@ -1,6 +1,3 @@
1
1
  export * from './types.js';
2
2
  export * from './consts.js';
3
- export * from './case.js';
4
- export * from './schemas.js';
5
- export * from './resolve.js';
6
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/blueprint/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAE1B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/blueprint/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAE1B,cAAc,aAAa,CAAA"}
@@ -171,11 +171,11 @@ export interface PackagesLayer {
171
171
  /**
172
172
  * Skills added to ONE persona, rather than to every prompt of the blueprint.
173
173
  *
174
- * The additive twin of {@link skillsForBlueprint}, which subtracts. `skills` above is what is
175
- * true of the whole stack; this is what is true of one performer — the analyst who has to know
176
- * that a game brief is a core loop rather than a numbered flow, the architect who has to know
177
- * when a tool loop is warranted. Without it a case could only change what a CODER is told, and
178
- * a case changes the product analysis first.
174
+ * The additive twin of `skillsForBlueprint` (in `@owlmeans/viable`), which subtracts. `skills`
175
+ * above is what is true of the whole stack; this is what is true of one performer — the analyst
176
+ * who has to know that a game brief is a core loop rather than a numbered flow, the architect who
177
+ * has to know when a tool loop is warranted. Without it a case could only change what a CODER is
178
+ * told, and a case changes the product analysis first.
179
179
  */
180
180
  personaSkills?: Partial<Record<ViablePersona, ViableSkill[]>>;
181
181
  /** Extra dependencies a role's manifest carries, beyond what the overlay ships. */
@@ -0,0 +1,57 @@
1
+ /**
2
+ * The intent-first hand-off — how a prompt typed on the public site reaches the platform.
3
+ *
4
+ * A visitor types the idea for a project on the marketing site before they have an account. The
5
+ * site cannot write into the platform's browser storage (IndexedDB is per origin) and must not put
6
+ * the prompt in a URL, so the prompt takes a short detour through the platform's own cache: the
7
+ * site stashes it behind an unguessable reference, sends the browser to the platform with only that
8
+ * reference, and the platform picks the prompt up once — after which it lives in the visitor's own
9
+ * browser until they decide what to do with it.
10
+ *
11
+ * Everything here is serializable and runtime-free: the site, the manager API and the manager web
12
+ * read the same declarations, and none of them may reinvent a name the others parse.
13
+ */
14
+ /** Every address of the hand-off. API routes are guest routes; the landing is a screen. */
15
+ export declare const intent: Readonly<{
16
+ readonly base: 'viable:manager-api:intent:base';
17
+ readonly stash: 'viable:manager-api:intent:stash';
18
+ readonly pickup: 'viable:manager-api:intent:pickup';
19
+ readonly landing: 'viable:manager-web:intent:landing';
20
+ }>;
21
+ /** Where the guest API lives, and the screen the visitor's browser is sent to. */
22
+ export declare const INTENT_API_PATH = "/public/intent";
23
+ export declare const INTENT_LANDING_PATH = "/start";
24
+ /** The flow the two sides walk. */
25
+ export declare const INTENT_FLOW = "viable:intent";
26
+ /**
27
+ * How long the platform keeps a stashed prompt waiting for pickup. Short on purpose: the pickup
28
+ * happens the moment the browser lands, so anything older was abandoned, and a prompt is personal
29
+ * data the platform has no business holding once nobody is coming for it.
30
+ */
31
+ export declare const INTENT_TTL_SECONDS = 120;
32
+ /** The longest prompt the platform will create a project from (`PromptSchema` in viable). */
33
+ export declare const INTENT_PROMPT_MAX = 8192;
34
+ /**
35
+ * The reference's shape: `createIdOfLength(24)` — Base58, so no `0`, `O`, `I` or `l`. Anything else
36
+ * is refused before the cache is asked, which keeps a crafted reference from ever being a key.
37
+ */
38
+ export declare const INTENT_REF_LENGTH = 24;
39
+ export declare const INTENT_REF_PATTERN = "^[1-9A-HJ-NP-Za-km-z]{24}$";
40
+ /** The flow payload key carrying the reference — short, because a payload is CSV-joined. */
41
+ export declare const INTENT_PAYLOAD_REF = "ref";
42
+ /** How long the visitor's draft survives in their own browser waiting for a decision. */
43
+ export declare const INTENT_DRAFT_TTL_MS: number;
44
+ /** How long a suspended landing waits while the visitor signs in or registers. */
45
+ export declare const INTENT_SUSPEND_TTL_MS: number;
46
+ /** Steps of {@link intentFlow}, exported so a screen never spells one as a literal. */
47
+ export declare enum IntentFlowStep {
48
+ /** The public site: the prompt is typed and stashed. */
49
+ Compose = "compose",
50
+ /** The platform's landing screen: the stash is picked up. */
51
+ Land = "land",
52
+ /** The platform's own sign-in dispatcher. */
53
+ SignIn = "sign-in",
54
+ /** The platform's home screen, where the draft is offered back. */
55
+ Review = "review"
56
+ }
57
+ //# sourceMappingURL=consts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../../src/intent/consts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,2FAA2F;AAC3F,eAAO,MAAM,MAAM;mBACX,gCAAgC;oBAC/B,iCAAiC;qBAChC,kCAAkC;sBACjC,mCAAmC;EACnC,CAAA;AAEX,kFAAkF;AAClF,eAAO,MAAM,eAAe,mBAAmB,CAAA;AAC/C,eAAO,MAAM,mBAAmB,WAAW,CAAA;AAE3C,mCAAmC;AACnC,eAAO,MAAM,WAAW,kBAAkB,CAAA;AAE1C;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,MAAM,CAAA;AAErC,6FAA6F;AAC7F,eAAO,MAAM,iBAAiB,OAAO,CAAA;AAErC;;;GAGG;AACH,eAAO,MAAM,iBAAiB,KAAK,CAAA;AACnC,eAAO,MAAM,kBAAkB,+BAA+B,CAAA;AAE9D,4FAA4F;AAC5F,eAAO,MAAM,kBAAkB,QAAQ,CAAA;AAEvC,yFAAyF;AACzF,eAAO,MAAM,mBAAmB,QAAsB,CAAA;AAEtD,kFAAkF;AAClF,eAAO,MAAM,qBAAqB,QAAiB,CAAA;AAEnD,uFAAuF;AACvF,oBAAY,cAAc;IACxB,wDAAwD;IACxD,OAAO,YAAY;IACnB,6DAA6D;IAC7D,IAAI,SAAS;IACb,6CAA6C;IAC7C,MAAM,YAAY;IAClB,mEAAmE;IACnE,MAAM,WAAW;CAClB"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * The intent-first hand-off — how a prompt typed on the public site reaches the platform.
3
+ *
4
+ * A visitor types the idea for a project on the marketing site before they have an account. The
5
+ * site cannot write into the platform's browser storage (IndexedDB is per origin) and must not put
6
+ * the prompt in a URL, so the prompt takes a short detour through the platform's own cache: the
7
+ * site stashes it behind an unguessable reference, sends the browser to the platform with only that
8
+ * reference, and the platform picks the prompt up once — after which it lives in the visitor's own
9
+ * browser until they decide what to do with it.
10
+ *
11
+ * Everything here is serializable and runtime-free: the site, the manager API and the manager web
12
+ * read the same declarations, and none of them may reinvent a name the others parse.
13
+ */
14
+ /** Every address of the hand-off. API routes are guest routes; the landing is a screen. */
15
+ export const intent = Object.freeze({
16
+ base: 'viable:manager-api:intent:base',
17
+ stash: 'viable:manager-api:intent:stash',
18
+ pickup: 'viable:manager-api:intent:pickup',
19
+ landing: 'viable:manager-web:intent:landing',
20
+ });
21
+ /** Where the guest API lives, and the screen the visitor's browser is sent to. */
22
+ export const INTENT_API_PATH = '/public/intent';
23
+ export const INTENT_LANDING_PATH = '/start';
24
+ /** The flow the two sides walk. */
25
+ export const INTENT_FLOW = 'viable:intent';
26
+ /**
27
+ * How long the platform keeps a stashed prompt waiting for pickup. Short on purpose: the pickup
28
+ * happens the moment the browser lands, so anything older was abandoned, and a prompt is personal
29
+ * data the platform has no business holding once nobody is coming for it.
30
+ */
31
+ export const INTENT_TTL_SECONDS = 120;
32
+ /** The longest prompt the platform will create a project from (`PromptSchema` in viable). */
33
+ export const INTENT_PROMPT_MAX = 8192;
34
+ /**
35
+ * The reference's shape: `createIdOfLength(24)` — Base58, so no `0`, `O`, `I` or `l`. Anything else
36
+ * is refused before the cache is asked, which keeps a crafted reference from ever being a key.
37
+ */
38
+ export const INTENT_REF_LENGTH = 24;
39
+ export const INTENT_REF_PATTERN = '^[1-9A-HJ-NP-Za-km-z]{24}$';
40
+ /** The flow payload key carrying the reference — short, because a payload is CSV-joined. */
41
+ export const INTENT_PAYLOAD_REF = 'ref';
42
+ /** How long the visitor's draft survives in their own browser waiting for a decision. */
43
+ export const INTENT_DRAFT_TTL_MS = 24 * 60 * 60 * 1000;
44
+ /** How long a suspended landing waits while the visitor signs in or registers. */
45
+ export const INTENT_SUSPEND_TTL_MS = 30 * 60 * 1000;
46
+ /** Steps of {@link intentFlow}, exported so a screen never spells one as a literal. */
47
+ export var IntentFlowStep;
48
+ (function (IntentFlowStep) {
49
+ /** The public site: the prompt is typed and stashed. */
50
+ IntentFlowStep["Compose"] = "compose";
51
+ /** The platform's landing screen: the stash is picked up. */
52
+ IntentFlowStep["Land"] = "land";
53
+ /** The platform's own sign-in dispatcher. */
54
+ IntentFlowStep["SignIn"] = "sign-in";
55
+ /** The platform's home screen, where the draft is offered back. */
56
+ IntentFlowStep["Review"] = "review";
57
+ })(IntentFlowStep || (IntentFlowStep = {}));
58
+ //# sourceMappingURL=consts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.js","sourceRoot":"","sources":["../../src/intent/consts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,2FAA2F;AAC3F,MAAM,CAAC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAClC,IAAI,EAAE,gCAAgC;IACtC,KAAK,EAAE,iCAAiC;IACxC,MAAM,EAAE,kCAAkC;IAC1C,OAAO,EAAE,mCAAmC;CACpC,CAAC,CAAA;AAEX,kFAAkF;AAClF,MAAM,CAAC,MAAM,eAAe,GAAG,gBAAgB,CAAA;AAC/C,MAAM,CAAC,MAAM,mBAAmB,GAAG,QAAQ,CAAA;AAE3C,mCAAmC;AACnC,MAAM,CAAC,MAAM,WAAW,GAAG,eAAe,CAAA;AAE1C;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,GAAG,CAAA;AAErC,6FAA6F;AAC7F,MAAM,CAAC,MAAM,iBAAiB,GAAG,IAAI,CAAA;AAErC;;;GAGG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAA;AACnC,MAAM,CAAC,MAAM,kBAAkB,GAAG,4BAA4B,CAAA;AAE9D,4FAA4F;AAC5F,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAA;AAEvC,yFAAyF;AACzF,MAAM,CAAC,MAAM,mBAAmB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;AAEtD,kFAAkF;AAClF,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;AAEnD,uFAAuF;AACvF,MAAM,CAAN,IAAY,cASX;AATD,WAAY,cAAc;IACxB,wDAAwD;IACxD,qCAAmB,CAAA;IACnB,6DAA6D;IAC7D,+BAAa,CAAA;IACb,6CAA6C;IAC7C,oCAAkB,CAAA;IAClB,mEAAmE;IACnE,mCAAiB,CAAA;AACnB,CAAC,EATW,cAAc,KAAd,cAAc,QASzB"}
@@ -0,0 +1,27 @@
1
+ import type { IntentPickupBody, IntentPickupResult, IntentProtocolOptions, IntentStashBody, IntentStashResult } from './types.js';
2
+ /**
3
+ * Declare the intent-first hand-off: two GUEST API routes and the landing screen's address.
4
+ *
5
+ * No guard and no gate anywhere on the API — the caller is a visitor who has no account yet — and
6
+ * no `service` on any route: each consumer fills it in (the public site names the platform's
7
+ * services in its own configuration; the manager binds them to its own).
8
+ *
9
+ * TODO(cors): these routes ride the framework's global `origin: '*'` CORS policy (no credentials).
10
+ * If viable ever restricts allowed origins globally, this entrypoint must keep answering the public
11
+ * site's origins — owlmeans.com, owlmeans.pl and, in dev/stage, `http://localhost:4321`.
12
+ *
13
+ * The landing screen is `sticky`, like the OAuth consent screens: it is an ordinary in-app screen
14
+ * that a visitor arrives at directly from another origin.
15
+ */
16
+ export declare const makeIntentProtocols: (opts?: IntentProtocolOptions) => {
17
+ base: import("@owlmeans/entrypoint").EntrypointProtocol<import("@owlmeans/entrypoint").OpenRequest, import("@owlmeans/entrypoint").OpenValue>;
18
+ stash: import("@owlmeans/entrypoint").EntrypointProtocol<{
19
+ body: IntentStashBody;
20
+ }, IntentStashResult>;
21
+ pickup: import("@owlmeans/entrypoint").EntrypointProtocol<{
22
+ body: IntentPickupBody;
23
+ }, IntentPickupResult>;
24
+ landing: import("@owlmeans/entrypoint").EntrypointProtocol<import("@owlmeans/entrypoint").OpenRequest, import("@owlmeans/entrypoint").OpenValue>;
25
+ };
26
+ export type IntentProtocols = ReturnType<typeof makeIntentProtocols>;
27
+ //# sourceMappingURL=entrypoints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entrypoints.d.ts","sourceRoot":"","sources":["../../src/intent/entrypoints.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,gBAAgB,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,eAAe,EAAE,iBAAiB,EAChG,MAAM,YAAY,CAAA;AAEnB;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB,UAAU,qBAAqB;;;;;;;;;CAkB9D,CAAA;AAED,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAA"}