@corenel/cli 0.9.4 → 0.10.0

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/main.js +67 -35
  2. package/package.json +7 -7
package/dist/main.js CHANGED
@@ -28479,9 +28479,9 @@ ${firstUserMsg.content}`;
28479
28479
  _MemoryFileSystem.MAX_PACKAGE_SIZE = 50 * 1024 * 1024;
28480
28480
  MemoryFileSystem = _MemoryFileSystem;
28481
28481
  HybridFileSystem = class {
28482
- constructor(files = {}, backend2) {
28482
+ constructor(files = {}, backend) {
28483
28483
  this.mem = new MemoryFileSystem(files);
28484
- this.backend = backend2;
28484
+ this.backend = backend;
28485
28485
  }
28486
28486
  /** Add or update an in-memory (synchronously-served) file. */
28487
28487
  addFile(filePath, content) {
@@ -28651,7 +28651,7 @@ var init_toolGuidance = __esm({
28651
28651
 
28652
28652
  // ../tools-node/promptHost.ts
28653
28653
  import { normalizeFilePath as normalizeFilePath2, flattenFiles as flattenFiles2 } from "@corenel/protocol";
28654
- function backend(svc) {
28654
+ function promptBackend(svc) {
28655
28655
  return {
28656
28656
  async readFile(p) {
28657
28657
  try {
@@ -28668,9 +28668,10 @@ function backend(svc) {
28668
28668
  }
28669
28669
  };
28670
28670
  }
28671
- async function preload(svc) {
28671
+ async function preloadPromptSources(svc, keep) {
28672
28672
  const out = {};
28673
28673
  for (const f of flattenFiles2(await svc.list())) {
28674
+ if (keep && !keep(f.path)) continue;
28674
28675
  try {
28675
28676
  out[f.path] = await svc.read(f.path);
28676
28677
  } catch {
@@ -28702,10 +28703,10 @@ function nodePromptHost(workspace, project) {
28702
28703
  parse: (source) => ({ meta: parser.parseContent(source).metadata ?? {} }),
28703
28704
  compileBody: (source, values) => compile(source, values),
28704
28705
  compileTemplate: async (path, liveSrc, values) => {
28705
- const sources = await preload(workspace);
28706
+ const sources = await preloadPromptSources(workspace);
28706
28707
  const p = normalizeFilePath2(path);
28707
28708
  sources[p] = liveSrc;
28708
- return compile("", values, new HybridFileSystem(sources, backend(workspace)), "/" + p);
28709
+ return compile("", values, new HybridFileSystem(sources, promptBackend(workspace)), "/" + p);
28709
28710
  },
28710
28711
  siteIndex: () => "",
28711
28712
  // no site index in node (the help chat is browser-only)
@@ -28982,6 +28983,14 @@ var init_approvalsStore = __esm({
28982
28983
  });
28983
28984
 
28984
28985
  // ../tools-node/deviceLogin.ts
28986
+ function verificationLink(dc) {
28987
+ const base = dc.verification_uri;
28988
+ const complete = dc.verification_uri_complete;
28989
+ if (typeof complete === "string" && complete.startsWith(base) && (complete[base.length] === "?" || complete[base.length] === "&")) {
28990
+ return complete;
28991
+ }
28992
+ return `${base}${base.includes("?") ? "&" : "?"}code=${encodeURIComponent(dc.user_code)}`;
28993
+ }
28985
28994
  function deadlineSignal(ms, outer) {
28986
28995
  const ac = new AbortController();
28987
28996
  const onOuter = () => ac.abort();
@@ -29049,7 +29058,7 @@ async function deviceLogin(opts) {
29049
29058
  };
29050
29059
  const dc = await post("/oauth/device/code", { client_id: "corenel-cli", scope: "agent pair" });
29051
29060
  if (!dc.device_code) throw new Error("device authorization failed");
29052
- (opts.open ?? defaultOpen)(dc.verification_uri, dc.user_code);
29061
+ (opts.open ?? defaultOpen)(verificationLink(dc), dc.user_code);
29053
29062
  let interval = opts.pollMs ?? Math.max(MIN_POLL_MS, (dc.interval ?? 5) * 1e3);
29054
29063
  const lifetimeMs = (typeof dc.expires_in === "number" && dc.expires_in > 0 ? dc.expires_in : DEFAULT_LIFETIME_S) * 1e3;
29055
29064
  const deadline = Date.now() + lifetimeMs;
@@ -32845,7 +32854,7 @@ function configWorkspaceRoot(base) {
32845
32854
  import { FileRecallStore, UNATTACHED_SESSION } from "@corenel/harness/sessions/fileRecallStore";
32846
32855
  import { makeSessionFoldStorage } from "@corenel/harness/sessions/foldStorage";
32847
32856
  import { makeSummarizer } from "@corenel/harness/core/summarize";
32848
- import { stateDirName as stateDirName7, sessionsRoot, isSourceRun } from "@corenel/protocol";
32857
+ import { stateDirName as stateDirName6, sessionsRoot, isSourceRun } from "@corenel/protocol";
32849
32858
  import { PermissionService as PermissionService6 } from "@corenel/harness/guardrail/permission-service";
32850
32859
 
32851
32860
  // src/nodeContext.ts
@@ -32947,6 +32956,7 @@ var crew_exports = {};
32947
32956
  __export(crew_exports, {
32948
32957
  AUTONOMY_TOOLS: () => AUTONOMY_TOOLS,
32949
32958
  CHECK_IN_BLOCK: () => CHECK_IN_BLOCK,
32959
+ COMMAND_CAPABILITIES: () => COMMAND_CAPABILITIES,
32950
32960
  CREW_EXCLUDED_TOOLS: () => CREW_EXCLUDED_TOOLS,
32951
32961
  CREW_SEG: () => CREW_SEG,
32952
32962
  DEPLOYMENT_FILE: () => DEPLOYMENT_FILE,
@@ -33001,6 +33011,7 @@ __export(crew_exports, {
33001
33011
  foldRoom: () => foldRoom,
33002
33012
  globMatch: () => globMatch,
33003
33013
  grantOfferedTools: () => grantOfferedTools,
33014
+ grantsCommandTools: () => grantsCommandTools,
33004
33015
  interjectHuman: () => interjectHuman,
33005
33016
  isAutonomyPreset: () => isAutonomyPreset,
33006
33017
  isOrchestrator: () => isOrchestrator,
@@ -33023,6 +33034,7 @@ __export(crew_exports, {
33023
33034
  newCrewDraft: () => newCrewDraft,
33024
33035
  nextCronAfter: () => nextCronAfter,
33025
33036
  normalizeRunStatus: () => normalizeRunStatus,
33037
+ offersCommandTools: () => offersCommandTools,
33026
33038
  openLineOf: () => openLineOf,
33027
33039
  openRoom: () => openRoom,
33028
33040
  parseCron: () => parseCron,
@@ -33056,6 +33068,7 @@ __export(crew_exports, {
33056
33068
  takeTurn: () => takeTurn,
33057
33069
  tightenAutonomy: () => tightenAutonomy,
33058
33070
  turnCosts: () => turnCosts,
33071
+ unsandboxedCommandsFact: () => unsandboxedCommandsFact,
33059
33072
  userMemoryRoot: () => userMemoryRoot,
33060
33073
  validateRoomRequest: () => validateRoomRequest,
33061
33074
  writeCrewAgentAt: () => writeCrewAgentAt
@@ -33249,6 +33262,24 @@ function enforcedLevel(policy, cap) {
33249
33262
  });
33250
33263
  }
33251
33264
 
33265
+ // ../crew/commandTools.ts
33266
+ var COMMAND_CAPABILITIES = [
33267
+ { tool: "sidecar_shell_exec", label: "Run shell commands", mutating: true, address: "sidecar:shell_exec", permission: "ask" },
33268
+ { tool: "sidecar_run_check", label: "Run confirmed checks", mutating: true, address: "sidecar:run_check", permission: "ask" },
33269
+ { tool: "proc_start", label: "Start long-running processes", mutating: true, address: "shell:spawn", permission: "ask" }
33270
+ ];
33271
+ function offersCommandTools(toolNames) {
33272
+ const names = new Set(toolNames);
33273
+ return COMMAND_CAPABILITIES.some((c) => names.has(c.tool));
33274
+ }
33275
+ function grantsCommandTools(policy) {
33276
+ return COMMAND_CAPABILITIES.some((c) => enforcedLevel(policy, c) !== "deny");
33277
+ }
33278
+ function unsandboxedCommandsFact(policy, offeredToolNames) {
33279
+ const offered = new Set(offeredToolNames);
33280
+ return COMMAND_CAPABILITIES.some((c) => offered.has(c.tool) && enforcedLevel(policy, c) !== "deny") ? { unsandboxedCommands: true } : {};
33281
+ }
33282
+
33252
33283
  // ../crew/autonomy.ts
33253
33284
  import { SIDECAR_GIT_PUSH, SIDECAR_OPEN_PR } from "@corenel/protocol";
33254
33285
  import { toolAddress, resolveNamespace } from "@corenel/harness/tools/namespaces";
@@ -35105,7 +35136,7 @@ import { createChatClient, setGatewayBase } from "@corenel/harness/providers/gat
35105
35136
  // src/apiBase.ts
35106
35137
  init_tools_node();
35107
35138
  import { DEFAULT_API_BASE as DEFAULT_API_BASE2 } from "@corenel/protocol";
35108
- import { DEV_PROFILE } from "@corenel/protocol";
35139
+ import { DEV_PROFILE, SANDBOX_GATEWAY_BASE_ENV } from "@corenel/protocol";
35109
35140
  var InvalidApiBaseError = class extends Error {
35110
35141
  constructor(value, why) {
35111
35142
  super(`invalid API base ${JSON.stringify(value)} -- ${why}`);
@@ -35159,7 +35190,10 @@ async function resolveCliApiBase(explicit, opts = {}) {
35159
35190
  if (url.protocol !== "https:" && url.protocol !== "http:") {
35160
35191
  throw new InvalidApiBaseError(value, `the scheme must be https or http, not ${url.protocol.replace(/:$/, "")}`);
35161
35192
  }
35162
- if (url.protocol === "http:" && !isLoopback(url.hostname) && !warnedCleartext) {
35193
+ const trim2 = (s) => s.trim().replace(/\/+$/, "");
35194
+ const marker = env[SANDBOX_GATEWAY_BASE_ENV];
35195
+ const sanctioned = typeof marker === "string" && marker.trim() !== "" && trim2(marker) === trim2(value);
35196
+ if (url.protocol === "http:" && !isLoopback(url.hostname) && !sanctioned && !warnedCleartext) {
35163
35197
  warnedCleartext = true;
35164
35198
  process.stderr.write(
35165
35199
  `corenel: warning: ${url.host} is plain http, so your access token is sent in cleartext. Use https unless this host is on a private network you trust.
