@popoverai/dotrequirements 0.24.2 → 0.24.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. package/README.md +0 -1
  2. package/dist/codebase-to-spec/cache.d.ts +6 -0
  3. package/dist/codebase-to-spec/cache.js +1 -0
  4. package/dist/codebase-to-spec/dispatch.d.ts +69 -0
  5. package/dist/codebase-to-spec/dispatch.js +484 -0
  6. package/dist/codebase-to-spec/schemas.d.ts +375 -0
  7. package/dist/codebase-to-spec/schemas.js +133 -0
  8. package/dist/codebase-to-spec/skill-install.d.ts +36 -12
  9. package/dist/codebase-to-spec/skill-install.js +127 -26
  10. package/dist/commands/codebase-to-spec/compose-orchestrator.d.ts +14 -0
  11. package/dist/commands/codebase-to-spec/compose-orchestrator.js +54 -0
  12. package/dist/commands/codebase-to-spec/dispatch-context.d.ts +12 -0
  13. package/dist/commands/codebase-to-spec/dispatch-context.js +22 -0
  14. package/dist/commands/codebase-to-spec/dispatch-editor.d.ts +16 -0
  15. package/dist/commands/codebase-to-spec/dispatch-editor.js +71 -0
  16. package/dist/commands/codebase-to-spec/dispatch-planner.d.ts +19 -0
  17. package/dist/commands/codebase-to-spec/dispatch-planner.js +90 -0
  18. package/dist/commands/codebase-to-spec/dispatch-spec.d.ts +16 -0
  19. package/dist/commands/codebase-to-spec/dispatch-spec.js +59 -0
  20. package/dist/commands/codebase-to-spec/index.js +56 -1
  21. package/dist/commands/codebase-to-spec/present-orchestrator.d.ts +20 -0
  22. package/dist/commands/codebase-to-spec/present-orchestrator.js +81 -0
  23. package/dist/commands/codebase-to-spec/skill-install.js +12 -1
  24. package/dist/templates/agents/cts-worker.md +9 -0
  25. package/dist/templates/hooks/cts-worker-persona.sh +76 -0
  26. package/dist/templates/skills/codebase-to-spec/SKILL.md +159 -68
  27. package/package.json +1 -1
@@ -337,5 +337,380 @@ export declare const SPEC_REVIEW_JSON_SCHEMA: {
337
337
  readonly required: readonly ["coverage_gaps", "framing_errors", "cross_area_issues", "internal_mechanics_drift", "revisions", "verdict"];
338
338
  readonly additionalProperties: false;
339
339
  };
