"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createWorkStatusCommand = createWorkStatusCommand;
exports.createWorkReviewCommand = createWorkReviewCommand;
exports.createWorkProjectReviewCommand = createWorkProjectReviewCommand;
exports.createWorkFollowUpCommand = createWorkFollowUpCommand;
exports.createWorkCloseCommand = createWorkCloseCommand;
const errors_1 = require("../../../lib/errors");
const output_1 = require("../../../lib/output");
const work_review_1 = require("../../../lib/work-review");
const work_creation_1 = require("../../../lib/work-creation");
const runtime_contract_1 = require("../../../lib/runtime/runtime-contract");
const registration_1 = require("../registration");
async function createWorkStatusCommand() {
    const { Command } = await import('commander');
    const command = new Command('status');
    command
        .description('Aggregate one Structured or Governed work root without writing canonical or derived state.')
        .requiredOption('--overview <path>', 'Canonical Structured work overview or Governed slice overview path.')
        .action((_, commandInstance) => {
        const format = resolveCommandFormat(commandInstance);
        const repository = (0, runtime_contract_1.createRepositoryContext)((0, runtime_contract_1.detectRepositoryRoot)(), false);
        const result = (0, work_review_1.aggregateStructuredProjectSync)({
            repositoryRoot: repository.root,
            overviewPath: commandInstance.opts().overview,
        });
        (0, output_1.emitSuccess)({
            command: 'work status',
            format,
            text: renderAggregation(result),
            data: result,
        });
    });
    return command;
}
async function createWorkReviewCommand() {
    const { Command } = await import('commander');
    const command = new Command('review');
    command
        .description('Review Structured or Governed specification coverage and closeout evidence without writes.')
        .requiredOption('--overview <path>', 'Canonical Structured work overview or Governed slice overview path.')
        .action((_, commandInstance) => {
        const format = resolveCommandFormat(commandInstance);
        const repository = (0, runtime_contract_1.createRepositoryContext)((0, runtime_contract_1.detectRepositoryRoot)(), false);
        const result = (0, work_review_1.reviewStructuredProjectSync)({
            repositoryRoot: repository.root,
            overviewPath: commandInstance.opts().overview,
        });
        (0, output_1.emitSuccess)({
            command: 'work review',
            format,
            text: [
                `Reviewed ${titleLevel(result.aggregation.workflowLevel)} project without writes.`,
                ...renderOwner(result.aggregation),
                `Closeout eligible: ${result.closeoutEligible}`,
                `Recommended disposition: ${result.recommendedDisposition}`,
                `Findings: ${result.findings.length}`,
                ...result.findings.map((entry) => `- ${entry.severity}: ${entry.code}: ${entry.message}`),
                `No-write boundary: ${result.noWriteBoundary}`,
                `Next action: ${result.nextAction}`,
            ].join('\n'),
            data: result,
        });
    });
    return command;
}
async function createWorkProjectReviewCommand() {
    const { Command } = await import('commander');
    const command = new Command('project-review');
    command.description('Persist canonical Structured or Governed project review through an explicit preview/apply action.');
    (0, registration_1.registerCommand)(command, await createProjectReviewCreateCommand());
    return command;
}
async function createProjectReviewCreateCommand() {
    const { Command } = await import('commander');
    const command = new Command('create');
    command
        .description('Preview or create one revision-bound canonical Structured or Governed project review.')
        .requiredOption('--overview <path>', 'Canonical Structured work overview or Governed slice overview path.')
        .requiredOption('--disposition <value>', 'accepted, accepted_with_follow_up, changes_requested, or blocked.')
        .requiredOption('--reviewer <value>', 'Reviewer identity recorded in the canonical review.')
        .requiredOption('--summary <value>', 'Reviewer-authored project review summary.')
        .option('--follow-up <json>', 'Complete follow-up task JSON contract; repeat in dependency order.', collect, [])
        .option('--dry-run', 'Preview reviewed evidence, preconditions, and the project-review write without mutation.')
        .action((_, commandInstance) => {
        const format = resolveCommandFormat(commandInstance);
        const repository = (0, runtime_contract_1.createRepositoryContext)((0, runtime_contract_1.detectRepositoryRoot)(), false);
        const options = commandInstance.opts();
        let result;
        try {
            const preview = (0, work_review_1.previewStructuredProjectReviewPersistenceSync)({
                repositoryRoot: repository.root,
                overviewPath: options.overview,
                disposition: options.disposition,
                reviewer: options.reviewer,
                summary: options.summary,
                followUpTasks: options.followUp.map(parseTaskInput),
            });
            result = options.dryRun === true ? preview : (0, work_review_1.applyStructuredProjectReviewPersistenceSync)(preview);
        }
        catch (error) {
            throw normalizeReviewError(error, 'WORK_PROJECT_REVIEW_CREATE');
        }
        ensureMutationSucceeded(result, `${titleLevel(result.workflowLevel)} project-review persistence`);
        (0, output_1.emitSuccess)({
            command: 'work project-review create',
            format,
            text: renderMutation(result),
            data: result,
        });
    });
    return command;
}
async function createWorkFollowUpCommand() {
    const { Command } = await import('commander');
    const command = new Command('follow-up');
    command.description('Create only follow-up task contracts declared by canonical Structured project review.');
    (0, registration_1.registerCommand)(command, await createFollowUpCreateCommand());
    return command;
}
async function createFollowUpCreateCommand() {
    const { Command } = await import('commander');
    const command = new Command('create');
    command
        .description('Preview or create review-declared Structured follow-up task pairs.')
        .requiredOption('--project-review <path>', 'Canonical Structured project-review path.')
        .option('--task-id <id>', 'Review-declared follow-up task id; repeat in dependency order.', collect, [])
        .option('--dry-run', 'Preview task-pair paths and review-bound preconditions without mutation.')
        .action((_, commandInstance) => {
        const format = resolveCommandFormat(commandInstance);
        const repository = (0, runtime_contract_1.createRepositoryContext)((0, runtime_contract_1.detectRepositoryRoot)(), false);
        const options = commandInstance.opts();
        let result;
        try {
            const preview = (0, work_review_1.previewStructuredFollowUpCreationSync)({
                repositoryRoot: repository.root,
                projectReviewPath: options.projectReview,
                taskIds: options.taskId,
            });
            result = options.dryRun === true ? preview : (0, work_review_1.applyStructuredFollowUpCreationSync)(preview);
        }
        catch (error) {
            throw normalizeReviewError(error, 'WORK_FOLLOW_UP_CREATE');
        }
        ensureTaskMutationSucceeded(result);
        (0, output_1.emitSuccess)({
            command: 'work follow-up create',
            format,
            text: [
                result.writeOutcome === 'previewed'
                    ? 'Previewed review-declared Structured follow-up task creation.'
                    : 'Created review-declared Structured follow-up task pairs.',
                `Work id: ${result.workId}`,
                `Tasks: ${result.tasks.map((entry) => `${entry.sequencePrefix}:${entry.taskId}:${entry.orderedTaskRootName}`).join(', ')}`,
                `Task inventory fingerprint: ${result.taskInventoryFingerprint}`,
                `Intended paths: ${result.intendedPaths.join(', ')}`,
                `Changed paths: ${result.changedPaths.join(', ') || 'none'}`,
                `Write outcome: ${result.writeOutcome}`,
                `Transaction id: ${result.transactionId ?? 'none'}`,
                `Recovery path: ${result.recoveryPath ?? 'none'}`,
                `Next action: ${result.nextAction}`,
            ].join('\n'),
            data: result,
        });
    });
    return command;
}
async function createWorkCloseCommand() {
    const { Command } = await import('commander');
    const command = new Command('close');
    command
        .description('Preview or explicitly close one reviewed Structured or Governed overview without propagating child mutations.')
        .requiredOption('--overview <path>', 'Canonical Structured work overview or Governed slice overview path.')
        .requiredOption('--project-review <path>', 'Matching canonical Structured or Governed project-review path.')
        .option('--dry-run', 'Preview closeout preconditions and the overview-only write without mutation.')
        .action((_, commandInstance) => {
        const format = resolveCommandFormat(commandInstance);
        const repository = (0, runtime_contract_1.createRepositoryContext)((0, runtime_contract_1.detectRepositoryRoot)(), false);
        const options = commandInstance.opts();
        let result;
        try {
            const preview = (0, work_review_1.previewStructuredProjectClosureSync)({
                repositoryRoot: repository.root,
                overviewPath: options.overview,
                projectReviewPath: options.projectReview,
            });
            result = options.dryRun === true ? preview : (0, work_review_1.applyStructuredProjectClosureSync)(preview);
        }
        catch (error) {
            throw normalizeReviewError(error, 'WORK_CLOSE');
        }
        ensureMutationSucceeded(result, `${titleLevel(result.workflowLevel)} project closure`);
        (0, output_1.emitSuccess)({ command: 'work close', format, text: renderMutation(result), data: result });
    });
    return command;
}
function resolveCommandFormat(commandInstance) {
    let root = commandInstance;
    while (root.parent !== null && root.parent !== undefined)
        root = root.parent;
    const format = (0, output_1.resolveOutputFormat)(root.opts?.().format);
    if (format === null)
        throw (0, errors_1.createUsageError)('Output format must be one of: text, json.');
    return format;
}
function collect(value, previous) {
    return [...previous, value];
}
function parseTaskInput(value) {
    let parsed;
    try {
        parsed = JSON.parse(value);
    }
    catch {
        throw new work_review_1.StructuredProjectReviewError('invalid-request', 'Each --follow-up value must be valid JSON.');
    }
    if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
        throw new work_review_1.StructuredProjectReviewError('invalid-request', 'Each --follow-up value must be a JSON object.');
    }
    return parsed;
}
function normalizeReviewError(error, prefix) {
    if (error instanceof errors_1.RuntimeError)
        return error;
    if (error instanceof work_review_1.StructuredProjectReviewError || error instanceof work_creation_1.StructuredWorkCreationError) {
        const conflict = error.code === 'destination-conflict' || error.code === 'stale-preview';
        const notCloseable = error instanceof work_review_1.StructuredProjectReviewError && error.code === 'not-closeable';
        return new errors_1.RuntimeError({
            message: error.message,
            code: `${prefix}_${error.code.toUpperCase().replace(/-/g, '_')}`,
            exitCode: conflict
                ? errors_1.RuntimeExitCode.CONCURRENCY_CONFLICT
                : notCloseable
                    ? errors_1.RuntimeExitCode.STALE_EVIDENCE
                    : errors_1.RuntimeExitCode.USAGE,
            details: [
                conflict || notCloseable
                    ? 'Refresh read-only work review evidence and preview again.'
                    : 'Correct the selected work artifact, review disposition, or follow-up contract before retrying.',
            ],
        });
    }
    if (error instanceof Error)
        return (0, errors_1.createUsageError)(error.message, ['No project review or closeout write was accepted.']);
    return (0, errors_1.createUsageError)('Invalid project review or closeout input.');
}
function ensureMutationSucceeded(result, label) {
    if (result.writeOutcome === 'previewed' || result.writeOutcome === 'committed')
        return;
    throw mutationOutcomeError(result, label);
}
function ensureTaskMutationSucceeded(result) {
    if (result.writeOutcome === 'previewed' || result.writeOutcome === 'committed')
        return;
    if (result.writeOutcome === 'incomplete') {
        throw new errors_1.RuntimeError({
            message: 'Structured follow-up creation stopped after a partial repository mutation.',
            code: 'WORK_FOLLOW_UP_CREATE_INCOMPLETE',
            exitCode: errors_1.RuntimeExitCode.PARTIAL_MUTATION,
            writeOutcome: 'partial',
            details: [`recoveryPath: ${result.recoveryPath ?? 'unavailable'}`],
            recoveryActions: [
                (0, errors_1.createNonCallableRecoveryAction)({
                    id: 'recovery.inspect-structured-follow-up-transaction',
                    explanation: 'Inspect retained transaction evidence before retrying follow-up creation.',
                    reason: result.recoveryPath ?? 'The retained transaction path was unavailable.',
                }),
            ],
        });
    }
    throw new errors_1.RuntimeError({
        message: 'Structured follow-up creation preview is stale or produced no canonical write.',
        code: 'WORK_FOLLOW_UP_CREATE_NO_WRITE',
        exitCode: result.writeOutcome === 'conflict' ? errors_1.RuntimeExitCode.CONCURRENCY_CONFLICT : errors_1.RuntimeExitCode.ERROR,
        details: [`writeOutcome: ${result.writeOutcome}`, `nextAction: ${result.nextAction}`],
    });
}
function mutationOutcomeError(result, label) {
    if (result.writeOutcome === 'incomplete') {
        return new errors_1.RuntimeError({
            message: `${label} stopped after a partial repository mutation.`,
            code: `${result.operation.toUpperCase().replace(/-/g, '_')}_INCOMPLETE`,
            exitCode: errors_1.RuntimeExitCode.PARTIAL_MUTATION,
            writeOutcome: 'partial',
            details: [`recoveryPath: ${result.recoveryPath ?? 'unavailable'}`],
            recoveryActions: [
                (0, errors_1.createNonCallableRecoveryAction)({
                    id: `recovery.inspect-${result.operation}-transaction`,
                    explanation: `Inspect retained transaction evidence before retrying ${label}.`,
                    reason: result.recoveryPath ?? 'The retained transaction path was unavailable.',
                }),
            ],
        });
    }
    return new errors_1.RuntimeError({
        message: `${label} preview is stale or produced no canonical write.`,
        code: `${result.operation.toUpperCase().replace(/-/g, '_')}_NO_WRITE`,
        exitCode: result.writeOutcome === 'conflict' ? errors_1.RuntimeExitCode.CONCURRENCY_CONFLICT : errors_1.RuntimeExitCode.ERROR,
        details: [`writeOutcome: ${result.writeOutcome}`, `nextAction: ${result.nextAction}`],
    });
}
function renderAggregation(result) {
    return [
        `Aggregated ${titleLevel(result.workflowLevel)} project without writes.`,
        `Workflow level: ${result.workflowLevel}`,
        ...renderOwner(result),
        `Specifications: ${result.counts.specifications}`,
        `Hierarchy artifacts: ${result.counts.hierarchyArtifacts}`,
        `Tasks: ${result.counts.tasks}`,
        `Completed tasks: ${result.counts.completedTasks}`,
        `Blocked tasks: ${result.counts.blockedTasks}`,
        `Reconciliations: ${result.counts.reconciliations}`,
        `Completed reconciliations: ${result.counts.completedReconciliations}`,
        `Closeout eligible: ${result.closeoutEligible}`,
        `No-write boundary: ${result.noWriteBoundary}`,
        `Next action: ${result.nextAction}`,
    ].join('\n');
}
function renderMutation(result) {
    const levelTitle = titleLevel(result.workflowLevel);
    return [
        result.writeOutcome === 'previewed'
            ? `Previewed ${levelTitle} ${result.operation}.`
            : `Applied ${levelTitle} ${result.operation}.`,
        `Workflow level: ${result.workflowLevel}`,
        ...renderOwner(result),
        `Project review: ${result.projectReviewPath}`,
        `Disposition: ${result.disposition}`,
        `Intended paths: ${result.intendedPaths.join(', ')}`,
        `Changed paths: ${result.changedPaths.join(', ') || 'none'}`,
        `Write outcome: ${result.writeOutcome}`,
        `Transaction id: ${result.transactionId ?? 'none'}`,
        `Recovery path: ${result.recoveryPath ?? 'none'}`,
        `Next action: ${result.nextAction}`,
    ].join('\n');
}
function renderOwner(result) {
    return result.workflowLevel === 'governed'
        ? [`Slice id: ${result.sliceId ?? '(missing)'}`, `Slice overview: ${result.sliceOverviewPath ?? '(missing)'}`]
        : [`Work id: ${result.workId ?? '(missing)'}`, `Overview: ${result.overviewPath ?? '(missing)'}`];
}
function titleLevel(value) {
    return value === 'structured' ? 'Structured' : 'Governed';
}
