From 356391a7ecbaeea26a1cef2f6eea0ee172f60733 Mon Sep 17 00:00:00 2001 From: "Runneth (for Vamsi)" Date: Mon, 6 Jul 2026 02:38:18 -0400 Subject: [PATCH 01/16] feat(package): add context-kit --- package-index.json | 22 +++- .../context-kit/data/context-kit-state.json | 22 ++++ .../context-kit/apps/context-kit/package.json | 12 ++ .../apps/context-kit/src/pages/index.astro | 117 ++++++++++++++++++ .../brain/context-kit/context-kit-state.json | 22 ++++ .../brain/context-kit/guardrails.md | 16 +++ .../brain/context-kit/legal-compliance.md | 18 +++ .../brain/context-kit/source-of-truth.md | 16 +++ .../brain/templates/briefing-template.md | 11 ++ packages/context-kit/instructions/behavior.md | 39 ++++++ packages/context-kit/runneth-package.json | 19 +++ packages/context-kit/skills/SKILL.md | 59 +++++++++ 12 files changed, 371 insertions(+), 2 deletions(-) create mode 100644 packages/context-kit/apps/context-kit/data/context-kit-state.json create mode 100644 packages/context-kit/apps/context-kit/package.json create mode 100644 packages/context-kit/apps/context-kit/src/pages/index.astro create mode 100644 packages/context-kit/brain/context-kit/context-kit-state.json create mode 100644 packages/context-kit/brain/context-kit/guardrails.md create mode 100644 packages/context-kit/brain/context-kit/legal-compliance.md create mode 100644 packages/context-kit/brain/context-kit/source-of-truth.md create mode 100644 packages/context-kit/brain/templates/briefing-template.md create mode 100644 packages/context-kit/instructions/behavior.md create mode 100644 packages/context-kit/runneth-package.json create mode 100644 packages/context-kit/skills/SKILL.md diff --git a/package-index.json b/package-index.json index ddfb614..528af26 100644 --- a/package-index.json +++ b/package-index.json @@ -1,5 +1,23 @@ { "schemaVersion": 1, - "indexRevision": "initial-empty", - "packages": [] + "indexRevision": "context-kit-0.1.0", + "packages": [ + { + "id": "context-kit", + "name": "Context Kit", + "description": "Builds the institutional knowledge that makes every Runneth answer sharper. Seeds a brain skeleton, a Context Kit board app, and the Context Kit skill that confirms what Motion knows, imports what already lives in Drive/Notion, researches what it can, and collects the rest.", + "version": "0.1.0", + "categories": ["baseline"], + "packageManagerVersion": 1, + "source": { + "type": "github", + "owner": "Motion-Creative", + "repo": "runneth-apps", + "ref": "main", + "path": "packages/context-kit" + }, + "updatePolicy": "manual", + "uninstallPolicy": "allowed" + } + ] } diff --git a/packages/context-kit/apps/context-kit/data/context-kit-state.json b/packages/context-kit/apps/context-kit/data/context-kit-state.json new file mode 100644 index 0000000..48cb2bf --- /dev/null +++ b/packages/context-kit/apps/context-kit/data/context-kit-state.json @@ -0,0 +1,22 @@ +{ + "version": 1, + "levels": [ + { "id": "L1", "name": "Answers questions", "state": "passed" }, + { "id": "L2", "name": "On-brand outputs", "state": "current" }, + { "id": "L3", "name": "Runs with full context", "state": "locked" } + ], + "items": [ + { "id": "brand-context", "label": "Brand context", "bucket": "A", "status": "inferred", "why": "Keeps every output unmistakably on-brand." }, + { "id": "kpis-goal", "label": "KPIs & goal", "bucket": "A", "status": "inferred", "why": "Every readout leads with the metric you care about." }, + { "id": "spend-threshold", "label": "Spend threshold", "bucket": "A", "status": "inferred", "why": "Separates a proven winner from early noise." }, + { "id": "competitors", "label": "Competitors", "bucket": "B", "status": "missing", "why": "Angles to attack the gaps rivals leave open." }, + { "id": "products", "label": "Products & SKUs", "bucket": "B", "status": "missing", "why": "Grounds every ad in real product facts." }, + { "id": "positioning", "label": "Positioning & personas", "bucket": "B", "status": "missing", "why": "Right audience, right angle." }, + { "id": "voice", "label": "Voice & tone", "bucket": "B", "status": "missing", "why": "Copy that sounds like you wrote it." }, + { "id": "voc", "label": "Voice-of-customer", "bucket": "B", "status": "missing", "why": "Real customer language for hooks." }, + { "id": "legal", "label": "Legal & compliance", "bucket": "C", "status": "missing", "why": "Clears review on the first pass." }, + { "id": "briefing-template", "label": "Briefing template", "bucket": "C", "status": "missing", "why": "Briefs come back in your exact format." }, + { "id": "source-of-truth", "label": "Source of truth", "bucket": "C", "status": "missing", "why": "Reports never fight your dashboard." }, + { "id": "guardrails", "label": "Guardrails", "bucket": "C", "status": "missing", "why": "Always/never rules for creative." } + ] +} diff --git a/packages/context-kit/apps/context-kit/package.json b/packages/context-kit/apps/context-kit/package.json new file mode 100644 index 0000000..ebbfd49 --- /dev/null +++ b/packages/context-kit/apps/context-kit/package.json @@ -0,0 +1,12 @@ +{ + "name": "onboarding", + "private": true, + "type": "module", + "scripts": { + "build": "astro build", + "dev": "astro dev" + }, + "dependencies": { + "astro": "^4.15.0" + } +} diff --git a/packages/context-kit/apps/context-kit/src/pages/index.astro b/packages/context-kit/apps/context-kit/src/pages/index.astro new file mode 100644 index 0000000..b938ff4 --- /dev/null +++ b/packages/context-kit/apps/context-kit/src/pages/index.astro @@ -0,0 +1,117 @@ +--- +import state from "../../data/context-kit-state.json"; +const items = state.items; +const total = items.length; +const confirmed = items.filter((i) => i.status === "confirmed").length; +const pct = Math.round((confirmed / total) * 100); +const buckets = [ + { key: "A", title: "From Motion — just confirm", sub: "Runneth already pulled these from your Motion setup." }, + { key: "B", title: "Runneth can research these", sub: "We'll draft it, you correct anything that's off." }, + { key: "C", title: "Only you can answer these", sub: "The few things no data source knows." }, +]; +const statusLabel = { confirmed: "Confirmed", inferred: "Confirm this", drafted: "Review draft", imported: "Imported", missing: "Not yet" }; +--- + + + + + + Runneth | Context Kit + + + + + +
+ Onboarding +

Your Context Kit

+

The more it knows about your brand, the better every output. Confirm what we pulled, react to what we drafted, add the few things only you know.

+ +
+ {state.levels.map((l) => ( +
+ {l.state === "passed" ? "✓" : l.state === "current" ? "You're here" : "🔒"} +
Level {l.id.replace("L", "")}
+
{l.name}
+
+ ))} +
+ +
+
{confirmed}/{total}
+
+
{confirmed === total ? "Full context unlocked." : `${total - confirmed} items left to unlock full context.`}
+
Confirm the blue ones, react to drafts, fill the rest. Say "build my Context Kit" in chat.
+
+
+
+ + {buckets.map((b) => ( +
+
{b.title}
+
{b.sub}
+
+ {items.filter((i) => i.bucket === b.key).map((i) => ( +
+
{i.label}
+
{i.why}
+
+ {statusLabel[i.status]} + {i.status === "confirmed" ? "Update" : i.status === "inferred" ? "Review & confirm" : "Add / drop file"} +
+
+ ))} +
+
+ ))} + +

This board mirrors your brain. Runneth updates it as you fill things in through chat. It doesn't store anything itself.

+
+ + diff --git a/packages/context-kit/brain/context-kit/context-kit-state.json b/packages/context-kit/brain/context-kit/context-kit-state.json new file mode 100644 index 0000000..a2ce66a --- /dev/null +++ b/packages/context-kit/brain/context-kit/context-kit-state.json @@ -0,0 +1,22 @@ +{ + "version": 1, + "levels": [ + { "id": "L1", "name": "Answers questions", "state": "passed" }, + { "id": "L2", "name": "On-brand outputs", "state": "current" }, + { "id": "L3", "name": "Runs with full context", "state": "locked" } + ], + "items": [ + { "id": "brand-context", "label": "Brand context", "bucket": "A", "status": "inferred", "source": "motion brand-context", "path": "workspace-config/brand-context", "why": "Keeps every output unmistakably on-brand." }, + { "id": "kpis-goal", "label": "KPIs & goal", "bucket": "A", "status": "inferred", "source": "motion workspace-goal", "path": "workspace-config/workspace-goal", "why": "Every readout leads with the metric you care about." }, + { "id": "spend-threshold", "label": "Spend threshold", "bucket": "A", "status": "inferred", "source": "motion spend-threshold", "path": "workspace-config/spend-threshold", "why": "Separates a proven winner from early noise." }, + { "id": "competitors", "label": "Competitors", "bucket": "B", "status": "missing", "source": "inspo + competitor-analysis", "path": "brand-audit//competitor-analysis.md", "why": "Angles to attack the gaps rivals leave open." }, + { "id": "products", "label": "Products & SKUs", "bucket": "B", "status": "missing", "source": "product-catalog", "path": "brand-audit//product-catalog.md", "why": "Grounds every ad in real product facts." }, + { "id": "positioning", "label": "Positioning & personas", "bucket": "B", "status": "missing", "source": "brand-audit strategy", "path": "brand-audit//strategy.md", "why": "Right audience, right angle, not spray-and-pray." }, + { "id": "voice", "label": "Voice & tone", "bucket": "B", "status": "missing", "source": "brand-audit", "path": "brand-audit//brand-context.md", "why": "Copy that sounds like you wrote it." }, + { "id": "voc", "label": "Voice-of-customer", "bucket": "B", "status": "missing", "source": "review-audit", "path": "brand-audit//review-audit.md", "why": "Real customer language for hooks." }, + { "id": "legal", "label": "Legal & compliance", "bucket": "C", "status": "missing", "source": "customer", "path": "onboarding/legal-compliance.md", "why": "Clears review on the first pass." }, + { "id": "briefing-template", "label": "Briefing template", "bucket": "C", "status": "missing", "source": "customer", "path": "templates/briefing-template.md", "why": "Briefs come back in your exact format." }, + { "id": "source-of-truth", "label": "Source of truth", "bucket": "C", "status": "missing", "source": "customer", "path": "onboarding/source-of-truth.md", "why": "Reports never fight your dashboard." }, + { "id": "guardrails", "label": "Guardrails", "bucket": "C", "status": "missing", "source": "customer", "path": "onboarding/guardrails.md", "why": "Always/never rules for creative." } + ] +} diff --git a/packages/context-kit/brain/context-kit/guardrails.md b/packages/context-kit/brain/context-kit/guardrails.md new file mode 100644 index 0000000..bcbd0ba --- /dev/null +++ b/packages/context-kit/brain/context-kit/guardrails.md @@ -0,0 +1,16 @@ +# Guardrails + +> Status: not yet filled. Runneth honors this before generating customer-facing output. Fill it +> through the Context Kit skill ("build my Context Kit") or tell Runneth here. + +## What belongs here +The always/never rules for how Runneth should and should not create for your brand. + +## Thought starters +- Anything Runneth should always do in creative? (a signature format, a required CTA, a mascot) +- Anything Runneth should never do? (a tone, a competitor mention, a discount level, an emoji style) +- Approval workflow: who signs off before something ships, and on what? +- Any internal targets or constraints beyond your Motion goal? + +## Your answers +_(empty)_ diff --git a/packages/context-kit/brain/context-kit/legal-compliance.md b/packages/context-kit/brain/context-kit/legal-compliance.md new file mode 100644 index 0000000..05e886d --- /dev/null +++ b/packages/context-kit/brain/context-kit/legal-compliance.md @@ -0,0 +1,18 @@ +# Legal & compliance + +> Status: not yet filled. Runneth reads this before any creative work. Fill it through the +> Context Kit skill ("build my Context Kit") or just tell Runneth the answers here. + +## What belongs here +The claims, words, and framings your brand is allowed and not allowed to make in ads and copy, +so creative clears review on the first pass. + +## Thought starters +- Any claims you legally cannot make? (e.g. "clinically proven", "#1", "cures", "guaranteed") +- Required disclaimers or fine print on specific claims? +- Regulated categories that apply to you? (health, finance, beauty, supplements, kids) +- Words or comparisons legal has flagged before? +- Anything you must always attribute or cite? + +## Your answers +_(empty)_ diff --git a/packages/context-kit/brain/context-kit/source-of-truth.md b/packages/context-kit/brain/context-kit/source-of-truth.md new file mode 100644 index 0000000..67557c4 --- /dev/null +++ b/packages/context-kit/brain/context-kit/source-of-truth.md @@ -0,0 +1,16 @@ +# Source of truth + +> Status: not yet filled. Runneth honors this before any performance or reporting answer. Fill it +> through the Context Kit skill ("build my Context Kit") or tell Runneth here. + +## What belongs here +Which numbers Runneth should trust when sources disagree, so reports never fight your dashboard. + +## Thought starters +- When the ad platform and your attribution tool disagree, which wins? (e.g. Triple Whale, Northbeam, GA4, platform-reported) +- What is your primary success metric, and over what attribution window? +- Any metric you explicitly do not trust or want ignored? +- Which dashboard is the one your team reviews in meetings? + +## Your answers +_(empty)_ diff --git a/packages/context-kit/brain/templates/briefing-template.md b/packages/context-kit/brain/templates/briefing-template.md new file mode 100644 index 0000000..eb34669 --- /dev/null +++ b/packages/context-kit/brain/templates/briefing-template.md @@ -0,0 +1,11 @@ +# Briefing template + +> Status: not yet filled. This is the exact format Runneth returns creative briefs in. Drop your +> current brief template during onboarding and Runneth will match it, or edit this file directly. + +## How to fill +Best path: drop your existing brief doc during "build my Context Kit" and Runneth saves it here +as the exact-match template. Otherwise, paste your preferred structure below. + +## Your template +_(empty. until filled, Runneth uses its default briefing structure.)_ diff --git a/packages/context-kit/instructions/behavior.md b/packages/context-kit/instructions/behavior.md new file mode 100644 index 0000000..6491a59 --- /dev/null +++ b/packages/context-kit/instructions/behavior.md @@ -0,0 +1,39 @@ +# Context Kit package instructions + +This package installs the Context Kit: the institutional knowledge that makes every Runneth answer +sharper. It seeds structured-but-empty scaffolds, a status index, the Context Kit board app, and the +Context Kit skill. These instructions are loaded as prompt context so Runneth knows the surface +exists and how to use it. + +## What Runneth should know from moment one + +- There is a Context Kit board app at `agent_apps/context-kit`. It is a read-only mirror of brain + completeness. Build it with `app build context-kit` before first use (package sync stages files + but does not build apps). +- State lives at `/agent/brain/context-kit/context-kit-state.json`. It is the source of truth for + what is confirmed, inferred, drafted, imported, or missing. +- The write-in scaffolds live at `/agent/brain/context-kit/` (legal-compliance.md, source-of-truth.md, + guardrails.md) and `/agent/brain/templates/briefing-template.md`. + +## Read-before-work rules (retrieval awareness) + +- Before creative work (hooks, concepts, briefs, scripts, ad copy), read + `/agent/brain/context-kit/legal-compliance.md` and `/agent/brain/templates/briefing-template.md` + if present and filled. +- Before any performance/reporting answer, honor `/agent/brain/context-kit/source-of-truth.md` + when it names which numbers to trust. +- Before generating any customer-facing output, honor `/agent/brain/context-kit/guardrails.md`. +- Bucket B context (competitors, products, positioning, voice, voice-of-customer) lives in the + existing `/agent/brain/brand-audit//` bundle and is already covered by the + creative-strategy read-before-work rules. + +## Rules + +- Never write Context Kit content into `user.md`. Fill happens as deliberate in-conversation brain + writes through the Context Kit skill. +- Prefer importing what already exists. If Google Drive or Notion is connected (or can be), offer to + find and pull the customer's existing brand, legal, brief, or positioning docs before asking them + to type anything. +- The scaffolds are create-if-absent. Never overwrite a file a customer has already filled. +- As each item is filled with real content, add or refresh its `/agent/INDEX.md` entry. Do not + blind-overwrite `INDEX.md` from a package sync. diff --git a/packages/context-kit/runneth-package.json b/packages/context-kit/runneth-package.json new file mode 100644 index 0000000..d3e4b7c --- /dev/null +++ b/packages/context-kit/runneth-package.json @@ -0,0 +1,19 @@ +{ + "schemaVersion": 1, + "id": "context-kit", + "name": "Context Kit", + "description": "Builds the institutional knowledge that makes every Runneth answer sharper. Seeds a brain skeleton, a Context Kit board app, and the Context Kit skill that confirms what Motion knows, imports what already lives in Drive/Notion, researches what it can, and collects the rest.", + "version": "0.1.0", + "updatePolicy": "manual", + "uninstallPolicy": "allowed", + "resources": [ + { "id": "context-kit-behavior", "type": "package_instruction", "sourcePath": "instructions/behavior.md" }, + { "id": "context-kit-state", "type": "file", "sourcePath": "brain/context-kit/context-kit-state.json", "target": { "root": "agent_brain", "path": "context-kit/context-kit-state.json" }, "executable": false }, + { "id": "legal-compliance", "type": "file", "sourcePath": "brain/context-kit/legal-compliance.md", "target": { "root": "agent_brain", "path": "context-kit/legal-compliance.md" }, "executable": false }, + { "id": "source-of-truth", "type": "file", "sourcePath": "brain/context-kit/source-of-truth.md", "target": { "root": "agent_brain", "path": "context-kit/source-of-truth.md" }, "executable": false }, + { "id": "guardrails", "type": "file", "sourcePath": "brain/context-kit/guardrails.md", "target": { "root": "agent_brain", "path": "context-kit/guardrails.md" }, "executable": false }, + { "id": "briefing-template", "type": "file", "sourcePath": "brain/templates/briefing-template.md", "target": { "root": "agent_brain", "path": "templates/briefing-template.md" }, "executable": false }, + { "id": "context-kit-skill", "type": "directory", "sourcePath": "skills", "target": { "root": "agent_skills", "path": "context-kit" }, "executablePaths": [] }, + { "id": "context-kit-app", "type": "directory", "sourcePath": "apps/context-kit", "target": { "root": "agent_apps", "path": "context-kit" }, "executablePaths": [] } + ] +} diff --git a/packages/context-kit/skills/SKILL.md b/packages/context-kit/skills/SKILL.md new file mode 100644 index 0000000..cbdd095 --- /dev/null +++ b/packages/context-kit/skills/SKILL.md @@ -0,0 +1,59 @@ +--- +name: context-kit +description: Builds a customer's Context Kit, the institutional knowledge that makes every Runneth answer sharper. Reads the Context Kit state index, confirms what Motion already knows, imports what already lives in Google Drive or Notion, drafts what Runneth can research, and collects what only the customer knows, filling each into the brain and moving the completeness meter. Triggers on "build my context kit", "set up my context kit", "context kit", "build my brain", "sharpen Runneth", "what makes my answers better", "what do you still need from me", "what does Runneth know about us". +--- + +# Context Kit skill + +Turn a fresh brain into a filled one, without the manual sales/CS back-and-forth. The Context Kit +board app is the mirror; this skill is the doer. Never write to `user.md`. Fill happens as deliberate +in-conversation brain writes. Always prefer importing what already exists over asking the customer to +retype it. + +## Step 0 — Load state +1. Read `/agent/brain/context-kit/context-kit-state.json`. +2. Run `motion brand-context --data-query "summary"`, `motion workspace-goal`, `motion spend-threshold` + to hydrate the three Bucket A items with live values. +3. Check which context sources are connected (Google Drive, Notion) so import is offered when available. +4. Compute completeness and resolve the workspace slug for brand-audit paths. + +## Step 1 — Open the board +- If the app is not built yet, run `app build context-kit`, then `app list` for the verified URL. +- Hand the URL back. Never invent it. + +## Step 2 — Bucket A: confirm (fast) +For brand-context, kpis-goal, spend-threshold: show the live value plainly and ask for a one-tap +confirm. On confirm, set the item `confirmed`. Do not re-collect what Motion already holds. + +## Step 3 — Import mode (try this before drafting or asking, for every remaining item) +Before researching or asking a customer to type, ask: "Do you already have this written down in +Google Drive or Notion?" +- If Drive or Notion is connected, search it for the relevant doc (brand guidelines, legal/claims, + brief template, positioning, competitor list), show what you found, confirm it's the right one, + and import it into the correct brain path. Mark the item `imported` then `confirmed`. +- If not connected, offer the native connect flow first. Only fall through to draft/write-in if they + decline or don't have it. +- Lean on the existing context-sweep / integration skills to do the search + pull rather than + reinventing retrieval. + +## Step 4 — Bucket B: draft, then confirm +For competitors, products, positioning, voice, voice-of-customer not covered by an import: run the +matching skill (product-catalog, competitor-analysis, brand-audit strategy/review passes, Inspo +followed brands + boards for competitors). Show the draft, invite corrections, write into the +existing `/agent/brain/brand-audit//` bundle, mark `confirmed`. No parallel files. + +## Step 5 — Bucket C: collect (only what import/research can't cover) +For legal, briefing-template, source-of-truth, guardrails still unfilled: pick the lightest mode. +File drop when they have the doc, thought starters when stuck (scaffolds carry these), one quick +prompt when short. Write into the scaffold file, replace the `_(empty)_` block, mark `confirmed`. + +## Step 6 — Keep the map correct +- After each item is filled with real content, add or refresh its `/agent/INDEX.md` entry. +- Update `context-kit-state.json` after every change so the board stays honest. +- Re-run `app build context-kit` (or refresh its data copy) so the meter reflects new state. + +## Rules +- Never touch `user.md`. +- Never overwrite an already-filled file (create-if-absent, edit-in-place only on confirm). +- Plain, non-technical language with the customer. No file paths or JSON in chat. +- One item at a time; celebrate the Level 3 unlock when the meter completes. From fc6768f329b314909585bb425a22a90aee18be8c Mon Sep 17 00:00:00 2001 From: "Runneth (for Vamsi)" Date: Mon, 6 Jul 2026 02:41:05 -0400 Subject: [PATCH 02/16] fix(context-kit): add package.json manifest for the VM installer --- packages/context-kit/package.json | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 packages/context-kit/package.json diff --git a/packages/context-kit/package.json b/packages/context-kit/package.json new file mode 100644 index 0000000..515869a --- /dev/null +++ b/packages/context-kit/package.json @@ -0,0 +1,20 @@ +{ + "schemaVersion": 1, + "id": "context-kit", + "name": "Context Kit", + "description": "Builds the institutional knowledge that makes every Runneth answer sharper. Seeds a brain skeleton, a Context Kit board app, and the Context Kit skill that confirms what Motion knows, imports what already lives in Drive/Notion, researches what it can, and collects the rest.", + "version": "0.1.0", + "installPolicy": "manual", + "updatePolicy": "manual", + "uninstallPolicy": "allowed", + "resources": [ + { "id": "context-kit-behavior", "type": "package_instruction", "sourcePath": "instructions/behavior.md" }, + { "id": "context-kit-state", "type": "file", "sourcePath": "brain/context-kit/context-kit-state.json", "target": { "root": "agent_brain", "path": "context-kit/context-kit-state.json" }, "executable": false }, + { "id": "legal-compliance", "type": "file", "sourcePath": "brain/context-kit/legal-compliance.md", "target": { "root": "agent_brain", "path": "context-kit/legal-compliance.md" }, "executable": false }, + { "id": "source-of-truth", "type": "file", "sourcePath": "brain/context-kit/source-of-truth.md", "target": { "root": "agent_brain", "path": "context-kit/source-of-truth.md" }, "executable": false }, + { "id": "guardrails", "type": "file", "sourcePath": "brain/context-kit/guardrails.md", "target": { "root": "agent_brain", "path": "context-kit/guardrails.md" }, "executable": false }, + { "id": "briefing-template", "type": "file", "sourcePath": "brain/templates/briefing-template.md", "target": { "root": "agent_brain", "path": "templates/briefing-template.md" }, "executable": false }, + { "id": "context-kit-skill", "type": "directory", "sourcePath": "skills", "target": { "root": "agent_skills", "path": "context-kit" }, "executablePaths": [] }, + { "id": "context-kit-app", "type": "directory", "sourcePath": "apps/context-kit", "target": { "root": "agent_apps", "path": "context-kit" }, "executablePaths": [] } + ] +} From 3ed7a9128b5cf76735032e8f3445fe7fe31e0653 Mon Sep 17 00:00:00 2001 From: "Runneth (for Vamsi)" Date: Mon, 6 Jul 2026 03:56:44 -0400 Subject: [PATCH 03/16] =?UTF-8?q?feat(context-kit):=20v0.2.0=20=E2=80=94?= =?UTF-8?q?=20bundle=20buildeth=20v3=20+=20astro=20base,=20runtime-fetch?= =?UTF-8?q?=20board=20with=20click-to-expand,=20is:global=20styles,=20data?= =?UTF-8?q?/=20scaffolds,=20richness=20+=20brand-context=20scoping=20(stag?= =?UTF-8?q?ing=20feedback)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-index.json | 4 +- packages/context-kit/README.md | 24 +++ .../apps/context-kit/astro.config.mjs | 6 + .../apps/context-kit/buildeth.app.json | 8 + .../apps/context-kit/data/competitors.md | 3 + .../context-kit/data/context-kit-state.json | 16 +- .../apps/context-kit/data/positioning.md | 3 + .../apps/context-kit/data/products.md | 3 + .../context-kit/apps/context-kit/data/voc.md | 3 + .../apps/context-kit/data/voice.md | 3 + .../apps/context-kit/src/pages/index.astro | 178 +++++++++++------- .../brain/context-kit/context-kit-state.json | 24 +-- packages/context-kit/instructions/behavior.md | 48 +++-- packages/context-kit/package.json | 2 +- packages/context-kit/runneth-package.json | 2 +- packages/context-kit/skills/SKILL.md | 74 ++++---- 16 files changed, 252 insertions(+), 149 deletions(-) create mode 100644 packages/context-kit/README.md create mode 100644 packages/context-kit/apps/context-kit/astro.config.mjs create mode 100644 packages/context-kit/apps/context-kit/buildeth.app.json create mode 100644 packages/context-kit/apps/context-kit/data/competitors.md create mode 100644 packages/context-kit/apps/context-kit/data/positioning.md create mode 100644 packages/context-kit/apps/context-kit/data/products.md create mode 100644 packages/context-kit/apps/context-kit/data/voc.md create mode 100644 packages/context-kit/apps/context-kit/data/voice.md diff --git a/package-index.json b/package-index.json index 528af26..9006ee5 100644 --- a/package-index.json +++ b/package-index.json @@ -1,12 +1,12 @@ { "schemaVersion": 1, - "indexRevision": "context-kit-0.1.0", + "indexRevision": "context-kit-0.2.0", "packages": [ { "id": "context-kit", "name": "Context Kit", "description": "Builds the institutional knowledge that makes every Runneth answer sharper. Seeds a brain skeleton, a Context Kit board app, and the Context Kit skill that confirms what Motion knows, imports what already lives in Drive/Notion, researches what it can, and collects the rest.", - "version": "0.1.0", + "version": "0.2.0", "categories": ["baseline"], "packageManagerVersion": 1, "source": { diff --git a/packages/context-kit/README.md b/packages/context-kit/README.md new file mode 100644 index 0000000..9304fe4 --- /dev/null +++ b/packages/context-kit/README.md @@ -0,0 +1,24 @@ +# Context Kit package + +Builds the institutional knowledge that makes every Runneth answer sharper: brain scaffolds, a board app +(read-only mirror of completeness), and the "build my Context Kit" skill. + +## App build gotchas (learned in staging — read before editing the app) + +- **`buildeth.app.json` must be v3** with `conversationId`, `workspaceId`, `oauthEnabled: true`, + `data: { "dir": "data" }`, `static: { "dist": "dist", "index": "index.html" }`. It ships as a template + with `__CONVERSATION_ID__` / `__WORKSPACE_ID__` tokens the skill substitutes before `app build`. +- **`astro.config.mjs` must set `base: "/context-kit"`** (and `trailingSlash: "never"`). Without a base, + Astro emits absolute `/_astro/...` asset URLs and `app build` rejects the static output. +- **Use `
- Onboarding + Context Kit

