mirror of
https://github.com/hanzoai/dev.git
synced 2026-10-25 03:32:32 +00:00
Merge branch 'main' of https://github.com/just-every/code into main
This commit is contained in:
@@ -7,6 +7,11 @@
|
||||
|
||||
- (none)
|
||||
|
||||
## [0.4.8] - 2025-11-03
|
||||
|
||||
- Auto Drive: Surface coordinator schema details when retries fail so validation issues are actionable. (cbc31dad)
|
||||
- TUI/Auto Drive: Resume the decision pipeline after diagnostics follow-ups so runs wrap up correctly. (1714bbd8)
|
||||
|
||||
## [0.4.7] - 2025-10-30
|
||||
|
||||
- TUI/Auto Drive: Keep router answers visible in the transcript so automation context stays complete. (cf17fc1)
|
||||
|
||||
+9
-5
@@ -1,14 +1,18 @@
|
||||
class Code < Formula
|
||||
desc "Terminal coding agent"
|
||||
homepage "https://github.com/just-every/code"
|
||||
version "v0.2.67"
|
||||
version "0.4.7"
|
||||
livecheck do
|
||||
url :homepage
|
||||
strategy :github_latest
|
||||
end
|
||||
on_macos do
|
||||
if Hardware::CPU.arm?
|
||||
url "https://github.com/just-every/code/releases/download/v0.2.67/code-aarch64-apple-darwin.tar.gz"
|
||||
sha256 "ed8fbb68d8cff0f76d28c9c9b69445dab66f8e645613e9145061e950e8cf7507"
|
||||
url "https://github.com/just-every/code/releases/download/v0.4.7/code-aarch64-apple-darwin.tar.gz"
|
||||
sha256 "76ac9be154c86193bd2f66ddc7bc82168f310574a3ebbdc279548d91d232e2a6"
|
||||
else
|
||||
url "https://github.com/just-every/code/releases/download/v0.2.67/code-x86_64-apple-darwin.tar.gz"
|
||||
sha256 "642f656b1d45fe305738f519b5d44c8329bd9963f3e3781ee542a4313d2102f7"
|
||||
url "https://github.com/just-every/code/releases/download/v0.4.7/code-x86_64-apple-darwin.tar.gz"
|
||||
sha256 "5968dc7bf681ccb7fb9a825cfbfb33870e2c249f2ca326e8a70c7f4cedfd63e7"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -2432,7 +2432,7 @@ fn agent_action_to_event(action: &AgentAction) -> AutoTurnAgentsAction {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn extract_first_json_object(input: &str) -> Option<String> {
|
||||
pub(crate) fn extract_first_json_object(input: &str) -> Option<String> {
|
||||
let mut depth = 0usize;
|
||||
let mut in_str = false;
|
||||
let mut escape = false;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
use anyhow::Context;
|
||||
use serde_json::Value;
|
||||
|
||||
use crate::auto_coordinator::extract_first_json_object;
|
||||
|
||||
pub fn user_turn_schema() -> Value {
|
||||
serde_json::json!({
|
||||
"type": "object",
|
||||
@@ -24,8 +26,20 @@ pub fn user_turn_schema() -> Value {
|
||||
}
|
||||
|
||||
pub fn parse_user_turn_reply(raw: &str) -> anyhow::Result<(Option<String>, Option<String>)> {
|
||||
let value: Value = serde_json::from_str(raw)
|
||||
.context("parsing coordinator user turn JSON")?;
|
||||
let value: Value = match serde_json::from_str(raw) {
|
||||
Ok(v) => v,
|
||||
Err(first_err) => {
|
||||
let Some(blob) = extract_first_json_object(raw) else {
|
||||
return Err(first_err).context("parsing coordinator user turn JSON");
|
||||
};
|
||||
let first_err_msg = first_err.to_string();
|
||||
serde_json::from_str(&blob).with_context(|| {
|
||||
format!(
|
||||
"parsing coordinator user turn JSON (after salvage); initial parse error: {first_err_msg}"
|
||||
)
|
||||
})?
|
||||
}
|
||||
};
|
||||
let obj = value
|
||||
.as_object()
|
||||
.ok_or_else(|| anyhow::anyhow!("coordinator response was not a JSON object"))?;
|
||||
@@ -52,3 +66,29 @@ pub fn parse_user_turn_reply(raw: &str) -> anyhow::Result<(Option<String>, Optio
|
||||
|
||||
Ok((extract("user_response")?, extract("cli_command")?))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use anyhow::Result;
|
||||
|
||||
#[test]
|
||||
fn parse_user_turn_reply_strict_object() -> Result<()> {
|
||||
let raw = r#"{"user_response":" Thanks! ","cli_command":null}"#;
|
||||
let (user, cli) = parse_user_turn_reply(raw)?;
|
||||
assert_eq!(user.as_deref(), Some("Thanks!"));
|
||||
assert_eq!(cli, None);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_user_turn_reply_salvages_embedded_json() -> Result<()> {
|
||||
let raw = r#"Here are two options: do A or B.
|
||||
{"user_response":null,"cli_command":" echo done "}
|
||||
Let me know."#;
|
||||
let (user, cli) = parse_user_turn_reply(raw)?;
|
||||
assert_eq!(user, None);
|
||||
assert_eq!(cli.as_deref(), Some("echo done"));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
+21
-6
@@ -6,6 +6,7 @@ import { fileURLToPath } from "url";
|
||||
import { platform as nodePlatform, arch as nodeArch } from "os";
|
||||
import { execSync } from "child_process";
|
||||
import { get as httpsGet } from "https";
|
||||
import { runPostinstall } from "../postinstall.js";
|
||||
|
||||
// __dirname equivalent in ESM
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
@@ -270,12 +271,26 @@ const tryBootstrapBinary = async () => {
|
||||
};
|
||||
|
||||
// If missing, attempt to bootstrap into place (helps when Bun blocks postinstall)
|
||||
if (!existsSync(binaryPath) && !existsSync(legacyBinaryPath)) {
|
||||
const ok = await tryBootstrapBinary();
|
||||
if (!ok) {
|
||||
// retry legacy name in case archive provided coder-*
|
||||
if (existsSync(legacyBinaryPath) && !existsSync(binaryPath)) {
|
||||
binaryPath = legacyBinaryPath;
|
||||
let binaryReady = existsSync(binaryPath) || existsSync(legacyBinaryPath);
|
||||
if (!binaryReady) {
|
||||
let runtimePostinstallError = null;
|
||||
try {
|
||||
await runPostinstall({ invokedByRuntime: true, skipGlobalAlias: true });
|
||||
} catch (err) {
|
||||
runtimePostinstallError = err;
|
||||
}
|
||||
|
||||
binaryReady = existsSync(binaryPath) || existsSync(legacyBinaryPath);
|
||||
if (!binaryReady) {
|
||||
const ok = await tryBootstrapBinary();
|
||||
if (!ok) {
|
||||
if (runtimePostinstallError && !lastBootstrapError) {
|
||||
lastBootstrapError = runtimePostinstallError;
|
||||
}
|
||||
// retry legacy name in case archive provided coder-*
|
||||
if (existsSync(legacyBinaryPath) && !existsSync(binaryPath)) {
|
||||
binaryPath = legacyBinaryPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@just-every/code",
|
||||
"version": "0.4.7",
|
||||
"version": "0.4.8",
|
||||
"license": "Apache-2.0",
|
||||
"description": "Lightweight coding agent that runs in your terminal - fork of OpenAI Codex",
|
||||
"bin": {
|
||||
@@ -35,10 +35,10 @@
|
||||
"prettier": "^3.3.3"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@just-every/code-darwin-arm64": "0.4.7",
|
||||
"@just-every/code-darwin-x64": "0.4.7",
|
||||
"@just-every/code-linux-x64-musl": "0.4.7",
|
||||
"@just-every/code-linux-arm64-musl": "0.4.7",
|
||||
"@just-every/code-win32-x64": "0.4.7"
|
||||
"@just-every/code-darwin-arm64": "0.4.8",
|
||||
"@just-every/code-darwin-x64": "0.4.8",
|
||||
"@just-every/code-linux-x64-musl": "0.4.8",
|
||||
"@just-every/code-linux-arm64-musl": "0.4.8",
|
||||
"@just-every/code-win32-x64": "0.4.8"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Non-functional change to trigger release workflow
|
||||
|
||||
import { existsSync, mkdirSync, createWriteStream, chmodSync, readFileSync, readSync, writeFileSync, unlinkSync, statSync, openSync, closeSync, copyFileSync, fsyncSync, renameSync, realpathSync } from 'fs';
|
||||
import { join, dirname } from 'path';
|
||||
import { join, dirname, resolve } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { get } from 'https';
|
||||
import { platform, arch, tmpdir } from 'os';
|
||||
@@ -288,13 +288,21 @@ function validateDownloadedBinary(p) {
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
export async function runPostinstall(options = {}) {
|
||||
const { skipGlobalAlias = false, invokedByRuntime = false } = options;
|
||||
if (process.env.CODE_POSTINSTALL_DRY_RUN === '1') {
|
||||
return { skipped: true };
|
||||
}
|
||||
|
||||
if (invokedByRuntime) {
|
||||
process.env.CODE_RUNTIME_POSTINSTALL = process.env.CODE_RUNTIME_POSTINSTALL || '1';
|
||||
}
|
||||
// Detect potential PATH conflict with an existing `code` command (e.g., VS Code)
|
||||
// Only relevant for global installs; skip for npx/local installs to keep postinstall fast.
|
||||
const ua = process.env.npm_config_user_agent || '';
|
||||
const isNpx = ua.includes('npx');
|
||||
const isGlobal = process.env.npm_config_global === 'true';
|
||||
if (isGlobal && !isNpx) {
|
||||
if (!skipGlobalAlias && isGlobal && !isNpx) {
|
||||
try {
|
||||
const whichCmd = process.platform === 'win32' ? 'where code' : 'command -v code || which code || true';
|
||||
const resolved = execSync(whichCmd, { stdio: ['ignore', 'pipe', 'ignore'], shell: process.platform !== 'win32' }).toString().split(/\r?\n/).filter(Boolean)[0];
|
||||
@@ -760,7 +768,19 @@ async function main() {
|
||||
}
|
||||
}
|
||||
|
||||
main().catch(error => {
|
||||
console.error('Installation failed:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
function isExecutedDirectly() {
|
||||
const entry = process.argv[1];
|
||||
if (!entry) return false;
|
||||
try {
|
||||
return resolve(entry) === fileURLToPath(import.meta.url);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isExecutedDirectly()) {
|
||||
runPostinstall().catch(error => {
|
||||
console.error('Installation failed:', error);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import { test } from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
|
||||
test('runPostinstall resolves in dry-run mode', async () => {
|
||||
const { runPostinstall } = await import('../postinstall.js');
|
||||
process.env.CODE_POSTINSTALL_DRY_RUN = '1';
|
||||
try {
|
||||
const result = await runPostinstall({ invokedByRuntime: true, skipGlobalAlias: true });
|
||||
assert.ok(result && result.skipped === true);
|
||||
} finally {
|
||||
delete process.env.CODE_POSTINSTALL_DRY_RUN;
|
||||
delete process.env.CODE_RUNTIME_POSTINSTALL;
|
||||
}
|
||||
});
|
||||
@@ -1,14 +1,18 @@
|
||||
class Code < Formula
|
||||
desc "Terminal coding agent"
|
||||
homepage "https://github.com/just-every/code"
|
||||
version "v0.2.67"
|
||||
version "0.4.7"
|
||||
livecheck do
|
||||
url :homepage
|
||||
strategy :github_latest
|
||||
end
|
||||
on_macos do
|
||||
if Hardware::CPU.arm?
|
||||
url "https://github.com/just-every/code/releases/download/v0.2.67/code-aarch64-apple-darwin.tar.gz"
|
||||
sha256 "ed8fbb68d8cff0f76d28c9c9b69445dab66f8e645613e9145061e950e8cf7507"
|
||||
url "https://github.com/just-every/code/releases/download/v0.4.7/code-aarch64-apple-darwin.tar.gz"
|
||||
sha256 "76ac9be154c86193bd2f66ddc7bc82168f310574a3ebbdc279548d91d232e2a6"
|
||||
else
|
||||
url "https://github.com/just-every/code/releases/download/v0.2.67/code-x86_64-apple-darwin.tar.gz"
|
||||
sha256 "642f656b1d45fe305738f519b5d44c8329bd9963f3e3781ee542a4313d2102f7"
|
||||
url "https://github.com/just-every/code/releases/download/v0.4.7/code-x86_64-apple-darwin.tar.gz"
|
||||
sha256 "5968dc7bf681ccb7fb9a825cfbfb33870e2c249f2ca326e8a70c7f4cedfd63e7"
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
## @just-every/code v0.4.7
|
||||
## @just-every/code v0.4.8
|
||||
|
||||
This release polishes Auto Drive transcripts to keep automation context intact.
|
||||
This release sharpens Auto Drive recovery and keeps coordinator runs flowing smoothly.
|
||||
|
||||
### Changes
|
||||
- TUI/Auto Drive: Keep router answers visible in the transcript so automation context stays complete.
|
||||
- TUI/Auto Drive: Persist diagnostics follow-up prompts when resuming runs to avoid lost context.
|
||||
|
||||
- Auto Drive: Surface coordinator schema details when retries fail so validation issues are actionable.
|
||||
- TUI/Auto Drive: Resume the decision pipeline after diagnostics follow-ups so runs wrap up correctly.
|
||||
|
||||
### Install
|
||||
```
|
||||
@@ -12,4 +13,4 @@ npm install -g @just-every/code@latest
|
||||
code
|
||||
```
|
||||
|
||||
Compare: https://github.com/just-every/code/compare/v0.4.6...v0.4.7
|
||||
Compare: https://github.com/just-every/code/compare/v0.4.7...v0.4.8
|
||||
|
||||
Reference in New Issue
Block a user