@@ -53,6 +53,7 @@ import { loadCodeDecaySkills } from "@submuxhq/codedecay-skills";
5353import { createTestProofAudit } from "@submuxhq/codedecay-test-audit" ;
5454import { createConfiguredToolHarnesses } from "@submuxhq/codedecay-tool-adapters" ;
5555import YAML from "yaml" ;
56+ import { runConfigCommand } from "./commands/config" ;
5657import { runUninstallCommand , runUpdateCommand , runVersionCommand } from "./commands/maintenance" ;
5758import {
5859 runMemoryCommand as runMemoryCommandWithDependencies ,
@@ -67,7 +68,6 @@ import {
6768 HelpRequested ,
6869 parseAgentArgs ,
6970 parseAnalyzeArgs ,
70- parseConfigArgs ,
7171 parseDashboardArgs ,
7272 parseDifferentialArgs ,
7373 parseExecuteArgs ,
@@ -85,7 +85,6 @@ import type {
8585 CliCommandHandler ,
8686 CliRuntime ,
8787 ConfigFormat ,
88- ConfigOptions ,
8988 DashboardOptions ,
9089 DifferentialOptions ,
9190 DifferentialProbeResult ,
@@ -258,13 +257,6 @@ async function run(args: string[], runtime: CliRuntime): Promise<void | number>
258257 } ) ;
259258}
260259
261- function runConfigCommand ( context : CliCommandContext ) : void {
262- const options = parseConfigArgs ( context . args ) ;
263- const cwd = resolve ( context . runtimeCwd , options . cwd ?? "." ) ;
264- const loadedConfig = loadCodeDecayConfig ( { cwd } ) ;
265- write ( context . runtime . stdout , renderConfig ( loadedConfig , options . format ) ) ;
266- }
267-
268260async function runMcpCommand ( context : CliCommandContext ) : Promise < void > {
269261 const options = parseMcpArgs ( context . args ) ;
270262 const cwd = resolve ( context . runtimeCwd , options . cwd ?? "." ) ;
@@ -1134,14 +1126,6 @@ function writeCliOutput(input: {
11341126 write ( input . runtime . stdout , input . rendered ) ;
11351127}
11361128
1137- function renderConfig ( loadedConfig : LoadedCodeDecayConfig , format : ConfigFormat ) : string {
1138- if ( format === "markdown" ) {
1139- return renderConfigMarkdown ( loadedConfig ) ;
1140- }
1141-
1142- return `${ JSON . stringify ( loadedConfig , null , 2 ) } \n` ;
1143- }
1144-
11451129function renderLlmReviewReport ( report : LlmReviewReport , format : ConfigFormat ) : string {
11461130 if ( format === "json" ) {
11471131 return `${ JSON . stringify ( report , null , 2 ) } \n` ;
@@ -5386,150 +5370,6 @@ function formatDifferentialStatus(status: DifferentialStatus): string {
53865370 return `${ status . charAt ( 0 ) . toUpperCase ( ) } ${ status . slice ( 1 ) } ` ;
53875371}
53885372
5389- function renderConfigMarkdown ( loadedConfig : LoadedCodeDecayConfig ) : string {
5390- const { config, sourcePath } = loadedConfig ;
5391- const lines = [
5392- "## CodeDecay Config" ,
5393- "" ,
5394- `**Source:** ${ sourcePath ? `\`${ sourcePath } \`` : "defaults (no config file found)" } ` ,
5395- "" ,
5396- "### Safety" ,
5397- "" ,
5398- "| Setting | Value |" ,
5399- "| --- | ---: |" ,
5400- `| Command timeout | ${ config . safety . commandTimeoutMs } ms |` ,
5401- `| Allow configured commands | ${ config . safety . allowCommands ? "yes" : "no" } |` ,
5402- "" ,
5403- "### Commands" ,
5404- "" ,
5405- "| Type | Commands |" ,
5406- "| --- | --- |" ,
5407- `| Test | ${ formatCommandList ( config . commands . test ) } |` ,
5408- `| Build | ${ formatCommandList ( config . commands . build ) } |` ,
5409- `| Start | ${ formatCommandList ( config . commands . start ) } |` ,
5410- "" ,
5411- "### LLM" ,
5412- "" ,
5413- "| Setting | Value |" ,
5414- "| --- | --- |" ,
5415- `| Provider | ${ config . llm . provider } |` ,
5416- `| Model | ${ config . llm . model ? `\`${ config . llm . model } \`` : "none" } |` ,
5417- `| Endpoint | ${ config . llm . endpoint ? `\`${ config . llm . endpoint } \`` : "none" } |` ,
5418- `| API key env | ${ config . llm . apiKeyEnv ? `\`${ config . llm . apiKeyEnv } \`` : "none" } |` ,
5419- `| Timeout | ${ config . llm . timeoutMs } ms |` ,
5420- "" ,
5421- "### Tool Adapters" ,
5422- ""
5423- ] ;
5424-
5425- appendConfigToolAdapters ( lines , config . toolAdapters ) ;
5426-
5427- lines . push ( "### Product Testing Targets" , "" ) ;
5428- appendConfigProductTargets ( lines , config . productTesting . targets ) ;
5429-
5430- lines . push (
5431- "### Probes" ,
5432- ""
5433- ) ;
5434-
5435- if ( config . probes . length === 0 ) {
5436- lines . push ( "No probes configured." , "" ) ;
5437- return `${ lines . join ( "\n" ) } \n` ;
5438- }
5439-
5440- lines . push ( "| Name | Command | Timeout |" , "| --- | --- | ---: |" ) ;
5441- for ( const probe of config . probes ) {
5442- lines . push (
5443- `| ${ probe . name } | \`${ probe . command } \` | ${ probe . timeoutMs ? `${ probe . timeoutMs } ms` : "default" } |`
5444- ) ;
5445- }
5446- lines . push ( "" ) ;
5447-
5448- return `${ lines . join ( "\n" ) } \n` ;
5449- }
5450-
5451- function appendConfigToolAdapters (
5452- lines : string [ ] ,
5453- toolAdapters : LoadedCodeDecayConfig [ "config" ] [ "toolAdapters" ]
5454- ) : void {
5455- const rows = [
5456- formatConfigToolAdapter ( "Agent Process" , toolAdapters . agentProcess ) ,
5457- formatConfigToolAdapter ( "Playwright" , toolAdapters . playwright ) ,
5458- formatConfigToolAdapter ( "StrykerJS" , toolAdapters . stryker ) ,
5459- formatConfigToolAdapter ( "Schemathesis" , toolAdapters . schemathesis ) ,
5460- formatConfigToolAdapter ( "Pact" , toolAdapters . pact ) ,
5461- formatConfigToolAdapter ( "Semgrep" , toolAdapters . semgrep ) ,
5462- formatConfigToolAdapter ( "Coverage" , toolAdapters . coverage )
5463- ] . filter ( ( row ) : row is string => row !== undefined ) ;
5464-
5465- if ( rows . length === 0 ) {
5466- lines . push ( "No tool adapters configured." , "" ) ;
5467- return ;
5468- }
5469-
5470- lines . push ( "| Adapter | Enabled | Command/details | Timeout |" , "| --- | --- | --- | ---: |" , ...rows , "" ) ;
5471- }
5472-
5473- function formatConfigToolAdapter (
5474- name : string ,
5475- adapter : LoadedCodeDecayConfig [ "config" ] [ "toolAdapters" ] [ keyof LoadedCodeDecayConfig [ "config" ] [ "toolAdapters" ] ]
5476- ) : string | undefined {
5477- if ( ! adapter ) {
5478- return undefined ;
5479- }
5480-
5481- const details = [
5482- adapter . command ? `command: \`${ adapter . command } \`` : "command: default" ,
5483- "reportPath" in adapter && adapter . reportPath ? `reportPath: \`${ adapter . reportPath } \`` : undefined ,
5484- "schema" in adapter && adapter . schema ? `schema: \`${ adapter . schema } \`` : undefined ,
5485- "baseUrl" in adapter && adapter . baseUrl ? `baseUrl: \`${ adapter . baseUrl } \`` : undefined ,
5486- "config" in adapter && adapter . config ? `config: \`${ adapter . config } \`` : undefined ,
5487- "failOnSeverity" in adapter && adapter . failOnSeverity ? `failOnSeverity: ${ adapter . failOnSeverity } ` : undefined ,
5488- "profile" in adapter && adapter . profile ? `profile: ${ adapter . profile } ` : undefined ,
5489- "bundleFormat" in adapter && adapter . bundleFormat ? `bundleFormat: ${ adapter . bundleFormat } ` : undefined ,
5490- "reportPaths" in adapter && adapter . reportPaths ? `reportPaths: \`${ adapter . reportPaths . join ( ", " ) } \`` : undefined ,
5491- "failOn" in adapter && adapter . failOn ? `failOn: ${ adapter . failOn } ` : undefined
5492- ]
5493- . filter ( ( item ) : item is string => item !== undefined )
5494- . join ( "<br>" ) ;
5495-
5496- return `| ${ name } | ${ adapter . enabled ? "yes" : "no" } | ${ details } | ${ adapter . timeoutMs ? `${ adapter . timeoutMs } ms` : "default" } |` ;
5497- }
5498-
5499- function appendConfigProductTargets (
5500- lines : string [ ] ,
5501- targets : LoadedCodeDecayConfig [ "config" ] [ "productTesting" ] [ "targets" ]
5502- ) : void {
5503- const entries = Object . values ( targets ) ;
5504- if ( entries . length === 0 ) {
5505- lines . push ( "No product testing targets configured." , "" ) ;
5506- return ;
5507- }
5508-
5509- lines . push (
5510- "| Target | Readiness | Effective URL | Commands | Health check | API endpoints | Timeout |" ,
5511- "| --- | --- | --- | --- | --- | ---: | ---: |"
5512- ) ;
5513- for ( const target of entries ) {
5514- const effectiveUrl = target . readiness . effectiveBaseUrl ? `\`${ target . readiness . effectiveBaseUrl } \`` : "none" ;
5515- const commands = target . readiness . commandsRequired . length > 0
5516- ? target . readiness . commandsRequired . map ( ( command ) => `\`${ command } \`` ) . join ( "<br>" )
5517- : "none" ;
5518- lines . push (
5519- `| ${ target . id } | ${ target . readiness . status } (${ target . readiness . mode } ) | ${ effectiveUrl } | ${ commands } | ${ target . healthCheck ? `\`${ target . healthCheck } \`` : "none" } | ${ target . apiEndpoints . length } | ${ target . timeoutMs } ms |`
5520- ) ;
5521- }
5522- lines . push ( "" , "Config inspection does not execute product target commands." , "" ) ;
5523- }
5524-
5525- function formatCommandList ( commands : string [ ] ) : string {
5526- if ( commands . length === 0 ) {
5527- return "none" ;
5528- }
5529-
5530- return commands . map ( ( command ) => `\`${ command } \`` ) . join ( "<br>" ) ;
5531- }
5532-
55335373function getRepoRootForCli ( cwd : string , options : { base ?: string | undefined ; head ?: string | undefined ; format : string } ) : string {
55345374 try {
55355375 return getRepoRoot ( cwd ) ;
0 commit comments