@bitmagic/cli 0.1.46-dev.3 → 0.1.46-dev.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 (81) hide show
  1. package/README.md +58 -10
  2. package/dist/auth/session.js +1 -1
  3. package/dist/auth/session.js.map +1 -1
  4. package/dist/auth/subscribe-flow.d.ts +10 -2
  5. package/dist/auth/subscribe-flow.js.map +1 -1
  6. package/dist/bin.js +6 -2
  7. package/dist/bin.js.map +1 -1
  8. package/dist/cli.d.ts +26 -3
  9. package/dist/cli.js +76 -7
  10. package/dist/cli.js.map +1 -1
  11. package/dist/commands/dev.js +9 -0
  12. package/dist/commands/dev.js.map +1 -1
  13. package/dist/commands/forge.js +1 -1
  14. package/dist/commands/forge.js.map +1 -1
  15. package/dist/commands/generate.js +9 -1
  16. package/dist/commands/generate.js.map +1 -1
  17. package/dist/commands/login.js +12 -9
  18. package/dist/commands/login.js.map +1 -1
  19. package/dist/commands/reset-account.d.ts +22 -9
  20. package/dist/commands/reset-account.js +58 -42
  21. package/dist/commands/reset-account.js.map +1 -1
  22. package/dist/commands/subscribe.d.ts +12 -0
  23. package/dist/commands/subscribe.js +12 -11
  24. package/dist/commands/subscribe.js.map +1 -1
  25. package/dist/commands/upgrade.d.ts +2 -1
  26. package/dist/commands/upgrade.js +12 -5
  27. package/dist/commands/upgrade.js.map +1 -1
  28. package/dist/commands/whoami.d.ts +8 -0
  29. package/dist/commands/whoami.js +29 -9
  30. package/dist/commands/whoami.js.map +1 -1
  31. package/dist/config/environments.d.ts +14 -0
  32. package/dist/config/environments.js +22 -0
  33. package/dist/config/environments.js.map +1 -1
  34. package/dist/errors.d.ts +10 -1
  35. package/dist/errors.js +11 -1
  36. package/dist/errors.js.map +1 -1
  37. package/dist/forge/run-pipeline.js +1 -1
  38. package/dist/forge/run-pipeline.js.map +1 -1
  39. package/dist/forge/stream.js +10 -5
  40. package/dist/forge/stream.js.map +1 -1
  41. package/dist/forge/upload-proxy.js +2 -0
  42. package/dist/forge/upload-proxy.js.map +1 -1
  43. package/dist/generate/stream.js +10 -5
  44. package/dist/generate/stream.js.map +1 -1
  45. package/dist/http/client.d.ts +6 -2
  46. package/dist/http/client.js +22 -12
  47. package/dist/http/client.js.map +1 -1
  48. package/dist/http/spark-refusal.d.ts +11 -0
  49. package/dist/http/spark-refusal.js +13 -0
  50. package/dist/http/spark-refusal.js.map +1 -1
  51. package/dist/publish/client.js +3 -1
  52. package/dist/publish/client.js.map +1 -1
  53. package/dist/scaffold/agents-md.d.ts +2 -1
  54. package/dist/scaffold/agents-md.js +7 -2
  55. package/dist/scaffold/agents-md.js.map +1 -1
  56. package/dist/scaffold/engine-download.js +5 -18
  57. package/dist/scaffold/engine-download.js.map +1 -1
  58. package/dist/scaffold/project-files.d.ts +3 -2
  59. package/dist/scaffold/project-files.js +46 -2
  60. package/dist/scaffold/project-files.js.map +1 -1
  61. package/dist/scaffold/project.d.ts +30 -0
  62. package/dist/scaffold/project.js +55 -29
  63. package/dist/scaffold/project.js.map +1 -1
  64. package/dist/scaffold/upgrade-project.js +19 -33
  65. package/dist/scaffold/upgrade-project.js.map +1 -1
  66. package/dist/telemetry/command-context.d.ts +73 -0
  67. package/dist/telemetry/command-context.js +114 -0
  68. package/dist/telemetry/command-context.js.map +1 -0
  69. package/dist/telemetry/report.d.ts +43 -0
  70. package/dist/telemetry/report.js +123 -0
  71. package/dist/telemetry/report.js.map +1 -0
  72. package/dist/telemetry/request-headers.d.ts +14 -0
  73. package/dist/telemetry/request-headers.js +48 -0
  74. package/dist/telemetry/request-headers.js.map +1 -0
  75. package/dist/update/check.d.ts +14 -0
  76. package/dist/update/check.js +20 -4
  77. package/dist/update/check.js.map +1 -1
  78. package/dist/update/notice.d.ts +59 -1
  79. package/dist/update/notice.js +75 -2
  80. package/dist/update/notice.js.map +1 -1
  81. package/package.json +4 -4
