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.
- package/README.md +2 -0
- package/index.mjs +45 -7
- 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
|
-
|
|
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
|
-
|
|
158
|
-
|
|
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
|
-
|
|
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];
|