@mycompbox/compbox-mcp 1.9.1 → 1.10.0

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.
Files changed (2) hide show
  1. package/index.js +196 -1
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -103,6 +103,22 @@ var init_mailbox = __esm({
103
103
  }
104
104
  });
105
105
 
106
+ // ../shared/dist/types/interview.js
107
+ function isInterviewStatus(value) {
108
+ return INTERVIEW_STATUSES.includes(value);
109
+ }
110
+ var INTERVIEW_STATUSES;
111
+ var init_interview = __esm({
112
+ "../shared/dist/types/interview.js"() {
113
+ "use strict";
114
+ INTERVIEW_STATUSES = [
115
+ "in_progress",
116
+ "completed",
117
+ "archived"
118
+ ];
119
+ }
120
+ });
121
+
106
122
  // ../shared/dist/types/index.js
107
123
  var init_types = __esm({
108
124
  "../shared/dist/types/index.js"() {
@@ -112,6 +128,7 @@ var init_types = __esm({
112
128
  init_invitation();
113
129
  init_session_events();
114
130
  init_mailbox();
131
+ init_interview();
115
132
  }
116
133
  });
117
134
 
@@ -363,11 +380,184 @@ var init_pxpipe = __esm({
363
380
  }
364
381
  });
365
382
 
383
+ // ../shared/dist/interview-definition.js
384
+ function interviewSectionKeys() {
385
+ return INTERVIEW_DEFINITION.map((s) => s.key);
386
+ }
387
+ function interviewFieldKeys() {
388
+ const seen = /* @__PURE__ */ new Set();
389
+ const out = [];
390
+ for (const section of INTERVIEW_DEFINITION) {
391
+ for (const f of section.fields) {
392
+ if (!seen.has(f)) {
393
+ seen.add(f);
394
+ out.push(f);
395
+ }
396
+ }
397
+ }
398
+ return out;
399
+ }
400
+ function buildInterviewSystemPrompt(definition = INTERVIEW_DEFINITION) {
401
+ const requiredSections = definition.filter((s) => s.required);
402
+ const optionalSections = definition.filter((s) => !s.required);
403
+ const renderSection = (s) => {
404
+ const tag = s.required ? "REQUIRED" : "OPTIONAL \u2014 ask, but the user may decline";
405
+ const followUps = s.followUps.map((q) => ` - ${q}`).join("\n");
406
+ return `- ${s.title} (${tag}) [json keys: ${s.fields.join(", ")}]
407
+ ${s.purpose}
408
+ ${followUps}`;
409
+ };
410
+ const completionKeys = [
411
+ "title",
412
+ ...interviewFieldKeysFor(definition),
413
+ "description"
414
+ ];
415
+ const completionShape = completionKeys.map((k) => `"${k}": "..."`).join(", ");
416
+ return `You are the CompBox request-formulator, interviewing an employee to turn their idea into a well-formed Epic Request. Ask exactly ONE short, focused question at a time \u2014 never multiple questions in one message, never preamble or explanation.
417
+
418
+ Work through these interview sections in order. Cover EVERY required section; for optional sections, ask about them too, but if the employee has nothing to add or declines, move on and leave that field out (never invent or pad it):
419
+
420
+ REQUIRED sections (an Epic Request cannot omit these):
421
+ ${requiredSections.map(renderSection).join("\n")}
422
+
423
+ OPTIONAL-BUT-RECOMMENDED sections (ask about each; omit the field if the employee has nothing):
424
+ ${optionalSections.map(renderSection).join("\n")}
425
+
426
+ The employee's answers may be short or casual \u2014 that's fine, but when you write the final fields below, EXPAND them into complete, well-written prose using everything they told you across the whole conversation, not just a compressed one-liner. Each required field is scored by an automated quality rubric with hard minimums, so undershooting length is a real failure, not just a style nitpick:
427
+ - problemStatement: at least ${String(INTERVIEW_FIELD_MIN_WORDS.problemStatement)} words.
428
+ - proposedSolution: at least ${String(INTERVIEW_FIELD_MIN_WORDS.proposedSolution)} words.
429
+ - impactAssessment: at least ${String(INTERVIEW_FIELD_MIN_WORDS.impactAssessment)} words.
430
+ - description: at least ${String(INTERVIEW_FIELD_MIN_WORDS.description)} words. This is a SEPARATE plain-text field (not shown to the employee) that stands alone as a full narrative summary of the whole request \u2014 restate the problem, the proposed solution, and the expected impact in flowing prose, as if writing the request from scratch for someone who hasn't seen the conversation.
431
+
432
+ Once you have gathered the required sections (and covered the optional ones), respond with ONLY a fenced JSON code block (no other text) in exactly this shape. Include a key for every optional field you gathered; omit any optional field the employee had nothing for:
433
+ \`\`\`json
434
+ {"done": true, ${completionShape}}
435
+ \`\`\`
436
+
437
+ Until then, respond with ONLY your next question as plain text \u2014 no JSON, no labels, no numbering.`;
438
+ }
439
+ function interviewFieldKeysFor(definition) {
440
+ const seen = /* @__PURE__ */ new Set();
441
+ const out = [];
442
+ for (const section of definition) {
443
+ for (const f of section.fields) {
444
+ if (!seen.has(f)) {
445
+ seen.add(f);
446
+ out.push(f);
447
+ }
448
+ }
449
+ }
450
+ return out;
451
+ }
452
+ var INTERVIEW_DEFINITION, INTERVIEW_FIELD_MIN_WORDS;
453
+ var init_interview_definition = __esm({
454
+ "../shared/dist/interview-definition.js"() {
455
+ "use strict";
456
+ INTERVIEW_DEFINITION = [
457
+ {
458
+ key: "problemStatement",
459
+ title: "Problem Statement",
460
+ purpose: "Establish the problem or opportunity being addressed, the gap in the current system, who feels it, and the cost of leaving it unsolved.",
461
+ required: true,
462
+ followUps: [
463
+ "What problem are you trying to solve?",
464
+ "What gap exists in the current system?",
465
+ "Who is experiencing this problem?",
466
+ "What's the impact if we don't address it?"
467
+ ],
468
+ fields: ["problemStatement"]
469
+ },
470
+ {
471
+ key: "proposedSolution",
472
+ title: "Proposed Solution",
473
+ purpose: "Capture what they propose building, how it solves the problem, the high-level approach, and the specific capabilities needed.",
474
+ required: true,
475
+ followUps: [
476
+ "What do you propose building?",
477
+ "How would this solve the problem?",
478
+ "What's the high-level approach?",
479
+ "Are there specific features or capabilities needed?"
480
+ ],
481
+ fields: ["proposedSolution"]
482
+ },
483
+ {
484
+ key: "impactAssessment",
485
+ title: "Impact Assessment",
486
+ purpose: "Capture who benefits, the expected benefits, how it improves the system/product/workflow, and what outcomes would indicate success.",
487
+ required: true,
488
+ followUps: [
489
+ "Who will benefit from this?",
490
+ "What are the expected benefits?",
491
+ "How will this improve the system, product, or workflow?",
492
+ "What outcomes would indicate success?"
493
+ ],
494
+ fields: ["impactAssessment"]
495
+ },
496
+ {
497
+ key: "successMetrics",
498
+ title: "Success Metrics",
499
+ purpose: "Define how success is measured \u2014 specific metrics, signals it is working, and the definition of done for the epic.",
500
+ required: false,
501
+ followUps: [
502
+ "What specific metrics would you track?",
503
+ "How would we know this is working?",
504
+ `What's the definition of "done" for this epic?`
505
+ ],
506
+ fields: ["successMetrics"]
507
+ },
508
+ {
509
+ key: "targetAudience",
510
+ title: "Target Audience",
511
+ purpose: "Identify which users or teams benefit, any specific personas or use cases, and whether they are internal or external.",
512
+ required: false,
513
+ followUps: [
514
+ "Which users or teams will use this?",
515
+ "Are there specific personas or use cases?",
516
+ "Are these internal or external users?"
517
+ ],
518
+ fields: ["targetAudience"]
519
+ },
520
+ {
521
+ key: "technicalContext",
522
+ title: "Technical Context",
523
+ purpose: "Surface dependencies and prerequisites, a rough effort estimate, and any technical constraints or risks.",
524
+ required: false,
525
+ followUps: [
526
+ "Are there dependencies or prerequisites?",
527
+ `What's your rough estimate of effort (e.g., "2-3 weeks", "1 quarter")?`,
528
+ "Are there technical constraints or risks to be aware of?"
529
+ ],
530
+ fields: ["dependencies", "estimatedEffort"]
531
+ },
532
+ {
533
+ key: "alternatives",
534
+ title: "Alternatives Considered",
535
+ purpose: "Capture alternative approaches that were considered and why they were not chosen.",
536
+ required: false,
537
+ followUps: [
538
+ "Are there alternative approaches you considered?",
539
+ "Why were those alternatives not chosen?"
540
+ ],
541
+ fields: ["alternatives"]
542
+ }
543
+ ];
544
+ INTERVIEW_FIELD_MIN_WORDS = {
545
+ problemStatement: 60,
546
+ proposedSolution: 100,
547
+ impactAssessment: 40,
548
+ description: 150
549
+ };
550
+ }
551
+ });
552
+
366
553
  // ../shared/dist/index.js
367
554
  var dist_exports = {};
368
555
  __export(dist_exports, {
369
556
  APPEND_DESCRIPTION_MAX: () => APPEND_DESCRIPTION_MAX,
370
557
  DESCRIPTION_MAX: () => DESCRIPTION_MAX,
558
+ INTERVIEW_DEFINITION: () => INTERVIEW_DEFINITION,
559
+ INTERVIEW_FIELD_MIN_WORDS: () => INTERVIEW_FIELD_MIN_WORDS,
560
+ INTERVIEW_STATUSES: () => INTERVIEW_STATUSES,
371
561
  JOB_STATUSES: () => JOB_STATUSES,
372
562
  JOB_TYPES: () => JOB_TYPES,
373
563
  MACHINE_STATUSES: () => MACHINE_STATUSES,
@@ -377,12 +567,16 @@ __export(dist_exports, {
377
567
  SessionEventType: () => SessionEventType,
378
568
  TURN_ROLES: () => TURN_ROLES,
379
569
  agentSchema: () => agentSchema,
570
+ buildInterviewSystemPrompt: () => buildInterviewSystemPrompt,
380
571
  err: () => err,
381
572
  getAnthropicProxyUrl: () => getAnthropicProxyUrl,
382
573
  getModelById: () => getModelById,
383
574
  getModelDisplayName: () => getModelDisplayName,
384
575
  getOpenAiProxyUrl: () => getOpenAiProxyUrl,
385
576
  instructionSchema: () => instructionSchema,
577
+ interviewFieldKeys: () => interviewFieldKeys,
578
+ interviewSectionKeys: () => interviewSectionKeys,
579
+ isInterviewStatus: () => isInterviewStatus,
386
580
  isJobStatus: () => isJobStatus,
387
581
  isJobType: () => isJobType,
388
582
  isMachineStatus: () => isMachineStatus,
@@ -417,6 +611,7 @@ var init_dist = __esm({
417
611
  init_skill_packs();
418
612
  init_model_catalog();
419
613
  init_pxpipe();
614
+ init_interview_definition();
420
615
  }
421
616
  });
422
617
 
@@ -10532,7 +10727,7 @@ function registerAllTools(server2) {
10532
10727
  var SERVER_NAME = "compbox-mcp";
10533
10728
  function resolveServerVersion() {
10534
10729
  if (true) {
10535
- return "1.9.1";
10730
+ return "1.10.0";
10536
10731
  }
10537
10732
  const require2 = createRequire(import.meta.url);
10538
10733
  for (const candidate of ["../package.json", "./package.json"]) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mycompbox/compbox-mcp",
3
- "version": "1.9.1",
3
+ "version": "1.10.0",
4
4
  "description": "CompBox MCP server - Uses HTTP API client (no direct database access)",
5
5
  "license": "MIT",
6
6
  "type": "module",