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
14 changes: 8 additions & 6 deletions apps/server/src/cli/thread.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ export class ThreadCliError extends Schema.TaggedErrorClass<ThreadCliError>()("T
const encodeJson = Schema.encodeEffect(Schema.fromJsonString(Schema.Unknown));
const isThreadCliError = Schema.is(ThreadCliError);

const currentThreadIdForHome = (home: string): string | undefined =>
process.env.T3CODE_HOME?.trim() === home ? process.env.T3CODE_THREAD_ID?.trim() : undefined;

const ThreadIdentity = Schema.Struct({
environmentId: Schema.String,
threadId: Schema.String,
Expand Down Expand Up @@ -890,6 +893,7 @@ const runThreadSend = Effect.fn("runThreadSend")(function* (
Effect.mapError((cause) => new ThreadSendServerUnavailableError({ cause })),
);
const minimumLogLevel = config.logLevel;
const currentThreadId = currentThreadIdForHome(config.baseDir);

return yield* Effect.gen(function* () {
const auth = yield* EnvironmentAuth.EnvironmentAuth;
Expand Down Expand Up @@ -956,12 +960,10 @@ const runThreadSend = Effect.fn("runThreadSend")(function* (
commandId,
messageId,
createdAt: DateTime.formatIso(yield* DateTime.now),
...(process.env.T3CODE_THREAD_ID?.trim()
? { sourceThreadId: ThreadId.make(process.env.T3CODE_THREAD_ID.trim()) }
: {}),
...(currentThreadId ? { sourceThreadId: ThreadId.make(currentThreadId) } : {}),
...(waitForCompletion ? { trackRequestCorrelation: true as const } : {}),
...(waitForCompletion && process.env.T3CODE_THREAD_ID?.trim()
? { rejectWaitForThreadId: ThreadId.make(process.env.T3CODE_THREAD_ID.trim()) }
...(waitForCompletion && currentThreadId
? { rejectWaitForThreadId: ThreadId.make(currentThreadId) }
: {}),
},
);
Expand Down Expand Up @@ -1046,7 +1048,7 @@ const runThreadWait = Effect.fn("runThreadWait")(function* (
),
});
}
const currentThreadId = process.env.T3CODE_THREAD_ID?.trim();
const currentThreadId = currentThreadIdForHome(config.baseDir);
const waitingOnCurrentThread = currentThreadId === waitHandle.threadId;
return yield* Effect.gen(function* () {
const auth = yield* EnvironmentAuth.EnvironmentAuth;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -381,11 +381,11 @@ layer("016_CanonicalizeModelSelections", (it) => {
);
});

layer("053_ClearAutomaticProjectModelDefaults", (it) => {
layer("044_ClearAutomaticProjectModelDefaults", (it) => {
it.effect("clears create-time seeds and preserves explicit project defaults", () =>
Effect.gen(function* () {
const sql = yield* SqlClient.SqlClient;
yield* runMigrations({ toMigrationInclusive: 52 });
yield* runMigrations({ toMigrationInclusive: 43 });

yield* sql`
INSERT INTO projection_projects (
Expand Down Expand Up @@ -429,7 +429,7 @@ layer("053_ClearAutomaticProjectModelDefaults", (it) => {
('event-explicit-update', 'project', 'project-explicit', 1, 'project.meta-updated', '2026-08-02T00:00:00.000Z', 'command-explicit-update', NULL, 'command-explicit-update', 'client', '{"defaultModelSelection":{"instanceId":"codex","model":"gpt-5.6-sol","options":[{"id":"reasoningEffort","value":"high"}]}}', '{}')
`;

yield* runMigrations({ toMigrationInclusive: 53 });
yield* runMigrations({ toMigrationInclusive: 44 });

const projects = yield* sql<{
readonly projectId: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ const layer = it.layer(Layer.mergeAll(NodeSqliteClient.layerMemory()));

const MODEL_SELECTION = '{"instanceId":"codex","model":"gpt-5.6-sol"}';

layer("055_RepairAutomaticSettlementTimestamps", (it) => {
layer("046_RepairAutomaticSettlementTimestamps", (it) => {
it.effect("repairs automatic stamps and leaves manual settlement alone", () =>
Effect.gen(function* () {
const sql = yield* SqlClient.SqlClient;
yield* runMigrations({ toMigrationInclusive: 54 });
yield* runMigrations({ toMigrationInclusive: 45 });

yield* sql`
INSERT INTO projection_threads (
Expand Down Expand Up @@ -164,7 +164,7 @@ layer("055_RepairAutomaticSettlementTimestamps", (it) => {
const eventsBefore =
yield* sql`SELECT payload_json FROM orchestration_events ORDER BY event_id`;

yield* runMigrations({ toMigrationInclusive: 55 });
yield* runMigrations({ toMigrationInclusive: 46 });

const threads = yield* sql<{
readonly threadId: string;
Expand Down
7 changes: 4 additions & 3 deletions apps/server/src/provider/Layers/CursorProvider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -368,26 +368,27 @@ describe("Cursor skills", () => {
"not a directory",
);

const realWorkspace = yield* fileSystem.realPath(workspace);
const skills = yield* discoverCursorSkills(workspace, { HOME: userHome });
expect(skills).toEqual([
{
name: "internal",
path: path.join(workspace, ".cursor", "skills", "internal", "SKILL.md"),
path: path.join(realWorkspace, ".cursor", "skills", "internal", "SKILL.md"),
scope: "project",
enabled: true,
userInvocable: false,
},
{
name: "oversized",
path: path.join(workspace, ".cursor", "skills", "oversized", "SKILL.md"),
path: path.join(realWorkspace, ".cursor", "skills", "oversized", "SKILL.md"),
scope: "project",
enabled: true,
},
{
name: "review",
displayName: "Review changes",
description: "project review",
path: path.join(workspace, ".agents", "skills", "nested", "review", "SKILL.md"),
path: path.join(realWorkspace, ".agents", "skills", "nested", "review", "SKILL.md"),
scope: "project",
enabled: true,
},
Expand Down
4 changes: 3 additions & 1 deletion scripts/lastcode-local-update.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -688,7 +688,9 @@ function buildUnlocked(options, updateRoot) {
if (!NodeFS.existsSync(installer)) {
throw new Error(`Checkpoint automation dependencies are missing at ${installer}.`);
}
run(worktreePath, installer, ["install", "--frozen-lockfile"], { logFd });
// The retained build worktree can otherwise keep stale snapshots of local
// file dependencies when their source changes without a lockfile change.
run(worktreePath, installer, ["install", "--frozen-lockfile", "--force"], { logFd });
const mise = resolveMise(options.home);
const nodeCommand = ["exec", "node@24.13.1", "--", "node"];
const nodeExecutable = run(worktreePath, mise, [...nodeCommand, "-p", "process.execPath"]);
Expand Down