@llm-dev-ops/agentics-cli 2.1.5 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/dist/pipeline/auto-chain.d.ts +190 -0
  2. package/dist/pipeline/auto-chain.d.ts.map +1 -1
  3. package/dist/pipeline/auto-chain.js +1571 -72
  4. package/dist/pipeline/auto-chain.js.map +1 -1
  5. package/dist/pipeline/phase2/phases/prompt-generator.d.ts.map +1 -1
  6. package/dist/pipeline/phase2/phases/prompt-generator.js +205 -12
  7. package/dist/pipeline/phase2/phases/prompt-generator.js.map +1 -1
  8. package/dist/pipeline/phase2/schemas.d.ts +10 -10
  9. package/dist/pipeline/phase4/phases/http-server-generator.d.ts +12 -0
  10. package/dist/pipeline/phase4/phases/http-server-generator.d.ts.map +1 -1
  11. package/dist/pipeline/phase4/phases/http-server-generator.js +92 -25
  12. package/dist/pipeline/phase4/phases/http-server-generator.js.map +1 -1
  13. package/dist/pipeline/phase4-5-pre-render/financial-model.d.ts +51 -0
  14. package/dist/pipeline/phase4-5-pre-render/financial-model.d.ts.map +1 -0
  15. package/dist/pipeline/phase4-5-pre-render/financial-model.js +118 -0
  16. package/dist/pipeline/phase4-5-pre-render/financial-model.js.map +1 -0
  17. package/dist/pipeline/phase4-5-pre-render/post-render-reconciler.d.ts +53 -0
  18. package/dist/pipeline/phase4-5-pre-render/post-render-reconciler.d.ts.map +1 -0
  19. package/dist/pipeline/phase4-5-pre-render/post-render-reconciler.js +130 -0
  20. package/dist/pipeline/phase4-5-pre-render/post-render-reconciler.js.map +1 -0
  21. package/dist/pipeline/phase4-5-pre-render/pre-render-coordinator.d.ts +47 -0
  22. package/dist/pipeline/phase4-5-pre-render/pre-render-coordinator.d.ts.map +1 -0
  23. package/dist/pipeline/phase4-5-pre-render/pre-render-coordinator.js +105 -0
  24. package/dist/pipeline/phase4-5-pre-render/pre-render-coordinator.js.map +1 -0
  25. package/dist/pipeline/phase4-5-pre-render/sector-baselines.d.ts +42 -0
  26. package/dist/pipeline/phase4-5-pre-render/sector-baselines.d.ts.map +1 -0
  27. package/dist/pipeline/phase4-5-pre-render/sector-baselines.js +117 -0
  28. package/dist/pipeline/phase4-5-pre-render/sector-baselines.js.map +1 -0
  29. package/dist/pipeline/phase5-build/phase5-build-coordinator.d.ts.map +1 -1
  30. package/dist/pipeline/phase5-build/phase5-build-coordinator.js +44 -0
  31. package/dist/pipeline/phase5-build/phase5-build-coordinator.js.map +1 -1
  32. package/dist/pipeline/phase5-build/phases/post-generation-validator.d.ts +75 -0
  33. package/dist/pipeline/phase5-build/phases/post-generation-validator.d.ts.map +1 -0
  34. package/dist/pipeline/phase5-build/phases/post-generation-validator.js +1068 -0
  35. package/dist/pipeline/phase5-build/phases/post-generation-validator.js.map +1 -0
  36. package/dist/pipeline/phase5-build/types.d.ts +1 -1
  37. package/dist/pipeline/phase5-build/types.d.ts.map +1 -1
  38. package/dist/pipeline/types.d.ts +87 -0
  39. package/dist/pipeline/types.d.ts.map +1 -1
  40. package/dist/pipeline/types.js +51 -1
  41. package/dist/pipeline/types.js.map +1 -1
  42. package/dist/synthesis/consensus-svg.d.ts +19 -0
  43. package/dist/synthesis/consensus-svg.d.ts.map +1 -0
  44. package/dist/synthesis/consensus-svg.js +95 -0
  45. package/dist/synthesis/consensus-svg.js.map +1 -0
  46. package/dist/synthesis/consensus-tiers.d.ts +99 -0
  47. package/dist/synthesis/consensus-tiers.d.ts.map +1 -0
  48. package/dist/synthesis/consensus-tiers.js +285 -0
  49. package/dist/synthesis/consensus-tiers.js.map +1 -0
  50. package/dist/synthesis/domain-labor-classifier.d.ts +101 -0
  51. package/dist/synthesis/domain-labor-classifier.d.ts.map +1 -0
  52. package/dist/synthesis/domain-labor-classifier.js +312 -0
  53. package/dist/synthesis/domain-labor-classifier.js.map +1 -0
  54. package/dist/synthesis/domain-unit-registry.d.ts +59 -0
  55. package/dist/synthesis/domain-unit-registry.d.ts.map +1 -0
  56. package/dist/synthesis/domain-unit-registry.js +320 -0
  57. package/dist/synthesis/domain-unit-registry.js.map +1 -0
  58. package/dist/synthesis/financial-claim-extractor.d.ts +72 -0
  59. package/dist/synthesis/financial-claim-extractor.d.ts.map +1 -0
  60. package/dist/synthesis/financial-claim-extractor.js +382 -0
  61. package/dist/synthesis/financial-claim-extractor.js.map +1 -0
  62. package/dist/synthesis/financial-consistency-rules.d.ts +70 -0
  63. package/dist/synthesis/financial-consistency-rules.d.ts.map +1 -0
  64. package/dist/synthesis/financial-consistency-rules.js +483 -0
  65. package/dist/synthesis/financial-consistency-rules.js.map +1 -0
  66. package/dist/synthesis/financial-consistency-runner.d.ts +73 -0
  67. package/dist/synthesis/financial-consistency-runner.d.ts.map +1 -0
  68. package/dist/synthesis/financial-consistency-runner.js +131 -0
  69. package/dist/synthesis/financial-consistency-runner.js.map +1 -0
  70. package/dist/synthesis/forbidden-spin-phrases.d.ts +32 -0
  71. package/dist/synthesis/forbidden-spin-phrases.d.ts.map +1 -0
  72. package/dist/synthesis/forbidden-spin-phrases.js +84 -0
  73. package/dist/synthesis/forbidden-spin-phrases.js.map +1 -0
  74. package/dist/synthesis/phase-gate-thresholds.d.ts +30 -0
  75. package/dist/synthesis/phase-gate-thresholds.d.ts.map +1 -0
  76. package/dist/synthesis/phase-gate-thresholds.js +34 -0
  77. package/dist/synthesis/phase-gate-thresholds.js.map +1 -0
  78. package/dist/synthesis/prompts/index.d.ts.map +1 -1
  79. package/dist/synthesis/prompts/index.js +22 -0
  80. package/dist/synthesis/prompts/index.js.map +1 -1
  81. package/dist/synthesis/roadmap-dates.d.ts +72 -0
  82. package/dist/synthesis/roadmap-dates.d.ts.map +1 -0
  83. package/dist/synthesis/roadmap-dates.js +203 -0
  84. package/dist/synthesis/roadmap-dates.js.map +1 -0
  85. package/dist/synthesis/simulation-artifact-generator.d.ts.map +1 -1
  86. package/dist/synthesis/simulation-artifact-generator.js +135 -1
  87. package/dist/synthesis/simulation-artifact-generator.js.map +1 -1
  88. package/dist/synthesis/simulation-renderers.d.ts +105 -2
  89. package/dist/synthesis/simulation-renderers.d.ts.map +1 -1
  90. package/dist/synthesis/simulation-renderers.js +1192 -123
  91. package/dist/synthesis/simulation-renderers.js.map +1 -1
  92. package/dist/synthesis/unit-economics-loader.d.ts +71 -0
  93. package/dist/synthesis/unit-economics-loader.d.ts.map +1 -0
  94. package/dist/synthesis/unit-economics-loader.js +200 -0
  95. package/dist/synthesis/unit-economics-loader.js.map +1 -0
  96. package/package.json +1 -1
