contextos-agents 2.2.0 → 2.3.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 (108) hide show
  1. package/.agents/AGENTS.md +53 -396
  2. package/.agents/adapters/aider/export.js +11 -16
  3. package/.agents/adapters/claude/export.js +13 -13
  4. package/.agents/adapters/copilot/export.js +29 -8
  5. package/.agents/adapters/cursor/export.js +9 -18
  6. package/.agents/adapters/gemini/export.js +11 -46
  7. package/.agents/adapters/pure-compiler.js +65 -42
  8. package/.agents/adapters/shared.js +35 -1
  9. package/.agents/adapters/zed/export.js +2 -2
  10. package/.agents/compiled/registry.v2.json +30 -18
  11. package/.agents/compiled/registry.v2.sha256 +1 -1
  12. package/.agents/compiler/manifest-compiler.js +5 -29
  13. package/.agents/core/skills/context-os/references/project-graph.md +3 -3
  14. package/.agents/core/skills/engineering-workflow/SKILL.md +11 -316
  15. package/.agents/core/skills/engineering-workflow/references/workflow.md +336 -0
  16. package/.agents/core/skills/engineering-workflow/skill.yaml +2 -4
  17. package/.agents/core/skills/gstack-roles/SKILL.md +11 -128
  18. package/.agents/core/skills/gstack-roles/references/roles.md +149 -0
  19. package/.agents/core/skills/gstack-roles/skill.yaml +2 -4
  20. package/.agents/core/skills/ponytail-mindset/SKILL.md +13 -165
  21. package/.agents/core/skills/ponytail-mindset/references/minimalism.md +186 -0
  22. package/.agents/core/skills/ponytail-mindset/skill.yaml +2 -5
  23. package/.agents/core/skills/security/skill.yaml +1 -0
  24. package/.agents/ctx.js +13 -13
  25. package/.agents/customization-dx.js +13 -9
  26. package/.agents/doctor.js +2 -2
  27. package/.agents/generated/claude/skills/context-manager/EXAMPLES.md +19 -0
  28. package/.agents/generated/claude/skills/context-manager/SKILL.md +0 -29
  29. package/.agents/generated/claude/skills/context-manager/TROUBLESHOOTING.md +7 -0
  30. package/.agents/generated/claude/skills/context-manager/VALIDATION.json +12 -0
  31. package/.agents/generated/claude/skills/context-manager/references/context-rules.md +59 -0
  32. package/.agents/generated/claude/skills/context-os/EXAMPLES.md +21 -0
  33. package/.agents/generated/claude/skills/context-os/SKILL.md +0 -31
  34. package/.agents/generated/claude/skills/context-os/TROUBLESHOOTING.md +7 -0
  35. package/.agents/generated/claude/skills/context-os/VALIDATION.json +12 -0
  36. package/.agents/generated/claude/skills/context-os/packs.yaml +59 -0
  37. package/.agents/generated/claude/skills/context-os/references/context-rules.md +68 -0
  38. package/.agents/generated/claude/skills/context-os/references/pipeline.md +119 -0
  39. package/.agents/generated/claude/skills/context-os/references/project-graph.md +103 -0
  40. package/.agents/generated/claude/skills/context-os/rules.yaml +135 -0
  41. package/.agents/generated/claude/skills/engineering-workflow/EXAMPLES.md +57 -0
  42. package/.agents/generated/claude/skills/engineering-workflow/SKILL.md +10 -391
  43. package/.agents/generated/claude/skills/engineering-workflow/TROUBLESHOOTING.md +19 -0
  44. package/.agents/generated/claude/skills/engineering-workflow/VALIDATION.json +12 -0
  45. package/.agents/generated/claude/skills/engineering-workflow/references/workflow.md +336 -0
  46. package/.agents/generated/claude/skills/gemini-precision/EXAMPLES.md +72 -0
  47. package/.agents/generated/claude/skills/gemini-precision/SKILL.md +0 -100
  48. package/.agents/generated/claude/skills/gemini-precision/TROUBLESHOOTING.md +25 -0
  49. package/.agents/generated/claude/skills/gemini-precision/VALIDATION.json +12 -0
  50. package/.agents/generated/claude/skills/gstack-roles/EXAMPLES.md +23 -0
  51. package/.agents/generated/claude/skills/gstack-roles/SKILL.md +10 -164
  52. package/.agents/generated/claude/skills/gstack-roles/TROUBLESHOOTING.md +13 -0
  53. package/.agents/generated/claude/skills/gstack-roles/VALIDATION.json +12 -0
  54. package/.agents/generated/claude/skills/gstack-roles/references/roles.md +149 -0
  55. package/.agents/generated/claude/skills/ponytail-mindset/EXAMPLES.md +45 -0
  56. package/.agents/generated/claude/skills/ponytail-mindset/SKILL.md +12 -228
  57. package/.agents/generated/claude/skills/ponytail-mindset/TROUBLESHOOTING.md +19 -0
  58. package/.agents/generated/claude/skills/ponytail-mindset/VALIDATION.json +12 -0
  59. package/.agents/generated/claude/skills/ponytail-mindset/references/minimalism.md +186 -0
  60. package/.agents/generated/claude/skills/security/EXAMPLES.md +64 -0
  61. package/.agents/generated/claude/skills/security/SKILL.md +0 -86
  62. package/.agents/generated/claude/skills/security/TROUBLESHOOTING.md +19 -0
  63. package/.agents/generated/claude/skills/security/VALIDATION.json +12 -0
  64. package/.agents/generated/gemini/skills/context-manager/EXAMPLES.md +19 -0
  65. package/.agents/generated/gemini/skills/context-manager/SKILL.md +1 -33
  66. package/.agents/generated/gemini/skills/context-manager/TROUBLESHOOTING.md +7 -0
  67. package/.agents/generated/gemini/skills/context-manager/VALIDATION.json +12 -0
  68. package/.agents/generated/gemini/skills/context-manager/references/context-rules.md +59 -0
  69. package/.agents/generated/gemini/skills/context-os/EXAMPLES.md +21 -0
  70. package/.agents/generated/gemini/skills/context-os/SKILL.md +0 -35
  71. package/.agents/generated/gemini/skills/context-os/TROUBLESHOOTING.md +7 -0
  72. package/.agents/generated/gemini/skills/context-os/VALIDATION.json +12 -0
  73. package/.agents/generated/gemini/skills/context-os/packs.yaml +59 -0
  74. package/.agents/generated/gemini/skills/context-os/references/context-rules.md +68 -0
  75. package/.agents/generated/gemini/skills/context-os/references/pipeline.md +119 -0
  76. package/.agents/generated/gemini/skills/context-os/references/project-graph.md +103 -0
  77. package/.agents/generated/gemini/skills/context-os/rules.yaml +135 -0
  78. package/.agents/generated/gemini/skills/engineering-workflow/EXAMPLES.md +57 -0
  79. package/.agents/generated/gemini/skills/engineering-workflow/SKILL.md +11 -396
  80. package/.agents/generated/gemini/skills/engineering-workflow/TROUBLESHOOTING.md +19 -0
  81. package/.agents/generated/gemini/skills/engineering-workflow/VALIDATION.json +12 -0
  82. package/.agents/generated/gemini/skills/engineering-workflow/references/workflow.md +336 -0
  83. package/.agents/generated/gemini/skills/gemini-precision/EXAMPLES.md +72 -0
  84. package/.agents/generated/gemini/skills/gemini-precision/SKILL.md +0 -104
  85. package/.agents/generated/gemini/skills/gemini-precision/TROUBLESHOOTING.md +25 -0
  86. package/.agents/generated/gemini/skills/gemini-precision/VALIDATION.json +12 -0
  87. package/.agents/generated/gemini/skills/gstack-roles/EXAMPLES.md +23 -0
  88. package/.agents/generated/gemini/skills/gstack-roles/SKILL.md +11 -169
  89. package/.agents/generated/gemini/skills/gstack-roles/TROUBLESHOOTING.md +13 -0
  90. package/.agents/generated/gemini/skills/gstack-roles/VALIDATION.json +12 -0
  91. package/.agents/generated/gemini/skills/gstack-roles/references/roles.md +149 -0
  92. package/.agents/generated/gemini/skills/ponytail-mindset/EXAMPLES.md +45 -0
  93. package/.agents/generated/gemini/skills/ponytail-mindset/SKILL.md +13 -233
  94. package/.agents/generated/gemini/skills/ponytail-mindset/TROUBLESHOOTING.md +19 -0
  95. package/.agents/generated/gemini/skills/ponytail-mindset/VALIDATION.json +12 -0
  96. package/.agents/generated/gemini/skills/ponytail-mindset/references/minimalism.md +186 -0
  97. package/.agents/generated/gemini/skills/security/EXAMPLES.md +64 -0
  98. package/.agents/generated/gemini/skills/security/SKILL.md +2 -92
  99. package/.agents/generated/gemini/skills/security/TROUBLESHOOTING.md +19 -0
  100. package/.agents/generated/gemini/skills/security/VALIDATION.json +12 -0
  101. package/.agents/plugins.js +24 -5
  102. package/.agents/resolver/canonical-resolver.js +43 -7
  103. package/.agents/resolver/resolve-args.js +31 -0
  104. package/.agents/stats.js +8 -11
  105. package/.agents/workspace/workspace-graph.js +16 -6
  106. package/README.md +24 -4
  107. package/bin/lib/ui.js +2 -2
  108. package/package.json +5 -2