@@ -1,7 +1,8 @@
1
1
  import * as fs from 'fs';
2
2
  import * as path from 'path';
3
3
  import { CliError } from '../errors.js';
4
- import { VENDORED_DIRS, OPTIONAL_VENDORED_DIRS, OPTIONAL_VENDORED_FILES, PLATFORM_GENERATED_FILES, } from './project.js';
4
+ import { VENDORED_DIRS, PLATFORM_GENERATED_FILES, copyOptionalEngineEntries, copyServiceWorker, writeProjectFile, } from './project.js';
5
+ import { isEnvironmentName } from '../config/environments.js';
5
6
  import { reconcileAgentsMd, AGENTS_MD_FILE } from './agents-md.js';
6
7
  import { CLAUDE_SETTINGS_FILE, mergeReloadHook } from './claude-settings.js';
7
8
  /**
@@ -52,39 +53,18 @@ export function upgradeProject(options) {
52
53
  for (const dir of VENDORED_DIRS) {
53
54
  fs.cpSync(path.join(extractedEngineDir, dir), path.join(engineDir, dir), { recursive: true });
54
55
  }
55
- // Copied only when present see OPTIONAL_VENDORED_DIRS. Upgrading onto a tarball that predates
56
- // the docs corpus must leave a working project, not a half-replaced engine/ and an error.
57
- for (const dir of OPTIONAL_VENDORED_DIRS) {
58
- const source = path.join(extractedEngineDir, dir);
59
- if (fs.existsSync(source)) {
60
- fs.cpSync(source, path.join(engineDir, dir), { recursive: true });
61
- }
62
- }
63
- // Same allowance, same reason — and this is how a project scaffolded before the licence shipped
64
- // acquires engine/LICENSE.md: the rmSync above took the old engine/ with it, so upgrading onto a
65
- // tarball that carries the terms puts them in place without the creator doing anything.
66
- for (const file of OPTIONAL_VENDORED_FILES) {
67
- const source = path.join(extractedEngineDir, file);
68
- if (fs.existsSync(source)) {
69
- fs.cpSync(source, path.join(engineDir, file));
70
- }
71
- }
56
+ // Copied only when present, exactly as at init — upgrading onto a tarball that predates the docs
57
+ // corpus or the licence files must leave a working project, not a half-replaced engine/ and an
58
+ // error. This is also how a project scaffolded before the licence shipped acquires
59
+ // engine/LICENSE.md: the rmSync above took the old engine/ with it, so upgrading onto a tarball
60
+ // that carries the terms puts them in place without the creator doing anything.
61
+ copyOptionalEngineEntries(extractedEngineDir, engineDir);
72
62
  replaced.push('engine/');
73
- // Same "missing is not corrupt" allowance as scaffoldProject: a tarball published before this
74
- // feature shipped simply won't have it, and upgrade must not fail a project onto that tarball.
75
- const serviceWorker = path.join(extractedEngineDir, 'sw-cache-buster.js');
76
- if (fs.existsSync(serviceWorker)) {
77
- fs.cpSync(serviceWorker, path.join(root, 'sw-cache-buster.js'));
63
+ if (copyServiceWorker(extractedEngineDir, root)) {
78
64
  replaced.push('sw-cache-buster.js');
79
65
  }
80
66
  for (const [name, render] of PLATFORM_GENERATED_FILES) {
81
- const filePath = path.join(root, name);
82
- // The skills nest two directories deep, and a project scaffolded before they existed — or
83
- // before a newly added one existed — has no such directory. Without this, writeFileSync ENOENTs
84
- // and the upgrade dies AFTER engine/ has already been replaced. mkdir on an existing directory
85
- // is a no-op, so the flat entries pay nothing for it.
86
- fs.mkdirSync(path.dirname(filePath), { recursive: true });
87
- fs.writeFileSync(filePath, render());
67
+ writeProjectFile(root, name, render());
88
68
  replaced.push(name);
89
69
  }
90
70
  // Merged, never rewritten — the creator's permissions and their own hooks live in this file, and
@@ -94,8 +74,7 @@ export function upgradeProject(options) {
94
74
  const existingSettings = fs.existsSync(settingsPath) ? fs.readFileSync(settingsPath, 'utf-8') : undefined;
95
75
  const settings = mergeReloadHook(existingSettings);
96
76
  if (settings.contents !== null) {
97
- fs.mkdirSync(path.dirname(settingsPath), { recursive: true });
98
- fs.writeFileSync(settingsPath, settings.contents);
77
+ writeProjectFile(root, CLAUDE_SETTINGS_FILE, settings.contents);
99
78
  replaced.push(CLAUDE_SETTINGS_FILE);
100
79
  }
101
80
  // Read-modify-write, not re-rendered from renderBitmagicJson: re-rendering would discard any
@@ -112,8 +91,15 @@ export function upgradeProject(options) {
112
91
  meta.environment = environmentPinned;
113
92
  // AGENTS.md last, because it is the one file here whose treatment depends on reading the stamp
114
93
  // out of the metadata above — and whose result is written back into it below.
94
+ //
95
+ // The pin goes in too: the template's CLI-update section names the npm line this project's
96
+ // environment implies, so it is read AFTER the backfill above (a project that just gained a pin
97
+ // gets an AGENTS.md that knows it). An unrecognised hand-edited value renders as unpinned rather
98
+ // than throwing — refusing to refresh the guidance would be a strange way to report a typo, and
99
+ // the environment resolution the command already did says it far better.
115
100
  const storedHash = typeof meta.agentsMdHash === 'string' ? meta.agentsMdHash : undefined;
116
- const agentsMd = reconcileAgentsMd(root, storedHash);
101
+ const pinned = typeof meta.environment === 'string' && isEnvironmentName(meta.environment) ? meta.environment : undefined;
102
+ const agentsMd = reconcileAgentsMd(root, storedHash, pinned);
117
103
  if (agentsMd.hashToStore !== undefined)
118
104
  meta.agentsMdHash = agentsMd.hashToStore;
119
105
  if (agentsMd.action === 'created' || agentsMd.action === 'rewritten')
@@ -1 +1 @@
1
- {"version":3,"file":"upgrade-project.js","sourceRoot":"","sources":["../../src/scaffold/upgrade-project.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"upgrade-project.js","sourceRoot":"","sources":["../../src/scaffold/upgrade-project.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import { type Environment } from '../config/environments.js';
2
+ /**
3
+ * What is driving the CLI.
4
+ *
5
+ * - `claude-code` — a Claude Code session (its `CLAUDECODE` env var, verified).
6
+ * - `json` — some agent, unidentified: `--json` is the flag agents pass.
7
+ * - `tty` — a person at a terminal.
8
+ * - `pipe` — a script or CI: no `--json`, no terminal.
9
+ *
10
+ * Add an agent here only once its marker is verified against the real thing; a
11
+ * guessed env var never fires and just misleads whoever reads the table.
12
+ */
13
+ export type CliDriver = 'claude-code' | 'json' | 'tty' | 'pipe';
14
+ export declare function detectDriver(input: {
15
+ json: boolean;
16
+ env: Record<string, string | undefined>;
17
+ isTTY: boolean;
18
+ }): CliDriver;
19
+ /**
20
+ * `DO_NOT_TRACK` set to anything but `0`/`false`/empty. The convention says
21
+ * `1`; being generous about the spelling is the polite reading of a signal
22
+ * that only ever means "please don't".
23
+ *
24
+ * Lives here rather than in report.ts because it is consulted BEFORE anything
25
+ * is collected — `beginCommand` skips the whole snapshot when it is set — and
26
+ * report.ts already imports this module, so the other direction would close a
27
+ * cycle. Re-exported from report.ts, which is where callers expect it.
28
+ */
29
+ export declare function isTelemetryDisabled(env: Record<string, string | undefined>): boolean;
30
+ export interface TokenSnapshot {
31
+ accessToken: string;
32
+ /** Epoch milliseconds, as stored. */
33
+ expiresAt: number;
34
+ }
35
+ export interface CommandContext {
36
+ /** As typed, so a report reads the way the creator invoked it: `publish`, `generate skybox`. */
37
+ name: string;
38
+ json: boolean;
39
+ driver: CliDriver;
40
+ /**
41
+ * Where this command is talking to, resolved ONCE here through the same
42
+ * precedence every command uses (`--env` > BITMAGIC_ENV > the project's
43
+ * bitmagic.json > the stored default). `report.ts` reads it rather than
44
+ * resolving again: a second resolution is a second chance to disagree, and
45
+ * one that skipped the project tier would send a project's beacons to a
46
+ * different environment than the work they describe.
47
+ *
48
+ * Null only when resolution threw — an unknown `--env`, or a project whose
49
+ * `environment` field is not a valid name. The command itself fails with
50
+ * that message moments later; there is simply nowhere to report it to.
51
+ */
52
+ environment: Environment | null;
53
+ /** Epoch milliseconds when the command began. */
54
+ startedAt: number;
55
+ /** See the module header: the stored access token at start, for the one command that removes it. */
56
+ tokenSnapshot: TokenSnapshot | null;
57
+ }
58
+ export interface BeginCommandInput {
59
+ name: string;
60
+ json: boolean;
61
+ explicitEnv?: string;
62
+ env?: Record<string, string | undefined>;
63
+ isTTY?: boolean;
64
+ now?: () => number;
65
+ baseDir?: string;
66
+ /** Where to look for the project's own environment pin; defaults to process.cwd(). */
67
+ cwd?: string;
68
+ }
69
+ export declare function beginCommand(input: BeginCommandInput): CommandContext;
70
+ /** The running command, or null before `beginCommand` — e.g. under a test that calls a module directly. */
71
+ export declare function currentCommand(): CommandContext | null;
72
+ /** Test seam: forget the running command, so one test's context cannot leak into the next. */
73
+ export declare function resetCommandContextForTests(): void;
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Which command this process is running — the one piece of state the CLI's usage
3
+ * reporting is built on.
4
+ *
5
+ * One process runs one command, so this is process-scoped: cli.ts's wrapper calls
6
+ * {@link beginCommand} once before the command's `run`, and two readers use it —
7
+ * `request-headers.ts`, which names the command on every api-server call, and
8
+ * `report.ts`, which sends the outcome when the command ends. It is the CLI's
9
+ * equivalent of a request context, and it lives here rather than being threaded
10
+ * through every command signature because there are five separate fetch sites and
11
+ * eighteen commands, and a parameter every one of them must remember to pass is
12
+ * how one of them ends up unlabelled.
13
+ *
14
+ * Nothing here reaches the network. The token snapshot is a file read, and it
15
+ * exists for exactly one command: `logout` removes the stored credentials, so by
16
+ * the time its outcome is reported there is nothing to authenticate the report
17
+ * with — except what was there when it started.
18
+ */
19
+ import { readCredentials } from '../config/credentials.js';
20
+ import { resolveEnvironmentForCommand } from '../config/environments.js';
21
+ const AGENT_ENV_MARKERS = [['CLAUDECODE', 'claude-code']];
22
+ export function detectDriver(input) {
23
+ for (const [marker, driver] of AGENT_ENV_MARKERS) {
24
+ if (input.env[marker])
25
+ return driver;
26
+ }
27
+ if (input.json)
28
+ return 'json';
29
+ return input.isTTY ? 'tty' : 'pipe';
30
+ }
31
+ /**
32
+ * `DO_NOT_TRACK` set to anything but `0`/`false`/empty. The convention says
33
+ * `1`; being generous about the spelling is the polite reading of a signal
34
+ * that only ever means "please don't".
35
+ *
36
+ * Lives here rather than in report.ts because it is consulted BEFORE anything
37
+ * is collected — `beginCommand` skips the whole snapshot when it is set — and
38
+ * report.ts already imports this module, so the other direction would close a
39
+ * cycle. Re-exported from report.ts, which is where callers expect it.
40
+ */
41
+ export function isTelemetryDisabled(env) {
42
+ const value = env.DO_NOT_TRACK?.trim().toLowerCase();
43
+ return value !== undefined && value !== '' && value !== '0' && value !== 'false';
44
+ }
45
+ let current = null;
46
+ /**
47
+ * The environment this command targets, or null if it cannot be resolved.
48
+ *
49
+ * `resolveEnvironmentForCommand` is the same entry point the commands use, so
50
+ * a project pinned to an environment reports there too. It throws for an
51
+ * unknown name typed right now (a bad `--env`, a bad `bitmagic.json`), which
52
+ * the command surfaces properly — here it only means "no environment to report
53
+ * to", never a failed command.
54
+ */
55
+ function snapshotEnvironment(input, env) {
56
+ try {
57
+ return resolveEnvironmentForCommand({
58
+ explicit: input.explicitEnv,
59
+ cwd: input.cwd,
60
+ baseDir: input.baseDir,
61
+ env,
62
+ });
63
+ }
64
+ catch {
65
+ return null;
66
+ }
67
+ }
68
+ /**
69
+ * The stored access token for `environment`, or null.
70
+ *
71
+ * Every failure collapses to null on purpose: no environment, an unreadable
72
+ * credentials file, nothing stored — the command itself will report whichever
73
+ * of those matters, in its own words. This is a snapshot for a report, and a
74
+ * report is never worth failing a command over.
75
+ */
76
+ function snapshotToken(environment, baseDir) {
77
+ if (environment === null)
78
+ return null;
79
+ try {
80
+ const stored = readCredentials(environment.name, baseDir);
81
+ return stored ? { accessToken: stored.accessToken, expiresAt: stored.expiresAt } : null;
82
+ }
83
+ catch {
84
+ return null;
85
+ }
86
+ }
87
+ export function beginCommand(input) {
88
+ const env = input.env ?? process.env;
89
+ // Nothing is collected for a creator who opted out. Both snapshots below are
90
+ // filesystem work — a walk up the tree for the project's bitmagic.json, then
91
+ // credentials.json — done on every one of the eighteen commands, including
92
+ // the offline ones and the `reload` hook that runs after every agent turn.
93
+ // None of it has a purpose if no report will be sent.
94
+ const collect = !isTelemetryDisabled(env);
95
+ const environment = collect ? snapshotEnvironment(input, env) : null;
96
+ current = {
97
+ name: input.name,
98
+ json: input.json,
99
+ driver: detectDriver({ json: input.json, env, isTTY: input.isTTY ?? process.stdout.isTTY === true }),
100
+ environment,
101
+ startedAt: (input.now ?? Date.now)(),
102
+ tokenSnapshot: collect ? snapshotToken(environment, input.baseDir) : null,
103
+ };
104
+ return current;
105
+ }
106
+ /** The running command, or null before `beginCommand` — e.g. under a test that calls a module directly. */
107
+ export function currentCommand() {
108
+ return current;
109
+ }
110
+ /** Test seam: forget the running command, so one test's context cannot leak into the next. */
111
+ export function resetCommandContextForTests() {
112
+ current = null;
113
+ }
114
+ //# sourceMappingURL=command-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-context.js","sourceRoot":"","sources":["../../src/telemetry/command-context.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ import { isTelemetryDisabled } from './command-context.js';
2
+ export { isTelemetryDisabled };
3
+ /**
4
+ * Cap on each request the report makes (the token refresh, when one is due, and
5
+ * the POST itself). A pending fetch keeps Node alive, so an unbounded one would
6
+ * hold a finished command open for as long as the network sulks.
7
+ */
8
+ export declare const REPORT_TIMEOUT_MS = 1500;
9
+ export declare const CLI_EVENTS_PATH = "/api/cli/v1/events";
10
+ export interface CommandReport {
11
+ /** `finished` for every command's end; `started` for a long-running command once it is up. */
12
+ stage: 'started' | 'finished';
13
+ ok?: boolean;
14
+ durationMs?: number;
15
+ exitCode?: number;
16
+ /** A category — `CliError.code`, `cli_error`, `crash:TypeError` — never a message. */
17
+ failure?: string;
18
+ }
19
+ export interface ReportDeps {
20
+ fetch: typeof globalThis.fetch;
21
+ env: Record<string, string | undefined>;
22
+ now?: () => number;
23
+ /** Where credentials live; tests point this at a temp dir. */
24
+ baseDir?: string;
25
+ }
26
+ /**
27
+ * The failure category for an error that is not a CliError — a genuine bug, not
28
+ * a refusal we wrote a message for. `crash:TypeError`, `crash:RangeError`: the
29
+ * error's class, which says what kind of bug without saying anything about the
30
+ * creator's machine. Anything odd in the name is folded to `_` so the value
31
+ * always fits the shape api-server accepts.
32
+ */
33
+ export declare function crashCategory(error: unknown): string;
34
+ /**
35
+ * Report the running command's `report` to api-server. Resolves when the report
36
+ * has been sent, refused, or given up on — always, and never by throwing.
37
+ *
38
+ * Callers `await` it (bounded, see above) rather than fire and forget: on the
39
+ * failure path cli.ts calls `process.exit` next, which would otherwise cut the
40
+ * request off mid-flight, and on the success path the pending fetch would keep
41
+ * the process alive for the same time either way.
42
+ */
43
+ export declare function reportCommandEvent(report: CommandReport, deps?: ReportDeps): Promise<void>;
@@ -0,0 +1,123 @@
1
+ /**
2
+ * The command beacon: one `POST /api/cli/v1/events` per command, saying how it went.
3
+ *
4
+ * Why it exists: api-server can see the commands that call it — but `dev`,
5
+ * `build`, `check`, `verify` and `reload` are offline by design, and even a
6
+ * `publish` that fails on a stale verify never reaches the server. This is how
7
+ * every command becomes visible, and how the ones the server does see get an
8
+ * end-to-end outcome and duration to go with the server's own event. The
9
+ * server turns it into `cli_command` / `cli_command_started` (see
10
+ * `api-server/src/cli/cli-analytics.ts`); nothing goes to Google from here.
11
+ *
12
+ * Contract, in order of importance:
13
+ *
14
+ * 1. It never fails or delays a command. Every failure path — not logged in,
15
+ * no network, a slow server, a bad `--env` — returns silently. It is
16
+ * bounded to {@link REPORT_TIMEOUT_MS} per request so a finished command is
17
+ * never held open by a sulking network (the same reasoning as
18
+ * update/check.ts). It never prints.
19
+ * 2. It sends categories, never messages: the command name, ok/failed, the
20
+ * exit code, a `CliError.code`, and a duration. A message can name a path
21
+ * or a game; none of that belongs in an analytics event.
22
+ * 3. It is authenticated with the creator's own token, so the server can key
23
+ * the event to the account and look up their real Pro state. No token, no
24
+ * report — an anonymous beacon would be a spammable endpoint for nothing.
25
+ * 4. `DO_NOT_TRACK=1` (the cross-tool convention, consoledonottrack.com)
26
+ * turns it off. It does not touch the ordinary api-server calls a command
27
+ * makes — those are the command's work, and the server logs them anyway.
28
+ */
29
+ import { resolveAuth0ClientId } from '../config/environments.js';
30
+ import { getAccessToken } from '../auth/session.js';
31
+ import { apiServerHeaders } from './request-headers.js';
32
+ import { currentCommand, isTelemetryDisabled } from './command-context.js';
33
+ // Re-exported because this is where the opt-out is enforced for a report that is already
34
+ // under way; `beginCommand` consults the same predicate to skip collecting anything at all.
35
+ export { isTelemetryDisabled };
36
+ /**
37
+ * Cap on each request the report makes (the token refresh, when one is due, and
38
+ * the POST itself). A pending fetch keeps Node alive, so an unbounded one would
39
+ * hold a finished command open for as long as the network sulks.
40
+ */
41
+ export const REPORT_TIMEOUT_MS = 1500;
42
+ export const CLI_EVENTS_PATH = '/api/cli/v1/events';
43
+ /**
44
+ * The failure category for an error that is not a CliError — a genuine bug, not
45
+ * a refusal we wrote a message for. `crash:TypeError`, `crash:RangeError`: the
46
+ * error's class, which says what kind of bug without saying anything about the
47
+ * creator's machine. Anything odd in the name is folded to `_` so the value
48
+ * always fits the shape api-server accepts.
49
+ */
50
+ export function crashCategory(error) {
51
+ const name = error instanceof Error && error.name ? error.name : 'unknown';
52
+ return `crash:${name.replace(/[^A-Za-z0-9_.-]/g, '_').slice(0, 40)}`;
53
+ }
54
+ /** The given fetch, with every call bounded by REPORT_TIMEOUT_MS. */
55
+ function boundedFetch(fetchImpl) {
56
+ return (input, init) => fetchImpl(input, { ...init, signal: AbortSignal.timeout(REPORT_TIMEOUT_MS) });
57
+ }
58
+ /**
59
+ * The token to authenticate the report with, or null for "no report".
60
+ *
61
+ * The stored token first — refreshed if it has expired, exactly as any command
62
+ * would, so a report never wastes a request on a 401 — and failing that the
63
+ * snapshot taken when the command began, which is what `logout` leaves behind.
64
+ */
65
+ async function resolveReportToken(environment, command, deps) {
66
+ try {
67
+ const clientId = resolveAuth0ClientId(environment, deps.env);
68
+ return await getAccessToken(environment, clientId, {
69
+ fetch: boundedFetch(deps.fetch),
70
+ sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
71
+ now: deps.now,
72
+ }, deps.baseDir);
73
+ }
74
+ catch {
75
+ const snapshot = command.tokenSnapshot;
76
+ const now = (deps.now ?? Date.now)();
77
+ return snapshot !== null && snapshot.expiresAt > now ? snapshot.accessToken : null;
78
+ }
79
+ }
80
+ function defaultDeps() {
81
+ return { fetch: globalThis.fetch, env: process.env };
82
+ }
83
+ /**
84
+ * Report the running command's `report` to api-server. Resolves when the report
85
+ * has been sent, refused, or given up on — always, and never by throwing.
86
+ *
87
+ * Callers `await` it (bounded, see above) rather than fire and forget: on the
88
+ * failure path cli.ts calls `process.exit` next, which would otherwise cut the
89
+ * request off mid-flight, and on the success path the pending fetch would keep
90
+ * the process alive for the same time either way.
91
+ */
92
+ export async function reportCommandEvent(report, deps = defaultDeps()) {
93
+ try {
94
+ if (isTelemetryDisabled(deps.env))
95
+ return;
96
+ const command = currentCommand();
97
+ if (command === null)
98
+ return;
99
+ // Resolved once, at command start — see CommandContext.environment for why
100
+ // this must not resolve again. Null means it could not be resolved at all,
101
+ // so there is nowhere to send this.
102
+ const environment = command.environment;
103
+ if (environment === null)
104
+ return;
105
+ const token = await resolveReportToken(environment, command, deps);
106
+ if (token === null)
107
+ return;
108
+ await boundedFetch(deps.fetch)(`${environment.apiUrl}${CLI_EVENTS_PATH}`, {
109
+ method: 'POST',
110
+ headers: {
111
+ ...apiServerHeaders(),
112
+ Authorization: `Bearer ${token}`,
113
+ 'Content-Type': 'application/json',
114
+ },
115
+ body: JSON.stringify({ command: command.name, ...report }),
116
+ });
117
+ }
118
+ catch {
119
+ // Best-effort by design — see the module header. Whatever went wrong here,
120
+ // the command's own outcome has already been decided and printed.
121
+ }
122
+ }
123
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/telemetry/report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export declare const CLI_COMMAND_HEADER = "X-Bitmagic-Cli-Command";
2
+ export declare const CLI_DRIVER_HEADER = "X-Bitmagic-Cli-Driver";
3
+ /** `bitmagic-cli/0.1.46 (darwin-arm64; node/v22.12.0)` — the shape api-server's context reader parses. */
4
+ export declare function userAgent(): string;
5
+ /**
6
+ * Spread these into the `headers` of every fetch aimed at api-server. Callers
7
+ * add their own `Authorization`, `Accept` and `Content-Type` after — nothing
8
+ * here collides with those.
9
+ *
10
+ * The command headers are present only once cli.ts has begun a command; a
11
+ * module exercised directly (a test, a future library caller) still identifies
12
+ * the CLI, just not the command.
13
+ */
14
+ export declare function apiServerHeaders(): Record<string, string>;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * The headers every api-server call carries, so the server's analytics know who
3
+ * asked and why.
4
+ *
5
+ * The CLI never sends analytics to Google itself — the GA4 Measurement Protocol
6
+ * needs an API secret, and a public npm package cannot keep one. api-server
7
+ * emits every event instead (`api-server/src/cli/cli-analytics.ts` reads these
8
+ * headers back as `cli_version`, `cli_platform`, `cli_node`, `cli_command` and
9
+ * `cli_driver`). That is what lets a `cli_asset_generated` event tell `generate
10
+ * image` from `cover`, which share a route, and a `publish` from a `forge`,
11
+ * which share the signed-URL route.
12
+ *
13
+ * Only for api-server. GCS signed URLs and the npm registry get nothing from
14
+ * here — a signed PUT can refuse headers it did not sign for, and neither has
15
+ * any use for them.
16
+ */
17
+ import { currentCliVersion } from '../update/cli-version.js';
18
+ import { currentCommand } from './command-context.js';
19
+ export const CLI_COMMAND_HEADER = 'X-Bitmagic-Cli-Command';
20
+ export const CLI_DRIVER_HEADER = 'X-Bitmagic-Cli-Driver';
21
+ let cachedUserAgent = null;
22
+ /** `bitmagic-cli/0.1.46 (darwin-arm64; node/v22.12.0)` — the shape api-server's context reader parses. */
23
+ export function userAgent() {
24
+ if (cachedUserAgent === null) {
25
+ const version = currentCliVersion() || 'unknown';
26
+ cachedUserAgent = `bitmagic-cli/${version} (${process.platform}-${process.arch}; node/${process.version})`;
27
+ }
28
+ return cachedUserAgent;
29
+ }
30
+ /**
31
+ * Spread these into the `headers` of every fetch aimed at api-server. Callers
32
+ * add their own `Authorization`, `Accept` and `Content-Type` after — nothing
33
+ * here collides with those.
34
+ *
35
+ * The command headers are present only once cli.ts has begun a command; a
36
+ * module exercised directly (a test, a future library caller) still identifies
37
+ * the CLI, just not the command.
38
+ */
39
+ export function apiServerHeaders() {
40
+ const headers = { 'User-Agent': userAgent() };
41
+ const command = currentCommand();
42
+ if (command) {
43
+ headers[CLI_COMMAND_HEADER] = command.name;
44
+ headers[CLI_DRIVER_HEADER] = command.driver;
45
+ }
46
+ return headers;
47
+ }
48
+ //# sourceMappingURL=request-headers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-headers.js","sourceRoot":"","sources":["../../src/telemetry/request-headers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,CAAC,MAAM,kBAAkB,GAAG,wBAAwB,CAAC;AAC3D,MAAM,CAAC,MAAM,iBAAiB,GAAG,uBAAuB,CAAC;AAEzD,IAAI,eAAe,GAAkB,IAAI,CAAC;AAE1C,0GAA0G;AAC1G,MAAM,UAAU,SAAS;IACvB,IAAI,eAAe,KAAK,IAAI,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAG,iBAAiB,EAAE,IAAI,SAAS,CAAC;QACjD,eAAe,GAAG,gBAAgB,OAAO,KAAK,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,IAAI,UAAU,OAAO,CAAC,OAAO,GAAG,CAAC;IAC7G,CAAC;IACD,OAAO,eAAe,CAAC;AACzB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,OAAO,GAA2B,EAAE,YAAY,EAAE,SAAS,EAAE,EAAE,CAAC;IACtE,MAAM,OAAO,GAAG,cAAc,EAAE,CAAC;IACjC,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;QAC3C,OAAO,CAAC,iBAAiB,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9C,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -1,3 +1,4 @@
1
+ import type { EnvironmentName } from '../config/environments.js';
1
2
  import { type UpdateCheckCache, type UpdateTag } from './notice.js';
