coursecast 0.2.2 → 0.2.3

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.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  // coursecast — one prompt → a whole interactive course → deployed live.
3
3
 
4
- import { createCourse, deployDir } from '../src/index.mjs';
4
+ import { createCourse, deployDir, detectProvider } from '../src/index.mjs';
5
5
 
6
6
  const argv = process.argv.slice(2);
7
7
 
@@ -27,7 +27,7 @@ OPTIONS
27
27
  --engine <id> generation engine: claude-code (default), gemini, codex, stub
28
28
  --model <id> model hint passed to the engine (e.g. gemini-3.5-flash)
29
29
  --storage <id> progress storage: local (default, no setup), cloud (sync across devices)
30
- --provider <id> deploy target: vercel (default), netlify
30
+ --provider <id> deploy target: vercel | netlify (auto-detects what you have installed)
31
31
  --lessons <n> target number of lessons (default ~12)
32
32
  --concurrency <n> how many lessons to generate at once (default 4)
33
33
  --deploy deploy after generating (otherwise generate only)
@@ -57,7 +57,7 @@ async function main() {
57
57
  }
58
58
 
59
59
  const engine = getFlag('engine', 'claude-code');
60
- const provider = getFlag('provider', 'vercel');
60
+ const providerFlag = getFlag('provider', undefined);
61
61
  const model = getFlag('model', undefined);
62
62
  const storage = getFlag('storage', 'local');
63
63
  const out = getFlag('out', undefined);
@@ -70,6 +70,8 @@ async function main() {
70
70
  log(`✅ Course ready: ${res.lessons.length} lessons${res.failed.length ? ` (${res.failed.length} failed: ${res.failed.join(', ')})` : ''}`);
71
71
 
72
72
  if (has('deploy')) {
73
+ const provider = providerFlag || await detectProvider();
74
+ if (!providerFlag) log(`🔎 Provider: ${provider} (auto-detected — use --provider to override)`);
73
75
  const dep = await deployDir({
74
76
  dir, provider, prod: !has('preview'), dryRun: has('dry-run'), log,
75
77
  });
@@ -77,7 +79,7 @@ async function main() {
77
79
  else log(`\n🎉 Live at: ${dep.url}`);
78
80
  } else {
79
81
  log(`\nPreview locally: npx serve "${dir}" (or open ${dir}/index.html)`);
80
- log(`Deploy: coursecast "${topic}" --deploy --provider ${provider}`);
82
+ log(`Deploy: coursecast "${topic}" --deploy`);
81
83
  }
82
84
  } catch (e) {
83
85
  log(`\n❌ ${e.message}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "coursecast",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "One prompt → a full interactive course — live widgets, quizzes, a mastery dashboard — rendered to self-contained HTML and deployed live.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/index.mjs CHANGED
@@ -19,6 +19,22 @@ async function loadEngine(id) {
19
19
  try { return await import(`./engines/${id}.mjs`); }
20
20
  catch { throw new Error(`Unknown engine "${id}". Available: claude-code, gemini, codex, stub.`); }
21
21
  }
22
+ // Pick a deploy provider by what's actually installed: vercel first, then netlify.
23
+ // Auto-detection beats a silent default (which pretended netlify didn't exist) and
24
+ // beats prompting (which would break CI/scripted use).
25
+ export async function detectProvider() {
26
+ for (const id of ['vercel', 'netlify']) {
27
+ const p = await loadProvider(id);
28
+ if (p.isAvailable()) return id;
29
+ }
30
+ throw new Error(
31
+ 'No deploy CLI found. Install one and log in:\n' +
32
+ ' vercel: npm i -g vercel && vercel login\n' +
33
+ ' netlify: npm i -g netlify-cli && netlify login\n' +
34
+ '…or skip --deploy and host the folder anywhere that serves static files.'
35
+ );
36
+ }
37
+
22
38
  async function loadProvider(id) {
23
39
  try { return await import(`./providers/${id}.mjs`); }
24
40
  catch { throw new Error(`Unknown provider "${id}". Available: vercel, netlify.`); }