Skip to content

[CTX-1227] feat: declare [settings] keys, user config honored (composer#18 follow-through) - #20

Merged
Xuepoo merged 1 commit into
mainfrom
ctx-1227/settings-declarations
Oct 15, 2026
Merged

Xuepoo merged 1 commit into
mainfrom
ctx-1227/settings-declarations

Conversation

@Xuepoo

@Xuepoo Xuepoo commented Oct 14, 2026

Copy link
Copy Markdown
Contributor

Priority: P1 | Area: composer | Labels: feat,P1 | Milestone: v0.1.0 | Task: CTX-1227

Follow-through on #18 (already CLOSED; activation proven). #19 kept activation alive with a fail-to-default pcall guard because the pinned SDK (862e29e) rejected [settings] as manifest.unknown-key (tripwire test held the line). SDK#152 is now merged (bitty-plugin-sdk#f6fc2f7): the linter admits [settings] and MockHost enforces the declared-keys gate. This PR lands the declarations.

Changes

  • Manifest [settings]: declares exactly the 5 keys init.lua reads — newline/submit/close/external_editor/open_chord, all { type = "string", default = ... } with defaults mirroring M.DEFAULT_KEYS/M.DEFAULT_OPEN_CHORD (enter, ctrl+enter, escape, alt+e, alt+e). Verbatim the SDK#151 snippet; shapes per SDK#152 SettingDecl validation (key grammar, kind/default agreement, string bounds).
  • SDK bump 862e29e -> f6fc2f7 (package.json + bun.lock) so just manifest and the mock enforce the same contract as the host.
  • pcall guard KEPT as defense-in-depth (not removed): on the success path it is a no-op (declared reads serve user config or the shipped default); it only fires on nonconforming or future host failure modes, converting them to defaults instead of reintroducing the exact [bug] Activation fails: settings.get without [settings] declarations (E_SETTINGS_UNDECLARED) #18 activation-kill shape. Removing it would trade a harmless one-pcall-per-key registration cost for a re-exposed single point of activation failure. The throwing-settings.get test still proves the guard.
  • init.lua open_chord fallback fix (1 line): open_chord, open_err = parse(default) overwrote the original parse error with the default's nil error, so the KEYS_FALLBACK note below was dead code — an invalid custom open_chord fell back silently while every other invalid chord records the diagnostic. Now keeps the original error; fallback chord still the shipped default. Found by the new invalid-open_chord test (red before, green after).

Tests (tripwire removed, declarations-live suite)

  • manifest declares exactly the five settings keys init.lua reads: model-level (loadManifestModel) kinds + defaults match shipped values.
  • wrong-typed stored values fail to defaults with no fallback (updated): mock serves defaults at read like the host; last_code "ok", default chords route.
  • custom values are honored across all five keys: all four roles remapped end to end (newline/submit/close/editor routing) + valid custom open_chord leaves no fallback.
  • an unparseable custom open_chord falls back with KEYS_FALLBACK + custom open_chord reaches the keymap suggestion (suggest-arg capture: ctrl+o honored, unset serves alt+e).
  • undeclared keys stay denied with E_SETTINGS_UNDECLARED: get AND set outside the five fail closed; declared-unset serves defaults.
  • Gates: just check green (fmt, markdownlint, metadata, hygiene, paths, manifest 0 errors, lua, lua-control, bun test 77 pass / 0 fail across 5 files).

Do NOT merge (commander integrates after review + CI).

@Xuepoo Xuepoo added this to the v0.1.0 milestone Oct 15, 2026
@Xuepoo Xuepoo added bug Something isn't working P1 labels Oct 15, 2026
@Xuepoo
Xuepoo merged commit de75a3f into main Oct 15, 2026
7 checks passed
@Xuepoo
Xuepoo deleted the ctx-1227/settings-declarations branch October 15, 2026 00:41
Xuepoo added a commit that referenced this pull request Oct 19, 2026
composer#23 reports activation aborting on Bitty 0.0.24 with
`E_SETTINGS_UNDECLARED` for `newline`. The five declarations landed in
`de75a3f` (PR #20); the runtime matrix installed `c9e94c4`, a stale
pre-declaration branch, so main was already past the defect while the
empty-settings and explicit-value activation paths were not pinned against
the declared key set.

Add `tests/settings-declarations.test.ts`:

- the manifest `[settings]` key set must equal exactly the keys
  registration reads (`M.DEFAULT_KEYS` plus `open_chord`), derived from the
  entry point instead of a hand-maintained list;
- declared kinds and shipped defaults must match the Lua fallbacks;
- activation must succeed with an empty settings file and with no settings
  bridge values at all, routing the shipped default chords (Enter inserts,
  Ctrl+Enter submits);
- explicit `newline`/`submit` values must be honored;
- the declared-key model must stay closed, which is the shape the host
  turns into `E_SETTINGS_UNDECLARED`.

Task: CTX-0010
Closes #23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working P1

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant