hngr 0.1.1 → 0.3.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 +7 -2
- package/dist/{auth-Bf4n5qaq.mjs → auth-CgBUQUQn.mjs} +177 -41
- package/dist/{catalog-jU0-wzh3.mjs → catalog-DbGLqQ8a.mjs} +713 -73
- package/dist/{commands-BchmocR_.mjs → commands-BHXSZ04F.mjs} +1 -1
- package/dist/{http-DpXNrkSL.mjs → http-2HWxLIOq.mjs} +11 -10
- package/dist/index.mjs +24 -26
- package/dist/{mcp-bi4OOz5J.mjs → mcp-b6bE3ZRt.mjs} +5 -5
- package/dist/{pagination-DYIwy5ZX.mjs → pagination-BbKLKSw3.mjs} +1 -1
- package/dist/{publish-DHAZ9BB_.mjs → publish-EUqgdp0G.mjs} +41 -11
- package/dist/{skills-By449rb4.mjs → skills-XDbBCC5f.mjs} +7 -7
- package/package.json +1 -1
|
@@ -161,7 +161,12 @@ async function readStoredConfig(env) {
|
|
|
161
161
|
});
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
|
-
|
|
164
|
+
/**
|
|
165
|
+
* The instance the CLI talks to when `--server`, `HANGAR_URL` and the config
|
|
166
|
+
* file are all absent. Point a deployment elsewhere with any of those.
|
|
167
|
+
*/
|
|
168
|
+
const DEFAULT_SERVER_URL = "http://10.199.100.24:26434";
|
|
169
|
+
const INVALID_SERVER_DETAIL = "Pass --server <url>, set HANGAR_URL, or run `hngr auth login` to store one in the config file.";
|
|
165
170
|
/** Parses and normalizes a server URL (no trailing slash); invalid input is a config error. */
|
|
166
171
|
function normalizeServerUrl(server) {
|
|
167
172
|
let url;
|
|
@@ -171,7 +176,7 @@ function normalizeServerUrl(server) {
|
|
|
171
176
|
throw new HngrError({
|
|
172
177
|
type: "config",
|
|
173
178
|
title: `Invalid server URL: ${redactUrl(server)}`,
|
|
174
|
-
detail:
|
|
179
|
+
detail: INVALID_SERVER_DETAIL
|
|
175
180
|
});
|
|
176
181
|
}
|
|
177
182
|
return url.toString().replace(/\/+$/, "");
|
|
@@ -209,16 +214,12 @@ async function deleteStoredConfig(env) {
|
|
|
209
214
|
}
|
|
210
215
|
/**
|
|
211
216
|
* Resolves the server and credentials for one call: `--server` beats
|
|
212
|
-
* `HANGAR_URL` beats the config file; `HANGAR_TOKEN`
|
|
217
|
+
* `HANGAR_URL` beats the config file beats the built-in default; `HANGAR_TOKEN`
|
|
218
|
+
* beats a stored token.
|
|
213
219
|
*/
|
|
214
220
|
async function resolveConnection(flags, env) {
|
|
215
221
|
const config = await readStoredConfig(env);
|
|
216
|
-
const server = flags.server ?? env.HANGAR_URL ?? config?.server;
|
|
217
|
-
if (!server) throw new HngrError({
|
|
218
|
-
type: "config",
|
|
219
|
-
title: "No Hangar server configured",
|
|
220
|
-
detail: NO_SERVER_DETAIL
|
|
221
|
-
});
|
|
222
|
+
const server = flags.server ?? env.HANGAR_URL ?? config?.server ?? "http://10.199.100.24:26434";
|
|
222
223
|
const token = env.HANGAR_TOKEN ?? config?.token;
|
|
223
224
|
return {
|
|
224
225
|
server: normalizeServerUrl(server),
|
|
@@ -455,4 +456,4 @@ async function apiFetch(connection, options) {
|
|
|
455
456
|
signal: options.signal
|
|
456
457
|
});
|
|
457
458
|
}
|
|
458
|
-
export { renderError as S,
|
|
459
|
+
export { renderError as C, HngrError as S, scrubCredentials as _, toHngrError as a, writeFileAtomically as b, redactUrlForDisplay as c, configFilePath as d, deleteStoredConfig as f, resolveConnection as g, redactUrl as h, buildRequestUrl as i, apiErrorFromResponse as l, readStoredConfig as m, apiGet as n, redactQuery as o, normalizeServerUrl as p, apiRequest as r, redactSensitive as s, apiFetch as t, DEFAULT_SERVER_URL as u, writeStoredConfig as v, CancelledError as x, writeDirectoryAtomically as y };
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { a as kebabCase, i as normalizeCommandName, n as COMMANDS, o as COMMAND_ALIASES, r as findCommand, t as commandCatalog } from "./catalog-
|
|
2
|
-
import {
|
|
3
|
-
import { t as collectPages } from "./pagination-
|
|
1
|
+
import { a as kebabCase, i as normalizeCommandName, n as COMMANDS, o as COMMAND_ALIASES, r as findCommand, t as commandCatalog } from "./catalog-DbGLqQ8a.mjs";
|
|
2
|
+
import { C as renderError, S as HngrError, c as redactUrlForDisplay, g as resolveConnection, i as buildRequestUrl, o as redactQuery, r as apiRequest, s as redactSensitive, u as DEFAULT_SERVER_URL, x as CancelledError } from "./http-2HWxLIOq.mjs";
|
|
3
|
+
import { t as collectPages } from "./pagination-BbKLKSw3.mjs";
|
|
4
4
|
import { createRequire } from "node:module";
|
|
5
5
|
import { notStrictEqual, strictEqual } from "assert";
|
|
6
6
|
import { basename, dirname, extname, join, normalize, relative, resolve } from "path";
|
|
@@ -5279,7 +5279,7 @@ function isYargsInstance(y) {
|
|
|
5279
5279
|
// ../../node_modules/.pnpm/yargs@18.2.0/node_modules/yargs/index.mjs
|
|
5280
5280
|
const Yargs = YargsFactory(esm_default);
|
|
5281
5281
|
// package.json
|
|
5282
|
-
var version = "0.
|
|
5282
|
+
var version = "0.3.0";
|
|
5283
5283
|
// src/generated/completion.ts
|
|
5284
5284
|
function isCompletionShell(value) {
|
|
5285
5285
|
return value === "bash" || value === "zsh" || value === "fish";
|
|
@@ -6822,7 +6822,7 @@ const USAGE_HINT = "Run 'hngr --help' to list available commands.";
|
|
|
6822
6822
|
const GLOBAL_OPTIONS = {
|
|
6823
6823
|
server: {
|
|
6824
6824
|
type: "string",
|
|
6825
|
-
describe:
|
|
6825
|
+
describe: `Override HANGAR_URL and the configured server for this call (default: ${DEFAULT_SERVER_URL})`,
|
|
6826
6826
|
global: true
|
|
6827
6827
|
},
|
|
6828
6828
|
json: {
|
|
@@ -6911,24 +6911,26 @@ function buildParser(onMatched) {
|
|
|
6911
6911
|
parser.command("commands", "Print the command catalog", () => {}, (argv) => {
|
|
6912
6912
|
onMatched({
|
|
6913
6913
|
argv,
|
|
6914
|
-
run: async (ctx) => (await import("./commands-
|
|
6914
|
+
run: async (ctx) => (await import("./commands-BHXSZ04F.mjs")).run(ctx)
|
|
6915
6915
|
});
|
|
6916
6916
|
});
|
|
6917
6917
|
parser.command("auth", "Manage credentials", (auth) => {
|
|
6918
|
-
auth.command("login", "Log in
|
|
6918
|
+
auth.command("login", "Log in through the browser device flow, or with --password / --token", (login) => login.option("password", {
|
|
6919
|
+
type: "boolean",
|
|
6920
|
+
describe: "Prompt for a username and password instead of the device flow"
|
|
6921
|
+
}).option("token", {
|
|
6919
6922
|
type: "boolean",
|
|
6920
|
-
default: false,
|
|
6921
6923
|
describe: "Read an access token from stdin instead of prompting"
|
|
6922
|
-
}), (argv) => {
|
|
6924
|
+
}).conflicts("password", "token"), (argv) => {
|
|
6923
6925
|
onMatched({
|
|
6924
6926
|
argv,
|
|
6925
|
-
run: async (ctx, matchedArgv) => (await import("./auth-
|
|
6927
|
+
run: async (ctx, matchedArgv) => (await import("./auth-CgBUQUQn.mjs")).login(ctx, matchedArgv)
|
|
6926
6928
|
});
|
|
6927
6929
|
});
|
|
6928
6930
|
auth.command("logout", "Revoke the stored token and delete the local config", () => {}, (argv) => {
|
|
6929
6931
|
onMatched({
|
|
6930
6932
|
argv,
|
|
6931
|
-
run: async (ctx) => (await import("./auth-
|
|
6933
|
+
run: async (ctx) => (await import("./auth-CgBUQUQn.mjs")).logout(ctx)
|
|
6932
6934
|
});
|
|
6933
6935
|
});
|
|
6934
6936
|
auth.command("status", "Show credential source, server, principal and token prefix", (status) => status.option("offline", {
|
|
@@ -6938,19 +6940,19 @@ function buildParser(onMatched) {
|
|
|
6938
6940
|
}), (argv) => {
|
|
6939
6941
|
onMatched({
|
|
6940
6942
|
argv,
|
|
6941
|
-
run: async (ctx, matchedArgv) => (await import("./auth-
|
|
6943
|
+
run: async (ctx, matchedArgv) => (await import("./auth-CgBUQUQn.mjs")).status(ctx, matchedArgv)
|
|
6942
6944
|
});
|
|
6943
6945
|
});
|
|
6944
6946
|
auth.command("token", "Print the access token to stdout and nothing else", () => {}, (argv) => {
|
|
6945
6947
|
onMatched({
|
|
6946
6948
|
argv,
|
|
6947
|
-
run: async (ctx) => (await import("./auth-
|
|
6949
|
+
run: async (ctx) => (await import("./auth-CgBUQUQn.mjs")).token(ctx)
|
|
6948
6950
|
});
|
|
6949
6951
|
});
|
|
6950
6952
|
auth.command("whoami", "Print the GET /me payload", () => {}, (argv) => {
|
|
6951
6953
|
onMatched({
|
|
6952
6954
|
argv,
|
|
6953
|
-
run: async (ctx) => (await import("./auth-
|
|
6955
|
+
run: async (ctx) => (await import("./auth-CgBUQUQn.mjs")).whoami(ctx)
|
|
6954
6956
|
});
|
|
6955
6957
|
});
|
|
6956
6958
|
registerGeneratedAuth(auth, onMatched);
|
|
@@ -6984,7 +6986,7 @@ function buildParser(onMatched) {
|
|
|
6984
6986
|
}), (argv) => {
|
|
6985
6987
|
onMatched({
|
|
6986
6988
|
argv,
|
|
6987
|
-
run: async (ctx, matchedArgv) => (await import("./skills-
|
|
6989
|
+
run: async (ctx, matchedArgv) => (await import("./skills-XDbBCC5f.mjs")).add(ctx, matchedArgv)
|
|
6988
6990
|
});
|
|
6989
6991
|
});
|
|
6990
6992
|
skills.command("publish <paths..>", "Publish a local skill directory as a capability or a new version", (publish) => publish.option("namespace", {
|
|
@@ -7002,11 +7004,9 @@ function buildParser(onMatched) {
|
|
|
7002
7004
|
}).option("readme", {
|
|
7003
7005
|
type: "string",
|
|
7004
7006
|
describe: "Markdown file to attach as the README"
|
|
7005
|
-
}).option("
|
|
7007
|
+
}).option("category", {
|
|
7006
7008
|
type: "string",
|
|
7007
|
-
|
|
7008
|
-
nargs: 1,
|
|
7009
|
-
describe: "Capability tag (repeatable, at most eight)"
|
|
7009
|
+
describe: "Category slug in the target namespace (create only; resolved even with --dry-run)"
|
|
7010
7010
|
}).option("new", {
|
|
7011
7011
|
type: "boolean",
|
|
7012
7012
|
default: false,
|
|
@@ -7014,7 +7014,7 @@ function buildParser(onMatched) {
|
|
|
7014
7014
|
}), (argv) => {
|
|
7015
7015
|
onMatched({
|
|
7016
7016
|
argv,
|
|
7017
|
-
run: async (ctx, matchedArgv) => (await import("./skills-
|
|
7017
|
+
run: async (ctx, matchedArgv) => (await import("./skills-XDbBCC5f.mjs")).publish(ctx, matchedArgv)
|
|
7018
7018
|
});
|
|
7019
7019
|
});
|
|
7020
7020
|
return skills.demandCommand(1);
|
|
@@ -7036,7 +7036,7 @@ function buildParser(onMatched) {
|
|
|
7036
7036
|
}), (argv) => {
|
|
7037
7037
|
onMatched({
|
|
7038
7038
|
argv,
|
|
7039
|
-
run: async (ctx, matchedArgv) => (await import("./mcp-
|
|
7039
|
+
run: async (ctx, matchedArgv) => (await import("./mcp-b6bE3ZRt.mjs")).add(ctx, matchedArgv)
|
|
7040
7040
|
});
|
|
7041
7041
|
});
|
|
7042
7042
|
mcp.command("publish <paths..>", "Publish an MCP snapshot as a capability or a new version", (publish) => publish.option("namespace", {
|
|
@@ -7054,11 +7054,9 @@ function buildParser(onMatched) {
|
|
|
7054
7054
|
}).option("readme", {
|
|
7055
7055
|
type: "string",
|
|
7056
7056
|
describe: "Markdown file to attach as the README"
|
|
7057
|
-
}).option("
|
|
7057
|
+
}).option("category", {
|
|
7058
7058
|
type: "string",
|
|
7059
|
-
|
|
7060
|
-
nargs: 1,
|
|
7061
|
-
describe: "Capability tag (repeatable, at most eight)"
|
|
7059
|
+
describe: "Category slug in the target namespace (create only; resolved even with --dry-run)"
|
|
7062
7060
|
}).option("new", {
|
|
7063
7061
|
type: "boolean",
|
|
7064
7062
|
default: false,
|
|
@@ -7066,7 +7064,7 @@ function buildParser(onMatched) {
|
|
|
7066
7064
|
}), (argv) => {
|
|
7067
7065
|
onMatched({
|
|
7068
7066
|
argv,
|
|
7069
|
-
run: async (ctx, matchedArgv) => (await import("./mcp-
|
|
7067
|
+
run: async (ctx, matchedArgv) => (await import("./mcp-b6bE3ZRt.mjs")).publish(ctx, matchedArgv)
|
|
7070
7068
|
});
|
|
7071
7069
|
});
|
|
7072
7070
|
return mcp.demandCommand(1);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { _ as resolveCapabilityVersion, a as failedResult, c as stringValues, f as downloadContent, g as resolveCapability, h as parseCapabilityPath, i as errorBody, l as AGENTS, n as readPublishFlags, o as positionalPaths, p as MCP_KIND, r as runPublish, s as runBatch, t as explicitName, u as findAgentDefinition } from "./publish-
|
|
1
|
+
import { S as HngrError, b as writeFileAtomically, g as resolveConnection, s as redactSensitive, t as apiFetch } from "./http-2HWxLIOq.mjs";
|
|
2
|
+
import { _ as resolveCapabilityVersion, a as failedResult, c as stringValues, f as downloadContent, g as resolveCapability, h as parseCapabilityPath, i as errorBody, l as AGENTS, n as readPublishFlags, o as positionalPaths, p as MCP_KIND, r as runPublish, s as runBatch, t as explicitName, u as findAgentDefinition } from "./publish-EUqgdp0G.mjs";
|
|
3
3
|
import { constants } from "node:fs";
|
|
4
4
|
import { access, readFile, stat } from "node:fs/promises";
|
|
5
5
|
import { basename, delimiter, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
@@ -517,7 +517,7 @@ function mcpPrepared(config, metadata) {
|
|
|
517
517
|
visibility: metadata.visibility
|
|
518
518
|
};
|
|
519
519
|
if (metadata.readme !== void 0) body.readme = metadata.readme;
|
|
520
|
-
if (metadata.
|
|
520
|
+
if (metadata.category !== void 0) body.category = metadata.category;
|
|
521
521
|
body.config = config;
|
|
522
522
|
return body;
|
|
523
523
|
};
|
|
@@ -536,7 +536,7 @@ function mcpPrepared(config, metadata) {
|
|
|
536
536
|
if (metadata.description !== void 0) preview.description = metadata.description;
|
|
537
537
|
preview.visibility = metadata.visibility;
|
|
538
538
|
if (metadata.readme !== void 0) preview.readme = metadata.readme;
|
|
539
|
-
if (metadata.
|
|
539
|
+
if (metadata.category !== void 0) preview.category = metadata.category;
|
|
540
540
|
preview.config = `<${serverCount} server${serverCount === 1 ? "" : "s"}>`;
|
|
541
541
|
return preview;
|
|
542
542
|
},
|
|
@@ -569,7 +569,7 @@ function defaultMcpName(file) {
|
|
|
569
569
|
async function publish(ctx, argv) {
|
|
570
570
|
const rawPaths = positionalPaths(argv.paths);
|
|
571
571
|
if (rawPaths.length === 0) throw usage("No MCP snapshot given", "Pass one or more JSON snapshot files.");
|
|
572
|
-
const flags = await readPublishFlags(argv
|
|
572
|
+
const flags = await readPublishFlags(argv);
|
|
573
573
|
const forcedName = explicitName(argv, rawPaths.length);
|
|
574
574
|
const items = rawPaths.map((file) => ({
|
|
575
575
|
name: forcedName ?? defaultMcpName(file),
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { S as HngrError } from "./http-2HWxLIOq.mjs";
|
|
2
2
|
// src/pagination.ts
|
|
3
3
|
function asCursorPage(body, path) {
|
|
4
4
|
if (body === null || typeof body !== "object" || !Array.isArray(body.items) || !("next_cursor" in body)) throw new HngrError({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as collectPages } from "./pagination-
|
|
1
|
+
import { S as HngrError, _ as scrubCredentials, a as toHngrError, g as resolveConnection, h as redactUrl, i as buildRequestUrl, l as apiErrorFromResponse, n as apiGet } from "./http-2HWxLIOq.mjs";
|
|
2
|
+
import { t as collectPages } from "./pagination-BbKLKSw3.mjs";
|
|
3
3
|
import { readFile } from "node:fs/promises";
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
5
|
import { join, resolve } from "node:path";
|
|
@@ -368,6 +368,7 @@ async function runBatch(options) {
|
|
|
368
368
|
};
|
|
369
369
|
}
|
|
370
370
|
// src/commands/publish.ts
|
|
371
|
+
const CATEGORIES_PATH = "/api/v1/categories";
|
|
371
372
|
const VISIBILITIES = [
|
|
372
373
|
"public",
|
|
373
374
|
"internal",
|
|
@@ -397,21 +398,15 @@ async function readOptionalFile(path) {
|
|
|
397
398
|
}
|
|
398
399
|
}
|
|
399
400
|
/** Reads the shared publish flags; a bad value fails before any request. */
|
|
400
|
-
async function readPublishFlags(argv
|
|
401
|
+
async function readPublishFlags(argv) {
|
|
401
402
|
const visibility = stringFlag(argv, "visibility") ?? "private";
|
|
402
403
|
if (!VISIBILITIES.includes(visibility)) throw usage(`Invalid --visibility ${JSON.stringify(visibility)}`, `Use one of: ${VISIBILITIES.join(", ")}.`);
|
|
403
|
-
const tags = stringValues(argv.tag);
|
|
404
|
-
if (tags.length > 8) throw usage("Too many --tag values", "At most eight tags are allowed.");
|
|
405
|
-
for (const tag of tags) {
|
|
406
|
-
if (tag.trim() === "") throw usage("Empty --tag value", "Pass a non-empty tag.");
|
|
407
|
-
if (kind === "skill" && tag.includes(",")) throw usage(`Invalid --tag ${JSON.stringify(tag)}`, "A Skill tag cannot contain a comma; the multipart form joins tags with commas.");
|
|
408
|
-
}
|
|
409
404
|
return {
|
|
410
405
|
namespace: stringFlag(argv, "namespace") ?? "system",
|
|
411
406
|
description: stringFlag(argv, "description"),
|
|
412
407
|
visibility,
|
|
413
408
|
readme: await readOptionalFile(stringFlag(argv, "readme")),
|
|
414
|
-
|
|
409
|
+
category: stringFlag(argv, "category"),
|
|
415
410
|
forceNew: argv.new === true
|
|
416
411
|
};
|
|
417
412
|
}
|
|
@@ -424,6 +419,39 @@ function explicitName(argv, targetCount) {
|
|
|
424
419
|
function asRecord(value) {
|
|
425
420
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
426
421
|
}
|
|
422
|
+
/** Reads one taxonomy page and narrows the fields resolution needs. */
|
|
423
|
+
async function categoryPage(connection, namespace, query) {
|
|
424
|
+
const body = await apiGet(connection, CATEGORIES_PATH, {
|
|
425
|
+
namespace,
|
|
426
|
+
limit: 200,
|
|
427
|
+
...query === void 0 ? {} : { q: query }
|
|
428
|
+
});
|
|
429
|
+
const items = asRecord(body)?.items;
|
|
430
|
+
if (!Array.isArray(items)) throw new HngrError({
|
|
431
|
+
type: "api",
|
|
432
|
+
title: "The server returned an unexpected response shape",
|
|
433
|
+
detail: `Expected {items: [...], truncated: ...} from GET ${CATEGORIES_PATH}.`
|
|
434
|
+
});
|
|
435
|
+
return {
|
|
436
|
+
slugs: items.map((item) => asRecord(item)?.slug).filter((value) => typeof value === "string"),
|
|
437
|
+
truncated: asRecord(body)?.truncated === true
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Resolves a Category slug against the target Namespace's taxonomy. A slug the
|
|
442
|
+
* Namespace does not own is a usage error; any transport or HTTP failure
|
|
443
|
+
* propagates, so the caller never uploads after a failed lookup. A truncated
|
|
444
|
+
* first page is re-queried by slug, and only an exact match counts, so a large
|
|
445
|
+
* taxonomy does not turn a valid Category into an unknown one.
|
|
446
|
+
*/
|
|
447
|
+
async function resolveCategorySlug(connection, namespace, slug) {
|
|
448
|
+
const first = await categoryPage(connection, namespace);
|
|
449
|
+
if (first.slugs.includes(slug)) return slug;
|
|
450
|
+
if (first.truncated) {
|
|
451
|
+
if ((await categoryPage(connection, namespace, slug)).slugs.includes(slug)) return slug;
|
|
452
|
+
}
|
|
453
|
+
throw usage(`Unknown --category ${JSON.stringify(slug)}`, first.slugs.length > 0 ? `Available in ${namespace}: ${first.slugs.join(", ")}.` : `No Categories exist in the ${namespace} namespace.`);
|
|
454
|
+
}
|
|
427
455
|
function printPreview(ctx, kind, namespace, name, preview) {
|
|
428
456
|
ctx.detail(`dry-run: would publish ${kind} ${namespace}/${name}`);
|
|
429
457
|
for (const [key, value] of Object.entries(preview)) {
|
|
@@ -439,6 +467,7 @@ function printPreview(ctx, kind, namespace, name, preview) {
|
|
|
439
467
|
async function runPublish(options) {
|
|
440
468
|
const { ctx } = options;
|
|
441
469
|
const connection = await resolveConnection(ctx.flags, ctx.env);
|
|
470
|
+
if (options.category !== void 0) await resolveCategorySlug(connection, options.namespace, options.category);
|
|
442
471
|
const results = [];
|
|
443
472
|
for (const item of options.items) {
|
|
444
473
|
const base = {
|
|
@@ -459,7 +488,7 @@ async function runPublish(options) {
|
|
|
459
488
|
description: options.description,
|
|
460
489
|
visibility: options.visibility,
|
|
461
490
|
readme: options.readme,
|
|
462
|
-
|
|
491
|
+
category: options.category
|
|
463
492
|
};
|
|
464
493
|
const prepared = await item.prepare(metadata);
|
|
465
494
|
if (ctx.flags.dryRun) {
|
|
@@ -475,6 +504,7 @@ async function runPublish(options) {
|
|
|
475
504
|
name: item.name
|
|
476
505
|
}, options.info);
|
|
477
506
|
if (existing !== null && options.forceNew) throw usage(`The ${options.info.noun} ${options.namespace}/${item.name} already exists`, "Drop --new to publish a new version of it.");
|
|
507
|
+
if (existing !== null && options.category !== void 0) throw usage(`Cannot change the category of the existing ${options.info.noun} ${options.namespace}/${item.name}`, "Drop --category to publish a new version; change the category in the Web console.");
|
|
478
508
|
let response;
|
|
479
509
|
let mode;
|
|
480
510
|
if (existing !== null) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { _ as resolveCapabilityVersion, a as failedResult, c as stringValues, d as homeDir, f as downloadContent, g as resolveCapability, h as parseCapabilityPath, i as errorBody, l as AGENTS, m as SKILL_KIND, n as readPublishFlags, o as positionalPaths, r as runPublish, s as runBatch, t as explicitName } from "./publish-
|
|
1
|
+
import { S as HngrError, g as resolveConnection, r as apiRequest, y as writeDirectoryAtomically } from "./http-2HWxLIOq.mjs";
|
|
2
|
+
import { _ as resolveCapabilityVersion, a as failedResult, c as stringValues, d as homeDir, f as downloadContent, g as resolveCapability, h as parseCapabilityPath, i as errorBody, l as AGENTS, m as SKILL_KIND, n as readPublishFlags, o as positionalPaths, r as runPublish, s as runBatch, t as explicitName } from "./publish-EUqgdp0G.mjs";
|
|
3
3
|
import { lstat, mkdir, readFile, readdir, rename, rm, symlink, writeFile } from "node:fs/promises";
|
|
4
4
|
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
5
5
|
import { randomUUID } from "node:crypto";
|
|
@@ -784,9 +784,9 @@ function skillPrepared(pkg, metadata) {
|
|
|
784
784
|
name: "readme",
|
|
785
785
|
value: metadata.readme
|
|
786
786
|
});
|
|
787
|
-
if (metadata.
|
|
788
|
-
name: "
|
|
789
|
-
value: metadata.
|
|
787
|
+
if (metadata.category !== void 0) parts.push({
|
|
788
|
+
name: "category",
|
|
789
|
+
value: metadata.category
|
|
790
790
|
});
|
|
791
791
|
parts.push(packagePart(pkg, metadata.name));
|
|
792
792
|
return parts;
|
|
@@ -809,7 +809,7 @@ function skillPrepared(pkg, metadata) {
|
|
|
809
809
|
if (metadata.description !== void 0) preview.description = metadata.description;
|
|
810
810
|
preview.visibility = metadata.visibility;
|
|
811
811
|
if (metadata.readme !== void 0) preview.readme = metadata.readme;
|
|
812
|
-
if (metadata.
|
|
812
|
+
if (metadata.category !== void 0) preview.category = metadata.category;
|
|
813
813
|
preview.package = `<${pkg.fileCount} files, ${pkg.byteCount} bytes>`;
|
|
814
814
|
return preview;
|
|
815
815
|
},
|
|
@@ -828,7 +828,7 @@ function skillPrepared(pkg, metadata) {
|
|
|
828
828
|
async function publish(ctx, argv) {
|
|
829
829
|
const rawPaths = positionalPaths(argv.paths);
|
|
830
830
|
if (rawPaths.length === 0) throw usage("No skill directory given", "Pass one or more local directories that contain SKILL.md.");
|
|
831
|
-
const flags = await readPublishFlags(argv
|
|
831
|
+
const flags = await readPublishFlags(argv);
|
|
832
832
|
const forcedName = explicitName(argv, rawPaths.length);
|
|
833
833
|
const items = rawPaths.map((dir) => ({
|
|
834
834
|
name: forcedName ?? basename(resolve(dir)),
|