# thoughtframe-core — agent notes This repo runs a live ThoughtFrame engine inside Eclipse, driven through the `tf` client (a thin HTTP client; it finds the port in `~/.thoughtframe/instances/*.json`). **Prefer `tf` over the shell** for work in this workspace — it's indexed, scoped to the real workspace, and goes through Eclipse, so the IDE stays the source of truth. Prefer it over shell `grep`/`find`/`ls`, and `tf write`/`tf replaceSelection` over direct FS edits. Run `tf help` for the live list. Verb pages are grouped in subfolders (search/ read/ edit/ run/ debug/ agent/ engine/); the `tf` client maps names to folders, so you still type `tf VERB`. The verbs: Search (Eclipse JDT index) tf find name=… type declarations (e.g. *Manager) tf references class=… [method=|field=] tf implementors class=… [method=] subtypes / overrides tf hierarchy class=… supertypes + subtypes tf type-info class=… fields, methods, supertypes tf source class=… the type's source Read tf status dashboard: editor, problems, launches, tests tf projects | tf project name=… | tf projectState name=&op=open|close tf editors | tf selection | tf stat path=… | tf properties path=… | tf classpath project=… tf markers [severity=] | tf tasks | tf bookmarks op=list | tf console [name=] [lines=] tf tests op=runs | tf problems [path=…] tf glob pattern=… | tf grep query=… [path=] | tf peek path=… [startLine= count=] tf localpeek path=/abs/or/~/file [startLine= count=] any host file, inside or outside the workspace (range reads with startLine/count — do not cat/sed whole files; raw dumps are a top token burn. A whole-file read is the exception, not the default: only when you genuinely need the entire reference surface (e.g. renaming every occurrence). Otherwise peek/localpeek the window you need.) tf git project=… op=status|log|branch|diff [path=] Edit (through Eclipse — creates parents, auto-reveals) tf open path=… [line=] | tf close | tf save [all=true] tf write path=… text=… | tf replaceSelection path=… before="" text=… (replaceSelection locators are exact content — before, or from+to head/tail anchors — not line numbers) tf delete | tf mkdir | tf moveFile path=&to= | tf copy path=&to= tf move class=&target= | tf rename class=&newName= (Eclipse LTK refactoring) tf format | tf formatAll path=… | tf organizeImports | tf highlight … | tf refresh Build / run / debug tf build | tf clean [name=] | tf run | tf runTests project=… tf launch op=configs|running|run|stop name=… | tf launchConfig op=delete name=… tf debug op=launch name=… launch a config in debug mode tf debug op=targets|threads|variables&thread=&frame= tf debug op=resume|suspend|stepOver|stepInto|stepReturn (step over = stepOver) tf breakpoints op=list|set|clear path=&line= (set takes path + line; the type is derived) tf runCommand command=… any workbench command id Extend / misc tf reloadframeplugins | tf clearCache | tf errors [lines=] tf websearch query=… (needs a key) | tf webfetch url=… [format=text] | tf scratch tf thought op=add|search|delete|taxonomy … (agent memory via the "thought" searcher) Engine tf engine status | frame framepath=… | tick framepath=… | until … | runframe … tf engine frames op=neighbours|connect|near|here … (frame graph; topics are frames) Notes - After editing engine Java the running engine is stale: check `tf errors` (Hot Code Replace failures land there), then restart the target (`tf launch op=stop` + `tf debug op=launch`). Better: draft it as a webapp Groovy page — that's live, no restart. - `tf help [q=…] [verb=…]` is a compact cheat sheet (names by folder, params on demand). Use it instead of searching the full Code Mode tool catalog. - For throwaway scripts, prefer a scratch Groovy page run in the engine (`tf scratch`) over shell one-liners: it runs in-process with `context` and `bench` in scope. - Everything searchable goes through ONE interface — `Searcher` (`bench.getSearcher("type")` + `QueryBuilder`) — backed by the embedded OpenSearch node: frames, thoughts, git repos, notes, framememory/RAG. It is already wired; do NOT reverse-engineer the search layer. Query idiom, semantic `deepsearch`, and "add a type by copying `WEB-INF/base/tf-eclipse/system/data/fields/.xml`" are in `tf help`. Copy the nearest example (`agent/notes.*` is the minimal one); deep-reading the framework is what makes agent context explode. - If a capability looks missing or unwired and you're about to deep-read the framework to find out, STOP and ASK the user first. Don't spelunk; only the user knows what's already there, and guessing is what burns the context. - Keep state in the graph, not just the conversation: recall with `tf thought op=search …` / `tf engine frames op=near framepath=topic/…` as you work, and write decisions to `topic/` after (`tags`/`status`; `status=parked` for measure-later items). Check it while you work, not only at the end. ## The Eclipse plugin project: keep it OUT of Gradle The PDE plugin lives at `eclipse/` and must NEVER be listed in `settings.gradle`. Buildship imports every project in `settings.gradle` and stamps it with `org.eclipse.buildship.core.gradleprojectnature`, overwriting the hand-maintained PDE metadata (`.project`/`.classpath`/`.settings`) and renaming the workspace project to the Gradle name. Removing it from `settings.gradle` later does NOT undo that import - the workspace entry stays until it is deleted and re-imported. (Seen twice now.) Symptoms: - plugin-side Java changes (e.g. `FrameViewer`) don't take effect after relaunching; - the workspace project is named `eclipse` (a Gradle project) instead of `thoughtframe-eclipse`; - the project's recorded natures show `gradleprojectnature`, not `org.eclipse.pde.PluginNature`. Fix (Eclipse-side; cannot be done through `tf`): 1. Delete the workspace project `eclipse` - UNCHECK "delete project contents on disk". 2. File > Import > Existing Projects into Workspace > `~/git/thoughtframe-core/eclipse` -> imports as `thoughtframe-eclipse` with PDE nature. 3. Ensure `eclipse/` is not in `settings.gradle` and that `eclipse/.settings/org.eclipse.buildship.core.prefs` does not exist. 4. Clean + relaunch the Eclipse Application. The Gradle split mirrors the classloader split: `eclipse-build/` is the Gradle subproject that stages the island runtime; `eclipse/` is a plain, hand-maintained PDE project. ## Rendering: load from the engine, do not `setText` Do not read pages out of the plugin bundle and inject them with `browser.setText(...)`. That document has no origin, so any in-page asset (e.g. the logo) resolves to `file:///...` and 404s, and it bypasses the engine (Velocity) entirely, so edits to the webapp never show. Point the browser at the engine URL instead (`http://127.0.0.1:/...`, via `setUrl`) and it renders from the webapp. Longer term the chat/transcript should be a served page updated over the websocket, so there is no per-turn `setUrl`/`setText` at all. The engine caches pages: after editing a webapp page run `tf clearCache`. ## Edit through `tf`, never raw disk Raw filesystem edits desync Eclipse's resource model - that is exactly what turned a stale workspace import into a hard-to-see bug (the running plugin kept reloading old classes). Use `tf write` / `tf replaceSelection` (JSON body for multi-line), then `tf refresh` if you changed files another way.