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
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ function makeProject(
workspaceRoot: `/workspaces/${input.id}`,
repositoryIdentity: null,
defaultModelSelection: null,
gitHubAccount: null,
scripts: [],
createdAt: "2026-06-01T00:00:00.000Z",
updatedAt: "2026-06-01T00:00:00.000Z",
Expand Down
1 change: 1 addition & 0 deletions apps/mobile/src/features/home/homeListItems.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ function makeProject(id: string, title: string): EnvironmentProject {
workspaceRoot: `/workspaces/${id}`,
repositoryIdentity: null,
defaultModelSelection: null,
gitHubAccount: null,
scripts: [],
createdAt: "2026-06-01T00:00:00.000Z",
updatedAt: "2026-06-01T00:00:00.000Z",
Expand Down
1 change: 1 addition & 0 deletions apps/mobile/src/features/home/homeThreadList.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ function makeProject(
workspaceRoot: `/workspaces/${input.id}`,
repositoryIdentity: null,
defaultModelSelection: null,
gitHubAccount: null,
scripts: [],
createdAt: "2026-06-01T00:00:00.000Z",
updatedAt: "2026-06-01T00:00:00.000Z",
Expand Down
1 change: 1 addition & 0 deletions apps/mobile/src/features/home/homeThreadList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ export function buildHomeThreadGroups(input: {
pendingTask.creation.projectCwd ?? String(pendingTask.creation.projectId),
repositoryIdentity: null,
defaultModelSelection: null,
gitHubAccount: null,
scripts: [],
createdAt: pendingTask.message.createdAt,
updatedAt: pendingTask.message.createdAt,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ const projects: ReadonlyArray<EnvironmentProject> = [
workspaceRoot: "/workspace/t3code",
repositoryIdentity: null,
defaultModelSelection: { instanceId: ProviderInstanceId.make("codex"), model: "gpt-5.4" },
gitHubAccount: null,
scripts: [],
createdAt: "2026-07-16T08:00:00.000Z",
updatedAt: "2026-07-16T08:00:00.000Z",
Expand All @@ -26,6 +27,7 @@ const projects: ReadonlyArray<EnvironmentProject> = [
workspaceRoot: "/workspace/react",
repositoryIdentity: null,
defaultModelSelection: null,
gitHubAccount: null,
scripts: [],
createdAt: "2026-07-16T08:00:00.000Z",
updatedAt: "2026-07-16T08:00:00.000Z",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ export function NewTaskFlowProvider(props: React.PropsWithChildren) {
workspaceRoot: creation.projectCwd ?? "",
repositoryIdentity: null,
defaultModelSelection: editingPendingTask.modelSelection ?? null,
gitHubAccount: null,
scripts: [],
createdAt: editingPendingTask.createdAt,
updatedAt: editingPendingTask.createdAt,
Expand Down
1 change: 1 addition & 0 deletions apps/mobile/src/lib/repositoryGroups.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ function makeProject(
workspaceRoot: `/workspaces/${input.id}`,
repositoryIdentity: null,
defaultModelSelection: null,
gitHubAccount: null,
scripts: [],
createdAt: "2026-04-01T00:00:00.000Z",
updatedAt: "2026-04-01T00:00:00.000Z",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ describe("OrchestrationEngine", () => {
instanceId: ProviderInstanceId.make("codex"),
model: "gpt-5-codex",
},
gitHubAccount: null,
scripts: [],
createdAt: "2026-03-03T00:00:00.000Z",
updatedAt: "2026-03-03T00:00:01.000Z",
Expand Down
4 changes: 4 additions & 0 deletions apps/server/src/orchestration/Layers/ProjectionPipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
title: event.payload.title,
workspaceRoot: event.payload.workspaceRoot,
defaultModelSelection: event.payload.defaultModelSelection,
gitHubAccount: event.payload.gitHubAccount ?? null,
scripts: event.payload.scripts,
createdAt: event.payload.createdAt,
updatedAt: event.payload.updatedAt,
Expand All @@ -518,6 +519,9 @@ const makeOrchestrationProjectionPipeline = Effect.fn("makeOrchestrationProjecti
...(event.payload.defaultModelSelection !== undefined
? { defaultModelSelection: event.payload.defaultModelSelection }
: {}),
...(event.payload.gitHubAccount !== undefined
? { gitHubAccount: event.payload.gitHubAccount }
: {}),
...(event.payload.scripts !== undefined ? { scripts: event.payload.scripts } : {}),
updatedAt: event.payload.updatedAt,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ projectionSnapshotLayer("ProjectionSnapshotQuery", (it) => {
instanceId: ProviderInstanceId.make("codex"),
model: "gpt-5-codex",
},
gitHubAccount: null,
scripts: [
{
id: "script-1",
Expand Down Expand Up @@ -381,6 +382,7 @@ projectionSnapshotLayer("ProjectionSnapshotQuery", (it) => {
instanceId: ProviderInstanceId.make("codex"),
model: "gpt-5-codex",
},
gitHubAccount: null,
scripts: [
{
id: "script-1",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
ChatAttachment,
CheckpointRef,
GitHubAccountRef,
IsoDateTime,
MessageId,
NonNegativeInt,
Expand Down Expand Up @@ -65,6 +66,7 @@ const decodeThread = Schema.decodeUnknownEffect(OrchestrationThread);
const ProjectionProjectDbRowSchema = ProjectionProject.mapFields(
Struct.assign({
defaultModelSelection: Schema.NullOr(Schema.fromJsonString(ModelSelection)),
gitHubAccount: Schema.NullOr(Schema.fromJsonString(GitHubAccountRef)),
scripts: Schema.fromJsonString(Schema.Array(ProjectScript)),
}),
);
Expand Down Expand Up @@ -234,6 +236,7 @@ function mapProjectShellRow(
workspaceRoot: row.workspaceRoot,
repositoryIdentity,
defaultModelSelection: row.defaultModelSelection,
gitHubAccount: row.gitHubAccount,
scripts: row.scripts,
createdAt: row.createdAt,
updatedAt: row.updatedAt,
Expand Down Expand Up @@ -307,6 +310,7 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
title,
workspace_root AS "workspaceRoot",
default_model_selection_json AS "defaultModelSelection",
github_account_json AS "gitHubAccount",
scripts_json AS "scripts",
created_at AS "createdAt",
updated_at AS "updatedAt",
Expand Down Expand Up @@ -680,6 +684,7 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
title,
workspace_root AS "workspaceRoot",
default_model_selection_json AS "defaultModelSelection",
github_account_json AS "gitHubAccount",
scripts_json AS "scripts",
created_at AS "createdAt",
updated_at AS "updatedAt",
Expand All @@ -702,6 +707,7 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
title,
workspace_root AS "workspaceRoot",
default_model_selection_json AS "defaultModelSelection",
github_account_json AS "gitHubAccount",
scripts_json AS "scripts",
created_at AS "createdAt",
updated_at AS "updatedAt",
Expand Down Expand Up @@ -1183,6 +1189,7 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
workspaceRoot: row.workspaceRoot,
repositoryIdentity: repositoryIdentities.get(row.projectId) ?? null,
defaultModelSelection: row.defaultModelSelection,
gitHubAccount: row.gitHubAccount,
scripts: row.scripts,
createdAt: row.createdAt,
updatedAt: row.updatedAt,
Expand Down Expand Up @@ -1309,6 +1316,7 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
title: row.title,
workspaceRoot: row.workspaceRoot,
defaultModelSelection: row.defaultModelSelection,
gitHubAccount: row.gitHubAccount,
scripts: row.scripts,
createdAt: row.createdAt,
updatedAt: row.updatedAt,
Expand Down Expand Up @@ -1757,6 +1765,7 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
workspaceRoot: option.value.workspaceRoot,
repositoryIdentity,
defaultModelSelection: option.value.defaultModelSelection,
gitHubAccount: option.value.gitHubAccount,
scripts: option.value.scripts,
createdAt: option.value.createdAt,
updatedAt: option.value.updatedAt,
Expand Down
2 changes: 2 additions & 0 deletions apps/server/src/orchestration/commandInvariants.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const readModel: OrchestrationReadModel = {
instanceId: ProviderInstanceId.make("codex"),
model: "gpt-5-codex",
},
gitHubAccount: null,
scripts: [],
createdAt: now,
updatedAt: now,
Expand All @@ -46,6 +47,7 @@ const readModel: OrchestrationReadModel = {
instanceId: ProviderInstanceId.make("codex"),
model: "gpt-5-codex",
},
gitHubAccount: null,
scripts: [],
createdAt: now,
updatedAt: now,
Expand Down
4 changes: 4 additions & 0 deletions apps/server/src/orchestration/decider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ export const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand"
title: command.title,
workspaceRoot: command.workspaceRoot,
defaultModelSelection: command.defaultModelSelection ?? null,
gitHubAccount: command.gitHubAccount ?? null,
scripts: [],
createdAt: command.createdAt,
updatedAt: command.createdAt,
Expand Down Expand Up @@ -287,6 +288,9 @@ export const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand"
...(command.defaultModelSelection !== undefined
? { defaultModelSelection: command.defaultModelSelection }
: {}),
...(command.gitHubAccount !== undefined
? { gitHubAccount: command.gitHubAccount }
: {}),
...(command.scripts !== undefined ? { scripts: command.scripts } : {}),
updatedAt: occurredAt,
},
Expand Down
4 changes: 4 additions & 0 deletions apps/server/src/orchestration/projector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ export function projectEvent(
title: payload.title,
workspaceRoot: payload.workspaceRoot,
defaultModelSelection: payload.defaultModelSelection,
gitHubAccount: payload.gitHubAccount ?? null,
scripts: payload.scripts,
createdAt: payload.createdAt,
updatedAt: payload.updatedAt,
Expand Down Expand Up @@ -243,6 +244,9 @@ export function projectEvent(
...(payload.defaultModelSelection !== undefined
? { defaultModelSelection: payload.defaultModelSelection }
: {}),
...(payload.gitHubAccount !== undefined
? { gitHubAccount: payload.gitHubAccount }
: {}),
...(payload.scripts !== undefined ? { scripts: payload.scripts } : {}),
updatedAt: payload.updatedAt,
}
Expand Down
8 changes: 7 additions & 1 deletion apps/server/src/persistence/Layers/ProjectionProjects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import * as Layer from "effect/Layer";
import * as Schema from "effect/Schema";
import * as Struct from "effect/Struct";

import { ModelSelection, ProjectScript } from "@t3tools/contracts";
import { GitHubAccountRef, ModelSelection, ProjectScript } from "@t3tools/contracts";
import { toPersistenceSqlError } from "../Errors.ts";
import {
DeleteProjectionProjectInput,
Expand All @@ -18,6 +18,7 @@ import {
const ProjectionProjectDbRow = ProjectionProject.mapFields(
Struct.assign({
defaultModelSelection: Schema.NullOr(Schema.fromJsonString(ModelSelection)),
gitHubAccount: Schema.NullOr(Schema.fromJsonString(GitHubAccountRef)),
scripts: Schema.fromJsonString(Schema.Array(ProjectScript)),
}),
);
Expand All @@ -35,6 +36,7 @@ const makeProjectionProjectRepository = Effect.gen(function* () {
title,
workspace_root,
default_model_selection_json,
github_account_json,
scripts_json,
created_at,
updated_at,
Expand All @@ -45,6 +47,7 @@ const makeProjectionProjectRepository = Effect.gen(function* () {
${row.title},
${row.workspaceRoot},
${row.defaultModelSelection !== null ? JSON.stringify(row.defaultModelSelection) : null},
${row.gitHubAccount !== null ? JSON.stringify(row.gitHubAccount) : null},
${JSON.stringify(row.scripts)},
${row.createdAt},
${row.updatedAt},
Expand All @@ -55,6 +58,7 @@ const makeProjectionProjectRepository = Effect.gen(function* () {
title = excluded.title,
workspace_root = excluded.workspace_root,
default_model_selection_json = excluded.default_model_selection_json,
github_account_json = excluded.github_account_json,
scripts_json = excluded.scripts_json,
created_at = excluded.created_at,
updated_at = excluded.updated_at,
Expand All @@ -72,6 +76,7 @@ const makeProjectionProjectRepository = Effect.gen(function* () {
title,
workspace_root AS "workspaceRoot",
default_model_selection_json AS "defaultModelSelection",
github_account_json AS "gitHubAccount",
scripts_json AS "scripts",
created_at AS "createdAt",
updated_at AS "updatedAt",
Expand All @@ -91,6 +96,7 @@ const makeProjectionProjectRepository = Effect.gen(function* () {
title,
workspace_root AS "workspaceRoot",
default_model_selection_json AS "defaultModelSelection",
github_account_json AS "gitHubAccount",
scripts_json AS "scripts",
created_at AS "createdAt",
updated_at AS "updatedAt",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ projectionRepositoriesLayer("Projection repositories", (it) => {
instanceId: ProviderInstanceId.make("codex"),
model: "gpt-5.4",
},
gitHubAccount: null,
scripts: [],
createdAt: "2026-03-24T00:00:00.000Z",
updatedAt: "2026-03-24T00:00:00.000Z",
Expand Down
2 changes: 2 additions & 0 deletions apps/server/src/persistence/Migrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ import Migration0031 from "./Migrations/031_AuthAuthorizationScopes.ts";
import Migration0032 from "./Migrations/032_AuthPairingProofKeyThumbprint.ts";
import Migration0033 from "./Migrations/033_ProjectionThreadsSettled.ts";
import Migration0034 from "./Migrations/034_ProjectionThreadsSnoozed.ts";
import Migration0035 from "./Migrations/035_ProjectionProjectsGitHubAccount.ts";

/**
* Migration loader with all migrations defined inline.
Expand Down Expand Up @@ -93,6 +94,7 @@ export const migrationEntries = [
[32, "AuthPairingProofKeyThumbprint", Migration0032],
[33, "ProjectionThreadsSettled", Migration0033],
[34, "ProjectionThreadsSnoozed", Migration0034],
[35, "ProjectionProjectsGitHubAccount", Migration0035],
] as const;

export const makeMigrationLoader = (throughId?: number) =>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import * as Effect from "effect/Effect";
import * as SqlClient from "effect/unstable/sql/SqlClient";

export default Effect.gen(function* () {
const sql = yield* SqlClient.SqlClient;
const columns = yield* sql<{ readonly name: string }>`
PRAGMA table_info(projection_projects)
`;

if (!columns.some((column) => column.name === "github_account_json")) {
yield* sql`
ALTER TABLE projection_projects
ADD COLUMN github_account_json TEXT
`;
}
});
9 changes: 8 additions & 1 deletion apps/server/src/persistence/Services/ProjectionProjects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@
*
* @module ProjectionProjectRepository
*/
import { IsoDateTime, ModelSelection, ProjectId, ProjectScript } from "@t3tools/contracts";
import {
GitHubAccountRef,
IsoDateTime,
ModelSelection,
ProjectId,
ProjectScript,
} from "@t3tools/contracts";
import * as Option from "effect/Option";
import * as Schema from "effect/Schema";
import * as Context from "effect/Context";
Expand All @@ -19,6 +25,7 @@ export const ProjectionProject = Schema.Struct({
title: Schema.String,
workspaceRoot: Schema.String,
defaultModelSelection: Schema.NullOr(ModelSelection),
gitHubAccount: Schema.NullOr(GitHubAccountRef),
scripts: Schema.Array(ProjectScript),
createdAt: IsoDateTime,
updatedAt: IsoDateTime,
Expand Down
1 change: 1 addition & 0 deletions apps/server/src/project/ProjectSetupScriptRunner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const makeProject = (scripts: OrchestrationProject["scripts"]): OrchestrationPro
title: "Project",
workspaceRoot: "/repo/project",
defaultModelSelection: null,
gitHubAccount: null,
scripts,
createdAt: "2026-01-01T00:00:00.000Z",
updatedAt: "2026-01-01T00:00:00.000Z",
Expand Down
2 changes: 2 additions & 0 deletions apps/server/src/relay/AgentAwarenessRelay.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ describe.sequential("signRelayAgentActivityPublishProof", () => {
workspaceRoot: "/workspace",
repositoryIdentity: null,
defaultModelSelection: null,
gitHubAccount: null,
scripts: [],
createdAt: now,
updatedAt: now,
Expand Down Expand Up @@ -586,6 +587,7 @@ describe.sequential("signRelayAgentActivityPublishProof", () => {
workspaceRoot: "/workspace",
repositoryIdentity: null,
defaultModelSelection: null,
gitHubAccount: null,
scripts: [],
createdAt: now,
updatedAt: now,
Expand Down
2 changes: 2 additions & 0 deletions apps/server/src/server.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ const makeDefaultOrchestrationReadModel = () => {
title: "Default Project",
workspaceRoot: "/tmp/default-project",
defaultModelSelection,
gitHubAccount: null,
scripts: [],
createdAt: now,
updatedAt: now,
Expand Down Expand Up @@ -5687,6 +5688,7 @@ it.layer(NodeServices.layer)("server router seam", (it) => {
title: "Project A",
workspaceRoot: "/tmp/project-a",
defaultModelSelection,
gitHubAccount: null,
scripts: [],
createdAt: now,
updatedAt: now,
Expand Down
Loading