Your Context Kit

-

The more it knows about your brand, the better every output. Confirm what we pulled, react to what we drafted, add the few things only you know.

- -
- {state.levels.map((l) => ( -
- {l.state === "passed" ? "✓" : l.state === "current" ? "You're here" : "🔒"} -
Level {l.id.replace("L", "")}
-
{l.name}
-
- ))} -
- -
-
{confirmed}/{total}
-
-
{confirmed === total ? "Full context unlocked." : `${total - confirmed} items left to unlock full context.`}
-
Confirm the blue ones, react to drafts, fill the rest. Say "build my Context Kit" in chat.
-
-
-
- - {buckets.map((b) => ( -
-
{b.title}
-
{b.sub}
-
- {items.filter((i) => i.bucket === b.key).map((i) => ( -
-
{i.label}
-
{i.why}
-
- {statusLabel[i.status]} - {i.status === "confirmed" ? "Update" : i.status === "inferred" ? "Review & confirm" : "Add / drop file"} -
-
- ))} -
-
- ))} - -

This board mirrors your brain. Runneth updates it as you fill things in through chat. It doesn't store anything itself.

+

The more Runneth knows about your brand, the sharper every answer. Confirm what we pulled, review what we drafted, add the few things only you know. Click any card to see what's saved.

+
+

This board mirrors your brain in real time. Runneth updates it as you fill things in through chat. It reads state on every load, so a refresh always shows the latest.

+ + diff --git a/packages/context-kit/brain/context-kit/context-kit-state.json b/packages/context-kit/brain/context-kit/context-kit-state.json index a2ce66a..cd4798e 100644 --- a/packages/context-kit/brain/context-kit/context-kit-state.json +++ b/packages/context-kit/brain/context-kit/context-kit-state.json @@ -6,17 +6,17 @@ { "id": "L3", "name": "Runs with full context", "state": "locked" } ], "items": [ - { "id": "brand-context", "label": "Brand context", "bucket": "A", "status": "inferred", "source": "motion brand-context", "path": "workspace-config/brand-context", "why": "Keeps every output unmistakably on-brand." }, - { "id": "kpis-goal", "label": "KPIs & goal", "bucket": "A", "status": "inferred", "source": "motion workspace-goal", "path": "workspace-config/workspace-goal", "why": "Every readout leads with the metric you care about." }, - { "id": "spend-threshold", "label": "Spend threshold", "bucket": "A", "status": "inferred", "source": "motion spend-threshold", "path": "workspace-config/spend-threshold", "why": "Separates a proven winner from early noise." }, - { "id": "competitors", "label": "Competitors", "bucket": "B", "status": "missing", "source": "inspo + competitor-analysis", "path": "brand-audit//competitor-analysis.md", "why": "Angles to attack the gaps rivals leave open." }, - { "id": "products", "label": "Products & SKUs", "bucket": "B", "status": "missing", "source": "product-catalog", "path": "brand-audit//product-catalog.md", "why": "Grounds every ad in real product facts." }, - { "id": "positioning", "label": "Positioning & personas", "bucket": "B", "status": "missing", "source": "brand-audit strategy", "path": "brand-audit//strategy.md", "why": "Right audience, right angle, not spray-and-pray." }, - { "id": "voice", "label": "Voice & tone", "bucket": "B", "status": "missing", "source": "brand-audit", "path": "brand-audit//brand-context.md", "why": "Copy that sounds like you wrote it." }, - { "id": "voc", "label": "Voice-of-customer", "bucket": "B", "status": "missing", "source": "review-audit", "path": "brand-audit//review-audit.md", "why": "Real customer language for hooks." }, - { "id": "legal", "label": "Legal & compliance", "bucket": "C", "status": "missing", "source": "customer", "path": "onboarding/legal-compliance.md", "why": "Clears review on the first pass." }, - { "id": "briefing-template", "label": "Briefing template", "bucket": "C", "status": "missing", "source": "customer", "path": "templates/briefing-template.md", "why": "Briefs come back in your exact format." }, - { "id": "source-of-truth", "label": "Source of truth", "bucket": "C", "status": "missing", "source": "customer", "path": "onboarding/source-of-truth.md", "why": "Reports never fight your dashboard." }, - { "id": "guardrails", "label": "Guardrails", "bucket": "C", "status": "missing", "source": "customer", "path": "onboarding/guardrails.md", "why": "Always/never rules for creative." } + { "id": "brand-context", "label": "Brand context", "bucket": "A", "status": "inferred", "why": "Keeps every output unmistakably on-brand.", "preview": "" }, + { "id": "kpis-goal", "label": "KPIs & goal", "bucket": "A", "status": "inferred", "why": "Every readout leads with the metric you care about.", "preview": "" }, + { "id": "spend-threshold", "label": "Spend threshold", "bucket": "A", "status": "inferred", "why": "Separates a proven winner from early noise.", "preview": "" }, + { "id": "competitors", "label": "Competitors", "bucket": "B", "status": "missing", "why": "Angles to attack the gaps rivals leave open.", "file": "competitors.md" }, + { "id": "products", "label": "Products & SKUs", "bucket": "B", "status": "missing", "why": "Grounds every ad in real product facts.", "file": "products.md" }, + { "id": "positioning", "label": "Positioning & personas", "bucket": "B", "status": "missing", "why": "Right audience, right angle.", "file": "positioning.md" }, + { "id": "voice", "label": "Voice & tone", "bucket": "B", "status": "missing", "why": "Copy that sounds like you wrote it.", "file": "voice.md" }, + { "id": "voc", "label": "Voice-of-customer", "bucket": "B", "status": "missing", "why": "Real customer language for hooks.", "file": "voc.md" }, + { "id": "legal", "label": "Legal & compliance", "bucket": "C", "status": "missing", "why": "Clears review on the first pass." }, + { "id": "briefing-template", "label": "Briefing template", "bucket": "C", "status": "missing", "why": "Briefs come back in your exact format." }, + { "id": "source-of-truth", "label": "Source of truth", "bucket": "C", "status": "missing", "why": "Reports never fight your dashboard." }, + { "id": "guardrails", "label": "Guardrails", "bucket": "C", "status": "missing", "why": "Always/never rules for creative." } ] } diff --git a/packages/context-kit/instructions/behavior.md b/packages/context-kit/instructions/behavior.md index 6491a59..5493fe8 100644 --- a/packages/context-kit/instructions/behavior.md +++ b/packages/context-kit/instructions/behavior.md @@ -2,38 +2,34 @@ This package installs the Context Kit: the institutional knowledge that makes every Runneth answer sharper. It seeds structured-but-empty scaffolds, a status index, the Context Kit board app, and the -Context Kit skill. These instructions are loaded as prompt context so Runneth knows the surface -exists and how to use it. +Context Kit skill. These instructions are loaded as prompt context so Runneth knows the surface exists. ## What Runneth should know from moment one -- There is a Context Kit board app at `agent_apps/context-kit`. It is a read-only mirror of brain - completeness. Build it with `app build context-kit` before first use (package sync stages files - but does not build apps). -- State lives at `/agent/brain/context-kit/context-kit-state.json`. It is the source of truth for - what is confirmed, inferred, drafted, imported, or missing. -- The write-in scaffolds live at `/agent/brain/context-kit/` (legal-compliance.md, source-of-truth.md, - guardrails.md) and `/agent/brain/templates/briefing-template.md`. +- There is a Context Kit board app at `agent_apps/context-kit`. Package sync stages files but does NOT + build apps. To build it: fill the bundled `buildeth.app.json` (replace `__CONVERSATION_ID__` and + `__WORKSPACE_ID__` with the current context), then `app build context-kit`. `astro.config.mjs` (base + `/context-kit`) ships with the package. +- The board is client-rendered: it fetches `data/context-kit-state.json` and the Bucket B `data/*.md` + files at runtime. Update those data files to change what the board shows. A rebuild is only needed for + app source changes, not content/state changes. +- State lives at `/agent/brain/context-kit/context-kit-state.json` (source of truth) and is mirrored to + `/agent/apps/context-kit/data/context-kit-state.json` (what the board reads). +- Write-in scaffolds: `/agent/brain/context-kit/` (legal-compliance.md, source-of-truth.md, guardrails.md) + and `/agent/brain/templates/briefing-template.md`. ## Read-before-work rules (retrieval awareness) -- Before creative work (hooks, concepts, briefs, scripts, ad copy), read - `/agent/brain/context-kit/legal-compliance.md` and `/agent/brain/templates/briefing-template.md` - if present and filled. -- Before any performance/reporting answer, honor `/agent/brain/context-kit/source-of-truth.md` - when it names which numbers to trust. -- Before generating any customer-facing output, honor `/agent/brain/context-kit/guardrails.md`. -- Bucket B context (competitors, products, positioning, voice, voice-of-customer) lives in the - existing `/agent/brain/brand-audit//` bundle and is already covered by the - creative-strategy read-before-work rules. +- Before creative work, read `/agent/brain/context-kit/legal-compliance.md` and + `/agent/brain/templates/briefing-template.md` if filled. +- Before performance/reporting, honor `/agent/brain/context-kit/source-of-truth.md`. +- Before customer-facing output, honor `/agent/brain/context-kit/guardrails.md`. +- Bucket B context lives in `/agent/brain/brand-audit//` and is covered by the creative-strategy + read-before-work rules. ## Rules -- Never write Context Kit content into `user.md`. Fill happens as deliberate in-conversation brain - writes through the Context Kit skill. -- Prefer importing what already exists. If Google Drive or Notion is connected (or can be), offer to - find and pull the customer's existing brand, legal, brief, or positioning docs before asking them - to type anything. -- The scaffolds are create-if-absent. Never overwrite a file a customer has already filled. -- As each item is filled with real content, add or refresh its `/agent/INDEX.md` entry. Do not - blind-overwrite `INDEX.md` from a package sync. +- Never write Context Kit content into `user.md`. Fill happens as deliberate in-conversation brain writes. +- Prefer importing existing docs from Google Drive / Notion before asking the customer to type. +- Scaffolds are create-if-absent. Never overwrite a file a customer has already filled. +- As each item is filled, refresh its `/agent/INDEX.md` entry. Do not blind-overwrite `INDEX.md` from sync. diff --git a/packages/context-kit/package.json b/packages/context-kit/package.json index 515869a..7206fc3 100644 --- a/packages/context-kit/package.json +++ b/packages/context-kit/package.json @@ -3,7 +3,7 @@ "id": "context-kit", "name": "Context Kit", "description": "Builds the institutional knowledge that makes every Runneth answer sharper. Seeds a brain skeleton, a Context Kit board app, and the Context Kit skill that confirms what Motion knows, imports what already lives in Drive/Notion, researches what it can, and collects the rest.", - "version": "0.1.0", + "version": "0.2.0", "installPolicy": "manual", "updatePolicy": "manual", "uninstallPolicy": "allowed", diff --git a/packages/context-kit/runneth-package.json b/packages/context-kit/runneth-package.json index d3e4b7c..a7518f2 100644 --- a/packages/context-kit/runneth-package.json +++ b/packages/context-kit/runneth-package.json @@ -3,7 +3,7 @@ "id": "context-kit", "name": "Context Kit", "description": "Builds the institutional knowledge that makes every Runneth answer sharper. Seeds a brain skeleton, a Context Kit board app, and the Context Kit skill that confirms what Motion knows, imports what already lives in Drive/Notion, researches what it can, and collects the rest.", - "version": "0.1.0", + "version": "0.2.0", "updatePolicy": "manual", "uninstallPolicy": "allowed", "resources": [ diff --git a/packages/context-kit/skills/SKILL.md b/packages/context-kit/skills/SKILL.md index cbdd095..64c606c 100644 --- a/packages/context-kit/skills/SKILL.md +++ b/packages/context-kit/skills/SKILL.md @@ -15,42 +15,50 @@ retype it. 2. Run `motion brand-context --data-query "summary"`, `motion workspace-goal`, `motion spend-threshold` to hydrate the three Bucket A items with live values. 3. Check which context sources are connected (Google Drive, Notion) so import is offered when available. -4. Compute completeness and resolve the workspace slug for brand-audit paths. - -## Step 1 — Open the board -- If the app is not built yet, run `app build context-kit`, then `app list` for the verified URL. -- Hand the URL back. Never invent it. - -## Step 2 — Bucket A: confirm (fast) -For brand-context, kpis-goal, spend-threshold: show the live value plainly and ask for a one-tap -confirm. On confirm, set the item `confirmed`. Do not re-collect what Motion already holds. - -## Step 3 — Import mode (try this before drafting or asking, for every remaining item) -Before researching or asking a customer to type, ask: "Do you already have this written down in -Google Drive or Notion?" -- If Drive or Notion is connected, search it for the relevant doc (brand guidelines, legal/claims, - brief template, positioning, competitor list), show what you found, confirm it's the right one, - and import it into the correct brain path. Mark the item `imported` then `confirmed`. -- If not connected, offer the native connect flow first. Only fall through to draft/write-in if they - decline or don't have it. -- Lean on the existing context-sweep / integration skills to do the search + pull rather than - reinventing retrieval. - -## Step 4 — Bucket B: draft, then confirm -For competitors, products, positioning, voice, voice-of-customer not covered by an import: run the -matching skill (product-catalog, competitor-analysis, brand-audit strategy/review passes, Inspo -followed brands + boards for competitors). Show the draft, invite corrections, write into the -existing `/agent/brain/brand-audit//` bundle, mark `confirmed`. No parallel files. - -## Step 5 — Bucket C: collect (only what import/research can't cover) -For legal, briefing-template, source-of-truth, guardrails still unfilled: pick the lightest mode. -File drop when they have the doc, thought starters when stuck (scaffolds carry these), one quick -prompt when short. Write into the scaffold file, replace the `_(empty)_` block, mark `confirmed`. +4. Resolve the workspace slug for brand-audit paths. + +## Step 1 — Build and open the board (first run only) +Package sync stages files but does NOT build the app. On first run: +1. Fill the bundled manifest: in `/agent/apps/context-kit/buildeth.app.json`, replace `__CONVERSATION_ID__` + with the current conversation id and `__WORKSPACE_ID__` with the current workspace id. The rest of the + v3 manifest (oauthEnabled, data dir, static dist/index) and `astro.config.mjs` (base `/context-kit`) + ship in the package, so no trial-and-error is needed. +2. Run `app build context-kit`, then `app list` for the verified URL. Hand the URL back. Never invent it. +3. After the first build, the board reads `data/` at runtime (client-side fetch), so later state/content + updates show on refresh with NO rebuild. Only rebuild if you change the app source itself. + +## Step 2 — Bucket A: confirm (fast) + write the full working doc +For brand-context, kpis-goal, spend-threshold: show the live value plainly and ask a one-tap confirm. +On confirm: set the item `confirmed`, set its `preview` string in the state index (short human summary +for the card), and write the full working document. `brand-context.md` (#10) is the *foundation only*: +brand name, story, positioning statement, product description, proof points, and a 2-sentence tone/audience +summary. Do NOT concatenate the Bucket B detail into it. Do not re-collect what Motion already holds. + +## Step 3 — Import mode (try before drafting or asking, for every remaining item) +Ask: "Do you already have this in Google Drive or Notion?" If connected, search for the relevant doc, +confirm it, import into the correct brain path, set `imported` then `confirmed`. If not connected, offer +the native connect flow first. Only fall through to draft/write-in if they decline or don't have it. Lean +on existing context-sweep / integration skills for the search + pull. + +## Step 4 — Bucket B: draft rich, then confirm, then mirror to the board +For competitors, products, positioning, voice, voice-of-customer: run the matching skill (product-catalog, +competitor-analysis, brand-audit strategy/review passes, Inspo followed brands + boards for competitors). +Write FULL working documents into `/agent/brain/brand-audit//` (#9): competitor tone/audience/ +positioning breakdowns, complete product feature lists, full personas with motivations and objections, all +voice-of-customer quotes and patterns. Thin summaries fail here. Then: +- set status `drafted` (customer reviews) then `confirmed` on accept. +- MIRROR each file into `/agent/apps/context-kit/data/.md` (competitors.md, products.md, + positioning.md, voice.md, voc.md) so the board's click-to-expand can fetch it at runtime. + +## Step 5 — Bucket C: collect with depth +For legal, briefing-template, source-of-truth, guardrails: file drop when they have the doc, thought +starters when stuck, one prompt when short. Prompt for the COMPLETE rule set, not a one-liner (#9). Write +into the scaffold file, fully populating the `## Your answers` section. Mark `confirmed`. ## Step 6 — Keep the map correct - After each item is filled with real content, add or refresh its `/agent/INDEX.md` entry. -- Update `context-kit-state.json` after every change so the board stays honest. -- Re-run `app build context-kit` (or refresh its data copy) so the meter reflects new state. +- Update `/agent/brain/context-kit/context-kit-state.json` AND the app's `data/context-kit-state.json` + after every change (the board reads the app copy). No rebuild needed for data-only changes. ## Rules - Never touch `user.md`. From c543b41a4a51a76daaf313ca6969d2034d9e0cfb Mon Sep 17 00:00:00 2001 From: "Runneth (for Vamsi)" Date: Mon, 6 Jul 2026 08:32:50 -0400 Subject: [PATCH 04/16] =?UTF-8?q?feat(context-kit):=20v0.3.0=20=E2=80=94?= =?UTF-8?q?=20Motion-drafted=20brand-context=20+=20Bucket=20B,=20single=20?= =?UTF-8?q?/brain/context-kit=20folder,=20dataFile=20on=20all=20items,=20e?= =?UTF-8?q?mpty-state=20copy,=20Drive/Notion=20header=20nudge,=20help=20ba?= =?UTF-8?q?nner,=20app=20name=20fix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-index.json | 4 +- .../apps/context-kit/data/brand-context.md | 3 + .../context-kit/data/briefing-template.md | 3 + .../context-kit/data/context-kit-state.json | 24 ++-- .../apps/context-kit/data/guardrails.md | 3 + .../apps/context-kit/data/kpis-goal.md | 3 + .../apps/context-kit/data/legal-compliance.md | 3 + .../apps/context-kit/data/source-of-truth.md | 3 + .../apps/context-kit/data/spend-threshold.md | 3 + .../context-kit/apps/context-kit/package.json | 2 +- .../apps/context-kit/src/pages/index.astro | 52 ++++++--- .../briefing-template.md | 0 .../brain/context-kit/context-kit-state.json | 24 ++-- packages/context-kit/package.json | 85 ++++++++++++-- packages/context-kit/runneth-package.json | 85 ++++++++++++-- packages/context-kit/skills/SKILL.md | 109 ++++++++++-------- 16 files changed, 297 insertions(+), 109 deletions(-) create mode 100644 packages/context-kit/apps/context-kit/data/brand-context.md create mode 100644 packages/context-kit/apps/context-kit/data/briefing-template.md create mode 100644 packages/context-kit/apps/context-kit/data/guardrails.md create mode 100644 packages/context-kit/apps/context-kit/data/kpis-goal.md create mode 100644 packages/context-kit/apps/context-kit/data/legal-compliance.md create mode 100644 packages/context-kit/apps/context-kit/data/source-of-truth.md create mode 100644 packages/context-kit/apps/context-kit/data/spend-threshold.md rename packages/context-kit/brain/{templates => context-kit}/briefing-template.md (100%) diff --git a/package-index.json b/package-index.json index 9006ee5..466b3ff 100644 --- a/package-index.json +++ b/package-index.json @@ -1,12 +1,12 @@ { "schemaVersion": 1, - "indexRevision": "context-kit-0.2.0", + "indexRevision": "context-kit-0.3.0", "packages": [ { "id": "context-kit", "name": "Context Kit", "description": "Builds the institutional knowledge that makes every Runneth answer sharper. Seeds a brain skeleton, a Context Kit board app, and the Context Kit skill that confirms what Motion knows, imports what already lives in Drive/Notion, researches what it can, and collects the rest.", - "version": "0.2.0", + "version": "0.3.0", "categories": ["baseline"], "packageManagerVersion": 1, "source": { diff --git a/packages/context-kit/apps/context-kit/data/brand-context.md b/packages/context-kit/apps/context-kit/data/brand-context.md new file mode 100644 index 0000000..787d433 --- /dev/null +++ b/packages/context-kit/apps/context-kit/data/brand-context.md @@ -0,0 +1,3 @@ +# brand-context + +_Not filled in yet. Runneth writes this to /agent/brain/context-kit/brand-context.md and mirrors it here when the Context Kit skill fills it._ diff --git a/packages/context-kit/apps/context-kit/data/briefing-template.md b/packages/context-kit/apps/context-kit/data/briefing-template.md new file mode 100644 index 0000000..7439c1f --- /dev/null +++ b/packages/context-kit/apps/context-kit/data/briefing-template.md @@ -0,0 +1,3 @@ +# briefing-template + +_Not filled in yet. Runneth writes this to /agent/brain/context-kit/briefing-template.md and mirrors it here when the Context Kit skill fills it._ diff --git a/packages/context-kit/apps/context-kit/data/context-kit-state.json b/packages/context-kit/apps/context-kit/data/context-kit-state.json index cd4798e..ffcbe39 100644 --- a/packages/context-kit/apps/context-kit/data/context-kit-state.json +++ b/packages/context-kit/apps/context-kit/data/context-kit-state.json @@ -6,17 +6,17 @@ { "id": "L3", "name": "Runs with full context", "state": "locked" } ], "items": [ - { "id": "brand-context", "label": "Brand context", "bucket": "A", "status": "inferred", "why": "Keeps every output unmistakably on-brand.", "preview": "" }, - { "id": "kpis-goal", "label": "KPIs & goal", "bucket": "A", "status": "inferred", "why": "Every readout leads with the metric you care about.", "preview": "" }, - { "id": "spend-threshold", "label": "Spend threshold", "bucket": "A", "status": "inferred", "why": "Separates a proven winner from early noise.", "preview": "" }, - { "id": "competitors", "label": "Competitors", "bucket": "B", "status": "missing", "why": "Angles to attack the gaps rivals leave open.", "file": "competitors.md" }, - { "id": "products", "label": "Products & SKUs", "bucket": "B", "status": "missing", "why": "Grounds every ad in real product facts.", "file": "products.md" }, - { "id": "positioning", "label": "Positioning & personas", "bucket": "B", "status": "missing", "why": "Right audience, right angle.", "file": "positioning.md" }, - { "id": "voice", "label": "Voice & tone", "bucket": "B", "status": "missing", "why": "Copy that sounds like you wrote it.", "file": "voice.md" }, - { "id": "voc", "label": "Voice-of-customer", "bucket": "B", "status": "missing", "why": "Real customer language for hooks.", "file": "voc.md" }, - { "id": "legal", "label": "Legal & compliance", "bucket": "C", "status": "missing", "why": "Clears review on the first pass." }, - { "id": "briefing-template", "label": "Briefing template", "bucket": "C", "status": "missing", "why": "Briefs come back in your exact format." }, - { "id": "source-of-truth", "label": "Source of truth", "bucket": "C", "status": "missing", "why": "Reports never fight your dashboard." }, - { "id": "guardrails", "label": "Guardrails", "bucket": "C", "status": "missing", "why": "Always/never rules for creative." } + { "id": "brand-context", "label": "Brand context", "bucket": "A", "status": "inferred", "why": "Keeps every output unmistakably on-brand.", "preview": "", "dataFile": "brand-context.md" }, + { "id": "kpis-goal", "label": "KPIs & goal", "bucket": "A", "status": "inferred", "why": "Every readout leads with the metric you care about.", "preview": "", "dataFile": "kpis-goal.md" }, + { "id": "spend-threshold", "label": "Spend threshold", "bucket": "A", "status": "inferred", "why": "Separates a proven winner from early noise.", "preview": "", "dataFile": "spend-threshold.md" }, + { "id": "competitors", "label": "Competitors", "bucket": "B", "status": "missing", "why": "Angles to attack the gaps rivals leave open.", "dataFile": "competitors.md" }, + { "id": "products", "label": "Products & SKUs", "bucket": "B", "status": "missing", "why": "Grounds every ad in real product facts.", "dataFile": "products.md" }, + { "id": "positioning", "label": "Positioning & personas", "bucket": "B", "status": "missing", "why": "Right audience, right angle.", "dataFile": "positioning.md" }, + { "id": "voice", "label": "Voice & tone", "bucket": "B", "status": "missing", "why": "Copy that sounds like you wrote it.", "dataFile": "voice.md" }, + { "id": "voc", "label": "Voice-of-customer", "bucket": "B", "status": "missing", "why": "Real customer language for hooks.", "dataFile": "voc.md" }, + { "id": "legal", "label": "Legal & compliance", "bucket": "C", "status": "missing", "why": "Clears review on the first pass.", "dataFile": "legal-compliance.md" }, + { "id": "briefing-template", "label": "Briefing template", "bucket": "C", "status": "missing", "why": "Briefs come back in your exact format.", "dataFile": "briefing-template.md" }, + { "id": "source-of-truth", "label": "Source of truth", "bucket": "C", "status": "missing", "why": "Reports never fight your dashboard.", "dataFile": "source-of-truth.md" }, + { "id": "guardrails", "label": "Guardrails", "bucket": "C", "status": "missing", "why": "Always/never rules for creative.", "dataFile": "guardrails.md" } ] } diff --git a/packages/context-kit/apps/context-kit/data/guardrails.md b/packages/context-kit/apps/context-kit/data/guardrails.md new file mode 100644 index 0000000..3d9f5cb --- /dev/null +++ b/packages/context-kit/apps/context-kit/data/guardrails.md @@ -0,0 +1,3 @@ +# guardrails + +_Not filled in yet. Runneth writes this to /agent/brain/context-kit/guardrails.md and mirrors it here when the Context Kit skill fills it._ diff --git a/packages/context-kit/apps/context-kit/data/kpis-goal.md b/packages/context-kit/apps/context-kit/data/kpis-goal.md new file mode 100644 index 0000000..6209f0a --- /dev/null +++ b/packages/context-kit/apps/context-kit/data/kpis-goal.md @@ -0,0 +1,3 @@ +# kpis-goal + +_Not filled in yet. Runneth writes this to /agent/brain/context-kit/kpis-goal.md and mirrors it here when the Context Kit skill fills it._ diff --git a/packages/context-kit/apps/context-kit/data/legal-compliance.md b/packages/context-kit/apps/context-kit/data/legal-compliance.md new file mode 100644 index 0000000..b535b69 --- /dev/null +++ b/packages/context-kit/apps/context-kit/data/legal-compliance.md @@ -0,0 +1,3 @@ +# legal-compliance + +_Not filled in yet. Runneth writes this to /agent/brain/context-kit/legal-compliance.md and mirrors it here when the Context Kit skill fills it._ diff --git a/packages/context-kit/apps/context-kit/data/source-of-truth.md b/packages/context-kit/apps/context-kit/data/source-of-truth.md new file mode 100644 index 0000000..b3ae8a5 --- /dev/null +++ b/packages/context-kit/apps/context-kit/data/source-of-truth.md @@ -0,0 +1,3 @@ +# source-of-truth + +_Not filled in yet. Runneth writes this to /agent/brain/context-kit/source-of-truth.md and mirrors it here when the Context Kit skill fills it._ diff --git a/packages/context-kit/apps/context-kit/data/spend-threshold.md b/packages/context-kit/apps/context-kit/data/spend-threshold.md new file mode 100644 index 0000000..963511a --- /dev/null +++ b/packages/context-kit/apps/context-kit/data/spend-threshold.md @@ -0,0 +1,3 @@ +# spend-threshold + +_Not filled in yet. Runneth writes this to /agent/brain/context-kit/spend-threshold.md and mirrors it here when the Context Kit skill fills it._ diff --git a/packages/context-kit/apps/context-kit/package.json b/packages/context-kit/apps/context-kit/package.json index ebbfd49..86d7599 100644 --- a/packages/context-kit/apps/context-kit/package.json +++ b/packages/context-kit/apps/context-kit/package.json @@ -1,5 +1,5 @@ { - "name": "onboarding", + "name": "context-kit", "private": true, "type": "module", "scripts": { diff --git a/packages/context-kit/apps/context-kit/src/pages/index.astro b/packages/context-kit/apps/context-kit/src/pages/index.astro index 440b110..ec08948 100644 --- a/packages/context-kit/apps/context-kit/src/pages/index.astro +++ b/packages/context-kit/apps/context-kit/src/pages/index.astro @@ -17,6 +17,8 @@ .kicker{display:inline-block;font-size:11px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;background:var(--lime);padding:5px 10px;border-radius:4px;margin-bottom:16px} h1{font-size:clamp(30px,4.5vw,44px);font-weight:800;letter-spacing:-.025em;margin-bottom:10px} .lede{font-size:16px;color:var(--muted);max-width:640px} + .integration-nudge{font-size:13.5px;color:var(--muted);margin-top:12px;max-width:640px} + .integration-nudge strong{color:var(--ink)} .levels{display:flex;gap:10px;margin:30px 0 22px} @media(max-width:640px){.levels{flex-direction:column}} .lvl{flex:1;border:1px solid var(--border);border-radius:var(--r);padding:14px 16px;background:var(--gray-0);position:relative} @@ -60,7 +62,8 @@ .card-panel h1,.card-panel h2,.card-panel h3{font-size:14px;margin:10px 0 4px} .card-panel p{margin:6px 0} .card-panel .empty{color:var(--muted);font-style:italic} - .note{margin-top:26px;font-size:13px;color:var(--muted);border-top:1px solid var(--border);padding-top:16px} + .help-banner{display:flex;align-items:flex-start;gap:12px;margin-top:32px;padding:16px 20px;border:1px solid var(--border);border-radius:var(--r);background:var(--surface);font-size:14px;color:var(--ink);line-height:1.55} + .help-banner .icon{font-size:18px;flex-shrink:0;margin-top:1px} @@ -68,8 +71,12 @@ Context Kit

