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
2 changes: 1 addition & 1 deletion pins.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
},
"t3": {
"repo": "pingdotgg/t3code",
"commit": "0bc95fcdea918e2d155c53ab21e5beefdaa59733",
"commit": "d01b92c0613936e5204ea2787a9ed6bf7d1ff547",
"paths": [
"apps/server/src/mcp/toolkits/attachment/tools.ts",
"apps/server/src/mcp/toolkits/device/tools.ts",
Expand Down
27 changes: 13 additions & 14 deletions t3/contract/apps/server/src/provider/Drivers/ClaudeSkills.ts
Original file line number Diff line number Diff line change
Expand Up @@ -428,24 +428,25 @@ const resolveClaudeConfigDirPath = Effect.fn("resolveClaudeConfigDirPath")(funct
return path.join(home, ".claude");
});

const SettingsBaseUrl = fromLenientJson(
Schema.Struct({
env: Schema.optional(Schema.Struct({ ANTHROPIC_BASE_URL: Schema.optional(Schema.String) })),
}),
const SettingsEnv = Schema.Struct({
ANTHROPIC_BASE_URL: Schema.optional(Schema.String),
CLAUDE_CODE_ENTRYPOINT: Schema.optional(Schema.String),
});
const decodeSettingsEnv = Schema.decodeUnknownEffect(
fromLenientJson(Schema.Struct({ env: Schema.optional(SettingsEnv) })),
);
const decodeSettingsBaseUrl = Schema.decodeUnknownEffect(SettingsBaseUrl);

/** ANTHROPIC_BASE_URL from Claude's settings `env`, which Claude Code applies over the process env. */
export const readClaudeSettingsBaseUrl = Effect.fn("readClaudeSettingsBaseUrl")(function* (
/** The `env` values T3 Code reads from Claude's user and managed settings; later files win. */
export const readClaudeSettingsEnv = Effect.fn("readClaudeSettingsEnv")(function* (
config: Pick<ClaudeSettings, "homePath">,
cwd: string | undefined,
environment: NodeJS.ProcessEnv,
): Effect.fn.Return<string | undefined, never, FileSystem.FileSystem | Path.Path> {
): Effect.fn.Return<typeof SettingsEnv.Type, never, FileSystem.FileSystem | Path.Path> {
const fileSystem = yield* FileSystem.FileSystem;
const path = yield* Path.Path;
const platform = yield* HostProcess.Platform;
const configDirPath = yield* resolveClaudeConfigDirPath(config, environment, cwd);
let baseUrl: string | undefined;
const settingsEnv: typeof SettingsEnv.Type = {};
for (const settingsPath of claudeSettingsPaths(
path,
configDirPath,
Expand All @@ -457,12 +458,10 @@ export const readClaudeSettingsBaseUrl = Effect.fn("readClaudeSettingsBaseUrl")(
.readFileString(settingsPath)
.pipe(Effect.orElseSucceed(() => undefined));
if (contents === undefined) continue;
const parsed = yield* decodeSettingsBaseUrl(contents).pipe(
Effect.orElseSucceed(() => undefined),
);
baseUrl = parsed?.env?.ANTHROPIC_BASE_URL ?? baseUrl;
const parsed = yield* decodeSettingsEnv(contents).pipe(Effect.orElseSucceed(() => undefined));
Object.assign(settingsEnv, parsed?.env);
}
return baseUrl;
return settingsEnv;
});

// Claude's --add-dir is repeatable and variadic; parseCliArgs keeps only one value.
Expand Down
3 changes: 3 additions & 0 deletions t3/contract/packages/contracts/src/orchestratorMcp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,9 @@ export const OrchestratorMcpScheduledTask = Schema.Struct({
"Public URL for the sender. Absent: no T3 Connect tunnel. The user must enable T3 Connect remote access.",
}),
webhookSignature: Schema.optional(Schema.Literals(["none", "set"])),
blockedByPolicy: Schema.optional(Schema.String).annotate({
description: "Present when an administrator's policy stops this task from running.",
}),
});
export type OrchestratorMcpScheduledTask = typeof OrchestratorMcpScheduledTask.Type;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const PULL_REQUEST_LINKING_INSTRUCTIONS = `<pull_request_linking>
/** Session-invariant; harnesses with a native system-prompt append can carry it once per session. */
export const PULL_REQUEST_LINKING_INSTRUCTIONS = `<pull_request_linking>
Link each PR you create, take over, or push to: link_pull_request, or link_pull_requests for several, full URL, every stack layer, as your next call. Host tools do not link for you. If linking fails, say so. Skip PRs you only read or review, and PRs named only as background. Call watch_pull_request when asked to monitor or babysit, or when work you were asked to do, such as a merge, still waits on checks or reviews, even after an earlier unwatch. Finish any needed branch update and push first, then watch and end your turn. Otherwise act now or hand back. Delegated children never watch, even if the brief says babysit. After PR work, a child's last line is: PR <full URL>, head <SHA>, checks and reviews <state>. Links and watches persist across pushes. For PR waits, no sleep, loops, gh --watch, Monitor or ScheduleWakeup. Before handback, call unwatch_pull_request on any PR you watch.
</pull_request_linking>`;

Expand All @@ -8,6 +9,8 @@ export function buildRuntimeInstructions(runtime: {
readonly model?: string | undefined;
readonly modelName?: string | undefined;
readonly reasoningEffort?: string | undefined;
/** False when the session's system prompt already carries the linking instructions. */
readonly pullRequestLinking?: boolean;
}): string {
const harness = toSingleLine(runtime.harness);
const model = toSingleLine(runtime.model ?? "");
Expand All @@ -17,7 +20,10 @@ export function buildRuntimeInstructions(runtime: {
modelName && modelName !== model ? `${modelName} (model slug: ${model})` : model;
const modelInfo = model && model !== "auto" && model !== "default" ? `, as ${modelLabel}` : "";
const effortInfo = effort ? ` with ${effort} reasoning effort` : "";
return `<runtime_info>In case you're asked: you are running in T3 Code through the ${harness} harness${modelInfo}${effortInfo}. No need to mention this otherwise. You can embed images, video, and audio in your response using Markdown image syntax with absolute file paths. Link any other file you produce using its absolute path so the user can open it in T3 Code's files viewer.</runtime_info>\n\n${PULL_REQUEST_LINKING_INSTRUCTIONS}`;
const runtimeInfo = `<runtime_info>In case you're asked: you are running in T3 Code through the ${harness} harness${modelInfo}${effortInfo}. No need to mention this otherwise. You can embed images, video, and audio in your response using Markdown image syntax with absolute file paths. Link any other file you produce using its absolute path so the user can open it in T3 Code's files viewer.</runtime_info>`;
return runtime.pullRequestLinking === false
? runtimeInfo
: `${runtimeInfo}\n\n${PULL_REQUEST_LINKING_INSTRUCTIONS}`;
}

function toSingleLine(value: string): string {
Expand Down
Loading