@mtaap/mcp 0.2.13 → 0.5.1

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/dist/cli.js CHANGED
@@ -30,15 +30,18 @@ var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
30
30
  // package.json
31
31
  var package_default = {
32
32
  name: "@mtaap/mcp",
33
- version: "0.2.12",
33
+ version: "0.5.1",
34
34
  description: "Model Context Protocol (MCP) server for AI agents to interact with Collab - the multi-tenant collaborative agent development platform",
35
35
  mcpName: "collab",
36
36
  scripts: {
37
- build: "tsup"
37
+ build: "pnpm build:ui && tsup",
38
+ "build:ui": "node scripts/build-ui.mjs",
39
+ "dev:ui": "vite build --watch"
38
40
  },
39
41
  main: "./dist/index.js",
40
42
  types: "./dist/index.d.ts",
41
43
  bin: {
44
+ mcp: "./dist/cli.js",
42
45
  "collab-mcp": "./dist/cli.js",
43
46
  "collab-mcp-server": "./dist/server.js"
44
47
  },
@@ -71,6 +74,7 @@ var package_default = {
71
74
  },
72
75
  dependencies: {
73
76
  "@modelcontextprotocol/sdk": "^1.0.0",
77
+ "@modelcontextprotocol/ext-apps": "^1.0.1",
74
78
  express: "^5.0.1",
75
79
  zod: "^4.3.5"
76
80
  },
@@ -79,8 +83,18 @@ var package_default = {
79
83
  "@mtaap/core": "workspace:*",
80
84
  "@types/express": "^5.0.0",
81
85
  "@types/node": "^22.0.0",
86
+ "@types/react": "^19.0.0",
87
+ "@types/react-dom": "^19.0.0",
88
+ "@vitejs/plugin-react": "^4.4.0",
89
+ autoprefixer: "^10.4.21",
90
+ postcss: "^8.5.3",
91
+ react: "^19.0.0",
92
+ "react-dom": "^19.0.0",
93
+ tailwindcss: "^3.4.17",
82
94
  tsup: "^8.5.1",
83
- typescript: "^5.4.0"
95
+ typescript: "^5.4.0",
96
+ vite: "^6.3.2",
97
+ "vite-plugin-singlefile": "^2.0.3"
84
98
  }
85
99
  };
86
100
 
@@ -88,7 +102,7 @@ var package_default = {
88
102
  var VERSION = package_default.version;
89
103
 
90
104
  // src/index.ts
91
- var import_zod3 = require("zod");
105
+ var import_zod9 = require("zod");
92
106
 
93
107
  // ../../packages/core/dist/constants/enums.js
94
108
  var TaskState;
@@ -174,13 +188,11 @@ var WebSocketEventType;
174
188
  WebSocketEventType2["TASK_UPDATED"] = "task.updated";
175
189
  WebSocketEventType2["TASK_DELETED"] = "task.deleted";
176
190
  WebSocketEventType2["MEMBER_JOINED"] = "member.joined";
191
+ WebSocketEventType2["AGENT_STARTED"] = "agent.started";
192
+ WebSocketEventType2["AGENT_OUTPUT"] = "agent.output";
193
+ WebSocketEventType2["AGENT_STOPPED"] = "agent.stopped";
194
+ WebSocketEventType2["AGENT_ERROR"] = "agent.error";
177
195
  })(WebSocketEventType || (WebSocketEventType = {}));
178
- var AuthProvider;
179
- (function(AuthProvider2) {
180
- AuthProvider2["CREDENTIALS"] = "credentials";
181
- AuthProvider2["LDAP"] = "ldap";
182
- AuthProvider2["SSO"] = "sso";
183
- })(AuthProvider || (AuthProvider = {}));
184
196
  var SubscriptionStatus;
185
197
  (function(SubscriptionStatus2) {
186
198
  SubscriptionStatus2["ACTIVE"] = "ACTIVE";
@@ -196,6 +208,37 @@ var EventType;
196
208
  EventType2["ACCESS"] = "ACCESS";
197
209
  EventType2["MODIFICATION"] = "MODIFICATION";
198
210
  })(EventType || (EventType = {}));
211
+ var CreatedVia;
212
+ (function(CreatedVia2) {
213
+ CreatedVia2["UI"] = "UI";
214
+ CreatedVia2["API_KEY"] = "API_KEY";
215
+ CreatedVia2["OAUTH"] = "OAUTH";
216
+ })(CreatedVia || (CreatedVia = {}));
217
+ var AgentModel;
218
+ (function(AgentModel2) {
219
+ AgentModel2["OPUS"] = "OPUS";
220
+ AgentModel2["SONNET"] = "SONNET";
221
+ AgentModel2["HAIKU"] = "HAIKU";
222
+ })(AgentModel || (AgentModel = {}));
223
+ var AgentModelMode;
224
+ (function(AgentModelMode2) {
225
+ AgentModelMode2["DEFAULT"] = "DEFAULT";
226
+ AgentModelMode2["PRESET"] = "PRESET";
227
+ AgentModelMode2["CUSTOM"] = "CUSTOM";
228
+ })(AgentModelMode || (AgentModelMode = {}));
229
+ var AgentCLIType;
230
+ (function(AgentCLIType2) {
231
+ AgentCLIType2["CLAUDE_CODE"] = "CLAUDE_CODE";
232
+ AgentCLIType2["OPENCODE"] = "OPENCODE";
233
+ })(AgentCLIType || (AgentCLIType = {}));
234
+ var AgentSessionStatus;
235
+ (function(AgentSessionStatus2) {
236
+ AgentSessionStatus2["STARTING"] = "STARTING";
237
+ AgentSessionStatus2["RUNNING"] = "RUNNING";
238
+ AgentSessionStatus2["STOPPING"] = "STOPPING";
239
+ AgentSessionStatus2["STOPPED"] = "STOPPED";
240
+ AgentSessionStatus2["ERROR"] = "ERROR";
241
+ })(AgentSessionStatus || (AgentSessionStatus = {}));
199
242
 
200
243
  // ../../packages/core/dist/constants/state-machine.js
