Skip to content

feat(kiloclaw): add @kilocode/kiloclaw-secret-catalog package#857

Merged
St0rmz1 merged 11 commits intomainfrom
feat/secret-catalog-package
Mar 6, 2026
Merged

feat(kiloclaw): add @kilocode/kiloclaw-secret-catalog package#857
St0rmz1 merged 11 commits intomainfrom
feat/secret-catalog-package

Conversation

@St0rmz1
Copy link
Copy Markdown
Contributor

@St0rmz1 St0rmz1 commented Mar 5, 2026

Summary

Adds a new shared workspace package (@kilocode/kiloclaw-secret-catalog) that provides a declarative registry of secret types for KiloClaw. Migrates channel definitions (Telegram, Discord, Slack) from hardcoded config in channel-config.tsx into a serializable catalog with types, validation patterns, lookup helpers, and env var mappings.

Verification

  • pnpm test — 27 unit tests pass (uniqueness, regex safety, backtracking, env var mappings, validation)
  • Validation patterns match existing channel-config.tsx regex exactly
  • All field keys, labels, placeholders, and validation messages are faithful migrations
  • maxLength set on all fields (100 Telegram, 200 Discord, 300 Slack)
  • Package builds as ESM with no runtime dependencies

Visual Changes

N/A

Reviewer Notes

  • This package has no consumers yet. Later PRs will wire it into the worker, tRPC layer, and UI respectively.
  • validationPattern is stored as a string (not RegExp) for JSON serializability across Next.js and CF Worker boundaries.
  • maxLength enforcement happens at the zod/input layer in PR 3, not in validateFieldValue() — documented in JSDoc.
  • Discord regex lazy quantifier ({24,}?) is preserved from the original channel-config.tsx; comment explains why.

@St0rmz1 St0rmz1 force-pushed the feat/secret-catalog-package branch from 7817c3b to 587cb73 Compare March 5, 2026 19:00
Comment thread kiloclaw/packages/secret-catalog/src/types.ts Outdated
Comment thread kiloclaw/packages/secret-catalog/src/catalog.ts Outdated
Comment thread kiloclaw/packages/secret-catalog/src/validation.ts Outdated
@kilo-code-bot
Copy link
Copy Markdown
Contributor

kilo-code-bot Bot commented Mar 5, 2026

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (10 files)
  • .github/workflows/ci.yml
  • kiloclaw/packages/secret-catalog/package.json
  • kiloclaw/packages/secret-catalog/src/__tests__/catalog.test.ts
  • kiloclaw/packages/secret-catalog/src/catalog.ts
  • kiloclaw/packages/secret-catalog/src/index.ts
  • kiloclaw/packages/secret-catalog/src/types.ts
  • kiloclaw/packages/secret-catalog/src/validation.ts
  • kiloclaw/packages/secret-catalog/tsconfig.json
  • kiloclaw/packages/secret-catalog/vitest.config.ts
  • pnpm-workspace.yaml

Comment thread kiloclaw/packages/secret-catalog/src/validation.ts Outdated
Comment thread kiloclaw/packages/secret-catalog/src/catalog.ts Outdated
Comment thread kiloclaw/packages/secret-catalog/package.json
Comment thread kiloclaw/packages/secret-catalog/src/types.ts Outdated
Comment thread kiloclaw/packages/secret-catalog/src/catalog.ts Outdated
Comment thread kiloclaw/packages/secret-catalog/src/__tests__/catalog.test.ts Outdated
Comment thread kiloclaw/packages/secret-catalog/src/__tests__/catalog.test.ts Outdated
@St0rmz1 St0rmz1 requested review from pandemicsyn and tspader March 5, 2026 23:51
Comment thread kiloclaw/packages/secret-catalog/src/types.ts Outdated
Comment thread kiloclaw/packages/secret-catalog/package.json
Comment thread kiloclaw/packages/secret-catalog/src/__tests__/catalog.test.ts
Comment thread .github/workflows/ci.yml
  - Add Zod schemas for runtime validation of catalog structure
  - Derive TypeScript types via z.infer<> (single source of truth)
  - Validate catalog at module load with z.array().parse()
  - Use as const satisfies for literal type preservation
  - Export schemas for reuse in downstream PR mutations
  - Add typecheck + test CI steps for secret-catalog package
  - Strengthen ReDoS test with near-match inputs
