@laurentenhoor/devclaw 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.
Files changed (163) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +406 -0
  3. package/dist/index.d.ts +88 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +107 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/lib/audit.d.ts +2 -0
  8. package/dist/lib/audit.d.ts.map +1 -0
  9. package/dist/lib/audit.js +42 -0
  10. package/dist/lib/audit.js.map +1 -0
  11. package/dist/lib/binding-manager.d.ts +35 -0
  12. package/dist/lib/binding-manager.d.ts.map +1 -0
  13. package/dist/lib/binding-manager.js +88 -0
  14. package/dist/lib/binding-manager.js.map +1 -0
  15. package/dist/lib/cli.d.ts +12 -0
  16. package/dist/lib/cli.d.ts.map +1 -0
  17. package/dist/lib/cli.js +69 -0
  18. package/dist/lib/cli.js.map +1 -0
  19. package/dist/lib/dispatch.d.ts +58 -0
  20. package/dist/lib/dispatch.d.ts.map +1 -0
  21. package/dist/lib/dispatch.js +163 -0
  22. package/dist/lib/dispatch.js.map +1 -0
  23. package/dist/lib/model-selector.d.ts +21 -0
  24. package/dist/lib/model-selector.d.ts.map +1 -0
  25. package/dist/lib/model-selector.js +74 -0
  26. package/dist/lib/model-selector.js.map +1 -0
  27. package/dist/lib/notify.d.ts +54 -0
  28. package/dist/lib/notify.d.ts.map +1 -0
  29. package/dist/lib/notify.js +143 -0
  30. package/dist/lib/notify.js.map +1 -0
  31. package/dist/lib/onboarding.d.ts +5 -0
  32. package/dist/lib/onboarding.d.ts.map +1 -0
  33. package/dist/lib/onboarding.js +124 -0
  34. package/dist/lib/onboarding.js.map +1 -0
  35. package/dist/lib/projects.d.ts +64 -0
  36. package/dist/lib/projects.d.ts.map +1 -0
  37. package/dist/lib/projects.js +127 -0
  38. package/dist/lib/projects.js.map +1 -0
  39. package/dist/lib/providers/github.d.ts +23 -0
  40. package/dist/lib/providers/github.d.ts.map +1 -0
  41. package/dist/lib/providers/github.js +130 -0
  42. package/dist/lib/providers/github.js.map +1 -0
  43. package/dist/lib/providers/gitlab.d.ts +23 -0
  44. package/dist/lib/providers/gitlab.d.ts.map +1 -0
  45. package/dist/lib/providers/gitlab.js +133 -0
  46. package/dist/lib/providers/gitlab.js.map +1 -0
  47. package/dist/lib/providers/index.d.ts +12 -0
  48. package/dist/lib/providers/index.d.ts.map +1 -0
  49. package/dist/lib/providers/index.js +25 -0
  50. package/dist/lib/providers/index.js.map +1 -0
  51. package/dist/lib/providers/provider.d.ts +35 -0
  52. package/dist/lib/providers/provider.d.ts.map +1 -0
  53. package/dist/lib/providers/provider.js +13 -0
  54. package/dist/lib/providers/provider.js.map +1 -0
  55. package/dist/lib/services/health.d.ts +38 -0
  56. package/dist/lib/services/health.d.ts.map +1 -0
  57. package/dist/lib/services/health.js +100 -0
  58. package/dist/lib/services/health.js.map +1 -0
  59. package/dist/lib/services/heartbeat.d.ts +38 -0
  60. package/dist/lib/services/heartbeat.d.ts.map +1 -0
  61. package/dist/lib/services/heartbeat.js +199 -0
  62. package/dist/lib/services/heartbeat.js.map +1 -0
  63. package/dist/lib/services/pipeline.d.ts +36 -0
  64. package/dist/lib/services/pipeline.d.ts.map +1 -0
  65. package/dist/lib/services/pipeline.js +90 -0
  66. package/dist/lib/services/pipeline.js.map +1 -0
  67. package/dist/lib/services/queue.d.ts +14 -0
  68. package/dist/lib/services/queue.d.ts.map +1 -0
  69. package/dist/lib/services/queue.js +31 -0
  70. package/dist/lib/services/queue.js.map +1 -0
  71. package/dist/lib/services/tick.d.ts +62 -0
  72. package/dist/lib/services/tick.d.ts.map +1 -0
  73. package/dist/lib/services/tick.js +160 -0
  74. package/dist/lib/services/tick.js.map +1 -0
  75. package/dist/lib/setup/agent.d.ts +14 -0
  76. package/dist/lib/setup/agent.d.ts.map +1 -0
  77. package/dist/lib/setup/agent.js +72 -0
  78. package/dist/lib/setup/agent.js.map +1 -0
  79. package/dist/lib/setup/config.d.ts +22 -0
  80. package/dist/lib/setup/config.d.ts.map +1 -0
  81. package/dist/lib/setup/config.js +67 -0
  82. package/dist/lib/setup/config.js.map +1 -0
  83. package/dist/lib/setup/index.d.ts +53 -0
  84. package/dist/lib/setup/index.d.ts.map +1 -0
  85. package/dist/lib/setup/index.js +68 -0
  86. package/dist/lib/setup/index.js.map +1 -0
  87. package/dist/lib/setup/workspace.d.ts +6 -0
  88. package/dist/lib/setup/workspace.d.ts.map +1 -0
  89. package/dist/lib/setup/workspace.js +69 -0
  90. package/dist/lib/setup/workspace.js.map +1 -0
  91. package/dist/lib/templates.d.ts +9 -0
  92. package/dist/lib/templates.d.ts.map +1 -0
  93. package/dist/lib/templates.js +163 -0
  94. package/dist/lib/templates.js.map +1 -0
  95. package/dist/lib/tiers.d.ts +55 -0
  96. package/dist/lib/tiers.d.ts.map +1 -0
  97. package/dist/lib/tiers.js +74 -0
  98. package/dist/lib/tiers.js.map +1 -0
  99. package/dist/lib/tool-helpers.d.ts +44 -0
  100. package/dist/lib/tool-helpers.d.ts.map +1 -0
  101. package/dist/lib/tool-helpers.js +65 -0
  102. package/dist/lib/tool-helpers.js.map +1 -0
  103. package/dist/lib/tools/health.d.ts +28 -0
  104. package/dist/lib/tools/health.d.ts.map +1 -0
  105. package/dist/lib/tools/health.js +61 -0
  106. package/dist/lib/tools/health.js.map +1 -0
  107. package/dist/lib/tools/onboard.d.ts +24 -0
  108. package/dist/lib/tools/onboard.d.ts.map +1 -0
  109. package/dist/lib/tools/onboard.js +27 -0
  110. package/dist/lib/tools/onboard.js.map +1 -0
  111. package/dist/lib/tools/project-register.d.ts +51 -0
  112. package/dist/lib/tools/project-register.d.ts.map +1 -0
  113. package/dist/lib/tools/project-register.js +172 -0
  114. package/dist/lib/tools/project-register.js.map +1 -0
  115. package/dist/lib/tools/queue-status.test.d.ts +2 -0
  116. package/dist/lib/tools/queue-status.test.d.ts.map +1 -0
  117. package/dist/lib/tools/queue-status.test.js +48 -0
  118. package/dist/lib/tools/queue-status.test.js.map +1 -0
  119. package/dist/lib/tools/setup.d.ts +76 -0
  120. package/dist/lib/tools/setup.d.ts.map +1 -0
  121. package/dist/lib/tools/setup.js +102 -0
  122. package/dist/lib/tools/setup.js.map +1 -0
  123. package/dist/lib/tools/status.d.ts +24 -0
  124. package/dist/lib/tools/status.d.ts.map +1 -0
  125. package/dist/lib/tools/status.js +53 -0
  126. package/dist/lib/tools/status.js.map +1 -0
  127. package/dist/lib/tools/task-comment.d.ts +40 -0
  128. package/dist/lib/tools/task-comment.d.ts.map +1 -0
  129. package/dist/lib/tools/task-comment.js +84 -0
  130. package/dist/lib/tools/task-comment.js.map +1 -0
  131. package/dist/lib/tools/task-create.d.ts +54 -0
  132. package/dist/lib/tools/task-create.d.ts.map +1 -0
  133. package/dist/lib/tools/task-create.js +77 -0
  134. package/dist/lib/tools/task-create.js.map +1 -0
  135. package/dist/lib/tools/task-update.d.ts +40 -0
  136. package/dist/lib/tools/task-update.d.ts.map +1 -0
  137. package/dist/lib/tools/task-update.js +79 -0
  138. package/dist/lib/tools/task-update.js.map +1 -0
  139. package/dist/lib/tools/task-update.test.d.ts +7 -0
  140. package/dist/lib/tools/task-update.test.d.ts.map +1 -0
  141. package/dist/lib/tools/task-update.test.js +55 -0
  142. package/dist/lib/tools/task-update.test.js.map +1 -0
  143. package/dist/lib/tools/work-finish.d.ts +43 -0
  144. package/dist/lib/tools/work-finish.d.ts.map +1 -0
  145. package/dist/lib/tools/work-finish.js +77 -0
  146. package/dist/lib/tools/work-finish.js.map +1 -0
  147. package/dist/lib/tools/work-start.d.ts +39 -0
  148. package/dist/lib/tools/work-start.d.ts.map +1 -0
  149. package/dist/lib/tools/work-start.js +129 -0
  150. package/dist/lib/tools/work-start.js.map +1 -0
  151. package/dist/lib/types.d.ts +17 -0
  152. package/dist/lib/types.d.ts.map +1 -0
  153. package/dist/lib/types.js +8 -0
  154. package/dist/lib/types.js.map +1 -0
  155. package/docs/ARCHITECTURE.md +662 -0
  156. package/docs/CONFIGURATION.md +336 -0
  157. package/docs/MANAGEMENT.md +120 -0
  158. package/docs/ONBOARDING.md +251 -0
  159. package/docs/QA_WORKFLOW.md +120 -0
  160. package/docs/ROADMAP.md +96 -0
  161. package/docs/TESTING.md +339 -0
  162. package/docs/TOOLS.md +361 -0
  163. package/package.json +55 -0
