# tools/core/inspectors/declaration.inspector.ts

> 44 lines of code and 10 definitions.

Tree: Coordination tree
Language: typescript
Layer: processing
Canonical: https://banes-lab.com/anatomy/coordination#file-coordination-tools-core-inspectors-declaration-inspector-ts
Source text: https://banes-lab.com/source/coordination/tools/core/inspectors/declaration.inspector.ts.txt

Listed in [tools/core/inspectors](https://banes-lab.com/api/source/coordination/tools/core/inspectors.md), after [tools/core/inspectors/checklist.inspector.ts](https://banes-lab.com/source/coordination/tools/core/inspectors/checklist.inspector.ts.md) and before [tools/core/inspectors/entrypoint.inspector.ts](https://banes-lab.com/source/coordination/tools/core/inspectors/entrypoint.inspector.ts.md).

## Definitions

- `inSurfaceRoot` (lexical_declaration, line 20)
- `placeholderSources` (lexical_declaration, line 24)
- `placeholderFindings` (lexical_declaration, line 41, exported)
- `Scanned` (interface_declaration, line 15)
- `treeRoot` (lexical_declaration, line 25)
- `treeFiles` (lexical_declaration, line 26)
- `manifest` (lexical_declaration, line 27)
- `onDisk` (lexical_declaration, line 28)
- `handed` (lexical_declaration, line 32)
- `seen` (lexical_declaration, line 35)

## Uses

- [tools/core/factories/declaration.factory.ts](https://banes-lab.com/source/coordination/tools/core/factories/declaration.factory.ts.md)

## Source

```typescript
import {
    BEHAVIOUR_TREE_PLACEHOLDER,
    BOOTSTRAP_DOCUMENT,
    PACKAGE_MANIFEST,
    SURFACE_ROOT,
} from "../constants/path.constants.ts";
import { existsSync, readFileSync } from "node:fs";
import { toPosix, walk } from "../iterators/file.iterator.ts";
import type { Finding } from "../types/segment.types.ts";
import type { RuleContext } from "../types/rule.types.ts";
import { leftoverFinding } from "../factories/declaration.factory.ts";
import { resolve } from "node:path";
import { surfacePath } from "../../../config/surface.config.ts";

interface Scanned {
    readonly path: string;
    readonly text: string;
}

const inSurfaceRoot = function inSurfaceRoot(path: string): string {
    return SURFACE_ROOT.length === 0 ? path : `${SURFACE_ROOT}/${path}`;
};

const placeholderSources = function placeholderSources(context: RuleContext): Scanned[] {
    const treeRoot = resolve(context.repoRoot, surfacePath("behaviour_tree"));
    const treeFiles = existsSync(treeRoot) ? walk({ extensions: [".md"], ignored: [], root: treeRoot }) : [];
    const manifest = resolve(context.repoRoot, inSurfaceRoot(PACKAGE_MANIFEST));
    const onDisk = [...treeFiles, ...(existsSync(manifest) ? [manifest] : [])].map((absolute) => ({
        path: toPosix(context.repoRoot, absolute),
        text: readFileSync(absolute, "utf8"),
    }));
    const handed = context.paths
        .filter((path) => path.endsWith(".md"))
        .map((path) => ({ path, text: context.read(path) }));
    const seen = new Set(handed.map((entry) => entry.path));
    return [...handed, ...onDisk.filter((entry) => !seen.has(entry.path))].filter(
        (entry) => entry.path !== BOOTSTRAP_DOCUMENT,
    );
};

export const placeholderFindings = function placeholderFindings(context: RuleContext): Finding[] {
    if (existsSync(resolve(context.repoRoot, inSurfaceRoot(BEHAVIOUR_TREE_PLACEHOLDER)))) {
        return [];
    }
    return placeholderSources(context)
        .filter((entry) => entry.text.includes(BEHAVIOUR_TREE_PLACEHOLDER))
        .map((entry) => leftoverFinding(entry.path));
};
```
