@ethlete/agent-rules 0.1.0-next.5 → 0.1.0-next.6
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/CHANGELOG.md +10 -0
- package/README.md +167 -3
- package/content/git-hooks/post-checkout.sh +10 -0
- package/content/git-hooks/pre-push.sh +5 -0
- package/content/hooks/context-warning.py +39 -11
- package/content/skills/git-flow/SKILL.md +83 -0
- package/content/skills/handoff/SKILL.md +4 -0
- package/content/skills/query/SKILL.md +17 -13
- package/package.json +12 -1
- package/src/index.js +10 -5
- package/src/index.js.map +1 -1
- package/src/lib/config.d.ts +28 -0
- package/src/lib/config.js +20 -3
- package/src/lib/config.js.map +1 -1
- package/src/lib/git-flow/build.d.ts +35 -0
- package/src/lib/git-flow/build.js +24 -0
- package/src/lib/git-flow/build.js.map +1 -0
- package/src/lib/git-flow/config.d.ts +59 -0
- package/src/lib/git-flow/config.js +50 -0
- package/src/lib/git-flow/config.js.map +1 -0
- package/src/lib/git-flow/index.d.ts +5 -0
- package/src/lib/git-flow/index.js +9 -0
- package/src/lib/git-flow/index.js.map +1 -0
- package/src/lib/git-flow/parse.d.ts +49 -0
- package/src/lib/git-flow/parse.js +274 -0
- package/src/lib/git-flow/parse.js.map +1 -0
- package/src/lib/git-flow/start.d.ts +22 -0
- package/src/lib/git-flow/start.js +24 -0
- package/src/lib/git-flow/start.js.map +1 -0
- package/src/lib/git-flow/validate.d.ts +34 -0
- package/src/lib/git-flow/validate.js +72 -0
- package/src/lib/git-flow/validate.js.map +1 -0
- package/src/lib/git-flow-command.d.ts +4 -0
- package/src/lib/git-flow-command.js +157 -0
- package/src/lib/git-flow-command.js.map +1 -0
- package/src/lib/git-flow-repair.d.ts +17 -0
- package/src/lib/git-flow-repair.js +150 -0
- package/src/lib/git-flow-repair.js.map +1 -0
- package/src/lib/git-flow-start.d.ts +20 -0
- package/src/lib/git-flow-start.js +147 -0
- package/src/lib/git-flow-start.js.map +1 -0
- package/src/lib/git.d.ts +27 -0
- package/src/lib/git.js +49 -0
- package/src/lib/git.js.map +1 -0
- package/src/lib/gitlab.d.ts +35 -0
- package/src/lib/gitlab.js +98 -0
- package/src/lib/gitlab.js.map +1 -0
- package/src/lib/jira.d.ts +28 -0
- package/src/lib/jira.js +83 -0
- package/src/lib/jira.js.map +1 -0
- package/src/lib/plan.js +20 -2
- package/src/lib/plan.js.map +1 -1
- package/src/lib/prompt.d.ts +8 -0
- package/src/lib/prompt.js +27 -0
- package/src/lib/prompt.js.map +1 -0
- package/src/lib/render.d.ts +12 -1
- package/src/lib/render.js +23 -6
- package/src/lib/render.js.map +1 -1
- package/src/lib/targets/git-hooks.d.ts +25 -0
- package/src/lib/targets/git-hooks.js +70 -0
- package/src/lib/targets/git-hooks.js.map +1 -0
package/src/lib/config.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.loadConfig = exports.detectTargets = exports.readLocalConfig = exports.LOCAL_CONFIG_FILE_NAME = exports.CONFIG_FILE_NAME = exports.AGENT_TARGETS = void 0;
|
|
4
4
|
const fs_1 = require("fs");
|
|
5
5
|
const path_1 = require("path");
|
|
6
|
+
const git_flow_1 = require("./git-flow");
|
|
6
7
|
const load_content_1 = require("./load-content");
|
|
7
8
|
exports.AGENT_TARGETS = ['claude', 'codex', 'cursor', 'copilot'];
|
|
8
9
|
exports.CONFIG_FILE_NAME = 'ethlete-agents.config.json';
|
|
@@ -13,7 +14,7 @@ const readRawConfig = (root) => {
|
|
|
13
14
|
return {};
|
|
14
15
|
return JSON.parse((0, fs_1.readFileSync)(path, 'utf8'));
|
|
15
16
|
};
|
|
16
|
-
const LOCAL_CONFIG_KEYS = ['disableHooks', 'disableAutoHandoffSave', 'sdkSourcePath'];
|
|
17
|
+
const LOCAL_CONFIG_KEYS = ['disableHooks', 'disableAutoHandoffSave', 'sdkSourcePath', 'jira'];
|
|
17
18
|
const readLocalConfig = (root) => {
|
|
18
19
|
const path = (0, path_1.join)(root, exports.LOCAL_CONFIG_FILE_NAME);
|
|
19
20
|
if (!(0, fs_1.existsSync)(path))
|
|
@@ -55,21 +56,37 @@ const assertKnownTargets = (targets) => {
|
|
|
55
56
|
throw new Error(`Unknown target(s): ${unknown.join(', ')}. Known targets: ${exports.AGENT_TARGETS.join(', ')}.`);
|
|
56
57
|
}
|
|
57
58
|
};
|
|
59
|
+
/**
|
|
60
|
+
* The git-flow skill interpolates the grammar it teaches from the same `gitFlow` block the
|
|
61
|
+
* validator reads, so the documented convention cannot drift from the enforced one. A repo can
|
|
62
|
+
* still override any of these through `vars`.
|
|
63
|
+
*/
|
|
64
|
+
const gitFlowVars = (gitFlow) => ({
|
|
65
|
+
gitFlowDevelopmentBranch: gitFlow.baseBranches.development,
|
|
66
|
+
gitFlowProductionBranch: gitFlow.baseBranches.production,
|
|
67
|
+
gitFlowTypes: gitFlow.types,
|
|
68
|
+
gitFlowEnforcement: gitFlow.enforcement,
|
|
69
|
+
gitFlowSubPrefix: gitFlow.subPrefix,
|
|
70
|
+
});
|
|
58
71
|
const loadConfig = (options) => {
|
|
59
|
-
var _a, _b, _c, _d, _e;
|
|
72
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
60
73
|
const { root, targetOverride } = options;
|
|
61
74
|
const raw = readRawConfig(root);
|
|
62
75
|
const configured = raw.targets && raw.targets !== 'auto' ? raw.targets : undefined;
|
|
63
76
|
const targets = (_a = targetOverride !== null && targetOverride !== void 0 ? targetOverride : configured) !== null && _a !== void 0 ? _a : (0, exports.detectTargets)(root);
|
|
77
|
+
const gitFlow = (0, git_flow_1.resolveGitFlowConfig)(raw.gitFlow);
|
|
64
78
|
assertKnownTargets(targets);
|
|
65
79
|
return {
|
|
66
80
|
root,
|
|
67
81
|
targets,
|
|
68
82
|
scopes: raw.profile === 'sdk' ? ['both'] : ['consumer', 'both'],
|
|
69
|
-
vars: Object.assign(Object.assign({}, (0, load_content_1.loadDefaultVars)()), ((_b = raw.vars) !== null && _b !== void 0 ? _b : {})),
|
|
83
|
+
vars: Object.assign(Object.assign(Object.assign({}, (0, load_content_1.loadDefaultVars)()), gitFlowVars(gitFlow)), ((_b = raw.vars) !== null && _b !== void 0 ? _b : {})),
|
|
70
84
|
exclude: (_c = raw.exclude) !== null && _c !== void 0 ? _c : [],
|
|
71
85
|
claudeMdImportsAgentsMd: (_d = raw.claudeMdImportsAgentsMd) !== null && _d !== void 0 ? _d : false,
|
|
72
86
|
hooks: (_e = raw.hooks) !== null && _e !== void 0 ? _e : [],
|
|
87
|
+
gitHooks: (_f = raw.gitHooks) !== null && _f !== void 0 ? _f : [],
|
|
88
|
+
gitFlow,
|
|
89
|
+
jira: (_g = raw.jira) !== null && _g !== void 0 ? _g : {},
|
|
73
90
|
};
|
|
74
91
|
};
|
|
75
92
|
exports.loadConfig = loadConfig;
|
package/src/lib/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../../libs/agent-rules/src/lib/config.ts"],"names":[],"mappings":";;;AAAA,2BAA8C;AAC9C,+BAA4B;AAE5B,iDAAiD;AAEpC,QAAA,aAAa,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAU,CAAC;AAIlE,QAAA,gBAAgB,GAAG,4BAA4B,CAAC;AAEhD,QAAA,sBAAsB,GAAG,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../../libs/agent-rules/src/lib/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { GitFlowConfig } from './config';
|
|
2
|
+
export declare const slugifySubject: (subject: string) => string;
|
|
3
|
+
/**
|
|
4
|
+
* `parent` is the full branch name the new branch nests under — `feat/FIP-2177-user-management`
|
|
5
|
+
* for a sub-feature, `release/2026.04.28` for a release fix. The nested name keeps that whole path
|
|
6
|
+
* under the config's `subPrefix`, so the parent stays derivable from the child.
|
|
7
|
+
*/
|
|
8
|
+
export type BranchNameSpec = {
|
|
9
|
+
kind: 'main-feature';
|
|
10
|
+
type?: string;
|
|
11
|
+
key: string;
|
|
12
|
+
subject: string;
|
|
13
|
+
} | {
|
|
14
|
+
kind: 'sub-feature';
|
|
15
|
+
parent: string;
|
|
16
|
+
key: string;
|
|
17
|
+
subject: string;
|
|
18
|
+
} | {
|
|
19
|
+
kind: 'release';
|
|
20
|
+
date: string;
|
|
21
|
+
} | {
|
|
22
|
+
kind: 'release-fix';
|
|
23
|
+
parent: string;
|
|
24
|
+
key: string;
|
|
25
|
+
subject: string;
|
|
26
|
+
} | {
|
|
27
|
+
kind: 'hotfix';
|
|
28
|
+
key: string;
|
|
29
|
+
subject: string;
|
|
30
|
+
};
|
|
31
|
+
/** Builds a conforming branch name from the grammar. The single naming implementation. */
|
|
32
|
+
export declare const buildBranchName: (options: {
|
|
33
|
+
spec: BranchNameSpec;
|
|
34
|
+
config: GitFlowConfig;
|
|
35
|
+
}) => string;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildBranchName = exports.slugifySubject = void 0;
|
|
4
|
+
const slugifySubject = (subject) => subject
|
|
5
|
+
.trim()
|
|
6
|
+
.toLowerCase()
|
|
7
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
8
|
+
.replace(/^-+|-+$/g, '');
|
|
9
|
+
exports.slugifySubject = slugifySubject;
|
|
10
|
+
/** Builds a conforming branch name from the grammar. The single naming implementation. */
|
|
11
|
+
const buildBranchName = (options) => {
|
|
12
|
+
var _a;
|
|
13
|
+
const { spec, config } = options;
|
|
14
|
+
if (spec.kind === 'release')
|
|
15
|
+
return `${config.releasePrefix}/${spec.date}`;
|
|
16
|
+
const leaf = [spec.key.toUpperCase(), (0, exports.slugifySubject)(spec.subject)].filter(Boolean).join('-');
|
|
17
|
+
if (spec.kind === 'main-feature')
|
|
18
|
+
return `${(_a = spec.type) !== null && _a !== void 0 ? _a : 'feat'}/${leaf}`;
|
|
19
|
+
if (spec.kind === 'hotfix')
|
|
20
|
+
return `${config.hotfixPrefix}/${leaf}`;
|
|
21
|
+
return `${config.subPrefix}/${spec.parent}/${leaf}`;
|
|
22
|
+
};
|
|
23
|
+
exports.buildBranchName = buildBranchName;
|
|
24
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../../../../../libs/agent-rules/src/lib/git-flow/build.ts"],"names":[],"mappings":";;;AAEO,MAAM,cAAc,GAAG,CAAC,OAAe,EAAE,EAAE,CAChD,OAAO;KACJ,IAAI,EAAE;KACN,WAAW,EAAE;KACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;KAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AALhB,QAAA,cAAc,kBAKE;AAc7B,0FAA0F;AACnF,MAAM,eAAe,GAAG,CAAC,OAAwD,EAAE,EAAE;;IAC1F,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAEjC,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,GAAG,MAAM,CAAC,aAAa,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;IAE3E,MAAM,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,EAAE,IAAA,sBAAc,EAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAE9F,IAAI,IAAI,CAAC,IAAI,KAAK,cAAc;QAAE,OAAO,GAAG,MAAA,IAAI,CAAC,IAAI,mCAAI,MAAM,IAAI,IAAI,EAAE,CAAC;IAC1E,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,GAAG,MAAM,CAAC,YAAY,IAAI,IAAI,EAAE,CAAC;IAEpE,OAAO,GAAG,MAAM,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,EAAE,CAAC;AACtD,CAAC,CAAC;AAXW,QAAA,eAAe,mBAW1B"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The branch grammar as data: one config drives the parser, the validators, the CLI, the generated
|
|
3
|
+
* skill and `@ethlete/timetrack`'s correlation engine.
|
|
4
|
+
*
|
|
5
|
+
* Nothing in this folder may import `fs`, `path` or `process`, or take a dependency — it is
|
|
6
|
+
* reachable as `@ethlete/agent-rules/git-flow` and gets bundled into a browser webview.
|
|
7
|
+
*/
|
|
8
|
+
export declare const GIT_FLOW_RULES: readonly ["unknown-type", "missing-key", "key-case", "missing-subject", "type-alias", "deprecated-prefix", "release-date", "wrong-mr-target", "protected-push"];
|
|
9
|
+
export type GitFlowRule = (typeof GIT_FLOW_RULES)[number];
|
|
10
|
+
export type GitFlowSeverity = 'off' | 'warn' | 'error';
|
|
11
|
+
export type GitFlowEnforcement = 'advisory' | 'gated';
|
|
12
|
+
export type GitFlowBranchKind = 'main-feature' | 'sub-feature' | 'release' | 'release-fix' | 'hotfix' | 'protected' | 'unknown';
|
|
13
|
+
/**
|
|
14
|
+
* A legacy spelling that means one of the known kinds. `match` is a regular expression whose
|
|
15
|
+
* `subject` and `key` named groups feed `renameTo`, in which `<subject>` and `<KEY>` are the
|
|
16
|
+
* placeholders — an unresolved `<KEY>` is left in place, because only Jira can supply it.
|
|
17
|
+
*/
|
|
18
|
+
export type GitFlowDeprecatedShape = {
|
|
19
|
+
match: string;
|
|
20
|
+
kind: GitFlowBranchKind;
|
|
21
|
+
renameTo: string;
|
|
22
|
+
};
|
|
23
|
+
export type GitFlowConfig = {
|
|
24
|
+
enforcement: GitFlowEnforcement;
|
|
25
|
+
/**
|
|
26
|
+
* The segment a nested branch is prefixed with. Git refuses a ref that is both a branch and a
|
|
27
|
+
* directory of branches, so a sub-feature cannot be spelled `<parent>/<KEY>-<subject>` while its
|
|
28
|
+
* parent exists — the push is rejected with "refname conflict". The prefix moves the whole nested
|
|
29
|
+
* tree out of the way while keeping the parent's full path inside the child's name.
|
|
30
|
+
*/
|
|
31
|
+
subPrefix: string;
|
|
32
|
+
keyPattern: string;
|
|
33
|
+
/**
|
|
34
|
+
* Project prefixes a key may use, e.g. `["FIP"]`. Empty accepts anything `keyPattern` matches,
|
|
35
|
+
* which also accepts `chore/angular-22` as issue ANGULAR-22 — set this in any repo whose
|
|
36
|
+
* branch subjects can start with a word followed by a number.
|
|
37
|
+
*/
|
|
38
|
+
keyPrefixes: string[];
|
|
39
|
+
baseBranches: {
|
|
40
|
+
development: string;
|
|
41
|
+
production: string;
|
|
42
|
+
};
|
|
43
|
+
types: string[];
|
|
44
|
+
typeAliases: Record<string, string>;
|
|
45
|
+
releasePrefix: string;
|
|
46
|
+
releasePattern: string;
|
|
47
|
+
hotfixPrefix: string;
|
|
48
|
+
subjectCase: 'kebab';
|
|
49
|
+
deprecatedShapes: GitFlowDeprecatedShape[];
|
|
50
|
+
severity: Record<GitFlowRule, GitFlowSeverity>;
|
|
51
|
+
};
|
|
52
|
+
export declare const DEFAULT_GIT_FLOW_CONFIG: GitFlowConfig;
|
|
53
|
+
export type RawGitFlowConfig = Partial<Omit<GitFlowConfig, 'baseBranches' | 'typeAliases' | 'severity'>> & {
|
|
54
|
+
baseBranches?: Partial<GitFlowConfig['baseBranches']>;
|
|
55
|
+
typeAliases?: Record<string, string>;
|
|
56
|
+
severity?: Partial<Record<GitFlowRule, GitFlowSeverity>>;
|
|
57
|
+
};
|
|
58
|
+
/** Fills a repo's `gitFlow` config block out to a complete grammar. */
|
|
59
|
+
export declare const resolveGitFlowConfig: (raw?: RawGitFlowConfig) => GitFlowConfig;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The branch grammar as data: one config drives the parser, the validators, the CLI, the generated
|
|
4
|
+
* skill and `@ethlete/timetrack`'s correlation engine.
|
|
5
|
+
*
|
|
6
|
+
* Nothing in this folder may import `fs`, `path` or `process`, or take a dependency — it is
|
|
7
|
+
* reachable as `@ethlete/agent-rules/git-flow` and gets bundled into a browser webview.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.resolveGitFlowConfig = exports.DEFAULT_GIT_FLOW_CONFIG = exports.GIT_FLOW_RULES = void 0;
|
|
11
|
+
exports.GIT_FLOW_RULES = [
|
|
12
|
+
'unknown-type',
|
|
13
|
+
'missing-key',
|
|
14
|
+
'key-case',
|
|
15
|
+
'missing-subject',
|
|
16
|
+
'type-alias',
|
|
17
|
+
'deprecated-prefix',
|
|
18
|
+
'release-date',
|
|
19
|
+
'wrong-mr-target',
|
|
20
|
+
'protected-push',
|
|
21
|
+
];
|
|
22
|
+
exports.DEFAULT_GIT_FLOW_CONFIG = {
|
|
23
|
+
enforcement: 'advisory',
|
|
24
|
+
subPrefix: 'sub',
|
|
25
|
+
keyPattern: '[A-Z]{2,10}-\\d+',
|
|
26
|
+
keyPrefixes: [],
|
|
27
|
+
baseBranches: { development: 'next', production: 'main' },
|
|
28
|
+
types: ['feat', 'fix', 'refactor', 'chore', 'docs', 'perf', 'test', 'style', 'build', 'ci'],
|
|
29
|
+
typeAliases: { feature: 'feat', bugfix: 'fix' },
|
|
30
|
+
releasePrefix: 'release',
|
|
31
|
+
releasePattern: '\\d{4}\\.\\d{2}\\.\\d{2}',
|
|
32
|
+
hotfixPrefix: 'hotfix',
|
|
33
|
+
subjectCase: 'kebab',
|
|
34
|
+
deprecatedShapes: [{ match: '^dev-(?<subject>.+)$', kind: 'main-feature', renameTo: 'feat/<KEY>-<subject>' }],
|
|
35
|
+
severity: {
|
|
36
|
+
'unknown-type': 'warn',
|
|
37
|
+
'missing-key': 'warn',
|
|
38
|
+
'key-case': 'warn',
|
|
39
|
+
'missing-subject': 'warn',
|
|
40
|
+
'type-alias': 'warn',
|
|
41
|
+
'deprecated-prefix': 'warn',
|
|
42
|
+
'release-date': 'warn',
|
|
43
|
+
'wrong-mr-target': 'warn',
|
|
44
|
+
'protected-push': 'error',
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
/** Fills a repo's `gitFlow` config block out to a complete grammar. */
|
|
48
|
+
const resolveGitFlowConfig = (raw) => (Object.assign(Object.assign(Object.assign({}, exports.DEFAULT_GIT_FLOW_CONFIG), raw), { baseBranches: Object.assign(Object.assign({}, exports.DEFAULT_GIT_FLOW_CONFIG.baseBranches), raw === null || raw === void 0 ? void 0 : raw.baseBranches), typeAliases: Object.assign(Object.assign({}, exports.DEFAULT_GIT_FLOW_CONFIG.typeAliases), raw === null || raw === void 0 ? void 0 : raw.typeAliases), severity: Object.assign(Object.assign({}, exports.DEFAULT_GIT_FLOW_CONFIG.severity), raw === null || raw === void 0 ? void 0 : raw.severity) }));
|
|
49
|
+
exports.resolveGitFlowConfig = resolveGitFlowConfig;
|
|
50
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../../../libs/agent-rules/src/lib/git-flow/config.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAEU,QAAA,cAAc,GAAG;IAC5B,cAAc;IACd,aAAa;IACb,UAAU;IACV,iBAAiB;IACjB,YAAY;IACZ,mBAAmB;IACnB,cAAc;IACd,iBAAiB;IACjB,gBAAgB;CACR,CAAC;AAiDE,QAAA,uBAAuB,GAAkB;IACpD,WAAW,EAAE,UAAU;IACvB,SAAS,EAAE,KAAK;IAChB,UAAU,EAAE,kBAAkB;IAC9B,WAAW,EAAE,EAAE;IACf,YAAY,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE;IACzD,KAAK,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC;IAC3F,WAAW,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE;IAC/C,aAAa,EAAE,SAAS;IACxB,cAAc,EAAE,0BAA0B;IAC1C,YAAY,EAAE,QAAQ;IACtB,WAAW,EAAE,OAAO;IACpB,gBAAgB,EAAE,CAAC,EAAE,KAAK,EAAE,sBAAsB,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,sBAAsB,EAAE,CAAC;IAC7G,QAAQ,EAAE;QACR,cAAc,EAAE,MAAM;QACtB,aAAa,EAAE,MAAM;QACrB,UAAU,EAAE,MAAM;QAClB,iBAAiB,EAAE,MAAM;QACzB,YAAY,EAAE,MAAM;QACpB,mBAAmB,EAAE,MAAM;QAC3B,cAAc,EAAE,MAAM;QACtB,iBAAiB,EAAE,MAAM;QACzB,gBAAgB,EAAE,OAAO;KAC1B;CACF,CAAC;AAQF,uEAAuE;AAChE,MAAM,oBAAoB,GAAG,CAAC,GAAsB,EAAiB,EAAE,CAAC,+CAC1E,+BAAuB,GACvB,GAAG,KACN,YAAY,kCAAO,+BAAuB,CAAC,YAAY,GAAK,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,YAAY,GAC7E,WAAW,kCAAO,+BAAuB,CAAC,WAAW,GAAK,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,WAAW,GAC1E,QAAQ,kCAAO,+BAAuB,CAAC,QAAQ,GAAK,GAAG,aAAH,GAAG,uBAAH,GAAG,CAAE,QAAQ,KACjE,CAAC;AANU,QAAA,oBAAoB,wBAM9B"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
tslib_1.__exportStar(require("./build"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./config"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./parse"), exports);
|
|
7
|
+
tslib_1.__exportStar(require("./start"), exports);
|
|
8
|
+
tslib_1.__exportStar(require("./validate"), exports);
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../libs/agent-rules/src/lib/git-flow/index.ts"],"names":[],"mappings":";;;AAAA,kDAAwB;AACxB,mDAAyB;AACzB,kDAAwB;AACxB,kDAAwB;AACxB,qDAA2B"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { GitFlowBranchKind, GitFlowConfig, GitFlowRule } from './config';
|
|
2
|
+
export type GitFlowFinding = {
|
|
3
|
+
rule: GitFlowRule;
|
|
4
|
+
message: string;
|
|
5
|
+
/** The conforming spelling, when it can be derived without asking Jira for an issue key. */
|
|
6
|
+
suggestion?: string;
|
|
7
|
+
};
|
|
8
|
+
export type BranchParseResult = {
|
|
9
|
+
branch: string;
|
|
10
|
+
/** True only for a fully conforming name — an alias or a lowercase key still parses, but is not `ok`. */
|
|
11
|
+
ok: boolean;
|
|
12
|
+
kind: GitFlowBranchKind;
|
|
13
|
+
/** The normalized type segment (`feature/` resolves to `feat`). */
|
|
14
|
+
type?: string;
|
|
15
|
+
storyKey?: string;
|
|
16
|
+
taskKey?: string;
|
|
17
|
+
/** The most specific issue the branch names — what time should be logged against. */
|
|
18
|
+
issueKey?: string;
|
|
19
|
+
subject?: string;
|
|
20
|
+
/** The branch this one nests under, for a sub-feature or a release fix. */
|
|
21
|
+
parent?: string;
|
|
22
|
+
/** The branch matched a `deprecatedShapes` entry, so it should be excluded from adoption reports. */
|
|
23
|
+
deprecated: boolean;
|
|
24
|
+
expectedBase?: string;
|
|
25
|
+
expectedMrTargets: string[];
|
|
26
|
+
/** Set by `resolveThroughBase` when the story key came from the base branch rather than this name. */
|
|
27
|
+
inheritedFrom?: string;
|
|
28
|
+
suggestedName?: string;
|
|
29
|
+
findings: GitFlowFinding[];
|
|
30
|
+
};
|
|
31
|
+
export declare const stripRefPrefix: (ref: string) => string;
|
|
32
|
+
/**
|
|
33
|
+
* Classifies a branch name against the grammar. Never throws: an unrecognised name comes back as
|
|
34
|
+
* `kind: 'unknown'` with findings, so the validator and timetrack's correlation engine can read
|
|
35
|
+
* the same result for different purposes.
|
|
36
|
+
*/
|
|
37
|
+
export declare const parseBranch: (options: {
|
|
38
|
+
branch: string;
|
|
39
|
+
config: GitFlowConfig;
|
|
40
|
+
}) => BranchParseResult;
|
|
41
|
+
/**
|
|
42
|
+
* Attributes a keyless branch through the branch it is based on. Reviewed branches land in an
|
|
43
|
+
* integration branch, so a flat name like `feat/logout-confirmation` usually has a parent that
|
|
44
|
+
* does carry the story key. Deterministic — no model involved.
|
|
45
|
+
*/
|
|
46
|
+
export declare const resolveThroughBase: (options: {
|
|
47
|
+
branch: BranchParseResult;
|
|
48
|
+
base: BranchParseResult;
|
|
49
|
+
}) => BranchParseResult;
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveThroughBase = exports.parseBranch = exports.stripRefPrefix = void 0;
|
|
4
|
+
const build_1 = require("./build");
|
|
5
|
+
const stripRefPrefix = (ref) => ref
|
|
6
|
+
.trim()
|
|
7
|
+
.replace(/^refs\/heads\//, '')
|
|
8
|
+
.replace(/^refs\/remotes\/[^/]+\//, '');
|
|
9
|
+
exports.stripRefPrefix = stripRefPrefix;
|
|
10
|
+
/**
|
|
11
|
+
* The key is only recognised anchored at the start of a segment. A trailing number is therefore
|
|
12
|
+
* never mistaken for one — `ratings-reveal-secondary-page-27` yields no key rather than a wrong
|
|
13
|
+
* one, and a confidently wrong attribution is worse than none.
|
|
14
|
+
*/
|
|
15
|
+
const parseSegment = (options) => {
|
|
16
|
+
const { segment, config, role } = options;
|
|
17
|
+
const match = new RegExp(`^(${config.keyPattern})(?:-(.*))?$`, 'i').exec(segment);
|
|
18
|
+
const rawKey = match === null || match === void 0 ? void 0 : match[1];
|
|
19
|
+
const known = config.keyPrefixes.length === 0 ||
|
|
20
|
+
config.keyPrefixes.some((prefix) => rawKey === null || rawKey === void 0 ? void 0 : rawKey.toUpperCase().startsWith(prefix.toUpperCase()));
|
|
21
|
+
if (!rawKey || !known) {
|
|
22
|
+
return {
|
|
23
|
+
subject: segment || undefined,
|
|
24
|
+
findings: [{ rule: 'missing-key', message: `"${segment}" carries no ${role} issue key.` }],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const key = rawKey.toUpperCase();
|
|
28
|
+
const subject = (match === null || match === void 0 ? void 0 : match[2]) || undefined;
|
|
29
|
+
const findings = [];
|
|
30
|
+
if (rawKey !== key) {
|
|
31
|
+
findings.push({ rule: 'key-case', message: `Issue key "${rawKey}" should be uppercase "${key}".` });
|
|
32
|
+
}
|
|
33
|
+
if (!subject) {
|
|
34
|
+
findings.push({ rule: 'missing-subject', message: `"${segment}" names ${key} but has no subject.` });
|
|
35
|
+
}
|
|
36
|
+
return { key, subject, findings };
|
|
37
|
+
};
|
|
38
|
+
const matchDeprecatedShape = (options) => {
|
|
39
|
+
var _a;
|
|
40
|
+
const { branch, config } = options;
|
|
41
|
+
for (const shape of config.deprecatedShapes) {
|
|
42
|
+
const match = new RegExp(shape.match).exec(branch);
|
|
43
|
+
if (match)
|
|
44
|
+
return { shape, groups: (_a = match.groups) !== null && _a !== void 0 ? _a : {} };
|
|
45
|
+
}
|
|
46
|
+
return undefined;
|
|
47
|
+
};
|
|
48
|
+
const renameSuggestion = (options) => {
|
|
49
|
+
var _a;
|
|
50
|
+
const { shape, groups } = options;
|
|
51
|
+
const key = groups['key'];
|
|
52
|
+
return shape.renameTo
|
|
53
|
+
.replace(/<subject>/g, (_a = groups['subject']) !== null && _a !== void 0 ? _a : '')
|
|
54
|
+
.replace(/<KEY>/g, key ? key.toUpperCase() : '<KEY>');
|
|
55
|
+
};
|
|
56
|
+
const targetsForKind = (options) => {
|
|
57
|
+
const { kind, config, parent, branch } = options;
|
|
58
|
+
const { development, production } = config.baseBranches;
|
|
59
|
+
switch (kind) {
|
|
60
|
+
case 'main-feature':
|
|
61
|
+
return { expectedBase: development, expectedMrTargets: [development] };
|
|
62
|
+
case 'sub-feature':
|
|
63
|
+
case 'release-fix':
|
|
64
|
+
return { expectedBase: parent, expectedMrTargets: parent ? [parent] : [] };
|
|
65
|
+
case 'release':
|
|
66
|
+
return { expectedBase: development, expectedMrTargets: [development, production] };
|
|
67
|
+
case 'hotfix':
|
|
68
|
+
return { expectedBase: production, expectedMrTargets: [production] };
|
|
69
|
+
case 'protected':
|
|
70
|
+
return { expectedMrTargets: branch === development ? [production] : [development] };
|
|
71
|
+
default:
|
|
72
|
+
return { expectedMrTargets: [] };
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Classifies a branch name against the grammar. Never throws: an unrecognised name comes back as
|
|
77
|
+
* `kind: 'unknown'` with findings, so the validator and timetrack's correlation engine can read
|
|
78
|
+
* the same result for different purposes.
|
|
79
|
+
*/
|
|
80
|
+
const parseBranch = (options) => {
|
|
81
|
+
const { config } = options;
|
|
82
|
+
const branch = (0, exports.stripRefPrefix)(options.branch);
|
|
83
|
+
const segments = branch.split('/');
|
|
84
|
+
const unknown = (message) => ({
|
|
85
|
+
branch,
|
|
86
|
+
ok: false,
|
|
87
|
+
kind: 'unknown',
|
|
88
|
+
deprecated: false,
|
|
89
|
+
expectedMrTargets: [],
|
|
90
|
+
findings: [{ rule: 'unknown-type', message }],
|
|
91
|
+
});
|
|
92
|
+
if (!branch || segments.some((segment) => !segment))
|
|
93
|
+
return unknown(`"${options.branch}" is not a branch name.`);
|
|
94
|
+
if (branch === config.baseBranches.development || branch === config.baseBranches.production) {
|
|
95
|
+
return Object.assign({ branch, ok: true, kind: 'protected', deprecated: false, findings: [] }, targetsForKind({ kind: 'protected', config, branch }));
|
|
96
|
+
}
|
|
97
|
+
const deprecated = matchDeprecatedShape({ branch, config });
|
|
98
|
+
if (deprecated) {
|
|
99
|
+
const suggestion = renameSuggestion(deprecated);
|
|
100
|
+
return Object.assign({ branch, ok: false, kind: deprecated.shape.kind, subject: deprecated.groups['subject'], deprecated: true, suggestedName: suggestion, findings: [
|
|
101
|
+
{
|
|
102
|
+
rule: 'deprecated-prefix',
|
|
103
|
+
message: `"${branch}" uses a deprecated spelling; rename it to ${suggestion}.`,
|
|
104
|
+
suggestion,
|
|
105
|
+
},
|
|
106
|
+
] }, targetsForKind({ kind: deprecated.shape.kind, config }));
|
|
107
|
+
}
|
|
108
|
+
const [prefix, ...rest] = segments;
|
|
109
|
+
if (prefix === config.subPrefix)
|
|
110
|
+
return dropRedundantSuggestion(parseNested({ branch, segments: rest, config }));
|
|
111
|
+
if (prefix === config.releasePrefix)
|
|
112
|
+
return dropRedundantSuggestion(parseRelease({ branch, segments: rest, config }));
|
|
113
|
+
if (prefix === config.hotfixPrefix)
|
|
114
|
+
return dropRedundantSuggestion(parseHotfix({ branch, segments: rest, config }));
|
|
115
|
+
return dropRedundantSuggestion(parseFeature({ branch, prefix: prefix !== null && prefix !== void 0 ? prefix : '', segments: rest, config }));
|
|
116
|
+
};
|
|
117
|
+
exports.parseBranch = parseBranch;
|
|
118
|
+
const unrecognised = (options) => ({
|
|
119
|
+
branch: options.branch,
|
|
120
|
+
ok: false,
|
|
121
|
+
kind: 'unknown',
|
|
122
|
+
deprecated: false,
|
|
123
|
+
expectedMrTargets: [],
|
|
124
|
+
findings: [{ rule: 'unknown-type', message: options.message }],
|
|
125
|
+
});
|
|
126
|
+
/**
|
|
127
|
+
* `sub/<parent path>/<KEY>-<subject>` — the nested shape. The parent's full name is inside the
|
|
128
|
+
* child's, so the merge request target needs no lookup; only two levels are allowed, so a parent
|
|
129
|
+
* that is itself nested is not a shape.
|
|
130
|
+
*/
|
|
131
|
+
const parseNested = (options) => {
|
|
132
|
+
var _a, _b, _c;
|
|
133
|
+
const { branch, segments, config } = options;
|
|
134
|
+
const leaf = segments[segments.length - 1];
|
|
135
|
+
const parent = segments.slice(0, -1).join('/');
|
|
136
|
+
if (!leaf || !parent) {
|
|
137
|
+
return unrecognised({ branch, message: `"${branch}" names no parent branch to nest under.` });
|
|
138
|
+
}
|
|
139
|
+
const parentParse = (0, exports.parseBranch)({ branch: parent, config });
|
|
140
|
+
const kind = nestedKindFor(parentParse);
|
|
141
|
+
if (!kind) {
|
|
142
|
+
return unrecognised({
|
|
143
|
+
branch,
|
|
144
|
+
message: `"${parent}" is not a branch anything can nest under — only a main feature or a release branch is.`,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
const parts = parseSegment({ segment: leaf, config, role: kind === 'release-fix' ? 'bug' : 'task' });
|
|
148
|
+
const findings = [...parentParse.findings, ...parts.findings];
|
|
149
|
+
return Object.assign({ branch, ok: findings.length === 0, type: parentParse.type, kind, storyKey: parentParse.storyKey, taskKey: parts.key, issueKey: (_a = parts.key) !== null && _a !== void 0 ? _a : parentParse.storyKey, subject: parts.subject, parent, deprecated: false, findings, suggestedName: parts.key
|
|
150
|
+
? (0, build_1.buildBranchName)({
|
|
151
|
+
spec: { kind, parent: (_b = parentParse.suggestedName) !== null && _b !== void 0 ? _b : parent, key: parts.key, subject: (_c = parts.subject) !== null && _c !== void 0 ? _c : '' },
|
|
152
|
+
config,
|
|
153
|
+
})
|
|
154
|
+
: undefined }, targetsForKind({ kind, config, parent }));
|
|
155
|
+
};
|
|
156
|
+
const nestedKindFor = (parent) => {
|
|
157
|
+
if (parent.kind === 'release')
|
|
158
|
+
return 'release-fix';
|
|
159
|
+
return parent.kind === 'main-feature' && !parent.deprecated ? 'sub-feature' : undefined;
|
|
160
|
+
};
|
|
161
|
+
/**
|
|
162
|
+
* The spelling the convention was originally written with, `<parent>/<KEY>-<subject>`. It parses so
|
|
163
|
+
* that `explain` and `repair` can say something useful about it, but it can never exist next to the
|
|
164
|
+
* parent it names — see `subPrefix`.
|
|
165
|
+
*/
|
|
166
|
+
const nestedTooDeep = (options) => {
|
|
167
|
+
var _a, _b;
|
|
168
|
+
const { branch, kind, parent, leaf, config, storyKey, type } = options;
|
|
169
|
+
const suggestion = leaf.key
|
|
170
|
+
? (0, build_1.buildBranchName)({ spec: { kind, parent, key: leaf.key, subject: (_a = leaf.subject) !== null && _a !== void 0 ? _a : '' }, config })
|
|
171
|
+
: `${config.subPrefix}/${branch}`;
|
|
172
|
+
return Object.assign({ branch, ok: false, kind,
|
|
173
|
+
type,
|
|
174
|
+
storyKey, taskKey: leaf.key, issueKey: (_b = leaf.key) !== null && _b !== void 0 ? _b : storyKey, subject: leaf.subject, parent, deprecated: true, suggestedName: suggestion, findings: [
|
|
175
|
+
{
|
|
176
|
+
rule: 'deprecated-prefix',
|
|
177
|
+
message: `"${branch}" cannot exist while ${parent} does — git rejects a ref that is both a branch and a directory of branches. Use ${suggestion}.`,
|
|
178
|
+
suggestion,
|
|
179
|
+
},
|
|
180
|
+
] }, targetsForKind({ kind, config, parent }));
|
|
181
|
+
};
|
|
182
|
+
const dropRedundantSuggestion = (result) => result.suggestedName === result.branch ? Object.assign(Object.assign({}, result), { suggestedName: undefined }) : result;
|
|
183
|
+
const parseRelease = (options) => {
|
|
184
|
+
const { branch, segments, config } = options;
|
|
185
|
+
const [date, leaf, ...extra] = segments;
|
|
186
|
+
if (!date || extra.length > 0) {
|
|
187
|
+
return unrecognised({ branch, message: `"${branch}" is not a release or release-fix branch.` });
|
|
188
|
+
}
|
|
189
|
+
const findings = [];
|
|
190
|
+
if (!new RegExp(`^${config.releasePattern}$`).test(date)) {
|
|
191
|
+
findings.push({ rule: 'release-date', message: `"${date}" is not a release date (expected YYYY.MM.DD).` });
|
|
192
|
+
}
|
|
193
|
+
const parent = `${config.releasePrefix}/${date}`;
|
|
194
|
+
if (leaf === undefined) {
|
|
195
|
+
return Object.assign({ branch, ok: findings.length === 0, kind: 'release', deprecated: false, findings }, targetsForKind({ kind: 'release', config }));
|
|
196
|
+
}
|
|
197
|
+
return nestedTooDeep({
|
|
198
|
+
branch,
|
|
199
|
+
kind: 'release-fix',
|
|
200
|
+
parent,
|
|
201
|
+
leaf: parseSegment({ segment: leaf, config, role: 'bug' }),
|
|
202
|
+
config,
|
|
203
|
+
});
|
|
204
|
+
};
|
|
205
|
+
const parseHotfix = (options) => {
|
|
206
|
+
var _a;
|
|
207
|
+
const { branch, segments, config } = options;
|
|
208
|
+
const [leaf, ...extra] = segments;
|
|
209
|
+
if (!leaf || extra.length > 0) {
|
|
210
|
+
return {
|
|
211
|
+
branch,
|
|
212
|
+
ok: false,
|
|
213
|
+
kind: 'unknown',
|
|
214
|
+
deprecated: false,
|
|
215
|
+
expectedMrTargets: [],
|
|
216
|
+
findings: [{ rule: 'unknown-type', message: `"${branch}" is not a hotfix branch.` }],
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
const parts = parseSegment({ segment: leaf, config, role: 'bug' });
|
|
220
|
+
return Object.assign({ branch, ok: parts.findings.length === 0, kind: 'hotfix', taskKey: parts.key, issueKey: parts.key, subject: parts.subject, deprecated: false, findings: parts.findings, suggestedName: parts.key
|
|
221
|
+
? (0, build_1.buildBranchName)({ spec: { kind: 'hotfix', key: parts.key, subject: (_a = parts.subject) !== null && _a !== void 0 ? _a : '' }, config })
|
|
222
|
+
: undefined }, targetsForKind({ kind: 'hotfix', config }));
|
|
223
|
+
};
|
|
224
|
+
const parseFeature = (options) => {
|
|
225
|
+
var _a;
|
|
226
|
+
const { branch, prefix, segments, config } = options;
|
|
227
|
+
const alias = config.typeAliases[prefix];
|
|
228
|
+
const type = config.types.includes(prefix) ? prefix : alias;
|
|
229
|
+
const [story, task, ...extra] = segments;
|
|
230
|
+
if (!type || !story || extra.length > 0) {
|
|
231
|
+
return unrecognised({
|
|
232
|
+
branch,
|
|
233
|
+
message: `"${branch}" matches no branch shape; expected <type>/<KEY>-<subject> with type one of ${config.types.join(', ')}.`,
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
const findings = [];
|
|
237
|
+
if (alias && prefix !== type) {
|
|
238
|
+
findings.push({ rule: 'type-alias', message: `"${prefix}/" is an alias; use "${type}/".` });
|
|
239
|
+
}
|
|
240
|
+
const storyParts = parseSegment({ segment: story, config, role: 'story' });
|
|
241
|
+
if (task === undefined) {
|
|
242
|
+
findings.push(...storyParts.findings);
|
|
243
|
+
return Object.assign({ branch, ok: findings.length === 0, kind: 'main-feature', type, storyKey: storyParts.key, issueKey: storyParts.key, subject: storyParts.subject, deprecated: false, findings, suggestedName: storyParts.key
|
|
244
|
+
? (0, build_1.buildBranchName)({
|
|
245
|
+
spec: { kind: 'main-feature', type, key: storyParts.key, subject: (_a = storyParts.subject) !== null && _a !== void 0 ? _a : '' },
|
|
246
|
+
config,
|
|
247
|
+
})
|
|
248
|
+
: undefined }, targetsForKind({ kind: 'main-feature', config }));
|
|
249
|
+
}
|
|
250
|
+
return nestedTooDeep({
|
|
251
|
+
branch,
|
|
252
|
+
kind: 'sub-feature',
|
|
253
|
+
parent: `${prefix}/${story}`,
|
|
254
|
+
leaf: parseSegment({ segment: task, config, role: 'task' }),
|
|
255
|
+
config,
|
|
256
|
+
storyKey: storyParts.key,
|
|
257
|
+
type,
|
|
258
|
+
});
|
|
259
|
+
};
|
|
260
|
+
/**
|
|
261
|
+
* Attributes a keyless branch through the branch it is based on. Reviewed branches land in an
|
|
262
|
+
* integration branch, so a flat name like `feat/logout-confirmation` usually has a parent that
|
|
263
|
+
* does carry the story key. Deterministic — no model involved.
|
|
264
|
+
*/
|
|
265
|
+
const resolveThroughBase = (options) => {
|
|
266
|
+
var _a, _b;
|
|
267
|
+
const { branch, base } = options;
|
|
268
|
+
const inherited = (_a = base.storyKey) !== null && _a !== void 0 ? _a : base.taskKey;
|
|
269
|
+
if (branch.storyKey || !inherited)
|
|
270
|
+
return branch;
|
|
271
|
+
return Object.assign(Object.assign({}, branch), { storyKey: inherited, issueKey: (_b = branch.taskKey) !== null && _b !== void 0 ? _b : inherited, inheritedFrom: base.branch });
|
|
272
|
+
};
|
|
273
|
+
exports.resolveThroughBase = resolveThroughBase;
|
|
274
|
+
//# sourceMappingURL=parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../../../../../../libs/agent-rules/src/lib/git-flow/parse.ts"],"names":[],"mappings":"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"}
|