@jaybeeuu/agent-cortex 1.41.0 → 1.42.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/.github/workflows/ci.yml +5 -5
- package/CHANGELOG.md +60 -0
- package/agents/ralph-plan/agent.md +7 -3
- package/agents/ralph-plan.agent.md +7 -3
- package/claude-extras/scripts/statusline-command.sh +0 -0
- package/docs/ideas/ban-content-assertion-tests.md +3 -1
- package/docs/ideas/dedicated-review-tests-skill.md +71 -0
- package/docs/ideas/unify-the-ticket-and-task-decomposition-workflows.md +71 -0
- package/package.json +5 -2
- package/plugin.json +1 -1
- package/scripts/install-instructions.sh +0 -0
- package/scripts/sync-plugin-version.sh +0 -0
- package/skills/engineering/grill-with-docs/SKILL.md +3 -2
- package/skills/engineering/improve-codebase-architecture/REFERENCE.md +5 -0
- package/skills/engineering/improve-codebase-architecture/SKILL.md +2 -1
- package/skills/planning/create-task/REFERENCE.md +1 -1
- package/skills/planning/create-task/SKILL.md +9 -4
- package/skills/planning/create-task/scripts/create-chores.ts +8 -1
- package/skills/planning/prd-to-tasks/REFERENCE.md +2 -2
- package/skills/planning/prd-to-tasks/SKILL.md +9 -4
- package/skills/planning/request-refactor-plan/FORMAT.md +5 -0
- package/skills/planning/request-refactor-plan/SKILL.md +3 -2
- package/skills/planning/spec-to-tickets/REFERENCE.md +82 -0
- package/skills/planning/spec-to-tickets/SKILL.md +143 -0
- package/skills/planning/write-a-prd/FORMAT.md +6 -0
- package/skills/planning/write-a-prd/SKILL.md +9 -6
- package/skills/planning/write-a-ticket/EXAMPLES.md +133 -0
- package/skills/planning/write-a-ticket/SKILL.md +77 -59
- package/skills/productivity/bd-tool/SKILL.md +27 -2
- package/skills/productivity/grill-me/SKILL.md +11 -0
- package/skills/review/review-security/scripts/install-gitleaks.sh +0 -0
- package/skills/style/style-code/SKILL.md +4 -0
- package/skills/style/style-tests/EXAMPLES.md +548 -0
- package/skills/style/style-tests/SKILL.md +34 -35
- package/skills/workflow/plan/SKILL.md +20 -8
- package/skills/workflow/ralph/REFERENCE.md +3 -1
- package/skills/workflow/run-pipeline-stage/SKILL.md +6 -1
- package/skills/workflow/using-agent-skills/SKILL.md +1 -0
- package/test/create-chores.test.mjs +85 -0
- package/test/fake-bd.test.mjs +72 -0
- package/test/helpers/fake-bd.mjs +87 -0
- package/extensions/agent-guardrails/node_modules/.bin/pi +0 -21
- package/extensions/agent-guardrails/node_modules/.bin/tsc +0 -21
- package/extensions/agent-guardrails/node_modules/.bin/tsserver +0 -21
- package/extensions/agent-guardrails/node_modules/.bin/tsx +0 -21
- package/extensions/agent-modes/node_modules/.bin/pi +0 -21
- package/extensions/agent-modes/node_modules/.bin/tsc +0 -21
- package/extensions/agent-modes/node_modules/.bin/tsserver +0 -21
- package/extensions/agent-modes/node_modules/.bin/tsx +0 -21
- package/extensions/skill-stats/node_modules/.bin/pi +0 -21
- package/extensions/skill-stats/node_modules/.bin/tsc +0 -21
- package/extensions/skill-stats/node_modules/.bin/tsserver +0 -21
- package/extensions/skill-stats/node_modules/.bin/tsx +0 -21
- package/extensions/skill-stats/pnpm-lock.yaml +0 -329
- package/extensions/subagent/node_modules/.bin/pi +0 -21
- package/extensions/subagent/node_modules/.bin/pi-ai +0 -21
- package/extensions/subagent/node_modules/.bin/tsc +0 -21
- package/extensions/subagent/node_modules/.bin/tsserver +0 -21
- package/extensions/subagent/node_modules/.bin/tsx +0 -21
- package/skills/planning/create-task/scripts/node_modules/.bin/tsc +0 -21
- package/skills/planning/create-task/scripts/node_modules/.bin/tsserver +0 -21
- package/skills/planning/create-task/scripts/node_modules/.bin/tsx +0 -21
- package/skills/planning/create-task/scripts/pnpm-lock.yaml +0 -342
- package/skills/productivity/validate-agent-dir/scripts/node_modules/.bin/tsc +0 -21
- package/skills/productivity/validate-agent-dir/scripts/node_modules/.bin/tsserver +0 -21
- package/skills/productivity/validate-agent-dir/scripts/node_modules/.bin/tsx +0 -21
- package/skills/productivity/validate-agent-dir/scripts/pnpm-lock.yaml +0 -329
- package/skills/workflow/run-pipeline-stage/scripts/node_modules/.bin/tsc +0 -21
- package/skills/workflow/run-pipeline-stage/scripts/node_modules/.bin/tsserver +0 -21
- package/skills/workflow/run-pipeline-stage/scripts/node_modules/.bin/tsx +0 -21
- package/skills/workflow/run-pipeline-stage/scripts/pnpm-lock.yaml +0 -342
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: style-tests
|
|
3
|
-
description: Defines
|
|
3
|
+
description: Defines test-writing conventions — assertion strategy, mock discipline, the content-assertion ban, and test-data construction. Use before writing or reviewing any test, or for a "test review" or "what should I test".
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Test Style
|
|
@@ -22,8 +22,9 @@ description: Defines this project's test-writing conventions — what to test, a
|
|
|
22
22
|
- **Test behaviour, not implementation.** A test must survive a refactor that does not change observable behaviour. If it fails after such a refactor, the test was wrong.
|
|
23
23
|
- **Mock last, at the edges.** Mock genuine external boundaries only. Never mock within the application/domain boundary; a real collaborator is almost always cheaper than a mock that lies.
|
|
24
24
|
- **Unit tests at module boundaries.** Exercise the surface of a deep module through its public API, never its internals.
|
|
25
|
-
- **Integration and e2e
|
|
25
|
+
- **Integration and e2e exercise real services.** Run the genuine collaborator — Postgres, Redis, a queue, object storage via TestContainers or LocalStack — never a fake that drifts from the real contract. Reserve e2e for a small number of smoke tests proving the system hangs together.
|
|
26
26
|
- **No more tests than needed.** Every test earns its cost by pinpointing exactly where a failure lies. A test that cannot localise a fault adds maintenance weight without signal.
|
|
27
|
+
- **One behaviour per test.** A test should fail for exactly one reason; several unrelated assertions turn a failure into a debugging exercise.
|
|
27
28
|
- **Test code is production code.** Linted, typechecked, properly typed — no `any`, no unsafe casts, no shortcuts in constructing data. Tolerate WETness where it leaves tests more descriptive.
|
|
28
29
|
- **All setup and assertion data is visible inline.** Show exactly and only the values that explain the case; a helper with sensible defaults keeps it terse.
|
|
29
30
|
- **Deterministic and performant.** A failing or flaky test is investigated now. Deferring is acceptable only against a top-priority bead.
|
|
@@ -50,14 +51,17 @@ is legitimate. `readFile(config).includes("x")` is not.
|
|
|
50
51
|
|
|
51
52
|
## Test-data construction
|
|
52
53
|
|
|
53
|
-
- **
|
|
54
|
+
- **Vital data is visible inline.** Any value that is asserted, derives the asserted state, or sets up the scenario under test appears in the test body — never hidden in a helper or a module-scope constant.
|
|
55
|
+
- **Incidental data is hidden.** Everything else takes an obvious default inside a factory, so the test body reads as only the values that matter.
|
|
54
56
|
- **No shared mutable top-level fixture.** If data must be reused, produce it fresh per test via a function — a factory, not a constant. Module-scope constants are acceptable only when genuinely immutable and read-only.
|
|
55
|
-
- **Prefer a small configurable
|
|
56
|
-
- **Name and locate the
|
|
57
|
+
- **Prefer a small configurable factory.** Optional partial overrides over sensible defaults beat repeated full literals. Build it when reuse justifies it; a single test's data stays a plain inline object.
|
|
58
|
+
- **Name and locate the factory conventionally.** Colocate it with the tests and name it for what it builds: `createNameOfType`.
|
|
59
|
+
|
|
60
|
+
Worked examples for each rule are in `EXAMPLES.md` under _Test data_.
|
|
57
61
|
|
|
58
62
|
## Workflow
|
|
59
63
|
|
|
60
|
-
1. **Determine the test level.** Can you test this behaviour through the module's public API or interface? Prefer integration-level tests (the trophy's higher coverage). Reserve unit tests for complex functional logic that genuinely benefits from tight isolation, always at the module boundary. Use a small number of e2e smoke tests
|
|
64
|
+
1. **Determine the test level.** A unit proves logic in isolation, integration proves your code against a real collaborator across one seam, and e2e proves the assembled system on a user-visible journey. Can you test this behaviour through the module's public API or interface? Prefer integration-level tests (the trophy's higher coverage). Reserve unit tests for complex functional logic that genuinely benefits from tight isolation, always at the module boundary. Use a small number of e2e smoke tests to prove the parts are wired together — not to re-prove rules already covered below.
|
|
61
65
|
|
|
62
66
|
2. **Decide what to mock.** Mock as little as possible, and only at genuine external boundaries. A useful mental model: mock what is **above** the module under test in the dependency tree, not below it. At e2e, mock almost nothing.
|
|
63
67
|
|
|
@@ -75,11 +79,18 @@ is legitimate. `readFile(config).includes("x")` is not.
|
|
|
75
79
|
|---|---|
|
|
76
80
|
| Asserting static file content — an expected config/markdown/terraform string, or a snapshot of static content | Assert the behaviour the file participates in: data inserted into a template, a header compiled correctly, a deployed service ready to serve traffic |
|
|
77
81
|
| Shared mutable top-level fixture reused across tests | Build fresh data per test via a factory; a module-scope constant only when genuinely immutable and read-only |
|
|
78
|
-
| Repeated full literals for the same shape | A small configurable
|
|
82
|
+
| Repeated full literals for the same shape | A small configurable factory taking partial overrides with sensible defaults |
|
|
83
|
+
| A test with no assertion, or one that cannot fail (`expect(result).toBeDefined()`) | Assert the observable contract — a specific value the code must produce |
|
|
84
|
+
| Computing the expected value with the implementation's own logic | Hard-code the expected value from a known-good case; the test must not share the implementation's bug |
|
|
79
85
|
| Mocking implementation details or internal module structure | Mock the genuine external boundary and test through the public interface |
|
|
86
|
+
| An "integration" test that mocks the collaborator it is meant to integrate with | Run the real collaborator (TestContainers/LocalStack); a fake drifts from the real contract |
|
|
87
|
+
| E2E re-testing business rules already covered by unit tests | Spend e2e on wiring, migrations, and the journey — keep it to a few smoke tests |
|
|
80
88
|
| Duplicating type or lint coverage | Delete the assertion — the compiler and linter already guarantee it |
|
|
81
|
-
| Skipping flaky or failing tests | Fix or delete; a skipped test is a blind spot |
|
|
89
|
+
| Skipping flaky or failing tests, or leaving `.only`/focus in | Fix or delete; a skipped or focused test is a blind spot |
|
|
82
90
|
| Sharing state via `before`/`after` hooks | Independent tests; hooks only for expensive, non-observable infrastructure |
|
|
91
|
+
| Sleeping or polling for async work to finish | Await the real completion signal; inject a clock for time-dependent logic |
|
|
92
|
+
| An unawaited promise in a test | `await` every async interaction so a rejection fails the test |
|
|
93
|
+
| Asserting log or console output | Assert the returned value or emitted event |
|
|
83
94
|
| `any` or unsafe casts in test code | Proper types — test code is production code |
|
|
84
95
|
|
|
85
96
|
## Common Rationalizations
|
|
@@ -93,6 +104,7 @@ is legitimate. `readFile(config).includes("x")` is not.
|
|
|
93
104
|
| "I'll skip this failing test and come back" | A skipped test is a blind spot. The failure is telling you something — listen to it. |
|
|
94
105
|
| "The config file must match exactly this content" | You are cataloguing a file, not proving behaviour. Assert what the code does with it. |
|
|
95
106
|
| "A shared fixture saves setup time" | It couples tests and hides which value drives the case. Build data fresh per test. |
|
|
107
|
+
| "Asserting every field is more thorough" | It makes the test break for reasons the case does not care about. Assert the fields that prove the behaviour. |
|
|
96
108
|
|
|
97
109
|
## Cross-skill references
|
|
98
110
|
|
|
@@ -105,45 +117,32 @@ is legitimate. `readFile(config).includes("x")` is not.
|
|
|
105
117
|
|
|
106
118
|
## Examples
|
|
107
119
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|---|---|
|
|
112
|
-
| Reading a generated config and asserting it equals an expected string | Assert the value the code inserted into the template |
|
|
113
|
-
| Snapshotting a markdown or terraform file's contents | Assert the behaviour the renderer/compiler produced |
|
|
114
|
-
| Asserting a deploy artefact's static bytes | A smoke test that the deployed service is up and ready to serve traffic |
|
|
115
|
-
|
|
116
|
-
### Mock boundaries
|
|
117
|
-
|
|
118
|
-
| Instead of… | Write… |
|
|
119
|
-
|---|---|
|
|
120
|
-
| Mocking the internal database driver to verify a query was called | Testing through the repository interface with a test double at that boundary |
|
|
121
|
-
| Mocking `fetch` in a unit test for an API client | Testing the client with a real HTTP stub that returns controlled responses |
|
|
122
|
-
|
|
123
|
-
### Targeted assertions
|
|
120
|
+
The full `❌ Instead` / `✅ Write` catalogue lives in `EXAMPLES.md`: behaviour over
|
|
121
|
+
implementation, test data, mocking, integration and e2e, targeted assertions, structure and
|
|
122
|
+
naming, determinism and async, isolation, and content assertions. Headline pairs:
|
|
124
123
|
|
|
125
124
|
| Instead of… | Write… |
|
|
126
125
|
|---|---|
|
|
126
|
+
| Mocking the internal database driver to verify a query was called | Testing through the repository interface with a real in-memory implementation |
|
|
127
|
+
| Snapshotting a markdown or terraform file's contents | Asserting the behaviour the renderer/compiler produced |
|
|
127
128
|
| `expect(result).toEqual(fullExpectedObject)` with every field asserted | `expect(result).toMatchObject({ status: "success", id: expect.any(String) })` |
|
|
128
|
-
| `expect(mockSave).toHaveBeenCalledTimes(1)` and then `expect(mockSave).toHaveBeenCalledWith(data)` | Just the call-args assertion — count is redundant |
|
|
129
|
-
|
|
130
|
-
### Test data
|
|
131
|
-
|
|
132
|
-
| Instead of… | Write… |
|
|
133
|
-
|---|---|
|
|
134
129
|
| `const user = sharedUser; user.isAdmin = true;` mutating a module-scope fixture | `const user = createUser({ isAdmin: true });` — fresh per test |
|
|
135
|
-
| Spelling the full object literal in every test | `createUser({ isAdmin: true })` — a helper with defaults and explicit overrides |
|
|
136
130
|
|
|
137
131
|
## Verification checklist
|
|
138
132
|
|
|
139
133
|
- [ ] Test verifies behaviour, not implementation structure
|
|
134
|
+
- [ ] Integration tests exercise the real collaborator — no mocking the engine you are integrating with
|
|
135
|
+
- [ ] E2E smoke tests prove wiring, migrations, and the journey — not business rules covered lower down
|
|
136
|
+
- [ ] Each test fails for exactly one reason, and its name states the behaviour
|
|
140
137
|
- [ ] No mocking of internal module details — only public interfaces
|
|
141
138
|
- [ ] No `before`/`after` hooks for shared test state (infrastructure setup only)
|
|
142
|
-
- [ ] Assertions are targeted — no over-asserting
|
|
139
|
+
- [ ] Assertions are targeted — no over-asserting, no tautologies, no assertion-free tests
|
|
143
140
|
- [ ] No test asserts static file content (config, markdown, terraform, static snapshots) — assertions prove behaviour, not inventory
|
|
144
141
|
- [ ] Test data is built inline or via a fresh-per-test factory; no shared mutable top-level fixture
|
|
145
|
-
- [ ]
|
|
146
|
-
- [ ]
|
|
147
|
-
- [ ] No
|
|
142
|
+
- [ ] Vital data is visible inline; incidental data is defaulted in a factory
|
|
143
|
+
- [ ] Reused test data uses a small configurable factory rather than repeated full literals
|
|
144
|
+
- [ ] No skipped, focused, or commented-out tests
|
|
145
|
+
- [ ] No flaky tests — all deterministic, no sleeps or real clocks
|
|
146
|
+
- [ ] Every async interaction is awaited
|
|
148
147
|
- [ ] No `any` or unsafe casts in test code
|
|
149
148
|
- [ ] No duplication of type or linting coverage
|
|
@@ -47,6 +47,10 @@ Establish what needs to be built through investigation and collaborative design.
|
|
|
47
47
|
- Technical constraints and trade-offs
|
|
48
48
|
- How each change will be verified
|
|
49
49
|
|
|
50
|
+
The epic's required sections — `## Success Criteria` for the PRD epic — are the interview's target:
|
|
51
|
+
it is complete only when every required section can be filled from agreed answers. Never invent
|
|
52
|
+
section content; surface assumptions and confirm them with the user.
|
|
53
|
+
|
|
50
54
|
4. Sketch the major modules that will be built or modified. Look for opportunities to extract deep modules — ones that encapsulate significant behaviour behind a simple, testable interface.
|
|
51
55
|
|
|
52
56
|
5. Draft a PRD using the template from `write-a-prd`. Include:
|
|
@@ -60,8 +64,9 @@ Establish what needs to be built through investigation and collaborative design.
|
|
|
60
64
|
7. Create an epic bead from the approved PRD:
|
|
61
65
|
```bash
|
|
62
66
|
bd create "<Feature Title> — PRD" --type epic \
|
|
63
|
-
--description "<rendered PRD as markdown>" --priority p2
|
|
67
|
+
--description "<rendered PRD as markdown>" --priority p2 --validate
|
|
64
68
|
bd tag <epic-id> workflow:plan
|
|
69
|
+
bd lint <epic-id>
|
|
65
70
|
```
|
|
66
71
|
|
|
67
72
|
#### Phase 1 gate
|
|
@@ -70,7 +75,7 @@ Establish what needs to be built through investigation and collaborative design.
|
|
|
70
75
|
- [ ] Design decisions resolved through interview
|
|
71
76
|
- [ ] Modules sketched and reviewed with the user
|
|
72
77
|
- [ ] PRD drafted and approved by the user
|
|
73
|
-
- [ ] Epic bead created from approved PRD
|
|
78
|
+
- [ ] Epic bead created from approved PRD and lints clean (`bd lint <epic-id>`)
|
|
74
79
|
|
|
75
80
|
### Phase 2 — Break into tasks
|
|
76
81
|
|
|
@@ -82,13 +87,14 @@ Take the approved PRD and produce a set of epics and tasks using tracer-bullet v
|
|
|
82
87
|
- **Title**: short descriptive name
|
|
83
88
|
- **User stories covered**: which PRD stories this phase addresses
|
|
84
89
|
- **What to build**: end-to-end behaviour description
|
|
85
|
-
- **
|
|
90
|
+
- **Success criteria**: verifiable outcomes — the epic's required `## Success Criteria`
|
|
86
91
|
|
|
87
92
|
10. If the work is small enough for a single epic (one phase, a few tasks), skip epics and proceed directly to Phase 3. A single epic with a few tasks dispatches through ralph more efficiently than creating unnecessary epic hierarchy. If the work has multiple distinct phases, create epics:
|
|
88
93
|
```bash
|
|
89
94
|
bd create "<Phase Title>" --type epic \
|
|
90
|
-
--description "<epic body with scope, criteria, dependencies>" --priority <same as parent>
|
|
95
|
+
--description "<epic body with scope, success criteria, dependencies>" --priority <same as parent> --validate
|
|
91
96
|
bd tag <epic-id> workflow:plan
|
|
97
|
+
bd lint <epic-id>
|
|
92
98
|
bd dep add <epic-id> <parent-epic-id> --type parent-child
|
|
93
99
|
```
|
|
94
100
|
|
|
@@ -146,8 +152,13 @@ Deliver a handoff bead and instructions for running ralph.
|
|
|
146
152
|
- **Multiple independent epics**: create a parent meta-epic that groups them:
|
|
147
153
|
```bash
|
|
148
154
|
bd create "<Feature Title> — Implementation" --type epic \
|
|
149
|
-
--description "Meta-epic grouping all phases for execution. See child epics for detail.
|
|
150
|
-
|
|
155
|
+
--description "Meta-epic grouping all phases for execution. See child epics for detail.
|
|
156
|
+
|
|
157
|
+
## Success Criteria
|
|
158
|
+
|
|
159
|
+
- [ ] All child epics complete and the feature verified end-to-end." \
|
|
160
|
+
--priority <same> --validate
|
|
161
|
+
bd lint <meta-epic>
|
|
151
162
|
bd dep add <epic-1> <meta-epic> --type parent-child
|
|
152
163
|
bd dep add <epic-2> <meta-epic> --type parent-child
|
|
153
164
|
```
|
|
@@ -187,13 +198,14 @@ Deliver a handoff bead and instructions for running ralph.
|
|
|
187
198
|
#### Phase 4 gate
|
|
188
199
|
|
|
189
200
|
- [ ] Handoff bead identified and tagged `workflow:ralph`
|
|
201
|
+
- [ ] Every handoff-path bead lints clean (`bd lint`)
|
|
190
202
|
- [ ] Bead state pushed with `bd dolt push`
|
|
191
203
|
- [ ] Handoff summary presented with the exact instruction to give an agent
|
|
192
204
|
|
|
193
205
|
## Phase-gate checklist
|
|
194
206
|
|
|
195
|
-
- [ ] Phase 1: PRD drafted and approved, epic bead created
|
|
196
|
-
- [ ] Phase 2: Task breakdown approved, epics created (if needed)
|
|
207
|
+
- [ ] Phase 1: PRD drafted and approved, epic bead created and validated
|
|
208
|
+
- [ ] Phase 2: Task breakdown approved, epics created (if needed) and validated
|
|
197
209
|
- [ ] Phase 3: All tasks created, classified, expanded, tree presented
|
|
198
210
|
- [ ] Phase 4: Handoff bead prepared, state pushed, summary delivered
|
|
199
211
|
|
|
@@ -79,7 +79,9 @@ When a verify or review stage fails:
|
|
|
79
79
|
```bash
|
|
80
80
|
fix_id=$(bd create "[<parent-id>] Fix (round <N>)" --type chore \
|
|
81
81
|
--priority <same as parent> \
|
|
82
|
-
--description "
|
|
82
|
+
--description "Requirements: see <parent-id> acceptance criteria (`bd show <parent-id>`).
|
|
83
|
+
|
|
84
|
+
<CHANGES_REQUESTED list or VERIFY_FAILURES list from the triggering REPORT>" -q)
|
|
83
85
|
bd tag $fix_id stage:fix
|
|
84
86
|
bd dep add $fix_id <parent-id> --type parent-child # fix-chore is child of parent
|
|
85
87
|
```
|
|
@@ -61,12 +61,17 @@ On stage failure, create a chore bead whose description carries the feedback so
|
|
|
61
61
|
|
|
62
62
|
```bash
|
|
63
63
|
new_id=$(bd create "[<parent-id>] <title>" --type chore \
|
|
64
|
-
--description "<
|
|
64
|
+
--description "Requirements: see <parent-id> acceptance criteria (`bd show <parent-id>`).
|
|
65
|
+
|
|
66
|
+
<feedback content from REPORT>" --priority <parent-priority> -q)
|
|
65
67
|
bd tag $new_id stage:<next-stage>
|
|
66
68
|
bd tag $new_id workflow:ralph
|
|
67
69
|
bd dep add $new_id <parent-id> --type parent-child
|
|
68
70
|
```
|
|
69
71
|
|
|
72
|
+
Chore beads carry no required sections, so the feedback description must point at the
|
|
73
|
+
parent/requirements bead (`<parent-id>`) rather than restating its acceptance criteria.
|
|
74
|
+
|
|
70
75
|
| Triggering outcome | Suggested title | Next stage tag | Description content |
|
|
71
76
|
|---|---|---|---|
|
|
72
77
|
| `OUTCOME: BLOCKED` from verify | `Fix: verify failures` | `stage:code` | Full BLOCKING_ISSUES list |
|
|
@@ -23,6 +23,7 @@ Task arrives
|
|
|
23
23
|
├── Have a rough idea? ─────────────────→ record-idea
|
|
24
24
|
├── New feature / PRD needed? ──────────→ write-a-prd
|
|
25
25
|
├── PRD approved, need tasks? ──────────→ prd-to-tasks
|
|
26
|
+
├── Spec approved, need tickets? ───────→ spec-to-tickets
|
|
26
27
|
├── Need a single task tracked? ────────→ create-task
|
|
27
28
|
├── Need to plan a feature end-to-end? ─→ plan
|
|
28
29
|
├── Running beads / task execution? ────→ ralph
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { describe, it } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { execFile } from "node:child_process";
|
|
4
|
+
import { mkdtemp, readFile, rm } from "node:fs/promises";
|
|
5
|
+
import { tmpdir } from "node:os";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
import { dirname, join } from "node:path";
|
|
8
|
+
|
|
9
|
+
import { makeFakeBd } from "./helpers/fake-bd.mjs";
|
|
10
|
+
|
|
11
|
+
const testDir = dirname(fileURLToPath(import.meta.url));
|
|
12
|
+
const CREATE_CHORES = join(testDir, "..", "skills", "planning", "create-task", "scripts", "create-chores.ts");
|
|
13
|
+
|
|
14
|
+
/** Run create-chores.ts against the fake `bd` with a parent that already
|
|
15
|
+
* carries implementation-type:afk — the label `bd create --parent` inherits.
|
|
16
|
+
* @param {string[]} parentLabels Labels seeded on the parent bead
|
|
17
|
+
* @returns {Promise<{ ids: Record<string, string>, beads: Array<{ id: string, title: string, labels: string[] }> }>} */
|
|
18
|
+
async function createChoresAgainstFakeBd(parentLabels) {
|
|
19
|
+
const dir = await mkdtemp(join(tmpdir(), "create-chores-"));
|
|
20
|
+
const { bin, state } = await makeFakeBd(dir, {
|
|
21
|
+
beads: [{ id: "parent-1", title: "Feature", labels: parentLabels }],
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
const { exitCode, stdout, stderr } = await runScript(
|
|
26
|
+
["--parent", "parent-1"],
|
|
27
|
+
{ BD_PATH: bin, FAKE_BD_STATE: state },
|
|
28
|
+
);
|
|
29
|
+
assert.equal(exitCode, 0, stderr);
|
|
30
|
+
|
|
31
|
+
const ids = JSON.parse(stdout);
|
|
32
|
+
const { beads } = JSON.parse(await readFile(state, "utf8"));
|
|
33
|
+
return { ids, beads };
|
|
34
|
+
} finally {
|
|
35
|
+
await rm(dir, { recursive: true, force: true });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Run create-chores.ts with the given env overrides. */
|
|
40
|
+
function runScript(args, env) {
|
|
41
|
+
return new Promise((resolve) => {
|
|
42
|
+
execFile(
|
|
43
|
+
process.execPath,
|
|
44
|
+
[CREATE_CHORES, ...args],
|
|
45
|
+
{ env: { ...process.env, ...env } },
|
|
46
|
+
(error, stdout, stderr) => {
|
|
47
|
+
resolve({ exitCode: error ? error.code ?? 1 : 0, stdout, stderr });
|
|
48
|
+
},
|
|
49
|
+
);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
describe("create-chores", () => {
|
|
54
|
+
it("gives the PR gate exactly its declared labels, without the parent's inherited implementation-type:afk", async () => {
|
|
55
|
+
const { ids, beads } = await createChoresAgainstFakeBd(["implementation-type:afk"]);
|
|
56
|
+
|
|
57
|
+
const gate = beads.find((b) => b.id === ids.featurePrReview);
|
|
58
|
+
assert.deepEqual(
|
|
59
|
+
[...gate.labels].sort(),
|
|
60
|
+
["implementation-type:hitl", "lifecycle:feature-pr"],
|
|
61
|
+
);
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it("still lets stage chores inherit implementation-type:afk from the parent", async () => {
|
|
65
|
+
const { ids, beads } = await createChoresAgainstFakeBd(["implementation-type:afk"]);
|
|
66
|
+
|
|
67
|
+
const codeChore = beads.find((b) => b.id === ids.code);
|
|
68
|
+
assert.deepEqual(
|
|
69
|
+
[...codeChore.labels].sort(),
|
|
70
|
+
["implementation-type:afk", "stage:code"],
|
|
71
|
+
);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("validates the PR gate task but not the stage chores", async () => {
|
|
75
|
+
const { ids, beads } = await createChoresAgainstFakeBd(["implementation-type:afk"]);
|
|
76
|
+
|
|
77
|
+
const gate = beads.find((b) => b.id === ids.featurePrReview);
|
|
78
|
+
assert.equal(gate.type, "task");
|
|
79
|
+
assert.equal(gate.validated, true);
|
|
80
|
+
assert.match(gate.description, /## Acceptance Criteria/);
|
|
81
|
+
|
|
82
|
+
const codeChore = beads.find((b) => b.id === ids.code);
|
|
83
|
+
assert.equal(codeChore.validated, false);
|
|
84
|
+
});
|
|
85
|
+
});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// Tests for the stateful fake `bd` helper's `--validate` model.
|
|
2
|
+
// The fake mirrors `bd create --validate`: a substantive bead whose description lacks the
|
|
3
|
+
// required section(s) for its type is rejected; chores have no requirements.
|
|
4
|
+
|
|
5
|
+
import { describe, it } from "node:test";
|
|
6
|
+
import assert from "node:assert/strict";
|
|
7
|
+
import { execFile } from "node:child_process";
|
|
8
|
+
import { mkdtemp, rm } from "node:fs/promises";
|
|
9
|
+
import { tmpdir } from "node:os";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
|
|
12
|
+
import { makeFakeBd } from "./helpers/fake-bd.mjs";
|
|
13
|
+
|
|
14
|
+
/** Run the fake `bd` binary with the given args. */
|
|
15
|
+
function runFake(bin, state, args) {
|
|
16
|
+
return new Promise((resolve) => {
|
|
17
|
+
execFile(bin, args, { env: { ...process.env, FAKE_BD_STATE: state } }, (error, stdout, stderr) => {
|
|
18
|
+
resolve({ exitCode: error ? error.code ?? 1 : 0, stdout, stderr });
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Create a fresh fake workspace, run `fn`, then remove it. */
|
|
24
|
+
async function withFake(fn) {
|
|
25
|
+
const dir = await mkdtemp(join(tmpdir(), "fake-bd-"));
|
|
26
|
+
try {
|
|
27
|
+
const { bin, state } = await makeFakeBd(dir, { beads: [] });
|
|
28
|
+
await fn(bin, state);
|
|
29
|
+
} finally {
|
|
30
|
+
await rm(dir, { recursive: true, force: true });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
describe("fake bd --validate", () => {
|
|
35
|
+
it("rejects a section-less task", async () => {
|
|
36
|
+
await withFake(async (bin, state) => {
|
|
37
|
+
const { exitCode, stderr } = await runFake(bin, state, ["create", "empty", "--type", "task", "--validate"]);
|
|
38
|
+
assert.equal(exitCode, 1);
|
|
39
|
+
assert.match(stderr, /Acceptance Criteria/);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("accepts a task carrying ## Acceptance Criteria (case-insensitive)", async () => {
|
|
44
|
+
await withFake(async (bin, state) => {
|
|
45
|
+
const { exitCode } = await runFake(bin, state, [
|
|
46
|
+
"create", "ok", "--type", "task",
|
|
47
|
+
"--description", "## Acceptance criteria\n- [ ] done",
|
|
48
|
+
"--validate",
|
|
49
|
+
]);
|
|
50
|
+
assert.equal(exitCode, 0);
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("requires ## Success Criteria for an epic", async () => {
|
|
55
|
+
await withFake(async (bin, state) => {
|
|
56
|
+
const { exitCode, stderr } = await runFake(bin, state, [
|
|
57
|
+
"create", "ep", "--type", "epic",
|
|
58
|
+
"--description", "## Acceptance Criteria\n- [ ] x",
|
|
59
|
+
"--validate",
|
|
60
|
+
]);
|
|
61
|
+
assert.equal(exitCode, 1);
|
|
62
|
+
assert.match(stderr, /Success Criteria/);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it("does not require sections for a chore", async () => {
|
|
67
|
+
await withFake(async (bin, state) => {
|
|
68
|
+
const { exitCode } = await runFake(bin, state, ["create", "c", "--type", "chore", "--validate"]);
|
|
69
|
+
assert.equal(exitCode, 0);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
});
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// Shared test helper: a stateful fake `bd` binary for create-chores.ts.
|
|
2
|
+
// `bd` is a genuine external system (its real database must never be touched
|
|
3
|
+
// by tests), so the script is driven against this fake via the BD_PATH
|
|
4
|
+
// override. The fake reproduces the real behaviours the tests depend on —
|
|
5
|
+
// `bd create --parent` label inheritance (unless `--no-inherit-labels` is
|
|
6
|
+
// passed) and `bd create --validate` section enforcement — and records every
|
|
7
|
+
// created bead to a JSON state file the test can read back.
|
|
8
|
+
//
|
|
9
|
+
// State lives in `state.json` next to the binary; the test seeds it with the
|
|
10
|
+
// parent bead and reads the children back after the script runs. Written async
|
|
11
|
+
// throughout — the repo's check-no-sync lint scans test/ (including helpers).
|
|
12
|
+
|
|
13
|
+
import { chmod, writeFile } from "node:fs/promises";
|
|
14
|
+
import { join } from "node:path";
|
|
15
|
+
|
|
16
|
+
const FAKE_BD_SCRIPT = [
|
|
17
|
+
"#!/usr/bin/env node",
|
|
18
|
+
"// Stateful fake for `bd create` (test/helpers/fake-bd.mjs).",
|
|
19
|
+
"const fs = require('node:fs/promises');",
|
|
20
|
+
"",
|
|
21
|
+
"const stateFile = process.env.FAKE_BD_STATE;",
|
|
22
|
+
"const VALUE_FLAGS = new Set(['--type', '--description', '--priority', '--labels', '--parent']);",
|
|
23
|
+
"const BOOL_FLAGS = new Set(['--silent', '--no-inherit-labels', '--validate']);",
|
|
24
|
+
"",
|
|
25
|
+
"(async () => {",
|
|
26
|
+
" const argv = process.argv.slice(2);",
|
|
27
|
+
" if (argv[0] === 'dep') process.exit(0);",
|
|
28
|
+
" if (argv[0] !== 'create') process.exit(1);",
|
|
29
|
+
"",
|
|
30
|
+
" const title = argv[1];",
|
|
31
|
+
" const flags = {};",
|
|
32
|
+
" const bools = new Set();",
|
|
33
|
+
" for (let i = 2; i < argv.length; i++) {",
|
|
34
|
+
" const arg = argv[i];",
|
|
35
|
+
" if (BOOL_FLAGS.has(arg)) { bools.add(arg); continue; }",
|
|
36
|
+
" if (VALUE_FLAGS.has(arg)) { flags[arg] = argv[++i]; continue; }",
|
|
37
|
+
" }",
|
|
38
|
+
"",
|
|
39
|
+
" const state = JSON.parse(await fs.readFile(stateFile, 'utf8'));",
|
|
40
|
+
"",
|
|
41
|
+
" // Model `bd create --validate`: reject a substantive bead whose description lacks the",
|
|
42
|
+
" // required section(s) for its type. Chores have no requirements and always pass.",
|
|
43
|
+
" if (bools.has('--validate')) {",
|
|
44
|
+
" const type = flags['--type'] || 'task';",
|
|
45
|
+
" const required = {",
|
|
46
|
+
" task: ['## Acceptance Criteria'],",
|
|
47
|
+
" feature: ['## Acceptance Criteria'],",
|
|
48
|
+
" bug: ['## Steps to Reproduce', '## Acceptance Criteria'],",
|
|
49
|
+
" epic: ['## Success Criteria'],",
|
|
50
|
+
" chore: [],",
|
|
51
|
+
" }[type] || ['## Acceptance Criteria'];",
|
|
52
|
+
" const description = flags['--description'] || '';",
|
|
53
|
+
" const missing = required.filter((section) => !description.toLowerCase().includes(section.toLowerCase()));",
|
|
54
|
+
" if (missing.length > 0) {",
|
|
55
|
+
" console.error('missing required sections for ' + type + ': ' + missing.join(', '));",
|
|
56
|
+
" process.exit(1);",
|
|
57
|
+
" }",
|
|
58
|
+
" }",
|
|
59
|
+
"",
|
|
60
|
+
" const explicit = (flags['--labels'] || '').split(',').filter(Boolean);",
|
|
61
|
+
" const parent = state.beads.find((b) => b.id === flags['--parent']);",
|
|
62
|
+
" const inherited = parent && !bools.has('--no-inherit-labels') ? parent.labels : [];",
|
|
63
|
+
" const labels = [...new Set([...inherited, ...explicit])];",
|
|
64
|
+
"",
|
|
65
|
+
" const id = 'bd-' + state.nextId++;",
|
|
66
|
+
" state.beads.push({ id, title, labels, parent: flags['--parent'] ?? null, type: flags['--type'] || 'task', description: flags['--description'] || '', validated: bools.has('--validate') });",
|
|
67
|
+
" await fs.writeFile(stateFile, JSON.stringify(state));",
|
|
68
|
+
" process.stdout.write(id + '\\n');",
|
|
69
|
+
"})().catch((err) => {",
|
|
70
|
+
" console.error(err);",
|
|
71
|
+
" process.exit(1);",
|
|
72
|
+
"});",
|
|
73
|
+
].join("\n");
|
|
74
|
+
|
|
75
|
+
/** Create a stateful fake `bd` binary in `dir`.
|
|
76
|
+
* @param {string} dir Directory to hold the binary and its state.json
|
|
77
|
+
* @param {{ beads: Array<{ id: string, title: string, labels: string[] }> }} seed
|
|
78
|
+
* Pre-existing beads (the parent) the fake inherits labels from
|
|
79
|
+
* @returns {Promise<{ bin: string, state: string }>} */
|
|
80
|
+
export async function makeFakeBd(dir, { beads }) {
|
|
81
|
+
const bin = join(dir, "bd");
|
|
82
|
+
const state = join(dir, "state.json");
|
|
83
|
+
await writeFile(bin, FAKE_BD_SCRIPT + "\n");
|
|
84
|
+
await chmod(bin, 0o755);
|
|
85
|
+
await writeFile(state, JSON.stringify({ beads, nextId: 1 }));
|
|
86
|
+
return { bin, state };
|
|
87
|
+
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
|
-
|
|
4
|
-
case `uname` in
|
|
5
|
-
*CYGWIN*|*MINGW*|*MSYS*)
|
|
6
|
-
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
-
basedir=`cygpath -w "$basedir"`
|
|
8
|
-
fi
|
|
9
|
-
;;
|
|
10
|
-
esac
|
|
11
|
-
|
|
12
|
-
if [ -z "$NODE_PATH" ]; then
|
|
13
|
-
export NODE_PATH="/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/@earendil-works+pi-coding-agent@0.78.1_ws@8.21.0_zod@4.4.3/node_modules/@earendil-works/pi-coding-agent/node_modules:/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/@earendil-works+pi-coding-agent@0.78.1_ws@8.21.0_zod@4.4.3/node_modules:/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/node_modules"
|
|
14
|
-
else
|
|
15
|
-
export NODE_PATH="/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/@earendil-works+pi-coding-agent@0.78.1_ws@8.21.0_zod@4.4.3/node_modules/@earendil-works/pi-coding-agent/node_modules:/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/@earendil-works+pi-coding-agent@0.78.1_ws@8.21.0_zod@4.4.3/node_modules:/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
|
-
fi
|
|
17
|
-
if [ -x "$basedir/node" ]; then
|
|
18
|
-
exec "$basedir/node" "$basedir/../@earendil-works/pi-coding-agent/dist/cli.js" "$@"
|
|
19
|
-
else
|
|
20
|
-
exec node "$basedir/../@earendil-works/pi-coding-agent/dist/cli.js" "$@"
|
|
21
|
-
fi
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
|
-
|
|
4
|
-
case `uname` in
|
|
5
|
-
*CYGWIN*|*MINGW*|*MSYS*)
|
|
6
|
-
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
-
basedir=`cygpath -w "$basedir"`
|
|
8
|
-
fi
|
|
9
|
-
;;
|
|
10
|
-
esac
|
|
11
|
-
|
|
12
|
-
if [ -z "$NODE_PATH" ]; then
|
|
13
|
-
export NODE_PATH="/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/typescript@5.9.3/node_modules:/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/node_modules"
|
|
14
|
-
else
|
|
15
|
-
export NODE_PATH="/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/typescript@5.9.3/node_modules:/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
|
-
fi
|
|
17
|
-
if [ -x "$basedir/node" ]; then
|
|
18
|
-
exec "$basedir/node" "$basedir/../typescript/bin/tsc" "$@"
|
|
19
|
-
else
|
|
20
|
-
exec node "$basedir/../typescript/bin/tsc" "$@"
|
|
21
|
-
fi
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
|
-
|
|
4
|
-
case `uname` in
|
|
5
|
-
*CYGWIN*|*MINGW*|*MSYS*)
|
|
6
|
-
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
-
basedir=`cygpath -w "$basedir"`
|
|
8
|
-
fi
|
|
9
|
-
;;
|
|
10
|
-
esac
|
|
11
|
-
|
|
12
|
-
if [ -z "$NODE_PATH" ]; then
|
|
13
|
-
export NODE_PATH="/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/typescript@5.9.3/node_modules:/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/node_modules"
|
|
14
|
-
else
|
|
15
|
-
export NODE_PATH="/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/typescript@5.9.3/node_modules:/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
|
-
fi
|
|
17
|
-
if [ -x "$basedir/node" ]; then
|
|
18
|
-
exec "$basedir/node" "$basedir/../typescript/bin/tsserver" "$@"
|
|
19
|
-
else
|
|
20
|
-
exec node "$basedir/../typescript/bin/tsserver" "$@"
|
|
21
|
-
fi
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
|
-
|
|
4
|
-
case `uname` in
|
|
5
|
-
*CYGWIN*|*MINGW*|*MSYS*)
|
|
6
|
-
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
-
basedir=`cygpath -w "$basedir"`
|
|
8
|
-
fi
|
|
9
|
-
;;
|
|
10
|
-
esac
|
|
11
|
-
|
|
12
|
-
if [ -z "$NODE_PATH" ]; then
|
|
13
|
-
export NODE_PATH="/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/tsx@4.22.4/node_modules/tsx/node_modules:/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/tsx@4.22.4/node_modules:/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/node_modules"
|
|
14
|
-
else
|
|
15
|
-
export NODE_PATH="/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/tsx@4.22.4/node_modules/tsx/node_modules:/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/tsx@4.22.4/node_modules:/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
|
-
fi
|
|
17
|
-
if [ -x "$basedir/node" ]; then
|
|
18
|
-
exec "$basedir/node" "$basedir/../tsx/dist/cli.mjs" "$@"
|
|
19
|
-
else
|
|
20
|
-
exec node "$basedir/../tsx/dist/cli.mjs" "$@"
|
|
21
|
-
fi
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
|
-
|
|
4
|
-
case `uname` in
|
|
5
|
-
*CYGWIN*|*MINGW*|*MSYS*)
|
|
6
|
-
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
-
basedir=`cygpath -w "$basedir"`
|
|
8
|
-
fi
|
|
9
|
-
;;
|
|
10
|
-
esac
|
|
11
|
-
|
|
12
|
-
if [ -z "$NODE_PATH" ]; then
|
|
13
|
-
export NODE_PATH="/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/@earendil-works+pi-coding-agent@0.78.1_ws@8.21.0_zod@4.4.3/node_modules/@earendil-works/pi-coding-agent/node_modules:/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/@earendil-works+pi-coding-agent@0.78.1_ws@8.21.0_zod@4.4.3/node_modules:/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/node_modules"
|
|
14
|
-
else
|
|
15
|
-
export NODE_PATH="/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/@earendil-works+pi-coding-agent@0.78.1_ws@8.21.0_zod@4.4.3/node_modules/@earendil-works/pi-coding-agent/node_modules:/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/@earendil-works+pi-coding-agent@0.78.1_ws@8.21.0_zod@4.4.3/node_modules:/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
|
-
fi
|
|
17
|
-
if [ -x "$basedir/node" ]; then
|
|
18
|
-
exec "$basedir/node" "$basedir/../@earendil-works/pi-coding-agent/dist/cli.js" "$@"
|
|
19
|
-
else
|
|
20
|
-
exec node "$basedir/../@earendil-works/pi-coding-agent/dist/cli.js" "$@"
|
|
21
|
-
fi
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
|
3
|
-
|
|
4
|
-
case `uname` in
|
|
5
|
-
*CYGWIN*|*MINGW*|*MSYS*)
|
|
6
|
-
if command -v cygpath > /dev/null 2>&1; then
|
|
7
|
-
basedir=`cygpath -w "$basedir"`
|
|
8
|
-
fi
|
|
9
|
-
;;
|
|
10
|
-
esac
|
|
11
|
-
|
|
12
|
-
if [ -z "$NODE_PATH" ]; then
|
|
13
|
-
export NODE_PATH="/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/typescript@5.9.3/node_modules:/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/node_modules"
|
|
14
|
-
else
|
|
15
|
-
export NODE_PATH="/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/typescript@5.9.3/node_modules:/home/runner/work/agent-cortex/agent-cortex/node_modules/.pnpm/node_modules:$NODE_PATH"
|
|
16
|
-
fi
|
|
17
|
-
if [ -x "$basedir/node" ]; then
|
|
18
|
-
exec "$basedir/node" "$basedir/../typescript/bin/tsc" "$@"
|
|
19
|
-
else
|
|
20
|
-
exec node "$basedir/../typescript/bin/tsc" "$@"
|
|
21
|
-
fi
|