claude-dev-env 8.82.1 → 8.83.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.
- package/.agents/skills/deepen/SKILL.md +42 -0
- package/bin/codex-skill-load-block.mjs +32 -0
- package/bin/codex-skill-load-block.test.mjs +27 -0
- package/bin/codex-trimmed-sol.test.mjs +1 -0
- package/bin/ever-shipped-skills.mjs +1 -0
- package/bin/install-pstack-plugin.mjs +12 -0
- package/bin/install-pstack-plugin.test.mjs +23 -0
- package/bin/install.agents-home.test.mjs +1 -0
- package/bin/install.codex-rules.test.mjs +2 -0
- package/bin/install.cursor-rules.test.mjs +38 -1
- package/bin/install.mjs +34 -2
- package/bin/install.prompt-context.test.mjs +3 -1
- package/bin/install.prune.test.mjs +1 -0
- package/bin/install.question-presentation.test.mjs +4 -0
- package/bin/install.settings-defaults.test.mjs +1 -0
- package/bin/install.shared-settings.test.mjs +1 -0
- package/bin/install.test.mjs +34 -1
- package/bin/install.transaction.test.mjs +8 -0
- package/bin/install.uninstall-transaction.test.mjs +2 -0
- package/bin/install.update-keeps-hooks.test.mjs +1 -0
- package/commands/deepen.md +19 -0
- package/docs/account-broker.md +1 -1
- package/docs/rule-guides/agent-board.md +27 -0
- package/docs/rule-guides/features-start-with-an-eval.md +4 -2
- package/docs/rule-guides/proof-before-pull-request.md +1 -1
- package/hooks/blocking/build_eval_before_eval_write_gate.py +102 -0
- package/hooks/blocking/pr_lifecycle_skill_gate.py +42 -16
- package/hooks/blocking/pull_request_proof.py +111 -2
- package/hooks/blocking/reply_length_gate.py +69 -13
- package/hooks/blocking/test_build_eval_before_eval_write_gate.py +162 -0
- package/hooks/blocking/test_pr_lifecycle_skill_gate.py +25 -0
- package/hooks/blocking/test_pull_request_proof.py +115 -0
- package/hooks/blocking/test_reply_length_gate.py +98 -10
- package/hooks/context_budget/tests/test_model.py +65 -0
- package/hooks/features/conduct-gates.md +4 -0
- package/hooks/features/lifecycle-cleanup.md +1 -1
- package/hooks/features/session-context.md +3 -0
- package/hooks/hooks.json +20 -0
- package/hooks/hooks_constants/build_eval_before_eval_write_gate_constants.py +19 -0
- package/hooks/hooks_constants/deepen_first_prompt_constants.py +119 -0
- package/hooks/hooks_constants/mod_handoff_constants.py +2 -0
- package/hooks/hooks_constants/nested_project_hooks_constants.py +2 -0
- package/hooks/hooks_constants/pull_request_proof_constants.py +38 -0
- package/hooks/hooks_constants/reply_length_gate_constants.py +14 -0
- package/hooks/hooks_constants/test_reply_length_gate_constants.py +8 -0
- package/hooks/lifecycle/nested_project_hooks.py +17 -8
- package/hooks/lifecycle/test_nested_project_hooks.py +50 -0
- package/hooks/session/deepen_first_prompt.py +390 -0
- package/hooks/session/test_deepen_first_prompt.py +274 -0
- package/hooks/test_transcript_skill_scan.py +6 -2
- package/hooks/transcript_skill_scan.py +18 -7
- package/package.json +1 -1
- package/rules/agent-board.md +9 -0
- package/rules/index.md +1 -1
- package/scripts/account_broker.py +1 -0
- package/scripts/account_broker_support.py +71 -24
- package/scripts/ci/install-playtest.mjs +329 -2
- package/scripts/ci/install-playtest.test.mjs +6 -0
- package/scripts/dev_env_scripts_constants/account_broker_constants.py +11 -3
- package/scripts/dev_env_scripts_constants/test_account_broker_constants.py +15 -0
- package/scripts/policy_lint/adapter_configuration.py +5 -0
- package/scripts/policy_lint/config/constants.py +1 -0
- package/scripts/test_account_broker.py +19 -1
- package/scripts/test_account_broker_support.py +161 -3
- package/scripts/tests/test_adapter_configuration.py +8 -0
- package/scripts/tests/test_rule_load_scopes.py +1 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: deepen
|
|
3
|
+
description: >-
|
|
4
|
+
Deepen a first user task before work starts. Triggers: /deepen, deepen this
|
|
5
|
+
task, first-task deepening, Cursor Cloud launch prompt.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# deepen
|
|
9
|
+
|
|
10
|
+
Rewrite a user task so the worker does the omitted expert job. Keep the rewrite short.
|
|
11
|
+
|
|
12
|
+
## When this applies
|
|
13
|
+
|
|
14
|
+
- An interactive first user task on Claude Code, Cursor, or Codex
|
|
15
|
+
- `/deepen` with a task in the arguments
|
|
16
|
+
- Cursor Cloud, where user `~/.cursor/hooks.json` does not run and `sessionStart` is deferred, so the launch prompt is already sent
|
|
17
|
+
|
|
18
|
+
Skip when the prompt already carries `CDE_DEEPEN:v1`, when the text is a thanks or yes/no or status line, when it is a slash command other than `/deepen`, when it is a `/loop` or helper report, or when it is a spawn rewrite that already starts with the poteto-mode prefix.
|
|
19
|
+
|
|
20
|
+
A prompt that is only `/deepen` with no task is skipped. `/deepen` plus a task deepens the remainder.
|
|
21
|
+
|
|
22
|
+
## Four answers
|
|
23
|
+
|
|
24
|
+
1. What a top person in that field would do that this prompt omitted.
|
|
25
|
+
2. The raw source to start from.
|
|
26
|
+
3. The methods and tools they would use.
|
|
27
|
+
4. What besides the agent or Jon would show the result is right.
|
|
28
|
+
|
|
29
|
+
Then rewrite the user prompt to ask for exactly that job. Put `CDE_DEEPEN:v1` at the top.
|
|
30
|
+
|
|
31
|
+
## How to deepen
|
|
32
|
+
|
|
33
|
+
Read the task. Name the field. Fill the four answers from the checkout, the docs, and the tools already in the tree. Keep the rewrite shorter than a new spec. The worker should start from the raw source and finish at the proof.
|
|
34
|
+
|
|
35
|
+
When you spawn a helper to fill the four answers, that helper's prompt starts with `CDE_DEEPEN_AGENT` so the first-task hook leaves it alone.
|
|
36
|
+
|
|
37
|
+
## Hosts
|
|
38
|
+
|
|
39
|
+
- Claude desktop and CLI: a `prompt.submit` mod rewrites the visible text. The Python `UserPromptSubmit` hook is silent when that mod is on outside a cloud session.
|
|
40
|
+
- Claude cloud and Codex local: the Python hook injects `additionalContext`. Command hooks cannot replace the prompt string.
|
|
41
|
+
- Cursor Cloud: run this skill on the launch prompt.
|
|
42
|
+
- Codex cloud orchestration skips command hooks. Local Codex only.
|
|
@@ -10,6 +10,16 @@ export const PACKAGE_GUIDANCE_BLOCK_START = '<!-- claude-dev-env package guidanc
|
|
|
10
10
|
export const PACKAGE_GUIDANCE_BLOCK_END = '<!-- claude-dev-env package guidance: end -->';
|
|
11
11
|
export const QUESTION_PRESENTATION_BLOCK_START = '<!-- claude-dev-env question presentation: start -->';
|
|
12
12
|
export const QUESTION_PRESENTATION_BLOCK_END = '<!-- claude-dev-env question presentation: end -->';
|
|
13
|
+
export const DEEPEN_GUIDANCE_BLOCK_START = '<!-- claude-dev-env deepen: start -->';
|
|
14
|
+
export const DEEPEN_GUIDANCE_BLOCK_END = '<!-- claude-dev-env deepen: end -->';
|
|
15
|
+
export const DEEPEN_GUIDANCE_TEXT = [
|
|
16
|
+
'Deepen the first interactive user task before any work starts.',
|
|
17
|
+
'Answer four things the prompt left out: what a top person in that field would do, the raw source to start from, the methods and tools they would use, and what besides the agent or Jon would show the result is right.',
|
|
18
|
+
'Then rewrite the task to ask for exactly that job. The rewrite carries the marker CDE_DEEPEN:v1.',
|
|
19
|
+
'On demand, follow the deepen skill or /deepen with a task.',
|
|
20
|
+
'Cursor Cloud has no user hooks.json and defers sessionStart, so the launch prompt is already sent. Use the deepen skill under ~/.cursor/skills there.',
|
|
21
|
+
'Codex cloud orchestration skips command hooks. This block is the local Codex instruction.',
|
|
22
|
+
].join('\n');
|
|
13
23
|
|
|
14
24
|
const WINDOWS_LONG_PATH_PREFIX = '\\\\?\\';
|
|
15
25
|
|
|
@@ -115,6 +125,23 @@ export function writeCodexPackageGuidance(codexHome, packageGuidanceText, allPac
|
|
|
115
125
|
);
|
|
116
126
|
}
|
|
117
127
|
|
|
128
|
+
export function writeCodexDeepenGuidance(codexHome, deepenText = DEEPEN_GUIDANCE_TEXT) {
|
|
129
|
+
const agentsPath = join(codexHome, 'AGENTS.md');
|
|
130
|
+
const agentsEntry = lstatSync(agentsPath, { throwIfNoEntry: false });
|
|
131
|
+
if (agentsEntry && !agentsEntry.isFile()) return null;
|
|
132
|
+
const currentText = agentsEntry ? readFileSync(agentsPath, 'utf8') : '';
|
|
133
|
+
const block = managedBlock(DEEPEN_GUIDANCE_BLOCK_START, deepenText, DEEPEN_GUIDANCE_BLOCK_END);
|
|
134
|
+
const replacedText = withBlockReplaced(
|
|
135
|
+
currentText, DEEPEN_GUIDANCE_BLOCK_START, DEEPEN_GUIDANCE_BLOCK_END, block,
|
|
136
|
+
);
|
|
137
|
+
const separator = currentText && !currentText.endsWith('\n') ? '\n' : '';
|
|
138
|
+
const updatedText = replacedText ?? `${currentText}${separator}${block}`;
|
|
139
|
+
if (updatedText === currentText) return null;
|
|
140
|
+
mkdirSync(codexHome, { recursive: true });
|
|
141
|
+
writeFileSync(agentsPath, updatedText, 'utf8');
|
|
142
|
+
return agentsPath;
|
|
143
|
+
}
|
|
144
|
+
|
|
118
145
|
export function writeCodexQuestionGuidance(codexHome, policyText) {
|
|
119
146
|
const agentsPath = join(codexHome, 'AGENTS.md');
|
|
120
147
|
const agentsEntry = lstatSync(agentsPath, { throwIfNoEntry: false });
|
|
@@ -136,6 +163,7 @@ const ALL_PACKAGE_MANAGED_BLOCK_MARKERS = [
|
|
|
136
163
|
[SKILL_LOAD_BLOCK_START, SKILL_LOAD_BLOCK_END],
|
|
137
164
|
[PACKAGE_GUIDANCE_BLOCK_START, PACKAGE_GUIDANCE_BLOCK_END],
|
|
138
165
|
[QUESTION_PRESENTATION_BLOCK_START, QUESTION_PRESENTATION_BLOCK_END],
|
|
166
|
+
[DEEPEN_GUIDANCE_BLOCK_START, DEEPEN_GUIDANCE_BLOCK_END],
|
|
139
167
|
];
|
|
140
168
|
|
|
141
169
|
/**
|
|
@@ -181,6 +209,10 @@ export function removeCodexQuestionGuidance(codexHome) {
|
|
|
181
209
|
);
|
|
182
210
|
}
|
|
183
211
|
|
|
212
|
+
export function removeCodexDeepenGuidance(codexHome) {
|
|
213
|
+
return removeCodexGuidanceBlock(codexHome, DEEPEN_GUIDANCE_BLOCK_START, DEEPEN_GUIDANCE_BLOCK_END);
|
|
214
|
+
}
|
|
215
|
+
|
|
184
216
|
/**
|
|
185
217
|
* Remove the managed package-guidance block while keeping surrounding guidance bytes.
|
|
186
218
|
*
|
|
@@ -11,10 +11,15 @@ import {
|
|
|
11
11
|
SKILL_LOAD_BLOCK_END,
|
|
12
12
|
SKILL_LOAD_BLOCK_START,
|
|
13
13
|
SKILL_LOAD_INSTRUCTION,
|
|
14
|
+
removeCodexDeepenGuidance,
|
|
14
15
|
removeCodexPackageGuidance,
|
|
15
16
|
removeCodexQuestionGuidance,
|
|
16
17
|
withSkillLoadBlock,
|
|
18
|
+
DEEPEN_GUIDANCE_BLOCK_END,
|
|
19
|
+
DEEPEN_GUIDANCE_BLOCK_START,
|
|
20
|
+
DEEPEN_GUIDANCE_TEXT,
|
|
17
21
|
writeCodexAgentsGuidance,
|
|
22
|
+
writeCodexDeepenGuidance,
|
|
18
23
|
writeCodexPackageGuidance,
|
|
19
24
|
writeCodexQuestionGuidance,
|
|
20
25
|
} from './codex-skill-load-block.mjs';
|
|
@@ -359,3 +364,25 @@ test('question removal leaves a missing guidance file absent', (context) => {
|
|
|
359
364
|
assert.equal(removeCodexQuestionGuidance(homes.codexHome), null);
|
|
360
365
|
assert.equal(lstatSync(homes.agentsPath, { throwIfNoEntry: false }), undefined);
|
|
361
366
|
});
|
|
367
|
+
|
|
368
|
+
test('should write the deepen block into Codex AGENTS.md', (context) => {
|
|
369
|
+
const homes = makeHomes(context);
|
|
370
|
+
|
|
371
|
+
assert.equal(writeCodexDeepenGuidance(homes.codexHome), homes.agentsPath);
|
|
372
|
+
const guidanceText = readFileSync(homes.agentsPath, 'utf8');
|
|
373
|
+
assert.ok(guidanceText.includes(DEEPEN_GUIDANCE_BLOCK_START));
|
|
374
|
+
assert.ok(guidanceText.includes(DEEPEN_GUIDANCE_BLOCK_END));
|
|
375
|
+
assert.ok(guidanceText.includes(DEEPEN_GUIDANCE_TEXT.split('\n')[0]));
|
|
376
|
+
assert.equal(writeCodexDeepenGuidance(homes.codexHome), null);
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
test('should restore the custom guidance bytes when the deepen block is removed', (context) => {
|
|
380
|
+
const homes = makeHomes(context);
|
|
381
|
+
mkdirSync(homes.codexHome);
|
|
382
|
+
const customGuidance = '# My notes\n\nKeep this line.\n';
|
|
383
|
+
writeFileSync(homes.agentsPath, customGuidance);
|
|
384
|
+
|
|
385
|
+
assert.equal(writeCodexDeepenGuidance(homes.codexHome), homes.agentsPath);
|
|
386
|
+
assert.equal(removeCodexDeepenGuidance(homes.codexHome), homes.agentsPath);
|
|
387
|
+
assert.equal(readFileSync(homes.agentsPath, 'utf8'), customGuidance);
|
|
388
|
+
});
|
|
@@ -34,6 +34,7 @@ function installInScratchHome(homeDirectory, argumentsList = [], environment = {
|
|
|
34
34
|
CDE_INSTALL_PSTACK: '0',
|
|
35
35
|
CDE_INSTALL_USAGE_WRAPUP: '0',
|
|
36
36
|
CDE_INSTALL_SUBAGENT_MODELS: '0',
|
|
37
|
+
CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
|
|
37
38
|
CLAUDE_DEV_ENV_INSTALL_FAULT: undefined,
|
|
38
39
|
HOME: homeDirectory,
|
|
39
40
|
USERPROFILE: homeDirectory,
|
|
@@ -34,6 +34,18 @@ export const USAGE_WRAPUP_PLUGIN_SPEC = Object.freeze({
|
|
|
34
34
|
optOutVariable: 'CDE_INSTALL_USAGE_WRAPUP',
|
|
35
35
|
});
|
|
36
36
|
|
|
37
|
+
export const DEEPEN_FIRST_PROMPT_PLUGIN_SPEC = Object.freeze({
|
|
38
|
+
name: 'deepen-first-prompt',
|
|
39
|
+
label: 'Deepen-first-prompt',
|
|
40
|
+
marketplaceRepository: 'jl-cmd-projects/claude-dev-env',
|
|
41
|
+
marketplaceName: 'claude-dev-env',
|
|
42
|
+
sparsePaths: Object.freeze(['.claude-plugin', 'packages/deepen-first-prompt']),
|
|
43
|
+
pluginIdentifier: 'deepen-first-prompt@claude-dev-env',
|
|
44
|
+
hosts: Object.freeze(['claude']),
|
|
45
|
+
optOutFlag: '--no-deepen-first-prompt',
|
|
46
|
+
optOutVariable: 'CDE_INSTALL_DEEPEN_FIRST_PROMPT',
|
|
47
|
+
});
|
|
48
|
+
|
|
37
49
|
export const SUBAGENT_MODELS_PLUGIN_SPEC = Object.freeze({
|
|
38
50
|
name: 'subagent-models',
|
|
39
51
|
label: 'Subagent-models',
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
PSTACK_MARKETPLACE_REPOSITORY,
|
|
8
8
|
PSTACK_PLUGIN_HOSTS,
|
|
9
9
|
PSTACK_PLUGIN_IDENTIFIER,
|
|
10
|
+
DEEPEN_FIRST_PROMPT_PLUGIN_SPEC,
|
|
10
11
|
PSTACK_PLUGIN_SPEC,
|
|
11
12
|
SUBAGENT_MODELS_PLUGIN_SPEC,
|
|
12
13
|
USAGE_WRAPUP_PLUGIN_SPEC,
|
|
@@ -272,6 +273,7 @@ test('the usage-wrapup opt-out flag and variable turn off only usage-wrapup', ()
|
|
|
272
273
|
for (const [spec, packageFolder] of [
|
|
273
274
|
[USAGE_WRAPUP_PLUGIN_SPEC, './packages/usage-wrapup'],
|
|
274
275
|
[SUBAGENT_MODELS_PLUGIN_SPEC, './packages/subagent-models'],
|
|
276
|
+
[DEEPEN_FIRST_PROMPT_PLUGIN_SPEC, './packages/deepen-first-prompt'],
|
|
275
277
|
]) {
|
|
276
278
|
test(`the repository marketplace lists ${spec.name} from its package folder in this repository`, () => {
|
|
277
279
|
const marketplace = JSON.parse(readFileSync(
|
|
@@ -305,6 +307,27 @@ test('should remove and add the shared marketplace once when installing usage-wr
|
|
|
305
307
|
]);
|
|
306
308
|
});
|
|
307
309
|
|
|
310
|
+
test('should include deepen-first-prompt in one marketplace add with the other repository plugins', () => {
|
|
311
|
+
const plan = marketplacePluginsPlan(
|
|
312
|
+
[USAGE_WRAPUP_PLUGIN_SPEC, SUBAGENT_MODELS_PLUGIN_SPEC, DEEPEN_FIRST_PROMPT_PLUGIN_SPEC],
|
|
313
|
+
'claude',
|
|
314
|
+
);
|
|
315
|
+
assert.deepEqual(plan.commands[0], [
|
|
316
|
+
'plugin', 'marketplace', 'add', 'jl-cmd-projects/claude-dev-env',
|
|
317
|
+
'--sparse', '.claude-plugin', 'packages/usage-wrapup', 'packages/subagent-models',
|
|
318
|
+
'packages/deepen-first-prompt',
|
|
319
|
+
]);
|
|
320
|
+
assert.equal(shouldInstallMarketplacePlugin(DEEPEN_FIRST_PROMPT_PLUGIN_SPEC, ['--no-deepen-first-prompt'], {}), false);
|
|
321
|
+
assert.equal(
|
|
322
|
+
shouldInstallMarketplacePlugin(
|
|
323
|
+
DEEPEN_FIRST_PROMPT_PLUGIN_SPEC,
|
|
324
|
+
[],
|
|
325
|
+
{ CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0' },
|
|
326
|
+
),
|
|
327
|
+
false,
|
|
328
|
+
);
|
|
329
|
+
});
|
|
330
|
+
|
|
308
331
|
test('should refuse one plan for plugins from two marketplaces', () => {
|
|
309
332
|
assert.throws(
|
|
310
333
|
() => marketplacePluginsPlan([PSTACK_PLUGIN_SPEC, SUBAGENT_MODELS_PLUGIN_SPEC], 'claude'),
|
|
@@ -55,6 +55,7 @@ function runInstaller(homeDirectory, extraArguments, environmentOverrides = {})
|
|
|
55
55
|
CDE_INSTALL_PSTACK: '0',
|
|
56
56
|
CDE_INSTALL_USAGE_WRAPUP: '0',
|
|
57
57
|
CDE_INSTALL_SUBAGENT_MODELS: '0',
|
|
58
|
+
CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
|
|
58
59
|
HOME: homeDirectory,
|
|
59
60
|
USERPROFILE: homeDirectory,
|
|
60
61
|
GIT_CONFIG_GLOBAL: join(homeDirectory, '.gitconfig'),
|
|
@@ -61,6 +61,7 @@ function runInstaller(homeDirectory, extraArguments) {
|
|
|
61
61
|
CDE_INSTALL_PSTACK: '0',
|
|
62
62
|
CDE_INSTALL_USAGE_WRAPUP: '0',
|
|
63
63
|
CDE_INSTALL_SUBAGENT_MODELS: '0',
|
|
64
|
+
CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
|
|
64
65
|
HOME: homeDirectory,
|
|
65
66
|
USERPROFILE: homeDirectory,
|
|
66
67
|
GIT_CONFIG_GLOBAL: join(homeDirectory, '.gitconfig'),
|
|
@@ -93,6 +94,7 @@ function scanTextWithProductionPiiScanner(scannedText) {
|
|
|
93
94
|
CDE_INSTALL_PSTACK: '0',
|
|
94
95
|
CDE_INSTALL_USAGE_WRAPUP: '0',
|
|
95
96
|
CDE_INSTALL_SUBAGENT_MODELS: '0',
|
|
97
|
+
CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
|
|
96
98
|
PYTHONPATH: BLOCKING_HOOKS_DIRECTORY,
|
|
97
99
|
CLAUDE_LOCAL_IDENTITY_PATH: join(
|
|
98
100
|
temporaryDirectory,
|
|
@@ -35,6 +35,7 @@ function runInstaller(homeDirectory, extraArguments, environmentOverrides = {})
|
|
|
35
35
|
CDE_INSTALL_PSTACK: '0',
|
|
36
36
|
CDE_INSTALL_USAGE_WRAPUP: '0',
|
|
37
37
|
CDE_INSTALL_SUBAGENT_MODELS: '0',
|
|
38
|
+
CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
|
|
38
39
|
HOME: homeDirectory,
|
|
39
40
|
USERPROFILE: homeDirectory,
|
|
40
41
|
CODEX_HOME: join(homeDirectory, '.codex'),
|
|
@@ -133,7 +134,12 @@ test('seeds one editable policy and one native Codex routing hook', () => {
|
|
|
133
134
|
);
|
|
134
135
|
assert.equal(firstSpawnPromptGroups.length, 1);
|
|
135
136
|
assert.match(firstSpawnPromptGroups[0].hooks[0].command, /skill_loaded_reminder\.py/);
|
|
136
|
-
assert.deepEqual(Object.keys(firstCodexHooks.hooks), ['PreToolUse']);
|
|
137
|
+
assert.deepEqual(Object.keys(firstCodexHooks.hooks), ['PreToolUse', 'UserPromptSubmit']);
|
|
138
|
+
assert.ok(
|
|
139
|
+
firstCodexHooks.hooks.UserPromptSubmit.some(group =>
|
|
140
|
+
group.hooks.some(hook => String(hook.command).includes('deepen_first_prompt.py')),
|
|
141
|
+
),
|
|
142
|
+
);
|
|
137
143
|
assert.equal(
|
|
138
144
|
firstCodexHooks.hooks.PreToolUse.some(group => group.matcher === 'Write|Edit|MultiEdit|apply_patch'),
|
|
139
145
|
false,
|
|
@@ -291,6 +297,11 @@ test('Codex reinstall removes omitted package hooks and preserves user configura
|
|
|
291
297
|
['Agent|Task', 'multi_agent_v1__spawn_agent'].includes(eachGroup.matcher));
|
|
292
298
|
assert.equal(allSpawnGroups.length, 2);
|
|
293
299
|
migratedHooks.hooks.PreToolUse = migratedHooks.hooks.PreToolUse.filter(eachGroup => !allSpawnGroups.includes(eachGroup));
|
|
300
|
+
const allPackagePromptCommands = migratedHooks.hooks.UserPromptSubmit
|
|
301
|
+
.flatMap(eachGroup => eachGroup.hooks)
|
|
302
|
+
.map(eachHook => eachHook.command);
|
|
303
|
+
assert.ok(allPackagePromptCommands.some(eachCommand => eachCommand.includes('deepen_first_prompt.py')));
|
|
304
|
+
delete migratedHooks.hooks.UserPromptSubmit;
|
|
294
305
|
assert.deepEqual(migratedHooks, { enabled: false, metadata: 'keep-file', hooks: expectedUserHooks });
|
|
295
306
|
assert.equal(readFileSync(configPath, 'utf8'), disabledConfig);
|
|
296
307
|
const firstInstall = readFileSync(codexHooksPath, 'utf8');
|
|
@@ -337,6 +348,32 @@ test('uninstall removes the routing hook and keeps a Codex user hook', () => {
|
|
|
337
348
|
}
|
|
338
349
|
});
|
|
339
350
|
|
|
351
|
+
test('should ship the deepen skill to Cursor and the deepen block to Codex, and remove both on uninstall', () => {
|
|
352
|
+
const homeDirectory = mkdtempSync(join(tmpdir(), 'cdev-deepen-surfaces-'));
|
|
353
|
+
try {
|
|
354
|
+
const sourceSkillPath = join(PACKAGE_DIRECTORY, '.agents', 'skills', 'deepen', 'SKILL.md');
|
|
355
|
+
const cursorSkillPath = join(homeDirectory, DEFAULT_CURSOR_DIRECTORY_NAME, 'skills', 'deepen', 'SKILL.md');
|
|
356
|
+
const codexGuidancePath = join(homeDirectory, '.codex', 'AGENTS.md');
|
|
357
|
+
const manifestPath = join(homeDirectory, '.claude', '.claude-dev-env-manifest.json');
|
|
358
|
+
|
|
359
|
+
runInstaller(homeDirectory, []);
|
|
360
|
+
|
|
361
|
+
assert.equal(readFileSync(cursorSkillPath, 'utf8'), readFileSync(sourceSkillPath, 'utf8'));
|
|
362
|
+
assert.equal(JSON.parse(readFileSync(manifestPath, 'utf8')).files.includes(cursorSkillPath), true);
|
|
363
|
+
const codexGuidance = readFileSync(codexGuidancePath, 'utf8');
|
|
364
|
+
assert.match(codexGuidance, /<!-- claude-dev-env deepen: start -->/);
|
|
365
|
+
assert.match(codexGuidance, /CDE_DEEPEN:v1/);
|
|
366
|
+
|
|
367
|
+
runInstaller(homeDirectory, ['--uninstall']);
|
|
368
|
+
|
|
369
|
+
assert.equal(existsSync(cursorSkillPath), false);
|
|
370
|
+
const remainingGuidance = existsSync(codexGuidancePath) ? readFileSync(codexGuidancePath, 'utf8') : '';
|
|
371
|
+
assert.doesNotMatch(remainingGuidance, /claude-dev-env deepen/);
|
|
372
|
+
} finally {
|
|
373
|
+
rmSync(homeDirectory, { recursive: true, force: true });
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
|
|
340
377
|
test('malformed Codex hooks restore the staged install', () => {
|
|
341
378
|
const homeDirectory = mkdtempSync(join(tmpdir(), 'cdev-routing-malformed-'));
|
|
342
379
|
try {
|
package/bin/install.mjs
CHANGED
|
@@ -54,6 +54,7 @@ import {
|
|
|
54
54
|
} from './install-constants.mjs';
|
|
55
55
|
import {
|
|
56
56
|
PSTACK_PLUGIN_SPEC,
|
|
57
|
+
DEEPEN_FIRST_PROMPT_PLUGIN_SPEC,
|
|
57
58
|
SUBAGENT_MODELS_PLUGIN_SPEC,
|
|
58
59
|
USAGE_WRAPUP_PLUGIN_SPEC,
|
|
59
60
|
installMarketplacePlugins,
|
|
@@ -68,9 +69,11 @@ import {
|
|
|
68
69
|
writeCodexSolSetting,
|
|
69
70
|
} from './codex-trimmed-sol.mjs';
|
|
70
71
|
import {
|
|
72
|
+
removeCodexDeepenGuidance,
|
|
71
73
|
removeCodexPackageGuidance,
|
|
72
74
|
removeCodexQuestionGuidance,
|
|
73
75
|
writeCodexAgentsGuidance,
|
|
76
|
+
writeCodexDeepenGuidance,
|
|
74
77
|
writeCodexPackageGuidance,
|
|
75
78
|
writeCodexQuestionGuidance,
|
|
76
79
|
} from './codex-skill-load-block.mjs';
|
|
@@ -223,6 +226,7 @@ export const CORE_SKILLS = [
|
|
|
223
226
|
'issue-tracker',
|
|
224
227
|
'task-build',
|
|
225
228
|
'eli5',
|
|
229
|
+
'deepen',
|
|
226
230
|
];
|
|
227
231
|
|
|
228
232
|
export function collectPackageSourceConflicts(packageDirectory) {
|
|
@@ -2207,12 +2211,14 @@ function mergeHooksAtPath(
|
|
|
2207
2211
|
|
|
2208
2212
|
function selectCodexNativeHooksConfig(hooksConfig) {
|
|
2209
2213
|
const preToolUseGroups = hooksConfig.hooks?.PreToolUse;
|
|
2214
|
+
const userPromptSubmitGroups = hooksConfig.hooks?.UserPromptSubmit;
|
|
2210
2215
|
return {
|
|
2211
2216
|
...hooksConfig,
|
|
2212
2217
|
hooks: {
|
|
2213
2218
|
PreToolUse: Array.isArray(preToolUseGroups)
|
|
2214
2219
|
? preToolUseGroups.filter(group => ALL_CODEX_NATIVE_PRE_TOOL_USE_MATCHERS.has(group?.matcher))
|
|
2215
2220
|
: [],
|
|
2221
|
+
UserPromptSubmit: Array.isArray(userPromptSubmitGroups) ? userPromptSubmitGroups : [],
|
|
2216
2222
|
},
|
|
2217
2223
|
};
|
|
2218
2224
|
}
|
|
@@ -2876,6 +2882,23 @@ function executeInstallPlanMutations(plan, transactionHelpers) {
|
|
|
2876
2882
|
}
|
|
2877
2883
|
summary.skills = { created: skillsCreated, updated: skillsUpdated, pruned: 0, paths: skillPaths };
|
|
2878
2884
|
allInstalledFiles.push(...skillPaths);
|
|
2885
|
+
if (copiedSkillNames.has('deepen')) {
|
|
2886
|
+
for (const sourceRoot of allSourceRoots) {
|
|
2887
|
+
const deepenSourceDirectory = join(
|
|
2888
|
+
resolvePackageManagedDirectory(sourceRoot, MANAGED_SKILLS_DIRECTORY_NAME),
|
|
2889
|
+
'deepen',
|
|
2890
|
+
);
|
|
2891
|
+
if (!existsSync(deepenSourceDirectory)) continue;
|
|
2892
|
+
const cursorDeepenDirectory = join(
|
|
2893
|
+
INSTALL_ROOT_RESOLUTION.cursorInstallDirectory,
|
|
2894
|
+
'skills',
|
|
2895
|
+
'deepen',
|
|
2896
|
+
);
|
|
2897
|
+
const cursorSkillStats = copyTree(deepenSourceDirectory, cursorDeepenDirectory);
|
|
2898
|
+
allInstalledFiles.push(...cursorSkillStats.paths);
|
|
2899
|
+
break;
|
|
2900
|
+
}
|
|
2901
|
+
}
|
|
2879
2902
|
if (!selectedGroups) {
|
|
2880
2903
|
summary.retiredSessionContinuity = {
|
|
2881
2904
|
changedPaths: removeRetiredSessionContinuityHooks(),
|
|
@@ -2915,8 +2938,11 @@ function executeInstallPlanMutations(plan, transactionHelpers) {
|
|
|
2915
2938
|
}
|
|
2916
2939
|
printPluginHostOutcomes([PSTACK_PLUGIN_SPEC], pstackPlugin);
|
|
2917
2940
|
}
|
|
2918
|
-
const allRepositoryPluginSpecs = [
|
|
2919
|
-
|
|
2941
|
+
const allRepositoryPluginSpecs = [
|
|
2942
|
+
USAGE_WRAPUP_PLUGIN_SPEC,
|
|
2943
|
+
SUBAGENT_MODELS_PLUGIN_SPEC,
|
|
2944
|
+
DEEPEN_FIRST_PROMPT_PLUGIN_SPEC,
|
|
2945
|
+
].filter(eachSpec => shouldInstallMarketplacePlugin(eachSpec));
|
|
2920
2946
|
if (!selectedGroups && allRepositoryPluginSpecs.length > 0) {
|
|
2921
2947
|
const repositoryPlugins = installMarketplacePlugins(allRepositoryPluginSpecs, {
|
|
2922
2948
|
claudeRoot: CLAUDE_HOME,
|
|
@@ -2939,6 +2965,10 @@ function executeInstallPlanMutations(plan, transactionHelpers) {
|
|
|
2939
2965
|
readFileSync(join(PACKAGE_ROOT, 'rules', 'question-presentation.md'), 'utf8'),
|
|
2940
2966
|
);
|
|
2941
2967
|
if (questionGuidancePath) allCodexGuidancePaths.push(questionGuidancePath);
|
|
2968
|
+
const deepenGuidancePath = writeCodexDeepenGuidance(
|
|
2969
|
+
INSTALL_ROOT_RESOLUTION.codexHomeDirectory,
|
|
2970
|
+
);
|
|
2971
|
+
if (deepenGuidancePath) allCodexGuidancePaths.push(deepenGuidancePath);
|
|
2942
2972
|
const solSettingPath = writeCodexSolSetting(
|
|
2943
2973
|
INSTALL_ROOT_RESOLUTION.codexHomeDirectory,
|
|
2944
2974
|
join(CLAUDE_HOME, SOL_PROMPT_DIRECTORY_NAME, SOL_PROMPT_FILE_NAME),
|
|
@@ -3307,6 +3337,7 @@ function executeUninstallPlan(plan, helpers = {}) {
|
|
|
3307
3337
|
}
|
|
3308
3338
|
removeCodexPackageGuidance(INSTALL_ROOT_RESOLUTION.codexHomeDirectory);
|
|
3309
3339
|
removeCodexQuestionGuidance(INSTALL_ROOT_RESOLUTION.codexHomeDirectory);
|
|
3340
|
+
removeCodexDeepenGuidance(INSTALL_ROOT_RESOLUTION.codexHomeDirectory);
|
|
3310
3341
|
removeCodexSolSetting(INSTALL_ROOT_RESOLUTION.codexHomeDirectory);
|
|
3311
3342
|
throwIfFault(FAULT_PHASES.AFTER_FILE_STAGING);
|
|
3312
3343
|
|
|
@@ -3455,6 +3486,7 @@ Usage:
|
|
|
3455
3486
|
npx ${PACKAGE_NAME} --no-pstack Full install without the pstack plugin (also CDE_INSTALL_PSTACK=0)
|
|
3456
3487
|
npx ${PACKAGE_NAME} --no-usage-wrapup Full install without the usage-wrapup plugin (also CDE_INSTALL_USAGE_WRAPUP=0)
|
|
3457
3488
|
npx ${PACKAGE_NAME} --no-subagent-models Full install without the subagent-models plugin (also CDE_INSTALL_SUBAGENT_MODELS=0)
|
|
3489
|
+
npx ${PACKAGE_NAME} --no-deepen-first-prompt Full install without the deepen-first-prompt plugin (also CDE_INSTALL_DEEPEN_FIRST_PROMPT=0)
|
|
3458
3490
|
npx ${PACKAGE_NAME} --uninstall Remove installed files from the selected root
|
|
3459
3491
|
npx ${PACKAGE_NAME} --help Show this help
|
|
3460
3492
|
|
|
@@ -35,9 +35,11 @@ test('reinstall drops the retired style reminder and keeps one skill reminder ho
|
|
|
35
35
|
mergeHooksIntoSettings(settings, hooksConfig, 'C:/Users/example/.claude', 'python');
|
|
36
36
|
|
|
37
37
|
const userPromptHooks = settings.hooks.UserPromptSubmit.flatMap(eachGroup => eachGroup.hooks);
|
|
38
|
-
assert.equal(userPromptHooks.length,
|
|
38
|
+
assert.equal(userPromptHooks.length, 4);
|
|
39
39
|
assert.equal(userPromptHooks[0].command, userCommand);
|
|
40
40
|
assert.match(userPromptHooks[1].command, /session\/skill_loaded_reminder\.py$/);
|
|
41
|
+
assert.match(userPromptHooks[2].command, /session\/deepen_first_prompt\.py$/);
|
|
42
|
+
assert.match(userPromptHooks[3].command, /lifecycle\/nested_project_hooks\.py$/);
|
|
41
43
|
assert.ok(userPromptHooks.every(eachHook => !eachHook.command.includes('style_reminder_prompt')));
|
|
42
44
|
|
|
43
45
|
const firstMerge = JSON.stringify(settings);
|
|
@@ -264,6 +264,7 @@ function resolveInstallerInvocation(homeDirectory) {
|
|
|
264
264
|
CDE_INSTALL_PSTACK: '0',
|
|
265
265
|
CDE_INSTALL_USAGE_WRAPUP: '0',
|
|
266
266
|
CDE_INSTALL_SUBAGENT_MODELS: '0',
|
|
267
|
+
CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
|
|
267
268
|
HOME: homeDirectory,
|
|
268
269
|
USERPROFILE: homeDirectory,
|
|
269
270
|
GIT_CONFIG_GLOBAL: join(homeDirectory, '.gitconfig'),
|
|
@@ -27,6 +27,7 @@ function installInScratchHome(homeDirectory, argumentsList = [], extraEnvironmen
|
|
|
27
27
|
CDE_INSTALL_PSTACK: '0',
|
|
28
28
|
CDE_INSTALL_USAGE_WRAPUP: '0',
|
|
29
29
|
CDE_INSTALL_SUBAGENT_MODELS: '0',
|
|
30
|
+
CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
|
|
30
31
|
HOME: homeDirectory,
|
|
31
32
|
USERPROFILE: homeDirectory,
|
|
32
33
|
CODEX_HOME: join(homeDirectory, '.codex'),
|
|
@@ -183,6 +184,7 @@ test('a successful pstack install retains its skill block and gains the question
|
|
|
183
184
|
CDE_INSTALL_PSTACK: '1',
|
|
184
185
|
CDE_INSTALL_USAGE_WRAPUP: '0',
|
|
185
186
|
CDE_INSTALL_SUBAGENT_MODELS: '0',
|
|
187
|
+
CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
|
|
186
188
|
CDE_CODEX_EXECUTABLE: commandPath,
|
|
187
189
|
CDE_CLAUDE_EXECUTABLE: commandPath,
|
|
188
190
|
});
|
|
@@ -211,6 +213,7 @@ test('enabling pstack after a pstack-off install preserves question guidance', (
|
|
|
211
213
|
CDE_INSTALL_PSTACK: '1',
|
|
212
214
|
CDE_INSTALL_USAGE_WRAPUP: '0',
|
|
213
215
|
CDE_INSTALL_SUBAGENT_MODELS: '0',
|
|
216
|
+
CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
|
|
214
217
|
CDE_CODEX_EXECUTABLE: commandPath,
|
|
215
218
|
CDE_CLAUDE_EXECUTABLE: commandPath,
|
|
216
219
|
});
|
|
@@ -240,6 +243,7 @@ test('a failed pstack transition restores question-only guidance and removes its
|
|
|
240
243
|
CDE_INSTALL_PSTACK: '1',
|
|
241
244
|
CDE_INSTALL_USAGE_WRAPUP: '0',
|
|
242
245
|
CDE_INSTALL_SUBAGENT_MODELS: '0',
|
|
246
|
+
CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
|
|
243
247
|
CDE_CODEX_EXECUTABLE: commandPath,
|
|
244
248
|
CDE_CLAUDE_EXECUTABLE: commandPath,
|
|
245
249
|
CLAUDE_DEV_ENV_INSTALL_FAULT: 'after_file_staging',
|
|
@@ -65,6 +65,7 @@ function runInstallerInSandbox(sandboxHome, installerArguments = []) {
|
|
|
65
65
|
CDE_INSTALL_PSTACK: '0',
|
|
66
66
|
CDE_INSTALL_USAGE_WRAPUP: '0',
|
|
67
67
|
CDE_INSTALL_SUBAGENT_MODELS: '0',
|
|
68
|
+
CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
|
|
68
69
|
HOME: sandboxHome,
|
|
69
70
|
USERPROFILE: sandboxHome,
|
|
70
71
|
GIT_CONFIG_GLOBAL: gitConfigGlobal,
|
package/bin/install.test.mjs
CHANGED
|
@@ -257,6 +257,11 @@ test('CORE_SKILLS ships ELI5 as the leaf presentation skill', () => {
|
|
|
257
257
|
assert.equal(INSTALL_GROUPS.core.skills.includes('eli5'), true);
|
|
258
258
|
});
|
|
259
259
|
|
|
260
|
+
test('CORE_SKILLS ships deepen so the first-task skill installs with core', () => {
|
|
261
|
+
assert.ok(CORE_SKILLS.includes('deepen'), 'deepen must be in CORE_SKILLS');
|
|
262
|
+
assert.equal(INSTALL_GROUPS.core.skills.includes('deepen'), true);
|
|
263
|
+
});
|
|
264
|
+
|
|
260
265
|
test('CORE_SKILLS ships test-runner for explicit Django and Playwright readiness checks', () => {
|
|
261
266
|
assert.ok(CORE_SKILLS.includes('test-runner'));
|
|
262
267
|
assert.equal(INSTALL_GROUPS.core.skills.includes('test-runner'), true);
|
|
@@ -3037,6 +3042,7 @@ test('a failed update preserves an existing skills lookup pointer', () => {
|
|
|
3037
3042
|
CDE_INSTALL_PSTACK: '0',
|
|
3038
3043
|
CDE_INSTALL_USAGE_WRAPUP: '0',
|
|
3039
3044
|
CDE_INSTALL_SUBAGENT_MODELS: '0',
|
|
3045
|
+
CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
|
|
3040
3046
|
};
|
|
3041
3047
|
const argumentsForCoreInstall = [PSTACK_TEST_INSTALLER_PATH, '--only', 'core'];
|
|
3042
3048
|
const firstRun = spawnSync(process.execPath, argumentsForCoreInstall, {
|
|
@@ -3090,6 +3096,7 @@ function runPstackInstaller(homeDirectory, extraArguments, environmentOverrides
|
|
|
3090
3096
|
CDE_INSTALL_PSTACK: '1',
|
|
3091
3097
|
CDE_INSTALL_USAGE_WRAPUP: '0',
|
|
3092
3098
|
CDE_INSTALL_SUBAGENT_MODELS: '0',
|
|
3099
|
+
CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
|
|
3093
3100
|
...environmentOverrides,
|
|
3094
3101
|
},
|
|
3095
3102
|
});
|
|
@@ -3402,15 +3409,18 @@ test('the help output names the usage-wrapup opt-out beside the pstack one', ()
|
|
|
3402
3409
|
|
|
3403
3410
|
assert.equal(helpRun.status, 0, helpRun.stderr);
|
|
3404
3411
|
assert.match(helpRun.stdout, /--no-pstack .*\n.*--no-usage-wrapup .*CDE_INSTALL_USAGE_WRAPUP=0/);
|
|
3412
|
+
assert.match(helpRun.stdout, /--no-deepen-first-prompt .*CDE_INSTALL_DEEPEN_FIRST_PROMPT=0/);
|
|
3405
3413
|
});
|
|
3406
3414
|
|
|
3407
3415
|
const REPOSITORY_PLUGIN_CLAUDE_COMMANDS = Object.freeze([
|
|
3408
3416
|
'claude plugin uninstall usage-wrapup@claude-dev-env',
|
|
3409
3417
|
'claude plugin uninstall subagent-models@claude-dev-env',
|
|
3418
|
+
'claude plugin uninstall deepen-first-prompt@claude-dev-env',
|
|
3410
3419
|
'claude plugin marketplace remove claude-dev-env',
|
|
3411
|
-
'claude plugin marketplace add jl-cmd-projects/claude-dev-env --sparse .claude-plugin packages/usage-wrapup packages/subagent-models',
|
|
3420
|
+
'claude plugin marketplace add jl-cmd-projects/claude-dev-env --sparse .claude-plugin packages/usage-wrapup packages/subagent-models packages/deepen-first-prompt',
|
|
3412
3421
|
'claude plugin install usage-wrapup@claude-dev-env',
|
|
3413
3422
|
'claude plugin install subagent-models@claude-dev-env',
|
|
3423
|
+
'claude plugin install deepen-first-prompt@claude-dev-env',
|
|
3414
3424
|
]);
|
|
3415
3425
|
|
|
3416
3426
|
test('should install subagent-models beside usage-wrapup with one marketplace add on a full install', t => {
|
|
@@ -3420,11 +3430,13 @@ test('should install subagent-models beside usage-wrapup with one marketplace ad
|
|
|
3420
3430
|
...sandbox.environment,
|
|
3421
3431
|
CDE_INSTALL_USAGE_WRAPUP: '1',
|
|
3422
3432
|
CDE_INSTALL_SUBAGENT_MODELS: '1',
|
|
3433
|
+
CDE_INSTALL_DEEPEN_FIRST_PROMPT: '1',
|
|
3423
3434
|
});
|
|
3424
3435
|
|
|
3425
3436
|
assert.deepEqual(usageWrapupCommands(sandbox.recordedCommands()), REPOSITORY_PLUGIN_CLAUDE_COMMANDS);
|
|
3426
3437
|
assert.match(installerOutput, /Usage-wrapup \(claude\): installed/);
|
|
3427
3438
|
assert.match(installerOutput, /Subagent-models \(claude\): installed/);
|
|
3439
|
+
assert.match(installerOutput, /Deepen-first-prompt \(claude\): installed/);
|
|
3428
3440
|
});
|
|
3429
3441
|
|
|
3430
3442
|
for (const [caseName, extraArguments, environmentOverrides] of [
|
|
@@ -3448,6 +3460,27 @@ for (const [caseName, extraArguments, environmentOverrides] of [
|
|
|
3448
3460
|
});
|
|
3449
3461
|
}
|
|
3450
3462
|
|
|
3463
|
+
for (const [caseName, extraArguments, environmentOverrides] of [
|
|
3464
|
+
['--no-deepen-first-prompt', ['--no-deepen-first-prompt'], { CDE_INSTALL_DEEPEN_FIRST_PROMPT: '1' }],
|
|
3465
|
+
['CDE_INSTALL_DEEPEN_FIRST_PROMPT=0', [], { CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0' }],
|
|
3466
|
+
['an --only run', ['--only', 'core'], { CDE_INSTALL_DEEPEN_FIRST_PROMPT: '1' }],
|
|
3467
|
+
]) {
|
|
3468
|
+
test(`should skip deepen-first-prompt on ${caseName}`, t => {
|
|
3469
|
+
const sandbox = pstackPluginSandbox(t);
|
|
3470
|
+
|
|
3471
|
+
const installerOutput = runPstackInstaller(sandbox.homeDirectory, extraArguments, {
|
|
3472
|
+
...sandbox.environment,
|
|
3473
|
+
...environmentOverrides,
|
|
3474
|
+
});
|
|
3475
|
+
|
|
3476
|
+
assert.equal(
|
|
3477
|
+
sandbox.recordedCommands().some(eachCommand => eachCommand.includes('deepen-first-prompt')),
|
|
3478
|
+
false,
|
|
3479
|
+
);
|
|
3480
|
+
assert.doesNotMatch(installerOutput, /Deepen-first-prompt \(/);
|
|
3481
|
+
});
|
|
3482
|
+
}
|
|
3483
|
+
|
|
3451
3484
|
test('should name the subagent-models opt-out in the help output', () => {
|
|
3452
3485
|
const helpRun = spawnSync(process.execPath, [PSTACK_TEST_INSTALLER_PATH, '--help'], {
|
|
3453
3486
|
encoding: 'utf8',
|
|
@@ -90,6 +90,7 @@ test('capture and restore recover settings, manifest, files, and hooksPath', ()
|
|
|
90
90
|
CDE_INSTALL_PSTACK: '0',
|
|
91
91
|
CDE_INSTALL_USAGE_WRAPUP: '0',
|
|
92
92
|
CDE_INSTALL_SUBAGENT_MODELS: '0',
|
|
93
|
+
CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
|
|
93
94
|
HOME: box.root,
|
|
94
95
|
USERPROFILE: box.root,
|
|
95
96
|
GIT_CONFIG_GLOBAL: gitConfigPath,
|
|
@@ -155,6 +156,7 @@ test('capture and restore recover an additional host settings file', () => {
|
|
|
155
156
|
CDE_INSTALL_PSTACK: '0',
|
|
156
157
|
CDE_INSTALL_USAGE_WRAPUP: '0',
|
|
157
158
|
CDE_INSTALL_SUBAGENT_MODELS: '0',
|
|
159
|
+
CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
|
|
158
160
|
HOME: box.root,
|
|
159
161
|
USERPROFILE: box.root,
|
|
160
162
|
GIT_CONFIG_GLOBAL: gitConfigPath,
|
|
@@ -193,6 +195,7 @@ test('runWithInstallTransaction restores prior state on injected fault', () => {
|
|
|
193
195
|
CDE_INSTALL_PSTACK: '0',
|
|
194
196
|
CDE_INSTALL_USAGE_WRAPUP: '0',
|
|
195
197
|
CDE_INSTALL_SUBAGENT_MODELS: '0',
|
|
198
|
+
CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
|
|
196
199
|
HOME: box.root,
|
|
197
200
|
USERPROFILE: box.root,
|
|
198
201
|
GIT_CONFIG_GLOBAL: gitConfigPath,
|
|
@@ -250,6 +253,7 @@ test('runWithInstallTransaction commits and discards journal on success', () =>
|
|
|
250
253
|
CDE_INSTALL_PSTACK: '0',
|
|
251
254
|
CDE_INSTALL_USAGE_WRAPUP: '0',
|
|
252
255
|
CDE_INSTALL_SUBAGENT_MODELS: '0',
|
|
256
|
+
CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
|
|
253
257
|
HOME: box.root,
|
|
254
258
|
USERPROFILE: box.root,
|
|
255
259
|
GIT_CONFIG_GLOBAL: gitConfigPath,
|
|
@@ -296,6 +300,7 @@ function runInstaller(homeDirectory, extraArguments, options = {}) {
|
|
|
296
300
|
CDE_INSTALL_PSTACK: '0',
|
|
297
301
|
CDE_INSTALL_USAGE_WRAPUP: '0',
|
|
298
302
|
CDE_INSTALL_SUBAGENT_MODELS: '0',
|
|
303
|
+
CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
|
|
299
304
|
HOME: homeDirectory,
|
|
300
305
|
USERPROFILE: homeDirectory,
|
|
301
306
|
GIT_CONFIG_GLOBAL: join(homeDirectory, '.gitconfig'),
|
|
@@ -332,6 +337,7 @@ test('a later install fault removes newly seeded Codex pstack files', () => {
|
|
|
332
337
|
CDE_INSTALL_PSTACK: '1',
|
|
333
338
|
CDE_INSTALL_USAGE_WRAPUP: '0',
|
|
334
339
|
CDE_INSTALL_SUBAGENT_MODELS: '0',
|
|
340
|
+
CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
|
|
335
341
|
CDE_CODEX_EXECUTABLE: codexCommandPath,
|
|
336
342
|
},
|
|
337
343
|
});
|
|
@@ -478,6 +484,7 @@ test('installer fault after_git_config restores prior core.hooksPath', () => {
|
|
|
478
484
|
CDE_INSTALL_PSTACK: '0',
|
|
479
485
|
CDE_INSTALL_USAGE_WRAPUP: '0',
|
|
480
486
|
CDE_INSTALL_SUBAGENT_MODELS: '0',
|
|
487
|
+
CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
|
|
481
488
|
HOME: homeDirectory,
|
|
482
489
|
USERPROFILE: homeDirectory,
|
|
483
490
|
GIT_CONFIG_GLOBAL: gitConfigPath,
|
|
@@ -498,6 +505,7 @@ test('installer fault after_git_config restores prior core.hooksPath', () => {
|
|
|
498
505
|
CDE_INSTALL_PSTACK: '0',
|
|
499
506
|
CDE_INSTALL_USAGE_WRAPUP: '0',
|
|
500
507
|
CDE_INSTALL_SUBAGENT_MODELS: '0',
|
|
508
|
+
CDE_INSTALL_DEEPEN_FIRST_PROMPT: '0',
|
|
501
509
|
HOME: homeDirectory,
|
|
502
510
|
USERPROFILE: homeDirectory,
|
|
503
511
|
GIT_CONFIG_GLOBAL: gitConfigPath,
|