openbot 0.2.11 → 0.2.13

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 (141) hide show
  1. package/.prettierrc +8 -0
  2. package/AGENTS.md +68 -0
  3. package/CONTRIBUTING.md +74 -0
  4. package/LICENSE +21 -0
  5. package/README.md +117 -14
  6. package/dist/agents/system.js +106 -0
  7. package/dist/app/cli.js +27 -0
  8. package/dist/app/config.js +64 -0
  9. package/dist/app/server.js +237 -0
  10. package/dist/app/utils.js +35 -0
  11. package/dist/harness/agent-harness.js +45 -0
  12. package/dist/harness/mcp.js +61 -0
  13. package/dist/harness/orchestrator.js +273 -0
  14. package/dist/harness/process.js +7 -0
  15. package/dist/plugins/ai-sdk.js +141 -0
  16. package/dist/plugins/delegation.js +52 -0
  17. package/dist/plugins/mcp.js +140 -0
  18. package/dist/plugins/storage.js +502 -0
  19. package/dist/plugins/ui.js +47 -0
  20. package/dist/registry/plugins.js +73 -0
  21. package/dist/services/storage.js +724 -0
  22. package/docs/README.md +7 -0
  23. package/docs/agents.md +83 -0
  24. package/docs/architecture.md +34 -0
  25. package/docs/plugins.md +77 -0
  26. package/logo-black.png +0 -0
  27. package/{dist/assets/logo.js → logo-black.svg} +24 -24
  28. package/{dist/ui/sidebar.js → logo-white.svg} +23 -88
  29. package/package.json +10 -9
  30. package/src/agents/system.ts +112 -0
  31. package/src/app/cli.ts +38 -0
  32. package/src/app/config.ts +104 -0
  33. package/src/app/server.ts +284 -0
  34. package/src/app/types.ts +476 -0
  35. package/src/app/utils.ts +43 -0
  36. package/src/assets/icon.svg +1 -0
  37. package/src/harness/agent-harness.ts +58 -0
  38. package/src/harness/mcp.ts +78 -0
  39. package/src/harness/orchestrator.ts +342 -0
  40. package/src/harness/process.ts +9 -0
  41. package/src/harness/types.ts +34 -0
  42. package/src/plugins/ai-sdk.ts +197 -0
  43. package/src/plugins/delegation.ts +60 -0
  44. package/src/plugins/mcp.ts +154 -0
  45. package/src/plugins/storage.ts +725 -0
  46. package/src/plugins/ui.ts +57 -0
  47. package/src/registry/plugins.ts +85 -0
  48. package/src/services/storage.ts +957 -0
  49. package/tsconfig.json +18 -0
  50. package/dist/agents/agent-creator.js +0 -74
  51. package/dist/agents/browser-agent.js +0 -31
  52. package/dist/agents/os-agent.js +0 -32
  53. package/dist/agents/planner-agent.js +0 -32
  54. package/dist/agents/topic-agent.js +0 -46
  55. package/dist/architecture/execution-engine.js +0 -151
  56. package/dist/architecture/intent-classifier.js +0 -26
  57. package/dist/architecture/planner.js +0 -106
  58. package/dist/automation-worker.js +0 -121
  59. package/dist/automations.js +0 -52
  60. package/dist/cli.js +0 -275
  61. package/dist/config.js +0 -53
  62. package/dist/core/agents.js +0 -41
  63. package/dist/core/delegation.js +0 -230
  64. package/dist/core/manager.js +0 -96
  65. package/dist/core/plugins.js +0 -74
  66. package/dist/core/router.js +0 -191
  67. package/dist/handlers/init.js +0 -29
  68. package/dist/handlers/session-change.js +0 -21
  69. package/dist/handlers/settings.js +0 -47
  70. package/dist/handlers/tab-change.js +0 -14
  71. package/dist/installers.js +0 -156
  72. package/dist/marketplace.js +0 -80
  73. package/dist/model-catalog.js +0 -132
  74. package/dist/model-defaults.js +0 -25
  75. package/dist/models.js +0 -47
  76. package/dist/open-bot.js +0 -51
  77. package/dist/orchestrator/direct-invocation.js +0 -13
  78. package/dist/orchestrator/events.js +0 -36
  79. package/dist/orchestrator/state.js +0 -54
  80. package/dist/orchestrator.js +0 -422
  81. package/dist/plugins/agent/index.js +0 -81
  82. package/dist/plugins/approval/index.js +0 -100
  83. package/dist/plugins/brain/identity.js +0 -77
  84. package/dist/plugins/brain/index.js +0 -204
  85. package/dist/plugins/brain/memory.js +0 -120
  86. package/dist/plugins/brain/prompt.js +0 -46
  87. package/dist/plugins/brain/types.js +0 -45
  88. package/dist/plugins/brain/ui.js +0 -7
  89. package/dist/plugins/browser/index.js +0 -629
  90. package/dist/plugins/browser/ui.js +0 -13
  91. package/dist/plugins/file-system/index.js +0 -171
  92. package/dist/plugins/file-system/ui.js +0 -6
  93. package/dist/plugins/llm/context-budget.js +0 -139
  94. package/dist/plugins/llm/context-shaping.js +0 -177
  95. package/dist/plugins/llm/index.js +0 -380
  96. package/dist/plugins/memory/index.js +0 -220
  97. package/dist/plugins/memory/memory.js +0 -122
  98. package/dist/plugins/memory/prompt.js +0 -55
  99. package/dist/plugins/memory/types.js +0 -45
  100. package/dist/plugins/meta-agent/index.js +0 -570
  101. package/dist/plugins/meta-agent/ui.js +0 -11
  102. package/dist/plugins/shell/index.js +0 -100
  103. package/dist/plugins/shell/ui.js +0 -6
  104. package/dist/plugins/skills/index.js +0 -286
  105. package/dist/plugins/skills/types.js +0 -50
  106. package/dist/plugins/skills/ui.js +0 -12
  107. package/dist/registry/agent-registry.js +0 -35
  108. package/dist/registry/index.js +0 -2
  109. package/dist/registry/plugin-loader.js +0 -499
  110. package/dist/registry/plugin-registry.js +0 -44
  111. package/dist/registry/ts-agent-loader.js +0 -82
  112. package/dist/registry/yaml-agent-loader.js +0 -246
  113. package/dist/runtime/execution-trace.js +0 -41
  114. package/dist/runtime/intent-routing.js +0 -26
  115. package/dist/runtime/openbot-runtime.js +0 -354
  116. package/dist/server.js +0 -890
  117. package/dist/session.js +0 -179
  118. package/dist/ui/block.js +0 -12
  119. package/dist/ui/header.js +0 -52
  120. package/dist/ui/layout.js +0 -26
  121. package/dist/ui/navigation.js +0 -15
  122. package/dist/ui/settings.js +0 -106
  123. package/dist/ui/skills.js +0 -7
  124. package/dist/ui/thread.js +0 -16
  125. package/dist/ui/widgets/action-list.js +0 -2
  126. package/dist/ui/widgets/approval-card.js +0 -9
  127. package/dist/ui/widgets/code-snippet.js +0 -2
  128. package/dist/ui/widgets/data-block.js +0 -2
  129. package/dist/ui/widgets/data-table.js +0 -2
  130. package/dist/ui/widgets/delegation.js +0 -29
  131. package/dist/ui/widgets/empty-state.js +0 -2
  132. package/dist/ui/widgets/index.js +0 -23
  133. package/dist/ui/widgets/inquiry.js +0 -7
  134. package/dist/ui/widgets/key-value.js +0 -2
  135. package/dist/ui/widgets/progress-step.js +0 -2
  136. package/dist/ui/widgets/resource-card.js +0 -2
  137. package/dist/ui/widgets/status.js +0 -2
  138. package/dist/ui/widgets/todo-list.js +0 -2
  139. package/dist/version.js +0 -62
  140. /package/dist/{types.js → app/types.js} +0 -0
  141. /package/dist/{architecture/contracts.js → harness/types.js} +0 -0
