create-sl-ide 0.1.0 → 0.1.2
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 +5 -1
- package/index.mjs +56 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,10 +5,13 @@ 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
|
|
9
|
+
pnpm create sl-ide . # in the current (empty) folder, named after it
|
|
8
10
|
# or: npm create sl-ide@latest my-deck · bun create sl-ide my-deck
|
|
9
11
|
```
|
|
10
12
|
|
|
11
|
-
It asks a few questions
|
|
13
|
+
It asks a few questions (slides or a memo; with no name in an empty
|
|
14
|
+
folder, whether to build right there; the repo; publishing), then:
|
|
12
15
|
|
|
13
16
|
1. Clones the **latest** sl-ide template from GitHub, keeping its history as
|
|
14
17
|
the `upstream` remote, so `git pull upstream main` brings later editor
|
|
@@ -27,6 +30,7 @@ Then `cd my-deck && pnpm dev`, open Claude Code or Codex there, and run
|
|
|
27
30
|
## Options
|
|
28
31
|
|
|
29
32
|
```
|
|
33
|
+
--format <slides|memo> 16:9 slides, or a US Letter memo (default slides; --memo for short)
|
|
30
34
|
--dir <path> folder for the deck (default ./<name>)
|
|
31
35
|
--github <private|public|none> the deck's repo (default private)
|
|
32
36
|
--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,20 @@ 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
|
+
// Asked too, when no name is given and this folder is empty.
|
|
153
|
+
const cwdEmpty = fs.readdirSync(process.cwd()).every((f) => f === '.DS_Store');
|
|
154
|
+
let here = positionals[0] === '.';
|
|
155
|
+
if (!positionals[0] && !o.dir && interactive && cwdEmpty) {
|
|
156
|
+
here = await ask(p.select({
|
|
157
|
+
message: 'Where should it go?',
|
|
158
|
+
options: [
|
|
159
|
+
{ value: true, label: 'This folder', hint: path.basename(process.cwd()) },
|
|
160
|
+
{ value: false, label: 'A new folder inside this one' },
|
|
161
|
+
],
|
|
162
|
+
}));
|
|
163
|
+
}
|
|
164
|
+
let name = here ? path.basename(process.cwd()) : positionals[0];
|
|
145
165
|
if (!name) {
|
|
146
166
|
if (!interactive) bail('Give the deck a name: pnpm create sl-ide my-deck');
|
|
147
167
|
name = await ask(p.text({
|
|
@@ -154,8 +174,27 @@ async function create() {
|
|
|
154
174
|
const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
|
|
155
175
|
if (!SLUG_RE.test(slug)) bail(`can't make a link name from "${name}"`);
|
|
156
176
|
|
|
157
|
-
|
|
158
|
-
|
|
177
|
+
// Slides or a memo. A memo is the same template with the memo starter
|
|
178
|
+
// swapped in by its own script (scripts/use-format.mjs).
|
|
179
|
+
let format = o.format;
|
|
180
|
+
if (!format) {
|
|
181
|
+
format = interactive ? await ask(p.select({
|
|
182
|
+
message: 'What are you making?',
|
|
183
|
+
options: [
|
|
184
|
+
{ value: 'slides', label: 'Slides', hint: '16:9 pages' },
|
|
185
|
+
{ value: 'memo', label: 'A memo', hint: 'US Letter pages, text flows from page to page' },
|
|
186
|
+
],
|
|
187
|
+
})) : 'slides';
|
|
188
|
+
}
|
|
189
|
+
if (!['slides', 'memo'].includes(format)) bail('--format is slides or memo');
|
|
190
|
+
|
|
191
|
+
const dest = path.resolve(o.dir ?? (here ? '.' : name));
|
|
192
|
+
if (fs.existsSync(dest)) {
|
|
193
|
+
// Finder leaves .DS_Store in folders it opens; it would stop git clone.
|
|
194
|
+
const left = fs.readdirSync(dest).filter((f) => f !== '.DS_Store');
|
|
195
|
+
if (left.length) bail(`${dest} already exists and isn't empty`);
|
|
196
|
+
fs.rmSync(path.join(dest, '.DS_Store'), { force: true });
|
|
197
|
+
}
|
|
159
198
|
|
|
160
199
|
for (const tool of ['git', 'pnpm']) {
|
|
161
200
|
if (!has(tool)) bail(tool === 'pnpm' ? 'pnpm is needed: corepack enable pnpm' : 'git is needed');
|
|
@@ -221,6 +260,16 @@ async function create() {
|
|
|
221
260
|
const head = await run('git', ['log', '-1', '--format=%h %s'], { cwd: dest });
|
|
222
261
|
s.stop(`Cloned sl-ide (${head.split(' ')[0]})`);
|
|
223
262
|
|
|
263
|
+
if (format !== 'slides') {
|
|
264
|
+
if (!fs.existsSync(path.join(dest, 'scripts', 'use-format.mjs'))) {
|
|
265
|
+
throw new Error(`this sl-ide template has no ${format} format yet`);
|
|
266
|
+
}
|
|
267
|
+
await run('node', ['scripts/use-format.mjs', format], { cwd: dest });
|
|
268
|
+
await run('git', ['add', '-A'], { cwd: dest });
|
|
269
|
+
await run('git', ['-c', 'core.hooksPath=/dev/null', 'commit', '-q', '-m', `Start from the ${format} starter`], { cwd: dest });
|
|
270
|
+
p.log.success(`Set up as a ${format}`);
|
|
271
|
+
}
|
|
272
|
+
|
|
224
273
|
if (pub) {
|
|
225
274
|
const config = { slug, team: pub.team, visibility: share };
|
|
226
275
|
fs.writeFileSync(path.join(dest, 'sl-ide.config.json'), `${JSON.stringify(config, null, 2)}\n`);
|
|
@@ -249,12 +298,12 @@ async function create() {
|
|
|
249
298
|
|
|
250
299
|
const rel = path.relative(process.cwd(), dest) || '.';
|
|
251
300
|
const lines = [
|
|
252
|
-
`cd ${rel}
|
|
301
|
+
...(rel === '.' ? [] : [`cd ${rel}`]),
|
|
253
302
|
...(o.install ? [] : ['pnpm install']),
|
|
254
303
|
'pnpm dev',
|
|
255
304
|
'',
|
|
256
305
|
'Then open Claude Code or Codex in that folder and run /new-deck',
|
|
257
|
-
|
|
306
|
+
`(Codex: $new-deck) to learn your style and outline the ${format === 'memo' ? 'memo' : 'story'}.`,
|
|
258
307
|
];
|
|
259
308
|
p.note(lines.join('\n'), 'Next');
|
|
260
309
|
if (pub) {
|
|
@@ -262,7 +311,7 @@ async function create() {
|
|
|
262
311
|
} else {
|
|
263
312
|
p.log.info('Not publishing. To publish later, add sl-ide.config.json (see the deck\'s README).');
|
|
264
313
|
}
|
|
265
|
-
p.outro('Deck ready.');
|
|
314
|
+
p.outro(format === 'memo' ? 'Memo ready.' : 'Deck ready.');
|
|
266
315
|
}
|
|
267
316
|
|
|
268
317
|
const cmd = positionals[0];
|