@intentius/chant 0.124.33 → 0.124.34

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 (75) hide show
  1. package/dist/cli/handlers/promote.d.ts.map +1 -1
  2. package/dist/cli/handlers/promote.js +261 -73
  3. package/dist/cli/main.d.ts.map +1 -1
  4. package/dist/cli/main.js +18 -1
  5. package/dist/cli/parse-args.d.ts.map +1 -1
  6. package/dist/cli/parse-args.js +7 -0
  7. package/dist/cli/registry.d.ts +3 -1
  8. package/dist/cli/registry.d.ts.map +1 -1
  9. package/dist/components/promote-rounds.d.ts +102 -0
  10. package/dist/components/promote-rounds.d.ts.map +1 -0
  11. package/dist/components/promote-rounds.js +174 -0
  12. package/dist/components/release-gate.d.ts +30 -0
  13. package/dist/components/release-gate.d.ts.map +1 -1
  14. package/dist/components/release-gate.js +92 -42
  15. package/dist/graph-declared.d.ts +4 -0
  16. package/dist/graph-declared.d.ts.map +1 -1
  17. package/dist/graph-declared.js +11 -1
  18. package/dist/wave-runtime.mjs +39 -39
  19. package/dist/workspace/__fixtures__/contract-repo.d.ts.map +1 -1
  20. package/dist/workspace/__fixtures__/contract-repo.js +13 -2
  21. package/dist/workspace/check.schema.json +20 -2
  22. package/dist/workspace/checks/ci-workflow.d.ts +17 -0
  23. package/dist/workspace/checks/ci-workflow.d.ts.map +1 -0
  24. package/dist/workspace/checks/ci-workflow.js +123 -0
  25. package/dist/workspace/checks/security.d.ts +16 -1
  26. package/dist/workspace/checks/security.d.ts.map +1 -1
  27. package/dist/workspace/checks/security.js +4 -4
  28. package/dist/workspace/checks.d.ts +1 -1
  29. package/dist/workspace/checks.d.ts.map +1 -1
  30. package/dist/workspace/checks.js +4 -1
  31. package/dist/workspace/ci-init.d.ts +100 -0
  32. package/dist/workspace/ci-init.d.ts.map +1 -0
  33. package/dist/workspace/ci-init.js +434 -0
  34. package/dist/workspace/ci-workflow.d.ts +91 -0
  35. package/dist/workspace/ci-workflow.d.ts.map +1 -0
  36. package/dist/workspace/ci-workflow.js +33 -0
  37. package/dist/workspace/declaration.d.ts +18 -0
  38. package/dist/workspace/declaration.d.ts.map +1 -1
  39. package/dist/workspace/declaration.js +9 -2
  40. package/dist/workspace/declaration.schema.json +28 -0
  41. package/dist/workspace/init.js +2 -2
  42. package/dist/workspace/reason-codes.d.ts +9 -0
  43. package/dist/workspace/reason-codes.d.ts.map +1 -1
  44. package/dist/workspace/reason-codes.js +10 -0
  45. package/dist/workspace/release-workflow.d.ts +31 -0
  46. package/dist/workspace/release-workflow.d.ts.map +1 -0
  47. package/dist/workspace/release-workflow.js +150 -0
  48. package/package.json +1 -1
  49. package/src/cli/handlers/promote.ts +280 -83
  50. package/src/cli/main.ts +18 -1
  51. package/src/cli/parse-args.ts +5 -0
  52. package/src/cli/registry.ts +3 -1
  53. package/src/components/promote-rounds.test.ts +220 -0
  54. package/src/components/promote-rounds.ts +232 -0
  55. package/src/components/release-gate.test.ts +47 -0
  56. package/src/components/release-gate.ts +111 -46
  57. package/src/graph-declared-exports.test.ts +40 -0
  58. package/src/graph-declared.ts +9 -1
  59. package/src/workspace/__fixtures__/contract-repo.ts +11 -2
  60. package/src/workspace/check-contract.test.ts +3 -2
  61. package/src/workspace/check.schema.json +20 -2
  62. package/src/workspace/checks/ci-workflow.test.ts +150 -0
  63. package/src/workspace/checks/ci-workflow.ts +129 -0
  64. package/src/workspace/checks/security.ts +4 -4
  65. package/src/workspace/checks.ts +4 -1
  66. package/src/workspace/ci-init.test.ts +159 -0
  67. package/src/workspace/ci-init.ts +445 -0
  68. package/src/workspace/ci-report-url.test.ts +6 -1
  69. package/src/workspace/ci-workflow.ts +71 -0
  70. package/src/workspace/declaration.schema.json +28 -0
  71. package/src/workspace/declaration.ts +32 -3
  72. package/src/workspace/init.ts +2 -2
  73. package/src/workspace/reason-codes.test.ts +2 -0
  74. package/src/workspace/reason-codes.ts +10 -0
  75. package/src/workspace/release-workflow.ts +167 -0
