@shepai/cli 1.2.0 → 1.3.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.
Files changed (208) hide show
  1. package/README.md +29 -12
  2. package/dist/eslint.config.d.mts +3 -0
  3. package/dist/eslint.config.d.mts.map +1 -0
  4. package/dist/eslint.config.mjs +188 -0
  5. package/dist/src/application/ports/output/index.d.ts +8 -0
  6. package/dist/src/application/ports/output/index.d.ts.map +1 -0
  7. package/dist/src/application/ports/output/index.js +7 -0
  8. package/dist/src/application/ports/output/settings.repository.interface.d.ts +43 -0
  9. package/dist/src/application/ports/output/settings.repository.interface.d.ts.map +1 -0
  10. package/dist/src/application/ports/output/settings.repository.interface.js +11 -0
  11. package/dist/src/application/use-cases/settings/index.d.ts +9 -0
  12. package/dist/src/application/use-cases/settings/index.d.ts.map +1 -0
  13. package/dist/src/application/use-cases/settings/index.js +8 -0
  14. package/dist/src/application/use-cases/settings/initialize-settings.use-case.d.ts +33 -0
  15. package/dist/src/application/use-cases/settings/initialize-settings.use-case.d.ts.map +1 -0
  16. package/dist/src/application/use-cases/settings/initialize-settings.use-case.js +63 -0
  17. package/dist/src/application/use-cases/settings/load-settings.use-case.d.ts +33 -0
  18. package/dist/src/application/use-cases/settings/load-settings.use-case.d.ts.map +1 -0
  19. package/dist/src/application/use-cases/settings/load-settings.use-case.js +57 -0
  20. package/dist/src/application/use-cases/settings/update-settings.use-case.d.ts +33 -0
  21. package/dist/src/application/use-cases/settings/update-settings.use-case.d.ts.map +1 -0
  22. package/dist/src/application/use-cases/settings/update-settings.use-case.js +56 -0
  23. package/dist/src/domain/factories/index.d.ts +7 -0
  24. package/dist/src/domain/factories/index.d.ts.map +1 -0
  25. package/dist/src/domain/factories/index.js +6 -0
  26. package/dist/src/domain/factories/settings-defaults.factory.d.ts +36 -0
  27. package/dist/src/domain/factories/settings-defaults.factory.d.ts.map +1 -0
  28. package/dist/src/domain/factories/settings-defaults.factory.js +81 -0
  29. package/dist/src/domain/generated/output.d.ts +717 -0
  30. package/dist/src/domain/generated/output.d.ts.map +1 -0
  31. package/dist/src/domain/generated/output.js +93 -0
  32. package/dist/src/index.d.ts.map +1 -0
  33. package/dist/src/infrastructure/di/container.d.ts +27 -0
  34. package/dist/src/infrastructure/di/container.d.ts.map +1 -0
  35. package/dist/src/infrastructure/di/container.js +53 -0
  36. package/dist/src/infrastructure/persistence/sqlite/connection.d.ts +39 -0
  37. package/dist/src/infrastructure/persistence/sqlite/connection.d.ts.map +1 -0
  38. package/dist/src/infrastructure/persistence/sqlite/connection.js +76 -0
  39. package/dist/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts +50 -0
  40. package/dist/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts.map +1 -0
  41. package/dist/src/infrastructure/persistence/sqlite/mappers/settings.mapper.js +80 -0
  42. package/dist/src/infrastructure/persistence/sqlite/migrations.d.ts +31 -0
  43. package/dist/src/infrastructure/persistence/sqlite/migrations.d.ts.map +1 -0
  44. package/dist/src/infrastructure/persistence/sqlite/migrations.js +66 -0
  45. package/dist/src/infrastructure/repositories/sqlite-settings.repository.d.ts +40 -0
  46. package/dist/src/infrastructure/repositories/sqlite-settings.repository.d.ts.map +1 -0
  47. package/dist/src/infrastructure/repositories/sqlite-settings.repository.js +123 -0
  48. package/dist/src/infrastructure/services/filesystem/shep-directory.service.d.ts +41 -0
  49. package/dist/src/infrastructure/services/filesystem/shep-directory.service.d.ts.map +1 -0
  50. package/dist/src/infrastructure/services/filesystem/shep-directory.service.js +64 -0
  51. package/dist/src/infrastructure/services/settings.service.d.ts +50 -0
  52. package/dist/src/infrastructure/services/settings.service.d.ts.map +1 -0
  53. package/dist/src/infrastructure/services/settings.service.js +67 -0
  54. package/dist/src/infrastructure/services/version.service.d.ts.map +1 -0
  55. package/dist/src/presentation/cli/commands/version.command.d.ts.map +1 -0
  56. package/dist/{presentation → src/presentation}/cli/index.d.ts +1 -1
  57. package/dist/src/presentation/cli/index.d.ts.map +1 -0
  58. package/dist/src/presentation/cli/index.js +86 -0
  59. package/dist/src/presentation/cli/ui/colors.d.ts.map +1 -0
  60. package/dist/src/presentation/cli/ui/formatters.d.ts.map +1 -0
  61. package/dist/src/presentation/cli/ui/index.d.ts.map +1 -0
  62. package/dist/src/presentation/cli/ui/messages.d.ts.map +1 -0
  63. package/dist/src/presentation/cli/ui/symbols.d.ts.map +1 -0
  64. package/dist/src/presentation/web/app/layout.d.ts +7 -0
  65. package/dist/src/presentation/web/app/layout.d.ts.map +1 -0
  66. package/dist/src/presentation/web/app/layout.js +21 -0
  67. package/dist/src/presentation/web/app/not-found.d.ts +2 -0
  68. package/dist/src/presentation/web/app/not-found.d.ts.map +1 -0
  69. package/dist/src/presentation/web/app/not-found.js +4 -0
  70. package/dist/src/presentation/web/app/page.d.ts +2 -0
  71. package/dist/src/presentation/web/app/page.d.ts.map +1 -0
  72. package/dist/src/presentation/web/app/page.js +6 -0
  73. package/dist/src/presentation/web/app/version/page.d.ts +2 -0
  74. package/dist/src/presentation/web/app/version/page.d.ts.map +1 -0
  75. package/dist/src/presentation/web/app/version/page.js +16 -0
  76. package/dist/src/presentation/web/components/features/index.d.ts +2 -0
  77. package/dist/src/presentation/web/components/features/index.d.ts.map +1 -0
  78. package/dist/src/presentation/web/components/features/index.js +2 -0
  79. package/dist/src/presentation/web/components/features/theme-toggle/index.d.ts +2 -0
  80. package/dist/src/presentation/web/components/features/theme-toggle/index.d.ts.map +1 -0
  81. package/dist/src/presentation/web/components/features/theme-toggle/index.js +1 -0
  82. package/dist/src/presentation/web/components/features/theme-toggle/theme-toggle.d.ts +2 -0
  83. package/dist/src/presentation/web/components/features/theme-toggle/theme-toggle.d.ts.map +1 -0
  84. package/dist/src/presentation/web/components/features/theme-toggle/theme-toggle.js +19 -0
  85. package/dist/src/presentation/web/components/features/theme-toggle/theme-toggle.stories.d.ts +8 -0
  86. package/dist/src/presentation/web/components/features/theme-toggle/theme-toggle.stories.d.ts.map +1 -0
  87. package/dist/src/presentation/web/components/features/theme-toggle/theme-toggle.stories.js +17 -0
  88. package/dist/src/presentation/web/components/ui/accordion.d.ts +8 -0
  89. package/dist/src/presentation/web/components/ui/accordion.d.ts.map +1 -0
  90. package/dist/src/presentation/web/components/ui/accordion.js +14 -0
  91. package/dist/src/presentation/web/components/ui/accordion.stories.d.ts +29 -0
  92. package/dist/src/presentation/web/components/ui/accordion.stories.d.ts.map +1 -0
  93. package/dist/src/presentation/web/components/ui/accordion.stories.js +35 -0
  94. package/dist/src/presentation/web/components/ui/alert.d.ts +9 -0
  95. package/dist/src/presentation/web/components/ui/alert.d.ts.map +1 -0
  96. package/dist/src/presentation/web/components/ui/alert.js +22 -0
  97. package/dist/src/presentation/web/components/ui/alert.stories.d.ts +10 -0
  98. package/dist/src/presentation/web/components/ui/alert.stories.d.ts.map +1 -0
  99. package/dist/src/presentation/web/components/ui/alert.stories.js +30 -0
  100. package/dist/src/presentation/web/components/ui/badge.d.ts +10 -0
  101. package/dist/src/presentation/web/components/ui/badge.d.ts.map +1 -0
  102. package/dist/src/presentation/web/components/ui/badge.js +20 -0
  103. package/dist/src/presentation/web/components/ui/badge.stories.d.ts +11 -0
  104. package/dist/src/presentation/web/components/ui/badge.stories.d.ts.map +1 -0
  105. package/dist/src/presentation/web/components/ui/badge.stories.js +44 -0
  106. package/dist/src/presentation/web/components/ui/button.d.ts +12 -0
  107. package/dist/src/presentation/web/components/ui/button.d.ts.map +1 -0
  108. package/dist/src/presentation/web/components/ui/button.js +33 -0
  109. package/dist/src/presentation/web/components/ui/button.stories.d.ts +17 -0
  110. package/dist/src/presentation/web/components/ui/button.stories.d.ts.map +1 -0
  111. package/dist/src/presentation/web/components/ui/button.stories.js +84 -0
  112. package/dist/src/presentation/web/components/ui/card.d.ts +9 -0
  113. package/dist/src/presentation/web/components/ui/card.d.ts.map +1 -0
  114. package/dist/src/presentation/web/components/ui/card.js +16 -0
  115. package/dist/src/presentation/web/components/ui/card.stories.d.ts +10 -0
  116. package/dist/src/presentation/web/components/ui/card.stories.d.ts.map +1 -0
  117. package/dist/src/presentation/web/components/ui/card.stories.js +24 -0
  118. package/dist/src/presentation/web/components/ui/dialog.d.ts +20 -0
  119. package/dist/src/presentation/web/components/ui/dialog.d.ts.map +1 -0
  120. package/dist/src/presentation/web/components/ui/dialog.js +23 -0
  121. package/dist/src/presentation/web/components/ui/dialog.stories.d.ts +9 -0
  122. package/dist/src/presentation/web/components/ui/dialog.stories.d.ts.map +1 -0
  123. package/dist/src/presentation/web/components/ui/dialog.stories.js +23 -0
  124. package/dist/src/presentation/web/components/ui/index.d.ts +13 -0
  125. package/dist/src/presentation/web/components/ui/index.d.ts.map +1 -0
  126. package/dist/src/presentation/web/components/ui/index.js +14 -0
  127. package/dist/src/presentation/web/components/ui/input.d.ts +4 -0
  128. package/dist/src/presentation/web/components/ui/input.d.ts.map +1 -0
  129. package/dist/src/presentation/web/components/ui/input.js +8 -0
  130. package/dist/src/presentation/web/components/ui/input.stories.d.ts +13 -0
  131. package/dist/src/presentation/web/components/ui/input.stories.d.ts.map +1 -0
  132. package/dist/src/presentation/web/components/ui/input.stories.js +55 -0
  133. package/dist/src/presentation/web/components/ui/label.d.ts +6 -0
  134. package/dist/src/presentation/web/components/ui/label.d.ts.map +1 -0
  135. package/dist/src/presentation/web/components/ui/label.js +10 -0
  136. package/dist/src/presentation/web/components/ui/label.stories.d.ts +9 -0
  137. package/dist/src/presentation/web/components/ui/label.stories.d.ts.map +1 -0
  138. package/dist/src/presentation/web/components/ui/label.stories.js +23 -0
  139. package/dist/src/presentation/web/components/ui/popover.d.ts +8 -0
  140. package/dist/src/presentation/web/components/ui/popover.d.ts.map +1 -0
  141. package/dist/src/presentation/web/components/ui/popover.js +11 -0
  142. package/dist/src/presentation/web/components/ui/popover.stories.d.ts +10 -0
  143. package/dist/src/presentation/web/components/ui/popover.stories.d.ts.map +1 -0
  144. package/dist/src/presentation/web/components/ui/popover.stories.js +26 -0
  145. package/dist/src/presentation/web/components/ui/select.d.ts +14 -0
  146. package/dist/src/presentation/web/components/ui/select.d.ts.map +1 -0
  147. package/dist/src/presentation/web/components/ui/select.js +26 -0
  148. package/dist/src/presentation/web/components/ui/select.stories.d.ts +10 -0
  149. package/dist/src/presentation/web/components/ui/select.stories.d.ts.map +1 -0
  150. package/dist/src/presentation/web/components/ui/select.stories.js +23 -0
  151. package/dist/src/presentation/web/components/ui/sonner.d.ts +5 -0
  152. package/dist/src/presentation/web/components/ui/sonner.d.ts.map +1 -0
  153. package/dist/src/presentation/web/components/ui/sonner.js +14 -0
  154. package/dist/src/presentation/web/components/ui/sonner.stories.d.ts +13 -0
  155. package/dist/src/presentation/web/components/ui/sonner.stories.d.ts.map +1 -0
  156. package/dist/src/presentation/web/components/ui/sonner.stories.js +51 -0
  157. package/dist/src/presentation/web/components/ui/tabs.d.ts +8 -0
  158. package/dist/src/presentation/web/components/ui/tabs.d.ts.map +1 -0
  159. package/dist/src/presentation/web/components/ui/tabs.js +13 -0
  160. package/dist/src/presentation/web/components/ui/tabs.stories.d.ts +9 -0
  161. package/dist/src/presentation/web/components/ui/tabs.stories.d.ts.map +1 -0
  162. package/dist/src/presentation/web/components/ui/tabs.stories.js +23 -0
  163. package/dist/src/presentation/web/eslint.config.d.mts +3 -0
  164. package/dist/src/presentation/web/eslint.config.d.mts.map +1 -0
  165. package/dist/src/presentation/web/eslint.config.mjs +15 -0
  166. package/dist/src/presentation/web/hooks/useTheme.d.ts +12 -0
  167. package/dist/src/presentation/web/hooks/useTheme.d.ts.map +1 -0
  168. package/dist/src/presentation/web/hooks/useTheme.js +73 -0
  169. package/dist/src/presentation/web/lib/utils.d.ts +11 -0
  170. package/dist/src/presentation/web/lib/utils.d.ts.map +1 -0
  171. package/dist/src/presentation/web/lib/utils.js +13 -0
  172. package/dist/src/presentation/web/next.config.d.ts +4 -0
  173. package/dist/src/presentation/web/next.config.d.ts.map +1 -0
  174. package/dist/src/presentation/web/next.config.js +9 -0
  175. package/dist/src/presentation/web/postcss.config.d.mts +4 -0
  176. package/dist/src/presentation/web/postcss.config.d.mts.map +1 -0
  177. package/dist/src/presentation/web/postcss.config.mjs +8 -0
  178. package/dist/src/presentation/web/types/theme.d.ts +12 -0
  179. package/dist/src/presentation/web/types/theme.d.ts.map +1 -0
  180. package/dist/src/presentation/web/types/theme.js +5 -0
  181. package/dist/tsconfig.build.tsbuildinfo +1 -0
  182. package/package.json +60 -12
  183. package/dist/index.d.ts.map +0 -1
  184. package/dist/infrastructure/services/version.service.d.ts.map +0 -1
  185. package/dist/presentation/cli/commands/version.command.d.ts.map +0 -1
  186. package/dist/presentation/cli/index.d.ts.map +0 -1
  187. package/dist/presentation/cli/index.js +0 -48
  188. package/dist/presentation/cli/ui/colors.d.ts.map +0 -1
  189. package/dist/presentation/cli/ui/formatters.d.ts.map +0 -1
  190. package/dist/presentation/cli/ui/index.d.ts.map +0 -1
  191. package/dist/presentation/cli/ui/messages.d.ts.map +0 -1
  192. package/dist/presentation/cli/ui/symbols.d.ts.map +0 -1
  193. /package/dist/{index.d.ts → src/index.d.ts} +0 -0
  194. /package/dist/{index.js → src/index.js} +0 -0
  195. /package/dist/{infrastructure → src/infrastructure}/services/version.service.d.ts +0 -0
  196. /package/dist/{infrastructure → src/infrastructure}/services/version.service.js +0 -0
  197. /package/dist/{presentation → src/presentation}/cli/commands/version.command.d.ts +0 -0
  198. /package/dist/{presentation → src/presentation}/cli/commands/version.command.js +0 -0
  199. /package/dist/{presentation → src/presentation}/cli/ui/colors.d.ts +0 -0
  200. /package/dist/{presentation → src/presentation}/cli/ui/colors.js +0 -0
  201. /package/dist/{presentation → src/presentation}/cli/ui/formatters.d.ts +0 -0
  202. /package/dist/{presentation → src/presentation}/cli/ui/formatters.js +0 -0
  203. /package/dist/{presentation → src/presentation}/cli/ui/index.d.ts +0 -0
  204. /package/dist/{presentation → src/presentation}/cli/ui/index.js +0 -0
  205. /package/dist/{presentation → src/presentation}/cli/ui/messages.d.ts +0 -0
  206. /package/dist/{presentation → src/presentation}/cli/ui/messages.js +0 -0
  207. /package/dist/{presentation → src/presentation}/cli/ui/symbols.d.ts +0 -0
  208. /package/dist/{presentation → src/presentation}/cli/ui/symbols.js +0 -0
