Function bodies 513 total
goplugin.pluginContext.GitDiff method · go · L447-L455 (9 LOC)internal/skills/goplugin/goplugin.go
func (c *pluginContext) GitDiff(args ...string) (string, error) {
if err := c.checker.CheckPermission(skills.PermGitRead); err != nil {
return "", fmt.Errorf("GitDiff: %w", err)
}
if c.gitRunner == nil {
return "", fmt.Errorf("GitDiff: git runner not configured")
}
return c.gitRunner.Diff(args...)
}goplugin.pluginContext.GitLog method · go · L458-L466 (9 LOC)internal/skills/goplugin/goplugin.go
func (c *pluginContext) GitLog(args ...string) ([]skillsdk.GitCommit, error) {
if err := c.checker.CheckPermission(skills.PermGitRead); err != nil {
return nil, fmt.Errorf("GitLog: %w", err)
}
if c.gitRunner == nil {
return nil, fmt.Errorf("GitLog: git runner not configured")
}
return c.gitRunner.Log(args...)
}goplugin.pluginContext.GitStatus method · go · L469-L477 (9 LOC)internal/skills/goplugin/goplugin.go
func (c *pluginContext) GitStatus() ([]skillsdk.GitFileStatus, error) {
if err := c.checker.CheckPermission(skills.PermGitRead); err != nil {
return nil, fmt.Errorf("GitStatus: %w", err)
}
if c.gitRunner == nil {
return nil, fmt.Errorf("GitStatus: git runner not configured")
}
return c.gitRunner.Status()
}goplugin.pluginContext.GetEnv method · go · L480-L485 (6 LOC)internal/skills/goplugin/goplugin.go
func (c *pluginContext) GetEnv(key string) string {
if err := c.checker.CheckPermission(skills.PermEnvRead); err != nil {
return ""
}
return os.Getenv(key)
}goplugin.pluginContext.InvokeSkill method · go · L493-L501 (9 LOC)internal/skills/goplugin/goplugin.go
func (c *pluginContext) InvokeSkill(name string, input map[string]any) (map[string]any, error) {
if err := c.checker.CheckPermission(skills.PermSkillInvoke); err != nil {
return nil, fmt.Errorf("InvokeSkill: %w", err)
}
if c.skillInvoker == nil {
return nil, fmt.Errorf("InvokeSkill: skill invoker not configured")
}
return c.skillInvoker.Invoke(name, input)
}main.testPlugin.Manifest method · go · L15-L23 (9 LOC)internal/skills/goplugin/testdata/testplugin.go
func (p *testPlugin) Manifest() skillsdk.Manifest {
return skillsdk.Manifest{
Name: "test-plugin",
Version: "1.0.0",
Description: "A test plugin",
Author: "test",
License: "MIT",
}
}skills.LifecycleManager.Register method · go · L57-L66 (10 LOC)internal/skills/hooks.go
func (lm *LifecycleManager) Register(phase HookPhase, skillName string, priority int, handler HookHandler) {
lm.mu.Lock()
defer lm.mu.Unlock()
lm.handlers[phase] = append(lm.handlers[phase], skillHookEntry{
skillName: skillName,
priority: priority,
handler: handler,
})
}Source: Repobility analyzer · https://repobility.com
skills.LifecycleManager.Unregister method · go · L69-L86 (18 LOC)internal/skills/hooks.go
func (lm *LifecycleManager) Unregister(skillName string) {
lm.mu.Lock()
defer lm.mu.Unlock()
for phase, entries := range lm.handlers {
filtered := entries[:0]
for _, e := range entries {
if e.skillName != skillName {
filtered = append(filtered, e)
}
}
if len(filtered) == 0 {
delete(lm.handlers, phase)
} else {
lm.handlers[phase] = filtered
}
}
}skills.LifecycleManager.Dispatch method · go · L100-L148 (49 LOC)internal/skills/hooks.go
func (lm *LifecycleManager) Dispatch(event HookEvent) (*HookResult, error) {
// Snapshot handlers under read lock, then release before calling them.
lm.mu.RLock()
entries, ok := lm.handlers[event.Phase]
if !ok || len(entries) == 0 {
lm.mu.RUnlock()
return nil, nil
}
sorted := make([]skillHookEntry, len(entries))
copy(sorted, entries)
lm.mu.RUnlock()
// Sort by priority (stable sort preserves registration order for equal priorities).
sort.SliceStable(sorted, func(i, j int) bool {
return sorted[i].priority < sorted[j].priority
})
isCancellable := cancellablePhases[event.Phase]
isModifying := modifyingPhases[event.Phase]
var lastResult *HookResult
for _, entry := range sorted {
result, err := entry.handler(event)
if err != nil {
return nil, fmt.Errorf("hook handler %q (phase %s) failed: %w",
entry.skillName, event.Phase, err)
}
lastResult = &result
// For cancellable phases, stop on first cancellation.
if isCancellable && result.Cancel {
reskills.SecurityRuleAdapter.RegisterScanner method · go · L43-L51 (9 LOC)internal/skills/integration.go
func (a *SecurityRuleAdapter) RegisterScanner(skillName, scannerName string, fn ScannerFunc) {
a.mu.Lock()
defer a.mu.Unlock()
a.scanners = append(a.scanners, RegisteredScanner{
SkillName: skillName,
Name: scannerName,
Scan: fn,
})
}skills.SecurityRuleAdapter.Scanners method · go · L54-L60 (7 LOC)internal/skills/integration.go
func (a *SecurityRuleAdapter) Scanners() []RegisteredScanner {
a.mu.RLock()
defer a.mu.RUnlock()
result := make([]RegisteredScanner, len(a.scanners))
copy(result, a.scanners)
return result
}skills.SecurityRuleAdapter.UnregisterBySkill method · go · L63-L73 (11 LOC)internal/skills/integration.go
func (a *SecurityRuleAdapter) UnregisterBySkill(skillName string) {
a.mu.Lock()
defer a.mu.Unlock()
var filtered []RegisteredScanner
for _, s := range a.scanners {
if s.SkillName != skillName {
filtered = append(filtered, s)
}
}
a.scanners = filtered
}skills.PromptCollector.Fragments method · go · L104-L110 (7 LOC)internal/skills/integration.go
func (pc *PromptCollector) Fragments() []PromptFragment {
pc.mu.RLock()
defer pc.mu.RUnlock()
result := make([]PromptFragment, len(pc.fragments))
copy(result, pc.fragments)
return result
}skills.PromptCollector.RemoveBySkill method · go · L113-L123 (11 LOC)internal/skills/integration.go
func (pc *PromptCollector) RemoveBySkill(skillName string) {
pc.mu.Lock()
defer pc.mu.Unlock()
var filtered []PromptFragment
for _, f := range pc.fragments {
if f.SkillName != skillName {
filtered = append(filtered, f)
}
}
pc.fragments = filtered
}skills.WorkflowRunner.Invoke method · go · L151-L159 (9 LOC)internal/skills/integration.go
func (wr *WorkflowRunner) Invoke(ctx context.Context, name string, args map[string]any) (map[string]any, error) {
wr.mu.RLock()
handler, ok := wr.workflows[name]
wr.mu.RUnlock()
if !ok {
return nil, fmt.Errorf("workflow %q not found", name)
}
return handler(ctx, args)
}Repobility · code-quality intelligence · https://repobility.com
skills.wirePromptSkill function · go · L172-L211 (40 LOC)internal/skills/integration.go
func wirePromptSkill(rt *Runtime, sk *Skill) {
fragment := PromptFragment{
SkillName: sk.Manifest.Name,
SystemPromptFile: sk.Manifest.Prompt.SystemPromptFile,
ContextFiles: sk.Manifest.Prompt.ContextFiles,
MaxContextTokens: sk.Manifest.Prompt.MaxContextTokens,
}
// Read the system prompt file content if a file path is specified and the
// skill has a directory on disk. For built-in skills (Dir=""), the
// SystemPromptFile value is used as inline content.
if sk.Manifest.Prompt.SystemPromptFile != "" {
if sk.Dir != "" {
promptPath := filepath.Join(sk.Dir, sk.Manifest.Prompt.SystemPromptFile)
data, err := os.ReadFile(promptPath)
if err != nil {
fragment.ResolvedPrompt = fmt.Sprintf("[error reading prompt file %q: %s]", promptPath, err)
} else {
fragment.ResolvedPrompt = string(data)
}
} else {
// Built-in skills without a directory use SystemPromptFile as
// inline content (no file to read).
fragment.ResolvedPrompt = sk.Manifesskills.wireSecurityRuleSkill function · go · L214-L219 (6 LOC)internal/skills/integration.go
func wireSecurityRuleSkill(rt *Runtime, sk *Skill) {
// The actual scanner functions are registered externally via
// rt.securityAdapter.RegisterScanner(). Here we just ensure the skill
// type is acknowledged during activation. Scanners may be pre-registered
// by the backend or by the caller before activation.
}skills.NewLoader function · go · L46-L52 (7 LOC)internal/skills/loader.go
func NewLoader(userDir, projectDir string) *Loader {
return &Loader{
userDir: userDir,
projectDir: projectDir,
builtins: make(map[string]*SkillManifest),
}
}skills.Loader.Discover method · go · L74-L189 (116 LOC)internal/skills/loader.go
func (l *Loader) Discover(explicit []string) ([]DiscoveredSkill, []string, error) {
explicitSet := make(map[string]bool, len(explicit))
for _, name := range explicit {
explicitSet[name] = true
}
// Collect skills from all directory sources.
// We build a map keyed by skill name; higher-priority sources overwrite lower ones.
byName := make(map[string]DiscoveredSkill)
// 1. Project skills (lowest directory priority).
projectSkills, err := scanDir(l.projectDir, SourceProject)
if err != nil {
return nil, nil, err
}
for _, ds := range projectSkills {
byName[ds.Manifest.Name] = ds
}
// 2. User skills override project skills.
userSkills, err := scanDir(l.userDir, SourceUser)
if err != nil {
return nil, nil, err
}
for _, ds := range userSkills {
byName[ds.Manifest.Name] = ds
}
// 3. Built-in skills override everything from directories.
for name, m := range l.builtins {
byName[name] = DiscoveredSkill{
Manifest: m,
Dir: "",
Source: SourceBuiltiskills.scanDir function · go · L193-L230 (38 LOC)internal/skills/loader.go
func scanDir(dir string, source Source) ([]DiscoveredSkill, error) {
entries, err := os.ReadDir(dir)
if err != nil {
if os.IsNotExist(err) {
return nil, nil
}
return nil, fmt.Errorf("scan skills dir %q: %w", dir, err)
}
var results []DiscoveredSkill
for _, entry := range entries {
if !entry.IsDir() {
continue
}
yamlPath := filepath.Join(dir, entry.Name(), "SKILL.yaml")
data, err := os.ReadFile(yamlPath)
if err != nil {
if os.IsNotExist(err) {
continue
}
return nil, fmt.Errorf("read skill manifest %q: %w", yamlPath, err)
}
manifest, err := ParseManifest(data)
if err != nil {
return nil, fmt.Errorf("parse skill %q: %w", entry.Name(), err)
}
results = append(results, DiscoveredSkill{
Manifest: manifest,
Dir: filepath.Join(dir, entry.Name()),
Source: source,
})
}
return results, nil
}skills.ParseManifest function · go · L181-L192 (12 LOC)internal/skills/manifest.go
func ParseManifest(data []byte) (*SkillManifest, error) {
var m SkillManifest
if err := yaml.Unmarshal(data, &m); err != nil {
return nil, fmt.Errorf("parse manifest: %w", err)
}
if err := validateManifest(&m); err != nil {
return nil, err
}
return &m, nil
}skills.validateManifest function · go · L194-L259 (66 LOC)internal/skills/manifest.go
func validateManifest(m *SkillManifest) error {
// Required fields.
if m.Name == "" {
return fmt.Errorf("manifest validation: name is required")
}
if m.Version == "" {
return fmt.Errorf("manifest validation: version is required")
}
if m.Description == "" {
return fmt.Errorf("manifest validation: description is required")
}
if len(m.Types) == 0 {
return fmt.Errorf("manifest validation: types is required (at least one skill type)")
}
// Name format and length.
const maxNameLength = 128
if len(m.Name) > maxNameLength {
return fmt.Errorf("manifest validation: name exceeds maximum length (%d > %d)", len(m.Name), maxNameLength)
}
if !nameRegex.MatchString(m.Name) {
return fmt.Errorf("manifest validation: invalid name %q (must match %s)", m.Name, nameRegex.String())
}
// Skill types.
for _, st := range m.Types {
if !validSkillTypes[st] {
return fmt.Errorf("manifest validation: unknown skill type %q", st)
}
}
// Permissions.
for _, p := range m.Permissmcpbackend.NewMCPBackend function · go · L27-L32 (6 LOC)internal/skills/mcpbackend/backend.go
func NewMCPBackend(serverName string, transport mcpclient.Transport) *MCPBackend {
return &MCPBackend{
serverName: serverName,
transport: transport,
}
}Repobility's GitHub App fixes findings like these · https://github.com/apps/repobility-bot
mcpbackend.NewMCPBackendFromConfig function · go · L37-L68 (32 LOC)internal/skills/mcpbackend/backend.go
func NewMCPBackendFromConfig(ctx context.Context, serverName, transport, command string, args []string, sseURL string) (*MCPBackend, error) {
var t mcpclient.Transport
var err error
switch transport {
case "stdio":
if command == "" {
return nil, fmt.Errorf("mcp backend: stdio transport requires a command")
}
t, err = mcpclient.NewStdioTransport(command, args)
if err != nil {
return nil, fmt.Errorf("mcp backend: create stdio transport: %w", err)
}
case "sse":
if sseURL == "" {
return nil, fmt.Errorf("mcp backend: sse transport requires a url")
}
initCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel()
t, err = mcpclient.NewSSETransport(initCtx, sseURL)
if err != nil {
return nil, fmt.Errorf("mcp backend: create sse transport: %w", err)
}
default:
return nil, fmt.Errorf("mcp backend: unsupported transport %q", transport)
}
return &MCPBackend{
serverName: serverName,
transport: t,
}, nil
}mcpbackend.MCPBackend.LoadWithContext method · go · L72-L90 (19 LOC)internal/skills/mcpbackend/backend.go
func (b *MCPBackend) LoadWithContext(ctx context.Context) error {
b.client = mcpclient.NewClient(b.serverName, b.transport)
if err := b.client.Initialize(ctx); err != nil {
return fmt.Errorf("initialize MCP server %q: %w", b.serverName, err)
}
mcpTools, err := b.client.ListTools(ctx)
if err != nil {
return fmt.Errorf("list MCP tools from %q: %w", b.serverName, err)
}
b.tools = make([]tools.Tool, len(mcpTools))
for i, mt := range mcpTools {
b.tools[i] = mcpclient.WrapTool(b.serverName, b.client, mt)
}
return nil
}mcpbackend.MCPBackend.Unload method · go · L109-L115 (7 LOC)internal/skills/mcpbackend/backend.go
func (b *MCPBackend) Unload() error {
b.tools = nil
if b.client != nil {
return b.client.Close()
}
return nil
}process.NewProcessBackend function · go · L79-L88 (10 LOC)internal/skills/process/manager.go
func NewProcessBackend(opts ...Option) *ProcessBackend {
b := &ProcessBackend{
callTimeout: defaultCallTimeout,
registeredHooks: make(map[skills.HookPhase]skills.HookHandler),
}
for _, opt := range opts {
opt(b)
}
return b
}process.ProcessBackend.Load method · go · L92-L122 (31 LOC)internal/skills/process/manager.go
func (b *ProcessBackend) Load(manifest skills.SkillManifest, checker skills.PermissionChecker) error {
if manifest.Implementation.Entrypoint == "" {
return fmt.Errorf("load process: entrypoint is required")
}
// Validate entrypoint is an absolute path to prevent executing arbitrary binaries.
if !filepath.IsAbs(manifest.Implementation.Entrypoint) {
return fmt.Errorf("load process: entrypoint must be an absolute path, got %q", manifest.Implementation.Entrypoint)
}
b.manifest = manifest
b.checker = checker
b.stopped = false
b.stopCh = make(chan struct{})
if err := b.startProcess(); err != nil {
return err
}
if err := b.initialize(); err != nil {
b.mu.Lock()
b.killAndCleanupLocked()
b.mu.Unlock()
return fmt.Errorf("load process %q: initialize failed: %w", manifest.Name, err)
}
// Start crash monitor goroutine with initial generation.
go b.monitorProcess(b.generation)
return nil
}process.ProcessBackend.Tools method · go · L126-L135 (10 LOC)internal/skills/process/manager.go
func (b *ProcessBackend) Tools() []tools.Tool {
b.mu.Lock()
defer b.mu.Unlock()
result := make([]tools.Tool, len(b.registeredTools))
for i := range b.registeredTools {
result[i] = &b.registeredTools[i]
}
return result
}process.ProcessBackend.Hooks method · go · L139-L148 (10 LOC)internal/skills/process/manager.go
func (b *ProcessBackend) Hooks() map[skills.HookPhase]skills.HookHandler {
b.mu.Lock()
defer b.mu.Unlock()
result := make(map[skills.HookPhase]skills.HookHandler, len(b.registeredHooks))
for k, v := range b.registeredHooks {
result[k] = v
}
return result
}process.ProcessBackend.Unload method · go · L152-L176 (25 LOC)internal/skills/process/manager.go
func (b *ProcessBackend) Unload() error {
b.mu.Lock()
defer b.mu.Unlock()
if b.cmd == nil {
return nil
}
b.stopped = true
// Signal the crash monitor to stop.
close(b.stopCh)
// Try to send shutdown gracefully.
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
b.callLocked(ctx, "shutdown", nil) //nolint: errcheck // best effort
b.killAndCleanupLocked()
b.registeredTools = nil
b.registeredHooks = make(map[skills.HookPhase]skills.HookHandler)
return nil
}Repobility · severity-and-effort ranking · https://repobility.com
process.ProcessBackend.call method · go · L180-L185 (6 LOC)internal/skills/process/manager.go
func (b *ProcessBackend) call(ctx context.Context, method string, params any) (*JSONRPCResponse, error) {
b.mu.Lock()
defer b.mu.Unlock()
return b.callLocked(ctx, method, params)
}process.ProcessBackend.callLocked method · go · L189-L241 (53 LOC)internal/skills/process/manager.go
func (b *ProcessBackend) callLocked(ctx context.Context, method string, params any) (*JSONRPCResponse, error) {
if b.cmd == nil {
return nil, fmt.Errorf("process not running")
}
id := int(b.nextID.Add(1))
req, err := NewRequest(id, method, params)
if err != nil {
return nil, fmt.Errorf("create request: %w", err)
}
data, err := json.Marshal(req)
if err != nil {
return nil, fmt.Errorf("marshal request: %w", err)
}
// Write request to stdin.
if _, err := fmt.Fprintf(b.stdin, "%s\n", data); err != nil {
return nil, fmt.Errorf("write to process stdin: %w", err)
}
// Apply call timeout.
deadline := b.callTimeout
if d, ok := ctx.Deadline(); ok {
remaining := time.Until(d)
if remaining < deadline {
deadline = remaining
}
}
// Read response from the dedicated reader goroutine's channel.
select {
case sr := <-b.readCh:
if !sr.ok {
return nil, fmt.Errorf("process closed stdout")
}
resp, err := DecodeResponse([]byte(sr.line))
if err != nil {
process.ProcessBackend.startProcess method · go · L246-L279 (34 LOC)internal/skills/process/manager.go
func (b *ProcessBackend) startProcess() error {
cmd := exec.Command(b.manifest.Implementation.Entrypoint)
stdin, err := cmd.StdinPipe()
if err != nil {
return fmt.Errorf("start process: pipe setup: %w", err)
}
stdout, err := cmd.StdoutPipe()
if err != nil {
return fmt.Errorf("start process: pipe setup: %w", err)
}
if err := cmd.Start(); err != nil {
return fmt.Errorf("start process %q: %w", b.manifest.Implementation.Entrypoint, err)
}
b.cmd = cmd
b.stdin = stdin
b.readCh = make(chan readResult, 1)
// Dedicated reader goroutine — owns the scanner and terminates when
// stdout is closed (process killed or exited).
go func(ch chan<- readResult) {
scanner := bufio.NewScanner(stdout)
scanner.Buffer(make([]byte, 1024*1024), 1024*1024)
for scanner.Scan() {
ch <- readResult{line: scanner.Text(), ok: true}
}
ch <- readResult{ok: false}
}(b.readCh)
return nil
}process.ProcessBackend.initialize method · go · L282-L335 (54 LOC)internal/skills/process/manager.go
func (b *ProcessBackend) initialize() error {
manifestData := map[string]any{
"name": b.manifest.Name,
"version": b.manifest.Version,
}
ctx, cancel := context.WithTimeout(context.Background(), b.callTimeout)
defer cancel()
resp, err := b.callLocked(ctx, "initialize", manifestData)
if err != nil {
return err
}
// Parse initialize result for tools and hooks.
var initResult struct {
Tools []struct {
Name string `json:"name"`
Description string `json:"description"`
InputSchema json.RawMessage `json:"input_schema"`
} `json:"tools"`
Hooks []string `json:"hooks"`
}
if err := json.Unmarshal(resp.Result, &initResult); err != nil {
return fmt.Errorf("parse initialize result: %w", err)
}
// Register tools.
b.registeredTools = make([]processTool, len(initResult.Tools))
for i, td := range initResult.Tools {
b.registeredTools[i] = processTool{
name: td.Name,
description: td.Description,
inputSchema: td.InputSchemprocess.ProcessBackend.handleHook method · go · L338-L364 (27 LOC)internal/skills/process/manager.go
func (b *ProcessBackend) handleHook(event skills.HookEvent, phase skills.HookPhase) (skills.HookResult, error) {
ctx := event.Ctx
if ctx == nil {
ctx = context.Background()
}
resp, err := b.call(ctx, "hook/handle", map[string]any{
"phase": phase.String(),
"data": event.Data,
})
if err != nil {
return skills.HookResult{}, fmt.Errorf("hook/handle: %w", err)
}
var hookResp struct {
Modified map[string]any `json:"modified"`
Cancel bool `json:"cancel"`
}
if err := json.Unmarshal(resp.Result, &hookResp); err != nil {
return skills.HookResult{}, fmt.Errorf("parse hook result: %w", err)
}
return skills.HookResult{
Modified: hookResp.Modified,
Cancel: hookResp.Cancel,
}, nil
}process.ProcessBackend.monitorProcess method · go · L369-L398 (30 LOC)internal/skills/process/manager.go
func (b *ProcessBackend) monitorProcess(gen int64) {
b.mu.Lock()
cmd := b.cmd
b.mu.Unlock()
if cmd == nil || cmd.Process == nil {
return
}
// Wait for the process to exit (does not need the lock — we captured cmd).
cmd.Wait() //nolint: errcheck
// Check if we were intentionally stopped.
select {
case <-b.stopCh:
return
default:
}
// Verify we are still the active monitor (generation hasn't changed).
b.mu.Lock()
if b.generation != gen || b.stopped {
b.mu.Unlock()
return
}
b.mu.Unlock()
// Process crashed unexpectedly -- restart with backoff.
b.restart(gen)
}process.ProcessBackend.restart method · go · L401-L446 (46 LOC)internal/skills/process/manager.go
func (b *ProcessBackend) restart(gen int64) {
backoff := 50 * time.Millisecond
maxBackoff := 5 * time.Second
maxAttempts := 5
for i := 0; i < maxAttempts; i++ {
select {
case <-b.stopCh:
return
case <-time.After(backoff):
}
b.mu.Lock()
if b.stopped || b.generation != gen {
b.mu.Unlock()
return
}
// Clean up old process state.
b.cmd = nil
b.stdin = nil
b.readCh = nil
if err := b.startProcess(); err != nil {
b.mu.Unlock()
backoff = min(backoff*2, maxBackoff)
continue
}
if err := b.initialize(); err != nil {
b.killAndCleanupLocked()
b.mu.Unlock()
backoff = min(backoff*2, maxBackoff)
continue
}
// Bump generation so the old monitor cannot race.
b.generation++
newGen := b.generation
b.mu.Unlock()
// Successfully restarted. Start monitoring again with new generation.
go b.monitorProcess(newGen)
return
}
}process.ProcessBackend.killProcess method · go · L449-L456 (8 LOC)internal/skills/process/manager.go
func (b *ProcessBackend) killProcess() {
b.mu.Lock()
defer b.mu.Unlock()
if b.cmd != nil && b.cmd.Process != nil {
b.cmd.Process.Kill() //nolint: errcheck
}
}Source: Repobility analyzer · https://repobility.com
process.ProcessBackend.killAndCleanupLocked method · go · L460-L471 (12 LOC)internal/skills/process/manager.go
func (b *ProcessBackend) killAndCleanupLocked() {
if b.cmd != nil && b.cmd.Process != nil {
b.cmd.Process.Kill() //nolint: errcheck
b.cmd.Wait() //nolint: errcheck
}
if b.stdin != nil {
b.stdin.Close() //nolint: errcheck
}
b.cmd = nil
b.stdin = nil
b.readCh = nil
}process.processTool.Execute method · go · L497-L518 (22 LOC)internal/skills/process/manager.go
func (pt *processTool) Execute(ctx context.Context, input json.RawMessage) (tools.ToolResult, error) {
resp, err := pt.backend.call(ctx, "tool/execute", map[string]any{
"name": pt.name,
"input": input,
})
if err != nil {
return tools.ToolResult{IsError: true, Content: err.Error()}, err
}
var toolResp struct {
Content string `json:"content"`
IsError bool `json:"is_error"`
}
if err := json.Unmarshal(resp.Result, &toolResp); err != nil {
return tools.ToolResult{IsError: true, Content: err.Error()}, fmt.Errorf("parse tool result: %w", err)
}
return tools.ToolResult{
Content: toolResp.Content,
IsError: toolResp.IsError,
}, nil
}process.parseHookPhase function · go · L524-L547 (24 LOC)internal/skills/process/manager.go
func parseHookPhase(name string) skills.HookPhase {
switch name {
case "OnActivate":
return skills.HookOnActivate
case "OnDeactivate":
return skills.HookOnDeactivate
case "OnConversationStart":
return skills.HookOnConversationStart
case "OnBeforePromptBuild":
return skills.HookOnBeforePromptBuild
case "OnBeforeToolCall":
return skills.HookOnBeforeToolCall
case "OnAfterToolResult":
return skills.HookOnAfterToolResult
case "OnAfterResponse":
return skills.HookOnAfterResponse
case "OnBeforeWikiSection":
return skills.HookOnBeforeWikiSection
case "OnSecurityScanComplete":
return skills.HookOnSecurityScanComplete
default:
return -1
}
}process.NewRequest function · go · L49-L65 (17 LOC)internal/skills/process/protocol.go
func NewRequest(id int, method string, params any) (*JSONRPCRequest, error) {
req := &JSONRPCRequest{
JSONRPC: "2.0",
ID: id,
Method: method,
}
if params != nil {
data, err := json.Marshal(params)
if err != nil {
return nil, fmt.Errorf("marshal params: %w", err)
}
req.Params = data
}
return req, nil
}process.DecodeResponse function · go · L68-L74 (7 LOC)internal/skills/process/protocol.go
func DecodeResponse(data []byte) (*JSONRPCResponse, error) {
var resp JSONRPCResponse
if err := json.Unmarshal(data, &resp); err != nil {
return nil, fmt.Errorf("decode response: %w", err)
}
return &resp, nil
}process.NewToolExecuteRequest function · go · L84-L90 (7 LOC)internal/skills/process/protocol.go
func NewToolExecuteRequest(id int, name string, input json.RawMessage) (*JSONRPCRequest, error) {
params := map[string]any{
"name": name,
"input": input,
}
return NewRequest(id, "tool/execute", params)
}process.NewHookHandleRequest function · go · L94-L100 (7 LOC)internal/skills/process/protocol.go
func NewHookHandleRequest(id int, phase string, data map[string]any) (*JSONRPCRequest, error) {
params := map[string]any{
"phase": phase,
"data": data,
}
return NewRequest(id, "hook/handle", params)
}main.main function · go · L42-L71 (30 LOC)internal/skills/process/testdata/echo_skill.go
func main() {
scanner := bufio.NewScanner(os.Stdin)
// Increase buffer size for large messages.
scanner.Buffer(make([]byte, 1024*1024), 1024*1024)
for scanner.Scan() {
line := scanner.Bytes()
var req request
if err := json.Unmarshal(line, &req); err != nil {
writeError(0, -32700, fmt.Sprintf("parse error: %v", err))
continue
}
switch req.Method {
case "initialize":
handleInitialize(req)
case "tool/execute":
handleToolExecute(req)
case "hook/handle":
handleHookHandle(req)
case "shutdown":
handleShutdown(req)
case "slow/method":
handleSlow(req)
default:
writeError(req.ID, -32601, fmt.Sprintf("method not found: %s", req.Method))
}
}
}Repobility · code-quality intelligence · https://repobility.com
main.handleInitialize function · go · L73-L93 (21 LOC)internal/skills/process/testdata/echo_skill.go
func handleInitialize(req request) {
result := map[string]interface{}{
"tools": []map[string]interface{}{
{
"name": "echo",
"description": "Echoes back the input",
"input_schema": map[string]interface{}{
"type": "object",
"properties": map[string]interface{}{
"message": map[string]interface{}{
"type": "string",
"description": "The message to echo",
},
},
},
},
},
"hooks": []string{"OnBeforeToolCall"},
}
writeResult(req.ID, result)
}main.handleToolExecute function · go · L95-L113 (19 LOC)internal/skills/process/testdata/echo_skill.go
func handleToolExecute(req request) {
var params map[string]json.RawMessage
if err := json.Unmarshal(req.Params, ¶ms); err != nil {
writeError(req.ID, -32602, fmt.Sprintf("invalid params: %v", err))
return
}
var name string
if err := json.Unmarshal(params["name"], &name); err != nil {
writeError(req.ID, -32602, fmt.Sprintf("invalid tool name: %v", err))
return
}
result := map[string]interface{}{
"content": fmt.Sprintf("echo: tool=%s input=%s", name, string(params["input"])),
"is_error": false,
}
writeResult(req.ID, result)
}main.handleHookHandle function · go · L115-L121 (7 LOC)internal/skills/process/testdata/echo_skill.go
func handleHookHandle(req request) {
result := map[string]interface{}{
"modified": map[string]interface{}{},
"cancel": false,
}
writeResult(req.ID, result)
}