testeiya 0.3.9 → 0.3.10
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 +312 -27
- package/dist/prompt/index.js +6 -2
- package/dist/prompt/index.js.map +1 -1
- package/dist/prompt/print.js +8 -0
- package/dist/prompt/print.js.map +1 -1
- package/dist/prompt/system-prompt.js +14 -4
- package/dist/prompt/system-prompt.js.map +1 -1
- package/dist/prompt/testomatio.js +3 -3
- package/dist/prompt/tools.js +15 -7
- package/dist/prompt/tools.js.map +1 -1
- package/dist/src/args.js +147 -47
- package/dist/src/args.js.map +1 -1
- package/dist/src/cli.js +50 -14
- package/dist/src/cli.js.map +1 -1
- package/dist/src/doctor.js +186 -0
- package/dist/src/doctor.js.map +1 -0
- package/dist/src/env.js +29 -5
- package/dist/src/env.js.map +1 -1
- package/dist/src/mcp.js +3 -3
- package/dist/src/mcp.js.map +1 -1
- package/dist/src/model.js +15 -10
- package/dist/src/model.js.map +1 -1
- package/dist/src/models.js +38 -0
- package/dist/src/models.js.map +1 -0
- package/dist/src/output.js +185 -0
- package/dist/src/output.js.map +1 -0
- package/dist/src/run.js +116 -24
- package/dist/src/run.js.map +1 -1
- package/dist/src/session.js +38 -23
- package/dist/src/session.js.map +1 -1
- package/dist/src/sessions.js +61 -0
- package/dist/src/sessions.js.map +1 -0
- package/package.json +7 -3
- package/prompt/index.ts +11 -2
- package/prompt/print.ts +9 -0
- package/prompt/system-prompt.ts +18 -4
- package/prompt/testomatio.ts +3 -3
- package/prompt/tools.ts +15 -7
- package/skills/codeceptjs/ci-fix-tests/SKILL.md +119 -0
- package/skills/codeceptjs/codeceptjs-auth/SKILL.md +141 -0
- package/skills/codeceptjs/codeceptjs-exploration/SKILL.md +100 -0
- package/skills/codeceptjs/codeceptjs-fundamentals/SKILL.md +196 -0
- package/skills/codeceptjs/codeceptjs-run-analysis/SKILL.md +83 -0
- package/skills/codeceptjs/debugging-codeceptjs-tests/SKILL.md +126 -0
- package/skills/codeceptjs/migrate-codeceptjs-4/SKILL.md +109 -0
- package/skills/codeceptjs/migrate-cypress-to-codeceptjs/SKILL.md +295 -0
- package/skills/codeceptjs/migrate-protractor-to-codeceptjs/SKILL.md +339 -0
- package/skills/codeceptjs/migrate-selenium-java-to-codeceptjs/SKILL.md +459 -0
- package/skills/codeceptjs/migrate-testcafe-to-codeceptjs/SKILL.md +338 -0
- package/skills/codeceptjs/refactoring-codeceptjs-tests/SKILL.md +78 -0
- package/skills/codeceptjs/writing-codeceptjs-tests/SKILL.md +102 -0
- package/skills/playwright/playwright-best-practices/SKILL.md +303 -0
- package/skills/playwright/playwright-best-practices/advanced/authentication-flows.md +360 -0
- package/skills/playwright/playwright-best-practices/advanced/authentication.md +871 -0
- package/skills/playwright/playwright-best-practices/advanced/clock-mocking.md +364 -0
- package/skills/playwright/playwright-best-practices/advanced/mobile-testing.md +409 -0
- package/skills/playwright/playwright-best-practices/advanced/multi-context.md +288 -0
- package/skills/playwright/playwright-best-practices/advanced/multi-user.md +393 -0
- package/skills/playwright/playwright-best-practices/advanced/network-advanced.md +452 -0
- package/skills/playwright/playwright-best-practices/advanced/third-party.md +464 -0
- package/skills/playwright/playwright-best-practices/architecture/pom-vs-fixtures.md +363 -0
- package/skills/playwright/playwright-best-practices/architecture/test-architecture.md +369 -0
- package/skills/playwright/playwright-best-practices/architecture/when-to-mock.md +383 -0
- package/skills/playwright/playwright-best-practices/browser-apis/browser-apis.md +391 -0
- package/skills/playwright/playwright-best-practices/browser-apis/iframes.md +403 -0
- package/skills/playwright/playwright-best-practices/browser-apis/service-workers.md +504 -0
- package/skills/playwright/playwright-best-practices/browser-apis/websockets.md +403 -0
- package/skills/playwright/playwright-best-practices/core/annotations.md +424 -0
- package/skills/playwright/playwright-best-practices/core/assertions-waiting.md +361 -0
- package/skills/playwright/playwright-best-practices/core/configuration.md +452 -0
- package/skills/playwright/playwright-best-practices/core/fixtures-hooks.md +417 -0
- package/skills/playwright/playwright-best-practices/core/global-setup.md +434 -0
- package/skills/playwright/playwright-best-practices/core/locators.md +242 -0
- package/skills/playwright/playwright-best-practices/core/page-object-model.md +315 -0
- package/skills/playwright/playwright-best-practices/core/projects-dependencies.md +453 -0
- package/skills/playwright/playwright-best-practices/core/test-data.md +492 -0
- package/skills/playwright/playwright-best-practices/core/test-suite-structure.md +361 -0
- package/skills/playwright/playwright-best-practices/core/test-tags.md +298 -0
- package/skills/playwright/playwright-best-practices/debugging/console-errors.md +420 -0
- package/skills/playwright/playwright-best-practices/debugging/debugging.md +504 -0
- package/skills/playwright/playwright-best-practices/debugging/error-testing.md +360 -0
- package/skills/playwright/playwright-best-practices/debugging/flaky-tests.md +496 -0
- package/skills/playwright/playwright-best-practices/frameworks/angular.md +530 -0
- package/skills/playwright/playwright-best-practices/frameworks/nextjs.md +469 -0
- package/skills/playwright/playwright-best-practices/frameworks/react.md +531 -0
- package/skills/playwright/playwright-best-practices/frameworks/vue.md +574 -0
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/ci-cd.md +468 -0
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/docker.md +283 -0
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/github-actions.md +546 -0
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/gitlab.md +397 -0
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/other-providers.md +521 -0
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/parallel-sharding.md +371 -0
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/performance.md +453 -0
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/reporting.md +424 -0
- package/skills/playwright/playwright-best-practices/infrastructure-ci-cd/test-coverage.md +497 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/accessibility.md +359 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/api-testing.md +719 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/browser-extensions.md +506 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/canvas-webgl.md +493 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/component-testing.md +500 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/drag-drop.md +576 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/electron.md +509 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/file-operations.md +377 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/file-upload-download.md +562 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/forms-validation.md +561 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/graphql-testing.md +331 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/i18n.md +508 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/performance-testing.md +476 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/security-testing.md +430 -0
- package/skills/playwright/playwright-best-practices/testing-patterns/visual-regression.md +634 -0
- package/skills/playwright/playwright-cli/SKILL.md +420 -0
- package/skills/playwright/playwright-cli/references/element-attributes.md +23 -0
- package/skills/playwright/playwright-cli/references/playwright-tests.md +39 -0
- package/skills/playwright/playwright-cli/references/request-mocking.md +87 -0
- package/skills/playwright/playwright-cli/references/running-code.md +241 -0
- package/skills/playwright/playwright-cli/references/session-management.md +225 -0
- package/skills/playwright/playwright-cli/references/storage-state.md +275 -0
- package/skills/playwright/playwright-cli/references/test-generation.md +433 -0
- package/skills/playwright/playwright-cli/references/tracing.md +139 -0
- package/skills/playwright/playwright-cli/references/video-recording.md +143 -0
- package/skills/skills.lock.json +39 -36
- package/skills/testomatio/explorbot/explorbot-fundamentals/SKILL.md +76 -0
- package/skills/testomatio/explorbot/explorbot-fundamentals/references/no-install.md +36 -0
- package/skills/testomatio/explorbot/explorbot-plan/SKILL.md +108 -0
- package/skills/testomatio/explorbot/explorbot-setup/SKILL.md +86 -0
- package/skills/testomatio/qa-process/qa-explain-behavior/SKILL.md +111 -0
- package/skills/testomatio/qa-process/qa-explain-behavior/references/answer-shapes.md +116 -0
- package/skills/testomatio/qa-process/qa-explain-behavior/references/examples.md +157 -0
- package/skills/testomatio/qa-process/qa-lead-strategy-advisor/SKILL.md +91 -0
- package/skills/testomatio/qa-process/qa-lead-strategy-advisor/references/output-format.md +71 -0
- package/skills/testomatio/qa-process/testing-workflow/SKILL.md +227 -0
- package/skills/testomatio/test-automation/automate-manual-test-cases/CLAUDE.md +56 -0
- package/skills/testomatio/test-automation/automate-manual-test-cases/SKILL.md +242 -0
- package/skills/testomatio/test-automation/automate-manual-test-cases/references/CODECEPTJS_BEST_PRACTICES.md +182 -0
- package/skills/testomatio/test-automation/automate-manual-test-cases/references/FINAL_SUMMARY_TEMPLATE.md +22 -0
- package/skills/testomatio/test-automation/automate-manual-test-cases/references/PLAYWRIGHT_BEST_PRACTICES.md +90 -0
- package/skills/testomatio/test-automation/automate-manual-test-cases/references/POM_BEST_PRACTICES.md +53 -0
- package/skills/testomatio/test-automation/automate-manual-test-cases/references/TEST_DATA_MANAGEMENT.md +52 -0
- package/skills/testomatio/test-automation/debug-fix-failed-flaky-autotests/SKILL.md +107 -0
- package/skills/testomatio/test-automation/debug-fix-failed-flaky-autotests/references/DEBUGGING_QUICK_REFERENCE.md +113 -0
- package/skills/testomatio/test-automation/qa-automation-test-consolidation/SKILL.md +29 -0
- package/skills/testomatio/test-automation/qa-data-seeder/SKILL.md +83 -0
- package/skills/testomatio/test-automation/run-tests-with-testomatio-reporter/SKILL.md +153 -0
- package/skills/testomatio/test-automation/setup-change-aware-pr-testing/SKILL.md +190 -0
- package/skills/testomatio/test-automation/setup-ci-automation/SKILL.md +76 -0
- package/skills/testomatio/test-automation/testomat-allure-adapter/SKILL.md +289 -0
- package/skills/testomatio/test-management/detect-duplicate-test-cases/SKILL.md +86 -0
- package/skills/testomatio/test-management/detect-duplicate-test-cases/references/DUPLICATE_INSTRUCTIONS.md +54 -0
- package/skills/testomatio/test-management/improve-test-cases/SKILL.md +114 -0
- package/skills/testomatio/test-management/improve-test-cases/references/TESTOMAT_MARKDOWN_EXAMPLE.md +66 -0
- package/skills/testomatio/test-management/pull-request-diff-analyzer/SKILL.md +141 -0
- package/skills/testomatio/test-management/qa-e2e-tests-reporting/SKILL.md +354 -0
- package/skills/testomatio/test-management/qa-e2e-tests-reporting/references/TESTOMATIO_ARTIFACTS.md +82 -0
- package/skills/testomatio/test-management/qa-e2e-tests-reporting/references/TESTOMATIO_HTML_REPORT.md +37 -0
- package/skills/testomatio/test-management/qa-e2e-tests-reporting/references/TESTOMATIO_REPORTERS_CONFIG.md +118 -0
- package/skills/testomatio/test-management/qa-pr-requirements-analyzer/SKILL.md +149 -0
- package/skills/testomatio/test-management/qa-pr-requirements-analyzer/references/summary-example.md +54 -0
- package/skills/testomatio/test-management/qa-requirement-reviewer/SKILL.md +126 -0
- package/skills/testomatio/test-management/qa-requirement-reviewer/references/requirements_reviewer_examples.md +128 -0
- package/skills/testomatio/test-management/qa-split-testing-levels-pyramid/SKILL.md +55 -0
- package/skills/testomatio/test-management/qa-sprint-report-by-testomatio/SKILL.md +220 -0
- package/skills/testomatio/test-management/qa-sprint-report-by-testomatio/references/qa-sprint-report.md +126 -0
- package/skills/testomatio/test-management/qa-test-code-coverage/SKILL.md +174 -0
- package/skills/testomatio/test-management/qa-test-code-coverage/references/COVERAGE_FILE_FORMAT.md +138 -0
- package/skills/testomatio/test-management/qa-test-code-coverage/references/E2E_FRAMEWORKS.md +65 -0
- package/skills/testomatio/test-management/qa-test-code-coverage/scripts/check-coverage.mjs +40 -0
- package/skills/testomatio/test-management/qa-thinking/SKILL.md +36 -0
- package/skills/testomatio/test-management/qa-write-test-cases/SKILL.md +267 -0
- package/skills/testomatio/test-management/qa-write-test-cases/references/test-case-format.md +387 -0
- package/skills/testomatio/test-management/qa-write-test-cases/references/testomat-tms-guide.md +72 -0
- package/skills/testomatio/test-management/qa-write-test-cases/references/writing-rule.md +159 -0
- package/skills/testomatio/test-management/scan-automation-project/SKILL.md +152 -0
- package/skills/testomatio/test-management/sync-test-cases-with-tms/SKILL.md +107 -0
- package/skills/testomatio/test-management/sync-test-cases-with-tms/references/TESTOMATIO_CLI.md +140 -0
- package/skills/testomatio/test-management/testomatio-mcp/SKILL.md +195 -0
- package/skills/testomatio/test-management/testomatio-mcp/references/MCP_SETUP.md +177 -0
package/dist/src/args.js
CHANGED
|
@@ -1,72 +1,172 @@
|
|
|
1
1
|
import { parseArgs } from "node:util";
|
|
2
|
-
export const
|
|
2
|
+
export const WELCOME = `
|
|
3
|
+
Testeiya, an AI testing agent.
|
|
4
|
+
|
|
5
|
+
testeiya task "analyze this pr and find inconsistencies"
|
|
6
|
+
testeiya ask "is this feature ready"
|
|
7
|
+
|
|
8
|
+
testeiya doctor check your setup
|
|
9
|
+
testeiya --help options and environment
|
|
10
|
+
testeiya help the full guide
|
|
11
|
+
`;
|
|
12
|
+
export const USAGE = `testeiya, an AI testing agent
|
|
3
13
|
|
|
4
14
|
Usage:
|
|
5
|
-
testeiya "<task>"
|
|
6
|
-
|
|
15
|
+
testeiya task "<task>" run one task and write a report
|
|
16
|
+
testeiya ask "<question>" answer a question
|
|
17
|
+
testeiya doctor check what a run would resolve
|
|
18
|
+
testeiya models [pattern] list the models your key can reach
|
|
19
|
+
testeiya sessions list saved sessions for this folder
|
|
7
20
|
|
|
8
21
|
Options:
|
|
9
|
-
-o, --output <
|
|
10
|
-
|
|
11
|
-
--
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
22
|
+
-o, --output <dest> report destination, repeatable: file.md, file.json, gh:pr-comment
|
|
23
|
+
--model <id> provider/model to run
|
|
24
|
+
--project <id> Testomat.io project id
|
|
25
|
+
-c, --continue continue the last session in this folder
|
|
26
|
+
--resume <id> continue that session
|
|
27
|
+
--name <label> name the session
|
|
28
|
+
--no-session do not save the session
|
|
29
|
+
--json machine-readable output
|
|
30
|
+
--probe doctor only: test the key with one request
|
|
31
|
+
-h, --help show this
|
|
32
|
+
-v, --version show version
|
|
33
|
+
|
|
34
|
+
Environment:
|
|
35
|
+
TESTEIYA_MODEL model to run, e.g. openrouter/anthropic/claude-sonnet-5
|
|
36
|
+
OPENROUTER_API_KEY provider key, also ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY
|
|
37
|
+
TESTOMATIO Testomat.io project API key
|
|
38
|
+
TESTOMATIO_PROJECT_ID Testomat.io project id, same as --project
|
|
39
|
+
TESTOMATIO_URL Testomat.io base url, for self-hosted
|
|
40
|
+
|
|
41
|
+
Run "testeiya help" for the full guide.`;
|
|
42
|
+
export const HELP = `${USAGE}
|
|
43
|
+
|
|
44
|
+
Running a task
|
|
45
|
+
|
|
46
|
+
The agent runs one task and exits. There is no interactive mode. Progress and
|
|
47
|
+
errors go to stderr, so a run drops into CI as-is.
|
|
48
|
+
|
|
49
|
+
A task can also come from stdin: cat task.md | testeiya task
|
|
50
|
+
A task starting with "-" must follow "--": testeiya task -- "-weird task"
|
|
51
|
+
|
|
52
|
+
Exit codes: 0 pass, 1 failed run or negative verdict, 2 bad usage, 130 interrupted.
|
|
15
53
|
|
|
16
|
-
|
|
17
|
-
Without --output the agent's final answer is printed to stdout instead.
|
|
54
|
+
Where the report goes
|
|
18
55
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
~/.testeiya/auth.json.
|
|
56
|
+
--output names a destination and can repeat. Without one the report goes to
|
|
57
|
+
stdout. --json prints the run envelope to stdout instead.
|
|
22
58
|
|
|
23
|
-
|
|
24
|
-
the
|
|
25
|
-
|
|
59
|
+
report.md the agent writes the report there
|
|
60
|
+
run.json the run envelope: verdict, reason, report, tokens, session id
|
|
61
|
+
gh:pr-comment posted on this branch's pull request, through the GitHub CLI
|
|
62
|
+
gh:pr#123 posted on that pull request
|
|
26
63
|
|
|
27
|
-
|
|
64
|
+
Every destination is checked before the run starts, so a missing gh costs no
|
|
65
|
+
tokens.
|
|
28
66
|
|
|
29
|
-
|
|
67
|
+
Models and keys
|
|
68
|
+
|
|
69
|
+
There is no default model. Pass --model or set TESTEIYA_MODEL. A resumed run
|
|
70
|
+
reuses its session's model. "testeiya models" lists what your key can reach.
|
|
71
|
+
|
|
72
|
+
The provider key comes from the environment, from ~/.testeiya/.env, or from
|
|
73
|
+
~/.testeiya/auth.json, which is the file the desktop app's Settings dialog
|
|
74
|
+
writes.
|
|
75
|
+
|
|
76
|
+
Sessions
|
|
77
|
+
|
|
78
|
+
Runs are saved under ~/.testeiya, so a follow-up picks up where the last one
|
|
79
|
+
stopped. -c continues the last session in this folder, --resume <id> picks
|
|
80
|
+
another, --name labels one, and --no-session saves nothing.
|
|
81
|
+
|
|
82
|
+
Testomat.io
|
|
83
|
+
|
|
84
|
+
Set TESTOMATIO to a project API key and the agent reads and writes that
|
|
85
|
+
project's tests, suites, runs and plans through check-tests and the REST API.
|
|
86
|
+
Add the project id, with --project or TESTOMATIO_PROJECT_ID, and it also gets
|
|
87
|
+
the Testomat.io tools. The MCP server needs the id: a token alone does not say
|
|
88
|
+
which project to talk to.`;
|
|
89
|
+
export const COMMANDS = ["task", "ask", "models", "doctor", "sessions", "help"];
|
|
30
90
|
export function parseCliArgs(argv) {
|
|
91
|
+
const first = argv[0];
|
|
92
|
+
if (!first)
|
|
93
|
+
return { command: "welcome" };
|
|
94
|
+
if (first === "-h" || first === "--help")
|
|
95
|
+
return { command: "usage" };
|
|
96
|
+
if (first === "-v" || first === "--version")
|
|
97
|
+
return { command: "version" };
|
|
98
|
+
if (!isCommand(first))
|
|
99
|
+
return { error: unknownCommand(first) };
|
|
100
|
+
if (first === "help")
|
|
101
|
+
return { command: "help" };
|
|
102
|
+
const options = OPTIONS[first];
|
|
31
103
|
let parsed;
|
|
32
104
|
try {
|
|
33
|
-
parsed = parseArgs({
|
|
34
|
-
args: argv,
|
|
35
|
-
options: {
|
|
36
|
-
output: { type: "string", short: "o" },
|
|
37
|
-
print: { type: "string", short: "p" },
|
|
38
|
-
model: { type: "string" },
|
|
39
|
-
project: { type: "string" },
|
|
40
|
-
help: { type: "boolean", short: "h" },
|
|
41
|
-
version: { type: "boolean", short: "v" },
|
|
42
|
-
},
|
|
43
|
-
allowPositionals: true,
|
|
44
|
-
strict: true,
|
|
45
|
-
});
|
|
105
|
+
parsed = parseArgs({ args: argv.slice(1), options, allowPositionals: true, strict: true });
|
|
46
106
|
}
|
|
47
107
|
catch (err) {
|
|
48
108
|
if (err instanceof Error)
|
|
49
109
|
return { error: err.message };
|
|
50
110
|
return { error: String(err) };
|
|
51
111
|
}
|
|
52
|
-
const
|
|
112
|
+
const values = parsed.values;
|
|
53
113
|
if (values.help)
|
|
54
|
-
return {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
114
|
+
return { command: "usage" };
|
|
115
|
+
const args = { command: first };
|
|
116
|
+
const text = parsed.positionals.join(" ").trim();
|
|
117
|
+
if ((first === "task" || first === "ask") && text)
|
|
118
|
+
args.prompt = text;
|
|
119
|
+
if (first === "models" && text)
|
|
120
|
+
args.pattern = text;
|
|
121
|
+
if (Array.isArray(values.output))
|
|
122
|
+
args.outputs = values.output;
|
|
123
|
+
if (values.json)
|
|
124
|
+
args.json = true;
|
|
125
|
+
if (values.probe)
|
|
126
|
+
args.probe = true;
|
|
127
|
+
if (typeof values.model === "string")
|
|
67
128
|
args.model = values.model;
|
|
68
|
-
if (values.project)
|
|
129
|
+
if (typeof values.project === "string")
|
|
69
130
|
args.project = values.project;
|
|
131
|
+
if (values.continue)
|
|
132
|
+
args.continueLast = true;
|
|
133
|
+
if (typeof values.resume === "string")
|
|
134
|
+
args.resume = values.resume;
|
|
135
|
+
if (typeof values.name === "string")
|
|
136
|
+
args.name = values.name;
|
|
137
|
+
if (values["no-session"])
|
|
138
|
+
args.noSession = true;
|
|
70
139
|
return args;
|
|
71
140
|
}
|
|
141
|
+
const HELP_FLAG = { type: "boolean", short: "h" };
|
|
142
|
+
const JSON_FLAG = { type: "boolean" };
|
|
143
|
+
const RUN_OPTIONS = {
|
|
144
|
+
output: { type: "string", short: "o", multiple: true },
|
|
145
|
+
json: JSON_FLAG,
|
|
146
|
+
model: { type: "string" },
|
|
147
|
+
project: { type: "string" },
|
|
148
|
+
continue: { type: "boolean", short: "c" },
|
|
149
|
+
resume: { type: "string" },
|
|
150
|
+
name: { type: "string" },
|
|
151
|
+
"no-session": { type: "boolean" },
|
|
152
|
+
help: HELP_FLAG,
|
|
153
|
+
};
|
|
154
|
+
const OPTIONS = {
|
|
155
|
+
task: RUN_OPTIONS,
|
|
156
|
+
ask: RUN_OPTIONS,
|
|
157
|
+
models: { json: JSON_FLAG, help: HELP_FLAG },
|
|
158
|
+
doctor: { json: JSON_FLAG, probe: { type: "boolean" }, model: { type: "string" }, help: HELP_FLAG },
|
|
159
|
+
sessions: { json: JSON_FLAG, help: HELP_FLAG },
|
|
160
|
+
help: {},
|
|
161
|
+
};
|
|
162
|
+
function isCommand(value) {
|
|
163
|
+
return COMMANDS.includes(value);
|
|
164
|
+
}
|
|
165
|
+
// The task used to be the first positional, so a bare prompt is the mistake to
|
|
166
|
+
// expect. Name the fix rather than printing the whole usage at them.
|
|
167
|
+
function unknownCommand(value) {
|
|
168
|
+
if (value.startsWith("-"))
|
|
169
|
+
return `unknown option "${value}"`;
|
|
170
|
+
return `unknown command "${value}" — did you mean: testeiya task "${value}"`;
|
|
171
|
+
}
|
|
72
172
|
//# sourceMappingURL=args.js.map
|
package/dist/src/args.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/args.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/args.ts"],"names":[],"mappings":"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"}
|
package/dist/src/cli.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import { join } from "node:path";
|
|
4
|
-
import { parseCliArgs, USAGE } from "./args.js";
|
|
5
|
-
import {
|
|
4
|
+
import { HELP, parseCliArgs, USAGE, WELCOME } from "./args.js";
|
|
5
|
+
import { runDoctor } from "./doctor.js";
|
|
6
|
+
import { loadEnvFiles, PACKAGE_ROOT } from "./env.js";
|
|
6
7
|
import { UsageError } from "./model.js";
|
|
8
|
+
import { runModels } from "./models.js";
|
|
9
|
+
import { parseDestinations, preflight } from "./output.js";
|
|
7
10
|
import { runPrint } from "./run.js";
|
|
11
|
+
import { openSessionManager, runSessions } from "./sessions.js";
|
|
8
12
|
main(process.argv.slice(2)).catch((err) => {
|
|
9
13
|
process.stderr.write(`${err?.message ?? err}\n`);
|
|
10
14
|
process.exit(1);
|
|
@@ -16,28 +20,36 @@ async function main(argv) {
|
|
|
16
20
|
process.stderr.write(`${args.error}\n\n${USAGE}\n`);
|
|
17
21
|
process.exit(2);
|
|
18
22
|
}
|
|
19
|
-
if (args.
|
|
23
|
+
if (args.command === "welcome") {
|
|
24
|
+
process.stdout.write(`${WELCOME}\n`);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (args.command === "usage") {
|
|
20
28
|
process.stdout.write(`${USAGE}\n`);
|
|
21
29
|
return;
|
|
22
30
|
}
|
|
23
|
-
if (args.
|
|
31
|
+
if (args.command === "help") {
|
|
32
|
+
process.stdout.write(`${HELP}\n`);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (args.command === "version") {
|
|
24
36
|
process.stdout.write(`${version()}\n`);
|
|
25
37
|
return;
|
|
26
38
|
}
|
|
27
|
-
loadEnvFiles();
|
|
39
|
+
const envSources = loadEnvFiles();
|
|
28
40
|
// --project is a spelling of the env var the MCP server needs, so the rest of
|
|
29
41
|
// the CLI only ever reads the environment.
|
|
30
42
|
if (args.project)
|
|
31
43
|
process.env.TESTOMATIO_PROJECT_ID = args.project;
|
|
32
|
-
// No task and nothing piped in: there is no interactive mode, so this is a
|
|
33
|
-
// usage error rather than a prompt.
|
|
34
|
-
const prompt = args.prompt ?? (await readStdin());
|
|
35
|
-
if (!prompt.trim()) {
|
|
36
|
-
process.stderr.write(`${USAGE}\n`);
|
|
37
|
-
process.exit(2);
|
|
38
|
-
}
|
|
39
44
|
try {
|
|
40
|
-
|
|
45
|
+
if (args.command === "models")
|
|
46
|
+
process.exit(await runModels(args.pattern, args.json));
|
|
47
|
+
if (args.command === "doctor") {
|
|
48
|
+
process.exit(await runDoctor({ envSources, json: args.json, probe: args.probe, model: args.model }));
|
|
49
|
+
}
|
|
50
|
+
if (args.command === "sessions")
|
|
51
|
+
process.exit(await runSessions(process.cwd(), args.json));
|
|
52
|
+
process.exit(await task(args));
|
|
41
53
|
}
|
|
42
54
|
catch (err) {
|
|
43
55
|
if (!(err instanceof UsageError))
|
|
@@ -46,6 +58,30 @@ async function main(argv) {
|
|
|
46
58
|
process.exit(2);
|
|
47
59
|
}
|
|
48
60
|
}
|
|
61
|
+
async function task(args) {
|
|
62
|
+
const prompt = args.prompt ?? (await readStdin());
|
|
63
|
+
if (!prompt.trim()) {
|
|
64
|
+
process.stderr.write(` ${args.command} needs something to work on\n\n${USAGE}\n`);
|
|
65
|
+
process.exit(2);
|
|
66
|
+
}
|
|
67
|
+
const destinations = parseDestinations(args.outputs ?? [], args.json);
|
|
68
|
+
if (typeof destinations === "string")
|
|
69
|
+
throw new UsageError(destinations);
|
|
70
|
+
// Everything a destination needs is checked before a single token is spent.
|
|
71
|
+
const unreachable = await preflight(destinations);
|
|
72
|
+
if (unreachable)
|
|
73
|
+
throw new UsageError(unreachable);
|
|
74
|
+
const sessionManager = await openSessionManager(process.cwd(), args);
|
|
75
|
+
if (typeof sessionManager === "string")
|
|
76
|
+
throw new UsageError(sessionManager);
|
|
77
|
+
if (args.name)
|
|
78
|
+
sessionManager.appendSessionInfo(args.name);
|
|
79
|
+
let sessionId = null;
|
|
80
|
+
if (!args.noSession)
|
|
81
|
+
sessionId = sessionManager.getSessionId();
|
|
82
|
+
const brief = args.command === "ask";
|
|
83
|
+
return runPrint({ prompt, destinations, sessionManager, sessionId, brief, model: args.model });
|
|
84
|
+
}
|
|
49
85
|
async function readStdin() {
|
|
50
86
|
if (process.stdin.isTTY)
|
|
51
87
|
return "";
|
|
@@ -55,7 +91,7 @@ async function readStdin() {
|
|
|
55
91
|
return Buffer.concat(chunks).toString("utf8");
|
|
56
92
|
}
|
|
57
93
|
function version() {
|
|
58
|
-
const pkg = JSON.parse(readFileSync(join(
|
|
94
|
+
const pkg = JSON.parse(readFileSync(join(PACKAGE_ROOT, "package.json"), "utf8"));
|
|
59
95
|
return pkg.version;
|
|
60
96
|
}
|
|
61
97
|
//# sourceMappingURL=cli.js.map
|
package/dist/src/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,OAAO,EAAgB,MAAM,WAAW,CAAC;AAC7E,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEhE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,EAAE,OAAO,IAAI,GAAG,IAAI,CAAC,CAAC;IACjD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,KAAK,UAAU,IAAI,CAAC,IAAc;IAChC,OAAO,CAAC,KAAK,GAAG,UAAU,CAAC;IAE3B,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,OAAO,KAAK,IAAI,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;QACrC,OAAO;IACT,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,KAAK,OAAO,EAAE,CAAC;QAC7B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC;QACnC,OAAO;IACT,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,KAAK,MAAM,EAAE,CAAC;QAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,IAAI,CAAC,CAAC;QAClC,OAAO;IACT,CAAC;IACD,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,OAAO,EAAE,IAAI,CAAC,CAAC;QACvC,OAAO;IACT,CAAC;IAED,MAAM,UAAU,GAAG,YAAY,EAAE,CAAC;IAClC,8EAA8E;IAC9E,2CAA2C;IAC3C,IAAI,IAAI,CAAC,OAAO;QAAE,OAAO,CAAC,GAAG,CAAC,qBAAqB,GAAG,IAAI,CAAC,OAAO,CAAC;IAEnE,IAAI,CAAC;QACH,IAAI,IAAI,CAAC,OAAO,KAAK,QAAQ;YAAE,OAAO,CAAC,IAAI,CAAC,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACtF,IAAI,IAAI,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,MAAM,SAAS,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QACvG,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,KAAK,UAAU;YAAE,OAAO,CAAC,IAAI,CAAC,MAAM,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC3F,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,CAAC,GAAG,YAAY,UAAU,CAAC;YAAE,MAAM,GAAG,CAAC;QAC5C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;QAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,IAAI,CAAC,IAAa;IAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,SAAS,EAAE,CAAC,CAAC;IAClD,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,OAAO,kCAAkC,KAAK,IAAI,CAAC,CAAC;QACnF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,YAAY,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACtE,IAAI,OAAO,YAAY,KAAK,QAAQ;QAAE,MAAM,IAAI,UAAU,CAAC,YAAY,CAAC,CAAC;IAEzE,4EAA4E;IAC5E,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,YAAY,CAAC,CAAC;IAClD,IAAI,WAAW;QAAE,MAAM,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC;IAEnD,MAAM,cAAc,GAAG,MAAM,kBAAkB,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC;IACrE,IAAI,OAAO,cAAc,KAAK,QAAQ;QAAE,MAAM,IAAI,UAAU,CAAC,cAAc,CAAC,CAAC;IAC7E,IAAI,IAAI,CAAC,IAAI;QAAE,cAAc,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAE3D,IAAI,SAAS,GAAkB,IAAI,CAAC;IACpC,IAAI,CAAC,IAAI,CAAC,SAAS;QAAE,SAAS,GAAG,cAAc,CAAC,YAAY,EAAE,CAAC;IAE/D,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,KAAK,KAAK,CAAC;IACrC,OAAO,QAAQ,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;AACjG,CAAC;AAED,KAAK,UAAU,SAAS;IACtB,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACnC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK;QAAE,MAAM,CAAC,IAAI,CAAC,KAAe,CAAC,CAAC;IACtE,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,OAAO;IACd,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACpB,YAAY,CAAC,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CACzD,CAAC;IACF,OAAO,GAAG,CAAC,OAAO,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { SettingsManager } from "@earendil-works/pi-coding-agent";
|
|
3
|
+
import { dirname, relative } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { TESTEIYA_HOME } from "./env.js";
|
|
6
|
+
import { hasMcp, hasTestomatio, metadataCachePath, vendorBundle } from "./mcp.js";
|
|
7
|
+
import { PROVIDER_KEYS, resolveModel, UsageError } from "./model.js";
|
|
8
|
+
import { BUNDLED_SKILLS_DIR, createLoader, createRuntime } from "./session.js";
|
|
9
|
+
const MIN_NODE = [22, 19];
|
|
10
|
+
/**
|
|
11
|
+
* Everything a run resolves silently: which key file won, whether skills loaded,
|
|
12
|
+
* whether MCP is on. Reads config only — `--probe` is the one check that spends.
|
|
13
|
+
*/
|
|
14
|
+
export async function runDoctor(options) {
|
|
15
|
+
const checks = [nodeCheck(), homeCheck()];
|
|
16
|
+
const runtime = await createRuntime();
|
|
17
|
+
checks.push(keyCheck(runtime, options.envSources));
|
|
18
|
+
const model = modelCheck(runtime, options.model);
|
|
19
|
+
checks.push(model.check);
|
|
20
|
+
const skills = await skillsChecks();
|
|
21
|
+
checks.push(...skills.checks);
|
|
22
|
+
checks.push(testomatioCheck(), mcpCacheCheck());
|
|
23
|
+
if (options.probe)
|
|
24
|
+
checks.push(await probeCheck(runtime, model.resolved));
|
|
25
|
+
if (options.json) {
|
|
26
|
+
const report = {
|
|
27
|
+
checks: checks.filter((check) => check.status !== "list"),
|
|
28
|
+
skills: skills.groups,
|
|
29
|
+
};
|
|
30
|
+
process.stdout.write(`${JSON.stringify(report, null, 2)}\n`);
|
|
31
|
+
return worst(checks) === "fail" ? 1 : 0;
|
|
32
|
+
}
|
|
33
|
+
process.stdout.write("\n");
|
|
34
|
+
for (const check of checks) {
|
|
35
|
+
process.stdout.write(` ${MARK[check.status]} ${check.name.padEnd(12)} ${check.detail}\n`);
|
|
36
|
+
}
|
|
37
|
+
process.stdout.write("\n");
|
|
38
|
+
return worst(checks) === "fail" ? 1 : 0;
|
|
39
|
+
}
|
|
40
|
+
function nodeCheck() {
|
|
41
|
+
const version = process.versions.node;
|
|
42
|
+
const [major = 0, minor = 0] = version.split(".").map(Number);
|
|
43
|
+
if (major > MIN_NODE[0] || (major === MIN_NODE[0] && minor >= MIN_NODE[1])) {
|
|
44
|
+
return { name: "node", status: "ok", detail: `v${version}` };
|
|
45
|
+
}
|
|
46
|
+
return { name: "node", status: "fail", detail: `v${version}, needs v22.19 or newer` };
|
|
47
|
+
}
|
|
48
|
+
function homeCheck() {
|
|
49
|
+
if (!existsSync(TESTEIYA_HOME)) {
|
|
50
|
+
return { name: "home", status: "warn", detail: `${TESTEIYA_HOME} (not created yet)` };
|
|
51
|
+
}
|
|
52
|
+
return { name: "home", status: "ok", detail: TESTEIYA_HOME };
|
|
53
|
+
}
|
|
54
|
+
// The key can come from four places and nothing else ever says which one won.
|
|
55
|
+
function keyCheck(runtime, sources) {
|
|
56
|
+
const found = [];
|
|
57
|
+
for (const { provider, env } of PROVIDER_KEYS) {
|
|
58
|
+
if (process.env[env]) {
|
|
59
|
+
found.push(`${provider} from ${sources.get(env) ?? "environment"}`);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (runtime.hasConfiguredAuth(provider))
|
|
63
|
+
found.push(`${provider} from auth.json`);
|
|
64
|
+
}
|
|
65
|
+
if (found.length === 0) {
|
|
66
|
+
return { name: "key", status: "fail", detail: "none — set OPENROUTER_API_KEY or similar" };
|
|
67
|
+
}
|
|
68
|
+
return { name: "key", status: "ok", detail: found.join(", ") };
|
|
69
|
+
}
|
|
70
|
+
function modelCheck(runtime, explicit) {
|
|
71
|
+
try {
|
|
72
|
+
const model = resolveModel(runtime, explicit);
|
|
73
|
+
return {
|
|
74
|
+
check: { name: "model", status: "ok", detail: `${model.provider}/${model.id}` },
|
|
75
|
+
resolved: model,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
const detail = err instanceof UsageError ? err.message : String(err);
|
|
80
|
+
return { check: { name: "model", status: "warn", detail } };
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async function skillsChecks() {
|
|
84
|
+
const loader = createLoader({
|
|
85
|
+
cwd: process.cwd(),
|
|
86
|
+
settingsManager: SettingsManager.inMemory(),
|
|
87
|
+
extensionPaths: [],
|
|
88
|
+
systemPrompt: () => "",
|
|
89
|
+
});
|
|
90
|
+
await loader.reload();
|
|
91
|
+
const { skills, diagnostics } = loader.getSkills();
|
|
92
|
+
const groups = byGroup(skills);
|
|
93
|
+
const checks = [];
|
|
94
|
+
if (skills.length === 0) {
|
|
95
|
+
checks.push({ name: "skills", status: "warn", detail: "none loaded" });
|
|
96
|
+
}
|
|
97
|
+
if (skills.length > 0) {
|
|
98
|
+
checks.push({ name: "skills", status: "ok", detail: `${skills.length} loaded` });
|
|
99
|
+
for (const [group, names] of groups) {
|
|
100
|
+
checks.push({ name: "", status: "list", detail: `${group.padEnd(28)} ${summarize(names)}` });
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Collisions and parse errors were dropped on the floor before this command.
|
|
104
|
+
for (const diagnostic of diagnostics) {
|
|
105
|
+
const status = diagnostic.type === "error" ? "fail" : "warn";
|
|
106
|
+
let detail = diagnostic.message;
|
|
107
|
+
if (diagnostic.path)
|
|
108
|
+
detail = `${detail} — ${shorten(diagnostic.path)}`;
|
|
109
|
+
checks.push({ name: "skills", status, detail });
|
|
110
|
+
}
|
|
111
|
+
return { checks, groups: [...groups].map(([group, names]) => ({ group, skills: names })) };
|
|
112
|
+
}
|
|
113
|
+
function shorten(path) {
|
|
114
|
+
const inBundle = relative(BUNDLED_SKILLS_DIR, path);
|
|
115
|
+
if (inBundle.startsWith(".."))
|
|
116
|
+
return path;
|
|
117
|
+
return inBundle;
|
|
118
|
+
}
|
|
119
|
+
// The full list is in --json; this line only has to prove the right set loaded.
|
|
120
|
+
function summarize(names) {
|
|
121
|
+
if (names.length <= 6)
|
|
122
|
+
return names.join(", ");
|
|
123
|
+
return `${names.slice(0, 6).join(", ")}, +${names.length - 6}`;
|
|
124
|
+
}
|
|
125
|
+
function byGroup(skills) {
|
|
126
|
+
const groups = new Map();
|
|
127
|
+
for (const skill of skills) {
|
|
128
|
+
let group = dirname(relative(BUNDLED_SKILLS_DIR, skill.baseDir));
|
|
129
|
+
if (group === "." || group.startsWith(".."))
|
|
130
|
+
group = "bundled";
|
|
131
|
+
const names = groups.get(group) ?? [];
|
|
132
|
+
names.push(skill.name);
|
|
133
|
+
groups.set(group, names);
|
|
134
|
+
}
|
|
135
|
+
return groups;
|
|
136
|
+
}
|
|
137
|
+
function testomatioCheck() {
|
|
138
|
+
if (!hasTestomatio()) {
|
|
139
|
+
return { name: "testomatio", status: "warn", detail: "no TESTOMATIO token, not connected" };
|
|
140
|
+
}
|
|
141
|
+
if (!hasMcp()) {
|
|
142
|
+
return {
|
|
143
|
+
name: "testomatio",
|
|
144
|
+
status: "warn",
|
|
145
|
+
detail: "token set, no project id — check-tests and REST only",
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
return { name: "testomatio", status: "ok", detail: "token and project id, MCP tools on" };
|
|
149
|
+
}
|
|
150
|
+
function mcpCacheCheck() {
|
|
151
|
+
if (!hasMcp())
|
|
152
|
+
return { name: "mcp", status: "ok", detail: "off" };
|
|
153
|
+
const bundle = fileURLToPath(vendorBundle());
|
|
154
|
+
if (!existsSync(bundle)) {
|
|
155
|
+
return { name: "mcp", status: "fail", detail: "vendor bundle missing — run npm run build" };
|
|
156
|
+
}
|
|
157
|
+
if (!existsSync(metadataCachePath())) {
|
|
158
|
+
return { name: "mcp", status: "warn", detail: "tool cache empty, first run is proxy-only" };
|
|
159
|
+
}
|
|
160
|
+
return { name: "mcp", status: "ok", detail: "direct tools and proxy" };
|
|
161
|
+
}
|
|
162
|
+
async function probeCheck(runtime, model) {
|
|
163
|
+
if (!model)
|
|
164
|
+
return { name: "probe", status: "warn", detail: "skipped, no model to probe" };
|
|
165
|
+
const message = await runtime
|
|
166
|
+
.completeSimple(model, { messages: [{ role: "user", content: "ping", timestamp: Date.now() }] })
|
|
167
|
+
.catch((err) => ({ stopReason: "error", errorMessage: String(err) }));
|
|
168
|
+
if (message.stopReason === "error") {
|
|
169
|
+
return { name: "probe", status: "fail", detail: message.errorMessage ?? "request failed" };
|
|
170
|
+
}
|
|
171
|
+
return { name: "probe", status: "ok", detail: "the key works" };
|
|
172
|
+
}
|
|
173
|
+
function worst(checks) {
|
|
174
|
+
if (checks.some((check) => check.status === "fail"))
|
|
175
|
+
return "fail";
|
|
176
|
+
if (checks.some((check) => check.status === "warn"))
|
|
177
|
+
return "warn";
|
|
178
|
+
return "ok";
|
|
179
|
+
}
|
|
180
|
+
const MARK = {
|
|
181
|
+
ok: "✓",
|
|
182
|
+
warn: "!",
|
|
183
|
+
fail: "✗",
|
|
184
|
+
list: " ",
|
|
185
|
+
};
|
|
186
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/doctor.ts"],"names":[],"mappings":"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"}
|
package/dist/src/env.js
CHANGED
|
@@ -6,11 +6,19 @@ import { dirname, join } from "node:path";
|
|
|
6
6
|
* in its Settings dialog works here with no extra step.
|
|
7
7
|
*/
|
|
8
8
|
export const TESTEIYA_HOME = join(homedir(), ".testeiya");
|
|
9
|
+
/**
|
|
10
|
+
* This package's root, found by walking up to package.json — `dist/src` when
|
|
11
|
+
* built, `src` when run from source. Bundled files resolve from here.
|
|
12
|
+
*/
|
|
13
|
+
export const PACKAGE_ROOT = packageRoot();
|
|
9
14
|
/**
|
|
10
15
|
* Where pi keeps its own state for this CLI. Deliberately not `~/.pi` — running
|
|
11
16
|
* `npx testeiya` must not write into a user's own pi installation.
|
|
12
17
|
*/
|
|
13
18
|
export const PI_STATE_DIR = join(TESTEIYA_HOME, "pi");
|
|
19
|
+
// pi reads this at import time to place sessions and its MCP cache, and a
|
|
20
|
+
// SessionManager is built before any session exists to read it from.
|
|
21
|
+
process.env.PI_CODING_AGENT_DIR = PI_STATE_DIR;
|
|
14
22
|
/**
|
|
15
23
|
* Fill gaps in process.env from `~/.testeiya/.env`, then from any `.env` found
|
|
16
24
|
* walking up from the working directory — so running in a repo picks up that
|
|
@@ -19,17 +27,21 @@ export const PI_STATE_DIR = join(TESTEIYA_HOME, "pi");
|
|
|
19
27
|
* The walk starts at cwd, never at this file: an installed package sits under
|
|
20
28
|
* some node_modules whose ancestors are none of the agent's business, and
|
|
21
29
|
* silently adopting a key from there is a surprise, not a convenience.
|
|
30
|
+
*
|
|
31
|
+
* Returns the file each variable came from, which is what `doctor` reports.
|
|
22
32
|
*/
|
|
23
33
|
export function loadEnvFiles() {
|
|
24
|
-
|
|
34
|
+
const sources = new Map();
|
|
35
|
+
loadFile(join(TESTEIYA_HOME, ".env"), sources);
|
|
25
36
|
let dir = process.cwd();
|
|
26
37
|
for (let i = 0; i < 8; i++) {
|
|
27
|
-
loadFile(join(dir, ".env"));
|
|
38
|
+
loadFile(join(dir, ".env"), sources);
|
|
28
39
|
const parent = dirname(dir);
|
|
29
40
|
if (parent === dir)
|
|
30
41
|
break;
|
|
31
42
|
dir = parent;
|
|
32
43
|
}
|
|
44
|
+
return sources;
|
|
33
45
|
}
|
|
34
46
|
export function parseEnv(content) {
|
|
35
47
|
const out = {};
|
|
@@ -51,7 +63,7 @@ export function parseEnv(content) {
|
|
|
51
63
|
}
|
|
52
64
|
return out;
|
|
53
65
|
}
|
|
54
|
-
function loadFile(path) {
|
|
66
|
+
function loadFile(path, sources) {
|
|
55
67
|
if (!existsSync(path))
|
|
56
68
|
return;
|
|
57
69
|
let vars;
|
|
@@ -62,8 +74,20 @@ function loadFile(path) {
|
|
|
62
74
|
return;
|
|
63
75
|
}
|
|
64
76
|
for (const [key, value] of Object.entries(vars)) {
|
|
65
|
-
if (process.env[key]
|
|
66
|
-
|
|
77
|
+
if (process.env[key] !== undefined)
|
|
78
|
+
continue;
|
|
79
|
+
process.env[key] = value;
|
|
80
|
+
sources.set(key, path);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function packageRoot() {
|
|
84
|
+
let dir = import.meta.dirname;
|
|
85
|
+
while (!existsSync(join(dir, "package.json"))) {
|
|
86
|
+
const parent = dirname(dir);
|
|
87
|
+
if (parent === dir)
|
|
88
|
+
return import.meta.dirname;
|
|
89
|
+
dir = parent;
|
|
67
90
|
}
|
|
91
|
+
return dir;
|
|
68
92
|
}
|
|
69
93
|
//# sourceMappingURL=env.js.map
|