studioflow 0.1.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.
@@ -0,0 +1,21 @@
1
+ id: billing
2
+ description: Open billing page and pick a plan
3
+ tags:
4
+ - billing
5
+ estimated_duration_sec: 20
6
+ steps:
7
+ - id: goto-billing
8
+ action: goto
9
+ value: /billing
10
+ - id: assert-billing-title
11
+ action: assert_visible
12
+ target: '[data-testid="billing-title"]'
13
+ - id: choose-plan
14
+ action: click
15
+ target: '[data-testid="plan-pro"]'
16
+ - id: assert-success
17
+ action: assert_visible
18
+ target: '[data-testid="success-title"]'
19
+ - id: assert-plan
20
+ action: assert_text
21
+ value: "Selected plan: pro"
@@ -0,0 +1,26 @@
1
+ id: onboarding
2
+ description: Complete onboarding form and continue to billing
3
+ tags:
4
+ - onboarding
5
+ - setup
6
+ estimated_duration_sec: 25
7
+ steps:
8
+ - id: goto-home
9
+ action: goto
10
+ value: /
11
+ - id: click-onboarding
12
+ action: click
13
+ target: '[data-testid="go-onboarding"]'
14
+ - id: assert-onboarding
15
+ action: assert_visible
16
+ target: '[data-testid="onboarding-title"]'
17
+ - id: fill-company
18
+ action: type
19
+ target: '[data-testid="company-name-input"]'
20
+ value: Acme Inc
21
+ - id: continue
22
+ action: click
23
+ target: '[data-testid="complete-onboarding"]'
24
+ - id: assert-billing
25
+ action: assert_visible
26
+ target: '[data-testid="billing-title"]'
@@ -0,0 +1,30 @@
1
+ id: onboarding_billing
2
+ description: Run onboarding and billing as a single showcase flow
3
+ tags:
4
+ - onboarding
5
+ - billing
6
+ - full-demo
7
+ estimated_duration_sec: 45
8
+ steps:
9
+ - id: goto-home
10
+ action: goto
11
+ value: /
12
+ - id: click-onboarding
13
+ action: click
14
+ target: '[data-testid="go-onboarding"]'
15
+ - id: fill-company
16
+ action: type
17
+ target: '[data-testid="company-name-input"]'
18
+ value: Acme Incorporated
19
+ - id: continue
20
+ action: click
21
+ target: '[data-testid="complete-onboarding"]'
22
+ - id: choose-plan
23
+ action: click
24
+ target: '[data-testid="plan-pro"]'
25
+ - id: assert-success
26
+ action: assert_visible
27
+ target: '[data-testid="success-title"]'
28
+ - id: screenshot-success
29
+ action: screenshot
30
+ value: success-screen
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "studioflow",
3
+ "version": "0.1.0",
4
+ "private": false,
5
+ "description": "Deterministic AI-assisted product demo automation CLI for Screen Studio workflows",
6
+ "type": "module",
7
+ "engines": {
8
+ "node": ">=22"
9
+ },
10
+ "os": [
11
+ "darwin"
12
+ ],
13
+ "publishConfig": {
14
+ "access": "public"
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "skills",
19
+ "flows",
20
+ "scripts/sync-skills.mjs",
21
+ "scripts/build.mjs",
22
+ "tsconfig.json",
23
+ "package.json"
24
+ ],
25
+ "bin": {
26
+ "studioflow": "dist/index.js"
27
+ },
28
+ "scripts": {
29
+ "prepare:assets": "node scripts/sync-skills.mjs",
30
+ "build": "node scripts/build.mjs",
31
+ "prepack": "node scripts/sync-skills.mjs && node scripts/build.mjs",
32
+ "demo": "tsx src/index.ts run",
33
+ "config": "tsx src/index.ts config",
34
+ "setup": "tsx src/index.ts setup",
35
+ "install-skills": "tsx src/index.ts install-skills",
36
+ "discover": "tsx src/index.ts discover",
37
+ "bootstrap": "tsx src/index.ts bootstrap",
38
+ "screenstudio-prep": "tsx src/index.ts screenstudio-prep",
39
+ "validate": "tsx src/index.ts validate",
40
+ "doctor": "tsx src/index.ts doctor",
41
+ "list-flows": "tsx src/index.ts list-flows"
42
+ },
43
+ "dependencies": {
44
+ "playwright": "^1.55.0"
45
+ },
46
+ "devDependencies": {
47
+ "@studioflow/adapters-desktop": "workspace:*",
48
+ "@studioflow/adapters-playwright": "workspace:*",
49
+ "@studioflow/adapters-screenstudio": "workspace:*",
50
+ "@studioflow/artifacts": "workspace:*",
51
+ "@studioflow/contracts": "workspace:*",
52
+ "@studioflow/flow-registry": "workspace:*",
53
+ "@studioflow/orchestrator": "workspace:*",
54
+ "esbuild": "^0.25.11",
55
+ "kleur": "^4.1.5",
56
+ "tsx": "^4.20.5"
57
+ }
58
+ }
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+ import { build } from "esbuild";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+
6
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
+ const packageRoot = path.resolve(__dirname, "..");
8
+
9
+ await build({
10
+ entryPoints: [path.join(packageRoot, "src/index.ts")],
11
+ outfile: path.join(packageRoot, "dist/index.js"),
12
+ bundle: true,
13
+ format: "esm",
14
+ platform: "node",
15
+ target: "node22",
16
+ sourcemap: true,
17
+ external: ["playwright", "playwright/*"],
18
+ alias: {
19
+ "@studioflow/contracts": path.join(packageRoot, "../../packages/contracts/src/index.ts"),
20
+ "@studioflow/flow-registry": path.join(packageRoot, "../../packages/flow-registry/src/index.ts"),
21
+ "@studioflow/orchestrator": path.join(packageRoot, "../../packages/orchestrator/src/index.ts"),
22
+ "@studioflow/artifacts": path.join(packageRoot, "../../packages/artifacts/src/index.ts"),
23
+ "@studioflow/adapters-desktop": path.join(packageRoot, "../../packages/adapters-desktop/src/index.ts"),
24
+ "@studioflow/adapters-playwright": path.join(packageRoot, "../../packages/adapters-playwright/src/index.ts"),
25
+ "@studioflow/adapters-screenstudio": path.join(packageRoot, "../../packages/adapters-screenstudio/src/index.ts")
26
+ },
27
+ banner: {
28
+ js: "#!/usr/bin/env node"
29
+ }
30
+ });
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env node
2
+ import fs from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+
6
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
+ const packageRoot = path.resolve(__dirname, "..");
8
+ const sourceSkillsRoot = path.resolve(packageRoot, "../../skills");
9
+ const targetSkillsRoot = path.join(packageRoot, "skills");
10
+ const sourceFlowsRoot = path.resolve(packageRoot, "../../packages/flow-registry/flows");
11
+ const targetFlowsRoot = path.join(packageRoot, "flows");
12
+ const skillNames = ["studioflow-cli", "studioflow-investigate"];
13
+ const flowNames = ["billing.yaml", "onboarding.yaml", "onboarding_billing.yaml"];
14
+
15
+ async function ensureSkillExists(skillName) {
16
+ const skillPath = path.join(sourceSkillsRoot, skillName, "SKILL.md");
17
+ await fs.access(skillPath);
18
+ }
19
+
20
+ async function ensureFlowExists(flowName) {
21
+ const flowPath = path.join(sourceFlowsRoot, flowName);
22
+ await fs.access(flowPath);
23
+ }
24
+
25
+ async function main() {
26
+ await Promise.all(skillNames.map(ensureSkillExists));
27
+ await Promise.all(flowNames.map(ensureFlowExists));
28
+
29
+ await fs.rm(targetSkillsRoot, { recursive: true, force: true });
30
+ await fs.mkdir(targetSkillsRoot, { recursive: true });
31
+
32
+ for (const skillName of skillNames) {
33
+ const source = path.join(sourceSkillsRoot, skillName);
34
+ const target = path.join(targetSkillsRoot, skillName);
35
+ await fs.cp(source, target, { recursive: true });
36
+ }
37
+
38
+ await fs.rm(targetFlowsRoot, { recursive: true, force: true });
39
+ await fs.mkdir(targetFlowsRoot, { recursive: true });
40
+
41
+ for (const flowName of flowNames) {
42
+ const source = path.join(sourceFlowsRoot, flowName);
43
+ const target = path.join(targetFlowsRoot, flowName);
44
+ await fs.cp(source, target);
45
+ }
46
+
47
+ console.log(`Bundled assets synced: skills -> ${targetSkillsRoot}, flows -> ${targetFlowsRoot}`);
48
+ }
49
+
50
+ main().catch((error) => {
51
+ console.error(error instanceof Error ? error.message : String(error));
52
+ process.exit(1);
53
+ });
@@ -0,0 +1,70 @@
1
+ ---
2
+ name: studioflow-cli
3
+ description: Execute validated demo artifacts with StudioFlow CLI. Use when the user wants to run a generated flow.json, validate flow artifacts, trigger recording, inspect run artifacts, or troubleshoot deterministic run failures.
4
+ ---
5
+
6
+ # StudioFlow CLI
7
+
8
+ Run validated artifacts through deterministic execution.
9
+
10
+ ## Workflow
11
+
12
+ 0. Resolve handoff input (if present):
13
+ - `artifacts/studioflow-cli-handoff.json`
14
+
15
+ If handoff exists, use it as the source of truth for `flowPath`, `intentSummary`, `baseUrl`, `startCommand`, and `healthPath`.
16
+
17
+ 1. Confirm artifact presence:
18
+ - `artifacts/flow.json`
19
+ - `artifacts/bootstrap.json` (recommended)
20
+ - optional `artifacts/structure-report.json`
21
+ - optional `artifacts/navigation-graph.json`
22
+ - optional `artifacts/studioflow-cli-handoff.json`
23
+
24
+ 2. Run doctor checks:
25
+
26
+ ```bash
27
+ pnpm setup
28
+ pnpm run doctor
29
+ ```
30
+
31
+ If run preflight fails, collect explicit Screen Studio diagnostics:
32
+
33
+ ```bash
34
+ pnpm screenstudio-prep
35
+ ```
36
+
37
+ 3. Validate flow artifact:
38
+
39
+ ```bash
40
+ pnpm validate -- --flow artifacts/flow.json
41
+ ```
42
+
43
+ 4. Execute recording run from artifact:
44
+
45
+ ```bash
46
+ pnpm demo -- --flow <flowPath> --intent "<intent-summary>" --base-url <baseUrl> --start-command "<startCommand>" --health-path <healthPath>
47
+ ```
48
+
49
+ 5. Inspect outputs:
50
+ - `.runs/<run-id>/run.json`
51
+ - `.runs/<run-id>/events.jsonl`
52
+ - `.runs/<run-id>/screenshots/*`
53
+
54
+ 6. If run fails, inspect error step in `events.jsonl`, patch flow selectors/pacing, and rerun from step 3.
55
+
56
+ ## Execution Behavior (Required)
57
+
58
+ 1. If the skill is invoked for execution, run the commands directly; do not stop at command suggestions.
59
+ 2. Do not ask the user "how to run the CLI" after handoff has already supplied run parameters.
60
+ 3. Only ask follow-up questions when required run anchors are missing (`flowPath`, `baseUrl`, or `startCommand`/healthy app).
61
+
62
+ ## Runtime Rules
63
+
64
+ 1. Use artifact execution (`--flow`) only.
65
+ 2. Keep execution deterministic; do not modify codebase during run unless explicitly requested.
66
+ 3. Report exact artifact paths and failing step IDs for every failure.
67
+
68
+ Use references in:
69
+ - `references/troubleshooting.md`
70
+ - `references/handoff-spec.md`
@@ -0,0 +1,38 @@
1
+ # Handoff Input Spec
2
+
3
+ `studioflow-cli` accepts a runtime handoff file from `studioflow-investigate`:
4
+
5
+ - `artifacts/studioflow-cli-handoff.json`
6
+
7
+ ## Expected payload
8
+
9
+ ```json
10
+ {
11
+ "version": 1,
12
+ "intentSummary": "Record only onboarding + CRM in Demo Lab",
13
+ "flowPath": "artifacts/flow.json",
14
+ "baseUrl": "http://localhost:4280",
15
+ "startCommand": "pnpm dev:demo-lab",
16
+ "healthPath": "/",
17
+ "notes": []
18
+ }
19
+ ```
20
+
21
+ ## Required keys
22
+
23
+ - `version`
24
+ - `intentSummary`
25
+ - `flowPath`
26
+ - `baseUrl`
27
+ - `healthPath`
28
+
29
+ `startCommand` is recommended. If omitted, runtime can still proceed when app is already healthy.
30
+
31
+ ## Execution mapping
32
+
33
+ From payload, execute:
34
+
35
+ 1. `pnpm validate -- --flow <flowPath>`
36
+ 2. `pnpm demo -- --flow <flowPath> --intent "<intentSummary>" --base-url <baseUrl> --start-command "<startCommand>" --health-path <healthPath>`
37
+
38
+ If payload is missing, fall back to explicit user arguments or repo defaults.
@@ -0,0 +1,16 @@
1
+ # Troubleshooting
2
+
3
+ ## Permission failures
4
+ - Error: osascript not allowed to send keystrokes
5
+ - Action: approve Terminal/iTerm in macOS Privacy & Security > Accessibility and Automation
6
+
7
+ ## Selector failures
8
+ - Error: step action missing target or locator timeout
9
+ - Action: patch `artifacts/flow.json` selector and rerun `pnpm validate`
10
+
11
+ ## Browser executable failures
12
+ - Error: Playwright Chromium not installed
13
+ - Action: `studioflow setup` (or `pnpm setup` in this repo)
14
+
15
+ ## Artifact path checks
16
+ - Run artifacts under `.runs/<run-id>/`
@@ -0,0 +1,95 @@
1
+ ---
2
+ name: studioflow-investigate
3
+ description: Investigate an arbitrary web project and generate deterministic StudioFlow artifacts. Use when the user asks to discover app structure, map routes/components/actions, synthesize artifacts/flow.json from natural-language intent, or clarify open/ambiguous intent before authoring a flow.
4
+ ---
5
+
6
+ # StudioFlow Investigate
7
+
8
+ Generate deterministic demo-planning artifacts for any web app.
9
+
10
+ ## Workflow
11
+
12
+ 1. Inspect project root and identify framework, package manager, and startup command.
13
+ 2. Always collect project context artifacts before intent mapping.
14
+
15
+ Do this automatically in the skill workflow. Do not ask the user to run these commands manually.
16
+
17
+ ```bash
18
+ pnpm bootstrap -- --out artifacts/bootstrap.json
19
+ pnpm discover -- --out artifacts
20
+ ```
21
+
22
+ Fallback if `pnpm` workspace scripts are unavailable:
23
+
24
+ ```bash
25
+ studioflow bootstrap --out artifacts/bootstrap.json
26
+ studioflow discover --out artifacts
27
+ ```
28
+
29
+ 3. Review generated artifacts:
30
+ - `artifacts/bootstrap.json`
31
+ - `artifacts/structure-report.json`
32
+ - `artifacts/navigation-graph.json`
33
+
34
+ 4. Resolve intent specificity before authoring `artifacts/flow.json`.
35
+
36
+ Open-intent detection:
37
+ - Treat intent as open when one or more anchors are missing:
38
+ - `target_route`: where the flow should navigate
39
+ - `user_goal`: what user action/outcome to demonstrate
40
+ - `done_assertion`: what text/element proves completion
41
+
42
+ Clarification loop:
43
+ - Max 2 rounds.
44
+ - Ask 1-3 questions per round (adaptive; only missing high-impact fields).
45
+ - Question priority: `done_assertion` -> `target_route` -> `user_goal` -> optional inputs/scope.
46
+ - If host supports structured question-card requests, emit payloads from `references/question-card-spec.md`.
47
+ - If structured cards are not supported, ask equivalent plain-language questions.
48
+ - Track known/missing fields using `references/clarification-state.md`.
49
+
50
+ 5. Author `artifacts/flow.json` from intent + discovered structure + clarified answers.
51
+
52
+ Rules for authored flow:
53
+ - Deterministic steps only.
54
+ - Prefer stable selectors (`data-testid`).
55
+ - Include clear step IDs and assertions at key transitions.
56
+ - Include optional pacing fields when useful for recording quality.
57
+ - If clarification remains incomplete after 2 rounds, generate best-effort flow with explicit assumptions.
58
+
59
+ 6. Validate candidate flow:
60
+
61
+ ```bash
62
+ pnpm validate -- --flow artifacts/flow.json
63
+ ```
64
+
65
+ 7. If validation fails, edit flow actions/selectors and rerun validation.
66
+
67
+ 8. Emit deterministic runtime handoff for `studioflow-cli`.
68
+
69
+ Write `artifacts/studioflow-cli-handoff.json` using `references/cli-handoff-spec.md`.
70
+
71
+ 9. Hand off execution to `studioflow-cli` immediately.
72
+
73
+ - If your host supports explicit skill invocation, invoke `studioflow-cli` in the same turn using the handoff payload.
74
+ - If explicit skill invocation is unavailable, execute the equivalent CLI run workflow directly in the same turn.
75
+ - Do not stop at "here is the command to run" when the user intent is to run/record a demo.
76
+
77
+ ## Output Requirements
78
+
79
+ Always produce these files for handoff to runtime execution:
80
+ 1. `artifacts/bootstrap.json`
81
+ 2. `artifacts/structure-report.json`
82
+ 3. `artifacts/navigation-graph.json`
83
+ 4. `artifacts/flow.json`
84
+ 5. `artifacts/studioflow-cli-handoff.json`
85
+
86
+ Always include a concise handoff summary in the response:
87
+ - resolved intent anchors
88
+ - unresolved assumptions (if any)
89
+ - confidence (`high|medium|low`)
90
+
91
+ Use references in:
92
+ - `references/artifact-spec.md`
93
+ - `references/question-card-spec.md`
94
+ - `references/clarification-state.md`
95
+ - `references/cli-handoff-spec.md`
@@ -0,0 +1,37 @@
1
+ # Artifact Spec
2
+
3
+ ## structure-report.json
4
+ - generatedAt
5
+ - projectRoot
6
+ - packageManager
7
+ - frameworkHints[]
8
+ - startCommands[]
9
+ - routes[]
10
+ - components[]
11
+ - existingFlowIds[]
12
+ - notes[]
13
+
14
+ ## navigation-graph.json
15
+ - generatedAt
16
+ - nodes[] with id/route/file
17
+ - edges[] with from/to/via/confidence
18
+
19
+ ## flow.json
20
+ Use StudioFlow FlowDefinition schema:
21
+ - id
22
+ - description
23
+ - tags[]
24
+ - preconditions[] optional
25
+ - steps[]
26
+
27
+ Flow steps may include pacing fields:
28
+ - preDelayMs
29
+ - postDelayMs
30
+ - mouseMoveMs
31
+ - highlightMs
32
+ - dwellMs
33
+ - narrativeCheckpoint
34
+
35
+ ## Open-intent fallback note
36
+
37
+ When the user intent remains open after clarification rounds, the assistant should still generate deterministic `flow.json` and include assumptions + confidence in the response handoff.
@@ -0,0 +1,42 @@
1
+ # Clarification State Template
2
+
3
+ Use this lightweight state model while resolving open intent.
4
+
5
+ ```yaml
6
+ roundsUsed: 0
7
+ maxRounds: 2
8
+ known:
9
+ target_route: null
10
+ user_goal: null
11
+ done_assertion: null
12
+ data_input: []
13
+ scope_limit: null
14
+ missing:
15
+ - target_route
16
+ - user_goal
17
+ - done_assertion
18
+ assumptions: []
19
+ confidence: low
20
+ risks: []
21
+ ```
22
+
23
+ ## Update rules
24
+
25
+ 1. After each user reply, update `known` and recalculate `missing`.
26
+ 2. Stop asking follow-ups when required anchors are all known:
27
+ - `target_route`
28
+ - `user_goal`
29
+ - `done_assertion`
30
+ 3. Do not exceed 2 rounds.
31
+ 4. If anchors are still missing after round 2:
32
+ - add explicit `assumptions`
33
+ - keep `confidence: low`
34
+ - generate best-effort deterministic `flow.json`
35
+
36
+ ## Handoff summary format
37
+
38
+ Include in final response:
39
+
40
+ - `Resolved`: key anchors and selected values
41
+ - `Assumptions`: any inferred defaults
42
+ - `Confidence`: `high|medium|low`
@@ -0,0 +1,42 @@
1
+ # CLI Handoff Spec
2
+
3
+ Use this artifact to hand execution from `studioflow-investigate` to `studioflow-cli`.
4
+
5
+ Path:
6
+
7
+ - `artifacts/studioflow-cli-handoff.json`
8
+
9
+ ## JSON shape
10
+
11
+ ```json
12
+ {
13
+ "version": 1,
14
+ "intentSummary": "Record only onboarding + CRM in Demo Lab",
15
+ "flowPath": "artifacts/flow.json",
16
+ "baseUrl": "http://localhost:4280",
17
+ "startCommand": "pnpm dev:demo-lab",
18
+ "healthPath": "/",
19
+ "notes": [
20
+ "Use deterministic artifact execution only."
21
+ ]
22
+ }
23
+ ```
24
+
25
+ ## Field rules
26
+
27
+ - `version`: integer, currently `1`.
28
+ - `intentSummary`: concise run label for CLI `--intent`.
29
+ - `flowPath`: deterministic artifact path. Default: `artifacts/flow.json`.
30
+ - `baseUrl`: runtime host URL.
31
+ - `startCommand`: command used when app is not already healthy.
32
+ - `healthPath`: health probe path used by runtime.
33
+ - `notes`: optional operator notes.
34
+
35
+ ## Invocation contract
36
+
37
+ When handoff artifact is written, immediately invoke `studioflow-cli` (or equivalent runtime workflow in same agent) to execute:
38
+
39
+ 1. `pnpm validate -- --flow <flowPath>`
40
+ 2. `pnpm demo -- --flow <flowPath> --intent "<intentSummary>" --base-url <baseUrl> --start-command "<startCommand>" --health-path <healthPath>`
41
+
42
+ Do not ask the user to translate the handoff into commands.
@@ -0,0 +1,44 @@
1
+ # Question Card Spec
2
+
3
+ Use this when intent is open and the host supports structured question-card UI.
4
+
5
+ If structured cards are unavailable, ask equivalent plain-language questions.
6
+
7
+ ## Payload shape
8
+
9
+ ```json
10
+ {
11
+ "cardId": "target-route",
12
+ "reason": "Need primary destination to map deterministic steps.",
13
+ "question": "Which route should the demo focus on first?",
14
+ "required": true,
15
+ "options": [
16
+ { "label": "Onboarding", "value": "/onboarding" },
17
+ { "label": "Billing", "value": "/billing" },
18
+ { "label": "Home", "value": "/" }
19
+ ],
20
+ "freeformAllowed": true,
21
+ "mapsTo": "target_route"
22
+ }
23
+ ```
24
+
25
+ ## Fields
26
+
27
+ - `cardId`: stable identifier for this question.
28
+ - `reason`: single-sentence rationale.
29
+ - `question`: user-facing prompt.
30
+ - `required`: whether this question is mandatory for mapping.
31
+ - `options`: 2-4 suggested choices from discovered app routes/actions when possible.
32
+ - `freeformAllowed`: allow custom response if choices do not fit.
33
+ - `mapsTo`: one of:
34
+ - `target_route`
35
+ - `user_goal`
36
+ - `done_assertion`
37
+ - `data_input`
38
+ - `scope_limit`
39
+
40
+ ## Round constraints
41
+
42
+ - Max 2 rounds total.
43
+ - Ask 1-3 cards/questions per round.
44
+ - Ask only missing high-impact fields.
package/tsconfig.json ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "outDir": "dist"
5
+ },
6
+ "include": ["src/**/*.ts"]
7
+ }