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
5 changes: 5 additions & 0 deletions apps/desktop/electron-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ const config: Configuration = {
to: "resources/migrations",
filter: ["**/*"],
},
{
from: "dist/resources/host-migrations",
to: "resources/host-migrations",
filter: ["**/*"],
},
],

files: [
Expand Down
2 changes: 2 additions & 0 deletions apps/desktop/src/main/host-service/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {

const authToken = process.env.AUTH_TOKEN;
const cloudApiUrl = process.env.CLOUD_API_URL;
const dbPath = process.env.HOST_DB_PATH;

const auth =
authToken && cloudApiUrl ? new JwtAuthProvider(authToken) : undefined;
Expand All @@ -24,6 +25,7 @@ const app = createApp({
credentials: new LocalCredentialProvider(),
auth,
cloudApiUrl,
dbPath,
});

const server = serve(
Expand Down
6 changes: 6 additions & 0 deletions apps/desktop/src/main/lib/host-service-manager.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { type ChildProcess, spawn } from "node:child_process";
import path from "node:path";
import { app } from "electron";
import { SUPERSET_HOME_DIR } from "./app-environment";

type HostServiceStatus = "starting" | "running" | "crashed";

Expand Down Expand Up @@ -69,6 +71,10 @@ class HostServiceManager {
...process.env,
ELECTRON_RUN_AS_NODE: "1",
ORGANIZATION_ID: organizationId,
HOST_DB_PATH: path.join(SUPERSET_HOME_DIR, "host.db"),
HOST_MIGRATIONS_PATH: app.isPackaged
? path.join(process.resourcesPath, "resources/host-migrations")
: path.join(app.getAppPath(), "../../packages/host-service/drizzle"),
};
if (this.authToken) {
env.AUTH_TOKEN = this.authToken;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ export function HostServiceStatus() {
const [cloudLoading, setCloudLoading] = useState(false);
const [cloudError, setCloudError] = useState<string | null>(null);

const [v2ProjectId, setV2ProjectId] = useState("");
const [v2WorkspaceId, setV2WorkspaceId] = useState("");
const [v2Branch, setV2Branch] = useState("main");
const [v2Loading, setV2Loading] = useState(false);
const [v2Result, setV2Result] = useState<string | null>(null);
const [v2Error, setV2Error] = useState<string | null>(null);

const checkHealth = useCallback(async () => {
if (!service) {
setStatus("unknown");
Expand Down Expand Up @@ -218,6 +225,114 @@ export function HostServiceStatus() {
)}
</div>

<div className="space-y-3 border-b border-border pb-3">
<span className="text-sm font-medium">V2 Operations</span>
<div className="flex gap-2">
<input
type="text"
value={v2ProjectId}
onChange={(e) => setV2ProjectId(e.target.value)}
placeholder="Project ID"
className="flex-1 rounded-md border border-input bg-background px-3 py-1.5 text-sm"
/>
<input
type="text"
value={v2Branch}
onChange={(e) => setV2Branch(e.target.value)}
placeholder="Branch"
className="w-32 rounded-md border border-input bg-background px-3 py-1.5 text-sm"
/>
</div>
<div className="flex gap-2">
<Button
size="sm"
variant="outline"
disabled={v2Loading || !service || !v2ProjectId}
onClick={async () => {
setV2Loading(true);
setV2Error(null);
setV2Result(null);
try {
const result =
await service?.client.workspace.create.mutate({
projectId: v2ProjectId,
name: `workspace-${v2Branch}`,
branch: v2Branch,
});
setV2WorkspaceId(result?.id ?? "");
setV2Result(JSON.stringify(result, null, 2));
} catch (err) {
setV2Error(err instanceof Error ? err.message : "Failed");
} finally {
setV2Loading(false);
}
}}
>
Create Workspace
</Button>
<Button
size="sm"
variant="outline"
disabled={v2Loading || !service || !v2WorkspaceId}
onClick={async () => {
setV2Loading(true);
setV2Error(null);
setV2Result(null);
try {
const result =
await service?.client.workspace.delete.mutate({
id: v2WorkspaceId,
});
setV2Result(JSON.stringify(result, null, 2));
setV2WorkspaceId("");
} catch (err) {
setV2Error(err instanceof Error ? err.message : "Failed");
} finally {
setV2Loading(false);
}
}}
>
Delete Workspace
</Button>
<Button
size="sm"
variant="outline"
disabled={v2Loading || !service || !v2ProjectId}
onClick={async () => {
setV2Loading(true);
setV2Error(null);
setV2Result(null);
try {
const result =
await service?.client.project.removeFromDevice.mutate({
projectId: v2ProjectId,
});
setV2Result(JSON.stringify(result, null, 2));
} catch (err) {
setV2Error(err instanceof Error ? err.message : "Failed");
} finally {
setV2Loading(false);
}
}}
>
Remove Project from Device
</Button>
</div>
{v2Loading && (
<div className="text-sm text-muted-foreground">Loading...</div>
)}
{v2Error && (
<div className="text-sm text-destructive bg-destructive/10 rounded-md px-3 py-2">
{v2Error}
</div>
)}
{v2Result && (
<pre className="text-xs font-mono bg-muted rounded-md p-2 overflow-auto max-h-40">
{v2Result}
</pre>
)}
</div>

{/* Git Operations */}
<div className="space-y-3 flex-1 min-h-0 flex flex-col">
<div className="flex gap-2">
Expand Down
4 changes: 4 additions & 0 deletions apps/desktop/vite/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ const RESOURCES_TO_COPY = [
src: resolve(__dirname, "../../../packages/local-db/drizzle"),
dest: resolve(__dirname, "..", devPath, "resources/migrations"),
},
{
src: resolve(__dirname, "../../../packages/host-service/drizzle"),
dest: resolve(__dirname, "..", devPath, "resources/host-migrations"),
},
{
src: resolve(__dirname, "../src/main/lib/agent-setup/templates"),
dest: resolve(__dirname, "..", devPath, "main/templates"),
Expand Down
6 changes: 5 additions & 1 deletion bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions packages/host-service/drizzle.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from "drizzle-kit";

export default defineConfig({
schema: "./src/db/schema.ts",
out: "./drizzle",
dialect: "sqlite",
});
18 changes: 18 additions & 0 deletions packages/host-service/drizzle/0000_initial_projects_workspaces.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
CREATE TABLE `projects` (
`id` text PRIMARY KEY NOT NULL,
`repo_path` text NOT NULL,
`created_at` integer NOT NULL
);
--> statement-breakpoint
CREATE INDEX `projects_repo_path_idx` ON `projects` (`repo_path`);--> statement-breakpoint
CREATE TABLE `workspaces` (
`id` text PRIMARY KEY NOT NULL,
`project_id` text NOT NULL,
`worktree_path` text NOT NULL,
`branch` text NOT NULL,
`created_at` integer NOT NULL,
FOREIGN KEY (`project_id`) REFERENCES `projects`(`id`) ON UPDATE no action ON DELETE cascade
);
--> statement-breakpoint
CREATE INDEX `workspaces_project_id_idx` ON `workspaces` (`project_id`);--> statement-breakpoint
CREATE INDEX `workspaces_branch_idx` ON `workspaces` (`branch`);
131 changes: 131 additions & 0 deletions packages/host-service/drizzle/meta/0000_snapshot.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
{
"version": "6",
"dialect": "sqlite",
"id": "6af1c5ed-ea02-45ae-8582-299afac9295e",
"prevId": "00000000-0000-0000-0000-000000000000",
"tables": {
"projects": {
"name": "projects",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"repo_path": {
"name": "repo_path",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"created_at": {
"name": "created_at",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
}
},
"indexes": {
"projects_repo_path_idx": {
"name": "projects_repo_path_idx",
"columns": [
"repo_path"
],
"isUnique": false
}
},
"foreignKeys": {},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
},
"workspaces": {
"name": "workspaces",
"columns": {
"id": {
"name": "id",
"type": "text",
"primaryKey": true,
"notNull": true,
"autoincrement": false
},
"project_id": {
"name": "project_id",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"worktree_path": {
"name": "worktree_path",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"branch": {
"name": "branch",
"type": "text",
"primaryKey": false,
"notNull": true,
"autoincrement": false
},
"created_at": {
"name": "created_at",
"type": "integer",
"primaryKey": false,
"notNull": true,
"autoincrement": false
}
},
"indexes": {
"workspaces_project_id_idx": {
"name": "workspaces_project_id_idx",
"columns": [
"project_id"
],
"isUnique": false
},
"workspaces_branch_idx": {
"name": "workspaces_branch_idx",
"columns": [
"branch"
],
"isUnique": false
}
},
"foreignKeys": {
"workspaces_project_id_projects_id_fk": {
"name": "workspaces_project_id_projects_id_fk",
"tableFrom": "workspaces",
"tableTo": "projects",
"columnsFrom": [
"project_id"
],
"columnsTo": [
"id"
],
"onDelete": "cascade",
"onUpdate": "no action"
}
},
"compositePrimaryKeys": {},
"uniqueConstraints": {},
"checkConstraints": {}
}
},
"views": {},
"enums": {},
"_meta": {
"schemas": {},
"tables": {},
"columns": {}
},
"internal": {
"indexes": {}
}
}
13 changes: 13 additions & 0 deletions packages/host-service/drizzle/meta/_journal.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"version": "7",
"dialect": "sqlite",
"entries": [
{
"idx": 0,
"version": "6",
"when": 1773188543980,
"tag": "0000_initial_projects_workspaces",
"breakpoints": true
}
]
}
Loading
Loading