@prismatic-io/lux 0.0.2-preview.14 → 0.0.2-preview.16
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/lib/answerers/claude-code/index.d.ts +14 -2
- package/lib/answerers/claude-code/index.d.ts.map +1 -1
- package/lib/answerers/claude-code/index.js +3 -3
- package/lib/answerers/claude-code/index.js.map +1 -1
- package/lib/answerers/persona/index.d.ts +28 -2
- package/lib/answerers/persona/index.d.ts.map +1 -1
- package/lib/answerers/persona/index.js +3 -3
- package/lib/answerers/persona/index.js.map +1 -1
- package/lib/answerers/terminal/index.d.ts +8 -2
- package/lib/answerers/terminal/index.d.ts.map +1 -1
- package/lib/answerers/terminal/index.js +3 -2
- package/lib/answerers/terminal/index.js.map +1 -1
- package/lib/assertions/core/resource-checks.d.ts.map +1 -1
- package/lib/assertions/core/resource-checks.js +3 -5
- package/lib/assertions/core/resource-checks.js.map +1 -1
- package/lib/assertions/rubric/index.d.ts.map +1 -1
- package/lib/assertions/rubric/index.js +7 -1
- package/lib/assertions/rubric/index.js.map +1 -1
- package/lib/assertions/rubric/internal.d.ts +16 -5
- package/lib/assertions/rubric/internal.d.ts.map +1 -1
- package/lib/assertions/rubric/internal.js +10 -6
- package/lib/assertions/rubric/internal.js.map +1 -1
- package/lib/authoring.d.ts +32 -2
- package/lib/authoring.d.ts.map +1 -1
- package/lib/authoring.js +33 -1
- package/lib/authoring.js.map +1 -1
- package/lib/cli/bin.js +2 -13
- package/lib/cli/bin.js.map +1 -1
- package/lib/cli/command-runtime.d.ts +3 -3
- package/lib/cli/command-runtime.d.ts.map +1 -1
- package/lib/cli/command-runtime.js +17 -6
- package/lib/cli/command-runtime.js.map +1 -1
- package/lib/cli/init-templates.d.ts +11 -0
- package/lib/cli/init-templates.d.ts.map +1 -0
- package/lib/cli/init-templates.js +207 -0
- package/lib/cli/init-templates.js.map +1 -0
- package/lib/cli/init.d.ts +7 -0
- package/lib/cli/init.d.ts.map +1 -1
- package/lib/cli/init.js +23 -173
- package/lib/cli/init.js.map +1 -1
- package/lib/cli/output-schemas.d.ts +1399 -0
- package/lib/cli/output-schemas.d.ts.map +1 -0
- package/lib/cli/output-schemas.js +91 -0
- package/lib/cli/output-schemas.js.map +1 -0
- package/lib/cli/program.d.ts +135 -4
- package/lib/cli/program.d.ts.map +1 -1
- package/lib/cli/program.js +725 -520
- package/lib/cli/program.js.map +1 -1
- package/lib/cli/render/reporter.d.ts.map +1 -1
- package/lib/cli/render/reporter.js +24 -4
- package/lib/cli/render/reporter.js.map +1 -1
- package/lib/cli/run-options.d.ts +0 -4
- package/lib/cli/run-options.d.ts.map +1 -1
- package/lib/cli/run-options.js +8 -19
- package/lib/cli/run-options.js.map +1 -1
- package/lib/cli/view.d.ts +5 -3
- package/lib/cli/view.d.ts.map +1 -1
- package/lib/cli/view.js +120 -78
- package/lib/cli/view.js.map +1 -1
- package/lib/core/annotation.d.ts +6 -2
- package/lib/core/annotation.d.ts.map +1 -1
- package/lib/core/annotation.js +2 -1
- package/lib/core/annotation.js.map +1 -1
- package/lib/core/answerer.d.ts +12 -0
- package/lib/core/answerer.d.ts.map +1 -1
- package/lib/core/answerer.js +2 -0
- package/lib/core/answerer.js.map +1 -1
- package/lib/core/assertion.d.ts +3 -0
- package/lib/core/assertion.d.ts.map +1 -1
- package/lib/core/assertion.js +3 -0
- package/lib/core/assertion.js.map +1 -1
- package/lib/core/case.d.ts +24 -2
- package/lib/core/case.d.ts.map +1 -1
- package/lib/core/case.js +5 -1
- package/lib/core/case.js.map +1 -1
- package/lib/core/driver.d.ts +40 -0
- package/lib/core/driver.d.ts.map +1 -1
- package/lib/core/driver.js +12 -0
- package/lib/core/driver.js.map +1 -1
- package/lib/core/environment.d.ts +18 -0
- package/lib/core/environment.d.ts.map +1 -0
- package/lib/core/environment.js +21 -0
- package/lib/core/environment.js.map +1 -0
- package/lib/core/evaluation-clusters.d.ts +17 -0
- package/lib/core/evaluation-clusters.d.ts.map +1 -0
- package/lib/core/evaluation-clusters.js +23 -0
- package/lib/core/evaluation-clusters.js.map +1 -0
- package/lib/core/experiment.d.ts +11 -0
- package/lib/core/experiment.d.ts.map +1 -1
- package/lib/core/experiment.js +31 -17
- package/lib/core/experiment.js.map +1 -1
- package/lib/core/file-tree.d.ts +7 -0
- package/lib/core/file-tree.d.ts.map +1 -0
- package/lib/core/file-tree.js +35 -0
- package/lib/core/file-tree.js.map +1 -0
- package/lib/core/index.d.ts +1 -0
- package/lib/core/index.d.ts.map +1 -1
- package/lib/core/index.js +1 -0
- package/lib/core/index.js.map +1 -1
- package/lib/core/lifecycle-fixtures.d.ts.map +1 -1
- package/lib/core/lifecycle-fixtures.js +4 -2
- package/lib/core/lifecycle-fixtures.js.map +1 -1
- package/lib/core/platform-process.d.ts +5 -1
- package/lib/core/platform-process.d.ts.map +1 -1
- package/lib/core/platform-process.js +48 -10
- package/lib/core/platform-process.js.map +1 -1
- package/lib/core/run.d.ts +93 -1
- package/lib/core/run.d.ts.map +1 -1
- package/lib/core/run.js +16 -0
- package/lib/core/run.js.map +1 -1
- package/lib/core/usage.d.ts +5 -0
- package/lib/core/usage.d.ts.map +1 -1
- package/lib/core/usage.js +3 -0
- package/lib/core/usage.js.map +1 -1
- package/lib/drivers/claude-code/index.d.ts +65 -2
- package/lib/drivers/claude-code/index.d.ts.map +1 -1
- package/lib/drivers/claude-code/index.js +30 -3
- package/lib/drivers/claude-code/index.js.map +1 -1
- package/lib/drivers/codex/app-events.d.ts.map +1 -1
- package/lib/drivers/codex/app-events.js +41 -30
- package/lib/drivers/codex/app-events.js.map +1 -1
- package/lib/drivers/codex/exec-events.d.ts +4 -0
- package/lib/drivers/codex/exec-events.d.ts.map +1 -0
- package/lib/drivers/codex/exec-events.js +230 -0
- package/lib/drivers/codex/exec-events.js.map +1 -0
- package/lib/drivers/codex/index.d.ts +76 -4
- package/lib/drivers/codex/index.d.ts.map +1 -1
- package/lib/drivers/codex/index.js +35 -232
- package/lib/drivers/codex/index.js.map +1 -1
- package/lib/drivers/cursor/acp-transport.d.ts +38 -0
- package/lib/drivers/cursor/acp-transport.d.ts.map +1 -0
- package/lib/drivers/cursor/acp-transport.js +152 -0
- package/lib/drivers/cursor/acp-transport.js.map +1 -0
- package/lib/drivers/cursor/config.d.ts +22 -0
- package/lib/drivers/cursor/config.d.ts.map +1 -0
- package/lib/drivers/cursor/config.js +26 -0
- package/lib/drivers/cursor/config.js.map +1 -0
- package/lib/drivers/cursor/events.d.ts +13 -0
- package/lib/drivers/cursor/events.d.ts.map +1 -0
- package/lib/drivers/cursor/events.js +73 -0
- package/lib/drivers/cursor/events.js.map +1 -0
- package/lib/drivers/cursor/index.d.ts +37 -0
- package/lib/drivers/cursor/index.d.ts.map +1 -0
- package/lib/drivers/cursor/index.js +276 -0
- package/lib/drivers/cursor/index.js.map +1 -0
- package/lib/drivers/cursor/interaction.d.ts +7 -0
- package/lib/drivers/cursor/interaction.d.ts.map +1 -0
- package/lib/drivers/cursor/interaction.js +66 -0
- package/lib/drivers/cursor/interaction.js.map +1 -0
- package/lib/drivers/mcp/index.d.ts +35 -2
- package/lib/drivers/mcp/index.d.ts.map +1 -1
- package/lib/drivers/mcp/index.js +16 -3
- package/lib/drivers/mcp/index.js.map +1 -1
- package/lib/drivers/shared/experiment-behavior.d.ts +13 -0
- package/lib/drivers/shared/experiment-behavior.d.ts.map +1 -0
- package/lib/drivers/shared/experiment-behavior.js +197 -0
- package/lib/drivers/shared/experiment-behavior.js.map +1 -0
- package/lib/drivers/shared/experiment-policy.d.ts +4 -0
- package/lib/drivers/shared/experiment-policy.d.ts.map +1 -0
- package/lib/drivers/shared/experiment-policy.js +143 -0
- package/lib/drivers/shared/experiment-policy.js.map +1 -0
- package/lib/drivers/subprocess/index.d.ts +37 -2
- package/lib/drivers/subprocess/index.d.ts.map +1 -1
- package/lib/drivers/subprocess/index.js +46 -6
- package/lib/drivers/subprocess/index.js.map +1 -1
- package/lib/index.d.ts +6 -5
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +4 -3
- package/lib/index.js.map +1 -1
- package/lib/orchestrator/annotation-loader.d.ts +6 -2
- package/lib/orchestrator/annotation-loader.d.ts.map +1 -1
- package/lib/orchestrator/annotation-loader.js +8 -0
- package/lib/orchestrator/annotation-loader.js.map +1 -1
- package/lib/orchestrator/annotation-store.d.ts.map +1 -1
- package/lib/orchestrator/annotation-store.js +16 -2
- package/lib/orchestrator/annotation-store.js.map +1 -1
- package/lib/orchestrator/campaign-lifecycle.d.ts +1 -0
- package/lib/orchestrator/campaign-lifecycle.d.ts.map +1 -1
- package/lib/orchestrator/campaign-lifecycle.js +4 -1
- package/lib/orchestrator/campaign-lifecycle.js.map +1 -1
- package/lib/orchestrator/compare.d.ts +4 -0
- package/lib/orchestrator/compare.d.ts.map +1 -1
- package/lib/orchestrator/compare.js +13 -1
- package/lib/orchestrator/compare.js.map +1 -1
- package/lib/orchestrator/comparison-identity.d.ts.map +1 -1
- package/lib/orchestrator/comparison-identity.js +1 -0
- package/lib/orchestrator/comparison-identity.js.map +1 -1
- package/lib/orchestrator/config.d.ts +42 -0
- package/lib/orchestrator/config.d.ts.map +1 -1
- package/lib/orchestrator/config.js +6 -2
- package/lib/orchestrator/config.js.map +1 -1
- package/lib/orchestrator/discover.d.ts +1 -0
- package/lib/orchestrator/discover.d.ts.map +1 -1
- package/lib/orchestrator/discover.js +7 -1
- package/lib/orchestrator/discover.js.map +1 -1
- package/lib/orchestrator/doctor.d.ts.map +1 -1
- package/lib/orchestrator/doctor.js +34 -26
- package/lib/orchestrator/doctor.js.map +1 -1
- package/lib/orchestrator/driver-capabilities.d.ts +3 -0
- package/lib/orchestrator/driver-capabilities.d.ts.map +1 -0
- package/lib/orchestrator/driver-capabilities.js +10 -0
- package/lib/orchestrator/driver-capabilities.js.map +1 -0
- package/lib/orchestrator/driver-identity.d.ts +5 -0
- package/lib/orchestrator/driver-identity.d.ts.map +1 -0
- package/lib/orchestrator/driver-identity.js +41 -0
- package/lib/orchestrator/driver-identity.js.map +1 -0
- package/lib/orchestrator/experiment-context.d.ts +10 -0
- package/lib/orchestrator/experiment-context.d.ts.map +1 -1
- package/lib/orchestrator/experiment-contracts.d.ts +10 -0
- package/lib/orchestrator/experiment-contracts.d.ts.map +1 -1
- package/lib/orchestrator/experiment-corpus.d.ts.map +1 -1
- package/lib/orchestrator/experiment-corpus.js +17 -19
- package/lib/orchestrator/experiment-corpus.js.map +1 -1
- package/lib/orchestrator/experiment-effects.d.ts +33 -0
- package/lib/orchestrator/experiment-effects.d.ts.map +1 -0
- package/lib/orchestrator/experiment-effects.js +44 -0
- package/lib/orchestrator/experiment-effects.js.map +1 -0
- package/lib/orchestrator/experiment-evaluation.d.ts.map +1 -1
- package/lib/orchestrator/experiment-evaluation.js +36 -3
- package/lib/orchestrator/experiment-evaluation.js.map +1 -1
- package/lib/orchestrator/experiment-identity.d.ts.map +1 -1
- package/lib/orchestrator/experiment-identity.js +18 -29
- package/lib/orchestrator/experiment-identity.js.map +1 -1
- package/lib/orchestrator/experiment-loader.d.ts +7 -2
- package/lib/orchestrator/experiment-loader.d.ts.map +1 -1
- package/lib/orchestrator/experiment-report.d.ts +70 -0
- package/lib/orchestrator/experiment-report.d.ts.map +1 -1
- package/lib/orchestrator/experiment-report.js +9 -1
- package/lib/orchestrator/experiment-report.js.map +1 -1
- package/lib/orchestrator/experiment-runs.d.ts +22 -1
- package/lib/orchestrator/experiment-runs.d.ts.map +1 -1
- package/lib/orchestrator/experiment-runs.js +13 -5
- package/lib/orchestrator/experiment-runs.js.map +1 -1
- package/lib/orchestrator/experiment-runtime-identity.d.ts +0 -16
- package/lib/orchestrator/experiment-runtime-identity.d.ts.map +1 -1
- package/lib/orchestrator/experiment-runtime-identity.js +5 -220
- package/lib/orchestrator/experiment-runtime-identity.js.map +1 -1
- package/lib/orchestrator/experiment-selection.d.ts.map +1 -1
- package/lib/orchestrator/experiment-selection.js +52 -0
- package/lib/orchestrator/experiment-selection.js.map +1 -1
- package/lib/orchestrator/experiment.d.ts +0 -2
- package/lib/orchestrator/experiment.d.ts.map +1 -1
- package/lib/orchestrator/experiment.js +23 -15
- package/lib/orchestrator/experiment.js.map +1 -1
- package/lib/orchestrator/fs-read.d.ts +1 -6
- package/lib/orchestrator/fs-read.d.ts.map +1 -1
- package/lib/orchestrator/fs-read.js +2 -32
- package/lib/orchestrator/fs-read.js.map +1 -1
- package/lib/orchestrator/grader-experiment.d.ts +17 -1
- package/lib/orchestrator/grader-experiment.d.ts.map +1 -1
- package/lib/orchestrator/grader-experiment.js +52 -7
- package/lib/orchestrator/grader-experiment.js.map +1 -1
- package/lib/orchestrator/grading.d.ts.map +1 -1
- package/lib/orchestrator/grading.js +13 -6
- package/lib/orchestrator/grading.js.map +1 -1
- package/lib/orchestrator/list-runs.d.ts +1 -0
- package/lib/orchestrator/list-runs.d.ts.map +1 -1
- package/lib/orchestrator/list-runs.js +27 -6
- package/lib/orchestrator/list-runs.js.map +1 -1
- package/lib/orchestrator/optimization-lifecycle.d.ts.map +1 -1
- package/lib/orchestrator/optimization-lifecycle.js +3 -1
- package/lib/orchestrator/optimization-lifecycle.js.map +1 -1
- package/lib/orchestrator/orchestrator.d.ts +6 -1
- package/lib/orchestrator/orchestrator.d.ts.map +1 -1
- package/lib/orchestrator/orchestrator.js +17 -143
- package/lib/orchestrator/orchestrator.js.map +1 -1
- package/lib/orchestrator/paired-effects.d.ts +34 -0
- package/lib/orchestrator/paired-effects.d.ts.map +1 -0
- package/lib/orchestrator/paired-effects.js +158 -0
- package/lib/orchestrator/paired-effects.js.map +1 -0
- package/lib/orchestrator/provenance.d.ts +5 -1
- package/lib/orchestrator/provenance.d.ts.map +1 -1
- package/lib/orchestrator/provenance.js +16 -3
- package/lib/orchestrator/provenance.js.map +1 -1
- package/lib/orchestrator/regrade.d.ts +1 -0
- package/lib/orchestrator/regrade.d.ts.map +1 -1
- package/lib/orchestrator/run-execution.d.ts +2 -0
- package/lib/orchestrator/run-execution.d.ts.map +1 -1
- package/lib/orchestrator/run-execution.js +18 -3
- package/lib/orchestrator/run-execution.js.map +1 -1
- package/lib/orchestrator/run-lifecycle.d.ts +1 -0
- package/lib/orchestrator/run-lifecycle.d.ts.map +1 -1
- package/lib/orchestrator/run-lifecycle.js +3 -2
- package/lib/orchestrator/run-lifecycle.js.map +1 -1
- package/lib/orchestrator/suite-runs.d.ts +3 -1
- package/lib/orchestrator/suite-runs.d.ts.map +1 -1
- package/lib/orchestrator/suite-runs.js +12 -2
- package/lib/orchestrator/suite-runs.js.map +1 -1
- package/lib/orchestrator/suite-summary.d.ts.map +1 -1
- package/lib/orchestrator/suite-summary.js +2 -1
- package/lib/orchestrator/suite-summary.js.map +1 -1
- package/lib/previewer/server.d.ts +6 -0
- package/lib/previewer/server.d.ts.map +1 -1
- package/lib/previewer/server.js +21 -5
- package/lib/previewer/server.js.map +1 -1
- package/package.json +2 -2
- package/skills/lux/references/cli.md +5 -2
- package/skills/lux/references/eval-authoring.md +0 -7
- package/skills/lux-answerer/SKILL.md +1 -1
- package/src/answerers/claude-code/index.ts +3 -3
- package/src/answerers/persona/index.ts +3 -3
- package/src/answerers/terminal/index.ts +4 -9
- package/src/assertions/core/resource-checks.ts +3 -5
- package/src/assertions/rubric/index.ts +7 -1
- package/src/assertions/rubric/internal.ts +13 -8
- package/src/authoring.ts +331 -2
- package/src/cli/bin.ts +2 -12
- package/src/cli/command-runtime.ts +20 -9
- package/src/cli/init-templates.ts +223 -0
- package/src/cli/init.ts +38 -184
- package/src/cli/output-schemas.ts +106 -0
- package/src/cli/program.ts +621 -548
- package/src/cli/render/reporter.ts +25 -4
- package/src/cli/run-options.ts +8 -25
- package/src/cli/view.ts +45 -84
- package/src/core/annotation.ts +2 -1
- package/src/core/answerer.ts +9 -0
- package/src/core/assertion.ts +3 -0
- package/src/core/case.ts +5 -1
- package/src/core/driver.ts +38 -0
- package/src/core/environment.ts +22 -0
- package/src/core/evaluation-clusters.ts +35 -0
- package/src/core/experiment.ts +60 -23
- package/src/core/file-tree.ts +35 -0
- package/src/core/index.ts +1 -0
- package/src/core/lifecycle-fixtures.ts +4 -2
- package/src/core/platform-process.ts +54 -6
- package/src/core/run.ts +20 -0
- package/src/core/usage.ts +8 -0
- package/src/drivers/claude-code/index.ts +34 -3
- package/src/drivers/codex/app-events.ts +43 -33
- package/src/drivers/codex/exec-events.ts +258 -0
- package/src/drivers/codex/index.ts +37 -262
- package/src/drivers/cursor/README.md +57 -0
- package/src/drivers/cursor/acp-transport.ts +182 -0
- package/src/drivers/cursor/config.ts +29 -0
- package/src/drivers/cursor/events.ts +83 -0
- package/src/drivers/cursor/index.ts +316 -0
- package/src/drivers/cursor/interaction.ts +90 -0
- package/src/drivers/mcp/index.ts +16 -3
- package/src/drivers/shared/experiment-behavior.ts +214 -0
- package/src/drivers/shared/experiment-policy.ts +195 -0
- package/src/drivers/subprocess/index.ts +45 -6
- package/src/index.ts +16 -5
- package/src/orchestrator/annotation-loader.ts +10 -0
- package/src/orchestrator/annotation-store.ts +24 -3
- package/src/orchestrator/campaign-lifecycle.ts +5 -1
- package/src/orchestrator/compare.ts +16 -1
- package/src/orchestrator/comparison-identity.ts +1 -0
- package/src/orchestrator/config.ts +6 -2
- package/src/orchestrator/discover.ts +8 -1
- package/src/orchestrator/doctor.ts +40 -22
- package/src/orchestrator/driver-capabilities.ts +16 -0
- package/src/orchestrator/driver-identity.ts +59 -0
- package/src/orchestrator/experiment-corpus.ts +23 -28
- package/src/orchestrator/experiment-effects.ts +61 -0
- package/src/orchestrator/experiment-evaluation.ts +45 -5
- package/src/orchestrator/experiment-identity.ts +27 -36
- package/src/orchestrator/experiment-report.ts +21 -1
- package/src/orchestrator/experiment-runs.ts +11 -4
- package/src/orchestrator/experiment-runtime-identity.ts +5 -243
- package/src/orchestrator/experiment-selection.ts +77 -0
- package/src/orchestrator/experiment.ts +26 -24
- package/src/orchestrator/fs-read.ts +2 -32
- package/src/orchestrator/grader-experiment.ts +72 -8
- package/src/orchestrator/grading.ts +15 -6
- package/src/orchestrator/list-runs.ts +29 -6
- package/src/orchestrator/optimization-lifecycle.ts +4 -1
- package/src/orchestrator/orchestrator.ts +26 -183
- package/src/orchestrator/paired-effects.ts +209 -0
- package/src/orchestrator/provenance.ts +23 -3
- package/src/orchestrator/run-execution.ts +18 -3
- package/src/orchestrator/run-lifecycle.ts +4 -2
- package/src/orchestrator/suite-runs.ts +10 -1
- package/src/orchestrator/suite-summary.ts +2 -1
- package/src/previewer/server.ts +27 -5
- package/viewer/app.js +27 -6
- package/viewer/detail.js +22 -5
- package/lib/answerers/scripted/index.d.ts +0 -18
- package/lib/answerers/scripted/index.d.ts.map +0 -1
- package/lib/answerers/scripted/index.js +0 -63
- package/lib/answerers/scripted/index.js.map +0 -1
- package/lib/cli/skills.d.ts +0 -38
- package/lib/cli/skills.d.ts.map +0 -1
- package/lib/cli/skills.js +0 -84
- package/lib/cli/skills.js.map +0 -1
- package/src/answerers/scripted/index.ts +0 -78
- package/src/cli/skills.ts +0 -129
package/src/previewer/server.ts
CHANGED
|
@@ -42,6 +42,7 @@ type PreviewRun = {
|
|
|
42
42
|
score: number | null;
|
|
43
43
|
assertions: { passed: number; total: number };
|
|
44
44
|
path: string;
|
|
45
|
+
readErrors?: string[];
|
|
45
46
|
};
|
|
46
47
|
|
|
47
48
|
type PreviewSuite = {
|
|
@@ -102,6 +103,7 @@ export type PreviewSnapshot = {
|
|
|
102
103
|
runs: PreviewRun[];
|
|
103
104
|
suites: PreviewSuite[];
|
|
104
105
|
experiments: PreviewExperiment[];
|
|
106
|
+
readErrors: Array<{ kind: "suite" | "experiment"; path: string; message: string }>;
|
|
105
107
|
};
|
|
106
108
|
|
|
107
109
|
type PreviewAssets = {
|
|
@@ -133,6 +135,7 @@ const displayPath = (runsRoot: string, path: string): string => {
|
|
|
133
135
|
};
|
|
134
136
|
|
|
135
137
|
const runStatus = (run: ListedRun): PreviewStatus => {
|
|
138
|
+
if (run.readErrors?.length) return "error";
|
|
136
139
|
if (run.exitReason && run.exitReason !== "done") return "error";
|
|
137
140
|
if (run.casePassed === true) return "passed";
|
|
138
141
|
if (run.casePassed === false) return "failed";
|
|
@@ -151,10 +154,21 @@ const buildSnapshot = async (
|
|
|
151
154
|
options: Pick<StartPreviewServerOptions, "initialPath" | "initialKind" | "caseFilter">,
|
|
152
155
|
): Promise<PreviewSnapshot> => {
|
|
153
156
|
const absoluteRunsRoot = resolve(runsRoot);
|
|
157
|
+
const readErrors: PreviewSnapshot["readErrors"] = [];
|
|
158
|
+
const onReadError = (kind: "suite" | "experiment") => (path: string, error: unknown) => {
|
|
159
|
+
readErrors.push({
|
|
160
|
+
kind,
|
|
161
|
+
path: displayPath(absoluteRunsRoot, path),
|
|
162
|
+
message: (error instanceof Error ? error.message : String(error)).replaceAll(
|
|
163
|
+
absoluteRunsRoot,
|
|
164
|
+
".",
|
|
165
|
+
),
|
|
166
|
+
});
|
|
167
|
+
};
|
|
154
168
|
const [listedRuns, listedSuites, listedExperiments] = await Promise.all([
|
|
155
169
|
listRuns(absoluteRunsRoot),
|
|
156
|
-
listSuiteRuns(absoluteRunsRoot),
|
|
157
|
-
listExperimentRuns(absoluteRunsRoot),
|
|
170
|
+
listSuiteRuns(absoluteRunsRoot, { onReadError: onReadError("suite") }),
|
|
171
|
+
listExperimentRuns(absoluteRunsRoot, { onReadError: onReadError("experiment") }),
|
|
158
172
|
]);
|
|
159
173
|
const runs = listedRuns
|
|
160
174
|
.filter((run) => !options.caseFilter || run.caseSlug === options.caseFilter)
|
|
@@ -176,6 +190,13 @@ const buildSnapshot = async (
|
|
|
176
190
|
score: run.caseScore,
|
|
177
191
|
assertions: { passed: run.assertionPassed, total: run.assertionTotal },
|
|
178
192
|
path: displayPath(absoluteRunsRoot, run.runDir),
|
|
193
|
+
...(run.readErrors
|
|
194
|
+
? {
|
|
195
|
+
readErrors: run.readErrors.map((message) =>
|
|
196
|
+
message.replaceAll(absoluteRunsRoot, "."),
|
|
197
|
+
),
|
|
198
|
+
}
|
|
199
|
+
: {}),
|
|
179
200
|
}),
|
|
180
201
|
);
|
|
181
202
|
const runIdsByPath = new Map(
|
|
@@ -260,6 +281,7 @@ const buildSnapshot = async (
|
|
|
260
281
|
runs,
|
|
261
282
|
suites,
|
|
262
283
|
experiments,
|
|
284
|
+
readErrors: readErrors.sort((a, b) => a.path.localeCompare(b.path)),
|
|
263
285
|
};
|
|
264
286
|
};
|
|
265
287
|
|
|
@@ -319,7 +341,7 @@ const findSuiteById = async (
|
|
|
319
341
|
runsRoot: string,
|
|
320
342
|
id: string,
|
|
321
343
|
): Promise<Awaited<ReturnType<typeof listSuiteRuns>>[number] | null> => {
|
|
322
|
-
const suites = await listSuiteRuns(runsRoot);
|
|
344
|
+
const suites = await listSuiteRuns(runsRoot, { onReadError: () => undefined });
|
|
323
345
|
return suites.find((suite) => opaqueId(runsRoot, suite.suiteDir) === id) ?? null;
|
|
324
346
|
};
|
|
325
347
|
|
|
@@ -327,7 +349,7 @@ const findSuitesById = async (
|
|
|
327
349
|
runsRoot: string,
|
|
328
350
|
ids: readonly string[],
|
|
329
351
|
): Promise<Awaited<ReturnType<typeof listSuiteRuns>> | null> => {
|
|
330
|
-
const suites = await listSuiteRuns(runsRoot);
|
|
352
|
+
const suites = await listSuiteRuns(runsRoot, { onReadError: () => undefined });
|
|
331
353
|
const found = ids.map(
|
|
332
354
|
(id) => suites.find((suite) => opaqueId(runsRoot, suite.suiteDir) === id) ?? null,
|
|
333
355
|
);
|
|
@@ -342,7 +364,7 @@ const findExperimentById = async (
|
|
|
342
364
|
runsRoot: string,
|
|
343
365
|
id: string,
|
|
344
366
|
): Promise<Awaited<ReturnType<typeof listExperimentRuns>>[number] | null> => {
|
|
345
|
-
const experiments = await listExperimentRuns(runsRoot);
|
|
367
|
+
const experiments = await listExperimentRuns(runsRoot, { onReadError: () => undefined });
|
|
346
368
|
return (
|
|
347
369
|
experiments.find((experiment) => opaqueId(runsRoot, experiment.experimentDir) === id) ?? null
|
|
348
370
|
);
|
package/viewer/app.js
CHANGED
|
@@ -84,6 +84,7 @@ const visibleItems = () => {
|
|
|
84
84
|
const rowTitle = (item) => item.caseId ?? item.campaignId ?? item.suiteId;
|
|
85
85
|
|
|
86
86
|
const rowMetric = (item) => {
|
|
87
|
+
if (item.readErrors?.length) return "<strong>Damaged</strong><small>evidence unavailable</small>";
|
|
87
88
|
if (item.kind === "run") {
|
|
88
89
|
return `<strong>${escapeHtml(percentage(item.score))}</strong><small>${escapeHtml(
|
|
89
90
|
`${item.assertions.passed}/${item.assertions.total} checks`,
|
|
@@ -97,6 +98,7 @@ const rowMetric = (item) => {
|
|
|
97
98
|
};
|
|
98
99
|
|
|
99
100
|
const rowMeta = (item) => {
|
|
101
|
+
if (item.readErrors?.length) return [item.path, ...item.readErrors];
|
|
100
102
|
if (item.kind === "run") {
|
|
101
103
|
return [
|
|
102
104
|
item.driver,
|
|
@@ -118,18 +120,37 @@ const compareSlot = (id) => {
|
|
|
118
120
|
|
|
119
121
|
const renderRows = () => {
|
|
120
122
|
const items = visibleItems();
|
|
123
|
+
const errors = (state.snapshot?.readErrors ?? []).filter(
|
|
124
|
+
(error) => `${error.kind}s` === state.tab,
|
|
125
|
+
);
|
|
126
|
+
const damagedRows = errors
|
|
127
|
+
.map(
|
|
128
|
+
(error) => `
|
|
129
|
+
<div class="evidence-row">
|
|
130
|
+
<span class="status-pin error" aria-label="Damaged"></span>
|
|
131
|
+
<span class="row-main">
|
|
132
|
+
<span class="row-title">${escapeHtml(error.path)}</span>
|
|
133
|
+
<span class="row-meta">${escapeHtml(error.message)}</span>
|
|
134
|
+
</span>
|
|
135
|
+
<span class="row-metric"><strong>Damaged</strong><small>evidence unavailable</small></span>
|
|
136
|
+
</div>`,
|
|
137
|
+
)
|
|
138
|
+
.join("");
|
|
121
139
|
elements.count.textContent = `${items.length} ${items.length === 1 ? "record" : "records"}`;
|
|
140
|
+
if (errors.length) elements.count.textContent += ` · ${errors.length} damaged`;
|
|
122
141
|
if (items.length === 0) {
|
|
123
|
-
elements.list.innerHTML =
|
|
142
|
+
elements.list.innerHTML = `${damagedRows}
|
|
124
143
|
<div class="empty-list">
|
|
125
144
|
<strong>No matching ${escapeHtml(state.tab)}</strong>
|
|
126
145
|
<p>Try another status or search term.</p>
|
|
127
146
|
</div>`;
|
|
128
147
|
return;
|
|
129
148
|
}
|
|
130
|
-
elements.list.innerHTML =
|
|
131
|
-
|
|
132
|
-
|
|
149
|
+
elements.list.innerHTML =
|
|
150
|
+
damagedRows +
|
|
151
|
+
items
|
|
152
|
+
.map(
|
|
153
|
+
(item) => `
|
|
133
154
|
<button
|
|
134
155
|
class="evidence-row${state.compareMode ? " is-compare-mode" : ""}${state.selectedId === item.id && !state.compareMode ? " is-selected" : ""}${
|
|
135
156
|
state.compareIds.includes(item.id) ? " is-compared" : ""
|
|
@@ -151,8 +172,8 @@ const renderRows = () => {
|
|
|
151
172
|
</span>
|
|
152
173
|
<span class="row-metric">${rowMetric(item)}</span>
|
|
153
174
|
</button>`,
|
|
154
|
-
|
|
155
|
-
|
|
175
|
+
)
|
|
176
|
+
.join("");
|
|
156
177
|
};
|
|
157
178
|
|
|
158
179
|
const renderFilters = () => {
|
package/viewer/detail.js
CHANGED
|
@@ -171,13 +171,20 @@ export const renderRunDetail = (item, detail) => {
|
|
|
171
171
|
const assertions = grading?.assertions ?? [];
|
|
172
172
|
const events = detail.events ?? [];
|
|
173
173
|
const artifacts = detail.artifacts ?? [];
|
|
174
|
-
const
|
|
174
|
+
const reportedAgentTokens = totalTokens(metadata?.usage?.agent);
|
|
175
|
+
const agentTokens =
|
|
176
|
+
metadata?.agentUsageAvailability === "reported" ||
|
|
177
|
+
(metadata?.agentUsageAvailability === undefined && reportedAgentTokens > 0)
|
|
178
|
+
? reportedAgentTokens
|
|
179
|
+
: undefined;
|
|
175
180
|
const answererTokens = totalTokens(metadata?.usage?.answerer);
|
|
176
181
|
const gradingTokens = totalTokens(metadata?.usage?.grading);
|
|
177
182
|
const harnessTokens = answererTokens + gradingTokens;
|
|
178
183
|
const phase = metadata?.phaseDurationMs;
|
|
179
184
|
const actionTiming = metadata?.actionTiming;
|
|
180
185
|
const prompt = detail.case?.prompt;
|
|
186
|
+
const conditions = metadata?.provenance?.environment;
|
|
187
|
+
const host = metadata?.provenance?.runtime?.host;
|
|
181
188
|
const driverMetrics = driverMetricStats(metadata?.driverMetrics);
|
|
182
189
|
const subagents = agentActivityCards(metadata?.agentActivity);
|
|
183
190
|
return `
|
|
@@ -220,6 +227,14 @@ export const renderRunDetail = (item, detail) => {
|
|
|
220
227
|
duration(actionTiming?.timeToFirstDurableMutationMs),
|
|
221
228
|
)}</dd></div>
|
|
222
229
|
</dl>
|
|
230
|
+
${
|
|
231
|
+
conditions
|
|
232
|
+
? `<section class="detail-section"><h3>Execution conditions</h3>
|
|
233
|
+
<p>Lux concurrency: ${escapeHtml(conditions.concurrency)}${host ? ` · Host: ${escapeHtml(host.availableParallelism)} available CPUs, ${escapeHtml(metricValue(host.totalMemoryBytes, "bytes"))} memory` : ""}</p>
|
|
234
|
+
${conditions.declared ? `<details><summary>Declared environment (not enforced by Lux)</summary><pre>${escapeHtml(JSON.stringify(conditions.declared, null, 2))}</pre></details>` : ""}
|
|
235
|
+
</section>`
|
|
236
|
+
: ""
|
|
237
|
+
}
|
|
223
238
|
${
|
|
224
239
|
driverMetrics
|
|
225
240
|
? `<section class="detail-section"><h3>Driver metrics <span>reported by ${escapeHtml(
|
|
@@ -262,7 +277,7 @@ export const renderRunDetail = (item, detail) => {
|
|
|
262
277
|
{ key: "answerer", label: "Answerer", value: answererTokens },
|
|
263
278
|
{ key: "grading", label: "Grading", value: gradingTokens },
|
|
264
279
|
],
|
|
265
|
-
`${agentTokens} agent, ${answererTokens} answerer, ${gradingTokens} grading tokens`,
|
|
280
|
+
`${agentTokens ?? "unavailable"} agent, ${answererTokens} answerer, ${gradingTokens} grading tokens`,
|
|
266
281
|
)
|
|
267
282
|
: ""
|
|
268
283
|
}
|
|
@@ -872,9 +887,11 @@ export const renderRunComparison = (payload, labels) => {
|
|
|
872
887
|
const mutationB = runDelta?.actionTiming?.b?.timeToFirstMutationMs;
|
|
873
888
|
const mutationDelta =
|
|
874
889
|
typeof mutationA === "number" && typeof mutationB === "number" ? mutationB - mutationA : null;
|
|
875
|
-
const tokenA =
|
|
876
|
-
|
|
877
|
-
const
|
|
890
|
+
const tokenA =
|
|
891
|
+
runDelta?.agentUsageAvailable?.a === false ? null : totalTokens(runDelta?.usage?.a?.agent);
|
|
892
|
+
const tokenB =
|
|
893
|
+
runDelta?.agentUsageAvailable?.b === false ? null : totalTokens(runDelta?.usage?.b?.agent);
|
|
894
|
+
const tokenDelta = tokenA === null || tokenB === null ? null : tokenB - tokenA;
|
|
878
895
|
const scoreDelta =
|
|
879
896
|
typeof comparison.grading.caseScoreA === "number" &&
|
|
880
897
|
typeof comparison.grading.caseScoreB === "number"
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import type { AnswererPlugin } from "../../core/index.js";
|
|
3
|
-
export declare const ScriptedAnswererConfigSchema: z.ZodObject<{
|
|
4
|
-
answers: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
5
|
-
kind: z.ZodLiteral<"ask">;
|
|
6
|
-
text: z.ZodString;
|
|
7
|
-
}, z.core.$strict>, z.ZodObject<{
|
|
8
|
-
kind: z.ZodLiteral<"approve">;
|
|
9
|
-
approved: z.ZodBoolean;
|
|
10
|
-
reason: z.ZodOptional<z.ZodString>;
|
|
11
|
-
}, z.core.$strict>, z.ZodObject<{
|
|
12
|
-
kind: z.ZodLiteral<"custom">;
|
|
13
|
-
payload: z.ZodUnknown;
|
|
14
|
-
}, z.core.$strict>], "kind">>;
|
|
15
|
-
}, z.core.$strict>;
|
|
16
|
-
export type ScriptedAnswererConfig = z.infer<typeof ScriptedAnswererConfigSchema>;
|
|
17
|
-
export declare const scriptedAnswerer: AnswererPlugin<ScriptedAnswererConfig>;
|
|
18
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/answerers/scripted/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAoB,cAAc,EAAa,MAAM,qBAAqB,CAAC;AAiBvF,eAAO,MAAM,4BAA4B;;;;;;;;;;;;kBAU9B,CAAC;AAEZ,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,CAAC;AA2ClF,eAAO,MAAM,gBAAgB,EAAE,cAAc,CAAC,sBAAsB,CAInE,CAAC"}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
const ScriptedAskAnswerSchema = z.object({ kind: z.literal("ask"), text: z.string() }).strict();
|
|
3
|
-
const ScriptedApproveAnswerSchema = z
|
|
4
|
-
.object({
|
|
5
|
-
kind: z.literal("approve"),
|
|
6
|
-
approved: z.boolean(),
|
|
7
|
-
reason: z.string().optional(),
|
|
8
|
-
})
|
|
9
|
-
.strict();
|
|
10
|
-
const ScriptedCustomAnswerSchema = z
|
|
11
|
-
.object({
|
|
12
|
-
kind: z.literal("custom"),
|
|
13
|
-
payload: z.unknown(),
|
|
14
|
-
})
|
|
15
|
-
.strict();
|
|
16
|
-
export const ScriptedAnswererConfigSchema = z
|
|
17
|
-
.object({
|
|
18
|
-
answers: z.array(z.discriminatedUnion("kind", [
|
|
19
|
-
ScriptedAskAnswerSchema,
|
|
20
|
-
ScriptedApproveAnswerSchema,
|
|
21
|
-
ScriptedCustomAnswerSchema,
|
|
22
|
-
])),
|
|
23
|
-
})
|
|
24
|
-
.strict();
|
|
25
|
-
class ScriptedAnswererImpl {
|
|
26
|
-
index = 0;
|
|
27
|
-
answers;
|
|
28
|
-
constructor(answers) {
|
|
29
|
-
this.answers = structuredClone(answers);
|
|
30
|
-
}
|
|
31
|
-
async prepare() {
|
|
32
|
-
this.index = 0;
|
|
33
|
-
}
|
|
34
|
-
async answer(interrupt) {
|
|
35
|
-
const scripted = this.answers[this.index];
|
|
36
|
-
if (!scripted) {
|
|
37
|
-
throw new Error(`scripted answerer: no answer configured for interrupt ${this.index + 1}`);
|
|
38
|
-
}
|
|
39
|
-
if (scripted.kind !== interrupt.kind) {
|
|
40
|
-
throw new Error(`scripted answerer: answer ${this.index + 1} expects ${scripted.kind}, received ${interrupt.kind}`);
|
|
41
|
-
}
|
|
42
|
-
this.index += 1;
|
|
43
|
-
if (scripted.kind === "ask") {
|
|
44
|
-
return { kind: "ask", id: interrupt.id, text: scripted.text };
|
|
45
|
-
}
|
|
46
|
-
if (scripted.kind === "approve") {
|
|
47
|
-
return {
|
|
48
|
-
kind: "approve",
|
|
49
|
-
id: interrupt.id,
|
|
50
|
-
approved: scripted.approved,
|
|
51
|
-
...(scripted.reason === undefined ? {} : { reason: scripted.reason }),
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
return { kind: "custom", id: interrupt.id, payload: structuredClone(scripted.payload) };
|
|
55
|
-
}
|
|
56
|
-
async close() { }
|
|
57
|
-
}
|
|
58
|
-
export const scriptedAnswerer = {
|
|
59
|
-
name: "scripted",
|
|
60
|
-
configSchema: ScriptedAnswererConfigSchema,
|
|
61
|
-
create: (config) => new ScriptedAnswererImpl(config.answers),
|
|
62
|
-
};
|
|
63
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/answerers/scripted/index.ts"],"names":[],"mappings":"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"}
|
package/lib/cli/skills.d.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
declare const PlatformSchema: z.ZodEnum<{
|
|
3
|
-
all: "all";
|
|
4
|
-
claude: "claude";
|
|
5
|
-
"claude-code": "claude-code";
|
|
6
|
-
codex: "codex";
|
|
7
|
-
}>;
|
|
8
|
-
export type SkillsPlatform = z.infer<typeof PlatformSchema>;
|
|
9
|
-
declare const SkillNameSchema: z.ZodEnum<{
|
|
10
|
-
lux: "lux";
|
|
11
|
-
"lux-answerer": "lux-answerer";
|
|
12
|
-
}>;
|
|
13
|
-
export type BundledSkillName = z.infer<typeof SkillNameSchema>;
|
|
14
|
-
declare const InstallSkillsOptionsSchema: z.ZodObject<{
|
|
15
|
-
cwd: z.ZodString;
|
|
16
|
-
platform: z.ZodEnum<{
|
|
17
|
-
all: "all";
|
|
18
|
-
claude: "claude";
|
|
19
|
-
"claude-code": "claude-code";
|
|
20
|
-
codex: "codex";
|
|
21
|
-
}>;
|
|
22
|
-
project: z.ZodDefault<z.ZodBoolean>;
|
|
23
|
-
dir: z.ZodOptional<z.ZodString>;
|
|
24
|
-
name: z.ZodOptional<z.ZodEnum<{
|
|
25
|
-
lux: "lux";
|
|
26
|
-
"lux-answerer": "lux-answerer";
|
|
27
|
-
}>>;
|
|
28
|
-
}, z.core.$strict>;
|
|
29
|
-
export interface InstalledSkill {
|
|
30
|
-
name: BundledSkillName;
|
|
31
|
-
platform: "claude-code" | "codex";
|
|
32
|
-
path: string;
|
|
33
|
-
}
|
|
34
|
-
export declare const formatSkillsList: () => string;
|
|
35
|
-
export declare const installSkills: (options: z.input<typeof InstallSkillsOptionsSchema>) => Promise<InstalledSkill[]>;
|
|
36
|
-
export declare const formatSkillsInstall: (installed: InstalledSkill[], cwd: string) => string;
|
|
37
|
-
export {};
|
|
38
|
-
//# sourceMappingURL=skills.d.ts.map
|
package/lib/cli/skills.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../../src/cli/skills.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,QAAA,MAAM,cAAc;;;;;EAAoD,CAAC;AACzE,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAC5D,QAAA,MAAM,eAAe;;;EAAkC,CAAC;AACxD,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC;AAE/D,QAAA,MAAM,0BAA0B;;;;;;;;;;;;;;kBAQrB,CAAC;AAEZ,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,gBAAgB,CAAC;IACvB,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;CACd;AAmBD,eAAO,MAAM,gBAAgB,QAAO,MAGtB,CAAC;AA2Df,eAAO,MAAM,aAAa,YACf,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,KAClD,OAAO,CAAC,cAAc,EAAE,CAU1B,CAAC;AAEF,eAAO,MAAM,mBAAmB,cAAe,cAAc,EAAE,OAAO,MAAM,KAAG,MAQhE,CAAC"}
|
package/lib/cli/skills.js
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { lstat, mkdir, readdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
-
import { homedir } from "node:os";
|
|
3
|
-
import { dirname, join, relative, resolve, sep } from "node:path";
|
|
4
|
-
import { fileURLToPath } from "node:url";
|
|
5
|
-
import { z } from "zod";
|
|
6
|
-
const PlatformSchema = z.enum(["claude", "claude-code", "codex", "all"]);
|
|
7
|
-
const SkillNameSchema = z.enum(["lux", "lux-answerer"]);
|
|
8
|
-
const InstallSkillsOptionsSchema = z
|
|
9
|
-
.object({
|
|
10
|
-
cwd: z.string().min(1),
|
|
11
|
-
platform: PlatformSchema,
|
|
12
|
-
project: z.boolean().default(false),
|
|
13
|
-
dir: z.string().min(1).optional(),
|
|
14
|
-
name: SkillNameSchema.optional(),
|
|
15
|
-
})
|
|
16
|
-
.strict();
|
|
17
|
-
const BUNDLED_SKILLS = [
|
|
18
|
-
{
|
|
19
|
-
name: "lux",
|
|
20
|
-
description: "Author and drive coding-agent evals with Lux",
|
|
21
|
-
platforms: ["claude-code", "codex"],
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
name: "lux-answerer",
|
|
25
|
-
description: "Play a simulated user for a running Lux eval",
|
|
26
|
-
platforms: ["claude-code"],
|
|
27
|
-
},
|
|
28
|
-
];
|
|
29
|
-
export const formatSkillsList = () => BUNDLED_SKILLS.map(({ name, description, platforms }) => `${name}\t${description}\t${platforms.join(",")}`).join("\n");
|
|
30
|
-
const targetsFor = (platform, cwd, project, dir, name) => {
|
|
31
|
-
const platforms = platform === "all"
|
|
32
|
-
? ["claude-code", "codex"]
|
|
33
|
-
: [platform === "claude" ? "claude-code" : platform];
|
|
34
|
-
const scopeRoot = project ? resolve(cwd) : homedir();
|
|
35
|
-
const skills = name ? BUNDLED_SKILLS.filter((skill) => skill.name === name) : BUNDLED_SKILLS;
|
|
36
|
-
return platforms.flatMap((platformName) => skills
|
|
37
|
-
.filter((skill) => skill.platforms.includes(platformName))
|
|
38
|
-
.map((skill) => ({
|
|
39
|
-
name: skill.name,
|
|
40
|
-
platform: platformName,
|
|
41
|
-
source: fileURLToPath(new URL(`../../skills/${skill.name}`, import.meta.url)),
|
|
42
|
-
path: dir
|
|
43
|
-
? join(resolve(dir), skill.name)
|
|
44
|
-
: join(scopeRoot, platformName === "claude-code" ? ".claude" : ".codex", "skills", skill.name),
|
|
45
|
-
})));
|
|
46
|
-
};
|
|
47
|
-
const copySkillDirectory = async (source, target) => {
|
|
48
|
-
const sourceInfo = await lstat(source);
|
|
49
|
-
if (!sourceInfo.isDirectory() || sourceInfo.isSymbolicLink()) {
|
|
50
|
-
throw new Error(`lux skills: bundled skill source is not a real directory: ${source}`);
|
|
51
|
-
}
|
|
52
|
-
await mkdir(target, { recursive: true });
|
|
53
|
-
for (const entry of await readdir(source, { withFileTypes: true })) {
|
|
54
|
-
const sourcePath = join(source, entry.name);
|
|
55
|
-
const targetPath = join(target, entry.name);
|
|
56
|
-
if (entry.isSymbolicLink()) {
|
|
57
|
-
throw new Error(`lux skills: bundled skill contains a symbolic link: ${sourcePath}`);
|
|
58
|
-
}
|
|
59
|
-
if (entry.isDirectory()) {
|
|
60
|
-
await copySkillDirectory(sourcePath, targetPath);
|
|
61
|
-
}
|
|
62
|
-
else if (entry.isFile()) {
|
|
63
|
-
await mkdir(dirname(targetPath), { recursive: true });
|
|
64
|
-
await writeFile(targetPath, await readFile(sourcePath));
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
throw new Error(`lux skills: bundled skill contains an unsupported entry: ${sourcePath}`);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
export const installSkills = async (options) => {
|
|
72
|
-
const parsed = InstallSkillsOptionsSchema.parse(options);
|
|
73
|
-
const targets = targetsFor(parsed.platform, parsed.cwd, parsed.project, parsed.dir, parsed.name);
|
|
74
|
-
if (targets.length === 0) {
|
|
75
|
-
throw new Error(`lux skills: '${parsed.name}' is not available for platform '${parsed.platform}'`);
|
|
76
|
-
}
|
|
77
|
-
for (const target of targets)
|
|
78
|
-
await copySkillDirectory(target.source, target.path);
|
|
79
|
-
return targets.map(({ source: _, ...installed }) => installed);
|
|
80
|
-
};
|
|
81
|
-
export const formatSkillsInstall = (installed, cwd) => installed
|
|
82
|
-
.map(({ name, platform, path }) => `installed ${name} skill for ${platform} at ${relative(cwd, path).split(sep).join("/") || "."}`)
|
|
83
|
-
.join("\n");
|
|
84
|
-
//# sourceMappingURL=skills.js.map
|
package/lib/cli/skills.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/cli/skills.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import type { Answer, Answerer, AnswererPlugin, Interrupt } from "../../core/index.js";
|
|
3
|
-
|
|
4
|
-
const ScriptedAskAnswerSchema = z.object({ kind: z.literal("ask"), text: z.string() }).strict();
|
|
5
|
-
const ScriptedApproveAnswerSchema = z
|
|
6
|
-
.object({
|
|
7
|
-
kind: z.literal("approve"),
|
|
8
|
-
approved: z.boolean(),
|
|
9
|
-
reason: z.string().optional(),
|
|
10
|
-
})
|
|
11
|
-
.strict();
|
|
12
|
-
const ScriptedCustomAnswerSchema = z
|
|
13
|
-
.object({
|
|
14
|
-
kind: z.literal("custom"),
|
|
15
|
-
payload: z.unknown(),
|
|
16
|
-
})
|
|
17
|
-
.strict();
|
|
18
|
-
|
|
19
|
-
export const ScriptedAnswererConfigSchema = z
|
|
20
|
-
.object({
|
|
21
|
-
answers: z.array(
|
|
22
|
-
z.discriminatedUnion("kind", [
|
|
23
|
-
ScriptedAskAnswerSchema,
|
|
24
|
-
ScriptedApproveAnswerSchema,
|
|
25
|
-
ScriptedCustomAnswerSchema,
|
|
26
|
-
]),
|
|
27
|
-
),
|
|
28
|
-
})
|
|
29
|
-
.strict();
|
|
30
|
-
|
|
31
|
-
export type ScriptedAnswererConfig = z.infer<typeof ScriptedAnswererConfigSchema>;
|
|
32
|
-
|
|
33
|
-
class ScriptedAnswererImpl implements Answerer {
|
|
34
|
-
private index = 0;
|
|
35
|
-
private readonly answers: ScriptedAnswererConfig["answers"];
|
|
36
|
-
|
|
37
|
-
constructor(answers: ScriptedAnswererConfig["answers"]) {
|
|
38
|
-
this.answers = structuredClone(answers);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
async prepare(): Promise<void> {
|
|
42
|
-
this.index = 0;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
async answer(interrupt: Interrupt): Promise<Answer> {
|
|
46
|
-
const scripted = this.answers[this.index];
|
|
47
|
-
if (!scripted) {
|
|
48
|
-
throw new Error(`scripted answerer: no answer configured for interrupt ${this.index + 1}`);
|
|
49
|
-
}
|
|
50
|
-
if (scripted.kind !== interrupt.kind) {
|
|
51
|
-
throw new Error(
|
|
52
|
-
`scripted answerer: answer ${this.index + 1} expects ${scripted.kind}, received ${interrupt.kind}`,
|
|
53
|
-
);
|
|
54
|
-
}
|
|
55
|
-
this.index += 1;
|
|
56
|
-
|
|
57
|
-
if (scripted.kind === "ask") {
|
|
58
|
-
return { kind: "ask", id: interrupt.id, text: scripted.text };
|
|
59
|
-
}
|
|
60
|
-
if (scripted.kind === "approve") {
|
|
61
|
-
return {
|
|
62
|
-
kind: "approve",
|
|
63
|
-
id: interrupt.id,
|
|
64
|
-
approved: scripted.approved,
|
|
65
|
-
...(scripted.reason === undefined ? {} : { reason: scripted.reason }),
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
return { kind: "custom", id: interrupt.id, payload: structuredClone(scripted.payload) };
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
async close(): Promise<void> {}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export const scriptedAnswerer: AnswererPlugin<ScriptedAnswererConfig> = {
|
|
75
|
-
name: "scripted",
|
|
76
|
-
configSchema: ScriptedAnswererConfigSchema,
|
|
77
|
-
create: (config) => new ScriptedAnswererImpl(config.answers),
|
|
78
|
-
};
|
package/src/cli/skills.ts
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import { lstat, mkdir, readdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
-
import { homedir } from "node:os";
|
|
3
|
-
import { dirname, join, relative, resolve, sep } from "node:path";
|
|
4
|
-
import { fileURLToPath } from "node:url";
|
|
5
|
-
import { z } from "zod";
|
|
6
|
-
|
|
7
|
-
const PlatformSchema = z.enum(["claude", "claude-code", "codex", "all"]);
|
|
8
|
-
export type SkillsPlatform = z.infer<typeof PlatformSchema>;
|
|
9
|
-
const SkillNameSchema = z.enum(["lux", "lux-answerer"]);
|
|
10
|
-
export type BundledSkillName = z.infer<typeof SkillNameSchema>;
|
|
11
|
-
|
|
12
|
-
const InstallSkillsOptionsSchema = z
|
|
13
|
-
.object({
|
|
14
|
-
cwd: z.string().min(1),
|
|
15
|
-
platform: PlatformSchema,
|
|
16
|
-
project: z.boolean().default(false),
|
|
17
|
-
dir: z.string().min(1).optional(),
|
|
18
|
-
name: SkillNameSchema.optional(),
|
|
19
|
-
})
|
|
20
|
-
.strict();
|
|
21
|
-
|
|
22
|
-
export interface InstalledSkill {
|
|
23
|
-
name: BundledSkillName;
|
|
24
|
-
platform: "claude-code" | "codex";
|
|
25
|
-
path: string;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const BUNDLED_SKILLS = [
|
|
29
|
-
{
|
|
30
|
-
name: "lux",
|
|
31
|
-
description: "Author and drive coding-agent evals with Lux",
|
|
32
|
-
platforms: ["claude-code", "codex"],
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
name: "lux-answerer",
|
|
36
|
-
description: "Play a simulated user for a running Lux eval",
|
|
37
|
-
platforms: ["claude-code"],
|
|
38
|
-
},
|
|
39
|
-
] as const satisfies readonly {
|
|
40
|
-
name: BundledSkillName;
|
|
41
|
-
description: string;
|
|
42
|
-
platforms: readonly ("claude-code" | "codex")[];
|
|
43
|
-
}[];
|
|
44
|
-
|
|
45
|
-
export const formatSkillsList = (): string =>
|
|
46
|
-
BUNDLED_SKILLS.map(
|
|
47
|
-
({ name, description, platforms }) => `${name}\t${description}\t${platforms.join(",")}`,
|
|
48
|
-
).join("\n");
|
|
49
|
-
|
|
50
|
-
const targetsFor = (
|
|
51
|
-
platform: SkillsPlatform,
|
|
52
|
-
cwd: string,
|
|
53
|
-
project: boolean,
|
|
54
|
-
dir?: string,
|
|
55
|
-
name?: BundledSkillName,
|
|
56
|
-
): (InstalledSkill & { source: string })[] => {
|
|
57
|
-
const platforms =
|
|
58
|
-
platform === "all"
|
|
59
|
-
? (["claude-code", "codex"] as const)
|
|
60
|
-
: ([platform === "claude" ? "claude-code" : platform] as const);
|
|
61
|
-
const scopeRoot = project ? resolve(cwd) : homedir();
|
|
62
|
-
const skills = name ? BUNDLED_SKILLS.filter((skill) => skill.name === name) : BUNDLED_SKILLS;
|
|
63
|
-
return platforms.flatMap((platformName) =>
|
|
64
|
-
skills
|
|
65
|
-
.filter((skill) =>
|
|
66
|
-
(skill.platforms as readonly ("claude-code" | "codex")[]).includes(platformName),
|
|
67
|
-
)
|
|
68
|
-
.map((skill) => ({
|
|
69
|
-
name: skill.name,
|
|
70
|
-
platform: platformName,
|
|
71
|
-
source: fileURLToPath(new URL(`../../skills/${skill.name}`, import.meta.url)),
|
|
72
|
-
path: dir
|
|
73
|
-
? join(resolve(dir), skill.name)
|
|
74
|
-
: join(
|
|
75
|
-
scopeRoot,
|
|
76
|
-
platformName === "claude-code" ? ".claude" : ".codex",
|
|
77
|
-
"skills",
|
|
78
|
-
skill.name,
|
|
79
|
-
),
|
|
80
|
-
})),
|
|
81
|
-
);
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
const copySkillDirectory = async (source: string, target: string): Promise<void> => {
|
|
85
|
-
const sourceInfo = await lstat(source);
|
|
86
|
-
if (!sourceInfo.isDirectory() || sourceInfo.isSymbolicLink()) {
|
|
87
|
-
throw new Error(`lux skills: bundled skill source is not a real directory: ${source}`);
|
|
88
|
-
}
|
|
89
|
-
await mkdir(target, { recursive: true });
|
|
90
|
-
for (const entry of await readdir(source, { withFileTypes: true })) {
|
|
91
|
-
const sourcePath = join(source, entry.name);
|
|
92
|
-
const targetPath = join(target, entry.name);
|
|
93
|
-
if (entry.isSymbolicLink()) {
|
|
94
|
-
throw new Error(`lux skills: bundled skill contains a symbolic link: ${sourcePath}`);
|
|
95
|
-
}
|
|
96
|
-
if (entry.isDirectory()) {
|
|
97
|
-
await copySkillDirectory(sourcePath, targetPath);
|
|
98
|
-
} else if (entry.isFile()) {
|
|
99
|
-
await mkdir(dirname(targetPath), { recursive: true });
|
|
100
|
-
await writeFile(targetPath, await readFile(sourcePath));
|
|
101
|
-
} else {
|
|
102
|
-
throw new Error(`lux skills: bundled skill contains an unsupported entry: ${sourcePath}`);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
};
|
|
106
|
-
|
|
107
|
-
export const installSkills = async (
|
|
108
|
-
options: z.input<typeof InstallSkillsOptionsSchema>,
|
|
109
|
-
): Promise<InstalledSkill[]> => {
|
|
110
|
-
const parsed = InstallSkillsOptionsSchema.parse(options);
|
|
111
|
-
const targets = targetsFor(parsed.platform, parsed.cwd, parsed.project, parsed.dir, parsed.name);
|
|
112
|
-
if (targets.length === 0) {
|
|
113
|
-
throw new Error(
|
|
114
|
-
`lux skills: '${parsed.name}' is not available for platform '${parsed.platform}'`,
|
|
115
|
-
);
|
|
116
|
-
}
|
|
117
|
-
for (const target of targets) await copySkillDirectory(target.source, target.path);
|
|
118
|
-
return targets.map(({ source: _, ...installed }) => installed);
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
export const formatSkillsInstall = (installed: InstalledSkill[], cwd: string): string =>
|
|
122
|
-
installed
|
|
123
|
-
.map(
|
|
124
|
-
({ name, platform, path }) =>
|
|
125
|
-
`installed ${name} skill for ${platform} at ${
|
|
126
|
-
relative(cwd, path).split(sep).join("/") || "."
|
|
127
|
-
}`,
|
|
128
|
-
)
|
|
129
|
-
.join("\n");
|