@phantomcodes/cli 1.1.0 → 1.2.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 +3 -1
- package/dist/cli/commands.mjs +3 -1
- package/dist/core/version.mjs +1 -1
- package/dist/plan/command.mjs +16 -11
- package/dist/setup/command.mjs +10 -2
- package/dist/workspace/command.mjs +4 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -49,10 +49,12 @@ routing. Connect it using your saved key:
|
|
|
49
49
|
|
|
50
50
|
```bash
|
|
51
51
|
npm i -g @phantomcodes/cli
|
|
52
|
-
phantom login
|
|
53
52
|
phantom setup
|
|
54
53
|
```
|
|
55
54
|
|
|
55
|
+
With no key saved yet, `phantom setup` signs you in first (the same device
|
|
56
|
+
approval as `phantom login`), then sets up your agents with the new key.
|
|
57
|
+
|
|
56
58
|
Used pai, this CLI's old name? Run `phantom setup` once after you install. Until
|
|
57
59
|
then, Claude Code and the shell block pai set up still call `pai`, and phantom
|
|
58
60
|
prints a reminder.
|
package/dist/cli/commands.mjs
CHANGED
|
@@ -133,8 +133,10 @@ export const COMMANDS = [
|
|
|
133
133
|
name: 'setup', handler: setupCommand, keyless: true,
|
|
134
134
|
help: ` setup set up every agent found: install the skill and
|
|
135
135
|
point its model calls at Phantom AI; shows each
|
|
136
|
-
file's changes and asks first
|
|
136
|
+
file's changes and asks first. With no key yet,
|
|
137
|
+
signs in first (in a terminal)
|
|
137
138
|
[--yes] don't ask
|
|
139
|
+
[--no-browser] print the sign-in link instead of opening it
|
|
138
140
|
[--dry-run] show the changes, write nothing
|
|
139
141
|
[--model <id>] the model each agent starts on (default ${SETUP_MODEL})
|
|
140
142
|
setup --agent <name> install the skill for one agent, without asking:
|
package/dist/core/version.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** This release of phantom. `npm version` keeps it equal to the version in package.json. */
|
|
2
|
-
export const VERSION = '1.
|
|
2
|
+
export const VERSION = '1.2.0';
|
package/dist/plan/command.mjs
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
import { die } from "../core/errors.mjs";
|
|
2
2
|
import { openUrl, out } from "../core/helpers.mjs";
|
|
3
3
|
import { request } from "../core/request.mjs";
|
|
4
|
-
|
|
4
|
+
import { savedManagement } from "../workspace/command.mjs";
|
|
5
|
+
/** The plan of the key's workspace and its week (GET /plan). */
|
|
5
6
|
export function getPlan(apiKey, baseUrl) {
|
|
6
7
|
return request('GET', '/plan', apiKey, undefined, baseUrl);
|
|
7
8
|
}
|
|
8
|
-
/** A Stripe Checkout link that puts `plan` on the key (POST /plan/checkout). */
|
|
9
|
+
/** A Stripe Checkout link that puts `plan` on the key's workspace (POST /plan/checkout). */
|
|
9
10
|
export function planCheckout(apiKey, plan, baseUrl) {
|
|
10
11
|
return request('POST', '/plan/checkout', apiKey, { plan }, baseUrl);
|
|
11
12
|
}
|
|
12
|
-
/**
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
/**
|
|
14
|
+
* A link to Stripe's billing page for a workspace's plan (POST /plan/portal).
|
|
15
|
+
* It takes the workspace's management credential: an inference key gets 403.
|
|
16
|
+
*/
|
|
17
|
+
export function planPortal(credential, baseUrl) {
|
|
18
|
+
return request('POST', '/plan/portal', credential, undefined, baseUrl);
|
|
15
19
|
}
|
|
16
20
|
const dollars = (n) => `$${n.toFixed(2)}`;
|
|
17
21
|
/** `--table` output for `plan`. */
|
|
@@ -36,11 +40,12 @@ export function tablePlan(d) {
|
|
|
36
40
|
/** What `phantom plan` accepts after `plan`. */
|
|
37
41
|
const USAGE = 'Use phantom plan, phantom plan pro, phantom plan max or phantom plan manage.';
|
|
38
42
|
/**
|
|
39
|
-
* `phantom plan`: the key's
|
|
40
|
-
* `phantom plan pro|max` prints a Stripe Checkout link that puts the
|
|
41
|
-
*
|
|
42
|
-
* same for Stripe's billing page, where the card changes, the
|
|
43
|
-
* and it cancels
|
|
43
|
+
* `phantom plan`: the plan of the key's workspace and how much of the week is
|
|
44
|
+
* used. `phantom plan pro|max` prints a Stripe Checkout link that puts the
|
|
45
|
+
* plan on that workspace, and opens it unless `--no-browser`. `phantom plan
|
|
46
|
+
* manage` does the same for Stripe's billing page, where the card changes, the
|
|
47
|
+
* plan switches and it cancels; it sends the workspace credential `phantom
|
|
48
|
+
* login` saved, since a key can't manage billing. Run by `run()`.
|
|
44
49
|
*/
|
|
45
50
|
export async function planCommand(input) {
|
|
46
51
|
const { io, apiKey, table, baseUrl, flags, subcommand } = input;
|
|
@@ -57,7 +62,7 @@ export async function planCommand(input) {
|
|
|
57
62
|
open(result.checkout_url);
|
|
58
63
|
}
|
|
59
64
|
else if (subcommand === 'manage') {
|
|
60
|
-
const result = await planPortal(apiKey, baseUrl);
|
|
65
|
+
const result = await planPortal(savedManagement(input) ?? apiKey, baseUrl);
|
|
61
66
|
out(result, table, (d) => `Open this link to manage billing: ${d.portal_url}`, io.stdout);
|
|
62
67
|
open(result.portal_url);
|
|
63
68
|
}
|
package/dist/setup/command.mjs
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { createInterface } from 'node:readline/promises';
|
|
2
2
|
import { die } from "../core/errors.mjs";
|
|
3
3
|
import { out } from "../core/helpers.mjs";
|
|
4
|
+
import { resolveApiKey } from "../keys/saved.mjs";
|
|
5
|
+
import { workspaceLogin } from "../workspace/command.mjs";
|
|
4
6
|
import { SETUP_AGENTS, SETUP_NAMES } from "./agents.mjs";
|
|
5
7
|
import { planSetup } from "./plan.mjs";
|
|
6
8
|
import { setupPreview, applySetup, previewSetup, restoreSetup } from "./apply.mjs";
|
|
@@ -52,8 +54,9 @@ export function tableRestore(d) {
|
|
|
52
54
|
];
|
|
53
55
|
return lines.length ? lines.join('\n') : 'Nothing to restore.';
|
|
54
56
|
}
|
|
55
|
-
/** `phantom setup`: plans, previews, asks, applies or restores agent setup. Run by `run()`. */
|
|
56
|
-
export async function setupCommand(
|
|
57
|
+
/** `phantom setup`: plans, previews, asks, applies or restores agent setup. Plain setup with no key yet signs in first when it runs in a terminal. Run by `run()`. */
|
|
58
|
+
export async function setupCommand(input) {
|
|
59
|
+
const { env, io, flags, table } = input;
|
|
57
60
|
const agent = flags['agent'];
|
|
58
61
|
if (agent === true)
|
|
59
62
|
die(`--agent requires ${SETUP_NAMES.join(', ')} or all`);
|
|
@@ -74,6 +77,11 @@ export async function setupCommand({ env, io, flags, table }) {
|
|
|
74
77
|
// Plain `phantom setup` sets up everything it finds and asks first. Any of
|
|
75
78
|
// the older flags runs just what they name, without asking.
|
|
76
79
|
const guided = agent === undefined && provider === undefined;
|
|
80
|
+
// With no key yet, sign in first, as phantom claude does, so the agents
|
|
81
|
+
// get one in this run. Its words go to stderr; stdout stays setup's result.
|
|
82
|
+
if (guided && !dryRun && io.isTTY && !resolveApiKey(env)) {
|
|
83
|
+
await workspaceLogin({ ...input, io: { ...io, stdout: io.stderr }, flags: flags['no-browser'] ? { 'no-browser': true } : {} });
|
|
84
|
+
}
|
|
77
85
|
const plan = planSetup(env, {
|
|
78
86
|
agent,
|
|
79
87
|
provider: guided || provider === true ? true : provider === 'off' ? 'off' : false,
|
|
@@ -27,6 +27,10 @@ function credentials(input) {
|
|
|
27
27
|
die('This workspace belongs to a different API address. Run phantom login for this address.', 'workspace_origin');
|
|
28
28
|
return saved;
|
|
29
29
|
}
|
|
30
|
+
/** The management credential `phantom login` saved for this API address, or null when it saved none. */
|
|
31
|
+
export function savedManagement(input) {
|
|
32
|
+
return existsSync(credentialPath(input.env)) ? credentials(input).management_credential : null;
|
|
33
|
+
}
|
|
30
34
|
/** A read from the saved workspace, such as `/spend`, with its management credential. */
|
|
31
35
|
export async function workspaceGet(input, path) {
|
|
32
36
|
const saved = credentials(input);
|