create-kedge 0.11.0 → 0.11.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 CHANGED
@@ -10,9 +10,9 @@ npm create kedge@latest
10
10
  ```
11
11
 
12
12
  Run it in an empty folder, or name a new one: `npm create kedge@latest my-store`.
13
- The store's name comes from the folder (`--name` chooses another). It needs Node 24
14
- or newer and pnpm 10 or newer (`npm install --global pnpm`), and checks both
15
- before it writes anything.
13
+ The store's name comes from the folder (`--name` chooses another; `--help` lists
14
+ the options and writes nothing). It needs Node 24 or newer and pnpm 10 or newer
15
+ (`npm install --global pnpm`), and checks both before it writes anything.
16
16
 
17
17
  ## With a coding agent
18
18
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-kedge",
3
- "version": "0.11.0",
3
+ "version": "0.11.2",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
package/src/create.mjs CHANGED
@@ -4,7 +4,7 @@
4
4
  // some dot files in a tarball, and a store needs its `.gitignore` and `.claude/`.
5
5
  import { spawnSync } from "node:child_process";
6
6
  import { randomBytes } from "node:crypto";
7
- import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
7
+ import { existsSync, mkdirSync, readdirSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
8
8
  import { basename, dirname, isAbsolute, join, resolve } from "node:path";
9
9
 
10
10
  /**
@@ -141,18 +141,68 @@ export function environmentProblem({ node, pnpm, install }) {
141
141
  return null;
142
142
  }
143
143
 
144
- const USAGE = `usage: create-kedge <directory> [--name <name>] [--from-packs <dir>] [--no-install] [--no-git]`;
144
+ const USAGE = `usage: create-kedge [<directory>] [--name <name>] [--from-packs <dir>] [--no-install] [--no-git]`;
145
+
146
+ const HELP = `${USAGE}
147
+
148
+ A new Kedge store from the starter, in <directory>, or in the empty folder it's run
149
+ in (one holding only its own dot-files, such as .git). Its name comes from the folder
150
+ unless --name gives one. Then pnpm install, kedge generate, and git init unless it's
151
+ inside a repository already, which the store joins.
152
+
153
+ --name <name> the store's name, for its Worker, databases and queue: 2 to 40
154
+ lowercase letters, digits and dashes, starting with a letter
155
+ --from-packs <dir> install the @kedge packages from local packs, not npm
156
+ --no-install write the files only
157
+ --no-git no git init
158
+ --help, -h this, writing nothing
159
+
160
+ Next: pnpm kedge check in the store; its AGENTS.md says what follows.`;
161
+
162
+ /** The options with a value, and the ones without. `--yes` and `-y` are npm create's habit: accepted, nothing more. */
163
+ const VALUED = ["--name", "--from-packs"];
164
+ const SWITCHES = new Set(["--no-install", "--no-git", "--yes", "-y", "--help", "-h"]);
165
+
166
+ /** Whether two paths are one directory; one that can't be read is no match. */
167
+ function sameDir(a, b) {
168
+ try {
169
+ return realpathSync(a) === realpathSync(b);
170
+ } catch {
171
+ return false;
172
+ }
173
+ }
145
174
 
146
175
  export function main(
147
176
  argv,
148
- { template, run = spawnSync, log = console.log, error = console.error, node = process.versions.node } = {},
177
+ {
178
+ template,
179
+ run = spawnSync,
180
+ log = console.log,
181
+ error = console.error,
182
+ node = process.versions.node,
183
+ pwd = process.env.PWD,
184
+ } = {},
149
185
  ) {
186
+ // Help writes nothing and checks nothing: an agent asks for it before running, in the folder it
187
+ // means to fill, and a --help read as a scaffold made a store there (p0.11.1 row 1).
188
+ if (argv.some((a) => a === "--help" || a === "-h")) {
189
+ log(HELP);
190
+ return 0;
191
+ }
192
+ // An option this doesn't read is one the agent thinks changed something: refused, nothing written.
193
+ const unknown = argv.find(
194
+ (a, i) => a.startsWith("-") && !SWITCHES.has(a) && !VALUED.includes(a) && !VALUED.includes(argv[i - 1]),
195
+ );
196
+ if (unknown) {
197
+ error(`unknown option ${unknown}\n${USAGE}`);
198
+ return 2;
199
+ }
150
200
  const flags = new Set(argv.filter((a) => a.startsWith("--no-")));
151
201
  const value = (f) => {
152
202
  const i = argv.indexOf(f);
153
203
  return i >= 0 ? argv[i + 1] : undefined;
154
204
  };
155
- const positional = argv.filter((a, i) => !a.startsWith("--") && !["--name", "--from-packs"].includes(argv[i - 1]));
205
+ const positional = argv.filter((a, i) => !a.startsWith("-") && !VALUED.includes(argv[i - 1]));
156
206
  // No directory: the folder it's run in, as `npm create kedge@latest` alone leaves it (p0.10.1 §1, 1).
157
207
  const target = positional[0] ?? ".";
158
208
  // Before anything is written: a half-made store on a machine that can't install it helps no one.
@@ -168,7 +218,11 @@ export function main(
168
218
  }
169
219
  const dir = resolve(target);
170
220
  const chosen = value("--name");
171
- const name = chosen ?? storeNameOf(basename(dir));
221
+ // The folder as it was named: one reached through a link is called by the link, which $PWD keeps
222
+ // and the working directory resolves away (salve's /workspace links to a volume named vo-…,
223
+ // which became the store's name: p0.11.1 row 7). A $PWD that isn't this directory is stale.
224
+ const named = pwd && sameDir(pwd, process.cwd()) ? resolve(pwd, target) : dir;
225
+ const name = chosen ?? storeNameOf(basename(named));
172
226
  if (!chosen) log(`store name ${name}, from the folder; --name to choose another`);
173
227
  const fromPacks = value("--from-packs");
174
228
  const t = JSON.parse(readFileSync(template, "utf8"));