faceted-prompting 0.3.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/README.md +39 -12
  2. package/dist/cli/compose-command.d.ts +2 -2
  3. package/dist/cli/compose-command.d.ts.map +1 -1
  4. package/dist/cli/compose-command.js +16 -145
  5. package/dist/cli/compose-command.js.map +1 -1
  6. package/dist/cli/compose-definition-resolution.d.ts +12 -0
  7. package/dist/cli/compose-definition-resolution.d.ts.map +1 -0
  8. package/dist/cli/compose-definition-resolution.js +50 -0
  9. package/dist/cli/compose-definition-resolution.js.map +1 -0
  10. package/dist/cli/compose-execution.d.ts +19 -0
  11. package/dist/cli/compose-execution.d.ts.map +1 -0
  12. package/dist/cli/compose-execution.js +167 -0
  13. package/dist/cli/compose-execution.js.map +1 -0
  14. package/dist/cli/compose-options.d.ts +4 -0
  15. package/dist/cli/compose-options.d.ts.map +1 -0
  16. package/dist/cli/compose-options.js +64 -0
  17. package/dist/cli/compose-options.js.map +1 -0
  18. package/dist/cli/index.d.ts.map +1 -1
  19. package/dist/cli/index.js +2 -1
  20. package/dist/cli/index.js.map +1 -1
  21. package/dist/cli/install-skill/facet-token-renderer.d.ts +1 -1
  22. package/dist/cli/install-skill/facet-token-renderer.d.ts.map +1 -1
  23. package/dist/cli/install-skill/facet-token-renderer.js +2 -2
  24. package/dist/cli/install-skill/facet-token-renderer.js.map +1 -1
  25. package/dist/cli/install-skill/facets.d.ts +2 -0
  26. package/dist/cli/install-skill/facets.d.ts.map +1 -1
  27. package/dist/cli/install-skill/facets.js +43 -4
  28. package/dist/cli/install-skill/facets.js.map +1 -1
  29. package/dist/cli/install-skill/flow.d.ts +2 -1
  30. package/dist/cli/install-skill/flow.d.ts.map +1 -1
  31. package/dist/cli/install-skill/flow.js +7 -2
  32. package/dist/cli/install-skill/flow.js.map +1 -1
  33. package/dist/cli/install-skill/instruction-partial-copy.d.ts +6 -0
  34. package/dist/cli/install-skill/instruction-partial-copy.d.ts.map +1 -0
  35. package/dist/cli/install-skill/instruction-partial-copy.js +32 -0
  36. package/dist/cli/install-skill/instruction-partial-copy.js.map +1 -0
  37. package/dist/cli/install-skill/modes.d.ts +3 -1
  38. package/dist/cli/install-skill/modes.d.ts.map +1 -1
  39. package/dist/cli/install-skill/modes.js +16 -14
  40. package/dist/cli/install-skill/modes.js.map +1 -1
  41. package/dist/cli/install-skill/targets.d.ts +4 -3
  42. package/dist/cli/install-skill/targets.d.ts.map +1 -1
  43. package/dist/cli/install-skill/targets.js +18 -4
  44. package/dist/cli/install-skill/targets.js.map +1 -1
  45. package/dist/cli/instruction-includes.d.ts +11 -0
  46. package/dist/cli/instruction-includes.d.ts.map +1 -0
  47. package/dist/cli/instruction-includes.js +130 -0
  48. package/dist/cli/instruction-includes.js.map +1 -0
  49. package/dist/cli/path-guard.d.ts +5 -0
  50. package/dist/cli/path-guard.d.ts.map +1 -1
  51. package/dist/cli/path-guard.js +25 -0
  52. package/dist/cli/path-guard.js.map +1 -1
  53. package/dist/cli/skill-commands.d.ts +8 -0
  54. package/dist/cli/skill-commands.d.ts.map +1 -1
  55. package/dist/cli/skill-commands.js +23 -6
  56. package/dist/cli/skill-commands.js.map +1 -1
  57. package/dist/cli/skill-document-renderer.d.ts +6 -0
  58. package/dist/cli/skill-document-renderer.d.ts.map +1 -0
  59. package/dist/cli/skill-document-renderer.js +73 -0
  60. package/dist/cli/skill-document-renderer.js.map +1 -0
  61. package/dist/cli/skill-file-ops.d.ts +1 -2
  62. package/dist/cli/skill-file-ops.d.ts.map +1 -1
  63. package/dist/cli/skill-file-ops.js +12 -38
  64. package/dist/cli/skill-file-ops.js.map +1 -1
  65. package/dist/cli/skill-renderer.d.ts +5 -3
  66. package/dist/cli/skill-renderer.d.ts.map +1 -1
  67. package/dist/cli/skill-renderer.js +98 -75
  68. package/dist/cli/skill-renderer.js.map +1 -1
  69. package/dist/cli/skill-types.d.ts +6 -2
  70. package/dist/cli/skill-types.d.ts.map +1 -1
  71. package/dist/cli/types.d.ts +6 -0
  72. package/dist/cli/types.d.ts.map +1 -1
  73. package/dist/compose-definition.d.ts.map +1 -1
  74. package/dist/compose-definition.js +4 -1
  75. package/dist/compose-definition.js.map +1 -1
  76. package/dist/compose.d.ts +3 -2
  77. package/dist/compose.d.ts.map +1 -1
  78. package/dist/compose.js +30 -33
  79. package/dist/compose.js.map +1 -1
  80. package/dist/config/index.d.ts +12 -0
  81. package/dist/config/index.d.ts.map +1 -1
  82. package/dist/config/index.js +44 -2
  83. package/dist/config/index.js.map +1 -1
  84. package/dist/config/install-targets.d.ts +6 -0
  85. package/dist/config/install-targets.d.ts.map +1 -0
  86. package/dist/config/install-targets.js +71 -0
  87. package/dist/config/install-targets.js.map +1 -0
  88. package/dist/index.d.ts +1 -1
  89. package/dist/index.d.ts.map +1 -1
  90. package/dist/index.js.map +1 -1
  91. package/dist/init/index.d.ts.map +1 -1
  92. package/dist/init/index.js +9 -1
  93. package/dist/init/index.js.map +1 -1
  94. package/dist/install-targets.d.ts +2 -0
  95. package/dist/install-targets.d.ts.map +1 -0
  96. package/dist/install-targets.js +2 -0
  97. package/dist/install-targets.js.map +1 -0
  98. package/dist/instruction-partial-paths.d.ts +3 -0
  99. package/dist/instruction-partial-paths.d.ts.map +1 -0
  100. package/dist/instruction-partial-paths.js +6 -0
  101. package/dist/instruction-partial-paths.js.map +1 -0
  102. package/dist/prompt-payload.d.ts +1 -0
  103. package/dist/prompt-payload.d.ts.map +1 -1
  104. package/dist/prompt-payload.js +26 -8
  105. package/dist/prompt-payload.js.map +1 -1
  106. package/dist/types.d.ts +9 -4
  107. package/dist/types.d.ts.map +1 -1
  108. package/dist/types.js +7 -2
  109. package/dist/types.js.map +1 -1
  110. package/package.json +3 -3
