@ia-qa/pal 0.2.0 → 0.4.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 +50 -10
- package/TUTORIAL.md +144 -27
- package/dist/accept.d.ts +20 -0
- package/dist/accept.js +119 -0
- package/dist/accept.js.map +1 -0
- package/dist/cli/index.js +97 -18
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/mcp/server.d.ts +95 -0
- package/dist/mcp/server.js +251 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/plan.d.ts +60 -1
- package/dist/plan.js +59 -1
- package/dist/plan.js.map +1 -1
- package/dist/report.js +113 -28
- package/dist/report.js.map +1 -1
- package/dist/run.d.ts +66 -0
- package/dist/run.js +209 -0
- package/dist/run.js.map +1 -0
- package/dist/setup.d.ts +11 -0
- package/dist/setup.js +52 -4
- package/dist/setup.js.map +1 -1
- package/dist/state.d.ts +3 -0
- package/dist/state.js.map +1 -1
- package/dist/suite.d.ts +63 -0
- package/dist/suite.js +145 -0
- package/dist/suite.js.map +1 -0
- package/dist/tour.d.ts +66 -6
- package/dist/tour.js +125 -30
- package/dist/tour.js.map +1 -1
- package/package.json +4 -3
package/dist/cli/index.js
CHANGED
|
@@ -35,9 +35,11 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
})();
|
|
36
36
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
37
|
const readline = __importStar(require("readline/promises"));
|
|
38
|
-
const
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
39
|
const report_1 = require("../report");
|
|
40
40
|
const setup_1 = require("../setup");
|
|
41
|
+
const run_1 = require("../run");
|
|
42
|
+
const accept_1 = require("../accept");
|
|
41
43
|
const VERSION = require('../../package.json').version;
|
|
42
44
|
const HELP = `ia-qa-pal — a QA pal next to your team
|
|
43
45
|
|
|
@@ -49,34 +51,59 @@ Runs entirely on your machine with a local browser. No LLM, nothing uploaded.
|
|
|
49
51
|
"Not seen" section included: a clean tour over part of an app is not a clean
|
|
50
52
|
app, and you must say which part was not seen. A first tour establishes the
|
|
51
53
|
baseline — never report it as a pass. Set a project up with flags only
|
|
52
|
-
(\`setup --url … --login … --yes\`),
|
|
53
|
-
Never run \`ia-qa-heal login\`: it waits for a human at a browser; ask
|
|
54
|
+
(\`setup --url … --login … --yes\`), with answers the human gave you — never
|
|
55
|
+
guessed. Never run \`ia-qa-heal login\`: it waits for a human at a browser; ask
|
|
56
|
+
them. Never apply the repairs a tour proposes without the human's review.
|
|
54
57
|
|
|
55
58
|
Usage:
|
|
56
59
|
ia-qa-pal tour First run: every page on the surface, the first
|
|
57
60
|
batch in depth, checks, baseline.
|
|
58
61
|
Next runs: re-capture, compare, check.
|
|
62
|
+
With a test suite declared: its selectors are
|
|
63
|
+
read, repairs are proposed (never applied).
|
|
59
64
|
No config yet: asks the setup questions first
|
|
60
65
|
(in a terminal), otherwise says what is missing.
|
|
61
66
|
--more explore the next batch in depth instead
|
|
67
|
+
--suite also run the testCommand from config.json once,
|
|
68
|
+
with the capture hook, to learn which pages
|
|
69
|
+
the suite never visits
|
|
70
|
+
--background start the tour detached and return at once;
|
|
71
|
+
follow it with \`ia-qa-pal status\`
|
|
72
|
+
--strict also fail on drift behind interaction (elements
|
|
73
|
+
reached only by clicking, which may depend on
|
|
74
|
+
the data the click lands on)
|
|
62
75
|
--batch <n> pages per depth batch (default 10)
|
|
63
76
|
--json the report as one JSON document on stdout
|
|
64
77
|
--session <file> a Playwright storageState to reuse
|
|
65
78
|
--config <dir> project holding .ia-qa/ (default: here)
|
|
66
79
|
|
|
80
|
+
ia-qa-pal accept <page>… A person reviewed the drift and it is intended:
|
|
81
|
+
make those pages' latest captures the reference.
|
|
82
|
+
--all every page the last tour reported drift on
|
|
83
|
+
--config <dir> project folder (default: here)
|
|
84
|
+
[FOR AI AGENTS] only on the human's decision.
|
|
85
|
+
|
|
86
|
+
ia-qa-pal status The tour running now (phase, progress) or the
|
|
87
|
+
last one (its report).
|
|
88
|
+
--json as one JSON document
|
|
89
|
+
--config <dir> project folder (default: here)
|
|
90
|
+
|
|
67
91
|
ia-qa-pal setup Write .ia-qa/config.json: the app address, how it
|
|
68
|
-
logs in,
|
|
69
|
-
following its links)
|
|
92
|
+
logs in, its pages (from sitemap.xml, else by
|
|
93
|
+
following its links), and your test suite.
|
|
94
|
+
Never overwrites a config.
|
|
70
95
|
--url <https://…> the app
|
|
71
96
|
--login none|browser|session none; by hand in a browser (then run
|
|
72
97
|
${setup_1.LOGIN_COMMAND});
|
|
73
98
|
or a storageState your suite already writes
|
|
74
99
|
--session <file> that storageState (with --login session)
|
|
100
|
+
--tests <dir>[,<dir>…] folders of your end-to-end suite
|
|
101
|
+
--test-command "<cmd>" the command that runs it (else detected)
|
|
75
102
|
--yes write without asking
|
|
76
103
|
--config <dir> project folder (default: here)
|
|
77
104
|
|
|
78
105
|
Exit codes: 0 nothing to decide · 1 something broke or needs a decision ·
|
|
79
|
-
2 could not answer (not set up, nothing mapped, refused).
|
|
106
|
+
2 could not answer (not set up, nothing mapped, refused, already running).
|
|
80
107
|
`;
|
|
81
108
|
function valueOf(args, flag) {
|
|
82
109
|
const i = args.indexOf(flag);
|
|
@@ -127,6 +154,21 @@ function printSetup(outcome, json) {
|
|
|
127
154
|
process.stderr.write(`\nNext:\n ia-qa-pal tour\n`);
|
|
128
155
|
}
|
|
129
156
|
}
|
|
157
|
+
function renderStatus(run, dir) {
|
|
158
|
+
if (!run)
|
|
159
|
+
return 'No tour has run on this project yet. Start one: ia-qa-pal tour\n';
|
|
160
|
+
if (run.status === 'running') {
|
|
161
|
+
const p = run.progress;
|
|
162
|
+
const where = p ? `${p.phase}${p.total ? ` ${p.done ?? 0}/${p.total}` : ''}${p.page ? ` · ${p.page}` : ''}` : 'starting';
|
|
163
|
+
return `⏳ A tour is running (pid ${run.pid}, since ${run.startedAt}) — ${where}\n log: ${(0, run_1.logFile)(dir)}\n`;
|
|
164
|
+
}
|
|
165
|
+
if (run.status === 'interrupted') {
|
|
166
|
+
return `⚠ The last tour stopped before finishing (pid ${run.pid}, started ${run.startedAt}, last seen ${run.updatedAt}). Nothing it did after that is reported. Run it again: ia-qa-pal tour\n`;
|
|
167
|
+
}
|
|
168
|
+
if (run.status === 'failed')
|
|
169
|
+
return `❌ The last tour failed (${run.finishedAt}): ${run.error}\n`;
|
|
170
|
+
return `Last tour finished ${run.finishedAt}.\n\n${run.report ? (0, report_1.renderReport)(run.report) : ''}`;
|
|
171
|
+
}
|
|
130
172
|
async function main() {
|
|
131
173
|
const args = process.argv.slice(2);
|
|
132
174
|
const command = args[0];
|
|
@@ -140,21 +182,45 @@ async function main() {
|
|
|
140
182
|
}
|
|
141
183
|
const json = args.includes('--json');
|
|
142
184
|
try {
|
|
185
|
+
const dir = path.resolve(valueOf(args, '--config') ?? process.cwd());
|
|
143
186
|
if (command === 'setup') {
|
|
187
|
+
const tests = valueOf(args, '--tests');
|
|
144
188
|
const options = {
|
|
145
|
-
dir
|
|
189
|
+
dir,
|
|
146
190
|
url: valueOf(args, '--url'),
|
|
147
191
|
login: loginFlag(args),
|
|
148
192
|
session: valueOf(args, '--session'),
|
|
193
|
+
tests: tests ? tests.split(',') : undefined,
|
|
194
|
+
testCommand: valueOf(args, '--test-command'),
|
|
149
195
|
yes: args.includes('--yes'),
|
|
150
196
|
};
|
|
151
|
-
const outcome = interactive() && !json
|
|
152
|
-
? await withPrompt((ask) => (0, setup_1.runSetup)({ ...options, ask }))
|
|
153
|
-
: await (0, setup_1.runSetup)(options);
|
|
197
|
+
const outcome = interactive() && !json ? await withPrompt((ask) => (0, setup_1.runSetup)({ ...options, ask })) : await (0, setup_1.runSetup)(options);
|
|
154
198
|
printSetup(outcome, json);
|
|
155
199
|
process.exitCode = outcome.written ? 0 : 2;
|
|
156
200
|
return;
|
|
157
201
|
}
|
|
202
|
+
if (command === 'accept') {
|
|
203
|
+
const pages = args.slice(1).filter((a, i, all) => !a.startsWith('--') && all[i - 1] !== '--config');
|
|
204
|
+
const outcome = await (0, accept_1.acceptPages)(dir, pages, { all: args.includes('--all') });
|
|
205
|
+
if (json)
|
|
206
|
+
process.stdout.write(`${JSON.stringify({ schema: 'ia-qa-pal/accept@1', ...outcome }, null, 2)}\n`);
|
|
207
|
+
else {
|
|
208
|
+
if (outcome.refused)
|
|
209
|
+
process.stderr.write(`❌ ${outcome.refused}\n`);
|
|
210
|
+
if (outcome.accepted.length > 0)
|
|
211
|
+
process.stderr.write(`✅ Accepted as the new reference: ${outcome.accepted.join(', ')}\n Commit .ia-qa/baseline — a reference that is not in git cannot be reviewed.\n`);
|
|
212
|
+
for (const s of outcome.skipped)
|
|
213
|
+
process.stderr.write(` skipped ${s.page} — ${s.reason}\n`);
|
|
214
|
+
}
|
|
215
|
+
process.exitCode = outcome.refused ? 2 : 0;
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
if (command === 'status') {
|
|
219
|
+
const run = (0, run_1.readRun)(dir);
|
|
220
|
+
process.stdout.write(json ? `${JSON.stringify({ schema: 'ia-qa-pal/status@1', run }, null, 2)}\n` : renderStatus(run, dir));
|
|
221
|
+
process.exitCode = run?.status === 'done' ? run.exitCode ?? 0 : run ? 0 : 2;
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
158
224
|
if (command !== 'tour') {
|
|
159
225
|
process.stderr.write(`Unknown command "${command}". Run ia-qa-pal help.\n`);
|
|
160
226
|
process.exitCode = 2;
|
|
@@ -164,10 +230,21 @@ async function main() {
|
|
|
164
230
|
const batch = batchRaw === undefined ? undefined : Number(batchRaw);
|
|
165
231
|
if (batch !== undefined && (!Number.isInteger(batch) || batch < 1))
|
|
166
232
|
throw new Error('--batch needs a positive whole number.');
|
|
167
|
-
const
|
|
168
|
-
if (
|
|
169
|
-
|
|
170
|
-
|
|
233
|
+
const tourOptions = { more: args.includes('--more'), suite: args.includes('--suite'), strict: args.includes('--strict'), batch, session: valueOf(args, '--session') };
|
|
234
|
+
if (args.includes('--background')) {
|
|
235
|
+
const started = (0, run_1.startBackground)(dir, tourOptions);
|
|
236
|
+
if (json)
|
|
237
|
+
process.stdout.write(`${JSON.stringify({ schema: 'ia-qa-pal/background@1', ...started }, null, 2)}\n`);
|
|
238
|
+
else if (started.started)
|
|
239
|
+
process.stderr.write(`⏳ Tour started in the background (pid ${started.pid}). Follow it: ia-qa-pal status\n log: ${started.log}\n`);
|
|
240
|
+
else
|
|
241
|
+
process.stderr.write(`❌ ${started.reason}\n`);
|
|
242
|
+
process.exitCode = started.started ? 0 : 2;
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
if (!(0, setup_1.configExists)(dir) && interactive() && !json) {
|
|
246
|
+
process.stderr.write('This project is not set up yet — a few questions first.\n\n');
|
|
247
|
+
const outcome = await withPrompt((ask) => (0, setup_1.runSetup)({ dir, session: tourOptions.session, ask }));
|
|
171
248
|
printSetup(outcome, false);
|
|
172
249
|
if (!outcome.written || outcome.next !== 'ia-qa-pal tour') {
|
|
173
250
|
process.exitCode = outcome.written ? 0 : 2;
|
|
@@ -175,16 +252,18 @@ async function main() {
|
|
|
175
252
|
}
|
|
176
253
|
process.stderr.write('\n');
|
|
177
254
|
}
|
|
178
|
-
const result = await (0,
|
|
255
|
+
const result = await (0, run_1.trackedTour)({ dir, ...tourOptions });
|
|
179
256
|
process.stdout.write(json ? `${JSON.stringify(result, null, 2)}\n` : (0, report_1.renderReport)(result));
|
|
180
257
|
process.exitCode = result.exitCode;
|
|
181
258
|
}
|
|
182
259
|
catch (err) {
|
|
183
260
|
const message = err instanceof Error ? err.message : String(err);
|
|
184
|
-
if (json)
|
|
185
|
-
process.stdout.write(`${JSON.stringify({ error: message, exitCode: 2 }, null, 2)}\n`);
|
|
186
|
-
|
|
261
|
+
if (json) {
|
|
262
|
+
process.stdout.write(`${JSON.stringify({ error: message, ...(err instanceof run_1.TourAlreadyRunning ? { running: err.run } : {}), exitCode: 2 }, null, 2)}\n`);
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
187
265
|
process.stderr.write(`❌ ${message}\n`);
|
|
266
|
+
}
|
|
188
267
|
process.exitCode = 2;
|
|
189
268
|
}
|
|
190
269
|
}
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,4DAA8C;AAC9C,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
export { runTour } from './tour';
|
|
2
|
-
export type { TourOptions, TourResult } from './tour';
|
|
2
|
+
export type { TourOptions, TourResult, TourEvent } from './tour';
|
|
3
|
+
export { trackedTour, startBackground, readRun, activeRun, TourAlreadyRunning } from './run';
|
|
4
|
+
export type { RunRecord, RunView, BackgroundStart } from './run';
|
|
5
|
+
export type { SuiteInventory, RepairPlan, SuiteAudit, SuiteRun } from './suite';
|
|
3
6
|
export { renderReport } from './report';
|
|
4
7
|
export { runSetup, LOGIN_COMMAND } from './setup';
|
|
5
8
|
export type { SetupOptions, SetupOutcome, PalLogin } from './setup';
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DEFAULT_BATCH = exports.exitCodeFor = exports.splitFindings = exports.estimate = exports.needingDepth = exports.selectBatch = exports.LOGIN_COMMAND = exports.runSetup = exports.renderReport = exports.runTour = void 0;
|
|
3
|
+
exports.DEFAULT_BATCH = exports.exitCodeFor = exports.splitFindings = exports.estimate = exports.needingDepth = exports.selectBatch = exports.LOGIN_COMMAND = exports.runSetup = exports.renderReport = exports.TourAlreadyRunning = exports.activeRun = exports.readRun = exports.startBackground = exports.trackedTour = exports.runTour = void 0;
|
|
4
4
|
var tour_1 = require("./tour");
|
|
5
5
|
Object.defineProperty(exports, "runTour", { enumerable: true, get: function () { return tour_1.runTour; } });
|
|
6
|
+
var run_1 = require("./run");
|
|
7
|
+
Object.defineProperty(exports, "trackedTour", { enumerable: true, get: function () { return run_1.trackedTour; } });
|
|
8
|
+
Object.defineProperty(exports, "startBackground", { enumerable: true, get: function () { return run_1.startBackground; } });
|
|
9
|
+
Object.defineProperty(exports, "readRun", { enumerable: true, get: function () { return run_1.readRun; } });
|
|
10
|
+
Object.defineProperty(exports, "activeRun", { enumerable: true, get: function () { return run_1.activeRun; } });
|
|
11
|
+
Object.defineProperty(exports, "TourAlreadyRunning", { enumerable: true, get: function () { return run_1.TourAlreadyRunning; } });
|
|
6
12
|
var report_1 = require("./report");
|
|
7
13
|
Object.defineProperty(exports, "renderReport", { enumerable: true, get: function () { return report_1.renderReport; } });
|
|
8
14
|
var setup_1 = require("./setup");
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,+BAAiC;AAAxB,+FAAA,OAAO,OAAA;AAEhB,mCAAwC;AAA/B,sGAAA,YAAY,OAAA;AACrB,iCAAkD;AAAzC,iGAAA,QAAQ,OAAA;AAAE,sGAAA,aAAa,OAAA;AAEhC,+BAAwG;AAA/F,mGAAA,WAAW,OAAA;AAAE,oGAAA,YAAY,OAAA;AAAE,gGAAA,QAAQ,OAAA;AAAE,qGAAA,aAAa,OAAA;AAAE,mGAAA,WAAW,OAAA;AAAE,qGAAA,aAAa,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,+BAAiC;AAAxB,+FAAA,OAAO,OAAA;AAEhB,6BAA6F;AAApF,kGAAA,WAAW,OAAA;AAAE,sGAAA,eAAe,OAAA;AAAE,8FAAA,OAAO,OAAA;AAAE,gGAAA,SAAS,OAAA;AAAE,yGAAA,kBAAkB,OAAA;AAG7E,mCAAwC;AAA/B,sGAAA,YAAY,OAAA;AACrB,iCAAkD;AAAzC,iGAAA,QAAQ,OAAA;AAAE,sGAAA,aAAa,OAAA;AAEhC,+BAAwG;AAA/F,mGAAA,WAAW,OAAA;AAAE,oGAAA,YAAY,OAAA;AAAE,gGAAA,QAAQ,OAAA;AAAE,qGAAA,aAAa,OAAA;AAAE,mGAAA,WAAW,OAAA;AAAE,qGAAA,aAAa,OAAA"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export declare const TOOLS: ({
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
inputSchema: {
|
|
6
|
+
type: string;
|
|
7
|
+
properties: {
|
|
8
|
+
project_dir: {
|
|
9
|
+
type: string;
|
|
10
|
+
description: string;
|
|
11
|
+
};
|
|
12
|
+
url?: undefined;
|
|
13
|
+
login?: undefined;
|
|
14
|
+
session_file?: undefined;
|
|
15
|
+
tests?: undefined;
|
|
16
|
+
more?: undefined;
|
|
17
|
+
suite?: undefined;
|
|
18
|
+
strict?: undefined;
|
|
19
|
+
batch?: undefined;
|
|
20
|
+
};
|
|
21
|
+
required?: undefined;
|
|
22
|
+
};
|
|
23
|
+
} | {
|
|
24
|
+
name: string;
|
|
25
|
+
description: string;
|
|
26
|
+
inputSchema: {
|
|
27
|
+
type: string;
|
|
28
|
+
properties: {
|
|
29
|
+
url: {
|
|
30
|
+
type: string;
|
|
31
|
+
description: string;
|
|
32
|
+
};
|
|
33
|
+
login: {
|
|
34
|
+
type: string;
|
|
35
|
+
enum: string[];
|
|
36
|
+
description: string;
|
|
37
|
+
};
|
|
38
|
+
session_file: {
|
|
39
|
+
type: string;
|
|
40
|
+
description: string;
|
|
41
|
+
};
|
|
42
|
+
tests: {
|
|
43
|
+
type: string;
|
|
44
|
+
items: {
|
|
45
|
+
type: string;
|
|
46
|
+
};
|
|
47
|
+
description: string;
|
|
48
|
+
};
|
|
49
|
+
project_dir: {
|
|
50
|
+
type: string;
|
|
51
|
+
description: string;
|
|
52
|
+
};
|
|
53
|
+
more?: undefined;
|
|
54
|
+
suite?: undefined;
|
|
55
|
+
strict?: undefined;
|
|
56
|
+
batch?: undefined;
|
|
57
|
+
};
|
|
58
|
+
required: string[];
|
|
59
|
+
};
|
|
60
|
+
} | {
|
|
61
|
+
name: string;
|
|
62
|
+
description: string;
|
|
63
|
+
inputSchema: {
|
|
64
|
+
type: string;
|
|
65
|
+
properties: {
|
|
66
|
+
more: {
|
|
67
|
+
type: string;
|
|
68
|
+
description: string;
|
|
69
|
+
};
|
|
70
|
+
suite: {
|
|
71
|
+
type: string;
|
|
72
|
+
description: string;
|
|
73
|
+
};
|
|
74
|
+
strict: {
|
|
75
|
+
type: string;
|
|
76
|
+
description: string;
|
|
77
|
+
};
|
|
78
|
+
batch: {
|
|
79
|
+
type: string;
|
|
80
|
+
description: string;
|
|
81
|
+
};
|
|
82
|
+
project_dir: {
|
|
83
|
+
type: string;
|
|
84
|
+
description: string;
|
|
85
|
+
};
|
|
86
|
+
url?: undefined;
|
|
87
|
+
login?: undefined;
|
|
88
|
+
session_file?: undefined;
|
|
89
|
+
tests?: undefined;
|
|
90
|
+
};
|
|
91
|
+
required?: undefined;
|
|
92
|
+
};
|
|
93
|
+
})[];
|
|
94
|
+
export declare function projectDir(given: unknown, root?: string): string;
|
|
95
|
+
export declare function callTool(name: string, args: Record<string, any>, root?: string): Promise<unknown>;
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.TOOLS = void 0;
|
|
38
|
+
exports.projectDir = projectDir;
|
|
39
|
+
exports.callTool = callTool;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const setup_1 = require("../setup");
|
|
43
|
+
const run_1 = require("../run");
|
|
44
|
+
const report_1 = require("../report");
|
|
45
|
+
/**
|
|
46
|
+
* @ia-qa/pal — local stdio MCP server.
|
|
47
|
+
*
|
|
48
|
+
* Dependency-free JSON-RPC 2.0 over stdio, the same shape as `@ia-qa/self-healing` and
|
|
49
|
+
* `@ia-qa/qa-discovery`. It exposes what the CLI exposes, so a person and an agent get one
|
|
50
|
+
* contract. Three restraints are load-bearing:
|
|
51
|
+
*
|
|
52
|
+
* - **A tour never blocks the call.** `pal_tour` starts it in the background and returns at
|
|
53
|
+
* once; `pal_status` reads progress and, when done, the report. A tour takes minutes, and a
|
|
54
|
+
* client that times out mid-call would leave the agent believing nothing ran.
|
|
55
|
+
* - **No tool takes a command.** The test command comes from config.json, written by a person.
|
|
56
|
+
* An agent steered by content it read cannot make this server run something else.
|
|
57
|
+
* - **No login tool.** `ia-qa-heal login` waits for a person at a browser.
|
|
58
|
+
*
|
|
59
|
+
* stdout carries the protocol only; all logs go to stderr.
|
|
60
|
+
*/
|
|
61
|
+
const PROTOCOL_VERSION = '2024-11-05';
|
|
62
|
+
const SERVER_INFO = { name: 'ia-qa-pal', version: require('../../package.json').version };
|
|
63
|
+
const CLI_ENTRY = path.join(__dirname, '..', 'cli', 'index.js');
|
|
64
|
+
const PROJECT_DIR = {
|
|
65
|
+
type: 'string',
|
|
66
|
+
description: 'Project folder holding .ia-qa/, relative to where this server runs. Default: the server’s own folder.',
|
|
67
|
+
};
|
|
68
|
+
exports.TOOLS = [
|
|
69
|
+
{
|
|
70
|
+
name: 'pal_project',
|
|
71
|
+
description: 'Where this project stands with ia-qa-pal: whether it is set up, its level (0 public pages, 1 with a login, 2 with its test suite), how many pages are configured, whether a baseline exists, and whether a tour is running. Read-only. Call it first.',
|
|
72
|
+
inputSchema: { type: 'object', properties: { project_dir: PROJECT_DIR } },
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
name: 'pal_setup',
|
|
76
|
+
description: 'Write .ia-qa/config.json for a project that has none: the app address, how it logs in, its pages (read from sitemap.xml, else by following its links — same host, GET only, at most 50 pages), and optionally the folders of its end-to-end suite. Never overwrites an existing config. Call it ONLY with answers the human gave you — ask them where the app lives and how it logs in; never guess. Login "browser" means the human must then run `' +
|
|
77
|
+
setup_1.LOGIN_COMMAND +
|
|
78
|
+
'` themselves: you cannot, it waits for a person at a browser. The command that runs the suite is detected from package.json or set by the human with the CLI — this tool never takes one.',
|
|
79
|
+
inputSchema: {
|
|
80
|
+
type: 'object',
|
|
81
|
+
properties: {
|
|
82
|
+
url: { type: 'string', description: 'The app, https://…' },
|
|
83
|
+
login: { type: 'string', enum: ['none', 'browser', 'session'], description: 'none; browser (the human logs in by hand); session (a Playwright storageState the suite already writes).' },
|
|
84
|
+
session_file: { type: 'string', description: 'With login "session": path of that storageState file, inside the project. Only its path is written.' },
|
|
85
|
+
tests: { type: 'array', items: { type: 'string' }, description: 'Folders of the end-to-end suite, relative to the project.' },
|
|
86
|
+
project_dir: PROJECT_DIR,
|
|
87
|
+
},
|
|
88
|
+
required: ['url', 'login'],
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
name: 'pal_tour',
|
|
93
|
+
description: 'Start a tour in the background and return at once — it takes minutes. First tour: every page on the surface, a batch explored in depth (menus, tabs, dialogs; every non-GET request blocked), checks, baseline. Later tours: re-capture, compare with the baseline, check; with a test suite declared, repairs to its selectors are proposed and never applied. Only one tour runs per project. Follow it with pal_status. Report the whole result to the human, including "Not seen": a first tour is a baseline, never a pass.',
|
|
94
|
+
inputSchema: {
|
|
95
|
+
type: 'object',
|
|
96
|
+
properties: {
|
|
97
|
+
more: { type: 'boolean', description: 'Explore the next batch in depth instead of a regression tour. Refused after a BLOCK.' },
|
|
98
|
+
suite: { type: 'boolean', description: 'Also run the test command from config.json once, with the capture hook, to learn which pages the suite never visits. It runs the human’s own suite on this machine — ask before setting it.' },
|
|
99
|
+
strict: { type: 'boolean', description: 'Also fail on drift behind interaction — elements reached only by clicking, which may depend on the data the click lands on.' },
|
|
100
|
+
batch: { type: 'integer', description: 'Pages per depth batch (default 10).' },
|
|
101
|
+
project_dir: PROJECT_DIR,
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
name: 'pal_status',
|
|
107
|
+
description: 'The tour running now — phase and progress — or the last one: its full report once done, as JSON and as the text a human reads. A tour whose process died before finishing is reported as interrupted, never as running. Read-only. When the report lists drift a human judges intended, the human accepts it with `ia-qa-pal accept <page>` — there is no tool for that on purpose.',
|
|
108
|
+
inputSchema: { type: 'object', properties: { project_dir: PROJECT_DIR } },
|
|
109
|
+
},
|
|
110
|
+
];
|
|
111
|
+
function projectDir(given, root = process.cwd()) {
|
|
112
|
+
const candidate = typeof given === 'string' && given.trim() ? given.trim() : '.';
|
|
113
|
+
const resolved = path.resolve(root, candidate);
|
|
114
|
+
const rootWithSep = root.endsWith(path.sep) ? root : root + path.sep;
|
|
115
|
+
if (resolved !== root && !resolved.startsWith(rootWithSep)) {
|
|
116
|
+
throw new Error(`project_dir "${candidate}" resolves outside "${root}". Refusing: an MCP call may be steered by content the agent read.`);
|
|
117
|
+
}
|
|
118
|
+
return resolved;
|
|
119
|
+
}
|
|
120
|
+
function readJson(file) {
|
|
121
|
+
try {
|
|
122
|
+
return JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
async function callTool(name, args, root = process.cwd()) {
|
|
129
|
+
const dir = projectDir(args.project_dir, root);
|
|
130
|
+
const config = readJson(path.join(dir, '.ia-qa', 'config.json'));
|
|
131
|
+
if (name === 'pal_project') {
|
|
132
|
+
const baseline = path.join(dir, '.ia-qa', 'baseline');
|
|
133
|
+
const run = (0, run_1.readRun)(dir);
|
|
134
|
+
return {
|
|
135
|
+
setUp: !!config,
|
|
136
|
+
...(config
|
|
137
|
+
? {
|
|
138
|
+
baseUrl: config.baseUrl,
|
|
139
|
+
pages: (config.pages ?? []).length,
|
|
140
|
+
level: (config.testPaths ?? []).length > 0 ? 2 : config.session || config.auth || fs.existsSync(path.join(dir, '.ia-qa', 'session.json')) ? 1 : 0,
|
|
141
|
+
testPaths: config.testPaths ?? [],
|
|
142
|
+
testCommand: config.testCommand ?? null,
|
|
143
|
+
baseline: fs.existsSync(baseline) && fs.readdirSync(baseline).some((f) => f.endsWith('.json')),
|
|
144
|
+
}
|
|
145
|
+
: { next: 'Ask the human where the app lives and how it logs in, then call pal_setup with their answers.' }),
|
|
146
|
+
tour: run ? { status: run.status, startedAt: run.startedAt, finishedAt: run.finishedAt ?? null } : null,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
if (name === 'pal_setup') {
|
|
150
|
+
const login = args.login;
|
|
151
|
+
if (!['none', 'browser', 'session'].includes(login))
|
|
152
|
+
throw new Error('login must be none, browser or session.');
|
|
153
|
+
const session = typeof args.session_file === 'string' && args.session_file ? path.relative(dir, projectDir(args.session_file, dir)) : undefined;
|
|
154
|
+
const tests = Array.isArray(args.tests) ? args.tests.map(String) : undefined;
|
|
155
|
+
const lines = [];
|
|
156
|
+
const outcome = await (0, setup_1.runSetup)({ dir, url: String(args.url ?? ''), login, session, tests, yes: true, onProgress: (l) => lines.push(l) });
|
|
157
|
+
return { ...outcome, progress: lines };
|
|
158
|
+
}
|
|
159
|
+
if (name === 'pal_tour') {
|
|
160
|
+
const batch = Number.isInteger(args.batch) && args.batch > 0 ? args.batch : undefined;
|
|
161
|
+
const started = (0, run_1.startBackground)(dir, { more: !!args.more, suite: !!args.suite, strict: !!args.strict, batch }, CLI_ENTRY);
|
|
162
|
+
return started.started
|
|
163
|
+
? { ...started, next: 'Call pal_status to follow it. A tour takes minutes.' }
|
|
164
|
+
: { ...started, ...(!config ? { next: 'Not set up: ask the human where the app lives and how it logs in, then call pal_setup.' } : {}) };
|
|
165
|
+
}
|
|
166
|
+
if (name === 'pal_status') {
|
|
167
|
+
const run = (0, run_1.readRun)(dir);
|
|
168
|
+
if (!run)
|
|
169
|
+
return { run: null, text: 'No tour has run on this project yet. Call pal_tour.' };
|
|
170
|
+
const text = run.status === 'done' && run.report ? (0, report_1.renderReport)(run.report) : undefined;
|
|
171
|
+
return { run, log: (0, run_1.logFile)(dir), ...(text ? { text } : {}) };
|
|
172
|
+
}
|
|
173
|
+
throw new Error(`Unknown tool "${name}". Call tools/list to see available tools.`);
|
|
174
|
+
}
|
|
175
|
+
function send(message) {
|
|
176
|
+
process.stdout.write(JSON.stringify(message) + '\n');
|
|
177
|
+
}
|
|
178
|
+
async function handle(req) {
|
|
179
|
+
const { id, method, params } = req;
|
|
180
|
+
const isNotification = id === undefined || id === null;
|
|
181
|
+
try {
|
|
182
|
+
if (method === 'initialize') {
|
|
183
|
+
send({ jsonrpc: '2.0', id, result: { protocolVersion: params?.protocolVersion || PROTOCOL_VERSION, capabilities: { tools: {} }, serverInfo: SERVER_INFO } });
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
if (method === 'notifications/initialized' || method === 'initialized')
|
|
187
|
+
return;
|
|
188
|
+
if (method === 'ping') {
|
|
189
|
+
send({ jsonrpc: '2.0', id, result: {} });
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
if (method === 'tools/list') {
|
|
193
|
+
send({ jsonrpc: '2.0', id, result: { tools: exports.TOOLS } });
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
if (method === 'tools/call') {
|
|
197
|
+
try {
|
|
198
|
+
const result = await callTool(params?.name, params?.arguments || {});
|
|
199
|
+
send({ jsonrpc: '2.0', id, result: { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] } });
|
|
200
|
+
}
|
|
201
|
+
catch (err) {
|
|
202
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
203
|
+
send({ jsonrpc: '2.0', id, result: { content: [{ type: 'text', text: `Error: ${message}` }], isError: true } });
|
|
204
|
+
}
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
if (!isNotification)
|
|
208
|
+
send({ jsonrpc: '2.0', id, error: { code: -32601, message: `Method not found: ${method}` } });
|
|
209
|
+
}
|
|
210
|
+
catch (err) {
|
|
211
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
212
|
+
if (!isNotification)
|
|
213
|
+
send({ jsonrpc: '2.0', id, error: { code: -32603, message } });
|
|
214
|
+
else
|
|
215
|
+
process.stderr.write(`[ia-qa-pal] error handling ${method}: ${message}\n`);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
function main() {
|
|
219
|
+
if (process.argv.includes('--version') || process.argv.includes('-v')) {
|
|
220
|
+
process.stdout.write(SERVER_INFO.version + '\n');
|
|
221
|
+
process.exit(0);
|
|
222
|
+
}
|
|
223
|
+
// The setup verbs print; stdout is the protocol.
|
|
224
|
+
console.log = console.info = console.warn = (...a) => console.error(...a);
|
|
225
|
+
process.stderr.write('[ia-qa-pal] MCP server ready (stdio)\n');
|
|
226
|
+
let buffer = '';
|
|
227
|
+
process.stdin.setEncoding('utf8');
|
|
228
|
+
process.stdin.on('data', (chunk) => {
|
|
229
|
+
buffer += chunk;
|
|
230
|
+
let nl;
|
|
231
|
+
while ((nl = buffer.indexOf('\n')) !== -1) {
|
|
232
|
+
const line = buffer.slice(0, nl).trim();
|
|
233
|
+
buffer = buffer.slice(nl + 1);
|
|
234
|
+
if (!line)
|
|
235
|
+
continue;
|
|
236
|
+
let req;
|
|
237
|
+
try {
|
|
238
|
+
req = JSON.parse(line);
|
|
239
|
+
}
|
|
240
|
+
catch {
|
|
241
|
+
process.stderr.write(`[ia-qa-pal] non-JSON line ignored: ${line.slice(0, 80)}\n`);
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
void handle(req);
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
process.stdin.on('end', () => process.exit(0));
|
|
248
|
+
}
|
|
249
|
+
if (require.main === module)
|
|
250
|
+
main();
|
|
251
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
|