@corenel/cli 0.4.1 → 0.4.3

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.
Files changed (2) hide show
  1. package/dist/cli.js +288 -55
  2. package/package.json +10 -5
package/dist/cli.js CHANGED
@@ -18832,7 +18832,7 @@ var NodeFileService = class {
18832
18832
  out.push({ name: e.name, path, kind: "directory", children: await walk(absChild) });
18833
18833
  } else {
18834
18834
  const st = await fs.stat(absChild).catch(() => null);
18835
- out.push({ name: e.name, path, kind: "file", size: st?.size, ext: extOf(e.name) });
18835
+ out.push({ name: e.name, path, kind: "file", size: st?.size, mtime: st?.mtimeMs, ext: extOf(e.name) });
18836
18836
  }
18837
18837
  }
18838
18838
  return out;
@@ -18845,7 +18845,7 @@ var NodeFileService = class {
18845
18845
  async stat(path) {
18846
18846
  try {
18847
18847
  const st = await fs.stat(this.abs(path));
18848
- return { path: normalizeFilePath(path), kind: st.isDirectory() ? "directory" : "file", size: st.size, ext: extOf(path) };
18848
+ return { path: normalizeFilePath(path), kind: st.isDirectory() ? "directory" : "file", size: st.size, mtime: st.mtimeMs, ext: extOf(path) };
18849
18849
  } catch {
18850
18850
  return null;
18851
18851
  }
@@ -18910,7 +18910,7 @@ var NodeFileService = class {
18910
18910
  import { promises as fs2 } from "node:fs";
18911
18911
  import { homedir } from "node:os";
18912
18912
  import { join as join2 } from "node:path";
18913
- import { stateDirName } from "@corenel/protocol";
18913
+ import { stateDirName, DEFAULT_API_BASE } from "@corenel/protocol";
18914
18914
  function corenelDir(base = homedir()) {
18915
18915
  return join2(base, stateDirName());
18916
18916
  }
@@ -18920,34 +18920,170 @@ function sidecarDir(base = homedir()) {
18920
18920
  function authTokenPath(base = homedir()) {
18921
18921
  return join2(corenelDir(base), "token");
18922
18922
  }
18923
- async function writeAuthToken(token) {
18924
- await fs2.mkdir(corenelDir(), { recursive: true, mode: 448 });
18925
- await fs2.writeFile(authTokenPath(), token.trim() + "\n", { mode: 384 });
18923
+ function credentialDir(stateDir) {
18924
+ return stateDir ?? corenelDir();
18925
+ }
18926
+ function tokenFilePath(stateDir) {
18927
+ return join2(credentialDir(stateDir), "token");
18928
+ }
18929
+ function credentialFilePath(stateDir) {
18930
+ return join2(credentialDir(stateDir), "auth.json");
18931
+ }
18932
+ var TOKEN_ENV = "CORENEL_TOKEN";
18933
+ var API_BASE_ENV = "CORENEL_API_BASE";
18934
+ async function writeLoginCredential(token, opts = {}) {
18935
+ const cred = {
18936
+ accessToken: token.trim(),
18937
+ ...opts.account ? { account: opts.account } : {},
18938
+ ...opts.apiBase ? { apiBase: opts.apiBase } : {}
18939
+ };
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}
18949
+ `, { mode: 384 });
18926
18950
  try {
18927
- await fs2.chmod(authTokenPath(), 384);
18951
+ await fs2.chmod(credTmp, 384);
18928
18952
  } catch {
18929
18953
  }
18930
18954
  try {
18931
- await fs2.chmod(corenelDir(), 448);
18955
+ await fs2.chmod(tokTmp, 384);
18932
18956
  } catch {
18933
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";
18979
+ }
18980
+ async function readAuthTokenRead(stateDir) {
18981
+ try {
18982
+ const t = (await fs2.readFile(tokenFilePath(stateDir), "utf8")).trim();
18983
+ return { value: t || null, unreadable: false };
18984
+ } catch (err) {
18985
+ return { value: null, unreadable: !isMissing(err) };
18986
+ }
18934
18987
  }
18935
- async function readAuthToken() {
18988
+ async function clearAuthToken(stateDir) {
18936
18989
  try {
18937
- const t = (await fs2.readFile(authTokenPath(), "utf8")).trim();
18938
- return t || null;
18990
+ await fs2.rm(tokenFilePath(stateDir), { force: true });
18939
18991
  } catch {
18940
- return null;
18941
18992
  }
18942
18993
  }
18943
- async function clearAuthToken() {
18994
+ async function readCredentialFileRead(stateDir) {
18995
+ let raw;
18996
+ try {
18997
+ raw = await fs2.readFile(credentialFilePath(stateDir), "utf8");
18998
+ } catch (err) {
18999
+ return { value: null, unreadable: !isMissing(err) };
19000
+ }
19001
+ try {
19002
+ const parsed = JSON.parse(raw);
19003
+ if (typeof parsed !== "object" || parsed === null) return { value: null, unreadable: false };
19004
+ const c = parsed;
19005
+ if (typeof c.accessToken !== "string" || !c.accessToken) return { value: null, unreadable: false };
19006
+ return {
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
19015
+ };
19016
+ } catch {
19017
+ return { value: null, unreadable: false };
19018
+ }
19019
+ }
19020
+ async function clearAllCredentials(stateDir) {
19021
+ await clearAuthToken(stateDir);
18944
19022
  try {
18945
- await fs2.rm(authTokenPath(), { force: true });
19023
+ await fs2.rm(credentialFilePath(stateDir), { force: true });
18946
19024
  } catch {
18947
19025
  }
18948
19026
  }
18949
- function nodeAuthToken() {
18950
- return { getToken: async () => await readAuthToken() ?? process.env.CORENEL_TOKEN ?? null };
19027
+ async function resolveNodeCredential(opts = {}) {
19028
+ const env = opts.env ?? process.env;
19029
+ const now = opts.now ?? Date.now;
19030
+ const stateDir = opts.stateDir;
19031
+ const fromEnv = env[TOKEN_ENV]?.trim();
19032
+ if (fromEnv) return { token: fromEnv, source: "env" };
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 } : {};
19038
+ if (fileToken) {
19039
+ const same = cred && cred.accessToken === fileToken ? cred : null;
19040
+ return {
19041
+ ...withExpiry({ token: fileToken, source: "token-file", path: tokenFilePath(stateDir) }, same, now),
19042
+ ...unreadable
19043
+ };
19044
+ }
19045
+ if (cred) {
19046
+ return {
19047
+ ...withExpiry(
19048
+ { token: cred.accessToken, source: "credential-file", path: credentialFilePath(stateDir) },
19049
+ cred,
19050
+ now
19051
+ ),
19052
+ ...unreadable
19053
+ };
19054
+ }
19055
+ return { token: null, source: "none", ...unreadable };
19056
+ }
19057
+ function withExpiry(base, cred, now) {
19058
+ if (!cred) return base;
19059
+ const expired = typeof cred.expiresAt === "number" && cred.expiresAt <= now();
19060
+ return {
19061
+ ...base,
19062
+ ...typeof cred.expiresAt === "number" ? { expiresAt: cred.expiresAt } : {},
19063
+ ...expired ? { expired: true } : {},
19064
+ ...cred.account ? { account: cred.account } : {},
19065
+ ...cred.apiBase ? { apiBase: cred.apiBase } : {}
19066
+ };
19067
+ }
19068
+ async function resolveApiBase(opts = {}) {
19069
+ const explicit = opts.explicit?.trim();
19070
+ if (explicit) return { base: explicit, source: "explicit" };
19071
+ const fromEnv = (opts.env ?? process.env)[API_BASE_ENV]?.trim();
19072
+ if (fromEnv) return { base: fromEnv, source: "env" };
19073
+ const cred = await resolveNodeCredential({
19074
+ env: {},
19075
+ ...opts.stateDir ? { stateDir: opts.stateDir } : {}
19076
+ });
19077
+ if (cred.apiBase) return { base: cred.apiBase, source: "credential" };
19078
+ return { base: DEFAULT_API_BASE, source: "default" };
19079
+ }
19080
+ function maskToken(token) {
19081
+ const t = token.trim();
19082
+ if (t.length <= 8) return "****";
19083
+ return `${t.slice(0, 4)}\u2026${t.slice(-2)} (${t.length} chars)`;
19084
+ }
19085
+ function nodeAuthToken(stateDir) {
19086
+ return { getToken: async () => (await resolveNodeCredential(stateDir ? { stateDir } : {})).token };
18951
19087
  }
18952
19088
 
18953
19089
  // ../../node_modules/.pnpm/@prompd+core@0.5.0-beta.10/node_modules/@prompd/core/dist/index.js
@@ -22048,30 +22184,41 @@ function configWorkspaceRoot(base) {
22048
22184
  // src/cli.ts
22049
22185
  import { FileRecallStore, UNATTACHED_SESSION } from "@corenel/harness/sessions/fileRecallStore";
22050
22186
  import { stateDirName as stateDirName6 } from "@corenel/protocol";
22051
- import { PermissionService as PermissionService3 } from "@corenel/harness/guardrail/permission-service";
22187
+ import { PermissionService as PermissionService4 } from "@corenel/harness/guardrail/permission-service";
22052
22188
 
22053
22189
  // src/nodeContext.ts
22054
22190
  import { ROOT_NODE_ID } from "@corenel/protocol";
22055
22191
  import { makeSpawn } from "@corenel/harness/core/spawn";
22056
22192
  function inMemoryMemory() {
22057
- const items = [];
22058
- let n = 0;
22193
+ const items = /* @__PURE__ */ new Map();
22059
22194
  return {
22060
- async save(text, tags = []) {
22061
- const it = { id: `m${++n}`, text, tags, createdAt: n };
22062
- items.push(it);
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);
22063
22206
  return it;
22064
22207
  },
22208
+ async read(name) {
22209
+ return items.get(name) ?? null;
22210
+ },
22065
22211
  async recall(q) {
22066
- return items.filter((i) => i.text.includes(q));
22212
+ return [...items.values()].filter((i) => i.text.includes(q) || i.description.includes(q));
22067
22213
  },
22068
22214
  async list() {
22069
- return [...items];
22215
+ return [...items.values()];
22070
22216
  },
22071
- async forget(id) {
22072
- const i = items.findIndex((x) => x.id === id);
22073
- if (i >= 0) items.splice(i, 1);
22217
+ async forget(name) {
22218
+ items.delete(name);
22074
22219
  }
22220
+ // No core(): this stub has no tiers, and Task 9 injects nothing rather than
22221
+ // pretending it has a memory block.
22075
22222
  };
22076
22223
  }
22077
22224
  function inMemoryKv() {
@@ -22144,6 +22291,42 @@ function tokenGuard(getToken) {
22144
22291
  var sleep = (ms) => new Promise((r) => setTimeout(r, ms));
22145
22292
  var MIN_POLL_MS = 1e3;
22146
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
+ }
22147
22330
  function defaultOpen(uri, code2) {
22148
22331
  process.stdout.write(`
22149
22332
  To authorize, open: ${uri}
@@ -22192,7 +22375,9 @@ async function deviceLogin(opts) {
22192
22375
  client_id: "corenel-cli"
22193
22376
  });
22194
22377
  if (tok.access_token) {
22195
- await opts.store(tok.access_token);
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);
22196
22381
  return tok.access_token;
22197
22382
  }
22198
22383
  if (tok.error === "authorization_pending") continue;
@@ -22209,7 +22394,7 @@ import { runAgent } from "@corenel/harness/core/loop";
22209
22394
  import { createChatClient, setGatewayBase } from "@corenel/harness/providers/gateway";
22210
22395
 
22211
22396
  // src/apiBase.ts
22212
- var DEFAULT_API_BASE = "https://api.corenel.ai/api";
22397
+ import { DEFAULT_API_BASE as DEFAULT_API_BASE2 } from "@corenel/protocol";
22213
22398
  var InvalidApiBaseError = class extends Error {
22214
22399
  constructor(value, why) {
22215
22400
  super(`invalid API base ${JSON.stringify(value)} -- ${why}`);
@@ -22223,8 +22408,13 @@ function isLoopback(hostname) {
22223
22408
  return h === "localhost" || h === "127.0.0.1" || h === "::1" || h.endsWith(".localhost");
22224
22409
  }
22225
22410
  var warnedCleartext = false;
22226
- function apiBase(explicit) {
22227
- const value = explicit || process.env.CORENEL_API_BASE || DEFAULT_API_BASE;
22411
+ async function apiBase(explicit, opts = {}) {
22412
+ const resolved = await resolveApiBase({
22413
+ explicit,
22414
+ env: opts.env ?? process.env,
22415
+ ...opts.stateDir ? { stateDir: opts.stateDir } : {}
22416
+ });
22417
+ const value = resolved.base;
22228
22418
  let url;
22229
22419
  try {
22230
22420
  url = new URL(value);
@@ -22453,8 +22643,11 @@ async function loadCrewAgentAtIfExists(files, root, name, scope = "workspace") {
22453
22643
  // ../crew/runtime.ts
22454
22644
  import { saveCustomPolicy } from "@corenel/harness/guardrail";
22455
22645
  import { allTools } from "@corenel/harness/tools/builtins";
22646
+ import { registerSyncConfig, readConfigSyncRendered } from "@corenel/harness/prompts/syncConfig";
22456
22647
  import { makeCallAgentTool } from "@corenel/harness/tools/callAgent";
22457
- function buildSystemExtra(def) {
22648
+ var MEMORY_BLOCK = registerSyncConfig("crew/memory.md");
22649
+ var SELF_DIRECTION_BLOCK = registerSyncConfig("crew/self-direction.md");
22650
+ function buildSystemExtra(def, memoryLocation) {
22458
22651
  const parts = [];
22459
22652
  if (def.jobTitle?.trim()) parts.push(`--- Role ---
22460
22653
  ${def.jobTitle.trim()}`);
@@ -22464,12 +22657,51 @@ ${def.soul.trim()}`);
22464
22657
  ${def.persona.trim()}`);
22465
22658
  if (def.instructions.trim()) parts.push(`--- Instructions ---
22466
22659
  ${def.instructions.trim()}`);
22660
+ const location = memoryLocation ?? "memory/";
22661
+ const dir = location.replace(/\/+$/, "");
22662
+ const index = `${dir}/MEMORY.md`;
22663
+ parts.push(readConfigSyncRendered(MEMORY_BLOCK, { dir, index }));
22664
+ const selfDirection = selfDirectionBlock(def);
22665
+ if (selfDirection) parts.push(selfDirection);
22467
22666
  return parts.join("\n\n");
22468
22667
  }
22668
+ function selfDirectionBlock(def) {
22669
+ const trigger = def.triggers?.find((t) => t.type === "self-directed");
22670
+ if (!trigger) return null;
22671
+ const raw = trigger.config?.fallbackMs;
22672
+ const fallbackMs = typeof raw === "number" && Number.isFinite(raw) && raw > 0 ? raw : null;
22673
+ 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.`;
22674
+ return readConfigSyncRendered(SELF_DIRECTION_BLOCK, { consequence });
22675
+ }
22676
+
22677
+ // ../crew/memory.ts
22678
+ import { makeFactStore } from "@corenel/harness/memory/store";
22679
+
22680
+ // ../crew/room/store.ts
22681
+ import { flattenFiles as flattenFiles4 } from "@corenel/protocol";
22682
+ import { encodeLine, foldSession } from "@corenel/harness/sessions/jsonl";
22683
+ import { FINDINGS_FILE, encodeFindingLine, foldFindings } from "@corenel/harness/rooms/findings";
22684
+
22685
+ // ../crew/room/prompt.ts
22686
+ import { registerSyncConfig as registerSyncConfig2, readConfigSyncRendered as readConfigSyncRendered2 } from "@corenel/harness/prompts/syncConfig";
22687
+ import { MAX_ROOM_FINDINGS, renderFindings } from "@corenel/harness/rooms/findings";
22688
+ var ROOM_BLOCK = registerSyncConfig2("crew/room.md");
22689
+
22690
+ // ../crew/room/turn.ts
22691
+ import { readRoomOutcome } from "@corenel/harness/tools/roomTools";
22692
+
22693
+ // ../crew/room/turnRuntime.ts
22694
+ import { PermissionService } from "@corenel/harness/guardrail";
22695
+ import { BudgetMeter, mergeSignals } from "@corenel/harness/core/budget";
22696
+ import { makeRoomTools, ROOM_TOOL_NAMES } from "@corenel/harness/tools/roomTools";
22697
+
22698
+ // ../crew/room/engine.ts
22699
+ import { describeParticipants, resolveAddressee } from "@corenel/harness/tools/roomTools";
22700
+ import { planFindingEdit, planFindingEdits } from "@corenel/harness/rooms/findings";
22469
22701
 
22470
22702
  // src/runAgent.ts
22471
22703
  import { stateDirName as stateDirName3 } from "@corenel/protocol";
22472
- import { PermissionService } from "@corenel/harness/guardrail/permission-service";
22704
+ import { PermissionService as PermissionService2 } from "@corenel/harness/guardrail/permission-service";
22473
22705
  import { STANDARD_POLICY } from "@corenel/harness/guardrail/builtins";
22474
22706
  import { toolAddress } from "@corenel/harness/tools/namespaces";
22475
22707
 
@@ -22508,7 +22740,7 @@ async function runCrewAgentCli(opts) {
22508
22740
  opts.warn(`agent "${opts.agent}" is disabled; enable it before running`);
22509
22741
  return 2;
22510
22742
  }
22511
- setGatewayBase(apiBase(opts.base));
22743
+ setGatewayBase(await apiBase(opts.base));
22512
22744
  const token = await nodeAuthToken().getToken();
22513
22745
  if (!token) {
22514
22746
  opts.warn("not signed in: set CORENEL_TOKEN, or run `corenel login` on this machine");
@@ -22543,7 +22775,7 @@ ${extra}` : base;
22543
22775
  if (operatorUnattended === "park" && !unattendedAllow) {
22544
22776
  opts.warn(`corenel: policy "${effectivePolicy.name}" asks to park an unattended action, but run-agent cannot wait -- refusing.`);
22545
22777
  }
22546
- const permission = new PermissionService({
22778
+ const permission = new PermissionService2({
22547
22779
  policy: effectivePolicy,
22548
22780
  ceiling: mutatingCeiling(tools, "ask"),
22549
22781
  ...unattendedAllow ? { prompt: { ask: async () => "allow" } } : {}
@@ -22819,16 +23051,13 @@ function version(read = (p) => readFileSync2(p, "utf8")) {
22819
23051
 
22820
23052
  // src/auth.ts
22821
23053
  function hintOf(token) {
22822
- const t = token.trim();
22823
- if (t.length <= 8) return "****";
22824
- return `${t.slice(0, 4)}\u2026${t.slice(-2)} (${t.length} chars)`;
23054
+ return maskToken(token);
22825
23055
  }
22826
- async function authState(read = readAuthToken, env = process.env) {
22827
- const path = authTokenPath();
22828
- const stored = await read();
22829
- if (stored) return { source: "file", path, hint: hintOf(stored) };
22830
- if (env.CORENEL_TOKEN) return { source: "env", path, hint: hintOf(env.CORENEL_TOKEN) };
22831
- return { source: "none", path };
23056
+ async function authState(resolve2 = (env2) => resolveNodeCredential({ env: env2 }), env = process.env) {
23057
+ const r = await resolve2(env);
23058
+ if (!r.token) return { source: "none", path: authTokenPath() };
23059
+ const source = r.source === "env" ? "env" : "file";
23060
+ return { source, path: r.path ?? authTokenPath(), hint: hintOf(r.token) };
22832
23061
  }
22833
23062
  function describeAuth(s, base) {
22834
23063
  if (s.source === "none") {
@@ -22846,12 +23075,12 @@ function describeAuth(s, base) {
22846
23075
  ].filter(Boolean).join("\n");
22847
23076
  }
22848
23077
  async function runAuth(out = (s) => process.stdout.write(s)) {
22849
- out(`${describeAuth(await authState(), apiBase())}
23078
+ out(`${describeAuth(await authState(), await apiBase())}
22850
23079
  `);
22851
23080
  }
22852
23081
  async function runLogout(out = (s) => process.stdout.write(s)) {
22853
23082
  const before = await authState();
22854
- await clearAuthToken();
23083
+ await clearAllCredentials();
22855
23084
  if (before.source === "file") out(`Signed out. Removed ${before.path}
22856
23085
  `);
22857
23086
  else out("Nothing to forget \u2014 no stored token.\n");
@@ -22892,7 +23121,7 @@ async function checkToken(base, token, f = fetch) {
22892
23121
  return { name: "token", status: "ok", detail: `accepted by ${base} (${res.status})` };
22893
23122
  }
22894
23123
  async function collectChecks(f = fetch, modelId = DEFAULT_MODEL) {
22895
- const base = apiBase();
23124
+ const base = await apiBase();
22896
23125
  const checks = [
22897
23126
  { name: "binary", status: "ok", detail: selfPath() },
22898
23127
  { name: "version", status: "ok", detail: `@corenel/cli ${version()}` },
@@ -22900,7 +23129,7 @@ async function collectChecks(f = fetch, modelId = DEFAULT_MODEL) {
22900
23129
  {
22901
23130
  name: "api",
22902
23131
  status: "ok",
22903
- detail: base === DEFAULT_API_BASE ? base : `${base} (overridden; default is ${DEFAULT_API_BASE})`
23132
+ detail: base === DEFAULT_API_BASE2 ? base : `${base} (overridden; default is ${DEFAULT_API_BASE2})`
22904
23133
  }
22905
23134
  ];
22906
23135
  try {
@@ -22917,7 +23146,7 @@ async function collectChecks(f = fetch, modelId = DEFAULT_MODEL) {
22917
23146
  status: auth.source === "none" ? "warn" : "ok",
22918
23147
  detail: auth.source === "none" ? "no" : `yes, from ${auth.source === "env" ? "CORENEL_TOKEN" : auth.path} (${auth.hint})`
22919
23148
  });
22920
- checks.push(await checkToken(base, await readAuthToken() ?? process.env.CORENEL_TOKEN ?? null, f));
23149
+ checks.push(await checkToken(base, (await resolveNodeCredential()).token, f));
22921
23150
  const sidecar = findSidecarEntry();
22922
23151
  checks.push({
22923
23152
  name: "sidecar",
@@ -22948,7 +23177,7 @@ ${failed.length} problem${failed.length > 1 ? "s" : ""} above.
22948
23177
 
22949
23178
  // src/repl.ts
22950
23179
  import { createInterface } from "node:readline";
22951
- import { PermissionService as PermissionService2 } from "@corenel/harness/guardrail/permission-service";
23180
+ import { PermissionService as PermissionService3 } from "@corenel/harness/guardrail/permission-service";
22952
23181
  import { STANDARD_POLICY as STANDARD_POLICY2 } from "@corenel/harness/guardrail/builtins";
22953
23182
  import { TermSession } from "@corenel/term/session";
22954
23183
  import { describeToolCall, formatOrd } from "@corenel/term/describe";
@@ -23126,7 +23355,7 @@ async function runRepl(deps) {
23126
23355
  }
23127
23356
  };
23128
23357
  rl.on("SIGINT", onSigint);
23129
- const permission = new PermissionService2({
23358
+ const permission = new PermissionService3({
23130
23359
  policy: deps.policy ?? STANDARD_POLICY2,
23131
23360
  prompt: {
23132
23361
  ask: async (req) => {
@@ -23804,7 +24033,7 @@ async function resolvePolicy(opts) {
23804
24033
  // src/cli.ts
23805
24034
  var EXIT_POLICY_PARK_REFUSED = 3;
23806
24035
  async function agentSetup(argv) {
23807
- setGatewayBase2(apiBase(flag(argv, "base", "")));
24036
+ setGatewayBase2(await apiBase(flag(argv, "base", "")));
23808
24037
  const token = await nodeAuthToken().getToken();
23809
24038
  if (!token) {
23810
24039
  process.stderr.write("corenel: not signed in.\n Run `corenel login`, or set CORENEL_TOKEN=<token> (a gateway bearer token), then try again.\n");
@@ -23890,7 +24119,7 @@ async function run(argv) {
23890
24119
  process.exitCode = EXIT_POLICY_PARK_REFUSED;
23891
24120
  return;
23892
24121
  }
23893
- const permission = new PermissionService3({
24122
+ const permission = new PermissionService4({
23894
24123
  policy,
23895
24124
  ceiling: mutatingCeiling(tools, "ask"),
23896
24125
  ...unattendedAllow ? { prompt: { ask: async () => "allow" } } : {}
@@ -24089,11 +24318,15 @@ async function main() {
24089
24318
  break;
24090
24319
  }
24091
24320
  case "login": {
24092
- const base = apiBase(flag(rest, "base", ""));
24093
- await deviceLogin({ base, store: writeAuthToken });
24321
+ const base = await apiBase(flag(rest, "base", ""));
24322
+ await deviceLogin({
24323
+ base,
24324
+ store: (token, account) => writeLoginCredential(token, { apiBase: base, ...account ? { account } : {} })
24325
+ });
24094
24326
  process.stdout.write(`
24095
24327
  Logged in. Token saved to ${authTokenPath()}
24096
24328
  `);
24329
+ process.stdout.write("If a sidecar daemon is already running, restart it to sign it in as well.\n");
24097
24330
  break;
24098
24331
  }
24099
24332
  case "auth":
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@corenel/cli",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
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.4.1",
13
- "@corenel/protocol": "0.4.1",
14
- "@corenel/term": "0.2.1"
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",
@@ -20,7 +20,7 @@
20
20
  "tsx": "^4.19.2",
21
21
  "typescript": "^5.9.3",
22
22
  "@corenel/crew": "0.0.0",
23
- "@corenel/tools-node": "0.2.2"
23
+ "@corenel/tools-node": "0.3.1"
24
24
  },
25
25
  "publishConfig": {
26
26
  "access": "public"
@@ -33,6 +33,11 @@
33
33
  "engines": {
34
34
  "node": ">=18"
35
35
  },
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "git+https://github.com/Prompd/prompd-web.git",
39
+ "directory": "packages/cli"
40
+ },
36
41
  "scripts": {
37
42
  "typecheck": "tsc --noEmit",
38
43
  "prestart": "pnpm --filter @corenel/protocol build && pnpm --filter @corenel/harness build && pnpm --filter @corenel/term build",