neurastream 0.1.5 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/cli/dispatch.ts +4 -2
- package/src/cli/init.ts +26 -20
package/package.json
CHANGED
package/src/cli/dispatch.ts
CHANGED
|
@@ -34,7 +34,9 @@ export function helpText(): string {
|
|
|
34
34
|
"",
|
|
35
35
|
"Usage:",
|
|
36
36
|
" neurastream --help",
|
|
37
|
-
" neurastream init
|
|
37
|
+
" neurastream init [--agent-dir <dir>]",
|
|
38
|
+
" create config, index, notes, blockers, queue template, state dirs",
|
|
39
|
+
" (--agent-dir: keep an existing index/notes/blockers dir)",
|
|
38
40
|
" neurastream adapter install omp",
|
|
39
41
|
" link the omp extension under this HOME",
|
|
40
42
|
" neurastream doctor report hand-edited live files and a stale install",
|
|
@@ -55,7 +57,7 @@ export async function run(cmd: string, args: string[]): Promise<number> {
|
|
|
55
57
|
console.log(helpText());
|
|
56
58
|
return 0;
|
|
57
59
|
}
|
|
58
|
-
if (cmd === "init") return runInit();
|
|
60
|
+
if (cmd === "init") return runInit(args);
|
|
59
61
|
if (cmd === "adapter") return runAdapterInstall(args);
|
|
60
62
|
if (cmd === "config") {
|
|
61
63
|
try {
|
package/src/cli/init.ts
CHANGED
|
@@ -53,19 +53,24 @@ export function installedBins(home: string, invoked: string): string[] {
|
|
|
53
53
|
return [...new Set(out)];
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
// The path keys that sit under the agent dir (same derivation as the queue library's agentDir()).
|
|
57
|
+
const AGENT_DIR_KEYS = /^( (?:agent_dir|queue_index|blockers|notes|ranking_board|subagents|cancelled|unlock): )"~\/\.config\/neurastream/gm;
|
|
58
|
+
|
|
59
|
+
function configText(home: string, invoked: string, agentDir?: string): string {
|
|
57
60
|
let text = readFileSync(TEMPLATE_PATH, "utf8");
|
|
58
61
|
if (!text.endsWith("\n")) text += "\n";
|
|
59
62
|
if (existsSync(join(home, "Work", "pm-counts"))) {
|
|
60
63
|
if (!text.includes('default_repo: ""')) throw new Error("templates/config.yml has no default_repo placeholder");
|
|
61
64
|
text = text.replace('default_repo: ""', 'default_repo: "~/Work/pm-counts"');
|
|
62
65
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
// An existing machine keeps its index, notes, blockers and unlock where they are today.
|
|
67
|
+
const agent = agentDir ? tilde(home, resolve(home, agentDir.replace(/^~(?=\/|$)/, home))) : "~/.config/neurastream";
|
|
68
|
+
if (agentDir) {
|
|
69
|
+
const hits = text.match(AGENT_DIR_KEYS)?.length ?? 0;
|
|
70
|
+
if (hits !== 8) throw new Error(`templates/config.yml: expected 8 agent-dir path keys, found ${hits}`);
|
|
71
|
+
text = text.replace(AGENT_DIR_KEYS, (_m, key: string) => `${key}${yamlQuote(agent).slice(0, -1)}`);
|
|
72
|
+
}
|
|
73
|
+
const protectedPaths = [...installedBins(home, invoked), `${agent}/notes/`, `${agent}/blockers/`, `${agent}/queue/`];
|
|
69
74
|
const list = [" protected:", ...protectedPaths.map(p => ` - ${yamlQuote(p)}`)].join("\n");
|
|
70
75
|
if (!text.includes(" protected: []")) throw new Error("templates/config.yml has no protected placeholder");
|
|
71
76
|
return text.replace(" protected: []", list);
|
|
@@ -101,12 +106,12 @@ Empty until \`agent-score board\` writes this file. Do not hand-edit after that.
|
|
|
101
106
|
`;
|
|
102
107
|
|
|
103
108
|
/** Create the layout. Existing files are left byte-for-byte alone. */
|
|
104
|
-
export function initHome(home: string, opts: { invoked?: string; env?: NodeJS.ProcessEnv } = {}): InitResult {
|
|
109
|
+
export function initHome(home: string, opts: { invoked?: string; env?: NodeJS.ProcessEnv; agentDir?: string } = {}): InitResult {
|
|
105
110
|
const created: string[] = [];
|
|
106
111
|
const unchanged: string[] = [];
|
|
107
112
|
const invoked = opts.invoked ?? "";
|
|
108
113
|
const cfgPath = configFile(home);
|
|
109
|
-
putFile(cfgPath, configText(home, invoked), 0o644, created, unchanged);
|
|
114
|
+
putFile(cfgPath, configText(home, invoked, opts.agentDir), 0o644, created, unchanged);
|
|
110
115
|
|
|
111
116
|
const cfg: Config = loadConfig({ home, env: opts.env ?? {} });
|
|
112
117
|
putDir(cfg.paths.config_dir);
|
|
@@ -127,15 +132,13 @@ export function initHome(home: string, opts: { invoked?: string; env?: NodeJS.Pr
|
|
|
127
132
|
putFile(cfg.paths.subagents, note("subagents.md"), 0o644, created, unchanged);
|
|
128
133
|
putFile(join(cfg.paths.notes, "lessons.md"), note("lessons.md"), 0o644, created, unchanged);
|
|
129
134
|
putFile(cfg.paths.ranking_board, RANKING_STUB, 0o644, created, unchanged);
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
join(
|
|
134
|
-
queueText.
|
|
135
|
-
0o644,
|
|
136
|
-
|
|
137
|
-
unchanged,
|
|
138
|
-
);
|
|
135
|
+
// An adopted agent dir (--agent-dir) keeps queue/ for the harness adapter, which links its own
|
|
136
|
+
// queue/lib.ts and queue/TEMPLATE.md there; two writers for one slot would collide.
|
|
137
|
+
if (!opts.agentDir) {
|
|
138
|
+
const queueText = readFileSync(join(PACKAGE_ROOT, "templates/queue/TEMPLATE.md"), "utf8");
|
|
139
|
+
if (!queueText.includes("{{HOME}}")) throw new Error("templates/queue/TEMPLATE.md has no {{HOME}} placeholder");
|
|
140
|
+
putFile(join(cfg.paths.agent_dir, "queue", "TEMPLATE.md"), queueText.replaceAll("{{HOME}}", home), 0o644, created, unchanged);
|
|
141
|
+
}
|
|
139
142
|
for (const b of BLOCKERS) {
|
|
140
143
|
putFile(join(cfg.paths.blockers, b.name), blockerWrapper(b.fn), 0o755, created, unchanged);
|
|
141
144
|
}
|
|
@@ -152,9 +155,12 @@ export function printInit(result: InitResult): void {
|
|
|
152
155
|
if (result.unchanged.length) console.log(`neurastream init: left ${result.unchanged.length} existing file(s) alone`);
|
|
153
156
|
}
|
|
154
157
|
|
|
155
|
-
export function runInit(): number {
|
|
158
|
+
export function runInit(args: string[] = []): number {
|
|
156
159
|
try {
|
|
157
|
-
|
|
160
|
+
const i = args.indexOf("--agent-dir");
|
|
161
|
+
const agentDir = i >= 0 ? args[i + 1] : undefined;
|
|
162
|
+
if (i >= 0 && !agentDir) throw new Error("usage: neurastream init [--agent-dir <dir>]");
|
|
163
|
+
printInit(initHome(homedir(), { invoked: process.argv[1] ?? "", env: process.env, agentDir }));
|
|
158
164
|
return 0;
|
|
159
165
|
} catch (err) {
|
|
160
166
|
console.error(err instanceof Error ? err.message : String(err));
|