create-sl-ide 0.1.0 → 0.1.1

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 (3) hide show
  1. package/README.md +2 -0
  2. package/index.mjs +45 -7
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -5,6 +5,7 @@ the IDE for building slides with Claude Code or Codex.
5
5
 
6
6
  ```sh
7
7
  pnpm create sl-ide my-deck
8
+ pnpm create sl-ide my-memo --memo # a memo on US Letter pages instead of slides
8
9
  # or: npm create sl-ide@latest my-deck · bun create sl-ide my-deck
9
10
  ```
10
11
 
@@ -27,6 +28,7 @@ Then `cd my-deck && pnpm dev`, open Claude Code or Codex there, and run
27
28
  ## Options
28
29
 
29
30
  ```
31
+ --format <slides|memo> 16:9 slides, or a US Letter memo (default slides; --memo for short)
30
32
  --dir <path> folder for the deck (default ./<name>)
31
33
  --github <private|public|none> the deck's repo (default private)
32
34
  --team <slug> the sl-ide cloud team that owns the deck
package/index.mjs CHANGED
@@ -7,6 +7,7 @@
7
7
  // cloud, and installs dependencies. The editor itself is never bundled here,
8
8
  // so a new deck always starts from the template's main.
9
9
  //
10
+ // pnpm create sl-ide . start the deck in this (empty) folder, named after it
10
11
  // pnpm create sl-ide login sign in to sl-ide cloud and save a team token
11
12
  // pnpm create sl-ide logout forget saved tokens
12
13
  import fs from 'node:fs';
@@ -21,10 +22,13 @@ const SLUG_RE = /^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$/;
21
22
 
22
23
  const HELP = `
23
24
  pnpm create sl-ide [name] [options]
25
+ pnpm create sl-ide . [options] in this empty folder, named after it
24
26
 
25
- Start a new deck from the latest sl-ide template.
27
+ Start a new deck (or memo) from the latest sl-ide template.
26
28
 
27
29
  Options
30
+ --format <slides|memo> 16:9 slides, or a memo on US Letter pages (default: slides)
31
+ --memo short for --format memo
28
32
  --dir <path> folder to create the deck in (default: ./<name>)
29
33
  --github <private|public|none> the deck's GitHub repo (default: private)
30
34
  --team <slug> the sl-ide cloud team that owns the deck
@@ -45,6 +49,8 @@ const HELP = `
45
49
  const { values: o, positionals } = parseArgs({
46
50
  allowPositionals: true,
47
51
  options: {
52
+ format: { type: 'string' },
53
+ memo: { type: 'boolean' },
48
54
  dir: { type: 'string' },
49
55
  github: { type: 'string' },
50
56
  team: { type: 'string' },
@@ -62,6 +68,7 @@ const { values: o, positionals } = parseArgs({
62
68
  if (o['no-publish']) o.publish = false;
63
69
  if (o['no-install']) o.install = false;
64
70
  if (o['no-open']) o.open = false;
71
+ if (o.memo) o.format = 'memo';
65
72
  if (o.help) { console.log(HELP); process.exit(0); }
66
73
 
67
74
  const interactive = process.stdin.isTTY && !o.yes;
@@ -141,7 +148,9 @@ function logout() {
141
148
  async function create() {
142
149
  p.intro('sl-ide · new deck');
143
150
 
144
- let name = positionals[0];
151
+ // `.` builds the deck in the current folder and names it after the folder.
152
+ const here = positionals[0] === '.';
153
+ let name = here ? path.basename(process.cwd()) : positionals[0];
145
154
  if (!name) {
146
155
  if (!interactive) bail('Give the deck a name: pnpm create sl-ide my-deck');
147
156
  name = await ask(p.text({
@@ -154,8 +163,27 @@ async function create() {
154
163
  const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
155
164
  if (!SLUG_RE.test(slug)) bail(`can't make a link name from "${name}"`);
156
165
 
