@amityco/social-plus-vise 1.3.0 → 1.4.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/CHANGELOG.md +45 -2
- package/README.md +19 -9
- package/dist/capabilities.js +29 -1
- package/dist/entryState.js +71 -0
- package/dist/experience.js +70 -0
- package/dist/explore.js +1 -1
- package/dist/flow.js +382 -0
- package/dist/humanFormat.js +25 -0
- package/dist/intake.js +117 -0
- package/dist/intelligence/placement.js +2 -1
- package/dist/outcomes.js +126 -28
- package/dist/productExpectations.js +15 -0
- package/dist/requestReadiness.js +99 -0
- package/dist/server.js +566 -19
- package/dist/sidecar.js +5 -0
- package/dist/solutionPath.js +1 -1
- package/dist/tools/compliance.js +752 -125
- package/dist/tools/creative.js +14 -12
- package/dist/tools/design.js +321 -11
- package/dist/tools/experienceCompiler.js +1 -1
- package/dist/tools/experienceSensors.js +1 -1
- package/dist/tools/harness.js +13 -0
- package/dist/tools/integration.js +263 -90
- package/dist/tools/learning.js +1 -3
- package/dist/tools/project.js +963 -66
- package/dist/tools/smoke.js +134 -0
- package/dist/tools/uxHarness.js +54 -6
- package/dist/uikitCustomization.js +3 -1
- package/dist/version.js +7 -3
- package/package.json +1 -1
- package/packages/intelligence/catalog/catalog.schema.json +1 -1
- package/packages/intelligence/catalog/experience-objects.json +2 -2
- package/packages/intelligence/catalog/variants.json +24 -0
- package/rules/event.yaml +3 -0
- package/rules/feed.yaml +251 -0
- package/rules/invitation.yaml +4 -0
- package/rules/live-data.yaml +110 -0
- package/rules/notification-tray.yaml +4 -0
- package/rules/poll.yaml +5 -0
- package/rules/sdk-lifecycle.yaml +559 -0
- package/rules/search.yaml +5 -0
- package/rules/security.yaml +12 -0
- package/rules/story.yaml +5 -0
- package/rules/user-blocking.yaml +5 -0
- package/skills/social-plus-vise/SKILL.md +163 -15
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,50 @@ All notable changes to `@amityco/social-plus-vise` are documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is loosely based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## Unreleased
|
|
8
|
+
|
|
9
|
+
No changes yet.
|
|
10
|
+
|
|
11
|
+
## 1.4.0 — 2026-07-02
|
|
12
|
+
|
|
13
|
+
**Entry-state flow + alignment gate.** `vise plan`/`init` now run a persona-free entry-state flow ahead of the build. A broad, multi-surface goal expands into a **blueprint** — the surfaces and experience to build — and for that journey `vise init` requires a human **blueprint sign-off** before it scaffolds anything: the *alignment gate* ("are we building the right thing?"), distinct from and complementary to the deterministic compliance gate ("did we build it the right way?"). The sign-off is a SELECT, not a rubber stamp — when the solution path is undecided it hard-picks `sdk` / `uikit` / `hybrid` first and surfaces candidate experiences, persists the choice, re-arms if the path/journey/design source changes, and cannot be bypassed. (A single-surface init is gated by intake/clarify, not the blueprint sign-off.)
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
- **Clarify-to-classify.** When a request is too vague to classify or names a capability the SDK doesn't support, `vise plan` returns a structured `clarify` block instead of silently scaffolding, and `vise init` blocks (exit 7) rather than guessing.
|
|
17
|
+
- **Runtime-readiness consent + no-data gate.** The blueprint runtime-readiness packet now makes natural target discovery explicit, tells agents what to do when tenant data is absent (Console prep or safe SDK seed data before populated proof), and requires asking the user before expensive browser/simulator/emulator runtime proof. If proof or data setup is declined, agents must report the remaining runtime risks instead of claiming product proof.
|
|
18
|
+
- **All-platform dogfood evidence packet.** Recorded the 2026-06-28 TypeScript, React Native, Android, Flutter, and iOS improvement loop with matrix results, runtime screenshots, validation commands, cleanup notes, and the explicit native caveat that RN/Flutter currently have starter launch proof but not archived completed-output proof.
|
|
19
|
+
- **SDK field-shape correctness advisories (TS/JS).** Advisory detectors (`warning`, never gate `vise check`) that catch *wrong-shape* use of correctly-named SDK symbols — a reaction count read as an object off a `number`, a follow `status` compared to a value absent from the SDK enum — grounded in the extracted SDK type model. The wrong-field class an exact-name presence check can't see.
|
|
20
|
+
- **Loading-state UX advisory (TS/JS).** Advisory detector that flags an SDK live-data binding rendered with no loading state nearby (the empty/blank-flash class), independent of the empty/error completeness baseline. Recognizes loaders by stem-matching the rendered component (skeleton/shimmer/spinner/progress families, library-agnostic) rather than an exact-name allowlist.
|
|
21
|
+
- **First-class `livestream` surface** and curated **messaging / discussion / creator experience bundles** in the Engagement Intelligence catalog.
|
|
22
|
+
- **`vise workplan trim`** — deliberately omit a companion surface on a multi-surface blueprint; requires a `--reason` and re-arms the blueprint sign-off (the trimmed blueprint must be re-signed before proceeding).
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
- **Experience-calibration dogfood harness honors current governance.** The harness now accepts EI variants with grounded rationale/confidence, performs the multi-surface blueprint sign-off with a digest before `init`, and preserves the runtime-boundary checks for score/ranking/upload/customer-data behavior.
|
|
26
|
+
- **ID-free target defaults.** Feed, follow, community, and chat intakes default to their ID-free / self / discovery sources rather than a hardcoded community or target id, so the agent never invents an id it wasn't given (advisory; gates unchanged).
|
|
27
|
+
- **React Native dogfood starter launchability.** The RN native starter now uses `expo run:ios` / `expo run:android` for runtime proof and pins `react-native-screens` to the Expo SDK 53-compatible range that builds on the local iOS simulator.
|
|
28
|
+
- **One design sign-off per journey.** On a multi-surface blueprint the per-surface design-preview confirmation is folded into the single blueprint sign-off — you approve the design once for the whole journey rather than per surface.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
**File-scoped attestation** — closes a false-negative in the merge gate found while verifying the brownfield baseline (pf-053 follow-up). Previously `vise attest` greened a rule **globally**: a session could attest a rule once over a legacy violation and then ship NEW code violating the *same* rule undetected — and `vise check --new-only` could **not** catch it, because the attested rule was green before baseline subtraction ran. An attestation is now **scoped to the violator files present at attest time**; a live violation in any file the attestation never covered re-gates the rule (`attestation-needed` / `deterministic-fail`, naming the uncovered file).
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
- **`vise check` re-gates new co-located violators of an attested rule.** For rules on the file-scopable allowlist, the attested green now covers only the reviewed files. This is intentionally stricter than before — a previously-masked new violation now gates. Rules **not** on the allowlist (project-aggregate rules such as `client.region`, whose finding points at a representative file rather than a located violation) keep the historical rule-global behavior, so this never false-gates. The allowlist (`FILE_SCOPABLE_SENSOR_SUFFIXES` in `compliance.ts`) covers **all 44** verified loop-file-scoped attestable per-file rules — the complete set of located-misuse detectors (e.g. `posts.status-filter-applied`, `feed.post-datatype-handled`, `live-collection.api-mismatch`, `comments.target-resolved`, `chat.sort-explicit`, `comments.query-has-limit`, `livestream.deprecated-stream`, `session-handler.retained`, `logging.no-secret-in-log`, the per-surface `*.live-collection` rules). Each entry is guarded by a test that fails if it stops resolving to a real attestable rule.
|
|
36
|
+
- **~19 per-file sensors converted to enumerate every violator** (they previously stopped at the first via an outer-loop `break` / `return findings` / per-rule dedup), so a file-scoped attestation over one violator can't mask a co-located new violation of the same rule. Covers `feed.post-datatype-handled`, `comments.target-resolved`, `chat.channel-type-dm`, the deprecated-chat/livestream detectors, `community.avatar-from-sdk`, `feed.poll-answer-data-shape`, `comments.query-has-limit`, `chat.sort-explicit`, `profile.social-counts-from-sdk`, `community.display-name-from-sdk`, `feed.room-post-fetched`, `feed.ui-states-present`, `session-handler.retained`, `client.no-ssr-init`, `follow.status-subscription`, and the `logging.no-secret-in-log` / `logging.no-pii-in-log` line scanner. (Non-attestable deterministic-fail rules like `chat.channel-target-resolved` are unaffected — they can't be attested, so there is nothing to scope.)
|
|
37
|
+
|
|
38
|
+
### Changed (cont.)
|
|
39
|
+
- **Attest-while-clean bypass — closed.** A file-scopable rule is now **always** marked `file_scoped`, even when attested while its sensor is *not* firing. The covered set is then just the attester's evidence files (often empty), so a violation introduced **later** is uncovered and re-gates (`attestation-needed`), instead of being masked rule-globally by an unscoped attestation. Guarded by a mutation-verified CLI test: a clean attest with prose-only evidence (empty covered set) → a new violator re-gates under `--new-only`. Old (pre-marker) attestations remain grandfathered to rule-global, so `test:sidecar-compat` stays green.
|
|
40
|
+
|
|
41
|
+
### Known residuals (disclosed)
|
|
42
|
+
- **Non-`"."` surface paths** are believed correct (attest and check both resolve via `sourceRootForCompliance` / `resolveEvidenceSourcePath`, which coincide with `inspection.effectiveRoot` when the surface root is set) but are **not yet covered by a test** — all current tests use surface `"."`.
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
- **`attest` records `file_scoped: true` + `source_fingerprints` for the live-violator files** (tagged `live_sensor_violator`) when a file-scopable rule is attested; the CLI response echoes `file_scoped` and `scoped_files`. The check-time pf-068 contradiction disclosure is unchanged; this adds the *check-time* enforcement it could only warn about at attest time.
|
|
46
|
+
|
|
47
|
+
### Compatibility
|
|
48
|
+
- **Additive sidecar field.** Attestation files gain an optional `file_scoped` flag and `live_sensor_violator` `source_fingerprints`; old attestations lack the flag and keep rule-global behavior (the frozen 1.1.0 `test:sidecar-compat` baseline stays green). The rule corpus and contract digest are unchanged, so existing attestations are not invalidated. **Behavior note:** a file-scoped rule that was attested over a legacy violation will now re-gate if the *same* rule is violated in a new/uncovered file — re-attest (covering the new file) or fix it. A bare `vise check` and `--new-only` both honor the new scope.
|
|
49
|
+
- **Re-run `vise baseline` after upgrading.** The converted sensors now emit one finding per violating file; for a rule with multiple violators in the SAME file, the single displayed `finding.file` can shift (first→last violator), which changes that rule's `rule@file` baseline key. A `baseline.json` recorded before this change may therefore not match the new key for such a rule, causing a pre-existing finding to re-gate under `--new-only`. The ruleset digest is unchanged so the staleness guard does not flag it — re-run `vise baseline` once after upgrading to refresh the keys.
|
|
50
|
+
|
|
7
51
|
## 1.3.0 — 2026-06-19
|
|
8
52
|
|
|
9
53
|
Discovery + readability surface, CLI/report honesty, and a batch of detector-precision fixes from two real-agent persona-dogfood sweeps (Sonnet 4.6), each fix mutation-verified and the whole batch adversarially reviewed. **No change to `vise check` exit codes, compliance rules, or sidecar *formats*** — the sidecar gains only **additive** fields (see Compatibility). The rule corpus is unchanged, so the contract digest is stable and no re-attestation is triggered.
|
|
@@ -624,8 +668,7 @@ The design, completeness, and SDK-version layers are **advisory** — they infor
|
|
|
624
668
|
- **agy + codex runners** (`run-agy-cells.sh`, `run-codex-cells.sh`) — production-quality scripts with TTY-detection fixes and workspace isolation.
|
|
625
669
|
|
|
626
670
|
### Findings & reports
|
|
627
|
-
-
|
|
628
|
-
- `benchmarks/MARKETING.html` — three-tier marketing-claim framework (safe / concrete / honest / aspirational) with supporting wallclock data and a list of metrics to instrument next.
|
|
671
|
+
- Historical generated HTML reports captured the benchmark methodology, results, and marketing-claim framework for this round. They were later removed from source control during the 1.4.0 benchmark cleanup; retained summaries now live in Markdown result files.
|
|
629
672
|
|
|
630
673
|
### Honest claim
|
|
631
674
|
On 9 new SDK domain implementations with codex gpt-5.4, vise+skill produced 7 working features vs 3 for pure MCP — same agent, same prompts. The cost: +28% wallclock per session. The net: −52% wallclock per *working* feature, because more features ship on the first try. Vise consistently catches five bug classes that capable models otherwise miss: wrong DM channel type, missing push register/unregister lifecycle, one-shot queries where live subscriptions are required, missing ban checks before write operations, and missing flag affordances on user-generated content.
|
package/README.md
CHANGED
|
@@ -77,7 +77,7 @@ vise install-skill --target copilot . # GitHub Copilot / VS Code
|
|
|
77
77
|
# "Add a social feed to this app using the social.plus SDK."
|
|
78
78
|
```
|
|
79
79
|
|
|
80
|
-
The skill drives the loop automatically — `vise inspect` → `vise plan` → `vise init` → edit code → `vise check` → `vise run-sensors`. You drive intent, answer scope questions, and
|
|
80
|
+
The skill drives the loop automatically — `vise inspect` → `vise plan` → `vise init` → edit code → `vise check` → `vise run-sensors`. You drive intent, answer scope questions, and **sign off the blueprint** (what gets built) before the agent writes a line; Vise keeps the agent honest. For dogfood or release proof, also launch the app and capture runtime evidence; static checks do not replace seeing the surface run. See [How it works](#how-it-works).
|
|
81
81
|
|
|
82
82
|
All skill targets:
|
|
83
83
|
|
|
@@ -98,11 +98,12 @@ Prefer a per-project install? `npm install -D @amityco/social-plus-vise`, then c
|
|
|
98
98
|
## How it works
|
|
99
99
|
|
|
100
100
|
1. **Inspect** — `vise inspect` detects the platform, app surfaces, available sensors, and design signals from the local repo.
|
|
101
|
-
2. **Plan** — `vise plan --request "..."` classifies the outcome, cites docs, and raises blocking intake and design-preview questions. Use `--summary` when you only need the route/intake readout before implementation. The agent surfaces questions; you answer.
|
|
102
|
-
3. **Initialize** — `vise init` writes the `sp-vise/` compliance contract.
|
|
101
|
+
2. **Plan** — `vise plan --request "..."` classifies the outcome, cites docs, and raises blocking intake and design-preview questions. If the request is too vague to classify or names a capability the SDK doesn't support, it returns a structured **clarify** block instead of guessing; for a broad goal it expands the outcome into a **blueprint** — the surfaces and experience it proposes to build. Use `--summary` when you only need the route/intake readout before implementation. The agent surfaces questions; you answer.
|
|
102
|
+
3. **Initialize** — `vise init` writes the `sp-vise/` compliance contract. For a **multi-surface build** (a journey spanning more than one surface), it first makes you **sign off the blueprint**: the *what* — the solution path (`sdk` / `uikit` / `hybrid`) and the experience/surfaces to build. This is the **alignment gate** — *"are we building the right thing?"* — the human-judgment counterpart to the deterministic compliance gate (*"did we build it the right way?"*) in step 5. `init` refuses and exits 7 until the request is resolved: `status: "needs-clarification"` when intake is unanswered or the request can't be classified, and `status: "needs-blueprint-confirmation"` until the blueprint is signed (`--answer blueprint_confirmation=<digest>`). The sign-off can't be bypassed, and it re-arms if the path, journey, or design source later changes.
|
|
103
103
|
4. **Build** — the agent edits your code, grounded by `vise search-docs` and `vise get-doc-page`.
|
|
104
104
|
5. **Check & repair** — `vise check` reports deterministic findings, completeness gaps, and attestation needs. The agent fixes findings or records attestations with evidence, looping until green.
|
|
105
105
|
6. **Sense** — `vise run-sensors` runs your project's own typecheck/build/lint/SDK smokes. Done means the contract and evidence are committed, not just that the agent stopped.
|
|
106
|
+
7. **Prove runtime readiness** — for dogfood, release, or any user-visible handoff, ask before spending browser/simulator/emulator/device resources. If approved, boot the actual target, capture screenshots/logs, and record what data was discovered or created at runtime. Discover targets naturally from host app state, SDK queries, user selection, or SDK create-flow return values; if the tenant has no data, ask whether to prepare Console data or seed safe dogfood data before claiming populated proof. When a `sp-vise/smoke.json` contract exists, run `vise smoke` against captured logs; `expect: "populated"` requires `loaded count=N` with `N > 0`. If runtime proof is declined or a completed native output cannot be archived, say so explicitly; starter launch proof is useful, but it is not proof that the completed social.plus surface ran.
|
|
106
107
|
|
|
107
108
|
### Solution path & UIKit routing (advisory)
|
|
108
109
|
|
|
@@ -122,17 +123,19 @@ The layer is set by the *kind of claim*, which is how Vise is designed to avoid
|
|
|
122
123
|
|
|
123
124
|
Correctness is gated by deterministic rules or attestations; completeness is gated by explicit scope decisions; conformance stays advisory because "matches the brand" is legitimately subjective. Each gating rule is itself mutation-verified — its fix is reverted to confirm the check actually fails without it, so a rule that can't fail is removed rather than shipped as theater. `vise explain <ruleId>` prints any rule's rationale, evidence requirements, and remediation.
|
|
124
125
|
|
|
126
|
+
Runtime proof is a separate evidence layer. `vise check` and `vise run-sensors` can prove structure, completeness, and local build commands, but they cannot prove that the selected community/feed/chat route renders on a cold launch. Ask before running browser or native runtime proof because it can consume local resources and agent tokens. If the user declines, state the expected limitation: cold-launch session races, empty tenant data, route wiring, permissions, and native packaging remain unproven. Use `vise smoke` where the app declares a runtime-smoke contract.
|
|
127
|
+
|
|
125
128
|
**Supported outcomes:** feed · comments · chat · moderation · community · social graph (follow) · in-app notifications · plus setup (SDK, push, live data). `vise plan`/`init` classify the request and tailor the plan, rules, and feature checklist.
|
|
126
129
|
|
|
127
130
|
### Engagement Intelligence
|
|
128
131
|
|
|
129
|
-
**Advisory, in preview.** The three layers above answer *whether you built it right*. Ahead of the build, Vise can also help reason about *what to build*: an **Engagement Intelligence** layer turns a product goal into multiple candidate **engagement strategies** — archetypes, UX patterns, and solution variants drawn from a social.plus experience catalog — with rationale, tradeoffs, no-fit guidance, availability boundaries, and review gaps. The human or driving agent still chooses the direction, then Vise compiles that selected variant into an implementation plan (`vise creative` → `vise creative accept` → `vise experience compile`), optionally bridging to installable social.plus blocks, plus advisory UX expectations and a multi-dimension experience review.
|
|
132
|
+
**Advisory, in preview.** The three layers above answer *whether you built it right*. Ahead of the build, Vise can also help reason about *what to build*: an **Engagement Intelligence** layer turns a product goal into multiple candidate **engagement strategies** — archetypes, UX patterns, and solution variants drawn from a social.plus experience catalog — with rationale, tradeoffs, no-fit guidance, availability boundaries, and review gaps. The driving agent presents the EI choice as a visible decision — recommended experience, concrete fit signals, credible alternatives, tradeoffs, expected blueprint surfaces, and no-fit option — before it accepts a variant. The human or driving agent still chooses the direction, then Vise compiles that selected variant into an implementation plan (`vise creative` → `vise creative accept` → `vise experience compile`), optionally bridging to installable social.plus blocks, plus advisory UX expectations and a multi-dimension experience review.
|
|
130
133
|
|
|
131
134
|
It is **local-only, never uploads, carries no calibrated score**, and **never changes `vise check`'s exit codes**. The opt-in ranking preview is review context, not a top-1 confidence claim or autonomous product-strategy selector. Use it to shape the work; the validation layers still decide when it's done.
|
|
132
135
|
|
|
133
136
|
### Design contracts
|
|
134
137
|
|
|
135
|
-
Vise can ingest your aesthetic from an HTML/CSS prototype (`vise design extract`) or from the host app's own design system across web, Android, Flutter, and iOS (`vise design extract --from-project`). The contract is **advisory input for generation**, never an enforcement gate, and it feeds forward into plans only after you confirm the generated preview with `--answer design_contract_confirmation=yes
|
|
138
|
+
Vise can ingest your aesthetic from an HTML/CSS prototype (`vise design extract`) or from the host app's own design system across web, Android, Flutter, and iOS (`vise design extract --from-project`). The contract is **advisory input for generation**, never an enforcement gate, and it feeds forward into plans only after you confirm the generated preview with `--answer design_contract_confirmation=yes` — and on a multi-surface blueprint that confirmation is folded into the single blueprint sign-off, so you approve the design once for the whole journey rather than per surface. For social.plus-specific styling, `vise design init-tokens` scaffolds a dedicated, customer-editable token file (`src/styles/social-plus-tokens.css`) — edit it, re-extract, and future builds inherit the palette with no agent in the loop.
|
|
136
139
|
|
|
137
140
|
## Evidence
|
|
138
141
|
|
|
@@ -185,13 +188,14 @@ Run `vise <command> --help` for full flags. JSON output is the default for agent
|
|
|
185
188
|
| `vise workplan next [path] --request "..."` | For broad social requests: print the next uncompleted surface and its focused commands |
|
|
186
189
|
| `vise workplan status [path] --request "..."` | Show the workplan sequence and completed surfaces |
|
|
187
190
|
| `vise workplan complete [path] --request "..." --surface <id>` | Record a green-checked surface; snapshots evidence under `sp-vise/workplan-snapshots/<surface>/` |
|
|
191
|
+
| `vise workplan trim [path] --request "..." --surface <id> --reason "..."` | Deliberately omit a companion surface (surface-level scope-omit). `--reason` required; re-arms the blueprint sign-off gate (re-sign the trimmed blueprint before proceeding) |
|
|
188
192
|
|
|
189
193
|
### Creative pre-planning (advisory)
|
|
190
194
|
|
|
191
195
|
| Command | Purpose |
|
|
192
196
|
|---|---|
|
|
193
197
|
| `vise creative [path] --request "..." [--requirements <path\|none>] [--prototype <html>] [--ranking-preview]` | Write an advisory Engagement Intelligence brief with multiple candidate solution variants, rationale, tradeoffs, and review gaps; `--ranking-preview` adds opt-in, local-only review context that never reorders the default candidates |
|
|
194
|
-
| `vise creative accept [path] --variant <id
|
|
198
|
+
| `vise creative accept [path] --variant <id> --rationale "..." --confidence high\|medium\|low` | Record the grounded selected variant so `plan`/`init`/`workplan` carry it forward; `--variant none --rationale "..." --confidence high\|medium\|low` records a catalog-gap signal instead |
|
|
195
199
|
| `vise ux-harness [path]` | Generate advisory UX expectations from the accepted selection |
|
|
196
200
|
| `vise experience compile [path]` | Compile the accepted variant into an implementation artifact plan |
|
|
197
201
|
| `vise experience sensors [path]` | Write an advisory multi-dimension sensor framework (no calibrated score) |
|
|
@@ -207,7 +211,8 @@ Everything in this group is local and advisory: no uploads, no `vise check` exit
|
|
|
207
211
|
|---|---|
|
|
208
212
|
| `vise design extract <prototypePath> [--repo .] [--no-write]` | Extract a graded design contract + visual preview from an HTML/CSS prototype |
|
|
209
213
|
| `vise design extract --from-project [path] [--no-write]` | Derive the contract from the project's own design system: CSS custom properties (incl. shadcn/Tailwind v4 `@theme`), TS/JS token modules, Android `colors.xml`/`dimens.xml`, Flutter `Color(0x…)`, iOS `.colorset`/Swift colors |
|
|
210
|
-
| `vise design check [path]` | Advisory token-conformance report; never fails a build |
|
|
214
|
+
| `vise design check [path]` | Advisory token-conformance report (incl. computed WCAG for the brand palette's role pairs when a profile exists); never fails a build |
|
|
215
|
+
| `vise design contrast <foreground> <background>` | Compute the WCAG 2.x contrast ratio between two colours (advisory) — check any text/icon colour that isn't a palette role instead of eyeballing it |
|
|
211
216
|
| `vise design preview [path] [--reference <prototype>]` | Write a self-contained visual review (`sp-vise/design-preview.html`) for human/VLM judgment |
|
|
212
217
|
| `vise design reference [path] [--title <name>]` | Write a self-contained design-system spec: swatches, type samples, component demos |
|
|
213
218
|
| `vise design init-tokens [path] [--force]` | Scaffold `src/styles/social-plus-tokens.css` (greenfield defaults or seeded from existing tokens); idempotent |
|
|
@@ -239,6 +244,7 @@ Everything in this group is local and advisory: no uploads, no `vise check` exit
|
|
|
239
244
|
| Command | Purpose |
|
|
240
245
|
|---|---|
|
|
241
246
|
| `vise run-sensors [path] [--dry-run]` | Run detected project scripts (npm, Gradle, Flutter, lint, typecheck, SDK smokes); `--dry-run` lists without executing |
|
|
247
|
+
| `vise smoke [path] --log <file>` | Assess a captured runtime mount-smoke log into a pass/fail verdict + record evidence. `expect: "populated"` requires `loaded count=N` with `N > 0`; this catches the session-establish and empty-data gaps `vise check` can't see (see [docs/RUNTIME_SMOKE.md](docs/RUNTIME_SMOKE.md)) |
|
|
242
248
|
| `vise install-skill --target <host>` | Install the bundled skill into a coding host (see [Quick Start](#quick-start)) |
|
|
243
249
|
| `vise print-skill` | Print the skill markdown to stdout |
|
|
244
250
|
| `vise engagement init [path] [--tier ...] [--customer-id ...] [--scope ...]` | Record optional contractual scope metadata |
|
|
@@ -260,7 +266,7 @@ MCP-capable hosts can call Vise as structured tool calls instead of shell comman
|
|
|
260
266
|
}
|
|
261
267
|
```
|
|
262
268
|
|
|
263
|
-
Tool names (snake_case per MCP convention): `inspect_project`, `creative_brief`, `creative_accept`, `ux_harness`, `compile_experience`, `experience_sensors`, `plan_harness`, `plan_integration`, `init_compliance`, `check_compliance`, `experience_report`, `record_learning`, `show_learning`, `sync_compliance`, `attest_rule`, `explain_rule`, `init_engagement`, `show_engagement`, `search_docs`, `get_doc_page`, `debug_issue`, `validate_setup`, `run_sensors`, `design_extract`, `design_check`, `design_preview`, `design_reference`, `design_init_tokens`.
|
|
269
|
+
Tool names (snake_case per MCP convention): `inspect_project`, `creative_brief`, `creative_accept`, `ux_harness`, `compile_experience`, `experience_sensors`, `plan_harness`, `plan_integration`, `init_compliance`, `check_compliance`, `experience_report`, `record_learning`, `show_learning`, `sync_compliance`, `attest_rule`, `explain_rule`, `init_engagement`, `show_engagement`, `search_docs`, `get_doc_page`, `debug_issue`, `validate_setup`, `run_sensors`, `design_extract`, `design_check`, `design_contrast`, `design_preview`, `design_reference`, `design_init_tokens`.
|
|
264
270
|
|
|
265
271
|
These mirror the CLI commands above. The adapter still answers the legacy `resolve_request` and `suggest_patch` names, but they are deprecated in favour of `plan_integration` plus host-tool edits.
|
|
266
272
|
|
|
@@ -313,15 +319,19 @@ Vise writes local planning, compliance, design, and evidence artifacts under `sp
|
|
|
313
319
|
| `sp-vise/creative-brief.json` + `creative-brief.md` | `vise creative` | Advisory brief: goals, archetypes, candidate variants (JSON + human-readable) |
|
|
314
320
|
| `sp-vise/candidate-ranking-preview.json` | `vise creative --ranking-preview` | Opt-in local ranking preview for review context; `experience_score: null`, no uploads, no default-order change, no top-1 confidence claim |
|
|
315
321
|
| `sp-vise/creative-selection.json` | `vise creative accept` | Accepted variant and plan/workplan feed-forward context |
|
|
316
|
-
| `sp-vise/catalog-gap.json` | `vise creative accept --variant none` | Local-only no-fit signal for human catalog review |
|
|
322
|
+
| `sp-vise/catalog-gap.json` | `vise creative accept --variant none --rationale "..." --confidence high\|medium\|low` | Local-only no-fit signal for human catalog review |
|
|
317
323
|
| `sp-vise/ux-harness.json` | `vise creative accept` or `vise ux-harness` | Advisory UX pattern expectations and anti-patterns |
|
|
318
324
|
| `sp-vise/experience-compiler.json` | `vise experience compile` | Advisory implementation plan: install guidance, surfaces, validation commands |
|
|
319
325
|
| `sp-vise/experience-sensors.json` | `vise experience sensors` | Advisory sensor framework; `score: null` until calibrated |
|
|
320
326
|
| `sp-vise/experience-report.json` | `vise experience-report` | Advisory dimensioned review; `score: null` until calibrated |
|
|
321
327
|
| `sp-vise/learning-events.jsonl` | `vise learning record` | Append-only, local-only learning event log |
|
|
322
328
|
| `sp-vise/learning-summary.json` | `vise learning record` | Derived summary; `recommendationOptimization.status: "not-active"` |
|
|
329
|
+
| `sp-vise/flow.json` | `vise workplan next` / `trim` | Entry-state, selected solution path, active blueprint digest, sign-off state, and omitted companion surfaces |
|
|
330
|
+
| `sp-vise/flow-blueprint.html` | `vise workplan next` | Human-readable blueprint preview for the alignment gate; review before passing `blueprint_confirmation=<digest>` |
|
|
323
331
|
| `sp-vise/workplan.json` | `vise workplan complete` | Broad-request progress: completed surfaces, green-check evidence |
|
|
324
332
|
| `sp-vise/workplan-snapshots/<surface>/` | `vise workplan complete` | Per-surface snapshots so later focused surfaces don't erase earlier proof |
|
|
333
|
+
| `sp-vise/smoke.json` | project/runtime harness | Declared runtime-smoke surfaces and expected resolution states |
|
|
334
|
+
| `sp-vise/evidence/runtime-smoke.json` | `vise smoke` | Captured runtime-smoke verdicts used by evidence-citing runtime rules |
|
|
325
335
|
| `sp-vise/design-contract.json` | `vise design extract` | Extracted tokens, breakpoints, source digests, stable design digest |
|
|
326
336
|
| `sp-vise/design-preview.html` | `vise design extract` / `preview` | Self-contained visual review; open before answering `design_contract_confirmation` |
|
|
327
337
|
| `sp-vise/design-reference.html` | `vise design reference` | Self-contained design-system spec (swatches, type, components) |
|
package/dist/capabilities.js
CHANGED
|
@@ -96,6 +96,17 @@ export const CAPABILITIES = [
|
|
|
96
96
|
symbols: [/AmityRoomRepository/i, /\bcreateRoom\b/, /createRoomAndStartStreaming/i, /getBroadcastData/i, /createLiveStreamPost/i, /\bgoLive\b/i, /startPublish/i],
|
|
97
97
|
hint: "live rooms/broadcasting via AmityRoomRepository (createRoom, go-live, live-viewing); post the stream with createLiveStreamPost (distinct from rendering a livestream post in the feed)",
|
|
98
98
|
},
|
|
99
|
+
{
|
|
100
|
+
id: "comment-preview",
|
|
101
|
+
label: "Comment preview on posts",
|
|
102
|
+
outcomes: ["add-feed"],
|
|
103
|
+
symbols: [
|
|
104
|
+
/\bgetComments\b/, /\bqueryComments\b/, /CommentRepository/i, /AmityCommentQueryBuilder/,
|
|
105
|
+
/\bgetCommentCount\b/, /\bgetLocalCommentCount\b/, /\bgetLatestComments\b/,
|
|
106
|
+
/\bcomments?Count\b/, /\blocalCommentCount\b/, /\blatestComments?(?:Ids?)?\b/,
|
|
107
|
+
],
|
|
108
|
+
hint: "Present a comment preview on each post: the comment count + a top-comment snippet + a tap-through to the thread. Read it off the post (commentsCount / latestComments) or query via getComments / CommentRepository. (The full thread + composer is the deeper add-comments work.) A genuinely comment-less feed (broadcast / announcement / a profile post-grid) opts out: `// vise: scope-omit comment-preview — <reason>`.",
|
|
109
|
+
},
|
|
99
110
|
{
|
|
100
111
|
id: "comments",
|
|
101
112
|
label: "Comment thread (list + composer)",
|
|
@@ -504,6 +515,23 @@ export const SHARED_PRODUCT_EXPECTATIONS = [
|
|
|
504
515
|
deterministicPlatforms: ["android", "flutter", "ios", "typescript"],
|
|
505
516
|
hint: "source unread badges from the SDK stream instead of counting stale local arrays",
|
|
506
517
|
},
|
|
518
|
+
{
|
|
519
|
+
id: "feed.post-body-rendering",
|
|
520
|
+
label: "Post body rendering",
|
|
521
|
+
outcomes: ["add-feed"],
|
|
522
|
+
kind: "shared-expectation",
|
|
523
|
+
availability: [
|
|
524
|
+
{
|
|
525
|
+
label: "SDK text post/body accessors",
|
|
526
|
+
symbols: [
|
|
527
|
+
/\b(?:text|description|caption)\b/i,
|
|
528
|
+
/\b(?:getData|getText|AmityTextPost|AmityPostData)\b/i,
|
|
529
|
+
],
|
|
530
|
+
},
|
|
531
|
+
],
|
|
532
|
+
deterministicPlatforms: ["android", "flutter", "ios", "typescript"],
|
|
533
|
+
hint: "render the post body/description/caption when present; a title field is optional and postId should not be the primary card content",
|
|
534
|
+
},
|
|
507
535
|
{
|
|
508
536
|
id: "feed.rich-post-rendering",
|
|
509
537
|
label: "Rich post rendering",
|
|
@@ -1144,7 +1172,7 @@ function symbolHaystack(symbols) {
|
|
|
1144
1172
|
}
|
|
1145
1173
|
const ADVISORY_NOTE = "Build each missing capability, or opt out with a recorded reason: `// vise: scope-omit <id> — <reason>`. A scope-omit marker without a reason is invalid and still counts as missing. Missing capabilities that are neither built nor validly opted-out cause `vise check` to exit with status `completeness-gap` (exit code 5).";
|
|
1146
1174
|
export const BASELINE_CAPABILITY_IDS_BY_OUTCOME = {
|
|
1147
|
-
"add-feed": ["pagination"],
|
|
1175
|
+
"add-feed": ["pagination", "comment-preview"],
|
|
1148
1176
|
"add-comments": ["comment-composer"],
|
|
1149
1177
|
"add-chat": ["send-message", "read-state"],
|
|
1150
1178
|
"add-follow": ["followers-following"],
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
export const ENTRY_STATE_ADVISORY = "This is an advisory entry-state classification. It does not change outcome classification, compliance rules, the sidecar schema, or `vise check` exit codes.";
|
|
2
|
+
export function classifyPathDecidedness(input) {
|
|
3
|
+
const { solutionPath, hasExplicitPathAnswer } = input;
|
|
4
|
+
const rec = solutionPath.recommendation;
|
|
5
|
+
if (hasExplicitPathAnswer) {
|
|
6
|
+
if (rec === "uikit")
|
|
7
|
+
return "uikit";
|
|
8
|
+
if (rec === "hybrid")
|
|
9
|
+
return "hybrid";
|
|
10
|
+
return "sdk";
|
|
11
|
+
}
|
|
12
|
+
if (rec === "hybrid")
|
|
13
|
+
return "hybrid";
|
|
14
|
+
if (rec === "needs-decision")
|
|
15
|
+
return "conflict";
|
|
16
|
+
if (rec === "uikit")
|
|
17
|
+
return solutionPath.signals.uikit.length > 0 ? "uikit" : "undecided";
|
|
18
|
+
return solutionPath.signals.sdk.length > 0 ? "sdk" : "undecided";
|
|
19
|
+
}
|
|
20
|
+
export function classifyFeatureCompleteness(input) {
|
|
21
|
+
const { outcome, broadSocialRequest, multiSurface, creativeSelected } = input;
|
|
22
|
+
if (creativeSelected)
|
|
23
|
+
return "has-feature-ref";
|
|
24
|
+
if (outcome !== "unknown" && !broadSocialRequest)
|
|
25
|
+
return "has-feature-ref";
|
|
26
|
+
if (broadSocialRequest || multiSurface)
|
|
27
|
+
return "goal-only-broad";
|
|
28
|
+
return "exploring";
|
|
29
|
+
}
|
|
30
|
+
export function classifyDesignCompleteness(input) {
|
|
31
|
+
if (!input.mentionsDesign)
|
|
32
|
+
return "none";
|
|
33
|
+
return input.designSignalCount > 0 ? "has-design-ref" : "mentions-no-ref";
|
|
34
|
+
}
|
|
35
|
+
export function entryStageFor(d) {
|
|
36
|
+
if (d.feature === "exploring")
|
|
37
|
+
return "explore";
|
|
38
|
+
if (d.path === "undecided" || d.path === "conflict")
|
|
39
|
+
return "decide-path";
|
|
40
|
+
if (d.feature === "goal-only-broad")
|
|
41
|
+
return "clarify";
|
|
42
|
+
if (d.design === "mentions-no-ref")
|
|
43
|
+
return "clarify";
|
|
44
|
+
return "confirm";
|
|
45
|
+
}
|
|
46
|
+
export function classifyEntryState(input) {
|
|
47
|
+
const pathDecidedness = classifyPathDecidedness(input);
|
|
48
|
+
const featureCompleteness = classifyFeatureCompleteness(input);
|
|
49
|
+
const designCompleteness = classifyDesignCompleteness(input);
|
|
50
|
+
const entryStage = entryStageFor({
|
|
51
|
+
path: pathDecidedness,
|
|
52
|
+
feature: featureCompleteness,
|
|
53
|
+
design: designCompleteness,
|
|
54
|
+
});
|
|
55
|
+
const sdkCount = input.solutionPath.signals.sdk.length;
|
|
56
|
+
const uikitCount = input.solutionPath.signals.uikit.length;
|
|
57
|
+
const rationale = [
|
|
58
|
+
`path-decidedness: ${pathDecidedness} (solution-path ${input.solutionPath.recommendation}; ${sdkCount} sdk / ${uikitCount} uikit signal(s)${input.hasExplicitPathAnswer ? "; explicit answer" : ""}).`,
|
|
59
|
+
`feature-completeness: ${featureCompleteness} (outcome ${input.outcome}${input.broadSocialRequest ? "; broad" : ""}${input.multiSurface ? "; multi-surface" : ""}${input.creativeSelected ? "; creative variant accepted" : ""}).`,
|
|
60
|
+
`design-completeness: ${designCompleteness} (${input.mentionsDesign ? "design mentioned" : "no design mention"}; ${input.designSignalCount} in-repo design signal(s)).`,
|
|
61
|
+
`enters the flow at the "${entryStage}" stage.`,
|
|
62
|
+
];
|
|
63
|
+
return {
|
|
64
|
+
entryStage,
|
|
65
|
+
pathDecidedness,
|
|
66
|
+
featureCompleteness,
|
|
67
|
+
designCompleteness,
|
|
68
|
+
rationale,
|
|
69
|
+
advisoryOnly: ENTRY_STATE_ADVISORY,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
const COMMUNITY_TOKEN = /\bcommunit(?:y|ies)\b/i;
|
|
2
|
+
const COMMUNITY_CONTENT_TOKEN = /\b(?:feed|posts?|timeline|wall|content|share|discuss(?:ion)?|stories)\b/i;
|
|
3
|
+
const COMMUNITY_EXPERIENCE_PHRASE = /\bcommunity\s+(?:experience|space|hub|home|page)\b/i;
|
|
4
|
+
const COMMUNITY_EXPERIENCE = {
|
|
5
|
+
id: "community",
|
|
6
|
+
variantId: "community-first",
|
|
7
|
+
matches: (request) => COMMUNITY_EXPERIENCE_PHRASE.test(request) || (COMMUNITY_TOKEN.test(request) && COMMUNITY_CONTENT_TOKEN.test(request)),
|
|
8
|
+
surfaces: [
|
|
9
|
+
{ id: "feed", tier: "required-for-coherence" },
|
|
10
|
+
{ id: "comments", tier: "recommended" },
|
|
11
|
+
{ id: "community", tier: "required-for-coherence" },
|
|
12
|
+
],
|
|
13
|
+
};
|
|
14
|
+
const MESSAGING_SIGNALS = [
|
|
15
|
+
/\b(?:direct|private|instant|encrypted|secure|one[\s-]?on[\s-]?one|one[\s-]?to[\s-]?one|1\s?[-:]\s?1|peer[\s-]?to[\s-]?peer)[\s-]+messag\w+\b/i,
|
|
16
|
+
/\b(?:messaging|messenger)\s+(?:experience|app|application|feature|inbox)\b/i,
|
|
17
|
+
/\b(?:dms?|direct[\s-]?messages?)\s+(?:feature|inbox|experience|system|thread|cent(?:er|re))\b/i,
|
|
18
|
+
];
|
|
19
|
+
const MESSAGING_EXPERIENCE = {
|
|
20
|
+
id: "messaging",
|
|
21
|
+
variantId: "messaging-first",
|
|
22
|
+
matches: (request) => MESSAGING_SIGNALS.some((re) => re.test(request)),
|
|
23
|
+
surfaces: [
|
|
24
|
+
{ id: "chat", tier: "required-for-coherence" },
|
|
25
|
+
{ id: "profile", tier: "recommended" },
|
|
26
|
+
{ id: "notifications", tier: "recommended" },
|
|
27
|
+
],
|
|
28
|
+
};
|
|
29
|
+
const DISCUSSION_SIGNALS = [
|
|
30
|
+
/\b(?:discussion|community|online|message|q\s?&\s?a|q&a|qanda)\s+(?:forums?|boards?)\b/i,
|
|
31
|
+
/\b(?:forums?|message\s+boards?|bulletin\s+boards?)\s+(?:feature|experience|for\b)/i,
|
|
32
|
+
/\bthreaded\s+discussions?\b/i,
|
|
33
|
+
/\bq\s?&\s?a\s+(?:community|forum|board|experience|platform)\b/i,
|
|
34
|
+
];
|
|
35
|
+
const DISCUSSION_EXPERIENCE = {
|
|
36
|
+
id: "discussion",
|
|
37
|
+
variantId: "knowledge-network",
|
|
38
|
+
surfaces: [
|
|
39
|
+
{ id: "feed", tier: "required-for-coherence" },
|
|
40
|
+
{ id: "comments", tier: "required-for-coherence" },
|
|
41
|
+
{ id: "community", tier: "recommended" },
|
|
42
|
+
],
|
|
43
|
+
matches: (request) => DISCUSSION_SIGNALS.some((re) => re.test(request)),
|
|
44
|
+
};
|
|
45
|
+
const CREATOR_SIGNALS = [
|
|
46
|
+
/\b(?:creator|influencer|content[\s-]?creators?)\s+(?:platform|econom\w+|hub|program|tools?|studio|community|app|application|experience|marketplace|network|portal|space)\b/i,
|
|
47
|
+
/\bcreator[\s-]?monetization\b/i,
|
|
48
|
+
/\bmonetiz\w+\s+(?:creators?|content|audiences?|fans?|subscribers?|followers?)\b/i,
|
|
49
|
+
];
|
|
50
|
+
const CREATOR_EXPERIENCE = {
|
|
51
|
+
id: "creator",
|
|
52
|
+
variantId: "creator-first",
|
|
53
|
+
surfaces: [
|
|
54
|
+
{ id: "feed", tier: "required-for-coherence" },
|
|
55
|
+
{ id: "profile", tier: "required-for-coherence" },
|
|
56
|
+
{ id: "comments", tier: "recommended" },
|
|
57
|
+
{ id: "livestream", tier: "recommended" },
|
|
58
|
+
],
|
|
59
|
+
matches: (request) => CREATOR_SIGNALS.some((re) => re.test(request)),
|
|
60
|
+
};
|
|
61
|
+
export const EXPERIENCE_BUNDLES = [
|
|
62
|
+
COMMUNITY_EXPERIENCE,
|
|
63
|
+
MESSAGING_EXPERIENCE,
|
|
64
|
+
DISCUSSION_EXPERIENCE,
|
|
65
|
+
CREATOR_EXPERIENCE,
|
|
66
|
+
];
|
|
67
|
+
export function experienceBundleFor(request) {
|
|
68
|
+
const text = typeof request === "string" ? request : "";
|
|
69
|
+
return EXPERIENCE_BUNDLES.find((bundle) => bundle.matches(text));
|
|
70
|
+
}
|
package/dist/explore.js
CHANGED
|
@@ -46,6 +46,6 @@ export function exploreRequest(request, platform = "typescript") {
|
|
|
46
46
|
matched_outcome: null,
|
|
47
47
|
unmatched_note: "This request didn't map to a single social.plus outcome. Below is everything Vise can guide you through — pick one and run its `start` command.",
|
|
48
48
|
routes: DISCOVERY_MENU.map((outcome) => outcomeBrief(outcome, platform, request)),
|
|
49
|
-
note: "Discovery is pre-credentials and read-only — no project or API key needed. When you're ready to build, `vise plan`/`vise init` starts a tracked integration.",
|
|
49
|
+
note: "Discovery is pre-credentials and read-only — no project or API key needed. When you're ready to build, `vise plan`/`vise init` starts a tracked integration. If this is a broad social *product* (you're still shaping WHICH surfaces fit), run `vise creative <project> --request \"...\"` for an experience brief (ranked surface journeys) before committing to a single outcome.",
|
|
50
50
|
};
|
|
51
51
|
}
|