cwd

package
v0.8.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 27, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

Documentation

Overview

Package cwd implements current-working-directory tools (cwd_get, cwd_push, cwd_pop)

Package cwd implements current-working-directory navigation tools (cwd_get, cwd_push, cwd_pop) with a disciplined stack model.

Motivation:

LLM assistants work within a project directory (ProjectRoot). When they need to operate in a different location — a sub-project, a build output directory, a test fixture path — every subsequent tool call must either pass absolute paths or rely on ambiguous relative-to-root conventions. Without CWD tools, path resolution is brittle and error-prone.

A naive "cd" is insufficient: the assistant needs to return to the original context after completing the task. The stack model matches the natural workflow: enter a scope, do work, then return.

Stack Model:

PUSH ./sub-project
│  save (CWD=A, ProjectRoot=X)  ──►  stack: [(A, X)]
│  os.Chdir(./sub-project)
│  recompute ProjectRoot (maybe Y)
│
▼  现在所有文件/Shell 工具都以 sub-project 为基准
...
POP
│  restore entry: (A, X)
│  os.Chdir(A)
│  context.ProjectRoot = X   ← 恢复 push 前的精确值
▼
回到原始上下文

Why push+pop Together:

push and pop are two halves of a contract. push saves state and enters a directory; pop restores state and exits. Separating them (e.g. a "cd" + implicit return) would leave the LLM responsible for tracking depth — a responsibility better handled by a machine. The stack is the mechanism that makes the contract work.

Why Save ProjectRoot at push (Not Recompute at pop):

pop restores the exact ProjectRoot value saved at push time. If we recomputed ProjectRoot after chdir back, a git branch change or repository restructure could yield a different result. Saving the push-time value guarantees the assistant returns to the same project context it left.

Path Normalization:

filepath.Abs         — resolves relative paths and ".." components
filepath.EvalSymlinks — resolves /tmp → /private/tmp on macOS for
                        comparison only (storage uses Abs to preserve
                        the user's original path semantics)

Edge Cases:

  • Same-directory push: detected via EvalSymlinks comparison, returns "already in ..." without creating a stack entry.
  • Non-git target: push succeeds with a note. GetProjectRoot() falls back to CWD when no .git is found.
  • Stack overflow: maxStackDepth (100) prevents unbounded growth.
  • Empty pop: returns a message (not an error) — the LLM can safely call pop without checking depth first.
  • chdir failure after push: the saved stack entry is immediately rolled back, leaving the stack in a consistent state.

Tool Semantics:

cwd_get  — returns CWD, ProjectRoot, and stack depth (no side effects)
cwd_push — (path) pushes state, chdirs, recomputes ProjectRoot
cwd_pop  — pops state, restores both CWD and ProjectRoot

Thread Safety:

A sync.Mutex protects dirStack. While concurrent LLM tool calls are unlikely in practice (assistants are single-threaded), the mutex is a low-cost guarantee against undefined behavior.

Inter-Package Contract:

This package writes to context.ProjectRoot (internal/context). No other package should mutate ProjectRoot directly — use cwd_push/cwd_pop to transition between project scopes.

Index

Constants

This section is empty.

Variables

View Source
var RegisterTool = toolcall.RegisterTool

Functions

func ToolArgsValue

func ToolArgsValue[T Primitive](args ToolArgs, key string, defaultValue T) T

Types

type Primitive

type Primitive = toolcall.Primitive

type ToolArgs

type ToolArgs = toolcall.ToolArgs

type ToolDef

type ToolDef = toolcall.ToolDef

Source Files

  • cwd.go
  • cwd_cwd.go
  • doc.go

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL