@testchimp/cli 0.1.16 → 0.1.18

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.
@@ -316,6 +316,59 @@ export function buildCliProgram() {
316
316
  }, { postMcp });
317
317
  console.log(out);
318
318
  });
319
+ program
320
+ .command("create-issue")
321
+ .description(TOOL_DEFINITIONS.find((t) => t.kebab === "create-issue").description)
322
+ .addOption(jsonInputOption())
323
+ .option("--title <title>", "Issue title (required unless provided via --json-input)")
324
+ .option("--description <text>", "Issue description (markdown supported)")
325
+ .option("--issue-type <type>", "BUG_ISSUE | SUGGESTION_ISSUE | OBSERVATION_ISSUE | TASK_ISSUE")
326
+ .option("--category <category>", "FUNCTIONAL | SECURITY | ACCESSIBILITY | PERFORMANCE | VISUAL | …")
327
+ .option("--severity <severity>", "LOW_SEVERITY | MEDIUM_SEVERITY | HIGH_SEVERITY | CRITICAL_SEVERITY")
328
+ .option("--status <status>", "ACTIVE | IGNORED | FIXED | DUPLICATE | IN_PROGRESS_BUG | ARCHIVED_BUG | BLOCKED")
329
+ .option("--reported-release-id <id>", "Release label/id to attach to the issue")
330
+ .option("--due-date-millis <ms>", "Due date as UTC epoch millis")
331
+ .option("--assignee <userId>", "Assignee user id")
332
+ .option("--labels <csv>", "Comma-separated labels")
333
+ .option("--source <name>", "External ingest source identifier (stored as label source:<name>)")
334
+ .option("--environment <name>", "Environment tag (defaults to QA when omitted)")
335
+ .action(async (opts) => {
336
+ const body = {};
337
+ if (opts.title)
338
+ body.title = String(opts.title).trim();
339
+ if (opts.description)
340
+ body.description = String(opts.description);
341
+ if (opts.issueType)
342
+ body.issueType = String(opts.issueType).trim();
343
+ if (opts.category)
344
+ body.category = String(opts.category).trim();
345
+ if (opts.severity)
346
+ body.severity = String(opts.severity).trim();
347
+ if (opts.status)
348
+ body.status = String(opts.status).trim();
349
+ if (opts.reportedReleaseId)
350
+ body.reportedReleaseId = String(opts.reportedReleaseId).trim();
351
+ if (opts.dueDateMillis != null)
352
+ body.dueDateMillis = Number(opts.dueDateMillis);
353
+ if (opts.assignee)
354
+ body.assignee = String(opts.assignee).trim();
355
+ if (opts.labels) {
356
+ body.labels = String(opts.labels)
357
+ .split(",")
358
+ .map((s) => s.trim())
359
+ .filter(Boolean);
360
+ }
361
+ if (opts.source)
362
+ body.source = String(opts.source).trim();
363
+ if (opts.environment)
364
+ body.environment = String(opts.environment).trim();
365
+ const merged = mergeBodies(body, opts.jsonInput);
366
+ if (!merged.title || String(merged.title).trim() === "") {
367
+ throw new Error("title is required (--title or --json-input {\"title\":\"...\"})");
368
+ }
369
+ const out = await runTool("create-issue", merged, { postMcp });
370
+ console.log(out);
371
+ });
319
372
  program
320
373
  .command("mark-plan-items-implementation-done")
321
374
  .description(TOOL_DEFINITIONS.find((t) => t.kebab === "mark-plan-items-implementation-done").description)
@@ -620,6 +673,22 @@ export function buildCliProgram() {
620
673
  const out = await runTool("get-release", { version: String(merged.version).trim() }, { postMcp });
621
674
  console.log(out);
622
675
  });
676
+ program
677
+ .command("get-release-details")
678
+ .description(TOOL_DEFINITIONS.find((t) => t.kebab === "get-release-details").description)
679
+ .addOption(jsonInputOption())
680
+ .option("--version <version>", "Release version / label (McpGetReleaseDetailsRequest.version)")
681
+ .action(async (opts) => {
682
+ const body = {};
683
+ if (opts.version)
684
+ body.version = String(opts.version);
685
+ const merged = mergeBodies(body, opts.jsonInput);
686
+ if (!merged.version || String(merged.version).trim() === "") {
687
+ throw new Error("version is required (--version or --json-input {\"version\":\"...\"})");
688
+ }
689
+ const out = await runTool("get-release-details", { version: String(merged.version).trim() }, { postMcp });
690
+ console.log(out);
691
+ });
623
692
  program
