Skip to content

feat(appstash): add per-context vars, getClientConfig with 3-tier resolution#70

Merged
pyramation merged 1 commit intomainfrom
devin/1773361555-appstash-config-vars-client-config
Mar 13, 2026
Merged

feat(appstash): add per-context vars, getClientConfig with 3-tier resolution#70
pyramation merged 1 commit intomainfrom
devin/1773361555-appstash-config-vars-client-config

Conversation

@pyramation
Copy link
Contributor

feat(appstash): add per-context vars and getClientConfig with 3-tier resolution

Summary

Extends ConfigStore with two new capabilities for CLI credential bridging and local key-value config:

  1. Per-context key-value vars (setVar/getVar/deleteVar/listVars) — stored in ~/.toolname/config/vars/<context>.json, scoped per-context so different environments can have different values (e.g. orgId, defaultDatabase).

  2. getClientConfig(targetName, contextName?) — returns { endpoint, headers } using 3-tier resolution following the AWS SDK pattern:

    • Tier 1: appstash store (context endpoint + credentials)
    • Tier 2: env vars (TOOLNAME_TOKEN, TOOLNAME_TARGET_ENDPOINT, TOOLNAME_ENDPOINT)
    • Tier 3: throws with actionable error message

Also fixes a pre-existing bug: the module-level DEFAULT_SETTINGS object was shared by reference across all store instances via readJson. When setCurrentContext mutated the returned settings object, it polluted the default for all subsequent stores. Fixed by deep-cloning fallback values in readJson.

Review & Testing Checklist for Human

  • Orphaned vars on context deletion: deleteContext does NOT clean up vars/<name>.json. Verify this is acceptable or if cleanup should be added.
  • readJson deep-clone via JSON.parse(JSON.stringify(...)): Works for JSON-serializable fallbacks (which is all current usage), but would silently drop non-serializable values if ever used with them. Confirm this is acceptable.
  • getClientConfig returns endpoint without auth when credentials are missing/expired: Tier 1 intentionally returns the endpoint with empty headers if no valid credentials exist. Verify SDK consumers handle unauthenticated responses gracefully.
  • Env var naming convention (TOOLNAME_TARGET_ENDPOINT): This convention will need to be matched by the constructive codegen in Phase 2. Verify the naming pattern is what you want before publishing.
  • Run npm test in packages/appstash — all 75 tests should pass (31 new).

Notes

  • This is Phase 1 of a two-part implementation. Phase 2 (constructive codegen: generated helpers.ts, config commands, BuiltinNames collision handling) will come after this is published.
  • ESLint is broken at the repo level (missing eslint.config.js for ESLint v9) — pre-existing, not related to this change.
  • Link to Devin session: https://app.devin.ai/sessions/6f16c8a57231488085f04a68be7d599b
  • Requested by: @pyramation

…olution

- Add setVar/getVar/deleteVar/listVars for per-context key-value storage
- Add getClientConfig(targetName) with 3-tier resolution: store → env vars → throw
- Export ClientConfig type
- Fix readJson shared-reference mutation bug (DEFAULT_SETTINGS was being mutated across stores)
- Add comprehensive tests for vars and getClientConfig (31 new test cases)
@devin-ai-integration
Copy link

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@pyramation pyramation merged commit 33e8ace into main Mar 13, 2026
36 checks passed
devin-ai-integration bot pushed a commit to constructive-io/constructive that referenced this pull request Mar 13, 2026
…on handling

Phase 2 of credential management and config system:

- Add config to BuiltinNames interface with collision handling (renames to 'vars' if target named 'config')
- Generate helpers.ts with typed per-target client factories using 3-tier credential resolution
- Generate config command (get/set/list/delete) wired to appstash store.getVar/setVar/deleteVar/listVars
- Update command map generator to include config built-in command
- Update appstash dependency to ^0.6.0
- Add comprehensive tests for new functionality (59 tests passing)

Builds on appstash@0.6.0 (published via constructive-io/dev-utils#70)
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