Skip to content

Commit 053cd3a

Browse files
committed
Add SwiftLint
1 parent cb86522 commit 053cd3a

8 files changed

Lines changed: 77 additions & 38 deletions

File tree

.swiftlint.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
opt_in_rules:
2+
# Performance
3+
- first_where
4+
- last_where
5+
- sorted_first_last
6+
- contains_over_filter_count
7+
- empty_count
8+
9+
# Modern Swift style
10+
- shorthand_optional_binding
11+
- implicit_return
12+
- toggle_bool
13+
14+
# Safety
15+
- fatal_error_message
16+
17+
# Code cleanliness
18+
- modifier_order
19+
- redundant_type_annotation
20+
- convenience_type
21+
22+
# Formatting
23+
- indentation_width
24+
25+
excluded:
26+
- .build
27+
- .swiftpm
28+
29+
indentation_width:
30+
indentation_width: 2
31+
32+
identifier_name:
33+
min_length:
34+
warning: 2
35+
excluded:
36+
- i
37+
- id
38+
- x
39+
- y

Package.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ let package = Package(
88
platforms: [.macOS(.v10_15)],
99
products: [
1010
.executable(name: "claude", targets: ["cli"]),
11-
.library(name: "Core", targets: ["Core"]),
11+
.library(name: "Core", targets: ["Core"])
1212
],
1313
dependencies: [
1414
.package(url: "https://github.com/swift-server/async-http-client.git", from: "1.32.0")
@@ -30,6 +30,6 @@ let package = Package(
3030
name: "CoreTests",
3131
dependencies: ["Core"],
3232
path: "Tests/CoreTests"
33-
),
33+
)
3434
]
3535
)

Sources/Core/Agent.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,10 @@ extension Agent {
103103
"properties": .object([
104104
"command": .object([
105105
"type": "string",
106-
"description": "The shell command to execute",
106+
"description": "The shell command to execute"
107107
])
108108
]),
109-
"required": .array(["command"]),
109+
"required": .array(["command"])
110110
])
111111
)
112112