@@ -0,0 +1,12 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "type": "object",
4
+ "properties": {
5
+ "rules_followed": {
6
+ "type": "boolean"
7
+ }
8
+ },
9
+ "required": [
10
+ "rules_followed"
11
+ ]
12
+ }
@@ -1221,11 +1221,11 @@ async function search(query) {
1221
1221
  * both core (builtin) and plugins.
1222
1222
  * Adapters call this instead of reading CORE_SKILLS directly.
1223
1223
  */
1224
- function collectAllSkillDirs(targetRoot) {
1224
+ function collectAllSkillDirs(targetRoot, options = {}) {
1225
1225
  const isTargetExplicit = Boolean(targetRoot);
1226
1226
  const root = targetRoot || process.cwd();
1227
- const agentsDir = path.join(root, '.agents');
1228
- const localCore = path.join(agentsDir, 'core', 'skills');
1227
+ const agentsDir = options.agentsDir || path.join(root, '.agents');
1228
+ const localCore = options.coreSkillsDir || path.join(agentsDir, 'core', 'skills');
1229
1229
  const localPlugins = path.join(agentsDir, 'plugins');
1230
1230
 
1231
1231
  const coreDir = fs.existsSync(localCore) ? localCore : (isTargetExplicit ? null : CORE_SKILLS);
@@ -1252,13 +1252,32 @@ function collectAllSkillDirs(targetRoot) {
1252
1252
  const subDir = path.join(nestedSkills, sub);
1253
1253
  if (fs.statSync(subDir).isDirectory()) dirs.push(subDir);
1254
1254
  }
1255
- } else if (fs.existsSync(path.join(d, 'SKILL.md')) || fs.existsSync(path.join(d, 'skill.yaml'))) {
1255
+ } else if (fs.existsSync(path.join(d, 'SKILL.md')) || fs.existsSync(path.join(d, 'skill.yaml')) || fs.existsSync(path.join(d, 'skill.v2.yaml'))) {
1256
1256
  dirs.push(d);
1257
1257
  }
1258
1258
  }
1259
1259
  }
