@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.
- package/dist/bin.js +7283 -4541
- package/dist/commands/advise.d.ts +31 -0
- package/dist/commands/answer-input.d.ts +20 -0
- package/dist/commands/complete.d.ts +1 -5
- package/dist/commands/context.d.ts +0 -7
- package/dist/commands/evaluate.d.ts +5 -0
- package/dist/commands/match.d.ts +5 -0
- package/dist/commands/new-finding.d.ts +2 -0
- package/dist/commands/open.d.ts +2 -1
- package/dist/commands/register-walkthrough.d.ts +1 -1
- package/dist/commands/report-data.d.ts +16 -0
- package/dist/commands/report.d.ts +7 -2
- package/dist/index.js +7497 -4732
- package/dist/templates/prompts/advise.md +111 -0
- package/dist/templates/prompts/walk.md +5 -3
- package/dist/templates/skills/iamu-findings.md +21 -12
- package/dist/templates/skills/iamu-new.md +45 -8
- package/dist/templates/skills/iamu-propose.md +36 -7
- package/dist/templates/skills/iamu-run.md +70 -32
- package/dist/templates/skills/iamu-setup.md +78 -13
- package/dist/templates/skills/iamu-stage.md +18 -3
- package/dist/ui/html-report.d.ts +87 -0
- package/dist/ui/report-view.d.ts +95 -0
- package/package.json +1 -1
|
@@ -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.
|
|
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
|
|
97
|
-
|
|
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.
|
|
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
|
|
158
|
-
|
|
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
|
|
161
|
-
|
|
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**.
|
|
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
|
|
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
|
|
211
|
-
|
|
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
|
-
**
|
|
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
|
|
111
|
-
|
|
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[];
|