@useguano/create 0.1.5 → 0.1.7

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 (2) hide show
  1. package/index.js +36 -14
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  // @useguano/create: scaffold a project dir that runs Guano via npm scripts,
3
- // install it, and connect Claude Desktop — all in this one command, so what
3
+ // install it, and connect Claude — all in this one command, so what
4
4
  // is left afterwards is `cd my-site && npm run dev`. Zero dependencies —
5
5
  // prompts with node:readline.
6
6
  //
@@ -9,7 +9,8 @@
9
9
  //
10
10
  // The MCP connect runs through the just-installed package's own
11
11
  // `guano connect --offline`: it mints a PENDING API token into <dir>/data,
12
- // writes the two agent permissions there, and writes Claude Desktop's config.
12
+ // writes the two agent permissions there, and writes the config of every
13
+ // Claude client on the machine (Claude Code and Claude Desktop).
13
14
  // The server binds the token to the first admin at /admin setup, and the
14
15
  // setup form shows the permissions instead of asking them again.
15
16
  import { spawnSync } from 'node:child_process'
@@ -43,7 +44,7 @@ if (!dir) {
43
44
  dir = rl ? (await ask(`Project folder (${DEFAULT_DIR}): `)).trim() || DEFAULT_DIR : DEFAULT_DIR
44
45
  }
45
46
 
46
- // Connect Claude Desktop? Flags decide non-interactively (CI never asks and
47
+ // Connect Claude? Flags decide non-interactively (CI never asks and
47
48
  // never connects); a terminal asks, default yes.
48
49
  let connect = false
49
50
  let policyFlags = []
@@ -52,7 +53,7 @@ if (flag('--no-connect')) {
52
53
  } else if (flag('--connect') || flag('--main') || flag('--publish')) {
53
54
  connect = true
54
55
  } else if (rl) {
55
- connect = await yes('Connect Claude Desktop to this site over MCP?', true)
56
+ connect = await yes('Connect Claude (Code and Desktop) to this site over MCP?', true)
56
57
  }