1260
1260
 
1261
- return dirs;
1261
+ // Higher ownership tiers replace an upstream skill with the same ID. Preserve
1262
+ // upstream duplicates so the compiler can still diagnose conflicting installs.
1263
+ for (const tier of ['vendor', 'project']) {
1264
+ const tierRoot = path.join(agentsDir, tier, 'skills');
1265
+ if (!fs.existsSync(tierRoot)) continue;
1266
+ for (const name of fs.readdirSync(tierRoot).sort()) {
1267
+ const dir = path.join(tierRoot, name);
1268
+ const { resolvedPath } = require('./filesystem/index.js').resolveManagedPath(root, path.relative(root, dir));
1269
+ if (!fs.statSync(resolvedPath).isDirectory()) continue;
1270
+ if (!fs.existsSync(path.join(dir, 'SKILL.md')) && !fs.existsSync(path.join(dir, 'skill.yaml')) && !fs.existsSync(path.join(dir, 'skill.v2.yaml'))) continue;
1271
+ for (let i = dirs.length - 1; i >= 0; i--) {
1272
+ if (path.basename(dirs[i]) === name) dirs.splice(i, 1);
1273
+ }
1274
+ dirs.push(dir);
1275
+ }
1276
+ }
1277
+ if (isTargetExplicit) {
1278
+ for (const dir of dirs) require('./filesystem/index.js').resolveManagedPath(root, path.relative(root, dir));
1279
+ }
1280
+ return dirs.sort();
1262
1281
  }
1263
1282
 
1264
1283
  module.exports = {
@@ -650,6 +650,12 @@ class CanonicalResolver {
650
650
  }
651
651
  }
652
652
 
653
+ if (resolvedId === 'security' && ['keyword', 'file_glob', 'explicit', 'safety_required'].includes(kind)) {
654
+ if (profileExcluded.delete(resolvedId)) {
655
+ warnings.push({ code: 'CTX_REQUIRED_SECURITY_PROFILE_CONFLICT', message: 'Task safety guidance overrides the profile exclusion of security.' });
656
+ }
657
+ kind = 'safety_required';
658
+ }
653
659
  if (profileExcluded.has(resolvedId)) return;
654
660
  if (!evidenceBySkill.has(resolvedId)) evidenceBySkill.set(resolvedId, []);
655
661
  evidenceBySkill.get(resolvedId).push({ kind, weight, reason });
@@ -836,6 +842,10 @@ class CanonicalResolver {
836
842
  }
837
843
  }
838
844
 
845
+ if (risk.value === 'high' || risk.value === 'destructive') {
846
+ addEvidence('security', 'safety_required', 100, `Required safety guidance for ${risk.value} risk task`);
847
+ }
848
+
839
849
  // 3. Compute Candidate Scores & Intent Precedence
840
850
  const candidates = [];