package/README.md CHANGED
@@ -4,15 +4,15 @@
4
4
 
5
5
  Structured prompt composition for LLMs — decompose prompts into reusable facets and compose them into LLM-ready messages.
6
6
 
7
- faceted-prompting separates prompt concerns into distinct facets (persona, policy, knowledge, instruction), each with a defined role and message placement. This keeps prompts modular, testable, and maintainable as they grow in complexity.
7
+ faceted-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.
8
8
 
9
9
  ## Why Faceted Prompting
10
10
 
11
- **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*, and instructions define *what to do*. Changes to one facet don't affect others.
11
+ **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.
12
12
 
13
- **Deterministic placement** — Persona always goes to the system prompt. Policies, knowledge, and instructions always go to the user message. This placement rule is enforced by the library, not left to convention.
13
+ **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.
14
14
 
15
- **Composable** — Facets are plain Markdown files. Mix and match personas, policies, and knowledge across different workflows. Share them as repertoire packages via `@owner/repo/facet-name` scope references.
15
+ **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.
16
16
 
17
17
  **Framework-independent** — Zero dependencies on any specific AI framework. Use it with Claude, OpenAI, or any LLM provider.
18
18
 
@@ -24,6 +24,7 @@ faceted-prompting separates prompt concerns into distinct facets (persona, polic
24
24
  | **Policy** | User message | HOW — rules, standards, constraints |
25
25
  | **Knowledge** | User message | WHAT TO KNOW — domain context, architecture |
26
26
  | **Instruction** | User message | WHAT TO DO — the specific task |
27
+ | **Output contracts** | User message | HOW TO ANSWER — output/report format |
27
28
 
28
29
  ## Install
29
30
 
@@ -52,12 +53,13 @@ const result = compose(
52
53
  policies: [{ body: 'Follow clean code principles. No any types.' }],
53
54
  knowledge: [{ body: 'The project uses Vitest for testing.' }],
54
55
  instructions: [{ body: 'Implement a retry function with exponential backoff.' }],
56
+ outputContracts: [{ body: 'Return a concise implementation report with test results.' }],
55
57
  },
56
58
  { contextMaxChars: 8000 },
57
59
  );
58
60
 
59
61
  // result.systemPrompt → "You are a senior TypeScript developer."
