@mycompbox/compbox-mcp 1.21.3 → 1.21.5
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/index.js +179 -114
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -130,7 +130,7 @@ var init_mailbox = __esm({
|
|
|
130
130
|
"failed"
|
|
131
131
|
];
|
|
132
132
|
TURN_ROLES = ["agent", "user"];
|
|
133
|
-
START_EXECUTION_KINDS = ["plan", "orchestrate"];
|
|
133
|
+
START_EXECUTION_KINDS = ["plan", "orchestrate", "refine"];
|
|
134
134
|
}
|
|
135
135
|
});
|
|
136
136
|
|
|
@@ -863,6 +863,18 @@ var init_interview_completion = __esm({
|
|
|
863
863
|
});
|
|
864
864
|
|
|
865
865
|
// ../shared/dist/interview-conversation.js
|
|
866
|
+
function requestLockReason(saved) {
|
|
867
|
+
if (!saved)
|
|
868
|
+
return null;
|
|
869
|
+
if (saved.status !== "pending")
|
|
870
|
+
return "status";
|
|
871
|
+
if (!saved.canEdit)
|
|
872
|
+
return "ownership";
|
|
873
|
+
return null;
|
|
874
|
+
}
|
|
875
|
+
function lockedRequestMessage(reason) {
|
|
876
|
+
return reason === "ownership" ? "Only the request's creator can change it; you can still discuss it." : "This request is locked, so it can't be changed any more.";
|
|
877
|
+
}
|
|
866
878
|
function renderSection(s) {
|
|
867
879
|
const tag = s.required ? "needed" : "nice to have";
|
|
868
880
|
return `- ${s.title} (${tag}): ${s.purpose} For example: ${s.followUps.slice(0, 2).join(" ")}`;
|
|
@@ -873,8 +885,10 @@ function renderSaved(saved) {
|
|
|
873
885
|
const issues = saved.compliance && saved.compliance.issues.length > 0 ? `
|
|
874
886
|
What the score says is missing or weak:
|
|
875
887
|
${saved.compliance.issues.slice(0, 8).map((i) => `- ${i.message}`).join("\n")}` : "";
|
|
876
|
-
const
|
|
877
|
-
|
|
888
|
+
const reason = requestLockReason(saved);
|
|
889
|
+
const locked = reason === null ? "It can still be changed." : reason === "status" ? `Its status is "${saved.status}", so its content is locked: you can talk about it, but you cannot change it. Never emit the completion JSON for a locked request.` : "Only the request's creator can change it, and the person you're talking to is not its creator, so its content is locked for them: you can talk about it, but you cannot change it. Never emit the completion JSON for a locked request. If they ask for a change, explain that only the creator can make it.";
|
|
890
|
+
const origin = saved.discussed ? `THE REQUEST ALREADY EXISTS. The person is discussing the existing request "${saved.title}"; this conversation did not create it.` : `THE REQUEST IS ALREADY SAVED. This conversation created the request "${saved.title}".`;
|
|
891
|
+
return `${origin} ${score} ${locked}${issues}
|
|
878
892
|
|
|
879
893
|
Its current content:
|
|
880
894
|
title: ${saved.title}
|
|
@@ -950,7 +964,7 @@ ${followUp}` : text;
|
|
|
950
964
|
async function runConversationStep(input, deps) {
|
|
951
965
|
const system = buildConversationSystemPrompt(input.saved);
|
|
952
966
|
const messages = toConversationMessages(input.turns);
|
|
953
|
-
const
|
|
967
|
+
const lockReason = requestLockReason(input.saved);
|
|
954
968
|
let requestId = input.saved?.id ?? null;
|
|
955
969
|
let savedNow = null;
|
|
956
970
|
let createdHere = false;
|
|
@@ -973,10 +987,11 @@ Send another message (for example "try again") when you're ready and I'll pick u
|
|
|
973
987
|
}
|
|
974
988
|
const draft = extractCompletionJson(reply);
|
|
975
989
|
if (draft) {
|
|
976
|
-
if (
|
|
977
|
-
|
|
990
|
+
if (lockReason) {
|
|
991
|
+
const why = lockReason === "ownership" ? "Only the request's creator can change it, and I'm not its creator." : "That request is locked and can't be changed.";
|
|
992
|
+
messages.push({ role: "assistant", content: reply }, { role: "user", content: `${why} Reply to me in plain text instead.` });
|
|
978
993
|
if (++repairs > JSON_REPAIRS)
|
|
979
|
-
return { kind: "error", text:
|
|
994
|
+
return { kind: "error", text: lockedRequestMessage(lockReason) };
|
|
980
995
|
continue;
|
|
981
996
|
}
|
|
982
997
|
let saved;
|
|
@@ -1019,7 +1034,7 @@ The request IS already saved, and the person will be shown its score. If you ask
|
|
|
1019
1034
|
return { kind: "message", text };
|
|
1020
1035
|
}
|
|
1021
1036
|
}
|
|
1022
|
-
function savedContextFromRecord(record) {
|
|
1037
|
+
function savedContextFromRecord(record, access) {
|
|
1023
1038
|
if (typeof record !== "object" || record === null)
|
|
1024
1039
|
return null;
|
|
1025
1040
|
const r = record;
|
|
@@ -1054,7 +1069,9 @@ function savedContextFromRecord(record) {
|
|
|
1054
1069
|
status: typeof r.status === "string" ? r.status : "pending",
|
|
1055
1070
|
description: typeof r.description === "string" ? r.description : "",
|
|
1056
1071
|
fields,
|
|
1057
|
-
compliance: complianceFromRecord(score)
|
|
1072
|
+
compliance: complianceFromRecord(score),
|
|
1073
|
+
canEdit: access.canEdit,
|
|
1074
|
+
...access.discussed ? { discussed: true } : {}
|
|
1058
1075
|
};
|
|
1059
1076
|
}
|
|
1060
1077
|
function complianceFromRecord(score) {
|
|
@@ -2048,6 +2065,7 @@ __export(dist_exports, {
|
|
|
2048
2065
|
isSubscriptionStatus: () => isSubscriptionStatus,
|
|
2049
2066
|
isTurnRole: () => isTurnRole,
|
|
2050
2067
|
isValidModelId: () => isValidModelId,
|
|
2068
|
+
lockedRequestMessage: () => lockedRequestMessage,
|
|
2051
2069
|
looksLikeCompletionAttempt: () => looksLikeCompletionAttempt,
|
|
2052
2070
|
mcpConfigSchema: () => mcpConfigSchema,
|
|
2053
2071
|
mcpServerConfigSchema: () => mcpServerConfigSchema,
|
|
@@ -2057,6 +2075,7 @@ __export(dist_exports, {
|
|
|
2057
2075
|
ok: () => ok,
|
|
2058
2076
|
probeProxyHealth: () => probeProxyHealth,
|
|
2059
2077
|
renderConversationPrompt: () => renderConversationPrompt,
|
|
2078
|
+
requestLockReason: () => requestLockReason,
|
|
2060
2079
|
resolveRouting: () => resolveRouting,
|
|
2061
2080
|
runConversationStep: () => runConversationStep,
|
|
2062
2081
|
safeReturnTo: () => safeReturnTo,
|
|
@@ -2927,6 +2946,14 @@ var ApiClient = class {
|
|
|
2927
2946
|
throw error;
|
|
2928
2947
|
}
|
|
2929
2948
|
}
|
|
2949
|
+
/**
|
|
2950
|
+
* The cloud a project deploys to: its own choice, or the organization's
|
|
2951
|
+
* default (veena-gcp style). `cloudConnectionId: null` on a team does NOT mean
|
|
2952
|
+
* "no cloud" — it means "follows the org default"; this resolves it.
|
|
2953
|
+
*/
|
|
2954
|
+
async getProjectCloud(teamId) {
|
|
2955
|
+
return this.request("GET", `/api/v1/teams/${encodeURIComponent(teamId)}/cloud`);
|
|
2956
|
+
}
|
|
2930
2957
|
// ---------------------------------------------------------------------------
|
|
2931
2958
|
// Personal Scope Methods
|
|
2932
2959
|
// ---------------------------------------------------------------------------
|
|
@@ -10487,6 +10514,7 @@ function isUuid(value) {
|
|
|
10487
10514
|
}
|
|
10488
10515
|
|
|
10489
10516
|
// src/tools/teams.ts
|
|
10517
|
+
import { z as z20 } from "zod";
|
|
10490
10518
|
function registerTeamTools(server2) {
|
|
10491
10519
|
server2.registerTool(
|
|
10492
10520
|
"compbox__list_teams",
|
|
@@ -10516,22 +10544,59 @@ function registerTeamTools(server2) {
|
|
|
10516
10544
|
}
|
|
10517
10545
|
}
|
|
10518
10546
|
);
|
|
10547
|
+
server2.registerTool(
|
|
10548
|
+
"compbox__get_project_cloud",
|
|
10549
|
+
{
|
|
10550
|
+
description: "Get the cloud a project (team) deploys to: provider (gcp/aws/azure), cloud project or account ID, region and deploy identity, and whether it is the project's own choice or the organization's default. A team's cloudConnectionId of null means it FOLLOWS THE ORG DEFAULT, not that it has no cloud; always call this before planning hosting, databases or deployment. Returns cloud: null only when the organization has no cloud connected.",
|
|
10551
|
+
inputSchema: {
|
|
10552
|
+
team: z20.string().min(1).describe("The project/team: UUID, name or key (e.g. 'SAISUD').")
|
|
10553
|
+
}
|
|
10554
|
+
},
|
|
10555
|
+
async (input) => {
|
|
10556
|
+
try {
|
|
10557
|
+
const apiClient = getApiClient();
|
|
10558
|
+
const found = await apiClient.getTeam(input.team);
|
|
10559
|
+
if (!found) {
|
|
10560
|
+
return createErrorResponse(new Error(`Team '${input.team}' not found`));
|
|
10561
|
+
}
|
|
10562
|
+
const { data } = await apiClient.getProjectCloud(found.data.id);
|
|
10563
|
+
const cloud = data.cloud;
|
|
10564
|
+
return createResponse({
|
|
10565
|
+
team: { id: found.data.id, name: found.data.name, key: found.data.key },
|
|
10566
|
+
hasCloud: cloud !== null,
|
|
10567
|
+
source: cloud === null ? "none" : data.isInherited ? "organization-default" : "project-choice",
|
|
10568
|
+
cloud: cloud && {
|
|
10569
|
+
name: cloud.name,
|
|
10570
|
+
provider: cloud.provider,
|
|
10571
|
+
projectId: cloud.projectId,
|
|
10572
|
+
region: cloud.region,
|
|
10573
|
+
serviceAccountEmail: cloud.serviceAccountEmail,
|
|
10574
|
+
stateStore: cloud.stateStore,
|
|
10575
|
+
consoleUrl: cloud.consoleUrl
|
|
10576
|
+
},
|
|
10577
|
+
guidance: cloud === null ? "No cloud is connected. An organization admin can connect one in Settings -> Cloud; until then don't assume a hosting provider." : `Plan hosting, databases and storage on ${cloud.provider.toUpperCase()} (${cloud.projectId}, ${cloud.region}). CompBox stacks deploy through GitHub Actions with keyless sign-in, so never plan stored cloud keys.`
|
|
10578
|
+
});
|
|
10579
|
+
} catch (error) {
|
|
10580
|
+
return createErrorResponse(error);
|
|
10581
|
+
}
|
|
10582
|
+
}
|
|
10583
|
+
);
|
|
10519
10584
|
}
|
|
10520
10585
|
|
|
10521
10586
|
// src/tools/team-hierarchy.ts
|
|
10522
|
-
import { z as
|
|
10587
|
+
import { z as z21 } from "zod";
|
|
10523
10588
|
var createTeamChildSchema = {
|
|
10524
|
-
parentId:
|
|
10525
|
-
name:
|
|
10526
|
-
key:
|
|
10527
|
-
level:
|
|
10589
|
+
parentId: z21.string().uuid().describe("The UUID of the parent team that will own the new child team."),
|
|
10590
|
+
name: z21.string().min(1).max(255).describe("Display name for the child team."),
|
|
10591
|
+
key: z21.string().min(1).max(10).regex(/^[A-Z][A-Z0-9-]*$/).describe("Unique team key for the child team. Must start with an uppercase letter and contain only uppercase letters, digits, or hyphens."),
|
|
10592
|
+
level: z21.enum(["group", "product-line", "product", "discipline"]).describe("Hierarchy level for the child team (required).")
|
|
10528
10593
|
};
|
|
10529
10594
|
var getTeamPathSchema = {
|
|
10530
|
-
teamId:
|
|
10595
|
+
teamId: z21.string().uuid().describe("The UUID of the team whose ordered ancestor path should be returned.")
|
|
10531
10596
|
};
|
|
10532
10597
|
var moveTeamSchema = {
|
|
10533
|
-
teamId:
|
|
10534
|
-
newParentId:
|
|
10598
|
+
teamId: z21.string().uuid().describe("The UUID of the team to move within the hierarchy."),
|
|
10599
|
+
newParentId: z21.string().uuid().nullable().describe("The UUID of the new parent team. Pass null to move the team to the root level.")
|
|
10535
10600
|
};
|
|
10536
10601
|
function registerTeamHierarchyTools(server2) {
|
|
10537
10602
|
server2.registerTool(
|
|
@@ -10631,7 +10696,7 @@ function registerTeamHierarchyTools(server2) {
|
|
|
10631
10696
|
|
|
10632
10697
|
// src/tools/composite.ts
|
|
10633
10698
|
init_dist();
|
|
10634
|
-
import { z as
|
|
10699
|
+
import { z as z22 } from "zod";
|
|
10635
10700
|
var COMPOSITE_TIMEOUT_MS = 12e4;
|
|
10636
10701
|
function withTimeout(promise, ms, operationName) {
|
|
10637
10702
|
return new Promise((resolve, reject) => {
|
|
@@ -10657,41 +10722,41 @@ function withTimeout(promise, ms, operationName) {
|
|
|
10657
10722
|
var estimatedComplexityValues = ["trivial", "simple", "moderate", "complex"];
|
|
10658
10723
|
var estimatedEffortValues = ["trivial", "small", "medium", "large", "xl"];
|
|
10659
10724
|
var riskLevelValues = ["low", "medium", "high"];
|
|
10660
|
-
var externalLinkSchema =
|
|
10661
|
-
url:
|
|
10662
|
-
title:
|
|
10725
|
+
var externalLinkSchema = z22.object({
|
|
10726
|
+
url: z22.string().describe("URL of the external resource"),
|
|
10727
|
+
title: z22.string().describe("Display title for the link")
|
|
10663
10728
|
});
|
|
10664
|
-
var structuredDescSchema =
|
|
10665
|
-
summary:
|
|
10666
|
-
aiInstructions:
|
|
10667
|
-
acceptanceCriteria:
|
|
10668
|
-
filesInvolved:
|
|
10669
|
-
functionsToModify:
|
|
10670
|
-
testingStrategy:
|
|
10671
|
-
testFiles:
|
|
10672
|
-
relatedItemIds:
|
|
10673
|
-
externalLinks:
|
|
10674
|
-
technicalNotes:
|
|
10675
|
-
riskLevel:
|
|
10676
|
-
estimatedEffort:
|
|
10729
|
+
var structuredDescSchema = z22.object({
|
|
10730
|
+
summary: z22.string().describe("Brief human-readable summary (required)"),
|
|
10731
|
+
aiInstructions: z22.string().optional().describe("Specific instructions for AI agents implementing this item"),
|
|
10732
|
+
acceptanceCriteria: z22.array(z22.string()).optional().describe("List of acceptance criteria that must be met"),
|
|
10733
|
+
filesInvolved: z22.array(z22.string()).optional().describe("File paths that will be involved in this work"),
|
|
10734
|
+
functionsToModify: z22.array(z22.string()).optional().describe("Functions to modify in format 'filePath:functionName'"),
|
|
10735
|
+
testingStrategy: z22.string().optional().describe("Description of how this work should be tested"),
|
|
10736
|
+
testFiles: z22.array(z22.string()).optional().describe("Test file paths"),
|
|
10737
|
+
relatedItemIds: z22.array(z22.string()).optional().describe("Related feature or task identifiers"),
|
|
10738
|
+
externalLinks: z22.array(externalLinkSchema).optional().describe("External documentation or reference links"),
|
|
10739
|
+
technicalNotes: z22.string().optional().describe("Technical implementation notes or constraints"),
|
|
10740
|
+
riskLevel: z22.enum(riskLevelValues).optional().describe("Risk level assessment: low, medium, or high"),
|
|
10741
|
+
estimatedEffort: z22.enum(estimatedEffortValues).optional().describe("Effort estimate: trivial, small, medium, large, or xl")
|
|
10677
10742
|
});
|
|
10678
|
-
var compositeTaskSchema =
|
|
10679
|
-
title:
|
|
10680
|
-
executionOrder:
|
|
10681
|
-
estimatedComplexity:
|
|
10743
|
+
var compositeTaskSchema = z22.object({
|
|
10744
|
+
title: z22.string().min(1).max(500).describe("Task title (required)"),
|
|
10745
|
+
executionOrder: z22.number().int().positive().optional().describe("Execution order within the feature (1, 2, 3...). Lower numbers first."),
|
|
10746
|
+
estimatedComplexity: z22.enum(estimatedComplexityValues).optional().describe("Complexity: trivial (<1hr), simple (1-4hr), moderate (1-3d), complex (>3d)"),
|
|
10682
10747
|
structuredDesc: structuredDescSchema.optional().describe("Structured description with summary, aiInstructions, acceptanceCriteria, etc.")
|
|
10683
10748
|
});
|
|
10684
|
-
var compositeFeatureSchema =
|
|
10685
|
-
title:
|
|
10686
|
-
executionOrder:
|
|
10687
|
-
estimatedComplexity:
|
|
10688
|
-
canParallelize:
|
|
10689
|
-
parallelGroup:
|
|
10690
|
-
dependencies:
|
|
10749
|
+
var compositeFeatureSchema = z22.object({
|
|
10750
|
+
title: z22.string().min(1).max(500).describe("Feature title (required)"),
|
|
10751
|
+
executionOrder: z22.number().int().positive().describe("Execution order within the epic (required). Lower numbers first."),
|
|
10752
|
+
estimatedComplexity: z22.enum(estimatedComplexityValues).describe("Complexity (required): trivial, simple, moderate, or complex"),
|
|
10753
|
+
canParallelize: z22.boolean().optional().describe("Whether this feature can run alongside other features in parallel"),
|
|
10754
|
+
parallelGroup: z22.string().max(100).optional().describe("Group identifier for features that can run together"),
|
|
10755
|
+
dependencies: z22.array(z22.number().int().min(0)).optional().describe(
|
|
10691
10756
|
"Array of 0-based indices referencing earlier features in this array that must complete first"
|
|
10692
10757
|
),
|
|
10693
10758
|
structuredDesc: structuredDescSchema.optional().describe("Structured description with summary, aiInstructions, acceptanceCriteria, etc."),
|
|
10694
|
-
tasks:
|
|
10759
|
+
tasks: z22.array(compositeTaskSchema).min(1).describe("Array of tasks for this feature (at least 1 required)")
|
|
10695
10760
|
});
|
|
10696
10761
|
function registerCompositeTools(server2) {
|
|
10697
10762
|
server2.registerTool(
|
|
@@ -10721,19 +10786,19 @@ Use this instead of individual create calls when building a complete implementat
|
|
|
10721
10786
|
|
|
10722
10787
|
Optionally pass epicRequestId to link this epic to an approved Epic Request.`,
|
|
10723
10788
|
inputSchema: {
|
|
10724
|
-
name:
|
|
10725
|
-
team:
|
|
10726
|
-
description:
|
|
10727
|
-
icon:
|
|
10728
|
-
color:
|
|
10729
|
-
epicRequestId:
|
|
10789
|
+
name: z22.string().min(1).max(255).describe("Epic name (required)"),
|
|
10790
|
+
team: z22.string().min(1).describe("Team ID, name, or key (required). Use compbox__list_teams to find available teams."),
|
|
10791
|
+
description: z22.string().max(DESCRIPTION_MAX).optional().describe("Epic description"),
|
|
10792
|
+
icon: z22.string().max(50).optional().describe("Icon identifier (e.g., 'rocket', 'star')"),
|
|
10793
|
+
color: z22.string().max(20).optional().describe("Hex color code (e.g., '#FF5733')"),
|
|
10794
|
+
epicRequestId: z22.string().uuid().optional().describe(
|
|
10730
10795
|
"UUID of an Epic Request to link to this epic. When provided without deferConversion, the Epic Request will be marked as converted. With deferConversion: true, conversion is skipped (ER must be in 'planning' status)."
|
|
10731
10796
|
),
|
|
10732
|
-
bypassGovernance:
|
|
10733
|
-
deferConversion:
|
|
10797
|
+
bypassGovernance: z22.boolean().optional(),
|
|
10798
|
+
deferConversion: z22.boolean().optional().describe(
|
|
10734
10799
|
"When true, governance accepts 'planning' status and skips auto-conversion of the Epic Request. Used by the planner pipeline which handles conversion in its final VERIFY stage."
|
|
10735
10800
|
),
|
|
10736
|
-
features:
|
|
10801
|
+
features: z22.array(compositeFeatureSchema).min(1).describe(
|
|
10737
10802
|
"Array of features to create. Each feature must have at least 1 task. Features are created in order, so dependencies must reference earlier indices (0-based)."
|
|
10738
10803
|
)
|
|
10739
10804
|
}
|
|
@@ -10829,19 +10894,19 @@ Optionally pass epicRequestId to link this epic to an approved Epic Request.`,
|
|
|
10829
10894
|
{
|
|
10830
10895
|
description: "Run all validations for a task and mark it complete if all pass.\n\nThis composite tool combines:\n- compbox__run_all_validations\n- compbox__complete_work (if validations pass)\n\nBehavior:\n- Runs all validation checks defined on the task\n- If ALL validations pass, marks the task as complete with the provided summary\n- If ANY validation fails, returns the failure details WITHOUT completing the task\n- If no validations are defined, completes the task immediately\n\nUse this at the end of implementing a task to ensure all acceptance criteria are met before marking it done.",
|
|
10831
10896
|
inputSchema: {
|
|
10832
|
-
taskId:
|
|
10897
|
+
taskId: z22.string().describe(
|
|
10833
10898
|
"The task identifier. Accepts UUID or human-readable identifier (e.g., 'COM-123-1')."
|
|
10834
10899
|
),
|
|
10835
|
-
summary:
|
|
10900
|
+
summary: z22.string().max(5e3).optional().describe(
|
|
10836
10901
|
"Summary of work completed. Will be logged as an AI note when the task is marked complete."
|
|
10837
10902
|
),
|
|
10838
|
-
workingDirectory:
|
|
10903
|
+
workingDirectory: z22.string().max(1e3).optional().describe(
|
|
10839
10904
|
"Working directory for running validation commands. Defaults to current working directory."
|
|
10840
10905
|
),
|
|
10841
|
-
stopOnFirstFailure:
|
|
10906
|
+
stopOnFirstFailure: z22.boolean().optional().describe(
|
|
10842
10907
|
"If true, stops running validations after the first failure. Default is false (run all)."
|
|
10843
10908
|
),
|
|
10844
|
-
skipValidations:
|
|
10909
|
+
skipValidations: z22.boolean().optional().describe(
|
|
10845
10910
|
"If true, skips running validations and completes the task immediately. Use with caution - only for tasks where validations are not applicable."
|
|
10846
10911
|
)
|
|
10847
10912
|
}
|
|
@@ -10954,17 +11019,17 @@ Optionally pass epicRequestId to link this epic to an approved Epic Request.`,
|
|
|
10954
11019
|
}
|
|
10955
11020
|
|
|
10956
11021
|
// src/tools/workflow.ts
|
|
10957
|
-
import { z as
|
|
11022
|
+
import { z as z23 } from "zod";
|
|
10958
11023
|
function registerWorkflowTools(server2) {
|
|
10959
11024
|
server2.registerTool(
|
|
10960
11025
|
"compbox__get_next_required_action",
|
|
10961
11026
|
{
|
|
10962
11027
|
description: "Analyze current work item state and suggest the next required action to maintain compliance with CompBox best practices. Returns prioritized list of suggestions with tool names and example parameters.\n\nUse this when you're unsure what to do next with a feature, task, or epic to ensure proper workflow compliance and tracking.",
|
|
10963
11028
|
inputSchema: {
|
|
10964
|
-
itemId:
|
|
11029
|
+
itemId: z23.string().describe(
|
|
10965
11030
|
"The feature, task, or epic identifier. Accepts UUID or human-readable identifier (e.g., 'COM-123' for features, 'COM-123-1' for tasks). Epics use UUID, identifier (e.g., 'ENG-E1'), or exact name."
|
|
10966
11031
|
),
|
|
10967
|
-
itemType:
|
|
11032
|
+
itemType: z23.enum(["feature", "task", "epic"]).describe(
|
|
10968
11033
|
"Whether this is a 'feature', 'task', or 'epic'."
|
|
10969
11034
|
)
|
|
10970
11035
|
}
|
|
@@ -11165,7 +11230,7 @@ function registerWorkflowTools(server2) {
|
|
|
11165
11230
|
{
|
|
11166
11231
|
description: "Get the current state of an AI session and allowed state transitions. The session state machine tracks workflow progress through states: STARTED \u2192 PLANNING \u2192 IMPLEMENTING \u2192 VALIDATING \u2192 COMPLETING.\n\nUse this to understand where you are in the workflow and what transitions are allowed.",
|
|
11167
11232
|
inputSchema: {
|
|
11168
|
-
sessionId:
|
|
11233
|
+
sessionId: z23.string().describe(
|
|
11169
11234
|
"The session ID to query. Get this from compbox__start_session or compbox__get_active_session."
|
|
11170
11235
|
)
|
|
11171
11236
|
}
|
|
@@ -11195,17 +11260,17 @@ function registerWorkflowTools(server2) {
|
|
|
11195
11260
|
// src/tools/project-flags.ts
|
|
11196
11261
|
import * as fs from "fs/promises";
|
|
11197
11262
|
import * as path from "path";
|
|
11198
|
-
import { z as
|
|
11263
|
+
import { z as z24 } from "zod";
|
|
11199
11264
|
function registerProjectFlagTools(server2) {
|
|
11200
11265
|
server2.registerTool(
|
|
11201
11266
|
"compbox__mark_docs_audit_complete",
|
|
11202
11267
|
{
|
|
11203
11268
|
description: "Mark a project's documentation audit as complete by writing the .compbox/docs-audit.json sentinel file. This creates the .compbox/ directory if needed and writes a JSON file that prevents the Request Formulator from prompting about documentation audits on future invocations. Use this when a user confirms their project is already documented.",
|
|
11204
|
-
inputSchema:
|
|
11205
|
-
projectRoot:
|
|
11269
|
+
inputSchema: z24.object({
|
|
11270
|
+
projectRoot: z24.string().optional().describe(
|
|
11206
11271
|
"Project root directory (default: current working directory)"
|
|
11207
11272
|
),
|
|
11208
|
-
epicRequestId:
|
|
11273
|
+
epicRequestId: z24.string().optional().describe(
|
|
11209
11274
|
"Optional Epic Request ID if the audit was completed via a CompBox epic request"
|
|
11210
11275
|
)
|
|
11211
11276
|
})
|
|
@@ -11257,7 +11322,7 @@ function registerProjectFlagTools(server2) {
|
|
|
11257
11322
|
}
|
|
11258
11323
|
|
|
11259
11324
|
// src/tools/changelog.ts
|
|
11260
|
-
import { z as
|
|
11325
|
+
import { z as z25 } from "zod";
|
|
11261
11326
|
var entityTypes = ["epic", "feature", "task"];
|
|
11262
11327
|
function registerChangelogTools(server2) {
|
|
11263
11328
|
server2.registerTool(
|
|
@@ -11265,31 +11330,31 @@ function registerChangelogTools(server2) {
|
|
|
11265
11330
|
{
|
|
11266
11331
|
description: "Query entity change history with formatted output. Returns field-level changes showing what was modified, when, and by whom. Each entry shows 'field: oldValue \u2192 newValue'. Useful for understanding how an entity evolved over time or tracking specific field changes.\n\nUse cases:\n- See all changes to a feature or task\n- Track status changes over time\n- Find who changed a specific field\n- Audit changes within a date range\n- Review epic-wide changes across all features/tasks",
|
|
11267
11332
|
inputSchema: {
|
|
11268
|
-
entityType:
|
|
11333
|
+
entityType: z25.enum(entityTypes).describe(
|
|
11269
11334
|
"Type of entity to query (required). 'epic' for epic changes, 'feature' for feature changes, 'task' for task changes."
|
|
11270
11335
|
),
|
|
11271
|
-
entityId:
|
|
11336
|
+
entityId: z25.string().describe(
|
|
11272
11337
|
"UUID of the entity to query (required). The specific epic, feature, or task ID."
|
|
11273
11338
|
),
|
|
11274
|
-
epicId:
|
|
11339
|
+
epicId: z25.string().uuid().optional().describe(
|
|
11275
11340
|
"Filter by epic ID (optional). Accepts UUID or identifier (e.g., 'ENG-E1'). When provided, only returns changes for entities within this epic. Useful for narrowing down results in a multi-epic query."
|
|
11276
11341
|
),
|
|
11277
|
-
field:
|
|
11342
|
+
field: z25.string().max(255).optional().describe(
|
|
11278
11343
|
"Filter by specific field name (optional). Examples: 'statusId', 'title', 'assigneeId', 'description'. Only changes to this field will be returned."
|
|
11279
11344
|
),
|
|
11280
|
-
changedBy:
|
|
11345
|
+
changedBy: z25.string().uuid().optional().describe(
|
|
11281
11346
|
"Filter by user ID who made the change (optional). Only returns changes made by this user."
|
|
11282
11347
|
),
|
|
11283
|
-
since:
|
|
11348
|
+
since: z25.string().optional().describe(
|
|
11284
11349
|
"Filter changes on or after this date (optional). Accepts ISO-8601 date (e.g., '2024-01-15') or duration (e.g., '-P7D' for last 7 days, '-P1M' for last month)."
|
|
11285
11350
|
),
|
|
11286
|
-
until:
|
|
11351
|
+
until: z25.string().optional().describe(
|
|
11287
11352
|
"Filter changes before this date (optional). Accepts ISO-8601 date format."
|
|
11288
11353
|
),
|
|
11289
|
-
limit:
|
|
11354
|
+
limit: z25.number().int().min(1).max(100).optional().describe(
|
|
11290
11355
|
"Maximum number of entries to return (default: 20, max: 100)."
|
|
11291
11356
|
),
|
|
11292
|
-
cursor:
|
|
11357
|
+
cursor: z25.string().optional().describe(
|
|
11293
11358
|
"Pagination cursor from a previous response. Pass this to fetch the next page of results."
|
|
11294
11359
|
)
|
|
11295
11360
|
}
|
|
@@ -11342,7 +11407,7 @@ function registerChangelogTools(server2) {
|
|
|
11342
11407
|
}
|
|
11343
11408
|
|
|
11344
11409
|
// src/tools/sessions.ts
|
|
11345
|
-
import { z as
|
|
11410
|
+
import { z as z26 } from "zod";
|
|
11346
11411
|
import * as fs2 from "fs";
|
|
11347
11412
|
import * as path2 from "path";
|
|
11348
11413
|
function readLocalManifest() {
|
|
@@ -11403,13 +11468,13 @@ function registerSessionTools(server2) {
|
|
|
11403
11468
|
{
|
|
11404
11469
|
description: "Start a new AI session for an epic. Creates a session record, abandons any existing active session, and returns the previous session's handoff data plus epic progress. Call this at the START of any work session to properly track AI activity. Optionally scope the session to a specific feature within the epic by providing featureId.",
|
|
11405
11470
|
inputSchema: {
|
|
11406
|
-
epicId:
|
|
11471
|
+
epicId: z26.string().describe(
|
|
11407
11472
|
"The epic to start a session for. Accepts epic ID (UUID), identifier (e.g., 'ENG-E1'), or exact epic name."
|
|
11408
11473
|
),
|
|
11409
|
-
externalId:
|
|
11474
|
+
externalId: z26.string().optional().describe(
|
|
11410
11475
|
"Optional external session identifier (e.g., from Copilot or another AI tool)."
|
|
11411
11476
|
),
|
|
11412
|
-
featureId:
|
|
11477
|
+
featureId: z26.string().uuid().optional().describe(
|
|
11413
11478
|
"Optional feature ID (UUID) to scope this session to a specific feature within the epic. When provided, the session tracks work on a single feature. Omit for epic-wide sessions (default behavior)."
|
|
11414
11479
|
)
|
|
11415
11480
|
}
|
|
@@ -11437,19 +11502,19 @@ function registerSessionTools(server2) {
|
|
|
11437
11502
|
{
|
|
11438
11503
|
description: "End the active AI session for an epic with handoff data. Records summary, next steps, blockers, and decisions for the next session. Call this at the END of a work session. If the session was feature-scoped, the response includes featureId indicating which feature was targeted.",
|
|
11439
11504
|
inputSchema: {
|
|
11440
|
-
epicId:
|
|
11505
|
+
epicId: z26.string().describe(
|
|
11441
11506
|
"The epic whose active session to end. Accepts epic ID (UUID), identifier (e.g., 'ENG-E1'), or exact epic name."
|
|
11442
11507
|
),
|
|
11443
|
-
summary:
|
|
11444
|
-
nextSteps:
|
|
11445
|
-
blockers:
|
|
11446
|
-
decisions:
|
|
11447
|
-
|
|
11448
|
-
decision:
|
|
11449
|
-
rationale:
|
|
11508
|
+
summary: z26.string().describe("Summary of work completed during this session."),
|
|
11509
|
+
nextSteps: z26.array(z26.string()).optional().describe("Recommended next actions for the successor session."),
|
|
11510
|
+
blockers: z26.array(z26.string()).optional().describe("Blockers encountered during this session."),
|
|
11511
|
+
decisions: z26.array(
|
|
11512
|
+
z26.object({
|
|
11513
|
+
decision: z26.string(),
|
|
11514
|
+
rationale: z26.string().optional()
|
|
11450
11515
|
})
|
|
11451
11516
|
).optional().describe("Key decisions made during this session with rationale."),
|
|
11452
|
-
contextBlob:
|
|
11517
|
+
contextBlob: z26.string().optional().describe("Optional free-form context blob for the next session.")
|
|
11453
11518
|
}
|
|
11454
11519
|
},
|
|
11455
11520
|
async (input) => {
|
|
@@ -11473,7 +11538,7 @@ function registerSessionTools(server2) {
|
|
|
11473
11538
|
{
|
|
11474
11539
|
description: "Check if there is an active AI session for an epic. Returns the session if active, or null.",
|
|
11475
11540
|
inputSchema: {
|
|
11476
|
-
epicId:
|
|
11541
|
+
epicId: z26.string().describe(
|
|
11477
11542
|
"The epic to check. Accepts epic ID (UUID), identifier (e.g., 'ENG-E1'), or exact epic name."
|
|
11478
11543
|
)
|
|
11479
11544
|
}
|
|
@@ -11493,7 +11558,7 @@ function registerSessionTools(server2) {
|
|
|
11493
11558
|
{
|
|
11494
11559
|
description: "Get the last completed session for an epic. Returns previous session handoff data without starting a new session. Use this to review what happened in the previous session.",
|
|
11495
11560
|
inputSchema: {
|
|
11496
|
-
epicId:
|
|
11561
|
+
epicId: z26.string().describe(
|
|
11497
11562
|
"The epic to query. Accepts epic ID (UUID), identifier (e.g., 'ENG-E1'), or exact epic name."
|
|
11498
11563
|
)
|
|
11499
11564
|
}
|
|
@@ -11513,10 +11578,10 @@ function registerSessionTools(server2) {
|
|
|
11513
11578
|
{
|
|
11514
11579
|
description: "Get the history of AI sessions for an epic. Returns past sessions ordered by most recent first.",
|
|
11515
11580
|
inputSchema: {
|
|
11516
|
-
epicId:
|
|
11581
|
+
epicId: z26.string().describe(
|
|
11517
11582
|
"The epic to query. Accepts epic ID (UUID), identifier (e.g., 'ENG-E1'), or exact epic name."
|
|
11518
11583
|
),
|
|
11519
|
-
limit:
|
|
11584
|
+
limit: z26.number().int().min(1).max(100).optional().describe("Maximum number of sessions to return (default: 10, max: 100).")
|
|
11520
11585
|
}
|
|
11521
11586
|
},
|
|
11522
11587
|
async (input) => {
|
|
@@ -11535,7 +11600,7 @@ function registerSessionTools(server2) {
|
|
|
11535
11600
|
}
|
|
11536
11601
|
|
|
11537
11602
|
// src/tools/compliance.ts
|
|
11538
|
-
import { z as
|
|
11603
|
+
import { z as z27 } from "zod";
|
|
11539
11604
|
var TIER_EMOJI = {
|
|
11540
11605
|
pass: "\u2705",
|
|
11541
11606
|
advisory: "\u26A0\uFE0F",
|
|
@@ -11606,7 +11671,7 @@ function registerComplianceTools(server2) {
|
|
|
11606
11671
|
{
|
|
11607
11672
|
description: "Trigger a compliance audit for an Epic Request. Evaluates the epic request against compliance rules and returns a detailed score with dimension breakdown and issues. The audit result is persisted on the epic request for future reference.",
|
|
11608
11673
|
inputSchema: {
|
|
11609
|
-
id:
|
|
11674
|
+
id: z27.string().min(1).describe(
|
|
11610
11675
|
"The epic request to audit. Accepts UUID or identifier (e.g., 'ER-1')."
|
|
11611
11676
|
)
|
|
11612
11677
|
}
|
|
@@ -11628,7 +11693,7 @@ function registerComplianceTools(server2) {
|
|
|
11628
11693
|
{
|
|
11629
11694
|
description: "Trigger a full compliance audit for an Epic. Evaluates the epic and all its features and tasks against compliance rules. Returns a detailed score with dimension breakdown and issues. The audit result is persisted on the epic for future reference.",
|
|
11630
11695
|
inputSchema: {
|
|
11631
|
-
id:
|
|
11696
|
+
id: z27.string().min(1).describe(
|
|
11632
11697
|
"The epic to audit. Accepts UUID, identifier (e.g., 'ENG-E1'), or exact name."
|
|
11633
11698
|
)
|
|
11634
11699
|
}
|
|
@@ -11665,20 +11730,20 @@ function registerComplianceTools(server2) {
|
|
|
11665
11730
|
}
|
|
11666
11731
|
|
|
11667
11732
|
// src/tools/skill-packs/manage.ts
|
|
11668
|
-
import { z as
|
|
11733
|
+
import { z as z30 } from "zod";
|
|
11669
11734
|
|
|
11670
11735
|
// src/tools/skill-packs/get-manifest.ts
|
|
11671
|
-
import { z as
|
|
11736
|
+
import { z as z28 } from "zod";
|
|
11672
11737
|
function registerGetPackManifestTool(server2) {
|
|
11673
11738
|
server2.registerTool(
|
|
11674
11739
|
"compbox__get_pack_manifest",
|
|
11675
11740
|
{
|
|
11676
11741
|
description: "Get the detailed manifest for a specific version of a skill pack.\n\nThe manifest describes the pack's contents including:\n- Agents: AI agents included in the pack\n- Skills: Individual skills/capabilities\n- Instructions: Documentation and usage guides\n- Dependencies: Other packs this pack depends on\n\nUse this to understand what a skill pack contains before installing it, or to see the details of an installed pack's current version.",
|
|
11677
11742
|
inputSchema: {
|
|
11678
|
-
id:
|
|
11743
|
+
id: z28.string().describe(
|
|
11679
11744
|
"Skill pack ID or name (e.g., '@mycompbox/planning' or UUID)"
|
|
11680
11745
|
),
|
|
11681
|
-
version:
|
|
11746
|
+
version: z28.string().optional().describe(
|
|
11682
11747
|
"Specific version to get manifest for (e.g., '1.2.3'). If not provided, uses latest stable version."
|
|
11683
11748
|
)
|
|
11684
11749
|
}
|
|
@@ -11768,7 +11833,7 @@ function registerGetPackManifestTool(server2) {
|
|
|
11768
11833
|
}
|
|
11769
11834
|
|
|
11770
11835
|
// src/tools/skill-packs/sync-local.ts
|
|
11771
|
-
import { z as
|
|
11836
|
+
import { z as z29 } from "zod";
|
|
11772
11837
|
import * as fs3 from "fs/promises";
|
|
11773
11838
|
import * as path3 from "path";
|
|
11774
11839
|
import { existsSync } from "fs";
|
|
@@ -11778,7 +11843,7 @@ function registerSyncLocalPacksTool(server2) {
|
|
|
11778
11843
|
{
|
|
11779
11844
|
description: "Detect drift between local skill pack installations and the registry.\n\nThis tool compares:\n1. .compbox/manifest.json (local installation record)\n2. Actual files in .github/ (agents, skills, instructions, presets)\n3. Database registry (what's officially installed)\n\nReports:\n- **Untracked files**: Files exist locally but not in manifest\n- **Missing files**: Files in manifest but not on filesystem\n- **Registry mismatches**: Local manifest differs from database registry\n- **Version differences**: Installed version vs. available version\n\nUse this to audit local installations and identify cleanup/sync needs.",
|
|
11780
11845
|
inputSchema: {
|
|
11781
|
-
projectRoot:
|
|
11846
|
+
projectRoot: z29.string().optional().describe(
|
|
11782
11847
|
"Project root directory (default: current working directory). Must contain .compbox/ and .github/ directories."
|
|
11783
11848
|
)
|
|
11784
11849
|
}
|
|
@@ -11970,21 +12035,21 @@ function registerSkillPackTools(server2) {
|
|
|
11970
12035
|
"compbox__manage_skill_packs",
|
|
11971
12036
|
{
|
|
11972
12037
|
description: "Manage Skill Packs with action-based routing. This composite tool provides 5 actions:\n\n**list** - List available skill packs from the registry (supports filtering by official/search)\n**get** - Get details about a specific skill pack by ID or name\n**install** - Install a skill pack by ID/name and version\n**update** - Update an installed skill pack to a new version (or 'latest')\n**list_installed** - List all installed skill packs with their status\n\nUse this to discover, install, and manage skill packs during AI sessions.",
|
|
11973
|
-
inputSchema:
|
|
11974
|
-
action:
|
|
12038
|
+
inputSchema: z30.object({
|
|
12039
|
+
action: z30.enum(["list", "get", "install", "update", "list_installed"]).describe(
|
|
11975
12040
|
"The action to perform: 'list' (browse registry), 'get' (pack details), 'install', 'update', or 'list_installed' (your installed packs)"
|
|
11976
12041
|
),
|
|
11977
12042
|
// Used by: list, get, install, update
|
|
11978
|
-
id:
|
|
12043
|
+
id: z30.string().optional().describe("Skill pack ID or name (e.g., '@mycompbox/planning'). Required for get/install/update actions."),
|
|
11979
12044
|
// Used by: list
|
|
11980
|
-
cursor:
|
|
11981
|
-
limit:
|
|
11982
|
-
isOfficial:
|
|
11983
|
-
query:
|
|
12045
|
+
cursor: z30.string().optional().describe("Pagination cursor from previous response (list action only)"),
|
|
12046
|
+
limit: z30.number().int().min(1).max(100).optional().describe("Maximum results per page, default 20, max 100 (list action only)"),
|
|
12047
|
+
isOfficial: z30.boolean().optional().describe("Filter by official packs (list action only)"),
|
|
12048
|
+
query: z30.string().optional().describe("Search query to filter by name (list action only)"),
|
|
11984
12049
|
// Used by: get
|
|
11985
|
-
includeVersions:
|
|
12050
|
+
includeVersions: z30.boolean().optional().describe("Include all versions in response (get action only)"),
|
|
11986
12051
|
// Used by: install, update
|
|
11987
|
-
version:
|
|
12052
|
+
version: z30.string().optional().describe("Version to install/update to (e.g., '1.2.3' or 'latest'). Required for install/update actions.")
|
|
11988
12053
|
})
|
|
11989
12054
|
},
|
|
11990
12055
|
async (input) => {
|
|
@@ -12270,7 +12335,7 @@ function withLegacyToolCallRewrite(transport) {
|
|
|
12270
12335
|
var SERVER_NAME = "compbox-mcp";
|
|
12271
12336
|
function resolveServerVersion() {
|
|
12272
12337
|
if (true) {
|
|
12273
|
-
return "1.21.
|
|
12338
|
+
return "1.21.5";
|
|
12274
12339
|
}
|
|
12275
12340
|
const require2 = createRequire(import.meta.url);
|
|
12276
12341
|
for (const candidate of ["../package.json", "./package.json"]) {
|