headlesscode 1.2.1 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "headlesscode",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "description": "Standalone headless coding-agent harness: runs the Zoo Code agent loop (prompts, tools, modes) without a VS Code UI, driven by CLI, HTTP, and parallel worktree orchestration.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -41,6 +41,7 @@
41
41
  "dev": "tsx src/index.ts",
42
42
  "start": "tsx src/cli.ts",
43
43
  "cli": "tsx src/cli.ts",
44
+ "monitor:pilot": "tsx scripts/monitor-pilot/run.ts",
44
45
  "test": "node scripts/run-tests.mjs",
45
46
  "prepublishOnly": "npm ci && npm test"
46
47
  },
@@ -0,0 +1,21 @@
1
+ id: headlesscode-openrouter
2
+ display_name: HeadlessCode OpenRouter
3
+ description: OpenRouter inference access for HeadlessCode workers running in Node.js
4
+ category: inference
5
+ inference_capable: true
6
+ credentials:
7
+ - name: api_key
8
+ description: OpenRouter API key
9
+ env_vars: [HEADLESSCODE_OPENROUTER_API_KEY]
10
+ required: true
11
+ auth_style: bearer
12
+ header_name: authorization
13
+ discovery:
14
+ credentials: [api_key]
15
+ endpoints:
16
+ - host: openrouter.ai
17
+ port: 443
18
+ protocol: rest
19
+ access: read-write
20
+ enforcement: enforce
21
+ binaries: [/usr/local/bin/node]
@@ -0,0 +1,21 @@
1
+ version: 1
2
+ filesystem_policy:
3
+ include_workdir: true
4
+ read_only:
5
+ - /usr
6
+ - /lib
7
+ - /lib64
8
+ - /etc
9
+ - /proc
10
+ - /dev/urandom
11
+ - /var/log
12
+ read_write:
13
+ - /sandbox
14
+ - /tmp
15
+ - /dev/null
16
+ landlock:
17
+ compatibility: hard_requirement
18
+ process:
19
+ run_as_user: sandbox
20
+ run_as_group: sandbox
21
+ network_policies: {}
package/src/cli.ts CHANGED
@@ -44,6 +44,7 @@ import { costHistoryCliMain } from "./orchestrator/cost-history-cli.js"
44
44
  import { resolvePermissions, type PermissionsConfig } from "./permissions/config.js"
45
45
  import { resolveModelForMode, resolveReasoningEffortForMode } from "./config/mode-models.js"
46
46
  import { improveMain } from "./rsi/controller.js"
47
+ import { openShellSessionMain } from "./cloud/openshell-session.js"
47
48
 
48
49
  const VERSION = "0.1.0"
49
50
 
@@ -187,6 +188,9 @@ Usage:
187
188
  headlesscode --dry-run [options] # build system prompt + validate config, no LLM call
188
189
 
189
190
  Subcommands:
191
+ headlesscode openshell-session --repo <path> --task <text> --policy <path>
192
+ Run one task in an OpenShell sandbox and keep its Git worktree
193
+ for review. See \`openshell-session --help\` for options.
190
194
  headlesscode improve --repo <path> [--model <id>] [--population <n>] [--dry-run]
191
195
  Run a bounded recursive self-improvement generation. Candidates
192
196
  use isolated git worktrees; evaluator/scoring paths are protected.
@@ -721,6 +725,32 @@ export function parseArgs(argv: string[]): { options: CliOptions; error?: string
721
725
  }
722
726
 
723
727
  export async function main(argv: string[] = process.argv.slice(2)): Promise<number> {
728
+ if (argv[0] === "openshell-review-session" || argv[0] === "openshell-qa-session") {
729
+ let payload: Record<string, unknown>
730
+ try {
731
+ payload = JSON.parse(Buffer.from(argv[1] ?? "", "base64url").toString("utf8")) as Record<string, unknown>
732
+ } catch {
733
+ process.stderr.write("headlesscode: invalid OpenShell session payload\n")
734
+ return 2
735
+ }
736
+ if (argv[0] === "openshell-review-session") {
737
+ const { runReview } = await import("./orchestrator/reviewer.js")
738
+ const result = await runReview(payload as unknown as Parameters<typeof runReview>[0])
739
+ process.stdout.write(`HEADLESSCODE_RESULT_JSON:${JSON.stringify(result)}\n`)
740
+ return 0
741
+ }
742
+ const { runQa } = await import("./qa/qa.js")
743
+ const result = await runQa(payload as unknown as Parameters<typeof runQa>[0])
744
+ process.stdout.write(`HEADLESSCODE_RESULT_JSON:${JSON.stringify(result)}\n`)
745
+ return 0
746
+ }
747
+ if (argv[0] === "openshell-worker") {
748
+ const { openShellWorkerMain } = await import("./cloud/openshell-worker.js")
749
+ return openShellWorkerMain(argv.slice(1))
750
+ }
751
+ if (argv[0] === "openshell-session") {
752
+ return openShellSessionMain(argv.slice(1))
753
+ }
724
754
  // Bounded recursive self-improvement: the supervisor owns the evaluator,
725
755
  // archive, and selection logic while each candidate runs in its own
726
756
  // worktree. See docs/recursive-self-improvement.md.
@@ -0,0 +1,16 @@
1
+ import { spawnSync } from "node:child_process"
2
+ import * as fs from "node:fs"
3
+
4
+ export function openshellPreflight(): string | undefined {
5
+ const policy = process.env.HEADLESSCODE_OPENSHELL_POLICY
6
+ if (!policy || !fs.existsSync(policy)) return "set HEADLESSCODE_OPENSHELL_POLICY to an existing base policy YAML"
7
+ if (!process.env.HEADLESSCODE_OPENROUTER_API_KEY) return "set HEADLESSCODE_OPENROUTER_API_KEY so OpenShell can provide the imported credential profile"
8
+ const version = spawnSync("openshell", ["--version"], { encoding: "utf8", timeout: 5000 })
9
+ if (version.error || version.status !== 0) return "OpenShell CLI is unavailable"
10
+ const gateway = spawnSync("openshell", ["gateway", "info"], { encoding: "utf8", timeout: 10000 })
11
+ const output = `${gateway.stdout ?? ""}${gateway.stderr ?? ""}`
12
+ if (gateway.error || gateway.status !== 0 || !/Status:\s+healthy/i.test(output)) {
13
+ return `OpenShell gateway is not healthy${output.trim() ? ": " + output.trim() : ""}`
14
+ }
15
+ return undefined
16
+ }