quiver-cli 1.2.0 → 1.3.1
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/cli.js +237 -10
- package/package.json +1 -1
- package/template/.agents/skills/agent-browser/SKILL.md +1 -0
- package/template/.agents/skills/apps/skybridge/SKILL.md +2 -0
- package/template/.agents/skills/data/prisma-cli/SKILL.md +25 -7
- package/template/.agents/skills/data/prisma-cli/references/agent-safety.md +27 -0
- package/template/.agents/skills/data/prisma-cli/references/complete.md +22 -0
- package/template/.agents/skills/data/prisma-cli/references/db-push.md +2 -0
- package/template/.agents/skills/data/prisma-cli/references/init.md +3 -0
- package/template/.agents/skills/data/prisma-cli/references/mcp.md +2 -1
- package/template/.agents/skills/data/prisma-cli/references/migrate-dev.md +1 -1
- package/template/.agents/skills/data/prisma-cli/references/migrate-reset.md +2 -0
- package/template/.agents/skills/data/prisma-client-api/SKILL.md +1 -1
- package/template/.agents/skills/data/prisma-client-api/references/constructor.md +13 -0
- package/template/.agents/skills/data/prisma-client-api/references/raw-queries.md +4 -0
- package/template/.agents/skills/design/impeccable/SKILL.md +5 -5
- package/template/.agents/skills/design/impeccable/reference/android.md +6 -0
- package/template/.agents/skills/design/impeccable/reference/animate.md +3 -0
- package/template/.agents/skills/design/impeccable/reference/bolder.md +3 -1
- package/template/.agents/skills/design/impeccable/reference/craft-floor.md +2 -0
- package/template/.agents/skills/design/impeccable/reference/critique.md +23 -5
- package/template/.agents/skills/design/impeccable/reference/degraded/asset-producer.md +15 -68
- package/template/.agents/skills/design/impeccable/reference/degraded/finish-reviewer.md +13 -12
- package/template/.agents/skills/design/impeccable/reference/distill.md +1 -1
- package/template/.agents/skills/design/impeccable/reference/doctor.md +1 -0
- package/template/.agents/skills/design/impeccable/reference/document.md +1 -1
- package/template/.agents/skills/design/impeccable/reference/extract.md +1 -1
- package/template/.agents/skills/design/impeccable/reference/hooks.md +17 -11
- package/template/.agents/skills/design/impeccable/reference/init.md +9 -3
- package/template/.agents/skills/design/impeccable/reference/ios.md +6 -0
- package/template/.agents/skills/design/impeccable/reference/new-work.md +69 -29
- package/template/.agents/skills/design/impeccable/reference/overdrive.md +1 -1
- package/template/.agents/skills/design/impeccable/reference/polish.md +13 -5
- package/template/.agents/skills/design/impeccable/reference/quieter.md +1 -1
- package/template/.agents/skills/design/impeccable/reference/routing.md +1 -1
- package/template/.agents/skills/design/impeccable/reference/visualize.md +21 -22
- package/template/.agents/skills/design/impeccable/scripts/build-phase.mjs +1022 -0
- package/template/.agents/skills/design/impeccable/scripts/comp-diff.mjs +391 -0
- package/template/.agents/skills/design/impeccable/scripts/comp-spec.mjs +513 -0
- package/template/.agents/skills/design/impeccable/scripts/concept-seed.mjs +297 -41
- package/template/.agents/skills/design/impeccable/scripts/context-signals.mjs +10 -19
- package/template/.agents/skills/design/impeccable/scripts/context.mjs +124 -9
- package/template/.agents/skills/design/impeccable/scripts/critique-storage.mjs +279 -19
- package/template/.agents/skills/design/impeccable/scripts/data/font-index-failures.json +121 -0
- package/template/.agents/skills/design/impeccable/scripts/data/font-index.json +1 -0
- package/template/.agents/skills/design/impeccable/scripts/detect.mjs +9 -0
- package/template/.agents/skills/design/impeccable/scripts/detector/browser/injected/index.mjs +192 -11
- package/template/.agents/skills/design/impeccable/scripts/detector/cli/main.mjs +10 -16
- package/template/.agents/skills/design/impeccable/scripts/detector/design-system.mjs +339 -11
- package/template/.agents/skills/design/impeccable/scripts/detector/detect-antipatterns-browser.js +1482 -722
- package/template/.agents/skills/design/impeccable/scripts/detector/detect-antipatterns.mjs +1 -0
- package/template/.agents/skills/design/impeccable/scripts/detector/engines/browser/detect-url.mjs +64 -2
- package/template/.agents/skills/design/impeccable/scripts/detector/engines/regex/detect-text.mjs +580 -29
- package/template/.agents/skills/design/impeccable/scripts/detector/engines/static-html/css-cascade.mjs +62 -7
- package/template/.agents/skills/design/impeccable/scripts/detector/engines/static-html/detect-html.mjs +31 -7
- package/template/.agents/skills/design/impeccable/scripts/detector/node/file-system.mjs +23 -22
- package/template/.agents/skills/design/impeccable/scripts/detector/registry/antipatterns.mjs +18 -0
- package/template/.agents/skills/design/impeccable/scripts/detector/rules/checks.mjs +471 -370
- package/template/.agents/skills/design/impeccable/scripts/detector/shared/color.mjs +474 -2
- package/template/.agents/skills/design/impeccable/scripts/detector/shared/constants.mjs +17 -2
- package/template/.agents/skills/design/impeccable/scripts/doctor.mjs +14 -21
- package/template/.agents/skills/design/impeccable/scripts/embed-prompt.mjs +81 -48
- package/template/.agents/skills/design/impeccable/scripts/font-match.mjs +457 -0
- package/template/.agents/skills/design/impeccable/scripts/generate-image.mjs +219 -12
- package/template/.agents/skills/design/impeccable/scripts/hook-admin.mjs +93 -15
- package/template/.agents/skills/design/impeccable/scripts/hook-before-edit.mjs +41 -19
- package/template/.agents/skills/design/impeccable/scripts/hook-lib.mjs +507 -117
- package/template/.agents/skills/design/impeccable/scripts/hook.mjs +10 -9
- package/template/.agents/skills/design/impeccable/scripts/lib/concept-catalog.mjs +40 -1
- package/template/.agents/skills/design/impeccable/scripts/lib/design-parser.mjs +120 -82
- package/template/.agents/skills/design/impeccable/scripts/lib/font-fingerprint.mjs +564 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/font-index.mjs +130 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/hero-checks.mjs +246 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/image-metrics.mjs +306 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/impeccable-config.mjs +41 -59
- package/template/.agents/skills/design/impeccable/scripts/lib/is-generated.mjs +5 -2
- package/template/.agents/skills/design/impeccable/scripts/lib/live-path-globs.mjs +37 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/open-system-browser.mjs +26 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/png.mjs +281 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/raster.mjs +194 -0
- package/template/.agents/skills/design/impeccable/scripts/lib/roll-selection.mjs +26 -19
- package/template/.agents/skills/design/impeccable/scripts/lib/staleness-deep.mjs +31 -3
- package/template/.agents/skills/design/impeccable/scripts/lib/staleness.mjs +93 -17
- package/template/.agents/skills/design/impeccable/scripts/lib/surface-briefs.mjs +9 -11
- package/template/.agents/skills/design/impeccable/scripts/live/browser-script-parts.mjs +31 -2
- package/template/.agents/skills/design/impeccable/scripts/live/project-ignores.mjs +139 -0
- package/template/.agents/skills/design/impeccable/scripts/live/svelte-ast.mjs +10 -2
- package/template/.agents/skills/design/impeccable/scripts/live/svelte-component.mjs +26 -2
- package/template/.agents/skills/design/impeccable/scripts/live/sveltekit-adapter.mjs +15 -27
- package/template/.agents/skills/design/impeccable/scripts/live/tanstack-adapter.mjs +4 -25
- package/template/.agents/skills/design/impeccable/scripts/live/ui-surfaces.mjs +75 -0
- package/template/.agents/skills/design/impeccable/scripts/live-accept.mjs +21 -37
- package/template/.agents/skills/design/impeccable/scripts/live-browser-ignores.js +242 -0
- package/template/.agents/skills/design/impeccable/scripts/live-browser.js +62 -23
- package/template/.agents/skills/design/impeccable/scripts/live-commit-manual-edits.mjs +68 -112
- package/template/.agents/skills/design/impeccable/scripts/live-copy-edit-agent.mjs +132 -15
- package/template/.agents/skills/design/impeccable/scripts/live-inject.mjs +2 -42
- package/template/.agents/skills/design/impeccable/scripts/live-poll.mjs +5 -4
- package/template/.agents/skills/design/impeccable/scripts/live-server.mjs +56 -19
- package/template/.agents/skills/design/impeccable/scripts/live.mjs +12 -37
- package/template/.agents/skills/design/impeccable/scripts/pin.mjs +8 -5
- package/template/.agents/skills/design/impeccable/scripts/serve-question.mjs +1006 -155
- package/template/.agents/skills/design/shadcn/rules/chat.md +26 -0
- package/template/.agents/skills/hono/SKILL.md +17 -3
- package/template/.agents/skills/integrations/langfuse/SKILL.md +8 -4
- package/template/.agents/skills/integrations/langfuse/references/cli.md +1 -1
- package/template/.agents/skills/integrations/langfuse/references/create-dataset.md +35 -0
- package/template/.agents/skills/integrations/langfuse/references/error-analysis.md +9 -10
- package/template/.agents/skills/integrations/langfuse/references/judge-calibration.md +8 -6
- package/template/.agents/skills/integrations/langfuse/references/sdk-upgrade.md +34 -0
- package/template/.agents/skills/integrations/langfuse/references/setting-up-evals.md +65 -0
- package/template/.agents/skills/integrations/langfuse/references/skill-feedback.md +20 -40
- package/template/.agents/skills/integrations/langfuse/references/user-feedback.md +4 -30
- package/template/.agents/skills/integrations/langfuse/references/v4-project-migration.md +3 -1
- package/template/.agents/skills/supabase/CHANGELOG.md +7 -0
- package/template/.agents/skills/supabase/SKILL.md +5 -1
- package/template/.agents/skills/writing/humanizer/LICENSE +21 -0
- package/template/.agents/skills/writing/humanizer/README.md +209 -0
- package/template/.agents/skills/writing/humanizer/SKILL.md +173 -338
- package/template/.agents/upstreams.json +21 -22
- package/template/.agents/skills/design/impeccable/scripts/live/ui-core.mjs +0 -180
package/dist/cli.js
CHANGED
|
@@ -2499,6 +2499,31 @@ var init_update = __esm({
|
|
|
2499
2499
|
}
|
|
2500
2500
|
});
|
|
2501
2501
|
|
|
2502
|
+
// src/mcp/tokens.ts
|
|
2503
|
+
var estimateTokens, formatTokens, sumTokens;
|
|
2504
|
+
var init_tokens = __esm({
|
|
2505
|
+
"src/mcp/tokens.ts"() {
|
|
2506
|
+
"use strict";
|
|
2507
|
+
init_digest();
|
|
2508
|
+
estimateTokens = (tool) => Math.ceil(
|
|
2509
|
+
canonicalJson({
|
|
2510
|
+
name: tool.name,
|
|
2511
|
+
description: tool.description,
|
|
2512
|
+
inputSchema: tool.inputSchema
|
|
2513
|
+
}).length / 4
|
|
2514
|
+
);
|
|
2515
|
+
formatTokens = (n) => n < 1e3 ? `~${n} tok` : `~${(n / 1e3).toFixed(1)}k tok`;
|
|
2516
|
+
sumTokens = (tools) => {
|
|
2517
|
+
let total = 0;
|
|
2518
|
+
for (const tool of Object.values(tools)) {
|
|
2519
|
+
if (tool.tokens === void 0) return null;
|
|
2520
|
+
total += tool.tokens;
|
|
2521
|
+
}
|
|
2522
|
+
return total;
|
|
2523
|
+
};
|
|
2524
|
+
}
|
|
2525
|
+
});
|
|
2526
|
+
|
|
2502
2527
|
// src/commands/list.ts
|
|
2503
2528
|
var list_exports = {};
|
|
2504
2529
|
__export(list_exports, {
|
|
@@ -2511,6 +2536,7 @@ var init_list = __esm({
|
|
|
2511
2536
|
init_repo();
|
|
2512
2537
|
init_io();
|
|
2513
2538
|
init_schema();
|
|
2539
|
+
init_tokens();
|
|
2514
2540
|
init_local_config();
|
|
2515
2541
|
init_prompts();
|
|
2516
2542
|
truncate = (s, max) => {
|
|
@@ -2570,6 +2596,7 @@ var init_list = __esm({
|
|
|
2570
2596
|
enabled: !disabled.has(name),
|
|
2571
2597
|
detail: serverDetail2.get(name) ?? null,
|
|
2572
2598
|
toolCount: entry.tools ? Object.keys(entry.tools).length : null,
|
|
2599
|
+
tokenEstimate: entry.tools ? sumTokens(entry.tools) : null,
|
|
2573
2600
|
authRequired: entry.authRequired ?? false
|
|
2574
2601
|
})),
|
|
2575
2602
|
plugins: plugins.map(({ name, entry }) => ({
|
|
@@ -2619,22 +2646,35 @@ var init_list = __esm({
|
|
|
2619
2646
|
return `${n ?? "?"} tools`.length;
|
|
2620
2647
|
})
|
|
2621
2648
|
);
|
|
2649
|
+
const tokenCell = (entry) => {
|
|
2650
|
+
const total = entry.tools ? sumTokens(entry.tools) : null;
|
|
2651
|
+
return total === null ? "? tok" : formatTokens(total);
|
|
2652
|
+
};
|
|
2653
|
+
const tokW = Math.max(...mcp.map((e) => tokenCell(e.entry).length));
|
|
2622
2654
|
lines.push("", ` ${c.bold("mcp servers")}`);
|
|
2623
2655
|
for (const { name, entry } of mcp) {
|
|
2624
2656
|
const count = entry.tools ? Object.keys(entry.tools).length : null;
|
|
2657
|
+
const tokenTotal = entry.tools ? sumTokens(entry.tools) : null;
|
|
2625
2658
|
if (count === null) {
|
|
2626
2659
|
if (entry.authRequired) needsAuth.push(name);
|
|
2627
2660
|
else missingTools = true;
|
|
2661
|
+
} else if (tokenTotal === null) {
|
|
2662
|
+
missingTools = true;
|
|
2628
2663
|
}
|
|
2629
2664
|
const tools = padCell(
|
|
2630
2665
|
`${count ?? "?"} tools`,
|
|
2631
2666
|
toolW,
|
|
2632
2667
|
count === null ? c.dim : c.green
|
|
2633
2668
|
);
|
|
2669
|
+
const tokens = padCell(
|
|
2670
|
+
tokenCell(entry),
|
|
2671
|
+
tokW,
|
|
2672
|
+
tokenTotal === null ? c.dim : c.cyan
|
|
2673
|
+
);
|
|
2634
2674
|
const detail = serverDetail2.get(name);
|
|
2635
2675
|
const off = disabled.has(name) ? ` ${c.yellow("disabled")}` : "";
|
|
2636
2676
|
lines.push(
|
|
2637
|
-
` ${name.padEnd(nameW)} ${entry.transport.padEnd(5)} ${tools}` + (detail ? ` ${c.dim(detail)}` : "") + off
|
|
2677
|
+
` ${name.padEnd(nameW)} ${entry.transport.padEnd(5)} ${tools} ${tokens}` + (detail ? ` ${c.dim(detail)}` : "") + off
|
|
2638
2678
|
);
|
|
2639
2679
|
}
|
|
2640
2680
|
}
|
|
@@ -2660,7 +2700,173 @@ var init_list = __esm({
|
|
|
2660
2700
|
);
|
|
2661
2701
|
}
|
|
2662
2702
|
if (missingTools) {
|
|
2663
|
-
lines.push(
|
|
2703
|
+
lines.push(
|
|
2704
|
+
` ${c.dim("run 'quiver-cli check' to populate tool counts and token estimates")}`
|
|
2705
|
+
);
|
|
2706
|
+
}
|
|
2707
|
+
lines.push("");
|
|
2708
|
+
block(lines);
|
|
2709
|
+
};
|
|
2710
|
+
}
|
|
2711
|
+
});
|
|
2712
|
+
|
|
2713
|
+
// src/commands/inspect.ts
|
|
2714
|
+
var inspect_exports = {};
|
|
2715
|
+
__export(inspect_exports, {
|
|
2716
|
+
inspect: () => inspect
|
|
2717
|
+
});
|
|
2718
|
+
var truncate2, padCell2, byCost, inspect;
|
|
2719
|
+
var init_inspect = __esm({
|
|
2720
|
+
"src/commands/inspect.ts"() {
|
|
2721
|
+
"use strict";
|
|
2722
|
+
init_repo();
|
|
2723
|
+
init_io();
|
|
2724
|
+
init_tokens();
|
|
2725
|
+
init_local_config();
|
|
2726
|
+
init_prompts();
|
|
2727
|
+
truncate2 = (s, max) => {
|
|
2728
|
+
const flat = s.replace(/\s+/g, " ").trim();
|
|
2729
|
+
if (max < 1) return "";
|
|
2730
|
+
return flat.length > max ? flat.slice(0, max - 1) + "\u2026" : flat;
|
|
2731
|
+
};
|
|
2732
|
+
padCell2 = (text, width, color) => color(text.padEnd(width));
|
|
2733
|
+
byCost = (a, b) => (b.tool.tokens ?? -1) - (a.tool.tokens ?? -1) || a.name.localeCompare(b.name);
|
|
2734
|
+
inspect = async (options) => {
|
|
2735
|
+
const arg = options.positionals[0];
|
|
2736
|
+
if (!arg) {
|
|
2737
|
+
if (options.json) {
|
|
2738
|
+
console.log(JSON.stringify({ ok: false, error: "missing-argument" }));
|
|
2739
|
+
} else {
|
|
2740
|
+
await error("Usage: quiver-cli inspect <mcp-name>");
|
|
2741
|
+
}
|
|
2742
|
+
process.exitCode = 1;
|
|
2743
|
+
return;
|
|
2744
|
+
}
|
|
2745
|
+
const name = arg.startsWith("mcp:") ? arg.slice("mcp:".length) : arg;
|
|
2746
|
+
const lock = readLockfile(options.targetRoot);
|
|
2747
|
+
if (!lock) {
|
|
2748
|
+
if (options.json) console.log(JSON.stringify({ ok: false, error: "no-lockfile" }));
|
|
2749
|
+
else await error("No quiver.lock found. Run `quiver-cli init` first.");
|
|
2750
|
+
process.exitCode = 1;
|
|
2751
|
+
return;
|
|
2752
|
+
}
|
|
2753
|
+
const entry = lock.entries[`mcp:${name}`];
|
|
2754
|
+
if (!entry || entry.type !== "mcp") {
|
|
2755
|
+
const available = Object.keys(lock.entries).filter((id) => id.startsWith("mcp:")).map((id) => id.slice("mcp:".length)).sort();
|
|
2756
|
+
if (options.json) {
|
|
2757
|
+
console.log(
|
|
2758
|
+
JSON.stringify({ ok: false, error: "unknown-server", available })
|
|
2759
|
+
);
|
|
2760
|
+
} else {
|
|
2761
|
+
await error(
|
|
2762
|
+
`Unknown MCP server "${name}".` + (available.length ? ` Available: ${available.join(", ")}` : "")
|
|
2763
|
+
);
|
|
2764
|
+
}
|
|
2765
|
+
process.exitCode = 1;
|
|
2766
|
+
return;
|
|
2767
|
+
}
|
|
2768
|
+
const mcpEntry = entry;
|
|
2769
|
+
let detail = null;
|
|
2770
|
+
if (repoCatalogExists(options.targetRoot)) {
|
|
2771
|
+
const { catalog } = loadRepoCatalog(options.targetRoot, lock.catalog.source);
|
|
2772
|
+
const cat = catalog.mcp.find((m) => m.name === name);
|
|
2773
|
+
if (cat) {
|
|
2774
|
+
detail = cat.server.transport === "http" ? cat.server.url : [cat.server.command, ...cat.server.args ?? []].join(" ");
|
|
2775
|
+
}
|
|
2776
|
+
}
|
|
2777
|
+
const enabled = !disabledMcpServers(options.targetRoot).has(name);
|
|
2778
|
+
const tools = mcpEntry.tools ? Object.entries(mcpEntry.tools).map(([toolName, tool]) => ({ name: toolName, tool })).sort(byCost) : null;
|
|
2779
|
+
const total = mcpEntry.tools ? sumTokens(mcpEntry.tools) : null;
|
|
2780
|
+
if (options.json) {
|
|
2781
|
+
console.log(
|
|
2782
|
+
JSON.stringify(
|
|
2783
|
+
{
|
|
2784
|
+
ok: true,
|
|
2785
|
+
name,
|
|
2786
|
+
transport: mcpEntry.transport,
|
|
2787
|
+
detail,
|
|
2788
|
+
enabled,
|
|
2789
|
+
authRequired: mcpEntry.authRequired ?? false,
|
|
2790
|
+
toolsFetchedAt: mcpEntry.toolsFetchedAt,
|
|
2791
|
+
toolCount: tools ? tools.length : null,
|
|
2792
|
+
tokenEstimate: total,
|
|
2793
|
+
tools: tools ? tools.map(({ name: toolName, tool }) => ({
|
|
2794
|
+
name: toolName,
|
|
2795
|
+
description: tool.description,
|
|
2796
|
+
tokens: tool.tokens ?? null,
|
|
2797
|
+
inputSchemaHash: tool.inputSchemaHash
|
|
2798
|
+
})) : null
|
|
2799
|
+
},
|
|
2800
|
+
null,
|
|
2801
|
+
2
|
|
2802
|
+
)
|
|
2803
|
+
);
|
|
2804
|
+
return;
|
|
2805
|
+
}
|
|
2806
|
+
const c = palette();
|
|
2807
|
+
const term = process.stdout.columns ?? 80;
|
|
2808
|
+
const lines = [""];
|
|
2809
|
+
lines.push(
|
|
2810
|
+
` ${c.bold(name)} ${mcpEntry.transport}` + (detail ? ` ${c.dim(detail)}` : "") + (enabled ? "" : ` ${c.yellow("disabled")}`)
|
|
2811
|
+
);
|
|
2812
|
+
if (!tools) {
|
|
2813
|
+
lines.push("", ` ${c.dim("no tool snapshot recorded yet")}`);
|
|
2814
|
+
if (mcpEntry.authRequired) {
|
|
2815
|
+
lines.push(
|
|
2816
|
+
` ${c.yellow(`${name} requires OAuth`)} ${c.dim(
|
|
2817
|
+
`\u2014 run 'opencode mcp auth ${name}', then 'quiver-cli check'`
|
|
2818
|
+
)}`
|
|
2819
|
+
);
|
|
2820
|
+
} else {
|
|
2821
|
+
lines.push(` ${c.dim("run 'quiver-cli check' to introspect this server")}`);
|
|
2822
|
+
}
|
|
2823
|
+
lines.push("");
|
|
2824
|
+
block(lines);
|
|
2825
|
+
return;
|
|
2826
|
+
}
|
|
2827
|
+
const summary = `${tools.length} tools` + (total !== null ? ` \xB7 ${formatTokens(total)}` : "");
|
|
2828
|
+
lines.push(
|
|
2829
|
+
` ${c.bold(summary)}` + (mcpEntry.toolsFetchedAt ? ` ${c.dim(`snapshot from ${mcpEntry.toolsFetchedAt}`)}` : ""),
|
|
2830
|
+
""
|
|
2831
|
+
);
|
|
2832
|
+
const nameW = Math.max(...tools.map((t) => t.name.length));
|
|
2833
|
+
const tokW = Math.max(
|
|
2834
|
+
...tools.map(
|
|
2835
|
+
({ tool }) => (tool.tokens === void 0 ? "? tok" : formatTokens(tool.tokens)).length
|
|
2836
|
+
)
|
|
2837
|
+
);
|
|
2838
|
+
const descMax = term - (4 + nameW + 2 + tokW + 2) - 1;
|
|
2839
|
+
let missingTokens = false;
|
|
2840
|
+
for (const { name: toolName, tool } of tools) {
|
|
2841
|
+
if (tool.tokens === void 0) missingTokens = true;
|
|
2842
|
+
const tokens = padCell2(
|
|
2843
|
+
tool.tokens === void 0 ? "? tok" : formatTokens(tool.tokens),
|
|
2844
|
+
tokW,
|
|
2845
|
+
tool.tokens === void 0 ? c.dim : c.cyan
|
|
2846
|
+
);
|
|
2847
|
+
if (options.verbose) {
|
|
2848
|
+
lines.push(` ${c.bold(toolName.padEnd(nameW))} ${tokens}`);
|
|
2849
|
+
for (const descLine of tool.description.split("\n")) {
|
|
2850
|
+
lines.push(` ${c.dim(descLine)}`);
|
|
2851
|
+
}
|
|
2852
|
+
lines.push("");
|
|
2853
|
+
} else {
|
|
2854
|
+
lines.push(
|
|
2855
|
+
` ${toolName.padEnd(nameW)} ${tokens} ${c.dim(
|
|
2856
|
+
truncate2(tool.description, descMax)
|
|
2857
|
+
)}`.trimEnd()
|
|
2858
|
+
);
|
|
2859
|
+
}
|
|
2860
|
+
}
|
|
2861
|
+
if (!options.verbose) lines.push("");
|
|
2862
|
+
lines.push(` ${c.dim("token counts are chars/4 estimates of name + description + input schema")}`);
|
|
2863
|
+
if (!options.verbose) {
|
|
2864
|
+
lines.push(` ${c.dim("use --verbose for full descriptions")}`);
|
|
2865
|
+
}
|
|
2866
|
+
if (missingTokens) {
|
|
2867
|
+
lines.push(
|
|
2868
|
+
` ${c.dim("run 'quiver-cli check' to populate missing token estimates")}`
|
|
2869
|
+
);
|
|
2664
2870
|
}
|
|
2665
2871
|
lines.push("");
|
|
2666
2872
|
block(lines);
|
|
@@ -2839,21 +3045,34 @@ var init_opencode_auth = __esm({
|
|
|
2839
3045
|
});
|
|
2840
3046
|
|
|
2841
3047
|
// src/mcp/snapshot.ts
|
|
2842
|
-
var toSnapshot;
|
|
3048
|
+
var toSnapshot, backfillTokens;
|
|
2843
3049
|
var init_snapshot = __esm({
|
|
2844
3050
|
"src/mcp/snapshot.ts"() {
|
|
2845
3051
|
"use strict";
|
|
2846
3052
|
init_digest();
|
|
3053
|
+
init_tokens();
|
|
2847
3054
|
toSnapshot = (tools) => {
|
|
2848
3055
|
const snapshot = {};
|
|
2849
3056
|
for (const tool of tools) {
|
|
2850
3057
|
snapshot[tool.name] = {
|
|
2851
3058
|
description: tool.description,
|
|
2852
|
-
inputSchemaHash: jsonDigest(tool.inputSchema)
|
|
3059
|
+
inputSchemaHash: jsonDigest(tool.inputSchema),
|
|
3060
|
+
tokens: estimateTokens(tool)
|
|
2853
3061
|
};
|
|
2854
3062
|
}
|
|
2855
3063
|
return snapshot;
|
|
2856
3064
|
};
|
|
3065
|
+
backfillTokens = (stored, current) => {
|
|
3066
|
+
let changed = false;
|
|
3067
|
+
for (const [name, tool] of Object.entries(stored)) {
|
|
3068
|
+
const estimate = current[name]?.tokens;
|
|
3069
|
+
if (tool.tokens === void 0 && estimate !== void 0) {
|
|
3070
|
+
tool.tokens = estimate;
|
|
3071
|
+
changed = true;
|
|
3072
|
+
}
|
|
3073
|
+
}
|
|
3074
|
+
return changed;
|
|
3075
|
+
};
|
|
2857
3076
|
}
|
|
2858
3077
|
});
|
|
2859
3078
|
|
|
@@ -2867,7 +3086,7 @@ __export(check_exports, {
|
|
|
2867
3086
|
});
|
|
2868
3087
|
import { accessSync as accessSync2, constants as constants2 } from "fs";
|
|
2869
3088
|
import { delimiter, resolve as resolve19 } from "path";
|
|
2870
|
-
var check, report2, driftLines, list2, recommend, summarize, authHint, hasCommand,
|
|
3089
|
+
var check, report2, driftLines, list2, recommend, summarize, authHint, hasCommand, truncate3, fail;
|
|
2871
3090
|
var init_check = __esm({
|
|
2872
3091
|
"src/commands/check.ts"() {
|
|
2873
3092
|
"use strict";
|
|
@@ -2970,6 +3189,7 @@ var init_check = __esm({
|
|
|
2970
3189
|
}
|
|
2971
3190
|
const diff = diffSnapshots(mcpEntry.tools, current);
|
|
2972
3191
|
if (isEmptyDiff(diff)) {
|
|
3192
|
+
if (backfillTokens(mcpEntry.tools, current)) lockChanged = true;
|
|
2973
3193
|
mcpReports.push({ id, status: "ok" });
|
|
2974
3194
|
} else if (options.accept) {
|
|
2975
3195
|
mcpEntry.tools = current;
|
|
@@ -3086,8 +3306,8 @@ var init_check = __esm({
|
|
|
3086
3306
|
for (const d of dc) {
|
|
3087
3307
|
lines.push(
|
|
3088
3308
|
` "${d.name}":
|
|
3089
|
-
before: ${
|
|
3090
|
-
after: ${
|
|
3309
|
+
before: ${truncate3(d.before)}
|
|
3310
|
+
after: ${truncate3(d.after)}`
|
|
3091
3311
|
);
|
|
3092
3312
|
}
|
|
3093
3313
|
}
|
|
@@ -3151,7 +3371,7 @@ var init_check = __esm({
|
|
|
3151
3371
|
}
|
|
3152
3372
|
return false;
|
|
3153
3373
|
};
|
|
3154
|
-
|
|
3374
|
+
truncate3 = (s, max = 120) => s.length > max ? s.slice(0, max) + "\u2026" : s;
|
|
3155
3375
|
fail = async (options, code, message) => {
|
|
3156
3376
|
if (options.json) console.log(JSON.stringify({ ok: false, error: code }));
|
|
3157
3377
|
else await error(message);
|
|
@@ -3661,6 +3881,7 @@ Commands:
|
|
|
3661
3881
|
providers [a,b] Change which tools get configs (claude, opencode, codex)
|
|
3662
3882
|
update [id] Pull newer catalog content into .agents/ (all or one entry)
|
|
3663
3883
|
list Show installed entries (skills, commands, plugins, MCP tool counts)
|
|
3884
|
+
inspect <name> Show an MCP server's tools with descriptions and token cost
|
|
3664
3885
|
check Detect drift: skill digests, provider shims, MCP tool
|
|
3665
3886
|
snapshots (--offline skips MCP re-introspection)
|
|
3666
3887
|
upstream Catalog maintenance: check source repos for skill updates
|
|
@@ -3672,8 +3893,9 @@ Commands:
|
|
|
3672
3893
|
Options:
|
|
3673
3894
|
-f, --force Overwrite existing files
|
|
3674
3895
|
--all, -y Keep everything without prompting (non-interactive)
|
|
3675
|
-
--json Machine-readable output (check/upstream/list)
|
|
3676
|
-
-V, --verbose Show full tool lists and description diffs (check)
|
|
3896
|
+
--json Machine-readable output (check/upstream/list/inspect)
|
|
3897
|
+
-V, --verbose Show full tool lists and description diffs (check);
|
|
3898
|
+
full tool descriptions (inspect)
|
|
3677
3899
|
--accept Record the current MCP tool snapshots as the new baseline (check)
|
|
3678
3900
|
--offline Skip MCP re-introspection; check digests + shims only (check)
|
|
3679
3901
|
--dry-run Report what would change without writing (update)
|
|
@@ -3797,6 +4019,11 @@ var run = async () => {
|
|
|
3797
4019
|
await list3(options);
|
|
3798
4020
|
break;
|
|
3799
4021
|
}
|
|
4022
|
+
case "inspect": {
|
|
4023
|
+
const { inspect: inspect2 } = await Promise.resolve().then(() => (init_inspect(), inspect_exports));
|
|
4024
|
+
await inspect2(options);
|
|
4025
|
+
break;
|
|
4026
|
+
}
|
|
3800
4027
|
case "check": {
|
|
3801
4028
|
const { check: check2 } = await Promise.resolve().then(() => (init_check(), check_exports));
|
|
3802
4029
|
await check2(options);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "quiver-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "Compose selected skills, commands, plugins and MCP servers from a central catalog into any repo as native configs for opencode, Claude Code and Codex - with lockfile-based drift awareness.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -32,6 +32,7 @@ agent-browser skills get slack # Slack workspace automation
|
|
|
32
32
|
agent-browser skills get dogfood # Exploratory testing / QA / bug hunts
|
|
33
33
|
agent-browser skills get derive-client # Record a HAR, derive a standalone API client for a site
|
|
34
34
|
agent-browser skills get vercel-sandbox # agent-browser inside Vercel Sandbox microVMs
|
|
35
|
+
agent-browser skills get protected-vercel-deployments # Access protected Vercel deployments
|
|
35
36
|
agent-browser skills get agentcore # AWS Bedrock AgentCore cloud browsers
|
|
36
37
|
```
|
|
37
38
|
|
|
@@ -20,6 +20,8 @@ SPEC.md keeps track of the app's requirements and design decisions. Keep it up t
|
|
|
20
20
|
|
|
21
21
|
**Migrating from Skybridge `< 0.36.x`?** → Read [migrate-to-v1.md](references/migrate-to-v1.md) first. Users may reference `skybridge >= 0.36.x` as v1.
|
|
22
22
|
|
|
23
|
+
**Building an ecommerce app?** → Read [ecommerce.md](references/ecommerce.md) first.
|
|
24
|
+
|
|
23
25
|
## Setup
|
|
24
26
|
|
|
25
27
|
1. **Copy template** → [copy-template.md](references/copy-template.md): when starting a new project with ready SPEC.md
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: prisma-cli
|
|
3
|
-
description: Prisma ORM CLI commands reference covering init, generate, migrate, db, dev, studio, validate, format, debug, and mcp. Use for ORM/database CLI workflows, not
|
|
3
|
+
description: Prisma ORM CLI commands reference covering init, generate, migrate, db, dev, complete, studio, validate, format, debug, and mcp. Use for ORM/database CLI workflows, not the Prisma Platform CLI. Triggers on "prisma init", "prisma generate", "prisma migrate", "prisma db", "prisma complete", "prisma studio", "prisma mcp".
|
|
4
4
|
license: MIT
|
|
5
5
|
metadata:
|
|
6
6
|
author: prisma
|
|
7
|
-
version: "7.
|
|
7
|
+
version: "7.9.1"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# Prisma CLI Reference
|
|
11
11
|
|
|
12
12
|
Reference for Prisma ORM CLI commands. This skill provides guidance on command usage, options, and best practices for current Prisma ORM releases.
|
|
13
13
|
|
|
14
|
-
## Boundary: Compute
|
|
14
|
+
## Boundary: Platform and Compute
|
|
15
15
|
|
|
16
|
-
Do not
|
|
16
|
+
Do not confuse the stable ORM command (`prisma`) with the public-beta Platform package (`@prisma/cli`, binary `prisma-cli`). Use `prisma-compute` for Compute apps and workspace auth, and `prisma-postgres` for Platform projects and databases.
|
|
17
17
|
|
|
18
18
|
## When to Apply
|
|
19
19
|
|
|
@@ -24,6 +24,7 @@ Reference this skill when:
|
|
|
24
24
|
- Managing database state (`prisma db push/pull`)
|
|
25
25
|
- Using local development database (`prisma dev`)
|
|
26
26
|
- Debugging Prisma issues (`prisma debug`)
|
|
27
|
+
- Generating shell completions (`prisma complete`)
|
|
27
28
|
|
|
28
29
|
## Rule Categories by Priority
|
|
29
30
|
|
|
@@ -34,19 +35,19 @@ Reference this skill when:
|
|
|
34
35
|
| 3 | Development | HIGH | `dev` |
|
|
35
36
|
| 4 | Database | HIGH | `db-` |
|
|
36
37
|
| 5 | Migrations | CRITICAL | `migrate-` |
|
|
37
|
-
| 6 | Utility | MEDIUM | `studio`, `validate`, `format`, `debug`, `mcp` |
|
|
38
|
+
| 6 | Utility | MEDIUM | `complete`, `studio`, `validate`, `format`, `debug`, `mcp` |
|
|
38
39
|
|
|
39
40
|
## Command Categories
|
|
40
41
|
|
|
41
42
|
| Category | Commands | Purpose |
|
|
42
43
|
|----------|----------|---------|
|
|
43
|
-
| Setup | `init` |
|
|
44
|
+
| Setup | `init` | Initialize a Prisma project |
|
|
44
45
|
| Generation | `generate` | Generate Prisma Client |
|
|
45
46
|
| Validation | `validate`, `format` | Schema validation and formatting |
|
|
46
47
|
| Development | `dev` | Local Prisma Postgres for development |
|
|
47
48
|
| Database | `db pull`, `db push`, `db seed`, `db execute` | Direct database operations |
|
|
48
49
|
| Migrations | `migrate dev`, `migrate deploy`, `migrate reset`, `migrate status`, `migrate diff`, `migrate resolve` | Schema migrations |
|
|
49
|
-
| Utility | `studio`, `mcp`, `version`, `debug` |
|
|
50
|
+
| Utility | `complete`, `studio`, `mcp`, `version`, `debug` | Shell, development, and AI tooling |
|
|
50
51
|
|
|
51
52
|
## Quick Reference
|
|
52
53
|
|
|
@@ -66,6 +67,7 @@ prisma init --db
|
|
|
66
67
|
|
|
67
68
|
# Initialize with an example model
|
|
68
69
|
prisma init --with-model
|
|
70
|
+
|
|
69
71
|
```
|
|
70
72
|
|
|
71
73
|
### Client Generation
|
|
@@ -178,8 +180,22 @@ prisma validate
|
|
|
178
180
|
|
|
179
181
|
# Format schema
|
|
180
182
|
prisma format
|
|
183
|
+
|
|
184
|
+
# Generate shell completion code
|
|
185
|
+
prisma complete zsh
|
|
181
186
|
```
|
|
182
187
|
|
|
188
|
+
## AI Safety Checkpoint
|
|
189
|
+
|
|
190
|
+
Prisma blocks destructive commands when it detects an AI agent until the agent has obtained explicit user consent. This covers `migrate reset`, `db push --force-reset`, and `db push --accept-data-loss`.
|
|
191
|
+
|
|
192
|
+
- Explain the exact data-loss impact and ask for consent immediately before running the command.
|
|
193
|
+
- Do not infer consent from earlier or unrelated messages.
|
|
194
|
+
- If automation needs the consent variable, set `PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION` to the user's exact consent message. Do not invent the text.
|
|
195
|
+
- The Prisma MCP server deliberately has no `migrate-reset` tool.
|
|
196
|
+
|
|
197
|
+
Read `references/agent-safety.md` before any destructive Prisma command.
|
|
198
|
+
|
|
183
199
|
## Current Prisma CLI Setup
|
|
184
200
|
|
|
185
201
|
### New Configuration File
|
|
@@ -237,6 +253,8 @@ references/migrate-resolve.md - Migration resolution
|
|
|
237
253
|
references/migrate-diff.md - Schema diffing
|
|
238
254
|
references/studio.md - Database GUI
|
|
239
255
|
references/mcp.md - Prisma MCP server
|
|
256
|
+
references/complete.md - Shell completion generation
|
|
257
|
+
references/agent-safety.md - AI consent checkpoint for destructive commands
|
|
240
258
|
references/validate.md - Schema validation
|
|
241
259
|
references/format.md - Schema formatting
|
|
242
260
|
references/debug.md - Debug info
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# AI safety checkpoint for destructive commands
|
|
2
|
+
|
|
3
|
+
Prisma detects common AI-agent environments and blocks these commands until the user gives explicit consent:
|
|
4
|
+
|
|
5
|
+
- `prisma migrate reset`
|
|
6
|
+
- `prisma db push --force-reset`
|
|
7
|
+
- `prisma db push --accept-data-loss`
|
|
8
|
+
|
|
9
|
+
## Required workflow
|
|
10
|
+
|
|
11
|
+
1. Inspect the target database/config and explain exactly what can be deleted or reset.
|
|
12
|
+
2. Ask the user for explicit consent immediately before the action.
|
|
13
|
+
3. Run the command only after that consent.
|
|
14
|
+
|
|
15
|
+
For an agent-run subprocess, Prisma accepts the exact consent text through:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
PRISMA_USER_CONSENT_FOR_DANGEROUS_AI_ACTION='<exact user consent message>' prisma migrate reset --force
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The value must match the user's message exactly and must not contain added quotes or newlines. Never fabricate consent, reuse an old unrelated approval, or bypass the checkpoint by hiding agent-detection environment variables.
|
|
22
|
+
|
|
23
|
+
The MCP server has no `migrate-reset` tool. Use the shell command only after consent.
|
|
24
|
+
|
|
25
|
+
## Reference
|
|
26
|
+
|
|
27
|
+
- [Prisma ORM 7.9.0 release](https://github.com/prisma/prisma/releases/tag/7.9.0)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# prisma complete
|
|
2
|
+
|
|
3
|
+
Prints a shell completion script.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
prisma complete zsh
|
|
7
|
+
prisma complete bash
|
|
8
|
+
prisma complete fish
|
|
9
|
+
prisma complete powershell
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
For a direct global CLI installation, load the output using the shell's normal startup mechanism. For example, in zsh:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
source <(prisma complete zsh)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Prisma also integrates with supported package-manager completion flows. `npx` and `bunx` do not themselves provide completion; invoke the installed binary or the package manager's supported execution form such as `npm exec` or `bun x`.
|
|
19
|
+
|
|
20
|
+
## Reference
|
|
21
|
+
|
|
22
|
+
- [Prisma ORM 7.9.0 release](https://github.com/prisma/prisma/releases/tag/7.9.0)
|
|
@@ -25,6 +25,8 @@ prisma db push [options]
|
|
|
25
25
|
| `--config` | Custom path to your Prisma config file |
|
|
26
26
|
| `--url` | Override the datasource URL from the Prisma config file |
|
|
27
27
|
|
|
28
|
+
When Prisma detects an AI agent, `--force-reset` and `--accept-data-loss` require explicit user consent. Follow `agent-safety.md`; never infer or fabricate the consent text.
|
|
29
|
+
|
|
28
30
|
### Follow-up Command
|
|
29
31
|
|
|
30
32
|
- Run `prisma generate` explicitly when you need refreshed client output
|
|
@@ -34,6 +34,9 @@ bunx --bun prisma init
|
|
|
34
34
|
| `--output` | Define Prisma Client generator output path to use | - |
|
|
35
35
|
| `--preview-feature` | Define a preview feature to use | - |
|
|
36
36
|
| `--with-model` | Add example model to created schema file | - |
|
|
37
|
+
| `--no-skills` | Skip the best-effort installation of Prisma agent skills | - |
|
|
38
|
+
|
|
39
|
+
`prisma init` attempts to install `prisma/skills` for detected agents. This is best-effort and does not make project initialization fail. Use `--no-skills` in minimal or controlled environments.
|
|
37
40
|
|
|
38
41
|
## Examples
|
|
39
42
|
|
|
@@ -30,7 +30,8 @@ prisma mcp
|
|
|
30
30
|
|
|
31
31
|
- Run this from the project that contains your Prisma schema and `prisma.config.ts`
|
|
32
32
|
- The command is separate from Prisma Studio and does not open a browser UI
|
|
33
|
-
- The MCP server
|
|
33
|
+
- The MCP server exposes `migrate-status`, `migrate-dev`, and Prisma Studio tooling. It does not expose the destructive `migrate-reset` tool; do not claim it is available or try to bypass that safety boundary.
|
|
34
|
+
- For destructive shell commands, follow `agent-safety.md` and obtain explicit user consent.
|
|
34
35
|
|
|
35
36
|
## References
|
|
36
37
|
|
|
@@ -31,7 +31,7 @@ prisma migrate dev [options]
|
|
|
31
31
|
- Run `prisma generate` explicitly when you need refreshed client output
|
|
32
32
|
- Run `prisma db seed` explicitly when you need seed data
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
Run `prisma generate` as an explicit follow-up when you need refreshed generated artifacts. Do not rely on historical CLI help that described generators as part of `migrate dev`.
|
|
35
35
|
|
|
36
36
|
## Examples
|
|
37
37
|
|
|
@@ -17,6 +17,8 @@ prisma migrate reset [options]
|
|
|
17
17
|
|
|
18
18
|
**Warning: All data will be lost.**
|
|
19
19
|
|
|
20
|
+
When Prisma detects an AI agent, this command is blocked until the user gives explicit consent. Follow `agent-safety.md`; `--force` skips the ordinary prompt but does not constitute user consent for an agent.
|
|
21
|
+
|
|
20
22
|
## Options
|
|
21
23
|
|
|
22
24
|
| Option | Description |
|
|
@@ -127,6 +127,19 @@ const prisma = new PrismaClient({
|
|
|
127
127
|
})
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
+
### queryPlanCacheMaxSize
|
|
131
|
+
|
|
132
|
+
Use `queryPlanCacheMaxSize` to limit the in-memory query-plan cache:
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
const prisma = new PrismaClient({
|
|
136
|
+
adapter,
|
|
137
|
+
queryPlanCacheMaxSize: 2_000,
|
|
138
|
+
})
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
The value must be a non-negative integer. Set it to `0` to disable query-plan caching; omit it to use Prisma's default. Treat this as a process-local memory/performance control, not a database prepared-statement setting.
|
|
142
|
+
|
|
130
143
|
## Singleton Pattern
|
|
131
144
|
|
|
132
145
|
Prevent multiple client instances in development:
|
|
@@ -192,3 +192,7 @@ const users = await prisma.$queryRaw<Result[]>`
|
|
|
192
192
|
`
|
|
193
193
|
// createdAt is already a Date object
|
|
194
194
|
```
|
|
195
|
+
|
|
196
|
+
Invalid JavaScript `Date` values passed to raw queries fail validation instead of being silently serialized as `null`. Validate date input at the application boundary; do not rely on `new Date(badValue)` reaching the database.
|
|
197
|
+
|
|
198
|
+
When a driver adapter returns an unmapped database-specific error, Prisma surfaces `P2039` with the adapter's preserved original code/message. If those details are missing, fix the adapter mapping rather than parsing rendered error text.
|