claude-dev-env 8.85.0 → 8.85.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.
@@ -3,9 +3,6 @@ import { dirname, join, resolve } from 'node:path';
3
3
 
4
4
  export const SKILL_LOAD_BLOCK_START = '<!-- claude-dev-env skill load: start -->';
5
5
  export const SKILL_LOAD_BLOCK_END = '<!-- claude-dev-env skill load: end -->';
6
- export const SKILL_LOAD_INSTRUCTION = 'Load the pstack:poteto-mode skill before your first tool call or reply: '
7
- + 'open its SKILL.md from your skills list and follow it. This binds every Codex agent, '
8
- + 'including a helper started with spawn_agent, whatever its task message says.';
9
6
  export const PACKAGE_GUIDANCE_BLOCK_START = '<!-- claude-dev-env package guidance: start -->';
10
7
  export const PACKAGE_GUIDANCE_BLOCK_END = '<!-- claude-dev-env package guidance: end -->';
11
8
  export const QUESTION_PRESENTATION_BLOCK_START = '<!-- claude-dev-env question presentation: start -->';
@@ -39,17 +36,24 @@ function withBlockReplaced(guidanceText, blockStart, blockEnd, block) {
39
36
  }
40
37
 
41
38
  /**
42
- * Return the Codex guidance text with the package's skill-load block in it.
39
+ * Return guidance text with every complete skill-load block removed.
43
40
  *
44
- * Codex starts a spawn_agent helper without running any hook, so the global
45
- * AGENTS.md is the one channel that reaches every helper. A block already in
46
- * the text is replaced where it stands; otherwise the block goes first.
41
+ * When a block is the start of the remaining text, one following blank line is
42
+ * removed with it. A start marker with no end marker stays.
47
43
  */
