@aiwg/cli 2026.9.15 → 2026.9.16

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 (33) hide show
  1. package/agentic/code/providers/capability-matrix.yaml +42 -0
  2. package/agentic/code/providers/model-capabilities.v1.json +119 -34
  3. package/agentic/code/providers/model-catalog.v1.json +259 -56
  4. package/dist/src/cli/handlers/sessions.js +159 -45
  5. package/dist/src/cli/handlers/use.js +20 -1
  6. package/dist/src/cli/scope-resolver.js +13 -0
  7. package/dist/src/cli/services/deployment-verification.js +33 -2
  8. package/dist/src/config/aiwg-config.js +39 -0
  9. package/dist/src/config/user-registry.js +9 -0
  10. package/dist/src/extensions/manifest.js +1 -0
  11. package/dist/src/models/model-capabilities.v1.json +119 -34
  12. package/dist/src/models/model-catalog.v1.json +259 -56
  13. package/dist/src/models/model-discovery.js +7 -0
  14. package/dist/src/models/provider-policy.js +1 -1
  15. package/dist/src/plugin/skill-command-translator.js +1 -0
  16. package/dist/src/providers/capability-matrix.yaml +42 -0
  17. package/dist/src/providers/grokbot-paths.js +103 -0
  18. package/dist/src/providers/provider-definitions.js +85 -1
  19. package/dist/src/providers/provider-inventory.js +1 -0
  20. package/dist/src/sessions/adapters/grokbot.js +49 -0
  21. package/dist/src/sessions/adapters/hermes.js +17 -9
  22. package/dist/src/sessions/adapters/opencode.js +12 -1
  23. package/dist/src/sessions/contracts.js +1 -1
  24. package/dist/src/sessions/export-plan.js +130 -4
  25. package/dist/src/sessions/fortemi-export-mapping.js +10 -6
  26. package/dist/src/sessions/fortemi-shard-blobs.js +78 -0
  27. package/dist/src/sessions/index.js +2 -0
  28. package/dist/src/sessions/workspace-discovery.js +1 -1
  29. package/dist/src/skills/deployer.js +17 -0
  30. package/dist/src/smiths/skillsmith/collision-detector.js +1 -0
  31. package/package.json +1 -1
  32. package/tools/agents/deploy-agents.mjs +3 -2
  33. package/tools/agents/providers/grokbot.mjs +285 -0
