Skip to content

feat(kiloclaw): derive config endpoint secret status from catalog#1033

Merged
St0rmz1 merged 1 commit intomainfrom
feat/catalog-driven-config-status
Mar 11, 2026
Merged

feat(kiloclaw): derive config endpoint secret status from catalog#1033
St0rmz1 merged 1 commit intomainfrom
feat/catalog-driven-config-status

Conversation

@St0rmz1
Copy link
Contributor

@St0rmz1 St0rmz1 commented Mar 11, 2026

Summary

Replaces the hardcoded per-field channel booleans in GET /api/kiloclaw/config with a catalog-driven configuredSecrets: Record<string, boolean> map keyed by catalog entry ID. This is the P0 future item from the secret-catalog-registry plan.

Before: The config endpoint returned channels: { telegram: bool, discord: bool, slackBot: bool, slackApp: bool } and the UI needed a manual isEntryConfigured() switch to map these per-field booleans back to per-entry status. Adding a new secret type required updating both the endpoint and the switch.

After: The endpoint iterates SECRET_CATALOG entries and checks if all fields have values, returning configuredSecrets: { telegram: bool, discord: bool, slack: bool }. The UI reads configuredSecrets[entry.id] directly — no manual mapping needed. New catalog entries get status automatically.

Verification

  • All 546 kiloclaw worker tests pass (29 suites)
  • All 41 secret-catalog package tests pass (2 new for getFieldKeysByCategory)
  • All 2525 cloud app tests pass (161 suites)
  • TypeScript typecheck passes across all packages
  • Prettier formatting passes
  • 8 new unit tests for buildConfiguredSecrets covering:
  • No secrets configured → all false
  • Single-field entry via encryptedSecrets (env var key lookup)
  • Multi-field entry (Slack) partial vs full
  • Legacy channels fallback when encryptedSecrets is null
  • Precedence: encryptedSecrets preferred over legacy channels
  • Non-channel keys in legacy storage don't false-positive
  • Result keys match catalog entry IDs
  • Null values treated as not configured

Visual Changes

None — the UI renders identically. SecretEntrySection still receives a configured: boolean prop; only the source of that boolean changed (from a hardcoded switch to a direct map lookup). The "Configured" / "Not configured" labels, placeholder text, and Remove button visibility are all unchanged.

Reviewer Notes

  • API shape change: UserConfigResponse.channels is replaced by configuredSecrets. This is consumed only by SettingsTab.tsx (verified via grep), which is updated in this PR. Both the worker and Next.js app change in this PR and deploy within minutes of each other. If they're briefly out of sync, the only effect is channels temporarily showing "Not configured" in the Settings tab — no errors, no data loss, tokens remain functional on the Fly machine.
  • encryptedSecrets storage uses env var names as keys (e.g. TELEGRAM_BOT_TOKEN), not field keys. This was verified against updateSecrets() line 446 which remaps via FIELD_KEY_TO_ENV_VAR before persisting, and confirmed by existing DO test fixtures. The field.envVar lookup in buildConfiguredSecrets is correct.
  • Legacy backward compat: Instances provisioned before the catalog migration store tokens in the channels field (keyed by field key, e.g. telegramBotToken). buildConfiguredSecrets checks both paths so these instances still report correct status.
  • buildConfiguredSecrets is exported solely for unit testability.
  • getFieldKeysByCategory allocates per call — documented in JSDoc. Currently only called once at module level, so no perf concern.

slackBot: !!config.channels?.slackBotToken,
slackApp: !!config.channels?.slackAppToken,
},
configuredSecrets: buildConfiguredSecrets(config),
Copy link
Contributor

Choose a reason for hiding this comment

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

WARNING: Keep the legacy channels field for a rollout window

cloud and the KiloClaw worker deploy independently (KILOCLAW_API_URL points the web app at an external worker). Removing channels here means an older web build will see config.channels === undefined and temporarily render every channel as not configured until the frontend rollout completes. Returning both configuredSecrets and the legacy channels booleans for one release avoids that cross-service break.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Acknowledged, this is documented in the Reviewer Notes. Both the worker and Next.js app change in this PR and deploy within minutes of each other. If briefly out of sync, the only effect is channels temporarily showing "Not configured" in the Settings tab. No errors, no data loss, tokens remain functional on the Fly machine.

@kilo-code-bot
Copy link
Contributor

kilo-code-bot bot commented Mar 11, 2026

Code Review Summary

Status: 1 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0

Fix these issues in Kilo Cloud

Issue Details (click to expand)

WARNING

File Line Issue
src/app/(app)/claw/components/SettingsTab.tsx 92 Frontend-first rollout drops the legacy channels fallback and will show all entries as unconfigured until the worker deploy lands.
Other Observations (not in diff)

None.

Files Reviewed (7 files)
  • kiloclaw/packages/secret-catalog/src/__tests__/catalog.test.ts - 0 issues
  • kiloclaw/packages/secret-catalog/src/catalog.ts - 0 issues
  • kiloclaw/packages/secret-catalog/src/index.ts - 0 issues
  • kiloclaw/src/routes/kiloclaw.test.ts - 0 issues
  • kiloclaw/src/routes/kiloclaw.ts - 0 new issues
  • src/app/(app)/claw/components/SettingsTab.tsx - 1 issue
  • src/lib/kiloclaw/types.ts - 0 issues

Reviewed by gpt-5.4-20260305 · 467,485 tokens

@St0rmz1 St0rmz1 force-pushed the feat/catalog-driven-config-status branch from 96af637 to 4449a15 Compare March 11, 2026 21:46
slackBot: false,
slackApp: false,
};
const configuredSecrets = config?.configuredSecrets ?? {};
Copy link
Contributor

Choose a reason for hiding this comment

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

WARNING: Frontend-first rollout marks every channel as not configured

This component now reads only configuredSecrets. If the Next.js deploy lands before the worker change, older /api/kiloclaw/config responses only contain channels, so all entries fall back to false until the worker is rolled out. Keep the old config.channels mapping as a temporary fallback until both deployments are live.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Prev acknowledged, this is documented in the Reviewer Notes. Both the worker and Next.js app change in this PR and deploy within minutes of each other. If briefly out of sync, the only effect is channels temporarily showing "Not configured" in the Settings tab. No errors, no data loss, tokens remain functional on the Fly machine.

@St0rmz1 St0rmz1 merged commit f6fa22e into main Mar 11, 2026
18 checks passed
@St0rmz1 St0rmz1 deleted the feat/catalog-driven-config-status branch March 11, 2026 21:53
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.

2 participants