@remcostoeten/use-shortcut 2.0.1 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md DELETED
@@ -1,66 +0,0 @@
1
- # Changelog
2
-
3
- All notable changes to this project will be documented in this file.
4
-
5
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
-
8
- ## [2.0.1] - 2026-03-11
9
-
10
- ### Fixed
11
-
12
- - Re-exported `useShortcutMap`, `registerShortcutMap`, `createShortcutGroup`, and `useShortcutGroup` from the public package entrypoint.
13
- - Re-exported shortcut map and shortcut group types from the public package entrypoint.
14
-
15
- ### Changed
16
-
17
- - Updated the README to document the public shortcut map API.
18
-
19
- ## [2.0.0] - 2026-03-04
20
-
21
- ### Changed
22
-
23
- - Removed non-React public entry points (`createShortcut`, `createShortcutMap`) to focus package API on React-first usage.
24
-
25
- ## [1.3.0] - 2026-02-28
26
-
27
- ### Added
28
-
29
- - Shortcut groups with `createShortcutGroup()` and `useShortcutGroup()` for bulk cleanup
30
- - Priority-based ordering and `stopOnMatch` for overlapping shortcuts
31
- - Global `eventFilter` hook option to guard shortcut handling per event
32
-
33
- ## [1.2.0] - 2026-02-28
34
-
35
- ### Added
36
-
37
- - CLI `scaffold` command to generate a scalable React/Next shortcut architecture
38
- - Scaffolded architecture with typed registry, scopes, provider state/actions, runtime mapping, and persistence adapter
39
- - `init --architecture` alias for architecture scaffolding workflow
40
- - Human architecture docs (`docs/app-architecture.md`) and LLM-focused architecture contract (`docs/app-architecture.llm.md`)
41
- - `LLM.txt` updates covering the new architecture scaffolding model
42
-
43
- ## [1.1.0] - 2026-02-28
44
-
45
- ### Added
46
-
47
- - Sequence/chord support with `.then()` for multi-step shortcuts (`$.key("g").then("d")`)
48
- - Named scope/context system with `.in()` and runtime scope controls (`setScopes`, `enableScope`, `disableScope`)
49
- - Conflict detection for exact overlaps and sequence-prefix collisions, including `mod` cross-platform normalization
50
- - `useShortcutMap`, `createShortcutMap`, and `registerShortcutMap` bulk registration helpers
51
- - Recording mode via `$.record()` to capture the next key combo
52
- - Test suite using Vitest + jsdom for advanced feature coverage
53
-
54
- ## [1.0.0] - 2026-01-22
55
-
56
- ### Added
57
-
58
- - Chainable API for fluent shortcut definitions (`$.cmd.key("s").on(handler)`)
59
- - Cross-platform `mod` modifier (⌘ on Mac, Ctrl on Windows/Linux)
60
- - Context-aware exceptions with `.except()` for inputs, modals, and custom predicates
61
- - Full TypeScript intellisense at every step of the chain
62
- - Platform-aware display formatting (⌘S on Mac, Ctrl+S on Windows)
63
- - `useShortcut` hook for React with automatic cleanup
64
- - `createShortcut` for non-React usage
65
- - CLI for shadcn-style copy-paste installation
66
- - Shortcut result object with `enable()`, `disable()`, `trigger()`, and `unbind()`
@@ -1,455 +0,0 @@
1
- #!/usr/bin/env node
2
- import{existsSync as h,mkdirSync as f,readFileSync as w,writeFileSync as x}from"fs";import{join as l,dirname as B}from"path";import{fileURLToPath as I}from"url";function m(t){return{"scopes.ts":`/** App-defined scope catalog used by the scaffolded provider. */
3
- export const shortcutScopes = ["global", "navigation", "editor", "modal"] as const
4
-
5
- export type ShortcutScope = (typeof shortcutScopes)[number]
6
-
7
- /** Default active scopes at provider boot. */
8
- export const defaultActiveScopes: ShortcutScope[] = ["global", "navigation"]
9
-
10
- /**
11
- * Normalizes a scope input into an array form.
12
- *
13
- * @param scopes - One or many scope names
14
- * @returns Array of scope names
15
- */
16
- export function normalizeScopes(scopes: ShortcutScope | ShortcutScope[]): ShortcutScope[] {
17
- return Array.isArray(scopes) ? scopes : [scopes]
18
- }
19
- `,"registry.ts":`import type { HandlerOptions } from "@remcostoeten/use-shortcut"
20
- import type { ShortcutScope } from "./scopes"
21
-
22
- export type ShortcutDefinition = {
23
- description: string
24
- defaultKeys: string | string[]
25
- scopes: ShortcutScope[]
26
- options?: Omit<HandlerOptions, "scopes">
27
- }
28
-
29
- export const shortcutRegistry = {
30
- openCommandPalette: {
31
- description: "Open global command palette",
32
- defaultKeys: "mod+k",
33
- scopes: ["global", "navigation"],
34
- },
35
- saveDocument: {
36
- description: "Save the active editor document",
37
- defaultKeys: "mod+s",
38
- scopes: ["editor"],
39
- },
40
- goDashboard: {
41
- description: "Navigate to dashboard (vim style sequence)",
42
- defaultKeys: ["g", "d"],
43
- scopes: ["navigation"],
44
- },
45
- closeOverlay: {
46
- description: "Close active overlay",
47
- defaultKeys: "escape",
48
- scopes: ["global", "modal"],
49
- },
50
- } as const satisfies Record<string, ShortcutDefinition>
51
-
52
- export type ShortcutActionId = keyof typeof shortcutRegistry
53
- export type ShortcutBindings = Record<ShortcutActionId, string | string[]>
54
- `,"types.ts":`import type { ShortcutActionId, ShortcutBindings } from "./registry"
55
- import type { ShortcutScope } from "./scopes"
56
-
57
- export type ShortcutHandlers = Record<ShortcutActionId, (event: KeyboardEvent) => void>
58
-
59
- export type ShortcutState = {
60
- activeScopes: ShortcutScope[]
61
- bindings: ShortcutBindings
62
- enabled: boolean
63
- }
64
-
65
- export type ShortcutActions = {
66
- setScopes: (scopes: ShortcutScope | ShortcutScope[]) => void
67
- enableScope: (scope: ShortcutScope) => void
68
- disableScope: (scope: ShortcutScope) => void
69
- setBinding: (actionId: ShortcutActionId, keys: string | string[]) => void
70
- resetBinding: (actionId: ShortcutActionId) => void
71
- resetBindings: () => void
72
- setEnabled: (enabled: boolean) => void
73
- }
74
-
75
- export type ShortcutMeta = {
76
- hasBindingOverrides: boolean
77
- availableActions: ShortcutActionId[]
78
- }
79
-
80
- export type ShortcutContextValue = {
81
- state: ShortcutState
82
- actions: ShortcutActions
83
- meta: ShortcutMeta
84
- }
85
- `,"runtime.ts":`import type { ShortcutMap } from "@remcostoeten/use-shortcut"
86
- import { shortcutRegistry, type ShortcutActionId, type ShortcutBindings } from "./registry"
87
- import type { ShortcutHandlers } from "./types"
88
-
89
- /**
90
- * Returns a fresh binding object seeded from \`shortcutRegistry\` defaults.
91
- *
92
- * @returns Default shortcut bindings for every registered action
93
- */
94
- export function createDefaultShortcutBindings(): ShortcutBindings {
95
- const bindings = {} as ShortcutBindings
96
-
97
- for (const actionId of Object.keys(shortcutRegistry) as ShortcutActionId[]) {
98
- bindings[actionId] = shortcutRegistry[actionId].defaultKeys
99
- }
100
-
101
- return bindings
102
- }
103
-
104
- /**
105
- * Builds a \`ShortcutMap\` by combining current bindings with action handlers.
106
- * Actions without handlers are skipped.
107
- *
108
- * @param bindings - Current binding state (defaults + user overrides)
109
- * @param handlers - Runtime action handlers from the consuming app
110
- * @returns Runtime shortcut map consumable by \`registerShortcutMap\`
111
- */
112
- export function buildShortcutMap(bindings: ShortcutBindings, handlers: ShortcutHandlers): ShortcutMap {
113
- const map: ShortcutMap = {}
114
-
115
- for (const actionId of Object.keys(shortcutRegistry) as ShortcutActionId[]) {
116
- const definition = shortcutRegistry[actionId]
117
- const handler = handlers[actionId]
118
-
119
- if (!handler) {
120
- continue
121
- }
122
-
123
- map[actionId] = {
124
- keys: bindings[actionId],
125
- handler,
126
- options: {
127
- ...definition.options,
128
- scopes: definition.scopes,
129
- description: definition.description,
130
- },
131
- }
132
- }
133
-
134
- return map
135
- }
136
- `,"storage.ts":`import type { ShortcutActionId, ShortcutBindings } from "./registry"
137
-
138
- /** Default localStorage key used by the scaffolded shortcut provider. */
139
- export const DEFAULT_SHORTCUT_STORAGE_KEY = "app-shortcut-bindings"
140
-
141
- function _isBindingValue(value: unknown): value is string | string[] {
142
- if (typeof value === "string") return true
143
- return Array.isArray(value) && value.every((entry) => typeof entry === "string")
144
- }
145
-
146
- /**
147
- * Loads persisted shortcut binding overrides from localStorage.
148
- *
149
- * @param storageKey - Storage key namespace
150
- * @returns Partial binding overrides keyed by action id
151
- */
152
- export function loadShortcutBindings(storageKey: string): Partial<ShortcutBindings> {
153
- if (typeof window === "undefined") return {}
154
-
155
- try {
156
- const raw = window.localStorage.getItem(storageKey)
157
- if (!raw) return {}
158
-
159
- const parsed = JSON.parse(raw) as unknown
160
- if (!parsed || typeof parsed !== "object") return {}
161
-
162
- const result: Partial<ShortcutBindings> = {}
163
-
164
- for (const [actionId, value] of Object.entries(parsed as Record<string, unknown>)) {
165
- if (!_isBindingValue(value)) continue
166
- result[actionId as ShortcutActionId] = value
167
- }
168
-
169
- return result
170
- } catch {
171
- return {}
172
- }
173
- }
174
-
175
- /**
176
- * Persists all shortcut bindings to localStorage.
177
- *
178
- * @param storageKey - Storage key namespace
179
- * @param bindings - Full current binding set
180
- */
181
- export function saveShortcutBindings(storageKey: string, bindings: ShortcutBindings): void {
182
- if (typeof window === "undefined") return
183
-
184
- try {
185
- window.localStorage.setItem(storageKey, JSON.stringify(bindings))
186
- } catch {
187
- // Ignore quota/security errors.
188
- }
189
- }
190
-
191
- /**
192
- * Removes persisted shortcut bindings from localStorage.
193
- *
194
- * @param storageKey - Storage key namespace
195
- */
196
- export function clearShortcutBindings(storageKey: string): void {
197
- if (typeof window === "undefined") return
198
-
199
- try {
200
- window.localStorage.removeItem(storageKey)
201
- } catch {
202
- // Ignore quota/security errors.
203
- }
204
- }
205
- `,"provider.tsx":`"use client"
206
-
207
- import {
208
- createContext,
209
- useCallback,
210
- useContext,
211
- useEffect,
212
- useMemo,
213
- useState,
214
- type ReactNode,
215
- } from "react"
216
- import { registerShortcutMap, useShortcut, type UseShortcutOptions } from "@remcostoeten/use-shortcut"
217
- import { shortcutRegistry, type ShortcutActionId, type ShortcutBindings } from "./registry"
218
- import { buildShortcutMap, createDefaultShortcutBindings } from "./runtime"
219
- import { defaultActiveScopes, normalizeScopes, type ShortcutScope } from "./scopes"
220
- import {
221
- DEFAULT_SHORTCUT_STORAGE_KEY,
222
- clearShortcutBindings,
223
- loadShortcutBindings,
224
- saveShortcutBindings,
225
- } from "./storage"
226
- import type { ShortcutContextValue, ShortcutHandlers } from "./types"
227
-
228
- const _ShortcutContext = createContext<ShortcutContextValue | null>(null)
229
-
230
- function _mergeBindings(defaultBindings: ShortcutBindings, persisted: Partial<ShortcutBindings>): ShortcutBindings {
231
- const merged = { ...defaultBindings }
232
-
233
- for (const actionId of Object.keys(defaultBindings) as ShortcutActionId[]) {
234
- const value = persisted[actionId]
235
- if (typeof value === "string" || Array.isArray(value)) {
236
- merged[actionId] = value
237
- }
238
- }
239
-
240
- return merged
241
- }
242
-
243
- function _isSameBinding(a: string | string[], b: string | string[]): boolean {
244
- const left = Array.isArray(a) ? a.join("|") : a
245
- const right = Array.isArray(b) ? b.join("|") : b
246
- return left === right
247
- }
248
-
249
- function _hasBindingOverrides(bindings: ShortcutBindings): boolean {
250
- const defaults = createDefaultShortcutBindings()
251
-
252
- for (const actionId of Object.keys(defaults) as ShortcutActionId[]) {
253
- if (!_isSameBinding(bindings[actionId], defaults[actionId])) {
254
- return true
255
- }
256
- }
257
-
258
- return false
259
- }
260
-
261
- /** Props for the scaffolded \`ShortcutProvider\`. */
262
- export type ShortcutProviderProps = {
263
- children: ReactNode
264
- handlers: ShortcutHandlers
265
- initialScopes?: ShortcutScope[]
266
- initialEnabled?: boolean
267
- persistBindings?: boolean
268
- storageKey?: string
269
- shortcutOptions?: Omit<UseShortcutOptions, "activeScopes" | "disabled">
270
- }
271
-
272
- /**
273
- * App-level provider that binds action handlers, scope state, and optional binding persistence.
274
- */
275
- export function ShortcutProvider({
276
- children,
277
- handlers,
278
- initialScopes = defaultActiveScopes,
279
- initialEnabled = true,
280
- persistBindings = true,
281
- storageKey = DEFAULT_SHORTCUT_STORAGE_KEY,
282
- shortcutOptions,
283
- }: ShortcutProviderProps) {
284
- const [activeScopes, setActiveScopes] = useState<ShortcutScope[]>(initialScopes)
285
- const [enabled, setEnabled] = useState(initialEnabled)
286
- const [bindings, setBindings] = useState<ShortcutBindings>(() => createDefaultShortcutBindings())
287
-
288
- useEffect(() => {
289
- setEnabled(initialEnabled)
290
- }, [initialEnabled])
291
-
292
- useEffect(() => {
293
- if (!persistBindings) return
294
-
295
- const persisted = loadShortcutBindings(storageKey)
296
- setBindings((current) => _mergeBindings(current, persisted))
297
- }, [persistBindings, storageKey])
298
-
299
- useEffect(() => {
300
- if (!persistBindings) return
301
- saveShortcutBindings(storageKey, bindings)
302
- }, [bindings, persistBindings, storageKey])
303
-
304
- const shortcutMap = useMemo(() => buildShortcutMap(bindings, handlers), [bindings, handlers])
305
-
306
- const $ = useShortcut({
307
- ...shortcutOptions,
308
- activeScopes,
309
- disabled: !enabled,
310
- })
311
-
312
- useEffect(() => {
313
- const registrations = registerShortcutMap($, shortcutMap)
314
-
315
- return () => {
316
- for (const result of Object.values(registrations)) {
317
- result.unbind()
318
- }
319
- }
320
- }, [$, shortcutMap])
321
-
322
- const setScopes = useCallback((scopes: ShortcutScope | ShortcutScope[]) => {
323
- setActiveScopes(normalizeScopes(scopes))
324
- }, [])
325
-
326
- const enableScope = useCallback((scope: ShortcutScope) => {
327
- setActiveScopes((current) => {
328
- if (current.includes(scope)) return current
329
- return [...current, scope]
330
- })
331
- }, [])
332
-
333
- const disableScope = useCallback((scope: ShortcutScope) => {
334
- setActiveScopes((current) => current.filter((item) => item !== scope))
335
- }, [])
336
-
337
- const setBinding = useCallback((actionId: ShortcutActionId, keys: string | string[]) => {
338
- setBindings((current) => ({
339
- ...current,
340
- [actionId]: keys,
341
- }))
342
- }, [])
343
-
344
- const resetBinding = useCallback((actionId: ShortcutActionId) => {
345
- setBindings((current) => ({
346
- ...current,
347
- [actionId]: shortcutRegistry[actionId].defaultKeys,
348
- }))
349
- }, [])
350
-
351
- const resetBindings = useCallback(() => {
352
- setBindings(createDefaultShortcutBindings())
353
- if (persistBindings) clearShortcutBindings(storageKey)
354
- }, [persistBindings, storageKey])
355
-
356
- const contextValue = useMemo<ShortcutContextValue>(
357
- () => ({
358
- state: {
359
- activeScopes,
360
- bindings,
361
- enabled,
362
- },
363
- actions: {
364
- setScopes,
365
- enableScope,
366
- disableScope,
367
- setBinding,
368
- resetBinding,
369
- resetBindings,
370
- setEnabled,
371
- },
372
- meta: {
373
- hasBindingOverrides: _hasBindingOverrides(bindings),
374
- availableActions: Object.keys(shortcutRegistry) as ShortcutActionId[],
375
- },
376
- }),
377
- [
378
- activeScopes,
379
- bindings,
380
- enabled,
381
- setScopes,
382
- enableScope,
383
- disableScope,
384
- setBinding,
385
- resetBinding,
386
- resetBindings,
387
- ],
388
- )
389
-
390
- return <_ShortcutContext.Provider value={contextValue}>{children}</_ShortcutContext.Provider>
391
- }
392
-
393
- /**
394
- * Reads the shortcut manager context exposed by \`ShortcutProvider\`.
395
- */
396
- export function useShortcutManager(): ShortcutContextValue {
397
- const context = useContext(_ShortcutContext)
398
-
399
- if (!context) {
400
- throw new Error("useShortcutManager must be used within <ShortcutProvider>")
401
- }
402
-
403
- return context
404
- }
405
- `,"index.ts":`export { ShortcutProvider, useShortcutManager, type ShortcutProviderProps } from "./provider"
406
- export { shortcutRegistry, type ShortcutActionId, type ShortcutBindings } from "./registry"
407
- export { defaultActiveScopes, shortcutScopes, type ShortcutScope } from "./scopes"
408
- export type {
409
- ShortcutContextValue,
410
- ShortcutActions,
411
- ShortcutHandlers,
412
- ShortcutMeta,
413
- ShortcutState,
414
- } from "./types"
415
- `,"README.md":`# Shortcut Architecture Scaffold
416
-
417
- This folder was generated by \`use-shortcut scaffold\`.
418
-
419
- It follows a scalable architecture with a strict split between:
420
-
421
- - **Registry (data)**: \`registry.ts\` is the single source of truth for action ids, default keys, scope ownership, and metadata.
422
- - **Runtime assembly**: \`runtime.ts\` converts registry + current bindings + handlers into a runtime map.
423
- - **State and actions provider**: \`provider.tsx\` owns scope state, binding overrides, and persistence.
424
- - **Storage adapter**: \`storage.ts\` isolates persistence so you can swap \`localStorage\` for API/DB.
425
- - **Typed contract**: \`types.ts\` exposes \`state/actions/meta\` for UI and feature modules.
426
-
427
- ## How To Extend
428
-
429
- 1. Add a new action in \`registry.ts\`.
430
- 2. Implement its handler in your app and pass it via \`handlers\` to \`<ShortcutProvider>\`.
431
- 3. Optionally expose a user-configurable key in your settings UI through \`useShortcutManager().actions.setBinding\`.
432
- 4. Activate scopes from feature boundaries (for example editor route enters \`editor\` scope).
433
-
434
- ${t==="next"?"## Next.js Integration\n\n1. Create a client provider wrapper at `app/shortcut-provider.tsx` and render `<ShortcutProvider />` there.\n2. Render that provider inside `app/layout.tsx` around your app shell.\n3. Keep page/server components pure; shortcut handlers stay in client components.\n":"## React Integration\n\n1. Wrap your app root (for example in `main.tsx`) with `<ShortcutProvider />`.\n2. Keep handlers in a top-level client component and pass them to the provider via `handlers`.\n3. Use `useShortcutManager()` inside feature components to toggle scopes and bindings.\n"}
435
- ## Rules For Scale
436
-
437
- - Keep handlers side-effect focused and feature-owned; keep the registry declarative.
438
- - Use scopes instead of conditionals in handlers.
439
- - Persist only key bindings, not executable handlers.
440
- - Treat \`registry.ts\` as your architectural contract.
441
- `}}var k=I(import.meta.url),_=B(k),e={reset:"\x1B[0m",green:"\x1B[32m",cyan:"\x1B[36m",yellow:"\x1B[33m",dim:"\x1B[2m",red:"\x1B[31m"};function r(t,o=e.reset){console.log(`${o}${t}${e.reset}`)}function O(){return l(_,"..","src")}function R(t){return l(process.cwd(),t,"use-shortcut")}function C(t,o){return l(process.cwd(),t,o)}function p(t,o,a){let s=t.indexOf(o);if(s===-1)return a;let n=t[s+1];return!n||n.startsWith("--")?a:n}function g(t,o){return t.includes(o)}var P=["index.ts","hook.ts","builder.ts","types.ts","parser.ts","constants.ts","formatter.ts","runtime/types.ts","runtime/binding.ts","runtime/conflicts.ts","runtime/debug.ts","runtime/guards.ts","runtime/keys.ts","runtime/listener.ts","runtime/recording.ts"];function E(t="hooks",o=!1){let a=O(),s=R(t);if(r(`
442
- use-shortcut CLI
443
- `,e.cyan),h(s)&&!o){r(`Directory already exists: ${s}`,e.yellow),r(`Use --force to overwrite existing files
444
- `,e.dim);return}f(s,{recursive:!0});let n=0;for(let i of P){let c=l(a,i),d=l(s,i);if(f(B(d),{recursive:!0}),!h(c)){r(`Source file not found: ${i}`,e.yellow);continue}let u=w(c,"utf-8");x(d,u),n+=1,r(` wrote ${i}`,e.green)}r(`
445
- Copied ${n} files to:`,e.green),r(` ${s}
446
- `,e.dim),r("Usage:",e.cyan),r(` import { useShortcut } from "@/${t}/use-shortcut"`,e.dim),r(" const $ = useShortcut()",e.dim),r(` $.mod.key("k").on(() => console.log("Search"))
447
- `,e.dim)}function y(t,o="src",a="shortcuts",s=!1){let n=C(o,a),i=m(t);r(`
448
- use-shortcut CLI
449
- `,e.cyan),r(`Scaffolding ${t} architecture in ${n}
450
- `,e.dim),f(n,{recursive:!0});let c=0,d=0;for(let[u,A]of Object.entries(i)){let S=l(n,u);if(h(S)&&!s){d+=1,r(` skipped ${u} (already exists)`,e.yellow);continue}x(S,A),c+=1,r(` wrote ${u}`,e.green)}r("",e.reset),r(`Architecture scaffold complete: ${c} written, ${d} skipped.`,e.green),r(`Location: ${n}
451
- `,e.dim),r("Next steps:",e.cyan),r(` 1. Open ${l(o,a,"registry.ts")} and define your action catalog`,e.dim),r(" 2. Wire app handlers into <ShortcutProvider handlers={...} />",e.dim),r(" 3. Toggle scopes from feature boundaries via useShortcutManager()",e.dim),r(` 4. Optionally expose setBinding/resetBinding in your settings UI
452
- `,e.dim)}function b(){r(`
453
- use-shortcut CLI
454
- `,e.cyan),r("Commands:",e.yellow),r(" init [--target hooks] [--force]",e.dim),r(" Copy source files into your project (shadcn-style).",e.dim),r("",e.dim),r(" scaffold [--framework next|react] [--target src] [--dir shortcuts] [--force]",e.dim),r(" Generate a scalable app shortcut architecture.",e.dim),r("",e.dim),r(" init --architecture",e.dim),r(` Alias for scaffold with defaults.
455
- `,e.dim)}function v(t){if(t==="next"||t==="react")return t;r(`Invalid framework: ${t}. Expected "next" or "react".`,e.red),process.exit(1)}function K(){let t=process.argv.slice(2),o=t[0];if(!o||o==="--help"||o==="-h"||o==="help"){b();return}if(o==="init"){if(g(t,"--architecture")||g(t,"--app")||g(t,"--scaffold")){let i=v(p(t,"--framework","next")),c=p(t,"--target","src"),d=p(t,"--dir","shortcuts"),u=g(t,"--force");y(i,c,d,u);return}let s=p(t,"--target","hooks"),n=g(t,"--force");E(s,n);return}if(o==="scaffold"||o==="architecture"){let s=v(p(t,"--framework","next")),n=p(t,"--target","src"),i=p(t,"--dir","shortcuts"),c=g(t,"--force");y(s,n,i,c);return}b(),process.exit(1)}K();