48
- export function withSkillLoadBlock(guidanceText) {
49
- const block = managedBlock(SKILL_LOAD_BLOCK_START, SKILL_LOAD_INSTRUCTION, SKILL_LOAD_BLOCK_END);
50
- const replacedText = withBlockReplaced(guidanceText, SKILL_LOAD_BLOCK_START, SKILL_LOAD_BLOCK_END, block);
51
- if (replacedText !== null) return replacedText;
52
- return guidanceText ? `${block}\n${guidanceText}` : block;
44
+ export function withoutSkillLoadBlock(guidanceText) {
45
+ let remainingText = guidanceText;
46
+ let removedBlockCount = 0;
47
+ while (remainingText.includes(SKILL_LOAD_BLOCK_START)) {
48
+ const blockStartsAtTop = remainingText.startsWith(SKILL_LOAD_BLOCK_START);
49
+ const replacedText = withBlockReplaced(remainingText, SKILL_LOAD_BLOCK_START, SKILL_LOAD_BLOCK_END, '');
50
+ if (replacedText === null || replacedText === remainingText) break;
51
+ removedBlockCount += 1;
52
+ remainingText = blockStartsAtTop && replacedText.startsWith('\n')
53
+ ? replacedText.slice(1)
54
+ : replacedText;
55
+ }
56
+ return removedBlockCount === 0 ? guidanceText : remainingText;
53
57
  }
54
58
 
55
59
  function withPackageGuidanceBlock(guidanceText, packageGuidanceText) {
@@ -84,7 +88,7 @@ function writeCodexGuidanceFile(codexHome, allPackageGuidancePaths, transformGui
84
88
  const isPackageGuidanceLink = agentsEntry?.isSymbolicLink() ?? false;
85
89
  if (isPackageGuidanceLink && !linksToPackageGuidance(agentsPath, allPackageGuidancePaths)) return null;
86
90
  const currentText = agentsEntry && !isPackageGuidanceLink ? readFileSync(agentsPath, 'utf8') : '';
87
- const updatedText = transformGuidance(currentText);
91
+ const updatedText = transformGuidance(withoutSkillLoadBlock(currentText));
88
92
  if (!isPackageGuidanceLink && updatedText === currentText) return null;
89
93
  mkdirSync(codexHome, { recursive: true });
90
94
  if (isPackageGuidanceLink) unlinkSync(agentsPath);
@@ -93,29 +97,24 @@ function writeCodexGuidanceFile(codexHome, allPackageGuidancePaths, transformGui
93
97
  }
94
98
 
95
99
  /**
96
- * Keep CODEX_HOME/AGENTS.md carrying the skill-load block and the package guidance.
97
- *
98
- * The skill-load block goes first, and the package-guidance block holds the
99
- * current guidance text. A symbolic link that points at the package guidance
100
- * (the shared agents-home copy, or the retired copy under the Claude home) is
101
- * replaced by a regular file holding both blocks, so Codex keeps both after
102
- * the package moves its guidance. A link to any other file is left alone.
100
+ * Remove a skill-load block and write package guidance into CODEX_HOME/AGENTS.md.
103
101
  *
104
- * Returns the file path when the file changed, and null otherwise.
102
+ * Link handling matches writeCodexPackageGuidance. Returns the file path when
103
+ * the file changed, and null otherwise.
105
104
  */
106
105
  export function writeCodexAgentsGuidance(codexHome, packageGuidanceText, allPackageGuidancePaths) {
107
- return writeCodexGuidanceFile(
108
- codexHome,
109
- allPackageGuidancePaths,
110
- currentText => withPackageGuidanceBlock(withSkillLoadBlock(currentText), packageGuidanceText),
111
- );
106
+ return writeCodexPackageGuidance(codexHome, packageGuidanceText, allPackageGuidancePaths);
112
107
  }
113
108
 
114
109
  /**
115
110
  * Keep CODEX_HOME/AGENTS.md carrying the package guidance, with no skill-load block.
116
111
  *
117
- * Links follow the same rule as writeCodexAgentsGuidance. Returns the file
118
- * path when the file changed, and null otherwise.
112
+ * An existing skill-load block is removed. A symbolic link that points at the
113
+ * package guidance, the shared agents-home copy or the retired copy under the
114
+ * Claude home, is replaced by a regular file. A link to any other file is left
115
+ * alone.
116
+ *
117
+ * Returns the file path when the file changed, and null otherwise.
119
118
  */
120
119
  export function writeCodexPackageGuidance(codexHome, packageGuidanceText, allPackageGuidancePaths) {
121
120
  return writeCodexGuidanceFile(
@@ -10,11 +10,10 @@ import {
10
10
  QUESTION_PRESENTATION_BLOCK_START,
11
11
  SKILL_LOAD_BLOCK_END,
12
12
  SKILL_LOAD_BLOCK_START,
13
- SKILL_LOAD_INSTRUCTION,
14
13
  removeCodexDeepenGuidance,
15
14
  removeCodexPackageGuidance,
16
15
  removeCodexQuestionGuidance,
17
- withSkillLoadBlock,
16
+ withoutSkillLoadBlock,
18
17
  DEEPEN_GUIDANCE_BLOCK_END,
19
18
  DEEPEN_GUIDANCE_BLOCK_START,
20
19
  DEEPEN_GUIDANCE_TEXT,
@@ -24,7 +23,10 @@ import {
24
23
  writeCodexQuestionGuidance,
25
24
  } from './codex-skill-load-block.mjs';
26
25
 
27
- const EXPECTED_BLOCK = `${SKILL_LOAD_BLOCK_START}\n${SKILL_LOAD_INSTRUCTION}\n${SKILL_LOAD_BLOCK_END}\n`;
26
+ const STALE_SKILL_LOAD_SENTENCE = 'Load the pstack:poteto-mode skill before your first tool call or reply: '
27
+ + 'open its SKILL.md from your skills list and follow it. This binds every Codex agent, '
28
+ + 'including a helper started with spawn_agent, whatever its task message says.';
29
+ const STALE_SKILL_LOAD_BLOCK = `${SKILL_LOAD_BLOCK_START}\n${STALE_SKILL_LOAD_SENTENCE}\n${SKILL_LOAD_BLOCK_END}\n`;
28
30
  const PACKAGE_GUIDANCE = 'Status\n\nChanged / proof / blocked.\n';
29
31
  const QUESTION_POLICY = '# Present questions clearly\n\nAsk one question.\n';
30
32
 
@@ -52,34 +54,44 @@ function writeGuidance(homes) {
52
54
  return writeCodexAgentsGuidance(homes.codexHome, PACKAGE_GUIDANCE, homes.allPackageGuidancePaths);
53
55
  }
54
56
 
55
- test('the instruction names the skill and binds spawned helpers', () => {
56
- assert.match(SKILL_LOAD_INSTRUCTION, /pstack:poteto-mode/);
57
- assert.match(SKILL_LOAD_INSTRUCTION, /spawn_agent/);
57
+ test('a complete skill-load block is removed and the lines around it stay', () => {
58
+ assert.equal(withoutSkillLoadBlock(`Intro\n${STALE_SKILL_LOAD_BLOCK}Outro\n`), 'Intro\nOutro\n');
59
+ assert.equal(withoutSkillLoadBlock(`${STALE_SKILL_LOAD_BLOCK}\nNotes\n`), 'Notes\n');
60
+ assert.equal(
61
+ withoutSkillLoadBlock(`${STALE_SKILL_LOAD_BLOCK}\n${STALE_SKILL_LOAD_BLOCK}\nNotes\n`),
62
+ 'Notes\n',
63
+ );
64
+ assert.equal(
65
+ withoutSkillLoadBlock(`${SKILL_LOAD_BLOCK_START}\nHalf a block\n`),
66
+ `${SKILL_LOAD_BLOCK_START}\nHalf a block\n`,
67
+ );
58
68
  });
59
69
 
60
- test('a missing Codex guidance file is created holding the skill-load block and the package guidance', (context) => {
70
+ test('a missing Codex guidance file is created holding the package guidance', (context) => {
61
71
  const homes = makeHomes(context);
62
72
 
63
73
  const writtenPath = writeGuidance(homes);
64
74
 
65
75
  assert.equal(writtenPath, homes.agentsPath);
66
- assert.equal(
67
- readFileSync(homes.agentsPath, 'utf8'),
68
- `${EXPECTED_BLOCK}\n${guidanceBlock(PACKAGE_GUIDANCE)}`,
69
- );
76
+ const rendered = readFileSync(homes.agentsPath, 'utf8');
77
+ assert.equal(rendered, guidanceBlock(PACKAGE_GUIDANCE));
78
+ assert.equal(rendered.includes('pstack:poteto-mode'), false);
79
+ assert.equal(rendered.includes(SKILL_LOAD_BLOCK_START), false);
70
80
  });
71
81
 
72
- test('existing guidance keeps every line between the skill-load block and the package guidance', (context) => {
82
+ test('existing guidance keeps its lines and gains the package guidance', (context) => {
73
83
  const homes = makeHomes(context);
74
84
  mkdirSync(homes.codexHome);
75
85
  writeFileSync(homes.agentsPath, '# pstack model configuration\n\nbug-fix: gpt-6-astra\n');
76
86
 
77
87
  writeGuidance(homes);
78
88
 
89
+ const rendered = readFileSync(homes.agentsPath, 'utf8');
79
90
  assert.equal(
80
- readFileSync(homes.agentsPath, 'utf8'),
81
- `${EXPECTED_BLOCK}\n# pstack model configuration\n\nbug-fix: gpt-6-astra\n\n${guidanceBlock(PACKAGE_GUIDANCE)}`,
91
+ rendered,
92
+ `# pstack model configuration\n\nbug-fix: gpt-6-astra\n\n${guidanceBlock(PACKAGE_GUIDANCE)}`,
82
93
  );
94
+ assert.equal(rendered.includes('pstack:poteto-mode'), false);
83
95
  });
84
96
 
85
97
  test('a repeat install leaves the file unchanged and reports no write', (context) => {
@@ -93,20 +105,43 @@ test('a repeat install leaves the file unchanged and reports no write', (context
93
105
  assert.equal(readFileSync(homes.agentsPath, 'utf8'), afterFirstInstall);
94
106
  });
95
107
 
96
- test('an outdated block is replaced in place and the text around it is kept', () => {
97
- const outdated = `Intro\n${SKILL_LOAD_BLOCK_START}\nOld wording\n${SKILL_LOAD_BLOCK_END}\nOutro\n`;
108
+ test('a stale skill-load sentence is removed and question and deepen blocks stay', (context) => {
109
+ const homes = makeHomes(context);
110
+ mkdirSync(homes.codexHome);
111
+ const questionBlock = `${QUESTION_PRESENTATION_BLOCK_START}\n${QUESTION_POLICY}${QUESTION_PRESENTATION_BLOCK_END}\n`;
112
+ const deepenBlock = `${DEEPEN_GUIDANCE_BLOCK_START}\n${DEEPEN_GUIDANCE_TEXT}\n${DEEPEN_GUIDANCE_BLOCK_END}\n`;
113
+ writeFileSync(
114
+ homes.agentsPath,
115
+ `${STALE_SKILL_LOAD_BLOCK}\n${guidanceBlock('Old guidance\n')}${questionBlock}${deepenBlock}`,
116
+ );
98
117
 
99
- assert.equal(withSkillLoadBlock(outdated), `Intro\n${EXPECTED_BLOCK}Outro\n`);
118
+ writeGuidance(homes);
119
+
120
+ const rendered = readFileSync(homes.agentsPath, 'utf8');
121
+ assert.equal(rendered.includes(STALE_SKILL_LOAD_SENTENCE), false);
122
+ assert.equal(rendered.includes('pstack:poteto-mode'), false);
123
+ assert.equal(rendered.includes(SKILL_LOAD_BLOCK_START), false);
124
+ assert.ok(rendered.includes(guidanceBlock(PACKAGE_GUIDANCE)));
125
+ assert.ok(rendered.includes(questionBlock));
126
+ assert.ok(rendered.includes(deepenBlock));
100
127
  });
101
128
 
102
- test('a start marker with no end marker gets a fresh block and keeps the stray text', () => {
129
+ test('a start marker with no end marker stays and no skill name is added', (context) => {
130
+ const homes = makeHomes(context);
103
131
  const broken = `${SKILL_LOAD_BLOCK_START}\nHalf a block\n`;
132
+ mkdirSync(homes.codexHome);
133
+ writeFileSync(homes.agentsPath, broken);
134
+
135
+ writeGuidance(homes);
104
136
 
105
- assert.equal(withSkillLoadBlock(broken), `${EXPECTED_BLOCK}\n${broken}`);
137
+ const rendered = readFileSync(homes.agentsPath, 'utf8');
138
+ assert.ok(rendered.startsWith(broken));
139
+ assert.equal(rendered.includes('pstack:poteto-mode'), false);
140
+ assert.ok(rendered.includes(PACKAGE_GUIDANCE_BLOCK_START));
106
141
  });
107
142
 
108
143
  for (const linkName of ['retiredGuidancePath', 'sharedGuidancePath']) {
109
- test(`a link to package guidance at ${linkName} becomes a file with both blocks`, (context) => {
144
+ test(`a link to package guidance at ${linkName} becomes a file with the package block`, (context) => {
110
145
  const homes = makeHomes(context);
111
146
  mkdirSync(homes.codexHome);
112
147
  symlinkSync(homes[linkName], homes.agentsPath);
@@ -115,24 +150,21 @@ for (const linkName of ['retiredGuidancePath', 'sharedGuidancePath']) {
115
150
 
116
151
  assert.equal(writtenPath, homes.agentsPath);
117
152
  assert.equal(lstatSync(homes.agentsPath).isSymbolicLink(), false);
118
- assert.equal(
119
- readFileSync(homes.agentsPath, 'utf8'),
120
- `${EXPECTED_BLOCK}\n${guidanceBlock(PACKAGE_GUIDANCE)}`,
121
- );
153
+ assert.equal(readFileSync(homes.agentsPath, 'utf8'), guidanceBlock(PACKAGE_GUIDANCE));
154
+ assert.equal(readFileSync(homes.agentsPath, 'utf8').includes('pstack:poteto-mode'), false);
122
155
  });
123
156
  }
124
157
 
125
- test('a converted file takes the new package guidance on the next install', (context) => {
158
+ test('a converted file takes the new package guidance and drops a stale skill-load block', (context) => {
126
159
  const homes = makeHomes(context);
127
160
  mkdirSync(homes.codexHome);
128
- writeFileSync(homes.agentsPath, `${EXPECTED_BLOCK}\n${guidanceBlock('Old guidance\n')}`);
161
+ writeFileSync(homes.agentsPath, `${STALE_SKILL_LOAD_BLOCK}\n${guidanceBlock('Old guidance\n')}`);
129
162
 
130
163
  writeGuidance(homes);
131
164
 
132
- assert.equal(
133
- readFileSync(homes.agentsPath, 'utf8'),
134
- `${EXPECTED_BLOCK}\n${guidanceBlock(PACKAGE_GUIDANCE)}`,
135
- );
165
+ const rendered = readFileSync(homes.agentsPath, 'utf8');
166
+ assert.equal(rendered, guidanceBlock(PACKAGE_GUIDANCE));
167
+ assert.equal(rendered.includes('pstack:poteto-mode'), false);
136
168
  });
137
169
 
138
170
  test('a link to a file the package does not own is left alone', (context) => {
package/bin/install.mjs CHANGED
@@ -2927,13 +2927,13 @@ function executeInstallPlanMutations(plan, transactionHelpers) {
2927
2927
  allUserOwnedPreferencePaths.add(eachPath);
2928
2928
  }
2929
2929
  }
2930
- const skillLoadGuidancePath = writeCodexAgentsGuidance(
2930
+ const codexGuidancePath = writeCodexAgentsGuidance(
2931
2931
  INSTALL_ROOT_RESOLUTION.codexHomeDirectory,
2932
2932
  packageGuidanceText,
2933
2933
  allPackageGuidancePaths,
2934
2934
  );
2935
- if (skillLoadGuidancePath) {
2936
- console.log(` \u2713 ${skillLoadGuidancePath} (Codex skill-load line)`);
2935
+ if (codexGuidancePath) {
2936
+ console.log(` \u2713 ${codexGuidancePath} (Codex package guidance)`);
2937
2937
  }
2938
2938
  }
2939
2939
  printPluginHostOutcomes([PSTACK_PLUGIN_SPEC], pstackPlugin);
@@ -171,7 +171,7 @@ test('a selected Claude profile receives the source rule and its Codex guidance'
171
171
  assert.ok(readFileSync(join(profileDirectory, '.codex', 'AGENTS.md'), 'utf8').includes(readFileSync(policyPath, 'utf8')));
172
172
  });
173
173
 
174
- test('a successful pstack install retains its skill block and gains the question block', (context) => {
174
+ test('a successful pstack install omits the retired skill block and gains the question block', (context) => {
175
175
  const homeDirectory = makeScratchHome(context);
176
176
  const commandPath = join(homeDirectory, process.platform === 'win32' ? 'codex.cmd' : 'codex');
177
177
  writeFileSync(
@@ -191,7 +191,7 @@ test('a successful pstack install retains its skill block and gains the question
191
191
 
192
192
  assert.equal(installation.status, 0, installation.stdout + installation.stderr);
193
193
  const guidanceText = readFileSync(join(homeDirectory, '.codex', 'AGENTS.md'), 'utf8');
194
- assert.match(guidanceText, /<!-- claude-dev-env skill load: start -->/);
194
+ assert.doesNotMatch(guidanceText, /<!-- claude-dev-env skill load: start -->/);
195
195
  assert.match(guidanceText, /<!-- claude-dev-env question presentation: start -->/);
196
196
  assert.ok(guidanceText.includes(readFileSync(policyPath, 'utf8')));
197
197
  });
@@ -221,7 +221,7 @@ test('enabling pstack after a pstack-off install preserves question guidance', (
221
221
  assert.equal(secondInstallation.status, 0, secondInstallation.stdout + secondInstallation.stderr);
222
222
  const updatedGuidance = readFileSync(codexGuidancePath, 'utf8');
223
223
  assert.ok(updatedGuidance.includes(firstGuidance));
224
- assert.match(updatedGuidance, /<!-- claude-dev-env skill load: start -->/);
224
+ assert.doesNotMatch(updatedGuidance, /<!-- claude-dev-env skill load: start -->/);
225
225
  assert.match(updatedGuidance, /^feature, refactoring: gpt-6-sol$/m);
226
226
  assert.match(readFileSync(join(homeDirectory, '.codex', 'pstack-models.md'), 'utf8'), /^session hook: on$/m);
227
227
  });
@@ -57,12 +57,12 @@ import {
57
57
  } from './install.mjs';
58
58
  import { EVER_SHIPPED_SKILL_NAMES } from './ever-shipped-skills.mjs';
59
59
  import {
60
+ DEEPEN_GUIDANCE_BLOCK_START,
60
61
  PACKAGE_GUIDANCE_BLOCK_END,
61
62
  PACKAGE_GUIDANCE_BLOCK_START,
62
- SKILL_LOAD_BLOCK_START,
63
- SKILL_LOAD_INSTRUCTION,
64
63
  QUESTION_PRESENTATION_BLOCK_START,
65
- withSkillLoadBlock,
64
+ SKILL_LOAD_BLOCK_END,
65
+ SKILL_LOAD_BLOCK_START,
66
66
  } from './codex-skill-load-block.mjs';
67
67
 
68
68
 
@@ -3124,6 +3124,17 @@ function pstackPluginSandbox(t) {
3124
3124
  };
3125
3125
  }
3126
3126
 
3127
+ const STALE_SKILL_LOAD_SENTENCE = 'Load the pstack:poteto-mode skill before your first tool call or reply: '
3128
+ + 'open its SKILL.md from your skills list and follow it. This binds every Codex agent, '
3129
+ + 'including a helper started with spawn_agent, whatever its task message says.';
3130
+
3131
+ function assertOmitsSkillLoadSentence(codexGuidance) {
3132
+ assert.equal(codexGuidance.includes(SKILL_LOAD_BLOCK_START), false);
3133
+ assert.equal(codexGuidance.includes(SKILL_LOAD_BLOCK_END), false);
3134
+ assert.equal(codexGuidance.includes('pstack:poteto-mode'), false);
3135
+ assert.equal(codexGuidance.includes(STALE_SKILL_LOAD_SENTENCE), false);
3136
+ }
3137
+
3127
3138
  test('a full install adds the pstack marketplace and plugin on both hosts', t => {
3128
3139
  const sandbox = pstackPluginSandbox(t);
3129
3140
 
@@ -3145,9 +3156,10 @@ test('a full install adds the pstack marketplace and plugin on both hosts', t =>
3145
3156
  const sheet = readFileSync(join(codexHome, 'pstack-models.md'), 'utf8');
3146
3157
  const agents = readFileSync(join(codexHome, 'AGENTS.md'), 'utf8');
3147
3158
  assert.match(sheet, /^session hook: on$/m);
3159
+ assert.match(agents, /^# pstack model configuration\n/);
3148
3160
  assert.match(agents, /^feature, refactoring: gpt-6-sol$/m);
3149
3161
  assert.doesNotMatch(agents, /^session hook:/m);
3150
- assert.ok(agents.startsWith(`${SKILL_LOAD_BLOCK_START}\n${SKILL_LOAD_INSTRUCTION}\n`));
3162
+ assertOmitsSkillLoadSentence(agents);
3151
3163
  assert.equal(existsSync(join(sandbox.homeDirectory, '.claude', 'pstack-models.md')), false);
3152
3164
  const manifestPath = join(sandbox.homeDirectory, '.claude', '.claude-dev-env-manifest.json');
3153
3165
  const manifest = JSON.parse(readFileSync(manifestPath, 'utf8'));
@@ -3159,14 +3171,19 @@ test('a repeat install preserves Codex pstack configuration', t => {
3159
3171
  const sandbox = pstackPluginSandbox(t);
3160
3172
  const codexHome = join(sandbox.homeDirectory, '.codex');
3161
3173
  runPstackInstaller(sandbox.homeDirectory, [], sandbox.environment);
3162
- writeFileSync(join(codexHome, 'AGENTS.md'), 'Custom Codex guidance\n');
3174
+ writeFileSync(
3175
+ join(codexHome, 'AGENTS.md'),
3176
+ `${SKILL_LOAD_BLOCK_START}\n${STALE_SKILL_LOAD_SENTENCE}\n${SKILL_LOAD_BLOCK_END}\nCustom Codex guidance\n`,
3177
+ );
3163
3178
  writeFileSync(join(codexHome, 'pstack-models.md'), 'session hook: off\n');
3164
3179
 
3165
3180
  runPstackInstaller(sandbox.homeDirectory, [], sandbox.environment);
3166
3181
 
3167
3182
  const codexGuidance = readFileSync(join(codexHome, 'AGENTS.md'), 'utf8');
3168
- assert.ok(codexGuidance.startsWith(withSkillLoadBlock('Custom Codex guidance\n')));
3183
+ assert.ok(codexGuidance.startsWith('Custom Codex guidance\n'));
3184
+ assertOmitsSkillLoadSentence(codexGuidance);
3169
3185
  assert.ok(codexGuidance.includes(QUESTION_PRESENTATION_BLOCK_START));
3186
+ assert.ok(codexGuidance.includes(DEEPEN_GUIDANCE_BLOCK_START));
3170
3187
  assert.equal(readFileSync(join(codexHome, 'pstack-models.md'), 'utf8'), 'session hook: off\n');
3171
3188
  });
3172
3189
 
@@ -3185,7 +3202,7 @@ test('a Codex guidance link to the retired Claude copy becomes a file Codex can
3185
3202
  );
3186
3203
  assert.equal(lstatSync(codexAgentsPath).isSymbolicLink(), false);
3187
3204
  const codexGuidance = readFileSync(codexAgentsPath, 'utf8');
3188
- assert.ok(codexGuidance.startsWith(`${SKILL_LOAD_BLOCK_START}\n${SKILL_LOAD_INSTRUCTION}\n`));
3205
+ assertOmitsSkillLoadSentence(codexGuidance);
3189
3206
  assert.ok(codexGuidance.includes(packageGuidance));
3190
3207
  });
3191
3208
 
@@ -3248,8 +3265,9 @@ test('a fresh full install writes the package guidance into Codex AGENTS.md', t
3248
3265
 
3249
3266
  const codexGuidance = readFileSync(join(sandbox.homeDirectory, '.codex', 'AGENTS.md'), 'utf8');
3250
3267
  assertHoldsPackageGuidance(codexGuidance);
3251
- assert.ok(codexGuidance.startsWith(`${SKILL_LOAD_BLOCK_START}\n${SKILL_LOAD_INSTRUCTION}\n`));
3268
+ assertOmitsSkillLoadSentence(codexGuidance);
3252
3269
  assert.ok(codexGuidance.includes(QUESTION_PRESENTATION_BLOCK_START));
3270
+ assert.ok(codexGuidance.includes(DEEPEN_GUIDANCE_BLOCK_START));
3253
3271
  });
3254
3272
 
3255
3273
  test('--no-pstack writes package and question guidance without the skill-load block', t => {
@@ -3329,9 +3347,10 @@ test('a pstack install after a --no-pstack install seeds the Codex model sheet',
3329
3347
  assert.match(readFileSync(join(codexHome, 'pstack-models.md'), 'utf8'), /^session hook: on$/m);
3330
3348
  const codexGuidance = readFileSync(join(codexHome, 'AGENTS.md'), 'utf8');
3331
3349
  assert.match(codexGuidance, /^feature, refactoring: gpt-6-sol$/m);
3332
- assert.ok(codexGuidance.startsWith(`${SKILL_LOAD_BLOCK_START}\n${SKILL_LOAD_INSTRUCTION}\n`));
3350
+ assertOmitsSkillLoadSentence(codexGuidance);
3333
3351
  assertHoldsPackageGuidance(codexGuidance);
3334
3352
  assert.ok(codexGuidance.includes(QUESTION_PRESENTATION_BLOCK_START));
3353
+ assert.ok(codexGuidance.includes(DEEPEN_GUIDANCE_BLOCK_START));
3335
3354
  });
3336
3355
 
3337
3356
  const USAGE_WRAPUP_CLAUDE_COMMANDS = Object.freeze([
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-dev-env",
3
- "version": "8.85.0",
3
+ "version": "8.85.1",
4
4
  "description": "Claude Code development standards — rules, hooks, agents, commands, and skills",
5
5
  "type": "module",
6
6
  "bin": {