Your Context Kit

The more Runneth knows about your brand, the sharper every answer. Confirm what we pulled, review what we drafted, add the few things only you know. Click any card to see what's saved.

+

📄 Already have brand docs in Google Drive or Notion? Connect them in chat and Runneth can pull from them directly.

-

This board mirrors your brain in real time. Runneth updates it as you fill things in through chat. It reads state on every load, so a refresh always shows the latest.

+
+ 💡 + This board mirrors your brain. Click any card to review what Runneth has saved. Tell Runneth in chat to update anything, or ask it to pull up any file anytime. Refresh after a chat update to see the latest. +
diff --git a/packages/context-kit/brain/templates/briefing-template.md b/packages/context-kit/brain/context-kit/briefing-template.md similarity index 100% rename from packages/context-kit/brain/templates/briefing-template.md rename to packages/context-kit/brain/context-kit/briefing-template.md diff --git a/packages/context-kit/brain/context-kit/context-kit-state.json b/packages/context-kit/brain/context-kit/context-kit-state.json index cd4798e..ffcbe39 100644 --- a/packages/context-kit/brain/context-kit/context-kit-state.json +++ b/packages/context-kit/brain/context-kit/context-kit-state.json @@ -6,17 +6,17 @@ { "id": "L3", "name": "Runs with full context", "state": "locked" } ], "items": [ - { "id": "brand-context", "label": "Brand context", "bucket": "A", "status": "inferred", "why": "Keeps every output unmistakably on-brand.", "preview": "" }, - { "id": "kpis-goal", "label": "KPIs & goal", "bucket": "A", "status": "inferred", "why": "Every readout leads with the metric you care about.", "preview": "" }, - { "id": "spend-threshold", "label": "Spend threshold", "bucket": "A", "status": "inferred", "why": "Separates a proven winner from early noise.", "preview": "" }, - { "id": "competitors", "label": "Competitors", "bucket": "B", "status": "missing", "why": "Angles to attack the gaps rivals leave open.", "file": "competitors.md" }, - { "id": "products", "label": "Products & SKUs", "bucket": "B", "status": "missing", "why": "Grounds every ad in real product facts.", "file": "products.md" }, - { "id": "positioning", "label": "Positioning & personas", "bucket": "B", "status": "missing", "why": "Right audience, right angle.", "file": "positioning.md" }, - { "id": "voice", "label": "Voice & tone", "bucket": "B", "status": "missing", "why": "Copy that sounds like you wrote it.", "file": "voice.md" }, - { "id": "voc", "label": "Voice-of-customer", "bucket": "B", "status": "missing", "why": "Real customer language for hooks.", "file": "voc.md" }, - { "id": "legal", "label": "Legal & compliance", "bucket": "C", "status": "missing", "why": "Clears review on the first pass." }, - { "id": "briefing-template", "label": "Briefing template", "bucket": "C", "status": "missing", "why": "Briefs come back in your exact format." }, - { "id": "source-of-truth", "label": "Source of truth", "bucket": "C", "status": "missing", "why": "Reports never fight your dashboard." }, - { "id": "guardrails", "label": "Guardrails", "bucket": "C", "status": "missing", "why": "Always/never rules for creative." } + { "id": "brand-context", "label": "Brand context", "bucket": "A", "status": "inferred", "why": "Keeps every output unmistakably on-brand.", "preview": "", "dataFile": "brand-context.md" }, + { "id": "kpis-goal", "label": "KPIs & goal", "bucket": "A", "status": "inferred", "why": "Every readout leads with the metric you care about.", "preview": "", "dataFile": "kpis-goal.md" }, + { "id": "spend-threshold", "label": "Spend threshold", "bucket": "A", "status": "inferred", "why": "Separates a proven winner from early noise.", "preview": "", "dataFile": "spend-threshold.md" }, + { "id": "competitors", "label": "Competitors", "bucket": "B", "status": "missing", "why": "Angles to attack the gaps rivals leave open.", "dataFile": "competitors.md" }, + { "id": "products", "label": "Products & SKUs", "bucket": "B", "status": "missing", "why": "Grounds every ad in real product facts.", "dataFile": "products.md" }, + { "id": "positioning", "label": "Positioning & personas", "bucket": "B", "status": "missing", "why": "Right audience, right angle.", "dataFile": "positioning.md" }, + { "id": "voice", "label": "Voice & tone", "bucket": "B", "status": "missing", "why": "Copy that sounds like you wrote it.", "dataFile": "voice.md" }, + { "id": "voc", "label": "Voice-of-customer", "bucket": "B", "status": "missing", "why": "Real customer language for hooks.", "dataFile": "voc.md" }, + { "id": "legal", "label": "Legal & compliance", "bucket": "C", "status": "missing", "why": "Clears review on the first pass.", "dataFile": "legal-compliance.md" }, + { "id": "briefing-template", "label": "Briefing template", "bucket": "C", "status": "missing", "why": "Briefs come back in your exact format.", "dataFile": "briefing-template.md" }, + { "id": "source-of-truth", "label": "Source of truth", "bucket": "C", "status": "missing", "why": "Reports never fight your dashboard.", "dataFile": "source-of-truth.md" }, + { "id": "guardrails", "label": "Guardrails", "bucket": "C", "status": "missing", "why": "Always/never rules for creative.", "dataFile": "guardrails.md" } ] } diff --git a/packages/context-kit/package.json b/packages/context-kit/package.json index 7206fc3..26457f1 100644 --- a/packages/context-kit/package.json +++ b/packages/context-kit/package.json @@ -3,18 +3,85 @@ "id": "context-kit", "name": "Context Kit", "description": "Builds the institutional knowledge that makes every Runneth answer sharper. Seeds a brain skeleton, a Context Kit board app, and the Context Kit skill that confirms what Motion knows, imports what already lives in Drive/Notion, researches what it can, and collects the rest.", - "version": "0.2.0", + "version": "0.3.0", "installPolicy": "manual", "updatePolicy": "manual", "uninstallPolicy": "allowed", "resources": [ - { "id": "context-kit-behavior", "type": "package_instruction", "sourcePath": "instructions/behavior.md" }, - { "id": "context-kit-state", "type": "file", "sourcePath": "brain/context-kit/context-kit-state.json", "target": { "root": "agent_brain", "path": "context-kit/context-kit-state.json" }, "executable": false }, - { "id": "legal-compliance", "type": "file", "sourcePath": "brain/context-kit/legal-compliance.md", "target": { "root": "agent_brain", "path": "context-kit/legal-compliance.md" }, "executable": false }, - { "id": "source-of-truth", "type": "file", "sourcePath": "brain/context-kit/source-of-truth.md", "target": { "root": "agent_brain", "path": "context-kit/source-of-truth.md" }, "executable": false }, - { "id": "guardrails", "type": "file", "sourcePath": "brain/context-kit/guardrails.md", "target": { "root": "agent_brain", "path": "context-kit/guardrails.md" }, "executable": false }, - { "id": "briefing-template", "type": "file", "sourcePath": "brain/templates/briefing-template.md", "target": { "root": "agent_brain", "path": "templates/briefing-template.md" }, "executable": false }, - { "id": "context-kit-skill", "type": "directory", "sourcePath": "skills", "target": { "root": "agent_skills", "path": "context-kit" }, "executablePaths": [] }, - { "id": "context-kit-app", "type": "directory", "sourcePath": "apps/context-kit", "target": { "root": "agent_apps", "path": "context-kit" }, "executablePaths": [] } + { + "id": "context-kit-behavior", + "type": "package_instruction", + "sourcePath": "instructions/behavior.md" + }, + { + "id": "context-kit-state", + "type": "file", + "sourcePath": "brain/context-kit/context-kit-state.json", + "target": { + "root": "agent_brain", + "path": "context-kit/context-kit-state.json" + }, + "executable": false + }, + { + "id": "legal-compliance", + "type": "file", + "sourcePath": "brain/context-kit/legal-compliance.md", + "target": { + "root": "agent_brain", + "path": "context-kit/legal-compliance.md" + }, + "executable": false + }, + { + "id": "source-of-truth", + "type": "file", + "sourcePath": "brain/context-kit/source-of-truth.md", + "target": { + "root": "agent_brain", + "path": "context-kit/source-of-truth.md" + }, + "executable": false + }, + { + "id": "guardrails", + "type": "file", + "sourcePath": "brain/context-kit/guardrails.md", + "target": { + "root": "agent_brain", + "path": "context-kit/guardrails.md" + }, + "executable": false + }, + { + "id": "briefing-template", + "type": "file", + "sourcePath": "brain/context-kit/briefing-template.md", + "target": { + "root": "agent_brain", + "path": "context-kit/briefing-template.md" + }, + "executable": false + }, + { + "id": "context-kit-skill", + "type": "directory", + "sourcePath": "skills", + "target": { + "root": "agent_skills", + "path": "context-kit" + }, + "executablePaths": [] + }, + { + "id": "context-kit-app", + "type": "directory", + "sourcePath": "apps/context-kit", + "target": { + "root": "agent_apps", + "path": "context-kit" + }, + "executablePaths": [] + } ] } diff --git a/packages/context-kit/runneth-package.json b/packages/context-kit/runneth-package.json index a7518f2..ccd54ea 100644 --- a/packages/context-kit/runneth-package.json +++ b/packages/context-kit/runneth-package.json @@ -3,17 +3,84 @@ "id": "context-kit", "name": "Context Kit", "description": "Builds the institutional knowledge that makes every Runneth answer sharper. Seeds a brain skeleton, a Context Kit board app, and the Context Kit skill that confirms what Motion knows, imports what already lives in Drive/Notion, researches what it can, and collects the rest.", - "version": "0.2.0", + "version": "0.3.0", "updatePolicy": "manual", "uninstallPolicy": "allowed", "resources": [ - { "id": "context-kit-behavior", "type": "package_instruction", "sourcePath": "instructions/behavior.md" }, - { "id": "context-kit-state", "type": "file", "sourcePath": "brain/context-kit/context-kit-state.json", "target": { "root": "agent_brain", "path": "context-kit/context-kit-state.json" }, "executable": false }, - { "id": "legal-compliance", "type": "file", "sourcePath": "brain/context-kit/legal-compliance.md", "target": { "root": "agent_brain", "path": "context-kit/legal-compliance.md" }, "executable": false }, - { "id": "source-of-truth", "type": "file", "sourcePath": "brain/context-kit/source-of-truth.md", "target": { "root": "agent_brain", "path": "context-kit/source-of-truth.md" }, "executable": false }, - { "id": "guardrails", "type": "file", "sourcePath": "brain/context-kit/guardrails.md", "target": { "root": "agent_brain", "path": "context-kit/guardrails.md" }, "executable": false }, - { "id": "briefing-template", "type": "file", "sourcePath": "brain/templates/briefing-template.md", "target": { "root": "agent_brain", "path": "templates/briefing-template.md" }, "executable": false }, - { "id": "context-kit-skill", "type": "directory", "sourcePath": "skills", "target": { "root": "agent_skills", "path": "context-kit" }, "executablePaths": [] }, - { "id": "context-kit-app", "type": "directory", "sourcePath": "apps/context-kit", "target": { "root": "agent_apps", "path": "context-kit" }, "executablePaths": [] } + { + "id": "context-kit-behavior", + "type": "package_instruction", + "sourcePath": "instructions/behavior.md" + }, + { + "id": "context-kit-state", + "type": "file", + "sourcePath": "brain/context-kit/context-kit-state.json", + "target": { + "root": "agent_brain", + "path": "context-kit/context-kit-state.json" + }, + "executable": false + }, + { + "id": "legal-compliance", + "type": "file", + "sourcePath": "brain/context-kit/legal-compliance.md", + "target": { + "root": "agent_brain", + "path": "context-kit/legal-compliance.md" + }, + "executable": false + }, + { + "id": "source-of-truth", + "type": "file", + "sourcePath": "brain/context-kit/source-of-truth.md", + "target": { + "root": "agent_brain", + "path": "context-kit/source-of-truth.md" + }, + "executable": false + }, + { + "id": "guardrails", + "type": "file", + "sourcePath": "brain/context-kit/guardrails.md", + "target": { + "root": "agent_brain", + "path": "context-kit/guardrails.md" + }, + "executable": false + }, + { + "id": "briefing-template", + "type": "file", + "sourcePath": "brain/context-kit/briefing-template.md", + "target": { + "root": "agent_brain", + "path": "context-kit/briefing-template.md" + }, + "executable": false + }, + { + "id": "context-kit-skill", + "type": "directory", + "sourcePath": "skills", + "target": { + "root": "agent_skills", + "path": "context-kit" + }, + "executablePaths": [] + }, + { + "id": "context-kit-app", + "type": "directory", + "sourcePath": "apps/context-kit", + "target": { + "root": "agent_apps", + "path": "context-kit" + }, + "executablePaths": [] + } ] } diff --git a/packages/context-kit/skills/SKILL.md b/packages/context-kit/skills/SKILL.md index 64c606c..aacce68 100644 --- a/packages/context-kit/skills/SKILL.md +++ b/packages/context-kit/skills/SKILL.md @@ -1,67 +1,86 @@ --- name: context-kit -description: Builds a customer's Context Kit, the institutional knowledge that makes every Runneth answer sharper. Reads the Context Kit state index, confirms what Motion already knows, imports what already lives in Google Drive or Notion, drafts what Runneth can research, and collects what only the customer knows, filling each into the brain and moving the completeness meter. Triggers on "build my context kit", "set up my context kit", "context kit", "build my brain", "sharpen Runneth", "what makes my answers better", "what do you still need from me", "what does Runneth know about us". +description: Builds a customer's Context Kit, the institutional knowledge that makes every Runneth answer sharper. Reads the Context Kit state index, confirms what Motion knows, drafts brand-context and every Bucket B item from Motion creative data before asking anything, imports what already lives in Google Drive or Notion, and collects what only the customer knows, filling each into the brain and moving the completeness meter. Triggers on "build my context kit", "set up my context kit", "context kit", "build my brain", "sharpen Runneth", "what makes my answers better", "what do you still need from me", "what does Runneth know about us". --- # Context Kit skill -Turn a fresh brain into a filled one, without the manual sales/CS back-and-forth. The Context Kit -board app is the mirror; this skill is the doer. Never write to `user.md`. Fill happens as deliberate -in-conversation brain writes. Always prefer importing what already exists over asking the customer to -retype it. +Turn a fresh brain into a filled one, without the manual sales/CS back-and-forth. The board app is the +mirror; this skill is the doer. Draft from Motion data first, then offer import, then collect. Never write +to `user.md`. Fill happens as deliberate in-conversation brain writes. + +## Single source of truth +Every one of the 12 files lives in `/agent/brain/context-kit/.md` and is mirrored to +`/agent/apps/context-kit/data/.md` so the board can fetch it. Do NOT scatter files into +`brand-audit/` or `templates/`. Item ids: brand-context, kpis-goal, spend-threshold, competitors, +products, positioning, voice, voc, legal (file legal-compliance.md), briefing-template, source-of-truth, +guardrails. ## Step 0 — Load state 1. Read `/agent/brain/context-kit/context-kit-state.json`. -2. Run `motion brand-context --data-query "summary"`, `motion workspace-goal`, `motion spend-threshold` - to hydrate the three Bucket A items with live values. -3. Check which context sources are connected (Google Drive, Notion) so import is offered when available. -4. Resolve the workspace slug for brand-audit paths. +2. Run `motion brand-context --data-query "summary"`, `motion workspace-goal`, `motion spend-threshold`. +3. Note which context sources are connected (Google Drive, Notion). ## Step 1 — Build and open the board (first run only) -Package sync stages files but does NOT build the app. On first run: -1. Fill the bundled manifest: in `/agent/apps/context-kit/buildeth.app.json`, replace `__CONVERSATION_ID__` - with the current conversation id and `__WORKSPACE_ID__` with the current workspace id. The rest of the - v3 manifest (oauthEnabled, data dir, static dist/index) and `astro.config.mjs` (base `/context-kit`) - ship in the package, so no trial-and-error is needed. -2. Run `app build context-kit`, then `app list` for the verified URL. Hand the URL back. Never invent it. -3. After the first build, the board reads `data/` at runtime (client-side fetch), so later state/content - updates show on refresh with NO rebuild. Only rebuild if you change the app source itself. +Sync stages files but does not build apps. Fill `/agent/apps/context-kit/buildeth.app.json` (replace +`__CONVERSATION_ID__` and `__WORKSPACE_ID__` with current context), run `app build context-kit`, then +`app list` for the URL. `astro.config.mjs` ships in the package. After first build the board reads `data/` +at runtime, so later content/state changes need NO rebuild. + +## Step 2 — Bucket A: confirm, and auto-draft brand-context +- **kpis-goal, spend-threshold:** show the live Motion value, one-tap confirm, write the full doc, set the + `preview` string in state, mark `confirmed`. +- **brand-context (auto-draft, never ask from scratch):** + 1. If `motion brand-context` returns content, show it and ask to confirm. + 2. If empty, say: "I don't have brand context saved yet, I'll draft it from your top-performing ad creative now." + 3. Pull top spend creative: `motion meta insights --date-range last_30d --sort topSpend --include-metrics` + (+ TikTok if connected). Read hooks, primary text, headlines, summaries. + 4. Draft `brand-context.md` as the FOUNDATION only: brand name, origin story, positioning statement, + product description, proof points, a 2-sentence tone summary, a 2-sentence audience summary. Do not + duplicate the full voice/VoC/competitor detail (those are their own files). + 5. Present the draft, ask to confirm, then write `/agent/brain/context-kit/brand-context.md`, save to + workspace config, mirror to `data/brand-context.md`, mark `confirmed`. -## Step 2 — Bucket A: confirm (fast) + write the full working doc -For brand-context, kpis-goal, spend-threshold: show the live value plainly and ask a one-tap confirm. -On confirm: set the item `confirmed`, set its `preview` string in the state index (short human summary -for the card), and write the full working document. `brand-context.md` (#10) is the *foundation only*: -brand name, story, positioning statement, product description, proof points, and a 2-sentence tone/audience -summary. Do NOT concatenate the Bucket B detail into it. Do not re-collect what Motion already holds. +## Step 3 — Proactive import offer +After state load, if any Bucket B/C item is missing AND Google Drive or Notion is connected, proactively +say: "I can see you have [Drive/Notion] connected, want me to search there first before drafting from +scratch?" If they say yes, search, confirm the doc, import into `/agent/brain/context-kit/.md`, mirror +to `data/`, mark `imported`. Lean on existing context-sweep / integration skills for the pull. -## Step 3 — Import mode (try before drafting or asking, for every remaining item) -Ask: "Do you already have this in Google Drive or Notion?" If connected, search for the relevant doc, -confirm it, import into the correct brain path, set `imported` then `confirmed`. If not connected, offer -the native connect flow first. Only fall through to draft/write-in if they decline or don't have it. Lean -on existing context-sweep / integration skills for the search + pull. +## Step 4 — Bucket B: draft from Motion creative data first, then correct +For each item, attempt a Motion-backed draft BEFORE import or manual collection. A rough draft the user can +react to beats a blank prompt. Write full working docs to `/agent/brain/context-kit/.md`, mirror to +`data/.md`, set `drafted` (then `confirmed` on accept), and tell the user +"I drafted [item] from your Motion data, click the card to review or tell me what to change." -## Step 4 — Bucket B: draft rich, then confirm, then mirror to the board -For competitors, products, positioning, voice, voice-of-customer: run the matching skill (product-catalog, -competitor-analysis, brand-audit strategy/review passes, Inspo followed brands + boards for competitors). -Write FULL working documents into `/agent/brain/brand-audit//` (#9): competitor tone/audience/ -positioning breakdowns, complete product feature lists, full personas with motivations and objections, all -voice-of-customer quotes and patterns. Thin summaries fail here. Then: -- set status `drafted` (customer reviews) then `confirmed` on accept. -- MIRROR each file into `/agent/apps/context-kit/data/.md` (competitors.md, products.md, - positioning.md, voice.md, voc.md) so the board's click-to-expand can fetch it at runtime. +- **competitors:** `motion inspo brands` (followed brands), then `motion inspo unique-creatives --brand-id + --sort-by impressionRank` per brand. Summarize who they are, what angles they run, what they + emphasize. Ask the user to add anyone missing. +- **products:** top spend creative via `motion meta insights` with summaries + glossary tags. Compile the + product list from repeated hero claims / SKU callouts / bundles, note claims per product. Ask the user to + add pricing, SKU codes, and anything not in copy. +- **positioning:** `motion meta insights --include-glossary`. Read intended-audience, messaging-angle, and + hook-tactic tag distribution; combine with hook language to draft positioning + personas. Flag assumptions. +- **voice:** hooks, primary text, and summaries of the top 20-30 by spend. Synthesize 4-6 named voice + characteristics, each with a "sounds like / doesn't sound like" pair. Should feel recognizable to a brand writer. +- **voc:** top spend VIDEO creative with `--include-transcript`. Extract the most repeated real customer + phrases, emotional beats, outcome language; supplement with static hooks. Group by problem language, + outcome language, objections, social proof. +- If a pull returns too little (no followed brands, no transcripts), say what was missing and fall through to + import or manual for that item only. Never silently skip. ## Step 5 — Bucket C: collect with depth -For legal, briefing-template, source-of-truth, guardrails: file drop when they have the doc, thought -starters when stuck, one prompt when short. Prompt for the COMPLETE rule set, not a one-liner (#9). Write -into the scaffold file, fully populating the `## Your answers` section. Mark `confirmed`. +legal, briefing-template, source-of-truth, guardrails: file drop when they have it, thought starters when +stuck, one prompt when short. Prompt for the COMPLETE rule set, not a one-liner. Write to +`/agent/brain/context-kit/.md` (legal -> legal-compliance.md), mirror to `data/`, mark `confirmed`. ## Step 6 — Keep the map correct -- After each item is filled with real content, add or refresh its `/agent/INDEX.md` entry. -- Update `/agent/brain/context-kit/context-kit-state.json` AND the app's `data/context-kit-state.json` - after every change (the board reads the app copy). No rebuild needed for data-only changes. +- Refresh `/agent/INDEX.md` entries pointing to `/agent/brain/context-kit/` as the canonical home for all + Context Kit files. No separate entries for scattered originals. +- After every change update BOTH `/agent/brain/context-kit/context-kit-state.json` and the app's + `data/context-kit-state.json` (the board reads the app copy). No rebuild needed for data-only changes. ## Rules -- Never touch `user.md`. -- Never overwrite an already-filled file (create-if-absent, edit-in-place only on confirm). +- Never touch `user.md`. Never overwrite an already-filled file (create-if-absent, edit-in-place on confirm). - Plain, non-technical language with the customer. No file paths or JSON in chat. - One item at a time; celebrate the Level 3 unlock when the meter completes. From a92c989d4df2823a7d65b595848fd56a5f4f692a Mon Sep 17 00:00:00 2001 From: "Runneth (for Vamsi)" Date: Mon, 6 Jul 2026 09:38:11 -0400 Subject: [PATCH 05/16] =?UTF-8?q?feat(context-kit):=20v0.4.0=20=E2=80=94?= =?UTF-8?q?=20reshape=20voc=20as=20real=20customer-language=20research=20(?= =?UTF-8?q?review-audit=20+=20brand-relevant-keywords=20+=20web=20+=20Levi?= =?UTF-8?q?nger=20lived-context/trigger-moments),=20split=20brand=20voice?= =?UTF-8?q?=20from=20customer=20voice,=20add=20reviews-platform=20connect?= =?UTF-8?q?=20prompts=20+=20per-card=20enrich=20nudge?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-index.json | 4 +- .../context-kit/data/context-kit-state.json | 130 ++++++++++++++++-- .../context-kit/apps/context-kit/data/voc.md | 4 +- .../apps/context-kit/src/pages/index.astro | 21 +-- .../brain/context-kit/context-kit-state.json | 130 ++++++++++++++++-- packages/context-kit/package.json | 2 +- packages/context-kit/runneth-package.json | 2 +- packages/context-kit/skills/SKILL.md | 86 ++++++------ 8 files changed, 295 insertions(+), 84 deletions(-) diff --git a/package-index.json b/package-index.json index 466b3ff..ce081490 100644 --- a/package-index.json +++ b/package-index.json @@ -1,12 +1,12 @@ { "schemaVersion": 1, - "indexRevision": "context-kit-0.3.0", + "indexRevision": "context-kit-0.4.0", "packages": [ { "id": "context-kit", "name": "Context Kit", "description": "Builds the institutional knowledge that makes every Runneth answer sharper. Seeds a brain skeleton, a Context Kit board app, and the Context Kit skill that confirms what Motion knows, imports what already lives in Drive/Notion, researches what it can, and collects the rest.", - "version": "0.3.0", + "version": "0.4.0", "categories": ["baseline"], "packageManagerVersion": 1, "source": { diff --git a/packages/context-kit/apps/context-kit/data/context-kit-state.json b/packages/context-kit/apps/context-kit/data/context-kit-state.json index ffcbe39..f2078a4 100644 --- a/packages/context-kit/apps/context-kit/data/context-kit-state.json +++ b/packages/context-kit/apps/context-kit/data/context-kit-state.json @@ -1,22 +1,122 @@ { "version": 1, "levels": [ - { "id": "L1", "name": "Answers questions", "state": "passed" }, - { "id": "L2", "name": "On-brand outputs", "state": "current" }, - { "id": "L3", "name": "Runs with full context", "state": "locked" } + { + "id": "L1", + "name": "Answers questions", + "state": "passed" + }, + { + "id": "L2", + "name": "On-brand outputs", + "state": "current" + }, + { + "id": "L3", + "name": "Runs with full context", + "state": "locked" + } ], "items": [ - { "id": "brand-context", "label": "Brand context", "bucket": "A", "status": "inferred", "why": "Keeps every output unmistakably on-brand.", "preview": "", "dataFile": "brand-context.md" }, - { "id": "kpis-goal", "label": "KPIs & goal", "bucket": "A", "status": "inferred", "why": "Every readout leads with the metric you care about.", "preview": "", "dataFile": "kpis-goal.md" }, - { "id": "spend-threshold", "label": "Spend threshold", "bucket": "A", "status": "inferred", "why": "Separates a proven winner from early noise.", "preview": "", "dataFile": "spend-threshold.md" }, - { "id": "competitors", "label": "Competitors", "bucket": "B", "status": "missing", "why": "Angles to attack the gaps rivals leave open.", "dataFile": "competitors.md" }, - { "id": "products", "label": "Products & SKUs", "bucket": "B", "status": "missing", "why": "Grounds every ad in real product facts.", "dataFile": "products.md" }, - { "id": "positioning", "label": "Positioning & personas", "bucket": "B", "status": "missing", "why": "Right audience, right angle.", "dataFile": "positioning.md" }, - { "id": "voice", "label": "Voice & tone", "bucket": "B", "status": "missing", "why": "Copy that sounds like you wrote it.", "dataFile": "voice.md" }, - { "id": "voc", "label": "Voice-of-customer", "bucket": "B", "status": "missing", "why": "Real customer language for hooks.", "dataFile": "voc.md" }, - { "id": "legal", "label": "Legal & compliance", "bucket": "C", "status": "missing", "why": "Clears review on the first pass.", "dataFile": "legal-compliance.md" }, - { "id": "briefing-template", "label": "Briefing template", "bucket": "C", "status": "missing", "why": "Briefs come back in your exact format.", "dataFile": "briefing-template.md" }, - { "id": "source-of-truth", "label": "Source of truth", "bucket": "C", "status": "missing", "why": "Reports never fight your dashboard.", "dataFile": "source-of-truth.md" }, - { "id": "guardrails", "label": "Guardrails", "bucket": "C", "status": "missing", "why": "Always/never rules for creative.", "dataFile": "guardrails.md" } + { + "id": "brand-context", + "label": "Brand context", + "bucket": "A", + "status": "inferred", + "why": "Keeps every output unmistakably on-brand.", + "preview": "", + "dataFile": "brand-context.md" + }, + { + "id": "kpis-goal", + "label": "KPIs & goal", + "bucket": "A", + "status": "inferred", + "why": "Every readout leads with the metric you care about.", + "preview": "", + "dataFile": "kpis-goal.md" + }, + { + "id": "spend-threshold", + "label": "Spend threshold", + "bucket": "A", + "status": "inferred", + "why": "Separates a proven winner from early noise.", + "preview": "", + "dataFile": "spend-threshold.md" + }, + { + "id": "competitors", + "label": "Competitors", + "bucket": "B", + "status": "missing", + "why": "Angles to attack the gaps rivals leave open.", + "dataFile": "competitors.md" + }, + { + "id": "products", + "label": "Products & SKUs", + "bucket": "B", + "status": "missing", + "why": "Grounds every ad in real product facts.", + "dataFile": "products.md" + }, + { + "id": "positioning", + "label": "Positioning & personas", + "bucket": "B", + "status": "missing", + "why": "Right audience, right angle.", + "dataFile": "positioning.md" + }, + { + "id": "voice", + "label": "Voice & tone", + "bucket": "B", + "status": "missing", + "why": "Copy that sounds like you wrote it.", + "dataFile": "voice.md" + }, + { + "id": "voc", + "label": "Voice-of-customer", + "bucket": "B", + "status": "missing", + "why": "How your customers actually talk about the problem.", + "dataFile": "voc.md", + "enrich": "Enrich this by connecting your reviews platform (Yotpo, Okendo, Trustpilot) in chat. Real reviews are the richest source of customer language." + }, + { + "id": "legal", + "label": "Legal & compliance", + "bucket": "C", + "status": "missing", + "why": "Clears review on the first pass.", + "dataFile": "legal-compliance.md" + }, + { + "id": "briefing-template", + "label": "Briefing template", + "bucket": "C", + "status": "missing", + "why": "Briefs come back in your exact format.", + "dataFile": "briefing-template.md" + }, + { + "id": "source-of-truth", + "label": "Source of truth", + "bucket": "C", + "status": "missing", + "why": "Reports never fight your dashboard.", + "dataFile": "source-of-truth.md" + }, + { + "id": "guardrails", + "label": "Guardrails", + "bucket": "C", + "status": "missing", + "why": "Always/never rules for creative.", + "dataFile": "guardrails.md" + } ] } diff --git a/packages/context-kit/apps/context-kit/data/voc.md b/packages/context-kit/apps/context-kit/data/voc.md index ea505ed..4bcc1b8 100644 --- a/packages/context-kit/apps/context-kit/data/voc.md +++ b/packages/context-kit/apps/context-kit/data/voc.md @@ -1,3 +1,3 @@ -# voc +# Voice-of-customer -_Not filled in yet. Runneth mirrors this from /agent/brain/brand-audit// when the Context Kit skill drafts it._ +_Not filled in yet. This is how your customers actually talk about the problem, drawn from real reviews, Reddit, and social language, not your ad scripts. Connect your reviews platform in chat to make it much richer. Runneth writes this to /agent/brain/context-kit/voc.md and mirrors it here._ diff --git a/packages/context-kit/apps/context-kit/src/pages/index.astro b/packages/context-kit/apps/context-kit/src/pages/index.astro index ec08948..416a0ef 100644 --- a/packages/context-kit/apps/context-kit/src/pages/index.astro +++ b/packages/context-kit/apps/context-kit/src/pages/index.astro @@ -62,6 +62,8 @@ .card-panel h1,.card-panel h2,.card-panel h3{font-size:14px;margin:10px 0 4px} .card-panel p{margin:6px 0} .card-panel .empty{color:var(--muted);font-style:italic} + .card-panel .enrich{display:block;margin-top:10px;padding:9px 12px;border:1px dashed var(--sky);border-radius:8px;background:#eef7fb;color:#0b4a59;font-size:12.5px} + .card-panel .enrich strong{color:#0b4a59} .help-banner{display:flex;align-items:flex-start;gap:12px;margin-top:32px;padding:16px 20px;border:1px solid var(--border);border-radius:var(--r);background:var(--surface);font-size:14px;color:var(--ink);line-height:1.55} .help-banner .icon{font-size:18px;flex-shrink:0;margin-top:1px} @@ -103,25 +105,28 @@ if(item.bucket==="B") return "Runneth hasn't researched this yet. Say \"build my Context Kit\" in chat and Runneth will draft it for you."; return "Only you can answer this one. Say \"fill in my "+esc(item.label)+"\" in chat and Runneth will walk you through it."; } + function enrichHtml(item){ + return item.enrich ? "
\u2728 Tip: "+esc(item.enrich)+"
" : ""; + } async function loadPanel(item, panel){ const filled = ["confirmed","imported","drafted"].includes(item.status); const file = item.dataFile || (item.id+".md"); + let content; if(filled){ try{ const r = await fetch(BASE+"/data/"+file,{cache:"no-store"}); if(!r.ok) throw 0; const t = await r.text(); - panel.innerHTML = "