340
+ export declare const ConversationalCustomerSchema: z.ZodObject<{
341
+ description: z.ZodString;
342
+ }, "strip", z.ZodTypeAny, {
343
+ description: string;
344
+ }, {
345
+ description: string;
346
+ }>;
347
+ export type ConversationalCustomer = z.infer<typeof ConversationalCustomerSchema>;
348
+ /**
349
+ * One entry in the review thread (project-level or per-area). Discriminated
350
+ * on `result`:
351
+ *
352
+ * - `approved`: no revisions required.
353
+ * - `needs-revision`: must include a non-empty `revisions` list — each
354
+ * entry is a clear, actionable instruction for the next planner pass.
355
+ */
356
+ export declare const ConversationalReviewEntrySchema: z.ZodDiscriminatedUnion<"result", [z.ZodObject<{
357
+ result: z.ZodLiteral<"approved">;
358
+ }, "strip", z.ZodTypeAny, {
359
+ result: "approved";
360
+ }, {
361
+ result: "approved";
362
+ }>, z.ZodObject<{
363
+ result: z.ZodLiteral<"needs-revision">;
364
+ revisions: z.ZodArray<z.ZodString, "many">;
365
+ }, "strip", z.ZodTypeAny, {
366
+ revisions: string[];
367
+ result: "needs-revision";
368
+ }, {
369
+ revisions: string[];
370
+ result: "needs-revision";
371
+ }>]>;
372
+ export type ConversationalReviewEntry = z.infer<typeof ConversationalReviewEntrySchema>;
373
+ /**
374
+ * Review state. Used both at the project level (outline.review) and per
375
+ * area (area.review). `result` mirrors the latest thread entry's result
376
+ * so callers can query state without walking the thread.
377
+ */
378
+ export declare const ConversationalReviewSchema: z.ZodObject<{
379
+ result: z.ZodEnum<["approved", "needs-revision"]>;
380
+ thread: z.ZodArray<z.ZodDiscriminatedUnion<"result", [z.ZodObject<{
381
+ result: z.ZodLiteral<"approved">;
382
+ }, "strip", z.ZodTypeAny, {
383
+ result: "approved";
384
+ }, {
385
+ result: "approved";
386
+ }>, z.ZodObject<{
387
+ result: z.ZodLiteral<"needs-revision">;
388
+ revisions: z.ZodArray<z.ZodString, "many">;
389
+ }, "strip", z.ZodTypeAny, {
390
+ revisions: string[];
391
+ result: "needs-revision";
392
+ }, {
393
+ revisions: string[];
394
+ result: "needs-revision";
395
+ }>]>, "many">;
396
+ }, "strip", z.ZodTypeAny, {
397
+ result: "approved" | "needs-revision";
398
+ thread: ({
399
+ result: "approved";
400
+ } | {
401
+ revisions: string[];
402
+ result: "needs-revision";
403
+ })[];
404
+ }, {
405
+ result: "approved" | "needs-revision";
406
+ thread: ({
407
+ result: "approved";
408
+ } | {
409
+ revisions: string[];
410
+ result: "needs-revision";
411
+ })[];
412
+ }>;
413
+ export type ConversationalReview = z.infer<typeof ConversationalReviewSchema>;
414
+ export declare const ConversationalAreaSchema: z.ZodObject<{
415
+ name: z.ZodString;
416
+ prefix: z.ZodString;
417
+ description: z.ZodString;
418
+ source_files: z.ZodArray<z.ZodString, "many">;
419
+ customers: z.ZodArray<z.ZodObject<{
420
+ description: z.ZodString;
421
+ }, "strip", z.ZodTypeAny, {
422
+ description: string;
423
+ }, {
424
+ description: string;
425
+ }>, "many">;
426
+ /**
427
+ * Per-area review state — same shape as the project-level review.
428
+ * Optional: planner output doesn't include it; CA adds it after reviewing
429
+ * a partial. Tracks the per-area iteration loop (specify → review →
430
+ * editor → re-review → approved) the same way `outline.review` tracks
431
+ * the outline iteration loop.
432
+ */
433
+ review: z.ZodOptional<z.ZodObject<{
434
+ result: z.ZodEnum<["approved", "needs-revision"]>;
435
+ thread: z.ZodArray<z.ZodDiscriminatedUnion<"result", [z.ZodObject<{
436
+ result: z.ZodLiteral<"approved">;
437
+ }, "strip", z.ZodTypeAny, {
438
+ result: "approved";
439
+ }, {
440
+ result: "approved";
441
+ }>, z.ZodObject<{
442
+ result: z.ZodLiteral<"needs-revision">;
443
+ revisions: z.ZodArray<z.ZodString, "many">;
444
+ }, "strip", z.ZodTypeAny, {
445
+ revisions: string[];
446
+ result: "needs-revision";
447
+ }, {
448
+ revisions: string[];
449
+ result: "needs-revision";
450
+ }>]>, "many">;
451
+ }, "strip", z.ZodTypeAny, {
452
+ result: "approved" | "needs-revision";
453
+ thread: ({
454
+ result: "approved";
455
+ } | {
456
+ revisions: string[];
457
+ result: "needs-revision";
458
+ })[];
459
+ }, {
460
+ result: "approved" | "needs-revision";
461
+ thread: ({
462
+ result: "approved";
463
+ } | {
464
+ revisions: string[];
465
+ result: "needs-revision";
466
+ })[];
467
+ }>>;
468
+ }, "strip", z.ZodTypeAny, {
469
+ prefix: string;
470
+ name: string;
471
+ description: string;
472
+ customers: {
473
+ description: string;
474
+ }[];
475
+ source_files: string[];
476
+ review?: {
477
+ result: "approved" | "needs-revision";
478
+ thread: ({
479
+ result: "approved";
480
+ } | {
481
+ revisions: string[];
482
+ result: "needs-revision";
483
+ })[];
484
+ } | undefined;
485
+ }, {
486
+ prefix: string;
487
+ name: string;
488
+ description: string;
489
+ customers: {
490
+ description: string;
491
+ }[];
492
+ source_files: string[];
493
+ review?: {
494
+ result: "approved" | "needs-revision";
495
+ thread: ({
496
+ result: "approved";
497
+ } | {
498
+ revisions: string[];
499
+ result: "needs-revision";
500
+ })[];
501
+ } | undefined;
502
+ }>;
503
+ export type ConversationalArea = z.infer<typeof ConversationalAreaSchema>;
504
+ export declare const ConversationalOutlineSchema: z.ZodObject<{
505
+ title: z.ZodString;
506
+ defaultPrefix: z.ZodString;
507
+ summary: z.ZodString;
508
+ review: z.ZodOptional<z.ZodObject<{
509
+ result: z.ZodEnum<["approved", "needs-revision"]>;
510
+ thread: z.ZodArray<z.ZodDiscriminatedUnion<"result", [z.ZodObject<{
511
+ result: z.ZodLiteral<"approved">;
512
+ }, "strip", z.ZodTypeAny, {
513
+ result: "approved";
514
+ }, {
515
+ result: "approved";
516
+ }>, z.ZodObject<{
517
+ result: z.ZodLiteral<"needs-revision">;
518
+ revisions: z.ZodArray<z.ZodString, "many">;
519
+ }, "strip", z.ZodTypeAny, {
520
+ revisions: string[];
521
+ result: "needs-revision";
522
+ }, {
523
+ revisions: string[];
524
+ result: "needs-revision";
525
+ }>]>, "many">;
526
+ }, "strip", z.ZodTypeAny, {
527
+ result: "approved" | "needs-revision";
528
+ thread: ({
529
+ result: "approved";
530
+ } | {
531
+ revisions: string[];
532
+ result: "needs-revision";
533
+ })[];
534
+ }, {
535
+ result: "approved" | "needs-revision";
536
+ thread: ({
537
+ result: "approved";
538
+ } | {
539
+ revisions: string[];
540
+ result: "needs-revision";
541
+ })[];
542
+ }>>;
543
+ areas: z.ZodArray<z.ZodObject<{
544
+ name: z.ZodString;
545
+ prefix: z.ZodString;
546
+ description: z.ZodString;
547
+ source_files: z.ZodArray<z.ZodString, "many">;
548
+ customers: z.ZodArray<z.ZodObject<{
549
+ description: z.ZodString;
550
+ }, "strip", z.ZodTypeAny, {
551
+ description: string;
552
+ }, {
553
+ description: string;
554
+ }>, "many">;
555
+ /**
556
+ * Per-area review state — same shape as the project-level review.
557
+ * Optional: planner output doesn't include it; CA adds it after reviewing
558
+ * a partial. Tracks the per-area iteration loop (specify → review →
559
+ * editor → re-review → approved) the same way `outline.review` tracks
560
+ * the outline iteration loop.
561
+ */
562
+ review: z.ZodOptional<z.ZodObject<{
563
+ result: z.ZodEnum<["approved", "needs-revision"]>;
564
+ thread: z.ZodArray<z.ZodDiscriminatedUnion<"result", [z.ZodObject<{
565
+ result: z.ZodLiteral<"approved">;
566
+ }, "strip", z.ZodTypeAny, {
567
+ result: "approved";
568
+ }, {
569
+ result: "approved";
570
+ }>, z.ZodObject<{
571
+ result: z.ZodLiteral<"needs-revision">;
572
+ revisions: z.ZodArray<z.ZodString, "many">;
573
+ }, "strip", z.ZodTypeAny, {
574
+ revisions: string[];
575
+ result: "needs-revision";
576
+ }, {
577
+ revisions: string[];
578
+ result: "needs-revision";
579
+ }>]>, "many">;
580
+ }, "strip", z.ZodTypeAny, {
581
+ result: "approved" | "needs-revision";
582
+ thread: ({
583
+ result: "approved";
584
+ } | {
585
+ revisions: string[];
586
+ result: "needs-revision";
587
+ })[];
588
+ }, {
589
+ result: "approved" | "needs-revision";
590
+ thread: ({
591
+ result: "approved";
592
+ } | {
593
+ revisions: string[];
594
+ result: "needs-revision";
595
+ })[];
596
+ }>>;
597
+ }, "strip", z.ZodTypeAny, {
598
+ prefix: string;
599
+ name: string;
600
+ description: string;
601
+ customers: {
602
+ description: string;
603
+ }[];
604
+ source_files: string[];
605
+ review?: {
606
+ result: "approved" | "needs-revision";
607
+ thread: ({
608
+ result: "approved";
609
+ } | {
610
+ revisions: string[];
611
+ result: "needs-revision";
612
+ })[];
613
+ } | undefined;
614
+ }, {
615
+ prefix: string;
616
+ name: string;
617
+ description: string;
618
+ customers: {
619
+ description: string;
620
+ }[];
621
+ source_files: string[];
622
+ review?: {
623
+ result: "approved" | "needs-revision";
624
+ thread: ({
625
+ result: "approved";
626
+ } | {
627
+ revisions: string[];
628
+ result: "needs-revision";
629
+ })[];
630
+ } | undefined;
631
+ }>, "many">;
632
+ }, "strip", z.ZodTypeAny, {
633
+ title: string;
634
+ defaultPrefix: string;
635
+ summary: string;
636
+ areas: {
637
+ prefix: string;
638
+ name: string;
639
+ description: string;
640
+ customers: {
641
+ description: string;
642
+ }[];
643
+ source_files: string[];
644
+ review?: {
645
+ result: "approved" | "needs-revision";
646
+ thread: ({
647
+ result: "approved";
648
+ } | {
649
+ revisions: string[];
650
+ result: "needs-revision";
651
+ })[];
652
+ } | undefined;
653
+ }[];
654
+ review?: {
655
+ result: "approved" | "needs-revision";
656
+ thread: ({
657
+ result: "approved";
658
+ } | {
659
+ revisions: string[];
660
+ result: "needs-revision";
661
+ })[];
662
+ } | undefined;
663
+ }, {
664
+ title: string;
665
+ defaultPrefix: string;
666
+ summary: string;
667
+ areas: {
668
+ prefix: string;
669
+ name: string;
670
+ description: string;
671
+ customers: {
672
+ description: string;
673
+ }[];
674
+ source_files: string[];
675
+ review?: {
676
+ result: "approved" | "needs-revision";
677
+ thread: ({
678
+ result: "approved";
679
+ } | {
680
+ revisions: string[];
681
+ result: "needs-revision";
682
+ })[];
683
+ } | undefined;
684
+ }[];
685
+ review?: {
686
+ result: "approved" | "needs-revision";
687
+ thread: ({
688
+ result: "approved";
689
+ } | {
690
+ revisions: string[];
691
+ result: "needs-revision";
692
+ })[];
693
+ } | undefined;
694
+ }>;
695
+ export type ConversationalOutline = z.infer<typeof ConversationalOutlineSchema>;
696
+ /**
697
+ * Parse YAML text against the conversational outline schema. Throws with
698
+ * a descriptive message on parse or validation failure.
699
+ */
700
+ export declare function parseConversationalOutline(text: string): ConversationalOutline;
701
+ /**
702
+ * Adapt a conversational orchestrator outline to the legacy Outline shape
703
+ * for use with stages that still take the legacy schema (compose, present).
704
+ *
705
+ * Discards orchestrator-only fields (review); maps `source_files` → `files`;
706
+ * bridges the customer-shape difference by synthesizing a `name` from each
707
+ * conversational customer's description.
708
+ */
709
+ export declare function conversationalOutlineToLegacy(outline: ConversationalOutline): Outline;
710
+ /**
711
+ * Serialize a conversational outline back to YAML text. Uses literal-block
712
+ * multi-line strings (`|`) where possible for readability.
713
+ */
714
+ export declare function stringifyConversationalOutline(outline: ConversationalOutline): string;
340
715
  export declare function parseSpecReview(text: string): SpecReview;
