hostctl 0.1.61 → 0.1.63
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 +14 -1
- package/dist/bin/hostctl.js +28 -10
- package/dist/bin/hostctl.js.map +1 -1
- package/dist/index.js +28 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -113,7 +113,20 @@ Mount SSH keys or AGE identities as needed (for example `-v "$HOME/.ssh:/home/no
|
|
|
113
113
|
```
|
|
114
114
|
|
|
115
115
|
- `-r/--remote` targets hosts selected by tags via SSH.
|
|
116
|
-
- `-t/--tag`
|
|
116
|
+
- `-t/--tag` specifies a tag filter; repeat for multiple tags.
|
|
117
|
+
|
|
118
|
+
Tag selection uses disjunctive normal form (DNF). Each `-t/--tag` value is a clause. Within a clause, `+` requires every tag (intersection). Multiple `-t` values are OR (union). Commas are literal characters in tag names; use repeated `-t` flags for unions.
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
# Intersection: host must have both tags
|
|
122
|
+
hostctl run -r -t web+prod core.net.interfaces
|
|
123
|
+
|
|
124
|
+
# Union: host may have either tag
|
|
125
|
+
hostctl run -r -t web -t prod core.net.interfaces
|
|
126
|
+
|
|
127
|
+
# Union of intersections
|
|
128
|
+
hostctl run -r -t web+prod -t api+prod core.net.interfaces
|
|
129
|
+
```
|
|
117
130
|
|
|
118
131
|
- **From npm or git**
|
|
119
132
|
```bash
|
package/dist/bin/hostctl.js
CHANGED
|
@@ -4043,7 +4043,7 @@ var ParamMap = class _ParamMap {
|
|
|
4043
4043
|
import * as z from "zod";
|
|
4044
4044
|
|
|
4045
4045
|
// src/version.ts
|
|
4046
|
-
var version = "0.1.
|
|
4046
|
+
var version = "0.1.63";
|
|
4047
4047
|
|
|
4048
4048
|
// src/app.ts
|
|
4049
4049
|
import { retryUntilDefined } from "ts-retry";
|
|
@@ -33576,6 +33576,9 @@ function shouldSkipConfig(envValue) {
|
|
|
33576
33576
|
function collectConfigHeader(value, previous) {
|
|
33577
33577
|
return previous.concat(value);
|
|
33578
33578
|
}
|
|
33579
|
+
function collectTag(value, previous) {
|
|
33580
|
+
return previous.concat(value);
|
|
33581
|
+
}
|
|
33579
33582
|
function parseHeaderEntry(entry) {
|
|
33580
33583
|
const index = entry.indexOf(":");
|
|
33581
33584
|
if (index === -1) {
|
|
@@ -33644,7 +33647,7 @@ var Cli = class {
|
|
|
33644
33647
|
'additional HTTP config header (repeatable, format: "Header-Name: value")',
|
|
33645
33648
|
collectConfigHeader,
|
|
33646
33649
|
[]
|
|
33647
|
-
).option("--json", "output should be json formatted").option("-p, --password", "should prompt for sudo password?", false).option("-t, --tag <
|
|
33650
|
+
).option("--json", "output should be json formatted").option("-p, --password", "should prompt for sudo password?", false).option("-t, --tag <tag>", "tag filter (repeatable; use + for intersection)", collectTag, []);
|
|
33648
33651
|
this.program.command("exec").alias("e").argument(
|
|
33649
33652
|
"<command...>",
|
|
33650
33653
|
`the command string to run, with optional arguments (e.g. hostctl exec sudo sh -c 'echo "$(whoami)"')`
|
|
@@ -34251,27 +34254,42 @@ function unwrapSchema(schema) {
|
|
|
34251
34254
|
}
|
|
34252
34255
|
return { schema: current, optional, nullable };
|
|
34253
34256
|
}
|
|
34254
|
-
function formatSchemaLines(schema) {
|
|
34257
|
+
function formatSchemaLines(schema, depth = 0) {
|
|
34255
34258
|
if (!schema) return ["none"];
|
|
34256
|
-
const
|
|
34259
|
+
const { schema: base } = unwrapSchema(schema);
|
|
34260
|
+
if (!base) return ["none"];
|
|
34261
|
+
const def = base._def ?? base.def;
|
|
34262
|
+
const typeName = def?.typeName || def?.type;
|
|
34263
|
+
const indent = " ".repeat(depth);
|
|
34264
|
+
if (typeName === "ZodUnion" || typeName === "union") {
|
|
34265
|
+
const options = def?.options ?? [];
|
|
34266
|
+
if (!options.length) return [];
|
|
34267
|
+
const lines = [];
|
|
34268
|
+
lines.push(`${indent}- anyOf:`);
|
|
34269
|
+
options.forEach((option, idx) => {
|
|
34270
|
+
lines.push(`${indent} - option ${idx + 1}:`);
|
|
34271
|
+
lines.push(...formatSchemaLines(option, depth + 2));
|
|
34272
|
+
});
|
|
34273
|
+
return lines;
|
|
34274
|
+
}
|
|
34257
34275
|
const shapeSource = def?.shape || def?.shape_;
|
|
34258
34276
|
const shape = shapeSource ? typeof shapeSource === "function" ? shapeSource.call(def) : shapeSource : void 0;
|
|
34259
34277
|
if (shape && typeof shape === "object") {
|
|
34260
34278
|
const lines = Object.entries(shape).map(([key, val]) => {
|
|
34261
|
-
const
|
|
34262
|
-
const
|
|
34279
|
+
const { schema: fieldSchema, optional } = unwrapSchema(val);
|
|
34280
|
+
const summary2 = summarizeType(fieldSchema);
|
|
34281
|
+
const anyVal = fieldSchema ?? val;
|
|
34263
34282
|
const tn = anyVal?._def?.typeName || anyVal?.def?.type;
|
|
34264
34283
|
const typeString = summary2.type || (tn ? String(tn).replace(/^Zod/, "").toLowerCase() : void 0);
|
|
34265
34284
|
const desc = summary2.desc;
|
|
34266
|
-
const optional = ["ZodOptional", "optional", "ZodNullable", "nullable", "ZodDefault", "default"].includes(tn);
|
|
34267
34285
|
const typePart = typeString ? `: ${typeString}` : "";
|
|
34268
34286
|
const descPart = desc ? ` - ${desc}` : "";
|
|
34269
|
-
return
|
|
34287
|
+
return `${indent}- ${key}${optional ? "?" : ""}${typePart}${descPart}`;
|
|
34270
34288
|
}).filter(Boolean);
|
|
34271
34289
|
return lines;
|
|
34272
34290
|
}
|
|
34273
|
-
const summary = summarizeType(
|
|
34274
|
-
return summary.type ? [
|
|
34291
|
+
const summary = summarizeType(base);
|
|
34292
|
+
return summary.type ? [`${indent}- ${summary.type}${summary.desc ? ` - ${summary.desc}` : ""}`] : [];
|
|
34275
34293
|
}
|
|
34276
34294
|
|
|
34277
34295
|
// src/bin/hostctl.ts
|