@next-open-ai/openbot 0.1.1

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 (139) hide show
  1. package/README.md +212 -0
  2. package/dist/agent/agent-dir.d.ts +14 -0
  3. package/dist/agent/agent-dir.js +75 -0
  4. package/dist/agent/agent-manager.d.ts +61 -0
  5. package/dist/agent/agent-manager.js +257 -0
  6. package/dist/agent/config-manager.d.ts +25 -0
  7. package/dist/agent/config-manager.js +84 -0
  8. package/dist/agent/desktop-config.d.ts +15 -0
  9. package/dist/agent/desktop-config.js +91 -0
  10. package/dist/agent/run.d.ts +26 -0
  11. package/dist/agent/run.js +65 -0
  12. package/dist/agent/skills.d.ts +20 -0
  13. package/dist/agent/skills.js +86 -0
  14. package/dist/cli.d.ts +2 -0
  15. package/dist/cli.js +168 -0
  16. package/dist/gateway/backend-url.d.ts +2 -0
  17. package/dist/gateway/backend-url.js +11 -0
  18. package/dist/gateway/clients.d.ts +5 -0
  19. package/dist/gateway/clients.js +4 -0
  20. package/dist/gateway/connection-handler.d.ts +6 -0
  21. package/dist/gateway/connection-handler.js +48 -0
  22. package/dist/gateway/desktop-config.d.ts +7 -0
  23. package/dist/gateway/desktop-config.js +25 -0
  24. package/dist/gateway/index.d.ts +3 -0
  25. package/dist/gateway/index.js +2 -0
  26. package/dist/gateway/message-handler.d.ts +5 -0
  27. package/dist/gateway/message-handler.js +65 -0
  28. package/dist/gateway/methods/agent-cancel.d.ts +10 -0
  29. package/dist/gateway/methods/agent-cancel.js +17 -0
  30. package/dist/gateway/methods/agent-chat.d.ts +8 -0
  31. package/dist/gateway/methods/agent-chat.js +194 -0
  32. package/dist/gateway/methods/connect.d.ts +8 -0
  33. package/dist/gateway/methods/connect.js +15 -0
  34. package/dist/gateway/methods/install-skill-from-path.d.ts +13 -0
  35. package/dist/gateway/methods/install-skill-from-path.js +48 -0
  36. package/dist/gateway/methods/run-scheduled-task.d.ts +13 -0
  37. package/dist/gateway/methods/run-scheduled-task.js +164 -0
  38. package/dist/gateway/server.d.ts +10 -0
  39. package/dist/gateway/server.js +268 -0
  40. package/dist/gateway/types.d.ts +76 -0
  41. package/dist/gateway/types.js +1 -0
  42. package/dist/gateway/utils.d.ts +22 -0
  43. package/dist/gateway/utils.js +67 -0
  44. package/dist/index.d.ts +3 -0
  45. package/dist/index.js +3 -0
  46. package/dist/memory/build-summary.d.ts +6 -0
  47. package/dist/memory/build-summary.js +27 -0
  48. package/dist/memory/compaction-extension.d.ts +6 -0
  49. package/dist/memory/compaction-extension.js +23 -0
  50. package/dist/memory/embedding.d.ts +10 -0
  51. package/dist/memory/embedding.js +22 -0
  52. package/dist/memory/index.d.ts +29 -0
  53. package/dist/memory/index.js +66 -0
  54. package/dist/memory/types.d.ts +16 -0
  55. package/dist/memory/types.js +1 -0
  56. package/dist/memory/vector-store.d.ts +15 -0
  57. package/dist/memory/vector-store.js +65 -0
  58. package/dist/server/agent-config/agent-config.controller.d.ts +30 -0
  59. package/dist/server/agent-config/agent-config.controller.js +83 -0
  60. package/dist/server/agent-config/agent-config.module.d.ts +2 -0
  61. package/dist/server/agent-config/agent-config.module.js +19 -0
  62. package/dist/server/agent-config/agent-config.service.d.ts +34 -0
  63. package/dist/server/agent-config/agent-config.service.js +171 -0
  64. package/dist/server/agents/agents.controller.d.ts +41 -0
  65. package/dist/server/agents/agents.controller.js +120 -0
  66. package/dist/server/agents/agents.gateway.d.ts +21 -0
  67. package/dist/server/agents/agents.gateway.js +103 -0
  68. package/dist/server/agents/agents.module.d.ts +2 -0
  69. package/dist/server/agents/agents.module.js +20 -0
  70. package/dist/server/agents/agents.service.d.ts +63 -0
  71. package/dist/server/agents/agents.service.js +167 -0
  72. package/dist/server/app.module.d.ts +2 -0
  73. package/dist/server/app.module.js +36 -0
  74. package/dist/server/auth/auth.controller.d.ts +20 -0
  75. package/dist/server/auth/auth.controller.js +64 -0
  76. package/dist/server/auth/auth.module.d.ts +2 -0
  77. package/dist/server/auth/auth.module.js +19 -0
  78. package/dist/server/config/config.controller.d.ts +51 -0
  79. package/dist/server/config/config.controller.js +81 -0
  80. package/dist/server/config/config.module.d.ts +2 -0
  81. package/dist/server/config/config.module.js +19 -0
  82. package/dist/server/config/config.service.d.ts +34 -0
  83. package/dist/server/config/config.service.js +91 -0
  84. package/dist/server/database/database.module.d.ts +2 -0
  85. package/dist/server/database/database.module.js +18 -0
  86. package/dist/server/database/database.service.d.ts +11 -0
  87. package/dist/server/database/database.service.js +137 -0
  88. package/dist/server/main.d.ts +1 -0
  89. package/dist/server/main.js +18 -0
  90. package/dist/server/skills/skills.controller.d.ts +63 -0
  91. package/dist/server/skills/skills.controller.js +194 -0
  92. package/dist/server/skills/skills.module.d.ts +2 -0
  93. package/dist/server/skills/skills.module.js +22 -0
  94. package/dist/server/skills/skills.service.d.ts +63 -0
  95. package/dist/server/skills/skills.service.js +324 -0
  96. package/dist/server/tasks/tasks.controller.d.ts +52 -0
  97. package/dist/server/tasks/tasks.controller.js +163 -0
  98. package/dist/server/tasks/tasks.module.d.ts +2 -0
  99. package/dist/server/tasks/tasks.module.js +22 -0
  100. package/dist/server/tasks/tasks.service.d.ts +84 -0
  101. package/dist/server/tasks/tasks.service.js +313 -0
  102. package/dist/server/usage/usage.controller.d.ts +12 -0
  103. package/dist/server/usage/usage.controller.js +46 -0
  104. package/dist/server/usage/usage.module.d.ts +2 -0
  105. package/dist/server/usage/usage.module.js +19 -0
  106. package/dist/server/usage/usage.service.d.ts +21 -0
  107. package/dist/server/usage/usage.service.js +55 -0
  108. package/dist/server/users/users.controller.d.ts +35 -0
  109. package/dist/server/users/users.controller.js +69 -0
  110. package/dist/server/users/users.module.d.ts +2 -0
  111. package/dist/server/users/users.module.js +19 -0
  112. package/dist/server/users/users.service.d.ts +39 -0
  113. package/dist/server/users/users.service.js +140 -0
  114. package/dist/server/workspace/workspace.controller.d.ts +24 -0
  115. package/dist/server/workspace/workspace.controller.js +132 -0
  116. package/dist/server/workspace/workspace.module.d.ts +2 -0
  117. package/dist/server/workspace/workspace.module.js +21 -0
  118. package/dist/server/workspace/workspace.service.d.ts +25 -0
  119. package/dist/server/workspace/workspace.service.js +103 -0
  120. package/dist/tools/browser-tool.d.ts +10 -0
  121. package/dist/tools/browser-tool.js +362 -0
  122. package/dist/tools/index.d.ts +3 -0
  123. package/dist/tools/index.js +3 -0
  124. package/dist/tools/install-skill-tool.d.ts +9 -0
  125. package/dist/tools/install-skill-tool.js +77 -0
  126. package/dist/tools/save-experience-tool.d.ts +5 -0
  127. package/dist/tools/save-experience-tool.js +54 -0
  128. package/package.json +80 -0
  129. package/skills/agent-browser/SKILL.md +207 -0
  130. package/skills/agent-browser/references/authentication.md +202 -0
  131. package/skills/agent-browser/references/commands.md +259 -0
  132. package/skills/agent-browser/references/proxy-support.md +188 -0
  133. package/skills/agent-browser/references/session-management.md +193 -0
  134. package/skills/agent-browser/references/snapshot-refs.md +194 -0
  135. package/skills/agent-browser/references/video-recording.md +173 -0
  136. package/skills/agent-browser/templates/authenticated-session.sh +97 -0
  137. package/skills/agent-browser/templates/capture-workflow.sh +69 -0
  138. package/skills/agent-browser/templates/form-automation.sh +62 -0
  139. package/skills/find-skills/SKILL.md +140 -0
