skyloom 1.13.6 → 1.13.8

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 (193) 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.d.ts +20 -0
  49. package/dist/core/agent.d.ts.map +1 -1
  50. package/dist/core/agent.js +199 -16
  51. package/dist/core/agent.js.map +1 -1
  52. package/dist/core/factory.d.ts.map +1 -1
  53. package/dist/core/factory.js +34 -2
  54. package/dist/core/factory.js.map +1 -1
  55. package/dist/core/file_checkpoint.d.ts +57 -0
  56. package/dist/core/file_checkpoint.d.ts.map +1 -0
  57. package/dist/core/file_checkpoint.js +162 -0
  58. package/dist/core/file_checkpoint.js.map +1 -0
  59. package/dist/core/hooks.d.ts +43 -0
  60. package/dist/core/hooks.d.ts.map +1 -0
  61. package/dist/core/hooks.js +110 -0
  62. package/dist/core/hooks.js.map +1 -0
  63. package/dist/core/llm.d.ts.map +1 -1
  64. package/dist/core/llm.js +15 -9
  65. package/dist/core/llm.js.map +1 -1
  66. package/dist/core/longdoc.js +5 -5
  67. package/dist/core/mcp.d.ts +16 -0
  68. package/dist/core/mcp.d.ts.map +1 -1
  69. package/dist/core/mcp.js +55 -0
  70. package/dist/core/mcp.js.map +1 -1
  71. package/dist/core/model_config.d.ts +40 -0
  72. package/dist/core/model_config.d.ts.map +1 -0
  73. package/dist/core/model_config.js +191 -0
  74. package/dist/core/model_config.js.map +1 -0
  75. package/dist/core/skill.d.ts +7 -0
  76. package/dist/core/skill.d.ts.map +1 -1
  77. package/dist/core/skill.js +47 -0
  78. package/dist/core/skill.js.map +1 -1
  79. package/dist/core/skymd.d.ts +39 -0
  80. package/dist/core/skymd.d.ts.map +1 -0
  81. package/dist/core/skymd.js +177 -0
  82. package/dist/core/skymd.js.map +1 -0
  83. package/dist/core/tool.d.ts +12 -0
  84. package/dist/core/tool.d.ts.map +1 -1
  85. package/dist/core/tool.js +30 -0
  86. package/dist/core/tool.js.map +1 -1
  87. package/dist/core/verify.d.ts +27 -0
  88. package/dist/core/verify.d.ts.map +1 -0
  89. package/dist/core/verify.js +62 -0
  90. package/dist/core/verify.js.map +1 -0
  91. package/dist/skills/loader.d.ts +22 -2
  92. package/dist/skills/loader.d.ts.map +1 -1
  93. package/dist/skills/loader.js +45 -15
  94. package/dist/skills/loader.js.map +1 -1
  95. package/dist/tools/builtin.d.ts.map +1 -1
  96. package/dist/tools/builtin.js +13 -3
  97. package/dist/tools/builtin.js.map +1 -1
  98. package/dist/tools/model_tool.d.ts +11 -0
  99. package/dist/tools/model_tool.d.ts.map +1 -0
  100. package/dist/tools/model_tool.js +71 -0
  101. package/dist/tools/model_tool.js.map +1 -0
  102. package/dist/tools/todo.d.ts +30 -0
  103. package/dist/tools/todo.d.ts.map +1 -0
  104. package/dist/tools/todo.js +78 -0
  105. package/dist/tools/todo.js.map +1 -0
  106. package/docs/AESTHETIC_DESIGN.md +152 -144
  107. package/docs/OPTIMIZATION_PLAN.md +178 -178
  108. package/package.json +68 -68
  109. package/scripts/install.js +48 -48
  110. package/scripts/link.js +10 -10
  111. package/setup.bat +79 -79
  112. package/skill-test-ty2fOA/test.md +10 -10
  113. package/src/agents/dew.ts +70 -70
  114. package/src/agents/fair.ts +102 -102
  115. package/src/agents/fog.ts +48 -48
  116. package/src/agents/frost.ts +50 -50
  117. package/src/agents/rain.ts +50 -50
  118. package/src/agents/snow.ts +239 -239
  119. package/src/cli/commands_md.ts +112 -0
  120. package/src/cli/input_macros.ts +83 -0
  121. package/src/cli/loom.ts +982 -0
  122. package/src/cli/loom_chat.ts +598 -0
  123. package/src/cli/main.ts +255 -9
  124. package/src/cli/mode.ts +58 -58
  125. package/src/cli/tui.ts +228 -222
  126. package/src/core/agent/guard.ts +134 -134
  127. package/src/core/agent/task.ts +100 -100
  128. package/src/core/agent.ts +195 -16
  129. package/src/core/arbitrate.ts +162 -162
  130. package/src/core/catalog.ts +178 -178
  131. package/src/core/checkpoint.ts +94 -94
  132. package/src/core/estimate.ts +104 -104
  133. package/src/core/evolve.ts +191 -191
  134. package/src/core/factory.ts +31 -2
  135. package/src/core/file_checkpoint.ts +136 -0
  136. package/src/core/filter.ts +103 -103
  137. package/src/core/graph.ts +156 -156
  138. package/src/core/hooks.ts +126 -0
  139. package/src/core/icons.ts +53 -53
  140. package/src/core/index.ts +37 -37
  141. package/src/core/learn.ts +146 -146
  142. package/src/core/llm.ts +15 -9
  143. package/src/core/longdoc.ts +155 -155
  144. package/src/core/mcp.ts +48 -0
  145. package/src/core/mcp_server.ts +176 -176
  146. package/src/core/model_config.ts +157 -0
  147. package/src/core/profile.ts +255 -255
  148. package/src/core/router.ts +124 -124
  149. package/src/core/sandbox.ts +142 -142
  150. package/src/core/security.ts +243 -243
  151. package/src/core/skill.ts +42 -0
  152. package/src/core/skymd.ts +143 -0
  153. package/src/core/theme.ts +65 -65
  154. package/src/core/tool.ts +30 -0
  155. package/src/core/tool_router.ts +193 -193
  156. package/src/core/vector.ts +152 -152
  157. package/src/core/verify.ts +71 -0
  158. package/src/core/workspace.ts +150 -150
  159. package/src/plugins/loader.ts +66 -66
  160. package/src/skills/loader.ts +45 -16
  161. package/src/sql.js.d.ts +29 -29
  162. package/src/tools/builtin.ts +13 -3
  163. package/src/tools/computer.ts +269 -269
  164. package/src/tools/delegate.ts +49 -49
  165. package/src/tools/model_tool.ts +74 -0
  166. package/src/tools/todo.ts +76 -0
  167. package/src/web/tts.ts +93 -93
  168. package/tests/agent.test.ts +159 -159
  169. package/tests/agent_helpers.test.ts +48 -48
  170. package/tests/bus.test.ts +121 -121
  171. package/tests/catalog.test.ts +86 -86
  172. package/tests/checkpoint_commands.test.ts +124 -0
  173. package/tests/claude_compat.test.ts +110 -0
  174. package/tests/config.test.ts +41 -41
  175. package/tests/guard.test.ts +75 -75
  176. package/tests/icons.test.ts +45 -45
  177. package/tests/loom.test.ts +248 -0
  178. package/tests/memory.test.ts +170 -170
  179. package/tests/model_config.test.ts +109 -0
  180. package/tests/router.test.ts +86 -86
  181. package/tests/schemas.test.ts +51 -51
  182. package/tests/semantic.test.ts +83 -83
  183. package/tests/setup.ts +10 -10
  184. package/tests/skill.test.ts +172 -172
  185. package/tests/skymd.test.ts +146 -0
  186. package/tests/task.test.ts +60 -60
  187. package/tests/todo_toolstats.test.ts +94 -0
  188. package/tests/tool.test.ts +108 -108
  189. package/tests/tool_router.test.ts +71 -71
  190. package/tests/tui.test.ts +67 -67
  191. package/vitest.config.ts +17 -17
  192. package/=12 +0 -0
  193. package/=8 +0 -0
@@ -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
  }