@testchimp/cli 0.1.77 → 0.1.79

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.
@@ -1105,6 +1105,10 @@ function writeOpencodeConfig(backend, apiKey, boot, llmBaseOverride) {
1105
1105
  TESTCHIMP_EXECUTION_SOURCE: "CLOUD_AGENT",
1106
1106
  CHIMPHANDS_UI_ATTACHED: uiAttached ? "true" : "false",
1107
1107
  };
1108
+ if (sessionId) {
1109
+ mcpEnv.SESSION_ID = sessionId;
1110
+ mcpEnv.CHIMPHANDS_SESSION_ID = sessionId;
1111
+ }
1108
1112
  const serviceUserId = bootStr(boot, "chimphands_service_account_user_id", "chimphandsServiceAccountUserId");
1109
1113
  if (serviceUserId) {
1110
1114
  mcpEnv.TESTCHIMP_USER_ID = serviceUserId;
@@ -2192,6 +2196,8 @@ export async function runChimphands(opts) {
2192
2196
  TESTCHIMP_API_KEY: apiKey,
2193
2197
  TESTCHIMP_BACKEND_URL: backend,
2194
2198
  TESTCHIMP_EXECUTION_SOURCE: "CLOUD_AGENT",
2199
+ SESSION_ID: sessionId,
2200
+ CHIMPHANDS_SESSION_ID: sessionId,
2195
2201
  };
2196
2202
  if (userId)
2197
2203
  childEnv.TESTCHIMP_USER_ID = userId;
@@ -434,6 +434,38 @@ export function buildCliProgram() {
434
434
  const out = await runTool("get-test-scenarios", merged, { postMcp });
435
435
  console.log(out);
436
436
  });
437
+ program
438
+ .command("list-test-scenarios-for-scope")
439
+ .description(TOOL_DEFINITIONS.find((t) => t.kebab === "list-test-scenarios-for-scope").description)
440
+ .addOption(jsonInputOption())
441
+ .option("--named-test-run-id <id>", "named test run id")
442
+ .option("--release <label>", "release catalog version / label")
443
+ .option("--plans-path <path>", "platform plans folder or .md file (e.g. plans/scenarios/checkout or plans/scenarios/checkout/login.md)")
444
+ .action(async (opts) => {
445
+ const body = {};
446
+ if (opts.namedTestRunId)
447
+ body.namedTestRunId = String(opts.namedTestRunId).trim();
448
+ if (opts.release)
449
+ body.release = String(opts.release).trim();
450
+ if (opts.plansPath)
451
+ body.plansPath = String(opts.plansPath).trim();
452
+ const merged = mergeBodies(body, opts.jsonInput);
453
+ for (const key of ["namedTestRunId", "release", "plansPath"]) {
454
+ const value = merged[key];
455
+ if (typeof value !== "string") {
456
+ continue;
457
+ }
458
+ const trimmed = value.trim();
459
+ if (!trimmed) {
460
+ delete merged[key];
461
+ }
462
+ else {
463
+ merged[key] = trimmed;
464
+ }
465
+ }
466
+ const out = await runTool("list-test-scenarios-for-scope", merged, { postMcp });
467
+ console.log(out);
468
+ });
437
469
  program
438
470
  .command("get-manual-session-details")
439
471
  .description(TOOL_DEFINITIONS.find((t) => t.kebab === "get-manual-session-details").description)
@@ -281,6 +281,11 @@ export declare const getTestScenariosInput: z.ZodObject<{
281
281
  scenarioOrdinalIds: z.ZodOptional<z.ZodArray<z.ZodCoercedNumber<unknown>>>;
282
282
  externalIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
283
283
  }, z.core.$strip>;
284
+ export declare const listTestScenariosForScopeInput: z.ZodObject<{
285
+ namedTestRunId: z.ZodOptional<z.ZodString>;
286
+ release: z.ZodOptional<z.ZodString>;
287
+ plansPath: z.ZodOptional<z.ZodString>;
288
+ }, z.core.$strip>;
284
289
  export declare const getManualSessionDetailsInput: z.ZodObject<{
285
290
  manualSessionId: z.ZodString;
286
291
  }, z.core.$strip>;
@@ -157,6 +157,13 @@ export const getTestScenariosInput = z
157
157
  })
158
158
  .refine((v) => (v.scenarioOrdinalIds != null && v.scenarioOrdinalIds.length > 0) ||
159
159
  (v.externalIds != null && v.externalIds.length > 0), { message: "Provide scenarioOrdinalIds and/or externalIds (non-empty)" });
160
+ export const listTestScenariosForScopeInput = z
161
+ .object({
162
+ namedTestRunId: z.string().min(1).optional(),
163
+ release: z.string().min(1).optional(),
164
+ plansPath: z.string().min(1).optional(),
165
+ })
166
+ .refine((v) => [v.namedTestRunId, v.release, v.plansPath].filter((x) => x != null && String(x).trim() !== "").length === 1, { message: "Provide exactly one of namedTestRunId, release, or plansPath" });
160
167
  export const getManualSessionDetailsInput = z.object({
161
168
  manualSessionId: z.string().min(1),
162
169
  });
