@ia-qa/self-healing 1.6.7 → 1.6.8
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 +94 -0
- package/TUTORIAL.md +112 -2
- package/assets/logoKawaiiGreenTiny.png +0 -0
- package/dist/cli/args.js +4 -2
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/diff.d.ts +6 -1
- package/dist/cli/diff.js +114 -4
- package/dist/cli/diff.js.map +1 -1
- package/dist/cli/emit.d.ts +71 -0
- package/dist/cli/emit.js +150 -0
- package/dist/cli/emit.js.map +1 -0
- package/dist/cli/fix.js +36 -0
- package/dist/cli/fix.js.map +1 -1
- package/dist/cli/history.d.ts +12 -0
- package/dist/cli/history.js +95 -0
- package/dist/cli/history.js.map +1 -0
- package/dist/cli/index.js +53 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init.js +32 -0
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/map.js +60 -0
- package/dist/cli/map.js.map +1 -1
- package/dist/cli/run.js +77 -7
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/ui.d.ts +16 -0
- package/dist/cli/ui.js +275 -0
- package/dist/cli/ui.js.map +1 -0
- package/dist/evidence.d.ts +130 -0
- package/dist/evidence.js +232 -0
- package/dist/evidence.js.map +1 -0
- package/dist/history.d.ts +145 -0
- package/dist/history.js +230 -0
- package/dist/history.js.map +1 -0
- package/dist/htmlReport.d.ts +47 -0
- package/dist/htmlReport.js +76 -1
- package/dist/htmlReport.js.map +1 -1
- package/dist/junit.d.ts +53 -0
- package/dist/junit.js +150 -0
- package/dist/junit.js.map +1 -0
- package/dist/mcp/server.js +41 -0
- package/dist/mcp/server.js.map +1 -1
- package/dist/ui/icon.d.ts +41 -0
- package/dist/ui/icon.js +115 -0
- package/dist/ui/icon.js.map +1 -0
- package/dist/ui/lock.d.ts +40 -0
- package/dist/ui/lock.js +138 -0
- package/dist/ui/lock.js.map +1 -0
- package/dist/ui/page.d.ts +1 -0
- package/dist/ui/page.js +584 -0
- package/dist/ui/page.js.map +1 -0
- package/dist/ui/registry.d.ts +62 -0
- package/dist/ui/registry.js +139 -0
- package/dist/ui/registry.js.map +1 -0
- package/dist/ui/server.d.ts +67 -0
- package/dist/ui/server.js +604 -0
- package/dist/ui/server.js.map +1 -0
- package/dist/ui/shortcut.d.ts +90 -0
- package/dist/ui/shortcut.js +176 -0
- package/dist/ui/shortcut.js.map +1 -0
- package/package.json +2 -1
- package/skills/ia-qa-heal/SKILL.md +27 -0
package/dist/ui/lock.js
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
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.UI_LOCK_FILENAME = void 0;
|
|
37
|
+
exports.lockPath = lockPath;
|
|
38
|
+
exports.writeLock = writeLock;
|
|
39
|
+
exports.clearLock = clearLock;
|
|
40
|
+
exports.readLock = readLock;
|
|
41
|
+
exports.probe = probe;
|
|
42
|
+
exports.findRunningConsole = findRunningConsole;
|
|
43
|
+
const fs = __importStar(require("fs"));
|
|
44
|
+
const http = __importStar(require("http"));
|
|
45
|
+
const path = __importStar(require("path"));
|
|
46
|
+
const config_1 = require("../config");
|
|
47
|
+
/**
|
|
48
|
+
* Who is already serving this project's console — `.ia-qa/ui.lock`.
|
|
49
|
+
*
|
|
50
|
+
* The console is opened by clicking something, and people click twice. Without
|
|
51
|
+
* this, the second click either fails on a port collision or starts a *second*
|
|
52
|
+
* server with a *different* token, leaving an orphan process and a browser tab
|
|
53
|
+
* that will 401 the moment the first one is closed. Neither is explicable to
|
|
54
|
+
* the person who clicked.
|
|
55
|
+
*
|
|
56
|
+
* So the lock holds the port and the token, and a launcher that finds a live
|
|
57
|
+
* console simply opens it. The file is a hint, never an authority: it is
|
|
58
|
+
* verified by an actual request before being believed (a lock left behind by a
|
|
59
|
+
* killed process is the normal case, not the exception), and it lives next to
|
|
60
|
+
* the contracts because that is what it is scoped to — one console per project
|
|
61
|
+
* directory, not one per machine.
|
|
62
|
+
*
|
|
63
|
+
* It holds a session token, so it is a file to gitignore, like `_shots/`.
|
|
64
|
+
*/
|
|
65
|
+
exports.UI_LOCK_FILENAME = 'ui.lock';
|
|
66
|
+
function lockPath(cwd = (0, config_1.baseDir)()) {
|
|
67
|
+
return path.join(cwd, config_1.CONFIG_DIR, exports.UI_LOCK_FILENAME);
|
|
68
|
+
}
|
|
69
|
+
function writeLock(lock) {
|
|
70
|
+
try {
|
|
71
|
+
fs.mkdirSync(path.dirname(lockPath()), { recursive: true });
|
|
72
|
+
// 0600: it carries the session token, and the console it unlocks can edit
|
|
73
|
+
// test files. On Windows the mode is advisory, which is why the token is
|
|
74
|
+
// random per process and dies with it rather than being a stored secret.
|
|
75
|
+
fs.writeFileSync(lockPath(), JSON.stringify(lock), { encoding: 'utf8', mode: 0o600 });
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
/* a console that cannot write its lock still works; it just cannot be found */
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function clearLock() {
|
|
82
|
+
try {
|
|
83
|
+
fs.unlinkSync(lockPath());
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
/* already gone */
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function readLock() {
|
|
90
|
+
try {
|
|
91
|
+
const raw = JSON.parse(fs.readFileSync(lockPath(), 'utf8'));
|
|
92
|
+
if (!Number.isInteger(raw.port) || typeof raw.token !== 'string' || raw.token === '')
|
|
93
|
+
return null;
|
|
94
|
+
return raw;
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Is the console named by the lock actually answering?
|
|
102
|
+
*
|
|
103
|
+
* Checked with a real request rather than by testing whether the pid exists: a
|
|
104
|
+
* pid can be reused, and what matters is not that *something* is alive but that
|
|
105
|
+
* it is a console that accepts this token. Short timeout — this runs before a
|
|
106
|
+
* human sees anything, so a stale lock must not cost them a visible pause.
|
|
107
|
+
*/
|
|
108
|
+
function probe(lock, timeoutMs = 700) {
|
|
109
|
+
return new Promise((resolve) => {
|
|
110
|
+
const req = http.get({
|
|
111
|
+
host: '127.0.0.1',
|
|
112
|
+
port: lock.port,
|
|
113
|
+
path: `/api/state?t=${encodeURIComponent(lock.token)}`,
|
|
114
|
+
timeout: timeoutMs,
|
|
115
|
+
headers: { Host: `127.0.0.1:${lock.port}` },
|
|
116
|
+
}, (res) => {
|
|
117
|
+
res.resume();
|
|
118
|
+
resolve(res.statusCode === 200);
|
|
119
|
+
});
|
|
120
|
+
req.on('timeout', () => {
|
|
121
|
+
req.destroy();
|
|
122
|
+
resolve(false);
|
|
123
|
+
});
|
|
124
|
+
req.on('error', () => resolve(false));
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
/** The URL of a console already serving this project, or null. */
|
|
128
|
+
async function findRunningConsole() {
|
|
129
|
+
const lock = readLock();
|
|
130
|
+
if (!lock)
|
|
131
|
+
return null;
|
|
132
|
+
if (!(await probe(lock))) {
|
|
133
|
+
clearLock();
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
return `http://127.0.0.1:${lock.port}/?t=${lock.token}`;
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=lock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock.js","sourceRoot":"","sources":["../../src/ui/lock.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function renderConsoleHtml(token: string): string;
|