@rubytech/create-sitedesk-code 0.1.513 → 0.1.515
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/package.json +1 -1
- package/payload/platform/docs/superpowers/plans/2026-07-27-task-2016-disabled-agent-routing.md +624 -0
- package/payload/platform/docs/superpowers/plans/2026-07-27-task-2052-account-machinery-write-fence.md +250 -0
- package/payload/platform/docs/superpowers/specs/2026-07-27-task-2016-disabled-agent-routing-design.md +139 -0
- package/payload/platform/docs/superpowers/specs/2026-07-27-task-2028-declared-file-write-deny-design.md +2 -1
- package/payload/platform/docs/superpowers/specs/2026-07-27-task-2052-account-machinery-write-fence-design.md +150 -0
- package/payload/platform/plugins/admin/hooks/__tests__/fs-schema-guard.test.sh +41 -0
- package/payload/platform/plugins/admin/hooks/fs-schema-guard-bash-post.sh +8 -0
- package/payload/platform/plugins/admin/hooks/fs-schema-guard.sh +40 -1
- package/payload/platform/plugins/admin/mcp/dist/index.js +14 -16
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/admin/mcp/dist/specialist-registry.d.ts +14 -0
- package/payload/platform/plugins/admin/mcp/dist/specialist-registry.d.ts.map +1 -0
- package/payload/platform/plugins/admin/mcp/dist/specialist-registry.js +57 -0
- package/payload/platform/plugins/admin/mcp/dist/specialist-registry.js.map +1 -0
- package/payload/platform/plugins/admin/skills/platform-architecture/SKILL.md +15 -3
- package/payload/platform/plugins/admin/skills/whats-new/SKILL.md +12 -0
- package/payload/platform/plugins/cloudflare/bin/schema-exposed-dirs.mjs +1 -1
- package/payload/platform/plugins/docs/references/admin-ui.md +14 -2
- package/payload/platform/plugins/whatsapp/references/channels-whatsapp.md +3 -3
- package/payload/platform/scripts/__tests__/agents-md-bootstrap.test.sh +47 -0
- package/payload/platform/scripts/lib/agents-md-bootstrap.sh +58 -1
- package/payload/platform/services/claude-session-manager/dist/config.d.ts +48 -12
- package/payload/platform/services/claude-session-manager/dist/config.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/config.js +65 -15
- package/payload/platform/services/claude-session-manager/dist/config.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/index.js +7 -4
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/rootless-client-audit.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/rootless-client-audit.js +17 -2
- package/payload/platform/services/claude-session-manager/dist/rootless-client-audit.js.map +1 -1
- package/payload/platform/templates/account-schema/SCHEMA.md +17 -0
- package/payload/server/public/activity.html +5 -5
- package/payload/server/public/agents.html +4 -4
- package/payload/server/public/assets/{AdminLoginScreens-bksN0XPe.js → AdminLoginScreens-Cs1jSnOF.js} +1 -1
- package/payload/server/public/assets/AdminLoginScreens-Cs1jSnOF.js.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-Cs1jSnOF.js.gz +0 -0
- package/payload/server/public/assets/{AdminShell-BMPEWNZk.js → AdminShell-DkrURZnF.js} +1 -1
- package/payload/server/public/assets/AdminShell-DkrURZnF.js.br +0 -0
- package/payload/server/public/assets/AdminShell-DkrURZnF.js.gz +0 -0
- package/payload/server/public/assets/{activity-ByWYF5dC.js → activity-BgZISMuE.js} +1 -1
- package/payload/server/public/assets/activity-BgZISMuE.js.br +0 -0
- package/payload/server/public/assets/activity-BgZISMuE.js.gz +0 -0
- package/payload/server/public/assets/{admin-6QN-k3zQ.js → admin-DjFysc3-.js} +1 -1
- package/payload/server/public/assets/admin-DjFysc3-.js.br +0 -0
- package/payload/server/public/assets/admin-DjFysc3-.js.gz +0 -0
- package/payload/server/public/assets/{agents-C0rTfrYd.js → agents-Bx-MSZW6.js} +1 -1
- package/payload/server/public/assets/agents-Bx-MSZW6.js.br +0 -0
- package/payload/server/public/assets/agents-Bx-MSZW6.js.gz +0 -0
- package/payload/server/public/assets/{browser-4tTaem8N.js → browser-1I7syhHu.js} +1 -1
- package/payload/server/public/assets/browser-1I7syhHu.js.br +0 -0
- package/payload/server/public/assets/browser-1I7syhHu.js.gz +0 -0
- package/payload/server/public/assets/{calendar-BEjnkKG1.js → calendar-D_04JIo1.js} +1 -1
- package/payload/server/public/assets/calendar-D_04JIo1.js.br +0 -0
- package/payload/server/public/assets/calendar-D_04JIo1.js.gz +0 -0
- package/payload/server/public/assets/chat-BFH3FM5a.js +1 -0
- package/payload/server/public/assets/chat-BFH3FM5a.js.br +0 -0
- package/payload/server/public/assets/chat-BFH3FM5a.js.gz +0 -0
- package/payload/server/public/assets/chevron-left-Ux9-qLkk.js +1 -0
- package/payload/server/public/assets/chevron-right-BwIuCfyG.js +1 -0
- package/payload/server/public/assets/chevron-right-BwIuCfyG.js.br +0 -0
- package/payload/server/public/assets/clock-DhJdZRhC.js +1 -0
- package/payload/server/public/assets/clock-DhJdZRhC.js.br +0 -0
- package/payload/server/public/assets/data-ChY_uSIk.js +1 -0
- package/payload/server/public/assets/data-ChY_uSIk.js.br +0 -0
- package/payload/server/public/assets/data-ChY_uSIk.js.gz +0 -0
- package/payload/server/public/assets/{file-text-DMKw3nIk.js → file-text-DkvKqHMx.js} +1 -1
- package/payload/server/public/assets/file-text-DkvKqHMx.js.br +0 -0
- package/payload/server/public/assets/file-text-DkvKqHMx.js.gz +0 -0
- package/payload/server/public/assets/{graph-C3vW8lvw.js → graph-CCZhrwZX.js} +1 -1
- package/payload/server/public/assets/graph-CCZhrwZX.js.br +0 -0
- package/payload/server/public/assets/graph-CCZhrwZX.js.gz +0 -0
- package/payload/server/public/assets/{graph-labels-BZgd0L6n.js → graph-labels-BJ7puQkX.js} +1 -1
- package/payload/server/public/assets/graph-labels-BJ7puQkX.js.br +0 -0
- package/payload/server/public/assets/graph-labels-BJ7puQkX.js.gz +0 -0
- package/payload/server/public/assets/{maximize-2-la3IBA3M.js → maximize-2-Xdj804U1.js} +1 -1
- package/payload/server/public/assets/maximize-2-Xdj804U1.js.br +0 -0
- package/payload/server/public/assets/maximize-2-Xdj804U1.js.gz +0 -0
- package/payload/server/public/assets/{operator-D9NgVL9_.js → operator-BkfNpBs7.js} +1 -1
- package/payload/server/public/assets/operator-BkfNpBs7.js.br +0 -0
- package/payload/server/public/assets/operator-BkfNpBs7.js.gz +0 -0
- package/payload/server/public/assets/{page-DC11gesX.js → page-BoYc9c4a.js} +1 -1
- package/payload/server/public/assets/page-BoYc9c4a.js.br +0 -0
- package/payload/server/public/assets/page-BoYc9c4a.js.gz +0 -0
- package/payload/server/public/assets/{page-BWFHRIAH.js → page-D5n8ShE7.js} +1 -1
- package/payload/server/public/assets/page-D5n8ShE7.js.br +0 -0
- package/payload/server/public/assets/page-D5n8ShE7.js.gz +0 -0
- package/payload/server/public/assets/{public-DQbbLHQN.js → public-CX5XSrxD.js} +1 -1
- package/payload/server/public/assets/public-CX5XSrxD.js.br +0 -0
- package/payload/server/public/assets/public-CX5XSrxD.js.gz +0 -0
- package/payload/server/public/assets/{rotate-ccw-OQD5si8N.js → rotate-ccw-dh_OhL23.js} +1 -1
- package/payload/server/public/assets/rotate-ccw-dh_OhL23.js.br +0 -0
- package/payload/server/public/assets/rotate-ccw-dh_OhL23.js.gz +0 -0
- package/payload/server/public/assets/{routines-asrBGZUR.js → routines-bb7dxcrr.js} +1 -1
- package/payload/server/public/assets/routines-bb7dxcrr.js.br +0 -0
- package/payload/server/public/assets/routines-bb7dxcrr.js.gz +0 -0
- package/payload/server/public/assets/{skills-D4ECwoxa.js → skills-TeMwxXmJ.js} +1 -1
- package/payload/server/public/assets/skills-TeMwxXmJ.js.br +0 -0
- package/payload/server/public/assets/skills-TeMwxXmJ.js.gz +0 -0
- package/payload/server/public/assets/{tasks-U3QdbUsO.js → tasks-BqBBJlkg.js} +1 -1
- package/payload/server/public/assets/tasks-BqBBJlkg.js.br +0 -0
- package/payload/server/public/assets/tasks-BqBBJlkg.js.gz +0 -0
- package/payload/server/public/assets/{time-entry-format-BgdTKgYr.js → time-entry-format-Cy_T-wiD.js} +1 -1
- package/payload/server/public/assets/time-entry-format-Cy_T-wiD.js.br +3 -0
- package/payload/server/public/assets/time-entry-format-Cy_T-wiD.js.gz +0 -0
- package/payload/server/public/assets/{triangle-alert-Ck_3VhT9.js → triangle-alert-D-bSbPnX.js} +1 -1
- package/payload/server/public/assets/triangle-alert-D-bSbPnX.js.br +1 -0
- package/payload/server/public/assets/triangle-alert-D-bSbPnX.js.gz +0 -0
- package/payload/server/public/assets/{useCopyFeedback-BdUwyNpa.js → useCopyFeedback-L7L55nFl.js} +1 -1
- package/payload/server/public/assets/useCopyFeedback-L7L55nFl.js.br +0 -0
- package/payload/server/public/assets/useCopyFeedback-L7L55nFl.js.gz +0 -0
- package/payload/server/public/assets/useSubAccountSwitcher-BYl2c7xA.css +1 -0
- package/payload/server/public/assets/useSubAccountSwitcher-BYl2c7xA.css.br +0 -0
- package/payload/server/public/assets/useSubAccountSwitcher-BYl2c7xA.css.gz +0 -0
- package/payload/server/public/assets/{useVoiceRecorder-ChnBrzbZ.js → useVoiceRecorder-MuZ7lpet.js} +1 -1
- package/payload/server/public/assets/useVoiceRecorder-MuZ7lpet.js.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-MuZ7lpet.js.gz +0 -0
- package/payload/server/public/assets/{wrench-Cpee3C3J.js → wrench-DUG1SZQB.js} +1 -1
- package/payload/server/public/assets/wrench-DUG1SZQB.js.br +0 -0
- package/payload/server/public/assets/wrench-DUG1SZQB.js.gz +0 -0
- package/payload/server/public/brand-defaults.css +2 -0
- package/payload/server/public/browser.html +4 -4
- package/payload/server/public/calendar.html +7 -7
- package/payload/server/public/chat.html +13 -13
- package/payload/server/public/data.html +11 -11
- package/payload/server/public/graph.html +9 -9
- package/payload/server/public/index.html +14 -14
- package/payload/server/public/operator.html +14 -14
- package/payload/server/public/public.html +13 -13
- package/payload/server/public/routines.html +6 -6
- package/payload/server/public/skills.html +5 -5
- package/payload/server/public/tasks.html +6 -6
- package/payload/server/server.js +138 -19
- package/payload/server/public/assets/AdminLoginScreens-bksN0XPe.js.br +0 -0
- package/payload/server/public/assets/AdminLoginScreens-bksN0XPe.js.gz +0 -0
- package/payload/server/public/assets/AdminShell-BMPEWNZk.js.br +0 -0
- package/payload/server/public/assets/AdminShell-BMPEWNZk.js.gz +0 -0
- package/payload/server/public/assets/activity-ByWYF5dC.js.br +0 -0
- package/payload/server/public/assets/activity-ByWYF5dC.js.gz +0 -0
- package/payload/server/public/assets/admin-6QN-k3zQ.js.br +0 -0
- package/payload/server/public/assets/admin-6QN-k3zQ.js.gz +0 -0
- package/payload/server/public/assets/agents-C0rTfrYd.js.br +0 -0
- package/payload/server/public/assets/agents-C0rTfrYd.js.gz +0 -0
- package/payload/server/public/assets/browser-4tTaem8N.js.br +0 -0
- package/payload/server/public/assets/browser-4tTaem8N.js.gz +0 -0
- package/payload/server/public/assets/calendar-BEjnkKG1.js.br +0 -0
- package/payload/server/public/assets/calendar-BEjnkKG1.js.gz +0 -0
- package/payload/server/public/assets/chat-DBgzjDIE.js +0 -1
- package/payload/server/public/assets/chat-DBgzjDIE.js.br +0 -0
- package/payload/server/public/assets/chat-DBgzjDIE.js.gz +0 -0
- package/payload/server/public/assets/chevron-left-DqYv3oFh.js +0 -1
- package/payload/server/public/assets/chevron-right-CQfPGsFb.js +0 -1
- package/payload/server/public/assets/chevron-right-CQfPGsFb.js.br +0 -0
- package/payload/server/public/assets/clock-Dn6FHB51.js +0 -1
- package/payload/server/public/assets/clock-Dn6FHB51.js.br +0 -0
- package/payload/server/public/assets/clock-Dn6FHB51.js.gz +0 -0
- package/payload/server/public/assets/data-D_e6Vdfd.js +0 -1
- package/payload/server/public/assets/data-D_e6Vdfd.js.br +0 -0
- package/payload/server/public/assets/data-D_e6Vdfd.js.gz +0 -0
- package/payload/server/public/assets/file-text-DMKw3nIk.js.br +0 -0
- package/payload/server/public/assets/file-text-DMKw3nIk.js.gz +0 -0
- package/payload/server/public/assets/graph-C3vW8lvw.js.br +0 -0
- package/payload/server/public/assets/graph-C3vW8lvw.js.gz +0 -0
- package/payload/server/public/assets/graph-labels-BZgd0L6n.js.br +0 -0
- package/payload/server/public/assets/graph-labels-BZgd0L6n.js.gz +0 -0
- package/payload/server/public/assets/maximize-2-la3IBA3M.js.br +0 -0
- package/payload/server/public/assets/maximize-2-la3IBA3M.js.gz +0 -0
- package/payload/server/public/assets/operator-D9NgVL9_.js.br +0 -0
- package/payload/server/public/assets/operator-D9NgVL9_.js.gz +0 -0
- package/payload/server/public/assets/page-BWFHRIAH.js.br +0 -0
- package/payload/server/public/assets/page-BWFHRIAH.js.gz +0 -0
- package/payload/server/public/assets/page-DC11gesX.js.br +0 -0
- package/payload/server/public/assets/page-DC11gesX.js.gz +0 -0
- package/payload/server/public/assets/public-DQbbLHQN.js.br +0 -0
- package/payload/server/public/assets/public-DQbbLHQN.js.gz +0 -0
- package/payload/server/public/assets/rotate-ccw-OQD5si8N.js.br +0 -0
- package/payload/server/public/assets/rotate-ccw-OQD5si8N.js.gz +0 -0
- package/payload/server/public/assets/routines-asrBGZUR.js.br +0 -0
- package/payload/server/public/assets/routines-asrBGZUR.js.gz +0 -0
- package/payload/server/public/assets/skills-D4ECwoxa.js.br +0 -0
- package/payload/server/public/assets/skills-D4ECwoxa.js.gz +0 -0
- package/payload/server/public/assets/tasks-U3QdbUsO.js.br +0 -0
- package/payload/server/public/assets/tasks-U3QdbUsO.js.gz +0 -0
- package/payload/server/public/assets/time-entry-format-BgdTKgYr.js.br +0 -0
- package/payload/server/public/assets/time-entry-format-BgdTKgYr.js.gz +0 -0
- package/payload/server/public/assets/triangle-alert-Ck_3VhT9.js.br +0 -0
- package/payload/server/public/assets/triangle-alert-Ck_3VhT9.js.gz +0 -0
- package/payload/server/public/assets/useCopyFeedback-BdUwyNpa.js.br +0 -0
- package/payload/server/public/assets/useCopyFeedback-BdUwyNpa.js.gz +0 -0
- package/payload/server/public/assets/useSubAccountSwitcher-DOWQXDT8.css +0 -1
- package/payload/server/public/assets/useSubAccountSwitcher-DOWQXDT8.css.br +0 -0
- package/payload/server/public/assets/useSubAccountSwitcher-DOWQXDT8.css.gz +0 -0
- package/payload/server/public/assets/useVoiceRecorder-ChnBrzbZ.js.br +0 -0
- package/payload/server/public/assets/useVoiceRecorder-ChnBrzbZ.js.gz +0 -0
- package/payload/server/public/assets/wrench-Cpee3C3J.js.br +0 -2
- package/payload/server/public/assets/wrench-Cpee3C3J.js.gz +0 -0
- /package/payload/server/public/assets/{useSubAccountSwitcher-CJKjEPNN.js → useSubAccountSwitcher-DH0P6QMV.js} +0 -0
- /package/payload/server/public/assets/{useSubAccountSwitcher-CJKjEPNN.js.br → useSubAccountSwitcher-DH0P6QMV.js.br} +0 -0
- /package/payload/server/public/assets/{useSubAccountSwitcher-CJKjEPNN.js.gz → useSubAccountSwitcher-DH0P6QMV.js.gz} +0 -0
package/payload/server/server.js
CHANGED
|
@@ -3219,7 +3219,7 @@ var WhatsAppConfigSchema = z.object({
|
|
|
3219
3219
|
z.string(),
|
|
3220
3220
|
z.object({ managesAccount: z.string(), mode: z.enum(["active", "passive"]).optional() })
|
|
3221
3221
|
])
|
|
3222
|
-
).optional().describe("Account-manager bindings: E.164 phone \u2192 sub-account. The value is a bare sub-account UUID (mode 'active', the default: a full admin session) or { managesAccount, mode } where mode 'passive' selects a constrained requirement-intake spawn (only work-create, no reply). A bare string and an object without mode both resolve to 'active'. Managed via add-account-manager / remove-account-manager. A phone here must not also be in adminPhones."),
|
|
3222
|
+
).optional().describe("Account-manager bindings: E.164 phone \u2192 sub-account. The value is a bare sub-account UUID (mode 'active', the default: a full admin session) or { managesAccount, mode } where mode 'passive' selects a constrained requirement-intake spawn (only work-create, no reply). A bare string and an object without mode both resolve to 'active'. Managed via add-account-manager / remove-account-manager. A phone here must not also be in adminPhones. Read only from the account whose account.json the manager loads its config from (the house); add-account-manager is refused on any other account, and a map left there is inert and purged at boot."),
|
|
3223
3223
|
allowFrom: z.array(z.string()).optional().describe("Phone numbers allowed to message the public agent when DM policy is 'allowlist'. Add '*' for open access. Does not affect admin routing \u2014 use adminPhones for that."),
|
|
3224
3224
|
sendReadReceipts: z.boolean().optional().default(true).describe("Whether to send read receipts (blue ticks) when messages are received. Disabling may feel less responsive but preserves privacy."),
|
|
3225
3225
|
mediaMaxMb: z.number().int().positive().optional().default(50).describe("Maximum file size in MB for media the agent will download and process."),
|
|
@@ -5104,6 +5104,9 @@ function resolvePlatformAccountId(accountsDir = ACCOUNTS_DIR) {
|
|
|
5104
5104
|
const routed = readChannelRoutingOverride(accountsDir, houseId);
|
|
5105
5105
|
return routed ?? houseId;
|
|
5106
5106
|
}
|
|
5107
|
+
function resolveHouseAccountId(accountsDir = ACCOUNTS_DIR) {
|
|
5108
|
+
return resolveHouseId(accountsDir);
|
|
5109
|
+
}
|
|
5107
5110
|
|
|
5108
5111
|
// app/lib/whatsapp/account-id-shape.ts
|
|
5109
5112
|
var UUID_RE2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
@@ -6277,10 +6280,12 @@ async function startConnection(accountId) {
|
|
|
6277
6280
|
return;
|
|
6278
6281
|
}
|
|
6279
6282
|
let platformAccountId;
|
|
6283
|
+
let houseAccountId;
|
|
6280
6284
|
try {
|
|
6281
6285
|
platformAccountId = resolvePlatformAccountId();
|
|
6286
|
+
houseAccountId = resolveHouseAccountId();
|
|
6282
6287
|
console.error(
|
|
6283
|
-
`[whatsapp-persist] resolved-account-id waname=${accountId} uuid=${platformAccountId}`
|
|
6288
|
+
`[whatsapp-persist] resolved-account-id waname=${accountId} uuid=${platformAccountId} house=${houseAccountId}`
|
|
6284
6289
|
);
|
|
6285
6290
|
} catch (err) {
|
|
6286
6291
|
const reason = err instanceof Error ? err.message : String(err);
|
|
@@ -6293,6 +6298,7 @@ async function startConnection(accountId) {
|
|
|
6293
6298
|
const conn = {
|
|
6294
6299
|
accountId,
|
|
6295
6300
|
platformAccountId,
|
|
6301
|
+
houseAccountId,
|
|
6296
6302
|
accountName: whatsAppConfig.accounts?.[accountId]?.name,
|
|
6297
6303
|
authDir,
|
|
6298
6304
|
sock: null,
|
|
@@ -6370,6 +6376,10 @@ function resolveInboundPersistAccount(args) {
|
|
|
6370
6376
|
warnNonUuidAccount("inbound-persist", account);
|
|
6371
6377
|
return account;
|
|
6372
6378
|
}
|
|
6379
|
+
function isManagerRoutedToHouse(args) {
|
|
6380
|
+
const result = args.accessResult;
|
|
6381
|
+
return result?.allowed === true && result.reason === "account-manager" && result.effectiveAccountId === args.houseAccountId;
|
|
6382
|
+
}
|
|
6373
6383
|
function resolveConversationPersistAccount(sendAccountId, counterpartyPhone) {
|
|
6374
6384
|
const conn = findConnectionByKey(Array.from(connections2.values()), sendAccountId);
|
|
6375
6385
|
if (!conn) {
|
|
@@ -6399,10 +6409,12 @@ function listConnectionPlatformAccountIds() {
|
|
|
6399
6409
|
async function registerLoginSocket(accountId, sock, authDir) {
|
|
6400
6410
|
if (!configDir) throw new Error("WhatsApp manager not initialized");
|
|
6401
6411
|
let platformAccountId;
|
|
6412
|
+
let houseAccountId;
|
|
6402
6413
|
try {
|
|
6403
6414
|
platformAccountId = resolvePlatformAccountId();
|
|
6415
|
+
houseAccountId = resolveHouseAccountId();
|
|
6404
6416
|
console.error(
|
|
6405
|
-
`[whatsapp-persist] resolved-account-id waname=${accountId} uuid=${platformAccountId}`
|
|
6417
|
+
`[whatsapp-persist] resolved-account-id waname=${accountId} uuid=${platformAccountId} house=${houseAccountId}`
|
|
6406
6418
|
);
|
|
6407
6419
|
} catch (err) {
|
|
6408
6420
|
const reason = err instanceof Error ? err.message : String(err);
|
|
@@ -6415,6 +6427,7 @@ async function registerLoginSocket(accountId, sock, authDir) {
|
|
|
6415
6427
|
const conn = {
|
|
6416
6428
|
accountId,
|
|
6417
6429
|
platformAccountId,
|
|
6430
|
+
houseAccountId,
|
|
6418
6431
|
accountName: whatsAppConfig.accounts?.[accountId]?.name,
|
|
6419
6432
|
authDir,
|
|
6420
6433
|
sock,
|
|
@@ -7079,7 +7092,10 @@ async function handleInboundMessage(conn, msg) {
|
|
|
7079
7092
|
`[whatsapp-native] op=account-manager-reject senderId=${senderPhone} reason=unresolved-effective-account`
|
|
7080
7093
|
);
|
|
7081
7094
|
}
|
|
7082
|
-
if (
|
|
7095
|
+
if (isManagerRoutedToHouse({
|
|
7096
|
+
accessResult,
|
|
7097
|
+
houseAccountId: conn.houseAccountId
|
|
7098
|
+
})) {
|
|
7083
7099
|
console.error(
|
|
7084
7100
|
`[whatsapp-native] op=escalation-tripwire senderId=${senderPhone} reason=account-manager-routed-to-house effectiveAccount=${accessResult.effectiveAccountId}`
|
|
7085
7101
|
);
|
|
@@ -8107,7 +8123,7 @@ function createScheduleInjectRoutes(deps) {
|
|
|
8107
8123
|
const houseAccountId = account.accountId;
|
|
8108
8124
|
console.error(`${TAG21} op=received eventId=${eventId} channel=${channel} destination=${destination} account=${houseAccountId}`);
|
|
8109
8125
|
if (channel === "whatsapp") {
|
|
8110
|
-
const effectiveAccount2 = deps.effectiveAccountFor(
|
|
8126
|
+
const effectiveAccount2 = deps.effectiveAccountFor(account.accountDir, destination);
|
|
8111
8127
|
if (effectiveAccount2 === null) {
|
|
8112
8128
|
console.error(`${TAG21} op=schedule-account-manager-reject eventId=${eventId} destination=${destination} reason=unresolved-effective-account`);
|
|
8113
8129
|
return c.json({ ok: false, error: "account-manager-unresolved" }, 403);
|
|
@@ -8425,6 +8441,54 @@ function purgeNonSocketAdminPhonesAtBoot() {
|
|
|
8425
8441
|
purgeNonSocketAdminPhones(acct.accountDir, socketOwner);
|
|
8426
8442
|
}
|
|
8427
8443
|
}
|
|
8444
|
+
function purgeNonSocketAccountManagers(accountDir, socketOwnerId) {
|
|
8445
|
+
try {
|
|
8446
|
+
const config = readConfig(accountDir);
|
|
8447
|
+
const wa = config.whatsapp;
|
|
8448
|
+
if (!wa || typeof wa !== "object") return { removed: [] };
|
|
8449
|
+
const targetId = typeof config.accountId === "string" && config.accountId ? config.accountId : basename2(resolve9(accountDir));
|
|
8450
|
+
if (targetId === socketOwnerId) return { removed: [] };
|
|
8451
|
+
const map = wa.accountManagers;
|
|
8452
|
+
if (!map || typeof map !== "object" || Array.isArray(map)) return { removed: [] };
|
|
8453
|
+
const removed = Object.entries(map).map(([phone, entry]) => ({
|
|
8454
|
+
phone,
|
|
8455
|
+
managesAccount: typeof entry === "string" ? entry : entry && typeof entry === "object" && typeof entry.managesAccount === "string" ? entry.managesAccount : ""
|
|
8456
|
+
}));
|
|
8457
|
+
if (removed.length === 0) return { removed: [] };
|
|
8458
|
+
delete wa.accountManagers;
|
|
8459
|
+
writeConfig(accountDir, config);
|
|
8460
|
+
for (const { phone, managesAccount } of removed) {
|
|
8461
|
+
console.error(`[admin-identity] op=purge-nonsocket-accountmanager accountId=${targetId} phone=${phone} managesAccount=${managesAccount} removed=true`);
|
|
8462
|
+
}
|
|
8463
|
+
return { removed };
|
|
8464
|
+
} catch (err) {
|
|
8465
|
+
console.error(`[admin-identity] purge-nonsocket-accountmanager failed dir=${accountDir}: ${String(err)}`);
|
|
8466
|
+
return { removed: [] };
|
|
8467
|
+
}
|
|
8468
|
+
}
|
|
8469
|
+
function purgeNonSocketAccountManagersAtBoot() {
|
|
8470
|
+
let socketOwner;
|
|
8471
|
+
try {
|
|
8472
|
+
socketOwner = resolveHouseOrSoleAccountId(ACCOUNTS_DIR);
|
|
8473
|
+
} catch (err) {
|
|
8474
|
+
console.error(`[admin-identity] purge-nonsocket-accountmanager skipped \u2014 cannot resolve socket owner: ${String(err)}`);
|
|
8475
|
+
return;
|
|
8476
|
+
}
|
|
8477
|
+
const configOwner = resolveAccount()?.accountId ?? null;
|
|
8478
|
+
if (configOwner !== socketOwner) {
|
|
8479
|
+
console.error(`[admin-identity] purge-nonsocket-accountmanager skipped \u2014 resolver disagreement house=${socketOwner} configLoadedFrom=${configOwner ?? "unresolved"}`);
|
|
8480
|
+
return;
|
|
8481
|
+
}
|
|
8482
|
+
let accounts;
|
|
8483
|
+
try {
|
|
8484
|
+
accounts = listValidAccounts();
|
|
8485
|
+
} catch {
|
|
8486
|
+
return;
|
|
8487
|
+
}
|
|
8488
|
+
for (const acct of accounts) {
|
|
8489
|
+
purgeNonSocketAccountManagers(acct.accountDir, socketOwner);
|
|
8490
|
+
}
|
|
8491
|
+
}
|
|
8428
8492
|
function setAccountManager(accountDir, phone, subAccountId, mode = "active") {
|
|
8429
8493
|
const normalized = phone.trim();
|
|
8430
8494
|
if (!E164_PATTERN.test(normalized)) {
|
|
@@ -8443,8 +8507,31 @@ function setAccountManager(accountDir, phone, subAccountId, mode = "active") {
|
|
|
8443
8507
|
if (!validIds.includes(sub)) {
|
|
8444
8508
|
return { ok: false, error: `Sub-account "${sub}" is not in this install's account registry. Check the sub-account id and try again.` };
|
|
8445
8509
|
}
|
|
8510
|
+
let houseId;
|
|
8511
|
+
try {
|
|
8512
|
+
houseId = resolveHouseOrSoleAccountId(dirname2(resolve9(accountDir)));
|
|
8513
|
+
} catch (err) {
|
|
8514
|
+
return { ok: false, error: `Could not resolve the house account to validate the binding: ${err instanceof Error ? err.message : String(err)}. Try again.` };
|
|
8515
|
+
}
|
|
8516
|
+
if (sub === houseId) {
|
|
8517
|
+
console.error(`${TAG22} set-account-manager rejected phone=${normalized} reason=house-account-binding`);
|
|
8518
|
+
return {
|
|
8519
|
+
ok: false,
|
|
8520
|
+
reason: "house-account-binding",
|
|
8521
|
+
error: `${sub} is the house account, not a sub-account. An account manager bound to it would get house-owner admin scope. To make ${normalized} a house admin, add it to admin phones instead.`
|
|
8522
|
+
};
|
|
8523
|
+
}
|
|
8446
8524
|
try {
|
|
8447
8525
|
const config = readConfig(accountDir);
|
|
8526
|
+
const targetId = typeof config.accountId === "string" && config.accountId ? config.accountId : basename2(resolve9(accountDir));
|
|
8527
|
+
if (targetId !== houseId) {
|
|
8528
|
+
console.error(`${TAG22} set-account-manager rejected phone=${normalized} reason=not-socket-account`);
|
|
8529
|
+
return {
|
|
8530
|
+
ok: false,
|
|
8531
|
+
reason: "not-socket-account",
|
|
8532
|
+
error: `The account-manager routing table is read from ${houseId}'s account.json only, so a binding stored on ${targetId} is never consulted. Bind ${normalized} on ${houseId} instead.`
|
|
8533
|
+
};
|
|
8534
|
+
}
|
|
8448
8535
|
if (!config.whatsapp || typeof config.whatsapp !== "object") {
|
|
8449
8536
|
config.whatsapp = {};
|
|
8450
8537
|
}
|
|
@@ -9622,7 +9709,8 @@ app2.post("/config", async (c) => {
|
|
|
9622
9709
|
}
|
|
9623
9710
|
const managerMode = mode === "passive" ? "passive" : "active";
|
|
9624
9711
|
const result = setAccountManager(account.accountDir, phone, managesAccount, managerMode);
|
|
9625
|
-
|
|
9712
|
+
const managerReasonTail = !result.ok && result.reason ? ` reason=${result.reason}` : "";
|
|
9713
|
+
console.error(`${TAG26} config action=add-account-manager phone=${phone} managesAccount=${managesAccount} mode=${managerMode} ok=${result.ok}${managerReasonTail}`);
|
|
9626
9714
|
return c.json(result, result.ok ? 200 : 400);
|
|
9627
9715
|
}
|
|
9628
9716
|
case "remove-account-manager": {
|
|
@@ -17031,6 +17119,7 @@ var session_upload_default = app17;
|
|
|
17031
17119
|
// server/routes/admin/agents.ts
|
|
17032
17120
|
import { resolve as resolve23 } from "path";
|
|
17033
17121
|
import { readdirSync as readdirSync22, readFileSync as readFileSync33, existsSync as existsSync31, rmSync as rmSync2, renameSync as renameSync9, mkdirSync as mkdirSync7, writeFileSync as writeFileSync13 } from "fs";
|
|
17122
|
+
import { execFileSync as execFileSync6 } from "child_process";
|
|
17034
17123
|
|
|
17035
17124
|
// ../services/claude-session-manager/src/tool-surface.ts
|
|
17036
17125
|
import { readFileSync as readFileSync32, readdirSync as readdirSync21, statSync as statSync15, existsSync as existsSync30 } from "fs";
|
|
@@ -17780,6 +17869,17 @@ async function resolveWritableAccount(c, op, slug) {
|
|
|
17780
17869
|
}
|
|
17781
17870
|
return account;
|
|
17782
17871
|
}
|
|
17872
|
+
function reconcileRoutingProse(accountDir, accountId, op, slug) {
|
|
17873
|
+
const script = resolve23(PLATFORM_ROOT, "scripts", "lib", "agents-md-bootstrap.sh");
|
|
17874
|
+
try {
|
|
17875
|
+
execFileSync6("bash", [script, accountDir], { encoding: "utf-8", timeout: 1e4 });
|
|
17876
|
+
return true;
|
|
17877
|
+
} catch (err) {
|
|
17878
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
17879
|
+
console.error(`[admin/agents] op=agents-md-reconcile source=${op} accountId=${accountId.slice(0, 8)} slug=${slug} outcome=failed reason="${msg}"`);
|
|
17880
|
+
return false;
|
|
17881
|
+
}
|
|
17882
|
+
}
|
|
17783
17883
|
app18.post("/:slug/disable", async (c) => {
|
|
17784
17884
|
const slug = c.req.param("slug");
|
|
17785
17885
|
if (SLUG_UNSAFE(slug)) return c.json({ error: "Invalid agent slug" }, 400);
|
|
@@ -17807,8 +17907,9 @@ app18.post("/:slug/disable", async (c) => {
|
|
|
17807
17907
|
console.error(`[admin/agents] op=disable accountId=${resolved.accountId.slice(0, 8)} slug=${slug} outcome=failed reason="${msg}"`);
|
|
17808
17908
|
return c.json({ error: `Disable failed, disabled store unreadable or unwritable: ${msg}` }, 500);
|
|
17809
17909
|
}
|
|
17810
|
-
|
|
17811
|
-
|
|
17910
|
+
const routingReconciled = reconcileRoutingProse(resolved.accountDir, resolved.accountId, "disable", slug);
|
|
17911
|
+
console.log(`[admin/agents] op=disable accountId=${resolved.accountId.slice(0, 8)} slug=${slug} outcome=ok moved=${moved} routingReconciled=${routingReconciled}`);
|
|
17912
|
+
return c.json({ ok: true, moved, routingReconciled });
|
|
17812
17913
|
});
|
|
17813
17914
|
app18.post("/:slug/enable", async (c) => {
|
|
17814
17915
|
const slug = c.req.param("slug");
|
|
@@ -17837,8 +17938,9 @@ app18.post("/:slug/enable", async (c) => {
|
|
|
17837
17938
|
console.error(`[admin/agents] op=enable accountId=${resolved.accountId.slice(0, 8)} slug=${slug} outcome=failed reason="${msg}"`);
|
|
17838
17939
|
return c.json({ error: `Enable failed: ${msg}` }, 500);
|
|
17839
17940
|
}
|
|
17840
|
-
|
|
17841
|
-
|
|
17941
|
+
const routingReconciled = reconcileRoutingProse(resolved.accountDir, resolved.accountId, "enable", slug);
|
|
17942
|
+
console.log(`[admin/agents] op=enable accountId=${resolved.accountId.slice(0, 8)} slug=${slug} outcome=ok restored=${restored} routingReconciled=${routingReconciled}`);
|
|
17943
|
+
return c.json({ ok: true, restored, routingReconciled });
|
|
17842
17944
|
});
|
|
17843
17945
|
app18.delete("/:slug", async (c) => {
|
|
17844
17946
|
const slug = c.req.param("slug");
|
|
@@ -26555,7 +26657,7 @@ var admin_users_list_default = app56;
|
|
|
26555
26657
|
import { readdirSync as readdirSync27 } from "fs";
|
|
26556
26658
|
var app57 = new Hono();
|
|
26557
26659
|
var TAG47 = "[activity]";
|
|
26558
|
-
function
|
|
26660
|
+
function resolveHouseAccountId2(accounts) {
|
|
26559
26661
|
const houses = accounts.filter((a) => a.config.role === "house");
|
|
26560
26662
|
if (houses.length === 1) return { accountId: houses[0].accountId, reason: "house" };
|
|
26561
26663
|
if (houses.length > 1) return { accountId: null, reason: "multiple-houses" };
|
|
@@ -26580,7 +26682,7 @@ app57.get("/", requireAdminSession, async (c) => {
|
|
|
26580
26682
|
const cacheKey = c.var.cacheKey;
|
|
26581
26683
|
const caller2 = getAccountIdForSession(cacheKey) ?? null;
|
|
26582
26684
|
const valid = listValidAccounts();
|
|
26583
|
-
const house =
|
|
26685
|
+
const house = resolveHouseAccountId2(valid);
|
|
26584
26686
|
const isHouse = caller2 !== null && house.accountId !== null && caller2 === house.accountId;
|
|
26585
26687
|
console.log(
|
|
26586
26688
|
`${TAG47} op=request req=${req} caller=${short(caller2)} house=${isHouse} houseVia=${house.reason}`
|
|
@@ -31749,6 +31851,22 @@ function warnOnChannelAdminBindingDrift() {
|
|
|
31749
31851
|
}
|
|
31750
31852
|
}
|
|
31751
31853
|
|
|
31854
|
+
// server/routes/channel/effective-account.ts
|
|
31855
|
+
function resolveScheduledEffectiveAccount(deps, accountDir, destination) {
|
|
31856
|
+
const managed = managedAccountFor(deps.readAccountManagers(accountDir), destination);
|
|
31857
|
+
if (managed === null) return deps.resolvePlatformAccountId();
|
|
31858
|
+
if (managed.mode === "passive") return null;
|
|
31859
|
+
if (!deps.isValidAccountId(managed.account)) return null;
|
|
31860
|
+
return managed.account;
|
|
31861
|
+
}
|
|
31862
|
+
function resolveScheduledEffectiveAccountForInstall(accountDir, destination) {
|
|
31863
|
+
return resolveScheduledEffectiveAccount(
|
|
31864
|
+
{ readAccountManagers, resolvePlatformAccountId, isValidAccountId },
|
|
31865
|
+
accountDir,
|
|
31866
|
+
destination
|
|
31867
|
+
);
|
|
31868
|
+
}
|
|
31869
|
+
|
|
31752
31870
|
// server/lib/booking-site-accounts.ts
|
|
31753
31871
|
import { existsSync as existsSync46, readFileSync as readFileSync46 } from "fs";
|
|
31754
31872
|
import { resolve as resolve43 } from "path";
|
|
@@ -32481,13 +32599,13 @@ var scheduleInjectRoutes = createScheduleInjectRoutes({
|
|
|
32481
32599
|
const sent = await sendTelegramText(botToken, chatId, text);
|
|
32482
32600
|
if (!sent.ok) throw new Error(sent.error ?? "telegram send failed");
|
|
32483
32601
|
},
|
|
32484
|
-
|
|
32485
|
-
|
|
32486
|
-
|
|
32487
|
-
|
|
32488
|
-
|
|
32489
|
-
|
|
32490
|
-
|
|
32602
|
+
// Task 2051 — the four branches moved into their own module so they have a
|
|
32603
|
+
// test, and so the non-manager branch resolves the channel account through
|
|
32604
|
+
// `resolvePlatformAccountId` (the function the live inbound path uses) rather
|
|
32605
|
+
// than returning the house id this closure used to be handed. See
|
|
32606
|
+
// effective-account.ts for why `resolveAccount()` was the wrong side to move,
|
|
32607
|
+
// and why the real dependencies are bound there rather than assembled here.
|
|
32608
|
+
effectiveAccountFor: resolveScheduledEffectiveAccountForInstall
|
|
32491
32609
|
});
|
|
32492
32610
|
app69.route("/api/channel/schedule-inject", scheduleInjectRoutes);
|
|
32493
32611
|
app69.use("*", clientIpMiddleware);
|
|
@@ -33789,6 +33907,7 @@ for (const acct of listValidAccounts()) {
|
|
|
33789
33907
|
cleanupLeakedPremiumSubs(acct.accountDir, acct.config, acct.accountId);
|
|
33790
33908
|
}
|
|
33791
33909
|
purgeNonSocketAdminPhonesAtBoot();
|
|
33910
|
+
purgeNonSocketAccountManagersAtBoot();
|
|
33792
33911
|
void preloadEmbedModel();
|
|
33793
33912
|
warnOnChannelAdminBindingDrift();
|
|
33794
33913
|
var bootEnabled = Array.isArray(bootAccountConfig?.enabledPlugins) ? bootAccountConfig.enabledPlugins : [];
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{B as e,W as t}from"./useSubAccountSwitcher-CJKjEPNN.js";import"./useVoiceRecorder-ChnBrzbZ.js";import"./AdminShell-BMPEWNZk.js";import{n}from"./page-DC11gesX.js";import"./useCopyFeedback-BdUwyNpa.js";var r=t(),i=e();(0,r.createRoot)(document.getElementById(`root`)).render((0,i.jsx)(n,{}));
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{P as e}from"./useSubAccountSwitcher-CJKjEPNN.js";var t=e(`chevron-left`,[[`path`,{d:`m15 18-6-6 6-6`,key:`1wnfg3`}]]);export{t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{P as e}from"./useSubAccountSwitcher-CJKjEPNN.js";var t=e(`chevron-right`,[[`path`,{d:`m9 18 6-6-6-6`,key:`mthhwq`}]]);export{t};
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{P as e}from"./useSubAccountSwitcher-CJKjEPNN.js";var t=e(`clock`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M12 6v6l4 2`,key:`mmk7yg`}]]);export{t};
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{B as e,W as t}from"./useSubAccountSwitcher-CJKjEPNN.js";import"./useVoiceRecorder-ChnBrzbZ.js";import{t as n}from"./page-BWFHRIAH.js";import"./graph-labels-BZgd0L6n.js";var r=t(),i=e();(0,r.createRoot)(document.getElementById(`root`)).render((0,i.jsx)(n,{}));
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|