codex-genesis-harness 0.1.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.
- package/.codex/skills/project-genesis-harness/SKILL.md +727 -0
- package/.codex/skills/project-genesis-harness/agents/openai.yaml +9 -0
- package/.codex/skills/project-genesis-harness/references/planning-schema.md +35 -0
- package/.codex/skills/project-genesis-harness/references/quality-rubric.md +21 -0
- package/.codex/skills/project-genesis-harness/references/research-rubric.md +41 -0
- package/.codex/skills/project-genesis-harness/references/workflows.md +33 -0
- package/.codex/skills/project-genesis-harness/resources/agents-template.md +27 -0
- package/.codex/skills/project-genesis-harness/resources/api-docs-template.md +32 -0
- package/.codex/skills/project-genesis-harness/resources/architecture-template.md +30 -0
- package/.codex/skills/project-genesis-harness/resources/audit-template.md +26 -0
- package/.codex/skills/project-genesis-harness/resources/bug-template.md +34 -0
- package/.codex/skills/project-genesis-harness/resources/check-template.md +21 -0
- package/.codex/skills/project-genesis-harness/resources/conventions-template.md +42 -0
- package/.codex/skills/project-genesis-harness/resources/decision-template.md +33 -0
- package/.codex/skills/project-genesis-harness/resources/design-template.md +26 -0
- package/.codex/skills/project-genesis-harness/resources/escalation-template.md +21 -0
- package/.codex/skills/project-genesis-harness/resources/feature-template.md +49 -0
- package/.codex/skills/project-genesis-harness/resources/integrations-template.md +32 -0
- package/.codex/skills/project-genesis-harness/resources/journeys-template.md +13 -0
- package/.codex/skills/project-genesis-harness/resources/lessons-learned-template.md +12 -0
- package/.codex/skills/project-genesis-harness/resources/observability-template.md +34 -0
- package/.codex/skills/project-genesis-harness/resources/phase-template.md +34 -0
- package/.codex/skills/project-genesis-harness/resources/pitfalls-template.md +22 -0
- package/.codex/skills/project-genesis-harness/resources/planning-tree-template.md +39 -0
- package/.codex/skills/project-genesis-harness/resources/project-template.md +38 -0
- package/.codex/skills/project-genesis-harness/resources/quality-score-template.md +11 -0
- package/.codex/skills/project-genesis-harness/resources/requirements-template.md +26 -0
- package/.codex/skills/project-genesis-harness/resources/research-template.md +26 -0
- package/.codex/skills/project-genesis-harness/resources/review-template.md +22 -0
- package/.codex/skills/project-genesis-harness/resources/spec-changelog-template.md +6 -0
- package/.codex/skills/project-genesis-harness/resources/stack-template.md +33 -0
- package/.codex/skills/project-genesis-harness/resources/verification-template.md +26 -0
- package/.codex/skills/project-genesis-harness/scripts/check-architecture-boundaries.sh +23 -0
- package/.codex/skills/project-genesis-harness/scripts/check-docs-sync.sh +24 -0
- package/.codex/skills/project-genesis-harness/scripts/check-no-debug-logs.sh +21 -0
- package/.codex/skills/project-genesis-harness/scripts/check-required-planning-files.sh +46 -0
- package/.codex/skills/project-genesis-harness/scripts/check-spec-changelog.sh +24 -0
- package/.codex/skills/project-genesis-harness/scripts/check-task-tracking.sh +25 -0
- package/.codex/skills/project-genesis-harness/scripts/create-adr.sh +74 -0
- package/.codex/skills/project-genesis-harness/scripts/create-bug.sh +160 -0
- package/.codex/skills/project-genesis-harness/scripts/create-feature.sh +217 -0
- package/.codex/skills/project-genesis-harness/scripts/detect-stack.sh +26 -0
- package/.codex/skills/project-genesis-harness/scripts/init-planning.sh +719 -0
- package/.codex/skills/project-genesis-harness/scripts/list-changed-files.sh +12 -0
- package/.codex/skills/project-genesis-harness/scripts/run-verification.sh +47 -0
- package/.codex/skills/project-genesis-harness/scripts/update-state.sh +33 -0
- package/.codex-plugin/plugin.json +35 -0
- package/LICENSE +22 -0
- package/README.md +181 -0
- package/VERSION +2 -0
- package/bin/genesis-harness.js +164 -0
- package/package.json +37 -0
- package/scripts/install.sh +69 -0
- package/scripts/run-evals.sh +52 -0
- package/scripts/uninstall.sh +52 -0
- package/scripts/verify.sh +109 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
root="${1:-.}"
|
|
5
|
+
cd "$root"
|
|
6
|
+
|
|
7
|
+
run_if() {
|
|
8
|
+
local label="$1"
|
|
9
|
+
shift
|
|
10
|
+
echo "==> $label"
|
|
11
|
+
"$@"
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if [ -f package.json ]; then
|
|
15
|
+
if command -v npm >/dev/null 2>&1; then
|
|
16
|
+
npm run lint --if-present
|
|
17
|
+
npm run typecheck --if-present
|
|
18
|
+
npm test --if-present
|
|
19
|
+
npm run build --if-present
|
|
20
|
+
fi
|
|
21
|
+
elif [ -f pyproject.toml ] || [ -f requirements.txt ]; then
|
|
22
|
+
command -v pytest >/dev/null 2>&1 && run_if "pytest" pytest -q
|
|
23
|
+
command -v ruff >/dev/null 2>&1 && run_if "ruff" ruff check .
|
|
24
|
+
command -v mypy >/dev/null 2>&1 && run_if "mypy" mypy .
|
|
25
|
+
elif [ -f Cargo.toml ]; then
|
|
26
|
+
run_if "cargo test" cargo test
|
|
27
|
+
run_if "cargo clippy" cargo clippy -- -D warnings
|
|
28
|
+
elif [ -f go.mod ]; then
|
|
29
|
+
run_if "go test" go test ./...
|
|
30
|
+
elif [ -f composer.json ]; then
|
|
31
|
+
command -v composer >/dev/null 2>&1 && composer test || true
|
|
32
|
+
else
|
|
33
|
+
echo "No known verification command detected. Add project-specific commands to .planning/SMOKE_TESTS.md."
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
for check in \
|
|
37
|
+
check-required-planning-files.sh \
|
|
38
|
+
check-task-tracking.sh \
|
|
39
|
+
check-no-debug-logs.sh \
|
|
40
|
+
check-spec-changelog.sh \
|
|
41
|
+
check-architecture-boundaries.sh
|
|
42
|
+
do
|
|
43
|
+
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
44
|
+
if [ -x "$script_dir/$check" ]; then
|
|
45
|
+
run_if "$check" "$script_dir/$check" "$root"
|
|
46
|
+
fi
|
|
47
|
+
done
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
usage() {
|
|
5
|
+
echo "Usage: $0 <root> <current-phase> <active-work> <last-completed-task> <next-task> <latest-verification>" >&2
|
|
6
|
+
exit 2
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
root="${1:-}"
|
|
10
|
+
phase="${2:-}"
|
|
11
|
+
active="${3:-}"
|
|
12
|
+
last="${4:-}"
|
|
13
|
+
next="${5:-}"
|
|
14
|
+
verification="${6:-}"
|
|
15
|
+
|
|
16
|
+
[ -n "$root" ] && [ -n "$phase" ] && [ -n "$active" ] && [ -n "$last" ] && [ -n "$next" ] && [ -n "$verification" ] || usage
|
|
17
|
+
|
|
18
|
+
cd "$root"
|
|
19
|
+
mkdir -p .planning
|
|
20
|
+
|
|
21
|
+
cat > .planning/STATE.md <<EOF
|
|
22
|
+
# State
|
|
23
|
+
|
|
24
|
+
Current project state: [~] Active
|
|
25
|
+
Current phase: $phase
|
|
26
|
+
Current feature or bug: $active
|
|
27
|
+
Last completed task: $last
|
|
28
|
+
Next task: $next
|
|
29
|
+
Blocked items: None recorded
|
|
30
|
+
Latest verification result: $verification
|
|
31
|
+
EOF
|
|
32
|
+
|
|
33
|
+
echo ".planning/STATE.md"
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "project-genesis-harness",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Codex project operating harness for planning, tracking, verification, docs sync, and reviews.",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Project Genesis Harness"
|
|
7
|
+
},
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"keywords": [
|
|
10
|
+
"codex",
|
|
11
|
+
"skill",
|
|
12
|
+
"planning",
|
|
13
|
+
"verification",
|
|
14
|
+
"engineering"
|
|
15
|
+
],
|
|
16
|
+
"skills": "./.codex/skills/",
|
|
17
|
+
"interface": {
|
|
18
|
+
"displayName": "Project Genesis Harness",
|
|
19
|
+
"shortDescription": "Planning and verification harness for Codex",
|
|
20
|
+
"longDescription": "A Codex plugin that installs the project-genesis-harness skill for disciplined project initialization, feature planning, bug workflows, documentation synchronization, verification, audits, and completion reports.",
|
|
21
|
+
"developerName": "Project Genesis Harness",
|
|
22
|
+
"category": "Productivity",
|
|
23
|
+
"capabilities": [
|
|
24
|
+
"Write",
|
|
25
|
+
"Review"
|
|
26
|
+
],
|
|
27
|
+
"defaultPrompt": [
|
|
28
|
+
"Use $project-genesis-harness and run /init.",
|
|
29
|
+
"Use $project-genesis-harness to plan this feature.",
|
|
30
|
+
"Use $project-genesis-harness to audit this repo."
|
|
31
|
+
],
|
|
32
|
+
"brandColor": "#2563EB"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Project Genesis Harness contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# Project Genesis Harness
|
|
2
|
+
|
|
3
|
+
Project Genesis Harness is a Codex skill that turns Codex into a project operating harness: planning first, repository inspection, task tracking, test-first implementation, docs synchronization, architecture decisions, Mermaid diagrams, audits, and completion reports.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
### From npm
|
|
8
|
+
|
|
9
|
+
After the package is published to npm:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install -g codex-genesis-harness@latest
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
The package auto-installs the Codex skill into:
|
|
16
|
+
|
|
17
|
+
```txt
|
|
18
|
+
~/.agents/skills/project-genesis-harness
|
|
19
|
+
~/.codex/skills/project-genesis-harness
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
You can also manage it manually:
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
genesis-harness install
|
|
26
|
+
genesis-harness verify
|
|
27
|
+
genesis-harness uninstall
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Install only one target:
|
|
31
|
+
|
|
32
|
+
```sh
|
|
33
|
+
genesis-harness install --target agents
|
|
34
|
+
genesis-harness install --target legacy
|
|
35
|
+
genesis-harness install --target both
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
To skip auto-install during npm installation:
|
|
39
|
+
|
|
40
|
+
```sh
|
|
41
|
+
GENESIS_HARNESS_SKIP_POSTINSTALL=1 npm install -g codex-genesis-harness@latest
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### From Git
|
|
45
|
+
|
|
46
|
+
Clone or download this repository, then run:
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
./scripts/install.sh
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
By default, the installer copies the skill to:
|
|
53
|
+
|
|
54
|
+
```txt
|
|
55
|
+
~/.agents/skills/project-genesis-harness
|
|
56
|
+
~/.codex/skills/project-genesis-harness
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
If you use a custom Codex home:
|
|
60
|
+
|
|
61
|
+
```sh
|
|
62
|
+
CODEX_HOME=/path/to/.codex ./scripts/install.sh
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
If you use a custom modern skills home:
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
GENESIS_HARNESS_HOME=/path/to/.agents ./scripts/install.sh
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Verify
|
|
72
|
+
|
|
73
|
+
```sh
|
|
74
|
+
./scripts/verify.sh
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Verify an installed copy:
|
|
78
|
+
|
|
79
|
+
```sh
|
|
80
|
+
./scripts/verify.sh ~/.codex/skills/project-genesis-harness
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Uninstall
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
./scripts/uninstall.sh
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Use
|
|
90
|
+
|
|
91
|
+
After installing, invoke the skill in Codex when working in a project:
|
|
92
|
+
|
|
93
|
+
```txt
|
|
94
|
+
Use $project-genesis-harness and run /init.
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The skill supports:
|
|
98
|
+
|
|
99
|
+
- `/init`
|
|
100
|
+
- `/new-feature <description>`
|
|
101
|
+
- `/fix-bug <description>`
|
|
102
|
+
- `/plan <description>`
|
|
103
|
+
- `/audit`
|
|
104
|
+
- `/review`
|
|
105
|
+
- `/status`
|
|
106
|
+
|
|
107
|
+
## What Gets Installed
|
|
108
|
+
|
|
109
|
+
```txt
|
|
110
|
+
.codex/skills/project-genesis-harness/
|
|
111
|
+
├── SKILL.md
|
|
112
|
+
├── agents/openai.yaml
|
|
113
|
+
├── resources/
|
|
114
|
+
└── scripts/
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
The skill itself can initialize a target project with a `.planning/` knowledge base after the project brief is confirmed.
|
|
118
|
+
|
|
119
|
+
## Plugin Metadata
|
|
120
|
+
|
|
121
|
+
This repository includes:
|
|
122
|
+
|
|
123
|
+
```txt
|
|
124
|
+
.codex-plugin/plugin.json
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
The plugin manifest points Codex-compatible plugin tooling at the packaged skill under `.codex/skills/`.
|
|
128
|
+
|
|
129
|
+
## Publish To npm
|
|
130
|
+
|
|
131
|
+
The npm package name is:
|
|
132
|
+
|
|
133
|
+
```txt
|
|
134
|
+
codex-genesis-harness
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
Publish flow:
|
|
138
|
+
|
|
139
|
+
```sh
|
|
140
|
+
npm login
|
|
141
|
+
npm run verify
|
|
142
|
+
npm run eval
|
|
143
|
+
npm run pack:check
|
|
144
|
+
npm version patch
|
|
145
|
+
npm publish --access public
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
The package is intentionally unscoped so it can be published by the token owner without requiring a pre-created npm organization or scope.
|
|
149
|
+
|
|
150
|
+
## GitHub Actions npm Publish
|
|
151
|
+
|
|
152
|
+
This repository includes `.github/workflows/publish-npm.yml`.
|
|
153
|
+
|
|
154
|
+
On every push to `main`, the workflow:
|
|
155
|
+
|
|
156
|
+
1. runs `npm run verify`
|
|
157
|
+
2. runs `npm run eval`
|
|
158
|
+
3. runs `npm run pack:check`
|
|
159
|
+
4. derives a unique CI version like `0.1.0-ci.123.1`
|
|
160
|
+
5. publishes `codex-genesis-harness` to npm with the `latest` tag
|
|
161
|
+
|
|
162
|
+
Required GitHub secret:
|
|
163
|
+
|
|
164
|
+
```txt
|
|
165
|
+
NPM_TOKEN
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Create it from npm with publish permission for `codex-genesis-harness`, then add it under:
|
|
169
|
+
|
|
170
|
+
```txt
|
|
171
|
+
GitHub repo -> Settings -> Secrets and variables -> Actions -> New repository secret
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
If GitHub Actions fails with `npm ERR! code E403` during `npm publish`, npm accepted the token format but rejected the publish authorization. Fix the npm-side credentials before re-running the workflow:
|
|
175
|
+
|
|
176
|
+
1. Confirm the token belongs to an npm account that owns `codex-genesis-harness`, or can create the package if this is the first publish.
|
|
177
|
+
2. Prefer an npm automation token with publish rights for CI. Granular tokens must include package write access.
|
|
178
|
+
3. If the package name is already owned by another account or organization, either transfer/grant access on npm or rename/scope the package in `package.json`.
|
|
179
|
+
4. Replace the GitHub `NPM_TOKEN` secret after rotating the token.
|
|
180
|
+
|
|
181
|
+
The workflow validates `NPM_TOKEN` and package visibility before running the expensive verification and publish steps so credential problems fail with an actionable error.
|
package/VERSION
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
const fs = require("fs");
|
|
5
|
+
const path = require("path");
|
|
6
|
+
const { spawnSync } = require("child_process");
|
|
7
|
+
|
|
8
|
+
const packageRoot = path.resolve(__dirname, "..");
|
|
9
|
+
const skillName = "project-genesis-harness";
|
|
10
|
+
const sourceDir = path.join(packageRoot, ".codex", "skills", skillName);
|
|
11
|
+
const codexHome = process.env.CODEX_HOME || path.join(process.env.HOME || "", ".codex");
|
|
12
|
+
const agentsHome = process.env.GENESIS_HARNESS_HOME || path.join(process.env.HOME || "", ".agents");
|
|
13
|
+
const legacyTargetDir = path.join(codexHome, "skills", skillName);
|
|
14
|
+
const agentsTargetDir = path.join(agentsHome, "skills", skillName);
|
|
15
|
+
|
|
16
|
+
function usage(exitCode = 0) {
|
|
17
|
+
const text = `
|
|
18
|
+
Project Genesis Harness
|
|
19
|
+
|
|
20
|
+
Usage:
|
|
21
|
+
genesis-harness install [--target agents|legacy|both]
|
|
22
|
+
genesis-harness verify [--target agents|legacy|both]
|
|
23
|
+
genesis-harness uninstall [--target agents|legacy|both]
|
|
24
|
+
genesis-harness path
|
|
25
|
+
|
|
26
|
+
Environment:
|
|
27
|
+
CODEX_HOME=/custom/.codex Override Codex home
|
|
28
|
+
GENESIS_HARNESS_HOME=/custom/.agents Override modern skills home
|
|
29
|
+
GENESIS_HARNESS_SKIP_POSTINSTALL=1 Skip npm postinstall auto-install
|
|
30
|
+
`;
|
|
31
|
+
console.log(text.trim());
|
|
32
|
+
process.exit(exitCode);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function fail(message) {
|
|
36
|
+
console.error(`genesis-harness: ${message}`);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function ensureSource() {
|
|
41
|
+
const skillFile = path.join(sourceDir, "SKILL.md");
|
|
42
|
+
if (!fs.existsSync(skillFile)) {
|
|
43
|
+
fail(`missing packaged skill at ${skillFile}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function parseTarget(args, fallback = "both") {
|
|
48
|
+
let target = fallback;
|
|
49
|
+
for (let i = 0; i < args.length; i++) {
|
|
50
|
+
if (args[i] === "--target") {
|
|
51
|
+
target = args[i + 1];
|
|
52
|
+
i++;
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
usage(2);
|
|
56
|
+
}
|
|
57
|
+
if (!["agents", "legacy", "both"].includes(target)) usage(2);
|
|
58
|
+
return target;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function targetDirs(target) {
|
|
62
|
+
if (target === "agents") return [agentsTargetDir];
|
|
63
|
+
if (target === "legacy") return [legacyTargetDir];
|
|
64
|
+
return [agentsTargetDir, legacyTargetDir];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function copySkill({ quiet = false, target = "both" } = {}) {
|
|
68
|
+
ensureSource();
|
|
69
|
+
for (const dir of targetDirs(target)) {
|
|
70
|
+
fs.mkdirSync(path.dirname(dir), { recursive: true });
|
|
71
|
+
|
|
72
|
+
if (fs.existsSync(dir)) {
|
|
73
|
+
const backupDir = `${dir}.backup.${timestamp()}`;
|
|
74
|
+
fs.renameSync(dir, backupDir);
|
|
75
|
+
if (!quiet) console.log(`Existing skill backed up to: ${backupDir}`);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
fs.cpSync(sourceDir, dir, { recursive: true });
|
|
79
|
+
chmodScripts(path.join(dir, "scripts"));
|
|
80
|
+
|
|
81
|
+
if (!quiet) console.log(`Installed ${skillName} to: ${dir}`);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (!quiet) console.log(`Restart Codex, then invoke: Use $${skillName}`);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function uninstallSkill(target = "both") {
|
|
88
|
+
for (const dir of targetDirs(target)) {
|
|
89
|
+
if (!fs.existsSync(dir)) {
|
|
90
|
+
console.log(`Skill is not installed at: ${dir}`);
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
94
|
+
console.log(`Removed: ${dir}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function verifySkill(target = "both") {
|
|
99
|
+
const verifyScript = path.join(packageRoot, "scripts", "verify.sh");
|
|
100
|
+
if (!fs.existsSync(verifyScript)) fail(`missing verify script at ${verifyScript}`);
|
|
101
|
+
|
|
102
|
+
for (const verifyTarget of targetDirs(target)) {
|
|
103
|
+
const result = spawnSync("bash", [verifyScript, verifyTarget], {
|
|
104
|
+
stdio: "inherit",
|
|
105
|
+
env: process.env
|
|
106
|
+
});
|
|
107
|
+
if (result.status) process.exit(result.status);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function chmodScripts(dir) {
|
|
112
|
+
if (!fs.existsSync(dir)) return;
|
|
113
|
+
for (const entry of fs.readdirSync(dir)) {
|
|
114
|
+
const file = path.join(dir, entry);
|
|
115
|
+
if (entry.endsWith(".sh") && fs.statSync(file).isFile()) {
|
|
116
|
+
fs.chmodSync(file, 0o755);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function timestamp() {
|
|
122
|
+
const date = new Date();
|
|
123
|
+
const pad = (value) => String(value).padStart(2, "0");
|
|
124
|
+
return [
|
|
125
|
+
date.getFullYear(),
|
|
126
|
+
pad(date.getMonth() + 1),
|
|
127
|
+
pad(date.getDate()),
|
|
128
|
+
pad(date.getHours()),
|
|
129
|
+
pad(date.getMinutes()),
|
|
130
|
+
pad(date.getSeconds())
|
|
131
|
+
].join("");
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const command = process.argv[2] || "help";
|
|
135
|
+
const args = process.argv.slice(3);
|
|
136
|
+
|
|
137
|
+
switch (command) {
|
|
138
|
+
case "install":
|
|
139
|
+
copySkill({ target: parseTarget(args, "both") });
|
|
140
|
+
break;
|
|
141
|
+
case "postinstall":
|
|
142
|
+
if (process.env.GENESIS_HARNESS_SKIP_POSTINSTALL === "1") {
|
|
143
|
+
process.exit(0);
|
|
144
|
+
}
|
|
145
|
+
copySkill({ quiet: true, target: "both" });
|
|
146
|
+
break;
|
|
147
|
+
case "verify":
|
|
148
|
+
verifySkill(parseTarget(args, "both"));
|
|
149
|
+
break;
|
|
150
|
+
case "uninstall":
|
|
151
|
+
uninstallSkill(parseTarget(args, "both"));
|
|
152
|
+
break;
|
|
153
|
+
case "path":
|
|
154
|
+
console.log(agentsTargetDir);
|
|
155
|
+
console.log(legacyTargetDir);
|
|
156
|
+
break;
|
|
157
|
+
case "help":
|
|
158
|
+
case "--help":
|
|
159
|
+
case "-h":
|
|
160
|
+
usage(0);
|
|
161
|
+
break;
|
|
162
|
+
default:
|
|
163
|
+
usage(2);
|
|
164
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "codex-genesis-harness",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Install and manage the Project Genesis Harness Codex skill.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"bin": {
|
|
7
|
+
"genesis-harness": "bin/genesis-harness.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"postinstall": "node bin/genesis-harness.js postinstall",
|
|
11
|
+
"verify": "bash scripts/verify.sh",
|
|
12
|
+
"eval": "bash scripts/run-evals.sh",
|
|
13
|
+
"pack:check": "npm pack --dry-run"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
".codex-plugin",
|
|
17
|
+
".codex/skills/project-genesis-harness",
|
|
18
|
+
"bin",
|
|
19
|
+
"scripts",
|
|
20
|
+
"README.md",
|
|
21
|
+
"LICENSE",
|
|
22
|
+
"VERSION"
|
|
23
|
+
],
|
|
24
|
+
"keywords": [
|
|
25
|
+
"codex",
|
|
26
|
+
"codex-skill",
|
|
27
|
+
"planning",
|
|
28
|
+
"project-management",
|
|
29
|
+
"engineering-harness"
|
|
30
|
+
],
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=18"
|
|
33
|
+
},
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
5
|
+
skill_name="project-genesis-harness"
|
|
6
|
+
source_dir="$repo_root/.codex/skills/$skill_name"
|
|
7
|
+
codex_home="${CODEX_HOME:-$HOME/.codex}"
|
|
8
|
+
agents_home="${GENESIS_HARNESS_HOME:-$HOME/.agents}"
|
|
9
|
+
target="both"
|
|
10
|
+
|
|
11
|
+
usage() {
|
|
12
|
+
echo "Usage: $0 [--target agents|legacy|both]" >&2
|
|
13
|
+
echo " agents: install to ${agents_home}/skills/${skill_name}" >&2
|
|
14
|
+
echo " legacy: install to ${codex_home}/skills/${skill_name}" >&2
|
|
15
|
+
echo " both: install to both locations" >&2
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
while [ "$#" -gt 0 ]; do
|
|
19
|
+
case "$1" in
|
|
20
|
+
--target)
|
|
21
|
+
target="${2:-}"
|
|
22
|
+
[ -n "$target" ] || { usage; exit 2; }
|
|
23
|
+
shift 2
|
|
24
|
+
;;
|
|
25
|
+
--help|-h)
|
|
26
|
+
usage
|
|
27
|
+
exit 0
|
|
28
|
+
;;
|
|
29
|
+
*)
|
|
30
|
+
usage
|
|
31
|
+
exit 2
|
|
32
|
+
;;
|
|
33
|
+
esac
|
|
34
|
+
done
|
|
35
|
+
|
|
36
|
+
case "$target" in
|
|
37
|
+
agents|legacy|both) ;;
|
|
38
|
+
*) usage; exit 2 ;;
|
|
39
|
+
esac
|
|
40
|
+
|
|
41
|
+
if [ ! -f "$source_dir/SKILL.md" ]; then
|
|
42
|
+
echo "Missing skill source: $source_dir/SKILL.md" >&2
|
|
43
|
+
exit 1
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
install_one() {
|
|
47
|
+
local target_dir="$1"
|
|
48
|
+
mkdir -p "$(dirname "$target_dir")"
|
|
49
|
+
|
|
50
|
+
if [ -e "$target_dir" ]; then
|
|
51
|
+
backup_dir="${target_dir}.backup.$(date +%Y%m%d%H%M%S)"
|
|
52
|
+
mv "$target_dir" "$backup_dir"
|
|
53
|
+
echo "Existing skill backed up to: $backup_dir"
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
cp -R "$source_dir" "$target_dir"
|
|
57
|
+
find "$target_dir/scripts" -type f -name '*.sh' -exec chmod +x {} \;
|
|
58
|
+
echo "Installed $skill_name to: $target_dir"
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if [ "$target" = "agents" ] || [ "$target" = "both" ]; then
|
|
62
|
+
install_one "$agents_home/skills/$skill_name"
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
if [ "$target" = "legacy" ] || [ "$target" = "both" ]; then
|
|
66
|
+
install_one "$codex_home/skills/$skill_name"
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
echo "Invoke it in Codex with: Use \$$skill_name"
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
5
|
+
skill_dir="$repo_root/.codex/skills/project-genesis-harness"
|
|
6
|
+
|
|
7
|
+
fail() {
|
|
8
|
+
echo "eval failed: $*" >&2
|
|
9
|
+
exit 1
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
assert_file() {
|
|
13
|
+
[ -f "$1" ] || fail "missing file: ${1#$repo_root/}"
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
assert_contains() {
|
|
17
|
+
local file="$1"
|
|
18
|
+
local text="$2"
|
|
19
|
+
grep -q -- "$text" "$file" || fail "missing '$text' in ${file#$repo_root/}"
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
assert_file "$repo_root/.codex-plugin/plugin.json"
|
|
23
|
+
assert_contains "$repo_root/.codex-plugin/plugin.json" '"skills"'
|
|
24
|
+
assert_contains "$repo_root/.codex-plugin/plugin.json" '"project-genesis-harness"'
|
|
25
|
+
|
|
26
|
+
for ref in workflows.md planning-schema.md research-rubric.md quality-rubric.md; do
|
|
27
|
+
assert_file "$skill_dir/references/$ref"
|
|
28
|
+
assert_contains "$skill_dir/SKILL.md" "references/$ref"
|
|
29
|
+
done
|
|
30
|
+
|
|
31
|
+
assert_contains "$repo_root/scripts/install.sh" '--target agents|legacy|both'
|
|
32
|
+
assert_contains "$repo_root/scripts/uninstall.sh" '--target agents|legacy|both'
|
|
33
|
+
assert_contains "$repo_root/bin/genesis-harness.js" '--target agents|legacy|both'
|
|
34
|
+
assert_contains "$repo_root/package.json" '".codex-plugin"'
|
|
35
|
+
assert_contains "$repo_root/README.md" '.agents/skills'
|
|
36
|
+
|
|
37
|
+
tmp="$(mktemp -d)"
|
|
38
|
+
cleanup() {
|
|
39
|
+
rm -rf "$tmp"
|
|
40
|
+
}
|
|
41
|
+
trap cleanup EXIT
|
|
42
|
+
|
|
43
|
+
CODEX_HOME="$tmp/codex" GENESIS_HARNESS_HOME="$tmp/agents" bash "$repo_root/scripts/install.sh" --target both >/dev/null
|
|
44
|
+
[ -f "$tmp/agents/skills/project-genesis-harness/SKILL.md" ] || fail "agents install target missing"
|
|
45
|
+
[ -f "$tmp/codex/skills/project-genesis-harness/SKILL.md" ] || fail "legacy install target missing"
|
|
46
|
+
bash "$repo_root/scripts/verify.sh" "$tmp/agents/skills/project-genesis-harness" >/dev/null
|
|
47
|
+
bash "$repo_root/scripts/verify.sh" "$tmp/codex/skills/project-genesis-harness" >/dev/null
|
|
48
|
+
CODEX_HOME="$tmp/codex" GENESIS_HARNESS_HOME="$tmp/agents" bash "$repo_root/scripts/uninstall.sh" --target both >/dev/null
|
|
49
|
+
[ ! -e "$tmp/agents/skills/project-genesis-harness" ] || fail "agents uninstall target remains"
|
|
50
|
+
[ ! -e "$tmp/codex/skills/project-genesis-harness" ] || fail "legacy uninstall target remains"
|
|
51
|
+
|
|
52
|
+
echo "evals passed"
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
skill_name="project-genesis-harness"
|
|
5
|
+
codex_home="${CODEX_HOME:-$HOME/.codex}"
|
|
6
|
+
agents_home="${GENESIS_HARNESS_HOME:-$HOME/.agents}"
|
|
7
|
+
target="both"
|
|
8
|
+
|
|
9
|
+
usage() {
|
|
10
|
+
echo "Usage: $0 [--target agents|legacy|both]" >&2
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
while [ "$#" -gt 0 ]; do
|
|
14
|
+
case "$1" in
|
|
15
|
+
--target)
|
|
16
|
+
target="${2:-}"
|
|
17
|
+
[ -n "$target" ] || { usage; exit 2; }
|
|
18
|
+
shift 2
|
|
19
|
+
;;
|
|
20
|
+
--help|-h)
|
|
21
|
+
usage
|
|
22
|
+
exit 0
|
|
23
|
+
;;
|
|
24
|
+
*)
|
|
25
|
+
usage
|
|
26
|
+
exit 2
|
|
27
|
+
;;
|
|
28
|
+
esac
|
|
29
|
+
done
|
|
30
|
+
|
|
31
|
+
case "$target" in
|
|
32
|
+
agents|legacy|both) ;;
|
|
33
|
+
*) usage; exit 2 ;;
|
|
34
|
+
esac
|
|
35
|
+
|
|
36
|
+
remove_one() {
|
|
37
|
+
local target_dir="$1"
|
|
38
|
+
if [ ! -e "$target_dir" ]; then
|
|
39
|
+
echo "Skill is not installed at: $target_dir"
|
|
40
|
+
return
|
|
41
|
+
fi
|
|
42
|
+
rm -rf "$target_dir"
|
|
43
|
+
echo "Removed: $target_dir"
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if [ "$target" = "agents" ] || [ "$target" = "both" ]; then
|
|
47
|
+
remove_one "$agents_home/skills/$skill_name"
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
if [ "$target" = "legacy" ] || [ "$target" = "both" ]; then
|
|
51
|
+
remove_one "$codex_home/skills/$skill_name"
|
|
52
|
+
fi
|