@impulselab/directory 2.7.4 → 2.7.5

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 +13 -13
  2. package/dist/index.js +31 -11
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -38,16 +38,16 @@ If the remote version changed first, `push` keeps your file and asks you to sync
38
38
 
39
39
  | Command | Description |
40
40
  | --- | --- |
41
- | `impulse login [--key <key>] [--url <baseUrl>]` | Browser device-flow login; `--key` is the headless/CI fallback |
42
- | `impulse logout` | Remove the saved API key |
43
- | `impulse whoami` | Show the authenticated user |
44
- | `impulse sync [--project] [--prune] [--force] [--dry-run] [--json]` | Install or update synced artifacts |
45
- | `impulse status [--project] [--json]` | Show synced, modified, outdated and missing files |
46
- | `impulse push <path> [-m <changelog>]` | Publish a local edit as a new artifact version |
47
- | `impulse add <owner/slug> [--target <target>]` | Public install without lock tracking; interactive picker in a TTY |
48
- | `impulse add stack <id> [--target <target>]` | One-shot public stack install |
49
- | `impulse agents` | List enabled agents |
50
- | `impulse agents enable\|disable <claude\|codex\|cursor>` | Update agent targets |
41
+ | `npx @impulselab/directory login [--key <key>] [--url <baseUrl>]` | Browser device-flow login; `--key` is the headless/CI fallback |
42
+ | `npx @impulselab/directory logout` | Remove the saved API key |
43
+ | `npx @impulselab/directory whoami` | Show the authenticated user |
44
+ | `npx @impulselab/directory sync [--project] [--prune] [--force] [--dry-run] [--json]` | Install or update synced artifacts |
45
+ | `npx @impulselab/directory status [--project] [--json]` | Show synced, modified, outdated and missing files |
46
+ | `npx @impulselab/directory push <path> [-m <changelog>]` | Publish a local edit as a new artifact version |
47
+ | `npx @impulselab/directory add <owner/slug> [--target <target>]` | Public install without lock tracking; interactive picker in a TTY |
48
+ | `npx @impulselab/directory add stack <id> [--target <target>]` | One-shot public stack install |
49
+ | `npx @impulselab/directory agents` | List enabled agents |
50
+ | `npx @impulselab/directory agents enable\|disable <claude\|codex\|cursor>` | Update agent targets |
51
51
 
52
52
  ## Installing an artifact
53
53
 
@@ -71,9 +71,9 @@ npx @impulselab/directory <owner>/<slug> --target claude-slash
71
71
  The picker is skipped automatically when stdin/stdout is not a TTY, when `--target`
72
72
  is set, or when `CI` is set. Legacy
73
73
  `npx @impulselab/directory user/slug --target claude-slash` still works and is
74
- treated as `impulse add user/slug`.
74
+ treated as `npx @impulselab/directory add user/slug`.
75
75
 
76
- > Note: `impulse add stack <id>` installs are non-interactive and use each
76
+ > Note: `npx @impulselab/directory add stack <id>` installs are non-interactive and use each
77
77
  > artifact's per-target default for now.
78
78
 
79
79
  ## Target Mapping
@@ -85,4 +85,4 @@ treated as `impulse add user/slug`.
85
85
  | `agent` | `~/.claude/agents/<slug>.md` | `.claude/agents/<slug>.md` | - | - |
86
86
  | `rule` | - | - | - | `.cursor/rules/<slug>.mdc` |
87
87
 
