@ia-qa/pal 1.4.0 → 1.7.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 +31 -1
- package/TUTORIAL.md +26 -2
- package/dist/cli/index.js +38 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/history.d.ts +2 -0
- package/dist/history.js +1 -0
- package/dist/history.js.map +1 -1
- package/dist/mcp/server.d.ts +6 -0
- package/dist/mcp/server.js +33 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/project.d.ts +11 -0
- package/dist/project.js +2 -0
- package/dist/project.js.map +1 -1
- package/dist/report.js +17 -0
- package/dist/report.js.map +1 -1
- package/dist/run.d.ts +2 -0
- package/dist/run.js +7 -0
- package/dist/run.js.map +1 -1
- package/dist/session.d.ts +5 -0
- package/dist/session.js +3 -3
- package/dist/session.js.map +1 -1
- package/dist/tour.d.ts +37 -0
- package/dist/tour.js +73 -2
- package/dist/tour.js.map +1 -1
- package/dist/ui/page.d.ts +15 -0
- package/dist/ui/page.js +362 -0
- package/dist/ui/page.js.map +1 -0
- package/dist/ui/server.d.ts +100 -0
- package/dist/ui/server.js +362 -0
- package/dist/ui/server.js.map +1 -0
- package/package.json +2 -2
- package/skills/ia-qa-pal/SKILL.md +11 -0
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.SECRET_NAME = void 0;
|
|
37
|
+
exports.consoleState = consoleState;
|
|
38
|
+
exports.consoleSecrets = consoleSecrets;
|
|
39
|
+
exports.checkSecrets = checkSecrets;
|
|
40
|
+
exports.setSecret = setSecret;
|
|
41
|
+
exports.startPalUi = startPalUi;
|
|
42
|
+
const fs = __importStar(require("fs"));
|
|
43
|
+
const path = __importStar(require("path"));
|
|
44
|
+
const self_healing_1 = require("@ia-qa/self-healing");
|
|
45
|
+
const project_1 = require("../project");
|
|
46
|
+
const run_1 = require("../run");
|
|
47
|
+
const history_1 = require("../history");
|
|
48
|
+
const htmlReport_1 = require("../htmlReport");
|
|
49
|
+
const page_1 = require("./page");
|
|
50
|
+
/** Names a request may send when it asks for a tour. Anything else is ignored, never passed on. */
|
|
51
|
+
const TOUR_FLAGS = ['suite', 'suiteOnly', 'strict', 'more', 'allContracts'];
|
|
52
|
+
function inProject(dir, fn) {
|
|
53
|
+
(0, self_healing_1.setBaseDir)(dir);
|
|
54
|
+
try {
|
|
55
|
+
return fn();
|
|
56
|
+
}
|
|
57
|
+
finally {
|
|
58
|
+
(0, self_healing_1.setBaseDir)(null);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async function inProjectAsync(dir, fn) {
|
|
62
|
+
(0, self_healing_1.setBaseDir)(dir);
|
|
63
|
+
try {
|
|
64
|
+
return await fn();
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
(0, self_healing_1.setBaseDir)(null);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async function jsonBody(req) {
|
|
71
|
+
const raw = await (0, self_healing_1.readBody)(req, 16 * 1024);
|
|
72
|
+
if (!raw.trim())
|
|
73
|
+
return {};
|
|
74
|
+
const parsed = JSON.parse(raw);
|
|
75
|
+
return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : {};
|
|
76
|
+
}
|
|
77
|
+
function personaFrom(body) {
|
|
78
|
+
const raw = typeof body.persona === 'string' ? body.persona.trim() : '';
|
|
79
|
+
if (!raw)
|
|
80
|
+
return undefined;
|
|
81
|
+
if (!(0, self_healing_1.validPersonaName)(raw))
|
|
82
|
+
throw new RangeError(`"${raw}" is not a persona name: letters, digits, dot, dash or underscore.`);
|
|
83
|
+
return raw;
|
|
84
|
+
}
|
|
85
|
+
/** What the page polls. Never the report itself — it can be large, and the page asks for it once. */
|
|
86
|
+
function consoleState(dir, job) {
|
|
87
|
+
const run = (0, run_1.readRun)(dir);
|
|
88
|
+
const report = run?.report;
|
|
89
|
+
const { report: _drop, ...runWithoutReport } = (run ?? {});
|
|
90
|
+
return {
|
|
91
|
+
project: (0, project_1.projectState)(dir),
|
|
92
|
+
run: run ? runWithoutReport : null,
|
|
93
|
+
summary: report
|
|
94
|
+
? {
|
|
95
|
+
mood: (0, history_1.moodOf)(report),
|
|
96
|
+
mode: report.mode,
|
|
97
|
+
exitCode: report.exitCode,
|
|
98
|
+
persona: report.persona ?? null,
|
|
99
|
+
refused: report.refused ?? null,
|
|
100
|
+
verdict: report.drift?.verdict ?? null,
|
|
101
|
+
totals: report.drift?.totals ?? null,
|
|
102
|
+
underContract: report.pages.underContract,
|
|
103
|
+
configured: report.pages.configured,
|
|
104
|
+
notMapped: report.pages.notMapped.length,
|
|
105
|
+
durationMs: report.durationMs,
|
|
106
|
+
}
|
|
107
|
+
: null,
|
|
108
|
+
history: (0, history_1.readHistory)(dir).slice(-20),
|
|
109
|
+
login: job ? { persona: job.persona, status: job.status, message: job.message ?? null, startedAt: job.startedAt } : null,
|
|
110
|
+
now: new Date().toISOString(),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Secrets, by name, with where each one lives — and nothing that could carry a value.
|
|
115
|
+
*
|
|
116
|
+
* The config's references (`secrets` in `.ia-qa/config.json`) plus the names in this machine's
|
|
117
|
+
* credential store. Both are names already: this function has nothing to leak even by mistake.
|
|
118
|
+
*/
|
|
119
|
+
function consoleSecrets(dir) {
|
|
120
|
+
const refs = inProject(dir, () => {
|
|
121
|
+
try {
|
|
122
|
+
return (0, self_healing_1.loadConfig)().secrets ?? {};
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
return {};
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
return {
|
|
129
|
+
references: Object.entries(refs).map(([name, ref]) => ({
|
|
130
|
+
name,
|
|
131
|
+
source: ref.source ?? 'unknown',
|
|
132
|
+
key: ref.key ?? '',
|
|
133
|
+
})),
|
|
134
|
+
stored: (0, self_healing_1.listSecrets)(),
|
|
135
|
+
store: (0, self_healing_1.storeDescription)(),
|
|
136
|
+
set: 'ia-qa-heal secret set <NAME>',
|
|
137
|
+
canStore: (0, self_healing_1.storeKind)() !== 'unsupported',
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Does each referenced secret resolve? Yes, no, or deliberately not checked — never the value.
|
|
142
|
+
*
|
|
143
|
+
* `env` is presence in this console's own environment, which is the one a tour it starts
|
|
144
|
+
* inherits. `keychain` is a lookup in this machine's store, answered as a boolean. `aws-ssm`
|
|
145
|
+
* is **not checked**: resolving it is a call to AWS, and this package announces and asks for
|
|
146
|
+
* anything that leaves the machine instead of doing it because a page loaded.
|
|
147
|
+
*/
|
|
148
|
+
function checkSecrets(dir) {
|
|
149
|
+
const { references } = consoleSecrets(dir);
|
|
150
|
+
const stored = new Set((0, self_healing_1.listSecrets)());
|
|
151
|
+
return references.map((r) => {
|
|
152
|
+
if (r.source === 'env') {
|
|
153
|
+
if (typeof process.env[r.key] === 'string' && process.env[r.key] !== '')
|
|
154
|
+
return { name: r.name, source: r.source, resolves: true, from: 'environment' };
|
|
155
|
+
// The same fallback `resolveSecret` makes: unset in the shell, stored on this machine.
|
|
156
|
+
return stored.has(r.key) ? { name: r.name, source: r.source, resolves: true, from: 'store' } : { name: r.name, source: r.source, resolves: false };
|
|
157
|
+
}
|
|
158
|
+
if (r.source === 'keychain')
|
|
159
|
+
return { name: r.name, source: r.source, resolves: stored.has(r.key) };
|
|
160
|
+
return { name: r.name, source: r.source, resolves: null, why: 'not checked from here: resolving it would call AWS' };
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
/** A name a store entry may carry: the shape of an environment variable, so one name serves both. */
|
|
164
|
+
exports.SECRET_NAME = /^[A-Za-z_][A-Za-z0-9_]{0,127}$/;
|
|
165
|
+
const MAX_SECRET = 8 * 1024;
|
|
166
|
+
/**
|
|
167
|
+
* Store one value in this machine's credential store — and answer without it.
|
|
168
|
+
*
|
|
169
|
+
* Every answer is built from the NAME and a fixed reason; the value is never interpolated into
|
|
170
|
+
* one, never returned, never measured back. The write is read back before "stored" is said,
|
|
171
|
+
* the same rule `ia-qa-heal secret set` follows: a store that accepted and returns something
|
|
172
|
+
* else is a failure, not a success.
|
|
173
|
+
*/
|
|
174
|
+
function setSecret(body, store) {
|
|
175
|
+
const name = typeof body.name === 'string' ? body.name.trim() : '';
|
|
176
|
+
const value = typeof body.value === 'string' ? body.value.trim() : '';
|
|
177
|
+
if (!name || (0, self_healing_1.looksLikeSecret)(name)) {
|
|
178
|
+
// A pasted key in the name field must not be echoed back as "not a valid name: sk-…".
|
|
179
|
+
return { status: 400, body: { stored: false, reason: name ? 'The name field holds what looks like the credential itself. Put the variable NAME there (e.g. OPENAI_API_KEY).' : 'Name the secret.' } };
|
|
180
|
+
}
|
|
181
|
+
if (!exports.SECRET_NAME.test(name)) {
|
|
182
|
+
return { status: 400, body: { stored: false, reason: `"${name}" is not a secret name: letters, digits and underscore, not starting with a digit.` } };
|
|
183
|
+
}
|
|
184
|
+
if (!value)
|
|
185
|
+
return { status: 400, body: { stored: false, reason: 'Nothing to store: the value is empty.' } };
|
|
186
|
+
if (value.length > MAX_SECRET)
|
|
187
|
+
return { status: 400, body: { stored: false, reason: 'That value is too long to be a credential.' } };
|
|
188
|
+
if (store.kind() === 'unsupported') {
|
|
189
|
+
return { status: 409, body: { stored: false, reason: 'This machine has no credential store. Export the variable in the shell that starts the console instead.' } };
|
|
190
|
+
}
|
|
191
|
+
const written = store.write(name, value);
|
|
192
|
+
if (!written.ok)
|
|
193
|
+
return { status: 500, body: { stored: false, name, reason: `The credential store refused it: ${written.reason}` } };
|
|
194
|
+
const back = store.read(name);
|
|
195
|
+
if (!back.ok || back.value !== value) {
|
|
196
|
+
return { status: 500, body: { stored: false, name, reason: 'Written, but it did not read back identical — treat it as not stored.' } };
|
|
197
|
+
}
|
|
198
|
+
return { status: 200, body: { stored: true, name } };
|
|
199
|
+
}
|
|
200
|
+
async function startPalUi(opts) {
|
|
201
|
+
const dir = path.resolve(opts.dir);
|
|
202
|
+
const login = opts.login ?? self_healing_1.performLogin;
|
|
203
|
+
const probe = opts.probe ?? self_healing_1.probeSession;
|
|
204
|
+
const store = opts.store ?? { write: self_healing_1.writeSecret, read: self_healing_1.readSecret, kind: self_healing_1.storeKind };
|
|
205
|
+
let job = null;
|
|
206
|
+
return (0, self_healing_1.startSecureServer)({
|
|
207
|
+
port: opts.port,
|
|
208
|
+
keepAlive: opts.keepAlive,
|
|
209
|
+
route: async (req, res, url, token) => {
|
|
210
|
+
const get = req.method === 'GET';
|
|
211
|
+
const post = req.method === 'POST';
|
|
212
|
+
if (get && url.pathname === '/') {
|
|
213
|
+
(0, self_healing_1.send)(res, 200, 'text/html; charset=utf-8', (0, page_1.renderConsolePage)(token));
|
|
214
|
+
return true;
|
|
215
|
+
}
|
|
216
|
+
if (get && url.pathname === '/api/state') {
|
|
217
|
+
(0, self_healing_1.sendJson)(res, 200, consoleState(dir, job));
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
220
|
+
if (get && url.pathname === '/report') {
|
|
221
|
+
const run = (0, run_1.readRun)(dir);
|
|
222
|
+
if (!run?.report) {
|
|
223
|
+
(0, self_healing_1.send)(res, 404, 'text/plain; charset=utf-8', 'No finished tour to show yet.');
|
|
224
|
+
return true;
|
|
225
|
+
}
|
|
226
|
+
(0, self_healing_1.send)(res, 200, 'text/html; charset=utf-8', (0, htmlReport_1.renderHtmlReport)(run.report, (0, history_1.readHistory)(dir), { generatedAt: run.finishedAt }));
|
|
227
|
+
return true;
|
|
228
|
+
}
|
|
229
|
+
if (post && url.pathname === '/api/tour') {
|
|
230
|
+
const body = await jsonBody(req);
|
|
231
|
+
let persona;
|
|
232
|
+
try {
|
|
233
|
+
persona = personaFrom(body);
|
|
234
|
+
}
|
|
235
|
+
catch (err) {
|
|
236
|
+
(0, self_healing_1.sendJson)(res, 400, { started: false, reason: err.message });
|
|
237
|
+
return true;
|
|
238
|
+
}
|
|
239
|
+
if (!fs.existsSync(path.join(dir, '.ia-qa', 'config.json'))) {
|
|
240
|
+
(0, self_healing_1.sendJson)(res, 409, { started: false, reason: 'This project is not set up yet — there is no .ia-qa/config.json.' });
|
|
241
|
+
return true;
|
|
242
|
+
}
|
|
243
|
+
// Who — decided now, while the person who clicked is still looking at the page.
|
|
244
|
+
const who = inProject(dir, () => (0, self_healing_1.resolveRunSession)((0, self_healing_1.loadConfig)(), { persona, verb: 'the console' }));
|
|
245
|
+
if (who.kind === 'refused') {
|
|
246
|
+
(0, self_healing_1.sendJson)(res, 409, {
|
|
247
|
+
started: false,
|
|
248
|
+
reason: who.lines.join('\n'),
|
|
249
|
+
personas: inProject(dir, () => (0, self_healing_1.listPersonas)((0, self_healing_1.loadConfig)()).map((p) => p.name)),
|
|
250
|
+
ask: 'persona',
|
|
251
|
+
});
|
|
252
|
+
return true;
|
|
253
|
+
}
|
|
254
|
+
const flags = Object.fromEntries(TOUR_FLAGS.map((f) => [f, body[f] === true]));
|
|
255
|
+
const started = (0, run_1.startBackground)(dir, { more: flags.more, suite: flags.suite || flags.suiteOnly, suiteOnly: flags.suiteOnly, strict: flags.strict, allContracts: flags.allContracts, persona }, opts.cliEntry);
|
|
256
|
+
(0, self_healing_1.sendJson)(res, started.started ? 202 : 409, started);
|
|
257
|
+
return true;
|
|
258
|
+
}
|
|
259
|
+
if (post && url.pathname === '/api/persona/check') {
|
|
260
|
+
const body = await jsonBody(req);
|
|
261
|
+
let persona;
|
|
262
|
+
try {
|
|
263
|
+
persona = personaFrom(body);
|
|
264
|
+
}
|
|
265
|
+
catch (err) {
|
|
266
|
+
(0, self_healing_1.sendJson)(res, 400, { reason: err.message });
|
|
267
|
+
return true;
|
|
268
|
+
}
|
|
269
|
+
const probed = await inProjectAsync(dir, () => probe(persona ? { persona } : {}));
|
|
270
|
+
// The probe never carries a session's contents — facts about the file and a verdict.
|
|
271
|
+
(0, self_healing_1.sendJson)(res, 200, {
|
|
272
|
+
persona: persona ?? null,
|
|
273
|
+
present: probed.present,
|
|
274
|
+
holds: probed.verdict?.holds ?? false,
|
|
275
|
+
cause: probed.verdict?.cause ?? (probed.unknownPersona ? 'unknown-persona' : probed.present ? 'unknown' : 'none'),
|
|
276
|
+
headline: probed.verdict?.headline ?? (probed.unknownPersona ? `No persona named "${persona}".` : 'No session to check.'),
|
|
277
|
+
remedy: probed.verdict?.remedy ?? [],
|
|
278
|
+
});
|
|
279
|
+
return true;
|
|
280
|
+
}
|
|
281
|
+
if (post && url.pathname === '/api/persona/login') {
|
|
282
|
+
const body = await jsonBody(req);
|
|
283
|
+
let persona;
|
|
284
|
+
try {
|
|
285
|
+
persona = personaFrom(body);
|
|
286
|
+
}
|
|
287
|
+
catch (err) {
|
|
288
|
+
(0, self_healing_1.sendJson)(res, 400, { reason: err.message });
|
|
289
|
+
return true;
|
|
290
|
+
}
|
|
291
|
+
if (!persona) {
|
|
292
|
+
(0, self_healing_1.sendJson)(res, 400, { reason: 'Name the user this session is for — a persona is a named session.' });
|
|
293
|
+
return true;
|
|
294
|
+
}
|
|
295
|
+
if (job?.status === 'waiting') {
|
|
296
|
+
(0, self_healing_1.sendJson)(res, 409, { reason: `A login for "${job.persona}" is already open. Finish it first.` });
|
|
297
|
+
return true;
|
|
298
|
+
}
|
|
299
|
+
if ((0, run_1.activeRun)(dir)) {
|
|
300
|
+
(0, self_healing_1.sendJson)(res, 409, { reason: 'A tour is running. Logging in now would change the session under it.' });
|
|
301
|
+
return true;
|
|
302
|
+
}
|
|
303
|
+
const config = inProject(dir, () => (0, self_healing_1.loadConfig)());
|
|
304
|
+
const target = new URL(config.pages[0]?.url || '/', config.baseUrl).toString();
|
|
305
|
+
const file = inProject(dir, () => (0, self_healing_1.personaFile)(persona, config));
|
|
306
|
+
let confirm = () => { };
|
|
307
|
+
const confirmed = new Promise((resolve) => {
|
|
308
|
+
confirm = resolve;
|
|
309
|
+
});
|
|
310
|
+
const current = { persona, status: 'waiting', startedAt: new Date().toISOString(), confirm };
|
|
311
|
+
job = current;
|
|
312
|
+
// Fired, not awaited: the watch lasts as long as the person takes. The page polls
|
|
313
|
+
// `/api/state` and sees the job move — and a visible browser opening from a click in
|
|
314
|
+
// a token-authenticated page on loopback is the most direct proof there is that a
|
|
315
|
+
// person is sitting there, which is the one condition this verb has always required.
|
|
316
|
+
void inProjectAsync(dir, () => login({
|
|
317
|
+
verb: `the console (as ${persona})`,
|
|
318
|
+
target,
|
|
319
|
+
file,
|
|
320
|
+
gitignore: '.ia-qa/.gitignore',
|
|
321
|
+
writeGitignore: () => (0, self_healing_1.writeSessionGitignore)(dir),
|
|
322
|
+
contextOptions: config.locale ? { locale: config.locale } : {},
|
|
323
|
+
confirmed,
|
|
324
|
+
}))
|
|
325
|
+
.then((result) => {
|
|
326
|
+
current.status = result.ok ? 'done' : 'failed';
|
|
327
|
+
current.message = result.ok
|
|
328
|
+
? `Session for ${persona} saved and checked.`
|
|
329
|
+
: `No working session for ${persona} — the terminal that started this console has the details.`;
|
|
330
|
+
})
|
|
331
|
+
.catch((err) => {
|
|
332
|
+
current.status = 'failed';
|
|
333
|
+
current.message = err instanceof Error ? err.message : String(err);
|
|
334
|
+
});
|
|
335
|
+
(0, self_healing_1.sendJson)(res, 202, { persona, status: 'waiting' });
|
|
336
|
+
return true;
|
|
337
|
+
}
|
|
338
|
+
if (post && url.pathname === '/api/persona/login/done') {
|
|
339
|
+
// The console's Enter: "look now". Harmless when nothing is waiting.
|
|
340
|
+
if (job?.status === 'waiting')
|
|
341
|
+
job.confirm();
|
|
342
|
+
(0, self_healing_1.sendJson)(res, 200, { ok: true });
|
|
343
|
+
return true;
|
|
344
|
+
}
|
|
345
|
+
if (get && url.pathname === '/api/secrets') {
|
|
346
|
+
(0, self_healing_1.sendJson)(res, 200, consoleSecrets(dir));
|
|
347
|
+
return true;
|
|
348
|
+
}
|
|
349
|
+
if (post && url.pathname === '/api/secrets/set') {
|
|
350
|
+
const answer = setSecret(await jsonBody(req), store);
|
|
351
|
+
(0, self_healing_1.sendJson)(res, answer.status, answer.body);
|
|
352
|
+
return true;
|
|
353
|
+
}
|
|
354
|
+
if (post && url.pathname === '/api/secrets/check') {
|
|
355
|
+
(0, self_healing_1.sendJson)(res, 200, { checks: checkSecrets(dir) });
|
|
356
|
+
return true;
|
|
357
|
+
}
|
|
358
|
+
return false;
|
|
359
|
+
},
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/ui/server.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ia-qa/pal",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "A QA pal next to your team: one command walks your web app, maps it, checks it and diffs it against yesterday, then reports what broke, what needs a decision and what it could not see. Local, deterministic, no LLM.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"qa",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"node": ">=18.0.0"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@ia-qa/self-healing": "^1.
|
|
46
|
+
"@ia-qa/self-healing": "^1.29.0"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"playwright": ">=1.40.0"
|
|
@@ -121,6 +121,17 @@ Exit codes: `0` answered · `1` something failed · `2` **could not answer**. Re
|
|
|
121
121
|
`ia-qa-heal run` captures the contract during their own test run, `ia-qa-heal baseline`
|
|
122
122
|
makes it the reference, and `run` gates from then on. That is heal's loop, not a tour —
|
|
123
123
|
pal opens the pages itself, which is the step that cannot work here.
|
|
124
|
+
9. **Never choose which user a tour runs as.** An admin and a guest see different apps.
|
|
125
|
+
`pal_project` lists the personas; when there are several, `pal_tour` without `persona` is
|
|
126
|
+
refused and returns their names — that is your cue to **ask the human**, never to pick
|
|
127
|
+
the first one, the one called `default`, or the one you guess they meant. A single persona
|
|
128
|
+
is used by itself; that case needs no question. Say which user in every result you report.
|
|
129
|
+
10. **Never run `ia-qa-pal ui`.** It is a console for a person: it opens their browser and
|
|
130
|
+
waits until they close the tab, so in your shell it is a hung command. Tell them it exists
|
|
131
|
+
when they would rather click than type — to follow a long tour, to log a user in, or to see
|
|
132
|
+
which secrets resolve or to **store one** (the value goes into their OS credential store,
|
|
133
|
+
never into the config) — and give them the command. Never ask them to type a secret to you
|
|
134
|
+
instead; if they paste one, tell them to rotate it.
|
|
124
135
|
|
|
125
136
|
## 6. What leaves the machine
|
|
126
137
|
|