@@ -25,12 +25,15 @@ import { CONTEXT_PRIMER } from "./system-prompt.js";
2525import { buildNudge , registerWatchdog } from "./watchdog.js" ;
2626import { registerNotebookTools } from "./notebook/tools.js" ;
2727import { registerNotebookRehydration } from "./notebook/rehydration.js" ;
28+ import { registerNotebookTopicTool } from "./notebook/topic-tool.js" ;
29+ import { setActiveNotebookTopic } from "./notebook/topic.js" ;
2830import { registerHandoffTool } from "./handoff/tool.js" ;
2931import { registerHandoffCommand } from "./handoff/command.js" ;
3032import { registerHandoffCompaction } from "./handoff/compact.js" ;
3133import { registerSpawnTool } from "./spawn/index.js" ;
3234import {
3335 STATUS_KEY_HANDOFF ,
36+ STATUS_KEY_TOPIC ,
3437 WIDGET_KEY_WARNING ,
3538 updateIndicators ,
3639} from "./tui.js" ;
@@ -41,6 +44,7 @@ export default function (pi: ExtensionAPI): void {
4144
4245 // ── Register all tools ──────────────────────────────────────────
4346 registerNotebookTools ( pi , state ) ;
47+ registerNotebookTopicTool ( pi , state ) ;
4448 registerHandoffTool ( pi , state ) ;
4549 registerSpawnTool ( pi , state ) ;
4650
@@ -54,8 +58,20 @@ export default function (pi: ExtensionAPI): void {
5458
5559 // ── /notebook command — interactive page selector ────────────────
5660 pi . registerCommand ( "notebook" , {
57- description : "Select a notebook page to preview" ,
58- handler : async ( _args , ctx ) => {
61+ description : "Select a notebook page to preview, or set the active notebook topic with /notebook <topic>" ,
62+ handler : async ( args , ctx ) => {
63+ const topicArg = args . trim ( ) ;
64+ if ( topicArg ) {
65+ const result = setActiveNotebookTopic ( state , topicArg , "human" ) ;
66+ if ( ctx . hasUI ) {
67+ const message = result . boundaryHint
68+ ? `Active notebook topic changed: ${ result . boundaryHint . from } → ${ result . boundaryHint . to } . This is a likely task boundary; handoff is recommended before continuing.`
69+ : `Active notebook topic: ${ result . current } ` ;
70+ ctx . ui . notify ( message , result . boundaryHint ? "warning" : "info" ) ;
71+ }
72+ updateIndicators ( ctx , state ) ;
73+ return ;
74+ }
5975 if ( ! ctx . hasUI ) {
6076 return ;
6177 }
@@ -152,12 +168,25 @@ export default function (pi: ExtensionAPI): void {
152168 // Inject context management primer at the end of the system prompt
153169 parts . push ( "\n" + CONTEXT_PRIMER ) ;
154170
155- // Inject ledger listing so the LLM always knows what's available
156- const entryNames = Array . from ( state . ledger . keys ( ) ) . sort ( ) ;
171+ if ( state . activeNotebookTopic ) {
172+ parts . push (
173+ `\n## Active Notebook Topic\n` +
174+ `Current topic: \`${ state . activeNotebookTopic } \` (${ state . activeNotebookTopicSource ?? "unknown" } -set).\n` +
175+ `Treat this as the current semantic frame. If new work fits it, prefer spawn for isolated noisy subtasks. If it does not fit it, prefer handoff over dragging stale context forward.` ,
176+ ) ;
177+ } else {
178+ parts . push (
179+ `\n## Active Notebook Topic\n` +
180+ `No active notebook topic is set. Early in the next substantive task, assign a short stable topic with \`notebook_topic_set\`. Human-set topics are authoritative.` ,
181+ ) ;
182+ }
183+
184+ // Inject notebook listing so the LLM always knows what's available
185+ const entryNames = Array . from ( state . notebookPages . keys ( ) ) . sort ( ) ;
157186 if ( entryNames . length > 0 ) {
158187 const listing = entryNames
159188 . map ( ( name ) => {
160- const content = state . ledger . get ( name ) ! ;
189+ const content = state . notebookPages . get ( name ) ! ;
161190 const firstLine = ( content . split ( "\n" ) [ 0 ] ?? "" ) . slice ( 0 , 80 ) ;
162191 return ` ${ name } : ${ firstLine } ` ;
163192 } )
@@ -201,6 +230,7 @@ export default function (pi: ExtensionAPI): void {
201230 // Clear any stale TUI indicators from the previous session
202231 if ( ctx . hasUI ) {
203232 ctx . ui . setStatus ( STATUS_KEY_HANDOFF , undefined ) ;
233+ ctx . ui . setStatus ( STATUS_KEY_TOPIC , undefined ) ;
204234 ctx . ui . setWidget ( WIDGET_KEY_WARNING , undefined ) ;
205235 }
206236 }
0 commit comments