artifact-contracts 0.33.12 → 0.33.13
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.
package/README.md
CHANGED
|
@@ -210,6 +210,7 @@ Validation rules:
|
|
|
210
210
|
| Command | Description |
|
|
211
211
|
|---------|-------------|
|
|
212
212
|
| `audit [--adapter NAME]` | Semantic quality audit — naming consistency, authority appropriateness, coverage gaps |
|
|
213
|
+
| `discover [--adapter NAME] [--write]` | LLM-based artifact discovery — analyzes project structure and generates/updates `artifact-contracts.yaml` |
|
|
213
214
|
|
|
214
215
|
LLM commands require [agent-contracts-runtime](https://www.npmjs.com/package/agent-contracts-runtime) (optional peer dependency) and an adapter API key. Use `--show-prompt` or `--dry-run` to inspect the prompt without calling the LLM.
|
|
215
216
|
|
|
@@ -224,6 +225,21 @@ npx artifact-contracts audit --adapter openai
|
|
|
224
225
|
npx artifact-contracts audit --show-prompt
|
|
225
226
|
```
|
|
226
227
|
|
|
228
|
+
```bash
|
|
229
|
+
# Discover artifacts from project structure
|
|
230
|
+
npx artifact-contracts discover --adapter openai
|
|
231
|
+
|
|
232
|
+
# Write directly to artifact-contracts.yaml
|
|
233
|
+
npx artifact-contracts discover --adapter openai --write
|
|
234
|
+
|
|
235
|
+
# Preview prompt without LLM call
|
|
236
|
+
npx artifact-contracts discover --show-prompt
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
The `discover` command has two modes:
|
|
240
|
+
- **init** — When no `artifact-contracts.yaml` exists, creates a registry from scratch by analyzing the file tree
|
|
241
|
+
- **update** — When the file exists, adds definitions for uncovered files while preserving existing artifacts
|
|
242
|
+
|
|
227
243
|
### Utility Commands
|
|
228
244
|
|
|
229
245
|
| Command | Description |
|
|
@@ -3000,7 +3000,7 @@ components:
|
|
|
3000
3000
|
`).filter(Boolean)}catch{try{let{globSync:n}=await Promise.resolve().then(()=>(m8(),f8));t=n("**/*",{cwd:e,dot:!0,nodir:!0,ignore:["node_modules/**",".git/**"]})}catch(n){throw new Error(`Failed to enumerate repository files: ${n.message}`)}}return d8e(t)}function d8e(e){let t={};for(let i of e.sort()){let r=i.split("/"),a=r.length>1?r.slice(0,-1).join("/"):".";t[a]||(t[a]=[]),t[a].push(i)}let n=[];for(let i of Object.keys(t).sort()){n.push(`${i}/`);for(let r of t[i])n.push(` ${r}`);n.push("")}return n.join(`
|
|
3001
3001
|
`)}function p8e(){let e=zS("package.json");if(!vK(e))return"No package.json found.";try{let t=JSON.parse(yK(e,"utf-8"));return[`name: ${t.name??"unknown"}`,t.description?`description: ${t.description}`:"",t.version?`version: ${t.version}`:"",t.keywords?.length?`keywords: ${t.keywords.join(", ")}`:"",t.repository?.url?`repository: ${t.repository.url}`:""].filter(Boolean).join(`
|
|
3002
3002
|
`)}catch{return"package.json exists but could not be parsed."}}function f8e(e){let{mode:t,fileTree:n,existingContent:i,metadata:r}=e,a=["# Artifact Discovery","",`## Mode: ${t}`,t==="init"?"Create a new artifact-contracts.yaml from scratch based on the project file structure.":"Update the existing artifact-contracts.yaml by adding definitions for uncovered files. Preserve all existing artifact definitions.","","## Project Metadata","",r,"","## Repository File Tree","",n];return t==="update"&&i&&a.push("## Existing artifact-contracts.yaml","","```yaml",i,"```",""),a.push("## artifact-contracts.yaml Schema Reference","","The generated YAML must conform to this schema:","","```yaml",'artifact_contracts: "2026A" # or latest schema version',"","system:"," id: <kebab-case-system-id>"," name: <human-readable name>","","artifacts:"," <artifact-id>: # kebab-case IDs"," type: <artifact-type> # e.g. source, config, generated-code, generated-doc"," description: <optional description>"," authority: canonical | derived | generated | control"," manual_edit: allowed | discouraged | forbidden # optional, defaults by authority"," change_control: none | approval-required | regeneration-required # optional"," visibility: public | internal | private # optional"," path_patterns: # required, at least one pattern",' - "glob/pattern/**"'," exclude_patterns: # optional",' - "glob/pattern/to/exclude/**"',"","trace:"," links:"," - id: <kebab-case-link-id>"," from: <source-artifact-id>"," to: <target-artifact-id>"," resolver: operationId | ast | naming | codegen"," description: <optional description>","```","","### Authority Guidelines","","- canonical: hand-written source of truth (source code, configs)","- derived: generated from canonical sources but may need review (docs)","- generated: auto-generated, should not be manually edited","- control: governance/control files (CI, hooks)","","### Type Guidelines","","- source: application/library source code","- config: configuration files (YAML, JSON configs)","- generated-code: auto-generated code","- generated-doc: auto-generated documentation","","### Path Pattern Rules","",'- Use specific glob patterns, not overly broad ones like "**/*"',"- Group logically related files into single artifacts","- Use exclude_patterns to omit test files, generated subdirs, etc.","- Artifact IDs must be kebab-case","","### Trace Link Guidelines","","- Detect relationships between config/DSL artifacts and their generated outputs","- Use resolver: codegen for build-time generation relationships","- Use resolver: naming for convention-based relationships","- Use resolver: ast for code-level references","- Use resolver: operationId for API operation references","","## Instructions","","1. Analyze the file tree and group files into logical artifacts","2. Assign appropriate type, authority, and path_patterns to each artifact","3. Detect trace link relationships (especially config/DSL \u2192 generated code)","4. In update mode, preserve ALL existing artifact definitions unchanged","5. Add new artifacts only for files not covered by existing patterns","6. Generate complete, valid artifact-contracts.yaml content","","## Output Format","","Respond with a JSON object matching the artifact-discovery-result handoff schema:","","```json","{",' "artifact_contracts_yaml": "<complete YAML string for artifact-contracts.yaml>",',' "decisions": [',' { "artifact_id": "<id>", "reasoning": "<why this grouping>" }'," ],",' "trace_decisions": [',' { "link_id": "<id>", "reasoning": "<why this trace link>" }'," ],",' "uncategorized_files": ["<files that could not be categorized>"],',' "suggestions": ["<improvement suggestions>"]',"}","```","","The artifact_contracts_yaml field must contain the complete, valid YAML document.",""),a.join(`
|
|
3003
|
-
`)}function m8e(e,t,n){if(e.status==="error"){let a=e.errorMessage??"Unknown error";return n==="json"?JSON.stringify({error:a},null,2):n==="yaml"?(0,_K.stringify)({error:a}):`Error: ${a}`}let i=e.data;if(n==="json"){let a={mode:t,artifact_contracts_yaml:i?.artifact_contracts_yaml??gK(e.raw),decisions:i?.decisions??[],trace_decisions:i?.trace_decisions??[],uncategorized_files:i?.uncategorized_files??[],suggestions:i?.suggestions??[]};return JSON.stringify(a,null,2)}let r=i?.artifact_contracts_yaml??gK(e.raw);return r}function gK(e){if(!e)return"";try{let n=JSON.parse(e);if(n.artifact_contracts_yaml)return n.artifact_contracts_yaml}catch{}let t=e.match(/```ya?ml\n([\s\S]*?)```/);return t?t[1].trim():e.includes("artifact_contracts:")?e.trim():e}vd();var YDe=Ve.object({mode:Ve.enum(["init","update"]),file_tree:Ve.string(),existing_definitions:Ve.string().optional(),project_metadata:Ve.string().optional()}),XDe=Ve.object({artifact_contracts_yaml:Ve.string(),decisions:Ve.array(Ve.object({artifact_id:Ve.string(),reasoning:Ve.string()})).optional(),trace_decisions:Ve.array(Ve.object({link_id:Ve.string(),reasoning:Ve.string()})).optional(),uncategorized_files:Ve.array(Ve.string()).optional(),suggestions:Ve.array(Ve.string()).optional()}),QDe=Ve.object({system_id:Ve.string(),artifact_count:Ve.number().int(),definitions_context:Ve.string()}),eCe=Ve.object({summary:Ve.string(),risk_level:Ve.enum(["none","low","medium","high","critical"]),findings:Ve.array(Ve.object({id:Ve.string(),severity:Ve.enum(["critical","error","warning","info"]),category:Ve.string(),title:Ve.string(),description:Ve.string(),target:Ve.string().optional(),recommendation:Ve.string().optional(),evidence:Ve.array(Ve.object({kind:Ve.enum(["schema","code","config","runtime","doc"]),target:Ve.string().optional(),location:Ve.string().optional(),excerpt:Ve.string().optional(),reasoning:Ve.string().optional()})).optional()})),recommended_actions:Ve.array(Ve.object({action:Ve.string(),priority:Ve.enum(["high","medium","low"]),description:Ve.string().optional()})),metadata:Ve.object({total_artifacts:Ve.number().int().optional(),analyzed_artifacts:Ve.number().int().optional(),analysis_scope:Ve.string().optional()}).optional()});g8();var h8e={version:"0.33.
|
|
3003
|
+
`)}function m8e(e,t,n){if(e.status==="error"){let a=e.errorMessage??"Unknown error";return n==="json"?JSON.stringify({error:a},null,2):n==="yaml"?(0,_K.stringify)({error:a}):`Error: ${a}`}let i=e.data;if(n==="json"){let a={mode:t,artifact_contracts_yaml:i?.artifact_contracts_yaml??gK(e.raw),decisions:i?.decisions??[],trace_decisions:i?.trace_decisions??[],uncategorized_files:i?.uncategorized_files??[],suggestions:i?.suggestions??[]};return JSON.stringify(a,null,2)}let r=i?.artifact_contracts_yaml??gK(e.raw);return r}function gK(e){if(!e)return"";try{let n=JSON.parse(e);if(n.artifact_contracts_yaml)return n.artifact_contracts_yaml}catch{}let t=e.match(/```ya?ml\n([\s\S]*?)```/);return t?t[1].trim():e.includes("artifact_contracts:")?e.trim():e}vd();var YDe=Ve.object({mode:Ve.enum(["init","update"]),file_tree:Ve.string(),existing_definitions:Ve.string().optional(),project_metadata:Ve.string().optional()}),XDe=Ve.object({artifact_contracts_yaml:Ve.string(),decisions:Ve.array(Ve.object({artifact_id:Ve.string(),reasoning:Ve.string()})).optional(),trace_decisions:Ve.array(Ve.object({link_id:Ve.string(),reasoning:Ve.string()})).optional(),uncategorized_files:Ve.array(Ve.string()).optional(),suggestions:Ve.array(Ve.string()).optional()}),QDe=Ve.object({system_id:Ve.string(),artifact_count:Ve.number().int(),definitions_context:Ve.string()}),eCe=Ve.object({summary:Ve.string(),risk_level:Ve.enum(["none","low","medium","high","critical"]),findings:Ve.array(Ve.object({id:Ve.string(),severity:Ve.enum(["critical","error","warning","info"]),category:Ve.string(),title:Ve.string(),description:Ve.string(),target:Ve.string().optional(),recommendation:Ve.string().optional(),evidence:Ve.array(Ve.object({kind:Ve.enum(["schema","code","config","runtime","doc"]),target:Ve.string().optional(),location:Ve.string().optional(),excerpt:Ve.string().optional(),reasoning:Ve.string().optional()})).optional()})),recommended_actions:Ve.array(Ve.object({action:Ve.string(),priority:Ve.enum(["high","medium","low"]),description:Ve.string().optional()})),metadata:Ve.object({total_artifacts:Ve.number().int().optional(),analyzed_artifacts:Ve.number().int().optional(),analysis_scope:Ve.string().optional()}).optional()});g8();var h8e={version:"0.33.13"},g8e={validate:async e=>{await gN(e)},resolve:async e=>{await yN(e)},list:async e=>{await bN(e)},explain:async(e,t)=>{e||(console.error("Error: <path> argument is required"),process.exit(1)),await EN(e,t)},audit:async e=>{await pK(e)},discover:async e=>{await bK(e)},agents:async e=>{let t=await Promise.resolve().then(()=>Ia(La(),1)),n=e.format??"yaml";try{console.log(n==="json"?JSON.stringify(zl,null,2):t.stringify(zl,{lineWidth:120}))}catch(i){console.error(`Failed to output DSL: ${i.message}`),process.exit(1)}}};hx(g8e,h8e.version).parse();
|
|
3004
3004
|
/*! Bundled license information:
|
|
3005
3005
|
|
|
3006
3006
|
agent-contracts/dist/index.js:
|