skyloom 1.13.5 → 1.13.7

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 (195) hide show
  1. package/.github/workflows/ci.yml +36 -36
  2. package/README.md +220 -159
  3. package/config/providers.yaml +39 -39
  4. package/config/skills/api_integrator/SKILL.md +15 -15
  5. package/config/skills/arch_designer/SKILL.md +13 -13
  6. package/config/skills/ci_cd_manager/SKILL.md +14 -14
  7. package/config/skills/code_analysis/SKILL.md +13 -13
  8. package/config/skills/code_generator/SKILL.md +12 -12
  9. package/config/skills/code_reviewer/SKILL.md +13 -13
  10. package/config/skills/content_writer/SKILL.md +14 -14
  11. package/config/skills/data_transformer/SKILL.md +15 -15
  12. package/config/skills/document_analysis/SKILL.md +13 -13
  13. package/config/skills/emotional_companion/SKILL.md +15 -15
  14. package/config/skills/performance_checker/SKILL.md +14 -14
  15. package/config/skills/security_auditor/SKILL.md +14 -14
  16. package/config/skills/self_evolve/SKILL.md +13 -13
  17. package/config/skills/sys_operator/SKILL.md +15 -15
  18. package/config/skills/task_planner/SKILL.md +14 -14
  19. package/config/skills/web_research/SKILL.md +14 -14
  20. package/config/skills/workflow_designer/SKILL.md +13 -13
  21. package/dist/agents/dew.js +52 -52
  22. package/dist/agents/fair.js +84 -84
  23. package/dist/agents/fog.js +30 -30
  24. package/dist/agents/frost.js +32 -32
  25. package/dist/agents/rain.js +32 -32
  26. package/dist/agents/snow.js +68 -68
  27. package/dist/cli/commands_md.d.ts +41 -0
  28. package/dist/cli/commands_md.d.ts.map +1 -0
  29. package/dist/cli/commands_md.js +140 -0
  30. package/dist/cli/commands_md.js.map +1 -0
  31. package/dist/cli/input_macros.d.ts +28 -0
  32. package/dist/cli/input_macros.d.ts.map +1 -0
  33. package/dist/cli/input_macros.js +120 -0
  34. package/dist/cli/input_macros.js.map +1 -0
  35. package/dist/cli/loom.d.ts +220 -0
  36. package/dist/cli/loom.d.ts.map +1 -0
  37. package/dist/cli/loom.js +1094 -0
  38. package/dist/cli/loom.js.map +1 -0
  39. package/dist/cli/loom_chat.d.ts +20 -0
  40. package/dist/cli/loom_chat.d.ts.map +1 -0
  41. package/dist/cli/loom_chat.js +685 -0
  42. package/dist/cli/loom_chat.js.map +1 -0
  43. package/dist/cli/main.js +310 -14
  44. package/dist/cli/main.js.map +1 -1
  45. package/dist/cli/tui.d.ts.map +1 -1
  46. package/dist/cli/tui.js +7 -1
  47. package/dist/cli/tui.js.map +1 -1
  48. package/dist/core/agent/guard.d.ts +45 -0
  49. package/dist/core/agent/guard.d.ts.map +1 -0
  50. package/dist/core/agent/guard.js +113 -0
  51. package/dist/core/agent/guard.js.map +1 -0
  52. package/dist/core/agent.d.ts +17 -0
  53. package/dist/core/agent.d.ts.map +1 -1
  54. package/dist/core/agent.js +182 -93
  55. package/dist/core/agent.js.map +1 -1
  56. package/dist/core/factory.d.ts.map +1 -1
  57. package/dist/core/factory.js +34 -2
  58. package/dist/core/factory.js.map +1 -1
  59. package/dist/core/file_checkpoint.d.ts +57 -0
  60. package/dist/core/file_checkpoint.d.ts.map +1 -0
  61. package/dist/core/file_checkpoint.js +162 -0
  62. package/dist/core/file_checkpoint.js.map +1 -0
  63. package/dist/core/hooks.d.ts +43 -0
  64. package/dist/core/hooks.d.ts.map +1 -0
  65. package/dist/core/hooks.js +110 -0
  66. package/dist/core/hooks.js.map +1 -0
  67. package/dist/core/llm.d.ts.map +1 -1
  68. package/dist/core/llm.js +15 -9
  69. package/dist/core/llm.js.map +1 -1
  70. package/dist/core/longdoc.js +5 -5
  71. package/dist/core/mcp.d.ts +16 -0
  72. package/dist/core/mcp.d.ts.map +1 -1
  73. package/dist/core/mcp.js +55 -0
  74. package/dist/core/mcp.js.map +1 -1
  75. package/dist/core/model_config.d.ts +40 -0
  76. package/dist/core/model_config.d.ts.map +1 -0
  77. package/dist/core/model_config.js +191 -0
  78. package/dist/core/model_config.js.map +1 -0
  79. package/dist/core/skill.d.ts +7 -0
  80. package/dist/core/skill.d.ts.map +1 -1
  81. package/dist/core/skill.js +47 -0
  82. package/dist/core/skill.js.map +1 -1
  83. package/dist/core/skymd.d.ts +39 -0
  84. package/dist/core/skymd.d.ts.map +1 -0
  85. package/dist/core/skymd.js +177 -0
  86. package/dist/core/skymd.js.map +1 -0
  87. package/dist/core/tool.d.ts +12 -0
  88. package/dist/core/tool.d.ts.map +1 -1
  89. package/dist/core/tool.js +30 -0
  90. package/dist/core/tool.js.map +1 -1
  91. package/dist/core/verify.d.ts +27 -0
  92. package/dist/core/verify.d.ts.map +1 -0
  93. package/dist/core/verify.js +62 -0
  94. package/dist/core/verify.js.map +1 -0
  95. package/dist/skills/loader.d.ts +22 -2
  96. package/dist/skills/loader.d.ts.map +1 -1
  97. package/dist/skills/loader.js +45 -15
  98. package/dist/skills/loader.js.map +1 -1
  99. package/dist/tools/builtin.d.ts.map +1 -1
  100. package/dist/tools/builtin.js +13 -3
  101. package/dist/tools/builtin.js.map +1 -1
  102. package/dist/tools/model_tool.d.ts +11 -0
  103. package/dist/tools/model_tool.d.ts.map +1 -0
  104. package/dist/tools/model_tool.js +71 -0
  105. package/dist/tools/model_tool.js.map +1 -0
  106. package/dist/tools/todo.d.ts +30 -0
  107. package/dist/tools/todo.d.ts.map +1 -0
  108. package/dist/tools/todo.js +78 -0
  109. package/dist/tools/todo.js.map +1 -0
  110. package/docs/AESTHETIC_DESIGN.md +152 -144
  111. package/docs/OPTIMIZATION_PLAN.md +178 -178
  112. package/package.json +1 -1
  113. package/scripts/install.js +48 -48
  114. package/scripts/link.js +10 -10
  115. package/setup.bat +79 -79
  116. package/skill-test-ty2fOA/test.md +10 -10
  117. package/src/agents/dew.ts +70 -70
  118. package/src/agents/fair.ts +102 -102
  119. package/src/agents/fog.ts +48 -48
  120. package/src/agents/frost.ts +50 -50
  121. package/src/agents/rain.ts +50 -50
  122. package/src/agents/snow.ts +239 -239
  123. package/src/cli/commands_md.ts +112 -0
  124. package/src/cli/input_macros.ts +83 -0
  125. package/src/cli/loom.ts +982 -0
  126. package/src/cli/loom_chat.ts +598 -0
  127. package/src/cli/main.ts +255 -9
  128. package/src/cli/mode.ts +58 -58
  129. package/src/cli/tui.ts +228 -222
  130. package/src/core/agent/guard.ts +134 -0
  131. package/src/core/agent/task.ts +100 -100
  132. package/src/core/agent.ts +177 -95
  133. package/src/core/arbitrate.ts +162 -162
  134. package/src/core/catalog.ts +178 -178
  135. package/src/core/checkpoint.ts +94 -94
  136. package/src/core/estimate.ts +104 -104
  137. package/src/core/evolve.ts +191 -191
  138. package/src/core/factory.ts +31 -2
  139. package/src/core/file_checkpoint.ts +136 -0
  140. package/src/core/filter.ts +103 -103
  141. package/src/core/graph.ts +156 -156
  142. package/src/core/hooks.ts +126 -0
  143. package/src/core/icons.ts +53 -53
  144. package/src/core/index.ts +37 -37
  145. package/src/core/learn.ts +146 -146
  146. package/src/core/llm.ts +15 -9
  147. package/src/core/longdoc.ts +155 -155
  148. package/src/core/mcp.ts +48 -0
  149. package/src/core/mcp_server.ts +176 -176
  150. package/src/core/model_config.ts +157 -0
  151. package/src/core/profile.ts +255 -255
  152. package/src/core/router.ts +124 -124
  153. package/src/core/sandbox.ts +142 -142
  154. package/src/core/security.ts +243 -243
  155. package/src/core/skill.ts +42 -0
  156. package/src/core/skymd.ts +143 -0
  157. package/src/core/theme.ts +65 -65
  158. package/src/core/tool.ts +30 -0
  159. package/src/core/tool_router.ts +193 -193
  160. package/src/core/vector.ts +152 -152
  161. package/src/core/verify.ts +71 -0
  162. package/src/core/workspace.ts +150 -150
  163. package/src/plugins/loader.ts +66 -66
  164. package/src/skills/loader.ts +45 -16
  165. package/src/sql.js.d.ts +29 -29
  166. package/src/tools/builtin.ts +13 -3
  167. package/src/tools/computer.ts +269 -269
  168. package/src/tools/delegate.ts +49 -49
  169. package/src/tools/model_tool.ts +74 -0
  170. package/src/tools/todo.ts +76 -0
  171. package/src/web/tts.ts +93 -93
  172. package/tests/agent.test.ts +159 -159
  173. package/tests/agent_helpers.test.ts +48 -48
  174. package/tests/bus.test.ts +121 -121
  175. package/tests/catalog.test.ts +86 -86
  176. package/tests/checkpoint_commands.test.ts +124 -0
  177. package/tests/claude_compat.test.ts +110 -0
  178. package/tests/config.test.ts +41 -41
  179. package/tests/guard.test.ts +75 -0
  180. package/tests/icons.test.ts +45 -45
  181. package/tests/loom.test.ts +248 -0
  182. package/tests/memory.test.ts +170 -170
  183. package/tests/model_config.test.ts +109 -0
  184. package/tests/router.test.ts +86 -86
  185. package/tests/schemas.test.ts +51 -51
  186. package/tests/semantic.test.ts +83 -83
  187. package/tests/setup.ts +10 -10
  188. package/tests/skill.test.ts +172 -172
  189. package/tests/skymd.test.ts +146 -0
  190. package/tests/task.test.ts +60 -60
  191. package/tests/todo_toolstats.test.ts +94 -0
  192. package/tests/tool.test.ts +108 -108
  193. package/tests/tool_router.test.ts +71 -71
  194. package/tests/tui.test.ts +67 -67
  195. package/vitest.config.ts +17 -17
