@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/index.js CHANGED
@@ -44,15 +44,18 @@ var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
44
44
  // package.json
45
45
  var package_default = {
46
46
  name: "@mtaap/mcp",
47
- version: "0.2.12",
47
+ version: "0.5.1",
48
48
  description: "Model Context Protocol (MCP) server for AI agents to interact with Collab - the multi-tenant collaborative agent development platform",
49
49
  mcpName: "collab",
50
50
  scripts: {
51
- build: "tsup"
51
+ build: "pnpm build:ui && tsup",
52
+ "build:ui": "node scripts/build-ui.mjs",
53
+ "dev:ui": "vite build --watch"
52
54
  },
53
55
  main: "./dist/index.js",
54
56
  types: "./dist/index.d.ts",
55
57
  bin: {
58
+ mcp: "./dist/cli.js",
56
59
  "collab-mcp": "./dist/cli.js",
57
60
  "collab-mcp-server": "./dist/server.js"
58
61
  },
@@ -85,6 +88,7 @@ var package_default = {
85
88
  },
86
89
  dependencies: {
87
90
  "@modelcontextprotocol/sdk": "^1.0.0",
91
+ "@modelcontextprotocol/ext-apps": "^1.0.1",
88
92
  express: "^5.0.1",
89
93
  zod: "^4.3.5"
90
94
  },
@@ -93,8 +97,18 @@ var package_default = {
93
97
  "@mtaap/core": "workspace:*",
94
98
  "@types/express": "^5.0.0",
95
99
  "@types/node": "^22.0.0",
100
+ "@types/react": "^19.0.0",
101
+ "@types/react-dom": "^19.0.0",
102
+ "@vitejs/plugin-react": "^4.4.0",
103
+ autoprefixer: "^10.4.21",
104
+ postcss: "^8.5.3",
105
+ react: "^19.0.0",
106
+ "react-dom": "^19.0.0",
107
+ tailwindcss: "^3.4.17",
96
108
  tsup: "^8.5.1",
97
- typescript: "^5.4.0"
109
+ typescript: "^5.4.0",
110
+ vite: "^6.3.2",
111
+ "vite-plugin-singlefile": "^2.0.3"
98
112
  }
99
113
  };
100
114
 
@@ -102,7 +116,7 @@ var package_default = {
102
116
  var VERSION = package_default.version;
103
117
 
104
118
  // src/index.ts
105
- var import_zod3 = require("zod");
119
+ var import_zod9 = require("zod");
106
120
 
107
121
  // ../../packages/core/dist/constants/enums.js
108
122
  var TaskState;
@@ -188,13 +202,11 @@ var WebSocketEventType;
188
202
  WebSocketEventType2["TASK_UPDATED"] = "task.updated";
189
203
  WebSocketEventType2["TASK_DELETED"] = "task.deleted";
190
204
  WebSocketEventType2["MEMBER_JOINED"] = "member.joined";
205
+ WebSocketEventType2["AGENT_STARTED"] = "agent.started";
206
+ WebSocketEventType2["AGENT_OUTPUT"] = "agent.output";
207
+ WebSocketEventType2["AGENT_STOPPED"] = "agent.stopped";
208
+ WebSocketEventType2["AGENT_ERROR"] = "agent.error";
191
209
  })(WebSocketEventType || (WebSocketEventType = {}));
192
- var AuthProvider;
193
- (function(AuthProvider2) {
194
- AuthProvider2["CREDENTIALS"] = "credentials";
195
- AuthProvider2["LDAP"] = "ldap";
196
- AuthProvider2["SSO"] = "sso";
197
- })(AuthProvider || (AuthProvider = {}));
198
210
  var SubscriptionStatus;
199
211
  (function(SubscriptionStatus2) {
200
212
  SubscriptionStatus2["ACTIVE"] = "ACTIVE";
@@ -210,6 +222,37 @@ var EventType;
210
222
  EventType2["ACCESS"] = "ACCESS";
211
223
  EventType2["MODIFICATION"] = "MODIFICATION";
212
224
  })(EventType || (EventType = {}));
225
+ var CreatedVia;
226
+ (function(CreatedVia2) {
227
+ CreatedVia2["UI"] = "UI";
228
+ CreatedVia2["API_KEY"] = "API_KEY";
229
+ CreatedVia2["OAUTH"] = "OAUTH";
230
+ })(CreatedVia || (CreatedVia = {}));
231
+ var AgentModel;
232
+ (function(AgentModel2) {
233
+ AgentModel2["OPUS"] = "OPUS";
234
+ AgentModel2["SONNET"] = "SONNET";
235
+ AgentModel2["HAIKU"] = "HAIKU";
236
+ })(AgentModel || (AgentModel = {}));
237
+ var AgentModelMode;
238
+ (function(AgentModelMode2) {
239
+ AgentModelMode2["DEFAULT"] = "DEFAULT";
240
+ AgentModelMode2["PRESET"] = "PRESET";
241
+ AgentModelMode2["CUSTOM"] = "CUSTOM";
242
+ })(AgentModelMode || (AgentModelMode = {}));
243
+ var AgentCLIType;
244
+ (function(AgentCLIType2) {
245
+ AgentCLIType2["CLAUDE_CODE"] = "CLAUDE_CODE";
246
+ AgentCLIType2["OPENCODE"] = "OPENCODE";
247
+ })(AgentCLIType || (AgentCLIType = {}));
248
+ var AgentSessionStatus;
249
+ (function(AgentSessionStatus2) {
250
+ AgentSessionStatus2["STARTING"] = "STARTING";
251
+ AgentSessionStatus2["RUNNING"] = "RUNNING";
252
+ AgentSessionStatus2["STOPPING"] = "STOPPING";
253
+ AgentSessionStatus2["STOPPED"] = "STOPPED";
254
+ AgentSessionStatus2["ERROR"] = "ERROR";
255
+ })(AgentSessionStatus || (AgentSessionStatus = {}));
213
256
 
214
257
  // ../../packages/core/dist/constants/state-machine.js
