fix(setup): dynamic FK cleanup, remove normalizeName coupling

- delete-cli-agent.ts discovers tables with agent_group_id dynamically
  instead of hardcoding a list
- cli-agent step emits FOLDER in its status block so setup/auto.ts
  reads it from the step result instead of re-deriving via normalizeName

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
gabi-simons
2026-04-29 14:27:03 +00:00
committed by exe.dev user
parent d86051805b
commit 8c5d67cc78
3 changed files with 17 additions and 21 deletions

View File

@@ -44,23 +44,18 @@ if (!ag) {
process.exit(0);
}
// Delete all rows referencing this agent group, in dependency order.
const fkTables = [
'messaging_group_agents',
'agent_destinations',
'agent_group_members',
'pending_sender_approvals',
'channel_registrations',
'user_roles',
'sessions',
];
for (const table of fkTables) {
const exists = db
.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name=?")
.get(table);
if (exists) {
db.prepare(`DELETE FROM ${table} WHERE agent_group_id = ?`).run(ag.id);
}
// Dynamically find every table with an agent_group_id column and delete
// matching rows. This is self-maintaining — new FK tables are picked up
// automatically without updating a hardcoded list.
const tables = db
.prepare(
`SELECT DISTINCT m.name FROM sqlite_master m
JOIN pragma_table_info(m.name) p ON p.name = 'agent_group_id'
WHERE m.type = 'table' AND m.name != 'agent_groups'`,
)
.all() as { name: string }[];
for (const { name } of tables) {
db.prepare(`DELETE FROM ${name} WHERE agent_group_id = ?`).run(ag.id);
}
deleteAgentGroup(ag.id);

View File

@@ -55,8 +55,6 @@ import { ensureAnswer, fail, runQuietChild, runQuietStep } from './lib/runner.js
import { emit as phEmit } from './lib/diagnostics.js';
import { accentGreen, brandBody, brandBold, brandChip, dimWrap, fitToWidth, note, wrapForGutter } from './lib/theme.js';
import { isValidTimezone } from '../src/timezone.js';
import { normalizeName } from '../src/modules/agent-to-agent/db/agent-destinations.js';
const CLI_AGENT_NAME = 'Terminal Agent';
const RUN_START = Date.now();
@@ -374,7 +372,7 @@ async function main(): Promise<void> {
const ping = await confirmAssistantResponds();
if (ping === 'ok') {
phEmit('first_chat_ready');
const scratchFolder = `cli-with-${normalizeName(displayName!)}`;
const scratchFolder = res.terminal?.fields.FOLDER ?? '';
spawnSync('pnpm', ['exec', 'tsx', 'scripts/delete-cli-agent.ts', '--folder', scratchFolder], {
stdio: 'ignore',
});

View File

@@ -60,8 +60,9 @@ export async function run(args: string[]): Promise<void> {
log.info('Invoking init-cli-agent', { displayName, agentName });
let stdout = '';
try {
execFileSync('pnpm', scriptArgs, {
stdout = execFileSync('pnpm', scriptArgs, {
cwd: projectRoot,
stdio: ['ignore', 'pipe', 'pipe'],
encoding: 'utf-8',
@@ -82,9 +83,11 @@ export async function run(args: string[]): Promise<void> {
process.exit(1);
}
const folderMatch = stdout.match(/@ groups\/(\S+)/);
emitStatus('CLI_AGENT', {
DISPLAY_NAME: displayName,
AGENT_NAME: agentName || displayName,
FOLDER: folderMatch?.[1] ?? '',
CHANNEL: 'cli/local',
STATUS: 'success',
LOG: 'logs/setup.log',