Skip to content

Commit d139517

Browse files
Merge pull request #998 from corbitsdev/cl-7926-restore-missing-common-patterns-in-create-issue-skill-from
Restore missing Common Patterns in create-issue skill
2 parents 7c41ba8 + 823f20d commit d139517

3 files changed

Lines changed: 146 additions & 15 deletions

File tree

.github/workflows/ci.yml

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,19 +78,28 @@ jobs:
7878
run: bun run build
7979

8080
# The suite is sharded so the slowest slice, not the whole suite, sets the
81-
# wall clock. Every shard still goes through check:projects-dir-guard: the
81+
# wall clock. The old ./src leg (387 files, ~88s local) is split into three
82+
# path-disjoint shards measured at ~30s (src-a: tui, 146 files), ~46s
83+
# (src-b: agent + subagent, 90 files), and ~45s (src-c: everything else in
84+
# src, 153 files); the ./tests leg stays whole because ./evals ./scripts
85+
# finish in ~1s and a leg of their own would be all setup overhead.
86+
# Every shard still goes through check:projects-dir-guard: the
8287
# guard forwards these path filters to the suite it wraps, and the union of
8388
# the shards' filters is exactly ./src ./tests ./evals ./scripts, so the gate covers
8489
# the same tests as before, all of them sandboxed.
8590
test:
8691
runs-on: ubuntu-latest
8792
strategy:
88-
# A red shard must not cancel the other; both results are the signal.
93+
# A red shard must not cancel the others; every result is the signal.
8994
fail-fast: false
9095
matrix:
9196
shard:
92-
- name: src
93-
paths: ./src
97+
- name: src-a
98+
paths: ./src/tui
99+
- name: src-b
100+
paths: ./src/agent ./src/subagent
101+
- name: src-c
102+
paths: ./src/auth ./src/changelog ./src/config ./src/cost ./src/crash ./src/exec ./src/logging ./src/mcp ./src/perf ./src/permission ./src/plugins ./src/provider ./src/session ./src/shell ./src/telemetry ./src/tools ./src/trust ./src/upgrade ./src/util ./src/web ./src/config.test.ts ./src/context-compactor.test.ts ./src/director.test.ts ./src/inference-abort.test.ts ./src/inference-error-message.test.ts ./src/inference-gateway-error.test.ts ./src/list-dir.test.ts ./src/pricing-fetcher.test.ts ./src/pricing-metadata.test.ts ./src/profiles.test.ts ./src/prompts.test.ts ./src/renderer.test.ts ./src/settings.test.ts ./src/state.test.ts
94103
- name: tests-evals-and-scripts
95104
paths: ./tests ./evals ./scripts
96105
name: test (${{ matrix.shard.name }})
@@ -161,3 +170,13 @@ jobs:
161170
runs-on: ubuntu-latest
162171
steps:
163172
- run: "true"
173+
174+
# The src-a/src-b/src-c matrix legs replaced the single test (src) leg, so
175+
# this publishes that context name once all legs pass. needs: test waits for
176+
# every matrix leg; a red leg skips this instead of greening it.
177+
test-src:
178+
name: test (src)
179+
needs: test
180+
runs-on: ubuntu-latest
181+
steps:
182+
- run: "true"

