UNPKG

aiwg

Version:

Deployment tool and support utility for AI context. Copies agents, skills, commands, rules, and behaviors into the paths each AI platform reads (Claude Code, Codex, Copilot, Cursor, Warp, OpenClaw, and 6 more) so one source of truth works across 10 platfo

395 lines 13.2 kB
/** * Artifact Index Types * * Shared TypeScript types for the artifact indexing system. * Used by index-builder, query-engine, dep-graph, and stats modules. * * @implements #420 * @source @src/artifacts/cli.ts * @tests @test/unit/artifacts/index-builder.test.ts */ /** * A single indexed artifact entry */ export interface MetadataEntry { /** Relative path from project root */ path: string; /** Artifact type (use-case, adr, test-plan, nfr, threat-model, etc.) */ type: string; /** SDLC phase (requirements, architecture, testing, security, deployment, etc.) */ phase: string; /** Title from frontmatter or first heading */ title: string; /** * Canonical short name (#1233). For skills this is the SKILL.md * directory basename (e.g. `aiwg-doctor`); for agents/commands/rules * the filename without extension; falls back to frontmatter `name` * when present. Used by the scorer to floor exact-name queries to 1.0 * so that hyphenated kernel-skill names remain searchable even when * the rendered title strips the hyphen. */ name?: string; /** Tags from frontmatter */ tags: string[]; /** ISO timestamp — file creation or frontmatter date */ created: string; /** ISO timestamp — file modification */ updated: string; /** Truncated SHA-256 hex (16 chars) for change detection */ checksum: string; /** Brief content summary (max 500 chars) */ summary: string; /** Outbound @-mention references (paths this artifact depends on) */ dependencies: string[]; /** Computed: paths that reference this artifact */ dependents: string[]; /** * Trigger phrases extracted from the `## Triggers` section of skill / agent * descriptors. One entry per phrase, lowercased. Used by capability search * (#1214) to boost matches that hit a skill's declared activation phrase. */ triggers?: string[]; /** * Capability summary — what this artifact does, in one sentence. * Drawn from frontmatter `description` for skills/agents/commands/rules. * Used by capability search (#1214) for substring scoring above the * generic body summary. */ capability?: string; /** * `kernel: true` from frontmatter. Marks always-loaded skills the * deploy pipeline routes to the platform-native skills directory * (#1212). Surfaced in the index for `aiwg index discover` so the * agent can prefer non-kernel skills when the kernel set already * covers a request. */ kernel?: boolean; /** * Script entrypoint declaration for executable skills (#1227). * * When present, the skill has a backing script the CLI can invoke via * `aiwg run skill <name>`. Surfaced in `aiwg discover --json` as * `executable: true` + a `run_hint` so agents know to use the run * command instead of trying to execute the SKILL.md instructions * themselves. */ script?: SkillScriptSpec; } /** * Skill script entrypoint declaration (#1227). * * Parsed from the optional `script:` block in a SKILL.md frontmatter. The * `entrypoint` is resolved relative to the skill's source directory; the * runtime executes from the calling project's root by default so relative * paths the script reads/writes resolve into the user's project, not the * AIWG install. */ export interface SkillScriptSpec { /** Path to the script file, relative to the skill's source directory */ entrypoint: string; /** Runtime to dispatch with: node | python | python3 | bash | sh | pwsh | ruby | auto */ runtime: string; /** * Working directory policy. Default is `project-root`: the script runs * from the project the CLI was invoked from, so relative paths resolve * into the caller's tree. `skill-dir` is rare (only for skills that * bundle assets they read via relative paths); `aiwg-root` is an escape * hatch and almost never correct. */ cwd?: 'project-root' | 'skill-dir' | 'aiwg-root'; /** Optional human-readable hint shown by `aiwg discover` and `aiwg show` */ argsHint?: string; } /** * The master artifact index stored at .aiwg/.index/metadata.json */ export interface ArtifactIndex { /** Index format version */ version: string; /** ISO timestamp of last build */ builtAt: string; /** Build duration in milliseconds */ buildTimeMs: number; /** All indexed entries keyed by path */ entries: Record<string, MetadataEntry>; } /** * Tag reverse index stored at .aiwg/.index/tags.json */ export interface TagIndex { /** Tag name -> array of artifact paths */ [tag: string]: string[]; } /** * A typed edge in the dependency graph * * @implements #724 */ export interface TypedEdge { /** Target artifact path */ path: string; /** Relationship type (e.g., "depends-on", "cites", "cited-by", "summarizes") */ type: string; } /** * Normalize a raw edge value to TypedEdge. * Handles backward compatibility: plain strings become { path, type: "depends-on" }. */ export declare function normalizeEdge(edge: string | TypedEdge): TypedEdge; /** * Normalize an array of raw edges to TypedEdge[]. */ export declare function normalizeEdges(edges: (string | TypedEdge)[]): TypedEdge[]; /** * Dependency graph stored at .aiwg/.index/dependencies.json * * @implements #724 */ export interface DependencyGraph { /** Path -> upstream and downstream relationships */ [path: string]: { /** Artifacts this one depends on (typed edges) */ upstream: TypedEdge[]; /** Artifacts that depend on this one (typed edges) */ downstream: TypedEdge[]; }; } /** * Index statistics stored at .aiwg/.index/stats.json */ export interface IndexStats { /** Index format version */ version: string; /** ISO timestamp of last build */ builtAt: string; /** Build duration in milliseconds */ buildTimeMs: number; /** Total artifact count */ totalArtifacts: number; /** Counts by SDLC phase */ byPhase: Record<string, number>; /** Counts by artifact type */ byType: Record<string, number>; /** Tag name -> count */ tagDistribution: Record<string, number>; /** Dependency graph metrics */ graphMetrics: { totalEdges: number; orphanedArtifacts: number; mostReferenced: { path: string; count: number; } | null; }; } /** * Result from a query operation */ export interface QueryResult { /** The matching entry */ entry: MetadataEntry; /** Relevance score (0-1) */ score: number; } /** * Query parameters for artifact search */ export interface QueryParams { /** Keyword search term */ text?: string; /** Filter by path glob pattern */ path?: string; /** Filter by artifact type */ type?: string; /** Filter by SDLC phase */ phase?: string; /** Filter by tags (AND logic) */ tags?: string[]; /** Filter by modification date */ updatedAfter?: string; /** Maximum results */ limit?: number; } /** * Phase name to directory mapping */ export declare const PHASE_DIRECTORIES: Record<string, string>; /** * Default index output directory */ export declare const INDEX_DIR = ".aiwg/.index"; /** * Current index format version */ export declare const INDEX_VERSION = "1.0.0"; /** * Built-in graph type identifiers * * @implements #421 #426 */ export type BuiltinGraphType = 'framework' | 'project' | 'codebase'; /** * Any graph identifier — built-in or user-defined via .aiwg/config.yaml * * @implements #426 */ export type GraphType = string; /** * Edge extraction configuration for a graph * * @implements #722 */ export interface EdgeExtractionConfig { /** Parser to use for edge extraction */ parser: 'citation-sidecar'; /** Edge definitions to extract */ edges: Array<{ /** Edge type label (e.g., "cites", "cited-by") */ type: string; /** Source field path (e.g., "frontmatter.ref") */ source: string; /** Target field path (e.g., "outgoing-table.inducted-ref") */ target: string; /** Skip rows where the target column is empty or dash */ skipEmpty?: boolean; }>; } /** * Metadata supplement configuration — merge fields from sidecar files * * @implements #723 */ export interface MetadataSupplementConfig { /** Directory to scan for sidecar files */ scanDir: string; /** Frontmatter field to match against (e.g., "frontmatter.ref") */ matchOn: string; /** Captured group name from filenamePattern to match against */ nodeKey: string; /** Fields to merge from the sidecar frontmatter into the node */ mergeFields: string[]; } /** * Graph configuration — defines what each graph indexes */ export interface GraphConfig { /** Graph type identifier */ type: string; /** Directories to scan (relative to project/framework root) */ scanDirs: string[]; /** File extensions to index */ extensions: string[]; /** Whether this graph is shared across projects */ shared: boolean; /** Whether to include in default `aiwg index build` (no --graph flag) */ defaultBuild: boolean; /** Optional edge extraction configuration */ edgeExtraction?: EdgeExtractionConfig; /** * Node creation strategy. * - 'default': read file content, parse frontmatter (standard behavior) * - 'filename-metadata': derive metadata from filename regex, skip content reading * * @implements #723 */ nodeStrategy?: 'default' | 'filename-metadata'; /** * Named-capture regex for extracting metadata from filenames. * Only used when nodeStrategy is 'filename-metadata'. * Example: "REF-(?P<ref>\\d{3})-(?P<author>[^-]+)-(?P<year>\\d{4})-(?P<slug>.+)\\.pdf" * * @implements #723 */ filenamePattern?: string; /** * Optional sidecar files that can enrich node metadata. * Merges frontmatter fields from matching sidecar files into the node. * * @implements #723 */ metadataSupplements?: MetadataSupplementConfig[]; /** * Graph storage backend for this graph. * - 'json' (default): zero-dep adjacency list * - 'graphology': rich traversal, community detection (requires npm install graphology) * - 'sqlite': persistent on-disk, SQL set operations (requires npm install better-sqlite3) * * @implements #727 */ graphBackend?: 'json' | 'graphology' | 'sqlite'; /** * Optional embedding index configuration for semantic similarity queries. * Requires: npm install @xenova/transformers hnswlib-node * * @implements #730 */ embedding?: { /** Enable embedding index for this graph */ enabled: boolean; /** Model to use (default: Xenova/all-MiniLM-L6-v2) */ model?: string; /** Number of results for semantic queries (default: 10) */ topK?: number; /** When to rebuild: 'content-change' | 'always' | 'never' */ rebuildOn?: 'content-change' | 'always' | 'never'; }; } /** * Built-in graph definitions */ export declare const BUILTIN_GRAPH_CONFIGS: Record<BuiltinGraphType, GraphConfig>; /** * Mutable graph configs — starts with built-ins, extended by user config * * @implements #426 */ export declare const GRAPH_CONFIGS: Record<string, GraphConfig>; /** * Load graph configs declared in framework/addon manifest.json files. * * Reads `.aiwg/frameworks/registry.json` to find installed modules, * then loads each module's manifest and merges `index.graphs` declarations * into GRAPH_CONFIGS. Module-declared graphs cannot override built-in names. * * This runs before operator config so that .aiwg/config.yaml can override * module-declared graphs. * * @param cwd - Project root directory * @returns Names of module-declared graphs that were loaded * * @implements #726 */ export declare function loadModuleGraphConfigs(cwd: string): string[]; /** * Load user-defined graph configs from .aiwg/config.yaml * * Also loads module-declared graphs from installed framework manifests. * Module graphs are loaded first; operator config overrides them. * Neither can override built-in graph names. * * @param cwd - Project root directory * @returns Names of user-defined graphs that were loaded (includes module graphs) * * @implements #426 #726 */ export declare function loadUserGraphConfigs(cwd: string): string[]; /** * Get the index output directory for a given graph type * * @param cwd - Project root * @param graphType - Graph type * @returns Absolute path to the graph's index directory */ export declare function getGraphIndexDir(cwd: string, graphType: GraphType): string; /** * Framework graph version tracking */ export interface FrameworkGraphVersion { /** AIWG version when graph was built */ aiwg_version: string; /** Frameworks included in the graph */ frameworks_installed: string[]; /** Build timestamp */ built_at: string; } //# sourceMappingURL=types.d.ts.map