diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts index 3fe828af8..60e3d4491 100644 --- a/packages/core/src/config.ts +++ b/packages/core/src/config.ts @@ -62,7 +62,7 @@ const ProjectConfigSchema = z.object({ repo: z.string(), path: z.string(), defaultBranch: z.string().default("main"), - sessionPrefix: z.string().optional(), + sessionPrefix: z.string().regex(/^[a-zA-Z0-9_-]+$/, "sessionPrefix must match [a-zA-Z0-9_-]+").optional(), runtime: z.string().optional(), agent: z.string().optional(), workspace: z.string().optional(), @@ -130,8 +130,9 @@ function applyProjectDefaults(config: OrchestratorConfig): OrchestratorConfig { } // Derive session prefix from project ID if not set + // Sanitize to match metadata ID rules: [a-zA-Z0-9_-]+ if (!project.sessionPrefix) { - project.sessionPrefix = id; + project.sessionPrefix = id.replace(/[^a-zA-Z0-9_-]/g, "-"); } // Infer SCM from repo if not set diff --git a/packages/core/src/tmux.ts b/packages/core/src/tmux.ts index 098a9e875..565d1af27 100644 --- a/packages/core/src/tmux.ts +++ b/packages/core/src/tmux.ts @@ -139,7 +139,7 @@ export async function sendKeys( const bufferName = `ao-${randomUUID().slice(0, 8)}`; const tmpFile = join(tmpdir(), `ao-tmux-${bufferName}.txt`); - writeFileSync(tmpFile, text, "utf-8"); + writeFileSync(tmpFile, text, { encoding: "utf-8", mode: 0o600 }); try { await tmux("load-buffer", "-b", bufferName, tmpFile);