# tools/core/entrypoints/segment.entrypoint.ts

> 174 lines of code and 34 definitions.

Tree: Coordination tree
Language: typescript
Layer: runtime
Canonical: https://banes-lab.com/anatomy/coordination#file-coordination-tools-core-entrypoints-segment-entrypoint-ts
Source text: https://banes-lab.com/assets/sources/source.b1c514ba7f26fc075dda50c382abbbc9728876c192b71c92b5d144e37d83287f.generated.txt

## Definitions

- `main` (lexical_declaration, line 84)
- `REPO_ROOT` (lexical_declaration, line 23)
- `RESTATES` (lexical_declaration, line 25, exported)
- `IGNORED` (lexical_declaration, line 31)
- `PATTERNS` (lexical_declaration, line 42)
- `Args` (interface_declaration, line 55)
- `parseArgs` (lexical_declaration, line 62)
- `scan` (lexical_declaration, line 63)
- `renameMap` (lexical_declaration, line 64)
- `apply` (lexical_declaration, line 65)
- `patternId` (lexical_declaration, line 66)
- `i` (lexical_declaration, line 68)
- `arg` (lexical_declaration, line 69)
- `args` (lexical_declaration, line 85)
- `root` (lexical_declaration, line 86)
- `files` (lexical_declaration, line 88)
- `patterns` (lexical_declaration, line 90)
- `mapPath` (lexical_declaration, line 92)
- `map` (lexical_declaration, line 93)
- `hits` (lexical_declaration, line 96)
- `edits` (lexical_declaration, line 97)
- `findings` (lexical_declaration, line 98)
- `byExtension` (lexical_declaration, line 99)
- `relPath` (lexical_declaration, line 102)
- `dot` (lexical_declaration, line 103)
- `ext` (lexical_declaration, line 104)
- `document` (lexical_declaration, line 107)
- `rejected` (lexical_declaration, line 131)
- `byPath` (lexical_declaration, line 134)
- `list` (lexical_declaration, line 136)
- `absolute` (lexical_declaration, line 142)
- `result` (lexical_declaration, line 143)
- `report` (lexical_declaration, line 177)
- `target` (lexical_declaration, line 188)

## Uses

- [tools/core/matchers/segment.matcher.ts](https://banes-lab.com/source/coordination/tools/core/matchers/segment.matcher.ts.md)
- [tools/core/transformers/segment.transformer.ts](https://banes-lab.com/source/coordination/tools/core/transformers/segment.transformer.ts.md)

## Source

```typescript
import type { Edit, Finding, Hit, SegmentPattern } from "../types/segment.types.ts";
import { GENERATED_DIR, NODE_MODULES, NO_FIX_FLAG } from "../constants/path.constants.ts";

import {
    type RenameMap,
    applyEdits,
    editsFromFieldPrefixes,
    editsFromFieldValues,
    editsFromInlinePrefixes,
    editsFromInlines,
} from "../transformers/segment.transformer.ts";
import { type Report, toEditRecords, toHitRecords, verdictOf, writeReport } from "../reporters/segment.reporter.ts";
import { projectRoot, surfacePrefix } from "../../../config/surface.config.ts";
import { readSource, toPosix, walk } from "../iterators/file.iterator.ts";
import { REFERENCE_FIELDS } from "../matchers/reference.matcher.ts";
import { isStringMap } from "../predicates/schema.predicate.ts";
import { matchAll } from "../matchers/segment.matcher.ts";
import { readDocument } from "../readers/document.reader.ts";
import { readJson } from "../readers/json.reader.ts";
import { resolve } from "node:path";
import { writeFileSync } from "node:fs";

const REPO_ROOT = projectRoot();

export const RESTATES: readonly string[] = [
    "mutation_preview_first",
    "healing_is_default_in_every_entrypoint",
    "pattern_references_verified_after_rename",
];

const IGNORED = [
    NODE_MODULES,
    ".git",
    GENERATED_DIR,
    "cache",
    "logs",
    "crashes",
    "settings.json",
    "settings.local.json",
];

const PATTERNS: SegmentPattern[] = [
    { id: "record-cross-reference", predicates: [{ keyEquals: "see", kind: "field" }] },
    { id: "record-source-pointer", predicates: [{ keyEquals: "source", kind: "field", valueStartsWith: "local:" }] },
    { id: "import-directive", predicates: [{ inlineKind: "import-path" }] },
    {
        id: "record-header",
        predicates: [
            { depthEquals: 3, kind: "heading" },
            { keyEquals: "type", kind: "field" },
        ],
    },
];

interface Args {
    readonly scan: string | null;
    readonly renameMap: string | null;
    readonly apply: boolean;
    readonly patternId: string | null;
}

const parseArgs = function parseArgs(argv: readonly string[]): Args {
    let scan: string | null = null;
    let renameMap: string | null = null;
    let apply = true;
    let patternId: string | null = null;

    for (let i = 0; i < argv.length; i += 1) {
        const arg = argv[i];
        if (arg === "--scan") {
            scan = argv[i + 1] ?? null;
        } else if (arg === "--rename") {
            renameMap = argv[i + 1] ?? null;
        } else if (arg === "--pattern") {
            patternId = argv[i + 1] ?? null;
        } else if (arg === NO_FIX_FLAG) {
            apply = false;
        }
    }

    return { apply, patternId, renameMap, scan };
};

const main = function main(): void {
    const args = parseArgs(process.argv.slice(2));
    const root = resolve(REPO_ROOT, args.scan ?? surfacePrefix());

    const files = walk({ extensions: [".md", ".ts"], ignored: IGNORED, root });

    const patterns = args.patternId === null ? PATTERNS : PATTERNS.filter((p) => p.id === args.patternId);

    const mapPath = args.renameMap;
    const map: RenameMap =
        mapPath === null ? {} : readJson(readSource(resolve(REPO_ROOT, mapPath)), isStringMap, mapPath, "RenameMap");

    const hits: Hit[] = [];
    const edits: Edit[] = [];
    const findings: Finding[] = [];
    const byExtension: Record<string, number> = {};

    for (const file of files) {
        const relPath = toPosix(REPO_ROOT, file);
        const dot = relPath.lastIndexOf(".");
        const ext = dot === -1 ? "(none)" : relPath.slice(dot);
        byExtension[ext] = (byExtension[ext] ?? 0) + 1;

        const document = readDocument(relPath, readSource(file));

        for (const hit of matchAll(document, patterns)) {
            hits.push(hit);
        }

        if (args.renameMap !== null) {
            for (const edit of editsFromInlines(document, map, ["link-target", "inline-code", "import-path"])) {
                edits.push(edit);
            }
            for (const key of REFERENCE_FIELDS) {
                for (const edit of editsFromFieldValues(document, key, map)) {
                    edits.push(edit);
                }
            }
            for (const edit of editsFromFieldPrefixes(document, REFERENCE_FIELDS, map)) {
                edits.push(edit);
            }
            for (const edit of editsFromInlinePrefixes(document, map, ["link-target", "inline-code"])) {
                edits.push(edit);
            }
        }
    }

    const rejected: Edit[] = [];

    if (args.renameMap !== null && args.apply) {
        const byPath = new Map<string, Edit[]>();
        for (const edit of edits) {
            const list = byPath.get(edit.path) ?? [];
            list.push(edit);
            byPath.set(edit.path, list);
        }

        for (const [relPath, fileEdits] of byPath) {
            const absolute = resolve(REPO_ROOT, relPath);
            const result = applyEdits(readSource(absolute), fileEdits);
            for (const bad of result.rejected) {
                rejected.push(bad);
            }
            if (result.rejected.length === 0) {
                writeFileSync(absolute, result.text, "utf8");
            }
        }
    }

    for (const bad of rejected) {
        findings.push({
            actual: bad.reason,
            expected: null,
            healed: false,
            line: 0,
            locus: `bytes ${bad.start}..${bad.end}`,
            path: bad.path,
            remediation: {
                action: "split",
                decide: "two rename-map entries resolve to overlapping spans in this file — narrow one key so the spans are disjoint, then re-run",
                deterministic: false,
                from: bad.reason,
                target: bad.path,
                to: null,
            },
            rule: "segment/editOverlap",
            stack: [
                { check: "applyEdits", resolved: "right-to-left" },
                { check: "boundary", resolved: `edit end ${bad.end} crossed a prior edit start` },
            ],
        });
    }

    const report: Report = {
        coverage: { filesByExtension: byExtension, roots: [toPosix(REPO_ROOT, root) || "."] },
        edits: toEditRecords(edits),
        findings,
        hits: toHitRecords(hits),
        rejected: toEditRecords(rejected),
        scanned: files.length,
        tool: "segment",
        verdict: verdictOf(findings, rejected),
    };

    const target = writeReport(REPO_ROOT, "segment", report);

    process.stdout.write(
        `${report.verdict.toUpperCase()}  scanned=${report.scanned} hits=${report.hits.length} ` +
            `edits=${report.edits.length} rejected=${report.rejected.length}\n` +
            `report: ${toPosix(REPO_ROOT, target)}\n${
                args.renameMap !== null && !args.apply ? `rehearsal only — rerun without ${NO_FIX_FLAG} to write\n` : ""
            }`,
    );

    process.exit(report.verdict === "pass" ? 0 : 1);
};

main();
```
