Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: CI

on:
workflow_dispatch:
pull_request:
push:
branches:
- main

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.sha }}

- uses: actions/setup-go@v6
with:
go-version: "stable"

- name: Unit tests (agent-kiro)
working-directory: agents/entire-agent-kiro
run: go test -race -count=1 ./...

- name: Build (agent-kiro)
working-directory: agents/entire-agent-kiro
run: go build -o /dev/null ./cmd/entire-agent-kiro
44 changes: 44 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Lint

on:
workflow_dispatch:
pull_request:
push:
branches:
- main

permissions:
contents: read

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
ref: ${{ github.event.pull_request.head.sha }}

- uses: actions/setup-go@v6
with:
go-version: "stable"

- name: Check formatting
run: |
unformatted=$(gofmt -l .)
if [ -n "$unformatted" ]; then
echo "The following files are not formatted:"
echo "$unformatted"
exit 1
fi

- name: Run golangci-lint (agent-kiro)
uses: golangci/golangci-lint-action@v9
with:
version: "v2.11.3"
working-directory: agents/entire-agent-kiro

- name: Run golangci-lint (e2e)
uses: golangci/golangci-lint-action@v9
with:
version: "v2.11.3"
working-directory: e2e
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Entire CLI runtime data
.entire/

# Built binaries
/agents/entire-agent-kiro/entire-agent-kiro
93 changes: 93 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
version: "2"

issues:
max-issues-per-linter: 0
max-same-issues: 0

linters:
default: standard
enable:
- asciicheck
- bidichk
- copyloopvar
- decorder
- durationcheck
- errchkjson
- errname
- errorlint
- exhaustive
- exptostd
- forcetypeassert
- gocheckcompilerdirectives
- gochecknoinits
- goconst
- gocritic
- gosec
- govet
- grouper
- importas
- ineffassign
- intrange
- makezero
- mirror
- misspell
- nakedret
- nilerr
- nilnesserr
- nolintlint
- perfsprint
- reassign
- recvcheck
- revive
- staticcheck
- testableexamples
- testifylint
- tparallel
- unconvert
- unparam
- unused
- usestdlibvars
- usetesting
- wastedassign
- whitespace
settings:
errcheck:
check-type-assertions: true
goconst:
min-occurrences: 5
gosec:
excludes:
- G204 # subprocess with variables is expected for CLI tools
- G304 # file inclusion via variable is expected for CLI tools
- G703 # path traversal via taint — paths are constructed from controlled inputs
- G705 # XSS not applicable to CLI stderr output
govet:
enable-all: true
disable:
- fieldalignment
- shadow
nolintlint:
require-explanation: true
require-specific: true
testifylint:
enable-all: true
exclusions:
presets:
- comments
- std-error-handling
rules:
- path: _test\.go
linters:
- errchkjson
- gosec
- goconst
- revive
- unparam
- path: ^e2e/
linters:
- errcheck
- gochecknoinits
- goconst
- gosec
- revive
- usetesting
6 changes: 4 additions & 2 deletions agents/entire-agent-kiro/internal/kiro/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import (
"github.com/entireio/external-agents/agents/entire-agent-kiro/internal/protocol"
)

const stubSessionID = "stub-session-000"

type Agent struct{}