2
3
  export declare function updateCachePath(baseDir?: string): string;
3
4
  /**
@@ -24,6 +25,19 @@ export declare function fetchTagVersion(tag: UpdateTag, fetchImpl?: typeof globa
24
25
  * every command wait on npm to be told something it could just as well be told tomorrow.
25
26
  */
26
27
  export declare function pendingUpdateNotice(currentVersion: string, baseDir?: string): string | null;
28
+ /**
29
+ * The single line bin.ts prints before a command runs — at most one install command, ever.
30
+ *
31
+ * The wrong-line notice wins over the newer-version one, and suppresses it. Both at once would
32
+ * print two different `npm i -g` commands in the same breath ("update to 0.1.45 on your line" next
33
+ * to "be on the other line"), which is the ambiguity this exists to end: a creator standing in a
34
+ * project should never have to choose which one they meant.
35
+ *
36
+ * `projectEnvironment` is the project's committed pin, or undefined outside a project and for one
37
+ * that has none. Undefined leaves the old behaviour exactly as it was: nothing here invents a line
38
+ * for a directory that never claimed one.
39
+ */
40
+ export declare function startupNotice(currentVersion: string, projectEnvironment: EnvironmentName | undefined, baseDir?: string): string | null;
27
41
  /**
28
42
  * Refresh the cache if it is stale. Fire-and-forget: callers must not await this.
29
43
  *
@@ -1,7 +1,7 @@
1
1
  import * as fs from 'fs';
2
2
  import * as path from 'path';
3
3
  import { defaultBaseDir } from '../config/credentials.js';
4
- import { cliUpdateNotice, isCacheStale, updateTagFor, } from './notice.js';
4
+ import { cliLineMismatchNotice, cliUpdateNotice, isCacheStale, updateTagFor, } from './notice.js';
5
5
  /** Public registry metadata, one document per dist-tag. No auth, no scope needed. */
