Victor Casado d4486a7a29 refactor: apply code-review findings to github-native coordination
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>
2026-06-11 14:05:42 -04:00

66 lines
1.8 KiB
JavaScript

'use strict';
const os = require('os');
const { createStateStore } = require('../state-store');
const { DEFAULT_SCHEMA_VERSION, DEFAULT_POLICY } = require('./policy');
const { normalizeLabels } = require('./gh-api');
const { slugifySegment, mapStateToWorkItemStatus, summarizeProjectProjection } = require('./state');
function epicWorkItemId(repo, issueNumber) {
return `github-${slugifySegment(repo)}-epic-${issueNumber}`;
}
function upsertCoordinationWorkItem(store, repo, issue, state, action, options = {}) {
if (!store) {
return null;
}
const now = new Date().toISOString();
const metadata = {
schemaVersion: state.schemaVersion || DEFAULT_SCHEMA_VERSION,
repo,
issueNumber: issue.number,
issueUrl: issue.url || null,
issueTitle: issue.title || null,
labels: normalizeLabels(issue.labels),
coordination: state,
projectProjection: summarizeProjectProjection(state, options.policy || DEFAULT_POLICY),
action,
actionAt: now,
syncedBy: 'ecc-github-coordination',
};
return store.upsertWorkItem({
id: epicWorkItemId(repo, issue.number),
source: 'github-epic',
sourceId: String(issue.number),
title: `Epic #${issue.number}: ${issue.title}`,
status: mapStateToWorkItemStatus(state.status),
priority: state.status === 'blocked' ? 'high' : 'normal',
url: issue.url || null,
owner: state.owner || (issue.author && issue.author.login) || null,
repoRoot: options.repoRoot || process.cwd(),
sessionId: options.sessionId || null,
metadata,
updatedAt: now,
});
}
async function openStore(options = {}) {
if (options.dbPath === false) {
return null;
}
return createStateStore({
dbPath: options.dbPath,
homeDir: options.homeDir || process.env.HOME || os.homedir(),
});
}
module.exports = {
epicWorkItemId,
openStore,
upsertCoordinationWorkItem,
};