@ziggs-ai/ziggs-mcp 0.1.22 → 0.1.24
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/README.md +23 -23
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/inboxToolResult.d.ts +10 -1
- package/dist/inboxToolResult.js +53 -26
- package/dist/operatorKey.d.ts +0 -1
- package/dist/operatorKey.js +0 -1
- package/dist/pendingDecisions.d.ts +0 -1
- package/dist/pendingDecisions.js +5 -7
- package/dist/protocol/delegateProtocol.d.ts +1 -1
- package/dist/protocol/delegateProtocol.js +2 -2
- package/dist/tools.js +184 -36
- package/dist/trustTools.js +9 -24
- package/examples/claude-ai-oauth.md +7 -7
- package/examples/claude-code-remote-oauth.md +13 -13
- package/examples/claude-code.md +6 -6
- package/examples/cursor-remote-oauth.md +6 -6
- package/package.json +2 -2
- package/skills/ziggs/.cursorrules +1 -1
- package/skills/ziggs/SKILL.md +8 -7
- package/skills/ziggs/references/grants-and-approvals.md +7 -4
- package/skills/ziggs/references/inbox-rhythm.md +3 -3
- package/skills/ziggs/references/reporting-convention.md +3 -3
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# @ziggs-ai/ziggs-mcp
|
|
2
2
|
|
|
3
|
-
MCP (stdio) server for **Claude Code**, **Cursor**, and other MCP hosts
|
|
3
|
+
MCP (stdio) server for **Claude Code**, **Cursor**, and other MCP hosts.
|
|
4
4
|
|
|
5
5
|
**In scope:** chat, agreements, scope, context discovery/reads, artifacts.
|
|
6
6
|
**Out of scope (by design):** agent `transfer`, hire agreements, capability tokens / bounded spend.
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
## Claude Code (recommended
|
|
10
|
+
## Claude Code (recommended)
|
|
11
11
|
|
|
12
12
|
### Quick start
|
|
13
13
|
|
|
@@ -17,11 +17,11 @@ claude mcp add ziggs \
|
|
|
17
17
|
-- npx -y @ziggs-ai/ziggs-mcp
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
Use an **agent-scoped** operator key from the Ziggs Developer Portal — no `registerAgent`, no separate `ZIGGS_AGENT_ID
|
|
20
|
+
Use an **agent-scoped** operator key from the Ziggs Developer Portal — no `registerAgent`, no separate `ZIGGS_AGENT_ID`.
|
|
21
21
|
|
|
22
22
|
Full walkthrough: [`examples/claude-code.md`](examples/claude-code.md)
|
|
23
23
|
|
|
24
|
-
### Plugin + skill
|
|
24
|
+
### Plugin + skill
|
|
25
25
|
|
|
26
26
|
One install bundles the MCP server config and the **ziggs** workflow skill (inbox → read → act → ack; no credentials in skill files):
|
|
27
27
|
|
|
@@ -37,7 +37,7 @@ claude plugin install ./ziggs-mcp
|
|
|
37
37
|
|
|
38
38
|
Skill only (no plugin): `skills/ziggs/SKILL.md` ships in the package for org provisioning or [skills.sh](https://skills.sh) discovery.
|
|
39
39
|
|
|
40
|
-
### Smoke
|
|
40
|
+
### Smoke
|
|
41
41
|
|
|
42
42
|
| Step | Tool |
|
|
43
43
|
|------|------|
|
|
@@ -53,13 +53,13 @@ ZIGGS_OPERATOR_KEY=<agent-scoped> node scripts/smoke-ziggs-mcp-z430-e2e.mjs
|
|
|
53
53
|
|
|
54
54
|
---
|
|
55
55
|
|
|
56
|
-
## claude.ai / remote MCP (OAuth
|
|
56
|
+
## claude.ai / remote MCP (OAuth)
|
|
57
57
|
|
|
58
58
|
Hosted Streamable HTTP: `https://mcp.ziggsai.com/mcp` (Bearer from OAuth, no key paste).
|
|
59
59
|
|
|
60
60
|
OAuth metadata: `https://api.ziggsai.com/.well-known/oauth-authorization-server`
|
|
61
61
|
|
|
62
|
-
**Consent
|
|
62
|
+
**Consent:** `GET /oauth/authorize` always redirects to `/app/oauth/mcp-consent` — even if you already have an API session. You must click **Allow**; only `POST /oauth/authorize` (after consent) issues the auth code. E2E smoke uses POST directly (same as the consent page).
|
|
63
63
|
|
|
64
64
|
Automated E2E (DCR → consent → token → remote MCP → list chats + send message):
|
|
65
65
|
|
|
@@ -72,19 +72,19 @@ ZIGGS_SMOKE_EMAIL=you@example.com ZIGGS_SMOKE_PASSWORD=... \
|
|
|
72
72
|
node scripts/smoke-ziggs-mcp-oauth-z468-e2e.mjs
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
-
**
|
|
75
|
+
**Consent probe** (GET must redirect to consent, not issue code):
|
|
76
76
|
|
|
77
77
|
```bash
|
|
78
78
|
node scripts/smoke-ziggs-mcp-oauth-z474-consent-probe.mjs --auto
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
-
**Manual claude.ai connector
|
|
81
|
+
**Manual claude.ai connector:** step-by-step checklist — [`examples/claude-ai-oauth.md`](examples/claude-ai-oauth.md).
|
|
82
82
|
|
|
83
83
|
---
|
|
84
84
|
|
|
85
85
|
## Cursor
|
|
86
86
|
|
|
87
|
-
### Remote OAuth (
|
|
87
|
+
### Remote OAuth (same path as claude.ai)
|
|
88
88
|
|
|
89
89
|
Add to `.cursor/mcp.json` or `~/.cursor/mcp.json`:
|
|
90
90
|
|
|
@@ -157,34 +157,34 @@ Startup validates the key shape, expiry (JWT `exp`), and agent resolution — er
|
|
|
157
157
|
From the **repository root** ([github.com/ZiggsAI/agentplus](https://github.com/ZiggsAI/agentplus)):
|
|
158
158
|
|
|
159
159
|
```bash
|
|
160
|
-
#
|
|
160
|
+
# basic boarding smoke
|
|
161
161
|
ZIGGS_OPERATOR_KEY=... ZIGGS_AGENT_ID=cursor-delegate \
|
|
162
162
|
node scripts/smoke-ziggs-mcp.mjs
|
|
163
163
|
|
|
164
|
-
#
|
|
164
|
+
# two delegates + negative 403
|
|
165
165
|
ZIGGS_OPERATOR_KEY_A=... ZIGGS_AGENT_ID_A=... \
|
|
166
166
|
ZIGGS_OPERATOR_KEY_B=... ZIGGS_AGENT_ID_B=... \
|
|
167
167
|
ZIGGS_SMOKE_CHAT_ID=... \
|
|
168
168
|
node scripts/smoke-ziggs-mcp-context.mjs
|
|
169
169
|
|
|
170
|
-
#
|
|
170
|
+
# tools-only (npx trust tools after publish)
|
|
171
171
|
ZIGGS_OPERATOR_KEY=<agent-scoped> node scripts/smoke-ziggs-mcp-z433-e2e.mjs --tools-only
|
|
172
172
|
|
|
173
|
-
#
|
|
173
|
+
# auto two-org (provisions users/agents/chat, then full flow)
|
|
174
174
|
HTTP_URL=https://api.ziggsai.com node scripts/smoke-ziggs-mcp-z433-e2e.mjs --auto
|
|
175
175
|
|
|
176
|
-
#
|
|
176
|
+
# full two-org (manual env)
|
|
177
177
|
ZIGGS_OPERATOR_KEY_A=... ZIGGS_AGENT_ID_A=... \
|
|
178
178
|
ZIGGS_OPERATOR_KEY_B=... ZIGGS_AGENT_ID_B=... \
|
|
179
179
|
ZIGGS_APPROVER_OPERATOR_KEY=... ZIGGS_APPROVER_USER_ID=... \
|
|
180
180
|
ZIGGS_SMOKE_CHAT_ID=... \
|
|
181
181
|
node scripts/smoke-ziggs-mcp-z433-e2e.mjs
|
|
182
182
|
|
|
183
|
-
#
|
|
183
|
+
# party handshake (link agreement, prod)
|
|
184
184
|
HTTP_URL=https://api.ziggsai.com \
|
|
185
185
|
OP_KEY_A=... AGENT_A=... USER_B=... OP_KEY_B=... AGENT_B=... \
|
|
186
186
|
npm run smoke:zig-481-prod
|
|
187
|
-
# Runbook: docs/evals/party-connection-two-claude.md
|
|
187
|
+
# Runbook: docs/evals/party-connection-two-claude.md
|
|
188
188
|
```
|
|
189
189
|
|
|
190
190
|
---
|
|
@@ -193,19 +193,19 @@ OP_KEY_A=... AGENT_A=... USER_B=... OP_KEY_B=... AGENT_B=... \
|
|
|
193
193
|
|
|
194
194
|
| Tool | Maps to |
|
|
195
195
|
|------|---------|
|
|
196
|
-
| `ziggs_inbox` | `GET /inbox` + `POST /inbox/ack`
|
|
196
|
+
| `ziggs_inbox` | `GET /inbox` + `POST /inbox/ack` |
|
|
197
197
|
| `ziggs_discover_context` | `GET /context/discovery` |
|
|
198
198
|
| `ziggs_read_context` | `GET /context/read/:type` |
|
|
199
199
|
| `ziggs_record_artifact` | `POST /artifacts` |
|
|
200
|
-
| `ziggs_search_agents` | Agent search
|
|
201
|
-
| `ziggs_list_my_grants` | `GET /context/grants` |
|
|
200
|
+
| `ziggs_search_agents` | Agent search |
|
|
202
201
|
| `ziggs_issue_grant` | Chat admission or `POST /context/grants` |
|
|
203
202
|
| `ziggs_delegate_grant` | `POST /context/grants/:id/delegate` |
|
|
204
203
|
| `ziggs_revoke_grant` | `DELETE /context/grants/:id` |
|
|
205
|
-
| `ziggs_request_link` | `POST /agreements` `{engagementKind:"link"}` (
|
|
204
|
+
| `ziggs_request_link` | `POST /agreements` `{engagementKind:"link"}` (a link is just an agreement) |
|
|
206
205
|
| `ziggs_list_links` | `GET /agreements?engagementKind=link` |
|
|
207
|
-
| `ziggs_revoke_link` | `DELETE /agreements/:agreementId` |
|
|
208
|
-
| `
|
|
206
|
+
| `ziggs_revoke_link` | `DELETE /agreements/:agreementId` (see also `ziggs_revoke_agreement`) |
|
|
207
|
+
| `ziggs_revoke_agreement` | `DELETE /agreements/:id` — any agreement (hire/service/quest/link) |
|
|
208
|
+
| `ziggs_smoke_impersonation` | [Internal/debug] connectivity check — not part of normal delegate workflow |
|
|
209
209
|
| `ziggs_get_scope` | `GET /scope?via=` |
|
|
210
210
|
| `ziggs_list_my_agreements` | `GET /agreements?scope=mine` |
|
|
211
211
|
| `ziggs_get_agreement` | `GET /agreements/:id` |
|
package/dist/config.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ declare const envSchema: z.ZodObject<{
|
|
|
8
8
|
ZIGGS_OPERATOR_KEY: z.ZodString;
|
|
9
9
|
/** Optional when the operator key is agent-scoped (ZIG-279). */
|
|
10
10
|
ZIGGS_AGENT_ID: z.ZodOptional<z.ZodString>;
|
|
11
|
-
/** Human user id for payer-side proposals
|
|
11
|
+
/** Human user id for payer-side proposals — defaults the payer on propose/publish tools. */
|
|
12
12
|
ZIGGS_OWNER_USER_ID: z.ZodOptional<z.ZodString>;
|
|
13
13
|
}, "strip", z.ZodTypeAny, {
|
|
14
14
|
ZIGGS_OPERATOR_KEY: string;
|
package/dist/config.js
CHANGED
|
@@ -9,7 +9,7 @@ const envSchema = z.object({
|
|
|
9
9
|
ZIGGS_OPERATOR_KEY: z.string().min(1, 'ZIGGS_OPERATOR_KEY is required'),
|
|
10
10
|
/** Optional when the operator key is agent-scoped (ZIG-279). */
|
|
11
11
|
ZIGGS_AGENT_ID: z.string().optional(),
|
|
12
|
-
/** Human user id for payer-side proposals
|
|
12
|
+
/** Human user id for payer-side proposals — defaults the payer on propose/publish tools. */
|
|
13
13
|
ZIGGS_OWNER_USER_ID: z.string().optional(),
|
|
14
14
|
});
|
|
15
15
|
/** Load delegate credentials from the environment (ZIG-222 / ZIG-430). */
|
|
@@ -9,6 +9,15 @@ export interface ReadPlanCall {
|
|
|
9
9
|
args: Record<string, unknown>;
|
|
10
10
|
why: string;
|
|
11
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* ZIG-660: buildReadPlan returns the (bounded, deduped) plan plus how many
|
|
14
|
+
* candidate entries the cap dropped, so the caller can surface truncation
|
|
15
|
+
* explicitly instead of the plan silently ending short.
|
|
16
|
+
*/
|
|
17
|
+
export interface ReadPlanResult {
|
|
18
|
+
plan: ReadPlanCall[];
|
|
19
|
+
truncated: number;
|
|
20
|
+
}
|
|
12
21
|
/**
|
|
13
22
|
* ZIG-634: replace the free-text `nextActions` hints with typed `readPlan`
|
|
14
23
|
* call objects — tool name + pre-filled args — so the most common loop
|
|
@@ -23,7 +32,7 @@ export interface ReadPlanCall {
|
|
|
23
32
|
* artifacts via chat or agreement. For multi-chat scopes (org / agreement) we
|
|
24
33
|
* use the per-chat breakdown (ZIG-543) to name the chatIds.
|
|
25
34
|
*/
|
|
26
|
-
export declare function buildReadPlan(inbox: InboxEnvelope):
|
|
35
|
+
export declare function buildReadPlan(inbox: InboxEnvelope, grantsByScope?: Map<string, ScopeGrantTag>): ReadPlanResult;
|
|
27
36
|
/**
|
|
28
37
|
* ZIG-634: forward-continuation for a read_context page. Built only from fields
|
|
29
38
|
* already on the page (via, hasMore/nextCursor, latestSequence) plus the grant
|
package/dist/inboxToolResult.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { formatPendingDecisionsPayload, resolveWebAppOrigin, } from './pendingDecisions.js';
|
|
2
2
|
/** Keep the plan bounded; the full scopes array still carries everything. */
|
|
3
3
|
const MAX_READ_PLAN = 12;
|
|
4
|
-
function readContextCall(type, kind, id) {
|
|
4
|
+
function readContextCall(type, kind, id, grantId) {
|
|
5
|
+
// ZIG-660: pin the covering grant so the read presents the right
|
|
6
|
+
// X-Context-Grant-Id without a separate discover_context round-trip.
|
|
7
|
+
const grant = grantId ? { contextGrantId: grantId } : {};
|
|
5
8
|
return {
|
|
6
9
|
tool: 'ziggs_read_context',
|
|
7
|
-
args: { type, via: `${kind}:${id}
|
|
10
|
+
args: { type, via: `${kind}:${id}`, ...grant },
|
|
8
11
|
why: `open the ${type} behind the count on ${kind}:${id}`,
|
|
9
12
|
};
|
|
10
13
|
}
|
|
@@ -22,59 +25,69 @@ function readContextCall(type, kind, id) {
|
|
|
22
25
|
* artifacts via chat or agreement. For multi-chat scopes (org / agreement) we
|
|
23
26
|
* use the per-chat breakdown (ZIG-543) to name the chatIds.
|
|
24
27
|
*/
|
|
25
|
-
export function buildReadPlan(inbox) {
|
|
26
|
-
const plan = [];
|
|
28
|
+
export function buildReadPlan(inbox, grantsByScope) {
|
|
27
29
|
const proposals = inbox.proposalsAwaitingMe ?? [];
|
|
28
30
|
const connectionRequests = inbox.connectionRequestsAwaitingMe ?? [];
|
|
29
31
|
const scopes = inbox.scopes ?? [];
|
|
32
|
+
// ZIG-660: dedup by call signature so the same (type, via) can't appear
|
|
33
|
+
// twice when one chat is covered by both its own grant and an org/agreement
|
|
34
|
+
// grant. Collect candidates uncapped; the cap is applied once, after the ack
|
|
35
|
+
// is reserved, so the ack step always survives.
|
|
36
|
+
const candidates = [];
|
|
37
|
+
const seen = new Set();
|
|
38
|
+
const add = (key, call) => {
|
|
39
|
+
if (seen.has(key))
|
|
40
|
+
return;
|
|
41
|
+
seen.add(key);
|
|
42
|
+
candidates.push(call);
|
|
43
|
+
};
|
|
30
44
|
// Decisions first — these also drive humanAttention (pull-only: no push).
|
|
31
45
|
// The decision (approve/reject) is the human's; we only pre-fill the target.
|
|
32
46
|
for (const p of proposals) {
|
|
33
|
-
|
|
34
|
-
break;
|
|
35
|
-
plan.push({
|
|
47
|
+
add(`respond:${p.agreementId}`, {
|
|
36
48
|
tool: 'ziggs_respond_to_agreement',
|
|
37
49
|
args: { agreementId: p.agreementId },
|
|
38
50
|
why: 'agreement proposal awaiting your response — wait for the human to approve/reject',
|
|
39
51
|
});
|
|
40
52
|
}
|
|
41
53
|
for (const c of connectionRequests) {
|
|
42
|
-
|
|
43
|
-
break;
|
|
44
|
-
plan.push({
|
|
54
|
+
add(`respond:${c.requestId}`, {
|
|
45
55
|
tool: 'ziggs_respond_to_agreement',
|
|
46
56
|
args: { agreementId: c.requestId },
|
|
47
57
|
why: 'connection request awaiting your response — wait for the human to approve/reject',
|
|
48
58
|
});
|
|
49
59
|
}
|
|
60
|
+
// The covering grant for reads derived from a scope is that scope's own grant
|
|
61
|
+
// (ZIG-635) — the same grant tagged onto the scope entry.
|
|
62
|
+
const grantFor = (s) => grantsByScope?.get(`${s.scope.kind}:${s.scope.id}`)?.grantId;
|
|
50
63
|
// Reads — point each scope's news at the call that opens it.
|
|
51
64
|
for (const s of scopes) {
|
|
52
|
-
if (plan.length >= MAX_READ_PLAN)
|
|
53
|
-
break;
|
|
54
65
|
const { kind, id } = s.scope;
|
|
66
|
+
const grantId = grantFor(s);
|
|
67
|
+
const read = (type, viaKind, viaId) => add(`read:${type}:${viaKind}:${viaId}`, readContextCall(type, viaKind, viaId, grantId));
|
|
55
68
|
if (kind === 'chat') {
|
|
56
69
|
if (s.newMessages)
|
|
57
|
-
|
|
70
|
+
read('messages', 'chat', id);
|
|
58
71
|
if (s.newArtifacts)
|
|
59
|
-
|
|
72
|
+
read('artifacts', 'chat', id);
|
|
60
73
|
}
|
|
61
74
|
else if (kind === 'agreement') {
|
|
62
75
|
// Messages resolve only via chat — name the chats from the breakdown.
|
|
63
76
|
for (const c of s.chats ?? []) {
|
|
64
77
|
if (c.newMessages)
|
|
65
|
-
|
|
78
|
+
read('messages', 'chat', c.chatId);
|
|
66
79
|
}
|
|
67
80
|
// Artifacts (incl. task-result artifacts) read directly via the agreement.
|
|
68
81
|
if (s.newArtifacts)
|
|
69
|
-
|
|
82
|
+
read('artifacts', 'agreement', id);
|
|
70
83
|
}
|
|
71
84
|
else {
|
|
72
85
|
// org: both messages and artifacts resolve per chat only.
|
|
73
86
|
for (const c of s.chats ?? []) {
|
|
74
87
|
if (c.newMessages)
|
|
75
|
-
|
|
88
|
+
read('messages', 'chat', c.chatId);
|
|
76
89
|
if (c.newArtifacts)
|
|
77
|
-
|
|
90
|
+
read('artifacts', 'chat', c.chatId);
|
|
78
91
|
}
|
|
79
92
|
}
|
|
80
93
|
}
|
|
@@ -83,14 +96,21 @@ export function buildReadPlan(inbox) {
|
|
|
83
96
|
const ackTargets = scopes
|
|
84
97
|
.filter((s) => s.latestAt)
|
|
85
98
|
.map((s) => ({ kind: s.scope.kind, id: s.scope.id, upTo: s.latestAt }));
|
|
86
|
-
|
|
99
|
+
// ZIG-660: reserve a slot for the ack before capping, so the pre-filled ack
|
|
100
|
+
// never gets squeezed out exactly when there's the most news. Report how many
|
|
101
|
+
// read/decision candidates the cap dropped as an explicit count.
|
|
102
|
+
const reserve = ackTargets.length ? 1 : 0;
|
|
103
|
+
const budget = Math.max(0, MAX_READ_PLAN - reserve);
|
|
104
|
+
const truncated = Math.max(0, candidates.length - budget);
|
|
105
|
+
const plan = candidates.slice(0, budget);
|
|
106
|
+
if (ackTargets.length) {
|
|
87
107
|
plan.push({
|
|
88
108
|
tool: 'ziggs_inbox',
|
|
89
109
|
args: { ack: ackTargets },
|
|
90
110
|
why: 'reading does not clear the inbox — ack the scopes you handled (drop any you did not)',
|
|
91
111
|
});
|
|
92
112
|
}
|
|
93
|
-
return plan
|
|
113
|
+
return { plan, truncated };
|
|
94
114
|
}
|
|
95
115
|
/**
|
|
96
116
|
* ZIG-634: forward-continuation for a read_context page. Built only from fields
|
|
@@ -169,10 +189,9 @@ export function indexReachByScope(reach) {
|
|
|
169
189
|
* matching live grant (e.g. reachable via membership, not a grant) are left
|
|
170
190
|
* untagged — the agent keeps navigating by id, never a fabricated grant.
|
|
171
191
|
*/
|
|
172
|
-
function tagScopesWithGrants(scopes,
|
|
173
|
-
if (!
|
|
192
|
+
function tagScopesWithGrants(scopes, byScope) {
|
|
193
|
+
if (!byScope?.size)
|
|
174
194
|
return scopes;
|
|
175
|
-
const byScope = indexReachByScope(reach);
|
|
176
195
|
return scopes.map((s) => {
|
|
177
196
|
const tag = byScope.get(`${s.scope.kind}:${s.scope.id}`);
|
|
178
197
|
return tag ? { ...s, grant: tag } : s;
|
|
@@ -187,8 +206,12 @@ function tagScopesWithGrants(scopes, reach) {
|
|
|
187
206
|
* with its covering grant (ZIG-635) so the agent can pin X-Context-Grant-Id.
|
|
188
207
|
*/
|
|
189
208
|
export function formatInboxToolResult(inbox, ack, webOrigin, activeTasks, reach) {
|
|
190
|
-
|
|
191
|
-
|
|
209
|
+
// ZIG-660: build the grant index once and feed both the read plan (grant
|
|
210
|
+
// pinning) and the scope tags from it — buildReadPlan no longer runs before
|
|
211
|
+
// the grants are available.
|
|
212
|
+
const byScope = reach?.length ? indexReachByScope(reach) : undefined;
|
|
213
|
+
const { plan: readPlan, truncated: readPlanTruncated } = buildReadPlan(inbox, byScope);
|
|
214
|
+
const scopes = tagScopesWithGrants(inbox.scopes ?? [], byScope);
|
|
192
215
|
const origin = resolveWebAppOrigin(webOrigin);
|
|
193
216
|
const pending = formatPendingDecisionsPayload(inbox, origin, { activeTasks });
|
|
194
217
|
const pendingTail = pending.hasActionable === true
|
|
@@ -201,7 +224,11 @@ export function formatInboxToolResult(inbox, ack, webOrigin, activeTasks, reach)
|
|
|
201
224
|
...(pending.workChatCard ? { workChatCard: pending.workChatCard } : {}),
|
|
202
225
|
}
|
|
203
226
|
: {};
|
|
204
|
-
const tail = {
|
|
227
|
+
const tail = {
|
|
228
|
+
...pendingTail,
|
|
229
|
+
...(readPlan.length ? { readPlan } : {}),
|
|
230
|
+
...(readPlanTruncated ? { readPlanTruncated } : {}),
|
|
231
|
+
};
|
|
205
232
|
const { humanAttention, ...rest } = inbox;
|
|
206
233
|
const payload = ack
|
|
207
234
|
? { acked: ack.acked, ...rest, scopes, ...tail }
|
package/dist/operatorKey.d.ts
CHANGED
package/dist/operatorKey.js
CHANGED
package/dist/pendingDecisions.js
CHANGED
|
@@ -35,10 +35,11 @@ function formatWhen(iso) {
|
|
|
35
35
|
});
|
|
36
36
|
}
|
|
37
37
|
function planProgress(plan) {
|
|
38
|
-
|
|
38
|
+
const steps = plan?.steps;
|
|
39
|
+
if (!steps?.length)
|
|
39
40
|
return { done: 0, total: 0 };
|
|
40
|
-
const total =
|
|
41
|
-
const done =
|
|
41
|
+
const total = steps.length;
|
|
42
|
+
const done = steps.filter((s) => s.status === 'completed' || s.status === 'skipped').length;
|
|
42
43
|
return { done, total };
|
|
43
44
|
}
|
|
44
45
|
function proposalToItem(p, origin) {
|
|
@@ -86,7 +87,7 @@ export function buildPendingDecisionItems(inbox, webOrigin) {
|
|
|
86
87
|
}
|
|
87
88
|
export function buildActiveWorkItems(tasks, webOrigin) {
|
|
88
89
|
return tasks
|
|
89
|
-
.filter((t) => t.state === 'active'
|
|
90
|
+
.filter((t) => t.state === 'active')
|
|
90
91
|
.slice(0, ACTIVE_TASK_LIMIT)
|
|
91
92
|
.map((t) => {
|
|
92
93
|
const { done, total } = planProgress(t.plan);
|
|
@@ -98,7 +99,6 @@ export function buildActiveWorkItems(tasks, webOrigin) {
|
|
|
98
99
|
state: t.state,
|
|
99
100
|
planDone: done,
|
|
100
101
|
planTotal: total,
|
|
101
|
-
processing: t.processing === true,
|
|
102
102
|
appUrl: agreementId ? agreementAppUrl(webOrigin, agreementId) : null,
|
|
103
103
|
sayWork: `work on ${t.taskId}`,
|
|
104
104
|
};
|
|
@@ -170,8 +170,6 @@ function buildWorkSection(work, startIndex = 1) {
|
|
|
170
170
|
meta.push(`agreement \`${item.agreementId}\``);
|
|
171
171
|
if (item.planTotal > 0)
|
|
172
172
|
meta.push(`Plan **${item.planDone}/${item.planTotal}**`);
|
|
173
|
-
if (item.processing)
|
|
174
|
-
meta.push('_processing_');
|
|
175
173
|
lines.push(meta.join(' · '));
|
|
176
174
|
lines.push('');
|
|
177
175
|
lines.push('_Assigned work under an active agreement — implement, test, and report back via artifact or chat. Approve the agreement first if it is still pending._');
|
|
@@ -39,7 +39,7 @@ export declare const PROTOCOL: {
|
|
|
39
39
|
*/
|
|
40
40
|
export declare const PROTOCOL_RULES: readonly string[];
|
|
41
41
|
/** HTML-comment markers delimiting the generated region in a markdown file. */
|
|
42
|
-
export declare const PROTOCOL_BLOCK_BEGIN = "<!-- BEGIN GENERATED: delegate-protocol \u2014 edit src/protocol/delegateProtocol.ts, run `npm run gen:protocol`
|
|
42
|
+
export declare const PROTOCOL_BLOCK_BEGIN = "<!-- BEGIN GENERATED: delegate-protocol \u2014 edit src/protocol/delegateProtocol.ts, run `npm run gen:protocol` -->";
|
|
43
43
|
export declare const PROTOCOL_BLOCK_END = "<!-- END GENERATED: delegate-protocol -->";
|
|
44
44
|
/**
|
|
45
45
|
* Server `instructions` string (ZIG-552/A1 consumes this). Plain text so any
|
|
@@ -48,7 +48,7 @@ export const PROTOCOL_RULES = [
|
|
|
48
48
|
PROTOCOL.untrusted,
|
|
49
49
|
];
|
|
50
50
|
/** HTML-comment markers delimiting the generated region in a markdown file. */
|
|
51
|
-
export const PROTOCOL_BLOCK_BEGIN = '<!-- BEGIN GENERATED: delegate-protocol — edit src/protocol/delegateProtocol.ts, run `npm run gen:protocol`
|
|
51
|
+
export const PROTOCOL_BLOCK_BEGIN = '<!-- BEGIN GENERATED: delegate-protocol — edit src/protocol/delegateProtocol.ts, run `npm run gen:protocol` -->';
|
|
52
52
|
export const PROTOCOL_BLOCK_END = '<!-- END GENERATED: delegate-protocol -->';
|
|
53
53
|
/**
|
|
54
54
|
* Server `instructions` string (ZIG-552/A1 consumes this). Plain text so any
|
|
@@ -70,7 +70,7 @@ export function renderProtocolBlock() {
|
|
|
70
70
|
/** `.cursorrules` body (ZIG-568/D1 ships placement; generated from here). */
|
|
71
71
|
export function renderCursorRules() {
|
|
72
72
|
return [
|
|
73
|
-
'# Ziggs delegate protocol (generated
|
|
73
|
+
'# Ziggs delegate protocol (generated)',
|
|
74
74
|
'# Source: ziggs-mcp/src/protocol/delegateProtocol.ts — run `npm run gen:protocol` to update.',
|
|
75
75
|
'',
|
|
76
76
|
PROTOCOL.tagline,
|