Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .ade/cto/openclaw-history.json

This file was deleted.

1 change: 0 additions & 1 deletion .ade/cto/openclaw-idempotency.json

This file was deleted.

1 change: 0 additions & 1 deletion .ade/cto/openclaw-outbox.json

This file was deleted.

3 changes: 0 additions & 3 deletions .ade/cto/openclaw-routes.json

This file was deleted.

11 changes: 8 additions & 3 deletions apps/desktop/src/main/main.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { app, BrowserWindow, nativeImage, shell } from "electron";
import { execSync } from "node:child_process";
import { execFileSync } from "node:child_process";
import path from "node:path";
type NodePtyType = typeof import("node-pty");

Check warning on line 4 in apps/desktop/src/main/main.ts

View workflow job for this annotation

GitHub Actions / lint-desktop

`import()` type annotations are forbidden
import { registerIpc } from "./services/ipc/registerIpc";
import { createFileLogger } from "./services/logging/logger";
import { openKvDb } from "./services/state/kvDb";
Expand Down Expand Up @@ -123,8 +123,8 @@

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

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

Expand Down Expand Up @@ -1253,6 +1254,9 @@
linearCredentials: linearCredentialService,
prService,
processService,
getTestService: () => testServiceRef,
ptyService,
getAutomationService: () => automationService,
episodicSummaryService,
laneService,
sessionService,
Expand Down Expand Up @@ -1331,6 +1335,7 @@
emitProjectEvent(projectRoot, IPC.testsEvent, ev);
}
});
testServiceRef = testService;

automationService = createAutomationService({
db,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,40 @@ describe("createCtoOperatorTools", () => {
expect(toolKeys).toContain("listFileWorkspaces");
expect(toolKeys).toContain("readWorkspaceFile");
expect(toolKeys).toContain("searchWorkspaceText");

// PR creation & management tools
expect(toolKeys).toContain("createPrFromLane");
expect(toolKeys).toContain("landPullRequest");
expect(toolKeys).toContain("closePullRequest");
expect(toolKeys).toContain("requestPrReviewers");

// Lane management tools
expect(toolKeys).toContain("deleteLane");

// Worker management tools
expect(toolKeys).toContain("removeWorker");
expect(toolKeys).toContain("updateWorker");

// Test management tools
expect(toolKeys).toContain("listTestSuites");
expect(toolKeys).toContain("runTests");
expect(toolKeys).toContain("stopTestRun");
expect(toolKeys).toContain("listTestRuns");
expect(toolKeys).toContain("getTestLog");

// Terminal management tools
expect(toolKeys).toContain("createTerminal");

// Linear issue discovery tools
expect(toolKeys).toContain("listLinearIssues");
expect(toolKeys).toContain("getLinearIssue");
expect(toolKeys).toContain("updateLinearIssueAssignee");
expect(toolKeys).toContain("addLinearIssueLabel");

// Automation management tools
expect(toolKeys).toContain("listAutomations");
expect(toolKeys).toContain("triggerAutomation");
expect(toolKeys).toContain("listAutomationRuns");
});

// ── Chat tools ──────────────────────────────────────────────────
Expand Down Expand Up @@ -791,7 +825,7 @@ describe("createCtoOperatorTools", () => {
// ── Linear workflow tools ───────────────────────────────────────

describe("Linear workflow tools", () => {
it.each(["approve", "reject", "retry", "complete"] as const)(
it.each(["approve", "reject", "retry", "resume", "complete"] as const)(
"resolves Linear run actions for %s",
async (action) => {
const deps = buildDeps({
Expand All @@ -813,6 +847,8 @@ describe("createCtoOperatorTools", () => {
action,
"operator note",
{ workflows: [] },
undefined,
undefined,
);
expect(result).toMatchObject({ success: true, run: { id: "run-1" } });
},
Expand Down
Loading
Loading