Commands and Namespaces
Invowk commands are named directly in invowkfile.cue. Namespaces come from modules: commands in a module are prefixed by the module ID from invowkmod.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 discovered from all sources and made available via their simple names (the name defined in the invowkfile.cue).
// invowkmod.cue
module: "com.company.frontend"
version: "1.0.0"
// invowkfile.cue
cmds: [
{name: "build"},
{name: "test unit"},
]
If these are the only commands with those names, they become available as:
invowk cmd buildinvowk cmd test unit
When command names are unique across all sources, you can omit any prefix and use just the simple command name. Invowk's transparent namespace system automatically resolves unambiguous commands.
If a command name exists in multiple sources, you must disambiguate using the @source prefix:
invowk cmd @invowkfile deploy(from local invowkfile)invowk cmd @com.company.frontend deploy(from specific module)
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 invowkfile (highest priority)
- Local modules (
*.invowkmodin current directory) - Configured includes (module paths from config file)
- User commands directory (
~/.invowk/cmds/—*.invowkmodonly, non-recursive)
When listing commands, you’ll see their source:
Available Commands
(* = default runtime)
From invowkfile:
build - Build the project [native*] (linux, macos, windows)
From tools.invowkmod:
hello - A greeting [native*] (linux, macos)
Command Dependencies
Commands can depend on other commands. Use the full command name as listed by invowk cmd (module prefix when applicable):
cmds: [
{
name: "build"
implementations: [...]
},
{
name: "test"
implementations: [...]
depends_on: {
cmds: [
// Reference by command name in the same invowkfile
{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