@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.
@@ -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 cloud coding agent running in GitHub Actions.
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
- - After creating a branch or opening a PR, IMMEDIATELY run:
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
- const checkoutMatch = text.match(/checkout\s+-b\s+((?:testchimp-|chimphands-)[^\s'"]+)/i);
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 branchMatch = text.match(/branch['":\s]+((?:testchimp-|chimphands-)[^\s'"]+)/i);
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-compatible",
335
+ npm: "@ai-sdk/openai",
316
336
  name: "TestChimp",
317
337
  options: providerOptions,
318
338
  models: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testchimp/cli",
3
- "version": "0.1.42",
3
+ "version": "0.1.44",
4
4
  "description": "TestChimp CLI and MCP server — coverage, plans, EaaS, TrueCoverage, API operations (calls /api/mcp/*)",
5
5
  "type": "module",
6
6
  "main": "dist/bin/testchimp.js",