341
716
  //# sourceMappingURL=schemas.d.ts.map
@@ -189,6 +189,139 @@ export const SPEC_REVIEW_JSON_SCHEMA = {
189
189
  ],
190
190
  additionalProperties: false,
191
191
  };
192
+ // ---------- Conversational orchestrator outline (Phase 2b refactor) ----------
193
+ //
194
+ // The conversational orchestrator uses a single evolving `outline.yaml` as
195
+ // the pipeline's substrate. The outline carries both the behavioral spec
196
+ // content (areas, customers, source_files) AND its own lifecycle state
197
+ // (review.result + review.thread). This is distinct from the legacy
198
+ // `OutlineSchema` above, which the `cts run` pipeline still uses.
199
+ //
200
+ // Field naming uses "result" rather than "verdict" deliberately: review is
201
+ // a collaborative interaction with the worker, not a juridical ruling.
202
+ import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
203
+ export const ConversationalCustomerSchema = z.object({
204
+ description: z.string().min(1),
205
+ });
206
+ /**
207
+ * One entry in the review thread (project-level or per-area). Discriminated
208
+ * on `result`:
209
+ *
210
+ * - `approved`: no revisions required.
211
+ * - `needs-revision`: must include a non-empty `revisions` list — each
212
+ * entry is a clear, actionable instruction for the next planner pass.
213
+ */
214
+ export const ConversationalReviewEntrySchema = z.discriminatedUnion("result", [
215
+ z.object({
216
+ result: z.literal("approved"),
217
+ }),
218
+ z.object({
219
+ result: z.literal("needs-revision"),
220
+ revisions: z.array(z.string()).min(1),
221
+ }),
222
+ ]);
223
+ /**
224
+ * Review state. Used both at the project level (outline.review) and per
225
+ * area (area.review). `result` mirrors the latest thread entry's result
226
+ * so callers can query state without walking the thread.
227
+ */
228
+ export const ConversationalReviewSchema = z.object({
229
+ result: z.enum(["approved", "needs-revision"]),
230
+ thread: z.array(ConversationalReviewEntrySchema).min(1),
231
+ });
232
+ export const ConversationalAreaSchema = z.object({
233
+ name: z.string().min(1),
234
+ prefix: z
235
+ .string()
236
+ .regex(/^[A-Z][A-Z0-9_]*$/, "prefix must be uppercase alphanumeric/underscore"),
237
+ description: z.string().min(1),
238
+ source_files: z.array(z.string()).min(0),
239
+ customers: z.array(ConversationalCustomerSchema).min(1),
240
+ /**
241
+ * Per-area review state — same shape as the project-level review.
242
+ * Optional: planner output doesn't include it; CA adds it after reviewing
243
+ * a partial. Tracks the per-area iteration loop (specify → review →
244
+ * editor → re-review → approved) the same way `outline.review` tracks
245
+ * the outline iteration loop.
246
+ */
247
+ review: ConversationalReviewSchema.optional(),
248
+ });
249
+ export const ConversationalOutlineSchema = z.object({
250
+ title: z.string().min(1),
251
+ defaultPrefix: z
252
+ .string()
253
+ .regex(/^[A-Z][A-Z0-9_]*$/, "defaultPrefix must be uppercase alphanumeric/underscore"),
254
+ summary: z.string().min(1),
255
+ review: ConversationalReviewSchema.optional(),
256
+ areas: z.array(ConversationalAreaSchema).min(1),
257
+ });
258
+ /**
259
+ * Parse YAML text against the conversational outline schema. Throws with
260
+ * a descriptive message on parse or validation failure.
261
+ */
262
+ export function parseConversationalOutline(text) {
263
+ let raw;
264
+ try {
265
+ raw = parseYaml(text);
266
+ }
267
+ catch (err) {
268
+ throw new Error(`Outline YAML is invalid: ${err instanceof Error ? err.message : String(err)}`);
269
+ }
270
+ return ConversationalOutlineSchema.parse(raw);
271
+ }
272
+ /**
273
+ * Synthesize a short customer `name` from a conversational customer's
274
+ * `description`. The orchestrator's `ConversationalCustomerSchema` only
275
+ * carries description, but the legacy `CustomerSchema` requires both
276
+ * `name` and `description`. Adapter use only — downstream compose/present
277
+ * stages don't read `name`, so this is a schema-shape bridge, not a
278
+ * semantic field.
279
+ *
280
+ * Heuristic: descriptions like "Priya, a CTS pipeline operator" yield
281
+ * "Priya" via first comma-segment. Otherwise truncate to 40 chars.
282
+ */
283
+ function synthesizeCustomerName(description) {
284
+ const firstSegment = description.split(",")[0]?.trim() ?? "";
285
+ if (firstSegment.length > 0 && firstSegment.length <= 40) {
286
+ return firstSegment;
287
+ }
288
+ return description.slice(0, 40).trim() || description;
289
+ }
290
+ /**
291
+ * Adapt a conversational orchestrator outline to the legacy Outline shape
292
+ * for use with stages that still take the legacy schema (compose, present).
293
+ *
294
+ * Discards orchestrator-only fields (review); maps `source_files` → `files`;
295
+ * bridges the customer-shape difference by synthesizing a `name` from each
296
+ * conversational customer's description.
297
+ */
298
+ export function conversationalOutlineToLegacy(outline) {
299
+ return {
300
+ title: outline.title,
301
+ defaultPrefix: outline.defaultPrefix,
302
+ summary: outline.summary,
303
+ areas: outline.areas.map((a) => ({
304
+ name: a.name,
305
+ description: a.description,
306
+ prefix: a.prefix,
307
+ files: a.source_files,
308
+ customers: a.customers.map((c) => ({
309
+ name: synthesizeCustomerName(c.description),
310
+ description: c.description,
311
+ })),
312
+ })),
313
+ };
314
+ }
315
+ /**
316
+ * Serialize a conversational outline back to YAML text. Uses literal-block
317
+ * multi-line strings (`|`) where possible for readability.
318
+ */
319
+ export function stringifyConversationalOutline(outline) {
320
+ return stringifyYaml(outline, {
321
+ lineWidth: 0,
322
+ blockQuote: "literal",
323
+ });
324
+ }
192
325
  export function parseSpecReview(text) {
193
326
  const trimmed = text.trim();
194
327
  let raw;
@@ -1,34 +1,39 @@
1
1
  /**
2
2
  * Skill installation logic for the codebase-to-spec skill.
3
3
  *
4
- * The skill is a thin conversational wrapper around `dotrequirements cts run`.
5
- * It ships as a SKILL.md template bundled in the CLI package, and this module
6
- * copies it into the host's skill directory (default: `.claude/skills/` for
7
- * Claude Code).
4
+ * Ships as a bundle: SKILL.md + cts-worker agent definition + persona-
5
+ * injection hook script + hook registration in `.claude/settings.local.json`.
6
+ * The skill body (the conversational orchestrator) DEPENDS on the companion
7
+ * files — installing just the skill without them would leave Task dispatches
8
+ * unable to resolve their persona. For `project` scope, all four pieces are
9
+ * installed in one shot. For `global` and `custom` scopes, only the skill
10
+ * body is installed; the companions are project-scoped by CC convention.
8
11
  *
9
12
  * Host portability (CTS-SKILL-5): the install logic supports any host that
10
13
  * follows the Agent Skills format. The default target is Claude Code's
11
14
  * convention; `--target-dir` lets users place the skill anywhere.
12
15
  *
13
16
  * Requirements covered:
14
- * - CTS-SKILL-1: skill artifact exists and points users at `dotrequirements cts run`
15
- * - CTS-SKILL-5: install logic is host-agnostic and works on any host with
16
- * Agent Skills format support
17
+ * - CTS-SKILL-1, CTS-SKILL-5
18
+ * - CTSO-CLI-1 (bundles the agent + hook that PreToolUse-injects persona bodies)
17
19
  */
18
20
  export type SkillInstallScope = "project" | "global" | "custom";
19
21
  export interface SkillInstallOptions {
20
22
  /**
21
23
  * Where to install:
22
24
  * - `project` (default): `<projectRoot>/.claude/skills/codebase-to-spec/`
23
- * - `global`: `~/.claude/skills/codebase-to-spec/`
24
- * - `custom`: requires `targetDir`
25
+ * (plus companions under `<projectRoot>/.claude/agents/` and
26
+ * `<projectRoot>/.claude/hooks/`, and hook registration in
27
+ * `<projectRoot>/.claude/settings.local.json`)
28
+ * - `global`: `~/.claude/skills/codebase-to-spec/` (skill body only)
29
+ * - `custom`: requires `targetDir` (skill body only)
25
30
  */
26
31
  scope?: SkillInstallScope;
27
32
  /** Required when `scope === 'custom'`. The skill directory will be created here. */
28
33
  targetDir?: string;
29
34
  /** Project root (used when scope === 'project'). Defaults to cwd. */
30
35
  projectRoot?: string;
31
- /** Overwrite existing SKILL.md if present. Default false. */
36
+ /** Overwrite existing SKILL.md / agent / hook if present. Default false. */
32
37
  overwrite?: boolean;
33
38
  }
34
39
  export interface SkillInstallResult {
@@ -38,6 +43,13 @@ export interface SkillInstallResult {
38
43
  installed: boolean;
39
44
  /** True if an existing file was replaced. */
40
45
  overwrote: boolean;
46
+ /** Companion files installed alongside the skill (project scope only). */
47
+ companions?: {
48
+ agentPath: string;
49
+ hookScriptPath: string;
50
+ settingsPath: string;
51
+ hookRegistered: boolean;
52
+ };
41
53
  }
42
54
  /**
43
55
  * Resolve the directory in which the skill should live, given the user's
@@ -50,8 +62,20 @@ export declare function resolveSkillDir(options: SkillInstallOptions): string;
50
62
  */
51
63
  export declare function loadSkillTemplate(): string;
52
64
  /**
53
- * Install (or refuse to overwrite) the codebase-to-spec SKILL.md at the
54
- * resolved location.
65
+ * Load the bundled cts-worker agent definition template.
66
+ */
67
+ export declare function loadAgentTemplate(): string;
68
+ /**
69
+ * Load the bundled persona-injection hook script template.
70
+ */
71
+ export declare function loadHookTemplate(): string;
72
+ /**
73
+ * Install (or refuse to overwrite) the codebase-to-spec skill bundle.
74
+ *
75
+ * For `project` scope: installs skill body, cts-worker agent, persona hook
76
+ * script, and registers the hook in settings.local.json.
77
+ *
78
+ * For `global` and `custom` scopes: installs only the skill body.
55
79
  */
56
80
  export declare function installSkill(options?: SkillInstallOptions): SkillInstallResult;
57
81
  //# sourceMappingURL=skill-install.d.ts.map