Commands and Namespaces
Invowk commands are named directly in invkfile.cue. Namespaces come from modules: commands in a module are prefixed by the module ID from invkmod.cue.
Command Names
Command names can include spaces to create subcommand-like hierarchies:
cmds: [
{name: "test"},
{name: "test unit"},
{name: "test integration"},
{name: "db migrate"},
{name: "db seed"},
]
Command Naming Rules
| Rule | Valid | Invalid |
|---|---|---|
| Must start with a letter | build, Test | 1build |
| Letters, numbers, spaces, hyphens, underscores | test unit, build-all | build@all |
Spaces are purely organizational - there’s no special parent-child relationship between commands.
Module Namespaces
Module commands are namespaced by the module field in invkmod.cue:
// invkmod.cue
module: "com.company.frontend"
// invkfile.cue
cmds: [
{name: "build"},
{name: "test unit"},
]
These commands become available as:
invowk cmd com.company.frontend buildinvowk cmd com.company.frontend test unit
When command names are unique across all sources, you can omit the module prefix and use just the command name (e.g., invowk cmd build). Invowk's transparent namespace system automatically resolves unambiguous commands. The full module prefix is only required when the same command name exists in multiple modules or sources.
Module ID Naming Rules
| Rule | Valid | Invalid |
|---|---|---|
| Must start with a letter | myproject, Project1 | 1project, _project |
| Letters and numbers only | myproject, v2 | my-project, my_project |
| Dots for nesting | my.project, a.b.c | my..project, .project, project. |
Valid Examples
module: "frontend"
module: "backend"
module: "my.project"
module: "com.company.tools"
module: "io.github.username.cli"
Invalid Examples
module: "my-project" // Hyphens not allowed
module: "my_project" // Underscores not allowed
module: ".project" // Can't start with dot
module: "project." // Can't end with dot
module: "my..project" // No consecutive dots
module: "123project" // Must start with letter
For shared modules, use Reverse Domain Name System (RDNS) naming (e.g., com.company.tools) to prevent collisions.
Command Discovery
Invowk discovers commands from multiple sources in priority order:
- Current directory (highest priority)
- User commands directory (
~/.invowk/cmds/) - Configured search paths (from config file)
When listing commands, you’ll see their source:
Available Commands
(* = default runtime)
From current directory:
build - Build the project [native*] (linux, macos, windows)
From user commands (~/.invowk/cmds):
com.example.tools hello - A greeting [native*] (linux, macos)
Command Dependencies
Commands can depend on other commands. Use the full command name as listed by invowk cmd --list (module prefix when applicable):
cmds: [
{
name: "build"
implementations: [...]
},
{
name: "test"
implementations: [...]
depends_on: {
cmds: [
// Reference by command name in the same invkfile
{alternatives: ["build"]}
]
}
},
{
name: "release"
implementations: [...]
depends_on: {
cmds: [
// Module-prefixed commands for dependencies
{alternatives: ["build"]},
{alternatives: ["com.company.tools lint"]},
]
}
}
]
Why Namespaces Matter
- Namespace isolation - Module commands stay distinct across shared toolkits
- Clear origin - Module prefixes show where commands come from
- Logical organization - Dot-separated module IDs organize related commands
- Tab completion - Module IDs provide natural completion boundaries
Best Practices
- Local projects: Keep command names short and focused (no prefixes).
- Modules: Use RDNS module IDs like
com.company.devtools. - Avoid generic module IDs: Prefer
com.company.toolsovertools.
Next Steps
- Implementations - Learn about platform-specific command implementations
- Runtime Modes - Understand native, virtual, and container execution