@@ -350,6 +350,28 @@ export const TOOL_DEFINITIONS = [
350
350
  return postMcp("/api/mcp/get_test_scenarios", body);
351
351
  },
352
352
  },
353
+ {
354
+ kebab: "list-test-scenarios-for-scope",
355
+ description: "List in-scope test scenarios (ordinalId + title only) for exactly one locator: " +
356
+ "a named test run, a release label, or a platform plans folder/file path. " +
357
+ "Does not return markdown — use get-test-scenarios for detail by known ordinal. " +
358
+ "Use when executing tests for a plans path, release, or named test run.",
359
+ inputSchema: S.listTestScenariosForScopeInput,
360
+ execute: async (args, { postMcp }) => {
361
+ const a = args;
362
+ const body = {};
363
+ const namedTestRunId = a.namedTestRunId?.trim();
364
+ const release = a.release?.trim();
365
+ const plansPath = a.plansPath?.trim();
366
+ if (namedTestRunId)
367
+ body.namedTestRunId = namedTestRunId;
368
+ if (release)
369
+ body.release = release;
370
+ if (plansPath)
371
+ body.plansPath = plansPath;
372
+ return postMcp("/api/mcp/list_test_scenarios_for_scope", body);
373
+ },
374
+ },
353
375
  {
354
376
  kebab: "get-manual-session-details",
355
377
  description: "Fetch a manual test session by id. Returns project id, title, environment, steps " +
@@ -1045,8 +1067,13 @@ export const TOOL_DEFINITIONS = [
1045
1067
  inputSchema: S.reportAgentActionInput,
1046
1068
  execute: async (args, { postMcp }) => {
1047
1069
  const a = args;
1048
- const actorRaw = (a.actorType ?? "local-agent").toString();
1049
- const actorType = actorRaw.toUpperCase().replace(/-/g, "_") === "CLOUD_AGENT" ? "CLOUD_AGENT" : "LOCAL_AGENT";
1070
+ const sessionId = (process.env.SESSION_ID ||
1071
+ process.env.CHIMPHANDS_SESSION_ID ||
1072
+ "").trim();
1073
+ const actorRaw = (a.actorType ?? (sessionId ? "cloud-agent" : "local-agent")).toString();
1074
+ const actorType = actorRaw.toUpperCase().replace(/-/g, "_") === "CLOUD_AGENT" || sessionId
1075
+ ? "CLOUD_AGENT"
1076
+ : "LOCAL_AGENT";
1050
1077
  const actionNorm = a.actionType.toString().toUpperCase().replace(/-/g, "_");
1051
1078
  let actionType = actionNorm;
1052
1079
  if (actionNorm === "COMPLETED" || actionNorm === "ACTION_COMPLETED") {
@@ -1062,6 +1089,8 @@ export const TOOL_DEFINITIONS = [
1062
1089
  actorType,
1063
1090
  entityType: a.entityType,
1064
1091
  };
1092
+ if (sessionId)
1093
+ body.chimphandsSessionId = sessionId;
1065
1094
  if (a.policyFile)
1066
1095
  body.policyFile = a.policyFile;
1067
1096
  if (a.policyVersion)
@@ -1071,8 +1100,10 @@ export const TOOL_DEFINITIONS = [
1071
1100
  body.gitSha = gitSha;
1072
1101
  if (a.userId)
1073
1102
  body.userId = a.userId;
1074
- else if (process.env.TESTCHIMP_USER_ID)
1103
+ else if (!sessionId && process.env.TESTCHIMP_USER_ID) {
1104
+ // ChimpHands: server resolves responsible user from SESSION_ID; do not stamp service account.
1075
1105
  body.userId = process.env.TESTCHIMP_USER_ID;
1106
+ }
1076
1107
  if (a.branchName)
1077
1108
  body.branchName = a.branchName;
1078
1109
  // Nested traceability wins for agentModel / skillVersion / cliVersion;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testchimp/cli",
3
- "version": "0.1.77",
3
+ "version": "0.1.79",
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",
@@ -32,6 +32,14 @@
32
32
  "@types/ws": "^8.18.1",
33
33
  "typescript": "^6.0.2"
34
34
  },
35
+ "overrides": {
36
+ "fast-uri": "3.1.7",
37
+ "qs": "6.16.0",
38
+ "ip-address": "10.3.1",
39
+ "hono": "4.12.34",
40
+ "@hono/node-server": "1.19.17",
41
+ "body-parser": "2.3.0"
42
+ },
35
43
  "keywords": [
36
44
  "testchimp",
37
45
  "mcp",