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,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* collaboration.js — Real-Time Collaboration Sessions (Item 65)
|
|
3
|
+
*
|
|
4
|
+
* Multiple humans and multiple agents working against
|
|
5
|
+
* the same initiative safely with conflict detection.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* node bin/lib/collaboration.js create|join|status|lock [options]
|
|
9
|
+
*
|
|
10
|
+
* State file: .jumpstart/state/collaboration.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', 'collaboration.json');
|
|
19
|
+
|
|
20
|
+
const PARTICIPANT_ROLES = ['owner', 'editor', 'reviewer', 'observer'];
|
|
21
|
+
|
|
22
|
+
function defaultState() {
|
|
23
|
+
return {
|
|
24
|
+
version: '1.0.0',
|
|
25
|
+
sessions: [],
|
|
26
|
+
locks: [],
|
|
27
|
+
last_updated: null
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function loadState(stateFile) {
|
|
32
|
+
const fp = stateFile || DEFAULT_STATE_FILE;
|
|
33
|
+
if (!fs.existsSync(fp)) return defaultState();
|
|
34
|
+
try { return JSON.parse(fs.readFileSync(fp, 'utf8')); }
|
|
35
|
+
catch { return defaultState(); }
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function saveState(state, stateFile) {
|
|
39
|
+
const fp = stateFile || DEFAULT_STATE_FILE;
|
|
40
|
+
const dir = path.dirname(fp);
|
|
41
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
42
|
+
state.last_updated = new Date().toISOString();
|
|
43
|
+
fs.writeFileSync(fp, JSON.stringify(state, null, 2) + '\n', 'utf8');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Create a collaboration session.
|
|
48
|
+
*/
|
|
49
|
+
function createSession(name, options = {}) {
|
|
50
|
+
if (!name) return { success: false, error: 'Session name is required' };
|
|
51
|
+
|
|
52
|
+
const stateFile = options.stateFile || DEFAULT_STATE_FILE;
|
|
53
|
+
const state = loadState(stateFile);
|
|
54
|
+
|
|
55
|
+
const session = {
|
|
56
|
+
id: `COLLAB-${Date.now()}`,
|
|
57
|
+
name,
|
|
58
|
+
status: 'active',
|
|
59
|
+
owner: options.owner || 'system',
|
|
60
|
+
participants: [{ name: options.owner || 'system', role: 'owner', joined_at: new Date().toISOString() }],
|
|
61
|
+
artifacts: options.artifacts || [],
|
|
62
|
+
created_at: new Date().toISOString(),
|
|
63
|
+
ended_at: null
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
state.sessions.push(session);
|
|
67
|
+
saveState(state, stateFile);
|
|
68
|
+
|
|
69
|
+
return { success: true, session };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Join an existing session.
|
|
74
|
+
*/
|
|
75
|
+
function joinSession(sessionId, participant, options = {}) {
|
|
76
|
+
if (!sessionId || !participant) return { success: false, error: 'sessionId and participant name are required' };
|
|
77
|
+
|
|
78
|
+
const stateFile = options.stateFile || DEFAULT_STATE_FILE;
|
|
79
|
+
const state = loadState(stateFile);
|
|
80
|
+
|
|
81
|
+
const session = state.sessions.find(s => s.id === sessionId);
|
|
82
|
+
if (!session) return { success: false, error: `Session ${sessionId} not found` };
|
|
83
|
+
if (session.status !== 'active') return { success: false, error: 'Session is not active' };
|
|
84
|
+
|
|
85
|
+
const role = options.role || 'editor';
|
|
86
|
+
if (!PARTICIPANT_ROLES.includes(role)) {
|
|
87
|
+
return { success: false, error: `Invalid role. Valid: ${PARTICIPANT_ROLES.join(', ')}` };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
session.participants.push({ name: participant, role, joined_at: new Date().toISOString() });
|
|
91
|
+
saveState(state, stateFile);
|
|
92
|
+
|
|
93
|
+
return { success: true, session };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Acquire a lock on an artifact.
|
|
98
|
+
*/
|
|
99
|
+
function acquireLock(artifact, owner, options = {}) {
|
|
100
|
+
if (!artifact || !owner) return { success: false, error: 'artifact and owner are required' };
|
|
101
|
+
|
|
102
|
+
const stateFile = options.stateFile || DEFAULT_STATE_FILE;
|
|
103
|
+
const state = loadState(stateFile);
|
|
104
|
+
|
|
105
|
+
const existingLock = state.locks.find(l => l.artifact === artifact && l.released_at === null);
|
|
106
|
+
if (existingLock) {
|
|
107
|
+
return { success: false, error: `Artifact ${artifact} is locked by ${existingLock.owner}` };
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const lock = {
|
|
111
|
+
id: `LOCK-${Date.now()}`,
|
|
112
|
+
artifact,
|
|
113
|
+
owner,
|
|
114
|
+
acquired_at: new Date().toISOString(),
|
|
115
|
+
released_at: null
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
state.locks.push(lock);
|
|
119
|
+
saveState(state, stateFile);
|
|
120
|
+
|
|
121
|
+
return { success: true, lock };
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Release a lock.
|
|
126
|
+
*/
|
|
127
|
+
function releaseLock(lockId, options = {}) {
|
|
128
|
+
if (!lockId) return { success: false, error: 'lockId is required' };
|
|
129
|
+
|
|
130
|
+
const stateFile = options.stateFile || DEFAULT_STATE_FILE;
|
|
131
|
+
const state = loadState(stateFile);
|
|
132
|
+
|
|
133
|
+
const lock = state.locks.find(l => l.id === lockId);
|
|
134
|
+
if (!lock) return { success: false, error: `Lock ${lockId} not found` };
|
|
135
|
+
|
|
136
|
+
lock.released_at = new Date().toISOString();
|
|
137
|
+
saveState(state, stateFile);
|
|
138
|
+
|
|
139
|
+
return { success: true, lock };
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Get collaboration status.
|
|
144
|
+
*/
|
|
145
|
+
function getStatus(options = {}) {
|
|
146
|
+
const stateFile = options.stateFile || DEFAULT_STATE_FILE;
|
|
147
|
+
const state = loadState(stateFile);
|
|
148
|
+
|
|
149
|
+
return {
|
|
150
|
+
success: true,
|
|
151
|
+
active_sessions: state.sessions.filter(s => s.status === 'active').length,
|
|
152
|
+
active_locks: state.locks.filter(l => l.released_at === null).length,
|
|
153
|
+
sessions: state.sessions,
|
|
154
|
+
locks: state.locks.filter(l => l.released_at === null)
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
module.exports = {
|
|
159
|
+
createSession,
|
|
160
|
+
joinSession,
|
|
161
|
+
acquireLock,
|
|
162
|
+
releaseLock,
|
|
163
|
+
getStatus,
|
|
164
|
+
loadState,
|
|
165
|
+
saveState,
|
|
166
|
+
defaultState,
|
|
167
|
+
PARTICIPANT_ROLES
|
|
168
|
+
};
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* compliance-packs.js — Prebuilt Compliance Control Mappings (Item 24)
|
|
3
|
+
*
|
|
4
|
+
* Prebuilt control mappings for SOC 2, ISO 27001, HIPAA, PCI,
|
|
5
|
+
* FedRAMP, GDPR, EU AI Act, NIST AI RMF.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* node bin/lib/compliance-packs.js list|apply|check|report [options]
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
|
|
16
|
+
const DEFAULT_STATE_FILE = path.join('.jumpstart', 'state', 'compliance.json');
|
|
17
|
+
|
|
18
|
+
const COMPLIANCE_FRAMEWORKS = {
|
|
19
|
+
'soc2': {
|
|
20
|
+
name: 'SOC 2 Type II',
|
|
21
|
+
controls: [
|
|
22
|
+
{ id: 'CC1.1', category: 'organization', description: 'Integrity and ethical values', checks: ['code-of-conduct', 'policy-engine'] },
|
|
23
|
+
{ id: 'CC6.1', category: 'security', description: 'Logical and physical access controls', checks: ['secret-scan', 'auth-review'] },
|
|
24
|
+
{ id: 'CC7.1', category: 'operations', description: 'System monitoring', checks: ['logging-review', 'alert-config'] },
|
|
25
|
+
{ id: 'CC8.1', category: 'change-management', description: 'Change management controls', checks: ['approval-workflow', 'spec-drift'] }
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
'iso27001': {
|
|
29
|
+
name: 'ISO 27001:2022',
|
|
30
|
+
controls: [
|
|
31
|
+
{ id: 'A.5.1', category: 'policies', description: 'Information security policies', checks: ['policy-engine'] },
|
|
32
|
+
{ id: 'A.8.1', category: 'asset-management', description: 'Asset inventory', checks: ['data-classification'] },
|
|
33
|
+
{ id: 'A.8.9', category: 'configuration', description: 'Configuration management', checks: ['spec-drift', 'version-control'] },
|
|
34
|
+
{ id: 'A.8.25', category: 'sdlc', description: 'Secure development lifecycle', checks: ['secret-scan', 'security-review'] }
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
'hipaa': {
|
|
38
|
+
name: 'HIPAA',
|
|
39
|
+
controls: [
|
|
40
|
+
{ id: '164.312(a)', category: 'access', description: 'Access control', checks: ['auth-review', 'role-approval'] },
|
|
41
|
+
{ id: '164.312(c)', category: 'integrity', description: 'Data integrity', checks: ['data-classification', 'audit-trail'] },
|
|
42
|
+
{ id: '164.312(e)', category: 'transmission', description: 'Transmission security', checks: ['encryption-review'] },
|
|
43
|
+
{ id: '164.308(a)(1)', category: 'risk', description: 'Risk analysis', checks: ['risk-register'] }
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
'pci': {
|
|
47
|
+
name: 'PCI DSS 4.0',
|
|
48
|
+
controls: [
|
|
49
|
+
{ id: '6.2', category: 'software', description: 'Secure software development', checks: ['secret-scan', 'code-review'] },
|
|
50
|
+
{ id: '6.3', category: 'vulnerabilities', description: 'Vulnerability management', checks: ['dependency-scan', 'security-review'] },
|
|
51
|
+
{ id: '10.1', category: 'logging', description: 'Audit logging', checks: ['logging-review', 'audit-trail'] },
|
|
52
|
+
{ id: '12.1', category: 'policy', description: 'Security policy', checks: ['policy-engine'] }
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
'fedramp': {
|
|
56
|
+
name: 'FedRAMP',
|
|
57
|
+
controls: [
|
|
58
|
+
{ id: 'AC-1', category: 'access', description: 'Access control policy', checks: ['auth-review', 'role-approval'] },
|
|
59
|
+
{ id: 'CM-1', category: 'configuration', description: 'Configuration management policy', checks: ['spec-drift', 'version-control'] },
|
|
60
|
+
{ id: 'RA-5', category: 'risk', description: 'Vulnerability scanning', checks: ['dependency-scan', 'secret-scan'] },
|
|
61
|
+
{ id: 'SA-11', category: 'development', description: 'Developer security testing', checks: ['security-review', 'code-review'] }
|
|
62
|
+
]
|
|
63
|
+
},
|
|
64
|
+
'gdpr': {
|
|
65
|
+
name: 'GDPR',
|
|
66
|
+
controls: [
|
|
67
|
+
{ id: 'Art.25', category: 'design', description: 'Data protection by design', checks: ['data-classification', 'privacy-review'] },
|
|
68
|
+
{ id: 'Art.30', category: 'records', description: 'Records of processing', checks: ['data-classification', 'audit-trail'] },
|
|
69
|
+
{ id: 'Art.32', category: 'security', description: 'Security of processing', checks: ['encryption-review', 'secret-scan'] },
|
|
70
|
+
{ id: 'Art.35', category: 'impact', description: 'Data protection impact assessment', checks: ['risk-register', 'privacy-review'] }
|
|
71
|
+
]
|
|
72
|
+
},
|
|
73
|
+
'eu-ai-act': {
|
|
74
|
+
name: 'EU AI Act',
|
|
75
|
+
controls: [
|
|
76
|
+
{ id: 'Art.9', category: 'risk-management', description: 'Risk management system', checks: ['risk-register', 'model-governance'] },
|
|
77
|
+
{ id: 'Art.10', category: 'data-governance', description: 'Data and data governance', checks: ['data-classification', 'bias-review'] },
|
|
78
|
+
{ id: 'Art.13', category: 'transparency', description: 'Transparency and information', checks: ['model-documentation'] },
|
|
79
|
+
{ id: 'Art.15', category: 'accuracy', description: 'Accuracy, robustness, cybersecurity', checks: ['model-eval', 'security-review'] }
|
|
80
|
+
]
|
|
81
|
+
},
|
|
82
|
+
'nist-ai-rmf': {
|
|
83
|
+
name: 'NIST AI RMF 1.0',
|
|
84
|
+
controls: [
|
|
85
|
+
{ id: 'GOVERN-1', category: 'governance', description: 'AI risk governance', checks: ['model-governance', 'risk-register'] },
|
|
86
|
+
{ id: 'MAP-1', category: 'context', description: 'Context and usage mapping', checks: ['ai-intake', 'requirements-baseline'] },
|
|
87
|
+
{ id: 'MEASURE-1', category: 'measurement', description: 'AI risks measured', checks: ['model-eval', 'bias-review'] },
|
|
88
|
+
{ id: 'MANAGE-1', category: 'management', description: 'AI risks managed', checks: ['risk-register', 'model-governance'] }
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
function defaultState() {
|
|
94
|
+
return {
|
|
95
|
+
version: '1.0.0',
|
|
96
|
+
created_at: new Date().toISOString(),
|
|
97
|
+
last_updated: null,
|
|
98
|
+
applied_frameworks: [],
|
|
99
|
+
check_results: []
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function loadState(stateFile) {
|
|
104
|
+
const filePath = stateFile || DEFAULT_STATE_FILE;
|
|
105
|
+
if (!fs.existsSync(filePath)) return defaultState();
|
|
106
|
+
try { return JSON.parse(fs.readFileSync(filePath, 'utf8')); }
|
|
107
|
+
catch { return defaultState(); }
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function saveState(state, stateFile) {
|
|
111
|
+
const filePath = stateFile || DEFAULT_STATE_FILE;
|
|
112
|
+
const dir = path.dirname(filePath);
|
|
113
|
+
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
114
|
+
state.last_updated = new Date().toISOString();
|
|
115
|
+
fs.writeFileSync(filePath, JSON.stringify(state, null, 2) + '\n', 'utf8');
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* List available compliance frameworks.
|
|
120
|
+
* @returns {object}
|
|
121
|
+
*/
|
|
122
|
+
function listFrameworks() {
|
|
123
|
+
return {
|
|
124
|
+
success: true,
|
|
125
|
+
frameworks: Object.entries(COMPLIANCE_FRAMEWORKS).map(([id, fw]) => ({
|
|
126
|
+
id,
|
|
127
|
+
name: fw.name,
|
|
128
|
+
controls: fw.controls.length
|
|
129
|
+
})),
|
|
130
|
+
total: Object.keys(COMPLIANCE_FRAMEWORKS).length
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Apply a compliance framework to the project.
|
|
136
|
+
*
|
|
137
|
+
* @param {string} frameworkId
|
|
138
|
+
* @param {object} [options]
|
|
139
|
+
* @returns {object}
|
|
140
|
+
*/
|
|
141
|
+
function applyFramework(frameworkId, options = {}) {
|
|
142
|
+
const fw = COMPLIANCE_FRAMEWORKS[frameworkId];
|
|
143
|
+
if (!fw) {
|
|
144
|
+
return { success: false, error: `Unknown framework: ${frameworkId}. Available: ${Object.keys(COMPLIANCE_FRAMEWORKS).join(', ')}` };
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const stateFile = options.stateFile || DEFAULT_STATE_FILE;
|
|
148
|
+
const state = loadState(stateFile);
|
|
149
|
+
|
|
150
|
+
if (!state.applied_frameworks.includes(frameworkId)) {
|
|
151
|
+
state.applied_frameworks.push(frameworkId);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
saveState(state, stateFile);
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
success: true,
|
|
158
|
+
framework: frameworkId,
|
|
159
|
+
name: fw.name,
|
|
160
|
+
controls_added: fw.controls.length,
|
|
161
|
+
total_applied: state.applied_frameworks.length
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Check compliance against applied frameworks.
|
|
167
|
+
*
|
|
168
|
+
* @param {object} [options]
|
|
169
|
+
* @returns {object}
|
|
170
|
+
*/
|
|
171
|
+
function checkCompliance(options = {}) {
|
|
172
|
+
const stateFile = options.stateFile || DEFAULT_STATE_FILE;
|
|
173
|
+
const state = loadState(stateFile);
|
|
174
|
+
|
|
175
|
+
if (state.applied_frameworks.length === 0) {
|
|
176
|
+
return { success: true, message: 'No compliance frameworks applied', compliant: true, findings: [] };
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const findings = [];
|
|
180
|
+
for (const fwId of state.applied_frameworks) {
|
|
181
|
+
const fw = COMPLIANCE_FRAMEWORKS[fwId];
|
|
182
|
+
if (!fw) continue;
|
|
183
|
+
for (const control of fw.controls) {
|
|
184
|
+
findings.push({
|
|
185
|
+
framework: fwId,
|
|
186
|
+
control_id: control.id,
|
|
187
|
+
description: control.description,
|
|
188
|
+
category: control.category,
|
|
189
|
+
required_checks: control.checks,
|
|
190
|
+
status: 'needs-review'
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return {
|
|
196
|
+
success: true,
|
|
197
|
+
applied_frameworks: state.applied_frameworks,
|
|
198
|
+
total_controls: findings.length,
|
|
199
|
+
findings,
|
|
200
|
+
compliant: false,
|
|
201
|
+
summary: `${findings.length} controls require review across ${state.applied_frameworks.length} framework(s)`
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
module.exports = {
|
|
206
|
+
defaultState,
|
|
207
|
+
loadState,
|
|
208
|
+
saveState,
|
|
209
|
+
listFrameworks,
|
|
210
|
+
applyFramework,
|
|
211
|
+
checkCompliance,
|
|
212
|
+
COMPLIANCE_FRAMEWORKS
|
|
213
|
+
};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* context-chunker.js — Implementation Chunking by Context Window (Item 53)
|
|
3
|
+
*
|
|
4
|
+
* Split large work into optimized execution packets for different models.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* node bin/lib/context-chunker.js chunk|estimate|report [options]
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
'use strict';
|
|
11
|
+
|
|
12
|
+
const fs = require('fs');
|
|
13
|
+
const path = require('path');
|
|
14
|
+
|
|
15
|
+
const MODEL_CONTEXT_LIMITS = {
|
|
16
|
+
'gpt-4': { tokens: 8192, chars: 32768 },
|
|
17
|
+
'gpt-4-turbo': { tokens: 128000, chars: 512000 },
|
|
18
|
+
'gpt-4o': { tokens: 128000, chars: 512000 },
|
|
19
|
+
'claude-3-sonnet': { tokens: 200000, chars: 800000 },
|
|
20
|
+
'claude-3-opus': { tokens: 200000, chars: 800000 },
|
|
21
|
+
'claude-3-haiku': { tokens: 200000, chars: 800000 },
|
|
22
|
+
'default': { tokens: 32000, chars: 128000 }
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Estimate token count from text (rough: ~4 chars per token).
|
|
27
|
+
*
|
|
28
|
+
* @param {string} text
|
|
29
|
+
* @returns {number}
|
|
30
|
+
*/
|
|
31
|
+
function estimateTokens(text) {
|
|
32
|
+
return Math.ceil(text.length / 4);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Chunk a large text into context-window-sized pieces.
|
|
37
|
+
*
|
|
38
|
+
* @param {string} content - Content to chunk.
|
|
39
|
+
* @param {object} [options] - { model?, max_tokens?, overlap? }
|
|
40
|
+
* @returns {object}
|
|
41
|
+
*/
|
|
42
|
+
function chunkContent(content, options = {}) {
|
|
43
|
+
const model = options.model || 'default';
|
|
44
|
+
const limits = MODEL_CONTEXT_LIMITS[model] || MODEL_CONTEXT_LIMITS.default;
|
|
45
|
+
const maxTokens = options.max_tokens || Math.floor(limits.tokens * 0.8); // 80% of limit for safety
|
|
46
|
+
const overlapTokens = options.overlap || Math.floor(maxTokens * 0.05); // 5% overlap
|
|
47
|
+
|
|
48
|
+
const maxChars = maxTokens * 4;
|
|
49
|
+
const overlapChars = overlapTokens * 4;
|
|
50
|
+
|
|
51
|
+
const chunks = [];
|
|
52
|
+
let start = 0;
|
|
53
|
+
|
|
54
|
+
while (start < content.length) {
|
|
55
|
+
let end = Math.min(start + maxChars, content.length);
|
|
56
|
+
|
|
57
|
+
// Try to break at a natural boundary
|
|
58
|
+
if (end < content.length) {
|
|
59
|
+
const lastNewline = content.lastIndexOf('\n', end);
|
|
60
|
+
if (lastNewline > start + maxChars * 0.5) end = lastNewline + 1;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
chunks.push({
|
|
64
|
+
index: chunks.length,
|
|
65
|
+
start,
|
|
66
|
+
end,
|
|
67
|
+
length: end - start,
|
|
68
|
+
estimated_tokens: estimateTokens(content.substring(start, end))
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
start = end - overlapChars;
|
|
72
|
+
if (start >= content.length) break;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
success: true,
|
|
77
|
+
total_chars: content.length,
|
|
78
|
+
total_tokens: estimateTokens(content),
|
|
79
|
+
model,
|
|
80
|
+
max_tokens: maxTokens,
|
|
81
|
+
chunks: chunks.length,
|
|
82
|
+
chunk_details: chunks
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Chunk implementation plan tasks into execution packets.
|
|
88
|
+
*
|
|
89
|
+
* @param {string} root - Project root.
|
|
90
|
+
* @param {object} [options]
|
|
91
|
+
* @returns {object}
|
|
92
|
+
*/
|
|
93
|
+
function chunkImplementationPlan(root, options = {}) {
|
|
94
|
+
const planFile = path.join(root, 'specs', 'implementation-plan.md');
|
|
95
|
+
if (!fs.existsSync(planFile)) {
|
|
96
|
+
return { success: false, error: 'Implementation plan not found at specs/implementation-plan.md' };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const content = fs.readFileSync(planFile, 'utf8');
|
|
100
|
+
|
|
101
|
+
// Split by milestone/task sections
|
|
102
|
+
const sections = content.split(/^##\s+/m).filter(Boolean);
|
|
103
|
+
const packets = sections.map((section, i) => ({
|
|
104
|
+
index: i,
|
|
105
|
+
title: section.split('\n')[0].trim(),
|
|
106
|
+
estimated_tokens: estimateTokens(section),
|
|
107
|
+
lines: section.split('\n').length
|
|
108
|
+
}));
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
success: true,
|
|
112
|
+
total_sections: packets.length,
|
|
113
|
+
total_tokens: estimateTokens(content),
|
|
114
|
+
packets,
|
|
115
|
+
model_recommendations: Object.entries(MODEL_CONTEXT_LIMITS).map(([model, limits]) => ({
|
|
116
|
+
model,
|
|
117
|
+
fits_in_single_call: estimateTokens(content) <= limits.tokens * 0.8,
|
|
118
|
+
chunks_needed: Math.ceil(estimateTokens(content) / (limits.tokens * 0.8))
|
|
119
|
+
})).filter(r => r.model !== 'default')
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
module.exports = {
|
|
124
|
+
estimateTokens,
|
|
125
|
+
chunkContent,
|
|
126
|
+
chunkImplementationPlan,
|
|
127
|
+
MODEL_CONTEXT_LIMITS
|
|
128
|
+
};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* context-onboarding.js — Context-Aware Onboarding (Item 76)
|
|
3
|
+
*
|
|
4
|
+
* New team member enters a project and gets a curated summary,
|
|
5
|
+
* key decisions, and current risks.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* node bin/lib/context-onboarding.js generate|customize [options]
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
|
|
16
|
+
const ONBOARDING_SECTIONS = ['overview', 'architecture', 'decisions', 'risks', 'team', 'getting_started'];
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Generate onboarding package for a new team member.
|
|
20
|
+
*/
|
|
21
|
+
function generateOnboarding(root, options = {}) {
|
|
22
|
+
const pkg = {
|
|
23
|
+
generated_at: new Date().toISOString(),
|
|
24
|
+
role: options.role || 'engineer',
|
|
25
|
+
sections: {}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// Project overview
|
|
29
|
+
const configFile = path.join(root, '.jumpstart', 'config.yaml');
|
|
30
|
+
if (fs.existsSync(configFile)) {
|
|
31
|
+
pkg.sections.overview = { config_exists: true };
|
|
32
|
+
} else {
|
|
33
|
+
pkg.sections.overview = { config_exists: false };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Architecture decisions
|
|
37
|
+
const decisionsDir = path.join(root, 'specs', 'decisions');
|
|
38
|
+
const decisions = [];
|
|
39
|
+
if (fs.existsSync(decisionsDir)) {
|
|
40
|
+
for (const f of fs.readdirSync(decisionsDir).filter(f => f.endsWith('.md'))) {
|
|
41
|
+
decisions.push({ file: f, name: f.replace('.md', '') });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
pkg.sections.decisions = { total: decisions.length, files: decisions };
|
|
45
|
+
|
|
46
|
+
// Current risks
|
|
47
|
+
const riskFile = path.join(root, '.jumpstart', 'state', 'risk-register.json');
|
|
48
|
+
if (fs.existsSync(riskFile)) {
|
|
49
|
+
try {
|
|
50
|
+
const risks = JSON.parse(fs.readFileSync(riskFile, 'utf8'));
|
|
51
|
+
pkg.sections.risks = {
|
|
52
|
+
total: (risks.risks || []).length,
|
|
53
|
+
high: (risks.risks || []).filter(r => r.score >= 15).length
|
|
54
|
+
};
|
|
55
|
+
} catch { pkg.sections.risks = { total: 0, high: 0 }; }
|
|
56
|
+
} else {
|
|
57
|
+
pkg.sections.risks = { total: 0, high: 0 };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Phase status
|
|
61
|
+
const stateFile = path.join(root, '.jumpstart', 'state', 'state.json');
|
|
62
|
+
if (fs.existsSync(stateFile)) {
|
|
63
|
+
try {
|
|
64
|
+
const state = JSON.parse(fs.readFileSync(stateFile, 'utf8'));
|
|
65
|
+
pkg.sections.project_status = {
|
|
66
|
+
current_phase: state.current_phase || 0,
|
|
67
|
+
current_agent: state.current_agent || null
|
|
68
|
+
};
|
|
69
|
+
} catch { pkg.sections.project_status = { current_phase: 0 }; }
|
|
70
|
+
} else {
|
|
71
|
+
pkg.sections.project_status = { current_phase: 0 };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Available specs
|
|
75
|
+
const specsDir = path.join(root, 'specs');
|
|
76
|
+
const specs = [];
|
|
77
|
+
if (fs.existsSync(specsDir)) {
|
|
78
|
+
for (const f of fs.readdirSync(specsDir).filter(f => f.endsWith('.md'))) {
|
|
79
|
+
specs.push(f);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
pkg.sections.specs = { total: specs.length, files: specs };
|
|
83
|
+
|
|
84
|
+
// Getting started
|
|
85
|
+
const readmeFile = path.join(root, 'README.md');
|
|
86
|
+
pkg.sections.getting_started = {
|
|
87
|
+
has_readme: fs.existsSync(readmeFile),
|
|
88
|
+
has_package_json: fs.existsSync(path.join(root, 'package.json'))
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
return { success: true, onboarding: pkg };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Customize onboarding for a specific role.
|
|
96
|
+
*/
|
|
97
|
+
function customizeForRole(onboarding, role) {
|
|
98
|
+
if (!onboarding) return { success: false, error: 'Onboarding data is required' };
|
|
99
|
+
|
|
100
|
+
const roleFocus = {
|
|
101
|
+
engineer: ['architecture', 'getting_started', 'decisions'],
|
|
102
|
+
product: ['overview', 'specs', 'risks'],
|
|
103
|
+
executive: ['overview', 'risks', 'project_status'],
|
|
104
|
+
qa: ['specs', 'getting_started', 'risks']
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const focus = roleFocus[role] || roleFocus.engineer;
|
|
108
|
+
|
|
109
|
+
return {
|
|
110
|
+
success: true,
|
|
111
|
+
role,
|
|
112
|
+
focus_areas: focus,
|
|
113
|
+
relevant_sections: Object.fromEntries(
|
|
114
|
+
Object.entries(onboarding.sections || {}).filter(([k]) => focus.includes(k))
|
|
115
|
+
)
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
module.exports = {
|
|
120
|
+
generateOnboarding, customizeForRole,
|
|
121
|
+
ONBOARDING_SECTIONS
|
|
122
|
+
};
|