style: strip section-banner decoration from comments (#7840)

312 banner separators across 63 files, the thing REASONIX.md bans outright and
nothing has ever checked. 64 were pure rules with no content and are gone; the
other 248 carried a label inside the dashes, so the decoration is stripped and
the label kept -- `// --- session/resume ---` becomes `// session/resume`, which
still orients a reader in a 1000-line test file without drawing a line across it.

The repolint ceiling for this rule drops 312 -> 0, so it is now zero-tolerance
rather than merely frozen.
This commit is contained in:
YHH authored and GitHub committed 2026-08-07 14:39:41 +08:00
1 parent 7b17eaf059
commit c969509d66
64 files changed
+251 -434

No files matched your search

+4 -4
View File
@@ -49,7 +49,7 @@ func main() {
}
}
// --- JSON-RPC framing ---
// JSON-RPC framing
type request struct {
JSONRPC string `json:"jsonrpc"`
@@ -151,7 +151,7 @@ func handleLine(line []byte, w *bufio.Writer) error {
return nil
}
// --- tools ---
// tools
// toolDef is one exposed tool: its advertised metadata plus the handler. run
// returns the text result, or an error which becomes an isError tool result the
@@ -257,7 +257,7 @@ func textResult(text string, isError bool) map[string]any {
}
}
// --- prompts ---
// prompts
// promptList advertises the server's prompts. They surface in reasonix as
// /mcp__example__<name> slash commands.
@@ -297,7 +297,7 @@ func getPrompt(params json.RawMessage) (any, *rpcError) {
}, nil
}
// --- resources ---
// resources
// resourceContents is the demo resource store, keyed by uri.
var resourceContents = map[string]string{
+2 -2
View File
@@ -1093,7 +1093,7 @@ func (a *App) commitPendingUpdateHealth() error {
)
}
// --- bound command surface (frontend → controller) ---
// bound command surface (frontend → controller)
// Each method guards on a nil controller so a pre-startup or failed-build call is
// a no-op, never a panic.
@@ -11552,7 +11552,7 @@ func workspaceRelativeIn(path, workspaceRoot string) (string, bool) {
return filepath.ToSlash(rel), true
}
// --- memory panel (frontend ⇄ controller) ---
// memory panel (frontend ⇄ controller)
type MemoryImport struct {
Path string `json:"path"`
+1 -1
View File
@@ -10326,7 +10326,7 @@ func TestSessionActionsWithoutControllerReturnError(t *testing.T) {
}
}
// --- Prompt history scanning tests ------------------------------------------
// Prompt history scanning tests
func identityPromptDisplay(text string) string { return text }
+2 -2
View File
@@ -400,7 +400,7 @@ func truncateForBridge(s string, limit int) string {
return string(runes[:limit]) + "…"
}
// ---- bot.DesktopBridge 实现 ----
// bot.DesktopBridge 实现
func (h *botBridgeHub) Sessions() []bot.DesktopSessionInfo {
if h.sessions == nil {
@@ -555,7 +555,7 @@ func (h *botBridgeHub) Answer(askID string, answers []event.AskAnswer) (string,
return fmt.Sprintf("已提交「%s」的回答。桌面端若已先处理,以先到者为准。", h.tabLabel(p.tabID)), nil
}
// ---- 显式接管 ----
// 显式接管
func (h *botBridgeHub) Takeover(route bot.DesktopWatchRoute, tabID string) (string, error) {
tabID = strings.TrimSpace(tabID)
+1 -1
View File
@@ -227,7 +227,7 @@ func TestCopyOwnedRegularFileCopiesMatchingOwner(t *testing.T) {
}
}
// --- runInstall table-driven coverage via injectable deps ---
// runInstall table-driven coverage via injectable deps
type installProbe struct {
phases []string
+1 -1
View File
@@ -199,7 +199,7 @@ func main() {
// against the --wails-drop-target element instead.
DragAndDrop: dragAndDrop,
// --- per-platform adaptation (see desktop/README.md for the rationale) ---
// per-platform adaptation (see desktop/README.md for the rationale)
Mac: &mac.Options{
// Inset traffic-lights over a frameless-feeling header; the frontend
// leaves a drag region at the top (CSS --wails-draggable).
+5 -5
View File
@@ -38,7 +38,7 @@ func occupyReadFileWithTimeoutSlots(t *testing.T) func() {
return release
}
// --- loadSessionTitles ---
// loadSessionTitles
func TestLoadSessionTitlesMissing(t *testing.T) {
dir := t.TempDir()
@@ -68,7 +68,7 @@ func TestLoadSessionTitlesValid(t *testing.T) {
}
}
// --- saveSessionTitles ---
// saveSessionTitles
func TestSaveSessionTitlesCreatesDir(t *testing.T) {
dir := filepath.Join(t.TempDir(), "nested", "sessions")
@@ -102,7 +102,7 @@ func TestSaveSessionTitlesRoundTrip(t *testing.T) {
}
}
// --- setSessionTitle ---
// setSessionTitle
func TestSetSessionTitle(t *testing.T) {
dir := t.TempDir()
@@ -160,7 +160,7 @@ func TestSetSessionTitlePreservesExistingTitlesWhenTimedReadSlotsFull(t *testing
}
}
// --- deleteSessionFile ---
// deleteSessionFile
func TestDeleteSessionFile(t *testing.T) {
dir := t.TempDir()
@@ -1176,7 +1176,7 @@ func writeSubagentArtifact(t *testing.T, dir, ref, parentSession string) {
}
}
// --- sessionTitlesPath ---
// sessionTitlesPath
func TestSessionTitlesPath(t *testing.T) {
got := sessionTitlesPath("/sessions")
+2 -2
View File
@@ -36,7 +36,7 @@ import (
// the exception: they go to Reasonix's global .env (upsertDotEnv), since config
// stores only the env-var name, not the key.
// --- read ---
// read
type ProviderView struct {
Name string `json:"name"`
@@ -1299,7 +1299,7 @@ func botDomainOrDefault(domain string) string {
return "feishu"
}
// --- apply (write config, then rebuild the controller so it's live) ---
// apply (write config, then rebuild the controller so it's live)
// applyConfigChange mutates the user-global config and rebuilds the controller so
// the change takes effect this session. Desktop settings such as providers and
+10 -10
View File
@@ -34,7 +34,7 @@ import (
"reasonix/internal/worktree"
)
// --- WorkspaceTab -----------------------------------------------------------
// WorkspaceTab
// tabDisplayState follows one live runtime across visible, detached, and
// reattached WorkspaceTab wrappers. Keeping one shared state pointer closes the
@@ -2137,7 +2137,7 @@ func (s *tabEventSink) telemetryTab() (*WorkspaceTab, string) {
return tab, sp
}
// --- wire event with tab ----------------------------------------------------
// wire event with tab
func toWireTab(e event.Event, tabID string, runtimeEpoch ...string) wireEventTab {
w := eventwire.ToWire(e)
@@ -2174,7 +2174,7 @@ type wireEventTab struct {
SessionCostUsd float64 `json:"sessionCostUsd,omitempty"`
}
// --- Tab management on App --------------------------------------------------
// Tab management on App
// TabMeta is the frontend-facing shape of one tab.
type TabMeta struct {
@@ -4388,7 +4388,7 @@ func sessionBindingFromMeta(path string, meta agent.BranchMeta) (sessionBinding,
}, true
}
// --- active tab helpers -----------------------------------------------------
// active tab helpers
// activeTab returns the currently active tab (nil when there are no tabs).
// Self-locking; safe to call from any goroutine without external lock.
@@ -4451,7 +4451,7 @@ func (a *App) ctrlByTabID(tabID string) control.SessionAPI {
return tab.Ctrl
}
// --- autosave per tab -------------------------------------------------------
// autosave per tab
const maxTabSnapshotFailureRetries = 2
@@ -4854,7 +4854,7 @@ func topicTitleFromText(text string) string {
return text
}
// --- persistence: desktop-projects.json -------------------------------------
// persistence: desktop-projects.json
const desktopProjectsFile = "desktop-projects.json"
const tabsFileName = "desktop-tabs.json"
@@ -5717,7 +5717,7 @@ func removeProject(root string) error {
})
}
// --- topic helpers ----------------------------------------------------------
// topic helpers
const (
topicTitlesFile = "desktop-topic-titles.json"
@@ -6395,7 +6395,7 @@ func ensureTopicIndexed(scope, workspaceRoot, topicID, title, source string) err
return prependTopicInProjectsFile(workspaceRoot, topicID, true)
}
// --- telemetry --------------------------------------------------------------
// telemetry
func saveTelemetry(path string, snapshot tabTelemetrySnapshot) error {
if snapshot.Version == 0 {
@@ -6437,7 +6437,7 @@ func loadTelemetry(path string) tabTelemetrySnapshot {
return tabTelemetrySnapshot{Version: 1, ReadFiles: records}
}
// --- project tree -----------------------------------------------------------
// project tree
// ProjectNode is one node in the sidebar project tree (a project folder or a
// topic leaf).
@@ -8327,7 +8327,7 @@ func (a *App) ContextPanel(tabID string) ContextPanelInfo {
return info
}
// --- utility ----------------------------------------------------------------
// utility
func (a *App) newUniqueTabIDLocked() string {
for {
+6 -6
View File
@@ -20,7 +20,7 @@ import (
"reasonix/internal/control"
)
// --- workspaceStatePath ---
// workspaceStatePath
func TestWorkspaceStatePath(t *testing.T) {
// workspaceStatePath depends on config.MemoryUserDir() which needs a
@@ -35,7 +35,7 @@ func TestWorkspaceStatePath(t *testing.T) {
}
}
// --- saveWorkspace / loadWorkspace round-trip ---
// saveWorkspace / loadWorkspace round-trip
func TestSaveLoadWorkspaceRoundTrip(t *testing.T) {
// workspaceStatePath() resolves via os.UserConfigDir() (HOME on unix,
@@ -575,7 +575,7 @@ func BenchmarkDesktopSessionDir(b *testing.B) {
}
}
// --- cwdWritable ---
// cwdWritable
func TestCwdWritable(t *testing.T) {
// In a normal test environment, cwd should be writable.
@@ -1048,7 +1048,7 @@ func TestReadFileGB18030(t *testing.T) {
}
}
// --- RemoveWorkspace cleanup of active pointer ---
// RemoveWorkspace cleanup of active pointer
func TestRemoveWorkspaceClearsActivePointerWhenRemovingCurrentWorkspace(t *testing.T) {
isolateDesktopUserDirs(t)
@@ -1115,7 +1115,7 @@ func TestClearWorkspace(t *testing.T) {
}
}
// --- OpenProjectTab updates active workspace pointer ---
// OpenProjectTab updates active workspace pointer
func TestOpenProjectTabUpdatesActiveWorkspacePointer(t *testing.T) {
isolateDesktopUserDirs(t)
@@ -1812,7 +1812,7 @@ func gitOutput(t *testing.T, args ...string) string {
return strings.TrimSpace(string(out))
}
// --- settings_app.go helpers ---
// settings_app.go helpers
// These are unexported but in the same package, so we can test them.
func TestOrDefault(t *testing.T) {
+17 -17
View File
@@ -32,7 +32,7 @@ const (
ErrInternal = -32603
)
// --- initialize ---
// initialize
// InitializeParams is the client's handshake. The agent records the client's
// capabilities — fs read/write proxying and host terminals are used when
@@ -168,7 +168,7 @@ type AuthenticateParams struct {
// AuthenticateResult is the empty authentication ack.
type AuthenticateResult struct{}
// --- session/new ---
// session/new
// SessionNewParams opens a session rooted at cwd, optionally with MCP servers
// the agent should connect for the session's lifetime.
@@ -259,7 +259,7 @@ type SessionNewResult struct {
ConfigOptions []SessionConfigOption `json:"configOptions,omitempty"`
}
// --- session modes ---
// session modes
// SessionMode is one operating mode the client can switch the session into.
type SessionMode struct {
@@ -297,7 +297,7 @@ type SessionModelState struct {
CurrentModelID string `json:"currentModelId"`
}
// --- session/load ---
// session/load
// SessionLoadParams resumes a session saved under sessionId (the id a prior
// session/new returned), optionally re-rooting it at cwd with fresh MCP servers.
@@ -317,7 +317,7 @@ type SessionLoadResult struct {
ConfigOptions []SessionConfigOption `json:"configOptions,omitempty"`
}
// --- session/resume ---
// session/resume
// SessionResumeParams resumes a session without replaying its transcript.
type SessionResumeParams struct {
@@ -333,7 +333,7 @@ type SessionResumeResult struct {
ConfigOptions []SessionConfigOption `json:"configOptions,omitempty"`
}
// --- session/set_config_option ---
// session/set_config_option
// SetSessionConfigOptionParams changes one advertised session config option.
type SetSessionConfigOptionParams struct {
@@ -365,7 +365,7 @@ type SessionConfigSelectOption struct {
Description string `json:"description,omitempty"`
}
// --- session/set_model ---
// session/set_model
// SetSessionModelParams is ACP's legacy model-switching request.
type SetSessionModelParams struct {
@@ -376,7 +376,7 @@ type SetSessionModelParams struct {
// SetSessionModelResult is the empty ack for legacy model switching.
type SetSessionModelResult struct{}
// --- session/list ---
// session/list
// SessionListParams lists known sessions, optionally filtered by cwd.
type SessionListParams struct {
@@ -400,7 +400,7 @@ type SessionInfo struct {
Meta map[string]any `json:"_meta,omitempty"`
}
// --- session/close ---
// session/close
// SessionCloseParams closes an active session and releases its resources.
type SessionCloseParams struct {
@@ -410,7 +410,7 @@ type SessionCloseParams struct {
// SessionCloseResult is the empty close ack.
type SessionCloseResult struct{}
// --- session/delete ---
// session/delete
// SessionDeleteParams removes a session from future session/list results.
type SessionDeleteParams struct {
@@ -420,7 +420,7 @@ type SessionDeleteParams struct {
// SessionDeleteResult is the empty delete ack.
type SessionDeleteResult struct{}
// --- content blocks (inbound prompt) ---
// content blocks (inbound prompt)
// ContentBlock is one piece of a prompt. The agent reads text blocks and the
// inline text of resource blocks (embeddedContext); image/audio are accepted on
@@ -461,7 +461,7 @@ func FlattenPrompt(blocks []ContentBlock) string {
return strings.TrimSpace(strings.Join(parts, "\n\n"))
}
// --- session/prompt ---
// session/prompt
// SessionPromptParams sends a turn's prompt to a session.
type SessionPromptParams struct {
@@ -516,7 +516,7 @@ type SessionPromptResult struct {
TranscriptPath *string `json:"transcriptPath,omitempty"`
}
// --- session/update (agent → client notifications) ---
// session/update (agent → client notifications)
//
// SessionUpdate is a tagged union discriminated by sessionUpdate. The variants
// reuse the JSON key "content" with two incompatible shapes (a single block for
@@ -639,7 +639,7 @@ type currentModeUpdate struct {
CurrentModeID string `json:"currentModeId"`
}
// --- fs/* (agent → client requests) ---
// fs/* (agent → client requests)
// FSReadTextFileParams asks the client for a file's current text, including
// unsaved editor state. Line (1-based) and Limit page the content; Reasonix
@@ -664,7 +664,7 @@ type FSWriteTextFileParams struct {
Content string `json:"content"`
}
// --- terminal/* (agent → client requests) ---
// terminal/* (agent → client requests)
// TerminalCreateParams starts a command in a client-owned terminal.
// Env follows ACP v1's official EnvVariable[] shape (same as MCP env): only
@@ -709,14 +709,14 @@ type TerminalExitStatus struct {
Signal *string `json:"signal,omitempty"`
}
// --- session/cancel (client → agent notification) ---
// session/cancel (client → agent notification)
// SessionCancelParams cancels an in-progress turn.
type SessionCancelParams struct {
SessionID string `json:"sessionId"`
}
// --- session/request_permission (agent → client request) ---
// session/request_permission (agent → client request)
// PermissionOptionKind classifies an option for host UI styling. It is an ACP v1
// wire enum, so host-visible permission choices must stay within the official
+5 -5
View File
@@ -89,7 +89,7 @@ func TestToolKindFor(t *testing.T) {
}
}
// --- newSessionID ---
// newSessionID
func TestNewSessionID(t *testing.T) {
id, err := newSessionID()
@@ -128,7 +128,7 @@ func TestNewSessionIDUnique(t *testing.T) {
}
}
// --- mcpSpecs ---
// mcpSpecs
func TestMcpSpecsNil(t *testing.T) {
if got, err := mcpSpecs(nil, ""); err != nil || got != nil {
@@ -273,7 +273,7 @@ func TestMcpSpecsRejectsUnsupportedTransport(t *testing.T) {
}
}
// --- transcriptPath ---
// transcriptPath
func TestTranscriptPath(t *testing.T) {
dir := t.TempDir()
@@ -283,7 +283,7 @@ func TestTranscriptPath(t *testing.T) {
}
}
// --- Protocol constants ---
// Protocol constants
func TestProtocolVersion(t *testing.T) {
if ProtocolVersion != 1 {
@@ -309,7 +309,7 @@ func TestErrorCodes(t *testing.T) {
}
}
// --- acpSession ---
// acpSession
func TestAcpSessionSetCancelAbort(t *testing.T) {
sess := &acpSession{id: "test"}
+3 -3
View File
@@ -25,7 +25,7 @@ import (
"reasonix/internal/tool"
)
// --- fakes: a Factory wrapping a behavior-driven runner in a real Controller ---
// fakes: a Factory wrapping a behavior-driven runner in a real Controller
// fakeRunner stands in for an agent.Runner; it emits to the session's sink and
// honors ctx cancellation, but runs no model.
@@ -297,7 +297,7 @@ func (f *configurableFactory) hookEventsSnapshot() []hook.Event {
return append([]hook.Event(nil), f.hookEvents...)
}
// --- a minimal JSON-RPC client over the wire, for integration tests ---
// a minimal JSON-RPC client over the wire, for integration tests
type frame struct {
ID *json.RawMessage `json:"id"`
@@ -584,7 +584,7 @@ func messageChunkText(t *testing.T, f frame) (string, bool) {
return p.Update.Content.Text, true
}
// --- tests ---
// tests
func TestServeLifecycle(t *testing.T) {
factory := &fakeFactory{behavior: func(_ context.Context, sink event.Sink, input string) error {
+2 -2
View File
@@ -570,7 +570,7 @@ func newAgent(t *testing.T, url string, reg *tool.Registry, contextWindow, recen
return a, sink
}
// --- request inspection helpers ---
// request inspection helpers
func decodeMessages(body []byte) []json.RawMessage {
var req struct {
@@ -609,7 +609,7 @@ func charsOf(msgs []json.RawMessage) int {
return total
}
// --- SSE chunk builders matching the streamResponse shape the provider parses ---
// SSE chunk builders matching the streamResponse shape the provider parses
type sseDelta struct {
Content string `json:"content,omitempty"`
+8 -8
View File
@@ -201,7 +201,7 @@ func requestContents(req provider.Request) string {
return b.String()
}
// --- agent.before_start ---
// agent.before_start
func TestAgentBeforeStartContinue(t *testing.T) {
client := &fakeDispatchClient{}
@@ -325,7 +325,7 @@ func TestSetExtensionsInstallsAfterConstruction(t *testing.T) {
}
}
// --- context.prepare ---
// context.prepare
func TestContextPrepareReplaceIsEphemeral(t *testing.T) {
client := &fakeDispatchClient{interceptFn: func(ev protocol.InterceptEvent, _ json.RawMessage) (protocol.InterceptResult, error) {
@@ -417,7 +417,7 @@ func TestContextPrepareFailurePolicy(t *testing.T) {
})
}
// --- provider.request ---
// provider.request
func TestProviderRequestReplace(t *testing.T) {
client := &fakeDispatchClient{interceptFn: func(ev protocol.InterceptEvent, payload json.RawMessage) (protocol.InterceptResult, error) {
@@ -567,7 +567,7 @@ func TestProviderRequestReplacementCacheEphemerality(t *testing.T) {
}
}
// --- provider.response ---
// provider.response
func TestProviderResponseReplaceIsTranscript(t *testing.T) {
client := &fakeDispatchClient{interceptFn: func(ev protocol.InterceptEvent, _ json.RawMessage) (protocol.InterceptResult, error) {
@@ -680,7 +680,7 @@ func TestProviderResponseFailurePolicy(t *testing.T) {
})
}
// --- tool.before ---
// tool.before
func TestToolBeforeContinue(t *testing.T) {
client := &fakeDispatchClient{}
@@ -860,7 +860,7 @@ func TestToolBeforeFailurePolicy(t *testing.T) {
})
}
// --- permission.decision ---
// permission.decision
func TestPermissionDecisionExtensionAllowOverridesHostDeny(t *testing.T) {
client := &fakeDispatchClient{interceptFn: func(ev protocol.InterceptEvent, payload json.RawMessage) (protocol.InterceptResult, error) {
@@ -995,7 +995,7 @@ func TestPermissionDecisionBlockAndFailure(t *testing.T) {
})
}
// --- tool.after ---
// tool.after
func TestToolAfterReplaceResult(t *testing.T) {
client := &fakeDispatchClient{interceptFn: func(ev protocol.InterceptEvent, _ json.RawMessage) (protocol.InterceptResult, error) {
@@ -1103,7 +1103,7 @@ func TestToolAfterFailurePolicy(t *testing.T) {
})
}
// --- compaction.prepare / compaction.complete ---
// compaction.prepare / compaction.complete
// newCompactionAgent builds an agent whose session has a foldable middle
// (large assistant turns) so CompactNow always finds a region, with the
+1 -1
View File
@@ -104,7 +104,7 @@ func TestEmptyFinalNotice(t *testing.T) {
}
}
// --- parallel-dispatch tests ---
// parallel-dispatch tests
// fakeTool is a minimal Tool stand-in for dispatch tests; ReadOnly is
// configurable and Execute sleeps a fixed duration so we can measure
+9 -9
View File
@@ -9,7 +9,7 @@ import (
"reasonix/internal/provider"
)
// --- NewSession ---
// NewSession
func TestNewSessionEmpty(t *testing.T) {
s := NewSession("")
@@ -31,7 +31,7 @@ func TestNewSessionWithSystem(t *testing.T) {
}
}
// --- Session.Add ---
// Session.Add
func TestSessionAdd(t *testing.T) {
s := NewSession("")
@@ -75,7 +75,7 @@ func TestSessionAddDecisionReceiptKeepsToolResultsAdjacent(t *testing.T) {
}
}
// --- Session.HasContent ---
// Session.HasContent
func TestHasContentEmpty(t *testing.T) {
s := NewSession("")
@@ -115,7 +115,7 @@ func TestHasContentWithTool(t *testing.T) {
}
}
// --- Session.HasSystemMessage ---
// Session.HasSystemMessage
func TestHasSystemMessageWithSystem(t *testing.T) {
s := NewSession("system prompt")
@@ -164,7 +164,7 @@ func TestHasSystemMessageCompactedKeepsSystem(t *testing.T) {
}
}
// --- Save / LoadSession round-trip ---
// Save / LoadSession round-trip
func TestSaveLoadSessionRoundTrip(t *testing.T) {
dir := t.TempDir()
@@ -238,7 +238,7 @@ func TestLoadSessionMalformed(t *testing.T) {
}
}
// --- ListSessions ---
// ListSessions
func TestListSessionsMissingDirReturnsNil(t *testing.T) {
sessions, err := ListSessions("/nonexistent/dir")
@@ -316,7 +316,7 @@ func TestListSessionsSkipsNonJSONL(t *testing.T) {
}
}
// --- previewSession ---
// previewSession
func TestPreviewSession(t *testing.T) {
dir := t.TempDir()
@@ -396,7 +396,7 @@ func TestPreviewSessionMalformed(t *testing.T) {
}
}
// --- NewSessionPath ---
// NewSessionPath
func TestNewSessionPath(t *testing.T) {
dir := t.TempDir()
@@ -451,7 +451,7 @@ func TestNewSessionPathEmptyModel(t *testing.T) {
}
}
// --- rewrite-save baseline ---
// rewrite-save baseline
// TestNeedsRewriteSaveFollowsSaves pins the baseline's lifecycle on the
// session object itself: an in-memory rewrite demands a rewrite save, every
+3 -3
View File
@@ -8,7 +8,7 @@ import (
"testing"
)
// --- symbol ---
// symbol
func TestSymbolCNY(t *testing.T) {
if got := symbol("CNY"); got != "¥" {
@@ -47,7 +47,7 @@ func TestSymbolLowercase(t *testing.T) {
}
}
// --- Display ---
// Display
func TestDisplayNil(t *testing.T) {
var b *Balance
@@ -82,7 +82,7 @@ func TestDisplayFallsBackToFirst(t *testing.T) {
}
}
// --- Fetch edge cases ---
// Fetch edge cases
func TestFetchContextCancelled(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
+3 -3
View File
@@ -5,7 +5,7 @@ import (
"testing"
)
// --- visibleWidth ---
// visibleWidth
func TestVisibleWidthPlain(t *testing.T) {
if got := visibleWidth("hello"); got != 5 {
@@ -27,7 +27,7 @@ func TestVisibleWidthANSI(t *testing.T) {
}
}
// --- padRight ---
// padRight
func TestPadRightAlreadyWide(t *testing.T) {
got := padRight("hello", 3)
@@ -57,7 +57,7 @@ func TestPadRightEmpty(t *testing.T) {
}
}
// --- boxed ---
// boxed
func TestBoxedSingleLine(t *testing.T) {
got := boxed([]string{"hello"})
+2 -2
View File
@@ -3058,7 +3058,7 @@ func TestEmptyEnterScrollsToBottom(t *testing.T) {
return n.(chatTUI)
}
// --- idle state ---
// idle state
t.Run("idle", func(t *testing.T) {
cur := adv(newChatTUI(ctrl, "", ch, 80), tea.WindowSizeMsg{Width: 80, Height: 8})
for i := 0; i < 12; i++ {
@@ -3076,7 +3076,7 @@ func TestEmptyEnterScrollsToBottom(t *testing.T) {
}
})
// --- running state ---
// running state
t.Run("running", func(t *testing.T) {
cur := adv(newChatTUI(ctrl, "", ch, 80), tea.WindowSizeMsg{Width: 80, Height: 8})
for i := 0; i < 12; i++ {
+1 -1
View File
@@ -81,7 +81,7 @@ func (c *chooser) answers() []event.AskAnswer {
return out
}
// --- chatTUI integration ---
// chatTUI integration
// handleChooserKey routes a keystroke to the active chooser (when not in free-text
// mode — that's handled in Update by the textarea). Selecting an option in a
+1 -1
View File
@@ -649,7 +649,7 @@ func hasLabel(items []compItem, label string) bool {
return false
}
// --- fuzzy matching for / completion ---
// fuzzy matching for / completion
// TestFuzzyFilterSlashSubsequence proves the slash-menu fuzzy filter matches
// command labels whose letters appear in order, even when they are not a
+4 -4
View File
@@ -263,7 +263,7 @@ func taskTmuxDetachCmd(a *taskmonitor.TmuxAdapter, args []string) int {
return printTmuxResult(a.Detach(context.Background(), dir, fs.Arg(0)), jsonOut)
}
// --- list ---
// list
func taskListCmd(store taskmonitor.Store, args []string) int {
fs := flag.NewFlagSet("task list", flag.ContinueOnError)
@@ -300,7 +300,7 @@ func taskListCmd(store taskmonitor.Store, args []string) int {
return 0
}
// --- status ---
// status
func taskStatusCmd(store taskmonitor.Store, args []string) int {
fs := flag.NewFlagSet("task status", flag.ContinueOnError)
@@ -342,7 +342,7 @@ func taskStatusCmd(store taskmonitor.Store, args []string) int {
return 0
}
// --- events ---
// events
func taskEventsCmd(store taskmonitor.Store, args []string) int {
fs := flag.NewFlagSet("task events", flag.ContinueOnError)
@@ -430,7 +430,7 @@ func taskEventsCmd(store taskmonitor.Store, args []string) int {
return 0
}
// --- control commands ---
// control commands
func taskStopCmd(store taskmonitor.Store, args []string) int {
fs := flag.NewFlagSet("task stop", flag.ContinueOnError)
+6 -6
View File
@@ -81,7 +81,7 @@ func captureOut(fn func() int) (int, string) {
return ec, string(data)
}
// --- JSON schema tests ---
// JSON schema tests
func TestTaskList_JSON_SchemaVersion(t *testing.T) {
s := testStore(t)
@@ -172,7 +172,7 @@ func TestTaskList_JSON_ProjectIsolation(t *testing.T) {
}
}
// --- status ---
// status
func TestTaskStatus_JSON_Found(t *testing.T) {
s := testStore(t)
@@ -235,7 +235,7 @@ func TestTaskStatus_JSON_SchemaVersion(t *testing.T) {
}
}
// --- events ---
// events
func TestTaskEvents_JSON_SchemaVersion(t *testing.T) {
s := testStore(t)
@@ -421,7 +421,7 @@ func TestTaskEvents_NoFlag(t *testing.T) {
}
}
// --- CLI wiring ---
// CLI wiring
func TestTaskCommand_Dispatch(t *testing.T) {
s := testStore(t)
@@ -478,7 +478,7 @@ func TestTaskCommand_UnknownSubcommand(t *testing.T) {
}
}
// --- FileStore integration tests (real filesystem) ---
// FileStore integration tests (real filesystem)
// writeTaskData creates a FileStore-compatible task tree in dir and resets
// taskStore so the CLI uses the production FileStore path.
@@ -642,7 +642,7 @@ func TestFileStoreIntegration_ListTasks_Empty(t *testing.T) {
}
}
// --- CLI+JobKiller e2e tests ---
// CLI+JobKiller e2e tests
// mockJobKiller is a thread-safe mock for JobKiller.
type mockJobKiller struct {
+3 -3
View File
@@ -7,7 +7,7 @@ import (
"testing"
)
// --- splitFrontmatter ---
// splitFrontmatter
func TestSplitFrontmatterNoFence(t *testing.T) {
fm, body := splitFrontmatter("just body text\nno fence")
@@ -56,7 +56,7 @@ func TestSplitFrontmatterCRLF(t *testing.T) {
}
}
// --- Render edge cases ---
// Render edge cases
func TestRenderManyPositionals(t *testing.T) {
c := Command{Body: "$1 $2 $3 $4 $5 $6 $7 $8 $9"}
@@ -99,7 +99,7 @@ func TestRenderNoTokens(t *testing.T) {
}
}
// --- Load edge cases ---
// Load edge cases
func TestLoadEmptyDir(t *testing.T) {
dir := t.TempDir()
+2 -2
View File
@@ -484,7 +484,7 @@ func normalizePlanModeReadOnlyCommandPrefix(prefix string) string {
return strings.Join(strings.Fields(strings.TrimSpace(prefix)), " ")
}
// --- decision helpers (caller holds a.mu) ---
// decision helpers (caller holds a.mu)
func (a *approvalManager) bypassAllowsLocked(tool, subject string, args json.RawMessage) bool {
if requiresFreshApprovalTool(tool) {
@@ -553,7 +553,7 @@ func (a *approvalManager) drainLocked(includeExplicitAsk bool) []drainedApproval
return pending
}
// --- pure approval helpers ---
// pure approval helpers
func normalizeToolApprovalMode(mode string) string {
switch strings.ToLower(strings.TrimSpace(mode)) {
+3 -3
View File
@@ -833,7 +833,7 @@ func (c *Controller) beginCheckpoint(input string) {
c.checkpoints.beginWithObserver(input, len(c.executor.Session().Messages), c.mutationObserver)
}
// --- commands (frontend → controller) ---
// commands (frontend → controller)
// admissionResult classifies what runGuarded did with a turn body.
type admissionResult int
@@ -5612,7 +5612,7 @@ func (c *Controller) Bypass() bool {
return c.AutoApproveTools()
}
// --- memory ---
// memory
//
// The memory snapshot, the pending turn-tail notes queue, and write serialization
// live in c.memory (a memoryManager) behind its own locks, off c.mu — so a
@@ -5681,7 +5681,7 @@ func (c *Controller) Memory() *memory.Set {
return c.memory.current()
}
// --- approval bridge (agent gate → events) ---
// approval bridge (agent gate → events)
// gateApprover adapts the Controller to permission.Approver. It is distinct
// from the public Approve command (different signature, different direction).
+5 -5
View File
@@ -5,7 +5,7 @@ import (
"testing"
)
// --- splitLines ---
// splitLines
func TestSplitLinesEmpty(t *testing.T) {
lines, eol := splitLines("")
@@ -60,7 +60,7 @@ func TestSplitLinesSingleLineWithNewline(t *testing.T) {
}
}
// --- isBinary ---
// isBinary
func TestIsBinaryEmpty(t *testing.T) {
if isBinary("") {
@@ -86,7 +86,7 @@ func TestIsBinaryNULAtEnd(t *testing.T) {
}
}
// --- Build edge cases ---
// Build edge cases
func TestBuildBothEmpty(t *testing.T) {
c := Build("empty.txt", "", "", Modify)
@@ -148,7 +148,7 @@ func TestBuildLargeFile(t *testing.T) {
}
}
// --- Kind constants ---
// Kind constants
func TestKindConstants(t *testing.T) {
if Create != "create" {
@@ -162,7 +162,7 @@ func TestKindConstants(t *testing.T) {
}
}
// --- itoa ---
// itoa
func TestItoa(t *testing.T) {
cases := []struct {
+10 -10
View File
@@ -8,7 +8,7 @@ import (
"reasonix/internal/provider"
)
// --- Kind constants ---
// Kind constants
func TestKindConstants(t *testing.T) {
// Verify the iota sequence is stable and sequential.
@@ -23,7 +23,7 @@ func TestKindConstants(t *testing.T) {
}
}
// --- Level constants ---
// Level constants
func TestLevelConstants(t *testing.T) {
if LevelInfo != 0 {
@@ -43,7 +43,7 @@ func TestNoticeAudienceConstants(t *testing.T) {
}
}
// --- FuncSink ---
// FuncSink
func TestFuncSinkEmit(t *testing.T) {
var received Event
@@ -126,7 +126,7 @@ func TestSyncForwardsProtocolRecoveryWithoutEmittingUIEvent(t *testing.T) {
}
}
// --- Discard ---
// Discard
func TestDiscardSink(t *testing.T) {
// Discard should accept any event without panic.
@@ -135,7 +135,7 @@ func TestDiscardSink(t *testing.T) {
Discard.Emit(Event{Kind: TurnDone})
}
// --- Event struct field access ---
// Event struct field access
func TestEventFields(t *testing.T) {
usage := &provider.Usage{PromptTokens: 100, CompletionTokens: 50}
@@ -162,7 +162,7 @@ func TestEventFields(t *testing.T) {
}
}
// --- Tool struct ---
// Tool struct
func TestToolStruct(t *testing.T) {
tool := Tool{
@@ -195,7 +195,7 @@ func TestToolStruct(t *testing.T) {
}
}
// --- Approval struct ---
// Approval struct
func TestApprovalStruct(t *testing.T) {
a := Approval{ID: "42", Tool: "bash", Subject: "rm -rf /"}
@@ -204,7 +204,7 @@ func TestApprovalStruct(t *testing.T) {
}
}
// --- Ask / AskQuestion / AskOption / AskAnswer ---
// Ask / AskQuestion / AskOption / AskAnswer
func TestAskStructs(t *testing.T) {
q := AskQuestion{
@@ -234,7 +234,7 @@ func TestAskStructs(t *testing.T) {
}
}
// --- Multiple Emit via channel-backed sink ---
// Multiple Emit via channel-backed sink
func TestChannelBackedSink(t *testing.T) {
ch := make(chan Event, 8)
@@ -264,7 +264,7 @@ func TestChannelBackedSink(t *testing.T) {
}
}
// --- FuncSink forwards every concurrent Emit exactly once ---
// FuncSink forwards every concurrent Emit exactly once
// FuncSink.Emit forwards to the wrapped func with no synchronization of its own,
// so a concurrency-safe callback is the caller's responsibility (here a
@@ -64,9 +64,7 @@ func TestMain(m *testing.M) {
os.Exit(m.Run())
}
// ---------------------------------------------------------------------------
// Host client fixture
// ---------------------------------------------------------------------------
const (
testPluginID = "conformance-ext"
@@ -136,9 +134,7 @@ func decodeReplacement(t *testing.T, result protocol.InterceptResult, out any) {
}
}
// ---------------------------------------------------------------------------
// Stub UI handler and stream router
// ---------------------------------------------------------------------------
// stubUI records host/ui/publish calls and answers host/ui/request through a
// programmable function (default: the user cancelled).
@@ -243,9 +239,7 @@ func protocolReason(t *testing.T, err error) protocol.ErrorReason {
return ""
}
// ---------------------------------------------------------------------------
// Tests: initialize handshake
// ---------------------------------------------------------------------------
// TestHandshakeAccepted proves the host accepts the example's full
// declaration: subscriptions, the system_prompt strategy slot, the namespaced
@@ -306,9 +300,7 @@ func TestHandshakeUnderDeclaredRejected(t *testing.T) {
}
}
// ---------------------------------------------------------------------------
// Tests: intercepts and strategy
// ---------------------------------------------------------------------------
// TestInputReceiveRewrite drives the "/fs " trigger: the example replaces the
// input; ordinary input continues untouched.
@@ -385,9 +377,7 @@ func TestSystemPromptStrategy(t *testing.T) {
}
}
// ---------------------------------------------------------------------------
// Tests: provider broker
// ---------------------------------------------------------------------------
// TestProviderCatalog fetches the extension's provider catalog through the
// host client.
@@ -499,9 +489,7 @@ func TestProviderStreamCancel(t *testing.T) {
}
}
// ---------------------------------------------------------------------------
// Tests: content refs
// ---------------------------------------------------------------------------
// TestContentRefRehydration sends an intercept payload above the 64 KiB
// externalization threshold: the host moves it into a content ref, and the
@@ -530,9 +518,7 @@ func TestContentRefRehydration(t *testing.T) {
}
}
// ---------------------------------------------------------------------------
// Tests: UI
// ---------------------------------------------------------------------------
// TestSessionStartPublishes drives one session.start observation: the example
// publishes its status line and demo card through host/ui/publish.
@@ -638,9 +624,7 @@ func TestUISubmitRoundTrip(t *testing.T) {
}
}
// ---------------------------------------------------------------------------
// Tests: timeout and crash
// ---------------------------------------------------------------------------
// TestInterceptTimeout stalls the example past the intercept budget; the host
// must surface the frozen intercept_timeout reason.
+6 -6
View File
@@ -12,7 +12,7 @@ import (
"golang.org/x/text/encoding/simplifiedchinese"
)
// --- Detect ---
// Detect
func TestDetectUTF8Plain(t *testing.T) {
enc, _ := Detect([]byte("hello world\n"))
@@ -71,7 +71,7 @@ func TestDetectEmpty(t *testing.T) {
}
}
// --- Decode ---
// Decode
func TestDecodeUTF8(t *testing.T) {
in := []byte("hello\n世界")
@@ -146,7 +146,7 @@ func TestDecodeLossyUTF8(t *testing.T) {
}
}
// --- Encode ---
// Encode
func TestEncodeUTF8(t *testing.T) {
out := Encode("hello", UTF8)
@@ -195,7 +195,7 @@ func TestEncodeGB18030(t *testing.T) {
}
}
// --- Round-trip ---
// Round-trip
func TestRoundTripGB18030(t *testing.T) {
original := "你好世界\n第二行\n"
@@ -235,7 +235,7 @@ func TestRoundTripUTF8BOM(t *testing.T) {
}
}
// --- BOM-less UTF-16 ---
// BOM-less UTF-16
func utf16NoBOM(t *testing.T, s string, order binary.ByteOrder) []byte {
t.Helper()
@@ -306,7 +306,7 @@ func TestRoundTripUTF16LENoBOM(t *testing.T) {
}
}
// --- UTF-16 supplementary plane (surrogate pairs) ---
// UTF-16 supplementary plane (surrogate pairs)
func TestSurrogatePairRoundTrip(t *testing.T) {
// U+1F600 (😀) is in the supplementary plane and requires a surrogate pair.
+13 -13
View File
@@ -11,7 +11,7 @@ import (
"time"
)
// --- Runner construction ---
// Runner construction
func TestNewRunnerNil(t *testing.T) {
var r *Runner
@@ -64,7 +64,7 @@ func TestToolMutationHooksEnabled(t *testing.T) {
}
}
// --- Runner.PreToolUse ---
// Runner.PreToolUse
func TestRunnerPreToolUseNoHooks(t *testing.T) {
r := NewRunner(nil, "/tmp", nil, nil)
@@ -110,7 +110,7 @@ func TestRunnerPreToolUseBlock(t *testing.T) {
}
}
// --- Runner.PostToolUse ---
// Runner.PostToolUse
func TestRunnerPostToolUseNoHooks(t *testing.T) {
r := NewRunner(nil, "/tmp", nil, nil)
@@ -150,7 +150,7 @@ func TestRunnerPostToolUseFailurePreservesNativeObserver(t *testing.T) {
}
}
// --- Runner.PermissionRequest ---
// Runner.PermissionRequest
func TestRunnerPermissionRequestPayload(t *testing.T) {
hooks := []ResolvedHook{
@@ -226,7 +226,7 @@ func TestRunnerPermissionRequestClaudeDecisions(t *testing.T) {
}
}
// --- Runner.PromptSubmit ---
// Runner.PromptSubmit
func TestRunnerPromptSubmitBlock(t *testing.T) {
hooks := []ResolvedHook{
@@ -242,7 +242,7 @@ func TestRunnerPromptSubmitBlock(t *testing.T) {
}
}
// --- Runner.Stop ---
// Runner.Stop
func TestRunnerStopNoHooks(t *testing.T) {
r := NewRunner(nil, "/tmp", nil, nil)
@@ -380,7 +380,7 @@ func TestRunnerClaudeLifecyclePayloadsShareSessionID(t *testing.T) {
}
}
// --- Runner.PostLLMCall ---
// Runner.PostLLMCall
func TestRunnerHasPostLLMCall(t *testing.T) {
with := NewRunner([]ResolvedHook{{HookConfig: HookConfig{Command: "x"}, Event: PostLLMCall}}, "/tmp", nil, nil)
@@ -427,7 +427,7 @@ func TestRunnerPostLLMCallKeepsOriginal(t *testing.T) {
}
}
// --- FormatOutcome ---
// FormatOutcome
func TestFormatOutcomePass(t *testing.T) {
o := Outcome{
@@ -456,7 +456,7 @@ func TestFormatOutcomeWithDetail(t *testing.T) {
}
}
// --- clipRunes ---
// clipRunes
func TestClipRunes(t *testing.T) {
if got := clipRunes("short", 10); got != "short" {
@@ -473,7 +473,7 @@ func TestClipRunes(t *testing.T) {
}
}
// --- payload JSON ---
// payload JSON
func TestPayloadJSON(t *testing.T) {
args := json.RawMessage(`{"command":"echo hi"}`)
@@ -503,7 +503,7 @@ func TestPayloadJSON(t *testing.T) {
}
}
// --- capping behavior ---
// capping behavior
func TestCappedBuffer(t *testing.T) {
var cb cappedBuffer
@@ -533,7 +533,7 @@ func TestCappedBuffer(t *testing.T) {
}
}
// --- IsBlocking ---
// IsBlocking
func TestIsBlocking(t *testing.T) {
if !IsBlocking(PreToolUse) {
@@ -550,7 +550,7 @@ func TestIsBlocking(t *testing.T) {
}
}
// --- defaultTimeout ---
// defaultTimeout
func TestDefaultTimeout(t *testing.T) {
if defaultTimeout(PreToolUse) != 5*time.Second {
+1 -1
View File
@@ -57,7 +57,7 @@ func TestCatalogsAgreeOnCodeTokens(t *testing.T) {
}
}
// --- token extraction -------------------------------------------------
// token extraction
var (
reBacktick = regexp.MustCompile("`([^`]+)`")
@@ -34,7 +34,7 @@ func TestPluginGitCommandDisablesLineEndingConversion(t *testing.T) {
}
}
// --- shared helpers ---------------------------------------------------------
// shared helpers
// execInstall marshals args, calls Execute, and unmarshals the response.
// Failures in Execute bubble up as t.Fatal; the response is returned so the
@@ -103,7 +103,7 @@ func (s *stubConnector) connector() MCPConnector {
}
}
// --- apply: skill paths -----------------------------------------------------
// apply: skill paths
func TestApplyLocalSkillRootRegistersPath(t *testing.T) {
project := t.TempDir()
@@ -594,7 +594,7 @@ func TestApplyStrictFalseWarnsWhenDescriptionMissing(t *testing.T) {
}
}
// --- plan / apply: MCP paths -----------------------------------------------
// plan / apply: MCP paths
func TestPlanLocalMCPJSON(t *testing.T) {
project := t.TempDir()
@@ -1389,7 +1389,7 @@ func TestPlanMarkdownSkillURL(t *testing.T) {
}
}
// --- uninstall --------------------------------------------------------------
// uninstall
func TestUninstallRemovesSkillByName(t *testing.T) {
project := t.TempDir()
@@ -1577,7 +1577,7 @@ func TestUninstallRequiresName(t *testing.T) {
}
}
// --- approval hook ----------------------------------------------------------
// approval hook
func TestApprovalHookDeniesApply(t *testing.T) {
project := t.TempDir()
@@ -1649,7 +1649,7 @@ func TestPlanIDIncludesActionDetails(t *testing.T) {
}
}
// --- sanitizers / parsers ---------------------------------------------------
// sanitizers / parsers
func TestSanitizeNameEdges(t *testing.T) {
cases := map[string]string{
@@ -1735,7 +1735,7 @@ func TestPlanIDUsesResolvedActionScope(t *testing.T) {
}
}
// --- local executable -------------------------------------------------------
// local executable
func TestPlanLocalExecutableDetected(t *testing.T) {
project := t.TempDir()
@@ -1818,7 +1818,7 @@ func writeLocalExecutable(t *testing.T, dir, name string) string {
return path
}
// --- plan-only: RiskLevel surfacing -----------------------------------------
// plan-only: RiskLevel surfacing
func TestLinkRiskIsMedium(t *testing.T) {
if level, _ := skillActionRisk("link", skillCandidate{SourcePath: "x"}); level != RiskMedium {
@@ -1836,7 +1836,7 @@ func TestEagerTierEscalatesRisk(t *testing.T) {
}
}
// --- helpers ----------------------------------------------------------------
// helpers
// ExampleNewTool is a godoc example that exercises the public surface
// without touching the filesystem. It also serves as smoke coverage that
+1 -1
View File
@@ -1905,7 +1905,7 @@ func jobKey(parentSession, id string) string {
return strings.TrimSpace(parentSession) + "\x00" + strings.TrimSpace(id)
}
// --- call-context injection (mirrors agent.CallContext) ---
// call-context injection (mirrors agent.CallContext)
type ctxKey struct{}
type sessionCtxKey struct{}
+13 -13
View File
@@ -27,7 +27,7 @@ func TestNewManagerTreatsTypedNilSinkAsDiscard(t *testing.T) {
}
}
// --- Wait with timeout ---
// Wait with timeout
func TestWaitTimeout(t *testing.T) {
m := NewManager(event.Discard)
@@ -49,7 +49,7 @@ func TestWaitTimeout(t *testing.T) {
m.Kill(j.ID)
}
// --- Wait with empty ids waits for all running ---
// Wait with empty ids waits for all running
func TestWaitAllRunning(t *testing.T) {
m := NewManager(event.Discard)
@@ -79,7 +79,7 @@ func TestWaitAllRunning(t *testing.T) {
m.Kill(j2.ID)
}
// --- Output with unknown id ---
// Output with unknown id
func TestOutputUnknownID(t *testing.T) {
m := NewManager(event.Discard)
@@ -91,7 +91,7 @@ func TestOutputUnknownID(t *testing.T) {
}
}
// --- Kill with unknown id ---
// Kill with unknown id
func TestKillUnknownID(t *testing.T) {
m := NewManager(event.Discard)
@@ -102,7 +102,7 @@ func TestKillUnknownID(t *testing.T) {
}
}
// --- startedText ---
// startedText
func TestStartedTextWithLabel(t *testing.T) {
got := startedText("bash", "bash-1", "my-label")
@@ -118,7 +118,7 @@ func TestStartedTextWithoutLabel(t *testing.T) {
}
}
// --- DrainCompletedNote with multiple jobs ---
// DrainCompletedNote with multiple jobs
func TestDrainMultiple(t *testing.T) {
m := NewManager(event.Discard)
@@ -137,7 +137,7 @@ func TestDrainMultiple(t *testing.T) {
}
}
// --- Close is idempotent ---
// Close is idempotent
func TestCloseIdempotent(t *testing.T) {
m := NewManager(event.Discard)
@@ -148,7 +148,7 @@ func TestCloseIdempotent(t *testing.T) {
m.Close() // should not panic
}
// --- Running with no jobs ---
// Running with no jobs
func TestRunningEmpty(t *testing.T) {
m := NewManager(event.Discard)
@@ -158,7 +158,7 @@ func TestRunningEmpty(t *testing.T) {
}
}
// --- Job with error sets Failed ---
// Job with error sets Failed
func TestJobFailed(t *testing.T) {
m := NewManager(event.Discard)
@@ -173,7 +173,7 @@ func TestJobFailed(t *testing.T) {
}
}
// --- Job with result and no error sets Done ---
// Job with result and no error sets Done
func TestJobWithResult(t *testing.T) {
m := NewManager(event.Discard)
@@ -191,7 +191,7 @@ func TestJobWithResult(t *testing.T) {
}
}
// --- Context injection ---
// Context injection
func TestWithManagerFromContext(t *testing.T) {
m := NewManager(event.Discard)
@@ -211,7 +211,7 @@ func TestFromContextEmpty(t *testing.T) {
}
}
// --- Status constants ---
// Status constants
func TestStatusConstants(t *testing.T) {
if Running != "running" {
@@ -228,7 +228,7 @@ func TestStatusConstants(t *testing.T) {
}
}
// --- nowMs ---
// nowMs
func TestNowMs(t *testing.T) {
before := time.Now().UnixMilli()
+8 -8
View File
@@ -7,7 +7,7 @@ import (
"testing"
)
// --- splitFrontmatter ---
// splitFrontmatter
func TestSplitFrontmatterNoFence(t *testing.T) {
fm, body := splitFrontmatter("just plain text\nno frontmatter")
@@ -79,7 +79,7 @@ func TestSplitFrontmatterQuotedValues(t *testing.T) {
}
}
// --- slug ---
// slug
func TestSlug(t *testing.T) {
cases := []struct {
@@ -119,7 +119,7 @@ func TestStoreSaveUnicodeAndRejectsEmptySlug(t *testing.T) {
}
}
// --- oneLine ---
// oneLine
func TestOneLine(t *testing.T) {
cases := []struct {
@@ -140,7 +140,7 @@ func TestOneLine(t *testing.T) {
}
}
// --- render ---
// render
func TestRenderRoundTrip(t *testing.T) {
m := Memory{
@@ -174,7 +174,7 @@ func TestRenderNormalizesType(t *testing.T) {
}
}
// --- loadMemory ---
// loadMemory
func TestLoadMemoryNoFrontmatter(t *testing.T) {
dir := t.TempDir()
@@ -213,7 +213,7 @@ func TestLoadMemoryEmptyFile(t *testing.T) {
}
}
// --- Store.List edge cases ---
// Store.List edge cases
func TestListSkipsNonMdFiles(t *testing.T) {
dir := t.TempDir()
@@ -252,7 +252,7 @@ func TestListSortedByName(t *testing.T) {
}
}
// --- Store.Save edge cases ---
// Store.Save edge cases
func TestSaveEmptyName(t *testing.T) {
s := Store{Dir: t.TempDir()}
@@ -274,7 +274,7 @@ func TestSaveCreatesDir(t *testing.T) {
}
}
// --- Store.Path ---
// Store.Path
func TestStorePath(t *testing.T) {
dir := filepath.Join(t.TempDir(), "memory")
+7 -7
View File
@@ -5,7 +5,7 @@ import (
"testing"
)
// --- ParseDecision ---
// ParseDecision
func TestParseDecisionAllow(t *testing.T) {
if ParseDecision("allow") != Allow {
@@ -46,7 +46,7 @@ func TestParseDecisionUnknown(t *testing.T) {
}
}
// --- Decision.String ---
// Decision.String
func TestDecisionString(t *testing.T) {
if Allow.String() != "allow" {
@@ -63,7 +63,7 @@ func TestDecisionString(t *testing.T) {
}
}
// --- matchGlob edge cases ---
// matchGlob edge cases
func TestMatchGlobEmptyPattern(t *testing.T) {
// Empty pattern matches empty name (both consumed simultaneously).
@@ -108,7 +108,7 @@ func TestMatchGlobQuestionMark(t *testing.T) {
}
}
// --- Subject edge cases ---
// Subject edge cases
func TestSubjectNestedJSON(t *testing.T) {
// Array values should not match.
@@ -147,7 +147,7 @@ func TestSubjectMoveFilePaths(t *testing.T) {
}
}
// --- rememberRule ---
// rememberRule
func TestRememberRuleWithBashSubjectUsesPrefixWhenAvailable(t *testing.T) {
// Bash commands with a safe prefix prefer the prefix over the exact command
@@ -368,7 +368,7 @@ func TestFileMutationRuleMatchesMutationToolsByPath(t *testing.T) {
}
}
// --- New ---
// New
func TestNewPolicy(t *testing.T) {
p := New("deny",
@@ -390,7 +390,7 @@ func TestNewPolicy(t *testing.T) {
}
}
// --- NewGate ---
// NewGate
func TestNewGate(t *testing.T) {
p := New("ask", nil, nil, nil)
+2 -2
View File
@@ -1898,7 +1898,7 @@ func summarizeFailureError(err error) string {
return msg
}
// --- JSON-RPC message types (shared by every transport) ---
// JSON-RPC message types (shared by every transport)
type rpcRequest struct {
JSONRPC string `json:"jsonrpc"`
@@ -1921,7 +1921,7 @@ type rpcError struct {
func (e *rpcError) Error() string { return fmt.Sprintf("rpc error %d: %s", e.Code, e.Message) }
// --- remote tool adapter ---
// remote tool adapter
type remoteTool struct {
client *Client
+1 -1
View File
@@ -772,7 +772,7 @@ func formatWebSearchResults(raw json.RawMessage) string {
return "\n" + b.String() + "\n"
}
// --- Messages API wire protocol ---
// Messages API wire protocol
const cacheWrite5MinuteInputMultiplier = 1.25
+1 -1
View File
@@ -1174,7 +1174,7 @@ func normaliseUsage(u *wireUsage) *provider.Usage {
}
}
// --- OpenAI-compatible wire protocol ---
// OpenAI-compatible wire protocol
type chatRequest struct {
Model string `json:"model"`
+3 -3
View File
@@ -92,7 +92,7 @@ func TestRealDeepSeekCacheProbe(t *testing.T) {
bigHead := "You are a coding agent. Follow these standing instructions precisely. " +
strings.Repeat("Keep the prefix identical across turns so the context cache can serve it. ", 60)
// ---- Probe 1: does the cache serve a repeated prefix at all? ----
// Probe 1: does the cache serve a repeated prefix at all?
base := []provider.Message{
{Role: provider.RoleSystem, Content: bigHead},
{Role: provider.RoleUser, Content: "Reply with the single word: ok."},
@@ -114,7 +114,7 @@ func TestRealDeepSeekCacheProbe(t *testing.T) {
"or the prefix is below the cacheable size")
}
// ---- Probe 3 (cheap, do it early): does v4-flash emit reasoning_content? ----
// Probe 3 (cheap, do it early): does v4-flash emit reasoning_content?
t.Logf("==== Probe 3: does deepseek-v4-flash return reasoning_content? ====")
t.Logf("saw reasoning chunks: %v reasoning_tokens reported: %d reasoning_text_len: %d",
p1a.sawReasoning, p1a.reasoning, len(p1a.reasoningText))
@@ -122,7 +122,7 @@ func TestRealDeepSeekCacheProbe(t *testing.T) {
t.Logf("→ this v4-flash response did not contain reasoning_content; replay cost applies only to tool-call turns that actually carry provider-issued reasoning")
}
// ---- Probe 2: cost/cache effect of required tool-call reasoning replay ----
// Probe 2: cost/cache effect of required tool-call reasoning replay
longReasoning := strings.Repeat("Let me think carefully about each requirement and weigh the trade-offs. ", 40)
histBase := func(withReasoning bool) []provider.Message {
asst := provider.Message{
+8 -8
View File
@@ -7,7 +7,7 @@ import (
"testing"
)
// --- SanitizeToolPairing ---
// SanitizeToolPairing
// toolIDsAnswered reports whether every assistant tool_call id has a following
// tool message answering it — the contract the OpenAI/DeepSeek API enforces.
@@ -391,7 +391,7 @@ func TestSanitizeToolPairingBackfillsMissingToolResultName(t *testing.T) {
}
}
// --- Pricing.Cost ---
// Pricing.Cost
func TestPricingCostNil(t *testing.T) {
var p *Pricing
@@ -477,7 +477,7 @@ func TestPricingCostZeroTokens(t *testing.T) {
}
}
// --- Pricing.Symbol ---
// Pricing.Symbol
func TestPricingSymbolDefault(t *testing.T) {
p := &Pricing{}
@@ -524,7 +524,7 @@ func TestPricingSymbolNormalizesCurrencyCodes(t *testing.T) {
}
}
// --- AuthError ---
// AuthError
func TestAuthErrorWithKeyEnv(t *testing.T) {
e := &AuthError{Provider: "deepseek", KeyEnv: "DEEPSEEK_API_KEY", Status: 401}
@@ -567,7 +567,7 @@ func TestAuthErrorImplementsError(t *testing.T) {
}
}
// --- Registry ---
// Registry
func TestRegistryKindsSorted(t *testing.T) {
// The openai package self-registers via init(); we can't control that here
@@ -615,7 +615,7 @@ func TestNewRejectsTypedNilProvider(t *testing.T) {
}
}
// --- Role constants ---
// Role constants
func TestRoleConstants(t *testing.T) {
if RoleSystem != "system" {
@@ -663,7 +663,7 @@ func TestMessageResponsesItemsRemainBackwardCompatible(t *testing.T) {
}
}
// --- ChunkType constants ---
// ChunkType constants
func TestChunkTypeConstants(t *testing.T) {
types := []ChunkType{ChunkText, ChunkReasoning, ChunkToolCallStart, ChunkToolCallArgsDelta, ChunkToolCall, ChunkUsage, ChunkDone, ChunkError, ChunkResponsesItem}
@@ -674,7 +674,7 @@ func TestChunkTypeConstants(t *testing.T) {
}
}
// --- ToolSchema ---
// ToolSchema
func TestToolSchemaJSON(t *testing.T) {
ts := ToolSchema{
+1 -1
View File
@@ -1179,7 +1179,7 @@ func (g *Gate) RecordDiagnosis(taskID, note string) {
}
}
// --- internals ---
// internals
func (g *Gate) activeMode() bool {
mode := strings.ToLower(strings.TrimSpace(g.opts.Mode()))
+5 -5
View File
@@ -9,7 +9,7 @@ import (
"testing"
)
// --- Spec.Enforce ---
// Spec.Enforce
func TestEnforce(t *testing.T) {
cases := []struct {
@@ -30,7 +30,7 @@ func TestEnforce(t *testing.T) {
}
}
// --- Spec zero value ---
// Spec zero value
func TestSpecZeroValue(t *testing.T) {
var s Spec
@@ -69,7 +69,7 @@ func TestUnavailableMessageIsActionable(t *testing.T) {
}
}
// --- Command ---
// Command
func TestCommandNonEnforce(t *testing.T) {
spec := Spec{Mode: "off"}
@@ -269,7 +269,7 @@ func TestShellArgvDefaultsPath(t *testing.T) {
}
}
// --- Command (platform-specific) ---
// platform-specific Command tests
func TestCommandNonDarwin(t *testing.T) {
if runtime.GOOS == "darwin" {
@@ -322,7 +322,7 @@ func TestCommandDarwinNonEnforce(t *testing.T) {
}
}
// --- Available ---
// Available
func TestAvailableNonDarwin(t *testing.T) {
if runtime.GOOS == "darwin" {
+3 -3
View File
@@ -8,7 +8,7 @@ import (
"testing"
)
// --- sbplString ---
// sbplString
func TestSbplString(t *testing.T) {
cases := []struct {
@@ -29,7 +29,7 @@ func TestSbplString(t *testing.T) {
}
}
// --- writeAllowDirs ---
// writeAllowDirs
func TestWriteAllowDirsDeduplication(t *testing.T) {
dirs := writeAllowDirs([]string{"/tmp", "/tmp", "/tmp"})
@@ -111,7 +111,7 @@ func TestWriteAllowDirsNoDuplicates(t *testing.T) {
}
}
// --- seatbeltProfile ---
// seatbeltProfile
func TestSeatbeltProfileDeniesNetwork(t *testing.T) {
spec := Spec{Mode: "enforce", Network: false, WriteRoots: []string{"/workspace"}}
+10 -10
View File
@@ -7,7 +7,7 @@ import (
"testing"
)
// --- IsValidName ---
// IsValidName
func TestIsValidName(t *testing.T) {
cases := []struct {
@@ -34,7 +34,7 @@ func TestIsValidName(t *testing.T) {
}
}
// --- splitFrontmatter ---
// splitFrontmatter
func TestSplitFrontmatterNoFence(t *testing.T) {
fm, body := splitFrontmatter("just body")
@@ -73,7 +73,7 @@ func TestSplitFrontmatterQuotedValues(t *testing.T) {
}
}
// --- parseAllowedTools ---
// parseAllowedTools
func TestParseAllowedToolsEmpty(t *testing.T) {
if got := parseAllowedTools(""); got != nil {
@@ -115,7 +115,7 @@ func TestParseAllowedToolsExtraSpaces(t *testing.T) {
}
}
// --- parseRunAs ---
// parseRunAs
func TestParseRunAsExplicit(t *testing.T) {
if parseRunAs("subagent", "", "") != RunSubagent {
@@ -150,7 +150,7 @@ func TestParseRunAsDefault(t *testing.T) {
}
}
// --- resolveCustomPaths ---
// resolveCustomPaths
func TestResolveCustomPathsTilde(t *testing.T) {
home := t.TempDir()
@@ -183,7 +183,7 @@ func TestResolveCustomPathsEmpty(t *testing.T) {
}
}
// --- dedupePaths ---
// dedupePaths
func TestDedupePaths(t *testing.T) {
got := dedupePaths([]string{"/a", "/b", "/a", "/c", "/b"})
@@ -199,7 +199,7 @@ func TestDedupePathsEmpty(t *testing.T) {
}
}
// --- stubBody ---
// stubBody
func TestStubBody(t *testing.T) {
body := stubBody("my-skill")
@@ -214,7 +214,7 @@ func TestStubBody(t *testing.T) {
}
}
// --- Read edge cases ---
// Read edge cases
func TestReadInvalidName(t *testing.T) {
home := t.TempDir()
@@ -234,7 +234,7 @@ func TestReadNotFound(t *testing.T) {
}
}
// --- Create edge cases ---
// Create edge cases
func TestCreateInvalidName(t *testing.T) {
home := t.TempDir()
@@ -464,7 +464,7 @@ func TestDeleteRefusesScopeMismatch(t *testing.T) {
}
}
// --- New edge cases ---
// New edge cases
func TestNewWithCustomPaths(t *testing.T) {
custom := t.TempDir()
+5 -5
View File
@@ -39,7 +39,7 @@ type ProfileResolver func(sk Skill) *event.Profile
// refresh UI (e.g. a skills sidebar) without a reload. nil is fine.
type InstalledHook func(name, path string, scope Scope)
// --- run_skill ---
// run_skill
type runSkillTool struct {
store *Store
@@ -149,7 +149,7 @@ func (t *runSkillTool) profileForSkill(sk Skill) *event.Profile {
return profileForSkill(sk, t.profileResolver)
}
// --- read_only_skill ---
// read_only_skill
type readOnlySkillTool struct {
store *Store
@@ -315,7 +315,7 @@ func (t *readSkillTool) Execute(_ context.Context, args json.RawMessage) (string
return renderInline(sk, strings.TrimSpace(p.Arguments)), nil
}
// --- dedicated subagent wrappers (explore / research / review / security_review) ---
// dedicated subagent wrappers (explore / research / review / security_review)
type subagentSkillTool struct {
toolName string
@@ -437,7 +437,7 @@ func BuiltinSubagentTools(store *Store, runner SubagentRunner, profileResolver .
return out
}
// --- install_skill ---
// install_skill
type installSkillTool struct {
store *Store
@@ -622,7 +622,7 @@ func RenderSkillFile(opts SkillFileOptions) string {
return "---\n" + string(raw) + "---\n\n" + strings.TrimRight(opts.Body, " \t\r\n") + "\n"
}
// --- shared helpers ---
// shared helpers
// Render builds a skill's invocation text: a header (name, description, source)
// followed by the body and any arguments. Used directly when a user invokes a
+1 -1
View File
@@ -447,7 +447,7 @@ func TestProviderSplit(t *testing.T) {
}
}
// --- test helpers ---
// test helpers
func dailyJSONLFiles(t *testing.T, dir string) []os.DirEntry {
t.Helper()
+3 -3
View File
@@ -71,7 +71,7 @@ func (s *InMemoryStore) AppendEvent(projectDir string, ev TaskEvent) error {
s.mu.Lock()
defer s.mu.Unlock()
// --- sequence validation ---
// sequence validation
prev, hasPrev := s.lastSeq[ev.TaskID]
if hasPrev {
if ev.Sequence <= prev {
@@ -80,13 +80,13 @@ func (s *InMemoryStore) AppendEvent(projectDir string, ev TaskEvent) error {
}
}
// --- terminal-state guard ---
// terminal-state guard
if snap, ok := s.tasks[ev.TaskID]; ok && snap.State.Terminal() {
return fmt.Errorf("append event: task %s is in terminal state %q",
ev.TaskID, snap.State)
}
// --- identity validation ---
// identity validation
if snap, ok := s.tasks[ev.TaskID]; ok {
if ev.SessionID != snap.SessionID {
return fmt.Errorf("append event: SessionID mismatch (event=%q, snapshot=%q)",
-10
View File
@@ -129,9 +129,7 @@ func TestRuntimeStateEffective_LegacyAndKnownValues(t *testing.T) {
}
}
// ---------------------------------------------------------------------------
// TaskSnapshot
// ---------------------------------------------------------------------------
func TestTaskSnapshotValidate_Valid(t *testing.T) {
ts := TaskSnapshot{
@@ -271,9 +269,7 @@ func TestTaskSnapshotJSON_LegacyMissingRuntimeState(t *testing.T) {
}
}
// ---------------------------------------------------------------------------
// TaskEvent
// ---------------------------------------------------------------------------
func TestTaskEventValidate_Valid(t *testing.T) {
ev := TaskEvent{
@@ -371,9 +367,7 @@ func TestTaskEventJSON_NoSensitiveFields(t *testing.T) {
}
}
// ---------------------------------------------------------------------------
// InMemoryStore
// ---------------------------------------------------------------------------
func seedTime(i int) time.Time {
return time.Date(2025, 1, 1, 0, 0, i, 0, time.UTC)
@@ -538,9 +532,7 @@ func TestInMemoryStore_ListEvents_ProjectIsolation(t *testing.T) {
}
}
// ---------------------------------------------------------------------------
// Event validation
// ---------------------------------------------------------------------------
func TestInMemoryStore_AppendEvent_RejectsDuplicateSequence(t *testing.T) {
store := NewInMemoryStore()
@@ -685,9 +677,7 @@ func TestStore_DoesNotLeakSensitiveViaInterface(t *testing.T) {
}
}
// ---------------------------------------------------------------------------
// helpers
// ---------------------------------------------------------------------------
func mustUpsert(t *testing.T, store *InMemoryStore, proj string, snap TaskSnapshot) {
t.Helper()
+3 -3
View File
@@ -26,7 +26,7 @@ func init() {
tool.RegisterBuiltin(waitJob{})
}
// --- bash_output: poll a background job's new output (non-blocking) ---
// bash_output: poll a background job's new output (non-blocking)
type bashOutput struct{}
@@ -93,7 +93,7 @@ func filterLines(s, re string) (string, error) {
return strings.Join(keep, "\n"), nil
}
// --- kill_shell: terminate a running background job ---
// kill_shell: terminate a running background job
type killShell struct{}
@@ -129,7 +129,7 @@ func (killShell) Execute(ctx context.Context, args json.RawMessage) (string, err
return fmt.Sprintf("Background job %q was not running (already finished or unknown).", p.JobID), nil
}
// --- wait: block until background jobs finish, then return their results ---
// wait: block until background jobs finish, then return their results
type waitJob struct{}
+1 -1
View File
@@ -490,7 +490,7 @@ func TestGlobNoMatches(t *testing.T) {
}
}
// --- GB18030 encoding integration tests (issue #2637) ---
// GB18030 encoding integration tests (issue #2637)
func TestReadFileGB18030(t *testing.T) {
f := filepath.Join(t.TempDir(), "gbk.txt")
+2 -2
View File
@@ -390,7 +390,7 @@ func TestUnconfinedWriterWritesAnywhere(t *testing.T) {
}
}
// --- confineRead & ConfineReaders ---
// confineRead & ConfineReaders
func TestConfineReadEmpty(t *testing.T) {
if confineRead(nil, "/anywhere") {
@@ -534,7 +534,7 @@ func TestGlobFiltersSensitiveMatchesWhenProtected(t *testing.T) {
}
}
// --- grep forbid-read ---
// grep forbid-read
func TestConfineReadBlocksGrepFile(t *testing.T) {
forbidDir := t.TempDir()
+4 -4
View File
@@ -10,7 +10,7 @@ import (
"testing"
)
// --- read_file extended tests ---
// read_file extended tests
func TestReadFileMissing(t *testing.T) {
_, err := readFile{}.Execute(context.Background(), argsJSON(t, map[string]any{"path": "/nonexistent/file.txt"}))
@@ -74,7 +74,7 @@ func TestReadFileInvalidArgs(t *testing.T) {
}
}
// --- ls extended tests ---
// ls extended tests
func TestLsEmptyDir(t *testing.T) {
dir := t.TempDir()
@@ -106,7 +106,7 @@ func TestLsInvalidArgs(t *testing.T) {
}
}
// --- grep extended tests ---
// grep extended tests
func TestGrepSingleFile(t *testing.T) {
dir := t.TempDir()
@@ -183,7 +183,7 @@ func TestGrepTruncation(t *testing.T) {
}
}
// --- glob extended tests ---
// glob extended tests
func TestGlobEmptyPattern(t *testing.T) {
_, err := globTool{}.Execute(context.Background(), argsJSON(t, map[string]any{"pattern": ""}))
+1 -1
View File
@@ -238,7 +238,7 @@ func TestWorkspaceReadToolsResolveExternalReadRoots(t *testing.T) {
assertExternalToolError(t, tools["glob"], map[string]any{"pattern": token + "/missing/**/*.go"}, token+"/missing/**/*.go", external)
}
// --- helpers ---
// helpers
func byName(tools []tool.Tool) map[string]tool.Tool {
m := make(map[string]tool.Tool, len(tools))
+6 -6
View File
@@ -10,7 +10,7 @@ import (
"testing"
)
// --- write_file extended tests ---
// write_file extended tests
func TestWriteFileCreatesParentDirs(t *testing.T) {
dir := t.TempDir()
@@ -81,7 +81,7 @@ func TestWriteFileInvalidArgs(t *testing.T) {
}
}
// --- move_file tests ---
// move_file tests
func TestMoveFileMovesIntoParentDir(t *testing.T) {
dir := t.TempDir()
@@ -244,7 +244,7 @@ func TestMoveFileFallsBackForCrossDeviceRename(t *testing.T) {
}
}
// --- edit_file extended tests ---
// edit_file extended tests
func TestEditFileNotFound(t *testing.T) {
f := filepath.Join(t.TempDir(), "missing.txt")
@@ -392,7 +392,7 @@ func TestEditFileInvalidArgs(t *testing.T) {
}
}
// --- multi_edit extended tests ---
// multi_edit extended tests
func TestMultiEditEmptyEdits(t *testing.T) {
f := filepath.Join(t.TempDir(), "a.txt")
@@ -506,7 +506,7 @@ func TestMultiEditChained(t *testing.T) {
}
}
// --- confine tests ---
// confine tests
func TestConfineRejectsEscape(t *testing.T) {
dir := t.TempDir()
@@ -534,7 +534,7 @@ func TestConfineEmptyRootsAllowsAll(t *testing.T) {
}
}
// --- resolveIn tests ---
// resolveIn tests
func TestResolveInAbsolute(t *testing.T) {
abs := filepath.Join(t.TempDir(), "absolute", "path")
+3 -3
View File
@@ -17,7 +17,7 @@ import (
"reasonix/internal/textutil"
)
// ---- list_sessions tool -----------------------------------------------------
// list_sessions tool
type listSessionsTool struct {
sessionDir string
@@ -63,7 +63,7 @@ func (t *listSessionsTool) Execute(_ context.Context, _ json.RawMessage) (string
return b.String(), nil
}
// ---- read_session tool ------------------------------------------------------
// read_session tool
type readSessionTool struct {
sessionDir string
@@ -198,7 +198,7 @@ loop:
return b.String(), nil
}
// ---- helpers ----------------------------------------------------------------
// helpers
// truncateRunes preserves the historical name but truncates by grapheme
// clusters so previews do not split combined emoji or other visible characters.
@@ -41,7 +41,7 @@ func runTool(t *testing.T, tl interface {
return out
}
// ---- list_sessions tests ----------------------------------------------------
// list_sessions tests
func TestListSessions_EmptyDir(t *testing.T) {
dir := t.TempDir()
@@ -109,7 +109,7 @@ func TestListSessions_SingleSession(t *testing.T) {
}
}
// ---- read_session tests -----------------------------------------------------
// read_session tests
func TestReadSession_ValidSession(t *testing.T) {
dir := t.TempDir()
@@ -307,7 +307,7 @@ func TestReadSession_ToolResultsWithOptIn(t *testing.T) {
}
}
// ---- helper tests -----------------------------------------------------------
// helper tests
func TestModelFromPath(t *testing.T) {
tests := []struct {
+2 -2
View File
@@ -232,7 +232,7 @@ type SnipHinter interface {
SnipHint() SnipHint
}
// --- process-global built-in set (populated by builtin subpackage init) ---
// process-global built-in set (populated by builtin subpackage init)
var builtins = map[string]Tool{}
@@ -266,7 +266,7 @@ func LookupBuiltin(name string) (Tool, bool) {
return t, ok
}
// --- per-run registry instance ---
// per-run registry instance
// Registry is a per-run set of tools: enabled built-ins plus plugin tools.
type Registry struct {
-6
View File
@@ -129,9 +129,7 @@ func (p *plugin) Initialize(_ context.Context, params extension.InitializeParams
}, nil
}
// ---------------------------------------------------------------------------
// Interceptors
// ---------------------------------------------------------------------------
// interceptInput rewrites any input that starts with the "/fs " trigger.
func (p *plugin) interceptInput(ctx context.Context, payload json.RawMessage) (*extension.InterceptResult, error) {
@@ -204,9 +202,7 @@ func (p *plugin) interceptSystemPrompt(_ context.Context, payload json.RawMessag
return extension.Replace(map[string]string{"prompt": owned, "workspaceRoot": in.WorkspaceRoot})
}
// ---------------------------------------------------------------------------
// Observation and UI
// ---------------------------------------------------------------------------
// observe publishes the extension's status line and demo card when the
// session starts.
@@ -286,9 +282,7 @@ func (p *plugin) submit(ctx context.Context, surfaceID string, values map[string
})
}
// ---------------------------------------------------------------------------
// Fake streaming provider
// ---------------------------------------------------------------------------
func fakeRef(pluginID string) string { return "plugin/" + pluginID + "/fake/" + fakeModel }
-24
View File
@@ -38,9 +38,7 @@ import (
"time"
)
// ---------------------------------------------------------------------------
// Public callback types
// ---------------------------------------------------------------------------
// Handler is the one mandatory extension hook. Initialize is called once and
// completes before any other callback. Return the sidecar's declaration
@@ -161,9 +159,7 @@ type Options struct {
Logger *log.Logger
}
// ---------------------------------------------------------------------------
// Sentinel errors
// ---------------------------------------------------------------------------
// ErrNotReady reports an Extension → Host call made before the handshake
// barrier opened: the sidecar must not send requests or notifications before
@@ -180,9 +176,7 @@ var ErrNoConnection = errors.New("extension: no host connection in context (use
// this sentinel.
var ErrUICancelled = errors.New("extension: the user dismissed the prompt")
// ---------------------------------------------------------------------------
// InterceptResult helpers
// ---------------------------------------------------------------------------
// Continue lets the event proceed unchanged.
func Continue() *InterceptResult { return &InterceptResult{Decision: DecisionContinue} }
@@ -224,9 +218,7 @@ func Deny(reason string) *InterceptResult {
return &InterceptResult{Decision: DecisionDeny, Reason: reason}
}
// ---------------------------------------------------------------------------
// Serve
// ---------------------------------------------------------------------------
type serverState uint8
@@ -328,9 +320,7 @@ func (s *server) withConnNotification(f notificationHandler) notificationHandler
}
}
// ---------------------------------------------------------------------------
// Handshake barrier
// ---------------------------------------------------------------------------
// gateRequest runs on the read loop before dispatch: the host must open with
// extension/initialize, and until its extension/initialized notification
@@ -390,9 +380,7 @@ func (s *server) checkReady() error {
return nil
}
// ---------------------------------------------------------------------------
// Lifecycle handlers
// ---------------------------------------------------------------------------
// fatalError marks handler failures that must end the connection after the
// error response is written (a failed handshake leaves nothing to serve).
@@ -495,9 +483,7 @@ func (s *server) handleShutdown(ctx context.Context, raw json.RawMessage) (any,
}, nil
}
// ---------------------------------------------------------------------------
// Intercept and observation
// ---------------------------------------------------------------------------
func (s *server) handleIntercept(ctx context.Context, raw json.RawMessage) (any, error) {
var p InterceptParams
@@ -569,9 +555,7 @@ func (s *server) handleResourcesChanged(ctx context.Context, raw json.RawMessage
}
}
// ---------------------------------------------------------------------------
// Provider broker
// ---------------------------------------------------------------------------
func (s *server) handleProviderCatalog(ctx context.Context, raw json.RawMessage) (any, error) {
if s.opts.Provider == nil {
@@ -725,9 +709,7 @@ func (s *server) sendStreamEnd(end *StreamEndParams) {
}
}
// ---------------------------------------------------------------------------
// UI handlers (Host → Extension)
// ---------------------------------------------------------------------------
func (s *server) handleUIAction(ctx context.Context, raw json.RawMessage) (any, error) {
if s.opts.UI.Action == nil {
@@ -759,9 +741,7 @@ func (s *server) handleUISubmit(ctx context.Context, raw json.RawMessage) (any,
return UISubmitResult{Accepted: true}, nil
}
// ---------------------------------------------------------------------------
// HostUI: Extension → Host UI client
// ---------------------------------------------------------------------------
// HostUI is the sidecar's client for the host's structured UI surfaces. The
// zero value is ready to use; every method takes the context of an SDK
@@ -1013,9 +993,7 @@ func validateFormPayload(p UIFormPayload) error {
return nil
}
// ---------------------------------------------------------------------------
// Content refs (Extension → Host)
// ---------------------------------------------------------------------------
// ReadContentRef pages one whole content ref back from the host in
// ContentRefChunkBytes chunks, verifies the reassembled byte count and
@@ -1131,9 +1109,7 @@ func resolveExternalized(ctx context.Context, raw json.RawMessage, externalized
return data, nil
}
// ---------------------------------------------------------------------------
// shared helpers
// ---------------------------------------------------------------------------
// callHost issues one Extension → Host request behind the handshake barrier
// and maps a structured wire error back to a *ProtocolError.
-8
View File
@@ -18,9 +18,7 @@ import (
// required fields, method names, directions, limits, error reasons, and
// semantics never change.
// ---------------------------------------------------------------------------
// Enum helpers
// ---------------------------------------------------------------------------
// InterceptEvents returns the 17 frozen hook point names, sorted.
func InterceptEvents() []string {
@@ -73,9 +71,7 @@ func validUISeverity(severity UISeverity) bool {
return false
}
// ---------------------------------------------------------------------------
// Wire DTO validators
// ---------------------------------------------------------------------------
// Validate enforces the deterministic wire shape.
func (request ProviderRequest) Validate() error {
@@ -142,9 +138,7 @@ func (d ProtocolErrorData) Validate() error {
return nil
}
// ---------------------------------------------------------------------------
// ProtocolError
// ---------------------------------------------------------------------------
// ProtocolError is the extension protocol's structured error. Handlers may
// return one to choose the wire reason; the SDK answers with the frozen
@@ -180,9 +174,7 @@ func MustProtocolError(reason ErrorReason) *ProtocolError {
return errValue
}
// ---------------------------------------------------------------------------
// internal helpers shared with the validator
// ---------------------------------------------------------------------------
type validationFailure struct{ message string }
+3 -122
View File
@@ -1,9 +1,9 @@
{
"limits": {
"banner": 312,
"banner": 0,
"commented-code": 0,
"essay": 4111,
"file-size": 73775,
"file-size": 73751,
"layering": 1,
"marker": 0,
"narrative": 66,
@@ -23,11 +23,9 @@
"essay": 1
},
"cmd/reasonix-plugin-example/main.go": {
"banner": 4,
"essay": 19
},
"desktop/app.go": {
"banner": 2,
"essay": 90,
"file-size": 11545
},
@@ -35,12 +33,10 @@
"essay": 1
},
"desktop/app_test.go": {
"banner": 1,
"essay": 2,
"test-file-size": 10208
},
"desktop/bot_bridge.go": {
"banner": 2,
"essay": 11
},
"desktop/bot_connection_app.go": {
@@ -58,9 +54,6 @@
"desktop/cmd/update-helper/args.go": {
"essay": 1
},
"desktop/cmd/update-helper/main_linux_test.go": {
"banner": 1
},
"desktop/cmd/update-helper/main_windows.go": {
"essay": 3
},
@@ -100,7 +93,6 @@
"essay": 1
},
"desktop/main.go": {
"banner": 1,
"essay": 7
},
"desktop/main_test.go": {
@@ -170,11 +162,9 @@
"essay": 3
},
"desktop/sessions_test.go": {
"banner": 5,
"test-file-size": 733
},
"desktop/settings_app.go": {
"banner": 2,
"essay": 28,
"file-size": 3014,
"narrative": 1
@@ -199,7 +189,6 @@
"essay": 1
},
"desktop/tabs.go": {
"banner": 10,
"essay": 123,
"file-size": 8822
},
@@ -270,7 +259,6 @@
"essay": 2
},
"desktop/workspace_test.go": {
"banner": 6,
"test-file-size": 1049
},
"internal/acp/clientio.go": {
@@ -292,17 +280,12 @@
"essay": 1
},
"internal/acp/protocol.go": {
"banner": 17,
"essay": 13
},
"internal/acp/protocol_test.go": {
"banner": 5
},
"internal/acp/server.go": {
"essay": 4
},
"internal/acp/server_test.go": {
"banner": 3,
"essay": 1,
"test-file-size": 1323
},
@@ -334,7 +317,6 @@
"essay": 1
},
"internal/agent/cachehit_e2e_test.go": {
"banner": 2,
"essay": 2
},
"internal/agent/capability_gate.go": {
@@ -383,7 +365,6 @@
"narrative": 1
},
"internal/agent/extensions_test.go": {
"banner": 8,
"essay": 4,
"narrative": 1,
"test-file-size": 1022
@@ -391,9 +372,6 @@
"internal/agent/fleet.go": {
"essay": 4
},
"internal/agent/guards_test.go": {
"banner": 1
},
"internal/agent/listsessions_bench_test.go": {
"essay": 4
},
@@ -490,9 +468,6 @@
"internal/agent/session_removal.go": {
"essay": 6
},
"internal/agent/session_test.go": {
"banner": 9
},
"internal/agent/steer_flush_test.go": {
"essay": 1
},
@@ -540,9 +515,6 @@
"essay": 3,
"file-size": 223
},
"internal/billing/balance_extra_test.go": {
"banner": 3
},
"internal/boot/boot.go": {
"essay": 110,
"file-size": 2203,
@@ -653,9 +625,6 @@
"internal/cli/acp.go": {
"essay": 7
},
"internal/cli/box_test.go": {
"banner": 3
},
"internal/cli/branch.go": {
"essay": 2
},
@@ -673,13 +642,9 @@
"essay": 9
},
"internal/cli/chat_tui_test.go": {
"banner": 2,
"essay": 8,
"test-file-size": 3590
},
"internal/cli/chooser.go": {
"banner": 1
},
"internal/cli/cli.go": {
"essay": 60,
"file-size": 2008
@@ -693,7 +658,6 @@
"file-size": 74
},
"internal/cli/complete_test.go": {
"banner": 1,
"test-file-size": 15
},
"internal/cli/composer_selection.go": {
@@ -794,12 +758,6 @@
"internal/cli/switch_recovery_test.go": {
"essay": 2
},
"internal/cli/task.go": {
"banner": 4
},
"internal/cli/task_test.go": {
"banner": 6
},
"internal/cli/transcript.go": {
"essay": 1,
"file-size": 2
@@ -816,9 +774,6 @@
"internal/cli/wrap_cache.go": {
"essay": 6
},
"internal/command/command_extra_test.go": {
"banner": 3
},
"internal/config/backfill_test.go": {
"test-file-size": 945
},
@@ -910,7 +865,6 @@
"essay": 2
},
"internal/control/approval.go": {
"banner": 2,
"essay": 19
},
"internal/control/autoresearch_manager.go": {
@@ -920,7 +874,6 @@
"essay": 10
},
"internal/control/controller.go": {
"banner": 3,
"essay": 180,
"file-size": 5379,
"narrative": 4
@@ -1020,9 +973,6 @@
"internal/control/yolo_test.go": {
"test-file-size": 473
},
"internal/diff/diff_extra_test.go": {
"banner": 5
},
"internal/doctor/report.go": {
"essay": 3
},
@@ -1045,9 +995,6 @@
"essay": 10,
"narrative": 1
},
"internal/event/event_test.go": {
"banner": 10
},
"internal/event/subagent_progress.go": {
"essay": 9
},
@@ -1078,9 +1025,6 @@
"internal/extension/catalog.go": {
"essay": 6
},
"internal/extension/conformance/conformance_test.go": {
"banner": 16
},
"internal/extension/contributor.go": {
"essay": 1
},
@@ -1186,9 +1130,6 @@
"internal/fileutil/atomicwrite_test.go": {
"essay": 2
},
"internal/fileutil/encoding/encoding_test.go": {
"banner": 6
},
"internal/fileutil/replacefallback_other.go": {
"essay": 1
},
@@ -1215,14 +1156,10 @@
"internal/hook/runner.go": {
"essay": 2
},
"internal/hook/runner_test.go": {
"banner": 13
},
"internal/hook/windows_compat.go": {
"essay": 1
},
"internal/i18n/catalog_parity_test.go": {
"banner": 1,
"essay": 13
},
"internal/i18n/i18n.go": {
@@ -1235,7 +1172,6 @@
"essay": 2
},
"internal/installsource/install_source_test.go": {
"banner": 9,
"essay": 2,
"test-file-size": 1720
},
@@ -1262,12 +1198,10 @@
"test-file-size": 238
},
"internal/jobs/jobs.go": {
"banner": 1,
"essay": 42,
"file-size": 1263
},
"internal/jobs/jobs_extra_test.go": {
"banner": 13,
"essay": 1
},
"internal/jobs/jobs_security_test.go": {
@@ -1286,9 +1220,6 @@
"essay": 9,
"file-size": 94
},
"internal/memory/store_extra_test.go": {
"banner": 8
},
"internal/memory/store_test.go": {
"test-file-size": 138
},
@@ -1300,7 +1231,6 @@
"file-size": 156
},
"internal/permission/permission_extra_test.go": {
"banner": 7,
"essay": 1
},
"internal/plugin/chrome_devtools_live_test.go": {
@@ -1323,7 +1253,6 @@
"test-file-size": 279
},
"internal/plugin/plugin.go": {
"banner": 2,
"essay": 30,
"file-size": 1324
},
@@ -1384,7 +1313,6 @@
"file-size": 5
},
"internal/provider/anthropic/anthropic.go": {
"banner": 1,
"essay": 36,
"file-size": 100
},
@@ -1396,7 +1324,6 @@
"essay": 8
},
"internal/provider/openai/openai.go": {
"banner": 1,
"essay": 42,
"file-size": 555
},
@@ -1405,16 +1332,12 @@
"test-file-size": 1558
},
"internal/provider/openai/realcache_test.go": {
"banner": 3,
"essay": 7
},
"internal/provider/provider.go": {
"essay": 50,
"file-size": 350
},
"internal/provider/provider_test.go": {
"banner": 8
},
"internal/provider/responses/responses.go": {
"essay": 26,
"file-size": 81
@@ -1448,7 +1371,6 @@
"essay": 1
},
"internal/recovery/gate.go": {
"banner": 1,
"essay": 7,
"file-size": 654
},
@@ -1536,15 +1458,9 @@
"internal/sandbox/sandbox.go": {
"essay": 11
},
"internal/sandbox/sandbox_test.go": {
"banner": 5
},
"internal/sandbox/seatbelt_darwin.go": {
"essay": 3
},
"internal/sandbox/seatbelt_darwin_test.go": {
"banner": 3
},
"internal/sandbox/seatbelt_other.go": {
"essay": 4
},
@@ -1604,14 +1520,10 @@
"essay": 7,
"file-size": 633
},
"internal/skill/skill_extra_test.go": {
"banner": 10
},
"internal/skill/skill_test.go": {
"test-file-size": 283
},
"internal/skill/tools.go": {
"banner": 5,
"essay": 2
},
"internal/skill/tools_test.go": {
@@ -1626,9 +1538,6 @@
"internal/stats/recorder.go": {
"essay": 1
},
"internal/stats/stats_test.go": {
"banner": 1
},
"internal/store/remote.go": {
"essay": 6
},
@@ -1648,12 +1557,8 @@
"essay": 3
},
"internal/taskmonitor/memory.go": {
"banner": 3,
"essay": 5
},
"internal/taskmonitor/model_test.go": {
"banner": 10
},
"internal/taskmonitor/store.go": {
"essay": 8
},
@@ -1665,14 +1570,12 @@
"essay": 4
},
"internal/tool/builtin/bgjobs.go": {
"banner": 3,
"essay": 10
},
"internal/tool/builtin/bgjobs_test.go": {
"essay": 6
},
"internal/tool/builtin/builtin_test.go": {
"banner": 1,
"essay": 3
},
"internal/tool/builtin/clientio.go": {
@@ -1684,9 +1587,6 @@
"internal/tool/builtin/confine.go": {
"essay": 16
},
"internal/tool/builtin/confine_test.go": {
"banner": 2
},
"internal/tool/builtin/encoding_helpers.go": {
"essay": 1
},
@@ -1714,9 +1614,6 @@
"internal/tool/builtin/session_guard.go": {
"essay": 25
},
"internal/tool/builtin/tool_extra_test.go": {
"banner": 4
},
"internal/tool/builtin/updategoal.go": {
"essay": 2
},
@@ -1726,12 +1623,6 @@
"internal/tool/builtin/workspace.go": {
"essay": 12
},
"internal/tool/builtin/workspace_test.go": {
"banner": 1
},
"internal/tool/builtin/write_tool_test.go": {
"banner": 6
},
"internal/tool/builtin/writefile.go": {
"essay": 2
},
@@ -1747,30 +1638,20 @@
"internal/tool/resolved.go": {
"essay": 1
},
"internal/tool/sessiontool/sessiontool.go": {
"banner": 3
},
"internal/tool/sessiontool/sessiontool_test.go": {
"banner": 3
},
"internal/tool/shell_execution.go": {
"essay": 3
},
"internal/tool/tool.go": {
"banner": 2,
"essay": 14
},
"sdk/go/examples/fullsidecar/main.go": {
"banner": 6,
"essay": 25
},
"sdk/go/sdk.go": {
"banner": 24,
"essay": 27,
"file-size": 391
"file-size": 367
},
"sdk/go/types_ext.go": {
"banner": 8,
"essay": 7
},
"sdk/go/wire.go": {