@goodbones/cli 0.1.0-beta.2 → 0.1.0-beta.20

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 (41) hide show
  1. package/build/dts/campaigns/host.d.ts +51 -0
  2. package/build/dts/campaigns/host.d.ts.map +1 -0
  3. package/build/dts/campaigns/live.d.ts +3 -0
  4. package/build/dts/campaigns/live.d.ts.map +1 -0
  5. package/build/dts/campaigns/none.d.ts +7 -0
  6. package/build/dts/campaigns/none.d.ts.map +1 -0
  7. package/build/dts/campaigns/verbs.d.ts +6 -0
  8. package/build/dts/campaigns/verbs.d.ts.map +1 -0
  9. package/build/dts/config-loader.d.ts +10 -3
  10. package/build/dts/config-loader.d.ts.map +1 -1
  11. package/build/dts/infer.d.ts +34 -0
  12. package/build/dts/infer.d.ts.map +1 -0
  13. package/build/dts/output.d.ts +9 -0
  14. package/build/dts/output.d.ts.map +1 -0
  15. package/build/dts/run.d.ts +67 -8
  16. package/build/dts/run.d.ts.map +1 -1
  17. package/build/esm/campaigns/host.js +2 -0
  18. package/build/esm/campaigns/host.js.map +1 -0
  19. package/build/esm/campaigns/live.js +106 -0
  20. package/build/esm/campaigns/live.js.map +1 -0
  21. package/build/esm/campaigns/none.js +34 -0
  22. package/build/esm/campaigns/none.js.map +1 -0
  23. package/build/esm/campaigns/verbs.js +489 -0
  24. package/build/esm/campaigns/verbs.js.map +1 -0
  25. package/build/esm/config-loader.js +66 -10
  26. package/build/esm/config-loader.js.map +1 -1
  27. package/build/esm/infer.js +378 -0
  28. package/build/esm/infer.js.map +1 -0
  29. package/build/esm/output.js +8 -0
  30. package/build/esm/output.js.map +1 -0
  31. package/build/esm/run.js +555 -78
  32. package/build/esm/run.js.map +1 -1
  33. package/package.json +19 -5
  34. package/src/campaigns/host.ts +120 -0
  35. package/src/campaigns/live.ts +136 -0
  36. package/src/campaigns/none.ts +47 -0
  37. package/src/campaigns/verbs.ts +620 -0
  38. package/src/config-loader.ts +81 -11
  39. package/src/infer.ts +511 -0
  40. package/src/output.ts +18 -0
  41. package/src/run.ts +870 -103
