create-walle 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/bin/create-walle.js +134 -0
  2. package/package.json +18 -0
  3. package/template/.env.example +40 -0
  4. package/template/CLAUDE.md +12 -0
  5. package/template/LICENSE +21 -0
  6. package/template/README.md +167 -0
  7. package/template/bin/setup.js +100 -0
  8. package/template/claude-code-skill.md +60 -0
  9. package/template/claude-task-manager/api-prompts.js +1841 -0
  10. package/template/claude-task-manager/api-reviews.js +275 -0
  11. package/template/claude-task-manager/approval-agent.js +454 -0
  12. package/template/claude-task-manager/bin/restart-ctm.sh +16 -0
  13. package/template/claude-task-manager/db.js +1721 -0
  14. package/template/claude-task-manager/docs/PROMPT-MANAGEMENT-DESIGN.md +631 -0
  15. package/template/claude-task-manager/git-utils.js +214 -0
  16. package/template/claude-task-manager/package-lock.json +1607 -0
  17. package/template/claude-task-manager/package.json +31 -0
  18. package/template/claude-task-manager/prompt-harvest.js +1148 -0
  19. package/template/claude-task-manager/public/css/prompts.css +880 -0
  20. package/template/claude-task-manager/public/css/reviews.css +430 -0
  21. package/template/claude-task-manager/public/css/walle.css +732 -0
  22. package/template/claude-task-manager/public/favicon.ico +0 -0
  23. package/template/claude-task-manager/public/icon.svg +37 -0
  24. package/template/claude-task-manager/public/index.html +8346 -0
  25. package/template/claude-task-manager/public/js/prompts.js +3159 -0
  26. package/template/claude-task-manager/public/js/reviews.js +1292 -0
  27. package/template/claude-task-manager/public/js/walle.js +3081 -0
  28. package/template/claude-task-manager/public/manifest.json +13 -0
  29. package/template/claude-task-manager/public/prompts.html +4353 -0
  30. package/template/claude-task-manager/public/setup.html +216 -0
  31. package/template/claude-task-manager/queue-engine.js +404 -0
  32. package/template/claude-task-manager/server-state.js +5 -0
  33. package/template/claude-task-manager/server.js +2254 -0
  34. package/template/claude-task-manager/session-utils.js +124 -0
  35. package/template/claude-task-manager/start.sh +17 -0
  36. package/template/claude-task-manager/tests/test-ai-search.js +61 -0
  37. package/template/claude-task-manager/tests/test-editor-ux.js +76 -0
  38. package/template/claude-task-manager/tests/test-editor-ux2.js +51 -0
  39. package/template/claude-task-manager/tests/test-features-v2.js +127 -0
  40. package/template/claude-task-manager/tests/test-insights-cached.js +78 -0
  41. package/template/claude-task-manager/tests/test-insights.js +124 -0
  42. package/template/claude-task-manager/tests/test-permissions-v2.js +127 -0
  43. package/template/claude-task-manager/tests/test-permissions.js +122 -0
  44. package/template/claude-task-manager/tests/test-pin.js +51 -0
  45. package/template/claude-task-manager/tests/test-prompts.js +164 -0
  46. package/template/claude-task-manager/tests/test-recent-sessions.js +96 -0
  47. package/template/claude-task-manager/tests/test-review.js +104 -0
  48. package/template/claude-task-manager/tests/test-send-dropdown.js +76 -0
  49. package/template/claude-task-manager/tests/test-send-final.js +30 -0
  50. package/template/claude-task-manager/tests/test-send-fixes.js +76 -0
  51. package/template/claude-task-manager/tests/test-send-integration.js +107 -0
  52. package/template/claude-task-manager/tests/test-send-visual.js +34 -0
  53. package/template/claude-task-manager/tests/test-session-create.js +147 -0
  54. package/template/claude-task-manager/tests/test-sidebar-ux.js +83 -0
  55. package/template/claude-task-manager/tests/test-url-hash.js +68 -0
  56. package/template/claude-task-manager/tests/test-ux-crop.js +34 -0
  57. package/template/claude-task-manager/tests/test-ux-review.js +130 -0
  58. package/template/claude-task-manager/tests/test-zoom-card.js +76 -0
  59. package/template/claude-task-manager/tests/test-zoom.js +92 -0
  60. package/template/claude-task-manager/tests/test-zoom2.js +67 -0
  61. package/template/docs/site/api/README.md +187 -0
  62. package/template/docs/site/guides/claude-code.md +58 -0
  63. package/template/docs/site/guides/configuration.md +96 -0
  64. package/template/docs/site/guides/quickstart.md +158 -0
  65. package/template/docs/site/index.md +14 -0
  66. package/template/docs/site/skills/README.md +135 -0
  67. package/template/wall-e/.dockerignore +11 -0
  68. package/template/wall-e/Dockerfile +25 -0
  69. package/template/wall-e/adapters/adapter-base.js +37 -0
  70. package/template/wall-e/adapters/ctm.js +193 -0
  71. package/template/wall-e/adapters/slack.js +56 -0
  72. package/template/wall-e/agent.js +319 -0
  73. package/template/wall-e/api-walle.js +1073 -0
  74. package/template/wall-e/brain.js +1235 -0
  75. package/template/wall-e/channels/agent-api.js +172 -0
  76. package/template/wall-e/channels/channel-base.js +14 -0
  77. package/template/wall-e/channels/imessage-channel.js +113 -0
  78. package/template/wall-e/channels/slack-channel.js +118 -0
  79. package/template/wall-e/chat.js +778 -0
  80. package/template/wall-e/decision/confidence.js +93 -0
  81. package/template/wall-e/deploy.sh +35 -0
  82. package/template/wall-e/docs/specs/2026-04-01-publish-plan.md +112 -0
  83. package/template/wall-e/docs/specs/SKILL-FORMAT.md +326 -0
  84. package/template/wall-e/extraction/contradiction.js +168 -0
  85. package/template/wall-e/extraction/knowledge-extractor.js +190 -0
  86. package/template/wall-e/fly.toml +24 -0
  87. package/template/wall-e/loops/ingest.js +34 -0
  88. package/template/wall-e/loops/reflect.js +63 -0
  89. package/template/wall-e/loops/tasks.js +487 -0
  90. package/template/wall-e/loops/think.js +125 -0
  91. package/template/wall-e/package-lock.json +533 -0
  92. package/template/wall-e/package.json +18 -0
  93. package/template/wall-e/scripts/ingest-slack-search.js +85 -0
  94. package/template/wall-e/scripts/pull-slack-via-claude.js +98 -0
  95. package/template/wall-e/scripts/slack-backfill.js +295 -0
  96. package/template/wall-e/scripts/slack-channel-history.js +454 -0
  97. package/template/wall-e/server.js +93 -0
  98. package/template/wall-e/skills/_bundled/email-digest/SKILL.md +95 -0
  99. package/template/wall-e/skills/_bundled/email-sync/SKILL.md +65 -0
  100. package/template/wall-e/skills/_bundled/email-sync/mail-reader.jxa +104 -0
  101. package/template/wall-e/skills/_bundled/email-sync/run.js +213 -0
  102. package/template/wall-e/skills/_bundled/google-calendar/SKILL.md +73 -0
  103. package/template/wall-e/skills/_bundled/google-calendar/cal-reader.swift +81 -0
  104. package/template/wall-e/skills/_bundled/google-calendar/run.js +181 -0
  105. package/template/wall-e/skills/_bundled/memory-search/SKILL.md +92 -0
  106. package/template/wall-e/skills/_bundled/morning-briefing/SKILL.md +131 -0
  107. package/template/wall-e/skills/_bundled/morning-briefing/run.js +264 -0
  108. package/template/wall-e/skills/_bundled/slack-backfill/SKILL.md +60 -0
  109. package/template/wall-e/skills/_bundled/slack-sync/SKILL.md +55 -0
  110. package/template/wall-e/skills/claude-code-reader.js +144 -0
  111. package/template/wall-e/skills/mcp-client.js +407 -0
  112. package/template/wall-e/skills/skill-executor.js +163 -0
  113. package/template/wall-e/skills/skill-loader.js +410 -0
  114. package/template/wall-e/skills/skill-planner.js +88 -0
  115. package/template/wall-e/skills/slack-ingest.js +329 -0
  116. package/template/wall-e/skills/slack-pull-live.js +270 -0
  117. package/template/wall-e/skills/tool-executor.js +188 -0
  118. package/template/wall-e/tests/adapter-base.test.js +20 -0
  119. package/template/wall-e/tests/adapter-ctm.test.js +122 -0
  120. package/template/wall-e/tests/adapter-slack.test.js +98 -0
  121. package/template/wall-e/tests/agent-api.test.js +256 -0
  122. package/template/wall-e/tests/api-walle.test.js +222 -0
  123. package/template/wall-e/tests/brain.test.js +602 -0
  124. package/template/wall-e/tests/channels.test.js +104 -0
  125. package/template/wall-e/tests/chat.test.js +103 -0
  126. package/template/wall-e/tests/confidence.test.js +134 -0
  127. package/template/wall-e/tests/contradiction.test.js +217 -0
  128. package/template/wall-e/tests/ingest.test.js +113 -0
  129. package/template/wall-e/tests/mcp-client.test.js +71 -0
  130. package/template/wall-e/tests/reflect.test.js +103 -0
  131. package/template/wall-e/tests/server.test.js +111 -0
  132. package/template/wall-e/tests/skills.test.js +198 -0
  133. package/template/wall-e/tests/slack-ingest.test.js +103 -0
  134. package/template/wall-e/tests/think.test.js +435 -0
  135. package/template/wall-e/tools/local-tools.js +697 -0
  136. package/template/wall-e/tools/slack-mcp.js +290 -0