60
- // result.userMessage → knowledge + instructions + policies (in order)
62
+ // result.userMessage → knowledge + instructions + output contracts + policies (in order)
61
63
  ```
62
64
 
63
65
  ### As a CLI
@@ -89,7 +91,10 @@ facet install skill
89
91
  │ ├── knowledge/
90
92
  │ ├── policies/
91
93
  │ ├── instructions/
92
- └── compositions/
94
+ ├── partials/
95
+ │ │ └── instructions/
96
+ │ └── output-contracts/
97
+ ├── compositions/
93
98
  └── templates/
94
99
 
95
100
  ~/.faceted/ # Global (fallback)
@@ -99,7 +104,10 @@ facet install skill
99
104
  │ ├── knowledge/ # Domain knowledge files
100
105
  │ ├── policies/ # Policy/rules files
101
106
  │ ├── instructions/ # Instruction files
102
- └── compositions/ # Compose definition YAML files
107
+ ├── partials/
108
+ │ │ └── instructions/ # Reusable instruction-only Markdown partials
109
+ │ └── output-contracts/ # Output/report format files
110
+ ├── compositions/ # Compose definition YAML files
103
111
  └── templates/ # Skill templates
104
112
  ```
105
113
 
@@ -129,15 +137,32 @@ policies:
129
137
  - quality
130
138
  instructions:
131
139
  - release-summary
140
+ output-contracts:
141
+ - concise-report
132
142
  order:
133
143
  - knowledge
134
144
  - instructions
145
+ - output-contracts
135
146
  - policies
136
147
  ```
137
148
 
138
149
  - `name` and `persona` are required.
139
- - `order` controls user-message section order (default: `knowledge` `instructions` `policies`).
140
- - `instructions` is a list of facet file references.
150
+ - `order` controls user-message section order (default: `knowledge` -> `instructions` -> `output-contracts` -> `policies`).
151
+ - `instructions` is a list of instruction facet names, Markdown file paths, scope references, or inline Markdown text.
152
+ - `output-contracts` is a list of facet names, file paths, or scope references and is exposed as `outputContracts` in the TypeScript API.
153
+ - 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.
154
+
155
+ Instruction facet files can include shared Markdown partials:
156
+
157
+ ```md
158
+ Review the change for mergeable quality.
159
+
160
+ {{include:instructions/review-common}}
161
+ ```
162
+
163
+ The include above resolves to `facets/partials/instructions/review-common.md` and expands at the include site before prompt composition. Includes are supported only in instruction facets. The supported syntax is `{{include:instructions/<name>}}` for local/global partials and `{{include:instructions/@owner/repo/<name>}}` for repertoire partials under `repertoire/@owner/repo/facets/partials/instructions/<name>.md`; shortened forms such as `{{include:review-common}}` are invalid.
164
+
165
+ Instruction partials use the same local-first layering as facets: `.faceted/facets/partials/instructions/` is checked before `~/.faceted/facets/partials/instructions/`. Missing includes and cyclic include chains fail with explicit errors. `composePromptPayload().copyFiles.instructions` includes instruction facet paths, and `composePromptPayload().copyFiles.instructionPartials` is present only when included partial paths exist.
141
166
 
142
167
  ## Scope References
143
168
 
@@ -149,7 +174,7 @@ knowledge:
149
174
  - "@nrslib/takt-fullstack/architecture"
150
175
  ```
151
176
 
152
- Scope references resolve to `~/.faceted/repertoire/@{owner}/{repo}/facets/{kind}/{name}.md`.
177
+ Scope references require repertoire roots and resolve to `~/.faceted/repertoire/@{owner}/{repo}/facets/{kind}/{name}.md`.
153
178
 
154
179
  ## API
155
180
 
@@ -205,7 +230,8 @@ See the [API Reference](./docs/api-reference.md) for the full API surface.
205
230
  │ ├── knowledge/
206
231
  │ ├── policies/
207
232
  │ ├── instructions/
208
- │ └── compositions/
233
+ │ └── output-contracts/
234
+ ├── compositions/
209
235
  └── templates/
210
236
 
211
237
  ~/.faceted/ # Global (fallback, created by `facet init global`)
@@ -215,7 +241,8 @@ See the [API Reference](./docs/api-reference.md) for the full API surface.
215
241
  │ ├── knowledge/
216
242
  │ ├── policies/
217
243
  │ ├── instructions/
218
- │ └── compositions/
244
+ │ └── output-contracts/
245
+ ├── compositions/
219
246
  ├── templates/ # Skill install templates
220
247
  └── repertoire/ # Installed repertoire packages