@@ -0,0 +1,489 @@
1
+ import { existsSync } from "node:fs";
2
+ import * as path from "node:path";
3
+ import { attest, authorOf, baseSideAt, campaignsOf, clear, concede, historyOf, note, nudgeOf, readDiff, renderCampaignRows, renderHistory, renderNudge, renderSectorView, sectorMovesOf, sectorViewOf, snapshotCampaignsOf, } from "@goodbones/campaigns";
4
+ import * as Effect from "effect/Effect";
5
+ import * as Result from "effect/Result";
6
+ import { count, fail, report } from "../output.js";
7
+ // The campaign commands. `campaigns` alone is the status table; `status
8
+ // --changed` is the nudge; `attest` and `note` write a sector's record;
9
+ // `history` replays the ledgers' git history. The ledgers themselves are
10
+ // written by `objectives clear` (the ledger reconciled with the code
11
+ // wherever that is not a regression) and `objectives concede` (the one way
12
+ // a holdout is added by hand, with a reason).
13
+ const flagOf = (argv, flag) => {
14
+ const at = argv.indexOf(flag);
15
+ const value = at === -1 ? undefined : argv[at + 1];
16
+ return value === undefined || value.startsWith("--") ? undefined : value;
17
+ };
18
+ const CAMPAIGN_SUBCOMMANDS = ["status", "attest", "note", "history", "clear", "concede"];
19
+ const OBJECTIVE_SUBCOMMANDS = ["clear", "concede"];
20
+ const VALUE_FLAGS = [
21
+ "--reason",
22
+ "--by",
23
+ "--holdouts",
24
+ "--entries",
25
+ "--sector",
26
+ "--campaign",
27
+ "--evidence",
28
+ "--base",
29
+ "--since",
30
+ "--hotfix",
31
+ ];
32
+ // The verbs the family shipped with, refused by name: each has a new name
33
+ // or no place.
34
+ const RETIRED = {
35
+ init: "`campaigns init` is gone: `objectives clear <campaign>` writes a first ledger, recording each sector's initial.",
36
+ prune: "`campaigns prune` is now `objectives clear`.",
37
+ allow: "`campaigns allow` is now `objectives concede`.",
38
+ };
39
+ // The positionals after the subcommand, with the value flags and their
40
+ // values stepped over: whatever is left names the roots to walk, as it
41
+ // does for every other command.
42
+ const positionalsOf = (argv) => {
43
+ const positional = [];
44
+ for (let at = 0; at < argv.length; at += 1) {
45
+ const one = argv[at] ?? "";
46
+ if (VALUE_FLAGS.includes(one)) {
47
+ at += 1;
48
+ continue;
49
+ }
50
+ if (!one.startsWith("--"))
51
+ positional.push(one);
52
+ }
53
+ return positional;
54
+ };
55
+ // `campaigns [status | attest <sector> <phase> | note <sector> "<text>" |
56
+ // history [<campaign>]] [roots…]`: the subcommand and its arguments come
57
+ // first.
58
+ const campaignArgsOf = (argv, ids) => {
59
+ const positional = positionalsOf(argv);
60
+ const [first, ...rest] = positional;
61
+ if (first === undefined)
62
+ return { subcommand: undefined, args: [], roots: [] };
63
+ if (first in RETIRED)
64
+ return { subcommand: first, args: [], roots: rest };
65
+ if (!CAMPAIGN_SUBCOMMANDS.includes(first)) {
66
+ return { subcommand: undefined, args: [], roots: positional };
67
+ }
68
+ switch (first) {
69
+ case "attest":
70
+ return { subcommand: first, args: rest.slice(0, 2), roots: rest.slice(2) };
71
+ case "note":
72
+ return { subcommand: first, args: rest.slice(0, 2), roots: rest.slice(2) };
73
+ case "history": {
74
+ const [second] = rest;
75
+ return second !== undefined && ids.includes(second)
76
+ ? { subcommand: first, args: [second], roots: rest.slice(1) }
77
+ : { subcommand: first, args: [], roots: rest };
78
+ }
79
+ case "clear":
80
+ case "concede": {
81
+ const [second] = rest;
82
+ return second !== undefined && ids.includes(second.split("/")[0] ?? "")
83
+ ? { subcommand: first, args: [second], roots: rest.slice(1) }
84
+ : { subcommand: first, args: [], roots: rest };
85
+ }
86
+ default:
87
+ return { subcommand: first, args: [], roots: rest };
88
+ }
89
+ };
90
+ // `objectives [clear [<campaign>[/<objective>]] | concede <campaign>[/<objective>]
91
+ // --reason <text>] [roots…]`.
92
+ const objectiveArgsOf = (argv, ids) => {
93
+ const positional = positionalsOf(argv);
94
+ const [first, second, ...rest] = positional;
95
+ if (first === undefined || !OBJECTIVE_SUBCOMMANDS.includes(first)) {
96
+ return { subcommand: first, target: null, roots: positional.slice(1) };
97
+ }
98
+ const [campaign = "", objective] = (second ?? "").split("/");
99
+ const named = second !== undefined && ids.includes(campaign);
100
+ return {
101
+ subcommand: first,
102
+ target: named ? { campaign, objective: objective ?? null } : null,
103
+ roots: named ? rest : second === undefined ? [] : [second, ...rest],
104
+ };
105
+ };
106
+ // The one campaign, when there is one, else the one `--campaign` names.
107
+ const campaignFor = (policy, argv) => {
108
+ const named = flagOf(argv, "--campaign");
109
+ if (named !== undefined) {
110
+ const found = campaignsOf(policy).campaignRules.find((rule) => rule.id === named);
111
+ return found === undefined
112
+ ? Result.fail(`no campaign is named "${named}"`)
113
+ : Result.succeed(found);
114
+ }
115
+ const [only] = campaignsOf(policy).campaignRules;
116
+ if (campaignsOf(policy).campaignRules.length === 1 && only !== undefined)
117
+ return Result.succeed(only);
118
+ return Result.fail(`this policy declares ${String(campaignsOf(policy).campaignRules.length)} campaigns; say which with --campaign <id>.`);
119
+ };
120
+ const objectiveFor = (rule, objective) => {
121
+ if (objective !== null) {
122
+ return rule.objectives.some((one) => one.id === objective)
123
+ ? Result.succeed(objective)
124
+ : Result.fail(`no objective of ${rule.id} is named "${objective}"`);
125
+ }
126
+ const [only] = rule.objectives;
127
+ if (rule.objectives.length === 1 && only !== undefined)
128
+ return Result.succeed(only.id);
129
+ return Result.fail(`campaign ${rule.id} declares ${String(rule.objectives.length)} objectives; say which as ${rule.id}/<objective>.`);
130
+ };
131
+ export const objectives = (context) => Effect.gen(function* () {
132
+ const { argv, defaultRoots, policy } = context;
133
+ const parsed = objectiveArgsOf(argv, campaignsOf(policy).campaignRules.map((rule) => rule.id));
134
+ const roots = parsed.roots.length > 0 ? parsed.roots : defaultRoots;
135
+ if (campaignsOf(policy).campaignRules.length === 0) {
136
+ return yield* report(["this policy declares no campaigns."]);
137
+ }
138
+ const evaluations = () => context.evaluate(roots);
139
+ switch (parsed.subcommand) {
140
+ case "clear": {
141
+ const targets = parsed.target === null
142
+ ? campaignsOf(policy).campaignRules
143
+ : campaignsOf(policy).campaignRules.filter((rule) => rule.id === parsed.target?.campaign);
144
+ const by = authorOf(flagOf(argv, "--by")) ?? "unknown";
145
+ const all = evaluations();
146
+ const lines = [];
147
+ for (const rule of targets) {
148
+ const evaluation = all.find((one) => one.rule.id === rule.id);
149
+ if (evaluation === undefined)
150
+ continue;
151
+ const only = parsed.target?.objective ?? null;
152
+ if (only !== null && !rule.objectives.some((one) => one.id === only)) {
153
+ return yield* Effect.fail(fail(`no objective of ${rule.id} is named "${only}"`));
154
+ }
155
+ const outcomes = yield* Effect.try({
156
+ try: () => clear(policy, evaluation, only, by),
157
+ catch: (cause) => fail(String(cause)),
158
+ });
159
+ // Where each sector went, read off the ledgers as they stood: a
160
+ // clear of one objective places no sector, so it says nothing.
161
+ const moves = only === null ? sectorMovesOf(policy, evaluation) : [];
162
+ for (const outcome of outcomes) {
163
+ const parts = [
164
+ ...(outcome.entered.length > 0
165
+ ? [
166
+ `${count(outcome.entered.length, "sector")} entered (${outcome.entered.join(", ")})`,
167
+ ]
168
+ : []),
169
+ ...(outcome.cleared > 0 ? [`${count(outcome.cleared, "holdout")} cleared`] : []),
170
+ ...(outcome.rewritten > 0
171
+ ? [`${count(outcome.rewritten, "holdout")} rewritten`]
172
+ : []),
173
+ ...(outcome.closed > 0 ? [`${count(outcome.closed, "holdout")} closed`] : []),
174
+ ...(outcome.rebaselined.length > 0
175
+ ? [
176
+ `${count(outcome.rebaselined.length, "sector")} re-baselined (${outcome.rebaselined.join(", ")})`,
177
+ ]
178
+ : []),
179
+ ];
180
+ if (outcome.measure !== undefined) {
181
+ const moved = [
182
+ ...(outcome.entered.length > 0
183
+ ? [
184
+ `${count(outcome.entered.length, "sector")} entered (${outcome.entered.join(", ")})`,
185
+ ]
186
+ : []),
187
+ ...(outcome.measure.improved.length > 0
188
+ ? [
189
+ `${count(outcome.measure.improved.length, "sector")} improved (${outcome.measure.improved
190
+ .map((one) => `${one.sector} ${String(one.from)} → ${String(one.to)}`)
191
+ .join(", ")})`,
192
+ ]
193
+ : []),
194
+ ...(outcome.measure.grown.length > 0
195
+ ? [
196
+ `${count(outcome.measure.grown.length, "sector")} grown (${outcome.measure.grown
197
+ .map((one) => `${one.sector} ${String(one.from)} → ${String(one.to)}, ${one.phase === null ? "measured, not held" : `as ${one.phase} expects`}`)
198
+ .join(", ")})`,
199
+ ]
200
+ : []),
201
+ ...(outcome.closed > 0 ? [`${count(outcome.closed, "sector")} closed`] : []),
202
+ ...(outcome.rebaselined.length > 0
203
+ ? [
204
+ `${count(outcome.rebaselined.length, "sector")} re-baselined (${outcome.rebaselined.join(", ")})`,
205
+ ]
206
+ : []),
207
+ ];
208
+ lines.push(`${outcome.campaign}/${outcome.objective}: ${moved.length === 0 ? "nothing to clear" : moved.join(", ")}; held to ${String(outcome.measure.recorded)}.`);
209
+ continue;
210
+ }
211
+ lines.push(`${outcome.campaign}/${outcome.objective}: ${parts.length === 0 ? "nothing to clear" : parts.join(", ")}; ${count(outcome.left, "holdout")} left.`);
212
+ }
213
+ for (const move of moves) {
214
+ lines.push(`${move.campaign}: ${move.sector} ${move.back ? "went back" : "moved"} ${move.from ?? "done"} → ${move.to ?? "done"}` +
215
+ (move.passed.length === 0
216
+ ? "."
217
+ : `, passing ${move.passed.join(", ")} in the same clear: nothing there was ever counted for it.`));
218
+ }
219
+ }
220
+ return yield* report(lines);
221
+ }
222
+ case "concede": {
223
+ if (parsed.target === null) {
224
+ return yield* Effect.fail(fail("objectives concede needs a campaign: `objectives concede <campaign>[/<objective>] --reason <text>`"));
225
+ }
226
+ const rule = campaignsOf(policy).campaignRules.find((one) => one.id === parsed.target?.campaign);
227
+ if (rule === undefined)
228
+ return yield* Effect.fail(fail(`no campaign is named "${parsed.target.campaign}"`));
229
+ const objective = objectiveFor(rule, parsed.target.objective);
230
+ if (Result.isFailure(objective))
231
+ return yield* Effect.fail(fail(objective.failure));
232
+ const reason = flagOf(argv, "--reason");
233
+ if (reason === undefined) {
234
+ return yield* Effect.fail(fail("objectives concede needs --reason <text>: growth is recorded with why, or not at all."));
235
+ }
236
+ const by = authorOf(flagOf(argv, "--by"));
237
+ if (by === null) {
238
+ return yield* Effect.fail(fail("objectives concede needs an author: pass --by <email>, or set git's user.email."));
239
+ }
240
+ const evaluation = evaluations().find((one) => one.rule.id === rule.id);
241
+ if (evaluation === undefined)
242
+ return yield* Effect.fail(fail(`campaign ${rule.id} was not evaluated`));
243
+ // `--holdouts` concedes a subset and refuses the rest: a pull
244
+ // request that legitimately adds one hit while another is an
245
+ // accident.
246
+ const chosen = (flagOf(argv, "--holdouts") ?? flagOf(argv, "--entries"))
247
+ ?.split(",")
248
+ .map((one) => one.trim()) ?? null;
249
+ const outcome = concede(policy, evaluation, objective.success, chosen, flagOf(argv, "--sector") ?? null, {
250
+ at: policy.now,
251
+ by,
252
+ reason,
253
+ });
254
+ if (Result.isFailure(outcome))
255
+ return yield* Effect.fail(fail(outcome.failure));
256
+ // A concession that sends a sector back a phase says so, and names
257
+ // the attestations it revoked on the way.
258
+ const sentBack = outcome.success.sentBack.flatMap((one) => [
259
+ "",
260
+ `this concession moves ${one.sector} back ${one.from ?? "done"} → ${one.to ?? "done"}.`,
261
+ ...(one.revoked.length === 0
262
+ ? []
263
+ : [
264
+ `It revokes ${one.sector}'s attestation of ${one.revoked.join(", ")}: what was attested no longer holds. Once it does again, attest it anew:`,
265
+ ...one.revoked.map((phase) => ` architecture campaigns attest ${one.sector} ${phase} --reason "…" --campaign ${rule.id}`),
266
+ ]),
267
+ ]);
268
+ const scalar = rule.objectives.find((one) => one.id === objective.success)?.measure !== null;
269
+ if (scalar) {
270
+ if (outcome.success.conceded.length === 0) {
271
+ return yield* report([
272
+ `${rule.id}/${objective.success}: nothing to concede; no sector measures past its record.`,
273
+ ]);
274
+ }
275
+ return yield* report([
276
+ `${rule.id}/${objective.success}: a rise conceded in ${count(outcome.success.conceded.length, "sector")}, recorded by ${by}.`,
277
+ ...outcome.success.conceded.map((one) => ` ${one.sector} · ${one.entry}`),
278
+ ...(outcome.success.left.length === 0
279
+ ? []
280
+ : [
281
+ "",
282
+ `${count(outcome.success.left.length, "sector")} left past the record; check still fails on them.`,
283
+ ]),
284
+ ...sentBack,
285
+ ]);
286
+ }
287
+ if (outcome.success.conceded.length === 0) {
288
+ return yield* report([
289
+ `${rule.id}/${objective.success}: nothing to concede; every hit is in the ledger.`,
290
+ ]);
291
+ }
292
+ return yield* report([
293
+ `${rule.id}/${objective.success}: ${count(outcome.success.conceded.length, "holdout")} conceded, recorded by ${by}.`,
294
+ ...outcome.success.conceded.map((one) => ` ${one.sector} · ${one.entry}`),
295
+ ...(outcome.success.left.length === 0
296
+ ? []
297
+ : [
298
+ "",
299
+ `${count(outcome.success.left.length, "hit")} left unrecorded; check still fails on them.`,
300
+ ]),
301
+ ...sentBack,
302
+ ]);
303
+ }
304
+ default:
305
+ return yield* Effect.fail(fail(`unknown objectives subcommand "${parsed.subcommand ?? ""}". Try: objectives clear [<campaign>[/<objective>]] | objectives concede <campaign>[/<objective>] --reason <text> [--by <email>] [--sector <name>] [--holdouts a,b]`));
306
+ }
307
+ });
308
+ export const campaigns = (context) => Effect.gen(function* () {
309
+ const { argv, defaultRoots, policy } = context;
310
+ const parsed = campaignArgsOf(argv, campaignsOf(policy).campaignRules.map((rule) => rule.id));
311
+ const roots = parsed.roots.length > 0 ? parsed.roots : defaultRoots;
312
+ if (campaignsOf(policy).campaignRules.length === 0) {
313
+ return yield* report(["this policy declares no campaigns."]);
314
+ }
315
+ const json = argv.includes("--json");
316
+ const retired = parsed.subcommand === undefined ? undefined : RETIRED[parsed.subcommand];
317
+ if (retired !== undefined)
318
+ return yield* Effect.fail(fail(retired));
319
+ // A positional that is no path is refused, not walked: most often it is
320
+ // a sector's name, and `--sector` is what asks about one.
321
+ for (const root of parsed.roots) {
322
+ if (existsSync(path.resolve(policy.repoRoot, root)))
323
+ continue;
324
+ const named = context.evaluate(defaultRoots).some((one) => one.sectors.has(root));
325
+ return yield* Effect.fail(fail(`campaigns: ${root} is not a path in the repository, so there is nothing to walk there.` +
326
+ (named ? ` It names a sector: \`campaigns status --sector ${root}\`.` : "")));
327
+ }
328
+ const sector = flagOf(argv, "--sector");
329
+ if (parsed.subcommand === "status" && sector !== undefined) {
330
+ const only = argv.includes("--campaign") ? campaignFor(policy, argv) : null;
331
+ if (only !== null && Result.isFailure(only))
332
+ return yield* Effect.fail(fail(only.failure));
333
+ const views = context
334
+ .evaluate(roots)
335
+ .filter((one) => only === null || one.rule.id === only.success.id)
336
+ .flatMap((one) => {
337
+ const view = sectorViewOf(policy, one, sector);
338
+ return view === null ? [] : [view];
339
+ });
340
+ if (views.length === 0) {
341
+ return yield* Effect.fail(fail(`campaigns: no campaign under ${roots.join(", ")} has a sector named ${sector}.`));
342
+ }
343
+ return yield* report(json
344
+ ? [JSON.stringify({ version: 1, sectors: views }, null, 2)]
345
+ : views.flatMap((view, i) => [...(i === 0 ? [] : [""]), ...renderSectorView(view)]));
346
+ }
347
+ // `status` without `--changed` is the overview, in text or JSON: the
348
+ // nudge alone is scoped to a diff.
349
+ const subcommand = parsed.subcommand === "status" && !argv.includes("--changed") ? undefined : parsed.subcommand;
350
+ switch (subcommand) {
351
+ case undefined: {
352
+ const snapshot = { campaigns: snapshotCampaignsOf(policy, context.evaluate(roots)) };
353
+ if (json) {
354
+ // Each campaign as the conformance snapshot carries it: its
355
+ // burn-down, its ladder, and a row per sector.
356
+ return yield* report([
357
+ JSON.stringify({ version: 1, campaigns: snapshot.campaigns }, null, 2),
358
+ ]);
359
+ }
360
+ return yield* report([
361
+ `${count(snapshot.campaigns.length, "campaign")} under ${roots.join(", ")}`,
362
+ "",
363
+ ...renderCampaignRows(snapshot.campaigns),
364
+ "",
365
+ " architecture campaigns status --changed [--base <ref>] [--json] # what a diff touches, and what to do",
366
+ " architecture campaigns status --sector <sector> [--json] # where one sector stands, and what holds it",
367
+ " architecture objectives clear [<campaign>[/<objective>]] # reconcile the ledgers with the code",
368
+ ' architecture objectives concede <campaign>[/<objective>] --reason "<why>" # record why a count may rise',
369
+ ' architecture campaigns attest <sector> <phase> --reason "<why>" [--evidence <url>]',
370
+ ' architecture campaigns note <sector> "<text>"',
371
+ " architecture campaigns history [<campaign>] [--since <ref>]",
372
+ ]);
373
+ }
374
+ case "status": {
375
+ const base = flagOf(argv, "--base") ?? null;
376
+ const diff = yield* Effect.try({
377
+ try: () => readDiff(policy.repoRoot, base),
378
+ catch: (cause) => fail(`could not read the diff: ${String(cause)}`),
379
+ });
380
+ const current = context.evaluate(roots);
381
+ const baseSide = base === null
382
+ ? null
383
+ : yield* Effect.tryPromise({
384
+ try: () => baseSideAt(policy, base, roots, context.reload),
385
+ catch: (cause) => fail(`could not evaluate the base tree at ${base}: ${String(cause)}`),
386
+ });
387
+ // The ledger mode's "before" for work done ahead of the plan is the
388
+ // HEAD tree, evaluated once per commit and cached: no ledger counts
389
+ // the holdouts of a phase a sector has not entered.
390
+ const headTree = base !== null || !current.some((one) => one.rule.phases.length > 0)
391
+ ? null
392
+ : yield* Effect.tryPromise({
393
+ try: () => baseSideAt(policy, "HEAD", roots, context.reload),
394
+ catch: (cause) => fail(`could not evaluate the tree at HEAD: ${String(cause)}`),
395
+ });
396
+ const hotfix = flagOf(argv, "--hotfix") ?? null;
397
+ const nudge = nudgeOf(policy, current, diff, baseSide, hotfix, hotfix === null ? null : authorOf(flagOf(argv, "--by")), headTree);
398
+ yield* report(json ? [JSON.stringify(nudge, null, 2)] : renderNudge(nudge, policy.now));
399
+ if (!nudge.ok) {
400
+ const ahead = nudge.sectors.some((one) => one.verdict === "ahead");
401
+ const back = nudge.sectors.some((one) => one.verdict !== "ok" && one.verdict !== "ahead" && one.verdict !== "hotfix");
402
+ return yield* Effect.fail(fail([
403
+ ...(back ? ["the diff sends a sector back under its onTouch"] : []),
404
+ ...(ahead ? ["the diff works ahead of a sector's phase under its onAhead"] : []),
405
+ ].join("; ")));
406
+ }
407
+ return;
408
+ }
409
+ case "attest": {
410
+ const [sector, phase] = parsed.args;
411
+ if (sector === undefined || phase === undefined) {
412
+ return yield* Effect.fail(fail('campaigns attest needs a sector and a phase: `campaigns attest <sector> <phase> --reason "<why>"`'));
413
+ }
414
+ const reason = flagOf(argv, "--reason");
415
+ if (reason === undefined)
416
+ return yield* Effect.fail(fail("campaigns attest needs --reason <text>."));
417
+ const by = authorOf(flagOf(argv, "--by"));
418
+ if (by === null)
419
+ return yield* Effect.fail(fail("campaigns attest needs an author: pass --by <email>, or set git's user.email."));
420
+ const rule = campaignFor(policy, argv);
421
+ if (Result.isFailure(rule))
422
+ return yield* Effect.fail(fail(rule.failure));
423
+ const evaluation = context.evaluate(roots).find((one) => one.rule.id === rule.success.id);
424
+ if (evaluation === undefined)
425
+ return yield* Effect.fail(fail(`campaign ${rule.success.id} was not evaluated`));
426
+ const written = attest(policy, evaluation, sector, phase, {
427
+ reason,
428
+ evidence: flagOf(argv, "--evidence"),
429
+ by,
430
+ });
431
+ if (Result.isFailure(written))
432
+ return yield* Effect.fail(fail(written.failure));
433
+ return yield* report([
434
+ `${rule.success.id}: sector ${sector} attested at ${phase} by ${by}, in ${written.success}.`,
435
+ "Run `objectives clear` to move it on.",
436
+ ]);
437
+ }
438
+ case "note": {
439
+ const [sector, text] = parsed.args;
440
+ if (sector === undefined || text === undefined) {
441
+ return yield* Effect.fail(fail('campaigns note needs a sector and a text: `campaigns note <sector> "<text>"`'));
442
+ }
443
+ const by = authorOf(flagOf(argv, "--by"));
444
+ if (by === null)
445
+ return yield* Effect.fail(fail("campaigns note needs an author: pass --by <email>, or set git's user.email."));
446
+ const rule = campaignFor(policy, argv);
447
+ if (Result.isFailure(rule))
448
+ return yield* Effect.fail(fail(rule.failure));
449
+ const evaluation = context.evaluate(roots).find((one) => one.rule.id === rule.success.id);
450
+ if (evaluation === undefined)
451
+ return yield* Effect.fail(fail(`campaign ${rule.success.id} was not evaluated`));
452
+ const written = note(policy, evaluation, sector, text, by);
453
+ if (Result.isFailure(written))
454
+ return yield* Effect.fail(fail(written.failure));
455
+ return yield* report([
456
+ `${rule.success.id}: note left on ${sector}, in ${written.success}.`,
457
+ ]);
458
+ }
459
+ case "history": {
460
+ const [named] = parsed.args;
461
+ const targets = named === undefined
462
+ ? campaignsOf(policy).campaignRules
463
+ : campaignsOf(policy).campaignRules.filter((rule) => rule.id === named);
464
+ const manifestPath = path
465
+ .relative(policy.repoRoot, context.manifestPath)
466
+ .replaceAll(path.sep, "/");
467
+ const lines = [];
468
+ for (const rule of targets) {
469
+ const rows = historyOf(policy, rule, flagOf(argv, "--since") ?? null, [manifestPath]);
470
+ if (json) {
471
+ lines.push(JSON.stringify({ campaign: rule.id, rows }, null, 2));
472
+ continue;
473
+ }
474
+ if (lines.length > 0)
475
+ lines.push("");
476
+ for (const line of renderHistory(rule, rows))
477
+ lines.push(line);
478
+ }
479
+ return yield* report(lines);
480
+ }
481
+ case "clear":
482
+ case "concede":
483
+ // The ledger verbs answer under `objectives`; accepted here too.
484
+ return yield* objectives(context);
485
+ default:
486
+ return yield* Effect.fail(fail(`unknown campaigns subcommand "${parsed.subcommand}". Try: campaigns | campaigns status --changed | campaigns attest <sector> <phase> --reason <text> | campaigns note <sector> "<text>" | campaigns history [<campaign>]`));
487
+ }
488
+ });
489
+ //# sourceMappingURL=verbs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verbs.js","sourceRoot":"","sources":["../../../src/campaigns/verbs.ts"],"names":[],"mappings":"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"}
@@ -1,28 +1,84 @@
1
1
  import * as path from "node:path";
2
- import { findManifestFile, loadPolicy, makeFileSystemLive, readManifestFile, } from "@goodbones/core";
2
+ import { findManifestFile, importOptional, loadPolicy, makeFileSystemLive, readManifestFile, } from "@goodbones/core";
3
3
  import { typescriptLanguage } from "@goodbones/typescript";
4
4
  import * as Result from "effect/Result";
5
+ import { campaignsNotInstalled } from "./campaigns/none.js";
6
+ // The language packs this host is composed with. Constructed here and handed
7
+ // down as the `Language` port, so nothing below this file names TypeScript —
8
+ // or ast-grep, the syntax matcher for the campaigns family's `syntax` term.
9
+ // The matcher is an optional peer, with a native binary: composed into the
10
+ // pack when it is installed, and a campaign that needs it without it is
11
+ // refused at load, naming the package.
12
+ export const hostLanguages = async () => {
13
+ const astGrep = await importOptional(() => import("@goodbones/ast-grep"), "@goodbones/ast-grep");
14
+ return [typescriptLanguage(astGrep === null ? {} : { syntax: astGrep.astGrepMatcher() })];
15
+ };
16
+ // The campaigns family, when `@goodbones/campaigns` is installed beside this
17
+ // host, and `none` when it is not. Everything that names the package is
18
+ // under `campaigns/`, reached through this one import.
19
+ export const hostCampaigns = async () => (await importOptional(() => import("./campaigns/live.js"), "@goodbones/campaigns"))
20
+ ?.liveCampaigns ?? campaignsNotInstalled;
21
+ // The clock the campaigns are judged by. `ARCHITECTURE_NOW` (an ISO date or
22
+ // epoch milliseconds) pins it, for a CI that replays a day or a test that
23
+ // needs a stall to have happened.
24
+ export const hostNow = () => {
25
+ const pinned = process.env.ARCHITECTURE_NOW;
26
+ if (pinned === undefined || pinned === "")
27
+ return Date.now();
28
+ const parsed = /^\d+$/.test(pinned) ? Number(pinned) : Date.parse(pinned);
29
+ if (Number.isNaN(parsed)) {
30
+ throw new Error(`ARCHITECTURE_NOW is ${JSON.stringify(pinned)}, which is not a date.`);
31
+ }
32
+ return parsed;
33
+ };
5
34
  // The CLI's composition root: read the manifest file, construct the language
