@ebowwa/glm-daemon 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/README.md +264 -0
- package/dist/agent.d.ts +37 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +97 -0
- package/dist/agent.js.map +1 -0
- package/dist/daemon.d.ts +91 -0
- package/dist/daemon.d.ts.map +1 -0
- package/dist/daemon.js +449 -0
- package/dist/daemon.js.map +1 -0
- package/dist/hooks.d.ts +34 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +82 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/state.d.ts +31 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +67 -0
- package/dist/state.js.map +1 -0
- package/dist/tools.d.ts +42 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +110 -0
- package/dist/tools.js.map +1 -0
- package/dist/types.d.ts +222 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +19 -0
- package/dist/types.js.map +1 -0
- package/dist/worktree.d.ts +42 -0
- package/dist/worktree.d.ts.map +1 -0
- package/dist/worktree.js +86 -0
- package/dist/worktree.js.map +1 -0
- package/package.json +70 -0
- package/src/agent.js +166 -0
- package/src/agent.ts +110 -0
- package/src/daemon.js +591 -0
- package/src/daemon.ts +529 -0
- package/src/hooks.js +145 -0
- package/src/hooks.ts +94 -0
- package/src/index.js +105 -0
- package/src/index.ts +43 -0
- package/src/state.js +168 -0
- package/src/state.ts +77 -0
- package/src/tools.js +192 -0
- package/src/tools.ts +134 -0
- package/src/types.js +21 -0
- package/src/types.ts +249 -0
- package/src/worktree.js +195 -0
- package/src/worktree.ts +122 -0
package/src/daemon.js
ADDED
|
@@ -0,0 +1,591 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* GLM Daemon - Core Daemon
|
|
4
|
+
*
|
|
5
|
+
* Main orchestrator for autonomous GLM 4.7 agents.
|
|
6
|
+
* Implements SLAM pattern: State → Loop → Action → Memory
|
|
7
|
+
*/
|
|
8
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
9
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
10
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
11
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
12
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
13
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
14
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
18
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
19
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
20
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
21
|
+
function step(op) {
|
|
22
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
23
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
24
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
25
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
26
|
+
switch (op[0]) {
|
|
27
|
+
case 0: case 1: t = op; break;
|
|
28
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
29
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
30
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
31
|
+
default:
|
|
32
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
33
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
34
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
35
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
36
|
+
if (t[2]) _.ops.pop();
|
|
37
|
+
_.trys.pop(); continue;
|
|
38
|
+
}
|
|
39
|
+
op = body.call(thisArg, _);
|
|
40
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
41
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.GLMDaemon = void 0;
|
|
46
|
+
var path_1 = require("path");
|
|
47
|
+
var agent_js_1 = require("./agent.js");
|
|
48
|
+
var hooks_js_1 = require("./hooks.js");
|
|
49
|
+
var tools_js_1 = require("./tools.js");
|
|
50
|
+
var state_js_1 = require("./state.js");
|
|
51
|
+
var worktree_js_1 = require("./worktree.js");
|
|
52
|
+
var teammates_1 = require("@ebowwa/teammates");
|
|
53
|
+
var client_1 = require("@codespaces/ai/client");
|
|
54
|
+
var STATE_FILE = ".glm-daemon.json";
|
|
55
|
+
var SETTINGS_FILE = ".claude/settings.local.json";
|
|
56
|
+
var GLMDaemon = /** @class */ (function () {
|
|
57
|
+
function GLMDaemon(config) {
|
|
58
|
+
this.team = null;
|
|
59
|
+
this.subagents = new Map();
|
|
60
|
+
this.running = false;
|
|
61
|
+
this.config = config;
|
|
62
|
+
this.statePath = (0, path_1.join)(config.cwd, STATE_FILE);
|
|
63
|
+
this.client = new client_1.GLMClient();
|
|
64
|
+
// Initialize state
|
|
65
|
+
this.state = this.initializeState();
|
|
66
|
+
// Initialize components
|
|
67
|
+
this.hooks = new hooks_js_1.HookSystem(config.hooks || {});
|
|
68
|
+
this.tools = new tools_js_1.ToolBridge(config.tools || {});
|
|
69
|
+
this.stateManager = new state_js_1.StateManager(this.statePath);
|
|
70
|
+
this.worktreeManager = new worktree_js_1.WorktreeManager(config);
|
|
71
|
+
// Initialize main agent
|
|
72
|
+
this.agent = new agent_js_1.GLMAgent({
|
|
73
|
+
agentId: "glm-daemon",
|
|
74
|
+
name: "GLM Daemon",
|
|
75
|
+
prompt: this.buildSystemPrompt(),
|
|
76
|
+
model: config.model,
|
|
77
|
+
tools: this.tools.getAvailableTools(),
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Initialize daemon state
|
|
82
|
+
*/
|
|
83
|
+
GLMDaemon.prototype.initializeState = function () {
|
|
84
|
+
var now = new Date().toISOString();
|
|
85
|
+
return {
|
|
86
|
+
prompt: "", // Will be set when starting
|
|
87
|
+
promise: this.config.completionPromise || "TASK_COMPLETE",
|
|
88
|
+
iteration: 0,
|
|
89
|
+
maxIterations: this.config.maxIterations || 0,
|
|
90
|
+
startTime: now,
|
|
91
|
+
lastUpdate: now,
|
|
92
|
+
tokens: {
|
|
93
|
+
totalInput: 0,
|
|
94
|
+
totalOutput: 0,
|
|
95
|
+
byIteration: [],
|
|
96
|
+
},
|
|
97
|
+
filesChanged: [],
|
|
98
|
+
workMemory: {
|
|
99
|
+
completedFiles: [],
|
|
100
|
+
fileChecksums: {},
|
|
101
|
+
},
|
|
102
|
+
slam: {
|
|
103
|
+
enabled: true,
|
|
104
|
+
phase: "planning",
|
|
105
|
+
state: {
|
|
106
|
+
currentTask: "",
|
|
107
|
+
beliefs: {},
|
|
108
|
+
goals: [this.config.completionPromise || "TASK_COMPLETE"],
|
|
109
|
+
},
|
|
110
|
+
subtasks: [],
|
|
111
|
+
currentSubtask: null,
|
|
112
|
+
completedSubtasks: [],
|
|
113
|
+
memory: {
|
|
114
|
+
actionsTaken: [],
|
|
115
|
+
outcomes: {},
|
|
116
|
+
patterns: {},
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
git: {
|
|
120
|
+
enabled: this.config.autoCommit || this.config.autoPR || false,
|
|
121
|
+
autoCommit: this.config.autoCommit || false,
|
|
122
|
+
autoPR: this.config.autoPR || false,
|
|
123
|
+
baseBranch: this.config.baseBranch || "main",
|
|
124
|
+
useWorktree: this.config.enableWorktree || false,
|
|
125
|
+
branchName: "",
|
|
126
|
+
branchCreated: false,
|
|
127
|
+
currentCommit: "",
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* Build system prompt from config and state
|
|
133
|
+
*/
|
|
134
|
+
GLMDaemon.prototype.buildSystemPrompt = function () {
|
|
135
|
+
return "You are an autonomous AI agent powered by GLM 4.7.\n\nYour task: ".concat(this.state.prompt, "\n\nYou work in SLAM phases:\n- Planning: Break down the task into subtasks\n- Executing: Work on the current subtask\n- Paranoid: Review your work for bugs and issues\n- Reviewing: Check quality of completed work\n- Fixing: Address any issues found\n- Committing: Commit your changes\n- Complete: Task is finished\n\nUse tools when available. Be thorough but efficient.\n\nCurrent phase: ").concat(this.state.slam.phase, "\nIteration: ").concat(this.state.iteration, "\n");
|
|
136
|
+
};
|
|
137
|
+
/**
|
|
138
|
+
* Start the daemon with a prompt
|
|
139
|
+
*/
|
|
140
|
+
GLMDaemon.prototype.start = function (prompt) {
|
|
141
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
142
|
+
var worktreePath, _a, _b;
|
|
143
|
+
var _this = this;
|
|
144
|
+
return __generator(this, function (_c) {
|
|
145
|
+
switch (_c.label) {
|
|
146
|
+
case 0:
|
|
147
|
+
if (this.running) {
|
|
148
|
+
throw new Error("Daemon already running");
|
|
149
|
+
}
|
|
150
|
+
this.state.prompt = prompt;
|
|
151
|
+
this.state.slam.state.currentTask = prompt;
|
|
152
|
+
this.running = true;
|
|
153
|
+
if (!this.config.enableWorktree) return [3 /*break*/, 3];
|
|
154
|
+
return [4 /*yield*/, this.worktreeManager.createWorktree()];
|
|
155
|
+
case 1:
|
|
156
|
+
worktreePath = _c.sent();
|
|
157
|
+
_a = this.state.git;
|
|
158
|
+
return [4 /*yield*/, this.worktreeManager.createBranch()];
|
|
159
|
+
case 2:
|
|
160
|
+
_a.branchName = _c.sent();
|
|
161
|
+
this.state.git.branchCreated = true;
|
|
162
|
+
_c.label = 3;
|
|
163
|
+
case 3:
|
|
164
|
+
// Initialize team for multi-agent coordination
|
|
165
|
+
_b = this;
|
|
166
|
+
return [4 /*yield*/, teammates_1.Team.create({
|
|
167
|
+
name: this.config.teamName,
|
|
168
|
+
description: "GLM daemon for: ".concat(prompt.substring(0, 50), "..."),
|
|
169
|
+
})];
|
|
170
|
+
case 4:
|
|
171
|
+
// Initialize team for multi-agent coordination
|
|
172
|
+
_b.team = _c.sent();
|
|
173
|
+
// Run session start hook
|
|
174
|
+
return [4 /*yield*/, this.hooks.execute("onSessionStart", this.state)];
|
|
175
|
+
case 5:
|
|
176
|
+
// Run session start hook
|
|
177
|
+
_c.sent();
|
|
178
|
+
// Save initial state
|
|
179
|
+
return [4 /*yield*/, this.stateManager.save(this.state)];
|
|
180
|
+
case 6:
|
|
181
|
+
// Save initial state
|
|
182
|
+
_c.sent();
|
|
183
|
+
// Start main loop
|
|
184
|
+
this.runLoop().catch(function (error) {
|
|
185
|
+
console.error("[GLMDaemon] Loop error:", error);
|
|
186
|
+
_this.running = false;
|
|
187
|
+
});
|
|
188
|
+
return [2 /*return*/, this.config.teamName];
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
};
|
|
193
|
+
/**
|
|
194
|
+
* Main daemon loop (SLAM pattern)
|
|
195
|
+
*/
|
|
196
|
+
GLMDaemon.prototype.runLoop = function () {
|
|
197
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
198
|
+
return __generator(this, function (_a) {
|
|
199
|
+
switch (_a.label) {
|
|
200
|
+
case 0:
|
|
201
|
+
if (!this.running) return [3 /*break*/, 9];
|
|
202
|
+
if (!this.checkCompletion()) return [3 /*break*/, 2];
|
|
203
|
+
return [4 /*yield*/, this.complete()];
|
|
204
|
+
case 1:
|
|
205
|
+
_a.sent();
|
|
206
|
+
return [3 /*break*/, 9];
|
|
207
|
+
case 2:
|
|
208
|
+
if (!(this.state.maxIterations > 0 &&
|
|
209
|
+
this.state.iteration >= this.state.maxIterations)) return [3 /*break*/, 4];
|
|
210
|
+
console.log("[GLMDaemon] Max iterations reached: ".concat(this.state.maxIterations));
|
|
211
|
+
return [4 /*yield*/, this.stop()];
|
|
212
|
+
case 3:
|
|
213
|
+
_a.sent();
|
|
214
|
+
return [3 /*break*/, 9];
|
|
215
|
+
case 4:
|
|
216
|
+
// Run iteration start hook
|
|
217
|
+
return [4 /*yield*/, this.hooks.execute("onIterationStart", this.state.iteration)];
|
|
218
|
+
case 5:
|
|
219
|
+
// Run iteration start hook
|
|
220
|
+
_a.sent();
|
|
221
|
+
// Execute current SLAM phase
|
|
222
|
+
return [4 /*yield*/, this.executePhase()];
|
|
223
|
+
case 6:
|
|
224
|
+
// Execute current SLAM phase
|
|
225
|
+
_a.sent();
|
|
226
|
+
// Update state
|
|
227
|
+
this.state.iteration++;
|
|
228
|
+
this.state.lastUpdate = new Date().toISOString();
|
|
229
|
+
// Save state
|
|
230
|
+
return [4 /*yield*/, this.stateManager.save(this.state)];
|
|
231
|
+
case 7:
|
|
232
|
+
// Save state
|
|
233
|
+
_a.sent();
|
|
234
|
+
// Run iteration end hook
|
|
235
|
+
return [4 /*yield*/, this.hooks.execute("onIterationEnd", this.state.iteration, null)];
|
|
236
|
+
case 8:
|
|
237
|
+
// Run iteration end hook
|
|
238
|
+
_a.sent();
|
|
239
|
+
return [3 /*break*/, 0];
|
|
240
|
+
case 9: return [2 /*return*/];
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
};
|
|
245
|
+
/**
|
|
246
|
+
* Execute current SLAM phase
|
|
247
|
+
*/
|
|
248
|
+
GLMDaemon.prototype.executePhase = function () {
|
|
249
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
250
|
+
var phase, _a;
|
|
251
|
+
return __generator(this, function (_b) {
|
|
252
|
+
switch (_b.label) {
|
|
253
|
+
case 0:
|
|
254
|
+
phase = this.state.slam.phase;
|
|
255
|
+
_a = phase;
|
|
256
|
+
switch (_a) {
|
|
257
|
+
case "planning": return [3 /*break*/, 1];
|
|
258
|
+
case "executing": return [3 /*break*/, 3];
|
|
259
|
+
case "paranoid": return [3 /*break*/, 5];
|
|
260
|
+
case "reviewing": return [3 /*break*/, 7];
|
|
261
|
+
case "fixing": return [3 /*break*/, 9];
|
|
262
|
+
case "committing": return [3 /*break*/, 11];
|
|
263
|
+
case "complete": return [3 /*break*/, 13];
|
|
264
|
+
}
|
|
265
|
+
return [3 /*break*/, 15];
|
|
266
|
+
case 1: return [4 /*yield*/, this.phasePlanning()];
|
|
267
|
+
case 2:
|
|
268
|
+
_b.sent();
|
|
269
|
+
return [3 /*break*/, 15];
|
|
270
|
+
case 3: return [4 /*yield*/, this.phaseExecuting()];
|
|
271
|
+
case 4:
|
|
272
|
+
_b.sent();
|
|
273
|
+
return [3 /*break*/, 15];
|
|
274
|
+
case 5: return [4 /*yield*/, this.phaseParanoid()];
|
|
275
|
+
case 6:
|
|
276
|
+
_b.sent();
|
|
277
|
+
return [3 /*break*/, 15];
|
|
278
|
+
case 7: return [4 /*yield*/, this.phaseReviewing()];
|
|
279
|
+
case 8:
|
|
280
|
+
_b.sent();
|
|
281
|
+
return [3 /*break*/, 15];
|
|
282
|
+
case 9: return [4 /*yield*/, this.phaseFixing()];
|
|
283
|
+
case 10:
|
|
284
|
+
_b.sent();
|
|
285
|
+
return [3 /*break*/, 15];
|
|
286
|
+
case 11: return [4 /*yield*/, this.phaseCommitting()];
|
|
287
|
+
case 12:
|
|
288
|
+
_b.sent();
|
|
289
|
+
return [3 /*break*/, 15];
|
|
290
|
+
case 13: return [4 /*yield*/, this.complete()];
|
|
291
|
+
case 14:
|
|
292
|
+
_b.sent();
|
|
293
|
+
return [3 /*break*/, 15];
|
|
294
|
+
case 15: return [2 /*return*/];
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
};
|
|
299
|
+
/**
|
|
300
|
+
* Planning phase - break down task into subtasks
|
|
301
|
+
*/
|
|
302
|
+
GLMDaemon.prototype.phasePlanning = function () {
|
|
303
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
304
|
+
var prompt, response, subtasks;
|
|
305
|
+
var _a;
|
|
306
|
+
return __generator(this, function (_b) {
|
|
307
|
+
switch (_b.label) {
|
|
308
|
+
case 0:
|
|
309
|
+
console.log("[GLMDaemon] Phase: Planning");
|
|
310
|
+
prompt = "".concat(this.state.prompt, "\n\nBreak this task down into 3-7 concrete subtasks.\nFor each subtask, specify:\n- Title (short description)\n- Description (what needs to be done)\n- Dependencies (which subtasks must come first)\n\nRespond with a JSON array of subtasks.\n");
|
|
311
|
+
return [4 /*yield*/, this.agent.execute(prompt)];
|
|
312
|
+
case 1:
|
|
313
|
+
response = _b.sent();
|
|
314
|
+
subtasks = this.parseSubtasks(response);
|
|
315
|
+
this.state.slam.subtasks = subtasks;
|
|
316
|
+
this.state.slam.phase = "executing";
|
|
317
|
+
this.state.slam.currentSubtask = ((_a = subtasks[0]) === null || _a === void 0 ? void 0 : _a.id) || null;
|
|
318
|
+
return [2 /*return*/];
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
});
|
|
322
|
+
};
|
|
323
|
+
/**
|
|
324
|
+
* Executing phase - work on current subtask
|
|
325
|
+
*/
|
|
326
|
+
GLMDaemon.prototype.phaseExecuting = function () {
|
|
327
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
328
|
+
var currentSubtaskId, subtask, prompt, response, nextSubtask;
|
|
329
|
+
var _this = this;
|
|
330
|
+
return __generator(this, function (_a) {
|
|
331
|
+
switch (_a.label) {
|
|
332
|
+
case 0:
|
|
333
|
+
currentSubtaskId = this.state.slam.currentSubtask;
|
|
334
|
+
if (!currentSubtaskId) {
|
|
335
|
+
this.state.slam.phase = "reviewing";
|
|
336
|
+
return [2 /*return*/];
|
|
337
|
+
}
|
|
338
|
+
subtask = this.state.slam.subtasks.find(function (st) { return st.id === currentSubtaskId; });
|
|
339
|
+
if (!subtask) {
|
|
340
|
+
this.state.slam.phase = "reviewing";
|
|
341
|
+
return [2 /*return*/];
|
|
342
|
+
}
|
|
343
|
+
console.log("[GLMDaemon] Executing subtask: ".concat(subtask.title));
|
|
344
|
+
prompt = "Work on this subtask: ".concat(subtask.title, "\n\n").concat(subtask.description, "\n\nUse available tools to complete the work.\nFocus on code changes, testing, and verification.\n");
|
|
345
|
+
return [4 /*yield*/, this.agent.execute(prompt)];
|
|
346
|
+
case 1:
|
|
347
|
+
response = _a.sent();
|
|
348
|
+
// Update subtask status
|
|
349
|
+
subtask.status = "completed";
|
|
350
|
+
subtask.result = response;
|
|
351
|
+
this.state.slam.completedSubtasks.push(currentSubtaskId);
|
|
352
|
+
nextSubtask = this.state.slam.subtasks.find(function (st) { return !_this.state.slam.completedSubtasks.includes(st.id); });
|
|
353
|
+
if (nextSubtask) {
|
|
354
|
+
this.state.slam.currentSubtask = nextSubtask.id;
|
|
355
|
+
}
|
|
356
|
+
else {
|
|
357
|
+
this.state.slam.phase = "paranoid";
|
|
358
|
+
}
|
|
359
|
+
return [2 /*return*/];
|
|
360
|
+
}
|
|
361
|
+
});
|
|
362
|
+
});
|
|
363
|
+
};
|
|
364
|
+
/**
|
|
365
|
+
* Paranoid phase - quality check after every edit
|
|
366
|
+
*/
|
|
367
|
+
GLMDaemon.prototype.phaseParanoid = function () {
|
|
368
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
369
|
+
var prompt, response, hasIssues;
|
|
370
|
+
return __generator(this, function (_a) {
|
|
371
|
+
switch (_a.label) {
|
|
372
|
+
case 0:
|
|
373
|
+
console.log("[GLMDaemon] Phase: Paranoid (quality check)");
|
|
374
|
+
prompt = "Review the changes made in this session for:\n- Bugs or errors\n- Edge cases not handled\n- Security vulnerabilities\n- Performance issues\n- Breaking changes\n\nTask: ".concat(this.state.prompt, "\n\nChanges made:\n").concat(this.state.filesChanged.map(function (f) { return "- ".concat(f); }).join("\n"), "\n\nBe thorough. If issues found, we'll fix them. If clean, we proceed to review.\n");
|
|
375
|
+
return [4 /*yield*/, this.agent.execute(prompt)];
|
|
376
|
+
case 1:
|
|
377
|
+
response = _a.sent();
|
|
378
|
+
hasIssues = this.detectIssues(response);
|
|
379
|
+
if (hasIssues) {
|
|
380
|
+
this.state.slam.phase = "fixing";
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
this.state.slam.phase = "reviewing";
|
|
384
|
+
}
|
|
385
|
+
return [2 /*return*/];
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
});
|
|
389
|
+
};
|
|
390
|
+
/**
|
|
391
|
+
* Reviewing phase - final quality review
|
|
392
|
+
*/
|
|
393
|
+
GLMDaemon.prototype.phaseReviewing = function () {
|
|
394
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
395
|
+
var prompt, response;
|
|
396
|
+
return __generator(this, function (_a) {
|
|
397
|
+
switch (_a.label) {
|
|
398
|
+
case 0:
|
|
399
|
+
console.log("[GLMDaemon] Phase: Reviewing");
|
|
400
|
+
prompt = "Final review of the completed work.\n\nTask: ".concat(this.state.prompt, "\nCompletion promise: ").concat(this.state.promise, "\n\nDoes the implementation fully satisfy the completion promise?\nAre there any remaining issues or TODOs?\n\nIf complete and clean, respond with \"APPROVED\".\nOtherwise, list remaining issues.\n");
|
|
401
|
+
return [4 /*yield*/, this.agent.execute(prompt)];
|
|
402
|
+
case 1:
|
|
403
|
+
response = _a.sent();
|
|
404
|
+
if (response.includes("APPROVED")) {
|
|
405
|
+
this.state.slam.phase = "committing";
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
this.state.slam.phase = "fixing";
|
|
409
|
+
}
|
|
410
|
+
return [2 /*return*/];
|
|
411
|
+
}
|
|
412
|
+
});
|
|
413
|
+
});
|
|
414
|
+
};
|
|
415
|
+
/**
|
|
416
|
+
* Fixing phase - fix issues found
|
|
417
|
+
*/
|
|
418
|
+
GLMDaemon.prototype.phaseFixing = function () {
|
|
419
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
420
|
+
var prompt;
|
|
421
|
+
return __generator(this, function (_a) {
|
|
422
|
+
switch (_a.label) {
|
|
423
|
+
case 0:
|
|
424
|
+
console.log("[GLMDaemon] Phase: Fixing");
|
|
425
|
+
prompt = "Fix the issues identified in the review.\n\nUse tools to make necessary changes.\nTest your fixes thoroughly.\n";
|
|
426
|
+
return [4 /*yield*/, this.agent.execute(prompt)];
|
|
427
|
+
case 1:
|
|
428
|
+
_a.sent();
|
|
429
|
+
this.state.slam.phase = "paranoid"; // Re-check after fixes
|
|
430
|
+
return [2 /*return*/];
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
});
|
|
434
|
+
};
|
|
435
|
+
/**
|
|
436
|
+
* Committing phase - commit changes
|
|
437
|
+
*/
|
|
438
|
+
GLMDaemon.prototype.phaseCommitting = function () {
|
|
439
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
440
|
+
return __generator(this, function (_a) {
|
|
441
|
+
switch (_a.label) {
|
|
442
|
+
case 0:
|
|
443
|
+
console.log("[GLMDaemon] Phase: Committing");
|
|
444
|
+
if (!this.state.git.autoCommit) return [3 /*break*/, 2];
|
|
445
|
+
// Commit changes via worktree manager
|
|
446
|
+
return [4 /*yield*/, this.worktreeManager.commitChanges({
|
|
447
|
+
message: "feat: ".concat(this.state.prompt.substring(0, 50)),
|
|
448
|
+
files: this.state.filesChanged,
|
|
449
|
+
})];
|
|
450
|
+
case 1:
|
|
451
|
+
// Commit changes via worktree manager
|
|
452
|
+
_a.sent();
|
|
453
|
+
_a.label = 2;
|
|
454
|
+
case 2:
|
|
455
|
+
this.state.slam.phase = "complete";
|
|
456
|
+
return [2 /*return*/];
|
|
457
|
+
}
|
|
458
|
+
});
|
|
459
|
+
});
|
|
460
|
+
};
|
|
461
|
+
/**
|
|
462
|
+
* Complete the daemon run
|
|
463
|
+
*/
|
|
464
|
+
GLMDaemon.prototype.complete = function () {
|
|
465
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
466
|
+
return __generator(this, function (_a) {
|
|
467
|
+
switch (_a.label) {
|
|
468
|
+
case 0:
|
|
469
|
+
console.log("[GLMDaemon] Task complete!");
|
|
470
|
+
this.state.slam.phase = "complete";
|
|
471
|
+
this.running = false;
|
|
472
|
+
// Run session end hook
|
|
473
|
+
return [4 /*yield*/, this.hooks.execute("onSessionEnd", this.state)];
|
|
474
|
+
case 1:
|
|
475
|
+
// Run session end hook
|
|
476
|
+
_a.sent();
|
|
477
|
+
// Save final state
|
|
478
|
+
return [4 /*yield*/, this.stateManager.save(this.state)];
|
|
479
|
+
case 2:
|
|
480
|
+
// Save final state
|
|
481
|
+
_a.sent();
|
|
482
|
+
if (!this.state.git.autoPR) return [3 /*break*/, 4];
|
|
483
|
+
return [4 /*yield*/, this.worktreeManager.createPullRequest({
|
|
484
|
+
title: this.state.prompt.substring(0, 50),
|
|
485
|
+
body: "Completes: ".concat(this.state.promise),
|
|
486
|
+
})];
|
|
487
|
+
case 3:
|
|
488
|
+
_a.sent();
|
|
489
|
+
_a.label = 4;
|
|
490
|
+
case 4: return [2 /*return*/];
|
|
491
|
+
}
|
|
492
|
+
});
|
|
493
|
+
});
|
|
494
|
+
};
|
|
495
|
+
/**
|
|
496
|
+
* Stop the daemon
|
|
497
|
+
*/
|
|
498
|
+
GLMDaemon.prototype.stop = function () {
|
|
499
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
500
|
+
return __generator(this, function (_a) {
|
|
501
|
+
switch (_a.label) {
|
|
502
|
+
case 0:
|
|
503
|
+
console.log("[GLMDaemon] Stopping...");
|
|
504
|
+
this.running = false;
|
|
505
|
+
if (!this.team) return [3 /*break*/, 2];
|
|
506
|
+
return [4 /*yield*/, this.team.broadcast("team-lead", "Daemon stopping")];
|
|
507
|
+
case 1:
|
|
508
|
+
_a.sent();
|
|
509
|
+
_a.label = 2;
|
|
510
|
+
case 2:
|
|
511
|
+
// Save final state
|
|
512
|
+
return [4 /*yield*/, this.stateManager.save(this.state)];
|
|
513
|
+
case 3:
|
|
514
|
+
// Save final state
|
|
515
|
+
_a.sent();
|
|
516
|
+
return [2 /*return*/];
|
|
517
|
+
}
|
|
518
|
+
});
|
|
519
|
+
});
|
|
520
|
+
};
|
|
521
|
+
/**
|
|
522
|
+
* Get daemon status
|
|
523
|
+
*/
|
|
524
|
+
GLMDaemon.prototype.getStatus = function () {
|
|
525
|
+
return {
|
|
526
|
+
id: this.config.teamName,
|
|
527
|
+
status: this.running ? "running" : "stopped",
|
|
528
|
+
phase: this.state.slam.phase,
|
|
529
|
+
iteration: this.state.iteration,
|
|
530
|
+
prompt: this.state.prompt,
|
|
531
|
+
currentTask: this.state.slam.state.currentTask,
|
|
532
|
+
totalSubtasks: this.state.slam.subtasks.length,
|
|
533
|
+
completedSubtasks: this.state.slam.completedSubtasks.length,
|
|
534
|
+
startedAt: this.state.startTime,
|
|
535
|
+
lastUpdate: this.state.lastUpdate,
|
|
536
|
+
};
|
|
537
|
+
};
|
|
538
|
+
/**
|
|
539
|
+
* Parse subtasks from agent response
|
|
540
|
+
*/
|
|
541
|
+
GLMDaemon.prototype.parseSubtasks = function (response) {
|
|
542
|
+
try {
|
|
543
|
+
var jsonMatch = response.match(/\[[\s\S]*\]/);
|
|
544
|
+
if (jsonMatch) {
|
|
545
|
+
var parsed = JSON.parse(jsonMatch[0]);
|
|
546
|
+
return parsed.map(function (st, idx) { return ({
|
|
547
|
+
id: st.id || "subtask-".concat(idx),
|
|
548
|
+
title: st.title || st.task || "Subtask ".concat(idx + 1),
|
|
549
|
+
description: st.description || "",
|
|
550
|
+
status: "pending",
|
|
551
|
+
dependencies: st.dependencies || [],
|
|
552
|
+
}); });
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
catch (_a) {
|
|
556
|
+
// Fallback: create single subtask from prompt
|
|
557
|
+
return [{
|
|
558
|
+
id: "subtask-0",
|
|
559
|
+
title: this.state.prompt.substring(0, 50),
|
|
560
|
+
description: this.state.prompt,
|
|
561
|
+
status: "pending",
|
|
562
|
+
}];
|
|
563
|
+
}
|
|
564
|
+
return [];
|
|
565
|
+
};
|
|
566
|
+
/**
|
|
567
|
+
* Detect issues in paranoid check response
|
|
568
|
+
*/
|
|
569
|
+
GLMDaemon.prototype.detectIssues = function (response) {
|
|
570
|
+
var issueKeywords = [
|
|
571
|
+
"bug", "error", "issue", "problem", "vulnerability",
|
|
572
|
+
"fix", "improve", "missing", "incomplete", "broken"
|
|
573
|
+
];
|
|
574
|
+
var lower = response.toLowerCase();
|
|
575
|
+
return issueKeywords.some(function (kw) { return lower.includes(kw); });
|
|
576
|
+
};
|
|
577
|
+
/**
|
|
578
|
+
* Check if completion promise is met
|
|
579
|
+
*/
|
|
580
|
+
GLMDaemon.prototype.checkCompletion = function () {
|
|
581
|
+
var _this = this;
|
|
582
|
+
// Simple check: all subtasks complete
|
|
583
|
+
var allComplete = this.state.slam.subtasks.length > 0 &&
|
|
584
|
+
this.state.slam.subtasks.every(function (st) {
|
|
585
|
+
return _this.state.slam.completedSubtasks.includes(st.id);
|
|
586
|
+
});
|
|
587
|
+
return allComplete || this.state.slam.phase === "complete";
|
|
588
|
+
};
|
|
589
|
+
return GLMDaemon;
|
|
590
|
+
}());
|
|
591
|
+
exports.GLMDaemon = GLMDaemon;
|