fleetfizz 0.14.1 → 0.15.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/dist/fleetfizz.mjs +360 -91
- package/package.json +1 -1
package/dist/fleetfizz.mjs
CHANGED
|
@@ -16,7 +16,7 @@ import * as readline from "node:readline";
|
|
|
16
16
|
import process$1, { cwd, env } from "node:process";
|
|
17
17
|
import tty from "node:tty";
|
|
18
18
|
import { EventEmitter } from "node:events";
|
|
19
|
-
import { types } from "node:util";
|
|
19
|
+
import { stripVTControlCharacters, types } from "node:util";
|
|
20
20
|
//#region \0rolldown/runtime.js
|
|
21
21
|
var __create = Object.create;
|
|
22
22
|
var __defProp = Object.defineProperty;
|
|
@@ -3791,7 +3791,7 @@ const ServiceProto = {
|
|
|
3791
3791
|
.../*#__PURE__*/ Prototype({
|
|
3792
3792
|
label: "Service",
|
|
3793
3793
|
evaluate(fiber) {
|
|
3794
|
-
return exitSucceed(get$
|
|
3794
|
+
return exitSucceed(get$4(fiber.context, this));
|
|
3795
3795
|
}
|
|
3796
3796
|
}),
|
|
3797
3797
|
toJSON() {
|
|
@@ -3807,10 +3807,10 @@ const ServiceProto = {
|
|
|
3807
3807
|
return make$32(this, self);
|
|
3808
3808
|
},
|
|
3809
3809
|
use(f) {
|
|
3810
|
-
return withFiber$1((fiber) => f(get$
|
|
3810
|
+
return withFiber$1((fiber) => f(get$4(fiber.context, this)));
|
|
3811
3811
|
},
|
|
3812
3812
|
useSync(f) {
|
|
3813
|
-
return withFiber$1((fiber) => exitSucceed(f(get$
|
|
3813
|
+
return withFiber$1((fiber) => exitSucceed(f(get$4(fiber.context, this))));
|
|
3814
3814
|
}
|
|
3815
3815
|
};
|
|
3816
3816
|
const cacheKeys = /*#__PURE__*/ new Set();
|
|
@@ -4170,7 +4170,7 @@ const getUnsafe = /*#__PURE__*/ dual(2, (self, service) => {
|
|
|
4170
4170
|
* @category getters
|
|
4171
4171
|
* @since 2.0.0
|
|
4172
4172
|
*/
|
|
4173
|
-
const get$
|
|
4173
|
+
const get$4 = getUnsafe;
|
|
4174
4174
|
const defaultValueCacheKey = "~effect/Context/defaultValue";
|
|
4175
4175
|
const getDefaultValue = (ref) => {
|
|
4176
4176
|
if (defaultValueCacheKey in ref) return ref[defaultValueCacheKey];
|
|
@@ -6908,7 +6908,7 @@ var FiberImpl = class {
|
|
|
6908
6908
|
return this._dispatcher ??= this.cache.scheduler.makeDispatcher();
|
|
6909
6909
|
}
|
|
6910
6910
|
getRef(ref) {
|
|
6911
|
-
return get$
|
|
6911
|
+
return get$4(this.context, ref);
|
|
6912
6912
|
}
|
|
6913
6913
|
addObserver(cb) {
|
|
6914
6914
|
if (this._exit) {
|
|
@@ -7066,17 +7066,17 @@ var FiberImpl = class {
|
|
|
7066
7066
|
const makeFiberContextCache = (context) => {
|
|
7067
7067
|
const currentTracer = getOrUndefinedUnsafe(context, TracerKey);
|
|
7068
7068
|
return {
|
|
7069
|
-
scheduler: get$
|
|
7069
|
+
scheduler: get$4(context, Scheduler),
|
|
7070
7070
|
tracer: currentTracer,
|
|
7071
7071
|
tracerContext: currentTracer ? currentTracer["context"] : void 0,
|
|
7072
|
-
tracerEnabled: get$
|
|
7072
|
+
tracerEnabled: get$4(context, TracerEnabled),
|
|
7073
7073
|
span: getOrUndefinedUnsafe(context, ParentSpanKey),
|
|
7074
|
-
logLevel: get$
|
|
7075
|
-
minimumLogLevel: get$
|
|
7076
|
-
stackFrame: get$
|
|
7074
|
+
logLevel: get$4(context, CurrentLogLevel),
|
|
7075
|
+
minimumLogLevel: get$4(context, MinimumLogLevel$1),
|
|
7076
|
+
stackFrame: get$4(context, CurrentStackFrame),
|
|
7077
7077
|
runtimeMetrics: getOrUndefinedUnsafe(context, FiberRuntimeMetricsKey),
|
|
7078
|
-
maxOpsBeforeYield: get$
|
|
7079
|
-
preventYield: get$
|
|
7078
|
+
maxOpsBeforeYield: get$4(context, MaxOpsBeforeYield),
|
|
7079
|
+
preventYield: get$4(context, PreventSchedulerYield)
|
|
7080
7080
|
};
|
|
7081
7081
|
};
|
|
7082
7082
|
const deferredInterruptCont = {
|
|
@@ -8434,11 +8434,11 @@ const NoopSpanProto = {
|
|
|
8434
8434
|
const noopSpan = (options) => Object.assign(Object.create(NoopSpanProto), options);
|
|
8435
8435
|
const filterDisablePropagation = (span) => {
|
|
8436
8436
|
if (!span) return none();
|
|
8437
|
-
return get$
|
|
8437
|
+
return get$4(span.annotations, DisablePropagation) ? span._tag === "Span" ? filterDisablePropagation(getOrUndefined$1(span.parent)) : none() : some(span);
|
|
8438
8438
|
};
|
|
8439
8439
|
/** @internal */
|
|
8440
8440
|
const makeSpanUnsafe = (fiber, name, options) => {
|
|
8441
|
-
const disablePropagation = !fiber.cache.tracerEnabled || options?.annotations && get$
|
|
8441
|
+
const disablePropagation = !fiber.cache.tracerEnabled || options?.annotations && get$4(options.annotations, DisablePropagation);
|
|
8442
8442
|
const parent = options?.parent !== void 0 ? some(options.parent) : options?.root ? none() : filterDisablePropagation(fiber.cache.span);
|
|
8443
8443
|
let span;
|
|
8444
8444
|
if (disablePropagation) span = noopSpan({
|
|
@@ -18071,7 +18071,7 @@ var RcRefImpl = class {
|
|
|
18071
18071
|
/** @internal */
|
|
18072
18072
|
const make$24 = (options) => withFiber((fiber) => {
|
|
18073
18073
|
const context = fiber.context;
|
|
18074
|
-
const scope = get$
|
|
18074
|
+
const scope = get$4(context, Scope);
|
|
18075
18075
|
const ref = new RcRefImpl(options.acquire, context, scope, options.idleTimeToLive !== void 0 ? fromInputUnsafe$1(options.idleTimeToLive) : void 0);
|
|
18076
18076
|
return as(addFinalizerExit(scope, () => {
|
|
18077
18077
|
const state = ref.state;
|
|
@@ -18134,7 +18134,7 @@ const awaitAcquiring = (self, acquiring, restore) => onExit$1(restore(join(acqui
|
|
|
18134
18134
|
return interrupt(acquiring.fiber);
|
|
18135
18135
|
});
|
|
18136
18136
|
/** @internal */
|
|
18137
|
-
const get$
|
|
18137
|
+
const get$3 = (self_) => {
|
|
18138
18138
|
const self = self_;
|
|
18139
18139
|
return uninterruptibleMask((restore) => flatMap$1(scope, (scope) => flatMap$1(getState(self, restore), (state) => as(addFinalizerExit(scope, () => release(self, state)), state.value))));
|
|
18140
18140
|
};
|
|
@@ -18252,7 +18252,7 @@ const make$23 = make$24;
|
|
|
18252
18252
|
* @category combinators
|
|
18253
18253
|
* @since 3.5.0
|
|
18254
18254
|
*/
|
|
18255
|
-
const get$
|
|
18255
|
+
const get$2 = get$3;
|
|
18256
18256
|
//#endregion
|
|
18257
18257
|
//#region ../../node_modules/.pnpm/effect@4.0.2/node_modules/effect/dist/Stream.js
|
|
18258
18258
|
/**
|
|
@@ -24846,7 +24846,7 @@ const TypeId$15 = /*#__PURE__*/ Symbol.for("~effect/http/Headers");
|
|
|
24846
24846
|
const Proto$7 = /*#__PURE__*/ Object.defineProperties(/*#__PURE__*/ Object.create(null), {
|
|
24847
24847
|
[TypeId$15]: { value: TypeId$15 },
|
|
24848
24848
|
[symbolRedactable]: { value(context) {
|
|
24849
|
-
return redact(this, get$
|
|
24849
|
+
return redact(this, get$4(context, CurrentRedactedNames));
|
|
24850
24850
|
} },
|
|
24851
24851
|
toJSON: { value() {
|
|
24852
24852
|
return redact$1(this);
|
|
@@ -28692,13 +28692,13 @@ const layer$5 = /*#__PURE__*/ effect(Terminal, /*#__PURE__*/ (/* @__PURE__ */ fn
|
|
|
28692
28692
|
stdin.on("keypress", handleKeypress);
|
|
28693
28693
|
if (inputEnded) handleEnd();
|
|
28694
28694
|
else {
|
|
28695
|
-
yield* get$
|
|
28695
|
+
yield* get$2(rlRef);
|
|
28696
28696
|
stdin.once("end", handleEnd);
|
|
28697
28697
|
}
|
|
28698
28698
|
return queue;
|
|
28699
28699
|
});
|
|
28700
28700
|
const readLine = suspend$2(() => poll(lines).pipe(flatMap$1(match$5({
|
|
28701
|
-
onNone: () => scoped(andThen(get$
|
|
28701
|
+
onNone: () => scoped(andThen(get$2(rlRef), take(lines))),
|
|
28702
28702
|
onSome: succeed$3
|
|
28703
28703
|
})), mapError(() => new QuitError({}))));
|
|
28704
28704
|
const display = (prompt) => uninterruptible(callback$1((resume) => {
|
|
@@ -35654,7 +35654,7 @@ const runWith = (command, config) => {
|
|
|
35654
35654
|
};
|
|
35655
35655
|
//#endregion
|
|
35656
35656
|
//#region package.json
|
|
35657
|
-
var version = "0.
|
|
35657
|
+
var version = "0.15.0";
|
|
35658
35658
|
//#endregion
|
|
35659
35659
|
//#region ../../node_modules/.pnpm/jsonc-parser@3.3.1/node_modules/jsonc-parser/lib/esm/impl/scanner.js
|
|
35660
35660
|
/**
|
|
@@ -38460,7 +38460,8 @@ const ReposSection = section({ cloneRoot: optionalKey(variants(withShorthand(Str
|
|
|
38460
38460
|
encode: (root) => root.path
|
|
38461
38461
|
}))).annotateKey({ description: `Where a Machine keeps its Managed Clones: a path, or a list of \`{ path, platforms?, machines? }\` where a Machine gets the first that targets it. \`~\` expands on that Machine. Default: \`${DEFAULT_CLONE_ROOT}\`.` }) }, Record(NonEmptyString, variants(TrackedRepo)), `Tracked Repos, keyed by name, which names the Managed Clone and the \`repos:<name>\` Item. Each is \`{ origin, ref, install, ... }\`, ${VARIANTS}.`);
|
|
38462
38462
|
const ITEM_NAME = /^[A-Za-z0-9._-]+$/;
|
|
38463
|
-
const
|
|
38463
|
+
const isItemName = (name) => ITEM_NAME.test(name) && name !== "." && name !== "..";
|
|
38464
|
+
const badName = (names) => names.find((name) => !isItemName(name));
|
|
38464
38465
|
const HomePath = NonEmptyString.check(isPattern(/^(\/|~\/)./, {
|
|
38465
38466
|
title: "path",
|
|
38466
38467
|
description: "an absolute path, or one under ~"
|
|
@@ -38562,6 +38563,11 @@ var ConfigNotFound = class extends TaggedError()("ConfigNotFound", { path: Strin
|
|
|
38562
38563
|
return `no config at ${this.path}; run fizz init to write one, or pass --config`;
|
|
38563
38564
|
}
|
|
38564
38565
|
};
|
|
38566
|
+
var ConfigIsLink = class extends TaggedError()("ConfigIsLink", { path: String$6 }) {
|
|
38567
|
+
get message() {
|
|
38568
|
+
return `${this.path} is a symlink. fleetfizz copies the config to every Machine itself, so it must be a regular file; to keep its history, put its directory under git instead`;
|
|
38569
|
+
}
|
|
38570
|
+
};
|
|
38565
38571
|
const lineOf = (text, offset) => text.slice(0, offset).split("\n").length;
|
|
38566
38572
|
const repeatedKeys = (text) => {
|
|
38567
38573
|
const problems = [];
|
|
@@ -38637,10 +38643,19 @@ const parseConfig = fn("parseConfig")(function* (path, text) {
|
|
|
38637
38643
|
})));
|
|
38638
38644
|
});
|
|
38639
38645
|
const formatIssue = makeFormatterDefault();
|
|
38640
|
-
const
|
|
38646
|
+
const refuseLink = fn("refuseLink")(function* (path) {
|
|
38641
38647
|
const fs = yield* FileSystem;
|
|
38642
|
-
if (
|
|
38643
|
-
|
|
38648
|
+
if (isSome(yield* option(fs.readLink(path)))) return yield* new ConfigIsLink({ path });
|
|
38649
|
+
});
|
|
38650
|
+
const readConfigText = fn("readConfigText")(function* (path) {
|
|
38651
|
+
yield* refuseLink(path);
|
|
38652
|
+
const fs = yield* FileSystem;
|
|
38653
|
+
if (!(yield* fs.exists(path))) return void 0;
|
|
38654
|
+
return yield* fs.readFileString(path);
|
|
38655
|
+
});
|
|
38656
|
+
const loadConfig = fn("loadConfig")(function* (path) {
|
|
38657
|
+
const text = yield* readConfigText(path);
|
|
38658
|
+
if (text === void 0) return yield* new ConfigNotFound({ path });
|
|
38644
38659
|
return yield* parseConfig(path, text);
|
|
38645
38660
|
});
|
|
38646
38661
|
//#endregion
|
|
@@ -38766,9 +38781,11 @@ const insertSpread = (text, path, value) => {
|
|
|
38766
38781
|
const result = insertText(text, path, value);
|
|
38767
38782
|
if (!("text" in result)) return result;
|
|
38768
38783
|
const at = firstDifference(text, result.text);
|
|
38769
|
-
|
|
38784
|
+
const tooLong = lineLength(result.text, at) > WIDTH;
|
|
38785
|
+
const added = result.text.slice(at, at + result.text.length - text.length);
|
|
38786
|
+
if (!tooLong && !added.includes("\n")) return result;
|
|
38770
38787
|
const container = oneLineAround(text, parse$2(text), Math.min(at, text.length - 1));
|
|
38771
|
-
if (container === void 0) return result;
|
|
38788
|
+
if (container === void 0 || !tooLong && at >= container.offset + container.length - 1) return result;
|
|
38772
38789
|
const spreadText = spread(text, container);
|
|
38773
38790
|
return sameComments(text, spreadText) ? insertSpread(spreadText, path, value) : result;
|
|
38774
38791
|
};
|
|
@@ -38863,12 +38880,12 @@ const targetingLists = (text, machine) => {
|
|
|
38863
38880
|
};
|
|
38864
38881
|
const saveConfig = fn("saveConfig")(function* (path, text) {
|
|
38865
38882
|
const config = yield* parseConfig(path, text);
|
|
38883
|
+
yield* refuseLink(path);
|
|
38866
38884
|
const fs = yield* FileSystem;
|
|
38867
|
-
|
|
38868
|
-
yield* fs.
|
|
38869
|
-
yield* fs.
|
|
38870
|
-
|
|
38871
|
-
yield* fs.rename(`${target}.tmp`, target);
|
|
38885
|
+
yield* fs.makeDirectory((yield* Path$1).dirname(path), { recursive: true });
|
|
38886
|
+
yield* fs.writeFileString(`${path}.tmp`, text);
|
|
38887
|
+
if (yield* fs.exists(path)) yield* fs.chmod(`${path}.tmp`, (yield* fs.stat(path)).mode & 4095);
|
|
38888
|
+
yield* fs.rename(`${path}.tmp`, path);
|
|
38872
38889
|
return config;
|
|
38873
38890
|
});
|
|
38874
38891
|
//#endregion
|
|
@@ -39196,6 +39213,10 @@ const EngineFact = Union([
|
|
|
39196
39213
|
sha: optionalKey(String$6),
|
|
39197
39214
|
base64: optionalKey(String$6)
|
|
39198
39215
|
}),
|
|
39216
|
+
Struct({
|
|
39217
|
+
fact: Literal("configLink"),
|
|
39218
|
+
path: String$6
|
|
39219
|
+
}),
|
|
39199
39220
|
Struct({
|
|
39200
39221
|
fact: Literal("configRecord"),
|
|
39201
39222
|
record: Unknown
|
|
@@ -39250,6 +39271,12 @@ const assembleState = (facts) => {
|
|
|
39250
39271
|
}
|
|
39251
39272
|
};
|
|
39252
39273
|
break;
|
|
39274
|
+
case "configLink":
|
|
39275
|
+
state = {
|
|
39276
|
+
...state,
|
|
39277
|
+
configLink: f.path
|
|
39278
|
+
};
|
|
39279
|
+
break;
|
|
39253
39280
|
case "configRecord":
|
|
39254
39281
|
state = {
|
|
39255
39282
|
...state,
|
|
@@ -39341,7 +39368,7 @@ const checkScript = (input) => {
|
|
|
39341
39368
|
lines.push(provider.observe(items, input.scope));
|
|
39342
39369
|
if (provider.rule === "record") for (const item of items) lines.push(...recordFact(provider.name, item.name));
|
|
39343
39370
|
}
|
|
39344
|
-
lines.push(`ff_c=${CONFIG_DIR_SH}/${quote(CONFIG_FILE)}`, `if [ -f "$ff_c" ]; then ff_b=$(base64 < "$ff_c" | tr -d '\\n'); ff_state "{\\"fact\\":\\"config\\",\\"present\\":true,\\"sha\\":\\"$(printf '%s' "$ff_b" | base64 -d | ff_sha)\\",\\"base64\\":\\"$ff_b\\"}"; else ff_state '{"fact":"config","present":false}'; fi`, `ff_r=${quotePath(CONFIG_RECORD)}`, `if [ -f "$ff_r" ]; then ff_state "{\\"fact\\":\\"configRecord\\",\\"record\\":$(tr -d '\\n' < "$ff_r")}"; fi`);
|
|
39371
|
+
lines.push(`ff_c=${CONFIG_DIR_SH}/${quote(CONFIG_FILE)}`, `if [ -L "$ff_c" ]; then ff_state "{\\"fact\\":\\"configLink\\",\\"path\\":\\"$(ff_json "$ff_c")\\"}"; elif [ -f "$ff_c" ]; then ff_b=$(base64 < "$ff_c" | tr -d '\\n'); ff_state "{\\"fact\\":\\"config\\",\\"present\\":true,\\"sha\\":\\"$(printf '%s' "$ff_b" | base64 -d | ff_sha)\\",\\"base64\\":\\"$ff_b\\"}"; else ff_state '{"fact":"config","present":false}'; fi`, `ff_r=${quotePath(CONFIG_RECORD)}`, `if [ -f "$ff_r" ]; then ff_state "{\\"fact\\":\\"configRecord\\",\\"record\\":$(tr -d '\\n' < "$ff_r")}"; fi`);
|
|
39345
39372
|
lines.push(`ff_state '{"fact":"end"}'`);
|
|
39346
39373
|
return lines.join("\n");
|
|
39347
39374
|
};
|
|
@@ -39479,7 +39506,7 @@ const applyScript = (plan, configRecord, init) => {
|
|
|
39479
39506
|
`IFS= read -r ff_schema || ff_schema=""`,
|
|
39480
39507
|
...inputsOf(plan).map((_, i) => `IFS= read -r ff_in_${i} || exit 1`),
|
|
39481
39508
|
`ff_git() { if [ -n "$ff_token" ]; then FF_TOKEN="$ff_token" git -c credential.helper= -c 'credential.helper=!f() { echo username=x-access-token; echo "password=$FF_TOKEN"; }; f' "$@"; else git "$@"; fi; }`,
|
|
39482
|
-
`ff_skills() { if [ -n "$ff_token" ]; then GH_TOKEN="$ff_token" GIT_CONFIG_COUNT=
|
|
39509
|
+
`ff_skills() { if [ -n "$ff_token" ]; then GH_TOKEN="$ff_token" GIT_CONFIG_COUNT=3 GIT_CONFIG_KEY_0=core.autocrlf GIT_CONFIG_VALUE_0=false GIT_CONFIG_KEY_1=credential.helper GIT_CONFIG_VALUE_1= GIT_CONFIG_KEY_2=credential.helper GIT_CONFIG_VALUE_2='!f() { echo username=x-access-token; echo "password=$GH_TOKEN"; }; f' DISABLE_TELEMETRY=1 skills "$@"; else GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=core.autocrlf GIT_CONFIG_VALUE_0=false DISABLE_TELEMETRY=1 skills "$@"; fi; }`,
|
|
39483
39510
|
...configStep(configRecord),
|
|
39484
39511
|
...plan.providers.flatMap((p) => providerSteps(p, offsets)),
|
|
39485
39512
|
doneLine("end", true)
|
|
@@ -40091,7 +40118,7 @@ const decideFile = (item, observed, resolved, ctx) => {
|
|
|
40091
40118
|
};
|
|
40092
40119
|
const recorded = record === void 0 ? void 0 : fingerprint(recordEntries(record));
|
|
40093
40120
|
const same = ctx.machine.name === from || current !== void 0 && fingerprint(current) === ours;
|
|
40094
|
-
const rerun = same && item.after !== void 0 ? ctx.rebuild(subject) ? "--rebuild" : ctx.machine.name
|
|
40121
|
+
const rerun = same && item.after !== void 0 ? ctx.rebuild(subject) ? "--rebuild" : ctx.machine.name === from || recorded === ours ? void 0 : recorded === void 0 ? "its after has not succeeded here" : "its after has not finished" : void 0;
|
|
40095
40122
|
if (rerun !== void 0) return {
|
|
40096
40123
|
kind: "change",
|
|
40097
40124
|
item: item.name,
|
|
@@ -41311,7 +41338,7 @@ const make$2 = (method) => (url, options) => modify(empty, {
|
|
|
41311
41338
|
* @category constructors
|
|
41312
41339
|
* @since 4.0.0
|
|
41313
41340
|
*/
|
|
41314
|
-
const get = /*#__PURE__*/ make$2("GET");
|
|
41341
|
+
const get$1 = /*#__PURE__*/ make$2("GET");
|
|
41315
41342
|
/**
|
|
41316
41343
|
* Applies request options to an `HttpClientRequest`, returning a new request.
|
|
41317
41344
|
*
|
|
@@ -41705,6 +41732,14 @@ const accessor = (method) => (...args) => flatMap$1(HttpClient, (client) => clie
|
|
|
41705
41732
|
*/
|
|
41706
41733
|
const execute = /*#__PURE__*/ accessor("execute");
|
|
41707
41734
|
/**
|
|
41735
|
+
* Executes a `GET` request using the `HttpClient` service from the environment.
|
|
41736
|
+
*
|
|
41737
|
+
* @stability unstable
|
|
41738
|
+
* @category accessors
|
|
41739
|
+
* @since 4.0.0
|
|
41740
|
+
*/
|
|
41741
|
+
const get = /*#__PURE__*/ accessor("get");
|
|
41742
|
+
/**
|
|
41708
41743
|
* Transforms a client by applying an effectful transformation to each response effect.
|
|
41709
41744
|
*
|
|
41710
41745
|
* @stability unstable
|
|
@@ -42101,7 +42136,8 @@ const treeHash = (dir) => {
|
|
|
42101
42136
|
try {
|
|
42102
42137
|
execFileSync("git", ["init", "-q", "--bare", git]);
|
|
42103
42138
|
const env = { ...process.env, GIT_DIR: git, GIT_INDEX_FILE: join(git, "index") };
|
|
42104
|
-
|
|
42139
|
+
// As ff_skills clones: no line-ending conversion, so the hash is GitHub's.
|
|
42140
|
+
execFileSync("git", ["-c", "core.autocrlf=false", "--work-tree", dir, "add", "-A", "-f", "."], { cwd: dir, env, stdio: "ignore" });
|
|
42105
42141
|
return execFileSync("git", ["write-tree"], { env, encoding: "utf8" }).trim();
|
|
42106
42142
|
} catch {
|
|
42107
42143
|
return undefined;
|
|
@@ -42200,16 +42236,18 @@ const TreeResponse = Struct({
|
|
|
42200
42236
|
path: String$6,
|
|
42201
42237
|
type: String$6,
|
|
42202
42238
|
sha: String$6
|
|
42203
|
-
}))
|
|
42239
|
+
})),
|
|
42240
|
+
truncated: Boolean$4
|
|
42204
42241
|
});
|
|
42205
42242
|
const fetchFolders = fn("fetchFolders")(function* (repo, ref, token) {
|
|
42206
|
-
const response = yield* execute(get(`https://api.github.com/repos/${repo}/git/trees/${encodeURIComponent(ref ?? "HEAD")}?recursive=1`).pipe(setHeaders({
|
|
42243
|
+
const response = yield* execute(get$1(`https://api.github.com/repos/${repo}/git/trees/${encodeURIComponent(ref ?? "HEAD")}?recursive=1`).pipe(setHeaders({
|
|
42207
42244
|
Accept: "application/vnd.github+json",
|
|
42208
42245
|
"User-Agent": "fleetfizz"
|
|
42209
42246
|
}), (request) => token === void 0 ? request : bearerToken(request, token)));
|
|
42210
42247
|
if (response.status === 404) return { error: `no ${ref ?? "default branch"} in ${repo}, or no access to it` };
|
|
42211
42248
|
if (response.status !== 200) return { error: `GitHub answered ${response.status}` };
|
|
42212
42249
|
const body = yield* schemaBodyJson(TreeResponse)(response);
|
|
42250
|
+
if (body.truncated) return { error: "the repo is too large for GitHub to list its folders" };
|
|
42213
42251
|
return { folders: new Map([["", body.sha], ...body.tree.flatMap((e) => e.type === "tree" ? [[e.path, e.sha]] : [])]) };
|
|
42214
42252
|
}, timeout("15 seconds"), orElseSucceed(() => ({ error: "could not reach GitHub" })), provide(layer$2));
|
|
42215
42253
|
const skillQuestion = (subject, found, problem) => ({
|
|
@@ -73448,6 +73486,72 @@ const changeText = (path, before, after, summary) => toText(/* @__PURE__ */ (0,
|
|
|
73448
73486
|
]
|
|
73449
73487
|
}));
|
|
73450
73488
|
//#endregion
|
|
73489
|
+
//#region src/localSkills.ts
|
|
73490
|
+
const decodeLock = decodeUnknownOption(fromJsonString(Struct({
|
|
73491
|
+
version: Number$2,
|
|
73492
|
+
skills: Record(String$6, Struct({
|
|
73493
|
+
source: String$6,
|
|
73494
|
+
sourceType: String$6,
|
|
73495
|
+
ref: optionalKey(String$6)
|
|
73496
|
+
}))
|
|
73497
|
+
})));
|
|
73498
|
+
/**
|
|
73499
|
+
* The Skills in the CLI's lock, read where the CLI keeps it, that every
|
|
73500
|
+
* Machine can install: a GitHub source and a name the config can hold. One
|
|
73501
|
+
* from a path here, or a folder the CLI did not install, has no source another
|
|
73502
|
+
* Machine has. None when the lock is missing or from an older CLI.
|
|
73503
|
+
*/
|
|
73504
|
+
const localSkills = fn("localSkills")(function* () {
|
|
73505
|
+
const fs = yield* FileSystem;
|
|
73506
|
+
const state = process.env.XDG_STATE_HOME;
|
|
73507
|
+
const path = state === void 0 || state === "" ? expandHome("~/.agents/.skill-lock.json") : `${state}/skills/.skill-lock.json`;
|
|
73508
|
+
const lock = decodeLock(yield* fs.readFileString(path).pipe(orElseSucceed(() => "")));
|
|
73509
|
+
if (lock._tag === "None" || lock.value.version < 3) return [];
|
|
73510
|
+
return Object.entries(lock.value.skills).filter(([name, entry]) => entry.sourceType === "github" && isItemName(name)).map(([name, entry]) => ({
|
|
73511
|
+
name,
|
|
73512
|
+
source: entry.source,
|
|
73513
|
+
...entry.ref === void 0 ? {} : { ref: entry.ref }
|
|
73514
|
+
})).sort((a, b) => a.name.localeCompare(b.name));
|
|
73515
|
+
});
|
|
73516
|
+
const NO_TELEMETRY = { DISABLE_TELEMETRY: "1" };
|
|
73517
|
+
const decodeList = decodeUnknownOption(fromJsonString(ArraySchema(Struct({ agents: ArraySchema(String$6) }))));
|
|
73518
|
+
/**
|
|
73519
|
+
* The Agents the skills CLI sees Skills installed for here, as the ids
|
|
73520
|
+
* `skills add -a` takes, or none when the CLI is not here. `skills ls --json`
|
|
73521
|
+
* names them for display ("Claude Code" is `claude-code`), the way most ids
|
|
73522
|
+
* are written; the few that are not (`roo` is "Roo Code") the CLI rejects,
|
|
73523
|
+
* and they are dropped.
|
|
73524
|
+
*/
|
|
73525
|
+
const localAgents = fn("localAgents")(function* () {
|
|
73526
|
+
const listed = yield* runLocal("skills", [
|
|
73527
|
+
"ls",
|
|
73528
|
+
"-g",
|
|
73529
|
+
"--json"
|
|
73530
|
+
], NO_TELEMETRY);
|
|
73531
|
+
const list = listed.code === 0 ? decodeList(listed.stdout) : void 0;
|
|
73532
|
+
const ids = list === void 0 || list._tag === "None" ? [] : [...new Set(list.value.flatMap((skill) => skill.agents.map((agent) => agent.toLowerCase().replace(/\s+/g, "-"))))];
|
|
73533
|
+
if (ids.length === 0) return ids;
|
|
73534
|
+
const validated = yield* runLocal("skills", [
|
|
73535
|
+
"ls",
|
|
73536
|
+
"-g",
|
|
73537
|
+
"-a",
|
|
73538
|
+
...ids,
|
|
73539
|
+
"--json"
|
|
73540
|
+
], NO_TELEMETRY);
|
|
73541
|
+
const invalid = validated.code === 0 ? [] : /Invalid agents: (.*)/.exec(stripVTControlCharacters(validated.stdout))?.[1]?.split(", ") ?? ids;
|
|
73542
|
+
return ids.filter((id) => !invalid.includes(id));
|
|
73543
|
+
});
|
|
73544
|
+
/** The skills section's `agents`, picked from `agents`, all picked to start. */
|
|
73545
|
+
const pickAgents = (agents) => MultiSelect({
|
|
73546
|
+
message: "Which agents are skills installed for? (skills CLI ids)",
|
|
73547
|
+
choices: agents.map((agent) => ({
|
|
73548
|
+
title: agent,
|
|
73549
|
+
value: agent,
|
|
73550
|
+
selected: true
|
|
73551
|
+
})),
|
|
73552
|
+
min: 1
|
|
73553
|
+
});
|
|
73554
|
+
//#endregion
|
|
73451
73555
|
//#region src/configAdd.tsx
|
|
73452
73556
|
var ConfigAddError = class extends TaggedError()("ConfigAddError", { reason: String$6 }) {
|
|
73453
73557
|
get message() {
|
|
@@ -73468,6 +73572,13 @@ const fileEntry = (path, exclude, targeting) => untargeted(targeting) && exclude
|
|
|
73468
73572
|
...exclude.length > 0 ? { exclude } : {},
|
|
73469
73573
|
...targeting
|
|
73470
73574
|
};
|
|
73575
|
+
/** A Skill's entry: its source alone, or `{ source, ref, agents, ... }` when it has more. */
|
|
73576
|
+
const skillEntry = (source, ref, agents, targeting) => ref === void 0 && agents.length === 0 && untargeted(targeting) ? source : {
|
|
73577
|
+
source,
|
|
73578
|
+
...ref === void 0 ? {} : { ref },
|
|
73579
|
+
...agents.length > 0 ? { agents } : {},
|
|
73580
|
+
...targeting
|
|
73581
|
+
};
|
|
73471
73582
|
const parseSpec = (spec) => {
|
|
73472
73583
|
const at = spec.lastIndexOf("@");
|
|
73473
73584
|
return at > 0 ? {
|
|
@@ -73478,9 +73589,8 @@ const parseSpec = (spec) => {
|
|
|
73478
73589
|
const fileName = (path) => (path.replace(/\/+$/, "").split("/").at(-1) ?? "").replace(/^\.+/, "").replace(/[^A-Za-z0-9._-]/g, "-");
|
|
73479
73590
|
const openConfig = fn("openConfig")(function* (flag) {
|
|
73480
73591
|
const path = flag ?? configPath(process.env);
|
|
73481
|
-
const
|
|
73482
|
-
if (
|
|
73483
|
-
const text = yield* fs.readFileString(path);
|
|
73592
|
+
const text = yield* readConfigText(path);
|
|
73593
|
+
if (text === void 0) return yield* new ConfigAddError({ reason: `no config at ${homeRelative(path)}; run fizz init to write one, or pass --config` });
|
|
73484
73594
|
return {
|
|
73485
73595
|
path,
|
|
73486
73596
|
text,
|
|
@@ -73503,18 +73613,24 @@ const addItem = fn("addItem")(function* (input) {
|
|
|
73503
73613
|
if (unknown.length > 0) return yield* new ConfigAddError({ reason: `not in machines: ${unknown.join(", ")} (add it with fizz config add machines)` });
|
|
73504
73614
|
const tailnet = yield* readTailnet();
|
|
73505
73615
|
const linux = config.machines.some((m) => tailnet.fleet.find((f) => f.name === m)?.platform === "linux");
|
|
73506
|
-
const
|
|
73507
|
-
|
|
73508
|
-
|
|
73509
|
-
|
|
73510
|
-
|
|
73511
|
-
|
|
73616
|
+
const edits = [
|
|
73617
|
+
...input.provider === "cask" && linux && config.cask?.platforms === void 0 ? [[["cask", "platforms"], ["darwin"]]] : [],
|
|
73618
|
+
...input.section ?? [],
|
|
73619
|
+
[[
|
|
73620
|
+
input.provider,
|
|
73621
|
+
"items",
|
|
73622
|
+
input.name
|
|
73623
|
+
], input.entry]
|
|
73512
73624
|
];
|
|
73513
|
-
|
|
73514
|
-
|
|
73515
|
-
|
|
73625
|
+
let next = text;
|
|
73626
|
+
for (const [at, value] of edits) {
|
|
73627
|
+
const edited = insertAt(next, at, value);
|
|
73628
|
+
if ("reason" in edited) return yield* new ConfigAddError({ reason: edited.reason });
|
|
73629
|
+
next = edited.text;
|
|
73630
|
+
}
|
|
73631
|
+
const saved = yield* saveConfig(path, next);
|
|
73516
73632
|
const to = reach(saved, tailnet, input.provider, input.targeting);
|
|
73517
|
-
yield* log(changeText(path, text,
|
|
73633
|
+
yield* log(changeText(path, text, next, /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
73518
73634
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(T, {
|
|
73519
73635
|
tone: "ok",
|
|
73520
73636
|
children: "added"
|
|
@@ -73575,6 +73691,40 @@ const addHomebrew = fn("addHomebrew")(function* (input) {
|
|
|
73575
73691
|
notes
|
|
73576
73692
|
});
|
|
73577
73693
|
});
|
|
73694
|
+
/** The skills section's first `agents`, picked from the Agents the skills CLI sees here. */
|
|
73695
|
+
const pickHere = fn("pickHere")(function* () {
|
|
73696
|
+
const here = yield* localAgents();
|
|
73697
|
+
if (here.length === 0) return yield* new ConfigAddError({ reason: "the skills CLI sees no agents here; pass --agent" });
|
|
73698
|
+
return yield* pickAgents(here);
|
|
73699
|
+
});
|
|
73700
|
+
/**
|
|
73701
|
+
* `fizz config add skills <name>`. The source and ref default to the ones the
|
|
73702
|
+
* skills CLI installed it from here. The first Skill also writes the section's
|
|
73703
|
+
* `agents`, from --agent or a pick of the Agents here; after that, --agent is
|
|
73704
|
+
* the Skill's own.
|
|
73705
|
+
*/
|
|
73706
|
+
const addSkill = fn("addSkill")(function* (input) {
|
|
73707
|
+
const { config } = yield* openConfig(input.config);
|
|
73708
|
+
const ask = interactive();
|
|
73709
|
+
const here = input.source === void 0 ? (yield* localSkills()).find((skill) => skill.name === input.name) : void 0;
|
|
73710
|
+
const source = input.source ?? here?.source ?? (ask ? yield* String$4({
|
|
73711
|
+
message: "Source (`owner/repo` on GitHub, or any source skills add takes)",
|
|
73712
|
+
validate: (value) => value.trim() === "" ? fail$3("a source is needed") : succeed$3(value.trim())
|
|
73713
|
+
}) : yield* needs("--source"));
|
|
73714
|
+
const ref = input.ref ?? here?.ref;
|
|
73715
|
+
const agents = [...new Set(input.agents)];
|
|
73716
|
+
const section = config.skills !== void 0 ? [] : [[["skills", "agents"], agents.length > 0 ? agents : !ask ? yield* needs("--agent") : yield* pickHere()]];
|
|
73717
|
+
const targeting = targetingOf(input.targeting);
|
|
73718
|
+
yield* addItem({
|
|
73719
|
+
config: input.config,
|
|
73720
|
+
provider: "skills",
|
|
73721
|
+
name: input.name,
|
|
73722
|
+
entry: skillEntry(source, ref, section.length > 0 ? [] : agents, targeting),
|
|
73723
|
+
targeting,
|
|
73724
|
+
section,
|
|
73725
|
+
notes: PACKAGE_MANAGERS.some((pm) => config[pm]?.items?.skills !== void 0) ? [] : [`No package manager in the config installs the skills CLI; add it with fizz config add ${PACKAGE_MANAGERS.join("|")} skills`]
|
|
73726
|
+
});
|
|
73727
|
+
});
|
|
73578
73728
|
const defaultBranch = fn("defaultBranch")(function* (origin) {
|
|
73579
73729
|
const remote = yield* runLocal("git", [
|
|
73580
73730
|
"ls-remote",
|
|
@@ -74391,6 +74541,12 @@ const check = fn("check")(function* (target, script, ledger) {
|
|
|
74391
74541
|
yield* ledger.fail(target.name, ["checking did not finish", ...output]);
|
|
74392
74542
|
return { kind: "failed" };
|
|
74393
74543
|
}
|
|
74544
|
+
if (state.configLink !== void 0) {
|
|
74545
|
+
const { configLink: link, home } = state;
|
|
74546
|
+
const path = home !== void 0 && link.startsWith(`${home}/`) ? `~${link.slice(home.length)}` : link;
|
|
74547
|
+
yield* ledger.fail(target.name, [new ConfigIsLink({ path }).message]);
|
|
74548
|
+
return { kind: "failed" };
|
|
74549
|
+
}
|
|
74394
74550
|
return {
|
|
74395
74551
|
kind: "checked",
|
|
74396
74552
|
state
|
|
@@ -74946,33 +75102,74 @@ const DOTFILES = [
|
|
|
74946
75102
|
];
|
|
74947
75103
|
const draftText = (picks) => {
|
|
74948
75104
|
const edits = [
|
|
74949
|
-
...picks.
|
|
74950
|
-
|
|
74951
|
-
"
|
|
74952
|
-
|
|
74953
|
-
]
|
|
74954
|
-
...picks.
|
|
74955
|
-
|
|
74956
|
-
|
|
75105
|
+
...picks.machines.map((m, i) => [
|
|
75106
|
+
m,
|
|
75107
|
+
["machines", i],
|
|
75108
|
+
m
|
|
75109
|
+
]),
|
|
75110
|
+
...picks.globals.map((g) => [
|
|
75111
|
+
g.name,
|
|
75112
|
+
[
|
|
75113
|
+
g.pm,
|
|
75114
|
+
"items",
|
|
75115
|
+
g.name
|
|
75116
|
+
],
|
|
75117
|
+
`^${g.version}`
|
|
75118
|
+
]),
|
|
75119
|
+
...picks.formulae.map((f) => [
|
|
75120
|
+
f.name,
|
|
75121
|
+
[
|
|
75122
|
+
"brew",
|
|
75123
|
+
"items",
|
|
75124
|
+
f.name
|
|
75125
|
+
],
|
|
75126
|
+
rangeEntry("*", picks.linux && f.macos ? { platforms: ["darwin"] } : {})
|
|
75127
|
+
]),
|
|
75128
|
+
...picks.casks.length > 0 && picks.linux ? [[
|
|
75129
|
+
"the cask platforms",
|
|
75130
|
+
["cask", "platforms"],
|
|
75131
|
+
["darwin"]
|
|
75132
|
+
]] : [],
|
|
75133
|
+
...picks.casks.map((c) => [
|
|
75134
|
+
c,
|
|
75135
|
+
[
|
|
75136
|
+
"cask",
|
|
75137
|
+
"items",
|
|
75138
|
+
c
|
|
75139
|
+
],
|
|
75140
|
+
"*"
|
|
75141
|
+
]),
|
|
75142
|
+
...picks.skills.length > 0 ? [[
|
|
75143
|
+
"the skills agents",
|
|
75144
|
+
["skills", "agents"],
|
|
75145
|
+
picks.agents
|
|
75146
|
+
]] : [],
|
|
75147
|
+
...picks.skills.map((skill) => [
|
|
75148
|
+
skill.name,
|
|
75149
|
+
[
|
|
75150
|
+
"skills",
|
|
75151
|
+
"items",
|
|
75152
|
+
skill.name
|
|
75153
|
+
],
|
|
75154
|
+
skillEntry(skill.source, skill.ref, [], {})
|
|
75155
|
+
]),
|
|
75156
|
+
...picks.files.map((f) => [
|
|
75157
|
+
f,
|
|
75158
|
+
[
|
|
75159
|
+
"files",
|
|
75160
|
+
"items",
|
|
75161
|
+
fileName(f)
|
|
75162
|
+
],
|
|
74957
75163
|
f
|
|
74958
|
-
]
|
|
74959
|
-
...picks.casks.length > 0 && picks.linux ? [[["cask", "platforms"], ["darwin"]]] : [],
|
|
74960
|
-
...picks.casks.map((c) => [[
|
|
74961
|
-
"cask",
|
|
74962
|
-
"items",
|
|
74963
|
-
c
|
|
74964
|
-
], "*"]),
|
|
74965
|
-
...picks.files.map((f) => [[
|
|
74966
|
-
"files",
|
|
74967
|
-
"items",
|
|
74968
|
-
fileName(f)
|
|
74969
|
-
], f])
|
|
75164
|
+
])
|
|
74970
75165
|
];
|
|
74971
|
-
|
|
74972
|
-
|
|
75166
|
+
let text = `{\n "$schema": "./${SCHEMA_FILE}",\n "version": ${JSON.stringify(picks.version)},\n "machines": [],\n}\n`;
|
|
75167
|
+
for (const [pick, path, value] of edits) {
|
|
74973
75168
|
const result = insertAt(text, path, value);
|
|
74974
|
-
|
|
74975
|
-
|
|
75169
|
+
if ("reason" in result) return { reason: `fizz init could not add ${pick}: ${result.reason}` };
|
|
75170
|
+
text = result.text;
|
|
75171
|
+
}
|
|
75172
|
+
return { text };
|
|
74976
75173
|
};
|
|
74977
75174
|
const CheckLine = (props) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(T, {
|
|
74978
75175
|
tone: props.check.ok ? "ok" : props.check.required ? "fail" : "skip",
|
|
@@ -75002,6 +75199,39 @@ const lines = fn("lines")(function* (command, args) {
|
|
|
75002
75199
|
const ran = yield* runLocal(command, args);
|
|
75003
75200
|
return ran.code === 0 ? ran.stdout.split("\n").filter((l) => l.trim() !== "") : [];
|
|
75004
75201
|
});
|
|
75202
|
+
const Requirements = ArraySchema(Struct({ name: String$6 }));
|
|
75203
|
+
const FormulaInfo = Struct({
|
|
75204
|
+
requirements: Requirements,
|
|
75205
|
+
variations: optionalKey(NullOr(Record(String$6, Struct({ requirements: optionalKey(Requirements) }))))
|
|
75206
|
+
});
|
|
75207
|
+
const macosOnly = (f) => {
|
|
75208
|
+
const linux = Object.entries(f.variations ?? {}).flatMap(([tag, v]) => tag.endsWith("_linux") ? [v.requirements ?? f.requirements] : []);
|
|
75209
|
+
return (linux.length > 0 ? linux : [f.requirements]).every((rs) => rs.some((r) => r.name === "macos"));
|
|
75210
|
+
};
|
|
75211
|
+
const BrewInfo = fromJsonString(Struct({ formulae: ArraySchema(Struct({
|
|
75212
|
+
...FormulaInfo.fields,
|
|
75213
|
+
full_name: String$6
|
|
75214
|
+
})) }));
|
|
75215
|
+
const coreMacosOnly = fn("coreMacosOnly")(function* (name) {
|
|
75216
|
+
const response = yield* get(`https://formulae.brew.sh/api/formula/${name}.json`);
|
|
75217
|
+
return macosOnly(yield* schemaBodyJson(FormulaInfo)(response));
|
|
75218
|
+
}, timeout("10 seconds"), orElseSucceed(() => false), provide(layer$2));
|
|
75219
|
+
const tappedMacosOnly = fn("tappedMacosOnly")(function* (names) {
|
|
75220
|
+
if (names.length === 0) return [];
|
|
75221
|
+
const ran = yield* runLocal("brew", [
|
|
75222
|
+
"info",
|
|
75223
|
+
"--json=v2",
|
|
75224
|
+
"--variations",
|
|
75225
|
+
"--formula",
|
|
75226
|
+
...names
|
|
75227
|
+
]);
|
|
75228
|
+
return (yield* decodeEffect(BrewInfo)(ran.stdout)).formulae.filter(macosOnly).map((f) => f.full_name);
|
|
75229
|
+
}, orElseSucceed(() => []));
|
|
75230
|
+
const macosFormulae = fn("macosFormulae")(function* (names) {
|
|
75231
|
+
const tapped = yield* tappedMacosOnly(names.filter((n) => n.includes("/")));
|
|
75232
|
+
const core = yield* filter(names.filter((n) => !n.includes("/")), coreMacosOnly, { concurrency: 8 });
|
|
75233
|
+
return /* @__PURE__ */ new Set([...tapped, ...core]);
|
|
75234
|
+
});
|
|
75005
75235
|
const pickSome = (message, choices) => choices.length === 0 ? succeed$3([]) : MultiSelect({
|
|
75006
75236
|
message,
|
|
75007
75237
|
choices,
|
|
@@ -75032,8 +75262,9 @@ const init = fn("init")(function* (flags) {
|
|
|
75032
75262
|
return;
|
|
75033
75263
|
}
|
|
75034
75264
|
const tailnet = yield* readTailnet();
|
|
75035
|
-
|
|
75036
|
-
|
|
75265
|
+
const existing = yield* readConfigText(path);
|
|
75266
|
+
if (existing !== void 0) {
|
|
75267
|
+
const config = yield* parseConfig(path, existing);
|
|
75037
75268
|
yield* log(`\n${configText({
|
|
75038
75269
|
path,
|
|
75039
75270
|
config,
|
|
@@ -75051,35 +75282,57 @@ const init = fn("init")(function* (flags) {
|
|
|
75051
75282
|
name,
|
|
75052
75283
|
version
|
|
75053
75284
|
})))))).flat().filter((g) => g.name !== SELF_PACKAGE);
|
|
75054
|
-
const
|
|
75285
|
+
const pickedGlobals = yield* pickSome(`Which Globals from this Machine? (${installed.length} installed)`, installed.map((g) => ({
|
|
75055
75286
|
title: `${g.name} ${g.version} ${g.pm}`,
|
|
75056
75287
|
value: g
|
|
75057
75288
|
})));
|
|
75289
|
+
const linux = machines.some((m) => tailnet.fleet.find((f) => f.name === m)?.platform === "linux");
|
|
75058
75290
|
const leaves = yield* lines("brew", ["leaves", "--installed-on-request"]);
|
|
75059
|
-
const
|
|
75291
|
+
const pickedFormulae = yield* pickSome(`Which Formulae from this Machine? (${leaves.length} installed on request)`, leaves.map((f) => ({
|
|
75060
75292
|
title: f,
|
|
75061
75293
|
value: f
|
|
75062
75294
|
})));
|
|
75295
|
+
const macos = linux ? yield* macosFormulae(pickedFormulae) : /* @__PURE__ */ new Set();
|
|
75296
|
+
const formulae = pickedFormulae.map((name) => ({
|
|
75297
|
+
name,
|
|
75298
|
+
macos: macos.has(name)
|
|
75299
|
+
}));
|
|
75063
75300
|
const installedCasks = process.platform === "darwin" ? yield* lines("brew", ["list", "--cask"]) : [];
|
|
75064
75301
|
const casks = yield* pickSome(`Which Casks from this Machine? (${installedCasks.length} installed)`, installedCasks.map((c) => ({
|
|
75065
75302
|
title: c,
|
|
75066
75303
|
value: c
|
|
75067
75304
|
})));
|
|
75305
|
+
const agentsHere = yield* localAgents();
|
|
75306
|
+
const fromGitHub = agentsHere.length === 0 ? [] : yield* localSkills();
|
|
75307
|
+
const skills = yield* pickSome(`Which skills from this Machine? (${fromGitHub.length} installed from GitHub)`, fromGitHub.map((skill) => ({
|
|
75308
|
+
title: `${skill.name} ${skill.source}${skill.ref === void 0 ? "" : `#${skill.ref}`}`,
|
|
75309
|
+
value: skill,
|
|
75310
|
+
selected: true
|
|
75311
|
+
})));
|
|
75312
|
+
const agents = skills.length === 0 ? [] : yield* pickAgents(agentsHere);
|
|
75313
|
+
const cli = installed.find((global) => global.name === "skills");
|
|
75314
|
+
const addCli = cli !== void 0 && skills.length > 0 && !pickedGlobals.some((global) => global.name === "skills");
|
|
75315
|
+
const globals = addCli ? [...pickedGlobals, cli] : pickedGlobals;
|
|
75316
|
+
if (addCli) yield* log(`The skills CLI is in the config too, as a ${cli.pm} Global: a Ship installs skills with it.`);
|
|
75317
|
+
if (cli === void 0 && skills.length > 0) yield* log(`No package manager here has the skills CLI, so a Ship cannot install skills; add it with fizz config add ${PACKAGE_MANAGERS.join("|")} skills.`);
|
|
75068
75318
|
const present = yield* filter(DOTFILES, (f) => fs.exists(expandHome(f)));
|
|
75069
75319
|
const files = yield* pickSome("Which Shared Files? A Ship copies each from the Machine it starts on.", present.map((f) => ({
|
|
75070
75320
|
title: f,
|
|
75071
75321
|
value: f
|
|
75072
75322
|
})));
|
|
75073
|
-
const
|
|
75323
|
+
const draft = draftText({
|
|
75074
75324
|
version: flags.version,
|
|
75075
75325
|
machines,
|
|
75076
75326
|
globals,
|
|
75077
75327
|
formulae,
|
|
75078
75328
|
casks,
|
|
75329
|
+
skills,
|
|
75330
|
+
agents,
|
|
75079
75331
|
files,
|
|
75080
|
-
linux
|
|
75332
|
+
linux
|
|
75081
75333
|
});
|
|
75082
|
-
|
|
75334
|
+
if ("reason" in draft) return yield* new ConfigAddError({ reason: draft.reason });
|
|
75335
|
+
const config = yield* saveConfig(path, draft.text);
|
|
75083
75336
|
const paths = yield* Path$1;
|
|
75084
75337
|
yield* fs.writeFileString(paths.join(paths.dirname(path), SCHEMA_FILE), fleetConfigSchemaText());
|
|
75085
75338
|
yield* log(`\n${toText(/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(T, {
|
|
@@ -75090,7 +75343,7 @@ const init = fn("init")(function* (flags) {
|
|
|
75090
75343
|
path,
|
|
75091
75344
|
config,
|
|
75092
75345
|
tailnet,
|
|
75093
|
-
footer: [`Add more with fizz config add repos|files|${PACKAGE_MANAGERS.join("|")}|brew|cask.`]
|
|
75346
|
+
footer: [`Add more with fizz config add repos|files|${PACKAGE_MANAGERS.join("|")}|brew|cask|skills.`]
|
|
75094
75347
|
}));
|
|
75095
75348
|
if (yield* Confirm({
|
|
75096
75349
|
message: "Run fizz ship --dry-run now?",
|
|
@@ -75347,10 +75600,10 @@ const install = fn("install")(function* (version, why) {
|
|
|
75347
75600
|
if ((yield* runHere("sh", ["-c", installWith(installer, [spec])])) !== 0) return yield* new VersionError({ reason: `could not install ${spec} with ${installer}; run ${MANAGERS[installer].install} ${spec}` });
|
|
75348
75601
|
});
|
|
75349
75602
|
const atConfigVersion = (flag, running, effect) => gen(function* () {
|
|
75350
|
-
const fs = yield* FileSystem;
|
|
75351
75603
|
const path = flag ?? configPath(process.env);
|
|
75352
|
-
|
|
75353
|
-
|
|
75604
|
+
const text = yield* readConfigText(path);
|
|
75605
|
+
if (text === void 0) return yield* effect;
|
|
75606
|
+
const wanted = readVersion(text);
|
|
75354
75607
|
if (wanted === void 0 || wanted === running) return yield* effect;
|
|
75355
75608
|
if (process.env[SWITCHED] !== void 0) return yield* new VersionError({ reason: `${homeRelative(path)} needs fleetfizz ${wanted}, but the fizz on PATH is still ${running} after installing it; see which fizz comes first (command -v fizz)` });
|
|
75356
75609
|
yield* install(wanted, `${homeRelative(path)} needs fleetfizz ${wanted}, not ${running}`);
|
|
@@ -75367,12 +75620,11 @@ const latest = fn("latest")(function* () {
|
|
|
75367
75620
|
return version;
|
|
75368
75621
|
});
|
|
75369
75622
|
const selfUpdate = fn("selfUpdate")(function* (input) {
|
|
75370
|
-
const fs = yield* FileSystem;
|
|
75371
75623
|
const path = input.config ?? configPath(process.env);
|
|
75372
|
-
|
|
75624
|
+
const text = yield* readConfigText(path);
|
|
75625
|
+
if (text === void 0) return yield* new VersionError({ reason: `no config at ${homeRelative(path)}; run fizz init to write one, or pass --config` });
|
|
75373
75626
|
const version = input.version ?? (yield* latest());
|
|
75374
75627
|
if (predatesVersion(version)) return yield* new VersionError({ reason: `fleetfizz ${version} cannot read this config, which needs 0.14.0 or newer` });
|
|
75375
|
-
const text = yield* fs.readFileString(path);
|
|
75376
75628
|
const named = readVersion(text) === version;
|
|
75377
75629
|
if (named && version === input.running) {
|
|
75378
75630
|
yield* log(`fleetfizz ${version} already`);
|
|
@@ -75475,6 +75727,23 @@ const addCommand = make$4("add").pipe(withDescription("Add an Item or a Machine
|
|
|
75475
75727
|
...PACKAGE_MANAGERS.map(globalCommand),
|
|
75476
75728
|
homebrewCommand("brew"),
|
|
75477
75729
|
homebrewCommand("cask"),
|
|
75730
|
+
make$4("skills", {
|
|
75731
|
+
name: String$2("name").pipe(withDescription$2("The skill, by the name its source gives it.")),
|
|
75732
|
+
source: String$1("source").pipe(optional, withDescription$1("Where the skills CLI installs it from: `owner/repo` on GitHub, or any source `skills add` takes. Default: the GitHub repo the CLI installed it from here. Asked for when missing.")),
|
|
75733
|
+
ref: String$1("ref").pipe(optional, withDescription$1("A branch, tag, or full commit SHA. Default: the repo's default branch, or without `--source`, the ref the CLI installed it at here.")),
|
|
75734
|
+
agent: String$1("agent").pipe(atLeast(0), withMetavar("id"), withDescription$1("An agent to install it for, as a skills CLI id (`claude-code`). Repeat the flag for more. For the first skill, they are the section's `agents`, picked from this Machine's when missing; after that, the skill's own.")),
|
|
75735
|
+
...targetingFlags
|
|
75736
|
+
}).pipe(withDescription("Add an agent skill."), withHandler((flags) => withConfig((config) => addSkill({
|
|
75737
|
+
config,
|
|
75738
|
+
name: flags.name,
|
|
75739
|
+
source: getOrUndefined$1(flags.source),
|
|
75740
|
+
ref: getOrUndefined$1(flags.ref),
|
|
75741
|
+
agents: flags.agent,
|
|
75742
|
+
targeting: {
|
|
75743
|
+
platforms: flags.platform,
|
|
75744
|
+
machines: flags.machine
|
|
75745
|
+
}
|
|
75746
|
+
})).pipe(printProblems))),
|
|
75478
75747
|
make$4("repos", {
|
|
75479
75748
|
origin: String$2("origin").pipe(withDescription$2("The GitHub `owner/repo`.")),
|
|
75480
75749
|
name: String$1("name").pipe(optional, withDescription$1("The Item's name. Default: the repo's name.")),
|