Skip to content

fix(onboard): validate Slack bot token format before saving#2130

Merged
jyaunches merged 4 commits into
NVIDIA:mainfrom
latenighthackathon:fix/slack-token-validation
Apr 24, 2026
Merged

fix(onboard): validate Slack bot token format before saving#2130
jyaunches merged 4 commits into
NVIDIA:mainfrom
latenighthackathon:fix/slack-token-validation

Conversation

@latenighthackathon

@latenighthackathon latenighthackathon commented Apr 21, 2026

Copy link
Copy Markdown
Contributor

Summary

The interactive setup wizard accepted any string as a Slack Bot Token — including the example abcd from the bug report — and continued to sandbox creation. The invalid token then surfaced as a cryptic auth failure only after the sandbox was built.

This PR adds a minimal format check at the prompt point.

Related Issue

Closes #1912

Changes

  • Add tokenFormat regex (^xoxb-[A-Za-z0-9-]+$) and tokenFormatHint to the slack entry in MESSAGING_CHANNELS so the validation rule travels with the channel definition. Future channels can opt in by adding the same fields.
  • In setupMessagingChannels' interactive prompt loop, reject tokens that do not match tokenFormat: print a one-line hint (Slack bot tokens start with 'xoxb-'...) and drop the channel from the enabled set, mirroring the existing "no token entered" skip path.
  • Non-interactive mode is intentionally unchanged — env-var credentials are assumed to be intentional.
  • Export MESSAGING_CHANNELS so the regex is directly unit-testable.

Testing

  • npx vitest run test/onboard.test.ts — 130 tests pass
  • New regression test verifies the regex rejects the bug-report value (abcd), empty strings, user tokens (xoxp-...), app tokens (xapp-...), leading prefixes (Bearer xoxb-...), and whitespace-bearing tokens while accepting valid xoxb-... forms
  • Build + typecheck clean (npm run build:cli, npm run typecheck:cli)

Executed:

  • Full test/onboard.test.ts suite in the nemoclaw-test Docker environment
  • Targeted -t "#1912" run to confirm new test is referenced by the issue number

Checklist

Signed-off-by: latenighthackathon latenighthackathon@users.noreply.github.com

Summary by CodeRabbit

  • New Features

    • Messaging channel definitions are now publicly exposed for easier integration.
    • Channel metadata supports optional token format checks and user-facing hints for token entry.
  • Bug Fixes

    • Token validation for Slack-style tokens tightened: invalid tokens are rejected, channels are skipped, credentials aren’t persisted, and a clear warning is shown.
  • Tests

    • Added tests covering Slack token format validation with multiple valid and invalid cases.

@coderabbitai

coderabbitai Bot commented Apr 21, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Onboarding now validates per-channel token formats: tokens are checked against channel tokenFormat during interactive setup; invalid tokens are rejected, the channel is disabled for that run, and credentials are not saved. MESSAGING_CHANNELS is exported from src/lib/onboard.ts. Tests for Slack token validation were added.

Changes

