feat(voyage)!: marketplace handoff — rename plugins/ultraplan-local to plugins/voyage [skip-docs]
Session 5 of voyage-rebrand (V6). Operator-authorized cross-plugin scope. - git mv plugins/ultraplan-local plugins/voyage (rename detected, history preserved) - .claude-plugin/marketplace.json: voyage entry replaces ultraplan-local - CLAUDE.md: voyage row in plugin list, voyage in design-system consumer list - README.md: bulk rename ultra*-local commands -> trek* commands; ultraplan-local refs -> voyage; type discriminators (type: trekbrief/trekreview); session-title pattern (voyage:<command>:<slug>); v4.0.0 release-note paragraph - plugins/voyage/.claude-plugin/plugin.json: homepage/repository URLs point to monorepo voyage path - plugins/voyage/verify.sh: drop URL whitelist exception (no longer needed) Closes voyage-rebrand. bash plugins/voyage/verify.sh PASS 7/7. npm test 361/361.
This commit is contained in:
parent
8f1bf9b7b4
commit
7a90d348ad
149 changed files with 26 additions and 33 deletions
|
|
@ -1,106 +0,0 @@
|
|||
// lib/parsers/project-discovery.mjs
|
||||
// Discover ultra-suite artifacts inside a project directory.
|
||||
//
|
||||
// Layout (post-v3.0.0 project-directory contract):
|
||||
// .claude/projects/<YYYY-MM-DD>-<slug>/
|
||||
// brief.md
|
||||
// research/<NN>-<slug>.md (sorted by filename)
|
||||
// architecture/overview.md (opt-in, owned by separate ultra-cc-architect plugin)
|
||||
// plan.md
|
||||
// progress.json
|
||||
|
||||
import { existsSync, readdirSync, statSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* projectDir: string,
|
||||
* brief: string|null,
|
||||
* research: string[],
|
||||
* architecture: { overview: string|null, gaps: string|null, looseFiles: string[] },
|
||||
* plan: string|null,
|
||||
* progress: string|null,
|
||||
* review: string|null,
|
||||
* }} ProjectArtifacts
|
||||
*/
|
||||
|
||||
/** @returns {ProjectArtifacts} */
|
||||
export function discoverProject(projectDir) {
|
||||
const out = {
|
||||
projectDir,
|
||||
brief: null,
|
||||
research: [],
|
||||
architecture: { overview: null, gaps: null, looseFiles: [] },
|
||||
plan: null,
|
||||
progress: null,
|
||||
review: null,
|
||||
};
|
||||
|
||||
if (!projectDir || !existsSync(projectDir) || !statSync(projectDir).isDirectory()) {
|
||||
return out;
|
||||
}
|
||||
|
||||
const briefPath = join(projectDir, 'brief.md');
|
||||
if (existsSync(briefPath) && statSync(briefPath).isFile()) out.brief = briefPath;
|
||||
|
||||
const planPath = join(projectDir, 'plan.md');
|
||||
if (existsSync(planPath) && statSync(planPath).isFile()) out.plan = planPath;
|
||||
|
||||
const progressPath = join(projectDir, 'progress.json');
|
||||
if (existsSync(progressPath) && statSync(progressPath).isFile()) out.progress = progressPath;
|
||||
|
||||
const reviewPath = join(projectDir, 'review.md');
|
||||
if (existsSync(reviewPath) && statSync(reviewPath).isFile()) out.review = reviewPath;
|
||||
|
||||
const researchDir = join(projectDir, 'research');
|
||||
if (existsSync(researchDir) && statSync(researchDir).isDirectory()) {
|
||||
out.research = readdirSync(researchDir)
|
||||
.filter(f => f.endsWith('.md'))
|
||||
.sort()
|
||||
.map(f => join(researchDir, f));
|
||||
}
|
||||
|
||||
const archDir = join(projectDir, 'architecture');
|
||||
if (existsSync(archDir) && statSync(archDir).isDirectory()) {
|
||||
const overviewPath = join(archDir, 'overview.md');
|
||||
const gapsPath = join(archDir, 'gaps.md');
|
||||
if (existsSync(overviewPath)) out.architecture.overview = overviewPath;
|
||||
if (existsSync(gapsPath)) out.architecture.gaps = gapsPath;
|
||||
const all = readdirSync(archDir).filter(f => f.endsWith('.md'));
|
||||
out.architecture.looseFiles = all
|
||||
.filter(f => f !== 'overview.md' && f !== 'gaps.md')
|
||||
.map(f => join(archDir, f));
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that artifact set is consistent for a given pipeline phase.
|
||||
* Phase = 'brief' | 'research' | 'plan' | 'execute' | 'review'.
|
||||
*/
|
||||
export function checkPhaseRequirements(artifacts, phase) {
|
||||
const errors = [];
|
||||
const warnings = [];
|
||||
if (phase === 'research' && !artifacts.brief) {
|
||||
errors.push({ code: 'PROJECT_NO_BRIEF', message: 'research phase requires brief.md' });
|
||||
}
|
||||
if (phase === 'plan' && !artifacts.brief) {
|
||||
errors.push({ code: 'PROJECT_NO_BRIEF', message: 'plan phase requires brief.md' });
|
||||
}
|
||||
if (phase === 'execute' && !artifacts.plan) {
|
||||
errors.push({ code: 'PROJECT_NO_PLAN', message: 'execute phase requires plan.md' });
|
||||
}
|
||||
if (phase === 'review') {
|
||||
if (!artifacts.brief) {
|
||||
errors.push({ code: 'PROJECT_NO_BRIEF', message: 'review phase requires brief.md' });
|
||||
}
|
||||
if (!artifacts.progress) {
|
||||
warnings.push({
|
||||
code: 'PROJECT_NO_PROGRESS',
|
||||
message: 'review phase: progress.json absent — scope detection will fall back to brief.md mtime',
|
||||
});
|
||||
}
|
||||
}
|
||||
return { valid: errors.length === 0, errors, warnings, parsed: artifacts };
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue