a18e530c03
Phase 0 entry point per PHASE0.md §4, §10.
Resolves the §10 config search:
--config <path> (explicit; failure if not openable, no fallback)
$AISH_CONFIG
~/.config/aish/config.lua
./config.lua
The explicit form now hard-fails instead of silently falling through to
the next candidate — caught in smoke (`--config /nonexistent` was loading
./config.lua).
Pre-pends `./?.lua;./vendor/?.lua` to package.path so `require("dkjson")`
finds vendor/dkjson.lua and project requires resolve from the repo root.
Run from the repo root; cwd-independent resolution lands later.
`--help` prints the usage block. Unrecognized arg exits 2 with a
diagnostic on stderr.
Phase 0 done-criteria (PHASE0.md §2):
✓ shell command execution with framed output
✓ :meta commands (full §5.2 set)
✓ in-memory conversation history with sliding-window eviction
✓ codebase layout matches §4 — every module name stable for Phase 1+
⏳ live AI exchange — structurally wired; live test deferred per
issue #12 (broker endpoint hostname not resolvable from noether)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
78 lines
2.2 KiB
Lua
78 lines
2.2 KiB
Lua
-- main.lua — entry point
|
|
-- Phase 0: arg parsing, config load, REPL start.
|
|
-- See docs/PHASE0.md §4, §10.
|
|
|
|
-- Make project modules and the vendored dkjson resolvable from the repo root.
|
|
-- Run aish with the repo root as cwd; PTY-relative resolution lands later.
|
|
package.path = "./?.lua;./vendor/?.lua;" .. package.path
|
|
|
|
local USAGE = [[
|
|
aish — AI-augmented conversational shell.
|
|
|
|
Usage: luajit main.lua [--config <path>] [--help]
|
|
|
|
Config resolution order (PHASE0.md §10):
|
|
1. --config <path>
|
|
2. $AISH_CONFIG
|
|
3. ~/.config/aish/config.lua
|
|
4. ./config.lua
|
|
]]
|
|
|
|
local function parse_args(argv)
|
|
local out = {}
|
|
local i = 1
|
|
while i <= #argv do
|
|
local a = argv[i]
|
|
if a == "--config" then
|
|
out.config = argv[i + 1]
|
|
i = i + 2
|
|
elseif a == "--help" or a == "-h" then
|
|
out.help = true
|
|
i = i + 1
|
|
else
|
|
io.stderr:write("aish: unrecognized argument: " .. a .. "\n")
|
|
os.exit(2)
|
|
end
|
|
end
|
|
return out
|
|
end
|
|
|
|
local function load_config(opts)
|
|
-- --config is explicit: use exactly that path or fail. No silent fallback.
|
|
if opts.config then
|
|
local f = io.open(opts.config, "r")
|
|
if not f then
|
|
error("aish: --config " .. opts.config .. ": cannot open")
|
|
end
|
|
f:close()
|
|
return dofile(opts.config), opts.config
|
|
end
|
|
|
|
local home = os.getenv("HOME") or ""
|
|
local candidates = {}
|
|
local function push(p) if p and p ~= "" then candidates[#candidates + 1] = p end end
|
|
push(os.getenv("AISH_CONFIG"))
|
|
push(home .. "/.config/aish/config.lua")
|
|
push("./config.lua")
|
|
|
|
for _, path in ipairs(candidates) do
|
|
local f = io.open(path, "r")
|
|
if f then f:close(); return dofile(path), path end
|
|
end
|
|
error("aish: no config.lua found (tried: "
|
|
.. table.concat(candidates, ", ") .. ")")
|
|
end
|
|
|
|
local function main(argv)
|
|
local opts = parse_args(argv or {})
|
|
if opts.help then io.write(USAGE); return end
|
|
|
|
local config, config_path = load_config(opts)
|
|
io.stderr:write(("aish: loaded config from %s\n"):format(config_path))
|
|
|
|
local repl = require("repl")
|
|
repl.run(config)
|
|
end
|
|
|
|
main(arg)
|