@appfleet-cli/cli 0.1.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/README.md +14 -0
- package/dist/appfleet.d.ts +4 -0
- package/dist/appfleet.js +12253 -0
- package/dist/audit.d.ts +10 -0
- package/dist/audit.js +85 -0
- package/dist/billing-cost.d.ts +8 -0
- package/dist/billing-cost.js +186 -0
- package/dist/cloud-session.d.ts +124 -0
- package/dist/cloud-session.js +1819 -0
- package/dist/command-registry.d.ts +18 -0
- package/dist/command-registry.js +1067 -0
- package/dist/demo-fixture.d.ts +11 -0
- package/dist/demo-fixture.js +39 -0
- package/dist/generate-cli-docs.d.ts +1 -0
- package/dist/generate-cli-docs.js +94 -0
- package/dist/health.d.ts +8 -0
- package/dist/health.js +60 -0
- package/dist/local-vault.d.ts +75 -0
- package/dist/local-vault.js +1169 -0
- package/dist/operations.d.ts +8 -0
- package/dist/operations.js +220 -0
- package/dist/project-memory.d.ts +138 -0
- package/dist/project-memory.js +1529 -0
- package/dist/prototype-inject.d.ts +21 -0
- package/dist/prototype-inject.js +170 -0
- package/dist/provider-integrations.d.ts +8 -0
- package/dist/provider-integrations.js +197 -0
- package/package.json +45 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { CredentialBlobEnvelope, KeyWrapperEnvelope } from "@appfleet/crypto";
|
|
2
|
+
export type PrototypeSecretFixture = {
|
|
3
|
+
project: string;
|
|
4
|
+
environment: string;
|
|
5
|
+
alias: string;
|
|
6
|
+
workspaceId: string;
|
|
7
|
+
masterPassword: string;
|
|
8
|
+
credentialEnvelope: CredentialBlobEnvelope;
|
|
9
|
+
keyWrapperEnvelope: KeyWrapperEnvelope;
|
|
10
|
+
};
|
|
11
|
+
export declare const demoSecretFixture: PrototypeSecretFixture;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export const demoSecretFixture = {
|
|
2
|
+
project: "demo-project",
|
|
3
|
+
environment: "dev",
|
|
4
|
+
alias: "APPFLEET_DEMO_SECRET",
|
|
5
|
+
workspaceId: "workspace_demo_local",
|
|
6
|
+
masterPassword: "appfleet-demo-master-password",
|
|
7
|
+
credentialEnvelope: {
|
|
8
|
+
type: "credential_blob",
|
|
9
|
+
envelopeVersion: 1,
|
|
10
|
+
algorithmId: "xchacha20poly1305-ietf",
|
|
11
|
+
workspaceId: "workspace_demo_local",
|
|
12
|
+
recordId: "credential_demo_openai_api_key",
|
|
13
|
+
keyGenerationId: "kg_demo_2026_05_27",
|
|
14
|
+
nonce: "28X7GCBkU0v_JBgrRSezamOlQxT4AU4L",
|
|
15
|
+
ciphertext: "U-TuenGLVQbs857WEf8qkWsGN4X9Ro6wEsUzbLkj7E4HHP3Ai-uO-qOm",
|
|
16
|
+
createdAt: "2026-05-27T12:00:00.000Z",
|
|
17
|
+
},
|
|
18
|
+
keyWrapperEnvelope: {
|
|
19
|
+
type: "key_wrapper",
|
|
20
|
+
envelopeVersion: 1,
|
|
21
|
+
algorithmId: "xchacha20poly1305-ietf",
|
|
22
|
+
workspaceId: "workspace_demo_local",
|
|
23
|
+
wrapperId: "wrapper_demo_master_password",
|
|
24
|
+
wrappedKeyId: "workspace_vault_key_demo_1",
|
|
25
|
+
keyGenerationId: "kg_demo_2026_05_27",
|
|
26
|
+
nonce: "z2SmjwlZyrdgrr1xwgdCWSmJLvuTPUPM",
|
|
27
|
+
salt: "hpcmtZiQE6tUpmjswhuxlg",
|
|
28
|
+
kdf: {
|
|
29
|
+
name: "argon2id",
|
|
30
|
+
algorithm: "argon2id13",
|
|
31
|
+
memoryBytes: 67108864,
|
|
32
|
+
operations: 3,
|
|
33
|
+
parallelism: 1,
|
|
34
|
+
outputBytes: 32,
|
|
35
|
+
},
|
|
36
|
+
ciphertext: "6MSTR3-VBVB52MXKu0E22lmiGKkEiHB2OVuf1i2mwcTpu7uvjmMuNgnvfUDeVbvO",
|
|
37
|
+
createdAt: "2026-05-27T12:00:00.000Z",
|
|
38
|
+
},
|
|
39
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function renderCliDocs(): string;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import { cliCommandDocs } from "./command-registry.js";
|
|
4
|
+
const docsPath = resolve(process.cwd(), "..", "..", "docs", "cli.md");
|
|
5
|
+
export function renderCliDocs() {
|
|
6
|
+
const lines = [
|
|
7
|
+
"# AppFleet CLI Reference",
|
|
8
|
+
"",
|
|
9
|
+
"This file is generated from the CLI command registry.",
|
|
10
|
+
"",
|
|
11
|
+
"Run `pnpm --filter @appfleet-cli/cli docs:generate` after changing command metadata.",
|
|
12
|
+
"",
|
|
13
|
+
"The CLI is the production local execution boundary for AppFleet. It handles local unlock, decrypt, and secret injection on the user's machine, while hosted auth, cloud metadata sync, provider contracts, and audit flows are explicit, authenticated, and secret-safe.",
|
|
14
|
+
"",
|
|
15
|
+
];
|
|
16
|
+
for (const command of cliCommandDocs) {
|
|
17
|
+
lines.push(`## ${command.namespace} ${command.name}`);
|
|
18
|
+
lines.push("");
|
|
19
|
+
lines.push(command.summary);
|
|
20
|
+
lines.push("");
|
|
21
|
+
lines.push("### Usage");
|
|
22
|
+
lines.push("");
|
|
23
|
+
lines.push("```sh");
|
|
24
|
+
lines.push(command.usage);
|
|
25
|
+
lines.push("```");
|
|
26
|
+
lines.push("");
|
|
27
|
+
if (command.arguments.length > 0) {
|
|
28
|
+
lines.push("### Arguments");
|
|
29
|
+
lines.push("");
|
|
30
|
+
for (const argument of command.arguments) {
|
|
31
|
+
lines.push(`- ${argument}`);
|
|
32
|
+
}
|
|
33
|
+
lines.push("");
|
|
34
|
+
}
|
|
35
|
+
if (command.options.length > 0) {
|
|
36
|
+
lines.push("### Options");
|
|
37
|
+
lines.push("");
|
|
38
|
+
for (const option of command.options) {
|
|
39
|
+
lines.push(`- \`${option.flags}\`: ${option.description}`);
|
|
40
|
+
}
|
|
41
|
+
lines.push("");
|
|
42
|
+
}
|
|
43
|
+
if (command.examples.length > 0) {
|
|
44
|
+
lines.push("### Examples");
|
|
45
|
+
lines.push("");
|
|
46
|
+
lines.push("```sh");
|
|
47
|
+
lines.push(...command.examples);
|
|
48
|
+
lines.push("```");
|
|
49
|
+
lines.push("");
|
|
50
|
+
}
|
|
51
|
+
if (command.reads.length > 0) {
|
|
52
|
+
lines.push("### Reads");
|
|
53
|
+
lines.push("");
|
|
54
|
+
for (const value of command.reads) {
|
|
55
|
+
lines.push(`- ${value}`);
|
|
56
|
+
}
|
|
57
|
+
lines.push("");
|
|
58
|
+
}
|
|
59
|
+
if (command.writes.length > 0) {
|
|
60
|
+
lines.push("### Writes");
|
|
61
|
+
lines.push("");
|
|
62
|
+
for (const value of command.writes) {
|
|
63
|
+
lines.push(`- ${value}`);
|
|
64
|
+
}
|
|
65
|
+
lines.push("");
|
|
66
|
+
}
|
|
67
|
+
lines.push("### Secret Safety");
|
|
68
|
+
lines.push("");
|
|
69
|
+
for (const value of command.secretSafety) {
|
|
70
|
+
lines.push(`- ${value}`);
|
|
71
|
+
}
|
|
72
|
+
lines.push("");
|
|
73
|
+
}
|
|
74
|
+
return `${lines.join("\n").trimEnd()}\n`;
|
|
75
|
+
}
|
|
76
|
+
async function main() {
|
|
77
|
+
const mode = process.argv.includes("--check") ? "check" : "generate";
|
|
78
|
+
const rendered = renderCliDocs();
|
|
79
|
+
if (mode === "check") {
|
|
80
|
+
const current = await readFile(docsPath, "utf8");
|
|
81
|
+
if (current !== rendered) {
|
|
82
|
+
process.stderr.write("AppFleet CLI docs are stale. Run `pnpm --filter @appfleet-cli/cli docs:generate`.\n");
|
|
83
|
+
return 1;
|
|
84
|
+
}
|
|
85
|
+
process.stdout.write("AppFleet CLI docs are current.\n");
|
|
86
|
+
return 0;
|
|
87
|
+
}
|
|
88
|
+
await writeFile(docsPath, rendered);
|
|
89
|
+
process.stdout.write(`Generated ${docsPath}\n`);
|
|
90
|
+
return 0;
|
|
91
|
+
}
|
|
92
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
93
|
+
process.exitCode = await main();
|
|
94
|
+
}
|
package/dist/health.d.ts
ADDED
package/dist/health.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { createCronHeartbeatContract, createHealthSchedulerContract, } from "@appfleet/domain";
|
|
2
|
+
export async function runHealthCommand(argv, options = {}) {
|
|
3
|
+
const normalizedArgv = argv[0] === "--" ? argv.slice(1) : argv;
|
|
4
|
+
if (normalizedArgv[0] !== "health" || normalizedArgv[1] !== "schedule") {
|
|
5
|
+
return {
|
|
6
|
+
exitCode: 1,
|
|
7
|
+
stdout: "",
|
|
8
|
+
stderr: "AppFleet health failed: usage: health schedule [--workspace <workspace-id>] [--json]\n",
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
const workspaceId = readFlag(normalizedArgv, "--workspace") ?? "workspace_local";
|
|
12
|
+
const now = (options.now ?? (() => new Date()))().toISOString();
|
|
13
|
+
const scheduler = createHealthSchedulerContract({
|
|
14
|
+
workspaceId,
|
|
15
|
+
scheduleId: "stored_public_health",
|
|
16
|
+
cadence: "manual",
|
|
17
|
+
});
|
|
18
|
+
const cronHeartbeat = createCronHeartbeatContract({
|
|
19
|
+
workspaceId,
|
|
20
|
+
scheduleId: scheduler.scheduleId,
|
|
21
|
+
heartbeatId: "stored_public_health_heartbeat",
|
|
22
|
+
expectedEveryMinutes: 24 * 60,
|
|
23
|
+
now,
|
|
24
|
+
});
|
|
25
|
+
const document = {
|
|
26
|
+
type: "health_schedule_contract_result",
|
|
27
|
+
version: 1,
|
|
28
|
+
scheduler,
|
|
29
|
+
cronHeartbeat,
|
|
30
|
+
providerApiCallsMade: false,
|
|
31
|
+
envFilesRead: false,
|
|
32
|
+
containsCredentialValues: false,
|
|
33
|
+
containsProviderPayload: false,
|
|
34
|
+
trustBoundary: scheduler.trustBoundary,
|
|
35
|
+
};
|
|
36
|
+
return {
|
|
37
|
+
exitCode: 0,
|
|
38
|
+
stdout: normalizedArgv.includes("--json")
|
|
39
|
+
? `${JSON.stringify(document, null, 2)}\n`
|
|
40
|
+
: `${[
|
|
41
|
+
"AppFleet health schedule: safe scheduler contract ready.",
|
|
42
|
+
`workspaceId=${workspaceId}`,
|
|
43
|
+
`scheduleId=${scheduler.scheduleId}`,
|
|
44
|
+
`cadence=${scheduler.cadence}`,
|
|
45
|
+
`heartbeatStatus=${cronHeartbeat.status}`,
|
|
46
|
+
"providerApiCallsMade=false",
|
|
47
|
+
"envFilesRead=false",
|
|
48
|
+
"trustBoundary:",
|
|
49
|
+
...scheduler.trustBoundary.map((item) => `- ${item}`),
|
|
50
|
+
].join("\n")}\n`,
|
|
51
|
+
stderr: "",
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function readFlag(argv, flag) {
|
|
55
|
+
const index = argv.indexOf(flag);
|
|
56
|
+
if (index === -1) {
|
|
57
|
+
return undefined;
|
|
58
|
+
}
|
|
59
|
+
return argv[index + 1];
|
|
60
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { type AppCredentialStatus, type AppOsKeychainIntegrationMetadata } from "@appfleet/domain";
|
|
2
|
+
type ParsedLocalVaultCommand = {
|
|
3
|
+
action: "vault-init";
|
|
4
|
+
workspaceId: string;
|
|
5
|
+
masterPassword?: string;
|
|
6
|
+
} | {
|
|
7
|
+
action: "vault-unlock";
|
|
8
|
+
masterPassword?: string;
|
|
9
|
+
} | {
|
|
10
|
+
action: "vault-change-password";
|
|
11
|
+
masterPassword?: string;
|
|
12
|
+
newMasterPassword?: string;
|
|
13
|
+
} | {
|
|
14
|
+
action: "vault-recovery-generate";
|
|
15
|
+
masterPassword?: string;
|
|
16
|
+
recoveryKey?: string;
|
|
17
|
+
} | {
|
|
18
|
+
action: "vault-recovery-unlock";
|
|
19
|
+
recoveryKey?: string;
|
|
20
|
+
} | {
|
|
21
|
+
action: "vault-recovery-rotate";
|
|
22
|
+
masterPassword?: string;
|
|
23
|
+
recoveryKey?: string;
|
|
24
|
+
} | {
|
|
25
|
+
action: "vault-recovery-kit";
|
|
26
|
+
} | {
|
|
27
|
+
action: "vault-device-key-register";
|
|
28
|
+
deviceId: string;
|
|
29
|
+
deviceLabel: string;
|
|
30
|
+
} | {
|
|
31
|
+
action: "vault-keychain-status";
|
|
32
|
+
provider?: AppOsKeychainIntegrationMetadata["provider"];
|
|
33
|
+
} | {
|
|
34
|
+
action: "secrets-set";
|
|
35
|
+
project: string;
|
|
36
|
+
environment: string;
|
|
37
|
+
alias: string;
|
|
38
|
+
label?: string;
|
|
39
|
+
status: AppCredentialStatus;
|
|
40
|
+
value?: string;
|
|
41
|
+
masterPassword?: string;
|
|
42
|
+
} | {
|
|
43
|
+
action: "secrets-list";
|
|
44
|
+
project: string;
|
|
45
|
+
environment?: string;
|
|
46
|
+
} | {
|
|
47
|
+
action: "secrets-inject";
|
|
48
|
+
project: string;
|
|
49
|
+
environment: string;
|
|
50
|
+
masterPassword?: string;
|
|
51
|
+
command: string;
|
|
52
|
+
args: string[];
|
|
53
|
+
} | {
|
|
54
|
+
action: "secrets-upload";
|
|
55
|
+
outputPath?: string;
|
|
56
|
+
} | {
|
|
57
|
+
action: "secrets-download";
|
|
58
|
+
inputPath?: string;
|
|
59
|
+
};
|
|
60
|
+
export type LocalVaultCommandResult = {
|
|
61
|
+
exitCode: number;
|
|
62
|
+
stdout: string;
|
|
63
|
+
stderr: string;
|
|
64
|
+
childStarted?: boolean;
|
|
65
|
+
auditId?: string;
|
|
66
|
+
};
|
|
67
|
+
export type LocalVaultCommandOptions = {
|
|
68
|
+
vaultPath?: string;
|
|
69
|
+
auditPath?: string;
|
|
70
|
+
now?: () => Date;
|
|
71
|
+
env?: NodeJS.ProcessEnv;
|
|
72
|
+
};
|
|
73
|
+
export declare function parseLocalVaultCommand(argv: string[]): ParsedLocalVaultCommand;
|
|
74
|
+
export declare function runLocalVaultCommand(argv: string[], options?: LocalVaultCommandOptions): Promise<LocalVaultCommandResult>;
|
|
75
|
+
export {};
|