@@ -35340,10 +35374,10 @@ var EXTENSIONS = [
35340
35374
  }
35341
35375
  },
35342
35376
  {
35343
- command: "sessions",
35377
+ command: "sandboxes",
35344
35378
  ...SIDECAR,
35345
- summary: "list and inspect local sandbox sessions",
35346
- argv: (rest) => ["sessions", ...rest]
35379
+ summary: "create, list and run in local sandboxes",
35380
+ argv: (rest) => ["sandboxes", ...rest]
35347
35381
  },
35348
35382
  {
35349
35383
  command: "crew",
@@ -35447,14 +35481,13 @@ async function runExtension(ext, rest, look = {}) {
35447
35481
  }
35448
35482
 
35449
35483
  // src/commands.ts
35450
- import { stateDirName as stateDirName4 } from "@corenel/protocol";
35451
35484
  var COMMANDS = [
35452
35485
  { name: "", args: "", summary: "with no command: an interactive agent in this directory" },
35453
- { name: "run", args: '"<prompt>" [--allow-mutations] | --session ID "<prompt>"', summary: "one-shot turn, then exit -- refuses writes/shell unless --allow-mutations; --session runs the bare prompt in a sandbox instead and ignores every other flag" },
35486
+ { name: "run", args: '"<prompt>" [--allow-mutations] | --sandbox ID "<prompt>"', summary: "one-shot turn, then exit -- refuses writes/shell unless --allow-mutations; --sandbox runs the bare prompt in a sandbox instead and ignores every other flag" },
35454
35487
  { name: "run-agent", args: '<name> --input "<text>" [--allow-mutations]', summary: "run a crew agent (same refuse-by-default gate as run); events as JSON Lines on stdout" },
35455
35488
  { name: "sidecar", args: "[start] [flags]", summary: "run the sidecar on this machine" },
35456
35489
  { name: "acp", args: "<agent> [flags]", summary: "proxy an external coding agent under Corenel policy" },
35457
- { name: "sessions", args: "[list|show|create|run]", summary: "create, list and run in local sandbox sessions" },
35490
+ { name: "sandboxes", args: "[list|show|create|run|pause|resume|destroy]", summary: "create, list and run in local sandboxes" },
35458
35491
  { name: "crew", args: "deployments | deploy|undeploy|resume <agent> | pause <agent> --reason R", summary: "deploy, undeploy, pause and resume crew agents on this machine" },
35459
35492
  { name: "login", args: "[--base URL]", summary: "sign in through your browser (device flow)" },
35460
35493
  { name: "auth", summary: "show whether you are signed in, and as what" },
@@ -35507,12 +35540,7 @@ function helpText(version2) {
35507
35540
  " --version, -v print the version",
35508
35541
  " --help, -h print this",
35509
35542
  "",
35510
- "--resume reopens a CONVERSATION (this face's own chat log, saved under",
35511
- `${stateDirName4()}/sessions/) -- not the same thing as \`run --session ID\` or the`,
35512
- "`sessions` command below, which forward into a sandbox on the sidecar.",
35513
- "Same word, two different nouns.",
35514
- "",
35515
- "sidecar, acp, sessions and crew are provided by @corenel/sidecar, installed separately.",
35543
+ "sidecar, acp, sandboxes and crew are provided by @corenel/sidecar, installed separately.",
35516
35544
  "Each takes its own flags: `corenel sidecar --help`.",
35517
35545
  "",
35518
35546
  "Exit codes (corenel run, corenel run-agent):",
@@ -36625,7 +36653,7 @@ function shellTool(cwd) {
36625
36653
  import { procTools } from "@corenel/harness/tools/procs";
36626
36654
 
36627
36655
  // src/sidecarConnect.ts
36628
- import { stateDirName as stateDirName5 } from "@corenel/protocol";
36656
+ import { stateDirName as stateDirName4 } from "@corenel/protocol";
36629
36657
  import { SidecarHost, isSidecarKeyMismatch, isSidecarAccountRefusal } from "@corenel/harness/sidecar/host";
36630
36658
 
36631
36659
  // ../../node_modules/.pnpm/ws@8.21.0/node_modules/ws/wrapper.mjs
@@ -37017,7 +37045,7 @@ async function connectSidecarProcs(env = process.env, store = cliDeviceStore(),
37017
37045
  const host = new SidecarHost({
37018
37046
  channel,
37019
37047
  ...credential,
37020
- stateDir: stateDirName5(),
37048
+ stateDir: stateDirName4(),
37021
37049
  clientId: `corenel-cli-${process.pid}`,
37022
37050
  clientName: cliDeviceName(),
37023
37051
  onIdentityChallenge: identity2.answer,
@@ -37062,7 +37090,7 @@ async function connectMcpAdmin(env = process.env, store = cliDeviceStore(), iden
37062
37090
  const host = new SidecarHost({
37063
37091
  channel,
37064
37092
  ...credential,
37065
- stateDir: stateDirName5(),
37093
+ stateDir: stateDirName4(),
37066
37094
  clientId: `corenel-cli-${process.pid}`,
37067
37095
  clientName: cliDeviceName(),
37068
37096
  onIdentityChallenge: identity2.answer,
@@ -37330,7 +37358,7 @@ async function resolveStrategyPrompt(files, id) {
37330
37358
  init_tools_node();
37331
37359
  import { readFile as readFile2, stat } from "node:fs/promises";
37332
37360
  import { join as join11 } from "node:path";
37333
- import { stateDirName as stateDirName6 } from "@corenel/protocol";
37361
+ import { stateDirName as stateDirName5 } from "@corenel/protocol";
37334
37362
  import { BUILTIN_POLICIES, STANDARD_POLICY as STANDARD_POLICY3, policyFromYaml } from "@corenel/harness/guardrail";
37335
37363
  var PolicyResolutionError = class extends Error {
37336
37364
  detail;
@@ -37415,7 +37443,7 @@ async function resolvePolicy(opts) {
37415
37443
  }
37416
37444
  return { policy: STANDARD_POLICY3, source: { kind: "default" }, warnings };
37417
37445
  }
37418
- const workspacePath = join11(cwd, stateDirName6(), "policy.yaml");
37446
+ const workspacePath = join11(cwd, stateDirName5(), "policy.yaml");
37419
37447
  if (await fileExists(workspacePath)) {
37420
37448
  warnings.push(
37421
37449
  `corenel: ${workspacePath} ignored -- a policy inside the workspace can be written by the agent or arrive in a cloned repo. To use it for this folder, move it to ${projectPath}, or pass --policy ${workspacePath} explicitly.`
@@ -38957,7 +38985,7 @@ async function agentSetup(argv, chosenModel) {
38957
38985
  try {
38958
38986
  const migrated = await migrateHomeLayout();
38959
38987
  if (migrated.moved.length) {
38960
- console.error(`layout: moved ${migrated.moved.length} item(s) into the current ~/${stateDirName7()} layout`);
38988
+ console.error(`layout: moved ${migrated.moved.length} item(s) into the current ~/${stateDirName6()} layout`);
38961
38989
  }
38962
38990
  for (const left of migrated.skipped) console.error(`layout: left ${left.path} alone (${left.reason})`);
38963
38991
  } catch (e) {
@@ -39025,19 +39053,23 @@ async function buildRunPermission(opts) {
39025
39053
  }) };
39026
39054
  }
39027
39055
  async function run(argv) {
39056
+ if (hasValueFlag(argv, "session")) {
39057
+ process.stderr.write("corenel: --session is not a flag of `run`. To run inside a sandbox use --sandbox ID.\n");
39058
+ process.exit(2);
39059
+ }
39028
39060
  const prompt = promptOf(argv);
39029
39061
  if (!prompt) {
39030
- process.stderr.write('usage: corenel run "<prompt>" [--model M] [--base URL] [--session ID] [--allow-mutations]\n [--max-usd N] [--max-tokens N] [--max-ms N] [--on-budget stop|warn]\n');
39062
+ process.stderr.write('usage: corenel run "<prompt>" [--model M] [--base URL] [--sandbox ID] [--allow-mutations]\n [--max-usd N] [--max-tokens N] [--max-ms N] [--on-budget stop|warn]\n');
39031
39063
  process.exit(2);
39032
39064
  }
39033
39065
  const budget = budgetConstraintsFrom(argv);
39034
- const session = flag(argv, "session", "");
39035
- if (session) {
39066
+ const sandbox = flag(argv, "sandbox", "");
39067
+ if (sandbox) {
39036
39068
  if (hasAllowMutationsFlag(argv) || hasValueFlag(argv, "model") || hasValueFlag(argv, "base") || budget) {
39037
- process.stderr.write("corenel: note: --session ignores every other flag on this line -- the sandboxed run uses its own defaults.\n");
39069
+ process.stderr.write("corenel: note: --sandbox ignores every other flag on this line -- the sandboxed run uses its own defaults.\n");
39038
39070
  }
39039
- const ext = findExtension("sessions");
39040
- process.exitCode = ext ? await runExtension(ext, ["run", session, prompt]) : 2;
39071
+ const ext = findExtension("sandboxes");
39072
+ process.exitCode = ext ? await runExtension(ext, ["run", sandbox, prompt]) : 2;
39041
39073
  return;
39042
39074
  }
39043
39075
  const { client, model, system, tools, policy, memory, disconnect } = await agentSetup(argv);
@@ -39394,7 +39426,7 @@ async function main() {
39394
39426
  }
39395
39427
  case "sidecar":
39396
39428
  case "acp":
39397
- case "sessions":
39429
+ case "sandboxes":
39398
39430
  case "crew": {
39399
39431
  const ext = findExtension(cmd);
39400
39432
  process.exitCode = ext ? await runExtension(ext, rest) : 2;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@corenel/cli",
3
- "version": "0.9.4",
3
+ "version": "0.10.0",
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,11 +9,11 @@
9
9
  "dependencies": {
10
10
  "openai": "^4.77.0",
11
11
  "ws": "^8.18.0",
12
- "@corenel/mcp": "0.6.2",
13
- "@corenel/config": "0.7.2",
14
- "@corenel/harness": "0.17.0",
15
- "@corenel/term": "0.8.3",
16
- "@corenel/protocol": "0.15.0"
12
+ "@corenel/config": "0.7.4",
13
+ "@corenel/protocol": "0.17.0",
14
+ "@corenel/harness": "0.19.0",
15
+ "@corenel/mcp": "0.6.4",
16
+ "@corenel/term": "0.8.5"
17
17
  },
18
18
  "devDependencies": {
19
19
  "esbuild": "^0.21.5",
@@ -22,7 +22,7 @@
22
22
  "tsx": "^4.19.2",
23
23
  "typescript": "^5.9.3",
24
24
  "@corenel/crew": "0.0.0",
25
- "@corenel/tools-node": "0.8.2"
25
+ "@corenel/tools-node": "0.9.0"
26
26
  },
27
27
  "publishConfig": {
28
28
  "access": "public"