88
- Global sync covers Claude Code and Claude Cowork because both read `~/.claude`. Codex slash commands sync to `~/.codex/prompts`. Cursor artifacts are project-scoped, so run `impulse sync --project` from inside the project.
88
+ Global sync covers Claude Code and Claude Cowork because both read `~/.claude`. Codex slash commands sync to `~/.codex/prompts`. Cursor artifacts are project-scoped, so run `npx @impulselab/directory sync --project` from inside the project.
package/dist/index.js CHANGED
@@ -151,6 +151,12 @@ function resolveInstallPaths(kind, slug, agents2, scope) {
151
151
  // src/commands/add.ts
152
152
  import pc from "picocolors";
153
153
 
154
+ // src/lib/cli-invocation.ts
155
+ var cliInvocation = "npx @impulselab/directory";
156
+ function cliCommand(args) {
157
+ return `${cliInvocation} ${args}`;
158
+ }
159
+
154
160
  // src/lib/config.ts
155
161
  import { chmod, mkdir, readFile, rename, writeFile } from "fs/promises";
156
162
  import { homedir } from "os";
@@ -326,13 +332,13 @@ async function readPayload(response) {
326
332
  }
327
333
  function errorMessage(status, payload) {
328
334
  if (status === 401) {
329
- return "Invalid or missing API key - run `impulse login`";
335
+ return `Invalid or missing API key - run \`${cliCommand("login")}\``;
330
336
  }
331
337
  if (status === 403) {
332
338
  return "You do not have permission to perform this action";
333
339
  }
334
340
  if (status === 409 && isObject(payload) && payload.error === "version_conflict") {
335
- return `Remote is at v${payload.currentVersion}, run \`impulse sync\` first (your file is kept)`;
341
+ return `Remote is at v${payload.currentVersion}, run \`${cliCommand("sync")}\` first (your file is kept)`;
336
342
  }
337
343
  if (status === 422) {
338
344
  return "The server rejected the request as invalid";
@@ -431,7 +437,11 @@ async function addCommand(identifier, options) {
431
437
  }
432
438
  return;
433
439
  }
434
- throw new Error("Use `impulse add <owner/slug>` or `impulse add stack <id>`");
440
+ throw new Error(
441
+ `Use \`${cliCommand("add <owner/slug>")}\` or \`${cliCommand(
442
+ "add stack <id>"
443
+ )}\``
444
+ );
435
445
  }
436
446
  function shouldRunInteractive(options) {
437
447
  return Boolean(
@@ -755,19 +765,21 @@ async function pollForToken(baseUrl, device) {
755
765
  }
756
766
  if (errorCode === "access_denied") {
757
767
  throw new Error(
758
- "Authorization was denied. Run `impulse login` to retry."
768
+ `Authorization was denied. Run \`${cliCommand("login")}\` to retry.`
759
769
  );
760
770
  }
761
771
  if (errorCode === "expired_token") {
762
772
  throw new Error(
763
- "The code expired. Run `impulse login` to get a new one."
773
+ `The code expired. Run \`${cliCommand("login")}\` to get a new one.`
764
774
  );
765
775
  }
766
776
  throw new Error(
767
777
  errorDescription(payload) ?? `Device login failed (${errorCode})`
768
778
  );
769
779
  }
770
- throw new Error("The code expired. Run `impulse login` to get a new one.");
780
+ throw new Error(
781
+ `The code expired. Run \`${cliCommand("login")}\` to get a new one.`
782
+ );
771
783
  }
772
784
  async function createApiKey(baseUrl, accessToken) {
773
785
  const { status, payload } = await authRequest(baseUrl, "/api-key/create", {
@@ -926,7 +938,9 @@ function isNotFound2(error) {
926
938
  async function pushCommand(filePath, options) {
927
939
  const config = await loadConfig();
928
940
  if (!config.apiKey) {
929
- throw new Error("Invalid or missing API key - run `impulse login`");
941
+ throw new Error(
942
+ `Invalid or missing API key - run \`${cliCommand("login")}\``
943
+ );
930
944
  }
931
945
  const absPath = path5.resolve(filePath);
932
946
  const match = await findLockedFile(absPath);
@@ -1329,7 +1343,9 @@ function prefixForAction(type) {
1329
1343
  async function statusCommand(options) {
1330
1344
  const config = await loadConfig();
1331
1345
  if (!config.apiKey) {
1332
- throw new Error("Invalid or missing API key - run `impulse login`");
1346
+ throw new Error(
1347
+ `Invalid or missing API key - run \`${cliCommand("login")}\``
1348
+ );
1333
1349
  }
1334
1350
  const scope = options.project ? "project" : "global";
1335
1351
  const scopeRoot = options.project ? await resolveProjectRoot() : homedir6();
@@ -1396,7 +1412,9 @@ import pc7 from "picocolors";
1396
1412
  async function syncCommand(options) {
1397
1413
  const config = await loadConfig();
1398
1414
  if (!config.apiKey) {
1399
- throw new Error("Invalid or missing API key - run `impulse login`");
1415
+ throw new Error(
1416
+ `Invalid or missing API key - run \`${cliCommand("login")}\``
1417
+ );
1400
1418
  }
1401
1419
  const scope = options.project ? "project" : "global";
1402
1420
  const scopeRoot = options.project ? await resolveProjectRoot() : homedir7();
@@ -1450,7 +1468,9 @@ async function syncCommand(options) {
1450
1468
  }
1451
1469
  if (skipped.length > 0) {
1452
1470
  console.info(
1453
- "Run `impulse push <path>` to publish, or `impulse sync --force`."
1471
+ `Run \`${cliCommand("push <path>")}\` to publish, or \`${cliCommand(
1472
+ "sync --force"
1473
+ )}\`.`
1454
1474
  );
1455
1475
  }
1456
1476
  const conflicts = actions.filter((action) => action.type === "skip-conflict");
@@ -1513,7 +1533,7 @@ import pc8 from "picocolors";
1513
1533
  async function whoamiCommand() {
1514
1534
  const config = await loadConfig();
1515
1535
  if (!config.apiKey) {
1516
- throw new Error("Not logged in - run `impulse login`");
1536
+ throw new Error(`Not logged in - run \`${cliCommand("login")}\``);
1517
1537
  }
1518
1538
  const me = await createApiClient(config.baseUrl, config.apiKey).me();
1519
1539
  console.info(`${pc8.green("\u2713")} ${me.user.slug} <${me.user.email}>`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@impulselab/directory",
3
- "version": "2.7.4",
3
+ "version": "2.7.5",
4
4
  "description": "Sync versioned skills, commands and agent configs across Claude Code, Cursor and Codex",
5
5
  "license": "MIT",
6
6
  "type": "module",