@ziggs-ai/ziggs-mcp 0.1.26 → 0.1.28

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.
@@ -73,4 +73,4 @@ export declare function indexReachByScope(reach: ContextReachDescriptor[]): Map<
73
73
  * When `reach` (the caller's own live grants) is passed, each scope is tagged
74
74
  * with its covering grant (ZIG-635) so the agent can pin X-Context-Grant-Id.
75
75
  */
76
- export declare function formatInboxToolResult(inbox: InboxEnvelope, ack?: InboxAckResult | null, webOrigin?: string, activeTasks?: Task[], reach?: ContextReachDescriptor[]): Record<string, unknown>;
76
+ export declare function formatInboxToolResult(inbox: InboxEnvelope, ack?: InboxAckResult | null, webOrigin?: string, activeTasks?: Task[], reach?: ContextReachDescriptor[], activeTasksError?: string): Record<string, unknown>;
@@ -205,7 +205,7 @@ function tagScopesWithGrants(scopes, byScope) {
205
205
  * When `reach` (the caller's own live grants) is passed, each scope is tagged
206
206
  * with its covering grant (ZIG-635) so the agent can pin X-Context-Grant-Id.
207
207
  */
208
- export function formatInboxToolResult(inbox, ack, webOrigin, activeTasks, reach) {
208
+ export function formatInboxToolResult(inbox, ack, webOrigin, activeTasks, reach, activeTasksError) {
209
209
  // ZIG-660: build the grant index once and feed both the read plan (grant
210
210
  // pinning) and the scope tags from it — buildReadPlan no longer runs before
211
211
  // the grants are available.
@@ -213,7 +213,7 @@ export function formatInboxToolResult(inbox, ack, webOrigin, activeTasks, reach)
213
213
  const { plan: readPlan, truncated: readPlanTruncated } = buildReadPlan(inbox, byScope);
214
214
  const scopes = tagScopesWithGrants(inbox.scopes ?? [], byScope);
215
215
  const origin = resolveWebAppOrigin(webOrigin);
216
- const pending = formatPendingDecisionsPayload(inbox, origin, { activeTasks });
216
+ const pending = formatPendingDecisionsPayload(inbox, origin, { activeTasks, activeTasksError });
217
217
  const pendingTail = pending.hasActionable === true
218
218
  ? {
219
219
  pendingCount: pending.pendingCount,
@@ -226,6 +226,14 @@ export function formatInboxToolResult(inbox, ack, webOrigin, activeTasks, reach)
226
226
  : {};
227
227
  const tail = {
228
228
  ...pendingTail,
229
+ // ZIG-700 — always surface a task-fetch failure, even when there is nothing
230
+ // else actionable, so hasActiveWork:false is not read as "no tasks".
231
+ ...(pending.activeTasksFetchError
232
+ ? {
233
+ activeTasksFetchError: pending.activeTasksFetchError,
234
+ workCardOmitted: true,
235
+ }
236
+ : {}),
229
237
  ...(readPlan.length ? { readPlan } : {}),
230
238
  ...(readPlanTruncated ? { readPlanTruncated } : {}),
231
239
  };
@@ -66,5 +66,6 @@ export declare function buildSessionChatCard(decisions: PendingDecisionItem[], w
66
66
  /** Structured session payload for MCP tools (ZIG-625 + active work). */
67
67
  export declare function formatPendingDecisionsPayload(inbox: InboxEnvelope, webOrigin: string, opts?: {
68
68
  activeTasks?: Task[];
69
+ activeTasksError?: string;
69
70
  }): Record<string, unknown>;
70
71
  export declare function buildPendingNextActions(decisions: PendingDecisionItem[], work?: ActiveWorkItem[]): string[];
@@ -407,6 +407,14 @@ export function formatPendingDecisionsPayload(inbox, webOrigin, opts) {
407
407
  ...(workChatCard ? { workChatCard } : {}),
408
408
  ...(sessionChatCard ? { sessionChatCard } : {}),
409
409
  ...(inbox.humanAttention ? { humanAttention: inbox.humanAttention } : {}),
410
+ // ZIG-700 — when the active-task fetch failed, say so instead of letting
411
+ // hasActiveWork:false read as "no tasks". Mirrors the inbox fetchError signal.
412
+ ...(opts?.activeTasksError
413
+ ? {
414
+ activeTasksFetchError: `Could not load active tasks: ${opts.activeTasksError}`,
415
+ workCardOmitted: true,
416
+ }
417
+ : {}),
410
418
  instruction,
411
419
  };
412
420
  }
package/dist/tools.js CHANGED
@@ -265,14 +265,17 @@ async function loadSessionActionsPayload(creds, cfg) {
265
265
  const client = new InboxClient(creds.operatorKey, creds.agentId);
266
266
  const inbox = await client.getInbox();
267
267
  let activeTasks = [];
268
+ let activeTasksError;
268
269
  try {
269
270
  const listed = await listTasks({ state: 'active', limit: 20 }, creds);
270
271
  activeTasks = filterTasksForDelegate(listed.tasks ?? [], delegateSelfIds(creds, cfg));
271
272
  }
272
- catch {
273
- // Inbox is still useful when task listing fails.
273
+ catch (e) {
274
+ // ZIG-700 — inbox is still useful when task listing fails, but surface the
275
+ // failure so hasActiveWork:false is not mistaken for "no tasks".
276
+ activeTasksError = e.message;
274
277
  }
275
- return formatPendingDecisionsPayload(inbox, webOrigin, { activeTasks });
278
+ return formatPendingDecisionsPayload(inbox, webOrigin, { activeTasks, activeTasksError });
276
279
  }
277
280
  export function registerZiggsTools(server, creds, cfg) {
278
281
  server.tool('ziggs_auth_status', 'Verify MCP OAuth binding: delegate agent id, owner user id, and org scope. Call after connect before inbox/chats. Includes pendingDecisions summary when approve/reject is waiting. (Renamed from ziggs_connection_status — "connection" now refers only to third-party credential connections, see ziggs_connection_proxy.)', {}, READ_ONLY, async () => {
@@ -619,12 +622,14 @@ export function registerZiggsTools(server, creds, cfg) {
619
622
  const acked = ack?.length ? await client.ack(ack) : null;
620
623
  const inbox = await client.getInbox();
621
624
  let activeTasks = [];
625
+ let activeTasksError;
622
626
  try {
623
627
  const listed = await listTasks({ state: 'active', limit: 20 }, creds);
624
628
  activeTasks = filterTasksForDelegate(listed.tasks ?? [], delegateSelfIds(creds, cfg));
625
629
  }
626
- catch {
627
- // omit work card when tasks fail
630
+ catch (e) {
631
+ // ZIG-700 surface the failure instead of silently omitting the work card.
632
+ activeTasksError = e.message;
628
633
  }
629
634
  // ZIG-635: tag each scope with the covering grant from the caller's own
630
635
  // live reach descriptors. Best-effort — the inbox still works untagged.
@@ -635,7 +640,7 @@ export function registerZiggsTools(server, creds, cfg) {
635
640
  catch {
636
641
  // omit grant tags when discovery fails
637
642
  }
638
- return textResult(formatInboxToolResult(inbox, acked, cfg.ZIGGS_WEB_URL, activeTasks, reach));
643
+ return textResult(formatInboxToolResult(inbox, acked, cfg.ZIGGS_WEB_URL, activeTasks, reach, activeTasksError));
639
644
  }
640
645
  catch (e) {
641
646
  return toolError(e.message);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ziggs-ai/ziggs-mcp",
3
- "version": "0.1.26",
3
+ "version": "0.1.28",
4
4
  "description": "MCP server for Claude Code, Cursor, and other MCP hosts — act as your Ziggs delegate agent",
5
5
  "type": "module",
6
6
  "bin": {
@@ -36,7 +36,7 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "@modelcontextprotocol/sdk": "^1.29.0",
39
- "@ziggs-ai/api-client": "^0.1.20",
39
+ "@ziggs-ai/api-client": "^0.1.24",
40
40
  "dotenv": "^16.6.1",
41
41
  "zod": "^3.24.2"
42
42
  },