@rubytech/create-maxy-code 0.1.23 → 0.1.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +63 -16
- package/package.json +1 -1
- package/payload/platform/plugins/admin/PLUGIN.md +50 -23
- package/payload/platform/plugins/admin/skills/admin-user-management/SKILL.md +47 -0
- package/payload/platform/plugins/admin/skills/commitment-followthrough/SKILL.md +60 -0
- package/payload/platform/plugins/admin/skills/file-presentation/SKILL.md +67 -0
- package/payload/platform/plugins/admin/skills/onboarding/SKILL.md +111 -126
- package/payload/platform/plugins/admin/skills/session-management/SKILL.md +62 -0
- package/payload/platform/plugins/cloudflare/references/dashboard-guide.md +37 -0
- package/payload/platform/plugins/cloudflare/references/manual-setup.md +81 -1
- package/payload/platform/plugins/cloudflare/scripts/__tests__/tunnel-ingress.test.ts +241 -0
- package/payload/platform/plugins/cloudflare/scripts/setup-tunnel.sh +267 -28
- package/payload/platform/plugins/cloudflare/scripts/tunnel-ingress.ts +291 -0
- package/payload/platform/plugins/cloudflare/skills/setup-tunnel/SKILL.md +42 -0
- package/payload/platform/plugins/contacts/PLUGIN.md +18 -9
- package/payload/platform/plugins/deep-research/.claude-plugin/plugin.json +1 -1
- package/payload/platform/plugins/deep-research/PLUGIN.md +7 -1
- package/payload/platform/plugins/deep-research/recipes/README.md +36 -0
- package/payload/platform/plugins/deep-research/skills/academic-verify/SKILL.md +75 -0
- package/payload/platform/plugins/deep-research/skills/book-mirror/SKILL.md +68 -0
- package/payload/platform/plugins/deep-research/skills/data-research/SKILL.md +108 -0
- package/payload/platform/plugins/deep-research/skills/strategic-reading/SKILL.md +69 -0
- package/payload/platform/plugins/docs/references/deployment.md +3 -2
- package/payload/platform/plugins/docs/references/platform.md +2 -0
- package/payload/platform/plugins/docs/references/troubleshooting.md +12 -0
- package/payload/platform/plugins/email/PLUGIN.md +18 -9
- package/payload/platform/plugins/email/mcp/dist/lib/claude-bridge.d.ts +17 -0
- package/payload/platform/plugins/email/mcp/dist/lib/claude-bridge.d.ts.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/lib/claude-bridge.js +185 -0
- package/payload/platform/plugins/email/mcp/dist/lib/claude-bridge.js.map +1 -0
- package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts +1 -1
- package/payload/platform/plugins/email/mcp/dist/scripts/email-auto-respond.js +34 -111
- package/payload/platform/plugins/email/mcp/dist/scripts/email-auto-respond.js.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/scripts/email-fetch.d.ts +7 -2
- package/payload/platform/plugins/email/mcp/dist/scripts/email-fetch.d.ts.map +1 -1
- package/payload/platform/plugins/email/mcp/dist/scripts/email-fetch.js +7 -2
- package/payload/platform/plugins/email/mcp/dist/scripts/email-fetch.js.map +1 -1
- package/payload/platform/plugins/linkedin-import/skills/linkedin-import/SKILL.md +2 -0
- package/payload/platform/plugins/memory/PLUGIN.md +64 -29
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.d.ts +3 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.js +105 -4
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-read.js.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.d.ts.map +1 -1
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js +16 -3
- package/payload/platform/plugins/memory/mcp/dist/tools/profile-update.js.map +1 -1
- package/payload/platform/plugins/memory/skills/archive-crawler/SKILL.md +67 -0
- package/payload/platform/plugins/memory/skills/concept-synthesis/SKILL.md +80 -0
- package/payload/platform/plugins/memory/skills/conversation-archive/SKILL.md +2 -0
- package/payload/platform/plugins/memory/skills/document-ingest/SKILL.md +2 -0
- package/payload/platform/plugins/outlook/PLUGIN.md +14 -7
- package/payload/platform/plugins/replicate/PLUGIN.md +6 -3
- package/payload/platform/plugins/scheduling/PLUGIN.md +19 -8
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.d.ts +7 -3
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.d.ts.map +1 -1
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +7 -3
- package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
- package/payload/platform/plugins/scheduling/skills/briefing/SKILL.md +75 -0
- package/payload/platform/plugins/scheduling/skills/daily-prep/SKILL.md +61 -0
- package/payload/platform/plugins/tasks/PLUGIN.md +28 -14
- package/payload/platform/plugins/telegram/PLUGIN.md +6 -3
- package/payload/platform/plugins/waitlist/PLUGIN.md +12 -6
- package/payload/platform/plugins/whatsapp/PLUGIN.md +25 -13
- package/payload/platform/plugins/workflows/PLUGIN.md +16 -8
- package/payload/platform/scripts/conversation-id-allowlist.txt +0 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/http-server.js +27 -2
- package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/index.js +27 -0
- package/payload/platform/services/claude-session-manager/dist/index.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +36 -0
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +41 -3
- package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts +25 -1
- package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/system-prompt.js +54 -3
- package/payload/platform/services/claude-session-manager/dist/system-prompt.js.map +1 -1
- package/payload/platform/services/claude-session-manager/dist/tool-surface.d.ts +25 -0
- package/payload/platform/services/claude-session-manager/dist/tool-surface.d.ts.map +1 -0
- package/payload/platform/services/claude-session-manager/dist/tool-surface.js +149 -0
- package/payload/platform/services/claude-session-manager/dist/tool-surface.js.map +1 -0
- package/payload/platform/templates/agents/admin/IDENTITY.md +38 -284
- package/payload/platform/templates/agents/admin/SOUL.md +4 -4
- package/payload/platform/templates/specialists/agents/content-producer.md +24 -69
- package/payload/platform/templates/specialists/agents/database-operator.md +49 -155
- package/payload/platform/templates/specialists/agents/personal-assistant.md +27 -177
- package/payload/platform/templates/specialists/agents/project-manager.md +29 -96
- package/payload/platform/templates/specialists/agents/research-assistant.md +36 -78
- package/payload/premium-plugins/real-agency/agents/compliance.md +14 -0
- package/payload/premium-plugins/real-agency/agents/negotiator.md +22 -0
- package/payload/premium-plugins/real-agency/agents/valuer.md +16 -0
- package/payload/premium-plugins/real-agency/plugins/estate-business/.claude-plugin/plugin.json +1 -1
- package/payload/premium-plugins/real-agency/plugins/estate-business/PLUGIN.md +44 -13
- package/payload/premium-plugins/real-agency/plugins/estate-business/skills/commission-calculator/SKILL.md +40 -0
- package/payload/premium-plugins/real-agency/plugins/estate-business/skills/month-end-close/SKILL.md +69 -0
- package/payload/premium-plugins/real-agency/plugins/estate-business/skills/payment-batch-stager/SKILL.md +42 -0
- package/payload/premium-plugins/real-agency/plugins/estate-business/skills/period-reconciler/SKILL.md +42 -0
- package/payload/premium-plugins/real-agency/plugins/estate-sales/.claude-plugin/plugin.json +1 -1
- package/payload/premium-plugins/real-agency/plugins/estate-sales/PLUGIN.md +32 -13
- package/payload/premium-plugins/real-agency/plugins/estate-sales/skills/chase-progression/SKILL.md +107 -0
- package/payload/premium-plugins/real-agency/plugins/estate-sales/skills/risk-scorer/SKILL.md +42 -0
- package/payload/premium-plugins/real-agency/plugins/leads/.claude-plugin/plugin.json +1 -1
- package/payload/premium-plugins/real-agency/plugins/leads/PLUGIN.md +40 -10
- package/payload/premium-plugins/real-agency/plugins/leads/skills/chain-progression-tracker/SKILL.md +51 -0
- package/payload/premium-plugins/real-agency/plugins/leads/skills/diary-builder/SKILL.md +38 -0
- package/payload/premium-plugins/real-agency/plugins/leads/skills/enquiry-triage/SKILL.md +36 -0
- package/payload/premium-plugins/real-agency/plugins/leads/skills/morning-round/SKILL.md +72 -0
- package/payload/premium-plugins/real-agency/plugins/listings/.claude-plugin/plugin.json +1 -1
- package/payload/premium-plugins/real-agency/plugins/listings/PLUGIN.md +82 -12
- package/payload/premium-plugins/real-agency/plugins/listings/skills/comparable-finder/SKILL.md +52 -0
- package/payload/premium-plugins/real-agency/plugins/listings/skills/epc-checker/SKILL.md +38 -0
- package/payload/premium-plugins/real-agency/plugins/listings/skills/listing-copy-writer/SKILL.md +55 -0
- package/payload/premium-plugins/real-agency/plugins/listings/skills/local-market-stats/SKILL.md +33 -0
- package/payload/premium-plugins/real-agency/plugins/listings/skills/new-instruction/SKILL.md +78 -0
- package/payload/premium-plugins/real-agency/plugins/listings/skills/particulars-builder/SKILL.md +48 -0
- package/payload/premium-plugins/real-agency/plugins/listings/skills/portal-launch-scheduler/SKILL.md +49 -0
- package/payload/premium-plugins/real-agency/plugins/listings/skills/pricing-scenario-builder/SKILL.md +35 -0
- package/payload/premium-plugins/real-agency/plugins/listings/skills/supplier-booker/SKILL.md +39 -0
- package/payload/premium-plugins/real-agency/plugins/listings/skills/talk-track-composer/SKILL.md +36 -0
- package/payload/premium-plugins/real-agency/plugins/listings/skills/terms-of-business-drafter/SKILL.md +54 -0
- package/payload/premium-plugins/real-agency/plugins/listings/skills/valuation-prep/SKILL.md +69 -0
- package/payload/premium-plugins/real-agency/plugins/loop/PLUGIN.md +35 -0
- package/payload/premium-plugins/real-agency/plugins/loop/skills/compliance-flag-checker/SKILL.md +53 -0
- package/payload/premium-plugins/real-agency/plugins/loop/skills/priority-ranker/SKILL.md +40 -0
- package/payload/premium-plugins/real-agency/plugins/loop/skills/tone-matched-drafter/SKILL.md +53 -0
- package/payload/premium-plugins/real-agency/plugins/loop/skills/variance-narrator/SKILL.md +50 -0
- package/payload/premium-plugins/real-agency/plugins/loop/skills/vendor-research/SKILL.md +54 -0
- package/payload/server/{chunk-2ZNKHCQB.js → chunk-2MRZBQMH.js} +1 -1
- package/payload/server/{chunk-GPUCA2RQ.js → chunk-NL7QLVAD.js} +0 -192
- package/payload/server/{chunk-IDKWGLM5.js → chunk-YPZFYTYP.js} +1 -247
- package/payload/server/{cloudflare-task-tracker-LYI5BTYI.js → cloudflare-task-tracker-QVOGHKWV.js} +2 -2
- package/payload/server/maxy-edge.js +2 -2
- package/payload/server/package.json +0 -2
- package/payload/server/public/assets/{Checkbox-D1OQD43b.js → Checkbox-YIF0payo.js} +1 -1
- package/payload/server/public/assets/{admin-czNBxWor.js → admin-DW8IJcLc.js} +1 -1
- package/payload/server/public/assets/{architectureDiagram-Q4EWVU46-BcwgT80u.js → architectureDiagram-Q4EWVU46-Bz8mlxZZ.js} +1 -1
- package/payload/server/public/assets/{blockDiagram-DXYQGD6D-BMSyZUQA.js → blockDiagram-DXYQGD6D-DwV8Z8-i.js} +1 -1
- package/payload/server/public/assets/{brand-2cku8WFs.css → brand-DqiRNMlu.css} +1 -1
- package/payload/server/public/assets/{c4Diagram-AHTNJAMY-DPRGY1jJ.js → c4Diagram-AHTNJAMY-DiUTejMp.js} +1 -1
- package/payload/server/public/assets/channel-PtVtoBEL.js +1 -0
- package/payload/server/public/assets/{chunk-336JU56O-B7oQ3g1c.js → chunk-336JU56O-4mHZpBXe.js} +2 -2
- package/payload/server/public/assets/{chunk-426QAEUC-C1P0yFXw.js → chunk-426QAEUC-Cbv0vrN9.js} +1 -1
- package/payload/server/public/assets/{chunk-4TB4RGXK-LI7kOJd0.js → chunk-4TB4RGXK-BvLhId_2.js} +1 -1
- package/payload/server/public/assets/{chunk-5FUZZQ4R-CXQRGTQE.js → chunk-5FUZZQ4R-bBafOTkw.js} +1 -1
- package/payload/server/public/assets/{chunk-5PVQY5BW-NSyzpXRy.js → chunk-5PVQY5BW-B0NqBKVy.js} +1 -1
- package/payload/server/public/assets/{chunk-EDXVE4YY-voNwxbDs.js → chunk-EDXVE4YY-CFd4SqI6.js} +1 -1
- package/payload/server/public/assets/{chunk-ENJZ2VHE-CMEMPzYY.js → chunk-ENJZ2VHE-ajf2sb6c.js} +1 -1
- package/payload/server/public/assets/{chunk-ICPOFSXX-hEbwu-pe.js → chunk-ICPOFSXX-pWg6bug7.js} +1 -1
- package/payload/server/public/assets/{chunk-OYMX7WX6-DxskDrLs.js → chunk-OYMX7WX6-OjEd-17c.js} +1 -1
- package/payload/server/public/assets/{chunk-U2HBQHQK-D7TKgUo0.js → chunk-U2HBQHQK-DbEFSPoh.js} +1 -1
- package/payload/server/public/assets/{chunk-X2U36JSP-BvPUQEPm.js → chunk-X2U36JSP-COdNwrBb.js} +1 -1
- package/payload/server/public/assets/{chunk-YZCP3GAM-BY-RWQUW.js → chunk-YZCP3GAM-CHMWuY9B.js} +1 -1
- package/payload/server/public/assets/{chunk-ZZ45TVLE-DZvOYDY6.js → chunk-ZZ45TVLE-B-uDLQOB.js} +1 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-RVH_SEhY.js +1 -0
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-Cm3rAb93.js +1 -0
- package/payload/server/public/assets/clone-BjY0Wzht.js +1 -0
- package/payload/server/public/assets/{dagre-KV5264BT-Cnj0mUZl.js → dagre-KV5264BT-CMEzmhIL.js} +1 -1
- package/payload/server/public/assets/{dagre-Bt-fpckL.js → dagre-bhIG_KnW.js} +1 -1
- package/payload/server/public/assets/data-K_kS__sL.js +1 -0
- package/payload/server/public/assets/{device-url-actions-Bjz3Xzbm.js → device-url-actions-AcOyLSeF.js} +1 -1
- package/payload/server/public/assets/{diagram-5BDNPKRD-DjLzvOlx.js → diagram-5BDNPKRD-6RIoQhIL.js} +1 -1
- package/payload/server/public/assets/{diagram-G4DWMVQ6-DTfuRd-T.js → diagram-G4DWMVQ6-BSp36TVv.js} +1 -1
- package/payload/server/public/assets/{diagram-MMDJMWI5-BaL2mCnx.js → diagram-MMDJMWI5-D54fo52D.js} +1 -1
- package/payload/server/public/assets/{diagram-TYMM5635-C5InWY5R.js → diagram-TYMM5635-CWL8z-Pq.js} +1 -1
- package/payload/server/public/assets/{erDiagram-SMLLAGMA-DO7BXTpn.js → erDiagram-SMLLAGMA-AnnHBo3z.js} +1 -1
- package/payload/server/public/assets/{flowDiagram-DWJPFMVM-DDdAKfLf.js → flowDiagram-DWJPFMVM-laWmBl5o.js} +1 -1
- package/payload/server/public/assets/{ganttDiagram-T4ZO3ILL-arJD8Utm.js → ganttDiagram-T4ZO3ILL-B94ko8ie.js} +1 -1
- package/payload/server/public/assets/{gitGraphDiagram-UUTBAWPF-C55GH-OS.js → gitGraphDiagram-UUTBAWPF-DxzL1fxZ.js} +1 -1
- package/payload/server/public/assets/graph-DeEigyO_.js +1 -0
- package/payload/server/public/assets/graph-labels-C7I5QvNv.js +1 -0
- package/payload/server/public/assets/{graphlib-DL9PM7Ex.js → graphlib-CY-zIElM.js} +1 -1
- package/payload/server/public/assets/{infoDiagram-42DDH7IO-BMSGqUbG.js → infoDiagram-42DDH7IO-BMTajIIr.js} +1 -1
- package/payload/server/public/assets/{ishikawaDiagram-UXIWVN3A-Dw6BZ6BG.js → ishikawaDiagram-UXIWVN3A-B_QauE5O.js} +1 -1
- package/payload/server/public/assets/{journeyDiagram-VCZTEJTY-DrywUGXw.js → journeyDiagram-VCZTEJTY-DmlqSIih.js} +1 -1
- package/payload/server/public/assets/{kanban-definition-6JOO6SKY-DuwtVBBc.js → kanban-definition-6JOO6SKY-ZGDQT7xB.js} +1 -1
- package/payload/server/public/assets/{line-JAksyKHj.js → line-D13opgep.js} +1 -1
- package/payload/server/public/assets/{mermaid-parser.core-BMq-ApBW.js → mermaid-parser.core-C650Sual.js} +1 -1
- package/payload/server/public/assets/{mermaid.core-tH4oX0Kh.js → mermaid.core-BqnQoXTp.js} +3 -3
- package/payload/server/public/assets/{mindmap-definition-QFDTVHPH-D1OiiJga.js → mindmap-definition-QFDTVHPH-BS_8y-tY.js} +1 -1
- package/payload/server/public/assets/{page-BZpoS7iR.js → page-B_rpjIRr.js} +1 -1
- package/payload/server/public/assets/{page-CkvBvezS.js → page-qSH972X0.js} +1 -1
- package/payload/server/public/assets/{pieDiagram-DEJITSTG-Ckwm69PW.js → pieDiagram-DEJITSTG-B5OmNvBO.js} +1 -1
- package/payload/server/public/assets/{public-C-dTMgXu.js → public-DDsYgotk.js} +3 -3
- package/payload/server/public/assets/{quadrantDiagram-34T5L4WZ-COw3yZ1j.js → quadrantDiagram-34T5L4WZ-DTYITdNo.js} +1 -1
- package/payload/server/public/assets/{requirementDiagram-MS252O5E-DqGzM4K-.js → requirementDiagram-MS252O5E-CRZWxH06.js} +1 -1
- package/payload/server/public/assets/{sankeyDiagram-XADWPNL6-D-l1c_Pl.js → sankeyDiagram-XADWPNL6-DazRENhe.js} +1 -1
- package/payload/server/public/assets/{sequenceDiagram-FGHM5R23-BeIi0DtJ.js → sequenceDiagram-FGHM5R23-BcHTxmPy.js} +1 -1
- package/payload/server/public/assets/{stateDiagram-FHFEXIEX-C-jgegLk.js → stateDiagram-FHFEXIEX-DYU7nbqg.js} +1 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BgljVtlp.js +1 -0
- package/payload/server/public/assets/{timeline-definition-GMOUNBTQ-BGFKkYmi.js → timeline-definition-GMOUNBTQ-BKGmqkST.js} +1 -1
- package/payload/server/public/assets/{vennDiagram-DHZGUBPP-5NuIhJLS.js → vennDiagram-DHZGUBPP-BXvLPmX7.js} +1 -1
- package/payload/server/public/assets/{wardleyDiagram-NUSXRM2D-Be9ytVut.js → wardleyDiagram-NUSXRM2D-BCclUa3Z.js} +1 -1
- package/payload/server/public/assets/{xychartDiagram-5P7HB3ND-DCyHg41R.js → xychartDiagram-5P7HB3ND-C-Xp-Eoc.js} +1 -1
- package/payload/server/public/data.html +5 -5
- package/payload/server/public/graph.html +6 -6
- package/payload/server/public/index.html +8 -8
- package/payload/server/public/public.html +5 -5
- package/payload/server/server.js +1152 -2564
- package/payload/platform/scripts/check-sdk-oauth.mjs +0 -185
- package/payload/server/public/assets/channel-fxEghWew.js +0 -1
- package/payload/server/public/assets/classDiagram-6PBFFD2Q-BsWzGW0N.js +0 -1
- package/payload/server/public/assets/classDiagram-v2-HSJHXN6E-BGVa3h90.js +0 -1
- package/payload/server/public/assets/clone-Khvocke2.js +0 -1
- package/payload/server/public/assets/data-DBd-Buhp.js +0 -1
- package/payload/server/public/assets/graph-DUtVdnZ6.js +0 -1
- package/payload/server/public/assets/graph-labels-Dxfue-fP.js +0 -1
- package/payload/server/public/assets/stateDiagram-v2-QKLJ7IA2-BaMs8Znv.js +0 -1
- /package/payload/server/public/assets/{brand-CSQuxS9w.js → brand-Bm671owU.js} +0 -0
package/dist/index.js
CHANGED
|
@@ -35,8 +35,20 @@ catch (err) {
|
|
|
35
35
|
process.exit(1);
|
|
36
36
|
}
|
|
37
37
|
const INSTALL_DIR = resolve(process.env.HOME ?? "/root", BRAND.installDir);
|
|
38
|
-
const
|
|
38
|
+
const PERSIST_DIR = resolve(process.env.HOME ?? "/root", BRAND.configDir);
|
|
39
|
+
const LOG_DIR = join(PERSIST_DIR, "logs");
|
|
39
40
|
const LOG_FILE = join(LOG_DIR, `install-${new Date().toISOString().replace(/[:.]/g, "-")}.log`);
|
|
41
|
+
// Task 048 — every `claude plugin` shellout must read/write the per-brand
|
|
42
|
+
// CLAUDE_CONFIG_DIR that the systemd unit at port-resolution.ts:229,286 uses
|
|
43
|
+
// at runtime. Without this override, the installer writes marketplaces and
|
|
44
|
+
// enabledPlugins to $HOME/.claude/settings.json (user-default), and the
|
|
45
|
+
// PTY spawned by the session-manager sees an empty config dir — the
|
|
46
|
+
// onboarding skill never registers, `<onboarding-state>` resolves to
|
|
47
|
+
// "Unknown skill: onboarding", and the operator is stuck at step 6.
|
|
48
|
+
const CLAUDE_CONFIG_DIR = join(PERSIST_DIR, ".claude");
|
|
49
|
+
function claudePluginEnv() {
|
|
50
|
+
return { ...process.env, CLAUDE_CONFIG_DIR };
|
|
51
|
+
}
|
|
40
52
|
/** Known brand hostnames in the Maxy ecosystem. Each brand ships a main unit
|
|
41
53
|
* (`<hostname>.service`) and a per-brand edge unit (`<hostname>-edge.service`,
|
|
42
54
|
* Task 662). Peer-brand detection matches only these filenames — stale units,
|
|
@@ -916,7 +928,10 @@ function installClaudeCode() {
|
|
|
916
928
|
}
|
|
917
929
|
}
|
|
918
930
|
console.log(" Registering Claude plugin marketplaces...");
|
|
919
|
-
|
|
931
|
+
// Task 048 — pre-create the per-brand CLAUDE_CONFIG_DIR so the first
|
|
932
|
+
// `claude plugin marketplace add` has a directory to write into.
|
|
933
|
+
mkdirSync(CLAUDE_CONFIG_DIR, { recursive: true });
|
|
934
|
+
const marketplaceList = spawnSync("claude", ["plugin", "marketplace", "list"], { stdio: "pipe", encoding: "utf-8", env: claudePluginEnv() });
|
|
920
935
|
if (marketplaceList.stderr)
|
|
921
936
|
process.stderr.write(marketplaceList.stderr);
|
|
922
937
|
const listed = marketplaceList.stdout ?? "";
|
|
@@ -938,16 +953,16 @@ function installClaudeCode() {
|
|
|
938
953
|
];
|
|
939
954
|
for (const { slug, marketplaceName } of MARKETPLACES) {
|
|
940
955
|
if (listed.includes(marketplaceName)) {
|
|
941
|
-
logFile(`[plugin-marketplace] added ${slug} idempotent=true`);
|
|
956
|
+
logFile(`[plugin-marketplace] added ${slug} idempotent=true CLAUDE_CONFIG_DIR=${CLAUDE_CONFIG_DIR}`);
|
|
942
957
|
continue;
|
|
943
958
|
}
|
|
944
|
-
const add = spawnSync("claude", ["plugin", "marketplace", "add", slug], { stdio: "pipe", encoding: "utf-8", timeout: 60_000 });
|
|
959
|
+
const add = spawnSync("claude", ["plugin", "marketplace", "add", slug], { stdio: "pipe", encoding: "utf-8", timeout: 60_000, env: claudePluginEnv() });
|
|
945
960
|
if (add.status === 0) {
|
|
946
|
-
logFile(`[plugin-marketplace] added ${slug} idempotent=false`);
|
|
961
|
+
logFile(`[plugin-marketplace] added ${slug} idempotent=false CLAUDE_CONFIG_DIR=${CLAUDE_CONFIG_DIR}`);
|
|
947
962
|
}
|
|
948
963
|
else {
|
|
949
964
|
const stderrShort = (add.stderr ?? "").split("\n")[0]?.slice(0, 200) ?? "";
|
|
950
|
-
logFile(`[plugin-marketplace] ERROR add ${slug} exit=${add.status} stderr=${JSON.stringify(stderrShort)}`);
|
|
965
|
+
logFile(`[plugin-marketplace] ERROR add ${slug} exit=${add.status} stderr=${JSON.stringify(stderrShort)} CLAUDE_CONFIG_DIR=${CLAUDE_CONFIG_DIR}`);
|
|
951
966
|
}
|
|
952
967
|
}
|
|
953
968
|
console.log(" Configuring git to use HTTPS for GitHub (plugin install support)...");
|
|
@@ -956,10 +971,10 @@ function installClaudeCode() {
|
|
|
956
971
|
// server in claude-agent.ts (with --cdp-endpoint) is the single correct path.
|
|
957
972
|
// The plugin creates a shadow server that intermittently handles tool calls
|
|
958
973
|
// without --cdp-endpoint, causing Chrome launch failures on ARM64.
|
|
959
|
-
const pluginList = spawnSync("claude", ["plugin", "list"], { stdio: "pipe", encoding: "utf-8" });
|
|
974
|
+
const pluginList = spawnSync("claude", ["plugin", "list"], { stdio: "pipe", encoding: "utf-8", env: claudePluginEnv() });
|
|
960
975
|
if (pluginList.stdout?.includes("playwright")) {
|
|
961
976
|
console.log(" Removing Playwright plugin (replaced by programmatic CDP server)...");
|
|
962
|
-
spawnSync("claude", ["plugin", "uninstall", "playwright"], { stdio: "inherit" });
|
|
977
|
+
spawnSync("claude", ["plugin", "uninstall", "playwright"], { stdio: "inherit", env: claudePluginEnv() });
|
|
963
978
|
}
|
|
964
979
|
// Ensure @playwright/mcp and all its dependencies (including playwright-core)
|
|
965
980
|
// are cached. Wipe any stale npx cache for it first — killed installs on Pi
|
|
@@ -1922,20 +1937,23 @@ function registerLocalAndExternalPlugins() {
|
|
|
1922
1937
|
}
|
|
1923
1938
|
}
|
|
1924
1939
|
// Add each local marketplace. Idempotence via `marketplace list` grep.
|
|
1925
|
-
|
|
1940
|
+
// Task 048 — every `claude plugin …` call carries CLAUDE_CONFIG_DIR so
|
|
1941
|
+
// marketplaces register into the per-brand config dir that the runtime
|
|
1942
|
+
// session-manager unit reads from.
|
|
1943
|
+
const mkList = spawnSync("claude", ["plugin", "marketplace", "list"], { stdio: "pipe", encoding: "utf-8", env: claudePluginEnv() });
|
|
1926
1944
|
const mkListed = mkList.stdout ?? "";
|
|
1927
1945
|
for (const { name, dir } of localTrees) {
|
|
1928
1946
|
if (mkListed.includes(name)) {
|
|
1929
|
-
logFile(`[plugin-marketplace] added ${name} idempotent=true`);
|
|
1947
|
+
logFile(`[plugin-marketplace] added ${name} idempotent=true CLAUDE_CONFIG_DIR=${CLAUDE_CONFIG_DIR}`);
|
|
1930
1948
|
continue;
|
|
1931
1949
|
}
|
|
1932
|
-
const add = spawnSync("claude", ["plugin", "marketplace", "add", dir], { stdio: "pipe", encoding: "utf-8", timeout: 60_000 });
|
|
1950
|
+
const add = spawnSync("claude", ["plugin", "marketplace", "add", dir], { stdio: "pipe", encoding: "utf-8", timeout: 60_000, env: claudePluginEnv() });
|
|
1933
1951
|
if (add.status === 0) {
|
|
1934
|
-
logFile(`[plugin-marketplace] added ${name} source=${dir} idempotent=false`);
|
|
1952
|
+
logFile(`[plugin-marketplace] added ${name} source=${dir} idempotent=false CLAUDE_CONFIG_DIR=${CLAUDE_CONFIG_DIR}`);
|
|
1935
1953
|
}
|
|
1936
1954
|
else {
|
|
1937
1955
|
const stderrShort = (add.stderr ?? "").split("\n")[0]?.slice(0, 200) ?? "";
|
|
1938
|
-
logFile(`[plugin-marketplace] ERROR add ${name} source=${dir} exit=${add.status} stderr=${JSON.stringify(stderrShort)}`);
|
|
1956
|
+
logFile(`[plugin-marketplace] ERROR add ${name} source=${dir} exit=${add.status} stderr=${JSON.stringify(stderrShort)} CLAUDE_CONFIG_DIR=${CLAUDE_CONFIG_DIR}`);
|
|
1939
1957
|
}
|
|
1940
1958
|
}
|
|
1941
1959
|
// Build the desired plugin list = (every local marketplace's plugins) +
|
|
@@ -1967,14 +1985,14 @@ function registerLocalAndExternalPlugins() {
|
|
|
1967
1985
|
}
|
|
1968
1986
|
desired.push(...externals);
|
|
1969
1987
|
// Snapshot what's installed to compute the install set.
|
|
1970
|
-
const pluginList = spawnSync("claude", ["plugin", "list"], { stdio: "pipe", encoding: "utf-8" });
|
|
1988
|
+
const pluginList = spawnSync("claude", ["plugin", "list"], { stdio: "pipe", encoding: "utf-8", env: claudePluginEnv() });
|
|
1971
1989
|
const installed = parsePluginList(pluginList.stdout ?? "");
|
|
1972
1990
|
const { toInstall, alreadyInstalled } = computeInstallActions(desired, installed);
|
|
1973
1991
|
for (const ref of alreadyInstalled) {
|
|
1974
1992
|
logFile(`[plugin-install] ${ref.name}@${ref.marketplace} idempotent=true`);
|
|
1975
1993
|
}
|
|
1976
1994
|
for (const ref of toInstall) {
|
|
1977
|
-
const install = spawnSync("claude", ["plugin", "install", `${ref.name}@${ref.marketplace}`, "--scope", "user"], { stdio: "pipe", encoding: "utf-8", timeout: 120_000 });
|
|
1995
|
+
const install = spawnSync("claude", ["plugin", "install", `${ref.name}@${ref.marketplace}`, "--scope", "user"], { stdio: "pipe", encoding: "utf-8", timeout: 120_000, env: claudePluginEnv() });
|
|
1978
1996
|
if (install.status === 0) {
|
|
1979
1997
|
logFile(`[plugin-install] ${ref.name}@${ref.marketplace} idempotent=false`);
|
|
1980
1998
|
}
|
|
@@ -2000,7 +2018,7 @@ function registerLocalAndExternalPlugins() {
|
|
|
2000
2018
|
// The piped-stdin form: `echo '/<name>:configure <secret>' | claude --print`
|
|
2001
2019
|
// is the documented one-shot configure path. We do not log the secret value.
|
|
2002
2020
|
const cmd = `/${action.plugin.name}:configure ${action.secretValue}`;
|
|
2003
|
-
const configure = spawnSync("claude", ["--print", "--input-format", "text"], { input: cmd, stdio: ["pipe", "pipe", "pipe"], encoding: "utf-8", timeout: 60_000 });
|
|
2021
|
+
const configure = spawnSync("claude", ["--print", "--input-format", "text"], { input: cmd, stdio: ["pipe", "pipe", "pipe"], encoding: "utf-8", timeout: 60_000, env: claudePluginEnv() });
|
|
2004
2022
|
if (configure.status === 0) {
|
|
2005
2023
|
logFile(`[plugin-configure] ${action.plugin.name} ok env-var=${action.plugin.configureSecret}`);
|
|
2006
2024
|
}
|
|
@@ -2009,6 +2027,35 @@ function registerLocalAndExternalPlugins() {
|
|
|
2009
2027
|
logFile(`[plugin-configure] ERROR ${action.plugin.name} exit=${configure.status} stderr=${JSON.stringify(stderrShort)}`);
|
|
2010
2028
|
}
|
|
2011
2029
|
}
|
|
2030
|
+
// Task 048 — post-install assertion. The per-brand CLAUDE_CONFIG_DIR is the
|
|
2031
|
+
// only surface the runtime session-manager reads from; if any expected
|
|
2032
|
+
// marketplace is missing under .claude/plugins/marketplaces/, the operator
|
|
2033
|
+
// will hit "Unknown skill: onboarding" at step 6 of the bring-up. Fail the
|
|
2034
|
+
// install loudly here rather than ship a broken PTY.
|
|
2035
|
+
//
|
|
2036
|
+
// Expected set = 3 Anthropic marketplace names (from the constant in
|
|
2037
|
+
// installClaudeCode) + every parsed localTrees name. Hardcoding the
|
|
2038
|
+
// Anthropic names keeps the assertion independent of `MARKETPLACES` scope.
|
|
2039
|
+
const expectedMarketplaces = new Set([
|
|
2040
|
+
"claude-plugins-official",
|
|
2041
|
+
"knowledge-work-plugins",
|
|
2042
|
+
"claude-for-financial-services",
|
|
2043
|
+
...localTrees.map(t => t.name),
|
|
2044
|
+
]);
|
|
2045
|
+
const marketplacesDir = join(CLAUDE_CONFIG_DIR, "plugins", "marketplaces");
|
|
2046
|
+
let actualMarketplaces;
|
|
2047
|
+
try {
|
|
2048
|
+
actualMarketplaces = readdirSync(marketplacesDir);
|
|
2049
|
+
}
|
|
2050
|
+
catch (err) {
|
|
2051
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2052
|
+
throw new Error(`Plugin registration produced no marketplaces directory at ${marketplacesDir} — every marketplace add failed (${msg}). Check setup.log for [plugin-marketplace] ERROR lines.`);
|
|
2053
|
+
}
|
|
2054
|
+
const missing = [...expectedMarketplaces].filter(m => !actualMarketplaces.includes(m));
|
|
2055
|
+
if (missing.length > 0) {
|
|
2056
|
+
throw new Error(`Plugin registration incomplete: expected marketplaces ${JSON.stringify([...expectedMarketplaces])} but ${marketplacesDir} contains ${JSON.stringify(actualMarketplaces)}. Missing: ${JSON.stringify(missing)}. Check setup.log for [plugin-marketplace] ERROR lines.`);
|
|
2057
|
+
}
|
|
2058
|
+
logFile(`[plugin-marketplace] assertion ok marketplaces=${JSON.stringify(actualMarketplaces)} CLAUDE_CONFIG_DIR=${CLAUDE_CONFIG_DIR}`);
|
|
2012
2059
|
}
|
|
2013
2060
|
function buildPlatform() {
|
|
2014
2061
|
log("9", TOTAL, "Installing dependencies and building...");
|
package/package.json
CHANGED
|
@@ -2,29 +2,52 @@
|
|
|
2
2
|
name: admin
|
|
3
3
|
description: "Platform administration plugin. Provides system-status, public-hostname (deterministic Cloudflare public-URL resolver — single call returning the operator's canonical hostname so agents never guess property names on :CloudflareHostname nodes), brand-settings, account-manage, account-update, admin-add, admin-remove, admin-list, admin-update-pin, agent-list, agent-config-read, logs-read, plugin-read, skill-load (one-call resolve+read for SKILL.md by skill name — the canonical primitive for loading a named skill; plugin-read remains the reader for references/* and PLUGIN.md), store-skill (deterministic write counterpart to plugin-read; persists operator-authored skills as plugin files under the active account), render-component, session-reset, session-resume, file-attach, wifi, and action-approval tools (action-pending, action-approve, action-reject, action-edit) for managing the Maxy platform."
|
|
4
4
|
tools:
|
|
5
|
-
- system-status
|
|
6
|
-
|
|
7
|
-
-
|
|
8
|
-
|
|
9
|
-
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
|
|
13
|
-
-
|
|
14
|
-
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
|
|
19
|
-
-
|
|
20
|
-
|
|
21
|
-
-
|
|
22
|
-
|
|
23
|
-
-
|
|
24
|
-
|
|
25
|
-
-
|
|
26
|
-
|
|
27
|
-
-
|
|
5
|
+
- name: system-status
|
|
6
|
+
publicAllowlist: false
|
|
7
|
+
- name: public-hostname
|
|
8
|
+
publicAllowlist: false
|
|
9
|
+
- name: brand-settings
|
|
10
|
+
publicAllowlist: false
|
|
11
|
+
- name: account-manage
|
|
12
|
+
publicAllowlist: false
|
|
13
|
+
- name: account-update
|
|
14
|
+
publicAllowlist: false
|
|
15
|
+
- name: admin-add
|
|
16
|
+
publicAllowlist: false
|
|
17
|
+
- name: admin-remove
|
|
18
|
+
publicAllowlist: false
|
|
19
|
+
- name: admin-list
|
|
20
|
+
publicAllowlist: false
|
|
21
|
+
- name: admin-update-pin
|
|
22
|
+
publicAllowlist: false
|
|
23
|
+
- name: agent-list
|
|
24
|
+
publicAllowlist: false
|
|
25
|
+
- name: agent-config-read
|
|
26
|
+
publicAllowlist: false
|
|
27
|
+
- name: logs-read
|
|
28
|
+
publicAllowlist: false
|
|
29
|
+
- name: plugin-read
|
|
30
|
+
publicAllowlist: false
|
|
31
|
+
- name: skill-load
|
|
32
|
+
publicAllowlist: false
|
|
33
|
+
- name: store-skill
|
|
34
|
+
publicAllowlist: false
|
|
35
|
+
- name: render-component
|
|
36
|
+
publicAllowlist: false
|
|
37
|
+
- name: session-reset
|
|
38
|
+
publicAllowlist: false
|
|
39
|
+
- name: session-resume
|
|
40
|
+
publicAllowlist: false
|
|
41
|
+
- name: file-attach
|
|
42
|
+
publicAllowlist: false
|
|
43
|
+
- name: action-pending
|
|
44
|
+
publicAllowlist: false
|
|
45
|
+
- name: action-approve
|
|
46
|
+
publicAllowlist: false
|
|
47
|
+
- name: action-reject
|
|
48
|
+
publicAllowlist: false
|
|
49
|
+
- name: action-edit
|
|
50
|
+
publicAllowlist: false
|
|
28
51
|
hidden:
|
|
29
52
|
- remote-auth-status
|
|
30
53
|
- remote-auth-set-password
|
|
@@ -69,6 +92,10 @@ Tools are available via the `admin` MCP server.
|
|
|
69
92
|
| Manage specialists | User asks to install or remove a specialist subagent, or activate/deactivate premium plugin agents | `skills/specialist-management/SKILL.md` |
|
|
70
93
|
| Generate print-quality PDF | User asks to create a PDF document, one-pager, brochure, or any HTML intended for print/download | `skills/a4-print-documents/SKILL.md` |
|
|
71
94
|
| Plain-English explanation | User asks to explain, define, or pre-empts ("explain in plain English", "what does X mean", "define X", "I don't understand", "what is this"), or admin is about to return a reply containing a term not in the operator's prior turn | `skills/plainly/SKILL.md` |
|
|
95
|
+
| Manage admin users | User asks to add, remove, or list admins on this account, or change an admin PIN | `skills/admin-user-management/SKILL.md` |
|
|
96
|
+
| Session reset / continue / resume | User asks to clear the session, start fresh, continue the last session, or pick up where they left off | `skills/session-management/SKILL.md` |
|
|
97
|
+
| Commitment follow-through | A `<commitment-detected>` block appears in the prompt; the owner has just made a commitment that needs a backing mechanism | `skills/commitment-followthrough/SKILL.md` |
|
|
98
|
+
| Show or download a file | User asks to view, attach, or download a file or document, or the current turn produces a document the owner needs to review | `skills/file-presentation/SKILL.md` |
|
|
72
99
|
|
|
73
100
|
## Hooks
|
|
74
101
|
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: admin-user-management
|
|
3
|
+
description: "Add, remove, list admins on this account, and update an admin PIN. Triggers when the owner asks to invite another admin, remove an admin, see who has admin access, or change a PIN."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Admin user management
|
|
7
|
+
|
|
8
|
+
This skill manages who has admin access to this account. It wraps four MCP tools and carries the discipline that keeps the three identity stores in lockstep. The owner (or any current admin) can manage admins; roles are labels only, with no capability differences enforced.
|
|
9
|
+
|
|
10
|
+
## The four tools
|
|
11
|
+
|
|
12
|
+
| Tool | Purpose |
|
|
13
|
+
|---|---|
|
|
14
|
+
| `admin-add` | Add a new admin. Requires a name. PIN is optional: omit it and a unique 4-digit PIN is generated. PIN must be at least 4 digits and unique across all users on the device. |
|
|
15
|
+
| `admin-remove` | Remove an admin by `userId` (find IDs via `admin-list`). The last admin on the account cannot be removed. The user's device-level entry is retained so they can still administer other accounts. |
|
|
16
|
+
| `admin-list` | List all admins on this account with names and roles. |
|
|
17
|
+
| `admin-update-pin` | Update an admin's PIN. Defaults to the calling admin if no `userId` is given. PIN must be at least 4 digits and unique across all users on the device. |
|
|
18
|
+
|
|
19
|
+
## The three-store invariant
|
|
20
|
+
|
|
21
|
+
Admin identity lives in three places that must stay in lockstep:
|
|
22
|
+
|
|
23
|
+
1. `account.json` `admins[]`: account-level role record.
|
|
24
|
+
2. `users.json`: device-level PIN authentication. This is the source of truth at login.
|
|
25
|
+
3. The Neo4j graph: `:AdminUser` + `:Person` + `OWNS` + `ADMIN_OF` edges. Display and graph identity.
|
|
26
|
+
|
|
27
|
+
`admin-add` writes all three. `admin-update-pin` writes `users.json` only (the other stores carry no PIN). If any leg fails, the tool returns `is_error: true` and `server.log` carries a `[admin-auth-store] action=… userId=… result=fail store=…` line naming which leg failed and what was already written. When you see that line, tell the owner the record is half-written and may need manual reconciliation.
|
|
28
|
+
|
|
29
|
+
## Never write `account.json` directly
|
|
30
|
+
|
|
31
|
+
All account-level mutations (`tier`, `outputStyle`, `thinkingView`, `effort`, `enabledPlugins`, `admins[]`, agent settings) go through the dedicated MCP tools: `account-update`, `plugin-toggle-enabled`, `admin-add`, `admin-remove`. The pre-tool-use hook denies direct `Edit` or `Write` on `account.json` server-side; this rule is the explanation for the denial. `tier` and `purchasedPlugins` derive from a Rubytech-signed entitlement payload on commercial installs, so a hand-edit is silently void.
|
|
32
|
+
|
|
33
|
+
## `admin-add` retries: re-pass any user-stated PIN
|
|
34
|
+
|
|
35
|
+
If `admin-add` returns an error (tier cap reached, PIN collision) and the owner resolves the blocker (upgrade tier, remove an existing admin), the retried `admin-add` MUST re-pass the PIN the owner originally stated as the `pin` parameter. Omitting `pin` on the retry auto-generates a different 4-digit PIN, silently substituting what the owner asked for. The resulting `admin-update-pin` correction loop is exactly the failure mode this rule exists to prevent.
|
|
36
|
+
|
|
37
|
+
## Standard flow
|
|
38
|
+
|
|
39
|
+
1. Read the request. Identify which of the four operations applies.
|
|
40
|
+
2. For `admin-add`, gather the name. The PIN is optional; if the owner stated one, use it; otherwise let the tool generate one. For `admin-remove`, call `admin-list` first if the owner did not give a `userId`.
|
|
41
|
+
3. Call the tool.
|
|
42
|
+
4. If the tool succeeds, confirm the result in plain English. Include the PIN in the reply for `admin-add` so the owner can share it with the new admin.
|
|
43
|
+
5. If the tool returns an error, surface the failure and the `[admin-auth-store]` line from `server.log` if present. Do not retry the same call; resolve the underlying blocker first.
|
|
44
|
+
|
|
45
|
+
## What this skill does not do
|
|
46
|
+
|
|
47
|
+
It does not manage tier upgrades. It does not change account-level settings. It does not manage public agents or plugins. Each of those has its own skill.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: commitment-followthrough
|
|
3
|
+
description: "Handles the platform-detected commitment signal: offers to track or automate the commitment, waits for owner confirmation, then picks the right backing mechanism (scheduled event, task, or workflow). Loads when the system prompt contains a `<commitment-detected>` block."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Commitment follow-through
|
|
7
|
+
|
|
8
|
+
This skill activates when the platform identifies that the owner has just made a commitment: something they said they would do. The skill's job is to offer the right backing mechanism, wait for the owner's confirmation, then create it. Without a backing mechanism, a commitment is a broken promise; with one, the agent can hold the owner to their word.
|
|
9
|
+
|
|
10
|
+
## The trigger
|
|
11
|
+
|
|
12
|
+
A `<commitment-detected>` block appears in the system prompt. The block names what the platform classifier extracted: the commitment text, the suggested mechanism (scheduled event, task, or workflow), and any time, recipient, or topic the classifier inferred.
|
|
13
|
+
|
|
14
|
+
## How to offer
|
|
15
|
+
|
|
16
|
+
Surface a brief, conversational offer. Name the commitment, name the suggested mechanism, and ask the owner to confirm, modify, or dismiss. One or two sentences. Not a form. Not a list of options. Examples:
|
|
17
|
+
|
|
18
|
+
- "I'll set a reminder for Tuesday morning to chase the Acme invoice. Confirm?"
|
|
19
|
+
- "Want me to create a task for the photo brief so it doesn't slip?"
|
|
20
|
+
- "Shall I schedule the weekly check-in with Daniel on Mondays at 9?"
|
|
21
|
+
|
|
22
|
+
## Never act without confirmation
|
|
23
|
+
|
|
24
|
+
The owner must say "yes" or give specifics before any tool call. If they dismiss ("no thanks", "I'll handle it"), acknowledge briefly and continue with whatever they were discussing. Do not re-offer for the same commitment.
|
|
25
|
+
|
|
26
|
+
If they modify ("make it next Monday instead"), incorporate the changes and confirm before creating.
|
|
27
|
+
|
|
28
|
+
## The two-rule discipline
|
|
29
|
+
|
|
30
|
+
This skill is the operator's side of the two-rule contract on commitments.
|
|
31
|
+
|
|
32
|
+
1. **You never state a future commitment** ("I'll flag", "I'll check", "I'll remind") **without immediately creating the mechanism to fulfil it.** A commitment without a backing mechanism is a broken promise.
|
|
33
|
+
2. **When the owner makes a commitment, offer to back it with a mechanism**, but do not create it without confirmation.
|
|
34
|
+
|
|
35
|
+
Rule 1 is yours; rule 2 is this skill's job.
|
|
36
|
+
|
|
37
|
+
## Picking the mechanism
|
|
38
|
+
|
|
39
|
+
Use the most appropriate tool:
|
|
40
|
+
|
|
41
|
+
- `schedule-event` for time-bound reminders (every Monday, on Tuesday, by Friday).
|
|
42
|
+
- `task-create` for open-ended obligations (chase X, finish Y, prepare Z).
|
|
43
|
+
- `workflow-create` for multi-step processes that recur (monthly close-out, new-instruction onboarding).
|
|
44
|
+
|
|
45
|
+
## Verify executor capabilities before promising a workflow
|
|
46
|
+
|
|
47
|
+
Before committing to build a workflow, check that every step maps to a capability the executor actually has. Tool steps need the named plugin and tool to exist. Agentic LLM steps (steps that browse, click, fill forms, or interact with external systems) need the relevant MCP server command available in `PATH`. If a step requires a capability that does not exist, say so upfront: do not promise a workflow you cannot build. The owner can either narrow the scope or wait for the capability to ship.
|
|
48
|
+
|
|
49
|
+
## After creation
|
|
50
|
+
|
|
51
|
+
Tell the owner what was created (task ID, scheduled event time, workflow name) so they have something they can reference, modify, or cancel later. Then resume the conversation.
|
|
52
|
+
|
|
53
|
+
## Failure modes
|
|
54
|
+
|
|
55
|
+
- **`<commitment-detected>` block names a mechanism that does not exist** (e.g. `workflow-create` while workflows are not enabled on this account). Surface the gap and offer the next-best mechanism.
|
|
56
|
+
- **Owner approves but the create tool fails.** Surface the error literally. Do not silently substitute a different mechanism.
|
|
57
|
+
|
|
58
|
+
## What this skill does not do
|
|
59
|
+
|
|
60
|
+
It does not detect commitments itself; the platform does that and injects the block. It does not act on the owner's behalf without explicit confirmation. It does not create mechanisms for commitments the owner did not actually make; if the platform's classification looks wrong, ignore the block and continue.
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: file-presentation
|
|
3
|
+
description: "Render a file or document inline for the owner to view, edit, and download. Triggers when the owner asks to see, attach, or download a file, when content is generated that the owner needs to review (summary, report, draft), or when a downloadable artefact is the right output."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# File presentation
|
|
7
|
+
|
|
8
|
+
This skill makes a file visible and downloadable inside the chat. It is the only sanctioned path for delivering file content to the owner. Synthesised content (a summary, a report, a draft) follows the same path: render via `document-editor` so the owner can review and download.
|
|
9
|
+
|
|
10
|
+
## The trigger
|
|
11
|
+
|
|
12
|
+
The owner asks to view, review, attach, or download a file or a document, or the current turn produces a document that the owner needs to see. Example phrasings:
|
|
13
|
+
|
|
14
|
+
- "show me the file"
|
|
15
|
+
- "attach the report"
|
|
16
|
+
- "let me download that"
|
|
17
|
+
- "preview the document"
|
|
18
|
+
- "send me the brochure"
|
|
19
|
+
- "save that as a markdown file"
|
|
20
|
+
|
|
21
|
+
## How to render
|
|
22
|
+
|
|
23
|
+
Call `render-component` with:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
name: "document-editor"
|
|
27
|
+
data: {
|
|
28
|
+
title: "<owner-facing title>",
|
|
29
|
+
content: "<the file content as markdown>"
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
The component gives the owner a render-review-edit-download flow: they see the content inline, can edit it in place, and can download it as a `.md` file directly from the component. Do not use `memory-write`, `memory-ingest`, or other tools to deliver file content to the owner; those tools have different purposes and skipping the render-review-download flow takes control away from the owner.
|
|
34
|
+
|
|
35
|
+
## Character sanitisation: the silent-failure rule
|
|
36
|
+
|
|
37
|
+
The document-editor's markdown parser fails silently on these typographical characters:
|
|
38
|
+
|
|
39
|
+
| Character | Unicode | Replace with |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| em-dash | U+2014 | hyphen with spaces |
|
|
42
|
+
| en-dash | U+2013 | hyphen with spaces |
|
|
43
|
+
| left curly double quote | U+201C | straight double quote |
|
|
44
|
+
| right curly double quote | U+201D | straight double quote |
|
|
45
|
+
| left curly single quote | U+2018 | straight single quote |
|
|
46
|
+
| right curly single quote | U+2019 | straight single quote |
|
|
47
|
+
| horizontal ellipsis | U+2026 | three periods |
|
|
48
|
+
|
|
49
|
+
Strip and replace these characters in the `content` field before the `render-component` call. The owner does not see a partial render or a warning; the content just silently breaks at the offending character. Currency symbols (£, €), accented characters, and other Unicode are unaffected: use them normally.
|
|
50
|
+
|
|
51
|
+
## When the file is a binary
|
|
52
|
+
|
|
53
|
+
For PDF, image, audio, or any binary deliverable, use `file-attach` plus `render-component` with `name: file-attachment` and pass the returned path. The document-editor component is for editable markdown text only.
|
|
54
|
+
|
|
55
|
+
## For static-site delivery
|
|
56
|
+
|
|
57
|
+
When the owner has uploaded a `.zip` containing HTML and assets and wants it hosted, this skill is not the right path. Delegate to `content-producer` on turn one; the specialist owns the `unzip-attachment` then `publish-site` chain.
|
|
58
|
+
|
|
59
|
+
## Failure modes
|
|
60
|
+
|
|
61
|
+
- **Content is too large for the component** (typically over 50,000 characters of markdown). Surface the size and offer to split into sections, save as an attachment, or render only the first section with a follow-up for the rest.
|
|
62
|
+
- **`render-component` returns an error.** Surface the error literally. Do not paste the content into chat as a fallback; the owner asked for the render-review-download flow, not a wall of text.
|
|
63
|
+
- **The content contains characters the parser rejects after the sanitisation pass** (rare; usually a non-printable control character). Strip the offending characters and surface a one-line warning naming the position.
|
|
64
|
+
|
|
65
|
+
## What this skill does not do
|
|
66
|
+
|
|
67
|
+
It does not write the content to the graph. It does not save the content to disk. The component handles the download path; the owner downloads what they edited in the component.
|