thatgfsj-code 0.2.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.
- package/.patches/0001-fix-repl-replace-readline-with-inquirer-input-for-ke.patch +279 -0
- package/.patches/0002-fix-repl-stream-AI-output-directly-to-stdout-so-term.patch +564 -0
- package/.patches/0003-fix-session-break-the-hallucination-loop-in-assistan.patch +194 -0
- package/.patches/0004-chore-release-bump-version-to-0.2.1.patch +24 -0
- package/LICENSE +21 -0
- package/README.md +100 -0
- package/ROADMAP.md +107 -0
- package/dist/agent/core.d.ts +56 -0
- package/dist/agent/core.d.ts.map +1 -0
- package/dist/agent/core.js +142 -0
- package/dist/agent/core.js.map +1 -0
- package/dist/agent/index.d.ts +8 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +8 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/intent.d.ts +36 -0
- package/dist/agent/intent.d.ts.map +1 -0
- package/dist/agent/intent.js +146 -0
- package/dist/agent/intent.js.map +1 -0
- package/dist/agent/streaming.d.ts +50 -0
- package/dist/agent/streaming.d.ts.map +1 -0
- package/dist/agent/streaming.js +110 -0
- package/dist/agent/streaming.js.map +1 -0
- package/dist/core/ai-engine.d.ts +59 -0
- package/dist/core/ai-engine.d.ts.map +1 -0
- package/dist/core/ai-engine.js +378 -0
- package/dist/core/ai-engine.js.map +1 -0
- package/dist/core/cli.d.ts +21 -0
- package/dist/core/cli.d.ts.map +1 -0
- package/dist/core/cli.js +143 -0
- package/dist/core/cli.js.map +1 -0
- package/dist/core/config.d.ts +38 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +129 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/context-compactor.d.ts +54 -0
- package/dist/core/context-compactor.d.ts.map +1 -0
- package/dist/core/context-compactor.js +197 -0
- package/dist/core/context-compactor.js.map +1 -0
- package/dist/core/hooks.d.ts +75 -0
- package/dist/core/hooks.d.ts.map +1 -0
- package/dist/core/hooks.js +146 -0
- package/dist/core/hooks.js.map +1 -0
- package/dist/core/permissions.d.ts +52 -0
- package/dist/core/permissions.d.ts.map +1 -0
- package/dist/core/permissions.js +237 -0
- package/dist/core/permissions.js.map +1 -0
- package/dist/core/session.d.ts +54 -0
- package/dist/core/session.d.ts.map +1 -0
- package/dist/core/session.js +147 -0
- package/dist/core/session.js.map +1 -0
- package/dist/core/skills.d.ts +60 -0
- package/dist/core/skills.d.ts.map +1 -0
- package/dist/core/skills.js +175 -0
- package/dist/core/skills.js.map +1 -0
- package/dist/core/state.d.ts +60 -0
- package/dist/core/state.d.ts.map +1 -0
- package/dist/core/state.js +106 -0
- package/dist/core/state.js.map +1 -0
- package/dist/core/subagent.d.ts +68 -0
- package/dist/core/subagent.d.ts.map +1 -0
- package/dist/core/subagent.js +142 -0
- package/dist/core/subagent.js.map +1 -0
- package/dist/core/system-prompt.d.ts +40 -0
- package/dist/core/system-prompt.d.ts.map +1 -0
- package/dist/core/system-prompt.js +138 -0
- package/dist/core/system-prompt.js.map +1 -0
- package/dist/core/tool-registry.d.ts +53 -0
- package/dist/core/tool-registry.d.ts.map +1 -0
- package/dist/core/tool-registry.js +138 -0
- package/dist/core/tool-registry.js.map +1 -0
- package/dist/core/types.d.ts +206 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +127 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +481 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/client.d.ts +83 -0
- package/dist/mcp/client.d.ts.map +1 -0
- package/dist/mcp/client.js +267 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/repl/index.d.ts +8 -0
- package/dist/repl/index.d.ts.map +1 -0
- package/dist/repl/index.js +8 -0
- package/dist/repl/index.js.map +1 -0
- package/dist/repl/input.d.ts +61 -0
- package/dist/repl/input.d.ts.map +1 -0
- package/dist/repl/input.js +127 -0
- package/dist/repl/input.js.map +1 -0
- package/dist/repl/loop.d.ts +53 -0
- package/dist/repl/loop.d.ts.map +1 -0
- package/dist/repl/loop.js +241 -0
- package/dist/repl/loop.js.map +1 -0
- package/dist/repl/output.d.ts +105 -0
- package/dist/repl/output.d.ts.map +1 -0
- package/dist/repl/output.js +197 -0
- package/dist/repl/output.js.map +1 -0
- package/dist/repl/welcome.d.ts +68 -0
- package/dist/repl/welcome.d.ts.map +1 -0
- package/dist/repl/welcome.js +249 -0
- package/dist/repl/welcome.js.map +1 -0
- package/dist/tools/file.d.ts +46 -0
- package/dist/tools/file.d.ts.map +1 -0
- package/dist/tools/file.js +100 -0
- package/dist/tools/file.js.map +1 -0
- package/dist/tools/git.d.ts +52 -0
- package/dist/tools/git.d.ts.map +1 -0
- package/dist/tools/git.js +112 -0
- package/dist/tools/git.js.map +1 -0
- package/dist/tools/index.d.ts +22 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +43 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/search.d.ts +36 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +223 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/shell.d.ts +57 -0
- package/dist/tools/shell.d.ts.map +1 -0
- package/dist/tools/shell.js +153 -0
- package/dist/tools/shell.js.map +1 -0
- package/dist/utils/diff-preview.d.ts +42 -0
- package/dist/utils/diff-preview.d.ts.map +1 -0
- package/dist/utils/diff-preview.js +174 -0
- package/dist/utils/diff-preview.js.map +1 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/memory.d.ts +81 -0
- package/dist/utils/memory.d.ts.map +1 -0
- package/dist/utils/memory.js +186 -0
- package/dist/utils/memory.js.map +1 -0
- package/dist/utils/project-context.d.ts +62 -0
- package/dist/utils/project-context.d.ts.map +1 -0
- package/dist/utils/project-context.js +197 -0
- package/dist/utils/project-context.js.map +1 -0
- package/docs/API_KEY_GUIDE.md +236 -0
- package/docs/FAQ.md +182 -0
- package/install.bat +63 -0
- package/install.ps1 +238 -0
- package/install.sh +113 -0
- package/package.json +36 -0
- package/src/agent/core.ts +179 -0
- package/src/agent/index.ts +8 -0
- package/src/agent/intent.ts +181 -0
- package/src/agent/streaming.ts +132 -0
- package/src/core/ai-engine.ts +437 -0
- package/src/core/cli.ts +171 -0
- package/src/core/config.ts +147 -0
- package/src/core/context-compactor.ts +245 -0
- package/src/core/hooks.ts +196 -0
- package/src/core/permissions.ts +308 -0
- package/src/core/session.ts +165 -0
- package/src/core/skills.ts +208 -0
- package/src/core/state.ts +120 -0
- package/src/core/subagent.ts +195 -0
- package/src/core/system-prompt.ts +163 -0
- package/src/core/tool-registry.ts +157 -0
- package/src/core/types.ts +280 -0
- package/src/index.ts +544 -0
- package/src/mcp/client.ts +330 -0
- package/src/repl/index.ts +8 -0
- package/src/repl/input.ts +139 -0
- package/src/repl/loop.ts +280 -0
- package/src/repl/output.ts +222 -0
- package/src/repl/welcome.ts +296 -0
- package/src/tools/file.ts +117 -0
- package/src/tools/git.ts +132 -0
- package/src/tools/index.ts +48 -0
- package/src/tools/search.ts +263 -0
- package/src/tools/shell.ts +181 -0
- package/src/utils/diff-preview.ts +202 -0
- package/src/utils/index.ts +8 -0
- package/src/utils/memory.ts +223 -0
- package/src/utils/project-context.ts +207 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* S10: Skills System
|
|
3
|
+
* Load skills from CLAUDE.md files and expose them as available commands
|
|
4
|
+
*
|
|
5
|
+
* Skills are domain-specific knowledge packages that extend agent capabilities.
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync, existsSync, readdirSync, statSync } from 'fs';
|
|
8
|
+
import { join } from 'path';
|
|
9
|
+
/**
|
|
10
|
+
* S10: Skills Loader — discovers and loads skills from filesystem
|
|
11
|
+
*/
|
|
12
|
+
export class SkillsLoader {
|
|
13
|
+
skills = new Map();
|
|
14
|
+
sources = new Set();
|
|
15
|
+
/**
|
|
16
|
+
* S10: Load skills from a directory
|
|
17
|
+
* Looks for .md files with # SkillName header
|
|
18
|
+
*/
|
|
19
|
+
loadFromDir(dirPath) {
|
|
20
|
+
if (!existsSync(dirPath))
|
|
21
|
+
return 0;
|
|
22
|
+
let count = 0;
|
|
23
|
+
const files = readdirSync(dirPath);
|
|
24
|
+
for (const file of files) {
|
|
25
|
+
const fullPath = join(dirPath, file);
|
|
26
|
+
const stat = statSync(fullPath);
|
|
27
|
+
if (stat.isDirectory()) {
|
|
28
|
+
count += this.loadFromDir(fullPath);
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if (file.endsWith('.md') || file.endsWith('.skill')) {
|
|
32
|
+
const loaded = this.loadFromFile(fullPath);
|
|
33
|
+
if (loaded)
|
|
34
|
+
count++;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return count;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* S10: Load a single skill file
|
|
41
|
+
*/
|
|
42
|
+
loadFromFile(filePath) {
|
|
43
|
+
try {
|
|
44
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
45
|
+
const skill = this.parseSkillFile(content, filePath);
|
|
46
|
+
if (skill) {
|
|
47
|
+
this.skills.set(skill.name, skill);
|
|
48
|
+
this.sources.add(filePath);
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
// Ignore errors
|
|
54
|
+
}
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* S10: Parse a skill file — extract name, description, prompt from markdown
|
|
59
|
+
*/
|
|
60
|
+
parseSkillFile(content, source) {
|
|
61
|
+
const lines = content.split('\n');
|
|
62
|
+
// Find skill name from first heading
|
|
63
|
+
let name = '';
|
|
64
|
+
let description = '';
|
|
65
|
+
let promptLines = [];
|
|
66
|
+
let inPrompt = false;
|
|
67
|
+
let tags = [];
|
|
68
|
+
for (let i = 0; i < lines.length; i++) {
|
|
69
|
+
const line = lines[i];
|
|
70
|
+
// Match # SkillName or ## SkillName
|
|
71
|
+
if (/^#{1,2}\s+(\S+)/.test(line.trim())) {
|
|
72
|
+
if (!name) {
|
|
73
|
+
name = line.replace(/^#{1,2}\s+/, '').trim();
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
// Second heading — end of prompt
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
// Description line (after name, before first code block or empty line)
|
|
82
|
+
if (name && !description && line.trim() && !line.startsWith('```')) {
|
|
83
|
+
description = line.trim();
|
|
84
|
+
}
|
|
85
|
+
// Code block — start of prompt template
|
|
86
|
+
if (line.startsWith('```')) {
|
|
87
|
+
if (!inPrompt) {
|
|
88
|
+
inPrompt = true;
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
// End of prompt
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (inPrompt) {
|
|
97
|
+
promptLines.push(line);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (!name)
|
|
101
|
+
return null;
|
|
102
|
+
return {
|
|
103
|
+
name,
|
|
104
|
+
description: description || name,
|
|
105
|
+
prompt: promptLines.join('\n').trim(),
|
|
106
|
+
source,
|
|
107
|
+
tags: this.extractTags(content)
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
extractTags(content) {
|
|
111
|
+
const tagMatch = content.match(/tags?:\s*(.+)/i);
|
|
112
|
+
if (tagMatch) {
|
|
113
|
+
return tagMatch[1].split(/[,\s]+/).filter(Boolean);
|
|
114
|
+
}
|
|
115
|
+
return [];
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* S10: Get all skills
|
|
119
|
+
*/
|
|
120
|
+
getAll() {
|
|
121
|
+
return [...this.skills.values()];
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* S10: Get skill by name
|
|
125
|
+
*/
|
|
126
|
+
get(name) {
|
|
127
|
+
return this.skills.get(name);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* S10: Search skills by tag or name
|
|
131
|
+
*/
|
|
132
|
+
search(query) {
|
|
133
|
+
const q = query.toLowerCase();
|
|
134
|
+
return this.getAll().filter(s => s.name.toLowerCase().includes(q) ||
|
|
135
|
+
s.description.toLowerCase().includes(q) ||
|
|
136
|
+
s.tags.some(t => t.toLowerCase().includes(q)));
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* S10: Get catalog
|
|
140
|
+
*/
|
|
141
|
+
getCatalog() {
|
|
142
|
+
return {
|
|
143
|
+
skills: this.getAll(),
|
|
144
|
+
loadedAt: new Date(),
|
|
145
|
+
sources: [...this.sources]
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* S10: Built-in skills
|
|
151
|
+
*/
|
|
152
|
+
export const BUILT_IN_SKILLS = [
|
|
153
|
+
{
|
|
154
|
+
name: 'explain-code',
|
|
155
|
+
description: 'Explain what a piece of code does in plain English',
|
|
156
|
+
prompt: 'Explain this code:\n\n```\n{{CODE}}\n```\n\nBe concise and clear.',
|
|
157
|
+
source: 'builtin',
|
|
158
|
+
tags: ['analysis', 'documentation']
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
name: 'review-code',
|
|
162
|
+
description: 'Review code for bugs, performance issues, and best practices',
|
|
163
|
+
prompt: 'Review this code:\n\n```\n{{CODE}}\n```\n\nFocus on: bugs, security, performance, readability.',
|
|
164
|
+
source: 'builtin',
|
|
165
|
+
tags: ['review', 'quality']
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
name: 'write-test',
|
|
169
|
+
description: 'Generate unit tests for the given code',
|
|
170
|
+
prompt: 'Write unit tests for:\n\n```\n{{CODE}}\n```\n\nUse a testing framework appropriate for the language.',
|
|
171
|
+
source: 'builtin',
|
|
172
|
+
tags: ['testing', 'quality']
|
|
173
|
+
}
|
|
174
|
+
];
|
|
175
|
+
//# sourceMappingURL=skills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/core/skills.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* S11: State & Session Management
|
|
3
|
+
*
|
|
4
|
+
* Three layers:
|
|
5
|
+
* 1. EphemeralState - in-memory, current session only
|
|
6
|
+
* 2. PersistentState - survives restarts (file-based)
|
|
7
|
+
* 3. SessionState - per-conversation state
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* S11: Ephemeral State — in-memory key-value store
|
|
11
|
+
*/
|
|
12
|
+
export declare class EphemeralState<T = any> {
|
|
13
|
+
private data;
|
|
14
|
+
get(key: string): T | undefined;
|
|
15
|
+
set(key: string, value: T): void;
|
|
16
|
+
has(key: string): boolean;
|
|
17
|
+
delete(key: string): void;
|
|
18
|
+
clear(): void;
|
|
19
|
+
keys(): string[];
|
|
20
|
+
entries(): [string, T][];
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* S11: Persistent State — file-backed key-value store
|
|
24
|
+
*/
|
|
25
|
+
export declare class PersistentState<T = any> {
|
|
26
|
+
private filePath;
|
|
27
|
+
private data;
|
|
28
|
+
constructor(filePath: string);
|
|
29
|
+
private load;
|
|
30
|
+
private save;
|
|
31
|
+
get(key: string): T | undefined;
|
|
32
|
+
set(key: string, value: T): void;
|
|
33
|
+
has(key: string): boolean;
|
|
34
|
+
delete(key: string): void;
|
|
35
|
+
clear(): void;
|
|
36
|
+
keys(): string[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* S11: Session State — per-conversation state
|
|
40
|
+
*/
|
|
41
|
+
export declare class SessionState<T = any> {
|
|
42
|
+
private sessions;
|
|
43
|
+
private currentSessionId;
|
|
44
|
+
createSession(sessionId: string): void;
|
|
45
|
+
deleteSession(sessionId: string): void;
|
|
46
|
+
setCurrentSession(sessionId: string): void;
|
|
47
|
+
getCurrentSession(): EphemeralState<T> | null;
|
|
48
|
+
getSession(sessionId: string): EphemeralState<T> | null;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* S11: Global State Manager
|
|
52
|
+
*/
|
|
53
|
+
export declare class StateManager {
|
|
54
|
+
ephemeral: EphemeralState;
|
|
55
|
+
persistent: PersistentState;
|
|
56
|
+
session: SessionState;
|
|
57
|
+
constructor(dataDir?: string);
|
|
58
|
+
}
|
|
59
|
+
export declare function getStateManager(): StateManager;
|
|
60
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/core/state.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH;;GAEG;AACH,qBAAa,cAAc,CAAC,CAAC,GAAG,GAAG;IACjC,OAAO,CAAC,IAAI,CAA6B;IAEzC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAC/B,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAChC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IACzB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IACzB,KAAK,IAAI,IAAI;IACb,IAAI,IAAI,MAAM,EAAE;IAChB,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE;CACzB;AAED;;GAEG;AACH,qBAAa,eAAe,CAAC,CAAC,GAAG,GAAG;IAClC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,IAAI,CAAyB;gBAEzB,QAAQ,EAAE,MAAM;IAK5B,OAAO,CAAC,IAAI;IAUZ,OAAO,CAAC,IAAI;IAQZ,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAC/B,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAChC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IACzB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IACzB,KAAK,IAAI,IAAI;IACb,IAAI,IAAI,MAAM,EAAE;CACjB;AAED;;GAEG;AACH,qBAAa,YAAY,CAAC,CAAC,GAAG,GAAG;IAC/B,OAAO,CAAC,QAAQ,CAA6C;IAC7D,OAAO,CAAC,gBAAgB,CAAuB;IAE/C,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAItC,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAItC,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAO1C,iBAAiB,IAAI,cAAc,CAAC,CAAC,CAAC,GAAG,IAAI;IAK7C,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC,GAAG,IAAI;CAGxD;AAED;;GAEG;AACH,qBAAa,YAAY;IACvB,SAAS,EAAE,cAAc,CAAC;IAC1B,UAAU,EAAE,eAAe,CAAC;IAC5B,OAAO,EAAE,YAAY,CAAC;gBAEV,OAAO,GAAE,MAAkD;CAKxE;AAID,wBAAgB,eAAe,IAAI,YAAY,CAK9C"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* S11: State & Session Management
|
|
3
|
+
*
|
|
4
|
+
* Three layers:
|
|
5
|
+
* 1. EphemeralState - in-memory, current session only
|
|
6
|
+
* 2. PersistentState - survives restarts (file-based)
|
|
7
|
+
* 3. SessionState - per-conversation state
|
|
8
|
+
*/
|
|
9
|
+
import { readFileSync, writeFileSync, existsSync } from 'fs';
|
|
10
|
+
import { join } from 'path';
|
|
11
|
+
/**
|
|
12
|
+
* S11: Ephemeral State — in-memory key-value store
|
|
13
|
+
*/
|
|
14
|
+
export class EphemeralState {
|
|
15
|
+
data = new Map();
|
|
16
|
+
get(key) { return this.data.get(key); }
|
|
17
|
+
set(key, value) { this.data.set(key, value); }
|
|
18
|
+
has(key) { return this.data.has(key); }
|
|
19
|
+
delete(key) { this.data.delete(key); }
|
|
20
|
+
clear() { this.data.clear(); }
|
|
21
|
+
keys() { return [...this.data.keys()]; }
|
|
22
|
+
entries() { return [...this.data.entries()]; }
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* S11: Persistent State — file-backed key-value store
|
|
26
|
+
*/
|
|
27
|
+
export class PersistentState {
|
|
28
|
+
filePath;
|
|
29
|
+
data = {};
|
|
30
|
+
constructor(filePath) {
|
|
31
|
+
this.filePath = filePath;
|
|
32
|
+
this.load();
|
|
33
|
+
}
|
|
34
|
+
load() {
|
|
35
|
+
try {
|
|
36
|
+
if (existsSync(this.filePath)) {
|
|
37
|
+
this.data = JSON.parse(readFileSync(this.filePath, 'utf-8'));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
this.data = {};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
save() {
|
|
45
|
+
try {
|
|
46
|
+
writeFileSync(this.filePath, JSON.stringify(this.data, null, 2), 'utf-8');
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
console.error('[State] Failed to save:', error.message);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
get(key) { return this.data[key]; }
|
|
53
|
+
set(key, value) { this.data[key] = value; this.save(); }
|
|
54
|
+
has(key) { return key in this.data; }
|
|
55
|
+
delete(key) { delete this.data[key]; this.save(); }
|
|
56
|
+
clear() { this.data = {}; this.save(); }
|
|
57
|
+
keys() { return Object.keys(this.data); }
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* S11: Session State — per-conversation state
|
|
61
|
+
*/
|
|
62
|
+
export class SessionState {
|
|
63
|
+
sessions = new Map();
|
|
64
|
+
currentSessionId = null;
|
|
65
|
+
createSession(sessionId) {
|
|
66
|
+
this.sessions.set(sessionId, new EphemeralState());
|
|
67
|
+
}
|
|
68
|
+
deleteSession(sessionId) {
|
|
69
|
+
this.sessions.delete(sessionId);
|
|
70
|
+
}
|
|
71
|
+
setCurrentSession(sessionId) {
|
|
72
|
+
if (!this.sessions.has(sessionId)) {
|
|
73
|
+
this.createSession(sessionId);
|
|
74
|
+
}
|
|
75
|
+
this.currentSessionId = sessionId;
|
|
76
|
+
}
|
|
77
|
+
getCurrentSession() {
|
|
78
|
+
if (!this.currentSessionId)
|
|
79
|
+
return null;
|
|
80
|
+
return this.sessions.get(this.currentSessionId) || null;
|
|
81
|
+
}
|
|
82
|
+
getSession(sessionId) {
|
|
83
|
+
return this.sessions.get(sessionId) || null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* S11: Global State Manager
|
|
88
|
+
*/
|
|
89
|
+
export class StateManager {
|
|
90
|
+
ephemeral;
|
|
91
|
+
persistent;
|
|
92
|
+
session;
|
|
93
|
+
constructor(dataDir = join(process.cwd(), '.thatgfsj', 'state')) {
|
|
94
|
+
this.ephemeral = new EphemeralState();
|
|
95
|
+
this.persistent = new PersistentState(join(dataDir, 'persistent.json'));
|
|
96
|
+
this.session = new SessionState();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
let globalStateManager = null;
|
|
100
|
+
export function getStateManager() {
|
|
101
|
+
if (!globalStateManager) {
|
|
102
|
+
globalStateManager = new StateManager();
|
|
103
|
+
}
|
|
104
|
+
return globalStateManager;
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/core/state.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* S06: Subagent Manager
|
|
3
|
+
* Spawn and manage subagents for parallel task execution
|
|
4
|
+
*
|
|
5
|
+
* Subagents enable "infinite parallelism" — complex tasks are broken into
|
|
6
|
+
* independent subtasks, each run by a separate agent instance.
|
|
7
|
+
*/
|
|
8
|
+
import { AIConfig } from './types.js';
|
|
9
|
+
export interface SubagentOptions {
|
|
10
|
+
/** Task prompt for the subagent */
|
|
11
|
+
prompt: string;
|
|
12
|
+
/** Custom system prompt (optional) */
|
|
13
|
+
systemPrompt?: string;
|
|
14
|
+
/** Tools available to this subagent */
|
|
15
|
+
tools?: any[];
|
|
16
|
+
/** Max iterations for this subagent */
|
|
17
|
+
maxIterations?: number;
|
|
18
|
+
/** Subagent name for logging */
|
|
19
|
+
name?: string;
|
|
20
|
+
/** Working directory */
|
|
21
|
+
cwd?: string;
|
|
22
|
+
}
|
|
23
|
+
export interface SubagentResult {
|
|
24
|
+
success: boolean;
|
|
25
|
+
output: string;
|
|
26
|
+
error?: string;
|
|
27
|
+
iterations: number;
|
|
28
|
+
durationMs: number;
|
|
29
|
+
name: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* S06: Subagent Manager
|
|
33
|
+
*/
|
|
34
|
+
export declare class SubagentManager {
|
|
35
|
+
private config;
|
|
36
|
+
private activeSubagents;
|
|
37
|
+
private maxConcurrent;
|
|
38
|
+
constructor(config: AIConfig);
|
|
39
|
+
/**
|
|
40
|
+
* S06: Spawn a subagent to run a task asynchronously
|
|
41
|
+
*/
|
|
42
|
+
spawn(options: SubagentOptions): Promise<SubagentResult>;
|
|
43
|
+
/**
|
|
44
|
+
* S06: Spawn multiple subagents in parallel (bounded concurrency)
|
|
45
|
+
*/
|
|
46
|
+
spawnAll(tasks: SubagentOptions[]): Promise<SubagentResult[]>;
|
|
47
|
+
/**
|
|
48
|
+
* S06: Run a single subagent task
|
|
49
|
+
*/
|
|
50
|
+
private runSubagent;
|
|
51
|
+
/**
|
|
52
|
+
* S06: Get number of active subagents
|
|
53
|
+
*/
|
|
54
|
+
getActiveCount(): number;
|
|
55
|
+
/**
|
|
56
|
+
* S06: Get active subagent names
|
|
57
|
+
*/
|
|
58
|
+
getActiveNames(): string[];
|
|
59
|
+
/**
|
|
60
|
+
* S06: Abort all active subagents
|
|
61
|
+
*/
|
|
62
|
+
abortAll(): void;
|
|
63
|
+
/**
|
|
64
|
+
* S06: Set max concurrent subagents
|
|
65
|
+
*/
|
|
66
|
+
setMaxConcurrent(max: number): void;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=subagent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subagent.d.ts","sourceRoot":"","sources":["../../src/core/subagent.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,MAAM,WAAW,eAAe;IAC9B,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,sCAAsC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uCAAuC;IACvC,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;IACd,uCAAuC;IACvC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gCAAgC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wBAAwB;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,eAAe,CAIR;IACf,OAAO,CAAC,aAAa,CAAK;gBAEd,MAAM,EAAE,QAAQ;IAI5B;;OAEG;IACG,KAAK,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAoB9D;;OAEG;IACG,QAAQ,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAsBnE;;OAEG;YACW,WAAW;IA8DzB;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;OAEG;IACH,cAAc,IAAI,MAAM,EAAE;IAI1B;;OAEG;IACH,QAAQ,IAAI,IAAI;IAOhB;;OAEG;IACH,gBAAgB,CAAC,GAAG,EAAE,MAAM;CAG7B"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* S06: Subagent Manager
|
|
3
|
+
* Spawn and manage subagents for parallel task execution
|
|
4
|
+
*
|
|
5
|
+
* Subagents enable "infinite parallelism" — complex tasks are broken into
|
|
6
|
+
* independent subtasks, each run by a separate agent instance.
|
|
7
|
+
*/
|
|
8
|
+
import { AIEngine } from './ai-engine.js';
|
|
9
|
+
/**
|
|
10
|
+
* S06: Subagent Manager
|
|
11
|
+
*/
|
|
12
|
+
export class SubagentManager {
|
|
13
|
+
config;
|
|
14
|
+
activeSubagents = new Map();
|
|
15
|
+
maxConcurrent = 3;
|
|
16
|
+
constructor(config) {
|
|
17
|
+
this.config = config;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* S06: Spawn a subagent to run a task asynchronously
|
|
21
|
+
*/
|
|
22
|
+
async spawn(options) {
|
|
23
|
+
const name = options.name || `subagent_${Date.now()}`;
|
|
24
|
+
const startedAt = new Date();
|
|
25
|
+
const task = this.runSubagent(name, options, startedAt);
|
|
26
|
+
// Track active subagent
|
|
27
|
+
this.activeSubagents.set(name, { task, startedAt, name });
|
|
28
|
+
// Auto-cleanup after completion
|
|
29
|
+
task.then(() => {
|
|
30
|
+
setTimeout(() => this.activeSubagents.delete(name), 5000);
|
|
31
|
+
}).catch(() => {
|
|
32
|
+
this.activeSubagents.delete(name);
|
|
33
|
+
});
|
|
34
|
+
// Return handle — caller can await or ignore
|
|
35
|
+
return task;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* S06: Spawn multiple subagents in parallel (bounded concurrency)
|
|
39
|
+
*/
|
|
40
|
+
async spawnAll(tasks) {
|
|
41
|
+
const results = [];
|
|
42
|
+
const queue = [...tasks];
|
|
43
|
+
const running = [];
|
|
44
|
+
while (queue.length > 0 || running.length > 0) {
|
|
45
|
+
while (running.length < this.maxConcurrent && queue.length > 0) {
|
|
46
|
+
const task = queue.shift();
|
|
47
|
+
const p = this.spawn(task).then(r => { results.push(r); }).then(() => { });
|
|
48
|
+
running.push(p);
|
|
49
|
+
}
|
|
50
|
+
if (running.length > 0) {
|
|
51
|
+
await Promise.race(running).catch(() => { });
|
|
52
|
+
await Promise.allSettled(running);
|
|
53
|
+
running.length = 0;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return results;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* S06: Run a single subagent task
|
|
60
|
+
*/
|
|
61
|
+
async runSubagent(name, options, startedAt) {
|
|
62
|
+
const startMs = Date.now();
|
|
63
|
+
let iterations = 0;
|
|
64
|
+
const maxIterations = options.maxIterations || 5;
|
|
65
|
+
try {
|
|
66
|
+
// Create isolated AI engine for subagent
|
|
67
|
+
const subAI = new AIEngine({
|
|
68
|
+
...this.config,
|
|
69
|
+
model: options.systemPrompt ? (this.config.model || 'unknown') : this.config.model
|
|
70
|
+
});
|
|
71
|
+
// Register tools if provided
|
|
72
|
+
if (options.tools) {
|
|
73
|
+
for (const tool of options.tools) {
|
|
74
|
+
subAI.registerTool(tool);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Build messages
|
|
78
|
+
const messages = [];
|
|
79
|
+
if (options.systemPrompt) {
|
|
80
|
+
messages.push({ role: 'system', content: options.systemPrompt });
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
messages.push({
|
|
84
|
+
role: 'system',
|
|
85
|
+
content: 'You are ' + (options.name || 'a subagent') + '. Complete the task assigned by the parent agent. Be concise and focused.'
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
messages.push({ role: 'user', content: options.prompt });
|
|
89
|
+
// Run agent loop
|
|
90
|
+
let output = '';
|
|
91
|
+
for await (const chunk of subAI.chatStream(messages, maxIterations)) {
|
|
92
|
+
output += chunk;
|
|
93
|
+
iterations++;
|
|
94
|
+
}
|
|
95
|
+
return {
|
|
96
|
+
success: true,
|
|
97
|
+
output,
|
|
98
|
+
iterations,
|
|
99
|
+
durationMs: Date.now() - startMs,
|
|
100
|
+
name
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
return {
|
|
105
|
+
success: false,
|
|
106
|
+
output: '',
|
|
107
|
+
error: error.message,
|
|
108
|
+
iterations,
|
|
109
|
+
durationMs: Date.now() - startMs,
|
|
110
|
+
name
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* S06: Get number of active subagents
|
|
116
|
+
*/
|
|
117
|
+
getActiveCount() {
|
|
118
|
+
return this.activeSubagents.size;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* S06: Get active subagent names
|
|
122
|
+
*/
|
|
123
|
+
getActiveNames() {
|
|
124
|
+
return [...this.activeSubagents.values()].map(s => s.name);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* S06: Abort all active subagents
|
|
128
|
+
*/
|
|
129
|
+
abortAll() {
|
|
130
|
+
for (const [name] of this.activeSubagents) {
|
|
131
|
+
// Subagents don't have abort support yet, just remove from tracking
|
|
132
|
+
this.activeSubagents.delete(name);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* S06: Set max concurrent subagents
|
|
137
|
+
*/
|
|
138
|
+
setMaxConcurrent(max) {
|
|
139
|
+
this.maxConcurrent = max;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=subagent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subagent.js","sourceRoot":"","sources":["../../src/core/subagent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* S04: System Prompt Builder
|
|
3
|
+
* Dynamic system prompt construction - not a static string, but a program
|
|
4
|
+
* that assembles context from multiple sources each turn
|
|
5
|
+
*/
|
|
6
|
+
import { Tool } from './types.js';
|
|
7
|
+
export interface SystemPromptConfig {
|
|
8
|
+
cwd?: string;
|
|
9
|
+
tools?: Tool[];
|
|
10
|
+
includeClaudeMd?: boolean;
|
|
11
|
+
projectInstructions?: string;
|
|
12
|
+
permissionMode?: 'accept' | 'deny' | 'ask';
|
|
13
|
+
date?: Date;
|
|
14
|
+
model?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* S04: System Prompt Builder - assembles prompt from multiple fragments
|
|
18
|
+
*/
|
|
19
|
+
export declare class SystemPromptBuilder {
|
|
20
|
+
private config;
|
|
21
|
+
constructor(config?: SystemPromptConfig);
|
|
22
|
+
build(): string;
|
|
23
|
+
private buildIdentity;
|
|
24
|
+
private buildToolInstructions;
|
|
25
|
+
private buildEnvironment;
|
|
26
|
+
private buildPermissionMode;
|
|
27
|
+
private buildProjectInstructions;
|
|
28
|
+
private buildDateInfo;
|
|
29
|
+
private buildOutputFormat;
|
|
30
|
+
setTools(tools: Tool[]): this;
|
|
31
|
+
setCwd(cwd: string): this;
|
|
32
|
+
setPermissionMode(mode: 'accept' | 'deny' | 'ask'): this;
|
|
33
|
+
setProjectInstructions(instructions: string): this;
|
|
34
|
+
setModel(model: string): this;
|
|
35
|
+
buildToolsFragment(): string;
|
|
36
|
+
injectReminder(reminder: string): string;
|
|
37
|
+
}
|
|
38
|
+
export declare function getSystemPromptBuilder(config?: SystemPromptConfig): SystemPromptBuilder;
|
|
39
|
+
export declare function updateSystemPrompt(tools?: Tool[], permissionMode?: 'accept' | 'deny' | 'ask'): void;
|
|
40
|
+
//# sourceMappingURL=system-prompt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../src/core/system-prompt.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAElC,MAAM,WAAW,kBAAkB;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,cAAc,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,KAAK,CAAC;IAC3C,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,MAAM,CAAqB;gBAEvB,MAAM,GAAE,kBAAuB;IAY3C,KAAK,IAAI,MAAM;IAYf,OAAO,CAAC,aAAa;IAiBrB,OAAO,CAAC,qBAAqB;IAgB7B,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,mBAAmB;IAU3B,OAAO,CAAC,wBAAwB;IAqBhC,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,iBAAiB;IAYzB,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE;IACtB,MAAM,CAAC,GAAG,EAAE,MAAM;IAClB,iBAAiB,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,KAAK;IACjD,sBAAsB,CAAC,YAAY,EAAE,MAAM;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM;IAEtB,kBAAkB,IAAI,MAAM;IAE5B,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;CAGzC;AAID,wBAAgB,sBAAsB,CAAC,MAAM,CAAC,EAAE,kBAAkB,GAAG,mBAAmB,CAGvF;AAED,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,EAAE,cAAc,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,KAAK,QAK5F"}
|