@jevitate/cli 0.1.0 → 0.3.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 +23 -0
- package/dist/ai-cli.d.ts +31 -11
- package/dist/ai-cli.js +131 -88
- package/dist/ai-cli.js.map +1 -1
- package/dist/author-journey-cli.d.ts +4 -0
- package/dist/author-journey-cli.js +111 -0
- package/dist/author-journey-cli.js.map +1 -0
- package/dist/bin.js +60349 -16477
- package/dist/bin.js.map +1 -1
- package/dist/browser-run-options.d.ts +89 -0
- package/dist/browser-run-options.js +175 -0
- package/dist/browser-run-options.js.map +1 -0
- package/dist/build-info.generated.d.ts +2 -0
- package/dist/build-info.generated.js +10 -0
- package/dist/build-info.generated.js.map +1 -0
- package/dist/campaign-api.d.ts +151 -0
- package/dist/campaign-api.js +446 -0
- package/dist/campaign-api.js.map +1 -0
- package/dist/campaign-cli.d.ts +6 -0
- package/dist/campaign-cli.js +66 -0
- package/dist/campaign-cli.js.map +1 -0
- package/dist/check-api.d.ts +5 -0
- package/dist/check-api.js +234 -0
- package/dist/check-api.js.map +1 -0
- package/dist/check-budget.d.ts +26 -0
- package/dist/check-budget.js +90 -0
- package/dist/check-budget.js.map +1 -0
- package/dist/check-cli.d.ts +31 -0
- package/dist/check-cli.js +109 -0
- package/dist/check-cli.js.map +1 -0
- package/dist/check-execute.d.ts +29 -0
- package/dist/check-execute.js +420 -0
- package/dist/check-execute.js.map +1 -0
- package/dist/check-plan.d.ts +118 -0
- package/dist/check-plan.js +516 -0
- package/dist/check-plan.js.map +1 -0
- package/dist/check-suite.d.ts +184 -0
- package/dist/check-suite.js +540 -0
- package/dist/check-suite.js.map +1 -0
- package/dist/check-types.d.ts +181 -0
- package/dist/check-types.js +35 -0
- package/dist/check-types.js.map +1 -0
- package/dist/cli-args.d.ts +26 -0
- package/dist/cli-args.js +50 -0
- package/dist/cli-args.js.map +1 -0
- package/dist/cli-output.d.ts +106 -0
- package/dist/cli-output.js +563 -0
- package/dist/cli-output.js.map +1 -0
- package/dist/cli-reference.d.ts +3 -0
- package/dist/cli-reference.js +81 -0
- package/dist/cli-reference.js.map +1 -0
- package/dist/cli-refusal.d.ts +12 -0
- package/dist/cli-refusal.js +52 -0
- package/dist/cli-refusal.js.map +1 -0
- package/dist/cli-shared.d.ts +340 -0
- package/dist/cli-shared.js +537 -0
- package/dist/cli-shared.js.map +1 -0
- package/dist/cli-surface.d.ts +33 -0
- package/dist/cli-surface.js +48 -0
- package/dist/cli-surface.js.map +1 -0
- package/dist/conversation-options.d.ts +15 -0
- package/dist/conversation-options.js +10 -0
- package/dist/conversation-options.js.map +1 -0
- package/dist/credentials-file.d.ts +15 -0
- package/dist/credentials-file.js +56 -0
- package/dist/credentials-file.js.map +1 -0
- package/dist/data-dir.d.ts +1 -1
- package/dist/data-dir.js +1 -1
- package/dist/defect-evidence.d.ts +141 -0
- package/dist/defect-evidence.js +505 -0
- package/dist/defect-evidence.js.map +1 -0
- package/dist/demo-aspect-api.d.ts +209 -0
- package/dist/demo-aspect-api.js +398 -0
- package/dist/demo-aspect-api.js.map +1 -0
- package/dist/demo-aspect-cli.d.ts +3 -0
- package/dist/demo-aspect-cli.js +243 -0
- package/dist/demo-aspect-cli.js.map +1 -0
- package/dist/demo-capture.d.ts +142 -0
- package/dist/demo-capture.js +537 -0
- package/dist/demo-capture.js.map +1 -0
- package/dist/engine.d.ts +35 -0
- package/dist/engine.js +25 -0
- package/dist/engine.js.map +1 -0
- package/dist/environments.d.ts +155 -0
- package/dist/environments.js +364 -0
- package/dist/environments.js.map +1 -0
- package/dist/exit-codes.d.ts +46 -0
- package/dist/exit-codes.js +91 -0
- package/dist/exit-codes.js.map +1 -0
- package/dist/explore-adversarial.d.ts +144 -0
- package/dist/explore-adversarial.js +227 -0
- package/dist/explore-adversarial.js.map +1 -0
- package/dist/explore-api.d.ts +7 -187
- package/dist/explore-api.js +7 -301
- package/dist/explore-api.js.map +1 -1
- package/dist/explore-author.d.ts +79 -0
- package/dist/explore-author.js +86 -0
- package/dist/explore-author.js.map +1 -0
- package/dist/explore-cli.d.ts +7 -0
- package/dist/explore-cli.js +1199 -0
- package/dist/explore-cli.js.map +1 -0
- package/dist/explore-coverage.d.ts +173 -0
- package/dist/explore-coverage.js +246 -0
- package/dist/explore-coverage.js.map +1 -0
- package/dist/explore-feature.d.ts +125 -0
- package/dist/explore-feature.js +218 -0
- package/dist/explore-feature.js.map +1 -0
- package/dist/explore-goal.d.ts +271 -0
- package/dist/explore-goal.js +417 -0
- package/dist/explore-goal.js.map +1 -0
- package/dist/explore-shared.d.ts +177 -0
- package/dist/explore-shared.js +149 -0
- package/dist/explore-shared.js.map +1 -0
- package/dist/explore-specs.d.ts +53 -0
- package/dist/explore-specs.js +333 -0
- package/dist/explore-specs.js.map +1 -0
- package/dist/findings-filing.d.ts +64 -0
- package/dist/findings-filing.js +108 -0
- package/dist/findings-filing.js.map +1 -0
- package/dist/fixture-auth.d.ts +63 -0
- package/dist/fixture-auth.js +95 -0
- package/dist/fixture-auth.js.map +1 -0
- package/dist/fixture-cli.d.ts +99 -0
- package/dist/fixture-cli.js +292 -0
- package/dist/fixture-cli.js.map +1 -0
- package/dist/github-issue-filer.d.ts +62 -0
- package/dist/github-issue-filer.js +189 -0
- package/dist/github-issue-filer.js.map +1 -0
- package/dist/host-health-run.d.ts +25 -0
- package/dist/host-health-run.js +33 -0
- package/dist/host-health-run.js.map +1 -0
- package/dist/http-5xx-outcome.d.ts +6 -0
- package/dist/http-5xx-outcome.js +39 -0
- package/dist/http-5xx-outcome.js.map +1 -0
- package/dist/inbox-cli.d.ts +7 -0
- package/dist/inbox-cli.js +197 -0
- package/dist/inbox-cli.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/init-cli.d.ts +4 -0
- package/dist/init-cli.js +156 -0
- package/dist/init-cli.js.map +1 -0
- package/dist/init-keys.d.ts +30 -2
- package/dist/init-keys.js +19 -5
- package/dist/init-keys.js.map +1 -1
- package/dist/init-next-steps.d.ts +35 -0
- package/dist/init-next-steps.js +79 -0
- package/dist/init-next-steps.js.map +1 -0
- package/dist/invariants-file.d.ts +34 -0
- package/dist/invariants-file.js +68 -0
- package/dist/invariants-file.js.map +1 -0
- package/dist/invariants-validate.d.ts +30 -0
- package/dist/invariants-validate.js +105 -0
- package/dist/invariants-validate.js.map +1 -0
- package/dist/journey-annotate-api.d.ts +76 -0
- package/dist/journey-annotate-api.js +269 -0
- package/dist/journey-annotate-api.js.map +1 -0
- package/dist/journey-annotate-cli.d.ts +9 -0
- package/dist/journey-annotate-cli.js +181 -0
- package/dist/journey-annotate-cli.js.map +1 -0
- package/dist/journey-api.d.ts +104 -2
- package/dist/journey-api.js +163 -20
- package/dist/journey-api.js.map +1 -1
- package/dist/journey-cli.d.ts +4 -0
- package/dist/journey-cli.js +411 -0
- package/dist/journey-cli.js.map +1 -0
- package/dist/journey-demo-api.d.ts +114 -0
- package/dist/journey-demo-api.js +405 -0
- package/dist/journey-demo-api.js.map +1 -0
- package/dist/journey-demo-cli.d.ts +10 -0
- package/dist/journey-demo-cli.js +158 -0
- package/dist/journey-demo-cli.js.map +1 -0
- package/dist/journey-prefix.d.ts +194 -0
- package/dist/journey-prefix.js +279 -0
- package/dist/journey-prefix.js.map +1 -0
- package/dist/key-report.d.ts +49 -0
- package/dist/key-report.js +101 -0
- package/dist/key-report.js.map +1 -0
- package/dist/kill-signal.d.ts +193 -0
- package/dist/kill-signal.js +283 -0
- package/dist/kill-signal.js.map +1 -0
- package/dist/launch-armed.d.ts +37 -0
- package/dist/launch-armed.js +31 -0
- package/dist/launch-armed.js.map +1 -0
- package/dist/ledger-api.d.ts +106 -0
- package/dist/ledger-api.js +239 -0
- package/dist/ledger-api.js.map +1 -0
- package/dist/ledger-cli.d.ts +18 -0
- package/dist/ledger-cli.js +107 -0
- package/dist/ledger-cli.js.map +1 -0
- package/dist/load-api.d.ts +29 -11
- package/dist/load-api.js +23 -15
- package/dist/load-api.js.map +1 -1
- package/dist/load-cli.d.ts +4 -0
- package/dist/load-cli.js +97 -0
- package/dist/load-cli.js.map +1 -0
- package/dist/log-correlation.d.ts +200 -0
- package/dist/log-correlation.js +394 -0
- package/dist/log-correlation.js.map +1 -0
- package/dist/log-lines.d.ts +131 -0
- package/dist/log-lines.js +389 -0
- package/dist/log-lines.js.map +1 -0
- package/dist/log-sources.d.ts +71 -0
- package/dist/log-sources.js +236 -0
- package/dist/log-sources.js.map +1 -0
- package/dist/log-trace.d.ts +80 -0
- package/dist/log-trace.js +210 -0
- package/dist/log-trace.js.map +1 -0
- package/dist/logs-cli.d.ts +3 -0
- package/dist/logs-cli.js +51 -0
- package/dist/logs-cli.js.map +1 -0
- package/dist/logs-retention.d.ts +28 -0
- package/dist/logs-retention.js +85 -0
- package/dist/logs-retention.js.map +1 -0
- package/dist/masked-input.d.ts +22 -0
- package/dist/masked-input.js +99 -0
- package/dist/masked-input.js.map +1 -0
- package/dist/mcp-api.d.ts +91 -1
- package/dist/mcp-api.js +514 -18
- package/dist/mcp-api.js.map +1 -1
- package/dist/mcp-args.d.ts +50 -0
- package/dist/mcp-args.js +164 -0
- package/dist/mcp-args.js.map +1 -0
- package/dist/mcp-cli-bridge.d.ts +34 -0
- package/dist/mcp-cli-bridge.js +62 -0
- package/dist/mcp-cli-bridge.js.map +1 -0
- package/dist/mcp-cli-runner.d.ts +29 -0
- package/dist/mcp-cli-runner.js +44 -0
- package/dist/mcp-cli-runner.js.map +1 -0
- package/dist/mcp-cli-tools.d.ts +129 -0
- package/dist/mcp-cli-tools.js +737 -0
- package/dist/mcp-cli-tools.js.map +1 -0
- package/dist/mcp-paths.d.ts +28 -0
- package/dist/mcp-paths.js +76 -0
- package/dist/mcp-paths.js.map +1 -0
- package/dist/mission-actors.d.ts +40 -0
- package/dist/mission-actors.js +72 -0
- package/dist/mission-actors.js.map +1 -0
- package/dist/mission-api.d.ts +35 -0
- package/dist/mission-api.js +60 -3
- package/dist/mission-api.js.map +1 -1
- package/dist/mission-cli.d.ts +4 -0
- package/dist/mission-cli.js +248 -0
- package/dist/mission-cli.js.map +1 -0
- package/dist/mission-exit.d.ts +22 -0
- package/dist/mission-exit.js +26 -0
- package/dist/mission-exit.js.map +1 -0
- package/dist/mission-fixtures.d.ts +234 -0
- package/dist/mission-fixtures.js +862 -0
- package/dist/mission-fixtures.js.map +1 -0
- package/dist/mission-journal.d.ts +60 -0
- package/dist/mission-journal.js +115 -0
- package/dist/mission-journal.js.map +1 -0
- package/dist/mission-queue-cli.d.ts +10 -0
- package/dist/mission-queue-cli.js +198 -0
- package/dist/mission-queue-cli.js.map +1 -0
- package/dist/mission-queue-runner.d.ts +126 -0
- package/dist/mission-queue-runner.js +406 -0
- package/dist/mission-queue-runner.js.map +1 -0
- package/dist/multi-run-cli.d.ts +37 -0
- package/dist/multi-run-cli.js +116 -0
- package/dist/multi-run-cli.js.map +1 -0
- package/dist/multi-run.d.ts +339 -0
- package/dist/multi-run.js +619 -0
- package/dist/multi-run.js.map +1 -0
- package/dist/openrouter-call.d.ts +22 -0
- package/dist/openrouter-call.js +64 -0
- package/dist/openrouter-call.js.map +1 -0
- package/dist/profile-cli.d.ts +4 -0
- package/dist/profile-cli.js +57 -0
- package/dist/profile-cli.js.map +1 -0
- package/dist/program.d.ts +3 -75
- package/dist/program.js +123 -1921
- package/dist/program.js.map +1 -1
- package/dist/project-dir.d.ts +96 -0
- package/dist/project-dir.js +221 -0
- package/dist/project-dir.js.map +1 -0
- package/dist/record-api.d.ts +13 -7
- package/dist/record-api.js +44 -30
- package/dist/record-api.js.map +1 -1
- package/dist/record-cli.d.ts +4 -0
- package/dist/record-cli.js +76 -0
- package/dist/record-cli.js.map +1 -0
- package/dist/recording-cli.d.ts +4 -0
- package/dist/recording-cli.js +248 -0
- package/dist/recording-cli.js.map +1 -0
- package/dist/regression-api.d.ts +107 -0
- package/dist/regression-api.js +387 -6
- package/dist/regression-api.js.map +1 -1
- package/dist/regression-cli.d.ts +4 -0
- package/dist/regression-cli.js +284 -0
- package/dist/regression-cli.js.map +1 -0
- package/dist/report-api.d.ts +146 -0
- package/dist/report-api.js +431 -0
- package/dist/report-api.js.map +1 -0
- package/dist/report-cli.d.ts +12 -0
- package/dist/report-cli.js +147 -0
- package/dist/report-cli.js.map +1 -0
- package/dist/resource-preflight.d.ts +87 -0
- package/dist/resource-preflight.js +160 -0
- package/dist/resource-preflight.js.map +1 -0
- package/dist/result-schema.d.ts +22 -0
- package/dist/result-schema.js +28 -0
- package/dist/result-schema.js.map +1 -0
- package/dist/run-index.d.ts +29 -0
- package/dist/run-index.js +70 -0
- package/dist/run-index.js.map +1 -0
- package/dist/run-key-preflight.d.ts +42 -0
- package/dist/run-key-preflight.js +82 -0
- package/dist/run-key-preflight.js.map +1 -0
- package/dist/run-screenshots.d.ts +123 -0
- package/dist/run-screenshots.js +235 -0
- package/dist/run-screenshots.js.map +1 -0
- package/dist/runtime-env.d.ts +8 -0
- package/dist/runtime-env.js +23 -0
- package/dist/runtime-env.js.map +1 -0
- package/dist/secret-args.d.ts +23 -0
- package/dist/secret-args.js +45 -0
- package/dist/secret-args.js.map +1 -0
- package/dist/serve-cli.d.ts +4 -0
- package/dist/serve-cli.js +95 -0
- package/dist/serve-cli.js.map +1 -0
- package/dist/server-log-verify.d.ts +36 -0
- package/dist/server-log-verify.js +120 -0
- package/dist/server-log-verify.js.map +1 -0
- package/dist/session-check.d.ts +14 -0
- package/dist/session-check.js +44 -0
- package/dist/session-check.js.map +1 -0
- package/dist/site-cli.d.ts +4 -0
- package/dist/site-cli.js +127 -0
- package/dist/site-cli.js.map +1 -0
- package/dist/site-gate-cli.d.ts +28 -0
- package/dist/site-gate-cli.js +59 -0
- package/dist/site-gate-cli.js.map +1 -0
- package/dist/source-api.js +20 -4
- package/dist/source-api.js.map +1 -1
- package/dist/source-cli.d.ts +4 -0
- package/dist/source-cli.js +284 -0
- package/dist/source-cli.js.map +1 -0
- package/dist/source-run-api.d.ts +27 -1
- package/dist/source-run-api.js +22 -11
- package/dist/source-run-api.js.map +1 -1
- package/dist/storage-state-snapshot.d.ts +50 -0
- package/dist/storage-state-snapshot.js +87 -0
- package/dist/storage-state-snapshot.js.map +1 -0
- package/dist/suite-explore-options.d.ts +321 -0
- package/dist/suite-explore-options.js +162 -0
- package/dist/suite-explore-options.js.map +1 -0
- package/dist/target-config.d.ts +115 -0
- package/dist/target-config.js +225 -0
- package/dist/target-config.js.map +1 -0
- package/dist/transcript-file.d.ts +12 -0
- package/dist/transcript-file.js +23 -0
- package/dist/transcript-file.js.map +1 -0
- package/dist/type-fixture-file.d.ts +9 -0
- package/dist/type-fixture-file.js +48 -0
- package/dist/type-fixture-file.js.map +1 -0
- package/dist/ui-api.d.ts +3 -0
- package/dist/ui-api.js +11 -4
- package/dist/ui-api.js.map +1 -1
- package/dist/usability-capture.d.ts +43 -0
- package/dist/usability-capture.js +327 -0
- package/dist/usability-capture.js.map +1 -0
- package/dist/usage-config.d.ts +36 -0
- package/dist/usage-config.js +114 -0
- package/dist/usage-config.js.map +1 -0
- package/dist/ux-api.d.ts +3 -75
- package/dist/ux-api.js +3 -220
- package/dist/ux-api.js.map +1 -1
- package/dist/ux-claim-probe.d.ts +45 -0
- package/dist/ux-claim-probe.js +386 -0
- package/dist/ux-claim-probe.js.map +1 -0
- package/dist/ux-cli.d.ts +4 -0
- package/dist/ux-cli.js +109 -0
- package/dist/ux-cli.js.map +1 -0
- package/dist/ux-config.d.ts +29 -0
- package/dist/ux-config.js +103 -0
- package/dist/ux-config.js.map +1 -0
- package/dist/ux-evidence.d.ts +54 -0
- package/dist/ux-evidence.js +197 -0
- package/dist/ux-evidence.js.map +1 -0
- package/dist/ux-product.d.ts +14 -0
- package/dist/ux-product.js +39 -0
- package/dist/ux-product.js.map +1 -0
- package/dist/ux-review.d.ts +116 -0
- package/dist/ux-review.js +171 -0
- package/dist/ux-review.js.map +1 -0
- package/dist/ux-usability.d.ts +263 -0
- package/dist/ux-usability.js +580 -0
- package/dist/ux-usability.js.map +1 -0
- package/dist/verify-fix-api.d.ts +194 -0
- package/dist/verify-fix-api.js +506 -0
- package/dist/verify-fix-api.js.map +1 -0
- package/dist/verify-fix-cli.d.ts +4 -0
- package/dist/verify-fix-cli.js +115 -0
- package/dist/verify-fix-cli.js.map +1 -0
- package/package.json +23 -18
- package/skills/jevitate-ci-check/SKILL.md +77 -0
- package/skills/jevitate-demo/SKILL.md +61 -0
- package/skills/jevitate-explore/SKILL.md +96 -87
- package/skills/jevitate-getting-started/SKILL.md +89 -0
- package/skills/jevitate-load-test/SKILL.md +11 -2
- package/skills/jevitate-mission-scope/SKILL.md +19 -11
- package/skills/jevitate-record/SKILL.md +23 -5
- package/skills/jevitate-run-journey/SKILL.md +61 -17
- package/skills/jevitate-sources/SKILL.md +57 -14
- package/skills/jevitate-test-campaign/SKILL.md +203 -0
- package/skills/jevitate-ux-review/SKILL.md +106 -16
- package/skills/jevitate-verify-fix/SKILL.md +76 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { DEFAULT_JEVITATE_REPO, fileDraft, } from "@jevitate/domain";
|
|
4
|
+
import { resolveDataDir } from "./data-dir.js";
|
|
5
|
+
export class FilingConfigError extends Error {
|
|
6
|
+
code = "E_FILING_CONFIG";
|
|
7
|
+
}
|
|
8
|
+
const REPO = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;
|
|
9
|
+
/** `owner/name`, or a config error — a malformed repo is never silently used. */
|
|
10
|
+
export function assertRepo(repo, where) {
|
|
11
|
+
if (!REPO.test(repo))
|
|
12
|
+
throw new FilingConfigError(`${where}: ${JSON.stringify(repo)} is not an owner/name repo`);
|
|
13
|
+
return repo;
|
|
14
|
+
}
|
|
15
|
+
/** Reads `~/.jevitate/filing.json`; a missing file is "no filing config". Anything malformed fails closed. */
|
|
16
|
+
export function loadFilingFileConfig(path = resolveDataDir(["filing.json"])) {
|
|
17
|
+
let raw;
|
|
18
|
+
try {
|
|
19
|
+
raw = readFileSync(path, "utf8");
|
|
20
|
+
}
|
|
21
|
+
catch (e) {
|
|
22
|
+
if (typeof e === "object" && e !== null && "code" in e && e.code === "ENOENT")
|
|
23
|
+
return {};
|
|
24
|
+
throw new FilingConfigError(`cannot read ${path}: ${e instanceof Error ? e.message : String(e)}`);
|
|
25
|
+
}
|
|
26
|
+
let parsed;
|
|
27
|
+
try {
|
|
28
|
+
parsed = JSON.parse(raw);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
throw new FilingConfigError(`${path} is not valid JSON`);
|
|
32
|
+
}
|
|
33
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
34
|
+
throw new FilingConfigError(`${path} must be a JSON object`);
|
|
35
|
+
}
|
|
36
|
+
const o = parsed;
|
|
37
|
+
const out = {};
|
|
38
|
+
if (o.enabled !== undefined) {
|
|
39
|
+
if (typeof o.enabled !== "boolean")
|
|
40
|
+
throw new FilingConfigError(`${path}: enabled must be a boolean`);
|
|
41
|
+
out.enabled = o.enabled;
|
|
42
|
+
}
|
|
43
|
+
if (o.jevitateRepo !== undefined) {
|
|
44
|
+
if (typeof o.jevitateRepo !== "string")
|
|
45
|
+
throw new FilingConfigError(`${path}: jevitateRepo must be a string`);
|
|
46
|
+
out.jevitateRepo = assertRepo(o.jevitateRepo, `${path} jevitateRepo`);
|
|
47
|
+
}
|
|
48
|
+
if (o.targets !== undefined) {
|
|
49
|
+
if (o.targets === null || typeof o.targets !== "object" || Array.isArray(o.targets)) {
|
|
50
|
+
throw new FilingConfigError(`${path}: targets must be an object keyed by origin`);
|
|
51
|
+
}
|
|
52
|
+
const targets = {};
|
|
53
|
+
for (const [origin, v] of Object.entries(o.targets)) {
|
|
54
|
+
const repo = v !== null && typeof v === "object" && "repo" in v ? v.repo : undefined;
|
|
55
|
+
if (typeof repo !== "string")
|
|
56
|
+
throw new FilingConfigError(`${path}: targets[${origin}].repo must be a string`);
|
|
57
|
+
targets[origin] = { repo: assertRepo(repo, `${path} targets[${origin}]`) };
|
|
58
|
+
}
|
|
59
|
+
out.targets = targets;
|
|
60
|
+
}
|
|
61
|
+
return out;
|
|
62
|
+
}
|
|
63
|
+
/** Flags win over the file; the target repo is looked up by the run's origin. */
|
|
64
|
+
export function resolveFilingConfig(file, flags, targetOrigin) {
|
|
65
|
+
const targetRepo = flags.issueRepo ?? file.targets?.[targetOrigin]?.repo;
|
|
66
|
+
return {
|
|
67
|
+
enabled: flags.fileIssues ?? file.enabled ?? false,
|
|
68
|
+
jevitateRepo: assertRepo(flags.jevitateRepo ?? file.jevitateRepo ?? DEFAULT_JEVITATE_REPO, "jevitate repo"),
|
|
69
|
+
...(targetRepo === undefined ? {} : { targetRepo: assertRepo(targetRepo, "issue repo") }),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/** `<dir>/<stem>.json` → `<dir>/<stem>.issues/`. */
|
|
73
|
+
export function issuesDirFor(recordingPath) {
|
|
74
|
+
return recordingPath.endsWith(".json") ? `${recordingPath.slice(0, -".json".length)}.issues` : `${recordingPath}.issues`;
|
|
75
|
+
}
|
|
76
|
+
/** Writes each draft as `<fingerprint>.md` (title heading + body) next to the Recording. */
|
|
77
|
+
export function writeIssueDrafts(recordingPath, drafts) {
|
|
78
|
+
if (drafts.length === 0)
|
|
79
|
+
return [];
|
|
80
|
+
const dir = issuesDirFor(recordingPath);
|
|
81
|
+
mkdirSync(dir, { recursive: true });
|
|
82
|
+
return drafts.map((d) => {
|
|
83
|
+
const path = join(dir, `${d.fingerprint}.md`);
|
|
84
|
+
writeFileSync(path, `# ${d.title}\n\n${d.body}\n`, "utf8");
|
|
85
|
+
return { fingerprint: d.fingerprint, title: d.title, attribution: d.attribution, targets: d.targets, labels: d.labels, path };
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Writes every draft, then files them per the config. The filer is created ONLY when filing is
|
|
90
|
+
* enabled (so a disabled run never even looks for `gh` or a token).
|
|
91
|
+
*/
|
|
92
|
+
export async function processIssueDrafts(recordingPath, drafts, config, makeFiler, nowIso) {
|
|
93
|
+
const written = writeIssueDrafts(recordingPath, drafts);
|
|
94
|
+
const filing = [];
|
|
95
|
+
const filer = config.enabled && drafts.length > 0 ? makeFiler() : null;
|
|
96
|
+
for (const d of drafts) {
|
|
97
|
+
const outcomes = filer === null
|
|
98
|
+
? d.targets.map((target) => ({
|
|
99
|
+
target,
|
|
100
|
+
status: "draft-only",
|
|
101
|
+
reason: config.enabled ? "no filer" : "filing is disabled",
|
|
102
|
+
}))
|
|
103
|
+
: await fileDraft(filer, d, config, nowIso);
|
|
104
|
+
filing.push({ fingerprint: d.fingerprint, outcomes });
|
|
105
|
+
}
|
|
106
|
+
return { drafts: written, filing };
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=findings-filing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"findings-filing.js","sourceRoot":"","sources":["../src/findings-filing.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session-derived request auth for code-issued HTTP calls (mission fixtures, #140/#144) — the
|
|
3
|
+
* "#135-style" helper: authenticate a request exactly as the app's own page would, from the run's
|
|
4
|
+
* `--storage-state` (a bearer token the SPA keeps in localStorage, or the session cookies) or from a
|
|
5
|
+
* `--secret-field` binding. No browser is needed: the storageState JSON already holds what the page
|
|
6
|
+
* would read.
|
|
7
|
+
*
|
|
8
|
+
* Every value this module returns is a credential. Callers put it on the wire and NOWHERE else — it
|
|
9
|
+
* never reaches a model, a log line or an artifact (fixture step logs never include request headers).
|
|
10
|
+
*
|
|
11
|
+
* NOTE (coordination): #135 (authenticated invariant probes) needs the same thing; if it lands its
|
|
12
|
+
* own helper, fold one into the other.
|
|
13
|
+
*/
|
|
14
|
+
export type RequestAuth =
|
|
15
|
+
/**
|
|
16
|
+
* `<header>: <scheme> <localStorage[key]>` for the request's origin (default `Authorization: Bearer`).
|
|
17
|
+
* `identity` (#243): read from that named fixture identity's storageState, not the mission's.
|
|
18
|
+
*/
|
|
19
|
+
{
|
|
20
|
+
readonly from: "localStorage";
|
|
21
|
+
readonly key: string;
|
|
22
|
+
readonly scheme?: string;
|
|
23
|
+
readonly header?: string;
|
|
24
|
+
readonly identity?: string;
|
|
25
|
+
}
|
|
26
|
+
/** The storageState cookies that match the request URL, as a `Cookie` header (`identity`: as above). */
|
|
27
|
+
| {
|
|
28
|
+
readonly from: "cookies";
|
|
29
|
+
readonly identity?: string;
|
|
30
|
+
}
|
|
31
|
+
/** `<header>: <scheme> <value>` from a `--secret-field` binding, named by its env variable. */
|
|
32
|
+
| {
|
|
33
|
+
readonly from: "secretField";
|
|
34
|
+
readonly name: string;
|
|
35
|
+
readonly scheme?: string;
|
|
36
|
+
readonly header?: string;
|
|
37
|
+
};
|
|
38
|
+
export interface AuthSources {
|
|
39
|
+
/** Path of the run's Playwright storageState JSON (`--storage-state`). */
|
|
40
|
+
readonly storageStatePath?: string;
|
|
41
|
+
/** `--secret-field` values by their env-variable name. */
|
|
42
|
+
readonly secretFields?: Readonly<Record<string, string>>;
|
|
43
|
+
/**
|
|
44
|
+
* #243: named fixture identities → their storageState PATH (`--fixture-identity <name>=<file>` or a
|
|
45
|
+
* targets.json persona). A step with `auth.identity` authenticates from that file only — never from
|
|
46
|
+
* the mission's own `--storage-state`, so the mission can run as someone else (or cold).
|
|
47
|
+
*/
|
|
48
|
+
readonly identities?: Readonly<Record<string, string>>;
|
|
49
|
+
}
|
|
50
|
+
export declare class FixtureAuthError extends Error {
|
|
51
|
+
constructor(message: string);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* A storageState file's `localStorage[key]` for `origin` (or null) — the same lookup `authHeaders`
|
|
55
|
+
* does for its `localStorage` source, exposed on its own for #173: an observer's cross-actor probe
|
|
56
|
+
* authenticates from its OWN storageState file this way, with no browser and no navigation needed.
|
|
57
|
+
*/
|
|
58
|
+
export declare function localStorageValue(storageStatePath: string, origin: string, key: string): string | null;
|
|
59
|
+
/**
|
|
60
|
+
* The header(s) `auth` adds to a request to `url`. Throws `FixtureAuthError` (naming the source,
|
|
61
|
+
* never a value) when the source is missing — a fixture never silently runs unauthenticated.
|
|
62
|
+
*/
|
|
63
|
+
export declare function authHeaders(auth: RequestAuth, url: string, sources: AuthSources): Record<string, string>;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { clock } from "@jevitate/domain";
|
|
3
|
+
export class FixtureAuthError extends Error {
|
|
4
|
+
constructor(message) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = "FixtureAuthError";
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
function readStorageState(path) {
|
|
10
|
+
let raw;
|
|
11
|
+
try {
|
|
12
|
+
raw = JSON.parse(readFileSync(path, "utf8"));
|
|
13
|
+
}
|
|
14
|
+
catch (e) {
|
|
15
|
+
// The message names the file only: its contents are credentials.
|
|
16
|
+
throw new FixtureAuthError(`cannot read storage state ${path}: ${e instanceof SyntaxError ? "not valid JSON" : "unreadable"}`);
|
|
17
|
+
}
|
|
18
|
+
const o = (raw ?? {});
|
|
19
|
+
const cookies = Array.isArray(o.cookies) ? o.cookies.filter((c) => typeof c?.name === "string" && typeof c.value === "string" && typeof c.domain === "string") : [];
|
|
20
|
+
const origins = Array.isArray(o.origins)
|
|
21
|
+
? o.origins.filter((x) => typeof x?.origin === "string" && Array.isArray(x.localStorage))
|
|
22
|
+
: [];
|
|
23
|
+
return { cookies, origins };
|
|
24
|
+
}
|
|
25
|
+
const LOOPBACK = new Set(["localhost", "127.0.0.1", "[::1]"]);
|
|
26
|
+
function cookieMatches(c, url, nowSec) {
|
|
27
|
+
const domain = c.domain.startsWith(".") ? c.domain.slice(1) : c.domain;
|
|
28
|
+
const host = url.hostname;
|
|
29
|
+
if (host !== domain && !(c.domain.startsWith(".") && host.endsWith(`.${domain}`)))
|
|
30
|
+
return false;
|
|
31
|
+
const path = c.path ?? "/";
|
|
32
|
+
if (!url.pathname.startsWith(path))
|
|
33
|
+
return false;
|
|
34
|
+
if (c.secure === true && url.protocol !== "https:" && !LOOPBACK.has(host))
|
|
35
|
+
return false;
|
|
36
|
+
if (typeof c.expires === "number" && c.expires > 0 && c.expires < nowSec)
|
|
37
|
+
return false;
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
function whose(auth) {
|
|
41
|
+
return auth.identity === undefined ? "the storage state" : `fixture identity ${auth.identity}'s storage state`;
|
|
42
|
+
}
|
|
43
|
+
function withScheme(scheme, value, fallback) {
|
|
44
|
+
const s = scheme ?? fallback;
|
|
45
|
+
return s === "" ? value : `${s} ${value}`;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* A storageState file's `localStorage[key]` for `origin` (or null) — the same lookup `authHeaders`
|
|
49
|
+
* does for its `localStorage` source, exposed on its own for #173: an observer's cross-actor probe
|
|
50
|
+
* authenticates from its OWN storageState file this way, with no browser and no navigation needed.
|
|
51
|
+
*/
|
|
52
|
+
export function localStorageValue(storageStatePath, origin, key) {
|
|
53
|
+
const state = readStorageState(storageStatePath);
|
|
54
|
+
return state.origins.find((o) => o.origin === origin)?.localStorage.find((i) => i.name === key)?.value ?? null;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The header(s) `auth` adds to a request to `url`. Throws `FixtureAuthError` (naming the source,
|
|
58
|
+
* never a value) when the source is missing — a fixture never silently runs unauthenticated.
|
|
59
|
+
*/
|
|
60
|
+
export function authHeaders(auth, url, sources) {
|
|
61
|
+
const target = new URL(url);
|
|
62
|
+
if (auth.from === "secretField") {
|
|
63
|
+
const value = sources.secretFields?.[auth.name];
|
|
64
|
+
if (value === undefined || value === "") {
|
|
65
|
+
throw new FixtureAuthError(`auth needs the --secret-field bound to env:${auth.name}, which this run does not have`);
|
|
66
|
+
}
|
|
67
|
+
return { [auth.header ?? "authorization"]: withScheme(auth.scheme, value, "Bearer") };
|
|
68
|
+
}
|
|
69
|
+
let statePath;
|
|
70
|
+
if (auth.identity !== undefined) {
|
|
71
|
+
statePath = sources.identities?.[auth.identity];
|
|
72
|
+
if (statePath === undefined) {
|
|
73
|
+
throw new FixtureAuthError(`auth.identity ${auth.identity} is not bound: pass --fixture-identity ${auth.identity}=<storageState> or declare personas.${auth.identity}.storageState for this origin in targets.json`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
statePath = sources.storageStatePath;
|
|
78
|
+
if (statePath === undefined)
|
|
79
|
+
throw new FixtureAuthError(`auth from ${auth.from} needs --storage-state (or an auth.identity)`);
|
|
80
|
+
}
|
|
81
|
+
const state = readStorageState(statePath);
|
|
82
|
+
if (auth.from === "cookies") {
|
|
83
|
+
const nowSec = clock.now() / 1000;
|
|
84
|
+
const jar = state.cookies.filter((c) => cookieMatches(c, target, nowSec));
|
|
85
|
+
if (jar.length === 0)
|
|
86
|
+
throw new FixtureAuthError(`${whose(auth)} has no cookie for ${target.origin}`);
|
|
87
|
+
return { cookie: jar.map((c) => `${c.name}=${c.value}`).join("; ") };
|
|
88
|
+
}
|
|
89
|
+
const entry = state.origins.find((o) => o.origin === target.origin)?.localStorage.find((i) => i.name === auth.key);
|
|
90
|
+
if (entry === undefined || entry.value === "") {
|
|
91
|
+
throw new FixtureAuthError(`${whose(auth)} has no localStorage "${auth.key}" for ${target.origin}`);
|
|
92
|
+
}
|
|
93
|
+
return { [auth.header ?? "authorization"]: withScheme(auth.scheme, entry.value, "Bearer") };
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=fixture-auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixture-auth.js","sourceRoot":"","sources":["../src/fixture-auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import type { MissionFailure } from "@jevitate/domain";
|
|
3
|
+
import type { SecretField } from "@jevitate/explore";
|
|
4
|
+
import { FixtureSetupError, MissionFixtures, UnboundSetupRefError, type FixtureBindings, type FixtureRecord, type FixtureSpec } from "./mission-fixtures.js";
|
|
5
|
+
/**
|
|
6
|
+
* The CLI side of mission fixtures (#140/#144): the shared flags, building the lifecycle from them
|
|
7
|
+
* (or from a target's `fixtures` in `~/.jevitate/targets.json`), the static `${setup.x}` checks that
|
|
8
|
+
* run before any browser or request, and the `inconclusive` result a failed setup ends a run with.
|
|
9
|
+
*/
|
|
10
|
+
export interface FixtureFlags {
|
|
11
|
+
readonly fixtures?: string;
|
|
12
|
+
readonly before?: string;
|
|
13
|
+
readonly after?: string;
|
|
14
|
+
readonly allowShellHooks?: boolean;
|
|
15
|
+
readonly hookTimeoutMs?: string;
|
|
16
|
+
/** #243: `--fixture-identity <name>=<storageState>` (repeatable) — who a step with `auth.identity` authenticates as. */
|
|
17
|
+
readonly fixtureIdentity?: readonly string[];
|
|
18
|
+
}
|
|
19
|
+
/** Adds `--fixtures`, `--before`, `--after`, `--allow-shell-hooks` and `--hook-timeout-ms`. */
|
|
20
|
+
export declare function withFixtureFlags(cmd: Command): Command;
|
|
21
|
+
export interface FixtureContext {
|
|
22
|
+
readonly allowlist: readonly string[];
|
|
23
|
+
readonly baseUrl: string;
|
|
24
|
+
readonly storageState?: string;
|
|
25
|
+
readonly secretFields?: readonly SecretField[];
|
|
26
|
+
readonly secrets?: readonly string[];
|
|
27
|
+
/** A target's own fixtures file (`~/.jevitate/targets.json`), used when `--fixtures` is absent. */
|
|
28
|
+
readonly targetFixtures?: string;
|
|
29
|
+
/** A spec already validated elsewhere (a persisted mission result), used when no file is given. */
|
|
30
|
+
readonly spec?: FixtureSpec;
|
|
31
|
+
/**
|
|
32
|
+
* #243: the origin's targets.json personas — `personas.<name>.storageState` binds fixture identity
|
|
33
|
+
* `<name>` when no `--fixture-identity` names it.
|
|
34
|
+
*/
|
|
35
|
+
readonly personas?: Readonly<Record<string, {
|
|
36
|
+
readonly storageState?: string;
|
|
37
|
+
}>>;
|
|
38
|
+
/** #243: identities a persisted mission result recorded (name → storageState path), for replays. */
|
|
39
|
+
readonly identities?: Readonly<Record<string, string>>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* #243: every fixture identity the run can authenticate a step as → its storageState PATH. Lowest to
|
|
43
|
+
* highest precedence: the origin's targets.json personas, the identities a persisted result recorded,
|
|
44
|
+
* then `--fixture-identity`. Only paths are kept (the file is read per request, never logged); a
|
|
45
|
+
* missing file is refused here, before any browser or request.
|
|
46
|
+
*/
|
|
47
|
+
export declare function resolveFixtureIdentities(flags: FixtureFlags, ctx: Pick<FixtureContext, "personas" | "identities">, cwd?: string): Record<string, string>;
|
|
48
|
+
/** The run's fixture lifecycle, or `undefined` when none was asked for. Throws `FixtureSpecError`. */
|
|
49
|
+
export declare function buildMissionFixtures(flags: FixtureFlags, ctx: FixtureContext): MissionFixtures | undefined;
|
|
50
|
+
/**
|
|
51
|
+
* Before any browser or request: every `${setup.x}` in `texts` must be an output the fixture
|
|
52
|
+
* declares (unless a `--before` hook may bind it), and a run without fixtures may not reference one.
|
|
53
|
+
*/
|
|
54
|
+
export declare function checkSetupRefs(texts: Readonly<Record<string, string | readonly string[] | undefined>>, fx: MissionFixtures | undefined): void;
|
|
55
|
+
/**
|
|
56
|
+
* `url` with each `${setup.*}` replaced by a placeholder that keeps its origin — what the run's
|
|
57
|
+
* origin, allowlist and target config are read from before setup binds the real values.
|
|
58
|
+
*/
|
|
59
|
+
export declare function setupRefFreeUrl(url: string): string;
|
|
60
|
+
/** Throws unless a `${setup.*}` reference in `url` leaves its origin fixed (the allowlist is decided before setup runs). */
|
|
61
|
+
export declare function checkUrlRefOrigin(url: string): void;
|
|
62
|
+
/**
|
|
63
|
+
* `--url` with its `${setup.*}` references bound — and the bound URL still on the origin
|
|
64
|
+
* {@link checkUrlRefOrigin} fixed: a value placed right after the origin must be a root-relative path
|
|
65
|
+
* (`/…`), never `@evil.test`, `:8080` or `.evil.test`.
|
|
66
|
+
*/
|
|
67
|
+
export declare function substituteUrlSetupRefs(url: string, b: FixtureBindings): string;
|
|
68
|
+
/** The `${setup.*}`-bearing strings of an invariants spec, keyed `--invariants <path>`, for {@link checkSetupRefs}. */
|
|
69
|
+
export declare function invariantSetupTexts(spec: unknown): Record<string, string>;
|
|
70
|
+
/**
|
|
71
|
+
* `${setup.x}` in an invariants spec (#187) — probe paths, `deniedAs.open`, capture routes — bound
|
|
72
|
+
* once setup ran. Origin-fixed like a fixture step: a bound value that moves a string off the origin
|
|
73
|
+
* it resolved to with the reference unfilled (`//evil.test/…`) is refused, never probed.
|
|
74
|
+
*/
|
|
75
|
+
export declare function substituteSpecSetupRefs<T>(spec: T, b: FixtureBindings, baseUrl: string): T;
|
|
76
|
+
/** The typed result a run ends with when its fixture could not be set up: `inconclusive`, a configuration error. */
|
|
77
|
+
export interface FixtureSetupFailedResult {
|
|
78
|
+
readonly outcome: "inconclusive";
|
|
79
|
+
readonly reason: string;
|
|
80
|
+
readonly failure: MissionFailure;
|
|
81
|
+
readonly attribution: "configuration";
|
|
82
|
+
readonly exitCode: 2;
|
|
83
|
+
readonly fixtures: FixtureRecord;
|
|
84
|
+
}
|
|
85
|
+
export declare function fixtureSetupFailedResult(err: FixtureSetupError | UnboundSetupRefError, fx: MissionFixtures): FixtureSetupFailedResult;
|
|
86
|
+
/**
|
|
87
|
+
* Regression capture (#144): every reproduce/minimize replay restores + re-runs the fixture the
|
|
88
|
+
* failing Recording was made from. The spec is `--fixtures`, else the one saved in `--result`
|
|
89
|
+
* (re-validated against that mission's allowlist); shell hooks must be re-supplied (and match the
|
|
90
|
+
* mission's by hash). A Recording that carries a fixture identity is never replayed without one.
|
|
91
|
+
*/
|
|
92
|
+
export declare function regressionFixtures(flags: FixtureFlags, recording: {
|
|
93
|
+
readonly site: string;
|
|
94
|
+
readonly fixture?: {
|
|
95
|
+
readonly identity: string;
|
|
96
|
+
};
|
|
97
|
+
}, missionResult: unknown,
|
|
98
|
+
/** `--storage-state` (#129): wins over the one recorded with the mission. */
|
|
99
|
+
storageState?: string): MissionFixtures | undefined;
|