Repository navigation
feat(extraction-config): add support for $ref file references - #156
Conversation
Enable users to split large extraction configs into multiple files by supporting $ref references in the modules array. This allows organizing configs by domain with one file per domain. Key changes: - New expandModuleRefs function to resolve $ref references - ModuleRefNotFoundError for clear error messages when refs not found - Updated JSON schema to allow moduleRef objects in modules array - Added ModuleRef TypeScript type for type safety - Integration with extract command for automatic expansion - Full test coverage for reference resolution and error cases Co-Authored-By: Claude Opus 4.5 <[email protected]>
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. 📝 WalkthroughWalkthroughAdds support for Changes
Sequence Diagram(s)sequenceDiagram
participant CLI as Extract CLI
participant Parser as Config Parser
participant Expander as ModuleRef Expander
participant FS as File System
participant Validator as Schema Validator
participant Processor as Config Processor
CLI->>Parser: Load & parse config file
Parser-->>CLI: Parse result (includes modules)
CLI->>Expander: expandModuleRefs(parseResult.data, configDir)
loop each module entry
alt module has `$ref`
Expander->>FS: Resolve path & check exists
FS-->>Expander: exists / not found
alt exists
Expander->>FS: Read file
FS-->>Expander: file content
Expander->>Expander: Parse YAML/JSON -> ModuleConfig
Expander-->>CLI: replace `$ref` with ModuleConfig
else not found
Expander-->>CLI: throw ModuleRefNotFoundError
end
else inline module
Expander-->>CLI: leave as-is
end
end
Expander-->>CLI: expanded config
CLI->>Validator: Validate expanded config
Validator-->>CLI: validation result
CLI->>Processor: Process validated config
Processor-->>CLI: extraction output
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
PR Compliance Guide 🔍Below is a summary of compliance checks for this PR:
Compliance status legend🟢 - Fully Compliant🟡 - Partial Compliant 🔴 - Not Compliant ⚪ - Requires Further Human Verification 🏷️ - Compliance label |
||||||||||||||||||||||||||||||||
Deploying living-architecture with
|
| Latest commit: |
4e2b261
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://0303a304.living-architecture.pages.dev |
| Branch Preview URL: | https://issue-141-feat-support-ref-f.living-architecture.pages.dev |
PR Code Suggestions ✨Explore these optional code suggestions:
|
|||||||||||||||||
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Fix all issues with AI agents
In @packages/riviere-cli/src/commands/extract/expand-module-refs.ts:
- Line 8: The local interface declaration "interface ModuleRef { $ref: string }"
in expand-module-refs.ts should be removed and replaced by importing ModuleRef
from the package export; update the top-level imports to add "ModuleRef" from
"@living-architecture/riviere-extract-config" and use that imported type
everywhere in this file (e.g., where ModuleRef is referenced) so the type is
sourced from the canonical config package rather than redefined locally.
In @packages/riviere-cli/src/commands/extract/extract.ts:
- Around line 118-119: The call to expandModuleRefs can throw
ModuleRefNotFoundError and must be handled like the other user-facing validation
errors: import ModuleRefNotFoundError, wrap the
expandModuleRefs(parseResult.data, configDir) call in a try/catch, catch errors
instanceof ModuleRefNotFoundError and emit the same structured JSON error output
and non-zero exit used elsewhere in this file (mirror the formatting/keys used
in the existing error handlers), then return/exit; rethrow unexpected errors.
In @packages/riviere-extract-config/src/types.ts:
- Around line 71-75: The ExtractionConfig type currently declares modules as
ModuleConfig[] but the schema allows each entry to be either ModuleConfig or
ModuleRef; update the ExtractionConfig interface (symbol ExtractionConfig) so
its modules property is typed as an array of (ModuleConfig | ModuleRef) instead
of ModuleConfig[] — ensure ModuleRef (interface ModuleRef {$ref: string}) and
ModuleConfig are imported/available and adjust the declaration line (previously
at the modules property) accordingly to match the schema.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
⛔ Files ignored due to path filters (1)
packages/riviere-extract-config/docs/generated/schema.mdis excluded by!**/generated/**
📒 Files selected for processing (10)
.claude/hooks/block-dangerous-commands.shpackages/riviere-cli/src/commands/extract/expand-module-refs.spec.tspackages/riviere-cli/src/commands/extract/expand-module-refs.tspackages/riviere-cli/src/commands/extract/extract.spec.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-cli/src/errors.spec.tspackages/riviere-cli/src/errors.tspackages/riviere-extract-config/extraction-config.schema.jsonpackages/riviere-extract-config/src/types.tspackages/riviere-extract-config/src/validation.spec.ts
🧰 Additional context used
📓 Path-based instructions (4)
packages/riviere-extract-config/**/*.ts
📄 CodeRabbit inference engine (packages/riviere-extract-config/CLAUDE.md)
Extraction config schema is the source of truth for valid structures. TypeScript types must mirror the schema definition to maintain consistency
Files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-config/src/types.ts
**/*.{js,mjs,ts,tsx,json}
📄 CodeRabbit inference engine (CLAUDE.md)
Always use nx commands for build, test, lint operations. Do not run npm/pnpm directly in project folders
Files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-config/src/types.tspackages/riviere-cli/src/errors.tspackages/riviere-cli/src/commands/extract/expand-module-refs.spec.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-cli/src/errors.spec.tspackages/riviere-cli/src/commands/extract/expand-module-refs.tspackages/riviere-cli/src/commands/extract/extract.spec.tspackages/riviere-extract-config/extraction-config.schema.json
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Use cross-project imports with package names (e.g.,import { X } from '@living-architecture/[pkg-name]'), not relative paths
When adding dependencies between projects, add"@living-architecture/[pkg-name]": "workspace:*"to the consuming project's package.json
Followdocs/conventions/software-design.mdwhen writing, editing, refactoring, or reviewing code
Look for and follow standard implementation patterns defined indocs/conventions/standard-patterns.md
Avoid anti-patterns documented in@docs/conventions/anti-patterns.md
Followdocs/conventions/testing.mdwhen writing tests. 100% test coverage is mandatory and enforced
Files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-config/src/types.tspackages/riviere-cli/src/errors.tspackages/riviere-cli/src/commands/extract/expand-module-refs.spec.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-cli/src/errors.spec.tspackages/riviere-cli/src/commands/extract/expand-module-refs.tspackages/riviere-cli/src/commands/extract/extract.spec.ts
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx,js,jsx}: Never commit secrets, API keys, or credentials. Use environment variables for sensitive configuration
Do not log sensitive data (passwords, tokens, PII). Validate and sanitize all external input
Files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-config/src/types.tspackages/riviere-cli/src/errors.tspackages/riviere-cli/src/commands/extract/expand-module-refs.spec.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-cli/src/errors.spec.tspackages/riviere-cli/src/commands/extract/expand-module-refs.tspackages/riviere-cli/src/commands/extract/extract.spec.ts
🧠 Learnings (39)
📓 Common learnings
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.{json,ts} : Define extraction configuration using the JSON Schema from `living-architecture/riviere-extract-config` DSL
📚 Learning: 2026-01-06T23:01:34.751Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Applies to packages/riviere-extract-config/**/*.ts : Extraction config schema is the source of truth for valid structures. TypeScript types must mirror the schema definition to maintain consistency
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-config/src/types.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-cli/src/commands/extract/expand-module-refs.tspackages/riviere-cli/src/commands/extract/extract.spec.tspackages/riviere-extract-config/extraction-config.schema.json
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement integration tests for end-to-end extraction from TypeScript code to JSON output
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-config/src/types.tspackages/riviere-cli/src/commands/extract/expand-module-refs.spec.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-cli/src/errors.spec.tspackages/riviere-cli/src/commands/extract/expand-module-refs.tspackages/riviere-cli/src/commands/extract/extract.spec.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Reject invalid extraction configs at load time, not during extraction phase
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-config/src/types.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-cli/src/commands/extract/expand-module-refs.tspackages/riviere-cli/src/commands/extract/extract.spec.tspackages/riviere-extract-config/extraction-config.schema.json
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement unit tests for each predicate type in isolation with positive and negative cases
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-cli/src/commands/extract/expand-module-refs.spec.tspackages/riviere-cli/src/errors.spec.tspackages/riviere-cli/src/commands/extract/extract.spec.ts
📚 Learning: 2026-01-11T14:38:35.637Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 129
File: packages/riviere-cli/src/commands/extract/config-loader.ts:31-39
Timestamp: 2026-01-11T14:38:35.637Z
Learning: In packages/riviere-cli/src/commands/extract/config-loader.ts, the isExtendedConfig type guard intentionally performs minimal validation (checks for non-null object and validates modules is an array if present) because comprehensive validation is handled downstream by the schema validator. The type guard's purpose is basic type narrowing to support both module-array and top-level-rules formats, not comprehensive validation. This follows the layered validation pattern where type guards are minimal and schema validation occurs at system boundaries.
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-config/src/types.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-cli/src/commands/extract/expand-module-refs.tspackages/riviere-extract-config/extraction-config.schema.json
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Use glob pattern matching for module-based organization of extraction rules
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-config/src/types.tspackages/riviere-cli/src/errors.tspackages/riviere-cli/src/commands/extract/expand-module-refs.spec.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-cli/src/commands/extract/expand-module-refs.tspackages/riviere-cli/src/commands/extract/extract.spec.tspackages/riviere-extract-config/extraction-config.schema.json
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Use ts-morph's in-memory file system (`useInMemoryFileSystem: true`) for fast isolated tests
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-cli/src/commands/extract/expand-module-refs.spec.tspackages/riviere-cli/src/errors.spec.tspackages/riviere-cli/src/commands/extract/extract.spec.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Implement extraction logic as pure functions with no side effects
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-config/src/types.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-cli/src/commands/extract/expand-module-refs.tspackages/riviere-cli/src/commands/extract/extract.spec.ts
📚 Learning: 2026-01-08T22:20:13.250Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.{json,ts} : Define extraction configuration using the JSON Schema from `living-architecture/riviere-extract-config` DSL
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-config/src/types.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-cli/src/commands/extract/expand-module-refs.tspackages/riviere-cli/src/commands/extract/extract.spec.tspackages/riviere-extract-config/extraction-config.schema.json
📚 Learning: 2026-01-13T11:37:59.334Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T11:37:59.334Z
Learning: Applies to vitest.config.ts : Add vitest.config.ts if tests are needed with 100% coverage as the default
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts
📚 Learning: 2026-01-11T22:42:36.650Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T22:42:36.650Z
Learning: Applies to docs/conventions/**/*.spec.{ts,tsx,js,jsx} : Systematically test edge cases for collections: empty collections, single element, duplicates, nested structures, circular references, large collections, sparse arrays, and mixed types.
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-cli/src/commands/extract/expand-module-refs.spec.tspackages/riviere-cli/src/errors.spec.tspackages/riviere-cli/src/commands/extract/extract.spec.ts
📚 Learning: 2026-01-06T23:01:34.751Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Extraction config schemas must define all six required component types per module: api, useCase, domainOp, event, eventHandler, and ui. Unused component types must be explicitly marked with `notUsed: true` rather than omitted
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-config/extraction-config.schema.json
📚 Learning: 2026-01-09T20:08:30.350Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 88
File: packages/riviere-cli/src/commands/extract/extract.spec.ts:33-38
Timestamp: 2026-01-09T20:08:30.350Z
Learning: In test files, keep type guard implementations like isExtractionOutput(value: unknown): value is ExtractionOutput focused on narrowing types for TypeScript. Do not perform comprehensive runtime shape validation in type guards; rely on explicit test assertions (e.g., expect(result).toMatchObject(...)) for shape checks. This keeps type guards simple and rely on assertion-based tests for thorough validation.
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-cli/src/commands/extract/expand-module-refs.spec.tspackages/riviere-cli/src/errors.spec.tspackages/riviere-cli/src/commands/extract/extract.spec.ts
📚 Learning: 2026-01-08T06:46:00.609Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 66
File: packages/riviere-extract-conventions/src/eslint/require-component-decorator.spec.ts:19-21
Timestamp: 2026-01-08T06:46:00.609Z
Learning: In test files using typescript-eslint/rule-tester's RuleTester.run(), ensure there is an explicit it() block with at least one expect() assertion (e.g., expect(rule).toBeDefined()) to satisfy sonarjs/no-empty-test-file and sonarjs/assertions-in-tests lint rules, which don’t recognize RuleTester's internal test blocks. Apply this pattern to all spec.ts test files to maintain consistency and pass lint checks.
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-cli/src/commands/extract/expand-module-refs.spec.tspackages/riviere-cli/src/errors.spec.tspackages/riviere-cli/src/commands/extract/extract.spec.ts
📚 Learning: 2026-01-11T22:42:36.650Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T22:42:36.650Z
Learning: Applies to docs/conventions/**/*-fixtures.ts : Create fixture files with pattern '<module>-fixtures.ts' alongside '<module>.spec.ts' to reduce test duplication. Use a buildArgs helper to define defaults and override specific values in tests.
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts
📚 Learning: 2026-01-10T08:54:09.466Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 96
File: apps/docs/.vitepress/theme/eclairLinkHandler.spec.ts:229-249
Timestamp: 2026-01-10T08:54:09.466Z
Learning: In jsdom test environments, window.location.assign cannot be spied on due to TypeError: Cannot redefine property. Use Object.defineProperty to mock the entire window.location object, replacing it with a controlled mock, and restore the original in afterEach. Ensure to clean up the mock after each test to avoid side effects.
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-cli/src/commands/extract/expand-module-refs.spec.tspackages/riviere-cli/src/errors.spec.tspackages/riviere-cli/src/commands/extract/extract.spec.ts
📚 Learning: 2026-01-11T18:47:09.232Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 129
File: apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts:13-19
Timestamp: 2026-01-11T18:47:09.232Z
Learning: In test files matching *.spec.ts or *.test.ts, avoid using try/catch blocks for testing error conditions. Prefer assertion library matchers like expect(...).toThrow() or expect(...).rejects.toThrow() to assert errors.
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-cli/src/commands/extract/expand-module-refs.spec.tspackages/riviere-cli/src/errors.spec.tspackages/riviere-cli/src/commands/extract/extract.spec.ts
📚 Learning: 2026-01-11T18:47:09.232Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 129
File: apps/eclair/src/components/SchemaModal/SchemaModal.cssModule.spec.ts:13-19
Timestamp: 2026-01-11T18:47:09.232Z
Learning: Encourage using const for declarations by default in TypeScript/JavaScript files and only use let when a variable must be reassigned. Do not rely on var. This improves immutability and clarity. If a variable needs mutation (e.g., counters in loops, reassigned values), use let, but prefer const whenever possible and refactor reassigned logic to avoid mutations where feasible.
Applied to files:
packages/riviere-extract-config/src/validation.spec.tspackages/riviere-extract-config/src/types.tspackages/riviere-cli/src/errors.tspackages/riviere-cli/src/commands/extract/expand-module-refs.spec.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-cli/src/errors.spec.tspackages/riviere-cli/src/commands/extract/expand-module-refs.tspackages/riviere-cli/src/commands/extract/extract.spec.ts
📚 Learning: 2026-01-08T07:05:01.766Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Applies to packages/riviere-extract-conventions/**/*.ts : Use `Custom(type)` decorator to annotate components with custom types not covered by standard decorators
Applied to files:
packages/riviere-extract-config/src/types.ts
📚 Learning: 2026-01-08T22:20:13.250Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use `living-architecture/riviere-extract-ts` TypeScript extractor with ts-morph for AST parsing when implementing TypeScript extraction for architecture schema components
Applied to files:
packages/riviere-extract-config/src/types.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-cli/src/commands/extract/expand-module-refs.tspackages/riviere-cli/src/commands/extract/extract.spec.tspackages/riviere-extract-config/extraction-config.schema.json
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Use ts-morph for TypeScript AST parsing instead of other parsers
Applied to files:
packages/riviere-extract-config/src/types.ts
📚 Learning: 2026-01-08T07:05:01.766Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-conventions/CLAUDE.md:0-0
Timestamp: 2026-01-08T07:05:01.766Z
Learning: Import and use the default extraction config from `living-architecture/riviere-extract-conventions/default-config` in extraction tooling to detect all 6 component types
Applied to files:
packages/riviere-extract-config/src/types.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-extract-config/extraction-config.schema.json
📚 Learning: 2026-01-08T12:57:19.167Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 67
File: packages/riviere-extract-ts/tsconfig.spec.json:5-22
Timestamp: 2026-01-08T12:57:19.167Z
Learning: In tsconfig.spec.json files, use expanded types array ["vitest/globals", "vitest/importMeta", "vite/client", "node", "vitest"] for complete test type coverage. Include patterns should cover .test and .spec files, config files (vitest.config.ts/mts, vite.config.ts/mts), multiple extensions (.ts, .tsx, .js, .jsx), and .d.ts files to ensure proper TypeScript coverage across the testing environment.
Applied to files:
packages/riviere-cli/src/commands/extract/expand-module-refs.spec.tspackages/riviere-cli/src/commands/extract/extract.spec.ts
📚 Learning: 2026-01-11T22:42:36.650Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T22:42:36.650Z
Learning: Applies to docs/conventions/**/*.spec.{ts,tsx,js,jsx} : Avoid implementation coupling in tests. Test behavior outcomes, not internal implementation details. For example, assert on result values rather than mock method call signatures.
Applied to files:
packages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts
📚 Learning: 2026-01-11T22:42:36.650Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T22:42:36.650Z
Learning: Applies to docs/conventions/**/*.spec.{ts,tsx,js,jsx} : Systematically test null and undefined cases: null input, undefined input, missing optional properties, and explicit undefined vs missing key distinction.
Applied to files:
packages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts
📚 Learning: 2026-01-11T22:42:12.408Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/anti-patterns.md:0-0
Timestamp: 2026-01-11T22:42:12.408Z
Learning: Applies to docs/conventions/**/packages/*/src/index.{ts,tsx} : Never export test fixtures from a package's public API for use by other packages. Each package should create its own local test fixtures to avoid fragile cross-package coupling.
Applied to files:
packages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts
📚 Learning: 2026-01-08T19:36:17.306Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/codebase-structure.md:0-0
Timestamp: 2026-01-08T19:36:17.306Z
Learning: Applies to docs/conventions/apps/*/src/**/*.test.ts : Test fixtures used across multiple test files may be grouped in shared locations (e.g., test-fixtures.ts), but otherwise test files should be co-located with the code they test.
Applied to files:
packages/riviere-cli/src/commands/extract/expand-module-refs.spec.tspackages/riviere-cli/src/commands/extract/extract.spec.ts
📚 Learning: 2026-01-11T22:42:36.650Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T22:42:36.650Z
Learning: Applies to docs/conventions/**/*.spec.{ts,tsx,js,jsx} : When testing errors, test both error type and message in a single test—they represent one error condition. For example: expect(() => loadConfig('nonexistent.json')).toThrow(ConfigurationError) and expect(() => loadConfig('nonexistent.json')).toThrow('Config file not found')
Applied to files:
packages/riviere-cli/src/commands/extract/expand-module-refs.spec.tspackages/riviere-cli/src/errors.spec.ts
📚 Learning: 2026-01-09T20:08:44.180Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 88
File: packages/riviere-cli/src/commands/extract/extract.ts:109-114
Timestamp: 2026-01-09T20:08:44.180Z
Learning: In packages/riviere-cli/src/commands/extract/**/*.{ts,tsx}, CLI extraction commands should only catch and format expected validation errors as structured JSON. Do not wrap or convert system-level exceptions (e.g., disk I/O failures, OOM, AST parse errors) into JSON errors; instead, fail loudly with stack traces to aid debugging. Follow fail-fast principles: validate inputs explicitly, and surface unexpected failures clearly.
Applied to files:
packages/riviere-cli/src/commands/extract/expand-module-refs.spec.tspackages/riviere-cli/src/commands/extract/extract.tspackages/riviere-cli/src/commands/extract/expand-module-refs.tspackages/riviere-cli/src/commands/extract/extract.spec.ts
📚 Learning: 2026-01-11T22:40:43.505Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 132
File: scripts/submit-pr.sh:76-82
Timestamp: 2026-01-11T22:40:43.505Z
Learning: Claude Code PreToolUse hooks (`.claude/hooks/block-dangerous-commands.sh`) intercept direct agent tool invocations but do not intercept commands that run inside scripts. When an agent executes a script like `./scripts/submit-pr.sh`, the hook checks the script execution command itself, not the individual commands (e.g., `git push`) that run within the script's subprocess.
Applied to files:
.claude/hooks/block-dangerous-commands.sh
📚 Learning: 2026-01-13T11:37:59.334Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-01-13T11:37:59.334Z
Learning: Always use scripts in `./scripts/` for git and GitHub operations (PRs, issues, tasks). Do not use `gh` or `git` commands directly unless no script exists
Applied to files:
.claude/hooks/block-dangerous-commands.sh
📚 Learning: 2026-01-06T18:13:55.588Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 58
File: scripts/reply-to-thread.sh:1-12
Timestamp: 2026-01-06T18:13:55.588Z
Learning: In shell scripts like reply-to-thread.sh, NTCoding prefers to keep code simple and not add explicit tool availability checks (e.g., for gh or jq) when the tools will fail immediately upon first use anyway, since such checks add code without changing behavior.
Applied to files:
.claude/hooks/block-dangerous-commands.sh
📚 Learning: 2026-01-07T08:54:48.071Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/workflow/code-review.md:0-0
Timestamp: 2026-01-07T08:54:48.071Z
Learning: Applies to docs/workflow/**/*.sh : In shell scripts (.sh files), use `jq` for JSON construction instead of manual string escaping to properly handle backslashes, newlines, and tabs.
Applied to files:
.claude/hooks/block-dangerous-commands.sh
📚 Learning: 2026-01-08T22:20:13.250Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use the Rivière Builder Node.js library to programmatically construct the schema graph when implementing custom extraction code
Applied to files:
packages/riviere-cli/src/commands/extract/extract.tspackages/riviere-cli/src/commands/extract/expand-module-refs.tspackages/riviere-cli/src/commands/extract/extract.spec.tspackages/riviere-extract-config/extraction-config.schema.json
📚 Learning: 2026-01-06T23:01:34.751Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: All validation of extraction config must occur at config load time, not during extraction. Invalid configs should fail fast with clear error messages that include paths and descriptive information
Applied to files:
packages/riviere-cli/src/commands/extract/extract.ts
📚 Learning: 2026-01-08T17:19:17.148Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: All extraction rules should come from validated ExtractionConfig provided by riviere-extract-config
Applied to files:
packages/riviere-cli/src/commands/extract/extract.ts
📚 Learning: 2026-01-09T20:08:44.180Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 88
File: packages/riviere-cli/src/commands/extract/extract.ts:109-114
Timestamp: 2026-01-09T20:08:44.180Z
Learning: Applies to packages/riviere-cli/src/commands/extract/**/*.{ts,tsx} : CLI extraction commands should only catch and format expected validation errors as structured JSON. System-level exceptions (disk I/O failures, OOM, AST parse errors) should fail loudly with stack traces for debugging rather than being wrapped in try-catch and converted to JSON errors. This follows the fail-fast principle: validate inputs explicitly, then let unexpected failures surface clearly.
Applied to files:
packages/riviere-cli/src/errors.spec.ts
📚 Learning: 2026-01-11T22:42:36.650Z
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/conventions/testing.md:0-0
Timestamp: 2026-01-11T22:42:36.650Z
Learning: Applies to docs/conventions/**/*.spec.{ts,tsx,js,jsx} : Use Arrange-Act-Assert structure in tests: Set up test data, execute behavior, then verify outcomes.
Applied to files:
packages/riviere-cli/src/commands/extract/extract.spec.ts
🧬 Code graph analysis (3)
packages/riviere-extract-config/src/validation.spec.ts (3)
packages/riviere-extract-config/src/index.ts (1)
isValidExtractionConfig(3-3)packages/riviere-extract-config/src/validation.ts (1)
isValidExtractionConfig(16-18)packages/riviere-extract-config/src/validation-fixtures.ts (1)
createMinimalModule(29-40)
packages/riviere-cli/src/errors.spec.ts (1)
packages/riviere-cli/src/errors.ts (1)
ModuleRefNotFoundError(118-128)
packages/riviere-cli/src/commands/extract/expand-module-refs.ts (2)
packages/riviere-extract-config/src/types.ts (1)
ModuleRef(75-75)packages/riviere-cli/src/errors.ts (1)
ModuleRefNotFoundError(118-128)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: main
🔇 Additional comments (20)
.claude/hooks/block-dangerous-commands.sh (1)
29-39: Implementation is correct and follows existing patterns.The regex pattern correctly matches
gh pr createcommands and the denial message provides a clear alternative. The structure mirrors the existinggit pushblock appropriately.One observation: this change appears unrelated to the PR's stated objective of adding
$reffile reference support for extraction configs. Consider whether this workflow enforcement belongs in a separate PR to keep changes focused and easier to review/revert independently.Based on learnings, this aligns with the repository guideline to use scripts in
./scripts/for git and GitHub operations rather than direct commands.packages/riviere-cli/src/errors.ts (1)
118-128: LGTM!The
ModuleRefNotFoundErrorclass follows the established error patterns in this file. The implementation is clean with:
- Clear, actionable error message
- Readonly properties for immutability
- Proper
nameassignment for error identificationpackages/riviere-cli/src/commands/extract/expand-module-refs.spec.ts (5)
12-19: Good mock lifecycle management.The
beforeEach/afterEachsetup correctly resets and restores mocks between tests, preventing test pollution.
21-43: Solid edge case coverage.These tests verify that
expandModuleRefsgracefully handles invalid or unexpected inputs by returning them unchanged, which is important for robustness.
129-140: LGTM!The error test correctly verifies both the error type and message, following the testing convention to test both in a single test case.
1-8: Missing import forcreateMinimalModulefixture.The test at line 27 uses
createMinimalModule()but this function is not imported. Based on the coding guidelines about cross-project imports, you should either:
- Import from the package if it's a public export:
+import { createMinimalModule } from '@living-architecture/riviere-extract-config/validation-fixtures'
- Or define a local fixture inline (as done in lines 66-75).
Option 2 is preferred per learnings: "Never export test fixtures from a package's public API for use by other packages."
Proposed fix
it('returns true when mixing $ref and inline modules', () => { - const config = {modules: [{ $ref: './domains/orders.extraction.json' }, createMinimalModule()],} + const inlineModule = { + name: 'test', + path: 'src/**', + api: { notUsed: true }, + useCase: { notUsed: true }, + domainOp: { notUsed: true }, + event: { notUsed: true }, + eventHandler: { notUsed: true }, + ui: { notUsed: true }, + } + const config = { modules: [{ $ref: './domains/orders.extraction.json' }, inlineModule] } expect(isValidExtractionConfig(config)).toBe(true) })Note: This issue is in
validation.spec.tsat line 27, not this file. Apologies for the confusion - I'll address the actual file review below.
85-126: YAML file expansion is already supported through theparseYamlfunction.The implementation uses the YAML parser for both JSON and YAML files since JSON is valid YAML syntax. The current test for JSON file expansion (lines 85–126) implicitly covers YAML support. Adding an explicit YAML test would improve test clarity and documentation, but is not required for functional correctness.
⛔ Skipped due to learnings
Learnt from: NTCoding Repo: NTCoding/living-architecture PR: 67 File: packages/riviere-extract-ts/tsconfig.spec.json:5-22 Timestamp: 2026-01-08T12:57:19.167Z Learning: In tsconfig.spec.json files, use expanded types array ["vitest/globals", "vitest/importMeta", "vite/client", "node", "vitest"] for complete test type coverage. Include patterns should cover .test and .spec files, config files (vitest.config.ts/mts, vite.config.ts/mts), multiple extensions (.ts, .tsx, .js, .jsx), and .d.ts files to ensure proper TypeScript coverage across the testing environment.Learnt from: CR Repo: NTCoding/living-architecture PR: 0 File: packages/riviere-extract-ts/CLAUDE.md:0-0 Timestamp: 2026-01-08T17:19:17.148Z Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement integration tests for end-to-end extraction from TypeScript code to JSON outputLearnt from: CR Repo: NTCoding/living-architecture PR: 0 File: packages/riviere-extract-ts/CLAUDE.md:0-0 Timestamp: 2026-01-08T17:19:17.148Z Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Use ts-morph's in-memory file system (`useInMemoryFileSystem: true`) for fast isolated testspackages/riviere-extract-config/extraction-config.schema.json (2)
18-23: LGTM! Schema correctly updated to support module references.The
oneOfconstruct properly allows modules array items to be either inline module definitions or external file references.
27-39: moduleRef definition is well-constrained.The definition correctly enforces:
- Required
$refproperty- No additional properties (strict shape)
- Non-empty string for the file path
This aligns with the
ModuleRefTypeScript interface.packages/riviere-extract-config/src/validation.spec.ts (1)
21-29: Good test coverage for $ref validation.The tests correctly verify that
isValidExtractionConfigaccepts both standalone$refmodules and mixed configurations. The test structure is consistent with existing patterns.Consider adding negative test cases to the
'returns false when data is %s'parameterized test to verify schema rejects invalid$refvalues:
{ modules: [{ $ref: '' }] }(empty string){ modules: [{ $ref: 123 }] }(non-string){ modules: [{ $ref: './file.json', extra: 'prop' }] }(additional properties)⛔ Skipped due to learnings
Learnt from: NTCoding Repo: NTCoding/living-architecture PR: 88 File: packages/riviere-cli/src/commands/extract/extract.spec.ts:33-38 Timestamp: 2026-01-09T20:08:30.350Z Learning: In test files (*.spec.ts, *.test.ts), type guards like `isExtractionOutput(value: unknown): value is ExtractionOutput` should focus on narrowing types for TypeScript rather than comprehensive validation. Actual shape validation is handled through explicit test assertions (e.g., `expect(result).toMatchObject(...)`). This keeps type guards simple while maintaining thorough validation through assertion-based testing.Learnt from: NTCoding Repo: NTCoding/living-architecture PR: 129 File: packages/riviere-cli/src/commands/extract/config-loader.ts:31-39 Timestamp: 2026-01-11T14:38:35.637Z Learning: In packages/riviere-cli/src/commands/extract/config-loader.ts, the isExtendedConfig type guard intentionally performs minimal validation (checks for non-null object and validates modules is an array if present) because comprehensive validation is handled downstream by the schema validator. The type guard's purpose is basic type narrowing to support both module-array and top-level-rules formats, not comprehensive validation. This follows the layered validation pattern where type guards are minimal and schema validation occurs at system boundaries.Learnt from: CR Repo: NTCoding/living-architecture PR: 0 File: packages/riviere-extract-ts/CLAUDE.md:0-0 Timestamp: 2026-01-08T17:19:17.148Z Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement unit tests for each predicate type in isolation with positive and negative casesLearnt from: CR Repo: NTCoding/living-architecture PR: 0 File: docs/conventions/testing.md:0-0 Timestamp: 2026-01-11T22:42:36.650Z Learning: Applies to docs/conventions/**/*.spec.{ts,tsx,js,jsx} : Systematically test edge cases for collections: empty collections, single element, duplicates, nested structures, circular references, large collections, sparse arrays, and mixed types.Learnt from: CR Repo: NTCoding/living-architecture PR: 0 File: packages/riviere-extract-ts/CLAUDE.md:0-0 Timestamp: 2026-01-08T17:19:17.148Z Learning: Applies to packages/riviere-extract-ts/**/*.test.{ts,tsx} : Implement integration tests for end-to-end extraction from TypeScript code to JSON outputLearnt from: CR Repo: NTCoding/living-architecture PR: 0 File: packages/riviere-extract-ts/CLAUDE.md:0-0 Timestamp: 2026-01-08T17:19:17.148Z Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Reject invalid extraction configs at load time, not during extraction phaseLearnt from: NTCoding Repo: NTCoding/living-architecture PR: 67 File: packages/riviere-extract-ts/tsconfig.spec.json:5-22 Timestamp: 2026-01-08T12:57:19.167Z Learning: In tsconfig.spec.json files, use expanded types array ["vitest/globals", "vitest/importMeta", "vite/client", "node", "vitest"] for complete test type coverage. Include patterns should cover .test and .spec files, config files (vitest.config.ts/mts, vite.config.ts/mts), multiple extensions (.ts, .tsx, .js, .jsx), and .d.ts files to ensure proper TypeScript coverage across the testing environment.Learnt from: CR Repo: NTCoding/living-architecture PR: 0 File: docs/conventions/testing.md:0-0 Timestamp: 2026-01-11T22:42:36.650Z Learning: Applies to docs/conventions/**/*.spec.{ts,tsx,js,jsx} : Systematically test null and undefined cases: null input, undefined input, missing optional properties, and explicit undefined vs missing key distinction.Learnt from: CR Repo: NTCoding/living-architecture PR: 0 File: packages/riviere-extract-config/CLAUDE.md:0-0 Timestamp: 2026-01-06T23:01:34.751Z Learning: Applies to packages/riviere-extract-config/**/*.ts : Extraction config schema is the source of truth for valid structures. TypeScript types must mirror the schema definition to maintain consistencyLearnt from: CR Repo: NTCoding/living-architecture PR: 0 File: docs/workflow/code-review.md:0-0 Timestamp: 2026-01-07T08:54:48.071Z Learning: Applies to docs/workflow/**/*.{ts,tsx,js,jsx} : Review usage of `/* v8 ignore next -- preserve */` coverage skip directives. This is only acceptable for unreachable code needed to satisfy the compiler. Most cases should be solved by extracting code or writing tests to mock behavior.Learnt from: NTCoding Repo: NTCoding/living-architecture PR: 66 File: packages/riviere-extract-conventions/src/eslint/require-component-decorator.spec.ts:19-21 Timestamp: 2026-01-08T06:46:05.503Z Learning: In test files using typescript-eslint/rule-tester's RuleTester.run(), include an explicit it() block with an expect() assertion (e.g., expect(rule).toBeDefined()) to satisfy sonarjs/no-empty-test-file and sonarjs/assertions-in-tests lint rules, which don't recognize RuleTester's internal test blocks.Learnt from: CR Repo: NTCoding/living-architecture PR: 0 File: docs/conventions/testing.md:0-0 Timestamp: 2026-01-11T22:42:36.650Z Learning: Applies to docs/conventions/**/*.spec.{ts,tsx,js,jsx} : When testing errors, test both error type and message in a single test—they represent one error condition. For example: expect(() => loadConfig('nonexistent.json')).toThrow(ConfigurationError) and expect(() => loadConfig('nonexistent.json')).toThrow('Config file not found')packages/riviere-cli/src/commands/extract/expand-module-refs.ts (4)
1-6: LGTM!Imports are appropriate—using
node:fsandnode:pathfor file operations,yamlfor parsing, and the custom error class for missing references.
10-18: LGTM!Type guard correctly narrows to
ModuleRefwith appropriate null/type checks before property access.
20-28: LGTM!Type guard correctly identifies configs with a
modulesarray property using minimal validation as expected per the layered validation pattern.
36-59: LGTM!Implementation correctly:
- Short-circuits for configs without modules array
- Resolves file paths relative to
configDiras required- Throws descriptive error for missing referenced files
- Preserves non-ref modules unchanged
- Returns a new object without mutating input
packages/riviere-cli/src/errors.spec.ts (2)
16-16: LGTM!Import addition follows the existing pattern for error imports.
209-231: LGTM!Test suite comprehensively covers the
ModuleRefNotFoundErrorclass with tests for message formatting, name property, and exposedref/filePathproperties. Structure matches established patterns in this file.packages/riviere-cli/src/commands/extract/extract.ts (2)
26-26: LGTM!Import follows cross-project import conventions using relative path within the same package.
121-136: LGTM!Correctly wires the expanded config data through validation and resolution. The flow ensures
$refentries are resolved before schema validation, which aligns with the PR objective of validating referenced files against the existing schema.packages/riviere-cli/src/commands/extract/extract.spec.ts (2)
137-140: LGTM!Test suite setup follows the established pattern with
createTestContextandsetupCommandTest.
141-196: LGTM!Comprehensive integration test that verifies the complete
$refexpansion flow:
- Sets up realistic file structure with source code and referenced module config
- Uses
$refin main config pointing to external module definition- Validates that extraction succeeds and produces expected component output
This effectively proves that
$refreferences are expanded before schema validation (since raw$refobjects would fail validation).
Extracted module ref expansion error handling into separate tryExpandModuleRefs function. Simplified type predicates for better readability. Added test coverage for missing module file scenario. Co-Authored-By: Claude Opus 4.5 <[email protected]>
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In @.claude/commands/complete-task.md:
- Around line 164-171: Update Step 5 to add explicit failure handling for the
./scripts/submit-pr.sh invocation: document the expected FAIL output block when
submit-pr.sh exits non‑zero (capture and paste raw output, show "SUBMIT PR
FAILED", include troubleshooting steps like verify branch pushed, network/auth
checks, and instruct whether to retry or run /complete-task), clarify PR
title/body guidance by telling agents to synthesize the title from changed files
and commit types (use conventional commit format via the diff and PR objectives)
and to generate the body from PR objectives plus a short summary of key changed
files and rationale, and reconcile the workflow diagram by making the "submit-pr
subagent → captures output" line consistent with the "Run directly" instruction
so both reference the same behavior for ./scripts/submit-pr.sh.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (1)
.claude/commands/complete-task.md
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 156
File: packages/riviere-extract-config/src/types.ts:71-75
Timestamp: 2026-01-14T00:09:27.486Z
Learning: In packages/riviere-extract-config/src/types.ts, the ExtractionConfig interface represents the post-expansion state where all $ref module references have been resolved to ModuleConfig entries. The extraction-config.schema.json allows both ModuleConfig and ModuleRef in the modules array because it validates raw input before expandModuleRefs runs, but after expansion, modules are always ModuleConfig[], so the TypeScript type correctly models this expanded state.
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.{json,ts} : Define extraction configuration using the JSON Schema from `living-architecture/riviere-extract-config` DSL
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: docs/architecture/overview.md:0-0
Timestamp: 2026-01-08T22:20:13.250Z
Learning: Applies to docs/architecture/**/*extract*.ts : Use `living-architecture/riviere-extract-ts` TypeScript extractor with ts-morph for AST parsing when implementing TypeScript extraction for architecture schema components
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Applies to packages/riviere-extract-config/**/*.ts : Extraction config schema is the source of truth for valid structures. TypeScript types must mirror the schema definition to maintain consistency
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Reject invalid extraction configs at load time, not during extraction phase
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-config/CLAUDE.md:0-0
Timestamp: 2026-01-06T23:01:34.751Z
Learning: Extraction config schemas must define all six required component types per module: api, useCase, domainOp, event, eventHandler, and ui. Unused component types must be explicitly marked with `notUsed: true` rather than omitted
Learnt from: CR
Repo: NTCoding/living-architecture PR: 0
File: packages/riviere-extract-ts/CLAUDE.md:0-0
Timestamp: 2026-01-08T17:19:17.148Z
Learning: Applies to packages/riviere-extract-ts/**/*.{ts,tsx} : Use glob pattern matching for module-based organization of extraction rules
📚 Learning: 2026-01-09T18:10:15.724Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 85
File: .claude/commands/post-merge-completion.md:35-39
Timestamp: 2026-01-09T18:10:15.724Z
Learning: In .claude/commands/post-merge-completion.md, the review files in `reviews/<branch>/` (code-review.md, bug-scanner.md, task-check.md, doc-suggestions.md) are optional inputs to the reflection process. The post-merge-completion command should work gracefully even if these files are missing or if /complete-task wasn't run before merging.
Applied to files:
.claude/commands/complete-task.md
📚 Learning: 2026-01-11T22:40:43.505Z
Learnt from: NTCoding
Repo: NTCoding/living-architecture PR: 132
File: scripts/submit-pr.sh:76-82
Timestamp: 2026-01-11T22:40:43.505Z
Learning: Claude Code PreToolUse hooks (`.claude/hooks/block-dangerous-commands.sh`) intercept direct agent tool invocations but do not intercept commands that run inside scripts. When an agent executes a script like `./scripts/submit-pr.sh`, the hook checks the script execution command itself, not the individual commands (e.g., `git push`) that run within the script's subprocess.
Applied to files:
.claude/commands/complete-task.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: main
- GitHub Check: Cloudflare Pages
✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.
| Run directly (10-minute timeout): | ||
|
|
||
| - FAIL → return: | ||
| ```text | ||
| SUBMIT PR FAILED | ||
| <raw-output> | ||
| [paste the COMPLETE raw output here - do not summarize] | ||
| </raw-output> | ||
| NEXT STEPS: Address the issues and re-run /complete-task | ||
| LOOP CONTROL: If this is your third successive attempt, ask the user for help. | ||
| ``` | ||
| ```bash | ||
| ./scripts/submit-pr.sh --title "<type>(scope): description" --body "<summary>" | ||
| ``` | ||
|
|
||
| Title: Use conventional commit format based on the changes. | ||
| Body: Brief summary of what changed and why. |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# First, check if the file exists and examine its structure
find . -name "complete-task.md" -type f 2>/dev/null | head -5Repository: NTCoding/living-architecture
Length of output: 107
🏁 Script executed:
# Check the repository structure to understand context
git ls-files | grep -E "(claude|script)" | head -20Repository: NTCoding/living-architecture
Length of output: 1032
🏁 Script executed:
# Once we know the file exists, get total line count and examine the target area
if [[ -f .claude/commands/complete-task.md ]]; then
wc -l .claude/commands/complete-task.md
fiRepository: NTCoding/living-architecture
Length of output: 109
🏁 Script executed:
# Examine the target lines (164-171) and the workflow diagram area (around line 30)
cat -n .claude/commands/complete-task.md | sed -n '25,35p'Repository: NTCoding/living-architecture
Length of output: 449
🏁 Script executed:
# Read the Step 5 section (lines 164-171)
cat -n .claude/commands/complete-task.md | sed -n '160,175p'Repository: NTCoding/living-architecture
Length of output: 608
🏁 Script executed:
# Also check Step 1 to understand the error handling pattern referenced in the review
cat -n .claude/commands/complete-task.md | sed -n '1,100p' | grep -A 30 "Step 1"Repository: NTCoding/living-architecture
Length of output: 54
🏁 Script executed:
# Check if submit-pr.sh exists and examine its interface
if [[ -f ./scripts/submit-pr.sh ]]; then
echo "=== Script found ==="
head -30 ./scripts/submit-pr.sh
echo -e "\n=== Error patterns ==="
grep -n "exit\|return\|ERROR\|FAIL" ./scripts/submit-pr.sh | head -20
else
echo "submit-pr.sh not found at ./scripts/submit-pr.sh"
find . -name "submit-pr.sh" 2>/dev/null
fiRepository: NTCoding/living-architecture
Length of output: 973
🏁 Script executed:
# Look for Step 1 to understand the error handling pattern
cat -n .claude/commands/complete-task.md | sed -n '50,130p'Repository: NTCoding/living-architecture
Length of output: 2907
🏁 Script executed:
# Get more of submit-pr.sh to understand its error handling better
cat -n ./scripts/submit-pr.sh | sed -n '1,60p'Repository: NTCoding/living-architecture
Length of output: 1865
🏁 Script executed:
# Look at the full Step 5 section and beyond to see if error handling is documented elsewhere
cat -n .claude/commands/complete-task.md | sed -n '162,190p'Repository: NTCoding/living-architecture
Length of output: 1243
Add error handling and clarify PR content guidance.
Step 5 has several issues:
-
Missing failure handling (major): Unlike Step 1 (verify gate), there's no documented error path if
submit-pr.shfails. The script usesset -euo pipefailand exits on errors, but the documentation doesn't tell agents whether to retry, fix, or report when script execution fails due to network issues, authentication failures, or validation errors. -
Insufficient guidance on PR content (minor): The placeholders
<type>(scope): descriptionand<summary>lack clear sourcing instructions. The guidance "based on the changes" and "what changed and why" is ambiguous—should the agent synthesize from diffs, use the issue description, reference PR objectives, or generate a new summary? -
Workflow diagram inconsistency (minor): Line 30 states "submit-pr subagent → captures output", but line 164 instructs "Run directly". These conflict and should be aligned.
📝 Suggested improvements
Add a failure handling block similar to Step 1:
Run directly (10-minute timeout):
```bash
./scripts/submit-pr.sh --title "<type>(scope): description" --body "<summary>"+- FAIL → return:
-
- SUBMIT PR FAILED
- [paste the COMPLETE error output here - do not summarize]
- NEXT STEPS: Verify branch is pushed, check network/auth, and retry /complete-task
-
Title: Use conventional commit format based on the changes.
-Body: Brief summary of what changed and why.
+Body: Synthesize a brief summary from the PR objectives and changed files, explaining what changed and why.
Update line 30 in the workflow diagram:
```diff
- ├── submit-pr subagent → captures output
+ ├── submit-pr script → run directly with timeout
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| Run directly (10-minute timeout): | |
| - FAIL → return: | |
| ```text | |
| SUBMIT PR FAILED | |
| <raw-output> | |
| [paste the COMPLETE raw output here - do not summarize] | |
| </raw-output> | |
| NEXT STEPS: Address the issues and re-run /complete-task | |
| LOOP CONTROL: If this is your third successive attempt, ask the user for help. | |
| ``` | |
| ```bash | |
| ./scripts/submit-pr.sh --title "<type>(scope): description" --body "<summary>" | |
| ``` | |
| Title: Use conventional commit format based on the changes. | |
| Body: Brief summary of what changed and why. | |
| Run directly (10-minute timeout): | |
🤖 Prompt for AI Agents
In @.claude/commands/complete-task.md around lines 164 - 171, Update Step 5 to
add explicit failure handling for the ./scripts/submit-pr.sh invocation:
document the expected FAIL output block when submit-pr.sh exits non‑zero
(capture and paste raw output, show "SUBMIT PR FAILED", include troubleshooting
steps like verify branch pushed, network/auth checks, and instruct whether to
retry or run /complete-task), clarify PR title/body guidance by telling agents
to synthesize the title from changed files and commit types (use conventional
commit format via the diff and PR objectives) and to generate the body from PR
objectives plus a short summary of key changed files and rationale, and
reconcile the workflow diagram by making the "submit-pr subagent → captures
output" line consistent with the "Run directly" instruction so both reference
the same behavior for ./scripts/submit-pr.sh.



User description
Closes #141
Adds support for $ref file references in extraction config, allowing users to split large configs into one file per domain.
Changes
Example Usage
Closes #141
PR Type
Enhancement
Description
Add support for $ref file references in extraction configs
Enable splitting large configs across multiple domain files
Implement expandModuleRefs function for reference resolution
Add ModuleRefNotFoundError for clear error messaging
Update JSON schema to support moduleRef in modules array
Integrate reference expansion into extract command workflow
Diagram Walkthrough
File Walkthrough
3 files
New function to expand $ref referencesIntegrate expandModuleRefs into extract workflowAdd ModuleRef interface type definition4 files
Comprehensive tests for reference expansionAdd integration test for $ref expansionAdd tests for ModuleRefNotFoundErrorAdd validation tests for $ref modules1 files
Add ModuleRefNotFoundError exception class2 files
Update schema to allow moduleRef in modulesBlock direct gh pr create command1 files
Document moduleRef schema in generated docsSummary by CodeRabbit
New Features
Bug Fixes / Errors
Tests
Chores
✏️ Tip: You can customize this high-level summary in your review settings.