Dagger
Search

speck

Speck — AI-powered spec-driven development agent.

Installation

dagger install github.com/telchak/daggerverse/speck@b7e5030da94a1004c04cde234845538e9502bcc5

Entrypoint

Return Type
Speck !
Arguments
NameTypeDefault ValueDescription
sourceDirectory -Project source directory
Example
dagger -m github.com/telchak/daggerverse/speck@b7e5030da94a1004c04cde234845538e9502bcc5 call \
func (m *MyModule) Example() *dagger.Speck  {
	return dag.
			Speck()
}
@function
def example() -> dagger.Speck:
	return (
		dag.speck()
	)
@func()
example(): Speck {
	return dag
		.speck()
}

Types

Speck 🔗

AI-powered spec-driven development agent. Takes a prompt or GitHub issue and produces structured task decompositions with agent and model assignments. The output is a JSON object designed for GitHub Actions matrix consumption. Pass your project as --source and provide an agent registry via --agents to enable intelligent agent assignment.

source() 🔗

Project source directory

Return Type
Directory !
Example
dagger -m github.com/telchak/daggerverse/speck@b7e5030da94a1004c04cde234845538e9502bcc5 call \
 source
func (m *MyModule) Example() *dagger.Directory  {
	return dag.
			Speck().
			Source()
}
@function
def example() -> dagger.Directory:
	return (
		dag.speck()
		.source()
	)
@func()
example(): Directory {
	return dag
		.speck()
		.source()
}

decompose() 🔗

Run the full spec-driven development pipeline.

Executes specify -> plan -> decompose in sequence and returns a structured JSON object with tasks, agent assignments, model suggestions, and an execution plan. Designed for GitHub Actions matrix consumption.

When create_pr is enabled, each phase in the execution plan gets a pr_branch field. The GitHub Actions workflow should matrix by phase, chain tasks sequentially (impl -> test -> review), and create one PR per phase with the accumulated changes.

Return Type
String !
Arguments
NameTypeDefault ValueDescription
promptString !""What to build (runs full pipeline: specify -> plan -> decompose)
issueIdInteger !0GitHub issue number (alternative to prompt)
repositoryString !""GitHub repository URL (required if using issue_id)
githubTokenSecret nullGitHub token (required if using issue_id)
agentsString !"[]"JSON array of available agents with name, source, specialization, capabilities
techStackString !""Tech stack hints (e.g. 'Python, FastAPI, PostgreSQL')
modelFamilyString !"claude"Model family for suggestions: 'claude' (default), 'gemini', or 'openai'
includeTestsBoolean !falseGenerate test tasks (write_tests) after implementation tasks
includeReviewBoolean !falseGenerate review tasks (review) at the end of each phase
createPrBoolean !falseAdd PR branch names to phases for automated PR creation (one PR per phase)
Example
dagger -m github.com/telchak/daggerverse/speck@b7e5030da94a1004c04cde234845538e9502bcc5 call \
 decompose --prompt string --issue-id integer --repository string --agents string --tech-stack string --model-family string --include-tests boolean --include-review boolean --create-pr boolean
func (m *MyModule) Example(ctx context.Context, prompt string, issueId int, repository string, agents string, techStack string, modelFamily string, includeTests bool, includeReview bool, createPr bool) string  {
	return dag.
			Speck().
			Decompose(ctx, prompt, issueId, repository, agents, techStack, modelFamily, includeTests, includeReview, createPr)
}
@function
async def example(prompt: str, issue_id: int, repository: str, agents: str, tech_stack: str, model_family: str, include_tests: bool, include_review: bool, create_pr: bool) -> str:
	return await (
		dag.speck()
		.decompose(prompt, issue_id, repository, agents, tech_stack, model_family, include_tests, include_review, create_pr)
	)
@func()
async example(prompt: string, issueId: number, repository: string, agents: string, techStack: string, modelFamily: string, includeTests: boolean, includeReview: boolean, createPr: boolean): Promise<string> {
	return dag
		.speck()
		.decompose(prompt, issueId, repository, agents, techStack, modelFamily, includeTests, includeReview, createPr)
}

decomposeFromSpec() 🔗

Decompose a pre-existing spec and plan into structured tasks.

Use this when you already have a specification and plan (e.g. from manual spec-kit usage) and want to generate the structured JSON task list with agent assignments.

