@khotan/cli 0.8.0 → 0.10.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 +15 -2
- package/dist/khotan.js +136 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -142,9 +142,11 @@ documented surface and the executable surface cannot drift. Run `khotan help` or
|
|
|
142
142
|
| App env | `apps env list <id>`, `apps env set <id> <KEY> --value V`, `apps env reveal <id> <KEY>`, `apps env unset <id> <KEY>`, `apps env bulk-set <id> --var A=1 --var B=2` |
|
|
143
143
|
| Pipelines | same shape as apps under `pipelines …` |
|
|
144
144
|
| Databases | `databases list`, `databases create --name db`, `databases connection <id>`, `databases rotate-credentials <id>`, `databases delete <id>` |
|
|
145
|
-
| Files | `files list`, `files get <id>`, `files upload <path>`, `files download <id> --output <path>`, `files update <id> --name new.txt`, `files delete <id>` |
|
|
145
|
+
| Files | `files list`, `files get <id>`, `files upload <path>`, `files download <id> --output <path>`, `files download-url <id>`, `files preview-url <id>`, `files update <id> --name new.txt`, `files delete <id>` |
|
|
146
146
|
| Folders | `folders list`, `folders create --name docs`, `folders rename <id> --name new`, `folders delete <id>` |
|
|
147
|
-
| Context | `context list`, `context get <slug>`, `context raw <slug>`, `context create --title T --kind knowledge --content '...'
|
|
147
|
+
| Context | `context list`, `context get <slug>`, `context raw <slug>`, `context create --title T --kind knowledge --content '...' --folder-id <id>`, `context update <slug> --expected-revision 3 --content '...' --folder-id <id>`, `context delete <slug>` |
|
|
148
|
+
| Context folders | `context folders list`, `context folders create --name docs --parent-id <id>`, `context folders update <id> --name new --parent-id <id>`, `context folders delete <id> --recursive` |
|
|
149
|
+
| Context revisions | `context revisions list <slug>`, `context revisions get <slug> <revision>`, `context revisions restore <slug> <revision>` |
|
|
148
150
|
|
|
149
151
|
### Output modes
|
|
150
152
|
|
|
@@ -173,6 +175,17 @@ khotan files upload ./report.pdf --folder-path /reports/2026
|
|
|
173
175
|
khotan files download file_123 --output ./report.pdf
|
|
174
176
|
```
|
|
175
177
|
|
|
178
|
+
To hand a file to a browser instead of saving it locally, mint a short-lived
|
|
179
|
+
presigned URL and load it directly (no API key on the URL; expires in ~5 minutes):
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
khotan files preview-url file_123 # inline disposition, images and PDFs only
|
|
183
|
+
khotan files download-url file_123 # attachment disposition, any file type
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
See [Serving file attachments](../../docs/files-api-attachments.md) for the full
|
|
187
|
+
preview/download flow and the receiver wiring guidance.
|
|
188
|
+
|
|
176
189
|
## MCP server
|
|
177
190
|
|
|
178
191
|
`khotan mcp serve` starts a local stdio MCP server that reuses the same profile,
|
package/dist/khotan.js
CHANGED
|
@@ -19,7 +19,7 @@ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
|
19
19
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
20
20
|
|
|
21
21
|
// ../khotan-core/src/version.ts
|
|
22
|
-
var CATALOG_SCHEMA_VERSION = 1, CATALOG_VERSION = "2026-
|
|
22
|
+
var CATALOG_SCHEMA_VERSION = 1, CATALOG_VERSION = "2026-07-01", KHOTAN_ADAPTER_NAME = "khotan", KHOTAN_ADAPTER_VERSION = "0.10.0", SUPPORTED_CATALOG_SCHEMA_VERSIONS;
|
|
23
23
|
var init_version = __esm(() => {
|
|
24
24
|
SUPPORTED_CATALOG_SCHEMA_VERSIONS = [
|
|
25
25
|
CATALOG_SCHEMA_VERSION
|
|
@@ -906,6 +906,19 @@ var init_catalog = __esm(() => {
|
|
|
906
906
|
cli: { command: ["files", "download-url"], summary: "Get a file download URL", defaultOutput: "detail" },
|
|
907
907
|
mcp: { tool: { name: "khotan_files_download", title: "Get a file download URL", description: "Return a short-lived presigned GET URL for a ready file." } }
|
|
908
908
|
},
|
|
909
|
+
{
|
|
910
|
+
id: "files.preview",
|
|
911
|
+
kind: "operation",
|
|
912
|
+
domain: "files",
|
|
913
|
+
safety: "read",
|
|
914
|
+
auth: true,
|
|
915
|
+
title: "Get a file preview URL",
|
|
916
|
+
description: "Return a short-lived presigned inline GET URL for a ready, preview-eligible file (images and PDFs).",
|
|
917
|
+
input: [idField("fileId", "The file id.")],
|
|
918
|
+
http: { method: "GET", path: "/api/v1/files/{fileId}/preview", operationId: "getFilePreviewUrl" },
|
|
919
|
+
cli: { command: ["files", "preview-url"], summary: "Get a file preview URL", defaultOutput: "detail" },
|
|
920
|
+
mcp: { tool: { name: "khotan_files_preview", title: "Get a file preview URL", description: "Return a short-lived presigned inline GET URL for a ready, preview-eligible file (images and PDFs)." } }
|
|
921
|
+
},
|
|
909
922
|
{
|
|
910
923
|
id: "files.resource",
|
|
911
924
|
kind: "resource",
|
|
@@ -1063,7 +1076,8 @@ var init_catalog = __esm(() => {
|
|
|
1063
1076
|
{ name: "content", location: "body", type: "string", required: true, description: "Canonical markdown content." },
|
|
1064
1077
|
{ name: "slug", location: "body", type: "string", description: "Optional slug; derived from the title when omitted." },
|
|
1065
1078
|
{ name: "description", location: "body", type: "string", description: "One-line purpose statement." },
|
|
1066
|
-
{ name: "tags", location: "body", type: "string[]", description: "Flat tag list." }
|
|
1079
|
+
{ name: "tags", location: "body", type: "string[]", description: "Flat tag list." },
|
|
1080
|
+
{ name: "folderId", location: "body", type: "string", description: "Folder placement; omit for the organization root." }
|
|
1067
1081
|
],
|
|
1068
1082
|
http: { method: "POST", path: "/api/v1/context", operationId: "createContextDocument", bodyMode: "json" },
|
|
1069
1083
|
cli: { command: ["context", "create"], summary: "Create a context document", defaultOutput: "detail" },
|
|
@@ -1085,6 +1099,7 @@ var init_catalog = __esm(() => {
|
|
|
1085
1099
|
{ name: "content", location: "body", type: "string", description: "New markdown content." },
|
|
1086
1100
|
{ name: "description", location: "body", type: "string", description: "New description (null clears it)." },
|
|
1087
1101
|
{ name: "tags", location: "body", type: "string[]", description: "New tag list." },
|
|
1102
|
+
{ name: "folderId", location: "body", type: "string", description: "Move the document to this folder; omit to leave unchanged. (Sending null to move to the root is not reachable via CLI flags.)" },
|
|
1088
1103
|
{ name: "changeSummary", location: "body", type: "string", description: "Optional revision-history note." }
|
|
1089
1104
|
],
|
|
1090
1105
|
http: { method: "PATCH", path: "/api/v1/context/{slug}", operationId: "updateContextDocument", bodyMode: "json" },
|
|
@@ -1104,6 +1119,113 @@ var init_catalog = __esm(() => {
|
|
|
1104
1119
|
cli: { command: ["context", "delete"], summary: "Delete a context document" },
|
|
1105
1120
|
mcp: { tool: { name: "khotan_context_delete", title: "Delete a context document", description: "Soft-delete a context document. Requires confirmation." } }
|
|
1106
1121
|
},
|
|
1122
|
+
{
|
|
1123
|
+
id: "context.folders.list",
|
|
1124
|
+
kind: "operation",
|
|
1125
|
+
domain: "context",
|
|
1126
|
+
safety: "read",
|
|
1127
|
+
auth: true,
|
|
1128
|
+
title: "List context folders",
|
|
1129
|
+
description: "List the organization's context folders as a flat list, each carrying parentId, path, depth, and its direct active-document count.",
|
|
1130
|
+
input: [],
|
|
1131
|
+
http: { method: "GET", path: "/api/v1/context/folders", operationId: "listContextFolders" },
|
|
1132
|
+
cli: { command: ["context", "folders", "list"], summary: "List context folders", defaultOutput: "table" },
|
|
1133
|
+
mcp: { tool: { name: "khotan_context_folders_list", title: "List context folders", description: "List context folders as a flat list with parentId, path, depth, and document count." } }
|
|
1134
|
+
},
|
|
1135
|
+
{
|
|
1136
|
+
id: "context.folders.create",
|
|
1137
|
+
kind: "operation",
|
|
1138
|
+
domain: "context",
|
|
1139
|
+
safety: "write",
|
|
1140
|
+
auth: true,
|
|
1141
|
+
title: "Create a context folder",
|
|
1142
|
+
description: "Create a folder under an optional parent (omit parentId for the organization root).",
|
|
1143
|
+
input: [
|
|
1144
|
+
{ name: "name", location: "body", type: "string", required: true, description: "The folder name; must be unique among active siblings." },
|
|
1145
|
+
{ name: "parentId", location: "body", type: "string", description: "Parent folder id; omit for the organization root." }
|
|
1146
|
+
],
|
|
1147
|
+
http: { method: "POST", path: "/api/v1/context/folders", operationId: "createContextFolder", bodyMode: "json" },
|
|
1148
|
+
cli: { command: ["context", "folders", "create"], summary: "Create a context folder", defaultOutput: "detail" },
|
|
1149
|
+
mcp: { tool: { name: "khotan_context_folders_create", title: "Create a context folder", description: "Create a context folder under an optional parent." } }
|
|
1150
|
+
},
|
|
1151
|
+
{
|
|
1152
|
+
id: "context.folders.update",
|
|
1153
|
+
kind: "operation",
|
|
1154
|
+
domain: "context",
|
|
1155
|
+
safety: "write",
|
|
1156
|
+
auth: true,
|
|
1157
|
+
title: "Rename or move a context folder",
|
|
1158
|
+
description: "Rename a folder (name) and/or move it under a new parent (parentId).",
|
|
1159
|
+
input: [
|
|
1160
|
+
idField("id", "The folder id."),
|
|
1161
|
+
{ name: "name", location: "body", type: "string", description: "New folder name." },
|
|
1162
|
+
{ name: "parentId", location: "body", type: "string", description: "New parent folder id. (Sending null to move to the root is not reachable via CLI flags.)" }
|
|
1163
|
+
],
|
|
1164
|
+
http: { method: "PATCH", path: "/api/v1/context/folders/{id}", operationId: "updateContextFolder", bodyMode: "json" },
|
|
1165
|
+
cli: { command: ["context", "folders", "update"], summary: "Rename or move a context folder", defaultOutput: "detail" },
|
|
1166
|
+
mcp: { tool: { name: "khotan_context_folders_update", title: "Rename or move a context folder", description: "Rename a context folder and/or move it under a new parent (parentId null moves it to the root)." } }
|
|
1167
|
+
},
|
|
1168
|
+
{
|
|
1169
|
+
id: "context.folders.delete",
|
|
1170
|
+
kind: "operation",
|
|
1171
|
+
domain: "context",
|
|
1172
|
+
safety: "destructive",
|
|
1173
|
+
auth: true,
|
|
1174
|
+
title: "Delete a context folder",
|
|
1175
|
+
description: "Soft-delete a folder. A non-empty folder requires --recursive, which also soft-deletes its subfolders and documents.",
|
|
1176
|
+
input: [
|
|
1177
|
+
idField("id", "The folder id."),
|
|
1178
|
+
{ name: "recursive", location: "query", type: "boolean", default: false, description: "Delete a non-empty folder and all of its contents." }
|
|
1179
|
+
],
|
|
1180
|
+
http: { method: "DELETE", path: "/api/v1/context/folders/{id}", operationId: "deleteContextFolder" },
|
|
1181
|
+
cli: { command: ["context", "folders", "delete"], summary: "Delete a context folder" },
|
|
1182
|
+
mcp: { tool: { name: "khotan_context_folders_delete", title: "Delete a context folder", description: "Soft-delete a context folder. Pass recursive=true to delete a non-empty folder and its contents. Requires confirmation." } }
|
|
1183
|
+
},
|
|
1184
|
+
{
|
|
1185
|
+
id: "context.revisions.list",
|
|
1186
|
+
kind: "operation",
|
|
1187
|
+
domain: "context",
|
|
1188
|
+
safety: "read",
|
|
1189
|
+
auth: true,
|
|
1190
|
+
title: "List a context document's revisions",
|
|
1191
|
+
description: "List a document's revision history, newest first (metadata only, never snapshot content).",
|
|
1192
|
+
input: [idField("slug", "The document slug.")],
|
|
1193
|
+
http: { method: "GET", path: "/api/v1/context/{slug}/revisions", operationId: "listContextDocumentRevisions" },
|
|
1194
|
+
cli: { command: ["context", "revisions", "list"], summary: "List a document's revisions", defaultOutput: "table" },
|
|
1195
|
+
mcp: { tool: { name: "khotan_context_revisions_list", title: "List document revisions", description: "List a context document's revision history, newest first (metadata only)." } }
|
|
1196
|
+
},
|
|
1197
|
+
{
|
|
1198
|
+
id: "context.revisions.get",
|
|
1199
|
+
kind: "operation",
|
|
1200
|
+
domain: "context",
|
|
1201
|
+
safety: "read",
|
|
1202
|
+
auth: true,
|
|
1203
|
+
title: "Get a context document revision",
|
|
1204
|
+
description: "Get a single captured revision including its markdown snapshot.",
|
|
1205
|
+
input: [
|
|
1206
|
+
idField("slug", "The document slug."),
|
|
1207
|
+
{ name: "revision", location: "path", type: "number", required: true, description: "The revision number." }
|
|
1208
|
+
],
|
|
1209
|
+
http: { method: "GET", path: "/api/v1/context/{slug}/revisions/{revision}", operationId: "getContextDocumentRevision" },
|
|
1210
|
+
cli: { command: ["context", "revisions", "get"], summary: "Get a document revision", defaultOutput: "detail" },
|
|
1211
|
+
mcp: { tool: { name: "khotan_context_revisions_get", title: "Get a document revision", description: "Get a single context document revision including its markdown snapshot." } }
|
|
1212
|
+
},
|
|
1213
|
+
{
|
|
1214
|
+
id: "context.revisions.restore",
|
|
1215
|
+
kind: "operation",
|
|
1216
|
+
domain: "context",
|
|
1217
|
+
safety: "write",
|
|
1218
|
+
auth: true,
|
|
1219
|
+
title: "Restore a context document revision",
|
|
1220
|
+
description: "Restore a document to an earlier revision by writing a new forward revision matching that snapshot (history is never rewritten).",
|
|
1221
|
+
input: [
|
|
1222
|
+
idField("slug", "The document slug."),
|
|
1223
|
+
{ name: "revision", location: "path", type: "number", required: true, description: "The revision number to restore." }
|
|
1224
|
+
],
|
|
1225
|
+
http: { method: "POST", path: "/api/v1/context/{slug}/revisions/{revision}/restore", operationId: "restoreContextDocumentRevision" },
|
|
1226
|
+
cli: { command: ["context", "revisions", "restore"], summary: "Restore a document revision", defaultOutput: "detail" },
|
|
1227
|
+
mcp: { tool: { name: "khotan_context_revisions_restore", title: "Restore a document revision", description: "Restore a context document to an earlier revision by writing a new forward revision." } }
|
|
1228
|
+
},
|
|
1107
1229
|
{
|
|
1108
1230
|
id: "context.resource",
|
|
1109
1231
|
kind: "resource",
|
|
@@ -2315,6 +2437,17 @@ function singleArrayProperty(record) {
|
|
|
2315
2437
|
}
|
|
2316
2438
|
return;
|
|
2317
2439
|
}
|
|
2440
|
+
function singleObjectProperty(record) {
|
|
2441
|
+
const keys = Object.keys(record);
|
|
2442
|
+
if (keys.length !== 1) {
|
|
2443
|
+
return;
|
|
2444
|
+
}
|
|
2445
|
+
const value = record[keys[0]];
|
|
2446
|
+
if (typeof value === "object" && value !== null && !Array.isArray(value)) {
|
|
2447
|
+
return value;
|
|
2448
|
+
}
|
|
2449
|
+
return;
|
|
2450
|
+
}
|
|
2318
2451
|
function renderResult(io, result, options) {
|
|
2319
2452
|
if (options.json) {
|
|
2320
2453
|
outLine(io, JSON.stringify(result, null, 2));
|
|
@@ -2341,7 +2474,7 @@ function renderResult(io, result, options) {
|
|
|
2341
2474
|
renderTable(io, list);
|
|
2342
2475
|
return;
|
|
2343
2476
|
}
|
|
2344
|
-
renderDetail(io, record);
|
|
2477
|
+
renderDetail(io, singleObjectProperty(record) ?? record);
|
|
2345
2478
|
return;
|
|
2346
2479
|
}
|
|
2347
2480
|
outLine(io, scalar(result));
|
package/package.json
CHANGED