@@ -44,6 +44,196 @@ export interface AutoChainResult {
44
44
  commitHash?: string;
45
45
  githubUrl?: string;
46
46
  }
47
+ /**
48
+ * Copy whatever planning artifacts exist from ~/.agentics/runs/<traceId>/
49
+ * to .agentics/plans/ in the current working directory. Uses .agentics/plans/
50
+ * instead of plans/ to avoid colliding with any existing plans/ folder in the
51
+ * project (e.g., SPARC artifacts checked into the repo). Skips files that
52
+ * already exist with identical content to avoid unnecessary duplication.
53
+ *
54
+ * Called after every phase so even if later phases fail, earlier artifacts
55
+ * are still available.
56
+ */
57
+ /**
58
+ * ADR-PIPELINE-074: scaffold body for `src/logger.ts`.
59
+ *
60
+ * Uses `node:async_hooks` AsyncLocalStorage so concurrent Express/Hono
61
+ * requests NEVER cross-contaminate log lines. The legacy
62
+ * `let currentCorrelationId` module-level mutable has been removed; any
63
+ * generator that reintroduces it is caught by PGV-016.
64
+ *
65
+ * Exports:
66
+ * - `Logger` interface with info/warn/error/child
67
+ * - `createLogger(service)` factory
68
+ * - `runWithCorrelation(id, fn)` — wraps an async scope with the ID
69
+ * - `getCorrelationId()` — returns the ID for the current async scope
70
+ * - `setCorrelationId(id)` — legacy shim; mutates the current store
71
+ */
72
+ export declare const LOGGER_SCAFFOLD = "// Auto-generated by Agentics pipeline (ADR-PIPELINE-074)\n// Correlation IDs flow through an AsyncLocalStorage so concurrent requests\n// never cross-contaminate log lines. Import runWithCorrelation + createLogger\n// from here; NEVER reach for a module-level mutable to store the ID.\nimport { AsyncLocalStorage } from 'node:async_hooks';\n\nexport interface Logger {\n info(event: string, data?: Record<string, unknown>): void;\n warn(event: string, data?: Record<string, unknown>): void;\n error(event: string, error: Error, data?: Record<string, unknown>): void;\n child(bindings: Record<string, unknown>): Logger;\n}\n\ninterface LoggerContext {\n correlationId?: string;\n bindings: Record<string, unknown>;\n}\n\nconst storage = new AsyncLocalStorage<LoggerContext>();\n\n/**\n * Run `fn` with `correlationId` installed in the current async scope.\n * Every log line emitted inside `fn` and its async descendants will carry\n * this ID, and it will NOT leak to other concurrent requests.\n */\nexport function runWithCorrelation<T>(correlationId: string, fn: () => T): T {\n const parent = storage.getStore();\n const ctx: LoggerContext = {\n correlationId,\n bindings: parent?.bindings ?? {},\n };\n return storage.run(ctx, fn);\n}\n\n/** Returns the correlation ID for the current async scope, if any. */\nexport function getCorrelationId(): string | undefined {\n return storage.getStore()?.correlationId;\n}\n\n/**\n * Back-compat shim \u2014 deprecated. Retained for legacy callers, but\n * SHOULD NOT be used inside request handlers. Use runWithCorrelation.\n * Under AsyncLocalStorage, this mutates the current store in place;\n * outside an async scope it is a silent no-op.\n */\nexport function setCorrelationId(id: string | undefined): void {\n const ctx = storage.getStore();\n if (ctx) ctx.correlationId = id;\n}\n\nexport function createLogger(service: string): Logger {\n const build = (bindings: Record<string, unknown>): Logger => {\n const emit = (level: string, event: string, extra?: Record<string, unknown>): void => {\n const ctx = storage.getStore();\n const entry = {\n timestamp: new Date().toISOString(),\n level,\n service,\n event,\n ...(ctx?.correlationId ? { correlationId: ctx.correlationId } : {}),\n ...bindings,\n ...(ctx?.bindings ?? {}),\n ...extra,\n };\n process.stderr.write(JSON.stringify(entry) + '\\n');\n };\n return {\n info: (event, data) => emit('info', event, data),\n warn: (event, data) => emit('warn', event, data),\n error: (event, err, data) => emit('error', event, {\n error: err.message,\n stack: err.stack,\n ...data,\n }),\n child: (childBindings) => build({ ...bindings, ...childBindings }),\n };\n };\n return build({});\n}\n";
73
+ /**
74
+ * ADR-PIPELINE-074: concurrency-correctness test emitted alongside
75
+ * `src/logger.ts` in every generated project. Fails loudly if
76
+ * AsyncLocalStorage wiring regresses.
77
+ */
78
+ export declare const LOGGER_CONCURRENCY_TEST_SCAFFOLD = "// Auto-generated by Agentics pipeline (ADR-PIPELINE-074)\n// Proves correlation IDs do NOT leak across concurrent async tasks.\n// Works with vitest and jest \u2014 both expose describe/it/expect as globals.\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { describe, it, expect } from 'vitest';\nimport { runWithCorrelation, getCorrelationId } from './logger.js';\n\ndescribe('logger correlation-id async scoping (ADR-PIPELINE-074)', () => {\n it('does not leak correlation IDs across concurrent async tasks', async () => {\n const results: Array<{ requested: string; observed: string | undefined }> = [];\n const tasks: Promise<void>[] = [];\n for (let i = 0; i < 50; i++) {\n const id = `req-${i}`;\n tasks.push(\n runWithCorrelation(id, async () => {\n await new Promise((r) => setTimeout(r, Math.random() * 10));\n results.push({ requested: id, observed: getCorrelationId() });\n }),\n );\n }\n await Promise.all(tasks);\n for (const r of results) {\n expect(r.observed).toBe(r.requested);\n }\n });\n});\n";
79
+ /**
80
+ * ADR-PIPELINE-068: scaffold body for `src/simulation-lineage.ts`.
81
+ *
82
+ * Exported so unit tests can write the file to a temp directory and
83
+ * exercise the runtime behavior (env override, manifest walk, fallback)
84
+ * without having to spin up the full pipeline.
85
+ *
86
+ * Invariants enforced by tests:
87
+ * - Uses `readFileSync` + `fileURLToPath` (NEVER `require(`)
88
+ * - Exports `loadSimulationLineage`, `requireSimulationLineage`,
89
+ * `formatLineageBanner`, and the legacy `loadSimulationId` alias
90
+ * - Walks up at most 6 directories from the module location and from cwd
91
+ */
92
+ export declare const SIMULATION_LINEAGE_SCAFFOLD = "// Auto-generated by Agentics pipeline (ADR-PIPELINE-068)\n// ESM-safe simulation lineage loader. Reads .agentics/plans/manifest.json\n// (or .agentics/runs/latest/manifest.json) using readFileSync \u2014 never\n// CommonJS require(). Do NOT reimplement this helper; import from it.\nimport { readFileSync, existsSync } from 'node:fs';\nimport { resolve, dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nexport type SimulationLineageSource = 'env' | 'manifest' | 'fallback';\n\nexport interface SimulationLineage {\n readonly simulationId: string;\n readonly traceId: string;\n readonly runId: string;\n readonly source: SimulationLineageSource;\n readonly manifestPath?: string;\n}\n\nconst MANIFEST_CANDIDATES: readonly string[] = [\n '.agentics/plans/manifest.json',\n '.agentics/runs/latest/manifest.json',\n];\n\nconst WALK_DEPTH = 6;\n\n/** Walk up from startDir looking for any manifest candidate path. */\nfunction findManifest(startDir: string): string | null {\n let dir = startDir;\n for (let i = 0; i < WALK_DEPTH; i++) {\n for (const rel of MANIFEST_CANDIDATES) {\n const candidate = resolve(dir, rel);\n if (existsSync(candidate)) return candidate;\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n return null;\n}\n\nfunction moduleDir(): string {\n try {\n return dirname(fileURLToPath(import.meta.url));\n } catch {\n return process.cwd();\n }\n}\n\n/**\n * Load the simulation lineage. Permissive \u2014 returns a fallback record when\n * nothing is available. Callers who need strict behavior should use\n * requireSimulationLineage() instead.\n *\n * Resolution order:\n * 1. AGENTICS_SIMULATION_ID / AGENTICS_TRACE_ID environment variables\n * 2. First manifest.json found walking up from this module (then cwd)\n * 3. Fallback record with source='fallback'\n */\nexport function loadSimulationLineage(): SimulationLineage {\n const envSim = process.env['AGENTICS_SIMULATION_ID'];\n const envTrace = process.env['AGENTICS_TRACE_ID'];\n if (envSim) {\n return {\n simulationId: envSim,\n traceId: envTrace ?? envSim,\n runId: envSim,\n source: 'env',\n };\n }\n\n const startDirs = [moduleDir(), process.cwd()];\n for (const start of startDirs) {\n try {\n const manifestPath = findManifest(start);\n if (!manifestPath) continue;\n const raw = JSON.parse(readFileSync(manifestPath, 'utf-8')) as Record<string, unknown>;\n const runId = String(raw['run_id'] ?? raw['runId'] ?? '');\n const simulationId = String(\n raw['simulation_id'] ?? raw['simulationId'] ?? raw['execution_id'] ?? runId,\n );\n const traceId = String(raw['trace_id'] ?? raw['traceId'] ?? simulationId);\n if (simulationId) {\n return { simulationId, traceId, runId: runId || simulationId, source: 'manifest', manifestPath };\n }\n } catch {\n // Try the next start dir. Never throw from the permissive loader.\n }\n }\n\n return {\n simulationId: 'sim-unknown',\n traceId: 'trace-unknown',\n runId: 'run-unknown',\n source: 'fallback',\n };\n}\n\n/**\n * Strict variant \u2014 throws ECLI-LIN-068 when no simulation lineage is\n * available. Use this at startup when the service MUST carry a real\n * simulation id (audit logs, ERP posts, etc.).\n */\nexport function requireSimulationLineage(): SimulationLineage {\n const lineage = loadSimulationLineage();\n if (lineage.source === 'fallback') {\n throw new Error(\n 'ECLI-LIN-068: simulation lineage unavailable \u2014 set AGENTICS_SIMULATION_ID or place .agentics/plans/manifest.json in the project tree',\n );\n }\n return lineage;\n}\n\n/**\n * Human-readable banner printed by the demo script when the loader falls\n * back. Makes the break visible instead of letting sim-unknown leak into\n * downstream audit logs and ERP posts.\n */\nexport function formatLineageBanner(lineage: SimulationLineage): string {\n if (lineage.source !== 'fallback') {\n return `simulation lineage: ${lineage.simulationId} (source: ${lineage.source})`;\n }\n return [\n '',\n '\u26A0\uFE0F Simulation lineage unavailable (source: fallback)',\n ' All audit entries and ERP posts will carry sim-unknown.',\n ' Fix: place .agentics/plans/manifest.json in the project tree,',\n ' or set AGENTICS_SIMULATION_ID=<run-id> before running the demo.',\n '',\n ].join('\\n');\n}\n\n/** Also exported under the legacy alias some older prompts referenced. */\nexport const loadSimulationId = (): string => loadSimulationLineage().simulationId;\n";
93
+ /**
94
+ * ADR-PIPELINE-069: scaffold body for `src/circuit-breaker.ts`.
95
+ *
96
+ * Extracted from the legacy middleware.ts scaffold so generators can
97
+ * `import { CircuitBreaker } from './circuit-breaker.js'` without pulling
98
+ * the entire middleware module. middleware.ts now re-exports this symbol
99
+ * so existing imports keep working.
100
+ */
101
+ export declare const CIRCUIT_BREAKER_SCAFFOLD = "// Auto-generated by Agentics pipeline (ADR-PIPELINE-069)\n// Owned by the scaffold \u2014 do NOT redeclare CircuitBreaker in generated code.\nimport { createLogger } from './logger.js';\n\n/** Simple circuit breaker for external service calls. */\nexport class CircuitBreaker {\n private failures = 0;\n private state: 'closed' | 'open' | 'half-open' = 'closed';\n private nextAttempt = 0;\n\n constructor(\n private readonly name: string,\n private readonly threshold = 5,\n private readonly cooldownMs = 30000,\n private readonly logger = createLogger('circuit-breaker'),\n ) {}\n\n async call<T>(fn: () => Promise<T>): Promise<T> {\n if (this.state === 'open') {\n if (Date.now() < this.nextAttempt) {\n throw new Error(`Circuit breaker '${this.name}' is OPEN \u2014 retry after ${new Date(this.nextAttempt).toISOString()}`);\n }\n this.state = 'half-open';\n this.logger.info('circuit.half-open', { name: this.name });\n }\n try {\n const result = await fn();\n if (this.state === 'half-open') {\n this.state = 'closed';\n this.failures = 0;\n this.logger.info('circuit.closed', { name: this.name });\n }\n return result;\n } catch (err) {\n this.failures++;\n if (this.failures >= this.threshold) {\n this.state = 'open';\n this.nextAttempt = Date.now() + this.cooldownMs;\n this.logger.warn('circuit.open', { name: this.name, failures: this.failures, retryAt: new Date(this.nextAttempt).toISOString() });\n }\n throw err;\n }\n }\n\n getState(): string { return this.state; }\n}\n";
102
+ /**
103
+ * ADR-PIPELINE-075: scaffold body for `src/persistence/repository.ts`.
104
+ *
105
+ * Defines the `Repository<T>` interface every stateful service should
106
+ * depend on. Each entity is identified by `idOf(entity)`, validated by a
107
+ * Zod schema on read, and bound to a table name for the SQLite backend.
108
+ */
109
+ export declare const REPOSITORY_SCAFFOLD = "// Auto-generated by Agentics pipeline (ADR-PIPELINE-075)\n// Repository interface every stateful service should depend on.\n// Generators: use this instead of storing state in a Map<string, T>.\nimport type { ZodType } from 'zod';\n\nexport interface Repository<T> {\n save(entity: T): Promise<void>;\n get(id: string): Promise<T | null>;\n list(filter?: Partial<T>): Promise<readonly T[]>;\n delete(id: string): Promise<void>;\n}\n\nexport interface RepositoryOptions<T> {\n /** How to extract the primary key from an entity. */\n readonly idOf: (entity: T) => string;\n /** Zod schema used to re-validate rows on load (SQLite JSON columns are untrusted). */\n readonly schema: ZodType<T>;\n /** Table name for SQLite backend. Must match /^[a-zA-Z_][a-zA-Z0-9_]*$/. */\n readonly tableName: string;\n}\n\n/** Errors thrown by all Repository implementations. */\nexport class RepositoryError extends Error {\n constructor(message: string, public readonly code: string) {\n super(`${code}: ${message}`);\n this.name = 'RepositoryError';\n }\n}\n";
110
+ /**
111
+ * ADR-PIPELINE-075: scaffold body for `src/persistence/in-memory-repository.ts`.
112
+ *
113
+ * Test-friendly `Repository<T>` implementation backed by a Map. Validates
114
+ * on write AND read so test fixtures catch schema drift. Production
115
+ * services should swap in SqliteRepository via the composition root.
116
+ */
117
+ export declare const IN_MEMORY_REPO_SCAFFOLD = "// Auto-generated by Agentics pipeline (ADR-PIPELINE-075)\n// In-memory Repository<T> for tests. Not for production use.\nimport type { Repository, RepositoryOptions } from './repository.js';\n\nexport class InMemoryRepository<T> implements Repository<T> {\n private readonly rows = new Map<string, T>();\n constructor(private readonly options: RepositoryOptions<T>) {}\n\n async save(entity: T): Promise<void> {\n const validated = this.options.schema.parse(entity);\n this.rows.set(this.options.idOf(validated), validated);\n }\n\n async get(id: string): Promise<T | null> {\n const row = this.rows.get(id);\n return row === undefined ? null : row;\n }\n\n async list(filter?: Partial<T>): Promise<readonly T[]> {\n const all = Array.from(this.rows.values());\n if (!filter) return all;\n return all.filter(row =>\n Object.entries(filter).every(\n ([k, v]) => (row as Record<string, unknown>)[k] === v,\n ),\n );\n }\n\n async delete(id: string): Promise<void> {\n this.rows.delete(id);\n }\n\n /** Test helper \u2014 never call from production code. */\n clear(): void {\n this.rows.clear();\n }\n\n /** Test helper \u2014 returns the current row count. */\n get size(): number {\n return this.rows.size;\n }\n}\n";
118
+ /**
119
+ * ADR-PIPELINE-075: scaffold body for `src/persistence/sqlite-repository.ts`.
120
+ *
121
+ * Production `Repository<T>` backed by better-sqlite3. Stores each entity
122
+ * as a JSON column keyed by its primary key. Zod re-validates on read
123
+ * because the JSON column is untrusted at runtime.
124
+ *
125
+ * Generated projects must add better-sqlite3 + @types/better-sqlite3 to
126
+ * their package.json — the cross-cutting prompt footer reminds the coding
127
+ * agent to include these deps.
128
+ */
129
+ export declare const SQLITE_REPO_SCAFFOLD = "// Auto-generated by Agentics pipeline (ADR-PIPELINE-075)\n// SQLite-backed Repository<T> using better-sqlite3.\n// Requires: better-sqlite3 in dependencies, @types/better-sqlite3 in devDependencies.\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type { Repository, RepositoryOptions } from './repository.js';\nimport { RepositoryError } from './repository.js';\n\n// Minimal structural type \u2014 works with better-sqlite3 without importing it\n// into the scaffold (so the scaffold compiles even when the dependency\n// isn't installed in the pipeline's own test environment).\nexport interface BetterSqliteDatabase {\n exec(sql: string): void;\n prepare(sql: string): {\n run(...params: any[]): { changes: number; lastInsertRowid: number | bigint };\n get(...params: any[]): any;\n all(...params: any[]): any[];\n };\n}\n\nexport interface SqliteRepositoryDeps {\n readonly db: BetterSqliteDatabase;\n}\n\nexport class SqliteRepository<T> implements Repository<T> {\n constructor(\n private readonly deps: SqliteRepositoryDeps,\n private readonly options: RepositoryOptions<T>,\n ) {\n this.assertSafeTableName();\n this.deps.db.exec(`\n CREATE TABLE IF NOT EXISTS ${this.options.tableName} (\n id TEXT PRIMARY KEY,\n data TEXT NOT NULL,\n updated_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now'))\n );\n `);\n }\n\n private assertSafeTableName(): void {\n if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(this.options.tableName)) {\n throw new RepositoryError(`unsafe table name: ${this.options.tableName}`, 'ECLI-REPO-001');\n }\n }\n\n async save(entity: T): Promise<void> {\n const validated = this.options.schema.parse(entity);\n const id = this.options.idOf(validated);\n const data = JSON.stringify(validated);\n this.deps.db\n .prepare(\n `INSERT INTO ${this.options.tableName} (id, data) VALUES (?, ?)\n ON CONFLICT(id) DO UPDATE SET data = excluded.data,\n updated_at = strftime('%Y-%m-%dT%H:%M:%fZ','now')`,\n )\n .run(id, data);\n }\n\n async get(id: string): Promise<T | null> {\n const row = this.deps.db\n .prepare(`SELECT data FROM ${this.options.tableName} WHERE id = ?`)\n .get(id) as { data: string } | undefined;\n if (!row) return null;\n return this.options.schema.parse(JSON.parse(row.data));\n }\n\n async list(filter?: Partial<T>): Promise<readonly T[]> {\n const rows = this.deps.db\n .prepare(`SELECT data FROM ${this.options.tableName}`)\n .all() as Array<{ data: string }>;\n const parsed = rows.map(r => this.options.schema.parse(JSON.parse(r.data)));\n if (!filter) return parsed;\n return parsed.filter(row =>\n Object.entries(filter).every(\n ([k, v]) => (row as Record<string, unknown>)[k] === v,\n ),\n );\n }\n\n async delete(id: string): Promise<void> {\n this.deps.db.prepare(`DELETE FROM ${this.options.tableName} WHERE id = ?`).run(id);\n }\n}\n";
130
+ /**
131
+ * ADR-PIPELINE-075: scaffold body for `src/persistence/audit-repository.ts`.
132
+ *
133
+ * Append-only audit repository. NO update, NO delete — an audit entry is
134
+ * committed and lives forever. Services that need to mutate a past entry
135
+ * have to bypass the repository and talk raw SQL, which PGV and code
136
+ * review will catch.
137
+ */
138
+ export declare const AUDIT_REPO_SCAFFOLD = "// Auto-generated by Agentics pipeline (ADR-PIPELINE-075)\n// Append-only audit repository. No update, no delete by design.\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type { BetterSqliteDatabase } from './sqlite-repository.js';\n\nexport interface AuditEntry {\n readonly entryId: string;\n readonly prevHash: string;\n readonly hash: string;\n readonly payload: Record<string, unknown>;\n readonly actor: string;\n readonly action: string;\n readonly entityType: string;\n readonly entityId: string;\n readonly createdAt: string;\n}\n\nexport interface AuditRepositoryDeps {\n readonly db: BetterSqliteDatabase;\n}\n\nexport class AppendOnlyAuditRepository {\n constructor(private readonly deps: AuditRepositoryDeps) {\n this.deps.db.exec(`\n CREATE TABLE IF NOT EXISTS audit_log (\n sequence INTEGER PRIMARY KEY AUTOINCREMENT,\n entry_id TEXT NOT NULL UNIQUE,\n prev_hash TEXT NOT NULL,\n hash TEXT NOT NULL,\n payload TEXT NOT NULL,\n actor TEXT NOT NULL,\n action TEXT NOT NULL,\n entity_type TEXT NOT NULL,\n entity_id TEXT NOT NULL,\n created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ','now'))\n );\n CREATE INDEX IF NOT EXISTS idx_audit_log_entity\n ON audit_log(entity_type, entity_id);\n `);\n }\n\n append(entry: AuditEntry): void {\n this.deps.db\n .prepare(\n `INSERT INTO audit_log\n (entry_id, prev_hash, hash, payload, actor, action, entity_type, entity_id, created_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,\n )\n .run(\n entry.entryId,\n entry.prevHash,\n entry.hash,\n JSON.stringify(entry.payload),\n entry.actor,\n entry.action,\n entry.entityType,\n entry.entityId,\n entry.createdAt,\n );\n }\n\n list(): readonly AuditEntry[] {\n const rows = this.deps.db\n .prepare(`SELECT * FROM audit_log ORDER BY sequence ASC`)\n .all() as Array<{\n entry_id: string;\n prev_hash: string;\n hash: string;\n payload: string;\n actor: string;\n action: string;\n entity_type: string;\n entity_id: string;\n created_at: string;\n }>;\n return rows.map(r => ({\n entryId: r.entry_id,\n prevHash: r.prev_hash,\n hash: r.hash,\n payload: JSON.parse(r.payload),\n actor: r.actor,\n action: r.action,\n entityType: r.entity_type,\n entityId: r.entity_id,\n createdAt: r.created_at,\n }));\n }\n\n listByEntity(entityType: string, entityId: string): readonly AuditEntry[] {\n const rows = this.deps.db\n .prepare(\n `SELECT * FROM audit_log\n WHERE entity_type = ? AND entity_id = ?\n ORDER BY sequence ASC`,\n )\n .all(entityType, entityId) as Array<{\n entry_id: string;\n prev_hash: string;\n hash: string;\n payload: string;\n actor: string;\n action: string;\n entity_type: string;\n entity_id: string;\n created_at: string;\n }>;\n return rows.map(r => ({\n entryId: r.entry_id,\n prevHash: r.prev_hash,\n hash: r.hash,\n payload: JSON.parse(r.payload),\n actor: r.actor,\n action: r.action,\n entityType: r.entity_type,\n entityId: r.entity_id,\n createdAt: r.created_at,\n }));\n }\n\n /** Total row count \u2014 used by verify() and reconciliation jobs. */\n size(): number {\n const row = this.deps.db\n .prepare('SELECT COUNT(*) AS n FROM audit_log')\n .get() as { n: number };\n return row.n;\n }\n}\n";
139
+ /**
140
+ * ADR-PIPELINE-078: scaffold body for `src/persistence/canonical-json.ts`.
141
+ *
142
+ * Deterministic JSON serialization for audit hash chains and idempotency
143
+ * keys. Follows JCS (RFC 8785) closely enough for the pipeline's needs:
144
+ * object keys are sorted lexicographically at every depth; arrays preserve
145
+ * order; strings, numbers, booleans, and null use standard JSON encoding.
146
+ *
147
+ * Rejects undefined, BigInt, and circular references. Date objects should
148
+ * be serialized as ISO strings at the boundary BEFORE passing to this
149
+ * function.
150
+ */
151
+ export declare const CANONICAL_JSON_SCAFFOLD = "// Auto-generated by Agentics pipeline (ADR-PIPELINE-078)\n// Deterministic JSON for audit hash chains. Keys sorted at every depth.\n\nexport class CanonicalJsonError extends Error {\n constructor(message: string) {\n super(`ECLI-CJ-078: ${message}`);\n this.name = 'CanonicalJsonError';\n }\n}\n\n/**\n * Canonicalize `value` into a deterministic JSON string. Keys are sorted\n * at every level; arrays preserve order; primitives use standard encoding.\n */\nexport function canonicalJson(value: unknown): string {\n const visited = new WeakSet<object>();\n return serialize(value, visited);\n}\n\nfunction serialize(value: unknown, visited: WeakSet<object>): string {\n if (value === undefined) {\n throw new CanonicalJsonError('undefined is not canonicalizable \u2014 pass null instead');\n }\n if (value === null) return 'null';\n if (typeof value === 'boolean') return value ? 'true' : 'false';\n if (typeof value === 'number') {\n if (!Number.isFinite(value)) {\n throw new CanonicalJsonError(`non-finite number: ${String(value)}`);\n }\n return JSON.stringify(value);\n }\n if (typeof value === 'string') {\n return JSON.stringify(value);\n }\n if (typeof value === 'bigint') {\n throw new CanonicalJsonError('BigInt is not canonicalizable \u2014 convert to string at the boundary');\n }\n if (Array.isArray(value)) {\n if (visited.has(value)) throw new CanonicalJsonError('circular reference in array');\n visited.add(value);\n const parts = value.map(item => serialize(item, visited));\n visited.delete(value);\n return '[' + parts.join(',') + ']';\n }\n if (typeof value === 'object') {\n if (visited.has(value as object)) throw new CanonicalJsonError('circular reference in object');\n visited.add(value as object);\n const record = value as Record<string, unknown>;\n const keys = Object.keys(record).sort();\n const pairs: string[] = [];\n for (const key of keys) {\n const v = record[key];\n if (v === undefined) continue;\n pairs.push(JSON.stringify(key) + ':' + serialize(v, visited));\n }\n visited.delete(value as object);\n return '{' + pairs.join(',') + '}';\n }\n throw new CanonicalJsonError(`unsupported value type: ${typeof value}`);\n}\n";
152
+ /**
153
+ * ADR-PIPELINE-078: scaffold body for `src/persistence/audit-hash.ts`.
154
+ *
155
+ * Wraps `canonicalJson` with audit-log-specific conventions. Every
156
+ * generated `AuditService.append()` method should call `hashAuditEntry`
157
+ * rather than rolling its own `JSON.stringify + createHash` chain.
158
+ */
159
+ export declare const AUDIT_HASH_SCAFFOLD = "// Auto-generated by Agentics pipeline (ADR-PIPELINE-078)\n// Audit hash-chain helper. Import hashAuditEntry instead of hand-rolling\n// createHash('sha256').update(JSON.stringify(...)).\nimport { createHash } from 'node:crypto';\nimport { canonicalJson } from './canonical-json.js';\n\nexport interface HashChainInput {\n readonly prevHash: string;\n readonly entryId: string;\n readonly actor: string;\n readonly action: string;\n readonly entityType: string;\n readonly entityId: string;\n readonly payload: unknown;\n readonly createdAt: string;\n}\n\n/**\n * Deterministically hash an audit entry's content + its link to the\n * previous entry. Payload keys are sorted at every depth so mutations\n * at any nesting level change the hash.\n */\nexport function hashAuditEntry(input: HashChainInput): string {\n const body = canonicalJson({\n prevHash: input.prevHash,\n entryId: input.entryId,\n actor: input.actor,\n action: input.action,\n entityType: input.entityType,\n entityId: input.entityId,\n payload: input.payload,\n createdAt: input.createdAt,\n });\n return createHash('sha256').update(body).digest('hex');\n}\n";
160
+ /**
161
+ * ADR-PIPELINE-077: scaffold body for `src/erp/schema-provenance.ts`.
162
+ *
163
+ * Every generated ERP adapter file (schema.ts, <system>-adapter.ts, etc.)
164
+ * must export an `ERP_SCHEMA_PROVENANCE` constant of type
165
+ * `ErpSchemaProvenance` declaring whether the schema was invented,
166
+ * pulled from a catalog, or validated by an SME. Under
167
+ * `AGENTICS_ERP_STRICT=true`, `assertErpProvenanceOrFail` refuses to
168
+ * start when source='invented'. PGV-020 enforces presence, PGV-021
169
+ * enforces reviewer + catalog_version on validated entries.
170
+ */
171
+ export declare const ERP_SCHEMA_PROVENANCE_SCAFFOLD = "// Auto-generated by Agentics pipeline (ADR-PIPELINE-077)\n// Provenance tag for generated ERP schemas. MANDATORY on every file\n// under src/erp/ that exports Zod schemas targeting an external ERP.\n\nexport type ErpProvenanceSource = 'invented' | 'catalog' | 'validated';\n\nexport interface ErpSchemaProvenance {\n /** Target ERP system \u2014 e.g. 'Ramco Aviation', 'Oracle OPERA', 'SAP S/4HANA'. */\n readonly erp_system: string;\n /** Specific module the schema targets \u2014 'Flight Catering Order'. */\n readonly module: string;\n /** Validation stage: invented (no review), catalog (fields match), validated (SME-reviewed). */\n readonly source: ErpProvenanceSource;\n /** Version identifier of the catalog source, when known. */\n readonly catalog_version: string | null;\n /** ISO timestamp of SME review when source='validated'. */\n readonly validated_at: string | null;\n /** Reviewer name + role when source='validated'. */\n readonly reviewer: { name: string; role: string } | null;\n /** Free-text notes visible in startup logs and generated README. */\n readonly notes: string;\n}\n\n/**\n * Assert an ERP adapter is allowed to run in the current environment.\n * Under AGENTICS_ERP_STRICT=true, source='invented' throws ECLI-ERP-077\n * and the process exits with code 77.\n */\nexport function assertErpProvenanceOrFail(\n provenance: ErpSchemaProvenance,\n env: NodeJS.ProcessEnv = process.env,\n): void {\n const strict = env['AGENTICS_ERP_STRICT'] === 'true';\n if (strict && provenance.source === 'invented') {\n throw new Error(\n `ECLI-ERP-077: ERP adapter for ${provenance.erp_system}/${provenance.module} has source='invented' ` +\n `and AGENTICS_ERP_STRICT=true. Pilot deployment requires an SME review \u2014 set source='validated' ` +\n `and provide reviewer + catalog_version before enabling strict mode.`,\n );\n }\n}\n\n/** Console-friendly banner for startup logs + demo output. */\nexport function formatProvenanceBanner(provenance: ErpSchemaProvenance): string {\n const icon = provenance.source === 'validated' ? '\u2705' :\n provenance.source === 'catalog' ? '\uD83D\uDFE1' :\n '\u26A0\uFE0F ';\n const lines: string[] = [\n `${icon} ERP SCHEMA PROVENANCE \u2014 ${provenance.erp_system} / ${provenance.module}`,\n ` source: ${provenance.source}`,\n ];\n if (provenance.catalog_version) lines.push(` catalog: ${provenance.catalog_version}`);\n if (provenance.validated_at) lines.push(` validated: ${provenance.validated_at}`);\n if (provenance.reviewer) lines.push(` reviewer: ${provenance.reviewer.name} (${provenance.reviewer.role})`);\n if (provenance.source === 'invented') {\n lines.push(\n ' ',\n ' WARNING: This schema has not been validated against a real ERP document catalog.',\n ' Pilot deployment requires an SME review before the first live call.',\n \" Set AGENTICS_ERP_STRICT=true in production to block runs until source='validated'.\",\n );\n }\n return lines.join('\\n');\n}\n\n/** Convenience wrapper \u2014 prints the banner to stderr. */\nexport function printProvenanceBanner(provenance: ErpSchemaProvenance): void {\n process.stderr.write(formatProvenanceBanner(provenance) + '\\n');\n}\n";
172
+ /**
173
+ * ADR-PIPELINE-076: scaffold body for `src/api/base-app.ts` (Hono variant).
174
+ *
175
+ * Ships a wire-complete base app so the coding agent never writes
176
+ * middleware/metrics/health plumbing from scratch. Generators extend
177
+ * via `createBaseApp({...}).route('/api/<domain>', yourRouter)` instead
178
+ * of rebuilding.
179
+ *
180
+ * Every generated project that imports `createBaseApp` gets:
181
+ * - correlation middleware (AsyncLocalStorage-scoped, ADR-074)
182
+ * - request logging with duration histogram
183
+ * - GET /health/live (process up check)
184
+ * - GET /health/ready (every readiness check passes)
185
+ * - GET /metrics (Prometheus text, ADR-051)
186
+ * - structured error handler (last)
187
+ */
188
+ export declare const BASE_APP_SCAFFOLD_HONO = "// Auto-generated by Agentics pipeline (ADR-PIPELINE-076)\n// Wire-complete Hono app base. DO NOT rewrite \u2014 extend via\n// `createBaseApp(deps).route('/api/...', yourRouter)` from your routes module.\nimport { Hono } from 'hono';\nimport { randomUUID } from 'node:crypto';\nimport { runWithCorrelation, createLogger } from '../logger.js';\nimport { incrementCounter, recordHistogram, metricsHandler } from '../middleware.js';\n\nexport interface HealthCheck {\n readonly name: string;\n readonly check: () => Promise<{ ok: boolean; detail?: string }>;\n}\n\nexport interface BaseAppDeps {\n readonly serviceName: string;\n readonly version: string;\n readonly readiness: readonly HealthCheck[];\n}\n\nexport interface BaseAppContextVariables {\n correlationId: string;\n startedAt: number;\n}\n\nconst baseLogger = createLogger('base-app');\n\n/**\n * Build the wire-complete base app.\n *\n * Returned Hono instance already has:\n * - correlation ID middleware (AsyncLocalStorage-scoped)\n * - request logging with duration histogram\n * - GET /health/live process-up check\n * - GET /health/ready runs every registered check\n * - GET /metrics Prometheus text format\n * - structured error handler\n *\n * Add domain routes with `.route('/api/<domain>', yourRouter)`.\n */\nexport function createBaseApp(\n deps: BaseAppDeps,\n): Hono<{ Variables: BaseAppContextVariables }> {\n const app = new Hono<{ Variables: BaseAppContextVariables }>();\n\n // Correlation ID \u2014 MUST be first so every downstream log carries it\n app.use('*', async (c, next) => {\n const id = c.req.header('x-correlation-id') ?? randomUUID();\n c.set('correlationId', id);\n c.set('startedAt', Date.now());\n c.header('X-Correlation-Id', id);\n await runWithCorrelation(id, async () => {\n await next();\n });\n });\n\n // Request logging + metrics\n app.use('*', async (c, next) => {\n await next();\n const durationMs = Date.now() - c.get('startedAt');\n const status = c.res.status;\n baseLogger.info('http.request', {\n method: c.req.method,\n path: c.req.path,\n status,\n durationMs,\n });\n incrementCounter('http_requests_total', {\n method: c.req.method,\n status: String(status),\n });\n recordHistogram('http_request_duration_ms', durationMs, {\n method: c.req.method,\n });\n });\n\n // Liveness \u2014 always returns OK if the process is running\n app.get('/health/live', (c) => {\n return c.json({\n status: 'ok',\n service: deps.serviceName,\n version: deps.version,\n uptime_sec: Math.round(process.uptime()),\n });\n });\n\n // Readiness \u2014 runs every registered check\n app.get('/health/ready', async (c) => {\n const results: Array<{ name: string; ok: boolean; detail?: string }> = [];\n for (const check of deps.readiness) {\n try {\n const r = await check.check();\n results.push({ name: check.name, ok: r.ok, ...(r.detail ? { detail: r.detail } : {}) });\n } catch (err) {\n results.push({\n name: check.name,\n ok: false,\n detail: err instanceof Error ? err.message : String(err),\n });\n }\n }\n const allOk = results.every((r) => r.ok);\n return c.json(\n { status: allOk ? 'ready' : 'not-ready', checks: results },\n allOk ? 200 : 503,\n );\n });\n\n // Metrics \u2014 Prometheus text format\n app.get('/metrics', (c) => {\n return c.text(metricsHandler(), 200, {\n 'Content-Type': 'text/plain; version=0.0.4',\n });\n });\n\n // Error handler \u2014 last, so it catches everything above\n app.onError((err, c) => {\n baseLogger.error('http.error', err as Error, {\n method: c.req.method,\n path: c.req.path,\n });\n const status = (err as { httpStatus?: number }).httpStatus ?? 500;\n return c.json(\n {\n error: {\n message: err.message,\n code: (err as { code?: string }).code ?? 'INTERNAL_ERROR',\n },\n },\n status as 500,\n );\n });\n\n return app;\n}\n";
189
+ /**
190
+ * ADR-PIPELINE-076: scaffold body for `src/api/base-app.ts` (Express variant).
191
+ *
192
+ * Used when the generator detects Express in Phase 4. Same guarantees as
193
+ * the Hono variant — wires correlation / logging / liveness / readiness
194
+ * / metrics / error handler in the correct order.
195
+ */
196
+ export declare const BASE_APP_SCAFFOLD_EXPRESS = "// Auto-generated by Agentics pipeline (ADR-PIPELINE-076)\n// Wire-complete Express app base. DO NOT rewrite \u2014 mount your routes\n// onto the returned `app` instance instead.\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport express from 'express';\nimport { randomUUID } from 'node:crypto';\nimport { runWithCorrelation, createLogger } from '../logger.js';\nimport { incrementCounter, recordHistogram, metricsHandlerExpress } from '../middleware.js';\n\nexport interface HealthCheck {\n readonly name: string;\n readonly check: () => Promise<{ ok: boolean; detail?: string }>;\n}\n\nexport interface BaseAppDeps {\n readonly serviceName: string;\n readonly version: string;\n readonly readiness: readonly HealthCheck[];\n}\n\nconst baseLogger = createLogger('base-app');\n\nexport function createBaseApp(deps: BaseAppDeps): express.Express {\n const app = express();\n app.use(express.json({ limit: '1mb' }));\n\n // Correlation ID \u2014 AsyncLocalStorage-scoped for the request's\n // entire async continuation.\n app.use((req: any, res: any, next: () => void) => {\n const id = (req.headers['x-correlation-id'] as string) || randomUUID();\n req.correlationId = id;\n res.setHeader('X-Correlation-Id', id);\n runWithCorrelation(id, next);\n });\n\n // Request logging + metrics\n app.use((req: any, res: any, next: () => void) => {\n const started = Date.now();\n res.on('finish', () => {\n const durationMs = Date.now() - started;\n baseLogger.info('http.request', {\n method: req.method,\n path: req.path,\n status: res.statusCode,\n durationMs,\n });\n incrementCounter('http_requests_total', {\n method: req.method,\n status: String(res.statusCode),\n });\n recordHistogram('http_request_duration_ms', durationMs, {\n method: req.method,\n });\n });\n next();\n });\n\n app.get('/health/live', (_req, res) => {\n res.json({\n status: 'ok',\n service: deps.serviceName,\n version: deps.version,\n uptime_sec: Math.round(process.uptime()),\n });\n });\n\n app.get('/health/ready', async (_req, res) => {\n const results: Array<{ name: string; ok: boolean; detail?: string }> = [];\n for (const check of deps.readiness) {\n try {\n const r = await check.check();\n results.push({ name: check.name, ok: r.ok, ...(r.detail ? { detail: r.detail } : {}) });\n } catch (err) {\n results.push({\n name: check.name,\n ok: false,\n detail: err instanceof Error ? err.message : String(err),\n });\n }\n }\n const allOk = results.every((r) => r.ok);\n res.status(allOk ? 200 : 503).json({\n status: allOk ? 'ready' : 'not-ready',\n checks: results,\n });\n });\n\n app.get('/metrics', metricsHandlerExpress);\n\n app.use((err: any, req: any, res: any, _next: () => void) => {\n baseLogger.error('http.error', err as Error, {\n method: req.method,\n path: req.path,\n });\n const status = err?.httpStatus ?? 500;\n res.status(status).json({\n error: {\n message: err?.message ?? 'Internal error',\n code: err?.code ?? 'INTERNAL_ERROR',\n },\n });\n });\n\n return app;\n}\n";
197
+ /**
198
+ * ADR-PIPELINE-069: Single source of truth for scaffold-owned modules.
199
+ *
200
+ * Every module the pipeline emits into `.agentics/plans/scaffold/src/` is
201
+ * listed here with its public exports. The list is consumed by:
202
+ * - `copyPlanningArtifacts()` — writes OWNED_MODULES.json sidecar
203
+ * - `prompt-generator.ts` — injects "do not reimplement" block
204
+ * - `post-generation-validator.ts` PGV-012 — bans duplicate declarations
205
+ *
206
+ * When you add a new scaffold file, add it here in the same change.
207
+ */
208
+ export interface OwnedScaffoldModule {
209
+ readonly path: string;
210
+ readonly exports: readonly string[];
211
+ }
212
+ export declare const OWNED_SCAFFOLD_MODULES: readonly OwnedScaffoldModule[];
213
+ export interface OwnedModulesManifest {
214
+ readonly version: '1.0';
215
+ readonly generated_at: string;
216
+ readonly owned: readonly OwnedScaffoldModule[];
217
+ }
218
+ export declare function buildOwnedModulesManifest(now?: Date): OwnedModulesManifest;
219
+ export interface ScaffoldDuplicateFinding {
220
+ /** Absolute path of the file that redeclares an owned export. */
221
+ readonly path: string;
222
+ /** The export name that collides. */
223
+ readonly exportName: string;
224
+ /** Scaffold path that owns the export. */
225
+ readonly ownedPath: string;
226
+ }
227
+ /**
228
+ * ADR-PIPELINE-069: Walk a project tree looking for generator-emitted files
229
+ * that redeclare an export listed in OWNED_SCAFFOLD_MODULES. Skips:
230
+ * - the scaffold-owned files themselves (matched by basename)
231
+ * - test files
232
+ * - node_modules / dist / .agentics
233
+ *
234
+ * Returns one finding per (file, export) pair.
235
+ */
236
+ export declare function detectScaffoldDuplicates(projectRoot: string, owned?: readonly OwnedScaffoldModule[]): ScaffoldDuplicateFinding[];
47
237
  export declare function executeAutoChain(traceId: string, options?: AutoChainOptions): Promise<AutoChainResult>;
48
238
  /**
49
239
  * Format the auto-chain result for stdout display.
@@ -1 +1 @@
1
- {"version":3,"file":"auto-chain.d.ts","sourceRoot":"","sources":["../../src/pipeline/auto-chain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAWH,OAAO,EAGL,KAAK,aAAa,EAEnB,MAAM,wBAAwB,CAAC;AA+BhC,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,aAAa,CAAC,EAAE,aAAa,CAAC;CACxC;AAED,UAAU,WAAW;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC3C,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CAC1E;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,aAAa,CAAC;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAglBD,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,eAAe,CAAC,CAmjD1B;AA0QD;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,CAoFzE"}
1
+ {"version":3,"file":"auto-chain.d.ts","sourceRoot":"","sources":["../../src/pipeline/auto-chain.ts"],"names":[],"mappings":"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"}