waygraph 0.15.9 → 0.15.10

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
@@ -920,6 +920,7 @@ really a Nav/Page/Assert/Method from this package's own factories.
920
920
  | Interactive explore (Add/Remove/Open details from live page) | `cd examples/saucedemo && npm i && npx waygraph auto` |
921
921
  | Scaffold a new **offline** project (green `npm test` on local fixture `:4177`) | `npx create-waygraph my-app` **or** `npx waygraph init my-app` |
922
922
  | Install coding-agent defs for diving an app into Blocks | `npx waygraph agent-dive --loop claude` (also `opencode` / `cursor` / `vscode`) |
923
+ | Print a packaged agent skill to stdout | `npx waygraph --skill` (list) / `--skill-pilot` / `--skill-pilot-blind` / `--skill-convention` |
923
924
  | Add waygraph to an existing repo | `npm install waygraph @playwright/test` |
924
925
 
925
926
  **Scaffold is not hidden inside waygraph alone** - the offline starter also ships as
@@ -1034,6 +1035,7 @@ Flows are files (0.10.5+):
1034
1035
  | Waygraph Map enforcement (verbatim url-vs-folder, exits 1 on a violation) | `waygraph map [project]` |
1035
1036
  | Graph crawl | `waygraph traverse [project] --parallel N --min-edge-coverage 80%` |
1036
1037
  | Coding-agent defs | `waygraph agent-dive --loop claude` |
1038
+ | Print packaged skills | `waygraph --skill` / `--skill-pilot` / `--skill-pilot-blind` / `--skill-convention` |
1037
1039
  | One-shot temp-dir demo | `waygraph try demo` / `waygraph try auto` / `waygraph try auto:cli` |
1038
1040
 
1039
1041
  `--blocks` / positional accepts a Flow export, a `.flow.ts` path, or `"a then b"`.
@@ -19,6 +19,17 @@ export declare function loadAgentSpecs(): AgentSpec[];
19
19
  * body frontmatter shape `parseAgentSpec` already parses.
20
20
  */
21
21
  export declare function loadSkillSpecs(): AgentSpec[];
