@corenel/cli 0.4.2 → 0.4.4
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/dist/cli.js +241 -75
- package/package.json +5 -5
package/dist/cli.js
CHANGED
|
@@ -18931,42 +18931,58 @@ function credentialFilePath(stateDir) {
|
|
|
18931
18931
|
}
|
|
18932
18932
|
var TOKEN_ENV = "CORENEL_TOKEN";
|
|
18933
18933
|
var API_BASE_ENV = "CORENEL_API_BASE";
|
|
18934
|
-
async function writeAuthToken(token, stateDir) {
|
|
18935
|
-
const dir = credentialDir(stateDir);
|
|
18936
|
-
const path = tokenFilePath(stateDir);
|
|
18937
|
-
await fs2.mkdir(dir, { recursive: true, mode: 448 });
|
|
18938
|
-
await fs2.writeFile(path, token.trim() + "\n", { mode: 384 });
|
|
18939
|
-
try {
|
|
18940
|
-
await fs2.chmod(path, 384);
|
|
18941
|
-
} catch {
|
|
18942
|
-
}
|
|
18943
|
-
try {
|
|
18944
|
-
await fs2.chmod(dir, 448);
|
|
18945
|
-
} catch {
|
|
18946
|
-
}
|
|
18947
|
-
}
|
|
18948
18934
|
async function writeLoginCredential(token, opts = {}) {
|
|
18949
18935
|
const cred = {
|
|
18950
18936
|
accessToken: token.trim(),
|
|
18951
18937
|
...opts.account ? { account: opts.account } : {},
|
|
18952
18938
|
...opts.apiBase ? { apiBase: opts.apiBase } : {}
|
|
18953
18939
|
};
|
|
18954
|
-
const
|
|
18955
|
-
|
|
18956
|
-
|
|
18940
|
+
const dir = credentialDir(opts.stateDir);
|
|
18941
|
+
const credPath = credentialFilePath(opts.stateDir);
|
|
18942
|
+
const tokPath = tokenFilePath(opts.stateDir);
|
|
18943
|
+
await fs2.mkdir(dir, { recursive: true, mode: 448 });
|
|
18944
|
+
const credTmp = `${credPath}.tmp-${process.pid.toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
18945
|
+
const tokTmp = `${tokPath}.tmp-${process.pid.toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
|
|
18946
|
+
await fs2.writeFile(credTmp, `${JSON.stringify(cred, null, 2)}
|
|
18947
|
+
`, { mode: 384 });
|
|
18948
|
+
await fs2.writeFile(tokTmp, `${cred.accessToken}
|
|
18957
18949
|
`, { mode: 384 });
|
|
18958
18950
|
try {
|
|
18959
|
-
await fs2.chmod(
|
|
18951
|
+
await fs2.chmod(credTmp, 384);
|
|
18960
18952
|
} catch {
|
|
18961
18953
|
}
|
|
18962
|
-
|
|
18954
|
+
try {
|
|
18955
|
+
await fs2.chmod(tokTmp, 384);
|
|
18956
|
+
} catch {
|
|
18957
|
+
}
|
|
18958
|
+
try {
|
|
18959
|
+
await fs2.rename(credTmp, credPath);
|
|
18960
|
+
await fs2.rename(tokTmp, tokPath);
|
|
18961
|
+
} catch (e) {
|
|
18962
|
+
try {
|
|
18963
|
+
await fs2.rm(credTmp, { force: true });
|
|
18964
|
+
} catch {
|
|
18965
|
+
}
|
|
18966
|
+
try {
|
|
18967
|
+
await fs2.rm(tokTmp, { force: true });
|
|
18968
|
+
} catch {
|
|
18969
|
+
}
|
|
18970
|
+
throw e;
|
|
18971
|
+
}
|
|
18972
|
+
try {
|
|
18973
|
+
await fs2.chmod(dir, 448);
|
|
18974
|
+
} catch {
|
|
18975
|
+
}
|
|
18976
|
+
}
|
|
18977
|
+
function isMissing(err) {
|
|
18978
|
+
return typeof err === "object" && err !== null && err.code === "ENOENT";
|
|
18963
18979
|
}
|
|
18964
|
-
async function
|
|
18980
|
+
async function readAuthTokenRead(stateDir) {
|
|
18965
18981
|
try {
|
|
18966
18982
|
const t = (await fs2.readFile(tokenFilePath(stateDir), "utf8")).trim();
|
|
18967
|
-
return t || null;
|
|
18968
|
-
} catch {
|
|
18969
|
-
return null;
|
|
18983
|
+
return { value: t || null, unreadable: false };
|
|
18984
|
+
} catch (err) {
|
|
18985
|
+
return { value: null, unreadable: !isMissing(err) };
|
|
18970
18986
|
}
|
|
18971
18987
|
}
|
|
18972
18988
|
async function clearAuthToken(stateDir) {
|
|
@@ -18975,27 +18991,30 @@ async function clearAuthToken(stateDir) {
|
|
|
18975
18991
|
} catch {
|
|
18976
18992
|
}
|
|
18977
18993
|
}
|
|
18978
|
-
async function
|
|
18994
|
+
async function readCredentialFileRead(stateDir) {
|
|
18979
18995
|
let raw;
|
|
18980
18996
|
try {
|
|
18981
18997
|
raw = await fs2.readFile(credentialFilePath(stateDir), "utf8");
|
|
18982
|
-
} catch {
|
|
18983
|
-
return null;
|
|
18998
|
+
} catch (err) {
|
|
18999
|
+
return { value: null, unreadable: !isMissing(err) };
|
|
18984
19000
|
}
|
|
18985
19001
|
try {
|
|
18986
19002
|
const parsed = JSON.parse(raw);
|
|
18987
|
-
if (typeof parsed !== "object" || parsed === null) return null;
|
|
19003
|
+
if (typeof parsed !== "object" || parsed === null) return { value: null, unreadable: false };
|
|
18988
19004
|
const c = parsed;
|
|
18989
|
-
if (typeof c.accessToken !== "string" || !c.accessToken) return null;
|
|
19005
|
+
if (typeof c.accessToken !== "string" || !c.accessToken) return { value: null, unreadable: false };
|
|
18990
19006
|
return {
|
|
18991
|
-
|
|
18992
|
-
|
|
18993
|
-
|
|
18994
|
-
|
|
18995
|
-
|
|
19007
|
+
value: {
|
|
19008
|
+
accessToken: c.accessToken,
|
|
19009
|
+
...typeof c.refreshToken === "string" ? { refreshToken: c.refreshToken } : {},
|
|
19010
|
+
...typeof c.expiresAt === "number" ? { expiresAt: c.expiresAt } : {},
|
|
19011
|
+
...typeof c.account === "string" ? { account: c.account } : {},
|
|
19012
|
+
...typeof c.apiBase === "string" && c.apiBase ? { apiBase: c.apiBase } : {}
|
|
19013
|
+
},
|
|
19014
|
+
unreadable: false
|
|
18996
19015
|
};
|
|
18997
19016
|
} catch {
|
|
18998
|
-
return null;
|
|
19017
|
+
return { value: null, unreadable: false };
|
|
18999
19018
|
}
|
|
19000
19019
|
}
|
|
19001
19020
|
async function clearAllCredentials(stateDir) {
|
|
@@ -19011,20 +19030,29 @@ async function resolveNodeCredential(opts = {}) {
|
|
|
19011
19030
|
const stateDir = opts.stateDir;
|
|
19012
19031
|
const fromEnv = env[TOKEN_ENV]?.trim();
|
|
19013
19032
|
if (fromEnv) return { token: fromEnv, source: "env" };
|
|
19014
|
-
const
|
|
19015
|
-
const
|
|
19033
|
+
const credRead = await readCredentialFileRead(stateDir);
|
|
19034
|
+
const tokenRead = await readAuthTokenRead(stateDir);
|
|
19035
|
+
const cred = credRead.value;
|
|
19036
|
+
const fileToken = tokenRead.value;
|
|
19037
|
+
const unreadable = credRead.unreadable || tokenRead.unreadable ? { unreadable: true } : {};
|
|
19016
19038
|
if (fileToken) {
|
|
19017
19039
|
const same = cred && cred.accessToken === fileToken ? cred : null;
|
|
19018
|
-
return
|
|
19040
|
+
return {
|
|
19041
|
+
...withExpiry({ token: fileToken, source: "token-file", path: tokenFilePath(stateDir) }, same, now),
|
|
19042
|
+
...unreadable
|
|
19043
|
+
};
|
|
19019
19044
|
}
|
|
19020
19045
|
if (cred) {
|
|
19021
|
-
return
|
|
19022
|
-
|
|
19023
|
-
|
|
19024
|
-
|
|
19025
|
-
|
|
19046
|
+
return {
|
|
19047
|
+
...withExpiry(
|
|
19048
|
+
{ token: cred.accessToken, source: "credential-file", path: credentialFilePath(stateDir) },
|
|
19049
|
+
cred,
|
|
19050
|
+
now
|
|
19051
|
+
),
|
|
19052
|
+
...unreadable
|
|
19053
|
+
};
|
|
19026
19054
|
}
|
|
19027
|
-
return { token: null, source: "none" };
|
|
19055
|
+
return { token: null, source: "none", ...unreadable };
|
|
19028
19056
|
}
|
|
19029
19057
|
function withExpiry(base, cred, now) {
|
|
19030
19058
|
if (!cred) return base;
|
|
@@ -22162,24 +22190,35 @@ import { PermissionService as PermissionService4 } from "@corenel/harness/guardr
|
|
|
22162
22190
|
import { ROOT_NODE_ID } from "@corenel/protocol";
|
|
22163
22191
|
import { makeSpawn } from "@corenel/harness/core/spawn";
|
|
22164
22192
|
function inMemoryMemory() {
|
|
22165
|
-
const items =
|
|
22166
|
-
let n = 0;
|
|
22193
|
+
const items = /* @__PURE__ */ new Map();
|
|
22167
22194
|
return {
|
|
22168
|
-
async save(
|
|
22169
|
-
const it = {
|
|
22170
|
-
|
|
22195
|
+
async save(input) {
|
|
22196
|
+
const it = {
|
|
22197
|
+
id: input.name,
|
|
22198
|
+
name: input.name,
|
|
22199
|
+
type: input.type,
|
|
22200
|
+
description: input.description,
|
|
22201
|
+
text: input.body,
|
|
22202
|
+
tags: [],
|
|
22203
|
+
createdAt: Date.now()
|
|
22204
|
+
};
|
|
22205
|
+
items.set(input.name, it);
|
|
22171
22206
|
return it;
|
|
22172
22207
|
},
|
|
22208
|
+
async read(name) {
|
|
22209
|
+
return items.get(name) ?? null;
|
|
22210
|
+
},
|
|
22173
22211
|
async recall(q) {
|
|
22174
|
-
return items.filter((i) => i.text.includes(q));
|
|
22212
|
+
return [...items.values()].filter((i) => i.text.includes(q) || i.description.includes(q));
|
|
22175
22213
|
},
|
|
22176
22214
|
async list() {
|
|
22177
|
-
return [...items];
|
|
22215
|
+
return [...items.values()];
|
|
22178
22216
|
},
|
|
22179
|
-
async forget(
|
|
22180
|
-
|
|
22181
|
-
if (i >= 0) items.splice(i, 1);
|
|
22217
|
+
async forget(name) {
|
|
22218
|
+
items.delete(name);
|
|
22182
22219
|
}
|
|
22220
|
+
// No core(): this stub has no tiers, and Task 9 injects nothing rather than
|
|
22221
|
+
// pretending it has a memory block.
|
|
22183
22222
|
};
|
|
22184
22223
|
}
|
|
22185
22224
|
function inMemoryKv() {
|
|
@@ -22211,7 +22250,7 @@ function previewWrite(files) {
|
|
|
22211
22250
|
}
|
|
22212
22251
|
function nodeToolCtx(signal, opts = {}) {
|
|
22213
22252
|
const base = {
|
|
22214
|
-
memory: inMemoryMemory(),
|
|
22253
|
+
memory: opts.memory ?? inMemoryMemory(),
|
|
22215
22254
|
kv: inMemoryKv(),
|
|
22216
22255
|
search: nullSearch,
|
|
22217
22256
|
confirm: async () => true,
|
|
@@ -22252,6 +22291,42 @@ function tokenGuard(getToken) {
|
|
|
22252
22291
|
var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
22253
22292
|
var MIN_POLL_MS = 1e3;
|
|
22254
22293
|
var DEFAULT_LIFETIME_S = 900;
|
|
22294
|
+
var ACCOUNT_LOOKUP_MS = 5e3;
|
|
22295
|
+
function deadlineSignal(ms, outer) {
|
|
22296
|
+
const ac = new AbortController();
|
|
22297
|
+
const onOuter = () => ac.abort();
|
|
22298
|
+
const timer = setTimeout(() => ac.abort(), ms);
|
|
22299
|
+
if (outer) {
|
|
22300
|
+
if (outer.aborted) ac.abort();
|
|
22301
|
+
else outer.addEventListener("abort", onOuter, { once: true });
|
|
22302
|
+
}
|
|
22303
|
+
return {
|
|
22304
|
+
signal: ac.signal,
|
|
22305
|
+
dispose: () => {
|
|
22306
|
+
clearTimeout(timer);
|
|
22307
|
+
outer?.removeEventListener("abort", onOuter);
|
|
22308
|
+
}
|
|
22309
|
+
};
|
|
22310
|
+
}
|
|
22311
|
+
async function whoIsThis(base, token, f, outer, deadlineMs = ACCOUNT_LOOKUP_MS) {
|
|
22312
|
+
const { signal, dispose } = deadlineSignal(deadlineMs, outer);
|
|
22313
|
+
try {
|
|
22314
|
+
const res = await f(`${base}/auth/me`, {
|
|
22315
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
22316
|
+
signal
|
|
22317
|
+
});
|
|
22318
|
+
if (!res.ok) return void 0;
|
|
22319
|
+
const body = JSON.parse(await res.text());
|
|
22320
|
+
const email = body?.user?.email;
|
|
22321
|
+
if (typeof email !== "string") return void 0;
|
|
22322
|
+
const trimmed = email.trim();
|
|
22323
|
+
return trimmed ? trimmed : void 0;
|
|
22324
|
+
} catch {
|
|
22325
|
+
return void 0;
|
|
22326
|
+
} finally {
|
|
22327
|
+
dispose();
|
|
22328
|
+
}
|
|
22329
|
+
}
|
|
22255
22330
|
function defaultOpen(uri, code2) {
|
|
22256
22331
|
process.stdout.write(`
|
|
22257
22332
|
To authorize, open: ${uri}
|
|
@@ -22300,7 +22375,9 @@ async function deviceLogin(opts) {
|
|
|
22300
22375
|
client_id: "corenel-cli"
|
|
22301
22376
|
});
|
|
22302
22377
|
if (tok.access_token) {
|
|
22303
|
-
|
|
22378
|
+
const claimed = typeof tok.account === "string" ? tok.account.trim() : "";
|
|
22379
|
+
const account = claimed || await whoIsThis(base, tok.access_token, f, opts.signal, opts.accountLookupMs);
|
|
22380
|
+
await opts.store(tok.access_token, account || void 0);
|
|
22304
22381
|
return tok.access_token;
|
|
22305
22382
|
}
|
|
22306
22383
|
if (tok.error === "authorization_pending") continue;
|
|
@@ -22450,6 +22527,41 @@ function isValidAgentName(name) {
|
|
|
22450
22527
|
// ../crew/store.ts
|
|
22451
22528
|
var import_yaml3 = __toESM(require_dist(), 1);
|
|
22452
22529
|
import { flattenFiles as flattenFiles3 } from "@corenel/protocol";
|
|
22530
|
+
|
|
22531
|
+
// ../crew/sessionBinding.ts
|
|
22532
|
+
var SESSION_NAME_RE = /^[a-z0-9_-]{1,32}$/;
|
|
22533
|
+
function isValidSessionName(name) {
|
|
22534
|
+
return SESSION_NAME_RE.test(name);
|
|
22535
|
+
}
|
|
22536
|
+
function parseSessionBinding(meta) {
|
|
22537
|
+
const raw = meta.session;
|
|
22538
|
+
if (raw === void 0) return { kind: "absent" };
|
|
22539
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
22540
|
+
return { kind: "malformed", reason: "session: must be a block with `name:` and `workdir:`" };
|
|
22541
|
+
}
|
|
22542
|
+
const o = raw;
|
|
22543
|
+
const name = typeof o.name === "string" ? o.name : "";
|
|
22544
|
+
const workdir = typeof o.workdir === "string" ? o.workdir.trim() : "";
|
|
22545
|
+
if (!isValidSessionName(name)) {
|
|
22546
|
+
return {
|
|
22547
|
+
kind: "malformed",
|
|
22548
|
+
reason: `session.name ${JSON.stringify(name)} must be 1-32 characters of a-z, 0-9, "-" or "_"`
|
|
22549
|
+
};
|
|
22550
|
+
}
|
|
22551
|
+
if (!workdir) return { kind: "malformed", reason: "session.workdir is required" };
|
|
22552
|
+
return {
|
|
22553
|
+
kind: "binding",
|
|
22554
|
+
binding: {
|
|
22555
|
+
name,
|
|
22556
|
+
workdir,
|
|
22557
|
+
// Anything but an explicit `false` is true, matching how `enabled` is read
|
|
22558
|
+
// in store.ts — absent means the default, and the default is on.
|
|
22559
|
+
createIfMissing: o.createIfMissing !== false
|
|
22560
|
+
}
|
|
22561
|
+
};
|
|
22562
|
+
}
|
|
22563
|
+
|
|
22564
|
+
// ../crew/store.ts
|
|
22453
22565
|
var TRIGGER_TYPES = [
|
|
22454
22566
|
"manual",
|
|
22455
22567
|
"file-change",
|
|
@@ -22535,6 +22647,7 @@ async function loadCrewAgentAt(files, root, name, scope = "workspace") {
|
|
|
22535
22647
|
if (!isValidAgentName(name)) throw new Error(`invalid crew agent name: ${name}`);
|
|
22536
22648
|
const dir = `${root}/${name}`;
|
|
22537
22649
|
const { meta, body } = parseFrontmatter(await readOr(files, `${dir}/AGENT.md`));
|
|
22650
|
+
const session = parseSessionBinding(meta);
|
|
22538
22651
|
return {
|
|
22539
22652
|
name,
|
|
22540
22653
|
jobTitle: typeof meta.jobTitle === "string" ? meta.jobTitle : "",
|
|
@@ -22549,7 +22662,9 @@ async function loadCrewAgentAt(files, root, name, scope = "workspace") {
|
|
|
22549
22662
|
policy: parsePolicyYaml(await readOr(files, `${dir}/POLICY.yaml`), name),
|
|
22550
22663
|
settings: parseSettings(await readOr(files, `${dir}/settings.json`, "{}")),
|
|
22551
22664
|
budget: parseBudget(meta),
|
|
22552
|
-
canCall: parseCanCall(meta)
|
|
22665
|
+
canCall: parseCanCall(meta),
|
|
22666
|
+
...session.kind === "binding" ? { session: session.binding } : {},
|
|
22667
|
+
...session.kind === "malformed" ? { sessionError: session.reason } : {}
|
|
22553
22668
|
};
|
|
22554
22669
|
}
|
|
22555
22670
|
async function loadCrewAgentAtIfExists(files, root, name, scope = "workspace") {
|
|
@@ -22566,7 +22681,10 @@ async function loadCrewAgentAtIfExists(files, root, name, scope = "workspace") {
|
|
|
22566
22681
|
// ../crew/runtime.ts
|
|
22567
22682
|
import { saveCustomPolicy } from "@corenel/harness/guardrail";
|
|
22568
22683
|
import { allTools } from "@corenel/harness/tools/builtins";
|
|
22684
|
+
import { registerSyncConfig, readConfigSyncRendered } from "@corenel/harness/prompts/syncConfig";
|
|
22569
22685
|
import { makeCallAgentTool } from "@corenel/harness/tools/callAgent";
|
|
22686
|
+
var MEMORY_BLOCK = registerSyncConfig("crew/memory.md");
|
|
22687
|
+
var SELF_DIRECTION_BLOCK = registerSyncConfig("crew/self-direction.md");
|
|
22570
22688
|
function buildSystemExtra(def, memoryLocation) {
|
|
22571
22689
|
const parts = [];
|
|
22572
22690
|
if (def.jobTitle?.trim()) parts.push(`--- Role ---
|
|
@@ -22580,11 +22698,7 @@ ${def.instructions.trim()}`);
|
|
|
22580
22698
|
const location = memoryLocation ?? "memory/";
|
|
22581
22699
|
const dir = location.replace(/\/+$/, "");
|
|
22582
22700
|
const index = `${dir}/MEMORY.md`;
|
|
22583
|
-
parts.push(
|
|
22584
|
-
`--- Memory ---
|
|
22585
|
-
You keep durable notes in your own memory folder, \`${dir}/\`, one Markdown file per note, alongside \`${index}\`, an index you maintain for yourself.
|
|
22586
|
-
Read \`${index}\` at the start of a run to recall what you already know, and call recall_memory to look up one note by name. If you can call save_memory, use it for what is worth knowing on a later run, and keep \`${index}\` current as you do. If a file tool you have takes a \`root\` argument, you can pass \`${dir}/\` as \`root\` to read and edit those files directly.`
|
|
22587
|
-
);
|
|
22701
|
+
parts.push(readConfigSyncRendered(MEMORY_BLOCK, { dir, index }));
|
|
22588
22702
|
const selfDirection = selfDirectionBlock(def);
|
|
22589
22703
|
if (selfDirection) parts.push(selfDirection);
|
|
22590
22704
|
return parts.join("\n\n");
|
|
@@ -22595,23 +22709,58 @@ function selfDirectionBlock(def) {
|
|
|
22595
22709
|
const raw = trigger.config?.fallbackMs;
|
|
22596
22710
|
const fallbackMs = typeof raw === "number" && Number.isFinite(raw) && raw > 0 ? raw : null;
|
|
22597
22711
|
const consequence = fallbackMs == null ? "If this run ends without that call, nothing will wake it again and your work stops here until someone starts you by hand." : `If this run ends without that call you will be woken anyway, about ${Math.round(fallbackMs / 6e4)} minutes from now -- but that is a backstop for a run that could not schedule itself, not a substitute for choosing when you should next run.`;
|
|
22598
|
-
return
|
|
22599
|
-
You run on your own schedule. You will not run again unless you call \`schedule_self\` with the time you should next wake, before this run ends.
|
|
22600
|
-
${consequence}
|
|
22601
|
-
So decide, before you finish, whether there is more to do and when it should happen.`;
|
|
22712
|
+
return readConfigSyncRendered(SELF_DIRECTION_BLOCK, { consequence });
|
|
22602
22713
|
}
|
|
22603
22714
|
|
|
22604
22715
|
// ../crew/memory.ts
|
|
22605
|
-
import {
|
|
22606
|
-
|
|
22716
|
+
import { makeFactStore } from "@corenel/harness/memory/store";
|
|
22717
|
+
function agentMemoryRoot(crewRoot, agentName) {
|
|
22718
|
+
return `${crewRoot}/${agentName}/memory`;
|
|
22719
|
+
}
|
|
22720
|
+
function makeAgentMemoryProvider(getFiles, memoryRoot) {
|
|
22721
|
+
const store = makeFactStore(getFiles, memoryRoot);
|
|
22722
|
+
const toItem = (f) => ({
|
|
22723
|
+
id: f.name,
|
|
22724
|
+
name: f.name,
|
|
22725
|
+
type: f.type,
|
|
22726
|
+
description: f.description,
|
|
22727
|
+
text: f.body,
|
|
22728
|
+
tags: [],
|
|
22729
|
+
createdAt: f.created
|
|
22730
|
+
});
|
|
22731
|
+
return {
|
|
22732
|
+
async save(input) {
|
|
22733
|
+
return toItem(await store.save(input));
|
|
22734
|
+
},
|
|
22735
|
+
async read(name) {
|
|
22736
|
+
const hit = await store.read(name);
|
|
22737
|
+
return hit ? toItem(hit) : null;
|
|
22738
|
+
},
|
|
22739
|
+
async recall(query, limit) {
|
|
22740
|
+
return (await store.recall(query, limit)).map(toItem);
|
|
22741
|
+
},
|
|
22742
|
+
async list(limit) {
|
|
22743
|
+
return (await store.list(limit)).map(toItem);
|
|
22744
|
+
},
|
|
22745
|
+
async forget(name) {
|
|
22746
|
+
return store.forget(name);
|
|
22747
|
+
},
|
|
22748
|
+
async core() {
|
|
22749
|
+
const block = await store.core();
|
|
22750
|
+
return { items: block.facts.map(toItem), archivedCount: block.archivedCount };
|
|
22751
|
+
}
|
|
22752
|
+
};
|
|
22753
|
+
}
|
|
22607
22754
|
|
|
22608
22755
|
// ../crew/room/store.ts
|
|
22609
|
-
import { flattenFiles as
|
|
22756
|
+
import { flattenFiles as flattenFiles4 } from "@corenel/protocol";
|
|
22610
22757
|
import { encodeLine, foldSession } from "@corenel/harness/sessions/jsonl";
|
|
22611
22758
|
import { FINDINGS_FILE, encodeFindingLine, foldFindings } from "@corenel/harness/rooms/findings";
|
|
22612
22759
|
|
|
22613
22760
|
// ../crew/room/prompt.ts
|
|
22761
|
+
import { registerSyncConfig as registerSyncConfig2, readConfigSyncRendered as readConfigSyncRendered2 } from "@corenel/harness/prompts/syncConfig";
|
|
22614
22762
|
import { MAX_ROOM_FINDINGS, renderFindings } from "@corenel/harness/rooms/findings";
|
|
22763
|
+
var ROOM_BLOCK = registerSyncConfig2("crew/room.md");
|
|
22615
22764
|
|
|
22616
22765
|
// ../crew/room/turn.ts
|
|
22617
22766
|
import { readRoomOutcome } from "@corenel/harness/tools/roomTools";
|
|
@@ -22641,6 +22790,12 @@ function workspaceStateDir() {
|
|
|
22641
22790
|
const fromEnv = process.env.CORENEL_STATE_DIR;
|
|
22642
22791
|
return fromEnv && /^\.[A-Za-z0-9][A-Za-z0-9._-]*$/.test(fromEnv) ? fromEnv : stateDirName3();
|
|
22643
22792
|
}
|
|
22793
|
+
function guestCrewRoot() {
|
|
22794
|
+
return `${workspaceStateDir()}/${CREW_SEG}`;
|
|
22795
|
+
}
|
|
22796
|
+
function guestAgentMemoryRoot(agent) {
|
|
22797
|
+
return agentMemoryRoot(guestCrewRoot(), agent);
|
|
22798
|
+
}
|
|
22644
22799
|
function mutatingCeiling(tools, defaultLevel = "deny") {
|
|
22645
22800
|
const overrides = {};
|
|
22646
22801
|
for (const t of tools) if (!t.mutates) overrides[toolAddress(t)] = "allow";
|
|
@@ -22656,7 +22811,9 @@ function eventLine(e) {
|
|
|
22656
22811
|
}
|
|
22657
22812
|
async function runCrewAgentCli(opts) {
|
|
22658
22813
|
const files = new NodeFileService(opts.cwd);
|
|
22659
|
-
const root =
|
|
22814
|
+
const root = guestCrewRoot();
|
|
22815
|
+
const memoryRoot = guestAgentMemoryRoot(opts.agent);
|
|
22816
|
+
const memory = makeAgentMemoryProvider(() => files, memoryRoot);
|
|
22660
22817
|
const def = await loadCrewAgentAtIfExists(files, root, opts.agent, "workspace");
|
|
22661
22818
|
if (!def) {
|
|
22662
22819
|
opts.warn(`no such agent "${opts.agent}" under ${opts.cwd}/${root}`);
|
|
@@ -22674,7 +22831,7 @@ async function runCrewAgentCli(opts) {
|
|
|
22674
22831
|
}
|
|
22675
22832
|
registerGuard(tokenGuard(() => token));
|
|
22676
22833
|
const tools = allTools2();
|
|
22677
|
-
const extra = buildSystemExtra(def);
|
|
22834
|
+
const extra = buildSystemExtra(def, memoryRoot);
|
|
22678
22835
|
let system = extra;
|
|
22679
22836
|
try {
|
|
22680
22837
|
const base = await composeAgentSystem({
|
|
@@ -22717,7 +22874,7 @@ ${extra}` : base;
|
|
|
22717
22874
|
// Cause-aware refusal text -- see cli.ts's `run()` for why the kernel's
|
|
22718
22875
|
// own "denied by the user" default would be a lie on this path.
|
|
22719
22876
|
describePermissionDenial: nonInteractiveDenialMessage,
|
|
22720
|
-
toolCtx: nodeToolCtx(ac.signal, { files }),
|
|
22877
|
+
toolCtx: nodeToolCtx(ac.signal, { files, memory }),
|
|
22721
22878
|
policy: effectivePolicy,
|
|
22722
22879
|
signal: ac.signal,
|
|
22723
22880
|
onEvent: (e) => opts.emit(eventLine(e))
|
|
@@ -23729,9 +23886,14 @@ function isOnValue(value) {
|
|
|
23729
23886
|
return value === void 0 || !FALSY_FLAG_VALUES.has(value.toLowerCase());
|
|
23730
23887
|
}
|
|
23731
23888
|
function hasBooleanFlag(argv, name) {
|
|
23732
|
-
for (
|
|
23733
|
-
const parsed = classifyToken(
|
|
23734
|
-
if (!parsed
|
|
23889
|
+
for (let i = 0; i < argv.length; i++) {
|
|
23890
|
+
const parsed = classifyToken(argv[i]);
|
|
23891
|
+
if (!parsed) continue;
|
|
23892
|
+
if (parsed.value === void 0 && !isBooleanFlag(parsed.name)) {
|
|
23893
|
+
i++;
|
|
23894
|
+
continue;
|
|
23895
|
+
}
|
|
23896
|
+
if (parsed.name !== name) continue;
|
|
23735
23897
|
if (isOnValue(parsed.value)) return true;
|
|
23736
23898
|
}
|
|
23737
23899
|
return false;
|
|
@@ -24245,10 +24407,14 @@ async function main() {
|
|
|
24245
24407
|
}
|
|
24246
24408
|
case "login": {
|
|
24247
24409
|
const base = await apiBase(flag(rest, "base", ""));
|
|
24248
|
-
await deviceLogin({
|
|
24410
|
+
await deviceLogin({
|
|
24411
|
+
base,
|
|
24412
|
+
store: (token, account) => writeLoginCredential(token, { apiBase: base, ...account ? { account } : {} })
|
|
24413
|
+
});
|
|
24249
24414
|
process.stdout.write(`
|
|
24250
24415
|
Logged in. Token saved to ${authTokenPath()}
|
|
24251
24416
|
`);
|
|
24417
|
+
process.stdout.write("If a sidecar daemon is already running, restart it to sign it in as well.\n");
|
|
24252
24418
|
break;
|
|
24253
24419
|
}
|
|
24254
24420
|
case "auth":
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@corenel/cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Corenel CLI — runs the harness in node, in-proc, no transport. The headless proof the kernel is host-agnostic. (corenel run/ask/chat/login + start --sidecar to follow.)",
|
|
6
6
|
"bin": {
|
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
"dependencies": {
|
|
10
10
|
"openai": "^4.77.0",
|
|
11
11
|
"ws": "^8.18.0",
|
|
12
|
-
"@corenel/harness": "0.6.
|
|
13
|
-
"@corenel/
|
|
14
|
-
"@corenel/
|
|
12
|
+
"@corenel/harness": "0.6.1",
|
|
13
|
+
"@corenel/term": "0.2.3",
|
|
14
|
+
"@corenel/protocol": "0.6.1"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
17
|
"esbuild": "^0.21.5",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"@types/ws": "^8.5.13",
|
|
20
20
|
"tsx": "^4.19.2",
|
|
21
21
|
"typescript": "^5.9.3",
|
|
22
|
-
"@corenel/tools-node": "0.3.
|
|
22
|
+
"@corenel/tools-node": "0.3.1",
|
|
23
23
|
"@corenel/crew": "0.0.0"
|
|
24
24
|
},
|
|
25
25
|
"publishConfig": {
|