clawspec 1.0.13 → 1.0.15
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/package.json +1 -1
- package/src/orchestrator/service.ts +23 -0
- package/src/utils/debug-log.ts +14 -0
package/package.json
CHANGED
|
@@ -6,6 +6,7 @@ import type {
|
|
|
6
6
|
PluginCommandResult,
|
|
7
7
|
PluginLogger,
|
|
8
8
|
} from "openclaw/plugin-sdk";
|
|
9
|
+
import { debugLog } from "../utils/debug-log.ts";
|
|
9
10
|
import { ProjectMemoryStore } from "../memory/store.ts";
|
|
10
11
|
import { OpenSpecClient, OpenSpecCommandError } from "../openspec/cli.ts";
|
|
11
12
|
import { parseTasksFile } from "../openspec/tasks.ts";
|
|
@@ -249,7 +250,9 @@ export class ClawSpecService {
|
|
|
249
250
|
event: PromptBuildEvent,
|
|
250
251
|
ctx: PromptBuildContext,
|
|
251
252
|
): Promise<{ prependContext?: string; prependSystemContext?: string } | void> {
|
|
253
|
+
debugLog(`[handleBeforePromptBuild] prompt="${event.prompt}", trigger=${ctx.trigger}`);
|
|
252
254
|
if (!shouldHandleUserVisiblePrompt(ctx.trigger)) {
|
|
255
|
+
debugLog(`[handleBeforePromptBuild] Skipped: non-user trigger`);
|
|
253
256
|
this.logger.debug?.(
|
|
254
257
|
`[clawspec] skipping prompt injection for non-user trigger "${ctx.trigger ?? "unknown"}".`,
|
|
255
258
|
);
|
|
@@ -257,6 +260,7 @@ export class ClawSpecService {
|
|
|
257
260
|
}
|
|
258
261
|
|
|
259
262
|
const keyword = extractEmbeddedClawSpecKeyword(event.prompt);
|
|
263
|
+
debugLog(`[handleBeforePromptBuild] keyword=${keyword?.command}`);
|
|
260
264
|
if (keyword) {
|
|
261
265
|
this.logger.debug?.(
|
|
262
266
|
`[clawspec] detected control keyword "${keyword.command}" for prompt build (session=${ctx.sessionKey ?? "unknown"}).`,
|
|
@@ -316,16 +320,21 @@ export class ClawSpecService {
|
|
|
316
320
|
|
|
317
321
|
switch (keyword.kind) {
|
|
318
322
|
case "plan": {
|
|
323
|
+
debugLog(`[cs-plan] Triggered for project: ${match?.project.changeName}`);
|
|
319
324
|
if (!match?.project.repoPath || !match.project.changeName) {
|
|
325
|
+
debugLog(`[cs-plan] Missing repoPath or changeName`);
|
|
320
326
|
return this.buildPluginReplyInjection(
|
|
321
327
|
event.prompt,
|
|
322
328
|
"Select a project and create a change first with `/clawspec use <project-name>` and `/clawspec proposal <change-name> [description]`.",
|
|
323
329
|
);
|
|
324
330
|
}
|
|
331
|
+
debugLog(`[cs-plan] Calling startVisiblePlanningSync`);
|
|
325
332
|
const planningSync = await this.startVisiblePlanningSync(match.channelKey, match.project, ctx, event.prompt, "apply");
|
|
326
333
|
if ("prependContext" in planningSync || "prependSystemContext" in planningSync) {
|
|
334
|
+
debugLog(`[cs-plan] Returning prompt injection`);
|
|
327
335
|
return planningSync;
|
|
328
336
|
}
|
|
337
|
+
debugLog(`[cs-plan] Returning plugin reply`);
|
|
329
338
|
return this.buildPluginReplyInjection(event.prompt, planningSync.text ?? "");
|
|
330
339
|
}
|
|
331
340
|
case "work":
|
|
@@ -758,14 +767,19 @@ export class ClawSpecService {
|
|
|
758
767
|
userPrompt: string,
|
|
759
768
|
mode: ExecutionMode,
|
|
760
769
|
): Promise<{ prependContext?: string; prependSystemContext?: string } | PluginCommandResult> {
|
|
770
|
+
debugLog(`[startVisiblePlanningSync] Called for ${project.changeName}`);
|
|
771
|
+
this.logger.info(`[clawspec] startVisiblePlanningSync called for ${project.changeName}`);
|
|
761
772
|
void project;
|
|
762
773
|
void mode;
|
|
763
774
|
|
|
764
775
|
const prepared = await this.preparePlanningSync(channelKey);
|
|
765
776
|
if ("result" in prepared) {
|
|
777
|
+
debugLog(`[startVisiblePlanningSync] preparePlanningSync failed`);
|
|
778
|
+
this.logger.warn(`[clawspec] preparePlanningSync returned error: ${prepared.result.text}`);
|
|
766
779
|
return prepared.result;
|
|
767
780
|
}
|
|
768
781
|
|
|
782
|
+
debugLog(`[startVisiblePlanningSync] Updating state to planning`);
|
|
769
783
|
const startedAt = new Date().toISOString();
|
|
770
784
|
const runningProject = await this.stateStore.updateProject(channelKey, (current) => ({
|
|
771
785
|
...current,
|
|
@@ -779,6 +793,8 @@ export class ClawSpecService {
|
|
|
779
793
|
execution: undefined,
|
|
780
794
|
lastExecutionAt: startedAt,
|
|
781
795
|
}));
|
|
796
|
+
debugLog(`[startVisiblePlanningSync] State updated: status=${runningProject.status}, phase=${runningProject.phase}, sessionKey=${runningProject.boundSessionKey}`);
|
|
797
|
+
this.logger.info(`[clawspec] Project state updated: status=planning, phase=planning_sync, boundSessionKey=${runningProject.boundSessionKey}`);
|
|
782
798
|
|
|
783
799
|
return await this.buildPlanningSyncInjection(runningProject, userPrompt, prepared.instructionResults);
|
|
784
800
|
}
|
|
@@ -896,6 +912,7 @@ export class ClawSpecService {
|
|
|
896
912
|
}
|
|
897
913
|
|
|
898
914
|
async handleAgentEnd(event: AgentEndEvent, ctx: PromptBuildContext): Promise<void> {
|
|
915
|
+
debugLog(`[agent_end] Called, sessionKey=${ctx.sessionKey}`);
|
|
899
916
|
const runningProject = await this.findRunningProjectBySessionKey(ctx.sessionKey);
|
|
900
917
|
if (runningProject?.repoPath && runningProject.changeName) {
|
|
901
918
|
const project = runningProject;
|
|
@@ -960,7 +977,9 @@ export class ClawSpecService {
|
|
|
960
977
|
|
|
961
978
|
const planningProject = await this.findPlanningProjectBySessionKey(ctx.sessionKey)
|
|
962
979
|
?? await this.findPlanningProjectByContext(ctx);
|
|
980
|
+
debugLog(`[agent_end] Planning project: ${planningProject?.changeName}, status=${planningProject?.status}, phase=${planningProject?.phase}`);
|
|
963
981
|
if (planningProject) {
|
|
982
|
+
debugLog(`[agent_end] Calling finalizePlanningTurn`);
|
|
964
983
|
this.logger.info(`[clawspec] agent_end: found planning project ${planningProject.changeName}, calling finalizePlanningTurn`);
|
|
965
984
|
await this.finalizePlanningTurn(planningProject, event);
|
|
966
985
|
return;
|
|
@@ -2409,8 +2428,10 @@ export class ClawSpecService {
|
|
|
2409
2428
|
}
|
|
2410
2429
|
|
|
2411
2430
|
private async finalizePlanningTurn(project: ProjectState, event: AgentEndEvent): Promise<void> {
|
|
2431
|
+
debugLog(`[finalizePlanningTurn] Called for ${project.changeName}, success=${event.success}`);
|
|
2412
2432
|
this.logger.info(`[clawspec] finalizePlanningTurn called for ${project.changeName}, success=${event.success}`);
|
|
2413
2433
|
if (!project.repoPath || !project.changeName) {
|
|
2434
|
+
debugLog(`[finalizePlanningTurn] Skipped: missing repoPath or changeName`);
|
|
2414
2435
|
this.logger.warn(`[clawspec] finalizePlanningTurn skipped: missing repoPath or changeName`);
|
|
2415
2436
|
return;
|
|
2416
2437
|
}
|
|
@@ -2470,7 +2491,9 @@ export class ClawSpecService {
|
|
|
2470
2491
|
}
|
|
2471
2492
|
}
|
|
2472
2493
|
|
|
2494
|
+
debugLog(`[finalizePlanningTurn] Writing snapshot`);
|
|
2473
2495
|
const snapshot = await journalStore.writeSnapshot(repoStatePaths.planningJournalSnapshotFile, project.changeName, timestamp);
|
|
2496
|
+
debugLog(`[finalizePlanningTurn] Snapshot written: entryCount=${snapshot.entryCount}, lastEntryAt=${snapshot.lastEntryAt}`);
|
|
2474
2497
|
this.logger.info(`[clawspec] Planning snapshot written for ${project.changeName}: entryCount=${snapshot.entryCount}, lastEntryAt=${snapshot.lastEntryAt}`);
|
|
2475
2498
|
this.logger.info(`[clawspec] Updating project state: status=${status}, phase=${phase}, dirty=${journalDirty}`);
|
|
2476
2499
|
await this.writeLatestSummary(repoStatePaths, latestSummary);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { appendFileSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
|
|
5
|
+
const LOG_FILE = path.join(homedir(), ".openclaw", "clawspec-debug.log");
|
|
6
|
+
|
|
7
|
+
export function debugLog(message: string): void {
|
|
8
|
+
try {
|
|
9
|
+
const timestamp = new Date().toISOString();
|
|
10
|
+
appendFileSync(LOG_FILE, `${timestamp} ${message}\n`);
|
|
11
|
+
} catch {
|
|
12
|
+
// ignore
|
|
13
|
+
}
|
|
14
|
+
}
|