Skip to content

Add shared config unmarshalling helper for hook executors #7695

Description

@wbreza

Add shared config unmarshalling helper for hook executors

Background & Motivation
Each hook executor will need to unmarshal execCtx.Config (a map[string]any) into a strongly-typed struct. Rather than duplicating unmarshalling logic across every executor, we should provide a shared helper that handles the conversion, nil-safety, and error formatting consistently.

User Story
As a hook executor developer, I want a shared helper to unmarshal the Config property bag into a typed struct so that I don't duplicate boilerplate across executors.

Solution Approach

  • Create a generic helper function in pkg/tools/ (or pkg/ext/):
    // UnmarshalHookConfig unmarshals the raw config map into a typed struct.
    // Returns a zero-value T if config is nil or empty.
    func UnmarshalHookConfig[T any](config map[string]any) (T, error)
  • Implementation: re-marshal map[string]any → JSON → unmarshal into T (same pattern used by ai.ParseConfig and UnmarshalStruct elsewhere in the codebase)
  • Handle nil/empty config gracefully (return zero-value struct, no error)
  • Provide clear error messages on type mismatches
  • Each executor calls this in Prepare():
    cfg, err := tools.UnmarshalHookConfig[nodeHookConfig](execCtx.Config)
    if err != nil {
        return fmt.Errorf("invalid hook config for JS executor: %w", err)
    }

Example Usage in Executors

// In js_executor.go Prepare():
type nodeHookConfig struct {
    PackageManager string `json:"packageManager"`
}

cfg, err := tools.UnmarshalHookConfig[nodeHookConfig](execCtx.Config)
if err != nil {
    return fmt.Errorf("invalid JS hook config: %w", err)
}
// cfg.PackageManager is now typed and ready to use

Acceptance Criteria

  • Generic helper function UnmarshalHookConfig[T] exists and is tested
  • Nil/empty config returns zero-value struct with no error
  • Invalid types produce clear error messages (e.g., packageManager: 123 when string expected)
  • Works with all executor config structs (nodeHookConfig, pythonHookConfig, dotnetHookConfig)
  • Unit tests covering nil config, empty config, valid config, and type mismatch cases
  • Follows existing patterns (ai.ParseConfig, UnmarshalStruct)

Default when omitted: N/A — this is a helper, not a user-facing config

Out of Scope

  • Config validation beyond type checking (each executor validates its own values)
  • Schema generation from config structs

Testing Expectations

  • Unit tests: table-driven tests with various config shapes
  • Test nil safety, empty map safety, type mismatch errors
  • Test with representative structs from each executor

Related Issues

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions