# tools/core/resolvers/sweep.resolver.ts

> 172 lines of code and 37 definitions.

Tree: Coordination tree
Language: typescript
Layer: infrastructure
Canonical: https://banes-lab.com/anatomy/coordination#file-coordination-tools-core-resolvers-sweep-resolver-ts
Source text: https://banes-lab.com/assets/sources/source.10fd9dbbd885ecbf8d357d80efd9b3fa373362797b507fbbe4d27b3629e0870e.generated.txt

## Definitions

- `itemSpans` (lexical_declaration, line 72, exported)
- `openVenues` (lexical_declaration, line 24, exported)
- `surfaceEntries` (lexical_declaration, line 12, exported)
- `withoutSpans` (lexical_declaration, line 149, exported)
- `bodyOf` (lexical_declaration, line 163)
- `duplicateTwinOf` (lexical_declaration, line 177, exported)
- `SEPARATOR` (lexical_declaration, line 8)
- `CANONICAL_SEPARATOR` (lexical_declaration, line 10)
- `prefix` (lexical_declaration, line 13, exported)
- `root` (lexical_declaration, line 14, exported)
- `ItemSpan` (interface_declaration, line 35, exported)
- `OPEN` (lexical_declaration, line 44)
- `CLOSE` (lexical_declaration, line 46)
- `EVERYONE` (lexical_declaration, line 48)
- `fieldOf` (lexical_declaration, line 50)
- `keyOf` (lexical_declaration, line 61)
- `at` (lexical_declaration, line 62)
- `rest` (lexical_declaration, line 67)
- `end` (lexical_declaration, line 68)
- `fenced` (lexical_declaration, line 75, exported)
- `open` (lexical_declaration, line 76, exported)
- `trimmed` (lexical_declaration, line 83, exported)
- `stamp` (lexical_declaration, line 91, exported)
- `to` (lexical_declaration, line 92, exported)
- `key` (lexical_declaration, line 105, exported)
- `seenItems` (lexical_declaration, line 125, exported)
- `latest` (lexical_declaration, line 126, exported)
- `held` (lexical_declaration, line 128, exported)
- `spanText` (lexical_declaration, line 142, exported)
- `dropped` (lexical_declaration, line 150, exported)
- `out` (lexical_declaration, line 164, exported)
- `index` (lexical_declaration, line 165, exported)
- `line` (lexical_declaration, line 166, exported)
- `lines` (lexical_declaration, line 178, exported)
- `spans` (lexical_declaration, line 179, exported)
- `target` (lexical_declaration, line 181, exported)
- `body` (lexical_declaration, line 186, exported)

## Used by

