devlyn-cli 4.1.0 → 4.2.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 (72) hide show
  1. package/AGENTS.md +10 -94
  2. package/CLAUDE.md +7 -160
  3. package/LICENSE +21 -0
  4. package/README.md +65 -110
  5. package/bin/devlyn.js +95 -116
  6. package/bin/instruction-templates.json +43 -2
  7. package/bin/instructions.js +29 -8
  8. package/config/skills/_shared/adapters/claude.md +8 -85
  9. package/config/skills/_shared/adapters/codex.md +14 -34
  10. package/config/skills/_shared/adapters/omp.md +1 -11
  11. package/config/skills/_shared/codex-monitored.sh +4 -54
  12. package/config/skills/_shared/engine-doctor.sh +18 -58
  13. package/config/skills/_shared/engine-preflight.md +15 -47
  14. package/config/skills/_shared/expected-contract.py +242 -0
  15. package/config/skills/_shared/expected.schema.json +10 -95
  16. package/config/skills/_shared/invocation-receipt.py +26 -757
  17. package/config/skills/_shared/platform-support.py +37 -28
  18. package/config/skills/_shared/role-config.py +100 -421
  19. package/config/skills/_shared/runtime-principles.md +17 -93
  20. package/config/skills/_shared/task-complete.py +490 -285
  21. package/config/skills/_shared/task-completion.md +235 -0
  22. package/config/skills/devlyn-engines/SKILL.md +9 -11
  23. package/config/skills/devlyn-ideate/SKILL.md +57 -107
  24. package/config/skills/devlyn-ideate/references/elicitation.md +18 -99
  25. package/config/skills/devlyn-ideate/references/loop.md +110 -0
  26. package/config/skills/devlyn-ideate/references/package-format.md +128 -0
  27. package/config/skills/devlyn-ideate/scripts/acceptance.py +795 -0
  28. package/config/skills/devlyn-ideate/scripts/queue.py +1780 -0
  29. package/package.json +2 -3
  30. package/config/commit-conventions.md +0 -28
  31. package/config/skills/_shared/adapters/README.md +0 -74
  32. package/config/skills/_shared/adapters/grok.md +0 -100
  33. package/config/skills/_shared/archive_run.py +0 -969
  34. package/config/skills/_shared/codex-config.md +0 -81
  35. package/config/skills/_shared/collect-codex-findings.py +0 -505
  36. package/config/skills/_shared/finish-gate.py +0 -521
  37. package/config/skills/_shared/grok-anchor-guard.py +0 -78
  38. package/config/skills/_shared/judge-output-parser.py +0 -200
  39. package/config/skills/_shared/judge-role-evidence.py +0 -320
  40. package/config/skills/_shared/phase-prompt-render.py +0 -183
  41. package/config/skills/_shared/process-evidence.py +0 -926
  42. package/config/skills/_shared/resolve-bootstrap.py +0 -1410
  43. package/config/skills/_shared/resolve-stop-hook.py +0 -359
  44. package/config/skills/_shared/run-bounded.py +0 -58
  45. package/config/skills/_shared/spec-verify-check.py +0 -5083
  46. package/config/skills/_shared/state-phase-write.py +0 -5989
  47. package/config/skills/_shared/terminal-claim-check.py +0 -777
  48. package/config/skills/_shared/verify-merge-findings.py +0 -3528
  49. package/config/skills/devlyn-design-ui/SKILL.md +0 -650
  50. package/config/skills/devlyn-ideate/references/from-spec-mode.md +0 -61
  51. package/config/skills/devlyn-ideate/references/project-mode.md +0 -80
  52. package/config/skills/devlyn-ideate/references/spec-template.md +0 -121
  53. package/config/skills/devlyn-ideate/references/templates/decision.md +0 -48
  54. package/config/skills/devlyn-ideate/references/templates/roadmap.md +0 -50
  55. package/config/skills/devlyn-ideate/references/templates/vision.md +0 -44
  56. package/config/skills/devlyn-queue/SKILL.md +0 -66
  57. package/config/skills/devlyn-queue/scripts/append.py +0 -94
  58. package/config/skills/devlyn-resolve/SKILL.md +0 -379
  59. package/config/skills/devlyn-resolve/references/free-form-mode.md +0 -71
  60. package/config/skills/devlyn-resolve/references/outer-loop.md +0 -23
  61. package/config/skills/devlyn-resolve/references/phases/build-gate.md +0 -75
  62. package/config/skills/devlyn-resolve/references/phases/cleanup.md +0 -33
  63. package/config/skills/devlyn-resolve/references/phases/implement.md +0 -44
  64. package/config/skills/devlyn-resolve/references/phases/plan.md +0 -39
  65. package/config/skills/devlyn-resolve/references/phases/probe-derive.md +0 -261
  66. package/config/skills/devlyn-resolve/references/phases/surface-close.md +0 -34
  67. package/config/skills/devlyn-resolve/references/phases/verify.md +0 -310
  68. package/config/skills/devlyn-resolve/references/state-schema.md +0 -152
  69. package/config/skills/devlyn-resolve/references/task-completion.md +0 -160
  70. package/config/templates/prompt-templates.md +0 -71
  71. package/config/templates/template-feature.spec.md +0 -255
  72. package/config/templates/template-product-spec.md +0 -680
package/bin/devlyn.js CHANGED
@@ -10,28 +10,30 @@ const { execSync } = require('child_process');
10
10
  const CONFIG_SOURCE = path.join(__dirname, '..', 'config');
11
11
  const OPTIONAL_SKILLS_SOURCE = path.join(__dirname, '..', 'optional-skills');
12
12
  const PKG = require('../package.json');
13
- const { updateInstructions, InstructionError, holdsDevlynDefaults } = require('./instructions');
13
+ const { updateInstructions, InstructionError, holdsDevlynDefaults, importsAgentsMd } = require('./instructions');
14
14
 
15
15
  // The devlyn skill bundle installed into every skill-capable agent's loader
16
16
  // directory. Single source of truth so codex/omp/pi stay in lockstep — adding a
17
17
  // skill here installs it everywhere.
18
- const DEVLYN_CORE_SKILLS = ['devlyn-resolve', 'devlyn-ideate', 'devlyn-design-ui', 'devlyn-engines', 'devlyn-queue', '_shared'];
18
+ const DEVLYN_CORE_SKILLS = ['devlyn-ideate', 'devlyn-engines', '_shared'];
19
19
  // 4.0.0 renamed the colon-named skills to the Agent Skills standard (`[a-z0-9-]`, name ==
20
20
  // folder): Git for Windows cannot check out a folder with ':' in its name. Installs from 3.x
21
21
  // and earlier keep the old folder under either spelling (':' or npm's U+F03A extraction
22
22
  // alias). Both are removed, and an optional skill that was installed is installed again
23
23
  // under its new name in the same place.
24
24
  const RENAMED_SKILLS = {
25
- 'devlyn:resolve': 'devlyn-resolve',
26
25
  'devlyn:ideate': 'devlyn-ideate',
27
- 'devlyn:design-ui': 'devlyn-design-ui',
28
26
  'devlyn:engines': 'devlyn-engines',
29
- 'devlyn:queue': 'devlyn-queue',
30
27
  'devlyn:pencil-pull': 'devlyn-pencil-pull',
31
28
  'devlyn:pencil-push': 'devlyn-pencil-push',
32
29
  'devlyn:reap': 'devlyn-reap',
33
30
  };
34
31
  const DEVLYN_INSTALL_MARKER = '.devlyn-install.json';