Cohort / File(s) Summary
Onboard + export & validation
src/lib/onboard.ts
Exports MESSAGING_CHANNELS via module.exports. During interactive messaging setup, tokens are validated against any channel tokenFormat; invalid tokens produce a console warning, the channel is removed from enabled set, and credential saving is skipped.
Channel definitions
src/lib/sandbox-channels.ts
ChannelDef gains optional tokenFormat?: RegExp and tokenFormatHint?: string. KNOWN_CHANNELS.slack now includes a tokenFormat (enforces xoxb-...) and a tokenFormatHint.
Tests for Slack token format
test/onboard.test.ts
Adds Vitest tests that simulate interactive setup, assert invalid Slack tokens are rejected and not persisted, expect an “Invalid format” warning, and verify the Slack tokenFormat/hint accept valid xoxb-... examples and reject invalid ones.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant CLI as "Interactive CLI"
  participant Onboard as "onboard.setupMessagingChannels"
  participant Channels as "MESSAGING_CHANNELS / ChannelDef"
  participant Store as "credentials (save/prompt)"

  User->>CLI: choose messaging channels, provide token
  CLI->>Onboard: submit token for channel
  Onboard->>Channels: read channel.tokenFormat?
  alt tokenFormat present
    Onboard->>Onboard: validate token against regex
    alt matches
      Onboard->>Store: save credential
      Onboard->>CLI: mark channel saved
    else does not match
      Onboard->>CLI: log "Invalid format" warning
      Onboard->>Onboard: remove channel from enabled set
      Onboard-->>Store: skip saving credential
    end
  else no tokenFormat
    Onboard->>Store: save credential (no format check)
  end
  Onboard->>CLI: return final enabled channels
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I nibble at strings and sniff for "xoxb-",
I hop through prompts until the tokens obey,
If gibberish tries to sneak, I stamp my paw,
No saved crumbs of nonsense in my tidy lair,
Hooray — clean channels and tests today!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: validating Slack bot token format before saving during onboarding setup.
Linked Issues check ✅ Passed The PR fully implements the core requirement from issue #1912: validating Slack bot token format (xoxb- prefix pattern) and rejecting invalid tokens during interactive setup.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing token validation: updating the ChannelDef interface, adding tokenFormat/tokenFormatHint to Slack channel definition, implementing validation logic in setupMessagingChannels, and adding comprehensive tests.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@wscurran wscurran added bug Something fails against expected or documented behavior integration: slack Slack integration or channel behavior labels Apr 21, 2026
@wscurran

Copy link
Copy Markdown
Contributor

✨ Thanks for submitting this PR that proposes a fix for the issue where the interactive setup wizard accepts any string as a Slack Bot Token without validation. The changes and testing you provided will help us review this further.


Possibly related open issues:

@wscurran

Copy link
Copy Markdown
Contributor

Branch has conflicts with main — could you rebase and we'll get a review queued up.

@copy-pr-bot

copy-pr-bot Bot commented Apr 22, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@latenighthackathon

latenighthackathon commented Apr 22, 2026

Copy link
Copy Markdown
Contributor Author

@wscurran rebased - Cheers!