Comment thread kiloclaw/packages/secret-catalog/tsconfig.json Outdated
Comment thread kiloclaw/packages/secret-catalog/src/types.ts Outdated
@St0rmz1 St0rmz1 merged commit 33ad856 into main Mar 6, 2026
13 checks passed
@St0rmz1 St0rmz1 deleted the feat/secret-catalog-package branch March 6, 2026 19:51
St0rmz1 added a commit that referenced this pull request Mar 9, 2026
…g lookups (#907)

<!-- PR title format: type(scope): description — e.g., feat(auth): add
SSO login -->
<!-- Keep the title under 72 characters, use imperative mood, no
trailing period. -->

## Summary
Replace hardcoded channel-to-env-var mappings in the CF Worker with
catalog-derived
lookups from @kilocode/kiloclaw-secret-catalog (PR1, #857). Behavior is
identical —
  only the source of truth changes.

- Replace CHANNEL_ENV_MAP in encryption.ts with FIELD_KEY_TO_ENV_VAR
from catalog
- Replace hardcoded SENSITIVE_KEYS in env.ts with catalog-derived
ALL_SECRET_ENV_VARS
- Unknown channel keys in DO state are gracefully skipped (warn +
continue) instead of
  silently ignored
  - Add ALL_SECRET_ENV_VARS export to the secret catalog package
<!-- What changed and why? Keep this brief and outcome-focused. -->
<!-- Include any architectural changes and enough context for a reviewer
unfamiliar with this code area. -->

## Verification

<!-- List the checks you ran and what passed. Add command output notes
when useful. -->

- [x] - pnpm --filter kiloclaw run test — 505 tests pass (504 existing +
1 new)
- [x] - pnpm --filter @kilocode/kiloclaw-secret-catalog run test — 30
tests pass
- [x]   - pnpm --filter kiloclaw run typecheck — clean
- [x] - New buildEnvVars equivalence test confirms catalog-derived
SENSITIVE_KEYS classifies
- [x]   all 4 channel env vars identically to the old hardcoded set
- [x] - New test confirms unknown channel keys are skipped gracefully
without blocking
- [x]   machine startup




## Visual Changes

<!-- If UI/visual behavior changed, add before/after screenshots in the
table below. -->
<!-- If there are no visual changes, replace the table with: N/A -->
N/A

| Before | After |
| ------ | ----- |
|        |       |

## Reviewer Notes
  - Depends on #857 (already merged)
- Non-breaking: catalog contains the exact same 4 field→env-var mappings
that were
hardcoded (TELEGRAM_BOT_TOKEN, DISCORD_BOT_TOKEN, SLACK_BOT_TOKEN,
SLACK_APP_TOKEN)
- One subtle behavioral change: decryptChannelTokens now iterates over
input channels
keys instead of the old map keys. Unknown keys produce a console.warn +
skip rather
than being silently ignored — same outcome (key not in result) but with
observability

This doesn't touch storage. It only changes how the worker reads stored
data:
- DO state format is unchanged — channels field still holds
EncryptedChannelTokens
- Decryption logic (decryptWithPrivateKey) is unchanged
- Only the key→env-var mapping source changed (hardcoded map → catalog
map with identical values)


<!-- Optional: reviewer focus areas, edge cases, or context that helps
review quickly. -->
St0rmz1 added a commit that referenced this pull request Mar 9, 2026
… validation (#947)

<!-- PR title format: type(scope): description — e.g., feat(auth): add
SSO login -->
<!-- Keep the title under 72 characters, use imperative mood, no
trailing period. -->

## Summary

feat(kiloclaw): add generic patchSecrets endpoint with catalog-driven
validation

<!-- What changed and why? Keep this brief and outcome-focused. -->
<!-- Include any architectural changes and enough context for a reviewer
unfamiliar with this code area. -->

Adds patchSecrets tRPC mutation and PATCH /api/platform/secrets worker
endpoint
alongside existing patchChannels. Uses secret catalog for key
validation,
pattern matching, maxLength enforcement, and allFieldsRequired
enforcement.
                                                            
Makes updateChannels delegate to updateSecrets internally so both
storage fields
(channels + encryptedSecrets) stay in sync regardless of which endpoint
is
  called. Eliminates interleave drift risk.

  Key design decisions:
- Key remapping at storage boundary: encryptedSecrets stores env var
names
(e.g., TELEGRAM_BOT_TOKEN) so the existing
buildEnvVars/mergeEnvVarsWithSecrets
pipeline works unchanged. A reverse map (ENV_VAR_TO_FIELD_KEY) converts
back to
  field keys when reading into the working set.
- allFieldsRequired enforced at DO level: The DO validates post-merge
state
  (existing secrets + patch), not just the incoming patch. This allows
single-field rotations (e.g., rotating slackBotToken when slackAppToken
is
  already stored) while still rejecting invalid partial clears.
- secretCount excludes channel env vars: Channel tokens are dual-written
into
encryptedSecrets but excluded from secretCount (via CHANNEL_ENV_VARS
filter)
  since they're already counted by channelCount. Applied in getStatus(),
  getDebugState(), and /api/kiloclaw/config.
- Validation errors return 400: DO validation errors carry status: 400
and an
Invalid secret patch: prefix so the route handler returns the actual
message
  instead of a generic 500.


## Verification
- Catalog package tests pass (37 tests) — includes new allFieldsRequired
contract, maxLength contract, and unknown key rejection tests
- DO updateSecrets tests pass (8 tests) — set, remove, merge, legacy
migration, Slack dual-token set/clear, channel-only filtering
- DO updateChannels tests pass (8 tests) — all 6 existing tests pass
through delegation path, plus 2 new interleave consistency tests
- updateChannels delegation produces identical boolean return shape as
original implementation
- Worker builds without errors (wrangler types + wrangler deploy
--dry-run)
- Integration: provision instance via patchChannels, update via
patchSecrets, verify both endpoints see consistent state

## Visual Changes
N/A

## Reviewer Notes

- Dual-write strategy: updateSecrets writes to both channels (legacy,
field-keyed) and encryptedSecrets (new, env-var-keyed). Channel-category
keys go to both; future non-channel secrets (tools, providers) only go
to encryptedSecrets.
- updateChannels delegation: The old method now delegates to
updateSecrets. This is the fix for the interleave drift edge case;
there's now a single write path. Existing updateChannels callers see no
behavior change.
- tRPC defers allFieldsRequired to DO: The tRPC layer validates key
membership, patterns, and maxLength, but does not check
allFieldsRequired — only the DO can see existing state to validate
post-merge correctness.
- configured response filtered: The configured array returned by
updateSecrets is filtered to ALL_SECRET_FIELD_KEYS only, preventing
non-catalog env var names from leaking into the response.
- Rate limiting: Not yet applied to patchSecrets. Should match whatever
strategy patchChannels uses. Can be added as a follow-up.
- tRPC-level integration tests: Validation logic is tested via catalog
contract tests and DO-level tests rather than full tRPC caller tests,
since the router test infrastructure requires real DB + user setup +
worker client mocking.
- Depends on: PR #857 (@kilocode/kiloclaw-secret-catalog package)
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