@jaimevalasek/aioson 1.20.0 → 1.21.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.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file.
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [1.21.0] - 2026-06-XX
8
+
9
+ ### Added
10
+ - **Gemini CLI deprecation warning (gemini-phaseout Phase 1).** Google announced (2026-05-20) that the Gemini CLI free/personal tier ends 2026-06-18.
11
+ - `install-wizard` now flags Gemini as `[DEPRECATED]` in the tool list and prints a post-selection notice when Gemini is chosen.
12
+ - `doctor` reports `harness:gemini_deprecation` (warning) when `.gemini/permissions.toml` or `.gemini/GEMINI.md` is detected — zero output on projects without `.gemini/`.
13
+ - `permissions-generator` continues to emit `.gemini/permissions.toml` with a header warning (enterprise unaffected).
14
+ - `tool-capabilities` Gemini entry annotated as deprecated.
15
+ - Warning strings localized in all 4 locales (en, pt-BR, es, fr).
16
+ - Enterprise users (Code Assist Standard/Enterprise) are unaffected.
17
+ - Hard removal scheduled for v1.22 (post 2026-06-18). Pre-existing `.gemini/permissions.toml` will be preserved.
18
+ - Recommended migration: `--tool=codex` or `--tool=opencode`.
19
+
7
20
  ## [1.18.0] - 2026-05-27
8
21
 
9
22
  ### Added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jaimevalasek/aioson",
3
- "version": "1.20.0",
3
+ "version": "1.21.0",
4
4
  "description": "AI operating framework for hyper-personalized software.",
5
5
  "keywords": [
6
6
  "ai",
@@ -147,6 +147,11 @@ async function runInstall({ args, options, logger, t }) {
147
147
  logger.log(t('install.existing_project_scan_hint'));
148
148
  }
149
149
 
150
+ if (installProfile && Array.isArray(installProfile.tools) && installProfile.tools.includes('gemini')) {
151
+ logger.log('');
152
+ logger.log(t('install.gemini_deprecation_notice'));
153
+ }
154
+
150
155
  return {
151
156
  ok: true,
152
157
  targetDir,
package/src/doctor.js CHANGED
@@ -241,6 +241,23 @@ async function runDoctor(targetDir) {
241
241
  });
242
242
  }
243
243
 
244
+ // Gemini CLI deprecation advisory (gemini-phaseout Phase 1 / v1.21.0).
245
+ // Emits ONLY when the project actually uses Gemini (.gemini/permissions.toml
246
+ // OR .gemini/GEMINI.md present) so greenfield projects stay silent (BR-GP-03).
247
+ const geminiInUse =
248
+ (await exists(path.join(targetDir, '.gemini/permissions.toml'))) ||
249
+ (await exists(path.join(targetDir, '.gemini/GEMINI.md')));
250
+ if (geminiInUse) {
251
+ checks.push({
252
+ id: 'harness:gemini_deprecation',
253
+ severity: 'warning',
254
+ key: 'doctor.gemini_deprecation',
255
+ params: {},
256
+ ok: false,
257
+ hintKey: 'doctor.gemini_deprecation_hint'
258
+ });
259
+ }
260
+
244
261
  const contextPath = path.join(targetDir, '.aioson/context/project.context.md');
