From 9079016789d0d4d8382f906f7d0ac5c89438fbdd Mon Sep 17 00:00:00 2001 From: Philip Niedertscheider Date: Fri, 11 Sep 2026 16:37:14 +0200 Subject: [PATCH] feat(cli): Add --agent as a JSON output alias --- .gitignore | 1 + .../TechnologiesListCommand.swift | 5 +- Sources/CLI/cmd/types/TypesListCommand.swift | 5 +- .../CLI/cmd/types/TypesSearchCommand.swift | 5 +- Sources/CLI/cmd/types/TypesViewCommand.swift | 5 +- Sources/CLI/skills/BundledAgentSkills.swift | 5 +- .../AppleDocsCommandIntegrationTests.swift | 24 ++++----- .../cmd/types/TypesViewCommandTests.swift | 54 +++++++++++-------- Tests/CLITests/main/CLITests.swift | 10 ++-- 9 files changed, 73 insertions(+), 41 deletions(-) diff --git a/.gitignore b/.gitignore index db7c43e..a745201 100644 --- a/.gitignore +++ b/.gitignore @@ -137,3 +137,4 @@ xcuserdata/ # --- Project --- .swiftpm dist/ +tmp/ diff --git a/Sources/CLI/cmd/technologies/TechnologiesListCommand.swift b/Sources/CLI/cmd/technologies/TechnologiesListCommand.swift index aad6ffb..737f7d3 100644 --- a/Sources/CLI/cmd/technologies/TechnologiesListCommand.swift +++ b/Sources/CLI/cmd/technologies/TechnologiesListCommand.swift @@ -15,7 +15,10 @@ struct TechnologiesListCommand: AsyncParsableCommand { abstract: "List Apple documentation technologies." ) - @Flag(help: "Output a JSON array of technologies.") + @Flag( + name: [.long, .customLong("agent")], + help: "Output a JSON array of technologies. --agent currently aliases --json." + ) var json = false mutating func run() async throws { diff --git a/Sources/CLI/cmd/types/TypesListCommand.swift b/Sources/CLI/cmd/types/TypesListCommand.swift index 1110729..089eb12 100644 --- a/Sources/CLI/cmd/types/TypesListCommand.swift +++ b/Sources/CLI/cmd/types/TypesListCommand.swift @@ -18,7 +18,10 @@ struct TypesListCommand: AsyncParsableCommand { @Option(help: "The framework or technology whose types to list.") var technology: String - @Flag(help: "Output a JSON array of types.") + @Flag( + name: [.long, .customLong("agent")], + help: "Output a JSON array of types. --agent currently aliases --json." + ) var json = false mutating func run() async throws { diff --git a/Sources/CLI/cmd/types/TypesSearchCommand.swift b/Sources/CLI/cmd/types/TypesSearchCommand.swift index 56a95d6..1100652 100644 --- a/Sources/CLI/cmd/types/TypesSearchCommand.swift +++ b/Sources/CLI/cmd/types/TypesSearchCommand.swift @@ -21,7 +21,10 @@ struct TypesSearchCommand: AsyncParsableCommand { @Option(help: "The framework or technology whose types to search.") var technology: String - @Flag(help: "Output a JSON array of matching types.") + @Flag( + name: [.long, .customLong("agent")], + help: "Output a JSON array of matching types. --agent currently aliases --json." + ) var json = false mutating func run() async throws { diff --git a/Sources/CLI/cmd/types/TypesViewCommand.swift b/Sources/CLI/cmd/types/TypesViewCommand.swift index 86eb30c..427abfc 100644 --- a/Sources/CLI/cmd/types/TypesViewCommand.swift +++ b/Sources/CLI/cmd/types/TypesViewCommand.swift @@ -21,7 +21,10 @@ struct TypesViewCommand: AsyncParsableCommand { @Option(help: "The framework or technology containing the type.") var technology: String - @Flag(help: "Output the raw Apple DocC JSON document.") + @Flag( + name: [.long, .customLong("agent")], + help: "Output the raw Apple DocC JSON document. --agent currently aliases --json." + ) var json = false mutating func run() async throws { diff --git a/Sources/CLI/skills/BundledAgentSkills.swift b/Sources/CLI/skills/BundledAgentSkills.swift index e6765d3..2e71245 100644 --- a/Sources/CLI/skills/BundledAgentSkills.swift +++ b/Sources/CLI/skills/BundledAgentSkills.swift @@ -81,8 +81,11 @@ enum BundledAgentSkills { ## Structured evidence + On JSON-capable commands, `--agent` currently aliases `--json`. It is not a global flag or auto-detected. + Agent output may evolve. Keep `types view --json` for raw upstream bytes. + ```bash - apple-docs technologies list --json + apple-docs technologies list --agent apple-docs types search URLSession --technology Foundation --json apple-docs types view URLSession --technology Foundation --json ``` diff --git a/Tests/CLIIntegrationTests/AppleDocsCommandIntegrationTests.swift b/Tests/CLIIntegrationTests/AppleDocsCommandIntegrationTests.swift index 128551d..5745ff6 100644 --- a/Tests/CLIIntegrationTests/AppleDocsCommandIntegrationTests.swift +++ b/Tests/CLIIntegrationTests/AppleDocsCommandIntegrationTests.swift @@ -10,10 +10,10 @@ private let integrationTestsEnabled = .serialized ) struct AppleDocsCommandIntegrationTests { - @Test("returns Swift String documentation as JSON") - func returnsSwiftStringJSON() throws { + @Test("returns Swift String documentation as JSON", arguments: ["--json", "--agent"]) + func returnsSwiftStringJSON(flag: String) throws { // -- Arrange -- - let arguments = ["types", "view", "String", "--technology", "Swift", "--json"] + let arguments = ["types", "view", "String", "--technology", "Swift", flag] // -- Act -- let output = try runAppleDocs(arguments) @@ -55,10 +55,10 @@ struct AppleDocsCommandIntegrationTests { #expect(output.contains("Overview\n────────")) } - @Test("lists MetricKit root types as JSON") - func listsMetricKitTypes() throws { + @Test("lists MetricKit root types as JSON", arguments: ["--json", "--agent"]) + func listsMetricKitTypes(flag: String) throws { // -- Arrange -- - let arguments = ["types", "list", "--technology", "MetricKit", "--json"] + let arguments = ["types", "list", "--technology", "MetricKit", flag] // -- Act -- let output = try runAppleDocs(arguments) @@ -77,13 +77,13 @@ struct AppleDocsCommandIntegrationTests { ) } - @Test("searches SwiftUI collection groups as JSON") - func searchesSwiftUITypes() throws { + @Test("searches SwiftUI collection groups as JSON", arguments: ["--json", "--agent"]) + func searchesSwiftUITypes(flag: String) throws { // -- Arrange -- let arguments = [ "types", "search", "Button", "--technology", "SwiftUI", - "--json", + flag, ] // -- Act -- @@ -120,10 +120,10 @@ struct AppleDocsCommandIntegrationTests { #expect(document.metadata.title == "URLSession.AsyncBytes") } - @Test("lists stable technologies as JSON") - func listsStableTechnologies() throws { + @Test("lists stable technologies as JSON", arguments: ["--json", "--agent"]) + func listsStableTechnologies(flag: String) throws { // -- Arrange -- - let arguments = ["technologies", "list", "--json"] + let arguments = ["technologies", "list", flag] // -- Act -- let output = try runAppleDocs(arguments) diff --git a/Tests/CLITests/cmd/types/TypesViewCommandTests.swift b/Tests/CLITests/cmd/types/TypesViewCommandTests.swift index e6e6a48..f47cda7 100644 --- a/Tests/CLITests/cmd/types/TypesViewCommandTests.swift +++ b/Tests/CLITests/cmd/types/TypesViewCommandTests.swift @@ -4,14 +4,18 @@ import Testing @Suite("Types command parsing") struct TypesViewCommandTests { - @Test("accepts the types list command with a required technology") - func parsesTypesList() throws { + @Test( + "accepts JSON and agent output for types list", + arguments: [ + ["--json"], ["--agent"], ["--json", "--agent"], ["--agent", "--json"], + ]) + func parsesTypesList(flags: [String]) throws { // -- Arrange -- - let arguments = [ - "types", "list", - "--technology", "MetricKit", - "--json", - ] + let arguments = + [ + "types", "list", + "--technology", "MetricKit", + ] + flags // -- Act -- let command = try CLI.parseAsRoot(arguments) @@ -22,14 +26,18 @@ struct TypesViewCommandTests { #expect(listCommand.json) } - @Test("accepts the types search command with a query and required technology") - func parsesTypesSearch() throws { + @Test( + "accepts JSON and agent output for types search", + arguments: [ + ["--json"], ["--agent"], ["--json", "--agent"], ["--agent", "--json"], + ]) + func parsesTypesSearch(flags: [String]) throws { // -- Arrange -- - let arguments = [ - "types", "search", "Button", - "--technology", "SwiftUI", - "--json", - ] + let arguments = + [ + "types", "search", "Button", + "--technology", "SwiftUI", + ] + flags // -- Act -- let command = try CLI.parseAsRoot(arguments) @@ -59,14 +67,18 @@ struct TypesViewCommandTests { #expect(viewCommand.json == false) } - @Test("accepts raw JSON output") - func parsesJSONFlag() throws { + @Test( + "accepts JSON and agent output for types view", + arguments: [ + ["--json"], ["--agent"], ["--json", "--agent"], ["--agent", "--json"], + ]) + func parsesJSONFlag(flags: [String]) throws { // -- Arrange -- - let arguments = [ - "types", "view", "MXHangDiagnostic", - "--technology", "MetricKit", - "--json", - ] + let arguments = + [ + "types", "view", "MXHangDiagnostic", + "--technology", "MetricKit", + ] + flags // -- Act -- let command = try CLI.parseAsRoot(arguments) diff --git a/Tests/CLITests/main/CLITests.swift b/Tests/CLITests/main/CLITests.swift index f6990b6..0e040d8 100644 --- a/Tests/CLITests/main/CLITests.swift +++ b/Tests/CLITests/main/CLITests.swift @@ -25,10 +25,14 @@ struct CLITests { #expect(command is TechnologiesListCommand) } - @Test("accepts JSON output for the technologies list") - func acceptsTechnologiesListJSONOutput() throws { + @Test( + "accepts JSON and agent output for technologies list", + arguments: [ + ["--json"], ["--agent"], ["--json", "--agent"], ["--agent", "--json"], + ]) + func acceptsTechnologiesListJSONOutput(flags: [String]) throws { // -- Arrange -- - let arguments = ["technologies", "list", "--json"] + let arguments = ["technologies", "list"] + flags // -- Act -- let command = try CLI.parseAsRoot(arguments)