Return Type
String !
Arguments
NameTypeDefault ValueDescription
specString !-Feature specification markdown
planString !-Technical implementation plan markdown
agentsString !"[]"JSON array of available agents
modelFamilyString !"claude"Model family for suggestions: 'claude' (default), 'gemini', or 'openai'
includeTestsBoolean !falseGenerate test tasks (write_tests) after implementation tasks
includeReviewBoolean !falseGenerate review tasks (review) at the end of each phase
createPrBoolean !falseAdd PR branch names to phases for automated PR creation (one PR per phase)
Example
dagger -m github.com/telchak/daggerverse/speck@b7e5030da94a1004c04cde234845538e9502bcc5 call \
 decompose-from-spec --spec string --plan string --agents string --model-family string --include-tests boolean --include-review boolean --create-pr boolean
func (m *MyModule) Example(ctx context.Context, spec string, plan string, agents string, modelFamily string, includeTests bool, includeReview bool, createPr bool) string  {
	return dag.
			Speck().
			DecomposeFromSpec(ctx, spec, plan, agents, modelFamily, includeTests, includeReview, createPr)
}
@function
async def example(spec: str, plan: str, agents: str, model_family: str, include_tests: bool, include_review: bool, create_pr: bool) -> str:
	return await (
		dag.speck()
		.decompose_from_spec(spec, plan, agents, model_family, include_tests, include_review, create_pr)
	)
@func()
async example(spec: string, plan: string, agents: string, modelFamily: string, includeTests: boolean, includeReview: boolean, createPr: boolean): Promise<string> {
	return dag
		.speck()
		.decomposeFromSpec(spec, plan, agents, modelFamily, includeTests, includeReview, createPr)
}

editFile() 🔗

Edit a file by replacing a string. The old_string must match exactly.

Return Type
Changeset !
Arguments
NameTypeDefault ValueDescription
filePathString !-Path to the file relative to the workspace root
oldStringString !-The exact string to find and replace
newStringString !-The replacement string
replaceAllBoolean !falseReplace all occurrences (default: first only)
Example
dagger -m github.com/telchak/daggerverse/speck@b7e5030da94a1004c04cde234845538e9502bcc5 call \
 edit-file --file-path string --old-string string --new-string string --replace-all boolean
func (m *MyModule) Example(filePath string, oldString string, newString string, replaceAll bool) *dagger.Changeset  {
	return dag.
			Speck().
			EditFile(filePath, oldString, newString, replaceAll)
}
@function
def example(file_path: str, old_string: str, new_string: str, replace_all: bool) -> dagger.Changeset:
	return (
		dag.speck()
		.edit_file(file_path, old_string, new_string, replace_all)
	)
@func()
example(filePath: string, oldString: string, newString: string, replaceAll: boolean): Changeset {
	return dag
		.speck()
		.editFile(filePath, oldString, newString, replaceAll)
}

glob() 🔗

Find files in the workspace matching a glob pattern.

Return Type
String !
Arguments
NameTypeDefault ValueDescription
patternString !-Glob pattern (e.g. 'src/**/*.py', '**/*.toml')
Example
dagger -m github.com/telchak/daggerverse/speck@b7e5030da94a1004c04cde234845538e9502bcc5 call \
 glob --pattern string
func (m *MyModule) Example(ctx context.Context, pattern string) string  {
	return dag.
			Speck().
			Glob(ctx, pattern)
}
@function
async def example(pattern: str) -> str:
	return await (
		dag.speck()
		.glob(pattern)
	)
@func()
async example(pattern: string): Promise<string> {
	return dag
		.speck()
		.glob(pattern)
}

grep() 🔗

Search file contents in the workspace using grep.

Return Type
String !
Arguments
NameTypeDefault ValueDescription
patternString !-Search pattern (regex supported)
pathsString !""Comma-separated paths to search in (optional)
fileGlobString !""Glob pattern to filter files (e.g. '*.py')
insensitiveBoolean !falseCase-insensitive search
limitInteger !100Maximum number of matching lines to return
Example
dagger -m github.com/telchak/daggerverse/speck@b7e5030da94a1004c04cde234845538e9502bcc5 call \
 grep --pattern string --paths string --file-glob string --insensitive boolean --limit integer
func (m *MyModule) Example(ctx context.Context, pattern string, paths string, fileGlob string, insensitive bool, limit int) string  {
	return dag.
			Speck().
			Grep(ctx, pattern, paths, fileGlob, insensitive, limit)
}
@function
async def example(pattern: str, paths: str, file_glob: str, insensitive: bool, limit: int) -> str:
	return await (
		dag.speck()
		.grep(pattern, paths, file_glob, insensitive, limit)
	)
@func()
async example(pattern: string, paths: string, fileGlob: string, insensitive: boolean, limit: number): Promise<string> {
	return dag
		.speck()
		.grep(pattern, paths, fileGlob, insensitive, limit)
}

plan() 🔗

Generate a technical implementation plan from a specification.

Takes a feature specification and produces a technical plan with architecture decisions, project structure, dependencies, and complexity analysis. Returns the plan as markdown text.

