@ksuchoi216/ahe 0.1.7 → 0.1.12
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/README.md +57 -20
- package/bin/ahe +34 -233
- package/package.json +7 -4
- package/packages/ahe-antigravity/bin/ahe-antigravity +325 -0
- package/packages/ahe-antigravity/package.json +7 -0
- package/packages/ahe-antigravity/skills/ahe-git/SKILL.md +35 -0
- package/packages/ahe-antigravity/skills/ahe-ship/SKILL.md +28 -0
- package/packages/ahe-antigravity/skills/ahe-ship/scripts/post-ship-hook.sh +12 -0
- package/packages/ahe-codex/.codex/agents/ahe-harness-manager.toml +19 -0
- package/{.codex → packages/ahe-codex/.codex}/ahe-shared/templates/AGENTS.md +11 -10
- package/{.codex/ahe-shared/templates/PRODUCT.md → packages/ahe-codex/.codex/ahe-shared/templates/product.md} +1 -1
- package/packages/ahe-codex/.codex/hooks/ahe-hook.js +249 -0
- package/packages/ahe-codex/.codex/skills/ahe/SKILL.md +36 -0
- package/packages/ahe-codex/.codex/skills/ahe-clean/SKILL.md +67 -0
- package/{.codex/skills/ahe-conversator → packages/ahe-codex/.codex/skills/ahe-converse}/SKILL.md +6 -6
- package/packages/ahe-codex/.codex/skills/ahe-feature/SKILL.md +25 -0
- package/packages/ahe-codex/.codex/skills/ahe-git/SKILL.md +34 -0
- package/packages/ahe-codex/.codex/skills/ahe-harness/SKILL.md +129 -0
- package/packages/ahe-codex/.codex/skills/ahe-harness-checker/SKILL.md +46 -0
- package/{.codex/skills/ahe-init → packages/ahe-codex/.codex/skills/ahe-new}/SKILL.md +36 -21
- package/packages/ahe-codex/.codex/skills/ahe-overview/SKILL.md +96 -0
- package/packages/ahe-codex/.codex/skills/ahe-review/SKILL.md +43 -0
- package/packages/ahe-codex/.codex/skills/ahe-ship/SKILL.md +58 -0
- package/packages/ahe-codex/.codex/skills/ahe-ship/agents/openai.yaml +4 -0
- package/packages/ahe-codex/.codex/skills/ahe-ship/scripts/write_plan.py +107 -0
- package/packages/ahe-codex/.codex/skills/ahe-solve/SKILL.md +30 -0
- package/packages/ahe-codex/.codex/skills/ahe-think/SKILL.md +125 -0
- package/packages/ahe-codex/bin/ahe-codex +398 -0
- package/packages/ahe-codex/package.json +7 -0
- package/.codex/ahe-shared/config.yaml +0 -8
- package/.codex/hooks/ahe-hook.js +0 -195
- package/.codex/skills/ahe-compression/SKILL.md +0 -97
- package/.codex/skills/ahe-compression/agents/openai.yaml +0 -6
- package/.codex/skills/ahe-compression/scripts/check-harness-size.sh +0 -109
- package/.codex/skills/ahe-harness/SKILL.md +0 -115
- package/.codex/skills/ahe-reviewer/SKILL.md +0 -35
- package/.codex/skills/ahe-solver/SKILL.md +0 -24
- package/.codex/skills/ahe-thinker/SKILL.md +0 -80
- /package/{.codex → packages/ahe-codex/.codex}/ahe-shared/schemas/feature-list-schema.json +0 -0
- /package/{.codex → packages/ahe-codex/.codex}/ahe-shared/schemas/process_status.schema.json +0 -0
- /package/{.codex → packages/ahe-codex/.codex}/ahe-shared/templates/INSTRUCTIONS.md +0 -0
- /package/{.codex → packages/ahe-codex/.codex}/ahe-shared/templates/feature-list.json +0 -0
- /package/{.codex → packages/ahe-codex/.codex}/ahe-shared/templates/init.sh +0 -0
- /package/{.codex/ahe-shared/templates/PROGRESS.md → packages/ahe-codex/.codex/ahe-shared/templates/progress.md} +0 -0
- /package/{.codex/ahe-shared/templates/SESSION-HANDOFF.md → packages/ahe-codex/.codex/ahe-shared/templates/session-handoff.md} +0 -0
- /package/{.codex → packages/ahe-codex/.codex}/hooks/hooks.json +0 -0
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
readonly VERSION="0.1.0"
|
|
5
|
+
SCRIPT_PATH="${BASH_SOURCE[0]}"
|
|
6
|
+
|
|
7
|
+
while [ -L "${SCRIPT_PATH}" ]; do
|
|
8
|
+
SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "${SCRIPT_PATH}")" && pwd)"
|
|
9
|
+
SCRIPT_PATH="$(readlink "${SCRIPT_PATH}")"
|
|
10
|
+
|
|
11
|
+
case "${SCRIPT_PATH}" in
|
|
12
|
+
/*) ;;
|
|
13
|
+
*) SCRIPT_PATH="${SCRIPT_DIR}/${SCRIPT_PATH}" ;;
|
|
14
|
+
esac
|
|
15
|
+
done
|
|
16
|
+
|
|
17
|
+
readonly SCRIPT_DIR="$(CDPATH= cd -- "$(dirname -- "${SCRIPT_PATH}")" && pwd)"
|
|
18
|
+
readonly PACKAGE_ROOT="$(CDPATH= cd -- "${SCRIPT_DIR}/.." && pwd)"
|
|
19
|
+
readonly SOURCE_SKILLS_DIR="${PACKAGE_ROOT}/.codex/skills"
|
|
20
|
+
readonly SOURCE_SHARED_DIR="${PACKAGE_ROOT}/.codex/ahe-shared"
|
|
21
|
+
readonly SOURCE_HOOKS_DIR="${PACKAGE_ROOT}/.codex/hooks"
|
|
22
|
+
readonly SOURCE_AGENTS_DIR="${PACKAGE_ROOT}/.codex/agents"
|
|
23
|
+
readonly AHE_CONFIG_BLOCK_START="# BEGIN AHE MANAGED CONFIG"
|
|
24
|
+
readonly AHE_CONFIG_BLOCK_END="# END AHE MANAGED CONFIG"
|
|
25
|
+
readonly MANAGED_SKILLS=(
|
|
26
|
+
"ahe"
|
|
27
|
+
"ahe-clean"
|
|
28
|
+
"ahe-converse"
|
|
29
|
+
"ahe-feature"
|
|
30
|
+
"ahe-git"
|
|
31
|
+
"ahe-harness"
|
|
32
|
+
"ahe-harness-checker"
|
|
33
|
+
"ahe-new"
|
|
34
|
+
"ahe-overview"
|
|
35
|
+
"ahe-review"
|
|
36
|
+
"ahe-ship"
|
|
37
|
+
"ahe-solve"
|
|
38
|
+
"ahe-think"
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
codex_home() {
|
|
42
|
+
if [ -n "${CODEX_HOME:-}" ]; then
|
|
43
|
+
printf '%s\n' "${CODEX_HOME}"
|
|
44
|
+
return 0
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
printf '%s\n' "${HOME}/.codex"
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
usage() {
|
|
51
|
+
cat <<'EOF'
|
|
52
|
+
Usage:
|
|
53
|
+
ahe install [--force] [--backup]
|
|
54
|
+
ahe uninstall
|
|
55
|
+
ahe doctor
|
|
56
|
+
ahe version
|
|
57
|
+
EOF
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
backup_existing_installation() {
|
|
61
|
+
local target_dir="$1"
|
|
62
|
+
local backup_root="$2"
|
|
63
|
+
local backup_name="$3"
|
|
64
|
+
local timestamp
|
|
65
|
+
|
|
66
|
+
timestamp="$(date '+%Y%m%d-%H%M%S')"
|
|
67
|
+
mkdir -p "${backup_root}"
|
|
68
|
+
mv "${target_dir}" "${backup_root}/${backup_name}-${timestamp}"
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
cleanup_ahe_config_entries() {
|
|
72
|
+
local config_path="$1"
|
|
73
|
+
local temp_path=""
|
|
74
|
+
|
|
75
|
+
if [ ! -f "${config_path}" ]; then
|
|
76
|
+
return 0
|
|
77
|
+
fi
|
|
78
|
+
|
|
79
|
+
temp_path="${config_path}.ahe-cleanup"
|
|
80
|
+
awk -v block_start="${AHE_CONFIG_BLOCK_START}" -v block_end="${AHE_CONFIG_BLOCK_END}" '
|
|
81
|
+
function is_ahe_header(line) {
|
|
82
|
+
return line ~ /^\[hooks\.state\."ahe[^"]*"\]$/ ||
|
|
83
|
+
line ~ /^\[plugins\."?ahe[^]]*"?\]$/ ||
|
|
84
|
+
line ~ /^\[plugins\."@ksuchoi216\/ahe[^"]*"\]$/
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
$0 == block_start {
|
|
88
|
+
in_block = 1
|
|
89
|
+
next
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
$0 == block_end {
|
|
93
|
+
in_block = 0
|
|
94
|
+
next
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
in_block == 1 {
|
|
98
|
+
next
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/^\[/ {
|
|
102
|
+
if (is_ahe_header($0)) {
|
|
103
|
+
skip_section = 1
|
|
104
|
+
next
|
|
105
|
+
}
|
|
106
|
+
skip_section = 0
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
skip_section == 1 {
|
|
110
|
+
next
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
{
|
|
114
|
+
print
|
|
115
|
+
}
|
|
116
|
+
' "${config_path}" > "${temp_path}"
|
|
117
|
+
mv "${temp_path}" "${config_path}"
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
install_skill() {
|
|
121
|
+
local force="false"
|
|
122
|
+
local backup="false"
|
|
123
|
+
|
|
124
|
+
while [ "$#" -gt 0 ]; do
|
|
125
|
+
case "$1" in
|
|
126
|
+
--force)
|
|
127
|
+
force="true"
|
|
128
|
+
;;
|
|
129
|
+
--backup)
|
|
130
|
+
backup="true"
|
|
131
|
+
;;
|
|
132
|
+
*)
|
|
133
|
+
printf 'Unknown install option: %s\n' "$1" >&2
|
|
134
|
+
usage >&2
|
|
135
|
+
exit 1
|
|
136
|
+
;;
|
|
137
|
+
esac
|
|
138
|
+
shift
|
|
139
|
+
done
|
|
140
|
+
|
|
141
|
+
if [ ! -d "${SOURCE_SKILLS_DIR}" ]; then
|
|
142
|
+
printf 'Packaged skill files are missing: %s\n' "${SOURCE_SKILLS_DIR}" >&2
|
|
143
|
+
exit 1
|
|
144
|
+
fi
|
|
145
|
+
|
|
146
|
+
if [ ! -d "${SOURCE_SHARED_DIR}" ]; then
|
|
147
|
+
printf 'Packaged shared files are missing: %s\n' "${SOURCE_SHARED_DIR}" >&2
|
|
148
|
+
exit 1
|
|
149
|
+
fi
|
|
150
|
+
|
|
151
|
+
local target_codex_home
|
|
152
|
+
target_codex_home="$(codex_home)"
|
|
153
|
+
|
|
154
|
+
local target_skills_dir="${target_codex_home}/skills"
|
|
155
|
+
local target_shared_dir="${target_codex_home}/ahe-shared"
|
|
156
|
+
local target_hooks_dir="${target_codex_home}/hooks"
|
|
157
|
+
local target_agents_dir="${target_codex_home}/agents"
|
|
158
|
+
local target_config_path="${target_codex_home}/config.toml"
|
|
159
|
+
local backup_dir="${target_codex_home}/_backups"
|
|
160
|
+
local skill_name=""
|
|
161
|
+
local skill_target=""
|
|
162
|
+
|
|
163
|
+
cleanup_ahe_config_entries "${target_config_path}"
|
|
164
|
+
|
|
165
|
+
for skill_name in "${MANAGED_SKILLS[@]}"; do
|
|
166
|
+
skill_target="${target_skills_dir}/${skill_name}"
|
|
167
|
+
|
|
168
|
+
if [ -e "${skill_target}" ]; then
|
|
169
|
+
if [ "${backup}" = "true" ]; then
|
|
170
|
+
backup_existing_installation "${skill_target}" "${backup_dir}" "${skill_name}"
|
|
171
|
+
elif [ "${force}" != "true" ]; then
|
|
172
|
+
cat <<EOF >&2
|
|
173
|
+
AHE skill is already installed at:
|
|
174
|
+
${skill_target}
|
|
175
|
+
|
|
176
|
+
Re-run with --force to overwrite or --backup to move the existing install aside first.
|
|
177
|
+
EOF
|
|
178
|
+
exit 1
|
|
179
|
+
else
|
|
180
|
+
rm -rf "${skill_target}"
|
|
181
|
+
fi
|
|
182
|
+
fi
|
|
183
|
+
done
|
|
184
|
+
|
|
185
|
+
if [ -e "${target_shared_dir}" ]; then
|
|
186
|
+
if [ "${backup}" = "true" ]; then
|
|
187
|
+
backup_existing_installation "${target_shared_dir}" "${backup_dir}" "ahe-shared"
|
|
188
|
+
elif [ "${force}" = "true" ]; then
|
|
189
|
+
rm -rf "${target_shared_dir}"
|
|
190
|
+
else
|
|
191
|
+
cat <<EOF >&2
|
|
192
|
+
AHE shared assets are already installed at:
|
|
193
|
+
${target_shared_dir}
|
|
194
|
+
|
|
195
|
+
Re-run with --force to overwrite or --backup to move the existing install aside first.
|
|
196
|
+
EOF
|
|
197
|
+
exit 1
|
|
198
|
+
fi
|
|
199
|
+
fi
|
|
200
|
+
|
|
201
|
+
if [ -e "${target_hooks_dir}" ]; then
|
|
202
|
+
if [ "${backup}" = "true" ]; then
|
|
203
|
+
backup_existing_installation "${target_hooks_dir}" "${backup_dir}" "hooks"
|
|
204
|
+
elif [ "${force}" = "true" ]; then
|
|
205
|
+
rm -rf "${target_hooks_dir}"
|
|
206
|
+
else
|
|
207
|
+
cat <<EOF >&2
|
|
208
|
+
AHE hooks are already installed at:
|
|
209
|
+
${target_hooks_dir}
|
|
210
|
+
|
|
211
|
+
Re-run with --force to overwrite or --backup to move the existing install aside first.
|
|
212
|
+
EOF
|
|
213
|
+
exit 1
|
|
214
|
+
fi
|
|
215
|
+
fi
|
|
216
|
+
|
|
217
|
+
mkdir -p "${target_skills_dir}"
|
|
218
|
+
for skill_name in "${MANAGED_SKILLS[@]}"; do
|
|
219
|
+
cp -R "${SOURCE_SKILLS_DIR}/${skill_name}" "${target_skills_dir}/${skill_name}"
|
|
220
|
+
done
|
|
221
|
+
cp -R "${SOURCE_SHARED_DIR}" "${target_shared_dir}"
|
|
222
|
+
cp -R "${SOURCE_HOOKS_DIR}" "${target_hooks_dir}"
|
|
223
|
+
mkdir -p "${target_agents_dir}"
|
|
224
|
+
cp -R "${SOURCE_AGENTS_DIR}"/* "${target_agents_dir}/"
|
|
225
|
+
|
|
226
|
+
cat <<EOF >> "${target_config_path}"
|
|
227
|
+
${AHE_CONFIG_BLOCK_START}
|
|
228
|
+
[agents.ahe-harness-manager]
|
|
229
|
+
config_file = "${target_agents_dir}/ahe-harness-manager.toml"
|
|
230
|
+
${AHE_CONFIG_BLOCK_END}
|
|
231
|
+
EOF
|
|
232
|
+
cat > "${target_hooks_dir}/hooks.json" <<EOF
|
|
233
|
+
{
|
|
234
|
+
"hooks": {
|
|
235
|
+
"UserPromptSubmit": [
|
|
236
|
+
{
|
|
237
|
+
"hooks": [
|
|
238
|
+
{
|
|
239
|
+
"type": "command",
|
|
240
|
+
"command": "node \"${target_hooks_dir}/ahe-hook.js\"",
|
|
241
|
+
"timeout": 5,
|
|
242
|
+
"statusMessage": "AHE: Checking Keyword Trigger"
|
|
243
|
+
}
|
|
244
|
+
]
|
|
245
|
+
}
|
|
246
|
+
]
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
EOF
|
|
250
|
+
|
|
251
|
+
cat <<EOF
|
|
252
|
+
AHE Codex skill installed.
|
|
253
|
+
Global Codex home:
|
|
254
|
+
${target_codex_home}
|
|
255
|
+
|
|
256
|
+
Next:
|
|
257
|
+
1. Open Codex chat in any workspace.
|
|
258
|
+
2. Use exact \`ahe\` to continue existing harness work or start a new harness when the workspace has none.
|
|
259
|
+
3. Use \`ahe ship\` after Plan Mode to write the latest plan to .plans.
|
|
260
|
+
4. Use \`ahe git\` for the safe git orchestration workflow.
|
|
261
|
+
5. Use \`ahe <query>\` for explicit AHE requests such as \`ahe update product spec\`.
|
|
262
|
+
EOF
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
doctor() {
|
|
266
|
+
printf '=== codex ===\n'
|
|
267
|
+
|
|
268
|
+
local target_codex_home
|
|
269
|
+
target_codex_home="$(codex_home)"
|
|
270
|
+
|
|
271
|
+
local target_skills_dir="${target_codex_home}/skills"
|
|
272
|
+
local target_shared_dir="${target_codex_home}/ahe-shared"
|
|
273
|
+
local target_hooks_dir="${target_codex_home}/hooks"
|
|
274
|
+
local target_agents_dir="${target_codex_home}/agents"
|
|
275
|
+
local target_config_path="${target_codex_home}/config.toml"
|
|
276
|
+
local skill_name=""
|
|
277
|
+
local errors=0
|
|
278
|
+
|
|
279
|
+
for skill_name in "${MANAGED_SKILLS[@]}"; do
|
|
280
|
+
if [ ! -f "${target_skills_dir}/${skill_name}/SKILL.md" ]; then
|
|
281
|
+
printf 'Missing: %s/%s/SKILL.md\n' "${target_skills_dir}" "${skill_name}" >&2
|
|
282
|
+
errors=$((errors + 1))
|
|
283
|
+
fi
|
|
284
|
+
done
|
|
285
|
+
|
|
286
|
+
if [ ! -d "${target_shared_dir}/templates" ]; then
|
|
287
|
+
printf 'Missing: %s/templates\n' "${target_shared_dir}" >&2
|
|
288
|
+
errors=$((errors + 1))
|
|
289
|
+
fi
|
|
290
|
+
|
|
291
|
+
if [ ! -d "${target_shared_dir}/schemas" ]; then
|
|
292
|
+
printf 'Missing: %s/schemas\n' "${target_shared_dir}" >&2
|
|
293
|
+
errors=$((errors + 1))
|
|
294
|
+
fi
|
|
295
|
+
|
|
296
|
+
if [ ! -f "${target_hooks_dir}/hooks.json" ]; then
|
|
297
|
+
printf 'Missing: %s/hooks.json\n' "${target_hooks_dir}" >&2
|
|
298
|
+
errors=$((errors + 1))
|
|
299
|
+
else
|
|
300
|
+
if ! TARGET_HOOKS_DIR="${target_hooks_dir}" node -e "
|
|
301
|
+
try {
|
|
302
|
+
const h = require(process.env.TARGET_HOOKS_DIR + '/hooks.json');
|
|
303
|
+
const cmd = h.hooks.UserPromptSubmit[0].hooks[0].command;
|
|
304
|
+
if (!cmd.includes(process.env.TARGET_HOOKS_DIR + '/ahe-hook.js')) {
|
|
305
|
+
process.exit(1);
|
|
306
|
+
}
|
|
307
|
+
} catch (e) {
|
|
308
|
+
process.exit(1);
|
|
309
|
+
}
|
|
310
|
+
" 2>/dev/null; then
|
|
311
|
+
printf 'Invalid hook command: %s/hooks.json does not point to %s/ahe-hook.js\n' "${target_hooks_dir}" "${target_hooks_dir}" >&2
|
|
312
|
+
errors=$((errors + 1))
|
|
313
|
+
fi
|
|
314
|
+
fi
|
|
315
|
+
|
|
316
|
+
if [ ! -f "${target_hooks_dir}/ahe-hook.js" ]; then
|
|
317
|
+
printf 'Missing: %s/ahe-hook.js\n' "${target_hooks_dir}" >&2
|
|
318
|
+
errors=$((errors + 1))
|
|
319
|
+
fi
|
|
320
|
+
|
|
321
|
+
if [ ! -f "${target_agents_dir}/ahe-harness-manager.toml" ]; then
|
|
322
|
+
printf 'Missing: %s/ahe-harness-manager.toml\n' "${target_agents_dir}" >&2
|
|
323
|
+
errors=$((errors + 1))
|
|
324
|
+
fi
|
|
325
|
+
|
|
326
|
+
if ! grep -q '\[agents\.ahe-harness-manager\]' "${target_config_path}" 2>/dev/null; then
|
|
327
|
+
printf 'Missing: [agents.ahe-harness-manager] in %s\n' "${target_config_path}" >&2
|
|
328
|
+
errors=$((errors + 1))
|
|
329
|
+
fi
|
|
330
|
+
|
|
331
|
+
if [ "${errors}" -gt 0 ]; then
|
|
332
|
+
printf 'AHE Codex skill installation is unhealthy (%d errors).\n' "${errors}" >&2
|
|
333
|
+
exit 1
|
|
334
|
+
fi
|
|
335
|
+
|
|
336
|
+
printf 'AHE Codex skill installation looks healthy.\n'
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
uninstall_skill() {
|
|
340
|
+
local target_codex_home
|
|
341
|
+
target_codex_home="$(codex_home)"
|
|
342
|
+
|
|
343
|
+
local target_skills_dir="${target_codex_home}/skills"
|
|
344
|
+
local target_shared_dir="${target_codex_home}/ahe-shared"
|
|
345
|
+
local target_hooks_dir="${target_codex_home}/hooks"
|
|
346
|
+
local target_agents_dir="${target_codex_home}/agents"
|
|
347
|
+
local target_config_path="${target_codex_home}/config.toml"
|
|
348
|
+
local skill_name=""
|
|
349
|
+
|
|
350
|
+
echo "Uninstalling AHE skills from ${target_codex_home}..."
|
|
351
|
+
|
|
352
|
+
for skill_name in "${MANAGED_SKILLS[@]}"; do
|
|
353
|
+
rm -rf "${target_skills_dir}/${skill_name}"
|
|
354
|
+
done
|
|
355
|
+
|
|
356
|
+
rm -rf "${target_shared_dir}"
|
|
357
|
+
rm -rf "${target_hooks_dir}"
|
|
358
|
+
rm -f "${target_agents_dir}/ahe-harness-manager.toml"
|
|
359
|
+
cleanup_ahe_config_entries "${target_config_path}"
|
|
360
|
+
|
|
361
|
+
echo "AHE skills uninstalled successfully."
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
main() {
|
|
365
|
+
if [ "$#" -eq 0 ]; then
|
|
366
|
+
usage
|
|
367
|
+
exit 1
|
|
368
|
+
fi
|
|
369
|
+
|
|
370
|
+
local command="$1"
|
|
371
|
+
shift
|
|
372
|
+
|
|
373
|
+
case "${command}" in
|
|
374
|
+
install)
|
|
375
|
+
install_skill "$@"
|
|
376
|
+
;;
|
|
377
|
+
uninstall)
|
|
378
|
+
uninstall_skill
|
|
379
|
+
;;
|
|
380
|
+
doctor)
|
|
381
|
+
doctor
|
|
382
|
+
;;
|
|
383
|
+
version)
|
|
384
|
+
printf '%s\n' "${VERSION}"
|
|
385
|
+
;;
|
|
386
|
+
-h|--help|help)
|
|
387
|
+
usage
|
|
388
|
+
exit 0
|
|
389
|
+
;;
|
|
390
|
+
*)
|
|
391
|
+
printf 'Unknown command: %s\n' "${command}" >&2
|
|
392
|
+
usage >&2
|
|
393
|
+
exit 1
|
|
394
|
+
;;
|
|
395
|
+
esac
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
main "$@"
|
package/.codex/hooks/ahe-hook.js
DELETED
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const AHE_DIRECTIVE_MARKER = "<ahe-mode>";
|
|
3
|
-
|
|
4
|
-
const STATUS_TABLE_LINES = [
|
|
5
|
-
" - Start the response with a concise status report table.",
|
|
6
|
-
" - Use this consistent Markdown table format:",
|
|
7
|
-
" | Item | Content |",
|
|
8
|
-
" |---|---|",
|
|
9
|
-
" | AGENTS.md | Exists/missing, purpose status, and any obvious issue. |",
|
|
10
|
-
" | PRODUCT.md | Exists/missing, completion state, and whether product scope needs work. |",
|
|
11
|
-
" | INSTRUCTIONS.md | Exists/missing, and whether instruction boundaries need work. |",
|
|
12
|
-
" | feature-list.json | Valid/missing/invalid, unfinished feature summary, and all-done status. |",
|
|
13
|
-
" | PROGRESS.md | Exists/missing and current session state. |",
|
|
14
|
-
" - Keep the table short and readable.",
|
|
15
|
-
" - Do not include the next step inside the table.",
|
|
16
|
-
];
|
|
17
|
-
|
|
18
|
-
const COMMON_ROUTING_LINES = [
|
|
19
|
-
"1. Run CodeGraph preflight before inspecting harness status:",
|
|
20
|
-
" - Check whether the CodeGraph CLI is installed with `command -v codegraph`.",
|
|
21
|
-
" - If the `codegraph` command is not installed, report `NOT INSTALLATION of codegraph`, skip `codegraph init` and `codegraph sync`, and continue with normal repo inspection.",
|
|
22
|
-
" - If `.codegraph/` does not exist, run `codegraph init` before reviewing code.",
|
|
23
|
-
" - If `.codegraph/` exists, run `codegraph sync` before reviewing code.",
|
|
24
|
-
"",
|
|
25
|
-
"2. Inspect current harness state before choosing a workflow:",
|
|
26
|
-
" - Check `AGENTS.md`.",
|
|
27
|
-
" - Check `docs/PRODUCT.md` and `docs/INSTRUCTIONS.md` as the product/specification source of truth.",
|
|
28
|
-
" - Check `feature-list.json` as a derived tracker.",
|
|
29
|
-
" - Check `PROGRESS.md`.",
|
|
30
|
-
" - Use `ahe-thinker` as the internal decision layer before choosing the next action.",
|
|
31
|
-
" - Before reading large harness files wholesale, let `ahe-thinker` run the `ahe-compression` size detector and call `ahe-compression` if compression is required.",
|
|
32
|
-
"",
|
|
33
|
-
"3. Review code through CodeGraph when available:",
|
|
34
|
-
" - Prefer CodeGraph MCP or CodeGraph exploration for code review and impact context after the preflight command succeeds.",
|
|
35
|
-
" - If CodeGraph is not installed, skip CodeGraph review and rely on normal repo inspection.",
|
|
36
|
-
"",
|
|
37
|
-
"4. Make the first response a simple harness engineering status report table before proceeding:",
|
|
38
|
-
...STATUS_TABLE_LINES,
|
|
39
|
-
];
|
|
40
|
-
|
|
41
|
-
const AHE_PROGRESS_DIRECTIVE = [
|
|
42
|
-
AHE_DIRECTIVE_MARKER,
|
|
43
|
-
"AHE automatic operation activated.",
|
|
44
|
-
"",
|
|
45
|
-
"The user sent the exact AHE command. Operate as the Awesome Harness Engineering router:",
|
|
46
|
-
"",
|
|
47
|
-
...COMMON_ROUTING_LINES,
|
|
48
|
-
"",
|
|
49
|
-
"5. Decide the next AHE workflow with `ahe-thinker`:",
|
|
50
|
-
" - If no harness files exist, route to `$ahe-init`.",
|
|
51
|
-
" - If `docs/PRODUCT.md` or `docs/INSTRUCTIONS.md` is missing or empty, classify the state as `harness engineering not enough`.",
|
|
52
|
-
" - If `feature-list.json` is missing or invalid, generating an empty one from template is allowed, but do not write specific features until `docs/PRODUCT.md` and `docs/INSTRUCTIONS.md` are created and organized.",
|
|
53
|
-
" - If any feature in `feature-list.json` has a status other than `done`, classify the state as `in the middle of building features` and continue the first unfinished feature whose dependencies are satisfied.",
|
|
54
|
-
" - If all features are `done` and no obvious harness gap remains, classify the state as `completed all` and ask the user for the next task.",
|
|
55
|
-
" - Call `ahe-reviewer` when repo or code understanding is needed.",
|
|
56
|
-
" - Call `ahe-conversator` when the next safe step is blocked on user input.",
|
|
57
|
-
" - Call `ahe-harness` when product docs, instructions, tracking, todo sync, or compression-aware harness maintenance must change.",
|
|
58
|
-
" - Call `ahe-solver` when the next job is solving or planning a feature.",
|
|
59
|
-
"",
|
|
60
|
-
"6. After the table, classify the harness into exactly one state.",
|
|
61
|
-
" - Use exactly one state: `harness engineering not enough`, `in the middle of building features`, or `completed all`.",
|
|
62
|
-
" - Do not include the next step inside the table.",
|
|
63
|
-
" - Continue automatically after classification.",
|
|
64
|
-
];
|
|
65
|
-
|
|
66
|
-
const AHE_INIT_DIRECTIVE = [
|
|
67
|
-
AHE_DIRECTIVE_MARKER,
|
|
68
|
-
"AHE automatic operation activated.",
|
|
69
|
-
"",
|
|
70
|
-
"The user sent the exact AHE init command. Treat this as a possible new start request:",
|
|
71
|
-
"",
|
|
72
|
-
"1. Route to `$ahe-init` first.",
|
|
73
|
-
"2. If no AHE-managed harness files exist, start initialization normally.",
|
|
74
|
-
"3. If any AHE-managed harness file exists, read the existing files, summarize the current project purpose and product specification state, and ask what restart scope the user wants.",
|
|
75
|
-
"4. Do not remove, overwrite, or refresh existing harness files before the user answers the restart-scope question.",
|
|
76
|
-
"5. If the chosen restart scope replaces prior harness history, summarize that replaced state in the refreshed tracking artifacts instead of creating backup copies.",
|
|
77
|
-
"6. Interpret the restart scope from the user's free-form answer; examples like `purpose` and `product` are not a closed list.",
|
|
78
|
-
"7. Product/instructions specification details belong in `docs/PRODUCT.md` and `docs/INSTRUCTIONS.md`, not `AGENTS.md`.",
|
|
79
|
-
"8. After setup, call `ahe-harness` to build the initial product, instructions, and tracking state.",
|
|
80
|
-
"9. Use `ahe-thinker` before clarification when the next setup step is uncertain.",
|
|
81
|
-
"10. If clarification is needed, call `ahe-conversator` for the exact missing detail.",
|
|
82
|
-
].join("\n");
|
|
83
|
-
|
|
84
|
-
function getQueryDirective(prompt) {
|
|
85
|
-
return [
|
|
86
|
-
AHE_DIRECTIVE_MARKER,
|
|
87
|
-
"AHE automatic operation activated.",
|
|
88
|
-
"",
|
|
89
|
-
`Original prompt: "${prompt}"`,
|
|
90
|
-
"",
|
|
91
|
-
"The user sent an explicit AHE query. Route it through `ahe-thinker`:",
|
|
92
|
-
"",
|
|
93
|
-
...COMMON_ROUTING_LINES,
|
|
94
|
-
"",
|
|
95
|
-
"5. Decide the next AHE workflow with `ahe-thinker` based on the original prompt:",
|
|
96
|
-
" - Use `ahe-reviewer` for code or harness review work.",
|
|
97
|
-
" - Use `ahe-harness` for product, instructions, progress, feature-list, todo, or compression maintenance.",
|
|
98
|
-
" - For `ahe compress feature-list`, replace old completed feature entries with one summarized done feature, preserve unfinished details, and reconcile `feature-list.json` against `docs/PRODUCT.md`.",
|
|
99
|
-
" - If no new feature can be derived from `docs/PRODUCT.md`, call `ahe-conversator` to ask what next feature, product direction, or goal should be tracked.",
|
|
100
|
-
" - Use `ahe-solver` for feature-solving work.",
|
|
101
|
-
" - If multiple plausible next steps remain, use `ahe-conversator` to ask the minimum question needed.",
|
|
102
|
-
"",
|
|
103
|
-
"6. After the table, classify the harness into exactly one state.",
|
|
104
|
-
" - Use exactly one state: `harness engineering not enough`, `in the middle of building features`, or `completed all`.",
|
|
105
|
-
" - Do not include the next step inside the table.",
|
|
106
|
-
" - Continue automatically after classification.",
|
|
107
|
-
].join("\n");
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
function normalizePrompt(prompt) {
|
|
111
|
-
return prompt.trim().toLowerCase();
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
function isExactAheCommand(prompt) {
|
|
115
|
-
return normalizePrompt(prompt) === "ahe";
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
function isExactAheInitCommand(prompt) {
|
|
119
|
-
const normalizedPrompt = normalizePrompt(prompt);
|
|
120
|
-
return (
|
|
121
|
-
normalizedPrompt === "ahe init" ||
|
|
122
|
-
normalizedPrompt === "ahe-init" ||
|
|
123
|
-
normalizedPrompt === "$ahe-init"
|
|
124
|
-
);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
function isExplicitAheQuery(prompt) {
|
|
128
|
-
const normalizedPrompt = normalizePrompt(prompt);
|
|
129
|
-
if (isExactAheCommand(prompt) || isExactAheInitCommand(prompt)) {
|
|
130
|
-
return false;
|
|
131
|
-
}
|
|
132
|
-
return normalizedPrompt.startsWith("ahe ");
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
async function main() {
|
|
136
|
-
let raw = "";
|
|
137
|
-
process.stdin.setEncoding("utf8");
|
|
138
|
-
for await (const chunk of process.stdin) {
|
|
139
|
-
raw += chunk;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
if (!raw.trim()) {
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
let parsed;
|
|
147
|
-
try {
|
|
148
|
-
parsed = JSON.parse(raw);
|
|
149
|
-
} catch {
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
if (
|
|
154
|
-
parsed &&
|
|
155
|
-
parsed.hook_event_name === "UserPromptSubmit" &&
|
|
156
|
-
typeof parsed.prompt === "string"
|
|
157
|
-
) {
|
|
158
|
-
if (isExactAheCommand(parsed.prompt)) {
|
|
159
|
-
process.stdout.write(
|
|
160
|
-
JSON.stringify({
|
|
161
|
-
hookSpecificOutput: {
|
|
162
|
-
hookEventName: "UserPromptSubmit",
|
|
163
|
-
additionalContext: AHE_PROGRESS_DIRECTIVE.join("\n"),
|
|
164
|
-
},
|
|
165
|
-
}) + "\n"
|
|
166
|
-
);
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
if (isExactAheInitCommand(parsed.prompt)) {
|
|
171
|
-
process.stdout.write(
|
|
172
|
-
JSON.stringify({
|
|
173
|
-
hookSpecificOutput: {
|
|
174
|
-
hookEventName: "UserPromptSubmit",
|
|
175
|
-
additionalContext: AHE_INIT_DIRECTIVE,
|
|
176
|
-
},
|
|
177
|
-
}) + "\n"
|
|
178
|
-
);
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
if (isExplicitAheQuery(parsed.prompt)) {
|
|
183
|
-
process.stdout.write(
|
|
184
|
-
JSON.stringify({
|
|
185
|
-
hookSpecificOutput: {
|
|
186
|
-
hookEventName: "UserPromptSubmit",
|
|
187
|
-
additionalContext: getQueryDirective(parsed.prompt),
|
|
188
|
-
},
|
|
189
|
-
}) + "\n"
|
|
190
|
-
);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
main().catch(() => {});
|