215
258
  var VALID_TRANSITIONS = {
@@ -233,6 +276,62 @@ var VALID_TRANSITIONS = {
233
276
  [TaskState.DONE]: []
234
277
  };
235
278
 
279
+ // ../../packages/core/dist/constants/oauth.js
280
+ var OAuthScopes = {
281
+ /** Read-only access to MCP resources */
282
+ READ: "mcp:read",
283
+ /** Read and write access to MCP resources */
284
+ WRITE: "mcp:write",
285
+ /** Full administrative access */
286
+ ADMIN: "mcp:admin"
287
+ };
288
+ var VALID_OAUTH_SCOPES = [
289
+ OAuthScopes.READ,
290
+ OAuthScopes.WRITE,
291
+ OAuthScopes.ADMIN
292
+ ];
293
+ var DEFAULT_OAUTH_SCOPES = `${OAuthScopes.READ} ${OAuthScopes.WRITE}`;
294
+ var OAUTH_SCOPE_TO_PERMISSION = {
295
+ [OAuthScopes.READ]: ApiKeyPermission.READ,
296
+ [OAuthScopes.WRITE]: ApiKeyPermission.WRITE,
297
+ [OAuthScopes.ADMIN]: ApiKeyPermission.ADMIN
298
+ };
299
+ var PERMISSION_TO_OAUTH_SCOPE = {
300
+ [ApiKeyPermission.READ]: OAuthScopes.READ,
301
+ [ApiKeyPermission.WRITE]: OAuthScopes.WRITE,
302
+ [ApiKeyPermission.ADMIN]: OAuthScopes.ADMIN
303
+ };
304
+ var OAuthTokenLifetimes = {
305
+ /** Access token lifetime: 1 hour */
306
+ ACCESS_TOKEN_MS: 60 * 60 * 1e3,
307
+ /** Refresh token lifetime: 30 days */
308
+ REFRESH_TOKEN_MS: 30 * 24 * 60 * 60 * 1e3,
309
+ /** Authorization code lifetime: 10 minutes */
310
+ AUTHORIZATION_CODE_MS: 10 * 60 * 1e3
311
+ };
312
+ var OAuthGrantTypes = {
313
+ AUTHORIZATION_CODE: "authorization_code",
314
+ REFRESH_TOKEN: "refresh_token"
315
+ };
316
+ var SUPPORTED_GRANT_TYPES = [
317
+ OAuthGrantTypes.AUTHORIZATION_CODE,
318
+ OAuthGrantTypes.REFRESH_TOKEN
319
+ ];
320
+ var OAuthResponseTypes = {
321
+ CODE: "code"
322
+ };
323
+ var OAuthCodeChallengeMethods = {
324
+ S256: "S256"
325
+ };
326
+ var OAuthRateLimits = {
327
+ /** /oauth/token: 30 requests per minute per client */
328
+ TOKEN_ENDPOINT: { limit: 30, windowMs: 60 * 1e3 },
329
+ /** /oauth/authorize: 10 requests per minute per user */
330
+ AUTHORIZE_ENDPOINT: { limit: 10, windowMs: 60 * 1e3 },
331
+ /** /oauth/register: 5 requests per minute per IP */
332
+ REGISTER_ENDPOINT: { limit: 5, windowMs: 60 * 1e3 }
333
+ };
334
+
236
335
  // ../../packages/core/dist/config/deployment.js
237
336
  var config = {
238
337
  deploymentMode: process.env.DEPLOYMENT_MODE || "saas"
@@ -240,20 +339,24 @@ var config = {
240
339
  var isSaas = config.deploymentMode === "saas";
241
340
  var isOnPrem = config.deploymentMode === "onprem";
242
341
 
243
- // ../../packages/core/dist/version.js
244
- var VERSION2 = "0.1.0";
342
+ // ../../packages/core/dist/versions.js
343
+ var VERSIONS = {
344
+ core: "0.4.0",
345
+ web: "0.4.0",
346
+ mcp: "0.5.0"
347
+ };
348
+ var VERSION2 = VERSIONS.core;
245
349
 
246
350
  // ../../packages/core/dist/config/index.js
247
351
  var DEPLOYMENT_MODE = process.env.DEPLOYMENT_MODE || "saas";
248
352
  var config2 = {
249
353
  version: VERSION2,
354
+ packages: VERSIONS,
250
355
  deploymentMode: DEPLOYMENT_MODE,
251
356
  billing: {
252
357
  enabled: DEPLOYMENT_MODE === "saas",
253
358
  revenuecat: {
254
- publicKey: process.env.REVENUECAT_PUBLIC_API_KEY,
255
- stripeKey: process.env.STRIPE_SECRET_KEY
256
- // Required by RevenueCat Web Billing
359
+ publicKey: process.env.NEXT_PUBLIC_REVENUECAT_PUBLIC_KEY
257
360
  }
258
361
  },
259
362
  licensing: {
@@ -321,6 +424,18 @@ var config2 = {
321
424
  requestsPerHour: 1e3
322
425
  }
323
426
  },
427
+ agent: {
428
+ defaultModel: "SONNET",
429
+ sessionTimeoutMs: 30 * 60 * 1e3,
430
+ // 30 minutes
431
+ maxSessionDurationMs: 4 * 60 * 60 * 1e3,
432
+ // 4 hours
433
+ maxConcurrentSessions: {
434
+ FREE: 1,
435
+ PRO: 5,
436
+ ENTERPRISE: -1
437
+ }
438
+ },
324
439
  limits: {
325
440
  projectNameMaxLength: 100,
326
441
  taskDescriptionMaxLength: 5e3,
@@ -359,7 +474,6 @@ var OrganizationIdSchema = import_zod.z.string().regex(/^org_[a-zA-Z0-9]+$/);
359
474
  var OrganizationSchema = import_zod.z.object({
360
475
  id: OrganizationIdSchema,
361
476
  name: import_zod.z.string().min(1).max(255),
362
- slug: import_zod.z.string().min(1).max(100).regex(/^[a-z0-9-]+$/),
363
477
  logoUrl: import_zod.z.string().url().nullable(),
364
478
  accentColor: import_zod.z.string().regex(/^#[0-9A-Fa-f]{6}$/).nullable(),
365
479
  tenantName: import_zod.z.string().nullable(),
@@ -487,239 +601,376 @@ var ProjectCollaboratorSchema = import_zod.z.object({
487
601
  });
488
602
 
489
603
  // ../../packages/core/dist/validation/index.js
604
+ var import_zod3 = require("zod");
605
+
606
+ // ../../packages/core/dist/validation/oauth.js
490
607
  var import_zod2 = require("zod");
491
- var ListProjectsInputSchema = import_zod2.z.object({
492
- workspaceType: import_zod2.z.preprocess((val) => typeof val === "string" ? val.toUpperCase() : val, import_zod2.z.enum(["TEAM", "PERSONAL", "ALL"]).optional())
493
- });
494
- var ListTasksInputSchema = import_zod2.z.object({
495
- projectId: import_zod2.z.string().optional(),
496
- state: import_zod2.z.nativeEnum(TaskState).optional(),
497
- assigneeId: import_zod2.z.string().optional(),
498
- includeArchived: import_zod2.z.boolean().optional()
499
- });
500
- var cuidOrPrefixedId = import_zod2.z.string().regex(/^([a-z0-9]+|[a-z]+_[a-zA-Z0-9]+)$/);
501
- 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");
502
- var GetTaskInputSchema = import_zod2.z.object({
608
+ var scopeString = import_zod2.z.string().optional().transform((val) => {
609
+ if (!val)
610
+ return void 0;
611
+ const scopes = val.split(" ").filter(Boolean);
612
+ const validScopes = scopes.filter((s) => VALID_OAUTH_SCOPES.includes(s));
613
+ return validScopes.length > 0 ? validScopes.join(" ") : void 0;
614
+ });
615
+ var redirectUri = import_zod2.z.string().url().refine((uri) => {
616
+ const url = new URL(uri);
617
+ return url.protocol === "https:" || url.hostname === "localhost" || url.hostname === "127.0.0.1";
618
+ }, { message: "redirect_uri must use HTTPS or be localhost" });
619
+ var codeVerifier = import_zod2.z.string().min(43).max(128).regex(/^[A-Za-z0-9._~-]+$/, "code_verifier must only contain unreserved characters");
620
+ var codeChallenge = import_zod2.z.string().min(43).max(128).regex(/^[A-Za-z0-9_-]+$/, "code_challenge must be base64url encoded (no padding)");
621
+ var DynamicClientRegistrationSchema = import_zod2.z.object({
622
+ redirect_uris: import_zod2.z.array(redirectUri).min(1),
623
+ client_name: import_zod2.z.string().min(1).max(255),
624
+ client_uri: import_zod2.z.string().url().optional(),
625
+ logo_uri: import_zod2.z.string().url().optional(),
626
+ // Accept lowercase OAuth spec values
627
+ grant_types: import_zod2.z.array(import_zod2.z.enum(["authorization_code", "refresh_token"])).default(["authorization_code", "refresh_token"]),
628
+ response_types: import_zod2.z.array(import_zod2.z.enum([OAuthResponseTypes.CODE])).default([OAuthResponseTypes.CODE]),
629
+ scope: scopeString,
630
+ // Accept lowercase OAuth spec values
631
+ token_endpoint_auth_method: import_zod2.z.enum(["none", "client_secret_post", "client_secret_basic"]).default("none")
632
+ });
633
+ var DynamicClientRegistrationResponseSchema = import_zod2.z.object({
634
+ client_id: import_zod2.z.string(),
635
+ client_secret: import_zod2.z.string().optional(),
636
+ client_id_issued_at: import_zod2.z.number(),
637
+ client_secret_expires_at: import_zod2.z.number().optional(),
638
+ redirect_uris: import_zod2.z.array(import_zod2.z.string()),
639
+ client_name: import_zod2.z.string(),
640
+ client_uri: import_zod2.z.string().optional(),
641
+ logo_uri: import_zod2.z.string().optional(),
642
+ grant_types: import_zod2.z.array(import_zod2.z.string()),
643
+ response_types: import_zod2.z.array(import_zod2.z.string()),
644
+ scope: import_zod2.z.string(),
645
+ token_endpoint_auth_method: import_zod2.z.string(),
646
+ registration_access_token: import_zod2.z.string().optional(),
647
+ registration_client_uri: import_zod2.z.string().optional()
648
+ });
649
+ var AuthorizationRequestSchema = import_zod2.z.object({
650
+ response_type: import_zod2.z.literal(OAuthResponseTypes.CODE),
651
+ client_id: import_zod2.z.string().min(1),
652
+ redirect_uri: redirectUri,
653
+ scope: scopeString,
654
+ state: import_zod2.z.string().max(255).optional(),
655
+ // PKCE is mandatory in OAuth 2.1
656
+ code_challenge: codeChallenge,
657
+ code_challenge_method: import_zod2.z.literal(OAuthCodeChallengeMethods.S256)
658
+ });
659
+ var TokenRequestAuthorizationCodeSchema = import_zod2.z.object({
660
+ grant_type: import_zod2.z.literal(OAuthGrantTypes.AUTHORIZATION_CODE),
661
+ code: import_zod2.z.string().min(1),
662
+ redirect_uri: redirectUri,
663
+ client_id: import_zod2.z.string().min(1),
664
+ // PKCE code verifier is mandatory
665
+ code_verifier: codeVerifier,
666
+ // Client secret is optional (for confidential clients)
667
+ client_secret: import_zod2.z.string().optional()
668
+ });
669
+ var TokenRequestRefreshTokenSchema = import_zod2.z.object({
670
+ grant_type: import_zod2.z.literal(OAuthGrantTypes.REFRESH_TOKEN),
671
+ refresh_token: import_zod2.z.string().min(1),
672
+ client_id: import_zod2.z.string().min(1),
673
+ // Optional: request reduced scope
674
+ scope: scopeString,
675
+ // Client secret is optional (for confidential clients)
676
+ client_secret: import_zod2.z.string().optional()
677
+ });
678
+ var TokenRequestSchema = import_zod2.z.discriminatedUnion("grant_type", [
679
+ TokenRequestAuthorizationCodeSchema,
680
+ TokenRequestRefreshTokenSchema
681
+ ]);
682
+ var TokenResponseSchema = import_zod2.z.object({
683
+ access_token: import_zod2.z.string(),
684
+ token_type: import_zod2.z.literal("Bearer"),
685
+ expires_in: import_zod2.z.number(),
686
+ refresh_token: import_zod2.z.string().optional(),
687
+ scope: import_zod2.z.string()
688
+ });
689
+ var TokenRevocationRequestSchema = import_zod2.z.object({
690
+ token: import_zod2.z.string().min(1),
691
+ token_type_hint: import_zod2.z.enum(["access_token", "refresh_token"]).optional(),
692
+ client_id: import_zod2.z.string().min(1),
693
+ client_secret: import_zod2.z.string().optional()
694
+ });
695
+ var OAuthErrorResponseSchema = import_zod2.z.object({
696
+ error: import_zod2.z.string(),
697
+ error_description: import_zod2.z.string().optional(),
698
+ error_uri: import_zod2.z.string().url().optional(),
699
+ state: import_zod2.z.string().optional()
700
+ });
701
+ var AuthorizationServerMetadataSchema = import_zod2.z.object({
702
+ issuer: import_zod2.z.string().url(),
703
+ authorization_endpoint: import_zod2.z.string().url(),
704
+ token_endpoint: import_zod2.z.string().url(),
705
+ registration_endpoint: import_zod2.z.string().url().optional(),
706
+ revocation_endpoint: import_zod2.z.string().url().optional(),
707
+ scopes_supported: import_zod2.z.array(import_zod2.z.string()),
708
+ response_types_supported: import_zod2.z.array(import_zod2.z.string()),
709
+ grant_types_supported: import_zod2.z.array(import_zod2.z.string()),
710
+ token_endpoint_auth_methods_supported: import_zod2.z.array(import_zod2.z.string()),
711
+ code_challenge_methods_supported: import_zod2.z.array(import_zod2.z.string()),
712
+ service_documentation: import_zod2.z.string().url().optional()
713
+ });
714
+ var ProtectedResourceMetadataSchema = import_zod2.z.object({
715
+ resource: import_zod2.z.string().url(),
716
+ authorization_servers: import_zod2.z.array(import_zod2.z.string().url()),
717
+ scopes_supported: import_zod2.z.array(import_zod2.z.string()).optional(),
718
+ bearer_methods_supported: import_zod2.z.array(import_zod2.z.string()).optional(),
719
+ resource_signing_alg_values_supported: import_zod2.z.array(import_zod2.z.string()).optional(),
720
+ resource_documentation: import_zod2.z.string().url().optional()
721
+ });
722
+ var InternalTokenValidationRequestSchema = import_zod2.z.object({
723
+ access_token: import_zod2.z.string().min(1)
724
+ });
725
+ var InternalTokenValidationResponseSchema = import_zod2.z.object({
726
+ valid: import_zod2.z.boolean(),
727
+ userId: import_zod2.z.string().optional(),
728
+ userEmail: import_zod2.z.string().optional(),
729
+ userName: import_zod2.z.string().optional(),
730
+ scope: import_zod2.z.string().optional(),
731
+ permissions: import_zod2.z.string().optional(),
732
+ clientId: import_zod2.z.string().optional(),
733
+ expiresAt: import_zod2.z.string().optional()
734
+ });
735
+
736
+ // ../../packages/core/dist/validation/index.js
737
+ var ListProjectsInputSchema = import_zod3.z.object({
738
+ workspaceType: import_zod3.z.preprocess((val) => typeof val === "string" ? val.toUpperCase() : val, import_zod3.z.enum(["TEAM", "PERSONAL", "ALL"]).optional())
739
+ });
740
+ var ListTasksInputSchema = import_zod3.z.object({
741
+ projectId: import_zod3.z.string().optional(),
742
+ state: import_zod3.z.nativeEnum(TaskState).optional(),
743
+ assigneeId: import_zod3.z.string().optional(),
744
+ includeArchived: import_zod3.z.boolean().optional()
745
+ });
746
+ var cuidOrPrefixedId = import_zod3.z.string().regex(/^([a-z0-9]+|[a-z]+_[a-zA-Z0-9]+)$/);
747
+ 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");
748
+ var GetTaskInputSchema = import_zod3.z.object({
503
749
  taskId: cuidOrPrefixedId
504
750
  });
505
- var AssignTaskInputSchema = import_zod2.z.object({
751
+ var AssignTaskInputSchema = import_zod3.z.object({
506
752
  projectId: cuidOrPrefixedId,
507
753
  taskId: cuidOrPrefixedId,
508
- expectedState: import_zod2.z.nativeEnum(TaskState).default(TaskState.TODO)
754
+ expectedState: import_zod3.z.nativeEnum(TaskState).default(TaskState.TODO)
509
755
  });
510
- var UpdateProgressInputSchema = import_zod2.z.object({
756
+ var UpdateProgressInputSchema = import_zod3.z.object({
511
757
  taskId: cuidOrPrefixedId,
512
- statusMessage: import_zod2.z.string().max(1e3).optional(),
513
- completedCheckpointIds: import_zod2.z.array(import_zod2.z.string()).optional(),
514
- currentCheckpointIndex: import_zod2.z.number().int().optional()
758
+ statusMessage: import_zod3.z.string().max(1e3).optional(),
759
+ completedCheckpointIds: import_zod3.z.array(import_zod3.z.string()).optional(),
760
+ currentCheckpointIndex: import_zod3.z.number().int().optional()
515
761
  });
516
- var CompleteTaskInputSchema = import_zod2.z.object({
762
+ var CompleteTaskInputSchema = import_zod3.z.object({
517
763
  projectId: cuidOrPrefixedId,
518
764
  taskId: cuidOrPrefixedId,
519
- pullRequestTitle: import_zod2.z.string().min(1).max(300).optional(),
520
- pullRequestBody: import_zod2.z.string().max(1e4).optional()
765
+ pullRequestTitle: import_zod3.z.string().min(1).max(300).optional(),
766
+ pullRequestBody: import_zod3.z.string().max(1e4).optional()
521
767
  });
522
- var ReportErrorInputSchema = import_zod2.z.object({
768
+ var ReportErrorInputSchema = import_zod3.z.object({
523
769
  taskId: cuidOrPrefixedId,
524
- errorType: import_zod2.z.nativeEnum(ErrorType),
525
- errorMessage: import_zod2.z.string().min(1).max(1e3),
526
- context: import_zod2.z.string().max(2e3).optional()
770
+ errorType: import_zod3.z.nativeEnum(ErrorType),
771
+ errorMessage: import_zod3.z.string().min(1).max(1e3),
772
+ context: import_zod3.z.string().max(2e3).optional()
527
773
  });
528
- var GetProjectContextInputSchema = import_zod2.z.object({
774
+ var GetProjectContextInputSchema = import_zod3.z.object({
529
775
  projectId: cuidOrPrefixedId
530
776
  });
531
- var AddNoteInputSchema = import_zod2.z.object({
777
+ var AddNoteInputSchema = import_zod3.z.object({
532
778
  taskId: cuidOrPrefixedId,
533
- content: import_zod2.z.string().min(1).max(500)
779
+ content: import_zod3.z.string().min(1).max(500)
534
780
  });
535
- var AbandonTaskInputSchema = import_zod2.z.object({
781
+ var AbandonTaskInputSchema = import_zod3.z.object({
536
782
  projectId: cuidOrPrefixedId,
537
783
  taskId: cuidOrPrefixedId,
538
- deleteBranch: import_zod2.z.boolean().optional()
784
+ deleteBranch: import_zod3.z.boolean().optional()
539
785
  });
540
- var RequestChangesInputSchema = import_zod2.z.object({
786
+ var RequestChangesInputSchema = import_zod3.z.object({
541
787
  projectId: cuidOrPrefixedId,
542
788
  taskId: cuidOrPrefixedId,
543
- reviewComments: import_zod2.z.string().min(1).max(5e3),
544
- requestedChanges: import_zod2.z.array(import_zod2.z.string().min(1).max(500)).optional()
789
+ reviewComments: import_zod3.z.string().min(1).max(5e3),
790
+ requestedChanges: import_zod3.z.array(import_zod3.z.string().min(1).max(500)).optional()
545
791
  });
546
- var ApproveTaskInputSchema = import_zod2.z.object({
792
+ var ApproveTaskInputSchema = import_zod3.z.object({
547
793
  projectId: cuidOrPrefixedId,
548
794
  taskId: cuidOrPrefixedId,
549
- reviewComments: import_zod2.z.string().max(2e3).optional()
795
+ reviewComments: import_zod3.z.string().max(2e3).optional()
550
796
  });
551
- var ArchiveTaskInputSchema = import_zod2.z.object({
797
+ var ArchiveTaskInputSchema = import_zod3.z.object({
552
798
  projectId: cuidOrPrefixedId,
553
799
  taskId: cuidOrPrefixedId
554
800
  });
555
- var UnarchiveTaskInputSchema = import_zod2.z.object({
801
+ var UnarchiveTaskInputSchema = import_zod3.z.object({
556
802
  projectId: cuidOrPrefixedId,
557
803
  taskId: cuidOrPrefixedId
558
804
  });
559
- var CreatePersonalProjectInputSchema = import_zod2.z.object({
560
- name: import_zod2.z.string().min(1).max(100),
561
- description: import_zod2.z.string().max(500).optional(),
562
- repositoryUrl: import_zod2.z.string().url()
805
+ var CreatePersonalProjectInputSchema = import_zod3.z.object({
806
+ name: import_zod3.z.string().min(1).max(100),
807
+ description: import_zod3.z.string().max(500).optional(),
808
+ repositoryUrl: import_zod3.z.string().url()
563
809
  });
564
- var CheckActiveTaskInputSchema = import_zod2.z.object({});
565
- var CreateTaskMCPInputSchema = import_zod2.z.object({
810
+ var CheckActiveTaskInputSchema = import_zod3.z.object({});
811
+ var CreateTaskMCPInputSchema = import_zod3.z.object({
566
812
  projectId: cuidOrPrefixedId,
567
813
  epicId: cuidOrPrefixedId.nullable().optional(),
568
- title: import_zod2.z.string().min(1).max(200),
569
- description: import_zod2.z.string().max(5e3),
570
- priority: import_zod2.z.nativeEnum(TaskPriority).default(TaskPriority.MEDIUM),
571
- acceptanceCriteria: import_zod2.z.array(import_zod2.z.object({
572
- description: import_zod2.z.string().min(1).max(500)
814
+ title: import_zod3.z.string().min(1).max(200),
815
+ description: import_zod3.z.string().max(5e3),
816
+ priority: import_zod3.z.nativeEnum(TaskPriority).default(TaskPriority.MEDIUM),
817
+ acceptanceCriteria: import_zod3.z.array(import_zod3.z.object({
818
+ description: import_zod3.z.string().min(1).max(500)
573
819
  })).min(1)
574
820
  });
575
- var CreateOrganizationInputSchema = import_zod2.z.object({
576
- name: import_zod2.z.string().min(1).max(255),
577
- slug: import_zod2.z.string().min(1).max(100).regex(/^[a-z0-9-]+$/).optional()
821
+ var CreateOrganizationInputSchema = import_zod3.z.object({
822
+ name: import_zod3.z.string().min(1).max(255)
578
823
  });
579
- var UpdateOrganizationInputSchema = import_zod2.z.object({
824
+ var UpdateOrganizationInputSchema = import_zod3.z.object({
580
825
  organizationId: cuidOrPrefixedId,
581
- name: import_zod2.z.string().min(1).max(255).optional(),
582
- logoUrl: import_zod2.z.string().url().nullable().optional(),
583
- accentColor: import_zod2.z.string().regex(/^#[0-9A-Fa-f]{6}$/, "Invalid hex color format. Expected #RRGGBB").nullable().optional(),
584
- tenantName: import_zod2.z.string().max(255).nullable().optional()
585
- });
586
- var CreateProjectInputSchema = import_zod2.z.object({
587
- name: import_zod2.z.string().min(1).max(100),
588
- description: import_zod2.z.string().max(500).optional(),
589
- type: import_zod2.z.nativeEnum(ProjectType),
590
- repositoryUrl: import_zod2.z.string().url(),
591
- baseBranch: import_zod2.z.string().default("develop").optional(),
592
- tags: import_zod2.z.array(import_zod2.z.string()).default([])
593
- });
594
- var UpdateProjectInputSchema = import_zod2.z.object({
595
- projectId: import_zod2.z.string().min(1).optional(),
596
- name: import_zod2.z.string().min(1).max(100).optional(),
597
- description: import_zod2.z.string().max(500).optional(),
598
- repositoryUrl: import_zod2.z.string().url().optional(),
599
- baseBranch: import_zod2.z.string().optional(),
600
- tags: import_zod2.z.array(import_zod2.z.string()).optional(),
601
- allowMemberArchive: import_zod2.z.boolean().optional()
602
- });
603
- var CreateEpicInputSchema = import_zod2.z.object({
826
+ name: import_zod3.z.string().min(1).max(255).optional(),
827
+ logoUrl: import_zod3.z.string().url().nullable().optional(),
828
+ accentColor: import_zod3.z.string().regex(/^#[0-9A-Fa-f]{6}$/, "Invalid hex color format. Expected #RRGGBB").nullable().optional(),
829
+ tenantName: import_zod3.z.string().max(255).nullable().optional()
830
+ });
831
+ var CreateProjectInputSchema = import_zod3.z.object({
832
+ name: import_zod3.z.string().min(1).max(100),
833
+ description: import_zod3.z.string().max(500).optional(),
834
+ type: import_zod3.z.nativeEnum(ProjectType),
835
+ repositoryUrl: import_zod3.z.string().url(),
836
+ baseBranch: import_zod3.z.string().default("develop").optional(),
837
+ tags: import_zod3.z.array(import_zod3.z.string()).default([])
838
+ });
839
+ var UpdateProjectInputSchema = import_zod3.z.object({
840
+ projectId: import_zod3.z.string().min(1).optional(),
841
+ name: import_zod3.z.string().min(1).max(100).optional(),
842
+ description: import_zod3.z.string().max(500).optional(),
843
+ repositoryUrl: import_zod3.z.string().url().optional(),
844
+ baseBranch: import_zod3.z.string().optional(),
845
+ tags: import_zod3.z.array(import_zod3.z.string()).optional(),
846
+ allowMemberArchive: import_zod3.z.boolean().optional(),
847
+ localRepoPath: import_zod3.z.string().max(500).optional()
848
+ });
849
+ var CreateEpicInputSchema = import_zod3.z.object({
604
850
  projectId: cuidOrPrefixedId,
605
- name: import_zod2.z.string().min(1).max(200),
606
- description: import_zod2.z.string().max(2e3).optional()
607
- });
608
- var CreateTaskInputSchema = import_zod2.z.object({
609
- projectId: import_zod2.z.string().min(1),
610
- epicId: import_zod2.z.string().min(1).nullable().optional(),
611
- title: import_zod2.z.string().min(1).max(200),
612
- description: import_zod2.z.string().max(5e3),
613
- priority: import_zod2.z.nativeEnum(TaskPriority).default(TaskPriority.MEDIUM),
614
- acceptanceCriteria: import_zod2.z.array(import_zod2.z.object({
615
- description: import_zod2.z.string().min(1).max(500)
851
+ name: import_zod3.z.string().min(1).max(200),
852
+ description: import_zod3.z.string().max(2e3).optional()
853
+ });
854
+ var CreateTaskInputSchema = import_zod3.z.object({
855
+ projectId: import_zod3.z.string().min(1),
856
+ epicId: import_zod3.z.string().min(1).nullable().optional(),
857
+ title: import_zod3.z.string().min(1).max(200),
858
+ description: import_zod3.z.string().max(5e3),
859
+ priority: import_zod3.z.nativeEnum(TaskPriority).default(TaskPriority.MEDIUM),
860
+ acceptanceCriteria: import_zod3.z.array(import_zod3.z.object({
861
+ description: import_zod3.z.string().min(1).max(500)
616
862
  })).min(1)
617
863
  });
618
- var UpdateTaskInputSchema = import_zod2.z.object({
619
- taskId: import_zod2.z.string().min(1),
620
- title: import_zod2.z.string().min(1).max(200).optional(),
621
- description: import_zod2.z.string().max(5e3).optional(),
622
- priority: import_zod2.z.nativeEnum(TaskPriority).optional(),
623
- state: import_zod2.z.nativeEnum(TaskState).optional(),
624
- assigneeId: import_zod2.z.string().nullable().optional(),
625
- acceptanceCriteria: import_zod2.z.array(import_zod2.z.object({
626
- id: import_zod2.z.string().optional(),
627
- description: import_zod2.z.string().min(1).max(500),
628
- completed: import_zod2.z.boolean().optional()
864
+ var UpdateTaskInputSchema = import_zod3.z.object({
865
+ taskId: import_zod3.z.string().min(1),
866
+ title: import_zod3.z.string().min(1).max(200).optional(),
867
+ description: import_zod3.z.string().max(5e3).optional(),
868
+ priority: import_zod3.z.nativeEnum(TaskPriority).optional(),
869
+ state: import_zod3.z.nativeEnum(TaskState).optional(),
870
+ assigneeId: import_zod3.z.string().nullable().optional(),
871
+ acceptanceCriteria: import_zod3.z.array(import_zod3.z.object({
872
+ id: import_zod3.z.string().optional(),
873
+ description: import_zod3.z.string().min(1).max(500),
874
+ completed: import_zod3.z.boolean().optional()
629
875
  })).optional()
630
876
  });
631
- var AssignTaskWebappInputSchema = import_zod2.z.object({
632
- taskId: import_zod2.z.string().min(1),
633
- userId: import_zod2.z.string().min(1)
877
+ var AssignTaskWebappInputSchema = import_zod3.z.object({
878
+ taskId: import_zod3.z.string().min(1),
879
+ userId: import_zod3.z.string().min(1)
634
880
  });
635
- var CreateTagInputSchema = import_zod2.z.object({
881
+ var CreateTagInputSchema = import_zod3.z.object({
636
882
  organizationId: cuidOrPrefixedId,
637
- name: import_zod2.z.string().min(1).max(50).regex(/^[a-zA-Z0-9\s-]+$/)
883
+ name: import_zod3.z.string().min(1).max(50).regex(/^[a-zA-Z0-9\s-]+$/)
638
884
  });
639
- var UpdateTagInputSchema = import_zod2.z.object({
640
- name: import_zod2.z.string().min(1).max(50).regex(/^[a-zA-Z0-9\s-]+$/)
885
+ var UpdateTagInputSchema = import_zod3.z.object({
886
+ name: import_zod3.z.string().min(1).max(50).regex(/^[a-zA-Z0-9\s-]+$/)
641
887
  });
642
- var UpdateOrganizationSettingsInputSchema = import_zod2.z.object({
888
+ var UpdateOrganizationSettingsInputSchema = import_zod3.z.object({
643
889
  organizationId: cuidOrPrefixedId,
644
- ldapEnabled: import_zod2.z.boolean().optional(),
645
- ldapUrl: import_zod2.z.string().url().nullable().optional(),
646
- ldapBindDN: import_zod2.z.string().nullable().optional(),
647
- ldapSearchBase: import_zod2.z.string().nullable().optional(),
648
- deleteMergedBranches: import_zod2.z.boolean().optional(),
649
- enforceConventionalCommits: import_zod2.z.boolean().optional(),
650
- maxPersonalProjectsPerUser: import_zod2.z.number().int().min(0).optional(),
651
- logoUrl: import_zod2.z.string().url().nullable().optional(),
652
- accentColor: import_zod2.z.string().regex(/^#[0-9A-Fa-f]{6}$/, "Invalid hex color format. Expected #RRGGBB").nullable().optional(),
653
- tenantName: import_zod2.z.string().max(255).nullable().optional()
654
- });
655
- var InviteUserInputSchema = import_zod2.z.object({
890
+ ldapEnabled: import_zod3.z.boolean().optional(),
891
+ ldapUrl: import_zod3.z.string().url().nullable().optional(),
892
+ ldapBindDN: import_zod3.z.string().nullable().optional(),
893
+ ldapSearchBase: import_zod3.z.string().nullable().optional(),
894
+ deleteMergedBranches: import_zod3.z.boolean().optional(),
895
+ enforceConventionalCommits: import_zod3.z.boolean().optional(),
896
+ maxPersonalProjectsPerUser: import_zod3.z.number().int().min(0).optional(),
897
+ logoUrl: import_zod3.z.string().url().nullable().optional(),
898
+ accentColor: import_zod3.z.string().regex(/^#[0-9A-Fa-f]{6}$/, "Invalid hex color format. Expected #RRGGBB").nullable().optional(),
899
+ tenantName: import_zod3.z.string().max(255).nullable().optional()
900
+ });
901
+ var InviteUserInputSchema = import_zod3.z.object({
656
902
  organizationId: cuidOrPrefixedId,
657
- email: import_zod2.z.string().email(),
658
- role: import_zod2.z.nativeEnum(UserRole).default(UserRole.MEMBER),
659
- tags: import_zod2.z.array(import_zod2.z.string()).default([])
903
+ email: import_zod3.z.string().email(),
904
+ role: import_zod3.z.nativeEnum(UserRole).default(UserRole.MEMBER),
905
+ tags: import_zod3.z.array(import_zod3.z.string()).default([])
660
906
  });
661
- var AssignUserTagsInputSchema = import_zod2.z.object({
907
+ var AssignUserTagsInputSchema = import_zod3.z.object({
662
908
  userId: cuidOrPrefixedId,
663
- tags: import_zod2.z.array(import_zod2.z.string()).min(0)
909
+ tags: import_zod3.z.array(import_zod3.z.string()).min(0)
664
910
  });
665
- var InviteCollaboratorInputSchema = import_zod2.z.object({
911
+ var InviteCollaboratorInputSchema = import_zod3.z.object({
666
912
  projectId: cuidOrPrefixedId,
667
- email: import_zod2.z.string().email()
913
+ email: import_zod3.z.string().email()
668
914
  });
669
- var PublishProjectInputSchema = import_zod2.z.object({
915
+ var PublishProjectInputSchema = import_zod3.z.object({
670
916
  projectId: cuidOrPrefixedId,
671
- transferOwnership: import_zod2.z.boolean().default(false),
672
- tags: import_zod2.z.array(import_zod2.z.string()).min(1)
917
+ transferOwnership: import_zod3.z.boolean().default(false),
918
+ tags: import_zod3.z.array(import_zod3.z.string()).min(1)
919
+ });
920
+ var GenerateApiKeyInputSchema = import_zod3.z.object({
921
+ name: import_zod3.z.string().min(1).max(100),
922
+ publicNickname: import_zod3.z.string().max(50).optional(),
923
+ expiresInDays: import_zod3.z.number().int().min(1).max(365).default(90),
924
+ permissions: import_zod3.z.nativeEnum(ApiKeyPermission).default(ApiKeyPermission.WRITE)
673
925
  });
674
- var GenerateApiKeyInputSchema = import_zod2.z.object({
675
- name: import_zod2.z.string().min(1).max(100),
676
- expiresInDays: import_zod2.z.number().int().min(1).max(365).default(90),
677
- permissions: import_zod2.z.nativeEnum(ApiKeyPermission).default(ApiKeyPermission.WRITE)
926
+ var UpdateApiKeyInputSchema = import_zod3.z.object({
927
+ publicNickname: import_zod3.z.string().max(50).nullable().optional(),
928
+ scopedOrganizationId: import_zod3.z.string().optional().nullable(),
929
+ scopedProjectIds: import_zod3.z.array(import_zod3.z.string()).optional()
678
930
  });
679
- var RevokeApiKeyInputSchema = import_zod2.z.object({
931
+ var RevokeApiKeyInputSchema = import_zod3.z.object({
680
932
  keyId: cuidOrPrefixedId
681
933
  });
682
- var LoginInputSchema = import_zod2.z.object({
683
- email: import_zod2.z.string().email(),
684
- password: import_zod2.z.string().min(8).max(255)
934
+ var LoginInputSchema = import_zod3.z.object({
935
+ email: import_zod3.z.string().email(),
936
+ password: import_zod3.z.string().min(8).max(255)
685
937
  });
686
- var RegisterInputSchema = import_zod2.z.object({
687
- email: import_zod2.z.string().email(),
688
- password: import_zod2.z.string().min(8).max(255),
689
- name: import_zod2.z.string().min(1).max(255),
690
- organizationSlug: import_zod2.z.string().min(1).max(100).regex(/^[a-z0-9-]+$/).optional()
938
+ var RegisterInputSchema = import_zod3.z.object({
939
+ email: import_zod3.z.string().email(),
940
+ password: import_zod3.z.string().min(8).max(255),
941
+ name: import_zod3.z.string().min(1).max(255)
691
942
  });
692
- var VerifyTaskInputSchema = import_zod2.z.object({
943
+ var VerifyTaskInputSchema = import_zod3.z.object({
693
944
  projectId: cuidOrPrefixedId,
694
945
  taskId: cuidOrPrefixedId,
695
- approved: import_zod2.z.boolean(),
696
- feedback: import_zod2.z.string().max(5e3).optional()
946
+ approved: import_zod3.z.boolean(),
947
+ feedback: import_zod3.z.string().max(5e3).optional()
697
948
  });
698
- var GetTaskPromptInputSchema = import_zod2.z.object({
949
+ var GetTaskPromptInputSchema = import_zod3.z.object({
699
950
  projectId: cuidOrPrefixedId,
700
951
  taskId: cuidOrPrefixedId
701
952
  });
702
- var UpdateTaskMCPInputSchema = import_zod2.z.object({
953
+ var UpdateTaskMCPInputSchema = import_zod3.z.object({
703
954
  projectId: cuidOrPrefixedId,
704
955
  taskId: cuidOrPrefixedId,
705
- title: import_zod2.z.string().min(1).max(200).optional(),
706
- description: import_zod2.z.string().max(5e3).optional(),
707
- priority: import_zod2.z.nativeEnum(TaskPriority).optional(),
708
- acceptanceCriteria: import_zod2.z.array(import_zod2.z.object({
709
- id: import_zod2.z.string().optional(),
710
- description: import_zod2.z.string().min(1).max(500)
956
+ title: import_zod3.z.string().min(1).max(200).optional(),
957
+ description: import_zod3.z.string().max(5e3).optional(),
958
+ priority: import_zod3.z.nativeEnum(TaskPriority).optional(),
959
+ acceptanceCriteria: import_zod3.z.array(import_zod3.z.object({
960
+ id: import_zod3.z.string().optional(),
961
+ description: import_zod3.z.string().min(1).max(500)
711
962
  })).optional()
712
963
  });
713
- var ReportBranchInputSchema = import_zod2.z.object({
964
+ var ReportBranchInputSchema = import_zod3.z.object({
714
965
  projectId: cuidOrPrefixedId,
715
966
  taskId: cuidOrPrefixedId,
716
967
  branchName: gitBranchName
717
968
  });
718
- var ReportPRInputSchema = import_zod2.z.object({
969
+ var ReportPRInputSchema = import_zod3.z.object({
719
970
  projectId: cuidOrPrefixedId,
720
971
  taskId: cuidOrPrefixedId,
721
- pullRequestUrl: import_zod2.z.string().url(),
722
- pullRequestNumber: import_zod2.z.number().int().positive()
972
+ pullRequestUrl: import_zod3.z.string().url(),
973
+ pullRequestNumber: import_zod3.z.number().int().positive()
723
974
  });
724
975
 
725
976
  // ../../packages/core/dist/logging/metrics.js
@@ -800,23 +1051,20 @@ function createHistogram(name, help, buckets = [5e-3, 0.01, 0.025, 0.05, 0.1, 0.
800
1051
  var httpRequestsTotal = createCounter("mtaap_http_requests_total", "Total number of HTTP requests");
801
1052
  var httpRequestDuration = createHistogram("mtaap_http_request_duration_seconds", "HTTP request duration in seconds");
802
1053
  var activeUsers = createGauge("mtaap_active_users", "Number of active users");
803
- var tasksTotal = createCounter("mtaap_tasks_total", "Total number of tasks by state");
804
- var taskStateChanges = createCounter("mtaap_task_state_changes_total", "Total number of task state changes");
805
1054
  var httpErrorsTotal = createCounter("mtaap_http_errors_total", "Total number of HTTP errors");
806
1055
  var httpActiveConnections = createGauge("mtaap_http_active_connections", "Number of active HTTP connections");
807
1056
  var newSignupsTotal = createCounter("mtaap_new_signups_total", "Total number of new user signups");
808
1057
  var loginSuccessTotal = createCounter("mtaap_login_success_total", "Total number of successful logins");
809
1058
  var loginFailureTotal = createCounter("mtaap_login_failure_total", "Total number of failed logins");
810
- var dbConnectionPoolActive = createGauge("mtaap_db_connection_pool_active", "Number of active database connections");
811
- var dbConnectionPoolIdle = createGauge("mtaap_db_connection_pool_idle", "Number of idle database connections");
812
- var dbConnectionPoolMax = createGauge("mtaap_db_connection_pool_max", "Maximum number of database connections");
813
1059
  var dbQueryDuration = createHistogram("mtaap_db_query_duration_seconds", "Database query duration in seconds");
814
1060
  var dbSlowQueriesTotal = createCounter("mtaap_db_slow_queries_total", "Total number of slow database queries (>1s)");
815
- var dbErrorsTotal = createCounter("mtaap_db_errors_total", "Total number of database errors");
816
1061
  var tasksCreatedTotal = createCounter("mtaap_tasks_created_total", "Total number of tasks created");
817
1062
  var tasksAssignedTotal = createCounter("mtaap_tasks_assigned_total", "Total number of tasks assigned");
818
1063
  var tasksCompletedTotal = createCounter("mtaap_tasks_completed_total", "Total number of tasks completed");
819
- var tasksByState = createGauge("mtaap_tasks_by_state", "Number of tasks by state");
1064
+ var agentSessionsTotal = createCounter("mtaap_agent_sessions_total", "Total number of agent sessions started");
1065
+ var agentErrorsTotal = createCounter("mtaap_agent_errors_total", "Total number of agent errors");
1066
+ var agentSessionDuration = createHistogram("mtaap_agent_session_duration_seconds", "Agent session duration in seconds", [1, 5, 15, 30, 60, 120, 300, 600, 1800, 3600]);
1067
+ var agentSessionsActive = createGauge("mtaap_agent_sessions_active", "Number of currently active agent sessions");
820
1068
 
821
1069
  // ../../packages/core/dist/logging/performance-monitor.js
822
1070
  var MAX_SAMPLES = 1e3;
@@ -1020,6 +1268,9 @@ var errorTrackerInstance = new NoOpErrorTracker();
1020
1268
 
1021
1269
  // src/api-client.ts
1022
1270
  var DEFAULT_TIMEOUT = 3e4;
1271
+ var DEFAULT_CACHE_TTL = 3e4;
1272
+ var MAX_RETRIES = 2;
1273
+ var INITIAL_RETRY_DELAY = 500;
1023
1274
  function sanitizeForLogging(str) {
1024
1275
  let sanitized = str.replace(/\bcollab_[a-zA-Z0-9_-]+\b/gi, "[REDACTED_API_KEY]");
1025
1276
  sanitized = sanitized.replace(/\bBearer\s+[a-zA-Z0-9._-]+\b/gi, "Bearer [REDACTED]");
@@ -1034,42 +1285,113 @@ var ApiError = class extends Error {
1034
1285
  this.details = details;
1035
1286
  this.name = "ApiError";
1036
1287
  }
1288
+ /**
1289
+ * Whether this error is transient and the request can be retried.
1290
+ * Retries on network errors (status 0), timeouts (408), and server errors (5xx).
1291
+ */
1292
+ get isRetryable() {
1293
+ return this.status === 0 || this.status === 408 || this.status >= 500;
1294
+ }
1037
1295
  };
1296
+ function sleep(ms) {
1297
+ return new Promise((resolve) => setTimeout(resolve, ms));
1298
+ }
1038
1299
  var MCPApiClient = class {
1039
1300
  baseUrl;
1040
1301
  apiKey;
1302
+ oauthToken;
1041
1303
  timeout;
1042
1304
  debug;
1043
1305
  authContext = null;
1306
+ cache = /* @__PURE__ */ new Map();
1044
1307
  constructor(config3) {
1308
+ if (!config3.apiKey && !config3.oauthToken) {
1309
+ throw new Error("Either apiKey or oauthToken must be provided");
1310
+ }
1045
1311
  this.baseUrl = config3.baseUrl.replace(/\/$/, "");
1046
1312
  this.apiKey = config3.apiKey;
1313
+ this.oauthToken = config3.oauthToken;
1047
1314
  this.timeout = config3.timeout ?? DEFAULT_TIMEOUT;
1048
1315
  this.debug = config3.debug ?? false;
1049
1316
  }
1050
1317
  /**
1051
- * Make an HTTP request to the API
1318
+ * Get a cached value if it exists and hasn't expired.
1319
+ */
1320
+ getCached(key) {
1321
+ const entry = this.cache.get(key);
1322
+ if (!entry) return void 0;
1323
+ if (Date.now() > entry.expiresAt) {
1324
+ this.cache.delete(key);
1325
+ return void 0;
1326
+ }
1327
+ return entry.data;
1328
+ }
1329
+ /**
1330
+ * Store a value in cache with a TTL.
1331
+ */
1332
+ setCache(key, data, ttl = DEFAULT_CACHE_TTL) {
1333
+ this.cache.set(key, { data, expiresAt: Date.now() + ttl });
1334
+ }
1335
+ /**
1336
+ * Make an HTTP request to the API with automatic retry on transient failures.
1337
+ */
1338
+ async request(method, path2, body) {
1339
+ let lastError;
1340
+ for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
1341
+ try {
1342
+ return await this.requestOnce(method, path2, body);
1343
+ } catch (error) {
1344
+ if (!(error instanceof ApiError) || !error.isRetryable || attempt === MAX_RETRIES) {
1345
+ throw error;
1346
+ }
1347
+ lastError = error;
1348
+ const delay = INITIAL_RETRY_DELAY * Math.pow(2, attempt);
1349
+ if (this.debug) {
1350
+ console.error(`[mcp-api] Retry ${attempt + 1}/${MAX_RETRIES} after ${delay}ms (${lastError.code})`);
1351
+ }
1352
+ await sleep(delay);
1353
+ }
1354
+ }
1355
+ throw lastError;
1356
+ }
1357
+ /**
1358
+ * Execute a single HTTP request to the API.
1052
1359
  */
1053
- async request(method, path, body) {
1054
- const url = `${this.baseUrl}${path}`;
1360
+ async requestOnce(method, path2, body) {
1361
+ const url = `${this.baseUrl}${path2}`;
1055
1362
  const controller = new AbortController();
1056
1363
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
1057
1364
  if (this.debug) {
1058
- console.error(`[mcp-api] ${method} ${sanitizeForLogging(path)}`);
1365
+ console.error(`[mcp-api] ${method} ${sanitizeForLogging(path2)}`);
1059
1366
  }
1060
1367
  try {
1368
+ const headers = {
1369
+ "Content-Type": "application/json"
1370
+ };
1371
+ if (this.oauthToken) {
1372
+ headers["Authorization"] = `Bearer ${this.oauthToken}`;
1373
+ } else if (this.apiKey) {
1374
+ headers["X-API-Key"] = this.apiKey;
1375
+ }
1061
1376
  const response = await fetch(url, {
1062
1377
  method,
1063
- headers: {
1064
- "Content-Type": "application/json",
1065
- "X-API-Key": this.apiKey
1066
- },
1378
+ headers,
1067
1379
  body: body ? JSON.stringify(body) : void 0,
1068
1380
  signal: controller.signal
1069
1381
  });
1070
1382
  clearTimeout(timeoutId);
1071
1383
  const data = await response.json();
1072
1384
  if (!response.ok) {
1385
+ if (response.status === 403 && data.code === "EMAIL_NOT_VERIFIED" && data.verificationUrl) {
1386
+ throw new ApiError(
1387
+ `${data.error}
1388
+
1389
+ To verify your email, visit: ${data.verificationUrl}
1390
+ ${data.hint ? `Hint: ${data.hint}` : ""}`,
1391
+ "EMAIL_NOT_VERIFIED",
1392
+ 403
1393
+ );
1394
+ }
1073
1395
  throw new ApiError(
1074
1396
  data.error || "API request failed",
1075
1397
  data.code || "UNKNOWN_ERROR",
@@ -1116,14 +1438,19 @@ var MCPApiClient = class {
1116
1438
  return this.authenticate();
1117
1439
  }
1118
1440
  /**
1119
- * List accessible projects
1441
+ * List accessible projects (cached for 30s)
1120
1442
  */
1121
1443
  async listProjects(workspaceType) {
1122
1444
  const type = workspaceType || "ALL";
1123
- return this.request(
1445
+ const cacheKey = `listProjects:${type}`;
1446
+ const cached = this.getCached(cacheKey);
1447
+ if (cached) return cached;
1448
+ const result = await this.request(
1124
1449
  "GET",
1125
1450
  `/api/mcp/projects?workspaceType=${encodeURIComponent(type)}`
1126
1451
  );
1452
+ this.setCache(cacheKey, result);
1453
+ return result;
1127
1454
  }
1128
1455
  /**
1129
1456
  * Get single project details
@@ -1132,13 +1459,18 @@ var MCPApiClient = class {
1132
1459
  return this.request("GET", `/api/mcp/projects/${projectId}`);
1133
1460
  }
1134
1461
  /**
1135
- * Get project context (README, stack, conventions)
1462
+ * Get project context (README, stack, conventions) (cached for 60s)
1136
1463
  */
1137
1464
  async getProjectContext(projectId) {
1138
- return this.request(
1465
+ const cacheKey = `projectContext:${projectId}`;
1466
+ const cached = this.getCached(cacheKey);
1467
+ if (cached) return cached;
1468
+ const result = await this.request(
1139
1469
  "GET",
1140
1470
  `/api/mcp/projects/${projectId}/context`
1141
1471
  );
1472
+ this.setCache(cacheKey, result, 6e4);
1473
+ return result;
1142
1474
  }
1143
1475
  /**
1144
1476
  * Create a personal project
@@ -1166,8 +1498,8 @@ var MCPApiClient = class {
1166
1498
  if (filters.assigneeId) params.set("assigneeId", filters.assigneeId);
1167
1499
  if (filters.includeArchived) params.set("includeArchived", "true");
1168
1500
  const queryString = params.toString();
1169
- const path = queryString ? `/api/mcp/tasks?${queryString}` : "/api/mcp/tasks";
1170
- return this.request("GET", path);
1501
+ const path2 = queryString ? `/api/mcp/tasks?${queryString}` : "/api/mcp/tasks";
1502
+ return this.request("GET", path2);
1171
1503
  }
1172
1504
  /**
1173
1505
  * Get full task details
@@ -1300,7 +1632,8 @@ var MCPApiClient = class {
1300
1632
  );
1301
1633
  }
1302
1634
  /**
1303
- * Update task details (DRAFT/TODO states only)
1635
+ * Update task details (DRAFT/TODO states only).
1636
+ * Task stays in its current state.
1304
1637
  */
1305
1638
  async updateTask(taskId, projectId, data) {
1306
1639
  return this.request("PATCH", `/api/mcp/tasks/${taskId}`, {
@@ -1332,7 +1665,7 @@ var PERMISSION_RANK = {
1332
1665
  ADMIN: 3
1333
1666
  };
1334
1667
  function assertApiKeyPermission(apiKey, required, toolName) {
1335
- const actualRank = PERMISSION_RANK[apiKey.permissions] ?? 0;
1668
+ const actualRank = apiKey.permissions ? PERMISSION_RANK[apiKey.permissions] ?? 0 : 0;
1336
1669
  const requiredRank = PERMISSION_RANK[required] ?? 0;
1337
1670
  if (actualRank >= requiredRank) {
1338
1671
  return;
@@ -1350,6 +1683,454 @@ function assertApiKeyPermission(apiKey, required, toolName) {
1350
1683
  throw error;
1351
1684
  }
1352
1685
 
1686
+ // src/apps/task-details.ts
1687
+ var import_server2 = require("@modelcontextprotocol/ext-apps/server");
1688
+ var import_zod4 = require("zod");
1689
+
1690
+ // src/apps/helpers.ts
1691
+ var import_server = require("@modelcontextprotocol/ext-apps/server");
1692
+ var import_promises = __toESM(require("fs/promises"));
1693
+ var import_node_path = __toESM(require("path"));
1694
+ var import_node_url = require("url");
1695
+ var import_meta = {};
1696
+ var getDirname = () => {
1697
+ try {
1698
+ return import_node_path.default.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
1699
+ } catch {
1700
+ return __dirname;
1701
+ }
1702
+ };
1703
+ function getAppHtmlPath(htmlFileName) {
1704
+ return import_node_path.default.join(getDirname(), "apps", htmlFileName);
1705
+ }
1706
+ function registerAppHtmlResource(server, config3) {
1707
+ (0, import_server.registerAppResource)(
1708
+ server,
1709
+ config3.name,
1710
+ config3.uri,
1711
+ {
1712
+ mimeType: import_server.RESOURCE_MIME_TYPE,
1713
+ description: config3.description
1714
+ },
1715
+ async () => {
1716
+ const htmlPath = getAppHtmlPath(config3.htmlFileName);
1717
+ try {
1718
+ const html = await import_promises.default.readFile(htmlPath, "utf-8");
1719
+ return {
1720
+ contents: [
1721
+ {
1722
+ uri: config3.uri,
1723
+ mimeType: import_server.RESOURCE_MIME_TYPE,
1724
+ text: html
1725
+ }
1726
+ ]
1727
+ };
1728
+ } catch {
1729
+ return {
1730
+ contents: [
1731
+ {
1732
+ uri: config3.uri,
1733
+ mimeType: import_server.RESOURCE_MIME_TYPE,
1734
+ text: `<!DOCTYPE html><html><body><p>${config3.fallbackLabel} UI not available. Build the UI apps first.</p></body></html>`
1735
+ }
1736
+ ]
1737
+ };
1738
+ }
1739
+ }
1740
+ );
1741
+ }
1742
+
1743
+ // src/apps/task-details.ts
1744
+ var RESOURCE_URI = "ui://collab/task-details.html";
1745
+ function registerTaskDetailsApp(server, apiClient, _authContext) {
1746
+ (0, import_server2.registerAppTool)(
1747
+ server,
1748
+ "view_task_details",
1749
+ {
1750
+ title: "Task Details",
1751
+ description: "View interactive task details with acceptance criteria, notes, and progress. Opens a rich UI panel.",
1752
+ inputSchema: {
1753
+ taskId: import_zod4.z.string().describe("The task ID to view"),
1754
+ projectId: import_zod4.z.string().describe("The project ID")
1755
+ },
1756
+ _meta: { ui: { resourceUri: RESOURCE_URI } }
1757
+ },
1758
+ async ({ taskId, projectId }) => {
1759
+ try {
1760
+ const task = await apiClient.getTask(taskId);
1761
+ let project = null;
1762
+ try {
1763
+ project = await apiClient.getProject(projectId);
1764
+ } catch {
1765
+ }
1766
+ return {
1767
+ content: [
1768
+ {
1769
+ type: "text",
1770
+ text: `Viewing task: ${task.title}`
1771
+ }
1772
+ ],
1773
+ structuredContent: {
1774
+ task,
1775
+ project
1776
+ }
1777
+ };
1778
+ } catch (error) {
1779
+ const message = error instanceof Error ? error.message : String(error);
1780
+ return {
1781
+ content: [{ type: "text", text: `Error loading task: ${message}` }],
1782
+ isError: true
1783
+ };
1784
+ }
1785
+ }
1786
+ );
1787
+ registerAppHtmlResource(server, {
1788
+ name: "Task Details UI",
1789
+ uri: RESOURCE_URI,
1790
+ description: "Interactive task details view with acceptance criteria and notes",
1791
+ htmlFileName: "task-details.html",
1792
+ fallbackLabel: "Task Details"
1793
+ });
1794
+ }
1795
+
1796
+ // src/apps/kanban.ts
1797
+ var import_server3 = require("@modelcontextprotocol/ext-apps/server");
1798
+ var import_zod5 = require("zod");
1799
+ var RESOURCE_URI2 = "ui://collab/kanban.html";
1800
+ function registerKanbanApp(server, apiClient, _authContext) {
1801
+ (0, import_server3.registerAppTool)(
1802
+ server,
1803
+ "view_kanban_board",
1804
+ {
1805
+ title: "Kanban Board",
1806
+ description: "View interactive drag-and-drop Kanban board for a project. Drag tasks between columns to change their state.",
1807
+ inputSchema: {
1808
+ projectId: import_zod5.z.string().describe("The project ID to display")
1809
+ },
1810
+ _meta: { ui: { resourceUri: RESOURCE_URI2 } }
1811
+ },
1812
+ async ({ projectId }) => {
1813
+ try {
1814
+ const [project, tasks] = await Promise.all([
1815
+ apiClient.getProject(projectId),
1816
+ apiClient.listTasks({ projectId })
1817
+ ]);
1818
+ return {
1819
+ content: [
1820
+ {
1821
+ type: "text",
1822
+ text: `Kanban board for ${project.name} (${tasks.length} tasks)`
1823
+ }
1824
+ ],
1825
+ structuredContent: {
1826
+ project,
1827
+ tasks
1828
+ }
1829
+ };
1830
+ } catch (error) {
1831
+ const message = error instanceof Error ? error.message : String(error);
1832
+ return {
1833
+ content: [{ type: "text", text: `Error loading kanban: ${message}` }],
1834
+ isError: true
1835
+ };
1836
+ }
1837
+ }
1838
+ );
1839
+ registerAppHtmlResource(server, {
1840
+ name: "Kanban Board UI",
1841
+ uri: RESOURCE_URI2,
1842
+ description: "Interactive drag-and-drop Kanban board for task management",
1843
+ htmlFileName: "kanban.html",
1844
+ fallbackLabel: "Kanban"
1845
+ });
1846
+ }
1847
+
1848
+ // src/apps/activity.ts
1849
+ var import_server4 = require("@modelcontextprotocol/ext-apps/server");
1850
+ var import_zod6 = require("zod");
1851
+ var RESOURCE_URI3 = "ui://collab/activity.html";
1852
+ function registerActivityApp(server, apiClient, _authContext) {
1853
+ (0, import_server4.registerAppTool)(
1854
+ server,
1855
+ "view_activity",
1856
+ {
1857
+ title: "User Activity",
1858
+ description: "View who is working on what across the team. Shows IN_PROGRESS and REVIEW tasks per user.",
1859
+ inputSchema: {
1860
+ projectId: import_zod6.z.string().optional().describe("Optional project ID to filter by")
1861
+ },
1862
+ _meta: { ui: { resourceUri: RESOURCE_URI3 } }
1863
+ },
1864
+ async ({ projectId }) => {
1865
+ try {
1866
+ const [inProgressTasks, reviewTasks] = await Promise.all([
1867
+ apiClient.listTasks({
1868
+ projectId,
1869
+ state: TaskState.IN_PROGRESS
1870
+ }),
1871
+ apiClient.listTasks({
1872
+ projectId,
1873
+ state: TaskState.REVIEW
1874
+ })
1875
+ ]);
1876
+ const userMap = /* @__PURE__ */ new Map();
1877
+ for (const task of inProgressTasks) {
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).activeTasks.push(task);
1889
+ }
1890
+ }
1891
+ for (const task of reviewTasks) {
1892
+ if (task.assigneeId) {
1893
+ if (!userMap.has(task.assigneeId)) {
1894
+ userMap.set(task.assigneeId, {
1895
+ id: task.assigneeId,
1896
+ name: task.assigneeName || "Unknown",
1897
+ email: task.assigneeEmail || "",
1898
+ activeTasks: [],
1899
+ reviewTasks: []
1900
+ });
1901
+ }
1902
+ userMap.get(task.assigneeId).reviewTasks.push(task);
1903
+ }
1904
+ }
1905
+ const users = Array.from(userMap.values());
1906
+ return {
1907
+ content: [
1908
+ {
1909
+ type: "text",
1910
+ text: `Activity: ${users.length} users with active work`
1911
+ }
1912
+ ],
1913
+ structuredContent: {
1914
+ users,
1915
+ projectId
1916
+ }
1917
+ };
1918
+ } catch (error) {
1919
+ const message = error instanceof Error ? error.message : String(error);
1920
+ return {
1921
+ content: [
1922
+ { type: "text", text: `Error loading activity: ${message}` }
1923
+ ],
1924
+ isError: true
1925
+ };
1926
+ }
1927
+ }
1928
+ );
1929
+ registerAppHtmlResource(server, {
1930
+ name: "User Activity UI",
1931
+ uri: RESOURCE_URI3,
1932
+ description: "Dashboard showing team member activity and workload",
1933
+ htmlFileName: "activity.html",
1934
+ fallbackLabel: "Activity"
1935
+ });
1936
+ }
1937
+
1938
+ // src/apps/project-overview.ts
1939
+ var import_server5 = require("@modelcontextprotocol/ext-apps/server");
1940
+ var import_zod7 = require("zod");
1941
+ var RESOURCE_URI4 = "ui://collab/project-overview.html";
1942
+ function registerProjectOverviewApp(server, apiClient, _authContext) {
1943
+ (0, import_server5.registerAppTool)(
1944
+ server,
1945
+ "view_project_overview",
1946
+ {
1947
+ title: "Project Overview",
1948
+ description: "View project health dashboard with task metrics, state distribution, and conventions.",
1949
+ inputSchema: {
1950
+ projectId: import_zod7.z.string().describe("The project ID to display")
1951
+ },
1952
+ _meta: { ui: { resourceUri: RESOURCE_URI4 } }
1953
+ },
1954
+ async ({ projectId }) => {
1955
+ try {
1956
+ const [project, context, tasks] = await Promise.all([
1957
+ apiClient.getProject(projectId),
1958
+ apiClient.getProjectContext(projectId).catch(() => null),
1959
+ apiClient.listTasks({ projectId })
1960
+ ]);
1961
+ const activeTasks = tasks.filter((t) => !t.isArchived);
1962
+ const inProgress = activeTasks.filter(
1963
+ (t) => t.state === TaskState.IN_PROGRESS
1964
+ ).length;
1965
+ const done = activeTasks.filter(
1966
+ (t) => t.state === TaskState.DONE
1967
+ ).length;
1968
+ const blocked = activeTasks.filter((t) => t.errorType).length;
1969
+ const tasksByState = {
1970
+ DRAFT: 0,
1971
+ TODO: 0,
1972
+ IN_PROGRESS: 0,
1973
+ REVIEW: 0,
1974
+ DONE: 0
1975
+ };
1976
+ for (const task of activeTasks) {
1977
+ tasksByState[task.state]++;
1978
+ }
1979
+ const tasksByPriority = {
1980
+ LOW: 0,
1981
+ MEDIUM: 0,
1982
+ HIGH: 0,
1983
+ CRITICAL: 0
1984
+ };
1985
+ for (const task of activeTasks) {
1986
+ tasksByPriority[task.priority]++;
1987
+ }
1988
+ const recentCompleted = activeTasks.filter((t) => t.state === TaskState.DONE).sort(
1989
+ (a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
1990
+ ).slice(0, 5);
1991
+ return {
1992
+ content: [
1993
+ {
1994
+ type: "text",
1995
+ text: `Project overview for ${project.name}: ${activeTasks.length} tasks`
1996
+ }
1997
+ ],
1998
+ structuredContent: {
1999
+ project,
2000
+ context,
2001
+ metrics: {
2002
+ totalTasks: activeTasks.length,
2003
+ inProgress,
2004
+ blocked,
2005
+ done
2006
+ },
2007
+ tasksByState,
2008
+ tasksByPriority,
2009
+ recentCompleted
2010
+ }
2011
+ };
2012
+ } catch (error) {
2013
+ const message = error instanceof Error ? error.message : String(error);
2014
+ return {
2015
+ content: [
2016
+ { type: "text", text: `Error loading project overview: ${message}` }
2017
+ ],
2018
+ isError: true
2019
+ };
2020
+ }
2021
+ }
2022
+ );
2023
+ registerAppHtmlResource(server, {
2024
+ name: "Project Overview UI",
2025
+ uri: RESOURCE_URI4,
2026
+ description: "Project health dashboard with metrics and visualizations",
2027
+ htmlFileName: "project-overview.html",
2028
+ fallbackLabel: "Project Overview"
2029
+ });
2030
+ }
2031
+
2032
+ // src/apps/agent-sessions.ts
2033
+ var import_server6 = require("@modelcontextprotocol/ext-apps/server");
2034
+ var import_zod8 = require("zod");
2035
+ var RESOURCE_URI5 = "ui://collab/agent-sessions.html";
2036
+ function registerAgentSessionsApp(server, apiClient, authContext) {
2037
+ (0, import_server6.registerAppTool)(
2038
+ server,
2039
+ "view_agent_sessions",
2040
+ {
2041
+ title: "Agent Sessions",
2042
+ description: "View active AI agent sessions working on tasks. Monitor real-time progress and session status.",
2043
+ inputSchema: {
2044
+ projectId: import_zod8.z.string().optional().describe("Optional project ID to filter by")
2045
+ },
2046
+ _meta: { ui: { resourceUri: RESOURCE_URI5 } }
2047
+ },
2048
+ async ({ projectId }) => {
2049
+ try {
2050
+ const [inProgressTasks, reviewTasks] = await Promise.all([
2051
+ apiClient.listTasks({
2052
+ projectId,
2053
+ state: TaskState.IN_PROGRESS
2054
+ }),
2055
+ apiClient.listTasks({
2056
+ projectId,
2057
+ state: TaskState.REVIEW
2058
+ })
2059
+ ]);
2060
+ const sessions = [];
2061
+ for (const task of inProgressTasks) {
2062
+ if (task.assigneeId) {
2063
+ const totalCriteria = task.acceptanceCriteria?.length || 0;
2064
+ const completedCriteria = task.acceptanceCriteria?.filter((c) => c.completed).length || 0;
2065
+ const progress = totalCriteria > 0 ? Math.round(completedCriteria / totalCriteria * 100) : 0;
2066
+ const latestUpdate = task.progressUpdates?.[task.progressUpdates.length - 1];
2067
+ sessions.push({
2068
+ id: `session-${task.id}`,
2069
+ taskId: task.id,
2070
+ taskTitle: task.title,
2071
+ agentName: task.assigneeName || "Agent",
2072
+ status: "RUNNING",
2073
+ startedAt: task.updatedAt,
2074
+ lastCheckpoint: latestUpdate?.timestamp,
2075
+ currentStep: latestUpdate?.statusMessage,
2076
+ progress
2077
+ });
2078
+ }
2079
+ }
2080
+ for (const task of reviewTasks) {
2081
+ if (task.assigneeId) {
2082
+ sessions.push({
2083
+ id: `session-${task.id}`,
2084
+ taskId: task.id,
2085
+ taskTitle: task.title,
2086
+ agentName: task.assigneeName || "Agent",
2087
+ status: "STOPPED",
2088
+ startedAt: task.updatedAt,
2089
+ progress: 100
2090
+ });
2091
+ }
2092
+ }
2093
+ return {
2094
+ content: [
2095
+ {
2096
+ type: "text",
2097
+ text: `Agent sessions: ${sessions.length} active`
2098
+ }
2099
+ ],
2100
+ structuredContent: {
2101
+ sessions,
2102
+ projectId
2103
+ }
2104
+ };
2105
+ } catch (error) {
2106
+ const message = error instanceof Error ? error.message : String(error);
2107
+ return {
2108
+ content: [
2109
+ { type: "text", text: `Error loading agent sessions: ${message}` }
2110
+ ],
2111
+ isError: true
2112
+ };
2113
+ }
2114
+ }
2115
+ );
2116
+ registerAppHtmlResource(server, {
2117
+ name: "Agent Sessions UI",
2118
+ uri: RESOURCE_URI5,
2119
+ description: "Real-time view of AI agent sessions and their progress",
2120
+ htmlFileName: "agent-sessions.html",
2121
+ fallbackLabel: "Agent Sessions"
2122
+ });
2123
+ }
2124
+
2125
+ // src/apps/index.ts
2126
+ function registerMCPApps(server, apiClient, authContext) {
2127
+ registerTaskDetailsApp(server, apiClient, authContext);
2128
+ registerKanbanApp(server, apiClient, authContext);
2129
+ registerActivityApp(server, apiClient, authContext);
2130
+ registerProjectOverviewApp(server, apiClient, authContext);
2131
+ registerAgentSessionsApp(server, apiClient, authContext);
2132
+ }
2133
+
1353
2134
  // src/index.ts
1354
2135
  var COLLAB_SERVER_INSTRUCTIONS = `Collab - AI-assisted software development task management platform.
1355
2136
 
@@ -1401,7 +2182,7 @@ Review Workflow:
1401
2182
  list_tasks(state=REVIEW) -> get_task -> approve_task OR request_changes
1402
2183
 
1403
2184
  Task Editing:
1404
- update_task (DRAFT/TODO only) -> if was TODO, reverts to DRAFT -> verify_task again
2185
+ update_task (DRAFT/TODO only) -> task stays in current state
1405
2186
 
1406
2187
  Error Recovery:
1407
2188
  report_error -> abandon_task -> list_tasks -> assign_task (retry or pick different task)
@@ -1420,7 +2201,7 @@ GIT OPERATIONS NOTE:
1420
2201
  TASK STATE FLOW:
1421
2202
  DRAFT -> TODO -> IN_PROGRESS -> REVIEW -> DONE
1422
2203
  (verify_task: DRAFT -> TODO)
1423
- (update_task on TODO: reverts to DRAFT)
2204
+ (update_task: DRAFT/TODO only, state unchanged)
1424
2205
  (request_changes: REVIEW -> IN_PROGRESS)
1425
2206
  (abandon_task: IN_PROGRESS -> TODO)
1426
2207
 
@@ -1453,7 +2234,7 @@ function initializeMCPServer(apiClient, authContext) {
1453
2234
  {
1454
2235
  description: "Discover all accessible projects. Use first to find project IDs. Filter by TEAM, PERSONAL, or ALL workspaces.",
1455
2236
  inputSchema: {
1456
- workspaceType: import_zod3.z.enum(["TEAM", "PERSONAL", "ALL"]).optional().describe("Filter by workspace type")
2237
+ workspaceType: import_zod9.z.enum(["TEAM", "PERSONAL", "ALL"]).optional().describe("Filter by workspace type")
1457
2238
  }
1458
2239
  },
1459
2240
  async (args) => {
@@ -1483,10 +2264,10 @@ function initializeMCPServer(apiClient, authContext) {
1483
2264
  {
1484
2265
  description: "Query tasks with filters. Use state=TODO for assignable tasks, state=REVIEW for pending reviews.",
1485
2266
  inputSchema: {
1486
- projectId: import_zod3.z.string().optional().describe("Filter by project ID"),
1487
- state: import_zod3.z.nativeEnum(TaskState).optional().describe("Filter by task state"),
1488
- assigneeId: import_zod3.z.string().optional().describe("Filter by assignee ID"),
1489
- includeArchived: import_zod3.z.boolean().optional().describe("Include archived tasks (default: false)")
2267
+ projectId: import_zod9.z.string().optional().describe("Filter by project ID"),
2268
+ state: import_zod9.z.nativeEnum(TaskState).optional().describe("Filter by task state"),
2269
+ assigneeId: import_zod9.z.string().optional().describe("Filter by assignee ID"),
2270
+ includeArchived: import_zod9.z.boolean().optional().describe("Include archived tasks (default: false)")
1490
2271
  }
1491
2272
  },
1492
2273
  async (args) => {
@@ -1517,7 +2298,7 @@ function initializeMCPServer(apiClient, authContext) {
1517
2298
  {
1518
2299
  description: "Get complete task details with acceptance criteria and notes. Call before assign_task to understand requirements.",
1519
2300
  inputSchema: {
1520
- taskId: import_zod3.z.string().describe("The task ID to retrieve")
2301
+ taskId: import_zod9.z.string().describe("The task ID to retrieve")
1521
2302
  }
1522
2303
  },
1523
2304
  async (args) => {
@@ -1543,9 +2324,9 @@ function initializeMCPServer(apiClient, authContext) {
1543
2324
  {
1544
2325
  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.",
1545
2326
  inputSchema: {
1546
- projectId: import_zod3.z.string().describe("The project ID"),
1547
- taskId: import_zod3.z.string().describe("The task ID to assign"),
1548
- expectedState: import_zod3.z.nativeEnum(TaskState).optional().describe("Expected task state (default: TODO)")
2327
+ projectId: import_zod9.z.string().describe("The project ID"),
2328
+ taskId: import_zod9.z.string().describe("The task ID to assign"),
2329
+ expectedState: import_zod9.z.nativeEnum(TaskState).optional().describe("Expected task state (default: TODO)")
1549
2330
  }
1550
2331
  },
1551
2332
  async (args) => {
@@ -1579,10 +2360,10 @@ function initializeMCPServer(apiClient, authContext) {
1579
2360
  {
1580
2361
  description: "Report progress and checkpoint work. Call frequently during execution. Marks acceptance criteria complete.",
1581
2362
  inputSchema: {
1582
- taskId: import_zod3.z.string().describe("The task ID to update"),
1583
- statusMessage: import_zod3.z.string().optional().describe("Status message (max 1000 chars)"),
1584
- completedCheckpointIds: import_zod3.z.array(import_zod3.z.string()).optional().describe("Array of completed checkpoint IDs"),
1585
- currentCheckpointIndex: import_zod3.z.number().optional().describe("Current checkpoint index")
2363
+ taskId: import_zod9.z.string().describe("The task ID to update"),
2364
+ statusMessage: import_zod9.z.string().optional().describe("Status message (max 1000 chars)"),
2365
+ completedCheckpointIds: import_zod9.z.array(import_zod9.z.string()).optional().describe("Array of completed checkpoint IDs"),
2366
+ currentCheckpointIndex: import_zod9.z.number().optional().describe("Current checkpoint index")
1586
2367
  }
1587
2368
  },
1588
2369
  async (args) => {
@@ -1616,10 +2397,10 @@ function initializeMCPServer(apiClient, authContext) {
1616
2397
  {
1617
2398
  description: "Prepare task for PR creation. Returns PR suggestions. After creating PR locally, call report_pr to transition to REVIEW. Requires IN_PROGRESS state.",
1618
2399
  inputSchema: {
1619
- projectId: import_zod3.z.string().describe("The project ID"),
1620
- taskId: import_zod3.z.string().describe("The task ID to complete"),
1621
- pullRequestTitle: import_zod3.z.string().optional().describe("PR title (max 300 chars)"),
1622
- pullRequestBody: import_zod3.z.string().optional().describe("PR body/description (max 10000 chars)")
2400
+ projectId: import_zod9.z.string().describe("The project ID"),
2401
+ taskId: import_zod9.z.string().describe("The task ID to complete"),
2402
+ pullRequestTitle: import_zod9.z.string().optional().describe("PR title (max 300 chars)"),
2403
+ pullRequestBody: import_zod9.z.string().optional().describe("PR body/description (max 10000 chars)")
1623
2404
  }
1624
2405
  },
1625
2406
  async (args) => {
@@ -1676,10 +2457,10 @@ function initializeMCPServer(apiClient, authContext) {
1676
2457
  {
1677
2458
  description: "Report unrecoverable errors (BUILD_FAILURE, TEST_FAILURE, CONFLICT, AUTH_ERROR). Consider abandon_task after.",
1678
2459
  inputSchema: {
1679
- taskId: import_zod3.z.string().describe("The task ID"),
1680
- errorType: import_zod3.z.nativeEnum(ErrorType).describe("Error type: BUILD_FAILURE, TEST_FAILURE, CONFLICT, AUTH_ERROR, OTHER"),
1681
- errorMessage: import_zod3.z.string().describe("Error message (max 1000 chars)"),
1682
- context: import_zod3.z.string().optional().describe("Additional context (max 2000 chars)")
2460
+ taskId: import_zod9.z.string().describe("The task ID"),
2461
+ errorType: import_zod9.z.nativeEnum(ErrorType).describe("Error type: BUILD_FAILURE, TEST_FAILURE, CONFLICT, AUTH_ERROR, OTHER"),
2462
+ errorMessage: import_zod9.z.string().describe("Error message (max 1000 chars)"),
2463
+ context: import_zod9.z.string().optional().describe("Additional context (max 2000 chars)")
1683
2464
  }
1684
2465
  },
1685
2466
  async (args) => {
@@ -1714,7 +2495,7 @@ function initializeMCPServer(apiClient, authContext) {
1714
2495
  {
1715
2496
  description: "Load project README, tech stack, and coding conventions. Call after selecting project.",
1716
2497
  inputSchema: {
1717
- projectId: import_zod3.z.string().describe("The project ID")
2498
+ projectId: import_zod9.z.string().describe("The project ID")
1718
2499
  }
1719
2500
  },
1720
2501
  async (args) => {
@@ -1744,8 +2525,8 @@ function initializeMCPServer(apiClient, authContext) {
1744
2525
  {
1745
2526
  description: "Document implementation decisions. Notes persist for future reference and handoff.",
1746
2527
  inputSchema: {
1747
- taskId: import_zod3.z.string().describe("The task ID"),
1748
- content: import_zod3.z.string().describe("Note content (max 500 chars)")
2528
+ taskId: import_zod9.z.string().describe("The task ID"),
2529
+ content: import_zod9.z.string().describe("Note content (max 500 chars)")
1749
2530
  }
1750
2531
  },
1751
2532
  async (args) => {
@@ -1774,9 +2555,9 @@ function initializeMCPServer(apiClient, authContext) {
1774
2555
  {
1775
2556
  description: "Release task assignment and optionally clean up branch. Task returns to TODO. Use after errors.",
1776
2557
  inputSchema: {
1777
- projectId: import_zod3.z.string().describe("The project ID"),
1778
- taskId: import_zod3.z.string().describe("The task ID to abandon"),
1779
- deleteBranch: import_zod3.z.boolean().optional().describe("Whether to delete the associated branch")
2558
+ projectId: import_zod9.z.string().describe("The project ID"),
2559
+ taskId: import_zod9.z.string().describe("The task ID to abandon"),
2560
+ deleteBranch: import_zod9.z.boolean().optional().describe("Whether to delete the associated branch")
1780
2561
  }
1781
2562
  },
1782
2563
  async (args) => {
@@ -1810,9 +2591,9 @@ function initializeMCPServer(apiClient, authContext) {
1810
2591
  {
1811
2592
  description: "Report a branch created by the agent. Call after using git to create and push a branch. Task must be IN_PROGRESS.",
1812
2593
  inputSchema: {
1813
- projectId: import_zod3.z.string().describe("The project ID"),
1814
- taskId: import_zod3.z.string().describe("The task ID"),
1815
- branchName: import_zod3.z.string().describe("Name of the branch created (e.g., feature/TASK-123-fix-login)")
2594
+ projectId: import_zod9.z.string().describe("The project ID"),
2595
+ taskId: import_zod9.z.string().describe("The task ID"),
2596
+ branchName: import_zod9.z.string().describe("Name of the branch created (e.g., feature/TASK-123-fix-login)")
1816
2597
  }
1817
2598
  },
1818
2599
  async (args) => {
@@ -1846,10 +2627,10 @@ function initializeMCPServer(apiClient, authContext) {
1846
2627
  {
1847
2628
  description: "Report a PR created by the agent. Call after using gh pr create. Transitions task to REVIEW state.",
1848
2629
  inputSchema: {
1849
- projectId: import_zod3.z.string().describe("The project ID"),
1850
- taskId: import_zod3.z.string().describe("The task ID"),
1851
- pullRequestUrl: import_zod3.z.string().describe("Full URL of the created PR (e.g., https://github.com/owner/repo/pull/123)"),
1852
- pullRequestNumber: import_zod3.z.number().describe("PR number (e.g., 123)")
2630
+ projectId: import_zod9.z.string().describe("The project ID"),
2631
+ taskId: import_zod9.z.string().describe("The task ID"),
2632
+ pullRequestUrl: import_zod9.z.string().describe("Full URL of the created PR (e.g., https://github.com/owner/repo/pull/123)"),
2633
+ pullRequestNumber: import_zod9.z.number().describe("PR number (e.g., 123)")
1853
2634
  }
1854
2635
  },
1855
2636
  async (args) => {
@@ -1884,8 +2665,8 @@ function initializeMCPServer(apiClient, authContext) {
1884
2665
  {
1885
2666
  description: "Soft-delete a task. Hidden but restorable via unarchive_task.",
1886
2667
  inputSchema: {
1887
- projectId: import_zod3.z.string().describe("The project ID"),
1888
- taskId: import_zod3.z.string().describe("The task ID to archive")
2668
+ projectId: import_zod9.z.string().describe("The project ID"),
2669
+ taskId: import_zod9.z.string().describe("The task ID to archive")
1889
2670
  }
1890
2671
  },
1891
2672
  async (args) => {
@@ -1918,8 +2699,8 @@ function initializeMCPServer(apiClient, authContext) {
1918
2699
  {
1919
2700
  description: "Restore previously archived task to original state.",
1920
2701
  inputSchema: {
1921
- projectId: import_zod3.z.string().describe("The project ID"),
1922
- taskId: import_zod3.z.string().describe("The task ID to restore")
2702
+ projectId: import_zod9.z.string().describe("The project ID"),
2703
+ taskId: import_zod9.z.string().describe("The task ID to restore")
1923
2704
  }
1924
2705
  },
1925
2706
  async (args) => {
@@ -1952,9 +2733,9 @@ function initializeMCPServer(apiClient, authContext) {
1952
2733
  {
1953
2734
  description: "Create new project in personal workspace linked to GitHub repository.",
1954
2735
  inputSchema: {
1955
- name: import_zod3.z.string().describe("Project name (max 100 chars)"),
1956
- description: import_zod3.z.string().optional().describe("Project description (max 500 chars)"),
1957
- repositoryUrl: import_zod3.z.string().describe("GitHub repository URL")
2736
+ name: import_zod9.z.string().describe("Project name (max 100 chars)"),
2737
+ description: import_zod9.z.string().optional().describe("Project description (max 500 chars)"),
2738
+ repositoryUrl: import_zod9.z.string().describe("GitHub repository URL")
1958
2739
  }
1959
2740
  },
1960
2741
  async (args) => {
@@ -1988,14 +2769,14 @@ function initializeMCPServer(apiClient, authContext) {
1988
2769
  {
1989
2770
  description: "Create task with title, description, acceptance criteria. Starts in DRAFT. Priority: LOW/MEDIUM/HIGH/CRITICAL.",
1990
2771
  inputSchema: {
1991
- projectId: import_zod3.z.string().describe("The project ID to create the task in"),
1992
- epicId: import_zod3.z.string().nullable().optional().describe("Optional epic ID to associate the task with"),
1993
- title: import_zod3.z.string().describe("Task title (max 200 chars)"),
1994
- description: import_zod3.z.string().describe("Task description (max 5000 chars)"),
1995
- priority: import_zod3.z.nativeEnum(TaskPriority).optional().describe("Task priority: LOW, MEDIUM, HIGH, CRITICAL (default: MEDIUM)"),
1996
- acceptanceCriteria: import_zod3.z.array(
1997
- import_zod3.z.object({
1998
- description: import_zod3.z.string().describe("Acceptance criterion description (max 500 chars)")
2772
+ projectId: import_zod9.z.string().describe("The project ID to create the task in"),
2773
+ epicId: import_zod9.z.string().nullable().optional().describe("Optional epic ID to associate the task with"),
2774
+ title: import_zod9.z.string().describe("Task title (max 200 chars)"),
2775
+ description: import_zod9.z.string().describe("Task description (max 5000 chars)"),
2776
+ priority: import_zod9.z.nativeEnum(TaskPriority).optional().describe("Task priority: LOW, MEDIUM, HIGH, CRITICAL (default: MEDIUM)"),
2777
+ acceptanceCriteria: import_zod9.z.array(
2778
+ import_zod9.z.object({
2779
+ description: import_zod9.z.string().describe("Acceptance criterion description (max 500 chars)")
1999
2780
  })
2000
2781
  ).describe("Array of acceptance criteria (at least 1 required)")
2001
2782
  }
@@ -2034,10 +2815,10 @@ function initializeMCPServer(apiClient, authContext) {
2034
2815
  {
2035
2816
  description: "Return task from REVIEW to IN_PROGRESS with feedback. Original assignee addresses changes.",
2036
2817
  inputSchema: {
2037
- projectId: import_zod3.z.string().describe("The project ID"),
2038
- taskId: import_zod3.z.string().describe("The task ID to review"),
2039
- reviewComments: import_zod3.z.string().describe("Review comments explaining requested changes (max 5000 chars)"),
2040
- requestedChanges: import_zod3.z.array(import_zod3.z.string()).optional().describe("List of specific changes requested")
2818
+ projectId: import_zod9.z.string().describe("The project ID"),
2819
+ taskId: import_zod9.z.string().describe("The task ID to review"),
2820
+ reviewComments: import_zod9.z.string().describe("Review comments explaining requested changes (max 5000 chars)"),
2821
+ requestedChanges: import_zod9.z.array(import_zod9.z.string()).optional().describe("List of specific changes requested")
2041
2822
  }
2042
2823
  },
2043
2824
  async (args) => {
@@ -2072,9 +2853,9 @@ function initializeMCPServer(apiClient, authContext) {
2072
2853
  {
2073
2854
  description: "Approve completed work and mark DONE. Only for REVIEW state tasks.",
2074
2855
  inputSchema: {
2075
- projectId: import_zod3.z.string().describe("The project ID"),
2076
- taskId: import_zod3.z.string().describe("The task ID to approve"),
2077
- reviewComments: import_zod3.z.string().optional().describe("Optional approval comments (max 2000 chars)")
2856
+ projectId: import_zod9.z.string().describe("The project ID"),
2857
+ taskId: import_zod9.z.string().describe("The task ID to approve"),
2858
+ reviewComments: import_zod9.z.string().optional().describe("Optional approval comments (max 2000 chars)")
2078
2859
  }
2079
2860
  },
2080
2861
  async (args) => {
@@ -2108,10 +2889,10 @@ function initializeMCPServer(apiClient, authContext) {
2108
2889
  {
2109
2890
  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.",
2110
2891
  inputSchema: {
2111
- projectId: import_zod3.z.string().describe("The project ID"),
2112
- taskId: import_zod3.z.string().describe("The task ID to verify"),
2113
- approved: import_zod3.z.boolean().describe("Whether to approve the task"),
2114
- feedback: import_zod3.z.string().optional().describe("Feedback for the task (required if not approved)")
2892
+ projectId: import_zod9.z.string().describe("The project ID"),
2893
+ taskId: import_zod9.z.string().describe("The task ID to verify"),
2894
+ approved: import_zod9.z.boolean().describe("Whether to approve the task"),
2895
+ feedback: import_zod9.z.string().optional().describe("Feedback for the task (required if not approved)")
2115
2896
  }
2116
2897
  },
2117
2898
  async (args) => {
@@ -2142,8 +2923,8 @@ function initializeMCPServer(apiClient, authContext) {
2142
2923
  {
2143
2924
  description: "Get state-appropriate prompt for a task. Returns verify prompt for DRAFT, assignment prompt for TODO, or continue prompt for IN_PROGRESS tasks.",
2144
2925
  inputSchema: {
2145
- projectId: import_zod3.z.string().describe("The project ID"),
2146
- taskId: import_zod3.z.string().describe("The task ID")
2926
+ projectId: import_zod9.z.string().describe("The project ID"),
2927
+ taskId: import_zod9.z.string().describe("The task ID")
2147
2928
  }
2148
2929
  },
2149
2930
  async (args) => {
@@ -2174,17 +2955,17 @@ function initializeMCPServer(apiClient, authContext) {
2174
2955
  server.registerTool(
2175
2956
  "update_task",
2176
2957
  {
2177
- 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.",
2958
+ description: "Update task details (title, description, priority, acceptanceCriteria). Only works for DRAFT and TODO states. Task stays in its current state.",
2178
2959
  inputSchema: {
2179
- projectId: import_zod3.z.string().describe("The project ID"),
2180
- taskId: import_zod3.z.string().describe("The task ID to update"),
2181
- title: import_zod3.z.string().optional().describe("New task title"),
2182
- description: import_zod3.z.string().optional().describe("New task description"),
2183
- priority: import_zod3.z.nativeEnum(TaskPriority).optional().describe("New task priority"),
2184
- acceptanceCriteria: import_zod3.z.array(
2185
- import_zod3.z.object({
2186
- id: import_zod3.z.string().optional().describe("Existing criterion ID (for updates)"),
2187
- description: import_zod3.z.string().describe("Criterion description")
2960
+ projectId: import_zod9.z.string().describe("The project ID"),
2961
+ taskId: import_zod9.z.string().describe("The task ID to update"),
2962
+ title: import_zod9.z.string().optional().describe("New task title"),
2963
+ description: import_zod9.z.string().optional().describe("New task description"),
2964
+ priority: import_zod9.z.nativeEnum(TaskPriority).optional().describe("New task priority"),
2965
+ acceptanceCriteria: import_zod9.z.array(
2966
+ import_zod9.z.object({
2967
+ id: import_zod9.z.string().optional().describe("Existing criterion ID (for updates)"),
2968
+ description: import_zod9.z.string().describe("Criterion description")
2188
2969
  })
2189
2970
  ).optional().describe("New acceptance criteria (replaces existing)")
2190
2971
  }
@@ -2240,6 +3021,7 @@ function initializeMCPServer(apiClient, authContext) {
2240
3021
  };
2241
3022
  }
2242
3023
  );
3024
+ registerMCPApps(server, apiClient, authContext);
2243
3025
  return server;
2244
3026
  }
2245
3027
  async function connectMCPServer(server, transport) {
@@ -2292,30 +3074,30 @@ function handleApiError(error) {
2292
3074
  isError: true
2293
3075
  };
2294
3076
  }
2295
- var ActiveTaskSchema = import_zod3.z.object({
2296
- taskId: import_zod3.z.string().min(1),
2297
- projectId: import_zod3.z.string().min(1),
2298
- branchName: import_zod3.z.string().optional(),
2299
- worktreePath: import_zod3.z.string().optional(),
2300
- startedAt: import_zod3.z.string().optional()
3077
+ var ActiveTaskSchema = import_zod9.z.object({
3078
+ taskId: import_zod9.z.string().min(1),
3079
+ projectId: import_zod9.z.string().min(1),
3080
+ branchName: import_zod9.z.string().optional(),
3081
+ worktreePath: import_zod9.z.string().optional(),
3082
+ startedAt: import_zod9.z.string().optional()
2301
3083
  });
2302
3084
  async function checkActiveTask() {
2303
- const fs = await import("fs");
2304
- const path = await import("path");
3085
+ const fs2 = await import("fs");
3086
+ const path2 = await import("path");
2305
3087
  const cwd = process.cwd();
2306
- const collabDir = path.join(cwd, ".collab");
2307
- const activeTaskPath = path.join(collabDir, "active-task.json");
3088
+ const collabDir = path2.join(cwd, ".collab");
3089
+ const activeTaskPath = path2.join(collabDir, "active-task.json");
2308
3090
  try {
2309
- const resolvedPath = path.resolve(activeTaskPath);
2310
- const resolvedCollabDir = path.resolve(collabDir);
2311
- if (!resolvedPath.startsWith(resolvedCollabDir + path.sep) && resolvedPath !== resolvedCollabDir) {
3091
+ const resolvedPath = path2.resolve(activeTaskPath);
3092
+ const resolvedCollabDir = path2.resolve(collabDir);
3093
+ if (!resolvedPath.startsWith(resolvedCollabDir + path2.sep) && resolvedPath !== resolvedCollabDir) {
2312
3094
  return {
2313
3095
  hasActiveTask: false,
2314
3096
  task: null,
2315
3097
  error: "Invalid active task path"
2316
3098
  };
2317
3099
  }
2318
- const stats = await fs.promises.lstat(activeTaskPath);
3100
+ const stats = await fs2.promises.lstat(activeTaskPath);
2319
3101
  if (stats.isSymbolicLink()) {
2320
3102
  return {
2321
3103
  hasActiveTask: false,
@@ -2329,7 +3111,7 @@ async function checkActiveTask() {
2329
3111
  task: null
2330
3112
  };
2331
3113
  }
2332
- const content = await fs.promises.readFile(activeTaskPath, "utf-8");
3114
+ const content = await fs2.promises.readFile(activeTaskPath, "utf-8");
2333
3115
  let parsed;
2334
3116
  try {
2335
3117
  parsed = JSON.parse(content);