freddie 0.0.50 → 0.0.52

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/AGENTS.md CHANGED
@@ -163,6 +163,7 @@ One `test.js` at project root. ≤200 lines. Plain assertions, real data, real s
163
163
  - **Bulk-rename: git grep is case-sensitive on literal patterns** — `git grep -lI <name>` only matches lowercase. For case-variant sweep during rename refactors, use `git grep -liI -e <lower> -e <Title> -e <UPPER>` (per-pattern `-i` requires `-e` form). Single-form check is a false-clean trap.
164
164
  - **freddie exec command Windows invocation** — `plugins/core-cli/plugin.js` registers the `exec` command (commit e5fb1b7) for non-interactive scripted use. Correct invocation on Windows: `bun run bin/freddie.js exec --prompt "..."`. Do NOT use `bun x freddie` — it hangs on Windows due to npm registry fetch timeouts. The command takes `--prompt` (required), `--model` (default ''), `--timeout` (default 60000ms) and is the validated entry point for CI pipelines.
165
165
  - **acptoapi-bridge max_tokens silent truncation** — `src/agent/acptoapi-bridge.js` line 20 controls max_tokens passed to the LLM. Prior to commit e5fb1b7, this was set to 1024, which silently truncated responses on generation tasks. Raised to 4096 to prevent hidden content loss. If generation output appears incomplete, verify max_tokens is 4096 or higher.
166
+ - **Rebase regression trap** — After `git pull --rebase` following a rejected push, a CI auto-bump commit on remote (based on pre-fix tree) can silently revert local fixes. The `anentrypoint-design: file:../anentrypoint-design → ^0.0.40` fix in commit `d469d25` was reverted this way. After any rebase, verify `package.json` dep versions and `package-lock.json` resolved URLs match expected values before pushing. Sanity check: `git show HEAD:package.json | node -e "const d=JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')); console.log(d.dependencies['anentrypoint-design'])"`. Tell: pages CI fails with "lock file's anentrypoint-design@0.0.40 does not satisfy anentrypoint-design@" (empty version = file: dep).
166
167
 
167
168
  ## Subsystem guide
168
169
 
package/CHANGELOG.md CHANGED
@@ -1,10 +1,13 @@
1
1
  # Changelog
2
2
 
3
- ## [Unreleased] - 2026-05-04
3
+ ## [0.0.51] - 2026-05-04
4
4
 
5
5
  ### Fixed
6
6
  - Add `plugins/` to npm `files` array so `bun x freddie` includes all commands (dashboard, tools, cron, etc.)
7
7
  - Switch `anentrypoint-design` dep from `file:../anentrypoint-design` to `^0.0.40` registry version so published package installs cleanly without local sibling repo
8
+ - `dashboard` CLI command: add `--cwd <dir>` flag to set working directory for file research; converts POSIX `/c/...` paths to Windows `c:/...` automatically
9
+ - `acptoapi-bridge`: when tools are requested, pass `x-cwd` header and inject working-directory context into system prompt so Claude CLI knows where to look
10
+ - acptoapi Claude backend: enable `--tools default` and `--add-dir` when request includes tool definitions, allowing Claude CLI's built-in Bash/Read tools to execute in the correct working directory; set `bypassPermissions` mode for tool execution
8
11
 
9
12
  ## [0.1.2] - 2026-05-04
10
13
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "freddie",
3
- "version": "0.0.50",
3
+ "version": "0.0.52",
4
4
  "type": "module",
5
5
  "description": "Open JS agent harness built on pi-mono, floosie, xstate, and anentrypoint-design",
6
6
  "bin": {
@@ -24,9 +24,9 @@
24
24
  "floosie": "^0.6.14",
25
25
  "gm-cc": "^2.0.727",
26
26
  "js-yaml": "^4.1.0",
27
+ "plugsdk": "^1.0.7",
27
28
  "xstate": "^5.31.0",
28
- "zod": "^4.0.0",
29
- "plugsdk": "^1.0.7"
29
+ "zod": "^4.0.0"
30
30
  },
31
31
  "optionalDependencies": {
32
32
  "@libsql/darwin-arm64": "0.3.19",
@@ -73,7 +73,8 @@ export default {
73
73
  const out = await runBatch({ prompts, concurrency: Number(opts.concurrency), model: opts.model })
74
74
  console.log('batch:', out.id, '\nfile:', out.file, '\nresults:', out.results.length)
75
75
  } })
76
- C({ name: 'dashboard', description: 'Boot web dashboard', options: [{ flag: '--port <port>', default: '0' }], action: async (opts) => {
76
+ C({ name: 'dashboard', description: 'Boot web dashboard', options: [{ flag: '--port <port>', default: '0' }, { flag: '--cwd <dir>', default: '' }], action: async (opts) => {
77
+ if (opts.cwd) { const p = process.platform === 'win32' ? opts.cwd.replace(/^\/([a-z])\//i, '$1:/') : opts.cwd; process.chdir(p) }
77
78
  const { createDashboard } = await import('../../src/web/server.js')
78
79
  const d = await createDashboard({ port: Number(opts.port) })
79
80
  console.log('dashboard:', d.url)
@@ -13,16 +13,28 @@ export function getAcptoapiModel() {
13
13
  export async function callLLM({ messages, tools = [], model } = {}) {
14
14
  const base = getAcptoapiUrl()
15
15
  const useModel = model || getAcptoapiModel()
16
+ const hasTools = Array.isArray(tools) && tools.length > 0
17
+ const adaptedMessages = messages.map(adaptMessage)
18
+ if (hasTools) {
19
+ const cwd = process.cwd()
20
+ const sysIdx = adaptedMessages.findIndex(m => m.role === 'system')
21
+ const cwdNote = `\nWorking directory: ${cwd}\nUse your built-in tools (Bash, Read, Write) to explore files in this directory when needed.`
22
+ if (sysIdx >= 0) adaptedMessages[sysIdx] = { ...adaptedMessages[sysIdx], content: (adaptedMessages[sysIdx].content || '') + cwdNote }
23
+ else adaptedMessages.unshift({ role: 'system', content: cwdNote.trim() })
24
+ }
16
25
  const body = {
17
26
  model: useModel,
18
- messages: messages.map(adaptMessage),
27
+ messages: adaptedMessages,
19
28
  stream: false,
20
29
  max_tokens: 4096,
21
30
  }
22
- if (Array.isArray(tools) && tools.length) body.tools = tools.map(adaptTool)
31
+ if (hasTools) body.tools = tools.map(adaptTool)
32
+ const headers = { 'content-type': 'application/json', authorization: 'Bearer none' }
33
+ const cwd = process.cwd()
34
+ if (Array.isArray(tools) && tools.length) headers['x-cwd'] = cwd
23
35
  const res = await fetch(base.replace(/\/$/, '') + '/chat/completions', {
24
36
  method: 'POST',
25
- headers: { 'content-type': 'application/json', authorization: 'Bearer none' },
37
+ headers,
26
38
  body: JSON.stringify(body),
27
39
  })
28
40
  if (!res.ok) {