Canvas: simplify show + report status
This commit is contained in:
@@ -18,13 +18,38 @@ final class CanvasManager {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
func show(sessionKey: String, path: String? = nil, placement: CanvasPlacement? = nil) throws -> String {
|
func show(sessionKey: String, path: String? = nil, placement: CanvasPlacement? = nil) throws -> String {
|
||||||
|
try self.showDetailed(sessionKey: sessionKey, target: path, placement: placement).directory
|
||||||
|
}
|
||||||
|
|
||||||
|
func showDetailed(sessionKey: String, target: String? = nil, placement: CanvasPlacement? = nil) throws -> CanvasShowResult {
|
||||||
let anchorProvider = self.defaultAnchorProvider ?? Self.mouseAnchorProvider
|
let anchorProvider = self.defaultAnchorProvider ?? Self.mouseAnchorProvider
|
||||||
let session = sessionKey.trimmingCharacters(in: .whitespacesAndNewlines)
|
let session = sessionKey.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
let normalizedTarget = target?
|
||||||
|
.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
.nonEmpty
|
||||||
|
|
||||||
|
let isWebTarget = Self.isWebTarget(normalizedTarget)
|
||||||
|
|
||||||
if let controller = self.panelController, self.panelSessionKey == session {
|
if let controller = self.panelController, self.panelSessionKey == session {
|
||||||
controller.presentAnchoredPanel(anchorProvider: anchorProvider)
|
controller.presentAnchoredPanel(anchorProvider: anchorProvider)
|
||||||
controller.applyPreferredPlacement(placement)
|
controller.applyPreferredPlacement(placement)
|
||||||
controller.goto(path: path ?? "/")
|
|
||||||
return controller.directoryPath
|
// Existing session: only navigate when an explicit target was provided.
|
||||||
|
if let normalizedTarget {
|
||||||
|
controller.goto(path: normalizedTarget)
|
||||||
|
return self.makeShowResult(
|
||||||
|
directory: controller.directoryPath,
|
||||||
|
target: target,
|
||||||
|
effectiveTarget: normalizedTarget,
|
||||||
|
isWebTarget: isWebTarget)
|
||||||
|
}
|
||||||
|
|
||||||
|
return CanvasShowResult(
|
||||||
|
directory: controller.directoryPath,
|
||||||
|
target: target,
|
||||||
|
effectiveTarget: nil,
|
||||||
|
status: .shown,
|
||||||
|
url: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.panelController?.close()
|
self.panelController?.close()
|
||||||
@@ -39,8 +64,16 @@ final class CanvasManager {
|
|||||||
self.panelController = controller
|
self.panelController = controller
|
||||||
self.panelSessionKey = session
|
self.panelSessionKey = session
|
||||||
controller.applyPreferredPlacement(placement)
|
controller.applyPreferredPlacement(placement)
|
||||||
controller.showCanvas(path: path ?? "/")
|
|
||||||
return controller.directoryPath
|
// New session: default to "/" so the user sees either the welcome page or `index.html`.
|
||||||
|
let effectiveTarget = normalizedTarget ?? "/"
|
||||||
|
controller.showCanvas(path: effectiveTarget)
|
||||||
|
|
||||||
|
return self.makeShowResult(
|
||||||
|
directory: controller.directoryPath,
|
||||||
|
target: target,
|
||||||
|
effectiveTarget: effectiveTarget,
|
||||||
|
isWebTarget: isWebTarget)
|
||||||
}
|
}
|
||||||
|
|
||||||
func hide(sessionKey: String) {
|
func hide(sessionKey: String) {
|
||||||
@@ -53,10 +86,6 @@ final class CanvasManager {
|
|||||||
self.panelController?.hideCanvas()
|
self.panelController?.hideCanvas()
|
||||||
}
|
}
|
||||||
|
|
||||||
func goto(sessionKey: String, path: String, placement: CanvasPlacement? = nil) throws {
|
|
||||||
_ = try self.show(sessionKey: sessionKey, path: path, placement: placement)
|
|
||||||
}
|
|
||||||
|
|
||||||
func eval(sessionKey: String, javaScript: String) async throws -> String {
|
func eval(sessionKey: String, javaScript: String) async throws -> String {
|
||||||
_ = try self.show(sessionKey: sessionKey, path: nil)
|
_ = try self.show(sessionKey: sessionKey, path: nil)
|
||||||
guard let controller = self.panelController else { return "" }
|
guard let controller = self.panelController else { return "" }
|
||||||
@@ -79,4 +108,89 @@ final class CanvasManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// placement interpretation is handled by the window controller.
|
// placement interpretation is handled by the window controller.
|
||||||
|
|
||||||
|
// MARK: - Helpers
|
||||||
|
|
||||||
|
private static func isWebTarget(_ target: String?) -> Bool {
|
||||||
|
guard let target, let url = URL(string: target), let scheme = url.scheme?.lowercased() else { return false }
|
||||||
|
return scheme == "https" || scheme == "http"
|
||||||
|
}
|
||||||
|
|
||||||
|
private func makeShowResult(
|
||||||
|
directory: String,
|
||||||
|
target: String?,
|
||||||
|
effectiveTarget: String,
|
||||||
|
isWebTarget: Bool) -> CanvasShowResult
|
||||||
|
{
|
||||||
|
if isWebTarget, let url = URL(string: effectiveTarget) {
|
||||||
|
return CanvasShowResult(
|
||||||
|
directory: directory,
|
||||||
|
target: target,
|
||||||
|
effectiveTarget: effectiveTarget,
|
||||||
|
status: .web,
|
||||||
|
url: url.absoluteString)
|
||||||
|
}
|
||||||
|
|
||||||
|
let sessionDir = URL(fileURLWithPath: directory)
|
||||||
|
let status = Self.localStatus(sessionDir: sessionDir, target: effectiveTarget)
|
||||||
|
let host = sessionDir.lastPathComponent
|
||||||
|
let canvasURL = CanvasScheme.makeURL(session: host, path: effectiveTarget)?.absoluteString
|
||||||
|
return CanvasShowResult(
|
||||||
|
directory: directory,
|
||||||
|
target: target,
|
||||||
|
effectiveTarget: effectiveTarget,
|
||||||
|
status: status,
|
||||||
|
url: canvasURL)
|
||||||
|
}
|
||||||
|
|
||||||
|
private static func localStatus(sessionDir: URL, target: String) -> CanvasShowStatus {
|
||||||
|
let fm = FileManager.default
|
||||||
|
let trimmed = target.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
let withoutQuery = trimmed.split(separator: "?", maxSplits: 1, omittingEmptySubsequences: false).first.map(String.init) ?? trimmed
|
||||||
|
var path = withoutQuery
|
||||||
|
if path.hasPrefix("/") { path.removeFirst() }
|
||||||
|
path = path.removingPercentEncoding ?? path
|
||||||
|
|
||||||
|
// Root special-case: welcome page when no index exists.
|
||||||
|
if path.isEmpty {
|
||||||
|
let a = sessionDir.appendingPathComponent("index.html", isDirectory: false)
|
||||||
|
let b = sessionDir.appendingPathComponent("index.htm", isDirectory: false)
|
||||||
|
if fm.fileExists(atPath: a.path) || fm.fileExists(atPath: b.path) { return .ok }
|
||||||
|
return .welcome
|
||||||
|
}
|
||||||
|
|
||||||
|
// Direct file or directory.
|
||||||
|
var candidate = sessionDir.appendingPathComponent(path, isDirectory: false)
|
||||||
|
var isDir: ObjCBool = false
|
||||||
|
if fm.fileExists(atPath: candidate.path, isDirectory: &isDir) {
|
||||||
|
if isDir.boolValue {
|
||||||
|
return Self.indexExists(in: candidate) ? .ok : .notFound
|
||||||
|
}
|
||||||
|
return .ok
|
||||||
|
}
|
||||||
|
|
||||||
|
// Directory index behavior ("/yolo" -> "yolo/index.html") if directory exists.
|
||||||
|
if !path.isEmpty, !path.hasSuffix("/") {
|
||||||
|
candidate = sessionDir.appendingPathComponent(path, isDirectory: true)
|
||||||
|
if fm.fileExists(atPath: candidate.path, isDirectory: &isDir), isDir.boolValue {
|
||||||
|
return Self.indexExists(in: candidate) ? .ok : .notFound
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return .notFound
|
||||||
|
}
|
||||||
|
|
||||||
|
private static func indexExists(in dir: URL) -> Bool {
|
||||||
|
let fm = FileManager.default
|
||||||
|
let a = dir.appendingPathComponent("index.html", isDirectory: false)
|
||||||
|
if fm.fileExists(atPath: a.path) { return true }
|
||||||
|
let b = dir.appendingPathComponent("index.htm", isDirectory: false)
|
||||||
|
return fm.fileExists(atPath: b.path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension String {
|
||||||
|
var nonEmpty: String? {
|
||||||
|
isEmpty ? nil : self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,8 +101,6 @@ final class CanvasWindowController: NSWindowController, WKNavigationDelegate, NS
|
|||||||
self.presentAnchoredPanel(anchorProvider: anchorProvider)
|
self.presentAnchoredPanel(anchorProvider: anchorProvider)
|
||||||
if let path {
|
if let path {
|
||||||
self.goto(path: path)
|
self.goto(path: path)
|
||||||
} else {
|
|
||||||
self.goto(path: "/")
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -112,8 +110,6 @@ final class CanvasWindowController: NSWindowController, WKNavigationDelegate, NS
|
|||||||
NSApp.activate(ignoringOtherApps: true)
|
NSApp.activate(ignoringOtherApps: true)
|
||||||
if let path {
|
if let path {
|
||||||
self.goto(path: path)
|
self.goto(path: path)
|
||||||
} else {
|
|
||||||
self.goto(path: "/")
|
|
||||||
}
|
}
|
||||||
self.onVisibilityChanged?(true)
|
self.onVisibilityChanged?(true)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,9 +61,6 @@ enum ControlRequestHandler {
|
|||||||
case let .canvasHide(session):
|
case let .canvasHide(session):
|
||||||
return await self.handleCanvasHide(session: session)
|
return await self.handleCanvasHide(session: session)
|
||||||
|
|
||||||
case let .canvasGoto(session, path, placement):
|
|
||||||
return await self.handleCanvasGoto(session: session, path: path, placement: placement)
|
|
||||||
|
|
||||||
case let .canvasEval(session, javaScript):
|
case let .canvasEval(session, javaScript):
|
||||||
return await self.handleCanvasEval(session: session, javaScript: javaScript)
|
return await self.handleCanvasEval(session: session, javaScript: javaScript)
|
||||||
|
|
||||||
@@ -196,10 +193,11 @@ enum ControlRequestHandler {
|
|||||||
{
|
{
|
||||||
guard self.canvasEnabled() else { return Response(ok: false, message: "Canvas disabled by user") }
|
guard self.canvasEnabled() else { return Response(ok: false, message: "Canvas disabled by user") }
|
||||||
do {
|
do {
|
||||||
let dir = try await MainActor.run {
|
let res = try await MainActor.run {
|
||||||
try CanvasManager.shared.show(sessionKey: session, path: path, placement: placement)
|
try CanvasManager.shared.showDetailed(sessionKey: session, target: path, placement: placement)
|
||||||
}
|
}
|
||||||
return Response(ok: true, message: dir)
|
let payload = try? JSONEncoder().encode(res)
|
||||||
|
return Response(ok: true, message: res.directory, payload: payload)
|
||||||
} catch {
|
} catch {
|
||||||
return Response(ok: false, message: error.localizedDescription)
|
return Response(ok: false, message: error.localizedDescription)
|
||||||
}
|
}
|
||||||
@@ -210,18 +208,6 @@ enum ControlRequestHandler {
|
|||||||
return Response(ok: true)
|
return Response(ok: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private static func handleCanvasGoto(session: String, path: String, placement: CanvasPlacement?) async -> Response {
|
|
||||||
guard self.canvasEnabled() else { return Response(ok: false, message: "Canvas disabled by user") }
|
|
||||||
do {
|
|
||||||
try await MainActor.run {
|
|
||||||
try CanvasManager.shared.goto(sessionKey: session, path: path, placement: placement)
|
|
||||||
}
|
|
||||||
return Response(ok: true)
|
|
||||||
} catch {
|
|
||||||
return Response(ok: false, message: error.localizedDescription)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static func handleCanvasEval(session: String, javaScript: String) async -> Response {
|
private static func handleCanvasEval(session: String, javaScript: String) async -> Response {
|
||||||
guard self.canvasEnabled() else { return Response(ok: false, message: "Canvas disabled by user") }
|
guard self.canvasEnabled() else { return Response(ok: false, message: "Canvas disabled by user") }
|
||||||
do {
|
do {
|
||||||
|
|||||||
@@ -830,7 +830,7 @@ extension DebugSettings {
|
|||||||
"""
|
"""
|
||||||
try html.write(to: url, atomically: true, encoding: .utf8)
|
try html.write(to: url, atomically: true, encoding: .utf8)
|
||||||
self.canvasStatus = "wrote: \(url.path)"
|
self.canvasStatus = "wrote: \(url.path)"
|
||||||
try CanvasManager.shared.goto(sessionKey: session.isEmpty ? "main" : session, path: "/")
|
_ = try CanvasManager.shared.show(sessionKey: session.isEmpty ? "main" : session, path: "/")
|
||||||
} catch {
|
} catch {
|
||||||
self.canvasError = error.localizedDescription
|
self.canvasError = error.localizedDescription
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -243,10 +243,10 @@ struct ClawdisCLI {
|
|||||||
switch sub {
|
switch sub {
|
||||||
case "show":
|
case "show":
|
||||||
var session = "main"
|
var session = "main"
|
||||||
var path: String?
|
var target: String?
|
||||||
let placement = self.parseCanvasPlacement(args: &args, session: &session, path: &path)
|
let placement = self.parseCanvasPlacement(args: &args, session: &session, target: &target)
|
||||||
return ParsedCLIRequest(
|
return ParsedCLIRequest(
|
||||||
request: .canvasShow(session: session, path: path, placement: placement),
|
request: .canvasShow(session: session, path: target, placement: placement),
|
||||||
kind: .generic)
|
kind: .generic)
|
||||||
case "hide":
|
case "hide":
|
||||||
var session = "main"
|
var session = "main"
|
||||||
@@ -258,14 +258,6 @@ struct ClawdisCLI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ParsedCLIRequest(request: .canvasHide(session: session), kind: .generic)
|
return ParsedCLIRequest(request: .canvasHide(session: session), kind: .generic)
|
||||||
case "goto":
|
|
||||||
var session = "main"
|
|
||||||
var path: String?
|
|
||||||
let placement = self.parseCanvasPlacement(args: &args, session: &session, path: &path)
|
|
||||||
guard let path else { throw CLIError.help }
|
|
||||||
return ParsedCLIRequest(
|
|
||||||
request: .canvasGoto(session: session, path: path, placement: placement),
|
|
||||||
kind: .generic)
|
|
||||||
case "eval":
|
case "eval":
|
||||||
var session = "main"
|
var session = "main"
|
||||||
var js: String?
|
var js: String?
|
||||||
@@ -359,7 +351,7 @@ struct ClawdisCLI {
|
|||||||
private static func parseCanvasPlacement(
|
private static func parseCanvasPlacement(
|
||||||
args: inout [String],
|
args: inout [String],
|
||||||
session: inout String,
|
session: inout String,
|
||||||
path: inout String?) -> CanvasPlacement?
|
target: inout String?) -> CanvasPlacement?
|
||||||
{
|
{
|
||||||
var x: Double?
|
var x: Double?
|
||||||
var y: Double?
|
var y: Double?
|
||||||
@@ -369,7 +361,7 @@ struct ClawdisCLI {
|
|||||||
let arg = args.removeFirst()
|
let arg = args.removeFirst()
|
||||||
switch arg {
|
switch arg {
|
||||||
case "--session": session = args.popFirst() ?? session
|
case "--session": session = args.popFirst() ?? session
|
||||||
case "--path": path = args.popFirst()
|
case "--target", "--path": target = args.popFirst()
|
||||||
case "--x": x = args.popFirst().flatMap(Double.init)
|
case "--x": x = args.popFirst().flatMap(Double.init)
|
||||||
case "--y": y = args.popFirst().flatMap(Double.init)
|
case "--y": y = args.popFirst().flatMap(Double.init)
|
||||||
case "--width": width = args.popFirst().flatMap(Double.init)
|
case "--width": width = args.popFirst().flatMap(Double.init)
|
||||||
@@ -388,6 +380,19 @@ struct ClawdisCLI {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if case .canvasShow = parsed.request {
|
||||||
|
if let message = response.message, !message.isEmpty {
|
||||||
|
FileHandle.standardOutput.write(Data((message + "\n").utf8))
|
||||||
|
}
|
||||||
|
if let payload = response.payload, let info = try? JSONDecoder().decode(CanvasShowResult.self, from: payload) {
|
||||||
|
FileHandle.standardOutput.write(Data(("STATUS:\(info.status.rawValue)\n").utf8))
|
||||||
|
if let url = info.url, !url.isEmpty {
|
||||||
|
FileHandle.standardOutput.write(Data(("URL:\(url)\n").utf8))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
switch parsed.kind {
|
switch parsed.kind {
|
||||||
case .generic:
|
case .generic:
|
||||||
if let payload = response.payload, let text = String(data: payload, encoding: .utf8), !text.isEmpty {
|
if let payload = response.payload, let text = String(data: payload, encoding: .utf8), !text.isEmpty {
|
||||||
@@ -468,11 +473,9 @@ struct ClawdisCLI {
|
|||||||
clawdis-mac node invoke --node <id> --command <name> [--params-json <json>]
|
clawdis-mac node invoke --node <id> --command <name> [--params-json <json>]
|
||||||
|
|
||||||
Canvas:
|
Canvas:
|
||||||
clawdis-mac canvas show [--session <key>] [--path </...>]
|
clawdis-mac canvas show [--session <key>] [--target </...|https://...>]
|
||||||
[--x <screenX> --y <screenY>] [--width <w> --height <h>]
|
[--x <screenX> --y <screenY>] [--width <w> --height <h>]
|
||||||
clawdis-mac canvas hide [--session <key>]
|
clawdis-mac canvas hide [--session <key>]
|
||||||
clawdis-mac canvas goto --path </...> [--session <key>]
|
|
||||||
[--x <screenX> --y <screenY>] [--width <w> --height <h>]
|
|
||||||
clawdis-mac canvas eval --js <code> [--session <key>]
|
clawdis-mac canvas eval --js <code> [--session <key>]
|
||||||
clawdis-mac canvas snapshot [--out <path>] [--session <key>]
|
clawdis-mac canvas snapshot [--out <path>] [--session <key>]
|
||||||
|
|
||||||
|
|||||||
@@ -55,6 +55,47 @@ public struct CanvasPlacement: Codable, Sendable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Canvas show result
|
||||||
|
|
||||||
|
public enum CanvasShowStatus: String, Codable, Sendable {
|
||||||
|
/// Panel was shown, but no navigation occurred (no target passed and session already existed).
|
||||||
|
case shown
|
||||||
|
/// Target was an http(s) URL.
|
||||||
|
case web
|
||||||
|
/// Local canvas target resolved to an existing file.
|
||||||
|
case ok
|
||||||
|
/// Local canvas target did not resolve to a file (404 page).
|
||||||
|
case notFound
|
||||||
|
/// Local canvas root ("/") has no index, so the welcome page is shown.
|
||||||
|
case welcome
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct CanvasShowResult: Codable, Sendable {
|
||||||
|
/// Session directory on disk (e.g. `~/Library/Application Support/Clawdis/canvas/<session>/`).
|
||||||
|
public var directory: String
|
||||||
|
/// Target as provided by the caller (may be nil/empty).
|
||||||
|
public var target: String?
|
||||||
|
/// Target actually navigated to (nil when no navigation occurred; defaults to "/" for a newly created session).
|
||||||
|
public var effectiveTarget: String?
|
||||||
|
public var status: CanvasShowStatus
|
||||||
|
/// URL that was loaded (nil when no navigation occurred).
|
||||||
|
public var url: String?
|
||||||
|
|
||||||
|
public init(
|
||||||
|
directory: String,
|
||||||
|
target: String?,
|
||||||
|
effectiveTarget: String?,
|
||||||
|
status: CanvasShowStatus,
|
||||||
|
url: String?)
|
||||||
|
{
|
||||||
|
self.directory = directory
|
||||||
|
self.target = target
|
||||||
|
self.effectiveTarget = effectiveTarget
|
||||||
|
self.status = status
|
||||||
|
self.url = url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public enum Request: Sendable {
|
public enum Request: Sendable {
|
||||||
case notify(
|
case notify(
|
||||||
title: String,
|
title: String,
|
||||||
@@ -74,7 +115,6 @@ public enum Request: Sendable {
|
|||||||
case rpcStatus
|
case rpcStatus
|
||||||
case canvasShow(session: String, path: String?, placement: CanvasPlacement?)
|
case canvasShow(session: String, path: String?, placement: CanvasPlacement?)
|
||||||
case canvasHide(session: String)
|
case canvasHide(session: String)
|
||||||
case canvasGoto(session: String, path: String, placement: CanvasPlacement?)
|
|
||||||
case canvasEval(session: String, javaScript: String)
|
case canvasEval(session: String, javaScript: String)
|
||||||
case canvasSnapshot(session: String, outPath: String?)
|
case canvasSnapshot(session: String, outPath: String?)
|
||||||
case nodeList
|
case nodeList
|
||||||
@@ -131,7 +171,6 @@ extension Request: Codable {
|
|||||||
case rpcStatus
|
case rpcStatus
|
||||||
case canvasShow
|
case canvasShow
|
||||||
case canvasHide
|
case canvasHide
|
||||||
case canvasGoto
|
|
||||||
case canvasEval
|
case canvasEval
|
||||||
case canvasSnapshot
|
case canvasSnapshot
|
||||||
case nodeList
|
case nodeList
|
||||||
@@ -188,12 +227,6 @@ extension Request: Codable {
|
|||||||
try container.encode(Kind.canvasHide, forKey: .type)
|
try container.encode(Kind.canvasHide, forKey: .type)
|
||||||
try container.encode(session, forKey: .session)
|
try container.encode(session, forKey: .session)
|
||||||
|
|
||||||
case let .canvasGoto(session, path, placement):
|
|
||||||
try container.encode(Kind.canvasGoto, forKey: .type)
|
|
||||||
try container.encode(session, forKey: .session)
|
|
||||||
try container.encode(path, forKey: .path)
|
|
||||||
try container.encodeIfPresent(placement, forKey: .placement)
|
|
||||||
|
|
||||||
case let .canvasEval(session, javaScript):
|
case let .canvasEval(session, javaScript):
|
||||||
try container.encode(Kind.canvasEval, forKey: .type)
|
try container.encode(Kind.canvasEval, forKey: .type)
|
||||||
try container.encode(session, forKey: .session)
|
try container.encode(session, forKey: .session)
|
||||||
@@ -278,12 +311,6 @@ extension Request: Codable {
|
|||||||
let session = try container.decode(String.self, forKey: .session)
|
let session = try container.decode(String.self, forKey: .session)
|
||||||
self = .canvasHide(session: session)
|
self = .canvasHide(session: session)
|
||||||
|
|
||||||
case .canvasGoto:
|
|
||||||
let session = try container.decode(String.self, forKey: .session)
|
|
||||||
let path = try container.decode(String.self, forKey: .path)
|
|
||||||
let placement = try container.decodeIfPresent(CanvasPlacement.self, forKey: .placement)
|
|
||||||
self = .canvasGoto(session: session, path: path, placement: placement)
|
|
||||||
|
|
||||||
case .canvasEval:
|
case .canvasEval:
|
||||||
let session = try container.decode(String.self, forKey: .session)
|
let session = try container.decode(String.self, forKey: .session)
|
||||||
let javaScript = try container.decode(String.self, forKey: .javaScript)
|
let javaScript = try container.decode(String.self, forKey: .javaScript)
|
||||||
|
|||||||
@@ -146,14 +146,6 @@ struct ControlRequestHandlerTests {
|
|||||||
#expect(show.ok == false)
|
#expect(show.ok == false)
|
||||||
#expect(show.message == "Canvas disabled by user")
|
#expect(show.message == "Canvas disabled by user")
|
||||||
|
|
||||||
let goto = try await Self.withDefaultOverride(pauseDefaultsKey, value: false) {
|
|
||||||
try await Self.withDefaultOverride(canvasEnabledKey, value: false) {
|
|
||||||
try await ControlRequestHandler.process(request: .canvasGoto(session: "s", path: "/tmp", placement: nil))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#expect(goto.ok == false)
|
|
||||||
#expect(goto.message == "Canvas disabled by user")
|
|
||||||
|
|
||||||
let eval = try await Self.withDefaultOverride(pauseDefaultsKey, value: false) {
|
let eval = try await Self.withDefaultOverride(pauseDefaultsKey, value: false) {
|
||||||
try await Self.withDefaultOverride(canvasEnabledKey, value: false) {
|
try await Self.withDefaultOverride(canvasEnabledKey, value: false) {
|
||||||
try await ControlRequestHandler.process(request: .canvasEval(session: "s", javaScript: "1+1"))
|
try await ControlRequestHandler.process(request: .canvasEval(session: "s", javaScript: "1+1"))
|
||||||
|
|||||||
Reference in New Issue
Block a user