@paigy/mcp 0.40.38 → 0.40.40
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 +11 -12
- package/dist/{chunk-2OMTJ3JN.js → chunk-6FG3PZR2.js} +30 -7
- package/dist/{chunk-3YXZUGFL.js → chunk-H2EBILBE.js} +323 -115
- package/dist/{chunk-FXPZQN3E.js → chunk-PKJJSHLW.js} +41 -44
- package/dist/{chunk-4PP522IN.js → chunk-V4OVLFMP.js} +242 -113
- package/dist/{dist-JDIRRDOJ.js → dist-EJWDUF5J.js} +3 -1
- package/dist/enable.js +3 -3
- package/dist/index.js +45 -21
- package/dist/listen.js +32 -6
- package/dist/onboard.js +18 -6
- package/dist/slot.js +1 -1
- package/dist/stalled.js +10 -5
- package/dist/statusline.js +1 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// ../../packages/sdk/dist/index.js
|
|
2
2
|
import { createRequire as __sdkCreateRequire } from "module";
|
|
3
3
|
import { execFileSync } from "child_process";
|
|
4
4
|
import { createHash, randomUUID } from "crypto";
|
|
@@ -59,6 +59,24 @@ function parentOf(pid) {
|
|
|
59
59
|
return void 0;
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
|
+
var CODEX_PARENT = /(^|\/)\.codex\/|CodexCLI\.app|(^|[\/\s])codex(\s|$)/;
|
|
63
|
+
var codexParent;
|
|
64
|
+
function underCodex() {
|
|
65
|
+
if (codexParent !== void 0) return codexParent;
|
|
66
|
+
codexParent = false;
|
|
67
|
+
if (process.platform === "win32") return codexParent;
|
|
68
|
+
for (const pid of ancestors()) {
|
|
69
|
+
try {
|
|
70
|
+
const command = execFileSync("ps", ["-o", "command=", "-p", String(pid)], { encoding: "utf8", timeout: 1e3 });
|
|
71
|
+
if (CODEX_PARENT.test(command)) {
|
|
72
|
+
codexParent = true;
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
} catch {
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return codexParent;
|
|
79
|
+
}
|
|
62
80
|
var lineage;
|
|
63
81
|
function ancestors() {
|
|
64
82
|
if (lineage) return lineage;
|
|
@@ -116,7 +134,8 @@ function parseSessionRecord(text) {
|
|
|
116
134
|
return void 0;
|
|
117
135
|
}
|
|
118
136
|
function sessionId() {
|
|
119
|
-
return envSession("PAIGY_SESSION_ID") ?? claudeConversation() ?? envSession("CLAUDE_CODE_SESSION_ID") ?? envSession("CODEX_THREAD_ID") ?? envSession("CODEX_SESSION_ID") ??
|
|
137
|
+
return envSession("PAIGY_SESSION_ID") ?? claudeConversation() ?? envSession("CLAUDE_CODE_SESSION_ID") ?? envSession("CODEX_THREAD_ID") ?? envSession("CODEX_SESSION_ID") ?? // A Codex thread that was handed no id is its own agent, not the folder's (`underCodex`).
|
|
138
|
+
(underCodex() ? INSTANCE_ID : WORKSPACE_ID);
|
|
120
139
|
}
|
|
121
140
|
function isNetworkError(e) {
|
|
122
141
|
return e instanceof Error && e.message.startsWith(NETWORK_MSG);
|
|
@@ -1498,16 +1517,16 @@ function parseWhen(said2, tz, nowMs, read22 = "earliest") {
|
|
|
1498
1517
|
let hour = null;
|
|
1499
1518
|
let minute = 0;
|
|
1500
1519
|
const spoken = new RegExp(`\\bat\\s+(${Object.keys(SPOKEN_HOUR).join("|")})\\b`, "i").exec(text);
|
|
1501
|
-
const
|
|
1520
|
+
const clock2 = CLOCK.exec(text);
|
|
1502
1521
|
if (spoken) {
|
|
1503
1522
|
hour = SPOKEN_HOUR[spoken[1].toLowerCase()];
|
|
1504
|
-
} else if (
|
|
1505
|
-
hour = Number(
|
|
1506
|
-
minute =
|
|
1523
|
+
} else if (clock2 && (clock2[3] || /\bat\s/i.test(clock2[0]))) {
|
|
1524
|
+
hour = Number(clock2[1]);
|
|
1525
|
+
minute = clock2[2] ? Number(clock2[2]) : 0;
|
|
1507
1526
|
if (hour > 23 || minute > 59) return null;
|
|
1508
1527
|
}
|
|
1509
1528
|
if (hour !== null) {
|
|
1510
|
-
const mer =
|
|
1529
|
+
const mer = clock2?.[3]?.toLowerCase().replace(/\./g, "") ?? "";
|
|
1511
1530
|
const pmWord = /\b(p\.?m\.?|afternoon|evening|tonight|at night)\b/i.test(text);
|
|
1512
1531
|
const amWord = /\b(a\.?m\.?|morning)\b/i.test(text);
|
|
1513
1532
|
if (mer.startsWith("p") || pmWord && !amWord) {
|
|
@@ -1551,7 +1570,7 @@ function parseDelay(said2, tz, nowMs, read22 = "earliest") {
|
|
|
1551
1570
|
return Math.max(0, Math.round((Date.parse(at2) - nowMs) / 1e3));
|
|
1552
1571
|
}
|
|
1553
1572
|
var NIGHT = { from: 23, to: 7 };
|
|
1554
|
-
var ASK_MAX =
|
|
1573
|
+
var ASK_MAX = 80;
|
|
1555
1574
|
var UNITS_MAX = 12;
|
|
1556
1575
|
var UNIT_TITLE_MAX = 50;
|
|
1557
1576
|
var UNIT_BODY_MAX = 200;
|
|
@@ -1616,15 +1635,15 @@ var CompletionSchema = z3.object({
|
|
|
1616
1635
|
}).strict();
|
|
1617
1636
|
var CompleteChangeSchema = CompletionSchema.extend({ kind: z3.literal("complete") });
|
|
1618
1637
|
var ASKING_RULES = `HOW TO ASK:
|
|
1619
|
-
1.
|
|
1620
|
-
2.
|
|
1621
|
-
3. \`workItBlocks\` only
|
|
1622
|
-
4.
|
|
1623
|
-
5. One question, one row
|
|
1624
|
-
6. Read the Goal
|
|
1625
|
-
7.
|
|
1626
|
-
8. A diagnosis says when, why and how it happens, then proposes one fix.
|
|
1627
|
-
9.
|
|
1638
|
+
1. One question per object in \`questions\`, so each is answered on its own.
|
|
1639
|
+
2. \`goalId\` names the existing Goal it is about (create one with manage_goals first); the answer comes back there.
|
|
1640
|
+
3. \`workItBlocks\` only when you are truly blocked: it asks for a call.
|
|
1641
|
+
4. No while-loops. While any Call is open, even one your question joined from their items, keep receiving through empty windows; otherwise stop at one: the answer reaches you on the Goal. Yield only with a listener or wakeup.
|
|
1642
|
+
5. One question, one row: never re-send one still waiting; take back one that no longer matters with \`withdrawQuestionIds\`.
|
|
1643
|
+
6. Read the Goal before asking; never re-ask what was answered or shipped. \`replied\` means they chose no option: it is still yours to settle.
|
|
1644
|
+
7. Give options when you have them. Each label names its choice in full (never "Option 2"); never add "Other". \`pickMode\`: one (default), many, rank.
|
|
1645
|
+
8. A diagnosis says when, why and how it happens, then proposes one fix.
|
|
1646
|
+
9. Give a report its \`reply\`: one line in THEIR voice for THAT report, so you learn whether they verified it or only received it. Required when it reaches them or completes a Goal.`;
|
|
1628
1647
|
function draft2020(node) {
|
|
1629
1648
|
if (Array.isArray(node)) return node.map(draft2020);
|
|
1630
1649
|
if (node && typeof node === "object") {
|
|
@@ -1667,7 +1686,7 @@ var userExplicitlyRequested = z4.enum(["any", "call"]).optional().describe(
|
|
|
1667
1686
|
`Only what the person said about THIS message, in so many words: "any" when they asked you to send it to them ("send it to my phone", "message me the result"), "call" when they asked to be called about it. It is then delivered (a call rings for the whole contact, and carries everything waiting on them); omitted, an update is only recorded as the Goal's progress unless the person needs it. Never set it to make a message louder.`
|
|
1668
1687
|
);
|
|
1669
1688
|
var units = z4.array(UnitInputSchema).optional().describe(
|
|
1670
|
-
`The context this message needs, as up to ${UNITS_MAX} units in reading order, each {title, body}: a title of at most ${UNIT_TITLE_MAX} characters and a body of at most ${UNIT_BODY_MAX}. One idea per unit. Leave it out when the main text says it all.`
|
|
1689
|
+
`The context this message needs, as up to ${UNITS_MAX} units in reading order, each {title, body}: a title of at most ${UNIT_TITLE_MAX} characters and a body of at most ${UNIT_BODY_MAX}. One idea per unit. Leave it out when the main text says it all. Over a cap is refused by name (ask_too_long, too_many_units, unit_title_too_long, unit_body_too_long) and nothing is sent.`
|
|
1671
1690
|
);
|
|
1672
1691
|
var UpdateInputSchema = z4.object({
|
|
1673
1692
|
message: z4.string().trim().min(1).describe(`The one point, at most ${ASK_MAX} characters; the context goes in units.`),
|
|
@@ -1722,7 +1741,7 @@ var questionFields = {
|
|
|
1722
1741
|
),
|
|
1723
1742
|
goalId: z4.string().uuid().describe("The Goal the question is about, which must exist (create it with manage_goals first). Its answer comes back there."),
|
|
1724
1743
|
units,
|
|
1725
|
-
options: z4.array(OptionInputSchema).min(1).max(6).optional().describe("The choices, when you have them. Each label stands on its own, at most 50 characters; a hint, at most 200."),
|
|
1744
|
+
options: z4.array(OptionInputSchema).min(1).max(6).optional().describe("The choices, when you have them. Each label stands on its own, at most 50 characters; a hint, at most 200. They can always answer in their own words, so no 'Other' or 'None of these'."),
|
|
1726
1745
|
// HOW THE OPTIONS ARE ANSWERED, SAID BY THE AGENT (owner, 2026-10-02: "one and many makes sense";
|
|
1727
1746
|
// brain_prompts.md §1: structured agent questions need no model). The app draws all three.
|
|
1728
1747
|
pickMode: z4.enum(["one", "many", "rank"]).optional().describe(
|
|
@@ -1764,7 +1783,9 @@ var QuestionDependencySchema = z4.object({
|
|
|
1764
1783
|
reason: reason.optional()
|
|
1765
1784
|
}).strict().refine(actionFits, ACTION_FITS);
|
|
1766
1785
|
var sendFields = {
|
|
1767
|
-
completions: z4.array(CompletionSchema).min(1).max(20).optional().describe(
|
|
1786
|
+
completions: z4.array(CompletionSchema).min(1).max(20).optional().describe(
|
|
1787
|
+
"COMPLETIONS close and report in one operation, the same contract as manage_goals kind:complete: closure and the report commit together or neither does. Required children and dependencies must already be finished. options suggest next steps: a tap acknowledges the report and requests that step, and never reopens the Goal (follow-up work needs a new one). No reviewer rejudges it: say only what your evidence supports. Ordinary updates never close a Goal."
|
|
1788
|
+
),
|
|
1768
1789
|
updates: z4.array(UpdateInputSchema).min(1).max(20).optional().describe(
|
|
1769
1790
|
"News: progress, findings, a result. An update asks nothing. It reaches the person only when they asked for it (userExplicitlyRequested), when it answers something they said, or once its Goal is done; otherwise it is recorded as the Goal's progress and nobody is notified."
|
|
1770
1791
|
),
|
|
@@ -1778,7 +1799,7 @@ var sendFields = {
|
|
|
1778
1799
|
};
|
|
1779
1800
|
var ContactSchema = z4.object({
|
|
1780
1801
|
...sendFields,
|
|
1781
|
-
questions: z4.array(QuestionInputSchema).min(1).max(20).optional().describe("Questions for the person, one per object."),
|
|
1802
|
+
questions: z4.array(QuestionInputSchema).min(1).max(20).optional().describe("Questions for the person, one per object, each sent exactly as written, with no reading in between."),
|
|
1782
1803
|
/** RECEIVING (2I, I2; brain_prompts.md §2.2): the events this agent handled. */
|
|
1783
1804
|
ackEventIds: z4.array(z4.string().uuid()).min(1).max(100).optional().describe(
|
|
1784
1805
|
"The exact eventIds of the events you have handled: an acknowledgment (ACK). Reading alone acknowledges nothing, so an event comes back until you acknowledge it; after that the next batch can come. Each recipient acknowledges separately, for itself only. A Question you owe is answered (answers), never acknowledged away."
|
|
@@ -1794,15 +1815,13 @@ var ContactWireSchema = z4.object({
|
|
|
1794
1815
|
questions: z4.array(QuestionWireSchema).min(1).max(20).optional()
|
|
1795
1816
|
}).strict().refine(sendsAnything, "a contact sends at least one update, question, answer, withdrawal or question dependency");
|
|
1796
1817
|
var CONTACT_SCHEMA = { type: "object", ...mcpInputSchema(ContactSchema) };
|
|
1797
|
-
var CONTACT_DESCRIPTION = "Send to and receive from the person: completions, updates, questions, answers to questions addressed to you, withdrawals
|
|
1798
|
-
|
|
1799
|
-
CUT A LONG MESSAGE BEFORE YOU SEND IT: a question, an update's message or an answer is the one point, in at most ${ASK_MAX} characters; everything else it needs goes in 'units', up to ${UNITS_MAX} {title, body} in reading order, one idea each, every title at most ${UNIT_TITLE_MAX} characters and every body at most ${UNIT_BODY_MAX}. The person sees the main text and the titles, and opens a unit to read its body. Over a cap is refused by name (ask_too_long, too_many_units, unit_title_too_long, unit_body_too_long) and nothing is sent.
|
|
1818
|
+
var CONTACT_DESCRIPTION = "Send to and receive from the person: completions, updates, questions, answers to questions addressed to you, withdrawals, and what a question holds up. Every Goal named must exist: an unknown one refuses the whole contact. Each item applies on its own: read `results`, where a failed one names why.\n\n" + ASKING_RULES + `
|
|
1800
1819
|
|
|
1801
|
-
|
|
1820
|
+
LENGTH: the question, message or answer is the one point, at most ${ASK_MAX} characters; the rest goes in \`units\`, one idea each. Over a cap is refused by name and nothing is sent. Several results are several updates.
|
|
1802
1821
|
|
|
1803
|
-
|
|
1822
|
+
UPDATES ask nothing. One reaches the person only when they asked for it, it answers something they said, or its Goal is done; else it is kept as progress. One that reaches them joins an open report card or a live call.
|
|
1804
1823
|
|
|
1805
|
-
RECEIVING:
|
|
1824
|
+
RECEIVING: contact({}) waits ~45 s; contact({wait:false}) returns \`events\` at once. Confirm the ones you handled with contact({ackEventIds}).`;
|
|
1806
1825
|
var CreateGoalSchema = z5.object({
|
|
1807
1826
|
outcome: z5.string().trim().min(1).max(1e4),
|
|
1808
1827
|
/** The work's NAME (#2115) — one to five words, how a person refers to it out loud ("the night
|
|
@@ -2017,11 +2036,28 @@ var messageBase = {
|
|
|
2017
2036
|
obligationIds: z6.array(id)
|
|
2018
2037
|
};
|
|
2019
2038
|
var BrainMessageSchema = z6.union([
|
|
2020
|
-
|
|
2039
|
+
// A MESSAGE TO THE PERSON KEEPS ITS SENTENCES (turns.md): the talker writes them one by one, and each is
|
|
2040
|
+
// its own unit of speech (`<cycle>:<key>:<n>`). `text` is the same words joined, for every reader of a
|
|
2041
|
+
// message's words. Absent on results written before sentences.
|
|
2042
|
+
z6.object({
|
|
2043
|
+
...messageBase,
|
|
2044
|
+
to: z6.object({ kind: z6.literal("user") }).strict(),
|
|
2045
|
+
sentences: z6.array(z6.string().min(1)).min(1).optional(),
|
|
2046
|
+
// THE REPORTS IT TELLS, BY THEIR OWN IDENTITY (call 9d1c096c, 2026-10-15): the talker's message names the report
|
|
2047
|
+
// Entries it speaks of, so the plan's line names that report rather than re-finding it by its Goal. Absent on
|
|
2048
|
+
// results written before it.
|
|
2049
|
+
tells: z6.array(z6.object({ id }).strict()).optional()
|
|
2050
|
+
}).strict(),
|
|
2021
2051
|
z6.object({
|
|
2022
2052
|
...messageBase,
|
|
2023
2053
|
to: z6.object({ kind: z6.literal("agent"), agentId: z6.string().regex(/^agent:(?!paigy$)\S+$/) }).strict(),
|
|
2024
|
-
call: z6.object({ callId: id, listen: z6.literal(true) }).strict().optional()
|
|
2054
|
+
call: z6.object({ callId: id, listen: z6.literal(true) }).strict().optional(),
|
|
2055
|
+
// WHAT IT ASKS THE AGENT, IN UNDER TEN WORDS (owner, 2026-10-15: "Yes, add the summary"): the talker's own, stored
|
|
2056
|
+
// as the sent Entry's summary, which the recap's "Sent to <agent>: …" row shows. Absent on results written before it.
|
|
2057
|
+
summary: z6.string().optional(),
|
|
2058
|
+
// THE PERSON ASKED TO BE CALLED BACK ONCE THIS AGENT'S WORK IS DONE (turns.md, step 0): the agent owes
|
|
2059
|
+
// the call, and its next contact about it rings them (`public.callbacks`).
|
|
2060
|
+
callback: z6.literal(true).optional()
|
|
2025
2061
|
}).strict()
|
|
2026
2062
|
]);
|
|
2027
2063
|
var BrainSearchSchema = z6.object({
|
|
@@ -2045,92 +2081,97 @@ var BrainResultSchema = z6.object({
|
|
|
2045
2081
|
next: BrainNextSchema,
|
|
2046
2082
|
search: BrainSearchSchema.optional()
|
|
2047
2083
|
}).strict();
|
|
2048
|
-
var
|
|
2084
|
+
var str2 = z6.string();
|
|
2049
2085
|
var strs = z6.array(z6.string());
|
|
2050
2086
|
var CompactResultSchema = z6.object({
|
|
2051
|
-
next: z6.object({ say: strs, then: z6.enum(["listen", "hold", "end", "none"]), waitFor: strs, reason:
|
|
2052
|
-
messages: z6.array(z6.object({ key:
|
|
2053
|
-
entries: z6.array(z6.object({ key:
|
|
2054
|
-
answers: z6.array(z6.object({ question:
|
|
2087
|
+
next: z6.object({ say: strs, then: z6.enum(["listen", "hold", "end", "none"]), waitFor: strs, reason: str2, instructions: strs }).strict(),
|
|
2088
|
+
messages: z6.array(z6.object({ key: str2, to: str2, text: str2, about: strs, entries: strs, owed: strs, inviteToCall: z6.boolean() }).strict()),
|
|
2089
|
+
entries: z6.array(z6.object({ key: str2, from: str2, on: strs }).strict()),
|
|
2090
|
+
answers: z6.array(z6.object({ question: str2, entries: strs, summary: str2, picked: strs }).strict()),
|
|
2055
2091
|
changes: z6.array(z6.object({
|
|
2056
|
-
key:
|
|
2092
|
+
key: str2,
|
|
2057
2093
|
what: z6.enum(["goal", "question", "lesson"]),
|
|
2058
2094
|
op: z6.enum(["create", "edit", "assign", "open", "complete", "cancel", "defer", "move", "block", "unblock", "withdraw", "remember", "revise"]),
|
|
2059
|
-
id:
|
|
2060
|
-
text:
|
|
2061
|
-
title:
|
|
2062
|
-
who:
|
|
2063
|
-
under:
|
|
2095
|
+
id: str2,
|
|
2096
|
+
text: str2,
|
|
2097
|
+
title: str2,
|
|
2098
|
+
who: str2,
|
|
2099
|
+
under: str2,
|
|
2064
2100
|
gate: z6.enum(["start", "complete", "answer", "none"]),
|
|
2065
|
-
options: z6.array(z6.object({ id:
|
|
2101
|
+
options: z6.array(z6.object({ id: str2, label: str2 }).strict()),
|
|
2066
2102
|
pick: z6.enum(["one", "many", "rank", "words"]),
|
|
2067
2103
|
entries: strs
|
|
2068
2104
|
}).strict()),
|
|
2069
2105
|
feedback: z6.array(strs),
|
|
2070
|
-
search: z6.object({ query:
|
|
2106
|
+
search: z6.object({ query: str2, within: strs, goal: str2 }).strict()
|
|
2071
2107
|
}).strict();
|
|
2072
2108
|
var COMPACT_RESULT_JSON_SCHEMA = (({ $schema: _, ...rest }) => rest)(
|
|
2073
2109
|
zodToJsonSchema(CompactResultSchema, { $refStrategy: "none" })
|
|
2074
2110
|
);
|
|
2075
|
-
var
|
|
2111
|
+
var str3 = z7.string();
|
|
2076
2112
|
var strs2 = z7.array(z7.string());
|
|
2077
2113
|
var TalkerReplySchema = z7.object({
|
|
2078
2114
|
/** What to say and send, messages to the person first: spoken in the order written. `to` is "user"
|
|
2079
|
-
* or an agent's handle; `
|
|
2080
|
-
*
|
|
2081
|
-
|
|
2115
|
+
* or an agent's handle; `sentences` is what a message to the person says, one short sentence each
|
|
2116
|
+
* ([] to an agent); `text` is what a message to an agent says ("" to the person); `summary` is what it
|
|
2117
|
+
* asks the agent, in under ten words, as the person would put it ("" to the person; owner, 2026-10-15:
|
|
2118
|
+
* "Yes, add the summary"), which the recap's "Sent to <agent>: …" row shows; `about` names
|
|
2119
|
+
* handles; `blocks` is the item a question to an agent must be answered before ("" for none);
|
|
2120
|
+
* `callback` is true on a message to the agent doing work the person asked to be called back about
|
|
2121
|
+
* once it is done (false otherwise): that agent then owes the call (turns.md, step 0). */
|
|
2122
|
+
messages: z7.array(z7.object({ key: str3, to: str3, sentences: strs2, text: str3, summary: str3, about: strs2, blocks: str3, callback: z7.boolean() }).strict()),
|
|
2082
2123
|
/** What the call does next: listen, hold (the person asked for a moment) or end (they asked to). */
|
|
2083
2124
|
then: z7.enum(["listen", "hold", "end"]),
|
|
2084
2125
|
/** The person's replies to items (replies, owner 2026-10-07): the item's handle, the chosen option
|
|
2085
2126
|
* IDs, the line handles, how they replied in under ten words (keeping any condition), and `defer`:
|
|
2086
2127
|
* "" when their words settle the item, else what a reply that puts it off waits for -- "call" (the
|
|
2087
2128
|
* end of this call), a question's handle (that question's answer) or an ISO time. */
|
|
2088
|
-
replies: z7.array(z7.object({ item:
|
|
2129
|
+
replies: z7.array(z7.object({ item: str3, options: strs2, lines: strs2, summary: str3, defer: str3 }).strict()),
|
|
2089
2130
|
/** The line handles that tell the talker how to run this call; they last until it ends and reach no agent. */
|
|
2090
2131
|
instruction: strs2,
|
|
2091
2132
|
/** The line handles the filer acts on, and the only ones it reads (3e): new work, a change to existing
|
|
2092
2133
|
* work, feedback on Paigy, anything said to an agent, and any rule meant to outlast the call. */
|
|
2093
2134
|
file: strs2,
|
|
2094
2135
|
/** Evidence to fetch for a second round: a search, an item's full text, or an agent by name. */
|
|
2095
|
-
need: z7.object({ kind: z7.enum(["search", "item", "agent", ""]), text:
|
|
2136
|
+
need: z7.object({ kind: z7.enum(["search", "item", "agent", ""]), text: str3 }).strict(),
|
|
2096
2137
|
/** The handle of the item to explain ("" for none). */
|
|
2097
|
-
explain:
|
|
2138
|
+
explain: str3
|
|
2098
2139
|
}).strict();
|
|
2099
2140
|
var TALKER_REPLY_JSON_SCHEMA = (({ $schema: _, ...rest }) => rest)(
|
|
2100
2141
|
zodToJsonSchema(TalkerReplySchema, { $refStrategy: "none" })
|
|
2101
2142
|
);
|
|
2102
|
-
var
|
|
2143
|
+
var str4 = z8.string();
|
|
2103
2144
|
var strs3 = z8.array(z8.string());
|
|
2104
2145
|
var FilerReplySchema = z8.object({
|
|
2105
2146
|
/** Which Goals each new line goes on: a line's handle, Goal handles (or keys of new Goals), and what
|
|
2106
2147
|
* the line says in at most ten words. */
|
|
2107
|
-
filed: z8.array(z8.object({ line:
|
|
2148
|
+
filed: z8.array(z8.object({ line: str4, goals: strs3, summary: str4 }).strict()),
|
|
2108
2149
|
goals: z8.array(z8.object({
|
|
2109
2150
|
op: z8.enum(["create", "edit", "complete", "cancel", "reopen", "assign", "defer", "move", "block", "unblock"]),
|
|
2110
|
-
key:
|
|
2111
|
-
goal:
|
|
2112
|
-
title:
|
|
2113
|
-
outcome:
|
|
2114
|
-
owner:
|
|
2115
|
-
under:
|
|
2116
|
-
until:
|
|
2117
|
-
on:
|
|
2151
|
+
key: str4,
|
|
2152
|
+
goal: str4,
|
|
2153
|
+
title: str4,
|
|
2154
|
+
outcome: str4,
|
|
2155
|
+
owner: str4,
|
|
2156
|
+
under: str4,
|
|
2157
|
+
until: str4,
|
|
2158
|
+
on: str4,
|
|
2118
2159
|
gate: z8.enum(["start", "complete", "answer", ""]),
|
|
2119
|
-
why:
|
|
2160
|
+
why: str4
|
|
2120
2161
|
}).strict()),
|
|
2121
2162
|
questions: z8.array(z8.object({
|
|
2122
2163
|
op: z8.enum(["create", "edit", "assign", "withdraw"]),
|
|
2123
|
-
key:
|
|
2124
|
-
question:
|
|
2125
|
-
text:
|
|
2126
|
-
summary:
|
|
2127
|
-
to:
|
|
2128
|
-
goal:
|
|
2129
|
-
options: z8.array(z8.object({ id:
|
|
2164
|
+
key: str4,
|
|
2165
|
+
question: str4,
|
|
2166
|
+
text: str4,
|
|
2167
|
+
summary: str4,
|
|
2168
|
+
to: str4,
|
|
2169
|
+
goal: str4,
|
|
2170
|
+
options: z8.array(z8.object({ id: str4, label: str4 }).strict()),
|
|
2130
2171
|
pick: z8.enum(["one", "many", "rank", "words", ""]),
|
|
2131
|
-
blocks:
|
|
2172
|
+
blocks: str4
|
|
2132
2173
|
}).strict()),
|
|
2133
|
-
lessons: z8.array(z8.object({ op: z8.enum(["remember", "revise", "withdraw"]), lesson:
|
|
2174
|
+
lessons: z8.array(z8.object({ op: z8.enum(["remember", "revise", "withdraw"]), lesson: str4, text: str4, scope: str4 }).strict()),
|
|
2134
2175
|
/** Line handles whose words comment on Paigy itself. */
|
|
2135
2176
|
feedback: strs3
|
|
2136
2177
|
}).strict();
|
|
@@ -2191,6 +2232,27 @@ var TidyReplySchema = z10.object({
|
|
|
2191
2232
|
var TIDY_REPLY_JSON_SCHEMA = (({ $schema: _, ...rest }) => rest)(
|
|
2192
2233
|
zodToJsonSchema(TidyReplySchema, { $refStrategy: "none" })
|
|
2193
2234
|
);
|
|
2235
|
+
var HandoutReplySchema = z11.object({
|
|
2236
|
+
assign: z11.array(z11.object({
|
|
2237
|
+
/** The Goal's handle (G). */
|
|
2238
|
+
goal: z11.string(),
|
|
2239
|
+
/** The agent's handle (A). */
|
|
2240
|
+
to: z11.string(),
|
|
2241
|
+
/** At most ten words, naming the Goal of theirs it is most like: the reason the hand-out records. */
|
|
2242
|
+
why: z11.string()
|
|
2243
|
+
}).strict()),
|
|
2244
|
+
/** The Goals no listed agent's work is even loosely like: Paigy starts a session for them (owner, 2026-10-24,
|
|
2245
|
+
* Goal 37603006, "One per family of related Goals"). */
|
|
2246
|
+
new: z11.array(z11.object({
|
|
2247
|
+
/** The Goal's handle (G). */
|
|
2248
|
+
goal: z11.string(),
|
|
2249
|
+
/** At most ten words: why nothing active fits it. */
|
|
2250
|
+
why: z11.string()
|
|
2251
|
+
}).strict())
|
|
2252
|
+
}).strict();
|
|
2253
|
+
var HANDOUT_REPLY_JSON_SCHEMA = (({ $schema: _, ...rest }) => rest)(
|
|
2254
|
+
zodToJsonSchema(HandoutReplySchema, { $refStrategy: "none" })
|
|
2255
|
+
);
|
|
2194
2256
|
function entryWords(entry) {
|
|
2195
2257
|
const content = entry.content;
|
|
2196
2258
|
if (content && "sealed" in content) return "";
|
|
@@ -2226,42 +2288,6 @@ var LIVE_MS = 3 * 6e4;
|
|
|
2226
2288
|
var WORKING_MS = 60 * 6e4;
|
|
2227
2289
|
var WORKING_TIER_MS = 2 * 60 * 6e4;
|
|
2228
2290
|
var RECENT_TIER_MS = 24 * 60 * 6e4;
|
|
2229
|
-
var json = z11.lazy(() => z11.union([
|
|
2230
|
-
z11.string(),
|
|
2231
|
-
z11.number().finite(),
|
|
2232
|
-
z11.boolean(),
|
|
2233
|
-
z11.null(),
|
|
2234
|
-
z11.array(json),
|
|
2235
|
-
z11.record(json)
|
|
2236
|
-
]));
|
|
2237
|
-
var clock = z11.number().int().nonnegative().safe();
|
|
2238
|
-
var HeardEventSchema = z11.object({
|
|
2239
|
-
eventId: z11.string().uuid(),
|
|
2240
|
-
source: z11.enum(["phone", "bot"]),
|
|
2241
|
-
sequence: clock,
|
|
2242
|
-
kind: z11.string().min(1),
|
|
2243
|
-
phoneAtMs: clock.optional(),
|
|
2244
|
-
botAtMs: clock.optional(),
|
|
2245
|
-
payload: z11.record(json)
|
|
2246
|
-
}).strict();
|
|
2247
|
-
var HeardCursorSchema = HeardEventSchema.pick({ source: true, sequence: true, eventId: true });
|
|
2248
|
-
var HeardPageSchema = z11.object({
|
|
2249
|
-
events: z11.array(HeardEventSchema).max(200),
|
|
2250
|
-
next: HeardCursorSchema.nullable()
|
|
2251
|
-
}).strict();
|
|
2252
|
-
var MAX_EVENTS = 50;
|
|
2253
|
-
var MAX_BYTES = 8e4;
|
|
2254
|
-
var batchBytes = (events) => {
|
|
2255
|
-
let bytes = 0;
|
|
2256
|
-
for (const char of JSON.stringify({ events })) {
|
|
2257
|
-
const point = char.codePointAt(0);
|
|
2258
|
-
bytes += point < 128 ? 1 : point < 2048 ? 2 : point < 65536 ? 3 : 4;
|
|
2259
|
-
}
|
|
2260
|
-
return bytes;
|
|
2261
|
-
};
|
|
2262
|
-
var HeardBatchSchema = z11.object({
|
|
2263
|
-
events: z11.array(HeardEventSchema).min(1).max(MAX_EVENTS)
|
|
2264
|
-
}).strict().refine((value) => batchBytes(value.events) <= MAX_BYTES, "heard_batch_too_large");
|
|
2265
2291
|
var ContextSchema = z12.object({
|
|
2266
2292
|
title: z12.string().min(1).describe("One-line headline of what you need (required, non-empty)."),
|
|
2267
2293
|
description: z12.array(z12.string().min(1)).describe(
|
|
@@ -2593,6 +2619,10 @@ var AgendaTurnSchema = z12.object({
|
|
|
2593
2619
|
/** The spoken sentences of the turn, in order. No count: how long a turn is is the brain's call
|
|
2594
2620
|
* (owner, 2026-09-25), and a count here refused whole plans. */
|
|
2595
2621
|
info: z12.array(z12.string().min(1)).default([]),
|
|
2622
|
+
/** THE ID OF EACH SENTENCE, when the plan names them (turns.md): a talker message's sentences are its
|
|
2623
|
+
* `info`, one piece each, and `units[i]` is the id the bot's line receipt carries for `info[i]`
|
|
2624
|
+
* (`<cycle>:<key>:<n>`), so what was heard is known per sentence. Absent on every other turn. */
|
|
2625
|
+
units: z12.array(z12.string().min(1)).optional(),
|
|
2596
2626
|
question: z12.string().min(1).nullable(),
|
|
2597
2627
|
/** True on the one turn carrying the agent's own declared question. */
|
|
2598
2628
|
asks: z12.boolean().optional(),
|
|
@@ -2617,6 +2647,21 @@ var AgendaTurnSchema = z12.object({
|
|
|
2617
2647
|
* the phone (`asking`, so the agenda goes gold and its options show) without treating the line as a
|
|
2618
2648
|
* question turn — the talker owns re-asking and the waits, so `question` stays null. */
|
|
2619
2649
|
onTable: z12.boolean().optional(),
|
|
2650
|
+
/** THE CARRIED ITEM THIS LINE TELLS (Goal 2a1e50eb, owner 2026-10-14: "Build the whole design") — a
|
|
2651
|
+
* request the Call carries that asks NOTHING: a report, a progress note, another agent's waiting news.
|
|
2652
|
+
* Its request Entry id, so the phone can make that agenda row the current one while it is read
|
|
2653
|
+
* (`telling` on the `turn` topic, `docs/clients/app/walk/design.md` §11).
|
|
2654
|
+
*
|
|
2655
|
+
* A FIELD OF ITS OWN, NEVER `claimId`: the claim is the RETURN identity — answers route by it and the
|
|
2656
|
+
* record tags the line with it (`workId`) — and an answer must never route to an Entry that asks
|
|
2657
|
+
* nothing. Absent on a turn speaking for a question (`claimId` says that) and on one speaking for no
|
|
2658
|
+
* carried item at all (an opener, a sign-off, Paigy's own line). */
|
|
2659
|
+
telling: z12.string().optional(),
|
|
2660
|
+
/** PAIGY'S OWN LINE (owner, 2026-10-15; calls ed2cbdce, ad50ad25): a turn that speaks for no item -- an
|
|
2661
|
+
* opener, a sign-off, a reply about nothing an agent asked or told -- is recorded as Paigy's, not as the
|
|
2662
|
+
* agent that rang. Absent on every turn that speaks for an item (`agentId` names whose), and on plans
|
|
2663
|
+
* from before it: a bot that does not know it records the ringing agent, as before. */
|
|
2664
|
+
speaksFor: z12.literal("paigy").optional(),
|
|
2620
2665
|
select: SelectShapeSchema.optional(),
|
|
2621
2666
|
options: z12.array(OptionSchema.omit({ id: true })).optional(),
|
|
2622
2667
|
/* `pace` STOOD HERE (#826). A turn could carry seconds and the model chose them. The walk
|
|
@@ -2705,7 +2750,7 @@ var InboxItemSchema = z12.object({
|
|
|
2705
2750
|
questions: z12.array(CallQuestionSchema).optional(),
|
|
2706
2751
|
/** The same call carrying order, including request Entries with no DecisionNeed as reports.
|
|
2707
2752
|
* Additive: questions stays decision-only for every other surface and older bundles. */
|
|
2708
|
-
callItems: z12.array(CallQuestionSchema.extend({ state: z12.enum(["open", "answered", "report"]) })).optional(),
|
|
2753
|
+
callItems: z12.array(CallQuestionSchema.extend({ state: z12.enum(["open", "answered", "report"]), acknowledged: z12.boolean().optional() })).optional(),
|
|
2709
2754
|
visuals: z12.array(VisualSchema).optional(),
|
|
2710
2755
|
/** The connected agent's name (the single pairing name — user-typed, or the
|
|
2711
2756
|
* agent's suggestion, or a default silly name). */
|
|
@@ -2770,6 +2815,21 @@ var InboxItemSchema = z12.object({
|
|
|
2770
2815
|
* urgency (see the main README's "premier use case" + docs/delivery/notify/states.md). Drives the
|
|
2771
2816
|
* inbox's blocking badge and the extra confirm step before dismissing it. */
|
|
2772
2817
|
blocking: z12.boolean().default(false),
|
|
2818
|
+
/** WHAT FREED THIS QUESTION (owner, 2026-10-16, Goal 2383ef14: "we don't really show the question
|
|
2819
|
+
* at the top until the question it could reply to with is resolved. And then we show it again
|
|
2820
|
+
* with the context of the other thing that was resolved"; asked how it should carry that, "The
|
|
2821
|
+
* answer above it"). A question they answered with a question of their own waits for theirs
|
|
2822
|
+
* (`private.ask_back`) and drops out of the front while it waits; when it comes back, the card
|
|
2823
|
+
* draws their question and the answer it got ABOVE the ask, as one card. Absent on a question
|
|
2824
|
+
* nothing ever held back. */
|
|
2825
|
+
freedBy: z12.object({
|
|
2826
|
+
questionId: z12.string(),
|
|
2827
|
+
asked: z12.string(),
|
|
2828
|
+
answer: z12.string(),
|
|
2829
|
+
answeredAt: z12.string(),
|
|
2830
|
+
/** The answer in ten words, when the talker wrote one beside it. */
|
|
2831
|
+
summary: z12.string().optional()
|
|
2832
|
+
}).optional(),
|
|
2773
2833
|
/** The user's locked-in answer; present only for replied items (GET /api/replied/:id). */
|
|
2774
2834
|
answer: UserAnswerSchema.optional(),
|
|
2775
2835
|
/** THE TARGET FACTS A CARD RENDERS (#1796 point 5, 2026-09-11): the Delivery it is a view of,
|
|
@@ -2829,8 +2889,8 @@ var MissedCallSchema = z12.enum([
|
|
|
2829
2889
|
"inbox",
|
|
2830
2890
|
"dismiss"
|
|
2831
2891
|
]);
|
|
2832
|
-
var
|
|
2833
|
-
var QUIET = ` Nothing rings from ${
|
|
2892
|
+
var clock = (h) => h === 0 ? "midnight" : h === 12 ? "noon" : h < 12 ? `${h} am` : `${h - 12} pm`;
|
|
2893
|
+
var QUIET = ` Nothing rings from ${clock(NIGHT.from)} to ${clock(NIGHT.to)} your time; the count waits for morning.`;
|
|
2834
2894
|
var BrokerTuningSchema = z12.object({
|
|
2835
2895
|
/** 'none' = skip the spoken ack after a mapped answer (power users find it slow). */
|
|
2836
2896
|
ackVerbosity: z12.enum(["normal", "none"]).optional(),
|
|
@@ -3167,6 +3227,13 @@ var QueueItemSchema = z12.object({
|
|
|
3167
3227
|
* can see (`replies`, `questions[].answeredAt`) miss a spontaneous note entirely — a `request`
|
|
3168
3228
|
* Entry with no `about_id` is in neither. */
|
|
3169
3229
|
lastPersonAt: z12.string().nullable().optional(),
|
|
3230
|
+
/** EACH SIDE'S NEWEST WORD IN THE LAST DAY (owner, 2026-10-13, the Work tab's order): the person's
|
|
3231
|
+
* (`yours`) and the agents' (`theirs`), each null when that side wrote nothing on it in 24 hours.
|
|
3232
|
+
* `latest` holds one Entry, so whichever side wrote first is hidden there; Work orders a Goal by
|
|
3233
|
+
* these two and draws the side it was placed by under its title. Optional, so hand-built queues
|
|
3234
|
+
* and a door older than 20261013045542 need not spell them. */
|
|
3235
|
+
yours: GoalLatestSchema.nullable().optional(),
|
|
3236
|
+
theirs: GoalLatestSchema.nullable().optional(),
|
|
3170
3237
|
/** WHAT THIS ROW IS, IN TWELVE CHARACTERS (#2928) — the hash of every other field on it, stamped
|
|
3171
3238
|
* by the one projection that builds the row (`apps/api/src/goal/queue.ts`). It is how the
|
|
3172
3239
|
* incremental read knows a row has not moved: the phone echoes back the revs it holds
|
|
@@ -3440,10 +3507,20 @@ var CallRecapSchema = z12.object({
|
|
|
3440
3507
|
title: z12.string(),
|
|
3441
3508
|
owner: z12.string(),
|
|
3442
3509
|
state: z12.string(),
|
|
3510
|
+
/** Presented Entry content and its author, separately from the current Goal owner. */
|
|
3511
|
+
items: z12.array(z12.object({ entryId: z12.string(), author: z12.string(), text: z12.string(), summary: z12.string().nullable(), acknowledged: z12.boolean().optional() })).optional(),
|
|
3443
3512
|
/** Whether the call put it to the person. An item it carried and never said has no row on the
|
|
3444
3513
|
* review (owner, 2026-10-08: "why do we get the third one when it didn't happen in the call?"). */
|
|
3445
3514
|
presented: z12.boolean(),
|
|
3446
|
-
|
|
3515
|
+
/** Whether THIS call created it — the third way a call touches work, beside carrying a request
|
|
3516
|
+
* there and filing words there (owner, 2026-10-08, Goal `5b4b1a0a`: "Show the new work, keep my
|
|
3517
|
+
* words under it"). Created work is never carried, so it is never `presented`; without this the
|
|
3518
|
+
* row is dropped by the "only what happened on the call" filter. False on a database before
|
|
3519
|
+
* 20261013080133. */
|
|
3520
|
+
created: z12.boolean(),
|
|
3521
|
+
/** `request` is the Entry that asked it — what a line's `about` names when the line answered or put
|
|
3522
|
+
* it off. Optional: an older API sent none. */
|
|
3523
|
+
questions: z12.array(z12.object({ id: z12.string().uuid(), state: z12.string(), title: z12.string(), request: z12.string().optional() })),
|
|
3447
3524
|
/** `words` is always what they SAID, verbatim — the record, never replaced. `summary` is what
|
|
3448
3525
|
* the line says in ten words (owner, 2026-10-07): the filer's, or the talker's for the answer it
|
|
3449
3526
|
* gave, so the row scans like a chosen option and their own words stay under it. Absent when
|
|
@@ -3479,7 +3556,44 @@ var CallRecapSchema = z12.object({
|
|
|
3479
3556
|
})),
|
|
3480
3557
|
more: z12.object({ lines: z12.number(), entries: z12.number(), topics: z12.number() }),
|
|
3481
3558
|
/** Last stored position on this page when another exists; absent before paging shipped. */
|
|
3482
|
-
next: z12.number().int().nonnegative().nullable().optional()
|
|
3559
|
+
next: z12.number().int().nonnegative().nullable().optional(),
|
|
3560
|
+
/** THE CALL AS ONE LIST OF ROWS (owner, 2026-10-14: "we only really want a thing like transcript but
|
|
3561
|
+
* built from the summaries", then "the transcript tabs should show the same but with full words").
|
|
3562
|
+
* Both tabs draw these rows, in this order: Summary from `summary`, Transcript from `words`.
|
|
3563
|
+
* - `put`: an item put to the person, at the first agent line that voiced it. Paigy's sentences
|
|
3564
|
+
* that voiced it are folded into `spoken`, never rows of their own.
|
|
3565
|
+
* - `said`: the person's words, one row per reply or per filed line no reply covers.
|
|
3566
|
+
* - `did`: what Paigy did ("Sent to Mouth: …", "Recorded: …", "Filed on …").
|
|
3567
|
+
* `by` is the row's real author, never inferred from `kind`: a relay Paigy sent to an agent is
|
|
3568
|
+
* Paigy's, not the person's. Optional and additive (owner: "make sure whatever you do is backward
|
|
3569
|
+
* compatible"): an API before it sends none, and the screen falls back to `topics` and `said`. */
|
|
3570
|
+
timeline: z12.array(z12.object({
|
|
3571
|
+
id: z12.string(),
|
|
3572
|
+
position: z12.number(),
|
|
3573
|
+
atMs: z12.number(),
|
|
3574
|
+
kind: z12.enum(["put", "said", "did"]),
|
|
3575
|
+
by: z12.object({ participant: z12.string().nullable(), agentId: z12.string().nullable(), name: z12.string().nullable() }),
|
|
3576
|
+
goalId: z12.string().uuid().nullable(),
|
|
3577
|
+
requestId: z12.string().nullable(),
|
|
3578
|
+
summary: z12.string().nullable(),
|
|
3579
|
+
words: z12.string(),
|
|
3580
|
+
/** Paigy's sentences folded into this row: on a `put` row, what it said putting the item to the
|
|
3581
|
+
* person (before their next row); on a `said` row, what it said in reply (until their next row).
|
|
3582
|
+
* `atMs` is when each was said; optional, absent before 2026-10-14's fix. */
|
|
3583
|
+
spoken: z12.array(z12.object({ lineId: z12.string(), words: z12.string(), atMs: z12.number().optional() })),
|
|
3584
|
+
/** On a `said` row: the work these words were filed on, and whether they answered (recorded) a
|
|
3585
|
+
* question. They replace the "Filed on ..." and "Recorded: ..." rows that repeated the person's own
|
|
3586
|
+
* summary (Brain, 2026-10-14). Optional: absent from an API before it. */
|
|
3587
|
+
filedOn: z12.array(z12.object({ goalId: z12.string().uuid(), title: z12.string() })).optional(),
|
|
3588
|
+
recorded: z12.boolean().optional(),
|
|
3589
|
+
settled: z12.object({ requestId: z12.string(), answer: z12.string() }).nullable().optional(),
|
|
3590
|
+
acknowledged: z12.boolean().optional(),
|
|
3591
|
+
/** On a `put` row: still waiting for the person's answer (not settled, not answered, not put off).
|
|
3592
|
+
* The server's judgement; the screen draws "Still waiting for your answer" from it. Optional: absent
|
|
3593
|
+
* from an API before it, where the screen falls back to its own reading. */
|
|
3594
|
+
waiting: z12.boolean().optional(),
|
|
3595
|
+
lineIds: z12.array(z12.string())
|
|
3596
|
+
})).optional()
|
|
3483
3597
|
});
|
|
3484
3598
|
function sessionSlot(sessionId2) {
|
|
3485
3599
|
const id2 = sessionId2 ?? sessionId();
|
|
@@ -3586,6 +3700,14 @@ async function requestCode(suggestedName = agentName(), device) {
|
|
|
3586
3700
|
if (!res.ok) throw new Error(`/api/device/code failed: ${res.status} ${await res.text()}`);
|
|
3587
3701
|
return await res.json();
|
|
3588
3702
|
}
|
|
3703
|
+
var ServerFault = class extends Error {
|
|
3704
|
+
constructor(status) {
|
|
3705
|
+
super(`Paigy's server failed (HTTP ${status}) while checking the code.`);
|
|
3706
|
+
this.status = status;
|
|
3707
|
+
this.name = "ServerFault";
|
|
3708
|
+
}
|
|
3709
|
+
status;
|
|
3710
|
+
};
|
|
3589
3711
|
async function pollToken(deviceCode) {
|
|
3590
3712
|
const res = await reach(`${BACKEND_URL}/api/device/token`, {
|
|
3591
3713
|
method: "POST",
|
|
@@ -3593,6 +3715,7 @@ async function pollToken(deviceCode) {
|
|
|
3593
3715
|
body: JSON.stringify({ device_code: deviceCode })
|
|
3594
3716
|
});
|
|
3595
3717
|
if (res.ok) return await res.json();
|
|
3718
|
+
if (res.status >= 500) throw new ServerFault(res.status);
|
|
3596
3719
|
const body = await res.json().catch(() => ({ error: "unknown" }));
|
|
3597
3720
|
const err = body.error ?? "unknown";
|
|
3598
3721
|
if (err === "authorization_pending") return null;
|
|
@@ -3954,6 +4077,9 @@ async function receiveContact(input, opts = {}) {
|
|
|
3954
4077
|
throw error;
|
|
3955
4078
|
}
|
|
3956
4079
|
}
|
|
4080
|
+
function viaLine(via) {
|
|
4081
|
+
return via ? `a card they shared by link${via.decidedBy ? `, decided by ${via.decidedBy}` : ""}` : void 0;
|
|
4082
|
+
}
|
|
3957
4083
|
function compact(o) {
|
|
3958
4084
|
return Object.fromEntries(Object.entries(o).filter(([, v]) => v !== void 0 && v !== null && v !== "" && !(Array.isArray(v) && v.length === 0)));
|
|
3959
4085
|
}
|
|
@@ -3977,7 +4103,8 @@ function decided(result) {
|
|
|
3977
4103
|
return void 0;
|
|
3978
4104
|
}
|
|
3979
4105
|
}
|
|
3980
|
-
function stateOf(state, answer, decided2) {
|
|
4106
|
+
function stateOf(state, answer, decided2, withdrawn) {
|
|
4107
|
+
if (withdrawn && state === "answered") return "closed";
|
|
3981
4108
|
return state === "answered" && answer && decided2 === void 0 ? "replied" : state;
|
|
3982
4109
|
}
|
|
3983
4110
|
var handle = (entryId) => entryId.slice(0, 8);
|
|
@@ -4006,10 +4133,11 @@ function conversation(e) {
|
|
|
4006
4133
|
at: at(entry.createdAt),
|
|
4007
4134
|
said: sealed ? "[encrypted]" : entryWords(entry).trim(),
|
|
4008
4135
|
caveat: entry.callOngoing ? "Call ongoing; what the person decides may change." : void 0,
|
|
4136
|
+
via: viaLine(entry.via),
|
|
4009
4137
|
units: askUnits(entry, e.entries ?? []).map((u) => `${u.title}: ${u.body}`),
|
|
4010
4138
|
re: re ? handle(re) : void 0,
|
|
4011
4139
|
options,
|
|
4012
|
-
decision: need ? compact({ state: stateOf(need.state, answer, decision), answer: decision }) : void 0
|
|
4140
|
+
decision: need ? compact({ state: stateOf(need.state, answer, decision, need.withdrawn), answer: decision, via: viaLine(answer?.via) }) : void 0
|
|
4013
4141
|
});
|
|
4014
4142
|
});
|
|
4015
4143
|
}
|
|
@@ -4177,7 +4305,7 @@ function receivedView(r, now = Date.now()) {
|
|
|
4177
4305
|
...rings.map((r2) => rerings(r2, now)),
|
|
4178
4306
|
...assigned.length ? [`${assigned.length} of your Goals are assigned to you and not started (assigned): read one with get_goals({goalIds:[goalId]}); your first write to it starts it.`] : [],
|
|
4179
4307
|
...w.claimable && !assigned.length ? [`Next waiting on you: ${w.claimable.title ?? w.claimable.goalId} (get_goals({ goalIds: ["${w.claimable.goalId}"] })).`] : [],
|
|
4180
|
-
...stalled.length ? [`${stalled.length} of your Goals have had no progress${stalled.length === 1 ? " " : ""}${quietFor(stalled, now)}: report on each with a contact update, or finish or
|
|
4308
|
+
...stalled.length ? [`${stalled.length} of your Goals have had no progress${stalled.length === 1 ? " " : ""}${quietFor(stalled, now)}: report on each with a contact update, or finish, cancel or defer it with manage_goals.`] : [],
|
|
4181
4309
|
// The COUNT, oldest three, and where to read them (owner, 2026-10-08): it was 34 rows of
|
|
4182
4310
|
// other agents' work on every window, ahead of this agent's own next step.
|
|
4183
4311
|
...others ? [`${others.count} of other agents' Goals have gone quiet${others.count === 1 ? " " : ""}${quietFor([{ since: others.oldestSince }], now, others.count)}: The oldest three are in others.goals: get_goals({goalIds:[goalId]}) reads one in full. A write to it puts you on it without changing its owner.`] : [],
|
|
@@ -4522,6 +4650,7 @@ export {
|
|
|
4522
4650
|
deleteToken,
|
|
4523
4651
|
revokeToken,
|
|
4524
4652
|
requestCode,
|
|
4653
|
+
ServerFault,
|
|
4525
4654
|
pollToken,
|
|
4526
4655
|
UnpairedError,
|
|
4527
4656
|
RevokedError,
|