@jyaunches jyaunches self-assigned this Apr 24, 2026
@jyaunches jyaunches self-requested a review April 24, 2026 15:44
@jyaunches jyaunches force-pushed the fix/slack-token-validation branch from 97de7a8 to ca9af21 Compare April 24, 2026 16:52

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/onboard.test.ts`:
- Around line 4917-4918: Replace the CommonJS require-based loading of the
module (the delete require.cache[onboardPath] + const { MESSAGING_CHANNELS } =
require(onboardPath)) with an ECMAScript dynamic import: use await import(...)
to load the module and destructure MESSAGING_CHANNELS from the resolved module
object, and implement cache-busting by appending a query param (e.g.
`?update=${Date.now()}`) to onboardPath when calling import; remove usage of
require.cache since it’s not applicable for ESM.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 943b142a-e11e-46ef-a2c6-9f8421a60465

📥 Commits

Reviewing files that changed from the base of the PR and between 97de7a8 and ca9af21.

📒 Files selected for processing (3)
  • src/lib/onboard.ts
  • src/lib/sandbox-channels.ts
  • test/onboard.test.ts
✅ Files skipped from review due to trivial changes (1)
  • src/lib/onboard.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/sandbox-channels.ts

Comment thread test/onboard.test.ts Outdated

@jyaunches jyaunches left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

PR Review: fix/slack-token-validation

Files Changed: 3
Lines: +53 / -0

🔴 Blocker (must fix before merge)

Missing runtime validation logic — The PR description states that setupMessagingChannels() rejects tokens that do not match tokenFormat, but this code does not exist. The tokenFormat and tokenFormatHint fields are added to the Slack channel definition and tested in isolation, but setupMessagingChannels() in onboard.ts never reads ch.tokenFormat or ch.tokenFormatHint. The token prompt flow accepts any non-empty string, saves it via saveCredential, and proceeds.

The bug (#1912) is not fixed. A user can still type abcd as a Slack bot token and it will be saved.

Suggested fix — add a format check in the prompt loop (around line 5140 of src/lib/onboard.ts), after the prompt and before saveCredential:

const token = normalizeCredentialValue(await prompt(`  ${ch.label}: `, { secret: true }));
if (token) {
  // Validate token format when the channel defines one
  if (ch.tokenFormat && !ch.tokenFormat.test(token)) {
    console.log(`  ✗ Invalid format. ${ch.tokenFormatHint || 'Check the token and try again.'}`);
    console.log(`  Skipped ${ch.name} (invalid token format)`);
    enabled.delete(ch.name);
    continue;
  }
  saveCredential(ch.envKey, token);
  process.env[ch.envKey] = token;
  console.log(`  ✓ ${ch.name} token saved`);
}

🟡 Warnings (should fix)

  1. Regex character class may be too restrictive (sandbox-channels.ts:61) — The regex ^xoxb-[A-Za-z0-9-]+$ only allows alphanumerics and hyphens. Real-world Slack tokens can contain underscores. Consider widening to ^xoxb-[A-Za-z0-9_-]+$ to avoid rejecting legitimate tokens. False negatives (rejecting valid tokens) are worse than false positives for a format hint check.

  2. Branch was 69 commits behind main — I rebased it for you. No conflicts.

🔵 Suggestions (nice to have)

  1. Once the runtime logic is added, consider adding a behavioral test that mocks prompt() to return "abcd" and verifies the channel is dropped from the enabled set and saveCredential is not called.

  2. Consider validating the app token (xapp- prefix) too — if tokenFormat is a general mechanism, the app token prompt could benefit from the same treatment.

✅ What's Good

  • Clean, scoped commit with good conventional commit message and DCO sign-off
  • Extensible design — tokenFormat/tokenFormatHint on ChannelDef is the right abstraction for future channels
  • Comprehensive regex test coverage with good edge cases
  • Non-interactive path intentionally excluded — correct for env-var credentials

latenighthackathon added a commit to latenighthackathon/NemoClaw that referenced this pull request Apr 24, 2026
…n test

Replaces the CommonJS `delete require.cache[onboardPath]` + `require(onboardPath)`
pair with `await import(\`${pathToFileURL(onboardPath).href}?update=\${Date.now()}\`)`
so the test reloads `dist/lib/onboard.js` through the ESM loader (require.cache
has no effect on ESM modules in this file). Addresses CodeRabbit nit on NVIDIA#2130.

Signed-off-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
@latenighthackathon

Copy link
Copy Markdown
Contributor Author

Thanks for the feedback, addressed CodeRabbit nit - Cheers!

@latenighthackathon

Copy link
Copy Markdown
Contributor Author

Thanks for the feedback @jyaunches, addressed the blocker (wired ch.tokenFormat into setupMessagingChannels), widened the regex for underscores, and added an interactive integration test for the invalid-token path - Cheers!

latenighthackathon added a commit to latenighthackathon/NemoClaw that referenced this pull request Apr 24, 2026
Parallels the bot-token check: adds appTokenFormat / appTokenFormatHint
to ChannelDef, pins Slack's app token to ^xapp-[A-Za-z0-9_-]+$, and
wires the check into setupMessagingChannels so a bogus xapp- prompt
drops the channel from the enabled set and skips saveCredential for
SLACK_APP_TOKEN.

Note: if the bot token passes but the app token fails, the bot token
stays persisted (it was already saved before the app-token prompt).
That's acceptable — on a retry onboard the bot token lights up as
"already configured" and only the app-token prompt fires again.

Extends the existing regex test with xapp- valid/invalid cases and
adds a second interactive integration test covering the
bot-valid + app-invalid path.

Per @jyaunches suggestion #2 on NVIDIA#2130.

Signed-off-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
@latenighthackathon

Copy link
Copy Markdown
Contributor Author

Also added Slack app token (xapp-) validation in fa2593c7 per suggestion #2 — same mechanism, with its own behavioral test for the bot-valid + app-invalid path - Cheers!

…VIDIA#1912)

The interactive setup wizard accepted any string as a Slack Bot Token —
including the example abcd from the bug report — and continued to sandbox
creation. The invalid token then surfaced as a cryptic auth failure only
after the sandbox was built.

Add a minimal format check:

- Add tokenFormat regex and tokenFormatHint to the slack MESSAGING_CHANNELS
  entry so the validation rule travels with the channel definition (future
  channels can opt in by adding the same fields).
- In the interactive prompt loop, reject tokens that do not match
  tokenFormat: print a one-line hint and drop the channel from the enabled
  set, mirroring the existing no-token-entered skip path.
- Non-interactive mode is intentionally unchanged — env-var credentials
  are assumed to be intentional.

Export MESSAGING_CHANNELS so the regex is directly unit-testable.

Tests
- test/onboard.test.ts targeted suite passes (130 tests)
- New test verifies the regex rejects the bug-report value (abcd),
  empty strings, user tokens (xoxp-), app tokens (xapp-), leading
  prefixes (Bearer ...), and whitespace-bearing tokens while accepting
  realistic xoxb- forms.

Closes NVIDIA#1912

Signed-off-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
…n test

Replaces the CommonJS `delete require.cache[onboardPath]` + `require(onboardPath)`
pair with `await import(\`${pathToFileURL(onboardPath).href}?update=\${Date.now()}\`)`
so the test reloads `dist/lib/onboard.js` through the ESM loader (require.cache
has no effect on ESM modules in this file). Addresses CodeRabbit nit on NVIDIA#2130.

Signed-off-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
…1912)