- [tools/core/entrypoints/board.entrypoint.ts](https://banes-lab.com/source/coordination/tools/core/entrypoints/board.entrypoint.ts.md)
- [tools/core/inspectors/board.inspector.ts](https://banes-lab.com/source/coordination/tools/core/inspectors/board.inspector.ts.md)
- [tools/core/reporters/board.reporter.ts](https://banes-lab.com/source/coordination/tools/core/reporters/board.reporter.ts.md)
- [tools/core/resolvers/snapshot.resolver.ts](https://banes-lab.com/source/coordination/tools/core/resolvers/snapshot.resolver.ts.md)
- [tools/core/runners/agenda.runner.ts](https://banes-lab.com/source/coordination/tools/core/runners/agenda.runner.ts.md)
- [tools/core/runners/sweep.runner.ts](https://banes-lab.com/source/coordination/tools/core/runners/sweep.runner.ts.md)
- [tools/core/validators/blocking.validator.ts](https://banes-lab.com/source/coordination/tools/core/validators/blocking.validator.ts.md)
- [tools/core/validators/venue.validator.ts](https://banes-lab.com/source/coordination/tools/core/validators/venue.validator.ts.md)

## Source

```typescript
import { AT_FIELD, TO_FIELD } from "../formatters/board.formatter.ts";
import { existsSync, readdirSync } from "node:fs";

import { fencedFlags } from "../predicates/fence.predicate.ts";
import { resolve } from "node:path";
import { surfacePrefix } from "../../../config/surface.config.ts";

const SEPARATOR = "\\";

const CANONICAL_SEPARATOR = "/";

export const surfaceEntries = function surfaceEntries(repoRoot: string): string[] {
    const prefix = surfacePrefix();
    const root = resolve(repoRoot, prefix);
    if (!existsSync(root)) {
        return [];
    }

    return readdirSync(root, { encoding: "utf8", recursive: true }).map((entry) =>
        prefix.length === 0 ? entry : `${prefix}${CANONICAL_SEPARATOR}${entry}`,
    );
};

export const openVenues = function openVenues(
    entries: readonly string[],
    archiveRoot: string,
    suffix: string,
): string[] {
    return entries
        .map((entry) => entry.split(SEPARATOR).join(CANONICAL_SEPARATOR))
        .filter((entry) => entry.endsWith(suffix))
        .filter((entry) => !entry.startsWith(archiveRoot));
};

export interface ItemSpan {
    readonly key: string;
    readonly agent: string;
    readonly at: number;
    readonly to: readonly string[];
    readonly from: number;
    readonly through: number;
}

const OPEN = "┌─── AGENT ";

const CLOSE = "└─── END AGENT ";

const EVERYONE = "*";

const fieldOf = function fieldOf(line: string, field: string): string {
    const at = line.indexOf(field);
    if (at === -1) {
        return "";
    }

    const rest = line.slice(at + field.length);
    const end = rest.indexOf(" ");
    return end === -1 ? rest.trim() : rest.slice(0, end).trim();
};

const keyOf = function keyOf(line: string, marker: string): string {
    const at = line.indexOf(marker);
    if (at === -1) {
        return "";
    }

    const rest = line.slice(at + marker.length).trim();
    const end = rest.indexOf(" ");
    return end === -1 ? rest : rest.slice(0, end);
};

export const itemSpans = function itemSpans(source: string): ItemSpan[] {
    const lines = source.split("\n");
    const out: ItemSpan[] = [];
    const fenced = fencedFlags(source);
    const open = new Map<string, { at: number; to: string[]; from: number }>();

    for (let index = 0; index < lines.length; index += 1) {
        if (fenced[index] === true) {
            continue;
        }
        const line = lines[index] ?? "";
        const trimmed = line.trim();

        if (trimmed.startsWith(OPEN)) {
            const key = keyOf(trimmed, OPEN);
            if (!key.includes("-")) {
                continue;
            }

            const stamp = Number(fieldOf(trimmed, AT_FIELD));
            const to = fieldOf(trimmed, TO_FIELD);
            open.set(key, {
                at: Number.isFinite(stamp) ? stamp : 0,
                from: index,
                to: to.length === 0 || to === EVERYONE ? [] : to.split(","),
            });
            continue;
        }

        if (!trimmed.startsWith(CLOSE)) {
            continue;
        }

        const key = keyOf(trimmed, CLOSE);
        const held = open.get(key);
        if (held === undefined) {
            continue;
        }

        open.delete(key);
        out.push({
            agent: key.slice(0, key.indexOf("-")),
            at: held.at,
            from: held.from,
            key,
            through: index,
            to: held.to,
        });
    }

    return out;
};

export const seenItems = function seenItems(spans: readonly ItemSpan[]): ItemSpan[] {
    const latest = new Map<string, number>();
    for (const span of spans) {
        const held = latest.get(span.agent) ?? 0;
        if (span.at > held) {
            latest.set(span.agent, span.at);
        }
    }

    return spans.filter((span) => {
        if (span.at === 0 || span.to.length === 0) {
            return false;
        }
        return span.to.every((reader) => (latest.get(reader) ?? 0) > span.at);
    });
};

export const spanText = function spanText(source: string, span: ItemSpan): string {
    return source
        .split("\n")
        .slice(span.from, span.through + 1)
        .join("\n");
};

export const withoutSpans = function withoutSpans(source: string, spans: readonly ItemSpan[]): string {
    const dropped = new Set<number>();
    for (const span of spans) {
        for (let line = span.from; line <= span.through; line += 1) {
            dropped.add(line);
        }
    }

    return source
        .split("\n")
        .filter((_line, index) => !dropped.has(index))
        .join("\n");
};

const bodyOf = function bodyOf(lines: readonly string[], from: number, through: number): string {
    const out: string[] = [];
    for (let index = from; index <= through && index < lines.length; index += 1) {
        const line = (lines[index] ?? "").trim();
        if (line.startsWith(OPEN) || line.startsWith(CLOSE)) {
            continue;
        }
        if (line.length > 0) {
            out.push(line);
        }
    }
    return out.join("\n");
};

export const duplicateTwinOf = function duplicateTwinOf(source: string, key: string): string | null {
    const lines = source.split("\n");
    const spans = itemSpans(source);

    const target = spans.find((span) => span.key === key);
    if (target === undefined) {
        return null;
    }

    const body = bodyOf(lines, target.from, target.through);
    if (body.length === 0) {
        return null;
    }

    for (const span of spans) {
        if (span.key === key) {
            continue;
        }
        if (span.agent !== target.agent) {
            continue;
        }
        if (bodyOf(lines, span.from, span.through) !== body) {
            continue;
        }
        return span.key;
    }

    return null;
};
```
