Skip to content

Commit 5535c98

Browse files
authored
Merge pull request #102 from arul28/release-10
Release 10: CTO pipeline, chat, sync, and cross-cutting improvements
2 parents 9e66957 + 79c64be commit 5535c98

81 files changed

Lines changed: 5847 additions & 977 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.ade/cto/openclaw-history.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

.ade/cto/openclaw-idempotency.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

.ade/cto/openclaw-outbox.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

.ade/cto/openclaw-routes.json

Lines changed: 0 additions & 3 deletions
This file was deleted.

apps/desktop/src/main/main.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { app, BrowserWindow, nativeImage, shell } from "electron";
2-
import { execSync } from "node:child_process";
2+
import { execFileSync } from "node:child_process";
33
import path from "node:path";
44
type NodePtyType = typeof import("node-pty");
55
import { registerIpc } from "./services/ipc/registerIpc";
@@ -123,8 +123,8 @@ function fixElectronShellPath(): void {
123123

124124
try {
125125
const loginShell = process.env.SHELL || "/bin/zsh";
126-
// Use login (-l) shell to source profile, printf to avoid trailing newline.
127-
const resolved = execSync(`${loginShell} -lc 'printf "%s" "$PATH"'`, {
126+
// Use execFileSync so SHELL is treated as a path, not interpolated shell text.
127+
const resolved = execFileSync(loginShell, ["-lc", 'printf "%s" "$PATH"'], {
128128
encoding: "utf-8",
129129
timeout: 5_000,
130130
}).trim();
@@ -570,6 +570,7 @@ app.whenReady().then(async () => {
570570
let conflictServiceRef: ReturnType<typeof createConflictService> | null = null;
571571
let prServiceRef: ReturnType<typeof createPrService> | null = null;
572572
let prPollingServiceRef: ReturnType<typeof createPrPollingService> | null = null;
573+
let testServiceRef: ReturnType<typeof createTestService> | null = null;
573574

574575
const lastHeadByLaneId = new Map<string, string>();
575576

@@ -1253,6 +1254,9 @@ app.whenReady().then(async () => {
12531254
linearCredentials: linearCredentialService,
12541255
prService,
12551256
processService,
1257+
getTestService: () => testServiceRef,
1258+
ptyService,
1259+
getAutomationService: () => automationService,
12561260
episodicSummaryService,
12571261
laneService,
12581262
sessionService,
@@ -1331,6 +1335,7 @@ app.whenReady().then(async () => {
13311335
emitProjectEvent(projectRoot, IPC.testsEvent, ev);
13321336
}
13331337
});
1338+
testServiceRef = testService;
13341339

13351340
automationService = createAutomationService({
13361341
db,

apps/desktop/src/main/services/ai/tools/ctoOperatorTools.test.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,40 @@ describe("createCtoOperatorTools", () => {
139139
expect(toolKeys).toContain("listFileWorkspaces");
140140
expect(toolKeys).toContain("readWorkspaceFile");
141141
expect(toolKeys).toContain("searchWorkspaceText");
142+
143+
// PR creation & management tools
144+
expect(toolKeys).toContain("createPrFromLane");
145+
expect(toolKeys).toContain("landPullRequest");
146+
expect(toolKeys).toContain("closePullRequest");
147+
expect(toolKeys).toContain("requestPrReviewers");
148+
149+
// Lane management tools
150+
expect(toolKeys).toContain("deleteLane");
151+
152+
// Worker management tools
153+
expect(toolKeys).toContain("removeWorker");
154+
expect(toolKeys).toContain("updateWorker");
155+
156+
// Test management tools
157+
expect(toolKeys).toContain("listTestSuites");
158+
expect(toolKeys).toContain("runTests");
159+
expect(toolKeys).toContain("stopTestRun");
160+
expect(toolKeys).toContain("listTestRuns");
161+
expect(toolKeys).toContain("getTestLog");
162+
163+
// Terminal management tools
164+
expect(toolKeys).toContain("createTerminal");
165+
166+
// Linear issue discovery tools
167+
expect(toolKeys).toContain("listLinearIssues");
168+
expect(toolKeys).toContain("getLinearIssue");
169+
expect(toolKeys).toContain("updateLinearIssueAssignee");
170+
expect(toolKeys).toContain("addLinearIssueLabel");
171+
172+
// Automation management tools
173+
expect(toolKeys).toContain("listAutomations");
174+
expect(toolKeys).toContain("triggerAutomation");
175+
expect(toolKeys).toContain("listAutomationRuns");
142176
});
143177

144178
// ── Chat tools ──────────────────────────────────────────────────
@@ -791,7 +825,7 @@ describe("createCtoOperatorTools", () => {
791825
// ── Linear workflow tools ───────────────────────────────────────
792826

793827
describe("Linear workflow tools", () => {
794-
it.each(["approve", "reject", "retry", "complete"] as const)(
828+
it.each(["approve", "reject", "retry", "resume", "complete"] as const)(
795829
"resolves Linear run actions for %s",
796830
async (action) => {
797831
const deps = buildDeps({
@@ -813,6 +847,8 @@ describe("createCtoOperatorTools", () => {
813847
action,
814848
"operator note",
815849
{ workflows: [] },
850+
undefined,
851+
undefined,
816852
);
817853
expect(result).toMatchObject({ success: true, run: { id: "run-1" } });
818854
},

0 commit comments

Comments
 (0)