6
6
  const NPM_PACKAGE_URL = 'https://registry.npmjs.org/@bitmagic/cli';
7
7
  /**
@@ -90,6 +90,22 @@ export function pendingUpdateNotice(currentVersion, baseDir) {
90
90
  return null;
91
91
  return cliUpdateNotice(currentVersion, cache.latest);
92
92
  }
93
+ /**
94
+ * The single line bin.ts prints before a command runs — at most one install command, ever.
95
+ *
96
+ * The wrong-line notice wins over the newer-version one, and suppresses it. Both at once would
97
+ * print two different `npm i -g` commands in the same breath ("update to 0.1.45 on your line" next
98
+ * to "be on the other line"), which is the ambiguity this exists to end: a creator standing in a
99
+ * project should never have to choose which one they meant.
100
+ *
101
+ * `projectEnvironment` is the project's committed pin, or undefined outside a project and for one
102
+ * that has none. Undefined leaves the old behaviour exactly as it was: nothing here invents a line
103
+ * for a directory that never claimed one.
104
+ */
105
+ export function startupNotice(currentVersion, projectEnvironment, baseDir) {
106
+ const mismatch = projectEnvironment === undefined ? null : cliLineMismatchNotice(currentVersion, projectEnvironment);
107
+ return mismatch ?? pendingUpdateNotice(currentVersion, baseDir);
108
+ }
93
109
  /**
94
110
  * Refresh the cache if it is stale. Fire-and-forget: callers must not await this.
95
111
  *
@@ -100,12 +116,12 @@ export async function refreshUpdateCacheInBackground(currentVersion, now = Date.
100
116
  const tag = updateTagFor(currentVersion);
101
117
  const cache = readUpdateCache(baseDir);
102
118
  // A cache about the other line is refreshed immediately however recent it is — switching lines
103
- // with `npm i -g @bitmagic/cli@dev` must not leave the nudge mute for up to a day.
119
+ // with `npm i -g @bitmagic/cli@dev` must not leave the nudge mute for the rest of its interval.
104
120
  if (cache !== null && cache.tag === tag && !isCacheStale(cache, now))
105
121
  return;
106
122
  const latest = await fetchTagVersion(tag, fetchImpl);
107
- // Recorded even when the fetch failed, so an offline machine backs off for a day rather than
108
- // retrying npm on every single command.
123
+ // Recorded even when the fetch failed, so an offline machine backs off for the interval rather
124
+ // than retrying npm on every single command.
109
125
  writeUpdateCache({ latest, tag, checkedAt: now }, baseDir);
110
126
  }
111
127
  //# sourceMappingURL=check.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/update/check.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/update/check.ts"],"names":[],"mappings":"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"}