@@ -0,0 +1,40 @@
1
+ /**
2
+ * task_update — Change issue state programmatically.
3
+ *
4
+ * Use cases:
5
+ * - Orchestrator or worker needs to change state without full pickup/complete flow
6
+ * - Manual status adjustments (e.g., Planning → To Do after approval)
7
+ * - Failed auto-transitions that need correction
8
+ */
9
+ import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
10
+ import type { ToolContext } from "../types.js";
11
+ export declare function createTaskUpdateTool(api: OpenClawPluginApi): (ctx: ToolContext) => {
12
+ name: string;
13
+ label: string;
14
+ description: string;
15
+ parameters: {
16
+ type: string;
17
+ required: string[];
18
+ properties: {
19
+ projectGroupId: {
20
+ type: string;
21
+ description: string;
22
+ };
23
+ issueId: {
24
+ type: string;
25
+ description: string;
26
+ };
27
+ state: {
28
+ type: string;
29
+ enum: readonly ["Planning", "To Do", "Doing", "To Test", "Testing", "Done", "To Improve", "Refining"];
30
+ description: string;
31
+ };
32
+ reason: {
33
+ type: string;
34
+ description: string;
35
+ };
36
+ };
37
+ };
38
+ execute(_id: string, params: Record<string, unknown>): Promise<import("@mariozechner/pi-agent-core").AgentToolResult<unknown>>;
39
+ };
40
+ //# sourceMappingURL=task-update.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-update.d.ts","sourceRoot":"","sources":["../../../lib/tools/task-update.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAK/C,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,iBAAiB,IACjD,KAAK,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsCH,MAAM,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;EAyC7D"}
@@ -0,0 +1,79 @@
1
+ import { jsonResult } from "openclaw/plugin-sdk";
2
+ import { log as auditLog } from "../audit.js";
3
+ import { STATE_LABELS } from "../providers/provider.js";
4
+ import { requireWorkspaceDir, resolveProject, resolveProvider } from "../tool-helpers.js";
5
+ export function createTaskUpdateTool(api) {
6
+ return (ctx) => ({
7
+ name: "task_update",
8
+ label: "Task Update",
9
+ description: `Change issue state programmatically. Use this when you need to update an issue's status without going through the full pickup/complete flow.
10
+
11
+ Use cases:
12
+ - Orchestrator or worker needs to change state manually
13
+ - Manual status adjustments (e.g., Planning → To Do after approval)
14
+ - Failed auto-transitions that need correction
15
+ - Bulk state changes
16
+
17
+ Examples:
18
+ - Simple: { projectGroupId: "-123456789", issueId: 42, state: "To Do" }
19
+ - With reason: { projectGroupId: "-123456789", issueId: 42, state: "To Do", reason: "Approved for development" }`,
20
+ parameters: {
21
+ type: "object",
22
+ required: ["projectGroupId", "issueId", "state"],
23
+ properties: {
24
+ projectGroupId: {
25
+ type: "string",
26
+ description: "Telegram/WhatsApp group ID (key in projects.json)",
27
+ },
28
+ issueId: {
29
+ type: "number",
30
+ description: "Issue ID to update",
31
+ },
32
+ state: {
33
+ type: "string",
34
+ enum: STATE_LABELS,
35
+ description: `New state for the issue. One of: ${STATE_LABELS.join(", ")}`,
36
+ },
37
+ reason: {
38
+ type: "string",
39
+ description: "Optional audit log reason for the state change",
40
+ },
41
+ },
42
+ },
43
+ async execute(_id, params) {
44
+ const groupId = params.projectGroupId;
45
+ const issueId = params.issueId;
46
+ const newState = params.state;
47
+ const reason = params.reason ?? undefined;
48
+ const workspaceDir = requireWorkspaceDir(ctx);
49
+ const { project } = await resolveProject(workspaceDir, groupId);
50
+ const { provider, type: providerType } = resolveProvider(project);
51
+ const issue = await provider.getIssue(issueId);
52
+ const currentState = provider.getCurrentStateLabel(issue);
53
+ if (!currentState) {
54
+ throw new Error(`Issue #${issueId} has no recognized state label. Cannot perform transition.`);
55
+ }
56
+ if (currentState === newState) {
57
+ return jsonResult({
58
+ success: true, issueId, state: newState, changed: false,
59
+ message: `Issue #${issueId} is already in state "${newState}".`,
60
+ project: project.name, provider: providerType,
61
+ });
62
+ }
63
+ await provider.transitionLabel(issueId, currentState, newState);
64
+ await auditLog(workspaceDir, "task_update", {
65
+ project: project.name, groupId, issueId,
66
+ fromState: currentState, toState: newState,
67
+ reason: reason ?? null, provider: providerType,
68
+ });
69
+ return jsonResult({
70
+ success: true, issueId, issueTitle: issue.title,
71
+ state: newState, changed: true,
72
+ labelTransition: `${currentState} → ${newState}`,
73
+ project: project.name, provider: providerType,
74
+ announcement: `🔄 Updated #${issueId}: "${currentState}" → "${newState}"${reason ? ` (${reason})` : ""}`,
75
+ });
76
+ },
77
+ });
78
+ }
79
+ //# sourceMappingURL=task-update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-update.js","sourceRoot":"","sources":["../../../lib/tools/task-update.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Integration test for task_update tool.
3
+ *
4
+ * Run manually: node --loader ts-node/esm lib/tools/task-update.test.ts
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=task-update.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-update.test.d.ts","sourceRoot":"","sources":["../../../lib/tools/task-update.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Integration test for task_update tool.
3
+ *
4
+ * Run manually: node --loader ts-node/esm lib/tools/task-update.test.ts
5
+ */
6
+ import { describe, it } from "node:test";
7
+ import assert from "node:assert";
8
+ describe("task_update tool", () => {
9
+ it("has correct schema", () => {
10
+ // Verify the tool signature matches requirements
11
+ const requiredParams = ["projectGroupId", "issueId", "state"];
12
+ const optionalParams = ["reason"];
13
+ // Schema validation would go here in a real test
14
+ assert.ok(true, "Schema structure is valid");
15
+ });
16
+ it("supports all state labels", () => {
17
+ const validStates = [
18
+ "Planning",
19
+ "To Do",
20
+ "Doing",
21
+ "To Test",
22
+ "Testing",
23
+ "Done",
24
+ "To Improve",
25
+ "Refining",
26
+ ];
27
+ // In a real test, we'd verify these against the tool's enum
28
+ assert.strictEqual(validStates.length, 8);
29
+ });
30
+ it("validates required parameters", () => {
31
+ // Test cases:
32
+ // - Missing projectGroupId → Error
33
+ // - Missing issueId → Error
34
+ // - Missing state → Error
35
+ // - Invalid state → Error
36
+ // - Valid params → Success
37
+ assert.ok(true, "Parameter validation works");
38
+ });
39
+ it("handles same-state transitions gracefully", () => {
40
+ // When current state === new state, should return success without changes
41
+ assert.ok(true, "No-op transitions handled correctly");
42
+ });
43
+ it("logs to audit trail", () => {
44
+ // Verify auditLog is called with correct parameters
45
+ assert.ok(true, "Audit logging works");
46
+ });
47
+ });
48
+ // Test scenarios for manual verification:
49
+ // 1. task_update({ projectGroupId: "-5239235162", issueId: 28, state: "Planning" })
50
+ // → Should transition from "To Do" to "Planning"
51
+ // 2. task_update({ projectGroupId: "-5239235162", issueId: 28, state: "Planning", reason: "Needs more discussion" })
52
+ // → Should log reason in audit trail
53
+ // 3. task_update({ projectGroupId: "-5239235162", issueId: 28, state: "To Do" })
54
+ // → Should transition back from "Planning" to "To Do"
55
+ //# sourceMappingURL=task-update.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-update.test.js","sourceRoot":"","sources":["../../../lib/tools/task-update.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,EAAE,CAAC,oBAAoB,EAAE,GAAG,EAAE;QAC5B,iDAAiD;QACjD,MAAM,cAAc,GAAG,CAAC,gBAAgB,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QAC9D,MAAM,cAAc,GAAG,CAAC,QAAQ,CAAC,CAAC;QAElC,iDAAiD;QACjD,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,2BAA2B,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,WAAW,GAAG;YAClB,UAAU;YACV,OAAO;YACP,OAAO;YACP,SAAS;YACT,SAAS;YACT,MAAM;YACN,YAAY;YACZ,UAAU;SACX,CAAC;QAEF,4DAA4D;QAC5D,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,cAAc;QACd,mCAAmC;QACnC,4BAA4B;QAC5B,0BAA0B;QAC1B,0BAA0B;QAC1B,2BAA2B;QAC3B,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,4BAA4B,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;QACnD,0EAA0E;QAC1E,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,qCAAqC,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qBAAqB,EAAE,GAAG,EAAE;QAC7B,oDAAoD;QACpD,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,qBAAqB,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,0CAA0C;AAC1C,oFAAoF;AACpF,oDAAoD;AACpD,qHAAqH;AACrH,wCAAwC;AACxC,iFAAiF;AACjF,yDAAyD"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * work_finish — Complete a task (DEV done, QA pass/fail/refine/blocked).
3
+ *
4
+ * Delegates side-effects to pipeline service, then ticks the project queue
5
+ * to fill free slots, sends notifications, and logs to audit.
6
+ */
7
+ import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
8
+ import type { ToolContext } from "../types.js";
9
+ export declare function createWorkFinishTool(api: OpenClawPluginApi): (ctx: ToolContext) => {
10
+ name: string;
11
+ label: string;
12
+ description: string;
13
+ parameters: {
14
+ type: string;
15
+ required: string[];
16
+ properties: {
17
+ role: {
18
+ type: string;
19
+ enum: string[];
20
+ description: string;
21
+ };
22
+ result: {
23
+ type: string;
24
+ enum: string[];
25
+ description: string;
26
+ };
27
+ projectGroupId: {
28
+ type: string;
29
+ description: string;
30
+ };
31
+ summary: {
32
+ type: string;
33
+ description: string;
34
+ };
35
+ prUrl: {
36
+ type: string;
37
+ description: string;
38
+ };
39
+ };
40
+ };
41
+ execute(_id: string, params: Record<string, unknown>): Promise<import("@mariozechner/pi-agent-core").AgentToolResult<unknown>>;
42
+ };
43
+ //# sourceMappingURL=work-finish.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"work-finish.d.ts","sourceRoot":"","sources":["../../../lib/tools/work-finish.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAO/C,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,iBAAiB,IACjD,KAAK,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAgBH,MAAM,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;EA+D7D"}
@@ -0,0 +1,77 @@
1
+ import { jsonResult } from "openclaw/plugin-sdk";
2
+ import { getWorker, resolveRepoPath } from "../projects.js";
3
+ import { executeCompletion, getRule, NEXT_STATE } from "../services/pipeline.js";
4
+ import { log as auditLog } from "../audit.js";
5
+ import { notify, getNotificationConfig } from "../notify.js";
6
+ import { requireWorkspaceDir, resolveProject, resolveProvider, getPluginConfig, tickAndNotify } from "../tool-helpers.js";
7
+ export function createWorkFinishTool(api) {
8
+ return (ctx) => ({
9
+ name: "work_finish",
10
+ label: "Work Finish",
11
+ description: `Complete a task: DEV done/blocked, QA pass/fail/refine/blocked. Handles label transition, state update, issue close/reopen, notifications, audit, and auto-ticks the queue to fill free slots.`,
12
+ parameters: {
13
+ type: "object",
14
+ required: ["role", "result", "projectGroupId"],
15
+ properties: {
16
+ role: { type: "string", enum: ["dev", "qa"], description: "Worker role" },
17
+ result: { type: "string", enum: ["done", "pass", "fail", "refine", "blocked"], description: "Completion result" },
18
+ projectGroupId: { type: "string", description: "Project group ID" },
19
+ summary: { type: "string", description: "Brief summary" },
20
+ prUrl: { type: "string", description: "PR/MR URL (auto-detected if omitted)" },
21
+ },
22
+ },
23
+ async execute(_id, params) {
24
+ const role = params.role;
25
+ const result = params.result;
26
+ const groupId = params.projectGroupId;
27
+ const summary = params.summary;
28
+ const prUrl = params.prUrl;
29
+ const workspaceDir = requireWorkspaceDir(ctx);
30
+ // Validate role:result
31
+ if (role === "dev" && result !== "done" && result !== "blocked")
32
+ throw new Error(`DEV can only complete with "done" or "blocked", got "${result}"`);
33
+ if (role === "qa" && result === "done")
34
+ throw new Error(`QA cannot use "done". Use "pass", "fail", "refine", or "blocked".`);
35
+ if (!getRule(role, result))
36
+ throw new Error(`Invalid completion: ${role}:${result}`);
37
+ // Resolve project + worker
38
+ const { project } = await resolveProject(workspaceDir, groupId);
39
+ const worker = getWorker(project, role);
40
+ if (!worker.active)
41
+ throw new Error(`${role.toUpperCase()} worker not active on ${project.name}`);
42
+ const issueId = worker.issueId ? Number(worker.issueId.split(",")[0]) : null;
43
+ if (!issueId)
44
+ throw new Error(`No issueId for active ${role.toUpperCase()} on ${project.name}`);
45
+ const { provider } = resolveProvider(project);
46
+ const repoPath = resolveRepoPath(project.repo);
47
+ const issue = await provider.getIssue(issueId);
48
+ // Execute completion (pipeline service)
49
+ const completion = await executeCompletion({
50
+ workspaceDir, groupId, role, result, issueId, summary, prUrl, provider, repoPath,
51
+ });
52
+ const output = {
53
+ success: true, project: project.name, groupId, issueId, role, result,
54
+ ...completion,
55
+ };
56
+ // Notify completion
57
+ const pluginConfig = getPluginConfig(api);
58
+ const notifyConfig = getNotificationConfig(pluginConfig);
59
+ await notify({ type: "workerComplete", project: project.name, groupId, issueId, issueUrl: issue.web_url, role, result: result, summary, nextState: NEXT_STATE[`${role}:${result}`] }, { workspaceDir, config: notifyConfig, groupId, channel: project.channel ?? "telegram" });
60
+ // Tick: fill free slots + notify starts
61
+ const tickPickups = await tickAndNotify({
62
+ workspaceDir, groupId, agentId: ctx.agentId, pluginConfig, sessionKey: ctx.sessionKey,
63
+ channel: project.channel ?? "telegram",
64
+ });
65
+ if (tickPickups.length)
66
+ output.tickPickups = tickPickups;
67
+ // Audit
68
+ await auditLog(workspaceDir, "work_finish", {
69
+ project: project.name, groupId, issue: issueId, role, result,
70
+ summary: summary ?? null, labelTransition: completion.labelTransition,
71
+ tickPickups: tickPickups.length,
72
+ });
73
+ return jsonResult(output);
74
+ },
75
+ });
76
+ }
77
+ //# sourceMappingURL=work-finish.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"work-finish.js","sourceRoot":"","sources":["../../../lib/tools/work-finish.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * work_start — Pick up a task from the issue queue.
3
+ *
4
+ * Context-aware: ONLY works in project group chats.
5
+ * Auto-detects: projectGroupId, role, level, issueId.
6
+ * Picks up only the explicitly requested issue (auto-tick disabled).
7
+ */
8
+ import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
9
+ import type { ToolContext } from "../types.js";
10
+ export declare function createWorkStartTool(api: OpenClawPluginApi): (ctx: ToolContext) => {
11
+ name: string;
12
+ label: string;
13
+ description: string;
14
+ parameters: {
15
+ type: string;
16
+ required: string[];
17
+ properties: {
18
+ projectGroupId: {
19
+ type: string;
20
+ description: string;
21
+ };
22
+ issueId: {
23
+ type: string;
24
+ description: string;
25
+ };
26
+ role: {
27
+ type: string;
28
+ enum: string[];
29
+ description: string;
30
+ };
31
+ level: {
32
+ type: string;
33
+ description: string;
34
+ };
35
+ };
36
+ };
37
+ execute(_id: string, params: Record<string, unknown>): Promise<import("@mariozechner/pi-agent-core").AgentToolResult<unknown>>;
38
+ };
39
+ //# sourceMappingURL=work-start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"work-start.d.ts","sourceRoot":"","sources":["../../../lib/tools/work-start.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAU/C,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,iBAAiB,IAChD,KAAK,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAeH,MAAM,UAAU,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;EAyF7D"}
@@ -0,0 +1,129 @@
1
+ import { jsonResult } from "openclaw/plugin-sdk";
2
+ import { selectLevel } from "../model-selector.js";
3
+ import { getWorker } from "../projects.js";
4
+ import { dispatchTask } from "../dispatch.js";
5
+ import { notify, getNotificationConfig } from "../notify.js";
6
+ import { findNextIssue, detectRoleFromLabel, detectLevelFromLabels } from "../services/tick.js";
7
+ import { isDevLevel } from "../tiers.js";
8
+ import { requireWorkspaceDir, resolveProject, resolveProvider, getPluginConfig } from "../tool-helpers.js";
9
+ export function createWorkStartTool(api) {
10
+ return (ctx) => ({
11
+ name: "work_start",
12
+ label: "Work Start",
13
+ description: `Pick up a task from the issue queue. ONLY works in project group chats. Handles label transition, level assignment, session creation, dispatch, and audit. Picks up only the explicitly requested issue.`,
14
+ parameters: {
15
+ type: "object",
16
+ required: ["projectGroupId"],
17
+ properties: {
18
+ projectGroupId: { type: "string", description: "Project group ID." },
19
+ issueId: { type: "number", description: "Issue ID. If omitted, picks next by priority." },
20
+ role: { type: "string", enum: ["dev", "qa"], description: "Worker role. Auto-detected from label if omitted." },
21
+ level: { type: "string", description: "Developer level (junior/medior/senior/reviewer). Auto-detected if omitted." },
22
+ },
23
+ },
24
+ async execute(_id, params) {
25
+ const issueIdParam = params.issueId;
26
+ const roleParam = params.role;
27
+ const groupId = params.projectGroupId;
28
+ const levelParam = (params.level ?? params.tier);
29
+ const workspaceDir = requireWorkspaceDir(ctx);
30
+ if (!groupId)
31
+ throw new Error("projectGroupId is required");
32
+ const { project } = await resolveProject(workspaceDir, groupId);
33
+ const { provider } = resolveProvider(project);
34
+ // Find issue
35
+ let issue;
36
+ let currentLabel;
37
+ if (issueIdParam !== undefined) {
38
+ issue = await provider.getIssue(issueIdParam);
39
+ const label = provider.getCurrentStateLabel(issue);
40
+ if (!label)
41
+ throw new Error(`Issue #${issueIdParam} has no recognized state label`);
42
+ currentLabel = label;
43
+ }
44
+ else {
45
+ const next = await findNextIssue(provider, roleParam);
46
+ if (!next)
47
+ return jsonResult({ success: false, error: `No issues available. Queue is empty.` });
48
+ issue = next.issue;
49
+ currentLabel = next.label;
50
+ }
51
+ // Detect role
52
+ const detectedRole = detectRoleFromLabel(currentLabel);
53
+ if (!detectedRole)
54
+ throw new Error(`Label "${currentLabel}" doesn't map to a role`);
55
+ const role = roleParam ?? detectedRole;
56
+ if (roleParam && roleParam !== detectedRole)
57
+ throw new Error(`Role mismatch: "${currentLabel}" → ${detectedRole}, requested ${roleParam}`);
58
+ // Check worker availability
59
+ const worker = getWorker(project, role);
60
+ if (worker.active)
61
+ throw new Error(`${role.toUpperCase()} already active on ${project.name} (issue: ${worker.issueId})`);
62
+ if ((project.roleExecution ?? "parallel") === "sequential") {
63
+ const other = role === "dev" ? "qa" : "dev";
64
+ if (getWorker(project, other).active)
65
+ throw new Error(`Sequential roleExecution: ${other.toUpperCase()} is active`);
66
+ }
67
+ // Select level
68
+ const targetLabel = role === "dev" ? "Doing" : "Testing";
69
+ let selectedLevel, levelReason, levelSource;
70
+ if (levelParam) {
71
+ selectedLevel = levelParam;
72
+ levelReason = "LLM-selected";
73
+ levelSource = "llm";
74
+ }
75
+ else {
76
+ const labelLevel = detectLevelFromLabels(issue.labels);
77
+ if (labelLevel) {
78
+ if (role === "qa" && isDevLevel(labelLevel)) {
79
+ const s = selectLevel(issue.title, issue.description ?? "", role);
80
+ selectedLevel = s.level;
81
+ levelReason = `QA overrides dev level "${labelLevel}"`;
82
+ levelSource = "role-override";
83
+ }
84
+ else if (role === "dev" && !isDevLevel(labelLevel)) {
85
+ const s = selectLevel(issue.title, issue.description ?? "", role);
86
+ selectedLevel = s.level;
87
+ levelReason = s.reason;
88
+ levelSource = "heuristic";
89
+ }
90
+ else {
91
+ selectedLevel = labelLevel;
92
+ levelReason = `Label: "${labelLevel}"`;
93
+ levelSource = "label";
94
+ }
95
+ }
96
+ else {
97
+ const s = selectLevel(issue.title, issue.description ?? "", role);
98
+ selectedLevel = s.level;
99
+ levelReason = s.reason;
100
+ levelSource = "heuristic";
101
+ }
102
+ }
103
+ // Dispatch
104
+ const pluginConfig = getPluginConfig(api);
105
+ const dr = await dispatchTask({
106
+ workspaceDir, agentId: ctx.agentId, groupId, project, issueId: issue.iid,
107
+ issueTitle: issue.title, issueDescription: issue.description ?? "", issueUrl: issue.web_url,
108
+ role, level: selectedLevel, fromLabel: currentLabel, toLabel: targetLabel,
109
+ transitionLabel: (id, from, to) => provider.transitionLabel(id, from, to),
110
+ pluginConfig, sessionKey: ctx.sessionKey,
111
+ });
112
+ // Notify
113
+ const notifyConfig = getNotificationConfig(pluginConfig);
114
+ await notify({ type: "workerStart", project: project.name, groupId, issueId: issue.iid, issueTitle: issue.title, issueUrl: issue.web_url, role, level: dr.level, sessionAction: dr.sessionAction }, { workspaceDir, config: notifyConfig, groupId, channel: project.channel ?? "telegram" });
115
+ // Auto-tick disabled per issue #125 - work_start should only pick up the explicitly requested issue
116
+ // The heartbeat service fills parallel slots automatically
117
+ const output = {
118
+ success: true, project: project.name, groupId, issueId: issue.iid, issueTitle: issue.title,
119
+ role, level: dr.level, model: dr.model, sessionAction: dr.sessionAction,
120
+ announcement: dr.announcement, labelTransition: `${currentLabel} → ${targetLabel}`,
121
+ levelReason, levelSource,
122
+ autoDetected: { role: !roleParam, issueId: issueIdParam === undefined, level: !levelParam },
123
+ };
124
+ // tickPickups removed with auto-tick
125
+ return jsonResult(output);
126
+ },
127
+ });
128
+ }
129
+ //# sourceMappingURL=work-start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"work-start.js","sourceRoot":"","sources":["../../../lib/tools/work-start.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Shared types for the DevClaw plugin.
3
+ *
4
+ * OpenClawPluginToolContext is declared in the plugin-sdk but not exported.
5
+ * We define a compatible local type for use in tool factory functions.
6
+ */
7
+ export type ToolContext = {
8
+ config?: Record<string, unknown>;
9
+ workspaceDir?: string;
10
+ agentDir?: string;
11
+ agentId?: string;
12
+ sessionKey?: string;
13
+ messageChannel?: string;
14
+ agentAccountId?: string;
15
+ sandboxed?: boolean;
16
+ };
17
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../lib/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Shared types for the DevClaw plugin.
3
+ *
4
+ * OpenClawPluginToolContext is declared in the plugin-sdk but not exported.
5
+ * We define a compatible local type for use in tool factory functions.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../lib/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}