22
+ /** CLI flag -> packaged skill file stem (under templates/skills/). */
23
+ export declare const SKILL_FLAG_MAP: {
24
+ readonly "--skill-pilot": "waygraph-pilot";
25
+ readonly "--skill-pilot-blind": "waygraph-blind-pilot";
26
+ readonly "--skill-convention": "waygraph-convention";
27
+ };
28
+ export type SkillFlag = keyof typeof SKILL_FLAG_MAP;
29
+ /** Raw skill markdown (frontmatter + body), as shipped in the package. */
30
+ export declare function readSkillMarkdown(stem: string): string;
31
+ /** Print `--skill` index (available flags + one-line descriptions). */
32
+ export declare function printSkillIndex(): void;
22
33
  export interface AgentDiveOptions {
23
34
  loop: AgentDiveLoop;
24
35
  projectDir: string;
@@ -85,6 +85,34 @@ export function loadSkillSpecs() {
85
85
  .sort()
86
86
  .map((f) => parseAgentSpec(join(dir, f)));
87
87
  }
88
+ /** CLI flag -> packaged skill file stem (under templates/skills/). */
89
+ export const SKILL_FLAG_MAP = {
90
+ "--skill-pilot": "waygraph-pilot",
91
+ "--skill-pilot-blind": "waygraph-blind-pilot",
92
+ "--skill-convention": "waygraph-convention",
93
+ };
94
+ /** Raw skill markdown (frontmatter + body), as shipped in the package. */
95
+ export function readSkillMarkdown(stem) {
96
+ const path = join(skillsTemplateDir(), `${stem}.skill.md`);
97
+ if (!existsSync(path)) {
98
+ throw new Error(`waygraph: skill template missing at ${path}`);
99
+ }
100
+ const raw = readFileSync(path, "utf-8");
101
+ return raw.endsWith("\n") ? raw : raw + "\n";
102
+ }
103
+ /** Print `--skill` index (available flags + one-line descriptions). */
104
+ export function printSkillIndex() {
105
+ const skills = loadSkillSpecs();
106
+ const byName = new Map(skills.map((s) => [s.name, s]));
107
+ console.log("waygraph skills (print full text with the matching flag):\n");
108
+ for (const [flag, stem] of Object.entries(SKILL_FLAG_MAP)) {
109
+ const spec = byName.get(stem);
110
+ const desc = spec?.description ?? stem;
111
+ console.log(` npx waygraph ${flag}`);
112
+ console.log(` ${desc}\n`);
113
+ }
114
+ console.log("Also: npx waygraph agent-dive --loop claude # write .claude/skills/*/SKILL.md");
115
+ }
88
116
  function writeFileLogged(path, content, kind) {
89
117
  mkdirSync(dirname(path), { recursive: true });
90
118
  writeFileSync(path, content.endsWith("\n") ? content : content + "\n");
package/dist/cli.js CHANGED
@@ -22,7 +22,7 @@ import { checkMap } from "./map-check.js";
22
22
  import { runAutoExplore } from "./auto-explore-run.js";
23
23
  import { pilotStart } from "./pilot.js";
24
24
  import { spawnDetachedSession, requestSession, runAttachLoop, runAutoServeCommand, } from "./auto-session-ipc.js";
25
- import { runAgentDive } from "./agent-dive.js";
25
+ import { runAgentDive, printSkillIndex, readSkillMarkdown, SKILL_FLAG_MAP, } from "./agent-dive.js";
26
26
  import { runTraverse } from "./traverse-run.js";
27
27
  import { parseMinEdgeCoverage } from "./traverse-coverage.js";
28
28
  import { isFileSelectToken, parseBlocksSelect, } from "./blocks-select.js";
@@ -7266,6 +7266,12 @@ Also:
7266
7266
  try auto:cli / --cli Terminal menu instead
7267
7267
  try auto --headed Same as try auto (compat)
7268
7268
 
7269
+ Skills (print packaged skill markdown to stdout - for agents / paste):
7270
+ waygraph --skill List available skills
7271
+ waygraph --skill-pilot Drive an existing Block graph
7272
+ waygraph --skill-pilot-blind Cold-start: raw ops + author Blocks
7273
+ waygraph --skill-convention Block/Map authoring conventions
7274
+
7269
7275
  Examples:
7270
7276
  waygraph list # file → export map
7271
7277
  waygraph run src/flows/shop.flow.ts --data '{...}'
@@ -7295,6 +7301,15 @@ async function main() {
7295
7301
  if (!command || command === "--help" || command === "-h") {
7296
7302
  usage();
7297
7303
  }
7304
+ if (command === "--skill") {
7305
+ printSkillIndex();
7306
+ process.exit(0);
7307
+ }
7308
+ if (command && command in SKILL_FLAG_MAP) {
7309
+ const stem = SKILL_FLAG_MAP[command];
7310
+ process.stdout.write(readSkillMarkdown(stem));
7311
+ process.exit(0);
7312
+ }
7298
7313
  switch (command) {
7299
7314
  case "list": {
7300
7315
  const proj = resolve(args[1] ?? process.cwd());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "waygraph",
3
- "version": "0.15.9",
3
+ "version": "0.15.10",
4
4
  "type": "module",
5
5
  "description": "A typed graph of reusable Blocks for driving a browser through E2E flows.",
6
6
  "license": "MIT",
@@ -0,0 +1,109 @@
1
+ ---
2
+ name: waygraph-convention
3
+ description: Author or review waygraph Blocks/Flows under the consumer + Waygraph Map conventions - use when writing new Blocks, migrating folder layout, or answering "how should this project be organized," not when driving an already-built session (use waygraph-pilot / waygraph-blind-pilot for that).
4
+ ---
5
+
6
+ Waygraph convention is how Blocks are *shaped and placed*, not how a live session is
7
+ driven. Print this skill, then write or rearrange files so `waygraph check` / `waygraph map`
8
+ stay clean. For operating an existing graph, use `--skill-pilot`. For cold-start authoring
9
+ against a live site, use `--skill-pilot-blind`.
10
+
11
+ ## Hard rules (not style preferences)
12
+
13
+ 1. **One distinct action per Block.** Fill and submit are two Blocks. A login form is
14
+ `fill-username` (self-loop) + `fill-password` (self-loop) + `submit-login` (transition),
15
+ never one Method that "fills and logs in." Same split for checkout fields. Canonical
16
+ shape: `examples/saucedemo/src/blocks/saucedemo-web/methods/`.
17
+ 2. **Navigation only inside Nav.** `page.goto` / NavBlock `click` live in
18
+ `defineNavBlock` / `defineNavClickBlock` only. Method/Effect `act` uses ActionPage
19
+ (no goto) even when the app changes URL as a side effect of a button click.
20
+ 3. **Selectors in `*Sel`, never inline.** DOM strings live in a `*Sel` next to the page
21
+ (static + `(id) => …`). Mem keys store values, not selectors. `waygraph check` warns on
22
+ inline selector literals in `Trait.visible` / `Trait.text`.
23
+ 4. **Assert-only = `defineAssertBlock`.** Self-loop, no hand-written `act`/`resolve`. Pass
24
+ an explicit type argument when it sits between two specifically-typed Blocks in a Flow.
25
+ 5. **`requires` = externally supplied.** A key an earlier Block in the same chain produces
26
+ is never listed under `requires` - preflight checks the whole chain up front.
27
+
28
+ ## Block kinds (file convention)
29
+
30
+ | Kind | File | Helper | `page.goto`? |
31
+ |------|------|--------|--------------|
32
+ | Page | `*.page.block.ts` / `_page.block.ts` | `definePageBlock` | Optional deep-link |
33
+ | Nav | `nav-*.block.ts` / `_nav.block.ts` | `defineNavBlock` / `defineNavClickBlock` | Yes (`url` XOR `click`) |
34
+ | Effect | `*.effect.block.ts` in `methods/` / `_methods/` | `defineEffectBlock` | No |
35
+ | Method | `*.method.block.ts` in `methods/` / `_methods/` | `defineMethodBlock` | No |
36
+ | Assert | with Method/Effect peers | `defineAssertBlock` | No |
37
+
38
+ Effects that appear in `waygraph auto` menus need `instanceOptions` that scan the live DOM
39
+ (or mem) for labeled rows.
40
+
41
+ ## Two layouts (same Block kinds)
42
+
43
+ **Freeform ("manual mode")** - still valid; real consumers depend on it:
44
+
45
+ ```text
46
+ src/blocks/<site>/ # THIS FOLDER IS URL "/"
47
+ nav-login.block.ts
48
+ methods/fill-username.method.block.ts
49
+ inventory/ # /inventory.html
50
+ inventory.page.block.ts
51
+ methods/add-to-cart.effect.block.ts
52
+ ```
53
+
54
+ Folders mirror real app routes (Next.js `app/` page routes). Do **not** invent parallel
55
+ families like `root/`, `landing/`, or `shell/nav/` that are not real URLs. `/` lives at the
56
+ namespace root.
57
+
58
+ **Waygraph Map** - forced convention when `src/map/` exists:
59
+
60
+ ```text
61
+ src/map/
62
+ (app_base)/ # organizational group only - never part of a Checkpoint tag
63
+ dashboard/ # must verbatim-match the real URL path (/dashboard)
64
+ _page.block.ts
65
+ _nav.block.ts
66
+ _sel.ts
67
+ _methods/click-widget.block.ts
68
+ (external)/ # cross-origin (mailpit, etc.) - same shape
69
+ docs/
70
+ _page.block.ts
71
+ _nav.block.ts
72
+ _sel.ts
73
+ ```
74
+
75
+ - `(group)` parentheses and leading-underscore segments (`_methods/`, `_page…`) are
76
+ **not** URL segments. `waygraph map` excludes them when checking folder-vs-URL.
77
+ - A bare non-underscore folder always means a real child Checkpoint/URL segment.
78
+ - Prefer `map()` over a hand-assembled `defineFlow([start, ...])` when wiring Map Blocks -
79
+ it rejects Blocks that didn't come from a real factory (no silent teleporting).
80
+
81
+ Mail / external tools: under `*-external/<tool>/` or `map/(external)/<tool>/`, never under
82
+ the site's `*-web/` tree. Browser-driven (DOM / iframe Traits), not the catcher's REST API.
83
+
84
+ ## Verify before you call it done
85
+
86
+ ```bash
87
+ npx waygraph check . # orphans + nav-escape + inline-selector warnings
88
+ npx waygraph map . # exit 1 if src/map/ folder path != real static url
89
+ npx waygraph validate . # every .flow.ts loads
90
+ npx waygraph graph . # nodes/edges/skipped/orphans - counts should make sense
91
+ npm run typecheck # when the consumer has it
92
+ ```
93
+
94
+ `waygraph check` should report zero nav warnings. Orphan Blocks (not in any `.flow.ts`)
95
+ are still runnable in Pilot's live menu - orphan status only blocks
96
+ `auto --blocks <From> <To>` pathfinding.
97
+
98
+ ## Related skills (print via CLI)
99
+
100
+ ```bash
101
+ npx waygraph --skill # list
102
+ npx waygraph --skill-pilot # drive an existing Block graph
103
+ npx waygraph --skill-pilot-blind # cold-start: raw ops + author Blocks as you go
104
+ npx waygraph --skill-convention # this file
105
+ ```
106
+
107
+ Worked freeform example: `examples/saucedemo/docs/CONVENTION.md`.
108
+ Map design history: `openspec/changes/waygraph-map/`.
109
+ Agent personas (author/planner/healer): `npx waygraph agent-dive --loop claude`.
@@ -1,8 +0,0 @@
1
- {
2
- "sessionId": "03710cfc",
3
- "socketPath": "/tmp/waygraph-auto/03710cfc.sock",
4
- "pid": 255515,
5
- "projectDir": "/home/dan/Desktop/Work/zsign/services/waygraph/examples/saucedemo",
6
- "startedAt": "2026-09-21T09:37:58.750Z",
7
- "headless": false
8
- }
@@ -1,8 +0,0 @@
1
- {
2
- "sessionId": "605d965b",
3
- "socketPath": "/tmp/waygraph-auto/605d965b.sock",
4
- "pid": 247729,
5
- "projectDir": "/home/dan/Desktop/Work/zsign/services/waygraph/examples/saucedemo",
6
- "startedAt": "2026-09-21T09:34:04.318Z",
7
- "headless": false
8
- }
@@ -1,8 +0,0 @@
1
- {
2
- "sessionId": "6b667734",
3
- "socketPath": "/tmp/waygraph-auto/6b667734.sock",
4
- "pid": 245167,
5
- "projectDir": "/home/dan/Desktop/Work/zsign/services/waygraph/examples/saucedemo",
6
- "startedAt": "2026-09-21T09:33:13.876Z",
7
- "headless": false
8
- }