⚠️ Definition of Done: this issue must be completed in full, in a single PR. Do not split this
work across multiple PRs, and do not defer any Deliverable below to a follow-up issue. A PR that
satisfies only some of the Deliverables, stubs a required test, or leaves a checkbox
partially-done does NOT resolve this issue and will be closed.
Context
Mirror this fix exactly: #8311 (fix(github): app.ts/comments.ts repoFullName parsing is missing the segment-count/whitespace guard every sibling GitHub-write module has) established the
segment-count + whitespace repoFullName guard as the required convention across every
src/github/*.ts write/read module. This issue applies the identical fix to
src/integrations/project-tracker-adapter.ts's own parseRepoFullName, which never adopted it.
The established guard, quoting one of the six existing copies (src/github/labels.ts:9-19):
function parseRepoFullName(repoFullName: string): { owner: string; repo: string } {
const parts = repoFullName.split("/");
const owner = parts[0];
const repo = parts[1];
if (parts.length !== 2 || !owner || !repo || /\s/.test(repoFullName)) {
throw new Error(`Invalid repository full name: ${repoFullName}`);
}
return { owner, repo };
}
src/integrations/project-tracker-adapter.ts:39-46 has its own, differently-named-but-same-purpose
parseRepoFullName:
function parseRepoFullName(repoFullName: string): { owner: string; repo: string } {
const parts = repoFullName.split("/");
const owner = parts[0];
const repo = parts[1];
if (parts.length !== 2 || !owner || !repo) {
throw new Error(`Invalid repository full name: ${repoFullName}`);
}
return { owner, repo };
}
This is the partial case #8311 explicitly named for comments.ts: it already has the
segment-count guard, but is missing the /\s/.test(repoFullName) whitespace check that
pr-actions.ts/assignees.ts/labels.ts/app.ts/comments.ts all now have. A repo name like
"owner/ repo" (embedded whitespace) currently passes this check and gets encodeURIComponent-ed
straight into a GitHub REST URL (GitHubMilestonesAdapter.listOpenMilestones/attachToMilestone)
or interpolated into a GraphQL login variable (GitHubProjectsAdapter.listOpenProjects) —
exactly the failure mode #8311 closed everywhere else.
Requirements
parseRepoFullName in src/integrations/project-tracker-adapter.ts:39-46 must additionally
reject any repoFullName containing whitespace (/\s/.test(repoFullName)), matching the
pr-actions.ts/assignees.ts/labels.ts convention #8311 extended to app.ts/comments.ts.
- The existing failure contract (throwing
Error("Invalid repository full name: ...")) must be
preserved exactly — only the validation condition gets stricter, not the failure shape.
- This is a one-line change to an existing local helper — do not introduce a shared cross-file
helper; this file already correctly keeps its own local copy per the established house
convention.
Deliverables
All of the above Deliverables are required in the same PR.
Test Coverage Requirements
99%+ Codecov patch coverage, branch-counted, on the changed line and its new branch in
src/integrations/project-tracker-adapter.ts.
Expected Outcome
src/integrations/project-tracker-adapter.ts rejects the same malformed repoFullName shapes
(embedded whitespace) that every src/github/*.ts write/read module already rejects since
#8311, with no behavior change for any well-formed owner/repo value.
Links & Resources
#8311 (the prior, closed instance of this exact bug class for src/github/)
src/github/labels.ts:9-19 (a full, current copy of the required guard, to mirror)
src/integrations/project-tracker-adapter.ts:39-46 (the module's own partial copy, to fix)
test/unit/project-tracker-adapter.test.ts (existing coverage — has no whitespace-rejection
test for this helper)
Context
Mirror this fix exactly:
#8311(fix(github): app.ts/comments.ts repoFullName parsing is missing the segment-count/whitespace guard every sibling GitHub-write module has) established thesegment-count + whitespace
repoFullNameguard as the required convention across everysrc/github/*.tswrite/read module. This issue applies the identical fix tosrc/integrations/project-tracker-adapter.ts's ownparseRepoFullName, which never adopted it.The established guard, quoting one of the six existing copies (
src/github/labels.ts:9-19):src/integrations/project-tracker-adapter.ts:39-46has its own, differently-named-but-same-purposeparseRepoFullName:This is the partial case
#8311explicitly named forcomments.ts: it already has thesegment-count guard, but is missing the
/\s/.test(repoFullName)whitespace check thatpr-actions.ts/assignees.ts/labels.ts/app.ts/comments.tsall now have. A repo name like"owner/ repo"(embedded whitespace) currently passes this check and getsencodeURIComponent-edstraight into a GitHub REST URL (
GitHubMilestonesAdapter.listOpenMilestones/attachToMilestone)or interpolated into a GraphQL
loginvariable (GitHubProjectsAdapter.listOpenProjects) —exactly the failure mode
#8311closed everywhere else.Requirements
parseRepoFullNameinsrc/integrations/project-tracker-adapter.ts:39-46must additionallyreject any
repoFullNamecontaining whitespace (/\s/.test(repoFullName)), matching thepr-actions.ts/assignees.ts/labels.tsconvention#8311extended toapp.ts/comments.ts.Error("Invalid repository full name: ...")) must bepreserved exactly — only the validation condition gets stricter, not the failure shape.
helper; this file already correctly keeps its own local copy per the established house
convention.
Deliverables
parseRepoFullName(src/integrations/project-tracker-adapter.ts:39-46) additionallyrejects a
repoFullNamecontaining whitespace.test/unit/project-tracker-adapter.test.tsasserting"owner/ repo"(and/or" owner/repo") is rejected the same way the existing malformed-inputcase(s) already are, mirroring the coverage pattern used for the sibling guard in
test/unit/github-pr-actions.test.ts/github-assignees.test.ts/github-labels.test.ts.All of the above Deliverables are required in the same PR.
Test Coverage Requirements
99%+ Codecov patch coverage, branch-counted, on the changed line and its new branch in
src/integrations/project-tracker-adapter.ts.Expected Outcome
src/integrations/project-tracker-adapter.tsrejects the same malformedrepoFullNameshapes(embedded whitespace) that every
src/github/*.tswrite/read module already rejects since#8311, with no behavior change for any well-formedowner/repovalue.Links & Resources
#8311(the prior, closed instance of this exact bug class forsrc/github/)src/github/labels.ts:9-19(a full, current copy of the required guard, to mirror)src/integrations/project-tracker-adapter.ts:39-46(the module's own partial copy, to fix)test/unit/project-tracker-adapter.test.ts(existing coverage — has no whitespace-rejectiontest for this helper)