@zhijiewang/openharness 0.5.1 → 0.6.0

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 (185) hide show
  1. package/dist/commands/cybergotchi.d.ts.map +1 -1
  2. package/dist/commands/cybergotchi.js +22 -19
  3. package/dist/commands/cybergotchi.js.map +1 -1
  4. package/dist/components/App.d.ts +1 -1
  5. package/dist/components/App.d.ts.map +1 -1
  6. package/dist/components/App.js +58 -2
  7. package/dist/components/App.js.map +1 -1
  8. package/dist/components/CompanionFooter.d.ts +9 -0
  9. package/dist/components/CompanionFooter.d.ts.map +1 -0
  10. package/dist/components/CompanionFooter.js +13 -0
  11. package/dist/components/CompanionFooter.js.map +1 -0
  12. package/dist/components/CybergotchiBubble.d.ts +2 -1
  13. package/dist/components/CybergotchiBubble.d.ts.map +1 -1
  14. package/dist/components/CybergotchiBubble.js +4 -5
  15. package/dist/components/CybergotchiBubble.js.map +1 -1
  16. package/dist/components/CybergotchiPanel.d.ts +5 -4
  17. package/dist/components/CybergotchiPanel.d.ts.map +1 -1
  18. package/dist/components/CybergotchiPanel.js +4 -2
  19. package/dist/components/CybergotchiPanel.js.map +1 -1
  20. package/dist/components/CybergotchiPanelConnected.js +4 -4
  21. package/dist/components/CybergotchiPanelConnected.js.map +1 -1
  22. package/dist/components/CybergotchiSetup.d.ts.map +1 -1
  23. package/dist/components/CybergotchiSetup.js +25 -61
  24. package/dist/components/CybergotchiSetup.js.map +1 -1
  25. package/dist/components/CybergotchiSprite.d.ts +5 -4
  26. package/dist/components/CybergotchiSprite.d.ts.map +1 -1
  27. package/dist/components/CybergotchiSprite.js +16 -9
  28. package/dist/components/CybergotchiSprite.js.map +1 -1
  29. package/dist/components/DiffView.d.ts +27 -0
  30. package/dist/components/DiffView.d.ts.map +1 -0
  31. package/dist/components/DiffView.js +74 -0
  32. package/dist/components/DiffView.js.map +1 -0
  33. package/dist/components/Messages.js +1 -1
  34. package/dist/components/Messages.js.map +1 -1
  35. package/dist/components/PermissionPrompt.d.ts.map +1 -1
  36. package/dist/components/PermissionPrompt.js +61 -8
  37. package/dist/components/PermissionPrompt.js.map +1 -1
  38. package/dist/components/REPL.d.ts.map +1 -1
  39. package/dist/components/REPL.js +75 -21
  40. package/dist/components/REPL.js.map +1 -1
  41. package/dist/components/TextInput.d.ts +2 -1
  42. package/dist/components/TextInput.d.ts.map +1 -1
  43. package/dist/components/TextInput.js +110 -6
  44. package/dist/components/TextInput.js.map +1 -1
  45. package/dist/cybergotchi/bones.d.ts +12 -0
  46. package/dist/cybergotchi/bones.d.ts.map +1 -0
  47. package/dist/cybergotchi/bones.js +89 -0
  48. package/dist/cybergotchi/bones.js.map +1 -0
  49. package/dist/cybergotchi/config.d.ts +14 -4
  50. package/dist/cybergotchi/config.d.ts.map +1 -1
  51. package/dist/cybergotchi/config.js +62 -9
  52. package/dist/cybergotchi/config.js.map +1 -1
  53. package/dist/cybergotchi/needs.d.ts +4 -4
  54. package/dist/cybergotchi/needs.d.ts.map +1 -1
  55. package/dist/cybergotchi/needs.js.map +1 -1
  56. package/dist/cybergotchi/personality.d.ts +11 -0
  57. package/dist/cybergotchi/personality.d.ts.map +1 -0
  58. package/dist/cybergotchi/personality.js +26 -0
  59. package/dist/cybergotchi/personality.js.map +1 -0
  60. package/dist/cybergotchi/species.d.ts +0 -1
  61. package/dist/cybergotchi/species.d.ts.map +1 -1
  62. package/dist/cybergotchi/species.js +253 -229
  63. package/dist/cybergotchi/species.js.map +1 -1
  64. package/dist/cybergotchi/types.d.ts +45 -7
  65. package/dist/cybergotchi/types.d.ts.map +1 -1
  66. package/dist/cybergotchi/types.js +36 -5
  67. package/dist/cybergotchi/types.js.map +1 -1
  68. package/dist/cybergotchi/useCybergotchi.d.ts +7 -5
  69. package/dist/cybergotchi/useCybergotchi.d.ts.map +1 -1
  70. package/dist/cybergotchi/useCybergotchi.js +27 -16
  71. package/dist/cybergotchi/useCybergotchi.js.map +1 -1
  72. package/dist/git/index.d.ts +9 -0
  73. package/dist/git/index.d.ts.map +1 -1
  74. package/dist/git/index.js +31 -0
  75. package/dist/git/index.js.map +1 -1
  76. package/dist/harness/config.d.ts +5 -0
  77. package/dist/harness/config.d.ts.map +1 -1
  78. package/dist/harness/config.js.map +1 -1
  79. package/dist/harness/credentials.d.ts +24 -0
  80. package/dist/harness/credentials.d.ts.map +1 -0
  81. package/dist/harness/credentials.js +104 -0
  82. package/dist/harness/credentials.js.map +1 -0
  83. package/dist/harness/hooks.d.ts +8 -0
  84. package/dist/harness/hooks.d.ts.map +1 -1
  85. package/dist/harness/hooks.js +98 -22
  86. package/dist/harness/hooks.js.map +1 -1
  87. package/dist/harness/keybindings.d.ts +37 -0
  88. package/dist/harness/keybindings.d.ts.map +1 -0
  89. package/dist/harness/keybindings.js +134 -0
  90. package/dist/harness/keybindings.js.map +1 -0
  91. package/dist/harness/memory.d.ts +35 -0
  92. package/dist/harness/memory.d.ts.map +1 -0
  93. package/dist/harness/memory.js +115 -0
  94. package/dist/harness/memory.js.map +1 -0
  95. package/dist/harness/plugins.d.ts +57 -0
  96. package/dist/harness/plugins.d.ts.map +1 -0
  97. package/dist/harness/plugins.js +142 -0
  98. package/dist/harness/plugins.js.map +1 -0
  99. package/dist/harness/session.d.ts +5 -0
  100. package/dist/harness/session.d.ts.map +1 -1
  101. package/dist/harness/session.js +39 -1
  102. package/dist/harness/session.js.map +1 -1
  103. package/dist/lsp/client.d.ts +58 -0
  104. package/dist/lsp/client.d.ts.map +1 -0
  105. package/dist/lsp/client.js +174 -0
  106. package/dist/lsp/client.js.map +1 -0
  107. package/dist/main.js +160 -0
  108. package/dist/main.js.map +1 -1
  109. package/dist/mcp/DeferredMcpTool.d.ts +30 -0
  110. package/dist/mcp/DeferredMcpTool.d.ts.map +1 -0
  111. package/dist/mcp/DeferredMcpTool.js +75 -0
  112. package/dist/mcp/DeferredMcpTool.js.map +1 -0
  113. package/dist/mcp/client.d.ts +7 -0
  114. package/dist/mcp/client.d.ts.map +1 -1
  115. package/dist/mcp/client.js +56 -8
  116. package/dist/mcp/client.js.map +1 -1
  117. package/dist/mcp/loader.d.ts +9 -0
  118. package/dist/mcp/loader.d.ts.map +1 -1
  119. package/dist/mcp/loader.js +43 -2
  120. package/dist/mcp/loader.js.map +1 -1
  121. package/dist/mcp/schema.d.ts +7 -0
  122. package/dist/mcp/schema.d.ts.map +1 -0
  123. package/dist/mcp/schema.js +41 -0
  124. package/dist/mcp/schema.js.map +1 -0
  125. package/dist/mcp/server.d.ts +16 -0
  126. package/dist/mcp/server.d.ts.map +1 -0
  127. package/dist/mcp/server.js +94 -0
  128. package/dist/mcp/server.js.map +1 -0
  129. package/dist/providers/anthropic.d.ts +1 -1
  130. package/dist/providers/anthropic.d.ts.map +1 -1
  131. package/dist/providers/anthropic.js.map +1 -1
  132. package/dist/providers/base.d.ts +15 -0
  133. package/dist/providers/base.d.ts.map +1 -1
  134. package/dist/providers/base.js +13 -1
  135. package/dist/providers/base.js.map +1 -1
  136. package/dist/providers/openai.d.ts +1 -1
  137. package/dist/providers/openai.d.ts.map +1 -1
  138. package/dist/providers/openai.js.map +1 -1
  139. package/dist/query.d.ts.map +1 -1
  140. package/dist/query.js +91 -14
  141. package/dist/query.js.map +1 -1
  142. package/dist/remote/server.d.ts +31 -0
  143. package/dist/remote/server.d.ts.map +1 -0
  144. package/dist/remote/server.js +163 -0
  145. package/dist/remote/server.js.map +1 -0
  146. package/dist/services/AgentDispatcher.d.ts +42 -0
  147. package/dist/services/AgentDispatcher.d.ts.map +1 -0
  148. package/dist/services/AgentDispatcher.js +181 -0
  149. package/dist/services/AgentDispatcher.js.map +1 -0
  150. package/dist/services/StreamingToolExecutor.d.ts +2 -1
  151. package/dist/services/StreamingToolExecutor.d.ts.map +1 -1
  152. package/dist/services/StreamingToolExecutor.js +11 -2
  153. package/dist/services/StreamingToolExecutor.js.map +1 -1
  154. package/dist/tools/AgentTool/index.d.ts +3 -0
  155. package/dist/tools/AgentTool/index.d.ts.map +1 -1
  156. package/dist/tools/AgentTool/index.js +54 -16
  157. package/dist/tools/AgentTool/index.js.map +1 -1
  158. package/dist/tools/DiagnosticsTool/index.d.ts +21 -0
  159. package/dist/tools/DiagnosticsTool/index.d.ts.map +1 -0
  160. package/dist/tools/DiagnosticsTool/index.js +108 -0
  161. package/dist/tools/DiagnosticsTool/index.js.map +1 -0
  162. package/dist/tools/GrepTool/index.d.ts +2 -2
  163. package/dist/tools/ParallelAgentTool/index.d.ts +37 -0
  164. package/dist/tools/ParallelAgentTool/index.d.ts.map +1 -0
  165. package/dist/tools/ParallelAgentTool/index.js +53 -0
  166. package/dist/tools/ParallelAgentTool/index.js.map +1 -0
  167. package/dist/tools/SkillTool/index.d.ts.map +1 -1
  168. package/dist/tools/SkillTool/index.js +22 -27
  169. package/dist/tools/SkillTool/index.js.map +1 -1
  170. package/dist/tools/ToolSearchTool/index.d.ts +15 -0
  171. package/dist/tools/ToolSearchTool/index.d.ts.map +1 -0
  172. package/dist/tools/ToolSearchTool/index.js +50 -0
  173. package/dist/tools/ToolSearchTool/index.js.map +1 -0
  174. package/dist/tools.d.ts.map +1 -1
  175. package/dist/tools.js +9 -0
  176. package/dist/tools.js.map +1 -1
  177. package/dist/types/message.d.ts +2 -0
  178. package/dist/types/message.d.ts.map +1 -1
  179. package/dist/types/message.js +3 -0
  180. package/dist/types/message.js.map +1 -1
  181. package/dist/types/permissions.d.ts +2 -0
  182. package/dist/types/permissions.d.ts.map +1 -1
  183. package/dist/types/permissions.js +30 -0
  184. package/dist/types/permissions.js.map +1 -1
  185. package/package.json +1 -1
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Plugin system — discover and load skills, plugins, and agent teams.
3
+ *
4
+ * Skills: Markdown files with YAML frontmatter defining trigger conditions and tool whitelists.
5
+ * Plugins: Bundles of skills + hooks + MCP server configs.
6
+ * Agent Teams: Named agent configurations for specific roles.
7
+ *
8
+ * Search order for skills:
9
+ * 1. .oh/skills/ (project-level)
10
+ * 2. ~/.oh/skills/ (global)
11
+ * 3. node_modules packages with "openharness-plugin" keyword
12
+ */
13
+ export type SkillMetadata = {
14
+ name: string;
15
+ description: string;
16
+ trigger: string | undefined;
17
+ tools: string[] | undefined;
18
+ args: string[] | undefined;
19
+ content: string;
20
+ filePath: string;
21
+ source: 'project' | 'global' | 'plugin';
22
+ };
23
+ export type PluginManifest = {
24
+ name: string;
25
+ version: string;
26
+ description?: string;
27
+ skills?: string[];
28
+ hooks?: Record<string, string>;
29
+ mcpServers?: Array<{
30
+ name: string;
31
+ command: string;
32
+ args?: string[];
33
+ }>;
34
+ agentTeams?: AgentTeamConfig[];
35
+ };
36
+ export type AgentTeamConfig = {
37
+ name: string;
38
+ description: string;
39
+ roles: Array<{
40
+ name: string;
41
+ systemPrompt: string;
42
+ tools?: string[];
43
+ }>;
44
+ };
45
+ /** Discover all available skills from project + global dirs */
46
+ export declare function discoverSkills(): SkillMetadata[];
47
+ /** Find a skill by name (case-insensitive) */
48
+ export declare function findSkill(name: string): SkillMetadata | null;
49
+ /** Find skills that match a trigger condition */
50
+ export declare function findTriggeredSkills(userMessage: string): SkillMetadata[];
51
+ /** Load a plugin manifest from a directory */
52
+ export declare function loadPluginManifest(dir: string): PluginManifest | null;
53
+ /** Discover plugins from node_modules */
54
+ export declare function discoverPlugins(): PluginManifest[];
55
+ /** Build a prompt listing available skills for the LLM */
56
+ export declare function skillsToPrompt(skills: SkillMetadata[]): string;
57
+ //# sourceMappingURL=plugins.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugins.d.ts","sourceRoot":"","sources":["../../src/harness/plugins.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAMH,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,KAAK,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC5B,IAAI,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAC;CACzC,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,UAAU,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;IACvE,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,KAAK,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,YAAY,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;KAClB,CAAC,CAAC;CACJ,CAAC;AA2DF,+DAA+D;AAC/D,wBAAgB,cAAc,IAAI,aAAa,EAAE,CAKhD;AAED,8CAA8C;AAC9C,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAG5D;AAED,iDAAiD;AACjD,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,EAAE,CAMxE;AAED,8CAA8C;AAC9C,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAQrE;AAED,yCAAyC;AACzC,wBAAgB,eAAe,IAAI,cAAc,EAAE,CA4BlD;AAED,0DAA0D;AAC1D,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,CAM9D"}
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Plugin system — discover and load skills, plugins, and agent teams.
3
+ *
4
+ * Skills: Markdown files with YAML frontmatter defining trigger conditions and tool whitelists.
5
+ * Plugins: Bundles of skills + hooks + MCP server configs.
6
+ * Agent Teams: Named agent configurations for specific roles.
7
+ *
8
+ * Search order for skills:
9
+ * 1. .oh/skills/ (project-level)
10
+ * 2. ~/.oh/skills/ (global)
11
+ * 3. node_modules packages with "openharness-plugin" keyword
12
+ */
13
+ import { readFileSync, readdirSync, existsSync } from 'node:fs';
14
+ import { join, basename } from 'node:path';
15
+ import { homedir } from 'node:os';
16
+ const PROJECT_SKILLS_DIR = join('.oh', 'skills');
17
+ const GLOBAL_SKILLS_DIR = join(homedir(), '.oh', 'skills');
18
+ /** Parse YAML frontmatter from a skill markdown file */
19
+ function parseSkillFrontmatter(content) {
20
+ const match = content.match(/^---\n([\s\S]*?)\n---/);
21
+ if (!match)
22
+ return {};
23
+ const frontmatter = match[1];
24
+ const result = {};
25
+ const nameMatch = frontmatter.match(/^name:\s*(.+)$/m);
26
+ if (nameMatch)
27
+ result.name = nameMatch[1].trim();
28
+ const descMatch = frontmatter.match(/^description:\s*(.+)$/m);
29
+ if (descMatch)
30
+ result.description = descMatch[1].trim();
31
+ const triggerMatch = frontmatter.match(/^trigger:\s*(.+)$/m);
32
+ if (triggerMatch)
33
+ result.trigger = triggerMatch[1].trim();
34
+ const toolsMatch = frontmatter.match(/^tools:\s*\[(.+)\]$/m);
35
+ if (toolsMatch)
36
+ result.tools = toolsMatch[1].split(',').map(t => t.trim());
37
+ const argsMatch = frontmatter.match(/^args:\s*\[(.+)\]$/m);
38
+ if (argsMatch)
39
+ result.args = argsMatch[1].split(',').map(a => a.trim());
40
+ return result;
41
+ }
42
+ /** Load skills from a directory */
43
+ function loadSkillsFromDir(dir, source) {
44
+ if (!existsSync(dir))
45
+ return [];
46
+ return readdirSync(dir)
47
+ .filter(f => f.endsWith('.md'))
48
+ .map(f => {
49
+ const filePath = join(dir, f);
50
+ try {
51
+ const content = readFileSync(filePath, 'utf-8');
52
+ const meta = parseSkillFrontmatter(content);
53
+ return {
54
+ name: meta.name || basename(f, '.md'),
55
+ description: meta.description || '',
56
+ trigger: meta.trigger,
57
+ tools: meta.tools,
58
+ args: meta.args,
59
+ content,
60
+ filePath,
61
+ source,
62
+ };
63
+ }
64
+ catch {
65
+ return null;
66
+ }
67
+ })
68
+ .filter((s) => s !== null);
69
+ }
70
+ /** Discover all available skills from project + global dirs */
71
+ export function discoverSkills() {
72
+ const skills = [];
73
+ skills.push(...loadSkillsFromDir(PROJECT_SKILLS_DIR, 'project'));
74
+ skills.push(...loadSkillsFromDir(GLOBAL_SKILLS_DIR, 'global'));
75
+ return skills;
76
+ }
77
+ /** Find a skill by name (case-insensitive) */
78
+ export function findSkill(name) {
79
+ const skills = discoverSkills();
80
+ return skills.find(s => s.name.toLowerCase() === name.toLowerCase()) ?? null;
81
+ }
82
+ /** Find skills that match a trigger condition */
83
+ export function findTriggeredSkills(userMessage) {
84
+ const skills = discoverSkills();
85
+ return skills.filter(s => {
86
+ if (!s.trigger)
87
+ return false;
88
+ return userMessage.toLowerCase().includes(s.trigger.toLowerCase());
89
+ });
90
+ }
91
+ /** Load a plugin manifest from a directory */
92
+ export function loadPluginManifest(dir) {
93
+ const manifestPath = join(dir, 'openharness-plugin.json');
94
+ if (!existsSync(manifestPath))
95
+ return null;
96
+ try {
97
+ return JSON.parse(readFileSync(manifestPath, 'utf-8'));
98
+ }
99
+ catch {
100
+ return null;
101
+ }
102
+ }
103
+ /** Discover plugins from node_modules */
104
+ export function discoverPlugins() {
105
+ const plugins = [];
106
+ // Check node_modules for packages with openharness-plugin.json
107
+ const nodeModules = join('.', 'node_modules');
108
+ if (!existsSync(nodeModules))
109
+ return plugins;
110
+ try {
111
+ for (const pkg of readdirSync(nodeModules)) {
112
+ if (pkg.startsWith('.'))
113
+ continue;
114
+ const pkgDir = join(nodeModules, pkg);
115
+ const manifest = loadPluginManifest(pkgDir);
116
+ if (manifest)
117
+ plugins.push(manifest);
118
+ // Scoped packages
119
+ if (pkg.startsWith('@')) {
120
+ try {
121
+ for (const sub of readdirSync(pkgDir)) {
122
+ const subDir = join(pkgDir, sub);
123
+ const subManifest = loadPluginManifest(subDir);
124
+ if (subManifest)
125
+ plugins.push(subManifest);
126
+ }
127
+ }
128
+ catch { /* ignore */ }
129
+ }
130
+ }
131
+ }
132
+ catch { /* ignore */ }
133
+ return plugins;
134
+ }
135
+ /** Build a prompt listing available skills for the LLM */
136
+ export function skillsToPrompt(skills) {
137
+ if (skills.length === 0)
138
+ return '';
139
+ const lines = skills.map(s => `- ${s.name}: ${s.description}${s.trigger ? ` (auto-trigger: "${s.trigger}")` : ''}`);
140
+ return `# Available Skills\nUse the Skill tool to invoke these:\n${lines.join('\n')}`;
141
+ }
142
+ //# sourceMappingURL=plugins.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugins.js","sourceRoot":"","sources":["../../src/harness/plugins.ts"],"names":[],"mappings":"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"}
@@ -23,4 +23,9 @@ export declare function listSessions(dir?: string): Array<{
23
23
  }>;