32
+ // Project settings earlier releases added for the retired pipeline.
33
+ const RETIRED_STOP_HOOK = 'python3 "$CLAUDE_PROJECT_DIR/.claude/skills/_shared/resolve-stop-hook.py"';
34
+ const RETIRED_ENV = ['CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS'];
35
+ const RETIRED_PERMISSIONS = ['Write(.devlyn/**)', 'Edit(.devlyn/**)', 'Bash(git add *)', 'Bash(git commit *)',
36
+ 'Bash(git diff *)', 'Bash(git status *)', 'Bash(git log *)'];
35
37
 
36
38
  // Every spelling a colon name can have on disk: its own and npm's U+F03A extraction alias.
37
39
  function legacySkillPaths(root, name) {
@@ -102,21 +104,21 @@ function skillRoots(target, global) {
102
104
 
103
105
  // A devlyn Claude install in this scope. Globally only the marker a `--global --claude` run
104
106
  // writes counts; in a project also a devlyn skill (0.6.0 and later), command (0.2-0.5) or
105
- // CLAUDE.md with devlyn defaults, which a team may commit while ignoring .claude/. An optional
106
- // devlyn skill is not one: 4.0.1 put those into .claude/skills without the Claude target. A
107
- // CLAUDE.md link (often to AGENTS.md) is not the Claude target's file: updateInstructions
108
- // refuses links.
107
+ // CLAUDE.md with devlyn defaults, held or imported from AGENTS.md, which a team may commit
108
+ // while ignoring .claude/. An optional devlyn skill is not one: 4.0.1 put those into
109
+ // .claude/skills without the Claude target. A CLAUDE.md link (often to AGENTS.md) is not the
110
+ // Claude target's file: updateInstructions refuses links.
109
111
  function hasDevlynClaude(global) {
110
112
  const claudeDir = path.dirname(skillRoots('claude', global)[0]);
111
113
  if (global) return fs.existsSync(path.join(claudeDir, 'skills', DEVLYN_INSTALL_MARKER));
112
114
  const names = (dir) => (fs.existsSync(dir) ? fs.readdirSync(dir) : []);
113
115
  const optional = new Set(OPTIONAL_ADDONS.map((addon) => addon.name));
114
116
  const instructions = path.join(path.dirname(claudeDir), 'CLAUDE.md');
117
+ const claude = fs.lstatSync(instructions, { throwIfNoEntry: false })?.isFile() ? fs.readFileSync(instructions, 'utf8') : '';
115
118
  return names(path.join(claudeDir, 'skills')).some((name) => name === DEVLYN_INSTALL_MARKER
116
119
  || (name.startsWith('devlyn') && !optional.has(name.replace(/[:\uF03A]/g, '-'))))
117
120
  || names(path.join(claudeDir, 'commands')).some((name) => name.startsWith('devlyn.'))
118
- || (fs.lstatSync(instructions, { throwIfNoEntry: false })?.isFile() === true
119
- && holdsDevlynDefaults('CLAUDE.md', fs.readFileSync(instructions, 'utf8')));
121
+ || holdsDevlynDefaults('CLAUDE.md', claude) || importsAgentsDefaults(claude);
120
122
  }
121
123
 
122
124
  // Commands removed in previous versions; the project Claude install deletes them from .claude/.
@@ -183,6 +185,15 @@ const DEPRECATED_DIRS = [
183
185
  // so users who previously opted in get their stale copies purged on upgrade.
184
186
  'skills/devlyn:team-design-ui',
185
187
  'skills/devlyn:design-system',
188
+ // Retired after 4.1.0 (design-ui deleted; the intent queue moved into
189
+ // devlyn-ideate; resolve retired). All were core skills, so their 3.x and
190
+ // 4.x folders go.
191
+ 'skills/devlyn-design-ui',
192
+ 'skills/devlyn:design-ui',
193
+ 'skills/devlyn-queue',
194
+ 'skills/devlyn:queue',
195
+ 'skills/devlyn-resolve',
196
+ 'skills/devlyn:resolve',
186
197
  ];
187
198
 
188
199
  function projectDir() {
@@ -257,10 +268,7 @@ const OPTIONAL_ADDONS = [
257
268
  { name: 'anthropics/skills', desc: 'Official Anthropic skill-creator with eval framework and description optimizer', type: 'external' },
258
269
  { name: 'Leonxlnx/taste-skill', desc: 'Premium frontend design skills — modern layouts, animations, and visual refinement', type: 'external' },
259
270
  // MCP servers (installed via claude mcp add)
260
- // Note: the Codex integration uses the local `codex` CLI binary (not MCP).
261
- // Install the CLI separately per https://platform.openai.com/docs/codex — the
262
- // pair/risk-probe routes fail closed when Codex is required but unavailable.
263
- { name: 'playwright', desc: 'Playwright MCP for browser testing — powers /devlyn-resolve BUILD_GATE browser tier', type: 'mcp', command: 'npx -y @playwright/mcp@latest' },
271
+ { name: 'playwright', desc: 'Playwright MCP for browser testing', type: 'mcp', command: 'npx -y @playwright/mcp@latest' },
264
272
  ];
265
273
 
266
274
  function log(msg, color = 'reset') {
@@ -306,23 +314,8 @@ function listContents() {
306
314
  showLogo();
307
315
  log('─'.repeat(44), 'dim');
308
316
 
309
- const templatesDir = path.join(CONFIG_SOURCE, 'templates');
310
317
  const skillsDir = path.join(CONFIG_SOURCE, 'skills');
311
318
 
312
- // List templates
313
- if (fs.existsSync(templatesDir)) {
314
- const templates = fs.readdirSync(templatesDir).filter((f) => f.endsWith('.md'));
315
- if (templates.length > 0) {
316
- log('\n📄 Templates:', 'blue');
317
- templates.forEach((file) => {
318
- const name = file.replace('.md', '');
319
- const desc = getDescription(path.join(templatesDir, file));
320
- log(` ${COLORS.green}${name}${COLORS.reset}`);
321
- if (desc) log(` ${COLORS.dim}${desc}${COLORS.reset}`);
322
- });
323
- }
324
- }
325
-
326
319
  // List skills
327
320
  if (fs.existsSync(skillsDir)) {
328
321
  const skills = fs.readdirSync(skillsDir).filter((d) => {
@@ -726,14 +719,56 @@ function installAgentsProject(withClaude) {
726
719
  ignoreInGit(['.devlyn/', '.agents/skills/.devlyn-install.json']);
727
720
  }
728
721
 
729
- // Project CLAUDE.md and .claude/: skills, templates, commit conventions and settings.
722
+ // Whether Claude Code reads the devlyn defaults of AGENTS.md through an `@AGENTS.md` import in this CLAUDE.md text.
723
+ // An AGENTS.md that is CLAUDE.md under another name holds CLAUDE.md's own defaults.
724
+ function importsAgentsDefaults(claude) {
725
+ const agents = path.join(projectDir(), 'AGENTS.md');
726
+ return importsAgentsMd(claude) && !agentsMdIsClaudeMd() && fs.statSync(agents, { throwIfNoEntry: false })?.isFile() === true
727
+ && holdsDevlynDefaults('AGENTS.md', fs.readFileSync(agents, 'utf8'));
728
+ }
729
+
730
+ // Claude Code reads AGENTS.md only where no CLAUDE.md exists, or through a CLAUDE.md that imports it. So a new
731
+ // CLAUDE.md imports an existing AGENTS.md, and a CLAUDE.md importing an AGENTS.md that holds devlyn defaults holds no
732
+ // copy of its own, not even one it got while AGENTS.md lacked the block. Only the AGENTS.md target updates those defaults,
733
+ // together with .agents/skills, so the Claude target stops while they need an update.
734
+ function installClaudeInstructions() {
735
+ const file = path.join(projectDir(), 'CLAUDE.md');
736
+ const stat = fs.lstatSync(file, { throwIfNoEntry: false });
737
+ const initial = !stat && fs.statSync(path.join(projectDir(), 'AGENTS.md'), { throwIfNoEntry: false })?.isFile() ? '@AGENTS.md\n' : '';
738
+ const imported = importsAgentsDefaults(stat?.isFile() ? fs.readFileSync(file, 'utf8') : initial);
739
+ if (imported && updateInstructions('AGENTS.md', '', true, false)) {
740
+ throw new InstructionError('Claude Code reads AGENTS.md here, and its devlyn defaults need an update. Codex, omp, Pi and Grok '
741
+ + 'read them too, with .agents/skills, so choose AGENTS.md as well (npx devlyn-cli -y --claude) to update both together.');
742
+ }
743
+ updateInstructions('CLAUDE.md', initial, !imported);
744
+ if (imported) log(' → CLAUDE.md imports AGENTS.md, which holds the devlyn block', 'dim');
745
+ }
746
+
747
+ // Project CLAUDE.md and .claude/: skills and settings.
730
748
  function installClaudeCore() {
731
- updateInstructions('CLAUDE.md');
732
749
  const skillsDir = skillRoots('claude', false)[0];
733
750
  const targetDir = path.dirname(skillsDir);
734
- for (const entry of fs.readdirSync(CONFIG_SOURCE)) {
735
- if (entry !== 'skills') copyRecursive(path.join(CONFIG_SOURCE, entry), path.join(targetDir, entry), targetDir);
751
+ // Read before any write, so settings this install cannot merge leave the Claude target as it was.
752
+ const settingsPath = path.join(targetDir, 'settings.json');
753
+ const unmergeable = (reason) => new InstructionError(`Cannot merge .claude/settings.json: ${reason}. `
754
+ + 'CLAUDE.md and .claude/ are unchanged; fix the file and rerun the same install command.');
755
+ let settings = {};
756
+ if (fs.existsSync(settingsPath)) {
757
+ try {
758
+ // Claude Code accepts a leading byte order mark.
759
+ settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8').replace(/^\uFEFF/, ''));
760
+ } catch (error) {
761
+ throw unmergeable(error.message);
762
+ }
763
+ }
764
+ if (!settings || typeof settings !== 'object' || Array.isArray(settings)) {
765
+ throw unmergeable('root must be a JSON object');
766
+ }
767
+ if (Object.prototype.hasOwnProperty.call(settings, 'env')
768
+ && (!settings.env || typeof settings.env !== 'object' || Array.isArray(settings.env))) {
769
+ throw unmergeable('env must be a JSON object');
736
770
  }
771
+ installClaudeInstructions();
737
772
  for (const relPath of DEPRECATED_FILES) {
738
773
  const fullPath = path.join(targetDir, relPath);
739
774
  if (fs.existsSync(fullPath)) {
@@ -744,108 +779,51 @@ function installClaudeCore() {
744
779
  installCoreSkills(skillsDir);
745
780
  ignoreInGit(['.devlyn/', '.claude/skills/.devlyn-install.json']);
746
781
 
747
- // Enable agent teams in project settings
748
- const settingsPath = path.join(targetDir, 'settings.json');
749
- let settings = {};
750
- if (fs.existsSync(settingsPath)) {
751
- try {
752
- settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8'));
753
- } catch (error) {
754
- throw new Error(`Cannot merge .claude/settings.json: ${error.message}`);
755
- }
756
- }
757
- if (!settings || typeof settings !== 'object' || Array.isArray(settings)) {
758
- throw new Error('Cannot merge .claude/settings.json: root must be a JSON object');
759
- }
760
- const hasOwnSetting = (key) => Object.prototype.hasOwnProperty.call(settings, key);
782
+ // One-hour foreground Bash calls and one-hour prompt caching serve a drain host that waits in the foreground.
761
783
  let settingsChanged = false;
762
- if (!hasOwnSetting('env')) {
784
+ if (!Object.prototype.hasOwnProperty.call(settings, 'env')) {
763
785
  settings.env = {};
764
786
  settingsChanged = true;
765
787
  }
766
- if (!settings.env || typeof settings.env !== 'object' || Array.isArray(settings.env)) {
767
- throw new Error('Cannot merge .claude/settings.json: env must be a JSON object');
768
- }
769
- // Auto-allow pipeline state directory and common git commands so resolve doesn't prompt
770
- if (!hasOwnSetting('permissions')) {
771
- settings.permissions = {};
772
- settingsChanged = true;
773
- }
774
- if (!settings.permissions || typeof settings.permissions !== 'object' || Array.isArray(settings.permissions)) {
775
- throw new Error('Cannot merge .claude/settings.json: permissions must be a JSON object');
776
- }
777
- if (!Object.prototype.hasOwnProperty.call(settings.permissions, 'allow')) {
778
- settings.permissions.allow = [];
779
- settingsChanged = true;
780
- }
781
- if (!Array.isArray(settings.permissions.allow)) {
782
- throw new Error('Cannot merge .claude/settings.json: permissions.allow must be an array');
783
- }
784
- const pipelinePermissions = [
785
- 'Write(.devlyn/**)',
786
- 'Edit(.devlyn/**)',
787
- 'Bash(git add *)',
788
- 'Bash(git commit *)',
789
- 'Bash(git diff *)',
790
- 'Bash(git status *)',
791
- 'Bash(git log *)',
792
- ];
793
- for (const perm of pipelinePermissions) {
794
- if (!settings.permissions.allow.includes(perm)) {
795
- settings.permissions.allow.push(perm);
796
- settingsChanged = true;
797
- }
798
- }
799
788
  if (!settings.env.ENABLE_PROMPT_CACHING_1H) {
800
789
  settings.env.ENABLE_PROMPT_CACHING_1H = 'true';
801
790
  settingsChanged = true;
802
791
  }
803
- if (!settings.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS) {
804
- settings.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS = '1';
805
- settingsChanged = true;
806
- }
807
792
  const bashMaxTimeoutMs = Number.parseInt(settings.env.BASH_MAX_TIMEOUT_MS, 10);
808
793
  if (!Number.isFinite(bashMaxTimeoutMs) || bashMaxTimeoutMs < 3600000) {
809
794
  settings.env.BASH_MAX_TIMEOUT_MS = '3600000';
810
795
  settingsChanged = true;
811
796
  }
812
- if (!hasOwnSetting('hooks')) {
813
- settings.hooks = {};
814
- settingsChanged = true;
815
- }
816
- if (!settings.hooks || typeof settings.hooks !== 'object' || Array.isArray(settings.hooks)) {
817
- throw new Error('Cannot merge .claude/settings.json: hooks must be a JSON object');
818
- }
819
- if (!Object.prototype.hasOwnProperty.call(settings.hooks, 'Stop')) {
820
- settings.hooks.Stop = [];
821
- settingsChanged = true;
822
- }
823
- if (!Array.isArray(settings.hooks.Stop)) {
824
- throw new Error('Cannot merge .claude/settings.json: hooks.Stop must be an array');
825
- }
826
- const stopHookCommand = 'python3 "$CLAUDE_PROJECT_DIR/.claude/skills/_shared/resolve-stop-hook.py"';
827
- const stopHookInstalled = settings.hooks.Stop.some((entry) => (
828
- entry && Array.isArray(entry.hooks) && entry.hooks.some((hook) => (
829
- hook && hook.type === 'command' && hook.command === stopHookCommand
830
- ))
831
- ));
832
- if (!stopHookInstalled) {
833
- settings.hooks.Stop.push({
834
- hooks: [{ type: 'command', command: stopHookCommand, timeout: 30 }],
835
- });
797
+ // Remove exactly the retired Stop hook command, and its entry only when nothing else is left in it.
798
+ const retiredHook = (hook) => hook?.type === 'command' && hook.command === RETIRED_STOP_HOOK;
799
+ const stop = Array.isArray(settings.hooks?.Stop) ? settings.hooks.Stop : [];
800
+ for (let i = stop.length - 1; i >= 0; i--) {
801
+ const hooks = stop[i]?.hooks;
802
+ if (!Array.isArray(hooks) || !hooks.some(retiredHook)) continue;
803
+ stop[i].hooks = hooks.filter((hook) => !retiredHook(hook));
804
+ if (stop[i].hooks.length === 0 && Object.keys(stop[i]).length === 1) stop.splice(i, 1);
805
+ log(' ✕ settings.json Stop hook of the retired pipeline (removed)', 'dim');
836
806
  settingsChanged = true;
837
807
  }
838
808
  if (settingsChanged) {
839
809
  fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
840
- log(' → settings.json (agent teams + one-hour Bash max + 1h prompt caching + pipeline permissions + Stop hook)', 'dim');
810
+ log(' → settings.json', 'dim');
811
+ }
812
+ // Their ownership cannot be established, so the other retired settings stay; name the ones present.
813
+ const retired = [
814
+ ...RETIRED_ENV.filter((key) => Object.prototype.hasOwnProperty.call(settings.env, key)),
815
+ ...RETIRED_PERMISSIONS.filter((rule) => Array.isArray(settings.permissions?.allow) && settings.permissions.allow.includes(rule)),
816
+ ];
817
+ if (retired.length > 0) {
818
+ log(` Retired devlyn settings may remain in .claude/settings.json: ${retired.join(', ')} — delete those you did not add yourself.`, 'yellow');
841
819
  }
842
820
  }
843
821
 
844
822
  // Installs the targets in one scope; returns the skill roots written.
845
823
  function install(targets, global) {
846
824
  // In the home folder CLAUDE.md, AGENTS.md (agents read a parent folder's too) and
847
- // .claude/settings.json (permissions, Stop hook) would apply to every project. Same folder by
848
- // identity, so a link or another spelling of the path is caught too.
825
+ // .claude/settings.json would apply to every project. Same folder by identity, so a link or
826
+ // another spelling of the path is caught too.
849
827
  const home = fs.statSync(os.homedir(), { bigint: true, throwIfNoEntry: false });
850
828
  const here = fs.statSync(projectDir(), { bigint: true });
851
829
  if (!global && home?.dev === here.dev && home?.ino === here.ino) {
@@ -853,7 +831,8 @@ function install(targets, global) {
853
831
  + 'would apply to every project. Run from a project folder, or use --global for skills only.');
854
832
  }
855
833
  const roots = targets.flatMap((target) => skillRoots(target, global));
856
- for (const target of targets) {
834
+ // AGENTS.md first, whatever order the menu gave: a new CLAUDE.md holds the block only when AGENTS.md does not.
835
+ for (const target of ['agents', 'claude'].filter((name) => targets.includes(name))) {
857
836
  if (global) skillRoots(target, true).forEach((root) => installCoreSkills(root));
858
837
  else if (target === 'agents') installAgentsProject(targets.includes('claude'));
859
838
  else installClaudeCore();
@@ -909,7 +888,7 @@ async function init({ yes, claude, global }) {
909
888
  log('\n🎯 What to install:\n', 'blue');
910
889
  const targetOptions = [
911
890
  { key: 'agents', name: 'AGENTS.md — Codex · omp · Pi · Grok', desc: 'AGENTS.md + .agents/skills' },
912
- { key: 'claude', name: 'CLAUDE.md — Claude Code', desc: 'CLAUDE.md + .claude/ (skills, templates, settings)' },
891
+ { key: 'claude', name: 'CLAUDE.md — Claude Code', desc: 'CLAUDE.md + .claude/ (skills, settings)' },
913
892
  ];
914
893
  const preselected = claude || hasDevlynClaude(false) || (global && hasDevlynClaude(true)) ? [0, 1] : [0];
915
894
  const targets = (await multiSelect(targetOptions, preselected)).map((option) => option.key);
@@ -951,7 +930,7 @@ function showHelp() {
951
930
  log(' npx devlyn-cli -y Without prompts: AGENTS.md + .agents/skills, plus CLAUDE.md + .claude/ if this project has them');
952
931
  log(' npx devlyn-cli -y --claude Also install CLAUDE.md + .claude/ for Claude Code');
953
932
  log(' npx devlyn-cli -y --global Skills only, for every project on this machine (~/.agents/skills, ~/.codex/skills; ~/.claude/skills with --claude, or when it already has a devlyn install)');
954
- log(' npx devlyn-cli list List available skills & templates');
933
+ log(' npx devlyn-cli list List available skills');
955
934
  log(' npx devlyn-cli --help Show this help\n');
956
935
  log('Optional skills (select during install):', 'green');
957
936
  OPTIONAL_ADDONS.filter((a) => a.type === 'local').forEach((skill) => {
@@ -89,10 +89,12 @@
89
89
  "029ce19ffbe7b9bab829a8da4aecbfec239c566b2b395112dddeda4516a50255",
90
90
  "02acf4d54b0fbb587b78b227a16d3394f737f9a984d168bd5ab71f4d6b00ab72",
91
91
  "03d85ed66f64ea52f2f96d9fb203b05ac6afc0ba634a4dfb3585429ce1531c44",
92
+ "0467080d13d933b663362006ae5f5a0ad73baaed51ad50faf3f0d3d9f92244a3",
92
93
  "0634a245075d1a5aac4e58c1345f40f5f4c3b4909315f86aacd7ab239ea3ce61",
93
94
  "0869633a322da8f8d800b1d2c23becc52f5ff592f0823533ea24f09de465c53a",
94
95
  "090f003bb30b98e6979865f3eb9bbc66eaa8f0cd74a89ff2eea5ef38cbee13b5",
95
96
  "0926622dde30d21c6cafe6b69b0bb0608b31e2528655615c7edbdedc6ae43d7c",
97
+ "0a8be3a2fb2bd90dd48d9bfa1f1419f77a5378929f6b296c5332252e73c61d43",
96
98
  "0b679ac026de2416da082320f94e0f4f0ae9680b97751500db80b3546f9db9be",
97
99
  "0bc87e8af36113cda1539f916c835fe65485fc33e9010ece546b07e5925f4a9c",
98
100
  "0c0458c53f32a021ed4cf6ca7db6f8c3d1dd4fc93204850017e7194864fcbc16",
@@ -108,9 +110,11 @@
108
110
  "15598b4bdb679c765c616182509d021633b964ecc7f8be77cc0d90680a713e98",
109
111
  "16a1d88b1a778004f91439f57371164b525b21d3aec1820510c0de596e5d1fb7",
110
112
  "16c7d965e59534532e390b17dba008a2414fe88dcd3595e89a16d6d86ca01f61",
113
+ "1705d88a34e295eef17ee08ebf412decb6f45d328e57c58996fe20f0594fb820",
111
114
  "17ac254ca2cf86f7637db35f6380370aef06c4f87c08af6c1976e968c4c3f549",
112
115
  "186f55e73293c12c2c5ada4c8ceffdbee69c7d147e17237f3650ae235e9ca7b8",
113
116
  "188e31cffa81acc58baf4c94b525d3a1945ffb41ba849244b7372e6852e48fb8",
117
+ "19d17a2a263d240c7e3c4520f8bd6cf4705bf99532edc84d4546eb0440e6dff8",
114
118
  "1b1d4045f72b6e96026b549edfcb24cfdb0e3d621814b769893f53095b11f362",
115
119
  "1c3ef72df964eb9d6ba964b4dc1e10c442c7ac46f44e40f9e634a74594cc2f3b",
116
120
  "1d90788860a8e032046629a2a0e106bbbf325a8a627012897ee9235fbab98bd0",
@@ -149,6 +153,7 @@
149
153
  "34a09b8d6023ae5b858ec5135cae8efeabd921e3108e63e9627a222b188fe554",
150
154
  "34a494444df9d11dea3e6f01868ed11ece52c322d7198ed2075ab2640da45266",
151
155
  "350aa6a3140d56a22cb4d5f2503f453ad238384150dc2b5e480fc626db33dfec",
156
+ "35782424442926d2fdc6128337e2f86ce681890ff7c2328dfe8475af009e6fea",
152
157
  "37f003566c80ead28d713e86bd6a877e2e3239302c884911f5144a896c291c17",
153
158
  "39972d3dd19a7d771d2d3a5d083fddca6da1a22ad8ea27dbe70bbb4615ef2c94",
154
159
  "39af5b94a2734e4fc6c943b604fde4b0d798c4a2a7b1ffb5d053ab7f22488de3",
@@ -179,6 +184,7 @@
179
184
  "4d756bc5c6a7c7ca1589efc6c340c75fb389699fe14d114aa211a29921e7effe",
180
185
  "4dcba526b49c91411d98925a7f638d990acea0f904ba8f143f195f7f99f85e33",
181
186
  "4e114313a6fbf27b89bebe7847f9aebb4ca2c61d23d167997efd459fa091e602",
187
+ "4e80a2a2797d5320ea96f785698b699a49fd69622bf00733edb8de67f46dd148",
182
188
  "4f6bf3fa8b8b706d234a7d5a3dda34e52ce1fcba68770aadf606c1717543bd5a",
183
189
  "50fe2edc6da214c0ae4bfce43d8d210f98ff15da2d2f9bca88269dab9a4ed179",
184
190
  "51a7490d3c92e196373ec01bde05d8209426b765b6351dfe27449838c487f073",
@@ -195,8 +201,10 @@
195
201
  "5978dcb6e377cf64fe4865f68355d9f48bbf6f2fa19a2d89eb94e5eabbb1e813",
196
202
  "5a12650a43b6a809a28ef665907740b90150fce895b4d4de4e5d7446a482f182",
197
203
  "5ad7118a8116ae2fea66b45dc6c59128b16f8e8000911f87acbcdba1525b9b68",
204
+ "5b82f9020d952e89ccf8803bce90dd5b9c38b39fa59a629349c9d15cc14c9597",
198
205
  "5c775bb62be74cec0b9f52520d89ac918872c3a65832c7eb120b5b4461b30854",
199
206
  "5da2a81f95f8697406622ac92c8ccb61537b90c74a99beb48905844394cdd93e",
207
+ "5dcd2f3c12ef8665788614439bc8a87f14b3c8ed6c2d779ec587ac304933d47a",
200
208
  "5e329ef8e25962ef0c9b29cf769fa1a92a82ab597ef29118961ff250eee76f70",
201
209
  "5e73319288935d1857bf1d9b8a46f56c19bdffd46ff2f822b930f2b17cb1f98d",
202
210
  "5eaedae1a36f29150537ca51771c3ed19afadc72e08a304179c52454252ad312",
@@ -220,6 +228,7 @@
220
228
  "69b0122066857d8b166ab5e94e162bf2479425760914ca6c05c655455b8f6e66",
221
229
  "6a08a11aea6a1dfaa99823a73bc8730e8fff9c483ec8989aaeca669cfc7b3ed6",
222
230
  "6b287911edc5fa5f7792941de251b46d8ae8500553239b559f11292136e89e7a",
231
+ "6b65f3883cfca3d531ab716c069c88f3a7d964657c5e026bda25eacdb37f16c5",
223
232
  "6c32954c006e1cbe92ca74656797f0165dbd55ca77a8873fa63737206e40b857",
224
233
  "6c7d2465dc68f1d040d5f3904f7d08622a0f2195de893635f5f359e72b9b2f5e",
225
234
  "6ce3f0a6ffffd02adb100b725b53ad6cacc2a133f38075e0103bfd854792b2dd",
@@ -233,6 +242,7 @@
233
242
  "6f9b366d18f73b72e6d66bc942a84126c60bed911faf834522c92fde7d12ad4c",
234
243
  "7076c6738e6d3e2739680f57c9ab3c7522ec0b9ace00b663619bcd7370ce570a",
235
244
  "722cc953822fe6a46b182f787999d166920a6b3ad4bd71b57ea2bdc79590071a",
245
+ "7457d0f899bffbe34526b04f89673a3f84a9aaaa8c12f90d69e3cc261cd4cecf",
236
246
  "74d1a65b0689c3a4fb81c950c56f8b753a240f43ca336389aadc90c02fae13b9",
237
247
  "7608b1cabef6a327cd841f8c994301a12aa29e04a00fcd02d641a3ed6d619db7",
238
248
  "76517a747d47a3986b7181db4bbe5898ad3d6d82644ce39d8bf62edc998cecb9",
@@ -253,6 +263,7 @@
253
263
  "8a612ad6038c31b74582cce2a2165c2be6be72e29db03dd2a2ab55d5a67d3055",
254
264
  "8b0c46ab550956964233c24c188a68b9e054b9a250c17a7f7d3ac49dcc735798",
255
265
  "8b5229a215f1b662c6da49a96f06bb7ec32e39c435100d49275272c25837fb47",
266
+ "8bfa724fab748a31d710b443ee13e4464369b7d5c82b9515ddb18df56132d671",
256
267
  "8c06bf7daf489571b342b7b4ba23b13f28cc5436e1b4694460e29962a7b63e8f",
257
268
  "8ce293fd80ec392803698f6564b995f6bbcb8fc6072dcc8a45b0b4afea989950",
258
269
  "8ec1424b49dbae25dcba6f7c220624a024e426f32a0fb1bb56b49cfb38ca4132",
@@ -275,20 +286,24 @@
275
286
  "9d9afeab8026b9bf7074febe07380d8ea7a9ef7168149e72ff8af93c1abee29b",
276
287
  "9e074e9e2c4302901a160f0ba121aa348b2a0e1e1313a2079aae289f2746de3e",
277
288
  "9e65019acb60433529160c929b840398fe6e5d72dcfd219cb79e69ba2d3cd5e9",
289
+ "9f105921480a9157deaad98839fee04bb52ae28f72a8efa6ddf78d658ec1b2b3",
278
290
  "9f62c5b2a94e8b5e81528ccbdb6f78d147d14882108568b2cb3b7f85212694c0",
279
291
  "9f6d9ef148d5b4ab1e365bd7411a01a1d019ee241d9ed556bab5ee7499d79417",
280
292
  "a02eb2d8d77553327fb77377dbfedeab059b2e68e0a33c469b9be54a5d55182b",
293
+ "a10a5a7838269e918a14d99e09bf54162b7f5e460ff488d068e420aa63180af7",
281
294
  "a12a5593a1725fceed3c52706a13ed6a72063f267e13696f0ce2a4bc50bb37b5",
282
295
  "a27ec7f5f0f0a2798e53695f20dc43fe28378d551fc060e2c772d0b522a336e5",
283
296
  "a3a15249968f64085b0cec8c0826688a4c3a1e4cf09b4879054baa086d5cbca1",
284
297
  "a4da26a46ab83815d8ca5d747c68a907ad67dad485adbc6c863b982ee23b307e",
285
298
  "a5d6ff585d696254d6727cd1e6d7f8825881f90210eff744265e211ced715ea3",
299
+ "a5f9cf621cf485e6247f664752e13929b4e52a0bbd3955cdd022c1af584b05ab",
286
300
  "a7ff913df40945a8a16b6632214020a368119ff665953d4a07ec58330b39f101",
287
301
  "a9395efaa63038c24ffaed027b72acd6d67612a80f697e47fd440e3ddc16ef20",
288
302
  "aafc680a7ac73e100f4a17d2c4070190e68563f78614c39f4c2f58f1e291d9a9",
289
303
  "ab7f6d08d95cf1c22b7ec6e2e113158b7f767b73d8dde04fd1c3b33788922c93",
290
304
  "ac432d9179f245fec0beaf4010355613dcd6d476d8c9268c9cd430c98e73ff35",
291
305
  "adcb46726c532fef32c4e420d305c2de9bd43b668fa5d0e7f00a570a6a426500",
306
+ "af35a3eee2e642bb1d32390efdcceb3de4558287e8b26d7c40df0e521cd00a3c",
292
307
  "af3a498714fecb29ebdc1e43e5cc0425efaf1c290130e6913cabd75fe4c9cc67",
293
308
  "af77f01317665c50815eb3cfefe481519efcc9c8b81bac06fc110abf723c7868",
294
309
  "af96d41e6e6d2dce4d1038d71f0f68306fa8170d2c37c537c593778e558f3dc5",
@@ -306,6 +321,7 @@
306
321
  "bddb4f88a0c11165b9cafe7a31027e9769313e1aee7c0a9ed9dad490e4fe1bcc",
307
322
  "be11c198a50be2884c4c1efec52bbddff55c7547a5daf0ec2ef046279c95dc45",
308
323
  "bfdb7c7e4db21e1c452e730cecadc8e97abd317c6e54ae58c298f4288b1f1354",
324
+ "c1a1e9722a0f3c13c693eeaacdac8cc3d13d36d242f2bab58311170496ea4e2e",
309
325
  "c236da36a45d4013ffb7e131575229b605f662a30b5174f14754f519acc24252",
310
326
  "c276962617888c5ac2d352c5e2ed018c5ce9d00f199c73e1dd61438ec4a914fb",
311
327
  "c2e80f501e29074e625206b864b084138153be2c83e63cacb20d47f62dd82f95",
@@ -338,8 +354,10 @@
338
354
  "d07f2a32bc75d6b25d60a5404db6fba52bc967bde80862484ed77cc7fdc8ce1f",
339
355
  "d189a2002b4ef0e858acb734c4ed14f6af6f0b7bb250b178f65d439369a9149a",
340
356
  "d342ef78e480e86a51375142cc31797143e3ebd3dec52ab2f788530505f54fe0",
357
+ "d3df16f5c755d614c644ac33c397e6ece6b0d3ddc4b18de70d45b2b938311248",
341
358
  "d41692aa7577bbd85144fe73d111947f98e1304f4aceb891d712daa5907d550d",
342
359
  "d486a0b267c9425bde2cba737d802d2412a9b4b4b339e925500c1643327d2a3d",
360
+ "d496c0136a48c3ee3de3fd8dbed8e0ebc649d906c507722993b9c5833239d49b",
343
361
  "d5d8d02a1fb53cd28ed1c33e7184067b76defbfcc6cab9498b365dee35579013",
344
362
  "d75bdfc9cf08cfcb46214f69dac4f20b1a0a30b86d91127007fe587de9eaaeb0",
345
363
  "d768a149b5842e0d50eda941872188c8b29bcfb4b1aa0f4190fd4299f237fce0",
@@ -347,6 +365,7 @@
347
365
  "d8c50cb04441e6b568236bc6cd494b4de296dfc7e8b33cf96e7aeb94612df3b8",
348
366
  "d940c2df4cfffa42265e4f85e429762b99dd6d055c1658d782c7b472c6ebacd5",
349
367
  "da019f3edfb762b9216016a3ea9cf7211b2ba698a55ddda5cec2e478218b0288",
368
+ "db194ffd774757f9e0c373e36fc127f8c031a541f23bf9abfdcd935277b0318b",
350
369
  "ddb200267b43942de3c061b449d08cc3f73441258b74816cfe13da091377b428",
351
370
  "dff43f9976c68267baf13f6a460f24af8e76be233c8440ac4684dc664106deae",
352
371
  "e031aef2a9adb0d0900e8269cf84c892f77b9938984e26df54826d1771861629",
@@ -387,7 +406,9 @@
387
406
  "fc5c3b053d38dcd91edeaef99ae8e308218563f10a66690b5fe1b5d12c42e42b",
388
407
  "fc813d93e760a69058c05fc0c9380f7dd09e3235cc22398a97ed2c1445eca29c",
389
408
  "fc98b9a7c2abdcc797b808459cea5ee0a1fdfcd95f24a8c0c38c0f4d920c77a7",
390
- "ffbd338af8a2b43cce01855c3d75582fe63e1bd1e60d9a62b70312afce30d331"
409
+ "fe77333774ef88faae6fa95402d7ced6f9caa18d6c97406aca0d934f5e700891",
410
+ "ffbd338af8a2b43cce01855c3d75582fe63e1bd1e60d9a62b70312afce30d331",
411
+ "ffd4b4af5ab9f5b4682e69a4a729df3dea59b98cc95e5724e0e4498e74a71e8d"
391
412
  ],
392
413
  "CLAUDE.md": [
393
414
  "00343e30ffbe497b405bfc956f52986fce298c1b162ec07831f06ae90d689369",
@@ -416,6 +437,7 @@
416
437
  "080051ed34915b572971d9fc734b95ba7a7984f6e799a7286055d41a7aeaa3b6",
417
438
  "0845abb4d59bce13c33c80b3292ba829bace0abe26d67a100a3bbc07e5db2b7d",
418
439
  "086b65c51d3342970968f4c3c6554a605b8740ed82809d26587cbd08f87d19f8",
440
+ "0a8be3a2fb2bd90dd48d9bfa1f1419f77a5378929f6b296c5332252e73c61d43",
419
441
  "0ab05e7ec571a8c899901514ab0655622817e8a77254ec2ec763fd78dad7f5bd",
420
442
  "0b45db686d97f33be4dc2b091ed259de534c2e3f97f8787574e722d2e86a0c1d",
421
443
  "0be26727b83829948ce23413a534c309a54dc7d238c8c1b232a31bbb26cb717c",
@@ -460,6 +482,7 @@
460
482
  "1c14e388ba39b4953aa51b2b73a92d287027f6849e25ee8725d9e3ea51f78fa1",
461
483
  "1c8eb04322ddd32ba3557b70d441e339d26159acb4b7361702177af607ecdf58",
462
484
  "1eb91782df82c7e317b7080d6caee3d8a3e638d3306b21c3dc1dbd8101179019",
485
+ "1f646b24267aeb362829ab0a63be6a9c43cad8621096f641675a774d3531bb6c",
463
486
  "1fa41c8a810b585535072b74f943a8570d942eb5617154353a5c8b6ebff4a2fb",
464
487
  "201b88453127e7a4dceb42a7ce6250812ed8a1aa00687c989d58741695ec8291",
465
488
  "20a6ad5c33b13bc791f34e1e414aadd5bf9b25383d21f0dde96a76cd9f45606a",
@@ -522,6 +545,7 @@
522
545
  "347019bc4c775fb46ff2fa68e8845b082aad6053b8e646c5f4aa5196a6a52f84",
523
546
  "34e0ff8adfd8d5088dcf09ef68a8f9d14d319b77115a5dc79b382dee1f7e451a",
524
547
  "35782424442926d2fdc6128337e2f86ce681890ff7c2328dfe8475af009e6fea",
548
+ "35b0cfdb6c727c658dc228e52e172061494bc0391479119fcff83a2f87e3fe6b",
525
549
  "35b1aa18fa6f90d3dac5b24aa9f54debf433857c694aa78f6bf122f4464480f5",
526
550
  "35d558ed31c5c53aeba50cd8c53f3d4fa8e2a8bc287f13a25a99944a8ebded29",
527
551
  "3610b254d617a02d9627f472a75326d11865f546c03df24e5acd6d047ba7d460",
@@ -617,6 +641,7 @@
617
641
  "5b82f9020d952e89ccf8803bce90dd5b9c38b39fa59a629349c9d15cc14c9597",
618
642
  "5d1183e08f92cb76c9fb41131742771101daebd65199b32050818a554e1ca185",
619
643
  "5d56b35a8b69aabc401bb42cf93f38d0eebcb1219f3a8a032e124c45d4e4b5d8",
644
+ "5dcd2f3c12ef8665788614439bc8a87f14b3c8ed6c2d779ec587ac304933d47a",
620
645
  "5dec4f3f015629b0c29c802b30a9e373c570fca85bb3e260c0dac9662d2685cd",
621
646
  "5dfd01e48b8b3eb9d6eec85d68624b2af0dd0eeb483307865ef88b0fc916bc97",
622
647
  "5e73319288935d1857bf1d9b8a46f56c19bdffd46ff2f822b930f2b17cb1f98d",
@@ -641,6 +666,7 @@
641
666
  "6a27907ba14fae9ddcacd551007b783b2f813c51c118828c74fd2174e09a7d41",
642
667
  "6a5ea10aa15a05ac992bd118adc3c0de48c85cea504aef655065d9678f93717c",
643
668
  "6b26d02b3f87d53a964b6fe405992104dd2ee85f8c1b3048951ece574d9005a8",
669
+ "6b65f3883cfca3d531ab716c069c88f3a7d964657c5e026bda25eacdb37f16c5",
644
670
  "6b726d35cdc0851401769b6de9c422cfa475dbe7c0d036726706439a2cdbb02a",
645
671
  "6b87c5a061164bac137a5bd44056ae78101b7315e09502bc9156b806e1ef0c00",
646
672
  "6bd51d5724a2ca78115853583a363b15bf74632714aebb5a51962159110a03f8",
@@ -659,6 +685,7 @@
659
685
  "72c9862cb638431dadce3a7ea004ebe76fa6e8d9e94f40178a8ad7a8d479fd0a",
660
686
  "730165a8d5893eec0b5056de6c79e50bd35a98321b78fcb946273c075d06140b",
661
687
  "74099aa171aa5bd6c61bb213f1c3b6735beb4abcabc197e75744e5c2d88817a8",
688
+ "7457d0f899bffbe34526b04f89673a3f84a9aaaa8c12f90d69e3cc261cd4cecf",
662
689
  "746f71b4a75713b055c6691179b364dc0da582e226e97f40ae409d9f73ee0311",
663
690
  "75b022c464eacbb24bf6e5b225e8e6fb1f313869603c1695a95cc995ee2699e0",
664
691
  "75d8e47601bab4fd9935ec353e7ea2146dc52954bf9b490816f97a42ed7610cf",
@@ -670,6 +697,7 @@
670
697
  "7aaf7227bd67650944c709f4143b6b9161834d391e5cfd4aaeea105f5e840594",
671
698
  "7af6e9be693d906ba1f942430f46b288176e418d35eefb869d3cc35570e3daff",
672
699
  "7b47b07e3062f3dc839f11397bc3265120e01a35b0fda094d738e28a6729e6c3",
700
+ "7bb5c341115c56592c0d1b5903d01321ce9c324136bc53babf9d438389796d94",
673
701
  "7c0dacd603b4381539d6d3cf21f5fe625cf54b05eb4aa750fce658529b11d81d",
674
702
  "7c79750557c7d7156df6f135fb582ec09cc5f4987ac8e2af0f5113e42c117224",
675
703
  "7d083db061c678113c12453eb73299caa9e207dd6418ad63406154fd330f3309",
@@ -682,6 +710,7 @@
682
710
  "818e10a1244cf2aa6fe34f6d1a8f680c124ecb201ab4364a2021a215dc5533cb",
683
711
  "82319a758f8397ba30f13857b1d814bb0652bcc9bf527e25a4761e0d60d685bf",
684
712
  "8320d006c59b36ea9a6227b6ee32c9da72e565b610e862e41a7d409894b56d09",
713
+ "835fe46abd073f866a928d1cd6cc0af1ef76d485e070d4c0ba9b0c2d8c411df8",
685
714
  "83abc941a813a09a37feea1edaa0b6ae69d28bfd88844cb5a1f867254638a4d8",
686
715
  "841faeaab5635f2552e257a69ab9b39a03db25d40ca711a31ec30853a0f69d08",
687
716
  "855c1f988b0794e1f1b1a589b8f5860312317bec5570af5f7c49001884f486da",
@@ -689,6 +718,7 @@
689
718
  "85fa19a45def0b572cd7b9a8310e7997677f88e48879f85b82688f1ab65b3b8d",
690
719
  "8619e97c3712d7d83a1101629f8546d013f3d5542659053283e9dbc565e4bfc0",
691
720
  "866c65c557a855671f5cd24ea4b9acf76b87a6ede4f42cea10c21c2486b26848",
721
+ "868cec4966c5b4b22dd6cdec48c973224a8a9d0187b58b711db55024fe9ff80a",
692
722
  "86e67b1646b959e175eaa510b7aee00d642dfb645da979b5a264218174e64584",
693
723
  "870231faeb0a9c7adb66e8e6d20bd271e45d4d1e5fb58737d9cadcca4f42de2a",
694
724
  "871b119f7954a8751ce0cfc08a2655d10ba66e4a27c632a4285d8d4eb916269d",
@@ -703,6 +733,7 @@
703
733
  "8aa71cc3b1cff95ecf309049f4fc6f6dec3b8827272e0ec72d05cec9f9e2803f",
704
734
  "8acb7ff8fca15e6f4c9db052f3690b908804e2bc98a20ffc12c5caaef6c87b55",
705
735
  "8b417f12b79e7328ab8998bde222da856470a9fe2a5eff838c710d5fc66c850e",
736
+ "8bfa724fab748a31d710b443ee13e4464369b7d5c82b9515ddb18df56132d671",
706
737
  "8c89d0106c4051f7400670c2e83e6e3cfd95533b6d4d5f715124f28dbf41c37e",
707
738
  "8cff7c530e70102f9506012e91f305c306c56a6e68073f44aba74a827c87f679",
708
739
  "8d0079bdee4cf4dc86c1cca826f81584fe2c97db04514fdd666167df8b509979",
@@ -735,11 +766,13 @@
735
766
  "9dcfd026c98eda9dad08214f602187ac47b3388029a8e33d46c20d49a4f8b3a4",
736
767
  "9de043ab22d62e6227b220e5d6ef7628f08380ba629c4c72766c2ec5fbc7cd9f",
737
768
  "9e8649d414e65cdeaffab5090601cfbdfc91ba3a78626b66ca8fe85669acb3e7",
769
+ "9f105921480a9157deaad98839fee04bb52ae28f72a8efa6ddf78d658ec1b2b3",
738
770
  "9f60ff43c2eb53ef727b06a0958e6636e034ece04fd542f9deb4a94b14871432",
739
771
  "9fb2bb484494751d0888a37d0de4d1b72fb2efb5453a8b0204de9fc8254a4595",
740
772
  "a045cf85544fd3b3c71c6ff5da52656247b81a8d22828f1d01e677704859e6b4",
741
773
  "a04d86da6195f71926bee98cc812b61497a0948cd60e2b235712de2215af7d4b",
742
774
  "a053c180750405173ec7141081081d171df1aa74ef62a3c8854b6f7f61a9e659",
775
+ "a10a5a7838269e918a14d99e09bf54162b7f5e460ff488d068e420aa63180af7",
743
776
  "a219da47dd42cfbfcc808a6f00279ba87b2bbe1928ee009434bcb4ffa71e790d",
744
777
  "a292850ee0ceb0549d2e0cd50e48c8596594a509597f7210f59acbad7b45b475",
745
778
  "a2b7ab33386255547ecd6fce85b574d0354ef8e93d2bafb58e0cb77d7fee46b7",
@@ -769,6 +802,7 @@
769
802
  "ae165ed9dd87a9a0cc44e6aedecda36e7baf30f906387b6b61498b15024e6ebd",
770
803
  "aee00431c6f1093dabf9f28ac906e6769e6a637bd7029b260e20c44120470ca5",
771
804
  "af009f3b01fe6d41be46d0992a74c1a3d0681264b72a1a344cb14e787c770a65",
805
+ "af35a3eee2e642bb1d32390efdcceb3de4558287e8b26d7c40df0e521cd00a3c",
772
806
  "b0bfa637d2cae4be520471a45c0503f517400c6bf30cd394318fcd28b0bf6df1",
773
807
  "b240b9b48eb5404781c4985878ebb29781bd9cd8d943796ea545a043847a696d",
774
808
  "b248b5c31b014ad5505bca439a714a0834f9c57b7132f8b5077c4369cc49279a",
@@ -776,6 +810,7 @@
776
810
  "b306b9a953a3fb5a9e15315099b7fa31bdac076f17b66ebc9259141ab1a47e98",
777
811
  "b38536c283085dced3d955f6d4e44709c2bf5e64111dc7c637593e36415aabbe",
778
812
  "b5aee45614a24eed18f2e4bc840a8065c8143717b41259c0c6a6f5fcda10c55b",
813
+ "b5ed93204a83bd43b1514c92330d41f7e30696fbb78243c934abcb264a2158c0",
779
814
  "b5eefabd99457de1df2edbe78d22ee3967c18c83975657f17d15c18abb4df28e",
780
815
  "b6ca70dfc1111cd1a43bf89e2a46459af77dfce229922f148a6f289fdd650691",
781
816
  "b72e4d316502751c6e43d943580182ece074d509fd520c097f782e206239ceb9",
@@ -793,6 +828,7 @@
793
828
  "bb88e23401b6d11ef9a198107a30eed055c5d21b589738a3f74ddd39b4d76701",
794
829
  "bba69a83c7459bb44e4558051ead063003c7d152be222cbdb250008dbd9d64cf",
795
830
  "bc2ed35fa458e1fb26fd52c14220622c1f9d5dc95a69ab888209949f26400cf9",
831
+ "bc94dea221397fcfca8011c44d7b05790d60a51bbfe35f8d5bef4aaa1b3f3002",
796
832
  "bd222e31dc5ecfdd8f1539aaf9d13f7c5f454113e65924f78060dd0e92974653",
797
833
  "be11c198a50be2884c4c1efec52bbddff55c7547a5daf0ec2ef046279c95dc45",
798
834
  "be49c865c8b78d714cd68baeace35163cf96ecc5c7ed5c7e2a4d5f46c7b1a8e6",
@@ -843,8 +879,11 @@
843
879
  "d19be0bfb42f1790c5b6ca1937208eea906828ff2a4ca3db9898efec50ba6fd3",
844
880
  "d1da83f9946ab02cfad62623784b08a52f3f063976ab9b0c5e8a43131aa10078",
845
881
  "d230016fd8ff7318169ccafa4ac50d94d9b8191370bc8b13149d8d58bfced9d0",
882
+ "d313ee61489edaf0c72ee2e70ee3a46b534ffbc49f02404c4516073bf16d2c91",
846
883
  "d36ca232e2f764ac114976ac179955a798824a148ff5a8e11fdab96428a0aa86",
847
884
  "d37bd6a360ef6f6d4ebc51c3fa9190021a350b68539750aff77682a67b48bb90",
885
+ "d3df16f5c755d614c644ac33c397e6ece6b0d3ddc4b18de70d45b2b938311248",
886
+ "d496c0136a48c3ee3de3fd8dbed8e0ebc649d906c507722993b9c5833239d49b",
848
887
  "d4bd7c282f4e5566a8c3d3500683801cb36d7fe41cd7c385fa10c38755dd4aa5",
849
888
  "d52b18bf2bf26813548370212ba9eef13360679c97baae313b87d2b5dea4ea88",
850
889
  "d58f34824ea64c3bcacb13c797c8ea68623288bc0d5280d12fa0af27a511acb1",
@@ -928,11 +967,13 @@
928
967
  "fd12c4da9cc5df8a0b41e98e30e3a6bfcce31902f860be541145d77ed458dda8",
929
968
  "fd8befbc4061f2476c8edb97982043a7ce43caa4b3a529f472ae191f5d9b81fd",
930
969
  "fe0bac647b061b1974ab623fbacd72865d7aec39969e2f4585b939abbcb43d6a",
970
+ "fe77333774ef88faae6fa95402d7ced6f9caa18d6c97406aca0d934f5e700891",
931
971
  "ff03ba1ce6021d1d81f710084d8fdda61cd3a38c2e4f7252ae2eae94bb7ba5d9",
932
972
  "ff2b34264a111ea52124a016fe6fdba437ca5752a183a9a80b8d5abc9be6ba0f",
933
973
  "ff39e0c8a38e75a76c5abb3ae3ab87fd6c7aa75fc40b2b9e269d99aaca02b30e",
934
974
  "ff6cc2213ac0ba09985ec631ac5320fd356f783e373b6e8a347cb7f88fd14f5c",
935
- "ff7303737742c55a8806c655cab4a65abf3fc0fcf1f96b50a5a1a534ed3148ff"
975
+ "ff7303737742c55a8806c655cab4a65abf3fc0fcf1f96b50a5a1a534ed3148ff",
976
+ "ffd4b4af5ab9f5b4682e69a4a729df3dea59b98cc95e5724e0e4498e74a71e8d"
936
977
  ]
937
978
  }
938
979
  }