841
851
  for (const [id, evList] of evidenceBySkill.entries()) {
@@ -850,7 +860,7 @@ class CanonicalResolver {
850
860
  if ((e.kind === 'keyword' || e.kind === 'alias') && e.weight >= 20) {
851
861
  hasDirectTaskIntent = true;
852
862
  }
853
- if (e.kind === 'explicit' || e.kind === 'profile_required') {
863
+ if (e.kind === 'explicit' || e.kind === 'profile_required' || e.kind === 'safety_required') {
854
864
  isMandatory = true;
855
865
  hasDirectTaskIntent = true;
856
866
  }
@@ -929,7 +939,7 @@ class CanonicalResolver {
929
939
  const closureMap = new Map();
930
940
  for (const item of initialSelection) {
931
941
  const rawEst = skillsDict[item.id]?.estimatedTokens || 1000;
932
- const estTokens = Math.min(rawEst, BUDGET_TIERS.SKILL_BODY);
942
+ const estTokens = rawEst;
933
943
  closureMap.set(item.id, {
934
944
  id: item.id,
935
945
  displayName: skillsDict[item.id]?.displayName || item.id,
@@ -953,7 +963,7 @@ class CanonicalResolver {
953
963
  }
954
964
  } else {
955
965
  const rawEst = skillsDict[reqId]?.estimatedTokens || 1000;
956
- const estTokens = Math.min(rawEst, BUDGET_TIERS.SKILL_BODY);
966
+ const estTokens = rawEst;
957
967
  closureMap.set(reqId, {
958
968
  id: reqId,
959
969
  displayName: skillsDict[reqId]?.displayName || reqId,
@@ -1000,7 +1010,12 @@ class CanonicalResolver {
1000
1010
  }
1001
1011
 
1002
1012
  // 7. Token Budget Planner & Capability Clustering
1003
- const BASE_SKILLS = ['ponytail-mindset', 'engineering-workflow'];
1013
+ const plannedPhase = resolvePhaseAndRole(explicitPhase, task, []).phase.value;
1014
+ const BASE_SKILLS = ['engineering-workflow'];
1015
+ if (risk.value !== 'routine' && plannedPhase === 'Build') BASE_SKILLS.push('ponytail-mindset');
1016
+ for (let i = BASE_SKILLS.length - 1; i >= 0; i--) {
1017
+ if (!skillsDict[BASE_SKILLS[i]]) BASE_SKILLS.splice(i, 1);
1018
+ }
1004
1019
  let baseTokens = 0;
1005
1020
 
1006
1021
  for (const baseId of BASE_SKILLS) {
@@ -1009,7 +1024,8 @@ class CanonicalResolver {
1009
1024
  }
1010
1025
  }
1011
1026
 
1012
- let allocatedDynamicTokens = 0;
1027
+ // Foundation bodies occupy the same budget as task-specific skills.
1028
+ let allocatedDynamicTokens = baseTokens;
1013
1029
  const admitted = new Map(); // id -> candidate entry
1014
1030
 
1015
1031
  // Separate mandatory vs optional candidates
@@ -1017,7 +1033,7 @@ class CanonicalResolver {
1017
1033
  const optionalCandidates = [];
1018
1034
 
1019
1035
  for (const cand of closureMap.values()) {
1020
- const isMandatory = cand.reasons.some(r => r.kind === 'explicit' || r.kind === 'profile_required');
1036
+ const isMandatory = cand.reasons.some(r => r.kind === 'explicit' || r.kind === 'profile_required' || r.kind === 'safety_required');
1021
1037
  if (isMandatory) {
1022
1038
  mandatoryCandidates.push(cand);
1023
1039
  } else {
@@ -1131,6 +1147,25 @@ class CanonicalResolver {
1131
1147
  }
1132
1148
  }
1133
1149
 
1150
+ const totalSelectedTokens = finalSelected.reduce((sum, skill) => sum + skill.estimatedTokens, 0);
1151
+ for (const skill of finalSelected) {
1152
+ if (!skillsDict[skill.id]) {
1153
+ warnings.push({ code: 'CTX_SELECTED_SKILL_UNAVAILABLE', message: `Selected skill "${skill.id}" has no installed manifest. Install it before assembling runtime context.` });
1154
+ }
1155
+ }
1156
+ if (finalSelected.length > maxSkillsLimit) {
1157
+ warnings.push({ code: 'CTX_RESOLVER_SKILL_LIMIT_EXCEEDED', message: `Required skills and dependencies occupy ${finalSelected.length} slots; soft maxSkills limit is ${maxSkillsLimit}.` });
1158
+ }
1159
+ if (finalSelected.length > maxSkillsLimit) {
1160
+ warnings.push({ code: 'CTX_RESOLVER_SKILL_LIMIT_EXCEEDED', message: `Required skills and dependencies occupy ${finalSelected.length} slots; soft maxSkills limit is ${maxSkillsLimit}.` });
1161
+ }
1162
+ if (totalSelectedTokens > budgetTokens && !warnings.some(w => w.code === 'CTX_RESOLVER_BUDGET_EXCEEDED')) {
1163
+ warnings.push({
1164
+ code: 'CTX_RESOLVER_BUDGET_EXCEEDED',
1165
+ message: `Soft context budget (${budgetTokens} tokens) exceeded by required/foundation skill bodies (total: ${totalSelectedTokens} tokens). Client instructions and chat history are additional.`,
1166
+ });
1167
+ }
1168
+
1134
1169
  // 9. Domain, Phase & Role
1135
1170
  let domain = request.domain || '';
1136
1171
  if (!domain) {
@@ -1208,7 +1243,7 @@ class CanonicalResolver {
1208
1243
  excluded,
1209
1244
  conflicts,
1210
1245
  warnings,
1211
- totalEstimatedTokens: baseTokens + allocatedDynamicTokens,
1246
+ totalEstimatedTokens: totalSelectedTokens,
1212
1247
  // Legacy compatibility properties
1213
1248
  skills: allSelectedIds,
1214
1249
  };
@@ -1229,6 +1264,7 @@ class CanonicalResolver {
1229
1264
  const lines = [
1230
1265
  `[DOMAIN: ${res.domain}] [PHASE: ${phaseStr}] [ROLE: ${res.role}] [MODE: ${modeStr}] [LENSES: ${lensesStr}] [RISK: ${riskStr}]`,
1231
1266
  `Skills loaded: ${skillsList}`,
1267
+ 'Selection declaration only; skill bodies are read by the consuming client or prompt assembler.',
1232
1268
  ];
1233
1269
  if (res.workflow && res.workflow.steps && res.workflow.steps.length > 0) {
1234
1270
  lines.push(`Workflow (${res.workflow.name}): ${res.workflow.steps[0]}`);
@@ -0,0 +1,31 @@
1
+ 'use strict';
2
+
3
+ function parseResolveArgs(args) {
4
+ const result = { task: '', files: [], explicitPhase: undefined, contextBudgetTokens: undefined, json: false, explain: false };
5
+ const task = [];
6
+ for (let i = 0; i < args.length; i++) {
7
+ const arg = args[i];
8
+ if (arg === '--json') result.json = true;
9
+ else if (arg === '--explain') result.explain = true;
10
+ else if (['--files', '--phase', '--budget'].includes(arg)) {
11
+ const value = args[++i];
12
+ if (!value || value.startsWith('--')) throw new Error(`Missing value for ${arg}`);
13
+ if (arg === '--files') result.files = value.split(',').map(file => file.trim()).filter(Boolean);
14
+ else if (arg === '--phase') result.explicitPhase = value;
15
+ else {
16
+ if (!/^[1-9]\d*$/.test(value) || !Number.isSafeInteger(Number(value))) {
17
+ throw new Error('--budget must be a positive integer');
18
+ }
19
+ result.contextBudgetTokens = Number(value);
20
+ }
21
+ } else if (arg === '--') {
22
+ task.push(...args.slice(i + 1));
23
+ break;
24
+ } else if (arg.startsWith('-')) throw new Error(`Unknown resolve option: ${arg}`);
25
+ else task.push(arg);
26
+ }
27
+ result.task = task.join(' ');
28
+ return result;
29
+ }
30
+
31
+ module.exports = { parseResolveArgs };
package/.agents/stats.js CHANGED
@@ -6,7 +6,7 @@
6
6
  * 1. Full context payload (all skills + AGENTS.md)
7
7
  * 2. Profiled context payload (after applying active profile exclusions)
8
8
  * 3. Dynamically resolved context (lean on-demand skill set for typical tasks)
9
- * 4. Concrete token savings percentage and cost reductions
9
+ * 4. Character-based payload estimates, not provider billing or quality results
10
10
  */
11
11
 
12
12
  'use strict';
@@ -22,7 +22,6 @@ function estimateTokens(text) {
22
22
 
23
23
  function calculateContextStats(projectDir = process.cwd()) {
24
24
  const agentsDir = path.join(projectDir, '.agents');
25
- const skillsDir = path.join(agentsDir, 'core', 'skills');
26
25
  const agentsMdPath = path.join(agentsDir, 'AGENTS.md');
27
26
 
28
27
  let agentsMdChars = 0;
@@ -31,15 +30,13 @@ function calculateContextStats(projectDir = process.cwd()) {
31
30
  }
32
31
 
33
32
  const skillCharMap = new Map();
34
- if (fs.existsSync(skillsDir)) {
35
- const entries = fs.readdirSync(skillsDir, { withFileTypes: true });
36
- for (const entry of entries) {
37
- if (!entry.isDirectory()) continue;
38
- const skillMd = path.join(skillsDir, entry.name, 'SKILL.md');
33
+ const { collectSkillDirectories } = require('./adapters/shared.js');
34
+ const allDirs = collectSkillDirectories({ exclude_skills: [] }, projectDir);
35
+ for (const directory of allDirs) {
36
+ const skillMd = path.join(directory, 'SKILL.md');
39
37
  if (fs.existsSync(skillMd)) {
40
- skillCharMap.set(entry.name, fs.readFileSync(skillMd, 'utf8').length);
38
+ skillCharMap.set(path.basename(directory), fs.readFileSync(skillMd, 'utf8').length);
41
39
  }
42
- }
43
40
  }
44
41
 
45
42
  const totalSkillCount = skillCharMap.size;
@@ -50,9 +47,9 @@ function calculateContextStats(projectDir = process.cwd()) {
50
47
 
51
48
  // Active profile
52
49
  const activeProfile = profiles.getActiveProfile(projectDir);
53
- const profileName = activeProfile ? (activeProfile.name || activeProfile.profile) : 'startup (recommended)';
50
+ const profileName = activeProfile ? (activeProfile.name || activeProfile.profile) : 'none';
54
51
  const excludedSkills = new Set(
55
- activeProfile ? activeProfile.exclude_skills || [] : (profiles.getProfile('startup')?.exclude_skills || [])
52
+ activeProfile ? activeProfile.exclude_skills || [] : []
56
53
  );
57
54
 
58
55
  let profileChars = agentsMdChars;
@@ -23,6 +23,8 @@ const DEFAULT_IGNORED_DIRS = new Set([
23
23
  '.git',
24
24
  'node_modules',
25
25
  '.contextos-worktrees',
26
+ '.swarm-worktrees',
27
+ '.external-skills',
26
28
  '.agents',
27
29
  'dist',
28
30
  'build',
@@ -121,6 +123,7 @@ class WorkspaceGraphBuilder {
121
123
  this.maxDepth = options.maxDepth || 8;
122
124
  this.maxPackages = options.maxPackages || 500;
123
125
  this.ignoredDirs = new Set([...DEFAULT_IGNORED_DIRS, ...(options.ignoredDirs || [])]);
126
+ this.includeNestedRepositories = options.includeNestedRepositories === true;
124
127
  }
125
128
 
126
129
  /**
@@ -223,7 +226,11 @@ class WorkspaceGraphBuilder {
223
226
  return;
224
227
  }
225
228
 
226
- for (const entry of entries) {
229
+ for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
230
+ if (packages.length >= this.maxPackages) {
231
+ hitLimit = true;
232
+ break;
233
+ }
227
234
  if (!entry.isDirectory() && !entry.isSymbolicLink()) continue;
228
235
  if (this.ignoredDirs.has(entry.name)) continue;
229
236
 
@@ -236,10 +243,8 @@ class WorkspaceGraphBuilder {
236
243
  }
237
244
 
238
245
  // Symlink escape guard: must remain within root realpath
239
- if (
240
- !realEntryPath.startsWith(visitedDirs.values().next().value) &&
241
- !realEntryPath.startsWith(realRoot)
242
- ) {
246
+ const realRelative = path.relative(realRoot, realEntryPath);
247
+ if (realRelative === '..' || realRelative.startsWith(`..${path.sep}`) || path.isAbsolute(realRelative)) {
243
248
  continue;
244
249
  }
245
250
 
@@ -253,7 +258,12 @@ class WorkspaceGraphBuilder {
253
258
  workspaceGlobs.length === 0 ||
254
259
  workspaceGlobs.some((g) => g.test(relPath));
255
260
 
256
- const pkg = this._inspectDirectoryForPackage(fullPath, relPath, realRoot);
261
+ if (fs.existsSync(path.join(fullPath, '.git')) &&
262
+ !this.includeNestedRepositories && !(workspaceGlobs.length > 0 && isDeclared)) {
263
+ continue;
264
+ }
265
+
266
+ const pkg = isDeclared ? this._inspectDirectoryForPackage(fullPath, relPath, realRoot) : null;
257
267
  if (pkg) {
258
268
  packages.push(pkg);
259
269
  packageIdSet.add(pkg.id);
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <p align="center">
2
2
  <a href="https://github.com/kok-o/contextos-agents">
3
- <img src="./Frame%202.png" alt="ContextOS Logo" width="88" height="88" />
3
+ <img src="./assets/logo.png" alt="ContextOS Logo" width="88" height="88" />
4
4
  </a>
5
5
  </p>
6
6
 
@@ -30,7 +30,7 @@
30
30
 
31
31
  ---
32
32
 
33
- ContextOS is a deterministic context and policy compiler for AI coding agents. It transforms your team's version-controlled engineering rules into focused, verifiable context for Gemini, Claude Code, Cursor, GitHub Copilot, Aider, and Zed - and detects configuration drift in CI.
33
+ ContextOS is a deterministic context and policy compiler for AI coding agents. It exports version-controlled engineering rules and detects configuration drift in CI. See the [adapter compatibility matrix](docs/ADAPTER_COMPATIBILITY.md) for native paths, instruction indexes and manual templates; client loader verification is separate from export tests.
34
34
 
35
35
  ## Installation
36
36
 
@@ -40,7 +40,13 @@ You do not need to clone anything manually. Just open your terminal in the root
40
40
  npx contextos-agents init
41
41
  ```
42
42
 
43
- By default, ContextOS sets up a focused **Lean Core** (7 essential skills: `engineering-workflow`, `ponytail-mindset`, `gemini-precision`, `security`, `context-os`, `context-manager`, and `gstack-roles`). This ensures your AI agent context remains lightweight and focused, preventing context degradation.
43
+ By default, ContextOS installs seven core skills: `engineering-workflow`, `ponytail-mindset`, `gemini-precision`, `security`, `context-os`, `context-manager`, and `gstack-roles`, then exports Gemini workspace skills. Supporting examples and references remain separate files. The actual context loaded and session cost depend on your client and task; ContextOS does not control an external client's chat history.
44
+
45
+ Codex also discovers the shared `.agents/skills` directory. The default Cursor
46
+ export always applies only the compact project bootstrap; skill bodies load by
47
+ file patterns or agent request. Resolver token budgets are soft: mandatory safety
48
+ guidance survives with an overflow warning. The experimental MCP prompt assembler
49
+ keeps selected bodies whole and can reject an explicit hard character limit.
44
50
 
45
51
  Want more skills right away? Install pre-packaged presets or the entire catalog:
46
52
 
@@ -53,6 +59,18 @@ npx contextos-agents init --all # Install all 36 catalog skills at
53
59
 
54
60
  ### Options
55
61
 
62
+ Try the [small local demo](examples/quickstart/README.md) to install the current
63
+ candidate in a new folder, select a TypeScript skill, and add a team rule without
64
+ calling a model API. The [five-minute guide](docs/product/onboarding.md) explains
65
+ the same workflow for an existing project.
66
+
67
+ For the current R2 candidates, see the [release preparation status](docs/R2_RELEASE_PREPARATION.md)
68
+ and [upgrade/checkpoint rollback](docs/COMPACT_CONTEXT_MIGRATION.md). The
69
+ [release manifest](docs/evidence/release-2.3.json) records the verified source,
70
+ cross-platform CI and candidate archive identities. The client pilot and
71
+ publication decision remain pending. Internal plans, local API probes
72
+ and raw logs are excluded from the public release surface.
73
+
56
74
  ```bash
57
75
  npx contextos-agents --help # Show all options
58
76
  npx contextos-agents --version # Show version
@@ -188,12 +206,14 @@ contextos hook uninstall
188
206
 
189
207
  ### CI Quality Gate (`contextos gate`)
190
208
 
191
- Run the complete 8-point production quality gate locally:
209
+ Check that generated adapter files match source skills and the active profile:
192
210
 
193
211
  ```bash
194
212
  contextos gate
195
213
  ```
196
214
 
215
+ This is a configuration drift gate. Run your application's tests, typecheck and security checks separately. `resolve` recommends skills for a task; ordinary exports use all installed skills allowed by the profile. Resolver budgets are soft estimates of selected skill bodies and exclude client instructions, chat history and tool output.
216
+
197
217
  ### CI Quality Gate Action (contextos-gate)
198
218
 
199
219
  Guard your repository against skill drift, missing outputs, and rule regressions using the official GitHub Composite Action:
package/bin/lib/ui.js CHANGED
@@ -116,8 +116,8 @@ function renderSuccessCard(options = {}) {
116
116
  console.log(renderCardLine(c.bold(c.green('✓ Project ready for AI coding agents!')), innerWidth));
117
117
  console.log(renderCardLine('', innerWidth));
118
118
  console.log(renderCardLine(c.bold('Next steps:'), innerWidth));
119
- console.log(renderCardLine(`1. Open project in your AI assistant (${c.cyan('Gemini')}, ${c.cyan('Cursor')}, ${c.cyan('Copilot')})`, innerWidth));
120
- console.log(renderCardLine(` Rules are auto-loaded from ${c.cyan('.agents/AGENTS.md')}`, innerWidth));
119
+ console.log(renderCardLine('1. Default init exports Gemini workspace skills.', innerWidth));
120
+ console.log(renderCardLine(` Other clients: ${c.cyan('contextos export <agent>')}`, innerWidth));
121
121
  console.log(renderCardLine('', innerWidth));
122
122
  console.log(renderCardLine('2. Explore and install domain skills:', innerWidth));
123
123
  console.log(renderCardLine(` ${c.cyan('contextos skill list --available')}`, innerWidth));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "contextos-agents",
3
- "version": "2.2.0",
3
+ "version": "2.3.0",
4
4
  "description": "Deterministic context and policy compiler for supported AI coding agents.",
5
5
  "bin": {
6
6
  "contextos": "./bin/index.js",
@@ -47,10 +47,13 @@
47
47
  "validate:catalog": "node .agents/ctx.js validate --catalog",
48
48
  "lint:md": "markdownlint README.md CONTRIBUTING.md GUIDE.md \".agents/core/skills/**/*.md\" --ignore \".agents/generated/**\" --config .markdownlint.json",
49
49
  "check:secrets": "node scripts/check-secrets.js --all",
50
+ "check:consumer": "node scripts/check-release-install.cjs",
51
+ "check:migration": "node scripts/check-release-migration.cjs",
52
+ "check:release-surface": "node scripts/check-release-surface.cjs",
50
53
  "setup:hooks": "node scripts/install-hooks.js",
51
54
  "watch": "node .agents/watch.js",
52
55
  "test:skills": "node scripts/verify-skill-examples.js",
53
- "test": "node --test --test-concurrency=1 tests/install.test.js tests/lockfile.test.js tests/safe-writer.test.js tests/adapter-safety.test.js tests/update.test.js tests/uninstall.test.js tests/plugin-security.test.js tests/export.test.js tests/skills.test.js tests/validate.test.js tests/plugins.test.js tests/benchmark.test.js tests/benchmark-api.test.js tests/profile.test.js tests/resolver.test.js tests/cli-registry.test.js tests/profile-enforcement.test.js tests/doctor-hardening.test.js tests/manifest-compiler.test.js tests/canonical-resolver.test.js tests/workspace-graph.test.js tests/profiles-v2.test.js tests/safe-path.test.js tests/project-lock.test.js tests/journaled-transaction.test.js tests/pure-adapters.test.js tests/prompt-skill-system.test.js tests/runtime-state-machine.test.js tests/verification-reviewer-pipeline.test.js tests/durable-concurrency-locks.test.js tests/transactional-git.test.js tests/sandbox-execution.test.js tests/plugin-supply-chain.test.js tests/platform-hardening.test.js tests/customization-dx.test.js tests/claims-governance.test.js tests/benchmark-v2.test.js tests/init-engine.test.js tests/mutation-paths.test.js tests/tarball-smoke.test.js tests/catalog-export-integration.test.js tests/consumer-gate.test.js tests/adapter-compatibility.test.js tests/consumer-init.test.js tests/skill-examples.test.js tests/scan.test.js tests/hooks.test.js tests/recovery-cli.test.js tests/doctor-v2.test.js tests/resolver-parity.test.js tests/watch-coalescing.test.js",
56
+ "test": "node --test --test-concurrency=1 tests/install.test.js tests/lockfile.test.js tests/safe-writer.test.js tests/adapter-safety.test.js tests/update.test.js tests/uninstall.test.js tests/plugin-security.test.js tests/export.test.js tests/skills.test.js tests/validate.test.js tests/plugins.test.js tests/benchmark.test.js tests/benchmark-api.test.js tests/profile.test.js tests/resolver.test.js tests/cli-registry.test.js tests/profile-enforcement.test.js tests/doctor-hardening.test.js tests/manifest-compiler.test.js tests/canonical-resolver.test.js tests/workspace-graph.test.js tests/profiles-v2.test.js tests/safe-path.test.js tests/project-lock.test.js tests/journaled-transaction.test.js tests/pure-adapters.test.js tests/prompt-skill-system.test.js tests/runtime-state-machine.test.js tests/verification-reviewer-pipeline.test.js tests/durable-concurrency-locks.test.js tests/transactional-git.test.js tests/sandbox-execution.test.js tests/plugin-supply-chain.test.js tests/platform-hardening.test.js tests/customization-dx.test.js tests/claims-governance.test.js tests/benchmark-v2.test.js tests/init-engine.test.js tests/mutation-paths.test.js tests/tarball-smoke.test.js tests/catalog-export-integration.test.js tests/consumer-gate.test.js tests/adapter-compatibility.test.js tests/consumer-init.test.js tests/skill-examples.test.js tests/scan.test.js tests/hooks.test.js tests/recovery-cli.test.js tests/doctor-v2.test.js tests/resolver-parity.test.js tests/watch-coalescing.test.js tests/consumer-stabilization.test.js tests/focused-context.test.js tests/spend-guard.test.js tests/maintenance-benchmark.test.js tests/luna-agent-benchmark.test.js tests/release-surface.test.js",
54
57
  "prepublishOnly": "npm run validate \u0026\u0026 npm run build"
55
58
  },
56
59
  "keywords": [