create-dss-project 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (83) hide show
  1. package/bin/create-dss-project.js +4 -0
  2. package/lib/index.js +80 -0
  3. package/lib/project-types.js +74 -0
  4. package/lib/prompts.js +42 -0
  5. package/lib/scaffold.js +169 -0
  6. package/package.json +30 -0
  7. package/template/.github/workflows/dashboard-build.yml +27 -0
  8. package/template/.github/workflows/template-lint.yml +71 -0
  9. package/template/CHANGELOG.md +43 -0
  10. package/template/CLAUDE.md +145 -0
  11. package/template/LICENSE +21 -0
  12. package/template/README.md +201 -0
  13. package/template/STATUS.md +34 -0
  14. package/template/context/competitor-snapshot.md +27 -0
  15. package/template/context/market-snapshot.md +32 -0
  16. package/template/context/pipeline-state.md +36 -0
  17. package/template/context/project-state.md +45 -0
  18. package/template/dashboard/CLAUDE.md +36 -0
  19. package/template/dashboard/DEPLOY.md +60 -0
  20. package/template/dashboard/build-data.js +395 -0
  21. package/template/dashboard/competitors.html +143 -0
  22. package/template/dashboard/css/styles.css +143 -0
  23. package/template/dashboard/data/.gitkeep +0 -0
  24. package/template/dashboard/decisions.html +132 -0
  25. package/template/dashboard/index.html +152 -0
  26. package/template/dashboard/js/app.js +59 -0
  27. package/template/dashboard/js/overview.js +50 -0
  28. package/template/dashboard/js/sidebar.js +62 -0
  29. package/template/dashboard/js/tailwind-config.js +52 -0
  30. package/template/dashboard/package-lock.json +351 -0
  31. package/template/dashboard/package.json +17 -0
  32. package/template/dashboard/pipeline.html +149 -0
  33. package/template/dashboard/research.html +215 -0
  34. package/template/dashboard/robots.txt +2 -0
  35. package/template/dashboard/scoring.html +187 -0
  36. package/template/dashboard/timeline.html +165 -0
  37. package/template/dashboard/vercel.json +5 -0
  38. package/template/dashboard/watch.js +57 -0
  39. package/template/data/.gitkeep +0 -0
  40. package/template/discovery/calls/.gitkeep +0 -0
  41. package/template/discovery/outreach/.gitkeep +0 -0
  42. package/template/discovery/prep/.gitkeep +0 -0
  43. package/template/docs/decks/.gitkeep +0 -0
  44. package/template/docs/executive-summary.md +104 -0
  45. package/template/docs/getting-started.md +274 -0
  46. package/template/docs/memos/evidence-grading.md +27 -0
  47. package/template/docs/memos/housekeeping-reference.md +101 -0
  48. package/template/docs/memos/reference-context.md +30 -0
  49. package/template/docs/output/project-activity.md +8 -0
  50. package/template/docs/output/status-blurb.md +4 -0
  51. package/template/docs/output/work-log.md +8 -0
  52. package/template/docs/skill-authoring-guide.md +212 -0
  53. package/template/memory/MEMORY.md +84 -0
  54. package/template/memory/decisions.md +13 -0
  55. package/template/memory/discovery.md +48 -0
  56. package/template/memory/research.md +33 -0
  57. package/template/memory/scoring.md +34 -0
  58. package/template/project.config.example.json +31 -0
  59. package/template/research/competitors/.gitkeep +0 -0
  60. package/template/research/market/.gitkeep +0 -0
  61. package/template/research/technical/.gitkeep +0 -0
  62. package/template/scripts/.gitkeep +0 -0
  63. package/template/scripts/build-cli-template.sh +32 -0
  64. package/template/scripts/health-check.sh +152 -0
  65. package/template/scripts/reset-to-template.sh +115 -0
  66. package/template/scripts/validate-placeholders.sh +47 -0
  67. package/template/skills/compare-options/SKILL.md +97 -0
  68. package/template/skills/critical-reasoning/SKILL.md +107 -0
  69. package/template/skills/decision/SKILL.md +75 -0
  70. package/template/skills/enrich-entity/SKILL.md +107 -0
  71. package/template/skills/health-check/SKILL.md +144 -0
  72. package/template/skills/onboard/SKILL.md +434 -0
  73. package/template/skills/outreach-sequence/SKILL.md +79 -0
  74. package/template/skills/pipeline-update/SKILL.md +90 -0
  75. package/template/skills/process-call/SKILL.md +96 -0
  76. package/template/skills/rebuild-snapshots/SKILL.md +88 -0
  77. package/template/skills/session-end/SKILL.md +120 -0
  78. package/template/skills/session-start/SKILL.md +93 -0
  79. package/template/skills/synthesise/SKILL.md +108 -0
  80. package/template/skills/weekly-report/SKILL.md +79 -0
  81. package/template/templates/call-notes.md +67 -0
  82. package/template/templates/call-prep.md +65 -0
  83. package/template/templates/entity-teardown.md +58 -0
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { main } = require('../lib/index.js');
4
+ main(process.argv[2]);
package/lib/index.js ADDED
@@ -0,0 +1,80 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const { execSync } = require('child_process');
4
+ const { askQuestions } = require('./prompts');
5
+ const { scaffold } = require('./scaffold');
6
+
7
+ async function main(nameArg) {
8
+ console.log('\n DS Strategy Stack\n');
9
+
10
+ const answers = await askQuestions(nameArg);
11
+
12
+ if (!answers.projectName || !answers.projectType || !answers.structure) {
13
+ console.log('Missing required answers. Exiting.');
14
+ process.exit(1);
15
+ }
16
+
17
+ const targetDir = path.resolve(process.cwd(), answers.projectName);
18
+
19
+ if (fs.existsSync(targetDir)) {
20
+ console.error(`\n Error: Directory "${answers.projectName}" already exists.\n`);
21
+ process.exit(1);
22
+ }
23
+
24
+ // Resolve template directory — when published, it's at cli/template/
25
+ // When running from source, it's the repo root (parent of cli/)
26
+ let templateDir = path.join(__dirname, '..', 'template');
27
+ if (!fs.existsSync(templateDir)) {
28
+ templateDir = path.resolve(__dirname, '..', '..');
29
+ }
30
+
31
+ console.log(`\n Creating project in ${targetDir}\n`);
32
+
33
+ const { modules } = scaffold(targetDir, templateDir, {
34
+ projectName: answers.projectName,
35
+ projectType: answers.projectType,
36
+ structure: answers.structure,
37
+ });
38
+
39
+ // Git init
40
+ try {
41
+ execSync('git init', { cwd: targetDir, stdio: 'ignore' });
42
+ execSync('git add -A', { cwd: targetDir, stdio: 'ignore' });
43
+ execSync('git commit -m "Initial project from DS Strategy Stack"', {
44
+ cwd: targetDir,
45
+ stdio: 'ignore',
46
+ });
47
+ console.log(' ✓ Git repository initialised');
48
+ } catch {
49
+ console.log(' ⚠ Could not initialise git — you can do this manually');
50
+ }
51
+
52
+ // Install dashboard dependencies
53
+ if (modules.dashboard && fs.existsSync(path.join(targetDir, 'dashboard', 'package.json'))) {
54
+ console.log(' ⏳ Installing dashboard dependencies...');
55
+ try {
56
+ execSync('npm install', {
57
+ cwd: path.join(targetDir, 'dashboard'),
58
+ stdio: 'ignore',
59
+ });
60
+ console.log(' ✓ Dashboard dependencies installed');
61
+ } catch {
62
+ console.log(' ⚠ Could not install dashboard deps — run "cd dashboard && npm install" manually');
63
+ }
64
+ }
65
+
66
+ console.log(`
67
+ ✅ Project created!
68
+
69
+ Next steps:
70
+
71
+ cd ${answers.projectName}
72
+ claude
73
+ /onboard
74
+
75
+ The /onboard skill will walk you through configuring
76
+ your hypothesis, scoring dimensions, and kill conditions.
77
+ `);
78
+ }
79
+
80
+ module.exports = { main };
@@ -0,0 +1,74 @@
1
+ const PROJECT_TYPES = {
2
+ 'market-entry': {
3
+ label: 'Market Entry',
4
+ description: 'Evaluating a new market or product opportunity',
5
+ discovery: true, pipeline: true, dashboard: true,
6
+ entityType: 'prospect',
7
+ scoringDimensions: ['White Space', 'Urgency', 'Feasibility', 'Defensibility', 'Revenue Potential'],
8
+ },
9
+ 'growth-strategy': {
10
+ label: 'Growth Strategy',
11
+ description: 'Expanding an existing product into new channels or segments',
12
+ discovery: true, pipeline: true, dashboard: true,
13
+ entityType: 'prospect',
14
+ scoringDimensions: ['Growth Potential', 'CAC Efficiency', 'Retention Impact', 'Speed to Market', 'Scalability'],
15
+ },
16
+ 'competitor-research': {
17
+ label: 'Competitor Research',
18
+ description: 'Competitive intelligence and landscape mapping',
19
+ discovery: false, pipeline: false, dashboard: true,
20
+ entityType: 'competitor',
21
+ scoringDimensions: ['Market Share', 'Product Strength', 'Pricing Power', 'Growth Trajectory', 'Threat Level'],
22
+ },
23
+ 'product-launch-gtm': {
24
+ label: 'Product Launch / GTM',
25
+ description: 'Bringing a product or feature to market',
26
+ discovery: true, pipeline: true, dashboard: true,
27
+ entityType: 'prospect',
28
+ scoringDimensions: ['Market Readiness', 'Channel Fit', 'Competitive Timing', 'Resource Requirement', 'Revenue Impact'],
29
+ },
30
+ 'internal-implementation': {
31
+ label: 'Internal Implementation',
32
+ description: 'Rolling out a new system, process, or initiative',
33
+ discovery: false, pipeline: true, dashboard: true,
34
+ entityType: 'workstream',
35
+ scoringDimensions: ['Business Impact', 'Technical Complexity', 'Change Readiness', 'Resource Cost', 'Timeline Risk'],
36
+ },
37
+ 'vendor-partner-eval': {
38
+ label: 'Vendor / Partner Evaluation',
39
+ description: 'Selecting tools, platforms, or partners',
40
+ discovery: true, pipeline: true, dashboard: true,
41
+ entityType: 'vendor',
42
+ scoringDimensions: ['Capability Fit', 'Total Cost', 'Integration Effort', 'Vendor Stability', 'Lock-in Risk'],
43
+ },
44
+ 'due-diligence': {
45
+ label: 'Due Diligence',
46
+ description: 'M&A, investment, or acquisition evaluation',
47
+ discovery: true, pipeline: true, dashboard: true,
48
+ entityType: 'target',
49
+ scoringDimensions: ['Strategic Fit', 'Financial Health', 'Integration Risk', 'Synergy Potential', 'Cultural Alignment'],
50
+ },
51
+ 'business-case': {
52
+ label: 'Business Case',
53
+ description: 'Building a case for investment or strategic change',
54
+ discovery: false, pipeline: false, dashboard: false,
55
+ entityType: 'option',
56
+ scoringDimensions: ['ROI Potential', 'Strategic Alignment', 'Execution Risk', 'Stakeholder Support', 'Opportunity Cost'],
57
+ },
58
+ 'transformation': {
59
+ label: 'Transformation / Change',
60
+ description: 'Organisational or process transformation',
61
+ discovery: true, pipeline: true, dashboard: true,
62
+ entityType: 'initiative',
63
+ scoringDimensions: ['Impact Scope', 'Organisational Readiness', 'Resource Requirement', 'Risk Level', 'Time to Value'],
64
+ },
65
+ 'custom': {
66
+ label: 'Custom',
67
+ description: 'Something else — configure modules manually',
68
+ discovery: true, pipeline: true, dashboard: true,
69
+ entityType: 'entity',
70
+ scoringDimensions: ['White Space', 'Urgency', 'Feasibility', 'Defensibility', 'Revenue Potential'],
71
+ },
72
+ };
73
+
74
+ module.exports = { PROJECT_TYPES };
package/lib/prompts.js ADDED
@@ -0,0 +1,42 @@
1
+ const prompts = require('prompts');
2
+ const { PROJECT_TYPES } = require('./project-types');
3
+
4
+ async function askQuestions(defaultName) {
5
+ const response = await prompts([
6
+ {
7
+ type: 'text',
8
+ name: 'projectName',
9
+ message: 'Project name',
10
+ initial: defaultName || 'my-strategy-project',
11
+ },
12
+ {
13
+ type: 'select',
14
+ name: 'projectType',
15
+ message: 'What type of project is this?',
16
+ choices: Object.entries(PROJECT_TYPES).map(([value, t]) => ({
17
+ title: t.label,
18
+ description: t.description,
19
+ value,
20
+ })),
21
+ },
22
+ {
23
+ type: 'select',
24
+ name: 'structure',
25
+ message: 'How much structure do you want?',
26
+ choices: [
27
+ { title: 'Full', description: 'All features: scoring, kill conditions, evidence grading, weekly reports, context snapshots', value: 'full' },
28
+ { title: 'Essentials', description: 'Core features: research, pipeline, decisions, dashboard', value: 'essentials' },
29
+ { title: 'Minimal', description: 'Bare bones: research and notes only', value: 'minimal' },
30
+ ],
31
+ },
32
+ ], {
33
+ onCancel: () => {
34
+ console.log('\nSetup cancelled.');
35
+ process.exit(0);
36
+ },
37
+ });
38
+
39
+ return response;
40
+ }
41
+
42
+ module.exports = { askQuestions };
@@ -0,0 +1,169 @@
1
+ const fs = require('fs');
2
+ const path = require('path');
3
+ const { PROJECT_TYPES } = require('./project-types');
4
+
5
+ const EXCLUDE_FROM_COPY = [
6
+ '.git',
7
+ 'node_modules',
8
+ '.DS_Store',
9
+ 'cli',
10
+ '.next',
11
+ '.claude',
12
+ 'dashboard/data/overview.json',
13
+ 'dashboard/data/entities.json',
14
+ 'dashboard/data/competitors.json',
15
+ 'dashboard/data/decisions.json',
16
+ 'dashboard/data/scoring.json',
17
+ 'dashboard/data/timeline.json',
18
+ 'dashboard/data/research.json',
19
+ 'dashboard/screenshot.png',
20
+ 'project.config.json',
21
+ 'CONTRIBUTING.md',
22
+ '.github/ISSUE_TEMPLATE',
23
+ '.github/pull_request_template.md',
24
+ ];
25
+
26
+ function shouldExclude(relativePath) {
27
+ return EXCLUDE_FROM_COPY.some(ex =>
28
+ relativePath === ex || relativePath.startsWith(ex + '/')
29
+ );
30
+ }
31
+
32
+ function copyDir(src, dest, baseDir) {
33
+ fs.mkdirSync(dest, { recursive: true });
34
+ const entries = fs.readdirSync(src, { withFileTypes: true });
35
+
36
+ for (const entry of entries) {
37
+ const srcPath = path.join(src, entry.name);
38
+ const destPath = path.join(dest, entry.name);
39
+ const relative = path.relative(baseDir, srcPath);
40
+
41
+ if (shouldExclude(relative)) continue;
42
+
43
+ if (entry.isDirectory()) {
44
+ copyDir(srcPath, destPath, baseDir);
45
+ } else {
46
+ fs.copyFileSync(srcPath, destPath);
47
+ // Preserve executable permissions
48
+ const stat = fs.statSync(srcPath);
49
+ fs.chmodSync(destPath, stat.mode);
50
+ }
51
+ }
52
+ }
53
+
54
+ function removeIfExists(targetDir, relativePath) {
55
+ const full = path.join(targetDir, relativePath);
56
+ if (fs.existsSync(full)) {
57
+ fs.rmSync(full, { recursive: true, force: true });
58
+ }
59
+ }
60
+
61
+ function scaffold(targetDir, templateDir, options) {
62
+ const { projectType, structure, projectName } = options;
63
+ const typeConfig = PROJECT_TYPES[projectType];
64
+
65
+ // 1. Copy template
66
+ copyDir(templateDir, targetDir, templateDir);
67
+
68
+ // 2. Determine effective module flags
69
+ const modules = {
70
+ discovery: typeConfig.discovery,
71
+ pipeline: typeConfig.pipeline,
72
+ dashboard: typeConfig.dashboard,
73
+ };
74
+
75
+ const features = {
76
+ scoring: true,
77
+ killConditions: true,
78
+ evidenceGrading: true,
79
+ weeklyReports: true,
80
+ contextSnapshots: true,
81
+ };
82
+
83
+ // 3. Apply structure-level removals
84
+ if (structure === 'minimal') {
85
+ modules.discovery = false;
86
+ modules.pipeline = false;
87
+ modules.dashboard = false;
88
+ features.scoring = false;
89
+ features.killConditions = false;
90
+ features.evidenceGrading = false;
91
+ features.weeklyReports = false;
92
+ features.contextSnapshots = false;
93
+
94
+ removeIfExists(targetDir, 'context');
95
+ removeIfExists(targetDir, 'skills/compare-options');
96
+ removeIfExists(targetDir, 'skills/weekly-report');
97
+ removeIfExists(targetDir, 'skills/rebuild-snapshots');
98
+ removeIfExists(targetDir, 'memory/scoring.md');
99
+ }
100
+
101
+ if (structure === 'essentials') {
102
+ features.scoring = false;
103
+ features.killConditions = false;
104
+ features.evidenceGrading = false;
105
+
106
+ removeIfExists(targetDir, 'memory/scoring.md');
107
+ removeIfExists(targetDir, 'dashboard/scoring.html');
108
+ removeIfExists(targetDir, 'skills/compare-options');
109
+ }
110
+
111
+ // 4. Apply module-level removals
112
+ if (!modules.discovery) {
113
+ removeIfExists(targetDir, 'discovery');
114
+ removeIfExists(targetDir, 'memory/discovery.md');
115
+ removeIfExists(targetDir, 'context/pipeline-state.md');
116
+ removeIfExists(targetDir, 'dashboard/pipeline.html');
117
+ removeIfExists(targetDir, 'skills/pipeline-update');
118
+ removeIfExists(targetDir, 'skills/outreach-sequence');
119
+ removeIfExists(targetDir, 'skills/process-call');
120
+ }
121
+
122
+ if (!modules.pipeline && modules.discovery) {
123
+ // Pipeline off but discovery might still be on in custom
124
+ removeIfExists(targetDir, 'skills/pipeline-update');
125
+ removeIfExists(targetDir, 'skills/outreach-sequence');
126
+ }
127
+
128
+ if (!modules.dashboard) {
129
+ removeIfExists(targetDir, 'dashboard');
130
+ }
131
+
132
+ // 5. Remove template-repo-only files
133
+ removeIfExists(targetDir, 'project.config.example.json');
134
+ removeIfExists(targetDir, 'scripts/reset-to-template.sh');
135
+ removeIfExists(targetDir, 'scripts/validate-placeholders.sh');
136
+
137
+ // 6. Write project.config.json
138
+ const config = {
139
+ templateVersion: '1.0.0',
140
+ templateSource: 'github.com/DiffTheEnder/DSS-Claude-Stack',
141
+ projectType,
142
+ projectName,
143
+ projectSlug: projectName.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, ''),
144
+ oneLineDescription: '',
145
+ goal: '',
146
+ team: '',
147
+ scope: '',
148
+ outOfScope: '',
149
+ strategicHypothesis: '',
150
+ icpDescription: '',
151
+ entityType: typeConfig.entityType,
152
+ entityTypePlural: typeConfig.entityType + 's',
153
+ pipelineSourceOfTruth: 'data/entities.csv',
154
+ dashboardUrl: '',
155
+ modules,
156
+ features,
157
+ scoringDimensions: typeConfig.scoringDimensions,
158
+ killConditions: [],
159
+ };
160
+
161
+ fs.writeFileSync(
162
+ path.join(targetDir, 'project.config.json'),
163
+ JSON.stringify(config, null, 2) + '\n'
164
+ );
165
+
166
+ return { modules, features };
167
+ }
168
+
169
+ module.exports = { scaffold };
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "create-dss-project",
3
+ "version": "0.1.0",
4
+ "description": "Scaffold a DS Strategy Stack project for Claude Code",
5
+ "bin": {
6
+ "create-dss-project": "./bin/create-dss-project.js"
7
+ },
8
+ "files": [
9
+ "bin/",
10
+ "lib/",
11
+ "template/"
12
+ ],
13
+ "scripts": {
14
+ "prepublishOnly": "bash ../scripts/build-cli-template.sh"
15
+ },
16
+ "keywords": [
17
+ "strategy",
18
+ "claude-code",
19
+ "scaffold",
20
+ "cli",
21
+ "project-template"
22
+ ],
23
+ "license": "MIT",
24
+ "engines": {
25
+ "node": ">=16.7.0"
26
+ },
27
+ "dependencies": {
28
+ "prompts": "^2.4.2"
29
+ }
30
+ }
@@ -0,0 +1,27 @@
1
+ name: Dashboard Build
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+
7
+ jobs:
8
+ build:
9
+ runs-on: ubuntu-latest
10
+
11
+ steps:
12
+ - name: Checkout repository
13
+ uses: actions/checkout@v4
14
+
15
+ - name: Set up Node.js 18
16
+ uses: actions/setup-node@v4
17
+ with:
18
+ node-version: 18
19
+
20
+ - name: Install dependencies and build dashboard data
21
+ run: cd dashboard && npm install && node build-data.js
22
+
23
+ - name: Validate placeholders in built JSON
24
+ run: |
25
+ # Check only the generated dashboard JSON files for leftover placeholders
26
+ chmod +x scripts/validate-placeholders.sh
27
+ scripts/validate-placeholders.sh dashboard/data
@@ -0,0 +1,71 @@
1
+ name: Template Lint
2
+
3
+ on:
4
+ pull_request:
5
+
6
+ jobs:
7
+ lint:
8
+ runs-on: ubuntu-latest
9
+
10
+ steps:
11
+ - name: Checkout repository
12
+ uses: actions/checkout@v4
13
+
14
+ - name: Validate SKILL.md frontmatter
15
+ run: |
16
+ # Every SKILL.md must have YAML frontmatter with 'name' and 'description' fields
17
+ EXIT_CODE=0
18
+ for skill_file in skills/*/SKILL.md; do
19
+ if [ ! -f "$skill_file" ]; then
20
+ continue
21
+ fi
22
+
23
+ # Check the file starts with ---
24
+ FIRST_LINE=$(head -n 1 "$skill_file")
25
+ if [ "$FIRST_LINE" != "---" ]; then
26
+ echo "FAIL: $skill_file — missing frontmatter (no opening ---)"
27
+ EXIT_CODE=1
28
+ continue
29
+ fi
30
+
31
+ # Extract frontmatter (between first and second ---)
32
+ FRONTMATTER=$(sed -n '2,/^---$/p' "$skill_file" | head -n -1)
33
+
34
+ # Check for 'name:' field
35
+ if ! echo "$FRONTMATTER" | grep -q '^name:'; then
36
+ echo "FAIL: $skill_file — frontmatter missing 'name' field"
37
+ EXIT_CODE=1
38
+ fi
39
+
40
+ # Check for 'description:' field
41
+ if ! echo "$FRONTMATTER" | grep -q '^description:'; then
42
+ echo "FAIL: $skill_file — frontmatter missing 'description' field"
43
+ EXIT_CODE=1
44
+ fi
45
+
46
+ if [ "$EXIT_CODE" -eq 0 ]; then
47
+ echo "PASS: $skill_file"
48
+ fi
49
+ done
50
+
51
+ exit $EXIT_CODE
52
+
53
+ - name: Check markdown for unclosed code blocks
54
+ run: |
55
+ # Verify all markdown files have balanced ``` fences
56
+ EXIT_CODE=0
57
+ while IFS= read -r md_file; do
58
+ # Count lines that start with ``` (opening or closing fence)
59
+ FENCE_COUNT=$(grep -c '^ *```' "$md_file" 2>/dev/null || echo 0)
60
+ # An odd count means an unclosed code block
61
+ if [ $((FENCE_COUNT % 2)) -ne 0 ]; then
62
+ echo "FAIL: $md_file — unclosed code block ($FENCE_COUNT fence markers, expected even)"
63
+ EXIT_CODE=1
64
+ fi
65
+ done < <(find . -name "*.md" -not -path "*/node_modules/*" -not -path "*/.git/*")
66
+
67
+ if [ "$EXIT_CODE" -eq 0 ]; then
68
+ echo "PASS: All markdown files have balanced code fences."
69
+ fi
70
+
71
+ exit $EXIT_CODE
@@ -0,0 +1,43 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [1.2.0] — 2026-03-26
6
+
7
+ ### Added
8
+ - 6 new project types: Competitor Research, Product Launch / GTM, Internal Implementation, Vendor / Partner Evaluation, Due Diligence, Business Case, Transformation / Change
9
+ - Alternative pipeline lifecycle for non-outreach projects (Not started → In progress → Blocked → Completed → Cancelled)
10
+ - `projectType` field in project.config.json
11
+ - Type-specific scoring dimensions and kill condition examples for all 10 types
12
+
13
+ ### Changed
14
+ - Replaced "Corporate Strategy" with more specific types: Business Case and Transformation / Change
15
+ - Onboarding now offers 10 project types with tailored defaults for each
16
+
17
+ ## [1.1.0] — 2026-03-26
18
+
19
+ ### Added
20
+ - Getting Started guide for non-technical users (`docs/getting-started.md`)
21
+ - Dashboard deployment guide (`dashboard/DEPLOY.md`)
22
+ - Onboarding now asks about user goals (learning, real project, team coordination, exploration)
23
+ - Onboarding now asks about experience level and feature selection (Full, Essentials, Minimal)
24
+ - Feature toggles in `project.config.json` (scoring, kill conditions, evidence grading, weekly reports, context snapshots)
25
+
26
+ ### Changed
27
+ - Simplified `/critical-reasoning` from 6 specialised lenses + leader frameworks to 4 accessible lenses (Is It True?, What Happens Next?, What Could Go Wrong?, Can It Actually Be Done?)
28
+ - Onboarding Quick Start expanded from 5 to 7 questions (added goal and structure level)
29
+ - Onboarding Full Setup expanded from 13 to 16 questions (added goals, experience, feature selection)
30
+
31
+ ## [1.0.0] — 2026-03-26
32
+
33
+ ### Added
34
+ - Initial open-source release
35
+ - 14-skill library (onboard, session-start, session-end, health-check, rebuild-snapshots, pipeline-update, outreach-sequence, process-call, enrich-entity, synthesise, critical-reasoning, decision, compare-options, weekly-report)
36
+ - Live dashboard with 7 pages (overview, pipeline, competitors, decisions, scoring, timeline, research hub)
37
+ - Memory layer with 5 persistent files
38
+ - Context snapshot system (4 pre-computed snapshots)
39
+ - 3 templates (call-prep, call-notes, entity-teardown)
40
+ - Evidence grading system
41
+ - Multi-agent coordination via STATUS.md
42
+ - Vercel deployment support
43
+ - Project template