@testchimp/cli 0.1.42 → 0.1.44
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/dist/chimphands/run.js +27 -7
- package/package.json +1 -1
package/dist/chimphands/run.js
CHANGED
|
@@ -19,7 +19,14 @@ const STATUS_IDLE = "CHIMPHANDS_SESSION_STATUS_IDLE";
|
|
|
19
19
|
const STATUS_FAILED = "CHIMPHANDS_SESSION_STATUS_FAILED";
|
|
20
20
|
const OPENCODE_AGENT_ID = "chimphands";
|
|
21
21
|
const STREAM_POST_MIN_INTERVAL_MS = 60;
|
|
22
|
-
const CHIMPHANDS_AGENT_PROMPT = `You are ChimpHands, TestChimp's
|
|
22
|
+
const CHIMPHANDS_AGENT_PROMPT = `You are ChimpHands, TestChimp's coding agent. You run on GitHub Actions, but this chat is an **interactive** conversation with the user in the TestChimp UI — same expectations as Cursor/Claude Code locally.
|
|
23
|
+
|
|
24
|
+
## Interactive session (mandatory — default)
|
|
25
|
+
- Default mode is **interactive**. Ask clarifying questions, seek plan approval, and wait for the user's reply — just as you would in Cursor.
|
|
26
|
+
- \`GITHUB_ACTIONS\`, \`CLOUD_AGENT\`, and "running in CI" mean **where** you execute (runner + \`TESTCHIMP_EXECUTION_SOURCE\`). They do **NOT** mean skip questions, invent defaults, or auto-approve.
|
|
27
|
+
- Only treat the run as non-interactive when the **user prompt** literally includes \`--mode=non-interactive\` (or \`mode=non-interactive\`), or the resolved skill policy explicitly sets \`allow-execute-without-approval\`.
|
|
28
|
+
- When you need clarification (e.g. import plans/tests, env strategy, CI choices) or plan approval: write the questions / plan summary as assistant text, then **stop this turn**. Do not invent answers or continue into Execute. The host will wait for the next chat message and revive you.
|
|
29
|
+
- Prefer a short numbered list of concrete questions over a long monologue. One decision gate at a time when possible (especially \`/testchimp project init\` Phase 1).
|
|
23
30
|
|
|
24
31
|
## Repo changes (mandatory)
|
|
25
32
|
- NEVER commit or push directly to the default branch (main/master).
|
|
@@ -27,14 +34,17 @@ const CHIMPHANDS_AGENT_PROMPT = `You are ChimpHands, TestChimp's cloud coding ag
|
|
|
27
34
|
- If bootstrap lists a working branch, checkout that branch and push additional commits there — update the same PR.
|
|
28
35
|
- Only create a NEW branch/PR when (a) no working branch exists yet for this conversation, or (b) the prior PR was merged/closed (verify with \`gh pr view\`).
|
|
29
36
|
- Branch names MUST start with \`testchimp-\` or \`chimphands-\`.
|
|
30
|
-
-
|
|
37
|
+
- When creating a NEW working branch: create it, then IMMEDIATELY publish it with
|
|
38
|
+
\`git push -u origin <branch>\` BEFORE calling report-branch. Users open the branch URL in the UI —
|
|
39
|
+
do not report a branch that only exists locally (that causes GitHub 404).
|
|
40
|
+
- After the branch is on the remote (and after opening a PR), IMMEDIATELY run:
|
|
31
41
|
\`testchimp chimphands report-branch --branch <name> [--pr-url <url>]\`
|
|
32
42
|
- Tell the user which branch you are on and include the PR URL when available.
|
|
33
43
|
|
|
34
44
|
## TestChimp workflows (/testchimp …)
|
|
35
45
|
- Load and follow the \`testchimp\` skill under \`.agents/skills/testchimp/SKILL.md\`.
|
|
36
46
|
- For any /testchimp command: use TestChimp MCP tools (preferred) or \`testchimp\` CLI — never invent API results.
|
|
37
|
-
- Follow plan → explicit user approval → execute. Do not skip MCP calls or claim done without tool evidence.
|
|
47
|
+
- Follow plan → explicit user approval → execute (interactive default). Do not skip MCP calls or claim done without tool evidence.
|
|
38
48
|
- Export \`TESTCHIMP_EXECUTION_SOURCE=CLOUD_AGENT\` before Playwright/Mobilewright runs.
|
|
39
49
|
|
|
40
50
|
## Honesty
|
|
@@ -251,12 +261,21 @@ function isMissingOpencodeSessionError(message) {
|
|
|
251
261
|
m.includes("unknown session") ||
|
|
252
262
|
m.includes("invalid session"));
|
|
253
263
|
}
|
|
264
|
+
function isNonInteractivePrompt(userPrompt) {
|
|
265
|
+
return /(?:^|\s)--mode\s*=?\s*non-interactive\b|mode\s*=\s*non-interactive\b/i.test(userPrompt);
|
|
266
|
+
}
|
|
267
|
+
function isTestchimpWorkflowPrompt(userPrompt) {
|
|
268
|
+
return /(?:^|\s)\/?testchimp\b/i.test(userPrompt.trim());
|
|
269
|
+
}
|
|
254
270
|
function wrapPromptWithContext(conversationSummary, userPrompt, isNewOpencodeSession, workingBranch, pullRequestUrl) {
|
|
255
271
|
const parts = [];
|
|
256
272
|
if (workingBranch?.trim()) {
|
|
257
273
|
parts.push("## Conversation working branch (reuse for this thread)", `Branch: \`${workingBranch.trim()}\``, pullRequestUrl?.trim() ? `PR: ${pullRequestUrl.trim()}` : "", "Checkout this branch, commit and push here. Do NOT open a new PR unless the one above was merged/closed.", "");
|
|
258
274
|
}
|
|
259
275
|
const task = normalizeUserMessage(userPrompt);
|
|
276
|
+
if (isTestchimpWorkflowPrompt(task) && !isNonInteractivePrompt(task)) {
|
|
277
|
+
parts.push("## Interactive turn reminder", "This is an interactive ChimpHands chat (not autonomous CI). Ask clarifying questions / seek plan approval, then end the turn and wait — do not invent defaults or Execute until the user replies. Only `--mode=non-interactive` skips that pause.", "");
|
|
278
|
+
}
|
|
260
279
|
if (isNewOpencodeSession && conversationSummary.trim()) {
|
|
261
280
|
parts.push(`Conversation so far:\n${conversationSummary.trim()}`, "", `Current task:\n${task}`);
|
|
262
281
|
return parts.filter(Boolean).join("\n");
|
|
@@ -272,10 +291,10 @@ function detectWorkingBranchFromToolOutput(output) {
|
|
|
272
291
|
if (!text)
|
|
273
292
|
return {};
|
|
274
293
|
const prMatch = text.match(/https:\/\/github\.com\/[^\s)\]]+\/pull\/\d+/);
|
|
275
|
-
|
|
294
|
+
// Only auto-detect after a successful push to origin — local checkout -b alone would
|
|
295
|
+
// report a branch URL that 404s until the remote ref exists.
|
|
276
296
|
const pushMatch = text.match(/push\s+(?:--set-upstream\s+|-u\s+)?origin\s+((?:testchimp-|chimphands-)[^\s'"]+)/i);
|
|
277
|
-
const
|
|
278
|
-
const branch = (checkoutMatch?.[1] || pushMatch?.[1] || branchMatch?.[1])?.replace(/[`'"]/g, "");
|
|
297
|
+
const branch = pushMatch?.[1]?.replace(/[`'"]/g, "");
|
|
279
298
|
return {
|
|
280
299
|
branch,
|
|
281
300
|
pullRequestUrl: prMatch?.[0],
|
|
@@ -305,6 +324,7 @@ function writeOpencodeConfig(backend, apiKey, boot) {
|
|
|
305
324
|
"X-TestChimp-ChimpHands-Session-Id": sessionId,
|
|
306
325
|
};
|
|
307
326
|
}
|
|
327
|
+
// @ai-sdk/openai uses /v1/responses (tools + reasoning). openai-compatible is chat-only.
|
|
308
328
|
writeFileSync("opencode.json", JSON.stringify({
|
|
309
329
|
$schema: "https://opencode.ai/config.json",
|
|
310
330
|
model,
|
|
@@ -312,7 +332,7 @@ function writeOpencodeConfig(backend, apiKey, boot) {
|
|
|
312
332
|
autoupdate: false,
|
|
313
333
|
provider: {
|
|
314
334
|
[TESTCHIMP_PROVIDER_ID]: {
|
|
315
|
-
npm: "@ai-sdk/openai
|
|
335
|
+
npm: "@ai-sdk/openai",
|
|
316
336
|
name: "TestChimp",
|
|
317
337
|
options: providerOptions,
|
|
318
338
|
models: {
|
package/package.json
CHANGED