@ia-qa/self-healing 1.25.0 → 1.26.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/README.md CHANGED
@@ -152,7 +152,16 @@ npx ia-qa-heal login # opens a real browser; you log in however the app asks
152
152
  npx ia-qa-heal map # reuses that session
153
153
  ```
154
154
 
155
- **The session is checked before it is saved.** Once you say you are logged in, `login` reopens
155
+ **Nothing to confirm in the terminal.** `login` watches the window and finishes by itself the
156
+ moment the session it carries genuinely opens the app — "press Enter when you are done" was
157
+ the last place this verb took somebody's word for a fact about the world, and it mostly went
158
+ unanswered while the person got on with their day. What counts as done is a definition rather
159
+ than a guess: a clean browser carrying only the captured session has to reach somewhere the
160
+ logged-out one could not, so a magic-link login page with no password field on it is never
161
+ mistaken for success. `--wait 0` restores the press-Enter flow for an app whose login cannot
162
+ be observed from outside; `--wait <seconds>` changes how long to watch.
163
+
164
+ **The session is checked before it is saved.** `login` reopens
156
165
  the same page in a clean browser carrying nothing but the captured session. Only a session that
157
166
  lands on the app is saved and reported as good. A session that carries nothing is **not
158
167
  written at all** — it could log nobody in, and writing it would replace a session that worked.
package/TUTORIAL.md CHANGED
@@ -278,9 +278,23 @@ npx ia-qa-heal login # a real browser window opens at your first configured
278
278
  npx ia-qa-heal map # reuses that session; no "auth" block needed
279
279
  ```
280
280
 
281
- **It checks the session before saving it, and tells you which file now holds what.** When you
282
- say you are logged in, the session is replayed in a clean browser: same page, nothing but the
283
- captured cookies and local storage.
281
+ **You do not have to come back and confirm anything.** The window is watched: the moment the
282
+ session it carries genuinely opens the app, it is saved and the command finishes on its own.
283
+ That replaces "press Enter when you are done", which was the last place this verb took a
284
+ human's word for a fact about the world — and which failed in the most ordinary way there is,
285
+ by being left unanswered while the person went back to work.
286
+
287
+ What counts as done is a definition, not a guess: **a clean browser carrying only the captured
288
+ session has to reach somewhere the logged-out one could not.** Reading "no password field on
289
+ screen" as success instead would call a magic-link or passkey login page a finished login.
290
+
291
+ If your app's login cannot be seen from the outside at all, `--wait 0` restores the plain
292
+ press-Enter flow, and `--wait <seconds>` sets how long to watch (default 10 minutes). Running
293
+ out of time is **not** a refusal: whatever the browser holds is checked and reported anyway.
294
+
295
+ **It checks the session before saving it, and tells you which file now holds what.** The
296
+ session is replayed in a clean browser: same page, nothing but the captured cookies and local
297
+ storage.
284
298
 
285
299
  | what the replay shows | what happens | exit |
286
300
  |---|---|---|