@@ -1,66 +1,66 @@
1
- /**
2
- * Plugin loader — loads external plugins that register additional tools.
3
- */
4
-
5
- import * as fs from 'fs';
6
- import * as path from 'path';
7
- import { ToolRegistry } from '../core/tool';
8
- import { getLogger } from '../core/logger';
9
-
10
- const log = getLogger('plugin-loader');
11
-
12
- export class PluginLoader {
13
- private toolRegistry: ToolRegistry;
14
-
15
- constructor(toolRegistry: ToolRegistry) {
16
- this.toolRegistry = toolRegistry;
17
- }
18
-
19
- /**
20
- * Load plugins from specified directories.
21
- */
22
- loadFromDirectories(directories: string[]): number {
23
- let total = 0;
24
- for (const dir of directories) {
25
- total += this.loadDirectory(dir);
26
- }
27
- return total;
28
- }
29
-
30
- /**
31
- * Load a single plugin directory.
32
- */
33
- private loadDirectory(dir: string): number {
34
- if (!fs.existsSync(dir)) {
35
- log.debug('plugin_dir_not_found', { dir });
36
- return 0;
37
- }
38
-
39
- let count = 0;
40
- try {
41
- const entries = fs.readdirSync(dir);
42
- for (const entry of entries) {
43
- const pluginPath = path.join(dir, entry);
44
- if (!fs.statSync(pluginPath).isDirectory()) continue;
45
-
46
- const pluginFile = path.join(pluginPath, 'index.js');
47
- if (!fs.existsSync(pluginFile)) continue;
48
-
49
- try {
50
- const plugin = require(pluginFile);
51
- if (typeof plugin.register === 'function') {
52
- plugin.register(this.toolRegistry);
53
- count++;
54
- log.info('plugin_loaded', { name: entry });
55
- }
56
- } catch (e) {
57
- log.warn('plugin_load_failed', { name: entry, error: String(e) });
58
- }
59
- }
60
- } catch (e) {
61
- log.warn('plugin_dir_scan_failed', { dir, error: String(e) });
62
- }
63
-
64
- return count;
65
- }
66
- }
1
+ /**
2
+ * Plugin loader — loads external plugins that register additional tools.
3
+ */
4
+
5
+ import * as fs from 'fs';
6
+ import * as path from 'path';
7
+ import { ToolRegistry } from '../core/tool';
8
+ import { getLogger } from '../core/logger';
9
+
10
+ const log = getLogger('plugin-loader');
11
+
12
+ export class PluginLoader {
13
+ private toolRegistry: ToolRegistry;
14
+
15
+ constructor(toolRegistry: ToolRegistry) {
16
+ this.toolRegistry = toolRegistry;
17
+ }
18
+
19
+ /**
20
+ * Load plugins from specified directories.
21
+ */
22
+ loadFromDirectories(directories: string[]): number {
23
+ let total = 0;
24
+ for (const dir of directories) {
25
+ total += this.loadDirectory(dir);
26
+ }
27
+ return total;
28
+ }
29
+
30
+ /**
31
+ * Load a single plugin directory.
32
+ */
33
+ private loadDirectory(dir: string): number {
34
+ if (!fs.existsSync(dir)) {
35
+ log.debug('plugin_dir_not_found', { dir });
36
+ return 0;
37
+ }
38
+
39
+ let count = 0;
40
+ try {
41
+ const entries = fs.readdirSync(dir);
42
+ for (const entry of entries) {
43
+ const pluginPath = path.join(dir, entry);
44
+ if (!fs.statSync(pluginPath).isDirectory()) continue;
45
+
46
+ const pluginFile = path.join(pluginPath, 'index.js');
47
+ if (!fs.existsSync(pluginFile)) continue;
48
+
49
+ try {
50
+ const plugin = require(pluginFile);
51
+ if (typeof plugin.register === 'function') {
52
+ plugin.register(this.toolRegistry);
53
+ count++;
54
+ log.info('plugin_loaded', { name: entry });
55
+ }
56
+ } catch (e) {
57
+ log.warn('plugin_load_failed', { name: entry, error: String(e) });
58
+ }
59
+ }
60
+ } catch (e) {
61
+ log.warn('plugin_dir_scan_failed', { dir, error: String(e) });
62
+ }
63
+
64
+ return count;
65
+ }
66
+ }
@@ -1,8 +1,21 @@
1
1
  /**
2
- * Skill loader — registers all built-in skills from skill definition files.
2
+ * Skill loader — built-in skills plus user/project skill discovery.
3
+ *
4
+ * Discovery order (later registration wins, so project beats user beats
5
+ * built-in when names collide):
6
+ * 1. built-in: config/skills/, assets/builtin_skills/
7
+ * 2. user: ~/.claude/skills/ (Claude Code compatible — zero-copy
8
+ * migration), then ~/.skyloom/skills/ (native)
9
+ * 3. project: <cwd>/.claude/skills/, then <cwd>/.sky/skills/
10
+ *
11
+ * All locations use the same folder layout as Claude Code:
12
+ * <root>/<skill-name>/SKILL.md (+ optional reference files / scripts)
13
+ * Frontmatter is Claude Code compatible (name / description /
14
+ * allowed-tools — tool names like `bash`/`read` are aliased to sky tools).
3
15
  */
