From bd308246450751e3ef3925075864ab74219064c5 Mon Sep 17 00:00:00 2001 From: Andrew Charneski Date: Fri, 12 Jul 2024 16:10:15 -0400 Subject: [PATCH] wip --- .../diff/AddApplyFileDiffLinks.kt | 30 +++++--- .../com/simiacryptus/diff/AddSaveLinks.kt | 73 ++++++++----------- .../diff/AddShellExecutionLinks.kt | 49 +++++++++++++ 3 files changed, 100 insertions(+), 52 deletions(-) create mode 100644 webui/src/main/kotlin/com/simiacryptus/diff/AddShellExecutionLinks.kt diff --git a/webui/src/main/kotlin/com/simiacryptus/diff/AddApplyFileDiffLinks.kt b/webui/src/main/kotlin/com/simiacryptus/diff/AddApplyFileDiffLinks.kt index 973432c4..4749db57 100644 --- a/webui/src/main/kotlin/com/simiacryptus/diff/AddApplyFileDiffLinks.kt +++ b/webui/src/main/kotlin/com/simiacryptus/diff/AddApplyFileDiffLinks.kt @@ -25,6 +25,7 @@ fun SocketManagerBase.addApplyFileDiffLinks( handle: (Map) -> Unit = {}, ui: ApplicationInterface, api: API, + shouldAutoApply: (Path) -> Boolean = { false }, ): String { // Check if there's an unclosed code block and close it if necessary val initiator = "(?s)```[\\w]*\n".toRegex() @@ -66,7 +67,7 @@ fun SocketManagerBase.addApplyFileDiffLinks( val header = headers.lastOrNull { it.first.endInclusive < diffBlock.first.start } val filename = resolve(root, header?.second ?: "Unknown") val diffVal = diffBlock.second - val newValue = renderDiffBlock(root, filename, diffVal, handle, ui, api) + val newValue = renderDiffBlock(root, filename, diffVal, handle, ui, api, shouldAutoApply) val regex = "(?s)```[^\n]*\n?${Pattern.quote(diffVal)}\n?```".toRegex() markdown.replace(regex, newValue) } @@ -166,6 +167,7 @@ private fun SocketManagerBase.renderDiffBlock( handle: (Map) -> Unit, ui: ApplicationInterface, api: API?, + shouldAutoApply: (Path) -> Boolean, ): String { val filepath = path(root, filename) @@ -178,11 +180,25 @@ private fun SocketManagerBase.renderDiffBlock( val applydiffTask = ui.newTask(false) lateinit var hrefLink: StringBuilder - var originalCode = load(filepath) - var newCode = patch(originalCode, diffVal) + var newCode = patch(prevCode, diffVal) + val echoDiff = try { + IterativePatchUtil.generatePatch(prevCode, newCode.newCode) + } catch (e: Throwable) { + renderMarkdown("```\n${e.stackTraceToString()}\n```", ui = ui) + } val diffTask = ui.newTask(root = false) diffTask?.complete(renderMarkdown("```diff\n$diffVal\n```", ui = ui)) + if (echoDiff.isNotBlank() && newCode.isValid && shouldAutoApply(filepath ?: root.resolve(filename))) { + try { + filepath?.toFile()?.writeText(newCode.newCode, Charsets.UTF_8) ?: log.warn("File not found: $filepath") + handle(mapOf(relativize!! to newCode.newCode)) + return """
Diff Automatically Applied
""" + } catch (e: Throwable) { + log.error("Error auto-applying diff", e) + return """
Error Auto-Applying Diff: ${e.message}
""" + } + } // Create tasks for displaying code and patch information val prevCodeTask = ui.newTask(root = false) @@ -224,6 +240,7 @@ private fun SocketManagerBase.renderDiffBlock( lateinit var revert: String + var originalCode = prevCode // For reverting changes // Create "Apply Diff" button var apply1 = hrefLink("Apply Diff", classname = "href-link cmd-button") { try { @@ -239,13 +256,6 @@ private fun SocketManagerBase.renderDiffBlock( } } - // Generate and display various code and patch information - newCode = patch(prevCode, diffVal) - val echoDiff = try { - IterativePatchUtil.generatePatch(prevCode, newCode.newCode) - } catch (e: Throwable) { - renderMarkdown("```\n${e.stackTraceToString()}\n```", ui = ui) - } if (echoDiff.isNotBlank()) { diff --git a/webui/src/main/kotlin/com/simiacryptus/diff/AddSaveLinks.kt b/webui/src/main/kotlin/com/simiacryptus/diff/AddSaveLinks.kt index 8c641e49..a67198db 100644 --- a/webui/src/main/kotlin/com/simiacryptus/diff/AddSaveLinks.kt +++ b/webui/src/main/kotlin/com/simiacryptus/diff/AddSaveLinks.kt @@ -12,6 +12,7 @@ fun SocketManagerBase.addSaveLinks( response: String, task: SessionTask, ui: ApplicationInterface, + shouldAutoApply: (Path) -> Boolean = { false }, ): String { val diffPattern = """(?s)(? filename1.trim() } + val filePath = File(filename).toPath() val codeValue = diffBlock.groupValues[2] - val commandTask = ui.newTask(false) - lateinit var hrefLink: StringBuilder - hrefLink = commandTask.complete(hrefLink("Save File", classname = "href-link cmd-button") { - try { - File(filename).toPath() - root.resolve(File(filename).toPath()).toFile().apply { - parentFile.mkdirs() - writeText(codeValue, Charsets.UTF_8) - } - hrefLink.set("""
Saved ${filename}
""") - commandTask.complete() - } catch (e: Throwable) { - task.error(null, e) + if (shouldAutoApply(root.resolve(filePath))) { + filePath.toFile().apply { + parentFile.mkdirs() + writeText(codeValue, Charsets.UTF_8) } - })!! - markdown.replace( - codeValue + "```", - codeValue + "```\n" + commandTask.placeholder - ) + markdown.replace( + codeValue + "```", + codeValue + "```\n
Auto-applied to ${filename}
" + ) + } else { + val commandTask = ui.newTask(false) + lateinit var hrefLink: StringBuilder + hrefLink = commandTask.complete(hrefLink("Save File", classname = "href-link cmd-button") { + try { + filePath.toFile().apply { + parentFile.mkdirs() + writeText(codeValue, Charsets.UTF_8) + } + hrefLink.set("""
Saved ${filename}
""") + commandTask.complete() + } catch (e: Throwable) { + task.error(null, e) + } + })!! + markdown.replace( + codeValue + "```", + codeValue + "```\n" + commandTask.placeholder + ) + } } return withLinks } -fun saveFiles( - root: Path, - response: String, -) { - val diffPattern = """(?s)(? - val filename1 = diffBlock.groupValues[1] - val filename = when { - pattern_backticks.containsMatchIn(filename1) -> { - pattern_backticks.find(filename1)!!.groupValues[1] - } - - else -> filename1.trim() - } - val codeValue = diffBlock.groupValues[2] - root.resolve(filename).toFile().apply { - parentFile.mkdirs() - writeText(codeValue) - } - } -} - -private val pattern_backticks = "`(.*)`".toRegex() +private val pattern_backticks = "`(.*)`".toRegex() \ No newline at end of file diff --git a/webui/src/main/kotlin/com/simiacryptus/diff/AddShellExecutionLinks.kt b/webui/src/main/kotlin/com/simiacryptus/diff/AddShellExecutionLinks.kt new file mode 100644 index 00000000..1d0b4487 --- /dev/null +++ b/webui/src/main/kotlin/com/simiacryptus/diff/AddShellExecutionLinks.kt @@ -0,0 +1,49 @@ +package com.simiacryptus.diff + + import com.simiacryptus.skyenet.webui.application.ApplicationInterface + import com.simiacryptus.skyenet.webui.session.SocketManagerBase + import com.simiacryptus.skyenet.webui.util.MarkdownUtil + import java.util.* +import java.io.BufferedReader +import java.io.InputStreamReader + + fun SocketManagerBase.addShellExecutionLinks( + response: String, + ui: ApplicationInterface +): String { + val shellCodePattern = """(?s)(? + val shellCode = matchResult.groupValues[1] + val executionId = UUID.randomUUID().toString() + val executionTask = ui.newTask(false) + val executeButton = hrefLink("Execute", classname = "href-link cmd-button") { + try { + val process = Runtime.getRuntime().exec(arrayOf("sh", "-c", shellCode)) + val reader = BufferedReader(InputStreamReader(process.inputStream)) + val errorReader = BufferedReader(InputStreamReader(process.errorStream)) + val output = StringBuilder() + var line: String? + while (reader.readLine().also { line = it } != null) { + output.append(line).append("\n") + } + while (errorReader.readLine().also { line = it } != null) { + output.append("Error: ").append(line).append("\n") + } + val exitCode = process.waitFor() + output.append("Exit code: $exitCode") + executionTask.complete(MarkdownUtil.renderMarkdown("```\n${output.toString()}\n```", ui = ui)) + } catch (e: Throwable) { + executionTask.error(null, e) + } + } + """ + ```shell + $shellCode + ``` +
+ $executeButton + ${executionTask.placeholder} +
+ """.trimIndent() + } +} \ No newline at end of file