@treenity/mods 3.0.3 → 3.0.4

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 (116) hide show
  1. package/dist/agent/client.d.ts +3 -0
  2. package/dist/agent/client.d.ts.map +1 -0
  3. package/dist/agent/client.js +3 -0
  4. package/dist/agent/client.js.map +1 -0
  5. package/dist/agent/guardian.d.ts +47 -0
  6. package/dist/agent/guardian.d.ts.map +1 -0
  7. package/dist/agent/guardian.js +452 -0
  8. package/dist/agent/guardian.js.map +1 -0
  9. package/dist/agent/seed.d.ts +2 -0
  10. package/dist/agent/seed.d.ts.map +1 -0
  11. package/dist/agent/seed.js +68 -0
  12. package/dist/agent/seed.js.map +1 -0
  13. package/dist/agent/server.d.ts +5 -0
  14. package/dist/agent/server.d.ts.map +1 -0
  15. package/dist/agent/server.js +5 -0
  16. package/dist/agent/server.js.map +1 -0
  17. package/dist/agent/service.d.ts +2 -0
  18. package/dist/agent/service.d.ts.map +1 -0
  19. package/dist/agent/service.js +556 -0
  20. package/dist/agent/service.js.map +1 -0
  21. package/dist/agent/types.d.ts +115 -0
  22. package/dist/agent/types.d.ts.map +1 -0
  23. package/dist/agent/types.js +168 -0
  24. package/dist/agent/types.js.map +1 -0
  25. package/dist/agent/view.d.ts +2 -0
  26. package/dist/agent/view.d.ts.map +1 -0
  27. package/dist/agent/view.js +137 -0
  28. package/dist/agent/view.js.map +1 -0
  29. package/dist/mcp/mcp-server.d.ts +16 -0
  30. package/dist/mcp/mcp-server.d.ts.map +1 -0
  31. package/dist/mcp/mcp-server.js +344 -0
  32. package/dist/mcp/mcp-server.js.map +1 -0
  33. package/dist/mcp/server.d.ts +3 -0
  34. package/dist/mcp/server.d.ts.map +1 -0
  35. package/dist/mcp/server.js +3 -0
  36. package/dist/mcp/server.js.map +1 -0
  37. package/dist/mcp/service.d.ts +2 -0
  38. package/dist/mcp/service.d.ts.map +1 -0
  39. package/dist/mcp/service.js +16 -0
  40. package/dist/mcp/service.js.map +1 -0
  41. package/dist/mcp/types.d.ts +4 -0
  42. package/dist/mcp/types.d.ts.map +1 -0
  43. package/dist/mcp/types.js +6 -0
  44. package/dist/mcp/types.js.map +1 -0
  45. package/dist/metatron/claude.d.ts +30 -0
  46. package/dist/metatron/claude.d.ts.map +1 -0
  47. package/dist/metatron/claude.js +201 -0
  48. package/dist/metatron/claude.js.map +1 -0
  49. package/dist/metatron/client.d.ts +3 -0
  50. package/dist/metatron/client.d.ts.map +1 -0
  51. package/dist/metatron/client.js +3 -0
  52. package/dist/metatron/client.js.map +1 -0
  53. package/dist/metatron/mentions.d.ts +9 -0
  54. package/dist/metatron/mentions.d.ts.map +1 -0
  55. package/dist/metatron/mentions.js +21 -0
  56. package/dist/metatron/mentions.js.map +1 -0
  57. package/dist/metatron/permissions.d.ts +16 -0
  58. package/dist/metatron/permissions.d.ts.map +1 -0
  59. package/dist/metatron/permissions.js +52 -0
  60. package/dist/metatron/permissions.js.map +1 -0
  61. package/dist/metatron/seed.d.ts +2 -0
  62. package/dist/metatron/seed.d.ts.map +1 -0
  63. package/dist/metatron/seed.js +41 -0
  64. package/dist/metatron/seed.js.map +1 -0
  65. package/dist/metatron/server.d.ts +4 -0
  66. package/dist/metatron/server.d.ts.map +1 -0
  67. package/dist/metatron/server.js +4 -0
  68. package/dist/metatron/server.js.map +1 -0
  69. package/dist/metatron/service.d.ts +2 -0
  70. package/dist/metatron/service.d.ts.map +1 -0
  71. package/dist/metatron/service.js +361 -0
  72. package/dist/metatron/service.js.map +1 -0
  73. package/dist/metatron/types.d.ts +76 -0
  74. package/dist/metatron/types.d.ts.map +1 -0
  75. package/dist/metatron/types.js +112 -0
  76. package/dist/metatron/types.js.map +1 -0
  77. package/dist/metatron/view.d.ts +4 -0
  78. package/dist/metatron/view.d.ts.map +1 -0
  79. package/dist/metatron/view.js +5 -0
  80. package/dist/metatron/view.js.map +1 -0
  81. package/dist/metatron/views/config.d.ts +2 -0
  82. package/dist/metatron/views/config.d.ts.map +1 -0
  83. package/dist/metatron/views/config.js +116 -0
  84. package/dist/metatron/views/config.js.map +1 -0
  85. package/dist/metatron/views/log.d.ts +18 -0
  86. package/dist/metatron/views/log.d.ts.map +1 -0
  87. package/dist/metatron/views/log.js +224 -0
  88. package/dist/metatron/views/log.js.map +1 -0
  89. package/dist/metatron/views/shared.d.ts +13 -0
  90. package/dist/metatron/views/shared.d.ts.map +1 -0
  91. package/dist/metatron/views/shared.js +33 -0
  92. package/dist/metatron/views/shared.js.map +1 -0
  93. package/dist/metatron/views/task.d.ts +4 -0
  94. package/dist/metatron/views/task.d.ts.map +1 -0
  95. package/dist/metatron/views/task.js +106 -0
  96. package/dist/metatron/views/task.js.map +1 -0
  97. package/dist/metatron/views/workspace.d.ts +2 -0
  98. package/dist/metatron/views/workspace.d.ts.map +1 -0
  99. package/dist/metatron/views/workspace.js +138 -0
  100. package/dist/metatron/views/workspace.js.map +1 -0
  101. package/metatron/CLAUDE.md +22 -0
  102. package/metatron/claude.ts +258 -0
  103. package/metatron/client.ts +2 -0
  104. package/metatron/mentions.ts +31 -0
  105. package/metatron/permissions.ts +76 -0
  106. package/metatron/seed.ts +50 -0
  107. package/metatron/server.ts +3 -0
  108. package/metatron/service.ts +406 -0
  109. package/metatron/types.ts +120 -0
  110. package/metatron/view.tsx +4 -0
  111. package/metatron/views/config.tsx +408 -0
  112. package/metatron/views/log.tsx +412 -0
  113. package/metatron/views/shared.tsx +40 -0
  114. package/metatron/views/task.tsx +255 -0
  115. package/metatron/views/workspace.tsx +418 -0
  116. package/package.json +2 -1
