@samahlstrom/forge-cli 0.1.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.
- package/README.md +175 -0
- package/bin/forge.js +2 -0
- package/dist/addons/index.d.ts +25 -0
- package/dist/addons/index.js +139 -0
- package/dist/addons/index.js.map +1 -0
- package/dist/commands/add.d.ts +1 -0
- package/dist/commands/add.js +61 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/doctor.d.ts +1 -0
- package/dist/commands/doctor.js +177 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/ingest.d.ts +24 -0
- package/dist/commands/ingest.js +316 -0
- package/dist/commands/ingest.js.map +1 -0
- package/dist/commands/init.d.ts +8 -0
- package/dist/commands/init.js +557 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/remove.d.ts +1 -0
- package/dist/commands/remove.js +42 -0
- package/dist/commands/remove.js.map +1 -0
- package/dist/commands/status.d.ts +1 -0
- package/dist/commands/status.js +48 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/upgrade.d.ts +5 -0
- package/dist/commands/upgrade.js +190 -0
- package/dist/commands/upgrade.js.map +1 -0
- package/dist/detect/features.d.ts +10 -0
- package/dist/detect/features.js +33 -0
- package/dist/detect/features.js.map +1 -0
- package/dist/detect/go.d.ts +3 -0
- package/dist/detect/go.js +38 -0
- package/dist/detect/go.js.map +1 -0
- package/dist/detect/index.d.ts +25 -0
- package/dist/detect/index.js +32 -0
- package/dist/detect/index.js.map +1 -0
- package/dist/detect/node.d.ts +3 -0
- package/dist/detect/node.js +99 -0
- package/dist/detect/node.js.map +1 -0
- package/dist/detect/python.d.ts +3 -0
- package/dist/detect/python.js +86 -0
- package/dist/detect/python.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/dist/render/engine.d.ts +8 -0
- package/dist/render/engine.js +71 -0
- package/dist/render/engine.js.map +1 -0
- package/dist/render/merge.d.ts +5 -0
- package/dist/render/merge.js +33 -0
- package/dist/render/merge.js.map +1 -0
- package/dist/utils/fs.d.ts +8 -0
- package/dist/utils/fs.js +42 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/git.d.ts +3 -0
- package/dist/utils/git.js +31 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/hash.d.ts +8 -0
- package/dist/utils/hash.js +22 -0
- package/dist/utils/hash.js.map +1 -0
- package/dist/utils/yaml.d.ts +3 -0
- package/dist/utils/yaml.js +12 -0
- package/dist/utils/yaml.js.map +1 -0
- package/package.json +53 -0
- package/templates/addons/beads-dolt-backend/files/dolt-setup.sh +267 -0
- package/templates/addons/beads-dolt-backend/manifest.yaml +13 -0
- package/templates/addons/browser-testing/files/browser-smoke.sh +196 -0
- package/templates/addons/browser-testing/files/visual-qa.md +103 -0
- package/templates/addons/browser-testing/manifest.yaml +20 -0
- package/templates/addons/compliance-hipaa/files/hipaa-checks.sh +184 -0
- package/templates/addons/compliance-hipaa/files/hipaa-context.md +91 -0
- package/templates/addons/compliance-hipaa/manifest.yaml +15 -0
- package/templates/addons/compliance-soc2/files/soc2-checks.sh +232 -0
- package/templates/addons/compliance-soc2/files/soc2-context.md +147 -0
- package/templates/addons/compliance-soc2/manifest.yaml +15 -0
- package/templates/core/CLAUDE.md.hbs +70 -0
- package/templates/core/agents/architect.md.hbs +68 -0
- package/templates/core/agents/backend.md.hbs +27 -0
- package/templates/core/agents/frontend.md.hbs +25 -0
- package/templates/core/agents/quality.md.hbs +40 -0
- package/templates/core/agents/security.md.hbs +53 -0
- package/templates/core/context/project.md.hbs +60 -0
- package/templates/core/forge.yaml.hbs +69 -0
- package/templates/core/hooks/post-edit.sh.hbs +8 -0
- package/templates/core/hooks/pre-edit.sh.hbs +41 -0
- package/templates/core/hooks/session-start.sh.hbs +34 -0
- package/templates/core/pipeline/classify.sh.hbs +159 -0
- package/templates/core/pipeline/decompose.md.hbs +100 -0
- package/templates/core/pipeline/deliver.sh.hbs +171 -0
- package/templates/core/pipeline/execute.md.hbs +138 -0
- package/templates/core/pipeline/intake.sh.hbs +152 -0
- package/templates/core/pipeline/orchestrator.sh.hbs +361 -0
- package/templates/core/pipeline/verify.sh.hbs +160 -0
- package/templates/core/settings.json.hbs +55 -0
- package/templates/core/skill-creator.md.hbs +151 -0
- package/templates/core/skill-deliver.md.hbs +46 -0
- package/templates/core/skill-ingest.md.hbs +245 -0
- package/templates/presets/go/stack.md.hbs +133 -0
- package/templates/presets/python-fastapi/stack.md.hbs +101 -0
- package/templates/presets/react-next-ts/stack.md.hbs +77 -0
- package/templates/presets/sveltekit-ts/stack.md.hbs +116 -0
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import * as p from '@clack/prompts';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { join, resolve, extname, basename } from 'node:path';
|
|
4
|
+
import { exists, writeText, ensureDir } from '../utils/fs.js';
|
|
5
|
+
import { execaCommand } from 'execa';
|
|
6
|
+
import { copyFile, stat, readFile } from 'node:fs/promises';
|
|
7
|
+
export async function ingest(files, options) {
|
|
8
|
+
const cwd = process.cwd();
|
|
9
|
+
p.intro(chalk.bold('forge') + chalk.dim(' — Spec Ingestion'));
|
|
10
|
+
// Resolve and validate all spec files
|
|
11
|
+
const resolvedFiles = [];
|
|
12
|
+
for (const file of files) {
|
|
13
|
+
const specPath = resolve(file);
|
|
14
|
+
if (!(await exists(specPath))) {
|
|
15
|
+
p.cancel(`File not found: ${specPath}`);
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
const ext = extname(specPath).toLowerCase();
|
|
19
|
+
const supportedFormats = ['.pdf', '.md', '.txt', '.markdown'];
|
|
20
|
+
if (!supportedFormats.includes(ext)) {
|
|
21
|
+
p.cancel(`Unsupported format: ${ext} (${basename(specPath)}). Supported: ${supportedFormats.join(', ')}`);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
const fileStats = await stat(specPath);
|
|
25
|
+
const sizeMB = (fileStats.size / (1024 * 1024)).toFixed(1);
|
|
26
|
+
let pageCount = null;
|
|
27
|
+
if (ext === '.pdf') {
|
|
28
|
+
pageCount = await detectPageCount(specPath);
|
|
29
|
+
}
|
|
30
|
+
resolvedFiles.push({ path: specPath, ext, name: basename(specPath), sizeMB, pageCount });
|
|
31
|
+
}
|
|
32
|
+
const isMulti = resolvedFiles.length > 1;
|
|
33
|
+
// Display source info
|
|
34
|
+
const infoLines = [];
|
|
35
|
+
if (isMulti) {
|
|
36
|
+
infoLines.push(`Documents: ${chalk.cyan(String(resolvedFiles.length))}`);
|
|
37
|
+
for (const f of resolvedFiles) {
|
|
38
|
+
const format = f.ext === '.pdf' ? 'PDF' : f.ext === '.md' || f.ext === '.markdown' ? 'MD' : 'TXT';
|
|
39
|
+
const pageInfo = f.pageCount ? ` (${f.pageCount}p)` : '';
|
|
40
|
+
infoLines.push(` ${chalk.dim('•')} ${chalk.cyan(f.name)} ${chalk.dim(`${format}, ${f.sizeMB} MB${pageInfo}`)}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
const f = resolvedFiles[0];
|
|
45
|
+
const format = f.ext === '.pdf' ? 'PDF' : f.ext === '.md' || f.ext === '.markdown' ? 'Markdown' : 'Text';
|
|
46
|
+
infoLines.push(`File: ${chalk.cyan(f.name)}`);
|
|
47
|
+
infoLines.push(`Format: ${chalk.cyan(format)}`);
|
|
48
|
+
infoLines.push(`Size: ${chalk.cyan(f.sizeMB + ' MB')}`);
|
|
49
|
+
if (f.pageCount)
|
|
50
|
+
infoLines.push(`Pages: ${chalk.cyan(String(f.pageCount))}`);
|
|
51
|
+
}
|
|
52
|
+
const chunkSize = parseInt(options.chunkSize ?? '20', 10);
|
|
53
|
+
const totalPages = resolvedFiles.reduce((sum, f) => sum + (f.pageCount ?? 0), 0);
|
|
54
|
+
if (totalPages > chunkSize) {
|
|
55
|
+
infoLines.push(`Chunks: ${chalk.cyan(`${Math.ceil(totalPages / chunkSize)} × ${chunkSize} pages`)}`);
|
|
56
|
+
}
|
|
57
|
+
p.note(infoLines.join('\n'), isMulti ? 'Source Documents' : 'Source Document');
|
|
58
|
+
// Generate spec ID
|
|
59
|
+
const specId = `spec-${randomHex(4)}`;
|
|
60
|
+
// Create spec directory and copy all files
|
|
61
|
+
const specDir = join(cwd, '.forge', 'specs', specId);
|
|
62
|
+
await ensureDir(specDir);
|
|
63
|
+
const sourceFiles = [];
|
|
64
|
+
for (let i = 0; i < resolvedFiles.length; i++) {
|
|
65
|
+
const f = resolvedFiles[i];
|
|
66
|
+
// Prefix with index to preserve order for multi-file
|
|
67
|
+
const destName = isMulti ? `source-${i + 1}${f.ext}` : `source${f.ext}`;
|
|
68
|
+
await copyFile(f.path, join(specDir, destName));
|
|
69
|
+
sourceFiles.push(destName);
|
|
70
|
+
}
|
|
71
|
+
// If multiple text/markdown files, create a concatenated version for analysis
|
|
72
|
+
let combinedPath = null;
|
|
73
|
+
if (isMulti) {
|
|
74
|
+
const parts = [];
|
|
75
|
+
for (const f of resolvedFiles) {
|
|
76
|
+
if (f.ext === '.pdf') {
|
|
77
|
+
parts.push(`\n\n---\n# [PDF Document: ${f.name}]\n# (Read separately via PDF reader)\n---\n\n`);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
const content = await readFile(f.path, 'utf-8');
|
|
81
|
+
parts.push(`\n\n---\n# Document: ${f.name}\n---\n\n${content}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
combinedPath = join(specDir, 'combined.md');
|
|
85
|
+
await writeText(combinedPath, parts.join(''));
|
|
86
|
+
}
|
|
87
|
+
p.log.success(`Copied ${resolvedFiles.length} file${isMulti ? 's' : ''} to ${chalk.dim(`.forge/specs/${specId}/`)}`);
|
|
88
|
+
if (combinedPath) {
|
|
89
|
+
p.log.success(`Combined document created at ${chalk.dim(`.forge/specs/${specId}/combined.md`)}`);
|
|
90
|
+
}
|
|
91
|
+
// Write spec metadata
|
|
92
|
+
const meta = {
|
|
93
|
+
spec_id: specId,
|
|
94
|
+
source: {
|
|
95
|
+
files: resolvedFiles.map((f, i) => ({
|
|
96
|
+
original: f.name,
|
|
97
|
+
stored: sourceFiles[i],
|
|
98
|
+
format: f.ext.replace('.', ''),
|
|
99
|
+
size_mb: parseFloat(f.sizeMB),
|
|
100
|
+
pages: f.pageCount,
|
|
101
|
+
})),
|
|
102
|
+
combined: combinedPath ? 'combined.md' : null,
|
|
103
|
+
ingested_at: new Date().toISOString(),
|
|
104
|
+
},
|
|
105
|
+
status: 'pending-analysis',
|
|
106
|
+
chunk_size: chunkSize,
|
|
107
|
+
};
|
|
108
|
+
await writeText(join(specDir, 'meta.json'), JSON.stringify(meta, null, 2));
|
|
109
|
+
// Check if harness exists
|
|
110
|
+
const harnessExists = await exists(join(cwd, 'forge.yaml'));
|
|
111
|
+
if (!harnessExists) {
|
|
112
|
+
const spinner = p.spinner();
|
|
113
|
+
spinner.start('Analyzing spec with Claude Code...');
|
|
114
|
+
let analysis = null;
|
|
115
|
+
const analysisTarget = combinedPath ?? resolvedFiles[0].path;
|
|
116
|
+
const analysisExt = combinedPath ? '.md' : resolvedFiles[0].ext;
|
|
117
|
+
const analysisPagesCount = combinedPath ? null : resolvedFiles[0].pageCount;
|
|
118
|
+
try {
|
|
119
|
+
analysis = await analyzeSpecWithClaude(analysisTarget, analysisExt, analysisPagesCount);
|
|
120
|
+
spinner.stop('Spec analysis complete');
|
|
121
|
+
}
|
|
122
|
+
catch (err) {
|
|
123
|
+
spinner.stop('Spec analysis failed');
|
|
124
|
+
p.log.warn(chalk.yellow('Could not analyze spec automatically. You can configure manually.'));
|
|
125
|
+
p.log.warn(chalk.dim(String(err)));
|
|
126
|
+
}
|
|
127
|
+
if (analysis) {
|
|
128
|
+
const extractedLines = [
|
|
129
|
+
`Project: ${chalk.cyan(analysis.project_name)}`,
|
|
130
|
+
`Description: ${chalk.cyan(analysis.description)}`,
|
|
131
|
+
`Type: ${chalk.cyan(analysis.project_type)}`,
|
|
132
|
+
`Language: ${chalk.cyan(analysis.language)}`,
|
|
133
|
+
];
|
|
134
|
+
if (analysis.framework)
|
|
135
|
+
extractedLines.push(`Framework: ${chalk.cyan(analysis.framework)}`);
|
|
136
|
+
if (analysis.modules.length > 0)
|
|
137
|
+
extractedLines.push(`Modules: ${chalk.cyan(analysis.modules.join(', '))}`);
|
|
138
|
+
extractedLines.push(`Architecture: ${chalk.cyan(analysis.architecture)}`);
|
|
139
|
+
if (analysis.sensitive_areas)
|
|
140
|
+
extractedLines.push(`Sensitive: ${chalk.cyan(analysis.sensitive_areas)}`);
|
|
141
|
+
if (analysis.constraints.length > 0)
|
|
142
|
+
extractedLines.push(`Constraints: ${chalk.cyan(analysis.constraints.slice(0, 3).join('; '))}`);
|
|
143
|
+
p.note(extractedLines.join('\n'), 'Extracted from spec');
|
|
144
|
+
const confirmed = await p.confirm({ message: 'Does this look right?', initialValue: true });
|
|
145
|
+
if (p.isCancel(confirmed)) {
|
|
146
|
+
p.cancel('Cancelled.');
|
|
147
|
+
process.exit(0);
|
|
148
|
+
}
|
|
149
|
+
if (!confirmed) {
|
|
150
|
+
const correctionsAnswer = await p.text({
|
|
151
|
+
message: 'What needs to change?',
|
|
152
|
+
placeholder: 'e.g. Use SvelteKit instead of Next.js, add billing as a module',
|
|
153
|
+
});
|
|
154
|
+
if (p.isCancel(correctionsAnswer)) {
|
|
155
|
+
p.cancel('Cancelled.');
|
|
156
|
+
process.exit(0);
|
|
157
|
+
}
|
|
158
|
+
if (correctionsAnswer) {
|
|
159
|
+
const spinner2 = p.spinner();
|
|
160
|
+
spinner2.start('Re-analyzing with corrections...');
|
|
161
|
+
try {
|
|
162
|
+
analysis = await analyzeSpecWithClaude(analysisTarget, analysisExt, analysisPagesCount, correctionsAnswer);
|
|
163
|
+
spinner2.stop('Updated analysis complete');
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
spinner2.stop('Re-analysis failed, using original analysis');
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
await writeText(join(specDir, 'analysis.json'), JSON.stringify(analysis, null, 2));
|
|
171
|
+
p.log.success('Spec analysis saved.');
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
// Show next steps
|
|
175
|
+
if (harnessExists) {
|
|
176
|
+
p.log.step('Next step:');
|
|
177
|
+
p.log.message(` Open Claude Code → ${chalk.cyan(`/ingest ${specId}`)}`);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
p.log.step('Next steps:');
|
|
181
|
+
p.log.message(` 1. Run ${chalk.cyan('forge init')} to scaffold the harness`);
|
|
182
|
+
p.log.message(` ${chalk.dim('(use the spec analysis above to answer onboarding questions)')}`);
|
|
183
|
+
p.log.message(` 2. Open Claude Code → ${chalk.cyan(`/ingest ${specId}`)}`);
|
|
184
|
+
}
|
|
185
|
+
p.outro(chalk.green('Spec ready for analysis.'));
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Called from `forge init --spec <file>` to analyze a spec and return
|
|
189
|
+
* structured metadata that pre-fills the onboarding answers.
|
|
190
|
+
*/
|
|
191
|
+
export async function analyzeSpecForInit(specPath) {
|
|
192
|
+
const ext = extname(specPath).toLowerCase();
|
|
193
|
+
let pageCount = null;
|
|
194
|
+
if (ext === '.pdf') {
|
|
195
|
+
pageCount = await detectPageCount(specPath);
|
|
196
|
+
}
|
|
197
|
+
return analyzeSpecWithClaude(specPath, ext, pageCount);
|
|
198
|
+
}
|
|
199
|
+
async function analyzeSpecWithClaude(specPath, ext, pageCount, corrections) {
|
|
200
|
+
const prompt = buildAnalysisPrompt(specPath, ext, pageCount, corrections);
|
|
201
|
+
// Write prompt to a temp file to avoid shell escaping issues
|
|
202
|
+
const tmpPromptFile = join('/tmp', `forge-prompt-${randomHex(4)}.txt`);
|
|
203
|
+
await writeText(tmpPromptFile, prompt);
|
|
204
|
+
try {
|
|
205
|
+
// Call claude as a subprocess, piping the prompt via stdin
|
|
206
|
+
const result = await execaCommand(`cat "${tmpPromptFile}" | claude -p --output-format json`, { timeout: 180000, shell: true });
|
|
207
|
+
const responseText = result.stdout;
|
|
208
|
+
// claude -p --output-format json wraps output as:
|
|
209
|
+
// {"type":"result","result":"<the actual content>", ...}
|
|
210
|
+
let content;
|
|
211
|
+
try {
|
|
212
|
+
const wrapper = JSON.parse(responseText);
|
|
213
|
+
content = wrapper.result ?? responseText;
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
// If it's not valid JSON wrapper, use raw output
|
|
217
|
+
content = responseText;
|
|
218
|
+
}
|
|
219
|
+
// Extract the JSON object from Claude's response
|
|
220
|
+
// Try multiple patterns since Claude might wrap it in markdown code blocks
|
|
221
|
+
let jsonStr = null;
|
|
222
|
+
// Pattern 1: ```json ... ``` code block
|
|
223
|
+
const codeBlockMatch = content.match(/```(?:json)?\s*(\{[\s\S]*?\})\s*```/);
|
|
224
|
+
if (codeBlockMatch) {
|
|
225
|
+
jsonStr = codeBlockMatch[1];
|
|
226
|
+
}
|
|
227
|
+
// Pattern 2: raw JSON object with project_name
|
|
228
|
+
if (!jsonStr) {
|
|
229
|
+
const rawMatch = content.match(/\{[\s\S]*?"project_name"[\s\S]*?\}/);
|
|
230
|
+
if (rawMatch) {
|
|
231
|
+
jsonStr = rawMatch[0];
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
// Pattern 3: the entire content is JSON
|
|
235
|
+
if (!jsonStr) {
|
|
236
|
+
try {
|
|
237
|
+
JSON.parse(content);
|
|
238
|
+
jsonStr = content;
|
|
239
|
+
}
|
|
240
|
+
catch { /* not json */ }
|
|
241
|
+
}
|
|
242
|
+
if (!jsonStr) {
|
|
243
|
+
throw new Error(`Could not find JSON in Claude response. Raw output:\n${content.slice(0, 500)}`);
|
|
244
|
+
}
|
|
245
|
+
const analysis = JSON.parse(jsonStr);
|
|
246
|
+
analysis.page_count = pageCount;
|
|
247
|
+
// Validate required fields
|
|
248
|
+
if (!analysis.project_name || !analysis.language) {
|
|
249
|
+
throw new Error(`Incomplete analysis: missing project_name or language`);
|
|
250
|
+
}
|
|
251
|
+
return analysis;
|
|
252
|
+
}
|
|
253
|
+
finally {
|
|
254
|
+
// Clean up temp file
|
|
255
|
+
try {
|
|
256
|
+
const { unlink } = await import('node:fs/promises');
|
|
257
|
+
await unlink(tmpPromptFile);
|
|
258
|
+
}
|
|
259
|
+
catch { /* ignore */ }
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
function buildAnalysisPrompt(specPath, ext, pageCount, corrections) {
|
|
263
|
+
let readInstruction;
|
|
264
|
+
if (ext === '.pdf') {
|
|
265
|
+
const pagesToRead = pageCount && pageCount > 40 ? 40 : pageCount ?? 20;
|
|
266
|
+
readInstruction = `Read the PDF at "${specPath}" (first ${pagesToRead} pages) to understand what this project is.`;
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
readInstruction = `Read the file at "${specPath}" to understand what this project is.`;
|
|
270
|
+
}
|
|
271
|
+
let correctionsClause = '';
|
|
272
|
+
if (corrections) {
|
|
273
|
+
correctionsClause = `\n\nThe user has provided these corrections to a previous analysis: "${corrections}". Apply these corrections to your analysis.`;
|
|
274
|
+
}
|
|
275
|
+
return `${readInstruction}
|
|
276
|
+
|
|
277
|
+
Extract the following as a JSON object. Output ONLY the JSON, no explanation, no markdown formatting:
|
|
278
|
+
|
|
279
|
+
{
|
|
280
|
+
"project_name": "short project name",
|
|
281
|
+
"description": "1-2 sentence description of what this project does",
|
|
282
|
+
"language": "typescript | javascript | python | go",
|
|
283
|
+
"framework": "next | sveltekit | fastapi | django | gin | null",
|
|
284
|
+
"project_type": "web-app | api | cli | library | automation | fullstack",
|
|
285
|
+
"modules": ["list", "of", "main", "modules"],
|
|
286
|
+
"architecture": "monolith | client-server | microservices | static-site | library",
|
|
287
|
+
"sensitive_areas": "description of sensitive data or security concerns, or empty string",
|
|
288
|
+
"domain_rules": "key business rules agents must follow, or empty string",
|
|
289
|
+
"constraints": ["list", "of", "hard", "constraints"]
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
Infer language and framework from the spec's technology requirements. If not specified, choose the best fit based on the project type. For medical/healthcare projects, note HIPAA requirements in sensitive_areas.${correctionsClause}`;
|
|
293
|
+
}
|
|
294
|
+
async function detectPageCount(pdfPath) {
|
|
295
|
+
try {
|
|
296
|
+
const result = await execaCommand(`mdls -name kMDItemNumberOfPages -raw "${pdfPath}"`, { shell: true });
|
|
297
|
+
const count = parseInt(result.stdout.trim(), 10);
|
|
298
|
+
if (!isNaN(count) && count > 0)
|
|
299
|
+
return count;
|
|
300
|
+
}
|
|
301
|
+
catch { /* fall through */ }
|
|
302
|
+
try {
|
|
303
|
+
const result = await execaCommand(`pdfinfo "${pdfPath}" 2>/dev/null | grep "^Pages:" | awk '{print $2}'`, { shell: true });
|
|
304
|
+
const count = parseInt(result.stdout.trim(), 10);
|
|
305
|
+
if (!isNaN(count) && count > 0)
|
|
306
|
+
return count;
|
|
307
|
+
}
|
|
308
|
+
catch { /* fall through */ }
|
|
309
|
+
return null;
|
|
310
|
+
}
|
|
311
|
+
function randomHex(bytes) {
|
|
312
|
+
const array = new Uint8Array(bytes);
|
|
313
|
+
crypto.getRandomValues(array);
|
|
314
|
+
return Array.from(array, (b) => b.toString(16).padStart(2, '0')).join('');
|
|
315
|
+
}
|
|
316
|
+
//# sourceMappingURL=ingest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ingest.js","sourceRoot":"","sources":["../../src/commands/ingest.ts"],"names":[],"mappings":"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"}
|