@@ -16,6 +16,7 @@ import { AGENT_SKILLS_SIDECAR_SCHEMA, AIWG_SKILL_CONTROL_FIELDS, createAgentSkil
16
16
  import { getImportedAgentSkill } from './importer.js';
17
17
  import { validateAgentSkillContent } from './validator.js';
18
18
  import { resolveHermesHomePath } from '../providers/hermes-home.js';
19
+ import { GROKBOT_SKILLS_DIR_ENV, grokbotMissingRootRemediation, resolveGrokbotSkillsDir, } from '../providers/grokbot-paths.js';
19
20
  export const AGENT_SKILL_MANAGED_MARKER = '.aiwg-managed';
20
21
  export const AGENT_SKILL_DEPLOYMENT_SIDECAR = '.aiwg-agent-skill.json';
21
22
  const MARKER_CONTENT = 'aiwg-agent-skill-v1\n';
@@ -78,6 +79,22 @@ function resolvePolicy(target, options) {
78
79
  appendToDescription = namespace.appendToDescription;
79
80
  reasons.push('applies the Factory description guidance before strict validation');
80
81
  break;
82
+ case 'grokbot': {
83
+ // Fail closed: never invent ~/grokbot-skills or ~/.grokbot.
84
+ const configured = resolveGrokbotSkillsDir(process.env);
85
+ if (!configured) {
86
+ root = '';
87
+ status = 'unsupported';
88
+ supported = false;
89
+ reasons.push(grokbotMissingRootRemediation(process.env));
90
+ warnings.push(`Agent Skills deploy for grokbot requires absolute ${GROKBOT_SKILLS_DIR_ENV}; no filesystem root was invented`);
91
+ }
92
+ else {
93
+ root = configured;
94
+ reasons.push(`uses the operator-configured ${GROKBOT_SKILLS_DIR_ENV} skills root with strict managed ownership markers`);
95
+ }
96
+ break;
97
+ }
81
98
  case 'hermes':
82
99
  if (options.homeDir === undefined) {
83
100
  root = resolveHermesHomePath('skills');
@@ -36,6 +36,7 @@ const PLATFORM_BUILTINS = {
36
36
  'opencode': ['help', 'run'],
37
37
  'warp': ['help', 'settings'],
38
38
  'hermes': [],
39
+ 'grokbot': [],
39
40
  'openclaw': [],
40
41
  'openhuman': [],
41
42
  'factory': [],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiwg/cli",
3
- "version": "2026.9.15",
3
+ "version": "2026.9.16",
4
4
  "description": "Lightweight AIWG CLI for signed, versioned web-backed resources.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -20,7 +20,7 @@
20
20
  * --rules-only Deploy only rules (skip agents)
21
21
  * --dry-run Show what would be deployed without writing
22
22
  * --force Overwrite existing files
23
- * --provider <name> Target provider: antigravity (agy), claude (default), openai, codex, cursor, opencode, copilot, factory, pi, omp, deepseek-harness (dsh), warp, devin, hermes, or openclaw
23
+ * --provider <name> Target provider: antigravity (agy), claude (default), openai, codex, cursor, opencode, copilot, factory, grokbot, pi, omp, deepseek-harness (dsh), warp, devin, hermes, openhuman, or openclaw
24
24
  * --model <name> Override model for all tiers (blanket)
25
25
  * --reasoning-model <name> Override model for reasoning tasks
26
26
  * --coding-model <name> Override model for coding tasks
@@ -123,7 +123,7 @@ const PROVIDER_ALIASES = {
123
123
  'dsh': 'deepseek-harness',
124
124
  };
125
125
 
126
- const AVAILABLE_PROVIDERS = ['antigravity', 'claude', 'factory', 'codex', 'opencode', 'copilot', 'cursor', 'pi', 'omp', 'deepseek-harness', 'warp', 'windsurf', 'hermes', 'openclaw', 'openhuman'];
126
+ const AVAILABLE_PROVIDERS = ['antigravity', 'claude', 'factory', 'codex', 'opencode', 'copilot', 'cursor', 'pi', 'omp', 'deepseek-harness', 'warp', 'windsurf', 'hermes', 'openclaw', 'openhuman', 'grokbot'];
127
127
 
128
128
  const UNSUPPORTED_PROVIDER_HINTS = {
129
129
  'devin-cli': [
@@ -651,6 +651,7 @@ Providers (all deploy agents, commands, skills, and rules):
651
651
  Paths: AGENTS.md, .agents/skills/, .dsh/aiwg.cordis.patch.yml
652
652
  devin - Devin Desktop (preferred; aliases: devin-desktop, windsurf)
653
653
  Paths: .windsurf/agents/, .windsurf/workflows/, .windsurf/skills/, .windsurf/rules/
654
+ grokbot - Grok Bot (experimental; AGENTS.md bridge; skills only with AIWG_GROKBOT_SKILLS_DIR)
654
655
  hermes - Hermes Agent (MCP-based integration)
655
656
  Skills: $HERMES_HOME/skills/ (user-global; defaults to ~/.hermes/skills/) | Agents: AGENTS.md
656
657
  Commands/Rules: served via MCP, not file-deployed
@@ -0,0 +1,285 @@
1
+ /**
2
+ * Grok Bot provider (experimental).
3
+ *
4
+ * Discover-first project bridge + fail-closed user skill root.
5
+ * Never targets `.cursor/**` or invents `~/.grokbot`.
6
+ *
7
+ * User-scope skill writes require AIWG_GROKBOT_SKILLS_DIR (absolute path).
8
+ * See `docs/architecture/adr-grokbot-provider-target.md` and #203–#208.
9
+ */
10
+
11
+ import path from 'path';
12
+ import os from 'os';
13
+ import {
14
+ collectFrameworkArtifacts,
15
+ createAgentsMdFromTemplate,
16
+ deploySkillsWithKernelRouting,
17
+ getAddonSkillDirs,
18
+ normalizeDeploymentMode,
19
+ resolveAiwgRoot,
20
+ } from './base.mjs';
21
+
22
+ export const name = 'grokbot';
23
+ export const aliases = [];
24
+
25
+ const SKILLS_DIR_ENV = 'AIWG_GROKBOT_SKILLS_DIR';
26
+
27
+ /**
28
+ * Resolve configured Grok Bot skills directory (fail-closed).
29
+ * Mirrors src/providers/grokbot-paths.ts for the JS deploy path.
30
+ */
31
+ export function resolveGrokbotSkillsDir(env = process.env, userHome = os.homedir()) {
32
+ const raw = (env[SKILLS_DIR_ENV] || '').trim();
33
+ if (!raw) return null;
34
+ let expanded = raw;
35
+ if (raw === '~') return null;
36
+ if (raw.startsWith('~/')) expanded = path.join(userHome, raw.slice(2));
37
+ if (!path.isAbsolute(expanded)) return null;
38
+ const resolved = path.resolve(expanded);
39
+ if (!resolved || resolved === path.sep) return null;
40
+ return resolved;
41
+ }
42
+
43
+ export function getGrokbotMissingRootMessage(env = process.env) {
44
+ const raw = (env[SKILLS_DIR_ENV] || '').trim();
45
+ if (!raw) {
46
+ return (
47
+ `Grok Bot user-scope skill root is not configured. Set ${SKILLS_DIR_ENV} ` +
48
+ 'to the absolute path of the Grok Bot skills/workflows directory before ' +
49
+ 'using --scope user or --global. AIWG does not invent ~/.grokbot.'
50
+ );
51
+ }
52
+ if (raw === '~' || (!raw.startsWith('~/') && !path.isAbsolute(raw))) {
53
+ return (
54
+ `${SKILLS_DIR_ENV} must be an absolute path (got '${raw}'). ` +
55
+ 'Relative values and bare ~ are rejected.'
56
+ );
57
+ }
58
+ if (raw.startsWith('~/')) {
59
+ const expanded = path.join(os.homedir(), raw.slice(2));
60
+ if (!path.isAbsolute(path.resolve(expanded))) {
61
+ return `${SKILLS_DIR_ENV} must resolve to an absolute path (got '${raw}').`;
62
+ }
63
+ }
64
+ return (
65
+ `Grok Bot skill root '${raw}' is not usable. Set ${SKILLS_DIR_ENV} to a ` +
66
+ 'valid absolute directory.'
67
+ );
68
+ }
69
+
70
+ // Project-relative paths stay empty: agents/commands/rules are indexed.
71
+ // Skills path is absolute only when the operator configured the env override;
72
+ // otherwise '' so project deploy skips native skill copies.
73
+ function configuredSkillsPath() {
74
+ return resolveGrokbotSkillsDir() || '';
75
+ }
76
+
77
+ export const paths = {
78
+ agents: '',
79
+ commands: '',
80
+ get skills() {
81
+ return configuredSkillsPath();
82
+ },
83
+ rules: '',
84
+ };
85
+
86
+ // Empty when unset — deploySkills resolves AIWG_GROKBOT_SKILLS_DIR dynamically.
87
+ // Never default to ~/.grokbot.
88
+ export const kernelSkillsPath = '';
89
+
90
+ export const support = {
91
+ agents: 'indexed',
92
+ commands: 'indexed',
93
+ skills: 'native-when-configured',
94
+ rules: 'indexed',
95
+ };
96
+
97
+ export const capabilities = {
98
+ skills: true,
99
+ rules: false,
100
+ aggregatedOutput: false,
101
+ yamlFormat: false,
102
+ homeDirectoryDeploy: true,
103
+ };
104
+
105
+ export function mapModel(originalModel) {
106
+ return originalModel;
107
+ }
108
+
109
+ export function transformAgent(_srcPath, content) {
110
+ return content;
111
+ }
112
+
113
+ export function transformCommand(_srcPath, content) {
114
+ return content;
115
+ }
116
+
117
+ export function deployAgents() {
118
+ return 0;
119
+ }
120
+
121
+ export function deployCommands() {
122
+ return 0;
123
+ }
124
+
125
+ export function deployRules() {
126
+ return 0;
127
+ }
128
+
129
+ /**
130
+ * Deploy skills only when AIWG_GROKBOT_SKILLS_DIR is configured.
131
+ * Kernel → configured root; standard → index/discovery unless --copy-all
132
+ * (then `<root>/.aiwg/skills`).
133
+ */
134
+ export function deploySkills(skillDirs, targetDir, opts = {}) {
135
+ const root = resolveGrokbotSkillsDir(opts.env || process.env);
136
+ if (!root) {
137
+ if (!opts.quiet) {
138
+ console.log(
139
+ `\n Grok Bot: skipping native skill copy (${SKILLS_DIR_ENV} unset). ` +
140
+ 'Skills remain available via aiwg discover / aiwg show.',
141
+ );
142
+ }
143
+ return 0;
144
+ }
145
+
146
+ if (root.includes(`${path.sep}.cursor${path.sep}`) || root.endsWith(`${path.sep}.cursor`) || root.includes('/.cursor/') || root.endsWith('/.cursor')) {
147
+ throw new Error(
148
+ `Refusing to deploy Grok Bot skills into a .cursor path (${root}). ` +
149
+ `Set ${SKILLS_DIR_ENV} to the Grok Bot skills root, not Cursor.`,
150
+ );
151
+ }
152
+
153
+ const kernelDest = root;
154
+ const standardDest = path.join(root, '.aiwg', 'skills');
155
+ if (!opts.quiet) {
156
+ console.log(
157
+ `\n Grok Bot skills root: ${root} (from ${SKILLS_DIR_ENV})` +
158
+ (opts.dryRun ? ' [dry-run]' : ''),
159
+ );
160
+ }
161
+ return deploySkillsWithKernelRouting(skillDirs, standardDest, kernelDest, {
162
+ ...opts,
163
+ copyStandardSkills: opts.copyStandardSkills === true,
164
+ });
165
+ }
166
+
167
+ export function createAgentsMd(target, srcRoot, dryRun) {
168
+ const aiwgRoot = resolveAiwgRoot(srcRoot) || srcRoot;
169
+ createAgentsMdFromTemplate(target, aiwgRoot, 'grokbot/AGENTS.md.aiwg-template', dryRun);
170
+ }
171
+
172
+ export async function postDeploy(targetDir, opts = {}) {
173
+ if (
174
+ opts.createAgentsMd ||
175
+ (!opts.commandsOnly && !opts.skillsOnly && !opts.rulesOnly)
176
+ ) {
177
+ createAgentsMd(targetDir, opts.srcRoot, opts.dryRun);
178
+ }
179
+ if (!opts.quiet) {
180
+ const root = resolveGrokbotSkillsDir(opts.env || process.env);
181
+ if (root) {
182
+ console.log(
183
+ 'Grok Bot: after deploy, start a new agent chat or re-read skills. ' +
184
+ 'Live refresh is not claimed until product behavior is verified.',
185
+ );
186
+ } else {
187
+ console.log(
188
+ `Grok Bot: project bridge only. Set ${SKILLS_DIR_ENV} for user-scope skill deploy.`,
189
+ );
190
+ }
191
+ }
192
+ }
193
+
194
+ export function getFileExtension() {
195
+ return '.md';
196
+ }
197
+
198
+ /**
199
+ * Assert user-scope is allowed. Called when the orchestrator is mirroring
200
+ * to user scope or when opts.scope === 'user'.
201
+ */
202
+ export function assertUserScopeConfigured(opts = {}) {
203
+ const root = resolveGrokbotSkillsDir(opts.env || process.env);
204
+ if (!root) {
205
+ const err = new Error(getGrokbotMissingRootMessage(opts.env || process.env));
206
+ err.code = 'GROKBOT_SKILLS_DIR_UNSET';
207
+ throw err;
208
+ }
209
+ return root;
210
+ }
211
+
212
+ export async function deploy(opts = {}) {
213
+ const {
214
+ srcRoot,
215
+ target,
216
+ mode,
217
+ deploySkills: shouldDeploySkills,
218
+ skillsOnly,
219
+ commandsOnly,
220
+ rulesOnly,
221
+ scope,
222
+ } = opts;
223
+
224
+ if (!opts.quiet) {
225
+ console.log(`\n=== Grok Bot Provider (experimental) ===`);
226
+ console.log(`Target: ${target}`);
227
+ console.log(`Mode: ${mode}`);
228
+ const root = resolveGrokbotSkillsDir(opts.env || process.env);
229
+ console.log(
230
+ `Skills root: ${root || `(unset — set ${SKILLS_DIR_ENV} for user-scope writes)`}`,
231
+ );
232
+ if (opts.dryRun) console.log('Dry-run: no filesystem mutations');
233
+ }
234
+
235
+ // Fail closed when caller explicitly requested user scope without a root.
236
+ if (scope === 'user' || opts.userScope === true) {
237
+ assertUserScopeConfigured(opts);
238
+ }
239
+
240
+ const skillDirs = [];
241
+ const normalizedMode = normalizeDeploymentMode(mode);
242
+
243
+ if (['general', 'sdlc', 'both', 'all'].includes(normalizedMode)) {
244
+ if (shouldDeploySkills || skillsOnly) skillDirs.push(...getAddonSkillDirs(srcRoot));
245
+ }
246
+
247
+ const fw = collectFrameworkArtifacts(srcRoot, normalizedMode, {
248
+ includeAgents: false,
249
+ includeCommands: false,
250
+ includeSkills: shouldDeploySkills || skillsOnly,
251
+ includeRules: false,
252
+ });
253
+ skillDirs.push(...fw.skills);
254
+
255
+ let count = 0;
256
+ if ((shouldDeploySkills || skillsOnly) && !commandsOnly && !rulesOnly) {
257
+ count += deploySkills(skillDirs, target, opts);
258
+ }
259
+
260
+ await postDeploy(target, opts);
261
+ return count;
262
+ }
263
+
264
+ export default {
265
+ name,
266
+ aliases,
267
+ paths,
268
+ kernelSkillsPath,
269
+ support,
270
+ capabilities,
271
+ mapModel,
272
+ transformAgent,
273
+ transformCommand,
274
+ deployAgents,
275
+ deployCommands,
276
+ deploySkills,
277
+ deployRules,
278
+ createAgentsMd,
279
+ postDeploy,
280
+ getFileExtension,
281
+ deploy,
282
+ resolveGrokbotSkillsDir,
283
+ getGrokbotMissingRootMessage,
284
+ assertUserScopeConfigured,
285
+ };