Welcome to the Bootstrap project! If you are just joining us, this is the very first chapter of our deep dive into the system's architecture.
Before we worry about complex AI agents, cost tracking, or telemetry, we need a place to store information. Imagine you are working on a team project in a conference room. To keep everyone on the same page, you write the most important details on a large Whiteboard at the front of the room.
In our application, Global Application State is that whiteboard.
Imagine you are writing a program that needs to know the Current Working Directory (CWD) (the folder you are currently working in). If you didn't have a global state, you would have to pass the cwd variable as an argument to every single function in your code.
Without Global State (Messy):
function startApp(cwd) {
loadConfig(cwd);
startAgent(cwd);
}
function startAgent(cwd) {
// Pass it down again... and again...
executeTool(cwd);
}
With Global State (Clean): Any part of the system can simply look at the "whiteboard" to see where we are.
STATE Object
At its core, the Global Application State is just a massive JavaScript object called STATE. It acts as a Singletonβmeaning there is only one instance of it alive while the application runs.
This object holds everything that defines the "context" of the application right now, including:
cwd).sessionId).totalCostUSD).Here is a simplified look at what this object looks like in code. It's a plain dictionary of values.
type State = {
// Where did we start?
originalCwd: string
// Where are we now?
cwd: string
// Who is this session?
sessionId: string
// How much have we spent?
totalCostUSD: number
// Is the user there?
isInteractive: boolean
}
Note: The actual
Statetype instate.tsis huge! It holds dozens of properties. But don't worry, you don't need to memorize them. You just need to know they live here.
In bootstrap, we never touch the STATE variable directly from other files. It is kept private to ensure safety. Instead, we use "Accessor Functions" (Getters and Setters).
Think of the Global State as a bank vault. You don't walk in and grab money. You ask a teller (a function) to give you money or deposit it for you.
Let's look at how we handle the Current Working Directory.
1. Reading the State (The Getter) When a module needs to know the current folder, it calls this function:
// From state.ts
export function getCwdState(): string {
return STATE.cwd
}
2. Writing to State (The Setter)
When the agent decides to change directories (like running a cd command), it calls this function:
// From state.ts
export function setCwdState(cwd: string): void {
// Normalize the path so it works across different OSs
STATE.cwd = cwd.normalize('NFC')
}
Notice that setCwdState normalizes the string (.normalize('NFC')) before saving it. By forcing everyone to use this function, we guarantee that the data in our state is always clean and consistent.
What actually happens when the application starts and runs? Let's visualize the lifecycle of the Global State using a simple diagram.
Let's look at how state.ts implements this.
The state isn't just null when we start. We have a function getInitialState() that sets up sensible defaults. It captures the exact moment the app starts (startTime) and where it starts (originalCwd).
// state.ts
function getInitialState(): State {
// ... logic to find current directory ...
const state: State = {
originalCwd: resolvedCwd,
startTime: Date.now(),
totalCostUSD: 0,
sessionId: randomUUID(), // Generate a unique ID
// ... many other defaults
}
return state
}
This is the most important line in the file. It creates the one true source of truth.
// AND ESPECIALLY HERE
const STATE: State = getInitialState()
The comment "THINK THRICE BEFORE MODIFYING" is a warning. Because this variable is global, adding data here adds it to the memory footprint of the entire application forever.
One of the most critical pieces of data stored here is the sessionId. This ID allows us to track conversations, logs, and history.
export function getSessionId(): string {
return STATE.sessionId
}
export function regenerateSessionId(): string {
STATE.sessionId = randomUUID()
return STATE.sessionId
}
This simple ID is the foundation for the next major concept: Sessions.
The Global State acts as the glue between several complex systems. We will explore these in detail in upcoming chapters:
sessionId stored here controls the lifecycle of a user's interaction. We cover this in Session Lifecycle Management.isInteractive and various "Modes" (like Plan Mode vs. Act Mode). This is detailed in Agent Context & Mode Tracking.totalCostUSD and modelUsage are vital for making sure the agent doesn't spend too much API credit. Learn more in Resource & Cost Accounting.meter and loggerProvider, which are the eyes and ears of the system. We discuss this in Telemetry Infrastructure.In this chapter, we learned:
STATE defined in state.ts.Now that we have a place to store our data, we need to understand how to manage the time and lifetime of that data.
Next Chapter: Session Lifecycle Management
Generated by Code IQ