@rashidee/co2 1.2.5

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.
Files changed (190) hide show
  1. package/dist/index.js +25449 -0
  2. package/drizzle/0000_remarkable_charles_xavier.sql +210 -0
  3. package/drizzle/0001_wise_wolf_cub.sql +13 -0
  4. package/drizzle/0002_secret_spyke.sql +16 -0
  5. package/drizzle/0003_workspace_config_singleton.sql +16 -0
  6. package/drizzle/0004_terminal_claim_v120.sql +11 -0
  7. package/drizzle/0005_brainstorm_v124.sql +10 -0
  8. package/drizzle/0006_project_v140.sql +6 -0
  9. package/drizzle/0007_prd_wizard_v124.sql +14 -0
  10. package/drizzle/0008_workflow_artifact_v126.sql +24 -0
  11. package/drizzle/0009_project_import_v150.sql +7 -0
  12. package/drizzle/0010_quality_v151.sql +3 -0
  13. package/drizzle/meta/0000_snapshot.json +1335 -0
  14. package/drizzle/meta/0001_snapshot.json +1416 -0
  15. package/drizzle/meta/0002_snapshot.json +1510 -0
  16. package/drizzle/meta/_journal.json +83 -0
  17. package/package.json +41 -0
  18. package/plugin/.claude-plugin/marketplace.json +36 -0
  19. package/plugin/.claude-plugin/plugin.json +22 -0
  20. package/plugin/README.md +625 -0
  21. package/plugin/SKILLS.md +350 -0
  22. package/plugin/co2.svg +5 -0
  23. package/plugin/commands/brainstorm-loop.md +129 -0
  24. package/plugin/skills/conductor-defect/SKILL.md +898 -0
  25. package/plugin/skills/conductor-feature-develop/SKILL.md +1383 -0
  26. package/plugin/skills/conductor-feature-develop/references/implementation-domain-template.md +131 -0
  27. package/plugin/skills/conductor-feature-develop/references/implementation-master-template.md +89 -0
  28. package/plugin/skills/conductor-feature-develop/references/playwright-setup.md +224 -0
  29. package/plugin/skills/conductor-feature-prepare/SKILL.md +604 -0
  30. package/plugin/skills/depgen-k8s/SKILL.md +468 -0
  31. package/plugin/skills/depgen-k8s/references/dockerfile-laravel.md +197 -0
  32. package/plugin/skills/depgen-k8s/references/dockerfile-nodejs.md +163 -0
  33. package/plugin/skills/depgen-k8s/references/dockerfile-spring-boot.md +174 -0
  34. package/plugin/skills/depgen-k8s/references/k8s-patterns.md +869 -0
  35. package/plugin/skills/mockgen-shadcn/SKILL.md +1067 -0
  36. package/plugin/skills/mockgen-shadcn/references/admin-layout-template.md +1467 -0
  37. package/plugin/skills/mockgen-shadcn/references/mockup-hub-template.md +498 -0
  38. package/plugin/skills/mockgen-shadcn/references/mockup-index-template.md +216 -0
  39. package/plugin/skills/mockgen-tailwind/SKILL.md +904 -0
  40. package/plugin/skills/mockgen-tailwind/references/admin-layout-template.md +720 -0
  41. package/plugin/skills/mockgen-tailwind/references/mockup-hub-template.md +498 -0
  42. package/plugin/skills/mockgen-tailwind/references/mockup-index-template.md +190 -0
  43. package/plugin/skills/modelgen-nosql/SKILL.md +617 -0
  44. package/plugin/skills/modelgen-nosql/references/model-extraction-methodology.md +497 -0
  45. package/plugin/skills/modelgen-nosql/references/nosql-design-guide.md +258 -0
  46. package/plugin/skills/modelgen-relational/SKILL.md +707 -0
  47. package/plugin/skills/modelgen-relational/references/model-extraction-methodology.md +499 -0
  48. package/plugin/skills/specgen-flutter-riverpod/SKILL.md +898 -0
  49. package/plugin/skills/specgen-flutter-riverpod/references/component-patterns.md +971 -0
  50. package/plugin/skills/specgen-flutter-riverpod/references/notification-patterns.md +457 -0
  51. package/plugin/skills/specgen-flutter-riverpod/references/routing-patterns.md +362 -0
  52. package/plugin/skills/specgen-flutter-riverpod/references/security-patterns.md +709 -0
  53. package/plugin/skills/specgen-flutter-riverpod/references/spec-template.md +1566 -0
  54. package/plugin/skills/specgen-flutter-riverpod/references/state-patterns.md +518 -0
  55. package/plugin/skills/specgen-flutter-riverpod/references/storage-patterns.md +370 -0
  56. package/plugin/skills/specgen-laravel-eloquent-bladehtmx/SKILL.md +984 -0
  57. package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/batch-patterns.md +359 -0
  58. package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/messaging-patterns.md +468 -0
  59. package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/modulith-patterns.md +461 -0
  60. package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/reporting-patterns.md +803 -0
  61. package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/security-patterns.md +501 -0
  62. package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/spec-template.md +1268 -0
  63. package/plugin/skills/specgen-laravel-eloquent-bladehtmx/references/web-patterns.md +301 -0
  64. package/plugin/skills/specgen-node-cli-web/SKILL.md +561 -0
  65. package/plugin/skills/specgen-node-cli-web/references/auth-patterns.md +293 -0
  66. package/plugin/skills/specgen-node-cli-web/references/cli-packaging-patterns.md +250 -0
  67. package/plugin/skills/specgen-node-cli-web/references/server-patterns.md +247 -0
  68. package/plugin/skills/specgen-node-cli-web/references/spec-template.md +401 -0
  69. package/plugin/skills/specgen-node-cli-web/references/testing-patterns.md +174 -0
  70. package/plugin/skills/specgen-react-mui/SKILL.md +789 -0
  71. package/plugin/skills/specgen-react-mui/references/component-patterns.md +1077 -0
  72. package/plugin/skills/specgen-react-mui/references/reporting-patterns.md +1998 -0
  73. package/plugin/skills/specgen-react-mui/references/routing-patterns.md +461 -0
  74. package/plugin/skills/specgen-react-mui/references/security-patterns.md +599 -0
  75. package/plugin/skills/specgen-react-mui/references/spec-template.md +1030 -0
  76. package/plugin/skills/specgen-react-mui/references/state-patterns.md +327 -0
  77. package/plugin/skills/specgen-react-tailwind/SKILL.md +859 -0
  78. package/plugin/skills/specgen-react-tailwind/references/component-patterns.md +1212 -0
  79. package/plugin/skills/specgen-react-tailwind/references/reporting-patterns.md +1529 -0
  80. package/plugin/skills/specgen-react-tailwind/references/routing-patterns.md +669 -0
  81. package/plugin/skills/specgen-react-tailwind/references/security-patterns.md +656 -0
  82. package/plugin/skills/specgen-react-tailwind/references/spec-template.md +1237 -0
  83. package/plugin/skills/specgen-react-tailwind/references/state-patterns.md +327 -0
  84. package/plugin/skills/specgen-sdk-java/SKILL.md +933 -0
  85. package/plugin/skills/specgen-sdk-java/references/api-extraction-patterns.md +247 -0
  86. package/plugin/skills/specgen-sdk-java/references/http-client-patterns.md +495 -0
  87. package/plugin/skills/specgen-sdk-java/references/packaging-patterns.md +366 -0
  88. package/plugin/skills/specgen-sdk-java/references/spec-template.md +956 -0
  89. package/plugin/skills/specgen-spring-jpa-jtehtmx/SKILL.md +1284 -0
  90. package/plugin/skills/specgen-spring-jpa-jtehtmx/references/batch-patterns.md +1224 -0
  91. package/plugin/skills/specgen-spring-jpa-jtehtmx/references/jasper-patterns.md +1638 -0
  92. package/plugin/skills/specgen-spring-jpa-jtehtmx/references/messaging-patterns.md +512 -0
  93. package/plugin/skills/specgen-spring-jpa-jtehtmx/references/modulith-patterns.md +354 -0
  94. package/plugin/skills/specgen-spring-jpa-jtehtmx/references/security-patterns.md +551 -0
  95. package/plugin/skills/specgen-spring-jpa-jtehtmx/references/spec-template.md +2502 -0
  96. package/plugin/skills/specgen-spring-jpa-jtehtmx/references/web-patterns.md +503 -0
  97. package/plugin/skills/specgen-spring-jpa-restapi/SKILL.md +990 -0
  98. package/plugin/skills/specgen-spring-jpa-restapi/references/batch-patterns.md +1224 -0
  99. package/plugin/skills/specgen-spring-jpa-restapi/references/messaging-patterns.md +512 -0
  100. package/plugin/skills/specgen-spring-jpa-restapi/references/modulith-patterns.md +279 -0
  101. package/plugin/skills/specgen-spring-jpa-restapi/references/reporting-patterns.md +1536 -0
  102. package/plugin/skills/specgen-spring-jpa-restapi/references/restapi-patterns.md +722 -0
  103. package/plugin/skills/specgen-spring-jpa-restapi/references/security-patterns.md +351 -0
  104. package/plugin/skills/specgen-spring-jpa-restapi/references/spec-template.md +553 -0
  105. package/plugin/skills/specgen-ts-cli/SKILL.md +861 -0
  106. package/plugin/skills/specgen-ts-cli/references/async-patterns.md +1101 -0
  107. package/plugin/skills/specgen-ts-cli/references/command-patterns.md +383 -0
  108. package/plugin/skills/specgen-ts-cli/references/config-patterns.md +430 -0
  109. package/plugin/skills/specgen-ts-cli/references/database-patterns.md +750 -0
  110. package/plugin/skills/specgen-ts-cli/references/packaging-patterns.md +426 -0
  111. package/plugin/skills/specgen-ts-cli/references/spec-template.md +1391 -0
  112. package/plugin/skills/specgen-ts-cli/references/testing-patterns.md +909 -0
  113. package/plugin/skills/testgen-functional/SKILL.md +1381 -0
  114. package/plugin/skills/tracegen-matrix/SKILL.md +243 -0
  115. package/plugin/skills/util-preparek8senv/SKILL.md +422 -0
  116. package/plugin/skills/util-projectinit/SKILL.md +307 -0
  117. package/plugin/skills/util-projectinit/reference/brainstorm-loop.md +129 -0
  118. package/plugin/skills/util-projectinit/reference/brainstorm-protocol.md +144 -0
  119. package/plugin/skills/util-projectinit/reference/brainstorm-setup-guide.md +153 -0
  120. package/plugin/skills/util-projectinit/reference/brainstorm-template-appdev.md +87 -0
  121. package/plugin/skills/util-projectinit/reference/co2-context-generation-guide.md +761 -0
  122. package/plugin/skills/util-projectsync/SKILL.md +501 -0
  123. package/plugin/skills/util-updprd/SKILL.md +324 -0
  124. package/plugin/skills/util-usanalyzer/SKILL.md +307 -0
  125. package/plugin/skills/util-ustagger/SKILL.md +154 -0
  126. package/static/assets/abnfDiagram-VRR7QNED-DvPuwyCV.js +1 -0
  127. package/static/assets/arc-DRKw7sjs.js +1 -0
  128. package/static/assets/architectureDiagram-ZJ3FMSHR-CaNcxUbC.js +36 -0
  129. package/static/assets/blockDiagram-677ZJIJ3-Demd4AOK.js +132 -0
  130. package/static/assets/c4Diagram-LMCZKHZV-PVKUfc2x.js +10 -0
  131. package/static/assets/channel-C2nVbuwv.js +1 -0
  132. package/static/assets/chunk-2Q5K7J3B-CExf8ww_.js +1 -0
  133. package/static/assets/chunk-32BRIVSS-CFPaoONF.js +1 -0
  134. package/static/assets/chunk-5VM5RSS4-DE2esM67.js +15 -0
  135. package/static/assets/chunk-EX3LRPZG-SON_YdDG.js +231 -0
  136. package/static/assets/chunk-JWPE2WC7-Qxah8LNr.js +1 -0
  137. package/static/assets/chunk-MOJQB5TN-BcWGQV3j.js +88 -0
  138. package/static/assets/chunk-RYQCIY6F-DkDj-OR5.js +1 -0
  139. package/static/assets/chunk-V7JOEXUC-BlI1Mrah.js +206 -0
  140. package/static/assets/chunk-VR4S4FIN-Agf__duj.js +1 -0
  141. package/static/assets/chunk-XXDRQBXY-B5CfAh85.js +1 -0
  142. package/static/assets/classDiagram-OUVF2IWQ-DXJIljsR.js +1 -0
  143. package/static/assets/classDiagram-v2-EOCWNBFH-DXJIljsR.js +1 -0
  144. package/static/assets/cose-bilkent-JH36ORCC-DO0cQkcy.js +1 -0
  145. package/static/assets/cynefin-VYW2F7L2-CfOnsnXc.js +178 -0
  146. package/static/assets/cynefinDiagram-TSTJHNR4-BJ8tULAv.js +62 -0
  147. package/static/assets/cytoscape.esm-DTSO7Bv0.js +331 -0
  148. package/static/assets/dagre-VKFMJZFB-DfjwzHqP.js +4 -0
  149. package/static/assets/defaultLocale-DX6XiGOO.js +1 -0
  150. package/static/assets/diagram-FQU43EPY-CndSOIIM.js +3 -0
  151. package/static/assets/diagram-G47NLZAW-Czf5hN0Z.js +24 -0
  152. package/static/assets/diagram-NH7WQ7WH-COAyojGh.js +24 -0
  153. package/static/assets/diagram-OA4YK3LP-H8PoiN2m.js +30 -0
  154. package/static/assets/diagram-WEI45ONY-DzcaVzjp.js +41 -0
  155. package/static/assets/ebnfDiagram-CCIWWBDH-DPazGYLJ.js +1 -0
  156. package/static/assets/erDiagram-Q63AITRT-Bo-fubgF.js +85 -0
  157. package/static/assets/flowDiagram-23GEKE2U-CSvxUDwh.js +156 -0
  158. package/static/assets/ganttDiagram-NO4QXBWP-DnBveWX6.js +292 -0
  159. package/static/assets/gitGraphDiagram-IHSO6WYX-B3rVL8c-.js +106 -0
  160. package/static/assets/graph-C9eacEi8.js +1 -0
  161. package/static/assets/index-LZSQkLE2.css +41 -0
  162. package/static/assets/index-y7XDSgMG.js +495 -0
  163. package/static/assets/infoDiagram-FWYZ7A6U-CvWV9yy2.js +2 -0
  164. package/static/assets/init-Gi6I4Gst.js +1 -0
  165. package/static/assets/ishikawaDiagram-FXEZZL3T-DF28a1N6.js +70 -0
  166. package/static/assets/journeyDiagram-5HDEW3XC-CB6CugYk.js +139 -0
  167. package/static/assets/kanban-definition-HUTT4EX6-ResSLF6d.js +89 -0
  168. package/static/assets/katex-C5jXJg4s.js +257 -0
  169. package/static/assets/layout-DEXfKzaS.js +1 -0
  170. package/static/assets/linear-CLO--ryk.js +1 -0
  171. package/static/assets/map-Czzmt4hB.js +1 -0
  172. package/static/assets/mindmap-definition-LN4V7U3C-BvW3EbxX.js +96 -0
  173. package/static/assets/ordinal-Cboi1Yqb.js +1 -0
  174. package/static/assets/pegDiagram-2B236MQR-BHCgqrrM.js +1 -0
  175. package/static/assets/pieDiagram-ENE6RG2P-DVmCQ5FA.js +39 -0
  176. package/static/assets/quadrantDiagram-ABIIQ3AL-B3e5KR52.js +7 -0
  177. package/static/assets/railroadDiagram-RFXS5EU6-Csv5ysLc.js +1 -0
  178. package/static/assets/requirementDiagram-TGXJPOKE-DOMVzvnB.js +84 -0
  179. package/static/assets/sankeyDiagram-HTMAVEWB-B1dcTOvy.js +40 -0
  180. package/static/assets/sequenceDiagram-DBY2YBRQ-BY414yeO.js +162 -0
  181. package/static/assets/sizeCapture-X5ZJPWSS-CuJfrfBN.js +1 -0
  182. package/static/assets/stateDiagram-2N3HPSRC-FX4rJkzV.js +1 -0
  183. package/static/assets/stateDiagram-v2-6OUMAXLB-BVufbO_H.js +1 -0
  184. package/static/assets/swimlanes-5IMT3BWC-Sfy58mmv.js +2 -0
  185. package/static/assets/swimlanesDiagram-G3AALYLV-wDCDw08H.js +8 -0
  186. package/static/assets/timeline-definition-FHXFAJF6-CmV7by8p.js +120 -0
  187. package/static/assets/vennDiagram-L72KCM5P-FqIyFZFt.js +34 -0
  188. package/static/assets/wardleyDiagram-EHGQE667-BZ06O45i.js +78 -0
  189. package/static/assets/xychartDiagram-FW5EYKEG-BOkffR06.js +7 -0
  190. package/static/index.html +24 -0
