mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-06-17 00:46:53 +08:00
scripts/github-coordination.js:
- parseArgs: replace 13-entry if/else chain with BOOL_FLAGS/VALUE_FLAGS
lookup maps; shrinks from 119 to ~45 lines
- Extract dispatchCommand(options, ctx) and formatOutput(payload, options)
from main(); main() shrinks to ~20 lines
scripts/lib/github-coordination.js:
- Split 1041-line monolith into 6 focused sub-modules under
scripts/lib/github-coordination/ (policy, parsing, gh-api, state,
actions, store); index becomes a thin re-export (~55 lines)
- Document ECC_GH_SHIM trust boundary in runGh() (gh-api.js)
- Document applyClaim() read→check→write race condition (actions.js)
tests/lib/github-coordination.test.js:
- Refactor runTests() to data-driven DESCRIPTORS array + runGroup()
helper; runTests() shrinks to ~10 lines
- Add 5 new edge-case tests: normalizeRepo('') and normalizeRepo(' ')
throw, desiredLabelsForState for blocked/ready statuses, and
buildIssueStateFromAction for validate action (15 → 20 tests)
tests/scripts/github-coordination.test.js:
- Replace console.log in test runner with process.stdout.write
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
108 lines
2.6 KiB
JavaScript
108 lines
2.6 KiB
JavaScript
'use strict';
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const DEFAULT_CONFIG_FILE = 'github-native-coordination.json';
|
|
const DEFAULT_CONFIG_PATH = path.join(__dirname, '..', '..', '..', 'config', DEFAULT_CONFIG_FILE);
|
|
const DEFAULT_SECTION_MARKER = 'ecc-coordination';
|
|
const DEFAULT_SCHEMA_VERSION = 'ecc.github.coordination.v1';
|
|
const DEFAULT_LABELS = Object.freeze({
|
|
epic: 'epic',
|
|
available: 'coordination:available',
|
|
claimed: 'coordination:claimed',
|
|
ready: 'coordination:ready',
|
|
blocked: 'coordination:blocked',
|
|
validated: 'coordination:validated',
|
|
reviewRequested: 'coordination:review-requested',
|
|
reviewApproved: 'coordination:review-approved',
|
|
reviewChangesRequested: 'coordination:review-changes-requested',
|
|
published: 'coordination:published',
|
|
synced: 'coordination:synced',
|
|
});
|
|
const DEFAULT_POLICY = Object.freeze({
|
|
schemaVersion: DEFAULT_SCHEMA_VERSION,
|
|
sectionMarker: DEFAULT_SECTION_MARKER,
|
|
labels: DEFAULT_LABELS,
|
|
review: {
|
|
required: true,
|
|
defaultMode: 'required',
|
|
},
|
|
validation: {
|
|
required: true,
|
|
},
|
|
branchModel: {
|
|
epicOnly: true,
|
|
taskBranches: false,
|
|
},
|
|
project: {
|
|
enabled: false,
|
|
fieldNames: {
|
|
status: 'Status',
|
|
owner: 'Owner',
|
|
branch: 'Branch',
|
|
validation: 'Validation',
|
|
review: 'Review',
|
|
},
|
|
},
|
|
});
|
|
|
|
function loadPolicy(rootDir = process.cwd(), configPath = null) {
|
|
const resolvedPath = configPath
|
|
? path.resolve(configPath)
|
|
: path.join(rootDir, 'config', DEFAULT_CONFIG_FILE);
|
|
|
|
if (!fs.existsSync(resolvedPath)) {
|
|
return {
|
|
...DEFAULT_POLICY,
|
|
sourcePath: null,
|
|
};
|
|
}
|
|
|
|
let parsed;
|
|
try {
|
|
parsed = JSON.parse(fs.readFileSync(resolvedPath, 'utf8'));
|
|
} catch (error) {
|
|
throw new Error(`Failed to load policy from ${resolvedPath}: ${error.message}`);
|
|
}
|
|
return {
|
|
...DEFAULT_POLICY,
|
|
...parsed,
|
|
labels: {
|
|
...DEFAULT_LABELS,
|
|
...(parsed.labels || {}),
|
|
},
|
|
review: {
|
|
...DEFAULT_POLICY.review,
|
|
...(parsed.review || {}),
|
|
},
|
|
validation: {
|
|
...DEFAULT_POLICY.validation,
|
|
...(parsed.validation || {}),
|
|
},
|
|
branchModel: {
|
|
...DEFAULT_POLICY.branchModel,
|
|
...(parsed.branchModel || {}),
|
|
},
|
|
project: {
|
|
...DEFAULT_POLICY.project,
|
|
...(parsed.project || {}),
|
|
fieldNames: {
|
|
...DEFAULT_POLICY.project.fieldNames,
|
|
...((parsed.project || {}).fieldNames || {}),
|
|
},
|
|
},
|
|
sourcePath: resolvedPath,
|
|
};
|
|
}
|
|
|
|
module.exports = {
|
|
DEFAULT_CONFIG_FILE,
|
|
DEFAULT_CONFIG_PATH,
|
|
DEFAULT_LABELS,
|
|
DEFAULT_POLICY,
|
|
DEFAULT_SCHEMA_VERSION,
|
|
DEFAULT_SECTION_MARKER,
|
|
loadPolicy,
|
|
};
|