245
262
  checks.push({
246
263
  id: 'context:project',
@@ -327,6 +327,7 @@ module.exports = {
327
327
  files_skipped: 'Files skipped: {count}',
328
328
  dry_run_header: '⚠ DRY RUN — no files were written. Showing what install would do:',
329
329
  dry_run_done_at: 'DRY RUN: nothing was written to {targetDir}',
330
+ gemini_deprecation_notice: '[DEPRECATED] Gemini CLI free/personal tier will be discontinued on 2026-06-18. Consider Codex or OpenCode for new projects. Enterprise (Code Assist Standard/Enterprise) continues to work.',
330
331
  dry_run_files_copied: 'Files that would be copied: {count}',
331
332
  dry_run_files_skipped: 'Files that would be skipped: {count}',
332
333
  next_steps: 'Next steps:',
@@ -399,6 +400,9 @@ module.exports = {
399
400
  context_conversation_language_format: '`conversation_language` is not a valid BCP-47 tag',
400
401
  context_conversation_language_format_hint: 'Use values like en, en-US, pt-BR.',
401
402
  node_version: 'Node.js >= 18 (current: {version})',
403
+ gemini_deprecation: 'Gemini CLI in use - free tier ends 2026-06-18 (enterprise unaffected)',
404
+ gemini_deprecation_hint:
405
+ 'Run `aioson permissions-generator --tool=codex` (or --tool=opencode) to migrate. Enterprise (Code Assist Standard/Enterprise) keeps working; pre-existing .gemini/permissions.toml is preserved.',
402
406
  gateway_claude_pointer: 'CLAUDE gateway references shared AIOSON files',
403
407
  gateway_claude_pointer_hint:
404
408
  'Ensure CLAUDE.md references .aioson/config.md and .aioson/agents/setup.md.',
@@ -198,6 +198,7 @@ module.exports = {
198
198
  files_skipped: 'Archivos omitidos: {count}',
199
199
  dry_run_header: '⚠ DRY RUN — no se escribio ningun archivo. Mostrando lo que haria el install:',
200
200
  dry_run_done_at: 'DRY RUN: no se escribio nada en {targetDir}',
201
+ gemini_deprecation_notice: '[DEPRECATED] El tier gratuito/personal de Gemini CLI se descontinuara el 2026-06-18. Considera Codex u OpenCode para nuevos proyectos. Enterprise (Code Assist Standard/Enterprise) sigue funcionando.',
201
202
  dry_run_files_copied: 'Archivos que se copiarian (would be copied): {count}',
202
203
  dry_run_files_skipped: 'Archivos que se omitirian (would be skipped): {count}',
203
204
  next_steps: 'Siguientes pasos:',
@@ -278,6 +279,9 @@ module.exports = {
278
279
  context_conversation_language_format: '`conversation_language` no es una etiqueta BCP-47 valida',
279
280
  context_conversation_language_format_hint: 'Usa valores como en, en-US, pt-BR.',
280
281
  node_version: 'Node.js >= 18 (actual: {version})',
282
+ gemini_deprecation: 'Gemini CLI en uso - el tier gratuito termina el 2026-06-18 (enterprise no afectado)',
283
+ gemini_deprecation_hint:
284
+ 'Ejecuta `aioson permissions-generator --tool=codex` (o --tool=opencode) para migrar. Enterprise (Code Assist Standard/Enterprise) sigue funcionando; el .gemini/permissions.toml preexistente se conserva.',
281
285
  gateway_claude_pointer: 'El gateway de CLAUDE referencia archivos compartidos de AIOSON',
282
286
  gateway_claude_pointer_hint:
283
287
  'Asegura que CLAUDE.md referencie .aioson/config.md y .aioson/agents/setup.md.',
@@ -198,6 +198,7 @@ module.exports = {
198
198
  files_skipped: 'Fichiers ignores : {count}',
199
199
  dry_run_header: '⚠ DRY RUN — aucun fichier ecrit. Apercu de ce que install ferait :',
200
200
  dry_run_done_at: 'DRY RUN : rien n a ete ecrit dans {targetDir}',
201
+ gemini_deprecation_notice: '[DEPRECATED] Le palier gratuit/personnel de Gemini CLI sera supprime le 2026-06-18. Envisagez Codex ou OpenCode pour les nouveaux projets. Enterprise (Code Assist Standard/Enterprise) continue de fonctionner.',
201
202
  dry_run_files_copied: 'Fichiers qui seraient copies (would be copied) : {count}',
202
203
  dry_run_files_skipped: 'Fichiers qui seraient ignores (would be skipped) : {count}',
203
204
  next_steps: 'Etapes suivantes :',
@@ -277,6 +278,9 @@ module.exports = {
277
278
  context_conversation_language_format: '`conversation_language` n est pas une balise BCP-47 valide',
278
279
  context_conversation_language_format_hint: 'Utilisez des valeurs comme en, en-US, pt-BR.',
279
280
  node_version: 'Node.js >= 18 (actuel : {version})',
281
+ gemini_deprecation: 'Gemini CLI utilise - le palier gratuit se termine le 2026-06-18 (enterprise non affecte)',
282
+ gemini_deprecation_hint:
283
+ 'Lancez `aioson permissions-generator --tool=codex` (ou --tool=opencode) pour migrer. Enterprise (Code Assist Standard/Enterprise) continue de fonctionner; le .gemini/permissions.toml preexistant est conserve.',
280
284
  gateway_claude_pointer: 'La passerelle CLAUDE reference les fichiers partages AIOSON',
281
285
  gateway_claude_pointer_hint:
282
286
  'Assurez-vous que CLAUDE.md reference .aioson/config.md et .aioson/agents/setup.md.',
@@ -292,6 +292,7 @@ module.exports = {
292
292
  files_skipped: 'Arquivos ignorados: {count}',
293
293
  dry_run_header: '⚠ DRY RUN — nenhum arquivo foi escrito. Mostrando o que o install faria:',
294
294
  dry_run_done_at: 'DRY RUN: nada foi escrito em {targetDir}',
295
+ gemini_deprecation_notice: '[DEPRECATED] O tier free/pessoal do Gemini CLI sera descontinuado em 2026-06-18. Considere Codex ou OpenCode para novos projetos. Enterprise (Code Assist Standard/Enterprise) continua funcionando.',
295
296
  dry_run_files_copied: 'Arquivos que seriam copiados (would be copied): {count}',
296
297
  dry_run_files_skipped: 'Arquivos que seriam ignorados (would be skipped): {count}',
297
298
  next_steps: 'Proximos passos:',
@@ -372,6 +373,9 @@ module.exports = {
372
373
  '`conversation_language` nao e uma tag BCP-47 valida',
373
374
  context_conversation_language_format_hint: 'Use valores como en, en-US, pt-BR.',
374
375
  node_version: 'Node.js >= 18 (atual: {version})',
376
+ gemini_deprecation: 'Gemini CLI em uso - tier free encerra em 2026-06-18 (enterprise nao afetado)',
377
+ gemini_deprecation_hint:
378
+ 'Rode `aioson permissions-generator --tool=codex` (ou --tool=opencode) para migrar. Enterprise (Code Assist Standard/Enterprise) continua funcionando; .gemini/permissions.toml pre-existente e preservado.',
375
379
  gateway_claude_pointer: 'Gateway do CLAUDE referencia arquivos compartilhados do AIOSON',
376
380
  gateway_claude_pointer_hint:
377
381
  'Garanta que CLAUDE.md referencie .aioson/config.md e .aioson/agents/setup.md.',
@@ -6,7 +6,7 @@ const { getCliVersionSync } = require('./version');
6
6
  const TOOLS = [
7
7
  { id: 'claude', label: 'Claude Code', desc: 'Slash commands, CLAUDE.md, .claude/' },
8
8
  { id: 'codex', label: 'Codex (OpenAI)', desc: 'AGENTS.md protocol' },
9
- { id: 'gemini', label: 'Gemini CLI', desc: 'GEMINI.md + .gemini/commands/' },
9
+ { id: 'gemini', label: 'Gemini CLI', desc: 'GEMINI.md + .gemini/commands/', deprecated: true },
10
10
  { id: 'opencode', label: 'OpenCode', desc: 'OPENCODE.md protocol' }
11
11
  ];
12
12
 
@@ -112,7 +112,8 @@ function renderScreen1(cursor, selected, warn, stdout) {
112
112
  const tool = TOOLS[i];
113
113
  const pointer = i === cursor ? '►' : ' ';
114
114
  const check = selected.has(tool.id) ? '✓' : ' ';
115
- stdout.write(` ${pointer} [${check}] ${tool.label.padEnd(20)} ${tool.desc}\n`);
115
+ const deprNote = tool.deprecated ? ' [DEPRECATED] free tier ends 2026-06-18' : '';
116
+ stdout.write(` ${pointer} [${check}] ${tool.label.padEnd(20)} ${tool.desc}${deprNote}\n`);
116
117
  }
117
118
  if (warn) stdout.write('\n ⚠ Select at least one tool to continue.\n');
118
119
  stdout.write('\n');
@@ -5,11 +5,11 @@
5
5
  // "continue last conversation" is achieved by passing the right resume flag
6
6
  // at spawn time — AIOSON never has to track an internal session ID.
7
7
  //
8
- // Used by:
9
- // - `aioson live:start --resume[=last|<id>]` to map to the correct argv
10
- // - `aioson live:start --permission-mode=yolo` to map to the correct argv
11
- // - `aioson tool:capabilities` to expose this map as JSON to UI clients
12
- // (e.g. AIOSON Play) so they don't duplicate the lookup.
8
+ // Used by:
9
+ // - `aioson live:start --resume[=last|<id>]` to map to the correct argv
10
+ // - `aioson live:start --permission-mode=yolo` to map to the correct argv
11
+ // - `aioson tool:capabilities` to expose this map as JSON to UI clients
12
+ // (e.g. AIOSON Play) so they don't duplicate the lookup.
13
13
  //
14
14
  // Keep entries minimal and source-of-truth here. Adding a new CLI = one entry.
15
15
  const TOOL_CAPS = {
@@ -18,50 +18,53 @@ const TOOL_CAPS = {
18
18
  binary: 'claude',
19
19
  supports_resume: true,
20
20
  resume_last: ['--continue'],
21
- supports_session_id: true,
22
- resume_session_id: ['--resume', '<id>'],
23
- supports_session_picker: true,
24
- session_picker: ['--resume'],
25
- supports_yolo: true,
26
- yolo_args: ['--dangerously-skip-permissions'],
27
- },
28
- codex: {
21
+ supports_session_id: true,
22
+ resume_session_id: ['--resume', '<id>'],
23
+ supports_session_picker: true,
24
+ session_picker: ['--resume'],
25
+ supports_yolo: true,
26
+ yolo_args: ['--dangerously-skip-permissions'],
27
+ },
28
+ codex: {
29
29
  install_command: 'npm install -g @openai/codex',
30
30
  binary: 'codex',
31
31
  supports_resume: true,
32
32
  resume_last: ['resume', '--last'],
33
- supports_session_id: true,
34
- resume_session_id: ['resume', '<id>'],
35
- supports_session_picker: true,
36
- session_picker: ['resume'],
37
- supports_yolo: true,
38
- yolo_args: ['--dangerously-bypass-approvals-and-sandbox'],
39
- },
40
- opencode: {
33
+ supports_session_id: true,
34
+ resume_session_id: ['resume', '<id>'],
35
+ supports_session_picker: true,
36
+ session_picker: ['resume'],
37
+ supports_yolo: true,
38
+ yolo_args: ['--dangerously-bypass-approvals-and-sandbox'],
39
+ },
40
+ opencode: {
41
41
  install_command: 'npm install -g opencode-ai',
42
42
  binary: 'opencode',
43
43
  supports_resume: true,
44
44
  resume_last: ['--continue'],
45
- supports_session_id: true,
46
- resume_session_id: ['--session', '<id>'],
47
- supports_session_picker: false,
48
- session_picker: null,
49
- supports_yolo: false,
50
- yolo_args: null,
51
- },
52
- gemini: {
45
+ supports_session_id: true,
46
+ resume_session_id: ['--session', '<id>'],
47
+ supports_session_picker: false,
48
+ session_picker: null,
49
+ supports_yolo: false,
50
+ yolo_args: null,
51
+ },
52
+ // DEPRECATED: Gemini CLI free/personal tier ends 2026-06-18. Enterprise
53
+ // (Code Assist Standard/Enterprise) unaffected. Hard removal in v1.22.
54
+ // See gemini-phaseout / CHANGELOG v1.21.x.
55
+ gemini: {
53
56
  install_command: 'npm install -g @google/gemini-cli',
54
57
  binary: 'gemini',
55
58
  supports_resume: false,
56
59
  resume_last: null,
57
- supports_session_id: false,
58
- resume_session_id: null,
59
- supports_session_picker: false,
60
- session_picker: null,
61
- supports_yolo: false,
62
- yolo_args: null,
63
- },
64
- };
60
+ supports_session_id: false,
61
+ resume_session_id: null,
62
+ supports_session_picker: false,
63
+ session_picker: null,
64
+ supports_yolo: false,
65
+ yolo_args: null,
66
+ },
67
+ };
65
68
 
66
69
  function getToolCapabilities(tool) {
67
70
  const key = String(tool || '').trim().toLowerCase();
@@ -80,7 +83,7 @@ function listSupportedTools() {
80
83
  // - '' / undefined / null / false → no resume
81
84
  // - any other string → treat as session id
82
85
  // Returns [] when the tool doesn't support resume or resumeOpt is falsy.
83
- function resolveResumeArgs(tool, resumeOpt) {
86
+ function resolveResumeArgs(tool, resumeOpt) {
84
87
  if (resumeOpt === undefined || resumeOpt === null || resumeOpt === '' || resumeOpt === false) {
85
88
  return [];
86
89
  }
@@ -101,29 +104,29 @@ function resolveResumeArgs(tool, resumeOpt) {
101
104
  }
102
105
 
103
106
  return Array.isArray(caps.resume_last) ? [...caps.resume_last] : [];
104
- }
105
-
106
- function resolvePermissionModeArgs(tool, permissionMode) {
107
- const mode = String(permissionMode || '').trim().toLowerCase();
108
- if (!mode || mode === 'default') return [];
109
- if (mode !== 'yolo') {
110
- throw new Error(`permission_mode_unknown:${permissionMode}`);
111
- }
112
-
113
- const caps = getToolCapabilities(tool);
114
- if (!caps) {
115
- throw new Error(`tool_unknown:${tool}`);
116
- }
117
- if (!caps.supports_yolo || !Array.isArray(caps.yolo_args)) {
118
- throw new Error(`permission_mode_unsupported:${tool}:yolo`);
119
- }
120
- return [...caps.yolo_args];
121
- }
122
-
123
- module.exports = {
124
- TOOL_CAPS,
125
- getToolCapabilities,
126
- listSupportedTools,
127
- resolveResumeArgs,
128
- resolvePermissionModeArgs,
129
- };
107
+ }
108
+
109
+ function resolvePermissionModeArgs(tool, permissionMode) {
110
+ const mode = String(permissionMode || '').trim().toLowerCase();
111
+ if (!mode || mode === 'default') return [];
112
+ if (mode !== 'yolo') {
113
+ throw new Error(`permission_mode_unknown:${permissionMode}`);
114
+ }
115
+
116
+ const caps = getToolCapabilities(tool);
117
+ if (!caps) {
118
+ throw new Error(`tool_unknown:${tool}`);
119
+ }
120
+ if (!caps.supports_yolo || !Array.isArray(caps.yolo_args)) {
121
+ throw new Error(`permission_mode_unsupported:${tool}:yolo`);
122
+ }
123
+ return [...caps.yolo_args];
124
+ }
125
+
126
+ module.exports = {
127
+ TOOL_CAPS,
128
+ getToolCapabilities,
129
+ listSupportedTools,
130
+ resolveResumeArgs,
131
+ resolvePermissionModeArgs,
132
+ };
@@ -195,6 +195,9 @@ function tomlString(value) {
195
195
  function buildGeminiToml({ shellPatterns, aiosonCommands, denyShellPatterns = [], denyAiosonCommands = [] }, tool) {
196
196
  const lines = [];
197
197
  lines.push('# Generated by aioson permissions-generator. Do not edit by hand.');
198
+ lines.push('# WARNING: Gemini CLI free tier ends 2026-06-18. This file remains');
199
+ lines.push('# functional for enterprise users (Code Assist Standard/Enterprise).');
200
+ lines.push('# See AIOSON CHANGELOG v1.21.x for migration guidance.');
198
201
  lines.push('version = "1.1"');
199
202
  lines.push(`mode = ${tomlString(tool.mode || 'guarded')}`);
200
203
  lines.push(`requires_tty = ${Boolean(tool.requires_tty)}`);