@entelligentsia/forgecli 0.8.4 → 0.9.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 (169) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/dist/bin/argv.d.ts +2 -2
  3. package/dist/bin/argv.js +17 -0
  4. package/dist/bin/argv.js.map +1 -1
  5. package/dist/bin/config.d.ts +69 -0
  6. package/dist/bin/config.js +315 -0
  7. package/dist/bin/config.js.map +1 -0
  8. package/dist/bin/doctor.d.ts +1 -0
  9. package/dist/bin/doctor.js +12 -0
  10. package/dist/bin/doctor.js.map +1 -1
  11. package/dist/bin/forge.js +7 -0
  12. package/dist/bin/forge.js.map +1 -1
  13. package/dist/extensions/forgecli/config-command.d.ts +8 -0
  14. package/dist/extensions/forgecli/config-command.js +66 -0
  15. package/dist/extensions/forgecli/config-command.js.map +1 -0
  16. package/dist/extensions/forgecli/config-layer.d.ts +38 -0
  17. package/dist/extensions/forgecli/config-layer.js +68 -0
  18. package/dist/extensions/forgecli/config-layer.js.map +1 -0
  19. package/dist/extensions/forgecli/config-tui/component.d.ts +35 -0
  20. package/dist/extensions/forgecli/config-tui/component.js +236 -0
  21. package/dist/extensions/forgecli/config-tui/component.js.map +1 -0
  22. package/dist/extensions/forgecli/config-tui/handler.d.ts +40 -0
  23. package/dist/extensions/forgecli/config-tui/handler.js +240 -0
  24. package/dist/extensions/forgecli/config-tui/handler.js.map +1 -0
  25. package/dist/extensions/forgecli/config-tui/index.d.ts +5 -0
  26. package/dist/extensions/forgecli/config-tui/index.js +5 -0
  27. package/dist/extensions/forgecli/config-tui/index.js.map +1 -0
  28. package/dist/extensions/forgecli/config-tui/keys.d.ts +26 -0
  29. package/dist/extensions/forgecli/config-tui/keys.js +33 -0
  30. package/dist/extensions/forgecli/config-tui/keys.js.map +1 -0
  31. package/dist/extensions/forgecli/config-tui/plugin-config-reader.d.ts +23 -0
  32. package/dist/extensions/forgecli/config-tui/plugin-config-reader.js +58 -0
  33. package/dist/extensions/forgecli/config-tui/plugin-config-reader.js.map +1 -0
  34. package/dist/extensions/forgecli/config-tui/screens/advanced-menu.d.ts +7 -0
  35. package/dist/extensions/forgecli/config-tui/screens/advanced-menu.js +83 -0
  36. package/dist/extensions/forgecli/config-tui/screens/advanced-menu.js.map +1 -0
  37. package/dist/extensions/forgecli/config-tui/screens/confirm-quit.d.ts +11 -0
  38. package/dist/extensions/forgecli/config-tui/screens/confirm-quit.js +54 -0
  39. package/dist/extensions/forgecli/config-tui/screens/confirm-quit.js.map +1 -0
  40. package/dist/extensions/forgecli/config-tui/screens/override-editor.d.ts +11 -0
  41. package/dist/extensions/forgecli/config-tui/screens/override-editor.js +233 -0
  42. package/dist/extensions/forgecli/config-tui/screens/override-editor.js.map +1 -0
  43. package/dist/extensions/forgecli/config-tui/screens/overrides-list-phases.d.ts +7 -0
  44. package/dist/extensions/forgecli/config-tui/screens/overrides-list-phases.js +91 -0
  45. package/dist/extensions/forgecli/config-tui/screens/overrides-list-phases.js.map +1 -0
  46. package/dist/extensions/forgecli/config-tui/screens/overrides-list.d.ts +7 -0
  47. package/dist/extensions/forgecli/config-tui/screens/overrides-list.js +71 -0
  48. package/dist/extensions/forgecli/config-tui/screens/overrides-list.js.map +1 -0
  49. package/dist/extensions/forgecli/config-tui/screens/persona-editor.d.ts +10 -0
  50. package/dist/extensions/forgecli/config-tui/screens/persona-editor.js +182 -0
  51. package/dist/extensions/forgecli/config-tui/screens/persona-editor.js.map +1 -0
  52. package/dist/extensions/forgecli/config-tui/screens/persona-picker.d.ts +7 -0
  53. package/dist/extensions/forgecli/config-tui/screens/persona-picker.js +76 -0
  54. package/dist/extensions/forgecli/config-tui/screens/persona-picker.js.map +1 -0
  55. package/dist/extensions/forgecli/config-tui/screens/personas-list.d.ts +7 -0
  56. package/dist/extensions/forgecli/config-tui/screens/personas-list.js +98 -0
  57. package/dist/extensions/forgecli/config-tui/screens/personas-list.js.map +1 -0
  58. package/dist/extensions/forgecli/config-tui/screens/shared.d.ts +29 -0
  59. package/dist/extensions/forgecli/config-tui/screens/shared.js +100 -0
  60. package/dist/extensions/forgecli/config-tui/screens/shared.js.map +1 -0
  61. package/dist/extensions/forgecli/config-tui/screens/show-resolved.d.ts +23 -0
  62. package/dist/extensions/forgecli/config-tui/screens/show-resolved.js +128 -0
  63. package/dist/extensions/forgecli/config-tui/screens/show-resolved.js.map +1 -0
  64. package/dist/extensions/forgecli/config-tui/screens/tier-menu.d.ts +7 -0
  65. package/dist/extensions/forgecli/config-tui/screens/tier-menu.js +135 -0
  66. package/dist/extensions/forgecli/config-tui/screens/tier-menu.js.map +1 -0
  67. package/dist/extensions/forgecli/config-tui/screens/tier-picker.d.ts +9 -0
  68. package/dist/extensions/forgecli/config-tui/screens/tier-picker.js +122 -0
  69. package/dist/extensions/forgecli/config-tui/screens/tier-picker.js.map +1 -0
  70. package/dist/extensions/forgecli/config-tui/screens/types.d.ts +24 -0
  71. package/dist/extensions/forgecli/config-tui/screens/types.js +5 -0
  72. package/dist/extensions/forgecli/config-tui/screens/types.js.map +1 -0
  73. package/dist/extensions/forgecli/config-tui/screens.d.ts +24 -0
  74. package/dist/extensions/forgecli/config-tui/screens.js +78 -0
  75. package/dist/extensions/forgecli/config-tui/screens.js.map +1 -0
  76. package/dist/extensions/forgecli/config-tui/state/buffer.d.ts +11 -0
  77. package/dist/extensions/forgecli/config-tui/state/buffer.js +91 -0
  78. package/dist/extensions/forgecli/config-tui/state/buffer.js.map +1 -0
  79. package/dist/extensions/forgecli/config-tui/state/constants.d.ts +4 -0
  80. package/dist/extensions/forgecli/config-tui/state/constants.js +14 -0
  81. package/dist/extensions/forgecli/config-tui/state/constants.js.map +1 -0
  82. package/dist/extensions/forgecli/config-tui/state/index.d.ts +6 -0
  83. package/dist/extensions/forgecli/config-tui/state/index.js +9 -0
  84. package/dist/extensions/forgecli/config-tui/state/index.js.map +1 -0
  85. package/dist/extensions/forgecli/config-tui/state/init.d.ts +2 -0
  86. package/dist/extensions/forgecli/config-tui/state/init.js +30 -0
  87. package/dist/extensions/forgecli/config-tui/state/init.js.map +1 -0
  88. package/dist/extensions/forgecli/config-tui/state/model.d.ts +192 -0
  89. package/dist/extensions/forgecli/config-tui/state/model.js +4 -0
  90. package/dist/extensions/forgecli/config-tui/state/model.js.map +1 -0
  91. package/dist/extensions/forgecli/config-tui/state/reducer.d.ts +2 -0
  92. package/dist/extensions/forgecli/config-tui/state/reducer.js +212 -0
  93. package/dist/extensions/forgecli/config-tui/state/reducer.js.map +1 -0
  94. package/dist/extensions/forgecli/config-tui/state/selectors.d.ts +91 -0
  95. package/dist/extensions/forgecli/config-tui/state/selectors.js +231 -0
  96. package/dist/extensions/forgecli/config-tui/state/selectors.js.map +1 -0
  97. package/dist/extensions/forgecli/config-tui/state.d.ts +6 -0
  98. package/dist/extensions/forgecli/config-tui/state.js +11 -0
  99. package/dist/extensions/forgecli/config-tui/state.js.map +1 -0
  100. package/dist/extensions/forgecli/config-tui/theme.d.ts +37 -0
  101. package/dist/extensions/forgecli/config-tui/theme.js +88 -0
  102. package/dist/extensions/forgecli/config-tui/theme.js.map +1 -0
  103. package/dist/extensions/forgecli/config-tui/tier-meta.d.ts +28 -0
  104. package/dist/extensions/forgecli/config-tui/tier-meta.js +69 -0
  105. package/dist/extensions/forgecli/config-tui/tier-meta.js.map +1 -0
  106. package/dist/extensions/forgecli/config-writer.d.ts +16 -0
  107. package/dist/extensions/forgecli/config-writer.js +63 -0
  108. package/dist/extensions/forgecli/config-writer.js.map +1 -0
  109. package/dist/extensions/forgecli/fix-bug.js +85 -1
  110. package/dist/extensions/forgecli/fix-bug.js.map +1 -1
  111. package/dist/extensions/forgecli/forge-cli-schema.json +54 -0
  112. package/dist/extensions/forgecli/forge-commands.js +3 -8
  113. package/dist/extensions/forgecli/forge-commands.js.map +1 -1
  114. package/dist/extensions/forgecli/forge-subagent.d.ts +13 -0
  115. package/dist/extensions/forgecli/forge-subagent.js +19 -0
  116. package/dist/extensions/forgecli/forge-subagent.js.map +1 -1
  117. package/dist/extensions/forgecli/index.js +16 -0
  118. package/dist/extensions/forgecli/index.js.map +1 -1
  119. package/dist/extensions/forgecli/input-router.d.ts +33 -0
  120. package/dist/extensions/forgecli/input-router.js +133 -0
  121. package/dist/extensions/forgecli/input-router.js.map +1 -0
  122. package/dist/extensions/forgecli/model-resolver.d.ts +32 -0
  123. package/dist/extensions/forgecli/model-resolver.js +65 -0
  124. package/dist/extensions/forgecli/model-resolver.js.map +1 -0
  125. package/dist/extensions/forgecli/model-validator.d.ts +29 -0
  126. package/dist/extensions/forgecli/model-validator.js +107 -0
  127. package/dist/extensions/forgecli/model-validator.js.map +1 -0
  128. package/dist/extensions/forgecli/run-sprint.js +59 -0
  129. package/dist/extensions/forgecli/run-sprint.js.map +1 -1
  130. package/dist/extensions/forgecli/run-task.js +93 -1
  131. package/dist/extensions/forgecli/run-task.js.map +1 -1
  132. package/dist/extensions/forgecli/thread-switcher.js +5 -2
  133. package/dist/extensions/forgecli/thread-switcher.js.map +1 -1
  134. package/dist/extensions/forgecli/whats-new-widget.js +5 -2
  135. package/dist/extensions/forgecli/whats-new-widget.js.map +1 -1
  136. package/package.json +11 -3
  137. package/dist/extensions/forgecli/review-command.d.ts +0 -2
  138. package/dist/extensions/forgecli/review-command.js +0 -184
  139. package/dist/extensions/forgecli/review-command.js.map +0 -1
  140. package/dist/forge-payload/.tools/banners.cjs +0 -435
  141. package/dist/forge-payload/.tools/build-context-pack.cjs +0 -290
  142. package/dist/forge-payload/.tools/build-init-context.cjs +0 -322
  143. package/dist/forge-payload/.tools/build-overlay.cjs +0 -326
  144. package/dist/forge-payload/.tools/build-persona-pack.cjs +0 -226
  145. package/dist/forge-payload/.tools/collate.cjs +0 -1041
  146. package/dist/forge-payload/.tools/generation-manifest.cjs +0 -311
  147. package/dist/forge-payload/.tools/lib/forge-root.cjs +0 -59
  148. package/dist/forge-payload/.tools/lib/paths.cjs +0 -29
  149. package/dist/forge-payload/.tools/lib/pricing.cjs +0 -165
  150. package/dist/forge-payload/.tools/lib/project-root.cjs +0 -32
  151. package/dist/forge-payload/.tools/lib/result.js +0 -40
  152. package/dist/forge-payload/.tools/lib/store-facade.cjs +0 -162
  153. package/dist/forge-payload/.tools/lib/store-nlp.cjs +0 -250
  154. package/dist/forge-payload/.tools/lib/store-query-exec.cjs +0 -272
  155. package/dist/forge-payload/.tools/lib/validate.js +0 -141
  156. package/dist/forge-payload/.tools/manage-config.cjs +0 -340
  157. package/dist/forge-payload/.tools/manage-versions.cjs +0 -365
  158. package/dist/forge-payload/.tools/package.json +0 -3
  159. package/dist/forge-payload/.tools/parse-gates.cjs +0 -151
  160. package/dist/forge-payload/.tools/parse-verdict.cjs +0 -67
  161. package/dist/forge-payload/.tools/preflight-gate.cjs +0 -350
  162. package/dist/forge-payload/.tools/prompts/sprint-plan-prompt.md +0 -70
  163. package/dist/forge-payload/.tools/schemas/task-list.schema.json +0 -53
  164. package/dist/forge-payload/.tools/seed-store.cjs +0 -237
  165. package/dist/forge-payload/.tools/store-cli.cjs +0 -1226
  166. package/dist/forge-payload/.tools/store-query.cjs +0 -319
  167. package/dist/forge-payload/.tools/store.cjs +0 -315
  168. package/dist/forge-payload/.tools/substitute-placeholders.cjs +0 -625
  169. package/dist/forge-payload/.tools/validate-store.cjs +0 -593
