@brunobracaioli/aibrain 0.4.0-beta.11 → 0.4.0-beta.12

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/README.md CHANGED
@@ -19,8 +19,9 @@ For licensed accounts, `aisac claude` downloads the AISAC Engineering pack for
19
19
  the session, verifies its Ed25519 signature against the key pinned in this
20
20
  release, and loads it as the `aisac-engineering` plugin from the session's
21
21
  private folder, which is deleted on exit. Any failure starts Claude without the
22
- pack. `aisac setup --lang pt-BR|en` picks the pack language without a network
23
- call. The pack is never part of this npm package.
22
+ pack. Once set up, `aisac setup --lang pt-BR|en` picks the pack language without a
23
+ network call; on a machine that was never set up it runs the full setup in that
24
+ language. The pack is never part of this npm package.
24
25
 
25
26
  `aisac codex` (Codex 0.164.0 or later) loads the same verified pack for that
26
27
  session only: its skills are added to the Codex app-server the launch owns
@@ -89,7 +90,7 @@ connection. Its failure or timeout closes only that auxiliary connection.
89
90
  ```sh
90
91
  # Install the published beta:
91
92
  npm install -g @aisac/cli@beta
92
- aisac setup --client both
93
+ aisac setup # configures the clients on PATH; --client claude|codex|both to choose
93
94
  aisac doctor --json
94
95
  aisac claude
95
96
  aisac codex
@@ -16,7 +16,7 @@ export const MAX_LOG_FILES = 3;
16
16
  const LOCK_WAIT_MS = 250;
17
17
  const LOCK_STALE_MS = 30_000;
18
18
  const ADMISSION_MS = 60 * 60 * 1000;
19
- export const ADAPTER_VERSION = '0.4.0-beta.11';
19
+ export const ADAPTER_VERSION = '0.4.0-beta.12';
20
20
  const MAX_DIAGNOSTIC_COUNT = 10_000_000;
21
21
  const MAX_DIAGNOSTIC_BYTES = 128 * 1024 * 1024;
22
22
  const CHECKPOINT_BACKENDS = new Set(['native_store', 'private_file']);
package/dist/cli.mjs CHANGED
@@ -41,7 +41,7 @@ import { extensionsSummary, hooksCommand, mcpCommand } from './extensions-cli.mj
41
41
  import { sessionServers } from './mcp-servers.mjs';
42
42
  import { anyFormatter } from './guardrails/format.mjs';
43
43
 
44
- const VERSION = '0.4.0-beta.11';
44
+ const VERSION = '0.4.0-beta.12';
45
45
  // The command is `aisac`; `aibrain` is an alias installed from the same entry.
46
46
  const COMMAND = 'aisac';
47
47
  const ENDPOINT = 'https://mcp.ai-brain.aisac.cloud/mcp';
@@ -52,6 +52,9 @@ function usage() {
52
52
  console.log(
53
53
  `${COMMAND} ${VERSION}\n\nUsage:\n ${COMMAND} setup [--client claude|codex|both] [--context-profile upstream|conservative]\n [--compact-at 1..95] [--keep-threshold 0..1] [--preserve-recent 1..100]\n [--min-reduction 0..1] [--truncate-head-chars 0..4096]\n [--max-state-tokens 1000..25000] [--max-request-tokens 1000..30000]\n [--tool-policy compatible|read_only] [--goal TEXT]\n ${COMMAND} doctor [--json]\n ${COMMAND} status [--json]\n ${COMMAND} disable\n ${COMMAND} setup --undo\n ${COMMAND} claude [-- native-args...]\n ${COMMAND} codex [-- native-args...]\n\nPolicy notes:\n Automatic monitoring asks for compaction at compact-at percent; state/request\n limits are estimated upper bounds and do not override server quotas.\n min-reduction, truncate-head-chars and tool-policy apply only to Claude;\n Codex keeps native compaction and same-session recovery.`,
54
54
  );
55
+ console.log(
56
+ 'Clients: setup without --client configures the clients installed on PATH (Claude Code, Codex, or both).',
57
+ );
55
58
  console.log(
56
59
  'Telemetry: setup --telemetry on|off (omitted preserves the stored choice; fresh defaults off).',
57
60
  );
@@ -59,7 +62,7 @@ function usage() {
59
62
  'Claude shadow: setup --claude-shadow on|off and --claude-diagnostics on|off (preview stays applied=false).',
60
63
  );
61
64
  console.log(
62
- 'AISAC Engineering: `aisac claude` and `aisac codex` (Codex 0.164+) load the licensed method; setup --lang pt-BR|en picks its language; setup and doctor report the license; status stays offline. `aibrain` is an alias of `aisac`.',
65
+ 'AISAC Engineering: `aisac claude` and `aisac codex` (Codex 0.164+) load the licensed method; setup --lang pt-BR|en picks its language (before the first setup it runs the full setup); setup and doctor report the license; status stays offline. `aibrain` is an alias of `aisac`.',
63
66
  );
64
67
  console.log(
65
68
  'Guardrails: `aisac hooks` lists them (a checklist on a terminal); `aisac hooks enable|disable <id>...` and `aisac hooks reset` change the next `aisac claude` session.',
@@ -187,8 +190,11 @@ function policyOverrides(args) {
187
190
  return values;
188
191
  }
189
192
 
190
- /** @param {string[]} args @param {Awaited<ReturnType<typeof readConfig>>} previous */
191
- function selectedPolicy(args, previous) {
193
+ /**
194
+ * @param {string[]} args @param {Awaited<ReturnType<typeof readConfig>>} previous
195
+ * @param {'claude' | 'codex' | 'both'} clients
196
+ */
197
+ function selectedPolicy(args, previous, clients) {
192
198
  const explicitProfile = option(args, '--context-profile');
193
199
  const explicitV2 =
194
200
  explicitProfile !== undefined ||
@@ -227,7 +233,6 @@ function selectedPolicy(args, previous) {
227
233
  if (option(args, '--goal') === undefined && inherited.goal !== undefined)
228
234
  overrides.goal = inherited.goal;
229
235
  }
230
- const clients = option(args, '--client') ?? 'both';
231
236
  if (
232
237
  clients === 'codex' &&
233
238
  args.some(
@@ -416,6 +421,32 @@ async function disclosureAccepted(
416
421
  }
417
422
  }
418
423
 
424
+ /**
425
+ * Client selection when `--client` is omitted: the native clients found on PATH. Codex
426
+ * also needs `node`, the same pair the explicit `--client codex` path checks.
427
+ * @returns {'claude' | 'codex' | 'both' | null}
428
+ */
429
+ function detectedClients() {
430
+ const hasClaude = resolveNative('claude') !== null;
431
+ const hasCodex = resolveNative('codex') !== null && resolveNative('node') !== null;
432
+ if (hasClaude && hasCodex) return 'both';
433
+ if (hasClaude) return 'claude';
434
+ return hasCodex ? 'codex' : null;
435
+ }
436
+
437
+ /** @param {string | undefined} requested @returns {'claude' | 'codex' | 'both'} */
438
+ function setupClients(requested) {
439
+ if (requested !== undefined) {
440
+ if (requested !== 'claude' && requested !== 'codex' && requested !== 'both')
441
+ throw new Error('invalid_client');
442
+ return requested;
443
+ }
444
+ const detected = detectedClients();
445
+ if (detected === null) throw new Error('no_native_client_found');
446
+ console.log(`Clients detected on PATH: ${detected} (pass --client to choose).`);
447
+ return detected;
448
+ }
449
+
419
450
  /** @param {string[]} args */
420
451
  async function setup(args) {
421
452
  if (args.includes('--yes')) throw new Error('explicit_disclosure_flag_required');
@@ -453,8 +484,10 @@ async function setup(args) {
453
484
  throw new Error('setup_undo_cannot_have_options');
454
485
  const lang = option(args, '--lang');
455
486
  if (lang !== undefined && !isPackLocale(lang)) throw new Error('invalid_lang');
456
- if (lang !== undefined && args.length === 2) return setPackLocale(lang);
457
487
  const previous = await readConfig();
488
+ // `--lang` alone only switches the language of an existing setup. Before the first
489
+ // setup it runs the full setup (token included) and stores the language at the end.
490
+ if (lang !== undefined && args.length === 2 && previous !== null) return setPackLocale(lang);
458
491
  if (await updateLocalOptOut(previous, args)) return;
459
492
  const localOptOut =
460
493
  option(args, '--telemetry') === 'off' &&
@@ -462,8 +495,7 @@ async function setup(args) {
462
495
  if (localOptOut) return disableTelemetryLocally(previous);
463
496
  const platform = platformCheck();
464
497
  if (!platform.ok) throw new Error(`${platform.code}:${platform.message}`);
465
- const clients = option(args, '--client') ?? 'both';
466
- if (!['claude', 'codex', 'both'].includes(clients)) throw new Error('invalid_client');
498
+ const clients = setupClients(option(args, '--client'));
467
499
  if (
468
500
  clients === 'codex' &&
469
501
  (option(args, '--claude-shadow') !== undefined ||
@@ -472,7 +504,7 @@ async function setup(args) {
472
504
  throw new Error('claude_observation_requires_claude_client');
473
505
  const endpoint = option(args, '--endpoint') ?? ENDPOINT;
474
506
  validateEndpoint(endpoint);
475
- const selection = selectedPolicy(args, previous);
507
+ const selection = selectedPolicy(args, previous, clients);
476
508
  const telemetry = telemetrySelection(args, previous);
477
509
  const claudeObservation = claudeObservationSelection(args, previous);
478
510
  const policy = selection.policy;
package/dist/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@brunobracaioli/aibrain",
3
- "version": "0.4.0-beta.11",
3
+ "version": "0.4.0-beta.12",
4
4
  "type": "module"
5
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brunobracaioli/aibrain",
3
- "version": "0.4.0-beta.11",
3
+ "version": "0.4.0-beta.12",
4
4
  "private": false,
5
5
  "description": "AISAC client for Claude Code and Codex: AI Brain memory, context management and AISAC Engineering",
6
6
  "license": "UNLICENSED",