201
244
  var VALID_TRANSITIONS = {
@@ -219,6 +262,62 @@ var VALID_TRANSITIONS = {
219
262
  [TaskState.DONE]: []
220
263
  };
221
264
 
265
+ // ../../packages/core/dist/constants/oauth.js
266
+ var OAuthScopes = {
267
+ /** Read-only access to MCP resources */
268
+ READ: "mcp:read",
269
+ /** Read and write access to MCP resources */
270
+ WRITE: "mcp:write",
271
+ /** Full administrative access */
272
+ ADMIN: "mcp:admin"
273
+ };
274
+ var VALID_OAUTH_SCOPES = [
275
+ OAuthScopes.READ,
276
+ OAuthScopes.WRITE,
277
+ OAuthScopes.ADMIN
278
+ ];
279
+ var DEFAULT_OAUTH_SCOPES = `${OAuthScopes.READ} ${OAuthScopes.WRITE}`;
280
+ var OAUTH_SCOPE_TO_PERMISSION = {
281
+ [OAuthScopes.READ]: ApiKeyPermission.READ,
282
+ [OAuthScopes.WRITE]: ApiKeyPermission.WRITE,
283
+ [OAuthScopes.ADMIN]: ApiKeyPermission.ADMIN
284
+ };
285
+ var PERMISSION_TO_OAUTH_SCOPE = {
286
+ [ApiKeyPermission.READ]: OAuthScopes.READ,
287
+ [ApiKeyPermission.WRITE]: OAuthScopes.WRITE,
288
+ [ApiKeyPermission.ADMIN]: OAuthScopes.ADMIN
289
+ };
290
+ var OAuthTokenLifetimes = {
291
+ /** Access token lifetime: 1 hour */
292
+ ACCESS_TOKEN_MS: 60 * 60 * 1e3,
293
+ /** Refresh token lifetime: 30 days */
294
+ REFRESH_TOKEN_MS: 30 * 24 * 60 * 60 * 1e3,
295
+ /** Authorization code lifetime: 10 minutes */
296
+ AUTHORIZATION_CODE_MS: 10 * 60 * 1e3
297
+ };
298
+ var OAuthGrantTypes = {
299
+ AUTHORIZATION_CODE: "authorization_code",
300
+ REFRESH_TOKEN: "refresh_token"
301
+ };
302
+ var SUPPORTED_GRANT_TYPES = [
303
+ OAuthGrantTypes.AUTHORIZATION_CODE,
304
+ OAuthGrantTypes.REFRESH_TOKEN
305
+ ];
306
+ var OAuthResponseTypes = {
307
+ CODE: "code"
308
+ };
309
+ var OAuthCodeChallengeMethods = {
310
+ S256: "S256"
311
+ };
312
+ var OAuthRateLimits = {
313
+ /** /oauth/token: 30 requests per minute per client */
314
+ TOKEN_ENDPOINT: { limit: 30, windowMs: 60 * 1e3 },
315
+ /** /oauth/authorize: 10 requests per minute per user */
316
+ AUTHORIZE_ENDPOINT: { limit: 10, windowMs: 60 * 1e3 },
317
+ /** /oauth/register: 5 requests per minute per IP */
318
+ REGISTER_ENDPOINT: { limit: 5, windowMs: 60 * 1e3 }
319
+ };
320
+
222
321
  // ../../packages/core/dist/config/deployment.js
223
322
  var config = {
224
323
  deploymentMode: process.env.DEPLOYMENT_MODE || "saas"
@@ -226,20 +325,24 @@ var config = {
226
325
  var isSaas = config.deploymentMode === "saas";
227
326
  var isOnPrem = config.deploymentMode === "onprem";
228
327
 
229
- // ../../packages/core/dist/version.js
230
- var VERSION2 = "0.1.0";
328
+ // ../../packages/core/dist/versions.js
329
+ var VERSIONS = {
330
+ core: "0.4.0",
331
+ web: "0.4.0",
332
+ mcp: "0.5.0"
333
+ };
334
+ var VERSION2 = VERSIONS.core;
231
335
 
232
336
  // ../../packages/core/dist/config/index.js
233
337
  var DEPLOYMENT_MODE = process.env.DEPLOYMENT_MODE || "saas";
234
338
  var config2 = {
235
339
  version: VERSION2,
340
+ packages: VERSIONS,
236
341
  deploymentMode: DEPLOYMENT_MODE,
237
342
  billing: {
238
343
  enabled: DEPLOYMENT_MODE === "saas",
239
344
  revenuecat: {
240
- publicKey: process.env.REVENUECAT_PUBLIC_API_KEY,
241
- stripeKey: process.env.STRIPE_SECRET_KEY
242
- // Required by RevenueCat Web Billing
345
+ publicKey: process.env.NEXT_PUBLIC_REVENUECAT_PUBLIC_KEY
243
346
  }
244
347
  },
245
348
  licensing: {
@@ -307,6 +410,18 @@ var config2 = {
307
410
  requestsPerHour: 1e3
308
411
  }
309
412
  },
413
+ agent: {
414
+ defaultModel: "SONNET",
415
+ sessionTimeoutMs: 30 * 60 * 1e3,
416
+ // 30 minutes
417
+ maxSessionDurationMs: 4 * 60 * 60 * 1e3,
418
+ // 4 hours
419
+ maxConcurrentSessions: {
420
+ FREE: 1,
421
+ PRO: 5,
422
+ ENTERPRISE: -1
423
+ }
424
+ },
310
425
  limits: {
311
426
  projectNameMaxLength: 100,
312
427
  taskDescriptionMaxLength: 5e3,
@@ -345,7 +460,6 @@ var OrganizationIdSchema = import_zod.z.string().regex(/^org_[a-zA-Z0-9]+$/);
345
460
  var OrganizationSchema = import_zod.z.object({
346
461
  id: OrganizationIdSchema,
347
462
  name: import_zod.z.string().min(1).max(255),
348
- slug: import_zod.z.string().min(1).max(100).regex(/^[a-z0-9-]+$/),
349
463
  logoUrl: import_zod.z.string().url().nullable(),
350
464
  accentColor: import_zod.z.string().regex(/^#[0-9A-Fa-f]{6}$/).nullable(),
351
465
  tenantName: import_zod.z.string().nullable(),
@@ -473,239 +587,376 @@ var ProjectCollaboratorSchema = import_zod.z.object({
473
587
  });
474
588
 
475
589
  // ../../packages/core/dist/validation/index.js
590
+ var import_zod3 = require("zod");
591
+
592
+ // ../../packages/core/dist/validation/oauth.js
476
593
  var import_zod2 = require("zod");
477
- var ListProjectsInputSchema = import_zod2.z.object({
478
- workspaceType: import_zod2.z.preprocess((val) => typeof val === "string" ? val.toUpperCase() : val, import_zod2.z.enum(["TEAM", "PERSONAL", "ALL"]).optional())
479
- });
480
- var ListTasksInputSchema = import_zod2.z.object({
481
- projectId: import_zod2.z.string().optional(),
482
- state: import_zod2.z.nativeEnum(TaskState).optional(),
483
- assigneeId: import_zod2.z.string().optional(),
484
- includeArchived: import_zod2.z.boolean().optional()
485
- });
486
- var cuidOrPrefixedId = import_zod2.z.string().regex(/^([a-z0-9]+|[a-z]+_[a-zA-Z0-9]+)$/);
487
- var gitBranchName = import_zod2.z.string().min(1).max(100).regex(/^[a-zA-Z0-9][-a-zA-Z0-9._/]*[a-zA-Z0-9]$|^[a-zA-Z0-9]$/, "Branch name must start and end with alphanumeric character").refine((val) => !val.includes("..") && !val.includes("@{") && !val.includes("//") && !val.endsWith(".lock") && !val.includes("~") && !val.includes("^") && !val.includes(":") && !val.includes("?") && !val.includes("*") && !val.includes("[") && !val.includes("\\") && !val.includes(" ") && !val.includes(";") && !val.includes("&") && !val.includes("|") && !val.includes("$") && !val.includes("`") && !val.includes("'") && !val.includes('"') && !val.includes("<") && !val.includes(">") && !val.includes("(") && !val.includes(")"), "Invalid branch name: contains forbidden characters or sequences");
488
- var GetTaskInputSchema = import_zod2.z.object({
594
+ var scopeString = import_zod2.z.string().optional().transform((val) => {
595
+ if (!val)
596
+ return void 0;
597
+ const scopes = val.split(" ").filter(Boolean);
598
+ const validScopes = scopes.filter((s) => VALID_OAUTH_SCOPES.includes(s));
599
+ return validScopes.length > 0 ? validScopes.join(" ") : void 0;
600
+ });
601
+ var redirectUri = import_zod2.z.string().url().refine((uri) => {
602
+ const url = new URL(uri);
603
+ return url.protocol === "https:" || url.hostname === "localhost" || url.hostname === "127.0.0.1";
604
+ }, { message: "redirect_uri must use HTTPS or be localhost" });
605
+ var codeVerifier = import_zod2.z.string().min(43).max(128).regex(/^[A-Za-z0-9._~-]+$/, "code_verifier must only contain unreserved characters");
606
+ var codeChallenge = import_zod2.z.string().min(43).max(128).regex(/^[A-Za-z0-9_-]+$/, "code_challenge must be base64url encoded (no padding)");
607
+ var DynamicClientRegistrationSchema = import_zod2.z.object({
608
+ redirect_uris: import_zod2.z.array(redirectUri).min(1),
609
+ client_name: import_zod2.z.string().min(1).max(255),
610
+ client_uri: import_zod2.z.string().url().optional(),
611
+ logo_uri: import_zod2.z.string().url().optional(),
612
+ // Accept lowercase OAuth spec values
613
+ grant_types: import_zod2.z.array(import_zod2.z.enum(["authorization_code", "refresh_token"])).default(["authorization_code", "refresh_token"]),
614
+ response_types: import_zod2.z.array(import_zod2.z.enum([OAuthResponseTypes.CODE])).default([OAuthResponseTypes.CODE]),
615
+ scope: scopeString,
616
+ // Accept lowercase OAuth spec values
617
+ token_endpoint_auth_method: import_zod2.z.enum(["none", "client_secret_post", "client_secret_basic"]).default("none")
618
+ });
619
+ var DynamicClientRegistrationResponseSchema = import_zod2.z.object({
620
+ client_id: import_zod2.z.string(),
621
+ client_secret: import_zod2.z.string().optional(),
622
+ client_id_issued_at: import_zod2.z.number(),
623
+ client_secret_expires_at: import_zod2.z.number().optional(),
624
+ redirect_uris: import_zod2.z.array(import_zod2.z.string()),
625
+ client_name: import_zod2.z.string(),
626
+ client_uri: import_zod2.z.string().optional(),
627
+ logo_uri: import_zod2.z.string().optional(),
628
+ grant_types: import_zod2.z.array(import_zod2.z.string()),
629
+ response_types: import_zod2.z.array(import_zod2.z.string()),
630
+ scope: import_zod2.z.string(),
631
+ token_endpoint_auth_method: import_zod2.z.string(),
632
+ registration_access_token: import_zod2.z.string().optional(),
633
+ registration_client_uri: import_zod2.z.string().optional()
634
+ });
635
+ var AuthorizationRequestSchema = import_zod2.z.object({
636
+ response_type: import_zod2.z.literal(OAuthResponseTypes.CODE),
637
+ client_id: import_zod2.z.string().min(1),
638
+ redirect_uri: redirectUri,
639
+ scope: scopeString,
640
+ state: import_zod2.z.string().max(255).optional(),
641
+ // PKCE is mandatory in OAuth 2.1
642
+ code_challenge: codeChallenge,
643
+ code_challenge_method: import_zod2.z.literal(OAuthCodeChallengeMethods.S256)
644
+ });
645
+ var TokenRequestAuthorizationCodeSchema = import_zod2.z.object({
646
+ grant_type: import_zod2.z.literal(OAuthGrantTypes.AUTHORIZATION_CODE),
647
+ code: import_zod2.z.string().min(1),
648
+ redirect_uri: redirectUri,
649
+ client_id: import_zod2.z.string().min(1),
650
+ // PKCE code verifier is mandatory
651
+ code_verifier: codeVerifier,
652
+ // Client secret is optional (for confidential clients)
653
+ client_secret: import_zod2.z.string().optional()
654
+ });
655
+ var TokenRequestRefreshTokenSchema = import_zod2.z.object({
656
+ grant_type: import_zod2.z.literal(OAuthGrantTypes.REFRESH_TOKEN),
657
+ refresh_token: import_zod2.z.string().min(1),
658
+ client_id: import_zod2.z.string().min(1),
659
+ // Optional: request reduced scope
660
+ scope: scopeString,
661
+ // Client secret is optional (for confidential clients)
662
+ client_secret: import_zod2.z.string().optional()
663
+ });
664
+ var TokenRequestSchema = import_zod2.z.discriminatedUnion("grant_type", [
665
+ TokenRequestAuthorizationCodeSchema,
666
+ TokenRequestRefreshTokenSchema
667
+ ]);
668
+ var TokenResponseSchema = import_zod2.z.object({
669
+ access_token: import_zod2.z.string(),
670
+ token_type: import_zod2.z.literal("Bearer"),
671
+ expires_in: import_zod2.z.number(),
672
+ refresh_token: import_zod2.z.string().optional(),
673
+ scope: import_zod2.z.string()
674
+ });
675
+ var TokenRevocationRequestSchema = import_zod2.z.object({
676
+ token: import_zod2.z.string().min(1),
677
+ token_type_hint: import_zod2.z.enum(["access_token", "refresh_token"]).optional(),
678
+ client_id: import_zod2.z.string().min(1),
679
+ client_secret: import_zod2.z.string().optional()
680
+ });
681
+ var OAuthErrorResponseSchema = import_zod2.z.object({
682
+ error: import_zod2.z.string(),
683
+ error_description: import_zod2.z.string().optional(),
684
+ error_uri: import_zod2.z.string().url().optional(),
685
+ state: import_zod2.z.string().optional()
686
+ });
687
+ var AuthorizationServerMetadataSchema = import_zod2.z.object({
688
+ issuer: import_zod2.z.string().url(),
689
+ authorization_endpoint: import_zod2.z.string().url(),
690
+ token_endpoint: import_zod2.z.string().url(),
691
+ registration_endpoint: import_zod2.z.string().url().optional(),
692
+ revocation_endpoint: import_zod2.z.string().url().optional(),
693
+ scopes_supported: import_zod2.z.array(import_zod2.z.string()),
694
+ response_types_supported: import_zod2.z.array(import_zod2.z.string()),
695
+ grant_types_supported: import_zod2.z.array(import_zod2.z.string()),
696
+ token_endpoint_auth_methods_supported: import_zod2.z.array(import_zod2.z.string()),
697
+ code_challenge_methods_supported: import_zod2.z.array(import_zod2.z.string()),
698
+ service_documentation: import_zod2.z.string().url().optional()
699
+ });
700
+ var ProtectedResourceMetadataSchema = import_zod2.z.object({
701
+ resource: import_zod2.z.string().url(),
702
+ authorization_servers: import_zod2.z.array(import_zod2.z.string().url()),
703
+ scopes_supported: import_zod2.z.array(import_zod2.z.string()).optional(),
704
+ bearer_methods_supported: import_zod2.z.array(import_zod2.z.string()).optional(),
705
+ resource_signing_alg_values_supported: import_zod2.z.array(import_zod2.z.string()).optional(),
706
+ resource_documentation: import_zod2.z.string().url().optional()
707
+ });
708
+ var InternalTokenValidationRequestSchema = import_zod2.z.object({
709
+ access_token: import_zod2.z.string().min(1)
710
+ });
711
+ var InternalTokenValidationResponseSchema = import_zod2.z.object({
712
+ valid: import_zod2.z.boolean(),
713
+ userId: import_zod2.z.string().optional(),
714
+ userEmail: import_zod2.z.string().optional(),
715
+ userName: import_zod2.z.string().optional(),
716
+ scope: import_zod2.z.string().optional(),
717
+ permissions: import_zod2.z.string().optional(),
718
+ clientId: import_zod2.z.string().optional(),
719
+ expiresAt: import_zod2.z.string().optional()
720
+ });
721
+
722
+ // ../../packages/core/dist/validation/index.js
723
+ var ListProjectsInputSchema = import_zod3.z.object({
724
+ workspaceType: import_zod3.z.preprocess((val) => typeof val === "string" ? val.toUpperCase() : val, import_zod3.z.enum(["TEAM", "PERSONAL", "ALL"]).optional())
725
+ });
726
+ var ListTasksInputSchema = import_zod3.z.object({
727
+ projectId: import_zod3.z.string().optional(),
728
+ state: import_zod3.z.nativeEnum(TaskState).optional(),
729
+ assigneeId: import_zod3.z.string().optional(),
730
+ includeArchived: import_zod3.z.boolean().optional()
731
+ });
732
+ var cuidOrPrefixedId = import_zod3.z.string().regex(/^([a-z0-9]+|[a-z]+_[a-zA-Z0-9]+)$/);
733
+ var gitBranchName = import_zod3.z.string().min(1).max(100).regex(/^[a-zA-Z0-9][-a-zA-Z0-9._/]*[a-zA-Z0-9]$|^[a-zA-Z0-9]$/, "Branch name must start and end with alphanumeric character").refine((val) => !val.includes("..") && !val.includes("@{") && !val.includes("//") && !val.endsWith(".lock") && !val.includes("~") && !val.includes("^") && !val.includes(":") && !val.includes("?") && !val.includes("*") && !val.includes("[") && !val.includes("\\") && !val.includes(" ") && !val.includes(";") && !val.includes("&") && !val.includes("|") && !val.includes("$") && !val.includes("`") && !val.includes("'") && !val.includes('"') && !val.includes("<") && !val.includes(">") && !val.includes("(") && !val.includes(")"), "Invalid branch name: contains forbidden characters or sequences");
734
+ var GetTaskInputSchema = import_zod3.z.object({
489
735
  taskId: cuidOrPrefixedId
490
736
  });
491
- var AssignTaskInputSchema = import_zod2.z.object({
737
+ var AssignTaskInputSchema = import_zod3.z.object({
492
738
  projectId: cuidOrPrefixedId,
493
739
  taskId: cuidOrPrefixedId,
494
- expectedState: import_zod2.z.nativeEnum(TaskState).default(TaskState.TODO)
740
+ expectedState: import_zod3.z.nativeEnum(TaskState).default(TaskState.TODO)
495
741
  });
496
- var UpdateProgressInputSchema = import_zod2.z.object({
742
+ var UpdateProgressInputSchema = import_zod3.z.object({
497
743
  taskId: cuidOrPrefixedId,
498
- statusMessage: import_zod2.z.string().max(1e3).optional(),
499
- completedCheckpointIds: import_zod2.z.array(import_zod2.z.string()).optional(),
500
- currentCheckpointIndex: import_zod2.z.number().int().optional()
744
+ statusMessage: import_zod3.z.string().max(1e3).optional(),
745
+ completedCheckpointIds: import_zod3.z.array(import_zod3.z.string()).optional(),
746
+ currentCheckpointIndex: import_zod3.z.number().int().optional()
501
747
  });
502
- var CompleteTaskInputSchema = import_zod2.z.object({
748
+ var CompleteTaskInputSchema = import_zod3.z.object({
503
749
  projectId: cuidOrPrefixedId,
504
750
  taskId: cuidOrPrefixedId,
505
- pullRequestTitle: import_zod2.z.string().min(1).max(300).optional(),
506
- pullRequestBody: import_zod2.z.string().max(1e4).optional()
751
+ pullRequestTitle: import_zod3.z.string().min(1).max(300).optional(),
752
+ pullRequestBody: import_zod3.z.string().max(1e4).optional()
507
753
  });
508
- var ReportErrorInputSchema = import_zod2.z.object({
754
+ var ReportErrorInputSchema = import_zod3.z.object({
509
755
  taskId: cuidOrPrefixedId,
510
- errorType: import_zod2.z.nativeEnum(ErrorType),
511
- errorMessage: import_zod2.z.string().min(1).max(1e3),
512
- context: import_zod2.z.string().max(2e3).optional()
756
+ errorType: import_zod3.z.nativeEnum(ErrorType),
757
+ errorMessage: import_zod3.z.string().min(1).max(1e3),
758
+ context: import_zod3.z.string().max(2e3).optional()
513
759
  });
514
- var GetProjectContextInputSchema = import_zod2.z.object({
760
+ var GetProjectContextInputSchema = import_zod3.z.object({
515
761
  projectId: cuidOrPrefixedId
516
762
  });
517
- var AddNoteInputSchema = import_zod2.z.object({
763
+ var AddNoteInputSchema = import_zod3.z.object({
518
764
  taskId: cuidOrPrefixedId,
519
- content: import_zod2.z.string().min(1).max(500)
765
+ content: import_zod3.z.string().min(1).max(500)
520
766
  });
521
- var AbandonTaskInputSchema = import_zod2.z.object({
767
+ var AbandonTaskInputSchema = import_zod3.z.object({
522
768
  projectId: cuidOrPrefixedId,
523
769
  taskId: cuidOrPrefixedId,
524
- deleteBranch: import_zod2.z.boolean().optional()
770
+ deleteBranch: import_zod3.z.boolean().optional()
525
771
  });
526
- var RequestChangesInputSchema = import_zod2.z.object({
772
+ var RequestChangesInputSchema = import_zod3.z.object({
527
773
  projectId: cuidOrPrefixedId,
528
774
  taskId: cuidOrPrefixedId,
529
- reviewComments: import_zod2.z.string().min(1).max(5e3),
530
- requestedChanges: import_zod2.z.array(import_zod2.z.string().min(1).max(500)).optional()
775
+ reviewComments: import_zod3.z.string().min(1).max(5e3),
776
+ requestedChanges: import_zod3.z.array(import_zod3.z.string().min(1).max(500)).optional()
531
777
  });
532
- var ApproveTaskInputSchema = import_zod2.z.object({
778
+ var ApproveTaskInputSchema = import_zod3.z.object({
533
779
  projectId: cuidOrPrefixedId,
534
780
  taskId: cuidOrPrefixedId,
535
- reviewComments: import_zod2.z.string().max(2e3).optional()
781
+ reviewComments: import_zod3.z.string().max(2e3).optional()
536
782
  });
537
- var ArchiveTaskInputSchema = import_zod2.z.object({
783
+ var ArchiveTaskInputSchema = import_zod3.z.object({
538
784
  projectId: cuidOrPrefixedId,
539
785
  taskId: cuidOrPrefixedId
540
786
  });
541
- var UnarchiveTaskInputSchema = import_zod2.z.object({
787
+ var UnarchiveTaskInputSchema = import_zod3.z.object({
542
788
  projectId: cuidOrPrefixedId,
543
789
  taskId: cuidOrPrefixedId
544
790
  });
545
- var CreatePersonalProjectInputSchema = import_zod2.z.object({
546
- name: import_zod2.z.string().min(1).max(100),
547
- description: import_zod2.z.string().max(500).optional(),
548
- repositoryUrl: import_zod2.z.string().url()
791
+ var CreatePersonalProjectInputSchema = import_zod3.z.object({
792
+ name: import_zod3.z.string().min(1).max(100),
793
+ description: import_zod3.z.string().max(500).optional(),
794
+ repositoryUrl: import_zod3.z.string().url()
549
795
  });
550
- var CheckActiveTaskInputSchema = import_zod2.z.object({});
551
- var CreateTaskMCPInputSchema = import_zod2.z.object({
796
+ var CheckActiveTaskInputSchema = import_zod3.z.object({});
797
+ var CreateTaskMCPInputSchema = import_zod3.z.object({
552
798
  projectId: cuidOrPrefixedId,
553
799
  epicId: cuidOrPrefixedId.nullable().optional(),
554
- title: import_zod2.z.string().min(1).max(200),
555
- description: import_zod2.z.string().max(5e3),
556
- priority: import_zod2.z.nativeEnum(TaskPriority).default(TaskPriority.MEDIUM),
557
- acceptanceCriteria: import_zod2.z.array(import_zod2.z.object({
558
- description: import_zod2.z.string().min(1).max(500)
800
+ title: import_zod3.z.string().min(1).max(200),
801
+ description: import_zod3.z.string().max(5e3),
802
+ priority: import_zod3.z.nativeEnum(TaskPriority).default(TaskPriority.MEDIUM),
803
+ acceptanceCriteria: import_zod3.z.array(import_zod3.z.object({
804
+ description: import_zod3.z.string().min(1).max(500)
559
805
  })).min(1)
560
806
  });
561
- var CreateOrganizationInputSchema = import_zod2.z.object({
562
- name: import_zod2.z.string().min(1).max(255),
563
- slug: import_zod2.z.string().min(1).max(100).regex(/^[a-z0-9-]+$/).optional()
807
+ var CreateOrganizationInputSchema = import_zod3.z.object({
808
+ name: import_zod3.z.string().min(1).max(255)
564
809
  });
565
- var UpdateOrganizationInputSchema = import_zod2.z.object({
810
+ var UpdateOrganizationInputSchema = import_zod3.z.object({
566
811
  organizationId: cuidOrPrefixedId,
567
- name: import_zod2.z.string().min(1).max(255).optional(),
568
- logoUrl: import_zod2.z.string().url().nullable().optional(),
569
- accentColor: import_zod2.z.string().regex(/^#[0-9A-Fa-f]{6}$/, "Invalid hex color format. Expected #RRGGBB").nullable().optional(),
570
- tenantName: import_zod2.z.string().max(255).nullable().optional()
571
- });
572
- var CreateProjectInputSchema = import_zod2.z.object({
573
- name: import_zod2.z.string().min(1).max(100),
574
- description: import_zod2.z.string().max(500).optional(),
575
- type: import_zod2.z.nativeEnum(ProjectType),
576
- repositoryUrl: import_zod2.z.string().url(),
577
- baseBranch: import_zod2.z.string().default("develop").optional(),
578
- tags: import_zod2.z.array(import_zod2.z.string()).default([])
579
- });
580
- var UpdateProjectInputSchema = import_zod2.z.object({
581
- projectId: import_zod2.z.string().min(1).optional(),
582
- name: import_zod2.z.string().min(1).max(100).optional(),
583
- description: import_zod2.z.string().max(500).optional(),
584
- repositoryUrl: import_zod2.z.string().url().optional(),
585
- baseBranch: import_zod2.z.string().optional(),
586
- tags: import_zod2.z.array(import_zod2.z.string()).optional(),
587
- allowMemberArchive: import_zod2.z.boolean().optional()
588
- });
589
- var CreateEpicInputSchema = import_zod2.z.object({
812
+ name: import_zod3.z.string().min(1).max(255).optional(),
813
+ logoUrl: import_zod3.z.string().url().nullable().optional(),
814
+ accentColor: import_zod3.z.string().regex(/^#[0-9A-Fa-f]{6}$/, "Invalid hex color format. Expected #RRGGBB").nullable().optional(),
815
+ tenantName: import_zod3.z.string().max(255).nullable().optional()
816
+ });
817
+ var CreateProjectInputSchema = import_zod3.z.object({
818
+ name: import_zod3.z.string().min(1).max(100),
819
+ description: import_zod3.z.string().max(500).optional(),
820
+ type: import_zod3.z.nativeEnum(ProjectType),
821
+ repositoryUrl: import_zod3.z.string().url(),
822
+ baseBranch: import_zod3.z.string().default("develop").optional(),
823
+ tags: import_zod3.z.array(import_zod3.z.string()).default([])
824
+ });
825
+ var UpdateProjectInputSchema = import_zod3.z.object({
826
+ projectId: import_zod3.z.string().min(1).optional(),
827
+ name: import_zod3.z.string().min(1).max(100).optional(),
828
+ description: import_zod3.z.string().max(500).optional(),
829
+ repositoryUrl: import_zod3.z.string().url().optional(),
830
+ baseBranch: import_zod3.z.string().optional(),
831
+ tags: import_zod3.z.array(import_zod3.z.string()).optional(),
832
+ allowMemberArchive: import_zod3.z.boolean().optional(),
833
+ localRepoPath: import_zod3.z.string().max(500).optional()
834
+ });
835
+ var CreateEpicInputSchema = import_zod3.z.object({
590
836
  projectId: cuidOrPrefixedId,
591
- name: import_zod2.z.string().min(1).max(200),
592
- description: import_zod2.z.string().max(2e3).optional()
593
- });
594
- var CreateTaskInputSchema = import_zod2.z.object({
595
- projectId: import_zod2.z.string().min(1),
596
- epicId: import_zod2.z.string().min(1).nullable().optional(),
597
- title: import_zod2.z.string().min(1).max(200),
598
- description: import_zod2.z.string().max(5e3),
599
- priority: import_zod2.z.nativeEnum(TaskPriority).default(TaskPriority.MEDIUM),
600
- acceptanceCriteria: import_zod2.z.array(import_zod2.z.object({
601
- description: import_zod2.z.string().min(1).max(500)
837
+ name: import_zod3.z.string().min(1).max(200),
838
+ description: import_zod3.z.string().max(2e3).optional()
839
+ });
840
+ var CreateTaskInputSchema = import_zod3.z.object({
841
+ projectId: import_zod3.z.string().min(1),
842
+ epicId: import_zod3.z.string().min(1).nullable().optional(),
843
+ title: import_zod3.z.string().min(1).max(200),
844
+ description: import_zod3.z.string().max(5e3),
845
+ priority: import_zod3.z.nativeEnum(TaskPriority).default(TaskPriority.MEDIUM),
846
+ acceptanceCriteria: import_zod3.z.array(import_zod3.z.object({
847
+ description: import_zod3.z.string().min(1).max(500)
602
848
  })).min(1)
603
849
  });
604
- var UpdateTaskInputSchema = import_zod2.z.object({
605
- taskId: import_zod2.z.string().min(1),
606
- title: import_zod2.z.string().min(1).max(200).optional(),
607
- description: import_zod2.z.string().max(5e3).optional(),
608
- priority: import_zod2.z.nativeEnum(TaskPriority).optional(),
609
- state: import_zod2.z.nativeEnum(TaskState).optional(),
610
- assigneeId: import_zod2.z.string().nullable().optional(),
611
- acceptanceCriteria: import_zod2.z.array(import_zod2.z.object({
612
- id: import_zod2.z.string().optional(),
613
- description: import_zod2.z.string().min(1).max(500),
614
- completed: import_zod2.z.boolean().optional()
850
+ var UpdateTaskInputSchema = import_zod3.z.object({
851
+ taskId: import_zod3.z.string().min(1),
852
+ title: import_zod3.z.string().min(1).max(200).optional(),
853
+ description: import_zod3.z.string().max(5e3).optional(),
854
+ priority: import_zod3.z.nativeEnum(TaskPriority).optional(),
855
+ state: import_zod3.z.nativeEnum(TaskState).optional(),
856
+ assigneeId: import_zod3.z.string().nullable().optional(),
857
+ acceptanceCriteria: import_zod3.z.array(import_zod3.z.object({
858
+ id: import_zod3.z.string().optional(),
859
+ description: import_zod3.z.string().min(1).max(500),
860
+ completed: import_zod3.z.boolean().optional()
615
861
  })).optional()
616
862
  });
617
- var AssignTaskWebappInputSchema = import_zod2.z.object({
618
- taskId: import_zod2.z.string().min(1),
619
- userId: import_zod2.z.string().min(1)
863
+ var AssignTaskWebappInputSchema = import_zod3.z.object({
864
+ taskId: import_zod3.z.string().min(1),
865
+ userId: import_zod3.z.string().min(1)
620
866
  });
621
- var CreateTagInputSchema = import_zod2.z.object({
867
+ var CreateTagInputSchema = import_zod3.z.object({
622
868
  organizationId: cuidOrPrefixedId,
623
- name: import_zod2.z.string().min(1).max(50).regex(/^[a-zA-Z0-9\s-]+$/)
869
+ name: import_zod3.z.string().min(1).max(50).regex(/^[a-zA-Z0-9\s-]+$/)
624
870
  });
625
- var UpdateTagInputSchema = import_zod2.z.object({
626
- name: import_zod2.z.string().min(1).max(50).regex(/^[a-zA-Z0-9\s-]+$/)
871
+ var UpdateTagInputSchema = import_zod3.z.object({
872
+ name: import_zod3.z.string().min(1).max(50).regex(/^[a-zA-Z0-9\s-]+$/)
627
873
  });
628
- var UpdateOrganizationSettingsInputSchema = import_zod2.z.object({
874
+ var UpdateOrganizationSettingsInputSchema = import_zod3.z.object({
629
875
  organizationId: cuidOrPrefixedId,
630
- ldapEnabled: import_zod2.z.boolean().optional(),
631
- ldapUrl: import_zod2.z.string().url().nullable().optional(),
632
- ldapBindDN: import_zod2.z.string().nullable().optional(),
633
- ldapSearchBase: import_zod2.z.string().nullable().optional(),
634
- deleteMergedBranches: import_zod2.z.boolean().optional(),
635
- enforceConventionalCommits: import_zod2.z.boolean().optional(),
636
- maxPersonalProjectsPerUser: import_zod2.z.number().int().min(0).optional(),
637
- logoUrl: import_zod2.z.string().url().nullable().optional(),
638
- accentColor: import_zod2.z.string().regex(/^#[0-9A-Fa-f]{6}$/, "Invalid hex color format. Expected #RRGGBB").nullable().optional(),
639
- tenantName: import_zod2.z.string().max(255).nullable().optional()
640
- });
641
- var InviteUserInputSchema = import_zod2.z.object({
876
+ ldapEnabled: import_zod3.z.boolean().optional(),
877
+ ldapUrl: import_zod3.z.string().url().nullable().optional(),
878
+ ldapBindDN: import_zod3.z.string().nullable().optional(),
879
+ ldapSearchBase: import_zod3.z.string().nullable().optional(),
880
+ deleteMergedBranches: import_zod3.z.boolean().optional(),
881
+ enforceConventionalCommits: import_zod3.z.boolean().optional(),
882
+ maxPersonalProjectsPerUser: import_zod3.z.number().int().min(0).optional(),
883
+ logoUrl: import_zod3.z.string().url().nullable().optional(),
884
+ accentColor: import_zod3.z.string().regex(/^#[0-9A-Fa-f]{6}$/, "Invalid hex color format. Expected #RRGGBB").nullable().optional(),
885
+ tenantName: import_zod3.z.string().max(255).nullable().optional()
886
+ });
887
+ var InviteUserInputSchema = import_zod3.z.object({
642
888
  organizationId: cuidOrPrefixedId,
643
- email: import_zod2.z.string().email(),
644
- role: import_zod2.z.nativeEnum(UserRole).default(UserRole.MEMBER),
645
- tags: import_zod2.z.array(import_zod2.z.string()).default([])
889
+ email: import_zod3.z.string().email(),
890
+ role: import_zod3.z.nativeEnum(UserRole).default(UserRole.MEMBER),
891
+ tags: import_zod3.z.array(import_zod3.z.string()).default([])
646
892
  });
647
- var AssignUserTagsInputSchema = import_zod2.z.object({
893
+ var AssignUserTagsInputSchema = import_zod3.z.object({
648
894
  userId: cuidOrPrefixedId,
649
- tags: import_zod2.z.array(import_zod2.z.string()).min(0)
895
+ tags: import_zod3.z.array(import_zod3.z.string()).min(0)
650
896
  });
651
- var InviteCollaboratorInputSchema = import_zod2.z.object({
897
+ var InviteCollaboratorInputSchema = import_zod3.z.object({
652
898
  projectId: cuidOrPrefixedId,
653
- email: import_zod2.z.string().email()
899
+ email: import_zod3.z.string().email()
654
900
  });
655
- var PublishProjectInputSchema = import_zod2.z.object({
901
+ var PublishProjectInputSchema = import_zod3.z.object({
656
902
  projectId: cuidOrPrefixedId,
657
- transferOwnership: import_zod2.z.boolean().default(false),
658
- tags: import_zod2.z.array(import_zod2.z.string()).min(1)
903
+ transferOwnership: import_zod3.z.boolean().default(false),
904
+ tags: import_zod3.z.array(import_zod3.z.string()).min(1)
659
905
  });
660
- var GenerateApiKeyInputSchema = import_zod2.z.object({
661
- name: import_zod2.z.string().min(1).max(100),
662
- expiresInDays: import_zod2.z.number().int().min(1).max(365).default(90),
663
- permissions: import_zod2.z.nativeEnum(ApiKeyPermission).default(ApiKeyPermission.WRITE)
906
+ var GenerateApiKeyInputSchema = import_zod3.z.object({
907
+ name: import_zod3.z.string().min(1).max(100),
908
+ publicNickname: import_zod3.z.string().max(50).optional(),
909
+ expiresInDays: import_zod3.z.number().int().min(1).max(365).default(90),
910
+ permissions: import_zod3.z.nativeEnum(ApiKeyPermission).default(ApiKeyPermission.WRITE)
664
911
  });
665
- var RevokeApiKeyInputSchema = import_zod2.z.object({
912
+ var UpdateApiKeyInputSchema = import_zod3.z.object({
913
+ publicNickname: import_zod3.z.string().max(50).nullable().optional(),
914
+ scopedOrganizationId: import_zod3.z.string().optional().nullable(),
915
+ scopedProjectIds: import_zod3.z.array(import_zod3.z.string()).optional()
916
+ });
917
+ var RevokeApiKeyInputSchema = import_zod3.z.object({
666
918
  keyId: cuidOrPrefixedId
667
919
  });
668
- var LoginInputSchema = import_zod2.z.object({
669
- email: import_zod2.z.string().email(),
670
- password: import_zod2.z.string().min(8).max(255)
920
+ var LoginInputSchema = import_zod3.z.object({
921
+ email: import_zod3.z.string().email(),
922
+ password: import_zod3.z.string().min(8).max(255)
671
923
  });
672
- var RegisterInputSchema = import_zod2.z.object({
673
- email: import_zod2.z.string().email(),
674
- password: import_zod2.z.string().min(8).max(255),
675
- name: import_zod2.z.string().min(1).max(255),
676
- organizationSlug: import_zod2.z.string().min(1).max(100).regex(/^[a-z0-9-]+$/).optional()
924
+ var RegisterInputSchema = import_zod3.z.object({
925
+ email: import_zod3.z.string().email(),
926
+ password: import_zod3.z.string().min(8).max(255),
927
+ name: import_zod3.z.string().min(1).max(255)
677
928
  });
678
- var VerifyTaskInputSchema = import_zod2.z.object({
929
+ var VerifyTaskInputSchema = import_zod3.z.object({
679
930
  projectId: cuidOrPrefixedId,
680
931
  taskId: cuidOrPrefixedId,
681
- approved: import_zod2.z.boolean(),
682
- feedback: import_zod2.z.string().max(5e3).optional()
932
+ approved: import_zod3.z.boolean(),
933
+ feedback: import_zod3.z.string().max(5e3).optional()
683
934
  });
684
- var GetTaskPromptInputSchema = import_zod2.z.object({
935
+ var GetTaskPromptInputSchema = import_zod3.z.object({
685
936
  projectId: cuidOrPrefixedId,
686
937
  taskId: cuidOrPrefixedId
687
938
  });
688
- var UpdateTaskMCPInputSchema = import_zod2.z.object({
939
+ var UpdateTaskMCPInputSchema = import_zod3.z.object({
689
940
  projectId: cuidOrPrefixedId,
690
941
  taskId: cuidOrPrefixedId,
691
- title: import_zod2.z.string().min(1).max(200).optional(),
692
- description: import_zod2.z.string().max(5e3).optional(),
693
- priority: import_zod2.z.nativeEnum(TaskPriority).optional(),
694
- acceptanceCriteria: import_zod2.z.array(import_zod2.z.object({
695
- id: import_zod2.z.string().optional(),
696
- description: import_zod2.z.string().min(1).max(500)
942
+ title: import_zod3.z.string().min(1).max(200).optional(),
943
+ description: import_zod3.z.string().max(5e3).optional(),
944
+ priority: import_zod3.z.nativeEnum(TaskPriority).optional(),
945
+ acceptanceCriteria: import_zod3.z.array(import_zod3.z.object({
946
+ id: import_zod3.z.string().optional(),
947
+ description: import_zod3.z.string().min(1).max(500)
697
948
  })).optional()
698
949
  });
699
- var ReportBranchInputSchema = import_zod2.z.object({
950
+ var ReportBranchInputSchema = import_zod3.z.object({
700
951
  projectId: cuidOrPrefixedId,
701
952
  taskId: cuidOrPrefixedId,
702
953
  branchName: gitBranchName
703
954
  });
704
- var ReportPRInputSchema = import_zod2.z.object({
955
+ var ReportPRInputSchema = import_zod3.z.object({
705
956
  projectId: cuidOrPrefixedId,
706
957
  taskId: cuidOrPrefixedId,
707
- pullRequestUrl: import_zod2.z.string().url(),
708
- pullRequestNumber: import_zod2.z.number().int().positive()
958
+ pullRequestUrl: import_zod3.z.string().url(),
959
+ pullRequestNumber: import_zod3.z.number().int().positive()
709
960
  });
710
961
 
711
962
  // ../../packages/core/dist/logging/metrics.js
@@ -786,23 +1037,20 @@ function createHistogram(name, help, buckets = [5e-3, 0.01, 0.025, 0.05, 0.1, 0.
786
1037
  var httpRequestsTotal = createCounter("mtaap_http_requests_total", "Total number of HTTP requests");
787
1038
  var httpRequestDuration = createHistogram("mtaap_http_request_duration_seconds", "HTTP request duration in seconds");
788
1039
  var activeUsers = createGauge("mtaap_active_users", "Number of active users");
789
- var tasksTotal = createCounter("mtaap_tasks_total", "Total number of tasks by state");
790
- var taskStateChanges = createCounter("mtaap_task_state_changes_total", "Total number of task state changes");
791
1040
  var httpErrorsTotal = createCounter("mtaap_http_errors_total", "Total number of HTTP errors");
792
1041
  var httpActiveConnections = createGauge("mtaap_http_active_connections", "Number of active HTTP connections");
793
1042
  var newSignupsTotal = createCounter("mtaap_new_signups_total", "Total number of new user signups");
794
1043
  var loginSuccessTotal = createCounter("mtaap_login_success_total", "Total number of successful logins");
795
1044
  var loginFailureTotal = createCounter("mtaap_login_failure_total", "Total number of failed logins");
796
- var dbConnectionPoolActive = createGauge("mtaap_db_connection_pool_active", "Number of active database connections");
797
- var dbConnectionPoolIdle = createGauge("mtaap_db_connection_pool_idle", "Number of idle database connections");
798
- var dbConnectionPoolMax = createGauge("mtaap_db_connection_pool_max", "Maximum number of database connections");
799
1045
  var dbQueryDuration = createHistogram("mtaap_db_query_duration_seconds", "Database query duration in seconds");
800
1046
  var dbSlowQueriesTotal = createCounter("mtaap_db_slow_queries_total", "Total number of slow database queries (>1s)");
801
- var dbErrorsTotal = createCounter("mtaap_db_errors_total", "Total number of database errors");
802
1047
  var tasksCreatedTotal = createCounter("mtaap_tasks_created_total", "Total number of tasks created");
803
1048
  var tasksAssignedTotal = createCounter("mtaap_tasks_assigned_total", "Total number of tasks assigned");
804
1049
  var tasksCompletedTotal = createCounter("mtaap_tasks_completed_total", "Total number of tasks completed");
805
- var tasksByState = createGauge("mtaap_tasks_by_state", "Number of tasks by state");
1050
+ var agentSessionsTotal = createCounter("mtaap_agent_sessions_total", "Total number of agent sessions started");
1051
+ var agentErrorsTotal = createCounter("mtaap_agent_errors_total", "Total number of agent errors");
1052
+ var agentSessionDuration = createHistogram("mtaap_agent_session_duration_seconds", "Agent session duration in seconds", [1, 5, 15, 30, 60, 120, 300, 600, 1800, 3600]);
1053
+ var agentSessionsActive = createGauge("mtaap_agent_sessions_active", "Number of currently active agent sessions");
806
1054
 
807
1055
  // ../../packages/core/dist/logging/performance-monitor.js
808
1056
  var MAX_SAMPLES = 1e3;
@@ -1006,6 +1254,9 @@ var errorTrackerInstance = new NoOpErrorTracker();
1006
1254
 
1007
1255
  // src/api-client.ts
1008
1256
  var DEFAULT_TIMEOUT = 3e4;
1257
+ var DEFAULT_CACHE_TTL = 3e4;
1258
+ var MAX_RETRIES = 2;
1259
+ var INITIAL_RETRY_DELAY = 500;
1009
1260
  function sanitizeForLogging(str) {
1010
1261
  let sanitized = str.replace(/\bcollab_[a-zA-Z0-9_-]+\b/gi, "[REDACTED_API_KEY]");
1011
1262
  sanitized = sanitized.replace(/\bBearer\s+[a-zA-Z0-9._-]+\b/gi, "Bearer [REDACTED]");
@@ -1020,42 +1271,113 @@ var ApiError = class extends Error {
1020
1271
  this.details = details;
1021
1272
  this.name = "ApiError";
1022
1273
  }
1274
+ /**
1275
+ * Whether this error is transient and the request can be retried.
1276
+ * Retries on network errors (status 0), timeouts (408), and server errors (5xx).
1277
+ */
1278
+ get isRetryable() {
1279
+ return this.status === 0 || this.status === 408 || this.status >= 500;
1280
+ }
1023
1281
  };
1282
+ function sleep(ms) {
1283
+ return new Promise((resolve) => setTimeout(resolve, ms));
1284
+ }
1024
1285
  var MCPApiClient = class {
1025
1286
  baseUrl;
1026
1287
  apiKey;
1288
+ oauthToken;
1027
1289
  timeout;
1028
1290
  debug;
1029
1291
  authContext = null;
1292
+ cache = /* @__PURE__ */ new Map();
1030
1293
  constructor(config3) {
1294
+ if (!config3.apiKey && !config3.oauthToken) {
1295
+ throw new Error("Either apiKey or oauthToken must be provided");
1296
+ }
1031
1297
  this.baseUrl = config3.baseUrl.replace(/\/$/, "");
1032
1298
  this.apiKey = config3.apiKey;
1299
+ this.oauthToken = config3.oauthToken;
1033
1300
  this.timeout = config3.timeout ?? DEFAULT_TIMEOUT;
1034
1301
  this.debug = config3.debug ?? false;
1035
1302
  }
1036
1303
  /**
1037
- * Make an HTTP request to the API
1304
+ * Get a cached value if it exists and hasn't expired.
1305
+ */
1306
+ getCached(key) {
1307
+ const entry = this.cache.get(key);
1308
+ if (!entry) return void 0;
1309
+ if (Date.now() > entry.expiresAt) {
1310
+ this.cache.delete(key);
1311
+ return void 0;
1312
+ }
1313
+ return entry.data;
1314
+ }
1315
+ /**
1316
+ * Store a value in cache with a TTL.
1038
1317
  */
1039
- async request(method, path, body) {
1040
- const url = `${this.baseUrl}${path}`;
1318
+ setCache(key, data, ttl = DEFAULT_CACHE_TTL) {
1319
+ this.cache.set(key, { data, expiresAt: Date.now() + ttl });
1320
+ }
1321
+ /**
1322
+ * Make an HTTP request to the API with automatic retry on transient failures.
1323
+ */
1324
+ async request(method, path2, body) {
1325
+ let lastError;
1326
+ for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
1327
+ try {
1328
+ return await this.requestOnce(method, path2, body);
1329
+ } catch (error) {
1330
+ if (!(error instanceof ApiError) || !error.isRetryable || attempt === MAX_RETRIES) {
1331
+ throw error;
1332
+ }
1333
+ lastError = error;
1334
+ const delay = INITIAL_RETRY_DELAY * Math.pow(2, attempt);
1335
+ if (this.debug) {
1336
+ console.error(`[mcp-api] Retry ${attempt + 1}/${MAX_RETRIES} after ${delay}ms (${lastError.code})`);
1337
+ }
1338
+ await sleep(delay);
1339
+ }
1340
+ }
1341
+ throw lastError;
1342
+ }
1343
+ /**
1344
+ * Execute a single HTTP request to the API.
1345
+ */
1346
+ async requestOnce(method, path2, body) {
1347
+ const url = `${this.baseUrl}${path2}`;
1041
1348
  const controller = new AbortController();
1042
1349
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1043
1350
  if (this.debug) {
1044
- console.error(`[mcp-api] ${method} ${sanitizeForLogging(path)}`);
1351
+ console.error(`[mcp-api] ${method} ${sanitizeForLogging(path2)}`);
1045
1352
  }
1046
1353
  try {
1354
+ const headers = {
1355
+ "Content-Type": "application/json"
1356
+ };
1357
+ if (this.oauthToken) {
1358
+ headers["Authorization"] = `Bearer ${this.oauthToken}`;
1359
+ } else if (this.apiKey) {
1360
+ headers["X-API-Key"] = this.apiKey;
1361
+ }
1047
1362
  const response = await fetch(url, {
1048
1363
  method,
1049
- headers: {
1050
- "Content-Type": "application/json",
1051
- "X-API-Key": this.apiKey
1052
- },
1364
+ headers,
1053
1365
  body: body ? JSON.stringify(body) : void 0,
1054
1366
  signal: controller.signal
1055
1367
  });
1056
1368
  clearTimeout(timeoutId);
1057
1369
  const data = await response.json();
1058
1370
  if (!response.ok) {
1371
+ if (response.status === 403 && data.code === "EMAIL_NOT_VERIFIED" && data.verificationUrl) {
1372
+ throw new ApiError(
1373
+ `${data.error}
1374
+
1375
+ To verify your email, visit: ${data.verificationUrl}
1376
+ ${data.hint ? `Hint: ${data.hint}` : ""}`,
1377
+ "EMAIL_NOT_VERIFIED",
1378
+ 403
1379
+ );
1380
+ }
1059
1381
  throw new ApiError(
1060
1382
  data.error || "API request failed",
1061
1383
  data.code || "UNKNOWN_ERROR",
@@ -1102,14 +1424,19 @@ var MCPApiClient = class {
1102
1424
  return this.authenticate();
1103
1425
  }
1104
1426
  /**
1105
- * List accessible projects
1427
+ * List accessible projects (cached for 30s)
1106
1428
  */
1107
1429
  async listProjects(workspaceType) {
1108
1430
  const type = workspaceType || "ALL";
1109
- return this.request(
1431
+ const cacheKey = `listProjects:${type}`;
1432
+ const cached = this.getCached(cacheKey);
1433
+ if (cached) return cached;
1434
+ const result = await this.request(
1110
1435
  "GET",
1111
1436
  `/api/mcp/projects?workspaceType=${encodeURIComponent(type)}`
1112
1437
  );
1438
+ this.setCache(cacheKey, result);
1439
+ return result;
1113
1440
  }
1114
1441
  /**
1115
1442
  * Get single project details
@@ -1118,13 +1445,18 @@ var MCPApiClient = class {
1118
1445
  return this.request("GET", `/api/mcp/projects/${projectId}`);
1119
1446
  }
1120
1447
  /**
1121
- * Get project context (README, stack, conventions)
1448
+ * Get project context (README, stack, conventions) (cached for 60s)
1122
1449
  */
1123
1450
  async getProjectContext(projectId) {
1124
- return this.request(
1451
+ const cacheKey = `projectContext:${projectId}`;
1452
+ const cached = this.getCached(cacheKey);
1453
+ if (cached) return cached;
1454
+ const result = await this.request(
1125
1455
  "GET",
1126
1456
  `/api/mcp/projects/${projectId}/context`
1127
1457
  );
1458
+ this.setCache(cacheKey, result, 6e4);
1459
+ return result;
1128
1460
  }
1129
1461
  /**
1130
1462
  * Create a personal project
@@ -1152,8 +1484,8 @@ var MCPApiClient = class {
1152
1484
  if (filters.assigneeId) params.set("assigneeId", filters.assigneeId);
1153
1485
  if (filters.includeArchived) params.set("includeArchived", "true");
1154
1486
  const queryString = params.toString();
1155
- const path = queryString ? `/api/mcp/tasks?${queryString}` : "/api/mcp/tasks";
1156
- return this.request("GET", path);
1487
+ const path2 = queryString ? `/api/mcp/tasks?${queryString}` : "/api/mcp/tasks";
1488
+ return this.request("GET", path2);
1157
1489
  }
1158
1490
  /**
1159
1491
  * Get full task details
@@ -1286,7 +1618,8 @@ var MCPApiClient = class {
1286
1618
  );
1287
1619
  }
1288
1620
  /**
1289
- * Update task details (DRAFT/TODO states only)
1621
+ * Update task details (DRAFT/TODO states only).
1622
+ * Task stays in its current state.
1290
1623
  */
1291
1624
  async updateTask(taskId, projectId, data) {
1292
1625
  return this.request("PATCH", `/api/mcp/tasks/${taskId}`, {
@@ -1318,7 +1651,7 @@ var PERMISSION_RANK = {
1318
1651
  ADMIN: 3
1319
1652
  };
1320
1653
  function assertApiKeyPermission(apiKey, required, toolName) {
1321
- const actualRank = PERMISSION_RANK[apiKey.permissions] ?? 0;
1654
+ const actualRank = apiKey.permissions ? PERMISSION_RANK[apiKey.permissions] ?? 0 : 0;
1322
1655
  const requiredRank = PERMISSION_RANK[required] ?? 0;
1323
1656
  if (actualRank >= requiredRank) {
1324
1657
  return;
@@ -1336,6 +1669,454 @@ function assertApiKeyPermission(apiKey, required, toolName) {
1336
1669
  throw error;
1337
1670
  }
1338
1671
 
1672
+ // src/apps/task-details.ts
1673
+ var import_server2 = require("@modelcontextprotocol/ext-apps/server");
1674
+ var import_zod4 = require("zod");
1675
+
1676
+ // src/apps/helpers.ts
1677
+ var import_server = require("@modelcontextprotocol/ext-apps/server");
1678
+ var import_promises = __toESM(require("fs/promises"));
1679
+ var import_node_path = __toESM(require("path"));
1680
+ var import_node_url = require("url");
1681
+ var import_meta = {};
1682
+ var getDirname = () => {
1683
+ try {
1684
+ return import_node_path.default.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
1685
+ } catch {
1686
+ return __dirname;
1687
+ }
1688
+ };
1689
+ function getAppHtmlPath(htmlFileName) {
1690
+ return import_node_path.default.join(getDirname(), "apps", htmlFileName);
1691
+ }
1692
+ function registerAppHtmlResource(server, config3) {
1693
+ (0, import_server.registerAppResource)(
1694
+ server,
1695
+ config3.name,
1696
+ config3.uri,
1697
+ {
1698
+ mimeType: import_server.RESOURCE_MIME_TYPE,
1699
+ description: config3.description
1700
+ },
1701
+ async () => {
1702
+ const htmlPath = getAppHtmlPath(config3.htmlFileName);
1703
+ try {
1704
+ const html = await import_promises.default.readFile(htmlPath, "utf-8");
1705
+ return {
1706
+ contents: [
1707
+ {
1708
+ uri: config3.uri,
1709
+ mimeType: import_server.RESOURCE_MIME_TYPE,
1710
+ text: html
1711
+ }
1712
+ ]
1713
+ };
1714
+ } catch {
1715
+ return {
1716
+ contents: [
1717
+ {
1718
+ uri: config3.uri,
1719
+ mimeType: import_server.RESOURCE_MIME_TYPE,
1720
+ text: `<!DOCTYPE html><html><body><p>${config3.fallbackLabel} UI not available. Build the UI apps first.</p></body></html>`
1721
+ }
1722
+ ]
1723
+ };
1724
+ }
1725
+ }
1726
+ );
1727
+ }
1728
+
1729
+ // src/apps/task-details.ts
1730
+ var RESOURCE_URI = "ui://collab/task-details.html";
1731
+ function registerTaskDetailsApp(server, apiClient, _authContext) {
1732
+ (0, import_server2.registerAppTool)(
1733
+ server,
1734
+ "view_task_details",
1735
+ {
1736
+ title: "Task Details",
1737
+ description: "View interactive task details with acceptance criteria, notes, and progress. Opens a rich UI panel.",
1738
+ inputSchema: {
1739
+ taskId: import_zod4.z.string().describe("The task ID to view"),
1740
+ projectId: import_zod4.z.string().describe("The project ID")
1741
+ },
1742
+ _meta: { ui: { resourceUri: RESOURCE_URI } }
1743
+ },
1744
+ async ({ taskId, projectId }) => {
1745
+ try {
1746
+ const task = await apiClient.getTask(taskId);
1747
+ let project = null;
1748
+ try {
1749
+ project = await apiClient.getProject(projectId);
1750
+ } catch {
1751
+ }
1752
+ return {
1753
+ content: [
1754
+ {
1755
+ type: "text",
1756
+ text: `Viewing task: ${task.title}`
1757
+ }
1758
+ ],
1759
+ structuredContent: {
1760
+ task,
1761
+ project
1762
+ }
1763
+ };
1764
+ } catch (error) {
1765
+ const message = error instanceof Error ? error.message : String(error);
1766
+ return {
1767
+ content: [{ type: "text", text: `Error loading task: ${message}` }],
1768
+ isError: true
1769
+ };
1770
+ }
1771
+ }
1772
+ );
1773
+ registerAppHtmlResource(server, {
1774
+ name: "Task Details UI",
1775
+ uri: RESOURCE_URI,
1776
+ description: "Interactive task details view with acceptance criteria and notes",
1777
+ htmlFileName: "task-details.html",
1778
+ fallbackLabel: "Task Details"
1779
+ });
1780
+ }
1781
+
1782
+ // src/apps/kanban.ts
1783
+ var import_server3 = require("@modelcontextprotocol/ext-apps/server");
1784
+ var import_zod5 = require("zod");
1785
+ var RESOURCE_URI2 = "ui://collab/kanban.html";
1786
+ function registerKanbanApp(server, apiClient, _authContext) {
1787
+ (0, import_server3.registerAppTool)(
1788
+ server,
1789
+ "view_kanban_board",
1790
+ {
1791
+ title: "Kanban Board",
1792
+ description: "View interactive drag-and-drop Kanban board for a project. Drag tasks between columns to change their state.",
1793
+ inputSchema: {
1794
+ projectId: import_zod5.z.string().describe("The project ID to display")
1795
+ },
1796
+ _meta: { ui: { resourceUri: RESOURCE_URI2 } }
1797
+ },
1798
+ async ({ projectId }) => {
1799
+ try {
1800
+ const [project, tasks] = await Promise.all([
1801
+ apiClient.getProject(projectId),
1802
+ apiClient.listTasks({ projectId })
1803
+ ]);
1804
+ return {
1805
+ content: [
1806
+ {
1807
+ type: "text",
1808
+ text: `Kanban board for ${project.name} (${tasks.length} tasks)`
1809
+ }
1810
+ ],
1811
+ structuredContent: {
1812
+ project,
1813
+ tasks
1814
+ }
1815
+ };
1816
+ } catch (error) {
1817
+ const message = error instanceof Error ? error.message : String(error);
1818
+ return {
1819
+ content: [{ type: "text", text: `Error loading kanban: ${message}` }],
1820
+ isError: true
1821
+ };
1822
+ }
1823
+ }
1824
+ );
1825
+ registerAppHtmlResource(server, {
1826
+ name: "Kanban Board UI",
1827
+ uri: RESOURCE_URI2,
1828
+ description: "Interactive drag-and-drop Kanban board for task management",
1829
+ htmlFileName: "kanban.html",
1830
+ fallbackLabel: "Kanban"
1831
+ });
1832
+ }
1833
+
1834
+ // src/apps/activity.ts
1835
+ var import_server4 = require("@modelcontextprotocol/ext-apps/server");
1836
+ var import_zod6 = require("zod");
1837
+ var RESOURCE_URI3 = "ui://collab/activity.html";
1838
+ function registerActivityApp(server, apiClient, _authContext) {
1839
+ (0, import_server4.registerAppTool)(
1840
+ server,
1841
+ "view_activity",
1842
+ {
1843
+ title: "User Activity",
1844
+ description: "View who is working on what across the team. Shows IN_PROGRESS and REVIEW tasks per user.",
1845
+ inputSchema: {
1846
+ projectId: import_zod6.z.string().optional().describe("Optional project ID to filter by")
1847
+ },
1848
+ _meta: { ui: { resourceUri: RESOURCE_URI3 } }
1849
+ },
1850
+ async ({ projectId }) => {
1851
+ try {
1852
+ const [inProgressTasks, reviewTasks] = await Promise.all([
1853
+ apiClient.listTasks({
1854
+ projectId,
1855
+ state: TaskState.IN_PROGRESS
1856
+ }),
1857
+ apiClient.listTasks({
1858
+ projectId,
1859
+ state: TaskState.REVIEW
1860
+ })
1861
+ ]);
1862
+ const userMap = /* @__PURE__ */ new Map();
1863
+ for (const task of inProgressTasks) {
1864
+ if (task.assigneeId) {
1865
+ if (!userMap.has(task.assigneeId)) {
1866
+ userMap.set(task.assigneeId, {
1867
+ id: task.assigneeId,
1868
+ name: task.assigneeName || "Unknown",
1869
+ email: task.assigneeEmail || "",
1870
+ activeTasks: [],
1871
+ reviewTasks: []
1872
+ });
1873
+ }
1874
+ userMap.get(task.assigneeId).activeTasks.push(task);
1875
+ }
1876
+ }
1877
+ for (const task of reviewTasks) {
1878
+ if (task.assigneeId) {
1879
+ if (!userMap.has(task.assigneeId)) {
1880
+ userMap.set(task.assigneeId, {
1881
+ id: task.assigneeId,
1882
+ name: task.assigneeName || "Unknown",
1883
+ email: task.assigneeEmail || "",
1884
+ activeTasks: [],
1885
+ reviewTasks: []
1886
+ });
1887
+ }
1888
+ userMap.get(task.assigneeId).reviewTasks.push(task);
1889
+ }
1890
+ }
1891
+ const users = Array.from(userMap.values());
1892
+ return {
1893
+ content: [
1894
+ {
1895
+ type: "text",
1896
+ text: `Activity: ${users.length} users with active work`
1897
+ }
1898
+ ],
1899
+ structuredContent: {
1900
+ users,
1901
+ projectId
1902
+ }
1903
+ };
1904
+ } catch (error) {
1905
+ const message = error instanceof Error ? error.message : String(error);
1906
+ return {
1907
+ content: [
1908
+ { type: "text", text: `Error loading activity: ${message}` }
1909
+ ],
1910
+ isError: true
1911
+ };
1912
+ }
1913
+ }
1914
+ );
1915
+ registerAppHtmlResource(server, {
1916
+ name: "User Activity UI",
1917
+ uri: RESOURCE_URI3,
1918
+ description: "Dashboard showing team member activity and workload",
1919
+ htmlFileName: "activity.html",
1920
+ fallbackLabel: "Activity"
1921
+ });
1922
+ }
1923
+
1924
+ // src/apps/project-overview.ts
1925
+ var import_server5 = require("@modelcontextprotocol/ext-apps/server");
1926
+ var import_zod7 = require("zod");
1927
+ var RESOURCE_URI4 = "ui://collab/project-overview.html";
1928
+ function registerProjectOverviewApp(server, apiClient, _authContext) {
1929
+ (0, import_server5.registerAppTool)(
1930
+ server,
1931
+ "view_project_overview",
1932
+ {
1933
+ title: "Project Overview",
1934
+ description: "View project health dashboard with task metrics, state distribution, and conventions.",
1935
+ inputSchema: {
1936
+ projectId: import_zod7.z.string().describe("The project ID to display")
1937
+ },
1938
+ _meta: { ui: { resourceUri: RESOURCE_URI4 } }
1939
+ },
1940
+ async ({ projectId }) => {
1941
+ try {
1942
+ const [project, context, tasks] = await Promise.all([
1943
+ apiClient.getProject(projectId),
1944
+ apiClient.getProjectContext(projectId).catch(() => null),
1945
+ apiClient.listTasks({ projectId })
1946
+ ]);
1947
+ const activeTasks = tasks.filter((t) => !t.isArchived);
1948
+ const inProgress = activeTasks.filter(
1949
+ (t) => t.state === TaskState.IN_PROGRESS
1950
+ ).length;
1951
+ const done = activeTasks.filter(
1952
+ (t) => t.state === TaskState.DONE
1953
+ ).length;
1954
+ const blocked = activeTasks.filter((t) => t.errorType).length;
1955
+ const tasksByState = {
1956
+ DRAFT: 0,
1957
+ TODO: 0,
1958
+ IN_PROGRESS: 0,
1959
+ REVIEW: 0,
1960
+ DONE: 0
1961
+ };
1962
+ for (const task of activeTasks) {
1963
+ tasksByState[task.state]++;
1964
+ }
1965
+ const tasksByPriority = {
1966
+ LOW: 0,
1967
+ MEDIUM: 0,
1968
+ HIGH: 0,
1969
+ CRITICAL: 0
1970
+ };
1971
+ for (const task of activeTasks) {
1972
+ tasksByPriority[task.priority]++;
1973
+ }
1974
+ const recentCompleted = activeTasks.filter((t) => t.state === TaskState.DONE).sort(
1975
+ (a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
1976
+ ).slice(0, 5);
1977
+ return {
1978
+ content: [
1979
+ {
1980
+ type: "text",
1981
+ text: `Project overview for ${project.name}: ${activeTasks.length} tasks`
1982
+ }
1983
+ ],
1984
+ structuredContent: {
1985
+ project,
1986
+ context,
1987
+ metrics: {
1988
+ totalTasks: activeTasks.length,
1989
+ inProgress,
1990
+ blocked,
1991
+ done
1992
+ },
1993
+ tasksByState,
1994
+ tasksByPriority,
1995
+ recentCompleted
1996
+ }
1997
+ };
1998
+ } catch (error) {
1999
+ const message = error instanceof Error ? error.message : String(error);
2000
+ return {
2001
+ content: [
2002
+ { type: "text", text: `Error loading project overview: ${message}` }
2003
+ ],
2004
+ isError: true
2005
+ };
2006
+ }
2007
+ }
2008
+ );
2009
+ registerAppHtmlResource(server, {
2010
+ name: "Project Overview UI",
2011
+ uri: RESOURCE_URI4,
2012
+ description: "Project health dashboard with metrics and visualizations",
2013
+ htmlFileName: "project-overview.html",
2014
+ fallbackLabel: "Project Overview"
2015
+ });
2016
+ }
2017
+
2018
+ // src/apps/agent-sessions.ts
2019
+ var import_server6 = require("@modelcontextprotocol/ext-apps/server");
2020
+ var import_zod8 = require("zod");
2021
+ var RESOURCE_URI5 = "ui://collab/agent-sessions.html";
2022
+ function registerAgentSessionsApp(server, apiClient, authContext) {
2023
+ (0, import_server6.registerAppTool)(
2024
+ server,
2025
+ "view_agent_sessions",
2026
+ {
2027
+ title: "Agent Sessions",
2028
+ description: "View active AI agent sessions working on tasks. Monitor real-time progress and session status.",
2029
+ inputSchema: {
2030
+ projectId: import_zod8.z.string().optional().describe("Optional project ID to filter by")
2031
+ },
2032
+ _meta: { ui: { resourceUri: RESOURCE_URI5 } }
2033
+ },
2034
+ async ({ projectId }) => {
2035
+ try {
2036
+ const [inProgressTasks, reviewTasks] = await Promise.all([
2037
+ apiClient.listTasks({
2038
+ projectId,
2039
+ state: TaskState.IN_PROGRESS
2040
+ }),
2041
+ apiClient.listTasks({
2042
+ projectId,
2043
+ state: TaskState.REVIEW
2044
+ })
2045
+ ]);
2046
+ const sessions = [];
2047
+ for (const task of inProgressTasks) {
2048
+ if (task.assigneeId) {
2049
+ const totalCriteria = task.acceptanceCriteria?.length || 0;
2050
+ const completedCriteria = task.acceptanceCriteria?.filter((c) => c.completed).length || 0;
2051
+ const progress = totalCriteria > 0 ? Math.round(completedCriteria / totalCriteria * 100) : 0;
2052
+ const latestUpdate = task.progressUpdates?.[task.progressUpdates.length - 1];
2053
+ sessions.push({
2054
+ id: `session-${task.id}`,
2055
+ taskId: task.id,
2056
+ taskTitle: task.title,
2057
+ agentName: task.assigneeName || "Agent",
2058
+ status: "RUNNING",
2059
+ startedAt: task.updatedAt,
2060
+ lastCheckpoint: latestUpdate?.timestamp,
2061
+ currentStep: latestUpdate?.statusMessage,
2062
+ progress
2063
+ });
2064
+ }
2065
+ }
2066
+ for (const task of reviewTasks) {
2067
+ if (task.assigneeId) {
2068
+ sessions.push({
2069
+ id: `session-${task.id}`,
2070
+ taskId: task.id,
2071
+ taskTitle: task.title,
2072
+ agentName: task.assigneeName || "Agent",
2073
+ status: "STOPPED",
2074
+ startedAt: task.updatedAt,
2075
+ progress: 100
2076
+ });
2077
+ }
2078
+ }
2079
+ return {
2080
+ content: [
2081
+ {
2082
+ type: "text",
2083
+ text: `Agent sessions: ${sessions.length} active`
2084
+ }
2085
+ ],
2086
+ structuredContent: {
2087
+ sessions,
2088
+ projectId
2089
+ }
2090
+ };
2091
+ } catch (error) {
2092
+ const message = error instanceof Error ? error.message : String(error);
2093
+ return {
2094
+ content: [
2095
+ { type: "text", text: `Error loading agent sessions: ${message}` }
2096
+ ],
2097
+ isError: true
2098
+ };
2099
+ }
2100
+ }
2101
+ );
2102
+ registerAppHtmlResource(server, {
2103
+ name: "Agent Sessions UI",
2104
+ uri: RESOURCE_URI5,
2105
+ description: "Real-time view of AI agent sessions and their progress",
2106
+ htmlFileName: "agent-sessions.html",
2107
+ fallbackLabel: "Agent Sessions"
2108
+ });
2109
+ }
2110
+
2111
+ // src/apps/index.ts
2112
+ function registerMCPApps(server, apiClient, authContext) {
2113
+ registerTaskDetailsApp(server, apiClient, authContext);
2114
+ registerKanbanApp(server, apiClient, authContext);
2115
+ registerActivityApp(server, apiClient, authContext);
2116
+ registerProjectOverviewApp(server, apiClient, authContext);
2117
+ registerAgentSessionsApp(server, apiClient, authContext);
2118
+ }
2119
+
1339
2120
  // src/index.ts
1340
2121
  var COLLAB_SERVER_INSTRUCTIONS = `Collab - AI-assisted software development task management platform.
1341
2122
 
@@ -1387,7 +2168,7 @@ Review Workflow:
1387
2168
  list_tasks(state=REVIEW) -> get_task -> approve_task OR request_changes
1388
2169
 
1389
2170
  Task Editing:
1390
- update_task (DRAFT/TODO only) -> if was TODO, reverts to DRAFT -> verify_task again
2171
+ update_task (DRAFT/TODO only) -> task stays in current state
1391
2172
 
1392
2173
  Error Recovery:
1393
2174
  report_error -> abandon_task -> list_tasks -> assign_task (retry or pick different task)
@@ -1406,7 +2187,7 @@ GIT OPERATIONS NOTE:
1406
2187
  TASK STATE FLOW:
1407
2188
  DRAFT -> TODO -> IN_PROGRESS -> REVIEW -> DONE
1408
2189
  (verify_task: DRAFT -> TODO)
1409
- (update_task on TODO: reverts to DRAFT)
2190
+ (update_task: DRAFT/TODO only, state unchanged)
1410
2191
  (request_changes: REVIEW -> IN_PROGRESS)
1411
2192
  (abandon_task: IN_PROGRESS -> TODO)
1412
2193
 
@@ -1439,7 +2220,7 @@ function initializeMCPServer(apiClient, authContext) {
1439
2220
  {
1440
2221
  description: "Discover all accessible projects. Use first to find project IDs. Filter by TEAM, PERSONAL, or ALL workspaces.",
1441
2222
  inputSchema: {
1442
- workspaceType: import_zod3.z.enum(["TEAM", "PERSONAL", "ALL"]).optional().describe("Filter by workspace type")
2223
+ workspaceType: import_zod9.z.enum(["TEAM", "PERSONAL", "ALL"]).optional().describe("Filter by workspace type")
1443
2224
  }
1444
2225
  },
1445
2226
  async (args) => {
@@ -1469,10 +2250,10 @@ function initializeMCPServer(apiClient, authContext) {
1469
2250
  {
1470
2251
  description: "Query tasks with filters. Use state=TODO for assignable tasks, state=REVIEW for pending reviews.",
1471
2252
  inputSchema: {
1472
- projectId: import_zod3.z.string().optional().describe("Filter by project ID"),
1473
- state: import_zod3.z.nativeEnum(TaskState).optional().describe("Filter by task state"),
1474
- assigneeId: import_zod3.z.string().optional().describe("Filter by assignee ID"),
1475
- includeArchived: import_zod3.z.boolean().optional().describe("Include archived tasks (default: false)")
2253
+ projectId: import_zod9.z.string().optional().describe("Filter by project ID"),
2254
+ state: import_zod9.z.nativeEnum(TaskState).optional().describe("Filter by task state"),
2255
+ assigneeId: import_zod9.z.string().optional().describe("Filter by assignee ID"),
2256
+ includeArchived: import_zod9.z.boolean().optional().describe("Include archived tasks (default: false)")
1476
2257
  }
1477
2258
  },
1478
2259
  async (args) => {
@@ -1503,7 +2284,7 @@ function initializeMCPServer(apiClient, authContext) {
1503
2284
  {
1504
2285
  description: "Get complete task details with acceptance criteria and notes. Call before assign_task to understand requirements.",
1505
2286
  inputSchema: {
1506
- taskId: import_zod3.z.string().describe("The task ID to retrieve")
2287
+ taskId: import_zod9.z.string().describe("The task ID to retrieve")
1507
2288
  }
1508
2289
  },
1509
2290
  async (args) => {
@@ -1529,9 +2310,9 @@ function initializeMCPServer(apiClient, authContext) {
1529
2310
  {
1530
2311
  description: "Atomically claim a task. Race-safe - fails if already assigned. Task must be TODO. Returns suggested branch name and worktree path for isolated parallel development.",
1531
2312
  inputSchema: {
1532
- projectId: import_zod3.z.string().describe("The project ID"),
1533
- taskId: import_zod3.z.string().describe("The task ID to assign"),
1534
- expectedState: import_zod3.z.nativeEnum(TaskState).optional().describe("Expected task state (default: TODO)")
2313
+ projectId: import_zod9.z.string().describe("The project ID"),
2314
+ taskId: import_zod9.z.string().describe("The task ID to assign"),
2315
+ expectedState: import_zod9.z.nativeEnum(TaskState).optional().describe("Expected task state (default: TODO)")
1535
2316
  }
1536
2317
  },
1537
2318
  async (args) => {
@@ -1565,10 +2346,10 @@ function initializeMCPServer(apiClient, authContext) {
1565
2346
  {
1566
2347
  description: "Report progress and checkpoint work. Call frequently during execution. Marks acceptance criteria complete.",
1567
2348
  inputSchema: {
1568
- taskId: import_zod3.z.string().describe("The task ID to update"),
1569
- statusMessage: import_zod3.z.string().optional().describe("Status message (max 1000 chars)"),
1570
- completedCheckpointIds: import_zod3.z.array(import_zod3.z.string()).optional().describe("Array of completed checkpoint IDs"),
1571
- currentCheckpointIndex: import_zod3.z.number().optional().describe("Current checkpoint index")
2349
+ taskId: import_zod9.z.string().describe("The task ID to update"),
2350
+ statusMessage: import_zod9.z.string().optional().describe("Status message (max 1000 chars)"),
2351
+ completedCheckpointIds: import_zod9.z.array(import_zod9.z.string()).optional().describe("Array of completed checkpoint IDs"),
2352
+ currentCheckpointIndex: import_zod9.z.number().optional().describe("Current checkpoint index")
1572
2353
  }
1573
2354
  },
1574
2355
  async (args) => {
@@ -1602,10 +2383,10 @@ function initializeMCPServer(apiClient, authContext) {
1602
2383
  {
1603
2384
  description: "Prepare task for PR creation. Returns PR suggestions. After creating PR locally, call report_pr to transition to REVIEW. Requires IN_PROGRESS state.",
1604
2385
  inputSchema: {
1605
- projectId: import_zod3.z.string().describe("The project ID"),
1606
- taskId: import_zod3.z.string().describe("The task ID to complete"),
1607
- pullRequestTitle: import_zod3.z.string().optional().describe("PR title (max 300 chars)"),
1608
- pullRequestBody: import_zod3.z.string().optional().describe("PR body/description (max 10000 chars)")
2386
+ projectId: import_zod9.z.string().describe("The project ID"),
2387
+ taskId: import_zod9.z.string().describe("The task ID to complete"),
2388
+ pullRequestTitle: import_zod9.z.string().optional().describe("PR title (max 300 chars)"),
2389
+ pullRequestBody: import_zod9.z.string().optional().describe("PR body/description (max 10000 chars)")
1609
2390
  }
1610
2391
  },
1611
2392
  async (args) => {
@@ -1662,10 +2443,10 @@ function initializeMCPServer(apiClient, authContext) {
1662
2443
  {
1663
2444
  description: "Report unrecoverable errors (BUILD_FAILURE, TEST_FAILURE, CONFLICT, AUTH_ERROR). Consider abandon_task after.",
1664
2445
  inputSchema: {
1665
- taskId: import_zod3.z.string().describe("The task ID"),
1666
- errorType: import_zod3.z.nativeEnum(ErrorType).describe("Error type: BUILD_FAILURE, TEST_FAILURE, CONFLICT, AUTH_ERROR, OTHER"),
1667
- errorMessage: import_zod3.z.string().describe("Error message (max 1000 chars)"),
1668
- context: import_zod3.z.string().optional().describe("Additional context (max 2000 chars)")
2446
+ taskId: import_zod9.z.string().describe("The task ID"),
2447
+ errorType: import_zod9.z.nativeEnum(ErrorType).describe("Error type: BUILD_FAILURE, TEST_FAILURE, CONFLICT, AUTH_ERROR, OTHER"),
2448
+ errorMessage: import_zod9.z.string().describe("Error message (max 1000 chars)"),
2449
+ context: import_zod9.z.string().optional().describe("Additional context (max 2000 chars)")
1669
2450
  }
1670
2451
  },
1671
2452
  async (args) => {
@@ -1700,7 +2481,7 @@ function initializeMCPServer(apiClient, authContext) {
1700
2481
  {
1701
2482
  description: "Load project README, tech stack, and coding conventions. Call after selecting project.",
1702
2483
  inputSchema: {
1703
- projectId: import_zod3.z.string().describe("The project ID")
2484
+ projectId: import_zod9.z.string().describe("The project ID")
1704
2485
  }
1705
2486
  },
1706
2487
  async (args) => {
@@ -1730,8 +2511,8 @@ function initializeMCPServer(apiClient, authContext) {
1730
2511
  {
1731
2512
  description: "Document implementation decisions. Notes persist for future reference and handoff.",
1732
2513
  inputSchema: {
1733
- taskId: import_zod3.z.string().describe("The task ID"),
1734
- content: import_zod3.z.string().describe("Note content (max 500 chars)")
2514
+ taskId: import_zod9.z.string().describe("The task ID"),
2515
+ content: import_zod9.z.string().describe("Note content (max 500 chars)")
1735
2516
  }
1736
2517
  },
1737
2518
  async (args) => {
@@ -1760,9 +2541,9 @@ function initializeMCPServer(apiClient, authContext) {
1760
2541
  {
1761
2542
  description: "Release task assignment and optionally clean up branch. Task returns to TODO. Use after errors.",
1762
2543
  inputSchema: {
1763
- projectId: import_zod3.z.string().describe("The project ID"),
1764
- taskId: import_zod3.z.string().describe("The task ID to abandon"),
1765
- deleteBranch: import_zod3.z.boolean().optional().describe("Whether to delete the associated branch")
2544
+ projectId: import_zod9.z.string().describe("The project ID"),
2545
+ taskId: import_zod9.z.string().describe("The task ID to abandon"),
2546
+ deleteBranch: import_zod9.z.boolean().optional().describe("Whether to delete the associated branch")
1766
2547
  }
1767
2548
  },
1768
2549
  async (args) => {
@@ -1796,9 +2577,9 @@ function initializeMCPServer(apiClient, authContext) {
1796
2577
  {
1797
2578
  description: "Report a branch created by the agent. Call after using git to create and push a branch. Task must be IN_PROGRESS.",
1798
2579
  inputSchema: {
1799
- projectId: import_zod3.z.string().describe("The project ID"),
1800
- taskId: import_zod3.z.string().describe("The task ID"),
1801
- branchName: import_zod3.z.string().describe("Name of the branch created (e.g., feature/TASK-123-fix-login)")
2580
+ projectId: import_zod9.z.string().describe("The project ID"),
2581
+ taskId: import_zod9.z.string().describe("The task ID"),
2582
+ branchName: import_zod9.z.string().describe("Name of the branch created (e.g., feature/TASK-123-fix-login)")
1802
2583
  }
1803
2584
  },
1804
2585
  async (args) => {
@@ -1832,10 +2613,10 @@ function initializeMCPServer(apiClient, authContext) {
1832
2613
  {
1833
2614
  description: "Report a PR created by the agent. Call after using gh pr create. Transitions task to REVIEW state.",
1834
2615
  inputSchema: {
1835
- projectId: import_zod3.z.string().describe("The project ID"),
1836
- taskId: import_zod3.z.string().describe("The task ID"),
1837
- pullRequestUrl: import_zod3.z.string().describe("Full URL of the created PR (e.g., https://github.com/owner/repo/pull/123)"),
1838
- pullRequestNumber: import_zod3.z.number().describe("PR number (e.g., 123)")
2616
+ projectId: import_zod9.z.string().describe("The project ID"),
2617
+ taskId: import_zod9.z.string().describe("The task ID"),
2618
+ pullRequestUrl: import_zod9.z.string().describe("Full URL of the created PR (e.g., https://github.com/owner/repo/pull/123)"),
2619
+ pullRequestNumber: import_zod9.z.number().describe("PR number (e.g., 123)")
1839
2620
  }
1840
2621
  },
1841
2622
  async (args) => {
@@ -1870,8 +2651,8 @@ function initializeMCPServer(apiClient, authContext) {
1870
2651
  {
1871
2652
  description: "Soft-delete a task. Hidden but restorable via unarchive_task.",
1872
2653
  inputSchema: {
1873
- projectId: import_zod3.z.string().describe("The project ID"),
1874
- taskId: import_zod3.z.string().describe("The task ID to archive")
2654
+ projectId: import_zod9.z.string().describe("The project ID"),
2655
+ taskId: import_zod9.z.string().describe("The task ID to archive")
1875
2656
  }
1876
2657
  },
1877
2658
  async (args) => {
@@ -1904,8 +2685,8 @@ function initializeMCPServer(apiClient, authContext) {
1904
2685
  {
1905
2686
  description: "Restore previously archived task to original state.",
1906
2687
  inputSchema: {
1907
- projectId: import_zod3.z.string().describe("The project ID"),
1908
- taskId: import_zod3.z.string().describe("The task ID to restore")
2688
+ projectId: import_zod9.z.string().describe("The project ID"),
2689
+ taskId: import_zod9.z.string().describe("The task ID to restore")
1909
2690
  }
1910
2691
  },
1911
2692
  async (args) => {
@@ -1938,9 +2719,9 @@ function initializeMCPServer(apiClient, authContext) {
1938
2719
  {
1939
2720
  description: "Create new project in personal workspace linked to GitHub repository.",
1940
2721
  inputSchema: {
1941
- name: import_zod3.z.string().describe("Project name (max 100 chars)"),
1942
- description: import_zod3.z.string().optional().describe("Project description (max 500 chars)"),
1943
- repositoryUrl: import_zod3.z.string().describe("GitHub repository URL")
2722
+ name: import_zod9.z.string().describe("Project name (max 100 chars)"),
2723
+ description: import_zod9.z.string().optional().describe("Project description (max 500 chars)"),
2724
+ repositoryUrl: import_zod9.z.string().describe("GitHub repository URL")
1944
2725
  }
1945
2726
  },
1946
2727
  async (args) => {
@@ -1974,14 +2755,14 @@ function initializeMCPServer(apiClient, authContext) {
1974
2755
  {
1975
2756
  description: "Create task with title, description, acceptance criteria. Starts in DRAFT. Priority: LOW/MEDIUM/HIGH/CRITICAL.",
1976
2757
  inputSchema: {
1977
- projectId: import_zod3.z.string().describe("The project ID to create the task in"),
1978
- epicId: import_zod3.z.string().nullable().optional().describe("Optional epic ID to associate the task with"),
1979
- title: import_zod3.z.string().describe("Task title (max 200 chars)"),
1980
- description: import_zod3.z.string().describe("Task description (max 5000 chars)"),
1981
- priority: import_zod3.z.nativeEnum(TaskPriority).optional().describe("Task priority: LOW, MEDIUM, HIGH, CRITICAL (default: MEDIUM)"),
1982
- acceptanceCriteria: import_zod3.z.array(
1983
- import_zod3.z.object({
1984
- description: import_zod3.z.string().describe("Acceptance criterion description (max 500 chars)")
2758
+ projectId: import_zod9.z.string().describe("The project ID to create the task in"),
2759
+ epicId: import_zod9.z.string().nullable().optional().describe("Optional epic ID to associate the task with"),
2760
+ title: import_zod9.z.string().describe("Task title (max 200 chars)"),
2761
+ description: import_zod9.z.string().describe("Task description (max 5000 chars)"),
2762
+ priority: import_zod9.z.nativeEnum(TaskPriority).optional().describe("Task priority: LOW, MEDIUM, HIGH, CRITICAL (default: MEDIUM)"),
2763
+ acceptanceCriteria: import_zod9.z.array(
2764
+ import_zod9.z.object({
2765
+ description: import_zod9.z.string().describe("Acceptance criterion description (max 500 chars)")
1985
2766
  })
1986
2767
  ).describe("Array of acceptance criteria (at least 1 required)")
1987
2768
  }
@@ -2020,10 +2801,10 @@ function initializeMCPServer(apiClient, authContext) {
2020
2801
  {
2021
2802
  description: "Return task from REVIEW to IN_PROGRESS with feedback. Original assignee addresses changes.",
2022
2803
  inputSchema: {
2023
- projectId: import_zod3.z.string().describe("The project ID"),
2024
- taskId: import_zod3.z.string().describe("The task ID to review"),
2025
- reviewComments: import_zod3.z.string().describe("Review comments explaining requested changes (max 5000 chars)"),
2026
- requestedChanges: import_zod3.z.array(import_zod3.z.string()).optional().describe("List of specific changes requested")
2804
+ projectId: import_zod9.z.string().describe("The project ID"),
2805
+ taskId: import_zod9.z.string().describe("The task ID to review"),
2806
+ reviewComments: import_zod9.z.string().describe("Review comments explaining requested changes (max 5000 chars)"),
2807
+ requestedChanges: import_zod9.z.array(import_zod9.z.string()).optional().describe("List of specific changes requested")
2027
2808
  }
2028
2809
  },
2029
2810
  async (args) => {
@@ -2058,9 +2839,9 @@ function initializeMCPServer(apiClient, authContext) {
2058
2839
  {
2059
2840
  description: "Approve completed work and mark DONE. Only for REVIEW state tasks.",
2060
2841
  inputSchema: {
2061
- projectId: import_zod3.z.string().describe("The project ID"),
2062
- taskId: import_zod3.z.string().describe("The task ID to approve"),
2063
- reviewComments: import_zod3.z.string().optional().describe("Optional approval comments (max 2000 chars)")
2842
+ projectId: import_zod9.z.string().describe("The project ID"),
2843
+ taskId: import_zod9.z.string().describe("The task ID to approve"),
2844
+ reviewComments: import_zod9.z.string().optional().describe("Optional approval comments (max 2000 chars)")
2064
2845
  }
2065
2846
  },
2066
2847
  async (args) => {
@@ -2094,10 +2875,10 @@ function initializeMCPServer(apiClient, authContext) {
2094
2875
  {
2095
2876
  description: "Verify a DRAFT task and move it to TODO state. Requires task to pass programmatic validation (title 10+ chars, description 50+ chars, each criterion 20+ chars). If approved=false, stores feedback with NEEDS_REVISION status.",
2096
2877
  inputSchema: {
2097
- projectId: import_zod3.z.string().describe("The project ID"),
2098
- taskId: import_zod3.z.string().describe("The task ID to verify"),
2099
- approved: import_zod3.z.boolean().describe("Whether to approve the task"),
2100
- feedback: import_zod3.z.string().optional().describe("Feedback for the task (required if not approved)")
2878
+ projectId: import_zod9.z.string().describe("The project ID"),
2879
+ taskId: import_zod9.z.string().describe("The task ID to verify"),
2880
+ approved: import_zod9.z.boolean().describe("Whether to approve the task"),
2881
+ feedback: import_zod9.z.string().optional().describe("Feedback for the task (required if not approved)")
2101
2882
  }
2102
2883
  },
2103
2884
  async (args) => {
@@ -2128,8 +2909,8 @@ function initializeMCPServer(apiClient, authContext) {
2128
2909
  {
2129
2910
  description: "Get state-appropriate prompt for a task. Returns verify prompt for DRAFT, assignment prompt for TODO, or continue prompt for IN_PROGRESS tasks.",
2130
2911
  inputSchema: {
2131
- projectId: import_zod3.z.string().describe("The project ID"),
2132
- taskId: import_zod3.z.string().describe("The task ID")
2912
+ projectId: import_zod9.z.string().describe("The project ID"),
2913
+ taskId: import_zod9.z.string().describe("The task ID")
2133
2914
  }
2134
2915
  },
2135
2916
  async (args) => {
@@ -2160,17 +2941,17 @@ function initializeMCPServer(apiClient, authContext) {
2160
2941
  server.registerTool(
2161
2942
  "update_task",
2162
2943
  {
2163
- description: "Update task details (title, description, priority, acceptanceCriteria). Only works for DRAFT and TODO states. If task is in TODO state, it reverts to DRAFT and requires re-verification.",
2944
+ description: "Update task details (title, description, priority, acceptanceCriteria). Only works for DRAFT and TODO states. Task stays in its current state.",
2164
2945
  inputSchema: {
2165
- projectId: import_zod3.z.string().describe("The project ID"),
2166
- taskId: import_zod3.z.string().describe("The task ID to update"),
2167
- title: import_zod3.z.string().optional().describe("New task title"),
2168
- description: import_zod3.z.string().optional().describe("New task description"),
2169
- priority: import_zod3.z.nativeEnum(TaskPriority).optional().describe("New task priority"),
2170
- acceptanceCriteria: import_zod3.z.array(
2171
- import_zod3.z.object({
2172
- id: import_zod3.z.string().optional().describe("Existing criterion ID (for updates)"),
2173
- description: import_zod3.z.string().describe("Criterion description")
2946
+ projectId: import_zod9.z.string().describe("The project ID"),
2947
+ taskId: import_zod9.z.string().describe("The task ID to update"),
2948
+ title: import_zod9.z.string().optional().describe("New task title"),
2949
+ description: import_zod9.z.string().optional().describe("New task description"),
2950
+ priority: import_zod9.z.nativeEnum(TaskPriority).optional().describe("New task priority"),
2951
+ acceptanceCriteria: import_zod9.z.array(
2952
+ import_zod9.z.object({
2953
+ id: import_zod9.z.string().optional().describe("Existing criterion ID (for updates)"),
2954
+ description: import_zod9.z.string().describe("Criterion description")
2174
2955
  })
2175
2956
  ).optional().describe("New acceptance criteria (replaces existing)")
2176
2957
  }
@@ -2226,6 +3007,7 @@ function initializeMCPServer(apiClient, authContext) {
2226
3007
  };
2227
3008
  }
2228
3009
  );
3010
+ registerMCPApps(server, apiClient, authContext);
2229
3011
  return server;
2230
3012
  }
2231
3013
  async function connectMCPServer(server, transport) {
@@ -2278,30 +3060,30 @@ function handleApiError(error) {
2278
3060
  isError: true
2279
3061
  };
2280
3062
  }
2281
- var ActiveTaskSchema = import_zod3.z.object({
2282
- taskId: import_zod3.z.string().min(1),
2283
- projectId: import_zod3.z.string().min(1),
2284
- branchName: import_zod3.z.string().optional(),
2285
- worktreePath: import_zod3.z.string().optional(),
2286
- startedAt: import_zod3.z.string().optional()
3063
+ var ActiveTaskSchema = import_zod9.z.object({
3064
+ taskId: import_zod9.z.string().min(1),
3065
+ projectId: import_zod9.z.string().min(1),
3066
+ branchName: import_zod9.z.string().optional(),
3067
+ worktreePath: import_zod9.z.string().optional(),
3068
+ startedAt: import_zod9.z.string().optional()
2287
3069
  });
2288
3070
  async function checkActiveTask() {
2289
- const fs = await import("fs");
2290
- const path = await import("path");
3071
+ const fs2 = await import("fs");
3072
+ const path2 = await import("path");
2291
3073
  const cwd = process.cwd();
2292
- const collabDir = path.join(cwd, ".collab");
2293
- const activeTaskPath = path.join(collabDir, "active-task.json");
3074
+ const collabDir = path2.join(cwd, ".collab");
3075
+ const activeTaskPath = path2.join(collabDir, "active-task.json");
2294
3076
  try {
2295
- const resolvedPath = path.resolve(activeTaskPath);
2296
- const resolvedCollabDir = path.resolve(collabDir);
2297
- if (!resolvedPath.startsWith(resolvedCollabDir + path.sep) && resolvedPath !== resolvedCollabDir) {
3077
+ const resolvedPath = path2.resolve(activeTaskPath);
3078
+ const resolvedCollabDir = path2.resolve(collabDir);
3079
+ if (!resolvedPath.startsWith(resolvedCollabDir + path2.sep) && resolvedPath !== resolvedCollabDir) {
2298
3080
  return {
2299
3081
  hasActiveTask: false,
2300
3082
  task: null,
2301
3083
  error: "Invalid active task path"
2302
3084
  };
2303
3085
  }
2304
- const stats = await fs.promises.lstat(activeTaskPath);
3086
+ const stats = await fs2.promises.lstat(activeTaskPath);
2305
3087
  if (stats.isSymbolicLink()) {
2306
3088
  return {
2307
3089
  hasActiveTask: false,
@@ -2315,7 +3097,7 @@ async function checkActiveTask() {
2315
3097
  task: null
2316
3098
  };
2317
3099
  }
2318
- const content = await fs.promises.readFile(activeTaskPath, "utf-8");
3100
+ const content = await fs2.promises.readFile(activeTaskPath, "utf-8");
2319
3101
  let parsed;
2320
3102
  try {
2321
3103
  parsed = JSON.parse(content);
@@ -2381,7 +3163,7 @@ Example mcp.json configuration:
2381
3163
  "mcpServers": {
2382
3164
  "collab": {
2383
3165
  "command": "npx",
2384
- "args": ["@mtaap/mcp"],
3166
+ "args": ["-p", "@mtaap/mcp", "collab-mcp"],
2385
3167
  "env": {
2386
3168
  "COLLAB_API_KEY": "collab_your_api_key_here",
2387
3169
  "COLLAB_BASE_URL": "https://collab.mtaap.de"
@@ -2416,7 +3198,7 @@ function validateEnvironment() {
2416
3198
  "mcpServers": {
2417
3199
  "collab": {
2418
3200
  "command": "npx",
2419
- "args": ["@mtaap/mcp"],
3201
+ "args": ["-p", "@mtaap/mcp", "collab-mcp"],
2420
3202
  "env": {
2421
3203
  "COLLAB_API_KEY": "collab_your_api_key_here",
2422
3204
  "COLLAB_BASE_URL": "https://collab.mtaap.de"