clawspec 1.0.14 → 1.0.16
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/control/keywords.ts +18 -2
- package/src/orchestrator/service.ts +0 -17
- package/src/watchers/notifier.ts +1 -0
- package/src/utils/debug-log.ts +0 -14
package/package.json
CHANGED
package/src/control/keywords.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
|
|
1
2
|
export type ClawSpecKeywordKind =
|
|
2
3
|
| "plan"
|
|
3
4
|
| "work"
|
|
@@ -59,11 +60,26 @@ export function extractEmbeddedClawSpecKeyword(text: string): ClawSpecKeywordInt
|
|
|
59
60
|
return direct;
|
|
60
61
|
}
|
|
61
62
|
|
|
62
|
-
|
|
63
|
-
|
|
63
|
+
const lines = text.split(/\r?\n/);
|
|
64
|
+
for (const line of lines) {
|
|
65
|
+
const trimmed = line.trim();
|
|
66
|
+
if (!trimmed) continue;
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
// Try parsing the whole line first
|
|
70
|
+
const parsed = parseClawSpecKeyword(trimmed);
|
|
64
71
|
if (parsed) {
|
|
65
72
|
return parsed;
|
|
66
73
|
}
|
|
74
|
+
|
|
75
|
+
// Try each word in the line
|
|
76
|
+
const words = trimmed.split(/\s+/);
|
|
77
|
+
for (const word of words) {
|
|
78
|
+
const wordParsed = parseClawSpecKeyword(word);
|
|
79
|
+
if (wordParsed) {
|
|
80
|
+
return wordParsed;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
67
83
|
}
|
|
68
84
|
|
|
69
85
|
return null;
|
|
@@ -6,7 +6,6 @@ import type {
|
|
|
6
6
|
PluginCommandResult,
|
|
7
7
|
PluginLogger,
|
|
8
8
|
} from "openclaw/plugin-sdk";
|
|
9
|
-
import { debugLog } from "../utils/debug-log.ts";
|
|
10
9
|
import { ProjectMemoryStore } from "../memory/store.ts";
|
|
11
10
|
import { OpenSpecClient, OpenSpecCommandError } from "../openspec/cli.ts";
|
|
12
11
|
import { parseTasksFile } from "../openspec/tasks.ts";
|
|
@@ -317,21 +316,16 @@ export class ClawSpecService {
|
|
|
317
316
|
|
|
318
317
|
switch (keyword.kind) {
|
|
319
318
|
case "plan": {
|
|
320
|
-
debugLog(`[cs-plan] Triggered for project: ${match?.project.changeName}`);
|
|
321
319
|
if (!match?.project.repoPath || !match.project.changeName) {
|
|
322
|
-
debugLog(`[cs-plan] Missing repoPath or changeName`);
|
|
323
320
|
return this.buildPluginReplyInjection(
|
|
324
321
|
event.prompt,
|
|
325
322
|
"Select a project and create a change first with `/clawspec use <project-name>` and `/clawspec proposal <change-name> [description]`.",
|
|
326
323
|
);
|
|
327
324
|
}
|
|
328
|
-
debugLog(`[cs-plan] Calling startVisiblePlanningSync`);
|
|
329
325
|
const planningSync = await this.startVisiblePlanningSync(match.channelKey, match.project, ctx, event.prompt, "apply");
|
|
330
326
|
if ("prependContext" in planningSync || "prependSystemContext" in planningSync) {
|
|
331
|
-
debugLog(`[cs-plan] Returning prompt injection`);
|
|
332
327
|
return planningSync;
|
|
333
328
|
}
|
|
334
|
-
debugLog(`[cs-plan] Returning plugin reply`);
|
|
335
329
|
return this.buildPluginReplyInjection(event.prompt, planningSync.text ?? "");
|
|
336
330
|
}
|
|
337
331
|
case "work":
|
|
@@ -764,19 +758,16 @@ export class ClawSpecService {
|
|
|
764
758
|
userPrompt: string,
|
|
765
759
|
mode: ExecutionMode,
|
|
766
760
|
): Promise<{ prependContext?: string; prependSystemContext?: string } | PluginCommandResult> {
|
|
767
|
-
debugLog(`[startVisiblePlanningSync] Called for ${project.changeName}`);
|
|
768
761
|
this.logger.info(`[clawspec] startVisiblePlanningSync called for ${project.changeName}`);
|
|
769
762
|
void project;
|
|
770
763
|
void mode;
|
|
771
764
|
|
|
772
765
|
const prepared = await this.preparePlanningSync(channelKey);
|
|
773
766
|
if ("result" in prepared) {
|
|
774
|
-
debugLog(`[startVisiblePlanningSync] preparePlanningSync failed`);
|
|
775
767
|
this.logger.warn(`[clawspec] preparePlanningSync returned error: ${prepared.result.text}`);
|
|
776
768
|
return prepared.result;
|
|
777
769
|
}
|
|
778
770
|
|
|
779
|
-
debugLog(`[startVisiblePlanningSync] Updating state to planning`);
|
|
780
771
|
const startedAt = new Date().toISOString();
|
|
781
772
|
const runningProject = await this.stateStore.updateProject(channelKey, (current) => ({
|
|
782
773
|
...current,
|
|
@@ -790,7 +781,6 @@ export class ClawSpecService {
|
|
|
790
781
|
execution: undefined,
|
|
791
782
|
lastExecutionAt: startedAt,
|
|
792
783
|
}));
|
|
793
|
-
debugLog(`[startVisiblePlanningSync] State updated: status=${runningProject.status}, phase=${runningProject.phase}, sessionKey=${runningProject.boundSessionKey}`);
|
|
794
784
|
this.logger.info(`[clawspec] Project state updated: status=planning, phase=planning_sync, boundSessionKey=${runningProject.boundSessionKey}`);
|
|
795
785
|
|
|
796
786
|
return await this.buildPlanningSyncInjection(runningProject, userPrompt, prepared.instructionResults);
|
|
@@ -909,7 +899,6 @@ export class ClawSpecService {
|
|
|
909
899
|
}
|
|
910
900
|
|
|
911
901
|
async handleAgentEnd(event: AgentEndEvent, ctx: PromptBuildContext): Promise<void> {
|
|
912
|
-
debugLog(`[agent_end] Called, sessionKey=${ctx.sessionKey}`);
|
|
913
902
|
const runningProject = await this.findRunningProjectBySessionKey(ctx.sessionKey);
|
|
914
903
|
if (runningProject?.repoPath && runningProject.changeName) {
|
|
915
904
|
const project = runningProject;
|
|
@@ -974,9 +963,7 @@ export class ClawSpecService {
|
|
|
974
963
|
|
|
975
964
|
const planningProject = await this.findPlanningProjectBySessionKey(ctx.sessionKey)
|
|
976
965
|
?? await this.findPlanningProjectByContext(ctx);
|
|
977
|
-
debugLog(`[agent_end] Planning project: ${planningProject?.changeName}, status=${planningProject?.status}, phase=${planningProject?.phase}`);
|
|
978
966
|
if (planningProject) {
|
|
979
|
-
debugLog(`[agent_end] Calling finalizePlanningTurn`);
|
|
980
967
|
this.logger.info(`[clawspec] agent_end: found planning project ${planningProject.changeName}, calling finalizePlanningTurn`);
|
|
981
968
|
await this.finalizePlanningTurn(planningProject, event);
|
|
982
969
|
return;
|
|
@@ -2425,10 +2412,8 @@ export class ClawSpecService {
|
|
|
2425
2412
|
}
|
|
2426
2413
|
|
|
2427
2414
|
private async finalizePlanningTurn(project: ProjectState, event: AgentEndEvent): Promise<void> {
|
|
2428
|
-
debugLog(`[finalizePlanningTurn] Called for ${project.changeName}, success=${event.success}`);
|
|
2429
2415
|
this.logger.info(`[clawspec] finalizePlanningTurn called for ${project.changeName}, success=${event.success}`);
|
|
2430
2416
|
if (!project.repoPath || !project.changeName) {
|
|
2431
|
-
debugLog(`[finalizePlanningTurn] Skipped: missing repoPath or changeName`);
|
|
2432
2417
|
this.logger.warn(`[clawspec] finalizePlanningTurn skipped: missing repoPath or changeName`);
|
|
2433
2418
|
return;
|
|
2434
2419
|
}
|
|
@@ -2488,9 +2473,7 @@ export class ClawSpecService {
|
|
|
2488
2473
|
}
|
|
2489
2474
|
}
|
|
2490
2475
|
|
|
2491
|
-
debugLog(`[finalizePlanningTurn] Writing snapshot`);
|
|
2492
2476
|
const snapshot = await journalStore.writeSnapshot(repoStatePaths.planningJournalSnapshotFile, project.changeName, timestamp);
|
|
2493
|
-
debugLog(`[finalizePlanningTurn] Snapshot written: entryCount=${snapshot.entryCount}, lastEntryAt=${snapshot.lastEntryAt}`);
|
|
2494
2477
|
this.logger.info(`[clawspec] Planning snapshot written for ${project.changeName}: entryCount=${snapshot.entryCount}, lastEntryAt=${snapshot.lastEntryAt}`);
|
|
2495
2478
|
this.logger.info(`[clawspec] Updating project state: status=${status}, phase=${phase}, dirty=${journalDirty}`);
|
|
2496
2479
|
await this.writeLatestSummary(repoStatePaths, latestSummary);
|
package/src/watchers/notifier.ts
CHANGED
package/src/utils/debug-log.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
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
|
-
}
|