@paigy/mcp 0.40.7 → 0.40.9
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/{chunk-UZPBDJ37.js → chunk-5OY6ED2Q.js} +80 -2740
- package/dist/{chunk-RJV6U6U4.js → chunk-LYPZ5QO2.js} +9 -43
- package/dist/{chunk-4XG3YLGY.js → chunk-UFOR2QEP.js} +53 -152
- package/dist/{chunk-CAKRIAGP.js → chunk-UOROFXDI.js} +2 -2
- package/dist/enable.js +3 -3
- package/dist/index.js +6 -23
- package/dist/listen.js +3 -6
- package/dist/onboard.js +4 -7
- package/dist/slot.js +1 -1
- package/dist/statusline.js +1 -1
- package/package.json +2 -3
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
|
-
deleteKeyFile,
|
|
3
|
-
fetchCredential,
|
|
4
|
-
finalizeE2ee,
|
|
5
2
|
isNetworkError,
|
|
6
|
-
|
|
7
|
-
readKeyFile,
|
|
3
|
+
pollToken,
|
|
8
4
|
requestCode,
|
|
9
|
-
saveKeyFile,
|
|
10
5
|
saveToken,
|
|
11
|
-
sleep
|
|
12
|
-
|
|
13
|
-
} from "./chunk-UZPBDJ37.js";
|
|
6
|
+
sleep
|
|
7
|
+
} from "./chunk-5OY6ED2Q.js";
|
|
14
8
|
|
|
15
9
|
// src/identity.ts
|
|
16
10
|
var CLIENT_LABELS = {
|
|
@@ -34,12 +28,14 @@ function suggestedAgentName(clientName) {
|
|
|
34
28
|
|
|
35
29
|
// src/pairing.ts
|
|
36
30
|
async function resolvePairing(deviceCode, capMs, pollMs = 2e3) {
|
|
37
|
-
let kf = readKeyFile();
|
|
38
31
|
const start = Date.now();
|
|
39
32
|
while (Date.now() - start < capMs) {
|
|
40
|
-
let step;
|
|
41
33
|
try {
|
|
42
|
-
|
|
34
|
+
const token = await pollToken(deviceCode);
|
|
35
|
+
if (token) {
|
|
36
|
+
saveToken(token);
|
|
37
|
+
return { kind: "paired", token };
|
|
38
|
+
}
|
|
43
39
|
} catch (e) {
|
|
44
40
|
if (isNetworkError(e)) {
|
|
45
41
|
await sleep(pollMs);
|
|
@@ -47,34 +43,6 @@ async function resolvePairing(deviceCode, capMs, pollMs = 2e3) {
|
|
|
47
43
|
}
|
|
48
44
|
return { kind: "error", message: e.message };
|
|
49
45
|
}
|
|
50
|
-
if (step.kind === "e2ee_aborted") {
|
|
51
|
-
deleteKeyFile();
|
|
52
|
-
kf = null;
|
|
53
|
-
await sleep(pollMs);
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
if (step.kind === "awaiting_confirm") {
|
|
57
|
-
return { kind: "awaiting_confirm", sas: step.sas };
|
|
58
|
-
}
|
|
59
|
-
if (step.kind === "paired") {
|
|
60
|
-
saveToken(step.token);
|
|
61
|
-
if (!step.sas || !kf) {
|
|
62
|
-
deleteKeyFile();
|
|
63
|
-
return { kind: "paired", token: step.token };
|
|
64
|
-
}
|
|
65
|
-
const finalDeadline = Math.min(Date.now() + 1e4, start + capMs);
|
|
66
|
-
let e2ee = false;
|
|
67
|
-
while (Date.now() < finalDeadline) {
|
|
68
|
-
const cred = kf.userCode ? await fetchCredential(kf.userCode) : null;
|
|
69
|
-
if (cred && step.uikPub) {
|
|
70
|
-
e2ee = finalizeE2ee(kf, cred, step.uikPub);
|
|
71
|
-
break;
|
|
72
|
-
}
|
|
73
|
-
await sleep(pollMs);
|
|
74
|
-
}
|
|
75
|
-
if (!e2ee) deleteKeyFile();
|
|
76
|
-
return { kind: "paired", token: step.token, sas: step.sas, e2ee };
|
|
77
|
-
}
|
|
78
46
|
await sleep(pollMs);
|
|
79
47
|
}
|
|
80
48
|
return { kind: "pending" };
|
|
@@ -83,15 +51,13 @@ var bg = null;
|
|
|
83
51
|
var started = null;
|
|
84
52
|
async function startPairing(agent) {
|
|
85
53
|
if (started) return started;
|
|
86
|
-
const
|
|
87
|
-
const code = await requestCode(agent, offer);
|
|
54
|
+
const code = await requestCode(agent);
|
|
88
55
|
started = {
|
|
89
56
|
verificationUri: code.verification_uri_complete,
|
|
90
57
|
userCode: code.user_code,
|
|
91
58
|
deviceCode: code.device_code,
|
|
92
59
|
expiresIn: code.expires_in
|
|
93
60
|
};
|
|
94
|
-
saveKeyFile({ ...keyFile, userCode: code.user_code });
|
|
95
61
|
startBackgroundPair(code.device_code, code.expires_in * 1e3);
|
|
96
62
|
return started;
|
|
97
63
|
}
|
|
@@ -34,41 +34,39 @@ function mcpInputSchema(s) {
|
|
|
34
34
|
delete schema.$schema;
|
|
35
35
|
return draft2020(schema);
|
|
36
36
|
}
|
|
37
|
-
var
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
// A DecisionNeed is settled only by an answer in the shape THIS ask declares. Bundle news,
|
|
42
|
-
// findings and a decision into one, and the person answers whichever part engaged them —
|
|
43
|
-
// which settles nothing, leaves the need open, and gets them asked again. On call 619c5a92
|
|
44
|
-
// one ask carried a briefing, a side question ("the ring should show the agent's name now —
|
|
45
|
-
// what did you actually see?") and a one-of-four about how far an erase reaches. The owner
|
|
46
|
-
// answered the side question. The need stayed open; the card asked again. Of the 45 call
|
|
47
|
-
// asks carrying a decision, 27 are over 600 characters.
|
|
48
|
-
//
|
|
49
|
-
// Sending them separately costs nothing, because a CALL contact joins the call already
|
|
50
|
-
// happening (`goal/store.ts`, JOIN BEFORE MINTING) — several contacts on one Goal arrive as
|
|
51
|
-
// one call, planned as its turns, and each keeps its own settleable need.
|
|
37
|
+
var AskInputSchema = z.object({
|
|
38
|
+
id: z.string().optional().describe("Optional idempotency key or client-side ID for this specific ask."),
|
|
39
|
+
parentId: z.string().uuid().optional().describe("Optional explicit parent Goal ID. If omitted, the platform's semantic router will auto-cluster it."),
|
|
40
|
+
repo: z.string().optional().describe("Optional repository context."),
|
|
52
41
|
ask: z.string().trim().min(1).max(1e4).describe(
|
|
53
42
|
"The question, and only what is needed to answer it. News, progress and findings are their own contact \u2014 a call contact JOINS a call already happening, so several arrive as one call. Do not bundle: a DecisionNeed is settled only by an answer in the shape this ask declares, so someone who answers the part that interested them settles nothing and is asked again."
|
|
54
43
|
),
|
|
44
|
+
options: z.array(z.object({
|
|
45
|
+
label: z.string().trim().min(1).max(1e3),
|
|
46
|
+
hint: z.string().trim().max(500).describe("Optional short projection of consequence or action if this option is chosen.").optional(),
|
|
47
|
+
image: z.string().url().optional(),
|
|
48
|
+
html: z.string().max(16384).describe("Optional sandboxed HTML/CSS preview. No JavaScript or network; inline CSS and data: URIs only. It renders edge-to-edge in a responsive card 200pt tall (about 320pt wide on a phone, with the next option peeking beside it), so fit the HTML to that viewport.").optional()
|
|
49
|
+
}).strict()).min(2).max(6).optional()
|
|
50
|
+
}).strict();
|
|
51
|
+
var StartContactSchema = z.object({
|
|
52
|
+
asks: z.array(AskInputSchema).min(1).describe("The list of asks/questions to pose. They will be semantically clustered by the API."),
|
|
55
53
|
waiting: z.enum(["none", "hard"]).default("none"),
|
|
56
|
-
channel: z.enum(["notification", "call"]).default("notification")
|
|
57
|
-
options: z.array(z.object({ label: z.string().trim().min(1).max(1e3), image: z.string().url().optional(), html: z.string().max(16384).optional() }).strict()).min(2).max(6).optional(),
|
|
58
|
-
threadId: z.string().uuid().optional().describe("Continue an existing Thread: the threadId a prior Delivery returned. Omit to start a new Thread.")
|
|
54
|
+
channel: z.enum(["notification", "call"]).default("notification")
|
|
59
55
|
}).strict();
|
|
60
56
|
var ContactSchema = z.union([StartContactSchema, z.object({ deliveryId: z.string().uuid() }).strict()]);
|
|
61
57
|
var CONTACT_SCHEMA = { type: "object", ...mcpInputSchema(ContactSchema) };
|
|
62
|
-
var CONTACT_DESCRIPTION = "Contact the user
|
|
58
|
+
var CONTACT_DESCRIPTION = "Contact the user with one or more asks/questions. Pass an array of asks (each with 'ask', optional 'options', 'id', 'parentId', 'repo'), plus channel:'notification'|'call', and waiting:'none'|'hard'. The platform will semantically cluster your asks under the correct Goals automatically. Notification returns immediately; collect durable answers with check_replies. On stdio, a Call holds one cancellable ~45s window; continue with ONLY {deliveryId}. Never bundle multiple questions into a single 'ask' string; pass them as separate objects in the 'asks' array.";
|
|
63
59
|
var CreateGoalSchema = z2.object({
|
|
64
60
|
outcome: z2.string().trim().min(1).max(1e4),
|
|
61
|
+
/** The work's NAME (#2115) — one to five words, how a person refers to it out loud ("the night
|
|
62
|
+
* rings"). Omit it and the brain writes one at admission from the outcome. */
|
|
63
|
+
title: z2.string().trim().min(1).max(80).optional(),
|
|
65
64
|
ownerParticipant: z2.string().trim().min(1).optional(),
|
|
66
65
|
idempotencyKey: z2.string().trim().min(1).max(200),
|
|
67
66
|
/** A past conversation this Goal should be read against — History's "new session from this"
|
|
68
67
|
* (owner, on the call of 2026-09-14: "let's do the reference with the threading"). A
|
|
69
68
|
* reference only: the owner reads it through `get_thread`, which does its own scoping, and
|
|
70
69
|
* the writer refuses a thread belonging to another account. */
|
|
71
|
-
contextThreadId: z2.string().uuid().optional(),
|
|
72
70
|
/** THE GOAL THIS ONE BELONGS UNDER (owner, 2026-09-15: "the ask I gave for the design doc
|
|
73
71
|
* didn't get created as a child goal of the voice UI goal, which is how it should've
|
|
74
72
|
* worked"). It could not have been: this door took no parent, so the only route was
|
|
@@ -76,16 +74,22 @@ var CreateGoalSchema = z2.object({
|
|
|
76
74
|
* took the short one. The hierarchy has been modelled since Goals existed and had been used
|
|
77
75
|
* ZERO times in 2,031 of them. Absent, the server judges it against the caller's open Goals
|
|
78
76
|
* (`apps/api/src/goal/intake.ts`). The writer refuses a Goal belonging to another account. */
|
|
79
|
-
parentGoalId: z2.string().uuid().optional()
|
|
77
|
+
parentGoalId: z2.string().uuid().optional(),
|
|
78
|
+
/** The repository or project identifier this Goal belongs to (#2280) — e.g. "owner/repo" or
|
|
79
|
+
* repo name. Delegated work inherits this from its parent Goal when omitted. */
|
|
80
|
+
repo: z2.string().trim().min(1).max(200).optional()
|
|
80
81
|
});
|
|
81
82
|
var CreateGoalToolSchema = CreateGoalSchema.extend({
|
|
82
83
|
idempotencyKey: CreateGoalSchema.shape.idempotencyKey.optional().describe("Optional. One is minted per call; pass your own only so a retry lands on the same Goal.")
|
|
83
84
|
}).strict();
|
|
84
|
-
var CREATE_GOAL_DESCRIPTION =
|
|
85
|
+
var CREATE_GOAL_DESCRIPTION = 'Create a durable Goal for an outcome. Without parentGoalId it is placed against your open Goals: if one already IS this work, that Goal comes back (existing: true) and nothing new is created \u2014 continue it; if the work belongs under one, it is created there (parentGoalId in the receipt); otherwise it is a root. Pass parentGoalId yourself to put it under a specific Goal. Pass repo to anchor the work to a specific repository ("owner/repo" or repo name); delegated children inherit it. Pass title to name it in one to five words, as a person would refer to it out loud ("the night rings") \u2014 it heads every list and is spoken on a call; without one the brain writes it. Admission only: the owner must claim it before doing work, then update it as it advances. Returns an admission receipt with goalId, current state, revision, ownerParticipant, and the next step; no Goal content or execution lease.';
|
|
85
86
|
var UpdateGoalSchema = z2.object({
|
|
86
87
|
revision: z2.number().int().positive(),
|
|
87
88
|
changes: z2.object({
|
|
88
89
|
outcome: z2.string().trim().min(1).max(1e4).optional(),
|
|
90
|
+
/** The work's NAME (#2115) — one to five words, how a person refers to it out loud. The
|
|
91
|
+
* brain writes one at admission; this is the owner saying it better. Null clears it. */
|
|
92
|
+
title: z2.string().trim().min(1).max(80).nullable().optional(),
|
|
89
93
|
ownerParticipant: z2.string().trim().min(1).optional(),
|
|
90
94
|
parentGoalId: z2.string().uuid().nullable().optional(),
|
|
91
95
|
dependencies: z2.array(z2.object({ goalId: z2.string().uuid(), gate: z2.enum(["start", "finish"]) }).strict()).optional(),
|
|
@@ -102,7 +106,7 @@ var UpdateGoalToolSchema = UpdateGoalSchema.omit({ operationId: true }).extend({
|
|
|
102
106
|
var ClaimGoalSchema = z2.object({ goalId: z2.string().uuid().optional() }).strict();
|
|
103
107
|
var GetGoalSchema = z2.object({ goalId: z2.string().uuid() }).strict();
|
|
104
108
|
var GET_GOAL_DESCRIPTION = "Read one Goal without claiming it: its outcome, state, revision, progress, blockers, the conversation on it (each question with its options and what was decided), and `next`, the one step to take. Foreign or sibling-owned Goals are not disclosed.";
|
|
105
|
-
var UPDATE_GOAL_DESCRIPTION = "Update an owned Goal at an exact revision. State, ownership, dependencies, children, progress, and review acknowledgement are explicit; stale revisions are rejected. reviewed: true acknowledges new evidence and closes the Deliveries addressed to you on that Goal, never over an open decision. dueAt (an ISO instant, or null) makes the Goal wait until then; when it passes you are woken for it \u2014 use it for a promise to follow up later. Returns the Goal as get_goal reads it, at its new revision.";
|
|
109
|
+
var UPDATE_GOAL_DESCRIPTION = "Update an owned Goal at an exact revision. State, ownership, dependencies, children, progress, title, and review acknowledgement are explicit; stale revisions are rejected. title is the work's name in one to five words, as a person would refer to it out loud (it is spoken on a call and heads every list); null clears it. reviewed: true acknowledges new evidence and closes the Deliveries addressed to you on that Goal, never over an open decision. dueAt (an ISO instant, or null) makes the Goal wait until then; when it passes you are woken for it \u2014 use it for a promise to follow up later. Returns the Goal as get_goal reads it, at its new revision.";
|
|
106
110
|
var CLAIM_GOAL_DESCRIPTION = "Claim the oldest runnable or review-pending Goal you own, or pass goalId to claim that Goal. Returns the Goal as get_goal reads it, and creates or renews the execution lease.";
|
|
107
111
|
var CHECK_REPLIES_DESCRIPTION = "Your open Deliveries: every Notification or Call currently addressed to you \u2014 a request the user started toward you, an answer relayed to something you asked, a handoff \u2014 one row each: its Goals, how many decisions are still open, and the newest words in brief. A pure read with no arguments: nothing is consumed, acknowledged or claimed by reading it, so call it on startup, after a long wait, or whenever you want to know what is outstanding. To act on one, claim its Goal (claim_goal) or reread it in full with contact({deliveryId}). Once you have acted on what arrived, update_goal with reviewed: true closes the Deliveries addressed to you on that Goal. Your runnable and review-pending Goals come from claim_goal, not from here.";
|
|
108
112
|
var CheckRepliesSchema = z2.object({}).strict();
|
|
@@ -126,7 +130,13 @@ var AGENT_TOOLS = [
|
|
|
126
130
|
];
|
|
127
131
|
var AGENT_TOOL_NAMES = AGENT_TOOLS.map((t) => t.name);
|
|
128
132
|
function serverInstructions(_opts) {
|
|
129
|
-
return
|
|
133
|
+
return `On startup and after a wake, call check_replies for the open Deliveries addressed to you, and claim_goal for your runnable or review-pending Goal and the conversation on it. get_goal rereads it without claiming. Every read ends in \`next\`, the one step to take. Contact only for an existing Goal. Notifications return immediately: keep working and collect answers through claim_goal/get_goal. On stdio, Calls hold one bounded window; on hosted MCP, Calls return after one read; continue with contact({deliveryId}) to reread that exact Delivery. Evidence can repeat: reads do not acknowledge or hide it. Use update_goal to report progress and explicitly acknowledge review. Never infer ringing from an open Call Delivery. Soft waiting, multipart contact, and re-presentation are unsupported. Your user is remote. Always interact with the user through Paigy. For decisions, approvals, or questions, contact them with structured options. Never assume anyone is reading the terminal stdout.
|
|
134
|
+
|
|
135
|
+
CRITICAL PAIGY WORKFLOW PHILOSOPHY:
|
|
136
|
+
1. Atomicity: Never dump a 5-part question into a single \`ask\`. Emit 5 separate objects in the \`asks\` array during a single \`contact\` call so the user can answer them independently.
|
|
137
|
+
2. Tree Structure: Always pass \`parentId\` to deliberately nest sub-decisions under the overarching Goal, ensuring the user workspace remains a clean tree rather than a flat mess.
|
|
138
|
+
3. Urgency: Use \`waiting: hard\` strictly for immediate, blocking decisions, and \`waiting: none\` for async, long-running progress updates or non-blocking questions.
|
|
139
|
+
4. Asynchrony: Never hold the process open with while-loops. Let the current process finish or explicitly schedule wakeups, and rely on \`check_replies\` or \`claim_goal\` on the next wake to process asynchronous answers.`;
|
|
130
140
|
}
|
|
131
141
|
function entryWords(entry) {
|
|
132
142
|
const content = entry.content;
|
|
@@ -143,6 +153,7 @@ function entryWords(entry) {
|
|
|
143
153
|
}
|
|
144
154
|
return entry.sources.map((source) => source.text).join("\n");
|
|
145
155
|
}
|
|
156
|
+
var LIVE_MS = 3 * 6e4;
|
|
146
157
|
var ContextSchema = z3.object({
|
|
147
158
|
title: z3.string().min(1).describe("One-line headline of what you need (required, non-empty)."),
|
|
148
159
|
description: z3.array(z3.string().min(1)).describe(
|
|
@@ -172,10 +183,11 @@ var TransformSchema = z3.enum([
|
|
|
172
183
|
var OptionSchema = z3.object({
|
|
173
184
|
id: z3.string(),
|
|
174
185
|
label: z3.string(),
|
|
186
|
+
hint: z3.string().max(500).describe("Optional short projection of consequence or action if this option is chosen (e.g. 'Reruns test suite', 'Merges to main').").optional(),
|
|
175
187
|
// .describe() flows into the MCP contact JSON schema (zodToJsonSchema), so
|
|
176
188
|
// the constraints below are what an agent reads when deciding to use these.
|
|
177
189
|
html: z3.string().max(16384).describe(
|
|
178
|
-
"Optional sandboxed HTML/CSS preview for a visual 'pick one' (shown in the option card). Untrusted-sandboxed: NO JavaScript, NO external network or images \u2014 inline CSS and data: URIs only; <=16KB. Use for layout/CSS mockups, tables, diffs. For a hosted image use `image` instead."
|
|
190
|
+
"Optional sandboxed HTML/CSS preview for a visual 'pick one' (shown in the option card). Untrusted-sandboxed: NO JavaScript, NO external network or images \u2014 inline CSS and data: URIs only; <=16KB. Rendered edge-to-edge in a responsive card that is 200pt tall (about 320pt wide on a phone, with the next option peeking beside it); make your HTML fit that viewport. Use for layout/CSS mockups, tables, diffs. For a hosted image use `image` instead."
|
|
179
191
|
).optional(),
|
|
180
192
|
image: z3.string().url().describe(
|
|
181
193
|
"Optional image URL rendered as the option's preview (plain image, not sandboxed). For agent-generated HTML/CSS mockups, use `html` instead."
|
|
@@ -266,23 +278,6 @@ var NotifyRequestFields = z3.object({
|
|
|
266
278
|
* when `parentId` became the conversation handle: `parentId` says WHERE, this
|
|
267
279
|
* says HOW. */
|
|
268
280
|
clarifies: z3.string().optional(),
|
|
269
|
-
/** E2EE (text lane): when the pairing is E2EE, the sealed replacements for the
|
|
270
|
-
* plaintext content fields, keyed by field name. FINALIZED wire shape (was
|
|
271
|
-
* provisional in the storage PR): a per-field map `{ context?, options?,
|
|
272
|
-
* visuals? }` of opaque Envelopes — one seal per present content field, so a
|
|
273
|
-
* message with no options/visuals seals only `context`. It COEXISTS with the
|
|
274
|
-
* plaintext fields by mutual exclusion: the superRefine below requires that
|
|
275
|
-
* when `envelope` is present the plaintext `context`/`options`/`visuals` are
|
|
276
|
-
* ABSENT (and vice-versa), so a row is either fully plaintext or fully sealed —
|
|
277
|
-
* never a readable half. The server persists this OPAQUELY into
|
|
278
|
-
* notifications.envelope and relays it blindly; it never decrypts. Absent =
|
|
279
|
-
* today's plaintext path (context/options/visuals carry the cleartext).
|
|
280
|
-
* z.lazy because EnvelopeSchema is declared further down (E2EE section). */
|
|
281
|
-
envelope: z3.object({
|
|
282
|
-
context: z3.lazy(() => EnvelopeSchema).optional(),
|
|
283
|
-
options: z3.lazy(() => EnvelopeSchema).optional(),
|
|
284
|
-
visuals: z3.lazy(() => EnvelopeSchema).optional()
|
|
285
|
-
}).optional(),
|
|
286
281
|
select: SelectShapeSchema.optional().describe(
|
|
287
282
|
"How the user answers \u2014 required on the fully-shaped form, pick the shape that fits the question: 'one' = pick one option, 'many' = pick several, 'rank' = pick & order (each needs `options`); 'confirm' = yes/no or approve/deny; 'text' = free-form reply only (status updates, open questions). 'confirm' and 'text' take no options. Omit only when sending the simplified `ask` form \u2014 the broker picks the shape."
|
|
288
283
|
),
|
|
@@ -336,22 +331,6 @@ var NotifyRequestFields = z3.object({
|
|
|
336
331
|
});
|
|
337
332
|
var NotifyRequestSchema = NotifyRequestFields.superRefine((r, ctx) => {
|
|
338
333
|
if (r.workId && r.goalId) ctx.addIssue({ code: z3.ZodIssueCode.custom, path: ["goalId"], message: "pass goalId or workId, not both" });
|
|
339
|
-
const sealed = !!r.envelope;
|
|
340
|
-
if (sealed) {
|
|
341
|
-
if (!r.envelope?.context)
|
|
342
|
-
ctx.addIssue({ code: z3.ZodIssueCode.custom, path: ["envelope", "context"], message: "sealed request must include envelope.context" });
|
|
343
|
-
for (const f of ["context", "options", "visuals"]) {
|
|
344
|
-
if (r[f] !== void 0)
|
|
345
|
-
ctx.addIssue({ code: z3.ZodIssueCode.custom, path: [f], message: `E2EE request must not carry plaintext ${f} \u2014 it's sealed in envelope.${f}` });
|
|
346
|
-
}
|
|
347
|
-
if (r.points !== void 0)
|
|
348
|
-
ctx.addIssue({ code: z3.ZodIssueCode.custom, path: ["points"], message: "E2EE request must not carry plaintext points" });
|
|
349
|
-
if (r.ask !== void 0)
|
|
350
|
-
ctx.addIssue({ code: z3.ZodIssueCode.custom, path: ["ask"], message: "E2EE request must not carry a plaintext ask \u2014 derive the shape agent-side and seal it" });
|
|
351
|
-
if (r.needs !== void 0)
|
|
352
|
-
ctx.addIssue({ code: z3.ZodIssueCode.custom, path: ["needs"], message: "E2EE request must not carry plaintext needs" });
|
|
353
|
-
return;
|
|
354
|
-
}
|
|
355
334
|
if (r.ask !== void 0) {
|
|
356
335
|
for (const f of ["context", "select", "points"]) {
|
|
357
336
|
if (r[f] !== void 0)
|
|
@@ -426,13 +405,6 @@ var AwaitItemSchema = z3.discriminatedUnion("type", [
|
|
|
426
405
|
workId: z3.string().uuid().optional(),
|
|
427
406
|
decisionId: z3.string().uuid().optional(),
|
|
428
407
|
answer: UserAnswerSchema,
|
|
429
|
-
/** E2EE: present when the answer is sealed. The server relays the opaque answer
|
|
430
|
-
* envelope + the plaintext `ignored` status hint; the receiving agent OPENS it
|
|
431
|
-
* with its device key and re-derives the real UserAnswer, treating a mismatch
|
|
432
|
-
* against `ignored` as tampering. Absent = today's plaintext answer (in `answer`).
|
|
433
|
-
* On a sealed reply the plaintext `answer` is a placeholder (kind reflects only
|
|
434
|
-
* the `ignored` bit) — never the real content, which stays sealed. */
|
|
435
|
-
sealed: z3.lazy(() => SealedAnswerSchema).optional(),
|
|
436
408
|
/** WHAT THE AGENT CANNOT KNOW FROM THE FIELDS BESIDE IT (owner, 2026-09-04, issue
|
|
437
409
|
* #1537). One line, built from the record: the ask and the caller's reply VERBATIM,
|
|
438
410
|
* the notification they belong to, and the `contact` call that reaches the person
|
|
@@ -654,21 +626,6 @@ var InboxItemSchema = z3.object({
|
|
|
654
626
|
blocking: z3.boolean().default(false),
|
|
655
627
|
/** The user's locked-in answer; present only for replied items (GET /api/replied/:id). */
|
|
656
628
|
answer: UserAnswerSchema.optional(),
|
|
657
|
-
/** E2EE (text lane): the sealed content this item carries when the pairing is E2EE, in
|
|
658
|
-
* place of the plaintext `context`/`options`/`visuals` (which the operator would
|
|
659
|
-
* otherwise read). A per-field map of opaque Envelopes — the SAME shape as
|
|
660
|
-
* NotifyRequest.envelope. The native app decrypts it locally via openNotification;
|
|
661
|
-
* web / an un-enrolled device can't and renders a locked placeholder. Absent = today's
|
|
662
|
-
* plaintext item (context carries the cleartext), so plaintext items are unchanged. */
|
|
663
|
-
envelope: z3.object({
|
|
664
|
-
context: z3.lazy(() => EnvelopeSchema).optional(),
|
|
665
|
-
options: z3.lazy(() => EnvelopeSchema).optional(),
|
|
666
|
-
visuals: z3.lazy(() => EnvelopeSchema).optional()
|
|
667
|
-
}).optional(),
|
|
668
|
-
/** E2EE: the agent's device X25519 public key to seal the user's answer BACK to (the
|
|
669
|
-
* sender the phone replies to). Sourced server-side from this item's pairing credential.
|
|
670
|
-
* Present only alongside `envelope`; the phone seals via sealAnswer(answer, this, id). */
|
|
671
|
-
agentX25519: z3.string().optional(),
|
|
672
629
|
/** THE TARGET FACTS A CARD RENDERS (#1796 point 5, 2026-09-11): the Delivery it is a view of,
|
|
673
630
|
* that Delivery's kind, the request Entry, the Goals it answers for, the exact DecisionNeed (none
|
|
674
631
|
* for a request that asks nothing), whether its content is sealed, and that Goal's state. The
|
|
@@ -766,13 +723,6 @@ var UserSettingsSchema = z3.object({
|
|
|
766
723
|
* setting. Absent = a spoken time can't be landed, so the reminder rides the next
|
|
767
724
|
* call — honest about what we know. */
|
|
768
725
|
timezone: z3.string().min(1).max(64).optional(),
|
|
769
|
-
/** Account E2EE state (text lane): 'off' (default) = today's plaintext; 'on' =
|
|
770
|
-
* content is sealed end-to-end between the local agent and the phone. Like
|
|
771
|
-
* voiceMode, OPTIONAL and NOT defaulted so a stale client PATCHing the full
|
|
772
|
-
* settings object without it can't silently flip the account's E2EE state.
|
|
773
|
-
* Absent = leave unchanged on write, 'off' on read (see store.ts). The demo
|
|
774
|
-
* account is plaintext by construction and refuses any non-'off' value. */
|
|
775
|
-
e2eeMode: z3.enum(["off", "on"]).optional(),
|
|
776
726
|
/** Rung-2 broker tuning (#381). Optional and NOT defaulted, same stale-client
|
|
777
727
|
* clobber guard as voiceMode: absent = leave unchanged on write. */
|
|
778
728
|
broker: BrokerTuningSchema.optional()
|
|
@@ -924,7 +874,19 @@ var QueueQuestionSchema = z3.object({
|
|
|
924
874
|
/** The ruling in the person's own words, from the contribution that replied — not the
|
|
925
875
|
* option id, which is not something anyone reads back. Null while it is open, and null
|
|
926
876
|
* for a settled question whose reply carried nothing readable. */
|
|
927
|
-
answer: z3.string().nullable().default(null)
|
|
877
|
+
answer: z3.string().nullable().default(null),
|
|
878
|
+
/** The Goal this question belongs to — a step knows its Goal on its own, not only through
|
|
879
|
+
* an `InboxItem`'s `communication.goalIds[0]` (walk/design.md §12 item 3).
|
|
880
|
+
* READ BY `apps/client/src/walk/order.ts`, which stamps it onto every `WalkStep`: the walk's
|
|
881
|
+
* order, its route, home's trees and the list of steps all take a step's Goal from here, so
|
|
882
|
+
* this is the field they agree through rather than each re-deriving it from the row it
|
|
883
|
+
* arrived under. Required because the API projects it on every need it sends. */
|
|
884
|
+
goalId: z3.string(),
|
|
885
|
+
/** True only while an unmet START gate holds the Goal — a Goal that merely waits to
|
|
886
|
+
* *finish* does not stop a person from answering (owner, 2026-09-16: "per need gate from
|
|
887
|
+
* the API"; §4's dashed node). Not the same fact as `QueueItem.blocked`, which counts any
|
|
888
|
+
* gate at all. */
|
|
889
|
+
blocked: z3.boolean().default(false)
|
|
928
890
|
});
|
|
929
891
|
var QueueItemSchema = z3.object({
|
|
930
892
|
id: z3.string(),
|
|
@@ -950,6 +912,8 @@ var QueueItemSchema = z3.object({
|
|
|
950
912
|
blocked: z3.boolean().default(false),
|
|
951
913
|
/** Every decision need on it, open or settled — the page decides which to show. */
|
|
952
914
|
questions: z3.array(QueueQuestionSchema).default([]),
|
|
915
|
+
/** The repository or project identifier this Goal belongs to (#2280), null if untracked. */
|
|
916
|
+
repo: z3.string().nullable().optional(),
|
|
953
917
|
createdAt: z3.string(),
|
|
954
918
|
updatedAt: z3.string().nullable().default(null)
|
|
955
919
|
});
|
|
@@ -1061,54 +1025,12 @@ var DeliveryConfigSchema = z3.object({
|
|
|
1061
1025
|
* carries credentials; only a `poll` registration can come back with null here. */
|
|
1062
1026
|
realtime: z3.object({ url: z3.string(), anonKey: z3.string() }).nullable()
|
|
1063
1027
|
});
|
|
1064
|
-
var EnvelopeRecipientSchema = z3.object({
|
|
1065
|
-
keyId: z3.string(),
|
|
1066
|
-
epk: z3.string(),
|
|
1067
|
-
wnonce: z3.string(),
|
|
1068
|
-
wrap: z3.string()
|
|
1069
|
-
});
|
|
1070
|
-
var EnvelopeHeaderSchema = z3.object({
|
|
1071
|
-
field: z3.enum(["context", "options", "visuals", "answer"]),
|
|
1072
|
-
kind: z3.string(),
|
|
1073
|
-
senderRole: z3.enum(["agent", "user"]),
|
|
1074
|
-
recipientKeyIds: z3.array(z3.string()),
|
|
1075
|
-
seq: z3.number().int().nonnegative()
|
|
1076
|
-
});
|
|
1077
|
-
var EnvelopeSchema = z3.object({
|
|
1078
|
-
v: z3.literal(1),
|
|
1079
|
-
alg: z3.literal("x25519-xsalsa20poly1305"),
|
|
1080
|
-
msgId: z3.string(),
|
|
1081
|
-
hdr: EnvelopeHeaderSchema,
|
|
1082
|
-
recipients: z3.array(EnvelopeRecipientSchema).min(1),
|
|
1083
|
-
nonce: z3.string(),
|
|
1084
|
-
ct: z3.string()
|
|
1085
|
-
});
|
|
1086
|
-
var SealedAnswerSchema = z3.object({
|
|
1087
|
-
ignored: z3.boolean(),
|
|
1088
|
-
envelope: EnvelopeSchema
|
|
1089
|
-
});
|
|
1090
|
-
var DeviceCredentialSchema = z3.object({
|
|
1091
|
-
deviceId: z3.string(),
|
|
1092
|
-
kind: z3.enum(["phone", "web", "agent"]),
|
|
1093
|
-
x25519Pub: z3.string(),
|
|
1094
|
-
ed25519Pub: z3.string(),
|
|
1095
|
-
sig: z3.string()
|
|
1096
|
-
});
|
|
1097
|
-
var DeviceRosterSchema = z3.object({
|
|
1098
|
-
uikPub: z3.string(),
|
|
1099
|
-
devices: z3.array(DeviceCredentialSchema)
|
|
1100
|
-
});
|
|
1101
1028
|
var WakeNudgeSchema = z3.object({
|
|
1102
1029
|
kind: z3.enum(["reply", "request", "callback"]),
|
|
1103
1030
|
notificationId: z3.string().optional(),
|
|
1104
1031
|
parentId: z3.string()
|
|
1105
1032
|
});
|
|
1106
1033
|
var PairingStatusSchema = z3.enum(["pending", "approved", "denied", "expired"]);
|
|
1107
|
-
var PairingRevealSchema = z3.object({
|
|
1108
|
-
x25519: z3.string(),
|
|
1109
|
-
ed25519: z3.string(),
|
|
1110
|
-
nonce: z3.string()
|
|
1111
|
-
});
|
|
1112
1034
|
var DeviceCodeSchema = z3.object({
|
|
1113
1035
|
device_code: z3.string(),
|
|
1114
1036
|
user_code: z3.string(),
|
|
@@ -1128,19 +1050,7 @@ var DeviceInfoSchema = z3.object({
|
|
|
1128
1050
|
* (seen live: PAIGY-5T, 2026-07-21). Remove once a newer binary is the floor. */
|
|
1129
1051
|
agent: z3.string().optional(),
|
|
1130
1052
|
device: z3.string().nullable(),
|
|
1131
|
-
status: PairingStatusSchema
|
|
1132
|
-
proto: z3.string().nullable().optional(),
|
|
1133
|
-
agent_commitment: z3.string().nullable().optional(),
|
|
1134
|
-
// Ca
|
|
1135
|
-
agent_reveal: PairingRevealSchema.nullable().optional(),
|
|
1136
|
-
// present once the agent reveals
|
|
1137
|
-
agent_credential: DeviceCredentialSchema.nullable().optional(),
|
|
1138
|
-
// the phone's UIK-signed cred over the agent's keys — the agent fetches it here to finalizeE2ee
|
|
1139
|
-
// The phone's reveal + identity key, exposed here so a GATED agent (e2ee_mode='on', token
|
|
1140
|
-
// withheld until e2ee=true) can compute the SAS WITHOUT a token. Public keys — same safety
|
|
1141
|
-
// class as agent_reveal above. Present only once the phone reveals; null otherwise.
|
|
1142
|
-
phone_reveal: PairingRevealSchema.nullable().optional(),
|
|
1143
|
-
uik_pub: z3.string().nullable().optional()
|
|
1053
|
+
status: PairingStatusSchema
|
|
1144
1054
|
});
|
|
1145
1055
|
var DeviceTokenSchema = z3.object({
|
|
1146
1056
|
access_token: z3.string(),
|
|
@@ -1159,8 +1069,6 @@ var DeviceTokenSchema = z3.object({
|
|
|
1159
1069
|
* landed in the FIRST granted workspace and the agent rediscovered its own repo from
|
|
1160
1070
|
* the thread each time (host.ts, live catch 2026-08-06 — prompt-papered until now). */
|
|
1161
1071
|
workspace: z3.string().nullable().optional(),
|
|
1162
|
-
phone_reveal: PairingRevealSchema.nullable().optional(),
|
|
1163
|
-
// present once the phone reveals
|
|
1164
1072
|
uik_pub: z3.string().nullable().optional()
|
|
1165
1073
|
});
|
|
1166
1074
|
var SupportRequestSchema = z3.object({
|
|
@@ -1182,13 +1090,6 @@ var NotificationFeedbackKindSchema = z3.enum([
|
|
|
1182
1090
|
"other"
|
|
1183
1091
|
// anything else — the note carries it.
|
|
1184
1092
|
]);
|
|
1185
|
-
var FeedbackResolutionSchema = z3.enum(["broker_fixed", "sent_to_agent"]);
|
|
1186
|
-
var FeedbackOutcomeSchema = z3.object({
|
|
1187
|
-
resolution: FeedbackResolutionSchema,
|
|
1188
|
-
transform: TransformSchema,
|
|
1189
|
-
message: z3.string(),
|
|
1190
|
-
childIds: z3.array(z3.string()).optional()
|
|
1191
|
-
});
|
|
1192
1093
|
|
|
1193
1094
|
export {
|
|
1194
1095
|
mcpInputSchema,
|
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
AGENT_TOOLS,
|
|
3
3
|
mcpInputSchema,
|
|
4
4
|
serverInstructions
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-UFOR2QEP.js";
|
|
6
6
|
import {
|
|
7
7
|
AGENT_NAME
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-5OY6ED2Q.js";
|
|
9
9
|
|
|
10
10
|
// src/toolset.ts
|
|
11
11
|
var ONBOARD_DESCRIPTION = "Get this agent talking to Paigy \u2014 call it FIRST, before contact, and any time you're unsure who you are. One call, and it does whatever the situation needs: NOT SET UP \u2192 hatches an identity instantly if this machine holds a device credential (the user ran the Paigy desktop app or harness), otherwise starts the code ceremony; ALREADY SET UP \u2192 returns your current identity and offers the two things left to decide, renaming it or unpairing; TOKEN NO LONGER VALID \u2192 says so, then re-pairs. Pass { name, voice } to choose who you are when hatching, or to RENAME yourself when already set up (voices: rachel, george, jessica, brian, lily). Safe to call any time: idempotent, and it never writes settings \u2014 the tool-allowlist state it reports is read-only. If it returns a `user_code`, print it to the user immediately and call onboard again with the `device_code`. If it returns `enable_command`, PRINT that command for the user to run \u2014 you cannot apply it yourself (it writes your own permission allowlist, which hosts block as privilege escalation), so print it, don't wait for it, and carry on.";
|
package/dist/enable.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
import {
|
|
3
3
|
PAIGY_TOOL_IDS,
|
|
4
4
|
enablePaigyTools
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-UOROFXDI.js";
|
|
6
|
+
import "./chunk-UFOR2QEP.js";
|
|
7
|
+
import "./chunk-5OY6ED2Q.js";
|
|
8
8
|
|
|
9
9
|
// src/enable.ts
|
|
10
10
|
function main() {
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
resolvePairing,
|
|
6
6
|
startPairing,
|
|
7
7
|
suggestedAgentName
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-LYPZ5QO2.js";
|
|
9
9
|
import {
|
|
10
10
|
ENABLE_COMMAND,
|
|
11
11
|
OnboardSchema,
|
|
@@ -13,11 +13,9 @@ import {
|
|
|
13
13
|
PairSchema,
|
|
14
14
|
SERVER_INSTRUCTIONS,
|
|
15
15
|
TOOLS,
|
|
16
|
-
autoConfigureClients,
|
|
17
|
-
claudeInstallHint,
|
|
18
16
|
paigyToolsAllowlisted
|
|
19
|
-
} from "./chunk-
|
|
20
|
-
import "./chunk-
|
|
17
|
+
} from "./chunk-UOROFXDI.js";
|
|
18
|
+
import "./chunk-UFOR2QEP.js";
|
|
21
19
|
import {
|
|
22
20
|
clearSurface,
|
|
23
21
|
writeSurface
|
|
@@ -25,7 +23,6 @@ import {
|
|
|
25
23
|
import {
|
|
26
24
|
AGENT_NAME,
|
|
27
25
|
UnpairedError,
|
|
28
|
-
deleteKeyFile,
|
|
29
26
|
deleteToken,
|
|
30
27
|
hatch,
|
|
31
28
|
heartbeat,
|
|
@@ -38,7 +35,7 @@ import {
|
|
|
38
35
|
setIdentity,
|
|
39
36
|
slotName,
|
|
40
37
|
whoAmI
|
|
41
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-5OY6ED2Q.js";
|
|
42
39
|
|
|
43
40
|
// src/index.ts
|
|
44
41
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
@@ -49,7 +46,7 @@ import {
|
|
|
49
46
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
50
47
|
import qrcode from "qrcode-generator";
|
|
51
48
|
var JOIN_CAP_MS = 45e3;
|
|
52
|
-
function pairedResult(token, sas, note
|
|
49
|
+
function pairedResult(token, sas, note) {
|
|
53
50
|
clearSurface();
|
|
54
51
|
const base = {
|
|
55
52
|
status: "paired",
|
|
@@ -57,21 +54,10 @@ function pairedResult(token, sas, note, e2ee) {
|
|
|
57
54
|
device: token.device
|
|
58
55
|
};
|
|
59
56
|
if (sas) {
|
|
60
|
-
base.e2ee = !!e2ee;
|
|
61
57
|
base.sas = sas;
|
|
62
|
-
base.verify_message = `This pairing is end-to-end encrypted. Ask the user to verify this code matches the one on their phone: ${sas}
|
|
58
|
+
base.verify_message = `This pairing is end-to-end encrypted. Ask the user to verify this code matches the one on their phone: ${sas}`;
|
|
63
59
|
}
|
|
64
60
|
if (note) base.note = note;
|
|
65
|
-
try {
|
|
66
|
-
const registered = autoConfigureClients();
|
|
67
|
-
if (registered.length) {
|
|
68
|
-
base.auto_registered = registered;
|
|
69
|
-
base.auto_register_message = `Also registered the Paigy MCP server in: ${registered.join("; ")}. Tell the user \u2014 those tools pick it up on their next restart/reload.`;
|
|
70
|
-
}
|
|
71
|
-
const hint = claudeInstallHint();
|
|
72
|
-
if (hint) base.claude_hint = hint;
|
|
73
|
-
} catch {
|
|
74
|
-
}
|
|
75
61
|
base.enable_tool_ids = PAIGY_TOOL_IDS;
|
|
76
62
|
base.enable_command = ENABLE_COMMAND;
|
|
77
63
|
base.enable_prompt = "REQUIRED \u2014 before you do anything else, print `enable_command` to the user and say: \"Run this to let Paigy's tools work without an approval prompt each time \u2014 it only allowlists the notify/await tools; pair and unpair still ask.\" Print it every time you pair; don't skip it.";
|
|
@@ -88,7 +74,6 @@ Check it matches the code on the phone, then type it there to confirm.` },
|
|
|
88
74
|
type: "text",
|
|
89
75
|
text: JSON.stringify({
|
|
90
76
|
status: "awaiting_confirmation",
|
|
91
|
-
e2ee: true,
|
|
92
77
|
sas,
|
|
93
78
|
device_code,
|
|
94
79
|
user_message: `# ${sas}`,
|
|
@@ -107,7 +92,6 @@ function renderPairOutcome(outcome, device_code) {
|
|
|
107
92
|
case "awaiting_confirm":
|
|
108
93
|
return awaitingConfirmResult(outcome.sas, device_code);
|
|
109
94
|
case "paired":
|
|
110
|
-
return pairedResult(outcome.token, outcome.sas, void 0, outcome.e2ee);
|
|
111
95
|
case "pending":
|
|
112
96
|
return {
|
|
113
97
|
content: [{
|
|
@@ -307,7 +291,6 @@ async function handleTool(request, signal) {
|
|
|
307
291
|
}
|
|
308
292
|
}
|
|
309
293
|
const removed = deleteToken();
|
|
310
|
-
deleteKeyFile();
|
|
311
294
|
clearPairing();
|
|
312
295
|
return {
|
|
313
296
|
content: [{
|
package/dist/listen.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
entryWords
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-UFOR2QEP.js";
|
|
5
5
|
import {
|
|
6
6
|
checkReplies,
|
|
7
7
|
contact,
|
|
8
8
|
getGoal,
|
|
9
9
|
subscribeWake
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-5OY6ED2Q.js";
|
|
11
11
|
|
|
12
12
|
// src/listen.ts
|
|
13
13
|
import { spawn } from "child_process";
|
|
@@ -124,11 +124,8 @@ function launchEnv(waiting, reason, goalId) {
|
|
|
124
124
|
const named = goalId ? waiting.deliveries.find((d) => d.goalIds.includes(goalId)) : void 0;
|
|
125
125
|
const lead = named ?? waiting.deliveries[0];
|
|
126
126
|
if (!lead) return env;
|
|
127
|
-
put("PAIGY_THREAD_ID", lead.threadId);
|
|
128
|
-
put("PAIGY_PARENT_ID", lead.threadId);
|
|
129
127
|
put("PAIGY_DELIVERY_ID", lead.deliveryId);
|
|
130
128
|
put("PAIGY_GOAL_ID", waiting.goal?.goalId ?? lead.goalIds[0]);
|
|
131
|
-
put("PAIGY_CONTEXT_THREAD_ID", waiting.goal?.contextThreadId);
|
|
132
129
|
put("PAIGY_TEXT", saidIn(lead) || ("about" in lead ? lead.about : ""));
|
|
133
130
|
return env;
|
|
134
131
|
}
|
|
@@ -140,7 +137,7 @@ async function sweep(reason, goalId) {
|
|
|
140
137
|
const full = lead ? await contact({ deliveryId: lead.deliveryId }, { waits: false }).catch(() => null) : null;
|
|
141
138
|
const deliveries = rows.map((d) => d === lead && full ? full : d);
|
|
142
139
|
const leadGoalId = lead?.goalIds[0];
|
|
143
|
-
const goal = leadGoalId ? await getGoal(leadGoalId).then((g) => ({ goalId: leadGoalId,
|
|
140
|
+
const goal = leadGoalId ? await getGoal(leadGoalId).then((g) => ({ goalId: leadGoalId, progress: g.progress })).catch(() => null) : null;
|
|
144
141
|
const waiting = { deliveries, goal };
|
|
145
142
|
emit({ type: "sweep", reason, ...goalId ? { about: goalId } : {}, ...waiting });
|
|
146
143
|
if (cmd && deliveries.length) {
|
package/dist/onboard.js
CHANGED
|
@@ -3,13 +3,13 @@ import {
|
|
|
3
3
|
resolvePairing,
|
|
4
4
|
startPairing,
|
|
5
5
|
suggestedAgentName
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-LYPZ5QO2.js";
|
|
7
7
|
import {
|
|
8
8
|
autoConfigureClients,
|
|
9
9
|
claudeInstallHint,
|
|
10
10
|
openBrowser
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-UOROFXDI.js";
|
|
12
|
+
import "./chunk-UFOR2QEP.js";
|
|
13
13
|
import {
|
|
14
14
|
AGENT_NAME,
|
|
15
15
|
TOKEN_PATH,
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
saveToken,
|
|
21
21
|
setIdentity,
|
|
22
22
|
whoAmI
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-5OY6ED2Q.js";
|
|
24
24
|
|
|
25
25
|
// src/onboard.ts
|
|
26
26
|
function reportRegistered() {
|
|
@@ -123,9 +123,6 @@ Paired! Token saved to ${TOKEN_PATH} (mode 0600).`);
|
|
|
123
123
|
console.log("Treat this token like a password \u2014 it grants account access. Never log, echo, or commit it.");
|
|
124
124
|
console.log(` Name : ${outcome.token.name}`);
|
|
125
125
|
console.log(` Device : ${outcome.token.device ?? "(none)"}`);
|
|
126
|
-
if (outcome.sas) {
|
|
127
|
-
console.log(` E2EE : ${outcome.e2ee ? "verified and pinned" : "offered, identity key not yet confirmed on the phone"} (code ${outcome.sas})`);
|
|
128
|
-
}
|
|
129
126
|
console.log();
|
|
130
127
|
reportRegistered();
|
|
131
128
|
return;
|