@rubytech/create-maxy-lite 0.1.5 → 0.1.6

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 (32) hide show
  1. package/index.mjs +15 -14
  2. package/lib/orchestrate.mjs +2 -2
  3. package/lib/paths.mjs +35 -0
  4. package/package.json +1 -1
  5. package/payload/package.json +2 -1
  6. package/payload/skills/README.md +26 -0
  7. package/payload/skills/admin/datetime/SKILL.md +147 -0
  8. package/payload/skills/admin/session-management/SKILL.md +39 -0
  9. package/payload/skills/admin/upgrade/SKILL.md +32 -0
  10. package/payload/skills/browser/SKILL.md +60 -0
  11. package/payload/skills/browser/scripts/cdp.mjs +134 -0
  12. package/payload/skills/browser/scripts/pdf.mjs +38 -0
  13. package/payload/skills/browser/scripts/render.mjs +43 -0
  14. package/payload/skills/browser/scripts/screenshot.mjs +52 -0
  15. package/payload/skills/business-assistant/SKILL.md +110 -0
  16. package/payload/skills/deep-research/SKILL.md +70 -0
  17. package/payload/skills/deep-research/references/citation-styles.md +52 -0
  18. package/payload/skills/deep-research/references/research-modes.md +22 -0
  19. package/payload/skills/deep-research/references/search-strategy.md +24 -0
  20. package/payload/skills/docs/SKILL.md +23 -0
  21. package/payload/skills/docs/references/capability-map.md +25 -0
  22. package/payload/skills/docs/references/getting-started.md +29 -0
  23. package/payload/skills/docs/references/vault-model.md +40 -0
  24. package/payload/skills/email-composition/SKILL.md +107 -0
  25. package/payload/skills/replicate/SKILL.md +63 -0
  26. package/payload/skills/replicate/scripts/replicate-image.mjs +131 -0
  27. package/payload/skills/url-get/SKILL.md +48 -0
  28. package/payload/skills/url-get/scripts/url-get.mjs +93 -0
  29. package/payload/webchat/inject-line.mjs +11 -0
  30. package/payload/webchat/package.json +2 -1
  31. package/payload/webchat/request-handler.mjs +62 -0
  32. package/payload/webchat/server.mjs +31 -31
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env node
2
+ // browser render — render a JavaScript-heavy page in the device Chromium and
3
+ // print its fully rendered DOM text and HTML. Use for pages url-get returns
4
+ // empty. One-shot: creates a target, navigates, reads the DOM, closes.
5
+ import { cdpPort, createTarget, closeTarget, openSession, navigate } from "./cdp.mjs";
6
+
7
+ const url = process.argv[2];
8
+ if (!url) {
9
+ console.error(`[browser] error=usage detail="usage: render.mjs <url>"`);
10
+ process.exit(1);
11
+ }
12
+
13
+ const port = cdpPort();
14
+ const target = await createTarget(port);
15
+ let session;
16
+ try {
17
+ session = await openSession(target);
18
+ await navigate(session, url);
19
+ const htmlRes = await session.cmd("Runtime.evaluate", {
20
+ expression: "document.documentElement.outerHTML",
21
+ returnByValue: true,
22
+ });
23
+ const textRes = await session.cmd("Runtime.evaluate", {
24
+ expression: "document.body && document.body.innerText || ''",
25
+ returnByValue: true,
26
+ });
27
+ const html = typeof htmlRes?.result?.value === "string" ? htmlRes.result.value : "";
28
+ const text = typeof textRes?.result?.value === "string" ? textRes.result.value : "";
29
+ console.error(`[browser-render] url=${url} domBytes=${Buffer.byteLength(html)}`);
30
+ process.stdout.write(
31
+ `--- VISIBLE TEXT ---\n${text.slice(0, 200_000)}\n\n--- RENDERED HTML ---\n${html.slice(0, 800_000)}\n`,
32
+ );
33
+ } catch (err) {
34
+ console.error(`[browser] error=render detail=${JSON.stringify(String(err?.message ?? err))}`);
35
+ process.exitCode = 1;
36
+ } finally {
37
+ try {
38
+ session?.ws?.close();
39
+ } catch {
40
+ /* already closed */
41
+ }
42
+ await closeTarget(port, target.id);
43
+ }
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env node
2
+ // browser screenshot — capture a PNG of a page to a file. One-shot: creates a
3
+ // target, navigates, captures, closes. Optional viewport width/height before
4
+ // capture to control the rendered size.
5
+ import { writeFileSync } from "node:fs";
6
+ import { cdpPort, createTarget, closeTarget, openSession, navigate } from "./cdp.mjs";
7
+
8
+ const url = process.argv[2];
9
+ const out = process.argv[3];
10
+ const args = Object.fromEntries(
11
+ process.argv.slice(4).map((a) => {
12
+ const m = a.match(/^--([^=]+)=(.*)$/);
13
+ return m ? [m[1], m[2]] : [a, true];
14
+ }),
15
+ );
16
+ if (!url || !out) {
17
+ console.error(`[browser] error=usage detail="usage: screenshot.mjs <url> <out.png> [--width=] [--height=]"`);
18
+ process.exit(1);
19
+ }
20
+
21
+ const port = cdpPort();
22
+ const target = await createTarget(port);
23
+ let session;
24
+ try {
25
+ session = await openSession(target);
26
+ // Set the viewport before navigating so responsive layout and any
27
+ // viewport-dependent resources load at the requested size, not the default.
28
+ if (args.width && args.height) {
29
+ await session.cmd("Emulation.setDeviceMetricsOverride", {
30
+ width: Number(args.width),
31
+ height: Number(args.height),
32
+ deviceScaleFactor: 1,
33
+ mobile: false,
34
+ });
35
+ }
36
+ await navigate(session, url);
37
+ const res = await session.cmd("Page.captureScreenshot", { format: "png" });
38
+ const buf = Buffer.from(res.data, "base64");
39
+ writeFileSync(out, buf);
40
+ console.error(`[browser-screenshot] url=${url} out=${out} bytes=${buf.length}`);
41
+ process.stdout.write(out + "\n");
42
+ } catch (err) {
43
+ console.error(`[browser] error=screenshot detail=${JSON.stringify(String(err?.message ?? err))}`);
44
+ process.exitCode = 1;
45
+ } finally {
46
+ try {
47
+ session?.ws?.close();
48
+ } catch {
49
+ /* already closed */
50
+ }
51
+ await closeTarget(port, target.id);
52
+ }
@@ -0,0 +1,110 @@
1
+ ---
2
+ name: business-assistant
3
+ description: Handle a customer enquiry end to end for a small business: triage it, find or create the customer, book the appointment, send the confirmation, format a quote, and record every step in the vault. Use when a customer message comes in, when the user asks to book someone in, chase a quote, or see what is outstanding, or when running the day to day customer side of a small business. Composes the contacts, scheduling, and email skills; it adds no tools of its own.
4
+ ---
5
+
6
+ # Business assistant
7
+
8
+ You run the customer side of a small business so the owner can get on with the work: enquiries, bookings, quotes, and the admin around them. You are the owner's assistant, not the owner. Be professional and warm, keep messages short, and always be honest that you are an AI when asked. Never impersonate the owner, never pretend to be human, and never commit to a price without the owner's approval.
9
+
10
+ This skill does not introduce new tools. It is a workflow over skills that already exist: `contacts` for the customer record, `scheduling` for the appointment, `email-composition` for correspondence, and `work`/`memory` for follow ups and context. Every record it writes is checked by the validator. The entity field lists are in [`SCHEMA.md`](../../schema/SCHEMA.md).
11
+
12
+ ## Read the vault first
13
+
14
+ Before answering a customer, read what the vault already knows. Grep `people/` for the sender, read their Person file and any notes linked to them, and check `calendar/` for anything booked. Answer from what you find, not from assumption. After anything meaningful happens, write it back, so the next message starts from a fuller picture.
15
+
16
+ ## Triage
17
+
18
+ Sort every incoming message into one of four levels and act accordingly.
19
+
20
+ - **Red, urgent.** A safety risk or escalating damage (a leak, no heat for a vulnerable person in the cold). Give immediate safety advice and tell the owner now, in this conversation, before waiting on anything else.
21
+ - **Amber, same or next day.** Something is broken but not dangerous. Gather the details needed to book or to quote, then handle it or surface it to the owner.
22
+ - **Green, routine.** Planned work, a maintenance job, a quote request, a booking. Gather details and book the next suitable slot.
23
+ - **Quick.** Confirming an appointment, chasing a quote, changing a booking, saying thanks. Answer straight away with minimal back and forth.
24
+
25
+ ## The enquiry workflow
26
+
27
+ A new enquiry runs through five steps. Each one writes a vault record, and each write is validated before you move on.
28
+
29
+ 1. **Find or create the customer.** Look the sender up in `people/` (the `contacts` skill). If they are not there and this is a real enquiry, create the Person file first, with the name and whatever contact details you have. Everything else links to this file, so it has to exist before the links will resolve.
30
+ 2. **Record the enquiry.** Write a Note in `activities/` capturing what they want, linked to the customer with `about` and, if there is a job, to a Project with `project`. The Note body is the detail (what they asked for, when they are free, anything notable).
31
+ 3. **Book the slot.** When the enquiry needs an appointment, create the Event with the `scheduling` skill: an Event file in `calendar/` with the customer as an attendee. The vault Event is the source of truth; `scheduling` handles the calendar sync.
32
+ 4. **Send the confirmation.** Confirm the booking to the customer with the `email-composition` skill, or as a reply on whatever channel they used. The send is recorded as a vault Email linked to the customer, exactly as `email-composition` describes.
33
+ 5. **Leave a clean record.** After the steps above, the vault holds the customer, the enquiry Note, the booked Event, and the confirmation Email, all linked and all passing the validator. Run `maxy-lite-validate "$HOME/maxy"` and fix any named field until it exits 0. An enquiry that leaves no conformant record set is the failure this workflow exists to prevent.
34
+
35
+ A worked example: the customer, the job, the enquiry, and the booked slot, the four files passing the validator together (the confirmation Email is the one the `email-composition` skill records). Every link resolves within the set, so the project links need the Project file present:
36
+
37
+ ```yaml
38
+ # people/Jane Doe.md
39
+ ---
40
+ type: person
41
+ name: Jane Doe
42
+ emails:
43
+ - jane@acme.example
44
+ ---
45
+
46
+ # projects/Bathroom refit.md
47
+ ---
48
+ type: project
49
+ name: Bathroom refit
50
+ area: work
51
+ ---
52
+
53
+ # activities/Enquiry - Jane.md
54
+ ---
55
+ type: note
56
+ title: Enquiry - bathroom refit
57
+ about: "[[Jane Doe]]"
58
+ project: "[[Bathroom refit]]"
59
+ area: work
60
+ ---
61
+ Jane enquired about a full bathroom refit. Wants a survey then a quote. Mornings.
62
+
63
+ # calendar/Bathroom survey - Jane.md
64
+ ---
65
+ type: event
66
+ summary: Bathroom survey - Jane Doe
67
+ start: 2026-06-25T09:30:00
68
+ end: 2026-06-25T10:00:00
69
+ location: 42 Oak Lane, Stansted
70
+ attendees:
71
+ - "[[Jane Doe]]"
72
+ project: "[[Bathroom refit]]"
73
+ status: CONFIRMED
74
+ area: work
75
+ ---
76
+ On-site survey ahead of quoting the refit.
77
+ ```
78
+
79
+ ## Quotes
80
+
81
+ A quote is a number, and a number needs the owner's approval before it goes to a customer. Gather the scope, work out what you would quote, and put it to the owner. Once they approve, send the figure to the customer with the `email-composition` skill, and record what was quoted as a Note in `activities/`, linked to the customer with `about`, so the quote is part of the record. Do not generate an invoice or a signed document here; producing those is a separate skill.
82
+
83
+ ## Channels are reply only
84
+
85
+ When a customer reaches you on a channel, reply on that channel; never send a cold first message to someone who has not contacted you. Cold outreach is not this skill's job and it puts the business's accounts at risk.
86
+
87
+ ## Escalating to the owner
88
+
89
+ In a small business there is one owner, and that owner is the person you are talking to in this session. Escalating means surfacing the matter to them here, clearly and briefly, not routing it anywhere. There is no broadcast across channels.
90
+
91
+ Always escalate, rather than deciding alone:
92
+
93
+ - A price or any money decision the owner has not already approved.
94
+ - A complaint or an unhappy customer.
95
+ - A request outside the normal services, or a suspicious one.
96
+ - An emergency that needs the owner's judgement.
97
+ - A customer asking to speak to the owner directly. Never block that. Take their number and a good time, capture the context, and hand it over.
98
+
99
+ Keep the escalation short. The owner is busy and reading on a phone.
100
+
101
+ ## Out of scope
102
+
103
+ This skill stays inside the enquiry, booking, and quote workflow. It does not do:
104
+
105
+ - **Sales pipeline objects** (deals, stages, a funnel). The store does not carry them yet; that is a separate, deferred part of the data model.
106
+ - **Invoices, payments, and signed documents.** Invoice and payment records and document generation belong to other skills, not here.
107
+ - **Industry specific scripts and overlays, voice or phone menus.** Out of scope.
108
+ - **The public booking site and its captured leads.** Standing up a booking page and pulling its submissions into the vault is the `calendar-site` skill's job; this skill consumes the Events that land, it does not build the site.
109
+ - **New tools.** Everything here is the contacts, scheduling, and email skills plus vault files.
110
+ </content>
@@ -0,0 +1,70 @@
1
+ ---
2
+ name: deep-research
3
+ description: >
4
+ Use when the owner asks to research a topic, find current information, compare
5
+ options, review literature, fact-check a claim, or answer any question that
6
+ benefits from live web sources. Trigger phrases: "research", "find out",
7
+ "what's the latest on", "compare X and Y", "who is", "look into", "fact-check",
8
+ "deep dive", "what do we know about", "literature review", or any question
9
+ where stored knowledge may be stale or insufficient. Runs over native web
10
+ search and the url-get skill, and saves the result as a vault Note.
11
+ ---
12
+
13
+ # deep-research
14
+
15
+ Answer questions using live web sources. Search, read, extract, and cite. Do not guess. Synthesise across sources and present the result with full attribution, then save it to the vault.
16
+
17
+ This runs over the native `WebSearch` and `WebFetch` tools and the `[[url-get]]` skill for full-page fetches. No external API key is needed.
18
+
19
+ ## Config
20
+
21
+ ```yaml
22
+ citation_style: "inline" # inline | footnotes | cards | minimal
23
+ max_sources: 8 # sources to synthesise per query (4-12 recommended)
24
+ search_depth: "standard" # standard (3-5 searches) | deep (6-12 searches)
25
+ show_confidence: true # append a High / Medium / Low confidence note
26
+ follow_up_questions: true # suggest 3 follow-up questions
27
+ ```
28
+
29
+ ## Workflow
30
+
31
+ **Phase 1, Decompose.** Before searching, break the question into: core question, temporal dimension (breaking / recent / evergreen), perspective breadth, and 2-5 sub-questions. State the decomposition in 1-3 lines, then proceed without asking permission. Read `references/research-modes.md` and select the research mode.
32
+
33
+ **Phase 2, Search.** Map sub-questions to targeted search queries via `WebSearch`. Read `references/search-strategy.md` for query crafting and source evaluation.
34
+
35
+ **Phase 3, Fetch and extract.** For each source, fetch the full page (`WebFetch`, or `[[url-get]]` for verbatim markdown), extract only what is relevant to the sub-question, and note publication dates. See `references/search-strategy.md` for the source-quality hierarchy and staleness rules.
36
+
37
+ **Phase 4, Synthesise.** Write a structured response that directly answers the original question. Read `references/citation-styles.md` and apply the style from `config.citation_style`.
38
+
39
+ **Phase 5, Confidence.** If `show_confidence: true`, append a confidence assessment. See `references/citation-styles.md` for the High / Medium / Low criteria.
40
+
41
+ **Phase 6, Follow-ups.** If `follow_up_questions: true`, suggest 3 genuinely useful next questions. See `references/citation-styles.md`.
42
+
43
+ **Phase 7, Persist.** Save the report to the vault as a Note so it is kept and searchable. Write one markdown file under the vault with frontmatter and the report in the body:
44
+
45
+ ```markdown
46
+ ---
47
+ type: note
48
+ title: <the research question>
49
+ area: <an Areas value, if the topic fits one>
50
+ ---
51
+
52
+ <the synthesised report, with citations inline>
53
+ ```
54
+
55
+ `type` and `title` are required; `area` is optional and must be a value from the schema's Areas vocabulary. The report prose lives in the body, not in frontmatter. After writing, validate the vault and confirm it passes:
56
+
57
+ ```bash
58
+ node ~/.maxy-lite/validator/cli.mjs ~/.maxy-lite/vault
59
+ ```
60
+
61
+ Expect `invalid=0` and exit 0. If the Note fails validation, fix the frontmatter and re-run before telling the owner it is saved.
62
+
63
+ ## Hard rules
64
+
65
+ 1. **Never fabricate citations.** If you cannot find a source for a claim, say so explicitly.
66
+ 2. **Never quote more than 15 words verbatim** from any single source.
67
+ 3. **One direct quote per source maximum.** Paraphrase everything else.
68
+ 4. **Do not recite stored knowledge as search results.** If relying on prior knowledge, say "(from prior knowledge, not verified live)".
69
+ 5. **Stale is worse than honest.** If you cannot find current information, state the most recent date you found and invite the owner to check for updates.
70
+ 6. **No padding.** Every sentence must carry information. No filler, no generic caveats, no restated conclusions.
@@ -0,0 +1,52 @@
1
+ # Citation Styles, Confidence, and Follow-ups
2
+
3
+ ## Citation Styles (Phase 4)
4
+
5
+ Apply the style set in `config.citation_style`:
6
+
7
+ ### inline (default)
8
+ > The company raised $120M in Series B funding [1], led by Andreessen Horowitz [2].
9
+ > Sources: [1] techcrunch.com/... [2] a16z.com/...
10
+
11
+ ### footnotes
12
+ > Prose with no inline markers. Full source list at end:
13
+ > ---
14
+ > **Sources**
15
+ > 1. Title. domain.com/path (Date if known)
16
+ > 2. Title. domain.com/path
17
+
18
+ ### cards
19
+ > Each source rendered as a mini card:
20
+ > ┌─────────────────────────────────────────┐
21
+ > │ [1] Title of article │
22
+ > │ Source: domain.com · Date: YYYY-MM-DD │
23
+ > │ Relevant finding: one-line summary │
24
+ > └─────────────────────────────────────────┘
25
+
26
+ ### minimal
27
+ > The company raised $120M (techcrunch.com/...), led by a16z (a16z.com/...).
28
+
29
+ ## Confidence Assessment (Phase 5)
30
+
31
+ If `show_confidence: true`, append a brief confidence assessment after the main answer:
32
+
33
+ **Confidence: High / Medium / Low**
34
+ - High: multiple independent sources agree, sources are recent and authoritative
35
+ - Medium: sources partially agree, or primary sources are thin
36
+ - Low: limited sources, conflicting information, or significant recency gaps
37
+
38
+ Always flag explicitly if:
39
+ - A key sub-question could not be answered from available sources
40
+ - Important information may exist behind paywalls or login walls
41
+ - The topic is moving fast and this answer may be stale within days/weeks
42
+
43
+ ## Follow-up Questions (Phase 6)
44
+
45
+ If `follow_up_questions: true`, end with:
46
+
47
+ **You might also want to ask:**
48
+ 1. [Specific follow-up question 1]
49
+ 2. [Specific follow-up question 2]
50
+ 3. [Specific follow-up question 3]
51
+
52
+ Make these genuinely useful: the next natural step in the research, not generic variations of the original question.
@@ -0,0 +1,22 @@
1
+ # Research Modes
2
+
3
+ Adjust behaviour based on query type. Select the appropriate mode after Phase 1 decomposition.
4
+
5
+ ## General Research / Fact-finding
6
+
7
+ - 3–5 sources is usually sufficient
8
+ - Prioritise recency and source authority
9
+ - Lead with the direct answer, then supporting evidence
10
+
11
+ ## Competitive / Market Intelligence
12
+
13
+ - Always cover: (a) the company's own claims, (b) independent analyst or press coverage, (c) user sentiment (G2, Reddit, Trustpilot where relevant)
14
+ - Structure output as: Overview, Key differentiators, Weaknesses/risks, Pricing (if findable), Verdict
15
+ - Flag if pricing is not publicly listed
16
+
17
+ ## Academic / Deep Literature Review
18
+
19
+ - Prioritise peer-reviewed sources, preprints (arXiv, bioRxiv), and institutional reports
20
+ - Note study size, methodology, and date for each source
21
+ - Distinguish between consensus findings and contested/emerging claims
22
+ - Use deep search depth. Do not stop at 3 sources for academic queries
@@ -0,0 +1,24 @@
1
+ # Search Strategy and Source Evaluation
2
+
3
+ ## Query Crafting (Phase 2)
4
+
5
+ Map each sub-question to one or more targeted search queries:
6
+
7
+ - Keep queries short (3–6 words). Specific nouns beat vague phrases.
8
+ - Vary query framing: try the direct question, a "site:domain" form, and a comparison form where relevant.
9
+ - For competitive intelligence: always search the target company directly AND search for independent reviews/comparisons.
10
+ - For literature/academic queries: search for primary papers, then for secondary summaries.
11
+ - For fast-changing topics (pricing, funding, personnel): append the current year to queries.
12
+ - Never repeat the same query twice. If a search returns poor results, rephrase. Do not retry identical terms.
13
+
14
+ ## Source Fetching and Extraction (Phase 3)
15
+
16
+ For each source returned:
17
+
18
+ 1. Fetch the full page content where possible, not just the snippet.
19
+ 2. Extract only what is relevant to the sub-question that drove this search.
20
+ 3. Note the publication date if visible.
21
+ 4. Flag sources older than 18 months as `[possibly outdated]`.
22
+ 5. Prefer: official docs, primary research, reputable press. Deprioritise: forums, SEO farms, undated pages.
23
+
24
+ Do not quote large blocks verbatim. Paraphrase and extract the key claim or data point.
@@ -0,0 +1,23 @@
1
+ ---
2
+ name: docs
3
+ description: >
4
+ Reference documentation for how maxy-lite works, loaded on demand. Use when the
5
+ owner asks how the assistant works, what it can do, where their files are, how
6
+ to get started, or for help. Trigger phrases: "how does this work", "what can
7
+ you do", "where are my files", "help", "getting started", "explain maxy",
8
+ "how is my data stored".
9
+ ---
10
+
11
+ # docs
12
+
13
+ A small set of reference documents describing how maxy-lite works. Do not load them all. Read the one that answers the owner's question with the `Read` tool, then answer from it.
14
+
15
+ ## References
16
+
17
+ - **`references/getting-started.md`** Read this for a new owner, or for "how do I use this", "what can you do" at a high level, "help", or general orientation. Plain-language, owner-facing.
18
+ - **`references/capability-map.md`** Read this for "what can you do" in detail, "what tools do you have", "can you do X", or to understand which capabilities exist and in what form.
19
+ - **`references/vault-model.md`** Read this for "where is my data", "how is it stored", "what is the vault", anything about file layout, entity types, areas, links, or the validator. The technical model of the store.
20
+
21
+ ## Boundaries
22
+
23
+ These references describe lite's own reality: a single assistant, a file-native vault, on one device. They are not the platform documentation for the larger graph-backed product. For the exact field-by-field schema, point to `schema/SCHEMA.md` rather than restating it.
@@ -0,0 +1,25 @@
1
+ # What maxy-lite can do
2
+
3
+ maxy-lite is a single assistant that organises a person's files and helps with everyday tasks, all on their own device. Its capabilities take one of a few forms, chosen to keep the device light.
4
+
5
+ ## The forms
6
+
7
+ - **Native file operations.** Reading, writing, and editing vault files directly. This covers all store work: contacts, notes, tasks, projects, events, and the filed documents and assets. No tool or process is involved.
8
+ - **Skills with small scripts.** A skill is instructions the assistant reads; some come with a small script run on demand. This is the default for anything that fetches a page, calls a service, or runs a one-off job. Skills are files, so they add no running process.
9
+ - **Official connectors.** Off-the-shelf remote services configured rather than built: Google (Gmail, Calendar, Drive) and Cloudflare.
10
+ - **Channel servers.** The one kind of long-lived process: the messaging channels (Telegram, WhatsApp) that must listen for incoming messages.
11
+
12
+ ## What it can do today
13
+
14
+ - **Store work** over the vault: keep contacts, notes, tasks, projects, a calendar, and filed documents, all as plain files.
15
+ - **Fetch a web page** faithfully as markdown (the `url-get` skill).
16
+ - **Research a topic** across live web sources and save a cited report to the vault (the `deep-research` skill).
17
+ - **Generate an image** from a prompt (the `replicate` skill).
18
+ - **Drive the browser** for the things plain HTTP cannot do: render a JavaScript page, turn HTML into a PDF, take a screenshot (the `browser` skill).
19
+ - **Answer time and date questions** deterministically (the `datetime` skill).
20
+ - **Manage sessions** start a new one, resume a past one, recall what a past one was about (the `session-management` skill).
21
+ - **Upgrade itself** by re-running the installer (the `upgrade` skill).
22
+
23
+ ## What it deliberately does not have
24
+
25
+ No graph database, no per-account separation, no specialist sub-agents, no public-facing agents. One assistant, one file tree, one device. Capabilities that exist only to serve those platform features are not part of lite.
@@ -0,0 +1,29 @@
1
+ # Getting started with maxy-lite
2
+
3
+ A short orientation for a new owner.
4
+
5
+ ## What it is
6
+
7
+ maxy-lite is a personal assistant that runs entirely on your own device. It keeps your information as ordinary files and helps you with everyday tasks. One assistant does everything; there is nothing to log into and nothing leaves your phone unless you ask it to.
8
+
9
+ ## Where your files live
10
+
11
+ Everything is stored as plain markdown files in your vault (by default `~/.maxy-lite/vault`). Each file is one thing: a contact, a note, a task, an event, a bill. You can open and edit the same files in Obsidian on your phone, so you are never locked out of your own data.
12
+
13
+ ## How to use it
14
+
15
+ Just ask in plain language. The assistant picks the right tool for the job.
16
+
17
+ - **Keep things organised:** "add Jane Smith to my contacts", "make a note about the boiler service", "remind me to renew the car insurance", "what's on my calendar next week".
18
+ - **Research:** "what's the latest on X", "compare these two options", "look into this and save me a summary". It searches the web, reads the sources, and saves a cited note to your vault.
19
+ - **Read a web page:** give it a link and ask what it says.
20
+ - **Make an image:** "generate a logo for my side project", "make a picture of a mountain lake".
21
+ - **Build a document or page:** ask for a deck, a brochure, or a simple website, and it turns the result into a PDF or publishes it.
22
+
23
+ ## Sessions
24
+
25
+ Each conversation is one session, saved as a transcript file. You can start fresh any time, or ask the assistant to pick up where you left off. Before you clear a conversation, ask it to save anything important to the vault, since a new session only remembers what is written to files.
26
+
27
+ ## Keeping it current
28
+
29
+ Ask the assistant to upgrade when you want the latest version. It re-runs the installer and the new version takes effect on your next session.
@@ -0,0 +1,40 @@
1
+ # The vault model
2
+
3
+ maxy-lite stores everything as plain markdown files in one folder tree, the vault. There is no database. Each file is one record: YAML frontmatter holds the structured fields, the markdown body holds the prose. This is the same substrate Obsidian reads, so the owner can browse and edit the same files on their phone.
4
+
5
+ ## Two organising dimensions
6
+
7
+ - **`type`** (a frontmatter field) says what kind of record a file is. It drives which fields the validator checks. It does not depend on the folder.
8
+ - **Area** says which part of life the record belongs to. It drives where the file is filed. The areas are a fixed list: `home`, `work`, `finance`, `health`, `vehicle`, `insurance`, `travel`, `education`, `family`, `legal`, `personal`.
9
+
10
+ Every document, asset, and project must declare an `area`. Contacts, events, and activities may.
11
+
12
+ ## Layout
13
+
14
+ - **Global folders** (cross-area): `people/`, `organizations/`, `calendar/`, `activities/`. These are the address book and calendar.
15
+ - **Area folders** (the filing cabinet): one folder per area, holding typed documents and assets.
16
+ - **`projects/`** holds projects.
17
+
18
+ ## Entity families
19
+
20
+ - **Contacts and orgs:** Person (vCard fields), Organization.
21
+ - **Time:** Event (iCalendar fields).
22
+ - **Work:** Task, Project.
23
+ - **Activity:** Note, Email, Call, Meeting. The long-form content (note body, email text, call notes) lives in the markdown body, not in a field.
24
+ - **Assets:** Property, Vehicle, Account.
25
+ - **Financial records:** Invoice, Expense, Bill, Statement, Payment.
26
+ - **Life documents:** Policy, Contract, Warranty, TaxDocument, IdentityDocument.
27
+
28
+ The full field-by-field declaration is `schema/SCHEMA.md`. Read that for the exact required and optional fields of each entity. Do not duplicate it here.
29
+
30
+ ## Links
31
+
32
+ A field whose value is `"[[Target]]"` (or a bare filename) is an association to another file, resolved by basename. Keep filenames unique across folders so links resolve unambiguously.
33
+
34
+ ## The validator
35
+
36
+ `validator/cli.mjs` checks a vault against `SCHEMA.md` with no model in the path. It flags missing required fields, wrong field types, bad area values, and links that resolve to no file or to the wrong entity type. A data skill writes vault files, then runs the validator and expects `invalid=0`, exit 0. A non-zero exit means a file violates the schema; fix it before claiming the data is saved.
37
+
38
+ ```bash
39
+ node ~/.maxy-lite/validator/cli.mjs ~/.maxy-lite/vault
40
+ ```
@@ -0,0 +1,107 @@
1
+ ---
2
+ name: email-composition
3
+ description: Draft and send email, and keep a record of what was sent in the vault. Use when the user asks to reply to a message, write a new email, follow up on a thread, or triage what is outstanding in the inbox (for example "reply to Sarah about the lease", "email Jane the quote", "what needs dealing with in my inbox"). Every send is approved by the user first, and every sent message is recorded as a vault Email associated to the person it went to.
4
+ ---
5
+
6
+ # Email composition
7
+
8
+ A conversational wrapper around the Gmail connector. Drafting, replying, follow-ups, triage, and recording the result. Human in the loop only: every send is approved by the user before it goes. There is no drip sequence, no scheduled send, no broadcast, and no automatic categorisation.
9
+
10
+ Two things make this skill more than a thin wrapper: the user approves before anything leaves, and after a send the message is written back into the vault as an Email so the correspondence is part of the store, not lost in the provider. The Email entity is in [`SCHEMA.md`](../../schema/SCHEMA.md) under *Activities*.
11
+
12
+ ## Transport: the Gmail connector
13
+
14
+ Outbound mail goes through the **Gmail connector** (the official Google remote MCP added on the device). Use whichever send, draft, and read tools that connector exposes; this skill names them by capability, not by a fixed tool name, because the connector is configured on the device and its tool surface belongs to the provider.
15
+
16
+ If the Gmail connector is not connected yet, do the whole draft and approval flow, then tell the user the message is ready but the Gmail connector still needs connecting before it can be sent, and stop. Do not invent a send. Connecting the connector is the connectors setup, not this skill.
17
+
18
+ ## When to use
19
+
20
+ - **Reply to a thread.** "Reply to Sarah's email about the lease."
21
+ - **New outbound email.** "Email Jane the quote." "Send the team a note about Friday."
22
+ - **Follow up.** "Follow up with everyone from yesterday."
23
+ - **Triage.** "What's outstanding in my inbox?"
24
+
25
+ Do not use it for listing or searching email as the end goal (a read tool answers that directly), or for any automated send loop. If the user asks for drip, scheduled, or broadcast sending, decline and say this skill is human in the loop only.
26
+
27
+ ## Who it is going to: resolve the person first
28
+
29
+ The recorded Email links to the recipient with a `participants` link, and that link fails validation if the person's file does not exist. So settle the recipient before sending:
30
+
31
+ - Find the contact by Grepping `people/` for the name or address, exactly as the `contacts` skill describes (`grep -rl "jane@acme.example" people/`).
32
+ - If the recipient is not in the vault yet, create the Person file first (via the `contacts` skill) so the link will resolve when you record the send.
33
+
34
+ ## Flow: reply to a thread
35
+
36
+ 1. **Find the thread.** Use the connector's read or search tool to pull the message and its parents. If several threads match the user's description, show three to five candidates with sender, subject, and date, and ask which one. Never guess. If nothing matches, ask the user to refine rather than inventing a thread.
37
+ 2. **Read the context.** Reply to the actual question in the latest message, not a one line summary. If the thread has attachments the reply refers to, name them and ask whether to forward.
38
+ 3. **Skip the ones that should be skipped.** An out of office autoreply, an unsubscribe or list message: do not draft. Flag it to the user and move on. A hostile or grief toned message: draft carefully and say so in the presentation, so the user reviews it closely before sending.
39
+ 4. **Draft.** Keep it tight. Anchor to the specific question, and to any decision the user has already stated in this conversation. Default to a neutral, polite British business register unless the user has asked for another tone.
40
+ 5. **Present.** Show the draft with the recipient, the subject, the body, and any flags from step 3. Do not send at this point. The send is not approved yet.
41
+ 6. **Edit loop.** The user approves ("send it"), edits verbally ("make it shorter", "say yes to the price, not the timeline"), or abandons. Apply edits and re present until they approve or abandon.
42
+ 7. **Send, on explicit approval.** Call the connector's reply or send tool so the message threads correctly. If it errors, show the error as is and let the user decide whether to fix and retry or abandon. Do not retry silently.
43
+ 8. **Record the send.** See "Record every send" below. This is not optional.
44
+
45
+ ## Flow: new outbound email
46
+
47
+ The same as a reply, with two differences: there is no thread to load, so ask the user for the recipient, the topic, and any constraints; and you send a fresh message rather than a reply. If the user names a group ("email the team") rather than one person, ask which addresses to include; list candidates you can resolve from `people/`, and do not invent recipients.
48
+
49
+ ## Flow: leave it in drafts
50
+
51
+ When the user wants a reviewable, unsent message ("draft it", "leave it in drafts", "don't send yet"), run the same present and edit loop, but save the approved draft through the connector's draft tool instead of sending. Nothing is dispatched. A saved draft is not a send, so it is not recorded as a vault Email until it is actually sent.
52
+
53
+ ## Flow: triage
54
+
55
+ When the user asks what is outstanding, read the last several unread messages and return a one line summary of each with a recommended action: reply, file, or ignore (autoreplies, newsletters, and list mail are ignore). Then wait. Triage never auto drafts; when the user picks one, drop into the reply flow for that message.
56
+
57
+ ## Record every send
58
+
59
+ After the connector confirms a send, write the message into the vault as an Email so the correspondence is part of the store. Without this step the send leaves no trace in the vault, which is lost provenance and the main failure this skill exists to prevent.
60
+
61
+ Write `activities/<subject>.md`:
62
+
63
+ ```yaml
64
+ ---
65
+ type: email
66
+ subject: Quote for the bathroom refit
67
+ timestamp: 2026-06-21T14:00:00
68
+ direction: outgoing
69
+ participants:
70
+ - "[[Jane Doe]]"
71
+ area: work
72
+ ---
73
+ Hi Jane, here is the quote we discussed.
74
+ ```
75
+
76
+ Required is `type: email` and `subject`. `timestamp` is the time of the send; `direction` is `outgoing` for a message you sent (use `incoming` if you are recording one that arrived). `participants` is a list of links to the people on the message, each of whom must already have a Person file. Optionally, `about` links the email to whatever it concerns (a project, a contact, anything), in which case that target file must already exist, and `area` files it under one life area. The body of the file is the email text. The field list is in [`SCHEMA.md`](../../schema/SCHEMA.md).
77
+
78
+ Then validate:
79
+
80
+ ```sh
81
+ maxy-lite-validate "$HOME/maxy"
82
+ ```
83
+
84
+ It exits 0 only when every file conforms. If the Email you just wrote is `ok=false`, the bracketed error names the field: `subject:missing` (the required subject is absent), `participants:dangling` (a linked person has no file, so create it), `participants:target` (a link points at a non person file), `area:area` (an area outside the controlled vocabulary). Fix the named field and re run until it is `ok=true`. Never leave a sent message unrecorded or a recorded Email in a failing state.
85
+
86
+ ## Edge cases
87
+
88
+ | Situation | What to do |
89
+ |-----------|------------|
90
+ | Several threads match the description | Show three to five candidates and ask. Never guess. |
91
+ | Recipient not in the vault yet | Create the Person file first, then send and record, so the link resolves. |
92
+ | Original thread has people in cc | Reply to the sender only by default. Ask before copying others. |
93
+ | Inbound is an out of office or list message | Do not draft. Flag it and move on. |
94
+ | Inbound is hostile or grief toned | Draft carefully and flag the tone. The user reviews before sending. |
95
+ | The connector returns an error after approval | Show the error as is. The user decides whether to fix and retry or abandon. No silent retry. |
96
+ | The Gmail connector is not connected | Draft and present, then say the connector needs connecting before the send. Do not fake a send. |
97
+
98
+ ## Out of scope
99
+
100
+ Never offer these here, even if asked:
101
+
102
+ - **Drip sequences** and any multi step automated send chain.
103
+ - **Scheduled or delayed sends.** The user triggers the send when they approve.
104
+ - **List broadcasts** to managed subscriber lists.
105
+ - **Automatic inbox labelling or categorisation.** Triage is on demand only.
106
+ - **New tools.** This skill orchestrates the Gmail connector and writes vault files. Nothing else.
107
+ </content>