Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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