Merge branch 'main' of https://github.com/just-every/code into main

This commit is contained in:
James Peter
2025-11-03 20:25:12 +10:00
10 changed files with 140 additions and 37 deletions
+5
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
}
}
}
+6 -6
View File
@@ -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"
}
}
+27 -7
View File
@@ -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);
});
}
+14
View File
@@ -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;
}
});
+9 -5
View File
@@ -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
+6 -5
View File
@@ -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