@appfleet-cli/cli 0.1.2 → 0.1.3
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/dist/appfleet.js +368 -21
- package/dist/cloud-session.js +18 -5
- package/dist/command-registry.js +121 -11
- package/dist/local-vault.js +2 -1
- package/dist/project-memory.js +2 -1
- package/package.json +1 -1
package/dist/appfleet.js
CHANGED
|
@@ -3370,10 +3370,58 @@ var program = new Command();
|
|
|
3370
3370
|
|
|
3371
3371
|
// src/appfleet.ts
|
|
3372
3372
|
import { realpathSync } from "node:fs";
|
|
3373
|
+
import { readFile as readFile5 } from "node:fs/promises";
|
|
3374
|
+
import { dirname as dirname5, join as join4 } from "node:path";
|
|
3373
3375
|
import { fileURLToPath } from "node:url";
|
|
3374
3376
|
|
|
3375
3377
|
// src/command-registry.ts
|
|
3376
3378
|
var cliCommandDocs = [
|
|
3379
|
+
{
|
|
3380
|
+
namespace: "appfleet",
|
|
3381
|
+
name: "login",
|
|
3382
|
+
summary: "Sign in to AppFleet Cloud.",
|
|
3383
|
+
usage: "appfleet login [--workspace <workspace-id>] [--email <email>] [--api-base-url <url>] [--local-test] [--json]",
|
|
3384
|
+
arguments: [],
|
|
3385
|
+
options: [
|
|
3386
|
+
{ flags: "--workspace <workspace-id>", description: "Workspace id to sign in to; defaults to workspace_local." },
|
|
3387
|
+
{ flags: "--email <email>", description: "Optional non-secret user label for local-test identity metadata." },
|
|
3388
|
+
{ flags: "--api-base-url <url>", description: "AppFleet API base URL; overrides APPFLEET_API_BASE_URL and the default https://appfleet.xyz." },
|
|
3389
|
+
{ flags: "--local-test", description: "Create local-test session metadata instead of signing in to AppFleet Cloud." },
|
|
3390
|
+
{ flags: "--json", description: "Emit machine-readable JSON." }
|
|
3391
|
+
],
|
|
3392
|
+
examples: [
|
|
3393
|
+
"appfleet login",
|
|
3394
|
+
"appfleet login --workspace workspace_prod",
|
|
3395
|
+
"appfleet login --json"
|
|
3396
|
+
],
|
|
3397
|
+
reads: [".appfleet/cloud-session.json if it already exists"],
|
|
3398
|
+
writes: [".appfleet/cloud-session.json hosted redacted session metadata with status and expiry", ".appfleet/cloud-auth-token mode-0600 local credential file"],
|
|
3399
|
+
secretSafety: [
|
|
3400
|
+
"Opens the hosted browser auth flow and stores session metadata only.",
|
|
3401
|
+
"The short-lived hosted session token is isolated in a mode-0600 local credential file and is never printed or included in project memory.",
|
|
3402
|
+
"Does not store OAuth refresh material, session cookies, provider credentials, encrypted credential blobs, key wrappers, command output, secret fragments, or secret values."
|
|
3403
|
+
]
|
|
3404
|
+
},
|
|
3405
|
+
{
|
|
3406
|
+
namespace: "appfleet",
|
|
3407
|
+
name: "logout",
|
|
3408
|
+
summary: "Sign out of AppFleet Cloud.",
|
|
3409
|
+
usage: "appfleet logout [--api-base-url <url>] [--local-test] [--json]",
|
|
3410
|
+
arguments: [],
|
|
3411
|
+
options: [
|
|
3412
|
+
{ flags: "--api-base-url <url>", description: "AppFleet API base URL; overrides APPFLEET_API_BASE_URL and the default https://appfleet.xyz." },
|
|
3413
|
+
{ flags: "--local-test", description: "Remove local-test session metadata instead of revoking a hosted AppFleet Cloud session." },
|
|
3414
|
+
{ flags: "--json", description: "Emit machine-readable JSON." }
|
|
3415
|
+
],
|
|
3416
|
+
examples: ["appfleet logout", "appfleet logout --json"],
|
|
3417
|
+
reads: [".appfleet/cloud-session.json"],
|
|
3418
|
+
writes: [".appfleet/cloud-session.json and .appfleet/cloud-auth-token are removed when present"],
|
|
3419
|
+
secretSafety: [
|
|
3420
|
+
"Revokes hosted session metadata through AppFleet Cloud when available.",
|
|
3421
|
+
"Removes local hosted session metadata and the local credential file without printing credential material.",
|
|
3422
|
+
"Does not read or print OAuth refresh material, session cookies, provider credentials, encrypted credential blobs, key wrappers, command output, or secret fragments."
|
|
3423
|
+
]
|
|
3424
|
+
},
|
|
3377
3425
|
{
|
|
3378
3426
|
namespace: "appfleet",
|
|
3379
3427
|
name: "link",
|
|
@@ -3389,6 +3437,68 @@ var cliCommandDocs = [
|
|
|
3389
3437
|
"Never uploads environment values, credential values, command output, key wrappers, or provider payloads."
|
|
3390
3438
|
]
|
|
3391
3439
|
},
|
|
3440
|
+
{
|
|
3441
|
+
namespace: "appfleet",
|
|
3442
|
+
name: "doctor",
|
|
3443
|
+
summary: "Run safe diagnostics for a remembered project, optionally uploading the report.",
|
|
3444
|
+
usage: "appfleet doctor [project] [--upload] [--json]",
|
|
3445
|
+
arguments: ["project: project id, path, URL, or repo fingerprint; defaults to the current project when resolvable."],
|
|
3446
|
+
options: [
|
|
3447
|
+
{ flags: "--upload", description: "Upload the safe doctor report to AppFleet Cloud after the local check." },
|
|
3448
|
+
{ flags: "--json", description: "Emit machine-readable JSON." }
|
|
3449
|
+
],
|
|
3450
|
+
examples: [
|
|
3451
|
+
"appfleet doctor appfleet-demo",
|
|
3452
|
+
"appfleet doctor .",
|
|
3453
|
+
"appfleet doctor appfleet-demo --upload"
|
|
3454
|
+
],
|
|
3455
|
+
reads: [".appfleet/project-memory.json", ".appfleet/cloud-session.json when --upload is used"],
|
|
3456
|
+
writes: [".appfleet/project-memory.json latest safe doctor evidence", ".appfleet/cloud-metadata-sync.json when --upload is used"],
|
|
3457
|
+
secretSafety: [
|
|
3458
|
+
"Runs safe URL and metadata checks only.",
|
|
3459
|
+
"Uploads safe project metadata and doctor evidence only when --upload is passed.",
|
|
3460
|
+
"Never reads .env files or uploads environment values, credential values, command output, key wrappers, or provider payloads."
|
|
3461
|
+
]
|
|
3462
|
+
},
|
|
3463
|
+
{
|
|
3464
|
+
namespace: "appfleet",
|
|
3465
|
+
name: "workspaces",
|
|
3466
|
+
summary: "List AppFleet Cloud workspaces available to the signed-in user.",
|
|
3467
|
+
usage: "appfleet workspaces [--api-base-url <url>] [--json]",
|
|
3468
|
+
arguments: [],
|
|
3469
|
+
options: [
|
|
3470
|
+
{ flags: "--api-base-url <url>", description: "AppFleet API base URL; overrides APPFLEET_API_BASE_URL and the default https://appfleet.xyz." },
|
|
3471
|
+
{ flags: "--json", description: "Emit machine-readable JSON." }
|
|
3472
|
+
],
|
|
3473
|
+
examples: ["appfleet workspaces", "appfleet workspaces --json"],
|
|
3474
|
+
reads: [".appfleet/cloud-session.json", ".appfleet/cloud-auth-token"],
|
|
3475
|
+
writes: [],
|
|
3476
|
+
secretSafety: [
|
|
3477
|
+
"Uses the active hosted AppFleet session to list workspace metadata.",
|
|
3478
|
+
"Does not print auth tokens, cookies, provider credentials, environment values, or secret fragments."
|
|
3479
|
+
]
|
|
3480
|
+
},
|
|
3481
|
+
{
|
|
3482
|
+
namespace: "appfleet",
|
|
3483
|
+
name: "workspace",
|
|
3484
|
+
summary: "Show or change the active AppFleet Cloud workspace.",
|
|
3485
|
+
usage: "appfleet workspace current|list|use <workspace-id> [--json]",
|
|
3486
|
+
arguments: [],
|
|
3487
|
+
options: [
|
|
3488
|
+
{ flags: "--json", description: "Emit machine-readable JSON." }
|
|
3489
|
+
],
|
|
3490
|
+
examples: [
|
|
3491
|
+
"appfleet workspace current",
|
|
3492
|
+
"appfleet workspace list",
|
|
3493
|
+
"appfleet workspace use workspace_prod"
|
|
3494
|
+
],
|
|
3495
|
+
reads: [".appfleet/cloud-session.json", ".appfleet/cloud-auth-token"],
|
|
3496
|
+
writes: [".appfleet/cloud-session.json and .appfleet/cloud-auth-token when using a workspace"],
|
|
3497
|
+
secretSafety: [
|
|
3498
|
+
"Workspace use runs the hosted AppFleet login flow for the selected workspace.",
|
|
3499
|
+
"Stores active workspace session metadata only and never prints auth tokens, cookies, provider credentials, or secret fragments."
|
|
3500
|
+
]
|
|
3501
|
+
},
|
|
3392
3502
|
{
|
|
3393
3503
|
namespace: "appfleet",
|
|
3394
3504
|
name: "init",
|
|
@@ -3421,20 +3531,21 @@ var cliCommandDocs = [
|
|
|
3421
3531
|
{
|
|
3422
3532
|
namespace: "auth",
|
|
3423
3533
|
name: "login",
|
|
3424
|
-
summary: "
|
|
3425
|
-
usage: "appfleet auth login [--workspace <workspace-id>] [--email <email>] [--
|
|
3534
|
+
summary: "Sign in to AppFleet Cloud; use --local-test for local scaffold sessions.",
|
|
3535
|
+
usage: "appfleet auth login [--workspace <workspace-id>] [--email <email>] [--api-base-url <url>] [--local-test] [--json]",
|
|
3426
3536
|
arguments: [],
|
|
3427
3537
|
options: [
|
|
3428
3538
|
{ flags: "--workspace <workspace-id>", description: "Workspace id for local-test or hosted session metadata." },
|
|
3429
3539
|
{ flags: "--email <email>", description: "Optional non-secret user label for local-test identity or hosted login metadata." },
|
|
3430
|
-
{ flags: "--
|
|
3540
|
+
{ flags: "--local-test", description: "Create local-test session metadata instead of signing in to AppFleet Cloud." },
|
|
3541
|
+
{ flags: "--production-cloud", description: "Deprecated compatibility flag; hosted AppFleet Cloud is already the default." },
|
|
3431
3542
|
{ flags: "--api-base-url <url>", description: "Production AppFleet API base URL; overrides APPFLEET_API_BASE_URL and the default https://appfleet.xyz." },
|
|
3432
3543
|
{ flags: "--json", description: "Emit machine-readable JSON." }
|
|
3433
3544
|
],
|
|
3434
3545
|
examples: [
|
|
3435
|
-
"appfleet
|
|
3436
|
-
"appfleet auth login --workspace
|
|
3437
|
-
"appfleet auth login --
|
|
3546
|
+
"appfleet login",
|
|
3547
|
+
"appfleet auth login --workspace workspace_prod --json",
|
|
3548
|
+
"appfleet auth login --local-test --workspace workspace_test --email demo@example.com --json"
|
|
3438
3549
|
],
|
|
3439
3550
|
reads: [".appfleet/cloud-session.json if it already exists"],
|
|
3440
3551
|
writes: [".appfleet/cloud-session.json local-test or hosted redacted session metadata with status and expiry"],
|
|
@@ -3447,18 +3558,19 @@ var cliCommandDocs = [
|
|
|
3447
3558
|
{
|
|
3448
3559
|
namespace: "auth",
|
|
3449
3560
|
name: "logout",
|
|
3450
|
-
summary: "
|
|
3451
|
-
usage: "appfleet auth logout [--
|
|
3561
|
+
summary: "Sign out of AppFleet Cloud; use --local-test for local scaffold sessions.",
|
|
3562
|
+
usage: "appfleet auth logout [--api-base-url <url>] [--local-test] [--json]",
|
|
3452
3563
|
arguments: [],
|
|
3453
3564
|
options: [
|
|
3454
|
-
{ flags: "--
|
|
3565
|
+
{ flags: "--local-test", description: "Remove local-test session metadata instead of revoking a hosted AppFleet Cloud session." },
|
|
3566
|
+
{ flags: "--production-cloud", description: "Deprecated compatibility flag; hosted AppFleet Cloud is already the default." },
|
|
3455
3567
|
{ flags: "--api-base-url <url>", description: "Production AppFleet API base URL; overrides APPFLEET_API_BASE_URL and the default https://appfleet.xyz." },
|
|
3456
3568
|
{ flags: "--json", description: "Emit machine-readable JSON." }
|
|
3457
3569
|
],
|
|
3458
3570
|
examples: [
|
|
3459
|
-
"appfleet
|
|
3571
|
+
"appfleet logout",
|
|
3460
3572
|
"appfleet auth logout --json",
|
|
3461
|
-
"appfleet auth logout --
|
|
3573
|
+
"appfleet auth logout --local-test --json"
|
|
3462
3574
|
],
|
|
3463
3575
|
reads: [".appfleet/cloud-session.json"],
|
|
3464
3576
|
writes: [".appfleet/cloud-session.json is removed when present; JSON output includes a safe logged_out/not_found/missing_hosted_session status"],
|
|
@@ -8093,7 +8205,7 @@ function defaultProjectMemoryStorePath(cwd) {
|
|
|
8093
8205
|
function errorMessage2(error) {
|
|
8094
8206
|
return error instanceof Error ? error.message : String(error);
|
|
8095
8207
|
}
|
|
8096
|
-
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
8208
|
+
if (import.meta.url.endsWith("/project-memory.ts") && import.meta.url === `file://${process.argv[1]}`) {
|
|
8097
8209
|
const result = await runProjectMemoryCommand(process.argv.slice(2), {
|
|
8098
8210
|
storePath: process.env.APPFLEET_PROJECT_MEMORY_STORE_PATH,
|
|
8099
8211
|
currentGitRemoteFingerprint: process.env.APPFLEET_GIT_REMOTE_FINGERPRINT
|
|
@@ -8173,7 +8285,7 @@ async function runCloudSessionCommand(argv, options = {}) {
|
|
|
8173
8285
|
createdAt: createdAt3,
|
|
8174
8286
|
result: authResult
|
|
8175
8287
|
});
|
|
8176
|
-
const localAuthToken = authResult.
|
|
8288
|
+
const localAuthToken = authResult.sessionId ?? authResult.authToken;
|
|
8177
8289
|
if (localAuthToken) {
|
|
8178
8290
|
await writeAuthToken(authTokenPath, localAuthToken);
|
|
8179
8291
|
}
|
|
@@ -8793,7 +8905,7 @@ function parseCloudSessionCommand(argv, env) {
|
|
|
8793
8905
|
action,
|
|
8794
8906
|
workspaceId: readFlag4(normalizedArgv, "--workspace") ?? "workspace_local",
|
|
8795
8907
|
email: readFlag4(normalizedArgv, "--email"),
|
|
8796
|
-
productionCloud: cloudProductionFlag(normalizedArgv, env),
|
|
8908
|
+
productionCloud: cloudProductionFlag(normalizedArgv, env, true),
|
|
8797
8909
|
productionCloudSource: cloudProductionSource(normalizedArgv, env),
|
|
8798
8910
|
apiBaseUrl: readFlag4(normalizedArgv, "--api-base-url"),
|
|
8799
8911
|
outputFormat
|
|
@@ -8803,7 +8915,7 @@ function parseCloudSessionCommand(argv, env) {
|
|
|
8803
8915
|
return {
|
|
8804
8916
|
namespace,
|
|
8805
8917
|
action,
|
|
8806
|
-
productionCloud: cloudProductionFlag(normalizedArgv, env),
|
|
8918
|
+
productionCloud: cloudProductionFlag(normalizedArgv, env, true),
|
|
8807
8919
|
productionCloudSource: cloudProductionSource(normalizedArgv, env),
|
|
8808
8920
|
apiBaseUrl: readFlag4(normalizedArgv, "--api-base-url"),
|
|
8809
8921
|
outputFormat
|
|
@@ -9111,16 +9223,28 @@ function createZeroSecretBoundary() {
|
|
|
9111
9223
|
storesSecretFragments: false
|
|
9112
9224
|
};
|
|
9113
9225
|
}
|
|
9114
|
-
function cloudProductionFlag(argv, env) {
|
|
9226
|
+
function cloudProductionFlag(argv, env, defaultProduction = false) {
|
|
9227
|
+
if (hasFlag2(argv, "--local-test")) {
|
|
9228
|
+
return false;
|
|
9229
|
+
}
|
|
9115
9230
|
if (hasFlag2(argv, "--production-cloud")) {
|
|
9116
9231
|
return true;
|
|
9117
9232
|
}
|
|
9118
|
-
|
|
9233
|
+
if (env.APPFLEET_CLOUD_MODE === "local-test") {
|
|
9234
|
+
return false;
|
|
9235
|
+
}
|
|
9236
|
+
return env.APPFLEET_PRODUCTION_CLOUD_ENABLED === "true" || env.APPFLEET_CLOUD_MODE === "production" || defaultProduction;
|
|
9119
9237
|
}
|
|
9120
9238
|
function cloudProductionSource(argv, env) {
|
|
9239
|
+
if (hasFlag2(argv, "--local-test")) {
|
|
9240
|
+
return "flag";
|
|
9241
|
+
}
|
|
9121
9242
|
if (hasFlag2(argv, "--production-cloud")) {
|
|
9122
9243
|
return "flag";
|
|
9123
9244
|
}
|
|
9245
|
+
if (env.APPFLEET_CLOUD_MODE === "local-test") {
|
|
9246
|
+
return "env";
|
|
9247
|
+
}
|
|
9124
9248
|
if (productionEnvEnabled(env)) {
|
|
9125
9249
|
return "env";
|
|
9126
9250
|
}
|
|
@@ -11459,7 +11583,7 @@ function commandError(error) {
|
|
|
11459
11583
|
childStarted: false
|
|
11460
11584
|
};
|
|
11461
11585
|
}
|
|
11462
|
-
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
11586
|
+
if (import.meta.url.endsWith("/local-vault.ts") && import.meta.url === `file://${process.argv[1]}`) {
|
|
11463
11587
|
const result = await runLocalVaultCommand(process.argv.slice(2));
|
|
11464
11588
|
process.stdout.write(result.stdout);
|
|
11465
11589
|
process.stderr.write(result.stderr);
|
|
@@ -11886,6 +12010,7 @@ var namespaces = [
|
|
|
11886
12010
|
"vault",
|
|
11887
12011
|
"secrets"
|
|
11888
12012
|
];
|
|
12013
|
+
var DEFAULT_PRODUCTION_API_BASE_URL2 = "https://appfleet.xyz";
|
|
11889
12014
|
async function runAppFleetCli(argv) {
|
|
11890
12015
|
const normalizedArgv = argv[0] === "--" ? argv.slice(1) : argv;
|
|
11891
12016
|
if (shouldShowHelp(normalizedArgv)) {
|
|
@@ -11899,6 +12024,61 @@ async function runAppFleetCli(argv) {
|
|
|
11899
12024
|
return 0;
|
|
11900
12025
|
}
|
|
11901
12026
|
const namespace = normalizedArgv[0];
|
|
12027
|
+
if (namespace === "login" || namespace === "logout") {
|
|
12028
|
+
const result = await runCloudSessionCommand(
|
|
12029
|
+
["auth", namespace, ...normalizedArgv.slice(1)],
|
|
12030
|
+
cloudCommandOptions()
|
|
12031
|
+
);
|
|
12032
|
+
process.stdout.write(result.stdout);
|
|
12033
|
+
process.stderr.write(result.stderr);
|
|
12034
|
+
return result.exitCode;
|
|
12035
|
+
}
|
|
12036
|
+
if (namespace === "workspaces") {
|
|
12037
|
+
const result = await runWorkspaceListCommand(normalizedArgv.slice(1));
|
|
12038
|
+
process.stdout.write(result.stdout);
|
|
12039
|
+
process.stderr.write(result.stderr);
|
|
12040
|
+
return result.exitCode;
|
|
12041
|
+
}
|
|
12042
|
+
if (namespace === "workspace") {
|
|
12043
|
+
const action = normalizedArgv[1] ?? "current";
|
|
12044
|
+
if (action === "use") {
|
|
12045
|
+
const workspaceId = normalizedArgv[2] ?? readFlag9(normalizedArgv, "--workspace");
|
|
12046
|
+
if (!workspaceId) {
|
|
12047
|
+
process.stderr.write("AppFleet workspace failed: usage: appfleet workspace use <workspace-id> [--json]\n");
|
|
12048
|
+
return 1;
|
|
12049
|
+
}
|
|
12050
|
+
const result = await runCloudSessionCommand(
|
|
12051
|
+
[
|
|
12052
|
+
"auth",
|
|
12053
|
+
"login",
|
|
12054
|
+
"--workspace",
|
|
12055
|
+
workspaceId,
|
|
12056
|
+
...normalizedArgv.includes("--json") ? ["--json"] : []
|
|
12057
|
+
],
|
|
12058
|
+
cloudCommandOptions()
|
|
12059
|
+
);
|
|
12060
|
+
process.stdout.write(result.stdout);
|
|
12061
|
+
process.stderr.write(result.stderr);
|
|
12062
|
+
return result.exitCode;
|
|
12063
|
+
}
|
|
12064
|
+
if (action === "current") {
|
|
12065
|
+
const result = await runWorkspaceCurrentCommand(normalizedArgv.slice(2));
|
|
12066
|
+
process.stdout.write(result.stdout);
|
|
12067
|
+
process.stderr.write(result.stderr);
|
|
12068
|
+
return result.exitCode;
|
|
12069
|
+
}
|
|
12070
|
+
if (action === "list") {
|
|
12071
|
+
const result = await runWorkspaceListCommand(normalizedArgv.slice(2));
|
|
12072
|
+
process.stdout.write(result.stdout);
|
|
12073
|
+
process.stderr.write(result.stderr);
|
|
12074
|
+
return result.exitCode;
|
|
12075
|
+
}
|
|
12076
|
+
process.stderr.write(
|
|
12077
|
+
`AppFleet workspace failed: unknown workspace command "${action}"
|
|
12078
|
+
`
|
|
12079
|
+
);
|
|
12080
|
+
return 1;
|
|
12081
|
+
}
|
|
11902
12082
|
if (namespace === "init") {
|
|
11903
12083
|
const result = await runFirstRunSetup(normalizedArgv.slice(1));
|
|
11904
12084
|
process.stdout.write(result.stdout);
|
|
@@ -11919,6 +12099,20 @@ async function runAppFleetCli(argv) {
|
|
|
11919
12099
|
process.stderr.write(result.stderr);
|
|
11920
12100
|
return result.exitCode;
|
|
11921
12101
|
}
|
|
12102
|
+
if (namespace === "doctor") {
|
|
12103
|
+
const args = ["projects", "doctor", ...normalizedArgv.slice(1)];
|
|
12104
|
+
if (normalizedArgv.includes("--upload")) {
|
|
12105
|
+
return runDoctorAndUpload(args);
|
|
12106
|
+
}
|
|
12107
|
+
const result = await runProjectMemoryCommand(args, {
|
|
12108
|
+
storePath: process.env.APPFLEET_PROJECT_MEMORY_STORE_PATH,
|
|
12109
|
+
currentGitRemoteFingerprint: process.env.APPFLEET_GIT_REMOTE_FINGERPRINT,
|
|
12110
|
+
projectRoot: process.env.INIT_CWD
|
|
12111
|
+
});
|
|
12112
|
+
process.stdout.write(result.stdout);
|
|
12113
|
+
process.stderr.write(result.stderr);
|
|
12114
|
+
return result.exitCode;
|
|
12115
|
+
}
|
|
11922
12116
|
if (namespace === "projects") {
|
|
11923
12117
|
if (normalizedArgv[1] === "doctor" && normalizedArgv.includes("--upload")) {
|
|
11924
12118
|
return runDoctorAndUpload(normalizedArgv);
|
|
@@ -11989,7 +12183,7 @@ async function runAppFleetCli(argv) {
|
|
|
11989
12183
|
}
|
|
11990
12184
|
function createAppFleetProgram() {
|
|
11991
12185
|
const program2 = new Command();
|
|
11992
|
-
program2.name("appfleet").description("
|
|
12186
|
+
program2.name("appfleet").description("AppFleet Cloud CLI for remembering, diagnosing, and recovering projects.").showHelpAfterError().configureHelp({ sortSubcommands: true, sortOptions: true });
|
|
11993
12187
|
const initDoc = findCliCommandDoc("appfleet", "init");
|
|
11994
12188
|
if (initDoc) {
|
|
11995
12189
|
program2.addCommand(commandFromDoc(initDoc));
|
|
@@ -11998,6 +12192,26 @@ function createAppFleetProgram() {
|
|
|
11998
12192
|
if (linkDoc) {
|
|
11999
12193
|
program2.addCommand(commandFromDoc(linkDoc));
|
|
12000
12194
|
}
|
|
12195
|
+
const loginDoc = findCliCommandDoc("appfleet", "login");
|
|
12196
|
+
if (loginDoc) {
|
|
12197
|
+
program2.addCommand(commandFromDoc(loginDoc));
|
|
12198
|
+
}
|
|
12199
|
+
const logoutDoc = findCliCommandDoc("appfleet", "logout");
|
|
12200
|
+
if (logoutDoc) {
|
|
12201
|
+
program2.addCommand(commandFromDoc(logoutDoc));
|
|
12202
|
+
}
|
|
12203
|
+
const doctorDoc = findCliCommandDoc("appfleet", "doctor");
|
|
12204
|
+
if (doctorDoc) {
|
|
12205
|
+
program2.addCommand(commandFromDoc(doctorDoc));
|
|
12206
|
+
}
|
|
12207
|
+
const workspacesDoc = findCliCommandDoc("appfleet", "workspaces");
|
|
12208
|
+
if (workspacesDoc) {
|
|
12209
|
+
program2.addCommand(commandFromDoc(workspacesDoc));
|
|
12210
|
+
}
|
|
12211
|
+
const workspaceDoc = findCliCommandDoc("appfleet", "workspace");
|
|
12212
|
+
if (workspaceDoc) {
|
|
12213
|
+
program2.addCommand(commandFromDoc(workspaceDoc));
|
|
12214
|
+
}
|
|
12001
12215
|
for (const namespace of namespaces) {
|
|
12002
12216
|
const namespaceCommand = new Command(namespace).description(
|
|
12003
12217
|
namespaceDescription(namespace)
|
|
@@ -12020,6 +12234,139 @@ function cloudCommandOptions() {
|
|
|
12020
12234
|
env: process.env
|
|
12021
12235
|
};
|
|
12022
12236
|
}
|
|
12237
|
+
async function runWorkspaceCurrentCommand(argv) {
|
|
12238
|
+
const outputFormat = argv.includes("--json") ? "json" : "human";
|
|
12239
|
+
const session = await readHostedSession();
|
|
12240
|
+
if (!session) {
|
|
12241
|
+
const document2 = {
|
|
12242
|
+
type: "appfleet_active_workspace_result",
|
|
12243
|
+
version: 1,
|
|
12244
|
+
status: "not_logged_in",
|
|
12245
|
+
activeWorkspaceId: void 0,
|
|
12246
|
+
next: "Run appfleet login."
|
|
12247
|
+
};
|
|
12248
|
+
return {
|
|
12249
|
+
exitCode: 1,
|
|
12250
|
+
stdout: outputFormat === "json" ? `${JSON.stringify(document2, null, 2)}
|
|
12251
|
+
` : "",
|
|
12252
|
+
stderr: outputFormat === "json" ? "" : "AppFleet workspace failed: not logged in. Run appfleet login.\n"
|
|
12253
|
+
};
|
|
12254
|
+
}
|
|
12255
|
+
const document = {
|
|
12256
|
+
type: "appfleet_active_workspace_result",
|
|
12257
|
+
version: 1,
|
|
12258
|
+
status: "ok",
|
|
12259
|
+
activeWorkspaceId: session.workspaceId,
|
|
12260
|
+
user: session.user,
|
|
12261
|
+
expiresAt: session.expiresAt
|
|
12262
|
+
};
|
|
12263
|
+
return {
|
|
12264
|
+
exitCode: 0,
|
|
12265
|
+
stdout: outputFormat === "json" ? `${JSON.stringify(document, null, 2)}
|
|
12266
|
+
` : `Active workspace: ${session.workspaceId}
|
|
12267
|
+
`,
|
|
12268
|
+
stderr: ""
|
|
12269
|
+
};
|
|
12270
|
+
}
|
|
12271
|
+
async function runWorkspaceListCommand(argv) {
|
|
12272
|
+
const outputFormat = argv.includes("--json") ? "json" : "human";
|
|
12273
|
+
const session = await readHostedSession();
|
|
12274
|
+
const authToken = await readWorkspaceAuthToken();
|
|
12275
|
+
if (!session || !authToken) {
|
|
12276
|
+
const document2 = {
|
|
12277
|
+
type: "appfleet_workspace_list_result",
|
|
12278
|
+
version: 1,
|
|
12279
|
+
status: "not_logged_in",
|
|
12280
|
+
workspaces: [],
|
|
12281
|
+
next: "Run appfleet login."
|
|
12282
|
+
};
|
|
12283
|
+
return {
|
|
12284
|
+
exitCode: 1,
|
|
12285
|
+
stdout: outputFormat === "json" ? `${JSON.stringify(document2, null, 2)}
|
|
12286
|
+
` : "",
|
|
12287
|
+
stderr: outputFormat === "json" ? "" : "AppFleet workspaces failed: not logged in. Run appfleet login.\n"
|
|
12288
|
+
};
|
|
12289
|
+
}
|
|
12290
|
+
const apiBaseUrl = readFlag9(argv, "--api-base-url") ?? process.env.APPFLEET_API_BASE_URL ?? DEFAULT_PRODUCTION_API_BASE_URL2;
|
|
12291
|
+
const url = new URL("/api/workspaces", apiBaseUrl);
|
|
12292
|
+
url.searchParams.set("workspaceId", session.workspaceId);
|
|
12293
|
+
const response = await fetch(url, {
|
|
12294
|
+
headers: {
|
|
12295
|
+
Accept: "application/json",
|
|
12296
|
+
"X-AppFleet-Hosted-Session": authToken,
|
|
12297
|
+
"X-AppFleet-Workspace-Id": session.workspaceId
|
|
12298
|
+
}
|
|
12299
|
+
});
|
|
12300
|
+
if (!response.ok) {
|
|
12301
|
+
const document2 = {
|
|
12302
|
+
type: "appfleet_workspace_list_result",
|
|
12303
|
+
version: 1,
|
|
12304
|
+
status: "request_failed",
|
|
12305
|
+
httpStatusCode: response.status,
|
|
12306
|
+
activeWorkspaceId: session.workspaceId,
|
|
12307
|
+
workspaces: []
|
|
12308
|
+
};
|
|
12309
|
+
return {
|
|
12310
|
+
exitCode: 1,
|
|
12311
|
+
stdout: outputFormat === "json" ? `${JSON.stringify(document2, null, 2)}
|
|
12312
|
+
` : "",
|
|
12313
|
+
stderr: outputFormat === "json" ? "" : `AppFleet workspaces failed: cloud request returned HTTP ${response.status}.
|
|
12314
|
+
`
|
|
12315
|
+
};
|
|
12316
|
+
}
|
|
12317
|
+
const parsed = await response.json();
|
|
12318
|
+
const workspaces = parsed.data?.workspaces ?? [];
|
|
12319
|
+
const document = {
|
|
12320
|
+
type: "appfleet_workspace_list_result",
|
|
12321
|
+
version: 1,
|
|
12322
|
+
status: "ok",
|
|
12323
|
+
activeWorkspaceId: session.workspaceId,
|
|
12324
|
+
workspaces: workspaces.map((workspace) => ({
|
|
12325
|
+
...workspace,
|
|
12326
|
+
active: workspace.id === session.workspaceId
|
|
12327
|
+
}))
|
|
12328
|
+
};
|
|
12329
|
+
return {
|
|
12330
|
+
exitCode: 0,
|
|
12331
|
+
stdout: outputFormat === "json" ? `${JSON.stringify(document, null, 2)}
|
|
12332
|
+
` : formatWorkspaceList(document),
|
|
12333
|
+
stderr: ""
|
|
12334
|
+
};
|
|
12335
|
+
}
|
|
12336
|
+
function formatWorkspaceList(document) {
|
|
12337
|
+
if (document.workspaces.length === 0) {
|
|
12338
|
+
return "No workspaces found.\n";
|
|
12339
|
+
}
|
|
12340
|
+
return `${document.workspaces.map(
|
|
12341
|
+
(workspace) => `${workspace.active ? "*" : " "} ${workspace.name} (${workspace.id})`
|
|
12342
|
+
).join("\n")}
|
|
12343
|
+
`;
|
|
12344
|
+
}
|
|
12345
|
+
async function readHostedSession() {
|
|
12346
|
+
try {
|
|
12347
|
+
const parsed = JSON.parse(await readFile5(defaultCliSessionPath(), "utf8"));
|
|
12348
|
+
if (!parsed.workspaceId) return void 0;
|
|
12349
|
+
return {
|
|
12350
|
+
type: parsed.type,
|
|
12351
|
+
workspaceId: parsed.workspaceId,
|
|
12352
|
+
user: parsed.user,
|
|
12353
|
+
expiresAt: parsed.expiresAt
|
|
12354
|
+
};
|
|
12355
|
+
} catch {
|
|
12356
|
+
return void 0;
|
|
12357
|
+
}
|
|
12358
|
+
}
|
|
12359
|
+
async function readWorkspaceAuthToken() {
|
|
12360
|
+
try {
|
|
12361
|
+
const token = await readFile5(join4(dirname5(defaultCliSessionPath()), "cloud-auth-token"), "utf8");
|
|
12362
|
+
return token.trim() || void 0;
|
|
12363
|
+
} catch {
|
|
12364
|
+
return void 0;
|
|
12365
|
+
}
|
|
12366
|
+
}
|
|
12367
|
+
function defaultCliSessionPath() {
|
|
12368
|
+
return process.env.APPFLEET_CLOUD_SESSION_PATH ?? join4(process.env.INIT_CWD ?? process.cwd(), ".appfleet", "cloud-session.json");
|
|
12369
|
+
}
|
|
12023
12370
|
async function runDoctorAndUpload(argv) {
|
|
12024
12371
|
const doctorArgs = argv.filter((argument) => argument !== "--upload");
|
|
12025
12372
|
if (!doctorArgs.includes("--json")) doctorArgs.push("--json");
|
|
@@ -12196,9 +12543,9 @@ function namespaceDescription(namespace) {
|
|
|
12196
12543
|
case "projects":
|
|
12197
12544
|
return "Remember projects, summarize recovery status, and run safe diagnostics.";
|
|
12198
12545
|
case "auth":
|
|
12199
|
-
return "Manage
|
|
12546
|
+
return "Manage AppFleet Cloud login sessions.";
|
|
12200
12547
|
case "cloud":
|
|
12201
|
-
return "
|
|
12548
|
+
return "Sync cloud-safe metadata with AppFleet Cloud.";
|
|
12202
12549
|
case "providers":
|
|
12203
12550
|
return "Inspect provider integration contracts and fail-closed discovery scaffolds.";
|
|
12204
12551
|
case "ops":
|
package/dist/cloud-session.js
CHANGED
|
@@ -73,7 +73,7 @@ export async function runCloudSessionCommand(argv, options = {}) {
|
|
|
73
73
|
createdAt,
|
|
74
74
|
result: authResult,
|
|
75
75
|
});
|
|
76
|
-
const localAuthToken = authResult.
|
|
76
|
+
const localAuthToken = authResult.sessionId ?? authResult.authToken;
|
|
77
77
|
if (localAuthToken) {
|
|
78
78
|
await writeAuthToken(authTokenPath, localAuthToken);
|
|
79
79
|
}
|
|
@@ -707,7 +707,7 @@ function parseCloudSessionCommand(argv, env) {
|
|
|
707
707
|
action,
|
|
708
708
|
workspaceId: readFlag(normalizedArgv, "--workspace") ?? "workspace_local",
|
|
709
709
|
email: readFlag(normalizedArgv, "--email"),
|
|
710
|
-
productionCloud: cloudProductionFlag(normalizedArgv, env),
|
|
710
|
+
productionCloud: cloudProductionFlag(normalizedArgv, env, true),
|
|
711
711
|
productionCloudSource: cloudProductionSource(normalizedArgv, env),
|
|
712
712
|
apiBaseUrl: readFlag(normalizedArgv, "--api-base-url"),
|
|
713
713
|
outputFormat,
|
|
@@ -717,7 +717,7 @@ function parseCloudSessionCommand(argv, env) {
|
|
|
717
717
|
return {
|
|
718
718
|
namespace,
|
|
719
719
|
action,
|
|
720
|
-
productionCloud: cloudProductionFlag(normalizedArgv, env),
|
|
720
|
+
productionCloud: cloudProductionFlag(normalizedArgv, env, true),
|
|
721
721
|
productionCloudSource: cloudProductionSource(normalizedArgv, env),
|
|
722
722
|
apiBaseUrl: readFlag(normalizedArgv, "--api-base-url"),
|
|
723
723
|
outputFormat,
|
|
@@ -1015,17 +1015,30 @@ function createZeroSecretBoundary() {
|
|
|
1015
1015
|
storesSecretFragments: false,
|
|
1016
1016
|
};
|
|
1017
1017
|
}
|
|
1018
|
-
function cloudProductionFlag(argv, env) {
|
|
1018
|
+
function cloudProductionFlag(argv, env, defaultProduction = false) {
|
|
1019
|
+
if (hasFlag(argv, "--local-test")) {
|
|
1020
|
+
return false;
|
|
1021
|
+
}
|
|
1019
1022
|
if (hasFlag(argv, "--production-cloud")) {
|
|
1020
1023
|
return true;
|
|
1021
1024
|
}
|
|
1025
|
+
if (env.APPFLEET_CLOUD_MODE === "local-test") {
|
|
1026
|
+
return false;
|
|
1027
|
+
}
|
|
1022
1028
|
return (env.APPFLEET_PRODUCTION_CLOUD_ENABLED === "true" ||
|
|
1023
|
-
env.APPFLEET_CLOUD_MODE === "production"
|
|
1029
|
+
env.APPFLEET_CLOUD_MODE === "production" ||
|
|
1030
|
+
defaultProduction);
|
|
1024
1031
|
}
|
|
1025
1032
|
function cloudProductionSource(argv, env) {
|
|
1033
|
+
if (hasFlag(argv, "--local-test")) {
|
|
1034
|
+
return "flag";
|
|
1035
|
+
}
|
|
1026
1036
|
if (hasFlag(argv, "--production-cloud")) {
|
|
1027
1037
|
return "flag";
|
|
1028
1038
|
}
|
|
1039
|
+
if (env.APPFLEET_CLOUD_MODE === "local-test") {
|
|
1040
|
+
return "env";
|
|
1041
|
+
}
|
|
1029
1042
|
if (productionEnvEnabled(env)) {
|
|
1030
1043
|
return "env";
|
|
1031
1044
|
}
|
package/dist/command-registry.js
CHANGED
|
@@ -1,4 +1,50 @@
|
|
|
1
1
|
export const cliCommandDocs = [
|
|
2
|
+
{
|
|
3
|
+
namespace: "appfleet",
|
|
4
|
+
name: "login",
|
|
5
|
+
summary: "Sign in to AppFleet Cloud.",
|
|
6
|
+
usage: "appfleet login [--workspace <workspace-id>] [--email <email>] [--api-base-url <url>] [--local-test] [--json]",
|
|
7
|
+
arguments: [],
|
|
8
|
+
options: [
|
|
9
|
+
{ flags: "--workspace <workspace-id>", description: "Workspace id to sign in to; defaults to workspace_local." },
|
|
10
|
+
{ flags: "--email <email>", description: "Optional non-secret user label for local-test identity metadata." },
|
|
11
|
+
{ flags: "--api-base-url <url>", description: "AppFleet API base URL; overrides APPFLEET_API_BASE_URL and the default https://appfleet.xyz." },
|
|
12
|
+
{ flags: "--local-test", description: "Create local-test session metadata instead of signing in to AppFleet Cloud." },
|
|
13
|
+
{ flags: "--json", description: "Emit machine-readable JSON." },
|
|
14
|
+
],
|
|
15
|
+
examples: [
|
|
16
|
+
"appfleet login",
|
|
17
|
+
"appfleet login --workspace workspace_prod",
|
|
18
|
+
"appfleet login --json",
|
|
19
|
+
],
|
|
20
|
+
reads: [".appfleet/cloud-session.json if it already exists"],
|
|
21
|
+
writes: [".appfleet/cloud-session.json hosted redacted session metadata with status and expiry", ".appfleet/cloud-auth-token mode-0600 local credential file"],
|
|
22
|
+
secretSafety: [
|
|
23
|
+
"Opens the hosted browser auth flow and stores session metadata only.",
|
|
24
|
+
"The short-lived hosted session token is isolated in a mode-0600 local credential file and is never printed or included in project memory.",
|
|
25
|
+
"Does not store OAuth refresh material, session cookies, provider credentials, encrypted credential blobs, key wrappers, command output, secret fragments, or secret values.",
|
|
26
|
+
],
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
namespace: "appfleet",
|
|
30
|
+
name: "logout",
|
|
31
|
+
summary: "Sign out of AppFleet Cloud.",
|
|
32
|
+
usage: "appfleet logout [--api-base-url <url>] [--local-test] [--json]",
|
|
33
|
+
arguments: [],
|
|
34
|
+
options: [
|
|
35
|
+
{ flags: "--api-base-url <url>", description: "AppFleet API base URL; overrides APPFLEET_API_BASE_URL and the default https://appfleet.xyz." },
|
|
36
|
+
{ flags: "--local-test", description: "Remove local-test session metadata instead of revoking a hosted AppFleet Cloud session." },
|
|
37
|
+
{ flags: "--json", description: "Emit machine-readable JSON." },
|
|
38
|
+
],
|
|
39
|
+
examples: ["appfleet logout", "appfleet logout --json"],
|
|
40
|
+
reads: [".appfleet/cloud-session.json"],
|
|
41
|
+
writes: [".appfleet/cloud-session.json and .appfleet/cloud-auth-token are removed when present"],
|
|
42
|
+
secretSafety: [
|
|
43
|
+
"Revokes hosted session metadata through AppFleet Cloud when available.",
|
|
44
|
+
"Removes local hosted session metadata and the local credential file without printing credential material.",
|
|
45
|
+
"Does not read or print OAuth refresh material, session cookies, provider credentials, encrypted credential blobs, key wrappers, command output, or secret fragments.",
|
|
46
|
+
],
|
|
47
|
+
},
|
|
2
48
|
{
|
|
3
49
|
namespace: "appfleet",
|
|
4
50
|
name: "link",
|
|
@@ -14,6 +60,68 @@ export const cliCommandDocs = [
|
|
|
14
60
|
"Never uploads environment values, credential values, command output, key wrappers, or provider payloads.",
|
|
15
61
|
],
|
|
16
62
|
},
|
|
63
|
+
{
|
|
64
|
+
namespace: "appfleet",
|
|
65
|
+
name: "doctor",
|
|
66
|
+
summary: "Run safe diagnostics for a remembered project, optionally uploading the report.",
|
|
67
|
+
usage: "appfleet doctor [project] [--upload] [--json]",
|
|
68
|
+
arguments: ["project: project id, path, URL, or repo fingerprint; defaults to the current project when resolvable."],
|
|
69
|
+
options: [
|
|
70
|
+
{ flags: "--upload", description: "Upload the safe doctor report to AppFleet Cloud after the local check." },
|
|
71
|
+
{ flags: "--json", description: "Emit machine-readable JSON." },
|
|
72
|
+
],
|
|
73
|
+
examples: [
|
|
74
|
+
"appfleet doctor appfleet-demo",
|
|
75
|
+
"appfleet doctor .",
|
|
76
|
+
"appfleet doctor appfleet-demo --upload",
|
|
77
|
+
],
|
|
78
|
+
reads: [".appfleet/project-memory.json", ".appfleet/cloud-session.json when --upload is used"],
|
|
79
|
+
writes: [".appfleet/project-memory.json latest safe doctor evidence", ".appfleet/cloud-metadata-sync.json when --upload is used"],
|
|
80
|
+
secretSafety: [
|
|
81
|
+
"Runs safe URL and metadata checks only.",
|
|
82
|
+
"Uploads safe project metadata and doctor evidence only when --upload is passed.",
|
|
83
|
+
"Never reads .env files or uploads environment values, credential values, command output, key wrappers, or provider payloads.",
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
namespace: "appfleet",
|
|
88
|
+
name: "workspaces",
|
|
89
|
+
summary: "List AppFleet Cloud workspaces available to the signed-in user.",
|
|
90
|
+
usage: "appfleet workspaces [--api-base-url <url>] [--json]",
|
|
91
|
+
arguments: [],
|
|
92
|
+
options: [
|
|
93
|
+
{ flags: "--api-base-url <url>", description: "AppFleet API base URL; overrides APPFLEET_API_BASE_URL and the default https://appfleet.xyz." },
|
|
94
|
+
{ flags: "--json", description: "Emit machine-readable JSON." },
|
|
95
|
+
],
|
|
96
|
+
examples: ["appfleet workspaces", "appfleet workspaces --json"],
|
|
97
|
+
reads: [".appfleet/cloud-session.json", ".appfleet/cloud-auth-token"],
|
|
98
|
+
writes: [],
|
|
99
|
+
secretSafety: [
|
|
100
|
+
"Uses the active hosted AppFleet session to list workspace metadata.",
|
|
101
|
+
"Does not print auth tokens, cookies, provider credentials, environment values, or secret fragments.",
|
|
102
|
+
],
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
namespace: "appfleet",
|
|
106
|
+
name: "workspace",
|
|
107
|
+
summary: "Show or change the active AppFleet Cloud workspace.",
|
|
108
|
+
usage: "appfleet workspace current|list|use <workspace-id> [--json]",
|
|
109
|
+
arguments: [],
|
|
110
|
+
options: [
|
|
111
|
+
{ flags: "--json", description: "Emit machine-readable JSON." },
|
|
112
|
+
],
|
|
113
|
+
examples: [
|
|
114
|
+
"appfleet workspace current",
|
|
115
|
+
"appfleet workspace list",
|
|
116
|
+
"appfleet workspace use workspace_prod",
|
|
117
|
+
],
|
|
118
|
+
reads: [".appfleet/cloud-session.json", ".appfleet/cloud-auth-token"],
|
|
119
|
+
writes: [".appfleet/cloud-session.json and .appfleet/cloud-auth-token when using a workspace"],
|
|
120
|
+
secretSafety: [
|
|
121
|
+
"Workspace use runs the hosted AppFleet login flow for the selected workspace.",
|
|
122
|
+
"Stores active workspace session metadata only and never prints auth tokens, cookies, provider credentials, or secret fragments.",
|
|
123
|
+
],
|
|
124
|
+
},
|
|
17
125
|
{
|
|
18
126
|
namespace: "appfleet",
|
|
19
127
|
name: "init",
|
|
@@ -46,20 +154,21 @@ export const cliCommandDocs = [
|
|
|
46
154
|
{
|
|
47
155
|
namespace: "auth",
|
|
48
156
|
name: "login",
|
|
49
|
-
summary: "
|
|
50
|
-
usage: "appfleet auth login [--workspace <workspace-id>] [--email <email>] [--
|
|
157
|
+
summary: "Sign in to AppFleet Cloud; use --local-test for local scaffold sessions.",
|
|
158
|
+
usage: "appfleet auth login [--workspace <workspace-id>] [--email <email>] [--api-base-url <url>] [--local-test] [--json]",
|
|
51
159
|
arguments: [],
|
|
52
160
|
options: [
|
|
53
161
|
{ flags: "--workspace <workspace-id>", description: "Workspace id for local-test or hosted session metadata." },
|
|
54
162
|
{ flags: "--email <email>", description: "Optional non-secret user label for local-test identity or hosted login metadata." },
|
|
55
|
-
{ flags: "--
|
|
163
|
+
{ flags: "--local-test", description: "Create local-test session metadata instead of signing in to AppFleet Cloud." },
|
|
164
|
+
{ flags: "--production-cloud", description: "Deprecated compatibility flag; hosted AppFleet Cloud is already the default." },
|
|
56
165
|
{ flags: "--api-base-url <url>", description: "Production AppFleet API base URL; overrides APPFLEET_API_BASE_URL and the default https://appfleet.xyz." },
|
|
57
166
|
{ flags: "--json", description: "Emit machine-readable JSON." },
|
|
58
167
|
],
|
|
59
168
|
examples: [
|
|
60
|
-
"appfleet
|
|
61
|
-
"appfleet auth login --workspace
|
|
62
|
-
"appfleet auth login --
|
|
169
|
+
"appfleet login",
|
|
170
|
+
"appfleet auth login --workspace workspace_prod --json",
|
|
171
|
+
"appfleet auth login --local-test --workspace workspace_test --email demo@example.com --json",
|
|
63
172
|
],
|
|
64
173
|
reads: [".appfleet/cloud-session.json if it already exists"],
|
|
65
174
|
writes: [".appfleet/cloud-session.json local-test or hosted redacted session metadata with status and expiry"],
|
|
@@ -72,18 +181,19 @@ export const cliCommandDocs = [
|
|
|
72
181
|
{
|
|
73
182
|
namespace: "auth",
|
|
74
183
|
name: "logout",
|
|
75
|
-
summary: "
|
|
76
|
-
usage: "appfleet auth logout [--
|
|
184
|
+
summary: "Sign out of AppFleet Cloud; use --local-test for local scaffold sessions.",
|
|
185
|
+
usage: "appfleet auth logout [--api-base-url <url>] [--local-test] [--json]",
|
|
77
186
|
arguments: [],
|
|
78
187
|
options: [
|
|
79
|
-
{ flags: "--
|
|
188
|
+
{ flags: "--local-test", description: "Remove local-test session metadata instead of revoking a hosted AppFleet Cloud session." },
|
|
189
|
+
{ flags: "--production-cloud", description: "Deprecated compatibility flag; hosted AppFleet Cloud is already the default." },
|
|
80
190
|
{ flags: "--api-base-url <url>", description: "Production AppFleet API base URL; overrides APPFLEET_API_BASE_URL and the default https://appfleet.xyz." },
|
|
81
191
|
{ flags: "--json", description: "Emit machine-readable JSON." },
|
|
82
192
|
],
|
|
83
193
|
examples: [
|
|
84
|
-
"appfleet
|
|
194
|
+
"appfleet logout",
|
|
85
195
|
"appfleet auth logout --json",
|
|
86
|
-
"appfleet auth logout --
|
|
196
|
+
"appfleet auth logout --local-test --json",
|
|
87
197
|
],
|
|
88
198
|
reads: [".appfleet/cloud-session.json"],
|
|
89
199
|
writes: [".appfleet/cloud-session.json is removed when present; JSON output includes a safe logged_out/not_found/missing_hosted_session status"],
|
package/dist/local-vault.js
CHANGED
|
@@ -1161,7 +1161,8 @@ function commandError(error) {
|
|
|
1161
1161
|
childStarted: false,
|
|
1162
1162
|
};
|
|
1163
1163
|
}
|
|
1164
|
-
if (import.meta.url
|
|
1164
|
+
if (import.meta.url.endsWith("/local-vault.ts") &&
|
|
1165
|
+
import.meta.url === `file://${process.argv[1]}`) {
|
|
1165
1166
|
const result = await runLocalVaultCommand(process.argv.slice(2));
|
|
1166
1167
|
process.stdout.write(result.stdout);
|
|
1167
1168
|
process.stderr.write(result.stderr);
|
package/dist/project-memory.js
CHANGED
|
@@ -1518,7 +1518,8 @@ function defaultProjectMemoryStorePath(cwd) {
|
|
|
1518
1518
|
function errorMessage(error) {
|
|
1519
1519
|
return error instanceof Error ? error.message : String(error);
|
|
1520
1520
|
}
|
|
1521
|
-
if (import.meta.url
|
|
1521
|
+
if (import.meta.url.endsWith("/project-memory.ts") &&
|
|
1522
|
+
import.meta.url === `file://${process.argv[1]}`) {
|
|
1522
1523
|
const result = await runProjectMemoryCommand(process.argv.slice(2), {
|
|
1523
1524
|
storePath: process.env.APPFLEET_PROJECT_MEMORY_STORE_PATH,
|
|
1524
1525
|
currentGitRemoteFingerprint: process.env.APPFLEET_GIT_REMOTE_FINGERPRINT,
|