Sources/Core/ShellExecutor.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public struct ShellResult: Sendable {
2626

2727
public struct ShellExecutor: Sendable {
2828
private static let dangerousPatterns = [
29-
"rm -rf /", "sudo", "shutdown", "reboot", "> /dev/",
29+
"rm -rf /", "sudo", "shutdown", "reboot", "> /dev/"
3030
]
3131

3232
public let workingDirectory: String

Sources/cli/SwiftClaudeCode.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import Core
22
import Foundation
33

44
@main
5-
struct SwiftClaudeCode {
5+
enum SwiftClaudeCode {
66
static func main() async throws {
77
print("\(ANSIColor.bold)swift-claude-code\(ANSIColor.reset) v\(Agent.version)")
88
print("\(ANSIColor.dim)A Claude Code-like agent built from scratch in Swift\(ANSIColor.reset)")

Tests/CoreTests/APIModelsTests.swift

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ struct ContentBlockTests {
1616
@Test func decodesToolUse() throws {
1717
let json = """
1818
{
19-
"type": "tool_use",
20-
"id": "toolu_123",
21-
"name": "bash",
22-
"input": {"command": "ls"}
19+
"type": "tool_use",
20+
"id": "toolu_123",
21+
"name": "bash",
22+
"input": {"command": "ls"}
2323
}
2424
"""
2525
let block = try JSONDecoder().decode(ContentBlock.self, from: Data(json.utf8))
@@ -36,10 +36,10 @@ struct ContentBlockTests {
3636
@Test func decodesToolResult() throws {
3737
let json = """
3838
{
39-
"type": "tool_result",
40-
"tool_use_id": "toolu_789",
41-
"content": "output text",
42-
"is_error": true
39+
"type": "tool_result",
40+
"tool_use_id": "toolu_789",
41+
"content": "output text",
42+
"is_error": true
4343
}
4444
"""
4545
let block = try JSONDecoder().decode(ContentBlock.self, from: Data(json.utf8))
@@ -64,15 +64,15 @@ struct ContentBlockTests {
6464
let blocks: [ContentBlock] = [
6565
.text("Hello"),
6666
.toolUse(id: "t1", name: "bash", input: .object(["command": "ls"])),
67-
.text("World"),
67+
.text("World")
6868
]
6969
#expect(blocks.textContent == "Hello\nWorld")
7070
}
7171

7272
@Test func textContentEmptyWhenNoTextBlocks() {
7373
let blocks: [ContentBlock] = [
7474
.toolUse(id: "t1", name: "bash", input: .object(["command": "ls"])),
75-
.toolResult(toolUseId: "t1", content: "output", isError: false),
75+
.toolResult(toolUseId: "t1", content: "output", isError: false)
7676
]
7777
#expect(blocks.textContent == "")
7878
}
@@ -93,7 +93,7 @@ struct MessageTests {
9393
role: .assistant,
9494
content: [
9595
.text("Let me run that."),
96-
.toolUse(id: "toolu_abc", name: "bash", input: .object(["command": "pwd"])),
96+
.toolUse(id: "toolu_abc", name: "bash", input: .object(["command": "pwd"]))
9797
]
9898
)
9999

@@ -113,7 +113,7 @@ struct StopReasonTests {
113113
arguments: [
114114
(#""end_turn""#, StopReason.endTurn),
115115
(#""tool_use""#, StopReason.toolUse),
116-
(#""max_tokens""#, StopReason.maxTokens),
116+
(#""max_tokens""#, StopReason.maxTokens)
117117
]
118118
)
119119
func decodes(json: String, expected: StopReason) throws {
@@ -141,7 +141,7 @@ struct APIRequestTests {
141141
"properties": .object([
142142
"command": .object(["type": "string"])
143143
]),
144-
"required": .array(["command"]),
144+
"required": .array(["command"])
145145
])
146146
)
147147
]
@@ -162,17 +162,17 @@ struct APIResponseTests {
162162
@Test func decodes() throws {
163163
let json = """
164164
{
165-
"id": "msg_abc123",
166-
"type": "message",
167-
"role": "assistant",
168-
"content": [
169-
{"type": "text", "text": "Here are the files."}
170-
],
171-
"stop_reason": "end_turn",
172-
"usage": {
173-
"input_tokens": 100,
174-
"output_tokens": 50
175-
}
165+
"id": "msg_abc123",
166+
"type": "message",
167+
"role": "assistant",
168+
"content": [
169+
{"type": "text", "text": "Here are the files."}
170+
],
171+
"stop_reason": "end_turn",
172+
"usage": {
173+
"input_tokens": 100,
174+
"output_tokens": 50
175+
}
176176
}
177177
"""
178178
let response = try JSONDecoder().decode(APIResponse.self, from: Data(json.utf8))
@@ -190,11 +190,11 @@ struct APIErrorTests {
190190
@Test func decodesErrorResponse() throws {
191191
let json = """
192192
{
193-
"type": "error",
194-
"error": {
195-
"type": "invalid_request_error",
196-
"message": "max_tokens must be positive"
197-
}
193+
"type": "error",
194+
"error": {
195+
"type": "invalid_request_error",
196+
"message": "max_tokens must be positive"
197+
}
198198
}
199199
"""
200200
let response = try JSONDecoder().decode(APIErrorResponse.self, from: Data(json.utf8))

Tests/CoreTests/AgentTests.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,12 +104,12 @@ struct AgentLoopTests {
104104
makeResponse(
105105
content: [
106106
.text("Let me check."),
107-
.toolUse(id: "t1", name: "bash", input: .object(["command": "echo hi"])),
107+
.toolUse(id: "t1", name: "bash", input: .object(["command": "echo hi"]))
108108
],
109109
stopReason: .toolUse
110110
),
111111
// Second response: final answer after seeing tool result
112-
makeResponse(content: [.text("done")]),
112+
makeResponse(content: [.text("done")])
113113
]
114114
let (agent, _) = makeAgent(mock: mock)
115115

Tests/CoreTests/JSONValueTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ struct JSONValueTests {
2525
"verbose": .bool(true),
2626
"count": .int(3),
2727
"ratio": .double(1.5),
28-
"nothing": .null,
28+
"nothing": .null
2929
])
3030
let data = try JSONEncoder().encode(original)
3131
let decoded = try JSONDecoder().decode(JSONValue.self, from: data)

0 commit comments

Comments
 (0)