package/dist/session.js DELETED
@@ -1,179 +0,0 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
3
- import os from "node:os";
4
- const SESSIONS_DIR = path.join(os.homedir(), ".openbot", "sessions");
5
- function getSessionDir(sessionId) {
6
- if (!fs.existsSync(SESSIONS_DIR)) {
7
- const today = new Date().toISOString().slice(0, 10);
8
- return path.join(SESSIONS_DIR, today, sessionId);
9
- }
10
- // 1. Check if it already exists in a date-based folder (YYYY-MM-DD or YYYY-MM)
11
- const dateFolders = fs.readdirSync(SESSIONS_DIR).filter(d => /^\d{4}-\d{2}(-\d{2})?$/.test(d));
12
- for (const folder of dateFolders) {
13
- const dir = path.join(SESSIONS_DIR, folder, sessionId);
14
- if (fs.existsSync(dir)) {
15
- return dir;
16
- }
17
- }
18
- // 2. Check if it exists in the root (legacy)
19
- const legacyDir = path.join(SESSIONS_DIR, sessionId);
20
- if (fs.existsSync(legacyDir) && fs.statSync(legacyDir).isDirectory()) {
21
- const stats = fs.statSync(legacyDir);
22
- const day = stats.mtime.toISOString().slice(0, 10);
23
- const newDir = path.join(SESSIONS_DIR, day, sessionId);
24
- fs.mkdirSync(path.dirname(newDir), { recursive: true });
25
- try {
26
- fs.renameSync(legacyDir, newDir);
27
- return newDir;
28
- }
29
- catch (error) {
30
- console.warn(`Failed to migrate session ${sessionId} to ${day}:`, error);
31
- return legacyDir;
32
- }
33
- }
34
- // 3. New session - use current day
35
- const today = new Date().toISOString().slice(0, 10);
36
- return path.join(SESSIONS_DIR, today, sessionId);
37
- }
38
- /**
39
- * Maximum number of messages to keep when loading a session.
40
- * Older messages are dropped to avoid bloated context windows.
41
- * System messages at the start are always preserved and don't count toward the limit.
42
- */
43
- const MAX_MESSAGES = 1000; // aiSdkPlugin defaults to latest 20 messages
44
- const MAX_LISTED_SESSIONS = 1000;
45
- function hasPersistedContent(state) {
46
- if (state.title)
47
- return true;
48
- if (state.messages && state.messages.length > 0)
49
- return true;
50
- // Direct sub-agent conversations are stored under agentStates.
51
- // Treat any non-empty agent state as a persisted session.
52
- if (state.agentStates && typeof state.agentStates === "object") {
53
- for (const agentState of Object.values(state.agentStates)) {
54
- if (!agentState || typeof agentState !== "object")
55
- continue;
56
- if (Object.keys(agentState).length > 0)
57
- return true;
58
- }
59
- }
60
- return false;
61
- }
62
- export async function loadSession(sessionId) {
63
- const sessionDir = getSessionDir(sessionId);
64
- const statePath = path.join(sessionDir, "state.json");
65
- if (!fs.existsSync(statePath)) {
66
- return null;
67
- }
68
- try {
69
- const data = fs.readFileSync(statePath, "utf-8");
70
- const state = JSON.parse(data);
71
- if (state.messages && state.messages.length > MAX_MESSAGES) {
72
- // Preserve system messages at the beginning, then keep the tail
73
- const systemMessages = [];
74
- let rest = state.messages;
75
- while (rest.length > 0 && rest[0].role === "system") {
76
- systemMessages.push(rest[0]);
77
- rest = rest.slice(1);
78
- }
79
- const kept = rest.slice(-MAX_MESSAGES);
80
- state.messages = [...systemMessages, ...kept];
81
- }
82
- return state;
83
- }
84
- catch (error) {
85
- console.error(`Failed to load session ${sessionId}:`, error);
86
- return null;
87
- }
88
- }
89
- export async function saveSession(sessionId, state) {
90
- const sessionDir = getSessionDir(sessionId);
91
- if (!fs.existsSync(sessionDir)) {
92
- fs.mkdirSync(sessionDir, { recursive: true });
93
- }
94
- const statePath = path.join(sessionDir, "state.json");
95
- fs.writeFileSync(statePath, JSON.stringify(state, null, 2), "utf-8");
96
- }
97
- export async function logEvent(sessionId, runId, event) {
98
- const sessionDir = getSessionDir(sessionId);
99
- if (!fs.existsSync(sessionDir)) {
100
- fs.mkdirSync(sessionDir, { recursive: true });
101
- }
102
- const logPath = path.join(sessionDir, `events.jsonl`);
103
- const entry = JSON.stringify({
104
- timestamp: new Date().toISOString(),
105
- runId,
106
- ...event,
107
- });
108
- fs.appendFileSync(logPath, entry + "\n", "utf-8");
109
- }
110
- export async function loadEvents(sessionId) {
111
- const sessionDir = getSessionDir(sessionId);
112
- const logPath = path.join(sessionDir, `events.jsonl`);
113
- if (!fs.existsSync(logPath)) {
114
- return [];
115
- }
116
- try {
117
- const data = fs.readFileSync(logPath, "utf-8");
118
- return data
119
- .split("\n")
120
- .filter((line) => line.trim() !== "")
121
- .map((line) => JSON.parse(line));
122
- }
123
- catch (error) {
124
- console.error(`Failed to load events for session ${sessionId}:`, error);
125
- return [];
126
- }
127
- }
128
- export async function listSessions() {
129
- if (!fs.existsSync(SESSIONS_DIR))
130
- return [];
131
- const sessions = [];
132
- try {
133
- const items = fs.readdirSync(SESSIONS_DIR);
134
- for (const item of items) {
135
- const itemPath = path.join(SESSIONS_DIR, item);
136
- const stat = fs.statSync(itemPath);
137
- if (stat.isDirectory()) {
138
- // If it's a date folder (YYYY-MM-DD), look inside
139
- if (/^\d{4}-\d{2}-\d{2}$/.test(item)) {
140
- const subItems = fs.readdirSync(itemPath);
141
- for (const subItem of subItems) {
142
- const sessionPath = path.join(itemPath, subItem);
143
- const statePath = path.join(sessionPath, "state.json");
144
- if (fs.existsSync(statePath)) {
145
- const state = JSON.parse(fs.readFileSync(statePath, "utf-8"));
146
- if (hasPersistedContent(state)) {
147
- sessions.push({
148
- id: subItem,
149
- mtime: fs.statSync(statePath).birthtime, // sort by creation time
150
- title: state.title ?? undefined,
151
- });
152
- }
153
- }
154
- }
155
- }
156
- else {
157
- // It's a legacy session folder in root
158
- const statePath = path.join(itemPath, "state.json");
159
- if (fs.existsSync(statePath)) {
160
- const state = JSON.parse(fs.readFileSync(statePath, "utf-8"));
161
- if (hasPersistedContent(state)) {
162
- sessions.push({
163
- id: item,
164
- title: state.title ?? undefined,
165
- mtime: fs.statSync(statePath).birthtime, // sort by creation time
166
- });
167
- }
168
- }
169
- }
170
- }
171
- }
172
- }
173
- catch (error) {
174
- console.error("Failed to list sessions:", error);
175
- }
176
- return sessions
177
- .sort((a, b) => b.mtime.getTime() - a.mtime.getTime())
178
- .slice(0, MAX_LISTED_SESSIONS);
179
- }
package/dist/ui/block.js DELETED
@@ -1,12 +0,0 @@
1
- export const block = (widget, props, options = {}) => ({
2
- type: "ui-block",
3
- widget,
4
- props,
5
- placement: options.placement ?? "thread",
6
- id: options.id,
7
- meta: options.meta,
8
- });
9
- export const uiEvent = (block) => ({
10
- type: "ui",
11
- data: block,
12
- });
package/dist/ui/header.js DELETED
@@ -1,52 +0,0 @@
1
- import { ui } from "@melony/ui-kit";
2
- export const headerUI = (tab) => ui.box({
3
- padding: "sm",
4
- background: "background",
5
- width: "full",
6
- }, [
7
- ui.row({ justify: "between", align: "center", width: "full" }, [
8
- ui.row({ gap: "xs", align: "center" }, [
9
- ui.listItem({
10
- onClickAction: {
11
- type: "client:navigate",
12
- data: { path: "/" }
13
- }
14
- }, [ui.text("OpenBot")]),
15
- ui.divider({ orientation: "vertical", margin: "xs" }),
16
- ui.button({
17
- label: "Chat",
18
- variant: (tab === "chat" || !tab) ? "secondary" : "ghost",
19
- size: "sm",
20
- onClickAction: {
21
- type: "client:navigate",
22
- data: { path: "/" },
23
- },
24
- }),
25
- ui.button({
26
- label: "Skills",
27
- variant: tab === "skills" ? "secondary" : "ghost",
28
- size: "sm",
29
- onClickAction: {
30
- type: "client:navigate",
31
- data: { path: "/?tab=skills" },
32
- },
33
- }),
34
- ui.button({
35
- label: "Settings",
36
- variant: tab === "settings" ? "secondary" : "ghost",
37
- size: "sm",
38
- onClickAction: {
39
- type: "client:navigate",
40
- data: { path: "/?tab=settings" },
41
- },
42
- }),
43
- ]),
44
- ui.row({ gap: "sm", align: "center", width: "auto" }, [
45
- ui.button({
46
- label: "JD",
47
- variant: "outline",
48
- size: "sm",
49
- }),
50
- ]),
51
- ]),
52
- ]);
package/dist/ui/layout.js DELETED
@@ -1,26 +0,0 @@
1
- import { ui } from "@melony/ui-kit";
2
- import { threadUI } from "./thread.js";
3
- import { sidebarUI } from "./sidebar.js";
4
- import { settingsUI } from "./settings.js";
5
- import { skillsUI } from "./skills.js";
6
- import { listSessions } from "../session.js";
7
- const tabs = {
8
- chat: threadUI,
9
- settings: settingsUI,
10
- skills: skillsUI,
11
- };
12
- export const layoutUI = async ({ tab, sessionId }) => {
13
- const sessions = await listSessions();
14
- const content = typeof tabs[tab] === "function" ? await tabs[tab]() : tabs[tab];
15
- return ui.row({ height: "full" }, [
16
- sidebarUI({ sessions, sessionId }),
17
- content
18
- ]);
19
- };
20
- export const sidebarOnlyUI = async ({ sessionId }) => {
21
- const sessions = await listSessions();
22
- return sidebarUI({ sessions, sessionId });
23
- };
24
- export const tabOnlyUI = async ({ tab }) => {
25
- return typeof tabs[tab] === "function" ? await tabs[tab]() : tabs[tab];
26
- };
@@ -1,15 +0,0 @@
1
- import { ui } from "@melony/ui-kit";
2
- const listItemProps = (path) => ({
3
- onClickAction: {
4
- type: "client:navigate",
5
- data: { path },
6
- },
7
- });
8
- export const navigationUI = ui.box({ width: "full" }, [ui.list({
9
- gap: "none",
10
- }, [
11
- ui.listItem(listItemProps("/"), [
12
- ui.icon("PlusIcon", { size: "sm" }),
13
- ui.text("New chat", { size: "sm" })
14
- ])
15
- ])]);
@@ -1,106 +0,0 @@
1
- import { ui } from "@melony/ui-kit";
2
- import { loadConfig, resolvePath, DEFAULT_BASE_DIR } from "../config.js";
3
- import { listYamlAgents } from "../registry/index.js";
4
- import path from "node:path";
5
- export const settingsUI = async () => {
6
- const config = loadConfig();
7
- const baseDir = config.baseDir || DEFAULT_BASE_DIR;
8
- const resolvedBaseDir = resolvePath(baseDir);
9
- const agentsDir = path.join(resolvedBaseDir, "agents");
10
- const hasOpenAIKey = !!config.openaiApiKey;
11
- const hasAnthropicKey = !!config.anthropicApiKey;
12
- const agents = await listYamlAgents(agentsDir);
13
- return ui.box({
14
- width: "full",
15
- height: "full",
16
- overflow: "auto",
17
- }, [
18
- ui.col({ padding: "xl", gap: "xl", width: "full", flex: 1 }, [
19
- ui.col({ gap: "xs" }, [
20
- ui.heading("Settings", 2),
21
- ui.text("Manage your OpenBot configuration", { color: "mutedForeground" }),
22
- ]),
23
- ui.divider(),
24
- ui.form({
25
- onSubmitAction: {
26
- type: "action:updateSettings",
27
- data: {}
28
- }
29
- }, [
30
- ui.col({ gap: "xl" }, [
31
- ui.col({ gap: "md" }, [
32
- ui.heading("Model Configuration", 4),
33
- ui.col({ gap: "sm" }, [
34
- ui.input("model", undefined, {
35
- placeholder: "provider/model (e.g. openai/gpt-4o)",
36
- width: "full",
37
- defaultValue: config.model || "openai/gpt-4o-mini"
38
- }),
39
- ]),
40
- ]),
41
- ui.col({ gap: "md" }, [
42
- ui.heading("API Keys", 4),
43
- ui.col({ gap: "lg" }, [
44
- // OpenAI Key
45
- ui.col({ gap: "sm" }, [
46
- ui.node("label", { value: "OpenAI API Key" }),
47
- ui.input("openai_api_key", undefined, {
48
- placeholder: "sk-...",
49
- inputType: "password",
50
- defaultValue: hasOpenAIKey ? "••••••••••••••••" : "",
51
- width: "full"
52
- }),
53
- ]),
54
- // Anthropic Key
55
- ui.col({ gap: "sm" }, [
56
- ui.node("label", { value: "Anthropic API Key" }),
57
- ui.input("anthropic_api_key", undefined, {
58
- placeholder: "sk-ant-...",
59
- inputType: "password",
60
- defaultValue: hasAnthropicKey ? "••••••••••••••••" : "",
61
- width: "full"
62
- }),
63
- ])
64
- ])
65
- ]),
66
- ui.col({ gap: "md" }, [
67
- ui.heading("Theme", 4),
68
- ui.themeToggle(),
69
- ]),
70
- ui.row({ justify: "end" }, [
71
- ui.button({
72
- label: "Save Settings",
73
- type: "submit",
74
- variant: "primary"
75
- })
76
- ])
77
- ])
78
- ]),
79
- ui.divider(),
80
- ui.col({ gap: "md" }, [
81
- ui.heading("Installed Agents", 4),
82
- ui.text("Agents installed in ~/.openbot/agents", { color: "mutedForeground", size: "sm" }),
83
- ui.col({ gap: "sm" }, agents.map(agent => (ui.box({
84
- padding: "md",
85
- background: "muted",
86
- }, [
87
- ui.row({ justify: "between", align: "center" }, [
88
- ui.col({ gap: "xs" }, [
89
- ui.text(agent.name, { weight: "bold" }),
90
- ui.text(agent.description, { size: "sm", color: "mutedForeground" }),
91
- ]),
92
- ui.button({
93
- label: "Open Folder",
94
- variant: "secondary",
95
- size: "sm",
96
- onClickAction: {
97
- type: "action:openAgentFolder",
98
- data: { folder: agent.folder }
99
- }
100
- })
101
- ])
102
- ]))))
103
- ])
104
- ]),
105
- ]);
106
- };
package/dist/ui/skills.js DELETED
@@ -1,7 +0,0 @@
1
- import { ui } from "@melony/ui-kit";
2
- export const skillsUI = ui.box({
3
- padding: "md",
4
- }, [
5
- ui.heading("Skills", 2),
6
- ui.text("The skills for the OpenBot", { size: "sm", color: "mutedForeground" }),
7
- ]);
package/dist/ui/thread.js DELETED
@@ -1,16 +0,0 @@
1
- import { ui } from "@melony/ui-kit";
2
- export const threadUI = ui.box({
3
- width: "full",
4
- height: "full",
5
- }, [ui.thread({
6
- placeholder: "Ask me anything about your system or projects...",
7
- }, [
8
- ui.heading("Hey there!"),
9
- ui.text("I'm your trusty system sidekick with superpowers over your files and terminal. Let's make some magic happen!", { size: "sm", color: "mutedForeground" }),
10
- ui.col({ gap: "sm" }, [
11
- ui.button({ onClickAction: { type: "user:text", data: { content: "What is in my current directory?" } }, label: "What is in my current directory?", size: "sm", variant: "outline" }),
12
- ui.button({ onClickAction: { type: "user:text", data: { content: "Check system status" } }, label: "Check system status", size: "sm", variant: "outline" }),
13
- ui.button({ onClickAction: { type: "user:text", data: { content: "Who am I?" } }, label: "Who am I?", size: "sm", variant: "outline" }),
14
- ui.button({ onClickAction: { type: "user:text", data: { content: "Who are you?" } }, label: "Who are you?", size: "sm", variant: "outline" }),
15
- ]),
16
- ])]);
@@ -1,2 +0,0 @@
1
- import { block } from '../block.js';
2
- export const actionList = (title, actions) => block('action-list', { title, actions });
@@ -1,9 +0,0 @@
1
- import { block } from '../block.js';
2
- export const approvalCard = (title, data, approveAction, denyAction, options = {}) => block('approval-card', {
3
- title,
4
- summary: data.summary,
5
- details: data.details,
6
- rawPayload: data.rawPayload,
7
- approveAction,
8
- denyAction
9
- }, options);
@@ -1,2 +0,0 @@
1
- import { block } from '../block.js';
2
- export const codeSnippet = (code, language = 'text') => block('code-snippet', { code, language });
@@ -1,2 +0,0 @@
1
- import { block } from '../block.js';
2
- export const dataBlockWidget = (data) => block('data-block', { data });
@@ -1,2 +0,0 @@
1
- import { block } from '../block.js';
2
- export const dataTable = (headers, rows) => block('data-table', { headers, rows });
@@ -1,29 +0,0 @@
1
- import { ui } from "@melony/ui-kit/server";
2
- function stateLabel(state) {
3
- if (state === "running")
4
- return "Running";
5
- if (state === "completed")
6
- return "Completed";
7
- return "Failed";
8
- }
9
- export const delegationWidget = (agentName, state, task, details) => {
10
- const taskPreview = (task || "").trim();
11
- const clippedTask = taskPreview.length > 240
12
- ? `${taskPreview.slice(0, 237)}...`
13
- : taskPreview;
14
- const detailsPreview = (details || "").trim();
15
- const clippedDetails = detailsPreview.length > 400
16
- ? `${detailsPreview.slice(0, 397)}...`
17
- : detailsPreview;
18
- return ui.box({ border: true, radius: "md", padding: "md" }, [
19
- ui.col({ gap: "sm" }, [
20
- ui.heading(`Sub-agent: ${agentName}`, { level: 4 }),
21
- ui.text(`State: ${stateLabel(state)}`, {
22
- size: "xs",
23
- color: state === "failed" ? "danger" : state === "completed" ? "success" : "muted",
24
- }),
25
- ...(clippedTask ? [ui.text(`Task: ${clippedTask}`, { size: "sm", color: "muted" })] : []),
26
- ...(clippedDetails ? [ui.text(clippedDetails, { size: "sm" })] : []),
27
- ]),
28
- ]);
29
- };
@@ -1,2 +0,0 @@
1
- import { block } from '../block.js';
2
- export const emptyState = (message, iconName) => block('empty-state', { message, iconName });
@@ -1,23 +0,0 @@
1
- import { keyValue } from './key-value.js';
2
- import { dataTable } from './data-table.js';
3
- import { codeSnippet } from './code-snippet.js';
4
- import { statusWidget as status } from './status.js';
5
- import { progressStep } from './progress-step.js';
6
- import { approvalCard } from './approval-card.js';
7
- import { actionList } from './action-list.js';
8
- import { emptyState } from './empty-state.js';
9
- import { todoList } from './todo-list.js';
10
- import { inquiryCard } from './inquiry.js';
11
- export const widgets = {
12
- keyValue,
13
- dataTable,
14
- codeSnippet,
15
- status,
16
- progressStep,
17
- approvalCard,
18
- actionList,
19
- emptyState,
20
- todoList,
21
- inquiryCard,
22
- };
23
- export default widgets;
@@ -1,7 +0,0 @@
1
- import { block } from '../block.js';
2
- export const inquiryCard = (title, data, options = {}) => block('inquiry-card', {
3
- title,
4
- question: data.question,
5
- description: data.description,
6
- options: data.options || [],
7
- }, options);
@@ -1,2 +0,0 @@
1
- import { block } from '../block.js';
2
- export const keyValue = (title, data) => block('key-value', { title, data });
@@ -1,2 +0,0 @@
1
- import { block } from '../block.js';
2
- export const progressStep = (currentStep, totalSteps, label) => block('progress-step', { currentStep, totalSteps, label });
@@ -1,2 +0,0 @@
1
- import { block } from '../block.js';
2
- export const resourceCardWidget = (title, subtitle, children = []) => block('resource-card', { title, subtitle, children });
@@ -1,2 +0,0 @@
1
- import { block } from '../block.js';
2
- export const statusWidget = (message, severity = 'info', options = {}) => block('status', { message, severity }, options);
@@ -1,2 +0,0 @@
1
- import { block } from '../block.js';
2
- export const todoList = (todos, options = {}) => block('todo-list', { todos }, options);
package/dist/version.js DELETED
@@ -1,62 +0,0 @@
1
- import { fileURLToPath } from "node:url";
2
- import { dirname, join } from "node:path";
3
- import { readFileSync } from "node:fs";
4
- /**
5
- * Gets the version of the currently running OpenBot instance.
6
- * Works regardless of where the command is executed from.
7
- */
8
- export function getCurrentVersion() {
9
- try {
10
- const __filename = fileURLToPath(import.meta.url);
11
- const __dirname = dirname(__filename);
12
- // Look for package.json by walking up from the current directory
13
- let currentDir = __dirname;
14
- for (let i = 0; i < 4; i++) {
15
- const pkgPath = join(currentDir, "package.json");
16
- try {
17
- const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
18
- if (pkg.name === "openbot") {
19
- return pkg.version;
20
- }
21
- }
22
- catch {
23
- // Continue walking up
24
- }
25
- currentDir = dirname(currentDir);
26
- }
27
- }
28
- catch (err) {
29
- console.warn("Could not determine OpenBot version:", err);
30
- }
31
- // Fallback to a hardcoded version if detection fails
32
- return "0.2.3";
33
- }
34
- /**
35
- * Fetches the latest version from NPM registry and checks for updates.
36
- */
37
- export async function getVersionStatus() {
38
- const current = getCurrentVersion();
39
- try {
40
- const response = await fetch("https://registry.npmjs.org/openbot/latest", {
41
- signal: AbortSignal.timeout(5000), // 5s timeout
42
- });
43
- if (!response.ok) {
44
- throw new Error(`NPM registry returned ${response.status}`);
45
- }
46
- const data = await response.json();
47
- const latest = data.version;
48
- return {
49
- current,
50
- latest,
51
- updateAvailable: current !== latest,
52
- };
53
- }
54
- catch (error) {
55
- console.error("Failed to check for updates:", error);
56
- return {
57
- current,
58
- latest: current,
59
- updateAvailable: false,
60
- };
61
- }
62
- }
File without changes