primcli 1.67.0 → 1.68.0
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 +34 -10
- package/bin/claude-pending-mail.mjs +58 -1
- package/bin/claude-wake.mjs +6 -1
- package/dist/{api-command-Dh4hs7kh.js → api-command-D7DPn2Ro.js} +76 -14
- package/dist/{machine-session-s6LvMvRd.js → machine-session-7bISVcRb.js} +181 -26
- package/dist/{notify-session-CeKAcPIX.js → notify-session-Cp0Kkstb.js} +1 -1
- package/dist/oclif/auto-signal-worker.js +2 -2
- package/dist/oclif/index.js +110 -42
- package/dist/oclif/receiver-heal.js +1 -1
- package/dist/{signal-command-BxafnMiU.js → signal-command-Bi2U2BR_.js} +1 -1
- package/dist/skills/primitive-connect/SKILL.md +6 -0
- package/dist/skills/primitive-connect/package-lock.json +78 -78
- package/dist/skills/primitive-connect/package.json +1 -1
- package/dist/skills/primitive-connect/references/conversations.md +22 -1
- package/dist/skills/primitive-connect.json +6 -6
- package/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { S as __exportAll } from "./repeats-BL7ZC-_6-BZ-MphTV.js";
|
|
2
2
|
import { B as parseOwnerMemberAddress, F as agentProfilesDirectory, I as connectedAgentIdentity, L as connectedApiBaseUrl, M as AgentConnectionSetupError, N as agentProfileDirectory, P as agentProfileName, R as loadConnectedAgentProfile, U as saveConnectedAgentProfile, V as profileAlreadyConnectedMessage, W as PrimitiveApiClient, j as AGENT_PROFILE_ENV, x as loadCliCredentials, z as parseConnectedAgentProfile } from "./cli-config-DMszFbGn.js";
|
|
3
|
-
import { Ct as cliInvocation, Jn as putAgentContactPolicy, Jt as refreshStoredCliCredentials, Pn as listDomains, Tt as defaultConnectionName, Vn as listSentEmails, Yn as putContact, an as deleteAgentContact, ar as sendEmail, jn as listContacts, kn as listAgentContacts, mn as getContact, nr as searchEmails, on as deleteContact, pn as getAgentContactPolicy, qn as putAgentContact, vn as getEmail } from "./api-command-
|
|
3
|
+
import { Ct as cliInvocation, Jn as putAgentContactPolicy, Jt as refreshStoredCliCredentials, Pn as listDomains, Tt as defaultConnectionName, Vn as listSentEmails, Yn as putContact, an as deleteAgentContact, ar as sendEmail, jn as listContacts, kn as listAgentContacts, mn as getContact, nr as searchEmails, on as deleteContact, pn as getAgentContactPolicy, qn as putAgentContact, vn as getEmail } from "./api-command-D7DPn2Ro.js";
|
|
4
4
|
import { _ as acquireListenLock, c as mailTime, d as readMailJson, f as removeMailFile, g as ListenStateError, h as writeMailJson, i as mailId, l as privateMailDirectory, o as mailObject, r as mailAddress, s as mailString } from "./shared-mail-files-MwlVE90c.js";
|
|
5
|
-
import { _ as detectAgentRuntime, a as NotificationRetryError, d as defaultSessionSocket, f as NativeSessionDisconnectedError, l as SESSION_UUID, t as notificationScope, u as connectNativeSession, v as installConnectSkill, x as readBundledConnectSkill } from "./notify-session-
|
|
5
|
+
import { _ as detectAgentRuntime, a as NotificationRetryError, d as defaultSessionSocket, f as NativeSessionDisconnectedError, l as SESSION_UUID, t as notificationScope, u as connectNativeSession, v as installConnectSkill, x as readBundledConnectSkill } from "./notify-session-Cp0Kkstb.js";
|
|
6
6
|
import { a as scopedChatSenderTrust } from "./scoped-chat-Dsark9hm.js";
|
|
7
7
|
import { l as stopBackgroundListen, r as backgroundListenStatus } from "./listen-background--0peztKE.js";
|
|
8
8
|
import { t as readSharedMailOwner } from "./shared-mail-watch-DtKpsgg8.js";
|
|
@@ -1674,8 +1674,9 @@ function readSessionRecord(configDir, session) {
|
|
|
1674
1674
|
agentInfo: row.agentInfo === "created" || row.agentInfo === "already_present" ? row.agentInfo : null,
|
|
1675
1675
|
registeredAt: typeof row.registeredAt === "string" ? row.registeredAt : (/* @__PURE__ */ new Date(0)).toISOString(),
|
|
1676
1676
|
endedAt: typeof row.endedAt === "string" ? row.endedAt : null,
|
|
1677
|
-
disconnect: row.disconnect === "done" || row.disconnect === "pending" || row.disconnect === "pending_enrollment" || row.disconnect === "deferred" ? row.disconnect : typeof row.endedAt === "string" ? "done" : null,
|
|
1677
|
+
disconnect: row.disconnect === "done" || row.disconnect === "pending" || row.disconnect === "pending_enrollment" || row.disconnect === "deferred" || row.disconnect === "kept" ? row.disconnect : typeof row.endedAt === "string" ? "done" : null,
|
|
1678
1678
|
deferredUntil: typeof row.deferredUntil === "string" ? row.deferredUntil : null,
|
|
1679
|
+
revokeOnEnd: row.revokeOnEnd === true,
|
|
1679
1680
|
endReason: typeof row.endReason === "string" && REASON.test(row.endReason) ? row.endReason : null,
|
|
1680
1681
|
release: parseRelease(row.release)
|
|
1681
1682
|
};
|
|
@@ -1741,6 +1742,7 @@ function releasedRecord(record, reason, at, current) {
|
|
|
1741
1742
|
endedAt: null,
|
|
1742
1743
|
disconnect: null,
|
|
1743
1744
|
deferredUntil: null,
|
|
1745
|
+
revokeOnEnd: false,
|
|
1744
1746
|
endReason: null,
|
|
1745
1747
|
release: {
|
|
1746
1748
|
at: at.toISOString(),
|
|
@@ -4799,6 +4801,8 @@ async function enrollAgent(params) {
|
|
|
4799
4801
|
var machine_session_exports = /* @__PURE__ */ __exportAll({
|
|
4800
4802
|
HOOK_END_GRACE_MS: () => HOOK_END_GRACE_MS,
|
|
4801
4803
|
OMP_MAIN: () => OMP_MAIN,
|
|
4804
|
+
RECONNECT_HINT: () => RECONNECT_HINT,
|
|
4805
|
+
STALE_SESSION_MS: () => STALE_SESSION_MS,
|
|
4802
4806
|
agentConnectionState: () => agentConnectionState,
|
|
4803
4807
|
agentInfoForSession: () => agentInfoForSession,
|
|
4804
4808
|
connectedProfilesForSession: () => connectedProfilesForSession,
|
|
@@ -4811,9 +4815,11 @@ var machine_session_exports = /* @__PURE__ */ __exportAll({
|
|
|
4811
4815
|
readClaudeHookInput: () => readClaudeHookInput,
|
|
4812
4816
|
registerSession: () => registerSession,
|
|
4813
4817
|
retryPendingDisconnects: () => retryPendingDisconnects,
|
|
4818
|
+
revokeStaleSessionAgents: () => revokeStaleSessionAgents,
|
|
4814
4819
|
revokeWithMemberLogin: () => revokeWithMemberLogin,
|
|
4815
4820
|
runDetached: () => runDetached,
|
|
4816
4821
|
runtimeSessionId: () => runtimeSessionId,
|
|
4822
|
+
staleSessionAgents: () => staleSessionAgents,
|
|
4817
4823
|
workspaceName: () => workspaceName
|
|
4818
4824
|
});
|
|
4819
4825
|
/** The repository (or directory) a session works in, for its default name. */
|
|
@@ -5221,8 +5227,15 @@ function withDefined(defaults, overrides) {
|
|
|
5221
5227
|
...Object.fromEntries(Object.entries(overrides ?? {}).filter(([, value]) => value !== void 0))
|
|
5222
5228
|
};
|
|
5223
5229
|
}
|
|
5230
|
+
/**
|
|
5231
|
+
* What to do about an agent that was disconnected in Primitive. The owner's
|
|
5232
|
+
* Reconnect re-invites the same address, and pasting that instruction into
|
|
5233
|
+
* the session claims it into the session's profile again.
|
|
5234
|
+
*/
|
|
5235
|
+
const RECONNECT_HINT = "To get the same address back, the owner can use Reconnect on this agent in the Primitive app and paste the instruction it gives into this session.";
|
|
5224
5236
|
const HELD_DETAIL = "This session already receives as another connected profile, so this profile's receive hooks were not added. Run `primitive machine doctor --fix --profile <profile>` to bind it deliberately.";
|
|
5225
|
-
const ENDED_DETAIL =
|
|
5237
|
+
const ENDED_DETAIL = `This session ended and its agent was disconnected. A new address is never created for the same session. ${RECONNECT_HINT}`;
|
|
5238
|
+
const ENDED_KEPT_DETAIL = "This session ended while it was registering. Its agent is kept, and resuming the session reconnects it at the same address.";
|
|
5226
5239
|
const ENDED_DEFERRED_DETAIL = "This session ended moments ago. Its agent is disconnected after a short wait unless the session starts again first.";
|
|
5227
5240
|
const RELEASED_DETAIL = "This session's profile now holds an agent connected some other way, so it was left connected.";
|
|
5228
5241
|
const ENDED_PENDING_DETAIL = "This session ended, but disconnecting its agent has not been confirmed yet; `primitive machine doctor --fix` retries it.";
|
|
@@ -5313,6 +5326,12 @@ async function registerSession(options) {
|
|
|
5313
5326
|
status: "ended",
|
|
5314
5327
|
detail: ENDED_DEFERRED_DETAIL
|
|
5315
5328
|
};
|
|
5329
|
+
if (current.disconnect === "kept") return {
|
|
5330
|
+
...known,
|
|
5331
|
+
address: current.address,
|
|
5332
|
+
status: "ended",
|
|
5333
|
+
detail: ENDED_KEPT_DETAIL
|
|
5334
|
+
};
|
|
5316
5335
|
const outcome = current.disconnect === "done" && !enrolledNow ? "done" : await finishSessionDisconnect(options.configDir, current, deps, env, options.fetch, enrolledNow);
|
|
5317
5336
|
if (outcome === "released") return {
|
|
5318
5337
|
...known,
|
|
@@ -5340,15 +5359,17 @@ async function registerSession(options) {
|
|
|
5340
5359
|
endedAt: null,
|
|
5341
5360
|
disconnect: null,
|
|
5342
5361
|
deferredUntil: null,
|
|
5362
|
+
revokeOnEnd: false,
|
|
5343
5363
|
endReason: null,
|
|
5344
5364
|
release: null
|
|
5345
5365
|
});
|
|
5346
5366
|
try {
|
|
5347
|
-
let record = await updateSessionRecord(options.configDir, sessionId, (current) => current?.endedAt && current.disconnect === "deferred" ? {
|
|
5367
|
+
let record = await updateSessionRecord(options.configDir, sessionId, (current) => current?.endedAt && (current.disconnect === "deferred" || current.disconnect === "kept") ? {
|
|
5348
5368
|
...current,
|
|
5349
5369
|
endedAt: null,
|
|
5350
5370
|
disconnect: null,
|
|
5351
5371
|
deferredUntil: null,
|
|
5372
|
+
revokeOnEnd: false,
|
|
5352
5373
|
endReason: null
|
|
5353
5374
|
} : current);
|
|
5354
5375
|
if (record?.endedAt) return await ended(record);
|
|
@@ -5387,7 +5408,7 @@ async function registerSession(options) {
|
|
|
5387
5408
|
if (state === "revoked" || state === "rejected") return {
|
|
5388
5409
|
...withAddress,
|
|
5389
5410
|
status: "revoked",
|
|
5390
|
-
detail:
|
|
5411
|
+
detail: `This session's agent was disconnected in Primitive, so it cannot receive mail. No new address was created. ${RECONNECT_HINT}`
|
|
5391
5412
|
};
|
|
5392
5413
|
if (state === "unavailable") return {
|
|
5393
5414
|
...withAddress,
|
|
@@ -5414,7 +5435,7 @@ async function registerSession(options) {
|
|
|
5414
5435
|
...known,
|
|
5415
5436
|
address: record.address,
|
|
5416
5437
|
status: "removed",
|
|
5417
|
-
detail:
|
|
5438
|
+
detail: `This session's local profile was removed. No new address was created for the same session. ${RECONNECT_HINT}`
|
|
5418
5439
|
};
|
|
5419
5440
|
let credentials;
|
|
5420
5441
|
try {
|
|
@@ -5512,24 +5533,62 @@ async function registerSession(options) {
|
|
|
5512
5533
|
}
|
|
5513
5534
|
}
|
|
5514
5535
|
/**
|
|
5515
|
-
* How long an end from a runtime hook waits before
|
|
5536
|
+
* How long an end from a runtime hook waits before it takes effect. A runtime
|
|
5516
5537
|
* reports the same end for a restart, a switch to another session and a real
|
|
5517
5538
|
* exit, so the hook cannot tell them apart; a start of the same session
|
|
5518
|
-
* within this window cancels the end
|
|
5539
|
+
* within this window cancels the end.
|
|
5519
5540
|
*/
|
|
5520
5541
|
const HOOK_END_GRACE_MS = 3e5;
|
|
5542
|
+
/**
|
|
5543
|
+
* How long an ended session keeps the agent `session-register` created for
|
|
5544
|
+
* it. A session that has not started again for this long has its agent
|
|
5545
|
+
* disconnected by `machine doctor --fix` or the next registration on this
|
|
5546
|
+
* machine, so closed sessions do not keep live credentials forever.
|
|
5547
|
+
*/
|
|
5548
|
+
const STALE_SESSION_MS = 2592e6;
|
|
5521
5549
|
/** The end of this record is a hook's, still waiting. */
|
|
5522
5550
|
function deferredEnd(record) {
|
|
5523
5551
|
return Boolean(record?.endedAt) && record?.disconnect === "deferred";
|
|
5524
5552
|
}
|
|
5553
|
+
/** Removes an ended session's own exact-session receive hooks. Best effort. */
|
|
5554
|
+
function removeSessionHooks(configDir, record, deps, env) {
|
|
5555
|
+
if (record.runtime !== "claude" || !record.address) return;
|
|
5556
|
+
try {
|
|
5557
|
+
deps.uninstallHook({
|
|
5558
|
+
configDir,
|
|
5559
|
+
profileName: record.profile,
|
|
5560
|
+
agentAddress: record.address,
|
|
5561
|
+
sessionId: record.session,
|
|
5562
|
+
env
|
|
5563
|
+
});
|
|
5564
|
+
} catch {}
|
|
5565
|
+
}
|
|
5566
|
+
/**
|
|
5567
|
+
* The record of an end that keeps the agent. Its exact-session receive hooks
|
|
5568
|
+
* are removed in the same step, under the record's lock, so a start of the
|
|
5569
|
+
* same session that clears the end afterwards reinstalls them.
|
|
5570
|
+
*/
|
|
5571
|
+
function keptEnd(configDir, current, deps, env, at) {
|
|
5572
|
+
removeSessionHooks(configDir, current, deps, env);
|
|
5573
|
+
return {
|
|
5574
|
+
...current,
|
|
5575
|
+
endedAt: current.endedAt ?? at.toISOString(),
|
|
5576
|
+
disconnect: "kept",
|
|
5577
|
+
deferredUntil: null,
|
|
5578
|
+
revokeOnEnd: false
|
|
5579
|
+
};
|
|
5580
|
+
}
|
|
5581
|
+
const KEPT_DETAIL = "This session is marked ended. Its agent stays connected, so resuming the session keeps the same address; it is disconnected only if the session does not start again for 30 days. Pass --revoke to disconnect it now.";
|
|
5525
5582
|
/**
|
|
5526
|
-
*
|
|
5527
|
-
* connected
|
|
5528
|
-
*
|
|
5529
|
-
*
|
|
5530
|
-
*
|
|
5531
|
-
*
|
|
5532
|
-
*
|
|
5583
|
+
* Record that a session ended. By default the agent `session-register`
|
|
5584
|
+
* created for it stays connected, with its credential and profile, so a
|
|
5585
|
+
* resume of the same session keeps its address; only its exact-session
|
|
5586
|
+
* receive hooks are removed. With `revoke` the agent is disconnected instead.
|
|
5587
|
+
* Agents connected any other way are left alone either way, including a
|
|
5588
|
+
* credential connected later into the same profile. The end is recorded
|
|
5589
|
+
* first, under the record's lock, so a registration still enrolling sees it.
|
|
5590
|
+
* With `graceMs` (an end reported by a runtime hook) the end waits that
|
|
5591
|
+
* long, and a start of the same session meanwhile cancels it. Never throws.
|
|
5533
5592
|
*/
|
|
5534
5593
|
async function endSession(options) {
|
|
5535
5594
|
const env = options.env ?? process.env;
|
|
@@ -5561,6 +5620,7 @@ async function endSession(options) {
|
|
|
5561
5620
|
};
|
|
5562
5621
|
const sessionId = session.toLowerCase();
|
|
5563
5622
|
const graceMs = Math.max(0, options.graceMs ?? 0);
|
|
5623
|
+
const revoke = options.revoke === true;
|
|
5564
5624
|
const reason = options.reason && /^[a-z_]{1,40}$/.test(options.reason) ? options.reason : null;
|
|
5565
5625
|
try {
|
|
5566
5626
|
let managed = false;
|
|
@@ -5574,21 +5634,29 @@ async function endSession(options) {
|
|
|
5574
5634
|
return current;
|
|
5575
5635
|
}
|
|
5576
5636
|
const now = deps.now();
|
|
5577
|
-
|
|
5637
|
+
const revoking = revoke || Boolean(current.endedAt) && (current.disconnect === "pending" || current.disconnect === "pending_enrollment" || current.disconnect === "deferred" && current.revokeOnEnd);
|
|
5638
|
+
if (!revoking && current.endedAt && current.disconnect === "kept") return current;
|
|
5639
|
+
if (graceMs > 0 && (!current.endedAt || deferredEnd(current) || current.disconnect === "kept")) {
|
|
5578
5640
|
deferred = true;
|
|
5579
5641
|
return {
|
|
5580
5642
|
...current,
|
|
5581
5643
|
endedAt: now.toISOString(),
|
|
5582
5644
|
disconnect: "deferred",
|
|
5583
5645
|
deferredUntil: new Date(now.getTime() + graceMs).toISOString(),
|
|
5646
|
+
revokeOnEnd: revoking,
|
|
5584
5647
|
endReason: reason
|
|
5585
5648
|
};
|
|
5586
5649
|
}
|
|
5650
|
+
if (!revoking) return {
|
|
5651
|
+
...keptEnd(options.configDir, current, deps, env, now),
|
|
5652
|
+
endReason: current.endReason ?? reason
|
|
5653
|
+
};
|
|
5587
5654
|
return {
|
|
5588
5655
|
...current,
|
|
5589
5656
|
endedAt: current.endedAt ?? now.toISOString(),
|
|
5590
5657
|
disconnect: current.disconnect === "pending_enrollment" ? "pending_enrollment" : "pending",
|
|
5591
5658
|
deferredUntil: null,
|
|
5659
|
+
revokeOnEnd: true,
|
|
5592
5660
|
endReason: current.endReason ?? reason
|
|
5593
5661
|
};
|
|
5594
5662
|
});
|
|
@@ -5616,18 +5684,23 @@ async function endSession(options) {
|
|
|
5616
5684
|
resumed = true;
|
|
5617
5685
|
return current;
|
|
5618
5686
|
}
|
|
5619
|
-
return {
|
|
5687
|
+
return current.revokeOnEnd ? {
|
|
5620
5688
|
...current,
|
|
5621
5689
|
disconnect: "pending",
|
|
5622
5690
|
deferredUntil: null
|
|
5623
|
-
};
|
|
5691
|
+
} : keptEnd(options.configDir, current, deps, env, deps.now());
|
|
5624
5692
|
});
|
|
5625
5693
|
if (resumed || !record) return {
|
|
5626
5694
|
...known,
|
|
5627
5695
|
status: "resumed",
|
|
5628
|
-
detail: "The session started again (or was ended again) before its end took effect, so this end
|
|
5696
|
+
detail: "The session started again (or was ended again) before its end took effect, so this end changed nothing."
|
|
5629
5697
|
};
|
|
5630
5698
|
}
|
|
5699
|
+
if (record.disconnect === "kept") return {
|
|
5700
|
+
...known,
|
|
5701
|
+
status: "kept",
|
|
5702
|
+
detail: KEPT_DETAIL
|
|
5703
|
+
};
|
|
5631
5704
|
const outcome = await finishSessionDisconnect(options.configDir, record, deps, env, options.fetch);
|
|
5632
5705
|
if (outcome === "released") return {
|
|
5633
5706
|
...known,
|
|
@@ -5648,17 +5721,99 @@ async function endSession(options) {
|
|
|
5648
5721
|
...base,
|
|
5649
5722
|
session: sessionId,
|
|
5650
5723
|
status: "failed",
|
|
5651
|
-
detail: error instanceof AgentDisconnectError ? error.message : "
|
|
5724
|
+
detail: error instanceof AgentDisconnectError ? error.message : "The end did not finish. The agent was left as it was."
|
|
5652
5725
|
};
|
|
5653
5726
|
}
|
|
5654
5727
|
}
|
|
5655
5728
|
/**
|
|
5656
|
-
* Ended sessions whose agent disconnect
|
|
5657
|
-
*
|
|
5658
|
-
* it (for example because the
|
|
5729
|
+
* Ended sessions whose agent disconnect was asked for and still needs
|
|
5730
|
+
* confirming, including a `--revoke` end from a hook whose grace period is
|
|
5731
|
+
* over but whose own process never finished it (for example because the
|
|
5732
|
+
* machine shut down). Ends that keep their agent are never listed here.
|
|
5659
5733
|
*/
|
|
5660
5734
|
function pendingSessionDisconnects(configDir, now = /* @__PURE__ */ new Date()) {
|
|
5661
|
-
return listSessionRecords(configDir).filter((record) => record.createdBy === "session-register" && record.endedAt && (record.disconnect === "pending" || record.disconnect === "pending_enrollment" || record.disconnect === "deferred" && !(Date.parse(record.deferredUntil ?? "") > now.getTime())));
|
|
5735
|
+
return listSessionRecords(configDir).filter((record) => record.createdBy === "session-register" && record.endedAt && (record.disconnect === "pending" || record.disconnect === "pending_enrollment" || record.disconnect === "deferred" && record.revokeOnEnd && !(Date.parse(record.deferredUntil ?? "") > now.getTime())));
|
|
5736
|
+
}
|
|
5737
|
+
/**
|
|
5738
|
+
* Ended sessions that kept their agent and have not started again for
|
|
5739
|
+
* STALE_SESSION_MS, whose profile still holds exactly the credential
|
|
5740
|
+
* `session-register` created. Only these are disconnected for being stale.
|
|
5741
|
+
*/
|
|
5742
|
+
function staleSessionAgents(configDir, now = /* @__PURE__ */ new Date()) {
|
|
5743
|
+
return listSessionRecords(configDir).filter((record) => {
|
|
5744
|
+
if (record.createdBy !== "session-register" || !record.endedAt || !(record.disconnect === "kept" || record.disconnect === "deferred" && !record.revokeOnEnd) || !(now.getTime() - Date.parse(record.endedAt) >= 2592e6)) return false;
|
|
5745
|
+
try {
|
|
5746
|
+
const current = loadConnectedAgentProfile(configDir, record.profile);
|
|
5747
|
+
return Boolean(current && holdsRegisteredCredential(configDir, record, current));
|
|
5748
|
+
} catch {
|
|
5749
|
+
return false;
|
|
5750
|
+
}
|
|
5751
|
+
});
|
|
5752
|
+
}
|
|
5753
|
+
/**
|
|
5754
|
+
* Disconnect the agent of every stale ended session (see
|
|
5755
|
+
* staleSessionAgents). Each disconnect names the exact credential it
|
|
5756
|
+
* checked, under the locks `agent connect` also takes, so a credential
|
|
5757
|
+
* connected into the profile meanwhile is never revoked, and nothing is
|
|
5758
|
+
* ever revoked by address here. A start of the session meanwhile turns it
|
|
5759
|
+
* into an ordinary pending disconnect, which that start finishes. Returns
|
|
5760
|
+
* how many agents were disconnected.
|
|
5761
|
+
*/
|
|
5762
|
+
async function revokeStaleSessionAgents(configDir, options = {}) {
|
|
5763
|
+
const deps = withDefined(DISCONNECT_DEFAULTS, options.dependencies);
|
|
5764
|
+
const env = options.env ?? process.env;
|
|
5765
|
+
let revoked = 0;
|
|
5766
|
+
for (const listed of staleSessionAgents(configDir, deps.now())) {
|
|
5767
|
+
if (listed.session === options.exclude?.toLowerCase()) continue;
|
|
5768
|
+
try {
|
|
5769
|
+
const current = loadConnectedAgentProfile(configDir, listed.profile);
|
|
5770
|
+
if (!current || !holdsRegisteredCredential(configDir, listed, current)) continue;
|
|
5771
|
+
let claimed = false;
|
|
5772
|
+
await updateSessionRecord(configDir, listed.session, (row) => {
|
|
5773
|
+
if (row?.createdBy !== "session-register" || row.endedAt !== listed.endedAt || row.disconnect !== listed.disconnect) return row;
|
|
5774
|
+
claimed = true;
|
|
5775
|
+
return {
|
|
5776
|
+
...row,
|
|
5777
|
+
disconnect: "pending",
|
|
5778
|
+
deferredUntil: null,
|
|
5779
|
+
revokeOnEnd: true
|
|
5780
|
+
};
|
|
5781
|
+
});
|
|
5782
|
+
if (!claimed) continue;
|
|
5783
|
+
let outcome;
|
|
5784
|
+
try {
|
|
5785
|
+
await deps.disconnect({
|
|
5786
|
+
configDir,
|
|
5787
|
+
profileName: listed.profile,
|
|
5788
|
+
fetch: options.fetch,
|
|
5789
|
+
env,
|
|
5790
|
+
expected: {
|
|
5791
|
+
address: current.agent_address,
|
|
5792
|
+
invitationHash: current.invitation_hash
|
|
5793
|
+
}
|
|
5794
|
+
});
|
|
5795
|
+
outcome = "done";
|
|
5796
|
+
} catch (error) {
|
|
5797
|
+
outcome = error instanceof AgentCredentialChangedError ? "released" : "failed";
|
|
5798
|
+
}
|
|
5799
|
+
await updateSessionRecord(configDir, listed.session, (row) => {
|
|
5800
|
+
if (row?.createdBy !== "session-register" || row.disconnect !== "pending") return row;
|
|
5801
|
+
if (outcome === "done") return {
|
|
5802
|
+
...row,
|
|
5803
|
+
disconnect: "done"
|
|
5804
|
+
};
|
|
5805
|
+
if (outcome === "released") return releasedRecord(row, "credential_changed", deps.now());
|
|
5806
|
+
return {
|
|
5807
|
+
...row,
|
|
5808
|
+
disconnect: listed.disconnect,
|
|
5809
|
+
deferredUntil: listed.deferredUntil,
|
|
5810
|
+
revokeOnEnd: false
|
|
5811
|
+
};
|
|
5812
|
+
});
|
|
5813
|
+
if (outcome === "done") revoked++;
|
|
5814
|
+
} catch {}
|
|
5815
|
+
}
|
|
5816
|
+
return revoked;
|
|
5662
5817
|
}
|
|
5663
5818
|
/**
|
|
5664
5819
|
* Retry every pending disconnect. Each goes through the same credential check
|
|
@@ -5748,4 +5903,4 @@ async function runDetached(params) {
|
|
|
5748
5903
|
}
|
|
5749
5904
|
}
|
|
5750
5905
|
//#endregion
|
|
5751
|
-
export {
|
|
5906
|
+
export { installClaudeWakeHook as $, evaluateContactPolicy as A, contactAddress as B, RECEIVER_MODES as C, withOwnerMemberAddress as Ct, NETWORK_ADMISSION_PENDING_RETRY_MS as D, ContactPolicyReadRetryError as E, disconnectAgent as F, connectAgent as G, runContactRequest as H, AddressNotesApiError as I, refusalAfterReplacement as J, readAgentInvitation as K, addressNoteTarget as L, AgentDisconnectError as M, claimOverRevokedSetup as N, NetworkAdmissionPendingError as O, clearRevokedAddresses as P, releaseRegistrationsForProfile as Q, runAddressNotesRequest as R, runAgentConnect as S, refreshOwnerMemberAddressPeriodically as St, verificationReplySubmitted as T, agentConnectionStatus as U, contactAgentAddress as V, agentInvitationHash as W, savedReceiver as X, saveConnectionName as Y, MACHINE_RUNTIMES as Z, enrollmentResumes as _, jsonIndentation as _t, endSession as a, describeSessionHookItem as at, invitationProfileName as b, writeManagedFile as bt, pendingSessionDisconnects as c, findOnPath as ct, registerSession as d, readClaudeSettings as dt, recordHookMailCheck as et, retryPendingDisconnects as f, repairClaudeHooks as ft, enrollAgent as g, inspectManagedBlock as gt, staleSessionAgents as h, MachineFileError as ht, connectedProfilesForSession as i, describeSessionHookChange as it, canonicalContactSelector as j, createNotificationContactPolicy as k, psProcessInfo as l, hasMachineSessionHooks as lt, runDetached as m, writeClaudeSettings as mt, OMP_MAIN as n, claudeConfigDir as nt, headlessClaudeRun as o, ensureHookLauncher as ot, revokeStaleSessionAgents as p, samePath as pt, receiverStatusCommand as q, agentConnectionState as r, currentCliLocation as rt, machine_session_exports as s, ephemeralCliReason as st, HOOK_END_GRACE_MS as t, boundSessionProfiles as tt, readClaudeHookInput as u, inspectClaudeHooks as ut, connectWarnings as v, readManagedFile as vt, externalReceivingState as w, pollCheckCommand as x, readHookLauncherWarning as xt, defaultAgentProfileName as y, upsertManagedBlock as yt, ContactsApiError as z };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { b as parseWebhookEvent, c as classifySignalContent, v as isEmailReceivedEvent, y as isTrustedSender } from "./repeats-BL7ZC-_6-BZ-MphTV.js";
|
|
2
|
-
import { F as wakeReadCommand, P as skillFirstLine, Y as wakeInteractionSentence, dn as downloadEmailAttachmentPart } from "./api-command-
|
|
2
|
+
import { F as wakeReadCommand, P as skillFirstLine, Y as wakeInteractionSentence, dn as downloadEmailAttachmentPart } from "./api-command-D7DPn2Ro.js";
|
|
3
3
|
import { _ as acquireListenLock, g as ListenStateError, y as listenIdentity } from "./shared-mail-files-MwlVE90c.js";
|
|
4
4
|
import { closeSync, copyFileSync, existsSync, fsyncSync, lstatSync, mkdirSync, openSync, opendirSync, readFileSync, readdirSync, readlinkSync, renameSync, rmSync, statSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { createHash, randomUUID, scryptSync } from "node:crypto";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { A as readThreadContext, En as getSentEmail, Kt as createAuthenticatedCliApiClient } from "../api-command-
|
|
1
|
+
import { A as readThreadContext, En as getSentEmail, Kt as createAuthenticatedCliApiClient } from "../api-command-D7DPn2Ro.js";
|
|
2
2
|
import { _ as acquireListenLock } from "../shared-mail-files-MwlVE90c.js";
|
|
3
|
-
import { t as sendSignal } from "../signal-command-
|
|
3
|
+
import { t as sendSignal } from "../signal-command-Bi2U2BR_.js";
|
|
4
4
|
import { AUTO_SIGNAL_KIND_ENV, AUTO_WORKING_RENEW_MS, autoSignalsDisabled, clearWorkingSending, markWorkingSending, readAutoClaim, readWorkingLease, recordRenewer, stopWorkingLease, writeWorkingLease } from "./auto-signals.js";
|
|
5
5
|
import { join } from "node:path";
|
|
6
6
|
import { homedir } from "node:os";
|