contextos-agents 2.2.0 → 2.3.1

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 (109) 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 +48 -18
  107. package/bin/index.js +1 -1
  108. package/bin/lib/ui.js +2 -2
  109. package/package.json +89 -86
@@ -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,20 @@ 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 package in a new folder, select a TypeScript skill, and add a team rule without
63
+ calling a model API. The [five-minute guide](docs/product/onboarding.md) explains
64
+ the same workflow for an existing project.
65
+
66
+ Core 2.3.1 / MCP 0.4.1 are being prepared as a maintenance release; they are not yet published.
67
+ See the [candidate checklist](docs/PATCH_RELEASE_2.3.1.md) and
68
+ [live client check](docs/LIVE_CLIENT_CHECK_RU.md).
69
+ Core 2.3.0 and MCP 0.4.0 remain the published pair. See the [release status](docs/R2_RELEASE_PREPARATION.md)
70
+ and [upgrade/checkpoint rollback](docs/COMPACT_CONTEXT_MIGRATION.md). The
71
+ [release manifest](docs/evidence/release-2.3.json) records the released source,
72
+ cross-platform CI and archive identities. Automatic client routing and the external
73
+ pilot remain unverified. Internal plans, local API probes and raw logs are excluded
74
+ from the public release surface.
75
+
56
76
  ```bash
57
77
  npx contextos-agents --help # Show all options
58
78
  npx contextos-agents --version # Show version
@@ -70,13 +90,13 @@ npx contextos-agents --skip-compile # Skip auto-compilation step
70
90
 
71
91
  Modern development teams face fragmented AI tooling: engineers use Cursor, Claude Code, GitHub Copilot, Gemini, Zed, and Aider. Each tool requires its own proprietary rules format, leading to configuration drift, contradictory standards, and unvetted AI slop (`// TODO`, leaked secrets).
72
92
 
73
- Artificially truncating skills to save tokens degrades model reasoning and induces hallucinations. Instead, ContextOS ensures that agents receive complete, high-fidelity engineering context from a single version-controlled source.
93
+ ContextOS preserves selected skill bodies and reports budget overflow instead of silently truncating required instructions. Whether a client loads and follows those rules requires separate verification. The current [calibration](docs/BENCHMARK_RESULTS.md) found no quality advantage over vanilla on its test corpus.
74
94
 
75
95
  **ContextOS is not another coding agent.** It is the deterministic context compiler and policy engine for the agents your team already uses.
76
96
 
77
97
  ### The Three Pillars
78
98
 
79
- 1. **Portable (Multi-Agent):** Define your engineering skills once in standard Markdown. ContextOS compiles native configurations for all supported agents (Gemini, Claude Code, Cursor, Copilot, Aider, and Zed).
99
+ 1. **Portable (Multi-Agent):** Define your engineering skills once in standard Markdown. ContextOS generates agent-specific exports (Gemini, Claude Code, Cursor, Copilot, Aider, and Zed); native loading and manual templates are distinguished in the compatibility matrix.
80
100
  2. **High-Fidelity & Focused:** The resolver maps domain skills to relevant tasks without lossy truncation, delivering rich, complete context to the model.
81
101
  3. **Verifiable in CI:** Lockfile v2 provenance, dual-hash verification, and CI quality gates detect configuration drift and enforce quality guardrails before merge.
82
102
 
@@ -93,15 +113,16 @@ contextos resolve "review authentication changes" \
93
113
  --explain
