@punks/cli 1.0.2 → 1.0.3

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/index.js CHANGED
@@ -41912,37 +41912,29 @@ var hookCatalog = [
41912
41912
  // src/data/catalog/lint.ts
41913
41913
  var sharedReactPlacement = {
41914
41914
  recommendedConfigFile: ".oxlintrc.json",
41915
- recommendedFiles: [
41916
- "apps/web/**/*.{js,jsx,ts,tsx}",
41917
- "packages/ui/**/*.{js,jsx,ts,tsx}"
41918
- ],
41919
- recommendedWorkspaces: ["apps/web", "packages/ui"],
41920
- placementNotes: "Add as an override for React-rendered code. Keep the same scope for shared UI packages unless the target repo clearly splits product UI into other workspaces."
41915
+ recommendedFiles: ["<detected-react-workspace>/**/*.{js,jsx,ts,tsx}"],
41916
+ recommendedWorkspaces: ["detected React workspaces"],
41917
+ placementNotes: "Add as an override for detected React-rendered code. Keep backend packages outside this override unless they render React."
41921
41918
  };
41922
41919
  var webOnlyPlacement = {
41923
41920
  recommendedConfigFile: ".oxlintrc.json",
41924
- recommendedFiles: ["apps/web/**/*.{js,jsx,ts,tsx}"],
41925
- recommendedWorkspaces: ["apps/web"],
41921
+ recommendedFiles: ["<detected-nextjs-workspace>/**/*.{js,jsx,ts,tsx}"],
41922
+ recommendedWorkspaces: ["detected Next.js workspaces"],
41926
41923
  placementNotes: "Place this in the Next.js app override. If the repo uses a different frontend app path, retarget the file globs to that workspace before composing the final Oxlint config."
41927
41924
  };
41928
41925
  var effectPlacement = {
41929
41926
  recommendedConfigFile: ".oxlintrc.json",
41930
- recommendedFiles: [
41931
- "apps/server/**/*.{js,jsx,ts,tsx}",
41932
- "packages/api/**/*.{js,jsx,ts,tsx}",
41933
- "packages/db/**/*.{js,jsx,ts,tsx}"
41934
- ],
41935
- recommendedWorkspaces: ["apps/server", "packages/api", "packages/db"],
41927
+ recommendedFiles: ["<detected-effect-workspace>/**/*.{js,jsx,ts,tsx}"],
41928
+ recommendedWorkspaces: ["detected Effect workspaces"],
41936
41929
  placementNotes: "Apply this only where Effect code lives. If the target repo renames or splits backend workspaces, move the override with those code paths instead of broadening it repo-wide."
41937
41930
  };
41938
41931
  var vitestPlacement = {
41939
41932
  recommendedConfigFile: ".oxlintrc.json",
41940
41933
  recommendedFiles: [
41941
- "apps/web/**/*.{test,spec}.{js,jsx,ts,tsx}",
41942
- "apps/web/src/test/**/*.{js,jsx,ts,tsx}",
41943
- "packages/api/**/*.{test,spec}.{js,jsx,ts,tsx}"
41934
+ "<detected-test-workspace>/**/*.{test,spec}.{js,jsx,ts,tsx}",
41935
+ "<detected-test-workspace>/src/test/**/*.{js,jsx,ts,tsx}"
41944
41936
  ],
41945
- recommendedWorkspaces: ["apps/web", "packages/api"],
41937
+ recommendedWorkspaces: ["detected JavaScript/TypeScript test workspaces"],
41946
41938
  placementNotes: "Attach this to test-only globs. Expand or narrow the file patterns to match the repo's actual Vitest test layout instead of treating it as a global default."
41947
41939
  };
41948
41940
  var lintCatalog = [
@@ -42193,11 +42185,11 @@ var validateLintCatalog = (catalog) => {
42193
42185
 
42194
42186
  // src/data/catalog/packs.ts
42195
42187
  var packCatalog = [
42196
- { id: "backend", category: "surface", triggerPackages: [], description: "Backend pack: domain structure and recoverable actions.", skills: ["backend-domain-structure", "backend-recoverable-actions"], lintAssets: [], hooks: [], promptSurfaces: ["shared-agents", "root-prompt-spec", "workspace-prompt-spec"], promptDetails: ["shared backend domain baseline", "workspace backend action/recovery guidance"] },
42188
+ { id: "backend", category: "surface", triggerPackages: [], description: "Backend pack: domain structure, recoverable actions, and logging.", skills: ["backend-domain-structure", "backend-recoverable-actions", "logging-best-practices"], lintAssets: [], hooks: [], promptSurfaces: ["shared-agents", "root-prompt-spec", "workspace-prompt-spec"], promptDetails: ["shared backend domain baseline", "workspace backend action/recovery guidance", "workspace logging/observability guidance"] },
42197
42189
  { id: "better-auth", category: "detected", triggerPackages: ["better-auth"], description: "Better Auth guidance pack.", skills: ["better-auth-best-practices"], lintAssets: [], hooks: [], promptSurfaces: ["shared-agents", "root-prompt-spec", "workspace-prompt-spec"], promptDetails: ["shared auth guardrails", "workspace auth boundaries"] },
42198
42190
  { id: "debug", category: "default", triggerPackages: [], description: "Default debug pack: debug-agent runtime-evidence workflow.", skills: ["debug-agent"], lintAssets: [], hooks: [], promptSurfaces: ["shared-agents", "root-prompt-spec", "workspace-prompt-spec"], promptDetails: ["shared runtime debugging baseline", "workspace evidence-first debugging workflow"] },
42199
42191
  { id: "docs", category: "default", triggerPackages: [], description: "Default docs pack: docs-maintenance.", skills: ["docs-maintenance"], lintAssets: [], hooks: [], promptSurfaces: ["shared-agents", "root-prompt-spec", "docs-prompt-spec"], promptDetails: ["shared docs baseline", "docs scope spec"] },
42200
- { id: "drizzle", category: "detected", triggerPackages: ["drizzle-kit", "drizzle-orm"], description: "Drizzle guidance pack.", skills: ["effect-backend-structure", "effect-recoverable-actions"], lintAssets: [], hooks: [], promptSurfaces: ["shared-agents", "root-prompt-spec", "workspace-prompt-spec"], promptDetails: ["shared data-layer baseline", "workspace db flow rules"] },
42192
+ { id: "drizzle", category: "detected", triggerPackages: ["drizzle-kit", "drizzle-orm"], description: "Drizzle guidance pack.", skills: [], lintAssets: [], hooks: [], promptSurfaces: ["shared-agents", "root-prompt-spec", "workspace-prompt-spec"], promptDetails: ["shared data-layer baseline", "workspace db flow rules"] },
42201
42193
  { id: "effect", category: "detected", triggerPackages: ["effect", "@effect/"], description: "Effect guidance pack family.", skills: ["effect-authoring", "effect-best-practices", "effect-backend-structure", "effect-recoverable-actions"], lintAssets: ["effect-no-barrel-imports"], hooks: [], promptSurfaces: ["shared-agents", "root-prompt-spec", "workspace-prompt-spec"], promptDetails: ["shared effect authoring baseline", "workspace service/layer rules"] },
42202
42194
  { id: "elysia", category: "detected", triggerPackages: ["elysia"], description: "Elysia guidance pack.", skills: ["elysiajs"], lintAssets: [], hooks: [], promptSurfaces: ["shared-agents", "root-prompt-spec", "workspace-prompt-spec"], promptDetails: ["shared api-server baseline", "workspace route/plugin rules"] },
42203
42195
  { id: "frontend", category: "surface", triggerPackages: [], description: "Frontend pack: agent-browser, design taste, and frontend domain structure.", skills: ["agent-browser", "design-taste-frontend", "frontend-domain-structure"], lintAssets: [], hooks: [], promptSurfaces: ["shared-agents", "root-prompt-spec", "workspace-prompt-spec"], promptDetails: ["shared product-ui baseline", "workspace UX/browser guidance", "workspace frontend domain boundaries"] },
@@ -42220,6 +42212,7 @@ var skillCatalog = [
42220
42212
  { id: "agent-browser", sourceDirectory: "skills/agnostic/frontend/agent-browser", tier: "framework", language: null, framework: "browser-automation", requiresTools: ["agent-browser"] },
42221
42213
  { id: "backend-domain-structure", sourceDirectory: "skills/agnostic/backend/backend-domain-structure", tier: "agnostic", language: null, framework: null, requiresTools: [] },
42222
42214
  { id: "backend-recoverable-actions", sourceDirectory: "skills/agnostic/backend/backend-recoverable-actions", tier: "agnostic", language: null, framework: null, requiresTools: [] },
42215
+ { id: "logging-best-practices", sourceDirectory: "skills/agnostic/backend/logging-best-practices", tier: "agnostic", language: null, framework: null, requiresTools: [] },
42223
42216
  { id: "better-auth-best-practices", sourceDirectory: "skills/frameworks/better-auth/better-auth-best-practices", tier: "framework", language: "typescript", framework: "better-auth", requiresTools: [] },
42224
42217
  { id: "create-plan", sourceDirectory: "skills/agnostic/planning/create-plan", tier: "agnostic", language: null, framework: null, requiresTools: [] },
42225
42218
  { id: "create-spec", sourceDirectory: "skills/agnostic/planning/create-spec", tier: "agnostic", language: null, framework: null, requiresTools: [] },
@@ -43135,7 +43128,6 @@ var section = (title, lines3) => [
43135
43128
  ...lines3
43136
43129
  ];
43137
43130
  var maybeSection = (title, lines3) => lines3.length === 1 && lines3[0] === " \u2205" ? [] : section(title, lines3);
43138
- var collectOpensrcReferences = (result) => [...new Set(result.promptSpecs.flatMap((spec) => spec.opensrcReferences))].toSorted();
43139
43131
  var formatDetectionSummary = (detection) => [
43140
43132
  "Scaffold detection summary",
43141
43133
  `cwd: ${detection.cwd}`,
@@ -43176,58 +43168,50 @@ var formatConfirmationSummary = (result, baseline = bundledBaseline) => [
43176
43168
  ...section("scaffold manifest:", formatList([result.scaffoldManifestFile]))
43177
43169
  ].join(`
43178
43170
  `);
43179
- var formatAgentHandoffSummary = (result) => (() => {
43180
- const opensrcReferences = collectOpensrcReferences(result);
43181
- return [
43182
- "Give this to the next agent",
43183
- "",
43184
- "You are continuing a `punks scaffold` run.",
43185
- "",
43186
- "Read first:",
43187
- ` \u2022 \`${result.scaffoldManifestFile}\``,
43188
- ` \u2022 \`${result.agentHandoffFile}\``,
43189
- ` \u2022 \`${result.requiredToolsFile}\``,
43190
- "",
43191
- ...result.toolBootstrapStatuses.length === 0 ? [] : [
43192
- "Tool bootstrap status:",
43193
- ...result.toolBootstrapStatuses.map((entry) => ` \u2022 \`${entry.toolId}\`: ${entry.status === "already-present" ? "already present" : "installed during scaffold"}`),
43194
- ""
43195
- ],
43196
- "What was scaffolded:",
43197
- " \u2022 final scoped/root prompt files were not written yet",
43198
- ...formatList([
43199
- ...result.promptOutputs,
43200
- ...result.lintSpecFiles,
43201
- ...result.skillFiles,
43202
- ...result.promptSpecFiles,
43203
- ...result.subagentFiles,
43204
- ...result.scriptFiles,
43205
- ...result.hookFiles,
43206
- ...result.harnessFiles
43207
- ]),
43208
- "",
43209
- "What you must do:",
43210
- " 1. Treat the prompt spec markdown files as instructions, not final prompt bodies.",
43211
- result.monorepo ? " 2. Repo is in monorepo mode. Generate final prompt files for root, docs, and each relevant app/package scope." : " 2. Repo is in single-repo mode. Stitch scoped guidance into one root prompt, plus docs guidance when present.",
43212
- " 3. Read `.devpunks/required-tools.json` and verify `skills`, `portless`, `opensrc`, and `agent-browser` are actually available when listed. If any are missing, install/fix that first.",
43213
- " 4. Keep the final prompt house style tight: `## ... Guidance`, `Primary skills here`, one short scope-boundary paragraph, optional `opensrc` guidance only when needed, then the docs-update rule.",
43214
- " 5. Treat every authored root/docs/workspace `AGENTS.md` file as the neutral scoped prompt source and create a sibling `CLAUDE.md` symlink mirror beside each one.",
43215
- " 6. Keep `.agents/AGENTS.md` as the shared global prompt source behind the scoped prompt tree; `.claude/CLAUDE.md` should mirror that neutral file.",
43216
- " 7. Keep `.agents/hooks/` as the neutral hook source, `.agents/skills/` as the main skill directory, and `.agents/scripts/sync-subagents.mjs` as the harness sync entrypoint. Only `.claude/skills` should mirror `.agents/skills`.",
43217
- " 8. Reconcile `.agents/subagents/manifest.mjs` with both `.agents/subagents/manifest.prompt.md` and `.devpunks/specs/subagents/manifest-spec.json`.",
43218
- " 9. Update owned paths / guidance file references in the subagent manifest to match the real repo shape.",
43219
- " 10. Use `portless` as the local-dev URL baseline. Prefer stable subdomains over raw `localhost:<port>` values in env examples, endpoint defaults, callback URLs, allowed origins, CORS, and app-to-app proxies.",
43220
- " 11. When you need source context from installed libraries, run `opensrc path <package>` or `opensrc path owner/repo`, then inspect the returned checkout path.",
43221
- ...opensrcReferences.length === 0 ? [
43222
- " 12. Use `opensrc path <package>` or `opensrc path owner/repo` to ensure local source checkouts exist only for the core framework/library sources that materially affect implementation decisions in this repo. Decide autonomously which dependencies are core enough; do not clone everything mechanically."
43223
- ] : [
43224
- " 12. Immediately use `opensrc path <package>` or `opensrc path owner/repo` to ensure local source checkouts exist for these core libraries before authoring final prompts or implementation plans. Then inspect the returned checkout paths, especially:",
43225
- ...opensrcReferences.map((reference) => ` \u2022 \`${reference}\``),
43226
- " 13. Use `opensrc path <package>` or `opensrc path owner/repo` again when you need source context from other installed libraries beyond that core set."
43227
- ]
43228
- ].join(`
43171
+ var formatAgentHandoffSummary = (result) => [
43172
+ "Give this to the next agent",
43173
+ "",
43174
+ "You are continuing a `punks scaffold` run.",
43175
+ "",
43176
+ "Read first:",
43177
+ ` \u2022 \`${result.scaffoldManifestFile}\``,
43178
+ ` \u2022 \`${result.agentHandoffFile}\``,
43179
+ ` \u2022 \`${result.requiredToolsFile}\``,
43180
+ "",
43181
+ ...result.toolBootstrapStatuses.length === 0 ? [] : [
43182
+ "Tool bootstrap status:",
43183
+ ...result.toolBootstrapStatuses.map((entry) => ` \u2022 \`${entry.toolId}\`: ${entry.status === "already-present" ? "already present" : "installed during scaffold"}`),
43184
+ ""
43185
+ ],
43186
+ "What was scaffolded:",
43187
+ " \u2022 final scoped/root prompt files were not written yet",
43188
+ ...formatList([
43189
+ ...result.promptOutputs,
43190
+ ...result.lintSpecFiles,
43191
+ ...result.skillFiles,
43192
+ ...result.promptSpecFiles,
43193
+ ...result.subagentFiles,
43194
+ ...result.scriptFiles,
43195
+ ...result.hookFiles,
43196
+ ...result.harnessFiles
43197
+ ]),
43198
+ "",
43199
+ "What you must do:",
43200
+ " 1. Treat the prompt spec markdown files as instructions, not final prompt bodies.",
43201
+ result.monorepo ? " 2. Repo is in monorepo mode. Generate final prompt files for root, docs, and each relevant app/package scope." : " 2. Repo is in single-repo mode. Stitch scoped guidance into one root prompt, plus docs guidance when present.",
43202
+ " 3. Read `.devpunks/required-tools.json` and verify `skills`, `portless`, `opensrc`, and `agent-browser` are actually available when listed. If any are missing, install/fix that first.",
43203
+ " 4. Keep the final prompt house style tight: `## ... Guidance`, `Primary skills here`, one short scope-boundary paragraph, optional `opensrc` guidance only when needed, then the docs-update rule.",
43204
+ " 5. Treat every authored root/docs/workspace `AGENTS.md` file as the neutral scoped prompt source and create a sibling `CLAUDE.md` symlink mirror beside each one.",
43205
+ " 6. Keep `.agents/AGENTS.md` as the shared global prompt source behind the scoped prompt tree; `.claude/CLAUDE.md` should mirror that neutral file.",
43206
+ " 7. Keep `.agents/hooks/` as the neutral hook source, `.agents/skills/` as the main skill directory, and `.agents/scripts/sync-subagents.mjs` as the harness sync entrypoint. Only `.claude/skills` should mirror `.agents/skills`.",
43207
+ " 8. Reconcile `.agents/subagents/manifest.mjs` with both `.agents/subagents/manifest.prompt.md` and `.devpunks/specs/subagents/manifest-spec.json`.",
43208
+ " 9. Update owned paths / guidance file references in the subagent manifest to match the real repo shape.",
43209
+ " 10. Use `portless` as the local-dev URL baseline. Prefer stable subdomains over raw `localhost:<port>` values in env examples, endpoint defaults, callback URLs, allowed origins, CORS, and app-to-app proxies.",
43210
+ " 11. If adopting Oxlint or Oxfmt, replace existing lint/format setup deliberately: package scripts, task pipelines, CI, editor/docs references, and hooks should agree on the new tools.",
43211
+ " 12. Before authoring final prompts or implementation plans, identify the core detected libraries whose source behavior matters.",
43212
+ " 13. Run `opensrc path <package>` or `opensrc path owner/repo` for those core libraries, then inspect the returned checkout paths. Clone the major framework/runtime libraries you will reason about; do not clone every dependency mechanically."
43213
+ ].join(`
43229
43214
  `);
43230
- })();
43231
43215
  var formatSelectionPreview = (options3) => [
43232
43216
  "Review scaffold selection before continuing",
43233
43217
  ...section("prefilled packs:", formatPackList(options3.preselectedPacks, options3.baseline)),
@@ -43636,9 +43620,11 @@ When a nested \`AGENTS.md\` lists "Primary skills here", treat those skill names
43636
43620
 
43637
43621
  Do not rely only on the root instructions when a scoped \`AGENTS.md\` exists.
43638
43622
 
43623
+ For code review requests, take a review stance: findings first, severity ordered, with precise file/line references. Use \`simplify\` to inspect changed code for clarity, naming, duplication, derivable state, and unnecessary abstraction. Use \`improve-codebase-architecture\` when review uncovers cross-module coupling, shallow-module sprawl, testability friction, or AI-navigation problems; surface grounded candidates and ask before turning them into broader refactor work.
43624
+
43639
43625
  When inspecting external library internals, prefer official docs first. If source context is needed, resolve cached read-only sources with \`opensrc path <package>\` for packages or \`opensrc path owner/repo\` for repositories, then inspect the returned absolute path. This applies broadly to third-party dependencies used here.
43640
43626
 
43641
- Use \`portless\` for local development URLs instead of baking raw \`localhost:<port>\` values into docs, env examples, endpoint defaults, callback URLs, allowed origins, CORS lists, or app-to-app proxy targets. Portless assigns stable \`*.localhost\` subdomains, injects \`PORT\` and \`PORTLESS_URL\` into child processes, and prefixes linked git worktrees with the branch name so parallel worktrees do not collide. When a local dev proxy calls another portless app, rewrite the host/origin (for example Vite \`changeOrigin: true\`) so the proxy reaches the intended app.
43627
+ Use \`portless\` for local development URLs instead of baking raw \`localhost:<port>\` values into docs, env examples, endpoint defaults, callback URLs, allowed origins, CORS lists, or app-to-app proxy targets.
43642
43628
 
43643
43629
  If work here changes setup, workflow, AI scaffold surfaces, or other non-obvious behavior, update \`docs/README.md\` and the relevant runbook in \`docs/runbooks/\` in the same task.`;
43644
43630
  var docsPromptTemplate = `## Docs Guidance
@@ -43671,8 +43657,7 @@ var resolveSeededWorkspacePrompt = ({
43671
43657
  "",
43672
43658
  `Primary skills here: ${renderPrimarySkills(primarySkills)}.`,
43673
43659
  "",
43674
- "This app is the frontend surface. Keep backend logic out of `apps/web`; use `packages/api` for API contracts and `packages/ui` for shared UI primitives.",
43675
- "Prefer portless URLs and `PORTLESS_URL`-aware env handling for local origins, API endpoints, OAuth/callback URLs, and browser test targets instead of hardcoded ports.",
43660
+ `This app is the frontend surface for \`${relativeWorkspacePath}\`. Keep backend logic out of this workspace; route API contracts and shared UI primitives to their owning workspaces.`,
43676
43661
  ...extraLines,
43677
43662
  "If work here changes non-obvious frontend behavior, integration constraints, or setup expectations, update `docs/README.md` and the relevant domain doc/runbook in the same task."
43678
43663
  ].join(`
@@ -43684,15 +43669,10 @@ var resolveSeededWorkspacePrompt = ({
43684
43669
  "",
43685
43670
  `Primary skills here: ${renderPrimarySkills(primarySkills)}.`,
43686
43671
  "",
43687
- "This app is the HTTP transport boundary. Keep business logic and Effect layers in `packages/api`; keep `apps/server` focused on Elysia routes, tRPC mounting, and request/response adaptation.",
43688
- "Treat portless hostnames as the local-dev origin contract. Keep CORS, callback origins, API base URLs, and service-to-service dev targets aligned with stable `*.localhost` names and worktree-prefixed subdomains.",
43672
+ `This app is the HTTP transport boundary for \`${relativeWorkspacePath}\`. Keep business logic in its owning backend/domain workspace; keep this scope focused on routes, mounting, middleware, and request/response adaptation.`,
43689
43673
  "If transport work touches Effect request/response schemas, adapters, or other Effect code, use `effect-authoring` before editing.",
43690
43674
  "",
43691
- "If you need Effect details, read `packages/api/AGENTS.md` and search:",
43692
- "",
43693
- "- `opensrc/repos/github.com/Effect-TS/effect/packages/effect`",
43694
- "- `opensrc/repos/github.com/Effect-TS/effect/packages/sql`",
43695
- "- `opensrc/repos/github.com/Effect-TS/effect/packages/sql-drizzle`",
43675
+ "If this workspace uses Effect and source behavior matters, run `opensrc path effect` or the relevant upstream repo lookup before relying on internals.",
43696
43676
  "",
43697
43677
  "If work here changes transport behavior, env/setup, or integration boundaries, update `docs/README.md` and the relevant domain doc/runbook in the same task."
43698
43678
  ].join(`
@@ -43705,10 +43685,8 @@ var resolveSeededWorkspacePrompt = ({
43705
43685
  `Primary skills here: ${renderPrimarySkills(primarySkills)}.`,
43706
43686
  "",
43707
43687
  "This app owns the `punks` CLI surface, repo detection flow, and scaffold-spec orchestration. Keep prompt/spec resolution logic in `apps/cli`; do not leak repo-specific business logic into this app.",
43708
- "When scaffold guidance touches local development URLs, include portless guidance for stable subdomains, worktree isolation, and env/origin/proxy alignment.",
43709
- "If you need Effect details, search:",
43710
- "",
43711
- "- `opensrc/repos/github.com/Effect-TS/effect/packages/effect`",
43688
+ "When scaffold guidance touches local development URLs, keep portless guidance concise and repo-wide unless a scoped prompt owns URL/proxy configuration.",
43689
+ "If Effect source behavior matters, run `opensrc path effect` before relying on internals.",
43712
43690
  "",
43713
43691
  "If work here changes operator workflow, setup, or AI scaffolding behavior, update `docs/README.md` and the relevant runbook in the same task."
43714
43692
  ].join(`
@@ -43720,14 +43698,11 @@ var resolveSeededWorkspacePrompt = ({
43720
43698
  "",
43721
43699
  `Primary skills here: ${renderPrimarySkills(primarySkills)}.`,
43722
43700
  "",
43723
- "`packages/api` is the home for Effect application logic and tRPC procedures. Keep HTTP transport concerns in `apps/server`.",
43724
- "Use `effect-authoring` before writing or refactoring Effect code. Use `effect-backend-structure` for repo-specific backend layout, and `effect-recoverable-actions` for multi-step mutation flows that need an explicit rollback/repair strategy.",
43725
- "",
43726
- "If you need Effect details, search:",
43701
+ `\`${relativeWorkspacePath}\` is the backend/domain workspace. Keep HTTP transport concerns in the transport app when the repo has one.`,
43702
+ "Use Effect skills only when this workspace actually uses Effect. For non-Effect Drizzle/backend code, follow the local backend prompt and nearest package conventions.",
43703
+ "Use `logging-best-practices` when adding or changing backend logging, request context, audit events, telemetry-adjacent diagnostics, or production debugging signals.",
43727
43704
  "",
43728
- "- `opensrc/repos/github.com/Effect-TS/effect/packages/effect`",
43729
- "- `opensrc/repos/github.com/Effect-TS/effect/packages/sql`",
43730
- "- `opensrc/repos/github.com/Effect-TS/effect/packages/sql-drizzle`",
43705
+ "If Effect source behavior matters, run `opensrc path effect` or the relevant upstream repo lookup before relying on internals.",
43731
43706
  "",
43732
43707
  "If work here changes procedures, domain boundaries, layer contracts, or required setup, update `docs/README.md` and the relevant domain doc/runbook in the same task."
43733
43708
  ].join(`
@@ -43758,7 +43733,7 @@ var resolveSeededWorkspacePrompt = ({
43758
43733
  "",
43759
43734
  `Primary skills here: ${renderPrimarySkills(primarySkills)}.`,
43760
43735
  "",
43761
- "This package owns shared frontend/UI primitives used by `apps/web`. Keep package APIs reusable and presentation-focused.",
43736
+ `\`${relativeWorkspacePath}\` owns shared frontend/UI primitives. Keep package APIs reusable and presentation-focused.`,
43762
43737
  ...extraLines,
43763
43738
  "If work here changes shared primitives, design tokens, or usage expectations, update `docs/README.md` and the relevant domain doc/runbook in the same task."
43764
43739
  ].join(`
@@ -43796,9 +43771,9 @@ var renderPromptSpecMarkdown = (spec) => [
43796
43771
  "- Follow with one short paragraph defining the scope boundary: what belongs here vs elsewhere.",
43797
43772
  "- Treat every authored `AGENTS.md` file as the neutral source of truth and create a sibling `CLAUDE.md` symlink mirror that points to it.",
43798
43773
  "- Add `opensrc` / source-inspection guidance only when this scope actually needs it.",
43799
- "- Add portless guidance anywhere local dev URLs, origins, callbacks, endpoint env vars, CORS, or app-to-app proxies are configured.",
43774
+ "- Add portless guidance only to the root/handoff, or to a scoped prompt that directly owns local URL, origin, callback, CORS, or proxy configuration.",
43800
43775
  "- End with the docs-update rule when work in this scope changes setup, workflow, contracts, or non-obvious behavior.",
43801
- "- Add extra focused sections only when the scope truly needs them, like the `packages/api` recoverable-action guidance.",
43776
+ "- Add extra focused sections only when the detected scope truly needs them.",
43802
43777
  "",
43803
43778
  "## Selected packs",
43804
43779
  "",
@@ -43808,18 +43783,17 @@ var renderPromptSpecMarkdown = (spec) => [
43808
43783
  "",
43809
43784
  ...bulletList(spec.primarySkills, "- `simplify`"),
43810
43785
  "",
43811
- "## Opensrc references",
43786
+ "## Source inspection",
43812
43787
  "",
43813
- ...bulletList(spec.opensrcReferences, "- `(none required for this scope)`"),
43788
+ "- No concrete `opensrc` repositories are preselected by scaffold.",
43789
+ "- During post-scaffold setup, decide which detected core libraries materially affect prompt or lint authoring, then run `opensrc path <package>` or `opensrc path owner/repo` for those libraries before relying on source behavior.",
43814
43790
  "",
43815
43791
  "## Authoring guidance",
43816
43792
  "",
43817
43793
  "- Keep the final prompt concise, imperative, and scope-first.",
43818
- "- Match the existing repo house style used by prompts like `apps/server/AGENTS.md`, `apps/web/AGENTS.md`, and `packages/api/AGENTS.md`.",
43794
+ "- Match the existing repo house style used by the detected workspace prompt files.",
43819
43795
  "- Preserve this order: heading, `Primary skills here`, scope boundary, optional `opensrc`, docs update rule.",
43820
43796
  "- Route broader monorepo concerns back to the root prompt instead of repeating them in every scope.",
43821
- "- Prefer portless stable URLs like `https://web.project.localhost` and `https://api.project.localhost` over hardcoded `localhost:<port>` values in docs, env examples, callback URLs, allowed origins, and local proxy targets.",
43822
- "- When one local app proxies to another through portless, configure the proxy to rewrite the host/origin (for example Vite `changeOrigin: true`) so requests route to the intended app instead of looping back.",
43823
43797
  "- If a seed prompt exists in the source repo, preserve repo-specific constraints while reconciling them with the detected pack set.",
43824
43798
  "- Keep docs-maintenance workflow in prompt files, not in generated docs pages."
43825
43799
  ].join(`
@@ -43840,8 +43814,7 @@ var renderAgentHandoffMarkdown = ({
43840
43814
  harnessFiles,
43841
43815
  scaffoldManifestFile,
43842
43816
  requiredToolsFile,
43843
- toolBootstrapStatuses,
43844
- opensrcReferences
43817
+ toolBootstrapStatuses
43845
43818
  }) => [
43846
43819
  "# Agent Handoff",
43847
43820
  "",
@@ -43874,20 +43847,13 @@ var renderAgentHandoffMarkdown = ({
43874
43847
  monorepo ? "4. Because this repo is in monorepo mode, create scoped prompt files for the root, docs scope when present, and each relevant app/package scope." : "4. Because this repo is in single-repo mode, stitch scope guidance into a single root prompt plus docs guidance when present.",
43875
43848
  "5. Author every root/docs/workspace `AGENTS.md` file as the neutral prompt source of truth and create a sibling `CLAUDE.md` symlink mirror beside each one instead of maintaining duplicated prompt bodies.",
43876
43849
  "6. Keep `.agents/AGENTS.md` as the shared global guidance source behind the scoped prompt tree; `.claude/CLAUDE.md` should stay a symlink mirror of that neutral file.",
43877
- "7. Prefer portless stable local URLs over raw localhost ports in env examples, endpoint constants, callback URLs, allowed origins, CORS, and app-to-app proxy targets. Account for worktree-prefixed subdomains.",
43850
+ "7. Keep portless as the repo-wide local URL baseline: prefer stable local subdomains over raw localhost ports where env examples, endpoint constants, callback URLs, allowed origins, CORS, or app-to-app proxy targets are configured.",
43878
43851
  "8. Use the lint asset specs to reconcile repo Oxlint config. If the repo has no Oxlint config yet, start from the generated starter config instead of inventing a baseline.",
43879
43852
  "9. Keep `.agents/hooks/` as the neutral hook source of truth; harness hook mirrors should point back to it.",
43880
43853
  "10. Use `.agents/scripts/sync-subagents.mjs` to regenerate harness-native agents, hook mirrors, shared prompt mirrors, and the `.claude/skills` compatibility mirror when the neutral manifest changes.",
43881
43854
  "11. Populate or reconcile `.agents/subagents/manifest.mjs` using both the manifest spec JSON and the manifest prompt markdown.",
43882
43855
  "12. Adjust owned paths and guidance file references in the subagent manifest to match the real repo layout. Monorepo vs single-repo shape affects these paths.",
43883
- "13. When inspecting installed libraries or packages in this repo, run `opensrc path <package>` or `opensrc path owner/repo`, then inspect the returned checkout path for source context instead of mutating vendored code.",
43884
- ...opensrcReferences.length === 0 ? [
43885
- "14. Use `opensrc path <package>` or `opensrc path owner/repo` to ensure local source checkouts exist only for the core framework/library sources that materially affect implementation decisions in this repo. Decide autonomously which dependencies are core enough; do not clone everything mechanically."
43886
- ] : [
43887
- "14. Immediately use `opensrc path <package>` or `opensrc path owner/repo` to ensure local source checkouts exist for these core libraries before authoring final prompts or implementation plans. Then inspect the returned checkout paths, especially:",
43888
- ...opensrcReferences.map((reference) => `- \`${reference}\``),
43889
- "15. Use `opensrc path <package>` or `opensrc path owner/repo` again when you need source context from other installed libraries beyond that core set."
43890
- ],
43856
+ "13. Before authoring final prompts or implementation plans, identify the core detected libraries whose source behavior matters, run `opensrc path <package>` or `opensrc path owner/repo` for those libraries, then inspect the returned checkout paths. Clone the major framework/runtime libraries you will reason about; do not clone every dependency mechanically.",
43891
43857
  "",
43892
43858
  "## Shared core files",
43893
43859
  "",
@@ -43933,6 +43899,8 @@ var renderLintSpecMarkdown = ({
43933
43899
  "",
43934
43900
  "Use these selected Oxlint assets to fit the target repo's real lint topology.",
43935
43901
  "Treat each asset as an atomic override payload plus placement guidance, not as a pre-merged final `.oxlintrc.json` block.",
43902
+ "If you adopt Oxlint or Oxfmt, replace the repo's existing lint/format entrypoints deliberately: update package scripts, task pipelines, editor/docs references, and agent hooks together so old ESLint/Prettier commands do not remain as stale defaults.",
43903
+ "If the repo already has lint/format tooling, preserve project-specific ignores, generated-file exclusions, and CI behavior while migrating; do not overwrite working config wholesale.",
43936
43904
  "",
43937
43905
  "## Baseline",
43938
43906
  "",
@@ -44062,7 +44030,8 @@ var specPathForPromptTarget = (relativePath) => {
44062
44030
  return path8.join(".devpunks/specs/prompts", path8.dirname(relativePath), "prompt.md");
44063
44031
  };
44064
44032
  var uniqueSorted = (values3) => [...new Set(values3)].toSorted();
44065
- var collectOpensrcReferences2 = (promptSpecs) => uniqueSorted(promptSpecs.flatMap((spec) => spec.opensrcReferences));
44033
+ var collectOpensrcReferences = (promptSpecs) => uniqueSorted(promptSpecs.flatMap((spec) => spec.opensrcReferences));
44034
+ var detectionHasPackage = (detection, packageName) => detection.manifests.some((manifest) => manifest.dependencies.includes(packageName));
44066
44035
  var selectedSkills = (finalPacks, baseline) => uniqueSorted(finalPacks.flatMap((packId) => skillsForPack(packId, baseline)));
44067
44036
  var selectedHookIds = (finalPacks, baseline) => uniqueSorted(finalPacks.flatMap((packId) => hooksForPack(packId, baseline)));
44068
44037
  var oxlintConfigCandidates = [
@@ -44109,7 +44078,11 @@ var packsForWorkspace = ({
44109
44078
  const hasDependency = (name) => dependencies.has(name);
44110
44079
  const hasDependencyPrefix = (prefix) => dependencyNames.some((name) => name.startsWith(prefix));
44111
44080
  const hasBackendDependency = () => hasDependency("better-auth") || hasDependency("drizzle-orm") || hasDependency("drizzle-kit") || hasDependency("elysia") || hasDependencyPrefix("@trpc/");
44081
+ const hasFrontendDependency = () => hasDependency("next") || hasDependency("react") || hasDependency("react-dom") || hasDependency("@tanstack/react-query");
44082
+ const hasFrontendWorkspaceName = () => relativeWorkspacePath.split(path8.sep).some((segment) => segment === "frontend" || segment === "ui" || segment === "web") || (manifest?.packageName?.replace(/^@[^/]+\//u, "").split(/[^a-zA-Z0-9]+/u).filter((segment) => segment.length > 0).map((segment) => segment.toLowerCase()).some((segment) => segment === "frontend" || segment === "ui" || segment === "web") ?? false);
44112
44083
  const hasBackendWorkspaceName2 = () => relativeWorkspacePath.split(path8.sep).some((segment) => segment === "api" || segment === "backend" || segment === "server" || segment === "services") || (manifest?.packageName?.replace(/^@[^/]+\//u, "").split(/[^a-zA-Z0-9]+/u).filter((segment) => segment.length > 0).map((segment) => segment.toLowerCase()).some((segment) => segment === "api" || segment === "backend" || segment === "server" || segment === "service") ?? false);
44084
+ const isFrontendWorkspace = hasFrontendDependency() || hasFrontendWorkspaceName();
44085
+ const isBackendWorkspace = hasBackendDependency() || hasBackendWorkspaceName2();
44113
44086
  const packs = [];
44114
44087
  if (selectedPacks.has("quality")) {
44115
44088
  packs.push("quality");
@@ -44147,7 +44120,7 @@ var packsForWorkspace = ({
44147
44120
  }
44148
44121
  return uniqueSorted(packs);
44149
44122
  }
44150
- if (relativeWorkspacePath === "apps/web" || relativeWorkspacePath === "packages/ui") {
44123
+ if (isFrontendWorkspace) {
44151
44124
  if (selectedPacks.has("frontend")) {
44152
44125
  packs.push("frontend");
44153
44126
  }
@@ -44161,7 +44134,7 @@ var packsForWorkspace = ({
44161
44134
  packs.push("tanstack-query");
44162
44135
  }
44163
44136
  }
44164
- if (relativeWorkspacePath === "apps/server") {
44137
+ if (isBackendWorkspace && !isFrontendWorkspace) {
44165
44138
  if (selectedPacks.has("backend")) {
44166
44139
  packs.push("backend");
44167
44140
  }
@@ -44183,20 +44156,6 @@ var packsForWorkspace = ({
44183
44156
  packs.push("turborepo");
44184
44157
  }
44185
44158
  }
44186
- if (relativeWorkspacePath === "packages/api") {
44187
- if (selectedPacks.has("backend")) {
44188
- packs.push("backend");
44189
- }
44190
- if (selectedPacks.has("effect")) {
44191
- packs.push("effect");
44192
- }
44193
- if (selectedPacks.has("drizzle")) {
44194
- packs.push("drizzle");
44195
- }
44196
- if (selectedPacks.has("trpc")) {
44197
- packs.push("trpc");
44198
- }
44199
- }
44200
44159
  if (relativeWorkspacePath === "packages/auth" && selectedPacks.has("better-auth")) {
44201
44160
  packs.push("better-auth");
44202
44161
  }
@@ -44234,7 +44193,7 @@ var packsForWorkspace = ({
44234
44193
  if (packId === "frontend" && (hasDependency("react") || hasDependency("next"))) {
44235
44194
  packs.push(packId);
44236
44195
  }
44237
- if (packId === "backend" && (hasBackendDependency() || hasBackendWorkspaceName2())) {
44196
+ if (packId === "backend" && isBackendWorkspace && !isFrontendWorkspace) {
44238
44197
  packs.push(packId);
44239
44198
  }
44240
44199
  }
@@ -44255,16 +44214,6 @@ var primarySkillsForWorkspace = ({
44255
44214
  const skills = workspacePacks.flatMap((packId) => skillsForPack(packId, baseline));
44256
44215
  return uniqueSorted(skills);
44257
44216
  };
44258
- var opensrcReferencesForWorkspace = (relativeWorkspacePath, packs) => {
44259
- if (relativeWorkspacePath === "apps/server" || relativeWorkspacePath === "packages/api" || packs.includes("effect") || packs.includes("drizzle")) {
44260
- return [
44261
- "opensrc/repos/github.com/Effect-TS/effect/packages/effect",
44262
- "opensrc/repos/github.com/Effect-TS/effect/packages/sql",
44263
- "opensrc/repos/github.com/Effect-TS/effect/packages/sql-drizzle"
44264
- ];
44265
- }
44266
- return [];
44267
- };
44268
44217
  var buildPromptSpec = ({
44269
44218
  scanDirectory,
44270
44219
  relativePath,
@@ -44294,7 +44243,7 @@ var buildPromptSpec = ({
44294
44243
  baseline
44295
44244
  }),
44296
44245
  packs,
44297
- opensrcReferences: opensrcReferencesForWorkspace(workspacePath, packs)
44246
+ opensrcReferences: []
44298
44247
  };
44299
44248
  };
44300
44249
  var buildSubagentManifestSpec = ({
@@ -44525,8 +44474,10 @@ var writeScaffoldOutput = ({
44525
44474
  const hookFiles = [];
44526
44475
  const harnessFiles = [];
44527
44476
  const finalSkills = selectedSkills(finalPacks, baseline);
44528
- const finalHookIds = selectedHookIds(finalPacks, baseline);
44529
- const lintAssets = resolveLintAssetsForPacks(finalPacks, baseline);
44477
+ const hasOxlint = detectionHasPackage(detection, "oxlint");
44478
+ const hasOxfmt = detectionHasPackage(detection, "oxfmt");
44479
+ const finalHookIds = selectedHookIds(finalPacks, baseline).filter((hookId) => hookId !== "format-edited-file" || hasOxfmt);
44480
+ const lintAssets = hasOxlint ? resolveLintAssetsForPacks(finalPacks, baseline) : [];
44530
44481
  const lintAssetIdsByPack = Object.fromEntries(finalPacks.map((packId) => [packId, lintAssets.filter((asset) => asset.sourcePacks.includes(packId)).map((asset) => asset.id)]).filter(([, assetIds]) => assetIds.length > 0));
44531
44482
  const rootOxlintConfigFiles = existingOxlintConfigFiles(scanDirectory);
44532
44483
  const hasExistingRootOxlintConfig = rootOxlintConfigFiles.length > 0;
@@ -44539,7 +44490,7 @@ var writeScaffoldOutput = ({
44539
44490
  finalPacks,
44540
44491
  baseline
44541
44492
  }));
44542
- const opensrcReferences = collectOpensrcReferences2(promptSpecs);
44493
+ const opensrcReferences = collectOpensrcReferences(promptSpecs);
44543
44494
  generatedFiles.push(writeArtifact({
44544
44495
  outputDirectory,
44545
44496
  relativePath: ".agents/AGENTS.md",
@@ -44923,12 +44874,26 @@ var runScaffold = ({
44923
44874
  ensureTools = true,
44924
44875
  baseline = bundledBaseline
44925
44876
  }) => exports_Effect.gen(function* () {
44926
- const detection = applyRepoShapeMode(yield* detectRepository(scanDirectory), repoShapeMode);
44927
- const resolved = resolvePackSelection(detection, baseline);
44877
+ const baseRequiredTools = requiredToolsForSkills([], baseline);
44878
+ let toolBootstrapStatuses = [];
44928
44879
  const resolvedOutputDirectory = path9.resolve(outputDirectory ?? scanDirectory);
44929
44880
  yield* prompt4.writeLine(renderScaffoldTitle());
44930
44881
  yield* prompt4.writeLine("");
44931
44882
  yield* prompt4.writeLine(renderSetupIntro());
44883
+ if (ensureTools && baseRequiredTools.length > 0) {
44884
+ yield* prompt4.writeLine("");
44885
+ yield* prompt4.writeLine(renderHint(`Checking base scaffold tools: ${baseRequiredTools.join(", ")}`));
44886
+ toolBootstrapStatuses = yield* exports_Effect.try({
44887
+ try: () => ensureToolsInstalled(baseRequiredTools, baseline),
44888
+ catch: (cause3) => new CliValidationError({
44889
+ message: cause3 instanceof Error ? cause3.message : "Failed to install required base scaffold tools."
44890
+ })
44891
+ });
44892
+ yield* prompt4.writeLine(renderCommandSection("Base tool check", toolBootstrapStatuses.map((entry) => `\u2022 ${entry.toolId}: ${entry.status === "already-present" ? "already present" : "installed during scaffold"}`).join(`
44893
+ `)));
44894
+ }
44895
+ const detection = applyRepoShapeMode(yield* detectRepository(scanDirectory), repoShapeMode);
44896
+ const resolved = resolvePackSelection(detection, baseline);
44932
44897
  yield* prompt4.writeLine("");
44933
44898
  yield* prompt4.writeLine(renderCommandSection("Detection", formatDetectionSummary(detection)));
44934
44899
  yield* prompt4.writeLine("");
@@ -44984,17 +44949,22 @@ var runScaffold = ({
44984
44949
  }
44985
44950
  const skillIds = selectedSkills2(finalPacks, baseline);
44986
44951
  const requiredTools = requiredToolsForSkills(skillIds, baseline);
44987
- let toolBootstrapStatuses = [];
44988
- if (ensureTools && requiredTools.length > 0) {
44952
+ const checkedToolIds = new Set(toolBootstrapStatuses.map((entry) => entry.toolId));
44953
+ const remainingRequiredTools = requiredTools.filter((toolId) => !checkedToolIds.has(toolId));
44954
+ if (ensureTools && remainingRequiredTools.length > 0) {
44989
44955
  yield* prompt4.writeLine("");
44990
- yield* prompt4.writeLine(renderHint(`Ensuring required tools: ${requiredTools.join(", ")}`));
44991
- toolBootstrapStatuses = yield* exports_Effect.try({
44992
- try: () => ensureToolsInstalled(requiredTools, baseline),
44956
+ yield* prompt4.writeLine(renderHint(`Ensuring selected-pack tools: ${remainingRequiredTools.join(", ")}`));
44957
+ const remainingToolBootstrapStatuses = yield* exports_Effect.try({
44958
+ try: () => ensureToolsInstalled(remainingRequiredTools, baseline),
44993
44959
  catch: (cause3) => new CliValidationError({
44994
44960
  message: cause3 instanceof Error ? cause3.message : "Failed to install required scaffold tools."
44995
44961
  })
44996
44962
  });
44997
- yield* prompt4.writeLine(renderCommandSection("Tool bootstrap", toolBootstrapStatuses.map((entry) => `\u2022 ${entry.toolId}: ${entry.status === "already-present" ? "already present" : "installed during scaffold"}`).join(`
44963
+ toolBootstrapStatuses = [
44964
+ ...toolBootstrapStatuses,
44965
+ ...remainingToolBootstrapStatuses
44966
+ ].toSorted((left3, right3) => left3.toolId.localeCompare(right3.toolId));
44967
+ yield* prompt4.writeLine(renderCommandSection("Tool bootstrap", remainingToolBootstrapStatuses.map((entry) => `\u2022 ${entry.toolId}: ${entry.status === "already-present" ? "already present" : "installed during scaffold"}`).join(`
44998
44968
  `)));
44999
44969
  }
45000
44970
  const scaffoldOutput = yield* writeScaffoldOutput({
@@ -46998,29 +46968,51 @@ var updateDpCliSkill = (scope5) => {
46998
46968
  });
46999
46969
  return result.status === 0;
47000
46970
  };
47001
- var updateDpCliSkillIfPresent = () => {
46971
+ var installDpCliSkillGlobal = () => {
46972
+ const result = spawnSync("skills", [
46973
+ "add",
46974
+ "wearedevpunks/skills",
46975
+ "--global",
46976
+ "--skill",
46977
+ "dp-cli",
46978
+ "--yes"
46979
+ ], {
46980
+ stdio: "ignore",
46981
+ shell: false,
46982
+ timeout: 30000
46983
+ });
46984
+ return result.status === 0;
46985
+ };
46986
+ var ensureDpCliSkillPresent = () => {
47002
46987
  if (!commandExists2("skills")) {
47003
46988
  return {
46989
+ skillsCliAvailable: false,
47004
46990
  detected: false,
47005
46991
  project: false,
47006
46992
  global: false,
46993
+ installedGlobal: false,
47007
46994
  updatedProject: false,
47008
46995
  updatedGlobal: false
47009
46996
  };
47010
46997
  }
47011
- const project3 = listSkills("project").some((skill) => skill.name === "dp-cli");
47012
- const global = listSkills("global").some((skill) => skill.name === "dp-cli");
46998
+ const projectBeforeInstall = listSkills("project").some((skill) => skill.name === "dp-cli");
46999
+ const globalBeforeInstall = listSkills("global").some((skill) => skill.name === "dp-cli");
47000
+ const installedGlobal = projectBeforeInstall || globalBeforeInstall ? false : installDpCliSkillGlobal();
47001
+ const project3 = projectBeforeInstall;
47002
+ const global = globalBeforeInstall || installedGlobal || listSkills("global").some((skill) => skill.name === "dp-cli");
47013
47003
  return {
47004
+ skillsCliAvailable: true,
47014
47005
  detected: project3 || global,
47015
47006
  project: project3,
47016
47007
  global,
47008
+ installedGlobal,
47017
47009
  updatedProject: project3 ? updateDpCliSkill("project") : false,
47018
47010
  updatedGlobal: global ? updateDpCliSkill("global") : false
47019
47011
  };
47020
47012
  };
47021
47013
 
47022
47014
  // src/index.ts
47023
- var app = exports_Command.make("punks", {}, () => exports_Effect.sync(() => console.log(renderCommandGuide()))).pipe(exports_Command.withDescription("DevPunks AI scaffolding CLI."), exports_Command.withSubcommands([scaffoldCommand, updateCommand]));
47015
+ var app = exports_Command.make("punks", {}, () => exports_Effect.sync(() => console.log(renderCommandGuide()))).pipe(exports_Command.withDescription("Devpunks AI scaffolding CLI."), exports_Command.withSubcommands([scaffoldCommand, updateCommand]));
47024
47016
  var cli = exports_Command.run(app, {
47025
47017
  name: "punks",
47026
47018
  version: cliVersion
@@ -47048,6 +47040,6 @@ var dpCliSkillUpdate = exports_Effect.sync(() => {
47048
47040
  if (!shouldCheckDpCliSkillUpdate()) {
47049
47041
  return;
47050
47042
  }
47051
- updateDpCliSkillIfPresent();
47043
+ ensureDpCliSkillPresent();
47052
47044
  });
47053
47045
  exports_Effect.zipRight(exports_Effect.zipRight(selfUpdateNotice, dpCliSkillUpdate), cli(process.argv)).pipe(exports_Effect.provide(exports_Layer.mergeAll(exports_BunContext.layer)), exports_BunRuntime.runMain);