@jevitate/cli 0.1.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/LICENSE +21 -0
- package/dist/ai-cli.d.ts +31 -0
- package/dist/ai-cli.js +238 -0
- package/dist/ai-cli.js.map +1 -0
- package/dist/bin.d.ts +2 -0
- package/dist/bin.js +50663 -0
- package/dist/bin.js.map +1 -0
- package/dist/data-dir.d.ts +9 -0
- package/dist/data-dir.js +13 -0
- package/dist/data-dir.js.map +1 -0
- package/dist/envelope.d.ts +11 -0
- package/dist/envelope.js +7 -0
- package/dist/envelope.js.map +1 -0
- package/dist/explore-api.d.ts +187 -0
- package/dist/explore-api.js +302 -0
- package/dist/explore-api.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/init-keys.d.ts +14 -0
- package/dist/init-keys.js +18 -0
- package/dist/init-keys.js.map +1 -0
- package/dist/init-mcp.d.ts +87 -0
- package/dist/init-mcp.js +198 -0
- package/dist/init-mcp.js.map +1 -0
- package/dist/init-skills.d.ts +80 -0
- package/dist/init-skills.js +256 -0
- package/dist/init-skills.js.map +1 -0
- package/dist/journey-api.d.ts +37 -0
- package/dist/journey-api.js +55 -0
- package/dist/journey-api.js.map +1 -0
- package/dist/load-api.d.ts +48 -0
- package/dist/load-api.js +84 -0
- package/dist/load-api.js.map +1 -0
- package/dist/mcp-api.d.ts +116 -0
- package/dist/mcp-api.js +359 -0
- package/dist/mcp-api.js.map +1 -0
- package/dist/mission-api.d.ts +56 -0
- package/dist/mission-api.js +65 -0
- package/dist/mission-api.js.map +1 -0
- package/dist/program.d.ts +77 -0
- package/dist/program.js +1938 -0
- package/dist/program.js.map +1 -0
- package/dist/record-api.d.ts +74 -0
- package/dist/record-api.js +93 -0
- package/dist/record-api.js.map +1 -0
- package/dist/regression-api.d.ts +17 -0
- package/dist/regression-api.js +16 -0
- package/dist/regression-api.js.map +1 -0
- package/dist/self-heal-adapter.d.ts +31 -0
- package/dist/self-heal-adapter.js +70 -0
- package/dist/self-heal-adapter.js.map +1 -0
- package/dist/source-api.d.ts +147 -0
- package/dist/source-api.js +208 -0
- package/dist/source-api.js.map +1 -0
- package/dist/source-run-api.d.ts +57 -0
- package/dist/source-run-api.js +91 -0
- package/dist/source-run-api.js.map +1 -0
- package/dist/ui-api.d.ts +35 -0
- package/dist/ui-api.js +369 -0
- package/dist/ui-api.js.map +1 -0
- package/dist/ux-api.d.ts +75 -0
- package/dist/ux-api.js +231 -0
- package/dist/ux-api.js.map +1 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +37 -0
- package/dist/version.js.map +1 -0
- package/package.json +85 -0
- package/skills/jevitate-explore/SKILL.md +108 -0
- package/skills/jevitate-load-test/SKILL.md +42 -0
- package/skills/jevitate-mission-scope/SKILL.md +107 -0
- package/skills/jevitate-record/SKILL.md +78 -0
- package/skills/jevitate-run-journey/SKILL.md +72 -0
- package/skills/jevitate-sources/SKILL.md +88 -0
- package/skills/jevitate-ux-review/SKILL.md +68 -0
- package/ui/app.js +538 -0
- package/ui/index.html +546 -0
package/dist/bin.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,6EAA6E;AAC7E,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,cAAc,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AAClE,MAAM,MAAM,GAAG,cAAc,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC;AAC7C,MAAM,OAAO,GAAG,YAAY,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;AACnD,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IAC7C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACzC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves a default runtime-data path under `~/.jevitate/<segments>`
|
|
3
|
+
* (product = Jevitate). Greenfield: there is no legacy `~/.doit` location.
|
|
4
|
+
* `homedir` is injectable so this is unit-testable without touching
|
|
5
|
+
* `os.homedir()`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function resolveDataDir(segments: string[], deps?: {
|
|
8
|
+
homedir?: () => string;
|
|
9
|
+
}): string;
|
package/dist/data-dir.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { homedir as osHomedir } from "node:os";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Resolves a default runtime-data path under `~/.jevitate/<segments>`
|
|
5
|
+
* (product = Jevitate). Greenfield: there is no legacy `~/.doit` location.
|
|
6
|
+
* `homedir` is injectable so this is unit-testable without touching
|
|
7
|
+
* `os.homedir()`.
|
|
8
|
+
*/
|
|
9
|
+
export function resolveDataDir(segments, deps = {}) {
|
|
10
|
+
const homedir = deps.homedir ?? osHomedir;
|
|
11
|
+
return join(homedir(), ".jevitate", ...segments);
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=data-dir.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-dir.js","sourceRoot":"","sources":["../src/data-dir.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;;;;;GAKG;AACH,MAAM,UAAU,cAAc,CAC5B,QAAkB,EAClB,OAAmC,EAAE;IAErC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,SAAS,CAAC;IAC1C,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,GAAG,QAAQ,CAAC,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface JsonEnvelope<T> {
|
|
2
|
+
v: 1;
|
|
3
|
+
ok: boolean;
|
|
4
|
+
data?: T;
|
|
5
|
+
error?: {
|
|
6
|
+
code: string;
|
|
7
|
+
message: string;
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export declare function ok<T>(data: T): JsonEnvelope<T>;
|
|
11
|
+
export declare function fail(code: string, message: string): JsonEnvelope<never>;
|
package/dist/envelope.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"envelope.js","sourceRoot":"","sources":["../src/envelope.ts"],"names":[],"mappings":"AAOA,MAAM,UAAU,EAAE,CAAI,IAAO;IAC3B,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,IAAY,EAAE,OAAe;IAChD,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import type { JudgmentPort, GenerationPort, CredentialKey } from "@jevitate/ai-core";
|
|
2
|
+
import { type BrowserPort } from "@jevitate/playwright";
|
|
3
|
+
import type { Assertion } from "@jevitate/recording";
|
|
4
|
+
import { type Bounds, type CoverageReport, type GoalBasedOutcome, type StopReason, type AuthorJourneyResult, type AdversarialOutcome, type MisuseStrategy, type FeatureRunResult } from "@jevitate/explore";
|
|
5
|
+
/**
|
|
6
|
+
* The programmatic surface behind `jevitate explore` — wires a real Playwright
|
|
7
|
+
* `Page` + gateways to `@jevitate/explore`'s goal-based mission, then persists
|
|
8
|
+
* the emitted `Recording` under `~/.jevitate/recordings`.
|
|
9
|
+
*
|
|
10
|
+
* The authorized-target guard runs FIRST (fail-closed), BEFORE any browser is
|
|
11
|
+
* opened — an unauthorized origin never launches Chromium. Gateways are
|
|
12
|
+
* injected (fakes in tests / live wiring in `program.ts`), so this file needs
|
|
13
|
+
* no keys or network to be unit-tested.
|
|
14
|
+
*/
|
|
15
|
+
export interface RunExplorationOptions {
|
|
16
|
+
readonly url: string;
|
|
17
|
+
readonly goal: string;
|
|
18
|
+
readonly successAssertion: Assertion;
|
|
19
|
+
readonly allowlist: readonly string[];
|
|
20
|
+
readonly judge: JudgmentPort;
|
|
21
|
+
readonly gen: GenerationPort;
|
|
22
|
+
readonly bounds?: Partial<Bounds>;
|
|
23
|
+
readonly secrets?: readonly string[];
|
|
24
|
+
/** Where the Recording is written. Default `~/.jevitate/recordings`. */
|
|
25
|
+
readonly outDir?: string;
|
|
26
|
+
/** Testing seam — defaults to a real `PlaywrightBrowserPort`. */
|
|
27
|
+
readonly browserPortFactory?: () => BrowserPort;
|
|
28
|
+
/** ISO clock for the recording filename. Default `Date.now()`. */
|
|
29
|
+
readonly nowIso?: () => string;
|
|
30
|
+
}
|
|
31
|
+
export interface RunExplorationResult {
|
|
32
|
+
readonly outcome: GoalBasedOutcome;
|
|
33
|
+
readonly assertionPassed: boolean;
|
|
34
|
+
readonly stop: StopReason;
|
|
35
|
+
readonly finalUrl: string;
|
|
36
|
+
readonly decisions: number;
|
|
37
|
+
readonly actions: number;
|
|
38
|
+
readonly recordingPath: string;
|
|
39
|
+
}
|
|
40
|
+
export declare function runExploration(opts: RunExplorationOptions): Promise<RunExplorationResult>;
|
|
41
|
+
/**
|
|
42
|
+
* Arguments handed to the authoring step of `runAuthorJourney`. Kept separate
|
|
43
|
+
* from `RunAuthorJourneyOptions` so tests can inject `authorImpl` (a fake
|
|
44
|
+
* authoring step) without opening a real browser.
|
|
45
|
+
*/
|
|
46
|
+
export interface AuthorViaBrowserArgs {
|
|
47
|
+
readonly url: string;
|
|
48
|
+
readonly origin: string;
|
|
49
|
+
readonly goal: string;
|
|
50
|
+
readonly successAssertion: Assertion;
|
|
51
|
+
readonly allowlist: readonly string[];
|
|
52
|
+
readonly judge?: JudgmentPort;
|
|
53
|
+
readonly gen?: GenerationPort;
|
|
54
|
+
readonly bounds?: Partial<Bounds>;
|
|
55
|
+
readonly takes: number;
|
|
56
|
+
readonly journeyId: string;
|
|
57
|
+
readonly journeyName: string;
|
|
58
|
+
readonly browserPortFactory?: () => BrowserPort;
|
|
59
|
+
}
|
|
60
|
+
export interface RunAuthorJourneyOptions {
|
|
61
|
+
readonly url: string;
|
|
62
|
+
readonly goal: string;
|
|
63
|
+
readonly successAssertion: Assertion;
|
|
64
|
+
readonly allowlist: readonly string[];
|
|
65
|
+
/** Where the authored Journey is persisted (via `FsJourneyStore`). */
|
|
66
|
+
readonly journeysDir: string;
|
|
67
|
+
readonly journeyId: string;
|
|
68
|
+
readonly journeyName: string;
|
|
69
|
+
/** Total takes incl. discovery. Default 1 (single-take MVP). */
|
|
70
|
+
readonly takes?: number;
|
|
71
|
+
readonly judge?: JudgmentPort;
|
|
72
|
+
readonly gen?: GenerationPort;
|
|
73
|
+
readonly bounds?: Partial<Bounds>;
|
|
74
|
+
readonly browserPortFactory?: () => BrowserPort;
|
|
75
|
+
/**
|
|
76
|
+
* Test seam: override the authoring step. Defaults to `authorViaBrowser`,
|
|
77
|
+
* which drives a real Playwright-backed actor through `authorJourney`.
|
|
78
|
+
*/
|
|
79
|
+
readonly authorImpl?: (args: AuthorViaBrowserArgs) => Promise<AuthorJourneyResult>;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The programmatic surface behind `jevitate explore author-journey` — drives
|
|
83
|
+
* the goal-based exploration mission and feeds its take(s) through RxD's
|
|
84
|
+
* diff/postdoc pipeline (`@jevitate/explore`'s `authorJourney`) to author a
|
|
85
|
+
* parameterized, replayable, UNPROMOTED Journey, then persists it under the
|
|
86
|
+
* journeys store. Additive: the record-by-demonstration authoring path is
|
|
87
|
+
* untouched.
|
|
88
|
+
*
|
|
89
|
+
* The authorized-target guard runs FIRST (fail-closed), before any browser is
|
|
90
|
+
* opened. The authoring step is injectable (`authorImpl`) so it is unit-testable
|
|
91
|
+
* without a browser.
|
|
92
|
+
*/
|
|
93
|
+
export declare function runAuthorJourney(opts: RunAuthorJourneyOptions): Promise<AuthorJourneyResult>;
|
|
94
|
+
/**
|
|
95
|
+
* The programmatic surface behind `jevitate explore --strategy coverage`
|
|
96
|
+
* (additive, alongside `runExploration`). Wires a real Playwright `Page` +
|
|
97
|
+
* gateways to `@jevitate/explore`'s proof-by-induction (state-coverage) mission
|
|
98
|
+
* and persists each emitted repro `Recording` under `~/.jevitate/recordings`.
|
|
99
|
+
*
|
|
100
|
+
* Same fail-closed discipline as `runExploration`: the authorized-target guard
|
|
101
|
+
* runs FIRST, before any browser is opened.
|
|
102
|
+
*/
|
|
103
|
+
export interface RunCoverageMissionOptions {
|
|
104
|
+
readonly url: string;
|
|
105
|
+
readonly allowlist: readonly string[];
|
|
106
|
+
readonly judge: JudgmentPort;
|
|
107
|
+
readonly gen: GenerationPort;
|
|
108
|
+
readonly bounds?: Partial<Bounds>;
|
|
109
|
+
/** Where the repro Recordings are written. Default `~/.jevitate/recordings`. */
|
|
110
|
+
readonly outDir?: string;
|
|
111
|
+
readonly browserPortFactory?: () => BrowserPort;
|
|
112
|
+
readonly nowIso?: () => string;
|
|
113
|
+
}
|
|
114
|
+
export interface RunCoverageMissionResult {
|
|
115
|
+
readonly coverage: CoverageReport;
|
|
116
|
+
readonly outcome: "exhausted" | "cap";
|
|
117
|
+
readonly recordingPaths: string[];
|
|
118
|
+
}
|
|
119
|
+
export declare function runCoverageMission(opts: RunCoverageMissionOptions): Promise<RunCoverageMissionResult>;
|
|
120
|
+
/**
|
|
121
|
+
* Options for the additive adversarial CLI mission. Mirrors `runExploration`'s
|
|
122
|
+
* fail-closed discipline: the authorized-target guard runs FIRST, before any
|
|
123
|
+
* browser is opened, so an unauthorized origin never launches Chromium.
|
|
124
|
+
*/
|
|
125
|
+
export interface RunAdversarialCliMissionOptions {
|
|
126
|
+
readonly seedUrl: string;
|
|
127
|
+
readonly allowlist: readonly string[];
|
|
128
|
+
readonly strategies: readonly MisuseStrategy[];
|
|
129
|
+
readonly judgment: JudgmentPort;
|
|
130
|
+
readonly generation: GenerationPort;
|
|
131
|
+
readonly profileDir: string;
|
|
132
|
+
readonly headless?: boolean;
|
|
133
|
+
/** Testing seam — defaults to a real `PlaywrightBrowserPort`. */
|
|
134
|
+
readonly browserPortFactory?: () => BrowserPort;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Runs `@jevitate/explore`'s adversarial "try to break it" mission behind the
|
|
138
|
+
* CLI. Guardrail #1 is enforced BEFORE opening a browser (fail-closed); the
|
|
139
|
+
* session is always torn down. The stop-on-defect decision is the mission's
|
|
140
|
+
* own trusted hard-signal oracle — never Jev's `Noul` (guardrail #4).
|
|
141
|
+
*/
|
|
142
|
+
export declare function runAdversarialCliMission(opts: RunAdversarialCliMissionOptions): Promise<AdversarialOutcome>;
|
|
143
|
+
/**
|
|
144
|
+
* The programmatic surface behind `jevitate explore --feature <name>` — the
|
|
145
|
+
* capability-scoped feature-testing mission (ticket #2, paired site ticket
|
|
146
|
+
* #11). Model-free by design, so unlike `runExploration` it needs no gateways.
|
|
147
|
+
*
|
|
148
|
+
* The authorized-target guard runs FIRST (fail-closed), BEFORE any browser is
|
|
149
|
+
* opened — an unauthorized origin never launches Chromium.
|
|
150
|
+
*/
|
|
151
|
+
export interface RunFeatureCliMissionOptions {
|
|
152
|
+
readonly seedUrl: string;
|
|
153
|
+
readonly allowlist: readonly string[];
|
|
154
|
+
readonly capability: string;
|
|
155
|
+
readonly routeGlobs: readonly string[];
|
|
156
|
+
readonly profileDir: string;
|
|
157
|
+
readonly headless?: boolean;
|
|
158
|
+
/** Testing seam — defaults to a real `PlaywrightBrowserPort`. */
|
|
159
|
+
readonly browserPortFactory?: () => BrowserPort;
|
|
160
|
+
}
|
|
161
|
+
export declare function runFeatureCliMission(opts: RunFeatureCliMissionOptions): Promise<FeatureRunResult>;
|
|
162
|
+
/** Injectable wiring for the `explore` CLI command (all optional). */
|
|
163
|
+
export interface ExploreCliDeps {
|
|
164
|
+
/** Injected judgment gateway (tests). */
|
|
165
|
+
judge?: JudgmentPort;
|
|
166
|
+
/** Injected generation gateway (tests). */
|
|
167
|
+
gen?: GenerationPort;
|
|
168
|
+
browserPortFactory?: () => BrowserPort;
|
|
169
|
+
env?: Record<string, string | undefined>;
|
|
170
|
+
localConfig?: Partial<Record<CredentialKey, string>>;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Compact `--success` assertion spec parser. Supported forms:
|
|
174
|
+
* urlIncludes:<text>
|
|
175
|
+
* visible:<descriptor>
|
|
176
|
+
* textIncludes:<descriptor>|<text>
|
|
177
|
+
* count:<descriptor>|min=<n>,max=<n>
|
|
178
|
+
* where <descriptor> is `k=v` pairs joined by `;` over
|
|
179
|
+
* testId/role/name/label/text/css.
|
|
180
|
+
*/
|
|
181
|
+
export declare function parseAssertionSpec(spec: string): Assertion;
|
|
182
|
+
/**
|
|
183
|
+
* The authorized-origins allowlist for a run: explicit `--allow` origins when
|
|
184
|
+
* given, otherwise the target URL's own origin (you asked to explore it). An
|
|
185
|
+
* unparseable URL yields an empty allowlist → the guard fails closed.
|
|
186
|
+
*/
|
|
187
|
+
export declare function resolveExploreAllowlist(url: string, allow: readonly string[]): string[];
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import { mkdtemp, mkdir, rm, writeFile } from "node:fs/promises";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { PlaywrightBrowserPort } from "@jevitate/playwright";
|
|
5
|
+
import { CastActor, BrowseTheWeb } from "@jevitate/screenplay";
|
|
6
|
+
import { runGoalBasedMission, authorJourney, runInductionMission, runAdversarialMission, runFeatureMission, assertAuthorizedExploreTarget, normalizeAllowlist, } from "@jevitate/explore";
|
|
7
|
+
import { FsJourneyStore } from "@jevitate/journey";
|
|
8
|
+
import { resolveDataDir } from "./data-dir.js";
|
|
9
|
+
export async function runExploration(opts) {
|
|
10
|
+
// Guardrail #1 — authorize BEFORE opening a browser. Throws on refusal.
|
|
11
|
+
const origin = assertAuthorizedExploreTarget(opts.url, opts.allowlist);
|
|
12
|
+
const portFactory = opts.browserPortFactory ?? (() => new PlaywrightBrowserPort());
|
|
13
|
+
const port = portFactory();
|
|
14
|
+
const profileDir = await mkdtemp(join(tmpdir(), "jevitate-explore-"));
|
|
15
|
+
const session = await port.open({
|
|
16
|
+
profileDir,
|
|
17
|
+
headless: true,
|
|
18
|
+
allowedOrigins: [...opts.allowlist],
|
|
19
|
+
baseUrl: origin,
|
|
20
|
+
});
|
|
21
|
+
try {
|
|
22
|
+
const actor = CastActor.named("explorer").whoCan(new BrowseTheWeb(session, [...opts.allowlist]));
|
|
23
|
+
const mission = await runGoalBasedMission({
|
|
24
|
+
actor,
|
|
25
|
+
judge: opts.judge,
|
|
26
|
+
gen: opts.gen,
|
|
27
|
+
goal: opts.goal,
|
|
28
|
+
allowlist: opts.allowlist,
|
|
29
|
+
startUrl: opts.url,
|
|
30
|
+
successAssertion: opts.successAssertion,
|
|
31
|
+
bounds: opts.bounds,
|
|
32
|
+
secrets: opts.secrets,
|
|
33
|
+
site: origin,
|
|
34
|
+
});
|
|
35
|
+
const outDir = opts.outDir ?? resolveDataDir(["recordings"]);
|
|
36
|
+
await mkdir(outDir, { recursive: true });
|
|
37
|
+
const iso = (opts.nowIso ?? (() => new Date().toISOString()))();
|
|
38
|
+
const recordingPath = join(outDir, `explore-${iso.replace(/[:.]/g, "-")}.json`);
|
|
39
|
+
await writeFile(recordingPath, `${JSON.stringify(mission.recording, null, 2)}\n`, "utf8");
|
|
40
|
+
return {
|
|
41
|
+
outcome: mission.outcome,
|
|
42
|
+
assertionPassed: mission.assertionPassed,
|
|
43
|
+
stop: mission.run.stop,
|
|
44
|
+
finalUrl: mission.finalUrl,
|
|
45
|
+
decisions: mission.run.decisions,
|
|
46
|
+
actions: mission.run.actions,
|
|
47
|
+
recordingPath,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
finally {
|
|
51
|
+
await session.close();
|
|
52
|
+
await rm(profileDir, { recursive: true, force: true });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The programmatic surface behind `jevitate explore author-journey` — drives
|
|
57
|
+
* the goal-based exploration mission and feeds its take(s) through RxD's
|
|
58
|
+
* diff/postdoc pipeline (`@jevitate/explore`'s `authorJourney`) to author a
|
|
59
|
+
* parameterized, replayable, UNPROMOTED Journey, then persists it under the
|
|
60
|
+
* journeys store. Additive: the record-by-demonstration authoring path is
|
|
61
|
+
* untouched.
|
|
62
|
+
*
|
|
63
|
+
* The authorized-target guard runs FIRST (fail-closed), before any browser is
|
|
64
|
+
* opened. The authoring step is injectable (`authorImpl`) so it is unit-testable
|
|
65
|
+
* without a browser.
|
|
66
|
+
*/
|
|
67
|
+
export async function runAuthorJourney(opts) {
|
|
68
|
+
// Guardrail #1 — authorize BEFORE opening a browser. Throws on refusal.
|
|
69
|
+
const origin = assertAuthorizedExploreTarget(opts.url, opts.allowlist);
|
|
70
|
+
const impl = opts.authorImpl ?? authorViaBrowser;
|
|
71
|
+
const result = await impl({
|
|
72
|
+
url: opts.url,
|
|
73
|
+
origin,
|
|
74
|
+
goal: opts.goal,
|
|
75
|
+
successAssertion: opts.successAssertion,
|
|
76
|
+
allowlist: opts.allowlist,
|
|
77
|
+
judge: opts.judge,
|
|
78
|
+
gen: opts.gen,
|
|
79
|
+
bounds: opts.bounds,
|
|
80
|
+
takes: opts.takes ?? 1,
|
|
81
|
+
journeyId: opts.journeyId,
|
|
82
|
+
journeyName: opts.journeyName,
|
|
83
|
+
browserPortFactory: opts.browserPortFactory,
|
|
84
|
+
});
|
|
85
|
+
if (result.outcome === "authored") {
|
|
86
|
+
await new FsJourneyStore(opts.journeysDir).put(result.journey);
|
|
87
|
+
}
|
|
88
|
+
return result;
|
|
89
|
+
}
|
|
90
|
+
/** Default authoring step: opens a real browser, builds an actor, authors. */
|
|
91
|
+
async function authorViaBrowser(args) {
|
|
92
|
+
if (!args.judge || !args.gen) {
|
|
93
|
+
throw new Error("runAuthorJourney: judge and gen gateways are required to drive the authoring mission");
|
|
94
|
+
}
|
|
95
|
+
const judge = args.judge;
|
|
96
|
+
const gen = args.gen;
|
|
97
|
+
const portFactory = args.browserPortFactory ?? (() => new PlaywrightBrowserPort());
|
|
98
|
+
const port = portFactory();
|
|
99
|
+
const profileDir = await mkdtemp(join(tmpdir(), "jevitate-author-"));
|
|
100
|
+
const session = await port.open({
|
|
101
|
+
profileDir,
|
|
102
|
+
headless: true,
|
|
103
|
+
allowedOrigins: [...args.allowlist],
|
|
104
|
+
baseUrl: args.origin,
|
|
105
|
+
});
|
|
106
|
+
try {
|
|
107
|
+
const actor = CastActor.named("author").whoCan(new BrowseTheWeb(session, [...args.allowlist]));
|
|
108
|
+
return await authorJourney({
|
|
109
|
+
goal: args.goal,
|
|
110
|
+
successAssertion: args.successAssertion,
|
|
111
|
+
allowlist: args.allowlist,
|
|
112
|
+
startUrl: args.url,
|
|
113
|
+
bounds: args.bounds,
|
|
114
|
+
actor,
|
|
115
|
+
judgment: judge,
|
|
116
|
+
generation: gen,
|
|
117
|
+
takes: args.takes,
|
|
118
|
+
journeyId: args.journeyId,
|
|
119
|
+
journeyName: args.journeyName,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
finally {
|
|
123
|
+
await session.close();
|
|
124
|
+
await rm(profileDir, { recursive: true, force: true });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
export async function runCoverageMission(opts) {
|
|
128
|
+
// Guardrail #1 — authorize BEFORE opening a browser. Throws on refusal.
|
|
129
|
+
const origin = assertAuthorizedExploreTarget(opts.url, opts.allowlist);
|
|
130
|
+
const portFactory = opts.browserPortFactory ?? (() => new PlaywrightBrowserPort());
|
|
131
|
+
const port = portFactory();
|
|
132
|
+
const profileDir = await mkdtemp(join(tmpdir(), "jevitate-coverage-"));
|
|
133
|
+
const session = await port.open({
|
|
134
|
+
profileDir,
|
|
135
|
+
headless: true,
|
|
136
|
+
allowedOrigins: [...opts.allowlist],
|
|
137
|
+
baseUrl: origin,
|
|
138
|
+
});
|
|
139
|
+
try {
|
|
140
|
+
const actor = CastActor.named("coverage-mission").whoCan(new BrowseTheWeb(session, [...opts.allowlist]));
|
|
141
|
+
const result = await runInductionMission({
|
|
142
|
+
page: session.page,
|
|
143
|
+
actor,
|
|
144
|
+
judgment: opts.judge,
|
|
145
|
+
generation: opts.gen,
|
|
146
|
+
seedUrl: opts.url,
|
|
147
|
+
allowlist: opts.allowlist,
|
|
148
|
+
bounds: opts.bounds,
|
|
149
|
+
});
|
|
150
|
+
const outDir = opts.outDir ?? resolveDataDir(["recordings"]);
|
|
151
|
+
await mkdir(outDir, { recursive: true });
|
|
152
|
+
const iso = (opts.nowIso ?? (() => new Date().toISOString()))();
|
|
153
|
+
const stamp = iso.replace(/[:.]/g, "-");
|
|
154
|
+
const recordingPaths = [];
|
|
155
|
+
for (let i = 0; i < result.recordings.length; i++) {
|
|
156
|
+
const p = join(outDir, `coverage-${stamp}-state-${i}.json`);
|
|
157
|
+
await writeFile(p, `${JSON.stringify(result.recordings[i], null, 2)}\n`, "utf8");
|
|
158
|
+
recordingPaths.push(p);
|
|
159
|
+
}
|
|
160
|
+
return { coverage: result.coverage, outcome: result.outcome, recordingPaths };
|
|
161
|
+
}
|
|
162
|
+
finally {
|
|
163
|
+
await session.close();
|
|
164
|
+
await rm(profileDir, { recursive: true, force: true });
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Runs `@jevitate/explore`'s adversarial "try to break it" mission behind the
|
|
169
|
+
* CLI. Guardrail #1 is enforced BEFORE opening a browser (fail-closed); the
|
|
170
|
+
* session is always torn down. The stop-on-defect decision is the mission's
|
|
171
|
+
* own trusted hard-signal oracle — never Jev's `Noul` (guardrail #4).
|
|
172
|
+
*/
|
|
173
|
+
export async function runAdversarialCliMission(opts) {
|
|
174
|
+
// Guardrail #1 — authorize BEFORE opening a browser. Throws on refusal.
|
|
175
|
+
const origin = assertAuthorizedExploreTarget(opts.seedUrl, opts.allowlist);
|
|
176
|
+
const portFactory = opts.browserPortFactory ?? (() => new PlaywrightBrowserPort());
|
|
177
|
+
const port = portFactory();
|
|
178
|
+
const session = await port.open({
|
|
179
|
+
profileDir: opts.profileDir,
|
|
180
|
+
headless: opts.headless ?? true,
|
|
181
|
+
allowedOrigins: [...opts.allowlist],
|
|
182
|
+
baseUrl: origin,
|
|
183
|
+
});
|
|
184
|
+
try {
|
|
185
|
+
const actor = CastActor.named("adversarial-mission").whoCan(new BrowseTheWeb(session, [...opts.allowlist]));
|
|
186
|
+
return await runAdversarialMission({
|
|
187
|
+
page: session.page,
|
|
188
|
+
actor,
|
|
189
|
+
judgment: opts.judgment,
|
|
190
|
+
generation: opts.generation,
|
|
191
|
+
seedUrl: opts.seedUrl,
|
|
192
|
+
allowlist: opts.allowlist,
|
|
193
|
+
strategies: opts.strategies,
|
|
194
|
+
site: origin,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
finally {
|
|
198
|
+
await session.close();
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
export async function runFeatureCliMission(opts) {
|
|
202
|
+
// Guardrail #1 — authorize BEFORE opening a browser. Throws on refusal.
|
|
203
|
+
const origin = assertAuthorizedExploreTarget(opts.seedUrl, opts.allowlist);
|
|
204
|
+
const scope = { name: opts.capability, originAllowlist: opts.allowlist, routeGlobs: opts.routeGlobs };
|
|
205
|
+
const portFactory = opts.browserPortFactory ?? (() => new PlaywrightBrowserPort());
|
|
206
|
+
const session = await portFactory().open({
|
|
207
|
+
profileDir: opts.profileDir,
|
|
208
|
+
headless: opts.headless ?? true,
|
|
209
|
+
allowedOrigins: [...opts.allowlist],
|
|
210
|
+
baseUrl: origin,
|
|
211
|
+
});
|
|
212
|
+
try {
|
|
213
|
+
const actor = CastActor.named("feature-mission").whoCan(new BrowseTheWeb(session, [...opts.allowlist]));
|
|
214
|
+
return await runFeatureMission({
|
|
215
|
+
page: session.page,
|
|
216
|
+
actor,
|
|
217
|
+
seedUrl: opts.seedUrl,
|
|
218
|
+
allowlist: opts.allowlist,
|
|
219
|
+
scope,
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
finally {
|
|
223
|
+
await session.close();
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Compact `--success` assertion spec parser. Supported forms:
|
|
228
|
+
* urlIncludes:<text>
|
|
229
|
+
* visible:<descriptor>
|
|
230
|
+
* textIncludes:<descriptor>|<text>
|
|
231
|
+
* count:<descriptor>|min=<n>,max=<n>
|
|
232
|
+
* where <descriptor> is `k=v` pairs joined by `;` over
|
|
233
|
+
* testId/role/name/label/text/css.
|
|
234
|
+
*/
|
|
235
|
+
export function parseAssertionSpec(spec) {
|
|
236
|
+
const ci = spec.indexOf(":");
|
|
237
|
+
if (ci === -1)
|
|
238
|
+
throw new Error(`invalid --success spec ${JSON.stringify(spec)}; expected "<kind>:<...>"`);
|
|
239
|
+
const kind = spec.slice(0, ci);
|
|
240
|
+
const rest = spec.slice(ci + 1);
|
|
241
|
+
switch (kind) {
|
|
242
|
+
case "urlIncludes": {
|
|
243
|
+
if (rest === "")
|
|
244
|
+
throw new Error("urlIncludes requires a text (urlIncludes:/path)");
|
|
245
|
+
return { kind: "urlIncludes", text: rest };
|
|
246
|
+
}
|
|
247
|
+
case "visible":
|
|
248
|
+
return { kind: "visible", target: parseDescriptorSpec(rest) };
|
|
249
|
+
case "textIncludes": {
|
|
250
|
+
const bar = rest.lastIndexOf("|");
|
|
251
|
+
if (bar === -1)
|
|
252
|
+
throw new Error('textIncludes requires "<descriptor>|<text>"');
|
|
253
|
+
return { kind: "textIncludes", target: parseDescriptorSpec(rest.slice(0, bar)), text: rest.slice(bar + 1) };
|
|
254
|
+
}
|
|
255
|
+
case "count": {
|
|
256
|
+
const bar = rest.indexOf("|");
|
|
257
|
+
const descPart = bar === -1 ? rest : rest.slice(0, bar);
|
|
258
|
+
const bounds = bar === -1 ? "" : rest.slice(bar + 1);
|
|
259
|
+
const target = parseDescriptorSpec(descPart);
|
|
260
|
+
const out = { kind: "count", target };
|
|
261
|
+
for (const pair of bounds.split(",")) {
|
|
262
|
+
const [k, v] = pair.split("=");
|
|
263
|
+
if (k === "min" && v)
|
|
264
|
+
out.min = Number(v);
|
|
265
|
+
if (k === "max" && v)
|
|
266
|
+
out.max = Number(v);
|
|
267
|
+
}
|
|
268
|
+
return out;
|
|
269
|
+
}
|
|
270
|
+
default:
|
|
271
|
+
throw new Error(`unsupported assertion kind ${JSON.stringify(kind)}`);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
function parseDescriptorSpec(s) {
|
|
275
|
+
const d = {};
|
|
276
|
+
const keys = ["testId", "role", "name", "label", "text", "css"];
|
|
277
|
+
for (const pair of s.split(";")) {
|
|
278
|
+
const eq = pair.indexOf("=");
|
|
279
|
+
if (eq === -1)
|
|
280
|
+
continue;
|
|
281
|
+
const k = pair.slice(0, eq);
|
|
282
|
+
const v = pair.slice(eq + 1);
|
|
283
|
+
if (keys.includes(k) && v !== "") {
|
|
284
|
+
d[k] = v;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
if (!(d.testId || d.role || d.label || d.text || d.css)) {
|
|
288
|
+
throw new Error(`descriptor spec ${JSON.stringify(s)} has no usable selector`);
|
|
289
|
+
}
|
|
290
|
+
return d;
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* The authorized-origins allowlist for a run: explicit `--allow` origins when
|
|
294
|
+
* given, otherwise the target URL's own origin (you asked to explore it). An
|
|
295
|
+
* unparseable URL yields an empty allowlist → the guard fails closed.
|
|
296
|
+
*/
|
|
297
|
+
export function resolveExploreAllowlist(url, allow) {
|
|
298
|
+
if (allow.length > 0)
|
|
299
|
+
return [...allow];
|
|
300
|
+
return normalizeAllowlist([url]);
|
|
301
|
+
}
|
|
302
|
+
//# sourceMappingURL=explore-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explore-api.js","sourceRoot":"","sources":["../src/explore-api.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type CredentialStore, type SecureKeyIO, type Feature, type CredentialKey } from "@jevitate/ai-core";
|
|
2
|
+
export interface FeatureKeyReport {
|
|
3
|
+
required: CredentialKey[];
|
|
4
|
+
collected: CredentialKey[];
|
|
5
|
+
}
|
|
6
|
+
export type KeyCollectionReport = Record<Feature, FeatureKeyReport>;
|
|
7
|
+
/**
|
|
8
|
+
* Thin orchestration over the existing, already-guardrailed `collectMissingKeys`
|
|
9
|
+
* — collects every feature's missing keys in turn (never in parallel:
|
|
10
|
+
* `SecureKeyIO.promptSecret` is a single shared stdin, so concurrent prompts
|
|
11
|
+
* would interleave). Adds NO new key-handling logic: it never reads, echoes,
|
|
12
|
+
* logs, or returns a key value — only the key NAMES (required/collected).
|
|
13
|
+
*/
|
|
14
|
+
export declare function collectAllMissingKeys(store: CredentialStore, io: SecureKeyIO): Promise<KeyCollectionReport>;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { collectMissingKeys, FEATURE_KEYS, } from "@jevitate/ai-core";
|
|
2
|
+
const FEATURES = ["generation", "judgment"];
|
|
3
|
+
/**
|
|
4
|
+
* Thin orchestration over the existing, already-guardrailed `collectMissingKeys`
|
|
5
|
+
* — collects every feature's missing keys in turn (never in parallel:
|
|
6
|
+
* `SecureKeyIO.promptSecret` is a single shared stdin, so concurrent prompts
|
|
7
|
+
* would interleave). Adds NO new key-handling logic: it never reads, echoes,
|
|
8
|
+
* logs, or returns a key value — only the key NAMES (required/collected).
|
|
9
|
+
*/
|
|
10
|
+
export async function collectAllMissingKeys(store, io) {
|
|
11
|
+
const report = {};
|
|
12
|
+
for (const feature of FEATURES) {
|
|
13
|
+
const collected = await collectMissingKeys(feature, store, io);
|
|
14
|
+
report[feature] = { required: [...FEATURE_KEYS[feature]], collected };
|
|
15
|
+
}
|
|
16
|
+
return report;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=init-keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init-keys.js","sourceRoot":"","sources":["../src/init-keys.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,YAAY,GAKb,MAAM,mBAAmB,CAAC;AAQ3B,MAAM,QAAQ,GAAc,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;AAEvD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,KAAsB,EACtB,EAAe;IAEf,MAAM,MAAM,GAAG,EAAyB,CAAC;IACzC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,SAAS,GAAG,MAAM,kBAAkB,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QAC/D,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC;IACxE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|