@rubytech/create-realagent-code 0.1.23 → 0.1.24

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.
Files changed (90) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/plugins/admin/PLUGIN.md +4 -0
  3. package/payload/platform/plugins/admin/skills/admin-user-management/SKILL.md +47 -0
  4. package/payload/platform/plugins/admin/skills/commitment-followthrough/SKILL.md +60 -0
  5. package/payload/platform/plugins/admin/skills/file-presentation/SKILL.md +67 -0
  6. package/payload/platform/plugins/admin/skills/session-management/SKILL.md +62 -0
  7. package/payload/platform/plugins/deep-research/.claude-plugin/plugin.json +1 -1
  8. package/payload/platform/plugins/deep-research/PLUGIN.md +7 -1
  9. package/payload/platform/plugins/deep-research/recipes/README.md +36 -0
  10. package/payload/platform/plugins/deep-research/skills/academic-verify/SKILL.md +75 -0
  11. package/payload/platform/plugins/deep-research/skills/book-mirror/SKILL.md +68 -0
  12. package/payload/platform/plugins/deep-research/skills/data-research/SKILL.md +108 -0
  13. package/payload/platform/plugins/deep-research/skills/strategic-reading/SKILL.md +69 -0
  14. package/payload/platform/plugins/docs/references/deployment.md +3 -2
  15. package/payload/platform/plugins/email/mcp/dist/lib/imap.d.ts +1 -1
  16. package/payload/platform/plugins/email/mcp/dist/scripts/email-fetch.d.ts +7 -2
  17. package/payload/platform/plugins/email/mcp/dist/scripts/email-fetch.d.ts.map +1 -1
  18. package/payload/platform/plugins/email/mcp/dist/scripts/email-fetch.js +7 -2
  19. package/payload/platform/plugins/email/mcp/dist/scripts/email-fetch.js.map +1 -1
  20. package/payload/platform/plugins/linkedin-import/skills/linkedin-import/SKILL.md +2 -0
  21. package/payload/platform/plugins/memory/PLUGIN.md +6 -0
  22. package/payload/platform/plugins/memory/skills/archive-crawler/SKILL.md +67 -0
  23. package/payload/platform/plugins/memory/skills/concept-synthesis/SKILL.md +80 -0
  24. package/payload/platform/plugins/memory/skills/conversation-archive/SKILL.md +2 -0
  25. package/payload/platform/plugins/memory/skills/document-ingest/SKILL.md +2 -0
  26. package/payload/platform/plugins/scheduling/PLUGIN.md +3 -0
  27. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.d.ts +7 -3
  28. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.d.ts.map +1 -1
  29. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js +7 -3
  30. package/payload/platform/plugins/scheduling/mcp/dist/scripts/check-due-events.js.map +1 -1
  31. package/payload/platform/plugins/scheduling/skills/briefing/SKILL.md +75 -0
  32. package/payload/platform/plugins/scheduling/skills/daily-prep/SKILL.md +61 -0
  33. package/payload/platform/services/claude-session-manager/dist/http-server.d.ts.map +1 -1
  34. package/payload/platform/services/claude-session-manager/dist/http-server.js +14 -1
  35. package/payload/platform/services/claude-session-manager/dist/http-server.js.map +1 -1
  36. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts +14 -0
  37. package/payload/platform/services/claude-session-manager/dist/pty-spawner.d.ts.map +1 -1
  38. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js +9 -2
  39. package/payload/platform/services/claude-session-manager/dist/pty-spawner.js.map +1 -1
  40. package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts +25 -1
  41. package/payload/platform/services/claude-session-manager/dist/system-prompt.d.ts.map +1 -1
  42. package/payload/platform/services/claude-session-manager/dist/system-prompt.js +54 -3
  43. package/payload/platform/services/claude-session-manager/dist/system-prompt.js.map +1 -1
  44. package/payload/platform/templates/agents/admin/IDENTITY.md +38 -284
  45. package/payload/platform/templates/agents/admin/SOUL.md +4 -4
  46. package/payload/platform/templates/specialists/agents/content-producer.md +24 -69
  47. package/payload/platform/templates/specialists/agents/database-operator.md +49 -155
  48. package/payload/platform/templates/specialists/agents/personal-assistant.md +27 -177
  49. package/payload/platform/templates/specialists/agents/project-manager.md +29 -96
  50. package/payload/platform/templates/specialists/agents/research-assistant.md +36 -78
  51. package/payload/premium-plugins/real-agency/agents/compliance.md +14 -0
  52. package/payload/premium-plugins/real-agency/agents/negotiator.md +22 -0
  53. package/payload/premium-plugins/real-agency/agents/valuer.md +16 -0
  54. package/payload/premium-plugins/real-agency/plugins/estate-business/.claude-plugin/plugin.json +1 -1
  55. package/payload/premium-plugins/real-agency/plugins/estate-business/PLUGIN.md +29 -13
  56. package/payload/premium-plugins/real-agency/plugins/estate-business/skills/commission-calculator/SKILL.md +40 -0
  57. package/payload/premium-plugins/real-agency/plugins/estate-business/skills/month-end-close/SKILL.md +69 -0
  58. package/payload/premium-plugins/real-agency/plugins/estate-business/skills/payment-batch-stager/SKILL.md +42 -0
  59. package/payload/premium-plugins/real-agency/plugins/estate-business/skills/period-reconciler/SKILL.md +42 -0
  60. package/payload/premium-plugins/real-agency/plugins/estate-sales/.claude-plugin/plugin.json +1 -1
  61. package/payload/premium-plugins/real-agency/plugins/estate-sales/PLUGIN.md +27 -13
  62. package/payload/premium-plugins/real-agency/plugins/estate-sales/skills/chase-progression/SKILL.md +107 -0
  63. package/payload/premium-plugins/real-agency/plugins/estate-sales/skills/risk-scorer/SKILL.md +42 -0
  64. package/payload/premium-plugins/real-agency/plugins/leads/.claude-plugin/plugin.json +1 -1
  65. package/payload/premium-plugins/real-agency/plugins/leads/PLUGIN.md +24 -10
  66. package/payload/premium-plugins/real-agency/plugins/leads/skills/chain-progression-tracker/SKILL.md +51 -0
  67. package/payload/premium-plugins/real-agency/plugins/leads/skills/diary-builder/SKILL.md +38 -0
  68. package/payload/premium-plugins/real-agency/plugins/leads/skills/enquiry-triage/SKILL.md +36 -0
  69. package/payload/premium-plugins/real-agency/plugins/leads/skills/morning-round/SKILL.md +72 -0
  70. package/payload/premium-plugins/real-agency/plugins/listings/.claude-plugin/plugin.json +1 -1
  71. package/payload/premium-plugins/real-agency/plugins/listings/PLUGIN.md +43 -12
  72. package/payload/premium-plugins/real-agency/plugins/listings/skills/comparable-finder/SKILL.md +52 -0
  73. package/payload/premium-plugins/real-agency/plugins/listings/skills/epc-checker/SKILL.md +38 -0
  74. package/payload/premium-plugins/real-agency/plugins/listings/skills/listing-copy-writer/SKILL.md +55 -0
  75. package/payload/premium-plugins/real-agency/plugins/listings/skills/local-market-stats/SKILL.md +33 -0
  76. package/payload/premium-plugins/real-agency/plugins/listings/skills/new-instruction/SKILL.md +78 -0
  77. package/payload/premium-plugins/real-agency/plugins/listings/skills/particulars-builder/SKILL.md +48 -0
  78. package/payload/premium-plugins/real-agency/plugins/listings/skills/portal-launch-scheduler/SKILL.md +49 -0
  79. package/payload/premium-plugins/real-agency/plugins/listings/skills/pricing-scenario-builder/SKILL.md +35 -0
  80. package/payload/premium-plugins/real-agency/plugins/listings/skills/supplier-booker/SKILL.md +39 -0
  81. package/payload/premium-plugins/real-agency/plugins/listings/skills/talk-track-composer/SKILL.md +36 -0
  82. package/payload/premium-plugins/real-agency/plugins/listings/skills/terms-of-business-drafter/SKILL.md +54 -0
  83. package/payload/premium-plugins/real-agency/plugins/listings/skills/valuation-prep/SKILL.md +69 -0
  84. package/payload/premium-plugins/real-agency/plugins/loop/PLUGIN.md +20 -0
  85. package/payload/premium-plugins/real-agency/plugins/loop/skills/compliance-flag-checker/SKILL.md +53 -0
  86. package/payload/premium-plugins/real-agency/plugins/loop/skills/priority-ranker/SKILL.md +40 -0
  87. package/payload/premium-plugins/real-agency/plugins/loop/skills/tone-matched-drafter/SKILL.md +53 -0
  88. package/payload/premium-plugins/real-agency/plugins/loop/skills/variance-narrator/SKILL.md +50 -0
  89. package/payload/premium-plugins/real-agency/plugins/loop/skills/vendor-research/SKILL.md +54 -0
  90. package/payload/server/server.js +73 -162
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubytech/create-realagent-code",
3
- "version": "0.1.23",
3
+ "version": "0.1.24",
4
4
  "description": "Install Real Agent — Built for agents. By agents.",