@@ -1 +1 @@
1
- {"version":3,"file":"contract-repo.d.ts","sourceRoot":"","sources":["../../../src/workspace/__fixtures__/contract-repo.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,OAAO,MAAM,eAAe,CAAC;AAGpC,6CAA6C;AAC7C,eAAO,MAAM,IAAI,QAAwE,CAAC;AAI1F,gGAAgG;AAChG,wBAAgB,YAAY,IAAI,IAAI,CAEnC;AAED,wBAAgB,UAAU,CAAC,MAAM,SAAoB,GAAG,MAAM,CAI7D;AAED,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAM1D;AAED,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,CAO7G;AAED,uFAAuF;AACvF,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EAAE,MAAM,UAAQ,GAAG,MAAM,CAS3G;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,MAAM,EAAE,MAAM,SAAyB,GAAG,MAAM,MAAM,CAQ9F;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,SAAS,GAAG,MAAM,CAIhE;AAED,QAAA,MAAM,GAAG,SAAiD,CAAC;AAE3D,4EAA4E;AAC5E,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,UAAU,CAAC,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC;IAAC,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAAA;CAAE,CAStH;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,eAAO,MAAM,WAAW,YAAa,OAAO,EAAE,UAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,WACL,CAAC;AAE1E;;;GAGG;AACH,eAAO,MAAM,gBAAgB,6XAU5B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,sZASjC,CAAC"}
1
+ {"version":3,"file":"contract-repo.d.ts","sourceRoot":"","sources":["../../../src/workspace/__fixtures__/contract-repo.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,OAAO,MAAM,eAAe,CAAC;AAGpC,6CAA6C;AAC7C,eAAO,MAAM,IAAI,QAAwE,CAAC;AAI1F,gGAAgG;AAChG,wBAAgB,YAAY,IAAI,IAAI,CAEnC;AAED,wBAAgB,UAAU,CAAC,MAAM,SAAoB,GAAG,MAAM,CAI7D;AAED,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAM1D;AAED,iFAAiF;AACjF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,IAAI,CAO7G;AAED,uFAAuF;AACvF,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,EAAE,MAAM,UAAQ,GAAG,MAAM,CAS3G;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,MAAM,EAAE,MAAM,SAAyB,GAAG,MAAM,MAAM,CAiB9F;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,SAAS,GAAG,MAAM,CAIhE;AAED,QAAA,MAAM,GAAG,SAAiD,CAAC;AAE3D,4EAA4E;AAC5E,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,UAAU,CAAC,OAAO,GAAG,CAAC,OAAO,CAAC,CAAC;IAAC,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAAA;CAAE,CAStH;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,eAAO,MAAM,WAAW,YAAa,OAAO,EAAE,UAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,WACL,CAAC;AAE1E;;;GAGG;AACH,eAAO,MAAM,gBAAgB,6XAU5B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,sZASjC,CAAC"}
@@ -22,7 +22,7 @@ export function scratchDir(prefix = "chant-contract-") {
22
22
  return d;
23
23
  }
24
24
  export function git(cwd, ...args) {
25
- return execFileSync("git", ["-c", "user.name=t", "-c", "user.email=t@example.com", "-c", "commit.gpgsign=false", ...args], {
25
+ return execFileSync("git", ["-c", "user.name=t", "-c", "user.email=t@example.com", "-c", "commit.gpgsign=false", "-c", "gc.auto=0", "-c", "maintenance.auto=false", ...args], {
26
26
  cwd,
27
27
  encoding: "utf-8",
28
28
  stdio: ["ignore", "pipe", "pipe"],
@@ -61,7 +61,18 @@ export function repoFixture(build, prefix = "chant-contract-copy-") {
61
61
  if (template === undefined || !existsSync(template))
62
62
  template = build();
63
63
  const root = scratchDir(prefix);
64
- cpSync(template, root, { recursive: true });
64
+ // A commit can leave a detached `git gc --auto` or maintenance run moving
65
+ // the template's objects, and a copy that meets it fails with ENOENT on
66
+ // .git/objects. Copy once more after it settles.
67
+ try {
68
+ cpSync(template, root, { recursive: true });
69
+ }
70
+ catch (err) {
71
+ if (err.code !== "ENOENT")
72
+ throw err;
73
+ rmSync(root, { recursive: true, force: true });
74
+ cpSync(template, root, { recursive: true });
75
+ }
65
76
  return root;
66
77
  };
67
78
  }
@@ -332,7 +332,16 @@
332
332
 
333
333
  "security-runner-start-no-role",
334
334
 
335
- "security-trust-unreadable"
335
+ "security-trust-unreadable",
336
+ "ci-workflow-green-undeclared",
337
+ "ci-workflow-no-pre-merge",
338
+ "ci-workflow-apply-in-green",
339
+ "ci-workflow-no-components",
340
+ "ci-workflow-no-environments",
341
+ "ci-workflow-ungated-env",
342
+ "ci-workflow-pipeline-missing",
343
+ "ci-workflow-pipeline-differs",
344
+ "ci-workflow-publish-missing"
336
345
  ],
337
346
  "description": "For WSP001: why the declaration can't be read. For WSP121 to WSP127, the box finding (#2726, #2727, #2780, #2850). For WSP117, work-acceptance-unmet (#2772). For WSP118, flag-stale (#4024). For WSP131 to WSP133, the diagram finding (#2764)."
338
347
  }
@@ -445,7 +454,16 @@
445
454
 
446
455
  "security-runner-start-no-role",
447
456
 
448
- "security-trust-unreadable"
457
+ "security-trust-unreadable",
458
+ "ci-workflow-green-undeclared",
459
+ "ci-workflow-no-pre-merge",
460
+ "ci-workflow-apply-in-green",
461
+ "ci-workflow-no-components",
462
+ "ci-workflow-no-environments",
463
+ "ci-workflow-ungated-env",
464
+ "ci-workflow-pipeline-missing",
465
+ "ci-workflow-pipeline-differs",
466
+ "ci-workflow-publish-missing"
449
467
  ],
450
468
  "description": "For WSP001: why the declaration can't be read. For WSP121 to WSP127, the box finding (#2726, #2727, #2780, #2850). For WSP117, work-acceptance-unmet (#2772). For WSP118, flag-stale (#4024). For WSP131 to WSP133, the diagram finding (#2764)."
451
469
  },
@@ -0,0 +1,17 @@
1
+ /**
2
+ * WSP151 (#4168 step 6): what a member under `ci.workflow` still lacks.
3
+ *
4
+ * A declaration that names no workflow gets no finding from this file. The
5
+ * requirements and their codes are {@link CI_WORKFLOW_REQUIREMENTS}
6
+ * (../ci-workflow.ts). Like the security checklists (./security.ts), the
7
+ * check reads files and never runs them: `chant.config.ts` for the
8
+ * environments (its literal `environments`, as `workspace status` reads it),
9
+ * `*.component.ts` for components and gates, and the forge pipeline files for
10
+ * the jobs. A generated file that differs from what its generator writes is
11
+ * WSP101 to WSP106's to report; this check asks only whether the jobs the
12
+ * workflow needs are there.
13
+ */
14
+ import type { WorkspaceCheck } from "../checks.js";
15
+ export declare const WSP_CI_WORKFLOW = "WSP151";
16
+ export declare const CI_WORKFLOW_CHECKS: readonly WorkspaceCheck[];
17
+ //# sourceMappingURL=ci-workflow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ci-workflow.d.ts","sourceRoot":"","sources":["../../../src/workspace/checks/ci-workflow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAuB,MAAM,WAAW,CAAC;AAQrE,eAAO,MAAM,eAAe,WAAW,CAAC;AAaxC,eAAO,MAAM,kBAAkB,EAAE,SAAS,cAAc,EA6FvD,CAAC"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * WSP151 (#4168 step 6): what a member under `ci.workflow` still lacks.
3
+ *
4
+ * A declaration that names no workflow gets no finding from this file. The
5
+ * requirements and their codes are {@link CI_WORKFLOW_REQUIREMENTS}
6
+ * (../ci-workflow.ts). Like the security checklists (./security.ts), the
7
+ * check reads files and never runs them: `chant.config.ts` for the
8
+ * environments (its literal `environments`, as `workspace status` reads it),
9
+ * `*.component.ts` for components and gates, and the forge pipeline files for
10
+ * the jobs. A generated file that differs from what its generator writes is
11
+ * WSP101 to WSP106's to report; this check asks only whether the jobs the
12
+ * workflow needs are there.
13
+ */
14
+ import { appliesOnMerge, STUB_MARKER, workflowOf } from "../ci-workflow.js";
15
+ import { matchesCheckRun } from "../ci-green.js";
16
+ import { staticPromotionOrder } from "../promotion-order.js";
17
+ import { joinPath } from "../tree.js";
18
+ import { allPipelineFiles, commandLines, componentFiles, read } from "./security.js";
19
+ export const WSP_CI_WORKFLOW = "WSP151";
20
+ const memberDir = (dir) => (dir === "." ? "" : dir);
21
+ const PLAN = /\bci\s+run\s+plan\b|\bcomponents\s+pr-plan\b/;
22
+ const RECORD = /\bci\s+run\s+record\b|\bcomponents\s+pr-record\b/;
23
+ const APPLY = /\bci\s+run\s+apply\b|\bcomponents\s+pr-apply\b/;
24
+ const TICK = /\bci\s+tick\b/;
25
+ const PUBLISH = /\brelease\s+publish\b/;
26
+ /** The apply job names a required phase could match. */
27
+ const APPLY_JOB_NAMES = ["apply", "pr-apply"];
28
+ export const CI_WORKFLOW_CHECKS = [
29
+ {
30
+ id: WSP_CI_WORKFLOW,
31
+ name: "ci-workflow",
32
+ description: "Under ci.workflow: ci.green with pre-merge phases and no apply job required, each member with a component, environments and a gate on each component, and pipeline files that plan, record (or apply under apply on merge), tick and publish.",
33
+ severity: "warning",
34
+ configurable: true,
35
+ check(ctx) {
36
+ const d = ctx.declaration;
37
+ const under = d.members
38
+ .map((m) => ({ member: m, workflow: workflowOf(d, m) }))
39
+ .filter((u) => u.workflow !== null)
40
+ // The top level's workflow covers the members that build with chant; a member that names one itself is held to it.
41
+ .filter((u) => u.member.ciWorkflow !== null || ctx.tree.stat(joinPath(memberDir(u.member.dir), "chant.config.ts")) === "file");
42
+ if (under.length === 0 && !d.ci?.workflow)
43
+ return [];
44
+ const pointer = d.ci?.workflow ? "/ci/workflow" : `${under[0].member.pointer}/ci/workflow`;
45
+ const out = [];
46
+ const finding = (code, message, at = {}) => {
47
+ out.push({
48
+ checkId: this.id,
49
+ severity: this.severity,
50
+ code,
51
+ message: `${code}: ${message}`,
52
+ pointer: at.pointer ?? pointer,
53
+ ...(at.entity !== undefined ? { entity: at.entity } : {}),
54
+ ...(at.treeFile !== undefined ? { treeFile: at.treeFile, line: at.line ?? 1, column: 1 } : {}),
55
+ });
56
+ };
57
+ const green = d.ci?.green ?? null;
58
+ if (!green) {
59
+ finding("ci-workflow-green-undeclared", "the workspace follows a ci.workflow and declares no ci.green, so no commit gets a verdict and no release can be cut; run chant ci init or add a ci.green block");
60
+ }
61
+ else {
62
+ if ((green.preMerge ?? []).length === 0) {
63
+ finding("ci-workflow-no-pre-merge", "ci.green.preMerge names no phase, so nothing says which checks run before the branch moves; name the quick ones", { pointer: green.pointer });
64
+ }
65
+ for (const name of green.require) {
66
+ const phase = green.phases.find((p) => p.name === name);
67
+ const hit = phase?.runs.find((pattern) => APPLY_JOB_NAMES.some((job) => matchesCheckRun(pattern, job)));
68
+ if (phase && hit) {
69
+ finding("ci-workflow-apply-in-green", `the required phase ${name} matches the apply job with ${JSON.stringify(hit)}, so an apply that waits for a green commit would wait on itself; drop the pattern`, { pointer: phase.pointer });
70
+ }
71
+ }
72
+ }
73
+ for (const { member } of under) {
74
+ const dir = memberDir(member.dir);
75
+ const components = componentFiles(ctx.tree, dir);
76
+ if (components.length === 0) {
77
+ finding("ci-workflow-no-components", `member ${member.name} declares no component, so nothing of it can be cut or promoted; chant ci init writes a stub`, { pointer: member.pointer, entity: member.name });
78
+ }
79
+ else if (components.every((f) => (read(ctx.tree, f) ?? "").includes(STUB_MARKER))) {
80
+ finding("ci-workflow-no-components", `member ${member.name}'s only component is the stub chant ci init wrote (${components[0]}); say how it is built and deployed, then delete its ${STUB_MARKER} line`, { pointer: member.pointer, entity: member.name, treeFile: components[0] });
81
+ }
82
+ const configPath = joinPath(dir, "chant.config.ts");
83
+ const config = read(ctx.tree, configPath);
84
+ // A config whose environments aren't literals can't be read without running it; say nothing rather than guess.
85
+ const order = config === null ? [] : staticPromotionOrder(config);
86
+ if (order !== undefined && order.length === 0) {
87
+ finding("ci-workflow-no-environments", `member ${member.name}'s chant.config.ts declares no environments, so a release has nowhere to be promoted to`, { pointer: member.pointer, entity: member.name, ...(config !== null ? { treeFile: configPath } : {}) });
88
+ }
89
+ for (const file of components) {
90
+ const text = read(ctx.tree, file) ?? "";
91
+ if (/\bgate\s*\(|kind\s*:\s*["']gate["']/.test(text))
92
+ continue;
93
+ const last = order && order.length > 0 ? order[order.length - 1].name : "the last environment";
94
+ finding("ci-workflow-ungated-env", `${file} has no gate, so a promote to ${last} waits on no approval; add a gate() step`, { pointer: member.pointer, entity: member.name, treeFile: file });
95
+ }
96
+ }
97
+ const files = allPipelineFiles(ctx);
98
+ const has = (re) => files.some((f) => f.lines.some((l) => re.test(l)));
99
+ const applyOnMerge = under.some((u) => appliesOnMerge(u.workflow)) || (d.ci?.workflow ? appliesOnMerge(d.ci.workflow) : false);
100
+ const missing = [
101
+ ...(has(PLAN) ? [] : ["a plan job (ci run plan)"]),
102
+ ...(has(RECORD) || has(APPLY) ? [] : [applyOnMerge ? "an apply job (ci run apply)" : "a record job (ci run record)"]),
103
+ ...(has(TICK) ? [] : ["chant ci tick"]),
104
+ ];
105
+ if (missing.length > 0) {
106
+ finding("ci-workflow-pipeline-missing", `no pipeline file runs ${missing.join(", ")}; generate them with chant build --components --generate <forge> --pr-loop and chant ci workflow`);
107
+ }
108
+ if (!applyOnMerge) {
109
+ for (const l of commandLines(ctx, APPLY)) {
110
+ finding("ci-workflow-pipeline-differs", `${l.path} applies on merge, and the workflow is trunk-curated, where a merge records the plan and deploys nothing; regenerate without --apply-on-merge, or set ci.workflow to trunk-curated+apply-on-merge`, { treeFile: l.path, line: l.line });
111
+ }
112
+ }
113
+ else if (!has(APPLY) && has(RECORD)) {
114
+ const l = commandLines(ctx, RECORD)[0];
115
+ finding("ci-workflow-pipeline-differs", `${l.path} records on merge, and the workflow is trunk-curated+apply-on-merge; regenerate with --apply-on-merge`, { treeFile: l.path, line: l.line });
116
+ }
117
+ if (!has(PUBLISH)) {
118
+ finding("ci-workflow-publish-missing", "no pipeline file runs chant release publish, so a cut release is never published; generate one with chant release workflow");
119
+ }
120
+ return out;
121
+ },
122
+ },
123
+ ];
@@ -23,7 +23,8 @@
23
23
  * pipeline file that runs `chant release publish`, `chant ci tick` or
24
24
  * `chant components pr-apply`.
25
25
  */
26
- import type { WorkspaceCheck } from "../checks.js";
26
+ import type { WorkspaceCheck, WorkspaceCheckContext } from "../checks.js";
27
+ import { type WorkspaceTree } from "../tree.js";
27
28
  /** The read contract's codes for the security findings, carried as `code` on each. */
28
29
  export declare const SECURITY_FINDING_CODES: readonly ["security-signers-missing", "security-release-gate-missing", "security-publish-allows-unsigned", "security-sbom-disabled", "security-sbom-unsourced", "security-publish-no-provenance", "security-component-no-sbom", "security-component-no-verify", "security-signed-since-unset", "security-runner-untrusted", "security-tick-no-key", "security-review-not-required", "security-attribution-any", "security-gate-unsigned", "security-runner-start-no-key", "security-runner-start-no-role", "security-trust-unreadable"];
29
30
  export declare const WSP_SECURITY_VERIFIED_RELEASES = "WSP161";
@@ -31,5 +32,19 @@ export declare const WSP_SECURITY_SUPPLY_CHAIN = "WSP162";
31
32
  export declare const WSP_SECURITY_WHO_RAN_IT = "WSP163";
32
33
  export declare const WSP_SECURITY_REVIEW_RULES = "WSP164";
33
34
  export declare const WSP_SECURITY_ISOLATED_RUNNERS = "WSP165";
35
+ export declare function read(tree: WorkspaceTree, path: string): string | null;
36
+ /** Every pipeline file of the workspace: its root's, and each member's. */
37
+ export declare function allPipelineFiles(ctx: WorkspaceCheckContext): {
38
+ path: string;
39
+ lines: string[];
40
+ }[];
41
+ /** The lines of the pipeline files that run a chant command, `command` naming it, such as `release publish`. */
42
+ export declare function commandLines(ctx: WorkspaceCheckContext, command: RegExp): {
43
+ path: string;
44
+ line: number;
45
+ text: string;
46
+ }[];
47
+ /** The member's `*.component.ts` files, walked a few levels down, past node_modules and build output. */
48
+ export declare function componentFiles(tree: WorkspaceTree, dir: string, depth?: number): string[];
34
49
  export declare const SECURITY_CHECKS: readonly WorkspaceCheck[];
35
50
  //# sourceMappingURL=security.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../../src/workspace/checks/security.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAA8C,MAAM,WAAW,CAAC;AAU5F,sFAAsF;AACtF,eAAO,MAAM,sBAAsB,ygBAkBO,CAAC;AAI3C,eAAO,MAAM,8BAA8B,WAAW,CAAC;AACvD,eAAO,MAAM,yBAAyB,WAAW,CAAC;AAClD,eAAO,MAAM,uBAAuB,WAAW,CAAC;AAChD,eAAO,MAAM,yBAAyB,WAAW,CAAC;AAClD,eAAO,MAAM,6BAA6B,WAAW,CAAC;AA0GtD,eAAO,MAAM,eAAe,EAAE,SAAS,cAAc,EAuIpD,CAAC"}
1
+ {"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../../src/workspace/checks/security.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAuB,MAAM,WAAW,CAAC;AAI5F,OAAO,EAAY,KAAK,aAAa,EAAE,MAAM,SAAS,CAAC;AAMvD,sFAAsF;AACtF,eAAO,MAAM,sBAAsB,ygBAkBO,CAAC;AAI3C,eAAO,MAAM,8BAA8B,WAAW,CAAC;AACvD,eAAO,MAAM,yBAAyB,WAAW,CAAC;AAClD,eAAO,MAAM,uBAAuB,WAAW,CAAC;AAChD,eAAO,MAAM,yBAAyB,WAAW,CAAC;AAClD,eAAO,MAAM,6BAA6B,WAAW,CAAC;AAsBtD,wBAAgB,IAAI,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOrE;AAkBD,2EAA2E;AAC3E,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,qBAAqB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,EAAE,CAGhG;AAED,gHAAgH;AAChH,wBAAgB,YAAY,CAAC,GAAG,EAAE,qBAAqB,EAAE,OAAO,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,CAExH;AAED,yGAAyG;AACzG,wBAAgB,cAAc,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,MAAM,EAAE,CAQpF;AAuCD,eAAO,MAAM,eAAe,EAAE,SAAS,cAAc,EAuIpD,CAAC"}
@@ -70,7 +70,7 @@ function groupPointer(declaration, group) {
70
70
  const m = declaration.members.find((e) => e.security.includes(group));
71
71
  return m ? `${m.pointer}/security/${m.security.indexOf(group)}` : "/security";
72
72
  }
73
- function read(tree, path) {
73
+ export function read(tree, path) {
74
74
  if (tree.stat(path) !== "file")
75
75
  return null;
76
76
  try {
@@ -99,16 +99,16 @@ function pipelineFiles(tree, dir) {
99
99
  return out;
100
100
  }
101
101
  /** Every pipeline file of the workspace: its root's, and each member's. */
102
- function allPipelineFiles(ctx) {
102
+ export function allPipelineFiles(ctx) {
103
103
  const dirs = new Set(["", ...ctx.declaration.members.map((m) => memberDir(m.dir))]);
104
104
  return [...dirs].flatMap((d) => pipelineFiles(ctx.tree, d));
105
105
  }
106
106
  /** The lines of the pipeline files that run a chant command, `command` naming it, such as `release publish`. */
107
- function commandLines(ctx, command) {
107
+ export function commandLines(ctx, command) {
108
108
  return allPipelineFiles(ctx).flatMap((f) => f.lines.flatMap((text, i) => (command.test(text) ? [{ path: f.path, line: i + 1, text }] : [])));
109
109
  }
110
110
  /** The member's `*.component.ts` files, walked a few levels down, past node_modules and build output. */
111
- function componentFiles(tree, dir, depth = 4) {
111
+ export function componentFiles(tree, dir, depth = 4) {
112
112
  const out = [];
113
113
  for (const e of tree.list(dir) ?? []) {
114
114
  if (e.type === "dir") {
@@ -37,7 +37,7 @@
37
37
  * | WSP126, WSP127 | box intent: the decision record a box names exists, and constrains a member or path of this workspace (#2850, #2857) |
38
38
  * | WSP141, WSP142 | member links resolved against a live read, with `--live` (#2549) |
39
39
  * | WSP131 to WSP133 | diagram artifacts: source and render exist, a recorded source hash still matches (#2764) |
40
- * | WSP151 | reserved for the `ci.workflow` preset (#4168 step 6) |
40
+ * | WSP151 | what a member under `ci.workflow` still lacks (#4168 step 6) |
41
41
  * | WSP161 to WSP165 | the security groups the declaration opts into: what each still lacks (#4168 step 7) |
42
42
  */
43
43
  import type { LintDiagnostic, LintRule, Severity } from "../lint/rule.js";
@@ -1 +1 @@
1
- {"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../../src/workspace/checks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../../src/workspace/checks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACvE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAsD,KAAK,WAAW,EAAkC,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AACzJ,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,EAAiE,KAAK,eAAe,EAAE,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AACjI,OAAO,EAA6D,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpH,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,QAAQ,CAAC;AAEjE,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACrD,OAAO,EAA0C,KAAK,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACrG,OAAO,EAAoC,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC5F,OAAO,EAAwC,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACpG,OAAO,EAAoC,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AACrF,OAAO,EAAiB,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAKnE,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAqB,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,EAAwB,KAAK,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEpF;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,6EAA6E;IAC7E,OAAO,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACvC,+EAA+E;IAC/E,SAAS,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAC3C,kFAAkF;IAClF,SAAS,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAC1C,oFAAoF;IACpF,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,oGAAoG;IACpG,aAAa,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IACxC,8EAA8E;IAC9E,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,uFAAuF;IACvF,UAAU,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;IAC1C,kHAAkH;IAClH,cAAc,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;CAC5D;AAED,0CAA0C;AAC1C,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,WAAW,CAAC;IACzB,IAAI,EAAE,aAAa,CAAC;IACpB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,KAAK,EAAE,YAAY,CAAC;IACpB,+CAA+C;IAC/C,YAAY,EAAE,eAAe,EAAE,CAAC;IAChC,yGAAyG;IACzG,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,mEAAmE;IACnE,aAAa,CAAC,EAAE,eAAe,EAAE,CAAC;IAClC,gDAAgD;IAChD,KAAK,CAAC,EAAE,cAAc,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAoB,SAAQ,mBAAmB;IAC9D,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,2IAA2I;IAC3I,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mJAAmJ;IACnJ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,mDAAmD;IACnD,EAAE,EAAE,MAAM,CAAC;IACX,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,QAAQ,CAAC;IACnB,kFAAkF;IAClF,YAAY,EAAE,OAAO,CAAC;IACtB,KAAK,CAAC,GAAG,EAAE,qBAAqB,GAAG,mBAAmB,EAAE,CAAC;CAC1D;AAED,2EAA2E;AAC3E,MAAM,WAAW,gBAAiB,SAAQ,cAAc;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mJAAmJ;IACnJ,IAAI,CAAC,EAAE,UAAU,CAAC;CACnB;AAED,MAAM,WAAW,iBAAkB,SAAQ,gBAAgB;IACzD,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,sBAAsB;IACrC,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,gBAAgB,EAAE,CAAC;IAChC,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,8EAA8E;IAC9E,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,0FAA0F;IAC1F,IAAI,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,EAAE,CAAA;KAAE,CAAC;IACzC,mDAAmD;IACnD,EAAE,EAAE,OAAO,CAAC;CACb;AAqBD,iHAAiH;AACjH,eAAO,MAAM,mBAAmB,WAAW,CAAC;AAE5C,eAAO,MAAM,gBAAgB,EAAE,SAAS,cAAc,EAqMrD,CAAC;AAWF;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,QAAQ,EAAE,CAShD;AAED,qFAAqF;AACrF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,qBAAqB,GAAG,mBAAmB,EAAE,CAEpF;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,mBAAmB,EAAE,GAC9B;IAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAAC,UAAU,EAAE,CAAC,mBAAmB,GAAG;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,EAAE,CAAA;CAAE,CAkB7F;AAED,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,sHAAsH;IACtH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,8FAA8F;IAC9F,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB;;;;;OAKG;IACH,IAAI,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;KAAE,CAAC;CAC3D;AAED;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,OAAO,GAAE;IAAE,aAAa,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAAC,cAAc,CAAC,CASrJ;AAUD;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAiB,EAC5C,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,sBAAsB,CAAC,CAqEjC"}
@@ -37,7 +37,7 @@
37
37
  * | WSP126, WSP127 | box intent: the decision record a box names exists, and constrains a member or path of this workspace (#2850, #2857) |
38
38
  * | WSP141, WSP142 | member links resolved against a live read, with `--live` (#2549) |
39
39
  * | WSP131 to WSP133 | diagram artifacts: source and render exist, a recorded source hash still matches (#2764) |
40
- * | WSP151 | reserved for the `ci.workflow` preset (#4168 step 6) |
40
+ * | WSP151 | what a member under `ci.workflow` still lacks (#4168 step 6) |
41
41
  * | WSP161 to WSP165 | the security groups the declaration opts into: what each still lacks (#4168 step 7) |
42
42
  */
43
43
  import { realpathSync } from "node:fs";
@@ -56,6 +56,7 @@ import { RECORD_CHECKS } from "./checks/records.js";
56
56
  import { BOX_CHECKS } from "./checks/boxes.js";
57
57
  import { DIAGRAM_CHECKS } from "./checks/diagrams.js";
58
58
  import { SECURITY_CHECKS } from "./checks/security.js";
59
+ import { CI_WORKFLOW_CHECKS } from "./checks/ci-workflow.js";
59
60
  import { loadDeclaredKinds } from "./declared-kinds.js";
60
61
  import { resolveBoxIntents } from "./box-intent.js";
61
62
  import { gatherLexiconOutputs } from "./lexicon-outputs.js";
@@ -273,6 +274,8 @@ export const WORKSPACE_CHECKS = [
273
274
  ...DIAGRAM_CHECKS,
274
275
  // Links resolved against a live read, with --live (#2549), WSP141 and WSP142.
275
276
  ...LIVE_CHECKS,
277
+ // What a member under ci.workflow still lacks (#4168 step 6), WSP151.
278
+ ...CI_WORKFLOW_CHECKS,
276
279
  // The security groups the declaration opts into (#4168 step 7), WSP161 to WSP165.
277
280
  ...SECURITY_CHECKS,
278
281
  ];
@@ -0,0 +1,100 @@
1
+ /**
2
+ * `chant ci init --workflow <name> [--forge <forge>] [--security <group>]...
3
+ * [--yes]` (#4168 step 6, section 9): set a workspace up for a prescribed
4
+ * delivery workflow (../ci-workflow.ts).
5
+ *
6
+ * It proposes, prints the proposal as a diff, and writes only on `--yes` or a
7
+ * yes at the prompt. What it proposes comes from what `workspace check`'s
8
+ * WSP151 reports for the workspace as it would be with `ci.workflow` set, so
9
+ * a second run proposes only what is still missing, and nothing once the
10
+ * workspace has it all.
11
+ *
12
+ * - The declaration gains `ci.workflow`, a `ci.green` block when it has none
13
+ * (one phase per GitHub workflow, its jobs as the check runs, and the
14
+ * workflows a pull request runs as `preMerge`), and `preMerge` when the
15
+ * block has none. `--security` adds groups to the top-level `security`;
16
+ * without it no group is turned on, and the groups are listed.
17
+ * - A member that builds with chant and declares no component gets a
18
+ * `<member>.component.ts` stub with a gate and a TODO line, which WSP151
19
+ * keeps reporting until someone fills the stub in. A `chant.config.ts`
20
+ * that declares no environments gains `environments: ["staging", "prod"]`
21
+ * when its default export is a plain object literal.
22
+ * - The generated files are written by the generators that own them, run
23
+ * after the edits: `chant build --components --generate <forge> --pr-loop`
24
+ * in each member, `chant ci workflow` for the tick, and `chant release
25
+ * workflow` for the publish job. Each is named in the proposal before it
26
+ * runs.
27
+ *
28
+ * It never edits a file the diff did not show, and never overwrites a file
29
+ * it proposed to create that appeared in the meantime.
30
+ */
31
+ import type { CommandContext } from "../cli/registry.js";
32
+ import type { WorkspaceDiagnostic } from "./checks.js";
33
+ import { STUB_MARKER } from "./ci-workflow.js";
34
+ export { STUB_MARKER };
35
+ import { type CiWorkflow } from "./declaration.js";
36
+ import { type SecurityGroup } from "./security.js";
37
+ import { type ReleaseWorkflowForge } from "./release-workflow.js";
38
+ /** The environments a config with none is given. */
39
+ export declare const DEFAULT_ENVIRONMENTS: readonly ["staging", "prod"];
40
+ /** One file the proposal writes: created when `before` is null. */
41
+ export interface ProposedFile {
42
+ path: string;
43
+ before: string | null;
44
+ after: string;
45
+ }
46
+ /** A generator the proposal runs after the edits, in `cwd` (relative to the workspace root). */
47
+ export interface ProposedCommand {
48
+ cwd: string;
49
+ args: string[];
50
+ why: string;
51
+ }
52
+ export interface CiInitProposal {
53
+ files: ProposedFile[];
54
+ commands: ProposedCommand[];
55
+ /** What the proposal leaves to a person, such as a component with no gate. */
56
+ notes: string[];
57
+ /** The WSP151 findings the proposal answers. */
58
+ findings: WorkspaceDiagnostic[];
59
+ }
60
+ export interface CiInitOptions {
61
+ workflow: CiWorkflow;
62
+ forge?: ReleaseWorkflowForge;
63
+ security?: readonly SecurityGroup[];
64
+ }
65
+ /** The forge whose pipeline files the repository has, or null. */
66
+ export declare function inferForge(repoRoot: string): ReleaseWorkflowForge | null;
67
+ /** The branch `origin/HEAD` names, else `main`. */
68
+ export declare function inferTrunk(repoRoot: string): string;
69
+ /**
70
+ * A `ci.green` block from the repository's GitHub workflows: a phase per
71
+ * workflow holding its jobs' check runs, all required, and those a pull
72
+ * request runs as `preMerge`. chant's own generated workflows are left out.
73
+ */
74
+ export declare function inferGreen(repoRoot: string): {
75
+ branch: string;
76
+ phases: Record<string, string[]>;
77
+ require: string[];
78
+ preMerge: string[];
79
+ };
80
+ /**
81
+ * The declaration's text with `next`'s top-level keys. A key the file lacks
82
+ * is added as text before the closing brace, so the rest keeps its layout; a
83
+ * key it has whose value changes rewrites the file, two-space indented.
84
+ */
85
+ export declare function editDeclarationText(text: string, raw: Record<string, unknown>, next: Record<string, unknown>): string;
86
+ /** The component stub for a member that declares none: a gate and a TODO, so WSP151 keeps asking until it is filled in. */
87
+ export declare function componentStub(member: string, lastEnvironment: string): string;
88
+ /** The config with `environments` added after `export default {`, or null when its default export is not a plain object literal. */
89
+ export declare function withEnvironments(config: string, environments?: readonly string[]): string | null;
90
+ /**
91
+ * What `chant ci init` would write for the workspace at `root`, and the
92
+ * generators it would run. Reads only; {@link applyCiInit} writes.
93
+ */
94
+ export declare function proposeCiInit(root: string, options: CiInitOptions): CiInitProposal;
95
+ /** A unified-style diff of two texts, for the proposal. Line-based, from their longest common subsequence. */
96
+ export declare function lineDiff(path: string, before: string | null, after: string): string;
97
+ /** Write the proposal's files. A file it would create that now exists is refused, and nothing is written. */
98
+ export declare function applyCiInit(root: string, proposal: CiInitProposal): string[];
99
+ export declare function runCiInit(ctx: CommandContext): Promise<number>;
100
+ //# sourceMappingURL=ci-init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ci-init.d.ts","sourceRoot":"","sources":["../../src/workspace/ci-init.ts"],"names":[],"mappings":"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"}