6
35
  // packs and the live file system, and hand them to the loader. The plugin has
7
36
  // one of its own with the same three lines, on purpose — the two hosts share
8
37
  // the core and never each other.
9
- export const loadPolicyFromFile = async (repoRoot, configFilename) => {
10
- // Named, or discovered: architecture.yaml, .yml, .json, or .config.mjs,
11
- // exactly one of which may be present.
12
- const configPath = configFilename === undefined
13
- ? findManifestFile(repoRoot)
14
- : path.resolve(repoRoot, configFilename);
38
+ // Named, or discovered: architecture.yaml, .yml, .json, or .config.mjs,
39
+ // exactly one of which may be present. Absolute.
40
+ export const manifestPathOf = (repoRoot, configFilename) => configFilename === undefined
41
+ ? findManifestFile(repoRoot)
42
+ : path.resolve(repoRoot, configFilename);
43
+ // `given` is the family to compose: found by `hostCampaigns` unless a
44
+ // test names one, which is how the host is run as if the package were absent.
45
+ export const loadPolicyFromFile = async (repoRoot, configFilename, given) => {
46
+ const configPath = manifestPathOf(repoRoot, configFilename);
15
47
  const read = await readManifestFile(configPath);
48
+ const campaigns = given ?? (await hostCampaigns());
49
+ const composed = await campaigns.compose(repoRoot, configPath, read.manifest);
16
50
  const loaded = loadPolicy({
17
51
  repoRoot,
18
52
  configPath,
19
- manifest: read.manifest,
53
+ manifest: composed.manifest,
20
54
  locate: read.locate,
21
- languages: [typescriptLanguage()],
55
+ languages: await hostLanguages(),
22
56
  fileSystem: makeFileSystemLive(repoRoot),
57
+ extensions: composed.extensions,
58
+ uninstalled: composed.uninstalled,
59
+ now: hostNow(),
23
60
  });
24
61
  if (Result.isFailure(loaded))
25
62
  throw loaded.failure;
26
- return loaded.success;
63
+ return { ...loaded.success, campaigns: campaigns.host };
64
+ };
65
+ // The same composition, for a manifest the host already holds as a value
66
+ // rather than a file: the bootstrap `infer` resolves through, and the
67
+ // manifest it then proves loads. Failure is returned, not thrown — the caller
68
+ // has a sentence to put around it.
69
+ export const loadPolicyFromManifest = async (repoRoot, manifest) => {
70
+ const campaigns = await hostCampaigns();
71
+ const composed = await campaigns.compose(repoRoot, null, manifest);
72
+ const loaded = loadPolicy({
73
+ repoRoot,
74
+ configPath: path.resolve(repoRoot, "architecture.yaml"),
75
+ manifest: composed.manifest,
76
+ languages: await hostLanguages(),
77
+ fileSystem: makeFileSystemLive(repoRoot),
78
+ extensions: composed.extensions,
79
+ uninstalled: composed.uninstalled,
80
+ now: hostNow(),
81
+ });
82
+ return Result.map(loaded, (policy) => ({ ...policy, campaigns: campaigns.host }));
27
83
  };
28
84
  //# sourceMappingURL=config-loader.js.map