plugins/corbits-skills/skills/create-issue/SKILL.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,3 +388,90 @@ Issues:
388388
4. "Add theme persistence to user preferences"
389389
- Blocked by: #1
390390
```
391+
392+
### Validation Project
393+
394+
```
395+
User: "We need to validate if customers want our new <product-name> product"
396+
397+
Project: Get 10 customer leads for <product-name> through direct outreach
398+
Lead: <to be assigned>
399+
Target: 2 weeks
400+
Description:
401+
Hypothesis - Teams we know and can reach out to have a need for <product-name>.
402+
403+
Experiment
404+
Direct Outreach
405+
406+
- [ ] Create list of targets
407+
- [ ] Create collateral if needed
408+
- [ ] Create strategy for outreach including any templates
409+
- [ ] Execute outreach
410+
- [ ] Conduct customer interviews
411+
- [ ] Analyze results
412+
413+
Milestones:
414+
1. Target list and collateral ready
415+
2. Outreach completed
416+
3. Customer interviews recorded
417+
4. Analysis complete
418+
419+
Issues:
420+
1. "Create target list for <product-name> outreach"
421+
2. "Create outreach collateral and templates"
422+
3. "Execute outreach campaign"
423+
- Blocked by: #1, #2
424+
4. "Conduct and record customer interviews"
425+
- Blocked by: #3
426+
5. "Analyze results and present findings"
427+
- Blocked by: #4
428+
```
429+
430+
### Strategic Goal to Initiative
431+
432+
```
433+
User: "We need to expand our platform to support enterprise customers"
434+
435+
Initiative: Enterprise platform expansion
436+
Owner: <executive-owner>
437+
Target: <target-quarter>
438+
439+
Projects:
440+
1. "Multi-tenant architecture" - Isolate customer data and resources
441+
2. "Enterprise SSO integration" - Support SAML and OIDC providers
442+
3. "Admin dashboard" - Self-service management for enterprise admins
443+
4. "Audit logging" - Compliance-ready activity tracking
444+
```
445+
446+
### Planning Document to Issues
447+
448+
```
449+
User: "Create issues from our product doc" or "--from-doc"
450+
451+
[Skill searches for PRODUCT.md, ARCHITECTURE.md, IMPLEMENTATION.md]
452+
[Finds PRODUCT.md with feature descriptions]
453+
454+
Skill: I found PRODUCT.md which describes the following features:
455+
- User authentication with SSO
456+
- Usage metrics dashboard
457+
- Export functionality
458+
459+
Based on the document, I propose:
460+
461+
**Project**: User authentication with SSO support
462+
(From PRODUCT.md: "Users need secure login with enterprise SSO...")
463+
464+
**Issues**:
465+
1. "Implement basic email/password authentication"
466+
# Background
467+
From PRODUCT.md: Users need secure login...
468+
469+
# Outcome
470+
- [ ] Users can register with email/password
471+
- [ ] Users can log in and log out
472+
473+
2. "Integrate SAML SSO provider"
474+
...
475+
476+
Which features would you like me to create issues for?
477+
```

tests/unit/check-gate.test.ts

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { readFileSync } from "node:fs";
2-
import { join } from "node:path";
1+
import { readdirSync, readFileSync, statSync } from "node:fs";
2+
import { join, relative } from "node:path";
33
import { describe, expect, test } from "bun:test";
44

55
// Guard against the gate drifting apart again (CL-7300): `bun run check` and
@@ -27,6 +27,25 @@ const GUARD_SCRIPT = "check:projects-dir-guard";
2727
const TEST_SUITE =
2828
"bun test ./src ./tests ./evals ./scripts --randomize --seed 424242";
2929

30+
function expandToTestFiles(filters: string[]): string[] {
31+
const files: string[] = [];
32+
const walk = (dir: string) => {
33+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
34+
const absolute = join(dir, entry.name);
35+
if (entry.isDirectory()) walk(absolute);
36+
else if (entry.name.endsWith(".test.ts"))
37+
files.push(relative(repoRoot, absolute).split("/").join("/"));
38+
}
39+
};
40+
for (const filter of filters) {
41+
const absolute = join(repoRoot, filter.replace(/^\.\//, ""));
42+
if (statSync(absolute).isFile())
43+
files.push(relative(repoRoot, absolute).split("/").join("/"));
44+
else walk(absolute);
45+
}
46+
return files.sort();
47+
}
48+
3049
describe("check gate", () => {
3150
test("`test` is the seeded, randomized one-process suite whose path union CI shards", () => {
3251
expect(pkg.scripts.test).toBe(TEST_SUITE);
@@ -67,14 +86,20 @@ describe("check gate", () => {
6786
});
6887

6988
test("CI test shards cover exactly the suite's paths", () => {
70-
// Sharding must never silently drop part of the suite: the union of the
71-
// matrix shards has to equal the unsharded `test` script's paths.
72-
const shardPaths = [...ci.matchAll(/^\s+paths: (.+)$/gm)]
73-
.flatMap((match) => match[1]?.trim().split(/\s+/) ?? [])
74-
.sort();
75-
const suitePaths = TEST_SUITE.split(" ")
76-
.filter((part) => part.startsWith("./"))
77-
.sort();
78-
expect(shardPaths).toEqual(suitePaths);
89+
// Sharding must never silently drop (or double-run) part of the suite:
90+
// expanding the matrix shards' filters to test files has to equal the
91+
// unsharded `test` script's paths expanded the same way. Subdirectory
92+
// shards (src-a/b/c) can never equal the literal ./src string, so this
93+
// compares sorted file sets; a file covered twice fails the equality
94+
// through the duplicate entry.
95+
const shardFilters = [...ci.matchAll(/^\s+paths: (.+)$/gm)].flatMap(
96+
(match) => match[1]?.trim().split(/\s+/) ?? [],
97+
);
98+
const suiteFilters = TEST_SUITE.split(" ").filter((part) =>
99+
part.startsWith("./"),
100+
);
101+
expect(expandToTestFiles(shardFilters)).toEqual(
102+
expandToTestFiles(suiteFilters),
103+
);
79104
});
80105
});

0 commit comments

Comments
 (0)