@dedesfr/prompter 0.7.8 → 0.7.9
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 +10 -0
- package/dist/cli/index.js +1 -1
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +3 -1
- package/dist/core/config.js.map +1 -1
- package/dist/core/configurators/slash/droid.d.ts +9 -0
- package/dist/core/configurators/slash/droid.d.ts.map +1 -0
- package/dist/core/configurators/slash/droid.js +36 -0
- package/dist/core/configurators/slash/droid.js.map +1 -0
- package/dist/core/configurators/slash/forge.d.ts +9 -0
- package/dist/core/configurators/slash/forge.d.ts.map +1 -0
- package/dist/core/configurators/slash/forge.js +36 -0
- package/dist/core/configurators/slash/forge.js.map +1 -0
- package/dist/core/configurators/slash/index.d.ts +2 -0
- package/dist/core/configurators/slash/index.d.ts.map +1 -1
- package/dist/core/configurators/slash/index.js +2 -0
- package/dist/core/configurators/slash/index.js.map +1 -1
- package/dist/core/configurators/slash/registry.d.ts.map +1 -1
- package/dist/core/configurators/slash/registry.js +6 -0
- package/dist/core/configurators/slash/registry.js.map +1 -1
- package/package.json +1 -1
- package/skills/design-system-generator/SKILL.md +324 -0
- package/skills/design-system-generator/assets/design-system-template.md +348 -0
- package/skills/design-system-generator/references/extraction-patterns.md +321 -0
- package/skills/laravel-code-review/SKILL.md +383 -0
- package/skills/laravel-code-review/assets/report-template-agent.md +195 -0
- package/skills/laravel-code-review/assets/report-template-compact.md +79 -0
- package/skills/laravel-code-review/assets/report-template-full.md +253 -0
- package/skills/laravel-code-review/assets/report-template-human.md +159 -0
- package/skills/laravel-code-review/references/laravel-patterns.md +571 -0
- package/skills/laravel-code-review/references/php84-features.md +442 -0
- package/src/cli/index.ts +1 -1
- package/src/core/config.ts +3 -1
- package/src/core/configurators/slash/droid.ts +40 -0
- package/src/core/configurators/slash/forge.ts +40 -0
- package/src/core/configurators/slash/index.ts +2 -0
- package/src/core/configurators/slash/registry.ts +6 -0
|
@@ -0,0 +1,442 @@
|
|
|
1
|
+
# PHP 8.4 Features Reference
|
|
2
|
+
|
|
3
|
+
Quick reference for PHP 8.4 features to use and deprecations to avoid.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## New Features to Adopt
|
|
8
|
+
|
|
9
|
+
### Property Hooks (PHP 8.4)
|
|
10
|
+
|
|
11
|
+
```php
|
|
12
|
+
// ✅ New: Property hooks
|
|
13
|
+
class User
|
|
14
|
+
{
|
|
15
|
+
public string $fullName {
|
|
16
|
+
get => $this->firstName . ' ' . $this->lastName;
|
|
17
|
+
set => [$this->firstName, $this->lastName] = explode(' ', $value, 2);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public string $email {
|
|
21
|
+
set => strtolower($value);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Asymmetric Visibility (PHP 8.4)
|
|
27
|
+
|
|
28
|
+
```php
|
|
29
|
+
// ✅ New: Different visibility for get/set
|
|
30
|
+
class User
|
|
31
|
+
{
|
|
32
|
+
public private(set) string $id;
|
|
33
|
+
public protected(set) string $name;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Can read $user->id publicly
|
|
37
|
+
// Can only set $user->id privately
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### new Without Parentheses (PHP 8.4)
|
|
41
|
+
|
|
42
|
+
```php
|
|
43
|
+
// ❌ Old: Required parentheses
|
|
44
|
+
$user = (new User())->setName('John');
|
|
45
|
+
|
|
46
|
+
// ✅ New: No parentheses needed
|
|
47
|
+
$user = new User()->setName('John');
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Array Find Functions (PHP 8.4)
|
|
51
|
+
|
|
52
|
+
```php
|
|
53
|
+
// ✅ New: array_find()
|
|
54
|
+
$users = [
|
|
55
|
+
['name' => 'John', 'active' => false],
|
|
56
|
+
['name' => 'Jane', 'active' => true],
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
$activeUser = array_find($users, fn($u) => $u['active']);
|
|
60
|
+
// Returns: ['name' => 'Jane', 'active' => true]
|
|
61
|
+
|
|
62
|
+
// ✅ New: array_find_key()
|
|
63
|
+
$key = array_find_key($users, fn($u) => $u['active']);
|
|
64
|
+
// Returns: 1
|
|
65
|
+
|
|
66
|
+
// ✅ New: array_any()
|
|
67
|
+
$hasActive = array_any($users, fn($u) => $u['active']);
|
|
68
|
+
// Returns: true
|
|
69
|
+
|
|
70
|
+
// ✅ New: array_all()
|
|
71
|
+
$allActive = array_all($users, fn($u) => $u['active']);
|
|
72
|
+
// Returns: false
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### HTML5 DOM Support (PHP 8.4)
|
|
76
|
+
|
|
77
|
+
```php
|
|
78
|
+
// ✅ New: Native HTML5 parsing
|
|
79
|
+
$dom = Dom\HTMLDocument::createFromString($html);
|
|
80
|
+
$dom = Dom\HTMLDocument::createFromFile('page.html');
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## PHP 8.3 Features (Ensure Usage)
|
|
86
|
+
|
|
87
|
+
### #[Override] Attribute
|
|
88
|
+
|
|
89
|
+
```php
|
|
90
|
+
// ✅ Use Override for overridden methods
|
|
91
|
+
class CustomHandler extends BaseHandler
|
|
92
|
+
{
|
|
93
|
+
#[\Override]
|
|
94
|
+
public function handle(): void
|
|
95
|
+
{
|
|
96
|
+
// Implementation
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Typed Class Constants
|
|
102
|
+
|
|
103
|
+
```php
|
|
104
|
+
// ✅ Type constants
|
|
105
|
+
class Status
|
|
106
|
+
{
|
|
107
|
+
public const string PENDING = 'pending';
|
|
108
|
+
public const string ACTIVE = 'active';
|
|
109
|
+
public const int MAX_RETRY = 3;
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### json_validate()
|
|
114
|
+
|
|
115
|
+
```php
|
|
116
|
+
// ❌ Old: Decode to validate
|
|
117
|
+
$valid = json_decode($json) !== null;
|
|
118
|
+
|
|
119
|
+
// ✅ New: Direct validation
|
|
120
|
+
$valid = json_validate($json);
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Randomizer Additions
|
|
124
|
+
|
|
125
|
+
```php
|
|
126
|
+
// ✅ New random methods
|
|
127
|
+
$randomizer = new Random\Randomizer();
|
|
128
|
+
$randomizer->getBytesFromString('abc', 10);
|
|
129
|
+
$randomizer->nextFloat();
|
|
130
|
+
$randomizer->getFloat(0.0, 1.0);
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## PHP 8.2 Features (Ensure Usage)
|
|
136
|
+
|
|
137
|
+
### Readonly Classes
|
|
138
|
+
|
|
139
|
+
```php
|
|
140
|
+
// ✅ Entire class readonly
|
|
141
|
+
readonly class UserDTO
|
|
142
|
+
{
|
|
143
|
+
public function __construct(
|
|
144
|
+
public string $name,
|
|
145
|
+
public string $email,
|
|
146
|
+
) {}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Null/False/True Types
|
|
151
|
+
|
|
152
|
+
```php
|
|
153
|
+
// ✅ Standalone null type
|
|
154
|
+
function alwaysNull(): null
|
|
155
|
+
{
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// ✅ Standalone false type
|
|
160
|
+
function failed(): false
|
|
161
|
+
{
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Disjunctive Normal Form Types
|
|
167
|
+
|
|
168
|
+
```php
|
|
169
|
+
// ✅ Complex union types
|
|
170
|
+
function process((A&B)|null $value): void {}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## PHP 8.1 Features (Ensure Usage)
|
|
176
|
+
|
|
177
|
+
### Enums
|
|
178
|
+
|
|
179
|
+
```php
|
|
180
|
+
// ✅ Backed enums
|
|
181
|
+
enum OrderStatus: string
|
|
182
|
+
{
|
|
183
|
+
case Pending = 'pending';
|
|
184
|
+
case Processing = 'processing';
|
|
185
|
+
case Completed = 'completed';
|
|
186
|
+
case Cancelled = 'cancelled';
|
|
187
|
+
|
|
188
|
+
public function label(): string
|
|
189
|
+
{
|
|
190
|
+
return match($this) {
|
|
191
|
+
self::Pending => 'Order Pending',
|
|
192
|
+
self::Processing => 'In Progress',
|
|
193
|
+
self::Completed => 'Completed',
|
|
194
|
+
self::Cancelled => 'Cancelled',
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
### Readonly Properties
|
|
201
|
+
|
|
202
|
+
```php
|
|
203
|
+
// ✅ Immutable properties
|
|
204
|
+
class User
|
|
205
|
+
{
|
|
206
|
+
public function __construct(
|
|
207
|
+
public readonly int $id,
|
|
208
|
+
public readonly string $email,
|
|
209
|
+
) {}
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### First-Class Callables
|
|
214
|
+
|
|
215
|
+
```php
|
|
216
|
+
// ❌ Old: Closure::fromCallable
|
|
217
|
+
$fn = Closure::fromCallable([$this, 'method']);
|
|
218
|
+
|
|
219
|
+
// ✅ New: First-class callable syntax
|
|
220
|
+
$fn = $this->method(...);
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Intersection Types
|
|
224
|
+
|
|
225
|
+
```php
|
|
226
|
+
// ✅ Require multiple interfaces
|
|
227
|
+
function process(Countable&Iterator $items): void {}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### Fibers
|
|
231
|
+
|
|
232
|
+
```php
|
|
233
|
+
// ✅ Fiber for async
|
|
234
|
+
$fiber = new Fiber(function() {
|
|
235
|
+
$value = Fiber::suspend('paused');
|
|
236
|
+
return $value;
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
$result = $fiber->start();
|
|
240
|
+
$final = $fiber->resume('resumed');
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## PHP 8.0 Features (Ensure Usage)
|
|
246
|
+
|
|
247
|
+
### Constructor Property Promotion
|
|
248
|
+
|
|
249
|
+
```php
|
|
250
|
+
// ❌ Old
|
|
251
|
+
class User
|
|
252
|
+
{
|
|
253
|
+
private string $name;
|
|
254
|
+
|
|
255
|
+
public function __construct(string $name)
|
|
256
|
+
{
|
|
257
|
+
$this->name = $name;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// ✅ New: Property promotion
|
|
262
|
+
class User
|
|
263
|
+
{
|
|
264
|
+
public function __construct(
|
|
265
|
+
private readonly string $name,
|
|
266
|
+
) {}
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Named Arguments
|
|
271
|
+
|
|
272
|
+
```php
|
|
273
|
+
// ✅ Named arguments for clarity
|
|
274
|
+
$user = new User(
|
|
275
|
+
name: 'John',
|
|
276
|
+
email: 'john@example.com',
|
|
277
|
+
isAdmin: false,
|
|
278
|
+
);
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Match Expression
|
|
282
|
+
|
|
283
|
+
```php
|
|
284
|
+
// ❌ Old: Switch
|
|
285
|
+
switch ($status) {
|
|
286
|
+
case 'pending':
|
|
287
|
+
$color = 'yellow';
|
|
288
|
+
break;
|
|
289
|
+
default:
|
|
290
|
+
$color = 'gray';
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// ✅ New: Match
|
|
294
|
+
$color = match($status) {
|
|
295
|
+
'pending' => 'yellow',
|
|
296
|
+
'approved' => 'green',
|
|
297
|
+
default => 'gray',
|
|
298
|
+
};
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Nullsafe Operator
|
|
302
|
+
|
|
303
|
+
```php
|
|
304
|
+
// ❌ Old: Null checks
|
|
305
|
+
$country = null;
|
|
306
|
+
if ($user !== null && $user->address !== null) {
|
|
307
|
+
$country = $user->address->country;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// ✅ New: Nullsafe
|
|
311
|
+
$country = $user?->address?->country;
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Union Types
|
|
315
|
+
|
|
316
|
+
```php
|
|
317
|
+
// ✅ Union types
|
|
318
|
+
function parse(string|int $value): string|false {}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### Attributes
|
|
322
|
+
|
|
323
|
+
```php
|
|
324
|
+
// ✅ Native attributes
|
|
325
|
+
#[Route('/users', methods: ['GET'])]
|
|
326
|
+
public function index(): Response {}
|
|
327
|
+
|
|
328
|
+
#[Deprecated('Use newMethod() instead')]
|
|
329
|
+
public function oldMethod(): void {}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
---
|
|
333
|
+
|
|
334
|
+
## Deprecations to Fix
|
|
335
|
+
|
|
336
|
+
### PHP 8.4 Deprecations
|
|
337
|
+
|
|
338
|
+
```php
|
|
339
|
+
// ❌ Deprecated: Implicit nullable
|
|
340
|
+
function foo(string $value = null) {}
|
|
341
|
+
|
|
342
|
+
// ✅ Fixed: Explicit nullable
|
|
343
|
+
function foo(?string $value = null) {}
|
|
344
|
+
|
|
345
|
+
// ❌ Deprecated: session_register()
|
|
346
|
+
session_register('var');
|
|
347
|
+
|
|
348
|
+
// ✅ Fixed: Use $_SESSION
|
|
349
|
+
$_SESSION['var'] = $value;
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
### PHP 8.2 Deprecations
|
|
353
|
+
|
|
354
|
+
```php
|
|
355
|
+
// ❌ Deprecated: Dynamic properties
|
|
356
|
+
class User
|
|
357
|
+
{
|
|
358
|
+
public string $name;
|
|
359
|
+
}
|
|
360
|
+
$user = new User();
|
|
361
|
+
$user->undefined = 'value'; // Deprecated!
|
|
362
|
+
|
|
363
|
+
// ✅ Fixed: Define property or use #[AllowDynamicProperties]
|
|
364
|
+
#[\AllowDynamicProperties]
|
|
365
|
+
class User
|
|
366
|
+
{
|
|
367
|
+
public string $name;
|
|
368
|
+
}
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### PHP 8.1 Deprecations
|
|
372
|
+
|
|
373
|
+
```php
|
|
374
|
+
// ❌ Deprecated: ${var} in strings
|
|
375
|
+
$name = 'John';
|
|
376
|
+
echo "Hello ${name}"; // Deprecated!
|
|
377
|
+
|
|
378
|
+
// ✅ Fixed: Use {$var}
|
|
379
|
+
echo "Hello {$name}";
|
|
380
|
+
|
|
381
|
+
// ❌ Deprecated: Passing null to non-nullable
|
|
382
|
+
strlen(null); // Deprecated!
|
|
383
|
+
|
|
384
|
+
// ✅ Fixed: Check for null
|
|
385
|
+
strlen($value ?? '');
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
## Type Safety Improvements
|
|
391
|
+
|
|
392
|
+
### Strict Return Types
|
|
393
|
+
|
|
394
|
+
```php
|
|
395
|
+
// ❌ Poor: No return type
|
|
396
|
+
public function getUsers()
|
|
397
|
+
{
|
|
398
|
+
return User::all();
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// ✅ Good: Explicit return type
|
|
402
|
+
public function getUsers(): Collection
|
|
403
|
+
{
|
|
404
|
+
return User::all();
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// ✅ Good: Never return type
|
|
408
|
+
public function fail(): never
|
|
409
|
+
{
|
|
410
|
+
throw new Exception('Failed');
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// ✅ Good: Void return type
|
|
414
|
+
public function log(string $message): void
|
|
415
|
+
{
|
|
416
|
+
Log::info($message);
|
|
417
|
+
}
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### Strict Parameter Types
|
|
421
|
+
|
|
422
|
+
```php
|
|
423
|
+
// ❌ Poor: No parameter types
|
|
424
|
+
public function process($data, $options)
|
|
425
|
+
|
|
426
|
+
// ✅ Good: Typed parameters
|
|
427
|
+
public function process(array $data, ProcessOptions $options): Result
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
---
|
|
431
|
+
|
|
432
|
+
## Detection Patterns
|
|
433
|
+
|
|
434
|
+
| Issue | Detection Pattern |
|
|
435
|
+
| ------------------ | ----------------------------------------------------------- |
|
|
436
|
+
| Missing readonly | Class properties without `readonly` that are never modified |
|
|
437
|
+
| Missing match | Switch statements that return values |
|
|
438
|
+
| Missing nullsafe | Nested null checks with `&&` |
|
|
439
|
+
| Missing named args | Constructor calls with 4+ positional parameters |
|
|
440
|
+
| Implicit nullable | Parameters with `= null` but no `?` type |
|
|
441
|
+
| Dynamic properties | Property access on undefined properties |
|
|
442
|
+
| Old string syntax | `${var}` instead of `{$var}` |
|
package/src/cli/index.ts
CHANGED
package/src/core/config.ts
CHANGED
|
@@ -28,7 +28,9 @@ export const SUPPORTED_TOOLS: ToolChoice[] = [
|
|
|
28
28
|
{ name: 'Codex', value: 'codex', available: true, successLabel: 'Codex' },
|
|
29
29
|
{ name: 'GitHub Copilot', value: 'github-copilot', available: true, successLabel: 'GitHub Copilot' },
|
|
30
30
|
{ name: 'OpenCode', value: 'opencode', available: true, successLabel: 'OpenCode' },
|
|
31
|
-
{ name: 'Kilo Code', value: 'kilocode', available: true, successLabel: 'Kilo Code' }
|
|
31
|
+
{ name: 'Kilo Code', value: 'kilocode', available: true, successLabel: 'Kilo Code' },
|
|
32
|
+
{ name: 'Forge', value: 'forge', available: true, successLabel: 'Forge' },
|
|
33
|
+
{ name: 'Droid', value: 'droid', available: true, successLabel: 'Droid' }
|
|
32
34
|
];
|
|
33
35
|
|
|
34
36
|
export const AVAILABLE_PROMPTS: PromptChoice[] = [
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { SlashCommandConfigurator } from './base.js';
|
|
2
|
+
import { SlashCommandId } from '../../templates/index.js';
|
|
3
|
+
|
|
4
|
+
const FILE_PATHS: Record<SlashCommandId, string> = {
|
|
5
|
+
enhance: '.factory/commands/prompter/enhance.md',
|
|
6
|
+
'prd-generator': '.factory/commands/prompter/prd-generator.md',
|
|
7
|
+
'prd-agent-generator': '.factory/commands/prompter/prd-agent-generator.md',
|
|
8
|
+
'product-brief': '.factory/commands/prompter/product-brief.md',
|
|
9
|
+
'epic-single': '.factory/commands/prompter/epic-single.md',
|
|
10
|
+
'epic-generator': '.factory/commands/prompter/epic-generator.md',
|
|
11
|
+
'story-single': '.factory/commands/prompter/story-single.md',
|
|
12
|
+
'story-generator': '.factory/commands/prompter/story-generator.md',
|
|
13
|
+
'qa-test-scenario': '.factory/commands/prompter/qa-test-scenario.md',
|
|
14
|
+
'skill-creator': '.factory/commands/prompter/skill-creator.md',
|
|
15
|
+
'ai-humanizer': '.factory/commands/prompter/ai-humanizer.md',
|
|
16
|
+
'api-contract-generator': '.factory/commands/prompter/api-contract-generator.md',
|
|
17
|
+
'apply': '.factory/commands/prompter/apply.md',
|
|
18
|
+
'archive': '.factory/commands/prompter/archive.md',
|
|
19
|
+
'design-system': '.factory/commands/prompter/design-system.md',
|
|
20
|
+
'erd-generator': '.factory/commands/prompter/erd-generator.md',
|
|
21
|
+
'fsd-generator': '.factory/commands/prompter/fsd-generator.md',
|
|
22
|
+
'proposal': '.factory/commands/prompter/proposal.md',
|
|
23
|
+
'tdd-generator': '.factory/commands/prompter/tdd-generator.md',
|
|
24
|
+
'tdd-lite-generator': '.factory/commands/prompter/tdd-lite-generator.md',
|
|
25
|
+
'wireframe-generator': '.factory/commands/prompter/wireframe-generator.md',
|
|
26
|
+
'document-explainer': '.factory/commands/prompter/document-explainer.md'
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export class DroidConfigurator extends SlashCommandConfigurator {
|
|
30
|
+
readonly toolId = 'droid';
|
|
31
|
+
readonly isAvailable = true;
|
|
32
|
+
|
|
33
|
+
protected getRelativePath(id: SlashCommandId): string {
|
|
34
|
+
return FILE_PATHS[id];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
protected getFrontmatter(id: SlashCommandId): string | undefined {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { SlashCommandConfigurator } from './base.js';
|
|
2
|
+
import { SlashCommandId } from '../../templates/index.js';
|
|
3
|
+
|
|
4
|
+
const FILE_PATHS: Record<SlashCommandId, string> = {
|
|
5
|
+
enhance: '.forge/commands/prompter/enhance.md',
|
|
6
|
+
'prd-generator': '.forge/commands/prompter/prd-generator.md',
|
|
7
|
+
'prd-agent-generator': '.forge/commands/prompter/prd-agent-generator.md',
|
|
8
|
+
'product-brief': '.forge/commands/prompter/product-brief.md',
|
|
9
|
+
'epic-single': '.forge/commands/prompter/epic-single.md',
|
|
10
|
+
'epic-generator': '.forge/commands/prompter/epic-generator.md',
|
|
11
|
+
'story-single': '.forge/commands/prompter/story-single.md',
|
|
12
|
+
'story-generator': '.forge/commands/prompter/story-generator.md',
|
|
13
|
+
'qa-test-scenario': '.forge/commands/prompter/qa-test-scenario.md',
|
|
14
|
+
'skill-creator': '.forge/commands/prompter/skill-creator.md',
|
|
15
|
+
'ai-humanizer': '.forge/commands/prompter/ai-humanizer.md',
|
|
16
|
+
'api-contract-generator': '.forge/commands/prompter/api-contract-generator.md',
|
|
17
|
+
'apply': '.forge/commands/prompter/apply.md',
|
|
18
|
+
'archive': '.forge/commands/prompter/archive.md',
|
|
19
|
+
'design-system': '.forge/commands/prompter/design-system.md',
|
|
20
|
+
'erd-generator': '.forge/commands/prompter/erd-generator.md',
|
|
21
|
+
'fsd-generator': '.forge/commands/prompter/fsd-generator.md',
|
|
22
|
+
'proposal': '.forge/commands/prompter/proposal.md',
|
|
23
|
+
'tdd-generator': '.forge/commands/prompter/tdd-generator.md',
|
|
24
|
+
'tdd-lite-generator': '.forge/commands/prompter/tdd-lite-generator.md',
|
|
25
|
+
'wireframe-generator': '.forge/commands/prompter/wireframe-generator.md',
|
|
26
|
+
'document-explainer': '.forge/commands/prompter/document-explainer.md'
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export class ForgeConfigurator extends SlashCommandConfigurator {
|
|
30
|
+
readonly toolId = 'forge';
|
|
31
|
+
readonly isAvailable = true;
|
|
32
|
+
|
|
33
|
+
protected getRelativePath(id: SlashCommandId): string {
|
|
34
|
+
return FILE_PATHS[id];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
protected getFrontmatter(id: SlashCommandId): string | undefined {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -6,3 +6,5 @@ export { CodexConfigurator } from './codex.js';
|
|
|
6
6
|
export { GithubCopilotConfigurator } from './github-copilot.js';
|
|
7
7
|
export { OpenCodeConfigurator } from './opencode.js';
|
|
8
8
|
export { KiloCodeConfigurator } from './kilocode.js';
|
|
9
|
+
export { ForgeConfigurator } from './forge.js';
|
|
10
|
+
export { DroidConfigurator } from './droid.js';
|
|
@@ -5,6 +5,8 @@ import { CodexConfigurator } from './codex.js';
|
|
|
5
5
|
import { GithubCopilotConfigurator } from './github-copilot.js';
|
|
6
6
|
import { OpenCodeConfigurator } from './opencode.js';
|
|
7
7
|
import { KiloCodeConfigurator } from './kilocode.js';
|
|
8
|
+
import { ForgeConfigurator } from './forge.js';
|
|
9
|
+
import { DroidConfigurator } from './droid.js';
|
|
8
10
|
|
|
9
11
|
export class ConfiguratorRegistry {
|
|
10
12
|
private configurators: Map<string, SlashCommandConfigurator> = new Map();
|
|
@@ -16,6 +18,8 @@ export class ConfiguratorRegistry {
|
|
|
16
18
|
const githubCopilot = new GithubCopilotConfigurator();
|
|
17
19
|
const opencode = new OpenCodeConfigurator();
|
|
18
20
|
const kilocode = new KiloCodeConfigurator();
|
|
21
|
+
const forge = new ForgeConfigurator();
|
|
22
|
+
const droid = new DroidConfigurator();
|
|
19
23
|
|
|
20
24
|
this.configurators.set(antigravity.toolId, antigravity);
|
|
21
25
|
this.configurators.set(claude.toolId, claude);
|
|
@@ -23,6 +27,8 @@ export class ConfiguratorRegistry {
|
|
|
23
27
|
this.configurators.set(githubCopilot.toolId, githubCopilot);
|
|
24
28
|
this.configurators.set(opencode.toolId, opencode);
|
|
25
29
|
this.configurators.set(kilocode.toolId, kilocode);
|
|
30
|
+
this.configurators.set(forge.toolId, forge);
|
|
31
|
+
this.configurators.set(droid.toolId, droid);
|
|
26
32
|
}
|
|
27
33
|
|
|
28
34
|
get(toolId: string): SlashCommandConfigurator | undefined {
|