Releases: FiveTechSoft/CCHarbour
v0.8.26 — Hooks system
CCHarbour v0.8.26 — Hooks system: fire-and-forget turn_complete shell hooks with a /hook REPL command.
New since v0.8.25
/hookcommand. Full CRUD over hooks stored in
.ccharbour/settings.json:/hook list,/hook add <event> <cmd>,/hook remove <event> <idx>,/hook edit <event> <idx> <cmd>,/hook test <event>,/hook log. Missing
subcommand defaults tolist. Unknown events echo the valid
event list; out-of-range indices report the actual range.turn_completeevent. Fires on every turn outcome
(success, error, interrupted) viaCCHOOKS_Runfrom inside
CCREPL_RunTurn. The fire ishb_processOpenwith
detach=.T., so the REPL never blocks on a hook. Each hook
is wrapped inBEGIN SEQUENCE / RECOVERso a single bad
command cannot take out the REPL or other hooks for the same
fire.CCHARBOUR_*env vars. Children inherit six env vars
set on the CCHarbour process before each spawn:
CCHARBOUR_EVENT,CCHARBOUR_STATUS
(success/error/interrupted),CCHARBOUR_MODEL,
CCHARBOUR_TOKENS,CCHARBOUR_DURATION_MS,CCHARBOUR_CWD.- Opt-in
hooks_log. Set"hooks_log": truein
.ccharbour/settings.jsonto append-log every fire to
.ccharbour/hooks.log([YYYY-MM-DD HH:MM:SS] event=... status=... cmd=...). Spawn failures and exceptions show up
asERROR spawn-failed/ERROR exceptionlines. - Settings reload on every fire. Editing the hooks block in
.ccharbour/settings.jsontakes effect on the next turn
without restarting CCHarbour (per-fireCCSETTINGS_Load). - New module
src/cchooks.prg. Pure helpers
(CCHOOKS_ValidEvents,IsValidEvent,List,Add,
Remove,Edit), log writer (LogPath,Log), the runtime
fire path (CCHOOKS_Run), and the user-facing renderer
(CCHOOKS_Render,CCHOOKS_EventList). Registered in
cc.hbp,cc_linux.hbp, andcc_mac.hbpso it links on
every platform. - 42 new hooks assertions in
tests/test_hooks.prgplus 4
/hookparser tests intests/test_ui.prgand a malformed-
hooks merge regression test intests/test_settings.prg. Test
suite goes from 431 to 490 passing. - Banner version bumped to v0.8.26.
Future work is documented in
docs/superpowers/specs/2026-05-27-hooks-system-design.md:
more events (session_start, pre_tool_use, ...), per-hook
timeouts, JSON-on-stdin context, hook conditions
(on_status: [...]), and log rotation.
New since v0.8.24
- Ollama auth fix. Ollama 0.20.4 silently hangs the request
whenAuthorization: Bearer sk-...(a left-over DeepSeek /
OpenAI key from a prior/provider deepseeksession) is sent
-- it appears to treat the credential as a cloud-forward
token and waits on a remote that never answers. CCHarbour now
forcesBearer ollamaon every request to alocalhost:11434
URL via aCC_IsOllamaUrlcheck inccapi.prg. The user's
stored cloud key stays untouched insettings.jsonso the
next/provider deepseekswitch reuses it. Accept: text/event-streamdropped for Ollama. With that
header set, Ollama collapses tool calls into a JSON blob
insidemessage.contentinstead of populatingtool_calls.
CCHarbour now omits the header for Ollama URLs; SSE still
works because the body's"stream": trueis what activates
streaming.stream_options.include_usageomitted for Ollama. Ollama
0.20.x stalls when that field is present./costwill not
show token counts for Ollama turns as a result; cloud
backends keep emitting the final usage chunk.- Ollama setup notes rewritten in
pages/commands.md. The
three quirks above are now documented, plus the real
bottleneck: even after the fixes, sending all 17 of
CCHarbour's tool schemas (~15 KB JSON) tollama3.1:8b
takes Ollama > 90 s per turn on consumer GPUs and frequently
hits the curl 120 s deadline. Best used for short
conversational turns, not the full agent loop.
v0.8.24 — Ollama preset default switched to llama3.1:8b + setup notes.
New since v0.8.23
/provider ollamadefault model is nowllama3.1:8b. Local
testing showedqwen2.5-coder:7b(the previous default) emits
bare JSON insidemessage.contentinstead of populating
tool_calls, so Ollama's OpenAI-compatible endpoint never
surfaces a tool call and the agent loop ends every turn with
the[hint: 0 tool calls...]warning.llama3.1:8breturns
propertool_callsthrough the same endpoint and works with
the loop end-to-end. Same caveat for the abliterated
qwen2.5-coderGGUFs floating around on Hugging Face.- Updated applied-preset message and commands.md. Three real
gotchas are now spelled out: (1)OLLAMA_CONTEXT_LENGTH=16384
is required -- the default 4096 ctx is too small for the
CCHarbour system prompt + 16 tool schemas (the request silently
hangs at the curl 120 s timeout); (2) only models that route
tool calls through the OpenAItool_callsfield actually
work with CCHarbour (llama3.1:8b,mistral-nemo:12b,
command-rconfirmed;qwen2.5-coderconfirmed broken);
(3) Ollama 0.20.x can hang on/v1/chat/completionswith
stream:trueand a populatedtoolsarray for some models --
switch model if the timeout fires.
v0.8.23 — Ollama provider preset + one-shot no-tool-call hint.
New since v0.8.22
/provider ollamapreset. Setsbase_urlto
http://localhost:11434/v1and the default model to
qwen2.5-coder:7b. The placeholder API keyollamais
auto-seeded so the agent loop does not block on the "no api
key" branch -- Ollama's OpenAI-compatible endpoint ignores
Authorization. The applied-preset message reminds the user
to runollama serve, pull the model, and pick a
tool-calling-capable model (qwen2.5-coder, llama3.1+,
mistral-nemo). UpdatedPresets:list, "no API key" banner
warning, and the playground/helpfooter to mention ollama.- No-tool-call detection.
CC_AgentRunnow returns
tool_call_count-- the total number of tool calls issued
across the whole run. After every successful turn,
CCREPL_MaybeWarnNoToolCallchecks whether the count is
zero AND the model's reply contains a phrase that suggests
the model wanted to act but could not ("I would run...", "I
cannot access...", "without access to tools", and ~15 more).
When both conditions hold, a one-shot warn-coloured hint
points at/provider model <name>with a curated list of
tool-calling models. The hint is muted permanently once any
tool call succeeds (proof of tool support);/clearand
/providerre-arm it so the next backend gets a fair
re-evaluation.
v0.8.22 — /load crash fix + working /loop and /rewind in the playground.
New since v0.8.21
- Fixed
/loadcrash.CCUI_SessionListOutputconcatenated a
Harbour DATE with a string (DToS(d) + " " + d) inside the row
formatter and raisedFatal: Argument errorthe first time
/loadwas run against a sessions directory that contained any
saved file. The bug shipped in v0.8.21. Switched to
DToC( mtime )so the date renders as a plain string. Verified
on Windows, macOS and Linux. - Playground
/rewind [N]. Pops the conversation snapshot
stack (capped at 20), restoring the message array and the
cumulative usage counter to the state before the last user
turn. Snapshots are pushed inhandleSubmitjust before the
user message is appended, so slash commands and the
API-key-missing branch do not push spurious entries. - Playground
/loop <interval> <prompt>. Arms a
setIntervalthat re-issues the prompt viahandleSubmit
every interval. Intervals accepts/m/hsuffixes;
bare numbers are seconds./loop status,/loop stopand
/loop clearmirror the native binary; ticks that would
overlap a running turn are skipped. - Playground
/clearnow resets/loopand/rewindstate.
The handler flushes the rewind stack and cancels any armed
loop alongside the existing project / conversation / usage
reset.
v0.8.21 — /loop fixed-interval rerun + /rewind (double-tap Esc).
New since v0.8.20
/loopslash command. Re-run a prompt on a fixed interval,
matching Claude Code's fixed-interval/loop./loop 5m check CI
arms a recurring turn every 5 minutes; intervals accept thes,
m,hsuffixes (a bare number is seconds)./loop/
/loop statusshows the active loop,/loop stopends it while
keeping the prompt text,/loop cleardrops both. The sleep
between turns is interruptible — pressing Esc ends the loop.
Hooks in parallel to the existing/goalauto-continue, so
/loopand/goalcan be armed independently. Model-paced
(self-scheduled) variant is not implemented in this release./rewindslash command + double-tap Esc. Undo the last
conversation turn./rewindpops one snapshot;/rewind Npops
N. A double-tap of Esc (≤ 600 ms apart) at the idle prompt is
detected inCCPROMPT_Polland converted into arewind
interrupt kind, whichCCREPL_PromptIdlereturns as the literal
/rewind. Snapshots are pushed before each user message,
/init,/btwdrain message, and/looprunner turn; the
stack is capped at 20 entries (oldest falls off the bottom).
Restored state coversaMsgs,s_cGoal,s_lGoalLooping,
s_cLoopPrompt,s_nLoopIntervalSec,s_lLoopActive,
s_lPlanMode,s_lLeanMode,s_hSessionUsage, and
s_lCompactNudged./clearand/loadflush the stack. File
modifications made bywrite/edit/shellare NOT rolled
back — only the conversation.
v0.8.20 — Ask-prompt deadlock fix: non-TTY auto-deny + CCHARBOUR_ASK_TIMEOUT.
New since v0.8.19
- **Non-TTY auto-den...
v0.8.25
CCHarbour v0.8.25 — Ollama-specific bug fixes uncovered by end-to-end testing.
New since v0.8.24
- Ollama auth fix. Ollama 0.20.4 silently hangs the request
whenAuthorization: Bearer sk-...(a left-over DeepSeek /
OpenAI key from a prior/provider deepseeksession) is sent
-- it appears to treat the credential as a cloud-forward
token and waits on a remote that never answers. CCHarbour now
forcesBearer ollamaon every request to alocalhost:11434
URL via aCC_IsOllamaUrlcheck inccapi.prg. The user's
stored cloud key stays untouched insettings.jsonso the
next/provider deepseekswitch reuses it. Accept: text/event-streamdropped for Ollama. With that
header set, Ollama collapses tool calls into a JSON blob
insidemessage.contentinstead of populatingtool_calls.
CCHarbour now omits the header for Ollama URLs; SSE still
works because the body's"stream": trueis what activates
streaming.stream_options.include_usageomitted for Ollama. Ollama
0.20.x stalls when that field is present./costwill not
show token counts for Ollama turns as a result; cloud
backends keep emitting the final usage chunk.- Ollama setup notes rewritten in
pages/commands.md. The
three quirks above are now documented, plus the real
bottleneck: even after the fixes, sending all 17 of
CCHarbour's tool schemas (~15 KB JSON) tollama3.1:8b
takes Ollama > 90 s per turn on consumer GPUs and frequently
hits the curl 120 s deadline. Best used for short
conversational turns, not the full agent loop.
v0.8.24 — Ollama preset default switched to llama3.1:8b + setup notes.
New since v0.8.23
/provider ollamadefault model is nowllama3.1:8b. Local
testing showedqwen2.5-coder:7b(the previous default) emits
bare JSON insidemessage.contentinstead of populating
tool_calls, so Ollama's OpenAI-compatible endpoint never
surfaces a tool call and the agent loop ends every turn with
the[hint: 0 tool calls...]warning.llama3.1:8breturns
propertool_callsthrough the same endpoint and works with
the loop end-to-end. Same caveat for the abliterated
qwen2.5-coderGGUFs floating around on Hugging Face.- Updated applied-preset message and commands.md. Three real
gotchas are now spelled out: (1)OLLAMA_CONTEXT_LENGTH=16384
is required -- the default 4096 ctx is too small for the
CCHarbour system prompt + 16 tool schemas (the request silently
hangs at the curl 120 s timeout); (2) only models that route
tool calls through the OpenAItool_callsfield actually
work with CCHarbour (llama3.1:8b,mistral-nemo:12b,
command-rconfirmed;qwen2.5-coderconfirmed broken);
(3) Ollama 0.20.x can hang on/v1/chat/completionswith
stream:trueand a populatedtoolsarray for some models --
switch model if the timeout fires.
v0.8.23 — Ollama provider preset + one-shot no-tool-call hint.
New since v0.8.22
/provider ollamapreset. Setsbase_urlto
http://localhost:11434/v1and the default model to
qwen2.5-coder:7b. The placeholder API keyollamais
auto-seeded so the agent loop does not block on the "no api
key" branch -- Ollama's OpenAI-compatible endpoint ignores
Authorization. The applied-preset message reminds the user
to runollama serve, pull the model, and pick a
tool-calling-capable model (qwen2.5-coder, llama3.1+,
mistral-nemo). UpdatedPresets:list, "no API key" banner
warning, and the playground/helpfooter to mention ollama.- No-tool-call detection.
CC_AgentRunnow returns
tool_call_count-- the total number of tool calls issued
across the whole run. After every successful turn,
CCREPL_MaybeWarnNoToolCallchecks whether the count is
zero AND the model's reply contains a phrase that suggests
the model wanted to act but could not ("I would run...", "I
cannot access...", "without access to tools", and ~15 more).
When both conditions hold, a one-shot warn-coloured hint
points at/provider model <name>with a curated list of
tool-calling models. The hint is muted permanently once any
tool call succeeds (proof of tool support);/clearand
/providerre-arm it so the next backend gets a fair
re-evaluation.
v0.8.22 — /load crash fix + working /loop and /rewind in the playground.
New since v0.8.21
- Fixed
/loadcrash.CCUI_SessionListOutputconcatenated a
Harbour DATE with a string (DToS(d) + " " + d) inside the row
formatter and raisedFatal: Argument errorthe first time
/loadwas run against a sessions directory that contained any
saved file. The bug shipped in v0.8.21. Switched to
DToC( mtime )so the date renders as a plain string. Verified
on Windows, macOS and Linux. - Playground
/rewind [N]. Pops the conversation snapshot
stack (capped at 20), restoring the message array and the
cumulative usage counter to the state before the last user
turn. Snapshots are pushed inhandleSubmitjust before the
user message is appended, so slash commands and the
API-key-missing branch do not push spurious entries. - Playground
/loop <interval> <prompt>. Arms a
setIntervalthat re-issues the prompt viahandleSubmit
every interval. Intervals accepts/m/hsuffixes;
bare numbers are seconds./loop status,/loop stopand
/loop clearmirror the native binary; ticks that would
overlap a running turn are skipped. - Playground
/clearnow resets/loopand/rewindstate.
The handler flushes the rewind stack and cancels any armed
loop alongside the existing project / conversation / usage
reset.
v0.8.21 — /loop fixed-interval rerun + /rewind (double-tap Esc).
New since v0.8.20
/loopslash command. Re-run a prompt on a fixed interval,
matching Claude Code's fixed-interval/loop./loop 5m check CI
arms a recurring turn every 5 minutes; intervals accept thes,
m,hsuffixes (a bare number is seconds)./loop/
/loop statusshows the active loop,/loop stopends it while
keeping the prompt text,/loop cleardrops both. The sleep
between turns is interruptible — pressing Esc ends the loop.
Hooks in parallel to the existing/goalauto-continue, so
/loopand/goalcan be armed independently. Model-paced
(self-scheduled) variant is not implemented in this release./rewindslash command + double-tap Esc. Undo the last
conversation turn./rewindpops one snapshot;/rewind Npops
N. A double-tap of Esc (≤ 600 ms apart) at the idle prompt is
detected inCCPROMPT_Polland converted into arewind
interrupt kind, whichCCREPL_PromptIdlereturns as the literal
/rewind. Snapshots are pushed before each user message,
/init,/btwdrain message, and/looprunner turn; the
stack is capped at 20 entries (oldest falls off the bottom).
Restored state coversaMsgs,s_cGoal,s_lGoalLooping,
s_cLoopPrompt,s_nLoopIntervalSec,s_lLoopActive,
s_lPlanMode,s_lLeanMode,s_hSessionUsage, and
s_lCompactNudged./clearand/loadflush the stack. File
modifications made bywrite/edit/shellare NOT rolled
back — only the conversation.
v0.8.20 — Ask-prompt deadlock fix: non-TTY auto-deny + CCHARBOUR_ASK_TIMEOUT.
New since v0.8.19
- Non-TTY auto-deny on
askprompts. When a tool gatedask
fires andstdinis not a TTY (piped input,script -c, a
background SSHexec_command, a CI runner),CCREPL_AskPerm
used to call the line reader anyway and block forever — no human
was at the keyboard to typey. Now the path is short-circuited
with a one-line[non-interactive stdin -- '<tool>' denied]
notice and the call is denied immediately, so the agent loop
surfaces anError: tool ... denied by userresult and keeps
moving instead of hanging. CCHARBOUR_ASK_TIMEOUTenv var. Bounds the wait even on a
real TTY. Set to a positive integer number of seconds; if no
answer is typed before the deadline, the REPL prints
[no response in Ns -- denied]and the call is denied. Default
(unset or0) keeps the original blocking behaviour. Both safety
nets fall back to deny — a missing human can never silently
approve.- New
CCREPL_ReadLineTimeout(nSecs)helper. Poll-based stdin
reader that wakes every 500 ms via the new
CCCON_StdInWait( nMs )C primitive (POSIXselect()on
STDIN_FILENOinsrc/ccconsole_posix.c;WaitForSingleObject
on the Win32 input handle insrc/ccconsole.c). Same paste/echo
conventions asCCREPL_ReadLineso the editing experience is
unchanged when the user does type.
v0.8.19 — /compact slash command + auto context-fill warning.
New since v0.8.18
/compactslash command. Summarises the older part of the
conversation into one synthetic system note, keeping the system
prompt and the last 4 turns verbatim. A stateless one-shot call
with a strict "preserve exact paths / identifiers / errors /
code verbatim, no paraphrase, no preamble" instruction. Refuses
to compact when the very last assistant turn has a dangling
tool_call(no matchingtoolresponse yet), so a compaction
cannot orphan a tool-call id mid-cycle.- Soft "/compact" hint when context fills up. After every
successful turnCCREPL_MaybeWarnCompactcompares the last
prompt_tokensagainstcompact_threshold(default0.7) of
the model's context window and prints
[context X% full -- run /compact ...]one time. Re-armable on
/clearor after a successful/compact. Never auto-runs. - Per-model context windows.
CCREPL_ModelContextmaps the
active model to its context size (deepseek 128k, kimi-k2...
v0.8.24
CCHarbour v0.8.24 — Ollama preset default switched to llama3.1:8b + setup notes.
New since v0.8.23
/provider ollamadefault model is nowllama3.1:8b. Local
testing showedqwen2.5-coder:7b(the previous default) emits
bare JSON insidemessage.contentinstead of populating
tool_calls, so Ollama's OpenAI-compatible endpoint never
surfaces a tool call and the agent loop ends every turn with
the[hint: 0 tool calls...]warning.llama3.1:8breturns
propertool_callsthrough the same endpoint and works with
the loop end-to-end. Same caveat for the abliterated
qwen2.5-coderGGUFs floating around on Hugging Face.- Updated applied-preset message and commands.md. Three real
gotchas are now spelled out: (1)OLLAMA_CONTEXT_LENGTH=16384
is required -- the default 4096 ctx is too small for the
CCHarbour system prompt + 16 tool schemas (the request silently
hangs at the curl 120 s timeout); (2) only models that route
tool calls through the OpenAItool_callsfield actually
work with CCHarbour (llama3.1:8b,mistral-nemo:12b,
command-rconfirmed;qwen2.5-coderconfirmed broken);
(3) Ollama 0.20.x can hang on/v1/chat/completionswith
stream:trueand a populatedtoolsarray for some models --
switch model if the timeout fires.
v0.8.23 — Ollama provider preset + one-shot no-tool-call hint.
New since v0.8.22
/provider ollamapreset. Setsbase_urlto
http://localhost:11434/v1and the default model to
qwen2.5-coder:7b. The placeholder API keyollamais
auto-seeded so the agent loop does not block on the "no api
key" branch -- Ollama's OpenAI-compatible endpoint ignores
Authorization. The applied-preset message reminds the user
to runollama serve, pull the model, and pick a
tool-calling-capable model (qwen2.5-coder, llama3.1+,
mistral-nemo). UpdatedPresets:list, "no API key" banner
warning, and the playground/helpfooter to mention ollama.- No-tool-call detection.
CC_AgentRunnow returns
tool_call_count-- the total number of tool calls issued
across the whole run. After every successful turn,
CCREPL_MaybeWarnNoToolCallchecks whether the count is
zero AND the model's reply contains a phrase that suggests
the model wanted to act but could not ("I would run...", "I
cannot access...", "without access to tools", and ~15 more).
When both conditions hold, a one-shot warn-coloured hint
points at/provider model <name>with a curated list of
tool-calling models. The hint is muted permanently once any
tool call succeeds (proof of tool support);/clearand
/providerre-arm it so the next backend gets a fair
re-evaluation.
v0.8.22 — /load crash fix + working /loop and /rewind in the playground.
New since v0.8.21
- Fixed
/loadcrash.CCUI_SessionListOutputconcatenated a
Harbour DATE with a string (DToS(d) + " " + d) inside the row
formatter and raisedFatal: Argument errorthe first time
/loadwas run against a sessions directory that contained any
saved file. The bug shipped in v0.8.21. Switched to
DToC( mtime )so the date renders as a plain string. Verified
on Windows, macOS and Linux. - Playground
/rewind [N]. Pops the conversation snapshot
stack (capped at 20), restoring the message array and the
cumulative usage counter to the state before the last user
turn. Snapshots are pushed inhandleSubmitjust before the
user message is appended, so slash commands and the
API-key-missing branch do not push spurious entries. - Playground
/loop <interval> <prompt>. Arms a
setIntervalthat re-issues the prompt viahandleSubmit
every interval. Intervals accepts/m/hsuffixes;
bare numbers are seconds./loop status,/loop stopand
/loop clearmirror the native binary; ticks that would
overlap a running turn are skipped. - Playground
/clearnow resets/loopand/rewindstate.
The handler flushes the rewind stack and cancels any armed
loop alongside the existing project / conversation / usage
reset.
v0.8.21 — /loop fixed-interval rerun + /rewind (double-tap Esc).
New since v0.8.20
/loopslash command. Re-run a prompt on a fixed interval,
matching Claude Code's fixed-interval/loop./loop 5m check CI
arms a recurring turn every 5 minutes; intervals accept thes,
m,hsuffixes (a bare number is seconds)./loop/
/loop statusshows the active loop,/loop stopends it while
keeping the prompt text,/loop cleardrops both. The sleep
between turns is interruptible — pressing Esc ends the loop.
Hooks in parallel to the existing/goalauto-continue, so
/loopand/goalcan be armed independently. Model-paced
(self-scheduled) variant is not implemented in this release./rewindslash command + double-tap Esc. Undo the last
conversation turn./rewindpops one snapshot;/rewind Npops
N. A double-tap of Esc (≤ 600 ms apart) at the idle prompt is
detected inCCPROMPT_Polland converted into arewind
interrupt kind, whichCCREPL_PromptIdlereturns as the literal
/rewind. Snapshots are pushed before each user message,
/init,/btwdrain message, and/looprunner turn; the
stack is capped at 20 entries (oldest falls off the bottom).
Restored state coversaMsgs,s_cGoal,s_lGoalLooping,
s_cLoopPrompt,s_nLoopIntervalSec,s_lLoopActive,
s_lPlanMode,s_lLeanMode,s_hSessionUsage, and
s_lCompactNudged./clearand/loadflush the stack. File
modifications made bywrite/edit/shellare NOT rolled
back — only the conversation.
v0.8.20 — Ask-prompt deadlock fix: non-TTY auto-deny + CCHARBOUR_ASK_TIMEOUT.
New since v0.8.19
- Non-TTY auto-deny on
askprompts. When a tool gatedask
fires andstdinis not a TTY (piped input,script -c, a
background SSHexec_command, a CI runner),CCREPL_AskPerm
used to call the line reader anyway and block forever — no human
was at the keyboard to typey. Now the path is short-circuited
with a one-line[non-interactive stdin -- '<tool>' denied]
notice and the call is denied immediately, so the agent loop
surfaces anError: tool ... denied by userresult and keeps
moving instead of hanging. CCHARBOUR_ASK_TIMEOUTenv var. Bounds the wait even on a
real TTY. Set to a positive integer number of seconds; if no
answer is typed before the deadline, the REPL prints
[no response in Ns -- denied]and the call is denied. Default
(unset or0) keeps the original blocking behaviour. Both safety
nets fall back to deny — a missing human can never silently
approve.- New
CCREPL_ReadLineTimeout(nSecs)helper. Poll-based stdin
reader that wakes every 500 ms via the new
CCCON_StdInWait( nMs )C primitive (POSIXselect()on
STDIN_FILENOinsrc/ccconsole_posix.c;WaitForSingleObject
on the Win32 input handle insrc/ccconsole.c). Same paste/echo
conventions asCCREPL_ReadLineso the editing experience is
unchanged when the user does type.
v0.8.19 — /compact slash command + auto context-fill warning.
New since v0.8.18
/compactslash command. Summarises the older part of the
conversation into one synthetic system note, keeping the system
prompt and the last 4 turns verbatim. A stateless one-shot call
with a strict "preserve exact paths / identifiers / errors /
code verbatim, no paraphrase, no preamble" instruction. Refuses
to compact when the very last assistant turn has a dangling
tool_call(no matchingtoolresponse yet), so a compaction
cannot orphan a tool-call id mid-cycle.- Soft "/compact" hint when context fills up. After every
successful turnCCREPL_MaybeWarnCompactcompares the last
prompt_tokensagainstcompact_threshold(default0.7) of
the model's context window and prints
[context X% full -- run /compact ...]one time. Re-armable on
/clearor after a successful/compact. Never auto-runs. - Per-model context windows.
CCREPL_ModelContextmaps the
active model to its context size (deepseek 128k, kimi-k2 200k,
gpt-5 400k, ...) with a 32k fallback. compact_thresholdsetting. New0.7default in
CCSETTINGS_Defaults; users can tune it per project.dispatch_agent_backgroundungated. Added to the never-gated
list inCCPERM_Decidealongsidedispatch_agent/
propose_agents— same consent model.
v0.8.18 — Background subagents: dispatch_agent_background tool + /tasks slash command.
New since v0.8.17
dispatch_agent_backgroundtool. Fire-and-forget variant of
dispatch_agent. Returns a task-id (bg1,bg2, ...) IMMEDIATELY
without blocking the parent. A freshhb_threadStartworker runs
CC_AgentRunin the background and writes progress into an in-
memory registry; the parent agent can chain its next step right
away.- Background-task registry (
src/ccbg.prg). Mutex-protected
hash keyed by task id. Each record carriesid,type,prompt,
timeout,status(queued/running/done/failed/
cancelled/timed_out),started_ms,ended_ms,
iterations,reply,error,cancel_requested. Public API:
CCBG_NextId / Add / Update / Get / List / Kill / CancelRequested / ClearFinished. Workers MUST NOT touch the terminal (that would
corrupt the dynamic input box); the main REPL polls the registry. /tasksslash command. The user's only window into the
registry:/tasks-- tabular list (id, status, elapsed, type, prompt
summary)./tasks view <id>-- full record including reply / error./tasks kill <id>-- request cancel; worker exits a...
v0.8.23
CCHarbour v0.8.23 — Ollama provider preset + one-shot no-tool-call hint.
New since v0.8.22
/provider ollamapreset. Setsbase_urlto
http://localhost:11434/v1and the default model to
qwen2.5-coder:7b. The placeholder API keyollamais
auto-seeded so the agent loop does not block on the "no api
key" branch -- Ollama's OpenAI-compatible endpoint ignores
Authorization. The applied-preset message reminds the user
to runollama serve, pull the model, and pick a
tool-calling-capable model (qwen2.5-coder, llama3.1+,
mistral-nemo). UpdatedPresets:list, "no API key" banner
warning, and the playground/helpfooter to mention ollama.- No-tool-call detection.
CC_AgentRunnow returns
tool_call_count-- the total number of tool calls issued
across the whole run. After every successful turn,
CCREPL_MaybeWarnNoToolCallchecks whether the count is
zero AND the model's reply contains a phrase that suggests
the model wanted to act but could not ("I would run...", "I
cannot access...", "without access to tools", and ~15 more).
When both conditions hold, a one-shot warn-coloured hint
points at/provider model <name>with a curated list of
tool-calling models. The hint is muted permanently once any
tool call succeeds (proof of tool support);/clearand
/providerre-arm it so the next backend gets a fair
re-evaluation.
v0.8.22 — /load crash fix + working /loop and /rewind in the playground.
New since v0.8.21
- Fixed
/loadcrash.CCUI_SessionListOutputconcatenated a
Harbour DATE with a string (DToS(d) + " " + d) inside the row
formatter and raisedFatal: Argument errorthe first time
/loadwas run against a sessions directory that contained any
saved file. The bug shipped in v0.8.21. Switched to
DToC( mtime )so the date renders as a plain string. Verified
on Windows, macOS and Linux. - Playground
/rewind [N]. Pops the conversation snapshot
stack (capped at 20), restoring the message array and the
cumulative usage counter to the state before the last user
turn. Snapshots are pushed inhandleSubmitjust before the
user message is appended, so slash commands and the
API-key-missing branch do not push spurious entries. - Playground
/loop <interval> <prompt>. Arms a
setIntervalthat re-issues the prompt viahandleSubmit
every interval. Intervals accepts/m/hsuffixes;
bare numbers are seconds./loop status,/loop stopand
/loop clearmirror the native binary; ticks that would
overlap a running turn are skipped. - Playground
/clearnow resets/loopand/rewindstate.
The handler flushes the rewind stack and cancels any armed
loop alongside the existing project / conversation / usage
reset.
v0.8.21 — /loop fixed-interval rerun + /rewind (double-tap Esc).
New since v0.8.20
/loopslash command. Re-run a prompt on a fixed interval,
matching Claude Code's fixed-interval/loop./loop 5m check CI
arms a recurring turn every 5 minutes; intervals accept thes,
m,hsuffixes (a bare number is seconds)./loop/
/loop statusshows the active loop,/loop stopends it while
keeping the prompt text,/loop cleardrops both. The sleep
between turns is interruptible — pressing Esc ends the loop.
Hooks in parallel to the existing/goalauto-continue, so
/loopand/goalcan be armed independently. Model-paced
(self-scheduled) variant is not implemented in this release./rewindslash command + double-tap Esc. Undo the last
conversation turn./rewindpops one snapshot;/rewind Npops
N. A double-tap of Esc (≤ 600 ms apart) at the idle prompt is
detected inCCPROMPT_Polland converted into arewind
interrupt kind, whichCCREPL_PromptIdlereturns as the literal
/rewind. Snapshots are pushed before each user message,
/init,/btwdrain message, and/looprunner turn; the
stack is capped at 20 entries (oldest falls off the bottom).
Restored state coversaMsgs,s_cGoal,s_lGoalLooping,
s_cLoopPrompt,s_nLoopIntervalSec,s_lLoopActive,
s_lPlanMode,s_lLeanMode,s_hSessionUsage, and
s_lCompactNudged./clearand/loadflush the stack. File
modifications made bywrite/edit/shellare NOT rolled
back — only the conversation.
v0.8.20 — Ask-prompt deadlock fix: non-TTY auto-deny + CCHARBOUR_ASK_TIMEOUT.
New since v0.8.19
- Non-TTY auto-deny on
askprompts. When a tool gatedask
fires andstdinis not a TTY (piped input,script -c, a
background SSHexec_command, a CI runner),CCREPL_AskPerm
used to call the line reader anyway and block forever — no human
was at the keyboard to typey. Now the path is short-circuited
with a one-line[non-interactive stdin -- '<tool>' denied]
notice and the call is denied immediately, so the agent loop
surfaces anError: tool ... denied by userresult and keeps
moving instead of hanging. CCHARBOUR_ASK_TIMEOUTenv var. Bounds the wait even on a
real TTY. Set to a positive integer number of seconds; if no
answer is typed before the deadline, the REPL prints
[no response in Ns -- denied]and the call is denied. Default
(unset or0) keeps the original blocking behaviour. Both safety
nets fall back to deny — a missing human can never silently
approve.- New
CCREPL_ReadLineTimeout(nSecs)helper. Poll-based stdin
reader that wakes every 500 ms via the new
CCCON_StdInWait( nMs )C primitive (POSIXselect()on
STDIN_FILENOinsrc/ccconsole_posix.c;WaitForSingleObject
on the Win32 input handle insrc/ccconsole.c). Same paste/echo
conventions asCCREPL_ReadLineso the editing experience is
unchanged when the user does type.
v0.8.19 — /compact slash command + auto context-fill warning.
New since v0.8.18
/compactslash command. Summarises the older part of the
conversation into one synthetic system note, keeping the system
prompt and the last 4 turns verbatim. A stateless one-shot call
with a strict "preserve exact paths / identifiers / errors /
code verbatim, no paraphrase, no preamble" instruction. Refuses
to compact when the very last assistant turn has a dangling
tool_call(no matchingtoolresponse yet), so a compaction
cannot orphan a tool-call id mid-cycle.- Soft "/compact" hint when context fills up. After every
successful turnCCREPL_MaybeWarnCompactcompares the last
prompt_tokensagainstcompact_threshold(default0.7) of
the model's context window and prints
[context X% full -- run /compact ...]one time. Re-armable on
/clearor after a successful/compact. Never auto-runs. - Per-model context windows.
CCREPL_ModelContextmaps the
active model to its context size (deepseek 128k, kimi-k2 200k,
gpt-5 400k, ...) with a 32k fallback. compact_thresholdsetting. New0.7default in
CCSETTINGS_Defaults; users can tune it per project.dispatch_agent_backgroundungated. Added to the never-gated
list inCCPERM_Decidealongsidedispatch_agent/
propose_agents— same consent model.
v0.8.18 — Background subagents: dispatch_agent_background tool + /tasks slash command.
New since v0.8.17
dispatch_agent_backgroundtool. Fire-and-forget variant of
dispatch_agent. Returns a task-id (bg1,bg2, ...) IMMEDIATELY
without blocking the parent. A freshhb_threadStartworker runs
CC_AgentRunin the background and writes progress into an in-
memory registry; the parent agent can chain its next step right
away.- Background-task registry (
src/ccbg.prg). Mutex-protected
hash keyed by task id. Each record carriesid,type,prompt,
timeout,status(queued/running/done/failed/
cancelled/timed_out),started_ms,ended_ms,
iterations,reply,error,cancel_requested. Public API:
CCBG_NextId / Add / Update / Get / List / Kill / CancelRequested / ClearFinished. Workers MUST NOT touch the terminal (that would
corrupt the dynamic input box); the main REPL polls the registry. /tasksslash command. The user's only window into the
registry:/tasks-- tabular list (id, status, elapsed, type, prompt
summary)./tasks view <id>-- full record including reply / error./tasks kill <id>-- request cancel; worker exits at next
agent-loop boundary./tasks clear-- drop every finished / failed / cancelled
/ timed-out record.
- Subagent filter widened.
CCTOOLS_FilterForAgentremoves BOTH
dispatch_agentanddispatch_agent_backgroundfrom a subagent's
registry, so a subagent cannot spawn its own subagents (no
unbounded recursion). - Help, README and
pages/commands.mdupdated with the new
command rows.
v0.8.17 — /save and /load now round-trip the full session state: goal, modes, skills, timer, and the pending suggestion.
New since v0.8.16
- /save / /load preserve every REPL-level static, not just the
conversation. Saved JSON now carries a newstateblock plus a
suggeststring in addition tomodel/usage/messages.
/loadrestores them on top of the conversation so a reload is
truly a full snapshot. stateblock.CCREPL_StateExport()packs the current
goal,goal_looping,session_turn_ms,plan_mode,lean_mode,
andskills(active skill names) into a primitive hash.
CCREPL_StateImport( hState )reapplies them, silently skipping
missing keys so legacy session files still load cleanly.suggestfield. The pending "Suggested next:" prompt that the
model emitted on its last turn is persisted alongside...
v0.8.22
CCHarbour v0.8.22 — /load crash fix + working /loop and /rewind in the playground.
New since v0.8.21
- Fixed
/loadcrash.CCUI_SessionListOutputconcatenated a
Harbour DATE with a string (DToS(d) + " " + d) inside the row
formatter and raisedFatal: Argument errorthe first time
/loadwas run against a sessions directory that contained any
saved file. The bug shipped in v0.8.21. Switched to
DToC( mtime )so the date renders as a plain string. Verified
on Windows, macOS and Linux. - Playground
/rewind [N]. Pops the conversation snapshot
stack (capped at 20), restoring the message array and the
cumulative usage counter to the state before the last user
turn. Snapshots are pushed inhandleSubmitjust before the
user message is appended, so slash commands and the
API-key-missing branch do not push spurious entries. - Playground
/loop <interval> <prompt>. Arms a
setIntervalthat re-issues the prompt viahandleSubmit
every interval. Intervals accepts/m/hsuffixes;
bare numbers are seconds./loop status,/loop stopand
/loop clearmirror the native binary; ticks that would
overlap a running turn are skipped. - Playground
/clearnow resets/loopand/rewindstate.
The handler flushes the rewind stack and cancels any armed
loop alongside the existing project / conversation / usage
reset.
v0.8.21 — /loop fixed-interval rerun + /rewind (double-tap Esc).
New since v0.8.20
/loopslash command. Re-run a prompt on a fixed interval,
matching Claude Code's fixed-interval/loop./loop 5m check CI
arms a recurring turn every 5 minutes; intervals accept thes,
m,hsuffixes (a bare number is seconds)./loop/
/loop statusshows the active loop,/loop stopends it while
keeping the prompt text,/loop cleardrops both. The sleep
between turns is interruptible — pressing Esc ends the loop.
Hooks in parallel to the existing/goalauto-continue, so
/loopand/goalcan be armed independently. Model-paced
(self-scheduled) variant is not implemented in this release./rewindslash command + double-tap Esc. Undo the last
conversation turn./rewindpops one snapshot;/rewind Npops
N. A double-tap of Esc (≤ 600 ms apart) at the idle prompt is
detected inCCPROMPT_Polland converted into arewind
interrupt kind, whichCCREPL_PromptIdlereturns as the literal
/rewind. Snapshots are pushed before each user message,
/init,/btwdrain message, and/looprunner turn; the
stack is capped at 20 entries (oldest falls off the bottom).
Restored state coversaMsgs,s_cGoal,s_lGoalLooping,
s_cLoopPrompt,s_nLoopIntervalSec,s_lLoopActive,
s_lPlanMode,s_lLeanMode,s_hSessionUsage, and
s_lCompactNudged./clearand/loadflush the stack. File
modifications made bywrite/edit/shellare NOT rolled
back — only the conversation.
v0.8.20 — Ask-prompt deadlock fix: non-TTY auto-deny + CCHARBOUR_ASK_TIMEOUT.
New since v0.8.19
- Non-TTY auto-deny on
askprompts. When a tool gatedask
fires andstdinis not a TTY (piped input,script -c, a
background SSHexec_command, a CI runner),CCREPL_AskPerm
used to call the line reader anyway and block forever — no human
was at the keyboard to typey. Now the path is short-circuited
with a one-line[non-interactive stdin -- '<tool>' denied]
notice and the call is denied immediately, so the agent loop
surfaces anError: tool ... denied by userresult and keeps
moving instead of hanging. CCHARBOUR_ASK_TIMEOUTenv var. Bounds the wait even on a
real TTY. Set to a positive integer number of seconds; if no
answer is typed before the deadline, the REPL prints
[no response in Ns -- denied]and the call is denied. Default
(unset or0) keeps the original blocking behaviour. Both safety
nets fall back to deny — a missing human can never silently
approve.- New
CCREPL_ReadLineTimeout(nSecs)helper. Poll-based stdin
reader that wakes every 500 ms via the new
CCCON_StdInWait( nMs )C primitive (POSIXselect()on
STDIN_FILENOinsrc/ccconsole_posix.c;WaitForSingleObject
on the Win32 input handle insrc/ccconsole.c). Same paste/echo
conventions asCCREPL_ReadLineso the editing experience is
unchanged when the user does type.
v0.8.19 — /compact slash command + auto context-fill warning.
New since v0.8.18
/compactslash command. Summarises the older part of the
conversation into one synthetic system note, keeping the system
prompt and the last 4 turns verbatim. A stateless one-shot call
with a strict "preserve exact paths / identifiers / errors /
code verbatim, no paraphrase, no preamble" instruction. Refuses
to compact when the very last assistant turn has a dangling
tool_call(no matchingtoolresponse yet), so a compaction
cannot orphan a tool-call id mid-cycle.- Soft "/compact" hint when context fills up. After every
successful turnCCREPL_MaybeWarnCompactcompares the last
prompt_tokensagainstcompact_threshold(default0.7) of
the model's context window and prints
[context X% full -- run /compact ...]one time. Re-armable on
/clearor after a successful/compact. Never auto-runs. - Per-model context windows.
CCREPL_ModelContextmaps the
active model to its context size (deepseek 128k, kimi-k2 200k,
gpt-5 400k, ...) with a 32k fallback. compact_thresholdsetting. New0.7default in
CCSETTINGS_Defaults; users can tune it per project.dispatch_agent_backgroundungated. Added to the never-gated
list inCCPERM_Decidealongsidedispatch_agent/
propose_agents— same consent model.
v0.8.18 — Background subagents: dispatch_agent_background tool + /tasks slash command.
New since v0.8.17
dispatch_agent_backgroundtool. Fire-and-forget variant of
dispatch_agent. Returns a task-id (bg1,bg2, ...) IMMEDIATELY
without blocking the parent. A freshhb_threadStartworker runs
CC_AgentRunin the background and writes progress into an in-
memory registry; the parent agent can chain its next step right
away.- Background-task registry (
src/ccbg.prg). Mutex-protected
hash keyed by task id. Each record carriesid,type,prompt,
timeout,status(queued/running/done/failed/
cancelled/timed_out),started_ms,ended_ms,
iterations,reply,error,cancel_requested. Public API:
CCBG_NextId / Add / Update / Get / List / Kill / CancelRequested / ClearFinished. Workers MUST NOT touch the terminal (that would
corrupt the dynamic input box); the main REPL polls the registry. /tasksslash command. The user's only window into the
registry:/tasks-- tabular list (id, status, elapsed, type, prompt
summary)./tasks view <id>-- full record including reply / error./tasks kill <id>-- request cancel; worker exits at next
agent-loop boundary./tasks clear-- drop every finished / failed / cancelled
/ timed-out record.
- Subagent filter widened.
CCTOOLS_FilterForAgentremoves BOTH
dispatch_agentanddispatch_agent_backgroundfrom a subagent's
registry, so a subagent cannot spawn its own subagents (no
unbounded recursion). - Help, README and
pages/commands.mdupdated with the new
command rows.
v0.8.17 — /save and /load now round-trip the full session state: goal, modes, skills, timer, and the pending suggestion.
New since v0.8.16
- /save / /load preserve every REPL-level static, not just the
conversation. Saved JSON now carries a newstateblock plus a
suggeststring in addition tomodel/usage/messages.
/loadrestores them on top of the conversation so a reload is
truly a full snapshot. stateblock.CCREPL_StateExport()packs the current
goal,goal_looping,session_turn_ms,plan_mode,lean_mode,
andskills(active skill names) into a primitive hash.
CCREPL_StateImport( hState )reapplies them, silently skipping
missing keys so legacy session files still load cleanly.suggestfield. The pending "Suggested next:" prompt that the
model emitted on its last turn is persisted alongside the messages
and re-seeded into the editor on the first idle frame after
/load, so the green Tab-acceptable preview survives a restart.CCSKILL_ClearAll(). New helper that drops every active skill
in one shot; called byCCREPL_StateImportbefore re-activating the
loaded skill list so the restored set takes over from whatever was
active.
v0.8.16 — /goal turns into "keep working until the condition is met": auto-continue loop + GOAL COMPLETE sentinel.
New since v0.8.15
- /goal redesigned around "keep working until the condition is met".
Setting a goal now arms an auto-continue loop in the main REPL:
after every user-initiated turn the loop scans the last assistant
reply for a literalGOAL COMPLETEsentinel. If absent it auto-
feedsContinue toward the goal. ...reply with ONLY the literal sentinel...as the next user message and runs another turn. - GOAL COMPLETE sentinel. The injected system note teaches the
model to emitGOAL COMPLETEon its own line when the condition
is met.CCREPL_GoalDone( cReply )checks the substring. - CC_GOAL_AUTO_CAP = 25. Hard cap on auto-iterations per user
turn so a stubborn model cannot loop forever; the REPL prints
[goal auto-continue cap (25) hit ...]when it trips. - Esc pauses the loop.
CCREPL_RunGoalLoopdrains the
CCPROMPT_Interruptedflag and disarmss_lGoalLooping...
v0.8.21
CCHarbour v0.8.21 — /loop fixed-interval rerun + /rewind (double-tap Esc).
New since v0.8.20
/loopslash command. Re-run a prompt on a fixed interval,
matching Claude Code's fixed-interval/loop./loop 5m check CI
arms a recurring turn every 5 minutes; intervals accept thes,
m,hsuffixes (a bare number is seconds)./loop/
/loop statusshows the active loop,/loop stopends it while
keeping the prompt text,/loop cleardrops both. The sleep
between turns is interruptible — pressing Esc ends the loop.
Hooks in parallel to the existing/goalauto-continue, so
/loopand/goalcan be armed independently. Model-paced
(self-scheduled) variant is not implemented in this release./rewindslash command + double-tap Esc. Undo the last
conversation turn./rewindpops one snapshot;/rewind Npops
N. A double-tap of Esc (≤ 600 ms apart) at the idle prompt is
detected inCCPROMPT_Polland converted into arewind
interrupt kind, whichCCREPL_PromptIdlereturns as the literal
/rewind. Snapshots are pushed before each user message,
/init,/btwdrain message, and/looprunner turn; the
stack is capped at 20 entries (oldest falls off the bottom).
Restored state coversaMsgs,s_cGoal,s_lGoalLooping,
s_cLoopPrompt,s_nLoopIntervalSec,s_lLoopActive,
s_lPlanMode,s_lLeanMode,s_hSessionUsage, and
s_lCompactNudged./clearand/loadflush the stack. File
modifications made bywrite/edit/shellare NOT rolled
back — only the conversation.
v0.8.20 — Ask-prompt deadlock fix: non-TTY auto-deny + CCHARBOUR_ASK_TIMEOUT.
New since v0.8.19
- Non-TTY auto-deny on
askprompts. When a tool gatedask
fires andstdinis not a TTY (piped input,script -c, a
background SSHexec_command, a CI runner),CCREPL_AskPerm
used to call the line reader anyway and block forever — no human
was at the keyboard to typey. Now the path is short-circuited
with a one-line[non-interactive stdin -- '<tool>' denied]
notice and the call is denied immediately, so the agent loop
surfaces anError: tool ... denied by userresult and keeps
moving instead of hanging. CCHARBOUR_ASK_TIMEOUTenv var. Bounds the wait even on a
real TTY. Set to a positive integer number of seconds; if no
answer is typed before the deadline, the REPL prints
[no response in Ns -- denied]and the call is denied. Default
(unset or0) keeps the original blocking behaviour. Both safety
nets fall back to deny — a missing human can never silently
approve.- New
CCREPL_ReadLineTimeout(nSecs)helper. Poll-based stdin
reader that wakes every 500 ms via the new
CCCON_StdInWait( nMs )C primitive (POSIXselect()on
STDIN_FILENOinsrc/ccconsole_posix.c;WaitForSingleObject
on the Win32 input handle insrc/ccconsole.c). Same paste/echo
conventions asCCREPL_ReadLineso the editing experience is
unchanged when the user does type.
v0.8.19 — /compact slash command + auto context-fill warning.
New since v0.8.18
/compactslash command. Summarises the older part of the
conversation into one synthetic system note, keeping the system
prompt and the last 4 turns verbatim. A stateless one-shot call
with a strict "preserve exact paths / identifiers / errors /
code verbatim, no paraphrase, no preamble" instruction. Refuses
to compact when the very last assistant turn has a dangling
tool_call(no matchingtoolresponse yet), so a compaction
cannot orphan a tool-call id mid-cycle.- Soft "/compact" hint when context fills up. After every
successful turnCCREPL_MaybeWarnCompactcompares the last
prompt_tokensagainstcompact_threshold(default0.7) of
the model's context window and prints
[context X% full -- run /compact ...]one time. Re-armable on
/clearor after a successful/compact. Never auto-runs. - Per-model context windows.
CCREPL_ModelContextmaps the
active model to its context size (deepseek 128k, kimi-k2 200k,
gpt-5 400k, ...) with a 32k fallback. compact_thresholdsetting. New0.7default in
CCSETTINGS_Defaults; users can tune it per project.dispatch_agent_backgroundungated. Added to the never-gated
list inCCPERM_Decidealongsidedispatch_agent/
propose_agents— same consent model.
v0.8.18 — Background subagents: dispatch_agent_background tool + /tasks slash command.
New since v0.8.17
dispatch_agent_backgroundtool. Fire-and-forget variant of
dispatch_agent. Returns a task-id (bg1,bg2, ...) IMMEDIATELY
without blocking the parent. A freshhb_threadStartworker runs
CC_AgentRunin the background and writes progress into an in-
memory registry; the parent agent can chain its next step right
away.- Background-task registry (
src/ccbg.prg). Mutex-protected
hash keyed by task id. Each record carriesid,type,prompt,
timeout,status(queued/running/done/failed/
cancelled/timed_out),started_ms,ended_ms,
iterations,reply,error,cancel_requested. Public API:
CCBG_NextId / Add / Update / Get / List / Kill / CancelRequested / ClearFinished. Workers MUST NOT touch the terminal (that would
corrupt the dynamic input box); the main REPL polls the registry. /tasksslash command. The user's only window into the
registry:/tasks-- tabular list (id, status, elapsed, type, prompt
summary)./tasks view <id>-- full record including reply / error./tasks kill <id>-- request cancel; worker exits at next
agent-loop boundary./tasks clear-- drop every finished / failed / cancelled
/ timed-out record.
- Subagent filter widened.
CCTOOLS_FilterForAgentremoves BOTH
dispatch_agentanddispatch_agent_backgroundfrom a subagent's
registry, so a subagent cannot spawn its own subagents (no
unbounded recursion). - Help, README and
pages/commands.mdupdated with the new
command rows.
v0.8.17 — /save and /load now round-trip the full session state: goal, modes, skills, timer, and the pending suggestion.
New since v0.8.16
- /save / /load preserve every REPL-level static, not just the
conversation. Saved JSON now carries a newstateblock plus a
suggeststring in addition tomodel/usage/messages.
/loadrestores them on top of the conversation so a reload is
truly a full snapshot. stateblock.CCREPL_StateExport()packs the current
goal,goal_looping,session_turn_ms,plan_mode,lean_mode,
andskills(active skill names) into a primitive hash.
CCREPL_StateImport( hState )reapplies them, silently skipping
missing keys so legacy session files still load cleanly.suggestfield. The pending "Suggested next:" prompt that the
model emitted on its last turn is persisted alongside the messages
and re-seeded into the editor on the first idle frame after
/load, so the green Tab-acceptable preview survives a restart.CCSKILL_ClearAll(). New helper that drops every active skill
in one shot; called byCCREPL_StateImportbefore re-activating the
loaded skill list so the restored set takes over from whatever was
active.
v0.8.16 — /goal turns into "keep working until the condition is met": auto-continue loop + GOAL COMPLETE sentinel.
New since v0.8.15
- /goal redesigned around "keep working until the condition is met".
Setting a goal now arms an auto-continue loop in the main REPL:
after every user-initiated turn the loop scans the last assistant
reply for a literalGOAL COMPLETEsentinel. If absent it auto-
feedsContinue toward the goal. ...reply with ONLY the literal sentinel...as the next user message and runs another turn. - GOAL COMPLETE sentinel. The injected system note teaches the
model to emitGOAL COMPLETEon its own line when the condition
is met.CCREPL_GoalDone( cReply )checks the substring. - CC_GOAL_AUTO_CAP = 25. Hard cap on auto-iterations per user
turn so a stubborn model cannot loop forever; the REPL prints
[goal auto-continue cap (25) hit ...]when it trips. - Esc pauses the loop.
CCREPL_RunGoalLoopdrains the
CCPROMPT_Interruptedflag and disarmss_lGoalLoopingwithout
dropping the goal text --[goal auto-continue paused by Esc -- /goal <text> or a new message to restart]. /goal stop. New sub-command that pauses the auto-continue
loop without clearing the goal text (so the badge stays on).
/goal clearstill drops the goal entirely and disarms the loop.- Per-iteration progress line.
[goal auto-continue N/25]prints
before each automatic turn so the user can see the loop ticking.
v0.8.15 — /goal slash command: pin a session-wide objective the agent carries through every turn.
New since v0.8.14
/goalslash command. Pins a session-wide objective the agent
carries through every subsequent turn until it is changed or
cleared:/goal— show the current goal (or(none))./goal <text>— store the goal AND inject it into the
conversation as a system note, so the model sees the intent on
the very next request without re-sending the goal on every
turn./goal clear(alias/goal off) — drop the goal and tell the
model to stop treating it as a constraint.
[goal]badge. When a goal is set, the status line under the
input box shows a[goal]tag alongside[plan-mode]/[lean]./clearresets the goal too. Resetting the conversation also
clears the session goal and the session-turn timer accumulator, so
the next session starts blank...
v0.8.20
CCHarbour v0.8.20 — Ask-prompt deadlock fix: non-TTY auto-deny + CCHARBOUR_ASK_TIMEOUT.
New since v0.8.19
- Non-TTY auto-deny on
askprompts. When a tool gatedask
fires andstdinis not a TTY (piped input,script -c, a
background SSHexec_command, a CI runner),CCREPL_AskPerm
used to call the line reader anyway and block forever — no human
was at the keyboard to typey. Now the path is short-circuited
with a one-line[non-interactive stdin -- '<tool>' denied]
notice and the call is denied immediately, so the agent loop
surfaces anError: tool ... denied by userresult and keeps
moving instead of hanging. CCHARBOUR_ASK_TIMEOUTenv var. Bounds the wait even on a
real TTY. Set to a positive integer number of seconds; if no
answer is typed before the deadline, the REPL prints
[no response in Ns -- denied]and the call is denied. Default
(unset or0) keeps the original blocking behaviour. Both safety
nets fall back to deny — a missing human can never silently
approve.- New
CCREPL_ReadLineTimeout(nSecs)helper. Poll-based stdin
reader that wakes every 500 ms via the new
CCCON_StdInWait( nMs )C primitive (POSIXselect()on
STDIN_FILENOinsrc/ccconsole_posix.c;WaitForSingleObject
on the Win32 input handle insrc/ccconsole.c). Same paste/echo
conventions asCCREPL_ReadLineso the editing experience is
unchanged when the user does type.
v0.8.19 — /compact slash command + auto context-fill warning.
New since v0.8.18
/compactslash command. Summarises the older part of the
conversation into one synthetic system note, keeping the system
prompt and the last 4 turns verbatim. A stateless one-shot call
with a strict "preserve exact paths / identifiers / errors /
code verbatim, no paraphrase, no preamble" instruction. Refuses
to compact when the very last assistant turn has a dangling
tool_call(no matchingtoolresponse yet), so a compaction
cannot orphan a tool-call id mid-cycle.- Soft "/compact" hint when context fills up. After every
successful turnCCREPL_MaybeWarnCompactcompares the last
prompt_tokensagainstcompact_threshold(default0.7) of
the model's context window and prints
[context X% full -- run /compact ...]one time. Re-armable on
/clearor after a successful/compact. Never auto-runs. - Per-model context windows.
CCREPL_ModelContextmaps the
active model to its context size (deepseek 128k, kimi-k2 200k,
gpt-5 400k, ...) with a 32k fallback. compact_thresholdsetting. New0.7default in
CCSETTINGS_Defaults; users can tune it per project.dispatch_agent_backgroundungated. Added to the never-gated
list inCCPERM_Decidealongsidedispatch_agent/
propose_agents— same consent model.
v0.8.18 — Background subagents: dispatch_agent_background tool + /tasks slash command.
New since v0.8.17
dispatch_agent_backgroundtool. Fire-and-forget variant of
dispatch_agent. Returns a task-id (bg1,bg2, ...) IMMEDIATELY
without blocking the parent. A freshhb_threadStartworker runs
CC_AgentRunin the background and writes progress into an in-
memory registry; the parent agent can chain its next step right
away.- Background-task registry (
src/ccbg.prg). Mutex-protected
hash keyed by task id. Each record carriesid,type,prompt,
timeout,status(queued/running/done/failed/
cancelled/timed_out),started_ms,ended_ms,
iterations,reply,error,cancel_requested. Public API:
CCBG_NextId / Add / Update / Get / List / Kill / CancelRequested / ClearFinished. Workers MUST NOT touch the terminal (that would
corrupt the dynamic input box); the main REPL polls the registry. /tasksslash command. The user's only window into the
registry:/tasks-- tabular list (id, status, elapsed, type, prompt
summary)./tasks view <id>-- full record including reply / error./tasks kill <id>-- request cancel; worker exits at next
agent-loop boundary./tasks clear-- drop every finished / failed / cancelled
/ timed-out record.
- Subagent filter widened.
CCTOOLS_FilterForAgentremoves BOTH
dispatch_agentanddispatch_agent_backgroundfrom a subagent's
registry, so a subagent cannot spawn its own subagents (no
unbounded recursion). - Help, README and
pages/commands.mdupdated with the new
command rows.
v0.8.17 — /save and /load now round-trip the full session state: goal, modes, skills, timer, and the pending suggestion.
New since v0.8.16
- /save / /load preserve every REPL-level static, not just the
conversation. Saved JSON now carries a newstateblock plus a
suggeststring in addition tomodel/usage/messages.
/loadrestores them on top of the conversation so a reload is
truly a full snapshot. stateblock.CCREPL_StateExport()packs the current
goal,goal_looping,session_turn_ms,plan_mode,lean_mode,
andskills(active skill names) into a primitive hash.
CCREPL_StateImport( hState )reapplies them, silently skipping
missing keys so legacy session files still load cleanly.suggestfield. The pending "Suggested next:" prompt that the
model emitted on its last turn is persisted alongside the messages
and re-seeded into the editor on the first idle frame after
/load, so the green Tab-acceptable preview survives a restart.CCSKILL_ClearAll(). New helper that drops every active skill
in one shot; called byCCREPL_StateImportbefore re-activating the
loaded skill list so the restored set takes over from whatever was
active.
v0.8.16 — /goal turns into "keep working until the condition is met": auto-continue loop + GOAL COMPLETE sentinel.
New since v0.8.15
- /goal redesigned around "keep working until the condition is met".
Setting a goal now arms an auto-continue loop in the main REPL:
after every user-initiated turn the loop scans the last assistant
reply for a literalGOAL COMPLETEsentinel. If absent it auto-
feedsContinue toward the goal. ...reply with ONLY the literal sentinel...as the next user message and runs another turn. - GOAL COMPLETE sentinel. The injected system note teaches the
model to emitGOAL COMPLETEon its own line when the condition
is met.CCREPL_GoalDone( cReply )checks the substring. - CC_GOAL_AUTO_CAP = 25. Hard cap on auto-iterations per user
turn so a stubborn model cannot loop forever; the REPL prints
[goal auto-continue cap (25) hit ...]when it trips. - Esc pauses the loop.
CCREPL_RunGoalLoopdrains the
CCPROMPT_Interruptedflag and disarmss_lGoalLoopingwithout
dropping the goal text --[goal auto-continue paused by Esc -- /goal <text> or a new message to restart]. /goal stop. New sub-command that pauses the auto-continue
loop without clearing the goal text (so the badge stays on).
/goal clearstill drops the goal entirely and disarms the loop.- Per-iteration progress line.
[goal auto-continue N/25]prints
before each automatic turn so the user can see the loop ticking.
v0.8.15 — /goal slash command: pin a session-wide objective the agent carries through every turn.
New since v0.8.14
/goalslash command. Pins a session-wide objective the agent
carries through every subsequent turn until it is changed or
cleared:/goal— show the current goal (or(none))./goal <text>— store the goal AND inject it into the
conversation as a system note, so the model sees the intent on
the very next request without re-sending the goal on every
turn./goal clear(alias/goal off) — drop the goal and tell the
model to stop treating it as a constraint.
[goal]badge. When a goal is set, the status line under the
input box shows a[goal]tag alongside[plan-mode]/[lean]./clearresets the goal too. Resetting the conversation also
clears the session goal and the session-turn timer accumulator, so
the next session starts blank.
v0.8.14 — Shell countdown lands above the box, diff bars equal width + bright-white text.
New since v0.8.13
- Shell command countdown no longer painted inside the input box.
CCTool_ShowCountdown/CCTool_ClearCountdownroute through the
CCREPL_OverwriteAtAnchorhelper when the persistent box is
mounted, sotimeout 300s · 252s leftlands on the scroll-region
anchor above the box and a trailingCCREPL_Out( Chr(10) )bakes
the final value in for the result summary. The plain-CR fallback
is kept for cooked / non-VT terminals. - Diff bars are all the same width.
CCUI_ResultBlockscans the
diff once for the widest added/removed line (floor 110), then pads
every coloured bar to that width viaCCUI_DiffPad( cLine, nWidth )
-- no more ragged edges when one line is longer than the rest. - Diff text rendered in bright white. Added lines go from SGR
37;42to97;42, removed from48;5;52to97;48;5;52-- the
red bar now matches the green bar's contrast.
v0.8.13 — Dynamic-box paint hardening, live timing in the spinner / token bar, /provider key picked up on the next turn.
New since v0.8.12
- Banner anchored at row 1.
CCREPL_RunemitsESC[H ESC[2J
before printing the banner so it is always at rows 1..N and the
CCPROMPT_Activate( nHeaderRows + 1 )anchor lands exactly below it.
Previously the banner started at the cursor's row (often row 2 after
the shellccline), so subsequent writes overwrote the banner's
bottom border. - Box paint uses absolute cursor jumps. `CC...
v0.8.19 — /compact + auto context-fill warning
CCHarbour v0.8.19 — /compact slash command + auto context-fill warning.
New since v0.8.18
/compactslash command. Summarises the older part of the
conversation into one synthetic system note, keeping the system
prompt and the last 4 turns verbatim. A stateless one-shot call
with a strict "preserve exact paths / identifiers / errors /
code verbatim, no paraphrase, no preamble" instruction. Refuses
to compact when the very last assistant turn has a dangling
tool_call(no matchingtoolresponse yet), so a compaction
cannot orphan a tool-call id mid-cycle.- Soft "/compact" hint when context fills up. After every
successful turnCCREPL_MaybeWarnCompactcompares the last
prompt_tokensagainstcompact_threshold(default0.7) of
the model's context window and prints
[context X% full -- run /compact ...]one time. Re-armable on
/clearor after a successful/compact. Never auto-runs. - Per-model context windows.
CCREPL_ModelContextmaps the
active model to its context size (deepseek 128k, kimi-k2 200k,
gpt-5 400k, ...) with a 32k fallback. compact_thresholdsetting. New0.7default in
CCSETTINGS_Defaults; users can tune it per project.dispatch_agent_backgroundungated. Added to the never-gated
list inCCPERM_Decidealongsidedispatch_agent/
propose_agents— same consent model.
v0.8.18 — Background subagents: dispatch_agent_background tool + /tasks slash command.
New since v0.8.17
dispatch_agent_backgroundtool. Fire-and-forget variant of
dispatch_agent. Returns a task-id (bg1,bg2, ...) IMMEDIATELY
without blocking the parent. A freshhb_threadStartworker runs
CC_AgentRunin the background and writes progress into an in-
memory registry; the parent agent can chain its next step right
away.- Background-task registry (
src/ccbg.prg). Mutex-protected
hash keyed by task id. Each record carriesid,type,prompt,
timeout,status(queued/running/done/failed/
cancelled/timed_out),started_ms,ended_ms,
iterations,reply,error,cancel_requested. Public API:
CCBG_NextId / Add / Update / Get / List / Kill / CancelRequested / ClearFinished. Workers MUST NOT touch the terminal (that would
corrupt the dynamic input box); the main REPL polls the registry. /tasksslash command. The user's only window into the
registry:/tasks-- tabular list (id, status, elapsed, type, prompt
summary)./tasks view <id>-- full record including reply / error./tasks kill <id>-- request cancel; worker exits at next
agent-loop boundary./tasks clear-- drop every finished / failed / cancelled
/ timed-out record.
- Subagent filter widened.
CCTOOLS_FilterForAgentremoves BOTH
dispatch_agentanddispatch_agent_backgroundfrom a subagent's
registry, so a subagent cannot spawn its own subagents (no
unbounded recursion). - Help, README and
pages/commands.mdupdated with the new
command rows.
v0.8.17 — /save and /load now round-trip the full session state: goal, modes, skills, timer, and the pending suggestion.
New since v0.8.16
- /save / /load preserve every REPL-level static, not just the
conversation. Saved JSON now carries a newstateblock plus a
suggeststring in addition tomodel/usage/messages.
/loadrestores them on top of the conversation so a reload is
truly a full snapshot. stateblock.CCREPL_StateExport()packs the current
goal,goal_looping,session_turn_ms,plan_mode,lean_mode,
andskills(active skill names) into a primitive hash.
CCREPL_StateImport( hState )reapplies them, silently skipping
missing keys so legacy session files still load cleanly.suggestfield. The pending "Suggested next:" prompt that the
model emitted on its last turn is persisted alongside the messages
and re-seeded into the editor on the first idle frame after
/load, so the green Tab-acceptable preview survives a restart.CCSKILL_ClearAll(). New helper that drops every active skill
in one shot; called byCCREPL_StateImportbefore re-activating the
loaded skill list so the restored set takes over from whatever was
active.
v0.8.16 — /goal turns into "keep working until the condition is met": auto-continue loop + GOAL COMPLETE sentinel.
New since v0.8.15
- /goal redesigned around "keep working until the condition is met".
Setting a goal now arms an auto-continue loop in the main REPL:
after every user-initiated turn the loop scans the last assistant
reply for a literalGOAL COMPLETEsentinel. If absent it auto-
feedsContinue toward the goal. ...reply with ONLY the literal sentinel...as the next user message and runs another turn. - GOAL COMPLETE sentinel. The injected system note teaches the
model to emitGOAL COMPLETEon its own line when the condition
is met.CCREPL_GoalDone( cReply )checks the substring. - CC_GOAL_AUTO_CAP = 25. Hard cap on auto-iterations per user
turn so a stubborn model cannot loop forever; the REPL prints
[goal auto-continue cap (25) hit ...]when it trips. - Esc pauses the loop.
CCREPL_RunGoalLoopdrains the
CCPROMPT_Interruptedflag and disarmss_lGoalLoopingwithout
dropping the goal text --[goal auto-continue paused by Esc -- /goal <text> or a new message to restart]. /goal stop. New sub-command that pauses the auto-continue
loop without clearing the goal text (so the badge stays on).
/goal clearstill drops the goal entirely and disarms the loop.- Per-iteration progress line.
[goal auto-continue N/25]prints
before each automatic turn so the user can see the loop ticking.
v0.8.15 — /goal slash command: pin a session-wide objective the agent carries through every turn.
New since v0.8.14
/goalslash command. Pins a session-wide objective the agent
carries through every subsequent turn until it is changed or
cleared:/goal— show the current goal (or(none))./goal <text>— store the goal AND inject it into the
conversation as a system note, so the model sees the intent on
the very next request without re-sending the goal on every
turn./goal clear(alias/goal off) — drop the goal and tell the
model to stop treating it as a constraint.
[goal]badge. When a goal is set, the status line under the
input box shows a[goal]tag alongside[plan-mode]/[lean]./clearresets the goal too. Resetting the conversation also
clears the session goal and the session-turn timer accumulator, so
the next session starts blank.
v0.8.14 — Shell countdown lands above the box, diff bars equal width + bright-white text.
New since v0.8.13
- Shell command countdown no longer painted inside the input box.
CCTool_ShowCountdown/CCTool_ClearCountdownroute through the
CCREPL_OverwriteAtAnchorhelper when the persistent box is
mounted, sotimeout 300s · 252s leftlands on the scroll-region
anchor above the box and a trailingCCREPL_Out( Chr(10) )bakes
the final value in for the result summary. The plain-CR fallback
is kept for cooked / non-VT terminals. - Diff bars are all the same width.
CCUI_ResultBlockscans the
diff once for the widest added/removed line (floor 110), then pads
every coloured bar to that width viaCCUI_DiffPad( cLine, nWidth )
-- no more ragged edges when one line is longer than the rest. - Diff text rendered in bright white. Added lines go from SGR
37;42to97;42, removed from48;5;52to97;48;5;52-- the
red bar now matches the green bar's contrast.
v0.8.13 — Dynamic-box paint hardening, live timing in the spinner / token bar, /provider key picked up on the next turn.
New since v0.8.12
- Banner anchored at row 1.
CCREPL_RunemitsESC[H ESC[2J
before printing the banner so it is always at rows 1..N and the
CCPROMPT_Activate( nHeaderRows + 1 )anchor lands exactly below it.
Previously the banner started at the cursor's row (often row 2 after
the shellccline), so subsequent writes overwrote the banner's
bottom border. - Box paint uses absolute cursor jumps.
CCPROMPT_Redrawnow
positions every row of the four-row box with an absoluteESC[<row>;1H
instead of chaining CRLFs. The CRLF chain scrolled the screen up by
one row each time the box sat near the terminal bottom, which is how
pressing Esc at the idle prompt could stack 10+ leftover╭frames
above the box. - Wipe rule rewritten. The old-box-frame wipe in
CCPROMPT_Redraw
is now[oldBoxTop .. min(oldBoxTop+3, newBoxTop-1)] minus the rows just written.CCREPL_Outstasheslast_write_startand a trailing
-LF flag so Redraw knows where the chunk actually wrote. Fixes the
FlushPending bullet ("\n + glyph + 2sp", no trailing LF) being
wiped right after it was painted, and the stale top-frame left
behind by multi-line writes (paragraph breaks in the streamed reply). - Banner scrolls when the box pins.
CCPROMPT_Regionsets
scroll_topto 1 oncebox_top == nFloor, so the VT scroll region
expands up to the top of the screen and the banner finally rolls off
the top edge as new content arrives. While the box is still
travelling the banner is still pinned (current behaviour). - Spinner shows elapsed seconds.
iteration_startstamps a wall-
clock inoRender[ "spinnerStartMs" ];CCREPL_SpinnerShowappends
Nsto the spinner line (e.g.⠦ Thinking... [32 tok] 7s). - Token bar shows turn / session seconds.
CCREPL_RunTurntimes
each turn withhb_MilliSeconds(), accumulates i...
v0.8.18 — background subagents + /tasks slash command
CCHarbour v0.8.18 — Background subagents: dispatch_agent_background tool + /tasks slash command.
New since v0.8.17
dispatch_agent_backgroundtool. Fire-and-forget variant of
dispatch_agent. Returns a task-id (bg1,bg2, ...) IMMEDIATELY
without blocking the parent. A freshhb_threadStartworker runs
CC_AgentRunin the background and writes progress into an in-
memory registry; the parent agent can chain its next step right
away.- Background-task registry (
src/ccbg.prg). Mutex-protected
hash keyed by task id. Each record carriesid,type,prompt,
timeout,status(queued/running/done/failed/
cancelled/timed_out),started_ms,ended_ms,
iterations,reply,error,cancel_requested. Public API:
CCBG_NextId / Add / Update / Get / List / Kill / CancelRequested / ClearFinished. Workers MUST NOT touch the terminal (that would
corrupt the dynamic input box); the main REPL polls the registry. /tasksslash command. The user's only window into the
registry:/tasks-- tabular list (id, status, elapsed, type, prompt
summary)./tasks view <id>-- full record including reply / error./tasks kill <id>-- request cancel; worker exits at next
agent-loop boundary./tasks clear-- drop every finished / failed / cancelled
/ timed-out record.
- Subagent filter widened.
CCTOOLS_FilterForAgentremoves BOTH
dispatch_agentanddispatch_agent_backgroundfrom a subagent's
registry, so a subagent cannot spawn its own subagents (no
unbounded recursion). - Help, README and
pages/commands.mdupdated with the new
command rows.
v0.8.17 — /save and /load now round-trip the full session state: goal, modes, skills, timer, and the pending suggestion.
New since v0.8.16
- /save / /load preserve every REPL-level static, not just the
conversation. Saved JSON now carries a newstateblock plus a
suggeststring in addition tomodel/usage/messages.
/loadrestores them on top of the conversation so a reload is
truly a full snapshot. stateblock.CCREPL_StateExport()packs the current
goal,goal_looping,session_turn_ms,plan_mode,lean_mode,
andskills(active skill names) into a primitive hash.
CCREPL_StateImport( hState )reapplies them, silently skipping
missing keys so legacy session files still load cleanly.suggestfield. The pending "Suggested next:" prompt that the
model emitted on its last turn is persisted alongside the messages
and re-seeded into the editor on the first idle frame after
/load, so the green Tab-acceptable preview survives a restart.CCSKILL_ClearAll(). New helper that drops every active skill
in one shot; called byCCREPL_StateImportbefore re-activating the
loaded skill list so the restored set takes over from whatever was
active.
v0.8.16 — /goal turns into "keep working until the condition is met": auto-continue loop + GOAL COMPLETE sentinel.
New since v0.8.15
- /goal redesigned around "keep working until the condition is met".
Setting a goal now arms an auto-continue loop in the main REPL:
after every user-initiated turn the loop scans the last assistant
reply for a literalGOAL COMPLETEsentinel. If absent it auto-
feedsContinue toward the goal. ...reply with ONLY the literal sentinel...as the next user message and runs another turn. - GOAL COMPLETE sentinel. The injected system note teaches the
model to emitGOAL COMPLETEon its own line when the condition
is met.CCREPL_GoalDone( cReply )checks the substring. - CC_GOAL_AUTO_CAP = 25. Hard cap on auto-iterations per user
turn so a stubborn model cannot loop forever; the REPL prints
[goal auto-continue cap (25) hit ...]when it trips. - Esc pauses the loop.
CCREPL_RunGoalLoopdrains the
CCPROMPT_Interruptedflag and disarmss_lGoalLoopingwithout
dropping the goal text --[goal auto-continue paused by Esc -- /goal <text> or a new message to restart]. /goal stop. New sub-command that pauses the auto-continue
loop without clearing the goal text (so the badge stays on).
/goal clearstill drops the goal entirely and disarms the loop.- Per-iteration progress line.
[goal auto-continue N/25]prints
before each automatic turn so the user can see the loop ticking.
v0.8.15 — /goal slash command: pin a session-wide objective the agent carries through every turn.
New since v0.8.14
/goalslash command. Pins a session-wide objective the agent
carries through every subsequent turn until it is changed or
cleared:/goal— show the current goal (or(none))./goal <text>— store the goal AND inject it into the
conversation as a system note, so the model sees the intent on
the very next request without re-sending the goal on every
turn./goal clear(alias/goal off) — drop the goal and tell the
model to stop treating it as a constraint.
[goal]badge. When a goal is set, the status line under the
input box shows a[goal]tag alongside[plan-mode]/[lean]./clearresets the goal too. Resetting the conversation also
clears the session goal and the session-turn timer accumulator, so
the next session starts blank.
v0.8.14 — Shell countdown lands above the box, diff bars equal width + bright-white text.
New since v0.8.13
- Shell command countdown no longer painted inside the input box.
CCTool_ShowCountdown/CCTool_ClearCountdownroute through the
CCREPL_OverwriteAtAnchorhelper when the persistent box is
mounted, sotimeout 300s · 252s leftlands on the scroll-region
anchor above the box and a trailingCCREPL_Out( Chr(10) )bakes
the final value in for the result summary. The plain-CR fallback
is kept for cooked / non-VT terminals. - Diff bars are all the same width.
CCUI_ResultBlockscans the
diff once for the widest added/removed line (floor 110), then pads
every coloured bar to that width viaCCUI_DiffPad( cLine, nWidth )
-- no more ragged edges when one line is longer than the rest. - Diff text rendered in bright white. Added lines go from SGR
37;42to97;42, removed from48;5;52to97;48;5;52-- the
red bar now matches the green bar's contrast.
v0.8.13 — Dynamic-box paint hardening, live timing in the spinner / token bar, /provider key picked up on the next turn.
New since v0.8.12
- Banner anchored at row 1.
CCREPL_RunemitsESC[H ESC[2J
before printing the banner so it is always at rows 1..N and the
CCPROMPT_Activate( nHeaderRows + 1 )anchor lands exactly below it.
Previously the banner started at the cursor's row (often row 2 after
the shellccline), so subsequent writes overwrote the banner's
bottom border. - Box paint uses absolute cursor jumps.
CCPROMPT_Redrawnow
positions every row of the four-row box with an absoluteESC[<row>;1H
instead of chaining CRLFs. The CRLF chain scrolled the screen up by
one row each time the box sat near the terminal bottom, which is how
pressing Esc at the idle prompt could stack 10+ leftover╭frames
above the box. - Wipe rule rewritten. The old-box-frame wipe in
CCPROMPT_Redraw
is now[oldBoxTop .. min(oldBoxTop+3, newBoxTop-1)] minus the rows just written.CCREPL_Outstasheslast_write_startand a trailing
-LF flag so Redraw knows where the chunk actually wrote. Fixes the
FlushPending bullet ("\n + glyph + 2sp", no trailing LF) being
wiped right after it was painted, and the stale top-frame left
behind by multi-line writes (paragraph breaks in the streamed reply). - Banner scrolls when the box pins.
CCPROMPT_Regionsets
scroll_topto 1 oncebox_top == nFloor, so the VT scroll region
expands up to the top of the screen and the banner finally rolls off
the top edge as new content arrives. While the box is still
travelling the banner is still pinned (current behaviour). - Spinner shows elapsed seconds.
iteration_startstamps a wall-
clock inoRender[ "spinnerStartMs" ];CCREPL_SpinnerShowappends
Nsto the spinner line (e.g.⠦ Thinking... [32 tok] 7s). - Token bar shows turn / session seconds.
CCREPL_RunTurntimes
each turn withhb_MilliSeconds(), accumulates into a session-wide
static, and passes the per-turn ms toCCREPL_ShowTokenBar. The bar
now reads▒ tokens in: 3670 out: 83 total: 3753 turn: 1.4s session: 7.2s./clearresets the session counter. - dispatch_agent timer ticks down. The opening Agent block prints
the separator / header / prompt and then drops a live elapsed-time
line via the newCCREPL_OverwriteAtAnchorhelper. The
interrupt_checkcallback refreshes the line at ~2 Hz so the user
seesNs elapsed / Ms timeout · press Esc on the input box to cancel
tick in place. A finalCCREPL_Outbakes the value in and lets the
"Agent done in X.Xs" line land below. - /provider key picked up on the next turn.
CCCFG_Resolvenow
falls back to$CCHARBOUR_CONFIG(or.ccharbour/settings.json)
when the env vars are empty, so a freshly-saved api_key reaches the
next chat call without rebuilding the client.
v0.8.12 — Start without an API key, configure the backend interactively with /provider.
New since v0.8.11
- Starts even with no API key configured. The session no longer
exits with an error whenDEEPSEEK_API_KEYis missing; the banner
and the input box come up normally and a yellow warning under the
banner tells the user to set up a backend. /providerslash command — configure the backend at runtime:/provider— show currentbase_url...
v0.8.17 — /save round-trips full session state
CCHarbour v0.8.17 — /save and /load now round-trip the full session state: goal, modes, skills, timer, and the pending suggestion.
New since v0.8.16
- /save / /load preserve every REPL-level static, not just the
conversation. Saved JSON now carries a newstateblock plus a
suggeststring in addition tomodel/usage/messages.
/loadrestores them on top of the conversation so a reload is
truly a full snapshot. stateblock.CCREPL_StateExport()packs the current
goal,goal_looping,session_turn_ms,plan_mode,lean_mode,
andskills(active skill names) into a primitive hash.
CCREPL_StateImport( hState )reapplies them, silently skipping
missing keys so legacy session files still load cleanly.suggestfield. The pending "Suggested next:" prompt that the
model emitted on its last turn is persisted alongside the messages
and re-seeded into the editor on the first idle frame after
/load, so the green Tab-acceptable preview survives a restart.CCSKILL_ClearAll(). New helper that drops every active skill
in one shot; called byCCREPL_StateImportbefore re-activating the
loaded skill list so the restored set takes over from whatever was
active.
v0.8.16 — /goal turns into "keep working until the condition is met": auto-continue loop + GOAL COMPLETE sentinel.
New since v0.8.15
- /goal redesigned around "keep working until the condition is met".
Setting a goal now arms an auto-continue loop in the main REPL:
after every user-initiated turn the loop scans the last assistant
reply for a literalGOAL COMPLETEsentinel. If absent it auto-
feedsContinue toward the goal. ...reply with ONLY the literal sentinel...as the next user message and runs another turn. - GOAL COMPLETE sentinel. The injected system note teaches the
model to emitGOAL COMPLETEon its own line when the condition
is met.CCREPL_GoalDone( cReply )checks the substring. - CC_GOAL_AUTO_CAP = 25. Hard cap on auto-iterations per user
turn so a stubborn model cannot loop forever; the REPL prints
[goal auto-continue cap (25) hit ...]when it trips. - Esc pauses the loop.
CCREPL_RunGoalLoopdrains the
CCPROMPT_Interruptedflag and disarmss_lGoalLoopingwithout
dropping the goal text --[goal auto-continue paused by Esc -- /goal <text> or a new message to restart]. /goal stop. New sub-command that pauses the auto-continue
loop without clearing the goal text (so the badge stays on).
/goal clearstill drops the goal entirely and disarms the loop.- Per-iteration progress line.
[goal auto-continue N/25]prints
before each automatic turn so the user can see the loop ticking.
v0.8.15 — /goal slash command: pin a session-wide objective the agent carries through every turn.
New since v0.8.14
/goalslash command. Pins a session-wide objective the agent
carries through every subsequent turn until it is changed or
cleared:/goal— show the current goal (or(none))./goal <text>— store the goal AND inject it into the
conversation as a system note, so the model sees the intent on
the very next request without re-sending the goal on every
turn./goal clear(alias/goal off) — drop the goal and tell the
model to stop treating it as a constraint.
[goal]badge. When a goal is set, the status line under the
input box shows a[goal]tag alongside[plan-mode]/[lean]./clearresets the goal too. Resetting the conversation also
clears the session goal and the session-turn timer accumulator, so
the next session starts blank.
v0.8.14 — Shell countdown lands above the box, diff bars equal width + bright-white text.
New since v0.8.13
- Shell command countdown no longer painted inside the input box.
CCTool_ShowCountdown/CCTool_ClearCountdownroute through the
CCREPL_OverwriteAtAnchorhelper when the persistent box is
mounted, sotimeout 300s · 252s leftlands on the scroll-region
anchor above the box and a trailingCCREPL_Out( Chr(10) )bakes
the final value in for the result summary. The plain-CR fallback
is kept for cooked / non-VT terminals. - Diff bars are all the same width.
CCUI_ResultBlockscans the
diff once for the widest added/removed line (floor 110), then pads
every coloured bar to that width viaCCUI_DiffPad( cLine, nWidth )
-- no more ragged edges when one line is longer than the rest. - Diff text rendered in bright white. Added lines go from SGR
37;42to97;42, removed from48;5;52to97;48;5;52-- the
red bar now matches the green bar's contrast.
v0.8.13 — Dynamic-box paint hardening, live timing in the spinner / token bar, /provider key picked up on the next turn.
New since v0.8.12
- Banner anchored at row 1.
CCREPL_RunemitsESC[H ESC[2J
before printing the banner so it is always at rows 1..N and the
CCPROMPT_Activate( nHeaderRows + 1 )anchor lands exactly below it.
Previously the banner started at the cursor's row (often row 2 after
the shellccline), so subsequent writes overwrote the banner's
bottom border. - Box paint uses absolute cursor jumps.
CCPROMPT_Redrawnow
positions every row of the four-row box with an absoluteESC[<row>;1H
instead of chaining CRLFs. The CRLF chain scrolled the screen up by
one row each time the box sat near the terminal bottom, which is how
pressing Esc at the idle prompt could stack 10+ leftover╭frames
above the box. - Wipe rule rewritten. The old-box-frame wipe in
CCPROMPT_Redraw
is now[oldBoxTop .. min(oldBoxTop+3, newBoxTop-1)] minus the rows just written.CCREPL_Outstasheslast_write_startand a trailing
-LF flag so Redraw knows where the chunk actually wrote. Fixes the
FlushPending bullet ("\n + glyph + 2sp", no trailing LF) being
wiped right after it was painted, and the stale top-frame left
behind by multi-line writes (paragraph breaks in the streamed reply). - Banner scrolls when the box pins.
CCPROMPT_Regionsets
scroll_topto 1 oncebox_top == nFloor, so the VT scroll region
expands up to the top of the screen and the banner finally rolls off
the top edge as new content arrives. While the box is still
travelling the banner is still pinned (current behaviour). - Spinner shows elapsed seconds.
iteration_startstamps a wall-
clock inoRender[ "spinnerStartMs" ];CCREPL_SpinnerShowappends
Nsto the spinner line (e.g.⠦ Thinking... [32 tok] 7s). - Token bar shows turn / session seconds.
CCREPL_RunTurntimes
each turn withhb_MilliSeconds(), accumulates into a session-wide
static, and passes the per-turn ms toCCREPL_ShowTokenBar. The bar
now reads▒ tokens in: 3670 out: 83 total: 3753 turn: 1.4s session: 7.2s./clearresets the session counter. - dispatch_agent timer ticks down. The opening Agent block prints
the separator / header / prompt and then drops a live elapsed-time
line via the newCCREPL_OverwriteAtAnchorhelper. The
interrupt_checkcallback refreshes the line at ~2 Hz so the user
seesNs elapsed / Ms timeout · press Esc on the input box to cancel
tick in place. A finalCCREPL_Outbakes the value in and lets the
"Agent done in X.Xs" line land below. - /provider key picked up on the next turn.
CCCFG_Resolvenow
falls back to$CCHARBOUR_CONFIG(or.ccharbour/settings.json)
when the env vars are empty, so a freshly-saved api_key reaches the
next chat call without rebuilding the client.
v0.8.12 — Start without an API key, configure the backend interactively with /provider.
New since v0.8.11
- Starts even with no API key configured. The session no longer
exits with an error whenDEEPSEEK_API_KEYis missing; the banner
and the input box come up normally and a yellow warning under the
banner tells the user to set up a backend. /providerslash command — configure the backend at runtime:/provider— show currentbase_url/model/ key state and
list the four presets./provider deepseek|glm|moonshot|openai— apply the preset's
base_urland default model, persist tosettings.json, and
rebuild the API client in place./provider key <secret>— store the API key insettings.json./provider model <name>— switch the model only./provider clear— wipe the stored API key.
- Turn skipped (not crashed) when no key. Submitting a message
before a key is configured prints the warning again instead of
erroring out. CCSETTINGS_Saveis now public so/provider(and any future
runtime configuration) can persist updates without poking the file
directly.
v0.8.11 — Dynamic input box stability fixes.
New since v0.8.10
- Scroll region spans the full band regardless of where the dynamic
box currently sits (scroll_bottom = nFloor - 1always), so an early
write between banner and box does not scroll content out of the
banner. - Interactive selectors force-pin the box before painting. ask_user
and propose_agents now call a newCCPROMPT_ForcePinthat drops the
box to the floor first, giving the selector a stable position right
above it and avoiding overlap with a still-travelling box. - Wipe never erases the just-written content. The old-box-frame
wipe inCCPROMPT_Redrawis now clamped to
[max(oldBoxTop, contentRow) .. newBoxTop - 1], so the rows that
hold the new user echo or the streamed reply are preserved. - Visual-row counting (auto-wrap).
CCREPL_Outnow advances
content_rowby the visual rows a chunk consumes (LFs + wrapped
printable runs + ANSI sequences skipped), ...