Class: Pikuri::Tool::Workspace

Inherits:
Object
  • Object
show all
Defined in:
lib/pikuri/tool/workspace.rb

Overview

Defines which paths the agent can see and write to. Subclass and implement #cwd, #resolve_for_read, and #resolve_for_write. Returned Pathnames are absolute, post-symlink-resolution.

Read-set vs. write-set

The two resolve methods exist because a future workspace may admit paths for reading that it refuses for writing — e.g. a multi-root workspace where ~/.claude/skills is readable but only the project CWD is writable. For v1’s Cwd the two methods are the same: read- set and write-set are both the CWD subtree.

Existence is not the workspace’s concern

resolve_for_read(‘foo.rb’) succeeds (returns a Pathname) even if foo.rb doesn’t exist; the caller (Read) errors with file-not-found when it tries to open it. resolve_for_write tolerates entirely non-existent paths (Write can create lib/new/dir/foo.rb even when lib/new/ doesn’t exist) — the caller is responsible for any mkdir_p before writing. This split keeps the workspace narrowly responsible for containment, not for filesystem-state checks.

Future extensions (out of scope for v1)

  • Multi-root workspace: ~/.claude/skills readable, CWD writable.

  • Tool::Workspace::ALLOW_ALL: no restriction, planned for Docker / dev-container mode.

Direct Known Subclasses

Cwd

Defined Under Namespace

Classes: Cwd, Error

Instance Method Summary collapse

Instance Method Details

#cwdPathname

Project anchor: where shells run, where modifications are made. For Cwd this is the constructor’s root: (after realpath); a future ALLOW_ALL would return the user’s invocation directory.

Returns:

  • (Pathname)

Raises:

  • (NotImplementedError)

    in the abstract base



48
49
50
# File 'lib/pikuri/tool/workspace.rb', line 48

def cwd
  raise NotImplementedError, "#{self.class}#cwd must be implemented"
end

#resolve_for_read(path) ⇒ Pathname

Resolve a user-supplied path against the workspace’s read-set. Returned Pathname is absolute and may not exist on disk; the caller validates existence separately.

Parameters:

  • path (String)

    user-supplied path, absolute or relative

Returns:

  • (Pathname)

Raises:

  • (Error)

    if the resolved path falls outside the read-set

  • (NotImplementedError)

    in the abstract base



60
61
62
# File 'lib/pikuri/tool/workspace.rb', line 60

def resolve_for_read(path)
  raise NotImplementedError, "#{self.class}#resolve_for_read must be implemented"
end

#resolve_for_write(path) ⇒ Pathname

Resolve a user-supplied path against the workspace’s write-set. Same shape as #resolve_for_read; semantically distinct so a future workspace can permit reading paths it refuses to write.

Parameters:

  • path (String)

Returns:

  • (Pathname)

Raises:

  • (Error)

    if the resolved path falls outside the write-set

  • (NotImplementedError)

    in the abstract base



72
73
74
# File 'lib/pikuri/tool/workspace.rb', line 72

def resolve_for_write(path)
  raise NotImplementedError, "#{self.class}#resolve_for_write must be implemented"
end