Skip to content

build: enable noUncheckedIndexedAccess#600

Merged
thymikee merged 8 commits into
mainfrom
codex/no-unchecked-indexed-access
May 28, 2026
Merged

build: enable noUncheckedIndexedAccess#600
thymikee merged 8 commits into
mainfrom
codex/no-unchecked-indexed-access

Conversation

@thymikee
Copy link
Copy Markdown
Member

@thymikee thymikee commented May 28, 2026

Summary

Enable TypeScript noUncheckedIndexedAccess so unchecked array[index] and record[key] reads now surface as | undefined during typecheck instead of being assumed present.

This improves codebase health by making each indexed access state its invariant: loop-bounded reads use targeted non-null assertions, parser/regex boundaries use explicit guards, and several call sites now use iteration APIs that avoid indexing entirely. The result is stricter compiler coverage across parsing, replay, selectors, dispatch, snapshot, platform, and test code without broad any or cast escapes.

Before:

const target = parsed.positionals[0];
action.positionals = [target, parsed.positionals[1]];

After:

if (!hasFillTargetAndText(parsed.positionals)) {
  action.positionals = parsed.positionals;
  return action;
}

const [target, text, ...textRest] = parsed.positionals;
action.positionals = [target, [text, ...textRest].join(' ')];

The tuple guard captures the parser invariant once, then downstream code can destructure target and text as present strings instead of repeating unchecked indexed reads.

Touched 60 files. Scope stayed within TypeScript strictness fallout from enabling the compiler option.

Validation

pnpm format passed.

pnpm check:tooling passed: lint, typecheck, MCP metadata check, and build/declaration generation.

Focused unit coverage passed for the touched strictness areas, including replay variables, Maestro replay parsing, selector parsing, React Native overlay handling, Android snapshot/scroll helpers, snapshot processing, snapshot diff, replay heal, find, snapshot handler, and CLI batch parsing.

The replay script parser test passed after the tuple-guard cleanup. The Maestro runScript http.post case passed when rerun outside the sandbox; inside the sandbox it can fail on local loopback/subprocess networking.

Full pnpm check:unit was attempted but remains blocked in this local environment by unrelated local networking/subprocess failures (EADDRNOTAVAIL, test timeouts, and local tool command failures).

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7eaa83a04a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/compat/maestro/support.ts Outdated
export function resolveMaestroString(value: string, context: MaestroParseContext): string {
return value.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g, (match, key: string) => {
return Object.prototype.hasOwnProperty.call(context.env, key) ? context.env[key] : match;
return context.env[key] ?? match;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use own-property checks for Maestro variables

When a Maestro flow references an unset variable whose name exists on Object.prototype (for example ${toString} or ${__proto__}), this now reads through the prototype and treats it as a defined env value instead of preserving the literal placeholder as before. Since context.env is a normal object, this can corrupt generated actions for those inputs; keep the own-property check (or use Object.hasOwn) before indexing.

Useful? React with 👍 / 👎.

Comment thread src/replay/vars.ts Outdated
Comment on lines +126 to +127
const value = scope.values[key];
if (value !== undefined) return value;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use own-property checks for replay variables

For an unset replay variable that collides with an inherited object property, such as ${toString} or ${__proto__}, this lookup now returns the prototype value and bypasses both the fallback and the unresolved-variable error. Because replay scopes are plain objects, this changes malformed/missing variables into substituted prototype strings; restore an own-property check before accepting the value.

Useful? React with 👍 / 👎.

@thymikee thymikee force-pushed the codex/no-unchecked-indexed-access branch from a23c466 to 207b7d7 Compare May 28, 2026 07:39
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 28, 2026

PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://callstackincubator.github.io/agent-device/pr-preview/pr-600/

Built to branch gh-pages at 2026-05-28 08:51 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@thymikee thymikee merged commit 136d313 into main May 28, 2026
19 checks passed
@thymikee thymikee deleted the codex/no-unchecked-indexed-access branch May 28, 2026 09:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant