@paradigma-inc/flywheel 0.1.52 → 0.1.60
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 +121 -10
- package/package.json +1 -1
- package/skills/flywheel/references/flywheel-cli-tool-map.md +8 -0
- package/skills/flywheel/references/flywheel-mcp-tool-map.md +8 -0
- package/src/agents.mjs +114 -48
- package/src/cli.mjs +267 -35
- package/src/mcp-writer.mjs +190 -17
- package/src/runtime/required-runtime-commands.json +17 -4
- package/src/runtime/vendor/flywheel-cli-dist/auth/login.d.ts +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/auth/login.js +3 -6
- package/src/runtime/vendor/flywheel-cli-dist/auth/login.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/auth/profiles.d.ts +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/auth/profiles.js +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/auth/profiles.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/_admin-auth.d.ts +25 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/_admin-auth.js +35 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/_admin-auth.js.map +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/_stream-file-out.d.ts +39 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/_stream-file-out.js +72 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/_stream-file-out.js.map +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/admin-compute-policy-get.d.ts +2 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/admin-compute-policy-get.js +10 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/admin-compute-policy-get.js.map +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/admin-compute-policy-set.d.ts +2 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/{compute-policy-set.js → admin-compute-policy-set.js} +8 -3
- package/src/runtime/vendor/flywheel-cli-dist/commands/admin-compute-policy-set.js.map +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/admin-graphs-export-stream.d.ts +2 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/admin-graphs-export-stream.js +114 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/admin-graphs-export-stream.js.map +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/admin-graphs-export.d.ts +2 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/admin-graphs-export.js +11 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/admin-graphs-export.js.map +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/admin-graphs-list.d.ts +4 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/admin-graphs-list.js +38 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/admin-graphs-list.js.map +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/admin-nodes-audit-list.d.ts +2 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/admin-nodes-audit-list.js +14 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/admin-nodes-audit-list.js.map +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/enums.d.ts +6 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/enums.js +3 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/enums.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/env.d.ts +0 -4
- package/src/runtime/vendor/flywheel-cli-dist/commands/env.js +7 -12
- package/src/runtime/vendor/flywheel-cli-dist/commands/env.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/export-history.js +40 -30
- package/src/runtime/vendor/flywheel-cli-dist/commands/export-history.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/help.d.ts +2 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/help.js +60 -10
- package/src/runtime/vendor/flywheel-cli-dist/commands/help.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-create.d.ts +2 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-create.js +25 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-create.js.map +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-delete.d.ts +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-delete.js +6 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-delete.js.map +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-list.d.ts +2 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-list.js +10 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-list.js.map +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-runs-list.d.ts +2 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-runs-list.js +15 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-runs-list.js.map +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-secrets-create.d.ts +2 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-secrets-create.js +8 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-secrets-create.js.map +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-secrets-delete.d.ts +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-secrets-delete.js +6 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-secrets-delete.js.map +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-secrets-list.d.ts +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-secrets-list.js +6 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-secrets-list.js.map +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-secrets-update.d.ts +2 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-secrets-update.js +8 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-secrets-update.js.map +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-set-enabled.d.ts +2 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-set-enabled.js +8 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-set-enabled.js.map +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-update.d.ts +2 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-update.js +29 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hooks-update.js.map +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/index.js +32 -6
- package/src/runtime/vendor/flywheel-cli-dist/commands/index.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/profile-set.js +4 -2
- package/src/runtime/vendor/flywheel-cli-dist/commands/profile-set.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry/admin.d.ts +8 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry/admin.js +118 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry/admin.js.map +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry/auth.js +2 -2
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry/auth.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry/env.js +7 -5
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry/env.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry/hooks.d.ts +2 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry/hooks.js +244 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry/hooks.js.map +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry/lifecycle.js +1 -16
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry/lifecycle.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry/profile.js +2 -2
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry/profile.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry/resources.js +1 -31
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry/resources.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry.d.ts +2 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry.js +4 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/main.js +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/main.js.map +1 -1
- package/src/runtime/vendor/manifest.json +61 -10
- package/src/setup/io/patchers/json.mjs +2 -0
- package/src/setup/io/patchers/toml.mjs +7 -1
- package/src/setup/io/patchers/yaml.mjs +2 -0
- package/src/setup/modes/cli.mjs +41 -16
- package/src/setup/modes/mcp-command.mjs +98 -19
- package/src/setup/modes/mcp.mjs +26 -1
- package/src/setup/shared/prior-mode-detect.mjs +133 -14
- package/src/skill-installer.mjs +179 -1
- package/src/unified-cli.mjs +38 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/compute-policy-get.d.ts +0 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/compute-policy-get.js +0 -6
- package/src/runtime/vendor/flywheel-cli-dist/commands/compute-policy-get.js.map +0 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/compute-policy-set.d.ts +0 -2
- package/src/runtime/vendor/flywheel-cli-dist/commands/compute-policy-set.js.map +0 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/nodes-audit-list.d.ts +0 -2
- package/src/runtime/vendor/flywheel-cli-dist/commands/nodes-audit-list.js +0 -7
- package/src/runtime/vendor/flywheel-cli-dist/commands/nodes-audit-list.js.map +0 -1
package/src/skill-installer.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SKILL_ONLY_HOST_NAMES } from "./agents.mjs";
|
|
1
2
|
import { execFile as execFileCb } from "node:child_process";
|
|
2
3
|
import { existsSync } from "node:fs";
|
|
3
4
|
import {
|
|
@@ -35,6 +36,12 @@ export const INSTALL_SKILLS_AGENT_BY_HOST = Object.freeze({
|
|
|
35
36
|
"pi-mono": "pi",
|
|
36
37
|
});
|
|
37
38
|
|
|
39
|
+
// Hosts that install skills via a direct filesystem copy (no `skills add`
|
|
40
|
+
// agent integration). These are mostly skill-only targets — they do not write
|
|
41
|
+
// any MCP config or agent-specific AGENTS.md; Flywheel just drops its bundled
|
|
42
|
+
// skills under a conventional directory the IDE or toolchain reads.
|
|
43
|
+
export const DIRECT_COPY_SKILL_HOSTS = Object.freeze(["gemini", "universal", "antigravity"]);
|
|
44
|
+
|
|
38
45
|
export const SUPPORTED_INSTALL_SKILL_HOSTS = Object.freeze([
|
|
39
46
|
"codex",
|
|
40
47
|
"claude",
|
|
@@ -42,6 +49,9 @@ export const SUPPORTED_INSTALL_SKILL_HOSTS = Object.freeze([
|
|
|
42
49
|
"cursor",
|
|
43
50
|
"openclaw",
|
|
44
51
|
"pi-mono",
|
|
52
|
+
"gemini",
|
|
53
|
+
"universal",
|
|
54
|
+
"antigravity",
|
|
45
55
|
]);
|
|
46
56
|
|
|
47
57
|
export function resolvePackageRoot(moduleUrl = import.meta.url) {
|
|
@@ -168,7 +178,10 @@ export function partitionInstallSkillHosts(hostNames) {
|
|
|
168
178
|
const unsupportedHosts = [];
|
|
169
179
|
|
|
170
180
|
for (const hostName of uniqueValues(hostNames)) {
|
|
171
|
-
if (
|
|
181
|
+
if (
|
|
182
|
+
hostName in INSTALL_SKILLS_AGENT_BY_HOST ||
|
|
183
|
+
DIRECT_COPY_SKILL_HOSTS.includes(hostName)
|
|
184
|
+
) {
|
|
172
185
|
supportedHosts.push(hostName);
|
|
173
186
|
} else {
|
|
174
187
|
unsupportedHosts.push(hostName);
|
|
@@ -178,6 +191,58 @@ export function partitionInstallSkillHosts(hostNames) {
|
|
|
178
191
|
return { supportedHosts, unsupportedHosts };
|
|
179
192
|
}
|
|
180
193
|
|
|
194
|
+
export function isDirectCopySkillHost(hostName) {
|
|
195
|
+
return DIRECT_COPY_SKILL_HOSTS.includes(hostName);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Resolve the path of the "Flywheel installed its skills here on behalf of
|
|
200
|
+
* <hostName>" ownership marker file. The marker lives at the parent of the
|
|
201
|
+
* bundled skill dirs (i.e. the skills root for that host), so it is not
|
|
202
|
+
* touched by agent-level skill installers that operate on individual skill
|
|
203
|
+
* subdirectories.
|
|
204
|
+
*
|
|
205
|
+
* The marker carries two related load-bearing signals, resolved by caller
|
|
206
|
+
* context:
|
|
207
|
+
*
|
|
208
|
+
* 1. For pure skill-only hosts (`universal`, `antigravity`): the marker
|
|
209
|
+
* is the ONLY ownership signal — these hosts write no MCP entry. An
|
|
210
|
+
* uninstall of another host sharing the same skills-root uses it to
|
|
211
|
+
* decide whether to retain those skill dirs.
|
|
212
|
+
*
|
|
213
|
+
* 2. For MCP-capable hosts installed through `runCliSetupMode` (which
|
|
214
|
+
* writes skills + runtime config but NO MCP entry): the marker is the
|
|
215
|
+
* per-host signal that this host was installed in CLI mode. Without
|
|
216
|
+
* it, a subsequent `setup --mode mcp --<host>` could not tell whether
|
|
217
|
+
* shared-root artifacts came from a real CLI install of this host or
|
|
218
|
+
* from an unrelated skill-only install at the same root, so it would
|
|
219
|
+
* silently skip the cross-mode conflict guard. MCP-capable hosts
|
|
220
|
+
* installed via the MCP path (with or without `--install-skill`) do
|
|
221
|
+
* NOT get a marker — their MCP entry is the canonical signal there.
|
|
222
|
+
*
|
|
223
|
+
* The marker file is host-scoped (embedded in the filename) so multiple
|
|
224
|
+
* hosts sharing the same skills-root can co-own it without collisions.
|
|
225
|
+
*/
|
|
226
|
+
export function resolveFlywheelInstalledMarkerPath(projectRoot, hostName, scope) {
|
|
227
|
+
if (!SUPPORTED_INSTALL_SKILL_HOSTS.includes(hostName)) {
|
|
228
|
+
throw new Error(
|
|
229
|
+
`resolveFlywheelInstalledMarkerPath requires a host that uses the flywheel skill installer; got '${hostName}'.`,
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
const normalizedScope = normalizeInstallScope(scope);
|
|
233
|
+
// Reuse resolveInstalledSkillDir with a placeholder skill name to get the
|
|
234
|
+
// scope/host-specific skills-root directory; the marker file lives at that
|
|
235
|
+
// root, next to (not inside) the individual skill dirs.
|
|
236
|
+
const placeholderSkillDir = resolveInstalledSkillDir(
|
|
237
|
+
projectRoot,
|
|
238
|
+
hostName,
|
|
239
|
+
normalizedScope,
|
|
240
|
+
"__placeholder__",
|
|
241
|
+
);
|
|
242
|
+
const skillsRoot = path.dirname(placeholderSkillDir);
|
|
243
|
+
return path.join(skillsRoot, `.flywheel-installed-by-${hostName}`);
|
|
244
|
+
}
|
|
245
|
+
|
|
181
246
|
export function resolveInstalledSkillDir(
|
|
182
247
|
projectRoot,
|
|
183
248
|
hostName,
|
|
@@ -208,6 +273,12 @@ export function resolveInstalledSkillDir(
|
|
|
208
273
|
return path.join(root, ".pi", "agent", "skills", normalizedSkillName);
|
|
209
274
|
}
|
|
210
275
|
return path.join(root, ".pi", "skills", normalizedSkillName);
|
|
276
|
+
case "gemini":
|
|
277
|
+
return path.join(root, ".gemini", "skills", normalizedSkillName);
|
|
278
|
+
case "universal":
|
|
279
|
+
return path.join(root, ".agents", "skills", normalizedSkillName);
|
|
280
|
+
case "antigravity":
|
|
281
|
+
return path.join(root, ".agent", "skills", normalizedSkillName);
|
|
211
282
|
default:
|
|
212
283
|
throw new Error(`--install-skill is not supported for host '${hostName}'.`);
|
|
213
284
|
}
|
|
@@ -321,15 +392,61 @@ export async function inspectInstalledSkillArtifactsForHosts({
|
|
|
321
392
|
skillStates.set(skillName, skillState);
|
|
322
393
|
}
|
|
323
394
|
|
|
395
|
+
// Capture pre-install presence of every relevant install marker so a
|
|
396
|
+
// rollback can restore the exact state the filesystem was in before this
|
|
397
|
+
// install attempt. Without this, a failure after a marker write leaves
|
|
398
|
+
// stale ownership state — and later uninstalls of other hosts retain
|
|
399
|
+
// shared skill dirs that were never actually claimed, or the cross-mode
|
|
400
|
+
// conflict guard flips for a host that was never really installed. Every
|
|
401
|
+
// host that uses the flywheel skill installer is tracked here because
|
|
402
|
+
// the install may write a marker for any of them depending on call
|
|
403
|
+
// context; markers we never wrote simply stay absent.
|
|
404
|
+
const skillOnlyHostMarkers = new Map();
|
|
405
|
+
for (const hostName of uniqueValues(hostNames)) {
|
|
406
|
+
if (!SUPPORTED_INSTALL_SKILL_HOSTS.includes(hostName)) continue;
|
|
407
|
+
const markerPath = resolveFlywheelInstalledMarkerPath(
|
|
408
|
+
projectRoot,
|
|
409
|
+
hostName,
|
|
410
|
+
normalizedScope,
|
|
411
|
+
);
|
|
412
|
+
// eslint-disable-next-line no-await-in-loop
|
|
413
|
+
const hadMarker = await pathExists(markerPath);
|
|
414
|
+
skillOnlyHostMarkers.set(hostName, {
|
|
415
|
+
markerPath,
|
|
416
|
+
hadMarker,
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
|
|
324
420
|
return {
|
|
325
421
|
backupRoot,
|
|
326
422
|
skillStates,
|
|
327
423
|
skillsLockPath,
|
|
328
424
|
hadSkillsLock,
|
|
329
425
|
skillsLockContents,
|
|
426
|
+
skillOnlyHostMarkers,
|
|
330
427
|
};
|
|
331
428
|
}
|
|
332
429
|
|
|
430
|
+
/**
|
|
431
|
+
* Install Flywheel's bundled skills into each selected host's conventional
|
|
432
|
+
* skill directory.
|
|
433
|
+
*
|
|
434
|
+
* `cliMode` toggles the ownership-marker policy to match the caller's
|
|
435
|
+
* install semantics:
|
|
436
|
+
*
|
|
437
|
+
* - `cliMode: false` (default, MCP setup path): write an install marker
|
|
438
|
+
* ONLY for pure skill-only hosts, because MCP-capable hosts advertise
|
|
439
|
+
* their install via the MCP config entry written elsewhere in the MCP
|
|
440
|
+
* flow. Writing a marker for them here would over-report ownership and
|
|
441
|
+
* break legitimate cross-mode conflict detection.
|
|
442
|
+
*
|
|
443
|
+
* - `cliMode: true` (CLI setup path): write an install marker for EVERY
|
|
444
|
+
* host passed in. The CLI setup path does not write any MCP config, so
|
|
445
|
+
* without a per-host marker, a subsequent MCP-mode setup cannot tell
|
|
446
|
+
* whether a shared-root skill dir belongs to this host's CLI install
|
|
447
|
+
* or to some other skill-only install at the same root, and its
|
|
448
|
+
* cross-mode conflict guard silently fails open.
|
|
449
|
+
*/
|
|
333
450
|
export async function installBundledSkillForHosts({
|
|
334
451
|
projectRoot = process.cwd(),
|
|
335
452
|
hostNames = [],
|
|
@@ -337,6 +454,7 @@ export async function installBundledSkillForHosts({
|
|
|
337
454
|
serverName = DEFAULT_SKILL_MCP_SERVER_NAME,
|
|
338
455
|
serverUrl = DEFAULT_SKILL_MCP_SERVER_URL,
|
|
339
456
|
skillNames,
|
|
457
|
+
cliMode = false,
|
|
340
458
|
} = {}) {
|
|
341
459
|
const packageRoot = resolvePackageRoot();
|
|
342
460
|
const skillsCliPath = resolveSkillsCliPath(packageRoot);
|
|
@@ -370,6 +488,36 @@ export async function installBundledSkillForHosts({
|
|
|
370
488
|
|
|
371
489
|
try {
|
|
372
490
|
for (const hostName of uniqueValues(hostNames)) {
|
|
491
|
+
// Skill-only hosts always get the ownership marker; MCP-capable
|
|
492
|
+
// hosts only get it when the caller is the CLI setup path (see the
|
|
493
|
+
// docstring on installBundledSkillForHosts for rationale).
|
|
494
|
+
const shouldWriteMarker =
|
|
495
|
+
SKILL_ONLY_HOST_NAMES.includes(hostName) || cliMode === true;
|
|
496
|
+
|
|
497
|
+
if (isDirectCopySkillHost(hostName)) {
|
|
498
|
+
const destinationDir = resolveInstalledSkillDir(
|
|
499
|
+
projectRoot,
|
|
500
|
+
hostName,
|
|
501
|
+
normalizedScope,
|
|
502
|
+
skillName,
|
|
503
|
+
);
|
|
504
|
+
// eslint-disable-next-line no-await-in-loop
|
|
505
|
+
await rm(destinationDir, { force: true, recursive: true });
|
|
506
|
+
// eslint-disable-next-line no-await-in-loop
|
|
507
|
+
await mkdir(path.dirname(destinationDir), { recursive: true });
|
|
508
|
+
// eslint-disable-next-line no-await-in-loop
|
|
509
|
+
await cp(installSkillSourceDir, destinationDir, { recursive: true });
|
|
510
|
+
if (shouldWriteMarker) {
|
|
511
|
+
const markerPath = resolveFlywheelInstalledMarkerPath(
|
|
512
|
+
projectRoot,
|
|
513
|
+
hostName,
|
|
514
|
+
normalizedScope,
|
|
515
|
+
);
|
|
516
|
+
// eslint-disable-next-line no-await-in-loop
|
|
517
|
+
await writeFile(markerPath, "", { encoding: "utf8", mode: 0o600 });
|
|
518
|
+
}
|
|
519
|
+
continue;
|
|
520
|
+
}
|
|
373
521
|
const agentName = resolveSkillsAgentName(hostName);
|
|
374
522
|
const addArgs = [
|
|
375
523
|
skillsCliPath,
|
|
@@ -388,6 +536,19 @@ export async function installBundledSkillForHosts({
|
|
|
388
536
|
cwd: projectRoot,
|
|
389
537
|
env: process.env,
|
|
390
538
|
});
|
|
539
|
+
if (shouldWriteMarker) {
|
|
540
|
+
// CLI-mode install of an MCP-capable host writes no MCP entry;
|
|
541
|
+
// the marker is the per-host signal prior-mode detection uses
|
|
542
|
+
// to distinguish a real CLI install from artifacts left by an
|
|
543
|
+
// unrelated skill-only install at the same shared skills-root.
|
|
544
|
+
const markerPath = resolveFlywheelInstalledMarkerPath(
|
|
545
|
+
projectRoot,
|
|
546
|
+
hostName,
|
|
547
|
+
normalizedScope,
|
|
548
|
+
);
|
|
549
|
+
// eslint-disable-next-line no-await-in-loop
|
|
550
|
+
await writeFile(markerPath, "", { encoding: "utf8", mode: 0o600 });
|
|
551
|
+
}
|
|
391
552
|
}
|
|
392
553
|
} finally {
|
|
393
554
|
if (stagedSkillSourceRoot) {
|
|
@@ -620,6 +781,23 @@ export async function cleanupInstalledSkillArtifactsForHosts({
|
|
|
620
781
|
await rm(resolveProjectSkillsLockPath(projectRoot), { force: true });
|
|
621
782
|
}
|
|
622
783
|
|
|
784
|
+
// Restore the direct-copy host ownership markers to their pre-install
|
|
785
|
+
// state. When a marker existed before this install (idempotent re-run),
|
|
786
|
+
// the marker file is an empty content-less file so simply leaving it in
|
|
787
|
+
// place is correct; but when the install added the marker for the first
|
|
788
|
+
// time and then failed, we must remove it to avoid false retention on
|
|
789
|
+
// subsequent uninstalls.
|
|
790
|
+
const markerEntries =
|
|
791
|
+
priorState?.skillOnlyHostMarkers instanceof Map
|
|
792
|
+
? [...priorState.skillOnlyHostMarkers.values()]
|
|
793
|
+
: [];
|
|
794
|
+
for (const { markerPath, hadMarker } of markerEntries) {
|
|
795
|
+
if (!hadMarker) {
|
|
796
|
+
// eslint-disable-next-line no-await-in-loop
|
|
797
|
+
await rm(markerPath, { force: true });
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
|
|
623
801
|
if (priorState?.backupRoot) {
|
|
624
802
|
await rm(priorState.backupRoot, { force: true, recursive: true });
|
|
625
803
|
}
|
package/src/unified-cli.mjs
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
|
|
1
5
|
import { runCli as runSetupCli } from "./cli.mjs";
|
|
2
6
|
import { runRuntimeCli } from "./runtime/delegate.mjs";
|
|
3
7
|
import { RUNTIME_ALIASES } from "./runtime/vendor/flywheel-cli-dist/commands/aliases.js";
|
|
4
8
|
|
|
9
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
const PACKAGE_JSON_PATH = path.resolve(__dirname, "..", "package.json");
|
|
11
|
+
|
|
5
12
|
const ALIAS_RESERVED_COMMANDS = new Set([
|
|
6
13
|
"setup",
|
|
7
14
|
"uninstall",
|
|
@@ -9,6 +16,7 @@ const ALIAS_RESERVED_COMMANDS = new Set([
|
|
|
9
16
|
"--help",
|
|
10
17
|
"-h",
|
|
11
18
|
]);
|
|
19
|
+
const VERSION_REQUEST_TOKENS = new Set(["--version", "-v", "version"]);
|
|
12
20
|
|
|
13
21
|
const HELP_EXTRAS = [
|
|
14
22
|
{
|
|
@@ -49,6 +57,30 @@ function stripFormatTokens(argv) {
|
|
|
49
57
|
return out;
|
|
50
58
|
}
|
|
51
59
|
|
|
60
|
+
let cachedPackageVersion = null;
|
|
61
|
+
|
|
62
|
+
async function loadPackageVersion() {
|
|
63
|
+
if (cachedPackageVersion !== null) {
|
|
64
|
+
return cachedPackageVersion;
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
const raw = await readFile(PACKAGE_JSON_PATH, "utf8");
|
|
68
|
+
const parsed = JSON.parse(raw);
|
|
69
|
+
if (typeof parsed.version === "string" && parsed.version.trim()) {
|
|
70
|
+
cachedPackageVersion = parsed.version.trim();
|
|
71
|
+
return cachedPackageVersion;
|
|
72
|
+
}
|
|
73
|
+
} catch {
|
|
74
|
+
// Fall through to deterministic fallback.
|
|
75
|
+
}
|
|
76
|
+
cachedPackageVersion = "0.0.0";
|
|
77
|
+
return cachedPackageVersion;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function isVersionRequest(argv) {
|
|
81
|
+
return argv.length === 1 && VERSION_REQUEST_TOKENS.has(argv[0]);
|
|
82
|
+
}
|
|
83
|
+
|
|
52
84
|
/**
|
|
53
85
|
* Detect a top-level help invocation.
|
|
54
86
|
*
|
|
@@ -104,6 +136,12 @@ export async function runUnifiedCli(argv = process.argv.slice(2)) {
|
|
|
104
136
|
throw new Error("runUnifiedCli expects an argv array.");
|
|
105
137
|
}
|
|
106
138
|
|
|
139
|
+
if (isVersionRequest(argv)) {
|
|
140
|
+
process.stdout.write(`${await loadPackageVersion()}\n`);
|
|
141
|
+
process.exitCode = 0;
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
107
145
|
if (isCombinedHelpRequest(argv)) {
|
|
108
146
|
// Preserve any --format token verbatim so the runtime's format validator
|
|
109
147
|
// runs and rejects unsupported values (e.g. `--format=badvalue`) with the
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const computePolicyGetCommand: import("./types.js").CommandHandler;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"compute-policy-get.js","sourceRoot":"","sources":["../../src/commands/compute-policy-get.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEpD,MAAM,CAAC,MAAM,uBAAuB,GAAG,YAAY,CAAC;IAClD,MAAM,EAAE,KAAK;IACb,YAAY,EAAE,iCAAiC;CAChD,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"compute-policy-set.js","sourceRoot":"","sources":["../../src/commands/compute-policy-set.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,MAAM,CAAC,MAAM,uBAAuB,GAAmB,KAAK,EAAE,OAAO,EAAE,EAAE;IACvE,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACzD,MAAM,IAAI,GAA4B,EAAE,CAAC;IACzC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1D,IAAI,GAAG,KAAK,SAAS;YAAE,SAAS;QAChC,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;YAC/B,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YAClB,SAAS;QACX,CAAC;QACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACzC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;QAC9E,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC,WAAW,CACxB,OAAO,EACP,UAAU,kBAAkB,CAAC,MAAM,CAAC,iBAAiB,EACrD,EAAE,IAAI,EAAE,CACT,CAAC;AACJ,CAAC,CAAC"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { optionalInt, requiredString } from './utils.js';
|
|
2
|
-
export const nodesAuditListCommand = async (context) => {
|
|
3
|
-
const nodeId = requiredString(context.params, 'node_id');
|
|
4
|
-
const limit = optionalInt(context.params, 'limit');
|
|
5
|
-
return context.requestJson('GET', `/nodes/${encodeURIComponent(nodeId)}/audit`, limit !== undefined ? { query: { limit } } : undefined);
|
|
6
|
-
};
|
|
7
|
-
//# sourceMappingURL=nodes-audit-list.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"nodes-audit-list.js","sourceRoot":"","sources":["../../src/commands/nodes-audit-list.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEzD,MAAM,CAAC,MAAM,qBAAqB,GAAmB,KAAK,EAAE,OAAO,EAAE,EAAE;IACrE,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACzD,MAAM,KAAK,GAAG,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnD,OAAO,OAAO,CAAC,WAAW,CACxB,KAAK,EACL,UAAU,kBAAkB,CAAC,MAAM,CAAC,QAAQ,EAC5C,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CACvD,CAAC;AACJ,CAAC,CAAC"}
|