@@ -0,0 +1,430 @@
1
+ # Configuration Management Patterns — conf + cosmiconfig
2
+
3
+ This reference describes the two configuration layers for CLI applications. Include
4
+ relevant content in Sections 9 and 10 of the generated specification.
5
+
6
+ ---
7
+
8
+ ## Configuration Layers Overview
9
+
10
+ ```
11
+ ┌─────────────────────────────────────────────────────────────────────┐
12
+ │ Precedence order (highest → lowest) │
13
+ │ │
14
+ │ 1. CLI flags --environment staging (per-invocation) │
15
+ │ 2. Env variables MY_TOOL_ENV=staging (per-session) │
16
+ │ 3. Project config .mytoolrc / mytool.config.js (per-project) │
17
+ │ 4. User config ~/.config/my-tool/config.json (per-user) │
18
+ │ 5. Built-in defaults (hardcoded in source) │
19
+ └─────────────────────────────────────────────────────────────────────┘
20
+ ```
21
+
22
+ - **User config** (`conf`) — global, per-user settings: API tokens, preferences,
23
+ default values. Stored in the OS user config directory
24
+ - **Project config** (`cosmiconfig`) — per-workspace/repo settings: project-specific
25
+ options, team conventions. Committed to source control
26
+
27
+ ---
28
+
29
+ ## User Configuration — conf
30
+
31
+ `conf` stores JSON in the OS user config directory and provides a typed, schema-validated
32
+ key-value store. It uses the OS keychain on macOS for sensitive fields (optional).
33
+
34
+ ### Setup
35
+
36
+ ```typescript
37
+ // src/config/user.config.ts
38
+ import Conf from 'conf'
39
+ import { z } from 'zod'
40
+
41
+ // 1. Define schema with Zod for runtime validation
42
+ const UserConfigSchema = z.object({
43
+ apiToken: z.string().optional(),
44
+ apiBaseUrl: z.string().url().default('https://api.example.com'),
45
+ defaultEnv: z.enum(['staging', 'production']).default('staging'),
46
+ telemetryEnabled: z.boolean().default(true),
47
+ })
48
+
49
+ export type UserConfigData = z.infer<typeof UserConfigSchema>
50
+
51
+ // 2. conf stores values as plain JSON (no Zod at rest — validated on read)
52
+ type ConfStore = Partial<UserConfigData>
53
+
54
+ const conf = new Conf<ConfStore>({
55
+ projectName: '{{BINARY_NAME}}',
56
+ projectVersion: 1, // increment when schema changes to trigger migration
57
+ schema: {
58
+ // JSON Schema (conf uses ajv) for basic type checking
59
+ apiToken: { type: 'string' },
60
+ apiBaseUrl: { type: 'string' },
61
+ defaultEnv: { type: 'string', enum: ['staging', 'production'] },
62
+ telemetryEnabled: { type: 'boolean' },
63
+ },
64
+ defaults: {
65
+ apiBaseUrl: 'https://api.example.com',
66
+ defaultEnv: 'staging',
67
+ telemetryEnabled: true,
68
+ },
69
+ })
70
+
71
+ // 3. Typed accessor — always validates on read
72
+ export function getUserConfig(): {
73
+ get<K extends keyof UserConfigData>(key: K): UserConfigData[K]
74
+ set<K extends keyof UserConfigData>(key: K, value: UserConfigData[K]): void
75
+ delete<K extends keyof UserConfigData>(key: K): void
76
+ all(): UserConfigData
77
+ clear(): void
78
+ path: string
79
+ } {
80
+ return {
81
+ get<K extends keyof UserConfigData>(key: K): UserConfigData[K] {
82
+ const raw = conf.get(key)
83
+ const parsed = UserConfigSchema.shape[key].safeParse(raw)
84
+ if (!parsed.success) {
85
+ // Fall back to default
86
+ return UserConfigSchema.shape[key].parse(undefined)
87
+ }
88
+ return parsed.data as UserConfigData[K]
89
+ },
90
+ set<K extends keyof UserConfigData>(key: K, value: UserConfigData[K]): void {
91
+ UserConfigSchema.shape[key].parse(value) // validate before write
92
+ conf.set(key, value)
93
+ },
94
+ delete<K extends keyof UserConfigData>(key: K): void {
95
+ conf.delete(key)
96
+ },
97
+ all(): UserConfigData {
98
+ return UserConfigSchema.parse(conf.store)
99
+ },
100
+ clear(): void {
101
+ conf.clear()
102
+ },
103
+ get path(): string {
104
+ return conf.path
105
+ },
106
+ }
107
+ }
108
+ ```
109
+
110
+ ### Config Sub-commands
111
+
112
+ Every CLI using `conf` should expose `config get`, `config set`, `config list`, and
113
+ `config reset` sub-commands so users can inspect and modify their settings without
114
+ editing JSON manually.
115
+
116
+ ```typescript
117
+ // src/commands/config/list.ts
118
+ import type { Command } from 'commander'
119
+ import { handleError } from '../../errors.js'
120
+ import { getUserConfig } from '../../config/user.config.js'
121
+ import { output } from '../../ui/output.js'
122
+ import { printTable } from '../../ui/table.js'
123
+
124
+ export function registerConfigListCommand(parent: Command): void {
125
+ parent
126
+ .command('list')
127
+ .alias('ls')
128
+ .description('List all configuration values')
129
+ .action(handleError(async (_opts, cmd: Command) => {
130
+ const { json } = cmd.parent?.parent?.opts<{ json: boolean }>() ?? { json: false }
131
+ if (json) output.enableJson()
132
+
133
+ const config = getUserConfig()
134
+ const all = config.all()
135
+
136
+ output.success(all, '') // JSON mode
137
+
138
+ if (!json) {
139
+ printTable({
140
+ head: ['Key', 'Value'],
141
+ rows: Object.entries(all).map(([k, v]) => [k, String(v)]),
142
+ })
143
+ logger.info(`Config stored at: ${config.path}`)
144
+ }
145
+ }))
146
+ }
147
+ ```
148
+
149
+ ```typescript
150
+ // src/commands/config/set.ts
151
+ import type { Command } from 'commander'
152
+ import { handleError, CliError } from '../../errors.js'
153
+ import { getUserConfig } from '../../config/user.config.js'
154
+ import { output } from '../../ui/output.js'
155
+ import type { UserConfigData } from '../../config/user.config.js'
156
+
157
+ export function registerConfigSetCommand(parent: Command): void {
158
+ parent
159
+ .command('set <key> <value>')
160
+ .description('Set a configuration value')
161
+ .action(handleError(async (key: string, rawValue: string) => {
162
+ const config = getUserConfig()
163
+ const validKeys = Object.keys(config.all()) as (keyof UserConfigData)[]
164
+
165
+ if (!validKeys.includes(key as keyof UserConfigData)) {
166
+ throw CliError.invalidInput(
167
+ `Unknown config key: "${key}". Valid keys: ${validKeys.join(', ')}`
168
+ )
169
+ }
170
+
171
+ // Coerce string to correct type
172
+ let value: unknown = rawValue
173
+ if (rawValue === 'true') value = true
174
+ if (rawValue === 'false') value = false
175
+ if (!isNaN(Number(rawValue)) && rawValue !== '') value = Number(rawValue)
176
+
177
+ config.set(key as keyof UserConfigData, value as never)
178
+ output.success({ key, value }, `Set ${key} = ${rawValue}`)
179
+ }))
180
+ }
181
+ ```
182
+
183
+ ```typescript
184
+ // src/commands/config/reset.ts
185
+ import type { Command } from 'commander'
186
+ import { confirm } from '@inquirer/prompts'
187
+ import { handleError } from '../../errors.js'
188
+ import { getUserConfig } from '../../config/user.config.js'
189
+ import { output, logger } from '../../ui/output.js'
190
+
191
+ export function registerConfigResetCommand(parent: Command): void {
192
+ parent
193
+ .command('reset')
194
+ .description('Reset all configuration to defaults')
195
+ .option('-f, --force', 'skip confirmation', false)
196
+ .action(handleError(async (opts: { force: boolean }) => {
197
+ if (!opts.force) {
198
+ const confirmed = await confirm({
199
+ message: 'Reset all configuration to defaults?',
200
+ default: false,
201
+ })
202
+ if (!confirmed) {
203
+ logger.info('Aborted.')
204
+ process.exit(0)
205
+ }
206
+ }
207
+ getUserConfig().clear()
208
+ output.success({}, 'Configuration reset to defaults')
209
+ }))
210
+ }
211
+ ```
212
+
213
+ ### Login / Logout Commands *(for API-token-based auth)*
214
+
215
+ ```typescript
216
+ // src/commands/login/index.ts
217
+ import { password } from '@inquirer/prompts'
218
+ import type { Command } from 'commander'
219
+ import { handleError } from '../../errors.js'
220
+ import { getUserConfig } from '../../config/user.config.js'
221
+ import { AuthService } from '../../services/auth.service.js'
222
+ import { output } from '../../ui/output.js'
223
+
224
+ export function registerLoginCommand(program: Command): void {
225
+ program
226
+ .command('login')
227
+ .description('Authenticate with {{APPLICATION_NAME}}')
228
+ .option('--token <token>', 'API token (or use interactive prompt)')
229
+ .action(handleError(async (opts: { token?: string }) => {
230
+ const token = opts.token ?? await password({
231
+ message: 'Enter your API token:',
232
+ mask: '*',
233
+ })
234
+
235
+ const authService = new AuthService()
236
+ const user = await authService.validateToken(token)
237
+
238
+ getUserConfig().set('apiToken', token)
239
+
240
+ output.success({ user: user.email }, `Logged in as ${user.email}`)
241
+ }))
242
+ }
243
+ ```
244
+
245
+ ```typescript
246
+ // src/commands/logout/index.ts
247
+ export function registerLogoutCommand(program: Command): void {
248
+ program
249
+ .command('logout')
250
+ .description('Remove stored credentials')
251
+ .action(handleError(async () => {
252
+ getUserConfig().delete('apiToken')
253
+ output.success({}, 'Logged out — credentials removed')
254
+ }))
255
+ }
256
+ ```
257
+
258
+ ---
259
+
260
+ ## Project Configuration — cosmiconfig
261
+
262
+ `cosmiconfig` searches for a project-level config file starting from the current working
263
+ directory and traversing upward. Useful when the CLI tool operates within a project
264
+ (e.g., a deployment tool, a linter, a build tool).
265
+
266
+ ### Supported Config File Formats
267
+
268
+ cosmiconfig automatically searches for (in order):
269
+ - `package.json` — `"{{BINARY_NAME}}"` field
270
+ - `.{{BINARY_NAME}}rc` — JSON or YAML
271
+ - `.{{BINARY_NAME}}rc.json`
272
+ - `.{{BINARY_NAME}}rc.yaml` / `.{{BINARY_NAME}}rc.yml`
273
+ - `.{{BINARY_NAME}}rc.js` / `.{{BINARY_NAME}}rc.mjs` / `.{{BINARY_NAME}}rc.cjs`
274
+ - `{{BINARY_NAME}}.config.js` / `{{BINARY_NAME}}.config.mjs` / `{{BINARY_NAME}}.config.cjs`
275
+
276
+ ### Setup
277
+
278
+ ```typescript
279
+ // src/config/project.config.ts
280
+ import { cosmiconfig } from 'cosmiconfig'
281
+ import { z } from 'zod'
282
+ import { CliError } from '../errors.js'
283
+
284
+ // 1. Define schema
285
+ const ProjectConfigSchema = z.object({
286
+ environment: z.enum(['staging', 'production', 'development']).default('staging'),
287
+ region: z.string().default('us-east-1'),
288
+ services: z.array(z.string()).default([]),
289
+ hooks: z.object({
290
+ preDeploy: z.string().optional(),
291
+ postDeploy: z.string().optional(),
292
+ }).default({}),
293
+ })
294
+
295
+ export type ProjectConfig = z.infer<typeof ProjectConfigSchema>
296
+
297
+ const DEFAULT_CONFIG: ProjectConfig = ProjectConfigSchema.parse({})
298
+
299
+ // 2. Cached search result
300
+ let _cachedConfig: ProjectConfig | null = null
301
+
302
+ /**
303
+ * Load and validate the project config file. Searches up from CWD.
304
+ * Returns defaults if no config file found (non-fatal).
305
+ */
306
+ export async function loadProjectConfig(searchFrom?: string): Promise<ProjectConfig> {
307
+ if (_cachedConfig) return _cachedConfig
308
+
309
+ const explorer = cosmiconfig('{{BINARY_NAME}}', {
310
+ searchStrategy: 'project',
311
+ stopDir: process.env['HOME'] ?? '/',
312
+ })
313
+
314
+ const result = await explorer.search(searchFrom ?? process.cwd())
315
+
316
+ if (!result || result.isEmpty) {
317
+ _cachedConfig = DEFAULT_CONFIG
318
+ return DEFAULT_CONFIG
319
+ }
320
+
321
+ const parsed = ProjectConfigSchema.safeParse(result.config)
322
+ if (!parsed.success) {
323
+ throw CliError.configError(
324
+ `Invalid config in ${result.filepath}:\n${parsed.error.message}`
325
+ )
326
+ }
327
+
328
+ _cachedConfig = parsed.data
329
+ return parsed.data
330
+ }
331
+
332
+ /** Reset the config cache (useful in tests) */
333
+ export function resetProjectConfigCache(): void {
334
+ _cachedConfig = null
335
+ }
336
+ ```
337
+
338
+ ### Merging Config Precedence
339
+
340
+ In command handlers, merge configuration sources in the correct precedence order:
341
+
342
+ ```typescript
343
+ // src/utils/resolve-config.ts
344
+ import { loadProjectConfig } from '../config/project.config.js'
345
+ import { getUserConfig } from '../config/user.config.js'
346
+ import type { DeployOptions } from '../commands/deploy/index.js'
347
+
348
+ export interface ResolvedDeployConfig {
349
+ environment: string
350
+ region: string
351
+ }
352
+
353
+ export async function resolveDeployConfig(
354
+ cliOpts: Partial<DeployOptions>
355
+ ): Promise<ResolvedDeployConfig> {
356
+ const projectConfig = await loadProjectConfig()
357
+ const userConfig = getUserConfig()
358
+
359
+ return {
360
+ // CLI flag > env var > project config > user default > hardcoded default
361
+ environment:
362
+ cliOpts.environment // CLI flag (highest)
363
+ ?? process.env['MY_TOOL_ENV'] // env var
364
+ ?? projectConfig.environment // project config
365
+ ?? userConfig.get('defaultEnv') // user preference
366
+ ?? 'staging', // hardcoded default (lowest)
367
+
368
+ region:
369
+ cliOpts.region
370
+ ?? process.env['MY_TOOL_REGION']
371
+ ?? projectConfig.region
372
+ ?? 'us-east-1',
373
+ }
374
+ }
375
+ ```
376
+
377
+ ### Sample Config Files
378
+
379
+ The spec must include example config files that developers can copy:
380
+
381
+ **`.mytoolrc.json`**
382
+ ```json
383
+ {
384
+ "environment": "production",
385
+ "region": "eu-west-1",
386
+ "services": ["api", "worker"],
387
+ "hooks": {
388
+ "preDeploy": "npm test",
389
+ "postDeploy": "npm run notify"
390
+ }
391
+ }
392
+ ```
393
+
394
+ **`mytool.config.js`** (for dynamic configs using JS)
395
+ ```javascript
396
+ // mytool.config.js
397
+ export default {
398
+ environment: process.env.NODE_ENV === 'production' ? 'production' : 'staging',
399
+ region: 'us-east-1',
400
+ services: ['api', 'worker'],
401
+ }
402
+ ```
403
+
404
+ **`package.json` field**
405
+ ```json
406
+ {
407
+ "name": "my-project",
408
+ "my-tool": {
409
+ "environment": "staging",
410
+ "services": ["api"]
411
+ }
412
+ }
413
+ ```
414
+
415
+ ---
416
+
417
+ ## Environment Variable Support
418
+
419
+ Every config key should have an environment variable equivalent. Define a mapping table
420
+ in the spec:
421
+
422
+ | Config Key | Environment Variable | Priority |
423
+ |--------------------|---------------------------|----------|
424
+ | `environment` | `MY_TOOL_ENV` | 2nd |
425
+ | `region` | `MY_TOOL_REGION` | 2nd |
426
+ | `apiToken` | `MY_TOOL_TOKEN` | 2nd |
427
+ | `apiBaseUrl` | `MY_TOOL_API_URL` | 2nd |
428
+
429
+ Load environment variables in the `resolveConfig` utility, not in services directly.
430
+ This keeps services testable without process.env manipulation.