@@ -0,0 +1,34 @@
1
+ export interface AppConfig {
2
+ gatewayUrl: string;
3
+ defaultProvider: string;
4
+ defaultModel: string;
5
+ /** 缺省智能体 id */
6
+ defaultAgentId?: string;
7
+ theme: 'light' | 'dark';
8
+ /** 同时存在的聊天 AgentSession 上限,超过时淘汰最久未用的 */
9
+ maxAgentSessions?: number;
10
+ /** 登录用户名,未配置时使用缺省(与缺省密码 123456 搭配) */
11
+ loginUsername?: string;
12
+ /** 登录密码,未配置时使用缺省 123456 */
13
+ loginPassword?: string;
14
+ providers: {
15
+ [key: string]: {
16
+ apiKey?: string;
17
+ baseUrl?: string;
18
+ };
19
+ };
20
+ }
21
+ export declare class ConfigService {
22
+ private configPath;
23
+ private config;
24
+ constructor();
25
+ private getDefaultConfig;
26
+ /** 当前缺省智能体 id */
27
+ getDefaultAgentId(config?: AppConfig): string;
28
+ private loadConfig;
29
+ getConfig(): Promise<AppConfig>;
30
+ updateConfig(updates: Partial<AppConfig>): Promise<AppConfig>;
31
+ private saveConfig;
32
+ getProviders(): Promise<string[]>;
33
+ getModels(provider: string): Promise<string[]>;
34
+ }
@@ -0,0 +1,91 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import { Injectable } from '@nestjs/common';
11
+ import { readFile, writeFile, mkdir } from 'fs/promises';
12
+ import { join } from 'path';
13
+ import { existsSync } from 'fs';
14
+ let ConfigService = class ConfigService {
15
+ configPath;
16
+ config;
17
+ constructor() {
18
+ const homeDir = process.env.HOME || process.env.USERPROFILE || '';
19
+ const configDir = join(homeDir, '.openbot', 'desktop');
20
+ this.configPath = join(configDir, 'config.json');
21
+ // Ensure config directory exists
22
+ if (!existsSync(configDir)) {
23
+ mkdir(configDir, { recursive: true });
24
+ }
25
+ this.config = this.getDefaultConfig();
26
+ this.loadConfig();
27
+ }
28
+ getDefaultConfig() {
29
+ return {
30
+ gatewayUrl: 'ws://localhost:3000',
31
+ defaultProvider: 'deepseek',
32
+ defaultModel: 'deepseek-chat',
33
+ defaultAgentId: 'default',
34
+ theme: 'dark',
35
+ maxAgentSessions: 5,
36
+ providers: {},
37
+ };
38
+ }
39
+ /** 当前缺省智能体 id */
40
+ getDefaultAgentId(config) {
41
+ const c = config ?? this.config;
42
+ return (c.defaultAgentId ?? 'default').trim() || 'default';
43
+ }
44
+ async loadConfig() {
45
+ try {
46
+ if (existsSync(this.configPath)) {
47
+ const content = await readFile(this.configPath, 'utf-8');
48
+ this.config = { ...this.getDefaultConfig(), ...JSON.parse(content) };
49
+ this.config.defaultAgentId = this.getDefaultAgentId(this.config);
50
+ }
51
+ }
52
+ catch (error) {
53
+ console.error('Error loading config:', error);
54
+ }
55
+ }
56
+ async getConfig() {
57
+ return this.config;
58
+ }
59
+ async updateConfig(updates) {
60
+ this.config = { ...this.config, ...updates };
61
+ this.config.defaultAgentId = this.getDefaultAgentId(this.config);
62
+ await this.saveConfig();
63
+ return this.config;
64
+ }
65
+ async saveConfig() {
66
+ try {
67
+ await writeFile(this.configPath, JSON.stringify(this.config, null, 2));
68
+ }
69
+ catch (error) {
70
+ console.error('Error saving config:', error);
71
+ throw error;
72
+ }
73
+ }
74
+ async getProviders() {
75
+ return ['deepseek', 'dashscope', 'openai', 'anthropic'];
76
+ }
77
+ async getModels(provider) {
78
+ const modelMap = {
79
+ deepseek: ['deepseek-chat', 'deepseek-coder'],
80
+ dashscope: ['qwen-max', 'qwen-plus', 'qwen-turbo'],
81
+ openai: ['gpt-4', 'gpt-3.5-turbo'],
82
+ anthropic: ['claude-3-opus', 'claude-3-sonnet'],
83
+ };
84
+ return modelMap[provider] || [];
85
+ }
86
+ };
87
+ ConfigService = __decorate([
88
+ Injectable(),
89
+ __metadata("design:paramtypes", [])
90
+ ], ConfigService);
91
+ export { ConfigService };
@@ -0,0 +1,2 @@
1
+ export declare class DatabaseModule {
2
+ }
@@ -0,0 +1,18 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { Global, Module } from '@nestjs/common';
8
+ import { DatabaseService } from './database.service.js';
9
+ let DatabaseModule = class DatabaseModule {
10
+ };
11
+ DatabaseModule = __decorate([
12
+ Global(),
13
+ Module({
14
+ providers: [DatabaseService],
15
+ exports: [DatabaseService],
16
+ })
17
+ ], DatabaseModule);
18
+ export { DatabaseModule };
@@ -0,0 +1,11 @@
1
+ import { OnModuleDestroy } from '@nestjs/common';
2
+ import Database from 'better-sqlite3';
3
+ export declare class DatabaseService implements OnModuleDestroy {
4
+ private db;
5
+ getDb(): Database.Database;
6
+ private runMigrations;
7
+ run(sql: string, params?: unknown[]): Database.RunResult;
8
+ get<T>(sql: string, params?: unknown[]): T | undefined;
9
+ all<T>(sql: string, params?: unknown[]): T[];
10
+ onModuleDestroy(): void;
11
+ }
@@ -0,0 +1,137 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { Injectable } from '@nestjs/common';
8
+ import Database from 'better-sqlite3';
9
+ import { mkdirSync, existsSync } from 'fs';
10
+ import { join } from 'path';
11
+ import { homedir } from 'os';
12
+ let DatabaseService = class DatabaseService {
13
+ db = null;
14
+ getDb() {
15
+ if (!this.db) {
16
+ const pathEnv = process.env.OPENBOT_DB_PATH;
17
+ const defaultDir = join(homedir(), '.openbot', 'desktop', 'data');
18
+ const path = pathEnv === ':memory:' || pathEnv === ''
19
+ ? ':memory:'
20
+ : pathEnv ?? join(process.env.OPENBOT_DB_DIR ?? defaultDir, 'openbot.db');
21
+ if (path !== ':memory:') {
22
+ const dir = path.endsWith('.db') ? join(path, '..') : path;
23
+ if (!existsSync(dir)) {
24
+ mkdirSync(dir, { recursive: true });
25
+ }
26
+ }
27
+ this.db = new Database(path);
28
+ this.db.pragma('journal_mode = WAL');
29
+ this.runMigrations();
30
+ }
31
+ return this.db;
32
+ }
33
+ runMigrations() {
34
+ const db = this.db;
35
+ db.exec(`
36
+ CREATE TABLE IF NOT EXISTS sessions (
37
+ id TEXT PRIMARY KEY,
38
+ created_at INTEGER NOT NULL,
39
+ last_active_at INTEGER NOT NULL,
40
+ message_count INTEGER NOT NULL DEFAULT 0,
41
+ status TEXT NOT NULL DEFAULT 'idle',
42
+ agent_id TEXT DEFAULT 'default',
43
+ workspace TEXT,
44
+ provider TEXT,
45
+ model TEXT,
46
+ title TEXT,
47
+ preview TEXT,
48
+ type TEXT DEFAULT 'chat'
49
+ );
50
+ CREATE TABLE IF NOT EXISTS chat_messages (
51
+ id TEXT PRIMARY KEY,
52
+ session_id TEXT NOT NULL,
53
+ role TEXT NOT NULL,
54
+ content TEXT NOT NULL,
55
+ timestamp INTEGER NOT NULL,
56
+ tool_calls_json TEXT,
57
+ FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
58
+ );
59
+ CREATE INDEX IF NOT EXISTS idx_chat_messages_session_id ON chat_messages(session_id);
60
+
61
+ CREATE TABLE IF NOT EXISTS scheduled_tasks (
62
+ id TEXT PRIMARY KEY,
63
+ workspace TEXT NOT NULL DEFAULT 'default',
64
+ message TEXT NOT NULL,
65
+ schedule_type TEXT NOT NULL,
66
+ run_at INTEGER,
67
+ cron_expr TEXT,
68
+ repeat_rule_json TEXT,
69
+ enabled INTEGER NOT NULL DEFAULT 1,
70
+ last_run_at INTEGER,
71
+ created_at INTEGER NOT NULL,
72
+ updated_at INTEGER NOT NULL
73
+ );
74
+ CREATE INDEX IF NOT EXISTS idx_scheduled_tasks_enabled ON scheduled_tasks(enabled);
75
+
76
+ CREATE TABLE IF NOT EXISTS scheduled_task_executions (
77
+ id TEXT PRIMARY KEY,
78
+ task_id TEXT NOT NULL,
79
+ ran_at INTEGER NOT NULL,
80
+ status TEXT NOT NULL,
81
+ session_id TEXT,
82
+ user_message TEXT NOT NULL,
83
+ assistant_content TEXT,
84
+ error_message TEXT,
85
+ created_at INTEGER NOT NULL,
86
+ FOREIGN KEY (task_id) REFERENCES scheduled_tasks(id) ON DELETE CASCADE
87
+ );
88
+ CREATE INDEX IF NOT EXISTS idx_task_executions_task_id ON scheduled_task_executions(task_id);
89
+
90
+ CREATE TABLE IF NOT EXISTS token_usage (
91
+ id TEXT PRIMARY KEY,
92
+ session_id TEXT NOT NULL,
93
+ source TEXT NOT NULL,
94
+ task_id TEXT,
95
+ execution_id TEXT,
96
+ prompt_tokens INTEGER NOT NULL DEFAULT 0,
97
+ completion_tokens INTEGER NOT NULL DEFAULT 0,
98
+ total_tokens INTEGER NOT NULL DEFAULT 0,
99
+ created_at INTEGER NOT NULL
100
+ );
101
+ CREATE INDEX IF NOT EXISTS idx_token_usage_session_id ON token_usage(session_id);
102
+ CREATE INDEX IF NOT EXISTS idx_token_usage_created_at ON token_usage(created_at);
103
+ `);
104
+ // Add session type column if missing (scheduled vs chat)
105
+ try {
106
+ const info = db.prepare('PRAGMA table_info(sessions)').all();
107
+ if (!info.some((c) => c.name === 'type')) {
108
+ db.exec(`ALTER TABLE sessions ADD COLUMN type TEXT DEFAULT 'chat'`);
109
+ }
110
+ if (!info.some((c) => c.name === 'agent_id')) {
111
+ db.exec(`ALTER TABLE sessions ADD COLUMN agent_id TEXT DEFAULT 'default'`);
112
+ }
113
+ }
114
+ catch (_) {
115
+ // ignore
116
+ }
117
+ }
118
+ run(sql, params = []) {
119
+ return this.getDb().prepare(sql).run(...params);
120
+ }
121
+ get(sql, params = []) {
122
+ return this.getDb().prepare(sql).get(...params);
123
+ }
124
+ all(sql, params = []) {
125
+ return this.getDb().prepare(sql).all(...params);
126
+ }
127
+ onModuleDestroy() {
128
+ if (this.db) {
129
+ this.db.close();
130
+ this.db = null;
131
+ }
132
+ }
133
+ };
134
+ DatabaseService = __decorate([
135
+ Injectable()
136
+ ], DatabaseService);
137
+ export { DatabaseService };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,18 @@
1
+ import { NestFactory } from '@nestjs/core';
2
+ import { AppModule } from './app.module.js';
3
+ async function bootstrap() {
4
+ const app = await NestFactory.create(AppModule, {
5
+ cors: true,
6
+ });
7
+ // Set global prefix
8
+ app.setGlobalPrefix('server-api');
9
+ // Enable CORS for frontend
10
+ app.enableCors({
11
+ origin: ['http://localhost:5173', 'http://localhost:3001'],
12
+ credentials: true,
13
+ });
14
+ const port = process.env.PORT || 3001;
15
+ await app.listen(port);
16
+ console.log(`🚀 OpenBot Desktop Server running on http://localhost:${port}`);
17
+ }
18
+ bootstrap();
@@ -0,0 +1,63 @@
1
+ import { SkillsService } from './skills.service.js';
2
+ import { AgentsService } from '../agents/agents.service.js';
3
+ import { AgentConfigService } from '../agent-config/agent-config.service.js';
4
+ export declare class SkillsController {
5
+ private readonly skillsService;
6
+ private readonly agentsService;
7
+ private readonly agentConfigService;
8
+ constructor(skillsService: SkillsService, agentsService: AgentsService, agentConfigService: AgentConfigService);
9
+ getSkills(workspace?: string, scope?: string): Promise<{
10
+ success: boolean;
11
+ data: import("./skills.service.js").Skill[];
12
+ }>;
13
+ /** 静态 POST 路由放在 :name 等参数路由之前,确保能被正确匹配 */
14
+ installSkill(body: {
15
+ url: string;
16
+ scope?: 'global' | 'workspace';
17
+ workspace?: string;
18
+ sessionId?: string;
19
+ /** 安装目标:具体 agentId,或 "global"|"all" 表示全局;优先于 sessionId */
20
+ targetAgentId?: string;
21
+ }): Promise<{
22
+ success: boolean;
23
+ data: {
24
+ stdout: string;
25
+ stderr: string;
26
+ installDir: string;
27
+ };
28
+ }>;
29
+ installSkillFromPath(body: {
30
+ path: string;
31
+ scope?: 'global' | 'workspace';
32
+ workspace?: string;
33
+ targetAgentId?: string;
34
+ }): Promise<{
35
+ success: boolean;
36
+ data: {
37
+ installDir: string;
38
+ name: string;
39
+ };
40
+ }>;
41
+ getSkill(name: string): Promise<{
42
+ success: boolean;
43
+ data: import("./skills.service.js").Skill;
44
+ }>;
45
+ getSkillContent(name: string, workspace?: string): Promise<{
46
+ success: boolean;
47
+ data: {
48
+ content: string;
49
+ };
50
+ }>;
51
+ addSkill(body: {
52
+ workspace: string;
53
+ name: string;
54
+ description?: string;
55
+ content?: string;
56
+ }): Promise<{
57
+ success: boolean;
58
+ data: import("./skills.service.js").Skill;
59
+ }>;
60
+ deleteSkill(name: string, workspace?: string, scope?: string): Promise<{
61
+ success: boolean;
62
+ }>;
63
+ }
@@ -0,0 +1,194 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
11
+ return function (target, key) { decorator(target, key, paramIndex); }
12
+ };
13
+ import { Controller, Get, Post, Delete, Param, Query, Body, HttpException, HttpStatus } from '@nestjs/common';
14
+ import { SkillsService } from './skills.service.js';
15
+ import { AgentsService } from '../agents/agents.service.js';
16
+ import { AgentConfigService } from '../agent-config/agent-config.service.js';
17
+ let SkillsController = class SkillsController {
18
+ skillsService;
19
+ agentsService;
20
+ agentConfigService;
21
+ constructor(skillsService, agentsService, agentConfigService) {
22
+ this.skillsService = skillsService;
23
+ this.agentsService = agentsService;
24
+ this.agentConfigService = agentConfigService;
25
+ }
26
+ async getSkills(workspace, scope) {
27
+ if (scope === 'global') {
28
+ const skills = await this.skillsService.getGlobalSkills();
29
+ return { success: true, data: skills };
30
+ }
31
+ const skills = workspace
32
+ ? await this.skillsService.getSkillsForWorkspace(workspace)
33
+ : await this.skillsService.getSkills();
34
+ return { success: true, data: skills };
35
+ }
36
+ /** 静态 POST 路由放在 :name 等参数路由之前,确保能被正确匹配 */
37
+ async installSkill(body) {
38
+ const url = body?.url?.trim();
39
+ if (!url) {
40
+ throw new HttpException('url is required', HttpStatus.BAD_REQUEST);
41
+ }
42
+ let scope = body?.scope ?? 'global';
43
+ let workspace = body?.workspace;
44
+ const tid = (body?.targetAgentId ?? '').trim().toLowerCase();
45
+ if (tid === 'global' || tid === 'all') {
46
+ scope = 'global';
47
+ workspace = undefined;
48
+ }
49
+ else if (body?.targetAgentId?.trim()) {
50
+ const agent = await this.agentConfigService.getAgent(body.targetAgentId.trim());
51
+ if (agent?.workspace) {
52
+ scope = 'workspace';
53
+ workspace = agent.workspace;
54
+ }
55
+ }
56
+ else if (body?.sessionId) {
57
+ const session = this.agentsService.getSession(body.sessionId);
58
+ const agentId = session?.agentId ?? 'default';
59
+ const agent = await this.agentConfigService.getAgent(agentId);
60
+ if (agent?.workspace) {
61
+ scope = 'workspace';
62
+ workspace = agent.workspace;
63
+ }
64
+ }
65
+ const result = await this.skillsService.installSkillByUrl(url, {
66
+ scope,
67
+ workspace: scope === 'workspace' ? workspace ?? 'default' : undefined,
68
+ });
69
+ return { success: true, data: result };
70
+ }
71
+ async installSkillFromPath(body) {
72
+ const localPath = body?.path?.trim();
73
+ if (!localPath) {
74
+ throw new HttpException('path is required', HttpStatus.BAD_REQUEST);
75
+ }
76
+ let scope = body?.scope ?? 'global';
77
+ let workspace = body?.workspace;
78
+ const tid = (body?.targetAgentId ?? '').trim().toLowerCase();
79
+ if (tid === 'global' || tid === 'all') {
80
+ scope = 'global';
81
+ workspace = undefined;
82
+ }
83
+ else if (body?.targetAgentId?.trim()) {
84
+ const agent = await this.agentConfigService.getAgent(body.targetAgentId.trim());
85
+ if (agent?.workspace) {
86
+ scope = 'workspace';
87
+ workspace = agent.workspace;
88
+ }
89
+ }
90
+ const result = await this.skillsService.installSkillFromPath(localPath, {
91
+ scope,
92
+ workspace: scope === 'workspace' ? workspace ?? 'default' : undefined,
93
+ });
94
+ return { success: true, data: result };
95
+ }
96
+ async getSkill(name) {
97
+ const skill = await this.skillsService.getSkill(name);
98
+ if (!skill) {
99
+ throw new HttpException('Skill not found', HttpStatus.NOT_FOUND);
100
+ }
101
+ return { success: true, data: skill };
102
+ }
103
+ async getSkillContent(name, workspace) {
104
+ const content = workspace
105
+ ? await this.skillsService.getSkillContentForWorkspace(workspace, name)
106
+ : await this.skillsService.getSkillContent(name);
107
+ if (!content) {
108
+ throw new HttpException('Skill not found', HttpStatus.NOT_FOUND);
109
+ }
110
+ return { success: true, data: { content } };
111
+ }
112
+ async addSkill(body) {
113
+ const { workspace, name, description, content } = body;
114
+ if (!workspace || !name) {
115
+ throw new HttpException('workspace and name are required', HttpStatus.BAD_REQUEST);
116
+ }
117
+ const skill = await this.skillsService.addSkill(workspace, name, {
118
+ description,
119
+ content,
120
+ });
121
+ return { success: true, data: skill };
122
+ }
123
+ async deleteSkill(name, workspace, scope) {
124
+ if (scope === 'global') {
125
+ await this.skillsService.deleteGlobalSkill(name);
126
+ return { success: true };
127
+ }
128
+ if (!workspace) {
129
+ throw new HttpException('workspace query is required', HttpStatus.BAD_REQUEST);
130
+ }
131
+ await this.skillsService.deleteSkill(workspace, name);
132
+ return { success: true };
133
+ }
134
+ };
135
+ __decorate([
136
+ Get(),
137
+ __param(0, Query('workspace')),
138
+ __param(1, Query('scope')),
139
+ __metadata("design:type", Function),
140
+ __metadata("design:paramtypes", [String, String]),
141
+ __metadata("design:returntype", Promise)
142
+ ], SkillsController.prototype, "getSkills", null);
143
+ __decorate([
144
+ Post('install'),
145
+ __param(0, Body()),
146
+ __metadata("design:type", Function),
147
+ __metadata("design:paramtypes", [Object]),
148
+ __metadata("design:returntype", Promise)
149
+ ], SkillsController.prototype, "installSkill", null);
150
+ __decorate([
151
+ Post('install-from-path'),
152
+ __param(0, Body()),
153
+ __metadata("design:type", Function),
154
+ __metadata("design:paramtypes", [Object]),
155
+ __metadata("design:returntype", Promise)
156
+ ], SkillsController.prototype, "installSkillFromPath", null);
157
+ __decorate([
158
+ Get(':name'),
159
+ __param(0, Param('name')),
160
+ __metadata("design:type", Function),
161
+ __metadata("design:paramtypes", [String]),
162
+ __metadata("design:returntype", Promise)
163
+ ], SkillsController.prototype, "getSkill", null);
164
+ __decorate([
165
+ Get(':name/content'),
166
+ __param(0, Param('name')),
167
+ __param(1, Query('workspace')),
168
+ __metadata("design:type", Function),
169
+ __metadata("design:paramtypes", [String, String]),
170
+ __metadata("design:returntype", Promise)
171
+ ], SkillsController.prototype, "getSkillContent", null);
172
+ __decorate([
173
+ Post(),
174
+ __param(0, Body()),
175
+ __metadata("design:type", Function),
176
+ __metadata("design:paramtypes", [Object]),
177
+ __metadata("design:returntype", Promise)
178
+ ], SkillsController.prototype, "addSkill", null);
179
+ __decorate([
180
+ Delete(':name'),
181
+ __param(0, Param('name')),
182
+ __param(1, Query('workspace')),
183
+ __param(2, Query('scope')),
184
+ __metadata("design:type", Function),
185
+ __metadata("design:paramtypes", [String, String, String]),
186
+ __metadata("design:returntype", Promise)
187
+ ], SkillsController.prototype, "deleteSkill", null);
188
+ SkillsController = __decorate([
189
+ Controller('skills'),
190
+ __metadata("design:paramtypes", [SkillsService,
191
+ AgentsService,
192
+ AgentConfigService])
193
+ ], SkillsController);
194
+ export { SkillsController };
@@ -0,0 +1,2 @@
1
+ export declare class SkillsModule {
2
+ }
@@ -0,0 +1,22 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { Module } from '@nestjs/common';
8
+ import { SkillsController } from './skills.controller.js';
9
+ import { SkillsService } from './skills.service.js';
10
+ import { AgentsModule } from '../agents/agents.module.js';
11
+ import { AgentConfigModule } from '../agent-config/agent-config.module.js';
12
+ let SkillsModule = class SkillsModule {
13
+ };
14
+ SkillsModule = __decorate([
15
+ Module({
16
+ imports: [AgentsModule, AgentConfigModule],
17
+ controllers: [SkillsController],
18
+ providers: [SkillsService],
19
+ exports: [SkillsService],
20
+ })
21
+ ], SkillsModule);
22
+ export { SkillsModule };
@@ -0,0 +1,63 @@
1
+ export interface Skill {
2
+ name: string;
3
+ description: string;
4
+ path: string;
5
+ category?: string;
6
+ source?: 'system' | 'global' | 'workspace';
7
+ metadata?: any;
8
+ }
9
+ /** 技能目录与来源:全局=OPENBOT_AGENT_DIR/skills,系统=项目根/skills,工作区=OPENBOT_WORKSPACE_DIR/xxx/skills */
10
+ export declare class SkillsService {
11
+ /** 待扫描的目录列表 */
12
+ private skillPaths;
13
+ constructor();
14
+ /** 指定工作区的 skills 目录绝对路径(受 OPENBOT_WORKSPACE_DIR 影响) */
15
+ getWorkspaceSkillsDir(workspaceName: string): string;
16
+ /** 全局技能目录(受 OPENBOT_AGENT_DIR 影响,默认 ~/.openbot/agent/skills) */
17
+ getGlobalSkillsDir(): string;
18
+ /** 仅返回全局技能(OPENBOT_AGENT_DIR/skills) */
19
+ getGlobalSkills(): Promise<Skill[]>;
20
+ /** 删除全局技能 */
21
+ deleteGlobalSkill(name: string): Promise<void>;
22
+ /**
23
+ * 通过 npx skills add 安装技能到指定目录。
24
+ * @param url 安装地址(Git 简写、URL 或 owner/repo@skill)
25
+ * @param options.scope 'global' 安装到 OPENBOT_AGENT_DIR/skills;'workspace' 安装到指定工作区的 skills
26
+ * @param options.workspace 当 scope 为 'workspace' 时的工作区名(对应 OPENBOT_WORKSPACE_DIR/<workspace>/skills)
27
+ */
28
+ installSkillByUrl(url: string, options?: {
29
+ scope?: 'global' | 'workspace';
30
+ workspace?: string;
31
+ }): Promise<{
32
+ stdout: string;
33
+ stderr: string;
34
+ installDir: string;
35
+ }>;
36
+ /**
37
+ * 从本地目录安装技能:将指定目录复制到目标 skills 目录。
38
+ * @param localPath 本地技能目录绝对路径(须包含 SKILL.md)
39
+ * @param options.scope 'global' 安装到全局;'workspace' 安装到指定工作区
40
+ * @param options.workspace 当 scope 为 'workspace' 时的工作区名
41
+ */
42
+ installSkillFromPath(localPath: string, options?: {
43
+ scope?: 'global' | 'workspace';
44
+ workspace?: string;
45
+ }): Promise<{
46
+ installDir: string;
47
+ name: string;
48
+ }>;
49
+ getSkills(): Promise<Skill[]>;
50
+ getSkill(name: string): Promise<Skill | null>;
51
+ getSkillContent(name: string): Promise<string | null>;
52
+ /** 仅返回指定工作区下的技能(文件目录管理,不涉及 SQLite) */
53
+ getSkillsForWorkspace(workspaceName: string): Promise<Skill[]>;
54
+ getSkillContentForWorkspace(workspaceName: string, name: string): Promise<string | null>;
55
+ /** 在工作区下新增技能(创建目录 + SKILL.md) */
56
+ addSkill(workspaceName: string, name: string, options?: {
57
+ description?: string;
58
+ content?: string;
59
+ }): Promise<Skill>;
60
+ /** 删除工作区下的技能目录;主智能体(default)下的 Skill 不可删除 */
61
+ deleteSkill(workspaceName: string, name: string): Promise<void>;
62
+ private parseSkillFile;
63
+ }