@planu/cli 1.2.0 → 1.4.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/dist/config/dev-lifecycle-catalog.json +22 -0
- package/dist/config/license-plans.json +20 -1
- package/dist/engine/aider-prompt-generator.d.ts +26 -0
- package/dist/engine/aider-prompt-generator.d.ts.map +1 -0
- package/dist/engine/aider-prompt-generator.js +144 -0
- package/dist/engine/aider-prompt-generator.js.map +1 -0
- package/dist/engine/claude-config-auditor/settings-auditor.d.ts.map +1 -1
- package/dist/engine/claude-config-auditor/settings-auditor.js +20 -1
- package/dist/engine/claude-config-auditor/settings-auditor.js.map +1 -1
- package/dist/engine/code-graph-configurator.d.ts +23 -0
- package/dist/engine/code-graph-configurator.d.ts.map +1 -0
- package/dist/engine/code-graph-configurator.js +80 -0
- package/dist/engine/code-graph-configurator.js.map +1 -0
- package/dist/engine/continue-config-generator.d.ts +15 -0
- package/dist/engine/continue-config-generator.d.ts.map +1 -0
- package/dist/engine/continue-config-generator.js +53 -0
- package/dist/engine/continue-config-generator.js.map +1 -0
- package/dist/engine/doc-compliance-checker.d.ts +23 -0
- package/dist/engine/doc-compliance-checker.d.ts.map +1 -0
- package/dist/engine/doc-compliance-checker.js +168 -0
- package/dist/engine/doc-compliance-checker.js.map +1 -0
- package/dist/engine/e2e-test-generator.d.ts +19 -0
- package/dist/engine/e2e-test-generator.d.ts.map +1 -0
- package/dist/engine/e2e-test-generator.js +210 -0
- package/dist/engine/e2e-test-generator.js.map +1 -0
- package/dist/engine/ecosystem-detector.d.ts +13 -0
- package/dist/engine/ecosystem-detector.d.ts.map +1 -0
- package/dist/engine/ecosystem-detector.js +128 -0
- package/dist/engine/ecosystem-detector.js.map +1 -0
- package/dist/engine/memory-config-generator.d.ts +8 -0
- package/dist/engine/memory-config-generator.d.ts.map +1 -0
- package/dist/engine/memory-config-generator.js +101 -0
- package/dist/engine/memory-config-generator.js.map +1 -0
- package/dist/engine/pr-spec-validator.d.ts +25 -0
- package/dist/engine/pr-spec-validator.d.ts.map +1 -0
- package/dist/engine/pr-spec-validator.js +172 -0
- package/dist/engine/pr-spec-validator.js.map +1 -0
- package/dist/engine/skill-generator/sections-docs.d.ts +13 -0
- package/dist/engine/skill-generator/sections-docs.d.ts.map +1 -0
- package/dist/engine/skill-generator/sections-docs.js +59 -0
- package/dist/engine/skill-generator/sections-docs.js.map +1 -0
- package/dist/engine/skill-generator/skills-content.d.ts +1 -1
- package/dist/engine/skill-generator/skills-content.d.ts.map +1 -1
- package/dist/engine/skill-generator/skills-content.js +3 -2
- package/dist/engine/skill-generator/skills-content.js.map +1 -1
- package/dist/engine/skill-generator/skills.d.ts +1 -0
- package/dist/engine/skill-generator/skills.d.ts.map +1 -1
- package/dist/engine/skill-generator/skills.js +1 -0
- package/dist/engine/skill-generator/skills.js.map +1 -1
- package/dist/engine/skill-generator.d.ts.map +1 -1
- package/dist/engine/skill-generator.js +21 -2
- package/dist/engine/skill-generator.js.map +1 -1
- package/dist/engine/sweep-issue-generator.d.ts +14 -0
- package/dist/engine/sweep-issue-generator.d.ts.map +1 -0
- package/dist/engine/sweep-issue-generator.js +140 -0
- package/dist/engine/sweep-issue-generator.js.map +1 -0
- package/dist/engine/web-fetcher/docs-intelligence.d.ts +8 -0
- package/dist/engine/web-fetcher/docs-intelligence.d.ts.map +1 -0
- package/dist/engine/web-fetcher/docs-intelligence.js +154 -0
- package/dist/engine/web-fetcher/docs-intelligence.js.map +1 -0
- package/dist/engine/web-fetcher/registry-auto-discovery.d.ts +20 -0
- package/dist/engine/web-fetcher/registry-auto-discovery.d.ts.map +1 -0
- package/dist/engine/web-fetcher/registry-auto-discovery.js +184 -0
- package/dist/engine/web-fetcher/registry-auto-discovery.js.map +1 -0
- package/dist/engine/web-fetcher/stack-detector.d.ts +4 -0
- package/dist/engine/web-fetcher/stack-detector.d.ts.map +1 -0
- package/dist/engine/web-fetcher/stack-detector.js +155 -0
- package/dist/engine/web-fetcher/stack-detector.js.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -1
- package/dist/tools/aider-launcher-handler.d.ts +4 -0
- package/dist/tools/aider-launcher-handler.d.ts.map +1 -0
- package/dist/tools/aider-launcher-handler.js +69 -0
- package/dist/tools/aider-launcher-handler.js.map +1 -0
- package/dist/tools/code-graph-handler.d.ts +6 -0
- package/dist/tools/code-graph-handler.d.ts.map +1 -0
- package/dist/tools/code-graph-handler.js +68 -0
- package/dist/tools/code-graph-handler.js.map +1 -0
- package/dist/tools/continue-config-handler.d.ts +4 -0
- package/dist/tools/continue-config-handler.d.ts.map +1 -0
- package/dist/tools/continue-config-handler.js +88 -0
- package/dist/tools/continue-config-handler.js.map +1 -0
- package/dist/tools/create-spec/spec-builder.d.ts.map +1 -1
- package/dist/tools/create-spec/spec-builder.js +20 -0
- package/dist/tools/create-spec/spec-builder.js.map +1 -1
- package/dist/tools/create-spec-hu/docs-criteria-adapter.d.ts +14 -0
- package/dist/tools/create-spec-hu/docs-criteria-adapter.d.ts.map +1 -0
- package/dist/tools/create-spec-hu/docs-criteria-adapter.js +50 -0
- package/dist/tools/create-spec-hu/docs-criteria-adapter.js.map +1 -0
- package/dist/tools/create-spec-hu.d.ts +1 -1
- package/dist/tools/create-spec-hu.d.ts.map +1 -1
- package/dist/tools/create-spec-hu.js +5 -1
- package/dist/tools/create-spec-hu.js.map +1 -1
- package/dist/tools/create-spec.d.ts.map +1 -1
- package/dist/tools/create-spec.js +2 -2
- package/dist/tools/create-spec.js.map +1 -1
- package/dist/tools/doc-compliance-handler.d.ts +3 -0
- package/dist/tools/doc-compliance-handler.d.ts.map +1 -0
- package/dist/tools/doc-compliance-handler.js +48 -0
- package/dist/tools/doc-compliance-handler.js.map +1 -0
- package/dist/tools/docs-registry-handler.d.ts +6 -0
- package/dist/tools/docs-registry-handler.d.ts.map +1 -0
- package/dist/tools/docs-registry-handler.js +73 -0
- package/dist/tools/docs-registry-handler.js.map +1 -0
- package/dist/tools/e2e-test-generator-handler.d.ts +12 -0
- package/dist/tools/e2e-test-generator-handler.d.ts.map +1 -0
- package/dist/tools/e2e-test-generator-handler.js +54 -0
- package/dist/tools/e2e-test-generator-handler.js.map +1 -0
- package/dist/tools/ecosystem-tools-handler.d.ts +4 -0
- package/dist/tools/ecosystem-tools-handler.d.ts.map +1 -0
- package/dist/tools/ecosystem-tools-handler.js +57 -0
- package/dist/tools/ecosystem-tools-handler.js.map +1 -0
- package/dist/tools/memory-config-handler.d.ts +4 -0
- package/dist/tools/memory-config-handler.d.ts.map +1 -0
- package/dist/tools/memory-config-handler.js +110 -0
- package/dist/tools/memory-config-handler.js.map +1 -0
- package/dist/tools/pr-agent-handler.d.ts +12 -0
- package/dist/tools/pr-agent-handler.d.ts.map +1 -0
- package/dist/tools/pr-agent-handler.js +47 -0
- package/dist/tools/pr-agent-handler.js.map +1 -0
- package/dist/tools/register-aider-tools.d.ts +3 -0
- package/dist/tools/register-aider-tools.d.ts.map +1 -0
- package/dist/tools/register-aider-tools.js +28 -0
- package/dist/tools/register-aider-tools.js.map +1 -0
- package/dist/tools/register-code-graph-tools.d.ts +3 -0
- package/dist/tools/register-code-graph-tools.d.ts.map +1 -0
- package/dist/tools/register-code-graph-tools.js +36 -0
- package/dist/tools/register-code-graph-tools.js.map +1 -0
- package/dist/tools/register-continue-tools.d.ts +3 -0
- package/dist/tools/register-continue-tools.d.ts.map +1 -0
- package/dist/tools/register-continue-tools.js +38 -0
- package/dist/tools/register-continue-tools.js.map +1 -0
- package/dist/tools/register-doc-compliance-tools.d.ts +3 -0
- package/dist/tools/register-doc-compliance-tools.d.ts.map +1 -0
- package/dist/tools/register-doc-compliance-tools.js +18 -0
- package/dist/tools/register-doc-compliance-tools.js.map +1 -0
- package/dist/tools/register-docs-registry-tools.d.ts +3 -0
- package/dist/tools/register-docs-registry-tools.d.ts.map +1 -0
- package/dist/tools/register-docs-registry-tools.js +35 -0
- package/dist/tools/register-docs-registry-tools.js.map +1 -0
- package/dist/tools/register-e2e-test-generator-tools.d.ts +3 -0
- package/dist/tools/register-e2e-test-generator-tools.d.ts.map +1 -0
- package/dist/tools/register-e2e-test-generator-tools.js +35 -0
- package/dist/tools/register-e2e-test-generator-tools.js.map +1 -0
- package/dist/tools/register-memory-config-tools.d.ts +3 -0
- package/dist/tools/register-memory-config-tools.d.ts.map +1 -0
- package/dist/tools/register-memory-config-tools.js +34 -0
- package/dist/tools/register-memory-config-tools.js.map +1 -0
- package/dist/tools/register-pr-agent-tools.d.ts +3 -0
- package/dist/tools/register-pr-agent-tools.d.ts.map +1 -0
- package/dist/tools/register-pr-agent-tools.js +34 -0
- package/dist/tools/register-pr-agent-tools.js.map +1 -0
- package/dist/tools/register-sweep-tools.d.ts +3 -0
- package/dist/tools/register-sweep-tools.d.ts.map +1 -0
- package/dist/tools/register-sweep-tools.js +42 -0
- package/dist/tools/register-sweep-tools.js.map +1 -0
- package/dist/tools/register-token-optimizer-tools.d.ts +3 -0
- package/dist/tools/register-token-optimizer-tools.d.ts.map +1 -0
- package/dist/tools/register-token-optimizer-tools.js +22 -0
- package/dist/tools/register-token-optimizer-tools.js.map +1 -0
- package/dist/tools/sweep-integration-handler.d.ts +4 -0
- package/dist/tools/sweep-integration-handler.d.ts.map +1 -0
- package/dist/tools/sweep-integration-handler.js +60 -0
- package/dist/tools/sweep-integration-handler.js.map +1 -0
- package/dist/types/aider.d.ts +21 -0
- package/dist/types/aider.d.ts.map +1 -0
- package/dist/types/aider.js +3 -0
- package/dist/types/aider.js.map +1 -0
- package/dist/types/code-graph-integration.d.ts +22 -0
- package/dist/types/code-graph-integration.d.ts.map +1 -0
- package/dist/types/code-graph-integration.js +3 -0
- package/dist/types/code-graph-integration.js.map +1 -0
- package/dist/types/continue-integration.d.ts +32 -0
- package/dist/types/continue-integration.d.ts.map +1 -0
- package/dist/types/continue-integration.js +3 -0
- package/dist/types/continue-integration.js.map +1 -0
- package/dist/types/docs.d.ts +70 -0
- package/dist/types/docs.d.ts.map +1 -1
- package/dist/types/e2e-test-generator.d.ts +27 -0
- package/dist/types/e2e-test-generator.d.ts.map +1 -0
- package/dist/types/e2e-test-generator.js +3 -0
- package/dist/types/e2e-test-generator.js.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/mcp.d.ts +17 -0
- package/dist/types/mcp.d.ts.map +1 -1
- package/dist/types/pr-agent.d.ts +28 -0
- package/dist/types/pr-agent.d.ts.map +1 -0
- package/dist/types/pr-agent.js +3 -0
- package/dist/types/pr-agent.js.map +1 -0
- package/dist/types/spec/core.d.ts +2 -0
- package/dist/types/spec/core.d.ts.map +1 -1
- package/dist/types/sweep.d.ts +22 -0
- package/dist/types/sweep.d.ts.map +1 -0
- package/dist/types/sweep.js +3 -0
- package/dist/types/sweep.js.map +1 -0
- package/dist/types/tooling/index.d.ts +2 -0
- package/dist/types/tooling/index.d.ts.map +1 -1
- package/dist/types/tooling/memory-config.d.ts +25 -0
- package/dist/types/tooling/memory-config.d.ts.map +1 -0
- package/dist/types/tooling/memory-config.js +3 -0
- package/dist/types/tooling/memory-config.js.map +1 -0
- package/dist/types/tooling/token-optimizer.d.ts +42 -0
- package/dist/types/tooling/token-optimizer.d.ts.map +1 -0
- package/dist/types/tooling/token-optimizer.js +3 -0
- package/dist/types/tooling/token-optimizer.js.map +1 -0
- package/dist/types/tooling.d.ts +1 -1
- package/dist/types/tooling.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/config/dev-lifecycle-catalog.json +22 -0
- package/src/config/license-plans.json +20 -1
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// engine/sweep-issue-generator.ts — Pure functions for SPEC-379 Sweep AI Integration
|
|
2
|
+
import { readFile, readdir } from 'node:fs/promises';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { execSync } from 'node:child_process';
|
|
5
|
+
import { parseFrontmatter } from './frontmatter-parser.js';
|
|
6
|
+
import { extractSection, extractListItems } from './validator/extractors.js';
|
|
7
|
+
const SPECS_DIR = 'planu/specs';
|
|
8
|
+
/**
|
|
9
|
+
* Find the spec directory for a given specId inside projectPath/planu/specs.
|
|
10
|
+
* Returns null if not found.
|
|
11
|
+
*/
|
|
12
|
+
async function findSpecDir(specId, projectPath) {
|
|
13
|
+
const specsRoot = join(projectPath, SPECS_DIR);
|
|
14
|
+
let entries;
|
|
15
|
+
try {
|
|
16
|
+
entries = await readdir(specsRoot);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
const prefix = specId.toUpperCase() + '-';
|
|
22
|
+
const dir = entries.find((e) => e.toUpperCase().startsWith(prefix));
|
|
23
|
+
if (!dir) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
return join(specsRoot, dir);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Read a list of affected files from technical.md.
|
|
30
|
+
* Returns empty array when technical.md is missing or has no list items.
|
|
31
|
+
*/
|
|
32
|
+
async function readAffectedFilesForSweep(specDir) {
|
|
33
|
+
const techPath = join(specDir, 'technical.md');
|
|
34
|
+
let raw;
|
|
35
|
+
try {
|
|
36
|
+
raw = await readFile(techPath, 'utf-8');
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
const section = extractSection(raw, 'affected files', 'archivos afectados');
|
|
42
|
+
return section ? extractListItems(section) : extractListItems(raw);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Build the GitHub issue body for Sweep AI.
|
|
46
|
+
*/
|
|
47
|
+
export function buildSweepIssueBody(specId, specSlug, title, description, criteria, affectedFiles) {
|
|
48
|
+
const criteriaLines = criteria.length > 0
|
|
49
|
+
? criteria.map((c) => `- [ ] ${c}`).join('\n')
|
|
50
|
+
: '- [ ] See spec.md for acceptance criteria';
|
|
51
|
+
const filesSection = affectedFiles.length > 0
|
|
52
|
+
? ['## Affected Files', '', ...affectedFiles.map((f) => `- \`${f}\``), ''].join('\n')
|
|
53
|
+
: '';
|
|
54
|
+
return [
|
|
55
|
+
`## Spec: ${title}`,
|
|
56
|
+
``,
|
|
57
|
+
description || `Implementation of ${specId}.`,
|
|
58
|
+
``,
|
|
59
|
+
`## Acceptance Criteria`,
|
|
60
|
+
criteriaLines,
|
|
61
|
+
``,
|
|
62
|
+
filesSection,
|
|
63
|
+
`---`,
|
|
64
|
+
`Spec: ${specId} | [View in Planu](planu/specs/${specSlug}/spec.md)`,
|
|
65
|
+
]
|
|
66
|
+
.join('\n')
|
|
67
|
+
.replace(/\n{3,}/g, '\n\n')
|
|
68
|
+
.trim();
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Generate and optionally create a GitHub issue for Sweep AI.
|
|
72
|
+
*/
|
|
73
|
+
export async function createSweepIssue(specId, projectPath, githubRepo, dryRun) {
|
|
74
|
+
const specDir = await findSpecDir(specId, projectPath);
|
|
75
|
+
if (!specDir) {
|
|
76
|
+
throw new Error(`Spec directory for ${specId} not found in ${join(projectPath, SPECS_DIR)}. ` +
|
|
77
|
+
`Ensure the spec exists and follows the SPEC-NNN-slug naming convention.`);
|
|
78
|
+
}
|
|
79
|
+
const specMdPath = join(specDir, 'spec.md');
|
|
80
|
+
let specContent;
|
|
81
|
+
try {
|
|
82
|
+
specContent = await readFile(specMdPath, 'utf-8');
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
throw new Error(`spec.md not found in ${specDir}.`);
|
|
86
|
+
}
|
|
87
|
+
const { metadata, body } = parseFrontmatter(specContent);
|
|
88
|
+
const title = typeof metadata.title === 'string' ? metadata.title : specId;
|
|
89
|
+
const description = typeof metadata.description === 'string' ? metadata.description : '';
|
|
90
|
+
const acSection = extractSection(body, 'acceptance criteria', 'criterios de aceptaci');
|
|
91
|
+
const criteria = acSection ? extractListItems(acSection) : [];
|
|
92
|
+
const affectedFiles = await readAffectedFilesForSweep(specDir);
|
|
93
|
+
// Extract the folder name (slug) from the specDir path for the footer link
|
|
94
|
+
const specSlug = specDir.split('/').pop() ?? specId;
|
|
95
|
+
const issueBody = buildSweepIssueBody(specId, specSlug, title, description, criteria, affectedFiles);
|
|
96
|
+
const issueTitle = `feat(${specId}): ${title}`;
|
|
97
|
+
if (dryRun) {
|
|
98
|
+
return { body: issueBody, dryRun: true, issueTitle };
|
|
99
|
+
}
|
|
100
|
+
// Create the actual GitHub issue using gh CLI
|
|
101
|
+
const escapedBody = issueBody.replace(/"/g, '\\"').replace(/`/g, '\\`');
|
|
102
|
+
const cmd = `gh issue create --repo "${githubRepo}" --title "${issueTitle}" --label sweep --body "${escapedBody}"`;
|
|
103
|
+
let issueUrl;
|
|
104
|
+
try {
|
|
105
|
+
issueUrl = execSync(cmd, { encoding: 'utf-8' }).trim();
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
109
|
+
throw new Error(`Failed to create GitHub issue: ${msg}. ` +
|
|
110
|
+
`Ensure gh is installed, authenticated, and the 'sweep' label exists on the repo.`, { cause: err });
|
|
111
|
+
}
|
|
112
|
+
return { issueUrl, body: issueBody, dryRun: false, issueTitle };
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Check whether gh CLI is installed and if the sweep label exists on the repo.
|
|
116
|
+
*/
|
|
117
|
+
export function checkSweepStatus(githubRepo) {
|
|
118
|
+
try {
|
|
119
|
+
const out = execSync('which gh', { encoding: 'utf-8' }).trim();
|
|
120
|
+
if (out.length === 0) {
|
|
121
|
+
return { ghInstalled: false, sweepLabelExists: false, githubRepo };
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
return { ghInstalled: false, sweepLabelExists: false, githubRepo };
|
|
126
|
+
}
|
|
127
|
+
if (!githubRepo) {
|
|
128
|
+
return { ghInstalled: true, sweepLabelExists: false, githubRepo };
|
|
129
|
+
}
|
|
130
|
+
let sweepLabelExists;
|
|
131
|
+
try {
|
|
132
|
+
const labels = execSync(`gh label list --repo "${githubRepo}"`, { encoding: 'utf-8' });
|
|
133
|
+
sweepLabelExists = labels.toLowerCase().includes('sweep');
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
sweepLabelExists = false;
|
|
137
|
+
}
|
|
138
|
+
return { ghInstalled: true, sweepLabelExists, githubRepo };
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=sweep-issue-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sweep-issue-generator.js","sourceRoot":"","sources":["../../src/engine/sweep-issue-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { StructuredDocsResult } from '../../types/index.js';
|
|
2
|
+
export declare function extractStructuredDocs(html: string, tech: string): StructuredDocsResult;
|
|
3
|
+
export declare function buildFallbackResult(tech: string): StructuredDocsResult;
|
|
4
|
+
export declare function fetchDocsBatch(techs: string[], options?: {
|
|
5
|
+
timeout?: number;
|
|
6
|
+
concurrency?: number;
|
|
7
|
+
}): Promise<Map<string, StructuredDocsResult>>;
|
|
8
|
+
//# sourceMappingURL=docs-intelligence.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs-intelligence.d.ts","sourceRoot":"","sources":["../../../src/engine/web-fetcher/docs-intelligence.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AA+DjE,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,oBAAoB,CAwCtF;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,CAatE;AA4BD,wBAAsB,cAAc,CAClC,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GACnD,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,CAwB5C"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// Planu — Web Fetcher: Universal Docs Intelligence Engine (SPEC-382)
|
|
2
|
+
import { consultDocsImpl } from './docs-fetcher.js';
|
|
3
|
+
const BEST_PRACTICE_PATTERNS = [
|
|
4
|
+
/\bbest practice[s]?\b/i,
|
|
5
|
+
/\brecommended?\b/i,
|
|
6
|
+
/\byou should\b/i,
|
|
7
|
+
/\balways\b.{0,40}\b(use|prefer|ensure|check)/i,
|
|
8
|
+
/\bprefer\b.{0,40}\bover\b/i,
|
|
9
|
+
/\buse\b.{0,20}\bfor\b.{0,40}/i,
|
|
10
|
+
];
|
|
11
|
+
const ANTI_PATTERN_PATTERNS = [
|
|
12
|
+
/\bavoid\b/i,
|
|
13
|
+
/\bdeprecated\b/i,
|
|
14
|
+
/\bdo not\b/i,
|
|
15
|
+
/\bnever\b/i,
|
|
16
|
+
/\bnot recommended\b/i,
|
|
17
|
+
/\bobsolete\b/i,
|
|
18
|
+
];
|
|
19
|
+
const CONVENTION_PATTERNS = [
|
|
20
|
+
/\bconvention\b/i,
|
|
21
|
+
/\bstyle\b.{0,20}\bguid/i,
|
|
22
|
+
/\bnaming\b/i,
|
|
23
|
+
/\bformat\b.{0,20}\bshould\b/i,
|
|
24
|
+
/\bfollow.{0,20}\bpattern\b/i,
|
|
25
|
+
/\bfile structure\b/i,
|
|
26
|
+
];
|
|
27
|
+
const VERSION_PATTERNS = [
|
|
28
|
+
/\bv?\d+(\.\d+){0,2}\b.{0,60}\b(migration|upgrade|breaking|changed)\b/i,
|
|
29
|
+
/\b(migration|upgrade|breaking change)\b.{0,60}\bv?\d+(\.\d+){0,2}\b/i,
|
|
30
|
+
/\bdeprecated in\b.{0,30}\bv?\d+/i,
|
|
31
|
+
];
|
|
32
|
+
const TOOL_NAME_PATTERNS = /\b(npm|pnpm|yarn|npx|pip|cargo|brew|apt|go get)\b.{0,80}/i;
|
|
33
|
+
function splitIntoLines(text) {
|
|
34
|
+
return text
|
|
35
|
+
.split(/[\n.!?]/)
|
|
36
|
+
.map((l) => l.trim())
|
|
37
|
+
.filter((l) => l.length > 15 && l.length < 300);
|
|
38
|
+
}
|
|
39
|
+
function stripHtml(html) {
|
|
40
|
+
return html
|
|
41
|
+
.replace(/<script[\s\S]*?<\/script>/gi, '')
|
|
42
|
+
.replace(/<style[\s\S]*?<\/style>/gi, '')
|
|
43
|
+
.replace(/<[^>]+>/g, ' ')
|
|
44
|
+
.replace(/&[a-z]+;/gi, ' ')
|
|
45
|
+
.replace(/\s+/g, ' ')
|
|
46
|
+
.trim();
|
|
47
|
+
}
|
|
48
|
+
function matchesAny(line, patterns) {
|
|
49
|
+
return patterns.some((p) => p.test(line));
|
|
50
|
+
}
|
|
51
|
+
function dedup(items) {
|
|
52
|
+
return [...new Set(items)];
|
|
53
|
+
}
|
|
54
|
+
export function extractStructuredDocs(html, tech) {
|
|
55
|
+
const text = stripHtml(html);
|
|
56
|
+
const lines = splitIntoLines(text);
|
|
57
|
+
const bestPractices = [];
|
|
58
|
+
const antiPatterns = [];
|
|
59
|
+
const conventions = [];
|
|
60
|
+
const versionNotes = [];
|
|
61
|
+
const toolingRecommendations = [];
|
|
62
|
+
for (const line of lines) {
|
|
63
|
+
if (matchesAny(line, ANTI_PATTERN_PATTERNS)) {
|
|
64
|
+
antiPatterns.push(line);
|
|
65
|
+
}
|
|
66
|
+
else if (matchesAny(line, BEST_PRACTICE_PATTERNS)) {
|
|
67
|
+
bestPractices.push(line);
|
|
68
|
+
}
|
|
69
|
+
else if (matchesAny(line, CONVENTION_PATTERNS)) {
|
|
70
|
+
conventions.push(line);
|
|
71
|
+
}
|
|
72
|
+
if (matchesAny(line, VERSION_PATTERNS)) {
|
|
73
|
+
versionNotes.push(line);
|
|
74
|
+
}
|
|
75
|
+
if (TOOL_NAME_PATTERNS.test(line)) {
|
|
76
|
+
toolingRecommendations.push(line);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
tech,
|
|
81
|
+
docsUrl: '',
|
|
82
|
+
bestPractices: dedup(bestPractices).slice(0, 10),
|
|
83
|
+
antiPatterns: dedup(antiPatterns).slice(0, 10),
|
|
84
|
+
conventions: dedup(conventions).slice(0, 10),
|
|
85
|
+
versionNotes: dedup(versionNotes).slice(0, 5),
|
|
86
|
+
toolingRecommendations: dedup(toolingRecommendations).slice(0, 5),
|
|
87
|
+
source: 'discovered',
|
|
88
|
+
fetchedAt: new Date().toISOString(),
|
|
89
|
+
stale: false,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
export function buildFallbackResult(tech) {
|
|
93
|
+
return {
|
|
94
|
+
tech,
|
|
95
|
+
docsUrl: '',
|
|
96
|
+
bestPractices: [],
|
|
97
|
+
antiPatterns: [],
|
|
98
|
+
conventions: [],
|
|
99
|
+
versionNotes: [],
|
|
100
|
+
toolingRecommendations: [],
|
|
101
|
+
source: 'fallback',
|
|
102
|
+
fetchedAt: new Date().toISOString(),
|
|
103
|
+
stale: true,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
async function fetchOneTech(tech, timeoutMs) {
|
|
107
|
+
try {
|
|
108
|
+
const controller = new AbortController();
|
|
109
|
+
const timer = setTimeout(() => {
|
|
110
|
+
controller.abort();
|
|
111
|
+
}, timeoutMs);
|
|
112
|
+
let result;
|
|
113
|
+
try {
|
|
114
|
+
const docsResult = await consultDocsImpl(tech, tech);
|
|
115
|
+
const html = [docsResult.summary, ...docsResult.bestPractices].join('\n');
|
|
116
|
+
result = extractStructuredDocs(html, tech);
|
|
117
|
+
result.docsUrl = docsResult.docsUrl;
|
|
118
|
+
result.source = docsResult.source === 'local-fallback' ? 'fallback' : 'registry';
|
|
119
|
+
result.stale = docsResult.stale ?? false;
|
|
120
|
+
result.fetchedAt = docsResult.fetchedAt ?? new Date().toISOString();
|
|
121
|
+
}
|
|
122
|
+
finally {
|
|
123
|
+
clearTimeout(timer);
|
|
124
|
+
}
|
|
125
|
+
return result;
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
return buildFallbackResult(tech);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
export async function fetchDocsBatch(techs, options) {
|
|
132
|
+
const timeoutMs = options?.timeout ?? 10_000;
|
|
133
|
+
const concurrency = options?.concurrency ?? 3;
|
|
134
|
+
const results = new Map();
|
|
135
|
+
for (let i = 0; i < techs.length; i += concurrency) {
|
|
136
|
+
const batch = techs.slice(i, i + concurrency);
|
|
137
|
+
const settled = await Promise.allSettled(batch.map((tech) => fetchOneTech(tech, timeoutMs)));
|
|
138
|
+
for (let j = 0; j < batch.length; j++) {
|
|
139
|
+
const tech = batch[j];
|
|
140
|
+
if (tech === undefined) {
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
const outcome = settled[j];
|
|
144
|
+
if (outcome === undefined || outcome.status === 'rejected') {
|
|
145
|
+
results.set(tech, buildFallbackResult(tech));
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
results.set(tech, outcome.value);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return results;
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=docs-intelligence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs-intelligence.js","sourceRoot":"","sources":["../../../src/engine/web-fetcher/docs-intelligence.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { DiscoveredDocsEntry, DocsRegistryHealth } from '../../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Verify that a URL is alive with a HEAD request (timeout 3s).
|
|
4
|
+
* Returns true if status is 200, 301, or 302.
|
|
5
|
+
*/
|
|
6
|
+
export declare function validateRegistryUrl(url: string): Promise<boolean>;
|
|
7
|
+
/**
|
|
8
|
+
* Discover docs URL for a tech package by querying npm, PyPI, and crates.io.
|
|
9
|
+
* Respects a 1 req/s rate limit per registry via simple delay.
|
|
10
|
+
* Returns null if not found anywhere.
|
|
11
|
+
*/
|
|
12
|
+
export declare function discoverDocsUrl(tech: string): Promise<DiscoveredDocsEntry | null>;
|
|
13
|
+
/**
|
|
14
|
+
* Batch validate all entries in the docs registry.
|
|
15
|
+
* Categorizes each entry as healthy (<=2s), slow (2-5s), or broken (timeout/error).
|
|
16
|
+
*/
|
|
17
|
+
export declare function checkRegistryHealth(entries: Record<string, {
|
|
18
|
+
base: string;
|
|
19
|
+
}>): Promise<DocsRegistryHealth>;
|
|
20
|
+
//# sourceMappingURL=registry-auto-discovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry-auto-discovery.d.ts","sourceRoot":"","sources":["../../../src/engine/web-fetcher/registry-auto-discovery.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,mBAAmB,EACnB,kBAAkB,EAInB,MAAM,sBAAsB,CAAC;AAkH9B;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAGvE;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CA6BvF;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GACxC,OAAO,CAAC,kBAAkB,CAAC,CAoC7B"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
// Planu — SPEC-386: Docs Registry Auto-Discovery
|
|
2
|
+
// Discovers docs URLs from npm/pypi/crates.io package metadata
|
|
3
|
+
const RATE_LIMIT_DELAY_MS = 1000;
|
|
4
|
+
const VERIFY_TIMEOUT_MS = 3000;
|
|
5
|
+
const HEALTH_TIMEOUT_MS = 5000;
|
|
6
|
+
const SLOW_THRESHOLD_MS = 2000;
|
|
7
|
+
/** Sleep for a given number of milliseconds. */
|
|
8
|
+
function sleep(ms) {
|
|
9
|
+
return new Promise((resolve) => {
|
|
10
|
+
setTimeout(resolve, ms);
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
/** Perform a HEAD request with a timeout, returning the HTTP status or null on failure. */
|
|
14
|
+
async function headWithTimeout(url, timeoutMs) {
|
|
15
|
+
const controller = new AbortController();
|
|
16
|
+
const timer = setTimeout(() => {
|
|
17
|
+
controller.abort();
|
|
18
|
+
}, timeoutMs);
|
|
19
|
+
try {
|
|
20
|
+
const res = await fetch(url, { method: 'HEAD', signal: controller.signal, redirect: 'follow' });
|
|
21
|
+
return res.status;
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
finally {
|
|
27
|
+
clearTimeout(timer);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/** Try to fetch JSON from a URL with a timeout. Returns null on any failure. */
|
|
31
|
+
async function fetchJson(url, timeoutMs = HEALTH_TIMEOUT_MS) {
|
|
32
|
+
const controller = new AbortController();
|
|
33
|
+
const timer = setTimeout(() => {
|
|
34
|
+
controller.abort();
|
|
35
|
+
}, timeoutMs);
|
|
36
|
+
try {
|
|
37
|
+
const res = await fetch(url, { signal: controller.signal });
|
|
38
|
+
if (!res.ok) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
return (await res.json());
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
finally {
|
|
47
|
+
clearTimeout(timer);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/** Extract a clean HTTPS docs URL from npm package metadata. */
|
|
51
|
+
function extractNpmDocsUrl(pkg) {
|
|
52
|
+
if (pkg.homepage?.startsWith('http')) {
|
|
53
|
+
return pkg.homepage;
|
|
54
|
+
}
|
|
55
|
+
if (pkg.docs?.startsWith('http')) {
|
|
56
|
+
return pkg.docs;
|
|
57
|
+
}
|
|
58
|
+
const repo = typeof pkg.repository === 'string' ? pkg.repository : pkg.repository?.url;
|
|
59
|
+
if (repo) {
|
|
60
|
+
const clean = repo
|
|
61
|
+
.replace(/^git\+/, '')
|
|
62
|
+
.replace(/\.git$/, '')
|
|
63
|
+
.replace(/^git:\/\//, 'https://');
|
|
64
|
+
if (clean.startsWith('https://')) {
|
|
65
|
+
return clean;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
/** Try npm registry to find docs URL for a package. */
|
|
71
|
+
async function tryNpm(tech) {
|
|
72
|
+
const pkg = await fetchJson(`https://registry.npmjs.org/${encodeURIComponent(tech)}`);
|
|
73
|
+
if (!pkg) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
return extractNpmDocsUrl(pkg);
|
|
77
|
+
}
|
|
78
|
+
/** Try PyPI registry to find docs URL for a package. */
|
|
79
|
+
async function tryPypi(tech) {
|
|
80
|
+
const data = await fetchJson(`https://pypi.org/pypi/${encodeURIComponent(tech)}/json`);
|
|
81
|
+
if (!data?.info) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
const urls = data.info.project_urls ?? {};
|
|
85
|
+
const docsUrl = urls.Documentation ?? urls.documentation ?? urls.Docs ?? urls.Homepage ?? data.info.home_page;
|
|
86
|
+
if (docsUrl?.startsWith('http')) {
|
|
87
|
+
return docsUrl;
|
|
88
|
+
}
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
/** Try crates.io registry to find docs URL for a crate. */
|
|
92
|
+
async function tryCrates(tech) {
|
|
93
|
+
const data = await fetchJson(`https://crates.io/api/v1/crates/${encodeURIComponent(tech)}`);
|
|
94
|
+
if (!data?.crate) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
const url = data.crate.documentation ?? data.crate.homepage;
|
|
98
|
+
if (url?.startsWith('http')) {
|
|
99
|
+
return url;
|
|
100
|
+
}
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Verify that a URL is alive with a HEAD request (timeout 3s).
|
|
105
|
+
* Returns true if status is 200, 301, or 302.
|
|
106
|
+
*/
|
|
107
|
+
export async function validateRegistryUrl(url) {
|
|
108
|
+
const status = await headWithTimeout(url, VERIFY_TIMEOUT_MS);
|
|
109
|
+
return status !== null && (status === 200 || status === 301 || status === 302);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Discover docs URL for a tech package by querying npm, PyPI, and crates.io.
|
|
113
|
+
* Respects a 1 req/s rate limit per registry via simple delay.
|
|
114
|
+
* Returns null if not found anywhere.
|
|
115
|
+
*/
|
|
116
|
+
export async function discoverDocsUrl(tech) {
|
|
117
|
+
const tryWithDelay = async (fn) => {
|
|
118
|
+
const result = await fn();
|
|
119
|
+
await sleep(RATE_LIMIT_DELAY_MS);
|
|
120
|
+
return result;
|
|
121
|
+
};
|
|
122
|
+
const registries = [
|
|
123
|
+
{ source: 'npm', fn: () => tryNpm(tech) },
|
|
124
|
+
{ source: 'pypi', fn: () => tryPypi(tech) },
|
|
125
|
+
{ source: 'crates', fn: () => tryCrates(tech) },
|
|
126
|
+
];
|
|
127
|
+
for (const { source, fn } of registries) {
|
|
128
|
+
const url = await tryWithDelay(fn);
|
|
129
|
+
if (url) {
|
|
130
|
+
const verified = await validateRegistryUrl(url);
|
|
131
|
+
return {
|
|
132
|
+
tech,
|
|
133
|
+
docsUrl: url,
|
|
134
|
+
source,
|
|
135
|
+
discoveredAt: new Date().toISOString(),
|
|
136
|
+
verified,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Batch validate all entries in the docs registry.
|
|
144
|
+
* Categorizes each entry as healthy (<=2s), slow (2-5s), or broken (timeout/error).
|
|
145
|
+
*/
|
|
146
|
+
export async function checkRegistryHealth(entries) {
|
|
147
|
+
const healthy = [];
|
|
148
|
+
const broken = [];
|
|
149
|
+
const slow = [];
|
|
150
|
+
const checks = Object.entries(entries).map(async ([key, entry]) => {
|
|
151
|
+
const start = Date.now();
|
|
152
|
+
const controller = new AbortController();
|
|
153
|
+
const timer = setTimeout(() => {
|
|
154
|
+
controller.abort();
|
|
155
|
+
}, HEALTH_TIMEOUT_MS);
|
|
156
|
+
try {
|
|
157
|
+
const res = await fetch(entry.base, {
|
|
158
|
+
method: 'HEAD',
|
|
159
|
+
signal: controller.signal,
|
|
160
|
+
redirect: 'follow',
|
|
161
|
+
});
|
|
162
|
+
const elapsed = Date.now() - start;
|
|
163
|
+
const ok = res.status === 200 || res.status === 301 || res.status === 302;
|
|
164
|
+
if (!ok) {
|
|
165
|
+
broken.push(key);
|
|
166
|
+
}
|
|
167
|
+
else if (elapsed > SLOW_THRESHOLD_MS) {
|
|
168
|
+
slow.push(key);
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
healthy.push(key);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
broken.push(key);
|
|
176
|
+
}
|
|
177
|
+
finally {
|
|
178
|
+
clearTimeout(timer);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
await Promise.all(checks);
|
|
182
|
+
return { healthy, broken, slow };
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=registry-auto-discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry-auto-discovery.js","sourceRoot":"","sources":["../../../src/engine/web-fetcher/registry-auto-discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stack-detector.d.ts","sourceRoot":"","sources":["../../../src/engine/web-fetcher/stack-detector.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AA2EzD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,EAAE,CAyChE;AAiCD,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE,CAgBvE"}
|