//go:build ignore

// context-inject.go — Injects context from a local file into every LLM turn.
//
// Reads a context file (default: .kit/context.md) and prepends it as a system
// message to every LLM context window via OnContextPrepare. This is useful for
// injecting project-specific knowledge, coding standards, or RAG results that
// should always be visible to the model — without cluttering the session history.
//
// The injected message does NOT persist in the session tree (it's ephemeral,
// added at query time only). This means:
//   - Changing the context file immediately affects future turns
//   - No session bloat from repeated context injection
//   - The model always sees the latest version of the context
//
// Configuration:
//
//	KIT_OPT_CONTEXT_FILE  — path to context file (default: .kit/context.md)
//
// Usage:
//
//	kit -e examples/extensions/context-inject.go
//	echo "Always use error wrapping with fmt.Errorf" > .kit/context.md
package main

import (
	"fmt"
	"os"
	"strings"

	ext "kit/ext"
)

func Init(api ext.API) {
	api.RegisterOption(ext.OptionDef{
		Name:        "context-file",
		Description: "Path to the context file to inject into every turn",
		Default:     ".kit/context.md",
	})

	api.OnContextPrepare(func(e ext.ContextPrepareEvent, ctx ext.Context) *ext.ContextPrepareResult {
		path := ctx.GetOption("context-file")
		if path == "" {
			return nil
		}

		data, err := os.ReadFile(path)
		if err != nil {
			// File doesn't exist or can't be read — skip silently.
			return nil
		}

		content := strings.TrimSpace(string(data))
		if content == "" {
			return nil
		}

		// Prepend a system message with the context file contents.
		injected := ext.ContextMessage{
			Index:   -1,
			Role:    "system",
			Content: fmt.Sprintf("[Project Context from %s]\n\n%s", path, content),
		}

		msgs := make([]ext.ContextMessage, 0, len(e.Messages)+1)
		msgs = append(msgs, injected)
		msgs = append(msgs, e.Messages...)

		return &ext.ContextPrepareResult{Messages: msgs}
	})

	api.RegisterCommand(ext.CommandDef{
		Name:        "context",
		Description: "Show or edit the injected context file path",
		Execute: func(args string, ctx ext.Context) (string, error) {
			path := ctx.GetOption("context-file")
			data, err := os.ReadFile(path)
			if err != nil {
				return fmt.Sprintf("Context file: %s (not found or unreadable)", path), nil
			}
			lines := strings.Split(strings.TrimSpace(string(data)), "\n")
			preview := strings.Join(lines, "\n")
			if len(lines) > 10 {
				preview = strings.Join(lines[:10], "\n") + "\n..."
			}
			return fmt.Sprintf("Context file: %s (%d lines)\n\n%s", path, len(lines), preview), nil
		},
	})
}