624
693
  .command("get-security-scan-config")
625
694
  .description(TOOL_DEFINITIONS.find((t) => t.kebab === "get-security-scan-config").description)
@@ -99,6 +99,72 @@ export declare const updateIssueStatusInput: z.ZodObject<{
99
99
  NOT_IMPORTANT: "NOT_IMPORTANT";
100
100
  }>>;
101
101
  }, z.core.$strip>;
102
+ export declare const createIssueInput: z.ZodObject<{
103
+ title: z.ZodString;
104
+ description: z.ZodOptional<z.ZodString>;
105
+ issueType: z.ZodOptional<z.ZodEnum<{
106
+ BUG_ISSUE: "BUG_ISSUE";
107
+ SUGGESTION_ISSUE: "SUGGESTION_ISSUE";
108
+ OBSERVATION_ISSUE: "OBSERVATION_ISSUE";
109
+ TASK_ISSUE: "TASK_ISSUE";
110
+ }>>;
111
+ category: z.ZodOptional<z.ZodEnum<{
112
+ ACCESSIBILITY: "ACCESSIBILITY";
113
+ SECURITY: "SECURITY";
114
+ VISUAL: "VISUAL";
115
+ PERFORMANCE: "PERFORMANCE";
116
+ FUNCTIONAL: "FUNCTIONAL";
117
+ NETWORK: "NETWORK";
118
+ USABILITY: "USABILITY";
119
+ COMPATIBILITY: "COMPATIBILITY";
120
+ DATA_INTEGRITY: "DATA_INTEGRITY";
121
+ INTERACTION: "INTERACTION";
122
+ LOCALIZATION: "LOCALIZATION";
123
+ RESPONSIVENESS: "RESPONSIVENESS";
124
+ LAYOUT: "LAYOUT";
125
+ VISUAL_REGRESSION: "VISUAL_REGRESSION";
126
+ MEMORY: "MEMORY";
127
+ PERFORMANCE_REGRESSION: "PERFORMANCE_REGRESSION";
128
+ MEMORY_REGRESSION: "MEMORY_REGRESSION";
129
+ FORM_VALIDATION_BUG: "FORM_VALIDATION_BUG";
130
+ OTHER: "OTHER";
131
+ }>>;
132
+ severity: z.ZodOptional<z.ZodEnum<{
133
+ LOW_SEVERITY: "LOW_SEVERITY";
134
+ MEDIUM_SEVERITY: "MEDIUM_SEVERITY";
135
+ HIGH_SEVERITY: "HIGH_SEVERITY";
136
+ CRITICAL_SEVERITY: "CRITICAL_SEVERITY";
137
+ }>>;
138
+ status: z.ZodOptional<z.ZodEnum<{
139
+ ACTIVE: "ACTIVE";
140
+ IGNORED: "IGNORED";
141
+ FIXED: "FIXED";
142
+ DUPLICATE: "DUPLICATE";
143
+ IN_PROGRESS_BUG: "IN_PROGRESS_BUG";
144
+ ARCHIVED_BUG: "ARCHIVED_BUG";
145
+ BLOCKED: "BLOCKED";
146
+ }>>;
147
+ reportedReleaseId: z.ZodOptional<z.ZodString>;
148
+ dueDateMillis: z.ZodOptional<z.ZodCoercedNumber<unknown>>;
149
+ assignee: z.ZodOptional<z.ZodString>;
150
+ linkTargets: z.ZodOptional<z.ZodArray<z.ZodObject<{
151
+ toEntityType: z.ZodEnum<{
152
+ STORY: "STORY";
153
+ SCENARIO: "SCENARIO";
154
+ TEST: "TEST";
155
+ ISSUE: "ISSUE";
156
+ EXTERNAL: "EXTERNAL";
157
+ TEST_EXECUTION: "TEST_EXECUTION";
158
+ BATCH_INVOCATION: "BATCH_INVOCATION";
159
+ }>;
160
+ toEntityId: z.ZodString;
161
+ }, z.core.$strip>>>;
162
+ labels: z.ZodOptional<z.ZodArray<z.ZodString>>;
163
+ source: z.ZodOptional<z.ZodString>;
164
+ environment: z.ZodOptional<z.ZodString>;
165
+ attachments: z.ZodOptional<z.ZodArray<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
166
+ artifactReference: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
167
+ }, z.core.$strip>;
102
168
  export declare const emptyInput: z.ZodObject<{}, z.core.$strip>;
103
169
  export declare const getBranchSpecificEndpointConfigInput: z.ZodObject<{
104
170
  branchName: z.ZodOptional<z.ZodString>;
@@ -581,6 +647,9 @@ export declare const listScreenStatesInput: z.ZodObject<{
581
647
  export declare const getReleaseInput: z.ZodObject<{
582
648
  version: z.ZodString;
583
649
  }, z.core.$strip>;
650
+ export declare const getReleaseDetailsInput: z.ZodObject<{
651
+ version: z.ZodString;
652
+ }, z.core.$strip>;
584
653
  export declare const getSecurityScanConfigInput: z.ZodObject<{
585
654
  id: z.ZodString;
586
655
  }, z.core.$strip>;
@@ -99,6 +99,72 @@ export const updateIssueStatusInput = z.object({
99
99
  .enum(["INTENDED_BEHAVIOUR", "INACCURATE_ASSESSMENT", "NOT_IMPORTANT"])
100
100
  .optional(),
101
101
  });
102
+ const linkedEntityTypeSchema = z.enum([
103
+ "STORY",
104
+ "SCENARIO",
105
+ "TEST",
106
+ "ISSUE",
107
+ "EXTERNAL",
108
+ "TEST_EXECUTION",
109
+ "BATCH_INVOCATION",
110
+ ]);
111
+ const createIssueLinkTargetSchema = z.object({
112
+ toEntityType: linkedEntityTypeSchema,
113
+ toEntityId: z.string().min(1),
114
+ });
115
+ export const createIssueInput = z.object({
116
+ title: z.string().min(1),
117
+ description: z.string().optional(),
118
+ issueType: z
119
+ .enum(["BUG_ISSUE", "SUGGESTION_ISSUE", "OBSERVATION_ISSUE", "TASK_ISSUE"])
120
+ .optional(),
121
+ category: z
122
+ .enum([
123
+ "ACCESSIBILITY",
124
+ "SECURITY",
125
+ "VISUAL",
126
+ "PERFORMANCE",
127
+ "FUNCTIONAL",
128
+ "NETWORK",
129
+ "USABILITY",
130
+ "COMPATIBILITY",
131
+ "DATA_INTEGRITY",
132
+ "INTERACTION",
133
+ "LOCALIZATION",
134
+ "RESPONSIVENESS",
135
+ "LAYOUT",
136
+ "VISUAL_REGRESSION",
137
+ "MEMORY",
138
+ "PERFORMANCE_REGRESSION",
139
+ "MEMORY_REGRESSION",
140
+ "FORM_VALIDATION_BUG",
141
+ "OTHER",
142
+ ])
143
+ .optional(),
144
+ severity: z
145
+ .enum(["LOW_SEVERITY", "MEDIUM_SEVERITY", "HIGH_SEVERITY", "CRITICAL_SEVERITY"])
146
+ .optional(),
147
+ status: z
148
+ .enum([
149
+ "ACTIVE",
150
+ "IGNORED",
151
+ "FIXED",
152
+ "DUPLICATE",
153
+ "IN_PROGRESS_BUG",
154
+ "ARCHIVED_BUG",
155
+ "BLOCKED",
156
+ ])
157
+ .optional(),
158
+ reportedReleaseId: z.string().optional(),
159
+ dueDateMillis: z.coerce.number().optional(),
160
+ assignee: z.string().optional(),
161
+ linkTargets: z.array(createIssueLinkTargetSchema).optional(),
162
+ labels: z.array(z.string()).optional(),
163
+ source: z.string().optional(),
164
+ environment: z.string().optional(),
165
+ attachments: z.array(z.record(z.string(), z.unknown())).optional(),
166
+ artifactReference: z.record(z.string(), z.unknown()).optional(),
167
+ });
102
168
  export const emptyInput = z.object({});
103
169
  export const getBranchSpecificEndpointConfigInput = z.object({
104
170
  branchName: z.string().optional(),
@@ -258,6 +324,10 @@ export const getReleaseInput = z.object({
258
324
  /** Release catalog version / label — maps to McpGetReleaseRequest.version */
259
325
  version: z.string().min(1),
260
326
  });
327
+ export const getReleaseDetailsInput = z.object({
328
+ /** Release catalog version / label — maps to McpGetReleaseDetailsRequest.version */
329
+ version: z.string().min(1),
330
+ });
261
331
  export const getSecurityScanConfigInput = z.object({
262
332
  id: z.string().min(1),
263
333
  });
@@ -250,6 +250,48 @@ export const TOOL_DEFINITIONS = [
250
250
  return postMcp("/api/mcp/update_issue_status", body);
251
251
  },
252
252
  },
253
+ {
254
+ kebab: "create-issue",
255
+ description: "Create a TestChimp issue in the current project. title is required. " +
256
+ "Use simple fields for common creates, or pass the full curated contract via --json-input " +
257
+ "(description, issueType, category, severity, status, reportedReleaseId, dueDateMillis, assignee, " +
258
+ "linkTargets, labels, source, environment, attachments, artifactReference). " +
259
+ "Authenticated via project API key; project is resolved from the key.",
260
+ inputSchema: S.createIssueInput,
261
+ execute: async (args, { postMcp }) => {
262
+ const a = args;
263
+ const body = { title: a.title.trim() };
264
+ if (a.description != null)
265
+ body.description = a.description;
266
+ if (a.issueType)
267
+ body.issueType = a.issueType;
268
+ if (a.category)
269
+ body.category = a.category;
270
+ if (a.severity)
271
+ body.severity = a.severity;
272
+ if (a.status)
273
+ body.status = a.status;
274
+ if (a.reportedReleaseId != null)
275
+ body.reportedReleaseId = a.reportedReleaseId;
276
+ if (a.dueDateMillis != null)
277
+ body.dueDateMillis = a.dueDateMillis;
278
+ if (a.assignee != null)
279
+ body.assignee = a.assignee;
280
+ if (a.linkTargets?.length)
281
+ body.linkTargets = a.linkTargets;
282
+ if (a.labels?.length)
283
+ body.labels = a.labels;
284
+ if (a.source != null)
285
+ body.source = a.source;
286
+ if (a.environment != null)
287
+ body.environment = a.environment;
288
+ if (a.attachments?.length)
289
+ body.attachments = a.attachments;
290
+ if (a.artifactReference != null)
291
+ body.artifactReference = a.artifactReference;
292
+ return postMcp("/api/mcp/create_issue", body);
293
+ },
294
+ },
253
295
  {
254
296
  kebab: "mark-plan-items-implementation-done",
255
297
  description: "Mark user stories and/or test scenarios implementation-complete in platform lifecycle (DB only; does not rewrite plan markdown). " +
@@ -510,6 +552,19 @@ export const TOOL_DEFINITIONS = [
510
552
  return postMcp("/api/mcp/get_release", body);
511
553
  },
512
554
  },
555
+ {
556
+ kebab: "get-release-details",
557
+ description: "Fetch gate-oriented release details for a version/label: scope, per-environment " +
558
+ "priority×status test stats, open issue stats, scan summaries, and detailed in-scope " +
559
+ "scenario/issue records (McpGetReleaseDetailsRequest/Response). Pass version (CLI: --version). " +
560
+ "Use for CI/agent release gating. Authenticated via project API key.",
561
+ inputSchema: S.getReleaseDetailsInput,
562
+ execute: async (args, { postMcp }) => {
563
+ const a = args;
564
+ const body = { version: a.version.trim() };
565
+ return postMcp("/api/mcp/get_release_details", body);
566
+ },
567
+ },
513
568
  {
514
569
  kebab: "get-security-scan-config",
515
570
  description: "Fetch security scan config by scan id (detail.dastCheckConfig / detail.sastCheckConfig / " +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@testchimp/cli",
3
- "version": "0.1.16",
3
+ "version": "0.1.18",
4
4
  "description": "TestChimp CLI and MCP server — coverage, plans, EaaS, TrueCoverage (calls /api/mcp/*)",
5
5
  "type": "module",
6
6
  "main": "dist/bin/testchimp.js",