Return Type
String !
Arguments
NameTypeDefault ValueDescription
specString !-Feature specification (output of specify)
techStackString !""Tech stack hints (e.g. 'Python, FastAPI, PostgreSQL')
Example
dagger -m github.com/telchak/daggerverse/speck@b7e5030da94a1004c04cde234845538e9502bcc5 call \
 plan --spec string --tech-stack string
func (m *MyModule) Example(ctx context.Context, spec string, techStack string) string  {
	return dag.
			Speck().
			Plan(ctx, spec, techStack)
}
@function
async def example(spec: str, tech_stack: str) -> str:
	return await (
		dag.speck()
		.plan(spec, tech_stack)
	)
@func()
async example(spec: string, techStack: string): Promise<string> {
	return dag
		.speck()
		.plan(spec, techStack)
}

readFile() 🔗

Read a file from the workspace with line numbers.

Return Type
String !
Arguments
NameTypeDefault ValueDescription
filePathString !-Path to the file relative to the workspace root
offsetInteger !0Line number to start reading from (1-based)
limitInteger !0Maximum number of lines to read
Example
dagger -m github.com/telchak/daggerverse/speck@b7e5030da94a1004c04cde234845538e9502bcc5 call \
 read-file --file-path string --offset integer --limit integer
func (m *MyModule) Example(ctx context.Context, filePath string, offset int, limit int) string  {
	return dag.
			Speck().
			ReadFile(ctx, filePath, offset, limit)
}
@function
async def example(file_path: str, offset: int, limit: int) -> str:
	return await (
		dag.speck()
		.read_file(file_path, offset, limit)
	)
@func()
async example(filePath: string, offset: number, limit: number): Promise<string> {
	return dag
		.speck()
		.readFile(filePath, offset, limit)
}

specify() 🔗

Generate a feature specification from a prompt or GitHub issue.

Produces a structured specification with user stories, acceptance criteria, functional requirements, and success criteria. Returns the specification as markdown text.

Return Type
String !
Arguments
NameTypeDefault ValueDescription
promptString !""Natural language description of what to build
issueIdInteger !0GitHub issue number (alternative to prompt)
repositoryString !""GitHub repository URL (required if using issue_id)
githubTokenSecret nullGitHub token (required if using issue_id)
Example
dagger -m github.com/telchak/daggerverse/speck@b7e5030da94a1004c04cde234845538e9502bcc5 call \
 specify --prompt string --issue-id integer --repository string
func (m *MyModule) Example(ctx context.Context, prompt string, issueId int, repository string) string  {
	return dag.
			Speck().
			Specify(ctx, prompt, issueId, repository)
}
@function
async def example(prompt: str, issue_id: int, repository: str) -> str:
	return await (
		dag.speck()
		.specify(prompt, issue_id, repository)
	)
@func()
async example(prompt: string, issueId: number, repository: string): Promise<string> {
	return dag
		.speck()
		.specify(prompt, issueId, repository)
}

task() 🔗

Launch a sub-agent for research or focused analysis.

The sub-agent has read-only access to the workspace. Use this for exploring the codebase to inform specification and planning.

Return Type
String !
Arguments
NameTypeDefault ValueDescription
descriptionString !-Short description of the sub-task
promptString !-Detailed prompt for the sub-agent
Example
dagger -m github.com/telchak/daggerverse/speck@b7e5030da94a1004c04cde234845538e9502bcc5 call \
 task --description string --prompt string
func (m *MyModule) Example(ctx context.Context, description string, prompt string) string  {
	return dag.
			Speck().
			Task(ctx, description, prompt)
}
@function
async def example(description: str, prompt: str) -> str:
	return await (
		dag.speck()
		.task(description, prompt)
	)
@func()
async example(description: string, prompt: string): Promise<string> {
	return dag
		.speck()
		.task(description, prompt)
}

writeFile() 🔗

Create or overwrite a file in the workspace.

Return Type
Changeset !
Arguments
NameTypeDefault ValueDescription
filePathString !-Path to the file relative to the workspace root
contentsString !-The full file contents to write
Example
dagger -m github.com/telchak/daggerverse/speck@b7e5030da94a1004c04cde234845538e9502bcc5 call \
 write-file --file-path string --contents string
func (m *MyModule) Example(filePath string, contents string) *dagger.Changeset  {
	return dag.
			Speck().
			WriteFile(filePath, contents)
}
@function
def example(file_path: str, contents: str) -> dagger.Changeset:
	return (
		dag.speck()
		.write_file(file_path, contents)
	)
@func()
example(filePath: string, contents: string): Changeset {
	return dag
		.speck()
		.writeFile(filePath, contents)
}