@@ -0,0 +1,93 @@
1
+ 'use strict';
2
+ const { v4: uuidv4 } = require('uuid');
3
+ const brain = require('../brain');
4
+
5
+ // Graduation thresholds from spec
6
+ const GRADUATION = {
7
+ '1_to_2': { memories_required: 50 },
8
+ '2_to_3': { approval_rate: 0.90, min_actions: 20 },
9
+ '3_to_4': { approval_rate: 0.95, min_actions: 50 },
10
+ };
11
+
12
+ function getDomainConfidence(domain) {
13
+ const db = brain.getDb();
14
+ let row = db.prepare('SELECT * FROM domain_confidence WHERE domain = ?').get(domain);
15
+ if (!row) {
16
+ const id = uuidv4();
17
+ db.prepare('INSERT INTO domain_confidence (id, domain) VALUES (?, ?)').run(id, domain);
18
+ row = db.prepare('SELECT * FROM domain_confidence WHERE domain = ?').get(domain);
19
+ }
20
+ return row;
21
+ }
22
+
23
+ function checkGraduation(domain) {
24
+ const dc = getDomainConfidence(domain);
25
+ const currentTier = dc.current_tier;
26
+ let newTier = currentTier;
27
+
28
+ if (currentTier === 1) {
29
+ // Tier 1 -> 2: enough memories in domain
30
+ const memCount = brain.listMemories({ source: domain, limit: 51 }).length;
31
+ if (memCount > 50) newTier = 2;
32
+ } else if (currentTier === 2) {
33
+ const rate = dc.total_actions > 0 ? dc.approved_actions / dc.total_actions : 0;
34
+ if (rate > 0.90 && dc.total_actions > 20) newTier = 3;
35
+ } else if (currentTier === 3) {
36
+ const rate = dc.total_actions > 0 ? dc.approved_actions / dc.total_actions : 0;
37
+ if (rate > 0.95 && dc.total_actions > 50) newTier = 4;
38
+ }
39
+
40
+ if (newTier !== currentTier) {
41
+ brain.getDb().prepare(
42
+ "UPDATE domain_confidence SET current_tier = ?, last_promotion = datetime('now'), updated_at = datetime('now') WHERE domain = ?"
43
+ ).run(newTier, domain);
44
+ return { promoted: true, from: currentTier, to: newTier };
45
+ }
46
+ return { promoted: false, tier: currentTier };
47
+ }
48
+
49
+ function recordAction(domain, approved) {
50
+ const dc = getDomainConfidence(domain);
51
+ const updates = {
52
+ total_actions: dc.total_actions + 1,
53
+ approved_actions: approved ? dc.approved_actions + 1 : dc.approved_actions,
54
+ rejected_actions: approved ? dc.rejected_actions : dc.rejected_actions + 1,
55
+ };
56
+
57
+ // Check demotion: 3 rejections in a row
58
+ if (!approved) {
59
+ const recentActions = brain.getDb().prepare(
60
+ "SELECT status FROM agent_actions WHERE domain = ? ORDER BY created_at DESC LIMIT 3"
61
+ ).all(domain);
62
+ const allRejected = recentActions.length === 3 && recentActions.every(a => a.status === 'rejected');
63
+ if (allRejected && dc.current_tier > 1) {
64
+ updates.current_tier = dc.current_tier - 1;
65
+ updates.last_demotion = new Date().toISOString();
66
+ }
67
+ }
68
+
69
+ const keys = Object.keys(updates);
70
+ const sets = keys.map(k => `${k} = ?`).join(', ');
71
+ const vals = keys.map(k => updates[k]);
72
+ brain.getDb().prepare(`UPDATE domain_confidence SET ${sets}, updated_at = datetime('now') WHERE domain = ?`)
73
+ .run(...vals, domain);
74
+
75
+ // Check graduation after recording
76
+ return checkGraduation(domain);
77
+ }
78
+
79
+ function canActAutonomously(domain, isHighRisk) {
80
+ const dc = getDomainConfidence(domain);
81
+ const tier = dc.current_tier;
82
+
83
+ if (tier <= 2) return false; // Always queue
84
+ if (tier === 3) return !isHighRisk; // Act on low-risk only
85
+ if (tier === 4) return true; // Full autonomy
86
+ return false;
87
+ }
88
+
89
+ function listDomainConfidences() {
90
+ return brain.getDb().prepare('SELECT * FROM domain_confidence ORDER BY domain').all();
91
+ }
92
+
93
+ module.exports = { getDomainConfidence, checkGraduation, recordAction, canActAutonomously, listDomainConfidences };
@@ -0,0 +1,35 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ echo "=== WALL-E Cloud Deployment ==="
5
+ echo ""
6
+
7
+ # Check fly CLI
8
+ if ! command -v fly &> /dev/null; then
9
+ echo "Error: fly CLI not installed. Run: brew install flyctl"
10
+ exit 1
11
+ fi
12
+
13
+ # Check if app exists
14
+ if ! fly apps list 2>/dev/null | grep -q wall-e-agent; then
15
+ echo "Creating Fly.io app..."
16
+ fly apps create wall-e-agent
17
+ fly volumes create wall_e_data --region sjc --size 1
18
+ fi
19
+
20
+ # Set secrets
21
+ echo "Setting secrets..."
22
+ echo "Make sure to set ANTHROPIC_API_KEY or Portkey headers:"
23
+ echo " fly secrets set ANTHROPIC_API_KEY=sk-..."
24
+ echo " fly secrets set ANTHROPIC_BASE_URL=https://..."
25
+ echo " fly secrets set ANTHROPIC_CUSTOM_HEADERS_B64=..."
26
+ echo ""
27
+
28
+ # Deploy
29
+ echo "Deploying..."
30
+ fly deploy
31
+
32
+ echo ""
33
+ echo "=== Deployment complete ==="
34
+ echo "WALL-E is running at: https://wall-e-agent.fly.dev"
35
+ echo "Health check: https://wall-e-agent.fly.dev/api/wall-e/health"
@@ -0,0 +1,112 @@
1
+ # Publishing Plan: CTM & Wall-E
2
+
3
+ **Date:** 2026-04-01
4
+ **Author:** Juncao Li
5
+ **Domain:** https://walle.sh
6
+
7
+ ## Overview
8
+
9
+ Publish CTM (Claude Task Manager) and Wall-E (personal digital twin agent) as open-source tools that others can discover, install, and run locally.
10
+
11
+ ## Phases
12
+
13
+ ### Phase 1: Code Cleanup & Open Source (Current)
14
+
15
+ **Goal:** Make the codebase safe and portable for public GitHub.
16
+
17
+ #### Security Cleanup
18
+
19
+ | Issue | Severity | Files | Fix |
20
+ |---|---|---|---|
21
+ | Hardcoded Slack User ID `YOUR_SLACK_USER_ID` | Critical | 5 files in `scripts/`, `slack-ingest.js` | Env var `SLACK_OWNER_USER_ID` |
22
+ | `owner@example.com` in SKILL.md examples | High | `email-sync/SKILL.md`, `google-calendar/SKILL.md` | Replace with `owner@example.com` |
23
+ | Hardcoded `juncao.li` in Slack queries | High | `slack-backfill.js`, `slack-channel-history.js`, `morning-briefing/run.js` | Read from config/brain |
24
+ | `OWNER_NAME` owner name constant | High | `pull-slack-via-claude.js`, `slack-ingest.js` | Use `brain.getOwnerName()` |
25
+ | Hardcoded `.walle/data` | Medium | `server.js`, `db.js`, `brain.js`, `api-walle.js` | Default to `~/.walle/data` |
26
+
27
+ #### Repo Hygiene
28
+
29
+ - [ ] `.env.example` documenting all env vars
30
+ - [ ] `.gitignore` excludes `.db`, `.env`, compiled binaries, oauth tokens
31
+ - [ ] MIT `LICENSE` file
32
+ - [ ] Scrub git history or start fresh public repo (if secrets were ever committed)
33
+
34
+ #### Already Good
35
+
36
+ - API keys (ANTHROPIC_API_KEY, SLACK_TOKEN) read from env vars
37
+ - `.db` files not in repo
38
+ - `CTM_DATA_DIR` / `WALL_E_DATA_DIR` env vars already supported
39
+
40
+ ### Phase 2: Distribution & Discovery
41
+
42
+ **Goal:** Make it easy for others to find and install.
43
+
44
+ | Channel | Effort | Reach | Priority |
45
+ |---|---|---|---|
46
+ | GitHub repo + README | Low | Devs who search GitHub | P0 |
47
+ | `npx create-walle` scaffolder | Medium | Anyone with Node.js | P1 |
48
+ | Claude Code skill registry | Low | Claude Code users | P1 |
49
+ | Homebrew tap | Medium | macOS users | P2 |
50
+ | walle.sh website | High | Broadest | P2 |
51
+
52
+ #### README Requirements
53
+
54
+ - One-paragraph pitch
55
+ - Screenshot / demo GIF
56
+ - "Try it in 2 minutes" quickstart
57
+ - Architecture diagram (CTM <-> Wall-E <-> Brain)
58
+ - List of bundled skills (calendar, slack, email, morning briefing)
59
+ - Configuration reference
60
+
61
+ #### npx Scaffolder
62
+
63
+ ```bash
64
+ npx create-walle
65
+ # Clones repo, runs npm install, creates ~/.walle/data,
66
+ # prompts for ANTHROPIC_API_KEY, owner name, optional Slack token
67
+ # Starts CTM + Wall-E daemon
68
+ ```
69
+
70
+ ### Phase 3: Website — walle.sh
71
+
72
+ **Goal:** Landing page, docs, and eventually auth + cloud hosting.
73
+
74
+ | Sub-phase | What | Tech |
75
+ |---|---|---|
76
+ | 3a | Static landing page: pitch, screenshots, install guide | Cloudflare Pages (free, deploys from repo) |
77
+ | 3b | Interactive docs: skill catalog, API reference | Same, or Astro/Starlight |
78
+ | 3c | Auth + cloud DB | Fly.io (already deployed), Turso/Libsql for SQLite-compat cloud DB, Clerk or Passkeys for auth |
79
+ | 3d | Web-based setup wizard | Create account -> configure integrations -> download CLI |
80
+
81
+ #### Domain DNS Roadmap
82
+
83
+ | Record | Now | Later |
84
+ |---|---|---|
85
+ | `walle.sh` | `127.0.0.1` (local alias) | Cloudflare Pages (landing) |
86
+ | `app.walle.sh` | — | Fly.io (cloud CTM + Wall-E) |
87
+ | `api.walle.sh` | — | Fly.io (public API) |
88
+ | `docs.walle.sh` | — | Cloudflare Pages (documentation) |
89
+
90
+ ### Phase 4: Multi-User & Marketplace
91
+
92
+ **Goal:** Let others contribute skills; host as SaaS.
93
+
94
+ - Per-user data isolation (separate brain DBs)
95
+ - Skill marketplace: browse, install, rate community skills
96
+ - Usage-based pricing or free tier + pro
97
+ - Telemetry opt-in for usage insights
98
+ - Rate limiting / cost management (Wall-E daemon burns API tokens)
99
+
100
+ ## Branding
101
+
102
+ - **Public name:** Wall-E (memorable, the face of the project)
103
+ - **CTM** is the task manager component (less catchy, keep as internal name)
104
+ - **Domain:** walle.sh
105
+ - **Tagline ideas:** "Your personal digital twin" / "An AI that knows you"
106
+
107
+ ## Open Questions
108
+
109
+ 1. Start fresh public repo or clean history of current repo?
110
+ 2. Pricing model for cloud version? Free tier limits?
111
+ 3. Skill contribution guidelines and review process?
112
+ 4. Should the Slack/Email/Calendar sync skills require specific setup guides per-platform?
@@ -0,0 +1,326 @@
1
+ # WALL-E Skill Format Specification
2
+
3
+ **Version:** 1.0.0
4
+ **Date:** 2026-03-31
5
+ **Status:** Draft
6
+
7
+ ## Overview
8
+
9
+ A WALL-E skill is a **reusable capability** that the agent can invoke to accomplish work. Skills sit between raw tools (Slack MCP, file I/O, shell) and tasks (scheduled/triggered jobs).
10
+
11
+ ```
12
+ ┌─────────────────────────────────────┐
13
+ │ TASKS (scheduling) │ "Run slack-sync every 15m"
14
+ │ When to run, checkpoints, status │
15
+ ├─────────────────────────────────────┤
16
+ │ SKILLS (capabilities) │ "How to sync Slack messages"
17
+ │ Reusable, composable, shareable │
18
+ ├─────────────────────────────────────┤
19
+ │ TOOLS (primitives) │ Slack MCP, brain DB, shell
20
+ │ Raw APIs, MCP servers │
21
+ └─────────────────────────────────────┘
22
+ ```
23
+
24
+ ## Skill Directory Structure
25
+
26
+ Each skill is a directory containing a `SKILL.md` file and optional supporting files:
27
+
28
+ ```
29
+ skills/
30
+ slack-sync/
31
+ SKILL.md # Required: metadata + instructions
32
+ run.js # Optional: script entry point
33
+ lib/ # Optional: supporting code
34
+ README.md # Optional: human docs
35
+ morning-briefing/
36
+ SKILL.md # Agent-based skill (no script)
37
+ my-custom-skill/
38
+ SKILL.md
39
+ run.sh # Shell scripts work too
40
+ ```
41
+
42
+ ## SKILL.md Format
43
+
44
+ A SKILL.md file has two parts: **YAML frontmatter** (metadata) and **Markdown body** (instructions).
45
+
46
+ ### Minimal Example
47
+
48
+ ```markdown
49
+ ---
50
+ name: hello-world
51
+ description: A simple test skill that greets the user
52
+ version: 1.0.0
53
+ execution: agent
54
+ ---
55
+ # Hello World
56
+
57
+ When invoked, respond with a friendly greeting that includes the owner's name.
58
+ ```
59
+
60
+ ### Full Example
61
+
62
+ ```markdown
63
+ ---
64
+ name: slack-sync
65
+ description: >
66
+ Pull latest Slack messages from active conversations.
67
+ Discovers recently active channels, fetches new messages,
68
+ and stores them in WALL-E's brain for search and context.
69
+ version: 1.2.0
70
+ author: juncao
71
+
72
+ # Execution mode: "script" (deterministic) or "agent" (LLM-driven)
73
+ execution: script
74
+ entry: run.js
75
+ args: ["--sync"]
76
+
77
+ # What this skill needs to run
78
+ requires:
79
+ env: [] # Environment variables (checked at load time)
80
+ tools: [slack-mcp] # MCP servers or tool modules
81
+ skills: [] # Other skills this depends on
82
+
83
+ # Default trigger for tasks that use this skill
84
+ trigger:
85
+ type: interval # interval | cron | manual | event
86
+ schedule: "every 15m" # Human-readable schedule
87
+
88
+ # Skill configuration schema (validated at runtime)
89
+ config:
90
+ mode:
91
+ type: string
92
+ enum: [incremental, full]
93
+ default: incremental
94
+ description: "incremental = only new messages, full = complete backfill"
95
+ max_channels:
96
+ type: number
97
+ default: 50
98
+ description: "Maximum channels to check per run"
99
+
100
+ # Tags for discovery
101
+ tags: [slack, messaging, sync, ingestion]
102
+
103
+ # Permissions this skill requires (shown to user before install)
104
+ permissions:
105
+ - slack:read # Read Slack messages
106
+ - brain:write # Write memories to brain DB
107
+ - network:outbound # Make HTTP requests
108
+ ---
109
+
110
+ # Slack Conversation Sync
111
+
112
+ ## What This Skill Does
113
+
114
+ Incrementally syncs Slack messages from your most active conversations
115
+ into WALL-E's brain. Only checks recently active channels (last 7 days)
116
+ to minimize API calls and run time.
117
+
118
+ ## How It Works
119
+
120
+ 1. Search Slack for YOUR recent messages to discover active channels
121
+ 2. Query brain DB for channels with recent activity
122
+ 3. For each active channel, fetch messages since last sync
123
+ 4. Deduplicate and store new messages as memories
124
+ 5. Emit checkpoint after each channel for resume support
125
+
126
+ ## Configuration
127
+
128
+ - `mode: incremental` — Only pulls channels with activity in the last 7 days (~35 channels, ~1 min)
129
+ - `mode: full` — Pulls ALL known channels (~800 channels, ~15 min)
130
+
131
+ ## Output
132
+
133
+ Returns: `{ new_messages, skipped, channels_done, total_after }`
134
+ ```
135
+
136
+ ## Frontmatter Fields
137
+
138
+ ### Required
139
+
140
+ | Field | Type | Description |
141
+ |-------|------|-------------|
142
+ | `name` | string | Unique skill identifier (kebab-case, e.g., `slack-sync`) |
143
+ | `description` | string | What this skill does. **This is the primary field used for skill discovery.** Write it like search keywords. |
144
+ | `version` | string | Semver version |
145
+ | `execution` | string | `"script"` or `"agent"` |
146
+
147
+ ### Optional
148
+
149
+ | Field | Type | Default | Description |
150
+ |-------|------|---------|-------------|
151
+ | `author` | string | — | Skill author |
152
+ | `entry` | string | `run.js` | Entry point file (for script execution) |
153
+ | `args` | string[] | `[]` | Default arguments passed to entry point |
154
+ | `requires.env` | string[] | `[]` | Required environment variables |
155
+ | `requires.tools` | string[] | `[]` | Required MCP servers or tool modules |
156
+ | `requires.skills` | string[] | `[]` | Other skills this depends on |
157
+ | `trigger.type` | string | `manual` | Default trigger: `interval`, `cron`, `manual`, `event` |
158
+ | `trigger.schedule` | string | — | Default schedule (e.g., `"every 15m"`, `"daily at 7am"`) |
159
+ | `config` | object | `{}` | Configuration schema (JSON Schema subset) |
160
+ | `tags` | string[] | `[]` | Discovery tags |
161
+ | `permissions` | string[] | `[]` | Required permissions (shown before install) |
162
+
163
+ ## Execution Modes
164
+
165
+ ### Script Mode (`execution: script`)
166
+
167
+ Deterministic execution. The skill runs a script file (Node.js, Python, shell) as a child process. No LLM tokens consumed. Fast and predictable.
168
+
169
+ ```yaml
170
+ execution: script
171
+ entry: run.js # Relative to skill directory
172
+ args: ["--sync"] # Default CLI arguments
173
+ ```
174
+
175
+ The script receives configuration via environment variables:
176
+ - `WALL_E_SKILL_CONFIG` — JSON string of the config object
177
+ - `WALL_E_DATA_DIR` — Path to WALL-E's data directory
178
+ - `WALL_E_SKILL_DIR` — Path to this skill's directory
179
+
180
+ Script exit codes:
181
+ - `0` — Success
182
+ - `1` — Failure (stderr captured as error)
183
+ - `2` — Partial success (some work done, checkpoint saved)
184
+
185
+ ### Agent Mode (`execution: agent`)
186
+
187
+ LLM-driven execution. WALL-E reads the SKILL.md instructions and uses available tools to accomplish the task. Flexible but costs tokens.
188
+
189
+ ```yaml
190
+ execution: agent
191
+ ```
192
+
193
+ The Markdown body below the frontmatter becomes the agent's instructions. The agent can use any available tools (MCP servers, brain DB, shell) to follow the instructions.
194
+
195
+ Agent skills are ideal for:
196
+ - Tasks requiring judgment (summarization, analysis)
197
+ - Multi-step workflows that may vary each run
198
+ - Skills that compose other skills
199
+ - Natural language output (briefings, reports)
200
+
201
+ ## Skill Discovery
202
+
203
+ When the agent needs to find relevant skills (e.g., user asks "sync my Slack"), it:
204
+
205
+ 1. Loads all installed skill metadata (name, description, tags)
206
+ 2. Matches against the user's request using description + tags
207
+ 3. For agent-mode skills: reads the full SKILL.md instructions
208
+ 4. For script-mode skills: executes the entry point
209
+
210
+ The `description` field is critical for discovery. Write it with:
211
+ - Action verbs: "Pull", "Sync", "Search", "Analyze"
212
+ - Domain keywords: "Slack", "messages", "channels"
213
+ - Use case phrases: "keep conversation context fresh"
214
+
215
+ ## Skill Locations & Precedence
216
+
217
+ Skills are loaded from multiple locations. Higher precedence wins on name conflicts:
218
+
219
+ 1. **Workspace skills** (highest): `<project>/.wall-e/skills/`
220
+ 2. **User skills**: `~/.wall-e/skills/`
221
+ 3. **Bundled skills**: `wall-e/skills/_bundled/`
222
+ 4. **Registry skills** (lowest): `~/.wall-e/registry-skills/`
223
+
224
+ ## Bundled Skills
225
+
226
+ WALL-E ships with these default skills:
227
+
228
+ | Skill | Execution | Description |
229
+ |-------|-----------|-------------|
230
+ | `slack-sync` | script | Incremental Slack message sync |
231
+ | `slack-backfill` | script | Full Slack history backfill |
232
+ | `slack-search` | agent | Search Slack messages with context |
233
+ | `morning-briefing` | agent | Daily meeting prep with calendar + Slack context |
234
+ | `team-pulse` | agent | Monitor team messages for urgent items |
235
+ | `memory-search` | agent | Search and summarize memories |
236
+
237
+ ## Skill ↔ Task Relationship
238
+
239
+ Tasks reference skills by name. A task defines WHEN to run; the skill defines HOW.
240
+
241
+ ```
242
+ Task: "Conversation Sync"
243
+ type: recurring
244
+ schedule: "every 15m"
245
+ skill: "slack-sync" # ← references the skill
246
+ skill_config: { mode: "incremental" } # ← overrides skill defaults
247
+ ```
248
+
249
+ A task can also chain multiple skills:
250
+ ```
251
+ Task: "Morning Briefing"
252
+ type: recurring
253
+ schedule: "daily at 7am"
254
+ skill: "morning-briefing" # Agent skill that internally uses:
255
+ # - slack-search (find recent context)
256
+ # - memory-search (find related memories)
257
+ # - calendar integration
258
+ ```
259
+
260
+ ## Configuration
261
+
262
+ Skills define a config schema in frontmatter. Tasks can override defaults:
263
+
264
+ ```yaml
265
+ # In SKILL.md
266
+ config:
267
+ mode:
268
+ type: string
269
+ enum: [incremental, full]
270
+ default: incremental
271
+ ```
272
+
273
+ ```json
274
+ // In task definition
275
+ {
276
+ "skill": "slack-sync",
277
+ "skill_config": { "mode": "full" }
278
+ }
279
+ ```
280
+
281
+ ## Skill Development
282
+
283
+ ### Creating a new skill
284
+
285
+ ```bash
286
+ wall-e skill create my-skill # Scaffold a new skill directory
287
+ wall-e skill test my-skill # Run the skill locally
288
+ wall-e skill validate my-skill # Check SKILL.md format
289
+ ```
290
+
291
+ ### Publishing
292
+
293
+ ```bash
294
+ wall-e skill publish my-skill # Publish to registry
295
+ ```
296
+
297
+ ### Installing third-party skills
298
+
299
+ ```bash
300
+ wall-e skill install <name> # From registry
301
+ wall-e skill install <git-url> # From Git repo
302
+ wall-e skill list # Show installed skills
303
+ wall-e skill update --all # Update all skills
304
+ ```
305
+
306
+ ## Security Model
307
+
308
+ 1. **Bundled skills** — Trusted, shipped with WALL-E
309
+ 2. **User skills** — Created by the user, trusted by default
310
+ 3. **Registry skills** — Third-party, require explicit permission grant
311
+ - Permissions declared in `permissions` field
312
+ - Shown to user before installation
313
+ - Sandboxed: no access beyond declared permissions
314
+
315
+ ## Migration from Current System
316
+
317
+ ### Current → New
318
+
319
+ | Current | New |
320
+ |---------|-----|
321
+ | `scripts/slack-backfill.js` | `skills/_bundled/slack-backfill/run.js` + `SKILL.md` |
322
+ | `scripts/slack-channel-history.js` | `skills/_bundled/slack-sync/run.js` + `SKILL.md` |
323
+ | `skills/slack-pull-live.js` | `skills/_bundled/slack-sync/incremental.js` |
324
+ | Task with `execution: script` | Task with `skill: "slack-sync"` |
325
+ | Task with `execution: chat` | Task with `skill: "morning-briefing"` |
326
+ | `skills` DB table | Filesystem-based skills + DB for execution history |