halfcycle 0.4.13 → 0.4.14

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 (52) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/bin/bin.bundle.mjs +4105 -369
  3. package/bin/pre-tool-use-filter.sh +93 -1
  4. package/dist/bin.d.ts +1 -0
  5. package/dist/bin.d.ts.map +1 -1
  6. package/dist/bin.js +0 -0
  7. package/dist/build-record/pair-io.d.ts +49 -0
  8. package/dist/build-record/pair-io.d.ts.map +1 -0
  9. package/dist/build-record/render-change.d.ts +25 -0
  10. package/dist/build-record/render-change.d.ts.map +1 -0
  11. package/dist/build-record/render-v2.d.ts +10 -5
  12. package/dist/build-record/render-v2.d.ts.map +1 -1
  13. package/dist/build-record/write-change.d.ts +63 -0
  14. package/dist/build-record/write-change.d.ts.map +1 -0
  15. package/dist/build-record/write.d.ts +5 -15
  16. package/dist/build-record/write.d.ts.map +1 -1
  17. package/dist/change.d.ts +136 -0
  18. package/dist/change.d.ts.map +1 -0
  19. package/dist/check-tasks.d.ts +71 -0
  20. package/dist/check-tasks.d.ts.map +1 -0
  21. package/dist/claude-plan.d.ts +114 -0
  22. package/dist/claude-plan.d.ts.map +1 -0
  23. package/dist/cli-contract.d.ts +12 -1
  24. package/dist/cli-contract.d.ts.map +1 -1
  25. package/dist/cli.js +5192 -2132
  26. package/dist/cli.js.map +3 -3
  27. package/dist/close-phase.d.ts +53 -1
  28. package/dist/close-phase.d.ts.map +1 -1
  29. package/dist/index.js +1529 -911
  30. package/dist/index.js.map +3 -3
  31. package/dist/install-manifest.d.ts +11 -1
  32. package/dist/install-manifest.d.ts.map +1 -1
  33. package/dist/install.d.ts +58 -1
  34. package/dist/install.d.ts.map +1 -1
  35. package/dist/merge-settings.d.ts +21 -2
  36. package/dist/merge-settings.d.ts.map +1 -1
  37. package/dist/open-phase.d.ts +1 -1
  38. package/dist/open-phase.d.ts.map +1 -1
  39. package/dist/pace.d.ts +138 -0
  40. package/dist/pace.d.ts.map +1 -0
  41. package/dist/phase-work.d.ts +37 -0
  42. package/dist/phase-work.d.ts.map +1 -0
  43. package/dist/plan.d.ts +5 -2
  44. package/dist/plan.d.ts.map +1 -1
  45. package/dist/prove.d.ts +77 -0
  46. package/dist/prove.d.ts.map +1 -0
  47. package/dist/review.d.ts +19 -1
  48. package/dist/review.d.ts.map +1 -1
  49. package/dist/system-report.d.ts +1 -1
  50. package/dist/system-report.d.ts.map +1 -1
  51. package/dist/uninstall.d.ts.map +1 -1
  52. package/package.json +11 -11
