Files
tutti/tools/scripts/generate-defaults.mjs
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

176 lines
6.0 KiB
JavaScript

import { execFileSync } from "node:child_process";
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
import { fileURLToPath, pathToFileURL } from "node:url";
import { format } from "prettier";
const __dirname = dirname(fileURLToPath(import.meta.url));
const repoRoot = resolve(__dirname, "../..");
const defaultsPath = resolve(repoRoot, "config/tutti.defaults.json");
const goOutputPath = resolve(
repoRoot,
"services/tuttid/types/defaults_generated.go"
);
const cliGoOutputPath = resolve(
repoRoot,
"apps/cli/internal/defaults/defaults_generated.go"
);
const tsOutputPath = resolve(
repoRoot,
"apps/desktop/src/main/generated/defaults.ts"
);
const prettierConfigPath = resolve(
repoRoot,
"packages/configs/prettier/base.mjs"
);
const checkOnly = process.argv.includes("--check");
const { default: prettierConfig } = await import(
pathToFileURL(prettierConfigPath).href
);
if (isMainModule()) {
const spec = JSON.parse(readFileSync(defaultsPath, "utf8"));
writeGeneratedFile(goOutputPath, renderGoDefaults(spec));
writeGeneratedFile(cliGoOutputPath, renderCliGoDefaults(spec));
writeGeneratedFile(tsOutputPath, await renderTSDefaults(spec));
}
function isMainModule() {
return Boolean(
process.argv[1] &&
resolve(process.argv[1]) === fileURLToPath(import.meta.url)
);
}
function writeGeneratedFile(targetPath, content) {
mkdirSync(dirname(targetPath), { recursive: true });
if (checkOnly) {
const existing = readFileSync(targetPath, "utf8");
if (existing !== content) {
throw new Error(`Generated defaults are out of date: ${targetPath}`);
}
return;
}
writeFileSync(targetPath, content, "utf8");
}
export function renderGoDefaults(specification) {
return formatGo(`package types
// Code generated by tools/scripts/generate-defaults.mjs. DO NOT EDIT.
var generatedDefaults = generatedDefaultsSpec{
\tState: generatedStateDefaults{
\t\tProductionDirName: ${goString(specification.state.productionDirName)},
\t\tDevelopmentDirName: ${goString(specification.state.developmentDirName)},
\t\tRunDirName: ${goString(specification.state.runDirName)},
\t\tLogsDirName: ${goString(specification.state.logsDirName)},
\t\tDBFileName: ${goString(specification.state.dbFileName)},
\t\tDaemonLogFileName: ${goString(specification.state.daemonLogFileName)},
\t\tDesktopLogFileName: ${goString(specification.state.desktopLogFileName)},
\t\tListenerInfoFileName: ${goString(specification.state.listenerInfoFileName)},
\t\tPIDFileName: ${goString(specification.state.pidFileName)},
\t},
\tTransport: generatedTransportDefaults{
\t\tDefaultTCPAddr: ${goString(specification.transport.defaultTCPAddr)},
\t},
\tLogging: generatedLoggingDefaults{
\t\tDefaultLevel: ${goString(specification.logging.defaultLevel)},
\t\tDefaultOutput: ${goString(specification.logging.defaultOutput)},
\t\tMaxSizeMB: ${specification.logging.maxSizeMB},
\t\tMaxBackups: ${specification.logging.maxBackups},
\t\tMaxAgeDays: ${specification.logging.maxAgeDays},
\t\tMaxTotalMB: ${specification.logging.maxTotalMB},
\t},
\tAnalytics: generatedAnalyticsDefaults{
\t\tAppID: ${specification.analytics.appId},
\t\tAppKey: ${goString(specification.analytics.appKey)},
\t\tChannel: ${goString(specification.analytics.channel)},
\t\tChannelDomain: ${goString(specification.analytics.channelDomain)},
\t\tAppVersion: ${goString(specification.analytics.appVersion)},
\t},
\tAgentExtensions: generatedAgentExtensionDefaults{
\t\tSources: []generatedAgentExtensionSourceDefaults{
${(specification.agentExtensions?.sources ?? [])
.map(
(source) => `\t\t\t{
\t\t\t\tKey: ${goString(source.key)},
\t\t\t\tPinnedVersion: ${goString(source.pinnedVersion)},
\t\t\t\tReleaseIndexURL: ${goString(source.releaseIndexUrl)},
\t\t\t\tFallbackReleaseIndexURLs: ${goStringSlice(source.fallbackReleaseIndexUrls)},
\t\t\t\tSigningKeyID: ${goString(source.signingKeyId)},
\t\t\t\tSigningPublicKey: ${goString(source.signingPublicKey)},
\t\t\t\tEnabled: ${source.enabled},
\t\t\t},`
)
.join("\n")}
\t\t},
\t},
\tAgentRuntimeTools: generatedAgentRuntimeToolDefaults{
\t\tUV: generatedUVToolDefaults{
\t\t\tVersion: ${goString(specification.agentRuntimeTools?.uv?.version ?? "")},
\t\t\tArtifacts: []generatedUVToolArtifactDefaults{
${(specification.agentRuntimeTools?.uv?.artifacts ?? [])
.map(
(artifact) => `\t\t\t\t{
\t\t\t\t\tPlatform: ${goString(artifact.platform)},
\t\t\t\t\tURL: ${goString(artifact.url)},
\t\t\t\t\tSHA256: ${goString(artifact.sha256)},
\t\t\t\t\tSizeBytes: ${artifact.sizeBytes},
\t\t\t\t\tArchive: ${goString(artifact.archive)},
\t\t\t\t\tArchiveExecutable: ${goString(artifact.archiveExecutable)},
\t\t\t\t},`
)
.join("\n")}
\t\t\t},
\t\t},
\t},
}
`);
}
export function renderCliGoDefaults(specification) {
return formatGo(`package defaults
// Code generated by tools/scripts/generate-defaults.mjs. DO NOT EDIT.
var generatedDefaults = generatedDefaultsSpec{
\tState: generatedStateDefaults{
\t\tProductionDirName: ${goString(specification.state.productionDirName)},
\t\tDevelopmentDirName: ${goString(specification.state.developmentDirName)},
\t\tRunDirName: ${goString(specification.state.runDirName)},
\t\tListenerInfoFileName: ${goString(specification.state.listenerInfoFileName)},
\t},
}
`);
}
export async function renderTSDefaults(specification) {
return await format(
`export const generatedDefaults = ${JSON.stringify(specification, null, 2)} as const;\n`,
{
...prettierConfig,
parser: "typescript"
}
);
}
function goString(value) {
return JSON.stringify(value);
}
function goStringSlice(values = []) {
return `[]string{${values.map(goString).join(", ")}}`;
}
function formatGo(content) {
return execFileSync("gofmt", {
input: content,
encoding: "utf8"
});
}