piezas 0.2.0 → 0.3.0
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/package.json +1 -1
- package/src/index.js +51 -22
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -690,7 +690,8 @@ async function waitForEnvKey(projectDir, timeoutSeconds, intervalMs) {
|
|
|
690
690
|
}
|
|
691
691
|
|
|
692
692
|
// resolveApiKey implements the key-intake precedence:
|
|
693
|
-
// existing .env key > --key flag > process env >
|
|
693
|
+
// existing .env key > --key flag > process env > `piezas login` auto-mint >
|
|
694
|
+
// interactive paste prompt > --wait.
|
|
694
695
|
// Only explicitly provided keys (--key/prompt/wait) may replace an existing
|
|
695
696
|
// .env value; the process env never overrides an already-configured project.
|
|
696
697
|
async function resolveApiKey(envPath, projectDir, options) {
|
|
@@ -709,6 +710,15 @@ async function resolveApiKey(envPath, projectDir, options) {
|
|
|
709
710
|
return { key: processKey, source: 'process-env' };
|
|
710
711
|
}
|
|
711
712
|
|
|
713
|
+
// Signed in via `piezas login`? Create the app and mint its key right here,
|
|
714
|
+
// from the terminal -- no dashboard visit, no copy-paste. This runs BEFORE the
|
|
715
|
+
// manual paste prompt so a logged-in user is never sent to the web UI to fetch
|
|
716
|
+
// a key by hand. Declining the offer falls through to the manual paths below.
|
|
717
|
+
const minted = await resolveKeyViaLogin(projectDir, options);
|
|
718
|
+
if (minted) {
|
|
719
|
+
return minted;
|
|
720
|
+
}
|
|
721
|
+
|
|
712
722
|
if (options.interactive && !options.yes) {
|
|
713
723
|
const promptFn = options.promptFn ?? promptViaTerminal;
|
|
714
724
|
const answer = String((await promptFn(KEY_PROMPT)) ?? '').trim();
|
|
@@ -726,13 +736,6 @@ async function resolveApiKey(envPath, projectDir, options) {
|
|
|
726
736
|
}
|
|
727
737
|
}
|
|
728
738
|
|
|
729
|
-
// Nothing resolved: with a saved `piezas login` session (and a TTY or an
|
|
730
|
-
// explicit --from-login) create the app + mint a key via the platform.
|
|
731
|
-
const minted = await resolveKeyViaLogin(projectDir, options);
|
|
732
|
-
if (minted) {
|
|
733
|
-
return minted;
|
|
734
|
-
}
|
|
735
|
-
|
|
736
739
|
return { key: undefined, source: 'none' };
|
|
737
740
|
}
|
|
738
741
|
|
|
@@ -1055,16 +1058,29 @@ async function resolveKeyViaLogin(projectDir, options) {
|
|
|
1055
1058
|
const credentials = readCredentials(env);
|
|
1056
1059
|
if (!credentials) return undefined;
|
|
1057
1060
|
|
|
1058
|
-
const
|
|
1061
|
+
const flagApp = (typeof options.app === 'string' && options.app.trim())
|
|
1059
1062
|
? options.app.trim()
|
|
1060
|
-
:
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
+
: undefined;
|
|
1064
|
+
const defaultName = flagApp || basename(projectDir);
|
|
1065
|
+
let appName = defaultName;
|
|
1066
|
+
|
|
1067
|
+
// Interactive (and not the non-interactive --from-login shortcut, and no
|
|
1068
|
+
// explicit --app): offer an explicit choice -- create a new app now (which
|
|
1069
|
+
// mints its key for you), or paste a key you already made in the dashboard.
|
|
1070
|
+
// Choosing "paste" (2) returns undefined so the caller falls through to the
|
|
1071
|
+
// paste prompt. Choosing "create" (1, the default) asks for the app name and
|
|
1072
|
+
// mints its key here -- no dashboard visit. An explicit --app skips the menu
|
|
1073
|
+
// and creates that app directly.
|
|
1074
|
+
if (!flagApp && !options.fromLogin && options.interactive && !options.yes) {
|
|
1063
1075
|
const promptFn = options.promptFn ?? promptViaTerminal;
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1076
|
+
log('');
|
|
1077
|
+
log(` Signed in as ${credentials.email}. How would you like to get your API key?`);
|
|
1078
|
+
log(" 1) Create a new app now - we'll mint its key (recommended)");
|
|
1079
|
+
log(' 2) Paste a key you already created in the dashboard');
|
|
1080
|
+
const choice = String((await promptFn(' Choose 1 or 2 [1]: ')) ?? '').trim();
|
|
1081
|
+
if (choice === '2') return undefined;
|
|
1082
|
+
const answer = String((await promptFn(` Name for the new app [${defaultName}]: `)) ?? '').trim();
|
|
1083
|
+
appName = answer || defaultName;
|
|
1068
1084
|
}
|
|
1069
1085
|
|
|
1070
1086
|
const fetchFn = options.fetchFn ?? fetch;
|
|
@@ -1120,7 +1136,7 @@ async function resolveKeyViaLogin(projectDir, options) {
|
|
|
1120
1136
|
return undefined;
|
|
1121
1137
|
}
|
|
1122
1138
|
log(` Minted a live API key for "${app.name}"`);
|
|
1123
|
-
return { key: minted.data.key, source: 'login' };
|
|
1139
|
+
return { key: minted.data.key, source: 'login', appName: app.name };
|
|
1124
1140
|
} catch (error) {
|
|
1125
1141
|
log(` Could not reach Piezas (${error?.message || 'network error'}) - continuing without a key.`);
|
|
1126
1142
|
return undefined;
|
|
@@ -1282,6 +1298,18 @@ async function runInit(options) {
|
|
|
1282
1298
|
}
|
|
1283
1299
|
}
|
|
1284
1300
|
|
|
1301
|
+
// When the app name came from the login prompt (not --app), record it in the
|
|
1302
|
+
// manifest so doctor/agents and the app we just created agree. Cosmetic — the
|
|
1303
|
+
// key is already written — so a write failure here is non-fatal.
|
|
1304
|
+
if (resolved.appName && manifest && manifest.appName !== resolved.appName) {
|
|
1305
|
+
manifest.appName = resolved.appName;
|
|
1306
|
+
try {
|
|
1307
|
+
writeFileSync(manifestPath, `${JSON.stringify(manifest, null, 2)}\n`);
|
|
1308
|
+
} catch {
|
|
1309
|
+
// ignore — manifest metadata is informational
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1285
1313
|
log('\n Done! Your project is set up for Piezas.\n');
|
|
1286
1314
|
log(' Your AI coding agent now knows how to use Piezas:');
|
|
1287
1315
|
log(' Claude Code -> /piezas or reads CLAUDE.md automatically');
|
|
@@ -1292,8 +1320,8 @@ async function runInit(options) {
|
|
|
1292
1320
|
log('');
|
|
1293
1321
|
if (apiKeyStatus === 'missing') {
|
|
1294
1322
|
log(' apiKey: missing');
|
|
1295
|
-
log(
|
|
1296
|
-
log(
|
|
1323
|
+
log(' Easiest: run `npx piezas login`, then re-run `npx piezas init` - it creates your app and API key automatically.');
|
|
1324
|
+
log(` Already have a key? Rerun: npx piezas init --key <key> (or add PIEZAS_API_KEY to ${envPath}).`);
|
|
1297
1325
|
} else if (apiKeyStatus === 'configured') {
|
|
1298
1326
|
log(` apiKey: configured (already in ${envPath})`);
|
|
1299
1327
|
} else {
|
|
@@ -1303,8 +1331,8 @@ async function runInit(options) {
|
|
|
1303
1331
|
log(' Next steps:');
|
|
1304
1332
|
let step = 1;
|
|
1305
1333
|
if (apiKeyStatus === 'missing') {
|
|
1306
|
-
log(` ${step++}.
|
|
1307
|
-
log(` ${step++}.
|
|
1334
|
+
log(` ${step++}. Run \`npx piezas login\`, then re-run \`npx piezas init\` to create your app + key`);
|
|
1335
|
+
log(` ${step++}. (or add an existing PIEZAS_API_KEY=sk_live_xxx to .env, server-side only)`);
|
|
1308
1336
|
}
|
|
1309
1337
|
log(` ${step++}. Run /piezas-spec [idea] or ask for Piezas spec mode`);
|
|
1310
1338
|
log(` ${step++}. After the spec is written, tell your AI agent to code from SPEC.md`);
|
|
@@ -1799,7 +1827,8 @@ function help() {
|
|
|
1799
1827
|
console.log(' --wait Watch the folder for a downloaded .env (.env / .env.download / env.txt)');
|
|
1800
1828
|
console.log(' --wait-timeout <seconds> How long --wait polls before giving up (default 300)');
|
|
1801
1829
|
console.log(' --app <name> App name recorded in piezas.manifest.json (and used for auto-created apps)');
|
|
1802
|
-
console.log(' --from-login
|
|
1830
|
+
console.log(' --from-login Non-interactive: create an app + key from your saved login (CI/agents;');
|
|
1831
|
+
console.log(' interactive `init` already offers this when you are signed in)');
|
|
1803
1832
|
console.log(' --yes Non-interactive: never prompt (for agents/CI)');
|
|
1804
1833
|
console.log(' --json Print a machine-readable JSON summary');
|
|
1805
1834
|
console.log(' --mode next-bff|static|server-runtime|custom-backend');
|