package/dist/cli/args.js CHANGED
@@ -17,7 +17,7 @@ exports.rejectUnknownFlags = rejectUnknownFlags;
17
17
  exports.KNOWN_FLAGS = {
18
18
  init: ['--yes', '--base-url', '--pages', '--discover', '--tests', '--test-command', '--bootstrap'],
19
19
  discover: ['--sitemap', '--crawl', '--no-reveal', '--strict-host', '--apply', '--max', '--depth', '--session'],
20
- login: ['--url', '--session'],
20
+ login: ['--url', '--session', '--wait'],
21
21
  secret: ['--json'],
22
22
  session: ['--check', '--offline', '--url', '--session', '--json'],
23
23
  map: ['--screenshots', '--session', '--deep', '--depth', '--deep-budget', '--fix-redirects'],
@@ -1 +1 @@
1
- {"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":";;;AAkCA,gDAeC;AAjDD;;;;;;;;;;;GAWG;AACU,QAAA,WAAW,GAAsC;IAC5D,IAAI,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,aAAa,CAAC;IAClG,QAAQ,EAAE,CAAC,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,CAAC;IAC9G,KAAK,EAAE,CAAC,OAAO,EAAE,WAAW,CAAC;IAC7B,MAAM,EAAE,CAAC,QAAQ,CAAC;IAClB,OAAO,EAAE,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,CAAC;IACjE,GAAG,EAAE,CAAC,eAAe,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,iBAAiB,CAAC;IAC5F,QAAQ,EAAE,CAAC,WAAW,CAAC;IACvB,IAAI,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC;IACtE,GAAG,EAAE,CAAC,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,CAAC;IACnD,MAAM,EAAE,CAAC,QAAQ,CAAC;IAClB,KAAK,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC;IAC7B,OAAO,EAAE,CAAC,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,CAAC;IACvD,KAAK,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,CAAC;IAC3D,KAAK,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC;IAChD,GAAG,EAAE,CAAC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC;IACtF,KAAK,EAAE,CAAC,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC;IAC7D,OAAO,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC9B,YAAY,EAAE,CAAC,QAAQ,CAAC;IACxB,EAAE,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,CAAC;CACnF,CAAC;AAEF,SAAgB,kBAAkB,CAAC,OAAe,EAAE,IAAc;IAChE,MAAM,KAAK,GAAG,mBAAW,CAAC,OAAO,CAAC,CAAC;IACnC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO;IAChC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QACjC,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,SAAS;QAChC,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CACb,eAAe,OAAO,0FAA0F;gBAC9G,4GAA4G;gBAC5G,8FAA8F,CACjG,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,qBAAqB,OAAO,8CAA8C,CAAC,CAAC;IAChH,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":";;;AAkCA,gDAeC;AAjDD;;;;;;;;;;;GAWG;AACU,QAAA,WAAW,GAAsC;IAC5D,IAAI,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,aAAa,CAAC;IAClG,QAAQ,EAAE,CAAC,WAAW,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,CAAC;IAC9G,KAAK,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,CAAC;IACvC,MAAM,EAAE,CAAC,QAAQ,CAAC;IAClB,OAAO,EAAE,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,WAAW,EAAE,QAAQ,CAAC;IACjE,GAAG,EAAE,CAAC,eAAe,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,iBAAiB,CAAC;IAC5F,QAAQ,EAAE,CAAC,WAAW,CAAC;IACvB,IAAI,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC;IACtE,GAAG,EAAE,CAAC,WAAW,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,CAAC;IACnD,MAAM,EAAE,CAAC,QAAQ,CAAC;IAClB,KAAK,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC;IAC7B,OAAO,EAAE,CAAC,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,CAAC;IACvD,KAAK,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,eAAe,CAAC;IAC3D,KAAK,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC;IAChD,GAAG,EAAE,CAAC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC;IACtF,KAAK,EAAE,CAAC,WAAW,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,CAAC;IAC7D,OAAO,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC;IAC9B,YAAY,EAAE,CAAC,QAAQ,CAAC;IACxB,EAAE,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,CAAC;CACnF,CAAC;AAEF,SAAgB,kBAAkB,CAAC,OAAe,EAAE,IAAc;IAChE,MAAM,KAAK,GAAG,mBAAW,CAAC,OAAO,CAAC,CAAC;IACnC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO;IAChC,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QACjC,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,SAAS;QAChC,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1C,MAAM,IAAI,KAAK,CACb,eAAe,OAAO,0FAA0F;gBAC9G,4GAA4G;gBAC5G,8FAA8F,CACjG,CAAC;QACJ,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,qBAAqB,OAAO,8CAA8C,CAAC,CAAC;IAChH,CAAC;AACH,CAAC"}
@@ -1,4 +1,4 @@
1
- import type { Browser } from 'playwright';
1
+ import type { Browser, BrowserContext, Page } from 'playwright';
2
2
  /**
3
3
  * `ia-qa-heal login` — open a browser, let a human log in, keep the session.
4
4
  *
@@ -26,7 +26,19 @@ import type { Browser } from 'playwright';
26
26
  * with your own suite's login) remain the two paths. A saved session is a local artefact
27
27
  * with a shelf life — when it expires, `map` hits the wall again and says to re-run this.
28
28
  */
29
- export declare function runLogin(args: string[]): Promise<void>;
29
+ /**
30
+ * What the verb achieved, for a caller that is not a shell.
31
+ *
32
+ * `ok` is the same thing the exit code says — a session that was **replayed** and opened the
33
+ * app — so an orchestrator cannot read success more loosely than the terminal does. The exit
34
+ * code is still set, because this is a CLI verb first.
35
+ */
36
+ export interface LoginResult {
37
+ ok: boolean;
38
+ /** Where the session was written, when anything was written at all. */
39
+ file?: string;
40
+ }
41
+ export declare function runLogin(args: string[]): Promise<LoginResult>;
30
42
  export interface SessionReplay {
31
43
  landed: string;
32
44
  wall: boolean;
@@ -58,6 +70,78 @@ export interface SessionReplay {
58
70
  * says nothing when the browser is not even on the app any more.
59
71
  */
60
72
  export declare function replaySession(browser: Browser, state: Awaited<ReturnType<Awaited<ReturnType<Browser['newContext']>>['storageState']>>, target: string, contextOptions?: Record<string, unknown>): Promise<SessionReplay>;
73
+ /** Why the watch stopped. Only `verified` means the session was proven from a clean context. */
74
+ export type LoginEnd = 'verified' | 'confirmed' | 'closed' | 'timeout';
75
+ export interface LoginWatch {
76
+ end: LoginEnd;
77
+ /** The verification that ended the watch, when one did. */
78
+ replay?: SessionReplay;
79
+ /**
80
+ * The state that `replay` was taken from — never a later one.
81
+ *
82
+ * They travel together because they must: verifying state S1 and then writing an S2 taken
83
+ * a moment later reports a proof about a file that was never the file. That is this
84
+ * verb's own bug in a new place, and the pair makes it unrepresentable.
85
+ */
86
+ state?: Awaited<ReturnType<BrowserContext['storageState']>>;
87
+ }
88
+ /**
89
+ * Is this state, replayed in a clean context, evidence that somebody logged in?
90
+ *
91
+ * One rule, and it is the definition rather than a heuristic: **a login worked when a clean
92
+ * context reaches somewhere the unauthenticated browser could not.** `startedAt` is where
93
+ * the very first navigation landed — the wall — so a replay that lands back there gained
94
+ * nothing, whatever it shows.
95
+ *
96
+ * Reading "no password field" as success instead is the trap this avoids, and it is not
97
+ * theoretical: a magic-link or passkey login page has no password field at all, so the
98
+ * cheap signal says *logged in* from the first second, and the watch would save a state
99
+ * that opens nothing and call it ✅ — the exact false green this verb was rewritten to stop.
100
+ */
101
+ export declare function loginProven(replay: SessionReplay, startedAt: string): boolean;
102
+ /**
103
+ * Watch a visible browser until the person is logged in — instead of asking them to say so.
104
+ *
105
+ * The prompt this replaces was the last place in the verb that trusted a human's word, and
106
+ * the verb's whole history is about not doing that: `storageState({ path })` wrote on that
107
+ * word and printed `✅ Session saved — 0 cookies` over a file that logged nobody in. Asking
108
+ * "are you done?" has the same shape — it is a question about the world answered by
109
+ * someone who is looking at a browser, not at the cookie jar. And it fails in the most
110
+ * ordinary way there is: the person logs in, goes back to what they were doing, and the
111
+ * terminal sits on an unanswered prompt. It was reported by the person who wrote it.
112
+ *
113
+ * So the watch asks the browser, on a loop, and the evidence it accepts is the one the rest
114
+ * of this file already accepts: a **clean context** carrying only the captured state,
115
+ * reaching somewhere the unauthenticated browser could not (`loginProven`).
116
+ *
117
+ * Three restraints:
118
+ *
119
+ * - **It never gives up early.** A verification that fails means *not yet* — a multi-step
120
+ * login, a consent screen still to come — never *this will not work*. After a few failed
121
+ * attempts it explains the one case that genuinely cannot succeed (a token in IndexedDB
122
+ * leaves a session file empty) and keeps watching, because the alternative is telling
123
+ * somebody their login failed while they are still typing.
124
+ * - **The keyboard still works.** `confirmed` is the escape hatch for every app whose
125
+ * login this cannot observe, and whichever finishes first wins. Nothing that worked
126
+ * before stops working.
127
+ * - **Replaying is not free**, so the cheap gate runs first: on the app's own site, no
128
+ * password field in any frame, and something in the cookie jar. A clean context is
129
+ * opened only once that holds, and then only when the live page has moved again or
130
+ * enough time has passed.
131
+ */
132
+ export declare function watchForLogin(opts: {
133
+ browser: Browser;
134
+ context: BrowserContext;
135
+ page: Page;
136
+ target: string;
137
+ /** Where the FIRST navigation landed: the wall, and the thing a replay must beat. */
138
+ startedAt: string;
139
+ contextOptions?: Record<string, unknown>;
140
+ confirmed: Promise<void>;
141
+ timeoutMs?: number;
142
+ now?: () => number;
143
+ note?: (line: string) => void;
144
+ }): Promise<LoginWatch>;
61
145
  export interface SessionDecision {
62
146
  ok: boolean;
63
147
  action: 'write' | 'quarantine' | 'none';
package/dist/cli/login.js CHANGED
@@ -38,6 +38,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.runLogin = runLogin;
40
40
  exports.replaySession = replaySession;
41
+ exports.loginProven = loginProven;
42
+ exports.watchForLogin = watchForLogin;
41
43
  exports.sessionDecision = sessionDecision;
42
44
  const fs = __importStar(require("fs"));
43
45
  const path = __importStar(require("path"));
@@ -46,33 +48,7 @@ const launcher_1 = require("../launcher");
46
48
  const map_1 = require("./map");
47
49
  const sessionCheck_1 = require("../sessionCheck");
48
50
  const config_1 = require("../config");
49
- /**
50
- * `ia-qa-heal login` — open a browser, let a human log in, keep the session.
51
- *
52
- * `config.auth` fills a form: a username field, a password field, a submit button. That
53
- * describes *one shape of login*, and every app whose login is not that shape is out of
54
- * reach — federated SSO, MFA, a consent screen, a magic link, a device check, a captcha.
55
- * No selector list gets through any of them, so "add an auth block" is the wrong answer
56
- * to most walls, and `map` was left mapping a login form under the name `dashboard`.
57
- *
58
- * This verb models nothing at all, which is why it is the general one: the human performs
59
- * whatever the app asks, and the resulting session is saved in Playwright's `storageState`
60
- * shape and reused by `map`. It cannot know *how* your app authenticates, and never needs to.
61
- *
62
- * Deliberately not automatic, and never part of a gate:
63
- * - It is the only caller that opens a **visible** browser (`headed`) — everything that
64
- * produces a contract stays headless, because a window in CI is a hung build.
65
- * - It refuses without a TTY and under CI: it waits for a person twice over (at the
66
- * browser, then at the keyboard), and a pipeline that runs it just hangs.
67
- * - What it writes is a **secret** — live cookies, i.e. whoever holds the file is logged
68
- * in as that user. So it announces the path before opening anything, and writes
69
- * `.ia-qa/.gitignore` so a commit cannot carry it. The file never leaves the machine:
70
- * nothing in this package uploads it.
71
- *
72
- * For CI, `config.auth` (reproducible, no human) and capture-during-run (`IAQA_CAPTURE=1`
73
- * with your own suite's login) remain the two paths. A saved session is a local artefact
74
- * with a shelf life — when it expires, `map` hits the wall again and says to re-run this.
75
- */
51
+ const sessionCheck_2 = require("../sessionCheck");
76
52
  async function runLogin(args) {
77
53
  if (process.env.CI) {
78
54
  console.error(`❌ Refusing to open a login browser under CI.\n\n` +
@@ -81,14 +57,14 @@ async function runLogin(args) {
81
57
  ` "auth" in .ia-qa/config.json fills a login form from env/SSM secrets\n` +
82
58
  ` IAQA_CAPTURE=1 + testCommand your own suite logs in; map rides along`);
83
59
  process.exitCode = 2;
84
- return;
60
+ return { ok: false };
85
61
  }
86
62
  if (!process.stdin.isTTY) {
87
63
  console.error(`❌ \`ia-qa-heal login\` needs a terminal: it opens a browser, then waits for you to say\n` +
88
64
  ` you are logged in. With stdin closed it would wait forever.\n` +
89
65
  ` Run it in your own shell — an agent cannot do this step for you.`);
90
66
  process.exitCode = 2;
91
- return;
67
+ return { ok: false };
92
68
  }
93
69
  const config = (0, config_1.loadConfig)();
94
70
  const urlIdx = args.indexOf('--url');
@@ -96,7 +72,7 @@ async function runLogin(args) {
96
72
  if (urlIdx !== -1 && (!wanted || wanted.startsWith('-'))) {
97
73
  console.error('❌ --url needs a URL or a path (e.g. --url /dashboard).');
98
74
  process.exitCode = 2;
99
- return;
75
+ return { ok: false };
100
76
  }
101
77
  const target = new URL(wanted || config.pages[0]?.url || '/', config.baseUrl).toString();
102
78
  // Written where this project keeps its session, not always the default: someone who
@@ -107,9 +83,19 @@ async function runLogin(args) {
107
83
  if (sessionIdx !== -1 && (!explicit || explicit.startsWith('-'))) {
108
84
  console.error('❌ --session needs a file path.');
109
85
  process.exitCode = 2;
110
- return;
86
+ return { ok: false };
111
87
  }
112
88
  const file = (0, config_1.sessionTarget)(config, explicit).file;
89
+ // How long to watch the window before falling back to "tell me what is in there".
90
+ // `--wait 0` turns the watch off and restores the plain press-Enter flow, which is the
91
+ // escape hatch for an app whose login cannot be observed from the outside at all.
92
+ const waitIdx = args.indexOf('--wait');
93
+ const waitSeconds = waitIdx !== -1 ? Number(args[waitIdx + 1]) : 600;
94
+ if (waitIdx !== -1 && (!Number.isFinite(waitSeconds) || waitSeconds < 0)) {
95
+ console.error('❌ --wait needs a number of seconds (0 turns the watch off).');
96
+ process.exitCode = 2;
97
+ return { ok: false };
98
+ }
113
99
  console.log(`\n🔑 ia-qa-heal login`);
114
100
  console.log(` Opens a visible browser at ${target}.`);
115
101
  console.log(` Log in there however your app asks — SSO, MFA, a consent screen, all of it.`);
@@ -123,7 +109,7 @@ async function runLogin(args) {
123
109
  if (!go.ok) {
124
110
  console.log('Nothing opened, nothing written.');
125
111
  process.exitCode = 1;
126
- return;
112
+ return { ok: false };
127
113
  }
128
114
  const { browser, using } = await (0, launcher_1.launchBrowser)({ headed: true });
129
115
  console.log(`🌐 Using ${using} (visible window)`);
@@ -132,21 +118,69 @@ async function runLogin(args) {
132
118
  const context = await browser.newContext(contextOptions);
133
119
  const page = await context.newPage();
134
120
  await page.goto(target, { waitUntil: 'domcontentloaded', timeout: 60000 });
135
- await (0, prompts_1.default)({
136
- type: 'confirm',
137
- name: 'done',
138
- message: 'Logged in? (leave the browser open — press Enter here when the app is showing)',
139
- initial: true,
140
- }, { onCancel: () => ({ done: true }) });
121
+ // Where an UNauthenticated browser lands is the thing a real login has to beat, so it
122
+ // is read before anything else happens.
123
+ const startedAt = page.url();
124
+ console.log(waitSeconds > 0
125
+ ? `\n👀 Log in in the browser window. I am watching it — when the session actually opens\n` +
126
+ ` the app, I save it and carry on by myself. Nothing to come back and confirm here.\n` +
127
+ ` (Press Enter if you would rather stop the wait now.)`
128
+ : `\n👀 Log in in the browser window, then press Enter here.`);
129
+ const enter = waitForEnter();
130
+ let watch;
131
+ try {
132
+ watch =
133
+ waitSeconds > 0
134
+ ? await watchForLogin({
135
+ browser,
136
+ context,
137
+ page,
138
+ target,
139
+ startedAt,
140
+ contextOptions,
141
+ confirmed: enter.promise,
142
+ timeoutMs: waitSeconds * 1000,
143
+ })
144
+ : (await enter.promise, { end: 'confirmed' });
145
+ }
146
+ finally {
147
+ enter.cancel();
148
+ }
149
+ // A timeout is **not** a refusal. It only means nobody told us the login finished, so
150
+ // the question becomes the one this verb always answers: what does the browser actually
151
+ // hold right now? `sessionDecision` says it honestly — an empty state writes nothing and
152
+ // keeps the file that worked, a wall goes beside it, neither is ever a ✅. Returning
153
+ // early instead would throw away a session somebody really did obtain, just because the
154
+ // watch could not see the app from the outside.
155
+ if (watch.end === 'timeout') {
156
+ console.log(`\n⏳ Nothing that looks like a login happened in ${(0, sessionCheck_2.describeAge)(waitSeconds)}. Checking what the\n` +
157
+ ` browser holds anyway — whatever it is, it is reported rather than assumed.`);
158
+ }
141
159
  // Taken in memory, written only once it has been replayed. `storageState({ path })`
142
160
  // wrote first and asked nothing, so an empty state — an app keeping its token in
143
161
  // IndexedDB, or a login that never completed — printed a green "Session saved" *and*
144
162
  // overwrote a session that worked. Two failures in one line: a false green, and the
145
163
  // destruction of the good file it replaced.
146
- const takenOn = page.url();
147
- const state = await context.storageState();
148
- console.log(`\n🔁 Checking the session actually holds reopening ${target} with it, in a clean browser.`);
149
- const replay = await replaySession(browser, state, target, contextOptions);
164
+ //
165
+ // A closed window is not a special case: whatever the context held when it went is what
166
+ // gets judged, and `sessionDecision` says the honest thing about it.
167
+ const takenOn = page.isClosed() ? startedAt : page.url();
168
+ // The state and the proof about it travel together — writing a state taken *after* the
169
+ // verification would report a proof about a file that was never the file.
170
+ //
171
+ // Which pair, though, depends on how the watch ended. `verified` is the watch's own, by
172
+ // definition. A **closed** window leaves no way to take another, so the last attempt is
173
+ // all there is. But `confirmed` must be re-checked: pressing Enter means *look now*, and
174
+ // the person very often finishes the login and only then reaches for the keyboard — the
175
+ // last failed attempt would be a verdict about the moment before they succeeded.
176
+ const reusable = watch.end === 'verified' || (watch.end === 'closed' && watch.state);
177
+ let state = reusable ? watch.state : undefined;
178
+ let replay = reusable ? watch.replay : undefined;
179
+ if (!state || !replay) {
180
+ state = await context.storageState().catch(() => ({ cookies: [], origins: [] }));
181
+ console.log(`\n🔁 Checking the session actually holds — reopening ${target} with it, in a clean browser.`);
182
+ replay = await replaySession(browser, state, target, contextOptions);
183
+ }
150
184
  const decision = sessionDecision({
151
185
  cookies: state.cookies.length,
152
186
  origins: state.origins?.length || 0,
@@ -167,11 +201,37 @@ async function runLogin(args) {
167
201
  (decision.ok ? console.log : console.error)(line);
168
202
  if (!decision.ok)
169
203
  process.exitCode = 1;
204
+ return { ok: decision.ok, ...(decision.action !== 'none' ? { file: decision.target } : {}) };
170
205
  }
171
206
  finally {
172
207
  await browser.close();
173
208
  }
174
209
  }
210
+ /**
211
+ * "Press Enter" as a *cancellable* promise, which `prompts` cannot be.
212
+ *
213
+ * The watch and the keyboard race each other, so the loser has to be taken back: a `prompts`
214
+ * question left open keeps stdin resumed and the process alive long after the browser has
215
+ * closed and the session has been written. Raw stdin gives back a `cancel` that removes the
216
+ * listener and pauses the stream, which is the whole reason for not reusing `prompts` here.
217
+ */
218
+ function waitForEnter() {
219
+ let done = () => { };
220
+ const promise = new Promise((resolve) => {
221
+ done = resolve;
222
+ });
223
+ const onData = () => {
224
+ cancel();
225
+ done();
226
+ };
227
+ const cancel = () => {
228
+ process.stdin.off('data', onData);
229
+ process.stdin.pause();
230
+ };
231
+ process.stdin.resume();
232
+ process.stdin.on('data', onData);
233
+ return { promise, cancel };
234
+ }
175
235
  /**
176
236
  * `.ia-qa/.gitignore`, scoped to the one file in there that is a secret.
177
237
  *
@@ -230,6 +290,117 @@ async function replaySession(browser, state, target, contextOptions = {}) {
230
290
  await context.close();
231
291
  }
232
292
  }
293
+ /**
294
+ * Is this state, replayed in a clean context, evidence that somebody logged in?
295
+ *
296
+ * One rule, and it is the definition rather than a heuristic: **a login worked when a clean
297
+ * context reaches somewhere the unauthenticated browser could not.** `startedAt` is where
298
+ * the very first navigation landed — the wall — so a replay that lands back there gained
299
+ * nothing, whatever it shows.
300
+ *
301
+ * Reading "no password field" as success instead is the trap this avoids, and it is not
302
+ * theoretical: a magic-link or passkey login page has no password field at all, so the
303
+ * cheap signal says *logged in* from the first second, and the watch would save a state
304
+ * that opens nothing and call it ✅ — the exact false green this verb was rewritten to stop.
305
+ */
306
+ function loginProven(replay, startedAt) {
307
+ if (replay.error || replay.wall || replay.offSite)
308
+ return false;
309
+ if (!replay.landed)
310
+ return false;
311
+ return !(0, map_1.samePath)(replay.landed, startedAt);
312
+ }
313
+ /**
314
+ * Watch a visible browser until the person is logged in — instead of asking them to say so.
315
+ *
316
+ * The prompt this replaces was the last place in the verb that trusted a human's word, and
317
+ * the verb's whole history is about not doing that: `storageState({ path })` wrote on that
318
+ * word and printed `✅ Session saved — 0 cookies` over a file that logged nobody in. Asking
319
+ * "are you done?" has the same shape — it is a question about the world answered by
320
+ * someone who is looking at a browser, not at the cookie jar. And it fails in the most
321
+ * ordinary way there is: the person logs in, goes back to what they were doing, and the
322
+ * terminal sits on an unanswered prompt. It was reported by the person who wrote it.
323
+ *
324
+ * So the watch asks the browser, on a loop, and the evidence it accepts is the one the rest
325
+ * of this file already accepts: a **clean context** carrying only the captured state,
326
+ * reaching somewhere the unauthenticated browser could not (`loginProven`).
327
+ *
328
+ * Three restraints:
329
+ *
330
+ * - **It never gives up early.** A verification that fails means *not yet* — a multi-step
331
+ * login, a consent screen still to come — never *this will not work*. After a few failed
332
+ * attempts it explains the one case that genuinely cannot succeed (a token in IndexedDB
333
+ * leaves a session file empty) and keeps watching, because the alternative is telling
334
+ * somebody their login failed while they are still typing.
335
+ * - **The keyboard still works.** `confirmed` is the escape hatch for every app whose
336
+ * login this cannot observe, and whichever finishes first wins. Nothing that worked
337
+ * before stops working.
338
+ * - **Replaying is not free**, so the cheap gate runs first: on the app's own site, no
339
+ * password field in any frame, and something in the cookie jar. A clean context is
340
+ * opened only once that holds, and then only when the live page has moved again or
341
+ * enough time has passed.
342
+ */
343
+ async function watchForLogin(opts) {
344
+ const note = opts.note ?? ((line) => console.log(line));
345
+ const now = opts.now ?? Date.now;
346
+ const deadline = now() + (opts.timeoutMs ?? 10 * 60 * 1000);
347
+ let confirmed = false;
348
+ void opts.confirmed.then(() => {
349
+ confirmed = true;
350
+ });
351
+ let lastVerifiedUrl = '';
352
+ let lastVerifiedAt = 0;
353
+ let attempts = 0;
354
+ // The last attempt, kept as a pair. It is offered on a `confirmed`/`closed` ending only
355
+ // because it is a true statement about a state we still hold; it is never a success.
356
+ let last;
357
+ for (;;) {
358
+ if (confirmed)
359
+ return { end: 'confirmed', ...last };
360
+ if (opts.page.isClosed())
361
+ return { end: 'closed', ...last };
362
+ if (now() >= deadline)
363
+ return { end: 'timeout', ...last };
364
+ let url = '';
365
+ let cookies = 0;
366
+ try {
367
+ url = opts.page.url();
368
+ cookies = (await opts.context.cookies()).length;
369
+ }
370
+ catch {
371
+ // The context went away under us — the person closed the window.
372
+ return { end: 'closed', ...last };
373
+ }
374
+ const worthVerifying = cookies > 0 &&
375
+ (0, sessionCheck_1.sameSite)(url, opts.target) &&
376
+ !(0, map_1.samePath)(url, opts.startedAt) &&
377
+ !(await (0, map_1.hasPasswordField)(opts.page, 0)) &&
378
+ (url !== lastVerifiedUrl || now() - lastVerifiedAt > 8000);
379
+ if (worthVerifying) {
380
+ lastVerifiedUrl = url;
381
+ lastVerifiedAt = now();
382
+ attempts++;
383
+ let state;
384
+ try {
385
+ state = await opts.context.storageState();
386
+ }
387
+ catch {
388
+ return { end: 'closed', ...last };
389
+ }
390
+ const replay = await replaySession(opts.browser, state, opts.target, opts.contextOptions ?? {});
391
+ last = { replay, state };
392
+ if (loginProven(replay, opts.startedAt))
393
+ return { end: 'verified', replay, state };
394
+ if (attempts === 3) {
395
+ note(`\n ⏳ You look logged in, but the session I can carry does not open the app on its own yet.\n` +
396
+ ` Still watching — a multi-step login is normal here. If your app keeps its token in\n` +
397
+ ` IndexedDB, in memory or in a service worker, a session file can never hold it:\n` +
398
+ ` press Enter and I will tell you exactly that instead of waiting.`);
399
+ }
400
+ }
401
+ await new Promise((r) => setTimeout(r, 1200));
402
+ }
403
+ }
233
404
  /**
234
405
  * What to do with a session that has just been replayed — and above all, what never to do.
235
406
  *
@@ -1 +1 @@
1
- {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/cli/login.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/cli/login.ts"],"names":[],"mappings":"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"}
@@ -21,4 +21,31 @@ export interface SessionCheck {
21
21
  facts: SessionFacts;
22
22
  verdict: SessionVerdict;
23
23
  }
24
+ /**
25
+ * The same check, for a caller that is not a terminal.
26
+ *
27
+ * Exported because an orchestrator has a reason to ask this *before* it spends minutes on a
28
+ * SUT — a session is one credential for the whole app, so a dead one makes every page of a
29
+ * tour fail in turn, and the field has watched exactly that happen for eighteen minutes.
30
+ * It is the verdict `session --check` prints, not a second opinion: rebuilding it from
31
+ * `readFacts` and a navigation is the CLI/MCP dispatch split in another costume.
32
+ *
33
+ * `present: false` is not a failure — a project with no session file is the ordinary case
34
+ * for a public app or one using `config.auth`, and calling that "broken" would be a wrong
35
+ * verdict on a healthy project.
36
+ */
37
+ export interface SessionProbe {
38
+ present: boolean;
39
+ file?: string;
40
+ source?: string;
41
+ facts?: SessionFacts;
42
+ verdict?: SessionVerdict;
43
+ /** The file exists but could not be read or parsed. */
44
+ unreadable?: string;
45
+ }
46
+ export declare function probeSession(opts?: {
47
+ url?: string;
48
+ session?: string;
49
+ offline?: boolean;
50
+ }): Promise<SessionProbe>;
24
51
  export declare function runSessionCheck(args: string[]): Promise<void>;
@@ -33,12 +33,40 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.probeSession = probeSession;
36
37
  exports.runSessionCheck = runSessionCheck;
37
38
  const fs = __importStar(require("fs"));
38
39
  const config_1 = require("../config");
39
40
  const launcher_1 = require("../launcher");
40
41
  const login_1 = require("./login");
41
42
  const sessionCheck_1 = require("../sessionCheck");
43
+ async function probeSession(opts = {}) {
44
+ const config = (0, config_1.loadConfig)();
45
+ const choice = (0, config_1.resolveSession)(config, opts.session);
46
+ if (!choice)
47
+ return { present: false };
48
+ let state;
49
+ try {
50
+ state = JSON.parse(fs.readFileSync(choice.file, 'utf8'));
51
+ }
52
+ catch (err) {
53
+ return { present: true, file: choice.file, source: choice.source, unreadable: err instanceof Error ? err.message : String(err) };
54
+ }
55
+ const target = opts.url ?? config.baseUrl;
56
+ const facts = (0, sessionCheck_1.readFacts)(state, target);
57
+ const offlineVerdict = (0, sessionCheck_1.judgeSession)(facts);
58
+ if (offlineVerdict.cause !== 'unknown' || opts.offline) {
59
+ return { present: true, file: choice.file, source: choice.source, facts, verdict: offlineVerdict };
60
+ }
61
+ const { browser } = await (0, launcher_1.launchBrowser)();
62
+ try {
63
+ const replay = await (0, login_1.replaySession)(browser, state, target);
64
+ return { present: true, file: choice.file, source: choice.source, facts, verdict: (0, sessionCheck_1.judgeSession)(facts, replay) };
65
+ }
66
+ finally {
67
+ await browser.close();
68
+ }
69
+ }
42
70
  /**
43
71
  * The causes that mean *could not tell*, as opposed to *does not hold*.
44
72
  *
@@ -74,9 +102,11 @@ async function runSessionCheck(args) {
74
102
  const wantedUrl = urlIdx !== -1 ? args[urlIdx + 1] : undefined;
75
103
  const sessionIdx = args.indexOf('--session');
76
104
  const wantedSession = sessionIdx !== -1 ? args[sessionIdx + 1] : undefined;
77
- const config = (0, config_1.loadConfig)();
78
- const choice = (0, config_1.resolveSession)(config, wantedSession);
79
- if (!choice) {
105
+ // Every fact and every verdict comes from `probeSession`; this function only renders and
106
+ // picks the exit code. An orchestrator asking the same question in process therefore gets
107
+ // the identical answer, which is the point of having extracted it.
108
+ const probe = await probeSession({ url: wantedUrl, session: wantedSession, offline });
109
+ if (!probe.present) {
80
110
  // Not a failure: a project with no session is the ordinary case for a public app or one
81
111
  // using `config.auth`. Saying "no session is broken" would be a wrong verdict.
82
112
  const message = `No session file to check.\n` +
@@ -88,33 +118,13 @@ async function runSessionCheck(args) {
88
118
  console.log(`\nℹ️ ${message}`);
89
119
  return;
90
120
  }
91
- let state;
92
- try {
93
- state = JSON.parse(fs.readFileSync(choice.file, 'utf8'));
94
- }
95
- catch (err) {
96
- console.error(`❌ ${choice.file} could not be read: ${err instanceof Error ? err.message : String(err)}`);
121
+ if (probe.unreadable || !probe.facts || !probe.verdict) {
122
+ console.error(`❌ ${probe.file} could not be read: ${probe.unreadable ?? 'no verdict'}`);
97
123
  process.exitCode = 2;
98
124
  return;
99
125
  }
100
- const target = wantedUrl ?? config.baseUrl;
101
- const facts = (0, sessionCheck_1.readFacts)(state, target);
102
- // The offline causes are conclusive, so the browser is not opened to re-confirm an expiry
103
- // date — the cheapest honest answer, not a degraded one.
104
- const offlineVerdict = (0, sessionCheck_1.judgeSession)(facts);
105
- const decidedOffline = offlineVerdict.cause !== 'unknown';
106
- let verdict = offlineVerdict;
107
- if (!decidedOffline && !offline) {
108
- const { browser } = await (0, launcher_1.launchBrowser)();
109
- try {
110
- const replay = await (0, login_1.replaySession)(browser, state, target);
111
- verdict = (0, sessionCheck_1.judgeSession)(facts, replay);
112
- }
113
- finally {
114
- await browser.close();
115
- }
116
- }
117
- const check = { file: choice.file, source: choice.source, facts, verdict };
126
+ const check = { file: probe.file, source: probe.source, facts: probe.facts, verdict: probe.verdict };
127
+ const verdict = probe.verdict;
118
128
  if (json) {
119
129
  console.log(JSON.stringify({ schema: 'ia-qa-heal/session@1', present: true, ...check }, null, 2));
120
130
  }
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/cli/session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/cli/session.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -36,6 +36,10 @@ export { configuredTestPaths } from './config';
36
36
  export { runMap, LoginWallError } from './cli/map';
37
37
  export type { MapResult, MapFailure, MapPageStat } from './cli/map';
38
38
  export { runBaseline } from './cli/baseline';
39
+ export { probeSession } from './cli/session';
40
+ export type { SessionProbe } from './cli/session';
41
+ export { runLogin } from './cli/login';
42
+ export type { LoginResult } from './cli/login';
39
43
  export { dirDiffAggregate } from './cli/diff';
40
44
  export type { DirReport, DirDiffCollection } from './cli/diff';
41
45
  export type { RouteChange } from './routeDrift';
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.globToRegex = exports.readTestDepth = exports.collectUnattributable = exports.computePageDepth = exports.computeTestDepth = exports.saveExercised = exports.EXERCISED_FILENAME = exports.contractPageNames = exports.exercisedPath = exports.loadExercised = exports.usagePath = exports.usageFiles = exports.loadUsage = exports.saveUsage = exports.ingestPaths = exports.scanText = exports.crawlApp = exports.sitemapsFromRobots = exports.isSitemapIndex = exports.extractLocs = exports.discoverFromSitemap = exports.UNSAFE_URL_RE = exports.mergePages = exports.toCandidate = exports.normalizedPath = exports.isSafeCandidateUrl = exports.resolvePageName = exports.pageNameFromUrl = exports.mapUrl = exports.markdownPath = exports.saveMarkdown = exports.renderPageContract = exports.saveMapping = exports.loadMapping = exports.extractInteractiveElements = exports.COMPATIBLE_EXAMPLES = exports.renderModelList = exports.defaultKeyEnv = exports.findProvider = exports.AI_PROVIDERS = exports.parseModelJson = exports.buildPrompt = exports.prefilter = exports.aiResolve = exports.PROVIDER_HOST = exports.egressHost = exports.createAiResolver = exports.llmResolverStub = exports.aiFill = exports.aiClick = void 0;
4
- exports.renderNavigation = exports.renderOverview = exports.buildOverview = exports.minPagesForLayout = exports.stripLayoutFromPages = exports.extractLayout = exports.isWebAddress = exports.readSitemap = exports.writeSetup = exports.planSetup = exports.listShape = exports.groupListChurn = exports.maskDigits = exports.groupNumericLabelDrift = exports.detectTestCommand = exports.auditProject = exports.runFix = exports.HISTORY_FILENAME = exports.historyPath = exports.WIDE_RUN_SHARE = exports.pageChurn = exports.readHistory = exports.checkCounts = exports.checkHeadline = exports.checkVerdict = exports.checkProject = exports.dirDiffAggregate = exports.runBaseline = exports.LoginWallError = exports.runMap = exports.configuredTestPaths = exports.baselineDir = exports.mappingDir = exports.setBaseDir = exports.LAYOUT_DIRNAME = exports.layoutPath = exports.layoutDir = exports.maskSecret = exports.looksLikeSecret = exports.resolveSecret = exports.loadConfig = exports.replaceQuoted = exports.collectFiles = exports.applyRewrites = exports.computeRewrites = exports.launchBrowser = exports.CAPTURE_DIRNAME = exports.captureDir = exports.unionElements = exports.mergeCaptures = void 0;
5
- exports.createSkillVerb = exports.NAVIGATION_SVG_FILENAME = exports.NAVIGATION_FILENAME = exports.OVERVIEW_FILENAME = exports.navigationSvgPath = exports.navigationPath = exports.overviewPath = exports.writeOverview = exports.navigationGraph = exports.layoutGraph = exports.renderNavigationSvg = void 0;
4
+ exports.buildOverview = exports.minPagesForLayout = exports.stripLayoutFromPages = exports.extractLayout = exports.isWebAddress = exports.readSitemap = exports.writeSetup = exports.planSetup = exports.listShape = exports.groupListChurn = exports.maskDigits = exports.groupNumericLabelDrift = exports.detectTestCommand = exports.auditProject = exports.runFix = exports.HISTORY_FILENAME = exports.historyPath = exports.WIDE_RUN_SHARE = exports.pageChurn = exports.readHistory = exports.checkCounts = exports.checkHeadline = exports.checkVerdict = exports.checkProject = exports.dirDiffAggregate = exports.runLogin = exports.probeSession = exports.runBaseline = exports.LoginWallError = exports.runMap = exports.configuredTestPaths = exports.baselineDir = exports.mappingDir = exports.setBaseDir = exports.LAYOUT_DIRNAME = exports.layoutPath = exports.layoutDir = exports.maskSecret = exports.looksLikeSecret = exports.resolveSecret = exports.loadConfig = exports.replaceQuoted = exports.collectFiles = exports.applyRewrites = exports.computeRewrites = exports.launchBrowser = exports.CAPTURE_DIRNAME = exports.captureDir = exports.unionElements = exports.mergeCaptures = void 0;
5
+ exports.createSkillVerb = exports.NAVIGATION_SVG_FILENAME = exports.NAVIGATION_FILENAME = exports.OVERVIEW_FILENAME = exports.navigationSvgPath = exports.navigationPath = exports.overviewPath = exports.writeOverview = exports.navigationGraph = exports.layoutGraph = exports.renderNavigationSvg = exports.renderNavigation = exports.renderOverview = void 0;
6
6
  var healer_1 = require("./playwright/healer");
7
7
  Object.defineProperty(exports, "aiClick", { enumerable: true, get: function () { return healer_1.aiClick; } });
8
8
  Object.defineProperty(exports, "aiFill", { enumerable: true, get: function () { return healer_1.aiFill; } });
@@ -112,6 +112,16 @@ Object.defineProperty(exports, "runMap", { enumerable: true, get: function () {
112
112
  Object.defineProperty(exports, "LoginWallError", { enumerable: true, get: function () { return map_1.LoginWallError; } });
113
113
  var baseline_1 = require("./cli/baseline");
114
114
  Object.defineProperty(exports, "runBaseline", { enumerable: true, get: function () { return baseline_1.runBaseline; } });
115
+ // The session half an orchestrator needs BEFORE it spends minutes on a SUT. A session is one
116
+ // credential for the whole app, so a dead one makes every page fail in turn — the field has
117
+ // watched that run for eighteen minutes. `probeSession` is the verdict `session --check`
118
+ // prints, not a second opinion; `runLogin` is the one step that needs a person, exported so
119
+ // an orchestrator can hand the browser over instead of printing a command to copy. It still
120
+ // refuses without a TTY and under CI, which is what keeps it out of an agent's reach.
121
+ var session_1 = require("./cli/session");
122
+ Object.defineProperty(exports, "probeSession", { enumerable: true, get: function () { return session_1.probeSession; } });
123
+ var login_1 = require("./cli/login");
124
+ Object.defineProperty(exports, "runLogin", { enumerable: true, get: function () { return login_1.runLogin; } });
115
125
  var diff_1 = require("./cli/diff");
116
126
  Object.defineProperty(exports, "dirDiffAggregate", { enumerable: true, get: function () { return diff_1.dirDiffAggregate; } });
117
127
  var check_1 = require("./cli/check");
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ia-qa/self-healing",
3
- "version": "1.25.0",
3
+ "version": "1.26.0",
4
4
  "description": "Your Playwright, Cypress or Selenium tests break when a selector moves — this finds the element again and rewrites the test. Deterministic: no LLM decides whether your build passes. Runs entirely on your machine, with a local MCP server for agents.",
5
5
  "keywords": [
6
6
  "self-healing",
@@ -174,7 +174,11 @@ established which element the test meant.
174
174
  report those as pages that failed. For everything a form cannot answer there is exactly one step, and it
175
175
  belongs to the human: `ia-qa-heal login` opens a visible browser, they log in once, and the
176
176
  session is reused by `map`. It refuses without a TTY and under CI — that refusal is aimed at
177
- you. Never ask for their password, never put a credential in `config.json` (it holds `secrets`
177
+ you. Tell them there is **nothing to confirm afterwards**: the verb watches the window and
178
+ saves the session the moment it genuinely opens the app, so the old "press Enter when done"
179
+ step is gone. Do not tell them to run it with `--wait 0` unless their login cannot be
180
+ observed from outside at all — that flag restores the manual step you would be asking them
181
+ to remember. Never ask for their password, never put a credential in `config.json` (it holds `secrets`
178
182
  *references* to env/SSM, never values), and never commit `.ia-qa/session.json` — it is a live
179
183
  session, gitignored on creation. For CI, the reproducible paths are `auth` and capture-during-
180
184
  run (`IAQA_CAPTURE=1` + `testCommand`), never a saved session.