@naturali/cli 0.27.3 → 0.28.1
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 +19 -10
- package/dist/index.mjs +88 -116
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -5,23 +5,19 @@ operation, generated from the [OpenAPI specs](../../api/openapi/).
|
|
|
5
5
|
|
|
6
6
|
```bash
|
|
7
7
|
pnpm add -g @naturali/cli
|
|
8
|
-
|
|
8
|
+
export NATURALI_TOKEN=nat_sk_...
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
## Configuration
|
|
12
12
|
|
|
13
|
-
`naturali
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
Environment variables take precedence, which is what CI should use:
|
|
13
|
+
The CLI always talks to `https://api.naturali.ai` — the only naturali.ai API
|
|
14
|
+
origin, and not configurable. Credentials and the default project come from
|
|
15
|
+
the environment:
|
|
18
16
|
|
|
19
17
|
| Variable | Purpose |
|
|
20
18
|
| --- | --- |
|
|
21
|
-
| `NATURALI_TOKEN` | Bearer credential
|
|
22
|
-
| `
|
|
23
|
-
|
|
24
|
-
Use `--profile <name>` to switch profiles per command.
|
|
19
|
+
| `NATURALI_TOKEN` | Bearer credential (`nat_sk_…` or a session JWT). Required. |
|
|
20
|
+
| `NATURALI_PROJECT` | Default `--project-id` for commands that take one. An explicit `--project-id` still wins. |
|
|
25
21
|
|
|
26
22
|
## Commands
|
|
27
23
|
|
|
@@ -92,6 +88,19 @@ pipeline.
|
|
|
92
88
|
Hand-written source is limited to dispatch, flag parsing, credentials and help;
|
|
93
89
|
there is no per-endpoint code.
|
|
94
90
|
|
|
91
|
+
## Testing
|
|
92
|
+
|
|
93
|
+
`pnpm test` runs the unit suite against a mocked `fetch` — flag parsing,
|
|
94
|
+
dispatch, and help output, on every pull request.
|
|
95
|
+
|
|
96
|
+
`pnpm e2e` (`tests/e2e/smoke.ts`) is different: it drives the *built* CLI
|
|
97
|
+
binary (`bin/naturali`) as real subprocesses against the real, deployed API,
|
|
98
|
+
using a `NATURALI_E2E_API_KEY` account-scoped key. It proves the one thing the
|
|
99
|
+
mocked suite can't — that the CLI, the `@naturali/sdk` it bundles, and the live
|
|
100
|
+
API actually agree — and it provisions and archives its own throwaway project.
|
|
101
|
+
It costs real model-provider money, so it only runs as part of the `e2e` job in
|
|
102
|
+
[`main.yml`](../../.github/workflows/main.yml), never on pull requests.
|
|
103
|
+
|
|
95
104
|
## Versioning
|
|
96
105
|
|
|
97
106
|
Releases are automatic, and the version is **shared with the API and with
|
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as nodePath from "node:path";
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
|
-
import password from "@inquirer/password";
|
|
4
3
|
import { Command } from "commander";
|
|
5
|
-
import * as fs from "node:fs";
|
|
6
|
-
import * as os from "node:os";
|
|
7
4
|
//#region \0rolldown/runtime.js
|
|
8
5
|
var __defProp = Object.defineProperty;
|
|
9
6
|
var __exportAll = (all, no_symbols) => {
|
|
@@ -17,7 +14,7 @@ var __exportAll = (all, no_symbols) => {
|
|
|
17
14
|
};
|
|
18
15
|
//#endregion
|
|
19
16
|
//#region package.json
|
|
20
|
-
var version = "0.
|
|
17
|
+
var version = "0.28.1";
|
|
21
18
|
//#endregion
|
|
22
19
|
//#region ../sdk/src/generated/core/bodySerializer.gen.ts
|
|
23
20
|
const jsonBodySerializer = { bodySerializer: (body) => JSON.stringify(body, (_key, value) => typeof value === "bigint" ? value.toString() : value) };
|
|
@@ -1302,7 +1299,7 @@ var Knowledge = class {
|
|
|
1302
1299
|
*/
|
|
1303
1300
|
static queryKnowledgeCollection(options) {
|
|
1304
1301
|
return (options.client ?? client).post({
|
|
1305
|
-
url: "/v1/projects/{project_id}/knowledge/collections/{collection_id}",
|
|
1302
|
+
url: "/v1/projects/{project_id}/knowledge/collections/{collection_id}:query",
|
|
1306
1303
|
...options,
|
|
1307
1304
|
headers: {
|
|
1308
1305
|
"Content-Type": "application/json",
|
|
@@ -1365,7 +1362,7 @@ var Knowledge = class {
|
|
|
1365
1362
|
*/
|
|
1366
1363
|
static reingestKnowledgeDocument(options) {
|
|
1367
1364
|
return (options.client ?? client).post({
|
|
1368
|
-
url: "/v1/projects/{project_id}/knowledge/collections/{collection_id}/documents/{document_id}",
|
|
1365
|
+
url: "/v1/projects/{project_id}/knowledge/collections/{collection_id}/documents/{document_id}:reingest",
|
|
1369
1366
|
...options
|
|
1370
1367
|
});
|
|
1371
1368
|
}
|
|
@@ -1822,24 +1819,6 @@ var src_exports = /* @__PURE__ */ __exportAll({
|
|
|
1822
1819
|
//#region src/config.ts
|
|
1823
1820
|
/** The naturali.ai API origin. Not configurable — there is only one. */
|
|
1824
1821
|
const API_BASE_URL = "https://api.naturali.ai";
|
|
1825
|
-
const CONFIG_FILE = path.join(os.homedir(), ".naturali", "config.json");
|
|
1826
|
-
const readConfig = () => {
|
|
1827
|
-
try {
|
|
1828
|
-
return JSON.parse(fs.readFileSync(CONFIG_FILE, "utf8"));
|
|
1829
|
-
} catch {
|
|
1830
|
-
return {};
|
|
1831
|
-
}
|
|
1832
|
-
};
|
|
1833
|
-
const writeProfile = (name, profile) => {
|
|
1834
|
-
const config = readConfig();
|
|
1835
|
-
config[name] = profile;
|
|
1836
|
-
fs.mkdirSync(path.dirname(CONFIG_FILE), { recursive: true });
|
|
1837
|
-
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
1838
|
-
};
|
|
1839
|
-
/** Where the config file lives, so `configure` can name it in its output. */
|
|
1840
|
-
const configFilePath = () => {
|
|
1841
|
-
return CONFIG_FILE;
|
|
1842
|
-
};
|
|
1843
1822
|
const buildClient = (args) => {
|
|
1844
1823
|
const { token } = args;
|
|
1845
1824
|
return createClient(createConfig({
|
|
@@ -1848,20 +1827,14 @@ const buildClient = (args) => {
|
|
|
1848
1827
|
}));
|
|
1849
1828
|
};
|
|
1850
1829
|
/**
|
|
1851
|
-
* Resolves credentials
|
|
1830
|
+
* Resolves credentials from `NATURALI_TOKEN`.
|
|
1852
1831
|
*
|
|
1853
|
-
*
|
|
1854
|
-
* 2. A named profile (`--profile` → `NATURALI_PROFILE` → `default`).
|
|
1855
|
-
*
|
|
1856
|
-
* Exits with an actionable message when neither applies.
|
|
1832
|
+
* Exits with an actionable message when it is unset.
|
|
1857
1833
|
*/
|
|
1858
|
-
const resolveContext = (
|
|
1859
|
-
const
|
|
1860
|
-
if (
|
|
1861
|
-
|
|
1862
|
-
const profile = readConfig()[name];
|
|
1863
|
-
if (profile) return { client: buildClient({ token: profile.token }) };
|
|
1864
|
-
console.error(`Profile "${name}" not found. Run: naturali configure${name !== "default" ? ` --profile ${name}` : ""}\nOr set NATURALI_TOKEN in the environment.`);
|
|
1834
|
+
const resolveContext = () => {
|
|
1835
|
+
const token = process.env["NATURALI_TOKEN"];
|
|
1836
|
+
if (token) return { client: buildClient({ token }) };
|
|
1837
|
+
console.error("NATURALI_TOKEN is not set. Set it to a nat_sk_… API key or a session JWT.");
|
|
1865
1838
|
process.exit(1);
|
|
1866
1839
|
};
|
|
1867
1840
|
//#endregion
|
|
@@ -1954,10 +1927,6 @@ const buildArrayFlagValue = (rawValues) => {
|
|
|
1954
1927
|
const oneLine = (text) => {
|
|
1955
1928
|
return text.replace(/\s+/g, " ").trim();
|
|
1956
1929
|
};
|
|
1957
|
-
const GLOBAL_FLAGS = [{
|
|
1958
|
-
name: "profile",
|
|
1959
|
-
description: "config profile to use"
|
|
1960
|
-
}];
|
|
1961
1930
|
/**
|
|
1962
1931
|
* Renders `naturali <command> --help`: the operation's own description, a link
|
|
1963
1932
|
* to the module docs page, and every flag the spec declares — grouped so it is
|
|
@@ -2000,21 +1969,16 @@ const renderCommandHelp = (args) => {
|
|
|
2000
1969
|
}
|
|
2001
1970
|
lines.push("");
|
|
2002
1971
|
}
|
|
2003
|
-
lines.push("Global flags:");
|
|
2004
|
-
for (const flag of GLOBAL_FLAGS) lines.push(` --${flag.name} <string> ${flag.description}`);
|
|
2005
1972
|
return lines.join("\n");
|
|
2006
1973
|
};
|
|
2007
1974
|
//#endregion
|
|
2008
1975
|
//#region src/routeCall.ts
|
|
2009
|
-
/** Flags the dispatcher owns, never forwarded to the API. */
|
|
2010
|
-
const RESERVED_FLAGS = /* @__PURE__ */ new Set(["profile"]);
|
|
2011
1976
|
const placeFlags = (args) => {
|
|
2012
1977
|
const { route, parsedFlags, call } = args;
|
|
2013
1978
|
const typeByCanonical = new Map(route.flags.map((flag) => {
|
|
2014
1979
|
return [toCanonical(flag.name), flag.type];
|
|
2015
1980
|
}));
|
|
2016
1981
|
for (const [flagKey, rawValue] of Object.entries(parsedFlags.single)) {
|
|
2017
|
-
if (RESERVED_FLAGS.has(flagKey)) continue;
|
|
2018
1982
|
const canonical = toCanonical(flagKey);
|
|
2019
1983
|
const value = typeByCanonical.get(canonical) === "array" ? buildArrayFlagValue(parsedFlags.repeated[flagKey] ?? [rawValue]) : parseFlagValue(rawValue);
|
|
2020
1984
|
const pathParam = route.pathParams.find((param) => {
|
|
@@ -2038,6 +2002,19 @@ const placeFlags = (args) => {
|
|
|
2038
2002
|
call.body[kebabToSnake(flagKey)] = value;
|
|
2039
2003
|
}
|
|
2040
2004
|
};
|
|
2005
|
+
const PROJECT_ID_PARAM = "project_id";
|
|
2006
|
+
/**
|
|
2007
|
+
* Falls back to `NATURALI_PROJECT` for the `project_id` path or query
|
|
2008
|
+
* parameter when a command doesn't pass `--project-id` explicitly, so a user
|
|
2009
|
+
* working within one project doesn't have to repeat it on every command.
|
|
2010
|
+
*/
|
|
2011
|
+
const applyProjectIdEnvDefault = (args) => {
|
|
2012
|
+
const { route, call } = args;
|
|
2013
|
+
const envProjectId = process.env["NATURALI_PROJECT"];
|
|
2014
|
+
if (!envProjectId) return;
|
|
2015
|
+
if (route.pathParams.includes(PROJECT_ID_PARAM) && !(PROJECT_ID_PARAM in call.path)) call.path[PROJECT_ID_PARAM] = envProjectId;
|
|
2016
|
+
else if (route.queryParams.includes(PROJECT_ID_PARAM) && !(PROJECT_ID_PARAM in call.query)) call.query[PROJECT_ID_PARAM] = envProjectId;
|
|
2017
|
+
};
|
|
2041
2018
|
/**
|
|
2042
2019
|
* Turns parsed flags into the `{ path, query, body }` an SDK method expects.
|
|
2043
2020
|
*
|
|
@@ -2056,6 +2033,10 @@ const buildRouteCall = (args) => {
|
|
|
2056
2033
|
parsedFlags,
|
|
2057
2034
|
call
|
|
2058
2035
|
});
|
|
2036
|
+
applyProjectIdEnvDefault({
|
|
2037
|
+
route,
|
|
2038
|
+
call
|
|
2039
|
+
});
|
|
2059
2040
|
const missingPathParams = route.pathParams.filter((param) => {
|
|
2060
2041
|
return !(param in call.path);
|
|
2061
2042
|
});
|
|
@@ -2133,7 +2114,7 @@ const formatError = (args) => {
|
|
|
2133
2114
|
* parameter, a missing SDK method, or a non-2xx response.
|
|
2134
2115
|
*/
|
|
2135
2116
|
const dispatchCommand = async (args) => {
|
|
2136
|
-
const { commandName, route, rawArgs
|
|
2117
|
+
const { commandName, route, rawArgs } = args;
|
|
2137
2118
|
if (rawArgs.includes("--help") || rawArgs.includes("-h")) {
|
|
2138
2119
|
console.log(renderCommandHelp({
|
|
2139
2120
|
commandName,
|
|
@@ -2142,7 +2123,7 @@ const dispatchCommand = async (args) => {
|
|
|
2142
2123
|
process.exit(0);
|
|
2143
2124
|
}
|
|
2144
2125
|
const parsedFlags = parseUnknownWithRepeats({ cliArgs: rawArgs });
|
|
2145
|
-
const context = resolveContext(
|
|
2126
|
+
const context = resolveContext();
|
|
2146
2127
|
const built = buildRouteCall({
|
|
2147
2128
|
route,
|
|
2148
2129
|
parsedFlags
|
|
@@ -3798,52 +3779,6 @@ const routes = {
|
|
|
3798
3779
|
"in": "path"
|
|
3799
3780
|
}]
|
|
3800
3781
|
},
|
|
3801
|
-
"query-knowledge-collection": {
|
|
3802
|
-
serviceClass: "Knowledge",
|
|
3803
|
-
operationId: "queryKnowledgeCollection",
|
|
3804
|
-
description: "Retrieval preview (API.md §4, K5): returns the chunks the collection would surface for a question — debuggable standalone, before any agent is bound to it. This is the `…:query` action; the path segment is `{collection_id}:query`.",
|
|
3805
|
-
moduleDocsUrl: "https://docs.naturali.ai/docs/modules/knowledge",
|
|
3806
|
-
httpMethod: "post",
|
|
3807
|
-
pathParams: ["project_id", "collection_id"],
|
|
3808
|
-
queryParams: [],
|
|
3809
|
-
flags: [
|
|
3810
|
-
{
|
|
3811
|
-
"name": "project_id",
|
|
3812
|
-
"description": "Project public ID (proj_ prefix).",
|
|
3813
|
-
"required": true,
|
|
3814
|
-
"type": "string",
|
|
3815
|
-
"in": "path"
|
|
3816
|
-
},
|
|
3817
|
-
{
|
|
3818
|
-
"name": "collection_id",
|
|
3819
|
-
"description": "Knowledge collection public ID (kcol_ prefix).",
|
|
3820
|
-
"required": true,
|
|
3821
|
-
"type": "string",
|
|
3822
|
-
"in": "path"
|
|
3823
|
-
},
|
|
3824
|
-
{
|
|
3825
|
-
"name": "query",
|
|
3826
|
-
"description": "The question to preview retrieval for.",
|
|
3827
|
-
"required": true,
|
|
3828
|
-
"type": "string",
|
|
3829
|
-
"in": "body"
|
|
3830
|
-
},
|
|
3831
|
-
{
|
|
3832
|
-
"name": "top_k",
|
|
3833
|
-
"description": "Maximum chunks to return.",
|
|
3834
|
-
"required": false,
|
|
3835
|
-
"type": "integer",
|
|
3836
|
-
"in": "body"
|
|
3837
|
-
},
|
|
3838
|
-
{
|
|
3839
|
-
"name": "min_score",
|
|
3840
|
-
"description": "Drop chunks below this similarity score.",
|
|
3841
|
-
"required": false,
|
|
3842
|
-
"type": "number",
|
|
3843
|
-
"in": "body"
|
|
3844
|
-
}
|
|
3845
|
-
]
|
|
3846
|
-
},
|
|
3847
3782
|
"update-knowledge-collection": {
|
|
3848
3783
|
serviceClass: "Knowledge",
|
|
3849
3784
|
operationId: "updateKnowledgeCollection",
|
|
@@ -3905,6 +3840,52 @@ const routes = {
|
|
|
3905
3840
|
"in": "path"
|
|
3906
3841
|
}]
|
|
3907
3842
|
},
|
|
3843
|
+
"query-knowledge-collection": {
|
|
3844
|
+
serviceClass: "Knowledge",
|
|
3845
|
+
operationId: "queryKnowledgeCollection",
|
|
3846
|
+
description: "Retrieval preview (API.md §4, K5): returns the chunks the collection would surface for a question — debuggable standalone, before any agent is bound to it. This is the `…:query` action; the path segment is `{collection_id}:query`.",
|
|
3847
|
+
moduleDocsUrl: "https://docs.naturali.ai/docs/modules/knowledge",
|
|
3848
|
+
httpMethod: "post",
|
|
3849
|
+
pathParams: ["project_id", "collection_id"],
|
|
3850
|
+
queryParams: [],
|
|
3851
|
+
flags: [
|
|
3852
|
+
{
|
|
3853
|
+
"name": "project_id",
|
|
3854
|
+
"description": "Project public ID (proj_ prefix).",
|
|
3855
|
+
"required": true,
|
|
3856
|
+
"type": "string",
|
|
3857
|
+
"in": "path"
|
|
3858
|
+
},
|
|
3859
|
+
{
|
|
3860
|
+
"name": "collection_id",
|
|
3861
|
+
"description": "Knowledge collection public ID (kcol_ prefix).",
|
|
3862
|
+
"required": true,
|
|
3863
|
+
"type": "string",
|
|
3864
|
+
"in": "path"
|
|
3865
|
+
},
|
|
3866
|
+
{
|
|
3867
|
+
"name": "query",
|
|
3868
|
+
"description": "The question to preview retrieval for.",
|
|
3869
|
+
"required": true,
|
|
3870
|
+
"type": "string",
|
|
3871
|
+
"in": "body"
|
|
3872
|
+
},
|
|
3873
|
+
{
|
|
3874
|
+
"name": "top_k",
|
|
3875
|
+
"description": "Maximum chunks to return.",
|
|
3876
|
+
"required": false,
|
|
3877
|
+
"type": "integer",
|
|
3878
|
+
"in": "body"
|
|
3879
|
+
},
|
|
3880
|
+
{
|
|
3881
|
+
"name": "min_score",
|
|
3882
|
+
"description": "Drop chunks below this similarity score.",
|
|
3883
|
+
"required": false,
|
|
3884
|
+
"type": "number",
|
|
3885
|
+
"in": "body"
|
|
3886
|
+
}
|
|
3887
|
+
]
|
|
3888
|
+
},
|
|
3908
3889
|
"list-knowledge-documents": {
|
|
3909
3890
|
serviceClass: "Knowledge",
|
|
3910
3891
|
operationId: "listKnowledgeDocuments",
|
|
@@ -4026,12 +4007,12 @@ const routes = {
|
|
|
4026
4007
|
}
|
|
4027
4008
|
]
|
|
4028
4009
|
},
|
|
4029
|
-
"
|
|
4010
|
+
"delete-knowledge-document": {
|
|
4030
4011
|
serviceClass: "Knowledge",
|
|
4031
|
-
operationId: "
|
|
4032
|
-
description: "
|
|
4012
|
+
operationId: "deleteKnowledgeDocument",
|
|
4013
|
+
description: "Delete a document",
|
|
4033
4014
|
moduleDocsUrl: "https://docs.naturali.ai/docs/modules/knowledge",
|
|
4034
|
-
httpMethod: "
|
|
4015
|
+
httpMethod: "delete",
|
|
4035
4016
|
pathParams: [
|
|
4036
4017
|
"project_id",
|
|
4037
4018
|
"collection_id",
|
|
@@ -4062,12 +4043,12 @@ const routes = {
|
|
|
4062
4043
|
}
|
|
4063
4044
|
]
|
|
4064
4045
|
},
|
|
4065
|
-
"
|
|
4046
|
+
"reingest-knowledge-document": {
|
|
4066
4047
|
serviceClass: "Knowledge",
|
|
4067
|
-
operationId: "
|
|
4068
|
-
description: "
|
|
4048
|
+
operationId: "reingestKnowledgeDocument",
|
|
4049
|
+
description: "Re-run ingestion for a document against its stored source, resetting it to `pending` before re-processing — the recovery path for a `failed` ingest (API.md §4, K1). This is the `…:reingest` action; the path segment is `{document_id}:reingest`.",
|
|
4069
4050
|
moduleDocsUrl: "https://docs.naturali.ai/docs/modules/knowledge",
|
|
4070
|
-
httpMethod: "
|
|
4051
|
+
httpMethod: "post",
|
|
4071
4052
|
pathParams: [
|
|
4072
4053
|
"project_id",
|
|
4073
4054
|
"collection_id",
|
|
@@ -5166,16 +5147,9 @@ const routes = {
|
|
|
5166
5147
|
* Every API operation is a command, generated from `api/openapi/v1/*.yaml` into
|
|
5167
5148
|
* `src/generated/routes.ts` and dispatched through `@naturali/sdk` — so the CLI
|
|
5168
5149
|
* is a thin client over exactly the public contract (api/API.md), with nothing
|
|
5169
|
-
* hand-written per endpoint. Only
|
|
5170
|
-
*
|
|
5150
|
+
* hand-written per endpoint. Only discovery (`list-commands`) is a command of
|
|
5151
|
+
* its own. Credentials come from the `NATURALI_TOKEN` environment variable.
|
|
5171
5152
|
*/
|
|
5172
|
-
const addConfigureCommand = (program) => {
|
|
5173
|
-
program.command("configure").description(`Save credentials to a named profile (${configFilePath()})`).option("-p, --profile <name>", "profile name", "default").action(async (opts) => {
|
|
5174
|
-
const token = await password({ message: "Token (nat_sk_… or a session JWT, hidden):" });
|
|
5175
|
-
writeProfile(opts.profile, { token });
|
|
5176
|
-
console.log(`Profile "${opts.profile}" saved to ${configFilePath()}.`);
|
|
5177
|
-
});
|
|
5178
|
-
};
|
|
5179
5153
|
const addListCommandsCommand = (program) => {
|
|
5180
5154
|
program.command("list-commands").description("List every available API command").action(() => {
|
|
5181
5155
|
const entries = Object.entries(routes).sort(([a], [b]) => {
|
|
@@ -5208,8 +5182,7 @@ const addDynamicDispatch = (program) => {
|
|
|
5208
5182
|
await dispatchCommand({
|
|
5209
5183
|
commandName,
|
|
5210
5184
|
route,
|
|
5211
|
-
rawArgs: commandIdx >= 0 ? process.argv.slice(commandIdx + 1) : []
|
|
5212
|
-
profileFromProgram: program.opts().profile
|
|
5185
|
+
rawArgs: commandIdx >= 0 ? process.argv.slice(commandIdx + 1) : []
|
|
5213
5186
|
});
|
|
5214
5187
|
});
|
|
5215
5188
|
};
|
|
@@ -5223,9 +5196,8 @@ const addDynamicDispatch = (program) => {
|
|
|
5223
5196
|
*/
|
|
5224
5197
|
const createProgram = () => {
|
|
5225
5198
|
const program = new Command();
|
|
5226
|
-
program.name("naturali").description("naturali.ai CLI").version(version)
|
|
5199
|
+
program.name("naturali").description("naturali.ai CLI").version(version);
|
|
5227
5200
|
program.addHelpText("after", "\nRun `naturali list-commands` to see every API command, and\n`naturali <command> --help` for a command's flags and docs link.");
|
|
5228
|
-
addConfigureCommand(program);
|
|
5229
5201
|
addListCommandsCommand(program);
|
|
5230
5202
|
addDynamicDispatch(program);
|
|
5231
5203
|
return program;
|
|
@@ -5241,7 +5213,7 @@ const runCli = async (args) => {
|
|
|
5241
5213
|
};
|
|
5242
5214
|
if ((() => {
|
|
5243
5215
|
if (!process.argv[1]) return false;
|
|
5244
|
-
return
|
|
5216
|
+
return nodePath.resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
5245
5217
|
})()) runCli(process.argv);
|
|
5246
5218
|
//#endregion
|
|
5247
5219
|
export { createProgram, runCli };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naturali/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.1",
|
|
4
4
|
"description": "Command-line interface for the naturali.ai API, generated from its OpenAPI specs",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -21,7 +21,6 @@
|
|
|
21
21
|
"access": "public"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@inquirer/password": "^5.1.1",
|
|
25
24
|
"commander": "^15.0.0"
|
|
26
25
|
},
|
|
27
26
|
"devDependencies": {
|
|
@@ -31,12 +30,13 @@
|
|
|
31
30
|
"tsx": "^4.23.1",
|
|
32
31
|
"typescript": "~6.0.3",
|
|
33
32
|
"vitest": "^4.1.10",
|
|
34
|
-
"@naturali/sdk": "0.
|
|
33
|
+
"@naturali/sdk": "0.28.1"
|
|
35
34
|
},
|
|
36
35
|
"scripts": {
|
|
37
36
|
"generate": "tsx scripts/generate.ts",
|
|
38
37
|
"typecheck": "tsc --noEmit",
|
|
39
38
|
"test": "vitest run",
|
|
40
|
-
"build": "tsdown"
|
|
39
|
+
"build": "tsdown",
|
|
40
|
+
"e2e": "tsx tests/e2e/smoke.ts"
|
|
41
41
|
}
|
|
42
42
|
}
|