cue-ai 0.9.0 → 0.9.2
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/CHANGELOG.md +40 -0
- package/README.md +82 -33
- package/bin/cue-review-progress +107 -0
- package/bin/cue-review-watch +98 -0
- package/dist/cue.js +7352 -3744
- package/package.json +16 -5
- package/profiles/_types.ts +9 -0
- package/profiles/backend/profile.yaml +2 -0
- package/profiles/blog-writer/profile.yaml +10 -0
- package/profiles/browser/profile.yaml +9 -2
- package/profiles/builder/profile.yaml +3 -6
- package/profiles/career/profile.yaml +13 -2
- package/profiles/claude-api/profile.yaml +1 -1
- package/profiles/commerce/profile.yaml +27 -3
- package/profiles/core/logo.png +0 -0
- package/profiles/core/profile.yaml +62 -2
- package/profiles/dash-merge-test/profile.yaml +109 -0
- package/profiles/designer/profile.yaml +2 -0
- package/profiles/designer-medusa-next/profile.yaml +4 -1
- package/profiles/designer-medusa-vite/profile.yaml +4 -1
- package/profiles/docs-writer/profile.yaml +3 -1
- package/profiles/eu-tender-research/README.md +48 -0
- package/profiles/eu-tender-research/logo.png +0 -0
- package/profiles/eu-tender-research/profile.yaml +108 -0
- package/profiles/finance/logo.png +0 -0
- package/profiles/finance/profile.yaml +46 -0
- package/profiles/frontend/profile.yaml +5 -9
- package/profiles/growth/profile.yaml +2 -3
- package/profiles/gstack/profile.yaml +15 -0
- package/profiles/higgsfield/profile.yaml +3 -0
- package/profiles/hyperframes/logo.png +0 -0
- package/profiles/hyperframes/profile.yaml +59 -0
- package/profiles/improver/profile.yaml +88 -0
- package/profiles/marketing/profile.yaml +0 -3
- package/profiles/medusa-dev/profile.yaml +2 -0
- package/profiles/medusa-next/profile.yaml +2 -3
- package/profiles/medusa-vite/profile.yaml +2 -3
- package/profiles/n8n/logo.png +0 -0
- package/profiles/n8n/profile.yaml +50 -0
- package/profiles/nextjs/profile.yaml +2 -3
- package/profiles/ops/profile.yaml +2 -0
- package/profiles/postizz/profile.yaml +13 -3
- package/profiles/python/profile.yaml +3 -0
- package/profiles/research/profile.yaml +3 -1
- package/profiles/schema.json +10 -0
- package/profiles/secops/profile.yaml +2 -0
- package/profiles/seo/profile.yaml +56 -0
- package/profiles/skill-writer/profile.yaml +8 -0
- package/profiles/ssh/profile.yaml +32 -0
- package/profiles/strapi/logo.png +0 -0
- package/profiles/strapi/profile.yaml +45 -0
- package/profiles/stripe/logo.png +0 -0
- package/profiles/stripe/profile.yaml +1 -0
- package/profiles/supabase/logo.png +0 -0
- package/profiles/supabase/profile.yaml +85 -0
- package/profiles/vercel/logo.png +0 -0
- package/profiles/vercel/profile.yaml +25 -1
- package/profiles/vite/profile.yaml +4 -3
- package/profiles/web-frontend-base/profile.yaml +5 -4
- package/profiles/webshop/profile.yaml +23 -5
- package/profiles/x-growth-bot/profile.yaml +44 -0
- package/resources/icons/generate-icons.py +128 -2
- package/resources/mcps/configs/claude.sanitized.json +42 -0
- package/resources/mcps/configs/codex.sanitized.json +7 -0
- package/resources/skills/skills/career/resume-version-manager/SKILL.md +351 -0
- package/resources/skills/skills/career/salary-negotiation-prep/SKILL.md +378 -0
- package/resources/skills/skills/content/pdf/SKILL.md +2 -0
- package/resources/skills/skills/content/postiz-cards/SKILL.md +48 -0
- package/resources/skills/skills/content/postiz-cards/scripts/analytics.sh +38 -0
- package/resources/skills/skills/content/postiz-cards/scripts/card.sh +42 -0
- package/resources/skills/skills/content/postiz-cards/scripts/lint.py +38 -0
- package/resources/skills/skills/design/headless-gif-demo/SKILL.md +1 -1
- package/resources/skills/skills/design/readme-svg-design/SKILL.md +1 -1
- package/resources/skills/skills/eu-funding/grant-outreach/SKILL.md +70 -0
- package/resources/skills/skills/eu-funding/hu-grant-finder/SKILL.md +114 -0
- package/resources/skills/skills/eu-funding/hu-grant-finder/evals.md +26 -0
- package/resources/skills/skills/eu-funding/ted-tender-search/SKILL.md +80 -0
- package/resources/skills/skills/eu-funding/ted-tender-search/evals.md +26 -0
- package/resources/skills/skills/eu-funding/ted-tender-search/scripts/ted-search.sh +46 -0
- package/resources/skills/skills/event-design/wedding-invitations/SKILL.md +1 -1
- package/resources/skills/skills/github/gx-agents/SKILL.md +96 -0
- package/resources/skills/skills/gstack/design-shotgun/SKILL.md +1 -1
- package/resources/skills/skills/marketing/ab-test-analyzer/SKILL.md +1 -1
- package/resources/skills/skills/marketing/ab-test-setup-and-analysis/SKILL.md +1 -1
- package/resources/skills/skills/marketing/account-structure-review/SKILL.md +1 -1
- package/resources/skills/skills/marketing/ad-copy-variant-generator/SKILL.md +1 -1
- package/resources/skills/skills/marketing/ad-extension-audit/SKILL.md +1 -1
- package/resources/skills/skills/marketing/ad-spend-allocator/SKILL.md +1 -1
- package/resources/skills/skills/marketing/anomaly-detection/SKILL.md +1 -1
- package/resources/skills/skills/marketing/attribution-model-comparison/SKILL.md +1 -1
- package/resources/skills/skills/marketing/audience-overlap-analysis/SKILL.md +7 -1
- package/resources/skills/skills/marketing/bid-strategy-recommendations/SKILL.md +7 -1
- package/resources/skills/skills/marketing/budget-scenario-planner/SKILL.md +6 -1
- package/resources/skills/skills/marketing/campaign-naming-convention-builder/SKILL.md +7 -1
- package/resources/skills/skills/marketing/channel-mix-optimizer/SKILL.md +7 -1
- package/resources/skills/skills/marketing/client-report-narratives/SKILL.md +6 -1
- package/resources/skills/skills/marketing/competitor-creative-analysis/SKILL.md +1 -1
- package/resources/skills/skills/marketing/competitor-teardown/SKILL.md +1 -1
- package/resources/skills/skills/marketing/content-repurposer/SKILL.md +1 -1
- package/resources/skills/skills/marketing/conversion-path-analysis/SKILL.md +1 -1
- package/resources/skills/skills/marketing/cpa-diagnostics/SKILL.md +1 -1
- package/resources/skills/skills/marketing/creative-fatigue-detection/SKILL.md +1 -1
- package/resources/skills/skills/marketing/day-hour-performance-breakdown/SKILL.md +1 -1
- package/resources/skills/skills/marketing/device-performance-split/SKILL.md +1 -1
- package/resources/skills/skills/marketing/e2e-seo-assistant/SKILL.md +1 -1
- package/resources/skills/skills/marketing/email-sequence-writer/SKILL.md +1 -1
- package/resources/skills/skills/marketing/frequency-cap-recommendations/SKILL.md +1 -1
- package/resources/skills/skills/marketing/geo-performance-analysis/SKILL.md +1 -1
- package/resources/skills/skills/marketing/google-ads-audit/SKILL.md +1 -1
- package/resources/skills/skills/marketing/icp-research-assistant/SKILL.md +1 -1
- package/resources/skills/skills/marketing/keyword-cannibalization-check/SKILL.md +1 -1
- package/resources/skills/skills/marketing/landing-page-audit/SKILL.md +1 -1
- package/resources/skills/skills/marketing/landing-page-audit-quick/SKILL.md +1 -1
- package/resources/skills/skills/marketing/linkedin-ads-audit/SKILL.md +1 -1
- package/resources/skills/skills/marketing/meta-ads-audit/SKILL.md +1 -1
- package/resources/skills/skills/marketing/pacing-monitor/SKILL.md +1 -1
- package/resources/skills/skills/marketing/performance-benchmarking/SKILL.md +1 -1
- package/resources/skills/skills/marketing/programmatic-seo-builder/SKILL.md +1 -1
- package/resources/skills/skills/marketing/quality-score-breakdown/SKILL.md +1 -1
- package/resources/skills/skills/marketing/reddit-ads-audit/SKILL.md +1 -1
- package/resources/skills/skills/marketing/retargeting-window-analysis/SKILL.md +1 -1
- package/resources/skills/skills/marketing/roas-forecasting/SKILL.md +1 -1
- package/resources/skills/skills/marketing/search-term-mining/SKILL.md +1 -1
- package/resources/skills/skills/marketing/utm-tracking-generator/SKILL.md +1 -1
- package/resources/skills/skills/marketing/wasted-spend-finder/SKILL.md +1 -1
- package/resources/skills/skills/marketing/weekly-account-summary/SKILL.md +1 -1
- package/resources/skills/skills/meta/awesome-list-submit/SKILL.md +4 -4
- package/resources/skills/skills/meta/cue-dashboard/SKILL.md +109 -0
- package/resources/skills/skills/meta/cue-developer/SKILL.md +161 -0
- package/resources/skills/skills/meta/cue-developer/evals/evals.json +57 -0
- package/resources/skills/skills/meta/cue-developer/references/architecture.md +65 -0
- package/resources/skills/skills/meta/cue-developer/references/build_and_test.md +72 -0
- package/resources/skills/skills/meta/cue-developer/references/contributing.md +75 -0
- package/resources/skills/skills/meta/cue-developer/references/conventions.md +57 -0
- package/resources/skills/skills/meta/cue-developer/references/first_time_setup.md +51 -0
- package/resources/skills/skills/meta/cue-developer/references/skill_and_mcp_authoring.md +84 -0
- package/resources/skills/skills/meta/cue-developer/references/troubleshooting.md +42 -0
- package/resources/skills/skills/meta/delegation-check/SKILL.md +148 -0
- package/resources/skills/skills/meta/delegation-check/specs/scan-algorithm.md +125 -0
- package/resources/skills/skills/meta/delegation-check/specs/separation-rules.md +190 -0
- package/resources/skills/skills/meta/focus/SKILL.md +62 -0
- package/resources/skills/skills/meta/help/SKILL.md +1 -1
- package/resources/skills/skills/meta/integrity-tags/SKILL.md +2 -0
- package/resources/skills/skills/meta/next-steps/SKILL.md +124 -0
- package/resources/skills/skills/meta/next-steps/evals/eval-set.json +92 -0
- package/resources/skills/skills/meta/profile-from-docs/SKILL.md +141 -0
- package/resources/skills/skills/meta/ralph-loop/SKILL.md +83 -0
- package/resources/skills/skills/meta/ralph-loop/scripts/loop.sh +73 -0
- package/resources/skills/skills/meta/skill-simplify/SKILL.md +136 -0
- package/resources/skills/skills/meta/skill-simplify/phases/01-analysis.md +173 -0
- package/resources/skills/skills/meta/skill-simplify/phases/02-optimize.md +104 -0
- package/resources/skills/skills/meta/skill-simplify/phases/03-check.md +145 -0
- package/resources/skills/skills/meta/smart-loader/scripts/smart-lookup.sh +13 -4
- package/resources/skills/skills/meta/verify-council/SKILL.md +182 -0
- package/resources/skills/skills/meta/verify-council/references/lane-prompts.md +103 -0
- package/resources/skills/skills/meta/verify-council/references/workflow.js +217 -0
- package/resources/skills/skills/nvidia/aiq-research/SKILL.md +1 -1
- package/resources/skills/skills/nvidia/cuopt-developer/SKILL.md +16 -1
- package/resources/skills/skills/nvidia/cuopt-developer/resources/contributing.md +2 -2
- package/resources/skills/skills/nvidia/cuopt-developer/resources/numerical_debugging.md +128 -0
- package/resources/skills/skills/nvidia/cuopt-developer/resources/python_bindings.md +2 -9
- package/resources/skills/skills/nvidia/cuopt-developer/resources/vrp_skills.md +166 -0
- package/resources/skills/skills/nvidia/cuopt-install/SKILL.md +2 -10
- package/resources/skills/skills/nvidia/cuopt-numerical-optimization-api-c/SKILL.md +3 -23
- package/resources/skills/skills/nvidia/cuopt-numerical-optimization-api-c/resources/examples.md +40 -20
- package/resources/skills/skills/nvidia/cuopt-numerical-optimization-api-python/SKILL.md +5 -1
- package/resources/skills/skills/nvidia/skill-evolution/SKILL.md +4 -5
- package/resources/skills/skills/research/trendradar/SKILL.md +1 -1
- package/resources/skills/skills/ssh/ssh-config/SKILL.md +94 -0
- package/resources/skills/skills/ssh/ssh-copy/SKILL.md +92 -0
- package/resources/skills/skills/ssh/ssh-harden/SKILL.md +108 -0
- package/resources/skills/skills/ssh/ssh-keys/SKILL.md +82 -0
- package/resources/skills/skills/ssh/ssh-paste-image/LICENSE +28 -0
- package/resources/skills/skills/ssh/ssh-paste-image/SKILL.md +149 -0
- package/resources/skills/skills/ssh/ssh-paste-image/scripts/build.sh +29 -0
- package/resources/skills/skills/ssh/ssh-paste-image/scripts/client/go.mod +3 -0
- package/resources/skills/skills/ssh/ssh-paste-image/scripts/client/main.go +79 -0
- package/resources/skills/skills/ssh/ssh-paste-image/scripts/daemon/ccimgd.service +12 -0
- package/resources/skills/skills/ssh/ssh-paste-image/scripts/daemon/com.ccimgd.plist +20 -0
- package/resources/skills/skills/ssh/ssh-paste-image/scripts/daemon/go.mod +3 -0
- package/resources/skills/skills/ssh/ssh-paste-image/scripts/daemon/main.go +98 -0
- package/resources/skills/skills/ssh/ssh-tunnel/SKILL.md +96 -0
- package/resources/skills/skills/strapi/building-with-strapi/SKILL.md +112 -0
- package/resources/skills/skills/strapi/strapi-cli/SKILL.md +93 -0
- package/resources/skills/skills/strapi/strapi-content-api/SKILL.md +115 -0
- package/resources/skills/skills/strapi/strapi-deploy/SKILL.md +89 -0
- package/resources/skills/skills/strapi/strapi-mcp-setup/SKILL.md +101 -0
- package/resources/skills/skills/strapi/strapi-plugins/SKILL.md +97 -0
- package/resources/skills/skills/tools/context7/SKILL.md +101 -0
- package/resources/skills/skills/tools/opensrc/SKILL.md +1 -1
- package/resources/skills/skills/tools/portless/SKILL.md +186 -0
- package/resources/skills/skills/xbot/operate/SKILL.md +229 -0
- package/src/commands/_index.ts +8 -0
- package/src/commands/ai-score.e2e.test.ts +11 -4
- package/src/commands/ai.ts +3 -4
- package/src/commands/auto-detect.ts +1 -1
- package/src/commands/cli.test.ts +1 -2
- package/src/commands/cli.ts +1 -1
- package/src/commands/cloud.ts +1 -1
- package/src/commands/current.ts +1 -4
- package/src/commands/dash.test.ts +110 -0
- package/src/commands/dash.ts +194 -0
- package/src/commands/dashboard.ts +26 -0
- package/src/commands/diff.ts +1 -1
- package/src/commands/discover.test.ts +1 -1
- package/src/commands/discover.ts +90 -40
- package/src/commands/doctor.test.ts +58 -0
- package/src/commands/doctor.ts +79 -3
- package/src/commands/eval-behavior.ts +1 -1
- package/src/commands/eval.ts +2 -2
- package/src/commands/evolve.ts +4 -3
- package/src/commands/failures.test.ts +1 -1
- package/src/commands/features-batch1.test.ts +6 -1
- package/src/commands/icon.ts +1 -5
- package/src/commands/import-profile.ts +1 -1
- package/src/commands/init.ts +50 -7
- package/src/commands/install-sh.e2e.test.ts +65 -0
- package/src/commands/launch-handoff.e2e.test.ts +88 -0
- package/src/commands/launch.e2e.test.ts +8 -1
- package/src/commands/launch.test.ts +29 -0
- package/src/commands/launch.ts +185 -131
- package/src/commands/lock.ts +0 -1
- package/src/commands/marketplace.ts +0 -4
- package/src/commands/materialize.ts +1 -1
- package/src/commands/mem.ts +341 -0
- package/src/commands/optimizer.ts +0 -3
- package/src/commands/playground.ts +1 -2
- package/src/commands/profile-draft-skill.ts +1 -1
- package/src/commands/replay-whatif.ts +1 -6
- package/src/commands/score.ts +2 -2
- package/src/commands/security.test.ts +88 -0
- package/src/commands/security.ts +74 -28
- package/src/commands/shell.test.ts +65 -4
- package/src/commands/shell.ts +67 -7
- package/src/commands/skills-test.ts +0 -1
- package/src/commands/skills.ts +28 -2
- package/src/commands/sources.ts +1 -2
- package/src/commands/status.ts +2 -6
- package/src/commands/submit-profile.ts +1 -1
- package/src/commands/suggest.ts +35 -10
- package/src/commands/trigger-gaps.test.ts +50 -0
- package/src/commands/trigger-gaps.ts +63 -29
- package/src/commands/update.ts +1 -1
- package/src/commands/validate.ts +16 -4
- package/src/commands/watch-live.ts +1 -1
- package/src/commands/workspace.ts +1 -1
- package/src/index.ts +26 -10
- package/src/lib/active-sessions.ts +1 -1
- package/src/lib/agent-adapters.test.ts +100 -0
- package/src/lib/agent-adapters.ts +2 -2
- package/src/lib/analytics.test.ts +88 -0
- package/src/lib/analytics.ts +82 -1
- package/src/lib/auto-detect.test.ts +10 -4
- package/src/lib/auto-detect.ts +19 -23
- package/src/lib/brand-icons.ts +0 -1
- package/src/lib/cache.ts +2 -3
- package/src/lib/claude-mem-env.test.ts +148 -0
- package/src/lib/claude-mem-env.ts +172 -0
- package/src/lib/combo-history.test.ts +53 -0
- package/src/lib/combo-history.ts +83 -0
- package/src/lib/companion-detect.test.ts +108 -0
- package/src/lib/companion-detect.ts +140 -0
- package/src/lib/companion-fetch.ts +4 -6
- package/src/lib/conditional-skills.test.ts +1 -1
- package/src/lib/config-paths.test.ts +53 -0
- package/src/lib/config-paths.ts +33 -0
- package/src/lib/dashboard-server.test.ts +351 -0
- package/src/lib/dashboard-server.ts +1476 -27
- package/src/lib/debug-log.test.ts +66 -0
- package/src/lib/debug-log.ts +45 -0
- package/src/lib/mcp-catalog.test.ts +102 -0
- package/src/lib/mcp-catalog.ts +193 -0
- package/src/lib/pair-suggestions.test.ts +111 -0
- package/src/lib/pair-suggestions.ts +98 -5
- package/src/lib/permissions.test.ts +76 -0
- package/src/lib/permissions.ts +125 -0
- package/src/lib/picker.test.ts +1106 -1
- package/src/lib/picker.ts +1230 -142
- package/src/lib/plugin-discovery.ts +126 -0
- package/src/lib/pr-poster.ts +1 -1
- package/src/lib/pr-throttle.ts +2 -6
- package/src/lib/profile-linter.test.ts +67 -1
- package/src/lib/profile-linter.ts +59 -14
- package/src/lib/profile-loader.test.ts +21 -0
- package/src/lib/profile-loader.ts +22 -3
- package/src/lib/profile-metrics.ts +2 -6
- package/src/lib/profile-names.test.ts +58 -0
- package/src/lib/repos.test.ts +57 -0
- package/src/lib/repos.ts +167 -0
- package/src/lib/resolver-npx.ts +10 -1
- package/src/lib/runtime-materializer.test.ts +200 -3
- package/src/lib/runtime-materializer.ts +129 -20
- package/src/lib/shared-profiles.ts +2 -3
- package/src/lib/skill-clis.test.ts +113 -0
- package/src/lib/skill-clis.ts +232 -0
- package/src/lib/skill-dependencies.ts +9 -1
- package/src/lib/skill-deps.ts +1 -1
- package/src/lib/skill-linter.ts +1 -1
- package/src/lib/skill-quality.ts +0 -1
- package/src/lib/skill-sandbox.test.ts +1 -1
- package/src/lib/skills-lock.test.ts +1 -1
- package/src/lib/telemetry-consent.ts +3 -5
- package/src/lib/telemetry-report.test.ts +2 -2
- package/src/lib/token-budget.ts +111 -0
- package/src/lib/trigger-gaps.test.ts +70 -0
- package/src/lib/trigger-gaps.ts +48 -6
- package/src/lib/tui/data.ts +1 -5
- package/src/lib/workflow-store.ts +150 -0
- package/src/lib/workspace-secrets.ts +0 -4
- package/src/lib/workspaces.ts +1 -1
package/src/lib/trigger-gaps.ts
CHANGED
|
@@ -45,10 +45,40 @@ export interface ComputeGapsInput {
|
|
|
45
45
|
* triggers (e.g. `"go"`) matching every prompt. Default 4.
|
|
46
46
|
*/
|
|
47
47
|
minTriggerLength?: number;
|
|
48
|
+
/**
|
|
49
|
+
* A bare single-word trigger (e.g. "help", "analyze") that isn't a
|
|
50
|
+
* slash-command only counts as a match when the prompt is at most this many
|
|
51
|
+
* characters — i.e. the word plausibly *is* the request, not a substring of a
|
|
52
|
+
* longer unrelated prompt. Multi-word and slash-command triggers match at any
|
|
53
|
+
* length. Default 80.
|
|
54
|
+
*/
|
|
55
|
+
weakTriggerMaxPromptChars?: number;
|
|
48
56
|
/** Cap on returned rows (sorted by gap DESC). Default 10. */
|
|
49
57
|
limit?: number;
|
|
50
58
|
}
|
|
51
59
|
|
|
60
|
+
const DEFAULT_MIN_TRIGGER_LENGTH = 4;
|
|
61
|
+
const DEFAULT_WEAK_TRIGGER_MAX_PROMPT_CHARS = 80;
|
|
62
|
+
|
|
63
|
+
/** A trigger is "weak" when it's a single bare word (no spaces) and not a
|
|
64
|
+
* slash-command — these are the ones that drown the metric in substring noise
|
|
65
|
+
* ("help" inside "help me", "analyze" inside "reanalyze"). */
|
|
66
|
+
function isWeakTrigger(triggerLower: string): boolean {
|
|
67
|
+
return !/\s/.test(triggerLower) && !triggerLower.startsWith("/");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Compile a trigger into a word-boundary matcher. Plain `String.includes` (the
|
|
72
|
+
* old behavior) matched "analyze" inside "reanalyze" and "help" inside
|
|
73
|
+
* "helpful"; `\b` doesn't work for triggers with leading punctuation
|
|
74
|
+
* ("/caveman") or internal hyphens ("agent-to-agent"), so we anchor on
|
|
75
|
+
* alphanumeric look-arounds instead: the trigger must not abut a word char.
|
|
76
|
+
*/
|
|
77
|
+
function compileTrigger(triggerLower: string): RegExp {
|
|
78
|
+
const escaped = triggerLower.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
79
|
+
return new RegExp(`(?<![a-z0-9_])${escaped}(?![a-z0-9_])`);
|
|
80
|
+
}
|
|
81
|
+
|
|
52
82
|
/**
|
|
53
83
|
* Compute the per-skill gap table. Designed for "user mostly says these
|
|
54
84
|
* things, here's which skills should fire but aren't" — not a high-precision
|
|
@@ -56,22 +86,34 @@ export interface ComputeGapsInput {
|
|
|
56
86
|
* surface real problems when the gap count is large.
|
|
57
87
|
*/
|
|
58
88
|
export function computeTriggerGaps(input: ComputeGapsInput): TriggerGapRow[] {
|
|
59
|
-
const minLen = input.minTriggerLength ??
|
|
89
|
+
const minLen = input.minTriggerLength ?? DEFAULT_MIN_TRIGGER_LENGTH;
|
|
60
90
|
const limit = input.limit ?? 10;
|
|
61
|
-
const
|
|
91
|
+
const weakMaxChars = input.weakTriggerMaxPromptChars ?? DEFAULT_WEAK_TRIGGER_MAX_PROMPT_CHARS;
|
|
92
|
+
// Keep each prompt's length alongside its lowercased text for the weak-trigger
|
|
93
|
+
// proportion check.
|
|
94
|
+
const prompts = input.userPrompts.map((p) => ({ text: p.toLowerCase(), len: p.length }));
|
|
62
95
|
|
|
63
96
|
const rows: TriggerGapRow[] = [];
|
|
64
97
|
for (const skill of input.skills) {
|
|
65
|
-
|
|
98
|
+
// Precompile each trigger's word-boundary matcher once (15k+ prompts × N
|
|
99
|
+
// triggers per skill — compiling per prompt would be wasteful).
|
|
100
|
+
const triggers = (skill.triggers ?? [])
|
|
101
|
+
.filter((t) => t.length >= minLen)
|
|
102
|
+
.map((t) => {
|
|
103
|
+
const lower = t.toLowerCase();
|
|
104
|
+
return { raw: t, re: compileTrigger(lower), weak: isWeakTrigger(lower) };
|
|
105
|
+
});
|
|
66
106
|
if (triggers.length === 0) continue;
|
|
67
107
|
|
|
68
108
|
let matched = 0;
|
|
69
109
|
const samples = new Set<string>();
|
|
70
|
-
for (const prompt of
|
|
110
|
+
for (const prompt of prompts) {
|
|
71
111
|
for (const t of triggers) {
|
|
72
|
-
|
|
112
|
+
// A bare single word only counts when it dominates a short prompt.
|
|
113
|
+
if (t.weak && prompt.len > weakMaxChars) continue;
|
|
114
|
+
if (t.re.test(prompt.text)) {
|
|
73
115
|
matched++;
|
|
74
|
-
if (samples.size < 3) samples.add(t);
|
|
116
|
+
if (samples.size < 3) samples.add(t.raw);
|
|
75
117
|
break;
|
|
76
118
|
}
|
|
77
119
|
}
|
package/src/lib/tui/data.ts
CHANGED
|
@@ -12,6 +12,7 @@ import { existsSync } from "node:fs";
|
|
|
12
12
|
import { readFile } from "node:fs/promises";
|
|
13
13
|
import { dirname, join, resolve } from "node:path";
|
|
14
14
|
import { fileURLToPath } from "node:url";
|
|
15
|
+
import { configDir } from "../config-paths";
|
|
15
16
|
|
|
16
17
|
import { listProfiles, loadProfile } from "../profile-loader";
|
|
17
18
|
import { resolveProfileForCwd } from "../cwd-resolver";
|
|
@@ -43,11 +44,6 @@ function repoRoot(): string {
|
|
|
43
44
|
return resolve(here, "..", "..", "..");
|
|
44
45
|
}
|
|
45
46
|
|
|
46
|
-
function configDir(): string {
|
|
47
|
-
return process.env.XDG_CONFIG_HOME
|
|
48
|
-
? join(process.env.XDG_CONFIG_HOME, "cue")
|
|
49
|
-
: join(homedir(), ".config", "cue");
|
|
50
|
-
}
|
|
51
47
|
|
|
52
48
|
function skillsRoot(): string {
|
|
53
49
|
return join(repoRoot(), "resources", "skills", "skills");
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cue workflow store — the on-disk format + CRUD for visually-authored
|
|
3
|
+
* Claude Code workflows (the n8n-style canvas in cue studio).
|
|
4
|
+
*
|
|
5
|
+
* A workflow is a DAG of cue primitives (skills, commands, subagents, MCP
|
|
6
|
+
* tools) saved as resources/workflows/<name>.json. The shape is deliberately
|
|
7
|
+
* React-Flow-compatible (nodes carry id + position, edges carry source/target
|
|
8
|
+
* + handles) so the studio canvas can load/save with no translation layer.
|
|
9
|
+
*
|
|
10
|
+
* This module is pure storage + validation; execution lives in a separate
|
|
11
|
+
* runtime (M4). Read-only callers (list/load) never throw; writes validate the
|
|
12
|
+
* name and shape and throw WorkflowError on bad input.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
16
|
+
import { join, resolve } from "node:path";
|
|
17
|
+
|
|
18
|
+
const REPO_ROOT = resolve(new URL(import.meta.url).pathname, "..", "..", "..");
|
|
19
|
+
|
|
20
|
+
/** Where workflow JSON lives. Honors the same env override as profiles. */
|
|
21
|
+
export function workflowsDir(): string {
|
|
22
|
+
return process.env.CUE_WORKFLOWS_DIR ?? join(REPO_ROOT, "resources", "workflows");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export type WorkflowNodeKind =
|
|
26
|
+
| "trigger" // entry point (manual / on-message / cron) — no cue ref
|
|
27
|
+
| "skill" // a cue skill, e.g. "meta/analyze"
|
|
28
|
+
| "command" // a slash command, e.g. "goal"
|
|
29
|
+
| "subagent" // a delegatable specialist
|
|
30
|
+
| "mcp" // an MCP tool call, e.g. lightpanda.goto
|
|
31
|
+
| "note"; // a free-text sticky, no execution
|
|
32
|
+
|
|
33
|
+
export interface WorkflowNode {
|
|
34
|
+
/** Unique within the workflow (React Flow node id). */
|
|
35
|
+
id: string;
|
|
36
|
+
kind: WorkflowNodeKind;
|
|
37
|
+
/** The cue primitive this node invokes (skill id / command / subagent / "mcp:tool"). Empty for trigger/note. */
|
|
38
|
+
ref: string;
|
|
39
|
+
/** Display label on the canvas. */
|
|
40
|
+
label: string;
|
|
41
|
+
position: { x: number; y: number };
|
|
42
|
+
/** Per-node params: prompt, args, the chosen MCP tool, etc. */
|
|
43
|
+
config?: Record<string, unknown>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface WorkflowEdge {
|
|
47
|
+
id: string;
|
|
48
|
+
source: string;
|
|
49
|
+
target: string;
|
|
50
|
+
sourceHandle?: string | null;
|
|
51
|
+
targetHandle?: string | null;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface CueWorkflow {
|
|
55
|
+
version: 1;
|
|
56
|
+
/** Slug, equal to the filename stem. */
|
|
57
|
+
name: string;
|
|
58
|
+
title: string;
|
|
59
|
+
description: string;
|
|
60
|
+
nodes: WorkflowNode[];
|
|
61
|
+
edges: WorkflowEdge[];
|
|
62
|
+
createdAt?: string;
|
|
63
|
+
updatedAt?: string;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface WorkflowSummary {
|
|
67
|
+
name: string;
|
|
68
|
+
title: string;
|
|
69
|
+
description: string;
|
|
70
|
+
nodeCount: number;
|
|
71
|
+
edgeCount: number;
|
|
72
|
+
updatedAt: string | null;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export class WorkflowError extends Error {}
|
|
76
|
+
|
|
77
|
+
const NAME_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
78
|
+
|
|
79
|
+
/** Validate a workflow name: slug only, no path traversal. */
|
|
80
|
+
export function assertValidName(name: string): void {
|
|
81
|
+
if (!NAME_RE.test(name) || name.includes("..") || name.length > 64) {
|
|
82
|
+
throw new WorkflowError(`invalid workflow name: ${name}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function readJson<T>(path: string): T | null {
|
|
87
|
+
try {
|
|
88
|
+
return JSON.parse(readFileSync(path, "utf8")) as T;
|
|
89
|
+
} catch {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Every saved workflow, newest-updated first. Never throws. */
|
|
95
|
+
export function listWorkflows(): WorkflowSummary[] {
|
|
96
|
+
const dir = workflowsDir();
|
|
97
|
+
if (!existsSync(dir)) return [];
|
|
98
|
+
const out: WorkflowSummary[] = [];
|
|
99
|
+
for (const f of readdirSync(dir)) {
|
|
100
|
+
if (!f.endsWith(".json")) continue;
|
|
101
|
+
const wf = readJson<CueWorkflow>(join(dir, f));
|
|
102
|
+
if (!wf || typeof wf.name !== "string") continue;
|
|
103
|
+
out.push({
|
|
104
|
+
name: wf.name,
|
|
105
|
+
title: wf.title ?? wf.name,
|
|
106
|
+
description: wf.description ?? "",
|
|
107
|
+
nodeCount: Array.isArray(wf.nodes) ? wf.nodes.length : 0,
|
|
108
|
+
edgeCount: Array.isArray(wf.edges) ? wf.edges.length : 0,
|
|
109
|
+
updatedAt: wf.updatedAt ?? null,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
return out.sort((a, b) => (b.updatedAt ?? "").localeCompare(a.updatedAt ?? ""));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** Load one workflow by name, or null when absent/corrupt. */
|
|
116
|
+
export function loadWorkflow(name: string): CueWorkflow | null {
|
|
117
|
+
assertValidName(name);
|
|
118
|
+
return readJson<CueWorkflow>(join(workflowsDir(), `${name}.json`));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Validate + persist a workflow. `nowIso` is injected (the dashboard server
|
|
123
|
+
* stamps it) so this module stays free of wall-clock calls. Returns the saved
|
|
124
|
+
* doc with timestamps applied.
|
|
125
|
+
*/
|
|
126
|
+
export function saveWorkflow(input: unknown, nowIso: string): CueWorkflow {
|
|
127
|
+
const wf = input as Partial<CueWorkflow>;
|
|
128
|
+
if (!wf || typeof wf !== "object") throw new WorkflowError("workflow must be an object");
|
|
129
|
+
if (typeof wf.name !== "string") throw new WorkflowError("workflow.name is required");
|
|
130
|
+
assertValidName(wf.name);
|
|
131
|
+
if (!Array.isArray(wf.nodes)) throw new WorkflowError("workflow.nodes must be an array");
|
|
132
|
+
if (!Array.isArray(wf.edges)) throw new WorkflowError("workflow.edges must be an array");
|
|
133
|
+
|
|
134
|
+
const dir = workflowsDir();
|
|
135
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
136
|
+
const existing = loadWorkflow(wf.name);
|
|
137
|
+
|
|
138
|
+
const doc: CueWorkflow = {
|
|
139
|
+
version: 1,
|
|
140
|
+
name: wf.name,
|
|
141
|
+
title: wf.title ?? wf.name,
|
|
142
|
+
description: wf.description ?? "",
|
|
143
|
+
nodes: wf.nodes as WorkflowNode[],
|
|
144
|
+
edges: wf.edges as WorkflowEdge[],
|
|
145
|
+
createdAt: existing?.createdAt ?? nowIso,
|
|
146
|
+
updatedAt: nowIso,
|
|
147
|
+
};
|
|
148
|
+
writeFileSync(join(dir, `${wf.name}.json`), JSON.stringify(doc, null, 2) + "\n");
|
|
149
|
+
return doc;
|
|
150
|
+
}
|
|
@@ -25,10 +25,6 @@ function storePath(): string {
|
|
|
25
25
|
return join(secretsDir(), "workspace-secrets.json.age");
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
function plainStorePath(): string {
|
|
29
|
-
return join(secretsDir(), "workspace-secrets.json");
|
|
30
|
-
}
|
|
31
|
-
|
|
32
28
|
function hasAge(): boolean {
|
|
33
29
|
try {
|
|
34
30
|
execSync("which age", { stdio: "pipe" });
|
package/src/lib/workspaces.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* or via `cue workspace <name>`.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { existsSync, readFileSync, writeFileSync, mkdirSync,
|
|
10
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, } from "node:fs";
|
|
11
11
|
import { join, dirname } from "node:path";
|
|
12
12
|
import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
|
|
13
13
|
|