"+mdToHtml(t)+"

"; + content = "

"+mdToHtml(t)+"

"; }catch(e){ - panel.innerHTML = "

"+ (item.bucket==="B" ? "This file hasn't been saved yet. Say \"build my Context Kit\" in chat and Runneth will fill it in." : emptyMsg(item)) +"

"; + content = "

"+ (item.bucket==="B" ? "This file hasn't been saved yet. Say \"build my Context Kit\" in chat and Runneth will fill it in." : emptyMsg(item)) +"

"; } - return; - } - if(item.bucket==="A" && item.preview){ - panel.innerHTML = "

"+esc(item.preview)+"

"+emptyMsg(item)+"

"; - return; + } else if(item.bucket==="A" && item.preview){ + content = "

"+esc(item.preview)+"

"+emptyMsg(item)+"

"; + } else { + content = "

"+emptyMsg(item)+"

"; } - panel.innerHTML = "

"+emptyMsg(item)+"

"; + panel.innerHTML = content + enrichHtml(item); } function render(state){ const items = state.items || []; diff --git a/packages/context-kit/brain/context-kit/context-kit-state.json b/packages/context-kit/brain/context-kit/context-kit-state.json index ffcbe39..f2078a4 100644 --- a/packages/context-kit/brain/context-kit/context-kit-state.json +++ b/packages/context-kit/brain/context-kit/context-kit-state.json @@ -1,22 +1,122 @@ { "version": 1, "levels": [ - { "id": "L1", "name": "Answers questions", "state": "passed" }, - { "id": "L2", "name": "On-brand outputs", "state": "current" }, - { "id": "L3", "name": "Runs with full context", "state": "locked" } + { + "id": "L1", + "name": "Answers questions", + "state": "passed" + }, + { + "id": "L2", + "name": "On-brand outputs", + "state": "current" + }, + { + "id": "L3", + "name": "Runs with full context", + "state": "locked" + } ], "items": [ - { "id": "brand-context", "label": "Brand context", "bucket": "A", "status": "inferred", "why": "Keeps every output unmistakably on-brand.", "preview": "", "dataFile": "brand-context.md" }, - { "id": "kpis-goal", "label": "KPIs & goal", "bucket": "A", "status": "inferred", "why": "Every readout leads with the metric you care about.", "preview": "", "dataFile": "kpis-goal.md" }, - { "id": "spend-threshold", "label": "Spend threshold", "bucket": "A", "status": "inferred", "why": "Separates a proven winner from early noise.", "preview": "", "dataFile": "spend-threshold.md" }, - { "id": "competitors", "label": "Competitors", "bucket": "B", "status": "missing", "why": "Angles to attack the gaps rivals leave open.", "dataFile": "competitors.md" }, - { "id": "products", "label": "Products & SKUs", "bucket": "B", "status": "missing", "why": "Grounds every ad in real product facts.", "dataFile": "products.md" }, - { "id": "positioning", "label": "Positioning & personas", "bucket": "B", "status": "missing", "why": "Right audience, right angle.", "dataFile": "positioning.md" }, - { "id": "voice", "label": "Voice & tone", "bucket": "B", "status": "missing", "why": "Copy that sounds like you wrote it.", "dataFile": "voice.md" }, - { "id": "voc", "label": "Voice-of-customer", "bucket": "B", "status": "missing", "why": "Real customer language for hooks.", "dataFile": "voc.md" }, - { "id": "legal", "label": "Legal & compliance", "bucket": "C", "status": "missing", "why": "Clears review on the first pass.", "dataFile": "legal-compliance.md" }, - { "id": "briefing-template", "label": "Briefing template", "bucket": "C", "status": "missing", "why": "Briefs come back in your exact format.", "dataFile": "briefing-template.md" }, - { "id": "source-of-truth", "label": "Source of truth", "bucket": "C", "status": "missing", "why": "Reports never fight your dashboard.", "dataFile": "source-of-truth.md" }, - { "id": "guardrails", "label": "Guardrails", "bucket": "C", "status": "missing", "why": "Always/never rules for creative.", "dataFile": "guardrails.md" } + { + "id": "brand-context", + "label": "Brand context", + "bucket": "A", + "status": "inferred", + "why": "Keeps every output unmistakably on-brand.", + "preview": "", + "dataFile": "brand-context.md" + }, + { + "id": "kpis-goal", + "label": "KPIs & goal", + "bucket": "A", + "status": "inferred", + "why": "Every readout leads with the metric you care about.", + "preview": "", + "dataFile": "kpis-goal.md" + }, + { + "id": "spend-threshold", + "label": "Spend threshold", + "bucket": "A", + "status": "inferred", + "why": "Separates a proven winner from early noise.", + "preview": "", + "dataFile": "spend-threshold.md" + }, + { + "id": "competitors", + "label": "Competitors", + "bucket": "B", + "status": "missing", + "why": "Angles to attack the gaps rivals leave open.", + "dataFile": "competitors.md" + }, + { + "id": "products", + "label": "Products & SKUs", + "bucket": "B", + "status": "missing", + "why": "Grounds every ad in real product facts.", + "dataFile": "products.md" + }, + { + "id": "positioning", + "label": "Positioning & personas", + "bucket": "B", + "status": "missing", + "why": "Right audience, right angle.", + "dataFile": "positioning.md" + }, + { + "id": "voice", + "label": "Voice & tone", + "bucket": "B", + "status": "missing", + "why": "Copy that sounds like you wrote it.", + "dataFile": "voice.md" + }, + { + "id": "voc", + "label": "Voice-of-customer", + "bucket": "B", + "status": "missing", + "why": "How your customers actually talk about the problem.", + "dataFile": "voc.md", + "enrich": "Enrich this by connecting your reviews platform (Yotpo, Okendo, Trustpilot) in chat. Real reviews are the richest source of customer language." + }, + { + "id": "legal", + "label": "Legal & compliance", + "bucket": "C", + "status": "missing", + "why": "Clears review on the first pass.", + "dataFile": "legal-compliance.md" + }, + { + "id": "briefing-template", + "label": "Briefing template", + "bucket": "C", + "status": "missing", + "why": "Briefs come back in your exact format.", + "dataFile": "briefing-template.md" + }, + { + "id": "source-of-truth", + "label": "Source of truth", + "bucket": "C", + "status": "missing", + "why": "Reports never fight your dashboard.", + "dataFile": "source-of-truth.md" + }, + { + "id": "guardrails", + "label": "Guardrails", + "bucket": "C", + "status": "missing", + "why": "Always/never rules for creative.", + "dataFile": "guardrails.md" + } ] } diff --git a/packages/context-kit/package.json b/packages/context-kit/package.json index 26457f1..decb779 100644 --- a/packages/context-kit/package.json +++ b/packages/context-kit/package.json @@ -3,7 +3,7 @@ "id": "context-kit", "name": "Context Kit", "description": "Builds the institutional knowledge that makes every Runneth answer sharper. Seeds a brain skeleton, a Context Kit board app, and the Context Kit skill that confirms what Motion knows, imports what already lives in Drive/Notion, researches what it can, and collects the rest.", - "version": "0.3.0", + "version": "0.4.0", "installPolicy": "manual", "updatePolicy": "manual", "uninstallPolicy": "allowed", diff --git a/packages/context-kit/runneth-package.json b/packages/context-kit/runneth-package.json index ccd54ea..8ca60de 100644 --- a/packages/context-kit/runneth-package.json +++ b/packages/context-kit/runneth-package.json @@ -3,7 +3,7 @@ "id": "context-kit", "name": "Context Kit", "description": "Builds the institutional knowledge that makes every Runneth answer sharper. Seeds a brain skeleton, a Context Kit board app, and the Context Kit skill that confirms what Motion knows, imports what already lives in Drive/Notion, researches what it can, and collects the rest.", - "version": "0.3.0", + "version": "0.4.0", "updatePolicy": "manual", "uninstallPolicy": "allowed", "resources": [ diff --git a/packages/context-kit/skills/SKILL.md b/packages/context-kit/skills/SKILL.md index aacce68..5aba8a5 100644 --- a/packages/context-kit/skills/SKILL.md +++ b/packages/context-kit/skills/SKILL.md @@ -1,6 +1,6 @@ --- name: context-kit -description: Builds a customer's Context Kit, the institutional knowledge that makes every Runneth answer sharper. Reads the Context Kit state index, confirms what Motion knows, drafts brand-context and every Bucket B item from Motion creative data before asking anything, imports what already lives in Google Drive or Notion, and collects what only the customer knows, filling each into the brain and moving the completeness meter. Triggers on "build my context kit", "set up my context kit", "context kit", "build my brain", "sharpen Runneth", "what makes my answers better", "what do you still need from me", "what does Runneth know about us". +description: Builds a customer's Context Kit, the institutional knowledge that makes every Runneth answer sharper. Reads the Context Kit state index, confirms what Motion knows, drafts brand-context and every Bucket B item from Motion creative data before asking anything, imports what already lives in Google Drive or Notion, researches real customer language for voice-of-customer, and collects what only the customer knows, filling each into the brain and moving the completeness meter. Triggers on "build my context kit", "set up my context kit", "context kit", "build my brain", "sharpen Runneth", "what makes my answers better", "what do you still need from me", "what does Runneth know about us". --- # Context Kit skill @@ -19,7 +19,7 @@ guardrails. ## Step 0 — Load state 1. Read `/agent/brain/context-kit/context-kit-state.json`. 2. Run `motion brand-context --data-query "summary"`, `motion workspace-goal`, `motion spend-threshold`. -3. Note which context sources are connected (Google Drive, Notion). +3. Note which context sources are connected (Google Drive, Notion, and any reviews platform). ## Step 1 — Build and open the board (first run only) Sync stages files but does not build apps. Fill `/agent/apps/context-kit/buildeth.app.json` (replace @@ -30,55 +30,61 @@ at runtime, so later content/state changes need NO rebuild. ## Step 2 — Bucket A: confirm, and auto-draft brand-context - **kpis-goal, spend-threshold:** show the live Motion value, one-tap confirm, write the full doc, set the `preview` string in state, mark `confirmed`. -- **brand-context (auto-draft, never ask from scratch):** - 1. If `motion brand-context` returns content, show it and ask to confirm. - 2. If empty, say: "I don't have brand context saved yet, I'll draft it from your top-performing ad creative now." - 3. Pull top spend creative: `motion meta insights --date-range last_30d --sort topSpend --include-metrics` - (+ TikTok if connected). Read hooks, primary text, headlines, summaries. - 4. Draft `brand-context.md` as the FOUNDATION only: brand name, origin story, positioning statement, - product description, proof points, a 2-sentence tone summary, a 2-sentence audience summary. Do not - duplicate the full voice/VoC/competitor detail (those are their own files). - 5. Present the draft, ask to confirm, then write `/agent/brain/context-kit/brand-context.md`, save to - workspace config, mirror to `data/brand-context.md`, mark `confirmed`. +- **brand-context (auto-draft, never ask from scratch):** if `motion brand-context` returns content, show it + and confirm; if empty, say you'll draft it from top-performing creative, pull + `motion meta insights --date-range last_30d --sort topSpend --include-metrics` (+ TikTok if connected), + and draft the FOUNDATION only (brand name, origin story, positioning statement, product description, proof + points, 2-sentence tone summary, 2-sentence audience summary). Present, confirm, write, save to workspace + config, mirror to `data/`, mark `confirmed`. Do not duplicate the voice/voc/competitor detail here. -## Step 3 — Proactive import offer -After state load, if any Bucket B/C item is missing AND Google Drive or Notion is connected, proactively -say: "I can see you have [Drive/Notion] connected, want me to search there first before drafting from -scratch?" If they say yes, search, confirm the doc, import into `/agent/brain/context-kit/.md`, mirror -to `data/`, mark `imported`. Lean on existing context-sweep / integration skills for the pull. +## Step 3 — Proactive import + connect offers +After state load, if any Bucket B/C item is missing: +- If Google Drive or Notion is connected: "I can see you have [Drive/Notion] connected, want me to search + there first before drafting from scratch?" +- If NO reviews platform is connected: proactively suggest it, because it powers the best voice-of-customer: + "Connecting your reviews platform (Yotpo, Okendo, Trustpilot, Amazon) gives me your real customer language, + the single richest input for hooks and angles. Want to connect it?" +Import confirmed docs into `/agent/brain/context-kit/.md`, mirror to `data/`, mark `imported`. Lean on +existing context-sweep / integration skills for the pull. -## Step 4 — Bucket B: draft from Motion creative data first, then correct -For each item, attempt a Motion-backed draft BEFORE import or manual collection. A rough draft the user can -react to beats a blank prompt. Write full working docs to `/agent/brain/context-kit/.md`, mirror to -`data/.md`, set `drafted` (then `confirmed` on accept), and tell the user -"I drafted [item] from your Motion data, click the card to review or tell me what to change." +## Step 4 — Bucket B: draft from real data first, then correct +For each item, attempt a data-backed draft BEFORE asking. Write full working docs to +`/agent/brain/context-kit/.md`, mirror to `data/.md`, set `drafted` (then `confirmed` on accept), and +tell the user "I drafted [item], click the card to review or tell me what to change." - **competitors:** `motion inspo brands` (followed brands), then `motion inspo unique-creatives --brand-id - --sort-by impressionRank` per brand. Summarize who they are, what angles they run, what they - emphasize. Ask the user to add anyone missing. -- **products:** top spend creative via `motion meta insights` with summaries + glossary tags. Compile the - product list from repeated hero claims / SKU callouts / bundles, note claims per product. Ask the user to - add pricing, SKU codes, and anything not in copy. + --sort-by impressionRank` per brand. Who they are, what angles they run, what they emphasize. +- **products:** top spend creative via `motion meta insights` with summaries + glossary tags. Product list + from repeated hero claims / SKU callouts / bundles. Ask user for pricing/SKU codes not in copy. - **positioning:** `motion meta insights --include-glossary`. Read intended-audience, messaging-angle, and - hook-tactic tag distribution; combine with hook language to draft positioning + personas. Flag assumptions. -- **voice:** hooks, primary text, and summaries of the top 20-30 by spend. Synthesize 4-6 named voice - characteristics, each with a "sounds like / doesn't sound like" pair. Should feel recognizable to a brand writer. -- **voc:** top spend VIDEO creative with `--include-transcript`. Extract the most repeated real customer - phrases, emotional beats, outcome language; supplement with static hooks. Group by problem language, - outcome language, objections, social proof. -- If a pull returns too little (no followed brands, no transcripts), say what was missing and fall through to - import or manual for that item only. Never silently skip. + hook-tactic tag distribution + hook language to draft positioning + personas. Flag assumptions. +- **voice (the BRAND's voice, not the customer's):** hooks, primary text, and summaries of the top 20-30 by + spend. Synthesize 4-6 named voice characteristics, each with a "sounds like / doesn't sound like" pair. + This is how the brand should write. +- **voc (voice-of-customer = how the CUSTOMER sounds, NOT the brand):** real, unfiltered customer language. + Ad transcripts are the WEAKEST source (they are the brand's scripted version of the customer), so do not + rely on them. Draft it this way: + 1. If a reviews platform is connected, run the `review-audit` skill over the real reviews. + 2. Generate customer-language search terms with the `brand-relevant-keywords` skill (search the customer's + problem, not the brand name), then web-research Reddit, review sites, and social comments for real quotes. + 3. Use Motion video transcripts (`--include-transcript`) only as a supplement, labeled as ad-mediated + (best for UGC/testimonial phrasing). + Layer in the lived-context frame (Sarah Levinger): which generation, what shaped their trust, and 5-10 + trigger moments (specific everyday situations where the problem fires) with the emotion attached to each. + Output a swipe file in 7 categories, near-verbatim: pain points, emotional language, desire statements, + before/after arcs, objections, competitor complaints, trigger events. If no reviews platform is connected, + say so and suggest connecting one, then proceed with web research and transcripts. +- If a pull returns too little, say what was missing and fall through to import or manual for that item only. ## Step 5 — Bucket C: collect with depth legal, briefing-template, source-of-truth, guardrails: file drop when they have it, thought starters when -stuck, one prompt when short. Prompt for the COMPLETE rule set, not a one-liner. Write to -`/agent/brain/context-kit/.md` (legal -> legal-compliance.md), mirror to `data/`, mark `confirmed`. +stuck, one prompt when short. Prompt for the COMPLETE rule set. Write to `/agent/brain/context-kit/.md` +(legal -> legal-compliance.md), mirror to `data/`, mark `confirmed`. ## Step 6 — Keep the map correct -- Refresh `/agent/INDEX.md` entries pointing to `/agent/brain/context-kit/` as the canonical home for all - Context Kit files. No separate entries for scattered originals. +- Refresh `/agent/INDEX.md` entries pointing to `/agent/brain/context-kit/` as the canonical home. - After every change update BOTH `/agent/brain/context-kit/context-kit-state.json` and the app's - `data/context-kit-state.json` (the board reads the app copy). No rebuild needed for data-only changes. + `data/context-kit-state.json`. No rebuild needed for data-only changes. ## Rules - Never touch `user.md`. Never overwrite an already-filled file (create-if-absent, edit-in-place on confirm). From 2f3e45923c8edbb6f55069bf888c08cd41f821e6 Mon Sep 17 00:00:00 2001 From: "Runneth (for Vamsi)" Date: Mon, 6 Jul 2026 12:15:09 -0400 Subject: [PATCH 06/16] =?UTF-8?q?feat(context-kit):=20v0.5.0=20=E2=80=94?= =?UTF-8?q?=20glossary-tag=20spine=20+=20explicit=20fallback=20chain=20(dr?= =?UTF-8?q?afted=20vs=20inferred=20+=20sourceNote),=20board=20chrome=20red?= =?UTF-8?q?esign=20(brand-name=20title,=20compact=20nudge,=20numbered=20pa?= =?UTF-8?q?th=20+=20pips,=20butter=20color,=20unified=20View=20CTA),=20ful?= =?UTF-8?q?l=20markdown=20renderer,=20thoughtStarters=20+=20more=20enrich?= =?UTF-8?q?=20tips,=20bucket=20icons?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-index.json | 4 +- .../context-kit/data/context-kit-state.json | 131 ++---------- .../apps/context-kit/src/pages/index.astro | 192 +++++++++++------- .../brain/context-kit/context-kit-state.json | 131 ++---------- packages/context-kit/package.json | 2 +- packages/context-kit/runneth-package.json | 2 +- packages/context-kit/skills/SKILL.md | 119 ++++++----- 7 files changed, 220 insertions(+), 361 deletions(-) diff --git a/package-index.json b/package-index.json index ce081490..286c212 100644 --- a/package-index.json +++ b/package-index.json @@ -1,12 +1,12 @@ { "schemaVersion": 1, - "indexRevision": "context-kit-0.4.0", + "indexRevision": "context-kit-0.5.0", "packages": [ { "id": "context-kit", "name": "Context Kit", "description": "Builds the institutional knowledge that makes every Runneth answer sharper. Seeds a brain skeleton, a Context Kit board app, and the Context Kit skill that confirms what Motion knows, imports what already lives in Drive/Notion, researches what it can, and collects the rest.", - "version": "0.4.0", + "version": "0.5.0", "categories": ["baseline"], "packageManagerVersion": 1, "source": { diff --git a/packages/context-kit/apps/context-kit/data/context-kit-state.json b/packages/context-kit/apps/context-kit/data/context-kit-state.json index f2078a4..d9471b1 100644 --- a/packages/context-kit/apps/context-kit/data/context-kit-state.json +++ b/packages/context-kit/apps/context-kit/data/context-kit-state.json @@ -1,122 +1,23 @@ { "version": 1, + "brandName": "", "levels": [ - { - "id": "L1", - "name": "Answers questions", - "state": "passed" - }, - { - "id": "L2", - "name": "On-brand outputs", - "state": "current" - }, - { - "id": "L3", - "name": "Runs with full context", - "state": "locked" - } + { "id": "L1", "name": "Answers questions", "state": "passed" }, + { "id": "L2", "name": "On-brand outputs", "state": "current" }, + { "id": "L3", "name": "Runs with full context", "state": "locked" } ], "items": [ - { - "id": "brand-context", - "label": "Brand context", - "bucket": "A", - "status": "inferred", - "why": "Keeps every output unmistakably on-brand.", - "preview": "", - "dataFile": "brand-context.md" - }, - { - "id": "kpis-goal", - "label": "KPIs & goal", - "bucket": "A", - "status": "inferred", - "why": "Every readout leads with the metric you care about.", - "preview": "", - "dataFile": "kpis-goal.md" - }, - { - "id": "spend-threshold", - "label": "Spend threshold", - "bucket": "A", - "status": "inferred", - "why": "Separates a proven winner from early noise.", - "preview": "", - "dataFile": "spend-threshold.md" - }, - { - "id": "competitors", - "label": "Competitors", - "bucket": "B", - "status": "missing", - "why": "Angles to attack the gaps rivals leave open.", - "dataFile": "competitors.md" - }, - { - "id": "products", - "label": "Products & SKUs", - "bucket": "B", - "status": "missing", - "why": "Grounds every ad in real product facts.", - "dataFile": "products.md" - }, - { - "id": "positioning", - "label": "Positioning & personas", - "bucket": "B", - "status": "missing", - "why": "Right audience, right angle.", - "dataFile": "positioning.md" - }, - { - "id": "voice", - "label": "Voice & tone", - "bucket": "B", - "status": "missing", - "why": "Copy that sounds like you wrote it.", - "dataFile": "voice.md" - }, - { - "id": "voc", - "label": "Voice-of-customer", - "bucket": "B", - "status": "missing", - "why": "How your customers actually talk about the problem.", - "dataFile": "voc.md", - "enrich": "Enrich this by connecting your reviews platform (Yotpo, Okendo, Trustpilot) in chat. Real reviews are the richest source of customer language." - }, - { - "id": "legal", - "label": "Legal & compliance", - "bucket": "C", - "status": "missing", - "why": "Clears review on the first pass.", - "dataFile": "legal-compliance.md" - }, - { - "id": "briefing-template", - "label": "Briefing template", - "bucket": "C", - "status": "missing", - "why": "Briefs come back in your exact format.", - "dataFile": "briefing-template.md" - }, - { - "id": "source-of-truth", - "label": "Source of truth", - "bucket": "C", - "status": "missing", - "why": "Reports never fight your dashboard.", - "dataFile": "source-of-truth.md" - }, - { - "id": "guardrails", - "label": "Guardrails", - "bucket": "C", - "status": "missing", - "why": "Always/never rules for creative.", - "dataFile": "guardrails.md" - } + { "id": "brand-context", "label": "Brand context", "bucket": "A", "status": "inferred", "why": "Keeps every output unmistakably on-brand.", "preview": "", "dataFile": "brand-context.md" }, + { "id": "kpis-goal", "label": "KPIs & goal", "bucket": "A", "status": "inferred", "why": "Every readout leads with the metric you care about.", "preview": "", "dataFile": "kpis-goal.md" }, + { "id": "spend-threshold", "label": "Spend threshold", "bucket": "A", "status": "inferred", "why": "Separates a proven winner from early noise.", "preview": "", "dataFile": "spend-threshold.md" }, + { "id": "competitors", "label": "Competitors", "bucket": "B", "status": "missing", "why": "Angles to attack the gaps rivals leave open.", "dataFile": "competitors.md", "enrich": "Follow brands in Motion Inspo so Runneth can research their live ads and creative angles automatically." }, + { "id": "products", "label": "Products & SKUs", "bucket": "B", "status": "missing", "why": "Grounds every ad in real product facts.", "dataFile": "products.md", "enrich": "Connect your Shopify store for live product data, pricing, and bestseller rankings." }, + { "id": "positioning", "label": "Positioning & personas", "bucket": "B", "status": "missing", "why": "Right audience, right angle.", "dataFile": "positioning.md" }, + { "id": "voice", "label": "Voice & tone", "bucket": "B", "status": "missing", "why": "Copy that sounds like you wrote it.", "dataFile": "voice.md" }, + { "id": "voc", "label": "Voice-of-customer", "bucket": "B", "status": "missing", "why": "How your customers actually talk about the problem.", "dataFile": "voc.md", "enrich": "Connect your reviews platform (Yotpo, Okendo, Trustpilot) for real customer language, the richest VoC source available." }, + { "id": "legal", "label": "Legal & compliance", "bucket": "C", "status": "missing", "why": "Clears review on the first pass.", "dataFile": "legal-compliance.md", "thoughtStarters": ["Any claims you legally can't make? (clinically proven, #1, cures, guaranteed)", "Required disclaimers or fine print on specific claims?", "Regulated categories that apply? (health, finance, beauty, supplements, kids)", "Words or comparisons legal has flagged before?"] }, + { "id": "briefing-template", "label": "Briefing template", "bucket": "C", "status": "missing", "why": "Briefs come back in your exact format.", "dataFile": "briefing-template.md", "thoughtStarters": ["Do you have an existing brief format you want matched? Drop it in chat.", "What sections does every brief need? (hook, angle, format, CTA)", "Who reads the brief, and what do they need from it?"] }, + { "id": "source-of-truth", "label": "Source of truth", "bucket": "C", "status": "missing", "why": "Reports never fight your dashboard.", "dataFile": "source-of-truth.md", "enrich": "Connect your attribution platform (Northbeam, Triple Whale, or similar) so Runneth always reports from your preferred source.", "thoughtStarters": ["When the ad platform and your attribution tool disagree, which wins?", "What's your primary success metric and attribution window?", "Any metric you explicitly don't trust or want ignored?", "Which dashboard does your team review in meetings?"] }, + { "id": "guardrails", "label": "Guardrails", "bucket": "C", "status": "missing", "why": "Always/never rules for creative.", "dataFile": "guardrails.md", "thoughtStarters": ["What should Runneth NEVER suggest in a creative concept?", "Any visual styles or creative directions that are always off-limits?", "Non-negotiables for claims, tone, or offers?", "Any past ad types or messages to avoid repeating?"] } ] } diff --git a/packages/context-kit/apps/context-kit/src/pages/index.astro b/packages/context-kit/apps/context-kit/src/pages/index.astro index 416a0ef..9bdc736 100644 --- a/packages/context-kit/apps/context-kit/src/pages/index.astro +++ b/packages/context-kit/apps/context-kit/src/pages/index.astro @@ -10,43 +10,48 @@
- Context Kit -

