pilot-ai 0.4.0 → 0.5.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/README.md +75 -5
- package/dist/agent/claude.d.ts +7 -0
- package/dist/agent/claude.d.ts.map +1 -1
- package/dist/agent/claude.js +30 -2
- package/dist/agent/claude.js.map +1 -1
- package/dist/agent/core.d.ts +3 -0
- package/dist/agent/core.d.ts.map +1 -1
- package/dist/agent/core.js +87 -6
- package/dist/agent/core.js.map +1 -1
- package/dist/agent/queue.d.ts +12 -7
- package/dist/agent/queue.d.ts.map +1 -1
- package/dist/agent/queue.js +89 -0
- package/dist/agent/queue.js.map +1 -1
- package/dist/agent/session.d.ts +44 -0
- package/dist/agent/session.d.ts.map +1 -0
- package/dist/agent/session.js +131 -0
- package/dist/agent/session.js.map +1 -0
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +17 -2
- package/dist/api/server.js.map +1 -1
- package/dist/cli/doctor.d.ts +2 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +198 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +51 -1
- package/dist/cli/init.js.map +1 -1
- package/dist/config/schema.d.ts +6 -0
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +9 -0
- package/dist/config/schema.js.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/messenger/slack.d.ts +1 -0
- package/dist/messenger/slack.d.ts.map +1 -1
- package/dist/messenger/slack.js +15 -6
- package/dist/messenger/slack.js.map +1 -1
- package/dist/messenger/split.d.ts +16 -0
- package/dist/messenger/split.d.ts.map +1 -0
- package/dist/messenger/split.js +66 -0
- package/dist/messenger/split.js.map +1 -0
- package/dist/messenger/telegram.d.ts +1 -0
- package/dist/messenger/telegram.d.ts.map +1 -1
- package/dist/messenger/telegram.js +14 -5
- package/dist/messenger/telegram.js.map +1 -1
- package/dist/security/permissions.d.ts +7 -0
- package/dist/security/permissions.d.ts.map +1 -1
- package/dist/security/permissions.js +57 -1
- package/dist/security/permissions.js.map +1 -1
- package/dist/security/sandbox.d.ts +1 -0
- package/dist/security/sandbox.d.ts.map +1 -1
- package/dist/security/sandbox.js +61 -4
- package/dist/security/sandbox.js.map +1 -1
- package/dist/tools/calendar.d.ts.map +1 -1
- package/dist/tools/calendar.js +9 -14
- package/dist/tools/calendar.js.map +1 -1
- package/dist/tools/clipboard.d.ts.map +1 -1
- package/dist/tools/clipboard.js +2 -2
- package/dist/tools/clipboard.js.map +1 -1
- package/dist/tools/email.d.ts +1 -0
- package/dist/tools/email.d.ts.map +1 -1
- package/dist/tools/email.js +26 -4
- package/dist/tools/email.js.map +1 -1
- package/dist/tools/filesystem.d.ts.map +1 -1
- package/dist/tools/filesystem.js +22 -6
- package/dist/tools/filesystem.js.map +1 -1
- package/dist/tools/github.d.ts.map +1 -1
- package/dist/tools/github.js +20 -0
- package/dist/tools/github.js.map +1 -1
- package/dist/tools/google-auth.d.ts +1 -0
- package/dist/tools/google-auth.d.ts.map +1 -1
- package/dist/tools/google-auth.js +26 -4
- package/dist/tools/google-auth.js.map +1 -1
- package/dist/tools/notification.d.ts.map +1 -1
- package/dist/tools/notification.js +2 -7
- package/dist/tools/notification.js.map +1 -1
- package/dist/tools/obsidian.d.ts.map +1 -1
- package/dist/tools/obsidian.js +23 -3
- package/dist/tools/obsidian.js.map +1 -1
- package/dist/utils/circuit-breaker.d.ts +30 -0
- package/dist/utils/circuit-breaker.d.ts.map +1 -0
- package/dist/utils/circuit-breaker.js +69 -0
- package/dist/utils/circuit-breaker.js.map +1 -0
- package/dist/utils/errors.d.ts +55 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +79 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/escape.d.ts +15 -0
- package/dist/utils/escape.d.ts.map +1 -0
- package/dist/utils/escape.js +23 -0
- package/dist/utils/escape.js.map +1 -0
- package/dist/utils/logger.d.ts +39 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +119 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/oauth-manager.d.ts +49 -0
- package/dist/utils/oauth-manager.d.ts.map +1 -0
- package/dist/utils/oauth-manager.js +112 -0
- package/dist/utils/oauth-manager.js.map +1 -0
- package/dist/utils/rate-limiter.d.ts +24 -0
- package/dist/utils/rate-limiter.d.ts.map +1 -0
- package/dist/utils/rate-limiter.js +52 -0
- package/dist/utils/rate-limiter.js.map +1 -0
- package/dist/utils/retry.d.ts +20 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +45 -0
- package/dist/utils/retry.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
<img src="design/logo_light.svg" alt="Pilot-AI Logo" width="360" />
|
|
6
|
-
</picture>
|
|
2
|
+
<a href="https://github.com/ahn283/pilot-ai">
|
|
3
|
+
<img src="https://raw.githubusercontent.com/ahn283/pilot-ai/main/design/logo_light.svg" alt="Pilot-AI Logo" width="360" />
|
|
4
|
+
</a>
|
|
7
5
|
</p>
|
|
8
6
|
|
|
9
7
|
<p align="center">
|
|
@@ -56,6 +54,8 @@ Pilot-AI is a local AI agent that lives on your Mac. Send it natural-language co
|
|
|
56
54
|
- **Notion integration** — search, create, update pages and databases
|
|
57
55
|
- **Google integration** — Gmail, Google Calendar, and Google Drive via OAuth2
|
|
58
56
|
- **MCP auto-discovery** — agent detects needed MCP servers and proposes installation with one-click approval
|
|
57
|
+
- **Coding agent** — writes code, runs builds, executes tests, and iterates until the task is done
|
|
58
|
+
- **Session continuity** — messages in the same thread share a Claude session with full conversation context
|
|
59
59
|
- **Scheduled tasks** — cron-like jobs with natural language scheduling
|
|
60
60
|
- **Skills system** — teach the agent reusable procedures
|
|
61
61
|
- **Project awareness** — resolves projects, remembers context per project
|
|
@@ -126,6 +126,76 @@ Just message your agent in Slack or Telegram:
|
|
|
126
126
|
| `Send a draft email to john@example.com` | Composes a Gmail draft with the given content |
|
|
127
127
|
| `List files in my Google Drive "Projects" folder` | Browses Google Drive and lists folder contents |
|
|
128
128
|
|
|
129
|
+
### Coding Sessions
|
|
130
|
+
|
|
131
|
+
The agent can write, build, test, and iterate on code — just like Claude Code. Messages in the same thread maintain full conversation context:
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
You: "Add a /health endpoint to the API server in fridgify"
|
|
135
|
+
Agent: ✏️ Editing file... ⚡ Running: npm run build... ✅ Done!
|
|
136
|
+
Added GET /health endpoint returning { status: "ok", uptime: ... }
|
|
137
|
+
Build passes, tests pass.
|
|
138
|
+
|
|
139
|
+
You: "Also add a test for it" ← same thread, agent remembers context
|
|
140
|
+
Agent: ✏️ Writing test... ⚡ Running: npm test...
|
|
141
|
+
Added test in tests/api/health.test.ts — 3 assertions, all pass.
|
|
142
|
+
|
|
143
|
+
You: "Commit and push"
|
|
144
|
+
Agent: 📂 Checking git... ⚡ Running: git commit...
|
|
145
|
+
Committed: "feat: add /health endpoint" and pushed to origin/main.
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Each Slack/Telegram thread maps to a persistent Claude session. The agent retains full context across messages — no need to repeat yourself.
|
|
149
|
+
|
|
150
|
+
### Project Development
|
|
151
|
+
|
|
152
|
+
For larger features or new projects, the agent follows a structured development workflow — planning first, then implementing step by step:
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
You: "Add OAuth2 login to the fridgify API"
|
|
156
|
+
Agent: 📋 Let me plan this out first.
|
|
157
|
+
|
|
158
|
+
**PRD (Product Requirements)**
|
|
159
|
+
- Add OAuth2 authorization code flow with Google provider
|
|
160
|
+
- Endpoints: /auth/login, /auth/callback, /auth/me
|
|
161
|
+
- Store tokens in DB, issue JWT sessions
|
|
162
|
+
- ...
|
|
163
|
+
|
|
164
|
+
**Checklist**
|
|
165
|
+
- [ ] Add google-auth config schema
|
|
166
|
+
- [ ] Implement /auth/login redirect endpoint
|
|
167
|
+
- [ ] Implement /auth/callback token exchange
|
|
168
|
+
- [ ] Add JWT session middleware
|
|
169
|
+
- [ ] Add /auth/me endpoint
|
|
170
|
+
- [ ] Write tests for each endpoint
|
|
171
|
+
|
|
172
|
+
Does this look good?
|
|
173
|
+
|
|
174
|
+
You: "Looks good, go ahead"
|
|
175
|
+
Agent: ⚡ Starting checklist item 1: google-auth config schema
|
|
176
|
+
✏️ Writing src/config/auth.ts...
|
|
177
|
+
🔨 npm run build — ✅ passed
|
|
178
|
+
🧪 npm test — ✅ 3 new tests pass
|
|
179
|
+
✅ Committed: "feat: add google-auth config schema"
|
|
180
|
+
|
|
181
|
+
⚡ Item 2: /auth/login redirect endpoint
|
|
182
|
+
✏️ Writing src/routes/auth.ts...
|
|
183
|
+
🔨 npm run build — ✅ passed
|
|
184
|
+
🧪 npm test — ✅ 5 new tests pass
|
|
185
|
+
✅ Committed: "feat: add /auth/login redirect endpoint"
|
|
186
|
+
|
|
187
|
+
... (continues through checklist)
|
|
188
|
+
|
|
189
|
+
✅ All 6 checklist items complete. OAuth2 login is ready.
|
|
190
|
+
|
|
191
|
+
You: "Actually, also support GitHub login" ← requirements change
|
|
192
|
+
Agent: 📋 Updating PRD and checklist first...
|
|
193
|
+
Added 3 new checklist items for GitHub provider.
|
|
194
|
+
Proceeding with implementation...
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
The agent writes a PRD and checklist before touching any code, gets your confirmation, then works through each item with build/test verification — just like a real development workflow.
|
|
198
|
+
|
|
129
199
|
## CLI Reference
|
|
130
200
|
|
|
131
201
|
```bash
|
package/dist/agent/claude.d.ts
CHANGED
|
@@ -6,6 +6,10 @@ export interface ClaudeCliOptions {
|
|
|
6
6
|
mcpConfigPath?: string;
|
|
7
7
|
timeoutMs?: number;
|
|
8
8
|
onToolUse?: (status: string) => void;
|
|
9
|
+
/** Start a new session with this UUID */
|
|
10
|
+
sessionId?: string;
|
|
11
|
+
/** Resume an existing session by its UUID */
|
|
12
|
+
resumeSessionId?: string;
|
|
9
13
|
}
|
|
10
14
|
export interface ClaudeCliResult {
|
|
11
15
|
result: string;
|
|
@@ -31,9 +35,12 @@ export declare function checkClaudeCli(binary?: string): Promise<boolean>;
|
|
|
31
35
|
* Checks whether the Claude CLI is authenticated using `claude auth status`.
|
|
32
36
|
*/
|
|
33
37
|
export declare function checkClaudeCliAuth(binary?: string): Promise<boolean>;
|
|
38
|
+
/** Expose circuit breaker state for health checks */
|
|
39
|
+
export declare function getClaudeCircuitState(): import("../utils/circuit-breaker.js").CircuitState;
|
|
34
40
|
/**
|
|
35
41
|
* Invokes the Claude Code CLI as a subprocess.
|
|
36
42
|
* Runs `claude -p --output-format json` and parses the JSON response.
|
|
43
|
+
* Protected by a circuit breaker to fail fast when Claude CLI is unavailable.
|
|
37
44
|
*/
|
|
38
45
|
export declare function invokeClaudeCli(options: ClaudeCliOptions): Promise<ClaudeCliResult>;
|
|
39
46
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/agent/claude.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/agent/claude.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,yCAAyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACjD,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAID,+EAA+E;AAC/E,eAAO,MAAM,qBAAqB,UAYjC,CAAC;AAEF;;GAEG;AACH,wBAAsB,cAAc,CAAC,MAAM,GAAE,MAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CAOhF;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,GAAE,MAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CAapF;AA8BD,qDAAqD;AACrD,wBAAgB,qBAAqB,uDAEpC;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAEzF;AA4GD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CA4B5D;AAED;;GAEG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBlB"}
|
package/dist/agent/claude.js
CHANGED
|
@@ -2,7 +2,13 @@ import { spawn } from 'node:child_process';
|
|
|
2
2
|
import { execFile } from 'node:child_process';
|
|
3
3
|
import { promisify } from 'node:util';
|
|
4
4
|
import Anthropic from '@anthropic-ai/sdk';
|
|
5
|
+
import { CircuitBreaker } from '../utils/circuit-breaker.js';
|
|
5
6
|
const execFileAsync = promisify(execFile);
|
|
7
|
+
/** Circuit breaker for Claude CLI invocations */
|
|
8
|
+
const claudeCircuit = new CircuitBreaker({
|
|
9
|
+
failureThreshold: 3,
|
|
10
|
+
resetTimeout: 120_000, // 2 minutes
|
|
11
|
+
});
|
|
6
12
|
const DEFAULT_TIMEOUT_MS = 15 * 60 * 1000; // 15 minutes (agentic tasks take longer)
|
|
7
13
|
/** Default tools to pre-approve for claude -p so it can operate agentically */
|
|
8
14
|
export const DEFAULT_ALLOWED_TOOLS = [
|
|
@@ -80,13 +86,31 @@ function describeToolUse(toolName, input) {
|
|
|
80
86
|
default: return `🔧 Using ${toolName}...`;
|
|
81
87
|
}
|
|
82
88
|
}
|
|
89
|
+
/** Expose circuit breaker state for health checks */
|
|
90
|
+
export function getClaudeCircuitState() {
|
|
91
|
+
return claudeCircuit.getState();
|
|
92
|
+
}
|
|
83
93
|
/**
|
|
84
94
|
* Invokes the Claude Code CLI as a subprocess.
|
|
85
95
|
* Runs `claude -p --output-format json` and parses the JSON response.
|
|
96
|
+
* Protected by a circuit breaker to fail fast when Claude CLI is unavailable.
|
|
86
97
|
*/
|
|
87
98
|
export async function invokeClaudeCli(options) {
|
|
88
|
-
|
|
89
|
-
|
|
99
|
+
return claudeCircuit.execute(() => invokeClaudeCliInner(options));
|
|
100
|
+
}
|
|
101
|
+
async function invokeClaudeCliInner(options) {
|
|
102
|
+
const { prompt, systemPrompt, cwd, allowedTools, mcpConfigPath, timeoutMs = DEFAULT_TIMEOUT_MS, onToolUse, sessionId, resumeSessionId } = options;
|
|
103
|
+
const args = [];
|
|
104
|
+
// Session management: --resume takes precedence (continuing existing session)
|
|
105
|
+
if (resumeSessionId) {
|
|
106
|
+
args.push('-p', '--resume', resumeSessionId, '--output-format', 'json');
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
args.push('-p', '--output-format', 'json');
|
|
110
|
+
if (sessionId) {
|
|
111
|
+
args.push('--session-id', sessionId);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
90
114
|
if (cwd) {
|
|
91
115
|
args.push('--cwd', cwd);
|
|
92
116
|
}
|
|
@@ -121,6 +145,10 @@ export async function invokeClaudeCli(options) {
|
|
|
121
145
|
// Stream-parse JSONL lines to detect tool usage in real-time
|
|
122
146
|
if (onToolUse) {
|
|
123
147
|
lineBuffer += chunk;
|
|
148
|
+
// Prevent unbounded buffer growth (max 1MB)
|
|
149
|
+
if (lineBuffer.length > 1_048_576) {
|
|
150
|
+
lineBuffer = lineBuffer.slice(-524_288); // Keep last 512KB
|
|
151
|
+
}
|
|
124
152
|
const lines = lineBuffer.split('\n');
|
|
125
153
|
lineBuffer = lines.pop() ?? '';
|
|
126
154
|
for (const line of lines) {
|
package/dist/agent/claude.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/agent/claude.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,SAAS,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/agent/claude.ts"],"names":[],"mappings":"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"}
|
package/dist/agent/core.d.ts
CHANGED
|
@@ -5,13 +5,16 @@ export declare class AgentCore {
|
|
|
5
5
|
private config;
|
|
6
6
|
private approvalManager;
|
|
7
7
|
private permissionWatcher;
|
|
8
|
+
private githubCheckInterval;
|
|
8
9
|
constructor(messenger: MessengerAdapter, config: PilotConfig);
|
|
9
10
|
private setupHandlers;
|
|
10
11
|
start(): Promise<void>;
|
|
12
|
+
private checkGitHubAuth;
|
|
11
13
|
stop(): Promise<void>;
|
|
12
14
|
private handleMessage;
|
|
13
15
|
/**
|
|
14
16
|
* Resolves project from message, builds memory context, and invokes Claude.
|
|
17
|
+
* Uses session continuity: messages in the same thread share a Claude session.
|
|
15
18
|
*/
|
|
16
19
|
private invokeClaudeWithContext;
|
|
17
20
|
}
|
package/dist/agent/core.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/agent/core.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAmB,MAAM,yBAAyB,CAAC;AACjF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/agent/core.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAmB,MAAM,yBAAyB,CAAC;AACjF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAuBvD,qBAAa,SAAS;IACpB,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,mBAAmB,CAA+C;gBAE9D,SAAS,EAAE,gBAAgB,EAAE,MAAM,EAAE,WAAW;IAkB5D,OAAO,CAAC,aAAa;IAOf,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAgBd,eAAe;IAoBvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAUb,aAAa;IAyG3B;;;OAGG;YACW,uBAAuB;CA0HtC"}
|
package/dist/agent/core.js
CHANGED
|
@@ -11,7 +11,10 @@ import { buildSkillsContext } from './skills.js';
|
|
|
11
11
|
import { buildToolDescriptions } from './tool-descriptions.js';
|
|
12
12
|
import { getMcpConfigPathIfExists } from '../tools/figma-mcp.js';
|
|
13
13
|
import { buildMcpContext } from './mcp-manager.js';
|
|
14
|
+
import { PilotError } from '../utils/errors.js';
|
|
15
|
+
import { getSession, createSession, touchSession, cleanupSessions } from './session.js';
|
|
14
16
|
import { detectPermissionError, PermissionWatcher } from '../security/permissions.js';
|
|
17
|
+
import { isGhAuthenticated } from '../tools/github.js';
|
|
15
18
|
function log(message) {
|
|
16
19
|
console.log(`[${new Date().toISOString()}] ${message}`);
|
|
17
20
|
}
|
|
@@ -20,6 +23,7 @@ export class AgentCore {
|
|
|
20
23
|
config;
|
|
21
24
|
approvalManager;
|
|
22
25
|
permissionWatcher;
|
|
26
|
+
githubCheckInterval = null;
|
|
23
27
|
constructor(messenger, config) {
|
|
24
28
|
this.messenger = messenger;
|
|
25
29
|
this.config = config;
|
|
@@ -48,8 +52,36 @@ export class AgentCore {
|
|
|
48
52
|
log('Messenger connected. Waiting for messages...');
|
|
49
53
|
await this.permissionWatcher.start();
|
|
50
54
|
log('Permission watcher started.');
|
|
55
|
+
// Check GitHub auth status on startup and periodically (every hour)
|
|
56
|
+
this.checkGitHubAuth().catch(() => { });
|
|
57
|
+
if (this.config.github?.enabled) {
|
|
58
|
+
this.githubCheckInterval = setInterval(() => {
|
|
59
|
+
this.checkGitHubAuth().catch(() => { });
|
|
60
|
+
}, 60 * 60 * 1000);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async checkGitHubAuth() {
|
|
64
|
+
if (!this.config.github?.enabled)
|
|
65
|
+
return;
|
|
66
|
+
const authed = await isGhAuthenticated();
|
|
67
|
+
if (!authed) {
|
|
68
|
+
log('GitHub CLI is not authenticated.');
|
|
69
|
+
const users = this.config.messenger.platform === 'slack'
|
|
70
|
+
? this.config.security.allowedUsers.slack
|
|
71
|
+
: this.config.security.allowedUsers.telegram;
|
|
72
|
+
if (users.length > 0) {
|
|
73
|
+
await this.messenger.sendText(users[0], '⚠️ GitHub CLI is not authenticated. Run `gh auth login` to reconnect.');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
log('GitHub CLI authenticated.');
|
|
78
|
+
}
|
|
51
79
|
}
|
|
52
80
|
async stop() {
|
|
81
|
+
if (this.githubCheckInterval) {
|
|
82
|
+
clearInterval(this.githubCheckInterval);
|
|
83
|
+
this.githubCheckInterval = null;
|
|
84
|
+
}
|
|
53
85
|
this.permissionWatcher.stop();
|
|
54
86
|
log('Stopping messenger...');
|
|
55
87
|
await this.messenger.stop();
|
|
@@ -122,11 +154,18 @@ export class AgentCore {
|
|
|
122
154
|
log(`Claude error: ${errorMsg}`);
|
|
123
155
|
await this.messenger.removeReaction?.(msg.channelId, incomingTs, 'gear');
|
|
124
156
|
await this.messenger.addReaction?.(msg.channelId, incomingTs, 'x');
|
|
125
|
-
//
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
157
|
+
// Determine user-friendly message based on error type
|
|
158
|
+
let displayMsg;
|
|
159
|
+
if (err instanceof PilotError) {
|
|
160
|
+
displayMsg = `❌ ${err.userMessage}`;
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
// Check if this is a macOS permission error and provide actionable guidance
|
|
164
|
+
const permissionHint = detectPermissionError(errorMsg);
|
|
165
|
+
displayMsg = permissionHint
|
|
166
|
+
? `❌ ${permissionHint}`
|
|
167
|
+
: `❌ Error: ${errorMsg}`;
|
|
168
|
+
}
|
|
130
169
|
await this.messenger.updateText(msg.channelId, statusMsgId, displayMsg);
|
|
131
170
|
await writeAuditLog({
|
|
132
171
|
timestamp: new Date().toISOString(),
|
|
@@ -143,6 +182,7 @@ export class AgentCore {
|
|
|
143
182
|
}
|
|
144
183
|
/**
|
|
145
184
|
* Resolves project from message, builds memory context, and invokes Claude.
|
|
185
|
+
* Uses session continuity: messages in the same thread share a Claude session.
|
|
146
186
|
*/
|
|
147
187
|
async invokeClaudeWithContext(msg, onStatus) {
|
|
148
188
|
// Resolve project from message text
|
|
@@ -171,6 +211,26 @@ RULES:
|
|
|
171
211
|
5. THINK STEP BY STEP — Before acting, plan your approach. "The user wants X. To find X, I need to check Y, which means I should run Z."
|
|
172
212
|
6. COMPLETE THE TASK — Do not stop halfway. If a command fails, try another approach. If you need more info, search for it. Only respond to the user when you have a concrete answer or have completed the action.
|
|
173
213
|
7. BE CONCISE — Report results directly. No filler, no "I'd be happy to help", no restating the question.
|
|
214
|
+
8. CODING TASKS — When asked to write or modify code, follow this workflow: understand → implement → build → test → fix errors → report. You have full access to the filesystem and shell. Write code, run builds, execute tests, and iterate until the task is done. Never say "I can't write code" — you absolutely can.
|
|
215
|
+
9. PROJECT WORKFLOW — When the user requests a new feature, project, or significant piece of work (not a simple one-off fix), follow this structured process:
|
|
216
|
+
**Phase A: Planning (before writing any code)**
|
|
217
|
+
a) Gather and clarify requirements from the user's request.
|
|
218
|
+
b) Write a PRD (Product Requirements Document) — create or update a PRD file (e.g. docs/PRD.md or a project-specific doc) defining what to build, why, and the technical approach.
|
|
219
|
+
c) Create a checklist — break the PRD into small, testable implementation tasks as a markdown checklist (e.g. docs/checklist.md). Each item should be one commit-sized unit.
|
|
220
|
+
d) Present the PRD and checklist to the user for confirmation before proceeding.
|
|
221
|
+
**Phase B: Implementation (repeat per checklist item)**
|
|
222
|
+
For each checklist item, execute this cycle:
|
|
223
|
+
a) Implement — write the code for one checklist item.
|
|
224
|
+
b) Build — run the project's build command and confirm it passes.
|
|
225
|
+
c) Test — write unit tests and run them. All tests must pass.
|
|
226
|
+
d) Update checklist — check off the completed item.
|
|
227
|
+
e) Commit — commit only after steps a-d all pass.
|
|
228
|
+
Then move to the next checklist item and repeat.
|
|
229
|
+
**Rules:**
|
|
230
|
+
- Never start coding before the PRD and checklist are confirmed by the user.
|
|
231
|
+
- Never commit with failing builds or tests.
|
|
232
|
+
- If requirements change mid-implementation, update the PRD and checklist first, then resume.
|
|
233
|
+
- Report progress to the user after completing each checklist item or group of related items.
|
|
174
234
|
|
|
175
235
|
CREDENTIAL MANAGEMENT:
|
|
176
236
|
You have a credential store at ~/.pilot/credentials/. Use it to store and retrieve API keys, tokens, and service account files.
|
|
@@ -204,14 +264,35 @@ You have a credential store at ~/.pilot/credentials/. Use it to store and retrie
|
|
|
204
264
|
apiKey: this.config.claude.apiKey,
|
|
205
265
|
});
|
|
206
266
|
}
|
|
267
|
+
// Session continuity: map messenger threads to Claude sessions
|
|
268
|
+
const threadId = msg.threadId ?? msg.channelId;
|
|
269
|
+
const existingSession = await getSession(msg.platform, msg.channelId, threadId);
|
|
270
|
+
let sessionId;
|
|
271
|
+
let resumeSessionId;
|
|
272
|
+
if (existingSession) {
|
|
273
|
+
// Resume existing session — Claude retains full conversation context
|
|
274
|
+
resumeSessionId = existingSession.sessionId;
|
|
275
|
+
await touchSession(msg.platform, msg.channelId, threadId);
|
|
276
|
+
log(`Resuming session ${resumeSessionId} (turn ${existingSession.turnCount + 1})`);
|
|
277
|
+
}
|
|
278
|
+
else {
|
|
279
|
+
// New session — create and store mapping
|
|
280
|
+
const session = await createSession(msg.platform, msg.channelId, threadId, projectPath);
|
|
281
|
+
sessionId = session.sessionId;
|
|
282
|
+
log(`New session ${sessionId}`);
|
|
283
|
+
}
|
|
284
|
+
// Periodically clean up expired sessions (non-blocking)
|
|
285
|
+
cleanupSessions().catch(() => { });
|
|
207
286
|
const mcpConfigPath = await getMcpConfigPathIfExists() ?? undefined;
|
|
208
287
|
const result = await invokeClaudeCli({
|
|
209
288
|
prompt: msg.text,
|
|
210
|
-
systemPrompt,
|
|
289
|
+
systemPrompt: resumeSessionId ? undefined : systemPrompt, // Only send system prompt on first turn
|
|
211
290
|
cwd: projectPath,
|
|
212
291
|
allowedTools: DEFAULT_ALLOWED_TOOLS,
|
|
213
292
|
mcpConfigPath,
|
|
214
293
|
onToolUse: (status) => onStatus?.(status),
|
|
294
|
+
sessionId,
|
|
295
|
+
resumeSessionId,
|
|
215
296
|
});
|
|
216
297
|
return result.result;
|
|
217
298
|
}
|
package/dist/agent/core.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.js","sourceRoot":"","sources":["../../src/agent/core.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACtF,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"core.js","sourceRoot":"","sources":["../../src/agent/core.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACtF,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACxF,OAAO,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACtF,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,SAAS,GAAG,CAAC,OAAe;IAC1B,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,KAAK,OAAO,EAAE,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,OAAO,SAAS;IACZ,SAAS,CAAmB;IAC5B,MAAM,CAAc;IACpB,eAAe,CAAkB;IACjC,iBAAiB,CAAoB;IACrC,mBAAmB,GAA0C,IAAI,CAAC;IAE1E,YAAY,SAA2B,EAAE,MAAmB;QAC1D,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;QAC7C,IAAI,CAAC,iBAAiB,GAAG,IAAI,iBAAiB,CAAC,CAAC,OAAO,EAAE,EAAE;YACzD,GAAG,CAAC,eAAe,OAAO,EAAE,CAAC,CAAC;YAC9B,2DAA2D;YAC3D,MAAM,KAAK,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,KAAK,OAAO;gBACjD,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,KAAK;gBACpC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC;YAC1C,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACrE,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC;IAEO,aAAa;QACnB,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3D,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE;YAC7C,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACxD,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,KAAK;QACT,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAClC,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QAC7B,GAAG,CAAC,8CAA8C,CAAC,CAAC;QACpD,MAAM,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC;QACrC,GAAG,CAAC,6BAA6B,CAAC,CAAC;QAEnC,oEAAoE;QACpE,IAAI,CAAC,eAAe,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACvC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;YAChC,IAAI,CAAC,mBAAmB,GAAG,WAAW,CAAC,GAAG,EAAE;gBAC1C,IAAI,CAAC,eAAe,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YACzC,CAAC,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,eAAe;QAC3B,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO;YAAE,OAAO;QAEzC,MAAM,MAAM,GAAG,MAAM,iBAAiB,EAAE,CAAC;QACzC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,GAAG,CAAC,kCAAkC,CAAC,CAAC;YACxC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,KAAK,OAAO;gBACtD,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,KAAK;gBACzC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC;YAC/C,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAC3B,KAAK,CAAC,CAAC,CAAC,EACR,uEAAuE,CACxE,CAAC;YACJ,CAAC;QACH,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,2BAA2B,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC7B,aAAa,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YACxC,IAAI,CAAC,mBAAmB,GAAG,IAAI,CAAC;QAClC,CAAC;QACD,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC;QAC9B,GAAG,CAAC,uBAAuB,CAAC,CAAC;QAC7B,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;IAC9B,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,GAAoB;QAC9C,IAAI,CAAC;YACH,GAAG,CAAC,yBAAyB,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,MAAM,OAAO,GAAG,CAAC,SAAS,MAAM,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC;YAC9F,GAAG,CAAC,kBAAkB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;YAE3E,gBAAgB;YAChB,IAAI,CAAC,gBAAgB,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;gBACxC,GAAG,CAAC,iBAAiB,GAAG,CAAC,MAAM,yBAAyB,CAAC,CAAC;gBAC1D,MAAM,aAAa,CAAC;oBAClB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;oBACnC,IAAI,EAAE,SAAS;oBACf,MAAM,EAAE,GAAG,CAAC,MAAM;oBAClB,QAAQ,EAAE,GAAG,CAAC,QAAQ;oBACtB,OAAO,EAAE,aAAa,GAAG,CAAC,IAAI,EAAE;iBACjC,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,GAAG,CAAC,mBAAmB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;YAErC,eAAe;YACf,MAAM,aAAa,CAAC;gBAClB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACnC,IAAI,EAAE,SAAS;gBACf,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,QAAQ,EAAE,GAAG,CAAC,QAAQ;gBACtB,OAAO,EAAE,GAAG,CAAC,IAAI;aAClB,CAAC,CAAC;YAEH,8BAA8B;YAC9B,MAAM,SAAS,GAAG,MAAM,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACtD,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;gBACtB,GAAG,CAAC,2BAA2B,CAAC,CAAC;gBACjC,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,QAAS,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;gBAChF,OAAO;YACT,CAAC;YAED,mDAAmD;YACnD,uBAAuB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;YAElD,mDAAmD;YACnD,GAAG,CAAC,4BAA4B,CAAC,CAAC;YAClC,MAAM,UAAU,GAAG,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC;YACtC,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC;YAC/E,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAC/C,GAAG,CAAC,SAAS,EAAE,gBAAgB,EAAE,GAAG,CAAC,QAAQ,CAC9C,CAAC;YACF,GAAG,CAAC,8BAA8B,WAAW,uBAAuB,CAAC,CAAC;YAEtE,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC;gBAClF,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;gBAEtE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,GAAG,EAAE,KAAK,EAAE,MAAc,EAAE,EAAE;oBAChF,IAAI,CAAC;wBACH,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;oBACtE,CAAC;oBAAC,MAAM,CAAC;wBACP,wDAAwD;oBAC1D,CAAC;gBACH,CAAC,CAAC,CAAC;gBAEH,GAAG,CAAC,oBAAoB,QAAQ,CAAC,MAAM,aAAa,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;gBAClF,MAAM,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;gBACzE,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,kBAAkB,CAAC,CAAC;gBAClF,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;gBAEtE,MAAM,aAAa,CAAC;oBAClB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;oBACnC,IAAI,EAAE,QAAQ;oBACd,MAAM,EAAE,GAAG,CAAC,MAAM;oBAClB,QAAQ,EAAE,GAAG,CAAC,QAAQ;oBACtB,OAAO,EAAE,QAAQ;iBAClB,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,QAAQ,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAClE,GAAG,CAAC,iBAAiB,QAAQ,EAAE,CAAC,CAAC;gBACjC,MAAM,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;gBACzE,MAAM,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,GAAG,CAAC,CAAC;gBAEnE,sDAAsD;gBACtD,IAAI,UAAkB,CAAC;gBACvB,IAAI,GAAG,YAAY,UAAU,EAAE,CAAC;oBAC9B,UAAU,GAAG,KAAK,GAAG,CAAC,WAAW,EAAE,CAAC;gBACtC,CAAC;qBAAM,CAAC;oBACN,4EAA4E;oBAC5E,MAAM,cAAc,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC;oBACvD,UAAU,GAAG,cAAc;wBACzB,CAAC,CAAC,KAAK,cAAc,EAAE;wBACvB,CAAC,CAAC,YAAY,QAAQ,EAAE,CAAC;gBAC7B,CAAC;gBACD,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;gBAExE,MAAM,aAAa,CAAC;oBAClB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;oBACnC,IAAI,EAAE,OAAO;oBACb,MAAM,EAAE,GAAG,CAAC,MAAM;oBAClB,QAAQ,EAAE,GAAG,CAAC,QAAQ;oBACtB,OAAO,EAAE,QAAQ;iBAClB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,iCAAiC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzF,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,uBAAuB,CACnC,GAAoB,EACpB,QAA4C;QAE5C,oCAAoC;QACpC,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,WAAW,GAAG,OAAO,EAAE,IAAI,CAAC;QAClC,MAAM,WAAW,GAAG,OAAO,EAAE,IAAI,CAAC;QAElC,gEAAgE;QAChE,IAAI,WAAW,IAAI,WAAW,EAAE,CAAC;YAC/B,MAAM,YAAY,CAAC,WAAW,CAAC,CAAC;YAChC,MAAM,mBAAmB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;QACtD,CAAC;QAED,iEAAiE;QACjE,MAAM,aAAa,GAAG,MAAM,kBAAkB,CAAC,WAAW,CAAC,CAAC;QAC5D,MAAM,aAAa,GAAG,MAAM,kBAAkB,EAAE,CAAC;QACjD,MAAM,gBAAgB,GAAG,qBAAqB,EAAE,CAAC;QAEjD,MAAM,WAAW,GAAa,EAAE,CAAC;QACjC,WAAW,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8GA4CyF,CAAC,CAAC;QAC5G,qDAAqD;QACrD,MAAM,UAAU,GAAG,MAAM,eAAe,EAAE,CAAC;QAC3C,IAAI,UAAU;YAAE,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAE7C,IAAI,aAAa;YAAE,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACnD,IAAI,aAAa;YAAE,WAAW,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACnD,IAAI,gBAAgB;YAAE,WAAW,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAEzD,MAAM,YAAY,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAE9C,MAAM,QAAQ,EAAE,CAAC,kBAAkB,CAAC,CAAC;QAErC,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACnE,uEAAuE;YACvE,MAAM,SAAS,GAAG,GAAG,YAAY,uBAAuB,GAAG,CAAC,IAAI,mBAAmB,CAAC;YACpF,OAAO,eAAe,CAAC;gBACrB,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM;aAClC,CAAC,CAAC;QACL,CAAC;QAED,+DAA+D;QAC/D,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,SAAS,CAAC;QAC/C,MAAM,eAAe,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAEhF,IAAI,SAA6B,CAAC;QAClC,IAAI,eAAmC,CAAC;QAExC,IAAI,eAAe,EAAE,CAAC;YACpB,qEAAqE;YACrE,eAAe,GAAG,eAAe,CAAC,SAAS,CAAC;YAC5C,MAAM,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;YAC1D,GAAG,CAAC,oBAAoB,eAAe,UAAU,eAAe,CAAC,SAAS,GAAG,CAAC,GAAG,CAAC,CAAC;QACrF,CAAC;aAAM,CAAC;YACN,yCAAyC;YACzC,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;YACxF,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;YAC9B,GAAG,CAAC,eAAe,SAAS,EAAE,CAAC,CAAC;QAClC,CAAC;QAED,wDAAwD;QACxD,eAAe,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAElC,MAAM,aAAa,GAAG,MAAM,wBAAwB,EAAE,IAAI,SAAS,CAAC;QACpE,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC;YACnC,MAAM,EAAE,GAAG,CAAC,IAAI;YAChB,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,EAAE,wCAAwC;YAClG,GAAG,EAAE,WAAW;YAChB,YAAY,EAAE,qBAAqB;YACnC,aAAa;YACb,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC;YACzC,SAAS;YACT,eAAe;SAChB,CAAC,CAAC;QACH,OAAO,MAAM,CAAC,MAAM,CAAC;IACvB,CAAC;CACF"}
|
package/dist/agent/queue.d.ts
CHANGED
|
@@ -17,20 +17,17 @@ export interface Task {
|
|
|
17
17
|
worktree?: WorktreeInfo;
|
|
18
18
|
}
|
|
19
19
|
export type TaskHandler = (task: Task) => Promise<void>;
|
|
20
|
-
/**
|
|
21
|
-
* Task queue with project-based parallel execution.
|
|
22
|
-
* - Different projects run in parallel
|
|
23
|
-
* - Same project tasks run sequentially
|
|
24
|
-
* - Null-project tasks (Notion, browser) run in parallel with everything
|
|
25
|
-
* - Max concurrent limit to respect Claude CLI rate limits
|
|
26
|
-
*/
|
|
27
20
|
export declare class TaskQueue {
|
|
28
21
|
private queue;
|
|
29
22
|
private runningTasks;
|
|
30
23
|
private handler;
|
|
31
24
|
private maxConcurrent;
|
|
32
25
|
private worktreeEnabled;
|
|
26
|
+
private persistTimer;
|
|
27
|
+
private onBackpressure?;
|
|
33
28
|
constructor(maxConcurrent?: number, worktreeEnabled?: boolean);
|
|
29
|
+
/** Register a callback for backpressure warnings */
|
|
30
|
+
setBackpressureCallback(cb: (depth: number) => void): void;
|
|
34
31
|
onTask(handler: TaskHandler): void;
|
|
35
32
|
enqueue(params: {
|
|
36
33
|
command: string;
|
|
@@ -57,5 +54,13 @@ export declare class TaskQueue {
|
|
|
57
54
|
getQueueLength(): number;
|
|
58
55
|
getRunningCount(): number;
|
|
59
56
|
formatStatus(): string;
|
|
57
|
+
private getQueueFilePath;
|
|
58
|
+
private schedulePersist;
|
|
59
|
+
private persistToDisk;
|
|
60
|
+
/**
|
|
61
|
+
* Restores queued tasks from disk on daemon startup.
|
|
62
|
+
* Running tasks are marked as failed (they were interrupted).
|
|
63
|
+
*/
|
|
64
|
+
restoreFromDisk(): Task[];
|
|
60
65
|
}
|
|
61
66
|
//# sourceMappingURL=queue.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../src/agent/queue.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../src/agent/queue.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkC,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAGlF,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,SAAS,GAAG,kBAAkB,GAAG,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE1G,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;IAChB,SAAS,EAAE,IAAI,GAAG,IAAI,CAAC;IACvB,WAAW,EAAE,IAAI,GAAG,IAAI,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,YAAY,CAAC;CACzB;AAED,MAAM,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAmBxD,qBAAa,SAAS;IACpB,OAAO,CAAC,KAAK,CAAc;IAC3B,OAAO,CAAC,YAAY,CAAwB;IAC5C,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,YAAY,CAA8C;IAClE,OAAO,CAAC,cAAc,CAAC,CAA0B;gBAErC,aAAa,GAAE,MAAU,EAAE,eAAe,GAAE,OAAe;IAKvE,oDAAoD;IACpD,uBAAuB,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI;IAI1D,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAIlC,OAAO,CAAC,MAAM,EAAE;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GAAG,IAAI;YAiCM,WAAW;IAuBzB;;;OAGG;IACH,OAAO,CAAC,gBAAgB;YAsBV,WAAW;IAqCzB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAQ/B,SAAS,IAAI;QAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QAAC,MAAM,EAAE,IAAI,EAAE,CAAC;QAAC,SAAS,EAAE,IAAI,EAAE,CAAA;KAAE;IAQnE,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS;IAIzC,cAAc,IAAI,MAAM;IAIxB,eAAe,IAAI,MAAM;IAIzB,YAAY,IAAI,MAAM;IAwBtB,OAAO,CAAC,gBAAgB;IAIxB,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,aAAa;IAiBrB;;;OAGG;IACH,eAAe,IAAI,IAAI,EAAE;CAoC1B"}
|
package/dist/agent/queue.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
1
3
|
import { createWorktree, removeWorktree } from './worktree.js';
|
|
4
|
+
import { getPilotDir } from '../config/store.js';
|
|
2
5
|
let taskCounter = 0;
|
|
3
6
|
function generateTaskId() {
|
|
4
7
|
return `task-${Date.now()}-${++taskCounter}`;
|
|
@@ -10,20 +13,33 @@ function generateTaskId() {
|
|
|
10
13
|
* - Null-project tasks (Notion, browser) run in parallel with everything
|
|
11
14
|
* - Max concurrent limit to respect Claude CLI rate limits
|
|
12
15
|
*/
|
|
16
|
+
const MAX_QUEUE_SIZE = 50;
|
|
17
|
+
const BACKPRESSURE_THRESHOLD = 20;
|
|
18
|
+
const PERSIST_DEBOUNCE_MS = 1000;
|
|
13
19
|
export class TaskQueue {
|
|
14
20
|
queue = [];
|
|
15
21
|
runningTasks = new Set();
|
|
16
22
|
handler = null;
|
|
17
23
|
maxConcurrent;
|
|
18
24
|
worktreeEnabled;
|
|
25
|
+
persistTimer = null;
|
|
26
|
+
onBackpressure;
|
|
19
27
|
constructor(maxConcurrent = 3, worktreeEnabled = false) {
|
|
20
28
|
this.maxConcurrent = maxConcurrent;
|
|
21
29
|
this.worktreeEnabled = worktreeEnabled;
|
|
22
30
|
}
|
|
31
|
+
/** Register a callback for backpressure warnings */
|
|
32
|
+
setBackpressureCallback(cb) {
|
|
33
|
+
this.onBackpressure = cb;
|
|
34
|
+
}
|
|
23
35
|
onTask(handler) {
|
|
24
36
|
this.handler = handler;
|
|
25
37
|
}
|
|
26
38
|
enqueue(params) {
|
|
39
|
+
const queuedCount = this.queue.filter((t) => t.status === 'queued').length;
|
|
40
|
+
if (queuedCount >= MAX_QUEUE_SIZE) {
|
|
41
|
+
throw new Error(`Task queue is full (max ${MAX_QUEUE_SIZE}). Please wait for existing tasks to complete.`);
|
|
42
|
+
}
|
|
27
43
|
const task = {
|
|
28
44
|
id: generateTaskId(),
|
|
29
45
|
status: 'queued',
|
|
@@ -38,6 +54,12 @@ export class TaskQueue {
|
|
|
38
54
|
completedAt: null,
|
|
39
55
|
};
|
|
40
56
|
this.queue.push(task);
|
|
57
|
+
this.schedulePersist();
|
|
58
|
+
// Backpressure warning
|
|
59
|
+
const newQueuedCount = this.queue.filter((t) => t.status === 'queued').length;
|
|
60
|
+
if (newQueuedCount > BACKPRESSURE_THRESHOLD && this.onBackpressure) {
|
|
61
|
+
this.onBackpressure(newQueuedCount);
|
|
62
|
+
}
|
|
41
63
|
this.processNext();
|
|
42
64
|
return task;
|
|
43
65
|
}
|
|
@@ -111,6 +133,7 @@ export class TaskQueue {
|
|
|
111
133
|
}
|
|
112
134
|
finally {
|
|
113
135
|
task.completedAt = new Date();
|
|
136
|
+
this.schedulePersist();
|
|
114
137
|
// Clean up worktree
|
|
115
138
|
if (task.worktree && task.projectPath) {
|
|
116
139
|
try {
|
|
@@ -163,5 +186,71 @@ export class TaskQueue {
|
|
|
163
186
|
}
|
|
164
187
|
return lines.join('\n');
|
|
165
188
|
}
|
|
189
|
+
// --- Persistence ---
|
|
190
|
+
getQueueFilePath() {
|
|
191
|
+
return path.join(getPilotDir(), 'task-queue.json');
|
|
192
|
+
}
|
|
193
|
+
schedulePersist() {
|
|
194
|
+
if (this.persistTimer)
|
|
195
|
+
return;
|
|
196
|
+
this.persistTimer = setTimeout(() => {
|
|
197
|
+
this.persistTimer = null;
|
|
198
|
+
this.persistToDisk();
|
|
199
|
+
}, PERSIST_DEBOUNCE_MS);
|
|
200
|
+
}
|
|
201
|
+
persistToDisk() {
|
|
202
|
+
try {
|
|
203
|
+
const serializable = this.queue
|
|
204
|
+
.filter((t) => t.status === 'queued' || t.status === 'running')
|
|
205
|
+
.map((t) => ({
|
|
206
|
+
...t,
|
|
207
|
+
createdAt: t.createdAt.toISOString(),
|
|
208
|
+
startedAt: t.startedAt?.toISOString() ?? null,
|
|
209
|
+
completedAt: t.completedAt?.toISOString() ?? null,
|
|
210
|
+
worktree: undefined, // Don't persist worktree info
|
|
211
|
+
}));
|
|
212
|
+
fs.writeFileSync(this.getQueueFilePath(), JSON.stringify(serializable, null, 2));
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
// Best-effort persistence
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Restores queued tasks from disk on daemon startup.
|
|
220
|
+
* Running tasks are marked as failed (they were interrupted).
|
|
221
|
+
*/
|
|
222
|
+
restoreFromDisk() {
|
|
223
|
+
try {
|
|
224
|
+
const data = fs.readFileSync(this.getQueueFilePath(), 'utf-8');
|
|
225
|
+
const items = JSON.parse(data);
|
|
226
|
+
const restored = [];
|
|
227
|
+
for (const item of items) {
|
|
228
|
+
const task = {
|
|
229
|
+
id: item.id,
|
|
230
|
+
status: item.status === 'running' ? 'failed' : 'queued',
|
|
231
|
+
project: item.project ?? null,
|
|
232
|
+
projectPath: item.projectPath,
|
|
233
|
+
command: item.command,
|
|
234
|
+
channelId: item.channelId,
|
|
235
|
+
userId: item.userId,
|
|
236
|
+
threadId: item.threadId,
|
|
237
|
+
createdAt: new Date(item.createdAt),
|
|
238
|
+
startedAt: item.startedAt ? new Date(item.startedAt) : null,
|
|
239
|
+
completedAt: item.status === 'running' ? new Date() : null,
|
|
240
|
+
error: item.status === 'running' ? 'Daemon restarted while task was running' : undefined,
|
|
241
|
+
};
|
|
242
|
+
this.queue.push(task);
|
|
243
|
+
restored.push(task);
|
|
244
|
+
}
|
|
245
|
+
// Clean up the file after restoring
|
|
246
|
+
fs.unlinkSync(this.getQueueFilePath());
|
|
247
|
+
// Resume processing queued tasks
|
|
248
|
+
this.processNext();
|
|
249
|
+
return restored;
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
return [];
|
|
253
|
+
}
|
|
254
|
+
}
|
|
166
255
|
}
|
|
167
256
|
//# sourceMappingURL=queue.js.map
|