5
5
  "bin": {
6
6
  "create-realagent-code": "./dist/index.js"
@@ -69,6 +69,10 @@ Tools are available via the `admin` MCP server.
69
69
  | Manage specialists | User asks to install or remove a specialist subagent, or activate/deactivate premium plugin agents | `skills/specialist-management/SKILL.md` |
70
70
  | 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
71
  | 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` |
72
+ | 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` |
73
+ | 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` |
74
+ | 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` |
75
+ | 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
76
 
73
77
  ## Hooks
74
78
 
@@ -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.
@@ -0,0 +1,62 @@
1
+ ---
2
+ name: session-management
3
+ description: "Reset the current session, list past sessions, continue a previous session, or read the session memory. Triggers when the owner says 'start a new session', 'continue the last session', 'pick up where we left off', 'what were we doing last time', or asks about session state."
4
+ ---
5
+
6
+ # Session management
7
+
8
+ This skill wraps the session tools and carries the discipline that keeps long-running work coherent across sessions. The platform handles a lot of session machinery automatically: this skill is for the moments where the owner names a session intent directly.
9
+
10
+ ## The tools
11
+
12
+ | Tool | Purpose |
13
+ |---|---|
14
+ | `session-reset` | Clear the current session and return to idle. |
15
+ | `session-list` | List recent sessions with metadata. |
16
+ | `session-resume` | Resume a specific session by `conversationId`. |
17
+ | `session-compact-status` | Read the compaction state of the current session: how much context has been compacted, what remains. |
18
+
19
+ ## Resetting the session
20
+
21
+ When the owner asks to start a new session, clear the conversation, or reset, call `session-reset`. Do not ask for confirmation. After the tool call, say nothing further; the UI clears and returns to idle.
22
+
23
+ **Before suggesting a reset (e.g. after a plugin activation, when context has drifted), persist every actionable finding from the current conversation to its durable store first.** Compaction saves a session summary, but summaries are lossy: decisions, working state, and unfinished threads must be captured explicitly before the context window is cleared. Write open tasks via `task-create`, profile updates via `profile-update`, and any other graph state. Then tell the owner what will carry into the new session (the summary and the open tasks via `<previous-context>`) and suggest the reset.
24
+
25
+ ## Continuing a previous session
26
+
27
+ When the owner asks to continue, pick up, resume, or carry on:
28
+
29
+ - **Most recent session.** Call `session-list` with `limit: 1`, then `session-resume` with the returned `conversationId`.
30
+ - **Specific session by name or topic.** Call `session-list` with a higher limit, identify the matching session, then `session-resume`.
31
+ - **No sessions found.** Tell the owner. Do not improvise by reading `<previous-context>`, searching memory, or re-researching prior work.
32
+
33
+ ## Trusting the session summary
34
+
35
+ When `<previous-context>` is present in the system prompt, the platform has injected a recent session summary and the open tasks at session end. The platform rejects stale summaries older than 48 hours; when the summary is present, it is recent and trustworthy.
36
+
37
+ - Trust the summary for state orientation. Do not re-verify claims it already describes.
38
+ - Pick up from the state the summary describes. Redundant `memory-search` or other tool calls for information already in the summary waste the owner's time.
39
+ - Use the summary to greet the owner with awareness of prior work and outstanding tasks.
40
+
41
+ When `<previous-context>` is absent, Neo4j was unreachable or no prior context exists: proceed normally, using tool calls to establish state.
42
+
43
+ ## The recovery context block
44
+
45
+ A `<recovery-context>` block on the user-message side appears whenever the previous turn was aborted by a stall recovery. It is the authoritative description of what failed, what was incomplete, and what to do now.
46
+
47
+ - The **resume variant** announces that a synthetic tool result for the in-flight `tool_use_id` was just pushed above this message. Read it for the completed-work summary, then resume by re-issuing the next pending step concretely.
48
+ - The **handoff variant** carries an LLM-generated continuation summary describing what was happening before the abort.
49
+
50
+ In both shapes, the next operator message means resume the work. Never treat it as empty, never ask "what would you like to do?", never wait for direction. Do not re-research the blocker. Do not call `session-list` to figure out what was happening.
51
+
52
+ ## The api-wait-ping liveness gate
53
+
54
+ The platform suppresses a heartbeat-driven stall fire while the SDK API request is still alive, bounded by a 600-second cap. When the cap forces an abort, the synthetic tool result names "API request stayed alive past the 600 s cap without producing tokens". This is upstream API latency, not specialist failure. Do not infer that the specialist's approach was wrong from a long stall; many stalls are not the subagent's fault.
55
+
56
+ ## In managed context mode
57
+
58
+ Conversation history is provided inside `<conversation-history>` tags. Use `session-compact-status` to retrieve older archived context if needed.
59
+
60
+ ## What this skill does not do
61
+
62
+ It does not edit summaries, delete past sessions, or modify the recovery-context block. These are platform-owned mechanics.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deep-research",
3
- "description": "Structured multi-source research workflow query decomposition, search strategy, source evaluation, synthesis, and citation formatting. Uses Claude Code's native WebSearch and WebFetch tools.",
3
+ "description": "Structured multi-source research workflow: query decomposition, search strategy, source evaluation, synthesis, citation formatting, plus four named knowledge-worker skills (book-mirror, strategic-reading, academic-verify, data-research). Uses Claude Code's native WebSearch and WebFetch tools.",
4
4
  "version": "0.1.0",
5
5
  "author": {
6
6
  "name": "Rubytech LLC"
@@ -1,7 +1,13 @@
1
1
  ---
2
2
  name: deep-research
3
- description: "Structured multi-source research workflow query decomposition, search strategy, source evaluation, synthesis, and citation formatting. Uses Claude Code's native WebSearch and WebFetch tools."
3
+ description: "Structured multi-source research workflow: query decomposition, search strategy, source evaluation, synthesis, citation formatting, plus four named knowledge-worker skills (book-mirror, strategic-reading, academic-verify, data-research). Uses Claude Code's native WebSearch and WebFetch tools."
4
4
  tools: []
5
+ skills:
6
+ - skills/deep-research/SKILL.md
7
+ - skills/book-mirror/SKILL.md
8
+ - skills/strategic-reading/SKILL.md
9
+ - skills/academic-verify/SKILL.md
10
+ - skills/data-research/SKILL.md
5
11
  always: false
6
12
  embed: false
7
13
  ---
@@ -0,0 +1,36 @@
1
+ # Recipes
2
+
3
+ Recipes for the `data-research` skill. Each recipe is a YAML file that declares the field-by-field shape of an extraction, the source kinds it accepts, the validations to apply, and the graph target.
4
+
5
+ A recipe is a contract. The owner reads the recipe and knows what `data-research` will write to the graph before it runs.
6
+
7
+ ## Recipe shape
8
+
9
+ ```yaml
10
+ name: <recipe-name>
11
+ description: One-line description of what this recipe extracts.
12
+ source_kinds:
13
+ - email-thread # one or more of: email-thread, web-page, pdf, text-file, form-submission
14
+ fields:
15
+ - name: <field name>
16
+ type: string | number | date | boolean
17
+ required: true | false
18
+ validation: # optional
19
+ min: <number>
20
+ max: <number>
21
+ pattern: <regex>
22
+ enum: [a, b, c]
23
+ graph_target:
24
+ label: <Node label that must exist in the live Neo4j ontology>
25
+ identity: # property names that together uniquely identify a row
26
+ - <field name>
27
+ - <field name>
28
+ relationships: # optional
29
+ - type: <RELATIONSHIP_TYPE>
30
+ target_label: <Node label>
31
+ target_match: <field name> # the field whose value resolves the target node via memory-search
32
+ ```
33
+
34
+ ## Updating a recipe
35
+
36
+ Recipes are part of the plugin and are committed alongside the plugin. To add or change a recipe, the owner names the extraction in conversation, the operator drafts the YAML, the owner reviews it, and the file is saved here. The `data-research` skill loads recipes by name at run-time; it does not author or modify them inline.
@@ -0,0 +1,75 @@
1
+ ---
2
+ name: academic-verify
3
+ description: "Traces an academic or scientific claim through the publication chain to a primary source, checks for retraction, and returns one of four verdicts: verified, contradicted, retracted, or cannot be confirmed. Triggers when the owner says 'verify this study', 'is this paper real', 'check the citation', 'is X actually peer-reviewed'."
4
+ ---
5
+
6
+ # Academic verify
7
+
8
+ This skill is for claims that arrive as "studies show", "research suggests", or a named paper title. It traces the claim to the actual paper, the actual journal, and the actual conclusion of the source. It never says "verified" without a primary source URL.
9
+
10
+ ## When to run
11
+
12
+ Run when the owner asks whether an academic or scientific claim is real. The trigger phrases are above. Also run when the owner repeats a strong claim attributed to "research" or "a study" and asks to check.
13
+
14
+ ## Inputs
15
+
16
+ `claim` (the statement to verify) and optionally `source` (the citation the owner has, if any: a paper title, DOI, author and year, journal name, or a URL).
17
+
18
+ If `claim` is missing, refuse. If `source` is missing, the skill will try to find the source from the claim wording.
19
+
20
+ ## Method
21
+
22
+ 1. **Find the originating paper.** If the owner provided a DOI or URL, fetch it. If they provided a paper title, search via `WebSearch` for the title in quotes, prioritising the journal's own site or a known repository (Google Scholar, PubMed, arXiv, OpenAlex). If they provided only the claim wording, search for the claim's distinctive phrasing in quotes.
23
+ 2. **Confirm the chain.** Pull these four facts from the source page:
24
+ - Paper title, authors, journal name, year.
25
+ - DOI (or arXiv ID, or PubMed ID).
26
+ - Peer-review status (peer-reviewed journal, preprint, working paper, conference abstract).
27
+ - The paper's own abstract or conclusion as written.
28
+ 3. **Check for retraction.** Search Retraction Watch and the journal's own page for a retraction notice. Capture the date and reason if found.
29
+ 4. **Cross-reference the claim against the paper.** Read the paper's abstract or conclusion. Compare the owner's claim wording to what the paper actually says. Decide one of four verdicts:
30
+ - **Verified.** The paper exists, is peer-reviewed (or clearly named as preprint), is not retracted, and the claim wording matches what the paper concludes.
31
+ - **Contradicted by source.** The paper exists but the claim wording overstates, reverses, or generalises beyond what the paper actually concludes.
32
+ - **Retracted.** The paper has been retracted. Name the date and reason.
33
+ - **Cannot be confirmed.** A search could not find a primary source, or the primary source is behind a paywall and only a secondary summary is available.
34
+ 5. **Return the verdict with the chain.** Verdict in the first sentence. Below it, the four facts from step 2. If retracted, the retraction details. If cannot-be-confirmed, name what was searched and where it stopped.
35
+
36
+ ## Output format
37
+
38
+ ```
39
+ **Verdict.** <verified | contradicted by source | retracted | cannot be confirmed>
40
+
41
+ **Source.**
42
+ - Title: <paper title>
43
+ - Authors: <list>
44
+ - Journal: <journal name>, <year>
45
+ - DOI: <DOI or other identifier>
46
+ - Peer-review status: <peer-reviewed | preprint | working paper | conference abstract>
47
+ - Primary source URL: <URL>
48
+
49
+ **The paper concludes.** <one to three sentences, paraphrased tightly or quoted verbatim if wording matters>
50
+
51
+ **The claim says.** <the owner's claim, verbatim>
52
+
53
+ **Match.** <one paragraph on whether the claim faithfully represents the paper's conclusion. If contradicted, name the specific divergence.>
54
+
55
+ (If retracted:)
56
+ **Retraction.** <date, reason, retraction notice URL>
57
+ ```
58
+
59
+ ## Discipline
60
+
61
+ - **Never say "verified" without a primary source URL in the output.** A claim is verified against the actual paper, not against a secondary summary.
62
+ - **Paywalled abstracts.** If the abstract is behind a paywall, the verdict is "cannot be confirmed". Surface the paywall, do not infer from training memory what the paper says.
63
+ - **Preprints.** A preprint is not the same as peer-reviewed. Surface the distinction explicitly; the owner may not want to act on a preprint result.
64
+ - **Press release vs paper.** Press releases routinely overstate the paper's conclusions. If the chain goes paper → press release → claim, the verdict is usually "contradicted by source"; name the divergence.
65
+ - **Author affiliation conflicts.** Surface known conflicts of interest from the paper's disclosure if present. Do not pretend they affect the verdict; they affect the owner's interpretation of the verdict.
66
+
67
+ ## Failure modes
68
+
69
+ - **Search returns no candidates.** Verdict is "cannot be confirmed". Report the search terms tried.
70
+ - **Multiple candidate papers.** Surface the top three and ask the owner to confirm which is the source.
71
+ - **Search returns a retraction watch entry but no journal page.** Use the retraction watch entry as the primary source; the verdict is "retracted".
72
+
73
+ ## What this skill does not do
74
+
75
+ It does not evaluate the paper's methodology or replicate the analysis. It checks whether the claim matches the source, not whether the source is correct. A flawed paper that is correctly cited returns "verified"; the owner is the one who decides whether the paper itself is sound.
@@ -0,0 +1,68 @@
1
+ ---
2
+ name: book-mirror
3
+ description: "Reads a book the owner provides (PDF, ePub, web link, or text), walks it chapter by chapter, and produces a personalised mirror that maps each chapter's claims to the owner's known context. Triggers when the owner says 'mirror this book', 'two-column analysis', 'how does this book apply to me', 'personalise this book against my business'."
4
+ ---
5
+
6
+ # Book mirror
7
+
8
+ This skill turns a book into a usable document by walking the chapters one at a time and asking, for each: "what does this say, and how does it apply to this specific owner". The output is a personalised pack the owner can read once and act on. It is grounded in the graph; the right-hand column is always specific to what the graph already knows about the owner.
9
+
10
+ ## When to run
11
+
12
+ Run when the owner asks for a book to be applied to their situation. The trigger phrases are above. Do not run when the owner asks for a simple summary; a summary is what `deep-research` produces, and that is the right skill for that intent.
13
+
14
+ ## Inputs
15
+
16
+ | Input | Meaning |
17
+ |---|---|
18
+ | `source` | The book. A path to a file in `$ACCOUNT_DIR`, a web URL, or pasted text. |
19
+ | `anchor` | A node in the graph the book is being mirrored against. Usually the `LocalBusiness` node; can also be a named `Project` or `Goal`. |
20
+
21
+ If the anchor is missing, ask for it in one sentence: "Mirror against the business, or a specific project?".
22
+
23
+ ## Method
24
+
25
+ 1. **Confirm the source.** If `source` is a file path, read it. If it is a URL, fetch it. If it is pasted text, work from the text directly. Reject sources that cannot be read; do not paraphrase a book the skill has not seen.
26
+ 2. **Identify the chapters.** Look for chapter headings in the text. If the book has none, segment by first-level headings or by every 2000 to 4000 words. Tell the owner the chapter count before starting.
27
+ 3. **For each chapter, build the two columns.**
28
+ - **Left.** A two-to-three-sentence summary of the chapter's actual claim. Quote verbatim only when the wording matters; otherwise paraphrase tightly.
29
+ - **Right.** A two-to-three-sentence note on how the claim applies to the anchor, grounded in graph specifics. Pull from `memory-search` against the anchor: the owner's business stage, recent obstacles, named projects, the LocalBusiness `businessType` schema. Name specific entities. Do not write "this applies to your business in general": that is jargon for "I have nothing specific to say".
30
+ - **Actions.** End each chapter with one or two concrete steps the owner could take this week. Use the imperative ("Call the photographer to confirm the brief for 14 Garth Road" rather than "Consider arranging photography").
31
+ 4. **Save the result.** Compose the whole pack as one `:KnowledgeDocument` with `:Section:Chapter` children per chapter. Link the document to the anchor node via `MIRRORS` (or `REFERENCES` if `MIRRORS` is not in the live ontology: call `maxy-graph-get_neo4j_schema` first).
32
+
33
+ ## Output format
34
+
35
+ ```
36
+ # Mirror: <book title> against <anchor name>
37
+
38
+ ## Chapter 1: <chapter title>
39
+
40
+ **The chapter.** <2-3 sentence summary>
41
+
42
+ **For <anchor>.** <2-3 sentence application, grounded in graph specifics>
43
+
44
+ **This week.**
45
+ - <one concrete action>
46
+ - <one concrete action>
47
+
48
+ ---
49
+
50
+ ## Chapter 2: ...
51
+ ```
52
+
53
+ Render the pack via `render-component name: document-editor` for owner review before saving. The owner can edit any chapter inline before the save. Once approved, write to the graph.
54
+
55
+ ## Length discipline
56
+
57
+ Each chapter must fit on one screen (roughly 30 lines). If a chapter's claims need more, split the application across two or three chapter mirrors; do not pad. The whole pack should be readable in one sitting; a 20-chapter book becomes a 60-page pack only if every chapter genuinely earns its application.
58
+
59
+ ## Failure modes
60
+
61
+ - **No chapters detectable and no headings.** Ask the owner to confirm the chunk size or to provide a chapter list.
62
+ - **Anchor has thin graph context** (LocalBusiness with no recent activity, Project with no Tasks). Surface the gap: "the graph has limited context for <anchor>. The right column will be general where it should be specific. Continue?". Wait for confirmation.
63
+ - **`memory-search` returns no useful results for the anchor**. Stop. The book cannot be mirrored against an empty anchor; tell the owner and recommend running `business-profile` or naming a different anchor.
64
+ - **Source fetch fails.** Surface the error literally. Do not summarise from training memory.
65
+
66
+ ## What this skill does not do
67
+
68
+ It does not summarise a book without an anchor; that is generic content, which `deep-research` can produce. It does not produce a study guide, a literature review, or a comparative essay. It produces one specific output: a personalised application of one book to one named entity in the graph.
@@ -0,0 +1,108 @@
1
+ ---
2
+ name: data-research
3
+ description: "Recipe-driven structured-data extraction. Takes a named recipe and a set of sources (emails, reports, web pages, forms, PDFs) and writes typed entities to the graph per the recipe's schema. Triggers when the owner says 'extract X from these emails', 'track investor updates', 'pull donation amounts', 'build a table of Y from these documents'."
4
+ ---
5
+
6
+ # Data research
7
+
8
+ This skill turns unstructured-looking sources (emails, reports, forms, web pages) into structured graph entities. The transformation is always recipe-driven: a named YAML recipe declares what fields to extract, what validations to apply, and what graph nodes to write. The skill runs a named recipe; it never invents a schema on the fly.
9
+
10
+ **Default parent.** Every recipe declares its hierarchy parent via `graph_target.parent` — either `Project` (the run-time recipe argument names which Project elementId to attach to) or `LocalBusiness` (the account root, for cross-project recipes like investor-updates). The skill refuses to run a recipe whose `parent` field is missing or whose named Project does not exist. Per-row writes attach to that parent via the canonical containment edge; the recipe's `relationships:` block describes cross-hierarchy edges (e.g. `ROUND_FOR → Organization`) which are written separately and do not substitute for the parent.
11
+
12
+ ## When to run
13
+
14
+ Run when the owner wants the same extraction repeated across many sources. The trigger phrases are above. Do not run for one-off extractions; a one-off is what `document-ingest` does.
15
+
16
+ ## Inputs
17
+
18
+ | Input | Meaning |
19
+ |---|---|
20
+ | `recipe` | The name of an existing recipe at `plugins/deep-research/recipes/<name>.yaml`. |
21
+ | `sources` | One or more source paths or URLs. Email thread paths, PDF paths, web URLs, or a folder. |
22
+ | `parent` | The Project elementId (or `LocalBusiness` for cross-project recipes) the writes anchor to. Required when the recipe's `parent` field is `Project`; ignored when the recipe's parent is `LocalBusiness` (the account root resolves automatically). |
23
+
24
+ If `recipe` does not match any file in the recipes directory, refuse. List the available recipe names. Do not invent a recipe.
25
+
26
+ If the owner asks for an extraction shape that no existing recipe covers, the answer is "no recipe exists for that yet. Want me to draft one?". The skill never extracts data without a recipe; that is the point of the recipe layer.
27
+
28
+ ## Recipe shape
29
+
30
+ A recipe is a YAML file with this shape:
31
+
32
+ ```yaml
33
+ name: investor-updates
34
+ description: One-line description of what this recipe extracts.
35
+ source_kinds:
36
+ - email-thread
37
+ - web-page
38
+ - pdf
39
+ fields:
40
+ - name: company_name
41
+ type: string
42
+ required: true
43
+ - name: round
44
+ type: string
45
+ required: false
46
+ - name: amount_gbp
47
+ type: number
48
+ required: false
49
+ validation:
50
+ min: 0
51
+ - name: date_announced
52
+ type: date
53
+ required: true
54
+ graph_target:
55
+ label: FundingRound
56
+ parent: LocalBusiness # or `Project` — names the hierarchy anchor for every row
57
+ identity:
58
+ - company_name
59
+ - date_announced
60
+ relationships:
61
+ - type: ROUND_FOR
62
+ target_label: Organization
63
+ target_match: company_name
64
+ ```
65
+
66
+ ## Method
67
+
68
+ 1. **Load and validate the recipe.** Read the recipe file. Check that every field declared has a `name` and `type`. Check that `graph_target.label` is a label in the live ontology (`maxy-graph-get_neo4j_schema`). Check that `graph_target.parent` is present and resolves (Project elementId supplied at call time, or `LocalBusiness` resolved from the account root). If anything fails, refuse and report the recipe's defect.
69
+ 2. **Iterate sources.** For each source: classify by kind against `source_kinds`. Skip sources whose kind is not in the recipe's allowed list, list them in the report.
70
+ 3. **Extract per source.** Fetch the source. Use Haiku-driven classification (`memory-classify` with a recipe-specific prompt) to extract each declared field. Apply each field's validation. Reject rows that fail required-field checks; capture them in a rejected list.
71
+ 4. **Write to the graph.** For each accepted row, `memory-write` a node with the declared label and the extracted properties. Attach it to the resolved hierarchy parent via the canonical containment edge. Stamp `createdByAgent: data-research`, `createdByRecipe: <recipe name>`, `sourceDocumentId: <source>`. Write the declared cross-hierarchy relationships, resolving target nodes via `memory-search` on the named match property.
72
+ 5. **Report.** Return one line per source (accepted count, rejected count) and one summary line: total rows written, total rejected, total relationships created.
73
+
74
+ ## Output format
75
+
76
+ ```
77
+ **Recipe.** <name>
78
+ **Sources.** <N> processed.
79
+
80
+ | Source | Accepted | Rejected | Reason |
81
+ |---|---|---|---|
82
+ | <source path or URL> | 3 | 1 | "amount_gbp negative" |
83
+ | ... | | | |
84
+
85
+ **Total.** 12 rows written as :<Label>, 9 relationships created via <RelType>.
86
+ **Rejections.** 3 rows rejected (full list below).
87
+ ```
88
+
89
+ ## Why recipes
90
+
91
+ A recipe is a contract. The owner reads the recipe and knows what will be written. The recipe is version-controlled and auditable. Without recipes, the skill would extract whatever the LLM thinks is interesting, which means the graph schema drifts with every run and the owner cannot trust what arrives. The recipe layer is the difference between a controlled pipeline and a junk shop.
92
+
93
+ ## Failure modes
94
+
95
+ - **Recipe file is malformed.** Surface the YAML error literally and refuse.
96
+ - **Recipe declares a `graph_target.label` not in the ontology.** Refuse. Tell the owner the label is missing and recommend either adjusting the recipe or extending the ontology.
97
+ - **Recipe's `graph_target.parent` is missing or unresolvable.** Refuse. The hierarchy parent is mandatory; without it, every row would land as an orphan.
98
+ - **No sources match the recipe's allowed kinds.** Refuse. List what the recipe accepts.
99
+ - **Target-match relationship cannot resolve** (the recipe wants `ROUND_FOR -> Organization` and the named company is not in the graph). Capture in the rejected list with the reason "target organisation not found"; do not create a placeholder organisation.
100
+ - **Embedding service unavailable mid-batch.** Stop. Report which sources completed and which did not.
101
+
102
+ ## Where recipes live
103
+
104
+ Recipes live at `platform/plugins/deep-research/recipes/<name>.yaml`. The directory is part of the plugin and ships with the platform. To author a new recipe, the owner names the extraction they want; the skill can scaffold the YAML and the owner reviews and saves it. Recipe authoring is a separate path; this skill consumes recipes, it does not write them inline.
105
+
106
+ ## What this skill does not do
107
+
108
+ It does not run free-form extractions. It does not write to the graph without an approved recipe. It does not modify recipes during a run; if the recipe needs changing, the run aborts, the owner edits the recipe, and the run is re-issued.