Your Context Kit

-

The more Runneth knows about your brand, the sharper every answer. Confirm what we pulled, review what we drafted, add the few things only you know. Click any card to see what's saved.

-

📄 Already have brand docs in Google Drive or Notion? Connect them in chat and Runneth can pull from them directly.

+

Context Kit

+

The more Runneth knows about your brand, the sharper every answer. Confirm what we pulled, review what we drafted, add the few things only you know.

+
+
🔗
+
+
Import from Google Drive or Notion
+
Connect them in chat and Runneth can pull your brand docs directly.
+
+
💡 @@ -83,30 +106,52 @@ diff --git a/packages/context-kit/brain/context-kit/context-kit-state.json b/packages/context-kit/brain/context-kit/context-kit-state.json index 79ce294..18d2c3d 100644 --- a/packages/context-kit/brain/context-kit/context-kit-state.json +++ b/packages/context-kit/brain/context-kit/context-kit-state.json @@ -144,6 +144,62 @@ "Non-negotiables for claims, tone, or offers?", "Any past ad types or messages to avoid repeating?" ] + }, + { + "id": "integration-ad-platform", + "label": "Ad platform", + "bucket": "D", + "status": "missing", + "why": "How you want Runneth to read your ad data.", + "dataFile": "integrations/ad-platform.md", + "enrich": "Connect your ad platform (Meta, TikTok) so Runneth can draft this from your live account.", + "thoughtStarters": [ + "Which metric should Runneth grade on?", + "Any spend floor before a result counts?", + "Campaigns that are always-on and shouldn't be flagged as new?" + ] + }, + { + "id": "integration-asset-library", + "label": "Asset library", + "bucket": "D", + "status": "missing", + "why": "Which assets Runneth can safely use.", + "dataFile": "integrations/asset-library.md", + "enrich": "Connect your asset library (Google Drive, a DAM) so Runneth pulls only approved, brand-safe assets.", + "thoughtStarters": [ + "Which folder holds cleared, approved assets?", + "What's off-limits (WIP, legal review)?", + "How do you mark a final, shippable version?" + ] + }, + { + "id": "integration-data-warehouse", + "label": "Data warehouse", + "bucket": "D", + "status": "missing", + "why": "How Runneth should read your warehouse.", + "dataFile": "integrations/data-warehouse.md", + "enrich": "Connect your warehouse (Snowflake, BigQuery) for blended reporting Runneth can reconcile against.", + "thoughtStarters": [ + "Which table is the source of truth for revenue?", + "Net or gross of fees?", + "What should Runneth NOT pull from here?" + ] + }, + { + "id": "integration-reviews", + "label": "Reviews platform", + "bucket": "D", + "status": "missing", + "why": "How Runneth should use your reviews.", + "dataFile": "integrations/reviews.md", + "enrich": "Connect your reviews platform (Yotpo, Okendo, Trustpilot) so Runneth mines real customer language.", + "thoughtStarters": [ + "Which products' reviews matter most?", + "Any themes you already know customers repeat?", + "Anything to exclude (spam, off-topic)?" + ] } ] } diff --git a/packages/context-kit/instructions/behavior.md b/packages/context-kit/instructions/behavior.md index 803d220..c515563 100644 --- a/packages/context-kit/instructions/behavior.md +++ b/packages/context-kit/instructions/behavior.md @@ -49,3 +49,17 @@ reads), not only when the Context Kit skill runs. entry. Never write to `user.md`. 3. Keep it to one offer per turn. This is a helpful nudge, not nagging. The goal is that Runneth visibly gets smarter about this brand the more it is used. + + +## Bucket A import contract (Auto-filled tab) + +The three Auto-filled items (brand-context, kpis-goal, spend-threshold) come from Motion but the customer can correct them. Store each as two sections so a correction survives a re-sync: + +- `## Latest Import From Motion` - the most recent value pulled from Motion. +- `## Runneth Instructions` - the customer's corrections and rules. + +When the two conflict, follow `Runneth Instructions` unless the customer explicitly chooses the Motion value, and say it plainly: "Motion currently says X, but your instructions say Y. I am using Y." A refresh updates only `Latest Import From Motion` and preserves `Runneth Instructions`. + +## Integration source guides (Your tools tab) + +Bucket D holds one guide per connected source: how THIS customer wants Runneth to use that tool, not what the tool can do. Files live at `/agent/brain/context-kit/integrations/.md`, mirrored to the board's `data/integrations/.md`. Create or fill a guide when the customer connects that source or gives rules for it; do not invent vendor-specific guides otherwise. Each guide covers: what it applies to, what to use it for, what to avoid, the customer's rules, and any open question. Before performance, reporting, or asset work that uses a connected source, read its guide first. Bucket D is tracked separately from the completeness meter, which measures brand knowledge only. diff --git a/packages/context-kit/package.json b/packages/context-kit/package.json index 17f357b..72234d7 100644 --- a/packages/context-kit/package.json +++ b/packages/context-kit/package.json @@ -3,7 +3,7 @@ "id": "context-kit", "name": "Context Kit", "description": "Builds the institutional knowledge that makes every Runneth answer sharper. Seeds a brain skeleton, a Context Kit board app, and the Context Kit skill that confirms what Motion knows, imports what already lives in Drive/Notion, researches what it can, and collects the rest.", - "version": "0.8.1", + "version": "0.9.0", "installPolicy": "manual", "updatePolicy": "manual", "uninstallPolicy": "allowed", diff --git a/packages/context-kit/runneth-package.json b/packages/context-kit/runneth-package.json index 47f47c1..f27afec 100644 --- a/packages/context-kit/runneth-package.json +++ b/packages/context-kit/runneth-package.json @@ -3,7 +3,7 @@ "id": "context-kit", "name": "Context Kit", "description": "Builds the institutional knowledge that makes every Runneth answer sharper. Seeds a brain skeleton, a Context Kit board app, and the Context Kit skill that confirms what Motion knows, imports what already lives in Drive/Notion, researches what it can, and collects the rest.", - "version": "0.8.1", + "version": "0.9.0", "updatePolicy": "manual", "uninstallPolicy": "allowed", "resources": [ diff --git a/packages/context-kit/skills/SKILL.md b/packages/context-kit/skills/SKILL.md index fc3dc8a..239c830 100644 --- a/packages/context-kit/skills/SKILL.md +++ b/packages/context-kit/skills/SKILL.md @@ -98,3 +98,13 @@ thoughtStarters when stuck, one prompt when short. Prompt for the COMPLETE rule - Plain, non-technical language with the customer. No file paths or JSON in chat. - One item at a time; celebrate the Level 3 unlock when the meter completes. - The self-improvement loop is ALWAYS ON (see the package instruction): on any creative-strategy turn, if a context-kit file was thin and you inferred, say so and offer once to capture the detail, then save it to the right file. Keep it to one in-chat offer, no persistent queue. + + +## Bucket A: two-section import contract +When writing brand-context, kpis-goal, and spend-threshold, use the durable import format so a Motion re-sync never wipes a customer correction: +- `## Latest Import From Motion` holds the current Motion value. +- `## Runneth Instructions` holds the customer's corrections and rules. +On conflict, follow `Runneth Instructions` and say so plainly. A refresh updates only the import section and preserves instructions. Confirming still moves the item to `confirmed`. + +## Bucket D: integration source guides (Your tools) +Bucket D is one card per connected source, capturing how the customer wants Runneth to USE that tool (not what it can do). Create-when-connected: when a customer connects a source or gives rules for it, write `/agent/brain/context-kit/integrations/.md`, mirror to `data/integrations/.md`, and set the item `confirmed` (or `imported` if pulled from an existing doc). Each guide answers: what it applies to (account/workspace/folder/table/brand), what to use it for, what to avoid, the customer's rules, and any open question. Leave the shipped generic scaffolds (ad-platform, asset-library, data-warehouse, reviews) `missing` with their thoughtStarters until the customer connects that source. Bucket D is excluded from the completeness meter. diff --git a/scripts/validate-runneth-package-index.mjs b/scripts/validate-runneth-package-index.mjs index eef87b7..48bf8c3 100644 --- a/scripts/validate-runneth-package-index.mjs +++ b/scripts/validate-runneth-package-index.mjs @@ -152,8 +152,14 @@ const assertPackageManifest = (manifest, label) => { `${label}.uninstallPolicy: invalid`, ) assert.ok(Array.isArray(manifest.resources), `${label}.resources: must be array`) + const resourceIds = new Set() manifest.resources.forEach((resource, index) => { assertPackageResource(resource, `${label}.resources[${index}]`) + assert.ok( + !resourceIds.has(resource.id), + `${label}.resources: duplicate resource id ${resource.id}`, + ) + resourceIds.add(resource.id) }) } From cdb611e2313cfeddf152463198addfb3fe2a5af8 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 20 Jul 2026 10:41:34 +0000 Subject: [PATCH 12/16] feat(context-kit): v1.0.0 brand knowledge refresh Co-authored-by: vamsi --- package-index.json | 6 +- .../brain/context-kit/business-team.md | 16 ++ .../brain/context-kit/landing-pages.md | 16 ++ .../brain/context-kit/media-buying.md | 20 ++ packages/context-kit/instructions/behavior.md | 88 +++--- packages/context-kit/package.json | 67 +++-- packages/context-kit/runneth-package.json | 44 ++- packages/context-kit/skills/SKILL.md | 189 ++++++------ .../workflows/context-kit-refresh.ts | 272 ++++++++++++++++++ 9 files changed, 553 insertions(+), 165 deletions(-) create mode 100755 packages/context-kit/brain/context-kit/business-team.md create mode 100755 packages/context-kit/brain/context-kit/landing-pages.md create mode 100755 packages/context-kit/brain/context-kit/media-buying.md create mode 100755 packages/context-kit/workflows/context-kit-refresh.ts diff --git a/package-index.json b/package-index.json index 27ac24c..9150891 100644 --- a/package-index.json +++ b/package-index.json @@ -1,12 +1,12 @@ { "schemaVersion": 1, - "indexRevision": "context-kit-0.9.0", + "indexRevision": "context-kit-1.0.0", "packages": [ { "id": "context-kit", "name": "Context Kit", - "description": "Builds the institutional knowledge that makes every Runneth answer sharper. Seeds a brain skeleton, a Context Kit board app, and the Context Kit skill that confirms what Motion knows, imports what already lives in Drive/Notion, researches what it can, and collects the rest.", - "version": "0.9.0", + "description": "Builds the brand knowledge that makes every Runneth answer sharper. Seeds a brain skeleton, a Context Kit board app, and the Context Kit skill. Install first.", + "version": "1.0.0", "categories": ["baseline"], "packageManagerVersion": 1, "source": { diff --git a/packages/context-kit/brain/context-kit/business-team.md b/packages/context-kit/brain/context-kit/business-team.md new file mode 100755 index 0000000..ce94a8a --- /dev/null +++ b/packages/context-kit/brain/context-kit/business-team.md @@ -0,0 +1,16 @@ +# Business & Team + +## Runneth Instructions + +_Fill this in so Runneth knows who is using it and how decisions get made._ + +--- + +**Thought starters:** +- Brand name and website URL. +- Who uses Runneth on the team, and what are their roles? +- Who makes the final call on creative concepts before they go into production? +- Who approves creative before launch? +- What is the typical launch cadence — how many new concepts per week/month? +- How are briefs delivered to creators or the production team (Notion, email, Slack)? +- Are there any external agencies or freelancers involved in creative production? diff --git a/packages/context-kit/brain/context-kit/landing-pages.md b/packages/context-kit/brain/context-kit/landing-pages.md new file mode 100755 index 0000000..783f2f0 --- /dev/null +++ b/packages/context-kit/brain/context-kit/landing-pages.md @@ -0,0 +1,16 @@ +# Landing Pages + +## Runneth Instructions + +_Fill this in so Runneth knows where ads send traffic and what is being optimized for._ + +--- + +**Thought starters:** +- What are the main landing page URLs you drive traffic to? +- What is each page optimized for (trial signup, demo booking, purchase, lead form)? +- Have you run any landing page tests? What did you learn? +- Which landing pages correlate with your strongest-performing creative? +- Are there any pages that consistently underperform despite strong creative? +- Do different audiences or funnels go to different pages? +- Are there pages you want Runneth to avoid recommending traffic to? diff --git a/packages/context-kit/brain/context-kit/media-buying.md b/packages/context-kit/brain/context-kit/media-buying.md new file mode 100755 index 0000000..785c09b --- /dev/null +++ b/packages/context-kit/brain/context-kit/media-buying.md @@ -0,0 +1,20 @@ +# Media Buying Model + +## Latest Import From Motion + +_Not yet populated. The skill will attempt to infer from campaign structure on first run._ + +## Runneth Instructions + +_Fill this in so Runneth knows how budget decisions are made._ + +--- + +**Thought starters:** +- What is the bid strategy (lowest cost, cost cap, target ROAS)? +- How is budget structured — CBO, ABO, or mixed? +- What is the testing budget per concept? +- What spend threshold does a creative need to reach before you make a call on it? +- What does the campaign architecture look like — how many campaigns, how are ad sets organized? +- How do you handle audience targeting — broad, interest, retargeting? +- How often does budget get redistributed between campaigns? diff --git a/packages/context-kit/instructions/behavior.md b/packages/context-kit/instructions/behavior.md index c515563..42b9106 100644 --- a/packages/context-kit/instructions/behavior.md +++ b/packages/context-kit/instructions/behavior.md @@ -1,65 +1,55 @@ # Context Kit package instructions -This package installs the Context Kit: the institutional knowledge that makes every Runneth answer -sharper. It seeds structured-but-empty scaffolds, a status index, the Context Kit board app, and the -Context Kit skill. These instructions are loaded as prompt context so Runneth knows the surface exists. +This package installs the Context Kit: brand knowledge that makes every Runneth answer sharper. It seeds structured-but-empty scaffolds, a status index, the Context Kit board app, and the Context Kit skill. -## What Runneth should know from moment one +Naming conventions, per-campaign KPI maps, and the Motion query contract are in the **ad-naming** companion package. Install Context Kit first, then ad-naming. -- There is a Context Kit board app at `agent_apps/context-kit`. Package sync stages files but does NOT - build apps. To build it: fill the bundled `buildeth.app.json` (replace `__CONVERSATION_ID__` and - `__WORKSPACE_ID__` with the current context), then `app build context-kit`. `astro.config.mjs` (base - `/context-kit`) ships with the package. -- The board is client-rendered: it fetches `data/context-kit-state.json` and the Bucket B `data/*.md` - files at runtime. Update those data files to change what the board shows. A rebuild is only needed for - app source changes, not content/state changes. -- State lives at `/agent/brain/context-kit/context-kit-state.json` (source of truth) and is mirrored to - `/agent/apps/context-kit/data/context-kit-state.json` (what the board reads). -- Write-in scaffolds: `/agent/brain/context-kit/` (legal-compliance.md, source-of-truth.md, guardrails.md) - and `/agent/brain/templates/briefing-template.md`. - -## Read-before-work rules (retrieval awareness) - -- Before creative work, read `/agent/brain/context-kit/legal-compliance.md` and - `/agent/brain/templates/briefing-template.md` if filled. -- Before performance/reporting, honor `/agent/brain/context-kit/source-of-truth.md`. -- Before customer-facing output, honor `/agent/brain/context-kit/guardrails.md`. -- Bucket B context lives in `/agent/brain/brand-audit//` and is covered by the creative-strategy - read-before-work rules. +## Knoweth lane model -## Rules +Context Kit registers three lanes on first run. The skill handles registration — do NOT use `user.md` guards. -- Never write Context Kit content into `user.md`. Fill happens as deliberate in-conversation brain writes. -- Prefer importing existing docs from Google Drive / Notion before asking the customer to type. -- Scaffolds are create-if-absent. Never overwrite a file a customer has already filled. -- As each item is filled, refresh its `/agent/INDEX.md` entry. Do not blind-overwrite `INDEX.md` from sync. +| Lane | What it injects | When it fires | +|---|---|---| +| `context-kit-core` | State, guardrails, legal, source-of-truth, briefing-template | Always | +| `context-kit-brand` | Brand-context, voice, voc, positioning, products, competitors | Creative, briefing, concept turns | +| `context-kit-performance` | KPIs-goal, spend-threshold | Performance and reporting turns | -## Self-improvement loop (always on, not just during onboarding) +If **ad-naming** is installed, it registers its own `ad-naming` lane covering the naming decoder, KPI map, and query contract. If **creative-corpus** is installed, it registers its own `creative-corpus` lane. Neither is owned or registered by this package. + +## What Runneth should know from moment one -This fires on EVERY creative-strategy turn (hooks, briefs, concepts, scripts, ad copy, performance -reads), not only when the Context Kit skill runs. +- Board app at `agent_apps/context-kit`. Package sync stages files but does NOT build apps. Build: fill `buildeth.app.json`, then `app build context-kit`. +- Board is client-rendered: fetches `data/context-kit-state.json` and `data/*.md` at runtime. Rebuild only needed for source changes, not content. +- State: `/agent/brain/context-kit/context-kit-state.json` (source of truth), mirrored to `data/context-kit-state.json`. +- Lanes: registered by the skill on first run. Check `lanesRegistered` in state. +- Refresh workflow: registered by the skill on first run. Check `refreshWorkflowId` in state. -1. Before answering, read the relevant `/agent/brain/context-kit/` files (per the read-before-work rules). -2. If a needed file was empty, thin, or you had to infer to answer well, then AFTER the answer: - - Say plainly what was missing and that you inferred it (don't hide it). - - Make ONE specific, low-friction offer to capture it, e.g. "I inferred your tone because your Voice - page is light. Want me to save your take so I nail it next time?" - - On yes: write the detail to the correct `/agent/brain/context-kit/.md`, mirror to the board's - `data/.md`, update `context-kit-state.json` (status + preview), and refresh the `/agent/INDEX.md` - entry. Never write to `user.md`. -3. Keep it to one offer per turn. This is a helpful nudge, not nagging. The goal is that Runneth visibly - gets smarter about this brand the more it is used. +## Self-improvement loop (always on) +Fires on every creative-strategy turn. -## Bucket A import contract (Auto-filled tab) +1. The relevant lane files are already injected. Use them. +2. If a needed file was empty or thin, AFTER the answer: + - Say plainly what was missing. + - Make ONE specific offer to capture it. + - On yes: write the file, mirror to `data/`, update state, refresh INDEX. +3. Keep it to one offer per turn. -The three Auto-filled items (brand-context, kpis-goal, spend-threshold) come from Motion but the customer can correct them. Store each as two sections so a correction survives a re-sync: +## Bucket A import contract -- `## Latest Import From Motion` - the most recent value pulled from Motion. -- `## Runneth Instructions` - the customer's corrections and rules. +Each Auto-filled item uses two sections: +- `## Latest Import From Motion` — most recent value from Motion. +- `## Runneth Instructions` — customer corrections and rules. -When the two conflict, follow `Runneth Instructions` unless the customer explicitly chooses the Motion value, and say it plainly: "Motion currently says X, but your instructions say Y. I am using Y." A refresh updates only `Latest Import From Motion` and preserves `Runneth Instructions`. +On conflict, follow `Runneth Instructions`. A refresh updates only `Latest Import From Motion`. -## Integration source guides (Your tools tab) +## Integration source guides (Your tools tab, Bucket D) + +Files at `/agent/brain/context-kit/integrations/.md`, mirrored to `data/integrations/.md`. The ad-platform guide (the account-specific Motion query contract) is provided by ad-naming when installed — do not create it here. Other guides use thoughtStarters until the customer connects that source. + +## Rules -Bucket D holds one guide per connected source: how THIS customer wants Runneth to use that tool, not what the tool can do. Files live at `/agent/brain/context-kit/integrations/.md`, mirrored to the board's `data/integrations/.md`. Create or fill a guide when the customer connects that source or gives rules for it; do not invent vendor-specific guides otherwise. Each guide covers: what it applies to, what to use it for, what to avoid, the customer's rules, and any open question. Before performance, reporting, or asset work that uses a connected source, read its guide first. Bucket D is tracked separately from the completeness meter, which measures brand knowledge only. +- Never write into `user.md`. +- Prefer importing from Drive/Notion before asking the customer to type. +- Scaffolds are create-if-absent. Never overwrite a file the customer has filled. +- Refresh INDEX.md as each item is filled. diff --git a/packages/context-kit/package.json b/packages/context-kit/package.json index 72234d7..dc07ff6 100644 --- a/packages/context-kit/package.json +++ b/packages/context-kit/package.json @@ -2,8 +2,8 @@ "schemaVersion": 1, "id": "context-kit", "name": "Context Kit", - "description": "Builds the institutional knowledge that makes every Runneth answer sharper. Seeds a brain skeleton, a Context Kit board app, and the Context Kit skill that confirms what Motion knows, imports what already lives in Drive/Notion, researches what it can, and collects the rest.", - "version": "0.9.0", + "description": "Builds the brand knowledge that makes every Runneth answer sharper. Seeds a brain skeleton, a Context Kit board app, and the Context Kit skill. Install first, then ad-naming for naming conventions and query contract, then creative-corpus for the full creative library.", + "version": "1.0.0", "installPolicy": "manual", "updatePolicy": "manual", "uninstallPolicy": "allowed", @@ -17,70 +17,77 @@ "id": "context-kit-state", "type": "file", "sourcePath": "brain/context-kit/context-kit-state.json", - "target": { - "root": "agent_brain", - "path": "context-kit/context-kit-state.json" - }, + "target": { "root": "agent_brain", "path": "context-kit/context-kit-state.json" }, "executable": false }, { "id": "legal-compliance", "type": "file", "sourcePath": "brain/context-kit/legal-compliance.md", - "target": { - "root": "agent_brain", - "path": "context-kit/legal-compliance.md" - }, + "target": { "root": "agent_brain", "path": "context-kit/legal-compliance.md" }, "executable": false }, { "id": "source-of-truth", "type": "file", "sourcePath": "brain/context-kit/source-of-truth.md", - "target": { - "root": "agent_brain", - "path": "context-kit/source-of-truth.md" - }, + "target": { "root": "agent_brain", "path": "context-kit/source-of-truth.md" }, "executable": false }, { "id": "guardrails", "type": "file", "sourcePath": "brain/context-kit/guardrails.md", - "target": { - "root": "agent_brain", - "path": "context-kit/guardrails.md" - }, + "target": { "root": "agent_brain", "path": "context-kit/guardrails.md" }, "executable": false }, { "id": "briefing-template", "type": "file", "sourcePath": "brain/context-kit/briefing-template.md", - "target": { - "root": "agent_brain", - "path": "context-kit/briefing-template.md" - }, + "target": { "root": "agent_brain", "path": "context-kit/briefing-template.md" }, + "executable": false + }, + { + "id": "media-buying-scaffold", + "type": "file", + "sourcePath": "brain/context-kit/media-buying.md", + "target": { "root": "agent_brain", "path": "context-kit/media-buying.md" }, + "executable": false + }, + { + "id": "business-team-scaffold", + "type": "file", + "sourcePath": "brain/context-kit/business-team.md", + "target": { "root": "agent_brain", "path": "context-kit/business-team.md" }, + "executable": false + }, + { + "id": "landing-pages-scaffold", + "type": "file", + "sourcePath": "brain/context-kit/landing-pages.md", + "target": { "root": "agent_brain", "path": "context-kit/landing-pages.md" }, + "executable": false + }, + { + "id": "context-kit-refresh-workflow", + "type": "file", + "sourcePath": "workflows/context-kit-refresh.ts", + "target": { "root": "agent_brain", "path": "context-kit/workflows/context-kit-refresh.ts" }, "executable": false }, { "id": "context-kit-skill", "type": "directory", "sourcePath": "skills", - "target": { - "root": "agent_skills", - "path": "context-kit" - }, + "target": { "root": "agent_skills", "path": "context-kit" }, "executablePaths": [] }, { "id": "context-kit-app", "type": "directory", "sourcePath": "apps/context-kit", - "target": { - "root": "agent_apps", - "path": "context-kit" - }, + "target": { "root": "agent_apps", "path": "context-kit" }, "executablePaths": [] } ] diff --git a/packages/context-kit/runneth-package.json b/packages/context-kit/runneth-package.json index f27afec..bf56f11 100644 --- a/packages/context-kit/runneth-package.json +++ b/packages/context-kit/runneth-package.json @@ -2,8 +2,8 @@ "schemaVersion": 1, "id": "context-kit", "name": "Context Kit", - "description": "Builds the institutional knowledge that makes every Runneth answer sharper. Seeds a brain skeleton, a Context Kit board app, and the Context Kit skill that confirms what Motion knows, imports what already lives in Drive/Notion, researches what it can, and collects the rest.", - "version": "0.9.0", + "description": "Builds the brand knowledge that makes every Runneth answer sharper. Seeds a brain skeleton, a Context Kit board app, and the Context Kit skill. Install first, then ad-naming for naming conventions and query contract, then creative-corpus for the full creative library.", + "version": "1.0.0", "updatePolicy": "manual", "uninstallPolicy": "allowed", "resources": [ @@ -62,6 +62,46 @@ }, "executable": false }, + { + "id": "media-buying-scaffold", + "type": "file", + "sourcePath": "brain/context-kit/media-buying.md", + "target": { + "root": "agent_brain", + "path": "context-kit/media-buying.md" + }, + "executable": false + }, + { + "id": "business-team-scaffold", + "type": "file", + "sourcePath": "brain/context-kit/business-team.md", + "target": { + "root": "agent_brain", + "path": "context-kit/business-team.md" + }, + "executable": false + }, + { + "id": "landing-pages-scaffold", + "type": "file", + "sourcePath": "brain/context-kit/landing-pages.md", + "target": { + "root": "agent_brain", + "path": "context-kit/landing-pages.md" + }, + "executable": false + }, + { + "id": "context-kit-refresh-workflow", + "type": "file", + "sourcePath": "workflows/context-kit-refresh.ts", + "target": { + "root": "agent_brain", + "path": "context-kit/workflows/context-kit-refresh.ts" + }, + "executable": false + }, { "id": "context-kit-skill", "type": "directory", diff --git a/packages/context-kit/skills/SKILL.md b/packages/context-kit/skills/SKILL.md index 239c830..5bc822e 100644 --- a/packages/context-kit/skills/SKILL.md +++ b/packages/context-kit/skills/SKILL.md @@ -1,110 +1,137 @@ --- name: context-kit -description: Builds a customer's Context Kit, the institutional knowledge that makes every Runneth answer sharper. Reads the Context Kit state index, confirms what Motion knows, drafts brand-context and every Bucket B item from Motion creative data (AI glossary tag distribution first) before asking anything, imports what already lives in Google Drive or Notion, researches real customer language for voice-of-customer, and collects what only the customer knows, filling each into the brain and moving the completeness meter. Triggers on "build my context kit", "set up my context kit", "context kit", "build my brain", "sharpen Runneth", "what makes my answers better", "what do you still need from me", "what does Runneth know about us". +description: Builds a customer's Context Kit, the brand knowledge that makes every Runneth answer sharper. Reads the Context Kit state index, confirms what Motion knows, drafts brand-context and every Bucket B item from Motion creative data before asking anything, imports what already lives in Google Drive or Notion, and collects what only the customer knows. Triggers on "build my context kit", "set up my context kit", "context kit", "build my brain", "sharpen Runneth", "what do you still need from me", "what does Runneth know about us". --- # Context Kit skill -Turn a fresh brain into a filled one, without the manual sales/CS back-and-forth. The board app is the -mirror; this skill is the doer. Draft from Motion data first, then import, then collect. Never write to -`user.md`. Fill happens as deliberate in-conversation brain writes. +Turn a fresh brain into a filled one. The board app is the mirror; this skill is the doer. Draft from Motion data first, then import, then collect. Never write to `user.md`. + +Naming conventions, per-campaign KPI maps, and the Motion query contract are handled by the **ad-naming** companion package. Install that after Context Kit when the account has a structured naming system. ## Single source of truth -Every one of the 12 files lives in `/agent/brain/context-kit/.md` and is mirrored to -`/agent/apps/context-kit/data/.md` so the board can fetch it. Do NOT scatter files into -`brand-audit/` or `templates/`. Item ids: brand-context, kpis-goal, spend-threshold, competitors, -products, positioning, voice, voc, legal (file legal-compliance.md), briefing-template, source-of-truth, -guardrails. -## Status meaning (drives the board color, keep it honest) +Every one of the 15 files lives in `/agent/brain/context-kit/.md` and is mirrored to `/agent/apps/context-kit/data/.md` so the board can fetch it. + +Item ids: brand-context, kpis-goal, spend-threshold, competitors, products, positioning, voice, voc, legal (file legal-compliance.md), briefing-template, source-of-truth, guardrails, media-buying, business-team, landing-pages. + +Integration guides: `/agent/brain/context-kit/integrations/.md`, mirrored to `data/integrations/.md`. + +## Status meaning - `confirmed` / `imported`: locked in by the customer (green). -- `drafted` (butter): built from ACTUAL Motion data (glossary tags, creative summaries, transcripts, Inspo). -- `inferred` (blue): written from general brand knowledge because Motion was unavailable. MUST carry a - `sourceNote` explaining that, so the customer knows to scrutinize it. +- `drafted`: built from ACTUAL Motion data. Must carry real data, not general knowledge. +- `inferred`: written from general brand knowledge because Motion was unavailable. MUST carry a `sourceNote`. - `missing`: nothing yet. ## Step 0 — Load state + set brand name + 1. Read `/agent/brain/context-kit/context-kit-state.json`. -2. Set top-level `brandName` from `motion workspaces` (current workspace name) or brand context, BEFORE the - first state write, so the board title reads "'s Context Kit" from first load. +2. Set top-level `brandName` from `motion workspaces` or brand context before the first state write. 3. Run `motion brand-context --data-query "summary"`, `motion workspace-goal`, `motion spend-threshold`. -4. Note which context sources are connected (Google Drive, Notion, reviews platform, Shopify, attribution). +4. Note which context sources are connected (Google Drive, Notion, reviews platform). + +## Step 0b — Register Knoweth lanes (first run only) + +If `context-kit-state.json` shows `lanesRegistered: false` or the field is absent, register the three core lanes before any brain writes: + +| Lane ID | Path | Patterns | +|---|---|---| +| `context-kit-core` | `/agent/brain/context-kit/` | `context-kit-state.json`, `guardrails.md`, `legal-compliance.md`, `source-of-truth.md`, `briefing-template.md` | +| `context-kit-brand` | `/agent/brain/context-kit/` | `brand-context.md`, `voice.md`, `voc.md`, `positioning.md`, `products.md`, `competitors.md` | +| `context-kit-performance` | `/agent/brain/context-kit/` | `kpis-goal.md`, `spend-threshold.md` | + +Set `lanesRegistered: true` in state. Do not re-register on subsequent runs. + +## Step 0c — Register the refresh workflow (first run only) + +If `context-kit-state.json` shows `refreshWorkflowId` absent: +1. Read `/agent/brain/context-kit/workflows/context-kit-refresh.ts`. +2. Run `workflow push /agent/brain/context-kit/workflows/context-kit-refresh.ts --name context-kit-refresh`. +3. Save the workflow ID to state as `refreshWorkflowId`. +4. `task add --kind workflow --workflow-id --name "Context Kit Refresh"` → save as `refreshTaskId`. +5. Mirror state. ## Step 1 — Build and open the board (first run only) -Sync stages files but does not build apps. Fill `/agent/apps/context-kit/buildeth.app.json` (replace -`__CONVERSATION_ID__` and `__WORKSPACE_ID__`), run `app build context-kit`, then `app list` for the URL. -`astro.config.mjs` ships in the package. After first build the board reads `data/` at runtime, no rebuild -needed for content/state changes. - -## Step 2 — Bucket A: confirm, and auto-draft brand-context -- **kpis-goal, spend-threshold:** show the live Motion value, one-tap confirm, write the full doc, set the - `preview` string, mark `confirmed`. -- **brand-context (auto-draft, never ask from scratch):** if `motion brand-context` has content, show and - confirm; if empty, draft from `motion meta insights --date-range last_30d --sort topSpend --include-metrics` - (+ TikTok if connected). Foundation only (brand name, origin story, positioning statement, product - description, proof points, 2-sentence tone, 2-sentence audience). Present, confirm, write, save to workspace - config, mirror to `data/`, mark `confirmed`. + +Fill `/agent/apps/context-kit/buildeth.app.json` (replace `__CONVERSATION_ID__` and `__WORKSPACE_ID__`), run `app build context-kit`, then `app list` for the URL. + +## Step 2 — Bucket A: confirm and auto-draft brand-context + +- **kpis-goal:** show the live Motion workspace-goal value. Present, confirm, write the full doc with `## Latest Import From Motion` and blank `## Runneth Instructions`. Mark `confirmed`. Note: the per-campaign KPI map is handled by the **ad-naming** package. +- **spend-threshold:** same pattern. +- **brand-context:** if `motion brand-context` has content, show and confirm; if empty, draft from `motion meta insights --date-range last_30d --sort topSpend --include-metrics`. Foundation only (brand name, origin story, positioning, product description, proof points, 2-sentence tone, 2-sentence audience). Present, confirm, write, save to workspace config, mirror, mark `confirmed`. ## Step 3 — Proactive import + connect offers + If any Bucket B/C item is missing: -- Drive/Notion connected: "I see you have [Drive/Notion] connected, want me to search there first?" -- No reviews platform: suggest it (powers the best voice-of-customer). -Import confirmed docs into `/agent/brain/context-kit/.md`, mirror to `data/`, mark `imported`. - -## Step 4 — Bucket B: glossary tag distribution is the data spine, then fallback chain -Before drafting ANY Bucket B item, pull the ground-truth spine once: -1. `motion ai-glossary` (which tag categories exist for this workspace). -2. `motion meta insights --include-glossary --date-range last_30d --sort topSpend` and read the tag - distribution from `creatives[].glossaryTags[]`. This is what the brand actually bets spend on. - -Category-to-item mapping (use as the factual spine, then layer language on top): -- `intended-audience` -> positioning (who the top-spend ads target) -- `messaging-angle` -> positioning + voice (what they lead with, how they frame claims) -- `hook-tactic` -> voice + voc (how ads open, which customer-language patterns win spend) -- `visual-format` + `asset-type` -> voice (UGC vs polished vs demo vs testimonial) -- `offer-type` -> products (which offer structures attach to which products) -- `seasonality` -> products + competitors - -Per-item **fallback chain** (explicit, sequential): -1. Motion first: glossary spine + creative summaries + hooks; Inspo brands for **competitors**; video - transcripts (`--include-transcript`) for **voc**; `review-audit` + `brand-relevant-keywords` + web research - for real customer language on **voc** (ad transcripts are only a labeled supplement there). -2. Good Motion signal -> draft, status `drafted`. -3. Motion empty or errors -> if Drive/Notion connected, search + import, status `imported`. -4. Neither -> draft from general brand knowledge, status `inferred`, and set a `sourceNote` like - "Drafted from general brand knowledge, Motion ad data was unavailable. Review and correct." -5. Even that unreliable -> leave `missing` and show thought starters / ask. -After each: mirror the file to `data/.md`, tell the user "I drafted [item], click the card to review or -tell me what to change." Never silently skip; say what was missing. - -Content depth: **voice** is the brand's voice (4-6 named characteristics with sounds-like/doesn't pairs). -**voc** is the customer's voice: a 7-category swipe file (pain, emotional language, desire, before/after, -objections, competitor complaints, trigger events), near-verbatim, plus the Sarah Levinger lived-context -layer (generation, what shaped their trust, 5-10 trigger moments with the emotion on each). +- Drive/Notion connected: offer to search there first. +- No reviews platform: suggest connecting it (powers voice-of-customer). + +Import confirmed docs, mirror, mark `imported`. + +## Step 4 — Bucket B: glossary spine, then draft each item + +Pull the ground-truth spine once: +1. `motion ai-glossary` +2. `motion meta insights --include-glossary --date-range last_30d --sort topSpend` — read tag distribution from `creatives[].glossaryTags[]` + +Category-to-item mapping: +- `intended-audience` → positioning + voc +- `messaging-angle` → positioning + voice +- `hook-tactic` → voice + voc +- `visual-format` + `asset-type` → voice +- `offer-type` → products +- `seasonality` → products + competitors + +Per-item fallback chain (explicit, sequential): +1. Motion glossary spine + summaries + transcripts → draft, status `drafted`. +2. Motion empty → Drive/Notion if connected → status `imported`. +3. Neither → general brand knowledge → status `inferred` + `sourceNote`. +4. Still unreliable → leave `missing`, show thought starters. + +After each: mirror to `data/.md`, tell the user what was drafted. + +**voice**: 4-6 named characteristics with sounds-like/doesn't-sound-like pairs. +**voc**: 7-category swipe file (pain, emotional language, desire, before/after, objections, competitor complaints, trigger events), near-verbatim from transcripts. ## Step 5 — Bucket C: collect with depth -legal, briefing-template, source-of-truth, guardrails: file drop when they have it, use the item's -thoughtStarters when stuck, one prompt when short. Prompt for the COMPLETE rule set. Write to -`/agent/brain/context-kit/.md` (legal -> legal-compliance.md), mirror to `data/`, mark `confirmed`. + +legal, briefing-template, source-of-truth, guardrails, media-buying, business-team, landing-pages: file drop when they have it, thought starters when stuck. Write, mirror, mark `confirmed`. ## Step 6 — Keep the map correct -- Refresh `/agent/INDEX.md` entries pointing to `/agent/brain/context-kit/` as the canonical home. -- After every change update BOTH state copies (`/agent/brain/context-kit/context-kit-state.json` and the - app's `data/context-kit-state.json`). No rebuild needed for data-only changes. -## Rules -- Never touch `user.md`. Never overwrite an already-filled file (create-if-absent, edit-in-place on confirm). -- Reserve `drafted` for real Motion-data content; use `inferred` + a `sourceNote` for general-knowledge drafts. -- Plain, non-technical language with the customer. No file paths or JSON in chat. -- One item at a time; celebrate the Level 3 unlock when the meter completes. -- The self-improvement loop is ALWAYS ON (see the package instruction): on any creative-strategy turn, if a context-kit file was thin and you inferred, say so and offer once to capture the detail, then save it to the right file. Keep it to one in-chat offer, no persistent queue. +- Refresh `/agent/INDEX.md` for all `/agent/brain/context-kit/` files. +- Update BOTH state copies after every change. + +## Step 7 — Offer the weekly refresh routine +After the completeness meter hits 100%, offer: + +``` +routine add \ + --name "Context Kit weekly refresh" \ + --cron "0 9 * * 1" \ + --delivery "Send a summary in a new web conversation." \ + --prompt "Run the context-kit refresh task (task id: ). Wait for completion with task wait. Read the returned JSON. Open a new conversation summarising what changed — highlight shifts in voice, voc, or competitors. Flag items not updated in 3+ weeks as stale. Deliver with conversation send --new." +``` + +Save routine ID to state as `refreshRoutineId`. + +## Rules +- Never touch `user.md`. +- Create-if-absent; edit-in-place on confirm. Never overwrite a filled file. +- Reserve `drafted` for real Motion data. Use `inferred` + `sourceNote` for general-knowledge drafts. +- Plain language with the customer. No file paths or JSON in chat. ## Bucket A: two-section import contract -When writing brand-context, kpis-goal, and spend-threshold, use the durable import format so a Motion re-sync never wipes a customer correction: -- `## Latest Import From Motion` holds the current Motion value. -- `## Runneth Instructions` holds the customer's corrections and rules. -On conflict, follow `Runneth Instructions` and say so plainly. A refresh updates only the import section and preserves instructions. Confirming still moves the item to `confirmed`. -## Bucket D: integration source guides (Your tools) -Bucket D is one card per connected source, capturing how the customer wants Runneth to USE that tool (not what it can do). Create-when-connected: when a customer connects a source or gives rules for it, write `/agent/brain/context-kit/integrations/.md`, mirror to `data/integrations/.md`, and set the item `confirmed` (or `imported` if pulled from an existing doc). Each guide answers: what it applies to (account/workspace/folder/table/brand), what to use it for, what to avoid, the customer's rules, and any open question. Leave the shipped generic scaffolds (ad-platform, asset-library, data-warehouse, reviews) `missing` with their thoughtStarters until the customer connects that source. Bucket D is excluded from the completeness meter. +- `## Latest Import From Motion` — current Motion value. +- `## Runneth Instructions` — customer corrections and rules. + +On conflict, follow `Runneth Instructions`. A refresh updates only the import section. + +## Bucket D: integration source guides + +Files at `/agent/brain/context-kit/integrations/.md`, mirrored to `data/integrations/.md`. The ad-platform guide (workspace ID, attribution windows, conversion events, metric gotchas) is provided by the **ad-naming** package when installed. Other guides (asset-library, data-warehouse, reviews) use their thoughtStarters until the customer connects that source. + +Bucket D excluded from completeness meter. diff --git a/packages/context-kit/workflows/context-kit-refresh.ts b/packages/context-kit/workflows/context-kit-refresh.ts new file mode 100755 index 0000000..95a08ae --- /dev/null +++ b/packages/context-kit/workflows/context-kit-refresh.ts @@ -0,0 +1,272 @@ +import type { Workflow } from "@runneth/workflow/v1"; + +type RefreshOutput = { + changed: string[]; + unchanged: string[]; + stale: string[]; + highlights: string[]; + lastRefreshed: string; + itemsUpdated: number; +}; + +/** + * Context Kit Brand Refresh Workflow + * + * Re-pulls all Motion-sourced brand data for Bucket A and Bucket B items. + * Does NOT touch naming decoder, KPI map, or query contract — those are + * owned by the ad-naming package and its own refresh workflow. + * + * Writes ONLY "## Latest Import From Motion" sections. + * Preserves "## Runneth Instructions" exactly. + * + * Motion CLI pattern for bash tasks: + * ENVELOPE=$(motion ...) # capture envelope to var + * FILE=$(printf '%s' "$ENVELOPE" | jq -r '.file') # parse file path + * jq '...' "$FILE" # read actual data + * + * Agent tasks write structured output to /tmp/ck-results/*.json. + * Bash tasks read those files. No stdout-parsing of agent responses. + */ +export const wf: Workflow, RefreshOutput> = async ({ + task, +}) => { + // ─── Step 1: Pull Motion data via bash ─────────────────────────────────── + + await task.bash({ + key: "pull-workspace-data", + script: ` + set -euo pipefail + mkdir -p /tmp/ck-refresh + + ENVELOPE=$(motion workspace-goal) + FILE=$(printf '%s' "$ENVELOPE" | jq -r '.file') + cp "$FILE" /tmp/ck-refresh/workspace-goal.json + + ENVELOPE=$(motion spend-threshold) + FILE=$(printf '%s' "$ENVELOPE" | jq -r '.file') + cp "$FILE" /tmp/ck-refresh/spend-threshold.json + + ENVELOPE=$(motion brand-context --data-query "summary") + FILE=$(printf '%s' "$ENVELOPE" | jq -r '.file') + cp "$FILE" /tmp/ck-refresh/brand-context.json + + echo "workspace-data-done" + `, + }); + + await task.bash({ + key: "pull-glossary-spine", + script: ` + set -euo pipefail + + ENVELOPE=$(motion ai-glossary) + FILE=$(printf '%s' "$ENVELOPE" | jq -r '.file') + cp "$FILE" /tmp/ck-refresh/glossary.json + + ENVELOPE=$(motion meta insights --include-glossary --date-range last_30d --sort topSpend --limit 100) + FILE=$(printf '%s' "$ENVELOPE" | jq -r '.file') + cp "$FILE" /tmp/ck-refresh/insights-glossary.json + + echo "glossary-done" + `, + }); + + await task.bash({ + key: "pull-inspo-brands", + script: ` + set -euo pipefail + + ENVELOPE=$(motion inspo brands --limit 20) + FILE=$(printf '%s' "$ENVELOPE" | jq -r '.file') + cp "$FILE" /tmp/ck-refresh/inspo-brands.json + + echo "inspo-done" + `, + }); + + await task.bash({ + key: "pull-voc-transcripts", + script: ` + set -euo pipefail + + ENVELOPE=$(motion meta insights --include-transcript --date-range last_30d --sort topSpend --limit 20) + FILE=$(printf '%s' "$ENVELOPE" | jq -r '.file') + cp "$FILE" /tmp/ck-refresh/transcripts.json + + echo "voc-done" + `, + }); + + // ─── Step 2: Agent re-drafts each item ─────────────────────────────────── + // Each agent writes a result JSON to /tmp/ck-results/.json. + // Format: {"changed": true/false, "preview": "one short sentence"} + + await task.bash({ + key: "setup-results-dir", + script: `mkdir -p /tmp/ck-results`, + }); + + await task.agent({ + key: "update-brand-context", + prompt: ` + Update /agent/brain/context-kit/brand-context.md from refreshed Motion data. + + Source files: /tmp/ck-refresh/brand-context.json and /tmp/ck-refresh/insights-glossary.json + (read .creatives[].glossaryTags[] from insights-glossary for tag distribution). + + Rules: + - Read the current file first. Preserve any "## Runneth Instructions" section exactly. + - Rewrite ONLY "## Latest Import From Motion": brand name, positioning, product description, + proof points from top-spend tags, 2-sentence tone, 2-sentence audience. + - Write back to /agent/brain/context-kit/brand-context.md. + - Mirror to /agent/apps/context-kit/data/brand-context.md. + - Write {"changed": true/false, "preview": "one short sentence"} to /tmp/ck-results/brand-context.json. + `, + }); + + await task.agent({ + key: "update-kpis-goal", + prompt: ` + Update /agent/brain/context-kit/kpis-goal.md from refreshed Motion data. + + Source: /tmp/ck-refresh/workspace-goal.json (primary KPI and attribution windows). + + Note: the per-campaign KPI map is owned by the ad-naming package. + Only update the primary KPI, conversion event, and attribution window sections here. + + Rules: + - Preserve "## Runneth Instructions" exactly. + - Rewrite only "## Latest Import From Motion". + - Write back and mirror to data/kpis-goal.md. + - Write {"changed": true/false, "preview": "..."} to /tmp/ck-results/kpis-goal.json. + `, + }); + + await task.agent({ + key: "update-spend-threshold", + prompt: ` + Update /agent/brain/context-kit/spend-threshold.md from /tmp/ck-refresh/spend-threshold.json. + Preserve "## Runneth Instructions". Rewrite only "## Latest Import From Motion". + Write back, mirror, write {"changed": true/false, "preview": "..."} to /tmp/ck-results/spend-threshold.json. + `, + }); + + await task.agent({ + key: "update-voice", + prompt: ` + Update /agent/brain/context-kit/voice.md from /tmp/ck-refresh/insights-glossary.json. + Read .creatives[].glossaryTags[] — focus on visual-format, asset-type, hook-tactic, messaging-angle by spend. + Derive 4-6 named voice characteristics (sounds-like / doesn't-sound-like pairs). + Preserve "## Runneth Instructions". Rewrite only "## Latest Import From Motion". + If Motion data is empty: status = "inferred", add sourceNote. + Write back, mirror, write {"changed": true/false, "preview": "..."} to /tmp/ck-results/voice.json. + `, + }); + + await task.agent({ + key: "update-voc", + prompt: ` + Update /agent/brain/context-kit/voc.md from /tmp/ck-refresh/transcripts.json. + Read .creatives[].transcript for top-spend videos. + Build or refresh the 7-category swipe file with near-verbatim language: + pain, emotional language, desire, before/after, objections, competitor complaints, trigger events. + Preserve "## Runneth Instructions". Rewrite only "## Latest Import From Motion". + If transcripts are empty, note it clearly. + Write back, mirror, write {"changed": true/false, "preview": "..."} to /tmp/ck-results/voc.json. + `, + }); + + await task.agent({ + key: "update-competitors", + prompt: ` + Update /agent/brain/context-kit/competitors.md from /tmp/ck-refresh/inspo-brands.json. + Read .data.brands[] for the customer's followed brands. + Note name, Motion brand ID, active ad count signal for each. + Flag brands with substantially more or fewer ads than the current file shows. + Preserve "## Runneth Instructions". Rewrite only "## Latest Import From Motion". + Write back, mirror, write {"changed": true/false, "preview": "..."} to /tmp/ck-results/competitors.json. + `, + }); + + // ─── Step 3: Collect results + check staleness ──────────────────────────── + + const collectResult = await task.bash({ + key: "collect-results", + script: ` + set -euo pipefail + + node -e " + const fs = require('fs'); + const items = ['brand-context', 'kpis-goal', 'spend-threshold', 'voice', 'voc', 'competitors']; + const changed = []; + const unchanged = []; + const highlights = []; + + for (const item of items) { + try { + const result = JSON.parse(fs.readFileSync('/tmp/ck-results/' + item + '.json', 'utf8')); + if (result.changed) { + changed.push(item); + if (result.preview) highlights.push(item + ': ' + result.preview); + } else { + unchanged.push(item); + } + } catch { + unchanged.push(item); + } + } + + const stale = []; + try { + const state = JSON.parse(fs.readFileSync('/agent/brain/context-kit/context-kit-state.json', 'utf8')); + const cutoff = Date.now() - (21 * 86400 * 1000); + for (const [id, item] of Object.entries(state.items || {})) { + if (item.updatedAt && new Date(item.updatedAt).getTime() < cutoff && item.status !== 'missing') { + stale.push(id); + } + } + } catch {} + + const today = new Date().toISOString().slice(0, 10); + console.log(JSON.stringify({ changed, unchanged, stale, highlights, lastRefreshed: today, itemsUpdated: changed.length })); + " + `, + }); + + // ─── Step 4: Update state ───────────────────────────────────────────────── + + await task.bash({ + key: "update-state", + script: ` + set -euo pipefail + TODAY=$(node -e "console.log(new Date().toISOString().slice(0,10))") + + node -e " + const fs = require('fs'); + let state = {}; + try { state = JSON.parse(fs.readFileSync('/agent/brain/context-kit/context-kit-state.json', 'utf8')); } catch {} + state.lastRefreshed = '$TODAY'; + const out = JSON.stringify(state, null, 2); + fs.writeFileSync('/agent/brain/context-kit/context-kit-state.json', out); + fs.writeFileSync('/agent/apps/context-kit/data/context-kit-state.json', out); + " + `, + }); + + let output: RefreshOutput = { + changed: [], + unchanged: [], + stale: [], + highlights: [], + lastRefreshed: new Date().toISOString().slice(0, 10), + itemsUpdated: 0, + }; + + try { + output = JSON.parse(collectResult.stdout.trim()); + } catch { + // Return partial result + } + + return output; +}; From aaed20ed8196eebb7f3c8bf728c8bb0ff862a52a Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 20 Jul 2026 10:42:27 +0000 Subject: [PATCH 13/16] fix(context-kit): align package contract metadata Co-authored-by: vamsi --- package-index.json | 2 +- packages/context-kit/brain/context-kit/business-team.md | 0 packages/context-kit/brain/context-kit/landing-pages.md | 0 packages/context-kit/brain/context-kit/media-buying.md | 0 packages/context-kit/workflows/context-kit-refresh.ts | 0 5 files changed, 1 insertion(+), 1 deletion(-) mode change 100755 => 100644 packages/context-kit/brain/context-kit/business-team.md mode change 100755 => 100644 packages/context-kit/brain/context-kit/landing-pages.md mode change 100755 => 100644 packages/context-kit/brain/context-kit/media-buying.md mode change 100755 => 100644 packages/context-kit/workflows/context-kit-refresh.ts diff --git a/package-index.json b/package-index.json index 9150891..a235266 100644 --- a/package-index.json +++ b/package-index.json @@ -5,7 +5,7 @@ { "id": "context-kit", "name": "Context Kit", - "description": "Builds the brand knowledge that makes every Runneth answer sharper. Seeds a brain skeleton, a Context Kit board app, and the Context Kit skill. Install first.", + "description": "Builds the brand knowledge that makes every Runneth answer sharper. Seeds a brain skeleton, a Context Kit board app, and the Context Kit skill. Install first, then ad-naming for naming conventions and query contract, then creative-corpus for the full creative library.", "version": "1.0.0", "categories": ["baseline"], "packageManagerVersion": 1, diff --git a/packages/context-kit/brain/context-kit/business-team.md b/packages/context-kit/brain/context-kit/business-team.md old mode 100755 new mode 100644 diff --git a/packages/context-kit/brain/context-kit/landing-pages.md b/packages/context-kit/brain/context-kit/landing-pages.md old mode 100755 new mode 100644 diff --git a/packages/context-kit/brain/context-kit/media-buying.md b/packages/context-kit/brain/context-kit/media-buying.md old mode 100755 new mode 100644 diff --git a/packages/context-kit/workflows/context-kit-refresh.ts b/packages/context-kit/workflows/context-kit-refresh.ts old mode 100755 new mode 100644 From 12ba6582c8e0ce95f2417cf19e149f4ded64f62e Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 20 Jul 2026 12:00:16 +0000 Subject: [PATCH 14/16] fix(context-kit): align fresh install state Co-authored-by: vamsi --- .../context-kit/data/context-kit-state.json | 45 +++++++++++++++++-- .../brain/context-kit/context-kit-state.json | 45 +++++++++++++++++-- 2 files changed, 84 insertions(+), 6 deletions(-) diff --git a/packages/context-kit/apps/context-kit/data/context-kit-state.json b/packages/context-kit/apps/context-kit/data/context-kit-state.json index 18d2c3d..c582b88 100644 --- a/packages/context-kit/apps/context-kit/data/context-kit-state.json +++ b/packages/context-kit/apps/context-kit/data/context-kit-state.json @@ -23,7 +23,7 @@ "id": "brand-context", "label": "Brand context", "bucket": "A", - "status": "inferred", + "status": "missing", "why": "Keeps every output unmistakably on-brand.", "preview": "", "dataFile": "brand-context.md" @@ -32,7 +32,7 @@ "id": "kpis-goal", "label": "KPIs & goal", "bucket": "A", - "status": "inferred", + "status": "missing", "why": "Every readout leads with the metric you care about.", "preview": "", "dataFile": "kpis-goal.md" @@ -41,7 +41,7 @@ "id": "spend-threshold", "label": "Spend threshold", "bucket": "A", - "status": "inferred", + "status": "missing", "why": "Separates a proven winner from early noise.", "preview": "", "dataFile": "spend-threshold.md" @@ -145,6 +145,45 @@ "Any past ad types or messages to avoid repeating?" ] }, + { + "id": "media-buying", + "label": "Media buying model", + "bucket": "C", + "status": "missing", + "why": "Keeps creative recommendations aligned with how you actually buy.", + "dataFile": "media-buying.md", + "thoughtStarters": [ + "How do you primarily buy? (ABO, CBO, Advantage+)", + "What does a typical campaign structure look like?", + "Any budget rules or pacing preferences Runneth should know?" + ] + }, + { + "id": "business-team", + "label": "Business & team", + "bucket": "C", + "status": "missing", + "why": "Runneth works better knowing who is using it and how decisions get made.", + "dataFile": "business-team.md", + "thoughtStarters": [ + "Who reviews and approves creatives?", + "Who owns the brief-to-production pipeline?", + "Any team rules or review steps Runneth should respect?" + ] + }, + { + "id": "landing-pages", + "label": "Landing pages", + "bucket": "C", + "status": "missing", + "why": "Briefs land harder when Runneth knows what the ad is sending to.", + "dataFile": "landing-pages.md", + "thoughtStarters": [ + "What are your main landing page URLs or page types?", + "What is the primary CTA on your top pages?", + "Any pages that are off-limits for ads?" + ] + }, { "id": "integration-ad-platform", "label": "Ad platform", diff --git a/packages/context-kit/brain/context-kit/context-kit-state.json b/packages/context-kit/brain/context-kit/context-kit-state.json index 18d2c3d..c582b88 100644 --- a/packages/context-kit/brain/context-kit/context-kit-state.json +++ b/packages/context-kit/brain/context-kit/context-kit-state.json @@ -23,7 +23,7 @@ "id": "brand-context", "label": "Brand context", "bucket": "A", - "status": "inferred", + "status": "missing", "why": "Keeps every output unmistakably on-brand.", "preview": "", "dataFile": "brand-context.md" @@ -32,7 +32,7 @@ "id": "kpis-goal", "label": "KPIs & goal", "bucket": "A", - "status": "inferred", + "status": "missing", "why": "Every readout leads with the metric you care about.", "preview": "", "dataFile": "kpis-goal.md" @@ -41,7 +41,7 @@ "id": "spend-threshold", "label": "Spend threshold", "bucket": "A", - "status": "inferred", + "status": "missing", "why": "Separates a proven winner from early noise.", "preview": "", "dataFile": "spend-threshold.md" @@ -145,6 +145,45 @@ "Any past ad types or messages to avoid repeating?" ] }, + { + "id": "media-buying", + "label": "Media buying model", + "bucket": "C", + "status": "missing", + "why": "Keeps creative recommendations aligned with how you actually buy.", + "dataFile": "media-buying.md", + "thoughtStarters": [ + "How do you primarily buy? (ABO, CBO, Advantage+)", + "What does a typical campaign structure look like?", + "Any budget rules or pacing preferences Runneth should know?" + ] + }, + { + "id": "business-team", + "label": "Business & team", + "bucket": "C", + "status": "missing", + "why": "Runneth works better knowing who is using it and how decisions get made.", + "dataFile": "business-team.md", + "thoughtStarters": [ + "Who reviews and approves creatives?", + "Who owns the brief-to-production pipeline?", + "Any team rules or review steps Runneth should respect?" + ] + }, + { + "id": "landing-pages", + "label": "Landing pages", + "bucket": "C", + "status": "missing", + "why": "Briefs land harder when Runneth knows what the ad is sending to.", + "dataFile": "landing-pages.md", + "thoughtStarters": [ + "What are your main landing page URLs or page types?", + "What is the primary CTA on your top pages?", + "Any pages that are off-limits for ads?" + ] + }, { "id": "integration-ad-platform", "label": "Ad platform", From 4ea9d10157ad92cfb346b66ce5f97370eb6630bf Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 20 Jul 2026 12:42:06 +0000 Subject: [PATCH 15/16] fix(context-kit): add app manifest identity Co-authored-by: vamsi --- packages/context-kit/README.md | 7 ++++--- packages/context-kit/apps/context-kit/buildeth.app.json | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/context-kit/README.md b/packages/context-kit/README.md index 9304fe4..e1dd96a 100644 --- a/packages/context-kit/README.md +++ b/packages/context-kit/README.md @@ -5,9 +5,10 @@ Builds the institutional knowledge that makes every Runneth answer sharper: brai ## App build gotchas (learned in staging — read before editing the app) -- **`buildeth.app.json` must be v3** with `conversationId`, `workspaceId`, `oauthEnabled: true`, - `data: { "dir": "data" }`, `static: { "dist": "dist", "index": "index.html" }`. It ships as a template - with `__CONVERSATION_ID__` / `__WORKSPACE_ID__` tokens the skill substitutes before `app build`. +- **`buildeth.app.json` must be v3** with `name: "context-kit"`, `route: "/context-kit"`, + `conversationId`, `workspaceId`, `oauthEnabled: true`, `data: { "dir": "data" }`, and + `static: { "dist": "dist", "index": "index.html" }`. It ships as a template with + `__CONVERSATION_ID__` / `__WORKSPACE_ID__` tokens the skill substitutes before `app build`. - **`astro.config.mjs` must set `base: "/context-kit"`** (and `trailingSlash: "never"`). Without a base, Astro emits absolute `/_astro/...` asset URLs and `app build` rejects the static output. - **Use `