@iamu-dev/iamu 0.3.0-beta.5 → 0.4.0-beta.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.
@@ -77,7 +77,10 @@ No local codebase detected. To seed context, provide one of:
77
77
 
78
78
  ### 3. Step 1/3: Establish the Safety Fence (`iamu/testability.md`)
79
79
 
80
- Present the detected environment and safety fence. Explain clearly *why* this boundary is required before any autonomous agent runs. Do NOT wrap in markdown code fences (` ``` `) when presenting to the user:
80
+ Present the detected environment and safety fence. Explain clearly *why* this boundary is required before any autonomous agent runs.
81
+
82
+ **Dual-Surface Prompting (Sequencing Rule):**
83
+ You MUST output the safety fence card to the chat stream FIRST. In the SAME turn, invoke `ask_question` with the full context embedded in the `question` argument:
81
84
 
82
85
  ```text
83
86
  Step 1/3: Safety Fence & Environment Boundary
@@ -93,12 +96,30 @@ Detected Environment:
93
96
  **Interactive Decision Gate:**
94
97
  Prompt the user to verify the safety boundary:
95
98
  - If interactive user-prompt tools exist (`ask_question`, `ask_followup_question`), invoke it:
96
- - Question: "Confirm safety fence and dev environment?"
97
- - Options:
99
+ - **Question:**
100
+ """
101
+ Step 1/3: Confirm Safety Fence & Dev Environment
102
+
103
+ Target URL: <target_url>
104
+ Dev Command: <dev_command>
105
+ Safe Fixtures: <detected seed scripts or mock handlers>
106
+
107
+ DO NOT WALK (Untestable Boundaries):
108
+ <detected external services, real SMS/email gateways, external submission portals>
109
+
110
+ Confirm safety fence and dev environment?
111
+ """
112
+ - **Options:**
98
113
  1. "[Recommended] Safety boundaries look safe — save fence and proceed"
99
114
  2. "Adjust boundaries (add forbidden external URLs, change dev command or port)"
100
115
  3. "Skip safety fence for now"
101
116
  - Otherwise (text-only/CLI):
117
+ Step 1/3: Safety Fence & Environment Boundary
118
+ Target URL: <target_url>
119
+ Dev Command: <dev_command>
120
+ Safe Fixtures: <detected seed scripts or mock handlers>
121
+ DO NOT WALK: <detected external services>
122
+
102
123
  Safety boundaries look safe. I recommend saving fence and proceeding.
103
124
  Proceeding to save safety fence — say "adjust" to change boundaries or "skip" to defer.
104
125
 
@@ -138,7 +159,10 @@ iamu set testability \
138
159
 
139
160
  Explain the purpose of project context: traditional tests only assert button clicks; Iamu evaluates user confusion, workflow friction, and whether a real person can succeed under real-world constraints.
140
161
 
141
- Present the discovered domain and project description. Do NOT introduce or ask the user to approve personas or roles at this stage — personas are cast later when designing specific test journeys. Do NOT wrap in markdown code fences (` ``` `) when presenting to the user:
162
+ Present the discovered domain and project description. Do NOT introduce or ask the user to approve personas or roles at this stage — personas are cast later when designing specific test journeys.
163
+
164
+ **Dual-Surface Prompting (Sequencing Rule):**
165
+ You MUST output the domain context and project description to the chat stream FIRST. In the SAME turn, invoke `ask_question` with the complete substantive project description embedded in the `question` argument so the reviewer can read the full text directly within the dialog modal:
142
166
 
143
167
  ```text
144
168
  Step 2/3: Project Domain & Description
@@ -154,15 +178,38 @@ Project Description:
154
178
  <1 cohesive paragraph: what the software fundamentally does, its primary user workflows, and the real-world conditions under which it is used. No marketing buzzwords, no hedging, and no tech stack trivia.>
155
179
  ```
156
180
 
157
- **Interactive Decision Gate:**
158
- Prompt the user to verify the project description:
181
+ **CRITICAL: Embed Full Project Description in Interactive Prompt Modal:**
182
+ Host interactive tools (`ask_question`, `ask_followup_question`) render a modal that obscures the terminal/chat and displays ONLY the tool's `question` argument. Never ask the user to confirm an invisible description. You MUST embed the full drafted project description text inside the `question` argument:
183
+
159
184
  - If interactive user-prompt tools exist (`ask_question`, `ask_followup_question`), invoke it:
160
- - Question: "Confirm project domain & description?"
161
- - Options:
185
+ - **Question:**
186
+ """
187
+ Step 2/3: Confirm Project Domain & Description
188
+
189
+ Domain: <domain name>
190
+ Industry: <industry>
191
+ Jurisdiction: <jurisdiction or omit if standard web app>
192
+ Governed By: <statutory regulations or standards, or omit if unregulated>
193
+
194
+ PROJECT DESCRIPTION:
195
+ <1 cohesive paragraph: what the software fundamentally does, its primary user workflows, and the real-world conditions under which it is used>
196
+
197
+ Confirm project domain & description?
198
+ """
199
+ - **Options:**
162
200
  1. "[Recommended] Project description is accurate — proceed to design first test"
163
201
  2. "Save project description only (skip scenario creation for now)"
164
202
  3. "Adjust domain or description"
165
203
  - Otherwise (text-only/CLI):
204
+ Step 2/3: Project Domain & Description
205
+ Domain: <domain name>
206
+ Industry: <industry>
207
+ Jurisdiction: <jurisdiction>
208
+ Governed By: <statutory regulations or standards>
209
+
210
+ Project Description:
211
+ <1 cohesive paragraph>
212
+
166
213
  Project description is accurate. I recommend proceeding to design your first test.
167
214
  Proceeding to first test design — say "save only" or describe adjustments to change course.
168
215
 
@@ -185,7 +232,10 @@ iamu set context \
185
232
 
186
233
  Explain the journey model: an Iamu test binds a **Persona** (with habits, pressures, and impatience) to a **Situation** (a realistic high-stakes problem) with an **Evaluation Checkpoint** (a concrete binary question for the AI judge).
187
234
 
188
- Present the proposed test journey, including explicit **Auth Precondition Verification**. Do NOT wrap in markdown code fences (` ``` `) when presenting to the user:
235
+ Present the proposed test journey, including explicit **Auth Precondition Verification**.
236
+
237
+ **Dual-Surface Prompting (Sequencing Rule):**
238
+ You MUST output the baseline test proposal to the chat stream FIRST. In the SAME turn, invoke `ask_question` with the full journey spec embedded in the `question` argument:
189
239
 
190
240
  ```text
191
241
  Step 3/3: Co-Design Your First Test Journey
@@ -204,11 +254,26 @@ Baseline Test Proposal (WYSIWGW Spec-Sheet):
204
254
  Walker Brief: "<2–3 sentence first-person test brief that will be written verbatim to disk. States immediate intent and constraints before opening tool. Zero UI terminology.>"
205
255
  ```
206
256
 
207
- **Interactive Decision Gate:**
208
- Prompt the user to verify the scenario and its auth precondition:
257
+ **CRITICAL: Embed Journey Spec in Interactive Prompt Modal:**
209
258
  - If interactive user-prompt tools exist (`ask_question`, `ask_followup_question`), invoke it:
210
- - Question: "Scaffold this baseline journey?"
211
- - Options:
259
+ - **Question:**
260
+ """
261
+ Step 3/3: Confirm Baseline Test Journey
262
+
263
+ Capability: <Capability Name> (<What staff can do in this area>)
264
+ Persona: <Name> (<Role / Title>) — Friction: <Diagnostic friction trigger>
265
+ Situation: <Outline Title>
266
+ Core Tension: <Core problem-space tension in X vs Y format>
267
+ Evaluation Check: <Concrete binary yes/partial/no question for evaluator>
268
+ Walk Surface: Entry: `<entry_path>` | Target: `<target_url>`
269
+ Auth Precondition: <Detected auth mechanism>
270
+
271
+ WALKER BRIEF:
272
+ "<2–3 sentence first-person test brief>"
273
+
274
+ Scaffold this baseline journey?
275
+ """
276
+ - **Options:**
212
277
  1. "[Recommended] Scaffold journey with <detected auth mechanism>"
213
278
  2. "Use interactive human login handshake (pause browser for live login)"
214
279
  3. "Switch role / design a different scenario (write-in)"
@@ -105,10 +105,25 @@ Now present the **Strategic Fork** to the user. Do not be an unyielding bureaucr
105
105
  - State: "This situation reads a public page and requires no pre-existing world state."
106
106
  - Mark `--state-description "No particular data needed"`.
107
107
 
108
- **Interactive Decision Gate:**
108
+ **Dual-Surface Staging Gate (Sequencing Rule):**
109
+ You MUST output the staging options to the chat stream FIRST. In the SAME turn, invoke `ask_question` with the staging options and requirements embedded in the `question` argument:
110
+
109
111
  - If your environment provides an interactive user-prompt tool (e.g. `ask_question`, `ask_followup_question`), invoke it:
110
- - Question: "How should we stage '<scenario-slug>' for walkthrough?"
111
- - Options:
112
+ - **Question:**
113
+ """
114
+ Staging Plan for '<scenario-slug>':
115
+
116
+ Entry Route: <route>
117
+ Required World State: <Description of required world in domain words>
118
+
119
+ Staging Options:
120
+ • Option A (Testability): <concrete seed or mock fixture proposal>
121
+ • Option B (Semantic Squinting): <squinting rule formula>
122
+ • Option C (Zero Setup): <why flow is public or self-contained>
123
+
124
+ How should we stage '<scenario-slug>' for walkthrough?
125
+ """
126
+ - **Options:**
112
127
  1. "[Recommended] Option A: Build Testability (<brief seed proposal>)"
113
128
  2. "Option B: Semantic Squinting (test immediately against current dev database)"
114
129
  3. "Option C: Zero Setup Needed (public or self-contained flow)"
@@ -0,0 +1,87 @@
1
+ export interface HtmlReportHighlight {
2
+ targetBox: {
3
+ x: number;
4
+ y: number;
5
+ width: number;
6
+ height: number;
7
+ viewportWidth?: number;
8
+ viewportHeight?: number;
9
+ viewport_width?: number;
10
+ viewport_height?: number;
11
+ };
12
+ label?: string;
13
+ severity?: string | null;
14
+ type?: string;
15
+ }
16
+ export interface HtmlReportStep {
17
+ stepNumber: number;
18
+ action: string;
19
+ screenTitle?: string | null;
20
+ personaReasoning?: string | null;
21
+ url?: string | null;
22
+ screenshotUrl?: string | null;
23
+ targetBox?: {
24
+ x: number;
25
+ y: number;
26
+ width: number;
27
+ height: number;
28
+ viewportWidth?: number;
29
+ viewportHeight?: number;
30
+ viewport_width?: number;
31
+ viewport_height?: number;
32
+ } | null;
33
+ highlights?: HtmlReportHighlight[];
34
+ }
35
+ export interface HtmlReportFinding {
36
+ id: string;
37
+ title: string;
38
+ type: string;
39
+ severity?: string | null;
40
+ uiFact?: string | null;
41
+ consequence?: string | null;
42
+ recommendation?: string | null;
43
+ }
44
+ export interface HtmlReportVerdict {
45
+ question: string;
46
+ rating: string;
47
+ reasoning?: string;
48
+ }
49
+ export interface HtmlReportVerification {
50
+ resolved: unknown[];
51
+ persists: unknown[];
52
+ newFindings: unknown[];
53
+ }
54
+ export interface HtmlReportData {
55
+ scenarioName: string;
56
+ scenarioNarrative?: string | null;
57
+ persona?: {
58
+ name: string;
59
+ role?: string | null;
60
+ context?: string | null;
61
+ } | null;
62
+ walkthroughId: string;
63
+ runNumber?: number | string | null;
64
+ startedAt?: string | null | Date;
65
+ completedAt?: string | null | Date;
66
+ targetUrl?: string | null;
67
+ steps: HtmlReportStep[];
68
+ findings: HtmlReportFinding[];
69
+ verdicts?: HtmlReportVerdict[];
70
+ verification?: HtmlReportVerification | null;
71
+ whatWorked?: string[];
72
+ openQuestions?: string[];
73
+ }
74
+ export declare function generateHtmlReport(data: HtmlReportData): string;
75
+ /**
76
+ * Builds HtmlReportData by reading a completed run directory and resolving
77
+ * persona/scenario files and local screenshots into base64 data URIs.
78
+ */
79
+ export declare function buildReportDataFromRun(projectRoot: string, runId: string): Promise<HtmlReportData>;
80
+ /**
81
+ * Creates and writes a self-contained local HTML report for a walkthrough run.
82
+ * Defaults to writing to `iamu/.runs/<runId>/report.html`.
83
+ */
84
+ export declare function createLocalHtmlReport(projectRoot: string, runId: string, destination?: string): Promise<{
85
+ filePath: string;
86
+ html: string;
87
+ }>;
@@ -0,0 +1,95 @@
1
+ export type VerdictLabel = "YES" | "PARTIAL" | "NO" | "PENDING" | "BLOCKED";
2
+ export interface RunFindingRow {
3
+ id: string;
4
+ /** Finding file slug, for `iamu triage <slug>`; null when the file is gone. */
5
+ slug: string | null;
6
+ severity: string | null;
7
+ type: string;
8
+ title: string;
9
+ where: string | null;
10
+ /** The advisor's recommendation, when the run was advised. */
11
+ recommendation: string | null;
12
+ persists: boolean;
13
+ isNew: boolean;
14
+ }
15
+ export type SinceOutcome = "resolved" | "persists" | "not_seen" | "uncertain";
16
+ export interface RunView {
17
+ persona: string;
18
+ situation: string;
19
+ completedAt: string | null;
20
+ steps: number;
21
+ targetUrl: string | null;
22
+ /** Cloud link, or a note that the run is not synced; null when not linked. */
23
+ cloud: string | null;
24
+ verdict: {
25
+ label: VerdictLabel;
26
+ question: string | null;
27
+ answer: string | null;
28
+ };
29
+ tests: Array<{
30
+ question: string;
31
+ label: VerdictLabel;
32
+ }>;
33
+ since: {
34
+ baselineAt: string | null;
35
+ resolved: number;
36
+ persists: number;
37
+ added: number;
38
+ notSeen: number;
39
+ /** Each earlier finding this run re-checked, by title. */
40
+ items: Array<{
41
+ title: string;
42
+ outcome: SinceOutcome;
43
+ }>;
44
+ } | null;
45
+ findings: RunFindingRow[];
46
+ strengths: string[];
47
+ directions: Array<{
48
+ title: string;
49
+ size: string;
50
+ absorbs: number;
51
+ verify: number;
52
+ }>;
53
+ observations: Array<{
54
+ kind: string;
55
+ title: string;
56
+ }>;
57
+ }
58
+ export interface OverviewRun {
59
+ completedAt: string | null;
60
+ label: VerdictLabel;
61
+ problems: number;
62
+ resolved: number;
63
+ persists: number;
64
+ added: number;
65
+ }
66
+ export interface OverviewScenario {
67
+ persona: string;
68
+ situation: string;
69
+ slug: string;
70
+ runs: OverviewRun[];
71
+ latestAnswer: string | null;
72
+ }
73
+ export interface OverviewView {
74
+ project: string;
75
+ scenarios: OverviewScenario[];
76
+ openProblems: number;
77
+ directions: Array<{
78
+ title: string;
79
+ status: string;
80
+ size: string;
81
+ absorbs: number;
82
+ }>;
83
+ }
84
+ export declare function verdictColor(label: VerdictLabel): (s: string) => string;
85
+ /** "9 Oct 07:54" in local time; the raw value when it does not parse. */
86
+ export declare function shortDate(iso: string | null): string;
87
+ /** Word-wrap plain text to `width`, each line prefixed with `indent`. */
88
+ export declare function wrap(text: string, width: number, indent: string): string[];
89
+ export declare function firstSentence(text: string): string;
90
+ /** Opening sentences of a text, enough to say something (≥ 60 chars). */
91
+ export declare function lead(text: string): string;
92
+ /** The latest run of one scenario, outcome first. */
93
+ export declare function renderRunView(v: RunView, width?: number): string[];
94
+ /** Every scenario and how its runs went, newest scenario first. */
95
+ export declare function renderOverview(v: OverviewView, width?: number): string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iamu-dev/iamu",
3
- "version": "0.3.0-beta.5",
3
+ "version": "0.4.0-beta.0",
4
4
  "type": "module",
5
5
  "description": "Test your product as realistic personas — scenario-driven development CLI",
6
6
  "license": "UNLICENSED",