Agent Skills › uw-syfi/vibesys › build-client-feature

build-client-feature

GitHub

指导在 TypeScript 客户端中开发、重构或修复功能。涵盖包结构放置、XState 状态机编写、数据折叠及异步工作管理,适用于客户端应用和库的变更与脚手架生成。

.agents/skills/build-client-feature/SKILL.md uw-syfi/vibesys

Trigger Scenarios

修改客户端应用、功能或共享库代码 创建新的客户端包脚手架 修复客户端中的挂起、泄漏连接或陈旧结果 bug

Install

npx skills add uw-syfi/vibesys --skill build-client-feature -g -y
More Options

Non-standard path

npx skills add https://github.com/uw-syfi/vibesys/tree/main/.agents/skills/build-client-feature -g -y

Use without installing

npx skills use uw-syfi/vibesys@build-client-feature

指定 Agent (Claude Code)

npx skills add uw-syfi/vibesys --skill build-client-feature -a claude-code -g -y

安装 repo 全部 skill

npx skills add uw-syfi/vibesys --all -g -y

预览 repo 内 skill

npx skills add uw-syfi/vibesys --list

SKILL.md

Frontmatter
{
    "name": "build-client-feature",
    "metadata": {
        "kind": "codebase"
    },
    "description": "Add or change a feature in the TypeScript clients (the desktop app, features, and shared libraries), placing it in the package graph, writing its control state as an XState machine and its data folds as reducers, wiring the live run through @vibesys\/run-session, and bounding and cancelling its asynchronous work. Use when changing client apps, features or shared libraries, scaffolding a client package, or fixing a client bug about stale results, hangs, or leaked connections."
}

Build a client feature

The clients are a pnpm workspace (the clients workspace): one package per concept, in layers that depend only downward ("Layers" and "State" in clients-architecture.md). Control state is a mode with effects: it starts work, waits, retries, times out, cancels, and decides what a late answer means (a live run session, a host connection). A data fold turns ordered inputs into a value and has no mode (the run event fold). The shell is the impure code around a pure core; it owns sockets, timers and processes.

Builds on

  • software-design (pure core, thin shell) and testing (Fakes, model tests).
  • write-vibesys-tests for test tiers; enforce-rules when a fix reveals a bug class a check could close.

When this applies

  • Any change to a client app, a client feature, or a shared client library.
  • Scaffolding or moving client packages. Changing the run protocol or the host-helper contract itself is the change-wire-protocol skill; this skill covers consuming them.

Steps

  1. Place the code by layer. Find the owning package in the package-graph table of clients-architecture.md: a library for shared code, a feature for one concept (its ./state entry is pure, ./renderer is DOM, ./main is Node), and composition only in an app. A feature never imports another feature; an app composes cross-feature flows. check_package_graph and the dependency-cruiser rule feature-state-is-pure (with its siblings) fail on a misplaced import.
  2. Scaffold a new package, never hand-write one. From the clients workspace root, run pnpm new:package <layer> <name> (or pnpm new:package feature <name>), then pnpm install; a feature starts from a machine skeleton with its tests. check_package_graph fails a hand-made package by rule name.
  3. Write control state as an XState machine, data folds as reducers. Follow references/state-and-async.md: invoked operations with ids, after delays on an injected clock, folds on @vibesys/store in their own modules. The Grit rule features-no-hand-rolled-control forbids timers and abort controllers in a feature's state and effects code, control-state-no-store-kernel forbids the reducer kernel in migrated features, and check_package_graph confines xstate to features and the machine packages. Migrating a feature adds it to the second rule's scope in the Biome configuration and drops its exclusion from the first.
  4. Cancel by ownership. Every async operation takes an abort signal owned by whoever started it; superseding, closing, or leaving the owning state aborts it, and the operation disposes what it opened. Every invoke has an onError. Unenforced: whether a shell honors its signal needs a reader, and no lint reads XState config objects.
  5. Bound every wait (bootstrap, dial, write, handshake, retirement) with a deadline from an injected ScheduleTimeout, so tests drive it with a fake clock. Inside a feature's state and effects code it is an after transition (features-no-hand-rolled-control). Shell code elsewhere is Unenforced: a timer ban there would also forbid the real scheduler that production injects, and a missing bound is an absence.
  6. Keep ui/ presentational: props in, events out; no fetch, sockets, effect hooks, timers, or transport imports. The Grit rules ui-no-io-calls, ui-no-io-imports, ui-no-effect-hooks, ui-no-timers and web-fetch-only-in-backend enforce it.
  7. Wire a live run through @vibesys/run-session. The app builds a web session from connect (connectRun over its transport) and a browser lifecycle; read the web app's entrypoint for the working composition. Features render the session's types and never re-implement start-up, recovery or snapshot fencing. feature-transport-is-type-only fails a feature that imports transport values.
  8. Consume the protocol; do not redefine it. Import message types from @vibesys/contracts and turn wire text into them only through its validators; never edit its generated bindings. The clients_quality check group regenerates the bindings and fails on a diff.
  9. Desktop: respect the runtimes. Main-process code is a feature's ./main entry or the desktop main app; a preload imports workspace packages only as types; welcome-view requests go through @vibesys/ipc's parsers. check_package_graph fails by rule name (preload-sandbox, runtime-reachability), and desktop-preloads-import-only-ipc-and-electron covers preloads.
  10. Build, check, test with Turborepo (from the clients workspace root): pnpm check:ts, pnpm check:ts-architecture, pnpm check:knip, pnpm check:clients, pnpm test:clients; ./scripts/check_clients.sh runs CI's client checks together.
  11. Before opening a pull request that changes what a user sees, run the verify-desktop-ui skill: replay fixtures through the built app, pass the screen checks, attach the contact sheet, judge the screens. The Run screen lives in @vibesys/feature-run-page (./state, ./renderer) and is composed by @vibesys/app-desktop-shell; others edit it at the same time, so rebase before the final sheet. Unenforced: whether a change alters what a user sees needs judgment; the PR template's Screens field asks for it.

