liteagents 2.5.3 → 2.6.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 (70) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +51 -45
  3. package/installer/cli.js +1 -1
  4. package/installer/installation-engine.js +82 -21
  5. package/installer/package-manager.js +34 -3
  6. package/package.json +3 -2
  7. package/packages/ampcode/AGENT.md +1 -0
  8. package/packages/ampcode/commands/friction/friction.js +19 -4
  9. package/packages/ampcode/commands/live-canvas/DESIGN_PRINCIPLES.md +2140 -0
  10. package/packages/ampcode/commands/live-canvas/README.md +273 -0
  11. package/packages/ampcode/commands/live-canvas/templates/.claude/settings.local.json +8 -0
  12. package/packages/ampcode/commands/live-canvas/templates/demo/post-variants.html +205 -0
  13. package/packages/ampcode/commands/live-canvas/templates/feedback-react/FeedbackOverlay.tsx +1299 -0
  14. package/packages/ampcode/commands/live-canvas/templates/feedback-react/format-utils.ts +283 -0
  15. package/packages/ampcode/commands/live-canvas/templates/feedback-react/index.ts +62 -0
  16. package/packages/ampcode/commands/live-canvas/templates/feedback-react/selector-utils.ts +423 -0
  17. package/packages/ampcode/commands/live-canvas/templates/feedback-react/types.ts +118 -0
  18. package/packages/ampcode/commands/live-canvas/templates/overlay-vanilla.js +477 -0
  19. package/packages/ampcode/commands/live-canvas.md +1104 -0
  20. package/packages/claude/CLAUDE.md +1 -0
  21. package/packages/claude/commands/friction/friction.js +19 -4
  22. package/packages/claude/plugins/live-canvas-marketplace/.claude-plugin/marketplace.json +14 -0
  23. package/packages/claude/plugins/live-canvas-marketplace/plugins/live-canvas-channel/.claude-plugin/plugin.json +18 -0
  24. package/packages/claude/plugins/live-canvas-marketplace/plugins/live-canvas-channel/README.md +89 -0
  25. package/packages/claude/plugins/live-canvas-marketplace/plugins/live-canvas-channel/package-lock.json +1142 -0
  26. package/packages/claude/plugins/live-canvas-marketplace/plugins/live-canvas-channel/package.json +17 -0
  27. package/packages/claude/plugins/live-canvas-marketplace/plugins/live-canvas-channel/schema.json +37 -0
  28. package/packages/claude/plugins/live-canvas-marketplace/plugins/live-canvas-channel/server.js +179 -0
  29. package/packages/claude/plugins/live-canvas-marketplace/setup.sh +61 -0
  30. package/packages/claude/skills/live-canvas/DESIGN_PRINCIPLES.md +2140 -0
  31. package/packages/claude/skills/live-canvas/INTEGRATION_NOTES.md +210 -0
  32. package/packages/claude/skills/live-canvas/README.md +273 -0
  33. package/packages/claude/skills/live-canvas/SKILL.md +1119 -0
  34. package/packages/claude/skills/live-canvas/templates/.claude/settings.local.json +8 -0
  35. package/packages/claude/skills/live-canvas/templates/demo/post-variants.html +205 -0
  36. package/packages/claude/skills/live-canvas/templates/feedback-react/FeedbackOverlay.tsx +1299 -0
  37. package/packages/claude/skills/live-canvas/templates/feedback-react/format-utils.ts +283 -0
  38. package/packages/claude/skills/live-canvas/templates/feedback-react/index.ts +62 -0
  39. package/packages/claude/skills/live-canvas/templates/feedback-react/selector-utils.ts +423 -0
  40. package/packages/claude/skills/live-canvas/templates/feedback-react/types.ts +118 -0
  41. package/packages/claude/skills/live-canvas/templates/overlay-vanilla.js +477 -0
  42. package/packages/claude/variants.json +2 -1
  43. package/packages/droid/AGENTS.md +1 -0
  44. package/packages/droid/commands/friction/friction.js +19 -4
  45. package/packages/droid/commands/live-canvas/DESIGN_PRINCIPLES.md +2140 -0
  46. package/packages/droid/commands/live-canvas/README.md +273 -0
  47. package/packages/droid/commands/live-canvas/templates/.claude/settings.local.json +8 -0
  48. package/packages/droid/commands/live-canvas/templates/demo/post-variants.html +205 -0
  49. package/packages/droid/commands/live-canvas/templates/feedback-react/FeedbackOverlay.tsx +1299 -0
  50. package/packages/droid/commands/live-canvas/templates/feedback-react/format-utils.ts +283 -0
  51. package/packages/droid/commands/live-canvas/templates/feedback-react/index.ts +62 -0
  52. package/packages/droid/commands/live-canvas/templates/feedback-react/selector-utils.ts +423 -0
  53. package/packages/droid/commands/live-canvas/templates/feedback-react/types.ts +118 -0
  54. package/packages/droid/commands/live-canvas/templates/overlay-vanilla.js +477 -0
  55. package/packages/droid/commands/live-canvas.md +1104 -0
  56. package/packages/opencode/AGENTS.md +1 -0
  57. package/packages/opencode/command/friction/friction.js +19 -4
  58. package/packages/opencode/command/live-canvas/DESIGN_PRINCIPLES.md +2140 -0
  59. package/packages/opencode/command/live-canvas/README.md +273 -0
  60. package/packages/opencode/command/live-canvas/templates/.claude/settings.local.json +8 -0
  61. package/packages/opencode/command/live-canvas/templates/demo/post-variants.html +205 -0
  62. package/packages/opencode/command/live-canvas/templates/feedback-react/FeedbackOverlay.tsx +1299 -0
  63. package/packages/opencode/command/live-canvas/templates/feedback-react/format-utils.ts +283 -0
  64. package/packages/opencode/command/live-canvas/templates/feedback-react/index.ts +62 -0
  65. package/packages/opencode/command/live-canvas/templates/feedback-react/selector-utils.ts +423 -0
  66. package/packages/opencode/command/live-canvas/templates/feedback-react/types.ts +118 -0
  67. package/packages/opencode/command/live-canvas/templates/overlay-vanilla.js +477 -0
  68. package/packages/opencode/command/live-canvas.md +1104 -0
  69. package/packages/opencode/opencode.jsonc +4 -0
  70. package/packages/subagentic-manual.md +15 -12
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "live-canvas-channel",
3
+ "version": "0.1.0",
4
+ "description": "MCP channel server: bridges Live Canvas HTTP overlay events into the Claude Code session.",
5
+ "main": "server.js",
6
+ "type": "commonjs",
7
+ "engines": {
8
+ "node": ">=18"
9
+ },
10
+ "scripts": {
11
+ "start": "node server.js"
12
+ },
13
+ "dependencies": {
14
+ "@modelcontextprotocol/sdk": "^1.0.0"
15
+ },
16
+ "license": "MIT"
17
+ }
@@ -0,0 +1,37 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "title": "LiveCanvasFeedback",
4
+ "description": "Payload shape posted by the Live Canvas overlay to POST /feedback. Wire-compatible with the v1.0 schema produced by overlay-vanilla.js and the upstream React FeedbackOverlay.",
5
+ "type": "object",
6
+ "required": ["version", "target", "comment"],
7
+ "properties": {
8
+ "version": { "type": "string", "enum": ["1.0"] },
9
+ "target": { "type": "string" },
10
+ "comment": {
11
+ "type": "object",
12
+ "required": ["id", "variant", "element", "text"],
13
+ "properties": {
14
+ "id": { "type": "string" },
15
+ "variant": { "type": "string", "enum": ["A", "B", "C", "D", "E", "F"] },
16
+ "element": {
17
+ "type": "object",
18
+ "required": ["selector", "tagName"],
19
+ "properties": {
20
+ "selector": { "type": "string" },
21
+ "readablePath": { "type": "string" },
22
+ "tagName": { "type": "string" },
23
+ "textContent": { "type": "string" },
24
+ "className": { "type": "string" },
25
+ "attributes": { "type": "object", "additionalProperties": { "type": "string" } }
26
+ }
27
+ },
28
+ "coordinates": {
29
+ "type": "object",
30
+ "properties": { "x": { "type": "number" }, "y": { "type": "number" } }
31
+ },
32
+ "text": { "type": "string" },
33
+ "timestamp": { "type": "number" }
34
+ }
35
+ }
36
+ }
37
+ }
@@ -0,0 +1,179 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * live-canvas-channel — MCP channel server for Claude Code.
4
+ *
5
+ * Two concurrent duties:
6
+ * 1. HTTP listener (LIVE_CANVAS_PORT, default 8788) — accepts feedback
7
+ * POSTs from the Live Canvas overlay running in the browser. The
8
+ * overlay probes GET /health to decide Live vs Batch mode.
9
+ * 2. MCP stdio server — declares the `experimental: claude/channel`
10
+ * capability and, on each valid POST, emits a
11
+ * `notifications/claude/channel` notification so the feedback lands
12
+ * in the active Claude turn.
13
+ *
14
+ * Protocol reference: https://code.claude.com/docs/en/channels-reference
15
+ */
16
+
17
+ 'use strict';
18
+
19
+ const http = require('http');
20
+ const { Server } = require('@modelcontextprotocol/sdk/server/index.js');
21
+ const { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js');
22
+
23
+ const PORT = Number(process.env.LIVE_CANVAS_PORT || 8788);
24
+ const SERVER_NAME = 'live-canvas';
25
+ const SERVER_VERSION = '0.1.0';
26
+
27
+ // ---------- MCP server ----------
28
+
29
+ const mcp = new Server(
30
+ { name: SERVER_NAME, version: SERVER_VERSION },
31
+ {
32
+ capabilities: { experimental: { 'claude/channel': {} } },
33
+ instructions: [
34
+ 'Events from the live-canvas channel arrive as <channel source="live-canvas" ...> tags.',
35
+ 'Each event is a single click-to-annotate comment made by the user on a UI variant in their browser.',
36
+ 'Tag attributes: target (component name), variant (A-F), selector (CSS selector of the clicked element),',
37
+ 'tagName (HTML tag), commentId (unique id). The body is the user\'s feedback text.',
38
+ 'When one arrives: acknowledge the feedback briefly, then edit the corresponding variant file',
39
+ 'in .claude-design/lab/ using the selector to locate the element. This is a one-way channel —',
40
+ 'no reply tool; respond to the user in chat as you would any normal message.',
41
+ ].join(' '),
42
+ }
43
+ );
44
+
45
+ async function emitChannel(content, meta) {
46
+ await mcp.notification({
47
+ method: 'notifications/claude/channel',
48
+ params: { content, meta },
49
+ });
50
+ }
51
+
52
+ // ---------- HTTP helpers ----------
53
+
54
+ function readBody(req) {
55
+ return new Promise((resolve, reject) => {
56
+ let data = '';
57
+ req.on('data', (c) => {
58
+ data += c;
59
+ if (data.length > 1e6) { req.destroy(); reject(new Error('payload too large')); }
60
+ });
61
+ req.on('end', () => resolve(data));
62
+ req.on('error', reject);
63
+ });
64
+ }
65
+
66
+ function cors(res) {
67
+ res.setHeader('Access-Control-Allow-Origin', '*');
68
+ res.setHeader('Access-Control-Allow-Methods', 'GET,POST,OPTIONS');
69
+ res.setHeader('Access-Control-Allow-Headers', 'content-type');
70
+ }
71
+
72
+ function validate(payload) {
73
+ if (!payload || payload.version !== '1.0') return 'version must be "1.0"';
74
+ if (typeof payload.target !== 'string') return 'target required';
75
+ const c = payload.comment;
76
+ if (!c || typeof c !== 'object') return 'comment required';
77
+ if (!c.variant || !/^[A-F]$/.test(c.variant)) return 'invalid variant';
78
+ if (!c.element || typeof c.element.selector !== 'string') return 'element.selector required';
79
+ if (typeof c.text !== 'string') return 'comment.text required';
80
+ return null;
81
+ }
82
+
83
+ // Human-readable body the assistant will see inside the Claude turn.
84
+ function formatContent(target, comment) {
85
+ const { variant, element, text } = comment;
86
+ const label = element.textContent ? `, ${element.tagName} with "${element.textContent}"` : '';
87
+ return [
88
+ `[LIVE-CANVAS ${variant} · ${target}] ${text}`,
89
+ ` selector: \`${element.selector}\`${label}`,
90
+ ` comment_id: ${comment.id}`,
91
+ ].join('\n');
92
+ }
93
+
94
+ // All values in `meta` must be strings per the claude/channel contract.
95
+ function buildMeta(target, comment) {
96
+ return {
97
+ source: 'live-canvas',
98
+ target,
99
+ variant: comment.variant,
100
+ selector: comment.element.selector,
101
+ tagName: comment.element.tagName,
102
+ commentId: comment.id,
103
+ };
104
+ }
105
+
106
+ // ---------- HTTP server ----------
107
+
108
+ const server = http.createServer(async (req, res) => {
109
+ cors(res);
110
+
111
+ if (req.method === 'OPTIONS') { res.writeHead(204); res.end(); return; }
112
+
113
+ if (req.method === 'GET' && req.url === '/health') {
114
+ res.writeHead(200, { 'content-type': 'application/json' });
115
+ res.end(JSON.stringify({ ok: true, channel: SERVER_NAME, port: PORT }));
116
+ return;
117
+ }
118
+
119
+ if (req.method === 'POST' && req.url === '/feedback') {
120
+ try {
121
+ const raw = await readBody(req);
122
+ const payload = JSON.parse(raw);
123
+ const err = validate(payload);
124
+ if (err) {
125
+ res.writeHead(400, { 'content-type': 'application/json' });
126
+ res.end(JSON.stringify({ error: err }));
127
+ return;
128
+ }
129
+
130
+ try {
131
+ await emitChannel(
132
+ formatContent(payload.target, payload.comment),
133
+ buildMeta(payload.target, payload.comment)
134
+ );
135
+ } catch (e) {
136
+ // MCP transport not yet connected or closed — still ack the HTTP
137
+ // caller so the overlay doesn't false-negative.
138
+ process.stderr.write(`[live-canvas] notify failed: ${e.message || e}\n`);
139
+ }
140
+
141
+ res.writeHead(200, { 'content-type': 'application/json' });
142
+ res.end(JSON.stringify({ ok: true }));
143
+ } catch (e) {
144
+ res.writeHead(400, { 'content-type': 'application/json' });
145
+ res.end(JSON.stringify({ error: String(e.message || e) }));
146
+ }
147
+ return;
148
+ }
149
+
150
+ res.writeHead(404); res.end();
151
+ });
152
+
153
+ server.on('error', (err) => {
154
+ if (err.code === 'EADDRINUSE') {
155
+ process.stderr.write(`[live-canvas] port ${PORT} in use — another session likely owns it; exiting.\n`);
156
+ process.exit(0);
157
+ }
158
+ process.stderr.write(`[live-canvas] http error: ${err}\n`);
159
+ process.exit(1);
160
+ });
161
+
162
+ // ---------- startup ----------
163
+
164
+ async function main() {
165
+ const transport = new StdioServerTransport();
166
+ await mcp.connect(transport);
167
+
168
+ server.listen(PORT, '127.0.0.1', () => {
169
+ process.stderr.write(`[live-canvas] listening on 127.0.0.1:${PORT}\n`);
170
+ });
171
+ }
172
+
173
+ process.on('SIGTERM', () => { server.close(() => process.exit(0)); });
174
+ process.on('SIGINT', () => { server.close(() => process.exit(0)); });
175
+
176
+ main().catch((err) => {
177
+ process.stderr.write(`[live-canvas] fatal: ${err}\n`);
178
+ process.exit(1);
179
+ });
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env bash
2
+ # Live Canvas channel — one-time setup helper.
3
+ #
4
+ # Run this once from a shell, then follow the printed manual steps in Claude Code.
5
+ # Safe to re-run; `npm install` is idempotent.
6
+
7
+ set -e
8
+ HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
9
+ PLUGIN_DIR="$HERE/plugins/live-canvas-channel"
10
+ MARKETPLACE_PATH="$HERE"
11
+
12
+ bold() { printf '\033[1m%s\033[0m\n' "$*"; }
13
+ ok() { printf '\033[32m✓\033[0m %s\n' "$*"; }
14
+ warn() { printf '\033[33m!\033[0m %s\n' "$*"; }
15
+
16
+ if ! command -v node >/dev/null 2>&1; then
17
+ warn "Node.js not found. Install Node >= 18 first: https://nodejs.org"
18
+ exit 1
19
+ fi
20
+
21
+ NODE_MAJOR="$(node -p 'process.versions.node.split(".")[0]')"
22
+ if [ "$NODE_MAJOR" -lt 18 ]; then
23
+ warn "Node >= 18 required (found $(node -v))."
24
+ exit 1
25
+ fi
26
+
27
+ if ! command -v npm >/dev/null 2>&1; then
28
+ warn "npm not found. Usually ships with Node."
29
+ exit 1
30
+ fi
31
+
32
+ bold "Installing channel plugin dependencies…"
33
+ cd "$PLUGIN_DIR"
34
+ npm install --silent
35
+ ok "Dependencies installed in $PLUGIN_DIR"
36
+
37
+ echo
38
+ bold "Next steps (run these inside Claude Code):"
39
+ cat <<EOF
40
+
41
+ 1. Register this marketplace:
42
+ /plugin marketplace add $MARKETPLACE_PATH
43
+
44
+ 2. Install the plugin from it:
45
+ /plugin install live-canvas-channel@live-canvas-marketplace
46
+
47
+ 3. Close this session and start a new one with the dev-channels flag:
48
+ claude --dangerously-load-development-channels plugin:live-canvas-channel@live-canvas-marketplace
49
+
50
+ 4. Confirm the one-time safety prompt. Channel is now listening on
51
+ port 8788 for overlay feedback events.
52
+
53
+ 5. Run /live-canvas to generate variants in any project. The skill will
54
+ auto-detect the channel and use Live mode.
55
+
56
+ Tip — save yourself typing with a shell alias in ~/.zshrc or ~/.bashrc:
57
+ alias claude-live='claude --dangerously-load-development-channels plugin:live-canvas-channel@live-canvas-marketplace'
58
+
59
+ EOF
60
+
61
+ ok "Setup complete."