@@ -0,0 +1,123 @@
1
+ /**
2
+ * SQLite Settings Repository Implementation
3
+ *
4
+ * Implements ISettingsRepository using SQLite database.
5
+ * Enforces singleton pattern (only one Settings record allowed).
6
+ * Uses prepared statements to prevent SQL injection.
7
+ */
8
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
9
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
10
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
11
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
12
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
13
+ };
14
+ var __metadata = (this && this.__metadata) || function (k, v) {
15
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
16
+ };
17
+ import { injectable } from 'tsyringe';
18
+ import { toDatabase, fromDatabase, } from '../persistence/sqlite/mappers/settings.mapper.js';
19
+ /**
20
+ * SQLite implementation of ISettingsRepository.
21
+ * Manages Settings persistence with singleton constraint.
22
+ */
23
+ let SQLiteSettingsRepository = class SQLiteSettingsRepository {
24
+ db;
25
+ constructor(db) {
26
+ this.db = db;
27
+ }
28
+ /**
29
+ * Initialize settings for the first time.
30
+ * Creates a new Settings record in the database.
31
+ *
32
+ * @param settings - The settings to initialize with
33
+ * @throws Error if settings already exist (singleton constraint)
34
+ */
35
+ async initialize(settings) {
36
+ // Check if settings already exist (singleton constraint)
37
+ const existing = await this.load();
38
+ if (existing !== null) {
39
+ throw new Error('Settings already exist. Use update() to modify existing settings.');
40
+ }
41
+ // Convert to database format
42
+ const row = toDatabase(settings);
43
+ // Prepare INSERT statement
44
+ const stmt = this.db.prepare(`
45
+ INSERT INTO settings (
46
+ id, created_at, updated_at,
47
+ model_analyze, model_requirements, model_plan, model_implement,
48
+ user_name, user_email, user_github_username,
49
+ env_default_editor, env_shell_preference,
50
+ sys_auto_update, sys_log_level
51
+ ) VALUES (
52
+ @id, @created_at, @updated_at,
53
+ @model_analyze, @model_requirements, @model_plan, @model_implement,
54
+ @user_name, @user_email, @user_github_username,
55
+ @env_default_editor, @env_shell_preference,
56
+ @sys_auto_update, @sys_log_level
57
+ )
58
+ `);
59
+ // Execute with named parameters (safe from SQL injection)
60
+ stmt.run(row);
61
+ }
62
+ /**
63
+ * Load existing settings from the database.
64
+ *
65
+ * @returns The existing Settings or null if not initialized
66
+ */
67
+ async load() {
68
+ // Prepare SELECT statement
69
+ const stmt = this.db.prepare('SELECT * FROM settings WHERE id = ?');
70
+ // Execute query
71
+ const row = stmt.get('singleton');
72
+ // Return null if not found
73
+ if (!row) {
74
+ return null;
75
+ }
76
+ // Convert from database format
77
+ return fromDatabase(row);
78
+ }
79
+ /**
80
+ * Update existing settings in the database.
81
+ *
82
+ * @param settings - The updated settings to persist
83
+ * @throws Error if settings don't exist (must initialize first)
84
+ */
85
+ async update(settings) {
86
+ // Check if settings exist
87
+ const existing = await this.load();
88
+ if (existing === null) {
89
+ throw new Error('Settings do not exist. Use initialize() first.');
90
+ }
91
+ // Convert to database format
92
+ const row = toDatabase(settings);
93
+ // Prepare UPDATE statement
94
+ const stmt = this.db.prepare(`
95
+ UPDATE settings SET
96
+ created_at = @created_at,
97
+ updated_at = @updated_at,
98
+ model_analyze = @model_analyze,
99
+ model_requirements = @model_requirements,
100
+ model_plan = @model_plan,
101
+ model_implement = @model_implement,
102
+ user_name = @user_name,
103
+ user_email = @user_email,
104
+ user_github_username = @user_github_username,
105
+ env_default_editor = @env_default_editor,
106
+ env_shell_preference = @env_shell_preference,
107
+ sys_auto_update = @sys_auto_update,
108
+ sys_log_level = @sys_log_level
109
+ WHERE id = @id
110
+ `);
111
+ // Execute with named parameters (safe from SQL injection)
112
+ const result = stmt.run(row);
113
+ // Verify update succeeded
114
+ if (result.changes === 0) {
115
+ throw new Error('Failed to update settings: no rows affected');
116
+ }
117
+ }
118
+ };
119
+ SQLiteSettingsRepository = __decorate([
120
+ injectable(),
121
+ __metadata("design:paramtypes", [Object])
122
+ ], SQLiteSettingsRepository);
123
+ export { SQLiteSettingsRepository };
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Shep Directory Service
3
+ *
4
+ * Manages the ~/.shep/ directory for global settings and data storage.
5
+ * Ensures directory exists with correct permissions before database operations.
6
+ */
7
+ /**
8
+ * The root directory for Shep AI CLI data.
9
+ * Located at ~/.shep/ in the user's home directory.
10
+ */
11
+ export declare const SHEP_HOME_DIR: string;
12
+ /**
13
+ * The path to the SQLite database file.
14
+ * Located at ~/.shep/data
15
+ */
16
+ export declare const SHEP_DB_PATH: string;
17
+ /**
18
+ * Ensures the ~/.shep/ directory exists with correct permissions.
19
+ * Creates the directory if it doesn't exist.
20
+ * Safe to call multiple times (idempotent).
21
+ *
22
+ * Permissions: 700 (rwx------) - only owner can read/write/execute
23
+ *
24
+ * @throws Error if directory cannot be created (permissions, disk space, etc.)
25
+ */
26
+ export declare function ensureShepDirectory(): Promise<void>;
27
+ /**
28
+ * Gets the path to the Shep home directory.
29
+ * Does not create the directory.
30
+ *
31
+ * @returns Path to ~/.shep/
32
+ */
33
+ export declare function getShepHomeDir(): string;
34
+ /**
35
+ * Gets the path to the SQLite database file.
36
+ * Does not create the file or directory.
37
+ *
38
+ * @returns Path to ~/.shep/data
39
+ */
40
+ export declare function getShepDbPath(): string;
41
+ //# sourceMappingURL=shep-directory.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shep-directory.service.d.ts","sourceRoot":"","sources":["../../../../../src/infrastructure/services/filesystem/shep-directory.service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH;;;GAGG;AACH,eAAO,MAAM,aAAa,QAA2B,CAAC;AAEtD;;;GAGG;AACH,eAAO,MAAM,YAAY,QAA8B,CAAC;AAExD;;;;;;;;GAQG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAkBzD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Shep Directory Service
3
+ *
4
+ * Manages the ~/.shep/ directory for global settings and data storage.
5
+ * Ensures directory exists with correct permissions before database operations.
6
+ */
7
+ import { mkdir } from 'node:fs/promises';
8
+ import { homedir } from 'node:os';
9
+ import { join } from 'node:path';
10
+ import { existsSync } from 'node:fs';
11
+ /**
12
+ * The root directory for Shep AI CLI data.
13
+ * Located at ~/.shep/ in the user's home directory.
14
+ */
15
+ export const SHEP_HOME_DIR = join(homedir(), '.shep');
16
+ /**
17
+ * The path to the SQLite database file.
18
+ * Located at ~/.shep/data
19
+ */
20
+ export const SHEP_DB_PATH = join(SHEP_HOME_DIR, 'data');
21
+ /**
22
+ * Ensures the ~/.shep/ directory exists with correct permissions.
23
+ * Creates the directory if it doesn't exist.
24
+ * Safe to call multiple times (idempotent).
25
+ *
26
+ * Permissions: 700 (rwx------) - only owner can read/write/execute
27
+ *
28
+ * @throws Error if directory cannot be created (permissions, disk space, etc.)
29
+ */
30
+ export async function ensureShepDirectory() {
31
+ // Check if directory already exists
32
+ if (existsSync(SHEP_HOME_DIR)) {
33
+ return;
34
+ }
35
+ try {
36
+ // Create directory with 700 permissions (owner read/write/execute only)
37
+ await mkdir(SHEP_HOME_DIR, {
38
+ recursive: true,
39
+ mode: 0o700,
40
+ });
41
+ }
42
+ catch (error) {
43
+ // Provide helpful error message
44
+ throw new Error(`Failed to create Shep directory at ${SHEP_HOME_DIR}: ${error instanceof Error ? error.message : String(error)}`);
45
+ }
46
+ }
47
+ /**
48
+ * Gets the path to the Shep home directory.
49
+ * Does not create the directory.
50
+ *
51
+ * @returns Path to ~/.shep/
52
+ */
53
+ export function getShepHomeDir() {
54
+ return SHEP_HOME_DIR;
55
+ }
56
+ /**
57
+ * Gets the path to the SQLite database file.
58
+ * Does not create the file or directory.
59
+ *
60
+ * @returns Path to ~/.shep/data
61
+ */
62
+ export function getShepDbPath() {
63
+ return SHEP_DB_PATH;
64
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Settings Service
3
+ *
4
+ * Provides global access to application settings within the CLI.
5
+ * Implements singleton pattern for consistent settings access.
6
+ *
7
+ * Usage:
8
+ * ```typescript
9
+ * import { getSettings } from './infrastructure/services/settings.service.js';
10
+ *
11
+ * const settings = getSettings();
12
+ * console.log(settings.models.analyze); // 'claude-opus-4'
13
+ * ```
14
+ */
15
+ import type { Settings } from '../../domain/generated/output.js';
16
+ /**
17
+ * Initialize the settings service with loaded settings.
18
+ * Must be called once during CLI bootstrap.
19
+ *
20
+ * @param settings - The initialized settings
21
+ * @throws Error if settings are already initialized
22
+ */
23
+ export declare function initializeSettings(settings: Settings): void;
24
+ /**
25
+ * Get the current application settings.
26
+ *
27
+ * @returns Current settings instance
28
+ * @throws Error if settings haven't been initialized yet
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * const settings = getSettings();
33
+ * console.log(settings.system.logLevel); // 'info'
34
+ * ```
35
+ */
36
+ export declare function getSettings(): Settings;
37
+ /**
38
+ * Check if settings have been initialized.
39
+ *
40
+ * @returns True if settings are initialized, false otherwise
41
+ */
42
+ export declare function hasSettings(): boolean;
43
+ /**
44
+ * Reset settings instance (for testing purposes only).
45
+ * DO NOT use in production code.
46
+ *
47
+ * @internal
48
+ */
49
+ export declare function resetSettings(): void;
50
+ //# sourceMappingURL=settings.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.service.d.ts","sourceRoot":"","sources":["../../../../src/infrastructure/services/settings.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AAQjE;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAM3D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,IAAI,QAAQ,CAMtC;AAED;;;;GAIG;AACH,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,IAAI,IAAI,CAEpC"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Settings Service
3
+ *
4
+ * Provides global access to application settings within the CLI.
5
+ * Implements singleton pattern for consistent settings access.
6
+ *
7
+ * Usage:
8
+ * ```typescript
9
+ * import { getSettings } from './infrastructure/services/settings.service.js';
10
+ *
11
+ * const settings = getSettings();
12
+ * console.log(settings.models.analyze); // 'claude-opus-4'
13
+ * ```
14
+ */
15
+ /**
16
+ * Singleton settings instance.
17
+ * Set during CLI initialization, accessed throughout application lifecycle.
18
+ */
19
+ let settingsInstance = null;
20
+ /**
21
+ * Initialize the settings service with loaded settings.
22
+ * Must be called once during CLI bootstrap.
23
+ *
24
+ * @param settings - The initialized settings
25
+ * @throws Error if settings are already initialized
26
+ */
27
+ export function initializeSettings(settings) {
28
+ if (settingsInstance !== null) {
29
+ throw new Error('Settings already initialized. Cannot re-initialize.');
30
+ }
31
+ settingsInstance = settings;
32
+ }
33
+ /**
34
+ * Get the current application settings.
35
+ *
36
+ * @returns Current settings instance
37
+ * @throws Error if settings haven't been initialized yet
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * const settings = getSettings();
42
+ * console.log(settings.system.logLevel); // 'info'
43
+ * ```
44
+ */
45
+ export function getSettings() {
46
+ if (settingsInstance === null) {
47
+ throw new Error('Settings not initialized. Call initializeSettings() during CLI bootstrap.');
48
+ }
49
+ return settingsInstance;
50
+ }
51
+ /**
52
+ * Check if settings have been initialized.
53
+ *
54
+ * @returns True if settings are initialized, false otherwise
55
+ */
56
+ export function hasSettings() {
57
+ return settingsInstance !== null;
58
+ }
59
+ /**
60
+ * Reset settings instance (for testing purposes only).
61
+ * DO NOT use in production code.
62
+ *
63
+ * @internal
64
+ */
65
+ export function resetSettings() {
66
+ settingsInstance = null;
67
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.service.d.ts","sourceRoot":"","sources":["../../../../src/infrastructure/services/version.service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,WAAW;IAC1B,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,WAAW,EAAE,MAAM,CAAC;CACrB;AA8BD;;GAEG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;;IAM1C,OAAO,CAAC,eAAe;IAqCvB;;OAEG;IACH,UAAU,IAAI,WAAW;CAG1B"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.command.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/cli/commands/version.command.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAa9C"}
@@ -16,5 +16,5 @@
16
16
  * -v, --version Display version number
17
17
  * -h, --help Display help
18
18
  */
19
- export {};
19
+ import 'reflect-metadata';
20
20
  //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/presentation/cli/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,kBAAkB,CAAC"}
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Shep AI CLI Entry Point
4
+ *
5
+ * Autonomous AI Native SDLC Platform - CLI Interface
6
+ *
7
+ * Usage:
8
+ * shep [command] [options]
9
+ *
10
+ * Commands:
11
+ * shep Show help
12
+ * shep version Display version information
13
+ * shep --version Display version number only
14
+ *
15
+ * Global Options:
16
+ * -v, --version Display version number
17
+ * -h, --help Display help
18
+ */
19
+ // IMPORTANT: reflect-metadata must be imported first for tsyringe DI
20
+ import 'reflect-metadata';
21
+ import { Command } from 'commander';
22
+ import { VersionService } from '../../infrastructure/services/version.service.js';
23
+ import { createVersionCommand } from './commands/version.command.js';
24
+ import { messages } from './ui/index.js';
25
+ // DI container and settings
26
+ import { initializeContainer, container } from '../../infrastructure/di/container.js';
27
+ import { InitializeSettingsUseCase } from '../../application/use-cases/settings/initialize-settings.use-case.js';
28
+ import { initializeSettings } from '../../infrastructure/services/settings.service.js';
29
+ /**
30
+ * Bootstrap function - initializes all dependencies before CLI starts.
31
+ * Performs async initialization (database, settings) before parsing commands.
32
+ */
33
+ async function bootstrap() {
34
+ try {
35
+ // Step 1: Initialize DI container (database + migrations)
36
+ try {
37
+ await initializeContainer();
38
+ }
39
+ catch (error) {
40
+ const err = error instanceof Error ? error : new Error(String(error));
41
+ messages.error('Failed to initialize database', err);
42
+ throw error; // Re-throw to trigger outer catch
43
+ }
44
+ // Step 2: Initialize settings
45
+ try {
46
+ const initializeSettingsUseCase = container.resolve(InitializeSettingsUseCase);
47
+ const settings = await initializeSettingsUseCase.execute();
48
+ initializeSettings(settings);
49
+ }
50
+ catch (error) {
51
+ const err = error instanceof Error ? error : new Error(String(error));
52
+ messages.error('Failed to initialize settings', err);
53
+ throw error;
54
+ }
55
+ // Step 3: Set up Commander CLI
56
+ const versionService = new VersionService();
57
+ const { version, description } = versionService.getVersion();
58
+ const program = new Command()
59
+ .name('shep')
60
+ .description(description)
61
+ .version(version, '-v, --version', 'Display version number')
62
+ .action(() => {
63
+ program.outputHelp();
64
+ });
65
+ // Register commands
66
+ program.addCommand(createVersionCommand());
67
+ // Parse arguments
68
+ program.parse();
69
+ }
70
+ catch (_error) {
71
+ // Final catch - already logged specific error above
72
+ process.exit(1);
73
+ }
74
+ }
75
+ // Global error handlers
76
+ process.on('uncaughtException', (error) => {
77
+ messages.error('An unexpected error occurred', error);
78
+ process.exit(1);
79
+ });
80
+ process.on('unhandledRejection', (reason) => {
81
+ const error = reason instanceof Error ? reason : new Error(String(reason));
82
+ messages.error('Unhandled promise rejection', error);
83
+ process.exit(1);
84
+ });
85
+ // Start the CLI
86
+ bootstrap();
@@ -0,0 +1 @@
1
+ {"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/cli/ui/colors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH;;GAEG;AACH,eAAO,MAAM,MAAM;IAEjB,iCAAiC;;IAIjC,4BAA4B;;IAE5B,wBAAwB;;IAExB,6BAA6B;;IAE7B,wBAAwB;;IAIxB,kCAAkC;;IAElC,wCAAwC;;CAEhC,CAAC;AAEX,MAAM,MAAM,MAAM,GAAG,OAAO,MAAM,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatters.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/cli/ui/formatters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH;;GAEG;AACH,eAAO,MAAM,GAAG;IACd,gBAAgB;;IAEhB,wBAAwB;;IAExB,kBAAkB;;IAElB,sBAAsB;;IAEtB,2CAA2C;;IAK3C,yCAAyC;6BACzB,MAAM;IACtB,gCAAgC;0BACnB,MAAM;IACnB,iCAAiC;2BACnB,MAAM;IACpB,2BAA2B;2BACb,MAAM;IACpB,2BAA2B;6BACX,MAAM;CACd,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/cli/ui/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,MAAM,EAAE,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,GAAG,EAAE,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/cli/ui/messages.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH;;GAEG;AACH,eAAO,MAAM,QAAQ;IACnB;;;;OAIG;6BACa,MAAM,KAAG,IAAI;IAI7B;;;;;;OAMG;2BACW,MAAM,UAAU,KAAK,KAAG,IAAI;IAO1C;;;;OAIG;6BACa,MAAM,KAAG,IAAI;IAI7B;;;;OAIG;0BACU,MAAM,KAAG,IAAI;IAI1B;;;;OAIG;2BACW,MAAM,KAAG,IAAI;IAM3B;;OAEG;4BACU,IAAI;IAIjB;;OAEG;yBACS,MAAM,KAAG,IAAI;CAGjB,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,OAAO,QAAQ,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"symbols.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/cli/ui/symbols.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAkCH;;GAEG;AACH,eAAO,MAAM,OAAO;IAClB,wBAAwB;;IAExB,kBAAkB;;IAElB,uBAAuB;;IAEvB,kBAAkB;;IAElB,oBAAoB;;IAEpB,mBAAmB;;IAEnB,oBAAoB;;IAEpB,sCAAsC;;IAEtC,qBAAqB;;IAErB,2CAA2C;;CAEnC,CAAC;AAEX,MAAM,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { Metadata } from 'next';
2
+ import './globals.css';
3
+ export declare const metadata: Metadata;
4
+ export default function RootLayout({ children, }: Readonly<{
5
+ children: React.ReactNode;
6
+ }>): import("react/jsx-runtime").JSX.Element;
7
+ //# sourceMappingURL=layout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/app/layout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,eAAe,CAAC;AAEvB,eAAO,MAAM,QAAQ,EAAE,QAItB,CAAC;AAEF,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,EACjC,QAAQ,GACT,EAAE,QAAQ,CAAC;IACV,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,CAAC,2CAuBD"}
@@ -0,0 +1,21 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import './globals.css';
3
+ export const metadata = {
4
+ title: 'Shep AI',
5
+ description: 'Autonomous AI Native SDLC Platform - Automate the development cycle from idea to deploy',
6
+ };
7
+ export default function RootLayout({ children, }) {
8
+ return (_jsxs("html", { lang: "en", suppressHydrationWarning: true, children: [_jsx("head", { children: _jsx("script", { dangerouslySetInnerHTML: {
9
+ __html: `
10
+ (function() {
11
+ try {
12
+ const theme = localStorage.getItem('shep-theme');
13
+ const systemDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
14
+ if (theme === 'dark' || (theme === 'system' && systemDark) || (!theme && systemDark)) {
15
+ document.documentElement.classList.add('dark');
16
+ }
17
+ } catch (e) {}
18
+ })();
19
+ `,
20
+ } }) }), _jsx("body", { className: "min-h-screen antialiased", children: children })] }));
21
+ }
@@ -0,0 +1,2 @@
1
+ export default function NotFound(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=not-found.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"not-found.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/app/not-found.tsx"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,UAAU,QAAQ,4CAS/B"}
@@ -0,0 +1,4 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ export default function NotFound() {
3
+ return (_jsx("div", { className: "flex min-h-screen items-center justify-center", children: _jsxs("div", { className: "text-center", children: [_jsx("h2", { className: "text-2xl font-bold", children: "Not Found" }), _jsx("p", { className: "text-muted-foreground", children: "Could not find requested resource" })] }) }));
4
+ }
@@ -0,0 +1,2 @@
1
+ export default function HomePage(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/app/page.tsx"],"names":[],"mappings":"AAGA,MAAM,CAAC,OAAO,UAAU,QAAQ,4CAe/B"}
@@ -0,0 +1,6 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import Link from 'next/link';
3
+ import { Button } from '@/components/ui/button';
4
+ export default function HomePage() {
5
+ return (_jsx("main", { className: "flex min-h-screen flex-col items-center justify-center p-4", children: _jsxs("div", { className: "text-center", children: [_jsx("h1", { className: "text-4xl font-bold tracking-tight", children: "Shep AI" }), _jsx("p", { className: "text-muted-foreground mt-4 text-lg", children: "Autonomous AI Native SDLC Platform" }), _jsx("p", { className: "text-muted-foreground mt-2 text-sm", children: "Web UI Component Library" }), _jsx("div", { className: "mt-6", children: _jsx(Button, { asChild: true, variant: "outline", children: _jsx(Link, { href: "/version", children: "View Version" }) }) })] }) }));
6
+ }
@@ -0,0 +1,2 @@
1
+ export default function VersionPage(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/version/page.tsx"],"names":[],"mappings":"AAgCA,MAAM,CAAC,OAAO,UAAU,WAAW,4CA8FlC"}
@@ -0,0 +1,16 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import Link from 'next/link';
4
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
5
+ import { Badge } from '@/components/ui/badge';
6
+ import { Button } from '@/components/ui/button';
7
+ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
8
+ const VERSION = '1.2.0';
9
+ const PACKAGE_NAME = '@shepai/cli';
10
+ const DESCRIPTION = 'Autonomous AI Native SDLC Platform';
11
+ function InfoRow({ label, value, badge, badgeVariant = 'secondary' }) {
12
+ return (_jsxs("div", { className: "flex items-center justify-between py-2", children: [_jsx("span", { className: "text-muted-foreground text-sm", children: label }), badge ? (_jsx(Badge, { variant: badgeVariant, children: value })) : (_jsx("span", { className: "font-mono text-sm", children: value }))] }));
13
+ }
14
+ export default function VersionPage() {
15
+ return (_jsx("main", { className: "flex min-h-screen flex-col items-center justify-center p-4", children: _jsxs("div", { className: "w-full max-w-2xl space-y-6", children: [_jsxs("div", { className: "text-center", children: [_jsx("h1", { className: "text-3xl font-bold tracking-tight", children: PACKAGE_NAME }), _jsx("p", { className: "text-muted-foreground mt-2", children: DESCRIPTION }), _jsx("div", { className: "mt-4", children: _jsxs(Badge, { variant: "default", "data-testid": "version-badge", children: ["v", VERSION] }) })] }), _jsxs(Tabs, { defaultValue: "overview", className: "w-full", children: [_jsxs(TabsList, { className: "grid w-full grid-cols-3", children: [_jsx(TabsTrigger, { value: "overview", children: "Overview" }), _jsx(TabsTrigger, { value: "system", children: "System" }), _jsx(TabsTrigger, { value: "features", children: "Features" })] }), _jsx(TabsContent, { value: "overview", children: _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: "Package Information" }), _jsx(CardDescription, { children: "Details about the Shep AI CLI package" })] }), _jsxs(CardContent, { className: "space-y-1", children: [_jsx(InfoRow, { label: "Package", value: PACKAGE_NAME }), _jsx(InfoRow, { label: "Version", value: `v${VERSION}`, badge: true, badgeVariant: "default" }), _jsx(InfoRow, { label: "License", value: "MIT", badge: true, badgeVariant: "outline" }), _jsx(InfoRow, { label: "Author", value: "Shep AI" })] })] }) }), _jsx(TabsContent, { value: "system", children: _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: "System Information" }), _jsx(CardDescription, { children: "Runtime environment details" })] }), _jsxs(CardContent, { className: "space-y-1", children: [_jsx(InfoRow, { label: "Node.js", value: "v22.x", badge: true, badgeVariant: "secondary" }), _jsx(InfoRow, { label: "React", value: "v19.x", badge: true, badgeVariant: "secondary" }), _jsx(InfoRow, { label: "Next.js", value: "v16.x", badge: true, badgeVariant: "secondary" }), _jsx(InfoRow, { label: "Platform", value: "Web" })] })] }) }), _jsx(TabsContent, { value: "features", children: _jsxs(Card, { children: [_jsxs(CardHeader, { children: [_jsx(CardTitle, { children: "Key Features" }), _jsx(CardDescription, { children: "What Shep AI can do for you" })] }), _jsx(CardContent, { children: _jsxs("ul", { className: "space-y-2 text-sm", children: [_jsxs("li", { className: "flex items-center gap-2", children: [_jsx(Badge, { variant: "outline", children: "AI" }), _jsx("span", { children: "Autonomous code generation" })] }), _jsxs("li", { className: "flex items-center gap-2", children: [_jsx(Badge, { variant: "outline", children: "SDLC" }), _jsx("span", { children: "Full development lifecycle automation" })] }), _jsxs("li", { className: "flex items-center gap-2", children: [_jsx(Badge, { variant: "outline", children: "CLI" }), _jsx("span", { children: "Powerful command-line interface" })] }), _jsxs("li", { className: "flex items-center gap-2", children: [_jsx(Badge, { variant: "outline", children: "Web" }), _jsx("span", { children: "Modern web UI dashboard" })] })] }) })] }) })] }), _jsxs("div", { className: "flex justify-center gap-4", children: [_jsx(Button, { asChild: true, variant: "outline", children: _jsx(Link, { href: "/", children: "Back to Home" }) }), _jsx(Button, { asChild: true, children: _jsx("a", { href: "https://github.com/shep-ai/cli", target: "_blank", rel: "noopener noreferrer", children: "View on GitHub" }) })] })] }) }));
16
+ }
@@ -0,0 +1,2 @@
1
+ export { ThemeToggle } from './theme-toggle';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/components/features/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,2 @@
1
+ // Feature components barrel export
2
+ export { ThemeToggle } from './theme-toggle';
@@ -0,0 +1,2 @@
1
+ export { ThemeToggle } from './theme-toggle';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/theme-toggle/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1 @@
1
+ export { ThemeToggle } from './theme-toggle';
@@ -0,0 +1,2 @@
1
+ export declare function ThemeToggle(): import("react/jsx-runtime").JSX.Element;
2
+ //# sourceMappingURL=theme-toggle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme-toggle.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/theme-toggle/theme-toggle.tsx"],"names":[],"mappings":"AAMA,wBAAgB,WAAW,4CAyB1B"}
@@ -0,0 +1,19 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Moon, Sun } from 'lucide-react';
4
+ import { Button } from '@/components/ui/button';
5
+ import { useTheme } from '@/hooks/useTheme';
6
+ export function ThemeToggle() {
7
+ const { theme, resolvedTheme, setTheme } = useTheme();
8
+ const toggleTheme = () => {
9
+ // If system theme, switch to explicit light/dark
10
+ // If explicit, toggle between light and dark
11
+ if (theme === 'system') {
12
+ setTheme(resolvedTheme === 'dark' ? 'light' : 'dark');
13
+ }
14
+ else {
15
+ setTheme(theme === 'dark' ? 'light' : 'dark');
16
+ }
17
+ };
18
+ return (_jsxs(Button, { variant: "ghost", size: "icon", onClick: toggleTheme, "aria-label": `Switch to ${resolvedTheme === 'dark' ? 'light' : 'dark'} mode`, children: [_jsx(Sun, { className: "h-5 w-5 scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90" }), _jsx(Moon, { className: "absolute h-5 w-5 scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0" }), _jsx("span", { className: "sr-only", children: "Toggle theme" })] }));
19
+ }
@@ -0,0 +1,8 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { ThemeToggle } from './theme-toggle';
3
+ declare const meta: Meta<typeof ThemeToggle>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof meta>;
6
+ export declare const Default: Story;
7
+ export declare const InContext: Story;
8
+ //# sourceMappingURL=theme-toggle.stories.d.ts.map