Testing

  • Test a machine with pure transitions (getNextSnapshot), checkMachine from @vibesys/machine/testing (seeded random events; every live operation and delay must belong to an active state), and a live actor settled in a chosen order for stale replies; test a fold with checkModel from @vibesys/store/testing. Unenforced: which cases a change needs is review judgment; the package scaffold only seeds them.
  • Drive time and I/O with Fakes (FakeClock, sessionWith from @vibesys/run-session/testing, FakeHelper from @vibesys/connection/testing); never the ambient setTimeout (check_test_isolation, rule wall_clock_sync).
  • The Bun test runner fails a run that collected fewer test files than the package holds, and bounds each test only as a hang guard. Unenforced: keep tests fast by driving time with a fake clock.
  • App journeys get Playwright tests in each app's end-to-end suite, which CI runs. Unenforced: which journeys need a browser test is judgment.
  • A bug fix carries a regression test that fails at the merge base. Unenforced: CI runs only the head; state the merge-base result in the PR.

Known failure modes

  • Unbounded waits in shell code hang a window: relay writes, page credit, process retirement, the gateway bootstrap, an unterminated helper line. Unenforced: step 5.
  • A late reply overwrites newer state: stale chat menu results, stale thread creation, a superseded snapshot load. Machines make this structural (features-no-hand-rolled-control).
  • Work outlives its owner: subscriptions left open at shutdown, abandoned relay dials, an ssh master attempt not killed on release. Unenforced: step 4.
  • A gap between checking aborted and listening lost a cancellation; use registerAbort from @vibesys/transport. Unenforced: a ban on bare abort listeners would also hit that helper.
  • A Python-side squash merge from an old branch silently reverted the run-session machine. check_stale_revert fails a change that restores an older copy of recently changed files; review client hunks in every PR too.
  • A machine test outran the runner's per-test limit on a loaded CI runner. Unenforced: the bound is a runner option; keep machine tests free of real time.

Sources of truth

  • clients-architecture.md (layers, runtimes, State, build) and desktop-connection.md.
  • The package-graph checker (check_package_graph): graph rules and their tables.
  • The clients Biome configuration: which Grit rules cover which packages, with exclusions.
  • The client CI check groups; ./support/repoctl/repoctl test --dry-run lists those a change selects.

Version History

  • 256ebe6 Current 2026-10-18 21:27

Same Skill Collection

.agents/skills/add-agent-provider/SKILL.md
.agents/skills/add-bundled-skill/SKILL.md
.agents/skills/change-container-images/SKILL.md
.agents/skills/create-issue/SKILL.md
.agents/skills/enforce-rules/SKILL.md
.agents/skills/open-pr/SKILL.md
.agents/skills/review-pr/SKILL.md
.agents/skills/software-design/SKILL.md
.agents/skills/testing/SKILL.md
.agents/skills/vs-init/SKILL.md
.agents/skills/write-agent-prompt/SKILL.md
.agents/skills/write-docs/SKILL.md
.agents/skills/write-skills/SKILL.md
.agents/skills/write-vibesys-tests/SKILL.md
resources/skills/dial9-tokio/skills/dial9-diagnose-long-poll/SKILL.md
resources/skills/dial9-tokio/skills/dial9-red-flags/SKILL.md
resources/skills/dial9-tokio/skills/dial9-runtime/SKILL.md
resources/skills/dial9-tokio/skills/dial9-toolkit/SKILL.md
resources/skills/dial9-tokio/skills/dial9-trace-analysis/SKILL.md
resources/skills/dial9-tokio/skills/dial9-trace-loading/SKILL.md
resources/skills/dial9-tokio/skills/dial9-trace-recipes/SKILL.md
resources/skills/dial9-tokio/skills/dial9-zoom-window/SKILL.md
resources/skills/kernel-correctness/SKILL.md
resources/skills/kernel-ncu-analysis/SKILL.md
resources/skills/kernel-performance/SKILL.md
resources/skills/kernel-rocprof-analysis/SKILL.md
resources/skills/microservice-optimization/SKILL.md
resources/skills/neuron-agentic-development/skills/neuron-nki-debugging/SKILL.md
resources/skills/neuron-agentic-development/skills/neuron-nki-docs/SKILL.md
resources/skills/neuron-agentic-development/skills/neuron-nki-profiling/SKILL.md
resources/skills/serving-systems/SKILL.md
.agents/skills/change-module-graph/SKILL.md
.agents/skills/triage-prs/SKILL.md
.agents/skills/tui-bug-hunt/SKILL.md
.agents/skills/vs-meta-opt/SKILL.md
resources/skills/neuron-agentic-development/skills/neuron-nki-profile-querying/SKILL.md
resources/skills/neuron-agentic-development/skills/neuron-nki-writing/SKILL.md

Metadata

Files
0
Version
256ebe6
Hash
59c41b59
Indexed
2026-10-18 21:27

홈 - 위키
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-10-20 00:05
浙ICP备14020137号-1