ineedcodes 0.1.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.
- package/LICENSE +21 -0
- package/README.md +161 -0
- package/docs/assets/ineed-logo.svg +161 -0
- package/docs/configuration.md +71 -0
- package/docs/skills.md +58 -0
- package/package.json +41 -0
- package/packages/agent/dist/boost.d.ts +34 -0
- package/packages/agent/dist/boost.js +138 -0
- package/packages/agent/dist/boost.js.map +1 -0
- package/packages/agent/dist/events.d.ts +67 -0
- package/packages/agent/dist/events.js +16 -0
- package/packages/agent/dist/events.js.map +1 -0
- package/packages/agent/dist/index.d.ts +6 -0
- package/packages/agent/dist/index.js +7 -0
- package/packages/agent/dist/index.js.map +1 -0
- package/packages/agent/dist/lead-agent.d.ts +85 -0
- package/packages/agent/dist/lead-agent.js +235 -0
- package/packages/agent/dist/lead-agent.js.map +1 -0
- package/packages/agent/dist/orchestrator.d.ts +43 -0
- package/packages/agent/dist/orchestrator.js +135 -0
- package/packages/agent/dist/orchestrator.js.map +1 -0
- package/packages/agent/dist/runtime.d.ts +44 -0
- package/packages/agent/dist/runtime.js +265 -0
- package/packages/agent/dist/runtime.js.map +1 -0
- package/packages/agent/dist/system-prompts.d.ts +24 -0
- package/packages/agent/dist/system-prompts.js +91 -0
- package/packages/agent/dist/system-prompts.js.map +1 -0
- package/packages/agent/package.json +21 -0
- package/packages/cli/dist/index.d.ts +3 -0
- package/packages/cli/dist/index.js +567 -0
- package/packages/cli/dist/index.js.map +1 -0
- package/packages/cli/dist/setup.d.ts +37 -0
- package/packages/cli/dist/setup.js +240 -0
- package/packages/cli/dist/setup.js.map +1 -0
- package/packages/cli/dist/tools-setup.d.ts +12 -0
- package/packages/cli/dist/tools-setup.js +28 -0
- package/packages/cli/dist/tools-setup.js.map +1 -0
- package/packages/cli/dist/ui/approval.d.ts +12 -0
- package/packages/cli/dist/ui/approval.js +52 -0
- package/packages/cli/dist/ui/approval.js.map +1 -0
- package/packages/cli/dist/ui/colors.d.ts +14 -0
- package/packages/cli/dist/ui/colors.js +21 -0
- package/packages/cli/dist/ui/colors.js.map +1 -0
- package/packages/cli/dist/ui/prompts.d.ts +46 -0
- package/packages/cli/dist/ui/prompts.js +135 -0
- package/packages/cli/dist/ui/prompts.js.map +1 -0
- package/packages/cli/dist/ui/renderer.d.ts +13 -0
- package/packages/cli/dist/ui/renderer.js +95 -0
- package/packages/cli/dist/ui/renderer.js.map +1 -0
- package/packages/cli/package.json +23 -0
- package/packages/core/dist/config/config.d.ts +32 -0
- package/packages/core/dist/config/config.js +43 -0
- package/packages/core/dist/config/config.js.map +1 -0
- package/packages/core/dist/context/engine.d.ts +25 -0
- package/packages/core/dist/context/engine.js +98 -0
- package/packages/core/dist/context/engine.js.map +1 -0
- package/packages/core/dist/index.d.ts +20 -0
- package/packages/core/dist/index.js +21 -0
- package/packages/core/dist/index.js.map +1 -0
- package/packages/core/dist/llm/openai-compatible.d.ts +23 -0
- package/packages/core/dist/llm/openai-compatible.js +177 -0
- package/packages/core/dist/llm/openai-compatible.js.map +1 -0
- package/packages/core/dist/memory/icm-adapter.d.ts +31 -0
- package/packages/core/dist/memory/icm-adapter.js +98 -0
- package/packages/core/dist/memory/icm-adapter.js.map +1 -0
- package/packages/core/dist/permissions/permissions.d.ts +28 -0
- package/packages/core/dist/permissions/permissions.js +89 -0
- package/packages/core/dist/permissions/permissions.js.map +1 -0
- package/packages/core/dist/security/secrets.d.ts +4 -0
- package/packages/core/dist/security/secrets.js +43 -0
- package/packages/core/dist/security/secrets.js.map +1 -0
- package/packages/core/dist/session/store.d.ts +16 -0
- package/packages/core/dist/session/store.js +54 -0
- package/packages/core/dist/session/store.js.map +1 -0
- package/packages/core/dist/shell/process.d.ts +26 -0
- package/packages/core/dist/shell/process.js +128 -0
- package/packages/core/dist/shell/process.js.map +1 -0
- package/packages/core/dist/skills/loader.d.ts +9 -0
- package/packages/core/dist/skills/loader.js +163 -0
- package/packages/core/dist/skills/loader.js.map +1 -0
- package/packages/core/dist/tools/fs.d.ts +10 -0
- package/packages/core/dist/tools/fs.js +409 -0
- package/packages/core/dist/tools/fs.js.map +1 -0
- package/packages/core/dist/tools/git.d.ts +7 -0
- package/packages/core/dist/tools/git.js +251 -0
- package/packages/core/dist/tools/git.js.map +1 -0
- package/packages/core/dist/tools/mcp.d.ts +42 -0
- package/packages/core/dist/tools/mcp.js +158 -0
- package/packages/core/dist/tools/mcp.js.map +1 -0
- package/packages/core/dist/tools/registry.d.ts +21 -0
- package/packages/core/dist/tools/registry.js +50 -0
- package/packages/core/dist/tools/registry.js.map +1 -0
- package/packages/core/dist/tools/search.d.ts +2 -0
- package/packages/core/dist/tools/search.js +243 -0
- package/packages/core/dist/tools/search.js.map +1 -0
- package/packages/core/dist/tools/shell.d.ts +8 -0
- package/packages/core/dist/tools/shell.js +164 -0
- package/packages/core/dist/tools/shell.js.map +1 -0
- package/packages/core/dist/tools/web.d.ts +14 -0
- package/packages/core/dist/tools/web.js +125 -0
- package/packages/core/dist/tools/web.js.map +1 -0
- package/packages/core/dist/types.d.ts +202 -0
- package/packages/core/dist/types.js +7 -0
- package/packages/core/dist/types.js.map +1 -0
- package/packages/core/dist/util/fs.d.ts +5 -0
- package/packages/core/dist/util/fs.js +33 -0
- package/packages/core/dist/util/fs.js.map +1 -0
- package/packages/core/dist/util/shell-quote.d.ts +7 -0
- package/packages/core/dist/util/shell-quote.js +20 -0
- package/packages/core/dist/util/shell-quote.js.map +1 -0
- package/packages/core/dist/workspace/workspace.d.ts +15 -0
- package/packages/core/dist/workspace/workspace.js +84 -0
- package/packages/core/dist/workspace/workspace.js.map +1 -0
- package/packages/core/package.json +21 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import * as path from 'node:path';
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import { shellQuote } from '@ineedcodes/core';
|
|
4
|
+
export class BoostIntegration {
|
|
5
|
+
registry;
|
|
6
|
+
toolContext;
|
|
7
|
+
emit;
|
|
8
|
+
run;
|
|
9
|
+
constructor(registry, toolContext, emit) {
|
|
10
|
+
this.registry = registry;
|
|
11
|
+
this.toolContext = toolContext;
|
|
12
|
+
this.emit = emit;
|
|
13
|
+
}
|
|
14
|
+
active() {
|
|
15
|
+
return this.run !== undefined;
|
|
16
|
+
}
|
|
17
|
+
current() {
|
|
18
|
+
return this.run;
|
|
19
|
+
}
|
|
20
|
+
async exec(tool, input) {
|
|
21
|
+
return this.registry.execute(tool, input, this.toolContext);
|
|
22
|
+
}
|
|
23
|
+
async start(objective) {
|
|
24
|
+
if (this.run) {
|
|
25
|
+
return { ok: false, summary: 'A Boost run is already active. Finish or abort it first.', error: 'boost_active' };
|
|
26
|
+
}
|
|
27
|
+
await this.emit({ type: 'boost-phase', phase: 'start', detail: objective });
|
|
28
|
+
// Require a Git repo for worktree isolation.
|
|
29
|
+
const status = await this.exec('git_status', {});
|
|
30
|
+
if (!status.ok) {
|
|
31
|
+
return { ok: false, summary: 'Boost needs a Git repository for worktree isolation. Initialize Git first.', error: 'no_git' };
|
|
32
|
+
}
|
|
33
|
+
const id = `boost-${Date.now()}`;
|
|
34
|
+
const branch = `boost/${id.split('-')[1] ?? id}`;
|
|
35
|
+
const worktreePath = path.join(this.toolContext.workspaceRoot, '.ineedcodes', id);
|
|
36
|
+
const added = await this.exec('git_worktree', { mode: 'add', path: worktreePath, branch });
|
|
37
|
+
if (!added.ok) {
|
|
38
|
+
return { ok: false, summary: `Could not create Boost worktree: ${added.summary}`, error: 'worktree_failed' };
|
|
39
|
+
}
|
|
40
|
+
this.run = { id, worktreePath, branch, phase: 'investigate', startedAt: Date.now() };
|
|
41
|
+
return {
|
|
42
|
+
ok: true,
|
|
43
|
+
summary: `Boost started in isolated worktree ${worktreePath} (branch ${branch}). Objective: ${objective}`,
|
|
44
|
+
data: { id, worktreePath, branch }
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
worktreeContext() {
|
|
48
|
+
if (!this.run)
|
|
49
|
+
return undefined;
|
|
50
|
+
return {
|
|
51
|
+
...this.toolContext,
|
|
52
|
+
cwd: this.run.worktreePath,
|
|
53
|
+
workspaceRoot: this.run.worktreePath
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/** Commit any uncommitted work inside the Boost worktree so it can merge. */
|
|
57
|
+
async commitWorktreeChanges() {
|
|
58
|
+
if (!this.run)
|
|
59
|
+
return { ok: false, summary: 'No active Boost run.', error: 'no_boost' };
|
|
60
|
+
await this.exec('shell_exec', { command: `git -C ${shellQuote(this.run.worktreePath)} add -A` });
|
|
61
|
+
const commit = await this.exec('shell_exec', {
|
|
62
|
+
command: `git -C ${shellQuote(this.run.worktreePath)} commit -m ${shellQuote(`boost: ${this.run.id}`)}`
|
|
63
|
+
});
|
|
64
|
+
// "nothing to commit" is fine; real failures are not.
|
|
65
|
+
const nothingToCommit = /nothing to commit|no changes added/i.test(commit.summary + JSON.stringify(commit.data ?? ''));
|
|
66
|
+
if (!commit.ok && !nothingToCommit) {
|
|
67
|
+
return { ok: false, summary: `Could not commit Boost worktree changes: ${commit.summary}`, error: 'commit_failed' };
|
|
68
|
+
}
|
|
69
|
+
return { ok: true, summary: nothingToCommit ? 'No changes to commit in the Boost worktree.' : 'Boost changes committed.' };
|
|
70
|
+
}
|
|
71
|
+
async reconcile() {
|
|
72
|
+
if (!this.run)
|
|
73
|
+
return { ok: false, summary: 'No active Boost run.', error: 'no_boost' };
|
|
74
|
+
this.run.phase = 'reconcile';
|
|
75
|
+
await this.emit({ type: 'boost-phase', phase: 'reconcile' });
|
|
76
|
+
const committed = await this.commitWorktreeChanges();
|
|
77
|
+
if (!committed.ok)
|
|
78
|
+
return committed;
|
|
79
|
+
// Merge the boost branch back into the user's branch.
|
|
80
|
+
const result = await this.exec('shell_exec', { command: `git merge --no-ff ${this.run.branch}` });
|
|
81
|
+
if (result.ok) {
|
|
82
|
+
// Safe-delete the merged branch.
|
|
83
|
+
await this.exec('shell_exec', { command: `git branch -d ${this.run.branch}` });
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
ok: result.ok,
|
|
87
|
+
summary: result.ok
|
|
88
|
+
? `Boost branch ${this.run.branch} merged into your branch (${committed.summary}).`
|
|
89
|
+
: `Merge failed: ${result.summary} Run abort + cleanup if needed.`,
|
|
90
|
+
data: result.data
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
async abort(reason) {
|
|
94
|
+
if (!this.run)
|
|
95
|
+
return { ok: false, summary: 'No active Boost run.', error: 'no_boost' };
|
|
96
|
+
this.run.phase = 'abort';
|
|
97
|
+
const { worktreePath, branch } = this.run;
|
|
98
|
+
await this.emit({ type: 'boost-phase', phase: 'abort', detail: reason });
|
|
99
|
+
// A branch checked out in a worktree cannot be deleted: remove the
|
|
100
|
+
// worktree first, then the branch. Your working tree was never touched.
|
|
101
|
+
const removed = await this.exec('git_worktree', { mode: 'remove', path: worktreePath });
|
|
102
|
+
try {
|
|
103
|
+
fs.rmSync(worktreePath, { recursive: true, force: true });
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// best effort
|
|
107
|
+
}
|
|
108
|
+
await this.exec('shell_exec', { command: `git branch -D ${shellQuote(branch)}` });
|
|
109
|
+
this.run = undefined;
|
|
110
|
+
return {
|
|
111
|
+
ok: true,
|
|
112
|
+
summary: `Boost run aborted (${reason}). Worktree removed${removed.ok ? '' : ' (forced)'} and branch ${branch} deleted. Your working tree was never touched by Boost changes.`
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
async cleanup() {
|
|
116
|
+
if (!this.run)
|
|
117
|
+
return { ok: false, summary: 'No active Boost run.', error: 'no_boost' };
|
|
118
|
+
this.run.phase = 'cleanup';
|
|
119
|
+
const worktree = this.run.worktreePath;
|
|
120
|
+
const branch = this.run.branch;
|
|
121
|
+
this.run = undefined;
|
|
122
|
+
const removed = await this.exec('git_worktree', { mode: 'remove', path: worktree });
|
|
123
|
+
try {
|
|
124
|
+
fs.rmSync(worktree, { recursive: true, force: true });
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
// best effort
|
|
128
|
+
}
|
|
129
|
+
// Safe-delete: only succeeds when the branch is fully merged.
|
|
130
|
+
await this.exec('shell_exec', { command: `git branch -d ${shellQuote(branch)}` });
|
|
131
|
+
return {
|
|
132
|
+
ok: true,
|
|
133
|
+
summary: `Boost cleaned up (worktree ${worktree} removed${removed.ok ? '' : ', with force'}).`
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
export const BOOST_PHASES = ['start', 'investigate', 'implement', 'test', 'verify', 'reconcile', 'abort', 'cleanup'];
|
|
138
|
+
//# sourceMappingURL=boost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"boost.js","sourceRoot":"","sources":["../src/boost.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { ToolResult, TaskPacket, AgentStatus, ContextCheckpoint } from '@ineedcodes/core';
|
|
2
|
+
export type RuntimeEvent = {
|
|
3
|
+
type: 'session-start';
|
|
4
|
+
projectRoot: string;
|
|
5
|
+
model: string;
|
|
6
|
+
} | {
|
|
7
|
+
type: 'turn-start';
|
|
8
|
+
turn: number;
|
|
9
|
+
} | {
|
|
10
|
+
type: 'assistant-message';
|
|
11
|
+
text: string;
|
|
12
|
+
} | {
|
|
13
|
+
type: 'thinking';
|
|
14
|
+
text: string;
|
|
15
|
+
} | {
|
|
16
|
+
type: 'tool-start';
|
|
17
|
+
tool: string;
|
|
18
|
+
input: unknown;
|
|
19
|
+
} | {
|
|
20
|
+
type: 'tool-result';
|
|
21
|
+
tool: string;
|
|
22
|
+
result: ToolResult;
|
|
23
|
+
} | {
|
|
24
|
+
type: 'agent-spawned';
|
|
25
|
+
taskId: string;
|
|
26
|
+
capability: string;
|
|
27
|
+
objective: string;
|
|
28
|
+
} | {
|
|
29
|
+
type: 'agent-status';
|
|
30
|
+
taskId: string;
|
|
31
|
+
status: AgentStatus;
|
|
32
|
+
} | {
|
|
33
|
+
type: 'agent-result';
|
|
34
|
+
taskId: string;
|
|
35
|
+
summary: string;
|
|
36
|
+
} | {
|
|
37
|
+
type: 'boost-phase';
|
|
38
|
+
phase: string;
|
|
39
|
+
detail?: string;
|
|
40
|
+
} | {
|
|
41
|
+
type: 'compaction';
|
|
42
|
+
checkpoint: ContextCheckpoint;
|
|
43
|
+
} | {
|
|
44
|
+
type: 'permission-denied';
|
|
45
|
+
tool: string;
|
|
46
|
+
reason: string;
|
|
47
|
+
} | {
|
|
48
|
+
type: 'memory-write';
|
|
49
|
+
content: string;
|
|
50
|
+
} | {
|
|
51
|
+
type: 'skill-invoked';
|
|
52
|
+
name: string;
|
|
53
|
+
} | {
|
|
54
|
+
type: 'turn-end';
|
|
55
|
+
turn: number;
|
|
56
|
+
stopReason: string;
|
|
57
|
+
} | {
|
|
58
|
+
type: 'session-end';
|
|
59
|
+
};
|
|
60
|
+
export type EventListener = (event: RuntimeEvent) => void | Promise<void>;
|
|
61
|
+
/** Tiny synchronous event bus shared by the lead agent, orchestrator, and CLI. */
|
|
62
|
+
export declare class EventBus {
|
|
63
|
+
private listeners;
|
|
64
|
+
on(listener: EventListener): () => void;
|
|
65
|
+
emit(event: RuntimeEvent): Promise<void>;
|
|
66
|
+
}
|
|
67
|
+
export type { TaskPacket };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Tiny synchronous event bus shared by the lead agent, orchestrator, and CLI. */
|
|
2
|
+
export class EventBus {
|
|
3
|
+
listeners = [];
|
|
4
|
+
on(listener) {
|
|
5
|
+
this.listeners.push(listener);
|
|
6
|
+
return () => {
|
|
7
|
+
this.listeners = this.listeners.filter((l) => l !== listener);
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
async emit(event) {
|
|
11
|
+
for (const listener of this.listeners) {
|
|
12
|
+
await listener(event);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../src/events.ts"],"names":[],"mappings":"AAsBA,kFAAkF;AAClF,MAAM,OAAO,QAAQ;IACX,SAAS,GAAoB,EAAE,CAAC;IAExC,EAAE,CAAC,QAAuB;QACxB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC9B,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC;QAChE,CAAC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAmB;QAC5B,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACtC,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { JsonValue, LLMProvider, MemoryProvider, PermissionEngine, SessionState, ToolRegistry, WorkspaceInfo } from '@ineedcodes/core';
|
|
2
|
+
import { SkillLoader } from '@ineedcodes/core';
|
|
3
|
+
import { type ApprovalRequest, type RuntimeOutcome } from './runtime.js';
|
|
4
|
+
import { EventBus, type EventListener } from './events.js';
|
|
5
|
+
import { Orchestrator } from './orchestrator.js';
|
|
6
|
+
import { type ExplanationDepth } from './system-prompts.js';
|
|
7
|
+
import type { IneedcodesConfig } from '@ineedcodes/core';
|
|
8
|
+
export interface LeadAgentOptions {
|
|
9
|
+
config: IneedcodesConfig;
|
|
10
|
+
registry: ToolRegistry;
|
|
11
|
+
permissions: PermissionEngine;
|
|
12
|
+
provider: LLMProvider;
|
|
13
|
+
workspace: WorkspaceInfo;
|
|
14
|
+
eventBus: EventBus;
|
|
15
|
+
depth: ExplanationDepth;
|
|
16
|
+
maxTurns?: number;
|
|
17
|
+
/** plan = analysis only (read-only tools); build = full autonomy. Default: build. */
|
|
18
|
+
mode?: 'plan' | 'build';
|
|
19
|
+
reasoningEffort?: 'low' | 'medium' | 'high';
|
|
20
|
+
requestApproval?: (req: ApprovalRequest) => Promise<boolean>;
|
|
21
|
+
signal?: AbortSignal;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* The Lead Agent is the authoritative coordinator of a session.
|
|
25
|
+
*/
|
|
26
|
+
export declare class LeadAgent {
|
|
27
|
+
private readonly opts;
|
|
28
|
+
readonly eventBus: EventBus;
|
|
29
|
+
private readonly orchestrator;
|
|
30
|
+
private memory;
|
|
31
|
+
private messages;
|
|
32
|
+
private objective;
|
|
33
|
+
private depth;
|
|
34
|
+
private mode;
|
|
35
|
+
private reasoningEffort;
|
|
36
|
+
private readonly skillsLoader;
|
|
37
|
+
private skillCache;
|
|
38
|
+
constructor(opts: LeadAgentOptions);
|
|
39
|
+
init(): Promise<void>;
|
|
40
|
+
setDepth(depth: ExplanationDepth): void;
|
|
41
|
+
getMode(): 'plan' | 'build';
|
|
42
|
+
setMode(mode: 'plan' | 'build'): void;
|
|
43
|
+
getReasoningEffort(): 'low' | 'medium' | 'high';
|
|
44
|
+
setReasoningEffort(effort: 'low' | 'medium' | 'high'): void;
|
|
45
|
+
/** Hot-swap the LLM provider (e.g. after /model) without restarting the session. */
|
|
46
|
+
setProvider(provider: LLMProvider): void;
|
|
47
|
+
/**
|
|
48
|
+
* Reasoning effort changes real execution budget, not just a request flag:
|
|
49
|
+
* low = quick answers (fewer turns), high = deep work (many more turns).
|
|
50
|
+
*/
|
|
51
|
+
private effectiveMaxTurns;
|
|
52
|
+
/** Fresh session: forget conversation and sub-agents (memory is durable, it stays). */
|
|
53
|
+
resetSession(): void;
|
|
54
|
+
/** Context usage breakdown for the /context command. */
|
|
55
|
+
contextStats(): {
|
|
56
|
+
system: number;
|
|
57
|
+
conversation: number;
|
|
58
|
+
tools: number;
|
|
59
|
+
total: number;
|
|
60
|
+
limit: number;
|
|
61
|
+
compactsAt: number;
|
|
62
|
+
};
|
|
63
|
+
getMemories(): MemoryProvider;
|
|
64
|
+
getOrchestrator(): Orchestrator;
|
|
65
|
+
listSkills(): Awaited<ReturnType<SkillLoader['list']>>;
|
|
66
|
+
reloadSkills(): Promise<void>;
|
|
67
|
+
getSkillText(name: string): string | undefined;
|
|
68
|
+
on(listener: EventListener): () => void;
|
|
69
|
+
private emitEvent;
|
|
70
|
+
private systemPromptFor;
|
|
71
|
+
recallMemories(objective: string): Promise<string[]>;
|
|
72
|
+
/**
|
|
73
|
+
* Run a user objective through the full loop:
|
|
74
|
+
* recall → inspect → reason → act → observe → verify.
|
|
75
|
+
*/
|
|
76
|
+
runObjective(objective: string): Promise<RuntimeOutcome>;
|
|
77
|
+
/** Continue the current session with a new user message. */
|
|
78
|
+
continueSession(userMessage: string): Promise<RuntimeOutcome>;
|
|
79
|
+
private toolContext;
|
|
80
|
+
private recordOutcome;
|
|
81
|
+
private extractDurableKnowledge;
|
|
82
|
+
toSessionState(sessionId: string): SessionState;
|
|
83
|
+
restore(state: SessionState): void;
|
|
84
|
+
}
|
|
85
|
+
export type { RuntimeOutcome, ApprovalRequest, JsonValue };
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { createMemoryProvider, SkillLoader, ProcessManager, estimateTokens } from '@ineedcodes/core';
|
|
2
|
+
import { AgentRuntime } from './runtime.js';
|
|
3
|
+
import { Orchestrator } from './orchestrator.js';
|
|
4
|
+
import { buildSystemPrompt } from './system-prompts.js';
|
|
5
|
+
/**
|
|
6
|
+
* The Lead Agent is the authoritative coordinator of a session.
|
|
7
|
+
*/
|
|
8
|
+
export class LeadAgent {
|
|
9
|
+
opts;
|
|
10
|
+
eventBus;
|
|
11
|
+
orchestrator;
|
|
12
|
+
memory;
|
|
13
|
+
messages = [];
|
|
14
|
+
objective = '';
|
|
15
|
+
depth;
|
|
16
|
+
mode;
|
|
17
|
+
reasoningEffort;
|
|
18
|
+
skillsLoader;
|
|
19
|
+
skillCache = [];
|
|
20
|
+
constructor(opts) {
|
|
21
|
+
this.opts = opts;
|
|
22
|
+
this.eventBus = opts.eventBus;
|
|
23
|
+
this.memory = createMemoryProvider(opts.config.memory.backend, opts.workspace.projectId, opts.workspace.projectRoot);
|
|
24
|
+
this.orchestrator = new Orchestrator(opts.config.permissions.maxParallelAgents);
|
|
25
|
+
this.depth = opts.depth;
|
|
26
|
+
this.mode = opts.mode ?? 'build';
|
|
27
|
+
this.reasoningEffort = opts.reasoningEffort ?? 'medium';
|
|
28
|
+
this.skillsLoader = new SkillLoader(opts.workspace.projectRoot);
|
|
29
|
+
}
|
|
30
|
+
async init() {
|
|
31
|
+
this.skillCache = await this.skillsLoader.list();
|
|
32
|
+
}
|
|
33
|
+
setDepth(depth) {
|
|
34
|
+
this.depth = depth;
|
|
35
|
+
}
|
|
36
|
+
getMode() {
|
|
37
|
+
return this.mode;
|
|
38
|
+
}
|
|
39
|
+
setMode(mode) {
|
|
40
|
+
this.mode = mode;
|
|
41
|
+
}
|
|
42
|
+
getReasoningEffort() {
|
|
43
|
+
return this.reasoningEffort;
|
|
44
|
+
}
|
|
45
|
+
setReasoningEffort(effort) {
|
|
46
|
+
this.reasoningEffort = effort;
|
|
47
|
+
}
|
|
48
|
+
/** Hot-swap the LLM provider (e.g. after /model) without restarting the session. */
|
|
49
|
+
setProvider(provider) {
|
|
50
|
+
this.opts.provider = provider;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Reasoning effort changes real execution budget, not just a request flag:
|
|
54
|
+
* low = quick answers (fewer turns), high = deep work (many more turns).
|
|
55
|
+
*/
|
|
56
|
+
effectiveMaxTurns() {
|
|
57
|
+
if (this.opts.maxTurns !== undefined)
|
|
58
|
+
return this.opts.maxTurns;
|
|
59
|
+
if (this.reasoningEffort === 'low')
|
|
60
|
+
return 20;
|
|
61
|
+
if (this.reasoningEffort === 'high')
|
|
62
|
+
return 80;
|
|
63
|
+
return 40;
|
|
64
|
+
}
|
|
65
|
+
/** Fresh session: forget conversation and sub-agents (memory is durable, it stays). */
|
|
66
|
+
resetSession() {
|
|
67
|
+
this.messages = [];
|
|
68
|
+
this.objective = '';
|
|
69
|
+
this.orchestrator.clear();
|
|
70
|
+
}
|
|
71
|
+
/** Context usage breakdown for the /context command. */
|
|
72
|
+
contextStats() {
|
|
73
|
+
let system = 0;
|
|
74
|
+
let tools = 0;
|
|
75
|
+
let conversation = 0;
|
|
76
|
+
for (const m of this.messages) {
|
|
77
|
+
const t = estimateTokens(m.content ?? '') + (m.toolCalls ?? []).reduce((a, tc) => a + estimateTokens(tc.arguments), 0);
|
|
78
|
+
if (m.role === 'system')
|
|
79
|
+
system += t;
|
|
80
|
+
else if (m.role === 'tool')
|
|
81
|
+
tools += t;
|
|
82
|
+
else
|
|
83
|
+
conversation += t;
|
|
84
|
+
}
|
|
85
|
+
const limit = this.opts.provider.contextLimit;
|
|
86
|
+
return { system, conversation, tools, total: system + conversation + tools, limit, compactsAt: Math.round(limit * 0.75) };
|
|
87
|
+
}
|
|
88
|
+
getMemories() {
|
|
89
|
+
return this.memory;
|
|
90
|
+
}
|
|
91
|
+
getOrchestrator() {
|
|
92
|
+
return this.orchestrator;
|
|
93
|
+
}
|
|
94
|
+
listSkills() {
|
|
95
|
+
return this.skillCache;
|
|
96
|
+
}
|
|
97
|
+
async reloadSkills() {
|
|
98
|
+
this.skillCache = await this.skillsLoader.list();
|
|
99
|
+
}
|
|
100
|
+
getSkillText(name) {
|
|
101
|
+
return this.skillCache.find((s) => s.name.toLowerCase() === name.toLowerCase())?.instructions;
|
|
102
|
+
}
|
|
103
|
+
on(listener) {
|
|
104
|
+
return this.eventBus.on(listener);
|
|
105
|
+
}
|
|
106
|
+
emitEvent(event) {
|
|
107
|
+
return this.eventBus.emit(event);
|
|
108
|
+
}
|
|
109
|
+
systemPromptFor(objective, extraMemories = []) {
|
|
110
|
+
return buildSystemPrompt({
|
|
111
|
+
objective,
|
|
112
|
+
workspace: this.opts.workspace,
|
|
113
|
+
skills: this.skillCache,
|
|
114
|
+
memories: extraMemories,
|
|
115
|
+
depth: this.depth,
|
|
116
|
+
permissionMode: this.opts.permissions.currentMode,
|
|
117
|
+
mode: this.mode,
|
|
118
|
+
reasoningEffort: this.reasoningEffort
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
async recallMemories(objective) {
|
|
122
|
+
try {
|
|
123
|
+
const records = await this.memory.recall(objective, 5);
|
|
124
|
+
return records.map((r) => r.content);
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return [];
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Run a user objective through the full loop:
|
|
132
|
+
* recall → inspect → reason → act → observe → verify.
|
|
133
|
+
*/
|
|
134
|
+
async runObjective(objective) {
|
|
135
|
+
this.objective = objective;
|
|
136
|
+
await this.emitEvent({ type: 'session-start', projectRoot: this.opts.workspace.projectRoot, model: this.opts.provider.model });
|
|
137
|
+
const memories = await this.recallMemories(objective);
|
|
138
|
+
if (memories.length) {
|
|
139
|
+
await this.emitEvent({ type: 'thinking', text: `Recalled ${memories.length} relevant memory item(s).` });
|
|
140
|
+
}
|
|
141
|
+
const runtime = new AgentRuntime({
|
|
142
|
+
provider: this.opts.provider,
|
|
143
|
+
registry: this.opts.registry,
|
|
144
|
+
memory: this.memory,
|
|
145
|
+
toolContext: this.toolContext(),
|
|
146
|
+
systemPrompt: this.systemPromptFor(objective, memories),
|
|
147
|
+
maxTurns: this.effectiveMaxTurns(),
|
|
148
|
+
mode: this.mode,
|
|
149
|
+
reasoningEffort: this.reasoningEffort
|
|
150
|
+
}, (event) => this.emitEvent(event), this.opts.requestApproval, this.messages, this.opts.signal);
|
|
151
|
+
const outcome = await runtime.run(objective);
|
|
152
|
+
this.messages = [...runtime.messages];
|
|
153
|
+
await this.recordOutcome(objective, outcome);
|
|
154
|
+
await this.emitEvent({ type: 'session-end' });
|
|
155
|
+
return outcome;
|
|
156
|
+
}
|
|
157
|
+
/** Continue the current session with a new user message. */
|
|
158
|
+
async continueSession(userMessage) {
|
|
159
|
+
return this.runObjective(userMessage);
|
|
160
|
+
}
|
|
161
|
+
toolContext() {
|
|
162
|
+
// The CLI normally registers a shared process manager on globalThis;
|
|
163
|
+
// library/embedded usage creates one on demand instead of failing.
|
|
164
|
+
let pm = globalThis['__ineedcodesProcessManager'];
|
|
165
|
+
if (!pm) {
|
|
166
|
+
pm = new ProcessManager();
|
|
167
|
+
globalThis['__ineedcodesProcessManager'] = pm;
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
workspaceRoot: this.opts.workspace.projectRoot,
|
|
171
|
+
cwd: this.opts.workspace.root,
|
|
172
|
+
permissions: this.opts.permissions,
|
|
173
|
+
processManager: pm
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
async recordOutcome(objective, outcome) {
|
|
177
|
+
if (outcome.stopReason !== 'complete')
|
|
178
|
+
return;
|
|
179
|
+
// Store durable knowledge, not chat dumps (plan §14–15).
|
|
180
|
+
const durable = await this.extractDurableKnowledge(objective, outcome);
|
|
181
|
+
if (durable) {
|
|
182
|
+
try {
|
|
183
|
+
await this.memory.remember(durable, ['session', 'outcome']);
|
|
184
|
+
await this.emitEvent({ type: 'memory-write', content: durable });
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
// memory failures never break the session
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
async extractDurableKnowledge(objective, outcome) {
|
|
192
|
+
try {
|
|
193
|
+
const response = await this.opts.provider.complete({
|
|
194
|
+
messages: [
|
|
195
|
+
{
|
|
196
|
+
role: 'system',
|
|
197
|
+
content: 'Decide whether this completed task produced durable knowledge worth remembering for future sessions ' +
|
|
198
|
+
'in this project (conventions, solved errors, environment facts, decisions). If yes, output one ' +
|
|
199
|
+
'concise memory sentence. If nothing is durable, output exactly NONE.'
|
|
200
|
+
},
|
|
201
|
+
{ role: 'user', content: `Objective: ${objective}\nOutcome: ${outcome.finalMessage.slice(0, 2000)}` }
|
|
202
|
+
],
|
|
203
|
+
temperature: 0,
|
|
204
|
+
maxTokens: 200
|
|
205
|
+
});
|
|
206
|
+
const text = (response.content ?? 'NONE').trim();
|
|
207
|
+
if (!text || text.toUpperCase().startsWith('NONE'))
|
|
208
|
+
return null;
|
|
209
|
+
return `Objective: ${objective.slice(0, 200)}: ${text.slice(0, 500)}`;
|
|
210
|
+
}
|
|
211
|
+
catch {
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
toSessionState(sessionId) {
|
|
216
|
+
return {
|
|
217
|
+
sessionId,
|
|
218
|
+
projectRoot: this.opts.workspace.projectRoot,
|
|
219
|
+
model: this.opts.provider.model,
|
|
220
|
+
objective: this.objective,
|
|
221
|
+
messages: this.messages,
|
|
222
|
+
agents: this.orchestrator.list(),
|
|
223
|
+
createdAt: new Date().toISOString(),
|
|
224
|
+
updatedAt: new Date().toISOString()
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
restore(state) {
|
|
228
|
+
this.messages = state.messages ?? [];
|
|
229
|
+
this.objective = state.objective ?? '';
|
|
230
|
+
for (const agent of state.agents ?? []) {
|
|
231
|
+
this.orchestrator.restore(agent);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
//# sourceMappingURL=lead-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lead-agent.js","sourceRoot":"","sources":["../src/lead-agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { AgentCapability, AgentRecord, TaskPacket, TaskResult } from '@ineedcodes/core';
|
|
2
|
+
/**
|
|
3
|
+
* Native multi-agent orchestrator (plan §9–11).
|
|
4
|
+
* Sub-agents are real isolated contexts, not simulated personas in one prompt.
|
|
5
|
+
* The Lead Agent remains the authoritative coordinator.
|
|
6
|
+
*/
|
|
7
|
+
export declare class Orchestrator {
|
|
8
|
+
private maxParallel;
|
|
9
|
+
private agents;
|
|
10
|
+
constructor(maxParallel?: number);
|
|
11
|
+
setMaxParallel(n: number): void;
|
|
12
|
+
get runningCount(): number;
|
|
13
|
+
createTask(opts: {
|
|
14
|
+
capability: AgentCapability;
|
|
15
|
+
objective: string;
|
|
16
|
+
parentAgentId: string;
|
|
17
|
+
context?: string;
|
|
18
|
+
constraints?: string[];
|
|
19
|
+
availableTools?: string[];
|
|
20
|
+
workspace?: string;
|
|
21
|
+
expectedResult?: string;
|
|
22
|
+
}): TaskPacket;
|
|
23
|
+
canStartMore(): boolean;
|
|
24
|
+
setStatus(taskId: string, status: AgentRecord['status']): void;
|
|
25
|
+
finish(taskId: string, result: TaskResult): void;
|
|
26
|
+
get(taskId: string): AgentRecord | undefined;
|
|
27
|
+
list(): AgentRecord[];
|
|
28
|
+
/** Forget all agents (used by /clear). */
|
|
29
|
+
clear(): void;
|
|
30
|
+
pendingTasks(): AgentRecord[];
|
|
31
|
+
restore(record: AgentRecord): void;
|
|
32
|
+
/**
|
|
33
|
+
* Run a set of task packets in parallel (bounded by maxParallel).
|
|
34
|
+
* Each worker gets its own AgentRuntime instance via the factory.
|
|
35
|
+
*/
|
|
36
|
+
runParallel(packets: TaskPacket[], worker: (packet: TaskPacket) => Promise<TaskResult>, hooks?: {
|
|
37
|
+
onStatus?: (taskId: string, status: AgentRecord['status']) => Promise<void>;
|
|
38
|
+
onResult?: (taskId: string, result: TaskResult) => Promise<void>;
|
|
39
|
+
}): Promise<Map<string, TaskResult>>;
|
|
40
|
+
}
|
|
41
|
+
/** Serialize a task result into compact text for the Lead Agent context. */
|
|
42
|
+
export declare function summarizeTaskResults(results: Map<string, TaskResult>): string;
|
|
43
|
+
export declare function worktreePathFor(projectRoot: string, label: string): string;
|