@paradigma-inc/flywheel 0.1.154 → 0.2.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/package.json +1 -1
- package/skills/flywheel/references/flywheel-mcp-tool-map.md +28 -0
- package/src/runtime/required-runtime-commands.json +3 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/artifact-metadata-schema.js +33 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/artifact-metadata-schema.js.map +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/graph-operation-resources.js +66 -9
- package/src/runtime/vendor/flywheel-cli-dist/commands/graph-operation-resources.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/help-metadata.js +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/help-metadata.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/help.js +10 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/help.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/hosted-graph.js +2 -5
- package/src/runtime/vendor/flywheel-cli-dist/commands/hosted-graph.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/hosted-repository-control.js +122 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/hosted-repository-control.js.map +1 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/index.js +2 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/index.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry/hosted.js +122 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry/hosted.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry/repository.js +148 -40
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry/repository.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry.js +2 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/registry.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/commands/repository-output.js +26 -0
- package/src/runtime/vendor/flywheel-cli-dist/commands/repository-output.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/local/store/diagnostics.js +3 -2
- package/src/runtime/vendor/flywheel-cli-dist/local/store/diagnostics.js.map +1 -1
- package/src/runtime/vendor/flywheel-cli-dist/main.js +79 -11
- package/src/runtime/vendor/flywheel-cli-dist/main.js.map +1 -1
- package/src/runtime/vendor/manifest.json +5 -1
- package/src/setup/modes/cli.mjs +137 -106
- package/src/update/cache.mjs +4 -2
package/src/setup/modes/cli.mjs
CHANGED
|
@@ -238,7 +238,9 @@ export async function runCliSetupMode({
|
|
|
238
238
|
serverUrl,
|
|
239
239
|
supportedCliHosts,
|
|
240
240
|
});
|
|
241
|
-
|
|
241
|
+
const hasPriorModeConflict =
|
|
242
|
+
Boolean(priorModeMatch.priorMode) && priorModeMatch.affectedHosts.length > 0;
|
|
243
|
+
if (hasPriorModeConflict) {
|
|
242
244
|
if (force !== true) {
|
|
243
245
|
throw new SetupModeUsageError(
|
|
244
246
|
formatPriorModeConflictError(priorModeMatch),
|
|
@@ -250,7 +252,85 @@ export async function runCliSetupMode({
|
|
|
250
252
|
"reconcilePriorMode dependency is required when --force is used.",
|
|
251
253
|
);
|
|
252
254
|
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const packageRoot = resolvePackageRootFn();
|
|
258
|
+
const skillNames = await listSkillNames(packageRoot);
|
|
259
|
+
if (skillNames.length === 0) {
|
|
260
|
+
throw new Error(`No bundled skills found under ${packageRoot}/skills.`);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const agentResults = [];
|
|
264
|
+
let runtimeConfigPath = null;
|
|
265
|
+
let pathHint = null;
|
|
266
|
+
let cleanupState = null;
|
|
267
|
+
|
|
268
|
+
// Usage errors (bad flags, empty --api-key, mode conflicts) are
|
|
269
|
+
// user-input problems, not operational failures on any particular host.
|
|
270
|
+
// Rethrow so they surface with their intended exit code and let the
|
|
271
|
+
// top-level handler print the message once — matching how `--mode mcp`
|
|
272
|
+
// already behaves. Wrapping them as per-host failures would falsely
|
|
273
|
+
// attribute a user-input error to every selected host and force the
|
|
274
|
+
// setup summary to exit 4 (operational) instead of 1/2 (usage). Shared by
|
|
275
|
+
// the prerequisite stage and the skill stage below so both stages classify
|
|
276
|
+
// failures identically and cannot drift apart.
|
|
277
|
+
function recordOperationalFailure(error) {
|
|
278
|
+
if (
|
|
279
|
+
error instanceof SetupInputUsageError ||
|
|
280
|
+
error instanceof SetupModeUsageError
|
|
281
|
+
) {
|
|
282
|
+
throw error;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
286
|
+
for (const hostName of supportedHosts) {
|
|
287
|
+
agentResults.push({
|
|
288
|
+
agent: hostName,
|
|
289
|
+
success: false,
|
|
290
|
+
touchedFiles: [],
|
|
291
|
+
skippedSteps: ["skill-install"],
|
|
292
|
+
warnings: [message],
|
|
293
|
+
error: message,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
}
|
|
253
297
|
|
|
298
|
+
// Prerequisites that can fail run before anything destructive: resolving
|
|
299
|
+
// the API key, confirming the server accepts it, and writing the CLI
|
|
300
|
+
// runtime configuration all happen before the forced reconcile below
|
|
301
|
+
// removes an existing --mode mcp host entry. That way an ordinary
|
|
302
|
+
// auth/network/config failure leaves the prior MCP entry intact instead of
|
|
303
|
+
// a machine with neither mode working. A skill-install failure *after* a
|
|
304
|
+
// successful reconcile is a separate, accepted boundary: the runtime
|
|
305
|
+
// config is already written, so the CLI stays usable and rerunning the
|
|
306
|
+
// same command converges — this boundary is intentional, not a gap.
|
|
307
|
+
let prerequisiteFailed = false;
|
|
308
|
+
if (!skillOnlyOnly) {
|
|
309
|
+
try {
|
|
310
|
+
const resolvedAuth = authResult ?? await resolveSetupApiKeyFn({
|
|
311
|
+
options: {
|
|
312
|
+
apiKey,
|
|
313
|
+
authMode,
|
|
314
|
+
},
|
|
315
|
+
baseUrl,
|
|
316
|
+
});
|
|
317
|
+
await validateRemoteReadinessFn({
|
|
318
|
+
baseUrl,
|
|
319
|
+
apiKey: resolvedAuth.apiKey,
|
|
320
|
+
});
|
|
321
|
+
const runtimeConfig = await writeRuntimeConfigFn({
|
|
322
|
+
origin: baseUrl,
|
|
323
|
+
apiKey: resolvedAuth.apiKey,
|
|
324
|
+
credentialProfile: await credentialProfileForSetupBaseUrl(baseUrl),
|
|
325
|
+
});
|
|
326
|
+
runtimeConfigPath = runtimeConfig.configPath;
|
|
327
|
+
} catch (error) {
|
|
328
|
+
recordOperationalFailure(error);
|
|
329
|
+
prerequisiteFailed = true;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
if (!prerequisiteFailed && hasPriorModeConflict) {
|
|
254
334
|
const reconcileEntries = Array.isArray(priorModeMatch.entries)
|
|
255
335
|
? priorModeMatch.entries
|
|
256
336
|
: priorModeMatch.affectedHosts.map((hostName) => ({
|
|
@@ -291,120 +371,71 @@ export async function runCliSetupMode({
|
|
|
291
371
|
);
|
|
292
372
|
}
|
|
293
373
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
let runtimeConfigPath = null;
|
|
302
|
-
let pathHint = null;
|
|
303
|
-
let cleanupState = null;
|
|
304
|
-
try {
|
|
305
|
-
cleanupState = await inspectSkillArtifactsForHosts({
|
|
306
|
-
projectRoot: cwd,
|
|
307
|
-
hostNames: supportedHosts,
|
|
308
|
-
scope,
|
|
309
|
-
skillNames,
|
|
310
|
-
});
|
|
311
|
-
|
|
312
|
-
await installSkillForHosts({
|
|
313
|
-
projectRoot: cwd,
|
|
314
|
-
hostNames: supportedHosts,
|
|
315
|
-
scope,
|
|
316
|
-
serverName,
|
|
317
|
-
serverUrl,
|
|
318
|
-
skillNames,
|
|
319
|
-
// CLI-mode install: write a per-host ownership marker for every host
|
|
320
|
-
// so a later `setup --mode mcp --<host>` can detect this install via
|
|
321
|
-
// the marker even when the skills-root is shared with other hosts.
|
|
322
|
-
cliMode: true,
|
|
323
|
-
});
|
|
324
|
-
|
|
325
|
-
// Skill-only hosts (e.g. --universal, --antigravity) do not bind to the
|
|
326
|
-
// flywheel CLI binary — they just drop skill directories for the IDE or
|
|
327
|
-
// toolchain to read. Skip API-key minting, runtime-config writing, and
|
|
328
|
-
// the binary-on-PATH hint when every selected host is skill-only, so a
|
|
329
|
-
// `flywheel setup --universal --mode cli --yes` run is entirely hermetic.
|
|
330
|
-
if (!skillOnlyOnly) {
|
|
331
|
-
const resolvedAuth = authResult ?? await resolveSetupApiKeyFn({
|
|
332
|
-
options: {
|
|
333
|
-
apiKey,
|
|
334
|
-
authMode,
|
|
335
|
-
},
|
|
336
|
-
baseUrl,
|
|
337
|
-
});
|
|
338
|
-
await validateRemoteReadinessFn({
|
|
339
|
-
baseUrl,
|
|
340
|
-
apiKey: resolvedAuth.apiKey,
|
|
341
|
-
});
|
|
342
|
-
const runtimeConfig = await writeRuntimeConfigFn({
|
|
343
|
-
origin: baseUrl,
|
|
344
|
-
apiKey: resolvedAuth.apiKey,
|
|
345
|
-
credentialProfile: await credentialProfileForSetupBaseUrl(baseUrl),
|
|
346
|
-
});
|
|
347
|
-
runtimeConfigPath = runtimeConfig.configPath;
|
|
348
|
-
|
|
349
|
-
const resolvedBinaryPath = await resolveFlywheelBinaryPath({
|
|
350
|
-
env,
|
|
351
|
-
platform,
|
|
374
|
+
if (!prerequisiteFailed) {
|
|
375
|
+
try {
|
|
376
|
+
cleanupState = await inspectSkillArtifactsForHosts({
|
|
377
|
+
projectRoot: cwd,
|
|
378
|
+
hostNames: supportedHosts,
|
|
379
|
+
scope,
|
|
380
|
+
skillNames,
|
|
352
381
|
});
|
|
353
|
-
pathHint = resolvedBinaryPath
|
|
354
|
-
? `flywheel binary detected on PATH at ${resolvedBinaryPath}.`
|
|
355
|
-
: formatMissingFlywheelPathHint({ platform });
|
|
356
|
-
}
|
|
357
382
|
|
|
358
|
-
|
|
359
|
-
await removeDir(cleanupState.backupRoot, { force: true, recursive: true });
|
|
360
|
-
cleanupState = null;
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
for (const hostName of supportedHosts) {
|
|
364
|
-
agentResults.push({
|
|
365
|
-
agent: hostName,
|
|
366
|
-
success: true,
|
|
367
|
-
touchedFiles: runtimeConfigPath ? [runtimeConfigPath] : [],
|
|
368
|
-
skippedSteps: [],
|
|
369
|
-
warnings: [],
|
|
370
|
-
});
|
|
371
|
-
}
|
|
372
|
-
} catch (error) {
|
|
373
|
-
if (cleanupState) {
|
|
374
|
-
await cleanupSkillArtifactsForHosts({
|
|
383
|
+
await installSkillForHosts({
|
|
375
384
|
projectRoot: cwd,
|
|
376
385
|
hostNames: supportedHosts,
|
|
377
|
-
priorState: cleanupState,
|
|
378
386
|
scope,
|
|
387
|
+
serverName,
|
|
388
|
+
serverUrl,
|
|
379
389
|
skillNames,
|
|
390
|
+
// CLI-mode install: write a per-host ownership marker for every host
|
|
391
|
+
// so a later `setup --mode mcp --<host>` can detect this install via
|
|
392
|
+
// the marker even when the skills-root is shared with other hosts.
|
|
393
|
+
cliMode: true,
|
|
380
394
|
});
|
|
381
|
-
cleanupState = null;
|
|
382
|
-
}
|
|
383
395
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
396
|
+
// Skill-only hosts (e.g. --universal, --antigravity) do not bind to
|
|
397
|
+
// the flywheel CLI binary — they just drop skill directories for the
|
|
398
|
+
// IDE or toolchain to read. Skip the binary-on-PATH hint when every
|
|
399
|
+
// selected host is skill-only, so a
|
|
400
|
+
// `flywheel setup --universal --mode cli --yes` run is entirely
|
|
401
|
+
// hermetic.
|
|
402
|
+
if (!skillOnlyOnly) {
|
|
403
|
+
const resolvedBinaryPath = await resolveFlywheelBinaryPath({
|
|
404
|
+
env,
|
|
405
|
+
platform,
|
|
406
|
+
});
|
|
407
|
+
pathHint = resolvedBinaryPath
|
|
408
|
+
? `flywheel binary detected on PATH at ${resolvedBinaryPath}.`
|
|
409
|
+
: formatMissingFlywheelPathHint({ platform });
|
|
410
|
+
}
|
|
397
411
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
412
|
+
if (cleanupState?.backupRoot) {
|
|
413
|
+
await removeDir(cleanupState.backupRoot, { force: true, recursive: true });
|
|
414
|
+
cleanupState = null;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
for (const hostName of supportedHosts) {
|
|
418
|
+
agentResults.push({
|
|
419
|
+
agent: hostName,
|
|
420
|
+
success: true,
|
|
421
|
+
touchedFiles: runtimeConfigPath ? [runtimeConfigPath] : [],
|
|
422
|
+
skippedSteps: [],
|
|
423
|
+
warnings: [],
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
} catch (error) {
|
|
427
|
+
if (cleanupState) {
|
|
428
|
+
await cleanupSkillArtifactsForHosts({
|
|
429
|
+
projectRoot: cwd,
|
|
430
|
+
hostNames: supportedHosts,
|
|
431
|
+
priorState: cleanupState,
|
|
432
|
+
scope,
|
|
433
|
+
skillNames,
|
|
434
|
+
});
|
|
435
|
+
cleanupState = null;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
recordOperationalFailure(error);
|
|
408
439
|
}
|
|
409
440
|
}
|
|
410
441
|
|
package/src/update/cache.mjs
CHANGED
|
@@ -24,8 +24,10 @@ export function resolveUpdateCheckCachePath({
|
|
|
24
24
|
String(env.LOCALAPPDATA || "").trim() ||
|
|
25
25
|
path.join(homeDir, "AppData", "Local");
|
|
26
26
|
} else {
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
const xdgCacheHome = String(env.XDG_CACHE_HOME || "").trim();
|
|
28
|
+
cacheRoot = path.isAbsolute(xdgCacheHome)
|
|
29
|
+
? xdgCacheHome
|
|
30
|
+
: path.join(homeDir, ".cache");
|
|
29
31
|
}
|
|
30
32
|
return path.join(cacheRoot, "flywheel", "update-check.json");
|
|
31
33
|
}
|