4
16
 
5
17
  import * as fs from 'fs';
18
+ import * as os from 'os';
6
19
  import * as path from 'path';
7
20
  import { SkillRegistry } from '../core/skill';
8
21
  import { getLogger } from '../core/logger';
@@ -15,32 +28,48 @@ const BUILTIN_SKILL_DIRS = [
15
28
  path.join(__dirname, '..', '..', 'assets', 'builtin_skills'),
16
29
  ];
17
30
 
31
+ /** User/project skill roots, lowest precedence first. */
32
+ export function dynamicSkillDirs(cwd: string = process.cwd()): string[] {
33
+ return [
34
+ path.join(os.homedir(), '.claude', 'skills'),
35
+ path.join(os.homedir(), '.skyloom', 'skills'),
36
+ path.join(cwd, '.claude', 'skills'),
37
+ path.join(cwd, '.sky', 'skills'),
38
+ ];
39
+ }
40
+
41
+ /**
42
+ * (Re)scan user/project skill folders. Cheap enough to call on demand —
43
+ * list_skills triggers it, so edits to SKILL.md files apply live without
44
+ * restarting the session.
45
+ */
46
+ export function registerDynamicSkills(registry: SkillRegistry, cwd: string = process.cwd()): number {
47
+ let count = 0;
48
+ for (const dir of dynamicSkillDirs(cwd)) {
49
+ try {
50
+ count += registry.loadSkillFolders(dir).length;
51
+ } catch (e) {
52
+ log.warn('dynamic_skill_load_failed', { dir, error: String(e) });
53
+ }
54
+ }
55
+ return count;
56
+ }
57
+
18
58
  /**
19
- * Register all available skills from built-in directories.
59
+ * Register all available skills: built-ins, then user/project overlays.
20
60
  */