24
24
  /** Returns the ID of the most recently updated session, or null if none exist. */
25
25
  export declare function getLastSessionId(dir?: string): string | null;
26
+ /**
27
+ * Evict oldest sessions when count exceeds MAX_SESSIONS.
28
+ * Called automatically by saveSession.
29
+ */
30
+ export declare function evictOldSessions(dir?: string, maxSessions?: number): number;
26
31
  //# sourceMappingURL=session.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/harness/session.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAInD,MAAM,MAAM,OAAO,GAAG;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAUtE;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAOlE;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAI7D;AAED,wBAAgB,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAChD,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC,CAsBD;AAED,kFAAkF;AAClF,wBAAgB,gBAAgB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG5D"}
1
+ {"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/harness/session.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAInD,MAAM,MAAM,OAAO,GAAG;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAUtE;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CASlE;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAI7D;AAED,wBAAgB,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAChD,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC,CAsBD;AAED,kFAAkF;AAClF,wBAAgB,gBAAgB,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG5D;AAKD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,WAAW,SAAe,GAAG,MAAM,CAuBjF"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Session persistence — save and resume conversations.
3
3
  */
4
- import { readFileSync, writeFileSync, mkdirSync, readdirSync, existsSync } from "node:fs";
4
+ import { readFileSync, writeFileSync, mkdirSync, readdirSync, existsSync, unlinkSync } from "node:fs";
5
5
  import { join } from "node:path";
6
6
  import { homedir } from "node:os";
7
7
  import { randomUUID } from "node:crypto";
@@ -23,6 +23,11 @@ export function saveSession(session, dir) {
23
23
  const path = join(sessionDir, `${session.id}.json`);
24
24
  session.updatedAt = Date.now();
25
25
  writeFileSync(path, JSON.stringify(session, null, 2));
26
+ // Evict old sessions in the background (non-blocking)
27
+ try {
28
+ evictOldSessions(sessionDir);
29
+ }
30
+ catch { /* ignore */ }
26
31
  return path;
27
32
  }
28
33
  export function loadSession(id, dir) {
@@ -59,4 +64,37 @@ export function getLastSessionId(dir) {
59
64
  const sessions = listSessions(dir);
60
65
  return sessions.length > 0 ? sessions[0].id : null;
61
66
  }
67
+ /** Maximum number of sessions to keep on disk. */
68
+ const MAX_SESSIONS = 100;
69
+ /**
70
+ * Evict oldest sessions when count exceeds MAX_SESSIONS.
71
+ * Called automatically by saveSession.
72
+ */
73
+ export function evictOldSessions(dir, maxSessions = MAX_SESSIONS) {
74
+ const sessionDir = dir ?? DEFAULT_SESSION_DIR;
75
+ if (!existsSync(sessionDir))
76
+ return 0;
77
+ const files = readdirSync(sessionDir).filter((f) => f.endsWith(".json"));
78
+ if (files.length <= maxSessions)
79
+ return 0;
80
+ // Sort by modification time (oldest first)
81
+ const withStats = files.map((f) => {
82
+ const path = join(sessionDir, f);
83
+ try {
84
+ const data = JSON.parse(readFileSync(path, "utf-8"));
85
+ return { path, updatedAt: data.updatedAt ?? 0 };
86
+ }
87
+ catch {
88
+ return { path, updatedAt: 0 };
89
+ }
90
+ }).sort((a, b) => a.updatedAt - b.updatedAt);
91
+ const toRemove = withStats.slice(0, files.length - maxSessions);
92
+ for (const { path } of toRemove) {
93
+ try {
94
+ unlinkSync(path);
95
+ }
96
+ catch { /* ignore */ }
97
+ }
98
+ return toRemove.length;
99
+ }
62
100
  //# sourceMappingURL=session.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/harness/session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/harness/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Lightweight LSP client — connects to a language server subprocess
3
+ * and provides diagnostics, go-to-definition, and find-references.
4
+ */
5
+ type Diagnostic = {
6
+ range: {
7
+ start: {
8
+ line: number;
9
+ character: number;
10
+ };
11
+ end: {
12
+ line: number;
13
+ character: number;
14
+ };
15
+ };
16
+ severity?: number;
17
+ message: string;
18
+ source?: string;
19
+ };
20
+ type Location = {
21
+ uri: string;
22
+ range: {
23
+ start: {
24
+ line: number;
25
+ character: number;
26
+ };
27
+ end: {
28
+ line: number;
29
+ character: number;
30
+ };
31
+ };
32
+ };
33
+ export declare class LspClient {
34
+ private proc;
35
+ private nextId;
36
+ private pending;
37
+ private buffer;
38
+ private contentLength;
39
+ private diagnostics;
40
+ private ready;
41
+ private constructor();
42
+ private parseMessages;
43
+ private handleMessage;
44
+ private send;
45
+ static connect(command: string, args: string[], rootPath: string): Promise<LspClient>;
46
+ /** Get diagnostics for a file (must be opened first) */
47
+ openFile(filePath: string): Promise<void>;
48
+ /** Get cached diagnostics for a file */
49
+ getDiagnostics(filePath: string): Diagnostic[];
50
+ /** Go to definition */
51
+ getDefinition(filePath: string, line: number, character: number): Promise<Location[]>;
52
+ /** Find references */
53
+ getReferences(filePath: string, line: number, character: number): Promise<Location[]>;
54
+ private guessLanguage;
55
+ disconnect(): void;
56
+ }
57
+ export {};
58
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/lsp/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAeH,KAAK,UAAU,GAAG;IAChB,KAAK,EAAE;QAAE,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,GAAG,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;IAChG,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,KAAK,QAAQ,GAAG;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE;QAAE,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,GAAG,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;CACjG,CAAC;AAEF,qBAAa,SAAS;IACpB,OAAO,CAAC,IAAI,CAAe;IAC3B,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,OAAO,CAAgF;IAC/F,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,aAAa,CAAM;IAC3B,OAAO,CAAC,WAAW,CAAmC;IACtD,OAAO,CAAC,KAAK,CAAS;IAEtB,OAAO;IAiBP,OAAO,CAAC,aAAa;IAyBrB,OAAO,CAAC,aAAa;IAoBrB,OAAO,CAAC,IAAI;WAmBC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC;IAyB3F,wDAAwD;IAClD,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAU/C,wCAAwC;IACxC,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,EAAE;IAK9C,uBAAuB;IACjB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAU3F,sBAAsB;IAChB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAU3F,OAAO,CAAC,aAAa;IAUrB,UAAU,IAAI,IAAI;CAQnB"}
@@ -0,0 +1,174 @@
1
+ /**
2
+ * Lightweight LSP client — connects to a language server subprocess
3
+ * and provides diagnostics, go-to-definition, and find-references.
4
+ */
5
+ import { spawn } from 'node:child_process';
6
+ import { readFileSync } from 'node:fs';
7
+ export class LspClient {
8
+ proc;
9
+ nextId = 1;
10
+ pending = new Map();
11
+ buffer = '';
12
+ contentLength = -1;
13
+ diagnostics = new Map();
14
+ ready = false;
15
+ constructor(proc) {
16
+ this.proc = proc;
17
+ // Parse LSP messages from stdout (Content-Length framed)
18
+ proc.stdout.on('data', (data) => {
19
+ this.buffer += data.toString();
20
+ this.parseMessages();
21
+ });
22
+ proc.on('exit', () => {
23
+ for (const p of this.pending.values()) {
24
+ p.reject(new Error('LSP server exited'));
25
+ }
26
+ this.pending.clear();
27
+ });
28
+ }
29
+ parseMessages() {
30
+ while (true) {
31
+ if (this.contentLength === -1) {
32
+ const headerEnd = this.buffer.indexOf('\r\n\r\n');
33
+ if (headerEnd === -1)
34
+ break;
35
+ const header = this.buffer.slice(0, headerEnd);
36
+ const match = header.match(/Content-Length:\s*(\d+)/i);
37
+ if (!match) {
38
+ this.buffer = this.buffer.slice(headerEnd + 4);
39
+ continue;
40
+ }
41
+ this.contentLength = parseInt(match[1]);
42
+ this.buffer = this.buffer.slice(headerEnd + 4);
43
+ }
44
+ if (this.buffer.length < this.contentLength)
45
+ break;
46
+ const body = this.buffer.slice(0, this.contentLength);
47
+ this.buffer = this.buffer.slice(this.contentLength);
48
+ this.contentLength = -1;
49
+ try {
50
+ const msg = JSON.parse(body);
51
+ this.handleMessage(msg);
52
+ }
53
+ catch { /* ignore parse errors */ }
54
+ }
55
+ }
56
+ handleMessage(msg) {
57
+ // Response to a request
58
+ if (msg.id !== undefined && this.pending.has(msg.id)) {
59
+ const p = this.pending.get(msg.id);
60
+ this.pending.delete(msg.id);
61
+ if (msg.error) {
62
+ p.reject(new Error(msg.error.message));
63
+ }
64
+ else {
65
+ p.resolve(msg.result);
66
+ }
67
+ return;
68
+ }
69
+ // Server notification
70
+ if (msg.method === 'textDocument/publishDiagnostics') {
71
+ const params = msg.params;
72
+ this.diagnostics.set(params.uri, params.diagnostics);
73
+ }
74
+ }
75
+ send(method, params, isNotification = false) {
76
+ const id = isNotification ? undefined : this.nextId++;
77
+ const msg = { jsonrpc: '2.0', id, method, params };
78
+ const body = JSON.stringify(msg);
79
+ const header = `Content-Length: ${Buffer.byteLength(body)}\r\n\r\n`;
80
+ this.proc.stdin.write(header + body);
81
+ if (isNotification)
82
+ return Promise.resolve();
83
+ return new Promise((resolve, reject) => {
84
+ this.pending.set(id, { resolve, reject });
85
+ setTimeout(() => {
86
+ if (this.pending.has(id)) {
87
+ this.pending.delete(id);
88
+ reject(new Error('LSP request timeout'));
89
+ }
90
+ }, 10_000);
91
+ });
92
+ }
93
+ static async connect(command, args, rootPath) {
94
+ const proc = spawn(command, args, {
95
+ stdio: ['pipe', 'pipe', 'pipe'],
96
+ });
97
+ const client = new LspClient(proc);
98
+ // Initialize
99
+ await client.send('initialize', {
100
+ processId: process.pid,
101
+ rootUri: `file://${rootPath.replace(/\\/g, '/')}`,
102
+ capabilities: {
103
+ textDocument: {
104
+ publishDiagnostics: { relatedInformation: true },
105
+ definition: { dynamicRegistration: false },
106
+ references: { dynamicRegistration: false },
107
+ },
108
+ },
109
+ });
110
+ client.send('initialized', {}, true);
111
+ client.ready = true;
112
+ return client;
113
+ }
114
+ /** Get diagnostics for a file (must be opened first) */
115
+ async openFile(filePath) {
116
+ const uri = `file://${filePath.replace(/\\/g, '/')}`;
117
+ const content = readFileSync(filePath, 'utf-8');
118
+ await this.send('textDocument/didOpen', {
119
+ textDocument: { uri, languageId: this.guessLanguage(filePath), version: 1, text: content },
120
+ }, true);
121
+ // Wait briefly for diagnostics to arrive
122
+ await new Promise(r => setTimeout(r, 1000));
123
+ }
124
+ /** Get cached diagnostics for a file */
125
+ getDiagnostics(filePath) {
126
+ const uri = `file://${filePath.replace(/\\/g, '/')}`;
127
+ return this.diagnostics.get(uri) ?? [];
128
+ }
129
+ /** Go to definition */
130
+ async getDefinition(filePath, line, character) {
131
+ const uri = `file://${filePath.replace(/\\/g, '/')}`;
132
+ const result = await this.send('textDocument/definition', {
133
+ textDocument: { uri },
134
+ position: { line, character },
135
+ });
136
+ if (!result)
137
+ return [];
138
+ return Array.isArray(result) ? result : [result];
139
+ }
140
+ /** Find references */
141
+ async getReferences(filePath, line, character) {
142
+ const uri = `file://${filePath.replace(/\\/g, '/')}`;
143
+ const result = await this.send('textDocument/references', {
144
+ textDocument: { uri },
145
+ position: { line, character },
146
+ context: { includeDeclaration: true },
147
+ });
148
+ return result ?? [];
149
+ }
150
+ guessLanguage(path) {
151
+ if (path.endsWith('.ts') || path.endsWith('.tsx'))
152
+ return 'typescript';
153
+ if (path.endsWith('.js') || path.endsWith('.jsx'))
154
+ return 'javascript';
155
+ if (path.endsWith('.py'))
156
+ return 'python';
157
+ if (path.endsWith('.rs'))
158
+ return 'rust';
159
+ if (path.endsWith('.go'))
160
+ return 'go';
161
+ if (path.endsWith('.java'))
162
+ return 'java';
163
+ return 'plaintext';
164
+ }
165
+ disconnect() {
166
+ this.send('shutdown', {}).then(() => {
167
+ this.send('exit', null, true);
168
+ this.proc.kill();
169
+ }).catch(() => {
170
+ this.proc.kill();
171
+ });
172
+ }
173
+ }
174
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/lsp/client.ts"],"names":[],"mappings":"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"}