221
248
  ```
@@ -1,3 +1,3 @@
1
- import type { FacetCliOptions, FacetCliResult } from './types.js';
2
- export declare function runComposeCommand(options: FacetCliOptions): Promise<FacetCliResult>;
1
+ import type { ComposeCliOptions, FacetCliOptions, FacetCliResult } from './types.js';
2
+ export declare function runComposeCommand(options: FacetCliOptions, composeOptions: ComposeCliOptions): Promise<FacetCliResult>;
3
3
  //# sourceMappingURL=compose-command.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"compose-command.d.ts","sourceRoot":"","sources":["../../src/cli/compose-command.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AA8KlE,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CA+BzF"}
1
+ {"version":3,"file":"compose-command.d.ts","sourceRoot":"","sources":["../../src/cli/compose-command.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAErF,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,eAAe,EACxB,cAAc,EAAE,iBAAiB,GAChC,OAAO,CAAC,cAAc,CAAC,CAyBzB"}
@@ -1,156 +1,27 @@
1
- import { existsSync, mkdirSync } from 'node:fs';
2
- import { dirname, resolve } from 'node:path';
3
- import { compose } from '../compose.js';
4
- import { loadComposeDefinition } from '../compose-definition.js';
5
- import { formatCombinedOutput, resolveOutputDirectory, writeComposeOutput } from '../output/index.js';
6
- import { buildFacetSet, buildSkillSections, ensureSafeDefinitionName, } from './skill-renderer.js';
7
- import { getSkillPaths, selectCompositionDefinitionPath, } from './skill-commands.js';
8
- import { collectDirectoryFiles, copyDirectoryTree, ensureTemplateDirectoryFromRoots, shouldOverwrite, } from './install-skill/flow.js';
9
- import { applyFacetTokensToFiles, buildInlineFacetTokenValues } from './install-skill/facets.js';
10
- import { ensurePathAncestorsContainNoSymbolicLinks, ensurePathIsNotSymbolicLink } from './path-guard.js';
11
- function buildComposeOutputPlans(params) {
12
- if (params.splitSystem) {
13
- return [
14
- {
15
- fileName: `${params.safeName}.system.md`,
16
- content: `${params.systemPrompt}\n`,
17
- },
18
- {
19
- fileName: `${params.safeName}.user.md`,
20
- content: `${params.userMessage}\n`,
21
- },
22
- ];
23
- }
24
- return [
25
- {
26
- fileName: `${params.safeName}.md`,
27
- content: formatCombinedOutput({
28
- systemPrompt: params.systemPrompt,
29
- userMessage: params.userMessage,
30
- }),
31
- },
32
- ];
33
- }
34
- async function confirmOverwriteForExistingPaths(params) {
35
- if (params.existingPaths.length === 0) {
36
- return false;
37
- }
38
- const overwriteAnswer = await params.options.input(`${params.promptMessage} (${params.existingPaths.join(', ')}) [y/N]`, 'n');
39
- if (!shouldOverwrite(overwriteAnswer)) {
40
- throw new Error(`${params.cancelMessage}: ${params.existingPaths.join(', ')}`);
41
- }
42
- return true;
43
- }
44
- async function runTemplateBackedCompose(params) {
45
- const templateName = params.definition.template;
46
- if (!templateName) {
47
- throw new Error(`Template-backed compose requires template: ${params.definition.name}`);
48
- }
49
- const templateDir = ensureTemplateDirectoryFromRoots(params.facetedRoots, templateName, dirname(params.definitionPath));
50
- const outputInput = await params.options.input('Output directory', params.options.cwd);
51
- const outputDir = resolveOutputDirectory(outputInput, params.options.cwd);
52
- ensurePathIsNotSymbolicLink(outputDir, 'Output directory');
53
- ensurePathAncestorsContainNoSymbolicLinks(outputDir, 'Output directory', params.options.cwd);
54
- mkdirSync(outputDir, { recursive: true });
55
- const templateRelativePaths = collectDirectoryFiles(templateDir);
56
- const templateOutputPaths = templateRelativePaths.map(relativePath => resolve(outputDir, relativePath));
57
- await confirmOverwriteForExistingPaths({
58
- options: params.options,
59
- existingPaths: templateOutputPaths.filter(path => existsSync(path)),
60
- promptMessage: 'Output files exist. Overwrite?',
61
- cancelMessage: 'Output files exist and overwrite was cancelled',
62
- });
63
- copyDirectoryTree(templateDir, outputDir);
64
- const sections = buildSkillSections({
65
- definition: params.definition,
66
- definitionDir: dirname(params.definitionPath),
67
- facetsRoots: params.facetsRoots,
68
- });
69
- applyFacetTokensToFiles({
70
- filePaths: templateOutputPaths.filter(path => existsSync(path)),
71
- tokenValues: buildInlineFacetTokenValues(sections),
72
- rootDir: outputDir,
73
- });
74
- return {
75
- kind: 'path',
76
- path: outputDir,
77
- };
78
- }
79
- async function runStandardCompose(params) {
80
- const safeName = ensureSafeDefinitionName(params.definition.name);
81
- const facetSet = buildFacetSet({
82
- definitionDir: dirname(params.definitionPath),
83
- facetsRoots: params.facetsRoots,
84
- definition: params.definition,
85
- });
86
- const composed = compose(facetSet, {
87
- contextMaxChars: 2000,
88
- userMessageOrder: params.definition.order,
89
- });
90
- const splitSelection = await params.options.select(['Combined (single file)', 'Split (system + user)'], 'Choose output mode with Up/Down and Enter:');
91
- const outputPlans = buildComposeOutputPlans({
92
- safeName,
93
- systemPrompt: composed.systemPrompt,
94
- userMessage: composed.userMessage,
95
- splitSystem: splitSelection === 'Split (system + user)',
96
- });
97
- const outputInput = await params.options.input('Output directory', params.options.cwd);
98
- const outputDir = resolveOutputDirectory(outputInput, params.options.cwd);
99
- const existingPaths = outputPlans
100
- .map(plan => resolve(outputDir, plan.fileName))
101
- .filter(path => existsSync(path));
102
- const overwrite = await confirmOverwriteForExistingPaths({
103
- options: params.options,
104
- existingPaths,
105
- promptMessage: 'Output file exists. Overwrite?',
106
- cancelMessage: 'Output file exists and overwrite was cancelled',
107
- });
108
- const outputPaths = [];
109
- for (const plan of outputPlans) {
110
- outputPaths.push(await writeComposeOutput({
111
- outputDir,
112
- fileName: plan.fileName,
113
- content: plan.content,
114
- overwrite,
115
- }));
116
- }
117
- if (outputPaths.length === 1) {
118
- return {
119
- kind: 'path',
120
- path: outputPaths[0],
121
- };
122
- }
123
- return {
124
- kind: 'paths',
125
- paths: outputPaths,
126
- };
127
- }
128
- export async function runComposeCommand(options) {
129
- const { facetedRoots, facetsRoots, compositionsDirs } = getSkillPaths(options.cwd, options.homeDir);
130
- const localCompositionsDir = facetedRoots.length > 1 ? resolve(facetedRoots[0], 'compositions') : undefined;
131
- const globalCompositionsDir = resolve(facetedRoots[facetedRoots.length - 1], 'compositions');
132
- const { definitionPath } = await selectCompositionDefinitionPath({
1
+ import { resolveComposeDefinition } from './compose-definition-resolution.js';
2
+ import { runStandardCompose, runTemplateBackedCompose } from './compose-execution.js';
3
+ export async function runComposeCommand(options, composeOptions) {
4
+ const resolved = await resolveComposeDefinition({
133
5
  options,
134
- compositionDefinitionDirs: compositionsDirs,
135
- localCompositionsDir,
136
- globalCompositionsDir,
137
- cancelAction: 'Compose',
6
+ composeOptions,
138
7
  });
139
- const definition = await loadComposeDefinition(definitionPath);
140
- if (definition.template) {
8
+ if (resolved.definition.template) {
141
9
  return runTemplateBackedCompose({
142
10
  options,
143
- facetedRoots,
144
- facetsRoots,
145
- definitionPath,
146
- definition,
11
+ facetedRoots: resolved.facetedRoots,
12
+ facetsRoots: resolved.facetsRoots,
13
+ definitionPath: resolved.definitionPath,
14
+ definition: resolved.definition,
15
+ composeOptions,
147
16
  });
148
17
  }
149
18
  return runStandardCompose({
150
19
  options,
151
- facetsRoots,
152
- definitionPath,
153
- definition,
20
+ facetedRoots: resolved.facetedRoots,
21
+ facetsRoots: resolved.facetsRoots,
22
+ definitionPath: resolved.definitionPath,
23
+ definition: resolved.definition,
24
+ composeOptions,
154
25
  });
155
26
  }
156
27
  //# sourceMappingURL=compose-command.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"compose-command.js","sourceRoot":"","sources":["../../src/cli/compose-command.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compose-command.js","sourceRoot":"","sources":["../../src/cli/compose-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,oCAAoC,CAAC;AAC9E,OAAO,EAAE,kBAAkB,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAGtF,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAwB,EACxB,cAAiC;IAEjC,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAAC;QAC9C,OAAO;QACP,cAAc;KACf,CAAC,CAAC;IAEH,IAAI,QAAQ,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;QACjC,OAAO,wBAAwB,CAAC;YAC9B,OAAO;YACP,YAAY,EAAE,QAAQ,CAAC,YAAY;YACnC,WAAW,EAAE,QAAQ,CAAC,WAAW;YACjC,cAAc,EAAE,QAAQ,CAAC,cAAc;YACvC,UAAU,EAAE,QAAQ,CAAC,UAAU;YAC/B,cAAc;SACf,CAAC,CAAC;IACL,CAAC;IAED,OAAO,kBAAkB,CAAC;QACxB,OAAO;QACP,YAAY,EAAE,QAAQ,CAAC,YAAY;QACnC,WAAW,EAAE,QAAQ,CAAC,WAAW;QACjC,cAAc,EAAE,QAAQ,CAAC,cAAc;QACvC,UAAU,EAAE,QAAQ,CAAC,UAAU;QAC/B,cAAc;KACf,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { ComposeDefinition } from '../types.js';
2
+ import type { ComposeCliOptions, FacetCliOptions } from './types.js';
3
+ export declare function resolveComposeDefinition(params: {
4
+ options: FacetCliOptions;
5
+ composeOptions: ComposeCliOptions;
6
+ }): Promise<{
7
+ facetedRoots: readonly string[];
8
+ facetsRoots: readonly string[];
9
+ definitionPath: string;
10
+ definition: ComposeDefinition;
11
+ }>;
12
+ //# sourceMappingURL=compose-definition-resolution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compose-definition-resolution.d.ts","sourceRoot":"","sources":["../../src/cli/compose-definition-resolution.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AA0BrE,wBAAsB,wBAAwB,CAAC,MAAM,EAAE;IACrD,OAAO,EAAE,eAAe,CAAC;IACzB,cAAc,EAAE,iBAAiB,CAAC;CACnC,GAAG,OAAO,CAAC;IACV,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,iBAAiB,CAAC;CAC/B,CAAC,CAqCD"}
@@ -0,0 +1,50 @@
1
+ import { loadComposeDefinition } from '../compose-definition.js';
2
+ import { isNonInteractiveMode } from './compose-options.js';
3
+ import { getSkillPaths, resolveCompositionDefinitionPathByName, selectCompositionDefinitionPath } from './skill-commands.js';
4
+ function requireCompositionName(composeOptions) {
5
+ if (!composeOptions.composition) {
6
+ throw new Error('Non-interactive compose requires --composition');
7
+ }
8
+ return composeOptions.composition;
9
+ }
10
+ function validateNonInteractiveComposeOptions(params) {
11
+ if (params.definition.template) {
12
+ if (params.composeOptions.outputMode) {
13
+ throw new Error('Template-backed compose does not support --split or --combined');
14
+ }
15
+ return;
16
+ }
17
+ if (!params.composeOptions.outputMode) {
18
+ throw new Error('Non-interactive standard compose requires --split or --combined');
19
+ }
20
+ }
21
+ export async function resolveComposeDefinition(params) {
22
+ const { facetedRoots, facetsRoots, compositionsDirs, localCompositionsDir, globalCompositionsDir, } = getSkillPaths(params.options.cwd, params.options.homeDir);
23
+ const nonInteractive = isNonInteractiveMode(params.composeOptions);
24
+ const definitionPath = nonInteractive
25
+ ? resolveCompositionDefinitionPathByName({
26
+ compositionName: requireCompositionName(params.composeOptions),
27
+ compositionDefinitionDirs: compositionsDirs,
28
+ }).definitionPath
29
+ : (await selectCompositionDefinitionPath({
30
+ options: params.options,
31
+ compositionDefinitionDirs: compositionsDirs,
32
+ localCompositionsDir,
33
+ globalCompositionsDir,
34
+ cancelAction: 'Compose',
35
+ })).definitionPath;
36
+ const definition = await loadComposeDefinition(definitionPath);
37
+ if (nonInteractive) {
38
+ validateNonInteractiveComposeOptions({
39
+ composeOptions: params.composeOptions,
40
+ definition,
41
+ });
42
+ }
43
+ return {
44
+ facetedRoots,
45
+ facetsRoots,
46
+ definitionPath,
47
+ definition,
48
+ };
49
+ }
50
+ //# sourceMappingURL=compose-definition-resolution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compose-definition-resolution.js","sourceRoot":"","sources":["../../src/cli/compose-definition-resolution.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,sCAAsC,EAAE,+BAA+B,EAAE,MAAM,qBAAqB,CAAC;AAG7H,SAAS,sBAAsB,CAAC,cAAiC;IAC/D,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,cAAc,CAAC,WAAW,CAAC;AACpC,CAAC;AAED,SAAS,oCAAoC,CAAC,MAG7C;IACC,IAAI,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;QAC/B,IAAI,MAAM,CAAC,cAAc,CAAC,UAAU,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;QACpF,CAAC;QACD,OAAO;IACT,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,UAAU,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;IACrF,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,MAG9C;IAMC,MAAM,EACJ,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,GACtB,GAAG,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9D,MAAM,cAAc,GAAG,oBAAoB,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;IAEnE,MAAM,cAAc,GAAG,cAAc;QACnC,CAAC,CAAC,sCAAsC,CAAC;YACvC,eAAe,EAAE,sBAAsB,CAAC,MAAM,CAAC,cAAc,CAAC;YAC9D,yBAAyB,EAAE,gBAAgB;SAC5C,CAAC,CAAC,cAAc;QACjB,CAAC,CAAC,CAAC,MAAM,+BAA+B,CAAC;YACvC,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,yBAAyB,EAAE,gBAAgB;YAC3C,oBAAoB;YACpB,qBAAqB;YACrB,YAAY,EAAE,SAAS;SACxB,CAAC,CAAC,CAAC,cAAc,CAAC;IAErB,MAAM,UAAU,GAAG,MAAM,qBAAqB,CAAC,cAAc,CAAC,CAAC;IAC/D,IAAI,cAAc,EAAE,CAAC;QACnB,oCAAoC,CAAC;YACnC,cAAc,EAAE,MAAM,CAAC,cAAc;YACrC,UAAU;SACX,CAAC,CAAC;IACL,CAAC;IAED,OAAO;QACL,YAAY;QACZ,WAAW;QACX,cAAc;QACd,UAAU;KACX,CAAC;AACJ,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { ComposeDefinition } from '../types.js';
2
+ import type { ComposeCliOptions, FacetCliOptions, FacetCliResult } from './types.js';
3
+ export declare function runTemplateBackedCompose(params: {
4
+ options: FacetCliOptions;
5
+ facetedRoots: readonly string[];
6
+ facetsRoots: readonly string[];
7
+ definitionPath: string;
8
+ definition: ComposeDefinition;
9
+ composeOptions: ComposeCliOptions;
10
+ }): Promise<FacetCliResult>;
11
+ export declare function runStandardCompose(params: {
12
+ options: FacetCliOptions;
13
+ facetedRoots: readonly string[];
14
+ facetsRoots: readonly string[];
15
+ definitionPath: string;
16
+ definition: ComposeDefinition;
17
+ composeOptions: ComposeCliOptions;
18
+ }): Promise<FacetCliResult>;
19
+ //# sourceMappingURL=compose-execution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compose-execution.d.ts","sourceRoot":"","sources":["../../src/cli/compose-execution.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAOrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAuFrF,wBAAsB,wBAAwB,CAAC,MAAM,EAAE;IACrD,OAAO,EAAE,eAAe,CAAC;IACzB,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,iBAAiB,CAAC;IAC9B,cAAc,EAAE,iBAAiB,CAAC;CACnC,GAAG,OAAO,CAAC,cAAc,CAAC,CAmD1B;AAED,wBAAsB,kBAAkB,CAAC,MAAM,EAAE;IAC/C,OAAO,EAAE,eAAe,CAAC;IACzB,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,iBAAiB,CAAC;IAC9B,cAAc,EAAE,iBAAiB,CAAC;CACnC,GAAG,OAAO,CAAC,cAAc,CAAC,CAuE1B"}
@@ -0,0 +1,167 @@
1
+ import { existsSync, mkdirSync } from 'node:fs';
2
+ import { dirname, resolve } from 'node:path';
3
+ import { compose } from '../compose.js';
4
+ import { formatCombinedOutput, resolveOutputDirectory, writeComposeOutput } from '../output/index.js';
5
+ import { isNonInteractiveMode } from './compose-options.js';
6
+ import { buildFacetSet, buildSkillSections, ensureSafeDefinitionName, } from './skill-renderer.js';
7
+ import { collectDirectoryFiles, copyDirectoryTree, ensureTemplateDirectoryFromRoots, shouldOverwrite, } from './install-skill/flow.js';
8
+ import { applyFacetTokensToFiles, buildInlineFacetTokenValues } from './install-skill/facets.js';
9
+ import { ensurePathAncestorsContainNoSymbolicLinks, ensurePathIsNotSymbolicLink } from './path-guard.js';
10
+ function buildComposeOutputPlans(params) {
11
+ if (params.splitSystem) {
12
+ return [
13
+ {
14
+ fileName: `${params.safeName}.system.md`,
15
+ content: `${params.systemPrompt}\n`,
16
+ },
17
+ {
18
+ fileName: `${params.safeName}.user.md`,
19
+ content: `${params.userMessage}\n`,
20
+ },
21
+ ];
22
+ }
23
+ return [
24
+ {
25
+ fileName: `${params.safeName}.md`,
26
+ content: formatCombinedOutput({
27
+ systemPrompt: params.systemPrompt,
28
+ userMessage: params.userMessage,
29
+ }),
30
+ },
31
+ ];
32
+ }
33
+ async function confirmOverwriteForExistingPaths(params) {
34
+ if (params.existingPaths.length === 0) {
35
+ return false;
36
+ }
37
+ const overwriteAnswer = await params.options.input(`${params.promptMessage} (${params.existingPaths.join(', ')}) [y/N]`, 'n');
38
+ if (!shouldOverwrite(overwriteAnswer)) {
39
+ throw new Error(`${params.cancelMessage}: ${params.existingPaths.join(', ')}`);
40
+ }
41
+ return true;
42
+ }
43
+ function resolveOutputDir(params) {
44
+ const outputDir = resolveOutputDirectory(params.output, params.cwd);
45
+ ensurePathIsNotSymbolicLink(outputDir, 'Output directory');
46
+ ensurePathAncestorsContainNoSymbolicLinks(outputDir, 'Output directory', params.cwd);
47
+ mkdirSync(outputDir, { recursive: true });
48
+ return outputDir;
49
+ }
50
+ async function resolveComposeOutputDir(params) {
51
+ const outputInput = params.composeOptions.output ?? (isNonInteractiveMode(params.composeOptions)
52
+ ? params.options.cwd
53
+ : await params.options.input('Output directory', params.options.cwd));
54
+ return resolveOutputDir({
55
+ output: outputInput,
56
+ cwd: params.options.cwd,
57
+ });
58
+ }
59
+ export async function runTemplateBackedCompose(params) {
60
+ const templateName = params.definition.template;
61
+ if (!templateName) {
62
+ throw new Error(`Template-backed compose requires template: ${params.definition.name}`);
63
+ }
64
+ const templateDir = ensureTemplateDirectoryFromRoots(params.facetedRoots, templateName, dirname(params.definitionPath));
65
+ const nonInteractive = isNonInteractiveMode(params.composeOptions);
66
+ const outputDir = await resolveComposeOutputDir({
67
+ options: params.options,
68
+ composeOptions: params.composeOptions,
69
+ });
70
+ const templateRelativePaths = collectDirectoryFiles(templateDir);
71
+ const templateOutputPaths = templateRelativePaths.map(relativePath => resolve(outputDir, relativePath));
72
+ const existingPaths = templateOutputPaths.filter(path => existsSync(path));
73
+ if (params.composeOptions.overwrite !== true) {
74
+ if (nonInteractive) {
75
+ if (existingPaths.length > 0) {
76
+ throw new Error(`Output files exist and overwrite was cancelled: ${existingPaths.join(', ')}`);
77
+ }
78
+ }
79
+ else {
80
+ await confirmOverwriteForExistingPaths({
81
+ options: params.options,
82
+ existingPaths,
83
+ promptMessage: 'Output files exist. Overwrite?',
84
+ cancelMessage: 'Output files exist and overwrite was cancelled',
85
+ });
86
+ }
87
+ }
88
+ copyDirectoryTree(templateDir, outputDir);
89
+ const sections = buildSkillSections({
90
+ definition: params.definition,
91
+ definitionDir: dirname(params.definitionPath),
92
+ facetedRoots: params.facetedRoots,
93
+ facetsRoots: params.facetsRoots,
94
+ });
95
+ applyFacetTokensToFiles({
96
+ filePaths: templateOutputPaths.filter(path => existsSync(path)),
97
+ tokenValues: buildInlineFacetTokenValues(sections),
98
+ rootDir: outputDir,
99
+ });
100
+ return {
101
+ kind: 'path',
102
+ path: outputDir,
103
+ };
104
+ }
105
+ export async function runStandardCompose(params) {
106
+ const safeName = ensureSafeDefinitionName(params.definition.name);
107
+ const facetSet = buildFacetSet({
108
+ definitionDir: dirname(params.definitionPath),
109
+ facetedRoots: params.facetedRoots,
110
+ facetsRoots: params.facetsRoots,
111
+ definition: params.definition,
112
+ });
113
+ const composed = compose(facetSet, {
114
+ contextMaxChars: 2000,
115
+ userMessageOrder: params.definition.order,
116
+ });
117
+ const nonInteractive = isNonInteractiveMode(params.composeOptions);
118
+ const splitSelection = params.composeOptions.outputMode
119
+ ? (params.composeOptions.outputMode === 'split' ? 'Split (system + user)' : 'Combined (single file)')
120
+ : await params.options.select(['Combined (single file)', 'Split (system + user)'], 'Choose output mode with Up/Down and Enter:');
121
+ const outputPlans = buildComposeOutputPlans({
122
+ safeName,
123
+ systemPrompt: composed.systemPrompt,
124
+ userMessage: composed.userMessage,
125
+ splitSystem: splitSelection === 'Split (system + user)',
126
+ });
127
+ const outputDir = await resolveComposeOutputDir({
128
+ options: params.options,
129
+ composeOptions: params.composeOptions,
130
+ });
131
+ const existingPaths = outputPlans
132
+ .map(plan => resolve(outputDir, plan.fileName))
133
+ .filter(path => existsSync(path));
134
+ const overwrite = params.composeOptions.overwrite === true
135
+ ? true
136
+ : nonInteractive
137
+ ? false
138
+ : await confirmOverwriteForExistingPaths({
139
+ options: params.options,
140
+ existingPaths,
141
+ promptMessage: 'Output file exists. Overwrite?',
142
+ cancelMessage: 'Output file exists and overwrite was cancelled',
143
+ });
144
+ if (!overwrite && existingPaths.length > 0) {
145
+ throw new Error(`Output file exists and overwrite was cancelled: ${existingPaths.join(', ')}`);
146
+ }
147
+ const outputPaths = [];
148
+ for (const plan of outputPlans) {
149
+ outputPaths.push(await writeComposeOutput({
150
+ outputDir,
151
+ fileName: plan.fileName,
152
+ content: plan.content,
153
+ overwrite,
154
+ }));
155
+ }
156
+ if (outputPaths.length === 1) {
157
+ return {
158
+ kind: 'path',
159
+ path: outputPaths[0],
160
+ };
161
+ }
162
+ return {
163
+ kind: 'paths',
164
+ paths: outputPaths,
165
+ };
166
+ }
167
+ //# sourceMappingURL=compose-execution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compose-execution.js","sourceRoot":"","sources":["../../src/cli/compose-execution.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { ComposeCliOptions } from './types.js';
2
+ export declare function parseComposeOptions(args: readonly string[]): ComposeCliOptions;
3
+ export declare function isNonInteractiveMode(options: ComposeCliOptions): boolean;
4
+ //# sourceMappingURL=compose-options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compose-options.d.ts","sourceRoot":"","sources":["../../src/cli/compose-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAcpD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,iBAAiB,CA0D9E;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAKxE"}