21
61
  export function registerAllSkills(registry: SkillRegistry): void {
22
62
  for (const dir of BUILTIN_SKILL_DIRS) {
23
63
  if (!fs.existsSync(dir)) continue;
24
-
25
64
  try {
26
- const entries = fs.readdirSync(dir);
27
- for (const entry of entries) {
28
- const skillDir = path.join(dir, entry);
29
- if (!fs.statSync(skillDir).isDirectory()) continue;
30
-
31
- const skillFile = path.join(skillDir, 'SKILL.md');
32
- if (!fs.existsSync(skillFile)) continue;
33
-
34
- const skill = registry.loadSkillsFromDirectory(skillDir);
35
- if (skill.length > 0) {
36
- log.debug('registered_skill', { name: entry, file: skillFile });
37
- }
38
- }
65
+ registry.loadSkillFolders(dir);
39
66
  } catch (e) {
40
67
  log.warn('skill_load_failed', { dir, error: String(e) });
41
68
  }
42
69
  }
43
70
 
71
+ registerDynamicSkills(registry);
72
+
44
73
  const count = registry.listNames().length;
45
74
  log.info('skills_loaded', { count });
46
75
  }
package/src/sql.js.d.ts CHANGED
@@ -1,29 +1,29 @@
1
- declare module 'sql.js' {
2
- interface SqlJsStatic {
3
- Database: new (data?: ArrayLike<number> | Buffer | null) => Database;
4
- }
5
-
6
- interface QueryExecResult {
7
- columns: string[];
8
- values: any[][];
9
- }
10
-
11
- interface Statement {
12
- bind(params?: any[]): boolean;
13
- step(): boolean;
14
- getAsObject(params?: object): Record<string, any>;
15
- free(): boolean;
16
- }
17
-
18
- interface Database {
19
- run(sql: string, params?: any[]): Database;
20
- exec(sql: string): QueryExecResult[];
21
- prepare(sql: string): Statement;
22
- export(): Uint8Array;
23
- close(): void;
24
- }
25
-
26
- export type { Database, SqlJsStatic, Statement };
27
-
28
- export default function initSqlJs(opts?: any): Promise<SqlJsStatic>;
29
- }
1
+ declare module 'sql.js' {
2
+ interface SqlJsStatic {
3
+ Database: new (data?: ArrayLike<number> | Buffer | null) => Database;
4
+ }
5
+
6
+ interface QueryExecResult {
7
+ columns: string[];
8
+ values: any[][];
9
+ }
10
+
11
+ interface Statement {
12
+ bind(params?: any[]): boolean;
13
+ step(): boolean;
14
+ getAsObject(params?: object): Record<string, any>;
15
+ free(): boolean;
16
+ }
17
+
18
+ interface Database {
19
+ run(sql: string, params?: any[]): Database;
20
+ exec(sql: string): QueryExecResult[];
21
+ prepare(sql: string): Statement;
22
+ export(): Uint8Array;
23
+ close(): void;
24
+ }
25
+
26
+ export type { Database, SqlJsStatic, Statement };
27
+
28
+ export default function initSqlJs(opts?: any): Promise<SqlJsStatic>;
29
+ }
@@ -20,16 +20,26 @@ export function registerBuiltinTools(registry: ToolRegistry): void {
20
20
 
21
21
  registry.register({
22
22
  name: 'read_file',
23
- description: 'Read the contents of a file at the given path. Use this to inspect files, check file contents, or verify writes.',
23
+ description: 'Read the contents of a file. Large files are paged: pass offset (1-based start line) and limit (line count) to read further sections; use grep to locate the right offset first.',
24
24
  parameters: [
25
25
  { name: 'path', type: 'string', description: 'Absolute or relative path to the file', required: true },
26
+ { name: 'offset', type: 'number', description: '1-based line number to start from (default 1)', required: false },
27
+ { name: 'limit', type: 'number', description: 'Max lines to return (default 800)', required: false },
26
28
  ],
27
29
  handler: async (params) => {
28
30
  const filePath = path.resolve(params.path as string);
29
31
  if (!fs.existsSync(filePath)) return `Error: File not found: ${filePath}`;
30
32
  try {
31
- const content = fs.readFileSync(filePath, 'utf-8');
32
- return `Successfully read ${filePath} (${content.length} chars):\n${content}`;
33
+ const lines = fs.readFileSync(filePath, 'utf-8').split('\n');
34
+ const offset = Math.max(1, Number(params.offset) || 1);
35
+ const limit = Math.max(1, Math.min(Number(params.limit) || 800, 4000));
36
+ const slice = lines.slice(offset - 1, offset - 1 + limit);
37
+ const remaining = lines.length - (offset - 1 + slice.length);
38
+ const tail = remaining > 0
39
+ ? `\n…[还有 ${remaining} 行 — read_file(path, offset=${offset + slice.length}) 继续]`
40
+ : '';
41
+ const range = offset > 1 || remaining > 0 ? ` lines ${offset}-${offset + slice.length - 1}/${lines.length}` : '';
42
+ return `Successfully read ${filePath}${range}:\n${slice.join('\n')}${tail}`;
33
43
  } catch (e) {
34
44
  return `Error reading file: ${e}`;
35
45
  }