primcli 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 +89 -0
- package/bin/run.js +16 -0
- package/dist/cli-config-B5hrwe8q.js +1330 -0
- package/dist/oclif/index.js +22646 -0
- package/dist/oclif/proxy-auto-detect.js +71 -0
- package/dist/oclif/root-signup-hint.js +136 -0
- package/man/primitive.1 +111 -0
- package/package.json +143 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
//#region src/oclif/proxy-auto-detect.ts
|
|
3
|
+
const PROXY_ENV_VARS = [
|
|
4
|
+
"HTTP_PROXY",
|
|
5
|
+
"HTTPS_PROXY",
|
|
6
|
+
"http_proxy",
|
|
7
|
+
"https_proxy"
|
|
8
|
+
];
|
|
9
|
+
let hintPrinted = false;
|
|
10
|
+
function _resetHintLatchForTest() {
|
|
11
|
+
hintPrinted = false;
|
|
12
|
+
}
|
|
13
|
+
function detectProxyVars(env) {
|
|
14
|
+
return PROXY_ENV_VARS.filter((name) => {
|
|
15
|
+
const value = env[name];
|
|
16
|
+
return typeof value === "string" && value.length > 0;
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
function restartWithProxyEnvIfNeeded(options = {}) {
|
|
20
|
+
const env = options.env ?? process.env;
|
|
21
|
+
const stderr = options.stderr ?? process.stderr;
|
|
22
|
+
const detectedVars = detectProxyVars(env);
|
|
23
|
+
if (detectedVars.length === 0) return {
|
|
24
|
+
applied: false,
|
|
25
|
+
detectedVars: [],
|
|
26
|
+
reason: "no_proxy_env"
|
|
27
|
+
};
|
|
28
|
+
if (Object.hasOwn(env, "NODE_USE_ENV_PROXY")) return {
|
|
29
|
+
applied: false,
|
|
30
|
+
detectedVars,
|
|
31
|
+
reason: "node_use_env_proxy_already_set"
|
|
32
|
+
};
|
|
33
|
+
const argv = options.argv ?? process.argv;
|
|
34
|
+
const entrypoint = argv[1];
|
|
35
|
+
if (!entrypoint) return {
|
|
36
|
+
applied: false,
|
|
37
|
+
detectedVars,
|
|
38
|
+
reason: "missing_entrypoint"
|
|
39
|
+
};
|
|
40
|
+
const execPath = options.execPath ?? process.execPath;
|
|
41
|
+
const execArgv = options.execArgv ?? process.execArgv;
|
|
42
|
+
const spawn = options.spawn ?? spawnSync;
|
|
43
|
+
const exit = options.exit ?? ((code) => {
|
|
44
|
+
process.exit(code);
|
|
45
|
+
throw new Error("process.exit returned unexpectedly");
|
|
46
|
+
});
|
|
47
|
+
if (!hintPrinted) {
|
|
48
|
+
hintPrinted = true;
|
|
49
|
+
const names = detectedVars.join("/");
|
|
50
|
+
stderr.write(`primitive: proxy detected via ${names}, restarting with NODE_USE_ENV_PROXY=1\n`);
|
|
51
|
+
}
|
|
52
|
+
const child = spawn(execPath, [
|
|
53
|
+
...execArgv,
|
|
54
|
+
entrypoint,
|
|
55
|
+
...argv.slice(2)
|
|
56
|
+
], {
|
|
57
|
+
env: {
|
|
58
|
+
...env,
|
|
59
|
+
NODE_USE_ENV_PROXY: "1"
|
|
60
|
+
},
|
|
61
|
+
stdio: "inherit"
|
|
62
|
+
});
|
|
63
|
+
if (child.error) throw child.error;
|
|
64
|
+
if (child.signal) {
|
|
65
|
+
(options.kill ?? process.kill)(options.pid ?? process.pid, child.signal);
|
|
66
|
+
return exit(1);
|
|
67
|
+
}
|
|
68
|
+
return exit(child.status ?? 1);
|
|
69
|
+
}
|
|
70
|
+
//#endregion
|
|
71
|
+
export { _resetHintLatchForTest, restartWithProxyEnvIfNeeded };
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { c as resolveConfigEnvironment, i as loadCliConfig, x as normalizeApiBaseUrl } from "../cli-config-B5hrwe8q.js";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
//#region src/oclif/root-signup-hint.ts
|
|
6
|
+
const CREDENTIALS_FILE = "credentials.json";
|
|
7
|
+
const ROOT_AUTH_TIMEOUT_MS = 1e3;
|
|
8
|
+
function activeConfigDir(env, home) {
|
|
9
|
+
if (env.PRIMITIVE_CONFIG_DIR) return env.PRIMITIVE_CONFIG_DIR;
|
|
10
|
+
return join(env.XDG_CONFIG_HOME || join(home, ".config"), "primitive");
|
|
11
|
+
}
|
|
12
|
+
function readRootCredentials(configDir) {
|
|
13
|
+
let raw;
|
|
14
|
+
try {
|
|
15
|
+
raw = readFileSync(join(configDir, CREDENTIALS_FILE), "utf8");
|
|
16
|
+
} catch {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
try {
|
|
20
|
+
const parsed = JSON.parse(raw);
|
|
21
|
+
if (parsed.auth_method !== "oauth") return null;
|
|
22
|
+
if (typeof parsed.access_token !== "string" || !parsed.access_token.trim()) return null;
|
|
23
|
+
const apiBaseUrl = parsed.api_base_url ?? parsed.api_base_url_1;
|
|
24
|
+
if (typeof apiBaseUrl !== "string" || !apiBaseUrl.trim()) return null;
|
|
25
|
+
return {
|
|
26
|
+
accessToken: parsed.access_token,
|
|
27
|
+
apiBaseUrl: apiBaseUrl.replace(/\/+$/, "")
|
|
28
|
+
};
|
|
29
|
+
} catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function accountEndpoint(apiBaseUrl) {
|
|
34
|
+
return `${apiBaseUrl.replace(/\/+$/, "")}/account`;
|
|
35
|
+
}
|
|
36
|
+
function parseRootAccount(payload) {
|
|
37
|
+
if (payload === null || typeof payload !== "object" || Array.isArray(payload)) return null;
|
|
38
|
+
const data = payload.data;
|
|
39
|
+
if (data === null || typeof data !== "object" || Array.isArray(data)) return null;
|
|
40
|
+
const account = data;
|
|
41
|
+
if (typeof account.email !== "string" || !account.email.trim()) return null;
|
|
42
|
+
if (typeof account.id !== "string" || !account.id.trim()) return null;
|
|
43
|
+
return {
|
|
44
|
+
email: account.email,
|
|
45
|
+
id: account.id
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function rootAuthLine(account) {
|
|
49
|
+
return `Signed in as ${account.email} (org ${account.id})\n\n`;
|
|
50
|
+
}
|
|
51
|
+
function rootRequestConfig(configDir, env) {
|
|
52
|
+
const currentEnvironment = resolveConfigEnvironment(loadCliConfig(configDir));
|
|
53
|
+
const configuredApiBaseUrl = currentEnvironment?.config.api_base_url;
|
|
54
|
+
const envApiBaseUrl = env.PRIMITIVE_API_BASE_URL?.trim();
|
|
55
|
+
if (currentEnvironment !== null && currentEnvironment.name !== "default" && !envApiBaseUrl && !configuredApiBaseUrl) return null;
|
|
56
|
+
return {
|
|
57
|
+
apiBaseUrl: normalizeApiBaseUrl(envApiBaseUrl || configuredApiBaseUrl),
|
|
58
|
+
headers: currentEnvironment?.config.headers
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
async function fetchRootAccount(params) {
|
|
62
|
+
const controller = new AbortController();
|
|
63
|
+
const timer = setTimeout(() => controller.abort(), params.timeoutMs);
|
|
64
|
+
try {
|
|
65
|
+
const response = await params.fetch(accountEndpoint(params.apiBaseUrl), {
|
|
66
|
+
headers: {
|
|
67
|
+
...params.headers ?? {},
|
|
68
|
+
accept: "application/json",
|
|
69
|
+
authorization: `Bearer ${params.apiKey}`
|
|
70
|
+
},
|
|
71
|
+
signal: controller.signal
|
|
72
|
+
});
|
|
73
|
+
if (!response.ok) return null;
|
|
74
|
+
return parseRootAccount(await response.json().catch(() => null));
|
|
75
|
+
} catch {
|
|
76
|
+
return null;
|
|
77
|
+
} finally {
|
|
78
|
+
clearTimeout(timer);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async function rootSignedInSummary(options = {}) {
|
|
82
|
+
if ((options.argv ?? process.argv.slice(2)).length > 0) return null;
|
|
83
|
+
const env = options.env ?? process.env;
|
|
84
|
+
const configDir = activeConfigDir(env, options.home ?? homedir());
|
|
85
|
+
let requestConfig;
|
|
86
|
+
try {
|
|
87
|
+
requestConfig = rootRequestConfig(configDir, env);
|
|
88
|
+
} catch {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
if (!requestConfig) return null;
|
|
92
|
+
const explicitApiKey = env.PRIMITIVE_API_KEY?.trim();
|
|
93
|
+
const stored = explicitApiKey ? null : readRootCredentials(configDir);
|
|
94
|
+
const apiKey = explicitApiKey || stored?.accessToken;
|
|
95
|
+
if (!apiKey) return null;
|
|
96
|
+
const account = await fetchRootAccount({
|
|
97
|
+
apiBaseUrl: stored?.apiBaseUrl ?? requestConfig.apiBaseUrl,
|
|
98
|
+
apiKey,
|
|
99
|
+
fetch: options.fetch ?? fetch,
|
|
100
|
+
headers: requestConfig.headers,
|
|
101
|
+
timeoutMs: options.timeoutMs ?? ROOT_AUTH_TIMEOUT_MS
|
|
102
|
+
});
|
|
103
|
+
return account ? rootAuthLine(account) : null;
|
|
104
|
+
}
|
|
105
|
+
function shouldShowLoggedOutSignupHint(options = {}) {
|
|
106
|
+
if ((options.argv ?? process.argv.slice(2)).length > 0) return false;
|
|
107
|
+
const env = options.env ?? process.env;
|
|
108
|
+
if (env.PRIMITIVE_HIDE_SIGNUP_HINT === "1") return false;
|
|
109
|
+
if (env.PRIMITIVE_API_KEY?.trim()) return false;
|
|
110
|
+
return !existsSync(join(activeConfigDir(env, options.home ?? homedir()), CREDENTIALS_FILE));
|
|
111
|
+
}
|
|
112
|
+
function loggedOutSignupHint() {
|
|
113
|
+
return [
|
|
114
|
+
"New to Primitive?",
|
|
115
|
+
" You or your user don't have an account yet?",
|
|
116
|
+
" Run `primitive signup <email> --accept-terms`",
|
|
117
|
+
" to create an account and get started.",
|
|
118
|
+
" Add `--signup-code <code>` if you have one.",
|
|
119
|
+
""
|
|
120
|
+
].join("\n");
|
|
121
|
+
}
|
|
122
|
+
function writeLoggedOutSignupHintIfNeeded(options = {}) {
|
|
123
|
+
if (!shouldShowLoggedOutSignupHint(options)) return;
|
|
124
|
+
(options.write ?? ((message) => process.stdout.write(message)))(loggedOutSignupHint());
|
|
125
|
+
}
|
|
126
|
+
async function writeRootAuthContextIfNeeded(options = {}) {
|
|
127
|
+
const write = options.write ?? ((message) => process.stdout.write(message));
|
|
128
|
+
const signedIn = await rootSignedInSummary(options);
|
|
129
|
+
if (signedIn) {
|
|
130
|
+
write(signedIn);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
writeLoggedOutSignupHintIfNeeded(options);
|
|
134
|
+
}
|
|
135
|
+
//#endregion
|
|
136
|
+
export { loggedOutSignupHint, rootSignedInSummary, shouldShowLoggedOutSignupHint, writeLoggedOutSignupHintIfNeeded, writeRootAuthContextIfNeeded };
|
package/man/primitive.1
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
.TH PRIMITIVE 1
|
|
2
|
+
.SH NAME
|
|
3
|
+
primitive \- command line interface for Primitive email and Functions
|
|
4
|
+
.SH SYNOPSIS
|
|
5
|
+
.B primitive
|
|
6
|
+
.I command
|
|
7
|
+
[\fIoptions\fR]
|
|
8
|
+
.br
|
|
9
|
+
.B primitive
|
|
10
|
+
.B --help
|
|
11
|
+
.br
|
|
12
|
+
.B primitive
|
|
13
|
+
.I command
|
|
14
|
+
.B --help
|
|
15
|
+
.SH DESCRIPTION
|
|
16
|
+
.B primitive
|
|
17
|
+
is the command line interface for Primitive. It sends mail, inspects inbound and outbound email, manages domains and webhook endpoints, deploys Primitive Functions, and exposes generated API operations for scripting.
|
|
18
|
+
.PP
|
|
19
|
+
Most commands print human-readable output by default. Commands that expose JSON usually provide a
|
|
20
|
+
.B --json
|
|
21
|
+
flag or use generated operation output that can be piped into tools such as
|
|
22
|
+
.BR jq (1).
|
|
23
|
+
.SH AUTHENTICATION
|
|
24
|
+
Commands use saved OAuth credentials from
|
|
25
|
+
.B primitive signin
|
|
26
|
+
or
|
|
27
|
+
.B primitive login
|
|
28
|
+
or an API key from
|
|
29
|
+
.B --api-key
|
|
30
|
+
or
|
|
31
|
+
.BR PRIMITIVE_API_KEY .
|
|
32
|
+
.PP
|
|
33
|
+
Run
|
|
34
|
+
.B primitive signin EMAIL --signup-code CODE --accept-terms
|
|
35
|
+
to start email-code sign-in, then run
|
|
36
|
+
.B primitive signin confirm EMAIL CODE
|
|
37
|
+
with the emailed verification code.
|
|
38
|
+
.B primitive login EMAIL
|
|
39
|
+
and
|
|
40
|
+
.B primitive otp EMAIL
|
|
41
|
+
support the same email-code flow. Run
|
|
42
|
+
.B primitive signin
|
|
43
|
+
or
|
|
44
|
+
.B primitive login
|
|
45
|
+
with no email to use browser approval.
|
|
46
|
+
.PP
|
|
47
|
+
Run
|
|
48
|
+
.B primitive logout --force
|
|
49
|
+
to remove local credentials, pending email-code auth state, and stale credential locks without contacting Primitive.
|
|
50
|
+
.PP
|
|
51
|
+
Run
|
|
52
|
+
.B primitive whoami
|
|
53
|
+
to verify which account the CLI is authenticated as.
|
|
54
|
+
.SH COMMON COMMANDS
|
|
55
|
+
.TP
|
|
56
|
+
.B primitive send --to ADDRESS --subject SUBJECT --body TEXT
|
|
57
|
+
Send an outbound email.
|
|
58
|
+
.TP
|
|
59
|
+
.B primitive send --to ADDRESS --body TEXT --attachment PATH
|
|
60
|
+
Send an outbound email with a file attachment.
|
|
61
|
+
.TP
|
|
62
|
+
.B primitive domains add DOMAIN
|
|
63
|
+
Start a custom-domain claim.
|
|
64
|
+
.TP
|
|
65
|
+
.B primitive domains verify --id DOMAIN_ID
|
|
66
|
+
Verify DNS records for a pending domain claim.
|
|
67
|
+
.TP
|
|
68
|
+
.B primitive domains zone-file --id DOMAIN_ID
|
|
69
|
+
Download DNS records as a BIND-format zone file.
|
|
70
|
+
.TP
|
|
71
|
+
.B primitive emails latest
|
|
72
|
+
Show recent inbound emails.
|
|
73
|
+
.TP
|
|
74
|
+
.B primitive functions init NAME
|
|
75
|
+
Scaffold a Primitive Function.
|
|
76
|
+
.TP
|
|
77
|
+
.B primitive functions deploy --name NAME --file PATH
|
|
78
|
+
Deploy a Primitive Function bundle.
|
|
79
|
+
.TP
|
|
80
|
+
.B primitive list-operations
|
|
81
|
+
Print the generated API operation manifest.
|
|
82
|
+
.TP
|
|
83
|
+
.B primitive describe COMMAND_OR_OPERATION
|
|
84
|
+
Describe a generated API operation, including request and response schemas.
|
|
85
|
+
.SH GLOBAL OPTIONS
|
|
86
|
+
.TP
|
|
87
|
+
.B --api-key KEY
|
|
88
|
+
Use an explicit Primitive API key for this command.
|
|
89
|
+
.TP
|
|
90
|
+
.B --time
|
|
91
|
+
Print command duration to standard error after completion.
|
|
92
|
+
.TP
|
|
93
|
+
.B --help
|
|
94
|
+
Show command help.
|
|
95
|
+
.SH ENVIRONMENT
|
|
96
|
+
.TP
|
|
97
|
+
.B PRIMITIVE_API_KEY
|
|
98
|
+
API key used when
|
|
99
|
+
.B --api-key
|
|
100
|
+
is not supplied and no saved OAuth credential should be used.
|
|
101
|
+
.TP
|
|
102
|
+
.B PRIMITIVE_API_BASE_URL
|
|
103
|
+
Override the API base URL. Intended for development and testing.
|
|
104
|
+
.SH FILES
|
|
105
|
+
.TP
|
|
106
|
+
.I ~/.config/primitive
|
|
107
|
+
Default CLI configuration directory used by oclif on most systems.
|
|
108
|
+
.SH SEE ALSO
|
|
109
|
+
.B primitive --help
|
|
110
|
+
.br
|
|
111
|
+
Primitive documentation: https://primitive.dev
|
package/package.json
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "primcli",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "Official Primitive CLI: deploy Primitive Functions, send and inspect mail, manage endpoints, all from the terminal. Wraps the @primitivedotdev/sdk runtime client with one-shot commands.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"files": [
|
|
8
|
+
"bin",
|
|
9
|
+
"dist",
|
|
10
|
+
"man"
|
|
11
|
+
],
|
|
12
|
+
"bin": {
|
|
13
|
+
"primitive": "./bin/run.js",
|
|
14
|
+
"prim": "./bin/run.js"
|
|
15
|
+
},
|
|
16
|
+
"man": [
|
|
17
|
+
"./man/primitive.1"
|
|
18
|
+
],
|
|
19
|
+
"oclif": {
|
|
20
|
+
"bin": "primitive",
|
|
21
|
+
"commands": {
|
|
22
|
+
"strategy": "explicit",
|
|
23
|
+
"target": "./dist/oclif/index.js",
|
|
24
|
+
"identifier": "COMMANDS"
|
|
25
|
+
},
|
|
26
|
+
"dirname": "primitive",
|
|
27
|
+
"plugins": [
|
|
28
|
+
"@oclif/plugin-help",
|
|
29
|
+
"@oclif/plugin-autocomplete",
|
|
30
|
+
"@oclif/plugin-warn-if-update-available"
|
|
31
|
+
],
|
|
32
|
+
"warn-if-update-available": {
|
|
33
|
+
"timeoutInDays": 1,
|
|
34
|
+
"frequency": 1,
|
|
35
|
+
"frequencyUnit": "days",
|
|
36
|
+
"message": "Primitive CLI update available from <%= chalk.greenBright(config.version) %> to <%= chalk.greenBright(latest) %>. Run `npm install -g @primitivedotdev/cli@latest` to update."
|
|
37
|
+
},
|
|
38
|
+
"topics": {
|
|
39
|
+
"chat": {
|
|
40
|
+
"description": "Chat with agents over email. Use `primitive chat <email> <message>` to start, `primitive chat reply <message>` to continue the active chat, or `primitive chat reply <id> <message>` to reply in a specific local chat."
|
|
41
|
+
},
|
|
42
|
+
"cli": {
|
|
43
|
+
"description": "CLI authentication"
|
|
44
|
+
},
|
|
45
|
+
"config": {
|
|
46
|
+
"description": "Manage local Primitive CLI request environments",
|
|
47
|
+
"hidden": true
|
|
48
|
+
},
|
|
49
|
+
"account": {
|
|
50
|
+
"description": "Manage your account settings, storage, and webhook secret"
|
|
51
|
+
},
|
|
52
|
+
"agent": {
|
|
53
|
+
"description": "Agent signup and authentication API operations"
|
|
54
|
+
},
|
|
55
|
+
"domains": {
|
|
56
|
+
"description": "Claim, verify, manage email domains, and download DNS zone files"
|
|
57
|
+
},
|
|
58
|
+
"inbox": {
|
|
59
|
+
"description": "Check inbound email setup and processing readiness. Prefer `primitive inbox setup` for a guided setup path and `primitive inbox status` for the readiness table."
|
|
60
|
+
},
|
|
61
|
+
"emails": {
|
|
62
|
+
"description": "List, inspect, and wait for received emails. Prefer task aliases like `primitive emails list`, `primitive emails get`, `primitive emails latest`, `primitive emails wait`, and `primitive emails watch`; generated API names remain available for compatibility."
|
|
63
|
+
},
|
|
64
|
+
"search": {
|
|
65
|
+
"description": "Cross-corpus semantic search. Prefer `primitive search <query>` for lexical inbound search and `primitive semantic-search <query>` for meaning-aware ranking across inbound and outbound.",
|
|
66
|
+
"hidden": true
|
|
67
|
+
},
|
|
68
|
+
"sending": {
|
|
69
|
+
"description": "Send outbound emails. Prefer `primitive send` for fresh sends and `primitive reply --id <inbound-id>` for replies. Use `primitive domains list` or `primitive inbox status` to find usable sender domains for --from; `primitive sending permissions` lists recipient-scope destinations you may send to."
|
|
70
|
+
},
|
|
71
|
+
"signin": {
|
|
72
|
+
"description": "Sign in to an existing Primitive account"
|
|
73
|
+
},
|
|
74
|
+
"login": {
|
|
75
|
+
"description": "Log in to an existing Primitive account"
|
|
76
|
+
},
|
|
77
|
+
"otp": {
|
|
78
|
+
"description": "Authenticate with an emailed one-time code"
|
|
79
|
+
},
|
|
80
|
+
"sent": {
|
|
81
|
+
"description": "Short aliases for outbound sent-email history: `primitive sent list` and `primitive sent get`."
|
|
82
|
+
},
|
|
83
|
+
"threads": {
|
|
84
|
+
"description": "Inspect conversation threads spanning received and sent emails. Prefer `primitive threads get --id <thread-id>`; generated API name `primitive threads get-thread --id <thread-id>` remains available."
|
|
85
|
+
},
|
|
86
|
+
"endpoints": {
|
|
87
|
+
"description": "Manage webhook endpoints that receive email events"
|
|
88
|
+
},
|
|
89
|
+
"filters": {
|
|
90
|
+
"description": "Manage whitelist and blocklist filter rules"
|
|
91
|
+
},
|
|
92
|
+
"webhook-deliveries": {
|
|
93
|
+
"description": "View and replay webhook delivery attempts. Prefer `primitive webhook-deliveries list` and `primitive webhook-deliveries replay`."
|
|
94
|
+
},
|
|
95
|
+
"deliveries": {
|
|
96
|
+
"description": "Short aliases for webhook delivery attempts: `primitive deliveries list` and `primitive deliveries replay`."
|
|
97
|
+
},
|
|
98
|
+
"functions": {
|
|
99
|
+
"description": "Deploy JavaScript handlers that run on inbound mail. Prefer `primitive functions templates`, `primitive functions init`, `primitive functions deploy`, `primitive functions redeploy`, `primitive functions list`, `primitive functions get`, `primitive functions logs`, and `primitive functions set-secret`; generated API names remain available for compatibility."
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
"topicSeparator": " "
|
|
103
|
+
},
|
|
104
|
+
"keywords": [
|
|
105
|
+
"primitive",
|
|
106
|
+
"cli",
|
|
107
|
+
"email",
|
|
108
|
+
"functions",
|
|
109
|
+
"webhook"
|
|
110
|
+
],
|
|
111
|
+
"author": "Primitive <support@primitive.dev>",
|
|
112
|
+
"license": "MIT",
|
|
113
|
+
"repository": {
|
|
114
|
+
"type": "git",
|
|
115
|
+
"url": "git+https://github.com/primitivedotdev/sdks.git",
|
|
116
|
+
"directory": "cli-node"
|
|
117
|
+
},
|
|
118
|
+
"bugs": {
|
|
119
|
+
"url": "https://github.com/primitivedotdev/sdks/issues"
|
|
120
|
+
},
|
|
121
|
+
"homepage": "https://primitive.dev",
|
|
122
|
+
"engines": {
|
|
123
|
+
"node": ">=22"
|
|
124
|
+
},
|
|
125
|
+
"dependencies": {
|
|
126
|
+
"@oclif/core": "^4.10.5",
|
|
127
|
+
"@oclif/plugin-autocomplete": "^3.2.45",
|
|
128
|
+
"@oclif/plugin-help": "^6.2.44",
|
|
129
|
+
"@oclif/plugin-warn-if-update-available": "^3.1.65"
|
|
130
|
+
},
|
|
131
|
+
"devDependencies": {
|
|
132
|
+
"@biomejs/biome": "^2.4.10",
|
|
133
|
+
"@primitivedotdev/api-core": "workspace:*",
|
|
134
|
+
"@types/node": "^22.10.2",
|
|
135
|
+
"@vitest/coverage-v8": "^4.1.4",
|
|
136
|
+
"oclif": "^4.23.0",
|
|
137
|
+
"tsdown": "^0.21.10",
|
|
138
|
+
"tsx": "^4.21.0",
|
|
139
|
+
"typescript": "^5.7.2",
|
|
140
|
+
"vite": "^8.0.8",
|
|
141
|
+
"vitest": "^4.1.4"
|
|
142
|
+
}
|
|
143
|
+
}
|