@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 +2 -2
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/agent-presentation/SKILL.md +1 -1
- package/agent-meta/skills/viable-common/SKILL.md +6 -4
- package/build/skills/catalogue.js +15 -15
- package/package.json +1 -1
- package/src/skills/catalogue.ts +15 -15
- package/tests/skills.spec.ts +4 -2
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.
|
|
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.
|
|
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
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/viable-common",
|
|
4
|
-
"version": "0.0.
|
|
5
|
-
"generatedAt": "2026-09-
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
-
(`
|
|
350
|
-
|
|
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 {
|
|
829
|
-
import { writeLandingHandoff } from '@/lib/handoff'
|
|
828
|
+
import { useLandingStart } from '@/lib/handoff'
|
|
830
829
|
|
|
831
|
-
const
|
|
832
|
-
|
|
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.
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
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.
|
|
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",
|
package/src/skills/catalogue.ts
CHANGED
|
@@ -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 {
|
|
860
|
-
import { writeLandingHandoff } from '@/lib/handoff'
|
|
859
|
+
import { useLandingStart } from '@/lib/handoff'
|
|
861
860
|
|
|
862
|
-
const
|
|
863
|
-
|
|
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.
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
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:
|
package/tests/skills.spec.ts
CHANGED
|
@@ -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('
|
|
100
|
+
expect(body).toContain('useLandingStart(target)')
|
|
101
|
+
expect(body).toContain('useLandingContinuation')
|
|
101
102
|
expect(body).toContain('readLandingHandoff')
|
|
102
103
|
expect(body).toContain('clearLandingHandoff()')
|
|
103
|
-
|
|
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('${')
|