94
114
  ```
95
115
 
96
- Selected:
97
- security explicit task match
98
- engineering-workflow required dependency
116
+ Example excerpt from the repository configuration (selection and scores depend on installed skills, files and profile):
99
117
 
100
- Excluded:
101
- context-manager domain relevance filter
118
+ ```text
119
+ Selected Skills:
120
+ ✓ engineering-workflow score: 100 tokens: ~418 (foundation: Core skill)
121
+ ✓ security score: 185 tokens: ~2237 (safety_required: Touched file "src/auth/session.ts" matches glob "**/*auth*" (+25); safety_required: Touched file "src/auth/session.ts" matches pattern (+60); safety_required: Required safety guidance for high risk task)
122
+ ✓ typescript score: 60 tokens: ~1000 (file_glob: Touched file "src/auth/session.ts" matches pattern (+60))
123
+ ```
102
124
 
103
- Risk: high
104
- Context status: complete and verified
125
+ Selection does not imply installation or activation. If TypeScript is not installed, the CLI also reports `CTX_SELECTED_SKILL_UNAVAILABLE`; install it with `contextos skill add typescript` before runtime assembly.
105
126
 
106
127
  ## Dynamic Skill Resolution & Unified CLI (`contextos` / `ctx.js`)
107
128
 
@@ -114,8 +135,9 @@ ContextOS provides a unified CLI (`contextos` or `npx contextos-agents`) and loc
114
135
  contextos resolve "Build an accessible modal component with React and Tailwind"
115
136
 
116
137
  # Output:
117
- # [DOMAIN: Frontend] [PHASE: Build] [ROLE: Senior Developer]
118
- # Skills loaded: ponytail-mindset, engineering-workflow, gemini-precision
138
+ # [DOMAIN: Frontend] [PHASE: Build] [ROLE: Senior Developer] [MODE: CHANGE] [LENSES: accessibility] [RISK: standard]
139
+ # Skills loaded: ponytail-mindset, engineering-workflow, react, web-accessibility, ui-ux-pro
140
+ # Selection declaration only; skill bodies are read by the consuming client or prompt assembler.
119
141
 
120
142
  # Resolve with full evidence scoring explanation:
121
143
  contextos resolve "security review" --files apps/web/app/login/page.tsx --explain
@@ -188,12 +210,14 @@ contextos hook uninstall
188
210
 
189
211
  ### CI Quality Gate (`contextos gate`)
190
212
 
191
- Run the complete 8-point production quality gate locally:
213
+ Check that generated adapter files match source skills and the active profile:
192
214
 
193
215
  ```bash
194
216
  contextos gate
195
217
  ```
196
218
 
219
+ 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.
220
+
197
221
  ### CI Quality Gate Action (contextos-gate)
198
222
 
199
223
  Guard your repository against skill drift, missing outputs, and rule regressions using the official GitHub Composite Action:
@@ -207,13 +231,17 @@ jobs:
207
231
  runs-on: ubuntu-latest
208
232
  steps:
209
233
  - uses: actions/checkout@v4
210
- - uses: kok-o/contextos-agents/.github/actions/contextos-gate@v2.2.0
234
+ - uses: kok-o/contextos-agents/.github/actions/contextos-gate@v2.3.1
211
235
  with:
212
- version: '2.2.0' # Pinned version of contextos-agents runner
236
+ version: '2.3.1' # Pinned version of contextos-agents runner
213
237
  adapters: 'all' # Adapters to verify (or specific: 'cursor', 'claude')
214
238
  working-directory: '.' # Project root directory
215
239
  ```
216
240
 
241
+ The example targets the forthcoming v2.3.1 release; use it after that tag and package are published.
242
+ Until then, keep both pins at v2.3.0 / 2.3.0. The existing `v2.3.0` action tag defaults to CLI 2.2.0,
243
+ so retain the explicit `version`. Updating the action source does not change an existing tag.
244
+
217
245
  The action executes the verified ContextOS quality gate in-process from the pinned package version, verifying generated AI adapter configs against source skills without executing untrusted scripts from pull requests, and without requiring a Node.js project or running `npm test`.
218
246
 
219
247
  ## Optional MCP integration (Beta)
@@ -223,10 +251,12 @@ The MCP server is a separate beta package. It is not part of the stable `context
223
251
  Install it separately if you want to try the beta integration:
224
252
 
225
253
  ```bash
226
- npm install --save-dev @contextos/mcp
254
+ npm install --save-dev contextos-mcp
227
255
  npx contextos-mcp --dir .
228
256
  ```
229
257
 
258
+ The former `@contextos/mcp` 0.3.x package is historical; use `contextos-mcp` for current releases.
259
+
230
260
  The MCP server is read-only by default. Runtime execution remains experimental and is outside the stable core scope.
231
261
 
232
262
  ## Security - Third-Party Skills
package/bin/index.js CHANGED
@@ -100,7 +100,7 @@ Options:
100
100
  --project <path> Specify target project root directory (default: current directory)
101
101
  --target <adapters> Target adapter(s) to verify or export (default: all)
102
102
  --github-annotations Emit GitHub Actions workflow commands and step summary
103
- --with-mcp, --mcp [DEPRECATED] Use the separate @contextos/mcp package instead
103
+ --with-mcp, --mcp [DEPRECATED] Use the separate contextos-mcp package instead
104
104
  --skip-compile Skip running ctx.js export after installation
105
105
  --add-skill <ref> Install a community plugin skill after setup
106
106
 
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));