@@ -0,0 +1,106 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { register } from '@treenity/core';
3
+ import { execute } from '@treenity/react/hooks';
4
+ import { cn } from '@treenity/react/lib/utils';
5
+ import { useCallback, useEffect, useState } from 'react';
6
+ import { LogRenderer, Md } from './log';
7
+ import { formatTime, StatusBadge, StatusDot } from './shared';
8
+ // ── Stop button ──
9
+ function StopButton({ taskPath }) {
10
+ const [stopping, setStopping] = useState(false);
11
+ const handleStop = useCallback(async (e) => {
12
+ e.stopPropagation();
13
+ setStopping(true);
14
+ try {
15
+ await execute(taskPath, 'stop', {});
16
+ }
17
+ finally {
18
+ setStopping(false);
19
+ }
20
+ }, [taskPath]);
21
+ return (_jsx("button", { onClick: handleStop, disabled: stopping, className: "w-5 h-5 rounded flex items-center justify-center bg-red-500/15 hover:bg-red-500/25 transition-all duration-150 shrink-0", title: "Stop task", children: _jsx("span", { className: cn('w-2 h-2 rounded-[1px] bg-red-400', stopping && 'opacity-50') }) }));
22
+ }
23
+ // ── Inject input ──
24
+ function InjectInput({ taskPath }) {
25
+ const [text, setText] = useState('');
26
+ const [sending, setSending] = useState(false);
27
+ const handleSend = useCallback(async () => {
28
+ const t = text.trim();
29
+ if (!t)
30
+ return;
31
+ setSending(true);
32
+ try {
33
+ await execute(taskPath, 'inject', { text: t });
34
+ setText('');
35
+ }
36
+ finally {
37
+ setSending(false);
38
+ }
39
+ }, [text, taskPath]);
40
+ return (_jsx("div", { className: "mt-2 pt-2 border-t border-zinc-800/40", children: _jsxs("div", { className: "relative", children: [_jsx("textarea", { value: text, onChange: e => setText(e.target.value), onKeyDown: e => { if (e.key === 'Enter' && (e.metaKey || e.ctrlKey))
41
+ handleSend(); }, rows: 1, placeholder: "Queue a follow-up message...", className: "w-full bg-zinc-950 border border-zinc-800 rounded-lg px-3 py-2 pr-16 text-xs text-zinc-200 resize-none focus:outline-none focus:border-violet-600/50 placeholder:text-zinc-700" }), _jsx("button", { onClick: handleSend, disabled: sending || !text.trim(), className: cn('absolute right-1.5 bottom-1.5 px-2.5 py-1 rounded-md text-[10px] font-semibold transition-all duration-150', text.trim()
42
+ ? 'bg-amber-600 hover:bg-amber-500 text-white'
43
+ : 'bg-zinc-800 text-zinc-600 cursor-not-allowed'), children: sending ? '...' : 'Queue' })] }) }));
44
+ }
45
+ // ── Task row (used in config lists) ──
46
+ export function TaskRow({ task }) {
47
+ const status = task.status || 'pending';
48
+ const isRunning = status === 'running';
49
+ const isActive = isRunning || status === 'done';
50
+ const [expanded, setExpanded] = useState(isActive);
51
+ const prompt = task.prompt || '';
52
+ const result = task.result || '';
53
+ const taskLog = task.log || '';
54
+ const hasLog = !!taskLog;
55
+ const [tab, setTab] = useState(hasLog ? 'log' : 'result');
56
+ const time = task.createdAt ? formatTime(task.createdAt) : '';
57
+ return (_jsxs("div", { className: cn('rounded-xl border transition-all duration-200', expanded ? 'bg-zinc-900/80 border-zinc-800' : 'bg-zinc-900/40 border-zinc-800/60 hover:border-zinc-700'), children: [_jsxs("div", { className: "flex items-center gap-2.5 px-3.5 py-2.5 cursor-pointer select-none", onClick: () => setExpanded(!expanded), children: [_jsx(StatusDot, { status: status }), _jsx("span", { className: "text-sm text-zinc-300 truncate flex-1", children: prompt }), isRunning && _jsx(StopButton, { taskPath: task.$path }), _jsx("span", { className: "text-[10px] text-zinc-600 shrink-0 font-mono", children: time }), _jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", className: cn('text-zinc-600 transition-transform duration-200 shrink-0', expanded && 'rotate-90'), children: _jsx("path", { d: "M9 18l6-6-6-6" }) })] }), expanded && (_jsxs("div", { className: "border-t border-zinc-800/60", children: [_jsx("div", { className: "flex gap-1 px-2 py-1", children: ['log', 'result'].map(t => (_jsx("button", { onClick: () => setTab(t), className: cn('px-2 py-0.5 rounded-md text-[11px] font-medium transition-all duration-150', tab === t
58
+ ? 'bg-zinc-800 text-zinc-200'
59
+ : 'text-zinc-600 hover:text-zinc-400'), children: t }, t))) }), _jsx("div", { className: "max-h-[60vh] overflow-y-auto", children: _jsx(LogRenderer, { text: tab === 'result' ? (result || 'No result yet') : (taskLog || result || 'No log yet') }) }), isRunning && _jsx(InjectInput, { taskPath: task.$path })] }))] }));
60
+ }
61
+ // ── Running indicator — animated ping ──
62
+ function RunningPing({ color = 'sky' }) {
63
+ const colors = {
64
+ sky: { ping: 'bg-sky-400', dot: 'bg-sky-500 shadow-sky-500/50' },
65
+ emerald: { ping: 'bg-emerald-400', dot: 'bg-emerald-500 shadow-emerald-500/50' },
66
+ amber: { ping: 'bg-amber-400', dot: 'bg-amber-500 shadow-amber-500/50' },
67
+ };
68
+ const c = colors[color];
69
+ return (_jsxs("span", { className: "relative flex h-3 w-3 shrink-0", children: [_jsx("span", { className: cn('animate-ping absolute inline-flex h-full w-full rounded-full opacity-75', c.ping) }), _jsx("span", { className: cn('relative inline-flex h-3 w-3 rounded-full shadow-lg', c.dot) })] }));
70
+ }
71
+ // ── Elapsed time hook ──
72
+ // XXX: should be two different operations, n ot one. use elapset return just number, and then it formatted as wanted
73
+ function useElapsed(startTs, active) {
74
+ const [now, setNow] = useState(Date.now());
75
+ useEffect(() => {
76
+ if (!active || !startTs)
77
+ return;
78
+ const id = setInterval(() => setNow(Date.now()), 1000);
79
+ return () => clearInterval(id);
80
+ }, [active, startTs]);
81
+ if (!startTs)
82
+ return '';
83
+ const s = Math.floor(((active ? now : Date.now()) - startTs) / 1000);
84
+ if (s < 60)
85
+ return `${s}s`;
86
+ if (s < 3600)
87
+ return `${Math.floor(s / 60)}m ${s % 60}s`;
88
+ return `${Math.floor(s / 3600)}h ${Math.floor((s % 3600) / 60)}m`;
89
+ }
90
+ // ── Task view (individual task page /t/.../tasks/xxx) ──
91
+ const TaskView = ({ value, ctx }) => {
92
+ const path = ctx.path;
93
+ const status = value.status || 'pending';
94
+ const isRunning = status === 'running';
95
+ const result = value.result || '';
96
+ const taskLog = value.log || '';
97
+ const [tab, setTab] = useState(taskLog ? 'log' : 'result');
98
+ const elapsed = useElapsed(value.createdAt, isRunning);
99
+ return (_jsxs("div", { className: "flex flex-col gap-5 p-5 max-w-4xl", children: [_jsxs("div", { className: "flex items-center gap-3", children: [isRunning ? _jsx(RunningPing, {}) : _jsx(StatusDot, { status: status }), _jsx(StatusBadge, { status: status }), _jsxs("div", { className: "flex items-center gap-2 ml-auto", children: [elapsed && (_jsx("span", { className: cn('text-[10px] font-mono tabular-nums', isRunning ? 'text-sky-400/70' : 'text-zinc-600'), children: elapsed })), _jsx("span", { className: "text-[10px] text-zinc-600 font-mono tabular-nums", children: value.createdAt ? formatTime(value.createdAt) : '' }), isRunning && _jsx(StopButton, { taskPath: path })] })] }), _jsx("div", { className: "bg-zinc-900/40 rounded-xl px-4 py-3 border border-zinc-800/40", children: _jsx(Md, { className: "text-sm text-zinc-300 leading-relaxed", text: value.prompt }) }), _jsx("div", { className: "flex gap-0.5 bg-zinc-900/40 rounded-lg p-0.5 w-fit", children: ['log', 'result'].map(t => (_jsx("button", { onClick: () => setTab(t), className: cn('px-3.5 py-1 rounded-md text-xs font-medium transition-all duration-150', tab === t
100
+ ? 'bg-zinc-800 text-zinc-200 shadow-sm'
101
+ : 'text-zinc-500 hover:text-zinc-300'), children: t }, t))) }), _jsx("div", { className: cn('rounded-xl px-3 py-2.5 max-h-[75vh] overflow-y-auto border transition-all duration-300', isRunning
102
+ ? 'bg-zinc-950 border-sky-500/15 shadow-lg shadow-sky-500/5'
103
+ : 'bg-zinc-950 border-zinc-800'), children: _jsx(LogRenderer, { text: tab === 'result' ? (result || 'No result yet') : (taskLog || result || 'No log yet') }) }), isRunning && _jsx(InjectInput, { taskPath: path })] }));
104
+ };
105
+ register('metatron.task', 'react', TaskView);
106
+ //# sourceMappingURL=task.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task.js","sourceRoot":"","sources":["../../../metatron/views/task.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=workspace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../../metatron/views/workspace.tsx"],"names":[],"mappings":""}
@@ -0,0 +1,138 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { register } from '@treenity/core';
3
+ import { Render } from '@treenity/react/context';
4
+ import { execute, useChildren, usePath } from '@treenity/react/hooks';
5
+ import { cn } from '@treenity/react/lib/utils';
6
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
7
+ import { MetatronWorkspace } from '../types';
8
+ import { LogRenderer } from './log';
9
+ import { formatTime, StatusDot } from './shared';
10
+ // ── Command Picker (modal overlay for adding columns) ──
11
+ function CommandPicker({ configPath, exclude, onSelect, onNewTask, onClose }) {
12
+ const [query, setQuery] = useState('');
13
+ const [sessions, setSessions] = useState([]);
14
+ const [searchResults, setSearchResults] = useState([]);
15
+ const [searching, setSearching] = useState(false);
16
+ const [newTaskPrompt, setNewTaskPrompt] = useState('');
17
+ const inputRef = useRef(null);
18
+ const backdropRef = useRef(null);
19
+ const allTasks = useChildren(`${configPath}/tasks`, { watch: true });
20
+ const tasks = (allTasks ?? [])
21
+ .filter(t => t.$type === 'metatron.task' && !exclude.includes(t.$path))
22
+ .sort((a, b) => (b.createdAt || 0) - (a.createdAt || 0));
23
+ // Load sessions on mount
24
+ useEffect(() => {
25
+ execute(configPath, 'listSessions', { lastN: 50 }).then(r => {
26
+ if (Array.isArray(r))
27
+ setSessions(r);
28
+ });
29
+ }, [configPath]);
30
+ // Auto-focus
31
+ useEffect(() => { inputRef.current?.focus(); }, []);
32
+ // Close on Escape
33
+ useEffect(() => {
34
+ const handler = (e) => { if (e.key === 'Escape')
35
+ onClose(); };
36
+ window.addEventListener('keydown', handler);
37
+ return () => window.removeEventListener('keydown', handler);
38
+ }, [onClose]);
39
+ // Debounced search
40
+ useEffect(() => {
41
+ if (!query.trim()) {
42
+ setSearchResults([]);
43
+ return;
44
+ }
45
+ const timer = setTimeout(async () => {
46
+ setSearching(true);
47
+ try {
48
+ const r = await execute(configPath, 'searchSessions', { query: query.trim(), maxResults: 20 });
49
+ if (Array.isArray(r))
50
+ setSearchResults(r);
51
+ }
52
+ finally {
53
+ setSearching(false);
54
+ }
55
+ }, 300);
56
+ return () => clearTimeout(timer);
57
+ }, [query, configPath]);
58
+ const isSearching = !!query.trim();
59
+ const filteredTasks = isSearching
60
+ ? tasks.filter(t => String(t.prompt ?? '').toLowerCase().includes(query.toLowerCase()))
61
+ : tasks;
62
+ const filteredSessions = isSearching
63
+ ? sessions.filter(s => s.firstMessage.toLowerCase().includes(query.toLowerCase()))
64
+ : sessions;
65
+ const handleNewTask = () => {
66
+ const text = newTaskPrompt.trim();
67
+ if (!text)
68
+ return;
69
+ onNewTask(text);
70
+ onClose();
71
+ };
72
+ return (_jsx("div", { ref: backdropRef, className: "fixed inset-0 z-50 flex items-start justify-center pt-[15vh] bg-black/60 backdrop-blur-sm", onClick: e => { if (e.target === backdropRef.current)
73
+ onClose(); }, children: _jsxs("div", { className: "w-full max-w-lg bg-zinc-900 border border-zinc-800 rounded-2xl shadow-2xl shadow-black/40 overflow-hidden flex flex-col max-h-[60vh]", children: [_jsxs("div", { className: "flex items-center gap-2 px-4 py-3 border-b border-zinc-800", children: [_jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", className: "text-zinc-500 shrink-0", children: [_jsx("circle", { cx: "11", cy: "11", r: "8" }), _jsx("path", { d: "M21 21l-4.35-4.35" })] }), _jsx("input", { ref: inputRef, value: query, onChange: e => setQuery(e.target.value), placeholder: "Search tasks and sessions...", className: "flex-1 bg-transparent text-sm text-zinc-200 placeholder:text-zinc-600 focus:outline-none" }), searching && (_jsx("span", { className: "text-[10px] text-zinc-600 animate-pulse", children: "searching..." })), _jsx("button", { onClick: onClose, className: "text-zinc-600 hover:text-zinc-400 transition-colors", children: _jsx("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M18 6L6 18M6 6l12 12" }) }) })] }), _jsxs("div", { className: "overflow-y-auto flex-1", children: [!isSearching && (_jsxs("div", { className: "flex flex-col gap-2 px-4 py-2.5 border-b border-zinc-800/60", children: [_jsx("textarea", { value: newTaskPrompt, onChange: e => setNewTaskPrompt(e.target.value), onKeyDown: e => { if (e.key === 'Enter' && (e.metaKey || e.ctrlKey) && newTaskPrompt.trim())
74
+ handleNewTask(); }, rows: 2, placeholder: "New task prompt...", className: "w-full bg-zinc-950 border border-zinc-800 rounded-lg px-3 py-2 text-xs text-zinc-200 resize-none focus:outline-none focus:border-violet-600/50 placeholder:text-zinc-700" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { onClick: handleNewTask, disabled: !newTaskPrompt.trim(), className: "px-3 py-1.5 rounded-lg text-[11px] font-medium bg-violet-600 hover:bg-violet-500 text-white disabled:bg-zinc-800 disabled:text-zinc-600 transition-all shrink-0", children: "Create & add" }), _jsx("span", { className: "text-[10px] text-zinc-700", children: "Cmd+Enter" })] })] })), isSearching && searchResults.length > 0 && (_jsxs("div", { className: "py-1", children: [_jsx("div", { className: "px-4 py-1.5", children: _jsxs("span", { className: "text-[10px] text-zinc-600 uppercase tracking-wider font-medium", children: ["Session matches (", searchResults.length, ")"] }) }), searchResults.map((r, i) => (_jsxs("button", { onClick: () => { onSelect(`session:${r.sessionId}`); onClose(); }, className: "flex flex-col gap-1 w-full px-4 py-2.5 text-left hover:bg-zinc-800/60 transition-colors", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: "text-[10px] text-zinc-600 font-mono", children: r.date }), _jsx("span", { className: cn('text-[10px] font-medium', r.role === 'user' ? 'text-sky-500' : 'text-emerald-500'), children: r.role }), _jsx("span", { className: "text-[10px] text-zinc-700 ml-auto font-mono", children: r.score.toFixed(1) })] }), _jsx("span", { className: "text-xs text-zinc-400 line-clamp-2 leading-relaxed", children: r.snippet })] }, `sr-${i}`)))] })), filteredTasks.length > 0 && (_jsxs("div", { className: "py-1", children: [_jsx("div", { className: "px-4 py-1.5", children: _jsx("span", { className: "text-[10px] text-zinc-600 uppercase tracking-wider font-medium", children: "Tasks" }) }), filteredTasks.map(t => (_jsxs("button", { onClick: () => { onSelect(t.$path); onClose(); }, className: "flex items-center gap-2.5 w-full px-4 py-2 text-left hover:bg-zinc-800/60 transition-colors", children: [_jsx(StatusDot, { status: t.status || 'pending' }), _jsx("span", { className: "text-xs text-zinc-300 truncate flex-1", children: String(t.prompt ?? '').slice(0, 80) }), _jsx("span", { className: "text-[10px] text-zinc-700 font-mono shrink-0", children: t.createdAt ? formatTime(t.createdAt) : '' })] }, t.$path)))] })), !isSearching && filteredSessions.length > 0 && (_jsxs("div", { className: "py-1 border-t border-zinc-800/60", children: [_jsx("div", { className: "px-4 py-1.5", children: _jsx("span", { className: "text-[10px] text-zinc-600 uppercase tracking-wider font-medium", children: "Claude Code sessions" }) }), filteredSessions.slice(0, 20).map(s => (_jsxs("button", { onClick: () => { onSelect(`session:${s.id}`); onClose(); }, className: "flex items-center gap-2.5 w-full px-4 py-2 text-left hover:bg-zinc-800/60 transition-colors", children: [_jsx("span", { className: "w-1.5 h-1.5 rounded-full bg-zinc-600 shrink-0" }), _jsx("span", { className: "text-xs text-zinc-400 truncate flex-1", children: s.firstMessage }), _jsxs("span", { className: "text-[10px] text-zinc-700 font-mono shrink-0", children: [s.messageCount, "m"] }), _jsx("span", { className: "text-[10px] text-zinc-700 font-mono shrink-0", children: s.date.slice(5) })] }, s.id)))] })), filteredTasks.length === 0 && filteredSessions.length === 0 && searchResults.length === 0 && (_jsx("div", { className: "px-4 py-8 text-center text-xs text-zinc-600", children: isSearching ? 'No matches found' : 'No tasks or sessions available' }))] })] }) }));
75
+ }
76
+ // ── Session column viewer ──
77
+ function SessionColumn({ sessionId, configPath }) {
78
+ const [text, setText] = useState('');
79
+ const [loading, setLoading] = useState(true);
80
+ useEffect(() => {
81
+ execute(configPath, 'readSession', { sessionId, maxLength: 50000 }).then(r => {
82
+ setText(typeof r === 'string' ? r : JSON.stringify(r));
83
+ setLoading(false);
84
+ });
85
+ }, [sessionId, configPath]);
86
+ if (loading) {
87
+ return _jsxs("div", { className: "p-4 text-zinc-600 text-xs animate-pulse", children: ["Loading session ", sessionId, "..."] });
88
+ }
89
+ const blocks = text.split(/\n\n(?=\[(?:user|assistant)\])/).filter(Boolean);
90
+ return (_jsx("div", { className: "flex flex-col gap-2 p-3 overflow-y-auto h-full", children: blocks.map((block, i) => {
91
+ const match = block.match(/^\[(user|assistant)\]\s*/);
92
+ if (!match)
93
+ return _jsx("pre", { className: "text-[11px] text-zinc-500 whitespace-pre-wrap", children: block }, i);
94
+ const role = match[1];
95
+ const content = block.slice(match[0].length);
96
+ return (_jsxs("div", { className: cn('rounded-lg px-3 py-2', role === 'user'
97
+ ? 'bg-zinc-800/80 text-zinc-300 ml-6'
98
+ : 'bg-zinc-900/80 text-zinc-400 mr-4'), children: [_jsx("span", { className: cn('text-[9px] uppercase tracking-wider font-semibold mb-1 block', role === 'user' ? 'text-sky-500/70' : 'text-emerald-500/70'), children: role }), _jsx(LogRenderer, { text: content })] }, i));
99
+ }) }));
100
+ }
101
+ // ── Workspace Column ──
102
+ function WorkspaceColumn({ columnRef, configPath, onRemove }) {
103
+ const isSession = columnRef.startsWith('session:');
104
+ const sessionId = isSession ? columnRef.slice(8) : '';
105
+ const node = usePath(isSession ? '' : columnRef);
106
+ const label = isSession
107
+ ? `session ${sessionId}`
108
+ : (node ? String(node.prompt ?? '').slice(0, 40) || columnRef.split('/').at(-1) : columnRef.split('/').at(-1));
109
+ const status = !isSession && node ? node.status || 'pending' : '';
110
+ return (_jsxs("div", { className: "flex-1 min-w-[340px] max-w-[50vw] flex flex-col border-r border-zinc-800 last:border-r-0", children: [_jsxs("div", { className: "flex items-center gap-2 px-3 py-2 bg-zinc-950 border-b border-zinc-800 shrink-0", children: [isSession ? (_jsx("span", { className: "w-1.5 h-1.5 rounded-full bg-zinc-500 shrink-0" })) : (status && _jsx(StatusDot, { status: status })), _jsx("span", { className: "text-[11px] text-zinc-400 truncate flex-1 font-mono", children: label }), _jsx("button", { onClick: onRemove, className: "text-zinc-700 hover:text-red-400 transition-colors duration-200 p-0.5", title: "Remove column", children: _jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M18 6L6 18M6 6l12 12" }) }) })] }), _jsx("div", { className: "flex-1 overflow-y-auto min-h-0", children: isSession ? (_jsx(SessionColumn, { sessionId: sessionId, configPath: configPath })) : node ? (_jsx(Render, { value: node })) : (_jsx("div", { className: "p-3 text-[11px] text-zinc-700 animate-pulse", children: "Loading..." })) })] }));
111
+ }
112
+ // ── Workspace View ──
113
+ const WorkspaceView = ({ value, ctx }) => {
114
+ const [showPicker, setShowPicker] = useState(false);
115
+ const path = ctx.path;
116
+ const ws = usePath(path, MetatronWorkspace);
117
+ const configPath = useMemo(() => path.replace(/\/workspaces\/[^/]+$/, ''), [path]);
118
+ const columns = value.columns;
119
+ const handleRemoveColumn = useCallback(async (taskPath) => {
120
+ await ws.removeColumn({ taskPath });
121
+ }, [ws]);
122
+ const handleAddColumn = useCallback(async (ref) => {
123
+ await ws.addColumn({ taskPath: ref });
124
+ }, [ws]);
125
+ const handleNewTask = useCallback(async (prompt) => {
126
+ // task action is on config service, not a typed class method
127
+ const result = await execute(configPath, 'task', { prompt });
128
+ if (result && typeof result === 'object' && 'taskPath' in result) {
129
+ await ws.addColumn({ taskPath: result.taskPath });
130
+ }
131
+ }, [configPath, ws]);
132
+ if (columns.length === 0) {
133
+ return (_jsxs("div", { className: "flex flex-col items-center justify-center gap-4 h-64", children: [_jsx("div", { className: "w-10 h-10 rounded-xl bg-zinc-800 flex items-center justify-center", children: _jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", className: "text-zinc-600", children: [_jsx("rect", { x: "3", y: "3", width: "7", height: "18", rx: "1.5" }), _jsx("rect", { x: "14", y: "3", width: "7", height: "18", rx: "1.5" })] }) }), _jsxs("div", { className: "text-center", children: [_jsx("h2", { className: "text-sm font-medium text-zinc-300", children: String(value.name) || 'Workspace' }), _jsx("p", { className: "text-[11px] text-zinc-600 mt-0.5", children: "Add columns to compare tasks side by side" })] }), _jsx("button", { onClick: () => setShowPicker(true), className: "px-4 py-2 rounded-lg text-xs font-medium bg-violet-600 hover:bg-violet-500 text-white shadow-sm shadow-violet-600/20 transition-all duration-200", children: "Add column" }), showPicker && (_jsx(CommandPicker, { configPath: configPath, exclude: columns, onSelect: handleAddColumn, onNewTask: handleNewTask, onClose: () => setShowPicker(false) }))] }));
134
+ }
135
+ return (_jsxs("div", { className: "flex h-full w-full overflow-x-auto", children: [columns.map(ref => (_jsx(WorkspaceColumn, { columnRef: ref, configPath: configPath, onRemove: () => handleRemoveColumn(ref) }, ref))), _jsx("div", { className: "flex items-center justify-center w-12 shrink-0 border-l border-zinc-800/60", children: _jsx("button", { onClick: () => setShowPicker(true), className: "w-8 h-8 rounded-lg flex items-center justify-center text-zinc-700 hover:text-violet-400 hover:bg-violet-500/10 transition-all duration-200", title: "Add column", children: _jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M12 5v14M5 12h14" }) }) }) }), showPicker && (_jsx(CommandPicker, { configPath: configPath, exclude: columns, onSelect: handleAddColumn, onNewTask: handleNewTask, onClose: () => setShowPicker(false) }))] }));
136
+ };
137
+ register('metatron.workspace', 'react', WorkspaceView);
138
+ //# sourceMappingURL=workspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace.js","sourceRoot":"","sources":["../../../metatron/views/workspace.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ # metatron
2
+
3
+ AI-оркестратор. Хранит Claude-диалоги как `metatron.task` ноды со структурированным `LogBlock[]` логом. Сервис следит за `running` тасками, собирает промпт из skills/memory/history, гонит Claude-turns. Параллельная обработка через `active: Set<string>`.
4
+
5
+ ## Types
6
+ - `metatron.config` — model, systemPrompt, service
7
+ - `metatron.task` — prompt, status, log[], actions: task/reply/approve
8
+ - `metatron.skill` — named prompt fragment
9
+ - `metatron.memory` — persistent context
10
+
11
+ ## Smart Permissions
12
+ - `ALLOWED_TOOLS` — generous whitelist, SDK auto-approves (never calls canUseTool)
13
+ - `NEEDS_APPROVAL` — only `remove_node` needs interactive user approval
14
+ - `canUseTool` — auto-allows anything not in NEEDS_APPROVAL; session memory auto-approves after first allow
15
+ - `metatron.permission` LogBlock — id, tool, input, status (pending/approved/denied)
16
+ - `approve` action on task — sets block status + resolves waiting canUseTool Promise
17
+ - Permission blocks flush immediately (bypass 2s debounce) for instant UI visibility
18
+
19
+ ## Parallel Execution
20
+ - `active: Set<string>` tracks running task paths (replaces `processing` boolean)
21
+ - `processRunning()` finds ALL running tasks not in active set, fires each independently (no await)
22
+ - Each `processTask()` self-contained: add to active → run → delete from active → recheck
@@ -0,0 +1,258 @@
1
+ // Metatron — Claude Agent SDK wrapper
2
+ // Uses v1 query() API — simpler, more robust than unstable_v2 sessions
3
+ // Sessions persist via `resume` option. If resume fails, auto-retries fresh.
4
+ // Active query registry: keyed by configPath, enables abort from stop action.
5
+
6
+ import { query, type CanUseTool, type Query } from '@anthropic-ai/claude-agent-sdk';
7
+ import { evaluatePermission, type PermissionRule } from './permissions';
8
+
9
+ function ts(): string {
10
+ const d = new Date();
11
+ return `${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}:${String(d.getSeconds()).padStart(2, '0')}`;
12
+ }
13
+
14
+ export type ClaudeResult = {
15
+ output: string; // full log: text + tool calls + thinking + results
16
+ text: string; // clean text only (assistant text blocks)
17
+ sessionId?: string;
18
+ durationMs: number;
19
+ costUsd?: number;
20
+ error?: boolean;
21
+ aborted?: boolean;
22
+ };
23
+
24
+ export type ClaudeStreamCallback = (chunk: string) => void;
25
+
26
+ const log = (msg: string) => console.log(`[metatron:claude] ${msg}`);
27
+
28
+ // ── Active query registry ──
29
+
30
+ type ActiveEntry = { query: Query; ac: AbortController };
31
+ const activeQueries = new Map<string, ActiveEntry>();
32
+
33
+ /** Abort a running query by key (config path). Returns true if aborted. */
34
+ export function abortQuery(key: string): boolean {
35
+ const entry = activeQueries.get(key);
36
+ if (!entry) return false;
37
+ log(`aborting query: ${key}`);
38
+ entry.ac.abort();
39
+ entry.query.close();
40
+ return true;
41
+ }
42
+
43
+ /** Check if a query is currently running for the given key */
44
+ export function isQueryRunning(key: string): boolean {
45
+ return activeQueries.has(key);
46
+ }
47
+
48
+ // Extract readable text from tool_result content.
49
+ // MCP tools return {content: [{type:"text", text:"already formatted string"}]}.
50
+ // We extract .text from each block instead of JSON.stringify'ing the whole array.
51
+ function extractToolResultText(content: unknown): string {
52
+ if (typeof content === 'string') return content;
53
+ if (Array.isArray(content)) {
54
+ return content.map((b: any) => {
55
+ if (b.type === 'text' && typeof b.text === 'string') return b.text;
56
+ return JSON.stringify(b);
57
+ }).join('\n');
58
+ }
59
+ return String(content);
60
+ }
61
+
62
+ const DEFAULT_TOOLS = [
63
+ 'mcp__treenity__get_node',
64
+ 'mcp__treenity__list_children',
65
+ 'mcp__treenity__set_node',
66
+ 'mcp__treenity__remove_node',
67
+ 'mcp__treenity__execute',
68
+ 'mcp__treenity__deploy_prefab',
69
+ 'mcp__treenity__compile_view',
70
+ 'mcp__treenity__catalog',
71
+ 'mcp__treenity__describe_type',
72
+ 'mcp__treenity__search_types',
73
+ ];
74
+
75
+ function applyPermissionRules(rules: PermissionRule[]): { allowed: string[]; denied: string[] } {
76
+ if (!rules.length) return { allowed: DEFAULT_TOOLS, denied: [] };
77
+
78
+ const allowed: string[] = [];
79
+ const denied: string[] = [];
80
+
81
+ for (const tool of DEFAULT_TOOLS) {
82
+ const policy = evaluatePermission(rules, tool, {});
83
+ if (policy === 'deny') {
84
+ denied.push(tool);
85
+ log(` permission: DENY ${tool}`);
86
+ } else {
87
+ allowed.push(tool);
88
+ }
89
+ }
90
+
91
+ return { allowed, denied };
92
+ }
93
+
94
+ async function runQuery(
95
+ prompt: string,
96
+ opts: {
97
+ key?: string;
98
+ sessionId?: string;
99
+ forkSession?: boolean;
100
+ model?: string;
101
+ mcpUrl?: string;
102
+ abortController?: AbortController;
103
+ permissionRules?: PermissionRule[];
104
+ canUseTool?: CanUseTool;
105
+ onOutput?: ClaudeStreamCallback;
106
+ },
107
+ ): Promise<ClaudeResult> {
108
+ const mcpUrl = opts.mcpUrl || process.env.TREENITY_MCP_URL || 'http://localhost:3212/mcp';
109
+ const startTime = Date.now();
110
+
111
+ let sessionId: string | undefined;
112
+ let costUsd: number | undefined;
113
+ let isError = false;
114
+
115
+ const ac = opts.abortController ?? new AbortController();
116
+ const { allowed, denied } = applyPermissionRules(opts.permissionRules ?? []);
117
+
118
+ // Array accumulation avoids O(n^2) string concatenation
119
+ const outputChunks: string[] = [];
120
+ const textChunks: string[] = [];
121
+
122
+ const stream = query({
123
+ prompt,
124
+ options: {
125
+ ...(opts.sessionId ? { resume: opts.sessionId } : {}),
126
+ ...(opts.forkSession ? { forkSession: true } : {}),
127
+ ...(opts.model ? { model: opts.model } : {}),
128
+ abortController: ac,
129
+ permissionMode: opts.canUseTool ? 'bypassPermissions' : 'default',
130
+ ...(opts.canUseTool ? { allowDangerouslySkipPermissions: true } : {}),
131
+ allowedTools: allowed,
132
+ ...(denied.length ? { disallowedTools: denied } : {}),
133
+ ...(opts.canUseTool ? { canUseTool: opts.canUseTool } : {}),
134
+ mcpServers: {
135
+ treenity: { type: 'http', url: mcpUrl },
136
+ },
137
+ },
138
+ });
139
+
140
+ // Register in active queries map
141
+ if (opts.key) activeQueries.set(opts.key, { query: stream, ac });
142
+
143
+ const append = (text: string) => {
144
+ outputChunks.push(text);
145
+ opts.onOutput?.(text);
146
+ };
147
+
148
+ try {
149
+ for await (const message of stream) {
150
+ if (message.type === 'system' && message.subtype === 'init') {
151
+ sessionId = (message as any).session_id;
152
+ log(` session: ${sessionId}`);
153
+ }
154
+
155
+ const msg = message as any;
156
+
157
+ if (message.type === 'assistant' && msg.message?.content) {
158
+ for (const block of msg.message.content) {
159
+ if (block.type === 'text' && block.text) {
160
+ textChunks.push(block.text);
161
+ append(block.text);
162
+ } else if (block.type === 'tool_use') {
163
+ log(` tool: ${block.name} ${JSON.stringify(block.input)}`);
164
+ const input = JSON.stringify(block.input, null, 2);
165
+ append(`\n[tool ${ts()}] ${block.name}\n${input}\n`);
166
+ } else if (block.type === 'thinking' && block.thinking) {
167
+ append(`\n[thinking ${ts()}]\n${block.thinking}\n`);
168
+ }
169
+ }
170
+ }
171
+
172
+ // tool results come as user messages with tool_result blocks
173
+ if (message.type === 'user' && msg.message?.content) {
174
+ for (const block of msg.message.content) {
175
+ if (block.type === 'tool_result') {
176
+ const content = extractToolResultText(block.content);
177
+ append(`\n[result ${ts()}] ${content}\n`);
178
+ }
179
+ }
180
+ }
181
+
182
+ if (message.type === 'result') {
183
+ sessionId = msg.session_id ?? sessionId;
184
+ costUsd = msg.cost_usd;
185
+ isError = msg.is_error ?? false;
186
+ }
187
+ }
188
+ } catch (err) {
189
+ // AbortError = user-initiated stop, not a failure
190
+ if (ac.signal.aborted) {
191
+ append(`\n[interrupted ${ts()}]\n`);
192
+ return {
193
+ output: outputChunks.join(''),
194
+ text: textChunks.join(''),
195
+ sessionId,
196
+ durationMs: Date.now() - startTime,
197
+ costUsd,
198
+ aborted: true,
199
+ };
200
+ }
201
+ throw err;
202
+ } finally {
203
+ if (opts.key) activeQueries.delete(opts.key);
204
+ }
205
+
206
+ return {
207
+ output: outputChunks.join(''),
208
+ text: textChunks.join(''),
209
+ sessionId,
210
+ durationMs: Date.now() - startTime,
211
+ costUsd,
212
+ error: isError,
213
+ };
214
+ }
215
+
216
+ export async function invokeClaude(
217
+ prompt: string,
218
+ opts: {
219
+ key?: string;
220
+ sessionId?: string;
221
+ forkSession?: boolean;
222
+ model?: string;
223
+ mcpUrl?: string;
224
+ abortController?: AbortController;
225
+ permissionRules?: PermissionRule[];
226
+ canUseTool?: CanUseTool;
227
+ onOutput?: ClaudeStreamCallback;
228
+ } = {},
229
+ ): Promise<ClaudeResult> {
230
+ const promptPreview = prompt.length > 120 ? prompt.slice(0, 120) + '...' : prompt;
231
+ log(`query: "${promptPreview}" session=${opts.sessionId?.slice(0, 8) ?? 'new'}`);
232
+
233
+ try {
234
+ return await runQuery(prompt, opts);
235
+ } catch (err) {
236
+ const msg = err instanceof Error ? err.message : String(err);
237
+ log(` FAILED: ${msg}`);
238
+
239
+ // If resuming a session failed, retry without session (fresh start)
240
+ if (opts.sessionId) {
241
+ log(` retrying without session...`);
242
+ try {
243
+ return await runQuery(prompt, { ...opts, sessionId: undefined });
244
+ } catch (retryErr) {
245
+ const retryMsg = retryErr instanceof Error ? retryErr.message : String(retryErr);
246
+ log(` retry also FAILED: ${retryMsg}`);
247
+ throw retryErr;
248
+ }
249
+ }
250
+
251
+ throw err;
252
+ }
253
+ }
254
+
255
+ /** Close a running session — no-op since queries self-clean via AbortController */
256
+ export function closeSession(_key: string) {
257
+ abortQuery(_key);
258
+ }
@@ -0,0 +1,2 @@
1
+ import './types';
2
+ import './view';
@@ -0,0 +1,31 @@
1
+ // @/path mention parser for Metatron chat
2
+ // Detects @/path/to/node in text, returns positions for chip rendering and context resolution
3
+
4
+ export type Mention = {
5
+ path: string;
6
+ start: number;
7
+ end: number;
8
+ };
9
+
10
+ const MENTION_RE = /@(\/[\w\-./]+)/g;
11
+
12
+ export function parseMentions(text: string): Mention[] {
13
+ const mentions: Mention[] = [];
14
+ let m: RegExpExecArray | null;
15
+
16
+ while ((m = MENTION_RE.exec(text)) !== null) {
17
+ mentions.push({
18
+ path: m[1],
19
+ start: m.index,
20
+ end: m.index + m[0].length,
21
+ });
22
+ }
23
+
24
+ return mentions;
25
+ }
26
+
27
+ /** Extract unique paths from mentions */
28
+ export function uniqueMentionPaths(text: string): string[] {
29
+ const mentions = parseMentions(text);
30
+ return [...new Set(mentions.map(m => m.path))];
31
+ }