registry  /  @orangeworks/orangetree  /  0.23.2

@orangeworks/orangetree@0.23.2

Branching session-tree work-tracking tool (local-first, TypeScript)

AI Security Review

scanned 4d ago · by lpm-firewall-ai

Suspicious primitives are aligned with a local desktop app for managing Claude sessions and user-defined dev servers. No confirmed malicious attack surface was found by source inspection.

Static reason
One or more suspicious static signals were detected.
Trigger
Explicit user invocation of orangetree bin or local web UI actions
Impact
Runs local helper processes and stores app metadata when the user uses the app; no confirmed unconsented exfiltration or install-time execution
Mechanism
User-invoked daemon, Claude CLI sessions, optional cloud/tunnel pairing, and user-configured service launcher
Rationale
The package contains powerful runtime features, but they are documented, user-invoked, and consistent with the declared local Claude work-tracking tool. I found no lifecycle execution, hidden credential harvesting, or unsolicited network exfiltration warranting a block or warning.
Evidence
package.jsonREADME.mddist/bin/orangetree.jsdist/server.jsdist/public/connection.js
Network endpoints3
api.orangetree.devorangetree.dev127.0.0.1

Decision evidence

public snapshot
AI called this Clean at 86.0% confidence as Benign with low false-positive risk.
Evidence for block
  • dist/server.js spawns Claude CLI with CLAUDE_CONFIG_DIR for bot sessions.
  • dist/server.js has optional cloud/onboarding/tunnel fetches to orangetree endpoints.
  • dist/server.js can launch user-configured service commands with shell:true.
  • dist/bin/orangetree.js can spawn daemon, browser opener, npm global update command on user CLI action.
Evidence against
  • package.json has no install/preinstall/postinstall lifecycle hooks.
  • README.md describes a local-first Claude session work-tracking app requiring a user-provided claude CLI.
  • dist/bin/orangetree.js only starts daemon/update/status/stop from explicit bin invocation.
  • dist/server.js binds local UI to 127.0.0.1 by default and uses local headers for local daemon calls.
  • Cloud/tunnel behavior is config/onboarding driven, not automatic credential harvesting.
  • No evidence of hidden payloads, obfuscation, import-time exfiltration, or destructive install-time behavior.
Behavioral surface
Source
ChildProcessCryptoEnvironmentVarsFilesystemNetworkShell
Supply chain
HighEntropyStringsUrlStrings
Manifest
NoLicense
scanned 62 file(s), 1.54 MB of source, external domains: 127.0.0.1, api.orangetree.dev, github.com, json-schema.org, orangetree.dev, registry.npmjs.org, www.w3.org

Source & flagged code

4 flagged · loading source
dist/bin/orangetree.jsView file
87// lib/daemon.ts L88: import { spawn, spawnSync } from "node:child_process"; L89: import { closeSync, existsSync as existsSync2, mkdirSync, openSync, readFileSync as readFileSync2, renameSync, rmSync, writeFileSync } from "node:fs";
High
Child Process

Package source references child process execution.

dist/bin/orangetree.jsView on unpkg · L87
312const ps = `$s=(New-Object -ComObject WScript.Shell).CreateShortcut(${psStr(lnk)});$s.TargetPath=${psStr(wscript)};$s.Arguments=${psStr(`//B //Nologo "${vbs}"`)};$s.Description='Or... L313: spawnSync("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command", ps], { stdio: "ignore", windowsHide: true }); L314: }
High
Shell

Package source references shell execution.

dist/bin/orangetree.jsView on unpkg · L312
87// lib/daemon.ts L88: import { spawn, spawnSync } from "node:child_process"; L89: import { closeSync, existsSync as existsSync2, mkdirSync, openSync, readFileSync as readFileSync2, renameSync, rmSync, writeFileSync } from "node:fs"; L90: import { request } from "node:http"; L91: import { homedir } from "node:os"; ... L99: function dataRoot() { L100: return process.env.OTREE_DATA ?? join2(homedir(), ".orangetree"); L101: }
High
Same File Env Network Execution

A single source file combines environment access, network access, and code or shell execution; review context before blocking.

dist/bin/orangetree.jsView on unpkg · L87
64Cross-file remote execution chain: dist/bin/orangetree.js spawns dist/server.js; helper contains network access plus dynamic code execution. L64: try { L65: return normalize(JSON.parse(readFileSync(path, "utf8"))); L66: } catch { ... L72: const fill = (key, value) => { L73: if (value != null && process.env[key] === void 0) process.env[key] = value; L74: }; ... L87: // lib/daemon.ts L88: import { spawn, spawnSync } from "node:child_process"; L89: import { closeSync, existsSync as existsSync2, mkdirSync, openSync, readFileSync as readFileSync2, renameSync, rmSync, writeFileSync } from "node:fs"; L90: import { request } from "node:http"; L91: import { homedir } from "node:os"; ... L99: function dataRoot() {
High
Cross File Remote Execution Context

Source spawns a local helper that also contains network and dynamic execution context; review data flow before blocking.

dist/bin/orangetree.jsView on unpkg · L64

Findings

4 High2 Medium5 Low
HighChild Processdist/bin/orangetree.js
HighShelldist/bin/orangetree.js
HighSame File Env Network Executiondist/bin/orangetree.js
HighCross File Remote Execution Contextdist/bin/orangetree.js
MediumNetwork
MediumEnvironment Vars
LowScripts Present
LowFilesystem
LowHigh Entropy Strings
LowUrl Strings
LowNo License