@@ -0,0 +1,30 @@
1
+ // Config TUI state constructor — pure function, no I/O.
2
+ // Split from state.ts (Phase 1).
3
+ export function initialState(opts) {
4
+ const buffer = {
5
+ global: opts.global ? cloneJSON(opts.global) : {},
6
+ project: opts.project ? cloneJSON(opts.project) : {},
7
+ };
8
+ const firstView = { kind: "tier-menu", cursor: 0 };
9
+ // Default scope: project when in a project, global otherwise.
10
+ const scope = opts.pipelineCatalogue !== null ? "project" : "global";
11
+ return {
12
+ buffer,
13
+ view: [firstView],
14
+ cwd: opts.cwd,
15
+ personaCatalogue: opts.personaCatalogue,
16
+ pipelineCatalogue: opts.pipelineCatalogue,
17
+ availableModels: opts.availableModels,
18
+ authenticatedProviders: opts.authenticatedProviders,
19
+ dirty: false,
20
+ scope,
21
+ authError: opts.authError ?? null,
22
+ confirmQuit: false,
23
+ shouldExit: false,
24
+ lastSaved: null,
25
+ };
26
+ }
27
+ function cloneJSON(value) {
28
+ return JSON.parse(JSON.stringify(value));
29
+ }
30
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../../../src/extensions/forgecli/config-tui/state/init.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,iCAAiC;AAIjC,MAAM,UAAU,YAAY,CAAC,IAAiB;IAC5C,MAAM,MAAM,GAA6B;QACvC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;QACjD,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;KACrD,CAAC;IAEF,MAAM,SAAS,GACb,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;IAEnC,8DAA8D;IAC9D,MAAM,KAAK,GAA4B,IAAI,CAAC,iBAAiB,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;IAE9F,OAAO;QACL,MAAM;QACN,IAAI,EAAE,CAAC,SAAS,CAAC;QACjB,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;QACvC,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;QACzC,eAAe,EAAE,IAAI,CAAC,eAAe;QACrC,sBAAsB,EAAE,IAAI,CAAC,sBAAsB;QACnD,KAAK,EAAE,KAAK;QACZ,KAAK;QACL,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI;QACjC,WAAW,EAAE,KAAK;QAClB,UAAU,EAAE,KAAK;QACjB,SAAS,EAAE,IAAI;KAChB,CAAC;AACJ,CAAC;AAED,SAAS,SAAS,CAAI,KAAQ;IAC5B,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAM,CAAC;AAChD,CAAC"}
@@ -0,0 +1,192 @@
1
+ import type { GlobalConfig, PersonaModel, ProjectConfig } from "../../config-layer.js";
2
+ import type { Tier } from "../tier-meta.js";
3
+ export type PhaseOverride = string | PersonaModel;
4
+ export type ConfigLayer = "global" | "project";
5
+ export type View = {
6
+ kind: "tier-menu";
7
+ cursor: number;
8
+ } | {
9
+ kind: "tier-picker";
10
+ tier: Tier;
11
+ step: "pick-provider" | "pick-model";
12
+ provider: string | undefined;
13
+ cursor: number;
14
+ } | {
15
+ kind: "advanced-menu";
16
+ cursor: number;
17
+ } | {
18
+ kind: "personas-list";
19
+ cursor: number;
20
+ } | {
21
+ kind: "persona-picker";
22
+ cursor: number;
23
+ } | {
24
+ kind: "persona-editor";
25
+ persona: string;
26
+ step: "pick-provider" | "pick-model" | "pick-layer";
27
+ provider: string | undefined;
28
+ model: string | undefined;
29
+ /** Cursor index inside the active step's list (provider/model/layer). */
30
+ cursor: number;
31
+ } | {
32
+ kind: "show-resolved";
33
+ cursor: number;
34
+ } | {
35
+ kind: "overrides-list-pipelines";
36
+ cursor: number;
37
+ } | {
38
+ kind: "overrides-list-phases";
39
+ pipeline: string;
40
+ cursor: number;
41
+ } | {
42
+ kind: "override-editor";
43
+ pipeline: string;
44
+ phaseRole: string;
45
+ step: "pick-type" | "pick-name" | "pick-provider" | "pick-model";
46
+ /** For the inline path: chosen provider before the model picker. */
47
+ provider: string | undefined;
48
+ cursor: number;
49
+ };
50
+ export type TierAssignment = {
51
+ status: "set";
52
+ provider: string;
53
+ model: string;
54
+ layer: ConfigLayer;
55
+ } | {
56
+ status: "mixed";
57
+ } | {
58
+ status: "unset";
59
+ };
60
+ export interface ResolvedPersonaEntry {
61
+ persona: string;
62
+ provider: string;
63
+ model: string;
64
+ source: "L1" | "L2";
65
+ }
66
+ export interface PersonaPickerEntry {
67
+ persona: string;
68
+ assignment: ResolvedPersonaEntry | undefined;
69
+ inCatalogue: boolean;
70
+ }
71
+ export interface PipelineOverrideSummary {
72
+ pipeline: string;
73
+ overrideCount: number;
74
+ }
75
+ export interface ConfigBuffer {
76
+ global: GlobalConfig;
77
+ project: ProjectConfig;
78
+ }
79
+ export interface AvailableModel {
80
+ provider: string;
81
+ id: string;
82
+ }
83
+ export interface InitOptions {
84
+ global: GlobalConfig | null;
85
+ project: ProjectConfig | null;
86
+ cwd: string;
87
+ personaCatalogue: string[];
88
+ /** null when no `.forge/config.json` exists (forge-cli run outside a Forge project). */
89
+ pipelineCatalogue: string[] | null;
90
+ availableModels: AvailableModel[];
91
+ authenticatedProviders: string[];
92
+ /** If model discovery failed, surfaces the diagnostic instead of a silent empty list. */
93
+ authError?: string;
94
+ }
95
+ export interface ConfigTuiState {
96
+ buffer: ConfigBuffer;
97
+ view: View[];
98
+ cwd: string;
99
+ personaCatalogue: string[];
100
+ pipelineCatalogue: string[] | null;
101
+ availableModels: AvailableModel[];
102
+ authenticatedProviders: string[];
103
+ /** True iff buffer differs from the initial state (or from disk). */
104
+ dirty: boolean;
105
+ /** Active write scope for tier-level commits (toggled by `tab` on tier-menu). */
106
+ scope: ConfigLayer;
107
+ /** If model/auth discovery failed at init, a diagnostic string. */
108
+ authError: string | null;
109
+ /** Pending quit confirmation modal. */
110
+ confirmQuit: boolean;
111
+ /** True when the TUI should unmount. */
112
+ shouldExit: boolean;
113
+ /** Last save path + layer (auto-cleared after 3 seconds). */
114
+ lastSaved: {
115
+ target: string;
116
+ layer: ConfigLayer;
117
+ } | null;
118
+ }
119
+ export type ConfigTuiAction = {
120
+ kind: "select-tier";
121
+ tier: Tier;
122
+ } | {
123
+ kind: "set-tier-provider";
124
+ tier: Tier;
125
+ provider: string;
126
+ } | {
127
+ kind: "commit-tier-model";
128
+ tier: Tier;
129
+ provider: string;
130
+ model: string;
131
+ layer: ConfigLayer;
132
+ } | {
133
+ kind: "toggle-scope";
134
+ } | {
135
+ kind: "push-view";
136
+ view: View;
137
+ } | {
138
+ kind: "pop-view";
139
+ } | {
140
+ kind: "cursor-move";
141
+ delta: number;
142
+ } | {
143
+ kind: "begin-persona-edit";
144
+ persona: string;
145
+ } | {
146
+ kind: "set-persona-provider";
147
+ provider: string;
148
+ } | {
149
+ kind: "set-persona-model";
150
+ model: string;
151
+ } | {
152
+ kind: "commit-persona-edit";
153
+ layer: ConfigLayer;
154
+ } | {
155
+ kind: "delete-persona-entry";
156
+ layer: ConfigLayer;
157
+ persona: string;
158
+ } | {
159
+ kind: "begin-override-edit";
160
+ pipeline: string;
161
+ phaseRole: string;
162
+ } | {
163
+ kind: "set-override-step";
164
+ step: "pick-type" | "pick-name" | "pick-provider" | "pick-model";
165
+ } | {
166
+ kind: "set-override-provider";
167
+ provider: string;
168
+ } | {
169
+ kind: "commit-override-name";
170
+ name: string;
171
+ } | {
172
+ kind: "commit-override-inline";
173
+ provider: string;
174
+ model: string;
175
+ } | {
176
+ kind: "clear-phase-override";
177
+ pipeline: string;
178
+ phaseRole: string;
179
+ } | {
180
+ kind: "mark-clean";
181
+ lastSaved?: {
182
+ target: string;
183
+ layer: ConfigLayer;
184
+ };
185
+ } | {
186
+ kind: "clear-status";
187
+ } | {
188
+ kind: "request-quit";
189
+ } | {
190
+ kind: "confirm-quit";
191
+ discard: boolean;
192
+ };
@@ -0,0 +1,4 @@
1
+ // Config TUI type definitions — View, Action, State, Buffer shapes.
2
+ // Split from state.ts (Phase 1: file split, no behavior change).
3
+ export {};
4
+ //# sourceMappingURL=model.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model.js","sourceRoot":"","sources":["../../../../../src/extensions/forgecli/config-tui/state/model.ts"],"names":[],"mappings":"AAAA,oEAAoE;AACpE,iEAAiE"}
@@ -0,0 +1,2 @@
1
+ import type { ConfigTuiAction, ConfigTuiState } from "./model.js";
2
+ export declare function reducer(state: ConfigTuiState, action: ConfigTuiAction): ConfigTuiState;
@@ -0,0 +1,212 @@
1
+ // Config TUI reducer — pure (state, action) → state. No I/O.
2
+ // Split from state.ts (Phase 1).
3
+ import { writePersonaEntry, deletePersonaEntry, writePhaseOverride, clearPhaseOverride, writeTierAssignment } from "./buffer.js";
4
+ export function reducer(state, action) {
5
+ switch (action.kind) {
6
+ case "push-view":
7
+ return { ...state, view: [...state.view, action.view] };
8
+ case "pop-view":
9
+ if (state.view.length <= 1)
10
+ return state;
11
+ return { ...state, view: state.view.slice(0, -1) };
12
+ case "cursor-move": {
13
+ const top = state.view[state.view.length - 1];
14
+ // Every cursored view variant gets the same lower-bound clamp; the
15
+ // component clamps the upper bound based on per-view item counts.
16
+ if (top.kind === "tier-menu" ||
17
+ top.kind === "tier-picker" ||
18
+ top.kind === "advanced-menu" ||
19
+ top.kind === "personas-list" ||
20
+ top.kind === "persona-picker" ||
21
+ top.kind === "show-resolved" ||
22
+ top.kind === "persona-editor" ||
23
+ top.kind === "overrides-list-pipelines" ||
24
+ top.kind === "overrides-list-phases" ||
25
+ top.kind === "override-editor") {
26
+ const newCursor = Math.max(0, top.cursor + action.delta);
27
+ const replaced = { ...top, cursor: newCursor };
28
+ return { ...state, view: [...state.view.slice(0, -1), replaced] };
29
+ }
30
+ return state;
31
+ }
32
+ case "begin-persona-edit": {
33
+ const editor = {
34
+ kind: "persona-editor",
35
+ persona: action.persona,
36
+ step: "pick-provider",
37
+ provider: undefined,
38
+ model: undefined,
39
+ cursor: 0,
40
+ };
41
+ return { ...state, view: [...state.view, editor] };
42
+ }
43
+ case "set-persona-provider": {
44
+ const top = state.view[state.view.length - 1];
45
+ if (top.kind !== "persona-editor")
46
+ return state;
47
+ const updated = {
48
+ ...top,
49
+ provider: action.provider,
50
+ model: undefined,
51
+ step: "pick-model",
52
+ cursor: 0,
53
+ };
54
+ return { ...state, view: [...state.view.slice(0, -1), updated] };
55
+ }
56
+ case "set-persona-model": {
57
+ const top = state.view[state.view.length - 1];
58
+ if (top.kind !== "persona-editor")
59
+ return state;
60
+ const updated = {
61
+ ...top,
62
+ model: action.model,
63
+ step: "pick-layer",
64
+ cursor: 0,
65
+ };
66
+ return { ...state, view: [...state.view.slice(0, -1), updated] };
67
+ }
68
+ // ── Tiered-baseline actions (Phase A+) ───────────────────────────────────
69
+ case "select-tier": {
70
+ const tierPicker = {
71
+ kind: "tier-picker",
72
+ tier: action.tier,
73
+ step: "pick-provider",
74
+ provider: undefined,
75
+ cursor: 0,
76
+ };
77
+ return { ...state, view: [...state.view, tierPicker] };
78
+ }
79
+ case "set-tier-provider": {
80
+ const top = state.view[state.view.length - 1];
81
+ if (top.kind !== "tier-picker")
82
+ return state;
83
+ const updated = {
84
+ ...top,
85
+ provider: action.provider,
86
+ step: "pick-model",
87
+ cursor: 0,
88
+ };
89
+ return { ...state, view: [...state.view.slice(0, -1), updated] };
90
+ }
91
+ case "commit-tier-model": {
92
+ const entry = { provider: action.provider, model: action.model };
93
+ const buffer = writeTierAssignment(state.buffer, action.layer, action.tier, entry);
94
+ // Pop the tier-picker view, returning to tier-menu
95
+ const view = state.view.length > 1 ? state.view.slice(0, -1) : state.view;
96
+ return {
97
+ ...state,
98
+ buffer,
99
+ view,
100
+ dirty: true,
101
+ };
102
+ }
103
+ case "toggle-scope": {
104
+ const newScope = state.scope === "global" ? "project" : "global";
105
+ return { ...state, scope: newScope };
106
+ }
107
+ // ── Legacy actions ────────────────────────────────────────────────────────
108
+ case "commit-persona-edit": {
109
+ const top = state.view[state.view.length - 1];
110
+ if (top.kind !== "persona-editor")
111
+ return state;
112
+ if (!top.provider || !top.model)
113
+ return state;
114
+ const entry = { provider: top.provider, model: top.model };
115
+ const buffer = writePersonaEntry(state.buffer, action.layer, top.persona, entry);
116
+ return {
117
+ ...state,
118
+ buffer,
119
+ view: state.view.slice(0, -1),
120
+ dirty: true,
121
+ };
122
+ }
123
+ case "delete-persona-entry": {
124
+ const buffer = deletePersonaEntry(state.buffer, action.layer, action.persona);
125
+ const changed = buffer !== state.buffer;
126
+ return changed ? { ...state, buffer, dirty: true } : state;
127
+ }
128
+ case "begin-override-edit": {
129
+ const editor = {
130
+ kind: "override-editor",
131
+ pipeline: action.pipeline,
132
+ phaseRole: action.phaseRole,
133
+ step: "pick-type",
134
+ provider: undefined,
135
+ cursor: 0,
136
+ };
137
+ return { ...state, view: [...state.view, editor] };
138
+ }
139
+ case "set-override-step": {
140
+ const top = state.view[state.view.length - 1];
141
+ if (top.kind !== "override-editor")
142
+ return state;
143
+ const updated = { ...top, step: action.step, cursor: 0 };
144
+ return { ...state, view: [...state.view.slice(0, -1), updated] };
145
+ }
146
+ case "set-override-provider": {
147
+ const top = state.view[state.view.length - 1];
148
+ if (top.kind !== "override-editor")
149
+ return state;
150
+ const updated = {
151
+ ...top,
152
+ provider: action.provider,
153
+ step: "pick-model",
154
+ cursor: 0,
155
+ };
156
+ return { ...state, view: [...state.view.slice(0, -1), updated] };
157
+ }
158
+ case "commit-override-name": {
159
+ const top = state.view[state.view.length - 1];
160
+ if (top.kind !== "override-editor")
161
+ return state;
162
+ const buffer = writePhaseOverride(state.buffer, top.pipeline, top.phaseRole, action.name);
163
+ return {
164
+ ...state,
165
+ buffer,
166
+ view: state.view.slice(0, -1),
167
+ dirty: true,
168
+ };
169
+ }
170
+ case "commit-override-inline": {
171
+ const top = state.view[state.view.length - 1];
172
+ if (top.kind !== "override-editor")
173
+ return state;
174
+ const buffer = writePhaseOverride(state.buffer, top.pipeline, top.phaseRole, {
175
+ provider: action.provider,
176
+ model: action.model,
177
+ });
178
+ return {
179
+ ...state,
180
+ buffer,
181
+ view: state.view.slice(0, -1),
182
+ dirty: true,
183
+ };
184
+ }
185
+ case "clear-phase-override": {
186
+ const buffer = clearPhaseOverride(state.buffer, action.pipeline, action.phaseRole);
187
+ const changed = buffer !== state.buffer;
188
+ // If invoked from inside the override-editor, also pop back to the phases list.
189
+ const top = state.view[state.view.length - 1];
190
+ const view = changed && top.kind === "override-editor" ? state.view.slice(0, -1) : state.view;
191
+ return changed ? { ...state, buffer, dirty: true, view } : state;
192
+ }
193
+ case "mark-clean":
194
+ return { ...state, dirty: false, lastSaved: action.lastSaved ?? state.lastSaved };
195
+ case "clear-status":
196
+ return { ...state, lastSaved: null };
197
+ case "request-quit":
198
+ // If a confirm-quit modal is already open, another `q` is a no-op
199
+ // (user must press y/n/esc). This is what makes repeated `q` "tricky"
200
+ // — without this guard, every q re-fires the modal and looks broken.
201
+ if (state.confirmQuit)
202
+ return state;
203
+ if (!state.dirty)
204
+ return { ...state, shouldExit: true };
205
+ return { ...state, confirmQuit: true };
206
+ case "confirm-quit":
207
+ return { ...state, confirmQuit: false, shouldExit: action.discard };
208
+ default:
209
+ return state;
210
+ }
211
+ }
212
+ //# sourceMappingURL=reducer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reducer.js","sourceRoot":"","sources":["../../../../../src/extensions/forgecli/config-tui/state/reducer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,91 @@
1
+ import type { ConfigTuiState, View, ResolvedPersonaEntry, PersonaPickerEntry, PipelineOverrideSummary, PhaseOverride, TierAssignment } from "./model.js";
2
+ import type { ConfigLayer } from "../../config-writer.js";
3
+ import { type Tier } from "../tier-meta.js";
4
+ export declare function getActiveView(state: ConfigTuiState): View;
5
+ export declare function listResolvedPersonas(state: ConfigTuiState): ResolvedPersonaEntry[];
6
+ export declare function listPersonaPickerEntries(state: ConfigTuiState): PersonaPickerEntry[];
7
+ export declare function uniqueProviders(state: ConfigTuiState): string[];
8
+ export declare function listPipelineOverrideSummaries(state: ConfigTuiState): PipelineOverrideSummary[];
9
+ export declare function getPhaseOverride(state: ConfigTuiState, pipeline: string, phaseRole: string): PhaseOverride | undefined;
10
+ import { type ResolveSource } from "../../model-resolver.js";
11
+ /** A row in the phase table (Screen 3 — "Show what runs at each step"). */
12
+ export interface PhaseTableRow {
13
+ /** Phase role (e.g. "plan", "review-plan"). */
14
+ role: string;
15
+ /** Persona name (e.g. "engineer"). */
16
+ persona: string;
17
+ /** Persona emoji (e.g. "🌱"). */
18
+ personaEmoji: string;
19
+ /** Persona tier ("heavy" | "standard" | "light"). */
20
+ tier: Tier;
21
+ /** Resolved model string ("provider:model") or "(inherit pi current)". */
22
+ resolved: string;
23
+ /** Raw model resolver source ("L1", "L2", "L4-inline", etc.). */
24
+ rawSource: ResolveSource;
25
+ /** Human-readable source label (e.g. "Standard tier (global)"). */
26
+ sourceLabel: string;
27
+ }
28
+ /** Map a model-resolver source + persona tier + resolved-layer to a
29
+ * human-readable source label per the plan's cascade vocabulary.
30
+ *
31
+ * | Internal | Plain English |
32
+ * |-----------|---------------|
33
+ * | L4-inline / L4-name | "Step override" |
34
+ * | L3 | "Per-persona override (pipeline)" |
35
+ * | L2 | "{Tier} tier (project)" |
36
+ * | L1 | "{Tier} tier (global)" |
37
+ * | default | "Default fallback" |
38
+ * | inherit | "Falls back to pi current" |
39
+ */
40
+ export declare function sourceToLabel(rawSource: ResolveSource, tier: Tier | undefined, isProject: boolean): string;
41
+ /** Build the phase table for Screen 3.
42
+ * Joins PHASE_PERSONA_TABLE with model resolution results. */
43
+ export declare function getPhaseTable(state: ConfigTuiState): PhaseTableRow[];
44
+ /** Determine the effective model for an entire tier.
45
+ * Returns "set" when all personas in the tier resolve to the same model,
46
+ * "mixed" when some are missing or they diverge, "unset" when none are resolved. */
47
+ export declare function getTierAssignment(state: ConfigTuiState, tier: Tier): TierAssignment;
48
+ /** Return all three tier assignments as an array (stable order: heavy, standard, light). */
49
+ export declare function getAllTierAssignments(state: ConfigTuiState): Array<{
50
+ tier: Tier;
51
+ assignment: TierAssignment;
52
+ }>;
53
+ /** Scope-aware tier assignment: returns what's set at the given scope layer.
54
+ * When scope is "global", shows global-layer assignments only.
55
+ * When scope is "project", shows the resolved (merged) view since project
56
+ * layer is where overrides live on top of global.
57
+ * If a tier has no assignment at the active scope layer but has one at
58
+ * the other layer, shows { status: "set-in-other-layer" } with the details. */
59
+ export type ScopedTierAssignment = {
60
+ status: "set";
61
+ provider: string;
62
+ model: string;
63
+ layer: ConfigLayer;
64
+ } | {
65
+ status: "set-in-other-layer";
66
+ provider: string;
67
+ model: string;
68
+ otherLayer: ConfigLayer;
69
+ } | {
70
+ status: "mixed";
71
+ } | {
72
+ status: "unset";
73
+ };
74
+ export declare function getScopedTierAssignment(state: ConfigTuiState, tier: Tier, scope: ConfigLayer): ScopedTierAssignment;
75
+ export declare function getAllScopedTierAssignments(state: ConfigTuiState, scope: ConfigLayer): Array<{
76
+ tier: Tier;
77
+ assignment: ScopedTierAssignment;
78
+ }>;
79
+ /** Which tier does a persona belong to? Returns undefined for unknown names. */
80
+ export declare function getTierForPersona(persona: string): Tier | undefined;
81
+ /** Persona names in a tier. */
82
+ export declare function getPersonasInTier(tier: Tier): readonly string[];
83
+ /** True when neither global nor project config has any persona-model assignments.
84
+ * Replaces the old `state.isEmpty` snapshot — this is derived from buffer,
85
+ * so it stays correct after mutations. */
86
+ export declare function isConfigEmpty(state: ConfigTuiState): boolean;
87
+ /** Human-readable source label for a persona-model assignment.
88
+ * Replaces the old raw L1/L2/default-L1/default-L2 display.
89
+ * Uses tier labels when the persona has a known tier, otherwise falls back
90
+ * to generic "global"/"project" labels. */
91
+ export declare function personaSourceLabel(persona: string, source: "L1" | "L2"): string;