Wires ch.tokenFormat into setupMessagingChannels so bogus tokens like
"abcd" are rejected at the prompt instead of silently saved. When the
entered value doesn't match the channel's tokenFormat regex, the
channel is dropped from the enabled set with the configured hint and
the loop continues.

Also widens the Slack bot-token regex from [A-Za-z0-9-]+ to
[A-Za-z0-9_-]+ so legitimate tokens containing underscores aren't
falsely rejected.

Adds an interactive integration test that mocks credentials.prompt to
return "abcd", drives the toggle UI via piped stdin, and asserts slack
is dropped from the enabled set and SLACK_BOT_TOKEN is never persisted.
Extends the existing regex test with underscore cases to lock in the
widened character class.

Signed-off-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
Parallels the bot-token check: adds appTokenFormat / appTokenFormatHint
to ChannelDef, pins Slack's app token to ^xapp-[A-Za-z0-9_-]+$, and
wires the check into setupMessagingChannels so a bogus xapp- prompt
drops the channel from the enabled set and skips saveCredential for
SLACK_APP_TOKEN.

Note: if the bot token passes but the app token fails, the bot token
stays persisted (it was already saved before the app-token prompt).
That's acceptable — on a retry onboard the bot token lights up as
"already configured" and only the app-token prompt fires again.

Extends the existing regex test with xapp- valid/invalid cases and
adds a second interactive integration test covering the
bot-valid + app-invalid path.

Per @jyaunches suggestion #2 on NVIDIA#2130.

Signed-off-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
@latenighthackathon latenighthackathon force-pushed the fix/slack-token-validation branch from 41ea051 to d6d92f5 Compare April 24, 2026 18:48

@jyaunches jyaunches left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

PR Review: fix/slack-token-validation (Round 2)

All Round 1 findings addressed — nice work @latenighthackathon.

✅ Verified

  • Blocker resolvedch.tokenFormat is now wired into setupMessagingChannels() (line 5416). Format check runs before saveCredential, so invalid tokens are never persisted.
  • Regex widened[A-Za-z0-9_-]+ now accepts underscores.
  • App token validation addedappTokenFormat/appTokenFormatHint mirrors the bot token pattern. Consistent.
  • Behavioral tests pass — 3 new tests verify both the regex and the interactive prompt rejection flow (mocked prompt(), piped stdin, outcome-based assertions).

🟡 Notes (non-blocking)

  1. "Already configured" path bypasses format validation — if a malformed token was saved before this fix, re-onboard skips straight to "✓ already configured" without re-checking format. Acceptable — credential migration is a separate concern.
  2. 1 commit behind main — trivial rebase for 660c7afc (refactor types). No conflicts.

Recommendation

Approve. Squash-merge recommended to collapse the 4 commits into one clean entry.

@jyaunches jyaunches merged commit eab0a80 into NVIDIA:main Apr 24, 2026
10 checks passed
ericksoa pushed a commit that referenced this pull request Apr 24, 2026
…2458)

## Summary

Tip of `main` currently fails `npm run typecheck:cli` with 8 errors in
`test/onboard.test.ts` — patterns introduced by #2130 (Slack token
validation tests) don't satisfy the `strict: true` setting introduced by
#2422. Every PR opened against main inherits these errors, which makes
the `checks` CI job red on unrelated PRs (e.g. #2454).

## Related

Follows from #2130 + #2422 interaction. No linked issue — local-only
breakage caught by CI on downstream PRs.

## Changes

`test/onboard.test.ts` — 8 annotations, zero behavior change:

- **4× `.pop()!`** — `Array.pop()` returns `string | undefined`. Each
site is immediately preceded by an `assert.equal(result.status, 0)` that
guarantees non-empty stdout, so the non-null assertion is safe.
- **3× `(c: { key: string }) => c.key === …`** — `saveCalls` entries
only read `.key`.
- **1× `(c: { name: string }) => c.name === …`** — `MESSAGING_CHANNELS`
entry lookup only reads `.name`.

The tests themselves still exercise the same cases; these changes are
purely to make the TypeScript compiler happy.

## Type of Change

- [x] Code change (feature, bug fix, or refactor)

## Verification

- [x] `npx tsc -p tsconfig.cli.json` — exits 0 (was 2 with 8 errors)
- [x] `npx prek run --all-files` passes
- [x] `npm test` passes
- [x] Tests added or updated for new or changed behavior
- [x] No secrets, API keys, or credentials committed

## AI Disclosure
- [x] AI-assisted — tool: Claude Code

---
Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## Tests
* Improved reliability of JSON payload extraction in onboarding tests
with defensive null-checks before parsing.
* Enhanced type safety in test callbacks and iterators with explicit
TypeScript type annotations.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ericksoa pushed a commit that referenced this pull request Apr 24, 2026
## Summary

Prevents the class of regression that required #2458. Adds an
unconditional `typecheck:cli` step to the shared CI action so future
hook-filter drift can't hide a tsc error.

## Related

Follow-up to #2458 (which fixed the symptom — this addresses the root
cause).

## Root cause recap

- `.pre-commit-config.yaml` had `files: ^(bin|scripts)/` on the
`tsc-cli` hook.
- PRs that touched only `test/` or `src/` never triggered the check.
- #2130 (test-only Slack validation) slipped through that gap.
- #2422 later turned on `strict: true`, and the latent errors surfaced —
but for every downstream PR, not the PR that introduced them.
- Six open PRs ended up blocked on the same error cluster before anyone
noticed.

## Changes

`.github/actions/basic-checks/action.yaml` — new **Typecheck CLI + tests
(strict)** step running `npm run typecheck:cli` unconditionally.
Independent of prek hook configuration, so future filter drift can't
hide a tsc error from CI.

## Type of Change

- [x] Code change (feature, bug fix, or refactor)

## Verification

- [x] YAML parses
- [x] `npm run typecheck:cli` exits 0 on this branch (requires #2458
merged to main first)
- [x] Tests added or updated for new or changed behavior (N/A — infra
change, existing suite covers)
- [x] No secrets, API keys, or credentials committed

## AI Disclosure
- [x] AI-assisted — tool: Claude Code

---
Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Enhanced continuous integration pipeline with additional TypeScript
typechecking to improve code quality assurance and detect type-related
issues earlier in the development process.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
DemianHeyGen pushed a commit to DemianHeyGen/NemoClaw that referenced this pull request Apr 30, 2026
)

Add tokenFormat/tokenFormatHint and appTokenFormat/appTokenFormatHint to ChannelDef
interface. Wire format checks into setupMessagingChannels() so invalid tokens are
rejected at the prompt instead of silently saved and surfacing as cryptic auth
failures after sandbox build.

- Slack bot token: ^xoxb-[A-Za-z0-9_-]+$
- Slack app token: ^xapp-[A-Za-z0-9_-]+$
- Non-interactive mode intentionally unchanged (env-var tokens assumed intentional)
- Future channels can opt in by adding tokenFormat/appTokenFormat to their definition

Closes NVIDIA#1912

Co-authored-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
DemianHeyGen pushed a commit to DemianHeyGen/NemoClaw that referenced this pull request Apr 30, 2026
…VIDIA#2458)

## Summary

