pidge-cli 0.15.0 → 0.15.2
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/CHANGELOG.md +23 -0
- package/bin/pidge.js +80 -19
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.15.2 — #280 the skill self-heals
|
|
4
|
+
|
|
5
|
+
#280 — the local skill self-heals: any pidge command silently refreshes
|
|
6
|
+
`.claude/skills/pidge/SKILL.md` when the skill revision or manifest version is newer than
|
|
7
|
+
what's installed, so onboarded agents always run the latest skill.
|
|
8
|
+
|
|
9
|
+
- **feat:** a bumpable `SKILL_REVISION` constant + the live manifest version are baked into a
|
|
10
|
+
first-line marker (`<!-- pidge-skill rev=R manifest=N -->`) of every generated `SKILL.md`.
|
|
11
|
+
`ensureSkillFresh()` (run from `checkManifestNews`, which already fires on every command via
|
|
12
|
+
the `x-pidge-manifest-version` header) compares the installed marker against this CLI's spine
|
|
13
|
+
and the server's manifest; when either is newer it silently regenerates the skill and prints
|
|
14
|
+
one stderr note. Only an EXISTING skill is refreshed (never auto-created), at most once per
|
|
15
|
+
process, fully best-effort (a refresh failure never breaks your command), and `QUIET_NAG`
|
|
16
|
+
suppresses the note (the regenerate still happens).
|
|
17
|
+
- **note:** this composes with `@latest` — an agent on `npx pidge-cli@latest` picks up a new
|
|
18
|
+
`SKILL_REVISION` and self-heals the spine on its next command. A PINNED CLI still self-heals
|
|
19
|
+
on a server manifest bump (via the header) but can't gain a newer hand-authored spine without
|
|
20
|
+
updating the CLI. BUMP `SKILL_REVISION` in any future sprint that edits the SKILL.md spine.
|
|
21
|
+
|
|
22
|
+
## 0.15.1 — #274-D skill polish
|
|
23
|
+
|
|
24
|
+
skill polish — catalog-first actions, write-for-the-lock-screen (banner = title+body; body_markdown is detail-only), good-report guidance; gold examples now set a plain --body.
|
|
25
|
+
|
|
3
26
|
## 0.15.0 — #274 CLI redesign (F1)
|
|
4
27
|
|
|
5
28
|
-m/--body-markdown-file input chain, --gated, English hello, --template off the help menu (still accepted), nag knows v46, --wait defaults to 60 min for decisions.
|
package/bin/pidge.js
CHANGED
|
@@ -562,8 +562,17 @@ function fetchT(url, opts = {}, timeoutMs = 30000) {
|
|
|
562
562
|
// than what this CLI shipped knowing, nudge on stderr — the agent re-reads the
|
|
563
563
|
// manifest (whats_new) and learns the new capabilities without polling.
|
|
564
564
|
const KNOWN_MANIFEST_VERSION = 46;
|
|
565
|
+
// #280: the hand-authored skill SPINE version. BUMP whenever the SKILL.md spine
|
|
566
|
+
// (the non-generated prose in installSkill) changes — an existing install whose
|
|
567
|
+
// baked marker is older than this self-heals on its next pidge command, so an
|
|
568
|
+
// onboarded agent always runs the latest skill without any human action. Start at 1.
|
|
569
|
+
const SKILL_REVISION = 1;
|
|
565
570
|
const NAG_TTL_MS = 24 * 60 * 60 * 1000; // #241: at most one nag per 24 h
|
|
566
571
|
let newsWarned = false;
|
|
572
|
+
// #280: the self-heal runs at most ONCE per process (one regeneration, even when
|
|
573
|
+
// many commands/poll-ticks call checkManifestNews). Non-stale checks stay cheap +
|
|
574
|
+
// repeatable; this only latches once an actual heal is attempted.
|
|
575
|
+
let skillHealed = false;
|
|
567
576
|
|
|
568
577
|
// #241: a tiny per-install state cache (~/.config/pidge/state.json, per-agent
|
|
569
578
|
// when PIDGE_AGENT is set — same dir as the env file). Best-effort: a read-only
|
|
@@ -581,9 +590,14 @@ function writeState(patch) {
|
|
|
581
590
|
} catch { /* best-effort — the nag just won't persist its throttle */ }
|
|
582
591
|
}
|
|
583
592
|
|
|
584
|
-
function checkManifestNews(res) {
|
|
585
|
-
if (QUIET_NAG || newsWarned) return;
|
|
593
|
+
async function checkManifestNews(res) {
|
|
586
594
|
const ver = parseInt(res.headers.get('x-pidge-manifest-version') || '0', 10);
|
|
595
|
+
// #280: the self-heal runs on EVERY command (its own once-guard + cheap
|
|
596
|
+
// first-line read), BEFORE the nag throttle below — it must fire even when the
|
|
597
|
+
// server isn't ahead of KNOWN_MANIFEST_VERSION (a pure spine bump) and even
|
|
598
|
+
// under QUIET_NAG (which only silences the stderr note, never the regenerate).
|
|
599
|
+
await ensureSkillFresh(ver);
|
|
600
|
+
if (QUIET_NAG || newsWarned) return;
|
|
587
601
|
// (c) only when the server is ahead of what THIS CLI knows.
|
|
588
602
|
if (!(ver > KNOWN_MANIFEST_VERSION)) return;
|
|
589
603
|
// #241 throttle: nag at most once per 24 h, and after that window only when the
|
|
@@ -607,6 +621,38 @@ function checkManifestNews(res) {
|
|
|
607
621
|
console.error(`pidge: the server has NEW capabilities (manifest v${ver}; this CLI knows v${KNOWN_MANIFEST_VERSION}) — pidge is a thin pipe, so you can use any new /notify field RIGHT NOW via --param KEY=VALUE. Read the catalog (whats_new) in the public manifest: curl $PIDGE_URL/api/v1/manifest (public; add -H "Authorization: Bearer $PIDGE_TOKEN" to also see your channel's config). Updating the CLI only matters to gain native flags: npx pidge-cli@latest (a pinned ref never self-updates). Silence this with --quiet-nag or PIDGE_QUIET_NAG=1.`);
|
|
608
622
|
}
|
|
609
623
|
|
|
624
|
+
// #280: STRUCTURAL self-heal — keep the LOCAL skill current with zero human action.
|
|
625
|
+
// The installed .claude/skills/pidge/SKILL.md is written once at onboarding and then
|
|
626
|
+
// goes stale silently (a CLI/skill improvement gives an onboarded agent no signal, so
|
|
627
|
+
// it keeps running the old skill). This silently regenerates it when EITHER trigger
|
|
628
|
+
// fires: this CLI's hand-authored spine moved (SKILL_REVISION > the baked rev) OR the
|
|
629
|
+
// server's manifest moved (serverManifestVersion > the baked manifest) — caught from
|
|
630
|
+
// the x-pidge-manifest-version header that already rides every response. So the agent's
|
|
631
|
+
// NEXT session is always current. Only REFRESHES an existing skill (creating one is
|
|
632
|
+
// onboarding's job, never a side effect of an unrelated command), runs at most once per
|
|
633
|
+
// process, and is wholly best-effort: any failure is swallowed — a skill refresh must
|
|
634
|
+
// NEVER break the user's actual command.
|
|
635
|
+
async function ensureSkillFresh(serverManifestVersion) {
|
|
636
|
+
if (skillHealed) return;
|
|
637
|
+
try {
|
|
638
|
+
// Resolve the path the SAME way installSkill does (cwd-relative).
|
|
639
|
+
const file = path.join(process.cwd(), '.claude', 'skills', 'pidge', 'SKILL.md');
|
|
640
|
+
if (!fs.existsSync(file)) return; // don't auto-create — only refresh an existing skill
|
|
641
|
+
const firstLine = fs.readFileSync(file, 'utf8').split('\n', 1)[0] || '';
|
|
642
|
+
const revM = firstLine.match(/rev=(\d+)/);
|
|
643
|
+
const manM = firstLine.match(/manifest=(\d+)/);
|
|
644
|
+
const installedRev = revM ? parseInt(revM[1], 10) : 0;
|
|
645
|
+
const installedManifest = manM ? parseInt(manM[1], 10) : 0;
|
|
646
|
+
const stale = SKILL_REVISION > installedRev || (serverManifestVersion || 0) > installedManifest;
|
|
647
|
+
if (!stale) return;
|
|
648
|
+
skillHealed = true; // latch BEFORE the network write — attempt the heal at most once
|
|
649
|
+
const r = await installSkill(BASE, TOKEN); // silent: it already writes the file
|
|
650
|
+
// Respect QUIET_NAG/PIDGE_QUIET_NAG for the note only — we STILL regenerated.
|
|
651
|
+
if (!QUIET_NAG)
|
|
652
|
+
console.error(`pidge: refreshed your local Pidge skill (rev ${SKILL_REVISION}, manifest v${r.manifest_version}) — your next session will use it.`);
|
|
653
|
+
} catch { /* best-effort — a skill refresh must never break the user's command */ }
|
|
654
|
+
}
|
|
655
|
+
|
|
610
656
|
// ---------------------------------------------------------------------------
|
|
611
657
|
// #119: the health ledger of one blocking session (wait/ask/listen). Drives
|
|
612
658
|
// (a) automatic DEGRADE from held ?wait= polls to plain GETs after
|
|
@@ -976,7 +1022,7 @@ async function doNotify(extra = {}) {
|
|
|
976
1022
|
} catch (e) {
|
|
977
1023
|
die(`pidge: send failed (network): ${e.message}`, 2);
|
|
978
1024
|
}
|
|
979
|
-
checkManifestNews(res);
|
|
1025
|
+
await checkManifestNews(res);
|
|
980
1026
|
const ok = res.status >= 200 && res.status < 300;
|
|
981
1027
|
let info = {};
|
|
982
1028
|
try { info = JSON.parse(raw); } catch { /* leave {} */ }
|
|
@@ -1100,7 +1146,7 @@ async function doWait(cid, { timeout, interval }) {
|
|
|
1100
1146
|
const askedAt = Date.now();
|
|
1101
1147
|
try {
|
|
1102
1148
|
const res = await fetchT(url, { headers }, (waitS + 10) * 1000);
|
|
1103
|
-
checkManifestNews(res);
|
|
1149
|
+
await checkManifestNews(res);
|
|
1104
1150
|
if (res.status === 200) {
|
|
1105
1151
|
health.ok();
|
|
1106
1152
|
const data = await res.json().catch(() => ({}));
|
|
@@ -1414,7 +1460,7 @@ async function runContract() {
|
|
|
1414
1460
|
} catch (e) {
|
|
1415
1461
|
die(`pidge: contract set failed (network): ${e.message}`, 2);
|
|
1416
1462
|
}
|
|
1417
|
-
checkManifestNews(res);
|
|
1463
|
+
await checkManifestNews(res);
|
|
1418
1464
|
if (!(res.status >= 200 && res.status < 300)) die(`pidge: contract set failed (${res.status}): ${body}`, 2);
|
|
1419
1465
|
// stdout = ONLY the operating_contract, never the raw channel JSON. The
|
|
1420
1466
|
// /channels PATCH echoes the whole channel — INCLUDING "key":"hld_…" — and
|
|
@@ -1464,7 +1510,7 @@ async function doSelftest() {
|
|
|
1464
1510
|
const res = await fetchT(`${BASE}/api/v1/selftest`, {
|
|
1465
1511
|
method: 'POST', headers, body: JSON.stringify({ window_seconds: windowS }),
|
|
1466
1512
|
});
|
|
1467
|
-
checkManifestNews(res);
|
|
1513
|
+
await checkManifestNews(res);
|
|
1468
1514
|
if (res.status < 200 || res.status >= 300) die(`pidge: selftest: the server refused (${res.status}) — is your key valid? try \`pidge doctor\``, 2);
|
|
1469
1515
|
fired = await res.json();
|
|
1470
1516
|
} catch (e) {
|
|
@@ -1537,7 +1583,7 @@ async function runDoctor(base = BASE, token = TOKEN, sourceLabel = null) {
|
|
|
1537
1583
|
process.exit(2);
|
|
1538
1584
|
}
|
|
1539
1585
|
const { res, data } = out;
|
|
1540
|
-
checkManifestNews(res);
|
|
1586
|
+
await checkManifestNews(res);
|
|
1541
1587
|
if (res.status === 401) {
|
|
1542
1588
|
console.error('pidge doctor: server reachable but the key is INVALID/REVOKED — re-onboard: ask your human for a fresh claim code (Pidge app → Canais → o canal → copiar prompt de setup)');
|
|
1543
1589
|
process.exit(2);
|
|
@@ -1719,7 +1765,8 @@ async function installSkill(base = BASE, token = TOKEN) {
|
|
|
1719
1765
|
const profileTable = (m.profiles && m.profiles.decision_table) || [];
|
|
1720
1766
|
const notes = m.notes || [];
|
|
1721
1767
|
const exits = (m.cli && m.cli.output) || '';
|
|
1722
|
-
const skill =
|
|
1768
|
+
const skill = `<!-- pidge-skill rev=${SKILL_REVISION} manifest=${m.manifest_version} -->
|
|
1769
|
+
---
|
|
1723
1770
|
name: pidge
|
|
1724
1771
|
description: Send rich, actionable iPhone notifications to your human and get their decision back (Pidge). Every send is a TYPE (message/important/urgent/event/live) plus an OPTIONAL response (buttons + send-and-go vs wait). Use when finishing long tasks, needing a decision/approval, sending updates with substance, or anything time-anchored. Also covers reading the human's replies back.
|
|
1725
1772
|
---
|
|
@@ -1748,6 +1795,13 @@ Every send is **a TYPE + a markdown body + an OPTIONAL response**. The TYPE (one
|
|
|
1748
1795
|
|
|
1749
1796
|
⭐ \`important\` is the default. On the fence between informing and asking, pick \`important\`. \`message\` is only for a true no-action FYI. (\`fyi\`/\`report\`/\`ask\`/\`alert\` still work as silent aliases → message/important/important/urgent.) Run \`pidge <type> --help\` for each one's flags.
|
|
1750
1797
|
|
|
1798
|
+
## Write for the lock screen (what the human actually sees)
|
|
1799
|
+
|
|
1800
|
+
The banner shows your **\`--title\`** and **\`--body\`** (plain text). **\`--body-markdown\` does NOT appear on the banner** — it's the in-app detail screen only. So:
|
|
1801
|
+
- **Always give a concise \`--body\`** — the one-line human-readable gist. A title-only send can show as an empty banner (just your channel name).
|
|
1802
|
+
- Put the rich part (tables, lists, code, an image) in **\`--body-markdown\`** (and/or \`--image\`) — the human sees it when they tap in.
|
|
1803
|
+
- A good send: **title = the answer at a glance · body = the few facts they need to decide/act · body-markdown = the rich detail · ONE ask.** Never ship a title-only notification.
|
|
1804
|
+
|
|
1751
1805
|
## Approval has two paths — know which one you're in
|
|
1752
1806
|
|
|
1753
1807
|
**Path A — YOU request it (\`pidge approval\`).** You decided this needs a human sign-off. \`pidge approval\` = \`important\` + an **Approve** (Face-ID gated) / **Reject** pair + \`--wait\`. You send it, you block, and you get \`chosen_action.action_id: "grant"\` (approved) or \`"deny"\` (rejected) back. Use it for money, deletions, irreversible actions.
|
|
@@ -1760,7 +1814,7 @@ Every send is **a TYPE + a markdown body + an OPTIONAL response**. The TYPE (one
|
|
|
1760
1814
|
|
|
1761
1815
|
Asking for a reply is orthogonal to the type — you don't need \`approval\` to get a button.
|
|
1762
1816
|
- **Free text** is always available; the human can write back on anything.
|
|
1763
|
-
- **Buttons**
|
|
1817
|
+
- **Buttons** — reach for a BUILT-IN catalog action FIRST; they're tappable right on the lock-screen banner. Decisions: \`--actions yes,no\` · \`approve,reject\` · \`accept,decline\` · \`later\`; plus \`done\`, \`snooze\`, \`reply\`. Use \`--custom-action id:label\` ONLY when none fit — **custom labels (and any destructive/Face-ID action) render detail-only**, so the human must open the app to answer instead of tapping the banner.
|
|
1764
1818
|
- **Face ID** on a consequential action: \`--gated\` injects one confirm-with-Face-ID button (use it for money/deletion). It does NOT change loudness — pair with a louder profile if it must also be loud. A flag, not a type.
|
|
1765
1819
|
- **send-and-go vs wait** — the choice that decides how YOU work:
|
|
1766
1820
|
- *send-and-go* (default): fire and continue; the answer arrives later in \`pidge listen --all\`.
|
|
@@ -1779,12 +1833,14 @@ Need a TYPED reply (a time/value/name)? \`--actions reply\` ALONE — never \`ye
|
|
|
1779
1833
|
6. **Don't spam to signal importance.** Consolidate into one markdown body; use \`--collapse-key\` for self-replacing progress, \`--thread\` only for follow-ups over time.
|
|
1780
1834
|
7. **Be listening when the answer lands, or you lose it.** Ack only AFTER the work is durably done.
|
|
1781
1835
|
8. **English only, phone-friendly markdown.** Narrow tables (they render), no emoji-spam.
|
|
1836
|
+
9. **Banner-first + catalog-first.** Give a real \`--body\` (the banner shows title+body, never body-markdown), and fit decisions into a catalog action (\`yes,no\`/\`approve,reject\`) before inventing a custom label (custom = a tap-through, not a banner tap).
|
|
1782
1837
|
|
|
1783
1838
|
## Gold examples (full commands)
|
|
1784
1839
|
|
|
1785
1840
|
Pendency with a real table → \`important\`:
|
|
1786
1841
|
\`\`\`bash
|
|
1787
1842
|
pidge important --title "Weekly metrics ready" \\
|
|
1843
|
+
--body "Signups 1,204 (+8%) · churn 1.9% (−0.3pp) · table inside" \\
|
|
1788
1844
|
--body-markdown $'| Metric | This week | Δ |\\n|---|---|---|\\n| Signups | 1,204 | +8% |\\n| Churn | 1.9% | −0.3pp |' \\
|
|
1789
1845
|
--actions reply
|
|
1790
1846
|
\`\`\`
|
|
@@ -1792,7 +1848,8 @@ pidge important --title "Weekly metrics ready" \\
|
|
|
1792
1848
|
Blocking decision → ask→wait loop (handle exit 3):
|
|
1793
1849
|
\`\`\`bash
|
|
1794
1850
|
pidge important --title "Run the schema migration?" \\
|
|
1795
|
-
--body
|
|
1851
|
+
--body "Drops legacy_orders (412k rows), not reversible. Safe mid-deploy?" \\
|
|
1852
|
+
--body-markdown "Dropping \\\`legacy_orders\\\` (412k rows, archived 2025). **Not reversible.** Safe to run mid-deploy?" \\
|
|
1796
1853
|
--actions yes,no --wait --timeout 3600
|
|
1797
1854
|
# exit 0 → read chosen_action.action_id (yes|no); exit 3 → no answer, treat as NO / hold, re-ask
|
|
1798
1855
|
\`\`\`
|
|
@@ -1800,19 +1857,22 @@ pidge important --title "Run the schema migration?" \\
|
|
|
1800
1857
|
Agent-initiated approval (money) → \`pidge approval\`:
|
|
1801
1858
|
\`\`\`bash
|
|
1802
1859
|
pidge approval --title "Place \\$4,200 purchase order?" \\
|
|
1803
|
-
--body
|
|
1860
|
+
--body "Acme · PO #4471 · \\$4,200 — moves real money" \\
|
|
1861
|
+
--body-markdown "Vendor: Acme · PO #4471 · **\\$4,200**, moves real money." \\
|
|
1804
1862
|
--wait --timeout 3600
|
|
1805
1863
|
# = important + Approve(Face ID)/Reject + wait; chosen_action.action_id: grant|deny
|
|
1806
1864
|
\`\`\`
|
|
1807
1865
|
|
|
1808
1866
|
Time-anchored → \`event\` (needs \`--event-at\` in the human's tz):
|
|
1809
1867
|
\`\`\`bash
|
|
1810
|
-
pidge event --event-at "2026-06-30T15:00:00-03:00" --title "Call with accountant"
|
|
1868
|
+
pidge event --event-at "2026-06-30T15:00:00-03:00" --title "Call with accountant" \\
|
|
1869
|
+
--body "3pm tomorrow with the accountant"
|
|
1811
1870
|
\`\`\`
|
|
1812
1871
|
|
|
1813
1872
|
Long markdown without shell-quoting pain → pipe it:
|
|
1814
1873
|
\`\`\`bash
|
|
1815
|
-
generate_report | pidge important --title "Report ready"
|
|
1874
|
+
generate_report | pidge important --title "Report ready" \\
|
|
1875
|
+
--body "Q2 report ready — revenue, churn, and 3 risks inside" --body-markdown-file - --actions reply
|
|
1816
1876
|
\`\`\`
|
|
1817
1877
|
|
|
1818
1878
|
## Gotchas we already paid for
|
|
@@ -1823,6 +1883,7 @@ generate_report | pidge important --title "Report ready" --body-markdown-file -
|
|
|
1823
1883
|
- **The ask reply-vs-yes/no trap.** \`--actions yes,no,reply\` lets the human dodge a typed answer with one tap — use \`--actions reply\` alone when you need text.
|
|
1824
1884
|
- **\`event\` is quiet today** — \`event --event-at\` schedules; the countdown LA-as-primitive is still being built.
|
|
1825
1885
|
- **content_template still parses as input** (back-compat) but is OFF the menu — if a legacy habit sends \`--template report\`, it silently maps; don't rely on it, don't teach it.
|
|
1886
|
+
- **The banner ≠ the detail screen.** Lock-screen banner = \`title\` + \`body\` (plain). \`body_markdown\`/images render only when the human taps in. A send with only \`--title\` can look empty on the lock screen — always include a \`--body\`.
|
|
1826
1887
|
|
|
1827
1888
|
## How it intrudes (profiles — the human owns them)
|
|
1828
1889
|
|
|
@@ -1867,7 +1928,7 @@ A turn-based agent (Claude Code, anything invoked on demand) stays COMMANDABLE w
|
|
|
1867
1928
|
}
|
|
1868
1929
|
case 'whoami': {
|
|
1869
1930
|
const { res, data } = await fetchWhoami().catch((e) => { die(`pidge: whoami failed (network): ${e.message}`, 2); });
|
|
1870
|
-
checkManifestNews(res);
|
|
1931
|
+
await checkManifestNews(res);
|
|
1871
1932
|
if (res.status !== 200) die(`pidge: whoami failed (${res.status}): ${JSON.stringify(data)}`, 2);
|
|
1872
1933
|
console.log(JSON.stringify(data, null, 2));
|
|
1873
1934
|
console.error(`pidge: you are canal "${data.channel && data.channel.name}" · ${data.devices ?? '?'} device(s)`);
|
|
@@ -2003,7 +2064,7 @@ A turn-based agent (Claude Code, anything invoked on demand) stays COMMANDABLE w
|
|
|
2003
2064
|
} catch (e) {
|
|
2004
2065
|
die(`pidge: cancel failed (network): ${e.message}`, 2);
|
|
2005
2066
|
}
|
|
2006
|
-
checkManifestNews(res);
|
|
2067
|
+
await checkManifestNews(res);
|
|
2007
2068
|
console.log(raw);
|
|
2008
2069
|
if (res.status >= 200 && res.status < 300) {
|
|
2009
2070
|
console.error(`pidge: cancelled ${cid} — nothing will fire`);
|
|
@@ -2032,7 +2093,7 @@ A turn-based agent (Claude Code, anything invoked on demand) stays COMMANDABLE w
|
|
|
2032
2093
|
} catch (e) {
|
|
2033
2094
|
die(`pidge: ack failed (network): ${e.message}`, 2);
|
|
2034
2095
|
}
|
|
2035
|
-
checkManifestNews(res);
|
|
2096
|
+
await checkManifestNews(res);
|
|
2036
2097
|
console.log(raw);
|
|
2037
2098
|
if (!(res.status >= 200 && res.status < 300)) die(`pidge: ack failed (${res.status}): ${raw}`, 2);
|
|
2038
2099
|
let adata = {};
|
|
@@ -2071,7 +2132,7 @@ A turn-based agent (Claude Code, anything invoked on demand) stays COMMANDABLE w
|
|
|
2071
2132
|
} catch (e) {
|
|
2072
2133
|
die(`pidge: inbox failed (network): ${e.message}`, 2);
|
|
2073
2134
|
}
|
|
2074
|
-
checkManifestNews(res);
|
|
2135
|
+
await checkManifestNews(res);
|
|
2075
2136
|
console.log(raw);
|
|
2076
2137
|
if (!(res.status >= 200 && res.status < 300)) die(`pidge: inbox failed (${res.status})`, 2);
|
|
2077
2138
|
let data = {};
|
|
@@ -2180,7 +2241,7 @@ A turn-based agent (Claude Code, anything invoked on demand) stays COMMANDABLE w
|
|
|
2180
2241
|
draining = true;
|
|
2181
2242
|
try {
|
|
2182
2243
|
const res = await fetchT(`${BASE}/api/v1/messages${queueQs}`, { headers });
|
|
2183
|
-
checkManifestNews(res);
|
|
2244
|
+
await checkManifestNews(res);
|
|
2184
2245
|
if (res.status === 200) {
|
|
2185
2246
|
health.ok();
|
|
2186
2247
|
const msgs = (await res.json().catch(() => ({}))).messages || [];
|
|
@@ -2239,7 +2300,7 @@ A turn-based agent (Claude Code, anything invoked on demand) stays COMMANDABLE w
|
|
|
2239
2300
|
if (waitS > 0) qs.set('wait', String(waitS));
|
|
2240
2301
|
if (v.all) qs.set('all', 'true');
|
|
2241
2302
|
const res = await fetchT(`${BASE}/api/v1/messages${qs.size ? `?${qs}` : ''}`, { headers }, (waitS + 10) * 1000);
|
|
2242
|
-
checkManifestNews(res);
|
|
2303
|
+
await checkManifestNews(res);
|
|
2243
2304
|
if (res.status === 200) {
|
|
2244
2305
|
health.ok();
|
|
2245
2306
|
const data = await res.json().catch(() => ({}));
|