pumuki 6.3.44 → 6.3.46
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/docs/RELEASE_NOTES.md +31 -0
- package/docs/USAGE.md +19 -0
- package/docs/seguimiento-activo-pumuki-saas-supermercados.md +287 -5
- package/integrations/git/runPlatformGate.ts +30 -19
- package/integrations/git/stageRunners.ts +128 -30
- package/integrations/lifecycle/watch.ts +26 -0
- package/integrations/mcp/aiGateCheck.ts +16 -2
- package/integrations/mcp/autoExecuteAiStart.ts +12 -2
- package/integrations/mcp/preFlightCheck.ts +16 -0
- package/integrations/sdd/learningInsights.ts +91 -0
- package/integrations/sdd/syncDocs.ts +317 -28
- package/package.json +5 -2
- package/scripts/backlog-id-issue-map-lib.ts +1 -1
- package/scripts/reconcile-consumer-backlog-issues-lib.ts +2 -2
- package/scripts/watch-consumer-backlog-fleet-tick.ts +225 -0
- package/scripts/watch-consumer-backlog-fleet.ts +200 -0
- package/scripts/watch-consumer-backlog-lib.ts +2 -2
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { existsSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { resolve } from 'node:path';
|
|
5
|
+
import {
|
|
6
|
+
buildWatchActionRequiredReasons,
|
|
7
|
+
formatActionReasonsForHuman,
|
|
8
|
+
} from './backlog-action-reasons-lib';
|
|
9
|
+
import {
|
|
10
|
+
BACKLOG_JSON_COMPAT_CONTRACT_ID,
|
|
11
|
+
BACKLOG_JSON_COMPAT_MIN_READER_VERSION,
|
|
12
|
+
BACKLOG_JSON_SCHEMA_VERSION,
|
|
13
|
+
} from './backlog-json-contract-lib';
|
|
14
|
+
import { runBacklogWatch } from './watch-consumer-backlog-lib';
|
|
15
|
+
|
|
16
|
+
type FleetTarget = {
|
|
17
|
+
key: 'saas' | 'ruralgo' | 'flux';
|
|
18
|
+
filePath: string;
|
|
19
|
+
repo?: string;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
type ParsedArgs = {
|
|
23
|
+
json: boolean;
|
|
24
|
+
failOnFindings: boolean;
|
|
25
|
+
targets: ReadonlyArray<FleetTarget>;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const JSON_TOOL_NAME = 'backlog-watch-fleet-tick';
|
|
29
|
+
const DEFAULT_REPO = 'SwiftEnProfundidad/ast-intelligence-hooks';
|
|
30
|
+
const DEFAULT_TARGETS = {
|
|
31
|
+
saas: resolve(
|
|
32
|
+
homedir(),
|
|
33
|
+
'Developer/Projects/SAAS:APP_SUPERMERCADOS/docs/pumuki/PUMUKI_BUGS_MEJORAS.md'
|
|
34
|
+
),
|
|
35
|
+
ruralgo: resolve(
|
|
36
|
+
homedir(),
|
|
37
|
+
'Developer/Projects/R_GO/docs/technical/08-validation/refactor/pumuki-integration-feedback.md'
|
|
38
|
+
),
|
|
39
|
+
flux: resolve(homedir(), 'Developer/Projects/Flux_training/docs/BUGS_Y_MEJORAS_PUMUKI.md'),
|
|
40
|
+
} as const;
|
|
41
|
+
|
|
42
|
+
const HELP_TEXT = `Usage:
|
|
43
|
+
npx --yes tsx@4.21.0 scripts/watch-consumer-backlog-fleet-tick.ts [--json] [--no-fail]
|
|
44
|
+
[--saas=<path>] [--ruralgo=<path>] [--flux=<path>] [--repo=<owner/name>]
|
|
45
|
+
|
|
46
|
+
Defaults:
|
|
47
|
+
--saas=${DEFAULT_TARGETS.saas}
|
|
48
|
+
--ruralgo=${DEFAULT_TARGETS.ruralgo}
|
|
49
|
+
--flux=${DEFAULT_TARGETS.flux}
|
|
50
|
+
--repo=${DEFAULT_REPO}
|
|
51
|
+
|
|
52
|
+
Options:
|
|
53
|
+
--json Imprime salida consolidada JSON.
|
|
54
|
+
--no-fail No devuelve exit code 1 aunque existan findings accionables.
|
|
55
|
+
--saas=PATH Override ruta backlog SAAS.
|
|
56
|
+
--ruralgo=PATH Override ruta backlog RuralGo.
|
|
57
|
+
--flux=PATH Override ruta backlog Flux.
|
|
58
|
+
--repo=NAME Override repo para targets que consultan upstream.
|
|
59
|
+
`;
|
|
60
|
+
|
|
61
|
+
class HelpRequestedError extends Error {
|
|
62
|
+
constructor() {
|
|
63
|
+
super(HELP_TEXT);
|
|
64
|
+
this.name = 'HelpRequestedError';
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const parseArgs = (argv: ReadonlyArray<string>): ParsedArgs => {
|
|
69
|
+
let json = false;
|
|
70
|
+
let failOnFindings = true;
|
|
71
|
+
let saasPath = DEFAULT_TARGETS.saas;
|
|
72
|
+
let ruralgoPath = DEFAULT_TARGETS.ruralgo;
|
|
73
|
+
let fluxPath = DEFAULT_TARGETS.flux;
|
|
74
|
+
let repo = DEFAULT_REPO;
|
|
75
|
+
|
|
76
|
+
for (const arg of argv) {
|
|
77
|
+
if (arg === '--help' || arg === '-h') {
|
|
78
|
+
throw new HelpRequestedError();
|
|
79
|
+
}
|
|
80
|
+
if (arg === '--json') {
|
|
81
|
+
json = true;
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (arg === '--no-fail') {
|
|
85
|
+
failOnFindings = false;
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (arg.startsWith('--saas=')) {
|
|
89
|
+
saasPath = resolve(arg.slice('--saas='.length).trim());
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (arg.startsWith('--ruralgo=')) {
|
|
93
|
+
ruralgoPath = resolve(arg.slice('--ruralgo='.length).trim());
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
if (arg.startsWith('--flux=')) {
|
|
97
|
+
fluxPath = resolve(arg.slice('--flux='.length).trim());
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
if (arg.startsWith('--repo=')) {
|
|
101
|
+
const value = arg.slice('--repo='.length).trim();
|
|
102
|
+
repo = value.length > 0 ? value : DEFAULT_REPO;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
throw new Error(`Unknown argument "${arg}"\n\n${HELP_TEXT}`);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const targets: FleetTarget[] = [
|
|
109
|
+
{ key: 'saas', filePath: saasPath, repo },
|
|
110
|
+
{ key: 'ruralgo', filePath: ruralgoPath, repo },
|
|
111
|
+
{ key: 'flux', filePath: fluxPath },
|
|
112
|
+
];
|
|
113
|
+
|
|
114
|
+
for (const target of targets) {
|
|
115
|
+
if (!existsSync(target.filePath)) {
|
|
116
|
+
throw new Error(
|
|
117
|
+
`Target backlog not found for ${target.key}: ${target.filePath}\n` +
|
|
118
|
+
`Use --${target.key}=<path> to override.\n\n${HELP_TEXT}`
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
json,
|
|
125
|
+
failOnFindings,
|
|
126
|
+
targets,
|
|
127
|
+
};
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
const formatHumanOutput = (
|
|
131
|
+
targets: ReadonlyArray<
|
|
132
|
+
Awaited<ReturnType<typeof runBacklogWatch>> & {
|
|
133
|
+
key: FleetTarget['key'];
|
|
134
|
+
actionRequiredReasons: ReadonlyArray<string>;
|
|
135
|
+
}
|
|
136
|
+
>
|
|
137
|
+
): string => {
|
|
138
|
+
const lines: string[] = [];
|
|
139
|
+
const actionRequiredTargets = targets.filter((item) => item.hasActionRequired).length;
|
|
140
|
+
const entriesTotal = targets.reduce((acc, item) => acc + item.entriesScanned, 0);
|
|
141
|
+
const nonClosedTotal = targets.reduce((acc, item) => acc + item.nonClosedEntries, 0);
|
|
142
|
+
lines.push(
|
|
143
|
+
`[pumuki][backlog-watch-fleet-tick] targets=${targets.length} entries_total=${entriesTotal} non_closed_total=${nonClosedTotal} action_required_targets=${actionRequiredTargets}`
|
|
144
|
+
);
|
|
145
|
+
for (const target of targets) {
|
|
146
|
+
lines.push(
|
|
147
|
+
`[pumuki][backlog-watch-fleet-tick] key=${target.key} target=${target.filePath} entries=${target.entriesScanned} non_closed=${target.nonClosedEntries} action_required=${target.hasActionRequired ? 'yes' : 'no'} reasons=${formatActionReasonsForHuman(target.actionRequiredReasons)}`
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
return `${lines.join('\n')}\n`;
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const main = async (): Promise<void> => {
|
|
154
|
+
const parsed = parseArgs(process.argv.slice(2));
|
|
155
|
+
const results = await Promise.all(
|
|
156
|
+
parsed.targets.map(async (target) => {
|
|
157
|
+
const watchResult = await runBacklogWatch({
|
|
158
|
+
filePath: target.filePath,
|
|
159
|
+
repo: target.repo,
|
|
160
|
+
});
|
|
161
|
+
const actionRequiredReasons = buildWatchActionRequiredReasons({
|
|
162
|
+
needsIssueCount: watchResult.classification.needsIssue.length,
|
|
163
|
+
driftClosedIssueCount: watchResult.classification.driftClosedIssue.length,
|
|
164
|
+
headingDriftCount: watchResult.headingDrift.length,
|
|
165
|
+
});
|
|
166
|
+
return {
|
|
167
|
+
...watchResult,
|
|
168
|
+
key: target.key,
|
|
169
|
+
actionRequiredReasons,
|
|
170
|
+
};
|
|
171
|
+
})
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
const hasActionRequired = results.some((item) => item.hasActionRequired);
|
|
175
|
+
const actionRequiredTargets = results.filter((item) => item.hasActionRequired).length;
|
|
176
|
+
const entriesScannedTotal = results.reduce((acc, item) => acc + item.entriesScanned, 0);
|
|
177
|
+
const nonClosedTotal = results.reduce((acc, item) => acc + item.nonClosedEntries, 0);
|
|
178
|
+
|
|
179
|
+
if (parsed.json) {
|
|
180
|
+
writeFileSync(
|
|
181
|
+
process.stdout.fd,
|
|
182
|
+
`${JSON.stringify(
|
|
183
|
+
{
|
|
184
|
+
tool: JSON_TOOL_NAME,
|
|
185
|
+
schema_version: BACKLOG_JSON_SCHEMA_VERSION,
|
|
186
|
+
generated_at: new Date().toISOString(),
|
|
187
|
+
run_id: randomUUID(),
|
|
188
|
+
compat: {
|
|
189
|
+
contract_id: BACKLOG_JSON_COMPAT_CONTRACT_ID,
|
|
190
|
+
min_reader_version: BACKLOG_JSON_COMPAT_MIN_READER_VERSION,
|
|
191
|
+
is_backward_compatible: true,
|
|
192
|
+
breaking_changes: [],
|
|
193
|
+
},
|
|
194
|
+
summary: {
|
|
195
|
+
targets: parsed.targets.length,
|
|
196
|
+
entries_scanned_total: entriesScannedTotal,
|
|
197
|
+
non_closed_total: nonClosedTotal,
|
|
198
|
+
action_required_targets: actionRequiredTargets,
|
|
199
|
+
has_action_required: hasActionRequired,
|
|
200
|
+
},
|
|
201
|
+
results,
|
|
202
|
+
},
|
|
203
|
+
null,
|
|
204
|
+
2
|
|
205
|
+
)}\n`
|
|
206
|
+
);
|
|
207
|
+
} else {
|
|
208
|
+
writeFileSync(process.stdout.fd, formatHumanOutput(results));
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (parsed.failOnFindings && hasActionRequired) {
|
|
212
|
+
process.exitCode = 1;
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
main().catch((error: unknown) => {
|
|
217
|
+
if (error instanceof HelpRequestedError) {
|
|
218
|
+
writeFileSync(process.stdout.fd, `${HELP_TEXT}\n`);
|
|
219
|
+
process.exitCode = 0;
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
223
|
+
writeFileSync(process.stderr.fd, `${message}\n`);
|
|
224
|
+
process.exitCode = 1;
|
|
225
|
+
});
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { writeFileSync } from 'node:fs';
|
|
3
|
+
import { resolve } from 'node:path';
|
|
4
|
+
import {
|
|
5
|
+
buildWatchActionRequiredReasons,
|
|
6
|
+
formatActionReasonsForHuman,
|
|
7
|
+
} from './backlog-action-reasons-lib';
|
|
8
|
+
import {
|
|
9
|
+
BACKLOG_JSON_COMPAT_CONTRACT_ID,
|
|
10
|
+
BACKLOG_JSON_COMPAT_MIN_READER_VERSION,
|
|
11
|
+
BACKLOG_JSON_SCHEMA_VERSION,
|
|
12
|
+
} from './backlog-json-contract-lib';
|
|
13
|
+
import { runBacklogWatch } from './watch-consumer-backlog-lib';
|
|
14
|
+
|
|
15
|
+
type FleetTarget = {
|
|
16
|
+
filePath: string;
|
|
17
|
+
repo?: string;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
type ParsedArgs = {
|
|
21
|
+
targets: ReadonlyArray<FleetTarget>;
|
|
22
|
+
json: boolean;
|
|
23
|
+
failOnFindings: boolean;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const JSON_TOOL_NAME = 'backlog-watch-fleet';
|
|
27
|
+
|
|
28
|
+
const HELP_TEXT = `Usage:
|
|
29
|
+
npx --yes tsx@4.21.0 scripts/watch-consumer-backlog-fleet.ts --target=<markdown-path>[::owner/name] [--target=<markdown-path>[::owner/name] ...] [--json] [--no-fail]
|
|
30
|
+
|
|
31
|
+
Options:
|
|
32
|
+
--target=<path>[::repo] Backlog markdown consumidor a vigilar. Puedes repetir el flag.
|
|
33
|
+
Ejemplo: --target=/repo/docs/backlog.md::owner/name
|
|
34
|
+
--json Imprime resultado consolidado en JSON.
|
|
35
|
+
--no-fail No devuelve exit code 1 aunque existan findings accionables.
|
|
36
|
+
`;
|
|
37
|
+
|
|
38
|
+
class HelpRequestedError extends Error {
|
|
39
|
+
constructor() {
|
|
40
|
+
super(HELP_TEXT);
|
|
41
|
+
this.name = 'HelpRequestedError';
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const parseTarget = (rawTarget: string): FleetTarget => {
|
|
46
|
+
const trimmed = rawTarget.trim();
|
|
47
|
+
const separatorIndex = trimmed.indexOf('::');
|
|
48
|
+
if (separatorIndex === -1) {
|
|
49
|
+
return {
|
|
50
|
+
filePath: resolve(trimmed),
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
const filePath = trimmed.slice(0, separatorIndex).trim();
|
|
54
|
+
const repo = trimmed.slice(separatorIndex + 2).trim();
|
|
55
|
+
return {
|
|
56
|
+
filePath: resolve(filePath),
|
|
57
|
+
repo: repo.length > 0 ? repo : undefined,
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const parseArgs = (argv: ReadonlyArray<string>): ParsedArgs => {
|
|
62
|
+
const targets: FleetTarget[] = [];
|
|
63
|
+
let json = false;
|
|
64
|
+
let failOnFindings = true;
|
|
65
|
+
|
|
66
|
+
for (const arg of argv) {
|
|
67
|
+
if (arg === '--help' || arg === '-h') {
|
|
68
|
+
throw new HelpRequestedError();
|
|
69
|
+
}
|
|
70
|
+
if (arg === '--json') {
|
|
71
|
+
json = true;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (arg === '--no-fail') {
|
|
75
|
+
failOnFindings = false;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (arg.startsWith('--target=')) {
|
|
79
|
+
const rawTarget = arg.slice('--target='.length);
|
|
80
|
+
if (rawTarget.trim().length === 0) {
|
|
81
|
+
throw new Error(`Invalid --target (empty value)\n\n${HELP_TEXT}`);
|
|
82
|
+
}
|
|
83
|
+
targets.push(parseTarget(rawTarget));
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
throw new Error(`Unknown argument "${arg}"\n\n${HELP_TEXT}`);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (targets.length === 0) {
|
|
90
|
+
throw new Error(`Missing --target\n\n${HELP_TEXT}`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
targets,
|
|
95
|
+
json,
|
|
96
|
+
failOnFindings,
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const formatHumanOutput = (
|
|
101
|
+
targets: ReadonlyArray<
|
|
102
|
+
Awaited<ReturnType<typeof runBacklogWatch>> & {
|
|
103
|
+
actionRequiredReasons: ReadonlyArray<string>;
|
|
104
|
+
}
|
|
105
|
+
>
|
|
106
|
+
): string => {
|
|
107
|
+
const lines: string[] = [];
|
|
108
|
+
const actionRequiredTargets = targets.filter((item) => item.hasActionRequired).length;
|
|
109
|
+
const entriesTotal = targets.reduce((acc, item) => acc + item.entriesScanned, 0);
|
|
110
|
+
const nonClosedTotal = targets.reduce((acc, item) => acc + item.nonClosedEntries, 0);
|
|
111
|
+
|
|
112
|
+
lines.push(
|
|
113
|
+
`[pumuki][backlog-watch-fleet] targets=${targets.length} entries_total=${entriesTotal} non_closed_total=${nonClosedTotal} action_required_targets=${actionRequiredTargets}`
|
|
114
|
+
);
|
|
115
|
+
for (const target of targets) {
|
|
116
|
+
lines.push(
|
|
117
|
+
`[pumuki][backlog-watch-fleet] target=${target.filePath} repo=${target.repo ?? '-'} entries=${target.entriesScanned} non_closed=${target.nonClosedEntries} action_required=${target.hasActionRequired ? 'yes' : 'no'} reasons=${formatActionReasonsForHuman(target.actionRequiredReasons)}`
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
return `${lines.join('\n')}\n`;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
const main = async (): Promise<void> => {
|
|
124
|
+
const parsed = parseArgs(process.argv.slice(2));
|
|
125
|
+
const results = await Promise.all(
|
|
126
|
+
parsed.targets.map(async (target) => {
|
|
127
|
+
const watchResult = await runBacklogWatch({
|
|
128
|
+
filePath: target.filePath,
|
|
129
|
+
repo: target.repo,
|
|
130
|
+
});
|
|
131
|
+
const actionRequiredReasons = buildWatchActionRequiredReasons({
|
|
132
|
+
needsIssueCount: watchResult.classification.needsIssue.length,
|
|
133
|
+
driftClosedIssueCount: watchResult.classification.driftClosedIssue.length,
|
|
134
|
+
headingDriftCount: watchResult.headingDrift.length,
|
|
135
|
+
});
|
|
136
|
+
return {
|
|
137
|
+
...watchResult,
|
|
138
|
+
actionRequiredReasons,
|
|
139
|
+
};
|
|
140
|
+
})
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
const hasActionRequired = results.some((item) => item.hasActionRequired);
|
|
144
|
+
const actionRequiredTargets = results.filter((item) => item.hasActionRequired).length;
|
|
145
|
+
const entriesScannedTotal = results.reduce((acc, item) => acc + item.entriesScanned, 0);
|
|
146
|
+
const nonClosedTotal = results.reduce((acc, item) => acc + item.nonClosedEntries, 0);
|
|
147
|
+
|
|
148
|
+
if (parsed.json) {
|
|
149
|
+
const generatedAt = new Date().toISOString();
|
|
150
|
+
const runId = randomUUID();
|
|
151
|
+
writeFileSync(
|
|
152
|
+
process.stdout.fd,
|
|
153
|
+
`${JSON.stringify(
|
|
154
|
+
{
|
|
155
|
+
tool: JSON_TOOL_NAME,
|
|
156
|
+
schema_version: BACKLOG_JSON_SCHEMA_VERSION,
|
|
157
|
+
generated_at: generatedAt,
|
|
158
|
+
run_id: runId,
|
|
159
|
+
invocation: {
|
|
160
|
+
mode: 'json',
|
|
161
|
+
targets_count: parsed.targets.length,
|
|
162
|
+
},
|
|
163
|
+
compat: {
|
|
164
|
+
contract_id: BACKLOG_JSON_COMPAT_CONTRACT_ID,
|
|
165
|
+
min_reader_version: BACKLOG_JSON_COMPAT_MIN_READER_VERSION,
|
|
166
|
+
is_backward_compatible: true,
|
|
167
|
+
breaking_changes: [],
|
|
168
|
+
},
|
|
169
|
+
summary: {
|
|
170
|
+
targets: parsed.targets.length,
|
|
171
|
+
entries_scanned_total: entriesScannedTotal,
|
|
172
|
+
non_closed_total: nonClosedTotal,
|
|
173
|
+
action_required_targets: actionRequiredTargets,
|
|
174
|
+
has_action_required: hasActionRequired,
|
|
175
|
+
},
|
|
176
|
+
results,
|
|
177
|
+
},
|
|
178
|
+
null,
|
|
179
|
+
2
|
|
180
|
+
)}\n`
|
|
181
|
+
);
|
|
182
|
+
} else {
|
|
183
|
+
writeFileSync(process.stdout.fd, formatHumanOutput(results));
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
if (parsed.failOnFindings && hasActionRequired) {
|
|
187
|
+
process.exitCode = 1;
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
main().catch((error: unknown) => {
|
|
192
|
+
if (error instanceof HelpRequestedError) {
|
|
193
|
+
writeFileSync(process.stdout.fd, `${HELP_TEXT}\n`);
|
|
194
|
+
process.exitCode = 0;
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
198
|
+
writeFileSync(process.stderr.fd, `${message}\n`);
|
|
199
|
+
process.exitCode = 1;
|
|
200
|
+
});
|
|
@@ -53,10 +53,10 @@ export type BacklogIssueNumberResolver = (
|
|
|
53
53
|
|
|
54
54
|
const STATUS_EMOJI_PATTERN = /(✅|🚧|⏳|⛔)/;
|
|
55
55
|
const ISSUE_REF_PATTERN = /#(\d+)/;
|
|
56
|
-
const BACKLOG_ID_PATTERN = /^(PUMUKI-(?:M)?\d+|PUMUKI-INC-\d+|FP-\d+|AST-GAP-\d+)$/;
|
|
56
|
+
const BACKLOG_ID_PATTERN = /^(PUMUKI-(?:M)?\d+|PUM-\d+|PUMUKI-INC-\d+|FP-\d+|AST-GAP-\d+)$/;
|
|
57
57
|
const STATUS_TEXT_PATTERN = /^(OPEN|PENDING|REPORTED|IN_PROGRESS|BLOCKED|FIXED|CLOSED)\b/i;
|
|
58
58
|
const BACKLOG_SECTION_HEADING_PATTERN =
|
|
59
|
-
/^(\s*###\s*)(✅|🚧|⏳|⛔)(\s+)(PUMUKI-(?:M)?\d+|PUMUKI-INC-\d+|FP-\d+|AST-GAP-\d+)\b/;
|
|
59
|
+
/^(\s*###\s*)(✅|🚧|⏳|⛔)(\s+)(PUMUKI-(?:M)?\d+|PUM-\d+|PUMUKI-INC-\d+|FP-\d+|AST-GAP-\d+)\b/;
|
|
60
60
|
const STATUS_TEXT_TO_EMOJI: Record<string, BacklogStatusEmoji> = {
|
|
61
61
|
OPEN: '⏳',
|
|
62
62
|
PENDING: '⏳',
|