Tip of `main` currently fails `npm run typecheck:cli` with 8 errors in
`test/onboard.test.ts` — patterns introduced by NVIDIA#2130 (Slack token
validation tests) don't satisfy the `strict: true` setting introduced by
NVIDIA#2422. Every PR opened against main inherits these errors, which makes
the `checks` CI job red on unrelated PRs (e.g. NVIDIA#2454).

## Related

Follows from NVIDIA#2130 + NVIDIA#2422 interaction. No linked issue — local-only
breakage caught by CI on downstream PRs.

## Changes

`test/onboard.test.ts` — 8 annotations, zero behavior change:

- **4× `.pop()!`** — `Array.pop()` returns `string | undefined`. Each
site is immediately preceded by an `assert.equal(result.status, 0)` that
guarantees non-empty stdout, so the non-null assertion is safe.
- **3× `(c: { key: string }) => c.key === …`** — `saveCalls` entries
only read `.key`.
- **1× `(c: { name: string }) => c.name === …`** — `MESSAGING_CHANNELS`
entry lookup only reads `.name`.

The tests themselves still exercise the same cases; these changes are
purely to make the TypeScript compiler happy.

## Type of Change

- [x] Code change (feature, bug fix, or refactor)

## Verification

- [x] `npx tsc -p tsconfig.cli.json` — exits 0 (was 2 with 8 errors)
- [x] `npx prek run --all-files` passes
- [x] `npm test` passes
- [x] Tests added or updated for new or changed behavior
- [x] No secrets, API keys, or credentials committed

## AI Disclosure
- [x] AI-assisted — tool: Claude Code

---
Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## Tests
* Improved reliability of JSON payload extraction in onboarding tests
with defensive null-checks before parsing.
* Enhanced type safety in test callbacks and iterators with explicit
TypeScript type annotations.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
DemianHeyGen pushed a commit to DemianHeyGen/NemoClaw that referenced this pull request Apr 30, 2026
## Summary

Prevents the class of regression that required NVIDIA#2458. Adds an
unconditional `typecheck:cli` step to the shared CI action so future
hook-filter drift can't hide a tsc error.

## Related

Follow-up to NVIDIA#2458 (which fixed the symptom — this addresses the root
cause).

## Root cause recap

- `.pre-commit-config.yaml` had `files: ^(bin|scripts)/` on the
`tsc-cli` hook.
- PRs that touched only `test/` or `src/` never triggered the check.
- NVIDIA#2130 (test-only Slack validation) slipped through that gap.
- NVIDIA#2422 later turned on `strict: true`, and the latent errors surfaced —
but for every downstream PR, not the PR that introduced them.
- Six open PRs ended up blocked on the same error cluster before anyone
noticed.

## Changes

`.github/actions/basic-checks/action.yaml` — new **Typecheck CLI + tests
(strict)** step running `npm run typecheck:cli` unconditionally.
Independent of prek hook configuration, so future filter drift can't
hide a tsc error from CI.

## Type of Change

- [x] Code change (feature, bug fix, or refactor)

## Verification

- [x] YAML parses
- [x] `npm run typecheck:cli` exits 0 on this branch (requires NVIDIA#2458
merged to main first)
- [x] Tests added or updated for new or changed behavior (N/A — infra
change, existing suite covers)
- [x] No secrets, API keys, or credentials committed

## AI Disclosure
- [x] AI-assisted — tool: Claude Code

---
Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Enhanced continuous integration pipeline with additional TypeScript
typechecking to improve code quality assurance and detect type-related
issues earlier in the development process.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ksapru pushed a commit to ksapru/NemoClaw that referenced this pull request May 12, 2026
)

Add tokenFormat/tokenFormatHint and appTokenFormat/appTokenFormatHint to ChannelDef
interface. Wire format checks into setupMessagingChannels() so invalid tokens are
rejected at the prompt instead of silently saved and surfacing as cryptic auth
failures after sandbox build.

- Slack bot token: ^xoxb-[A-Za-z0-9_-]+$
- Slack app token: ^xapp-[A-Za-z0-9_-]+$
- Non-interactive mode intentionally unchanged (env-var tokens assumed intentional)
- Future channels can opt in by adding tokenFormat/appTokenFormat to their definition

Closes NVIDIA#1912

Co-authored-by: latenighthackathon <latenighthackathon@users.noreply.github.com>
ksapru pushed a commit to ksapru/NemoClaw that referenced this pull request May 12, 2026
…VIDIA#2458)