57
58
  if (connect) {
58
59
  if (flag('--main')) policyFlags.push('--main')
@@ -74,6 +75,20 @@ const name =
74
75
  .replace(/[^a-z0-9-]+/g, '-')
75
76
  .replace(/^-+|-+$/g, '') || DEFAULT_DIR
76
77
 
78
+ /**
79
+ * The same thing, as a NAME rather than a package slug.
80
+ *
81
+ * `acme-landing` is what npm needs and what the folder is called; "Acme
82
+ * Landing" is what belongs in a field labelled Project name. The setup screen
83
+ * prefills it and the human can change it there — this is a head start, not a
84
+ * decision.
85
+ */
86
+ const displayName = name
87
+ .split('-')
88
+ .filter(Boolean)
89
+ .map((w) => w[0].toUpperCase() + w.slice(1))
90
+ .join(' ')
91
+
77
92
  await mkdir(target, { recursive: true })
78
93
  if ((await readdir(target)).length) {
79
94
  rl?.close()
@@ -95,9 +110,10 @@ if ((await readdir(target)).length) {
95
110
  * 4174 is still preferred, so a first project looks exactly as documented.
96
111
  */
97
112
  async function pickPort(first = 4174, tries = 40) {
98
- // A site needs its own port AND the preview port above it, so step by two.
99
- for (let port = first; port < first + tries * 2; port += 2) {
100
- if ((await free(port)) && (await free(port + 1))) return port
113
+ // One port per site: the preview is served by the same server under
114
+ // /_guano/preview, so there is no second port to keep free above it.
115
+ for (let port = first; port < first + tries; port += 1) {
116
+ if (await free(port)) return port
101
117
  }
102
118
  return first
103
119
  }
@@ -147,6 +163,12 @@ export default {}
147
163
  # must not share one, or whichever starts first answers for both and the
148
164
  # other's MCP token is refused with a 401.
149
165
  PORT=${port}
166
+
167
+ # What you called this project in the terminal. It prefills the Project name
168
+ # on the setup screen, so nobody is asked to name the same thing twice. Only
169
+ # read before the first admin account exists; edit the name in the editor
170
+ # after that.
171
+ GUANO_PROJECT_NAME=${displayName}
150
172
  `,
151
173
 
152
174
  '.env.example': `PORT=${port}
@@ -176,14 +198,14 @@ site. Your published site is served at http://localhost:${port}/.
176
198
  This project runs on port ${port} (set in \`.env\`). Each Guano site on a
177
199
  machine needs its own, so two of them never answer for one address.
178
200
 
179
- If you said yes to Claude Desktop when scaffolding, it is already connected:
201
+ If you said yes to Claude when scaffolding, it is already connected:
180
202
  the agent token is bound to the admin account you create, and the permissions
181
203
  you chose (edit the live project, publish) show on the setup form and stay
182
204
  editable in Settings → MCP → Agent permissions.
183
205
 
184
206
  - \`npm run start\` — production server (\`NODE_ENV=production\`)
185
207
  - \`npm run build\` — export the site as static files to \`./dist-site\`
186
- - \`npm run connect\` — connect Claude Desktop later, or from another machine (quit Claude first; \`--main\` / \`--publish\` grant the agent permissions, or it asks)
208
+ - \`npm run connect\` — connect Claude later, or from another machine (writes Claude Code's \`~/.claude.json\` and Claude Desktop's config; quit Desktop first; \`--main\` / \`--publish\` grant the agent permissions, or it asks)
187
209
  - everything lives in \`./data\` — **backing up = copying that directory**
188
210
 
189
211
  See the @useguano/guano package README for deploy notes and environment variables.
@@ -205,7 +227,7 @@ if (install) {
205
227
  if (!installed) console.error('\nnpm install failed — run it yourself in the project folder.')
206
228
  }
207
229
 
208
- // ---- connect Claude Desktop, through the installed package ----
230
+ // ---- connect Claude, through the installed package ----
209
231
  // GUANO_CREATE_LOCAL_PKG is a dev-only escape hatch: with --no-install there
210
232
  // is no node_modules, so a repo checkout names its own packages/guano here.
211
233
  let connected = false
@@ -214,7 +236,7 @@ if (connect) {
214
236
  ? join(target, 'node_modules', '@useguano', 'guano')
215
237
  : process.env.GUANO_CREATE_LOCAL_PKG
216
238
  if (!pkgDir) {
217
- console.error('\nClaude Desktop not connected: guano is not installed yet — run `npm run connect` inside the project later.')
239
+ console.error('\nClaude not connected: guano is not installed yet — run `npm run connect` inside the project later.')
218
240
  } else {
219
241
  try {
220
242
  // the package resolves its data dir from this env at import time
@@ -224,7 +246,7 @@ if (connect) {
224
246
  const { main } = await import(pathToFileURL(join(pkgDir, 'mcp', 'connect.mjs')).href)
225
247
  const connectArgs = [...policyFlags, '--offline', '--yes']
226
248
  if (opt('--config')) connectArgs.push('--config', resolve(opt('--config')))
227
- console.log('\nConnecting Claude Desktop…')
249
+ console.log('\nConnecting Claude…')
228
250
  await main(connectArgs, {
229
251
  whenClaudeRunning: async () => {
230
252
  if (!rl) return 'skip'
@@ -236,7 +258,7 @@ if (connect) {
236
258
  })
237
259
  connected = true
238
260
  } catch (e) {
239
- console.error(`\n✗ ${e?.message ?? e}\n Claude Desktop not connected — run \`npm run connect\` inside the project later.`)
261
+ console.error(`\n✗ ${e?.message ?? e}\n Claude not connected — run \`npm run connect\` inside the project later.`)
240
262
  }
241
263
  }
242
264
  }
@@ -246,4 +268,4 @@ console.log(`
246
268
  Next:
247
269
  cd ${dir}${installed || !install ? '' : '\n npm install'}
248
270
  npm run dev → http://localhost:4174/admin (create your admin account)
249
- ${connected ? '\nThen open Claude Desktop — guano is connected; the agent token is bound to the admin you create.\n' : ''}`)
271
+ ${connected ? '\nThen open Claude — guano is connected; the agent token is bound to the admin you create.\n' : ''}`)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@useguano/create",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "license": "AGPL-3.0-only",
5
5
  "publishConfig": {
6
6
  "access": "public"