Add X social search adapter#98
Conversation
…ters Add digest.ts and digest.test.ts for airtable, asana, clickup, hubspot, intercom, pipedrive, salesforce, zendesk. Each digest handler classifies provider-specific lifecycle states (completed, merged, won/lost, solved, converted, archived, reopened) and exports deterministic bullets sorted by event time and id. Tests cover ordering, terminal states, and empty windows. Package index.ts files updated to re-export digest module. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add state-diff inference in 5 adapters so terminal lifecycle transitions are reflected in _webhook.action instead of being flattened to "updated": - asana: detect task completion via change.field === "completed" - clickup: detect task completion/archival via history_items + status type - pipedrive: detect deal won/lost via current vs previous status comparison - salesforce: detect case closure/lead conversion via ChangeEventHeader - zendesk: detect ticket solved via current vs previous status comparison This makes the digest handlers' terminal state classifications reachable from real webhook data, closing the gaps identified by lifecycle audit. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (10)
🚧 Files skipped from review as they are similar to previous changes (3)
📝 WalkthroughWalkthroughAdds a new X adapter package with types, client, path-mapper, emitters, digest, tests, and build config; updates docs and publish-group mapping for ChangesX Social Adapter & Core Files
GitHub alias/meta & emit changes
Digest/identifier refactor across adapters
GitLab canonical-trust & emit tests
Scripts & contract tests
Estimated code review effort Possibly related PRs
Poem
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
|
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/x/src/__tests__/emit-auxiliary-files.test.ts`:
- Around line 127-204: Add a new test in the same file that exercises
emitXAuxiliaryFiles with colliding alias inputs: construct two bundles (via
makeBundle / modified bundle fixtures) that normalize to the same
query/username/post-author slugs, call emitXAuxiliaryFiles with a createClient
pre-seeded as needed, then assert that writes include collision-disambiguated
alias paths (use xSearchByQueryAliasPath, xUserByUsernameAliasPath,
xPostByAuthorAliasPath and related x*AliasPath helpers) and that stale ambiguous
aliases are deleted; refer to existing tests "emitXAuxiliaryFiles writes
layout..." and "emitXAuxiliaryFiles reconciles renamed searches..." for
setup/assertion patterns and reuse createClient, makeBundle, and
emitXAuxiliaryFiles to locate where to add the new collision assertions.
In `@packages/x/src/digest.test.ts`:
- Around line 17-63: Add two tests to packages/x/src/digest.test.ts: one that
sends an event with action 'created' (use runDigest to assert the returned
section includes a bullet like "X was created" with the correct canonicalPath
and ordering alongside other events), and one that sends an event using the
adapter's terminal-state action (check the adapter to pick the exact action
name, e.g., 'archived' or 'closed') and assert the digest uses the
terminal-state phrasing (e.g., "was archived"/"was closed") in the bullet text
and preserves canonicalPath; place these alongside the existing tests that use
runDigest so they run with the same fixtures.
In `@packages/x/src/digest.ts`:
- Around line 120-131: The pastTense function in digest.ts currently maps any
unmatched action to "was updated", causing terminal lifecycle actions (e.g.,
archived, completed, resolved, closed, merged, canceled) to be misreported;
update the pastTense(event: DigestChangeEvent) implementation to explicitly
detect these terminal verbs by adding checks (using hasActionVerb) for
terminal-action patterns like
'close|closed|closed|merged|merge|archive|archived|complete|completed|cancel|canceled|resolve|resolved'
and return a suitable past-tense phrase such as 'was closed', 'was merged', 'was
archived', or a generic 'was finalized' (pick one consistent label) before the
final fallback, ensuring the new checks appear above the existing 'was updated'
return and reference the same hasActionVerb helper and
event.action/event.eventType/event.type extraction logic.
In `@packages/x/src/emit-auxiliary-files.ts`:
- Around line 193-207: Precompute slug buckets for query and username aliases
for the entire emit batch and detect collisions (buckets with length >1); then
when building deletes and writes use xSearchByQueryAliasPath(...,
colliding=true) or xUserByUsernameAliasPath(..., colliding=true) for any id in a
colliding bucket (leave colliding omitted/false for singleton buckets), and
propagate the same colliding flag into staleDeletes and every mirrorWrite call
so alias targets remain unique and stable (update the logic around
xSearchByQueryAliasPath, xUserByUsernameAliasPath, staleDeletes, and the
mirrorWrite calls in both the shown block and the similar block at ~290-301).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: ff2c12f8-3533-4a0d-bf59-ab0077ebf800
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (19)
docs/EVAL_INTEGRATION_CATALOG.mddocs/integration-scopes.yamlpackages/x/package.jsonpackages/x/src/__tests__/client.test.tspackages/x/src/__tests__/emit-auxiliary-files.test.tspackages/x/src/__tests__/path-mapper.test.tspackages/x/src/alias-slug.tspackages/x/src/client.tspackages/x/src/digest.test.tspackages/x/src/digest.tspackages/x/src/emit-auxiliary-files.tspackages/x/src/index-emitter.tspackages/x/src/index.tspackages/x/src/layout-prompt.tspackages/x/src/layout.tspackages/x/src/path-mapper.tspackages/x/src/types.tspackages/x/tsconfig.jsonscripts/resolve-publish-targets.mjs
There was a problem hiding this comment.
4 issues found across 20 files
Tip: cubic can generate docs of your entire codebase and keep them up to date. Try it here.
Fix all with cubic | Re-trigger cubic
Brings codex/adapter-digest-lifecycle-coverage into #98 so the X social search adapter ships with its security and correctness hardening. Conflicts on packages/x/** resolved in favor of the hardened version. Includes beyond the original PR #98 contents: - X security: validated baseUrl, AbortController timeout, truncated error bodies, trustedPriorCanonicalPath rejecting cross-provider paths. - X path-mapper __ joiner round-trip + safe-decode helpers. - GitLab emit-aux trustedPriorCanonicalPath via parseGitLabPath. - GitHub emit-aux NumberedDeleteRecoveryCache (N+1 fix). - Asana + ClickUp digest tests rewired to real path-mapper helpers. - relay CLI hardening from the parallel review-loop run. - Digest lifecycle coverage (#97 follow-up). Each fix is mutation-checked. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Merged the parallel The two branches had diverged at merge-base What's now in #98 beyond the originalX adapter security/correctness:
GitLab emit-aux:
GitHub emit-aux:
Test contract integrity:
relay-related CLI hardening carried in this tree from the parallel review-loop run (CORR-1..5, SECPERF-1, TC-1, codex-aggregate-001..004). Each fix has a mutation-checked regression test (revert fix → test FAILS → restore → PASSES) under Local verification on the merged treeThe original 🤖 Generated with Claude Code |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/jira/src/path-mapper.ts (1)
41-53: 🛠️ Refactor suggestion | 🟠 Major | 🏗️ Heavy liftReplace provider-local slugifier usage in canonical path composition.
titleSegmentWithIdstill depends on a customslugify()implementation. Please route this through the shared alias slug helper (slugifyAlias) and keep path compatibility via additive/deprecated helper or reader fallback if output changes.As per coding guidelines,
packages/*/src/**/*.ts: “Usepackages/core/src/alias-slug.ts(slugifyAlias,aliasCollisionSuffix)… NEVER write a new slugifier.”🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/jira/src/path-mapper.ts` around lines 41 - 53, Replace the local slugify() usage in titleSegmentWithId with the shared slug helper by importing and calling slugifyAlias from packages/core/src/alias-slug.ts; remove the local slugify implementation and instead call slugifyAlias(title) inside titleSegmentWithId, and to preserve existing canonical paths create a small additive/deprecated wrapper (e.g., legacySlugify or slugifyWithFallback) that returns the old-local-slugify output when a compatibility flag or reader fallback is required, or appends aliasCollisionSuffix as per alias-slug utilities to avoid collisions—keep encodeJiraPathSegment(id) usage and ensure the wrapper is used only for canonical path composition so consumers see unchanged paths unless they opt-in.
♻️ Duplicate comments (1)
packages/x/src/digest.ts (1)
133-149:⚠️ Potential issue | 🟠 Major | ⚡ Quick winMap terminal lifecycle actions before the
was updatedfallback.Terminal actions are currently collapsed into
was updated, which misstates lifecycle outcomes.As per coding guidelines, `Classify lifecycle actions explicitly in digest.ts. Terminal states such as closed, merged, archived, completed, canceled, and resolved must not fall through to a generic 'updated' line unless the provider has no terminal concept.`Proposed fix
const ACTION_VERB_PATTERN_1 = actionVerbRegex('search|searched|run|ran'); const ACTION_VERB_PATTERN_2 = actionVerbRegex('create|created|add|added|write|written'); +const ACTION_VERB_PATTERN_2B = actionVerbRegex('close|closed'); +const ACTION_VERB_PATTERN_2C = actionVerbRegex('merge|merged'); +const ACTION_VERB_PATTERN_2D = actionVerbRegex('archive|archived'); +const ACTION_VERB_PATTERN_2E = actionVerbRegex('complete|completed'); +const ACTION_VERB_PATTERN_2F = actionVerbRegex('cancel|canceled|cancelled'); +const ACTION_VERB_PATTERN_2G = actionVerbRegex('resolve|resolved'); const ACTION_VERB_PATTERN_3 = actionVerbRegex('delete|deleted|remove|removed'); function pastTense(event: DigestChangeEvent): string { const action = (event.action ?? event.eventType ?? event.type ?? '').toLowerCase(); if (hasActionVerb(action, ACTION_VERB_PATTERN_1)) { return 'ran'; } if (hasActionVerb(action, ACTION_VERB_PATTERN_2)) { return 'was created'; } + if (hasActionVerb(action, ACTION_VERB_PATTERN_2B)) return 'was closed'; + if (hasActionVerb(action, ACTION_VERB_PATTERN_2C)) return 'was merged'; + if (hasActionVerb(action, ACTION_VERB_PATTERN_2D)) return 'was archived'; + if (hasActionVerb(action, ACTION_VERB_PATTERN_2E)) return 'was completed'; + if (hasActionVerb(action, ACTION_VERB_PATTERN_2F)) return 'was canceled'; + if (hasActionVerb(action, ACTION_VERB_PATTERN_2G)) return 'was resolved'; if (hasActionVerb(action, ACTION_VERB_PATTERN_3)) { return 'was deleted'; } return 'was updated'; }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/x/src/digest.ts` around lines 133 - 149, The pastTense function currently falls back to 'was updated' and needs explicit handling of terminal lifecycle verbs; add a new ACTION_VERB_PATTERN_TERMINAL (use actionVerbRegex('closed|merged|archived|completed|canceled|resolved')) and check it before the final fallback in pastTense (alongside ACTION_VERB_PATTERN_1/2/3); when matched, return the correct terminal phrasing (e.g., 'was closed', 'was merged', 'was archived', 'was completed', 'was canceled', or 'was resolved') by mapping the matched verb to its specific past-tense string so terminal states are not collapsed into 'was updated'.
🧹 Nitpick comments (1)
packages/github/src/__tests__/emit-auxiliary-files.test.ts (1)
221-312: ⚡ Quick winRemove duplicated reconciliation tests in this file.
These two test cases are duplicated later with the same names and assertions, which adds redundant runtime and failure noise.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/github/src/__tests__/emit-auxiliary-files.test.ts` around lines 221 - 312, Delete the duplicated test cases that reconcile PR state transitions and issue metadata in this file: remove the two it(...) blocks titled "reconciles a PR state transition by moving the by-state alias" and "reconciles issue assignee, creator, and priority aliases on metadata changes" that call emitGitHubAuxiliaryFiles and assert deletes/writes using githubByIdAliasPath, githubByStateAliasPath, githubByAssigneeAliasPath, githubByCreatorAliasPath, and githubByPriorityAliasPath; keep only one copy of each test (or the later occurrences) to eliminate redundant execution and assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/github/src/emit-auxiliary-files.ts`:
- Around line 717-720: The code is pushing duplicate delete targets because
githubByTitleAliasPath(...) and githubLegacyByTitleAliasPath(...) can resolve to
the same path; update the block that runs when options.includeLegacyTitleAlias
is true to only add the legacy path if it is different from the primary path
(compare the string result of githubByTitleAliasPath(owner, repo, aliasKind,
title, number) with githubLegacyByTitleAliasPath(owner, repo, aliasKind, title,
number) before pushing), or alternatively compute the primary path once into a
variable and push the legacy path only when its value !== primary; adjust the
code that populates the paths array (the paths variable) accordingly.
In `@packages/github/src/pr/diff-writer.ts`:
- Around line 430-435: The current code uses resolveAliasPath(...) to pick an
alias path for numbered PRs (constructed via githubNumberedByTitleAliasPath)
which can cause writes to go to a collision path and leave the base numbered
alias stale; instead, when a numbered alias is being created (you already
compute baseAliasPath via githubNumberedByTitleAliasPath(owner, repo, 'pulls',
title, number)), skip resolveAliasPath and directly set aliasPath to
baseAliasPath and ensure the write/update uses that path (update usages of
aliasPath accordingly), so the canonical numbered alias always overwrites the
base alias; adjust the logic around resolveAliasPath, vfs, and content to only
call resolveAliasPath for non-numbered aliases.
In `@packages/gitlab/src/path-mapper.ts`:
- Around line 127-129: The new mapper emits flat ids with "__" (e.g.,
"release__candidate.json") but decodeFlatObjectId still strips the prefix by
assuming any "__" means "slug__id"; update decodeFlatObjectId (the decoder used
by parseGitLabPath) so that when the incoming path segment contains "__" but is
itself a flat filename (no "/" present) it returns the full base name (e.g.,
"release__candidate") instead of splitting; implement this by checking the raw
segment (or filename without ".json") for the pattern of a single path segment
containing "__" and only split on "__" in cases that clearly represent slug+id
(for example when there are surrounding path segments or an explicit slug
context), otherwise return the entire segment unchanged to preserve back-compat.
In `@packages/x/src/emit-auxiliary-files.ts`:
- Around line 519-531: staleCurrentSearchResultDeletes currently removes stale
search-result files and index rows but does not remove the corresponding
"post-by-query" alias files for each removed (searchId, postId); update
staleCurrentSearchResultDeletes to also compute the alias paths for each stale
result (using the same searchId and result.postId, e.g. the function that builds
post-by-query alias paths) and pass those paths to the deletion logic alongside
xSearchResultPath so that both the result file and its post-by-query alias are
deleted; ensure this happens after resultIndex.remove(...) and leverage the
existing staleDeletes helper so both sets of paths are cleaned up.
---
Outside diff comments:
In `@packages/jira/src/path-mapper.ts`:
- Around line 41-53: Replace the local slugify() usage in titleSegmentWithId
with the shared slug helper by importing and calling slugifyAlias from
packages/core/src/alias-slug.ts; remove the local slugify implementation and
instead call slugifyAlias(title) inside titleSegmentWithId, and to preserve
existing canonical paths create a small additive/deprecated wrapper (e.g.,
legacySlugify or slugifyWithFallback) that returns the old-local-slugify output
when a compatibility flag or reader fallback is required, or appends
aliasCollisionSuffix as per alias-slug utilities to avoid collisions—keep
encodeJiraPathSegment(id) usage and ensure the wrapper is used only for
canonical path composition so consumers see unchanged paths unless they opt-in.
---
Duplicate comments:
In `@packages/x/src/digest.ts`:
- Around line 133-149: The pastTense function currently falls back to 'was
updated' and needs explicit handling of terminal lifecycle verbs; add a new
ACTION_VERB_PATTERN_TERMINAL (use
actionVerbRegex('closed|merged|archived|completed|canceled|resolved')) and check
it before the final fallback in pastTense (alongside ACTION_VERB_PATTERN_1/2/3);
when matched, return the correct terminal phrasing (e.g., 'was closed', 'was
merged', 'was archived', 'was completed', 'was canceled', or 'was resolved') by
mapping the matched verb to its specific past-tense string so terminal states
are not collapsed into 'was updated'.
---
Nitpick comments:
In `@packages/github/src/__tests__/emit-auxiliary-files.test.ts`:
- Around line 221-312: Delete the duplicated test cases that reconcile PR state
transitions and issue metadata in this file: remove the two it(...) blocks
titled "reconciles a PR state transition by moving the by-state alias" and
"reconciles issue assignee, creator, and priority aliases on metadata changes"
that call emitGitHubAuxiliaryFiles and assert deletes/writes using
githubByIdAliasPath, githubByStateAliasPath, githubByAssigneeAliasPath,
githubByCreatorAliasPath, and githubByPriorityAliasPath; keep only one copy of
each test (or the later occurrences) to eliminate redundant execution and
assertions.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: d7f48a10-6ce0-407d-a047-7db57d824549
📒 Files selected for processing (82)
.trajectories/index.jsonpackage.jsonpackages/airtable/src/digest.tspackages/asana/src/digest.test.tspackages/asana/src/digest.tspackages/azure-blob/src/digest.tspackages/box/src/digest.tspackages/calendly/src/digest.test.tspackages/calendly/src/digest.tspackages/clickup/src/digest.test.tspackages/clickup/src/digest.tspackages/confluence/src/digest.tspackages/dropbox/src/digest.tspackages/gcs/src/digest.tspackages/github/src/__tests__/aliases.test.tspackages/github/src/__tests__/emit-auxiliary-files.test.tspackages/github/src/__tests__/index-emission.test.tspackages/github/src/__tests__/lazy-materialization.test.tspackages/github/src/__tests__/path-mapper.test.tspackages/github/src/bulk/bulk-writer.tspackages/github/src/digest.test.tspackages/github/src/digest.tspackages/github/src/emit-auxiliary-files.tspackages/github/src/issues/__tests__/issue-mapping.test.tspackages/github/src/issues/issue-mapper.tspackages/github/src/layout-prompt.tspackages/github/src/lazy.tspackages/github/src/path-mapper.tspackages/github/src/pr/diff-writer.tspackages/gitlab/src/digest.tspackages/gitlab/src/emit-auxiliary-files.tspackages/gitlab/src/path-mapper.tspackages/gitlab/test/digest.test.tspackages/gitlab/test/emit-auxiliary-delete.test.tspackages/gitlab/test/emit-auxiliary-files.test.tspackages/gitlab/test/path-mapper.test.tspackages/gmail/src/digest.tspackages/google-calendar/src/digest.tspackages/google-drive/src/digest.tspackages/hubspot/src/digest.tspackages/intercom/src/digest.tspackages/jira/src/__tests__/emit-auxiliary-files.test.tspackages/jira/src/__tests__/jira-adapter.test.tspackages/jira/src/__tests__/path-mapper.test.tspackages/jira/src/digest.tspackages/jira/src/jira-adapter.tspackages/jira/src/path-mapper.tspackages/linear/src/digest.tspackages/mailgun/src/digest.test.tspackages/mailgun/src/digest.tspackages/mixpanel/src/digest.tspackages/notion/src/digest.tspackages/onedrive/src/digest.tspackages/pipedrive/src/digest.tspackages/postgres/src/digest.tspackages/redis/src/digest.tspackages/s3/src/digest.tspackages/salesforce/src/__tests__/webhook-normalizer.test.tspackages/salesforce/src/digest.tspackages/salesforce/src/webhook-normalizer.tspackages/segment/src/digest.tspackages/sendgrid/src/digest.tspackages/sharepoint/src/digest.tspackages/shopify/src/digest.tspackages/slack/src/digest.tspackages/stripe/src/digest.tspackages/teams/src/digest.tspackages/x/src/__tests__/client.test.tspackages/x/src/__tests__/emit-auxiliary-files.test.tspackages/x/src/__tests__/index-emitter.test.tspackages/x/src/__tests__/path-mapper.test.tspackages/x/src/client.tspackages/x/src/digest.test.tspackages/x/src/digest.tspackages/x/src/emit-auxiliary-files.tspackages/x/src/index-emitter.tspackages/x/src/path-mapper.tspackages/zendesk/src/digest.tsscripts/digest-layout-contracts.mjsscripts/digest-layout-contracts.test.mjsscripts/resolve-publish-targets.mjsscripts/resolve-publish-targets.test.mjs
✅ Files skipped from review due to trivial changes (3)
- packages/github/src/layout-prompt.ts
- packages/github/src/lazy.ts
- .trajectories/index.json
🚧 Files skipped from review as they are similar to previous changes (4)
- packages/x/src/digest.test.ts
- packages/x/src/tests/path-mapper.test.ts
- packages/x/src/client.ts
- packages/x/src/index-emitter.ts
There was a problem hiding this comment.
2 issues found across 16 files (changes from recent commits).
You’re at about 92% of the monthly reviewed-line limit. You may want to disable incremental reviews to conserve quota. Reviews will continue until that limit is exceeded. If you need help avoiding interruptions, please contact contact@cubic.dev.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="packages/x/src/emit-auxiliary-files.ts">
<violation number="1" location="packages/x/src/emit-auxiliary-files.ts:88">
P2: Collision detection is based only on the current batch, so incremental syncs can write the wrong alias mode when colliding records already exist in workspace state.</violation>
</file>
<file name="packages/gitlab/src/path-mapper.ts">
<violation number="1" location="packages/gitlab/src/path-mapper.ts:165">
P2: The numeric-tail fallback incorrectly decodes raw flat IDs like `release__2024` as composed names, truncating the real object ID.</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
Fix all with cubic | Re-trigger cubic
| const results = [...(input.results ?? []), ...bundles.flatMap((bundle) => bundle.results)]; | ||
| const resultSearchIdsByPostId = groupResultSearchIdsByPostId(results); | ||
| const resultPostIdsBySearchId = groupResultPostIdsBySearchId(results); | ||
| const collidingSearchQueryIds = aliasCollisionIds(searches.filter(isFullSearch), (search) => search.id, (search) => search.query); |
There was a problem hiding this comment.
P2: Collision detection is based only on the current batch, so incremental syncs can write the wrong alias mode when colliding records already exist in workspace state.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/x/src/emit-auxiliary-files.ts, line 88:
<comment>Collision detection is based only on the current batch, so incremental syncs can write the wrong alias mode when colliding records already exist in workspace state.</comment>
<file context>
@@ -84,6 +85,8 @@ export async function emitXAuxiliaryFiles(
const results = [...(input.results ?? []), ...bundles.flatMap((bundle) => bundle.results)];
const resultSearchIdsByPostId = groupResultSearchIdsByPostId(results);
const resultPostIdsBySearchId = groupResultPostIdsBySearchId(results);
+ const collidingSearchQueryIds = aliasCollisionIds(searches.filter(isFullSearch), (search) => search.id, (search) => search.query);
+ const collidingUserUsernameIds = aliasCollisionIds(users.filter(isFullUser), (user) => user.id, (user) => user.username);
</file context>
Tip: Review your code locally with the cubic CLI to iterate faster.
| } | ||
| const encodedId = value.slice(separatorIndex + 2); | ||
| try { | ||
| return /^\d+$/u.test(decodeURIComponent(encodedId)); |
There was a problem hiding this comment.
P2: The numeric-tail fallback incorrectly decodes raw flat IDs like release__2024 as composed names, truncating the real object ID.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At packages/gitlab/src/path-mapper.ts, line 165:
<comment>The numeric-tail fallback incorrectly decodes raw flat IDs like `release__2024` as composed names, truncating the real object ID.</comment>
<file context>
@@ -152,6 +152,22 @@ function isComposedFlatRecordFilename(value: string): boolean {
+ }
+ const encodedId = value.slice(separatorIndex + 2);
+ try {
+ return /^\d+$/u.test(decodeURIComponent(encodedId));
+ } catch {
+ return false;
</file context>
Summary
@relayfile/adapter-xwith path-mapper helpers for/xsearches, posts, users, indexes, aliases, layout docs, and digest outputLAYOUT.md, resource_index.jsonfiles, by-key aliases, and result pointers for bundled search sync outputValidation
npx turbo build typecheck test --filter @relayfile/adapter-x...Cross-repo coordination
codex/x-social-search-cloud@relayfile/adapter-xpackage and complete its dependency lock refresh.