@@ -0,0 +1,114 @@
1
+ /**
2
+ * SETUP ASKS THE CLAUDE PLAN ONCE (`builds-paced-to-plan` AC2, setup half).
3
+ *
4
+ * `bin.ts`'s setup arm calls `setupClaudePlan` after the project is created or found.
5
+ * In order:
6
+ *
7
+ * 1. NOBODY IS ASKED, AND NOTHING IS SENT, unless this account owns the project
8
+ * and a person is there (`isInteractiveRun`: a terminal on standard input and no
9
+ * `CI`). That one gate covers a script, CI, an agent running `npx halfcycle` from
10
+ * its own shell (no terminal on standard input) and a guest. A remembered answer
11
+ * is not sent either: the spec's "a setup with no person there sends nothing".
12
+ * 2. A COMPUTER THAT WAS TOLD BEFORE is not asked again: the remembered plan is
13
+ * sent, and, once control has taken it, the remembered line says so.
14
+ * 3. OTHERWISE the question is asked (`askLine`), the answer remembered on this
15
+ * computer and sent. An answer that names no plan is asked again, up to
16
+ * `PLAN_QUESTION_TRIES` times in all; after that nothing is remembered or sent,
17
+ * and the plan stays unknown until the owner sets it in the console.
18
+ *
19
+ * ONE HOME FOR EVERY WORD AND SHAPE, AND IT IS NOT HERE. The question, the answer's
20
+ * reading, the remembered line, the seven plans and the request body are
21
+ * `@halfcycle/events`' `pacing.ts`; the remembered file's shape IS the request body
22
+ * (`claudePlanRequestSchema`), so the file and the wire cannot drift apart. This
23
+ * module holds only the order above and the file and network I/O.
24
+ *
25
+ * THE CREDENTIAL IS THE MACHINE'S ACCOUNT CREDENTIAL, read the way the create route's
26
+ * is (`HALFCYCLE_TOKEN` in the environment first, else this machine's saved sign-in),
27
+ * and never a browser sign-in: the project is already set up, and a sign-in for a
28
+ * question about pacing would be out of all proportion. The engagement credential is
29
+ * never sent; control refuses it on this route. With no account credential the answer
30
+ * is still remembered, so the next setup sends it.
31
+ *
32
+ * BEST EFFORT, NEVER A FAILURE. The install has already succeeded when this runs. A
33
+ * network error, a timeout, a refusal (control not yet carrying the route, or a
34
+ * project this account does not own after all) or a file that cannot be written is
35
+ * silent: the remembered answer is re-sent by the next setup, and the owner can set
36
+ * the plan in the console. Nothing here throws.
37
+ *
38
+ * A REMEMBERED ANSWER IS RE-SENT ON EVERY LATER SETUP, as the spec says, so a plan the
39
+ * owner changed in the console is set back by their next `npx halfcycle` on this
40
+ * computer. That is the spec's rule, written down here so it is not mistaken for a
41
+ * defect of this module.
42
+ *
43
+ * INV-001: Node builtins, `@halfcycle/core`, `@halfcycle/events` and this package's
44
+ * own modules. Nothing about usage crosses (ADR-015): only the plan's id.
45
+ */
46
+ import { type ClaudePlanId } from '@halfcycle/events';
47
+ /** The remembered answer's file name, under `~/.halfcycle/`. Machine-level, never in a project (INV-016). */
48
+ export declare const CLAUDE_PLAN_FILENAME = "claude-plan.json";
49
+ /** How many times the question is put before an answer that names no plan is given up on. */
50
+ export declare const PLAN_QUESTION_TRIES = 3;
51
+ /** `~/.halfcycle/claude-plan.json`. */
52
+ export declare function claudePlanPath(home?: string): string;
53
+ /**
54
+ * The plan this computer was told before, or `undefined` when it was never told or
55
+ * the file does not read as one: a file that does not parse is asked about again and
56
+ * overwritten, never an error.
57
+ */
58
+ export declare function readRememberedClaudePlan(home?: string): ClaudePlanId | undefined;
59
+ /**
60
+ * Remember the plan on this computer, owner-only, the account store's posture
61
+ * (`account-credential.ts`). Returns false when it could not be written.
62
+ */
63
+ export declare function rememberClaudePlan(plan: ClaudePlanId, home?: string): boolean;
64
+ /**
65
+ * The owner's settings page, under the project's console address, or `undefined` when
66
+ * this run has no console address (an older control, or none configured). No address
67
+ * is guessed: `bin.ts` passes the same address it prints as the project's console.
68
+ */
69
+ export declare function settingsPageUrl(consoleUrl: string | undefined): string | undefined;
70
+ /**
71
+ * Send the plan to `PUT /engagements/:engagementId/claude-plan` with the account
72
+ * credential. True only when control took it (a 2xx). Never throws.
73
+ */
74
+ export declare function sendClaudePlan(serviceUrl: string, engagementId: string, credential: string, plan: ClaudePlanId, fetchImpl?: typeof fetch): Promise<boolean>;
75
+ /** What `setupClaudePlan` did, for the caller's tests; `bin.ts` reads none of it. */
76
+ export type ClaudePlanSetupOutcome = {
77
+ readonly kind: 'not-owner';
78
+ } | {
79
+ readonly kind: 'no-person';
80
+ } | {
81
+ readonly kind: 'no-answer';
82
+ } | {
83
+ readonly kind: 'failed';
84
+ } | {
85
+ readonly kind: 'remembered';
86
+ readonly plan: ClaudePlanId;
87
+ readonly sent: boolean;
88
+ } | {
89
+ readonly kind: 'answered';
90
+ readonly plan: ClaudePlanId;
91
+ readonly sent: boolean;
92
+ };
93
+ export interface ClaudePlanSetupInput {
94
+ readonly serviceUrl: string;
95
+ readonly engagementId: string;
96
+ /** True when this run's account owns the project; false for a guest, or when ownership is not known. */
97
+ readonly ownsProject: boolean;
98
+ /** The project's console address this run prints, if any; the settings page is under it. */
99
+ readonly consoleUrl: string | undefined;
100
+ }
101
+ export interface ClaudePlanSetupDeps {
102
+ readonly interactive: () => boolean;
103
+ readonly ask: (question: string) => Promise<string>;
104
+ readonly write: (text: string) => void;
105
+ readonly env?: NodeJS.ProcessEnv;
106
+ readonly home?: string;
107
+ readonly fetchImpl?: typeof fetch;
108
+ }
109
+ /**
110
+ * The setup arm's one call: ask the plan once, remember it, send it (module
111
+ * docblock). Never throws; the outcome is for tests.
112
+ */
113
+ export declare function setupClaudePlan(input: ClaudePlanSetupInput, deps: ClaudePlanSetupDeps): Promise<ClaudePlanSetupOutcome>;
114
+ //# sourceMappingURL=claude-plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-plan.d.ts","sourceRoot":"","sources":["../src/claude-plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAKH,OAAO,EAKL,KAAK,YAAY,EAClB,MAAM,mBAAmB,CAAC;AAG3B,6GAA6G;AAC7G,eAAO,MAAM,oBAAoB,qBAAqB,CAAC;AAEvD,6FAA6F;AAC7F,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAQrC,uCAAuC;AACvC,wBAAgB,cAAc,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAOhF;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAU7E;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAGlF;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,YAAY,EAClB,SAAS,GAAE,OAAO,KAAa,GAC9B,OAAO,CAAC,OAAO,CAAC,CAiBlB;AAED,qFAAqF;AACrF,MAAM,MAAM,sBAAsB,GAC9B;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;CAAE,GAC9B;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;CAAE,GAC9B;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;CAAE,GAC9B;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAC3B;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GACpF;IAAE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,CAAC;AAEvF,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,wGAAwG;IACxG,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,4FAA4F;IAC5F,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,WAAW,EAAE,MAAM,OAAO,CAAC;IACpC,QAAQ,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACpD,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACjC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CACnC;AASD;;;GAGG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,oBAAoB,EAC3B,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,sBAAsB,CAAC,CA+BjC"}
@@ -62,7 +62,7 @@
62
62
  * home is the failure mode it exists to prevent.
