@insforge/cli 0.1.80 → 0.1.81
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 +10 -8
- package/dist/index.js +125 -42
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -674,17 +674,19 @@ Skill files are written to per-agent directories (e.g. `.claude/`, `.cursor/`, `
|
|
|
674
674
|
|
|
675
675
|
The CLI reports anonymous usage events to [PostHog](https://posthog.com) so we can understand which features are being used and prioritize improvements.
|
|
676
676
|
|
|
677
|
-
|
|
677
|
+
We capture only non-sensitive metadata: the command name, subcommand, outcome (`success`, `applied`, `aborted`, `dry_run`, `no_changes`, `all_skipped`, `error`), flag shape (e.g. `dry_run`, `json_mode`), section names from `insforge.toml` schema (e.g. `auth.smtp`), region, and an OSS-vs-cloud flag. We never send SQL, TOML file contents, credentials, environment variable values, or any free text you type.
|
|
678
|
+
|
|
679
|
+
If you build the CLI from source without setting `POSTHOG_API_KEY` at build time, analytics become a no-op automatically.
|
|
678
680
|
|
|
679
681
|
## Environment Variables
|
|
680
682
|
|
|
681
|
-
| Variable | Description
|
|
682
|
-
| ----------------------- |
|
|
683
|
-
| `INSFORGE_ACCESS_TOKEN` | Override the stored access token
|
|
684
|
-
| `INSFORGE_PROJECT_ID` | Override the linked project ID
|
|
685
|
-
| `INSFORGE_API_URL` | Override the Platform API URL
|
|
686
|
-
| `INSFORGE_EMAIL` | Email for non-interactive login
|
|
687
|
-
| `INSFORGE_PASSWORD` | Password for non-interactive login
|
|
683
|
+
| Variable | Description |
|
|
684
|
+
| ----------------------- | --------------------------------------------------------------- |
|
|
685
|
+
| `INSFORGE_ACCESS_TOKEN` | Override the stored access token |
|
|
686
|
+
| `INSFORGE_PROJECT_ID` | Override the linked project ID |
|
|
687
|
+
| `INSFORGE_API_URL` | Override the Platform API URL |
|
|
688
|
+
| `INSFORGE_EMAIL` | Email for non-interactive login |
|
|
689
|
+
| `INSFORGE_PASSWORD` | Password for non-interactive login |
|
|
688
690
|
|
|
689
691
|
## Non-Interactive / CI Usage
|
|
690
692
|
|
package/dist/index.js
CHANGED
|
@@ -1215,9 +1215,24 @@ function trackPayments(subcommand, config, properties) {
|
|
|
1215
1215
|
...properties
|
|
1216
1216
|
});
|
|
1217
1217
|
}
|
|
1218
|
+
function trackConfig(subcommand, config, properties) {
|
|
1219
|
+
const distinctId = config?.project_id ?? FAKE_PROJECT_ID;
|
|
1220
|
+
captureEvent(distinctId, "cli_config_invoked", {
|
|
1221
|
+
subcommand,
|
|
1222
|
+
project_id: config?.project_id,
|
|
1223
|
+
project_name: config?.project_name,
|
|
1224
|
+
org_id: config?.org_id,
|
|
1225
|
+
region: config?.region,
|
|
1226
|
+
oss_mode: !config || config.project_id === FAKE_PROJECT_ID,
|
|
1227
|
+
...properties
|
|
1228
|
+
});
|
|
1229
|
+
}
|
|
1218
1230
|
async function shutdownAnalytics() {
|
|
1231
|
+
if (!client) return;
|
|
1232
|
+
const c = client;
|
|
1233
|
+
client = null;
|
|
1219
1234
|
try {
|
|
1220
|
-
|
|
1235
|
+
await c.shutdown();
|
|
1221
1236
|
} catch {
|
|
1222
1237
|
}
|
|
1223
1238
|
}
|
|
@@ -6961,7 +6976,7 @@ function registerDiagnoseCommands(diagnoseCmd2) {
|
|
|
6961
6976
|
const s = !json ? clack15.spinner() : null;
|
|
6962
6977
|
s?.start("Collecting diagnostic data...");
|
|
6963
6978
|
const data2 = await collectDiagnosticData(projectId, ossMode, apiUrl);
|
|
6964
|
-
const cliVersion = "0.1.
|
|
6979
|
+
const cliVersion = "0.1.81";
|
|
6965
6980
|
s?.stop("Data collected");
|
|
6966
6981
|
if (!json) {
|
|
6967
6982
|
console.log(`
|
|
@@ -8325,7 +8340,6 @@ function registerPaymentsCommands(paymentsCmd2) {
|
|
|
8325
8340
|
}
|
|
8326
8341
|
|
|
8327
8342
|
// src/commands/posthog/setup.ts
|
|
8328
|
-
import { spawnSync as spawnSync2 } from "child_process";
|
|
8329
8343
|
import * as clack16 from "@clack/prompts";
|
|
8330
8344
|
import pc3 from "picocolors";
|
|
8331
8345
|
|
|
@@ -8528,41 +8542,20 @@ async function runSetup(opts) {
|
|
|
8528
8542
|
outputSuccess(`Linked to InsForge project: ${proj.project_name} (${proj.project_id})`);
|
|
8529
8543
|
}
|
|
8530
8544
|
const dashboardConnection = await ensureDashboardConnection(proj.project_id, token, opts);
|
|
8531
|
-
if (opts.json) {
|
|
8532
|
-
|
|
8533
|
-
|
|
8534
|
-
|
|
8535
|
-
|
|
8536
|
-
|
|
8537
|
-
|
|
8538
|
-
|
|
8539
|
-
|
|
8540
|
-
pc3.dim("(it will open a browser for OAuth and let you pick a PostHog project)")
|
|
8541
|
-
);
|
|
8542
|
-
const wizardResult = spawnSync2(NPX_COMMAND, ["-y", "@posthog/wizard@latest"], {
|
|
8543
|
-
stdio: "inherit",
|
|
8544
|
-
env: process.env
|
|
8545
|
-
});
|
|
8546
|
-
if (wizardResult.error) {
|
|
8547
|
-
throw new CLIError(`Failed to launch PostHog wizard: ${wizardResult.error.message}`);
|
|
8548
|
-
}
|
|
8549
|
-
const exitCode = wizardResult.status ?? 1;
|
|
8550
|
-
if (wizardResult.signal === "SIGINT" || exitCode === 130) {
|
|
8551
|
-
clack16.outro("Setup cancelled.");
|
|
8552
|
-
return {
|
|
8553
|
-
dashboardConnection,
|
|
8554
|
-
wizardSkipped: false,
|
|
8555
|
-
wizardExitCode: exitCode
|
|
8556
|
-
};
|
|
8557
|
-
}
|
|
8558
|
-
if (exitCode !== 0) {
|
|
8559
|
-
throw new CLIError(`PostHog wizard exited with code ${exitCode}.`);
|
|
8545
|
+
if (!opts.json) {
|
|
8546
|
+
clack16.note(
|
|
8547
|
+
`Run this in your terminal to wire PostHog into your app code:
|
|
8548
|
+
|
|
8549
|
+
${WIZARD_COMMAND}
|
|
8550
|
+
|
|
8551
|
+
Once it completes, open the Analytics page in your InsForge dashboard.`,
|
|
8552
|
+
"Next step"
|
|
8553
|
+
);
|
|
8560
8554
|
}
|
|
8561
|
-
clack16.outro("Done. Open the Analytics page in your InsForge dashboard to view data.");
|
|
8562
8555
|
return {
|
|
8563
8556
|
dashboardConnection,
|
|
8564
|
-
wizardSkipped:
|
|
8565
|
-
|
|
8557
|
+
wizardSkipped: true,
|
|
8558
|
+
wizardCommand: WIZARD_COMMAND
|
|
8566
8559
|
};
|
|
8567
8560
|
}
|
|
8568
8561
|
async function ensureDashboardConnection(projectId, token, opts) {
|
|
@@ -8589,10 +8582,14 @@ async function runConnectFlow(projectId, token, authorizeUrl, opts) {
|
|
|
8589
8582
|
process.stderr.write("Your browser should open automatically. If not, copy the URL above.\n");
|
|
8590
8583
|
} else {
|
|
8591
8584
|
clack16.log.info("PostHog is not yet connected to your InsForge dashboard.");
|
|
8592
|
-
|
|
8593
|
-
|
|
8594
|
-
|
|
8595
|
-
|
|
8585
|
+
if (opts.skipBrowser) {
|
|
8586
|
+
clack16.log.info(`Open this URL to authorize PostHog:
|
|
8587
|
+
${pc3.cyan(pc3.underline(authorizeUrl))}`);
|
|
8588
|
+
} else {
|
|
8589
|
+
clack16.log.info("Opening browser to authorize PostHog...");
|
|
8590
|
+
clack16.log.info(`If browser doesn't open, visit:
|
|
8591
|
+
${pc3.cyan(pc3.underline(authorizeUrl))}`);
|
|
8592
|
+
}
|
|
8596
8593
|
}
|
|
8597
8594
|
if (!opts.skipBrowser) {
|
|
8598
8595
|
try {
|
|
@@ -8602,7 +8599,11 @@ async function runConnectFlow(projectId, token, authorizeUrl, opts) {
|
|
|
8602
8599
|
}
|
|
8603
8600
|
}
|
|
8604
8601
|
const spinner11 = !opts.json && isInteractive ? clack16.spinner() : null;
|
|
8605
|
-
|
|
8602
|
+
if (spinner11) {
|
|
8603
|
+
spinner11.start("Waiting for InsForge dashboard connection... (timeout: 15 minutes)");
|
|
8604
|
+
} else if (!opts.json) {
|
|
8605
|
+
clack16.log.info("Waiting for InsForge dashboard connection (up to 15 minutes)...");
|
|
8606
|
+
}
|
|
8606
8607
|
try {
|
|
8607
8608
|
await pollPosthogConnection(
|
|
8608
8609
|
projectId,
|
|
@@ -8622,9 +8623,17 @@ async function runConnectFlow(projectId, token, authorizeUrl, opts) {
|
|
|
8622
8623
|
},
|
|
8623
8624
|
opts.apiUrl
|
|
8624
8625
|
);
|
|
8625
|
-
spinner11
|
|
8626
|
+
if (spinner11) {
|
|
8627
|
+
spinner11.stop("InsForge dashboard connection received.");
|
|
8628
|
+
} else if (!opts.json) {
|
|
8629
|
+
clack16.log.success("InsForge dashboard connection received.");
|
|
8630
|
+
}
|
|
8626
8631
|
} catch (err) {
|
|
8627
|
-
spinner11
|
|
8632
|
+
if (spinner11) {
|
|
8633
|
+
spinner11.stop("InsForge dashboard connection wait failed.");
|
|
8634
|
+
} else if (!opts.json) {
|
|
8635
|
+
clack16.log.error("InsForge dashboard connection wait failed.");
|
|
8636
|
+
}
|
|
8628
8637
|
throw err;
|
|
8629
8638
|
}
|
|
8630
8639
|
}
|
|
@@ -9111,7 +9120,9 @@ function configFromMetadata(raw) {
|
|
|
9111
9120
|
function registerConfigExportCommand(cfg) {
|
|
9112
9121
|
cfg.command("export").description("Pull live project config and write insforge.toml").option("--out <path>", "output path", "insforge.toml").option("--force", "overwrite without confirmation").action(async (opts, cmd) => {
|
|
9113
9122
|
const { json } = getRootOpts(cmd);
|
|
9123
|
+
let projectConfig = null;
|
|
9114
9124
|
try {
|
|
9125
|
+
projectConfig = getProjectConfig();
|
|
9115
9126
|
await requireAuth();
|
|
9116
9127
|
const target = resolve5(process.cwd(), opts.out);
|
|
9117
9128
|
if (existsSync10(target) && !opts.force) {
|
|
@@ -9128,6 +9139,12 @@ function registerConfigExportCommand(cfg) {
|
|
|
9128
9139
|
});
|
|
9129
9140
|
if (!ok || p.isCancel(ok)) {
|
|
9130
9141
|
console.log("Aborted.");
|
|
9142
|
+
await reportCliUsage("cli.config.export", true);
|
|
9143
|
+
trackConfig("export", projectConfig, {
|
|
9144
|
+
json_mode: !!json,
|
|
9145
|
+
force: !!opts.force,
|
|
9146
|
+
outcome: "aborted"
|
|
9147
|
+
});
|
|
9131
9148
|
return;
|
|
9132
9149
|
}
|
|
9133
9150
|
}
|
|
@@ -9149,9 +9166,23 @@ function registerConfigExportCommand(cfg) {
|
|
|
9149
9166
|
}
|
|
9150
9167
|
}
|
|
9151
9168
|
await reportCliUsage("cli.config.export", true);
|
|
9169
|
+
trackConfig("export", projectConfig, {
|
|
9170
|
+
json_mode: !!json,
|
|
9171
|
+
force: !!opts.force,
|
|
9172
|
+
skipped_count: skipped.length,
|
|
9173
|
+
outcome: "success"
|
|
9174
|
+
});
|
|
9152
9175
|
} catch (err) {
|
|
9153
9176
|
await reportCliUsage("cli.config.export", false);
|
|
9177
|
+
trackConfig("export", projectConfig, {
|
|
9178
|
+
json_mode: !!json,
|
|
9179
|
+
force: !!opts.force,
|
|
9180
|
+
outcome: "error"
|
|
9181
|
+
});
|
|
9182
|
+
await shutdownAnalytics();
|
|
9154
9183
|
handleError(err, json);
|
|
9184
|
+
} finally {
|
|
9185
|
+
await shutdownAnalytics();
|
|
9155
9186
|
}
|
|
9156
9187
|
});
|
|
9157
9188
|
}
|
|
@@ -9460,7 +9491,9 @@ function authPasswordWireKey(key) {
|
|
|
9460
9491
|
function registerConfigPlanCommand(cfg) {
|
|
9461
9492
|
cfg.command("plan").description("Show diff between insforge.toml and live project state").option("--file <path>", "path to insforge.toml", "insforge.toml").action(async (opts, cmd) => {
|
|
9462
9493
|
const { json } = getRootOpts(cmd);
|
|
9494
|
+
let projectConfig = null;
|
|
9463
9495
|
try {
|
|
9496
|
+
projectConfig = getProjectConfig();
|
|
9464
9497
|
await requireAuth();
|
|
9465
9498
|
const tomlPath = resolve6(process.cwd(), opts.file);
|
|
9466
9499
|
const tomlSource = readFileSync8(tomlPath, "utf8");
|
|
@@ -9483,9 +9516,25 @@ function registerConfigPlanCommand(cfg) {
|
|
|
9483
9516
|
}
|
|
9484
9517
|
}
|
|
9485
9518
|
await reportCliUsage("cli.config.plan", true);
|
|
9519
|
+
trackConfig("plan", projectConfig, {
|
|
9520
|
+
json_mode: !!json,
|
|
9521
|
+
changes_count: result.changes.length,
|
|
9522
|
+
skipped_count: skipped.length,
|
|
9523
|
+
sections_changed: Array.from(
|
|
9524
|
+
new Set(result.changes.map((c) => changePath(c)))
|
|
9525
|
+
),
|
|
9526
|
+
outcome: "success"
|
|
9527
|
+
});
|
|
9486
9528
|
} catch (err) {
|
|
9487
9529
|
await reportCliUsage("cli.config.plan", false);
|
|
9530
|
+
trackConfig("plan", projectConfig, {
|
|
9531
|
+
json_mode: !!json,
|
|
9532
|
+
outcome: "error"
|
|
9533
|
+
});
|
|
9534
|
+
await shutdownAnalytics();
|
|
9488
9535
|
handleError(err, json);
|
|
9536
|
+
} finally {
|
|
9537
|
+
await shutdownAnalytics();
|
|
9489
9538
|
}
|
|
9490
9539
|
});
|
|
9491
9540
|
}
|
|
@@ -9498,7 +9547,9 @@ import pc6 from "picocolors";
|
|
|
9498
9547
|
function registerConfigApplyCommand(cfg) {
|
|
9499
9548
|
cfg.command("apply").description("Apply insforge.toml to the live project").option("--file <path>", "path to insforge.toml", "insforge.toml").option("--dry-run", "show plan, do not apply").option("--auto-approve", "skip confirmation prompt").action(async (opts, cmd) => {
|
|
9500
9549
|
const { json, yes } = getRootOpts(cmd);
|
|
9550
|
+
let projectConfig = null;
|
|
9501
9551
|
try {
|
|
9552
|
+
projectConfig = getProjectConfig();
|
|
9502
9553
|
await requireAuth();
|
|
9503
9554
|
const tomlPath = resolve7(process.cwd(), opts.file);
|
|
9504
9555
|
const tomlSource = readFileSync9(tomlPath, "utf8");
|
|
@@ -9508,6 +9559,9 @@ function registerConfigApplyCommand(cfg) {
|
|
|
9508
9559
|
const live = liveFromMetadata(raw);
|
|
9509
9560
|
const result = diffConfig({ live, file });
|
|
9510
9561
|
const approved = opts.autoApprove || yes;
|
|
9562
|
+
const sectionsChanged = Array.from(
|
|
9563
|
+
new Set(result.changes.map((c) => changePath(c)))
|
|
9564
|
+
);
|
|
9511
9565
|
if (!json) {
|
|
9512
9566
|
console.log(formatPlan(result));
|
|
9513
9567
|
}
|
|
@@ -9518,6 +9572,13 @@ function registerConfigApplyCommand(cfg) {
|
|
|
9518
9572
|
);
|
|
9519
9573
|
}
|
|
9520
9574
|
await reportCliUsage("cli.config.apply", true);
|
|
9575
|
+
trackConfig("apply", projectConfig, {
|
|
9576
|
+
dry_run: !!opts.dryRun,
|
|
9577
|
+
json_mode: !!json,
|
|
9578
|
+
changes_count: result.changes.length,
|
|
9579
|
+
sections_changed: sectionsChanged,
|
|
9580
|
+
outcome: result.changes.length === 0 ? "no_changes" : "dry_run"
|
|
9581
|
+
});
|
|
9521
9582
|
return;
|
|
9522
9583
|
}
|
|
9523
9584
|
if (!approved) {
|
|
@@ -9535,6 +9596,12 @@ function registerConfigApplyCommand(cfg) {
|
|
|
9535
9596
|
if (!ok || p2.isCancel(ok)) {
|
|
9536
9597
|
console.log("Aborted.");
|
|
9537
9598
|
await reportCliUsage("cli.config.apply", true);
|
|
9599
|
+
trackConfig("apply", projectConfig, {
|
|
9600
|
+
json_mode: !!json,
|
|
9601
|
+
changes_count: result.changes.length,
|
|
9602
|
+
sections_changed: sectionsChanged,
|
|
9603
|
+
outcome: "aborted"
|
|
9604
|
+
});
|
|
9538
9605
|
return;
|
|
9539
9606
|
}
|
|
9540
9607
|
}
|
|
@@ -9571,9 +9638,25 @@ function registerConfigApplyCommand(cfg) {
|
|
|
9571
9638
|
}
|
|
9572
9639
|
}
|
|
9573
9640
|
await reportCliUsage("cli.config.apply", true);
|
|
9641
|
+
trackConfig("apply", projectConfig, {
|
|
9642
|
+
auto_approved: !!approved,
|
|
9643
|
+
json_mode: !!json,
|
|
9644
|
+
changes_count: result.changes.length,
|
|
9645
|
+
applied_count: applied.length,
|
|
9646
|
+
skipped_count: skipped.length,
|
|
9647
|
+
sections_changed: sectionsChanged,
|
|
9648
|
+
outcome: applied.length > 0 ? "applied" : "all_skipped"
|
|
9649
|
+
});
|
|
9574
9650
|
} catch (err) {
|
|
9575
9651
|
await reportCliUsage("cli.config.apply", false);
|
|
9652
|
+
trackConfig("apply", projectConfig, {
|
|
9653
|
+
json_mode: !!json,
|
|
9654
|
+
outcome: "error"
|
|
9655
|
+
});
|
|
9656
|
+
await shutdownAnalytics();
|
|
9576
9657
|
handleError(err, json);
|
|
9658
|
+
} finally {
|
|
9659
|
+
await shutdownAnalytics();
|
|
9577
9660
|
}
|
|
9578
9661
|
});
|
|
9579
9662
|
}
|