@cloudstreamsoftware/claude-tools 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +152 -37
- package/agents/INDEX.md +183 -0
- package/agents/architect.md +247 -0
- package/agents/build-error-resolver.md +555 -0
- package/agents/catalyst-deployer.md +132 -0
- package/agents/code-reviewer.md +121 -0
- package/agents/compliance-auditor.md +148 -0
- package/agents/creator-architect.md +395 -0
- package/agents/deluge-reviewer.md +98 -0
- package/agents/doc-updater.md +471 -0
- package/agents/e2e-runner.md +711 -0
- package/agents/planner.md +122 -0
- package/agents/refactor-cleaner.md +309 -0
- package/agents/security-reviewer.md +582 -0
- package/agents/tdd-guide.md +302 -0
- package/bin/cloudstream-setup.js +16 -6
- package/config/versions.json +63 -0
- package/dist/hooks/hooks.json +209 -0
- package/dist/index.js +47 -0
- package/dist/lib/asset-value.js +609 -0
- package/dist/lib/client-manager.js +300 -0
- package/dist/lib/command-matcher.js +242 -0
- package/dist/lib/cross-session-patterns.js +754 -0
- package/dist/lib/intent-classifier.js +1075 -0
- package/dist/lib/package-manager.js +374 -0
- package/dist/lib/recommendation-engine.js +597 -0
- package/dist/lib/session-memory.js +489 -0
- package/dist/lib/skill-effectiveness.js +486 -0
- package/dist/lib/skill-matcher.js +595 -0
- package/dist/lib/tutorial-metrics.js +242 -0
- package/dist/lib/tutorial-progress.js +209 -0
- package/dist/lib/tutorial-renderer.js +431 -0
- package/dist/lib/utils.js +380 -0
- package/dist/lib/verify-formatter.js +143 -0
- package/dist/lib/workflow-state.js +249 -0
- package/hooks/hooks.json +209 -0
- package/package.json +5 -1
- package/scripts/aggregate-sessions.js +290 -0
- package/scripts/branch-name-validator.js +291 -0
- package/scripts/build.js +101 -0
- package/scripts/commands/client-switch.js +231 -0
- package/scripts/deprecate-skill.js +610 -0
- package/scripts/diagnose.js +324 -0
- package/scripts/doc-freshness.js +168 -0
- package/scripts/generate-weekly-digest.js +393 -0
- package/scripts/health-check.js +270 -0
- package/scripts/hooks/credential-check.js +101 -0
- package/scripts/hooks/evaluate-session.js +81 -0
- package/scripts/hooks/pre-compact.js +66 -0
- package/scripts/hooks/prompt-analyzer.js +276 -0
- package/scripts/hooks/prompt-router.js +422 -0
- package/scripts/hooks/quality-gate-enforcer.js +371 -0
- package/scripts/hooks/session-end.js +156 -0
- package/scripts/hooks/session-start.js +195 -0
- package/scripts/hooks/skill-injector.js +333 -0
- package/scripts/hooks/suggest-compact.js +58 -0
- package/scripts/lib/asset-value.js +609 -0
- package/scripts/lib/client-manager.js +300 -0
- package/scripts/lib/command-matcher.js +242 -0
- package/scripts/lib/cross-session-patterns.js +754 -0
- package/scripts/lib/intent-classifier.js +1075 -0
- package/scripts/lib/package-manager.js +374 -0
- package/scripts/lib/recommendation-engine.js +597 -0
- package/scripts/lib/session-memory.js +489 -0
- package/scripts/lib/skill-effectiveness.js +486 -0
- package/scripts/lib/skill-matcher.js +595 -0
- package/scripts/lib/tutorial-metrics.js +242 -0
- package/scripts/lib/tutorial-progress.js +209 -0
- package/scripts/lib/tutorial-renderer.js +431 -0
- package/scripts/lib/utils.js +380 -0
- package/scripts/lib/verify-formatter.js +143 -0
- package/scripts/lib/workflow-state.js +249 -0
- package/scripts/onboard.js +363 -0
- package/scripts/quarterly-report.js +692 -0
- package/scripts/setup-package-manager.js +204 -0
- package/scripts/sync-upstream.js +391 -0
- package/scripts/test.js +108 -0
- package/scripts/tutorial-runner.js +351 -0
- package/scripts/validate-all.js +201 -0
- package/scripts/verifiers/agents.js +245 -0
- package/scripts/verifiers/config.js +186 -0
- package/scripts/verifiers/environment.js +123 -0
- package/scripts/verifiers/hooks.js +188 -0
- package/scripts/verifiers/index.js +38 -0
- package/scripts/verifiers/persistence.js +140 -0
- package/scripts/verifiers/plugin.js +215 -0
- package/scripts/verifiers/skills.js +209 -0
- package/scripts/verify-setup.js +164 -0
- package/skills/INDEX.md +157 -0
- package/skills/backend-patterns/SKILL.md +586 -0
- package/skills/backend-patterns/catalyst-patterns.md +128 -0
- package/skills/bigquery-patterns/SKILL.md +27 -0
- package/skills/bigquery-patterns/performance-optimization.md +518 -0
- package/skills/bigquery-patterns/query-patterns.md +372 -0
- package/skills/bigquery-patterns/schema-design.md +78 -0
- package/skills/cloudstream-project-template/SKILL.md +20 -0
- package/skills/cloudstream-project-template/structure.md +65 -0
- package/skills/coding-standards/SKILL.md +524 -0
- package/skills/coding-standards/deluge-standards.md +83 -0
- package/skills/compliance-patterns/SKILL.md +28 -0
- package/skills/compliance-patterns/hipaa/audit-requirements.md +251 -0
- package/skills/compliance-patterns/hipaa/baa-process.md +298 -0
- package/skills/compliance-patterns/hipaa/data-archival-strategy.md +387 -0
- package/skills/compliance-patterns/hipaa/phi-handling.md +52 -0
- package/skills/compliance-patterns/pci-dss/saq-a-requirements.md +307 -0
- package/skills/compliance-patterns/pci-dss/tokenization-patterns.md +382 -0
- package/skills/compliance-patterns/pci-dss/zoho-checkout-patterns.md +56 -0
- package/skills/compliance-patterns/soc2/access-controls.md +344 -0
- package/skills/compliance-patterns/soc2/audit-logging.md +458 -0
- package/skills/compliance-patterns/soc2/change-management.md +403 -0
- package/skills/compliance-patterns/soc2/deluge-execution-logging.md +407 -0
- package/skills/consultancy-workflows/SKILL.md +19 -0
- package/skills/consultancy-workflows/client-isolation.md +21 -0
- package/skills/consultancy-workflows/documentation-automation.md +454 -0
- package/skills/consultancy-workflows/handoff-procedures.md +257 -0
- package/skills/consultancy-workflows/knowledge-capture.md +513 -0
- package/skills/consultancy-workflows/time-tracking.md +26 -0
- package/skills/continuous-learning/SKILL.md +84 -0
- package/skills/continuous-learning/config.json +18 -0
- package/skills/continuous-learning/evaluate-session.sh +60 -0
- package/skills/continuous-learning-v2/SKILL.md +126 -0
- package/skills/continuous-learning-v2/config.json +61 -0
- package/skills/frontend-patterns/SKILL.md +635 -0
- package/skills/frontend-patterns/zoho-widget-patterns.md +103 -0
- package/skills/gcp-data-engineering/SKILL.md +36 -0
- package/skills/gcp-data-engineering/bigquery/performance-optimization.md +337 -0
- package/skills/gcp-data-engineering/dataflow/error-handling.md +496 -0
- package/skills/gcp-data-engineering/dataflow/pipeline-patterns.md +444 -0
- package/skills/gcp-data-engineering/dbt/model-organization.md +63 -0
- package/skills/gcp-data-engineering/dbt/testing-patterns.md +503 -0
- package/skills/gcp-data-engineering/medallion-architecture/bronze-layer.md +60 -0
- package/skills/gcp-data-engineering/medallion-architecture/gold-layer.md +311 -0
- package/skills/gcp-data-engineering/medallion-architecture/layer-transitions.md +517 -0
- package/skills/gcp-data-engineering/medallion-architecture/silver-layer.md +305 -0
- package/skills/gcp-data-engineering/zoho-to-gcp/data-extraction.md +543 -0
- package/skills/gcp-data-engineering/zoho-to-gcp/real-time-vs-batch.md +337 -0
- package/skills/security-review/SKILL.md +498 -0
- package/skills/security-review/compliance-checklist.md +53 -0
- package/skills/strategic-compact/SKILL.md +67 -0
- package/skills/tdd-workflow/SKILL.md +413 -0
- package/skills/tdd-workflow/zoho-testing.md +124 -0
- package/skills/tutorial/SKILL.md +249 -0
- package/skills/tutorial/docs/ACCESSIBILITY.md +169 -0
- package/skills/tutorial/lessons/00-philosophy-and-workflow.md +198 -0
- package/skills/tutorial/lessons/01-basics.md +81 -0
- package/skills/tutorial/lessons/02-training.md +86 -0
- package/skills/tutorial/lessons/03-commands.md +109 -0
- package/skills/tutorial/lessons/04-workflows.md +115 -0
- package/skills/tutorial/lessons/05-compliance.md +116 -0
- package/skills/tutorial/lessons/06-zoho.md +121 -0
- package/skills/tutorial/lessons/07-hooks-system.md +277 -0
- package/skills/tutorial/lessons/08-mcp-servers.md +316 -0
- package/skills/tutorial/lessons/09-client-management.md +215 -0
- package/skills/tutorial/lessons/10-testing-e2e.md +260 -0
- package/skills/tutorial/lessons/11-skills-deep-dive.md +272 -0
- package/skills/tutorial/lessons/12-rules-system.md +326 -0
- package/skills/tutorial/lessons/13-golden-standard-graduation.md +213 -0
- package/skills/tutorial/lessons/14-fork-setup-and-sync.md +312 -0
- package/skills/tutorial/lessons/15-living-examples-system.md +221 -0
- package/skills/tutorial/tracks/accelerated/README.md +134 -0
- package/skills/tutorial/tracks/accelerated/assessment/checkpoint-1.md +161 -0
- package/skills/tutorial/tracks/accelerated/assessment/checkpoint-2.md +175 -0
- package/skills/tutorial/tracks/accelerated/day-1-core-concepts.md +234 -0
- package/skills/tutorial/tracks/accelerated/day-2-essential-commands.md +270 -0
- package/skills/tutorial/tracks/accelerated/day-3-workflow-mastery.md +305 -0
- package/skills/tutorial/tracks/accelerated/day-4-compliance-zoho.md +304 -0
- package/skills/tutorial/tracks/accelerated/day-5-hooks-skills.md +344 -0
- package/skills/tutorial/tracks/accelerated/day-6-client-testing.md +386 -0
- package/skills/tutorial/tracks/accelerated/day-7-graduation.md +369 -0
- package/skills/zoho-patterns/CHANGELOG.md +108 -0
- package/skills/zoho-patterns/SKILL.md +446 -0
- package/skills/zoho-patterns/analytics/dashboard-patterns.md +352 -0
- package/skills/zoho-patterns/analytics/zoho-to-bigquery-pipeline.md +427 -0
- package/skills/zoho-patterns/catalyst/appsail-deployment.md +349 -0
- package/skills/zoho-patterns/catalyst/context-close-patterns.md +354 -0
- package/skills/zoho-patterns/catalyst/cron-batch-processing.md +374 -0
- package/skills/zoho-patterns/catalyst/function-patterns.md +439 -0
- package/skills/zoho-patterns/creator/form-design.md +304 -0
- package/skills/zoho-patterns/creator/publish-api-patterns.md +313 -0
- package/skills/zoho-patterns/creator/widget-integration.md +306 -0
- package/skills/zoho-patterns/creator/workflow-automation.md +253 -0
- package/skills/zoho-patterns/deluge/api-patterns.md +468 -0
- package/skills/zoho-patterns/deluge/batch-processing.md +403 -0
- package/skills/zoho-patterns/deluge/cross-app-integration.md +356 -0
- package/skills/zoho-patterns/deluge/error-handling.md +423 -0
- package/skills/zoho-patterns/deluge/syntax-reference.md +65 -0
- package/skills/zoho-patterns/integration/cors-proxy-architecture.md +426 -0
- package/skills/zoho-patterns/integration/crm-books-native-sync.md +277 -0
- package/skills/zoho-patterns/integration/oauth-token-management.md +461 -0
- package/skills/zoho-patterns/integration/zoho-flow-patterns.md +334 -0
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Tutorial visual rendering module.
|
|
4
|
+
* Provides rich terminal output for the interactive tutorial.
|
|
5
|
+
*
|
|
6
|
+
* Uses chalk, boxen, and figures for cross-platform styled output.
|
|
7
|
+
* Respects NO_COLOR environment variable for accessibility.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// Dynamic imports for ESM modules (chalk, boxen, figures, ora)
|
|
11
|
+
let chalk, boxen, figures, ora;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Initialize ESM modules.
|
|
15
|
+
* Must be called before using any rendering functions.
|
|
16
|
+
*/
|
|
17
|
+
async function init() {
|
|
18
|
+
if (!chalk) {
|
|
19
|
+
chalk = (await import('chalk')).default;
|
|
20
|
+
boxen = (await import('boxen')).default;
|
|
21
|
+
figures = (await import('figures')).default;
|
|
22
|
+
ora = (await import('ora')).default;
|
|
23
|
+
|
|
24
|
+
// Force colors ON by default (Windows terminals often misdetect)
|
|
25
|
+
// User can still disable with NO_COLOR=1 or --no-color
|
|
26
|
+
if (!process.env.NO_COLOR && !process.argv.includes('--no-color')) {
|
|
27
|
+
chalk.level = 3; // Full truecolor support
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Check if colors should be disabled.
|
|
34
|
+
* @returns {boolean} True if colors should be disabled
|
|
35
|
+
*/
|
|
36
|
+
function isAccessible() {
|
|
37
|
+
return (
|
|
38
|
+
process.env.NO_COLOR ||
|
|
39
|
+
process.env.TERM === 'dumb' ||
|
|
40
|
+
process.argv.includes('--no-color') ||
|
|
41
|
+
process.argv.includes('--accessible')
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Get the appropriate checkmark symbol.
|
|
47
|
+
* @returns {string} Checkmark symbol
|
|
48
|
+
*/
|
|
49
|
+
function getCheck() {
|
|
50
|
+
return figures ? figures.tick : '✓';
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Get the appropriate arrow symbol.
|
|
55
|
+
* @returns {string} Arrow symbol
|
|
56
|
+
*/
|
|
57
|
+
function getArrow() {
|
|
58
|
+
return figures ? figures.arrowRight : '→';
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Get the appropriate circle symbol.
|
|
63
|
+
* @returns {string} Circle symbol
|
|
64
|
+
*/
|
|
65
|
+
function getCircle() {
|
|
66
|
+
return figures ? figures.circle : '○';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Render the welcome banner.
|
|
71
|
+
* @returns {string} Formatted banner
|
|
72
|
+
*/
|
|
73
|
+
function renderBanner() {
|
|
74
|
+
const title = 'EVERYTHING CLAUDE CODE TUTORIAL';
|
|
75
|
+
const subtitle = 'Learn the system in 15 interactive lessons';
|
|
76
|
+
|
|
77
|
+
if (isAccessible()) {
|
|
78
|
+
return ['═'.repeat(56), '', ` ${title}`, ` ${subtitle}`, '', '═'.repeat(56)].join('\n');
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const content = [chalk.bold.cyan(title), chalk.dim(subtitle)].join('\n');
|
|
82
|
+
|
|
83
|
+
return boxen(content, {
|
|
84
|
+
padding: 1,
|
|
85
|
+
margin: 0,
|
|
86
|
+
borderStyle: 'double',
|
|
87
|
+
borderColor: 'cyan',
|
|
88
|
+
textAlignment: 'center',
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Render a progress bar.
|
|
94
|
+
* @param {number} completed - Number of completed items
|
|
95
|
+
* @param {number} total - Total number of items
|
|
96
|
+
* @returns {string} Formatted progress bar
|
|
97
|
+
*/
|
|
98
|
+
function renderProgressBar(completed, total) {
|
|
99
|
+
const percent = Math.round((completed / total) * 100);
|
|
100
|
+
const width = 20;
|
|
101
|
+
const filled = Math.round((completed / total) * width);
|
|
102
|
+
const empty = width - filled;
|
|
103
|
+
|
|
104
|
+
const filledChar = '█';
|
|
105
|
+
const emptyChar = '░';
|
|
106
|
+
|
|
107
|
+
const bar = filledChar.repeat(filled) + emptyChar.repeat(empty);
|
|
108
|
+
|
|
109
|
+
if (isAccessible()) {
|
|
110
|
+
return `Progress: [${bar}] ${completed}/${total} lessons (${percent}%)`;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return `Progress: ${chalk.cyan('[')}${chalk.green(filledChar.repeat(filled))}${chalk.dim(emptyChar.repeat(empty))}${chalk.cyan(']')} ${completed}/${total} lessons ${chalk.dim(`(${percent}%)`)}`;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Render the lesson list with status indicators.
|
|
118
|
+
* @param {object} progress - Progress state from tutorial-progress
|
|
119
|
+
* @param {Array} lessons - Array of lesson info objects
|
|
120
|
+
* @returns {string} Formatted lesson list
|
|
121
|
+
*/
|
|
122
|
+
function renderLessonList(progress, lessons) {
|
|
123
|
+
const lines = [];
|
|
124
|
+
|
|
125
|
+
for (const lesson of lessons) {
|
|
126
|
+
const isCompleted = progress.completedLessons.includes(lesson.num);
|
|
127
|
+
const isCurrent = lesson.num === progress.currentLesson;
|
|
128
|
+
|
|
129
|
+
let indicator, style, suffix;
|
|
130
|
+
|
|
131
|
+
if (isCompleted) {
|
|
132
|
+
indicator = getCheck();
|
|
133
|
+
style = isAccessible() ? (s) => s : chalk.green;
|
|
134
|
+
suffix = '';
|
|
135
|
+
} else if (isCurrent) {
|
|
136
|
+
indicator = getArrow();
|
|
137
|
+
style = isAccessible() ? (s) => s : chalk.yellow.bold;
|
|
138
|
+
suffix = isAccessible() ? ' <- YOU ARE HERE' : chalk.dim(' ← YOU ARE HERE');
|
|
139
|
+
} else {
|
|
140
|
+
indicator = getCircle();
|
|
141
|
+
style = isAccessible() ? (s) => s : chalk.dim;
|
|
142
|
+
suffix = '';
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
lines.push(style(` ${indicator} Lesson ${lesson.num}: ${lesson.title}${suffix}`));
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return lines.join('\n');
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Render a lesson header.
|
|
153
|
+
* @param {object} lesson - Lesson info object
|
|
154
|
+
* @returns {string} Formatted lesson header
|
|
155
|
+
*/
|
|
156
|
+
function renderLessonHeader(lesson) {
|
|
157
|
+
const title = `LESSON ${lesson.num}: ${lesson.title.toUpperCase()}`;
|
|
158
|
+
const line = '━'.repeat(56);
|
|
159
|
+
|
|
160
|
+
if (isAccessible()) {
|
|
161
|
+
return [line, '', ` ${title}`, '', line].join('\n');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return [chalk.dim(line), '', chalk.bold.white(` ${title}`), '', chalk.dim(line)].join('\n');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Render a completion badge for a lesson.
|
|
169
|
+
* @param {object} lesson - Lesson info object
|
|
170
|
+
* @param {Array} commandsLearned - Array of command names learned
|
|
171
|
+
* @param {number|null} nextLesson - Next lesson number or null if complete
|
|
172
|
+
* @returns {string} Formatted completion badge
|
|
173
|
+
*/
|
|
174
|
+
function renderCompletionBadge(lesson, commandsLearned, nextLesson) {
|
|
175
|
+
const check = getCheck();
|
|
176
|
+
const lines = [
|
|
177
|
+
` ${check} LESSON ${lesson.num} COMPLETE!`,
|
|
178
|
+
'',
|
|
179
|
+
' Commands learned:',
|
|
180
|
+
` ${commandsLearned.map((c) => `• ${c}`).join(' ')}`,
|
|
181
|
+
'',
|
|
182
|
+
];
|
|
183
|
+
|
|
184
|
+
if (nextLesson) {
|
|
185
|
+
lines.push(' Next:');
|
|
186
|
+
lines.push(` Terminal: node scripts/tutorial-runner.js ${nextLesson}`);
|
|
187
|
+
lines.push(` Claude Code: /tutorial ${nextLesson}`);
|
|
188
|
+
} else {
|
|
189
|
+
lines.push(' Tutorial complete! Get certificate:');
|
|
190
|
+
lines.push(' Terminal: node scripts/tutorial-runner.js certificate');
|
|
191
|
+
lines.push(' Claude Code: /tutorial certificate');
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (isAccessible()) {
|
|
195
|
+
return [
|
|
196
|
+
'┌' + '─'.repeat(58) + '┐',
|
|
197
|
+
...lines.map((l) => '│' + l.padEnd(58) + '│'),
|
|
198
|
+
'└' + '─'.repeat(58) + '┘',
|
|
199
|
+
].join('\n');
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
return boxen(lines.join('\n'), {
|
|
203
|
+
padding: { top: 0, bottom: 0, left: 0, right: 0 },
|
|
204
|
+
margin: 0,
|
|
205
|
+
borderStyle: 'round',
|
|
206
|
+
borderColor: 'green',
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* Render the completion certificate.
|
|
212
|
+
* @param {object} progress - Progress state
|
|
213
|
+
* @param {string} completionId - Unique certificate ID
|
|
214
|
+
* @returns {string} Formatted certificate
|
|
215
|
+
*/
|
|
216
|
+
function renderCertificate(progress, completionId) {
|
|
217
|
+
const completedDate = progress.completedAt
|
|
218
|
+
? new Date(progress.completedAt).toLocaleDateString('en-US', {
|
|
219
|
+
year: 'numeric',
|
|
220
|
+
month: 'long',
|
|
221
|
+
day: 'numeric',
|
|
222
|
+
})
|
|
223
|
+
: new Date().toLocaleDateString('en-US', {
|
|
224
|
+
year: 'numeric',
|
|
225
|
+
month: 'long',
|
|
226
|
+
day: 'numeric',
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
const content = [
|
|
230
|
+
'',
|
|
231
|
+
' CERTIFICATE OF COMPLETION',
|
|
232
|
+
'',
|
|
233
|
+
' This certifies completion of the',
|
|
234
|
+
' Everything Claude Code Tutorial',
|
|
235
|
+
'',
|
|
236
|
+
' 15/15 Lessons • 22 Commands • 13 Agents',
|
|
237
|
+
'',
|
|
238
|
+
` Completed: ${completedDate}`,
|
|
239
|
+
` ID: ${completionId}`,
|
|
240
|
+
'',
|
|
241
|
+
].join('\n');
|
|
242
|
+
|
|
243
|
+
if (isAccessible()) {
|
|
244
|
+
const width = 58;
|
|
245
|
+
return [
|
|
246
|
+
'╔' + '═'.repeat(width) + '╗',
|
|
247
|
+
...content.split('\n').map((l) => '║' + l.padEnd(width) + '║'),
|
|
248
|
+
'╚' + '═'.repeat(width) + '╝',
|
|
249
|
+
].join('\n');
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return boxen(content, {
|
|
253
|
+
padding: 1,
|
|
254
|
+
margin: 0,
|
|
255
|
+
borderStyle: 'double',
|
|
256
|
+
borderColor: 'yellow',
|
|
257
|
+
textAlignment: 'center',
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Render a session resume prompt.
|
|
263
|
+
* @param {object} progress - Progress state
|
|
264
|
+
* @returns {string} Formatted resume prompt
|
|
265
|
+
*/
|
|
266
|
+
function renderResumePrompt(progress) {
|
|
267
|
+
const lastAccessed = new Date(progress.lastAccessed).toLocaleDateString();
|
|
268
|
+
|
|
269
|
+
const lines = [
|
|
270
|
+
'Tutorial in progress!',
|
|
271
|
+
'',
|
|
272
|
+
renderProgressBar(progress.completedLessons.length, 15),
|
|
273
|
+
'',
|
|
274
|
+
`Last accessed: ${lastAccessed}`,
|
|
275
|
+
'Resume:',
|
|
276
|
+
` Terminal: node scripts/tutorial-runner.js ${progress.currentLesson}`,
|
|
277
|
+
` Claude Code: /tutorial ${progress.currentLesson}`,
|
|
278
|
+
];
|
|
279
|
+
|
|
280
|
+
if (isAccessible()) {
|
|
281
|
+
return lines.join('\n');
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
return boxen(lines.join('\n'), {
|
|
285
|
+
padding: 1,
|
|
286
|
+
margin: 0,
|
|
287
|
+
borderStyle: 'round',
|
|
288
|
+
borderColor: 'blue',
|
|
289
|
+
title: 'Tutorial Progress',
|
|
290
|
+
titleAlignment: 'center',
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Render lesson content with markdown styling.
|
|
296
|
+
* @param {string} content - Raw markdown content
|
|
297
|
+
* @returns {string} Styled content
|
|
298
|
+
*/
|
|
299
|
+
function renderLessonContent(content) {
|
|
300
|
+
if (isAccessible()) {
|
|
301
|
+
return content;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
const lines = content.split('\n');
|
|
305
|
+
const styledLines = [];
|
|
306
|
+
let inCodeBlock = false;
|
|
307
|
+
|
|
308
|
+
for (const line of lines) {
|
|
309
|
+
// Code block toggle
|
|
310
|
+
if (line.startsWith('```')) {
|
|
311
|
+
inCodeBlock = !inCodeBlock;
|
|
312
|
+
styledLines.push(chalk.dim(line));
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
// Inside code block - dim styling
|
|
317
|
+
if (inCodeBlock) {
|
|
318
|
+
styledLines.push(chalk.dim.cyan(line));
|
|
319
|
+
continue;
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// H1 headers
|
|
323
|
+
if (line.startsWith('# ')) {
|
|
324
|
+
styledLines.push(chalk.bold.cyan(line));
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
// H2 headers
|
|
329
|
+
if (line.startsWith('## ')) {
|
|
330
|
+
styledLines.push(chalk.bold.yellow(line));
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// H3 headers
|
|
335
|
+
if (line.startsWith('### ')) {
|
|
336
|
+
styledLines.push(chalk.bold.white(line));
|
|
337
|
+
continue;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// Blockquotes
|
|
341
|
+
if (line.startsWith('> ')) {
|
|
342
|
+
styledLines.push(chalk.italic.green(line));
|
|
343
|
+
continue;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// List items
|
|
347
|
+
if (line.match(/^[-*] /)) {
|
|
348
|
+
const styled = line
|
|
349
|
+
.replace(/^([-*]) /, chalk.cyan('• '))
|
|
350
|
+
.replace(/\*\*([^*]+)\*\*/g, (_, text) => chalk.bold(text))
|
|
351
|
+
.replace(/`([^`]+)`/g, (_, code) => chalk.cyan(code));
|
|
352
|
+
styledLines.push(styled);
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Table rows
|
|
357
|
+
if (line.startsWith('|')) {
|
|
358
|
+
styledLines.push(chalk.dim(line));
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Regular text - style inline elements
|
|
363
|
+
let styled = line
|
|
364
|
+
.replace(/\*\*([^*]+)\*\*/g, (_, text) => chalk.bold(text))
|
|
365
|
+
.replace(/`([^`]+)`/g, (_, code) => chalk.cyan(code));
|
|
366
|
+
styledLines.push(styled);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
return styledLines.join('\n');
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Render an error message.
|
|
374
|
+
* @param {string} message - Error message
|
|
375
|
+
* @returns {string} Formatted error
|
|
376
|
+
*/
|
|
377
|
+
function renderError(message) {
|
|
378
|
+
if (isAccessible()) {
|
|
379
|
+
return `ERROR: ${message}`;
|
|
380
|
+
}
|
|
381
|
+
return chalk.red(`${figures.cross} ${message}`);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* Render a success message.
|
|
386
|
+
* @param {string} message - Success message
|
|
387
|
+
* @returns {string} Formatted success
|
|
388
|
+
*/
|
|
389
|
+
function renderSuccess(message) {
|
|
390
|
+
if (isAccessible()) {
|
|
391
|
+
return `SUCCESS: ${message}`;
|
|
392
|
+
}
|
|
393
|
+
return chalk.green(`${figures.tick} ${message}`);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Render a spinner (returns ora instance).
|
|
398
|
+
* @param {string} text - Spinner text
|
|
399
|
+
* @returns {object} Ora spinner instance
|
|
400
|
+
*/
|
|
401
|
+
function createSpinner(text) {
|
|
402
|
+
if (isAccessible()) {
|
|
403
|
+
// In accessible mode, just log the text
|
|
404
|
+
console.log(text);
|
|
405
|
+
return {
|
|
406
|
+
succeed: (msg) => console.log(`SUCCESS: ${msg || text}`),
|
|
407
|
+
fail: (msg) => console.log(`FAILED: ${msg || text}`),
|
|
408
|
+
stop: () => {},
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
return ora({ text, color: 'cyan' }).start();
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
module.exports = {
|
|
415
|
+
init,
|
|
416
|
+
isAccessible,
|
|
417
|
+
renderBanner,
|
|
418
|
+
renderProgressBar,
|
|
419
|
+
renderLessonList,
|
|
420
|
+
renderLessonHeader,
|
|
421
|
+
renderLessonContent,
|
|
422
|
+
renderCompletionBadge,
|
|
423
|
+
renderCertificate,
|
|
424
|
+
renderResumePrompt,
|
|
425
|
+
renderError,
|
|
426
|
+
renderSuccess,
|
|
427
|
+
createSpinner,
|
|
428
|
+
getCheck,
|
|
429
|
+
getArrow,
|
|
430
|
+
getCircle,
|
|
431
|
+
};
|