## Summary

Tip of `main` currently fails `npm run typecheck:cli` with 8 errors in
`test/onboard.test.ts` — patterns introduced by NVIDIA#2130 (Slack token
validation tests) don't satisfy the `strict: true` setting introduced by
NVIDIA#2422. Every PR opened against main inherits these errors, which makes
the `checks` CI job red on unrelated PRs (e.g. NVIDIA#2454).

## Related

Follows from NVIDIA#2130 + NVIDIA#2422 interaction. No linked issue — local-only
breakage caught by CI on downstream PRs.

## Changes

`test/onboard.test.ts` — 8 annotations, zero behavior change:

- **4× `.pop()!`** — `Array.pop()` returns `string | undefined`. Each
site is immediately preceded by an `assert.equal(result.status, 0)` that
guarantees non-empty stdout, so the non-null assertion is safe.
- **3× `(c: { key: string }) => c.key === …`** — `saveCalls` entries
only read `.key`.
- **1× `(c: { name: string }) => c.name === …`** — `MESSAGING_CHANNELS`
entry lookup only reads `.name`.

The tests themselves still exercise the same cases; these changes are
purely to make the TypeScript compiler happy.

## Type of Change

- [x] Code change (feature, bug fix, or refactor)

## Verification

- [x] `npx tsc -p tsconfig.cli.json` — exits 0 (was 2 with 8 errors)
- [x] `npx prek run --all-files` passes
- [x] `npm test` passes
- [x] Tests added or updated for new or changed behavior
- [x] No secrets, API keys, or credentials committed

## AI Disclosure
- [x] AI-assisted — tool: Claude Code

---
Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## Tests
* Improved reliability of JSON payload extraction in onboarding tests
with defensive null-checks before parsing.
* Enhanced type safety in test callbacks and iterators with explicit
TypeScript type annotations.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
ksapru pushed a commit to ksapru/NemoClaw that referenced this pull request May 12, 2026
## Summary

Prevents the class of regression that required NVIDIA#2458. Adds an
unconditional `typecheck:cli` step to the shared CI action so future
hook-filter drift can't hide a tsc error.

## Related

Follow-up to NVIDIA#2458 (which fixed the symptom — this addresses the root
cause).

## Root cause recap

- `.pre-commit-config.yaml` had `files: ^(bin|scripts)/` on the
`tsc-cli` hook.
- PRs that touched only `test/` or `src/` never triggered the check.
- NVIDIA#2130 (test-only Slack validation) slipped through that gap.
- NVIDIA#2422 later turned on `strict: true`, and the latent errors surfaced —
but for every downstream PR, not the PR that introduced them.
- Six open PRs ended up blocked on the same error cluster before anyone
noticed.

## Changes

`.github/actions/basic-checks/action.yaml` — new **Typecheck CLI + tests
(strict)** step running `npm run typecheck:cli` unconditionally.
Independent of prek hook configuration, so future filter drift can't
hide a tsc error from CI.

## Type of Change

- [x] Code change (feature, bug fix, or refactor)

## Verification

- [x] YAML parses
- [x] `npm run typecheck:cli` exits 0 on this branch (requires NVIDIA#2458
merged to main first)
- [x] Tests added or updated for new or changed behavior (N/A — infra
change, existing suite covers)
- [x] No secrets, API keys, or credentials committed

## AI Disclosure
- [x] AI-assisted — tool: Claude Code

---
Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Enhanced continuous integration pipeline with additional TypeScript
typechecking to improve code quality assurance and detect type-related
issues earlier in the development process.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

Signed-off-by: Charan Jagwani <cjagwani@nvidia.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@latenighthackathon latenighthackathon deleted the fix/slack-token-validation branch May 18, 2026 05:11
@wscurran wscurran added area: install Install, setup, prerequisites, or uninstall flow area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow bug-fix PR fixes a bug or regression needs: rebase PR needs rebase or conflict resolution and removed Getting Started bug Something fails against expected or documented behavior labels Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: install Install, setup, prerequisites, or uninstall flow area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow bug-fix PR fixes a bug or regression integration: slack Slack integration or channel behavior needs: rebase PR needs rebase or conflict resolution

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[All Platform] Slack Bot Token is accepted and saved without validation during setup

3 participants