refactor(modules): extract approvals + interactive as registry-based modules
Phase 2 / PR #3 of the module refactor. Moves the approval and interactive- question flows out of core and into src/modules/, wired through the response dispatcher and delivery action registries. New modules: - src/modules/interactive/ — registers a response handler that claims pending_questions rows, writes question_response to the session DB, wakes the container. createPendingQuestion call stays inline in delivery.ts (guarded by hasTable) per plan. - src/modules/approvals/ — registers 3 delivery actions (install_packages, request_rebuild, add_mcp_server), a response handler for pending_approvals (including OneCLI action fall-through), an adapter-ready hook that boots the OneCLI manual-approval handler, and a shutdown hook that stops it. OneCLI implementation (src/onecli-approvals.ts) moves into the module. Core lifecycle hooks added (narrow, not registries): - onDeliveryAdapterReady(cb) in delivery.ts — fires when setDeliveryAdapter runs (or immediately if already set). Used by approvals for OneCLI boot. - onShutdown(cb) in index.ts — fires on SIGTERM/SIGINT. Used by approvals for OneCLI teardown. - getDeliveryAdapter() getter in delivery.ts — for live-flow adapter access in registered delivery actions. Core shrinks: delivery.ts 911 → 665 lines, index.ts 405 → 224 lines. dispatchResponse now logs "Unclaimed response" instead of falling through to an inline handler — the inline fallback moved into the two modules. Migration files renamed to the module-<name>-<short>.ts convention: - 003-pending-approvals.ts → module-approvals-pending-approvals.ts - 007-pending-approvals-title-options.ts → module-approvals-title-options.ts Migration.name fields unchanged so existing DBs treat them as already-applied. Degradation verified: emptying the modules barrel builds clean and 137/137 tests pass. Actions would log "Unknown system action"; button clicks would log "Unclaimed response". Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,11 +3,11 @@ import type Database from 'better-sqlite3';
|
||||
import { log } from '../../log.js';
|
||||
import { migration001 } from './001-initial.js';
|
||||
import { migration002 } from './002-chat-sdk-state.js';
|
||||
import { migration003 } from './003-pending-approvals.js';
|
||||
import { migration004 } from './004-agent-destinations.js';
|
||||
import { migration007 } from './007-pending-approvals-title-options.js';
|
||||
import { migration008 } from './008-dropped-messages.js';
|
||||
import { migration009 } from './009-drop-pending-credentials.js';
|
||||
import { moduleApprovalsPendingApprovals } from './module-approvals-pending-approvals.js';
|
||||
import { moduleApprovalsTitleOptions } from './module-approvals-title-options.js';
|
||||
|
||||
export interface Migration {
|
||||
version: number;
|
||||
@@ -18,9 +18,9 @@ export interface Migration {
|
||||
const migrations: Migration[] = [
|
||||
migration001,
|
||||
migration002,
|
||||
migration003,
|
||||
moduleApprovalsPendingApprovals,
|
||||
migration004,
|
||||
migration007,
|
||||
moduleApprovalsTitleOptions,
|
||||
migration008,
|
||||
migration009,
|
||||
];
|
||||
|
||||
@@ -12,7 +12,10 @@ import type { Migration } from './index.js';
|
||||
* `platform_message_id`, `expires_at`, `status`) let the host edit the admin
|
||||
* card when a request expires and sweep stale rows on startup.
|
||||
*/
|
||||
export const migration003: Migration = {
|
||||
// Retains the original `name` ('pending-approvals') so existing DBs that
|
||||
// already recorded this migration under that name don't re-run it. The
|
||||
// module- prefix lives on the filename / export identifier only.
|
||||
export const moduleApprovalsPendingApprovals: Migration = {
|
||||
version: 3,
|
||||
name: 'pending-approvals',
|
||||
up(db) {
|
||||
@@ -12,7 +12,10 @@ import type { Migration } from './index.js';
|
||||
* the ALTER statements will fail harmlessly (column already exists) and
|
||||
* we swallow the error per-column.
|
||||
*/
|
||||
export const migration007: Migration = {
|
||||
// Retains the original `name` ('pending-approvals-title-options') so
|
||||
// existing DBs that already recorded this migration don't re-run it. The
|
||||
// module- prefix lives on the filename / export identifier only.
|
||||
export const moduleApprovalsTitleOptions: Migration = {
|
||||
version: 7,
|
||||
name: 'pending-approvals-title-options',
|
||||
up(db) {
|
||||
Reference in New Issue
Block a user