{"_id":"faceted-prompting","_rev":"19-90c27bb1fb42824c45b8415dea855442","name":"faceted-prompting","dist-tags":{"next":"0.6.1","latest":"0.6.1"},"versions":{"0.0.0":{"name":"faceted-prompting","version":"0.0.0","author":{"name":"nrslib"},"license":"MIT","_id":"faceted-prompting@0.0.0","maintainers":[{"name":"nrslib","email":"masanobu.naruse@gmail.com"}],"homepage":"https://github.com/nrslib/faceted-prompting#readme","bugs":{"url":"https://github.com/nrslib/faceted-prompting/issues"},"dist":{"shasum":"3c5799b4f5cd04d0e0ad03efdef89b350584179d","tarball":"https://registry.npmjs.org/faceted-prompting/-/faceted-prompting-0.0.0.tgz","fileCount":2,"integrity":"sha512-/chHMGkdaNJ0z81IXm7I4z7m5d78Glh0wjY+pzEnmY0N4gQR49zAGBRgpdXYTx5R0kq4frsug82BOfSww9p/gg==","signatures":[{"sig":"MEQCIFFow0w+qaK1S8FZ2GENdt3zW20oOqrNq9SDiwiyJHW4AiAzf4KgvmqI76pa4w8bJvRfHQr74udZ7ufB8PmAQMyMjQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":488},"_npmUser":{"name":"nrslib","email":"masanobu.naruse@gmail.com"},"repository":{"url":"git+https://github.com/nrslib/faceted-prompting.git","type":"git"},"_npmVersion":"11.3.0","description":"Faceted Prompting - A design pattern for composing structured AI prompts from multiple facets (persona, policy, knowledge, instruction)","directories":{},"_nodeVersion":"23.11.0","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/faceted-prompting_0.0.0_1771289414863_0.5576267479946304","host":"s3://npm-registry-packages-npm-production"}},"0.1.0":{"name":"faceted-prompting","version":"0.1.0","keywords":["prompt","llm","faceted-prompting","prompt-engineering","ai"],"license":"MIT","_id":"faceted-prompting@0.1.0","maintainers":[{"name":"nrslib","email":"masanobu.naruse@gmail.com"}],"dist":{"shasum":"6320b77eca71b8ad0825d5c25db297d6c529ff25","tarball":"https://registry.npmjs.org/faceted-prompting/-/faceted-prompting-0.1.0.tgz","fileCount":39,"integrity":"sha512-nFXVRwIvIWgVMLGlY2XO83D/BRSJ177ecIqyARisxHsUWBnJXpGSRIIe/O+Nbp+YMRRCaMwC04bxUaRFRpM4kw==","signatures":[{"sig":"MEUCIQCbkCL2LH7rh8bGkG+wbkKhVXw4+mVOjofpjJgOF8xSwQIgAu7rZ3Onhxu+xq/BWM8bEsRLKfnaMBLYVwfYYDTuyZA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":56196},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=18"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"110e67483c1064e2437ae2d0fc7be311b5f2b650","scripts":{"lint":"eslint src/","test":"vitest run","build":"tsc","watch":"tsc --watch","test:watch":"vitest","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"nrslib","email":"masanobu.naruse@gmail.com"},"_npmVersion":"10.8.2","description":"Faceted Prompting — structured prompt composition for LLMs","directories":{},"_nodeVersion":"20.20.0","_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.0.0","vitest":"^3.2.4","typescript":"^5.9.3","@types/node":"^22.19.11"},"_npmOperationalInternal":{"tmp":"tmp/faceted-prompting_0.1.0_1772929270110_0.04730321453744479","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"faceted-prompting","version":"0.2.0","keywords":["prompt","llm","faceted-prompting","prompt-engineering","ai"],"license":"MIT","_id":"faceted-prompting@0.2.0","maintainers":[{"name":"nrslib","email":"masanobu.naruse@gmail.com"}],"bin":{"facet":"bin/facet"},"dist":{"shasum":"6f2b5a4fea7e5c223466fcfea5e85fb560a6bf84","tarball":"https://registry.npmjs.org/faceted-prompting/-/faceted-prompting-0.2.0.tgz","fileCount":116,"integrity":"sha512-RZzg2Sp28S4GEGmdJLgjdAVekx/meGThK4iZldaMvyEbAHNL175/vYwjTHDcw1LYnLXW6+LOUCGBTWPvOr+R0Q==","signatures":[{"sig":"MEQCIDVwNINy6mJzgvX/UiQID/ehMRhgjCdoyQZ2mBX+ybzkAiAjqPhJ+pthgsJJC06lGk2svTuANf4hS4c2d2FthG5i3A==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":215421},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"84f93cd1b08db967cb92ab3345cdeac1ce05a875","scripts":{"lint":"eslint src/","test":"npm run test:unit","build":"tsc","watch":"tsc --watch","test:e2e":"tmp=\"$(mktemp -t faceted-prompting-e2e.XXXXXX)\"; mkdir -p e2e/results; npm run test:e2e:cli >\"$tmp\" 2>&1; code=$?; cat \"$tmp\"; rm -f \"$tmp\"; if [ \"$code\" -eq 0 ]; then msg='test:e2e passed'; else msg=\"test:e2e failed (exit=$code)\"; fi; if command -v osascript >/dev/null 2>&1; then osascript -e \"display notification \\\"$msg\\\" with title \\\"faceted-prompting\\\" subtitle \\\"E2E\\\"\" >/dev/null 2>&1 || true; fi; echo \"[faceted-prompting] $msg\"; exit $code","test:unit":"vitest run --config vitest.config.ts","test:watch":"vitest","test:e2e:cli":"vitest run --config vitest.config.e2e.ts --outputFile.json=e2e/results/cli.json","check:release":"npm run build && npm run lint && npm run test:unit && npm run test:e2e; code=$?; if [ \"$code\" -eq 0 ]; then msg='check:release passed'; else msg=\"check:release failed (exit=$code)\"; fi; if command -v osascript >/dev/null 2>&1; then osascript -e \"display notification \\\"$msg\\\" with title \\\"faceted-prompting\\\" subtitle \\\"Release Check\\\"\" >/dev/null 2>&1 || true; fi; echo \"[faceted-prompting] $msg\"; exit $code","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"nrslib","email":"masanobu.naruse@gmail.com"},"_npmVersion":"10.8.2","description":"Faceted Prompting — structured prompt composition for LLMs","directories":{},"_nodeVersion":"20.20.0","dependencies":{"yaml":"^2.8.1","traced-config":"^0.1.0"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.0.0","vitest":"^3.2.4","typescript":"^5.9.3","@types/node":"^22.19.11"},"_npmOperationalInternal":{"tmp":"tmp/faceted-prompting_0.2.0_1773282457451_0.8306565081619051","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"faceted-prompting","version":"0.2.1","keywords":["prompt","llm","faceted-prompting","prompt-engineering","ai"],"license":"MIT","_id":"faceted-prompting@0.2.1","maintainers":[{"name":"nrslib","email":"masanobu.naruse@gmail.com"}],"bin":{"facet":"bin/facet"},"dist":{"shasum":"bed87bda0e4605fb8566fc47395b4b5eaa88e2d1","tarball":"https://registry.npmjs.org/faceted-prompting/-/faceted-prompting-0.2.1.tgz","fileCount":116,"integrity":"sha512-uyegSbWM6OncgTRwLjZnsGnu4SVBTh9xAljb75ttoUUVzM1eJifnmiE2clN2kjjG1BSmJEtRKdP/JU5h8oNwfA==","signatures":[{"sig":"MEYCIQDJoS+hyMAEAhjZh0Z/zX3gIs6nDP2f3NAO1kPbTvyZDQIhAOSlKjAWKz/asXR073PwO/KouXldTAFF2lz4faqLFepi","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":216769},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"ad46169c144c884fd8f66efb28ca8ccc96de2671","scripts":{"lint":"eslint src/","test":"npm run test:unit","build":"tsc","watch":"tsc --watch","prepack":"npm run build","test:e2e":"tmp=\"$(mktemp -t faceted-prompting-e2e.XXXXXX)\"; mkdir -p e2e/results; npm run test:e2e:cli >\"$tmp\" 2>&1; code=$?; cat \"$tmp\"; rm -f \"$tmp\"; if [ \"$code\" -eq 0 ]; then msg='test:e2e passed'; else msg=\"test:e2e failed (exit=$code)\"; fi; if command -v osascript >/dev/null 2>&1; then osascript -e \"display notification \\\"$msg\\\" with title \\\"faceted-prompting\\\" subtitle \\\"E2E\\\"\" >/dev/null 2>&1 || true; fi; echo \"[faceted-prompting] $msg\"; exit $code","test:unit":"vitest run --config vitest.config.ts","pack:check":"npm_config_cache=/tmp/.npm-faceted npm pack --dry-run","smoke:pack":"tmp=\"$(mktemp -d -t faceted-prompting-pack.XXXXXX)\"; npm_config_cache=/tmp/.npm-faceted npm pack --pack-destination \"$tmp\" >/dev/null; tarball=\"$(find \"$tmp\" -maxdepth 1 -name '*.tgz' -print -quit)\"; npm_config_cache=/tmp/.npm-faceted npm install --no-audit --fund=false --ignore-scripts --prefix \"$tmp/install\" \"$tarball\" >/dev/null; cd \"$tmp/install\" && node --input-type=module -e \"const pkg = await import('faceted-prompting'); if (typeof pkg.compose !== 'function') throw new Error('compose export missing');\" && test -x ./node_modules/.bin/facet; rm -rf \"$tmp\"","test:watch":"vitest","test:e2e:cli":"vitest run --config vitest.config.e2e.ts --outputFile.json=e2e/results/cli.json","check:release":"npm run build && npm run lint && npm run test:unit && npm run test:e2e; code=$?; if [ \"$code\" -eq 0 ]; then msg='check:release passed'; else msg=\"check:release failed (exit=$code)\"; fi; if command -v osascript >/dev/null 2>&1; then osascript -e \"display notification \\\"$msg\\\" with title \\\"faceted-prompting\\\" subtitle \\\"Release Check\\\"\" >/dev/null 2>&1 || true; fi; echo \"[faceted-prompting] $msg\"; exit $code","prepublishOnly":"npm run verify:release","verify:release":"npm run build && npm run lint && npm run test:unit && npm run test:e2e && npm run pack:check && npm run smoke:pack"},"_npmUser":{"name":"nrslib","email":"masanobu.naruse@gmail.com"},"_npmVersion":"10.8.2","description":"Faceted Prompting — structured prompt composition for LLMs","directories":{},"_nodeVersion":"20.20.0","dependencies":{"yaml":"^2.8.1","traced-config":"^0.1.0"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.0.0","vitest":"^3.2.4","typescript":"^5.9.3","@types/node":"^22.19.11","typescript-eslint":"^8.57.0"},"_npmOperationalInternal":{"tmp":"tmp/faceted-prompting_0.2.1_1773311789245_0.37834029526145185","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"faceted-prompting","version":"0.3.0","keywords":["prompt","llm","faceted-prompting","prompt-engineering","ai"],"license":"MIT","_id":"faceted-prompting@0.3.0","maintainers":[{"name":"nrslib","email":"masanobu.naruse@gmail.com"}],"bin":{"facet":"bin/facet"},"dist":{"shasum":"3432260ab12d99a4387a58758a3bea8f61ccf2ce","tarball":"https://registry.npmjs.org/faceted-prompting/-/faceted-prompting-0.3.0.tgz","fileCount":132,"integrity":"sha512-xlxa2ju22RfQzolNisdiS9tG/JMw+GqGo92UQpgYcoskGcf1epzzwBPy6miGcIEHGeYEq2LqxZZgNbXvy+/58w==","signatures":[{"sig":"MEUCIDpeMddK/LWYkb6HTj8h9tREcOaioFicC8xaVb42ukjaAiEApaV5hR/21tjglFXUoG2NFJAbKdxGl3/suhZdXT/yv/o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":256378},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"c07210b7f8a996ea3acf7a12a881a77b536c9e32","scripts":{"lint":"eslint src/","test":"npm run test:unit","build":"tsc","watch":"tsc --watch","prepack":"npm run build","test:e2e":"tmp=\"$(mktemp -t faceted-prompting-e2e.XXXXXX)\"; mkdir -p e2e/results; npm run test:e2e:cli >\"$tmp\" 2>&1; code=$?; cat \"$tmp\"; rm -f \"$tmp\"; if [ \"$code\" -eq 0 ]; then msg='test:e2e passed'; else msg=\"test:e2e failed (exit=$code)\"; fi; if command -v osascript >/dev/null 2>&1; then osascript -e \"display notification \\\"$msg\\\" with title \\\"faceted-prompting\\\" subtitle \\\"E2E\\\"\" >/dev/null 2>&1 || true; fi; echo \"[faceted-prompting] $msg\"; exit $code","test:unit":"vitest run --config vitest.config.ts","pack:check":"npm_config_cache=/tmp/.npm-faceted npm pack --dry-run","smoke:pack":"tmp=\"$(mktemp -d -t faceted-prompting-pack.XXXXXX)\"; npm_config_cache=/tmp/.npm-faceted npm pack --pack-destination \"$tmp\" >/dev/null; tarball=\"$(find \"$tmp\" -maxdepth 1 -name '*.tgz' -print -quit)\"; npm_config_cache=/tmp/.npm-faceted npm install --no-audit --fund=false --ignore-scripts --prefix \"$tmp/install\" \"$tarball\" >/dev/null; cd \"$tmp/install\" && node --input-type=module -e \"const pkg = await import('faceted-prompting'); if (typeof pkg.compose !== 'function') throw new Error('compose export missing');\" && test -x ./node_modules/.bin/facet; rm -rf \"$tmp\"","test:watch":"vitest","test:e2e:cli":"vitest run --config vitest.config.e2e.ts --outputFile.json=e2e/results/cli.json","check:release":"npm run build && npm run lint && npm run test:unit && npm run test:e2e; code=$?; if [ \"$code\" -eq 0 ]; then msg='check:release passed'; else msg=\"check:release failed (exit=$code)\"; fi; if command -v osascript >/dev/null 2>&1; then osascript -e \"display notification \\\"$msg\\\" with title \\\"faceted-prompting\\\" subtitle \\\"Release Check\\\"\" >/dev/null 2>&1 || true; fi; echo \"[faceted-prompting] $msg\"; exit $code","prepublishOnly":"npm run verify:release","verify:release":"npm run build && npm run lint && npm run test:unit && npm run test:e2e && npm run pack:check && npm run smoke:pack"},"_npmUser":{"name":"nrslib","email":"masanobu.naruse@gmail.com"},"_npmVersion":"10.8.2","description":"Faceted Prompting — structured prompt composition for LLMs","directories":{},"_nodeVersion":"20.20.1","dependencies":{"yaml":"^2.8.1","traced-config":"^0.1.0","update-notifier":"^7.3.1"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.0.0","vitest":"^3.2.4","typescript":"^5.9.3","@types/node":"^22.19.11","typescript-eslint":"^8.57.0"},"_npmOperationalInternal":{"tmp":"tmp/faceted-prompting_0.3.0_1773830311604_0.1382814050331873","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"faceted-prompting","version":"0.3.1","keywords":["prompt","llm","faceted-prompting","prompt-engineering","ai"],"license":"MIT","_id":"faceted-prompting@0.3.1","maintainers":[{"name":"nrslib","email":"masanobu.naruse@gmail.com"}],"bin":{"facet":"bin/facet"},"dist":{"shasum":"fceeeac2435e8c846280a3fea5fa122c5c4fb6a4","tarball":"https://registry.npmjs.org/faceted-prompting/-/faceted-prompting-0.3.1.tgz","fileCount":132,"integrity":"sha512-f53cAFFZ4JDLa+hgCNPXaigLFS5QiOkmoeIPP7U0hnL9ZfzihB2e2Rwur+4n/PwRB2BdVv2Uo3DfqJQ5QZcCtw==","signatures":[{"sig":"MEUCIQDJbkaHvpt4XyOZaWWVonZkVlRY2KuG+DvgV7DFOPtqxQIgZYcqvPLne1pUcc1m6soGx7izPVomzQ++lK9hj6xXzYc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":261087},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"ba3c35edcd27d5c094224703cb0720d271b8cd1f","scripts":{"lint":"eslint src/","test":"npm run test:unit","build":"tsc","watch":"tsc --watch","prepack":"npm run build","test:e2e":"tmp=\"$(mktemp -t faceted-prompting-e2e.XXXXXX)\"; mkdir -p e2e/results; npm run test:e2e:cli >\"$tmp\" 2>&1; code=$?; cat \"$tmp\"; rm -f \"$tmp\"; if [ \"$code\" -eq 0 ]; then msg='test:e2e passed'; else msg=\"test:e2e failed (exit=$code)\"; fi; if command -v osascript >/dev/null 2>&1; then osascript -e \"display notification \\\"$msg\\\" with title \\\"faceted-prompting\\\" subtitle \\\"E2E\\\"\" >/dev/null 2>&1 || true; fi; echo \"[faceted-prompting] $msg\"; exit $code","test:unit":"vitest run --config vitest.config.ts","pack:check":"npm_config_cache=/tmp/.npm-faceted npm pack --dry-run","smoke:pack":"tmp=\"$(mktemp -d -t faceted-prompting-pack.XXXXXX)\"; npm_config_cache=/tmp/.npm-faceted npm pack --pack-destination \"$tmp\" >/dev/null; tarball=\"$(find \"$tmp\" -maxdepth 1 -name '*.tgz' -print -quit)\"; npm_config_cache=/tmp/.npm-faceted npm install --no-audit --fund=false --ignore-scripts --prefix \"$tmp/install\" \"$tarball\" >/dev/null; cd \"$tmp/install\" && node --input-type=module -e \"const pkg = await import('faceted-prompting'); if (typeof pkg.compose !== 'function') throw new Error('compose export missing');\" && test -x ./node_modules/.bin/facet; rm -rf \"$tmp\"","test:watch":"vitest","test:e2e:cli":"vitest run --config vitest.config.e2e.ts --outputFile.json=e2e/results/cli.json","check:release":"npm run build && npm run lint && npm run test:unit && npm run test:e2e; code=$?; if [ \"$code\" -eq 0 ]; then msg='check:release passed'; else msg=\"check:release failed (exit=$code)\"; fi; if command -v osascript >/dev/null 2>&1; then osascript -e \"display notification \\\"$msg\\\" with title \\\"faceted-prompting\\\" subtitle \\\"Release Check\\\"\" >/dev/null 2>&1 || true; fi; echo \"[faceted-prompting] $msg\"; exit $code","prepublishOnly":"npm run verify:release","verify:release":"npm run build && npm run lint && npm run test:unit && npm run test:e2e && npm run pack:check && npm run smoke:pack"},"_npmUser":{"name":"nrslib","email":"masanobu.naruse@gmail.com"},"_npmVersion":"10.8.2","description":"Faceted Prompting — structured prompt composition for LLMs","directories":{},"_nodeVersion":"20.20.1","dependencies":{"yaml":"^2.8.1","traced-config":"^0.1.0","update-notifier":"^7.3.1"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.0.0","vitest":"^3.2.4","typescript":"^5.9.3","@types/node":"^22.19.11","typescript-eslint":"^8.57.0"},"_npmOperationalInternal":{"tmp":"tmp/faceted-prompting_0.3.1_1773907348127_0.6983117165671942","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"faceted-prompting","version":"0.4.0","keywords":["prompt","llm","faceted-prompting","prompt-engineering","ai"],"license":"MIT","_id":"faceted-prompting@0.4.0","maintainers":[{"name":"nrslib","email":"masanobu.naruse@gmail.com"}],"bin":{"facet":"bin/facet"},"dist":{"shasum":"c0a8a2eb914c6b5ff42740f7540ce0831a4ec22d","tarball":"https://registry.npmjs.org/faceted-prompting/-/faceted-prompting-0.4.0.tgz","fileCount":152,"integrity":"sha512-qoPFUMffSEOmw3OVobvRSeU36Lw4zHorGVtuSbwXOonBmN2kzYIXYQEXIR2MJrAuFhsIDpIH8+XYpX1zHQmA/A==","signatures":[{"sig":"MEUCIQCLvLmBPcxop+I/4WQignFKn4s4f1AoiJQTXcshwW0PswIgSqad2++P3h+w2CMZ3JUVujBBPFkTDWRWOLYSa5ryQQI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":289591},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"fde0ec6e51549965c0a9b051d61101c39a58ee92","scripts":{"lint":"eslint src/","test":"npm run test:unit","build":"tsc","watch":"tsc --watch","prepack":"npm run build","test:e2e":"tmp=\"$(mktemp -t faceted-prompting-e2e.XXXXXX)\"; mkdir -p e2e/results; npm run test:e2e:cli >\"$tmp\" 2>&1; code=$?; cat \"$tmp\"; rm -f \"$tmp\"; if [ \"$code\" -eq 0 ]; then msg='test:e2e passed'; else msg=\"test:e2e failed (exit=$code)\"; fi; if command -v osascript >/dev/null 2>&1; then osascript -e \"display notification \\\"$msg\\\" with title \\\"faceted-prompting\\\" subtitle \\\"E2E\\\"\" >/dev/null 2>&1 || true; fi; echo \"[faceted-prompting] $msg\"; exit $code","test:unit":"vitest run --config vitest.config.ts","pack:check":"npm_config_cache=/tmp/.npm-faceted npm pack --dry-run","smoke:pack":"tmp=\"$(mktemp -d -t faceted-prompting-pack.XXXXXX)\"; npm_config_cache=/tmp/.npm-faceted npm pack --pack-destination \"$tmp\" >/dev/null; tarball=\"$(find \"$tmp\" -maxdepth 1 -name '*.tgz' -print -quit)\"; npm_config_cache=/tmp/.npm-faceted npm install --no-audit --fund=false --ignore-scripts --prefix \"$tmp/install\" \"$tarball\" >/dev/null; cd \"$tmp/install\" && node --input-type=module -e \"const pkg = await import('faceted-prompting'); if (typeof pkg.compose !== 'function') throw new Error('compose export missing');\" && test -x ./node_modules/.bin/facet; rm -rf \"$tmp\"","test:watch":"vitest","test:e2e:cli":"vitest run --config vitest.config.e2e.ts --outputFile.json=e2e/results/cli.json","check:release":"npm run build && npm run lint && npm run test:unit && npm run test:e2e; code=$?; if [ \"$code\" -eq 0 ]; then msg='check:release passed'; else msg=\"check:release failed (exit=$code)\"; fi; if command -v osascript >/dev/null 2>&1; then osascript -e \"display notification \\\"$msg\\\" with title \\\"faceted-prompting\\\" subtitle \\\"Release Check\\\"\" >/dev/null 2>&1 || true; fi; echo \"[faceted-prompting] $msg\"; exit $code","prepublishOnly":"npm run verify:release","verify:release":"npm run build && npm run lint && npm run test:unit && npm run test:e2e && npm run pack:check && npm run smoke:pack"},"_npmUser":{"name":"nrslib","email":"masanobu.naruse@gmail.com"},"_npmVersion":"10.8.2","description":"Faceted Prompting — structured prompt composition for LLMs","directories":{},"_nodeVersion":"20.20.1","dependencies":{"yaml":"^2.8.1","traced-config":"^0.1.0","update-notifier":"^7.3.1"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.0.0","vitest":"^3.2.4","typescript":"^5.9.3","@types/node":"^22.19.11","typescript-eslint":"^8.57.0"},"_npmOperationalInternal":{"tmp":"tmp/faceted-prompting_0.4.0_1775017959005_0.43974179868567687","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"faceted-prompting","version":"0.5.0","keywords":["prompt","llm","faceted-prompting","prompt-engineering","ai"],"license":"MIT","_id":"faceted-prompting@0.5.0","maintainers":[{"name":"nrslib","email":"masanobu.naruse@gmail.com"}],"bin":{"facet":"bin/facet"},"dist":{"shasum":"23a776d5d898e15971b48972e5f46a501f1ddf4d","tarball":"https://registry.npmjs.org/faceted-prompting/-/faceted-prompting-0.5.0.tgz","fileCount":168,"integrity":"sha512-pP6Nd07KSn1cwH6yMDqszSx/J9JSx1FkmucvWMBFKiavxD18QBjQ56QgQSbmGeRp2lxDtRnHALnp03Kk78N84g==","signatures":[{"sig":"MEYCIQCgmUbo7lZKIeOYRfwxV/KY9hRJVbfvsso0f14PlT79ygIhAM5asQy/3uDJe+524DyWOgLnkcWtgmI0tsJUtRhLzJok","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":323516},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"fc6be27b7b013c27e920a52a0d0c53d04980ec36","scripts":{"lint":"eslint src/","test":"npm run test:unit","build":"tsc","watch":"tsc --watch","prepack":"npm run build","test:e2e":"tmp=\"$(mktemp -t faceted-prompting-e2e.XXXXXX)\"; mkdir -p e2e/results; npm run test:e2e:cli >\"$tmp\" 2>&1; code=$?; cat \"$tmp\"; rm -f \"$tmp\"; if [ \"$code\" -eq 0 ]; then msg='test:e2e passed'; else msg=\"test:e2e failed (exit=$code)\"; fi; if command -v osascript >/dev/null 2>&1; then osascript -e \"display notification \\\"$msg\\\" with title \\\"faceted-prompting\\\" subtitle \\\"E2E\\\"\" >/dev/null 2>&1 || true; fi; echo \"[faceted-prompting] $msg\"; exit $code","test:unit":"vitest run --config vitest.config.ts","pack:check":"npm_config_cache=/tmp/.npm-faceted npm pack --dry-run","smoke:pack":"tmp=\"$(mktemp -d -t faceted-prompting-pack.XXXXXX)\"; npm_config_cache=/tmp/.npm-faceted npm pack --pack-destination \"$tmp\" >/dev/null; tarball=\"$(find \"$tmp\" -maxdepth 1 -name '*.tgz' -print -quit)\"; npm_config_cache=/tmp/.npm-faceted npm install --no-audit --fund=false --ignore-scripts --prefix \"$tmp/install\" \"$tarball\" >/dev/null; cd \"$tmp/install\" && node --input-type=module -e \"const pkg = await import('faceted-prompting'); if (typeof pkg.compose !== 'function') throw new Error('compose export missing');\" && test -x ./node_modules/.bin/facet; rm -rf \"$tmp\"","test:watch":"vitest","test:e2e:cli":"vitest run --config vitest.config.e2e.ts --outputFile.json=e2e/results/cli.json","check:release":"npm run build && npm run lint && npm run test:unit && npm run test:e2e; code=$?; if [ \"$code\" -eq 0 ]; then msg='check:release passed'; else msg=\"check:release failed (exit=$code)\"; fi; if command -v osascript >/dev/null 2>&1; then osascript -e \"display notification \\\"$msg\\\" with title \\\"faceted-prompting\\\" subtitle \\\"Release Check\\\"\" >/dev/null 2>&1 || true; fi; echo \"[faceted-prompting] $msg\"; exit $code","prepublishOnly":"npm run verify:release","verify:release":"npm run build && npm run lint && npm run test:unit && npm run test:e2e && npm run pack:check && npm run smoke:pack"},"_npmUser":{"name":"nrslib","email":"masanobu.naruse@gmail.com"},"_npmVersion":"10.8.2","description":"Faceted Prompting — structured prompt composition for LLMs","directories":{},"_nodeVersion":"20.20.2","dependencies":{"yaml":"^2.9.0","traced-config":"^0.1.0","update-notifier":"^7.3.1"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.0.0","vitest":"^4.1.9","typescript":"^5.9.3","@types/node":"^22.19.11","typescript-eslint":"^8.57.0"},"_npmOperationalInternal":{"tmp":"tmp/faceted-prompting_0.5.0_1781873675819_0.8489177262840724","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"faceted-prompting","version":"0.6.0","keywords":["prompt","llm","faceted-prompting","prompt-engineering","ai"],"license":"MIT","_id":"faceted-prompting@0.6.0","maintainers":[{"name":"nrslib","email":"masanobu.naruse@gmail.com"}],"bin":{"facet":"bin/facet"},"dist":{"shasum":"ce46b6d3a9fa2817c01386e5332738fc951b63b9","tarball":"https://registry.npmjs.org/faceted-prompting/-/faceted-prompting-0.6.0.tgz","fileCount":168,"integrity":"sha512-K5sVFUf/mSBayWuRH9s+BI/kxtiQwOpfXuSpQ+20fAT33AaDWrhDgAbWsXiqzianXmgKYB7Ca0ntjqLkT+2Ugg==","signatures":[{"sig":"MEQCIACm9UHrdtsb2tgHWviV8wZuXBu5vS/1GEowtzKPLfIYAiBQ+0UCokcIYmbSeu/SLiV7ullNDKya6yVeJFZn3RmZVg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":331354},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"30586ff4c4121bebc4a8731dcf143583c040c1df","scripts":{"lint":"eslint src/","test":"npm run test:unit","build":"tsc","watch":"tsc --watch","prepack":"npm run build","test:e2e":"tmp=\"$(mktemp -t faceted-prompting-e2e.XXXXXX)\"; mkdir -p e2e/results; npm run test:e2e:cli >\"$tmp\" 2>&1; code=$?; cat \"$tmp\"; rm -f \"$tmp\"; if [ \"$code\" -eq 0 ]; then msg='test:e2e passed'; else msg=\"test:e2e failed (exit=$code)\"; fi; if command -v osascript >/dev/null 2>&1; then osascript -e \"display notification \\\"$msg\\\" with title \\\"faceted-prompting\\\" subtitle \\\"E2E\\\"\" >/dev/null 2>&1 || true; fi; echo \"[faceted-prompting] $msg\"; exit $code","test:unit":"vitest run --config vitest.config.ts","pack:check":"npm_config_cache=/tmp/.npm-faceted npm pack --dry-run","smoke:pack":"tmp=\"$(mktemp -d -t faceted-prompting-pack.XXXXXX)\"; npm_config_cache=/tmp/.npm-faceted npm pack --pack-destination \"$tmp\" >/dev/null; tarball=\"$(find \"$tmp\" -maxdepth 1 -name '*.tgz' -print -quit)\"; npm_config_cache=/tmp/.npm-faceted npm install --no-audit --fund=false --ignore-scripts --prefix \"$tmp/install\" \"$tarball\" >/dev/null; cd \"$tmp/install\" && node --input-type=module -e \"const pkg = await import('faceted-prompting'); if (typeof pkg.compose !== 'function') throw new Error('compose export missing');\" && test -x ./node_modules/.bin/facet; rm -rf \"$tmp\"","test:watch":"vitest","test:e2e:cli":"vitest run --config vitest.config.e2e.ts --outputFile.json=e2e/results/cli.json","check:release":"npm run build && npm run lint && npm run test:unit && npm run test:e2e; code=$?; if [ \"$code\" -eq 0 ]; then msg='check:release passed'; else msg=\"check:release failed (exit=$code)\"; fi; if command -v osascript >/dev/null 2>&1; then osascript -e \"display notification \\\"$msg\\\" with title \\\"faceted-prompting\\\" subtitle \\\"Release Check\\\"\" >/dev/null 2>&1 || true; fi; echo \"[faceted-prompting] $msg\"; exit $code","prepublishOnly":"npm run verify:release","verify:release":"npm run build && npm run lint && npm run test:unit && npm run test:e2e && npm run pack:check && npm run smoke:pack"},"_npmUser":{"name":"nrslib","email":"masanobu.naruse@gmail.com"},"_npmVersion":"10.8.2","description":"Faceted Prompting — structured prompt composition for LLMs","directories":{},"_nodeVersion":"20.20.2","dependencies":{"yaml":"^2.9.0","traced-config":"^0.1.0","update-notifier":"^7.3.1"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.0.0","vitest":"^4.1.9","typescript":"^5.9.3","@types/node":"^22.19.11","typescript-eslint":"^8.57.0"},"_npmOperationalInternal":{"tmp":"tmp/faceted-prompting_0.6.0_1782724854291_0.01622353621531092","host":"s3://npm-registry-packages-npm-production"}},"0.6.1":{"name":"faceted-prompting","version":"0.6.1","keywords":["prompt","llm","faceted-prompting","prompt-engineering","ai"],"license":"MIT","_id":"faceted-prompting@0.6.1","maintainers":[{"name":"nrslib","email":"masanobu.naruse@gmail.com"}],"bin":{"facet":"bin/facet"},"dist":{"shasum":"c322313859a8d58b5046fd2b84f8f454b4db4d41","tarball":"https://registry.npmjs.org/faceted-prompting/-/faceted-prompting-0.6.1.tgz","fileCount":168,"integrity":"sha512-W8DWu7d5/uAwV/zxNnyL/4khflhy6Cw/l/TRospUq4DprNsyv+A8BydK9tkdHbakgPct2tLW0UJHG2ArQimj9Q==","signatures":[{"sig":"MEUCIFmdbh8AKa1k0gPnNd5+I1KhqfJYwJ3w1Ck9LqhQEhMvAiEAmw3jTdzZxfGD+nU31jVbzUWFufL1Udqtplxx2yXvc74=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":331487},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./cli/facet-includes":{"types":"./dist/cli/facet-includes.d.ts","import":"./dist/cli/facet-includes.js"}},"gitHead":"2f849de00db8ab22506c05c2aaf321cf6ad69121","scripts":{"lint":"eslint src/","test":"npm run test:unit","build":"tsc","watch":"tsc --watch","prepack":"npm run build","test:e2e":"tmp=\"$(mktemp -t faceted-prompting-e2e.XXXXXX)\"; mkdir -p e2e/results; npm run test:e2e:cli >\"$tmp\" 2>&1; code=$?; cat \"$tmp\"; rm -f \"$tmp\"; if [ \"$code\" -eq 0 ]; then msg='test:e2e passed'; else msg=\"test:e2e failed (exit=$code)\"; fi; if command -v osascript >/dev/null 2>&1; then osascript -e \"display notification \\\"$msg\\\" with title \\\"faceted-prompting\\\" subtitle \\\"E2E\\\"\" >/dev/null 2>&1 || true; fi; echo \"[faceted-prompting] $msg\"; exit $code","test:unit":"vitest run --config vitest.config.ts","pack:check":"npm_config_cache=/tmp/.npm-faceted npm pack --dry-run","smoke:pack":"tmp=\"$(mktemp -d -t faceted-prompting-pack.XXXXXX)\"; npm_config_cache=/tmp/.npm-faceted npm pack --pack-destination \"$tmp\" >/dev/null; tarball=\"$(find \"$tmp\" -maxdepth 1 -name '*.tgz' -print -quit)\"; npm_config_cache=/tmp/.npm-faceted npm install --no-audit --fund=false --ignore-scripts --prefix \"$tmp/install\" \"$tarball\" >/dev/null; cd \"$tmp/install\" && node --input-type=module -e \"const pkg = await import('faceted-prompting'); if (typeof pkg.compose !== 'function') throw new Error('compose export missing');\" && test -x ./node_modules/.bin/facet; rm -rf \"$tmp\"","test:watch":"vitest","test:e2e:cli":"vitest run --config vitest.config.e2e.ts --outputFile.json=e2e/results/cli.json","check:release":"npm run build && npm run lint && npm run test:unit && npm run test:e2e; code=$?; if [ \"$code\" -eq 0 ]; then msg='check:release passed'; else msg=\"check:release failed (exit=$code)\"; fi; if command -v osascript >/dev/null 2>&1; then osascript -e \"display notification \\\"$msg\\\" with title \\\"faceted-prompting\\\" subtitle \\\"Release Check\\\"\" >/dev/null 2>&1 || true; fi; echo \"[faceted-prompting] $msg\"; exit $code","prepublishOnly":"npm run verify:release","verify:release":"npm run build && npm run lint && npm run test:unit && npm run test:e2e && npm run pack:check && npm run smoke:pack"},"_npmUser":{"name":"nrslib","email":"masanobu.naruse@gmail.com"},"_npmVersion":"10.8.2","description":"Faceted Prompting — structured prompt composition for LLMs","directories":{},"_nodeVersion":"20.20.2","dependencies":{"yaml":"^2.9.0","traced-config":"^0.1.0","update-notifier":"^7.3.1"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^9.0.0","vitest":"^4.1.9","typescript":"^5.9.3","@types/node":"^22.19.11","typescript-eslint":"^8.57.0"},"_npmOperationalInternal":{"tmp":"tmp/faceted-prompting_0.6.1_1782728070797_0.259288566109662","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2026-02-17T00:50:14.862Z","modified":"2026-06-29T10:14:31.990Z","0.0.0":"2026-02-17T00:50:15.012Z","0.1.0":"2026-03-08T00:21:10.248Z","0.2.0":"2026-03-12T02:27:37.632Z","0.2.1":"2026-03-12T10:36:29.393Z","0.3.0":"2026-03-18T10:38:31.758Z","0.3.1":"2026-03-19T08:02:28.268Z","0.4.0":"2026-04-01T04:32:39.173Z","0.5.0":"2026-06-19T12:54:35.965Z","0.6.0":"2026-06-29T09:20:54.422Z","0.6.1":"2026-06-29T10:14:30.971Z"},"license":"MIT","keywords":["prompt","llm","faceted-prompting","prompt-engineering","ai"],"description":"Faceted Prompting — structured prompt composition for LLMs","maintainers":[{"name":"nrslib","email":"masanobu.naruse@gmail.com"}],"readme":"# faceted-prompting\n\n[Faceted Prompting 解説記事](https://nrslib.com/faceted-prompting)\n\nStructured prompt composition for LLMs — decompose prompts into reusable facets and compose them into LLM-ready messages.\n\nfaceted-prompting separates prompt concerns into distinct facets (persona, policy, knowledge, instruction, output contracts), each with a defined role and message placement. This keeps prompts modular, testable, and maintainable as they grow in complexity.\n\n## Why Faceted Prompting\n\n**Separation of concerns** — Each facet has a single responsibility. Persona defines *who* the agent is, policies define *how* it should behave, knowledge provides *what it needs to know*, instructions define *what to do*, and output contracts define *how to answer*. Changes to one facet don't affect others.\n\n**Deterministic placement** — Persona always goes to the system prompt. Policies, knowledge, instructions, and output contracts always go to the user message. This placement rule is enforced by the library, not left to convention.\n\n**Composable** — Facets are plain Markdown files. Mix and match personas, policies, knowledge, instructions, and output contracts across different workflows. Share them as repertoire packages via `@owner/repo/facet-name` scope references.\n\n**Framework-independent** — Zero dependencies on any specific AI framework. Use it with Claude, OpenAI, or any LLM provider.\n\n## Facet Kinds\n\n| Facet | Placement | Role |\n|-------|-----------|------|\n| **Persona** | System prompt | WHO — agent identity and character |\n| **Policy** | User message | HOW — rules, standards, constraints |\n| **Knowledge** | User message | WHAT TO KNOW — domain context, architecture |\n| **Instruction** | User message | WHAT TO DO — the specific task |\n| **Output contracts** | User message | HOW TO ANSWER — output/report format |\n\n## Install\n\n```bash\nnpm install faceted-prompting\n```\n\nGlobal CLI:\n\n```bash\nnpm install -g faceted-prompting\nfacet init\nfacet pull-sample\n```\n\n## Quick Start\n\n### As a library\n\n```typescript\nimport { compose } from 'faceted-prompting';\n\nconst result = compose(\n  {\n    persona: { body: 'You are a senior TypeScript developer.' },\n    policies: [{ body: 'Follow clean code principles. No any types.' }],\n    knowledge: [{ body: 'The project uses Vitest for testing.' }],\n    instructions: [{ body: 'Implement a retry function with exponential backoff.' }],\n    outputContracts: [{ body: 'Return a concise implementation report with test results.' }],\n  },\n  { contextMaxChars: 8000 },\n);\n\n// result.systemPrompt → \"You are a senior TypeScript developer.\"\n// result.userMessage  → knowledge + instructions + output contracts + policies (in order)\n```\n\n### As a CLI\n\n```bash\n# Create local .faceted/ in current directory\nfacet init\n\n# Initialize global ~/.faceted/ and pull sample facets\nfacet init global\n\n# Pull sample facets from TAKT on GitHub\nfacet pull-sample\n\n# Compose prompts with auto-detected context\nfacet compose\n\n# Install a skill to Claude Code or Codex\nfacet install skill\n```\n\n`facet init` creates `.faceted/` in the current directory with config and empty directories. `facet init global` initializes `~/.faceted/` and pulls sample facets. Run `facet pull-sample` to update sample facets, compositions, and templates:\n\n```\n.faceted/                       # Local (per-project)\n├── config.yaml\n├── facets/\n│   ├── persona/\n│   ├── knowledge/\n│   ├── policies/\n│   ├── instructions/\n│   ├── partials/\n│   │   ├── instructions/\n│   │   ├── policies/\n│   │   ├── knowledge/\n│   │   └── output-contracts/\n│   └── output-contracts/\n├── compositions/\n└── templates/\n\n~/.faceted/                     # Global (fallback)\n├── config.yaml\n├── facets/\n│   ├── persona/          # Persona Markdown files\n│   ├── knowledge/        # Domain knowledge files\n│   ├── policies/         # Policy/rules files\n│   ├── instructions/     # Instruction files\n│   ├── partials/\n│   │   ├── instructions/ # Reusable Markdown partials by facet kind\n│   │   ├── policies/\n│   │   ├── knowledge/\n│   │   └── output-contracts/\n│   └── output-contracts/ # Output/report format files\n├── compositions/         # Compose definition YAML files\n└── templates/            # Skill templates\n```\n\n## CLI Commands\n\n| Command | Description |\n|---------|-------------|\n| `facet init` | Create local `.faceted/` in current directory |\n| `facet init global` | Initialize global `~/.faceted/` and pull sample facets |\n| `facet pull-sample` | Pull sample coding facets from TAKT on GitHub |\n| `facet compose` | Auto-detect context, compose prompts, and write to files |\n| `facet install skill` | Install a skill with facets to Claude Code or Codex |\n\nSee the [CLI Reference](./docs/cli-reference.md) for details.\n\n## Compose Definition\n\nPlace definition files in `~/.faceted/compositions/*.yaml`:\n\n```yaml\nname: release\ndescription: Release summary composition\npersona: coder\nknowledge:\n  - architecture\npolicies:\n  - quality\ninstructions:\n  - release-summary\noutput-contracts:\n  - concise-report\norder:\n  - knowledge\n  - instructions\n  - output-contracts\n  - policies\n```\n\n- `name` and `persona` are required.\n- `order` controls user-message section order (default: `knowledge` -> `instructions` -> `output-contracts` -> `policies`).\n- `instructions` is a list of instruction facet names, Markdown file paths, scope references, or inline Markdown text.\n- `output-contracts` is a list of facet names, file paths, or scope references and is exposed as `outputContracts` in the TypeScript API.\n- Relative file paths are resolved from the compose definition directory. Real paths must stay inside that directory or the configured facets roots; symlinks and paths outside those roots fail.\n\nFile-backed instruction, policy, knowledge, and output-contract facet files can include shared Markdown partials:\n\n```md\nReview the change for mergeable quality.\n\n{{include:instructions/review-common}}\n```\n\nThe include above resolves to `facets/partials/instructions/review-common.md` and expands at the include site before prompt composition. Supported include kinds are `instructions`, `policies`, `knowledge`, and `output-contracts`. The syntax is `{{include:<kind>/<name>}}` for local/global partials and `{{include:<kind>/@owner/repo/<name>}}` for repertoire partials under `repertoire/@owner/repo/facets/partials/<kind>/<name>.md`; shortened forms such as `{{include:review-common}}` are invalid.\n\nFacet partials use the same local-first layering as facets: `.faceted/facets/partials/<kind>/` is checked before `~/.faceted/facets/partials/<kind>/`. Missing includes, empty include names, shortened syntax, cyclic include chains, paths that escape the allowed roots, and partial paths that resolve to directories or other non-file targets fail with explicit errors. Include tokens inside inline instruction text are not expanded. `composePromptPayload().copyFiles.facetPartials` is present only when included partial paths exist; `copyFiles.instructionPartials` is retained for compatibility with existing instruction partial consumers.\n\n## Scope References\n\nReference facets from installed repertoire packages using `@owner/repo/facet-name` syntax:\n\n```yaml\npersona: \"@nrslib/takt-fullstack/expert-coder\"\nknowledge:\n  - \"@nrslib/takt-fullstack/architecture\"\n```\n\nScope references require repertoire roots and resolve to `~/.faceted/repertoire/@{owner}/{repo}/facets/{kind}/{name}.md`.\n\n## API\n\n### `compose(facets, options)`\n\nCore composition function. Takes a `FacetSet` and `ComposeOptions`, returns a `ComposedPrompt` with `systemPrompt` and `userMessage`.\n\n### `composePromptPayload(params)`\n\nHigher-level API that composes prompts from a `ComposeDefinition` and also returns `copyFiles` metadata listing the source file paths used.\n\n### `FileDataEngine`\n\nFile-system backed facet loader. Reads `{root}/{kind}/{key}.md`.\n\n```typescript\nimport { FileDataEngine } from 'faceted-prompting';\n\nconst engine = new FileDataEngine('./prompts');\nconst persona = await engine.resolve('personas', 'coder');\n```\n\n### `CompositeDataEngine`\n\nChains multiple `DataEngine` instances with first-match-wins resolution. Useful for layering project-level facets over global defaults.\n\n```typescript\nimport { FileDataEngine, CompositeDataEngine } from 'faceted-prompting';\n\nconst engine = new CompositeDataEngine([\n  new FileDataEngine('./project/facets'),   // project-level (wins)\n  new FileDataEngine('~/.faceted/facets'),   // global fallback\n]);\n```\n\n### `renderTemplate(template, vars)`\n\nMinimal template engine with `{{variable}}` substitution and `{{#if var}}...{{else}}...{{/if}}` conditionals.\n\n### `escapeTemplateChars(str)`\n\nEscapes curly braces to full-width Unicode equivalents to prevent template injection in user-supplied content.\n\nSee the [API Reference](./docs/api-reference.md) for the full API surface.\n\n## Project Structure\n\n```\n.faceted/                       # Local (per-project, created by `facet init`)\n├── config.yaml\n├── facets/\n│   ├── persona/\n│   ├── knowledge/\n│   ├── policies/\n│   ├── instructions/\n│   └── output-contracts/\n├── compositions/\n└── templates/\n\n~/.faceted/                     # Global (fallback, created by `facet init global`)\n├── config.yaml\n├── facets/\n│   ├── persona/\n│   ├── knowledge/\n│   ├── policies/\n│   ├── instructions/\n│   └── output-contracts/\n├── compositions/\n├── templates/                  # Skill install templates\n└── repertoire/                 # Installed repertoire packages\n```\n\nFacet resolution is local-first: local `.faceted/facets/` is checked before global `~/.faceted/facets/`.\n\n## Documentation\n\n| Document | Description |\n|----------|-------------|\n| [Concepts](./docs/concepts.md) | Faceted Prompting design methodology |\n| [CLI Reference](./docs/cli-reference.md) | All commands and options |\n| [API Reference](./docs/api-reference.md) | Library API surface |\n| [Changelog](./CHANGELOG.md) | Version history |\n\n## Contributing\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md) for details.\n\n## License\n\nMIT — See [LICENSE](./LICENSE) for details.\n","readmeFilename":"README.md"}