@polpo-ai/cli 0.6.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/LICENSE +13 -0
- package/dist/commands/cloud/api.js +32 -0
- package/dist/commands/cloud/api.js.map +1 -0
- package/dist/commands/cloud/byok.js +125 -0
- package/dist/commands/cloud/byok.js.map +1 -0
- package/dist/commands/cloud/config.js +42 -0
- package/dist/commands/cloud/config.js.map +1 -0
- package/dist/commands/cloud/deploy.js +752 -0
- package/dist/commands/cloud/deploy.js.map +1 -0
- package/dist/commands/cloud/login.js +99 -0
- package/dist/commands/cloud/login.js.map +1 -0
- package/dist/commands/cloud/logout.js +11 -0
- package/dist/commands/cloud/logout.js.map +1 -0
- package/dist/commands/cloud/logs.js +114 -0
- package/dist/commands/cloud/logs.js.map +1 -0
- package/dist/commands/cloud/project-context.js +17 -0
- package/dist/commands/cloud/project-context.js.map +1 -0
- package/dist/commands/cloud/projects.js +95 -0
- package/dist/commands/cloud/projects.js.map +1 -0
- package/dist/commands/cloud/prompt.js +74 -0
- package/dist/commands/cloud/prompt.js.map +1 -0
- package/dist/commands/cloud/status.js +84 -0
- package/dist/commands/cloud/status.js.map +1 -0
- package/dist/commands/create.js +286 -0
- package/dist/commands/create.js.map +1 -0
- package/dist/commands/link.js +71 -0
- package/dist/commands/link.js.map +1 -0
- package/dist/commands/models.js +60 -0
- package/dist/commands/models.js.map +1 -0
- package/dist/commands/orgs.js +42 -0
- package/dist/commands/orgs.js.map +1 -0
- package/dist/commands/update.js +95 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/whoami.js +62 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/index.js +138 -0
- package/dist/index.js.map +1 -0
- package/dist/interactive-menu.js +111 -0
- package/dist/interactive-menu.js.map +1 -0
- package/dist/update-check.js +106 -0
- package/dist/update-check.js.map +1 -0
- package/dist/util/api-keys.js +21 -0
- package/dist/util/api-keys.js.map +1 -0
- package/dist/util/auth.js +71 -0
- package/dist/util/auth.js.map +1 -0
- package/dist/util/base-url.js +43 -0
- package/dist/util/base-url.js.map +1 -0
- package/dist/util/browser.js +20 -0
- package/dist/util/browser.js.map +1 -0
- package/dist/util/device-code.js +103 -0
- package/dist/util/device-code.js.map +1 -0
- package/dist/util/errors.js +13 -0
- package/dist/util/errors.js.map +1 -0
- package/dist/util/install-cli.js +68 -0
- package/dist/util/install-cli.js.map +1 -0
- package/dist/util/org.js +53 -0
- package/dist/util/org.js.map +1 -0
- package/dist/util/polpo-config.js +39 -0
- package/dist/util/polpo-config.js.map +1 -0
- package/dist/util/project.js +87 -0
- package/dist/util/project.js.map +1 -0
- package/dist/util/skills.js +53 -0
- package/dist/util/skills.js.map +1 -0
- package/dist/util/slugify.js +19 -0
- package/dist/util/slugify.js.map +1 -0
- package/dist/util/template.js +118 -0
- package/dist/util/template.js.map +1 -0
- package/package.json +38 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import pc from "picocolors";
|
|
2
|
+
import { getAuth } from "../util/auth.js";
|
|
3
|
+
import { createApiClient } from "./cloud/api.js";
|
|
4
|
+
export function registerWhoamiCommand(program) {
|
|
5
|
+
program
|
|
6
|
+
.command("whoami")
|
|
7
|
+
.description("Show the authenticated user + default organization")
|
|
8
|
+
.option("--json", "Output as JSON")
|
|
9
|
+
.action(async (opts) => {
|
|
10
|
+
const creds = getAuth();
|
|
11
|
+
if (!creds) {
|
|
12
|
+
if (opts.json) {
|
|
13
|
+
console.log(JSON.stringify({ loggedIn: false }));
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
console.log(pc.red("Not logged in.") + " Run: " + pc.bold("polpo login"));
|
|
17
|
+
}
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
const client = createApiClient({ apiKey: creds.apiKey, baseUrl: creds.baseUrl });
|
|
21
|
+
let user = null;
|
|
22
|
+
let orgs = [];
|
|
23
|
+
try {
|
|
24
|
+
const meRes = await client.get("/v1/me");
|
|
25
|
+
user = meRes.data ?? null;
|
|
26
|
+
}
|
|
27
|
+
catch { /* endpoint may not exist — graceful */ }
|
|
28
|
+
try {
|
|
29
|
+
const orgsRes = await client.get("/v1/orgs");
|
|
30
|
+
orgs = Array.isArray(orgsRes.data) ? orgsRes.data : [];
|
|
31
|
+
}
|
|
32
|
+
catch { /* graceful */ }
|
|
33
|
+
if (opts.json) {
|
|
34
|
+
console.log(JSON.stringify({
|
|
35
|
+
loggedIn: true,
|
|
36
|
+
apiUrl: creds.baseUrl,
|
|
37
|
+
user,
|
|
38
|
+
orgs,
|
|
39
|
+
}, null, 2));
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
console.log();
|
|
43
|
+
if (user?.email) {
|
|
44
|
+
console.log(pc.bold(" User: ") + user.email + (user.name ? pc.dim(` (${user.name})`) : ""));
|
|
45
|
+
}
|
|
46
|
+
console.log(pc.bold(" API: ") + creds.baseUrl);
|
|
47
|
+
if (orgs.length === 0) {
|
|
48
|
+
console.log(pc.bold(" Orgs: ") + pc.dim("none"));
|
|
49
|
+
}
|
|
50
|
+
else if (orgs.length === 1) {
|
|
51
|
+
console.log(pc.bold(" Org: ") + orgs[0].name + pc.dim(` (${orgs[0].id})`));
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
console.log(pc.bold(` Orgs: ${orgs.length}`));
|
|
55
|
+
for (const o of orgs) {
|
|
56
|
+
console.log(pc.dim(` · ${o.name} (${o.id})`));
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
console.log();
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=whoami.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Node.js version gate — fail fast with a clear message
|
|
3
|
+
const [major] = process.versions.node.split(".").map(Number);
|
|
4
|
+
if (major < 20) {
|
|
5
|
+
console.error(`\x1b[31mPolpo requires Node.js >= 20. You have ${process.version}.\x1b[0m`);
|
|
6
|
+
console.error("Install the latest LTS: https://nodejs.org");
|
|
7
|
+
process.exit(1);
|
|
8
|
+
}
|
|
9
|
+
import { resolve, dirname } from "node:path";
|
|
10
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
11
|
+
import { fileURLToPath } from "node:url";
|
|
12
|
+
import { Command } from "commander";
|
|
13
|
+
// Read version from package.json at build time fallback
|
|
14
|
+
const __dirname_cli = dirname(fileURLToPath(import.meta.url));
|
|
15
|
+
const pkgPath = resolve(__dirname_cli, "..", "..", "package.json");
|
|
16
|
+
const PKG_VERSION = existsSync(pkgPath)
|
|
17
|
+
? JSON.parse(readFileSync(pkgPath, "utf-8")).version
|
|
18
|
+
: "0.0.0";
|
|
19
|
+
// Load .env files from process.cwd() (project-local, then .polpo/.env).
|
|
20
|
+
// NOTE: This runs at module top-level, before --dir is parsed. When --dir differs
|
|
21
|
+
// from cwd, the correct .env is loaded later via parseConfig/provider overrides.
|
|
22
|
+
for (const envPath of [".env", ".polpo/.env"]) {
|
|
23
|
+
try {
|
|
24
|
+
const abs = resolve(envPath);
|
|
25
|
+
if (existsSync(abs)) {
|
|
26
|
+
for (const line of readFileSync(abs, "utf-8").split("\n")) {
|
|
27
|
+
const trimmed = line.trim();
|
|
28
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
29
|
+
continue;
|
|
30
|
+
const eq = trimmed.indexOf("=");
|
|
31
|
+
if (eq === -1)
|
|
32
|
+
continue;
|
|
33
|
+
const key = trimmed.slice(0, eq).trim();
|
|
34
|
+
const val = trimmed.slice(eq + 1).trim().replace(/^["']|["']$/g, "");
|
|
35
|
+
if (!process.env[key])
|
|
36
|
+
process.env[key] = val;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch { /* ignore */ }
|
|
41
|
+
}
|
|
42
|
+
import pc from "picocolors";
|
|
43
|
+
import { registerModelsCommands } from "./commands/models.js";
|
|
44
|
+
// Removed: task, mission, team, memory, config, playbook, skills, schedule,
|
|
45
|
+
// agent-onboard, logs, browser-profile — all file-based commands.
|
|
46
|
+
// Resources are defined in files and synced via polpo deploy.
|
|
47
|
+
import { registerUpdateCommand } from "./commands/update.js";
|
|
48
|
+
// Cloud commands (unified CLI)
|
|
49
|
+
import { registerLoginCommand } from "./commands/cloud/login.js";
|
|
50
|
+
import { registerLogoutCommand } from "./commands/cloud/logout.js";
|
|
51
|
+
import { registerDeployCommand } from "./commands/cloud/deploy.js";
|
|
52
|
+
import { registerByokCommand } from "./commands/cloud/byok.js";
|
|
53
|
+
import { registerProjectsCommand } from "./commands/cloud/projects.js";
|
|
54
|
+
import { registerStatusCommand as registerCloudStatusCommand } from "./commands/cloud/status.js";
|
|
55
|
+
import { registerLogsCommand as registerCloudLogsCommand } from "./commands/cloud/logs.js";
|
|
56
|
+
import { registerLinkCommand } from "./commands/link.js";
|
|
57
|
+
import { registerCreateCommand } from "./commands/create.js";
|
|
58
|
+
import { registerWhoamiCommand } from "./commands/whoami.js";
|
|
59
|
+
import { registerOrgsCommand } from "./commands/orgs.js";
|
|
60
|
+
import { startUpdateCheck } from "./update-check.js";
|
|
61
|
+
import { isBareInteractiveInvocation, runInteractiveMenu } from "./interactive-menu.js";
|
|
62
|
+
// Gradient from pink (#F78B97) to indigo (#3B3E73) — 6 rows
|
|
63
|
+
const _logoLines = [
|
|
64
|
+
"██████╗ ██████╗ ██╗ ██████╗ ██████╗",
|
|
65
|
+
"██╔══██╗██╔═══██╗██║ ██╔══██╗██╔═══██╗",
|
|
66
|
+
"██████╔╝██║ ██║██║ ██████╔╝██║ ██║",
|
|
67
|
+
"██╔═══╝ ██║ ██║██║ ██╔═══╝ ██║ ██║",
|
|
68
|
+
"██║ ╚██████╔╝███████╗██║ ╚██████╔╝",
|
|
69
|
+
"╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═════╝",
|
|
70
|
+
];
|
|
71
|
+
const _gradColors = [
|
|
72
|
+
[247, 139, 151], // #F78B97
|
|
73
|
+
[209, 119, 135],
|
|
74
|
+
[170, 99, 119],
|
|
75
|
+
[132, 79, 103],
|
|
76
|
+
[93, 59, 87],
|
|
77
|
+
[59, 62, 115], // #3B3E73
|
|
78
|
+
];
|
|
79
|
+
/** Apply bold + 24-bit RGB foreground via raw ANSI escapes (picocolors has no truecolor). */
|
|
80
|
+
function rgbBold(r, g, b, s) {
|
|
81
|
+
return `\x1b[1;38;2;${r};${g};${b}m${s}\x1b[0m`;
|
|
82
|
+
}
|
|
83
|
+
function _buildLogo(center = false) {
|
|
84
|
+
const cols = process.stdout.columns || 80;
|
|
85
|
+
return "\n" + _logoLines.map((l, i) => {
|
|
86
|
+
const pad = center ? " ".repeat(Math.max(0, Math.floor((cols - l.length) / 2))) : " ";
|
|
87
|
+
const [r, g, b] = _gradColors[i];
|
|
88
|
+
return pad + rgbBold(r, g, b, l);
|
|
89
|
+
}).join("\n") + "\n";
|
|
90
|
+
}
|
|
91
|
+
const LOGO = _buildLogo(false);
|
|
92
|
+
const program = new Command();
|
|
93
|
+
program
|
|
94
|
+
.name("polpo-ai")
|
|
95
|
+
.description("The open-source platform for AI agent teams")
|
|
96
|
+
.version(PKG_VERSION)
|
|
97
|
+
.enablePositionalOptions()
|
|
98
|
+
.passThroughOptions()
|
|
99
|
+
// Default (no subcommand): print a short get-started message + help.
|
|
100
|
+
.action(() => {
|
|
101
|
+
console.log(LOGO);
|
|
102
|
+
console.log(pc.bold(" Get started:\n") +
|
|
103
|
+
pc.dim(" polpo login authenticate\n") +
|
|
104
|
+
pc.dim(" polpo create create a new project\n") +
|
|
105
|
+
pc.dim(" polpo link --project-id <id> link an existing one\n") +
|
|
106
|
+
pc.dim(" polpo deploy push to cloud\n"));
|
|
107
|
+
console.log(pc.dim(" See `polpo --help` for all commands."));
|
|
108
|
+
});
|
|
109
|
+
// Register subcommand groups
|
|
110
|
+
registerModelsCommands(program);
|
|
111
|
+
registerUpdateCommand(program);
|
|
112
|
+
// Cloud commands
|
|
113
|
+
registerLoginCommand(program);
|
|
114
|
+
registerLogoutCommand(program);
|
|
115
|
+
registerDeployCommand(program);
|
|
116
|
+
registerByokCommand(program);
|
|
117
|
+
registerProjectsCommand(program);
|
|
118
|
+
registerCloudStatusCommand(program);
|
|
119
|
+
registerCloudLogsCommand(program);
|
|
120
|
+
registerLinkCommand(program);
|
|
121
|
+
registerCreateCommand(program);
|
|
122
|
+
registerWhoamiCommand(program);
|
|
123
|
+
registerOrgsCommand(program);
|
|
124
|
+
// Non-blocking update check — prints notice at exit if a new version exists
|
|
125
|
+
const printUpdateNotice = startUpdateCheck(PKG_VERSION);
|
|
126
|
+
process.on("exit", printUpdateNotice);
|
|
127
|
+
// Bare `polpo` on an interactive TTY → show the picker menu.
|
|
128
|
+
// Non-TTY (CI/pipe) or any args → standard commander dispatch.
|
|
129
|
+
if (isBareInteractiveInvocation()) {
|
|
130
|
+
runInteractiveMenu(program).catch((err) => {
|
|
131
|
+
console.error(err);
|
|
132
|
+
process.exit(1);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
program.parse();
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { resolve } from "node:path";
|
|
3
|
+
import * as clack from "@clack/prompts";
|
|
4
|
+
import pc from "picocolors";
|
|
5
|
+
import { loadCredentials } from "./commands/cloud/config.js";
|
|
6
|
+
function hasLinkedProject(cwd = process.cwd()) {
|
|
7
|
+
return existsSync(resolve(cwd, ".polpo", "polpo.json"));
|
|
8
|
+
}
|
|
9
|
+
export function isBareInteractiveInvocation() {
|
|
10
|
+
return process.argv.length <= 2 && !!process.stdout.isTTY && !process.env.CI;
|
|
11
|
+
}
|
|
12
|
+
export async function runInteractiveMenu(program) {
|
|
13
|
+
const isLoggedIn = !!loadCredentials();
|
|
14
|
+
const linked = hasLinkedProject();
|
|
15
|
+
clack.intro(pc.bold("Polpo"));
|
|
16
|
+
const options = [];
|
|
17
|
+
if (!isLoggedIn) {
|
|
18
|
+
options.push({ value: "login", label: "Log in to Polpo Cloud" });
|
|
19
|
+
}
|
|
20
|
+
options.push({
|
|
21
|
+
value: "create",
|
|
22
|
+
label: "Create a new project",
|
|
23
|
+
hint: !isLoggedIn ? "requires login" : undefined,
|
|
24
|
+
});
|
|
25
|
+
options.push({
|
|
26
|
+
value: "link",
|
|
27
|
+
label: "Link an existing project",
|
|
28
|
+
hint: !isLoggedIn ? "requires login" : undefined,
|
|
29
|
+
});
|
|
30
|
+
if (linked) {
|
|
31
|
+
options.push({ value: "deploy", label: "Deploy this project" });
|
|
32
|
+
}
|
|
33
|
+
options.push({ value: "projects", label: "List projects" });
|
|
34
|
+
options.push({ value: "docs", label: "View documentation" });
|
|
35
|
+
options.push({ value: "help", label: "Show all commands" });
|
|
36
|
+
const choice = await clack.select({
|
|
37
|
+
message: "What would you like to do?",
|
|
38
|
+
options,
|
|
39
|
+
});
|
|
40
|
+
if (clack.isCancel(choice)) {
|
|
41
|
+
clack.cancel("Cancelled.");
|
|
42
|
+
process.exit(0);
|
|
43
|
+
}
|
|
44
|
+
if (choice === "docs") {
|
|
45
|
+
const { openBrowser } = await import("./util/browser.js");
|
|
46
|
+
await openBrowser("https://docs.polpo.sh");
|
|
47
|
+
clack.outro(pc.dim("Opened https://docs.polpo.sh"));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
if (choice === "help") {
|
|
51
|
+
clack.outro(pc.dim("Showing full command list."));
|
|
52
|
+
program.outputHelp();
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
// For "link" we need a --project-id. Ask the user up front so the
|
|
56
|
+
// command receives a valid argv.
|
|
57
|
+
if (choice === "link") {
|
|
58
|
+
const projectId = await promptForProjectId();
|
|
59
|
+
if (!projectId) {
|
|
60
|
+
clack.cancel("Cancelled.");
|
|
61
|
+
process.exit(0);
|
|
62
|
+
}
|
|
63
|
+
await program.parseAsync([
|
|
64
|
+
process.argv[0], process.argv[1],
|
|
65
|
+
"link", "--project-id", projectId,
|
|
66
|
+
]);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
// Dispatch to the real subcommand. Commander consumes argv shape
|
|
70
|
+
// ['node', 'polpo', '<cmd>', ...args], so we rebuild that here.
|
|
71
|
+
await program.parseAsync([process.argv[0], process.argv[1], choice]);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Fetch the user's projects and let them pick, with a paste-id fallback
|
|
75
|
+
* for folks whose creds are valid but org/project listing is gated.
|
|
76
|
+
*/
|
|
77
|
+
async function promptForProjectId() {
|
|
78
|
+
const creds = loadCredentials();
|
|
79
|
+
if (!creds)
|
|
80
|
+
return null;
|
|
81
|
+
const { createApiClient } = await import("./commands/cloud/api.js");
|
|
82
|
+
const { pickOrg } = await import("./util/org.js");
|
|
83
|
+
const { listProjects } = await import("./util/project.js");
|
|
84
|
+
try {
|
|
85
|
+
const client = createApiClient({ apiKey: creds.apiKey, baseUrl: creds.baseUrl });
|
|
86
|
+
const org = await pickOrg(client);
|
|
87
|
+
const projects = await listProjects(client, org.id);
|
|
88
|
+
if (projects.length === 0) {
|
|
89
|
+
clack.log.warn("No projects found in this organization.");
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
const choice = await clack.select({
|
|
93
|
+
message: "Select a project to link:",
|
|
94
|
+
options: projects.map((p) => ({ value: p.id, label: p.name })),
|
|
95
|
+
});
|
|
96
|
+
if (clack.isCancel(choice))
|
|
97
|
+
return null;
|
|
98
|
+
return choice;
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
// Fallback to manual paste if the API call fails.
|
|
102
|
+
const id = await clack.text({
|
|
103
|
+
message: "Project ID:",
|
|
104
|
+
placeholder: "c816c3b5-0eab-46a5-aeb0-311a036b271b",
|
|
105
|
+
});
|
|
106
|
+
if (clack.isCancel(id) || !id)
|
|
107
|
+
return null;
|
|
108
|
+
return id;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=interactive-menu.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive-menu.js","sourceRoot":"","sources":["../src/interactive-menu.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Non-blocking update checker.
|
|
3
|
+
*
|
|
4
|
+
* Fires a single HTTP GET to the npm registry at CLI startup.
|
|
5
|
+
* If a newer version exists, prints a one-liner after the command finishes.
|
|
6
|
+
* Never blocks, never throws, never slows anything down.
|
|
7
|
+
*
|
|
8
|
+
* Rate-limited to once per 24 hours via a tiny timestamp file in ~/.polpo/.
|
|
9
|
+
*/
|
|
10
|
+
import { resolve, join } from "node:path";
|
|
11
|
+
import { homedir } from "node:os";
|
|
12
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "node:fs";
|
|
13
|
+
const PACKAGE_NAME = "polpo-ai";
|
|
14
|
+
const CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
15
|
+
/** File where we store the last check timestamp + latest version. */
|
|
16
|
+
function stateFilePath() {
|
|
17
|
+
const dir = join(homedir(), ".polpo");
|
|
18
|
+
if (!existsSync(dir))
|
|
19
|
+
mkdirSync(dir, { recursive: true });
|
|
20
|
+
return resolve(dir, ".update-check");
|
|
21
|
+
}
|
|
22
|
+
function readState() {
|
|
23
|
+
try {
|
|
24
|
+
const raw = readFileSync(stateFilePath(), "utf-8");
|
|
25
|
+
return JSON.parse(raw);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return { lastCheck: 0 };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function writeState(state) {
|
|
32
|
+
try {
|
|
33
|
+
writeFileSync(stateFilePath(), JSON.stringify(state));
|
|
34
|
+
}
|
|
35
|
+
catch { /* best-effort */ }
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Compare two semver strings. Returns true if `remote` is newer than `local`.
|
|
39
|
+
*/
|
|
40
|
+
function isNewer(local, remote) {
|
|
41
|
+
const a = local.split(".").map(Number);
|
|
42
|
+
const b = remote.split(".").map(Number);
|
|
43
|
+
for (let i = 0; i < 3; i++) {
|
|
44
|
+
if ((b[i] || 0) > (a[i] || 0))
|
|
45
|
+
return true;
|
|
46
|
+
if ((b[i] || 0) < (a[i] || 0))
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Start a non-blocking update check. Returns a function you call at exit
|
|
53
|
+
* to print the update notice (if any). Safe to ignore the return value.
|
|
54
|
+
*/
|
|
55
|
+
export function startUpdateCheck(currentVersion) {
|
|
56
|
+
// Respect POLPO_NO_UPDATE_CHECK=1 or CI environments
|
|
57
|
+
if (process.env.POLPO_NO_UPDATE_CHECK === "1" ||
|
|
58
|
+
process.env.CI === "true" ||
|
|
59
|
+
process.env.NO_COLOR !== undefined) {
|
|
60
|
+
return () => { };
|
|
61
|
+
}
|
|
62
|
+
const state = readState();
|
|
63
|
+
const now = Date.now();
|
|
64
|
+
// Already checked recently — use cached result
|
|
65
|
+
if (now - state.lastCheck < CHECK_INTERVAL_MS && state.latestVersion) {
|
|
66
|
+
if (isNewer(currentVersion, state.latestVersion)) {
|
|
67
|
+
return () => printNotice(currentVersion, state.latestVersion);
|
|
68
|
+
}
|
|
69
|
+
return () => { };
|
|
70
|
+
}
|
|
71
|
+
// Fire-and-forget fetch — never awaited, never blocks
|
|
72
|
+
let latestVersion;
|
|
73
|
+
const controller = new AbortController();
|
|
74
|
+
const timeout = setTimeout(() => controller.abort(), 5000);
|
|
75
|
+
fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`, {
|
|
76
|
+
signal: controller.signal,
|
|
77
|
+
headers: { Accept: "application/json" },
|
|
78
|
+
})
|
|
79
|
+
.then((r) => r.json())
|
|
80
|
+
.then((data) => {
|
|
81
|
+
clearTimeout(timeout);
|
|
82
|
+
latestVersion = data.version;
|
|
83
|
+
writeState({ lastCheck: now, latestVersion });
|
|
84
|
+
})
|
|
85
|
+
.catch(() => {
|
|
86
|
+
clearTimeout(timeout);
|
|
87
|
+
/* offline, timeout, etc. — silently ignore */
|
|
88
|
+
});
|
|
89
|
+
// Return a sync function that the caller invokes when the CLI is about to exit
|
|
90
|
+
return () => {
|
|
91
|
+
if (latestVersion && isNewer(currentVersion, latestVersion)) {
|
|
92
|
+
printNotice(currentVersion, latestVersion);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
function printNotice(current, latest) {
|
|
97
|
+
// Plain ANSI escapes — no color lib needed for a single-line notice
|
|
98
|
+
const yellow = "\x1b[33m";
|
|
99
|
+
const cyan = "\x1b[36m";
|
|
100
|
+
const dim = "\x1b[2m";
|
|
101
|
+
const bold = "\x1b[1m";
|
|
102
|
+
const reset = "\x1b[0m";
|
|
103
|
+
process.stderr.write(`\n${yellow}${bold} Update available!${reset} ${dim}${current}${reset} → ${cyan}${bold}${latest}${reset}\n` +
|
|
104
|
+
`${dim} Run ${reset}${cyan}polpo update${reset}${dim} to upgrade${reset}\n\n`);
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=update-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-check.js","sourceRoot":"","sources":["../src/update-check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export async function createApiKey(client, opts) {
|
|
2
|
+
const res = await client.post("/v1/api-keys", {
|
|
3
|
+
orgId: opts.orgId,
|
|
4
|
+
name: opts.name,
|
|
5
|
+
scopes: opts.scopes,
|
|
6
|
+
environment: opts.environment ?? "live",
|
|
7
|
+
});
|
|
8
|
+
if (!res.data?.rawKey) {
|
|
9
|
+
throw new Error(`Failed to create API key: ${res.data?.error ?? `HTTP ${res.status}`}`);
|
|
10
|
+
}
|
|
11
|
+
return res.data;
|
|
12
|
+
}
|
|
13
|
+
/** Convenience wrapper for the common "one project, one key" case. */
|
|
14
|
+
export async function createProjectApiKey(client, orgId, projectId, name = "CLI generated") {
|
|
15
|
+
return createApiKey(client, {
|
|
16
|
+
orgId,
|
|
17
|
+
name,
|
|
18
|
+
scopes: [{ type: "project", projectId }],
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=api-keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-keys.js","sourceRoot":"","sources":["../../src/util/api-keys.ts"],"names":[],"mappings":"AA4CA,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAiB,EACjB,IAAyB;IAEzB,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,IAAI,CAAgB,cAAc,EAAE;QAC3D,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,MAAM;KACxC,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CACb,6BAA8B,GAAG,CAAC,IAAY,EAAE,KAAK,IAAI,QAAQ,GAAG,CAAC,MAAM,EAAE,EAAE,CAChF,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,CAAC;AAClB,CAAC;AAED,sEAAsE;AACtE,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,MAAiB,EACjB,KAAa,EACb,SAAiB,EACjB,OAAe,eAAe;IAE9B,OAAO,YAAY,CAAC,MAAM,EAAE;QAC1B,KAAK;QACL,IAAI;QACJ,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC;KACzC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart auth helper for cloud commands.
|
|
3
|
+
*
|
|
4
|
+
* `requireAuth()` ensures the user is logged in before a cloud-scoped
|
|
5
|
+
* command runs. Behaviour:
|
|
6
|
+
*
|
|
7
|
+
* - Credentials present → returns them.
|
|
8
|
+
* - Credentials missing + interactive TTY → prints a notice, triggers
|
|
9
|
+
* the device-code browser flow, retries once on failure, returns
|
|
10
|
+
* the new credentials on success.
|
|
11
|
+
* - Credentials missing + non-interactive (CI, pipe) → exits with a
|
|
12
|
+
* clear hint pointing at `polpo login`.
|
|
13
|
+
*
|
|
14
|
+
* The retry loop keeps the user unblocked without a separate "run login
|
|
15
|
+
* and come back" round-trip.
|
|
16
|
+
*/
|
|
17
|
+
import pc from "picocolors";
|
|
18
|
+
import * as clack from "@clack/prompts";
|
|
19
|
+
import { loadCredentials } from "../commands/cloud/config.js";
|
|
20
|
+
import { performDeviceCodeLogin, DeviceCodeError } from "./device-code.js";
|
|
21
|
+
function isInteractive() {
|
|
22
|
+
return !!process.stdout.isTTY && !process.env.CI;
|
|
23
|
+
}
|
|
24
|
+
export async function requireAuth(opts = {}) {
|
|
25
|
+
const existing = loadCredentials();
|
|
26
|
+
if (existing)
|
|
27
|
+
return existing;
|
|
28
|
+
if (!isInteractive()) {
|
|
29
|
+
if (opts.context)
|
|
30
|
+
console.error(pc.red(opts.context));
|
|
31
|
+
console.error(pc.red("Not logged in. Run: ") + pc.bold("polpo login"));
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
// Interactive: trigger login inline, retry once on recoverable failure.
|
|
35
|
+
if (opts.context)
|
|
36
|
+
clack.log.info(opts.context);
|
|
37
|
+
clack.log.info("You need to log in to continue.");
|
|
38
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
39
|
+
try {
|
|
40
|
+
return await performDeviceCodeLogin({
|
|
41
|
+
apiUrl: opts.apiUrl,
|
|
42
|
+
dashboardUrl: opts.dashboardUrl,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
if (err instanceof DeviceCodeError) {
|
|
47
|
+
clack.log.warn(`Login failed: ${err.message}`);
|
|
48
|
+
if (attempt === 0 && (err.reason === "expired" || err.reason === "timeout")) {
|
|
49
|
+
const retry = await clack.confirm({
|
|
50
|
+
message: "Would you like to try again?",
|
|
51
|
+
initialValue: true,
|
|
52
|
+
});
|
|
53
|
+
if (clack.isCancel(retry) || !retry)
|
|
54
|
+
break;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
break;
|
|
58
|
+
}
|
|
59
|
+
throw err;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
clack.outro(pc.red("Authentication required. Run ") +
|
|
63
|
+
pc.bold("polpo login") +
|
|
64
|
+
pc.red(" to try again."));
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
/** Non-fatal variant: returns null when not logged in. For commands that work both ways. */
|
|
68
|
+
export function getAuth() {
|
|
69
|
+
return loadCredentials();
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/util/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,eAAe,EAAoB,MAAM,6BAA6B,CAAC;AAChF,OAAO,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAW3E,SAAS,aAAa;IACpB,OAAO,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;AACnD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,OAA2B,EAAE;IAE7B,MAAM,QAAQ,GAAG,eAAe,EAAE,CAAC;IACnC,IAAI,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE9B,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;QACrB,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QACtD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,sBAAsB,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;QACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,wEAAwE;IACxE,IAAI,IAAI,CAAC,OAAO;QAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/C,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IAElD,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;QAC7C,IAAI,CAAC;YACH,OAAO,MAAM,sBAAsB,CAAC;gBAClC,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,YAAY,EAAE,IAAI,CAAC,YAAY;aAChC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,eAAe,EAAE,CAAC;gBACnC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,iBAAiB,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC/C,IAAI,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,EAAE,CAAC;oBAC5E,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC;wBAChC,OAAO,EAAE,8BAA8B;wBACvC,YAAY,EAAE,IAAI;qBACnB,CAAC,CAAC;oBACH,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK;wBAAE,MAAM;oBAC3C,SAAS;gBACX,CAAC;gBACD,MAAM;YACR,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAK,CACT,EAAE,CAAC,GAAG,CAAC,+BAA+B,CAAC;QACrC,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC;QACtB,EAAE,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAC3B,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,OAAO;IACrB,OAAO,eAAe,EAAE,CAAC;AAC3B,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Single source of truth for "where do I send data plane requests?".
|
|
3
|
+
*
|
|
4
|
+
* Resolution priority (first match wins):
|
|
5
|
+
*
|
|
6
|
+
* 1. Explicit `--url` flag passed to the command (caller's responsibility
|
|
7
|
+
* to surface it as the highest-priority override).
|
|
8
|
+
* 2. `POLPO_API_URL` env var. Lets users redirect a single command run
|
|
9
|
+
* without touching files (e.g. `POLPO_API_URL=http://localhost:4000
|
|
10
|
+
* polpo deploy` for self-hosted dev).
|
|
11
|
+
* 3. `apiUrl` field in `.polpo/polpo.json`. Per-project pin — used by
|
|
12
|
+
* teams that want their `.env.local` and CLI to point somewhere
|
|
13
|
+
* non-standard (custom domain, on-prem cluster).
|
|
14
|
+
* 4. `https://{projectSlug}.polpo.cloud` — derived from the slug stored
|
|
15
|
+
* in `polpo.json`. The default for cloud users post-F4.
|
|
16
|
+
* 5. Stored CLI credentials baseUrl (from `~/.polpo/credentials.json`,
|
|
17
|
+
* defaults to `https://api.polpo.sh`). Last-resort fallback for
|
|
18
|
+
* legacy clients that don't have a slug yet.
|
|
19
|
+
*
|
|
20
|
+
* Self-hosted users override (1) or (2) and the rest of the chain is
|
|
21
|
+
* irrelevant. Cloud users normally hit (4).
|
|
22
|
+
*
|
|
23
|
+
* IMPORTANT: this function does NOT touch the network or read env files —
|
|
24
|
+
* it's a pure function of the inputs. The caller decides which sources
|
|
25
|
+
* to consult.
|
|
26
|
+
*/
|
|
27
|
+
export const POLPO_API_DOMAIN = "polpo.cloud";
|
|
28
|
+
export function resolveBaseUrl(inputs) {
|
|
29
|
+
if (inputs.flagOverride)
|
|
30
|
+
return stripTrailingSlash(inputs.flagOverride);
|
|
31
|
+
if (inputs.envOverride)
|
|
32
|
+
return stripTrailingSlash(inputs.envOverride);
|
|
33
|
+
const cfg = inputs.polpoConfig;
|
|
34
|
+
if (cfg?.apiUrl)
|
|
35
|
+
return stripTrailingSlash(cfg.apiUrl);
|
|
36
|
+
if (cfg?.projectSlug)
|
|
37
|
+
return `https://${cfg.projectSlug}.${POLPO_API_DOMAIN}`;
|
|
38
|
+
return stripTrailingSlash(inputs.fallback);
|
|
39
|
+
}
|
|
40
|
+
function stripTrailingSlash(s) {
|
|
41
|
+
return s.endsWith("/") ? s.slice(0, -1) : s;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=base-url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-url.js","sourceRoot":"","sources":["../../src/util/base-url.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAaH,MAAM,CAAC,MAAM,gBAAgB,GAAG,aAAa,CAAC;AAE9C,MAAM,UAAU,cAAc,CAAC,MAAqB;IAClD,IAAI,MAAM,CAAC,YAAY;QAAE,OAAO,kBAAkB,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;IACxE,IAAI,MAAM,CAAC,WAAW;QAAE,OAAO,kBAAkB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IAEtE,MAAM,GAAG,GAAG,MAAM,CAAC,WAAW,CAAC;IAC/B,IAAI,GAAG,EAAE,MAAM;QAAE,OAAO,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACvD,IAAI,GAAG,EAAE,WAAW;QAAE,OAAO,WAAW,GAAG,CAAC,WAAW,IAAI,gBAAgB,EAAE,CAAC;IAE9E,OAAO,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,kBAAkB,CAAC,CAAS;IACnC,OAAO,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-platform browser opener.
|
|
3
|
+
*
|
|
4
|
+
* Uses the platform-specific command to open a URL:
|
|
5
|
+
* macOS → open
|
|
6
|
+
* Windows → start
|
|
7
|
+
* Linux → xdg-open
|
|
8
|
+
*
|
|
9
|
+
* Fire-and-forget: does not wait for the command to complete and swallows errors.
|
|
10
|
+
* Callers should always print the URL as a fallback so users can copy-paste if
|
|
11
|
+
* the browser doesn't open (headless/ssh/WSL cases).
|
|
12
|
+
*/
|
|
13
|
+
export async function openBrowser(url) {
|
|
14
|
+
const { platform } = await import("node:os");
|
|
15
|
+
const { exec } = await import("node:child_process");
|
|
16
|
+
const os = platform();
|
|
17
|
+
const cmd = os === "darwin" ? "open" : os === "win32" ? "start" : "xdg-open";
|
|
18
|
+
exec(`${cmd} "${url}"`);
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/util/browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAW;IAC3C,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;IAC7C,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;IACpD,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAC;IACtB,MAAM,GAAG,GAAG,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC;IAC7E,IAAI,CAAC,GAAG,GAAG,KAAK,GAAG,GAAG,CAAC,CAAC;AAC1B,CAAC"}
|