identityforge
Advanced tools
+20
-1
| import { resolveApiKey, resolveApiUrl } from "./config.js"; | ||
| import { isVersionGreater } from "./updateCheck.js"; | ||
| export const CLI_VERSION = "0.3.7"; | ||
| export const CLI_VERSION = "0.3.8"; | ||
| let apiClient = "cli"; | ||
@@ -345,2 +345,21 @@ /** Select the client identity used by subsequent API requests. */ | ||
| } | ||
| /** | ||
| * Record one completed local apply without sending paths or file contents. | ||
| * This is deliberately best-effort: analytics must never make a successful | ||
| * filesystem write look like a failed apply. | ||
| */ | ||
| export async function recordApplyCompleted(identifier) { | ||
| if (process.env.IDENTITYFORGE_TELEMETRY === "0") | ||
| return; | ||
| try { | ||
| await fetch(`${resolveApiUrl()}/api/v1/kits/${encodeURIComponent(identifier)}/applied`, { | ||
| method: "POST", | ||
| headers: authHeaders(), | ||
| signal: AbortSignal.timeout(1_000), | ||
| }); | ||
| } | ||
| catch { | ||
| // Best-effort telemetry. The kit is already safely written. | ||
| } | ||
| } | ||
| export async function listImageDirections(opts = {}) { | ||
@@ -347,0 +366,0 @@ const qs = new URLSearchParams(); |
+2
-1
| import { createHash } from "node:crypto"; | ||
| import { existsSync, readFileSync, writeFileSync } from "node:fs"; | ||
| import { isAbsolute, join, relative, resolve, sep } from "node:path"; | ||
| import { exportKit, isSafeExportFilename } from "./api.js"; | ||
| import { exportKit, isSafeExportFilename, recordApplyCompleted, } from "./api.js"; | ||
| // Applying a kit writes into someone else's repository, so it is the one place | ||
@@ -378,2 +378,3 @@ // in this CLI that can destroy work. The rule here: never overwrite a file we | ||
| writeFileSync(stampPath, `${JSON.stringify(stamp, null, 2)}\n`, "utf8"); | ||
| await recordApplyCompleted(identity.slug ?? options.slug); | ||
| return { ...result, mode: "applied", overwritten, stamp }; | ||
@@ -380,0 +381,0 @@ } |
+1
-1
| { | ||
| "name": "identityforge", | ||
| "version": "0.3.7", | ||
| "version": "0.3.8", | ||
| "mcpName": "io.identityforge/mcp", | ||
@@ -5,0 +5,0 @@ "description": "Agent-native brand naming, domain research, and design systems through one CLI and MCP server.", |
+4
-1
@@ -443,2 +443,3 @@ # identityforge | ||
| export IDENTITYFORGE_API_URL=https://identityforge.io # override the API base | ||
| export IDENTITYFORGE_TELEMETRY=0 # optional: disable apply-completion counting | ||
| ``` | ||
@@ -448,2 +449,4 @@ | ||
| After a successful local apply, the client sends one metadata-only completion request so aggregate builds can be counted. It includes the kit identifier plus the client name and version already present in every API request. It never sends the repository path or file contents, never changes the apply result, and can be disabled with `IDENTITYFORGE_TELEMETRY=0`. | ||
| Existing design-only keys are not silently upgraded. If a key reports that it is missing `naming:read` or `naming:write`, create a scoped key or run browser login again. | ||
@@ -460,3 +463,3 @@ | ||
| The key is optional. Without it the server still starts and serves free kits. | ||
| The image contains no kit payloads. The key is optional: without one, the server still starts and fetches published Free kits from the Identity Forge platform API. Pro kits, saved work, and writes require an account key. | ||
@@ -463,0 +466,0 @@ ## Links |
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
337147
0.4%5733
0.35%473
0.64%17
6.25%10
11.11%