func New() *Agent {
Expand Down Expand Up @@ -48,7 +50,7 @@ func (a *Agent) GetSessionID(input *protocol.HookInputJSON) string {
if input != nil && input.SessionID != "" {
return input.SessionID
}
return "stub-session-000"
return stubSessionID
}

func (a *Agent) ReadSession(input *protocol.HookInputJSON) (protocol.AgentSessionJSON, error) {
Expand All @@ -58,7 +60,7 @@ func (a *Agent) ReadSession(input *protocol.HookInputJSON) (protocol.AgentSessio
if err != nil {
return protocol.AgentSessionJSON{}, err
}
sessionRef := ""
var sessionRef string
if input != nil && input.SessionRef != "" {
sessionRef = input.SessionRef
} else {
Expand Down
5 changes: 2 additions & 3 deletions agents/entire-agent-kiro/internal/kiro/hooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ const (
localDevCommandBase = "go run ${KIRO_PROJECT_DIR}/cmd/entire/main.go hooks kiro "
localDevTrustedCmd = "sh -c 'go run ${KIRO_PROJECT_DIR}/cmd/entire/main.go hooks *"
prodHookCommandBase = "entire hooks kiro "
sessionIDFile = "kiro-active-session"
toolCallsFile = "kiro-tool-calls.jsonl"
sessionIDFile = "kiro-active-session"
toolCallsFile = "kiro-tool-calls.jsonl"
)

type ideHookDef struct {
Expand Down Expand Up @@ -504,7 +504,6 @@ func (a *Agent) sessionIDCachePath() string {
return filepath.Join(protocol.RepoRoot(), ".entire", "tmp", sessionIDFile)
}


func fallbackStopSessionID() string {
return generateSessionID()
}
Expand Down
4 changes: 2 additions & 2 deletions agents/entire-agent-kiro/internal/kiro/lifecycle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ func TestParseHookUserPromptSubmitSupportsIDEFallback(t *testing.T) {
if event.Type != 2 {
t.Fatalf("event.Type = %d, want %d", event.Type, 2)
}
if event.SessionID == "" || event.SessionID == "stub-session-000" {
if event.SessionID == "" || event.SessionID == stubSessionID {
t.Fatalf("session_id = %q, want generated stable ID", event.SessionID)
}
if event.Prompt != "ide prompt" {
Expand Down Expand Up @@ -158,7 +158,7 @@ func TestParseHookStopWithoutCachedSessionIDUsesNonPredictableFallback(t *testin
if event.SessionID == "" {
t.Fatal("session_id should not be empty")
}
if event.SessionID == "my-repo" || event.SessionID == "stub-session-000" {
if event.SessionID == "my-repo" || event.SessionID == stubSessionID {
t.Fatalf("session_id = %q, want generated non-predictable fallback", event.SessionID)
}

Expand Down
27 changes: 17 additions & 10 deletions agents/entire-agent-kiro/internal/kiro/transcript.go
Original file line number Diff line number Diff line change
Expand Up @@ -850,7 +850,10 @@ func convertExecutionActionsToHistoryEntries(actions []kiroExecutionAction) []ki
if toolName, ok := execActionToToolName[action.ActionType]; ok {
filePath := extractFilePath(action.Input)
if filePath != "" {
args, _ := json.Marshal(map[string]string{"path": filePath})
args, err := json.Marshal(map[string]string{"path": filePath})
if err != nil {
continue
}
toolCalls = append(toolCalls, kiroToolCall{
Name: toolName,
Args: args,
Expand All @@ -864,26 +867,32 @@ func convertExecutionActionsToHistoryEntries(actions []kiroExecutionAction) []ki
if err := json.Unmarshal(action.Output, &out); err == nil && out.Message != "" {
// Flush any pending tool calls first
if len(toolCalls) > 0 {
toolUseJSON, _ := json.Marshal(kiroToolUseContent{
toolUseJSON, err := json.Marshal(kiroToolUseContent{
ToolUse: kiroToolUsePayload{ToolUses: toolCalls},
})
entries = append(entries, kiroHistoryEntry{Assistant: toolUseJSON})
if err == nil {
entries = append(entries, kiroHistoryEntry{Assistant: toolUseJSON})
}
toolCalls = nil
}
responseJSON, _ := json.Marshal(kiroResponseContent{
responseJSON, err := json.Marshal(kiroResponseContent{
Response: kiroResponsePayload{Content: out.Message},
})
entries = append(entries, kiroHistoryEntry{Assistant: responseJSON})
if err == nil {
entries = append(entries, kiroHistoryEntry{Assistant: responseJSON})
}
}
}
}

// Flush remaining tool calls without a trailing say
if len(toolCalls) > 0 {
toolUseJSON, _ := json.Marshal(kiroToolUseContent{
toolUseJSON, err := json.Marshal(kiroToolUseContent{
ToolUse: kiroToolUsePayload{ToolUses: toolCalls},
})
entries = append(entries, kiroHistoryEntry{Assistant: toolUseJSON})
if err == nil {
entries = append(entries, kiroHistoryEntry{Assistant: toolUseJSON})
}
}

return entries
Expand Down Expand Up @@ -924,9 +933,7 @@ func enrichIDETranscriptWithExecutionLogs(ideData []byte, execLogs map[string]*k
if len(assistantEntries) > 0 {
userEntry.Assistant = assistantEntries[0].Assistant
transcript.History = append(transcript.History, userEntry)
for _, extra := range assistantEntries[1:] {
transcript.History = append(transcript.History, extra)
}
transcript.History = append(transcript.History, assistantEntries[1:]...)
pendingUser = nil
continue
}
Expand Down
12 changes: 0 additions & 12 deletions agents/entire-agent-kiro/internal/kiro/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,18 +134,6 @@ type kiroIDEHistoryMeta struct {
// from the session files and contain the full action trace (tool calls,
// agent responses, file modifications) for each agent turn.

type kiroExecutionIndex struct {
Executions []kiroExecutionIndexEntry `json:"executions"`
}

type kiroExecutionIndexEntry struct {
ExecutionID string `json:"executionId"`
Type string `json:"type"`
Status string `json:"status"`
StartTime int64 `json:"startTime"`
EndTime int64 `json:"endTime"`
}

type kiroExecutionLog struct {
ExecutionID string `json:"executionId"`
ChatSessionID string `json:"chatSessionId"`
Expand Down
3 changes: 1 addition & 2 deletions agents/entire-agent-kiro/internal/protocol/protocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package protocol
import (
"encoding/json"
"flag"
"fmt"
"io"
"os"
"path/filepath"
Expand Down Expand Up @@ -309,5 +308,5 @@ func DefaultSessionDir(repoPath string) string {
}

func ResolveSessionFile(sessionDir, sessionID string) string {
return filepath.Join(sessionDir, fmt.Sprintf("%s.json", sessionID))
return filepath.Join(sessionDir, sessionID+".json")
}
Loading