vybekiit 0.7.0 → 0.7.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/dist/bin.js +1697 -562
- package/dist/global-skills/add-ai/SKILL.md +1 -1
- package/dist/global-skills/add-analytics/SKILL.md +1 -1
- package/dist/global-skills/add-blog/SKILL.md +1 -1
- package/dist/global-skills/add-crud/SKILL.md +1 -1
- package/dist/global-skills/add-files/SKILL.md +1 -1
- package/dist/global-skills/add-images/SKILL.md +1 -1
- package/dist/global-skills/add-language/SKILL.md +1 -1
- package/dist/global-skills/add-notifications/SKILL.md +1 -1
- package/dist/global-skills/add-realtime/SKILL.md +1 -1
- package/dist/global-skills/add-route/SKILL.md +1 -1
- package/dist/global-skills/add-search/SKILL.md +1 -1
- package/dist/global-skills/add-signin/SKILL.md +1 -1
- package/dist/global-skills/add-teams/SKILL.md +1 -1
- package/dist/global-skills/add-upload/SKILL.md +1 -1
- package/dist/global-skills/aws-serverless/SKILL.md +44 -44
- package/dist/global-skills/aws-serverless/assets/powertools-handler.py +1 -2
- package/dist/global-skills/aws-serverless/references/api-gateway.md +470 -50
- package/dist/global-skills/aws-serverless/references/architecture.md +186 -47
- package/dist/global-skills/aws-serverless/references/concurrency.md +158 -44
- package/dist/global-skills/aws-serverless/references/deployment.md +1 -1
- package/dist/global-skills/aws-serverless/references/event-sources.md +391 -72
- package/dist/global-skills/aws-serverless/references/lambda.md +428 -69
- package/dist/global-skills/aws-serverless/references/orchestration.md +384 -65
- package/dist/global-skills/aws-serverless/references/production.md +415 -78
- package/dist/global-skills/aws-serverless/references/troubleshooting.md +626 -79
- package/dist/global-skills/back-up-my-code/SKILL.md +1 -1
- package/dist/global-skills/buy-domain/SKILL.md +1 -1
- package/dist/global-skills/check-safety/SKILL.md +1 -1
- package/dist/global-skills/configure-capabilities/SKILL.md +1 -1
- package/dist/global-skills/connect-account/SKILL.md +1 -1
- package/dist/global-skills/connect-account-backend/SKILL.md +1 -1
- package/dist/global-skills/design-my-data/SKILL.md +1 -1
- package/dist/global-skills/doctor/SKILL.md +1 -1
- package/dist/global-skills/feedback/SKILL.md +63 -0
- package/dist/global-skills/go-live/SKILL.md +1 -1
- package/dist/global-skills/harden/SKILL.md +1 -1
- package/dist/global-skills/instrument-feature-flags/references/usage.md +0 -35
- package/dist/global-skills/instrument-product-analytics/SKILL.md +1 -1
- package/dist/global-skills/instrument-product-analytics/references/android.md +0 -36
- package/dist/global-skills/instrument-product-analytics/references/configuration.md +0 -1
- package/dist/global-skills/instrument-product-analytics/references/flutter.md +0 -37
- package/dist/global-skills/instrument-product-analytics/references/posthog-python.md +2 -3
- package/dist/global-skills/instrument-product-analytics/references/usage.md +0 -35
- package/dist/global-skills/manifest.json +2 -1
- package/dist/global-skills/neon/SKILL.md +20 -27
- package/dist/global-skills/neon-ai-gateway/SKILL.md +2 -68
- package/dist/global-skills/neon-functions/SKILL.md +7 -7
- package/dist/global-skills/neon-object-storage/SKILL.md +2 -2
- package/dist/global-skills/neon-postgres/SKILL.md +5 -5
- package/dist/global-skills/neon-postgres-branches/SKILL.md +1 -1
- package/dist/global-skills/onboarding/SKILL.md +1 -1
- package/dist/global-skills/plan-my-idea/SKILL.md +1 -1
- package/dist/global-skills/publish-app/SKILL.md +1 -1
- package/dist/global-skills/publish-extension/SKILL.md +1 -1
- package/dist/global-skills/reset-password/SKILL.md +1 -1
- package/dist/global-skills/save-data/SKILL.md +1 -1
- package/dist/global-skills/setup-email/SKILL.md +1 -1
- package/dist/global-skills/setup-payments/SKILL.md +1 -1
- package/dist/global-skills/setup-sms/SKILL.md +1 -1
- package/dist/global-skills/sign-in-with-email-link/SKILL.md +1 -1
- package/dist/global-skills/sign-in-with-google/SKILL.md +1 -1
- package/dist/global-skills/sign-in-with-phone/SKILL.md +1 -1
- package/dist/global-skills/stripe-best-practices/SKILL.md +6 -11
- package/dist/global-skills/stripe-best-practices/references/billing.md +0 -5
- package/dist/global-skills/stripe-best-practices/references/payments.md +2 -4
- package/dist/global-skills/stripe-best-practices/references/tax.md +8 -78
- package/dist/global-skills/track-errors/SKILL.md +1 -1
- package/dist/global-skills/update-kit/SKILL.md +1 -1
- package/dist/global-skills/wire-auth/SKILL.md +1 -1
- package/dist/global-skills/wire-database/SKILL.md +1 -1
- package/dist/global-skills/wire-email/SKILL.md +1 -1
- package/dist/global-skills/wire-payments/SKILL.md +1 -1
- package/package.json +8 -8
- package/dist/global-skills/email-best-practices/.github/workflows/sync-skills.yml +0 -30
- package/dist/global-skills/email-best-practices/README.md +0 -63
- package/dist/global-skills/email-best-practices/references/accessibility.md +0 -189
- package/dist/global-skills/email-best-practices/references/compliance.md +0 -125
- package/dist/global-skills/email-best-practices/references/deliverability.md +0 -121
- package/dist/global-skills/email-best-practices/references/email-capture.md +0 -129
- package/dist/global-skills/email-best-practices/references/email-types.md +0 -173
- package/dist/global-skills/email-best-practices/references/list-management.md +0 -157
- package/dist/global-skills/email-best-practices/references/marketing-emails.md +0 -115
- package/dist/global-skills/email-best-practices/references/sending-reliability.md +0 -155
- package/dist/global-skills/email-best-practices/references/transactional-email-catalog.md +0 -418
- package/dist/global-skills/email-best-practices/references/transactional-emails.md +0 -92
- package/dist/global-skills/email-best-practices/references/webhooks-events.md +0 -167
- package/dist/global-skills/email-best-practices/tests/README.md +0 -35
- package/dist/global-skills/email-best-practices/tests/scenarios/01-spam-deliverability.md +0 -46
- package/dist/global-skills/email-best-practices/tests/scenarios/02-multi-region-compliance.md +0 -48
- package/dist/global-skills/email-best-practices/tests/scenarios/03-retry-idempotency.md +0 -36
- package/dist/global-skills/email-best-practices/tests/scenarios/04-webhook-bounce-handling.md +0 -52
- package/dist/global-skills/email-best-practices/tests/scenarios/05-new-saas-email-plan.md +0 -51
- package/dist/global-skills/neon-postgres/references/neon-sdk.md +0 -262
package/dist/bin.js
CHANGED
|
@@ -5236,7 +5236,7 @@ var init_esm = __esm({
|
|
|
5236
5236
|
});
|
|
5237
5237
|
|
|
5238
5238
|
// src/bin.ts
|
|
5239
|
-
import
|
|
5239
|
+
import process32 from "process";
|
|
5240
5240
|
|
|
5241
5241
|
// ../packages/core/src/accessGate.ts
|
|
5242
5242
|
import { Data, Effect, Either } from "effect";
|
|
@@ -5688,9 +5688,9 @@ var walkPreferenceLadder = (walk) => Effect2.gen(function* () {
|
|
|
5688
5688
|
});
|
|
5689
5689
|
|
|
5690
5690
|
// src/cliRunner.ts
|
|
5691
|
-
import { readFile as
|
|
5692
|
-
import { dirname as
|
|
5693
|
-
import
|
|
5691
|
+
import { readFile as readFile26 } from "fs/promises";
|
|
5692
|
+
import { dirname as dirname18, join as join55 } from "path";
|
|
5693
|
+
import process31 from "process";
|
|
5694
5694
|
import { fileURLToPath as fileURLToPath9 } from "url";
|
|
5695
5695
|
|
|
5696
5696
|
// src/commands/createSurfaceRegistry.ts
|
|
@@ -5756,6 +5756,7 @@ ${createSurfaceUsage}
|
|
|
5756
5756
|
After your app exists (your AI coding tool drives these):
|
|
5757
5757
|
vybekiit list-pieces \xB7 list-page-recipes \xB7 list-presets
|
|
5758
5758
|
vybekiit add page-recipe <id> [--to=dir] [--dry-run] [--force]
|
|
5759
|
+
vybekiit add report-mode [--to=dir] [--dry-run] [--force]
|
|
5759
5760
|
vybekiit apply-preset <id> [--cwd=dir] \xB7 verify-presets
|
|
5760
5761
|
vybekiit scaffold backend \xB7 backend add-route|add-crud|add-upload|gen-contract
|
|
5761
5762
|
vybekiit env wizard \xB7 sync-agent-layer \xB7 update path via your agent
|
|
@@ -5805,6 +5806,7 @@ Agent / kit:
|
|
|
5805
5806
|
vybekiit list-page-recipes
|
|
5806
5807
|
vybekiit list-presets
|
|
5807
5808
|
vybekiit add page-recipe <id> [--to=dir] [--dry-run] [--force]
|
|
5809
|
+
vybekiit add report-mode [--to=dir] [--dry-run] [--force] (point & fix overlay into an existing app)
|
|
5808
5810
|
vybekiit add (interactive: pick a ready piece)
|
|
5809
5811
|
vybekiit apply-preset <feature> [--provider=supabase|neon|railway|mongodb|firebase|aws] [--cwd=dir] [--dry-run]
|
|
5810
5812
|
vybekiit verify-presets [--fix] [--cwd=dir] [preset...]
|
|
@@ -5813,6 +5815,7 @@ Agent / kit:
|
|
|
5813
5815
|
vybekiit live-work payments [--mode=demo|dogfood|buyer] [--vendor=lemon-squeezy|stripe|paypal] [--cwd=dir] [--no-pin] [--fresh]
|
|
5814
5816
|
vybekiit lint-extension-skill <path> [--kind=buyer-goal|platform-wrapper|agent-skills-global]
|
|
5815
5817
|
vybekiit doc-fallback <tech-id>
|
|
5818
|
+
vybekiit feedback status | feedback submit <draft> [--confirm]
|
|
5816
5819
|
vybekiit dedup [--intent <desc>] [--target <file>] [--scope <dir>] [--index] [--json]
|
|
5817
5820
|
vybekiit add bridge
|
|
5818
5821
|
vybekiit env wizard
|
|
@@ -6288,6 +6291,23 @@ var GOAL_ENTRIES = [
|
|
|
6288
6291
|
phrases: ["send emails", "email my users", "set up email"],
|
|
6289
6292
|
skills: { web: "setup-email", mobile: null, extension: null, spa: null, backend: "wire-email" }
|
|
6290
6293
|
},
|
|
6294
|
+
{
|
|
6295
|
+
id: "feedback",
|
|
6296
|
+
pageRecipeRequired: false,
|
|
6297
|
+
phrases: [
|
|
6298
|
+
"send feedback",
|
|
6299
|
+
"report a kit bug",
|
|
6300
|
+
"suggest a kit improvement",
|
|
6301
|
+
"the kit is confusing"
|
|
6302
|
+
],
|
|
6303
|
+
skills: {
|
|
6304
|
+
web: "feedback",
|
|
6305
|
+
mobile: "feedback",
|
|
6306
|
+
extension: "feedback",
|
|
6307
|
+
spa: "feedback",
|
|
6308
|
+
backend: "feedback"
|
|
6309
|
+
}
|
|
6310
|
+
},
|
|
6291
6311
|
{
|
|
6292
6312
|
id: "doctor",
|
|
6293
6313
|
phrases: ["it's broken", "nothing works", "get an error", "check my app"],
|
|
@@ -7208,6 +7228,88 @@ var renderToneSection = () => {
|
|
|
7208
7228
|
return lines.join("\n");
|
|
7209
7229
|
};
|
|
7210
7230
|
|
|
7231
|
+
// ../packages/agentKit/src/feedback/feedback.ts
|
|
7232
|
+
import { createHash } from "crypto";
|
|
7233
|
+
import { Schema as Schema2 } from "effect";
|
|
7234
|
+
var boundedText = (maximumLength) => Schema2.String.pipe(Schema2.minLength(1), Schema2.maxLength(maximumLength));
|
|
7235
|
+
var FeedbackDiagnosticsSchema = Schema2.Struct({
|
|
7236
|
+
agent: boundedText(100),
|
|
7237
|
+
agentVersion: boundedText(100),
|
|
7238
|
+
kitVersion: boundedText(100),
|
|
7239
|
+
operatingSystem: boundedText(200)
|
|
7240
|
+
});
|
|
7241
|
+
var FeedbackDraftSchema = Schema2.Struct({
|
|
7242
|
+
kind: Schema2.Literal("bug", "idea", "confusing"),
|
|
7243
|
+
buyerMessage: boundedText(4e3),
|
|
7244
|
+
agentSummary: boundedText(2e3),
|
|
7245
|
+
reproductionSteps: Schema2.Array(boundedText(500)).pipe(Schema2.maxItems(10)),
|
|
7246
|
+
template: Schema2.Literal("web", "mobile", "extension", "backend", "spa", "unknown"),
|
|
7247
|
+
trigger: Schema2.Literal("explicit", "automatic-suggestion"),
|
|
7248
|
+
diagnostics: FeedbackDiagnosticsSchema
|
|
7249
|
+
});
|
|
7250
|
+
var decodeFeedbackDraft = Schema2.decodeUnknownSync(FeedbackDraftSchema, {
|
|
7251
|
+
onExcessProperty: "error"
|
|
7252
|
+
});
|
|
7253
|
+
var REDACTION_PATTERNS = [
|
|
7254
|
+
// ghp_abc123... -> [removed]
|
|
7255
|
+
[/\b(?:gh[oprsu]_[A-Za-z0-9_]{20,}|github_pat_[A-Za-z0-9_]{20,})\b/gu, "[removed]"],
|
|
7256
|
+
// sk-proj-abc123... -> [removed]
|
|
7257
|
+
[/\bsk-[A-Za-z0-9_-]{20,}\b/gu, "[removed]"],
|
|
7258
|
+
// AKIAIOSFODNN7EXAMPLE -> [removed]
|
|
7259
|
+
[/\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/gu, "[removed]"],
|
|
7260
|
+
// eyJ...payload.signature -> [removed]
|
|
7261
|
+
[/\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/gu, "[removed]"],
|
|
7262
|
+
// Authorization: Bearer abc -> Authorization: [removed]
|
|
7263
|
+
[/\bAuthorization\s*:\s*(?:Bearer|Basic)\s+[^\s,;]+/giu, "Authorization: [removed]"],
|
|
7264
|
+
// API_KEY=abc -> API_KEY=[removed]
|
|
7265
|
+
[
|
|
7266
|
+
/\b[A-Z0-9_-]*(?:API[_-]?KEY|TOKEN|SECRET|PASSWORD|PRIVATE[_-]?KEY)\s*[:=]\s*[^\s,;]+/giu,
|
|
7267
|
+
"[removed]"
|
|
7268
|
+
],
|
|
7269
|
+
// postgres://buyer:secret@host/db -> [removed]
|
|
7270
|
+
[/\b(?:postgres(?:ql)?|mysql|mongodb(?:\+srv)?|redis):\/\/[^\s,;]+/giu, "[removed]"],
|
|
7271
|
+
// buyer@example.com -> [removed]
|
|
7272
|
+
[/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/giu, "[removed]"],
|
|
7273
|
+
// C:\Users\buyer\project -> [removed]
|
|
7274
|
+
[/[A-Z]:\\(?:[^\\\s]+\\)*[^\\\s,;]+/giu, "[removed]"],
|
|
7275
|
+
// /Users/buyer/project -> [removed]
|
|
7276
|
+
[/(?:\/Users|\/home|\/root|\/private|\/tmp|\/var|\/opt)\/(?:[^/\s]+\/)*[^/\s,;]+/gu, "[removed]"],
|
|
7277
|
+
// buyer-mac.local -> [removed]
|
|
7278
|
+
[/\b[A-Z0-9][A-Z0-9-]*\.local\b/giu, "[removed]"]
|
|
7279
|
+
];
|
|
7280
|
+
var redactText = (text2) => {
|
|
7281
|
+
let safeText = text2;
|
|
7282
|
+
for (const [pattern, replacement] of REDACTION_PATTERNS) {
|
|
7283
|
+
safeText = safeText.replace(pattern, replacement);
|
|
7284
|
+
}
|
|
7285
|
+
return safeText.replaceAll(/\s+/gu, " ").trim();
|
|
7286
|
+
};
|
|
7287
|
+
var redactFeedbackDraft = (draft) => ({
|
|
7288
|
+
...draft,
|
|
7289
|
+
buyerMessage: redactText(draft.buyerMessage),
|
|
7290
|
+
agentSummary: redactText(draft.agentSummary),
|
|
7291
|
+
reproductionSteps: draft.reproductionSteps.map(redactText),
|
|
7292
|
+
diagnostics: {
|
|
7293
|
+
agent: redactText(draft.diagnostics.agent),
|
|
7294
|
+
agentVersion: redactText(draft.diagnostics.agentVersion),
|
|
7295
|
+
kitVersion: redactText(draft.diagnostics.kitVersion),
|
|
7296
|
+
operatingSystem: redactText(draft.diagnostics.operatingSystem)
|
|
7297
|
+
}
|
|
7298
|
+
});
|
|
7299
|
+
var fingerprintFeedbackDraft = (draft) => {
|
|
7300
|
+
const safeDraft = redactFeedbackDraft(draft);
|
|
7301
|
+
const canonicalDraft = JSON.stringify({
|
|
7302
|
+
kind: safeDraft.kind,
|
|
7303
|
+
buyerMessage: safeDraft.buyerMessage,
|
|
7304
|
+
agentSummary: safeDraft.agentSummary,
|
|
7305
|
+
reproductionSteps: safeDraft.reproductionSteps,
|
|
7306
|
+
template: safeDraft.template,
|
|
7307
|
+
trigger: safeDraft.trigger,
|
|
7308
|
+
diagnostics: safeDraft.diagnostics
|
|
7309
|
+
});
|
|
7310
|
+
return createHash("sha256").update(canonicalDraft).digest("hex");
|
|
7311
|
+
};
|
|
7312
|
+
|
|
7211
7313
|
// ../packages/agentKit/src/lint/lintExtensionSkill.ts
|
|
7212
7314
|
var BUYER_GOAL_REQUIRED = [
|
|
7213
7315
|
{ rule: "goal", pattern: /\*\*Goal:\*\*/ },
|
|
@@ -7452,7 +7554,7 @@ var renderBuyerSkillStub = (skillStem, buyerContent, template) => {
|
|
|
7452
7554
|
return [
|
|
7453
7555
|
"---",
|
|
7454
7556
|
`name: ${skillStem}`,
|
|
7455
|
-
`description: ${description}`,
|
|
7557
|
+
`description: ${JSON.stringify(description)}`,
|
|
7456
7558
|
"metadata:",
|
|
7457
7559
|
" vybekiit-generated: buyer-skill-stub",
|
|
7458
7560
|
"---",
|
|
@@ -10549,13 +10651,13 @@ var parseCreateAppArgs = (argumentsToParse) => {
|
|
|
10549
10651
|
return { ok: true, inputs: { surface: selectedSurface, destPath: destinationPath } };
|
|
10550
10652
|
};
|
|
10551
10653
|
var promptCreateSurface = async () => {
|
|
10552
|
-
const { cancel: cancel4, intro: intro2, isCancel:
|
|
10654
|
+
const { cancel: cancel4, intro: intro2, isCancel: isCancel6, outro, select: select3 } = await import("@clack/prompts");
|
|
10553
10655
|
intro2("VybeKiit \u2014 create an app");
|
|
10554
10656
|
const picked = await select3({
|
|
10555
10657
|
message: "What are you building?",
|
|
10556
10658
|
options: CREATE_SURFACE_PROMPT_OPTIONS
|
|
10557
10659
|
});
|
|
10558
|
-
if (
|
|
10660
|
+
if (isCancel6(picked) || typeof picked !== "string" || !isCreateSurface(picked)) {
|
|
10559
10661
|
cancel4("Cancelled.");
|
|
10560
10662
|
return null;
|
|
10561
10663
|
}
|
|
@@ -10925,13 +11027,13 @@ var writeTemplateRequired = (flags) => {
|
|
|
10925
11027
|
return 1;
|
|
10926
11028
|
};
|
|
10927
11029
|
var promptForDropInputs = async (parsed) => {
|
|
10928
|
-
const { confirm:
|
|
11030
|
+
const { confirm: confirm3, intro: intro2, isCancel: isCancel6, select: select3, text: text2, cancel: cancel4 } = await import("@clack/prompts");
|
|
10929
11031
|
intro2("VybeKiit: drop a template");
|
|
10930
11032
|
const picked = await select3({
|
|
10931
11033
|
message: "Which template?",
|
|
10932
11034
|
options: DROP_TEMPLATE_OPTIONS
|
|
10933
11035
|
});
|
|
10934
|
-
if (
|
|
11036
|
+
if (isCancel6(picked) || typeof picked !== "string" || !isTemplateName(picked)) {
|
|
10935
11037
|
cancel4("Cancelled.");
|
|
10936
11038
|
return null;
|
|
10937
11039
|
}
|
|
@@ -10944,17 +11046,17 @@ var promptForDropInputs = async (parsed) => {
|
|
|
10944
11046
|
defaultValue: `./${picked}`,
|
|
10945
11047
|
validate: (value) => typeof value === "string" && value.trim() !== "" ? void 0 : "Path is required"
|
|
10946
11048
|
});
|
|
10947
|
-
if (
|
|
11049
|
+
if (isCancel6(dest) || typeof dest !== "string") {
|
|
10948
11050
|
cancel4("Cancelled.");
|
|
10949
11051
|
return null;
|
|
10950
11052
|
}
|
|
10951
11053
|
destPath = dest;
|
|
10952
11054
|
}
|
|
10953
11055
|
const mode = dropMode(parsed.flags);
|
|
10954
|
-
const confirmed = await
|
|
11056
|
+
const confirmed = await confirm3({
|
|
10955
11057
|
message: `Drop "${picked}" -> ${resolve5(destPath)}${mode === "new" ? "" : ` (${mode})`}?`
|
|
10956
11058
|
});
|
|
10957
|
-
if (
|
|
11059
|
+
if (isCancel6(confirmed) || !confirmed) {
|
|
10958
11060
|
cancel4("Cancelled.");
|
|
10959
11061
|
return null;
|
|
10960
11062
|
}
|
|
@@ -11149,19 +11251,255 @@ var runDrop = async (args) => {
|
|
|
11149
11251
|
}
|
|
11150
11252
|
};
|
|
11151
11253
|
|
|
11254
|
+
// src/commands/feedbackCmd.ts
|
|
11255
|
+
import process7 from "process";
|
|
11256
|
+
import { confirm, isCancel } from "@clack/prompts";
|
|
11257
|
+
import open from "open";
|
|
11258
|
+
|
|
11259
|
+
// src/feedback/feedbackClient.ts
|
|
11260
|
+
import { Schema as Schema3 } from "effect";
|
|
11261
|
+
var DeviceLoginSchema = Schema3.Struct({
|
|
11262
|
+
deviceCode: Schema3.String,
|
|
11263
|
+
userCode: Schema3.String,
|
|
11264
|
+
verificationUri: Schema3.String,
|
|
11265
|
+
expiresIn: Schema3.Number,
|
|
11266
|
+
interval: Schema3.Number
|
|
11267
|
+
});
|
|
11268
|
+
var IntakeSessionStateSchema = Schema3.Union(
|
|
11269
|
+
Schema3.Struct({
|
|
11270
|
+
status: Schema3.Literal("pending"),
|
|
11271
|
+
retryAfter: Schema3.optional(Schema3.Number)
|
|
11272
|
+
}),
|
|
11273
|
+
Schema3.Struct({ status: Schema3.Literal("ready"), session: Schema3.String }),
|
|
11274
|
+
Schema3.Struct({ status: Schema3.Literal("denied"), message: Schema3.String })
|
|
11275
|
+
);
|
|
11276
|
+
var FeedbackReceiptSchema = Schema3.Struct({ reference: Schema3.String });
|
|
11277
|
+
var resolveBaseUrl = (configuredUrl) => {
|
|
11278
|
+
const baseUrl = configuredUrl || process.env.VYBEKIIT_API_URL || "https://vybekiit.com/api";
|
|
11279
|
+
const parsedUrl = new URL(baseUrl);
|
|
11280
|
+
const localDevelopment = parsedUrl.hostname === "localhost" || parsedUrl.hostname === "127.0.0.1";
|
|
11281
|
+
if (parsedUrl.protocol !== "https:" && !localDevelopment) {
|
|
11282
|
+
throw new Error("Feedback intake requires HTTPS.");
|
|
11283
|
+
}
|
|
11284
|
+
return baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
|
|
11285
|
+
};
|
|
11286
|
+
var readJson = async (response, schema) => {
|
|
11287
|
+
if (!response.ok) {
|
|
11288
|
+
throw new Error(`Feedback intake returned ${response.status}.`);
|
|
11289
|
+
}
|
|
11290
|
+
return Schema3.decodeUnknownSync(schema)(await response.json());
|
|
11291
|
+
};
|
|
11292
|
+
var createFeedbackIntakeClient = (options = {}) => {
|
|
11293
|
+
const baseUrl = resolveBaseUrl(options.baseUrl);
|
|
11294
|
+
const fetchRequest = options.fetch || globalThis.fetch;
|
|
11295
|
+
return {
|
|
11296
|
+
createDeviceLogin: async () => {
|
|
11297
|
+
const response = await fetchRequest(`${baseUrl}/feedback/auth/device`, { method: "POST" });
|
|
11298
|
+
return await readJson(response, DeviceLoginSchema);
|
|
11299
|
+
},
|
|
11300
|
+
pollDeviceLogin: async (deviceCode) => {
|
|
11301
|
+
const response = await fetchRequest(`${baseUrl}/feedback/auth/poll`, {
|
|
11302
|
+
method: "POST",
|
|
11303
|
+
headers: { "content-type": "application/json" },
|
|
11304
|
+
body: JSON.stringify({ deviceCode })
|
|
11305
|
+
});
|
|
11306
|
+
return await readJson(response, IntakeSessionStateSchema);
|
|
11307
|
+
},
|
|
11308
|
+
submit: async ({ session, draft }) => {
|
|
11309
|
+
const response = await fetchRequest(`${baseUrl}/feedback/report`, {
|
|
11310
|
+
method: "POST",
|
|
11311
|
+
headers: {
|
|
11312
|
+
authorization: `Bearer ${session}`,
|
|
11313
|
+
"content-type": "application/json"
|
|
11314
|
+
},
|
|
11315
|
+
body: JSON.stringify(redactFeedbackDraft(draft))
|
|
11316
|
+
});
|
|
11317
|
+
return await readJson(response, FeedbackReceiptSchema);
|
|
11318
|
+
}
|
|
11319
|
+
};
|
|
11320
|
+
};
|
|
11321
|
+
|
|
11322
|
+
// src/feedback/feedbackFiles.ts
|
|
11323
|
+
import { chmod, lstat as lstat2, mkdir as mkdir6, readFile as readFile7, realpath, rename, writeFile as writeFile6 } from "fs/promises";
|
|
11324
|
+
import { isAbsolute, join as join14, relative } from "path";
|
|
11325
|
+
var FeedbackFileError = class extends Error {
|
|
11326
|
+
code;
|
|
11327
|
+
constructor(code, message, cause) {
|
|
11328
|
+
super(message, { cause });
|
|
11329
|
+
this.name = "FeedbackFileError";
|
|
11330
|
+
this.code = code;
|
|
11331
|
+
}
|
|
11332
|
+
};
|
|
11333
|
+
var isBeneath = (candidatePath, parentPath) => {
|
|
11334
|
+
const pathFromParent = relative(parentPath, candidatePath);
|
|
11335
|
+
return pathFromParent !== "" && !pathFromParent.startsWith("..") && !isAbsolute(pathFromParent);
|
|
11336
|
+
};
|
|
11337
|
+
var readFeedbackDraft = async (draftPath, projectRoot) => {
|
|
11338
|
+
const draftsDirectory = await realpath(join14(projectRoot, ".vybekiit", "feedback-drafts"));
|
|
11339
|
+
const draftEntry = await lstat2(draftPath).catch(() => void 0);
|
|
11340
|
+
if (!draftEntry?.isFile() || draftEntry.isSymbolicLink()) {
|
|
11341
|
+
throw new FeedbackFileError(
|
|
11342
|
+
"invalid_draft_path",
|
|
11343
|
+
"Choose a feedback draft created in this app."
|
|
11344
|
+
);
|
|
11345
|
+
}
|
|
11346
|
+
const resolvedDraftPath = await realpath(draftPath);
|
|
11347
|
+
if (!isBeneath(resolvedDraftPath, draftsDirectory)) {
|
|
11348
|
+
throw new FeedbackFileError(
|
|
11349
|
+
"invalid_draft_path",
|
|
11350
|
+
"Choose a feedback draft created in this app."
|
|
11351
|
+
);
|
|
11352
|
+
}
|
|
11353
|
+
if (draftEntry.size > 32 * 1024) {
|
|
11354
|
+
throw new FeedbackFileError(
|
|
11355
|
+
"draft_too_large",
|
|
11356
|
+
"This feedback draft is too large to send safely."
|
|
11357
|
+
);
|
|
11358
|
+
}
|
|
11359
|
+
try {
|
|
11360
|
+
return decodeFeedbackDraft(JSON.parse(await readFile7(resolvedDraftPath, "utf8")));
|
|
11361
|
+
} catch (error) {
|
|
11362
|
+
if (error instanceof FeedbackFileError) {
|
|
11363
|
+
throw error;
|
|
11364
|
+
}
|
|
11365
|
+
throw new FeedbackFileError(
|
|
11366
|
+
"invalid_draft",
|
|
11367
|
+
"This feedback draft could not be read safely.",
|
|
11368
|
+
error
|
|
11369
|
+
);
|
|
11370
|
+
}
|
|
11371
|
+
};
|
|
11372
|
+
var recordFeedbackSubmission = async (projectRoot, submission) => {
|
|
11373
|
+
const feedbackDirectory = join14(projectRoot, ".vybekiit");
|
|
11374
|
+
const submissionsPath = join14(feedbackDirectory, "feedback-submissions.json");
|
|
11375
|
+
const temporaryPath = `${submissionsPath}.${process.pid}.tmp`;
|
|
11376
|
+
await mkdir6(feedbackDirectory, { recursive: true, mode: 448 });
|
|
11377
|
+
let submissions = [];
|
|
11378
|
+
try {
|
|
11379
|
+
const storedSubmissions = JSON.parse(await readFile7(submissionsPath, "utf8"));
|
|
11380
|
+
if (Array.isArray(storedSubmissions)) {
|
|
11381
|
+
submissions = storedSubmissions.filter(
|
|
11382
|
+
(entry) => typeof entry === "object" && entry !== null && "fingerprint" in entry && typeof entry.fingerprint === "string" && "reference" in entry && typeof entry.reference === "string" && "submittedAt" in entry && typeof entry.submittedAt === "string"
|
|
11383
|
+
);
|
|
11384
|
+
}
|
|
11385
|
+
} catch {
|
|
11386
|
+
submissions = [];
|
|
11387
|
+
}
|
|
11388
|
+
await writeFile6(temporaryPath, `${JSON.stringify([...submissions, submission], null, 2)}
|
|
11389
|
+
`, {
|
|
11390
|
+
mode: 384
|
|
11391
|
+
});
|
|
11392
|
+
await rename(temporaryPath, submissionsPath);
|
|
11393
|
+
await chmod(submissionsPath, 384);
|
|
11394
|
+
};
|
|
11395
|
+
|
|
11396
|
+
// src/commands/feedbackCmd.ts
|
|
11397
|
+
var defaultDependencies = () => ({
|
|
11398
|
+
projectRoot: process7.cwd(),
|
|
11399
|
+
interactive: isInteractive(),
|
|
11400
|
+
confirm: async () => {
|
|
11401
|
+
const answer = await confirm({ message: "Send this private feedback report to VybeKiit?" });
|
|
11402
|
+
return !isCancel(answer) && answer;
|
|
11403
|
+
},
|
|
11404
|
+
openBrowser: open,
|
|
11405
|
+
sleep: async (milliseconds) => await new Promise((resolve13) => setTimeout(resolve13, milliseconds)),
|
|
11406
|
+
writeOutput: (message) => process7.stdout.write(`${message}
|
|
11407
|
+
`),
|
|
11408
|
+
writeError: (message) => process7.stderr.write(`${message}
|
|
11409
|
+
`),
|
|
11410
|
+
now: () => /* @__PURE__ */ new Date(),
|
|
11411
|
+
client: createFeedbackIntakeClient()
|
|
11412
|
+
});
|
|
11413
|
+
var waitForSession = async (deviceCode, interval, expiresIn, dependencies) => {
|
|
11414
|
+
const expiresAt = dependencies.now().getTime() + expiresIn * 1e3;
|
|
11415
|
+
let pollingInterval = interval;
|
|
11416
|
+
while (dependencies.now().getTime() < expiresAt) {
|
|
11417
|
+
const sessionState = await dependencies.client.pollDeviceLogin(deviceCode);
|
|
11418
|
+
if (sessionState.status !== "pending") {
|
|
11419
|
+
return sessionState;
|
|
11420
|
+
}
|
|
11421
|
+
if (sessionState.retryAfter) {
|
|
11422
|
+
pollingInterval += sessionState.retryAfter;
|
|
11423
|
+
}
|
|
11424
|
+
await dependencies.sleep(pollingInterval * 1e3);
|
|
11425
|
+
}
|
|
11426
|
+
return { status: "denied", message: "The sign-in code expired. Run /feedback again." };
|
|
11427
|
+
};
|
|
11428
|
+
var showFeedbackStatus = (dependencies) => {
|
|
11429
|
+
dependencies.writeOutput(
|
|
11430
|
+
JSON.stringify({ ok: true, drafts: ".vybekiit/feedback-drafts", confirmationRequired: true })
|
|
11431
|
+
);
|
|
11432
|
+
return 0;
|
|
11433
|
+
};
|
|
11434
|
+
var showFeedbackUsage = (dependencies) => {
|
|
11435
|
+
dependencies.writeError("Usage: vybekiit feedback status | feedback submit <draft> [--confirm]");
|
|
11436
|
+
return 1;
|
|
11437
|
+
};
|
|
11438
|
+
var runFeedback = async (args, suppliedDependencies) => {
|
|
11439
|
+
const dependencies = suppliedDependencies || defaultDependencies();
|
|
11440
|
+
const [action, draftPath] = args;
|
|
11441
|
+
if (action === "status") {
|
|
11442
|
+
return showFeedbackStatus(dependencies);
|
|
11443
|
+
}
|
|
11444
|
+
if (action !== "submit" || !draftPath) {
|
|
11445
|
+
return showFeedbackUsage(dependencies);
|
|
11446
|
+
}
|
|
11447
|
+
const confirmed = dependencies.interactive ? await dependencies.confirm() : args.includes("--confirm");
|
|
11448
|
+
if (!confirmed) {
|
|
11449
|
+
if (!dependencies.interactive) {
|
|
11450
|
+
dependencies.writeError(
|
|
11451
|
+
"Add --confirm only after the buyer has approved sending the report."
|
|
11452
|
+
);
|
|
11453
|
+
return 1;
|
|
11454
|
+
}
|
|
11455
|
+
dependencies.writeOutput("Feedback was not sent. Your draft is still saved.");
|
|
11456
|
+
return 0;
|
|
11457
|
+
}
|
|
11458
|
+
try {
|
|
11459
|
+
const draft = await readFeedbackDraft(draftPath, dependencies.projectRoot);
|
|
11460
|
+
const deviceLogin = await dependencies.client.createDeviceLogin();
|
|
11461
|
+
dependencies.writeOutput(
|
|
11462
|
+
`Sign in to send feedback: ${deviceLogin.verificationUri} code ${deviceLogin.userCode}`
|
|
11463
|
+
);
|
|
11464
|
+
await dependencies.openBrowser(deviceLogin.verificationUri);
|
|
11465
|
+
const sessionState = await waitForSession(
|
|
11466
|
+
deviceLogin.deviceCode,
|
|
11467
|
+
deviceLogin.interval,
|
|
11468
|
+
deviceLogin.expiresIn,
|
|
11469
|
+
dependencies
|
|
11470
|
+
);
|
|
11471
|
+
if (sessionState.status !== "ready") {
|
|
11472
|
+
dependencies.writeError(sessionState.message);
|
|
11473
|
+
return 1;
|
|
11474
|
+
}
|
|
11475
|
+
const receipt = await dependencies.client.submit({ session: sessionState.session, draft });
|
|
11476
|
+
await recordFeedbackSubmission(dependencies.projectRoot, {
|
|
11477
|
+
fingerprint: fingerprintFeedbackDraft(draft),
|
|
11478
|
+
reference: receipt.reference,
|
|
11479
|
+
submittedAt: dependencies.now().toISOString()
|
|
11480
|
+
});
|
|
11481
|
+
dependencies.writeOutput(JSON.stringify({ ok: true, reference: receipt.reference }));
|
|
11482
|
+
return 0;
|
|
11483
|
+
} catch (error) {
|
|
11484
|
+
const detail = error instanceof Error ? error.message : "The feedback service is unavailable.";
|
|
11485
|
+
dependencies.writeError(`Feedback was not sent. Your draft is still saved. ${detail}`);
|
|
11486
|
+
return 1;
|
|
11487
|
+
}
|
|
11488
|
+
};
|
|
11489
|
+
|
|
11152
11490
|
// src/commands/init.ts
|
|
11153
|
-
import { join as
|
|
11491
|
+
import { join as join19 } from "path";
|
|
11154
11492
|
|
|
11155
11493
|
// src/commands/initAssets.ts
|
|
11156
11494
|
import { execFile as execFile5 } from "child_process";
|
|
11157
|
-
import { cp as cp4, mkdir as
|
|
11158
|
-
import { dirname as dirname8, join as
|
|
11495
|
+
import { cp as cp4, mkdir as mkdir7, readdir as readdir7, readFile as readFile9, writeFile as writeFile7 } from "fs/promises";
|
|
11496
|
+
import { dirname as dirname8, join as join16 } from "path";
|
|
11159
11497
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
11160
11498
|
import { promisify as promisify5 } from "util";
|
|
11161
11499
|
|
|
11162
11500
|
// src/commands/initTypes.ts
|
|
11163
|
-
import { access as access8, readFile as
|
|
11164
|
-
import { join as
|
|
11501
|
+
import { access as access8, readFile as readFile8 } from "fs/promises";
|
|
11502
|
+
import { join as join15 } from "path";
|
|
11165
11503
|
var pathExists4 = async (path) => {
|
|
11166
11504
|
try {
|
|
11167
11505
|
await access8(path);
|
|
@@ -11172,7 +11510,7 @@ var pathExists4 = async (path) => {
|
|
|
11172
11510
|
};
|
|
11173
11511
|
var readInitPackageJson = async (cwd) => {
|
|
11174
11512
|
try {
|
|
11175
|
-
const raw = await
|
|
11513
|
+
const raw = await readFile8(join15(cwd, "package.json"), "utf8");
|
|
11176
11514
|
return JSON.parse(raw);
|
|
11177
11515
|
} catch {
|
|
11178
11516
|
return null;
|
|
@@ -11183,22 +11521,22 @@ var readInitPackageJson = async (cwd) => {
|
|
|
11183
11521
|
var execFileAsync5 = promisify5(execFile5);
|
|
11184
11522
|
var HERE5 = dirname8(fileURLToPath5(import.meta.url));
|
|
11185
11523
|
var copyClaudeHooks = async (cwd, templateDir) => {
|
|
11186
|
-
const claudeSource =
|
|
11524
|
+
const claudeSource = join16(templateDir, ".claude");
|
|
11187
11525
|
if (!await pathExists4(claudeSource)) {
|
|
11188
11526
|
process.stdout.write(" \u26A0\uFE0F Could not copy .claude hooks (source missing)\n");
|
|
11189
11527
|
return;
|
|
11190
11528
|
}
|
|
11191
|
-
await cp4(claudeSource,
|
|
11529
|
+
await cp4(claudeSource, join16(cwd, ".claude"), { recursive: true, force: true });
|
|
11192
11530
|
process.stdout.write(" \u2705 .claude/settings.json + hooks\n");
|
|
11193
11531
|
};
|
|
11194
11532
|
var copyWorkflows = async (cwd, templateDir, pm) => {
|
|
11195
|
-
const workflowsDir =
|
|
11196
|
-
const workflowsSource =
|
|
11533
|
+
const workflowsDir = join16(cwd, ".github", "workflows");
|
|
11534
|
+
const workflowsSource = join16(templateDir, ".github", "workflows");
|
|
11197
11535
|
if (!await pathExists4(workflowsSource)) {
|
|
11198
11536
|
process.stdout.write(" \u26A0\uFE0F Could not copy workflows (source missing)\n");
|
|
11199
11537
|
return;
|
|
11200
11538
|
}
|
|
11201
|
-
await
|
|
11539
|
+
await mkdir7(workflowsDir, { recursive: true });
|
|
11202
11540
|
await cp4(workflowsSource, workflowsDir, { recursive: true, force: true });
|
|
11203
11541
|
if (pm !== "pnpm") {
|
|
11204
11542
|
await adaptWorkflows(workflowsDir, pm);
|
|
@@ -11206,23 +11544,23 @@ var copyWorkflows = async (cwd, templateDir, pm) => {
|
|
|
11206
11544
|
process.stdout.write(" \u2705 .github/workflows/ (CI pipeline)\n");
|
|
11207
11545
|
};
|
|
11208
11546
|
var copyPrePushHook = async (cwd, templateDir) => {
|
|
11209
|
-
const huskySource =
|
|
11547
|
+
const huskySource = join16(templateDir, ".husky", "pre-push");
|
|
11210
11548
|
if (!await pathExists4(huskySource)) {
|
|
11211
11549
|
process.stdout.write(" \u26A0\uFE0F Could not copy pre-push hook\n");
|
|
11212
11550
|
return;
|
|
11213
11551
|
}
|
|
11214
|
-
const huskyDir =
|
|
11215
|
-
await
|
|
11216
|
-
await cp4(huskySource,
|
|
11552
|
+
const huskyDir = join16(cwd, ".husky");
|
|
11553
|
+
await mkdir7(huskyDir, { recursive: true });
|
|
11554
|
+
await cp4(huskySource, join16(huskyDir, "pre-push"), { force: true });
|
|
11217
11555
|
process.stdout.write(" \u2705 .husky/pre-push\n");
|
|
11218
11556
|
};
|
|
11219
11557
|
var copySecurityFile = async (cwd, templateDir) => {
|
|
11220
|
-
const dest =
|
|
11558
|
+
const dest = join16(cwd, "SECURITY.md");
|
|
11221
11559
|
if (await pathExists4(dest)) {
|
|
11222
11560
|
process.stdout.write(" \u2713 SECURITY.md (already exists)\n");
|
|
11223
11561
|
return;
|
|
11224
11562
|
}
|
|
11225
|
-
const source =
|
|
11563
|
+
const source = join16(templateDir, "SECURITY.md");
|
|
11226
11564
|
if (!await pathExists4(source)) {
|
|
11227
11565
|
process.stdout.write(" \u26A0\uFE0F Could not copy SECURITY.md\n");
|
|
11228
11566
|
return;
|
|
@@ -11231,14 +11569,14 @@ var copySecurityFile = async (cwd, templateDir) => {
|
|
|
11231
11569
|
process.stdout.write(" \u2705 SECURITY.md\n");
|
|
11232
11570
|
};
|
|
11233
11571
|
var createDevScriptsDir = async (cwd) => {
|
|
11234
|
-
const devScriptsDir =
|
|
11235
|
-
const gitkeepPath =
|
|
11236
|
-
await
|
|
11572
|
+
const devScriptsDir = join16(cwd, "dev-scripts");
|
|
11573
|
+
const gitkeepPath = join16(devScriptsDir, ".gitkeep");
|
|
11574
|
+
await mkdir7(devScriptsDir, { recursive: true });
|
|
11237
11575
|
if (await pathExists4(gitkeepPath)) {
|
|
11238
11576
|
process.stdout.write(" \u2713 dev-scripts/ (already exists)\n");
|
|
11239
11577
|
return;
|
|
11240
11578
|
}
|
|
11241
|
-
await
|
|
11579
|
+
await writeFile7(
|
|
11242
11580
|
gitkeepPath,
|
|
11243
11581
|
"# Local-only dev scripts - gitignored, never committed to the repo.\n",
|
|
11244
11582
|
{ flag: "wx" }
|
|
@@ -11247,8 +11585,8 @@ var createDevScriptsDir = async (cwd) => {
|
|
|
11247
11585
|
};
|
|
11248
11586
|
var generatePlatformConfigs = async (cwd) => {
|
|
11249
11587
|
const possiblePaths = [
|
|
11250
|
-
|
|
11251
|
-
|
|
11588
|
+
join16(cwd, ".claude", "platforms", "generate-platform-configs.sh"),
|
|
11589
|
+
join16(
|
|
11252
11590
|
HERE5,
|
|
11253
11591
|
"..",
|
|
11254
11592
|
"..",
|
|
@@ -11276,12 +11614,12 @@ var generatePlatformConfigs = async (cwd) => {
|
|
|
11276
11614
|
return;
|
|
11277
11615
|
}
|
|
11278
11616
|
}
|
|
11279
|
-
const agentsPath =
|
|
11617
|
+
const agentsPath = join16(cwd, "AGENTS.md");
|
|
11280
11618
|
if (await pathExists4(agentsPath)) {
|
|
11281
11619
|
process.stdout.write(" \u2713 AGENTS.md (already exists)\n");
|
|
11282
11620
|
return;
|
|
11283
11621
|
}
|
|
11284
|
-
await
|
|
11622
|
+
await writeFile7(
|
|
11285
11623
|
agentsPath,
|
|
11286
11624
|
"# Agent Instructions\n\nThis project uses VybeKiit conventions.\n\nSee .claude/hooks/ for enforced rules.\n"
|
|
11287
11625
|
);
|
|
@@ -11314,19 +11652,19 @@ var adaptWorkflows = async (dir, pm) => {
|
|
|
11314
11652
|
const workflowFiles = files.filter((file) => file.endsWith(".yml"));
|
|
11315
11653
|
await Promise.all(
|
|
11316
11654
|
workflowFiles.map(async (file) => {
|
|
11317
|
-
const path =
|
|
11318
|
-
let content = await
|
|
11655
|
+
const path = join16(dir, file);
|
|
11656
|
+
let content = await readFile9(path, "utf8");
|
|
11319
11657
|
for (const [from, to] of Object.entries(replacements[pm])) {
|
|
11320
11658
|
content = content.replaceAll(from, to);
|
|
11321
11659
|
}
|
|
11322
|
-
await
|
|
11660
|
+
await writeFile7(path, content);
|
|
11323
11661
|
})
|
|
11324
11662
|
);
|
|
11325
11663
|
};
|
|
11326
11664
|
|
|
11327
11665
|
// src/commands/initDetect.ts
|
|
11328
11666
|
import { existsSync as existsSync4 } from "fs";
|
|
11329
|
-
import { join as
|
|
11667
|
+
import { join as join17 } from "path";
|
|
11330
11668
|
var packageManagerFromManifest = (value) => {
|
|
11331
11669
|
if (value === void 0 || value === "") {
|
|
11332
11670
|
return null;
|
|
@@ -11353,7 +11691,7 @@ var detectPackageManager = async (cwd) => {
|
|
|
11353
11691
|
["package-lock.json", "npm"]
|
|
11354
11692
|
];
|
|
11355
11693
|
const lockfileMatches = checks.map(([file, pm]) => ({
|
|
11356
|
-
found: existsSync4(
|
|
11694
|
+
found: existsSync4(join17(cwd, file)),
|
|
11357
11695
|
pm
|
|
11358
11696
|
}));
|
|
11359
11697
|
const match = lockfileMatches.find((entry) => entry.found);
|
|
@@ -11420,15 +11758,15 @@ var writeInitSuccess = (pm) => {
|
|
|
11420
11758
|
};
|
|
11421
11759
|
|
|
11422
11760
|
// src/commands/initPatches.ts
|
|
11423
|
-
import { readFile as
|
|
11424
|
-
import { join as
|
|
11761
|
+
import { readFile as readFile10, writeFile as writeFile8 } from "fs/promises";
|
|
11762
|
+
import { join as join18 } from "path";
|
|
11425
11763
|
var patchGitignore = async (cwd) => {
|
|
11426
|
-
const gitignorePath =
|
|
11427
|
-
const content = await pathExists4(gitignorePath) ? await
|
|
11764
|
+
const gitignorePath = join18(cwd, ".gitignore");
|
|
11765
|
+
const content = await pathExists4(gitignorePath) ? await readFile10(gitignorePath, "utf8") : "";
|
|
11428
11766
|
const needed = ["dev-scripts/", ".env", ".env.*", "!.env.example"];
|
|
11429
11767
|
const additions = needed.filter((pattern) => !content.includes(pattern));
|
|
11430
11768
|
if (additions.length > 0) {
|
|
11431
|
-
await
|
|
11769
|
+
await writeFile8(gitignorePath, `${content}
|
|
11432
11770
|
# VybeKiit guardrails
|
|
11433
11771
|
${additions.join("\n")}
|
|
11434
11772
|
`);
|
|
@@ -11438,7 +11776,7 @@ ${additions.join("\n")}
|
|
|
11438
11776
|
process.stdout.write(" \u2713 .gitignore (already has required entries)\n");
|
|
11439
11777
|
};
|
|
11440
11778
|
var patchPackageScripts = async (cwd, pm) => {
|
|
11441
|
-
const pkgPath =
|
|
11779
|
+
const pkgPath = join18(cwd, "package.json");
|
|
11442
11780
|
const pkg = await readInitPackageJson(cwd);
|
|
11443
11781
|
if (pkg === null) {
|
|
11444
11782
|
process.stdout.write(" \u26A0\uFE0F package.json scripts skipped (package.json missing)\n");
|
|
@@ -11452,7 +11790,7 @@ var patchPackageScripts = async (cwd, pm) => {
|
|
|
11452
11790
|
...scripts.verify === void 0 ? { verify: `${pm} run check:ci && ${pm} run typecheck && ${pm} run test` } : {}
|
|
11453
11791
|
};
|
|
11454
11792
|
if (Object.keys(patchedScripts).length !== Object.keys(scripts).length) {
|
|
11455
|
-
await
|
|
11793
|
+
await writeFile8(pkgPath, `${JSON.stringify({ ...pkg, scripts: patchedScripts }, null, 2)}
|
|
11456
11794
|
`);
|
|
11457
11795
|
process.stdout.write(" \u2705 package.json scripts patched (check:ci, typecheck, verify)\n");
|
|
11458
11796
|
return;
|
|
@@ -11463,7 +11801,7 @@ var patchPackageScripts = async (cwd, pm) => {
|
|
|
11463
11801
|
// src/commands/init.ts
|
|
11464
11802
|
var runInit = async (args) => {
|
|
11465
11803
|
const [targetPath] = args;
|
|
11466
|
-
const cwd = targetPath !== void 0 && targetPath !== "" ?
|
|
11804
|
+
const cwd = targetPath !== void 0 && targetPath !== "" ? join19(process.cwd(), targetPath) : process.cwd();
|
|
11467
11805
|
process.stdout.write("\u{1F512} VybeKiit init: bootstrapping security guardrails...\n");
|
|
11468
11806
|
process.stdout.write("\n");
|
|
11469
11807
|
const pm = await detectPackageManager(cwd);
|
|
@@ -11482,7 +11820,7 @@ var runInit = async (args) => {
|
|
|
11482
11820
|
try {
|
|
11483
11821
|
const { cleanup: resolvedCleanup, source } = await resolveTemplatesSource(projectType);
|
|
11484
11822
|
cleanup = resolvedCleanup;
|
|
11485
|
-
const templateDir =
|
|
11823
|
+
const templateDir = join19(source, projectType);
|
|
11486
11824
|
await copyClaudeHooks(cwd, templateDir);
|
|
11487
11825
|
await copyWorkflows(cwd, templateDir, pm);
|
|
11488
11826
|
await copyPrePushHook(cwd, templateDir);
|
|
@@ -11504,7 +11842,7 @@ var runInit = async (args) => {
|
|
|
11504
11842
|
};
|
|
11505
11843
|
|
|
11506
11844
|
// src/commands/lintExtensionSkill.ts
|
|
11507
|
-
import { readFile as
|
|
11845
|
+
import { readFile as readFile11 } from "fs/promises";
|
|
11508
11846
|
var resolveExtensionSkillKind = (path, explicit) => {
|
|
11509
11847
|
if (explicit === "buyer-goal" || explicit === "platform-wrapper" || explicit === "agent-skills-global") {
|
|
11510
11848
|
return explicit;
|
|
@@ -11549,7 +11887,7 @@ var runLintExtensionSkill = async (args) => {
|
|
|
11549
11887
|
}
|
|
11550
11888
|
let content;
|
|
11551
11889
|
try {
|
|
11552
|
-
content = await
|
|
11890
|
+
content = await readFile11(path, "utf8");
|
|
11553
11891
|
} catch {
|
|
11554
11892
|
return {
|
|
11555
11893
|
json: JSON.stringify({ ok: false, error: `Cannot read file: ${path}` }),
|
|
@@ -11565,7 +11903,7 @@ var runLintExtensionSkill = async (args) => {
|
|
|
11565
11903
|
|
|
11566
11904
|
// src/commands/liveWorkDataCmd.ts
|
|
11567
11905
|
import { resolve as resolve7 } from "path";
|
|
11568
|
-
import
|
|
11906
|
+
import process8 from "process";
|
|
11569
11907
|
|
|
11570
11908
|
// ../packages/db/src/types.ts
|
|
11571
11909
|
import { Data as Data3 } from "effect";
|
|
@@ -14548,9 +14886,9 @@ import { Effect as Effect12, Either as Either2 } from "effect";
|
|
|
14548
14886
|
|
|
14549
14887
|
// ../packages/core/src/node.ts
|
|
14550
14888
|
import { existsSync as existsSync5, readFileSync as readFileSync3 } from "fs";
|
|
14551
|
-
import { join as
|
|
14889
|
+
import { join as join20 } from "path";
|
|
14552
14890
|
var loadEnvFile = (cwd, filename = ".env") => {
|
|
14553
|
-
const path =
|
|
14891
|
+
const path = join20(cwd, filename);
|
|
14554
14892
|
if (!existsSync5(path)) {
|
|
14555
14893
|
return {};
|
|
14556
14894
|
}
|
|
@@ -14575,7 +14913,7 @@ var mergeEnvFile = (processEnv, fileEnv) => ({ ...processEnv, ...fileEnv });
|
|
|
14575
14913
|
|
|
14576
14914
|
// src/doctor/writeEnvKeys.ts
|
|
14577
14915
|
import { existsSync as existsSync6, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
|
|
14578
|
-
import { join as
|
|
14916
|
+
import { join as join21 } from "path";
|
|
14579
14917
|
var TRAILING_NEWLINES_PATTERN = /\n*$/;
|
|
14580
14918
|
var renderEnvValue = (value) => {
|
|
14581
14919
|
if (value.includes(" ")) {
|
|
@@ -14592,7 +14930,7 @@ var replaceEnvLine = (lines, key, newLine) => {
|
|
|
14592
14930
|
return true;
|
|
14593
14931
|
};
|
|
14594
14932
|
var writeEnvKeys = (cwd, keys) => {
|
|
14595
|
-
const path =
|
|
14933
|
+
const path = join21(cwd, ".env");
|
|
14596
14934
|
const existing = existsSync6(path) ? readFileSync4(path, "utf8") : "";
|
|
14597
14935
|
const lines = existing.length > 0 ? existing.split("\n") : [];
|
|
14598
14936
|
for (const [key, value] of Object.entries(keys)) {
|
|
@@ -14623,7 +14961,7 @@ var parseLiveWorkDataFlags = (args) => {
|
|
|
14623
14961
|
const modeRaw = readFlagValue(args, "mode") ?? "demo";
|
|
14624
14962
|
const vendorRaw = readFlagValue(args, "vendor");
|
|
14625
14963
|
const cwdRaw = readFlagValue(args, "cwd");
|
|
14626
|
-
const cwd = resolve7(
|
|
14964
|
+
const cwd = resolve7(process8.cwd(), cwdRaw === void 0 || cwdRaw === "" ? "." : cwdRaw);
|
|
14627
14965
|
if (!isLiveWorkMode(modeRaw)) {
|
|
14628
14966
|
return {
|
|
14629
14967
|
mode: "demo",
|
|
@@ -14686,7 +15024,7 @@ var toFailurePayload = (error) => {
|
|
|
14686
15024
|
}
|
|
14687
15025
|
return failure;
|
|
14688
15026
|
};
|
|
14689
|
-
var resolveLiveWorkEnv = (cwd) => mergeEnv(
|
|
15027
|
+
var resolveLiveWorkEnv = (cwd) => mergeEnv(process8.env, loadEnvFile2(cwd));
|
|
14690
15028
|
var writeDataPin = (cwd, keys) => Effect12.try({
|
|
14691
15029
|
try: () => {
|
|
14692
15030
|
writeEnvKeys2(cwd, keys);
|
|
@@ -14742,7 +15080,7 @@ var runLiveWorkData = async (args) => {
|
|
|
14742
15080
|
|
|
14743
15081
|
// src/commands/liveWorkHostCmd.ts
|
|
14744
15082
|
import { resolve as resolve8 } from "path";
|
|
14745
|
-
import
|
|
15083
|
+
import process9 from "process";
|
|
14746
15084
|
|
|
14747
15085
|
// ../packages/deploy/src/deployEffect.ts
|
|
14748
15086
|
import { Effect as Effect13 } from "effect";
|
|
@@ -14759,7 +15097,7 @@ var failDeploy = (code, message) => Effect13.fail(deployError(code, message));
|
|
|
14759
15097
|
// ../packages/deploy/src/liveWork/cloudflareProvision.ts
|
|
14760
15098
|
import { mkdirSync as mkdirSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
14761
15099
|
import { tmpdir as tmpdir3 } from "os";
|
|
14762
|
-
import { join as
|
|
15100
|
+
import { join as join22 } from "path";
|
|
14763
15101
|
import { Effect as Effect14 } from "effect";
|
|
14764
15102
|
|
|
14765
15103
|
// ../packages/deploy/src/liveWork/types.ts
|
|
@@ -14817,10 +15155,10 @@ var defaultLiveWorkProjectName = (prefix = "vybekiit-lw") => {
|
|
|
14817
15155
|
return `${prefix}-${stamp}`.toLowerCase().replaceAll(/[^a-z0-9-]/g, "-").slice(0, 58);
|
|
14818
15156
|
};
|
|
14819
15157
|
var writeDemoStaticSite = (parentDir) => {
|
|
14820
|
-
const buildDir =
|
|
15158
|
+
const buildDir = join22(parentDir, "site");
|
|
14821
15159
|
mkdirSync2(buildDir, { recursive: true });
|
|
14822
15160
|
writeFileSync3(
|
|
14823
|
-
|
|
15161
|
+
join22(buildDir, "index.html"),
|
|
14824
15162
|
`<!doctype html><html lang="en"><head><meta charset="utf-8"/><title>VybeKiit Live work</title></head><body><main data-vybekiit-live-work="1"><h1>Live work host OK</h1></main></body></html>
|
|
14825
15163
|
`,
|
|
14826
15164
|
"utf8"
|
|
@@ -14897,7 +15235,7 @@ var createCloudflarePagesHost = (options) => Effect14.gen(function* () {
|
|
|
14897
15235
|
})
|
|
14898
15236
|
);
|
|
14899
15237
|
}
|
|
14900
|
-
const parent = options.cwd ??
|
|
15238
|
+
const parent = options.cwd ?? join22(tmpdir3(), defaultLiveWorkProjectName("vybekiit-lw-site"));
|
|
14901
15239
|
mkdirSync2(parent, { recursive: true });
|
|
14902
15240
|
buildDir = writeDemoStaticSite(parent);
|
|
14903
15241
|
}
|
|
@@ -14998,7 +15336,7 @@ var mapCloudflareCause = (cause) => {
|
|
|
14998
15336
|
// ../packages/deploy/src/liveWork/githubPagesProvision.ts
|
|
14999
15337
|
import { mkdirSync as mkdirSync3, readFileSync as readFileSync5 } from "fs";
|
|
15000
15338
|
import { tmpdir as tmpdir4 } from "os";
|
|
15001
|
-
import { join as
|
|
15339
|
+
import { join as join23 } from "path";
|
|
15002
15340
|
import { Effect as Effect15 } from "effect";
|
|
15003
15341
|
var readGithubToken = (env) => {
|
|
15004
15342
|
for (const key of ["GITHUB_TOKEN", "GH_TOKEN"]) {
|
|
@@ -15126,7 +15464,7 @@ var createGithubPagesHost = (options) => Effect15.gen(function* () {
|
|
|
15126
15464
|
);
|
|
15127
15465
|
}
|
|
15128
15466
|
if (options.createPages === void 0) {
|
|
15129
|
-
const parent = options.cwd ??
|
|
15467
|
+
const parent = options.cwd ?? join23(tmpdir4(), defaultLiveWorkProjectName("vybekiit-lw-gp-site"));
|
|
15130
15468
|
mkdirSync3(parent, { recursive: true });
|
|
15131
15469
|
buildDir = writeDemoStaticSite(parent);
|
|
15132
15470
|
}
|
|
@@ -15183,7 +15521,7 @@ var createGithubPagesHost = (options) => Effect15.gen(function* () {
|
|
|
15183
15521
|
if (!createRepo.ok) {
|
|
15184
15522
|
throw mapGithubHttp(createRepo.status, createText, "github_pages_repo_create_failed");
|
|
15185
15523
|
}
|
|
15186
|
-
const indexPath =
|
|
15524
|
+
const indexPath = join23(buildDir, "index.html");
|
|
15187
15525
|
let indexHtml;
|
|
15188
15526
|
try {
|
|
15189
15527
|
indexHtml = readFileSync5(indexPath, "utf8");
|
|
@@ -15331,10 +15669,10 @@ var isHostLadderProvider = (value) => isLadderProvider(HOST_PREFERENCE_LADDER, v
|
|
|
15331
15669
|
var resolveHostLadderOrder = (env, namedVendor) => resolveLadderOrder(HOST_PREFERENCE_LADDER, env.HOSTING_PROVIDER, namedVendor);
|
|
15332
15670
|
|
|
15333
15671
|
// ../packages/deploy/src/liveWork/netlifyProvision.ts
|
|
15334
|
-
import { createHash } from "crypto";
|
|
15672
|
+
import { createHash as createHash2 } from "crypto";
|
|
15335
15673
|
import { mkdirSync as mkdirSync4, readdirSync, readFileSync as readFileSync6, statSync } from "fs";
|
|
15336
15674
|
import { tmpdir as tmpdir5 } from "os";
|
|
15337
|
-
import { join as
|
|
15675
|
+
import { join as join24, relative as relative2 } from "path";
|
|
15338
15676
|
import { Effect as Effect16 } from "effect";
|
|
15339
15677
|
var readNetlifyAuthToken = (env) => {
|
|
15340
15678
|
const value = env.NETLIFY_AUTH_TOKEN;
|
|
@@ -15355,7 +15693,7 @@ var collectStaticFiles = (buildDir) => {
|
|
|
15355
15693
|
const out = /* @__PURE__ */ new Map();
|
|
15356
15694
|
const walk = (dir) => {
|
|
15357
15695
|
for (const entry of readdirSync(dir)) {
|
|
15358
|
-
const full =
|
|
15696
|
+
const full = join24(dir, entry);
|
|
15359
15697
|
const st = statSync(full);
|
|
15360
15698
|
if (st.isDirectory()) {
|
|
15361
15699
|
walk(full);
|
|
@@ -15364,7 +15702,7 @@ var collectStaticFiles = (buildDir) => {
|
|
|
15364
15702
|
if (!st.isFile()) {
|
|
15365
15703
|
continue;
|
|
15366
15704
|
}
|
|
15367
|
-
const rel =
|
|
15705
|
+
const rel = relative2(buildDir, full).split("\\").join("/");
|
|
15368
15706
|
const webPath = rel.startsWith("/") ? rel : `/${rel}`;
|
|
15369
15707
|
out.set(webPath, readFileSync6(full));
|
|
15370
15708
|
}
|
|
@@ -15372,7 +15710,7 @@ var collectStaticFiles = (buildDir) => {
|
|
|
15372
15710
|
walk(buildDir);
|
|
15373
15711
|
return out;
|
|
15374
15712
|
};
|
|
15375
|
-
var sha1Hex = (bytes) =>
|
|
15713
|
+
var sha1Hex = (bytes) => createHash2("sha1").update(bytes).digest("hex");
|
|
15376
15714
|
var typedNetlifyError = (code, hopClass, message) => Object.assign(new Error(message), { hopClass, code });
|
|
15377
15715
|
var mapNetlifyHttp = (status, body, code) => {
|
|
15378
15716
|
const lower = body.toLowerCase();
|
|
@@ -15437,7 +15775,7 @@ var createNetlifyHost = (options) => Effect16.gen(function* () {
|
|
|
15437
15775
|
);
|
|
15438
15776
|
}
|
|
15439
15777
|
if (options.createSite === void 0) {
|
|
15440
|
-
const parent = options.cwd ??
|
|
15778
|
+
const parent = options.cwd ?? join24(tmpdir5(), defaultLiveWorkProjectName("vybekiit-lw-nl-site"));
|
|
15441
15779
|
mkdirSync4(parent, { recursive: true });
|
|
15442
15780
|
buildDir = writeDemoStaticSite(parent);
|
|
15443
15781
|
}
|
|
@@ -15692,7 +16030,7 @@ var buyerHostSuccessMessage = (provider, hopped, fromProvider) => {
|
|
|
15692
16030
|
// ../packages/deploy/src/liveWork/railwayHostProvision.ts
|
|
15693
16031
|
import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync4 } from "fs";
|
|
15694
16032
|
import { tmpdir as tmpdir6 } from "os";
|
|
15695
|
-
import { join as
|
|
16033
|
+
import { join as join25 } from "path";
|
|
15696
16034
|
import { Effect as Effect17 } from "effect";
|
|
15697
16035
|
var defaultRailwayHostCliRunner = async (args, options = {}) => {
|
|
15698
16036
|
const { execFile: execFile8 } = await import("child_process");
|
|
@@ -15755,11 +16093,11 @@ var createRailwayHost = (options) => Effect17.gen(function* () {
|
|
|
15755
16093
|
})
|
|
15756
16094
|
);
|
|
15757
16095
|
}
|
|
15758
|
-
workDir = workDir ??
|
|
16096
|
+
workDir = workDir ?? join25(tmpdir6(), defaultLiveWorkProjectName("vybekiit-lw-r-site"));
|
|
15759
16097
|
mkdirSync5(workDir, { recursive: true });
|
|
15760
16098
|
buildDir = writeDemoStaticSite(workDir);
|
|
15761
16099
|
writeFileSync4(
|
|
15762
|
-
|
|
16100
|
+
join25(workDir, "package.json"),
|
|
15763
16101
|
JSON.stringify({
|
|
15764
16102
|
name: projectName,
|
|
15765
16103
|
private: true,
|
|
@@ -15861,7 +16199,7 @@ var mapRailwayHostCause = (cause) => {
|
|
|
15861
16199
|
// ../packages/deploy/src/liveWork/renderProvision.ts
|
|
15862
16200
|
import { mkdirSync as mkdirSync6 } from "fs";
|
|
15863
16201
|
import { tmpdir as tmpdir7 } from "os";
|
|
15864
|
-
import { join as
|
|
16202
|
+
import { join as join26 } from "path";
|
|
15865
16203
|
import { Effect as Effect18 } from "effect";
|
|
15866
16204
|
var readRenderApiKey = (env) => {
|
|
15867
16205
|
const value = env.RENDER_API_KEY;
|
|
@@ -15944,7 +16282,7 @@ var createRenderHost = (options) => Effect18.gen(function* () {
|
|
|
15944
16282
|
);
|
|
15945
16283
|
}
|
|
15946
16284
|
if (options.mode !== "buyer" && (options.buildDir === void 0 || options.buildDir.length === 0)) {
|
|
15947
|
-
const parent = options.cwd ??
|
|
16285
|
+
const parent = options.cwd ?? join26(tmpdir7(), defaultLiveWorkProjectName("vybekiit-lw-rd-site"));
|
|
15948
16286
|
mkdirSync6(parent, { recursive: true });
|
|
15949
16287
|
writeDemoStaticSite(parent);
|
|
15950
16288
|
}
|
|
@@ -16073,7 +16411,7 @@ import { Effect as Effect20 } from "effect";
|
|
|
16073
16411
|
// ../packages/deploy/src/liveWork/vercelProvision.ts
|
|
16074
16412
|
import { mkdirSync as mkdirSync7 } from "fs";
|
|
16075
16413
|
import { tmpdir as tmpdir8 } from "os";
|
|
16076
|
-
import { join as
|
|
16414
|
+
import { join as join27 } from "path";
|
|
16077
16415
|
import { Effect as Effect19 } from "effect";
|
|
16078
16416
|
var defaultVercelCliRunner = async (args, options = {}) => {
|
|
16079
16417
|
const { execFile: execFile8 } = await import("child_process");
|
|
@@ -16134,7 +16472,7 @@ var createVercelHost = (options) => Effect19.gen(function* () {
|
|
|
16134
16472
|
})
|
|
16135
16473
|
);
|
|
16136
16474
|
}
|
|
16137
|
-
const parent = options.cwd ??
|
|
16475
|
+
const parent = options.cwd ?? join27(tmpdir8(), defaultLiveWorkProjectName("vybekiit-lw-v-site"));
|
|
16138
16476
|
mkdirSync7(parent, { recursive: true });
|
|
16139
16477
|
buildDir = writeDemoStaticSite(parent);
|
|
16140
16478
|
}
|
|
@@ -16521,7 +16859,7 @@ var parseLiveWorkHostFlags = (args) => {
|
|
|
16521
16859
|
const cwdRaw = readFlagValue(args, "cwd");
|
|
16522
16860
|
const buildDirRaw = readFlagValue(args, "build-dir");
|
|
16523
16861
|
const projectNameRaw = readFlagValue(args, "project-name");
|
|
16524
|
-
const cwd = resolve8(
|
|
16862
|
+
const cwd = resolve8(process9.cwd(), cwdRaw === void 0 || cwdRaw === "" ? "." : cwdRaw);
|
|
16525
16863
|
if (!isLiveWorkMode2(modeRaw)) {
|
|
16526
16864
|
return {
|
|
16527
16865
|
mode: "buyer",
|
|
@@ -16584,7 +16922,7 @@ var runLiveWorkHost = async (args) => {
|
|
|
16584
16922
|
exitCode: 1
|
|
16585
16923
|
};
|
|
16586
16924
|
}
|
|
16587
|
-
const env = mergeEnv(
|
|
16925
|
+
const env = mergeEnv(process9.env, loadEnvFile2(flags.cwd));
|
|
16588
16926
|
const either = await Effect23.runPromise(
|
|
16589
16927
|
Effect23.either(
|
|
16590
16928
|
runHostLiveWork({
|
|
@@ -16626,7 +16964,7 @@ var runLiveWorkHost = async (args) => {
|
|
|
16626
16964
|
|
|
16627
16965
|
// src/commands/liveWorkPaymentsCmd.ts
|
|
16628
16966
|
import { resolve as resolve9 } from "path";
|
|
16629
|
-
import
|
|
16967
|
+
import process10 from "process";
|
|
16630
16968
|
|
|
16631
16969
|
// ../packages/payments/src/liveWork/journeyEvents.ts
|
|
16632
16970
|
var toPaymentsLiveWorkJourneyEvents = (result) => {
|
|
@@ -16837,7 +17175,7 @@ var parseLiveWorkPaymentsFlags = (args) => {
|
|
|
16837
17175
|
const modeRaw = readFlagValue(args, "mode") ?? "buyer";
|
|
16838
17176
|
const vendorRaw = readFlagValue(args, "vendor");
|
|
16839
17177
|
const cwdRaw = readFlagValue(args, "cwd");
|
|
16840
|
-
const cwd = resolve9(
|
|
17178
|
+
const cwd = resolve9(process10.cwd(), cwdRaw === void 0 || cwdRaw === "" ? "." : cwdRaw);
|
|
16841
17179
|
if (!isLiveWorkMode3(modeRaw)) {
|
|
16842
17180
|
return {
|
|
16843
17181
|
mode: "buyer",
|
|
@@ -16895,7 +17233,7 @@ var runLiveWorkPayments = async (args) => {
|
|
|
16895
17233
|
exitCode: 1
|
|
16896
17234
|
};
|
|
16897
17235
|
}
|
|
16898
|
-
const env = mergeEnv(
|
|
17236
|
+
const env = mergeEnv(process10.env, loadEnvFile2(flags.cwd));
|
|
16899
17237
|
const either = await Effect26.runPromise(
|
|
16900
17238
|
Effect26.either(
|
|
16901
17239
|
runPaymentsLiveWork({
|
|
@@ -16937,7 +17275,7 @@ var runLiveWorkPayments = async (args) => {
|
|
|
16937
17275
|
// src/commands/localDev.ts
|
|
16938
17276
|
import { spawn } from "child_process";
|
|
16939
17277
|
import { access as access9 } from "fs/promises";
|
|
16940
|
-
import { dirname as dirname9, join as
|
|
17278
|
+
import { dirname as dirname9, join as join28 } from "path";
|
|
16941
17279
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
16942
17280
|
|
|
16943
17281
|
// src/lib/agentDetection.ts
|
|
@@ -17062,15 +17400,15 @@ var listAgents = () => Object.values(AGENTS);
|
|
|
17062
17400
|
// src/commands/localDev.ts
|
|
17063
17401
|
var HERE6 = dirname9(fileURLToPath6(import.meta.url));
|
|
17064
17402
|
var PORT = 3005;
|
|
17065
|
-
var resolveMonorepoRoot = () =>
|
|
17403
|
+
var resolveMonorepoRoot = () => join28(HERE6, "..", "..", "..");
|
|
17066
17404
|
var openBrowser = async (url) => {
|
|
17067
|
-
const { default:
|
|
17068
|
-
await
|
|
17405
|
+
const { default: open2 } = await import("open");
|
|
17406
|
+
await open2(url);
|
|
17069
17407
|
};
|
|
17070
17408
|
var runLocalDev = async () => {
|
|
17071
17409
|
const root = resolveMonorepoRoot();
|
|
17072
17410
|
try {
|
|
17073
|
-
await access9(
|
|
17411
|
+
await access9(join28(root, "pnpm-workspace.yaml"));
|
|
17074
17412
|
} catch {
|
|
17075
17413
|
process.stderr.write("\u274C vybekiit local-dev must be run from inside the VybeKiit monorepo.\n");
|
|
17076
17414
|
return 1;
|
|
@@ -17084,7 +17422,7 @@ var runLocalDev = async () => {
|
|
|
17084
17422
|
process.stdout.write(` URL: http://localhost:${PORT}
|
|
17085
17423
|
`);
|
|
17086
17424
|
process.stdout.write("\n");
|
|
17087
|
-
const appDir =
|
|
17425
|
+
const appDir = join28(root, "apps", "localDevelopmentWebsite");
|
|
17088
17426
|
const child = spawn("pnpm", ["dev"], {
|
|
17089
17427
|
cwd: appDir,
|
|
17090
17428
|
stdio: "pipe",
|
|
@@ -17118,10 +17456,10 @@ var runLocalDev = async () => {
|
|
|
17118
17456
|
};
|
|
17119
17457
|
|
|
17120
17458
|
// src/commands/new.ts
|
|
17121
|
-
import
|
|
17459
|
+
import process11 from "process";
|
|
17122
17460
|
var runNew = async (args) => {
|
|
17123
17461
|
const [template, dir] = args;
|
|
17124
|
-
|
|
17462
|
+
process11.stderr.write(
|
|
17125
17463
|
`Note: \`vybekiit new\` is deprecated. Use \`vybekiit create app ${CREATE_SURFACE_PIPE_FLAGS}\`.
|
|
17126
17464
|
`
|
|
17127
17465
|
);
|
|
@@ -17132,24 +17470,24 @@ var runNew = async (args) => {
|
|
|
17132
17470
|
if (template === void 0 || template === "") {
|
|
17133
17471
|
return await runCreateApp([]);
|
|
17134
17472
|
}
|
|
17135
|
-
|
|
17473
|
+
process11.stderr.write(
|
|
17136
17474
|
`Unknown surface "${template}". Use ${CREATE_SURFACE_LIST_FLAGS} (spa is not a create-app surface).
|
|
17137
17475
|
`
|
|
17138
17476
|
);
|
|
17139
|
-
|
|
17477
|
+
process11.stderr.write(
|
|
17140
17478
|
"Examples:\n vybekiit create app --web my-app\n vybekiit create app --mobile\n"
|
|
17141
17479
|
);
|
|
17142
17480
|
return 1;
|
|
17143
17481
|
};
|
|
17144
17482
|
|
|
17145
17483
|
// src/commands/piecesCmd.ts
|
|
17146
|
-
import
|
|
17484
|
+
import process12 from "process";
|
|
17147
17485
|
|
|
17148
17486
|
// src/lib/pageRecipeCatalog.ts
|
|
17149
|
-
import { readFile as
|
|
17150
|
-
import { join as
|
|
17151
|
-
var PAGE_RECIPE_MANIFEST_RELATIVE =
|
|
17152
|
-
var pageRecipeManifestPath = (kitRoot) =>
|
|
17487
|
+
import { readFile as readFile12 } from "fs/promises";
|
|
17488
|
+
import { join as join29 } from "path";
|
|
17489
|
+
var PAGE_RECIPE_MANIFEST_RELATIVE = join29("scripts", "data", "page-recipe-manifest.json");
|
|
17490
|
+
var pageRecipeManifestPath = (kitRoot) => join29(kitRoot, PAGE_RECIPE_MANIFEST_RELATIVE);
|
|
17153
17491
|
var nonEmptyOr = (value, fallback) => {
|
|
17154
17492
|
if (value === void 0 || value === "") {
|
|
17155
17493
|
return fallback;
|
|
@@ -17228,7 +17566,7 @@ var parsePageRecipeManifest = (raw) => {
|
|
|
17228
17566
|
};
|
|
17229
17567
|
var loadPageRecipes = async (kitRoot) => {
|
|
17230
17568
|
try {
|
|
17231
|
-
const raw = await
|
|
17569
|
+
const raw = await readFile12(pageRecipeManifestPath(kitRoot), "utf8");
|
|
17232
17570
|
return parsePageRecipeManifest(raw);
|
|
17233
17571
|
} catch {
|
|
17234
17572
|
return [];
|
|
@@ -17237,8 +17575,8 @@ var loadPageRecipes = async (kitRoot) => {
|
|
|
17237
17575
|
var findPageRecipe = (recipes, idOrSlug) => recipes.find((recipe) => recipe.id === idOrSlug || recipe.slug === idOrSlug);
|
|
17238
17576
|
|
|
17239
17577
|
// src/lib/pageRecipeInstall.ts
|
|
17240
|
-
import { access as access11, mkdir as
|
|
17241
|
-
import { basename as basename2, dirname as dirname11, join as
|
|
17578
|
+
import { access as access11, mkdir as mkdir8, readFile as readFile14, writeFile as writeFile9 } from "fs/promises";
|
|
17579
|
+
import { basename as basename2, dirname as dirname11, join as join32, relative as relative4, resolve as resolve11 } from "path";
|
|
17242
17580
|
|
|
17243
17581
|
// src/lib/pageRecipeImports.ts
|
|
17244
17582
|
var SHARED_IMPORT_PATTERN = /from\s+['"]((?:\.\.\/)+shared\/[^'"]+|\.\/shared\/[^'"]+)['"]/g;
|
|
@@ -17303,8 +17641,8 @@ var rewriteInstalledSource = (source) => (
|
|
|
17303
17641
|
);
|
|
17304
17642
|
|
|
17305
17643
|
// src/lib/pageRecipePlanFiles.ts
|
|
17306
|
-
import { access as access10, readFile as
|
|
17307
|
-
import { basename, dirname as dirname10, join as
|
|
17644
|
+
import { access as access10, readFile as readFile13 } from "fs/promises";
|
|
17645
|
+
import { basename, dirname as dirname10, join as join31, relative as relative3 } from "path";
|
|
17308
17646
|
|
|
17309
17647
|
// src/lib/pageRecipeRouteStub.ts
|
|
17310
17648
|
var buildRouteStub = (exportName, componentImportPath, targetRoute) => `import { ${exportName} } from '${componentImportPath}';
|
|
@@ -17406,7 +17744,7 @@ export const foregroundTripletFor = (hex: string): string => {
|
|
|
17406
17744
|
`;
|
|
17407
17745
|
|
|
17408
17746
|
// src/lib/resolveAppSurface.ts
|
|
17409
|
-
import { join as
|
|
17747
|
+
import { join as join30, resolve as resolve10 } from "path";
|
|
17410
17748
|
var stripLeadingSlashes = (route) => {
|
|
17411
17749
|
let result = route;
|
|
17412
17750
|
while (result.startsWith("/")) {
|
|
@@ -17425,11 +17763,11 @@ var appRootCandidates = (dest) => {
|
|
|
17425
17763
|
const root = resolve10(dest);
|
|
17426
17764
|
return [
|
|
17427
17765
|
root,
|
|
17428
|
-
|
|
17429
|
-
|
|
17430
|
-
|
|
17431
|
-
|
|
17432
|
-
|
|
17766
|
+
join30(root, "templates", "web"),
|
|
17767
|
+
join30(root, "web"),
|
|
17768
|
+
join30(root, "templates", "spa"),
|
|
17769
|
+
join30(root, "spa"),
|
|
17770
|
+
join30(root, "apps", "web")
|
|
17433
17771
|
];
|
|
17434
17772
|
};
|
|
17435
17773
|
var fallbackLayout = (dest) => {
|
|
@@ -17438,15 +17776,15 @@ var fallbackLayout = (dest) => {
|
|
|
17438
17776
|
appRoot: root,
|
|
17439
17777
|
appDir: void 0,
|
|
17440
17778
|
usesLocaleSegment: false,
|
|
17441
|
-
componentsDir:
|
|
17779
|
+
componentsDir: join30(root, "src", "components", "pageRecipes")
|
|
17442
17780
|
};
|
|
17443
17781
|
};
|
|
17444
17782
|
var probeAppRoot = async (candidate) => {
|
|
17445
|
-
const appAtRoot =
|
|
17446
|
-
const appUnderSrc =
|
|
17447
|
-
const srcDir =
|
|
17783
|
+
const appAtRoot = join30(candidate, "app");
|
|
17784
|
+
const appUnderSrc = join30(candidate, "src", "app");
|
|
17785
|
+
const srcDir = join30(candidate, "src");
|
|
17448
17786
|
const [hasPackage, hasAppAtRoot, hasAppUnderSrc, hasSrc] = await Promise.all([
|
|
17449
|
-
pathExists3(
|
|
17787
|
+
pathExists3(join30(candidate, "package.json")),
|
|
17450
17788
|
pathExists3(appAtRoot),
|
|
17451
17789
|
pathExists3(appUnderSrc),
|
|
17452
17790
|
pathExists3(srcDir)
|
|
@@ -17460,8 +17798,8 @@ var probeAppRoot = async (candidate) => {
|
|
|
17460
17798
|
} else if (hasAppUnderSrc) {
|
|
17461
17799
|
appDir = appUnderSrc;
|
|
17462
17800
|
}
|
|
17463
|
-
const usesLocaleSegment = appDir !== void 0 && await pathExists3(
|
|
17464
|
-
const componentsDir = hasSrc ?
|
|
17801
|
+
const usesLocaleSegment = appDir !== void 0 && await pathExists3(join30(appDir, "[locale]"));
|
|
17802
|
+
const componentsDir = hasSrc ? join30(candidate, "src", "components", "pageRecipes") : join30(candidate, "components", "pageRecipes");
|
|
17465
17803
|
return {
|
|
17466
17804
|
appRoot: candidate,
|
|
17467
17805
|
appDir,
|
|
@@ -17481,7 +17819,7 @@ var routeSegmentPath = (targetRoute, usesLocaleSegment) => {
|
|
|
17481
17819
|
const trimmed = stripTrailingSlashes(stripLeadingSlashes(targetRoute));
|
|
17482
17820
|
const body = trimmed === "" ? "index" : trimmed;
|
|
17483
17821
|
if (usesLocaleSegment) {
|
|
17484
|
-
return
|
|
17822
|
+
return join30("[locale]", body);
|
|
17485
17823
|
}
|
|
17486
17824
|
return body;
|
|
17487
17825
|
};
|
|
@@ -17518,7 +17856,7 @@ var resolveSourceFile = async (basePath) => {
|
|
|
17518
17856
|
var findKitSharedDir = async (fromFile) => {
|
|
17519
17857
|
let dir = dirname10(fromFile);
|
|
17520
17858
|
for (let depth = 0; depth < 6; depth += 1) {
|
|
17521
|
-
const candidate =
|
|
17859
|
+
const candidate = join31(dir, "shared");
|
|
17522
17860
|
if (await pathExists5(candidate)) {
|
|
17523
17861
|
return candidate;
|
|
17524
17862
|
}
|
|
@@ -17532,19 +17870,19 @@ var findKitSharedDir = async (fromFile) => {
|
|
|
17532
17870
|
};
|
|
17533
17871
|
var loadSharedModule = async (options) => {
|
|
17534
17872
|
const { spec, appRoot, componentsDir, kitSharedDir } = options;
|
|
17535
|
-
const kitSharedBase =
|
|
17873
|
+
const kitSharedBase = join31(kitSharedDir, stripLeadingDotSlash(spec));
|
|
17536
17874
|
const kitSharedFile = await resolveSourceFile(kitSharedBase);
|
|
17537
17875
|
if (kitSharedFile === null) {
|
|
17538
17876
|
throw new Error(`Missing shared recipe dependency: ${spec}`);
|
|
17539
17877
|
}
|
|
17540
|
-
const sharedDest =
|
|
17541
|
-
const sharedRaw = await
|
|
17878
|
+
const sharedDest = join31(componentsDir, "shared", basename(kitSharedFile));
|
|
17879
|
+
const sharedRaw = await readFile13(kitSharedFile, "utf8");
|
|
17542
17880
|
const sharedContent = rewriteInstalledSource(sharedRaw);
|
|
17543
17881
|
const nextSpecs = collectRelativeImports(sharedRaw).map((rel) => stripLeadingDotSlash(rel));
|
|
17544
17882
|
return {
|
|
17545
17883
|
file: {
|
|
17546
17884
|
absolutePath: sharedDest,
|
|
17547
|
-
relativePath:
|
|
17885
|
+
relativePath: relative3(appRoot, sharedDest),
|
|
17548
17886
|
kind: "shared",
|
|
17549
17887
|
content: sharedContent
|
|
17550
17888
|
},
|
|
@@ -17617,7 +17955,7 @@ var planRouteFile = async (options) => {
|
|
|
17617
17955
|
return [];
|
|
17618
17956
|
}
|
|
17619
17957
|
const segment = routeSegmentPath(recipe.targetRoute, usesLocaleSegment);
|
|
17620
|
-
const routeFile =
|
|
17958
|
+
const routeFile = join31(appDir, segment, "page.tsx");
|
|
17621
17959
|
const importPath = `@/components/pageRecipes/${stripComponentExtension(recipeFileName)}`;
|
|
17622
17960
|
if (await pathExists5(routeFile)) {
|
|
17623
17961
|
return [];
|
|
@@ -17625,7 +17963,7 @@ var planRouteFile = async (options) => {
|
|
|
17625
17963
|
return [
|
|
17626
17964
|
{
|
|
17627
17965
|
absolutePath: routeFile,
|
|
17628
|
-
relativePath:
|
|
17966
|
+
relativePath: relative3(appRoot, routeFile),
|
|
17629
17967
|
kind: "route",
|
|
17630
17968
|
content: buildRouteStub(recipe.exportName, importPath, recipe.targetRoute)
|
|
17631
17969
|
}
|
|
@@ -17635,11 +17973,11 @@ var themeHelperFiles = (layout, needsThemeHelper) => {
|
|
|
17635
17973
|
if (!needsThemeHelper) {
|
|
17636
17974
|
return [];
|
|
17637
17975
|
}
|
|
17638
|
-
const helperDest =
|
|
17976
|
+
const helperDest = join31(layout.componentsDir, "shared", "themeHelpers.ts");
|
|
17639
17977
|
return [
|
|
17640
17978
|
{
|
|
17641
17979
|
absolutePath: helperDest,
|
|
17642
|
-
relativePath:
|
|
17980
|
+
relativePath: relative3(layout.appRoot, helperDest),
|
|
17643
17981
|
kind: "theme-helper",
|
|
17644
17982
|
content: THEME_HELPER_SOURCE
|
|
17645
17983
|
}
|
|
@@ -17672,15 +18010,15 @@ var pathExists6 = async (path) => {
|
|
|
17672
18010
|
var planPageRecipeInstall = async (options) => {
|
|
17673
18011
|
const { kitRoot, dest, recipe } = options;
|
|
17674
18012
|
const layout = await resolveAppSurface(dest);
|
|
17675
|
-
const sourceAbs =
|
|
18013
|
+
const sourceAbs = join32(kitRoot, recipe.sourcePath);
|
|
17676
18014
|
if (!await pathExists6(sourceAbs)) {
|
|
17677
18015
|
throw new Error(
|
|
17678
18016
|
`Recipe source not found at ${recipe.sourcePath}. Re-run from a kit workspace or with kit access.`
|
|
17679
18017
|
);
|
|
17680
18018
|
}
|
|
17681
|
-
const recipeSource = await
|
|
18019
|
+
const recipeSource = await readFile14(sourceAbs, "utf8");
|
|
17682
18020
|
const recipeFileName = basename2(recipe.sourcePath);
|
|
17683
|
-
const recipeDest =
|
|
18021
|
+
const recipeDest = join32(layout.componentsDir, recipeFileName);
|
|
17684
18022
|
const shared = await planSharedFiles({
|
|
17685
18023
|
sourceAbs,
|
|
17686
18024
|
recipeSource,
|
|
@@ -17697,7 +18035,7 @@ var planPageRecipeInstall = async (options) => {
|
|
|
17697
18035
|
const followUps = buildInstallFollowUps(recipe);
|
|
17698
18036
|
const mainFile = {
|
|
17699
18037
|
absolutePath: recipeDest,
|
|
17700
|
-
relativePath:
|
|
18038
|
+
relativePath: relative4(layout.appRoot, recipeDest),
|
|
17701
18039
|
kind: "component",
|
|
17702
18040
|
content: rewriteInstalledSource(recipeSource)
|
|
17703
18041
|
};
|
|
@@ -17728,8 +18066,8 @@ var applyPageRecipeInstall = async (plan, options = { force: false }) => {
|
|
|
17728
18066
|
if (exists3 && !options.force) {
|
|
17729
18067
|
return { kind: "skipped", path: file.relativePath };
|
|
17730
18068
|
}
|
|
17731
|
-
await
|
|
17732
|
-
await
|
|
18069
|
+
await mkdir8(dirname11(file.absolutePath), { recursive: true });
|
|
18070
|
+
await writeFile9(file.absolutePath, file.content, "utf8");
|
|
17733
18071
|
return { kind: "written", path: file.relativePath };
|
|
17734
18072
|
})
|
|
17735
18073
|
);
|
|
@@ -17776,6 +18114,15 @@ var backendPieces = () => [
|
|
|
17776
18114
|
command: "vybekiit backend add-upload"
|
|
17777
18115
|
}
|
|
17778
18116
|
];
|
|
18117
|
+
var reportModePieces = () => [
|
|
18118
|
+
{
|
|
18119
|
+
kind: "report-mode",
|
|
18120
|
+
id: "report-mode",
|
|
18121
|
+
title: "Report Mode",
|
|
18122
|
+
summary: "Install the dev-only point & fix inspect/report overlay into an existing app.",
|
|
18123
|
+
command: "vybekiit add report-mode [--to=dir]"
|
|
18124
|
+
}
|
|
18125
|
+
];
|
|
17779
18126
|
var dbPieces = () => ALL_PRESETS.map((preset) => {
|
|
17780
18127
|
const summary = preset.description === void 0 || preset.description === "" ? `Database preset ${preset.id}` : preset.description;
|
|
17781
18128
|
return {
|
|
@@ -17795,7 +18142,7 @@ var pageRecipePieces = (recipes) => recipes.map((recipe) => ({
|
|
|
17795
18142
|
linkedPresets: recipe.presetIds,
|
|
17796
18143
|
command: `vybekiit add page-recipe ${recipe.id}`
|
|
17797
18144
|
}));
|
|
17798
|
-
var buildCatalog = (recipes, kindFilter) => [...dbPieces(), ...pageRecipePieces(recipes), ...backendPieces()].filter(
|
|
18145
|
+
var buildCatalog = (recipes, kindFilter) => [...dbPieces(), ...pageRecipePieces(recipes), ...backendPieces(), ...reportModePieces()].filter(
|
|
17799
18146
|
(piece) => kindFilter === void 0 || piece.kind === kindFilter
|
|
17800
18147
|
);
|
|
17801
18148
|
|
|
@@ -17931,7 +18278,7 @@ var runAddPageRecipe = async (args) => {
|
|
|
17931
18278
|
if (recipe === void 0) {
|
|
17932
18279
|
return recipeError(`Unknown page recipe "${recipeId}". Run: vybekiit list-page-recipes`);
|
|
17933
18280
|
}
|
|
17934
|
-
const dest = resolveInstallDest(destArg,
|
|
18281
|
+
const dest = resolveInstallDest(destArg, process12.cwd());
|
|
17935
18282
|
const plan = await planPageRecipeInstall({ kitRoot, dest, recipe });
|
|
17936
18283
|
if (flags.dryRun) {
|
|
17937
18284
|
return {
|
|
@@ -17955,12 +18302,12 @@ var runAddPageRecipe = async (args) => {
|
|
|
17955
18302
|
};
|
|
17956
18303
|
|
|
17957
18304
|
// src/commands/piecesInteractive.ts
|
|
17958
|
-
import
|
|
17959
|
-
import { cancel, isCancel, select } from "@clack/prompts";
|
|
18305
|
+
import process15 from "process";
|
|
18306
|
+
import { cancel, isCancel as isCancel2, select } from "@clack/prompts";
|
|
17960
18307
|
|
|
17961
18308
|
// src/commands/presetsCmd.ts
|
|
17962
18309
|
import { resolve as resolve12 } from "path";
|
|
17963
|
-
import
|
|
18310
|
+
import process13 from "process";
|
|
17964
18311
|
import { Effect as Effect27, Either as Either5 } from "effect";
|
|
17965
18312
|
var POSTGRES_PROVIDERS = ["supabase", "neon", "railway"];
|
|
17966
18313
|
var NOSQL_PROVIDERS = ["mongodb", "firebase", "aws"];
|
|
@@ -17988,10 +18335,10 @@ var parseFlags = (args) => {
|
|
|
17988
18335
|
};
|
|
17989
18336
|
var resolvePresetEnv = (cwd) => {
|
|
17990
18337
|
if (cwd === void 0 || cwd === "") {
|
|
17991
|
-
return
|
|
18338
|
+
return process13.env;
|
|
17992
18339
|
}
|
|
17993
|
-
const absolute = resolve12(
|
|
17994
|
-
return mergeEnv(
|
|
18340
|
+
const absolute = resolve12(process13.cwd(), cwd);
|
|
18341
|
+
return mergeEnv(process13.env, loadEnvFile2(absolute));
|
|
17995
18342
|
};
|
|
17996
18343
|
var databaseUrlFromEnv = (env) => env.DATABASE_URL;
|
|
17997
18344
|
var isNosqlProvider2 = (provider) => provider === "mongodb" || provider === "firebase" || provider === "aws";
|
|
@@ -18095,7 +18442,7 @@ var runApplyPreset = async (args) => {
|
|
|
18095
18442
|
result.ok ? {
|
|
18096
18443
|
ok: true,
|
|
18097
18444
|
...result.value,
|
|
18098
|
-
...flags.cwd === void 0 ? {} : { cwd: resolve12(
|
|
18445
|
+
...flags.cwd === void 0 ? {} : { cwd: resolve12(process13.cwd(), flags.cwd) }
|
|
18099
18446
|
} : result,
|
|
18100
18447
|
null,
|
|
18101
18448
|
2
|
|
@@ -18155,97 +18502,591 @@ var runListPresets = () => {
|
|
|
18155
18502
|
};
|
|
18156
18503
|
};
|
|
18157
18504
|
|
|
18158
|
-
// src/commands/
|
|
18159
|
-
|
|
18160
|
-
|
|
18161
|
-
|
|
18162
|
-
|
|
18163
|
-
|
|
18164
|
-
|
|
18165
|
-
|
|
18166
|
-
const picked = await select({
|
|
18167
|
-
message: "Which database preset?",
|
|
18168
|
-
options: ALL_PRESETS.map((preset) => ({
|
|
18169
|
-
value: preset.id,
|
|
18170
|
-
label: preset.id,
|
|
18171
|
-
hint: preset.description === void 0 || preset.description === "" ? preset.id : preset.description
|
|
18172
|
-
}))
|
|
18173
|
-
});
|
|
18174
|
-
if (isCancel(picked) || typeof picked !== "string") {
|
|
18175
|
-
cancel("Cancelled.");
|
|
18176
|
-
return 1;
|
|
18505
|
+
// src/commands/reportModeCmd.ts
|
|
18506
|
+
import { spawnSync } from "child_process";
|
|
18507
|
+
import process14 from "process";
|
|
18508
|
+
|
|
18509
|
+
// ../packages/reportMode/src/deeplink.ts
|
|
18510
|
+
var inferVybeAssistant = (options) => {
|
|
18511
|
+
if (options.cursorSession) {
|
|
18512
|
+
return "cursor";
|
|
18177
18513
|
}
|
|
18178
|
-
|
|
18179
|
-
|
|
18180
|
-
|
|
18181
|
-
|
|
18182
|
-
|
|
18183
|
-
|
|
18184
|
-
(
|
|
18185
|
-
|
|
18186
|
-
|
|
18187
|
-
|
|
18514
|
+
if (options.claudeInstalled) {
|
|
18515
|
+
return "claude";
|
|
18516
|
+
}
|
|
18517
|
+
if (options.codexInstalled) {
|
|
18518
|
+
return "codex";
|
|
18519
|
+
}
|
|
18520
|
+
if (options.kiroInstalled === true) {
|
|
18521
|
+
return "kiro";
|
|
18522
|
+
}
|
|
18523
|
+
if (options.kimiInstalled === true) {
|
|
18524
|
+
return "kimi";
|
|
18525
|
+
}
|
|
18526
|
+
if (options.grokInstalled === true) {
|
|
18527
|
+
return "grok";
|
|
18528
|
+
}
|
|
18529
|
+
if (options.devinInstalled === true) {
|
|
18530
|
+
return "devin";
|
|
18531
|
+
}
|
|
18532
|
+
return null;
|
|
18188
18533
|
};
|
|
18189
|
-
|
|
18190
|
-
|
|
18534
|
+
|
|
18535
|
+
// src/lib/reportModeInstall.ts
|
|
18536
|
+
import { access as access12, mkdir as mkdir9, readdir as readdir8, readFile as readFile16, writeFile as writeFile11 } from "fs/promises";
|
|
18537
|
+
import { dirname as dirname12, join as join33, relative as relative5 } from "path";
|
|
18538
|
+
|
|
18539
|
+
// src/lib/packageJsonDeps.ts
|
|
18540
|
+
import { readFile as readFile15, writeFile as writeFile10 } from "fs/promises";
|
|
18541
|
+
var ensureDependencies = async (pkgPath, deps) => {
|
|
18542
|
+
let raw;
|
|
18191
18543
|
try {
|
|
18192
|
-
|
|
18193
|
-
|
|
18194
|
-
|
|
18195
|
-
|
|
18196
|
-
|
|
18197
|
-
|
|
18198
|
-
|
|
18199
|
-
|
|
18200
|
-
|
|
18201
|
-
|
|
18202
|
-
|
|
18203
|
-
value: recipe.id,
|
|
18204
|
-
label: recipe.title,
|
|
18205
|
-
hint: `${recipe.groupLabel} \xB7 ${recipe.targetRoute}`
|
|
18206
|
-
}))
|
|
18207
|
-
});
|
|
18208
|
-
if (isCancel(picked) || typeof picked !== "string") {
|
|
18209
|
-
cancel("Cancelled.");
|
|
18210
|
-
return 1;
|
|
18544
|
+
raw = await readFile15(pkgPath, "utf8");
|
|
18545
|
+
} catch {
|
|
18546
|
+
return [];
|
|
18547
|
+
}
|
|
18548
|
+
const pkg = JSON.parse(raw);
|
|
18549
|
+
const dependencies = pkg.dependencies ?? {};
|
|
18550
|
+
const added = [];
|
|
18551
|
+
for (const [name, version] of Object.entries(deps)) {
|
|
18552
|
+
if (dependencies[name] === void 0) {
|
|
18553
|
+
dependencies[name] = version;
|
|
18554
|
+
added.push(name);
|
|
18211
18555
|
}
|
|
18212
|
-
|
|
18213
|
-
|
|
18556
|
+
}
|
|
18557
|
+
if (added.length === 0) {
|
|
18558
|
+
return [];
|
|
18559
|
+
}
|
|
18560
|
+
pkg.dependencies = dependencies;
|
|
18561
|
+
await writeFile10(pkgPath, `${JSON.stringify(pkg, null, 2)}
|
|
18214
18562
|
`);
|
|
18215
|
-
|
|
18216
|
-
|
|
18217
|
-
|
|
18218
|
-
|
|
18219
|
-
|
|
18220
|
-
|
|
18563
|
+
return added;
|
|
18564
|
+
};
|
|
18565
|
+
|
|
18566
|
+
// src/lib/reportModeInstall.ts
|
|
18567
|
+
var INSTALLABLE_SURFACES = ["web", "mobile", "extension"];
|
|
18568
|
+
var isInstallableSurface = (surface) => INSTALLABLE_SURFACES.includes(surface);
|
|
18569
|
+
var listFilesRecursive = async (dir, prefix = "") => {
|
|
18570
|
+
try {
|
|
18571
|
+
const entries = await readdir8(dir, { withFileTypes: true });
|
|
18572
|
+
const nested = await Promise.all(
|
|
18573
|
+
entries.map(async (entry) => {
|
|
18574
|
+
const rel = prefix === "" ? entry.name : `${prefix}/${entry.name}`;
|
|
18575
|
+
if (entry.isDirectory()) {
|
|
18576
|
+
return await listFilesRecursive(join33(dir, entry.name), rel);
|
|
18577
|
+
}
|
|
18578
|
+
return [rel];
|
|
18579
|
+
})
|
|
18580
|
+
);
|
|
18581
|
+
return nested.flat();
|
|
18582
|
+
} catch {
|
|
18583
|
+
return [];
|
|
18584
|
+
}
|
|
18585
|
+
};
|
|
18586
|
+
var defaultReportModeFs = {
|
|
18587
|
+
listFiles: (dir) => listFilesRecursive(dir),
|
|
18588
|
+
readText: async (path) => {
|
|
18589
|
+
try {
|
|
18590
|
+
return await readFile16(path, "utf8");
|
|
18591
|
+
} catch {
|
|
18592
|
+
return null;
|
|
18221
18593
|
}
|
|
18222
|
-
|
|
18223
|
-
|
|
18224
|
-
|
|
18225
|
-
|
|
18226
|
-
|
|
18227
|
-
|
|
18228
|
-
|
|
18229
|
-
if (cleanup !== void 0) {
|
|
18230
|
-
await cleanup();
|
|
18594
|
+
},
|
|
18595
|
+
exists: async (path) => {
|
|
18596
|
+
try {
|
|
18597
|
+
await access12(path);
|
|
18598
|
+
return true;
|
|
18599
|
+
} catch {
|
|
18600
|
+
return false;
|
|
18231
18601
|
}
|
|
18602
|
+
},
|
|
18603
|
+
writeText: async (path, content) => {
|
|
18604
|
+
await mkdir9(dirname12(path), { recursive: true });
|
|
18605
|
+
await writeFile11(path, content, "utf8");
|
|
18232
18606
|
}
|
|
18233
18607
|
};
|
|
18234
|
-
var
|
|
18235
|
-
|
|
18236
|
-
|
|
18237
|
-
|
|
18238
|
-
|
|
18239
|
-
|
|
18608
|
+
var SURFACE_SOURCES = {
|
|
18609
|
+
web: {
|
|
18610
|
+
subtrees: ["src/components/report-mode", "src/lib/report-mode", "src/components/walkthrough"],
|
|
18611
|
+
companions: ["src/lib/nodeEnv.ts", "src/lib/utils.ts"],
|
|
18612
|
+
assumedPresent: []
|
|
18613
|
+
},
|
|
18614
|
+
mobile: {
|
|
18615
|
+
subtrees: ["src/components/report-mode", "src/lib/report-mode"],
|
|
18616
|
+
companions: ["src/lib/nodeEnv.ts"],
|
|
18617
|
+
assumedPresent: ["@/theme/useTheme"]
|
|
18618
|
+
},
|
|
18619
|
+
extension: {
|
|
18620
|
+
subtrees: ["src/components/report-mode", "src/lib/report-mode"],
|
|
18621
|
+
companions: ["src/lib/utils.ts", "styles/report-mode-note.css"],
|
|
18622
|
+
assumedPresent: ["@/components/ui/button", "@/components/ui/input"]
|
|
18240
18623
|
}
|
|
18241
|
-
|
|
18242
|
-
|
|
18243
|
-
|
|
18244
|
-
|
|
18245
|
-
|
|
18624
|
+
};
|
|
18625
|
+
var REWRITE_TARGET = "src/components/report-mode/report-mode-dev.tsx";
|
|
18626
|
+
var UTILS_FILE = "src/lib/utils.ts";
|
|
18627
|
+
var WORKSPACE_RANGE = "workspace:*";
|
|
18628
|
+
var parseDependencies = (raw) => {
|
|
18629
|
+
if (raw === null || raw === "") {
|
|
18630
|
+
return {};
|
|
18631
|
+
}
|
|
18632
|
+
try {
|
|
18633
|
+
const parsed = JSON.parse(raw);
|
|
18634
|
+
return parsed.dependencies ?? {};
|
|
18635
|
+
} catch {
|
|
18636
|
+
return {};
|
|
18637
|
+
}
|
|
18638
|
+
};
|
|
18639
|
+
var rewriteContent = (relativePath, raw, applyRewrite) => {
|
|
18640
|
+
if (!applyRewrite || relativePath !== REWRITE_TARGET) {
|
|
18641
|
+
return raw;
|
|
18642
|
+
}
|
|
18643
|
+
return raw.replaceAll("from '@/i18n/navigation'", "from 'next/navigation'");
|
|
18644
|
+
};
|
|
18645
|
+
var toPlannedFile = async (options) => {
|
|
18646
|
+
const { fs, sourceDir, dest, relativePath, applyRewrite } = options;
|
|
18647
|
+
const raw = await fs.readText(join33(sourceDir, relativePath));
|
|
18648
|
+
if (raw === null) {
|
|
18649
|
+
return null;
|
|
18650
|
+
}
|
|
18651
|
+
const absolutePath = join33(dest, relativePath);
|
|
18652
|
+
return {
|
|
18653
|
+
relativePath,
|
|
18654
|
+
absolutePath,
|
|
18655
|
+
content: rewriteContent(relativePath, raw, applyRewrite),
|
|
18656
|
+
exists: await fs.exists(absolutePath)
|
|
18657
|
+
};
|
|
18658
|
+
};
|
|
18659
|
+
var buildPlannedFiles = async (options) => {
|
|
18660
|
+
const { fs, sourceDir, dest, sources, applyRewrite } = options;
|
|
18661
|
+
const subtreeGroups = await Promise.all(
|
|
18662
|
+
sources.subtrees.map(async (subtree) => {
|
|
18663
|
+
const names = await fs.listFiles(join33(sourceDir, subtree));
|
|
18664
|
+
return names.map((name) => `${subtree}/${name}`);
|
|
18665
|
+
})
|
|
18666
|
+
);
|
|
18667
|
+
const relativePaths = [...subtreeGroups.flat(), ...sources.companions];
|
|
18668
|
+
const planned = await Promise.all(
|
|
18669
|
+
relativePaths.map(
|
|
18670
|
+
(relativePath) => toPlannedFile({ fs, sourceDir, dest, relativePath, applyRewrite })
|
|
18671
|
+
)
|
|
18672
|
+
);
|
|
18673
|
+
return planned.filter((file) => file !== null);
|
|
18674
|
+
};
|
|
18675
|
+
var buildDeps = (surface, sourceDeps, willWriteUtils) => {
|
|
18676
|
+
const deps = { "@vybekiit/report-mode": WORKSPACE_RANGE };
|
|
18677
|
+
if (surface === "web") {
|
|
18678
|
+
deps["@vybekiit/ui"] = WORKSPACE_RANGE;
|
|
18679
|
+
deps["@vybekiit/walkthrough"] = WORKSPACE_RANGE;
|
|
18680
|
+
const { sonner } = sourceDeps;
|
|
18681
|
+
if (sonner !== void 0) {
|
|
18682
|
+
deps.sonner = sonner;
|
|
18683
|
+
}
|
|
18684
|
+
}
|
|
18685
|
+
if (willWriteUtils && (surface === "web" || surface === "extension")) {
|
|
18686
|
+
const { cnfast } = sourceDeps;
|
|
18687
|
+
if (cnfast !== void 0) {
|
|
18688
|
+
deps.cnfast = cnfast;
|
|
18689
|
+
}
|
|
18690
|
+
}
|
|
18691
|
+
return deps;
|
|
18692
|
+
};
|
|
18693
|
+
var buildEnv = (surface, assistant) => {
|
|
18694
|
+
const env = { VYBE_REPORT_MODE: "1" };
|
|
18695
|
+
if (assistant === null) {
|
|
18696
|
+
return env;
|
|
18697
|
+
}
|
|
18698
|
+
const projectSurface = {
|
|
18699
|
+
template: surface,
|
|
18700
|
+
mobile: surface === "mobile",
|
|
18701
|
+
extension: surface === "extension"
|
|
18702
|
+
};
|
|
18703
|
+
return { ...env, ...reportModeEnvKeysForSurface(projectSurface, assistant) };
|
|
18704
|
+
};
|
|
18705
|
+
var planRewrite = async (options) => {
|
|
18706
|
+
const { surface, dest, fs, appSurface, destDeps } = options;
|
|
18707
|
+
if (surface !== "web") {
|
|
18708
|
+
return { applied: false, reason: `No i18n rewrite for the ${surface} surface.` };
|
|
18709
|
+
}
|
|
18710
|
+
const usesLocaleSegment = appSurface?.usesLocaleSegment === true;
|
|
18711
|
+
const hasI18nNavigation = await fs.exists(join33(dest, "src", "i18n", "navigation.ts"));
|
|
18712
|
+
const hasNextIntlDep = destDeps["next-intl"] !== void 0;
|
|
18713
|
+
if (usesLocaleSegment || hasI18nNavigation || hasNextIntlDep) {
|
|
18714
|
+
return { applied: false, reason: "Project uses next-intl; kept @/i18n/navigation." };
|
|
18715
|
+
}
|
|
18716
|
+
return { applied: true, reason: "Non-next-intl project; rewrote to next/navigation." };
|
|
18717
|
+
};
|
|
18718
|
+
var uniquePaths = (paths) => [...new Set(paths)];
|
|
18719
|
+
var buildMountSpec = (surface, dest, appSurface) => {
|
|
18720
|
+
if (surface === "web") {
|
|
18721
|
+
const appDir = appSurface?.appDir;
|
|
18722
|
+
const candidates = [];
|
|
18723
|
+
if (appDir !== void 0 && appSurface?.usesLocaleSegment === true) {
|
|
18724
|
+
candidates.push(join33(appDir, "[locale]", "layout.tsx"));
|
|
18725
|
+
}
|
|
18726
|
+
if (appDir !== void 0) {
|
|
18727
|
+
candidates.push(join33(appDir, "layout.tsx"));
|
|
18728
|
+
}
|
|
18729
|
+
candidates.push(join33(dest, "src", "app", "layout.tsx"));
|
|
18730
|
+
return {
|
|
18731
|
+
component: "ReportModeDevShell",
|
|
18732
|
+
importStatement: "import { ReportModeDevShell } from '@/components/report-mode/report-mode-shell';",
|
|
18733
|
+
jsxTag: "<ReportModeDevShell />",
|
|
18734
|
+
candidatePaths: uniquePaths(candidates),
|
|
18735
|
+
anchor: "</body>"
|
|
18736
|
+
};
|
|
18737
|
+
}
|
|
18738
|
+
if (surface === "mobile") {
|
|
18739
|
+
return {
|
|
18740
|
+
component: "ReportModeDev",
|
|
18741
|
+
importStatement: "import { ReportModeDev } from '@/components/report-mode/report-mode-dev';",
|
|
18742
|
+
jsxTag: "<ReportModeDev />",
|
|
18743
|
+
candidatePaths: [join33(dest, "app", "_layout.tsx")],
|
|
18744
|
+
anchor: void 0
|
|
18745
|
+
};
|
|
18746
|
+
}
|
|
18747
|
+
return {
|
|
18748
|
+
component: "ReportModeDev",
|
|
18749
|
+
importStatement: "import { ReportModeDev } from '@/components/report-mode/report-mode-dev';",
|
|
18750
|
+
jsxTag: "<ReportModeDev />",
|
|
18751
|
+
candidatePaths: [join33(dest, "src", "components", "app-root.tsx")],
|
|
18752
|
+
anchor: void 0
|
|
18753
|
+
};
|
|
18754
|
+
};
|
|
18755
|
+
var insertMount = (content, importStatement, jsxTag, anchor) => {
|
|
18756
|
+
const lines = content.split("\n");
|
|
18757
|
+
const lastImportIndex = lines.reduce(
|
|
18758
|
+
(acc, line, index) => line.startsWith("import ") ? index : acc,
|
|
18759
|
+
-1
|
|
18760
|
+
);
|
|
18761
|
+
const withImport = lastImportIndex >= 0 ? [
|
|
18762
|
+
...lines.slice(0, lastImportIndex + 1),
|
|
18763
|
+
importStatement,
|
|
18764
|
+
...lines.slice(lastImportIndex + 1)
|
|
18765
|
+
].join("\n") : `${importStatement}
|
|
18766
|
+
${content}`;
|
|
18767
|
+
return withImport.replace(anchor, ` ${jsxTag}
|
|
18768
|
+
${anchor}`);
|
|
18769
|
+
};
|
|
18770
|
+
var planMount = async (fs, spec) => {
|
|
18771
|
+
const loaded = await Promise.all(
|
|
18772
|
+
spec.candidatePaths.map(async (candidate) => ({
|
|
18773
|
+
candidate,
|
|
18774
|
+
content: await fs.readText(candidate)
|
|
18775
|
+
}))
|
|
18776
|
+
);
|
|
18777
|
+
const existing = loaded.filter(
|
|
18778
|
+
(entry) => entry.content !== null
|
|
18779
|
+
);
|
|
18780
|
+
const base = {
|
|
18781
|
+
path: existing[0]?.candidate ?? spec.candidatePaths[0] ?? "",
|
|
18782
|
+
importSnippet: spec.importStatement,
|
|
18783
|
+
jsxSnippet: spec.jsxTag
|
|
18784
|
+
};
|
|
18785
|
+
if (existing.length === 0) {
|
|
18786
|
+
return { ...base, status: "todo", reason: "No root layout found; mount manually." };
|
|
18787
|
+
}
|
|
18788
|
+
const alreadyMounted = existing.find((entry) => entry.content.includes(spec.component));
|
|
18789
|
+
if (alreadyMounted !== void 0) {
|
|
18790
|
+
return {
|
|
18791
|
+
...base,
|
|
18792
|
+
path: alreadyMounted.candidate,
|
|
18793
|
+
status: "already",
|
|
18794
|
+
reason: "Report Mode is already mounted."
|
|
18795
|
+
};
|
|
18796
|
+
}
|
|
18797
|
+
const anchor = spec.anchor;
|
|
18798
|
+
if (anchor !== void 0) {
|
|
18799
|
+
const mountable = existing.filter((entry) => entry.content.split(anchor).length - 1 === 1);
|
|
18800
|
+
const target = mountable[0];
|
|
18801
|
+
if (mountable.length === 1 && target !== void 0) {
|
|
18802
|
+
return {
|
|
18803
|
+
...base,
|
|
18804
|
+
path: target.candidate,
|
|
18805
|
+
status: "inserted",
|
|
18806
|
+
reason: "Mounted into the root layout.",
|
|
18807
|
+
newContent: insertMount(target.content, spec.importStatement, spec.jsxTag, anchor)
|
|
18808
|
+
};
|
|
18809
|
+
}
|
|
18810
|
+
}
|
|
18811
|
+
return { ...base, status: "todo", reason: "Mount manually (no single layout anchor found)." };
|
|
18812
|
+
};
|
|
18813
|
+
var planReportModeInstall = async (options) => {
|
|
18814
|
+
const { kitRoot, dest, surface, assistant, appSurface, fs = defaultReportModeFs } = options;
|
|
18815
|
+
if (!isInstallableSurface(surface)) {
|
|
18816
|
+
return { available: false, surface };
|
|
18817
|
+
}
|
|
18818
|
+
const sourceDir = join33(kitRoot, "templates", surface);
|
|
18819
|
+
const sources = SURFACE_SOURCES[surface];
|
|
18820
|
+
const destDeps = parseDependencies(await fs.readText(join33(dest, "package.json")));
|
|
18821
|
+
const rewrite = await planRewrite({ surface, dest, fs, appSurface, destDeps });
|
|
18822
|
+
const files = await buildPlannedFiles({
|
|
18823
|
+
fs,
|
|
18824
|
+
sourceDir,
|
|
18825
|
+
dest,
|
|
18826
|
+
sources,
|
|
18827
|
+
applyRewrite: rewrite.applied
|
|
18828
|
+
});
|
|
18829
|
+
if (files.length === 0) {
|
|
18830
|
+
throw new Error(
|
|
18831
|
+
`Report Mode source not found under templates/${surface}. Re-run from a kit workspace or with kit access.`
|
|
18832
|
+
);
|
|
18833
|
+
}
|
|
18834
|
+
const utilsFile = files.find((file) => file.relativePath === UTILS_FILE);
|
|
18835
|
+
const willWriteUtils = utilsFile !== void 0 && !utilsFile.exists;
|
|
18836
|
+
const sourceDeps = parseDependencies(await fs.readText(join33(sourceDir, "package.json")));
|
|
18837
|
+
const deps = buildDeps(surface, sourceDeps, willWriteUtils);
|
|
18838
|
+
const env = buildEnv(surface, assistant);
|
|
18839
|
+
const mount = await planMount(fs, buildMountSpec(surface, dest, appSurface));
|
|
18840
|
+
const todos = [];
|
|
18841
|
+
if (assistant === null) {
|
|
18842
|
+
todos.push(
|
|
18843
|
+
"Run `vybekiit doctor` to set your assistant key so Report Mode knows where to hand off."
|
|
18844
|
+
);
|
|
18845
|
+
}
|
|
18846
|
+
if (sources.assumedPresent.length > 0) {
|
|
18847
|
+
todos.push(
|
|
18848
|
+
`Report Mode also imports these files that ship in every VybeKiit ${surface} app: ${sources.assumedPresent.join(", ")}. Add them first if your project predates them.`
|
|
18849
|
+
);
|
|
18850
|
+
}
|
|
18851
|
+
if (mount.status === "todo") {
|
|
18852
|
+
todos.push(
|
|
18853
|
+
`Mount Report Mode in ${relative5(dest, mount.path) || mount.path}: add \`${mount.importSnippet}\` and render \`${mount.jsxSnippet}\` in the layout.`
|
|
18854
|
+
);
|
|
18855
|
+
}
|
|
18856
|
+
return {
|
|
18857
|
+
available: true,
|
|
18858
|
+
surface,
|
|
18859
|
+
dest,
|
|
18860
|
+
files,
|
|
18861
|
+
deps,
|
|
18862
|
+
env,
|
|
18863
|
+
rewrite,
|
|
18864
|
+
mount,
|
|
18865
|
+
assumedPresent: sources.assumedPresent,
|
|
18866
|
+
todos,
|
|
18867
|
+
nextCommands: assistant === null ? ["vybekiit doctor"] : []
|
|
18868
|
+
};
|
|
18869
|
+
};
|
|
18870
|
+
var defaultApplySeams = {
|
|
18871
|
+
fs: defaultReportModeFs,
|
|
18872
|
+
ensureDeps: ensureDependencies,
|
|
18873
|
+
writeEnv: writeEnvKeys
|
|
18874
|
+
};
|
|
18875
|
+
var applyReportModeInstall = async (plan, options = { force: false }, seams = defaultApplySeams) => {
|
|
18876
|
+
const outcomes = await Promise.all(
|
|
18877
|
+
plan.files.map(async (file) => {
|
|
18878
|
+
if (file.exists && !options.force) {
|
|
18879
|
+
return { kind: "skipped", path: file.relativePath };
|
|
18880
|
+
}
|
|
18881
|
+
await seams.fs.writeText(file.absolutePath, file.content);
|
|
18882
|
+
return { kind: "written", path: file.relativePath };
|
|
18883
|
+
})
|
|
18884
|
+
);
|
|
18885
|
+
const written = outcomes.filter((row) => row.kind === "written").map((row) => row.path);
|
|
18886
|
+
const skipped = outcomes.filter((row) => row.kind === "skipped").map((row) => row.path);
|
|
18887
|
+
const depsAdded = await seams.ensureDeps(join33(plan.dest, "package.json"), plan.deps);
|
|
18888
|
+
if (Object.keys(plan.env).length > 0) {
|
|
18889
|
+
seams.writeEnv(plan.dest, plan.env);
|
|
18890
|
+
}
|
|
18891
|
+
if (plan.mount.status === "inserted" && plan.mount.newContent !== void 0) {
|
|
18892
|
+
await seams.fs.writeText(plan.mount.path, plan.mount.newContent);
|
|
18893
|
+
}
|
|
18894
|
+
return {
|
|
18895
|
+
written,
|
|
18896
|
+
skipped,
|
|
18897
|
+
depsAdded,
|
|
18898
|
+
envKeys: Object.keys(plan.env),
|
|
18899
|
+
mount: plan.mount.status
|
|
18900
|
+
};
|
|
18901
|
+
};
|
|
18902
|
+
|
|
18903
|
+
// src/commands/reportModeCmd.ts
|
|
18904
|
+
var isCursorSession = () => Boolean(process14.env.CURSOR_TRACE_ID || process14.env.CURSOR_SESSION_ID);
|
|
18905
|
+
var succeeds = (command, args) => spawnSync(command, [...args], { stdio: "ignore" }).status === 0;
|
|
18906
|
+
var resolveAssistant = () => inferVybeAssistant({
|
|
18907
|
+
cursorSession: isCursorSession(),
|
|
18908
|
+
claudeInstalled: succeeds("claude", ["--version"]),
|
|
18909
|
+
codexInstalled: succeeds("codex", ["--version"])
|
|
18910
|
+
});
|
|
18911
|
+
var installPayload2 = (plan, written, skipped, dryRun) => ({
|
|
18912
|
+
ok: true,
|
|
18913
|
+
dryRun,
|
|
18914
|
+
surface: plan.surface,
|
|
18915
|
+
files: plan.files.map((file) => file.relativePath),
|
|
18916
|
+
written,
|
|
18917
|
+
skipped,
|
|
18918
|
+
deps: plan.deps,
|
|
18919
|
+
env: plan.env,
|
|
18920
|
+
mount: { status: plan.mount.status, path: plan.mount.path, reason: plan.mount.reason },
|
|
18921
|
+
rewrite: plan.rewrite,
|
|
18922
|
+
assumedPresent: plan.assumedPresent,
|
|
18923
|
+
todos: plan.todos,
|
|
18924
|
+
nextCommands: plan.nextCommands
|
|
18925
|
+
});
|
|
18926
|
+
var reportModeError = (error) => ({
|
|
18927
|
+
json: JSON.stringify({ ok: false, error }),
|
|
18928
|
+
exitCode: 1
|
|
18929
|
+
});
|
|
18930
|
+
var runAddReportMode = async (args) => {
|
|
18931
|
+
const flags = parsePieceFlags(args);
|
|
18932
|
+
const destArg = flags.to === void 0 || flags.to === "" ? flags.positionals.at(0) : flags.to;
|
|
18933
|
+
const dest = resolveInstallDest(destArg, process14.cwd());
|
|
18934
|
+
const surface = inferProjectSurfaceSync(dest).template;
|
|
18935
|
+
let cleanup;
|
|
18936
|
+
try {
|
|
18937
|
+
const resolved = await resolveKitSource();
|
|
18938
|
+
const { cleanup: resolvedCleanup, kitRoot } = resolved;
|
|
18939
|
+
cleanup = resolvedCleanup;
|
|
18940
|
+
const appSurface = surface === "web" ? await resolveAppSurface(dest) : void 0;
|
|
18941
|
+
const plan = await planReportModeInstall({
|
|
18942
|
+
kitRoot,
|
|
18943
|
+
dest,
|
|
18944
|
+
surface,
|
|
18945
|
+
assistant: resolveAssistant(),
|
|
18946
|
+
...appSurface === void 0 ? {} : { appSurface }
|
|
18947
|
+
});
|
|
18948
|
+
if (!plan.available) {
|
|
18949
|
+
return {
|
|
18950
|
+
json: JSON.stringify(
|
|
18951
|
+
{
|
|
18952
|
+
ok: true,
|
|
18953
|
+
available: false,
|
|
18954
|
+
surface: plan.surface,
|
|
18955
|
+
reason: `Report Mode has no installable files for the ${plan.surface} surface (web, mobile, and extension only).`
|
|
18956
|
+
},
|
|
18957
|
+
null,
|
|
18958
|
+
2
|
|
18959
|
+
),
|
|
18960
|
+
exitCode: 0
|
|
18961
|
+
};
|
|
18962
|
+
}
|
|
18963
|
+
if (flags.dryRun) {
|
|
18964
|
+
return {
|
|
18965
|
+
json: JSON.stringify(installPayload2(plan, [], [], true), null, 2),
|
|
18966
|
+
exitCode: 0
|
|
18967
|
+
};
|
|
18968
|
+
}
|
|
18969
|
+
const { written, skipped } = await applyReportModeInstall(plan, { force: flags.force });
|
|
18970
|
+
return {
|
|
18971
|
+
json: JSON.stringify(installPayload2(plan, written, skipped, false), null, 2),
|
|
18972
|
+
exitCode: 0
|
|
18973
|
+
};
|
|
18974
|
+
} catch (error) {
|
|
18975
|
+
return reportModeError(caughtMessage(error));
|
|
18976
|
+
} finally {
|
|
18977
|
+
if (cleanup !== void 0) {
|
|
18978
|
+
await cleanup();
|
|
18979
|
+
}
|
|
18980
|
+
}
|
|
18981
|
+
};
|
|
18982
|
+
|
|
18983
|
+
// src/commands/piecesInteractive.ts
|
|
18984
|
+
var runListPath = async () => {
|
|
18985
|
+
const result = await runListPieces([]);
|
|
18986
|
+
process15.stdout.write(`${result.json}
|
|
18987
|
+
`);
|
|
18988
|
+
return result.exitCode;
|
|
18989
|
+
};
|
|
18990
|
+
var runDbPresetPath = async () => {
|
|
18991
|
+
const picked = await select({
|
|
18992
|
+
message: "Which database preset?",
|
|
18993
|
+
options: ALL_PRESETS.map((preset) => ({
|
|
18994
|
+
value: preset.id,
|
|
18995
|
+
label: preset.id,
|
|
18996
|
+
hint: preset.description === void 0 || preset.description === "" ? preset.id : preset.description
|
|
18997
|
+
}))
|
|
18998
|
+
});
|
|
18999
|
+
if (isCancel2(picked) || typeof picked !== "string") {
|
|
19000
|
+
cancel("Cancelled.");
|
|
19001
|
+
return 1;
|
|
19002
|
+
}
|
|
19003
|
+
const result = await runApplyPreset([picked, "--dry-run"]);
|
|
19004
|
+
process15.stdout.write(`${result.json}
|
|
19005
|
+
`);
|
|
19006
|
+
process15.stdout.write(
|
|
19007
|
+
`
|
|
19008
|
+
Dry-run shown. Apply for real with: vybekiit apply-preset ${picked}
|
|
19009
|
+
(Needs DATABASE_URL in the project.)
|
|
19010
|
+
`
|
|
19011
|
+
);
|
|
19012
|
+
return result.exitCode;
|
|
19013
|
+
};
|
|
19014
|
+
var runReportModePath = async () => {
|
|
19015
|
+
const result = await runAddReportMode(["--to=."]);
|
|
19016
|
+
process15.stdout.write(`${result.json}
|
|
19017
|
+
`);
|
|
19018
|
+
if (result.exitCode === 0) {
|
|
19019
|
+
process15.stdout.write(
|
|
19020
|
+
"\nInstalled Report Mode into the current folder. Wire any TODOs in the JSON report next.\n"
|
|
19021
|
+
);
|
|
19022
|
+
}
|
|
19023
|
+
return result.exitCode;
|
|
19024
|
+
};
|
|
19025
|
+
var runPageRecipePath = async () => {
|
|
19026
|
+
let cleanup;
|
|
19027
|
+
try {
|
|
19028
|
+
const resolved = await resolveKitSource();
|
|
19029
|
+
const { cleanup: resolvedCleanup, kitRoot } = resolved;
|
|
19030
|
+
cleanup = resolvedCleanup;
|
|
19031
|
+
const recipes = await loadPageRecipes(kitRoot);
|
|
19032
|
+
if (recipes.length === 0) {
|
|
19033
|
+
process15.stderr.write("No page recipes available from the kit source.\n");
|
|
19034
|
+
return 1;
|
|
19035
|
+
}
|
|
19036
|
+
const picked = await select({
|
|
19037
|
+
message: "Which page recipe?",
|
|
19038
|
+
options: recipes.map((recipe) => ({
|
|
19039
|
+
value: recipe.id,
|
|
19040
|
+
label: recipe.title,
|
|
19041
|
+
hint: `${recipe.groupLabel} \xB7 ${recipe.targetRoute}`
|
|
19042
|
+
}))
|
|
19043
|
+
});
|
|
19044
|
+
if (isCancel2(picked) || typeof picked !== "string") {
|
|
19045
|
+
cancel("Cancelled.");
|
|
19046
|
+
return 1;
|
|
19047
|
+
}
|
|
19048
|
+
const result = await runAddPageRecipe([picked, "--to=."]);
|
|
19049
|
+
process15.stdout.write(`${result.json}
|
|
19050
|
+
`);
|
|
19051
|
+
if (result.exitCode === 0) {
|
|
19052
|
+
process15.stdout.write(
|
|
19053
|
+
`
|
|
19054
|
+
Installed "${picked}" into the current folder. Wire the TODOs in the JSON report next.
|
|
19055
|
+
`
|
|
19056
|
+
);
|
|
19057
|
+
}
|
|
19058
|
+
return result.exitCode;
|
|
19059
|
+
} catch (error) {
|
|
19060
|
+
const message = caughtMessage(error);
|
|
19061
|
+
process15.stderr.write(`${message}
|
|
19062
|
+
`);
|
|
19063
|
+
return 1;
|
|
19064
|
+
} finally {
|
|
19065
|
+
if (cleanup !== void 0) {
|
|
19066
|
+
await cleanup();
|
|
19067
|
+
}
|
|
19068
|
+
}
|
|
19069
|
+
};
|
|
19070
|
+
var runAddPiecesInteractive = async () => {
|
|
19071
|
+
if (!isInteractive()) {
|
|
19072
|
+
process15.stderr.write(
|
|
19073
|
+
"add requires arguments in non-interactive mode. Try: vybekiit list-pieces\n"
|
|
19074
|
+
);
|
|
19075
|
+
return 1;
|
|
19076
|
+
}
|
|
19077
|
+
const kind = await select({
|
|
19078
|
+
message: "What kind of ready piece?",
|
|
19079
|
+
options: [
|
|
19080
|
+
{
|
|
19081
|
+
value: "page-recipe",
|
|
18246
19082
|
label: "Page recipe (ready screen)",
|
|
18247
19083
|
hint: "Copy a full page into your app"
|
|
18248
19084
|
},
|
|
19085
|
+
{
|
|
19086
|
+
value: "report-mode",
|
|
19087
|
+
label: "Report Mode (point & fix overlay)",
|
|
19088
|
+
hint: "Add the dev-only inspect/report dock"
|
|
19089
|
+
},
|
|
18249
19090
|
{
|
|
18250
19091
|
value: "db",
|
|
18251
19092
|
label: "Database preset",
|
|
@@ -18258,7 +19099,7 @@ var runAddPiecesInteractive = async () => {
|
|
|
18258
19099
|
}
|
|
18259
19100
|
]
|
|
18260
19101
|
});
|
|
18261
|
-
if (
|
|
19102
|
+
if (isCancel2(kind) || typeof kind !== "string") {
|
|
18262
19103
|
cancel("Cancelled.");
|
|
18263
19104
|
return 1;
|
|
18264
19105
|
}
|
|
@@ -18268,11 +19109,14 @@ var runAddPiecesInteractive = async () => {
|
|
|
18268
19109
|
if (kind === "db") {
|
|
18269
19110
|
return runDbPresetPath();
|
|
18270
19111
|
}
|
|
19112
|
+
if (kind === "report-mode") {
|
|
19113
|
+
return runReportModePath();
|
|
19114
|
+
}
|
|
18271
19115
|
return runPageRecipePath();
|
|
18272
19116
|
};
|
|
18273
19117
|
|
|
18274
19118
|
// src/commands/planDataModelCmd.ts
|
|
18275
|
-
import { readFile as
|
|
19119
|
+
import { readFile as readFile17 } from "fs/promises";
|
|
18276
19120
|
var PROVIDERS = [
|
|
18277
19121
|
"supabase",
|
|
18278
19122
|
"neon",
|
|
@@ -18302,7 +19146,7 @@ var runPlanDataModel = async (args) => {
|
|
|
18302
19146
|
};
|
|
18303
19147
|
}
|
|
18304
19148
|
try {
|
|
18305
|
-
const raw = await
|
|
19149
|
+
const raw = await readFile17(inputPath, "utf8");
|
|
18306
19150
|
const parsed = JSON.parse(raw);
|
|
18307
19151
|
const { entities } = parsed;
|
|
18308
19152
|
if (entities === void 0 || entities.length === 0) {
|
|
@@ -18328,9 +19172,9 @@ var runPlanDataModel = async (args) => {
|
|
|
18328
19172
|
};
|
|
18329
19173
|
|
|
18330
19174
|
// src/commands/planReadiness.ts
|
|
18331
|
-
import { access as
|
|
18332
|
-
import { join as
|
|
18333
|
-
import
|
|
19175
|
+
import { access as access13 } from "fs/promises";
|
|
19176
|
+
import { join as join34 } from "path";
|
|
19177
|
+
import process16 from "process";
|
|
18334
19178
|
var FEATURES = [
|
|
18335
19179
|
"sign-in",
|
|
18336
19180
|
"payments",
|
|
@@ -18342,13 +19186,13 @@ var FEATURES = [
|
|
|
18342
19186
|
var resolveFeatureName = (value) => FEATURES.find((feature) => feature === value);
|
|
18343
19187
|
var pathExists7 = async (path) => {
|
|
18344
19188
|
try {
|
|
18345
|
-
await
|
|
19189
|
+
await access13(path);
|
|
18346
19190
|
return true;
|
|
18347
19191
|
} catch {
|
|
18348
19192
|
return false;
|
|
18349
19193
|
}
|
|
18350
19194
|
};
|
|
18351
|
-
var runPlanReadiness = async (args, cwd =
|
|
19195
|
+
var runPlanReadiness = async (args, cwd = process16.cwd()) => {
|
|
18352
19196
|
const [featureArg, templateArg] = args;
|
|
18353
19197
|
const feature = featureArg === void 0 ? void 0 : resolveFeatureName(featureArg);
|
|
18354
19198
|
if (feature === void 0) {
|
|
@@ -18374,7 +19218,7 @@ var runPlanReadiness = async (args, cwd = process14.cwd()) => {
|
|
|
18374
19218
|
exitCode: 1
|
|
18375
19219
|
};
|
|
18376
19220
|
}
|
|
18377
|
-
const hasBackend = await pathExists7(
|
|
19221
|
+
const hasBackend = await pathExists7(join34(cwd, "backend", "package.json"));
|
|
18378
19222
|
const hasWeb = inferProjectSurfaceSync(cwd).template === "web";
|
|
18379
19223
|
const plan = planFeatureReadiness({
|
|
18380
19224
|
template,
|
|
@@ -18417,16 +19261,16 @@ var runPlanSetup = (args) => {
|
|
|
18417
19261
|
};
|
|
18418
19262
|
|
|
18419
19263
|
// src/commands/renderAgentLayer.ts
|
|
18420
|
-
import { mkdir as
|
|
18421
|
-
import { dirname as
|
|
18422
|
-
import
|
|
19264
|
+
import { mkdir as mkdir10, writeFile as writeFile12 } from "fs/promises";
|
|
19265
|
+
import { dirname as dirname13, join as join35 } from "path";
|
|
19266
|
+
import process17 from "process";
|
|
18423
19267
|
var writeBuyerSkillStubs = async (cwd, template, skillContents) => {
|
|
18424
19268
|
const stubs = planBuyerSkillStubOutputs(template, skillContents);
|
|
18425
19269
|
await Promise.all(
|
|
18426
19270
|
stubs.map(async (stub) => {
|
|
18427
|
-
const absolute =
|
|
18428
|
-
await
|
|
18429
|
-
await
|
|
19271
|
+
const absolute = join35(cwd, stub.stubPath);
|
|
19272
|
+
await mkdir10(dirname13(absolute), { recursive: true });
|
|
19273
|
+
await writeFile12(absolute, stub.content, "utf8");
|
|
18430
19274
|
})
|
|
18431
19275
|
);
|
|
18432
19276
|
return stubs.map((stub) => stub.stubPath);
|
|
@@ -18441,7 +19285,7 @@ var resolveRenderTemplate = async (cwd, templateArg) => {
|
|
|
18441
19285
|
}
|
|
18442
19286
|
return "web";
|
|
18443
19287
|
};
|
|
18444
|
-
var runRenderAgentLayer = async (cwd =
|
|
19288
|
+
var runRenderAgentLayer = async (cwd = process17.cwd(), templateArg) => {
|
|
18445
19289
|
const template = await resolveRenderTemplate(cwd, templateArg);
|
|
18446
19290
|
const { contents, present } = await loadAgentLayerRenderInputs(cwd);
|
|
18447
19291
|
const skillContents = await listBuyerSkillContents(cwd);
|
|
@@ -18464,22 +19308,22 @@ var runRenderAgentLayer = async (cwd = process15.cwd(), templateArg) => {
|
|
|
18464
19308
|
};
|
|
18465
19309
|
|
|
18466
19310
|
// src/commands/setup.ts
|
|
18467
|
-
import
|
|
19311
|
+
import process27 from "process";
|
|
18468
19312
|
|
|
18469
19313
|
// src/doctor/gate.ts
|
|
18470
|
-
import { spawnSync } from "child_process";
|
|
18471
|
-
import
|
|
18472
|
-
var { org: GATE_ORG, repos: GATE_REPOS } = readGateIdentity(
|
|
19314
|
+
import { spawnSync as spawnSync2 } from "child_process";
|
|
19315
|
+
import process18 from "process";
|
|
19316
|
+
var { org: GATE_ORG, repos: GATE_REPOS } = readGateIdentity(process18.env);
|
|
18473
19317
|
var SITE_URL = (() => {
|
|
18474
|
-
const value =
|
|
19318
|
+
const value = process18.env.VYBEKIIT_SITE_URL;
|
|
18475
19319
|
if (value !== void 0 && value.trim() !== "") {
|
|
18476
19320
|
return value;
|
|
18477
19321
|
}
|
|
18478
19322
|
return "https://vybekiit.com";
|
|
18479
19323
|
})();
|
|
18480
|
-
var ghSucceeds = (args) =>
|
|
19324
|
+
var ghSucceeds = (args) => spawnSync2("gh", [...args], { stdio: "ignore" }).status === 0;
|
|
18481
19325
|
var isOrgMember = () => {
|
|
18482
|
-
const result =
|
|
19326
|
+
const result = spawnSync2("gh", ["api", `user/memberships/orgs/${GATE_ORG}`, "--jq", ".state"], {
|
|
18483
19327
|
encoding: "utf8"
|
|
18484
19328
|
});
|
|
18485
19329
|
const stdout = result.stdout === void 0 ? "" : result.stdout;
|
|
@@ -18487,7 +19331,7 @@ var isOrgMember = () => {
|
|
|
18487
19331
|
};
|
|
18488
19332
|
var hasRepoAccess = () => GATE_REPOS.some((repo) => ghSucceeds(["api", `repos/${GATE_ORG}/${repo}`]));
|
|
18489
19333
|
var checkAccess = () => {
|
|
18490
|
-
if (
|
|
19334
|
+
if (process18.env.VYBEKIIT_SKIP_GATE === "1") {
|
|
18491
19335
|
return { allowed: true, reason: "skipped", org: GATE_ORG };
|
|
18492
19336
|
}
|
|
18493
19337
|
if (!ghSucceeds(["--version"])) {
|
|
@@ -18519,61 +19363,35 @@ var ensureAccessOrExit = () => {
|
|
|
18519
19363
|
if (result.allowed) {
|
|
18520
19364
|
return true;
|
|
18521
19365
|
}
|
|
18522
|
-
|
|
19366
|
+
process18.stderr.write(`${formatGateFailure(result)}
|
|
18523
19367
|
`);
|
|
18524
19368
|
return false;
|
|
18525
19369
|
};
|
|
18526
19370
|
|
|
18527
19371
|
// src/doctor/run.ts
|
|
18528
|
-
import { spawnSync as
|
|
18529
|
-
import
|
|
18530
|
-
|
|
18531
|
-
// ../packages/reportMode/src/deeplink.ts
|
|
18532
|
-
var inferVybeAssistant = (options) => {
|
|
18533
|
-
if (options.cursorSession) {
|
|
18534
|
-
return "cursor";
|
|
18535
|
-
}
|
|
18536
|
-
if (options.claudeInstalled) {
|
|
18537
|
-
return "claude";
|
|
18538
|
-
}
|
|
18539
|
-
if (options.codexInstalled) {
|
|
18540
|
-
return "codex";
|
|
18541
|
-
}
|
|
18542
|
-
if (options.kiroInstalled === true) {
|
|
18543
|
-
return "kiro";
|
|
18544
|
-
}
|
|
18545
|
-
if (options.kimiInstalled === true) {
|
|
18546
|
-
return "kimi";
|
|
18547
|
-
}
|
|
18548
|
-
if (options.grokInstalled === true) {
|
|
18549
|
-
return "grok";
|
|
18550
|
-
}
|
|
18551
|
-
if (options.devinInstalled === true) {
|
|
18552
|
-
return "devin";
|
|
18553
|
-
}
|
|
18554
|
-
return null;
|
|
18555
|
-
};
|
|
19372
|
+
import { spawnSync as spawnSync8 } from "child_process";
|
|
19373
|
+
import process21 from "process";
|
|
18556
19374
|
|
|
18557
19375
|
// src/doctor/agentExperience.ts
|
|
18558
|
-
import { spawnSync as
|
|
19376
|
+
import { spawnSync as spawnSync4 } from "child_process";
|
|
18559
19377
|
import { accessSync, constants } from "fs";
|
|
18560
19378
|
import { homedir } from "os";
|
|
18561
|
-
import { join as
|
|
19379
|
+
import { join as join37 } from "path";
|
|
18562
19380
|
|
|
18563
19381
|
// src/doctor/mcpWire.ts
|
|
18564
|
-
import { spawnSync as
|
|
19382
|
+
import { spawnSync as spawnSync3 } from "child_process";
|
|
18565
19383
|
import { existsSync as existsSync7, mkdirSync as mkdirSync8, readFileSync as readFileSync7, writeFileSync as writeFileSync5 } from "fs";
|
|
18566
|
-
import { dirname as
|
|
19384
|
+
import { dirname as dirname14, join as join36 } from "path";
|
|
18567
19385
|
var CATALOG_RELATIVE_PATHS = [
|
|
18568
|
-
|
|
19386
|
+
join36(".claude", "mcp", "mcp-servers.json"),
|
|
18569
19387
|
"mcp-servers.json"
|
|
18570
19388
|
];
|
|
18571
19389
|
var defaultCommandExists = (command) => {
|
|
18572
|
-
const version =
|
|
19390
|
+
const version = spawnSync3(command, ["--version"], { stdio: "ignore" });
|
|
18573
19391
|
if (version.status === 0) {
|
|
18574
19392
|
return true;
|
|
18575
19393
|
}
|
|
18576
|
-
const help =
|
|
19394
|
+
const help = spawnSync3(command, ["--help"], { stdio: "ignore" });
|
|
18577
19395
|
return help.status === 0 || help.error === void 0;
|
|
18578
19396
|
};
|
|
18579
19397
|
var createDefaultMcpWireDeps = () => ({
|
|
@@ -18587,7 +19405,7 @@ var createDefaultMcpWireDeps = () => ({
|
|
|
18587
19405
|
},
|
|
18588
19406
|
commandExists: defaultCommandExists,
|
|
18589
19407
|
spawn: (command, args, options) => {
|
|
18590
|
-
const result =
|
|
19408
|
+
const result = spawnSync3(command, [...args], {
|
|
18591
19409
|
stdio: "ignore",
|
|
18592
19410
|
cwd: options?.cwd,
|
|
18593
19411
|
timeout: 8e3,
|
|
@@ -18597,8 +19415,8 @@ var createDefaultMcpWireDeps = () => ({
|
|
|
18597
19415
|
}
|
|
18598
19416
|
});
|
|
18599
19417
|
var findMcpCatalogPath = (cwd, pathExists9) => {
|
|
18600
|
-
for (const
|
|
18601
|
-
const absolute =
|
|
19418
|
+
for (const relative6 of CATALOG_RELATIVE_PATHS) {
|
|
19419
|
+
const absolute = join36(cwd, relative6);
|
|
18602
19420
|
if (pathExists9(absolute)) {
|
|
18603
19421
|
return absolute;
|
|
18604
19422
|
}
|
|
@@ -18745,7 +19563,7 @@ var writeMergedMcpConfig = (configPath, core, deps) => {
|
|
|
18745
19563
|
if (added.length === 0 && deps.pathExists(configPath)) {
|
|
18746
19564
|
return { written: false, added: [] };
|
|
18747
19565
|
}
|
|
18748
|
-
deps.mkdir(
|
|
19566
|
+
deps.mkdir(dirname14(configPath));
|
|
18749
19567
|
deps.writeFile(configPath, formatMcpServersConfig(config));
|
|
18750
19568
|
return { written: true, added };
|
|
18751
19569
|
};
|
|
@@ -18803,7 +19621,7 @@ var wireCoreMcps = (cwd, agents, deps = createDefaultMcpWireDeps()) => {
|
|
|
18803
19621
|
let anyFailure = false;
|
|
18804
19622
|
for (const agent of capable) {
|
|
18805
19623
|
if (agent.id === "cursor") {
|
|
18806
|
-
const configPath =
|
|
19624
|
+
const configPath = join36(cwd, ".cursor", "mcp.json");
|
|
18807
19625
|
try {
|
|
18808
19626
|
const { written, added } = writeMergedMcpConfig(configPath, core, deps);
|
|
18809
19627
|
agentsWired.push("cursor");
|
|
@@ -18821,7 +19639,7 @@ var wireCoreMcps = (cwd, agents, deps = createDefaultMcpWireDeps()) => {
|
|
|
18821
19639
|
continue;
|
|
18822
19640
|
}
|
|
18823
19641
|
if (agent.id === "claude-code") {
|
|
18824
|
-
const configPath =
|
|
19642
|
+
const configPath = join36(cwd, ".mcp.json");
|
|
18825
19643
|
try {
|
|
18826
19644
|
const { written, added } = writeMergedMcpConfig(configPath, core, deps);
|
|
18827
19645
|
if (written && added.length > 0) {
|
|
@@ -18859,11 +19677,11 @@ var wireCoreMcps = (cwd, agents, deps = createDefaultMcpWireDeps()) => {
|
|
|
18859
19677
|
|
|
18860
19678
|
// src/doctor/agentExperience.ts
|
|
18861
19679
|
var defaultCommandExists2 = (command) => {
|
|
18862
|
-
const version =
|
|
19680
|
+
const version = spawnSync4(command, ["--version"], { stdio: "ignore" });
|
|
18863
19681
|
if (version.status === 0) {
|
|
18864
19682
|
return true;
|
|
18865
19683
|
}
|
|
18866
|
-
const help =
|
|
19684
|
+
const help = spawnSync4(command, ["--help"], { stdio: "ignore" });
|
|
18867
19685
|
return help.status === 0 || help.error === void 0;
|
|
18868
19686
|
};
|
|
18869
19687
|
var defaultPathExists = (path) => {
|
|
@@ -18910,22 +19728,22 @@ var detectPresentAgents = (cwd, deps = createDefaultAgentExperienceDeps()) => {
|
|
|
18910
19728
|
add("gemini");
|
|
18911
19729
|
}
|
|
18912
19730
|
const home = homedir();
|
|
18913
|
-
if (deps.pathExists(
|
|
19731
|
+
if (deps.pathExists(join37(home, ".claude"))) {
|
|
18914
19732
|
add("claude-code");
|
|
18915
19733
|
}
|
|
18916
|
-
if (deps.pathExists(
|
|
19734
|
+
if (deps.pathExists(join37(home, ".codex"))) {
|
|
18917
19735
|
add("codex");
|
|
18918
19736
|
}
|
|
18919
|
-
if (deps.pathExists(
|
|
19737
|
+
if (deps.pathExists(join37(home, ".cursor"))) {
|
|
18920
19738
|
add("cursor");
|
|
18921
19739
|
}
|
|
18922
|
-
if (deps.pathExists(
|
|
19740
|
+
if (deps.pathExists(join37(cwd, ".claude"))) {
|
|
18923
19741
|
add("claude-code");
|
|
18924
19742
|
}
|
|
18925
|
-
if (deps.pathExists(
|
|
19743
|
+
if (deps.pathExists(join37(cwd, ".cursor"))) {
|
|
18926
19744
|
add("cursor");
|
|
18927
19745
|
}
|
|
18928
|
-
if (deps.pathExists(
|
|
19746
|
+
if (deps.pathExists(join37(cwd, "AGENTS.md"))) {
|
|
18929
19747
|
add("codex");
|
|
18930
19748
|
}
|
|
18931
19749
|
if (found.size === 0) {
|
|
@@ -18951,7 +19769,7 @@ var runAgentExperience = async (cwd, options, deps = createDefaultAgentExperienc
|
|
|
18951
19769
|
let ok = true;
|
|
18952
19770
|
const names = agents.map((agent) => agent.name).join(", ");
|
|
18953
19771
|
lines.push(`\u2713 agents detected - ${names}`);
|
|
18954
|
-
const hasProjectSkills = deps.pathExists(
|
|
19772
|
+
const hasProjectSkills = deps.pathExists(join37(cwd, ".agents", "skills")) || deps.pathExists(join37(cwd, "platform-skills.manifest.json")) || deps.pathExists(join37(cwd, "skills-lock.json"));
|
|
18955
19773
|
if (hasProjectSkills) {
|
|
18956
19774
|
try {
|
|
18957
19775
|
await deps.ensureProjectSkillLinks(cwd);
|
|
@@ -19003,17 +19821,17 @@ var runAgentExperience = async (cwd, options, deps = createDefaultAgentExperienc
|
|
|
19003
19821
|
);
|
|
19004
19822
|
}
|
|
19005
19823
|
}
|
|
19006
|
-
const kitRootAgentMcp =
|
|
19007
|
-
const surfaceAgentMcp =
|
|
19824
|
+
const kitRootAgentMcp = join37(cwd, "packages", "agentMcp");
|
|
19825
|
+
const surfaceAgentMcp = join37(cwd, "..", "..", "packages", "agentMcp");
|
|
19008
19826
|
const hasKitRootMcp = deps.pathExists(kitRootAgentMcp);
|
|
19009
19827
|
const hasSurfaceMcp = deps.pathExists(surfaceAgentMcp);
|
|
19010
19828
|
if (hasKitRootMcp || hasSurfaceMcp) {
|
|
19011
19829
|
try {
|
|
19012
19830
|
const layout = hasKitRootMcp ? "kit-root" : "surface";
|
|
19013
19831
|
const template = layout === "kit-root" ? ["web", "mobile", "extension", "backend", "spa"].find(
|
|
19014
|
-
(name) => deps.pathExists(
|
|
19832
|
+
(name) => deps.pathExists(join37(cwd, "templates", name))
|
|
19015
19833
|
) : void 0;
|
|
19016
|
-
const configPaths = [
|
|
19834
|
+
const configPaths = [join37(cwd, ".cursor", "mcp.json"), join37(cwd, ".mcp.json")];
|
|
19017
19835
|
for (const configPath of configPaths) {
|
|
19018
19836
|
await writeFirstPartyMcpConfigFile(
|
|
19019
19837
|
configPath,
|
|
@@ -19035,7 +19853,7 @@ var runAgentExperience = async (cwd, options, deps = createDefaultAgentExperienc
|
|
|
19035
19853
|
|
|
19036
19854
|
// src/doctor/assetsValidate.ts
|
|
19037
19855
|
import { existsSync as existsSync8, readFileSync as readFileSync8 } from "fs";
|
|
19038
|
-
import { join as
|
|
19856
|
+
import { join as join38 } from "path";
|
|
19039
19857
|
var ASSET_SURFACE_DIRS = {
|
|
19040
19858
|
web: "public",
|
|
19041
19859
|
spa: "public",
|
|
@@ -19056,9 +19874,9 @@ var OPTIMIZE_FILE_CANDIDATES = [
|
|
|
19056
19874
|
"scripts/optimize.ts"
|
|
19057
19875
|
];
|
|
19058
19876
|
var createDefaultAssetsValidateDeps = (cwd) => ({
|
|
19059
|
-
exists: (relativePath) => existsSync8(
|
|
19877
|
+
exists: (relativePath) => existsSync8(join38(cwd, relativePath)),
|
|
19060
19878
|
readUtf8: (relativePath) => {
|
|
19061
|
-
const absolute =
|
|
19879
|
+
const absolute = join38(cwd, relativePath);
|
|
19062
19880
|
if (!existsSync8(absolute)) {
|
|
19063
19881
|
return null;
|
|
19064
19882
|
}
|
|
@@ -19197,35 +20015,35 @@ var verifyAssetsPipeline = (cwd, surface = inferProjectSurfaceSync(cwd), deps =
|
|
|
19197
20015
|
|
|
19198
20016
|
// src/global/globalPaths.ts
|
|
19199
20017
|
import { homedir as homedir2 } from "os";
|
|
19200
|
-
import { dirname as
|
|
19201
|
-
import
|
|
20018
|
+
import { dirname as dirname15, join as join39 } from "path";
|
|
20019
|
+
import process19 from "process";
|
|
19202
20020
|
import { fileURLToPath as fileURLToPath7 } from "url";
|
|
19203
|
-
var MODULE_DIR =
|
|
20021
|
+
var MODULE_DIR = dirname15(fileURLToPath7(import.meta.url));
|
|
19204
20022
|
var resolveConfigDir = () => {
|
|
19205
|
-
const override =
|
|
20023
|
+
const override = process19.env.CLAUDE_CONFIG_DIR;
|
|
19206
20024
|
if (override !== void 0 && override.trim() !== "") {
|
|
19207
20025
|
return override.trim();
|
|
19208
20026
|
}
|
|
19209
|
-
return
|
|
20027
|
+
return join39(homedir2(), ".claude");
|
|
19210
20028
|
};
|
|
19211
20029
|
var resolveGlobalPaths = (configDir = resolveConfigDir()) => ({
|
|
19212
20030
|
configDir,
|
|
19213
|
-
skillsDir:
|
|
19214
|
-
commandsDir:
|
|
19215
|
-
memoryFile:
|
|
19216
|
-
settingsFile:
|
|
20031
|
+
skillsDir: join39(configDir, "skills"),
|
|
20032
|
+
commandsDir: join39(configDir, "commands"),
|
|
20033
|
+
memoryFile: join39(configDir, "CLAUDE.md"),
|
|
20034
|
+
settingsFile: join39(configDir, "settings.json"),
|
|
19217
20035
|
// At runtime this module is inlined into dist/bin.js, so MODULE_DIR is <install>/dist
|
|
19218
20036
|
// and the payload sits beside it at dist/global-skills.
|
|
19219
|
-
bundledSkillsDir:
|
|
20037
|
+
bundledSkillsDir: join39(MODULE_DIR, "global-skills")
|
|
19220
20038
|
});
|
|
19221
20039
|
|
|
19222
20040
|
// src/global/globalStatus.ts
|
|
19223
|
-
import { readFile as
|
|
19224
|
-
import { join as
|
|
20041
|
+
import { readFile as readFile18, stat as stat2 } from "fs/promises";
|
|
20042
|
+
import { join as join41 } from "path";
|
|
19225
20043
|
|
|
19226
20044
|
// src/global/managedSkills.ts
|
|
19227
|
-
import { readdir as
|
|
19228
|
-
import { join as
|
|
20045
|
+
import { readdir as readdir9, stat } from "fs/promises";
|
|
20046
|
+
import { join as join40 } from "path";
|
|
19229
20047
|
var GLOBAL_SKILL_SAMPLE_SIZE = 5;
|
|
19230
20048
|
var MANAGED_SKILL_MARKER = ".vybekiit-managed";
|
|
19231
20049
|
var exists = async (path) => {
|
|
@@ -19238,13 +20056,13 @@ var exists = async (path) => {
|
|
|
19238
20056
|
};
|
|
19239
20057
|
var listManagedSkillNames = async (skillsDir) => {
|
|
19240
20058
|
try {
|
|
19241
|
-
const entries = await
|
|
20059
|
+
const entries = await readdir9(skillsDir, { withFileTypes: true });
|
|
19242
20060
|
const names = [];
|
|
19243
20061
|
for (const entry of entries) {
|
|
19244
20062
|
if (!entry.isDirectory()) {
|
|
19245
20063
|
continue;
|
|
19246
20064
|
}
|
|
19247
|
-
if (await exists(
|
|
20065
|
+
if (await exists(join40(skillsDir, entry.name, MANAGED_SKILL_MARKER))) {
|
|
19248
20066
|
names.push(entry.name);
|
|
19249
20067
|
}
|
|
19250
20068
|
}
|
|
@@ -19259,6 +20077,7 @@ var sampleManagedSkillNames = (names, size = GLOBAL_SKILL_SAMPLE_SIZE) => {
|
|
|
19259
20077
|
return [];
|
|
19260
20078
|
}
|
|
19261
20079
|
const preferred = [
|
|
20080
|
+
"feedback",
|
|
19262
20081
|
"onboarding",
|
|
19263
20082
|
"plan-my-idea",
|
|
19264
20083
|
"setup-payments",
|
|
@@ -19284,13 +20103,13 @@ var exists2 = async (path) => {
|
|
|
19284
20103
|
var readGlobalStatus = async (paths) => {
|
|
19285
20104
|
let hasMemory = false;
|
|
19286
20105
|
try {
|
|
19287
|
-
hasMemory = (await
|
|
20106
|
+
hasMemory = (await readFile18(paths.memoryFile, "utf8")).includes("BEGIN VYBEKIIT");
|
|
19288
20107
|
} catch {
|
|
19289
20108
|
hasMemory = false;
|
|
19290
20109
|
}
|
|
19291
20110
|
const managed = await listManagedSkillNames(paths.skillsDir);
|
|
19292
20111
|
return {
|
|
19293
|
-
hasCommand: await exists2(
|
|
20112
|
+
hasCommand: await exists2(join41(paths.commandsDir, "vybekiit.md")),
|
|
19294
20113
|
hasMemory,
|
|
19295
20114
|
skillCount: managed.length,
|
|
19296
20115
|
skillSample: sampleManagedSkillNames(managed)
|
|
@@ -19309,9 +20128,9 @@ var formatGlobalStatus = (status) => {
|
|
|
19309
20128
|
};
|
|
19310
20129
|
|
|
19311
20130
|
// src/doctor/codexConfig.ts
|
|
19312
|
-
import { access as
|
|
20131
|
+
import { access as access14, mkdir as mkdir11, readFile as readFile19, writeFile as writeFile13 } from "fs/promises";
|
|
19313
20132
|
import { homedir as homedir3 } from "os";
|
|
19314
|
-
import { join as
|
|
20133
|
+
import { join as join42 } from "path";
|
|
19315
20134
|
var FEATURES_BLOCK = ["[features]", "skills = true"].join("\n");
|
|
19316
20135
|
var FEATURES_SKILLS_ENABLED_PATTERN = /\[features\][\s\S]*?\bskills\s*=\s*true\b/m;
|
|
19317
20136
|
var FEATURES_BLOCK_PATTERN = /(\[features\][^[]*)/m;
|
|
@@ -19320,10 +20139,10 @@ var SKILLS_LINE_PATTERN = /\bskills\s*=\s*.*/m;
|
|
|
19320
20139
|
var codexConfigPath = () => {
|
|
19321
20140
|
const configuredHome = process.env.CODEX_HOME;
|
|
19322
20141
|
if (configuredHome !== void 0 && configuredHome.trim() !== "") {
|
|
19323
|
-
return
|
|
20142
|
+
return join42(configuredHome.trim(), "config.toml");
|
|
19324
20143
|
}
|
|
19325
|
-
const home =
|
|
19326
|
-
return
|
|
20144
|
+
const home = join42(homedir3(), ".codex");
|
|
20145
|
+
return join42(home, "config.toml");
|
|
19327
20146
|
};
|
|
19328
20147
|
var upsertFeaturesSkills = (content) => {
|
|
19329
20148
|
if (FEATURES_SKILLS_ENABLED_PATTERN.test(content)) {
|
|
@@ -19349,10 +20168,10 @@ ${FEATURES_BLOCK}
|
|
|
19349
20168
|
};
|
|
19350
20169
|
var ensureCodexSkillsEnabled = async () => {
|
|
19351
20170
|
const path = codexConfigPath();
|
|
19352
|
-
await
|
|
20171
|
+
await mkdir11(join42(path, ".."), { recursive: true });
|
|
19353
20172
|
let previous = "";
|
|
19354
20173
|
try {
|
|
19355
|
-
previous = await
|
|
20174
|
+
previous = await readFile19(path, "utf8");
|
|
19356
20175
|
} catch (error) {
|
|
19357
20176
|
if (!(error instanceof Error && "code" in error) || error.code !== "ENOENT") {
|
|
19358
20177
|
throw error;
|
|
@@ -19362,13 +20181,13 @@ var ensureCodexSkillsEnabled = async () => {
|
|
|
19362
20181
|
if (next === previous) {
|
|
19363
20182
|
return { updated: false, path };
|
|
19364
20183
|
}
|
|
19365
|
-
await
|
|
20184
|
+
await writeFile13(path, next, "utf8");
|
|
19366
20185
|
return { updated: true, path };
|
|
19367
20186
|
};
|
|
19368
20187
|
|
|
19369
20188
|
// src/doctor/kitWorkspaceHealth.ts
|
|
19370
20189
|
import { existsSync as existsSync9, readdirSync as readdirSync2, readFileSync as readFileSync9, statSync as statSync2 } from "fs";
|
|
19371
|
-
import { join as
|
|
20190
|
+
import { join as join43 } from "path";
|
|
19372
20191
|
var readPackageJsonSafe = (packageJsonPath) => {
|
|
19373
20192
|
if (!existsSync9(packageJsonPath)) {
|
|
19374
20193
|
return null;
|
|
@@ -19401,7 +20220,7 @@ var listPackageRelDirs = (packagesRoot) => {
|
|
|
19401
20220
|
const top = readdirSync2(packagesRoot);
|
|
19402
20221
|
const rels = [];
|
|
19403
20222
|
for (const entry of top) {
|
|
19404
|
-
const abs =
|
|
20223
|
+
const abs = join43(packagesRoot, entry);
|
|
19405
20224
|
let isDir = false;
|
|
19406
20225
|
try {
|
|
19407
20226
|
isDir = statSync2(abs).isDirectory();
|
|
@@ -19411,7 +20230,7 @@ var listPackageRelDirs = (packagesRoot) => {
|
|
|
19411
20230
|
if (!isDir) {
|
|
19412
20231
|
continue;
|
|
19413
20232
|
}
|
|
19414
|
-
if (existsSync9(
|
|
20233
|
+
if (existsSync9(join43(abs, "package.json"))) {
|
|
19415
20234
|
rels.push(entry);
|
|
19416
20235
|
continue;
|
|
19417
20236
|
}
|
|
@@ -19422,10 +20241,10 @@ var listPackageRelDirs = (packagesRoot) => {
|
|
|
19422
20241
|
continue;
|
|
19423
20242
|
}
|
|
19424
20243
|
for (const child of nested) {
|
|
19425
|
-
const childAbs =
|
|
20244
|
+
const childAbs = join43(abs, child);
|
|
19426
20245
|
try {
|
|
19427
|
-
if (statSync2(childAbs).isDirectory() && existsSync9(
|
|
19428
|
-
rels.push(
|
|
20246
|
+
if (statSync2(childAbs).isDirectory() && existsSync9(join43(childAbs, "package.json"))) {
|
|
20247
|
+
rels.push(join43(entry, child));
|
|
19429
20248
|
}
|
|
19430
20249
|
} catch {
|
|
19431
20250
|
}
|
|
@@ -19434,15 +20253,15 @@ var listPackageRelDirs = (packagesRoot) => {
|
|
|
19434
20253
|
return rels;
|
|
19435
20254
|
};
|
|
19436
20255
|
var findMissingDistPackages = (cwd) => {
|
|
19437
|
-
const packagesRoot =
|
|
20256
|
+
const packagesRoot = join43(cwd, "packages");
|
|
19438
20257
|
const missing = [];
|
|
19439
20258
|
for (const relDir of listPackageRelDirs(packagesRoot)) {
|
|
19440
|
-
const packageDir =
|
|
19441
|
-
const pkg = readPackageJsonSafe(
|
|
20259
|
+
const packageDir = join43(packagesRoot, relDir);
|
|
20260
|
+
const pkg = readPackageJsonSafe(join43(packageDir, "package.json"));
|
|
19442
20261
|
if (pkg === null || !packageExpectsDist(pkg)) {
|
|
19443
20262
|
continue;
|
|
19444
20263
|
}
|
|
19445
|
-
if (!existsSync9(
|
|
20264
|
+
if (!existsSync9(join43(packageDir, "dist"))) {
|
|
19446
20265
|
const name = typeof pkg.name === "string" ? pkg.name : relDir;
|
|
19447
20266
|
missing.push({ name, relDir });
|
|
19448
20267
|
}
|
|
@@ -19450,7 +20269,7 @@ var findMissingDistPackages = (cwd) => {
|
|
|
19450
20269
|
return missing;
|
|
19451
20270
|
};
|
|
19452
20271
|
var verifyKitWorkspaceHealth = (cwd) => {
|
|
19453
|
-
const packagesRoot =
|
|
20272
|
+
const packagesRoot = join43(cwd, "packages");
|
|
19454
20273
|
if (!existsSync9(packagesRoot)) {
|
|
19455
20274
|
return { ok: true, lines: [] };
|
|
19456
20275
|
}
|
|
@@ -19468,7 +20287,7 @@ var verifyKitWorkspaceHealth = (cwd) => {
|
|
|
19468
20287
|
);
|
|
19469
20288
|
}
|
|
19470
20289
|
const buildRoots = ["tsconfig.base.json", "scripts/lib/tsupWorkspaceAliases.mjs"];
|
|
19471
|
-
const missingRoots = buildRoots.filter((rel) => !existsSync9(
|
|
20290
|
+
const missingRoots = buildRoots.filter((rel) => !existsSync9(join43(cwd, rel)));
|
|
19472
20291
|
if (missingRoots.length > 0 && missing.length > 0) {
|
|
19473
20292
|
lines.push(
|
|
19474
20293
|
`\u2717 Kit is also missing rebuild helpers (${missingRoots.join(", ")}). Re-run \`vybekiit create app\` with a current CLI so build roots ship with the workspace.`
|
|
@@ -19528,12 +20347,12 @@ var verifyMobilePublishReadiness = (platform, env, probe) => {
|
|
|
19528
20347
|
}
|
|
19529
20348
|
return { ok, lines };
|
|
19530
20349
|
};
|
|
19531
|
-
var createDefaultCommandProbe = (
|
|
20350
|
+
var createDefaultCommandProbe = (spawnSync10) => ({
|
|
19532
20351
|
succeeds(command, args) {
|
|
19533
|
-
return
|
|
20352
|
+
return spawnSync10(command, args, { encoding: "utf8", stdio: "pipe" }).status === 0;
|
|
19534
20353
|
},
|
|
19535
20354
|
output(command, args) {
|
|
19536
|
-
const result =
|
|
20355
|
+
const result = spawnSync10(command, args, { encoding: "utf8", stdio: "pipe" });
|
|
19537
20356
|
return `${result.stdout}
|
|
19538
20357
|
${result.stderr}`.trim();
|
|
19539
20358
|
}
|
|
@@ -19617,11 +20436,11 @@ var mergeDoctorTools = (providerTools, nativeTools) => {
|
|
|
19617
20436
|
|
|
19618
20437
|
// src/doctor/perfReadiness.ts
|
|
19619
20438
|
import { existsSync as existsSync10, readFileSync as readFileSync10 } from "fs";
|
|
19620
|
-
import { join as
|
|
20439
|
+
import { join as join44 } from "path";
|
|
19621
20440
|
var createDefaultPerfReadinessDeps = (cwd) => ({
|
|
19622
|
-
exists: (relativePath) => existsSync10(
|
|
20441
|
+
exists: (relativePath) => existsSync10(join44(cwd, relativePath)),
|
|
19623
20442
|
readUtf8: (relativePath) => {
|
|
19624
|
-
const absolute =
|
|
20443
|
+
const absolute = join44(cwd, relativePath);
|
|
19625
20444
|
if (!existsSync10(absolute)) {
|
|
19626
20445
|
return null;
|
|
19627
20446
|
}
|
|
@@ -19754,17 +20573,17 @@ var reportFor = (reports, name) => reports.find((r) => r.tool === name);
|
|
|
19754
20573
|
|
|
19755
20574
|
// src/doctor/platformSkills.ts
|
|
19756
20575
|
import { existsSync as existsSync11, readFileSync as readFileSync11 } from "fs";
|
|
19757
|
-
import { join as
|
|
19758
|
-
import
|
|
20576
|
+
import { join as join45 } from "path";
|
|
20577
|
+
import process20 from "process";
|
|
19759
20578
|
var readManifest = (cwd) => {
|
|
19760
|
-
const path =
|
|
20579
|
+
const path = join45(cwd, "platform-skills.manifest.json");
|
|
19761
20580
|
if (!existsSync11(path)) {
|
|
19762
20581
|
return null;
|
|
19763
20582
|
}
|
|
19764
20583
|
return JSON.parse(readFileSync11(path, "utf8"));
|
|
19765
20584
|
};
|
|
19766
20585
|
var readSkillsLock = (cwd) => {
|
|
19767
|
-
const path =
|
|
20586
|
+
const path = join45(cwd, "skills-lock.json");
|
|
19768
20587
|
if (!existsSync11(path)) {
|
|
19769
20588
|
return null;
|
|
19770
20589
|
}
|
|
@@ -19774,7 +20593,7 @@ var readSkillsLock = (cwd) => {
|
|
|
19774
20593
|
return null;
|
|
19775
20594
|
}
|
|
19776
20595
|
};
|
|
19777
|
-
var skillFileExists = (cwd, name) => existsSync11(
|
|
20596
|
+
var skillFileExists = (cwd, name) => existsSync11(join45(cwd, ".agents", "skills", name, "SKILL.md"));
|
|
19778
20597
|
var verifyPlatformSkills = (cwd) => {
|
|
19779
20598
|
const manifest = readManifest(cwd);
|
|
19780
20599
|
if (manifest === null) {
|
|
@@ -19798,7 +20617,7 @@ var verifyPlatformSkills = (cwd) => {
|
|
|
19798
20617
|
};
|
|
19799
20618
|
};
|
|
19800
20619
|
var templateLabelForPlatformSkills = (cwd) => {
|
|
19801
|
-
if (!existsSync11(
|
|
20620
|
+
if (!existsSync11(join45(cwd, "platform-skills.manifest.json"))) {
|
|
19802
20621
|
return null;
|
|
19803
20622
|
}
|
|
19804
20623
|
return inferProjectSurfaceSync(cwd).template;
|
|
@@ -19808,7 +20627,7 @@ var formatPlatformSkillsReport = (report) => {
|
|
|
19808
20627
|
return [];
|
|
19809
20628
|
}
|
|
19810
20629
|
const lines = [];
|
|
19811
|
-
const lockPath =
|
|
20630
|
+
const lockPath = join45(process20.cwd(), "skills-lock.json");
|
|
19812
20631
|
if (existsSync11(lockPath)) {
|
|
19813
20632
|
try {
|
|
19814
20633
|
const lock = JSON.parse(readFileSync11(lockPath, "utf8"));
|
|
@@ -19865,10 +20684,10 @@ var formatProductSurfaceHints = (env) => {
|
|
|
19865
20684
|
|
|
19866
20685
|
// src/doctor/projectHealth.ts
|
|
19867
20686
|
import { existsSync as existsSync12, readFileSync as readFileSync12 } from "fs";
|
|
19868
|
-
import { join as
|
|
20687
|
+
import { join as join46 } from "path";
|
|
19869
20688
|
var GITIGNORE_ENV_LINE_PATTERN = /^\.env/m;
|
|
19870
20689
|
var gitignoreCoversEnv = (cwd) => {
|
|
19871
|
-
const path =
|
|
20690
|
+
const path = join46(cwd, ".gitignore");
|
|
19872
20691
|
if (!existsSync12(path)) {
|
|
19873
20692
|
return false;
|
|
19874
20693
|
}
|
|
@@ -19876,7 +20695,7 @@ var gitignoreCoversEnv = (cwd) => {
|
|
|
19876
20695
|
return GITIGNORE_ENV_LINE_PATTERN.test(content) || content.includes(".env\n") || content.includes(".env\r\n");
|
|
19877
20696
|
};
|
|
19878
20697
|
var cursorignoreCoversEnv = (cwd) => {
|
|
19879
|
-
const path =
|
|
20698
|
+
const path = join46(cwd, ".cursorignore");
|
|
19880
20699
|
if (!existsSync12(path)) {
|
|
19881
20700
|
return false;
|
|
19882
20701
|
}
|
|
@@ -19904,7 +20723,7 @@ var verifyProjectHealth = (cwd) => {
|
|
|
19904
20723
|
};
|
|
19905
20724
|
|
|
19906
20725
|
// src/doctor/railwayAgentSetup.ts
|
|
19907
|
-
import { spawnSync as
|
|
20726
|
+
import { spawnSync as spawnSync5 } from "child_process";
|
|
19908
20727
|
var isRailwayStackActive2 = (env) => isRailwayStackActive(env);
|
|
19909
20728
|
var verifyCoupledStack = (env) => {
|
|
19910
20729
|
const { HOSTING_PROVIDER } = parseEnv(hostingConfigSchema, env);
|
|
@@ -19932,7 +20751,7 @@ var runRailwayAgentSetup = (railwayInstalled, railwayAuthed) => {
|
|
|
19932
20751
|
message: "\u2192 Railway agent setup skipped - sign in with `railway login` first."
|
|
19933
20752
|
};
|
|
19934
20753
|
}
|
|
19935
|
-
const result =
|
|
20754
|
+
const result = spawnSync5("railway", ["setup", "agent", "-y"], {
|
|
19936
20755
|
stdio: "pipe",
|
|
19937
20756
|
encoding: "utf8"
|
|
19938
20757
|
});
|
|
@@ -19964,17 +20783,17 @@ var formatRailwayStackReport = (env, agentSetup) => {
|
|
|
19964
20783
|
};
|
|
19965
20784
|
|
|
19966
20785
|
// src/doctor/runNativeProjectSetup.ts
|
|
19967
|
-
import { spawnSync as
|
|
20786
|
+
import { spawnSync as spawnSync6 } from "child_process";
|
|
19968
20787
|
import { existsSync as existsSync13 } from "fs";
|
|
19969
|
-
import { join as
|
|
20788
|
+
import { join as join47 } from "path";
|
|
19970
20789
|
var runCommand = (options) => {
|
|
19971
20790
|
const { args, command, cwd, label, log } = options;
|
|
19972
20791
|
log.log(`[doctor] ${label}: ${command} ${args.join(" ")}`);
|
|
19973
|
-
const result =
|
|
20792
|
+
const result = spawnSync6(command, [...args], { cwd, stdio: "inherit" });
|
|
19974
20793
|
return result.status === 0;
|
|
19975
20794
|
};
|
|
19976
20795
|
var runExtensionSetup = (cwd, log) => {
|
|
19977
|
-
const wxtTypes =
|
|
20796
|
+
const wxtTypes = join47(cwd, ".wxt", "wxt.d.ts");
|
|
19978
20797
|
if (existsSync13(wxtTypes)) {
|
|
19979
20798
|
return ["\u2713 Extension - WXT types already generated."];
|
|
19980
20799
|
}
|
|
@@ -19993,7 +20812,7 @@ var runMobileSetup = (cwd, platform, log) => {
|
|
|
19993
20812
|
if (platform !== "darwin") {
|
|
19994
20813
|
return [];
|
|
19995
20814
|
}
|
|
19996
|
-
const podfile =
|
|
20815
|
+
const podfile = join47(cwd, "ios", "Podfile");
|
|
19997
20816
|
if (!existsSync13(podfile)) {
|
|
19998
20817
|
return [
|
|
19999
20818
|
"\u2192 Mobile - no `ios/` folder yet. Run `pnpm ios` (Simulator) or `npx expo prebuild --platform ios` before store builds."
|
|
@@ -20002,7 +20821,7 @@ var runMobileSetup = (cwd, platform, log) => {
|
|
|
20002
20821
|
const ok = runCommand({
|
|
20003
20822
|
log,
|
|
20004
20823
|
label: "installing iOS pods",
|
|
20005
|
-
cwd:
|
|
20824
|
+
cwd: join47(cwd, "ios"),
|
|
20006
20825
|
command: "pod",
|
|
20007
20826
|
args: ["install"]
|
|
20008
20827
|
});
|
|
@@ -20025,16 +20844,16 @@ var runNativeProjectSetup = (cwd, surface, platform, log = console) => {
|
|
|
20025
20844
|
};
|
|
20026
20845
|
|
|
20027
20846
|
// src/doctor/storageR2.ts
|
|
20028
|
-
import { spawnSync as
|
|
20847
|
+
import { spawnSync as spawnSync7 } from "child_process";
|
|
20029
20848
|
import { readFileSync as readFileSync13 } from "fs";
|
|
20030
|
-
import { join as
|
|
20849
|
+
import { join as join48 } from "path";
|
|
20031
20850
|
var R2_BUCKET_UNSAFE_PATTERN = /[^a-z0-9-]/g;
|
|
20032
20851
|
var R2_BUCKET_DASH_RUN_PATTERN = /-+/g;
|
|
20033
20852
|
var R2_BUCKET_EDGE_DASH_PATTERN = /^-|-$/g;
|
|
20034
20853
|
var sanitizeBucketName = (name) => name.toLowerCase().replace(R2_BUCKET_UNSAFE_PATTERN, "-").replace(R2_BUCKET_DASH_RUN_PATTERN, "-").replace(R2_BUCKET_EDGE_DASH_PATTERN, "").slice(0, 40);
|
|
20035
20854
|
var readProjectName = (cwd) => {
|
|
20036
20855
|
try {
|
|
20037
|
-
const pkg = JSON.parse(readFileSync13(
|
|
20856
|
+
const pkg = JSON.parse(readFileSync13(join48(cwd, "package.json"), "utf8"));
|
|
20038
20857
|
if (pkg.name !== void 0 && pkg.name !== "" && pkg.name !== "my-vybekiit-app") {
|
|
20039
20858
|
return sanitizeBucketName(pkg.name);
|
|
20040
20859
|
}
|
|
@@ -20042,7 +20861,7 @@ var readProjectName = (cwd) => {
|
|
|
20042
20861
|
}
|
|
20043
20862
|
return "vybekiit-app";
|
|
20044
20863
|
};
|
|
20045
|
-
var wranglerOk = (args) =>
|
|
20864
|
+
var wranglerOk = (args) => spawnSync7("wrangler", [...args], { stdio: "ignore" }).status === 0;
|
|
20046
20865
|
var createR2ApiToken = async (accountId, apiToken, bucketName) => {
|
|
20047
20866
|
const response = await fetch(
|
|
20048
20867
|
`https://api.cloudflare.com/client/v4/accounts/${accountId}/r2/tokens`,
|
|
@@ -20601,12 +21420,12 @@ var verifyPresetsDoctor = async (env) => {
|
|
|
20601
21420
|
|
|
20602
21421
|
// src/doctor/run.ts
|
|
20603
21422
|
var toPlatform = (platform) => platform === "darwin" || platform === "win32" || platform === "linux" ? platform : null;
|
|
20604
|
-
var
|
|
20605
|
-
var
|
|
21423
|
+
var isCursorSession2 = () => Boolean(process21.env.CURSOR_TRACE_ID || process21.env.CURSOR_SESSION_ID);
|
|
21424
|
+
var succeeds2 = (command, args) => spawnSync8(command, [...args], { stdio: "ignore" }).status === 0;
|
|
20606
21425
|
var errorCode = (error) => error !== void 0 && "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
20607
21426
|
var runInstall = (action, log) => {
|
|
20608
21427
|
log.log(`[doctor] setting up ${action.tool}: ${action.command} ${action.args.join(" ")}`);
|
|
20609
|
-
const result =
|
|
21428
|
+
const result = spawnSync8(action.command, [...action.args], { stdio: "inherit" });
|
|
20610
21429
|
if (errorCode(result.error) === "ENOENT") {
|
|
20611
21430
|
return action.requires ? { ok: false, missingRequirement: action.requires } : { ok: false };
|
|
20612
21431
|
}
|
|
@@ -20630,7 +21449,7 @@ var buildReport = (tool, presence, installs) => {
|
|
|
20630
21449
|
if (tool.auth === void 0) {
|
|
20631
21450
|
return { tool: tool.name, purpose: tool.purpose, installed: true, authed: null };
|
|
20632
21451
|
}
|
|
20633
|
-
const authed =
|
|
21452
|
+
const authed = succeeds2(tool.auth.command, tool.auth.args);
|
|
20634
21453
|
return {
|
|
20635
21454
|
tool: tool.name,
|
|
20636
21455
|
purpose: tool.purpose,
|
|
@@ -20654,7 +21473,7 @@ var runToolchain = (platform, surface, env, log) => {
|
|
|
20654
21473
|
const toolchain = mergeAgentAndProviderTools(providerAndNative);
|
|
20655
21474
|
const presence = toolchain.map((tool) => ({
|
|
20656
21475
|
tool: tool.name,
|
|
20657
|
-
present:
|
|
21476
|
+
present: succeeds2(tool.name, tool.versionArgs)
|
|
20658
21477
|
}));
|
|
20659
21478
|
const installs = /* @__PURE__ */ new Map();
|
|
20660
21479
|
for (const action of planInstall(platform, presence, toolchain)) {
|
|
@@ -20670,7 +21489,7 @@ var verifyMobilePublishing = (platform, env, mobile, log) => {
|
|
|
20670
21489
|
if (!mobile) {
|
|
20671
21490
|
return true;
|
|
20672
21491
|
}
|
|
20673
|
-
const report = verifyMobilePublishReadiness(platform, env, createDefaultCommandProbe(
|
|
21492
|
+
const report = verifyMobilePublishReadiness(platform, env, createDefaultCommandProbe(spawnSync8));
|
|
20674
21493
|
writeLines(log, report.lines);
|
|
20675
21494
|
return report.ok;
|
|
20676
21495
|
};
|
|
@@ -20729,15 +21548,15 @@ var writeReportModeAssistant = (options) => {
|
|
|
20729
21548
|
}
|
|
20730
21549
|
};
|
|
20731
21550
|
var runDoctor = async (log = console) => {
|
|
20732
|
-
const platform = toPlatform(
|
|
21551
|
+
const platform = toPlatform(process21.platform);
|
|
20733
21552
|
if (platform === null) {
|
|
20734
|
-
log.error(`[doctor] This operating system (${
|
|
21553
|
+
log.error(`[doctor] This operating system (${process21.platform}) isn't supported yet.`);
|
|
20735
21554
|
return 1;
|
|
20736
21555
|
}
|
|
20737
|
-
const cwd =
|
|
21556
|
+
const cwd = process21.cwd();
|
|
20738
21557
|
const surface = inferProjectSurfaceSync(cwd);
|
|
20739
|
-
const env = mergeEnv(
|
|
20740
|
-
const cursorSession =
|
|
21558
|
+
const env = mergeEnv(process21.env, loadEnvFile2(cwd));
|
|
21559
|
+
const cursorSession = isCursorSession2();
|
|
20741
21560
|
if (cursorSession) {
|
|
20742
21561
|
log.log("\u2713 Cursor - you're in Cursor; no separate agent install needed.");
|
|
20743
21562
|
}
|
|
@@ -20777,13 +21596,57 @@ var runDoctor = async (log = console) => {
|
|
|
20777
21596
|
});
|
|
20778
21597
|
};
|
|
20779
21598
|
|
|
21599
|
+
// src/global/installState.ts
|
|
21600
|
+
import { mkdir as mkdir12, readFile as readFile20, writeFile as writeFile14 } from "fs/promises";
|
|
21601
|
+
import { join as join49 } from "path";
|
|
21602
|
+
var INSTALL_STATE_FILENAME = ".vybekiit-install.json";
|
|
21603
|
+
var installStatePath = (configDir) => join49(configDir, INSTALL_STATE_FILENAME);
|
|
21604
|
+
var readInstallState = async (configDir) => {
|
|
21605
|
+
try {
|
|
21606
|
+
const raw = await readFile20(installStatePath(configDir), "utf8");
|
|
21607
|
+
const parsed = JSON.parse(raw);
|
|
21608
|
+
if (typeof parsed.version !== "string" || parsed.version === "") {
|
|
21609
|
+
return null;
|
|
21610
|
+
}
|
|
21611
|
+
if (typeof parsed.updatedAt !== "string" || parsed.updatedAt === "") {
|
|
21612
|
+
return null;
|
|
21613
|
+
}
|
|
21614
|
+
const firstAppPath = typeof parsed.firstAppPath === "string" && parsed.firstAppPath !== "" ? parsed.firstAppPath : void 0;
|
|
21615
|
+
return {
|
|
21616
|
+
version: parsed.version,
|
|
21617
|
+
updatedAt: parsed.updatedAt,
|
|
21618
|
+
...firstAppPath === void 0 ? {} : { firstAppPath }
|
|
21619
|
+
};
|
|
21620
|
+
} catch {
|
|
21621
|
+
return null;
|
|
21622
|
+
}
|
|
21623
|
+
};
|
|
21624
|
+
var writeInstallState = async (configDir, version, options = {}, now = () => /* @__PURE__ */ new Date()) => {
|
|
21625
|
+
const previous = await readInstallState(configDir);
|
|
21626
|
+
let firstAppPath = previous?.firstAppPath;
|
|
21627
|
+
if (options.clearFirstAppPath === true) {
|
|
21628
|
+
firstAppPath = void 0;
|
|
21629
|
+
} else if (options.firstAppPath !== void 0 && options.firstAppPath !== "") {
|
|
21630
|
+
firstAppPath = options.firstAppPath;
|
|
21631
|
+
}
|
|
21632
|
+
const state = {
|
|
21633
|
+
version,
|
|
21634
|
+
updatedAt: now().toISOString(),
|
|
21635
|
+
...firstAppPath === void 0 ? {} : { firstAppPath }
|
|
21636
|
+
};
|
|
21637
|
+
await mkdir12(configDir, { recursive: true });
|
|
21638
|
+
await writeFile14(installStatePath(configDir), `${JSON.stringify(state, null, 2)}
|
|
21639
|
+
`, "utf8");
|
|
21640
|
+
return state;
|
|
21641
|
+
};
|
|
21642
|
+
|
|
20780
21643
|
// src/global/runGlobalInstall.ts
|
|
20781
|
-
import
|
|
20782
|
-
import { confirm, isCancel as
|
|
21644
|
+
import process24 from "process";
|
|
21645
|
+
import { confirm as confirm2, isCancel as isCancel3 } from "@clack/prompts";
|
|
20783
21646
|
|
|
20784
21647
|
// src/global/awareness.ts
|
|
20785
|
-
import { mkdir as
|
|
20786
|
-
import { dirname as
|
|
21648
|
+
import { mkdir as mkdir13, readFile as readFile21, writeFile as writeFile15 } from "fs/promises";
|
|
21649
|
+
import { dirname as dirname16 } from "path";
|
|
20787
21650
|
var BEGIN_MARKER = "<!-- BEGIN VYBEKIIT (managed by `vybekiit setup`) -->";
|
|
20788
21651
|
var END_MARKER = "<!-- END VYBEKIIT -->";
|
|
20789
21652
|
var LEADING_NEWLINE = /^\n/;
|
|
@@ -20796,8 +21659,10 @@ Do this now, briefly:
|
|
|
20796
21659
|
1. Say: "\u2705 VybeKiit is active \u2014 you have its skills and browser automation in every project."
|
|
20797
21660
|
2. Read the skill names under ~/.claude/skills and name 4-5 useful ones (for example: onboarding,
|
|
20798
21661
|
plan-my-idea, setup-payments, add-signin, go-live).
|
|
20799
|
-
3. If there is no app in the current folder yet,
|
|
20800
|
-
|
|
21662
|
+
3. If there is no app in the current folder yet, check for ~/vybekiit-app (first-install default).
|
|
21663
|
+
If it exists, offer to open that folder and run onboarding. Otherwise offer
|
|
21664
|
+
\`vybekiit create app --web\`. If they are already in an app folder, ask what they want next.
|
|
21665
|
+
4. Mention Report mode once if they are in an app: Option+Shift+R (Alt+Shift+R on Windows).
|
|
20801
21666
|
|
|
20802
21667
|
Keep it short and friendly. Do not dump the whole skill list.
|
|
20803
21668
|
`;
|
|
@@ -20806,7 +21671,10 @@ var buildMemoryBlock = () => [
|
|
|
20806
21671
|
"## VybeKiit is active on this machine",
|
|
20807
21672
|
"",
|
|
20808
21673
|
"VybeKiit is installed globally: its skills live in `~/.claude/skills`, and the `playwright`",
|
|
20809
|
-
"and `context7` MCP servers are registered (browser automation
|
|
21674
|
+
"and `context7` MCP servers are registered (browser automation, live library docs). Key-gated",
|
|
21675
|
+
"servers like `sentry`, `github`, and `stripe` register once their API key is set (run",
|
|
21676
|
+
"`vybekiit env wizard`). Inside a scaffolded app (`vybekiit create app`), a project-scoped",
|
|
21677
|
+
"`vybekiit` MCP server adds the kit tools (UI catalog, skills, browser automations).",
|
|
20810
21678
|
"",
|
|
20811
21679
|
"At the start of a session in any project, briefly tell the user VybeKiit is available, and use",
|
|
20812
21680
|
"its skills (onboarding, plan-my-idea, setup-payments, add-signin, go-live, harden, \u2026) when they",
|
|
@@ -20831,7 +21699,7 @@ ${block}`;
|
|
|
20831
21699
|
};
|
|
20832
21700
|
var readOrEmpty = async (path) => {
|
|
20833
21701
|
try {
|
|
20834
|
-
return await
|
|
21702
|
+
return await readFile21(path, "utf8");
|
|
20835
21703
|
} catch (error) {
|
|
20836
21704
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") {
|
|
20837
21705
|
return "";
|
|
@@ -20843,8 +21711,8 @@ var writeIfChanged = async (path, next, previous) => {
|
|
|
20843
21711
|
if (next === previous) {
|
|
20844
21712
|
return false;
|
|
20845
21713
|
}
|
|
20846
|
-
await
|
|
20847
|
-
await
|
|
21714
|
+
await mkdir13(dirname16(path), { recursive: true });
|
|
21715
|
+
await writeFile15(path, next, "utf8");
|
|
20848
21716
|
return true;
|
|
20849
21717
|
};
|
|
20850
21718
|
var STATUSLINE_BADGE = "\u25C6 vybekiit";
|
|
@@ -20903,20 +21771,20 @@ var installAwareness = async (paths) => {
|
|
|
20903
21771
|
};
|
|
20904
21772
|
|
|
20905
21773
|
// src/global/cliVersion.ts
|
|
20906
|
-
import { readFile as
|
|
20907
|
-
import { dirname as
|
|
21774
|
+
import { readFile as readFile22 } from "fs/promises";
|
|
21775
|
+
import { dirname as dirname17, join as join50 } from "path";
|
|
20908
21776
|
import { fileURLToPath as fileURLToPath8 } from "url";
|
|
20909
|
-
var MODULE_DIR2 =
|
|
21777
|
+
var MODULE_DIR2 = dirname17(fileURLToPath8(import.meta.url));
|
|
20910
21778
|
var readCliVersion = async () => {
|
|
20911
21779
|
const candidates = [
|
|
20912
21780
|
// Published layout: dist/*.js → cli/package.json
|
|
20913
|
-
|
|
21781
|
+
join50(MODULE_DIR2, "..", "package.json"),
|
|
20914
21782
|
// Source layout: src/global/*.ts → cli/package.json
|
|
20915
|
-
|
|
21783
|
+
join50(MODULE_DIR2, "..", "..", "package.json")
|
|
20916
21784
|
];
|
|
20917
21785
|
for (const candidate of candidates) {
|
|
20918
21786
|
try {
|
|
20919
|
-
const raw = await
|
|
21787
|
+
const raw = await readFile22(candidate, "utf8");
|
|
20920
21788
|
const parsed = JSON.parse(raw);
|
|
20921
21789
|
if (parsed.version !== void 0 && parsed.version !== "") {
|
|
20922
21790
|
return parsed.version;
|
|
@@ -21004,15 +21872,14 @@ var formatEntitlementBlock = (result) => {
|
|
|
21004
21872
|
};
|
|
21005
21873
|
|
|
21006
21874
|
// src/global/installGlobalMcp.ts
|
|
21007
|
-
import
|
|
21875
|
+
import process22 from "process";
|
|
21008
21876
|
var ZERO_CONFIG = [
|
|
21009
21877
|
{
|
|
21010
21878
|
name: "playwright",
|
|
21011
21879
|
transport: "stdio",
|
|
21012
|
-
command: ["npx", "-y", "@
|
|
21880
|
+
command: ["npx", "-y", "@playwright/mcp@latest"]
|
|
21013
21881
|
},
|
|
21014
|
-
{ name: "context7", transport: "stdio", command: ["npx", "-y", "@upstash/context7-mcp@latest"] }
|
|
21015
|
-
{ name: "sentry", transport: "sse", command: ["https://mcp.sentry.dev/sse"] }
|
|
21882
|
+
{ name: "context7", transport: "stdio", command: ["npx", "-y", "@upstash/context7-mcp@latest"] }
|
|
21016
21883
|
];
|
|
21017
21884
|
var KEY_GATED = [
|
|
21018
21885
|
{
|
|
@@ -21024,32 +21891,28 @@ var KEY_GATED = [
|
|
|
21024
21891
|
{
|
|
21025
21892
|
name: "supabase",
|
|
21026
21893
|
transport: "stdio",
|
|
21027
|
-
command: ["npx", "-y", "supabase
|
|
21894
|
+
command: ["npx", "-y", "@supabase/mcp-server-supabase@latest"],
|
|
21028
21895
|
envKeys: ["SUPABASE_ACCESS_TOKEN"]
|
|
21029
21896
|
},
|
|
21030
|
-
{
|
|
21031
|
-
name: "vercel",
|
|
21032
|
-
transport: "stdio",
|
|
21033
|
-
command: ["npx", "-y", "@vercel/mcp"],
|
|
21034
|
-
envKeys: ["VERCEL_TOKEN"]
|
|
21035
|
-
},
|
|
21036
21897
|
{
|
|
21037
21898
|
name: "stripe",
|
|
21038
21899
|
transport: "stdio",
|
|
21039
|
-
command: ["npx", "-y", "@stripe/mcp"],
|
|
21900
|
+
command: ["npx", "-y", "@stripe/mcp", "--tools=all"],
|
|
21040
21901
|
envKeys: ["STRIPE_SECRET_KEY"]
|
|
21041
21902
|
},
|
|
21042
21903
|
{
|
|
21043
|
-
|
|
21904
|
+
// Sentry's hosted server is OAuth-only (would sit "failed to connect" until the user
|
|
21905
|
+
// authenticates in a browser); its stdio server takes a token, so gate on that like the rest.
|
|
21906
|
+
name: "sentry",
|
|
21044
21907
|
transport: "stdio",
|
|
21045
|
-
command: ["npx", "-y", "@
|
|
21046
|
-
envKeys: ["
|
|
21908
|
+
command: ["npx", "-y", "@sentry/mcp-server@latest"],
|
|
21909
|
+
envKeys: ["SENTRY_ACCESS_TOKEN"]
|
|
21047
21910
|
},
|
|
21048
21911
|
{
|
|
21049
21912
|
name: "figma",
|
|
21050
21913
|
transport: "stdio",
|
|
21051
|
-
command: ["npx", "-y", "
|
|
21052
|
-
envKeys: ["
|
|
21914
|
+
command: ["npx", "-y", "figma-developer-mcp", "--stdio"],
|
|
21915
|
+
envKeys: ["FIGMA_API_KEY"]
|
|
21053
21916
|
},
|
|
21054
21917
|
{
|
|
21055
21918
|
name: "resend",
|
|
@@ -21076,7 +21939,7 @@ var KEY_GATED = [
|
|
|
21076
21939
|
envKeys: ["TAVILY_API_KEY"]
|
|
21077
21940
|
}
|
|
21078
21941
|
];
|
|
21079
|
-
var defaultDeps2 = { exec: makeExec("claude"), env:
|
|
21942
|
+
var defaultDeps2 = { exec: makeExec("claude"), env: process22.env };
|
|
21080
21943
|
var buildAddArgs = (def, env) => {
|
|
21081
21944
|
if (def.transport === "sse") {
|
|
21082
21945
|
const [url = ""] = def.command;
|
|
@@ -21137,8 +22000,9 @@ var installGlobalMcp = async (deps = defaultDeps2) => {
|
|
|
21137
22000
|
};
|
|
21138
22001
|
|
|
21139
22002
|
// src/global/installGlobalSkills.ts
|
|
21140
|
-
import { cp as cp5, mkdir as
|
|
21141
|
-
import { join as
|
|
22003
|
+
import { cp as cp5, mkdir as mkdir14, readdir as readdir10, readFile as readFile23, rm as rm5, stat as stat3, writeFile as writeFile16 } from "fs/promises";
|
|
22004
|
+
import { join as join51 } from "path";
|
|
22005
|
+
var REQUIRED_MANAGED_SKILLS = ["feedback"];
|
|
21142
22006
|
var pathExists8 = async (path) => {
|
|
21143
22007
|
try {
|
|
21144
22008
|
await stat3(path);
|
|
@@ -21149,14 +22013,14 @@ var pathExists8 = async (path) => {
|
|
|
21149
22013
|
};
|
|
21150
22014
|
var listBundledSkills = async (sourceDir) => {
|
|
21151
22015
|
try {
|
|
21152
|
-
const manifest = JSON.parse(await
|
|
22016
|
+
const manifest = JSON.parse(await readFile23(join51(sourceDir, "manifest.json"), "utf8"));
|
|
21153
22017
|
if (Array.isArray(manifest.skills)) {
|
|
21154
22018
|
return [...manifest.skills];
|
|
21155
22019
|
}
|
|
21156
22020
|
} catch {
|
|
21157
22021
|
}
|
|
21158
22022
|
try {
|
|
21159
|
-
const entries = await
|
|
22023
|
+
const entries = await readdir10(sourceDir, { withFileTypes: true });
|
|
21160
22024
|
return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
21161
22025
|
} catch {
|
|
21162
22026
|
return [];
|
|
@@ -21164,54 +22028,285 @@ var listBundledSkills = async (sourceDir) => {
|
|
|
21164
22028
|
};
|
|
21165
22029
|
var installGlobalSkills = async (paths, sourceDir = paths.bundledSkillsDir) => {
|
|
21166
22030
|
const names = await listBundledSkills(sourceDir);
|
|
21167
|
-
|
|
22031
|
+
for (const requiredSkill of REQUIRED_MANAGED_SKILLS) {
|
|
22032
|
+
if (!names.includes(requiredSkill)) {
|
|
22033
|
+
throw new Error(`Bundled skills are incomplete: ${requiredSkill} is missing.`);
|
|
22034
|
+
}
|
|
22035
|
+
}
|
|
22036
|
+
await mkdir14(paths.skillsDir, { recursive: true });
|
|
21168
22037
|
const installed = [];
|
|
21169
22038
|
const skipped = [];
|
|
21170
22039
|
for (const name of names) {
|
|
21171
|
-
const dest =
|
|
22040
|
+
const dest = join51(paths.skillsDir, name);
|
|
21172
22041
|
if (await pathExists8(dest)) {
|
|
21173
|
-
if (!await pathExists8(
|
|
22042
|
+
if (!await pathExists8(join51(dest, MANAGED_SKILL_MARKER))) {
|
|
21174
22043
|
skipped.push(name);
|
|
21175
22044
|
continue;
|
|
21176
22045
|
}
|
|
21177
22046
|
await rm5(dest, { recursive: true, force: true });
|
|
21178
22047
|
}
|
|
21179
|
-
await cp5(
|
|
21180
|
-
await
|
|
22048
|
+
await cp5(join51(sourceDir, name), dest, { recursive: true });
|
|
22049
|
+
await writeFile16(join51(dest, MANAGED_SKILL_MARKER), "", "utf8");
|
|
21181
22050
|
installed.push(name);
|
|
21182
22051
|
}
|
|
21183
22052
|
return { installed, skipped, path: paths.skillsDir };
|
|
21184
22053
|
};
|
|
21185
22054
|
|
|
21186
|
-
// src/global/
|
|
21187
|
-
import {
|
|
21188
|
-
import {
|
|
21189
|
-
|
|
21190
|
-
|
|
21191
|
-
|
|
22055
|
+
// src/global/runSessionOne.ts
|
|
22056
|
+
import { spawn as spawn2 } from "child_process";
|
|
22057
|
+
import { access as access15, readdir as readdir11 } from "fs/promises";
|
|
22058
|
+
import { homedir as homedir4 } from "os";
|
|
22059
|
+
import { join as join52 } from "path";
|
|
22060
|
+
import process23 from "process";
|
|
22061
|
+
var DEFAULT_FIRST_APP_DIR_NAME = "vybekiit-app";
|
|
22062
|
+
var SESSION_ONE_SEED_PROMPT = "Set up my app.";
|
|
22063
|
+
var shouldSkipSessionOne = (args, env = process23.env) => {
|
|
22064
|
+
if (args.includes("--skip-session-one") || args.includes("--skip-first-app")) {
|
|
22065
|
+
return true;
|
|
22066
|
+
}
|
|
22067
|
+
const flag = env.VYBEKIIT_SKIP_SESSION_ONE;
|
|
22068
|
+
return flag === "1" || flag === "true" || flag === "yes";
|
|
22069
|
+
};
|
|
22070
|
+
var resolveFirstAppPath = (deps) => {
|
|
22071
|
+
const override = deps.env.VYBEKIIT_FIRST_APP_DIR?.trim();
|
|
22072
|
+
if (override !== void 0 && override !== "") {
|
|
22073
|
+
return override.startsWith("/") || /^[A-Za-z]:[\\/]/.test(override) ? override : join52(deps.homeDir(), override);
|
|
22074
|
+
}
|
|
22075
|
+
return join52(deps.homeDir(), DEFAULT_FIRST_APP_DIR_NAME);
|
|
22076
|
+
};
|
|
22077
|
+
var defaultPathExists2 = async (path) => {
|
|
21192
22078
|
try {
|
|
21193
|
-
|
|
21194
|
-
|
|
21195
|
-
|
|
21196
|
-
|
|
21197
|
-
|
|
21198
|
-
|
|
21199
|
-
|
|
22079
|
+
await access15(path);
|
|
22080
|
+
return true;
|
|
22081
|
+
} catch {
|
|
22082
|
+
return false;
|
|
22083
|
+
}
|
|
22084
|
+
};
|
|
22085
|
+
var defaultIsEmptyDir = async (path) => {
|
|
22086
|
+
try {
|
|
22087
|
+
const entries = await readdir11(path);
|
|
22088
|
+
return entries.length === 0;
|
|
22089
|
+
} catch {
|
|
22090
|
+
return true;
|
|
22091
|
+
}
|
|
22092
|
+
};
|
|
22093
|
+
var defaultRunCommand = async (cwd, bin, args) => await new Promise((resolve13) => {
|
|
22094
|
+
const child = spawn2(bin, [...args], {
|
|
22095
|
+
cwd,
|
|
22096
|
+
stdio: ["ignore", "inherit", "inherit"],
|
|
22097
|
+
env: process23.env
|
|
22098
|
+
});
|
|
22099
|
+
child.on("error", () => {
|
|
22100
|
+
resolve13({ code: 127 });
|
|
22101
|
+
});
|
|
22102
|
+
child.on("close", (code) => {
|
|
22103
|
+
resolve13({ code: code ?? 1 });
|
|
22104
|
+
});
|
|
22105
|
+
});
|
|
22106
|
+
var defaultStartDetached = (cwd, bin, args) => {
|
|
22107
|
+
try {
|
|
22108
|
+
const child = spawn2(bin, [...args], {
|
|
22109
|
+
cwd,
|
|
22110
|
+
detached: true,
|
|
22111
|
+
stdio: "ignore",
|
|
22112
|
+
env: process23.env
|
|
22113
|
+
});
|
|
22114
|
+
child.unref();
|
|
22115
|
+
return true;
|
|
22116
|
+
} catch {
|
|
22117
|
+
return false;
|
|
22118
|
+
}
|
|
22119
|
+
};
|
|
22120
|
+
var openClaudeWithSeed = async (appPath, prompt, platform = process23.platform) => {
|
|
22121
|
+
if (platform === "darwin") {
|
|
22122
|
+
const shellCommand = `cd ${JSON.stringify(appPath)} && claude ${JSON.stringify(prompt)}`;
|
|
22123
|
+
const osa = makeExec("osascript");
|
|
22124
|
+
const result = await osa([
|
|
22125
|
+
"-e",
|
|
22126
|
+
`tell application "Terminal" to do script ${JSON.stringify(shellCommand)}`
|
|
22127
|
+
]);
|
|
22128
|
+
if (result.code === 0) {
|
|
22129
|
+
return true;
|
|
21200
22130
|
}
|
|
21201
|
-
|
|
22131
|
+
}
|
|
22132
|
+
try {
|
|
22133
|
+
const child = spawn2("claude", [prompt], {
|
|
22134
|
+
cwd: appPath,
|
|
22135
|
+
detached: true,
|
|
22136
|
+
stdio: "ignore",
|
|
22137
|
+
env: process23.env
|
|
22138
|
+
});
|
|
22139
|
+
child.unref();
|
|
22140
|
+
return true;
|
|
21202
22141
|
} catch {
|
|
21203
|
-
return
|
|
22142
|
+
return false;
|
|
21204
22143
|
}
|
|
21205
22144
|
};
|
|
21206
|
-
var
|
|
21207
|
-
const
|
|
21208
|
-
|
|
21209
|
-
|
|
22145
|
+
var defaultResolvePnpm = async () => {
|
|
22146
|
+
const pnpm = makeExec("pnpm");
|
|
22147
|
+
const version = await pnpm(["--version"]);
|
|
22148
|
+
if (version.code === 0) {
|
|
22149
|
+
return ["pnpm"];
|
|
22150
|
+
}
|
|
22151
|
+
const corepack = makeExec("corepack");
|
|
22152
|
+
const enabled = await corepack(["enable"]);
|
|
22153
|
+
if (enabled.code === 0) {
|
|
22154
|
+
const prepared = await corepack(["prepare", "pnpm@10.33.2", "--activate"]);
|
|
22155
|
+
if (prepared.code === 0) {
|
|
22156
|
+
const again = await pnpm(["--version"]);
|
|
22157
|
+
if (again.code === 0) {
|
|
22158
|
+
return ["pnpm"];
|
|
22159
|
+
}
|
|
22160
|
+
}
|
|
22161
|
+
}
|
|
22162
|
+
const npx = makeExec("npx");
|
|
22163
|
+
const npxCheck = await npx(["-y", "pnpm@10.33.2", "--version"]);
|
|
22164
|
+
if (npxCheck.code === 0) {
|
|
22165
|
+
return ["npx", "-y", "pnpm@10.33.2"];
|
|
22166
|
+
}
|
|
22167
|
+
return null;
|
|
22168
|
+
};
|
|
22169
|
+
var defaultDeps3 = () => ({
|
|
22170
|
+
createApp: runCreateApp,
|
|
22171
|
+
pathExists: defaultPathExists2,
|
|
22172
|
+
isEmptyDir: defaultIsEmptyDir,
|
|
22173
|
+
runCommand: defaultRunCommand,
|
|
22174
|
+
startDetached: defaultStartDetached,
|
|
22175
|
+
openClaude: (appPath, prompt) => openClaudeWithSeed(appPath, prompt, process23.platform),
|
|
22176
|
+
resolvePnpm: defaultResolvePnpm,
|
|
22177
|
+
homeDir: homedir4,
|
|
22178
|
+
env: process23.env,
|
|
22179
|
+
platform: process23.platform
|
|
22180
|
+
});
|
|
22181
|
+
var formatSessionOneLines = (result) => {
|
|
22182
|
+
if (result.appPath === null) {
|
|
22183
|
+
return [
|
|
22184
|
+
"",
|
|
22185
|
+
"Session #1: could not create your first app automatically.",
|
|
22186
|
+
" Run: npx vybekiit create app --web",
|
|
22187
|
+
' Then open that folder in Claude Code and say: "Set up my app."',
|
|
22188
|
+
""
|
|
22189
|
+
];
|
|
22190
|
+
}
|
|
22191
|
+
const lines = [
|
|
22192
|
+
"",
|
|
22193
|
+
result.created ? `\u2705 Your first web app is ready at ${result.appPath}` : `\u2705 Using your app at ${result.appPath}`
|
|
22194
|
+
];
|
|
22195
|
+
if (result.depsInstalled) {
|
|
22196
|
+
lines.push(" \u2022 Dependencies installed");
|
|
22197
|
+
} else {
|
|
22198
|
+
lines.push(" \u2022 Dependencies still need install \u2014 in that folder run: pnpm install");
|
|
22199
|
+
}
|
|
22200
|
+
if (result.packagesBuilt) {
|
|
22201
|
+
lines.push(" \u2022 Kit packages built for local preview");
|
|
22202
|
+
} else if (result.depsInstalled) {
|
|
22203
|
+
lines.push(" \u2022 Kit packages still need a build \u2014 in that folder run: pnpm build:packages");
|
|
22204
|
+
}
|
|
22205
|
+
if (result.devStarted) {
|
|
22206
|
+
lines.push(" \u2022 Preview starting at http://localhost:3000");
|
|
22207
|
+
} else if (result.depsInstalled && result.packagesBuilt) {
|
|
22208
|
+
lines.push(" \u2022 Preview not started \u2014 in that folder run: pnpm dev");
|
|
22209
|
+
}
|
|
22210
|
+
if (result.claudeOpened) {
|
|
22211
|
+
lines.push(' \u2022 Claude Code opening with: "Set up my app."');
|
|
22212
|
+
} else {
|
|
22213
|
+
lines.push(' \u2022 Open Claude Code in that folder and say: "Set up my app."');
|
|
22214
|
+
lines.push(` cd ${result.appPath} && claude "Set up my app."`);
|
|
22215
|
+
}
|
|
22216
|
+
lines.push(
|
|
22217
|
+
"",
|
|
22218
|
+
"Report mode is built in \u2014 if something looks wrong, press Option+Shift+R",
|
|
22219
|
+
"(Alt+Shift+R on Windows), click it, and tell Claude what is off.",
|
|
22220
|
+
""
|
|
22221
|
+
);
|
|
22222
|
+
return lines;
|
|
22223
|
+
};
|
|
22224
|
+
var runSessionOne = async (deps = defaultDeps3()) => {
|
|
22225
|
+
const appPath = resolveFirstAppPath(deps);
|
|
22226
|
+
const exists3 = await deps.pathExists(appPath);
|
|
22227
|
+
const empty = exists3 ? await deps.isEmptyDir(appPath) : true;
|
|
22228
|
+
let created = false;
|
|
22229
|
+
if (exists3 && !empty) {
|
|
22230
|
+
const looksLikeKit = await deps.pathExists(join52(appPath, "templates", "web"));
|
|
22231
|
+
if (!looksLikeKit) {
|
|
22232
|
+
const failed = {
|
|
22233
|
+
appPath: null,
|
|
22234
|
+
created: false,
|
|
22235
|
+
depsInstalled: false,
|
|
22236
|
+
packagesBuilt: false,
|
|
22237
|
+
devStarted: false,
|
|
22238
|
+
claudeOpened: false
|
|
22239
|
+
};
|
|
22240
|
+
return {
|
|
22241
|
+
...failed,
|
|
22242
|
+
lines: [
|
|
22243
|
+
"",
|
|
22244
|
+
`Session #1: ${appPath} already exists and is not a VybeKiit app.`,
|
|
22245
|
+
" Pick a free folder and run: npx vybekiit create app --web ~/my-app",
|
|
22246
|
+
" Or set VYBEKIIT_FIRST_APP_DIR and re-run install once.",
|
|
22247
|
+
""
|
|
22248
|
+
]
|
|
22249
|
+
};
|
|
22250
|
+
}
|
|
22251
|
+
} else {
|
|
22252
|
+
process23.stdout.write(`
|
|
22253
|
+
Creating your first web app at ${appPath}\u2026
|
|
22254
|
+
`);
|
|
22255
|
+
const code = await deps.createApp(["--web", appPath]);
|
|
22256
|
+
if (code !== 0) {
|
|
22257
|
+
const failed = {
|
|
22258
|
+
appPath: null,
|
|
22259
|
+
created: false,
|
|
22260
|
+
depsInstalled: false,
|
|
22261
|
+
packagesBuilt: false,
|
|
22262
|
+
devStarted: false,
|
|
22263
|
+
claudeOpened: false
|
|
22264
|
+
};
|
|
22265
|
+
return { ...failed, lines: formatSessionOneLines(failed) };
|
|
22266
|
+
}
|
|
22267
|
+
created = true;
|
|
22268
|
+
}
|
|
22269
|
+
const pnpm = await deps.resolvePnpm();
|
|
22270
|
+
if (pnpm === null) {
|
|
22271
|
+
const partial = {
|
|
22272
|
+
appPath,
|
|
22273
|
+
created,
|
|
22274
|
+
depsInstalled: false,
|
|
22275
|
+
packagesBuilt: false,
|
|
22276
|
+
devStarted: false,
|
|
22277
|
+
claudeOpened: false
|
|
22278
|
+
};
|
|
22279
|
+
const claudeOpened2 = await deps.openClaude(appPath, SESSION_ONE_SEED_PROMPT);
|
|
22280
|
+
return {
|
|
22281
|
+
...partial,
|
|
22282
|
+
claudeOpened: claudeOpened2,
|
|
22283
|
+
lines: formatSessionOneLines({ ...partial, claudeOpened: claudeOpened2 })
|
|
22284
|
+
};
|
|
22285
|
+
}
|
|
22286
|
+
const [pnpmBin, ...pnpmPrefix] = pnpm;
|
|
22287
|
+
process23.stdout.write("\nInstalling dependencies (this can take a few minutes)\u2026\n");
|
|
22288
|
+
const install = await deps.runCommand(appPath, pnpmBin, [...pnpmPrefix, "install"]);
|
|
22289
|
+
const depsInstalled = install.code === 0;
|
|
22290
|
+
let packagesBuilt = false;
|
|
22291
|
+
if (depsInstalled) {
|
|
22292
|
+
process23.stdout.write("\nBuilding kit packages for preview\u2026\n");
|
|
22293
|
+
const build = await deps.runCommand(appPath, pnpmBin, [...pnpmPrefix, "build:packages"]);
|
|
22294
|
+
packagesBuilt = build.code === 0;
|
|
22295
|
+
}
|
|
22296
|
+
let devStarted = false;
|
|
22297
|
+
if (depsInstalled && packagesBuilt) {
|
|
22298
|
+
devStarted = deps.startDetached(appPath, pnpmBin, [...pnpmPrefix, "dev"]);
|
|
22299
|
+
}
|
|
22300
|
+
const claudeOpened = await deps.openClaude(appPath, SESSION_ONE_SEED_PROMPT);
|
|
22301
|
+
const outcome = {
|
|
22302
|
+
appPath,
|
|
22303
|
+
created,
|
|
22304
|
+
depsInstalled,
|
|
22305
|
+
packagesBuilt,
|
|
22306
|
+
devStarted,
|
|
22307
|
+
claudeOpened
|
|
21210
22308
|
};
|
|
21211
|
-
|
|
21212
|
-
await writeFile13(installStatePath(configDir), `${JSON.stringify(state, null, 2)}
|
|
21213
|
-
`, "utf8");
|
|
21214
|
-
return state;
|
|
22309
|
+
return { ...outcome, lines: formatSessionOneLines(outcome) };
|
|
21215
22310
|
};
|
|
21216
22311
|
|
|
21217
22312
|
// src/global/runGlobalInstall.ts
|
|
@@ -21236,6 +22331,11 @@ var formatGlobalInstallSummary = (summary) => {
|
|
|
21236
22331
|
if (summary.skillSample.length > 0) {
|
|
21237
22332
|
lines.push(` smoke: ${summary.skillSample.join(", ")}`);
|
|
21238
22333
|
}
|
|
22334
|
+
if (summary.skippedSkillNames.length > 0) {
|
|
22335
|
+
lines.push(
|
|
22336
|
+
` kept your own same-named skills: ${summary.skippedSkillNames.join(", ")}`
|
|
22337
|
+
);
|
|
22338
|
+
}
|
|
21239
22339
|
if (skillsEmpty) {
|
|
21240
22340
|
lines.push(
|
|
21241
22341
|
" No managed skills on disk \u2014 Claude Code will not load kit skills until this is fixed.",
|
|
@@ -21246,7 +22346,7 @@ var formatGlobalInstallSummary = (summary) => {
|
|
|
21246
22346
|
lines.push(" \u2022 MCP skipped \u2014 the `claude` command was not found on your PATH");
|
|
21247
22347
|
} else {
|
|
21248
22348
|
const enabledLabel = summary.mcpEnabled.length > 0 ? summary.mcpEnabled.join(", ") : "none newly added";
|
|
21249
|
-
lines.push(` \u2022 MCP ${enabledLabel} (browser automation + live docs
|
|
22349
|
+
lines.push(` \u2022 MCP ${enabledLabel} (browser automation + live docs + error monitoring)`);
|
|
21250
22350
|
if (summary.mcpRefreshed.length > 0) {
|
|
21251
22351
|
lines.push(` refreshed: ${summary.mcpRefreshed.join(", ")}`);
|
|
21252
22352
|
}
|
|
@@ -21260,7 +22360,7 @@ var formatGlobalInstallSummary = (summary) => {
|
|
|
21260
22360
|
lines.push("");
|
|
21261
22361
|
} else {
|
|
21262
22362
|
lines.push(
|
|
21263
|
-
" \u2022 Command type /vybekiit in Claude Code to see status anytime",
|
|
22363
|
+
summary.feedbackInstalled ? " \u2022 Command type /vybekiit for status or /feedback to send us a note" : " \u2022 Command type /vybekiit in Claude Code to see status anytime",
|
|
21264
22364
|
" \u2022 Claude now knows it is VybeKiit-enabled in every project",
|
|
21265
22365
|
"",
|
|
21266
22366
|
"To see it: restart Claude Code (or run `claude` once) to approve the new MCP servers,",
|
|
@@ -21268,6 +22368,8 @@ var formatGlobalInstallSummary = (summary) => {
|
|
|
21268
22368
|
"",
|
|
21269
22369
|
"Re-run anytime to update: curl -fsSL https://vybekiit.com/install.sh | sh",
|
|
21270
22370
|
" or: npx -y vybekiit@latest update",
|
|
22371
|
+
'First install also creates your web app and opens Claude with "Set up my app."',
|
|
22372
|
+
"Skip that step: VYBEKIIT_SKIP_SESSION_ONE=1 or --skip-session-one",
|
|
21271
22373
|
""
|
|
21272
22374
|
);
|
|
21273
22375
|
}
|
|
@@ -21277,7 +22379,7 @@ var runGlobalInstall = async (args, gate = checkEntitlement) => {
|
|
|
21277
22379
|
const entitlement = await gate();
|
|
21278
22380
|
if (!entitlement.entitled) {
|
|
21279
22381
|
for (const line of formatEntitlementBlock(entitlement)) {
|
|
21280
|
-
|
|
22382
|
+
process24.stderr.write(`${line}
|
|
21281
22383
|
`);
|
|
21282
22384
|
}
|
|
21283
22385
|
return 1;
|
|
@@ -21285,17 +22387,17 @@ var runGlobalInstall = async (args, gate = checkEntitlement) => {
|
|
|
21285
22387
|
const skipPrompt = args.includes("--yes") || args.includes("-y");
|
|
21286
22388
|
if (!skipPrompt) {
|
|
21287
22389
|
if (!isInteractive()) {
|
|
21288
|
-
|
|
22390
|
+
process24.stdout.write(
|
|
21289
22391
|
"Skipping global setup (non-interactive). Run `vybekiit global-install --yes` or `vybekiit update` to provision Claude Code globally.\n"
|
|
21290
22392
|
);
|
|
21291
22393
|
return 0;
|
|
21292
22394
|
}
|
|
21293
|
-
const proceed = await
|
|
22395
|
+
const proceed = await confirm2({
|
|
21294
22396
|
message: "Set up / update VybeKiit globally in Claude Code? Refreshes skills + browser automation in every project.",
|
|
21295
22397
|
initialValue: true
|
|
21296
22398
|
});
|
|
21297
|
-
if (
|
|
21298
|
-
|
|
22399
|
+
if (isCancel3(proceed) || proceed !== true) {
|
|
22400
|
+
process24.stdout.write(
|
|
21299
22401
|
"Skipped global setup. You can run `vybekiit update` or `vybekiit global-install` anytime.\n"
|
|
21300
22402
|
);
|
|
21301
22403
|
return 0;
|
|
@@ -21308,7 +22410,7 @@ var runGlobalInstall = async (args, gate = checkEntitlement) => {
|
|
|
21308
22410
|
const skills = await installGlobalSkills(paths);
|
|
21309
22411
|
const mcp = await installGlobalMcp({
|
|
21310
22412
|
exec: makeExec("claude"),
|
|
21311
|
-
env:
|
|
22413
|
+
env: process24.env,
|
|
21312
22414
|
forceRefresh: isRerun
|
|
21313
22415
|
});
|
|
21314
22416
|
const awareness = await installAwareness(paths);
|
|
@@ -21317,6 +22419,8 @@ var runGlobalInstall = async (args, gate = checkEntitlement) => {
|
|
|
21317
22419
|
const summary = {
|
|
21318
22420
|
skillsInstalled: skills.installed.length,
|
|
21319
22421
|
skillsSkipped: skills.skipped.length,
|
|
22422
|
+
skippedSkillNames: skills.skipped,
|
|
22423
|
+
feedbackInstalled: skills.installed.includes("feedback"),
|
|
21320
22424
|
skillSample,
|
|
21321
22425
|
skillsPath: skills.path,
|
|
21322
22426
|
mcpEnabled: mcp.enabled,
|
|
@@ -21328,24 +22432,38 @@ var runGlobalInstall = async (args, gate = checkEntitlement) => {
|
|
|
21328
22432
|
previousVersion: previous?.version ?? null
|
|
21329
22433
|
};
|
|
21330
22434
|
for (const line of formatGlobalInstallSummary(summary)) {
|
|
21331
|
-
|
|
22435
|
+
process24.stdout.write(`${line}
|
|
21332
22436
|
`);
|
|
21333
22437
|
}
|
|
21334
22438
|
if (!isGloballyInstalled(postStatus)) {
|
|
21335
|
-
|
|
22439
|
+
process24.stderr.write(
|
|
21336
22440
|
"VybeKiit global install incomplete: expected managed skills + /vybekiit + CLAUDE.md block.\n"
|
|
21337
22441
|
);
|
|
21338
22442
|
return 1;
|
|
21339
22443
|
}
|
|
21340
|
-
|
|
22444
|
+
let firstAppPath = previous?.firstAppPath;
|
|
22445
|
+
const isFirstInstall = previous === null;
|
|
22446
|
+
if (isFirstInstall && !shouldSkipSessionOne(args)) {
|
|
22447
|
+
const sessionOne = await runSessionOne();
|
|
22448
|
+
for (const line of sessionOne.lines) {
|
|
22449
|
+
process24.stdout.write(`${line}
|
|
22450
|
+
`);
|
|
22451
|
+
}
|
|
22452
|
+
if (sessionOne.appPath !== null) {
|
|
22453
|
+
firstAppPath = sessionOne.appPath;
|
|
22454
|
+
}
|
|
22455
|
+
}
|
|
22456
|
+
await writeInstallState(paths.configDir, version, {
|
|
22457
|
+
...firstAppPath === void 0 ? {} : { firstAppPath }
|
|
22458
|
+
});
|
|
21341
22459
|
return 0;
|
|
21342
22460
|
};
|
|
21343
22461
|
|
|
21344
22462
|
// src/ui/welcomeBanner.ts
|
|
21345
|
-
import
|
|
22463
|
+
import process26 from "process";
|
|
21346
22464
|
|
|
21347
22465
|
// src/ui/ansiShimmer.ts
|
|
21348
|
-
import
|
|
22466
|
+
import process25 from "process";
|
|
21349
22467
|
var RESET = "\x1B[0m";
|
|
21350
22468
|
var GRADIENT_START = [34, 211, 238];
|
|
21351
22469
|
var GRADIENT_END = [167, 139, 250];
|
|
@@ -21357,7 +22475,7 @@ var colorAt = (t) => rgb(
|
|
|
21357
22475
|
lerp(GRADIENT_START[1], GRADIENT_END[1], t),
|
|
21358
22476
|
lerp(GRADIENT_START[2], GRADIENT_END[2], t)
|
|
21359
22477
|
);
|
|
21360
|
-
var supportsColor = (env =
|
|
22478
|
+
var supportsColor = (env = process25.env, isTTY = Boolean(process25.stdout.isTTY)) => {
|
|
21361
22479
|
if (env.NO_COLOR !== void 0 && env.NO_COLOR !== "") {
|
|
21362
22480
|
return false;
|
|
21363
22481
|
}
|
|
@@ -21419,13 +22537,13 @@ var writeBlock = (write, lines) => {
|
|
|
21419
22537
|
}
|
|
21420
22538
|
};
|
|
21421
22539
|
var playWelcomeBanner = async (options = {}) => {
|
|
21422
|
-
const write = options.write === void 0 ? (text2) =>
|
|
22540
|
+
const write = options.write === void 0 ? (text2) => process26.stdout.write(text2) : options.write;
|
|
21423
22541
|
const sleepFn = options.sleep === void 0 ? sleep : options.sleep;
|
|
21424
22542
|
const frames = options.frames === void 0 ? DEFAULT_FRAMES : options.frames;
|
|
21425
22543
|
const frameDelayMs = options.frameDelayMs === void 0 ? DEFAULT_FRAME_DELAY_MS : options.frameDelayMs;
|
|
21426
22544
|
const art = [...WELCOME_ART];
|
|
21427
22545
|
const useColor = !options.forcePlain && supportsColor();
|
|
21428
|
-
const animate = useColor && Boolean(
|
|
22546
|
+
const animate = useColor && Boolean(process26.stdout.isTTY) && frames > 0;
|
|
21429
22547
|
if (!animate) {
|
|
21430
22548
|
writeBlock(write, art);
|
|
21431
22549
|
writeln(write, "");
|
|
@@ -21480,6 +22598,14 @@ var formatSetupNextStep = (input) => {
|
|
|
21480
22598
|
""
|
|
21481
22599
|
];
|
|
21482
22600
|
}
|
|
22601
|
+
if (input.firstAppPath !== void 0 && input.firstAppPath !== "") {
|
|
22602
|
+
return [
|
|
22603
|
+
'Your app is ready \u2014 open Claude Code in that folder and say: "Set up my app."',
|
|
22604
|
+
` ${input.firstAppPath}`,
|
|
22605
|
+
" (If Claude is already open there, you are set.)",
|
|
22606
|
+
""
|
|
22607
|
+
];
|
|
22608
|
+
}
|
|
21483
22609
|
return [
|
|
21484
22610
|
"Next: create your app",
|
|
21485
22611
|
" vybekiit create app --web",
|
|
@@ -21493,13 +22619,15 @@ var runSetup = async () => {
|
|
|
21493
22619
|
await playWelcomeBanner();
|
|
21494
22620
|
const code = await runDoctor();
|
|
21495
22621
|
await runGlobalInstall(["--yes"]);
|
|
21496
|
-
const
|
|
21497
|
-
|
|
22622
|
+
const access17 = checkAccess();
|
|
22623
|
+
const installState = await readInstallState(resolveGlobalPaths().configDir);
|
|
22624
|
+
process27.stdout.write("\n");
|
|
21498
22625
|
for (const line of formatSetupNextStep({
|
|
21499
22626
|
doctorExitCode: code,
|
|
21500
|
-
gateReason:
|
|
22627
|
+
gateReason: access17.reason,
|
|
22628
|
+
...installState?.firstAppPath === void 0 ? {} : { firstAppPath: installState.firstAppPath }
|
|
21501
22629
|
})) {
|
|
21502
|
-
|
|
22630
|
+
process27.stdout.write(`${line}
|
|
21503
22631
|
`);
|
|
21504
22632
|
}
|
|
21505
22633
|
return code;
|
|
@@ -21507,20 +22635,20 @@ var runSetup = async () => {
|
|
|
21507
22635
|
|
|
21508
22636
|
// src/commands/syncAgentLayer.ts
|
|
21509
22637
|
import { execFile as execFile7 } from "child_process";
|
|
21510
|
-
import { access as
|
|
21511
|
-
import { join as
|
|
21512
|
-
import
|
|
22638
|
+
import { access as access16, cp as cp6, readFile as readFile24, writeFile as writeFile17 } from "fs/promises";
|
|
22639
|
+
import { join as join53 } from "path";
|
|
22640
|
+
import process28 from "process";
|
|
21513
22641
|
import { promisify as promisify6 } from "util";
|
|
21514
22642
|
var execFileAsync6 = promisify6(execFile7);
|
|
21515
|
-
var
|
|
22643
|
+
var defaultDeps4 = {
|
|
21516
22644
|
resolve: resolveTemplatesSource,
|
|
21517
22645
|
copy: cp6,
|
|
21518
22646
|
runSkillsUpdate: async (cwd) => {
|
|
21519
|
-
await execFileAsync6("npx", ["skills", "update", "-y"], { cwd, env:
|
|
22647
|
+
await execFileAsync6("npx", ["skills", "update", "-y"], { cwd, env: process28.env });
|
|
21520
22648
|
},
|
|
21521
22649
|
pathExists: async (path) => {
|
|
21522
22650
|
try {
|
|
21523
|
-
await
|
|
22651
|
+
await access16(path);
|
|
21524
22652
|
return true;
|
|
21525
22653
|
} catch {
|
|
21526
22654
|
return false;
|
|
@@ -21539,7 +22667,7 @@ var resolveSyncTemplate = async (explicit, cwd) => {
|
|
|
21539
22667
|
var listMirrorAgentPaths = async (mirrorRoot, pathExists9) => {
|
|
21540
22668
|
const entries = await Promise.all(
|
|
21541
22669
|
AGENT_LAYER_PATHS.map(async (path) => {
|
|
21542
|
-
if (await pathExists9(
|
|
22670
|
+
if (await pathExists9(join53(mirrorRoot, path))) {
|
|
21543
22671
|
return path;
|
|
21544
22672
|
}
|
|
21545
22673
|
return null;
|
|
@@ -21549,28 +22677,28 @@ var listMirrorAgentPaths = async (mirrorRoot, pathExists9) => {
|
|
|
21549
22677
|
};
|
|
21550
22678
|
var copyAgentLayerPath = async (options) => {
|
|
21551
22679
|
const { mirrorRoot, cwd, path, copy, pathExists: pathExists9 } = options;
|
|
21552
|
-
const src =
|
|
21553
|
-
const dest =
|
|
22680
|
+
const src = join53(mirrorRoot, path);
|
|
22681
|
+
const dest = join53(cwd, path);
|
|
21554
22682
|
if (path !== ".vybekiit") {
|
|
21555
22683
|
await copy(src, dest, { recursive: true, force: true });
|
|
21556
22684
|
return;
|
|
21557
22685
|
}
|
|
21558
|
-
const { readdir:
|
|
22686
|
+
const { readdir: readdir12, stat: stat4, mkdir: mkdir15 } = await import("fs/promises");
|
|
21559
22687
|
const walk = async (rel) => {
|
|
21560
22688
|
const relNorm = rel.split("\\").join("/");
|
|
21561
22689
|
if (isAgentLayerExtensionPath(relNorm)) {
|
|
21562
22690
|
return;
|
|
21563
22691
|
}
|
|
21564
|
-
const srcPath =
|
|
21565
|
-
const destPath =
|
|
22692
|
+
const srcPath = join53(mirrorRoot, relNorm);
|
|
22693
|
+
const destPath = join53(cwd, relNorm);
|
|
21566
22694
|
if (!await pathExists9(srcPath)) {
|
|
21567
22695
|
return;
|
|
21568
22696
|
}
|
|
21569
22697
|
const info = await stat4(srcPath);
|
|
21570
22698
|
if (info.isDirectory()) {
|
|
21571
|
-
await
|
|
21572
|
-
const entries = await
|
|
21573
|
-
await Promise.all(entries.map((entry) => walk(
|
|
22699
|
+
await mkdir15(destPath, { recursive: true });
|
|
22700
|
+
const entries = await readdir12(srcPath);
|
|
22701
|
+
await Promise.all(entries.map((entry) => walk(join53(relNorm, entry))));
|
|
21574
22702
|
return;
|
|
21575
22703
|
}
|
|
21576
22704
|
await copy(srcPath, destPath, { force: true });
|
|
@@ -21594,21 +22722,21 @@ var readGoalIndexBeforeSync = async (pathsToSync, cwd, deps) => {
|
|
|
21594
22722
|
if (!pathsToSync.includes(".vybekiit")) {
|
|
21595
22723
|
return;
|
|
21596
22724
|
}
|
|
21597
|
-
const goalIndexPath =
|
|
22725
|
+
const goalIndexPath = join53(cwd, ".vybekiit/agent/goal-index.md");
|
|
21598
22726
|
if (!await deps.pathExists(goalIndexPath)) {
|
|
21599
22727
|
return;
|
|
21600
22728
|
}
|
|
21601
|
-
return await
|
|
22729
|
+
return await readFile24(goalIndexPath, "utf8");
|
|
21602
22730
|
};
|
|
21603
22731
|
var mergeGoalIndexAfterSync = async (cwd, goalIndexBefore) => {
|
|
21604
22732
|
if (goalIndexBefore === void 0) {
|
|
21605
22733
|
return;
|
|
21606
22734
|
}
|
|
21607
|
-
const goalIndexPath =
|
|
21608
|
-
const synced = await
|
|
22735
|
+
const goalIndexPath = join53(cwd, ".vybekiit/agent/goal-index.md");
|
|
22736
|
+
const synced = await readFile24(goalIndexPath, "utf8");
|
|
21609
22737
|
const merged = mergeGoalIndexOnSync(synced, goalIndexBefore);
|
|
21610
22738
|
if (merged !== synced) {
|
|
21611
|
-
await
|
|
22739
|
+
await writeFile17(goalIndexPath, merged, "utf8");
|
|
21612
22740
|
}
|
|
21613
22741
|
};
|
|
21614
22742
|
var refreshGeneratedInstructionSections = async (cwd, template, deps) => {
|
|
@@ -21619,14 +22747,14 @@ var refreshGeneratedInstructionSections = async (cwd, template, deps) => {
|
|
|
21619
22747
|
const rendered = applyAgentLayerSections(fileContents, { template });
|
|
21620
22748
|
const writes = Object.entries(rendered).map(async ([file, content]) => {
|
|
21621
22749
|
if (fileContents[file] !== void 0 && content !== fileContents[file]) {
|
|
21622
|
-
await
|
|
22750
|
+
await writeFile17(join53(cwd, file), content, "utf8");
|
|
21623
22751
|
}
|
|
21624
22752
|
});
|
|
21625
22753
|
await Promise.all(writes);
|
|
21626
22754
|
return true;
|
|
21627
22755
|
};
|
|
21628
22756
|
var refreshPlatformInstructionFiles = async (cwd, deps) => {
|
|
21629
|
-
if (!await deps.pathExists(
|
|
22757
|
+
if (!await deps.pathExists(join53(cwd, "skills-lock.json"))) {
|
|
21630
22758
|
return "missing-lock";
|
|
21631
22759
|
}
|
|
21632
22760
|
try {
|
|
@@ -21636,7 +22764,7 @@ var refreshPlatformInstructionFiles = async (cwd, deps) => {
|
|
|
21636
22764
|
return "failed";
|
|
21637
22765
|
}
|
|
21638
22766
|
};
|
|
21639
|
-
var runSyncAgentLayer = async (args, cwd =
|
|
22767
|
+
var runSyncAgentLayer = async (args, cwd = process28.cwd(), deps = defaultDeps4) => {
|
|
21640
22768
|
const [explicit] = args;
|
|
21641
22769
|
const template = await resolveSyncTemplate(explicit, cwd);
|
|
21642
22770
|
if (template === null) {
|
|
@@ -21655,7 +22783,7 @@ var runSyncAgentLayer = async (args, cwd = process25.cwd(), deps = defaultDeps3)
|
|
|
21655
22783
|
});
|
|
21656
22784
|
const { cleanup: resolvedCleanup, source } = resolved;
|
|
21657
22785
|
cleanup = resolvedCleanup;
|
|
21658
|
-
const mirrorRoot =
|
|
22786
|
+
const mirrorRoot = join53(source, template);
|
|
21659
22787
|
const mirrorPaths = await listMirrorAgentPaths(mirrorRoot, deps.pathExists);
|
|
21660
22788
|
const plan = planAgentLayerSync(mirrorPaths);
|
|
21661
22789
|
const lines = [formatAgentLayerSyncSummary(plan)];
|
|
@@ -21691,7 +22819,7 @@ var runSyncAgentLayer = async (args, cwd = process25.cwd(), deps = defaultDeps3)
|
|
|
21691
22819
|
};
|
|
21692
22820
|
|
|
21693
22821
|
// src/commands/updateKit.ts
|
|
21694
|
-
import
|
|
22822
|
+
import process29 from "process";
|
|
21695
22823
|
import { Effect as Effect31 } from "effect";
|
|
21696
22824
|
var runUpdateKit = async (args = []) => {
|
|
21697
22825
|
const apply = args.includes("--apply");
|
|
@@ -21719,21 +22847,21 @@ var runUpdateKit = async (args = []) => {
|
|
|
21719
22847
|
var runUpdateKitCommand = async (args) => {
|
|
21720
22848
|
const result = await runUpdateKit(args);
|
|
21721
22849
|
for (const line of result.lines) {
|
|
21722
|
-
|
|
22850
|
+
process29.stdout.write(`${line}
|
|
21723
22851
|
`);
|
|
21724
22852
|
}
|
|
21725
22853
|
return result.exitCode;
|
|
21726
22854
|
};
|
|
21727
22855
|
|
|
21728
22856
|
// src/doctor/ensureTool.ts
|
|
21729
|
-
import { spawnSync as
|
|
21730
|
-
import
|
|
22857
|
+
import { spawnSync as spawnSync9 } from "child_process";
|
|
22858
|
+
import process30 from "process";
|
|
21731
22859
|
var toPlatform2 = (platform) => platform === "darwin" || platform === "win32" || platform === "linux" ? platform : null;
|
|
21732
|
-
var
|
|
22860
|
+
var succeeds3 = (command, args) => spawnSync9(command, [...args], { stdio: "ignore" }).status === 0;
|
|
21733
22861
|
var errorCode2 = (error) => error !== void 0 && "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
21734
22862
|
var runInstall2 = (action, log) => {
|
|
21735
22863
|
log.log(`[doctor] setting up ${action.tool}: ${action.command} ${action.args.join(" ")}`);
|
|
21736
|
-
const result =
|
|
22864
|
+
const result = spawnSync9(action.command, [...action.args], { stdio: "inherit" });
|
|
21737
22865
|
if (errorCode2(result.error) === "ENOENT") {
|
|
21738
22866
|
return action.requires ? { ok: false, missingRequirement: action.requires } : { ok: false };
|
|
21739
22867
|
}
|
|
@@ -21743,19 +22871,19 @@ var probeAuth = (tool) => {
|
|
|
21743
22871
|
if (tool.auth === void 0) {
|
|
21744
22872
|
return null;
|
|
21745
22873
|
}
|
|
21746
|
-
return
|
|
22874
|
+
return succeeds3(tool.auth.command, tool.auth.args);
|
|
21747
22875
|
};
|
|
21748
22876
|
var ensureTool = (name, log = console) => {
|
|
21749
22877
|
const tool = findToolByName(name);
|
|
21750
22878
|
if (tool === void 0) {
|
|
21751
22879
|
return { tool: name, known: false, installed: false, installedNow: false, authed: null };
|
|
21752
22880
|
}
|
|
21753
|
-
const platform = toPlatform2(
|
|
22881
|
+
const platform = toPlatform2(process30.platform);
|
|
21754
22882
|
if (!platform) {
|
|
21755
|
-
log.error(`[doctor] This operating system (${
|
|
22883
|
+
log.error(`[doctor] This operating system (${process30.platform}) isn't supported yet.`);
|
|
21756
22884
|
return { tool: name, known: true, installed: false, installedNow: false, authed: null };
|
|
21757
22885
|
}
|
|
21758
|
-
const present =
|
|
22886
|
+
const present = succeeds3(tool.name, tool.versionArgs);
|
|
21759
22887
|
const presence = [{ tool: tool.name, present }];
|
|
21760
22888
|
let installedNow = false;
|
|
21761
22889
|
let missingRequirement;
|
|
@@ -21796,9 +22924,9 @@ var formatEnsureResult = (result) => {
|
|
|
21796
22924
|
};
|
|
21797
22925
|
|
|
21798
22926
|
// src/prompts/envWizard.ts
|
|
21799
|
-
import { readFile as
|
|
21800
|
-
import { join as
|
|
21801
|
-
import { cancel as cancel2, isCancel as
|
|
22927
|
+
import { readFile as readFile25 } from "fs/promises";
|
|
22928
|
+
import { join as join54 } from "path";
|
|
22929
|
+
import { cancel as cancel2, isCancel as isCancel4, text } from "@clack/prompts";
|
|
21802
22930
|
var ENV_KEY_PATTERN = /^[A-Z][A-Z0-9_]*$/;
|
|
21803
22931
|
var parseExampleEnvKeys = (raw) => raw.split("\n").reduce((keys, line) => {
|
|
21804
22932
|
const separatorIndex = line.indexOf("=");
|
|
@@ -21849,19 +22977,19 @@ ${nextLine}
|
|
|
21849
22977
|
`;
|
|
21850
22978
|
};
|
|
21851
22979
|
var runEnvWizard = async (cwd = process.cwd()) => {
|
|
21852
|
-
const examplePath =
|
|
22980
|
+
const examplePath = join54(cwd, ".env.example");
|
|
21853
22981
|
let raw;
|
|
21854
22982
|
try {
|
|
21855
|
-
raw = await
|
|
22983
|
+
raw = await readFile25(examplePath, "utf8");
|
|
21856
22984
|
} catch {
|
|
21857
22985
|
process.stderr.write("No .env.example in this folder.\n");
|
|
21858
22986
|
return 1;
|
|
21859
22987
|
}
|
|
21860
22988
|
const keys = parseExampleEnvKeys(raw);
|
|
21861
|
-
const envPath =
|
|
22989
|
+
const envPath = join54(cwd, ".env");
|
|
21862
22990
|
let envContent = "";
|
|
21863
22991
|
try {
|
|
21864
|
-
envContent = await
|
|
22992
|
+
envContent = await readFile25(envPath, "utf8");
|
|
21865
22993
|
} catch {
|
|
21866
22994
|
}
|
|
21867
22995
|
for (const key of keys) {
|
|
@@ -21873,19 +23001,19 @@ var runEnvWizard = async (cwd = process.cwd()) => {
|
|
|
21873
23001
|
defaultValue: current,
|
|
21874
23002
|
placeholder: current
|
|
21875
23003
|
});
|
|
21876
|
-
if (
|
|
23004
|
+
if (isCancel4(value)) {
|
|
21877
23005
|
cancel2("Cancelled.");
|
|
21878
23006
|
return 1;
|
|
21879
23007
|
}
|
|
21880
23008
|
envContent = upsertEnvLine(envContent, key, value);
|
|
21881
23009
|
}
|
|
21882
|
-
const { writeFile:
|
|
21883
|
-
await
|
|
23010
|
+
const { writeFile: writeFile18 } = await import("fs/promises");
|
|
23011
|
+
await writeFile18(envPath, envContent, "utf8");
|
|
21884
23012
|
return 0;
|
|
21885
23013
|
};
|
|
21886
23014
|
|
|
21887
23015
|
// src/prompts/mainMenu.ts
|
|
21888
|
-
import { cancel as cancel3, intro, isCancel as
|
|
23016
|
+
import { cancel as cancel3, intro, isCancel as isCancel5, select as select2 } from "@clack/prompts";
|
|
21889
23017
|
var promptMainMenu = async () => {
|
|
21890
23018
|
intro("Welcome to VybeKiit");
|
|
21891
23019
|
const picked = await select2({
|
|
@@ -21918,7 +23046,7 @@ var promptMainMenu = async () => {
|
|
|
21918
23046
|
}
|
|
21919
23047
|
]
|
|
21920
23048
|
});
|
|
21921
|
-
if (
|
|
23049
|
+
if (isCancel5(picked) || typeof picked !== "string") {
|
|
21922
23050
|
cancel3("Cancelled.");
|
|
21923
23051
|
return null;
|
|
21924
23052
|
}
|
|
@@ -21929,11 +23057,11 @@ var promptMainMenu = async () => {
|
|
|
21929
23057
|
};
|
|
21930
23058
|
|
|
21931
23059
|
// src/cliRunner.ts
|
|
21932
|
-
var HERE7 =
|
|
21933
|
-
var GATE_EXEMPT = /* @__PURE__ */ new Set(["doctor", "setup", "global-install", "update"]);
|
|
23060
|
+
var HERE7 = dirname18(fileURLToPath9(import.meta.url));
|
|
23061
|
+
var GATE_EXEMPT = /* @__PURE__ */ new Set(["doctor", "setup", "global-install", "update", "feedback"]);
|
|
21934
23062
|
var readVersion = async () => {
|
|
21935
23063
|
try {
|
|
21936
|
-
const raw = await
|
|
23064
|
+
const raw = await readFile26(join55(HERE7, "..", "package.json"), "utf8");
|
|
21937
23065
|
const parsed = JSON.parse(raw);
|
|
21938
23066
|
if (parsed.version !== void 0 && parsed.version !== "") {
|
|
21939
23067
|
return parsed.version;
|
|
@@ -21958,7 +23086,7 @@ var commandArgs = (context) => {
|
|
|
21958
23086
|
};
|
|
21959
23087
|
var writeLines2 = (lines) => {
|
|
21960
23088
|
for (const line of lines) {
|
|
21961
|
-
|
|
23089
|
+
process31.stdout.write(`${line}
|
|
21962
23090
|
`);
|
|
21963
23091
|
}
|
|
21964
23092
|
};
|
|
@@ -21974,20 +23102,20 @@ var runDoctorEnsure = (toolName, json) => {
|
|
|
21974
23102
|
if (toolName === void 0 || toolName === "" || toolName.startsWith("--")) {
|
|
21975
23103
|
const message = "Usage: vybekiit doctor --ensure <tool> [--json]";
|
|
21976
23104
|
if (json) {
|
|
21977
|
-
|
|
23105
|
+
process31.stdout.write(`${JSON.stringify({ ok: false, error: message })}
|
|
21978
23106
|
`);
|
|
21979
23107
|
} else {
|
|
21980
|
-
|
|
23108
|
+
process31.stderr.write(`${message}
|
|
21981
23109
|
`);
|
|
21982
23110
|
}
|
|
21983
23111
|
return 1;
|
|
21984
23112
|
}
|
|
21985
23113
|
const result = ensureTool(toolName);
|
|
21986
23114
|
if (json) {
|
|
21987
|
-
|
|
23115
|
+
process31.stdout.write(`${JSON.stringify({ ok: result.installed, ...result })}
|
|
21988
23116
|
`);
|
|
21989
23117
|
} else {
|
|
21990
|
-
|
|
23118
|
+
process31.stdout.write(`${formatEnsureResult(result)}
|
|
21991
23119
|
`);
|
|
21992
23120
|
}
|
|
21993
23121
|
return result.installed ? 0 : 1;
|
|
@@ -22003,47 +23131,47 @@ var handleDoctorCommand = async (context) => {
|
|
|
22003
23131
|
var handleBackendCommand = async (context) => {
|
|
22004
23132
|
if (context.subcommand === "add-route") {
|
|
22005
23133
|
const result = await runBackendAddRoute([...context.rest]);
|
|
22006
|
-
|
|
23134
|
+
process31.stdout.write(`${result.message}
|
|
22007
23135
|
`);
|
|
22008
23136
|
return result.exitCode;
|
|
22009
23137
|
}
|
|
22010
23138
|
if (context.subcommand === "add-crud") {
|
|
22011
23139
|
const result = await runBackendAddCrud([...context.rest]);
|
|
22012
|
-
|
|
23140
|
+
process31.stdout.write(`${result.message}
|
|
22013
23141
|
`);
|
|
22014
23142
|
return result.exitCode;
|
|
22015
23143
|
}
|
|
22016
23144
|
if (context.subcommand === "add-upload") {
|
|
22017
23145
|
const result = await runBackendAddUpload();
|
|
22018
|
-
|
|
23146
|
+
process31.stdout.write(`${result.message}
|
|
22019
23147
|
`);
|
|
22020
23148
|
return result.exitCode;
|
|
22021
23149
|
}
|
|
22022
23150
|
if (context.subcommand === "gen-contract") {
|
|
22023
23151
|
const result = await runBackendGenContract();
|
|
22024
|
-
|
|
23152
|
+
process31.stdout.write(`${result.message}
|
|
22025
23153
|
`);
|
|
22026
23154
|
return result.exitCode;
|
|
22027
23155
|
}
|
|
22028
|
-
|
|
23156
|
+
process31.stderr.write(
|
|
22029
23157
|
"Unknown backend command. Try: backend add-route | add-crud | add-upload | gen-contract\n"
|
|
22030
23158
|
);
|
|
22031
23159
|
return 1;
|
|
22032
23160
|
};
|
|
22033
23161
|
var handleEnvCommand = async (context) => {
|
|
22034
23162
|
if (context.subcommand !== "wizard") {
|
|
22035
|
-
|
|
23163
|
+
process31.stderr.write("Unknown env command. Try: vybekiit env wizard\n");
|
|
22036
23164
|
return 1;
|
|
22037
23165
|
}
|
|
22038
23166
|
if (!isInteractive()) {
|
|
22039
|
-
|
|
23167
|
+
process31.stderr.write("env wizard requires an interactive terminal.\n");
|
|
22040
23168
|
return 1;
|
|
22041
23169
|
}
|
|
22042
23170
|
return await runEnvWizard();
|
|
22043
23171
|
};
|
|
22044
23172
|
var handleCreateCommand = async (context) => {
|
|
22045
23173
|
if (context.subcommand !== "app") {
|
|
22046
|
-
|
|
23174
|
+
process31.stderr.write("Usage: vybekiit create app --web|--mobile|--extension [directory]\n");
|
|
22047
23175
|
return 1;
|
|
22048
23176
|
}
|
|
22049
23177
|
return await runCreateApp([...context.rest]);
|
|
@@ -22051,7 +23179,7 @@ var handleCreateCommand = async (context) => {
|
|
|
22051
23179
|
var wantsFullHelp = (argv) => argv.includes("--all") || argv.includes("-a");
|
|
22052
23180
|
var runMainMenuChoice = async (choice) => {
|
|
22053
23181
|
if (choice === "help-all") {
|
|
22054
|
-
|
|
23182
|
+
process31.stdout.write(`${CLI_HELP_ALL}
|
|
22055
23183
|
`);
|
|
22056
23184
|
return 0;
|
|
22057
23185
|
}
|
|
@@ -22078,18 +23206,24 @@ var handleAddCommand = async (context) => {
|
|
|
22078
23206
|
}
|
|
22079
23207
|
if (context.subcommand === "page-recipe") {
|
|
22080
23208
|
const result = await runAddPageRecipe([...context.rest]);
|
|
22081
|
-
|
|
23209
|
+
process31.stdout.write(`${result.json}
|
|
23210
|
+
`);
|
|
23211
|
+
return result.exitCode;
|
|
23212
|
+
}
|
|
23213
|
+
if (context.subcommand === "report-mode") {
|
|
23214
|
+
const result = await runAddReportMode([...context.rest]);
|
|
23215
|
+
process31.stdout.write(`${result.json}
|
|
22082
23216
|
`);
|
|
22083
23217
|
return result.exitCode;
|
|
22084
23218
|
}
|
|
22085
23219
|
if (context.subcommand === "preset") {
|
|
22086
23220
|
const result = await runApplyPreset([...context.rest]);
|
|
22087
|
-
|
|
23221
|
+
process31.stdout.write(`${result.json}
|
|
22088
23222
|
`);
|
|
22089
23223
|
return result.exitCode;
|
|
22090
23224
|
}
|
|
22091
|
-
|
|
22092
|
-
"Unknown add command. Try: vybekiit add page-recipe <id> | add preset <id> | add bridge\n"
|
|
23225
|
+
process31.stderr.write(
|
|
23226
|
+
"Unknown add command. Try: vybekiit add page-recipe <id> | add report-mode | add preset <id> | add bridge\n"
|
|
22093
23227
|
);
|
|
22094
23228
|
return 1;
|
|
22095
23229
|
};
|
|
@@ -22117,96 +23251,96 @@ var COMMAND_HANDLERS = {
|
|
|
22117
23251
|
"render-agent-layer": async () => (await runRenderAgentLayer()).exitCode,
|
|
22118
23252
|
"check-goals": async (context) => {
|
|
22119
23253
|
const result = await runCheckGoals([...context.rest]);
|
|
22120
|
-
|
|
23254
|
+
process31.stdout.write(`${result.json}
|
|
22121
23255
|
`);
|
|
22122
23256
|
return result.exitCode;
|
|
22123
23257
|
},
|
|
22124
23258
|
"check-agent-layer": async (context) => {
|
|
22125
23259
|
const result = await runCheckAgentLayer([...context.rest]);
|
|
22126
|
-
|
|
23260
|
+
process31.stdout.write(`${result.json}
|
|
22127
23261
|
`);
|
|
22128
23262
|
return result.exitCode;
|
|
22129
23263
|
},
|
|
22130
23264
|
"plan-readiness": async (context) => {
|
|
22131
23265
|
const result = await runPlanReadiness([...context.rest]);
|
|
22132
|
-
|
|
23266
|
+
process31.stdout.write(`${result.json}
|
|
22133
23267
|
`);
|
|
22134
23268
|
return result.exitCode;
|
|
22135
23269
|
},
|
|
22136
23270
|
"plan-setup": async (context) => {
|
|
22137
23271
|
const result = await runPlanSetup([...context.rest]);
|
|
22138
|
-
|
|
23272
|
+
process31.stdout.write(`${result.output}
|
|
22139
23273
|
`);
|
|
22140
23274
|
return result.exitCode;
|
|
22141
23275
|
},
|
|
22142
23276
|
"plan-data-model": async (context) => {
|
|
22143
23277
|
const result = await runPlanDataModel([...context.rest]);
|
|
22144
|
-
|
|
23278
|
+
process31.stdout.write(`${result.json}
|
|
22145
23279
|
`);
|
|
22146
23280
|
return result.exitCode;
|
|
22147
23281
|
},
|
|
22148
23282
|
"apply-preset": async (context) => {
|
|
22149
23283
|
const result = await runApplyPreset(commandArgs(context));
|
|
22150
|
-
|
|
23284
|
+
process31.stdout.write(`${result.json}
|
|
22151
23285
|
`);
|
|
22152
23286
|
return result.exitCode;
|
|
22153
23287
|
},
|
|
22154
23288
|
"list-presets": () => {
|
|
22155
23289
|
const result = runListPresets();
|
|
22156
|
-
|
|
23290
|
+
process31.stdout.write(`${result.json}
|
|
22157
23291
|
`);
|
|
22158
23292
|
return result.exitCode;
|
|
22159
23293
|
},
|
|
22160
23294
|
"list-pieces": async (context) => {
|
|
22161
23295
|
const result = await runListPieces(commandArgs(context));
|
|
22162
|
-
|
|
23296
|
+
process31.stdout.write(`${result.json}
|
|
22163
23297
|
`);
|
|
22164
23298
|
return result.exitCode;
|
|
22165
23299
|
},
|
|
22166
23300
|
"list-page-recipes": async (context) => {
|
|
22167
23301
|
const result = await runListPageRecipes(commandArgs(context));
|
|
22168
|
-
|
|
23302
|
+
process31.stdout.write(`${result.json}
|
|
22169
23303
|
`);
|
|
22170
23304
|
return result.exitCode;
|
|
22171
23305
|
},
|
|
22172
23306
|
"verify-presets": async (context) => {
|
|
22173
23307
|
const result = await runVerifyPresets(commandArgs(context));
|
|
22174
|
-
|
|
23308
|
+
process31.stdout.write(`${result.json}
|
|
22175
23309
|
`);
|
|
22176
23310
|
return result.exitCode;
|
|
22177
23311
|
},
|
|
22178
23312
|
"lint-extension-skill": async (context) => {
|
|
22179
23313
|
const result = await runLintExtensionSkill([...context.rest]);
|
|
22180
|
-
|
|
23314
|
+
process31.stdout.write(`${result.json}
|
|
22181
23315
|
`);
|
|
22182
23316
|
return result.exitCode;
|
|
22183
23317
|
},
|
|
22184
23318
|
"doc-fallback": (context) => {
|
|
22185
23319
|
const result = runDocFallback([...context.rest]);
|
|
22186
|
-
|
|
23320
|
+
process31.stdout.write(`${result.json}
|
|
22187
23321
|
`);
|
|
22188
23322
|
return result.exitCode;
|
|
22189
23323
|
},
|
|
22190
23324
|
"live-work": async (context) => {
|
|
22191
23325
|
if (context.subcommand === "data") {
|
|
22192
23326
|
const result = await runLiveWorkData([...context.rest]);
|
|
22193
|
-
|
|
23327
|
+
process31.stdout.write(`${result.json}
|
|
22194
23328
|
`);
|
|
22195
23329
|
return result.exitCode;
|
|
22196
23330
|
}
|
|
22197
23331
|
if (context.subcommand === "host") {
|
|
22198
23332
|
const result = await runLiveWorkHost([...context.rest]);
|
|
22199
|
-
|
|
23333
|
+
process31.stdout.write(`${result.json}
|
|
22200
23334
|
`);
|
|
22201
23335
|
return result.exitCode;
|
|
22202
23336
|
}
|
|
22203
23337
|
if (context.subcommand === "payments") {
|
|
22204
23338
|
const result = await runLiveWorkPayments([...context.rest]);
|
|
22205
|
-
|
|
23339
|
+
process31.stdout.write(`${result.json}
|
|
22206
23340
|
`);
|
|
22207
23341
|
return result.exitCode;
|
|
22208
23342
|
}
|
|
22209
|
-
|
|
23343
|
+
process31.stderr.write(
|
|
22210
23344
|
"Usage: vybekiit live-work data|host|payments [--mode=demo|dogfood|buyer] [--vendor=\u2026] [--cwd=dir] [--no-pin] [--fresh]\n"
|
|
22211
23345
|
);
|
|
22212
23346
|
return 1;
|
|
@@ -22214,7 +23348,7 @@ var COMMAND_HANDLERS = {
|
|
|
22214
23348
|
dedup: async (context) => {
|
|
22215
23349
|
const result = await runDedup(commandArgs(context));
|
|
22216
23350
|
if (result.output !== "") {
|
|
22217
|
-
|
|
23351
|
+
process31.stdout.write(result.output);
|
|
22218
23352
|
}
|
|
22219
23353
|
return result.exitCode;
|
|
22220
23354
|
},
|
|
@@ -22222,15 +23356,16 @@ var COMMAND_HANDLERS = {
|
|
|
22222
23356
|
env: handleEnvCommand,
|
|
22223
23357
|
scaffold: async (context) => {
|
|
22224
23358
|
if (context.subcommand !== "backend") {
|
|
22225
|
-
|
|
23359
|
+
process31.stderr.write("Unknown scaffold command. Try: vybekiit scaffold backend\n");
|
|
22226
23360
|
return 1;
|
|
22227
23361
|
}
|
|
22228
|
-
const result = await runScaffoldBackend([...context.rest],
|
|
22229
|
-
|
|
23362
|
+
const result = await runScaffoldBackend([...context.rest], process31.cwd());
|
|
23363
|
+
process31.stdout.write(`${result.message}
|
|
22230
23364
|
`);
|
|
22231
23365
|
return result.exitCode;
|
|
22232
23366
|
},
|
|
22233
|
-
backend: handleBackendCommand
|
|
23367
|
+
backend: handleBackendCommand,
|
|
23368
|
+
feedback: (context) => runFeedback(commandArgs(context))
|
|
22234
23369
|
};
|
|
22235
23370
|
var COMMAND_NAMES = Object.keys(COMMAND_HANDLERS);
|
|
22236
23371
|
var runCli = async (argv) => {
|
|
@@ -22243,17 +23378,17 @@ var runCli = async (argv) => {
|
|
|
22243
23378
|
}
|
|
22244
23379
|
return await runMainMenuChoice(choice);
|
|
22245
23380
|
}
|
|
22246
|
-
|
|
23381
|
+
process31.stdout.write(`${CLI_HELP}
|
|
22247
23382
|
`);
|
|
22248
23383
|
return 0;
|
|
22249
23384
|
}
|
|
22250
23385
|
if (context.command === "help" || context.command === "--help" || context.command === "-h") {
|
|
22251
|
-
|
|
23386
|
+
process31.stdout.write(`${wantsFullHelp(argv) ? CLI_HELP_ALL : CLI_HELP}
|
|
22252
23387
|
`);
|
|
22253
23388
|
return 0;
|
|
22254
23389
|
}
|
|
22255
23390
|
if (context.command === "--version" || context.command === "-v") {
|
|
22256
|
-
|
|
23391
|
+
process31.stdout.write(`${await readVersion()}
|
|
22257
23392
|
`);
|
|
22258
23393
|
return 0;
|
|
22259
23394
|
}
|
|
@@ -22262,7 +23397,7 @@ var runCli = async (argv) => {
|
|
|
22262
23397
|
}
|
|
22263
23398
|
const handler = COMMAND_HANDLERS[context.command];
|
|
22264
23399
|
if (handler === void 0) {
|
|
22265
|
-
|
|
23400
|
+
process31.stderr.write(
|
|
22266
23401
|
`Unknown command: ${context.command}
|
|
22267
23402
|
Try: vybekiit or vybekiit --help
|
|
22268
23403
|
`
|
|
@@ -22274,9 +23409,9 @@ Try: vybekiit or vybekiit --help
|
|
|
22274
23409
|
|
|
22275
23410
|
// src/bin.ts
|
|
22276
23411
|
try {
|
|
22277
|
-
|
|
23412
|
+
process32.exit(await runCli(process32.argv.slice(2)));
|
|
22278
23413
|
} catch (error) {
|
|
22279
|
-
|
|
23414
|
+
process32.stderr.write(`vybekiit: ${caughtMessage(error)}
|
|
22280
23415
|
`);
|
|
22281
|
-
|
|
23416
|
+
process32.exit(1);
|
|
22282
23417
|
}
|