clawspec 1.0.12 → 1.0.14

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawspec",
3
- "version": "1.0.12",
3
+ "version": "1.0.14",
4
4
  "type": "module",
5
5
  "description": "OpenClaw plugin that orchestrates OpenSpec project workflows with visible main-agent execution.",
6
6
  "keywords": [
@@ -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";
@@ -316,16 +317,21 @@ export class ClawSpecService {
316
317
 
317
318
  switch (keyword.kind) {
318
319
  case "plan": {
320
+ debugLog(`[cs-plan] Triggered for project: ${match?.project.changeName}`);
319
321
  if (!match?.project.repoPath || !match.project.changeName) {
322
+ debugLog(`[cs-plan] Missing repoPath or changeName`);
320
323
  return this.buildPluginReplyInjection(
321
324
  event.prompt,
322
325
  "Select a project and create a change first with `/clawspec use <project-name>` and `/clawspec proposal <change-name> [description]`.",
323
326
  );
324
327
  }
328
+ debugLog(`[cs-plan] Calling startVisiblePlanningSync`);
325
329
  const planningSync = await this.startVisiblePlanningSync(match.channelKey, match.project, ctx, event.prompt, "apply");
326
330
  if ("prependContext" in planningSync || "prependSystemContext" in planningSync) {
331
+ debugLog(`[cs-plan] Returning prompt injection`);
327
332
  return planningSync;
328
333
  }
334
+ debugLog(`[cs-plan] Returning plugin reply`);
329
335
  return this.buildPluginReplyInjection(event.prompt, planningSync.text ?? "");
330
336
  }
331
337
  case "work":
@@ -758,14 +764,19 @@ export class ClawSpecService {
758
764
  userPrompt: string,
759
765
  mode: ExecutionMode,
760
766
  ): Promise<{ prependContext?: string; prependSystemContext?: string } | PluginCommandResult> {
767
+ debugLog(`[startVisiblePlanningSync] Called for ${project.changeName}`);
768
+ this.logger.info(`[clawspec] startVisiblePlanningSync called for ${project.changeName}`);
761
769
  void project;
762
770
  void mode;
763
771
 
764
772
  const prepared = await this.preparePlanningSync(channelKey);
765
773
  if ("result" in prepared) {
774
+ debugLog(`[startVisiblePlanningSync] preparePlanningSync failed`);
775
+ this.logger.warn(`[clawspec] preparePlanningSync returned error: ${prepared.result.text}`);
766
776
  return prepared.result;
767
777
  }
768
778
 
779
+ debugLog(`[startVisiblePlanningSync] Updating state to planning`);
769
780
  const startedAt = new Date().toISOString();
770
781
  const runningProject = await this.stateStore.updateProject(channelKey, (current) => ({
771
782
  ...current,
@@ -779,6 +790,8 @@ export class ClawSpecService {
779
790
  execution: undefined,
780
791
  lastExecutionAt: startedAt,
781
792
  }));
793
+ debugLog(`[startVisiblePlanningSync] State updated: status=${runningProject.status}, phase=${runningProject.phase}, sessionKey=${runningProject.boundSessionKey}`);
794
+ this.logger.info(`[clawspec] Project state updated: status=planning, phase=planning_sync, boundSessionKey=${runningProject.boundSessionKey}`);
782
795
 
783
796
  return await this.buildPlanningSyncInjection(runningProject, userPrompt, prepared.instructionResults);
784
797
  }
@@ -896,6 +909,7 @@ export class ClawSpecService {
896
909
  }
897
910
 
898
911
  async handleAgentEnd(event: AgentEndEvent, ctx: PromptBuildContext): Promise<void> {
912
+ debugLog(`[agent_end] Called, sessionKey=${ctx.sessionKey}`);
899
913
  const runningProject = await this.findRunningProjectBySessionKey(ctx.sessionKey);
900
914
  if (runningProject?.repoPath && runningProject.changeName) {
901
915
  const project = runningProject;
@@ -960,7 +974,10 @@ export class ClawSpecService {
960
974
 
961
975
  const planningProject = await this.findPlanningProjectBySessionKey(ctx.sessionKey)
962
976
  ?? await this.findPlanningProjectByContext(ctx);
977
+ debugLog(`[agent_end] Planning project: ${planningProject?.changeName}, status=${planningProject?.status}, phase=${planningProject?.phase}`);
963
978
  if (planningProject) {
979
+ debugLog(`[agent_end] Calling finalizePlanningTurn`);
980
+ this.logger.info(`[clawspec] agent_end: found planning project ${planningProject.changeName}, calling finalizePlanningTurn`);
964
981
  await this.finalizePlanningTurn(planningProject, event);
965
982
  return;
966
983
  }
@@ -2408,7 +2425,11 @@ export class ClawSpecService {
2408
2425
  }
2409
2426
 
2410
2427
  private async finalizePlanningTurn(project: ProjectState, event: AgentEndEvent): Promise<void> {
2428
+ debugLog(`[finalizePlanningTurn] Called for ${project.changeName}, success=${event.success}`);
2429
+ this.logger.info(`[clawspec] finalizePlanningTurn called for ${project.changeName}, success=${event.success}`);
2411
2430
  if (!project.repoPath || !project.changeName) {
2431
+ debugLog(`[finalizePlanningTurn] Skipped: missing repoPath or changeName`);
2432
+ this.logger.warn(`[clawspec] finalizePlanningTurn skipped: missing repoPath or changeName`);
2412
2433
  return;
2413
2434
  }
2414
2435
 
@@ -2467,8 +2488,11 @@ export class ClawSpecService {
2467
2488
  }
2468
2489
  }
2469
2490
 
2491
+ debugLog(`[finalizePlanningTurn] Writing snapshot`);
2470
2492
  const snapshot = await journalStore.writeSnapshot(repoStatePaths.planningJournalSnapshotFile, project.changeName, timestamp);
2493
+ debugLog(`[finalizePlanningTurn] Snapshot written: entryCount=${snapshot.entryCount}, lastEntryAt=${snapshot.lastEntryAt}`);
2471
2494
  this.logger.info(`[clawspec] Planning snapshot written for ${project.changeName}: entryCount=${snapshot.entryCount}, lastEntryAt=${snapshot.lastEntryAt}`);
2495
+ this.logger.info(`[clawspec] Updating project state: status=${status}, phase=${phase}, dirty=${journalDirty}`);
2472
2496
  await this.writeLatestSummary(repoStatePaths, latestSummary);
2473
2497
 
2474
2498
  const finalized = await this.stateStore.updateProject(project.channelKey, (current) => ({
@@ -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
+ }