@brainervirus/workit-core 0.10.0 → 1.0.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.
- package/README.md +5 -3
- package/package.json +8 -3
- package/scripts/analyze-release-scope.ts +4 -1
- package/scripts/doctor-check.ts +3 -1
- package/scripts/install-codex-plugin.sh +28 -0
- package/scripts/install-cursor-plugin.sh +1 -0
- package/scripts/install-opencode-plugin.sh +1 -0
- package/scripts/install-pi-package.sh +56 -0
- package/scripts/rewrite-workspace-deps.ts +22 -5
- package/scripts/sync-release-manifests.ts +8 -5
- package/scripts/sync-runtime.sh +7 -3
- package/scripts/validate-cursor-marketplace.ts +16 -62
- package/skills/workit-babysit/SKILL.md +33 -0
- package/skills/workit-behavioral-tdd/SKILL.md +53 -0
- package/skills/workit-blast-radius/SKILL.md +31 -0
- package/skills/workit-challenge/SKILL.md +62 -0
- package/skills/workit-debug/SKILL.md +61 -0
- package/skills/workit-deslop/SKILL.md +36 -0
- package/skills/workit-diagram/SKILL.md +32 -0
- package/skills/workit-green-run/SKILL.md +29 -0
- package/skills/workit-handoff/SKILL.md +43 -0
- package/skills/workit-implement/SKILL.md +46 -0
- package/skills/workit-mockup/SKILL.md +28 -0
- package/skills/workit-plan/SKILL.md +66 -0
- package/skills/workit-review/SKILL.md +60 -0
- package/skills/workit-steer/SKILL.md +32 -0
- package/src/core/authority.ts +918 -0
- package/src/core/boundary.ts +29 -0
- package/src/core/branch.ts +26 -255
- package/src/core/changelog.ts +95 -18
- package/src/core/commit-flavors.ts +65 -0
- package/src/core/config-conversion.ts +183 -0
- package/src/core/config.ts +42 -0
- package/src/core/cutover.ts +721 -0
- package/src/core/detect-hosts.ts +107 -0
- package/src/core/doctor.ts +428 -18
- package/src/core/external-action-effects.ts +1171 -0
- package/src/core/external-action.ts +541 -0
- package/src/core/init.ts +83 -32
- package/src/core/methods.ts +125 -0
- package/src/core/policy-resolver.ts +523 -0
- package/src/core/pr-create.ts +7 -1
- package/src/core/registration.ts +69 -4
- package/src/core/repo-context.ts +59 -1
- package/src/core/setup.ts +28 -0
- package/src/core/skill-manifests.ts +40 -42
- package/src/core/support-matrix.ts +8 -3
- package/src/core/sync-runtime.ts +15 -3
- package/src/core/task-context.ts +179 -0
- package/src/core/task-contract.ts +1136 -0
- package/src/core/task-engine.ts +2562 -0
- package/src/core/task-evaluation.ts +679 -0
- package/src/core/task-store.ts +1071 -0
- package/src/core/tracker-issues.ts +237 -0
- package/src/core/uninstall.ts +67 -3
- package/src/core/vcs-config.ts +53 -22
- package/src/core/workers.ts +166 -0
- package/src/core/workspaces.ts +3 -1
- package/src/core/youtrack-tools.ts +2 -0
- package/src/core/youtrack.ts +145 -10
- package/src/core.ts +126 -0
- package/templates/execution-contract.md +17 -50
- package/templates/plan-template.md +3 -3
- package/templates/spec-template.md +15 -3
- package/templates/workit-contract.md +12 -0
- package/commands/wk-changelog.md +0 -2
- package/commands/wk-commit.md +0 -2
- package/commands/wk-docs-refresh.md +0 -2
- package/commands/wk-handoff.md +0 -2
- package/commands/wk-implement.md +0 -2
- package/commands/wk-init.md +0 -2
- package/commands/wk-issue-update.md +0 -2
- package/commands/wk-meetings.md +0 -2
- package/commands/wk-pr.md +0 -2
- package/commands/wk-release-notes.md +0 -2
- package/commands/wk-status.md +0 -2
- package/commands/wk-verify.md +0 -2
- package/scripts/update-superpowers.sh +0 -82
- package/scripts/vendor-assets.ts +0 -37
- package/skills/wk-changelog/SKILL.md +0 -15
- package/skills/wk-commit/SKILL.md +0 -16
- package/skills/wk-docs-refresh/SKILL.md +0 -15
- package/skills/wk-handoff/SKILL.md +0 -20
- package/skills/wk-implement/SKILL.md +0 -47
- package/skills/wk-init/SKILL.md +0 -31
- package/skills/wk-issue-update/SKILL.md +0 -27
- package/skills/wk-issue-update/references/youtrack-update-style.md +0 -81
- package/skills/wk-meetings/SKILL.md +0 -17
- package/skills/wk-pr/SKILL.md +0 -27
- package/skills/wk-release-notes/SKILL.md +0 -15
- package/skills/wk-status/SKILL.md +0 -16
- package/skills/wk-verify/SKILL.md +0 -16
- package/src/core/detector.ts +0 -239
- package/src/core/flow-state.ts +0 -3048
- package/src/core/handoff-context.ts +0 -136
- package/src/core/handoff-tools.ts +0 -133
- package/src/core/menu.ts +0 -70
- package/src/core/plan-tasks.ts +0 -43
- package/src/core/reminder.ts +0 -124
- package/src/core/sdd.ts +0 -353
- package/src/state.ts +0 -22
- package/templates/superpowers-doc-contract.md +0 -75
- package/vendor/superpowers/skills/brainstorming/SKILL.md +0 -159
- package/vendor/superpowers/skills/brainstorming/scripts/frame-template.html +0 -213
- package/vendor/superpowers/skills/brainstorming/scripts/helper.js +0 -167
- package/vendor/superpowers/skills/brainstorming/scripts/server.cjs +0 -723
- package/vendor/superpowers/skills/brainstorming/scripts/start-server.sh +0 -209
- package/vendor/superpowers/skills/brainstorming/scripts/stop-server.sh +0 -120
- package/vendor/superpowers/skills/brainstorming/spec-document-reviewer-prompt.md +0 -49
- package/vendor/superpowers/skills/brainstorming/visual-companion.md +0 -291
- package/vendor/superpowers/skills/dispatching-parallel-agents/SKILL.md +0 -185
- package/vendor/superpowers/skills/executing-plans/SKILL.md +0 -70
- package/vendor/superpowers/skills/finishing-a-development-branch/SKILL.md +0 -241
- package/vendor/superpowers/skills/receiving-code-review/SKILL.md +0 -213
- package/vendor/superpowers/skills/requesting-code-review/SKILL.md +0 -103
- package/vendor/superpowers/skills/requesting-code-review/code-reviewer.md +0 -172
- package/vendor/superpowers/skills/subagent-driven-development/SKILL.md +0 -426
- package/vendor/superpowers/skills/subagent-driven-development/implementer-prompt.md +0 -139
- package/vendor/superpowers/skills/subagent-driven-development/scripts/review-package +0 -44
- package/vendor/superpowers/skills/subagent-driven-development/scripts/sdd-workspace +0 -22
- package/vendor/superpowers/skills/subagent-driven-development/scripts/task-brief +0 -40
- package/vendor/superpowers/skills/subagent-driven-development/task-reviewer-prompt.md +0 -188
- package/vendor/superpowers/skills/systematic-debugging/CREATION-LOG.md +0 -119
- package/vendor/superpowers/skills/systematic-debugging/SKILL.md +0 -296
- package/vendor/superpowers/skills/systematic-debugging/condition-based-waiting-example.ts +0 -158
- package/vendor/superpowers/skills/systematic-debugging/condition-based-waiting.md +0 -115
- package/vendor/superpowers/skills/systematic-debugging/defense-in-depth.md +0 -122
- package/vendor/superpowers/skills/systematic-debugging/find-polluter.sh +0 -63
- package/vendor/superpowers/skills/systematic-debugging/root-cause-tracing.md +0 -169
- package/vendor/superpowers/skills/systematic-debugging/test-academic.md +0 -14
- package/vendor/superpowers/skills/systematic-debugging/test-pressure-1.md +0 -58
- package/vendor/superpowers/skills/systematic-debugging/test-pressure-2.md +0 -68
- package/vendor/superpowers/skills/systematic-debugging/test-pressure-3.md +0 -69
- package/vendor/superpowers/skills/test-driven-development/SKILL.md +0 -371
- package/vendor/superpowers/skills/test-driven-development/testing-anti-patterns.md +0 -299
- package/vendor/superpowers/skills/using-git-worktrees/SKILL.md +0 -202
- package/vendor/superpowers/skills/using-superpowers/SKILL.md +0 -62
- package/vendor/superpowers/skills/using-superpowers/references/antigravity-tools.md +0 -23
- package/vendor/superpowers/skills/using-superpowers/references/codex-tools.md +0 -39
- package/vendor/superpowers/skills/using-superpowers/references/pi-tools.md +0 -16
- package/vendor/superpowers/skills/verification-before-completion/SKILL.md +0 -139
- package/vendor/superpowers/skills/writing-plans/SKILL.md +0 -174
- package/vendor/superpowers/skills/writing-plans/plan-document-reviewer-prompt.md +0 -49
- package/vendor/superpowers/skills/writing-skills/SKILL.md +0 -689
- package/vendor/superpowers/skills/writing-skills/anthropic-best-practices.md +0 -1150
- package/vendor/superpowers/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +0 -189
- package/vendor/superpowers/skills/writing-skills/graphviz-conventions.dot +0 -172
- package/vendor/superpowers/skills/writing-skills/persuasion-principles.md +0 -187
- package/vendor/superpowers/skills/writing-skills/render-graphs.js +0 -168
- package/vendor/superpowers/skills/writing-skills/testing-skills-with-subagents.md +0 -384
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { isConfigObject, mergePreset, type BranchPreset, type ToolkitConfig } from "./config";
|
|
5
|
+
|
|
6
|
+
export type ConversionInput = {
|
|
7
|
+
configDir: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export type ConversionMapping = {
|
|
11
|
+
key: string;
|
|
12
|
+
from: unknown;
|
|
13
|
+
to: unknown;
|
|
14
|
+
note?: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export type ConversionUnresolved = {
|
|
18
|
+
key: string;
|
|
19
|
+
reason: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export type ConversionPreview = {
|
|
23
|
+
mappings: ConversionMapping[];
|
|
24
|
+
preserved: string[];
|
|
25
|
+
unresolved: ConversionUnresolved[];
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const REDACT_KEYS = /token|secret|password|credential/i;
|
|
29
|
+
|
|
30
|
+
const readJsonObject = (file: string): Record<string, unknown> | null => {
|
|
31
|
+
if (!existsSync(file)) return null;
|
|
32
|
+
try {
|
|
33
|
+
const parsed = JSON.parse(readFileSync(file, "utf8"));
|
|
34
|
+
return isConfigObject(parsed) ? parsed : null;
|
|
35
|
+
} catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const redactValue = (key: string, value: unknown): unknown => {
|
|
41
|
+
if (REDACT_KEYS.test(key)) return "[redacted]";
|
|
42
|
+
if (typeof value === "string" && value.length > 8 && !value.includes(" ")) return "[redacted]";
|
|
43
|
+
return value;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export const redactConversionPreview = (preview: ConversionPreview): ConversionPreview => ({
|
|
47
|
+
mappings: preview.mappings.map((m) => ({
|
|
48
|
+
...m,
|
|
49
|
+
from: redactValue(m.key, m.from),
|
|
50
|
+
to: redactValue(m.key, m.to),
|
|
51
|
+
})),
|
|
52
|
+
preserved: preview.preserved,
|
|
53
|
+
unresolved: preview.unresolved,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
export function previewConversion(input: ConversionInput): ConversionPreview {
|
|
57
|
+
const configFile = path.join(input.configDir, "config.json");
|
|
58
|
+
const config = readJsonObject(configFile);
|
|
59
|
+
const mappings: ConversionMapping[] = [];
|
|
60
|
+
const unresolved: ConversionUnresolved[] = [];
|
|
61
|
+
const preserved: string[] = [];
|
|
62
|
+
|
|
63
|
+
if (config) {
|
|
64
|
+
if (config.locale !== undefined) {
|
|
65
|
+
mappings.push({ key: "locale", from: config.locale, to: config.locale });
|
|
66
|
+
}
|
|
67
|
+
if (config.timezone !== undefined) {
|
|
68
|
+
mappings.push({ key: "timezone", from: config.timezone, to: config.timezone });
|
|
69
|
+
}
|
|
70
|
+
if (config.branchPolicy !== undefined && isConfigObject(config.branchPolicy)) {
|
|
71
|
+
const bp = config.branchPolicy as ToolkitConfig["branchPolicy"] & {
|
|
72
|
+
allowed?: string[];
|
|
73
|
+
protected?: string[];
|
|
74
|
+
};
|
|
75
|
+
const preset = (bp.preset ?? "gitflow") as BranchPreset;
|
|
76
|
+
const merged = mergePreset(
|
|
77
|
+
preset,
|
|
78
|
+
{
|
|
79
|
+
allowed: Array.isArray(bp.allowed) ? bp.allowed : undefined,
|
|
80
|
+
protectedNames: Array.isArray(bp.protected) ? bp.protected : undefined,
|
|
81
|
+
},
|
|
82
|
+
{ branchPolicy: bp },
|
|
83
|
+
);
|
|
84
|
+
mappings.push({
|
|
85
|
+
key: "branchPolicy",
|
|
86
|
+
from: config.branchPolicy,
|
|
87
|
+
to: merged,
|
|
88
|
+
note: "preset-derived allowed/protected reset through mergePreset",
|
|
89
|
+
});
|
|
90
|
+
if (preset === "custom" && Array.isArray(bp.allowed)) {
|
|
91
|
+
if (bp.allowed.includes("*")) {
|
|
92
|
+
unresolved.push({
|
|
93
|
+
key: "branchPolicy.allowed",
|
|
94
|
+
reason: 'unsupported permissive value "*" requires an explicit v1 choice',
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (config.workflowMode !== undefined) {
|
|
100
|
+
unresolved.push({
|
|
101
|
+
key: "legacyWorkflowMode",
|
|
102
|
+
reason: "0.x workflow mode has no automatic v1 equivalent; choose how to continue",
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
for (const name of ["youtrack.json", "vcs.json", "workspaces.json"]) {
|
|
108
|
+
const file = path.join(input.configDir, name);
|
|
109
|
+
if (!existsSync(file)) continue;
|
|
110
|
+
const parsed = readJsonObject(file);
|
|
111
|
+
if (parsed)
|
|
112
|
+
mappings.push({ key: name, from: parsed, to: parsed, note: "carry forward unchanged" });
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
for (const token of ["youtrack.token", "gitlab.token", "github.token"]) {
|
|
116
|
+
const file = path.join(input.configDir, token);
|
|
117
|
+
if (existsSync(file)) preserved.push(file);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return { mappings, preserved, unresolved };
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export const conversionDigest = (preview: ConversionPreview): string =>
|
|
124
|
+
createHash("sha256")
|
|
125
|
+
.update(JSON.stringify(redactConversionPreview(preview)))
|
|
126
|
+
.digest("hex");
|
|
127
|
+
|
|
128
|
+
export type ConversionApplyResult = {
|
|
129
|
+
configPath: string;
|
|
130
|
+
choicesPath: string;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
/** Apply approved conversion mappings and record explicit resolution choices. */
|
|
134
|
+
export function applyConversionConfig(
|
|
135
|
+
configDir: string,
|
|
136
|
+
preview: ConversionPreview,
|
|
137
|
+
resolutions: Record<string, string>,
|
|
138
|
+
): ConversionApplyResult {
|
|
139
|
+
const configFile = path.join(configDir, "config.json");
|
|
140
|
+
const raw = readJsonObject(configFile) ?? {};
|
|
141
|
+
const next: Record<string, unknown> = { ...raw };
|
|
142
|
+
|
|
143
|
+
for (const mapping of preview.mappings) {
|
|
144
|
+
if (mapping.key === "locale" || mapping.key === "timezone") {
|
|
145
|
+
next[mapping.key] = mapping.to;
|
|
146
|
+
}
|
|
147
|
+
if (mapping.key === "branchPolicy" && !resolutions["branchPolicy.allowed"]) {
|
|
148
|
+
next.branchPolicy = mapping.to;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (resolutions["branchPolicy.allowed"]) {
|
|
153
|
+
const bp = isConfigObject(next.branchPolicy)
|
|
154
|
+
? (next.branchPolicy as ToolkitConfig["branchPolicy"])
|
|
155
|
+
: { preset: "custom" as BranchPreset, allowed: [], protected: [] };
|
|
156
|
+
const preset = bp.preset ?? "custom";
|
|
157
|
+
next.branchPolicy = mergePreset(
|
|
158
|
+
preset,
|
|
159
|
+
{
|
|
160
|
+
allowed: resolutions["branchPolicy.allowed"]
|
|
161
|
+
.split(",")
|
|
162
|
+
.map((s) => s.trim())
|
|
163
|
+
.filter(Boolean),
|
|
164
|
+
},
|
|
165
|
+
{ branchPolicy: bp },
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (resolutions["legacyWorkflowMode"]) {
|
|
170
|
+
delete next.workflowMode;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
mkdirSync(configDir, { recursive: true });
|
|
174
|
+
writeFileSync(configFile, JSON.stringify(next, null, 2) + "\n");
|
|
175
|
+
|
|
176
|
+
const choicesPath = path.join(configDir, "cutover-choices.json");
|
|
177
|
+
writeFileSync(
|
|
178
|
+
choicesPath,
|
|
179
|
+
JSON.stringify({ resolutions, applied_at: new Date().toISOString() }, null, 2) + "\n",
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
return { configPath: configFile, choicesPath };
|
|
183
|
+
}
|
package/src/core/config.ts
CHANGED
|
@@ -11,6 +11,7 @@ import os from "node:os";
|
|
|
11
11
|
import path from "node:path";
|
|
12
12
|
import type { Logger } from "./logger";
|
|
13
13
|
import { EVENT, errorDetail } from "./boundary";
|
|
14
|
+
import type { CommitFlavorPreset } from "./commit-flavors";
|
|
14
15
|
|
|
15
16
|
// Optional diagnostic seam: adapters install their host logger so config
|
|
16
17
|
// migration and provenance events land in the same sanitized log stream.
|
|
@@ -27,6 +28,7 @@ export type ToolkitConfig = {
|
|
|
27
28
|
localeOptions: string[];
|
|
28
29
|
timezone: string;
|
|
29
30
|
branchPolicy: { preset: BranchPreset; allowed: string[]; protected: string[] };
|
|
31
|
+
commitPolicy: { preset: CommitFlavorPreset; pattern?: string };
|
|
30
32
|
};
|
|
31
33
|
|
|
32
34
|
export const PRESETS: Record<BranchPreset, { allowed: string[]; protected: string[] }> = {
|
|
@@ -135,6 +137,7 @@ const DEFAULTS: ToolkitConfig = {
|
|
|
135
137
|
allowed: [...PRESETS.gitflow.allowed],
|
|
136
138
|
protected: [...PRESETS.gitflow.protected],
|
|
137
139
|
},
|
|
140
|
+
commitPolicy: { preset: "conventional" },
|
|
138
141
|
};
|
|
139
142
|
|
|
140
143
|
const readSafe = (p: string): string | null => {
|
|
@@ -183,6 +186,11 @@ const parseConfigResult = (raw: string | null, file: string): ReaderResult<Toolk
|
|
|
183
186
|
? input.branchPolicy?.preset
|
|
184
187
|
: "gitflow"
|
|
185
188
|
) as BranchPreset;
|
|
189
|
+
const commitPreset = (
|
|
190
|
+
COMMIT_PRESETS.includes(String(input.commitPolicy?.preset ?? ""))
|
|
191
|
+
? input.commitPolicy?.preset
|
|
192
|
+
: "conventional"
|
|
193
|
+
) as CommitFlavorPreset;
|
|
186
194
|
return {
|
|
187
195
|
status: "valid",
|
|
188
196
|
path: file,
|
|
@@ -206,6 +214,12 @@ const parseConfigResult = (raw: string | null, file: string): ReaderResult<Toolk
|
|
|
206
214
|
},
|
|
207
215
|
DEFAULTS,
|
|
208
216
|
),
|
|
217
|
+
commitPolicy: {
|
|
218
|
+
preset: commitPreset,
|
|
219
|
+
...(typeof input.commitPolicy?.pattern === "string"
|
|
220
|
+
? { pattern: input.commitPolicy.pattern }
|
|
221
|
+
: {}),
|
|
222
|
+
},
|
|
209
223
|
},
|
|
210
224
|
};
|
|
211
225
|
};
|
|
@@ -236,6 +250,7 @@ export type ConfigInput = {
|
|
|
236
250
|
preset?: BranchPreset;
|
|
237
251
|
allowed?: string[];
|
|
238
252
|
protectedNames?: string[];
|
|
253
|
+
commitPolicy?: ToolkitConfig["commitPolicy"];
|
|
239
254
|
};
|
|
240
255
|
|
|
241
256
|
// RL-02: the single authoritative ToolkitConfig merge. CLI, OpenCode, and Cursor
|
|
@@ -246,6 +261,7 @@ export const mergeConfigValues = (input: ConfigInput, current: ToolkitConfig): T
|
|
|
246
261
|
localeOptions: input.localeOptions ?? current.localeOptions,
|
|
247
262
|
timezone: input.timezone ?? current.timezone,
|
|
248
263
|
branchPolicy: mergePreset(input.preset ?? current.branchPolicy.preset, input, current),
|
|
264
|
+
commitPolicy: input.commitPolicy ?? current.commitPolicy,
|
|
249
265
|
});
|
|
250
266
|
|
|
251
267
|
export const writeConfig = (config: ToolkitConfig): void => {
|
|
@@ -315,3 +331,29 @@ export const resolveBranchPolicy = (
|
|
|
315
331
|
preset === "github-flow" ? "main" : preset === "trunk-based" ? "master" : "develop",
|
|
316
332
|
};
|
|
317
333
|
};
|
|
334
|
+
|
|
335
|
+
const COMMIT_PRESETS: readonly string[] = [
|
|
336
|
+
"conventional",
|
|
337
|
+
"gitmoji",
|
|
338
|
+
"ticket-prefix",
|
|
339
|
+
"freeform",
|
|
340
|
+
"custom",
|
|
341
|
+
"auto",
|
|
342
|
+
];
|
|
343
|
+
|
|
344
|
+
/** Workspace commitPolicy override wins, else global — mirrors
|
|
345
|
+
* resolveBranchPolicy's workspace > global order, including the invalid-preset
|
|
346
|
+
* fallback instead of a crash. */
|
|
347
|
+
export const resolveCommitPolicy = (
|
|
348
|
+
config: ToolkitConfig,
|
|
349
|
+
workspace?: { commitPolicy?: Record<string, any> } | null,
|
|
350
|
+
): { preset: CommitFlavorPreset; pattern?: string } => {
|
|
351
|
+
const wp = (workspace?.commitPolicy ?? {}) as Record<string, any>;
|
|
352
|
+
if (COMMIT_PRESETS.includes(String(wp.preset ?? ""))) {
|
|
353
|
+
return {
|
|
354
|
+
preset: wp.preset as CommitFlavorPreset,
|
|
355
|
+
...(typeof wp.pattern === "string" ? { pattern: wp.pattern } : {}),
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
return config.commitPolicy ?? ({ preset: "conventional" } as ToolkitConfig["commitPolicy"]);
|
|
359
|
+
};
|