mirror of
https://github.com/harivansh-afk/sandbox-agent.git
synced 2026-04-16 14:01:09 +00:00
Merge remote-tracking branch 'origin/main' into test-dev-webhooks-flow
# Conflicts: # factory/packages/backend/src/actors/project/actions.ts # factory/packages/backend/src/actors/workspace/actions.ts # factory/packages/frontend/src/components/mock-layout.tsx
This commit is contained in:
commit
c8a095b69f
302 changed files with 11419 additions and 9952 deletions
|
|
@ -2,53 +2,60 @@ import { z } from "zod";
|
|||
|
||||
export const AgentEnumSchema = z.enum(["claude", "codex"]);
|
||||
|
||||
export const NotifyBackendSchema = z.enum([
|
||||
"openclaw",
|
||||
"macos-osascript",
|
||||
"linux-notify-send",
|
||||
"terminal"
|
||||
]);
|
||||
export const NotifyBackendSchema = z.enum(["openclaw", "macos-osascript", "linux-notify-send", "terminal"]);
|
||||
|
||||
export const ConfigSchema = z.object({
|
||||
theme: z.string().min(1).optional(),
|
||||
auto_submit: z.boolean().default(false),
|
||||
default_agent: AgentEnumSchema.default("codex"),
|
||||
model: z.object({
|
||||
provider: z.string(),
|
||||
model: z.string()
|
||||
}).optional(),
|
||||
model: z
|
||||
.object({
|
||||
provider: z.string(),
|
||||
model: z.string(),
|
||||
})
|
||||
.optional(),
|
||||
notify: z.array(NotifyBackendSchema).default(["terminal"]),
|
||||
workspace: z.object({
|
||||
default: z.string().min(1).default("default")
|
||||
}).default({ default: "default" }),
|
||||
backend: z.object({
|
||||
host: z.string().default("127.0.0.1"),
|
||||
port: z.number().int().min(1).max(65535).default(7741),
|
||||
dbPath: z.string().default("~/.local/share/openhandoff/handoff.db"),
|
||||
opencode_poll_interval: z.number().default(2),
|
||||
github_poll_interval: z.number().default(30),
|
||||
backup_interval_secs: z.number().default(3600),
|
||||
backup_retention_days: z.number().default(7)
|
||||
}).default({
|
||||
host: "127.0.0.1",
|
||||
port: 7741,
|
||||
dbPath: "~/.local/share/openhandoff/handoff.db",
|
||||
opencode_poll_interval: 2,
|
||||
github_poll_interval: 30,
|
||||
backup_interval_secs: 3600,
|
||||
backup_retention_days: 7
|
||||
}),
|
||||
providers: z.object({
|
||||
local: z.object({
|
||||
rootDir: z.string().optional(),
|
||||
sandboxAgentPort: z.number().int().min(1).max(65535).optional(),
|
||||
}).default({}),
|
||||
daytona: z.object({
|
||||
endpoint: z.string().optional(),
|
||||
apiKey: z.string().optional(),
|
||||
image: z.string().default("ubuntu:24.04")
|
||||
}).default({ image: "ubuntu:24.04" })
|
||||
}).default({ local: {}, daytona: { image: "ubuntu:24.04" } })
|
||||
workspace: z
|
||||
.object({
|
||||
default: z.string().min(1).default("default"),
|
||||
})
|
||||
.default({ default: "default" }),
|
||||
backend: z
|
||||
.object({
|
||||
host: z.string().default("127.0.0.1"),
|
||||
port: z.number().int().min(1).max(65535).default(7741),
|
||||
dbPath: z.string().default("~/.local/share/openhandoff/handoff.db"),
|
||||
opencode_poll_interval: z.number().default(2),
|
||||
github_poll_interval: z.number().default(30),
|
||||
backup_interval_secs: z.number().default(3600),
|
||||
backup_retention_days: z.number().default(7),
|
||||
})
|
||||
.default({
|
||||
host: "127.0.0.1",
|
||||
port: 7741,
|
||||
dbPath: "~/.local/share/openhandoff/handoff.db",
|
||||
opencode_poll_interval: 2,
|
||||
github_poll_interval: 30,
|
||||
backup_interval_secs: 3600,
|
||||
backup_retention_days: 7,
|
||||
}),
|
||||
providers: z
|
||||
.object({
|
||||
local: z
|
||||
.object({
|
||||
rootDir: z.string().optional(),
|
||||
sandboxAgentPort: z.number().int().min(1).max(65535).optional(),
|
||||
})
|
||||
.default({}),
|
||||
daytona: z
|
||||
.object({
|
||||
endpoint: z.string().optional(),
|
||||
apiKey: z.string().optional(),
|
||||
image: z.string().default("ubuntu:24.04"),
|
||||
})
|
||||
.default({ image: "ubuntu:24.04" }),
|
||||
})
|
||||
.default({ local: {}, daytona: { image: "ubuntu:24.04" } }),
|
||||
});
|
||||
|
||||
export type AppConfig = z.infer<typeof ConfigSchema>;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
import { z } from "zod";
|
||||
|
||||
export const WorkspaceIdSchema = z.string().min(1).max(64).regex(/^[a-zA-Z0-9._-]+$/);
|
||||
export const WorkspaceIdSchema = z
|
||||
.string()
|
||||
.min(1)
|
||||
.max(64)
|
||||
.regex(/^[a-zA-Z0-9._-]+$/);
|
||||
export type WorkspaceId = z.infer<typeof WorkspaceIdSchema>;
|
||||
|
||||
export const ProviderIdSchema = z.enum(["daytona", "local"]);
|
||||
|
|
@ -36,7 +40,7 @@ export const HandoffStatusSchema = z.enum([
|
|||
"kill_destroy_sandbox",
|
||||
"kill_finalize",
|
||||
"killed",
|
||||
"error"
|
||||
"error",
|
||||
]);
|
||||
export type HandoffStatus = z.infer<typeof HandoffStatusSchema>;
|
||||
|
||||
|
|
@ -64,7 +68,7 @@ export const CreateHandoffInputSchema = z.object({
|
|||
initialPrompt: z.string().optional(),
|
||||
providerId: ProviderIdSchema.optional(),
|
||||
agentType: AgentTypeSchema.optional(),
|
||||
onBranch: z.string().trim().min(1).optional()
|
||||
onBranch: z.string().trim().min(1).optional(),
|
||||
});
|
||||
export type CreateHandoffInput = z.infer<typeof CreateHandoffInputSchema>;
|
||||
|
||||
|
|
@ -90,7 +94,7 @@ export const HandoffRecordSchema = z.object({
|
|||
cwd: z.string().nullable(),
|
||||
createdAt: z.number().int(),
|
||||
updatedAt: z.number().int(),
|
||||
})
|
||||
}),
|
||||
),
|
||||
agentType: z.string().nullable(),
|
||||
prSubmitted: z.boolean(),
|
||||
|
|
@ -104,7 +108,7 @@ export const HandoffRecordSchema = z.object({
|
|||
hasUnpushed: z.string().nullable(),
|
||||
parentBranch: z.string().nullable(),
|
||||
createdAt: z.number().int(),
|
||||
updatedAt: z.number().int()
|
||||
updatedAt: z.number().int(),
|
||||
});
|
||||
export type HandoffRecord = z.infer<typeof HandoffRecordSchema>;
|
||||
|
||||
|
|
@ -115,13 +119,13 @@ export const HandoffSummarySchema = z.object({
|
|||
branchName: z.string().min(1).nullable(),
|
||||
title: z.string().min(1).nullable(),
|
||||
status: HandoffStatusSchema,
|
||||
updatedAt: z.number().int()
|
||||
updatedAt: z.number().int(),
|
||||
});
|
||||
export type HandoffSummary = z.infer<typeof HandoffSummarySchema>;
|
||||
|
||||
export const HandoffActionInputSchema = z.object({
|
||||
workspaceId: WorkspaceIdSchema,
|
||||
handoffId: z.string().min(1)
|
||||
handoffId: z.string().min(1),
|
||||
});
|
||||
export type HandoffActionInput = z.infer<typeof HandoffActionInputSchema>;
|
||||
|
||||
|
|
@ -129,13 +133,13 @@ export const SwitchResultSchema = z.object({
|
|||
workspaceId: WorkspaceIdSchema,
|
||||
handoffId: z.string().min(1),
|
||||
providerId: ProviderIdSchema,
|
||||
switchTarget: z.string().min(1)
|
||||
switchTarget: z.string().min(1),
|
||||
});
|
||||
export type SwitchResult = z.infer<typeof SwitchResultSchema>;
|
||||
|
||||
export const ListHandoffsInputSchema = z.object({
|
||||
workspaceId: WorkspaceIdSchema,
|
||||
repoId: RepoIdSchema.optional()
|
||||
repoId: RepoIdSchema.optional(),
|
||||
});
|
||||
export type ListHandoffsInput = z.infer<typeof ListHandoffsInputSchema>;
|
||||
|
||||
|
|
@ -158,7 +162,7 @@ export const RepoBranchRecordSchema = z.object({
|
|||
reviewer: z.string().nullable(),
|
||||
firstSeenAt: z.number().int().nullable(),
|
||||
lastSeenAt: z.number().int().nullable(),
|
||||
updatedAt: z.number().int()
|
||||
updatedAt: z.number().int(),
|
||||
});
|
||||
export type RepoBranchRecord = z.infer<typeof RepoBranchRecordSchema>;
|
||||
|
||||
|
|
@ -169,17 +173,11 @@ export const RepoOverviewSchema = z.object({
|
|||
baseRef: z.string().nullable(),
|
||||
stackAvailable: z.boolean(),
|
||||
fetchedAt: z.number().int(),
|
||||
branches: z.array(RepoBranchRecordSchema)
|
||||
branches: z.array(RepoBranchRecordSchema),
|
||||
});
|
||||
export type RepoOverview = z.infer<typeof RepoOverviewSchema>;
|
||||
|
||||
export const RepoStackActionSchema = z.enum([
|
||||
"sync_repo",
|
||||
"restack_repo",
|
||||
"restack_subtree",
|
||||
"rebase_branch",
|
||||
"reparent_branch"
|
||||
]);
|
||||
export const RepoStackActionSchema = z.enum(["sync_repo", "restack_repo", "restack_subtree", "rebase_branch", "reparent_branch"]);
|
||||
export type RepoStackAction = z.infer<typeof RepoStackActionSchema>;
|
||||
|
||||
export const RepoStackActionInputSchema = z.object({
|
||||
|
|
@ -187,7 +185,7 @@ export const RepoStackActionInputSchema = z.object({
|
|||
repoId: RepoIdSchema,
|
||||
action: RepoStackActionSchema,
|
||||
branchName: z.string().trim().min(1).optional(),
|
||||
parentBranch: z.string().trim().min(1).optional()
|
||||
parentBranch: z.string().trim().min(1).optional(),
|
||||
});
|
||||
export type RepoStackActionInput = z.infer<typeof RepoStackActionInputSchema>;
|
||||
|
||||
|
|
@ -195,20 +193,31 @@ export const RepoStackActionResultSchema = z.object({
|
|||
action: RepoStackActionSchema,
|
||||
executed: z.boolean(),
|
||||
message: z.string().min(1),
|
||||
at: z.number().int()
|
||||
at: z.number().int(),
|
||||
});
|
||||
export type RepoStackActionResult = z.infer<typeof RepoStackActionResultSchema>;
|
||||
|
||||
export const WorkspaceUseInputSchema = z.object({
|
||||
workspaceId: WorkspaceIdSchema
|
||||
workspaceId: WorkspaceIdSchema,
|
||||
});
|
||||
export type WorkspaceUseInput = z.infer<typeof WorkspaceUseInputSchema>;
|
||||
|
||||
export const StarSandboxAgentRepoInputSchema = z.object({
|
||||
workspaceId: WorkspaceIdSchema,
|
||||
});
|
||||
export type StarSandboxAgentRepoInput = z.infer<typeof StarSandboxAgentRepoInputSchema>;
|
||||
|
||||
export const StarSandboxAgentRepoResultSchema = z.object({
|
||||
repo: z.string().min(1),
|
||||
starredAt: z.number().int(),
|
||||
});
|
||||
export type StarSandboxAgentRepoResult = z.infer<typeof StarSandboxAgentRepoResultSchema>;
|
||||
|
||||
export const HistoryQueryInputSchema = z.object({
|
||||
workspaceId: WorkspaceIdSchema,
|
||||
limit: z.number().int().positive().max(500).optional(),
|
||||
branch: z.string().min(1).optional(),
|
||||
handoffId: z.string().min(1).optional()
|
||||
handoffId: z.string().min(1).optional(),
|
||||
});
|
||||
export type HistoryQueryInput = z.infer<typeof HistoryQueryInputSchema>;
|
||||
|
||||
|
|
@ -220,14 +229,14 @@ export const HistoryEventSchema = z.object({
|
|||
branchName: z.string().nullable(),
|
||||
kind: z.string().min(1),
|
||||
payloadJson: z.string().min(1),
|
||||
createdAt: z.number().int()
|
||||
createdAt: z.number().int(),
|
||||
});
|
||||
export type HistoryEvent = z.infer<typeof HistoryEventSchema>;
|
||||
|
||||
export const PruneInputSchema = z.object({
|
||||
workspaceId: WorkspaceIdSchema,
|
||||
dryRun: z.boolean(),
|
||||
yes: z.boolean()
|
||||
yes: z.boolean(),
|
||||
});
|
||||
export type PruneInput = z.infer<typeof PruneInputSchema>;
|
||||
|
||||
|
|
@ -235,19 +244,19 @@ export const KillInputSchema = z.object({
|
|||
workspaceId: WorkspaceIdSchema,
|
||||
handoffId: z.string().min(1),
|
||||
deleteBranch: z.boolean(),
|
||||
abandon: z.boolean()
|
||||
abandon: z.boolean(),
|
||||
});
|
||||
export type KillInput = z.infer<typeof KillInputSchema>;
|
||||
|
||||
export const StatuslineInputSchema = z.object({
|
||||
workspaceId: WorkspaceIdSchema,
|
||||
format: z.enum(["table", "claude-code"])
|
||||
format: z.enum(["table", "claude-code"]),
|
||||
});
|
||||
export type StatuslineInput = z.infer<typeof StatuslineInputSchema>;
|
||||
|
||||
export const ListInputSchema = z.object({
|
||||
workspaceId: WorkspaceIdSchema,
|
||||
format: z.enum(["table", "json"]),
|
||||
full: z.boolean()
|
||||
full: z.boolean(),
|
||||
});
|
||||
export type ListInput = z.infer<typeof ListInputSchema>;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
import type { AppConfig } from "./config.js";
|
||||
|
||||
export function resolveWorkspaceId(
|
||||
flagWorkspace: string | undefined,
|
||||
config: AppConfig
|
||||
): string {
|
||||
export function resolveWorkspaceId(flagWorkspace: string | undefined, config: AppConfig): string {
|
||||
if (flagWorkspace && flagWorkspace.trim().length > 0) {
|
||||
return flagWorkspace.trim();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,11 +12,11 @@ const cfg: AppConfig = ConfigSchema.parse({
|
|||
opencode_poll_interval: 2,
|
||||
github_poll_interval: 30,
|
||||
backup_interval_secs: 3600,
|
||||
backup_retention_days: 7
|
||||
backup_retention_days: 7,
|
||||
},
|
||||
providers: {
|
||||
daytona: { image: "ubuntu:24.04" }
|
||||
}
|
||||
daytona: { image: "ubuntu:24.04" },
|
||||
},
|
||||
});
|
||||
|
||||
describe("resolveWorkspaceId", () => {
|
||||
|
|
@ -31,7 +31,7 @@ describe("resolveWorkspaceId", () => {
|
|||
it("falls back to literal default when config value is empty", () => {
|
||||
const empty = {
|
||||
...cfg,
|
||||
workspace: { default: "" }
|
||||
workspace: { default: "" },
|
||||
} as AppConfig;
|
||||
|
||||
expect(resolveWorkspaceId(undefined, empty)).toBe("default");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue