@owlmeans/viable-common 0.0.26 → 0.0.27

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/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.26
24
+ bun add @owlmeans/viable-common@^0.0.27
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.22` and talks to a separately deployed platform, so an executor kind it
42
+ `npx -y @owlmeans/viable-mcp@^0.1.18-rc.23` 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
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "package": "@owlmeans/viable-common",
4
- "version": "0.0.26",
5
- "generatedAt": "2026-09-21T21:54:22.967Z",
4
+ "version": "0.0.27",
5
+ "generatedAt": "2026-09-22T09:20:40.384Z",
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.26"` in `dependencies`
9
+ **Install:** `"@owlmeans/viable-common": "^0.0.27"` 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
@@ -8,7 +8,7 @@ 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.26"` in `dependencies`
11
+ **Install:** `"@owlmeans/viable-common": "^0.0.27"` in `dependencies`
12
12
  **Subpaths:** `.` · `./slot` · `./connect` · `./convert` · `./integrity`
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`,
@@ -253,7 +253,7 @@ code, never as `minItems`/`maxItems`. The descriptions are what the planning mod
253
253
  state each field's purpose and bounds; `gate.target` is filled by code and described as such.
254
254
 
255
255
  **A field that crosses a version skew carries no `enum`.** Users run
256
- `npx -y @owlmeans/viable-mcp@^0.1.18-rc.22` (the moving prerelease tag) against a separately deployed
256
+ `npx -y @owlmeans/viable-mcp@^0.1.18-rc.23` (the moving prerelease tag) against a separately deployed
257
257
  platform, so `ConnectCapabilitiesSchema.executors.items`
258
258
  is a bare string: a newer executor kind must stay an unused capability on an older platform, never
259
259
  a refused session. Apply the same reasoning to anything else a newer connector may send an older
@@ -346,8 +346,10 @@ theme, a brand palette, gradients; the product's subject matter is not a request
346
346
  `tests/skills.spec.ts` pins both texts against drifting back.
347
347
 
348
348
  `ViableSkill.LandingGate` teaches the gate-worthy story, the gate card, the synchronous handoff
349
- (`writeLandingHandoff` then `useLogin(target)` in one gesture) and the full-scale screen that reads
350
- and clears it. Every `ViableSkill` member has a body in `VIABLE_SKILLS` and a weight in
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
351
353
  `SKILL_ORDER`: the prompt service skips an alias it cannot resolve, so a missing body is a rule no
352
354
  model ever receives.
353
355
 
@@ -825,24 +825,24 @@ there is no gate and the hero keeps its buttons — a correct answer, not a fail
825
825
  **The handoff.** The button carries the guest's choices across sign-in in \`sessionStorage\`,
826
826
  through \`@/lib/handoff\` — never in the URL, never in a cookie, never through the server:
827
827
 
828
- import { useLogin } from '@owlmeans/client-iam'
829
- import { writeLandingHandoff } from '@/lib/handoff'
828
+ import { useLandingStart } from '@/lib/handoff'
830
829
 
831
- const [, login] = useLogin(target)
832
- const start = () => {
833
- writeLandingHandoff(target, { picks })
834
- login()
835
- }
836
- <button type="button" className="cta-btn" onClick={start}>{cta}</button>
830
+ const start = useLandingStart(target)
831
+ <button type="button" className="cta-btn" onClick={() => start({ picks })}>{cta}</button>
837
832
 
838
833
  - \`target\` is the ALIAS of the story's own full-scale screen in the user area — the prop the guest
839
- home passes — never a URL. \`useLogin(target)\` returns \`[path, handler]\`, and the handler
840
- brings the person to \`target\` once they are signed in.
841
- - The click handler is SYNCHRONOUS: write, then call the handler, in the same gesture. A sign-in
842
- that has to open a window is eaten by the popup blocker once anything has been awaited first.
843
-
844
- onClick={async () => { await saveDraft(picks); login() }} // WRONG — the gesture is gone
845
- href={'/frontoffice/recipes?picks=' + picks.join(',')} // WRONG — a URL, the picks in it, no sign-in
834
+ home passes — never a URL.
835
+ - \`useLandingStart(target)\` is the whole button: it writes the handoff, then navigates to
836
+ \`target\` when the visitor is already signed in, or starts the ordinary sign-in otherwise. After
837
+ sign-in the guest home's \`Hero\` (\`useLandingContinuation\`) sends the visitor on to \`target\`.
838
+ - NEVER \`useLogin(target)\` for the gate: its continuation navigates straight to the guarded screen,
839
+ which answers a signed-out visitor with "Sign in required", and that card's own sign-in lands on the
840
+ home page — the full-scale screen is never reached.
841
+ - The handler \`useLandingStart\` returns is SYNCHRONOUS, and the click calls it in the same gesture.
842
+ A sign-in that has to open a window is eaten by the popup blocker once anything has been awaited.
843
+
844
+ onClick={async () => { await saveDraft(picks); start({ picks }) }} // WRONG — the gesture is gone
845
+ href={'/frontoffice/recipes?picks=' + picks.join(',')} // WRONG — a URL, the picks in it, no sign-in
846
846
 
847
847
  **The full-scale screen** — the story's own screen in the user area — reads the handoff once in its
848
848
  view model, pre-fills from it, says so in one line, and clears it:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/viable-common",
3
- "version": "0.0.26",
3
+ "version": "0.0.27",
4
4
  "license": "MIT",
5
5
  "description": "Runtime-free contracts of the OwlMeans Viable platform — the analysis, design and metadata shapes of a generated project, its target-shape manifest, the slot command vocabulary, the connector protocol and the conversion vocabulary.",
6
6
  "type": "module",
@@ -856,24 +856,24 @@ there is no gate and the hero keeps its buttons — a correct answer, not a fail
856
856
  **The handoff.** The button carries the guest's choices across sign-in in \`sessionStorage\`,
857
857
  through \`@/lib/handoff\` — never in the URL, never in a cookie, never through the server:
858
858
 
859
- import { useLogin } from '@owlmeans/client-iam'
860
- import { writeLandingHandoff } from '@/lib/handoff'
859
+ import { useLandingStart } from '@/lib/handoff'
861
860
 
862
- const [, login] = useLogin(target)
863
- const start = () => {
864
- writeLandingHandoff(target, { picks })
865
- login()
866
- }
867
- <button type="button" className="cta-btn" onClick={start}>{cta}</button>
861
+ const start = useLandingStart(target)
862
+ <button type="button" className="cta-btn" onClick={() => start({ picks })}>{cta}</button>
868
863
 
869
864
  - \`target\` is the ALIAS of the story's own full-scale screen in the user area — the prop the guest
870
- home passes — never a URL. \`useLogin(target)\` returns \`[path, handler]\`, and the handler
871
- brings the person to \`target\` once they are signed in.
872
- - The click handler is SYNCHRONOUS: write, then call the handler, in the same gesture. A sign-in
873
- that has to open a window is eaten by the popup blocker once anything has been awaited first.
874
-
875
- onClick={async () => { await saveDraft(picks); login() }} // WRONG — the gesture is gone
876
- href={'/frontoffice/recipes?picks=' + picks.join(',')} // WRONG — a URL, the picks in it, no sign-in
865
+ home passes — never a URL.
866
+ - \`useLandingStart(target)\` is the whole button: it writes the handoff, then navigates to
867
+ \`target\` when the visitor is already signed in, or starts the ordinary sign-in otherwise. After
868
+ sign-in the guest home's \`Hero\` (\`useLandingContinuation\`) sends the visitor on to \`target\`.
869
+ - NEVER \`useLogin(target)\` for the gate: its continuation navigates straight to the guarded screen,
870
+ which answers a signed-out visitor with "Sign in required", and that card's own sign-in lands on the
871
+ home page — the full-scale screen is never reached.
872
+ - The handler \`useLandingStart\` returns is SYNCHRONOUS, and the click calls it in the same gesture.
873
+ A sign-in that has to open a window is eaten by the popup blocker once anything has been awaited.
874
+
875
+ onClick={async () => { await saveDraft(picks); start({ picks }) }} // WRONG — the gesture is gone
876
+ href={'/frontoffice/recipes?picks=' + picks.join(',')} // WRONG — a URL, the picks in it, no sign-in
877
877
 
878
878
  **The full-scale screen** — the story's own screen in the user area — reads the handoff once in its
879
879
  view model, pre-fills from it, says so in one line, and clears it:
@@ -97,10 +97,12 @@ describe('viable-common catalogue — the house style', () => {
97
97
 
98
98
  expect(body).toContain('data-home-gate')
99
99
  expect(body).toContain('aria-pressed')
100
- expect(body).toContain('writeLandingHandoff(target')
100
+ expect(body).toContain('useLandingStart(target)')
101
+ expect(body).toContain('useLandingContinuation')
101
102
  expect(body).toContain('readLandingHandoff')
102
103
  expect(body).toContain('clearLandingHandoff()')
103
- expect(body).toContain("useLogin(target)")
104
+ // Named only as the thing NOT to do: its continuation lands on the guarded screen.
105
+ expect(body).toContain('NEVER `useLogin(target)`')
104
106
  expect(body).toContain('SYNCHRONOUS')
105
107
  expect(body).toContain('WRONG')
106
108
  expect(body).not.toContain('${')