63
63
  */
64
64
  /** The verbs the CLI dispatches. Anything else after `halfcycle ` is unknown. */
65
- export declare const CLI_VERBS: readonly ["install", "check-drift", "build-record", "open-phase", "close-phase", "system", "draw", "plan", "review", "uninstall"];
65
+ export declare const CLI_VERBS: readonly ["install", "check-drift", "build-record", "open-phase", "close-phase", "system", "draw", "plan", "review", "check-tasks", "uninstall", "change", "pace", "prove"];
66
66
  export type CliVerb = (typeof CLI_VERBS)[number];
67
67
  /** A flag every invocation of the verb must carry. */
68
68
  export interface RequiredFlag {
@@ -85,10 +85,21 @@ export interface ConditionalFlag {
85
85
  readonly takesValue: boolean;
86
86
  readonly missingMessage: string;
87
87
  }
88
+ /**
89
+ * One form of a verb that has several, chosen by the first word after the verb
90
+ * (`change sort`, `change up`, `change done`). Each form declares its own required
91
+ * flags; the verb's own lists stay empty.
92
+ */
93
+ export interface FormContract {
94
+ readonly form: string;
95
+ readonly required: readonly RequiredFlag[];
96
+ readonly conditional: readonly ConditionalFlag[];
97
+ }
88
98
  export interface VerbContract {
89
99
  readonly verb: CliVerb;
90
100
  readonly required: readonly RequiredFlag[];
91
101
  readonly conditional: readonly ConditionalFlag[];
102
+ readonly forms?: readonly FormContract[];
92
103
  }
93
104
  /** The contract for a verb, or `undefined` when the CLI has no such verb. */
94
105
  export declare function contractFor(verb: string): VerbContract | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"cli-contract.d.ts","sourceRoot":"","sources":["../src/cli-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AAIH,iFAAiF;AACjF,eAAO,MAAM,SAAS,mIAAoI,CAAC;AAE3J,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjD,sDAAsD;AACtD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,2DAA2D;IAC3D,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,+EAA+E;IAC/E,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;IAC3C,QAAQ,CAAC,WAAW,EAAE,SAAS,eAAe,EAAE,CAAC;CAClD;AAiFD,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAElE;AAED,iDAAiD;AACjD,MAAM,WAAW,SAAS;IACxB,kEAAkE;IAClE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oCAAoC;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAmBD;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EAAE,CAyBxF;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMtE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAMvE;AASD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB;;CAErB,CAAC;AAyBX;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAa1F"}
1
+ {"version":3,"file":"cli-contract.d.ts","sourceRoot":"","sources":["../src/cli-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AAIH,iFAAiF;AACjF,eAAO,MAAM,SAAS,6KAA8K,CAAC;AAErM,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AAEjD,sDAAsD;AACtD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,2DAA2D;IAC3D,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,+EAA+E;IAC/E,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,iDAAiD;AACjD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;IAC3C,QAAQ,CAAC,WAAW,EAAE,SAAS,eAAe,EAAE,CAAC;CAClD;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,QAAQ,EAAE,SAAS,YAAY,EAAE,CAAC;IAC3C,QAAQ,CAAC,WAAW,EAAE,SAAS,eAAe,EAAE,CAAC;IACjD,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;CAC1C;AAqID,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAElE;AAED,iDAAiD;AACjD,MAAM,WAAW,SAAS;IACxB,kEAAkE;IAClE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,oCAAoC;IACpC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAmBD;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,EAAE,CAyBxF;AAuBD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMtE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAMvE;AASD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB;;CAErB,CAAC;AA0BX;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAa1F"}