From a18e530c031c9d44af4a134de2dd1b14c029094d Mon Sep 17 00:00:00 2001 From: Markus Fritsche Date: Sun, 10 May 2026 17:12:25 +0000 Subject: [PATCH] main: --config/--help arg parsing, vendor on package.path, REPL start MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 0 entry point per PHASE0.md §4, §10. Resolves the §10 config search: --config (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) --- main.lua | 83 +++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 64 insertions(+), 19 deletions(-) diff --git a/main.lua b/main.lua index 6d7a6af..1af821d 100644 --- a/main.lua +++ b/main.lua @@ -2,31 +2,76 @@ -- Phase 0: arg parsing, config load, REPL start. -- See docs/PHASE0.md §4, §10. -local function load_config() - -- Resolution order per PHASE0.md §10: - -- 1. --config 2. $AISH_CONFIG - -- 3. ~/.config/aish/config.lua 4. ./config.lua - -- Phase 0 stub: pick the first existing path; no CLI parsing yet. - local home = os.getenv("HOME") or "" - local candidates = { - os.getenv("AISH_CONFIG"), - home .. "/.config/aish/config.lua", - "./config.lua", - } - for _, path in ipairs(candidates) do - if path then - local f = io.open(path, "r") - if f then f:close(); return dofile(path), path end +-- 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 ] [--help] + +Config resolution order (PHASE0.md §10): + 1. --config + 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 - error("aish: no config.lua found in any standard location") + return out end -local function main() - local config, config_path = load_config() +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() +main(arg)