create-claude-context 1.0.0 → 1.2.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 (112) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +146 -146
  3. package/bin/create-claude-context.js +61 -61
  4. package/lib/detector.js +373 -373
  5. package/lib/index.js +170 -170
  6. package/lib/installer.js +371 -362
  7. package/lib/placeholder.js +208 -208
  8. package/lib/prompts.js +287 -287
  9. package/lib/spinner.js +60 -60
  10. package/lib/validate.js +147 -147
  11. package/package.json +59 -59
  12. package/templates/CLAUDE.md.template +235 -235
  13. package/templates/base/README.md +257 -257
  14. package/templates/base/RPI_WORKFLOW_PLAN.md +320 -320
  15. package/templates/base/agents/api-developer.md +76 -76
  16. package/templates/base/agents/context-engineer.md +525 -525
  17. package/templates/base/agents/core-architect.md +76 -76
  18. package/templates/base/agents/database-ops.md +76 -76
  19. package/templates/base/agents/deployment-ops.md +76 -76
  20. package/templates/base/agents/integration-hub.md +76 -76
  21. package/templates/base/analytics/README.md +114 -114
  22. package/templates/base/automation/config.json +58 -0
  23. package/templates/base/automation/generators/code-mapper.js +308 -0
  24. package/templates/base/automation/generators/index-builder.js +321 -0
  25. package/templates/base/automation/hooks/post-commit.sh +83 -0
  26. package/templates/base/automation/hooks/pre-commit.sh +103 -0
  27. package/templates/base/ci-templates/README.md +108 -108
  28. package/templates/base/ci-templates/github-actions/context-check.yml +144 -144
  29. package/templates/base/ci-templates/github-actions/validate-docs.yml +105 -105
  30. package/templates/base/commands/analytics.md +238 -238
  31. package/templates/base/commands/auto-sync.md +172 -0
  32. package/templates/base/commands/collab.md +194 -194
  33. package/templates/base/commands/help.md +450 -450
  34. package/templates/base/commands/rpi-implement.md +115 -115
  35. package/templates/base/commands/rpi-plan.md +93 -93
  36. package/templates/base/commands/rpi-research.md +88 -88
  37. package/templates/base/commands/session-resume.md +144 -0
  38. package/templates/base/commands/session-save.md +112 -0
  39. package/templates/base/commands/validate-all.md +77 -77
  40. package/templates/base/commands/verify-docs-current.md +86 -86
  41. package/templates/base/config/base.json +57 -57
  42. package/templates/base/config/environments/development.json +13 -13
  43. package/templates/base/config/environments/production.json +17 -17
  44. package/templates/base/config/environments/staging.json +13 -13
  45. package/templates/base/config/local.json.example +21 -21
  46. package/templates/base/context/.meta/generated-at.json +18 -0
  47. package/templates/base/context/ARCHITECTURE_SNAPSHOT.md +156 -156
  48. package/templates/base/context/CODE_TO_WORKFLOW_MAP.md +94 -94
  49. package/templates/base/context/FILE_OWNERSHIP.md +57 -0
  50. package/templates/base/context/INTEGRATION_POINTS.md +92 -0
  51. package/templates/base/context/KNOWN_GOTCHAS.md +195 -195
  52. package/templates/base/context/TESTING_MAP.md +95 -0
  53. package/templates/base/context/WORKFLOW_INDEX.md +129 -129
  54. package/templates/base/context/workflows/WORKFLOW_TEMPLATE.md +294 -294
  55. package/templates/base/indexes/agents/CAPABILITY_MATRIX.md +255 -255
  56. package/templates/base/indexes/agents/CATEGORY_INDEX.md +44 -44
  57. package/templates/base/indexes/code/CATEGORY_INDEX.md +38 -38
  58. package/templates/base/indexes/routing/CATEGORY_INDEX.md +39 -39
  59. package/templates/base/indexes/search/CATEGORY_INDEX.md +39 -39
  60. package/templates/base/indexes/workflows/CATEGORY_INDEX.md +38 -38
  61. package/templates/base/knowledge/README.md +98 -98
  62. package/templates/base/knowledge/sessions/README.md +88 -88
  63. package/templates/base/knowledge/sessions/TEMPLATE.md +150 -150
  64. package/templates/base/knowledge/shared/decisions/0001-adopt-context-engineering.md +144 -144
  65. package/templates/base/knowledge/shared/decisions/README.md +49 -49
  66. package/templates/base/knowledge/shared/decisions/TEMPLATE.md +123 -123
  67. package/templates/base/knowledge/shared/patterns/README.md +62 -62
  68. package/templates/base/knowledge/shared/patterns/TEMPLATE.md +120 -120
  69. package/templates/base/plans/PLAN_TEMPLATE.md +250 -250
  70. package/templates/base/research/RESEARCH_TEMPLATE.md +153 -153
  71. package/templates/base/schemas/agent.schema.json +141 -141
  72. package/templates/base/schemas/anchors.schema.json +54 -0
  73. package/templates/base/schemas/automation.schema.json +93 -0
  74. package/templates/base/schemas/command.schema.json +134 -134
  75. package/templates/base/schemas/hashes.schema.json +40 -0
  76. package/templates/base/schemas/manifest.schema.json +117 -117
  77. package/templates/base/schemas/plan.schema.json +136 -136
  78. package/templates/base/schemas/research.schema.json +115 -115
  79. package/templates/base/schemas/roles.schema.json +34 -0
  80. package/templates/base/schemas/session.schema.json +77 -0
  81. package/templates/base/schemas/settings.schema.json +244 -244
  82. package/templates/base/schemas/staleness.schema.json +53 -0
  83. package/templates/base/schemas/team-config.schema.json +42 -0
  84. package/templates/base/schemas/workflow.schema.json +126 -126
  85. package/templates/base/session/checkpoints/.gitkeep +2 -0
  86. package/templates/base/session/current/state.json +20 -0
  87. package/templates/base/session/history/.gitkeep +2 -0
  88. package/templates/base/settings.json +79 -57
  89. package/templates/base/standards/COMPATIBILITY.md +219 -219
  90. package/templates/base/standards/EXTENSION_GUIDELINES.md +280 -280
  91. package/templates/base/standards/QUALITY_CHECKLIST.md +211 -211
  92. package/templates/base/standards/README.md +66 -66
  93. package/templates/base/sync/anchors.json +6 -0
  94. package/templates/base/sync/hashes.json +6 -0
  95. package/templates/base/sync/staleness.json +10 -0
  96. package/templates/base/team/README.md +168 -168
  97. package/templates/base/team/config.json +79 -79
  98. package/templates/base/team/roles.json +145 -145
  99. package/templates/base/tools/bin/claude-context.js +151 -151
  100. package/templates/base/tools/lib/anchor-resolver.js +276 -0
  101. package/templates/base/tools/lib/config-loader.js +363 -363
  102. package/templates/base/tools/lib/detector.js +350 -350
  103. package/templates/base/tools/lib/diagnose.js +206 -206
  104. package/templates/base/tools/lib/drift-detector.js +373 -0
  105. package/templates/base/tools/lib/errors.js +199 -199
  106. package/templates/base/tools/lib/index.js +36 -24
  107. package/templates/base/tools/lib/init.js +192 -192
  108. package/templates/base/tools/lib/logger.js +230 -230
  109. package/templates/base/tools/lib/placeholder.js +201 -201
  110. package/templates/base/tools/lib/session-manager.js +354 -0
  111. package/templates/base/tools/lib/validate.js +521 -521
  112. package/templates/base/tools/package.json +49 -49
