@curviate/cli 0.19.0 → 0.21.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/CHANGELOG.md +133 -0
- package/dist/{account-EGJJNBXW.js → account-A3FOYUKC.js} +29 -29
- package/dist/{chunk-42VUUKQ3.js → chunk-56ORAZJO.js} +4 -1
- package/dist/{chunk-TMU3CSPR.js → chunk-CUTMZWL6.js} +5 -1
- package/dist/chunk-HOQ7EUHJ.js +50 -0
- package/dist/{chunk-M33MI53G.js → chunk-LMVDURUZ.js} +23 -1
- package/dist/{chunk-KVV6LZ7E.js → chunk-Q7XG2VIF.js} +60 -24
- package/dist/chunk-ZYURL5VK.js +83 -0
- package/dist/cli.js +51 -36
- package/dist/{comment-VT6PO4MN.js → comment-RPLZHFJQ.js} +9 -9
- package/dist/{company-XEEBBCRZ.js → company-DFJK2RHM.js} +23 -22
- package/dist/{config-P5CPF5WC.js → config-FPWWYG7G.js} +3 -2
- package/dist/{connect-6PU7QCOL.js → connect-ELSSMOIC.js} +37 -15
- package/dist/{feed-KAUDRE5K.js → feed-23Z7OQNL.js} +4 -3
- package/dist/{group-LPVVJ2JX.js → group-52MP24W3.js} +8 -7
- package/dist/{inbox-BXCWHGWP.js → inbox-G6KNWWLI.js} +10 -9
- package/dist/{inboxes-MTPWLP5F.js → inboxes-NTTYCQPM.js} +5 -4
- package/dist/{job-EIXBJXLW.js → job-WOPIAHOR.js} +8 -7
- package/dist/{login-GDLWR542.js → login-ZLDDIAFW.js} +14 -15
- package/dist/{message-UWMRE2SJ.js → message-KJXY5RCD.js} +7 -4
- package/dist/{notification-RYFDHM3G.js → notification-MNEABNVW.js} +6 -5
- package/dist/{post-HK6HHIKV.js → post-A7YZWBFG.js} +12 -12
- package/dist/{profile-PES67647.js → profile-XOMDIYSY.js} +14 -13
- package/dist/{recruiter-MVPSTH2V.js → recruiter-CCLG4PM4.js} +38 -35
- package/dist/{sales-nav-TMXWDKSE.js → sales-nav-5ZRE2UAQ.js} +20 -19
- package/dist/{search-O2LACGHE.js → search-NDESJC3Y.js} +16 -14
- package/dist/{webhook-QFSZN3P2.js → webhook-TNZF3FMN.js} +51 -19
- package/package.json +2 -2
- package/dist/chunk-U7Y4EXHT.js +0 -33
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,139 @@ a new command or flag is a minor; a breaking command/flag/exit-code change is a
|
|
|
8
8
|
|
|
9
9
|
## [Unreleased]
|
|
10
10
|
|
|
11
|
+
## [0.21.0] - 2026-08-04
|
|
12
|
+
|
|
13
|
+
A correctness release for every argument that reads from stdin. Upgrade
|
|
14
|
+
immediately if you are on 0.20.0: on that version the documented quick-start
|
|
15
|
+
login silently stored a placeholder instead of your API key, so the very first
|
|
16
|
+
command after it failed and blamed your key.
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- **`curviate login --api-key -` now stores the piped key.** It previously
|
|
21
|
+
reported success and exited 0 while writing the literal string
|
|
22
|
+
`__curviate_stdin__` into your config, so every later command answered 401 and
|
|
23
|
+
attributed the failure to your API key. That is the first command in the
|
|
24
|
+
quick-start, so a new install failed on first contact with a misleading cause.
|
|
25
|
+
|
|
26
|
+
- **Eleven further arguments documented as accepting `-` now read stdin.** Each
|
|
27
|
+
compared its raw value against `-`, but the dispatcher had already substituted
|
|
28
|
+
an internal placeholder by that point, so the branch was unreachable and the
|
|
29
|
+
placeholder was consumed as your data. Affected: `--filters` on the eight
|
|
30
|
+
search and list commands, and `--body` on the three recruiter and webhook
|
|
31
|
+
commands, which answered `--filters is not valid JSON` or
|
|
32
|
+
`--body only accepts '-'` to a caller who had passed exactly that.
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- **A bare `-` is only special on an argument that declares a stdin contract.**
|
|
37
|
+
Every other argument now receives a literal `-`, restored between the parser
|
|
38
|
+
and the handler. Previously the substitution was indiscriminate, so a bare `-`
|
|
39
|
+
became the internal placeholder at any argument, including places where it
|
|
40
|
+
then travelled to the wire as a value. If you were relying on `-` being read
|
|
41
|
+
from stdin on an argument whose help text does not describe that behaviour, it
|
|
42
|
+
no longer is; the arguments that document the contract are unchanged.
|
|
43
|
+
|
|
44
|
+
- **The internal placeholder can no longer leave the process.** The request
|
|
45
|
+
transport and the config writer both refuse it as a defence in depth backstop,
|
|
46
|
+
and report what to do instead, so no future argument can leak it into a
|
|
47
|
+
request or a config file.
|
|
48
|
+
|
|
49
|
+
## [0.20.0] - 2026-08-03
|
|
50
|
+
|
|
51
|
+
A safety and correctness release. Upgrade promptly: it closes a path by which a
|
|
52
|
+
mistyped command sent a message, and it is the first release in which
|
|
53
|
+
`curviate webhook verify` works at all.
|
|
54
|
+
|
|
55
|
+
### Fixed
|
|
56
|
+
|
|
57
|
+
- **An unknown subcommand under `message` no longer becomes a send.**
|
|
58
|
+
`curviate message search "sophie"` did not error. `message` accepts both
|
|
59
|
+
subcommands and a bare `message <chat_id> "<text>"` form, and an unregistered
|
|
60
|
+
first token fell through to the bare form, so it bound `chatId="search"`,
|
|
61
|
+
`text="sophie"` and **sent a message**. That applied to any unknown or
|
|
62
|
+
mistyped subcommand: with `search` it 404s, but with a real chat id in that
|
|
63
|
+
position, or a paste that lands one there, it messaged a real person.
|
|
64
|
+
|
|
65
|
+
An unknown subcommand now exits 2 with usage and issues **no request at all**.
|
|
66
|
+
The legitimate `curviate message <chat_id> "<text>"` form is unchanged, and
|
|
67
|
+
`curviate message send <chat_id> "<text>"` is always available for a chat id
|
|
68
|
+
the check does not recognise.
|
|
69
|
+
|
|
70
|
+
To search your messages, the command is `curviate inbox search`.
|
|
71
|
+
|
|
72
|
+
- **A mistyped `connect` subcommand no longer sends a connection invitation.**
|
|
73
|
+
Same shape: `curviate connect <id>` sends an invitation, so `connect snet`
|
|
74
|
+
(for `sent`) invited whoever owns the slug `snet`. A first argument that is a
|
|
75
|
+
near-miss of a `connect` subcommand is now refused with a suggestion. If the
|
|
76
|
+
slug really was intended, pass the full profile URL or the provider id.
|
|
77
|
+
|
|
78
|
+
- **`curviate webhook verify` now verifies real deliveries.** It inherited a
|
|
79
|
+
defect from `@curviate/sdk`: the platform sends the event name in `event` and
|
|
80
|
+
the SDK required a `type` field no delivery has ever carried, so verification
|
|
81
|
+
failed on 100% of genuine webhooks and reported `malformed_header`, pointing
|
|
82
|
+
at the header and the secret when both were correct. Fixed by the `@curviate/sdk`
|
|
83
|
+
0.19.0 dependency bump. A body that verifies but cannot be parsed now reports
|
|
84
|
+
`malformed_payload`.
|
|
85
|
+
|
|
86
|
+
- **`webhook verify --body` accepts the raw body inline, as a file path, or on
|
|
87
|
+
stdin.** Every documented invocation failed before this: the flag value was
|
|
88
|
+
handed straight to the filesystem, so inline JSON was opened as a filename
|
|
89
|
+
(`ENOENT`/`ENAMETOOLONG`), and `--body -` opened the internal placeholder the
|
|
90
|
+
argument parser substitutes for a bare dash. Only a file path ever worked, and
|
|
91
|
+
the failure surfaced as exit `1` with a raw filesystem error rather than a
|
|
92
|
+
usage error. A body is now recognised by its leading `{`, `-` reads stdin on
|
|
93
|
+
every platform, and anything unreadable exits `2` naming all three accepted
|
|
94
|
+
forms. A trailing newline added by a shell redirect, `curl -o`, or an editor
|
|
95
|
+
save is ignored; newlines inside the body are preserved.
|
|
96
|
+
|
|
97
|
+
- **`webhook verify --help` named the wrong signature header.** It said
|
|
98
|
+
`X-Curviate-Signature`; the platform sends `Curviate-Signature`, so a reader
|
|
99
|
+
who copied the name read for a header that is never present. The same help
|
|
100
|
+
also claimed `--header` falls back to stdin, which it never did. Both flags
|
|
101
|
+
are now marked required, so omitting one is a usage error instead of a
|
|
102
|
+
signature failure that points at a secret which was never wrong.
|
|
103
|
+
|
|
104
|
+
- **`group list` help said `--profile`; the flag is `--target`.** `--profile` is
|
|
105
|
+
the global config-profile selector, so following the help text selected a
|
|
106
|
+
config profile and silently returned your own groups instead of the target
|
|
107
|
+
member's.
|
|
108
|
+
|
|
109
|
+
- **`job publish` and `recruiter job publish` help said `--budget-*`.** The glob
|
|
110
|
+
is not a flag anyone can type; the help now names `--budget-amount`,
|
|
111
|
+
`--budget-currency`, and `--budget-scope`.
|
|
112
|
+
|
|
113
|
+
- **Em dashes removed from all CLI output** (error messages, help text, usage
|
|
114
|
+
blocks), including the `no API key` error.
|
|
115
|
+
|
|
116
|
+
### Changed
|
|
117
|
+
|
|
118
|
+
- `@curviate/sdk` dependency bumped to `^0.19.0`. If you also call the SDK
|
|
119
|
+
directly, note that its webhook event discriminant moved from `event.type` to
|
|
120
|
+
`event.event`; see the SDK's 0.19.0 changelog.
|
|
121
|
+
|
|
122
|
+
### Added
|
|
123
|
+
|
|
124
|
+
- Two mechanical guards in the test suite, both derived from the live command
|
|
125
|
+
tree rather than a hand-maintained list, so this class of defect cannot
|
|
126
|
+
quietly return:
|
|
127
|
+
- a fall-through audit that forces an explicit safe/read-only/write-bearing
|
|
128
|
+
verdict on every command group that mixes subcommands with a positional
|
|
129
|
+
fallback, and
|
|
130
|
+
- a help-vs-args check that fails when any command's help text names a flag
|
|
131
|
+
that command does not declare (resolving cross-references, so a reference
|
|
132
|
+
to another command's flag is checked against that command).
|
|
133
|
+
|
|
134
|
+
- Two further mechanical guards, in the same spirit:
|
|
135
|
+
- an em-dash check that walks the TypeScript syntax tree, so it inspects
|
|
136
|
+
string and template literals only and leaves comments exempt structurally
|
|
137
|
+
rather than by a fragile line-based heuristic, and
|
|
138
|
+
- a pre-publish binary gate that runs every documented `webhook verify --body`
|
|
139
|
+
form against a recorded delivery: the exact body bytes and the exact
|
|
140
|
+
signature header the platform put on the wire, replayed verbatim and never
|
|
141
|
+
re-signed. Tampering with a single field is still rejected, so the gate
|
|
142
|
+
proves the verdict as well as the plumbing.
|
|
143
|
+
|
|
11
144
|
## [0.19.0] - 2026-07-29
|
|
12
145
|
|
|
13
146
|
A minor release closing the remaining SDK-parity gap: 25 new commands across seven
|
|
@@ -5,9 +5,6 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
AUTH_NEEDED
|
|
7
7
|
} from "./chunk-M6UDWFHX.js";
|
|
8
|
-
import {
|
|
9
|
-
defaultReadStdin
|
|
10
|
-
} from "./chunk-U7Y4EXHT.js";
|
|
11
8
|
import {
|
|
12
9
|
slimAccountGet,
|
|
13
10
|
slimAccountList,
|
|
@@ -26,12 +23,15 @@ import {
|
|
|
26
23
|
renderSuccess,
|
|
27
24
|
renderUnexpectedError,
|
|
28
25
|
resolveEffectiveConfig
|
|
29
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-LMVDURUZ.js";
|
|
30
27
|
import {
|
|
31
28
|
GLOBAL_FLAGS,
|
|
32
29
|
READ_SINGLE_FLAGS,
|
|
33
30
|
WRITE_SINGLE_FLAGS
|
|
34
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-CUTMZWL6.js";
|
|
32
|
+
import {
|
|
33
|
+
defaultReadStdin
|
|
34
|
+
} from "./chunk-ZYURL5VK.js";
|
|
35
35
|
|
|
36
36
|
// src/commands/account.ts
|
|
37
37
|
import { defineCommand } from "citty";
|
|
@@ -90,15 +90,15 @@ function checkCredentialConflicts(flags, out) {
|
|
|
90
90
|
const passwordStdin = flags["password-stdin"] ?? false;
|
|
91
91
|
const liAtStdin = flags["li-at-stdin"] ?? false;
|
|
92
92
|
if (flags.password !== void 0 && passwordStdin) {
|
|
93
|
-
failConflict(out, "--password and --password-stdin cannot both be set
|
|
93
|
+
failConflict(out, "--password and --password-stdin cannot both be set. Choose one source.");
|
|
94
94
|
}
|
|
95
95
|
if (flags["li-at"] !== void 0 && liAtStdin) {
|
|
96
|
-
failConflict(out, "--li-at and --li-at-stdin cannot both be set
|
|
96
|
+
failConflict(out, "--li-at and --li-at-stdin cannot both be set. Choose one source.");
|
|
97
97
|
}
|
|
98
98
|
if (passwordStdin && liAtStdin) {
|
|
99
99
|
failConflict(
|
|
100
100
|
out,
|
|
101
|
-
"--password-stdin and --li-at-stdin cannot both be set
|
|
101
|
+
"--password-stdin and --li-at-stdin cannot both be set. stdin can feed only one secret per invocation."
|
|
102
102
|
);
|
|
103
103
|
}
|
|
104
104
|
if (liAtStdin && flags["auth-method"] === "credentials") {
|
|
@@ -164,7 +164,7 @@ function challengeDescription(type) {
|
|
|
164
164
|
case "two_factor_app":
|
|
165
165
|
return "Enter the current code from your authenticator app.";
|
|
166
166
|
case "mobile_app_approval":
|
|
167
|
-
return "Open your LinkedIn mobile app and approve this sign-in
|
|
167
|
+
return "Open your LinkedIn mobile app and approve this sign-in. This will continue automatically once you tap approve.";
|
|
168
168
|
}
|
|
169
169
|
}
|
|
170
170
|
function printChallengeCopy(type, out) {
|
|
@@ -293,7 +293,7 @@ async function buildAuthBody(flags, ctx) {
|
|
|
293
293
|
// of --email — an email-less body still fails downstream validation,
|
|
294
294
|
// as expected, rather than the flag being silently ignored.
|
|
295
295
|
allowInteractiveStdinRead: !ctx.previewMode,
|
|
296
|
-
failMessage: "no password
|
|
296
|
+
failMessage: "no password. Pass --password, --password-stdin, or set CURVIATE_LINKEDIN_PASSWORD",
|
|
297
297
|
prompt: { isTTY: ctx.isTTY, readline: ctx.readline, promptText: "LinkedIn password: " },
|
|
298
298
|
out: ctx.out
|
|
299
299
|
});
|
|
@@ -314,7 +314,7 @@ async function buildAuthBody(flags, ctx) {
|
|
|
314
314
|
readSingleLine: ctx.readSingleLine,
|
|
315
315
|
required: true,
|
|
316
316
|
allowInteractive: !ctx.previewMode,
|
|
317
|
-
failMessage: "no li_at
|
|
317
|
+
failMessage: "no li_at. Pass --li-at, --li-at-stdin, or set CURVIATE_LINKEDIN_LI_AT",
|
|
318
318
|
out: ctx.out
|
|
319
319
|
});
|
|
320
320
|
const liA = await resolveSecret({
|
|
@@ -377,7 +377,7 @@ function printConnected(result, ctx) {
|
|
|
377
377
|
}
|
|
378
378
|
function printInvalidCodeRetryHint(err, out) {
|
|
379
379
|
const attemptsRemaining = err.attempts_remaining;
|
|
380
|
-
const message = typeof attemptsRemaining === "number" ? `That code was not accepted
|
|
380
|
+
const message = typeof attemptsRemaining === "number" ? `That code was not accepted. ${attemptsRemaining} attempt(s) remaining.` : "That code was not accepted. Please try again.";
|
|
381
381
|
out.stderr.write(`${message}
|
|
382
382
|
`);
|
|
383
383
|
}
|
|
@@ -620,7 +620,7 @@ async function runAccountConnectSessionPoll(client, flags, out, io = {}) {
|
|
|
620
620
|
}
|
|
621
621
|
renderSuccess(outcome.result, outOpts, out);
|
|
622
622
|
out.stderr.write(
|
|
623
|
-
`Still waiting for the account to connect
|
|
623
|
+
`Still waiting for the account to connect. The wait window elapsed. Check again: curviate account connect-session poll --session ${flags.session} --wait
|
|
624
624
|
`
|
|
625
625
|
);
|
|
626
626
|
process.exit(AUTH_NEEDED);
|
|
@@ -851,7 +851,7 @@ async function runAccountCheckpointPoll(client, flags, out, io = {}) {
|
|
|
851
851
|
}
|
|
852
852
|
renderSuccess(outcome.result, outOpts, out);
|
|
853
853
|
out.stderr.write(
|
|
854
|
-
`Still waiting for approval
|
|
854
|
+
`Still waiting for approval. The wait window elapsed. Check again: curviate account checkpoint poll ${accountId} --wait
|
|
855
855
|
`
|
|
856
856
|
);
|
|
857
857
|
process.exit(AUTH_NEEDED);
|
|
@@ -868,7 +868,7 @@ var accountListCommand = defineCommand({
|
|
|
868
868
|
profile: flags.profile
|
|
869
869
|
});
|
|
870
870
|
if (!cfg.apiKey) {
|
|
871
|
-
process.stderr.write("error: no API key
|
|
871
|
+
process.stderr.write("error: no API key, run `curviate login` or pass --api-key.\n");
|
|
872
872
|
process.exit(3);
|
|
873
873
|
}
|
|
874
874
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
@@ -892,7 +892,7 @@ var accountGetCommand = defineCommand({
|
|
|
892
892
|
profile: flags.profile
|
|
893
893
|
});
|
|
894
894
|
if (!cfg.apiKey) {
|
|
895
|
-
process.stderr.write("error: no API key
|
|
895
|
+
process.stderr.write("error: no API key, run `curviate login` or pass --api-key.\n");
|
|
896
896
|
process.exit(3);
|
|
897
897
|
}
|
|
898
898
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
@@ -924,10 +924,10 @@ var accountLinkCommand = defineCommand({
|
|
|
924
924
|
"proxy-password": { type: "string", description: `Proxy auth password. ${OPTIONAL_SECRET_WARNING("CURVIATE_PROXY_PASSWORD")}` },
|
|
925
925
|
"user-agent": { type: "string", description: "Browser User-Agent to pin for this account." },
|
|
926
926
|
"recruiter-contract-id": { type: "string", description: "Recruiter contract to bind to (Recruiter tier only)." },
|
|
927
|
-
"account-id": { type: "string", description: "Existing account id (acc_\u2026) to re-authenticate IN PLACE
|
|
927
|
+
"account-id": { type: "string", description: "Existing account id (acc_\u2026) to re-authenticate IN PLACE. Passing it makes this an in-place reconnect of that account. Omit to connect a NEW account into --seat-id." },
|
|
928
928
|
"no-interactive": {
|
|
929
929
|
type: "boolean",
|
|
930
|
-
description: "Never prompt for a checkpoint code
|
|
930
|
+
description: "Never prompt for a checkpoint code. On a checkpoint, always render the envelope and exit 12, even on a TTY.",
|
|
931
931
|
default: false
|
|
932
932
|
}
|
|
933
933
|
},
|
|
@@ -940,7 +940,7 @@ var accountLinkCommand = defineCommand({
|
|
|
940
940
|
profile: flags.profile
|
|
941
941
|
});
|
|
942
942
|
if (!cfg.apiKey) {
|
|
943
|
-
process.stderr.write("error: no API key
|
|
943
|
+
process.stderr.write("error: no API key, run `curviate login` or pass --api-key.\n");
|
|
944
944
|
process.exit(3);
|
|
945
945
|
}
|
|
946
946
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
@@ -951,7 +951,7 @@ var accountLinkCommand = defineCommand({
|
|
|
951
951
|
var accountConnectSessionPollCommand = defineCommand({
|
|
952
952
|
meta: {
|
|
953
953
|
name: "poll",
|
|
954
|
-
description: "Poll the status of an in-progress connect (auth intent) for completion. Without --wait: a single poll
|
|
954
|
+
description: "Poll the status of an in-progress connect (auth intent) for completion. Without --wait: a single poll. The JSON `status` field (pending | resolved | expired | failed) tells you what to do next. With --wait: block on the same adaptive cadence as `account link` until a terminal state."
|
|
955
955
|
},
|
|
956
956
|
args: {
|
|
957
957
|
...WRITE_SINGLE_FLAGS,
|
|
@@ -982,7 +982,7 @@ var accountConnectSessionPollCommand = defineCommand({
|
|
|
982
982
|
profile: flags.profile
|
|
983
983
|
});
|
|
984
984
|
if (!cfg.apiKey) {
|
|
985
|
-
process.stderr.write("error: no API key
|
|
985
|
+
process.stderr.write("error: no API key, run `curviate login` or pass --api-key.\n");
|
|
986
986
|
process.exit(3);
|
|
987
987
|
}
|
|
988
988
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
@@ -1004,7 +1004,7 @@ var accountUpdateCommand = defineCommand({
|
|
|
1004
1004
|
args: {
|
|
1005
1005
|
...WRITE_SINGLE_FLAGS,
|
|
1006
1006
|
"account-id": { type: "positional", description: "Account id (acc_\u2026)." },
|
|
1007
|
-
metadata: { type: "string", description: `Custom metadata as a JSON object (flat string\u2192string map)
|
|
1007
|
+
metadata: { type: "string", description: `Custom metadata as a JSON object (flat string\u2192string map). Replaces the store wholesale. Example: '{"team":"growth"}'.` },
|
|
1008
1008
|
"clear-proxy": { type: "boolean", description: "Clear the custom proxy (revert to automatic proxy protection). Mutually exclusive with --proxy-host.", default: false },
|
|
1009
1009
|
"proxy-protocol": { type: "string", description: "Proxy protocol: http | https | socks5." },
|
|
1010
1010
|
"proxy-host": { type: "string", description: "Proxy host or IP." },
|
|
@@ -1021,7 +1021,7 @@ var accountUpdateCommand = defineCommand({
|
|
|
1021
1021
|
profile: flags.profile
|
|
1022
1022
|
});
|
|
1023
1023
|
if (!cfg.apiKey) {
|
|
1024
|
-
process.stderr.write("error: no API key
|
|
1024
|
+
process.stderr.write("error: no API key, run `curviate login` or pass --api-key.\n");
|
|
1025
1025
|
process.exit(3);
|
|
1026
1026
|
}
|
|
1027
1027
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
@@ -1044,7 +1044,7 @@ var accountDisconnectCommand = defineCommand({
|
|
|
1044
1044
|
profile: flags.profile
|
|
1045
1045
|
});
|
|
1046
1046
|
if (!cfg.apiKey) {
|
|
1047
|
-
process.stderr.write("error: no API key
|
|
1047
|
+
process.stderr.write("error: no API key, run `curviate login` or pass --api-key.\n");
|
|
1048
1048
|
process.exit(3);
|
|
1049
1049
|
}
|
|
1050
1050
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
@@ -1075,7 +1075,7 @@ var accountCheckpointSolveCommand = defineCommand({
|
|
|
1075
1075
|
profile: flags.profile
|
|
1076
1076
|
});
|
|
1077
1077
|
if (!cfg.apiKey) {
|
|
1078
|
-
process.stderr.write("error: no API key
|
|
1078
|
+
process.stderr.write("error: no API key, run `curviate login` or pass --api-key.\n");
|
|
1079
1079
|
process.exit(3);
|
|
1080
1080
|
}
|
|
1081
1081
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
@@ -1105,7 +1105,7 @@ var accountCheckpointPollCommand = defineCommand({
|
|
|
1105
1105
|
// --timeout`. Default: the time remaining to the checkpoint's own expiry.
|
|
1106
1106
|
timeout: {
|
|
1107
1107
|
type: "string",
|
|
1108
|
-
description: "Wait-loop timeout in milliseconds (requires --wait; default: time remaining to the checkpoint's expiry). Note the unit: this is milliseconds
|
|
1108
|
+
description: "Wait-loop timeout in milliseconds (requires --wait; default: time remaining to the checkpoint's expiry). Note the unit: this is milliseconds; `inbox sync-chat --timeout` is seconds."
|
|
1109
1109
|
}
|
|
1110
1110
|
},
|
|
1111
1111
|
async run({ args }) {
|
|
@@ -1116,7 +1116,7 @@ var accountCheckpointPollCommand = defineCommand({
|
|
|
1116
1116
|
profile: flags.profile
|
|
1117
1117
|
});
|
|
1118
1118
|
if (!cfg.apiKey) {
|
|
1119
|
-
process.stderr.write("error: no API key
|
|
1119
|
+
process.stderr.write("error: no API key, run `curviate login` or pass --api-key.\n");
|
|
1120
1120
|
process.exit(3);
|
|
1121
1121
|
}
|
|
1122
1122
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
@@ -1127,7 +1127,7 @@ var accountCheckpointPollCommand = defineCommand({
|
|
|
1127
1127
|
var accountCheckpointRequestCommand = defineCommand({
|
|
1128
1128
|
meta: {
|
|
1129
1129
|
name: "request",
|
|
1130
|
-
description: "Re-request the challenge notification for a pending checkpoint (e.g. re-send an OTP email, SMS code, or mobile-app approval push). Not every challenge type supports it
|
|
1130
|
+
description: "Re-request the challenge notification for a pending checkpoint (e.g. re-send an OTP email, SMS code, or mobile-app approval push). Not every challenge type supports it; an authenticator- app code has nothing to re-send. The response's `resent` boolean tells you honestly whether a new notification actually went out; the command still exits 0 either way."
|
|
1131
1131
|
},
|
|
1132
1132
|
args: {
|
|
1133
1133
|
...WRITE_SINGLE_FLAGS,
|
|
@@ -1145,7 +1145,7 @@ var accountCheckpointRequestCommand = defineCommand({
|
|
|
1145
1145
|
profile: flags.profile
|
|
1146
1146
|
});
|
|
1147
1147
|
if (!cfg.apiKey) {
|
|
1148
|
-
process.stderr.write("error: no API key
|
|
1148
|
+
process.stderr.write("error: no API key, run `curviate login` or pass --api-key.\n");
|
|
1149
1149
|
process.exit(3);
|
|
1150
1150
|
}
|
|
1151
1151
|
const client = createClient({ apiKey: cfg.apiKey, baseUrl: cfg.baseUrl, timeout: cfg.timeout });
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
isStdinToken
|
|
4
|
+
} from "./chunk-ZYURL5VK.js";
|
|
2
5
|
|
|
3
6
|
// src/lib/search-filters.ts
|
|
4
7
|
import { readFile } from "fs/promises";
|
|
@@ -23,7 +26,7 @@ async function assembleFilters(flags, readers = DEFAULT_FILTER_READERS) {
|
|
|
23
26
|
} catch {
|
|
24
27
|
return { error: `cannot read ${source}` };
|
|
25
28
|
}
|
|
26
|
-
} else if (flags.filters
|
|
29
|
+
} else if (isStdinToken(flags.filters)) {
|
|
27
30
|
source = "--filters - (stdin)";
|
|
28
31
|
raw = await readers.readStdin();
|
|
29
32
|
} else if (flags.filters !== void 0) {
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
assertNoStdinPlaceholder
|
|
4
|
+
} from "./chunk-ZYURL5VK.js";
|
|
2
5
|
|
|
3
6
|
// src/lib/config.ts
|
|
4
7
|
import {
|
|
@@ -37,6 +40,7 @@ async function writeConfig(cfg) {
|
|
|
37
40
|
} catch {
|
|
38
41
|
}
|
|
39
42
|
const content = JSON.stringify(cfg, null, 2) + "\n";
|
|
43
|
+
assertNoStdinPlaceholder("the configuration about to be written", [content]);
|
|
40
44
|
const tmpPath = join(
|
|
41
45
|
tmpdir(),
|
|
42
46
|
`curviate-cfg-${randomBytes(6).toString("hex")}.tmp`
|
|
@@ -87,7 +91,7 @@ async function renameProfile(oldName, newName) {
|
|
|
87
91
|
}
|
|
88
92
|
if (cfg.profiles[newName]) {
|
|
89
93
|
throw new Error(
|
|
90
|
-
`Profile "${newName}" already exists
|
|
94
|
+
`Profile "${newName}" already exists. Remove it first or choose another name.`
|
|
91
95
|
);
|
|
92
96
|
}
|
|
93
97
|
cfg.profiles[newName] = cfg.profiles[oldName];
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/lib/bare-form-guard.ts
|
|
4
|
+
var COMMAND_WORD_RE = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
|
|
5
|
+
function looksLikeCommandWord(token) {
|
|
6
|
+
return COMMAND_WORD_RE.test(token);
|
|
7
|
+
}
|
|
8
|
+
function editDistance(a, b) {
|
|
9
|
+
const m = a.length;
|
|
10
|
+
const n = b.length;
|
|
11
|
+
if (m === 0) return n;
|
|
12
|
+
if (n === 0) return m;
|
|
13
|
+
const d = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
|
|
14
|
+
for (let i = 0; i <= m; i++) d[i][0] = i;
|
|
15
|
+
for (let j = 0; j <= n; j++) d[0][j] = j;
|
|
16
|
+
for (let i = 1; i <= m; i++) {
|
|
17
|
+
for (let j = 1; j <= n; j++) {
|
|
18
|
+
const cost = a[i - 1] === b[j - 1] ? 0 : 1;
|
|
19
|
+
let best = Math.min(
|
|
20
|
+
d[i - 1][j] + 1,
|
|
21
|
+
// deletion
|
|
22
|
+
d[i][j - 1] + 1,
|
|
23
|
+
// insertion
|
|
24
|
+
d[i - 1][j - 1] + cost
|
|
25
|
+
// substitution
|
|
26
|
+
);
|
|
27
|
+
if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {
|
|
28
|
+
best = Math.min(best, d[i - 2][j - 2] + 1);
|
|
29
|
+
}
|
|
30
|
+
d[i][j] = best;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return d[m][n];
|
|
34
|
+
}
|
|
35
|
+
function nearestSubcommand(token, subcommandNames) {
|
|
36
|
+
let best = null;
|
|
37
|
+
for (const name of subcommandNames) {
|
|
38
|
+
const threshold = name.length < 6 ? 1 : 2;
|
|
39
|
+
const isPrefix = token.length >= 2 && token.length < name.length && name.startsWith(token);
|
|
40
|
+
const distance = isPrefix ? 1 : editDistance(token, name);
|
|
41
|
+
if (distance > threshold) continue;
|
|
42
|
+
if (best === null || distance < best.distance) best = { name, distance };
|
|
43
|
+
}
|
|
44
|
+
return best?.name ?? null;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export {
|
|
48
|
+
looksLikeCommandWord,
|
|
49
|
+
nearestSubcommand
|
|
50
|
+
};
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
readConfig
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-CUTMZWL6.js";
|
|
5
|
+
import {
|
|
6
|
+
assertNoStdinPlaceholder
|
|
7
|
+
} from "./chunk-ZYURL5VK.js";
|
|
5
8
|
|
|
6
9
|
// src/lib/resolve.ts
|
|
7
10
|
var DEFAULT_BASE_URL = "https://api.curviate.com";
|
|
@@ -20,9 +23,28 @@ async function resolveEffectiveConfig(flags) {
|
|
|
20
23
|
|
|
21
24
|
// src/lib/client.ts
|
|
22
25
|
import { Curviate } from "@curviate/sdk";
|
|
26
|
+
function headerStrings(headers) {
|
|
27
|
+
if (!headers) return [];
|
|
28
|
+
if (headers instanceof Headers) {
|
|
29
|
+
const out = [];
|
|
30
|
+
headers.forEach((value, key) => out.push(key, value));
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
if (Array.isArray(headers)) return headers.flat().map(String);
|
|
34
|
+
return Object.entries(headers).flat().map(String);
|
|
35
|
+
}
|
|
36
|
+
var guardedFetch = (input, init) => {
|
|
37
|
+
assertNoStdinPlaceholder("the request about to be sent", [
|
|
38
|
+
String(input instanceof Request ? input.url : input),
|
|
39
|
+
...headerStrings(init?.headers),
|
|
40
|
+
typeof init?.body === "string" ? init.body : void 0
|
|
41
|
+
]);
|
|
42
|
+
return fetch(input, init);
|
|
43
|
+
};
|
|
23
44
|
function createClient(config) {
|
|
24
45
|
return new Curviate({
|
|
25
46
|
apiKey: config.apiKey.trim(),
|
|
47
|
+
fetch: guardedFetch,
|
|
26
48
|
...config.baseUrl !== void 0 ? { baseUrl: config.baseUrl } : {},
|
|
27
49
|
...config.timeout !== void 0 ? { timeout: config.timeout } : {}
|
|
28
50
|
});
|