jumpstart-mode 1.1.11 → 1.1.13
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/.github/agents/jumpstart-adversary.agent.md +2 -1
- package/.github/agents/jumpstart-architect.agent.md +6 -7
- package/.github/agents/jumpstart-challenger.agent.md +2 -1
- package/.github/agents/jumpstart-developer.agent.md +1 -1
- package/.github/agents/jumpstart-devops.agent.md +2 -2
- package/.github/agents/jumpstart-diagram-verifier.agent.md +2 -1
- package/.github/agents/jumpstart-maintenance.agent.md +1 -0
- package/.github/agents/jumpstart-performance.agent.md +1 -0
- package/.github/agents/jumpstart-pm.agent.md +1 -1
- package/.github/agents/jumpstart-refactor.agent.md +1 -0
- package/.github/agents/jumpstart-requirements-extractor.agent.md +1 -0
- package/.github/agents/jumpstart-researcher.agent.md +1 -0
- package/.github/agents/jumpstart-retrospective.agent.md +1 -0
- package/.github/agents/jumpstart-reviewer.agent.md +2 -0
- package/.github/agents/jumpstart-scout.agent.md +1 -1
- package/.github/agents/jumpstart-scrum-master.agent.md +1 -0
- package/.github/agents/jumpstart-security.agent.md +2 -1
- package/.github/agents/jumpstart-tech-writer.agent.md +1 -0
- package/.github/agents/jumpstart-uiux-designer.agent.md +66 -0
- package/.github/workflows/quality.yml +19 -2
- package/.jumpstart/agents/analyst.md +38 -0
- package/.jumpstart/agents/architect.md +39 -1
- package/.jumpstart/agents/challenger.md +38 -0
- package/.jumpstart/agents/developer.md +41 -0
- package/.jumpstart/agents/pm.md +38 -0
- package/.jumpstart/agents/scout.md +33 -0
- package/.jumpstart/agents/ux-designer.md +29 -9
- package/.jumpstart/commands/commands.md +6 -5
- package/.jumpstart/config.yaml +25 -1
- package/.jumpstart/roadmap.md +1 -1
- package/.jumpstart/schemas/timeline.schema.json +1 -0
- package/.jumpstart/skills/README.md +1 -0
- package/.jumpstart/skills/quality-gates/SKILL.md +126 -0
- package/.jumpstart/skills/skill-creator/SKILL.md +485 -357
- package/.jumpstart/skills/skill-creator/agents/analyzer.md +274 -0
- package/.jumpstart/skills/skill-creator/agents/comparator.md +202 -0
- package/.jumpstart/skills/skill-creator/agents/grader.md +223 -0
- package/.jumpstart/skills/skill-creator/assets/eval_review.html +146 -0
- package/.jumpstart/skills/skill-creator/eval-viewer/generate_review.py +471 -0
- package/.jumpstart/skills/skill-creator/eval-viewer/viewer.html +1325 -0
- package/.jumpstart/skills/skill-creator/references/schemas.md +430 -0
- package/.jumpstart/skills/skill-creator/scripts/__init__.py +0 -0
- package/.jumpstart/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/.jumpstart/skills/skill-creator/scripts/generate_report.py +326 -0
- package/.jumpstart/skills/skill-creator/scripts/improve_description.py +247 -0
- package/.jumpstart/skills/skill-creator/scripts/package_skill.py +136 -110
- package/.jumpstart/skills/skill-creator/scripts/run_eval.py +310 -0
- package/.jumpstart/skills/skill-creator/scripts/run_loop.py +328 -0
- package/.jumpstart/skills/skill-creator/scripts/utils.py +47 -0
- package/.jumpstart/skills/ui-ux-pro-max/SKILL.md +266 -0
- package/.jumpstart/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/.jumpstart/skills/ui-ux-pro-max/data/colors.csv +97 -0
- package/.jumpstart/skills/ui-ux-pro-max/data/icons.csv +101 -0
- package/.jumpstart/skills/ui-ux-pro-max/data/landing.csv +31 -0
- package/.jumpstart/skills/ui-ux-pro-max/data/products.csv +97 -0
- package/.jumpstart/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/.jumpstart/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
- package/.jumpstart/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/.jumpstart/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/.jumpstart/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/.jumpstart/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/.jumpstart/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/.jumpstart/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/.jumpstart/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/.jumpstart/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/.jumpstart/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/.jumpstart/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/.jumpstart/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/.jumpstart/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/.jumpstart/skills/ui-ux-pro-max/data/styles.csv +68 -0
- package/.jumpstart/skills/ui-ux-pro-max/data/typography.csv +58 -0
- package/.jumpstart/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/.jumpstart/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/.jumpstart/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/.jumpstart/skills/ui-ux-pro-max/scripts/core.py +253 -0
- package/.jumpstart/skills/ui-ux-pro-max/scripts/design_system.py +1067 -0
- package/.jumpstart/skills/ui-ux-pro-max/scripts/search.py +114 -0
- package/.jumpstart/state/timeline.json +659 -0
- package/.jumpstart/templates/model-map.md +1 -1
- package/.jumpstart/templates/ux-design.md +3 -3
- package/.jumpstart/usage-log.json +74 -3
- package/AGENTS.md +1 -1
- package/README.md +64 -3
- package/bin/cli.js +3217 -1
- package/bin/headless-runner.js +62 -2
- package/bin/lib/agent-checkpoint.js +168 -0
- package/bin/lib/ai-evaluation.js +104 -0
- package/bin/lib/ai-intake.js +152 -0
- package/bin/lib/ambiguity-heatmap.js +152 -0
- package/bin/lib/artifact-comparison.js +104 -0
- package/bin/lib/ast-edit-engine.js +157 -0
- package/bin/lib/backlog-sync.js +338 -0
- package/bin/lib/bcdr-planning.js +158 -0
- package/bin/lib/bidirectional-trace.js +199 -0
- package/bin/lib/branch-workflow.js +266 -0
- package/bin/lib/cab-output.js +119 -0
- package/bin/lib/chat-integration.js +122 -0
- package/bin/lib/ci-cd-integration.js +208 -0
- package/bin/lib/codebase-retrieval.js +125 -0
- package/bin/lib/collaboration.js +168 -0
- package/bin/lib/compliance-packs.js +213 -0
- package/bin/lib/context-chunker.js +128 -0
- package/bin/lib/context-onboarding.js +122 -0
- package/bin/lib/contract-first.js +124 -0
- package/bin/lib/cost-router.js +148 -0
- package/bin/lib/credential-boundary.js +155 -0
- package/bin/lib/data-classification.js +180 -0
- package/bin/lib/data-contracts.js +129 -0
- package/bin/lib/db-evolution.js +158 -0
- package/bin/lib/decision-conflicts.js +299 -0
- package/bin/lib/delivery-confidence.js +361 -0
- package/bin/lib/dependency-upgrade.js +153 -0
- package/bin/lib/design-system.js +133 -0
- package/bin/lib/deterministic-artifacts.js +151 -0
- package/bin/lib/diagram-studio.js +115 -0
- package/bin/lib/domain-ontology.js +140 -0
- package/bin/lib/ea-review-packet.js +151 -0
- package/bin/lib/enterprise-search.js +123 -0
- package/bin/lib/enterprise-templates.js +140 -0
- package/bin/lib/environment-promotion.js +220 -0
- package/bin/lib/estimation-studio.js +130 -0
- package/bin/lib/event-modeling.js +133 -0
- package/bin/lib/evidence-collector.js +179 -0
- package/bin/lib/finops-planner.js +182 -0
- package/bin/lib/fitness-functions.js +279 -0
- package/bin/lib/focus.js +448 -0
- package/bin/lib/governance-dashboard.js +165 -0
- package/bin/lib/guided-handoff.js +120 -0
- package/bin/lib/impact-analysis.js +190 -0
- package/bin/lib/incident-feedback.js +157 -0
- package/bin/lib/integrate.js +1 -1
- package/bin/lib/knowledge-graph.js +122 -0
- package/bin/lib/legacy-modernizer.js +160 -0
- package/bin/lib/migration-planner.js +144 -0
- package/bin/lib/model-governance.js +185 -0
- package/bin/lib/model-router.js +144 -0
- package/bin/lib/multi-repo.js +272 -0
- package/bin/lib/next-phase.js +53 -8
- package/bin/lib/ops-ownership.js +152 -0
- package/bin/lib/parallel-agents.js +257 -0
- package/bin/lib/pattern-library.js +115 -0
- package/bin/lib/persona-packs.js +99 -0
- package/bin/lib/plan-executor.js +366 -0
- package/bin/lib/platform-engineering.js +119 -0
- package/bin/lib/playback-summaries.js +126 -0
- package/bin/lib/policy-engine.js +240 -0
- package/bin/lib/portfolio-reporting.js +357 -0
- package/bin/lib/pr-package.js +197 -0
- package/bin/lib/project-memory.js +235 -0
- package/bin/lib/prompt-governance.js +130 -0
- package/bin/lib/promptless-mode.js +128 -0
- package/bin/lib/quality-graph.js +193 -0
- package/bin/lib/raci-matrix.js +188 -0
- package/bin/lib/refactor-planner.js +167 -0
- package/bin/lib/reference-architectures.js +304 -0
- package/bin/lib/release-readiness.js +171 -0
- package/bin/lib/repo-graph.js +262 -0
- package/bin/lib/requirements-baseline.js +358 -0
- package/bin/lib/risk-register.js +211 -0
- package/bin/lib/role-approval.js +249 -0
- package/bin/lib/role-views.js +142 -0
- package/bin/lib/root-cause-analysis.js +132 -0
- package/bin/lib/runtime-debugger.js +154 -0
- package/bin/lib/safe-rename.js +135 -0
- package/bin/lib/secret-scanner.js +313 -0
- package/bin/lib/semantic-diff.js +335 -0
- package/bin/lib/sla-slo.js +210 -0
- package/bin/lib/smoke-tester.js +344 -0
- package/bin/lib/spec-comments.js +147 -0
- package/bin/lib/spec-maturity.js +287 -0
- package/bin/lib/sre-integration.js +154 -0
- package/bin/lib/structured-elicitation.js +174 -0
- package/bin/lib/telemetry-feedback.js +118 -0
- package/bin/lib/test-generator.js +146 -0
- package/bin/lib/timeline.js +2 -1
- package/bin/lib/tool-bridge.js +159 -0
- package/bin/lib/tool-guardrails.js +139 -0
- package/bin/lib/tool-schemas.js +281 -3
- package/bin/lib/transcript-ingestion.js +150 -0
- package/bin/lib/type-checker.js +261 -0
- package/bin/lib/uat-coverage.js +411 -0
- package/bin/lib/vendor-risk.js +173 -0
- package/bin/lib/waiver-workflow.js +174 -0
- package/bin/lib/web-dashboard.js +126 -0
- package/bin/lib/workshop-mode.js +165 -0
- package/bin/lib/workstream-ownership.js +104 -0
- package/package.json +1 -1
- package/.github/agents/jumpstart-ux-designer.agent.md +0 -45
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* delivery-confidence.js — Delivery Confidence Scoring
|
|
3
|
+
*
|
|
4
|
+
* Score a planned or implemented feature on completeness, risk,
|
|
5
|
+
* ambiguity, quality, and enterprise readiness.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* node bin/lib/delivery-confidence.js score|report [options]
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
|
|
16
|
+
const DIMENSIONS = ['completeness', 'risk', 'ambiguity', 'quality', 'enterprise_readiness'];
|
|
17
|
+
|
|
18
|
+
const WEIGHT_DEFAULTS = {
|
|
19
|
+
completeness: 0.25,
|
|
20
|
+
risk: 0.20,
|
|
21
|
+
ambiguity: 0.20,
|
|
22
|
+
quality: 0.20,
|
|
23
|
+
enterprise_readiness: 0.15
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const CONFIDENCE_LEVELS = [
|
|
27
|
+
{ min: 90, label: 'Very High', emoji: '🟢' },
|
|
28
|
+
{ min: 75, label: 'High', emoji: '🟡' },
|
|
29
|
+
{ min: 50, label: 'Medium', emoji: '🟠' },
|
|
30
|
+
{ min: 25, label: 'Low', emoji: '🔴' },
|
|
31
|
+
{ min: 0, label: 'Very Low', emoji: '⛔' }
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Analyze completeness of an artifact.
|
|
36
|
+
* @param {string} content
|
|
37
|
+
* @param {string} artifactType
|
|
38
|
+
* @returns {object}
|
|
39
|
+
*/
|
|
40
|
+
function analyzeCompleteness(content, artifactType) {
|
|
41
|
+
const checks = [];
|
|
42
|
+
const lines = content.split('\n');
|
|
43
|
+
|
|
44
|
+
// Check for required sections
|
|
45
|
+
const hasFrontmatter = content.startsWith('---');
|
|
46
|
+
checks.push({ check: 'has_frontmatter', passed: hasFrontmatter });
|
|
47
|
+
|
|
48
|
+
const hasApproval = content.includes('Phase Gate Approval');
|
|
49
|
+
checks.push({ check: 'has_approval_section', passed: hasApproval });
|
|
50
|
+
|
|
51
|
+
const headingCount = (content.match(/^#{1,4}\s+/gm) || []).length;
|
|
52
|
+
checks.push({ check: 'has_sections', passed: headingCount >= 3 });
|
|
53
|
+
|
|
54
|
+
// Check for placeholder content
|
|
55
|
+
const placeholders = (content.match(/\[TODO\]|\[TBD\]|\[PLACEHOLDER\]|\[NEEDS CLARIFICATION\]/gi) || []).length;
|
|
56
|
+
checks.push({ check: 'no_placeholders', passed: placeholders === 0 });
|
|
57
|
+
|
|
58
|
+
// Check for empty sections
|
|
59
|
+
const emptySections = [];
|
|
60
|
+
let currentHeading = null;
|
|
61
|
+
let hasContent = false;
|
|
62
|
+
for (const line of lines) {
|
|
63
|
+
if (/^#{1,4}\s+/.test(line)) {
|
|
64
|
+
if (currentHeading && !hasContent) emptySections.push(currentHeading);
|
|
65
|
+
currentHeading = line.trim();
|
|
66
|
+
hasContent = false;
|
|
67
|
+
} else if (line.trim().length > 0) {
|
|
68
|
+
hasContent = true;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
checks.push({ check: 'no_empty_sections', passed: emptySections.length === 0 });
|
|
72
|
+
|
|
73
|
+
// Check minimum content length
|
|
74
|
+
checks.push({ check: 'sufficient_content', passed: content.length > 500 });
|
|
75
|
+
|
|
76
|
+
const passed = checks.filter(c => c.passed).length;
|
|
77
|
+
return {
|
|
78
|
+
score: Math.round((passed / checks.length) * 100),
|
|
79
|
+
checks,
|
|
80
|
+
gaps: checks.filter(c => !c.passed).map(c => c.check),
|
|
81
|
+
placeholders_found: placeholders
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Analyze risk factors.
|
|
87
|
+
* @param {string} content
|
|
88
|
+
* @returns {object}
|
|
89
|
+
*/
|
|
90
|
+
function analyzeRisk(content) {
|
|
91
|
+
const risks = [];
|
|
92
|
+
|
|
93
|
+
// Check for risk-related keywords
|
|
94
|
+
const riskKeywords = ['risk', 'concern', 'unknown', 'assumption', 'constraint', 'blocker', 'dependency'];
|
|
95
|
+
for (const keyword of riskKeywords) {
|
|
96
|
+
const pattern = new RegExp(`\\b${keyword}s?\\b`, 'gi');
|
|
97
|
+
const matches = content.match(pattern) || [];
|
|
98
|
+
if (matches.length > 0) {
|
|
99
|
+
risks.push({ factor: keyword, mentions: matches.length });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Check for explicit risk sections
|
|
104
|
+
const hasRiskSection = /#{1,4}\s+.*risk/i.test(content);
|
|
105
|
+
const hasMitigations = /mitigation|mitigate|contingency|fallback/i.test(content);
|
|
106
|
+
|
|
107
|
+
// Score: more risk identification + mitigations = higher score (better managed)
|
|
108
|
+
const riskIdentified = risks.length > 0;
|
|
109
|
+
const score = riskIdentified
|
|
110
|
+
? (hasMitigations ? 85 : 55)
|
|
111
|
+
: (hasRiskSection ? 70 : 40);
|
|
112
|
+
|
|
113
|
+
return {
|
|
114
|
+
score,
|
|
115
|
+
risk_factors: risks,
|
|
116
|
+
has_risk_section: hasRiskSection,
|
|
117
|
+
has_mitigations: hasMitigations
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Analyze ambiguity in content.
|
|
123
|
+
* @param {string} content
|
|
124
|
+
* @returns {object}
|
|
125
|
+
*/
|
|
126
|
+
function analyzeAmbiguity(content) {
|
|
127
|
+
const ambiguousTerms = [
|
|
128
|
+
'should', 'might', 'could', 'may', 'possibly', 'potentially',
|
|
129
|
+
'approximately', 'roughly', 'maybe', 'etc', 'and so on',
|
|
130
|
+
'as needed', 'as appropriate', 'if necessary', 'TBD', 'TBA'
|
|
131
|
+
];
|
|
132
|
+
|
|
133
|
+
const findings = [];
|
|
134
|
+
for (const term of ambiguousTerms) {
|
|
135
|
+
const pattern = new RegExp(`\\b${term}\\b`, 'gi');
|
|
136
|
+
const matches = content.match(pattern) || [];
|
|
137
|
+
if (matches.length > 0) {
|
|
138
|
+
findings.push({ term, count: matches.length });
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const totalAmbiguous = findings.reduce((sum, f) => sum + f.count, 0);
|
|
143
|
+
const wordCount = content.split(/\s+/).length;
|
|
144
|
+
const ambiguityRate = wordCount > 0 ? totalAmbiguous / wordCount : 0;
|
|
145
|
+
|
|
146
|
+
// Lower ambiguity rate = higher score
|
|
147
|
+
const score = Math.max(0, Math.round(100 - (ambiguityRate * 2000)));
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
score,
|
|
151
|
+
ambiguous_terms: findings,
|
|
152
|
+
total_ambiguous: totalAmbiguous,
|
|
153
|
+
word_count: wordCount,
|
|
154
|
+
ambiguity_rate: Math.round(ambiguityRate * 10000) / 100
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Analyze quality indicators.
|
|
160
|
+
* @param {string} content
|
|
161
|
+
* @param {string} root
|
|
162
|
+
* @returns {object}
|
|
163
|
+
*/
|
|
164
|
+
function analyzeQuality(content, root) {
|
|
165
|
+
const checks = [];
|
|
166
|
+
|
|
167
|
+
// Check for acceptance criteria
|
|
168
|
+
const hasAC = /acceptance\s+criteria/i.test(content);
|
|
169
|
+
checks.push({ check: 'acceptance_criteria', passed: hasAC });
|
|
170
|
+
|
|
171
|
+
// Check for test references
|
|
172
|
+
const hasTests = /test|spec|verify|validate/i.test(content);
|
|
173
|
+
checks.push({ check: 'test_references', passed: hasTests });
|
|
174
|
+
|
|
175
|
+
// Check for diagrams
|
|
176
|
+
const hasDiagrams = /```mermaid|flowchart|sequenceDiagram|classDiagram/i.test(content);
|
|
177
|
+
checks.push({ check: 'has_diagrams', passed: hasDiagrams });
|
|
178
|
+
|
|
179
|
+
// Check for traceability IDs
|
|
180
|
+
const hasTracing = /\b(REQ-\d+|E\d+-S\d+|NFR-\d+|M\d+-T\d+)\b/.test(content);
|
|
181
|
+
checks.push({ check: 'traceability_ids', passed: hasTracing });
|
|
182
|
+
|
|
183
|
+
// Check for code examples
|
|
184
|
+
const hasCodeExamples = /```\w+/.test(content);
|
|
185
|
+
checks.push({ check: 'code_examples', passed: hasCodeExamples });
|
|
186
|
+
|
|
187
|
+
// Check for cross-references
|
|
188
|
+
const hasCrossRefs = /\[.*\]\(.*\.md\)/.test(content);
|
|
189
|
+
checks.push({ check: 'cross_references', passed: hasCrossRefs });
|
|
190
|
+
|
|
191
|
+
const passed = checks.filter(c => c.passed).length;
|
|
192
|
+
return {
|
|
193
|
+
score: Math.round((passed / checks.length) * 100),
|
|
194
|
+
checks,
|
|
195
|
+
gaps: checks.filter(c => !c.passed).map(c => c.check)
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Analyze enterprise readiness.
|
|
201
|
+
* @param {string} content
|
|
202
|
+
* @returns {object}
|
|
203
|
+
*/
|
|
204
|
+
function analyzeEnterpriseReadiness(content) {
|
|
205
|
+
const checks = [];
|
|
206
|
+
|
|
207
|
+
// Security considerations
|
|
208
|
+
const hasSecurity = /security|auth|encryption|RBAC|access control|OWASP/i.test(content);
|
|
209
|
+
checks.push({ check: 'security_considerations', passed: hasSecurity });
|
|
210
|
+
|
|
211
|
+
// Scalability
|
|
212
|
+
const hasScalability = /scalab|performance|latency|throughput|load/i.test(content);
|
|
213
|
+
checks.push({ check: 'scalability', passed: hasScalability });
|
|
214
|
+
|
|
215
|
+
// Compliance
|
|
216
|
+
const hasCompliance = /compliance|regulatory|GDPR|HIPAA|SOC|PCI|audit/i.test(content);
|
|
217
|
+
checks.push({ check: 'compliance', passed: hasCompliance });
|
|
218
|
+
|
|
219
|
+
// Monitoring / Observability
|
|
220
|
+
const hasMonitoring = /monitor|observab|logging|tracing|alert|metric/i.test(content);
|
|
221
|
+
checks.push({ check: 'monitoring', passed: hasMonitoring });
|
|
222
|
+
|
|
223
|
+
// Deployment
|
|
224
|
+
const hasDeployment = /deploy|CI\/CD|pipeline|container|kubernetes|docker/i.test(content);
|
|
225
|
+
checks.push({ check: 'deployment', passed: hasDeployment });
|
|
226
|
+
|
|
227
|
+
// Documentation
|
|
228
|
+
const hasDocumentation = /document|README|runbook|wiki|onboard/i.test(content);
|
|
229
|
+
checks.push({ check: 'documentation', passed: hasDocumentation });
|
|
230
|
+
|
|
231
|
+
const passed = checks.filter(c => c.passed).length;
|
|
232
|
+
return {
|
|
233
|
+
score: Math.round((passed / checks.length) * 100),
|
|
234
|
+
checks,
|
|
235
|
+
gaps: checks.filter(c => !c.passed).map(c => c.check)
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Compute overall delivery confidence score.
|
|
241
|
+
*
|
|
242
|
+
* @param {string} content - Artifact content.
|
|
243
|
+
* @param {object} [options]
|
|
244
|
+
* @returns {object}
|
|
245
|
+
*/
|
|
246
|
+
function scoreConfidence(content, options = {}) {
|
|
247
|
+
const weights = { ...WEIGHT_DEFAULTS, ...options.weights };
|
|
248
|
+
const root = options.root || '.';
|
|
249
|
+
const artifactType = options.artifactType || 'generic';
|
|
250
|
+
|
|
251
|
+
const dimensions = {
|
|
252
|
+
completeness: analyzeCompleteness(content, artifactType),
|
|
253
|
+
risk: analyzeRisk(content),
|
|
254
|
+
ambiguity: analyzeAmbiguity(content),
|
|
255
|
+
quality: analyzeQuality(content, root),
|
|
256
|
+
enterprise_readiness: analyzeEnterpriseReadiness(content)
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
const weightedScore = Math.round(
|
|
260
|
+
dimensions.completeness.score * weights.completeness +
|
|
261
|
+
dimensions.risk.score * weights.risk +
|
|
262
|
+
dimensions.ambiguity.score * weights.ambiguity +
|
|
263
|
+
dimensions.quality.score * weights.quality +
|
|
264
|
+
dimensions.enterprise_readiness.score * weights.enterprise_readiness
|
|
265
|
+
);
|
|
266
|
+
|
|
267
|
+
const level = CONFIDENCE_LEVELS.find(l => weightedScore >= l.min) || CONFIDENCE_LEVELS[CONFIDENCE_LEVELS.length - 1];
|
|
268
|
+
|
|
269
|
+
const allGaps = [
|
|
270
|
+
...(dimensions.completeness.gaps || []),
|
|
271
|
+
...(dimensions.quality.gaps || []),
|
|
272
|
+
...(dimensions.enterprise_readiness.gaps || [])
|
|
273
|
+
];
|
|
274
|
+
|
|
275
|
+
return {
|
|
276
|
+
success: true,
|
|
277
|
+
overall_score: weightedScore,
|
|
278
|
+
confidence_level: level.label,
|
|
279
|
+
confidence_emoji: level.emoji,
|
|
280
|
+
dimensions,
|
|
281
|
+
top_gaps: allGaps.slice(0, 5),
|
|
282
|
+
weights_used: weights
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
* Score a file on disk.
|
|
288
|
+
*
|
|
289
|
+
* @param {string} filePath - Path to artifact.
|
|
290
|
+
* @param {object} [options]
|
|
291
|
+
* @returns {object}
|
|
292
|
+
*/
|
|
293
|
+
function scoreFile(filePath, options = {}) {
|
|
294
|
+
if (!fs.existsSync(filePath)) {
|
|
295
|
+
return { success: false, error: `File not found: ${filePath}` };
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
299
|
+
const result = scoreConfidence(content, options);
|
|
300
|
+
result.file = filePath;
|
|
301
|
+
return result;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Score all spec artifacts in a project.
|
|
306
|
+
*
|
|
307
|
+
* @param {string} root - Project root.
|
|
308
|
+
* @param {object} [options]
|
|
309
|
+
* @returns {object}
|
|
310
|
+
*/
|
|
311
|
+
function scoreProject(root, options = {}) {
|
|
312
|
+
const specsDir = path.join(root, 'specs');
|
|
313
|
+
if (!fs.existsSync(specsDir)) {
|
|
314
|
+
return { success: false, error: 'specs/ directory not found' };
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
const results = [];
|
|
318
|
+
const artifacts = ['challenger-brief.md', 'product-brief.md', 'prd.md', 'architecture.md', 'implementation-plan.md'];
|
|
319
|
+
|
|
320
|
+
for (const artifact of artifacts) {
|
|
321
|
+
const fullPath = path.join(specsDir, artifact);
|
|
322
|
+
if (fs.existsSync(fullPath)) {
|
|
323
|
+
const result = scoreFile(fullPath, { ...options, root });
|
|
324
|
+
results.push({ artifact, ...result });
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const avgScore = results.length > 0
|
|
329
|
+
? Math.round(results.reduce((sum, r) => sum + (r.overall_score || 0), 0) / results.length)
|
|
330
|
+
: 0;
|
|
331
|
+
|
|
332
|
+
const level = CONFIDENCE_LEVELS.find(l => avgScore >= l.min) || CONFIDENCE_LEVELS[CONFIDENCE_LEVELS.length - 1];
|
|
333
|
+
|
|
334
|
+
return {
|
|
335
|
+
success: true,
|
|
336
|
+
project_score: avgScore,
|
|
337
|
+
project_confidence: level.label,
|
|
338
|
+
project_emoji: level.emoji,
|
|
339
|
+
artifacts: results,
|
|
340
|
+
summary: {
|
|
341
|
+
artifacts_scored: results.length,
|
|
342
|
+
average_score: avgScore,
|
|
343
|
+
highest: results.length > 0 ? results.reduce((a, b) => (a.overall_score || 0) > (b.overall_score || 0) ? a : b).artifact : null,
|
|
344
|
+
lowest: results.length > 0 ? results.reduce((a, b) => (a.overall_score || 0) < (b.overall_score || 0) ? a : b).artifact : null
|
|
345
|
+
}
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
module.exports = {
|
|
350
|
+
analyzeCompleteness,
|
|
351
|
+
analyzeRisk,
|
|
352
|
+
analyzeAmbiguity,
|
|
353
|
+
analyzeQuality,
|
|
354
|
+
analyzeEnterpriseReadiness,
|
|
355
|
+
scoreConfidence,
|
|
356
|
+
scoreFile,
|
|
357
|
+
scoreProject,
|
|
358
|
+
DIMENSIONS,
|
|
359
|
+
WEIGHT_DEFAULTS,
|
|
360
|
+
CONFIDENCE_LEVELS
|
|
361
|
+
};
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dependency-upgrade.js — Dependency Upgrade Autopilot (Item 51)
|
|
3
|
+
*
|
|
4
|
+
* Plan, test, patch, and validate framework/library upgrades
|
|
5
|
+
* in a governed manner.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* node bin/lib/dependency-upgrade.js scan|plan|report [options]
|
|
9
|
+
*
|
|
10
|
+
* State file: .jumpstart/state/dependency-upgrades.json
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
const fs = require('fs');
|
|
16
|
+
const path = require('path');
|
|
17
|
+
|
|
18
|
+
const DEFAULT_STATE_FILE = path.join('.jumpstart', 'state', 'dependency-upgrades.json');
|
|
19
|
+
|
|
20
|
+
const UPGRADE_TYPES = ['patch', 'minor', 'major'];
|
|
21
|
+
const RISK_BY_TYPE = { patch: 'low', minor: 'medium', major: 'high' };
|
|
22
|
+
|
|
23
|
+
function defaultState() {
|
|
24
|
+
return {
|
|
25
|
+
version: '1.0.0',
|
|
26
|
+
created_at: new Date().toISOString(),
|
|
27
|
+
last_updated: null,
|
|
28
|
+
scans: [],
|
|
29
|
+
upgrade_plans: []
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function loadState(stateFile) {
|
|
34
|
+
const filePath = stateFile || DEFAULT_STATE_FILE;
|
|
35
|
+
if (!fs.existsSync(filePath)) return defaultState();
|
|
36
|
+
try { return JSON.parse(fs.readFileSync(filePath, 'utf8')); }
|
|
37
|
+
catch { return defaultState(); }
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function saveState(state, stateFile) {
|
|
41
|
+
const filePath = stateFile || DEFAULT_STATE_FILE;
|
|
42
|
+
const dir = path.dirname(filePath);
|
|
43
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
44
|
+
state.last_updated = new Date().toISOString();
|
|
45
|
+
fs.writeFileSync(filePath, JSON.stringify(state, null, 2) + '\n', 'utf8');
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Scan for available dependency upgrades.
|
|
50
|
+
*
|
|
51
|
+
* @param {string} root - Project root.
|
|
52
|
+
* @param {object} [options]
|
|
53
|
+
* @returns {object}
|
|
54
|
+
*/
|
|
55
|
+
function scanUpgrades(root, options = {}) {
|
|
56
|
+
const packageFile = path.join(root, 'package.json');
|
|
57
|
+
if (!fs.existsSync(packageFile)) {
|
|
58
|
+
return { success: false, error: 'package.json not found' };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
let pkg;
|
|
62
|
+
try { pkg = JSON.parse(fs.readFileSync(packageFile, 'utf8')); }
|
|
63
|
+
catch { return { success: false, error: 'Invalid package.json' }; }
|
|
64
|
+
|
|
65
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
66
|
+
const candidates = [];
|
|
67
|
+
|
|
68
|
+
for (const [name, version] of Object.entries(deps)) {
|
|
69
|
+
const clean = version.replace(/^[\^~>=<]/, '');
|
|
70
|
+
candidates.push({
|
|
71
|
+
name,
|
|
72
|
+
current_version: clean,
|
|
73
|
+
specified: version,
|
|
74
|
+
type: version.startsWith('^') ? 'minor-range' : version.startsWith('~') ? 'patch-range' : 'fixed',
|
|
75
|
+
is_dev: !!(pkg.devDependencies && pkg.devDependencies[name])
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const stateFile = options.stateFile || path.join(root, DEFAULT_STATE_FILE);
|
|
80
|
+
const state = loadState(stateFile);
|
|
81
|
+
state.scans.push({
|
|
82
|
+
scanned_at: new Date().toISOString(),
|
|
83
|
+
total: candidates.length
|
|
84
|
+
});
|
|
85
|
+
saveState(state, stateFile);
|
|
86
|
+
|
|
87
|
+
return { success: true, dependencies: candidates, total: candidates.length };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Create an upgrade plan.
|
|
92
|
+
*
|
|
93
|
+
* @param {object} plan - { name, upgrades[] }
|
|
94
|
+
* @param {object} [options]
|
|
95
|
+
* @returns {object}
|
|
96
|
+
*/
|
|
97
|
+
function createUpgradePlan(plan, options = {}) {
|
|
98
|
+
if (!plan || !plan.name) return { success: false, error: 'plan.name is required' };
|
|
99
|
+
|
|
100
|
+
const stateFile = options.stateFile || DEFAULT_STATE_FILE;
|
|
101
|
+
const state = loadState(stateFile);
|
|
102
|
+
|
|
103
|
+
const upgradePlan = {
|
|
104
|
+
id: `UPG-${(state.upgrade_plans.length + 1).toString().padStart(3, '0')}`,
|
|
105
|
+
name: plan.name,
|
|
106
|
+
upgrades: (plan.upgrades || []).map(u => ({
|
|
107
|
+
package: u.package || u.name,
|
|
108
|
+
from: u.from || u.current_version,
|
|
109
|
+
to: u.to || u.target_version,
|
|
110
|
+
type: u.type || 'minor',
|
|
111
|
+
risk: RISK_BY_TYPE[u.type] || 'medium',
|
|
112
|
+
status: 'planned',
|
|
113
|
+
test_result: null
|
|
114
|
+
})),
|
|
115
|
+
status: 'draft',
|
|
116
|
+
created_at: new Date().toISOString()
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
state.upgrade_plans.push(upgradePlan);
|
|
120
|
+
saveState(state, stateFile);
|
|
121
|
+
|
|
122
|
+
return { success: true, plan: upgradePlan };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Generate upgrade report.
|
|
127
|
+
*
|
|
128
|
+
* @param {object} [options]
|
|
129
|
+
* @returns {object}
|
|
130
|
+
*/
|
|
131
|
+
function generateReport(options = {}) {
|
|
132
|
+
const stateFile = options.stateFile || DEFAULT_STATE_FILE;
|
|
133
|
+
const state = loadState(stateFile);
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
success: true,
|
|
137
|
+
total_plans: state.upgrade_plans.length,
|
|
138
|
+
total_scans: state.scans.length,
|
|
139
|
+
plans: state.upgrade_plans,
|
|
140
|
+
last_scan: state.scans.length > 0 ? state.scans[state.scans.length - 1] : null
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
module.exports = {
|
|
145
|
+
defaultState,
|
|
146
|
+
loadState,
|
|
147
|
+
saveState,
|
|
148
|
+
scanUpgrades,
|
|
149
|
+
createUpgradePlan,
|
|
150
|
+
generateReport,
|
|
151
|
+
UPGRADE_TYPES,
|
|
152
|
+
RISK_BY_TYPE
|
|
153
|
+
};
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* design-system.js — Design System Integration (Item 69)
|
|
3
|
+
*
|
|
4
|
+
* Connect to enterprise design tokens, component libraries,
|
|
5
|
+
* accessibility standards, and brand rules.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* node bin/lib/design-system.js register|check|report [options]
|
|
9
|
+
*
|
|
10
|
+
* State file: .jumpstart/state/design-system.json
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
const fs = require('fs');
|
|
16
|
+
const path = require('path');
|
|
17
|
+
|
|
18
|
+
const DEFAULT_STATE_FILE = path.join('.jumpstart', 'state', 'design-system.json');
|
|
19
|
+
|
|
20
|
+
const TOKEN_CATEGORIES = ['color', 'typography', 'spacing', 'elevation', 'breakpoint', 'motion'];
|
|
21
|
+
const ACCESSIBILITY_LEVELS = ['A', 'AA', 'AAA'];
|
|
22
|
+
|
|
23
|
+
function defaultState() {
|
|
24
|
+
return { version: '1.0.0', tokens: {}, components: [], accessibility: { level: 'AA' }, brand: {}, last_updated: null };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function loadState(stateFile) {
|
|
28
|
+
const fp = stateFile || DEFAULT_STATE_FILE;
|
|
29
|
+
if (!fs.existsSync(fp)) return defaultState();
|
|
30
|
+
try { return JSON.parse(fs.readFileSync(fp, 'utf8')); }
|
|
31
|
+
catch { return defaultState(); }
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function saveState(state, stateFile) {
|
|
35
|
+
const fp = stateFile || DEFAULT_STATE_FILE;
|
|
36
|
+
const dir = path.dirname(fp);
|
|
37
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
38
|
+
state.last_updated = new Date().toISOString();
|
|
39
|
+
fs.writeFileSync(fp, JSON.stringify(state, null, 2) + '\n', 'utf8');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Register design tokens.
|
|
44
|
+
*/
|
|
45
|
+
function registerTokens(category, tokens, options = {}) {
|
|
46
|
+
if (!category || !tokens) return { success: false, error: 'category and tokens are required' };
|
|
47
|
+
if (!TOKEN_CATEGORIES.includes(category)) {
|
|
48
|
+
return { success: false, error: `Unknown category: ${category}. Valid: ${TOKEN_CATEGORIES.join(', ')}` };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const stateFile = options.stateFile || DEFAULT_STATE_FILE;
|
|
52
|
+
const state = loadState(stateFile);
|
|
53
|
+
state.tokens[category] = tokens;
|
|
54
|
+
saveState(state, stateFile);
|
|
55
|
+
|
|
56
|
+
return { success: true, category, token_count: Object.keys(tokens).length };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Register a component.
|
|
61
|
+
*/
|
|
62
|
+
function registerComponent(name, spec, options = {}) {
|
|
63
|
+
if (!name) return { success: false, error: 'Component name is required' };
|
|
64
|
+
|
|
65
|
+
const stateFile = options.stateFile || DEFAULT_STATE_FILE;
|
|
66
|
+
const state = loadState(stateFile);
|
|
67
|
+
|
|
68
|
+
const component = {
|
|
69
|
+
name,
|
|
70
|
+
props: spec.props || [],
|
|
71
|
+
accessibility: spec.accessibility || [],
|
|
72
|
+
tokens_used: spec.tokens_used || [],
|
|
73
|
+
registered_at: new Date().toISOString()
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
state.components.push(component);
|
|
77
|
+
saveState(state, stateFile);
|
|
78
|
+
|
|
79
|
+
return { success: true, component };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Check design system compliance.
|
|
84
|
+
*/
|
|
85
|
+
function checkCompliance(options = {}) {
|
|
86
|
+
const stateFile = options.stateFile || DEFAULT_STATE_FILE;
|
|
87
|
+
const state = loadState(stateFile);
|
|
88
|
+
|
|
89
|
+
const issues = [];
|
|
90
|
+
const tokenCategories = Object.keys(state.tokens);
|
|
91
|
+
|
|
92
|
+
for (const required of ['color', 'typography', 'spacing']) {
|
|
93
|
+
if (!tokenCategories.includes(required)) {
|
|
94
|
+
issues.push({ type: 'missing_tokens', category: required, severity: 'warning' });
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
for (const comp of state.components) {
|
|
99
|
+
if (!comp.accessibility || comp.accessibility.length === 0) {
|
|
100
|
+
issues.push({ type: 'missing_accessibility', component: comp.name, severity: 'warning' });
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
success: true,
|
|
106
|
+
compliant: issues.length === 0,
|
|
107
|
+
issues,
|
|
108
|
+
token_categories: tokenCategories.length,
|
|
109
|
+
components: state.components.length,
|
|
110
|
+
accessibility_level: state.accessibility.level
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Generate design system report.
|
|
116
|
+
*/
|
|
117
|
+
function generateReport(options = {}) {
|
|
118
|
+
const stateFile = options.stateFile || DEFAULT_STATE_FILE;
|
|
119
|
+
const state = loadState(stateFile);
|
|
120
|
+
|
|
121
|
+
return {
|
|
122
|
+
success: true,
|
|
123
|
+
tokens: Object.fromEntries(Object.entries(state.tokens).map(([k, v]) => [k, Object.keys(v).length])),
|
|
124
|
+
components: state.components.length,
|
|
125
|
+
accessibility_level: state.accessibility.level,
|
|
126
|
+
brand: state.brand
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
module.exports = {
|
|
131
|
+
registerTokens, registerComponent, checkCompliance, generateReport,
|
|
132
|
+
loadState, saveState, defaultState, TOKEN_CATEGORIES, ACCESSIBILITY_LEVELS
|
|
133
|
+
};
|