157
- const dest = path.resolve(o.dir ?? name);
158
- if (fs.existsSync(dest) && fs.readdirSync(dest).length) bail(`${dest} already exists and isn't empty`);
166
+ // Slides or a memo. A memo is the same template with the memo starter
167
+ // swapped in by its own script (scripts/use-format.mjs).
168
+ let format = o.format;
169
+ if (!format) {
170
+ format = interactive ? await ask(p.select({
171
+ message: 'What are you making?',
172
+ options: [
173
+ { value: 'slides', label: 'Slides', hint: '16:9 pages' },
174
+ { value: 'memo', label: 'A memo', hint: 'US Letter pages, text flows from page to page' },
175
+ ],
176
+ })) : 'slides';
177
+ }
178
+ if (!['slides', 'memo'].includes(format)) bail('--format is slides or memo');
179
+
180
+ const dest = path.resolve(o.dir ?? (here ? '.' : name));
181
+ if (fs.existsSync(dest)) {
182
+ // Finder leaves .DS_Store in folders it opens; it would stop git clone.
183
+ const left = fs.readdirSync(dest).filter((f) => f !== '.DS_Store');
184
+ if (left.length) bail(`${dest} already exists and isn't empty`);
185
+ fs.rmSync(path.join(dest, '.DS_Store'), { force: true });
186
+ }
159
187
 
160
188
  for (const tool of ['git', 'pnpm']) {
161
189
  if (!has(tool)) bail(tool === 'pnpm' ? 'pnpm is needed: corepack enable pnpm' : 'git is needed');
@@ -221,6 +249,16 @@ async function create() {
221
249
  const head = await run('git', ['log', '-1', '--format=%h %s'], { cwd: dest });
222
250
  s.stop(`Cloned sl-ide (${head.split(' ')[0]})`);
223
251
 
252
+ if (format !== 'slides') {
253
+ if (!fs.existsSync(path.join(dest, 'scripts', 'use-format.mjs'))) {
254
+ throw new Error(`this sl-ide template has no ${format} format yet`);
255
+ }
256
+ await run('node', ['scripts/use-format.mjs', format], { cwd: dest });
257
+ await run('git', ['add', '-A'], { cwd: dest });
258
+ await run('git', ['-c', 'core.hooksPath=/dev/null', 'commit', '-q', '-m', `Start from the ${format} starter`], { cwd: dest });
259
+ p.log.success(`Set up as a ${format}`);
260
+ }
261
+
224
262
  if (pub) {
225
263
  const config = { slug, team: pub.team, visibility: share };
226
264
  fs.writeFileSync(path.join(dest, 'sl-ide.config.json'), `${JSON.stringify(config, null, 2)}\n`);
@@ -249,12 +287,12 @@ async function create() {
249
287
 
250
288
  const rel = path.relative(process.cwd(), dest) || '.';
251
289
  const lines = [
252
- `cd ${rel}`,
290
+ ...(rel === '.' ? [] : [`cd ${rel}`]),
253
291
  ...(o.install ? [] : ['pnpm install']),
254
292
  'pnpm dev',
255
293
  '',
256
294
  'Then open Claude Code or Codex in that folder and run /new-deck',
257
- '(Codex: $new-deck) to learn your style and outline the story.',
295
+ `(Codex: $new-deck) to learn your style and outline the ${format === 'memo' ? 'memo' : 'story'}.`,
258
296
  ];
259
297
  p.note(lines.join('\n'), 'Next');
260
298
  if (pub) {
@@ -262,7 +300,7 @@ async function create() {
262
300
  } else {
263
301
  p.log.info('Not publishing. To publish later, add sl-ide.config.json (see the deck\'s README).');
264
302
  }
265
- p.outro('Deck ready.');
303
+ p.outro(format === 'memo' ? 'Memo ready.' : 'Deck ready.');
266
304
  }
267
305
 
268
306
  const cmd = positionals[0];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-sl-ide",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Start a slide deck with sl-ide: pnpm create sl-ide",
5
5
  "type": "module",
6
6
  "bin": {