@@ -1,208 +1,208 @@
1
- /**
2
- * Claude Context Engineering - Placeholder Replacement Engine
3
- *
4
- * Finds and replaces {{PLACEHOLDER}} patterns in template files.
5
- */
6
-
7
- const fs = require('fs');
8
- const path = require('path');
9
- const { glob } = require('glob');
10
-
11
- /**
12
- * Known placeholders with their descriptions
13
- */
14
- const KNOWN_PLACEHOLDERS = {
15
- // Project identity
16
- PROJECT_NAME: { description: 'Project name', example: 'my-awesome-app' },
17
- PROJECT_DESCRIPTION: { description: 'Brief project description', example: 'A web application for...' },
18
- TECH_STACK: { description: 'Technologies used', example: 'Python 3.11, FastAPI, PostgreSQL' },
19
- PRODUCTION_URL: { description: 'Production URL', example: 'https://api.example.com' },
20
- PROJECT_STATUS: { description: 'Project status', example: 'Production' },
21
-
22
- // URLs
23
- API_URL: { description: 'API base URL', example: 'https://api.example.com/v1' },
24
- REPO_URL: { description: 'Repository URL', example: 'https://github.com/user/repo' },
25
- DEPLOYMENT_PLATFORM: { description: 'Where deployed', example: 'AWS ECS' },
26
-
27
- // Commands
28
- INSTALL_COMMAND: { description: 'Install dependencies command', example: 'npm install' },
29
- DEV_START_COMMAND: { description: 'Start dev server command', example: 'npm run dev' },
30
- TEST_COMMAND: { description: 'Run tests command', example: 'npm test' },
31
- TEST_E2E_COMMAND: { description: 'Run E2E tests command', example: 'npm run test:e2e' },
32
- TEST_COVERAGE_COMMAND: { description: 'Run coverage command', example: 'npm run coverage' },
33
- MIGRATION_CREATE_COMMAND: { description: 'Create migration command', example: 'npm run db:migrate:create' },
34
- MIGRATION_RUN_COMMAND: { description: 'Run migrations command', example: 'npm run db:migrate' },
35
- DEPLOY_COMMAND: { description: 'Deploy command', example: 'npm run deploy' },
36
-
37
- // Paths
38
- MODELS_PATH: { description: 'Models directory path', example: 'src/models/' },
39
- MIGRATIONS_PATH: { description: 'Migrations directory path', example: 'src/migrations/' },
40
- CORE_FILES_LIST: { description: 'List of core files', example: '- src/services/\n- src/models/' },
41
-
42
- // Counts
43
- WORKFLOWS_COUNT: { description: 'Number of workflows', example: '12' },
44
- AGENTS_COUNT: { description: 'Number of agents', example: '6' },
45
- COMMANDS_COUNT: { description: 'Number of commands', example: '8' },
46
-
47
- // Meta
48
- DATE: { description: 'Current date', example: '2025-01-24' },
49
- AGENT_TABLE_ROWS: { description: 'Agent table rows', example: '| core-architect | System design |' },
50
- };
51
-
52
- /**
53
- * Get default placeholder values based on config and tech stack
54
- */
55
- function getDefaultValues(config = {}, techStack = {}) {
56
- const today = new Date().toISOString().split('T')[0];
57
- const projectName = config.projectName || 'my-project';
58
-
59
- // Determine commands based on tech stack
60
- let commands = {
61
- install: 'npm install',
62
- dev: 'npm run dev',
63
- test: 'npm test',
64
- migrate: 'npm run migrate'
65
- };
66
-
67
- if (techStack.commands) {
68
- commands = techStack.commands;
69
- } else if (techStack.languages?.includes('python')) {
70
- commands = {
71
- install: 'pip install -r requirements.txt',
72
- dev: 'python main.py',
73
- test: 'pytest',
74
- migrate: 'alembic upgrade head'
75
- };
76
- } else if (techStack.languages?.includes('go')) {
77
- commands = {
78
- install: 'go mod download',
79
- dev: 'go run .',
80
- test: 'go test ./...',
81
- migrate: 'migrate -path migrations up'
82
- };
83
- } else if (techStack.languages?.includes('rust')) {
84
- commands = {
85
- install: 'cargo build',
86
- dev: 'cargo run',
87
- test: 'cargo test',
88
- migrate: 'sqlx migrate run'
89
- };
90
- }
91
-
92
- return {
93
- PROJECT_NAME: projectName,
94
- PROJECT_DESCRIPTION: `${projectName} application`,
95
- TECH_STACK: techStack.summary || techStack.stack || 'Not detected',
96
- PRODUCTION_URL: `https://${projectName}.example.com`,
97
- PROJECT_STATUS: 'Development',
98
- API_URL: `https://api.${projectName}.example.com`,
99
- REPO_URL: `https://github.com/user/${projectName}`,
100
- DEPLOYMENT_PLATFORM: 'Docker',
101
- INSTALL_COMMAND: commands.install,
102
- DEV_START_COMMAND: commands.dev,
103
- TEST_COMMAND: commands.test,
104
- TEST_E2E_COMMAND: `${commands.test} --e2e`,
105
- TEST_COVERAGE_COMMAND: `${commands.test} --coverage`,
106
- MIGRATION_CREATE_COMMAND: `${commands.migrate}:create`,
107
- MIGRATION_RUN_COMMAND: commands.migrate,
108
- DEPLOY_COMMAND: 'docker-compose up -d',
109
- MODELS_PATH: 'src/models/',
110
- MIGRATIONS_PATH: 'src/migrations/',
111
- CORE_FILES_LIST: '- src/\n- config/',
112
- WORKFLOWS_COUNT: '8',
113
- AGENTS_COUNT: '6',
114
- COMMANDS_COUNT: '8',
115
- DATE: today,
116
- AGENT_TABLE_ROWS: '',
117
- };
118
- }
119
-
120
- /**
121
- * Replace placeholders in all files in a directory
122
- */
123
- async function replacePlaceholders(targetDir, config = {}) {
124
- const claudeDir = path.join(targetDir, '.claude');
125
- const values = getDefaultValues(config, config.techStack || {});
126
-
127
- // Find all markdown and JSON files
128
- const files = await glob('**/*.{md,json}', {
129
- cwd: claudeDir,
130
- ignore: ['node_modules/**', '.git/**'],
131
- nodir: true,
132
- absolute: true
133
- });
134
-
135
- let totalReplaced = 0;
136
-
137
- for (const filePath of files) {
138
- try {
139
- let content = fs.readFileSync(filePath, 'utf8');
140
- const originalContent = content;
141
-
142
- // Replace all placeholders
143
- for (const [key, value] of Object.entries(values)) {
144
- const pattern = new RegExp(`\\{\\{${key}\\}\\}`, 'g');
145
- content = content.replace(pattern, String(value));
146
- }
147
-
148
- if (content !== originalContent) {
149
- fs.writeFileSync(filePath, content, 'utf8');
150
- totalReplaced++;
151
- }
152
- } catch (error) {
153
- // Skip files that can't be read
154
- }
155
- }
156
-
157
- // Also replace in CLAUDE.md at root
158
- const claudeMdPath = path.join(targetDir, 'CLAUDE.md');
159
- if (fs.existsSync(claudeMdPath)) {
160
- try {
161
- let content = fs.readFileSync(claudeMdPath, 'utf8');
162
- const originalContent = content;
163
-
164
- for (const [key, value] of Object.entries(values)) {
165
- const pattern = new RegExp(`\\{\\{${key}\\}\\}`, 'g');
166
- content = content.replace(pattern, String(value));
167
- }
168
-
169
- if (content !== originalContent) {
170
- fs.writeFileSync(claudeMdPath, content, 'utf8');
171
- totalReplaced++;
172
- }
173
- } catch (error) {
174
- // Skip if can't read
175
- }
176
- }
177
-
178
- return totalReplaced;
179
- }
180
-
181
- /**
182
- * Find all placeholders in a file
183
- */
184
- function findPlaceholders(filePath) {
185
- const content = fs.readFileSync(filePath, 'utf8');
186
- const placeholderPattern = /\{\{([A-Z_]+)\}\}/g;
187
-
188
- const found = [];
189
- let match;
190
-
191
- while ((match = placeholderPattern.exec(content)) !== null) {
192
- found.push({
193
- placeholder: match[0],
194
- name: match[1],
195
- index: match.index,
196
- known: KNOWN_PLACEHOLDERS.hasOwnProperty(match[1]),
197
- });
198
- }
199
-
200
- return found;
201
- }
202
-
203
- module.exports = {
204
- replacePlaceholders,
205
- findPlaceholders,
206
- getDefaultValues,
207
- KNOWN_PLACEHOLDERS,
208
- };
1
+ /**
2
+ * Claude Context Engineering - Placeholder Replacement Engine
3
+ *
4
+ * Finds and replaces {{PLACEHOLDER}} patterns in template files.
5
+ */
6
+
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+ const { glob } = require('glob');
10
+
11
+ /**
12
+ * Known placeholders with their descriptions
13
+ */
14
+ const KNOWN_PLACEHOLDERS = {
15
+ // Project identity
16
+ PROJECT_NAME: { description: 'Project name', example: 'my-awesome-app' },
17
+ PROJECT_DESCRIPTION: { description: 'Brief project description', example: 'A web application for...' },
18
+ TECH_STACK: { description: 'Technologies used', example: 'Python 3.11, FastAPI, PostgreSQL' },
19
+ PRODUCTION_URL: { description: 'Production URL', example: 'https://api.example.com' },
20
+ PROJECT_STATUS: { description: 'Project status', example: 'Production' },
21
+
22
+ // URLs
23
+ API_URL: { description: 'API base URL', example: 'https://api.example.com/v1' },
24
+ REPO_URL: { description: 'Repository URL', example: 'https://github.com/user/repo' },
25
+ DEPLOYMENT_PLATFORM: { description: 'Where deployed', example: 'AWS ECS' },
26
+
27
+ // Commands
28
+ INSTALL_COMMAND: { description: 'Install dependencies command', example: 'npm install' },
29
+ DEV_START_COMMAND: { description: 'Start dev server command', example: 'npm run dev' },
30
+ TEST_COMMAND: { description: 'Run tests command', example: 'npm test' },
31
+ TEST_E2E_COMMAND: { description: 'Run E2E tests command', example: 'npm run test:e2e' },
32
+ TEST_COVERAGE_COMMAND: { description: 'Run coverage command', example: 'npm run coverage' },
33
+ MIGRATION_CREATE_COMMAND: { description: 'Create migration command', example: 'npm run db:migrate:create' },
34
+ MIGRATION_RUN_COMMAND: { description: 'Run migrations command', example: 'npm run db:migrate' },
35
+ DEPLOY_COMMAND: { description: 'Deploy command', example: 'npm run deploy' },
36
+
37
+ // Paths
38
+ MODELS_PATH: { description: 'Models directory path', example: 'src/models/' },
39
+ MIGRATIONS_PATH: { description: 'Migrations directory path', example: 'src/migrations/' },
40
+ CORE_FILES_LIST: { description: 'List of core files', example: '- src/services/\n- src/models/' },
41
+
42
+ // Counts
43
+ WORKFLOWS_COUNT: { description: 'Number of workflows', example: '12' },
44
+ AGENTS_COUNT: { description: 'Number of agents', example: '6' },
45
+ COMMANDS_COUNT: { description: 'Number of commands', example: '8' },
46
+
47
+ // Meta
48
+ DATE: { description: 'Current date', example: '2025-01-24' },
49
+ AGENT_TABLE_ROWS: { description: 'Agent table rows', example: '| core-architect | System design |' },
50
+ };
51
+
52
+ /**
53
+ * Get default placeholder values based on config and tech stack
54
+ */
55
+ function getDefaultValues(config = {}, techStack = {}) {
56
+ const today = new Date().toISOString().split('T')[0];
57
+ const projectName = config.projectName || 'my-project';
58
+
59
+ // Determine commands based on tech stack
60
+ let commands = {
61
+ install: 'npm install',
62
+ dev: 'npm run dev',
63
+ test: 'npm test',
64
+ migrate: 'npm run migrate'
65
+ };
66
+
67
+ if (techStack.commands) {
68
+ commands = techStack.commands;
69
+ } else if (techStack.languages?.includes('python')) {
70
+ commands = {
71
+ install: 'pip install -r requirements.txt',
72
+ dev: 'python main.py',
73
+ test: 'pytest',
74
+ migrate: 'alembic upgrade head'
75
+ };
76
+ } else if (techStack.languages?.includes('go')) {
77
+ commands = {
78
+ install: 'go mod download',
79
+ dev: 'go run .',
80
+ test: 'go test ./...',
81
+ migrate: 'migrate -path migrations up'
82
+ };
83
+ } else if (techStack.languages?.includes('rust')) {
84
+ commands = {
85
+ install: 'cargo build',
86
+ dev: 'cargo run',
87
+ test: 'cargo test',
88
+ migrate: 'sqlx migrate run'
89
+ };
90
+ }
91
+
92
+ return {
93
+ PROJECT_NAME: projectName,
94
+ PROJECT_DESCRIPTION: `${projectName} application`,
95
+ TECH_STACK: techStack.summary || techStack.stack || 'Not detected',
96
+ PRODUCTION_URL: `https://${projectName}.example.com`,
97
+ PROJECT_STATUS: 'Development',
98
+ API_URL: `https://api.${projectName}.example.com`,
99
+ REPO_URL: `https://github.com/user/${projectName}`,
100
+ DEPLOYMENT_PLATFORM: 'Docker',
101
+ INSTALL_COMMAND: commands.install,
102
+ DEV_START_COMMAND: commands.dev,
103
+ TEST_COMMAND: commands.test,
104
+ TEST_E2E_COMMAND: `${commands.test} --e2e`,
105
+ TEST_COVERAGE_COMMAND: `${commands.test} --coverage`,
106
+ MIGRATION_CREATE_COMMAND: `${commands.migrate}:create`,
107
+ MIGRATION_RUN_COMMAND: commands.migrate,
108
+ DEPLOY_COMMAND: 'docker-compose up -d',
109
+ MODELS_PATH: 'src/models/',
110
+ MIGRATIONS_PATH: 'src/migrations/',
111
+ CORE_FILES_LIST: '- src/\n- config/',
112
+ WORKFLOWS_COUNT: '8',
113
+ AGENTS_COUNT: '6',
114
+ COMMANDS_COUNT: '8',
115
+ DATE: today,
116
+ AGENT_TABLE_ROWS: '',
117
+ };
118
+ }
119
+
120
+ /**
121
+ * Replace placeholders in all files in a directory
122
+ */
123
+ async function replacePlaceholders(targetDir, config = {}) {
124
+ const claudeDir = path.join(targetDir, '.claude');
125
+ const values = getDefaultValues(config, config.techStack || {});
126
+
127
+ // Find all markdown and JSON files
128
+ const files = await glob('**/*.{md,json}', {
129
+ cwd: claudeDir,
130
+ ignore: ['node_modules/**', '.git/**'],
131
+ nodir: true,
132
+ absolute: true
133
+ });
134
+
135
+ let totalReplaced = 0;
136
+
137
+ for (const filePath of files) {
138
+ try {
139
+ let content = fs.readFileSync(filePath, 'utf8');
140
+ const originalContent = content;
141
+
142
+ // Replace all placeholders
143
+ for (const [key, value] of Object.entries(values)) {
144
+ const pattern = new RegExp(`\\{\\{${key}\\}\\}`, 'g');
145
+ content = content.replace(pattern, String(value));
146
+ }
147
+
148
+ if (content !== originalContent) {
149
+ fs.writeFileSync(filePath, content, 'utf8');
150
+ totalReplaced++;
151
+ }
152
+ } catch (error) {
153
+ // Skip files that can't be read
154
+ }
155
+ }
156
+
157
+ // Also replace in CLAUDE.md at root
158
+ const claudeMdPath = path.join(targetDir, 'CLAUDE.md');
159
+ if (fs.existsSync(claudeMdPath)) {
160
+ try {
161
+ let content = fs.readFileSync(claudeMdPath, 'utf8');
162
+ const originalContent = content;
163
+
164
+ for (const [key, value] of Object.entries(values)) {
165
+ const pattern = new RegExp(`\\{\\{${key}\\}\\}`, 'g');
166
+ content = content.replace(pattern, String(value));
167
+ }
168
+
169
+ if (content !== originalContent) {
170
+ fs.writeFileSync(claudeMdPath, content, 'utf8');
171
+ totalReplaced++;
172
+ }
173
+ } catch (error) {
174
+ // Skip if can't read
175
+ }
176
+ }
177
+
178
+ return totalReplaced;
179
+ }
180
+
181
+ /**
182
+ * Find all placeholders in a file
183
+ */
184
+ function findPlaceholders(filePath) {
185
+ const content = fs.readFileSync(filePath, 'utf8');
186
+ const placeholderPattern = /\{\{([A-Z_]+)\}\}/g;
187
+
188
+ const found = [];
189
+ let match;
190
+
191
+ while ((match = placeholderPattern.exec(content)) !== null) {
192
+ found.push({
193
+ placeholder: match[0],
194
+ name: match[1],
195
+ index: match.index,
196
+ known: KNOWN_PLACEHOLDERS.hasOwnProperty(match[1]),
197
+ });
198
+ }
199
+
200
+ return found;
201
+ }
202
+
203
+ module.exports = {
204
+ replacePlaceholders,
205
+ findPlaceholders,
206
+ getDefaultValues,
207
+ KNOWN_PLACEHOLDERS,
208
+ };