Documentation
¶
Overview ¶
Package workspace implements local workspace operations.
HTML→Markdown / HTML→Text conversion helpers used by webfetch.
Inlined from go-pkg/x/htmlx — keep in sync. flashduty-runner is open-source and may not import internal flashcatcloud modules.
SSRF guard for outbound HTTP. Runner pods must NEVER reach IMDS or the cluster apiserver from inside; without dial-time IP validation a prompt-injected URL can exfiltrate cloud credentials from 169.254.169.254 or hit internal VPC services. The DNS-to-dial re-resolution closes the DNS-rebinding gap a host-string allowlist would leave open.
Inlined from go-pkg/x/netsafe — keep in sync. flashduty-runner is open-source and may not import internal flashcatcloud modules.
Index ¶
- Constants
- Variables
- func BundledToolsDir() string
- func ShouldSkipForOutputsDir(command string) bool
- type Environment
- func (e *Environment) Bash(ctx context.Context, args *protocol.BashArgs) (*protocol.BashResult, error)
- func (e *Environment) DeleteKnowledgeFiles(ctx context.Context, args *protocol.DeleteKnowledgeFilesArgs) (*protocol.DeleteKnowledgeFilesResult, error)
- func (e *Environment) Glob(ctx context.Context, args *protocol.GlobArgs) (*protocol.GlobResult, error)
- func (e *Environment) Grep(ctx context.Context, args *protocol.GrepArgs) (*protocol.GrepResult, error)
- func (e *Environment) List(ctx context.Context, args *protocol.ListArgs) (*protocol.ListResult, error)
- func (e *Environment) MCPCall(ctx context.Context, args *protocol.MCPCallArgs, logger *slog.Logger) (*protocol.MCPCallResult, error)
- func (e *Environment) MCPListTools(ctx context.Context, args *protocol.MCPListToolsArgs, logger *slog.Logger) (*protocol.MCPListToolsResult, error)
- func (e *Environment) PackFolder(ctx context.Context, args *protocol.PackFolderArgs) (*protocol.PackFolderResult, error)
- func (e *Environment) Read(ctx context.Context, args *protocol.ReadArgs) (*protocol.ReadResult, error)
- func (e *Environment) ReconcileKnowledgeManifest(ctx context.Context, args *protocol.ReconcileKnowledgeManifestArgs) (*protocol.ReconcileKnowledgeManifestResult, error)
- func (e *Environment) Root() string
- func (e *Environment) StageKnowledgeFiles(ctx context.Context, args *protocol.StageKnowledgeFilesArgs) (*protocol.StageKnowledgeFilesResult, error)
- func (e *Environment) SyncSkill(ctx context.Context, args *protocol.SyncSkillArgs) (*protocol.SyncSkillResult, error)
- func (e *Environment) WebFetch(ctx context.Context, args *protocol.WebFetchArgs) (*protocol.WebFetchResult, error)
- func (e *Environment) Write(ctx context.Context, args *protocol.WriteArgs) error
- type LargeOutputConfig
- type LargeOutputProcessor
- type LimitedWriter
- type ProcessResult
Constants ¶
const ( // DefaultMaxOutputSize is the default character limit before truncation (~7.5k tokens) DefaultMaxOutputSize = 30000 // ~7.5k tokens at 4 chars/token // DefaultPreviewSize is the maximum characters for preview DefaultPreviewSize = 8000 // ~2k tokens // DefaultPreviewLines is the number of lines shown in the preview DefaultPreviewLines = 20 // OutputsDir is the directory name for storing large outputs OutputsDir = ".outputs" )
Variables ¶
var ErrOutputCapped = errors.New("output capped")
ErrOutputCapped is returned by LimitedWriter once its byte cap has been reached. Surfaces the contract violation that would otherwise be hidden by the writer pretending it accepted everything (`return len(p), nil`).
Functions ¶
func BundledToolsDir ¶ added in v0.0.11
func BundledToolsDir() string
bundledToolsDir returns the directory holding the CLIs the runner ships with it — the flashduty CLI in particular. Bash subprocesses must resolve OUR bundled flashduty rather than whatever a BYOC host happens to have earlier on PATH (a different version, or an unrelated binary of the same name). FLASHDUTY_RUNNER_BIN_DIR overrides the location; the default is the directory the runner executable lives in, since both the container image and install.sh place the CLI next to the runner binary. Returns "" when the path can't be determined, in which case PATH is left untouched.
func ShouldSkipForOutputsDir ¶
ShouldSkipForOutputsDir checks if large output processing should be skipped for commands operating on .outputs/ directory to avoid circular processing. Uses a word-boundary regex so commands like "thread " don't match "head ".
Types ¶
type Environment ¶
type Environment struct {
// contains filtered or unexported fields
}
Environment handles local filesystem operations.
func New ¶
func New(root string, checker *permission.Checker) (*Environment, error)
New creates a new workspace with the given root directory and permission checker.
func (*Environment) Bash ¶
func (e *Environment) Bash(ctx context.Context, args *protocol.BashArgs) (*protocol.BashResult, error)
Bash executes a bash command in the workspace.
func (*Environment) DeleteKnowledgeFiles ¶
func (e *Environment) DeleteKnowledgeFiles(ctx context.Context, args *protocol.DeleteKnowledgeFilesArgs) (*protocol.DeleteKnowledgeFilesResult, error)
DeleteKnowledgeFiles removes the supplied files from the workspace root and scrubs their entries from the sentinel.
func (*Environment) Glob ¶
func (e *Environment) Glob(ctx context.Context, args *protocol.GlobArgs) (*protocol.GlobResult, error)
Glob searches for files matching a pattern.
func (*Environment) Grep ¶
func (e *Environment) Grep(ctx context.Context, args *protocol.GrepArgs) (*protocol.GrepResult, error)
Grep searches for a pattern in files.
func (*Environment) List ¶
func (e *Environment) List(ctx context.Context, args *protocol.ListArgs) (*protocol.ListResult, error)
List lists entries in a directory.
func (*Environment) MCPCall ¶
func (e *Environment) MCPCall(ctx context.Context, args *protocol.MCPCallArgs, logger *slog.Logger) (*protocol.MCPCallResult, error)
MCPCall executes an MCP tool call.
func (*Environment) MCPListTools ¶
func (e *Environment) MCPListTools(ctx context.Context, args *protocol.MCPListToolsArgs, logger *slog.Logger) (*protocol.MCPListToolsResult, error)
MCPListTools lists available tools from an MCP server.
func (*Environment) PackFolder ¶ added in v0.0.8
func (e *Environment) PackFolder(ctx context.Context, args *protocol.PackFolderArgs) (*protocol.PackFolderResult, error)
PackFolder walks args.Path, applies the skill exclusion rules, and returns a base64-encoded zip whose entries are rooted at the basename of args.Path.
func (*Environment) Read ¶
func (e *Environment) Read(ctx context.Context, args *protocol.ReadArgs) (*protocol.ReadResult, error)
Read reads a file from the workspace.
func (*Environment) ReconcileKnowledgeManifest ¶ added in v0.0.7
func (e *Environment) ReconcileKnowledgeManifest(ctx context.Context, args *protocol.ReconcileKnowledgeManifestArgs) (*protocol.ReconcileKnowledgeManifestResult, error)
ReconcileKnowledgeManifest reconciles the on-disk knowledge tree against the supplied manifest. Files present on disk but absent from the manifest are orphans (pruned). Files present in the manifest with a checksum that disagrees with the sentinel are stale (also pruned, so the next read triggers a fresh lazy install from Safari). Files whose checksum already matches are left in place.
The runner does NOT pre-stage anything in this call: the manifest declares what *should* exist if it were read, not what *must* be cached. Cold packs stay cold; only drift is corrected. The whole pass runs under the sentinel lock so it is safe with concurrent stage calls from the same Safari.
func (*Environment) Root ¶
func (e *Environment) Root() string
Root returns the workspace root directory.
func (*Environment) StageKnowledgeFiles ¶
func (e *Environment) StageKnowledgeFiles(ctx context.Context, args *protocol.StageKnowledgeFilesArgs) (*protocol.StageKnowledgeFilesResult, error)
StageKnowledgeFiles writes the supplied files into the workspace root and updates the sentinel checksum map.
func (*Environment) SyncSkill ¶
func (e *Environment) SyncSkill(ctx context.Context, args *protocol.SyncSkillArgs) (*protocol.SyncSkillResult, error)
SyncSkill is probe-or-install. With empty ZipData it checks local cache against args.Checksum: hit returns {Cached:true,Path}; miss returns {Cached:false,Path:""} so the cloud retries with zip. With ZipData present it overwrites <home>/skills/<name>/ and writes .checksum.
args.SkillDir is accepted for backward compatibility but ignored — the runner derives the path from skill_name to keep layout under its control.
func (*Environment) WebFetch ¶
func (e *Environment) WebFetch(ctx context.Context, args *protocol.WebFetchArgs) (*protocol.WebFetchResult, error)
WebFetch fetches content from a URL and converts it to readable format.
type LargeOutputConfig ¶
LargeOutputConfig holds configuration for large output handling.
func DefaultLargeOutputConfig ¶
func DefaultLargeOutputConfig() LargeOutputConfig
DefaultLargeOutputConfig returns the default configuration.
type LargeOutputProcessor ¶
type LargeOutputProcessor struct {
// contains filtered or unexported fields
}
LargeOutputProcessor handles large output truncation and file storage.
func NewLargeOutputProcessor ¶
func NewLargeOutputProcessor(ws *Environment, config LargeOutputConfig) *LargeOutputProcessor
NewLargeOutputProcessor creates a new processor with the given workspace.
func (*LargeOutputProcessor) Process ¶
func (p *LargeOutputProcessor) Process(ctx context.Context, content string, prefix string) (*ProcessResult, error)
Process checks if content exceeds the limit and handles accordingly.
type LimitedWriter ¶
LimitedWriter is an io.Writer that caps the total number of bytes forwarded to the wrapped writer. After the cap is reached it appends an inline marker once and then returns ErrOutputCapped on every subsequent write so callers can detect truncation via Hit().
NOTE: exec.Cmd treats any writer error as fatal — callers wrapping LimitedWriter around a stdio pipe must filter ErrOutputCapped out of cmd.Run()'s error chain.
func (*LimitedWriter) Hit ¶ added in v0.0.7
func (l *LimitedWriter) Hit() bool
Hit reports whether the writer's byte cap has been reached.