mirror of
https://github.com/multica-ai/multica.git
synced 2026-08-03 11:10:23 +02:00
MUL-5261: revert domain-specific prompt additions (#5913)
Revert the built-in focused-testing skill (#5877) and the always-on Repository Setup Preflight brief section (#5886). Both delivered software-engineering domain content through platform-level prompt surfaces that every agent receives regardless of workspace type. - multica-focused-testing was the only built-in skill that did not describe a Multica platform contract, and the only one without `user-invocable: false` / `allowed-tools: Bash(multica *)`. Built-in skills are meta/system skills; a workspace with no repository bound still carried it in its skill index and slash-command menu. - Repository Setup Preflight was emitted for every non-quick-create task without consulting `ctx.Repos`, so non-code workspaces received build/dependency instructions in the always-on brief. writeRepositories already elides itself when no repo is bound; this section did not. Pure revert. No replacement behavior is introduced here. Co-authored-by: Lambda <lambda@multica.ai> Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
@@ -111,10 +111,6 @@ func TestBuildMetaSkillContentSlimKindMatrix(t *testing.T) {
|
||||
kindCommentTriggered: true, kindAssignmentTriggered: true,
|
||||
kindAutopilotRunOnly: true, kindChat: true,
|
||||
}},
|
||||
{"## Repository Setup Preflight", map[taskKind]bool{
|
||||
kindCommentTriggered: true, kindAssignmentTriggered: true,
|
||||
kindAutopilotRunOnly: true, kindChat: true,
|
||||
}},
|
||||
{"## Issue Metadata", issueKinds},
|
||||
{"## Instruction Precedence", map[taskKind]bool{kindAssignmentTriggered: true}},
|
||||
{"## Sub-issue Creation", issueKinds},
|
||||
@@ -156,51 +152,6 @@ func TestBuildMetaSkillContentSlimKindMatrix(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRepositorySetupPreflightIsStackAgnostic(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var b strings.Builder
|
||||
writeRepositorySetupPreflight(&b)
|
||||
out := b.String()
|
||||
|
||||
for _, want := range []string{
|
||||
"after `multica repo checkout`",
|
||||
"Before editing code or running build/test commands",
|
||||
"`AGENTS.md`, `README`, development docs",
|
||||
"dependency manifests and lockfiles",
|
||||
"missing, stale, or readiness is uncertain",
|
||||
"documented, reproducible setup command",
|
||||
"Do not reinstall when the existing environment is demonstrably ready",
|
||||
"did not unexpectedly modify dependency manifests or lockfiles",
|
||||
"Do not use a failing build or test run",
|
||||
} {
|
||||
if !strings.Contains(out, want) {
|
||||
t.Errorf("repository setup preflight missing %q\n---\n%s", want, out)
|
||||
}
|
||||
}
|
||||
|
||||
for _, packageManager := range []string{"pnpm", "npm install", "yarn", "bun install", "pip install", "poetry", "cargo"} {
|
||||
if strings.Contains(strings.ToLower(out), packageManager) {
|
||||
t.Errorf("repository setup preflight must stay stack-agnostic; found %q\n---\n%s", packageManager, out)
|
||||
}
|
||||
}
|
||||
|
||||
brief := buildMetaSkillContent("codex", TaskContextForEnv{
|
||||
IssueID: "issue-1",
|
||||
Repos: []RepoContextForEnv{{URL: "https://example.com/repo.git"}},
|
||||
})
|
||||
repositoriesIndex := strings.Index(brief, "\n## Repositories\n")
|
||||
preflightIndex := strings.Index(brief, "\n## Repository Setup Preflight\n")
|
||||
if repositoriesIndex == -1 || preflightIndex <= repositoriesIndex {
|
||||
t.Errorf("repository setup preflight must follow repository checkout guidance\n---\n%s", brief)
|
||||
}
|
||||
|
||||
localBrief := buildMetaSkillContent("codex", TaskContextForEnv{IssueID: "issue-1"})
|
||||
if !strings.Contains(localBrief, "\n## Repository Setup Preflight\n") {
|
||||
t.Errorf("repository setup preflight must also cover an existing local working directory\n---\n%s", localBrief)
|
||||
}
|
||||
}
|
||||
|
||||
// TestSlimQuickCreateAvailableCommands locks the minimal-variant content
|
||||
// for quick-create's Available Commands: `issue create` present, every
|
||||
// other Core command absent (the hard guardrails forbid the call).
|
||||
|
||||
@@ -30,8 +30,8 @@ import (
|
||||
// 2. Per-section prose compression — Available Commands, Issue
|
||||
// Metadata, Mentions, Sub-issue Creation, Comment Formatting,
|
||||
// Always Use CLI, Background Task Safety, Task Initiator,
|
||||
// Repositories, Repository Setup Preflight, Output are all
|
||||
// tightened. Every test-asserted phrase stays.
|
||||
// Repositories, Output are all tightened. Every test-asserted phrase
|
||||
// stays.
|
||||
//
|
||||
// Background Task Safety is emitted by `writeBackgroundTaskSafetySlim`
|
||||
// below.
|
||||
@@ -299,20 +299,6 @@ func writeRepositories(b *strings.Builder, ctx TaskContextForEnv) {
|
||||
b.WriteString("\n")
|
||||
}
|
||||
|
||||
// writeRepositorySetupPreflight emits a stack-agnostic readiness check for
|
||||
// every task surface that can perform repository work. It deliberately asks
|
||||
// the agent to infer the repository's own setup contract instead of naming a
|
||||
// package manager or forcing a reinstall on a warm workdir.
|
||||
func writeRepositorySetupPreflight(b *strings.Builder) {
|
||||
b.WriteString("## Repository Setup Preflight\n\n")
|
||||
b.WriteString("Before editing code or running build/test commands in a repository (after `multica repo checkout`, or immediately when working in an existing local directory):\n\n")
|
||||
b.WriteString("- Read the repository instructions and setup documentation (`AGENTS.md`, `README`, development docs), plus the relevant dependency manifests and lockfiles.\n")
|
||||
b.WriteString("- Identify the stack and package/dependency manager, then determine whether the required dependencies and tools are already usable.\n")
|
||||
b.WriteString("- If dependencies are missing, stale, or readiness is uncertain, run the repository's documented, reproducible setup command before proceeding. Do not reinstall when the existing environment is demonstrably ready.\n")
|
||||
b.WriteString("- Check that setup did not unexpectedly modify dependency manifests or lockfiles; investigate unexpected changes before continuing.\n")
|
||||
b.WriteString("- Do not use a failing build or test run as the way to discover that dependencies were not prepared.\n\n")
|
||||
}
|
||||
|
||||
// writeProjectContext emits the Project Context section when the task carries
|
||||
// an active project. Project context is independent of the task surface: an
|
||||
// issue inherits it from its project, while a chat receives it from the
|
||||
@@ -654,7 +640,6 @@ func writeOutput(b *strings.Builder, kind taskKind, ctx TaskContextForEnv) {
|
||||
// Comment Formatting | ✓ | ✓ | — | — | —
|
||||
// Repositories | △ | △ | △ | — | △
|
||||
// Project Context | △ | △ | △ | △ | △
|
||||
// Repository Preflight | ✓ | ✓ | ✓ | — | ✓
|
||||
// Issue Metadata | ✓ | ✓ | — | — | —
|
||||
// Instruction Precedence| — | ✓ | — | — | —
|
||||
// Sub-issue Creation | ✓ | ✓ | — | — | —
|
||||
@@ -696,10 +681,6 @@ func buildMetaSkillContentSlim(provider string, ctx TaskContextForEnv) string {
|
||||
|
||||
writeProjectContext(&b, ctx)
|
||||
|
||||
if kind != kindQuickCreate {
|
||||
writeRepositorySetupPreflight(&b)
|
||||
}
|
||||
|
||||
if kind.hasIssueContext() {
|
||||
writeIssueMetadata(&b)
|
||||
}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
---
|
||||
name: multica-focused-testing
|
||||
description: "Use when selecting or running a focused or targeted test in any user repository. Detect the repository's stack and runner first, prefer its commands, and verify discovery before execution. Not for an explicitly requested full-suite run."
|
||||
---
|
||||
|
||||
# Focused testing
|
||||
|
||||
Run the narrowest runner-native scope without expanding it to a full suite.
|
||||
|
||||
## Workflow
|
||||
|
||||
1. Read repository instructions and test configuration. Verify the target,
|
||||
ownership, build tool, and runner.
|
||||
2. Prefer repository Agent configuration, then a dedicated repository script,
|
||||
then a runner-native focused selector confirmed by configuration or local
|
||||
`--help`. Infer only as a last resort.
|
||||
3. Keep the target as a distinct argument. Do not guess whether a wrapper
|
||||
forwards separators or positional arguments, and do not add a separator
|
||||
unless the detected tool requires it.
|
||||
4. Use list, collect, discovery, or dry-run mode first when available. Compare
|
||||
it with the runner-native scope: file, package plus case, target, class,
|
||||
module, or project. Never impose
|
||||
`expected_file_count=1` on a runner that does not discover by file.
|
||||
5. Run only when scope is confirmed. If discovery is broader or the target,
|
||||
ownership, runner, or forwarding contract remains unclear, stop and correct
|
||||
or report the gap rather than guessing.
|
||||
|
||||
## Stack reference
|
||||
|
||||
After detection, read exactly the matching reference:
|
||||
|
||||
- JavaScript or TypeScript: `references/javascript-typescript.md`
|
||||
- Go: `references/go.md`
|
||||
- Python: `references/python.md`
|
||||
- Rust: `references/rust.md`
|
||||
- JVM (Gradle or Maven): `references/jvm.md`
|
||||
- .NET: `references/dotnet.md`
|
||||
- Ruby: `references/ruby.md`
|
||||
|
||||
If no reference matches, use the repository's own instructions and the detected
|
||||
runner's local help. Do not borrow a template from another stack.
|
||||
@@ -1,39 +0,0 @@
|
||||
# .NET
|
||||
|
||||
Identify the owning project or solution and inspect repository build scripts
|
||||
before calling `dotnet test`. Prefer a project file over a whole solution for a
|
||||
focused run. Check the SDK and `global.json` first: .NET 10 can select either
|
||||
VSTest or Microsoft.Testing.Platform (MTP), and their CLI contracts differ.
|
||||
|
||||
For VSTest, after confirming the adapter's filter support:
|
||||
|
||||
```text
|
||||
["dotnet", "test", "path/to/project.csproj", "--filter", "FullyQualifiedName=Namespace.ClassName.MethodName"]
|
||||
```
|
||||
|
||||
Verify the same filter without executing tests:
|
||||
|
||||
```text
|
||||
["dotnet", "test", "path/to/project.csproj", "--list-tests", "--filter", "FullyQualifiedName=Namespace.ClassName.MethodName"]
|
||||
```
|
||||
|
||||
`FullyQualifiedName` is available in the popular VSTest adapters, but the exact
|
||||
value format and other filter properties vary. Confirm the discovered name from
|
||||
`--list-tests`.
|
||||
|
||||
Do not reuse that argv for MTP. With the .NET 10 MTP driver, project selection
|
||||
uses `--project`, while test-related arguments come from the registered
|
||||
framework extensions and should be placed after a literal `--` when forwarding
|
||||
would otherwise be ambiguous. Inspect `global.json`, the test framework, and
|
||||
the local `dotnet test --help` / test-application help before constructing the
|
||||
filter. Do not assume MSTest, NUnit, xUnit, or custom MTP extensions share a
|
||||
universal selector.
|
||||
|
||||
## Official documentation
|
||||
|
||||
- Runner selection in `dotnet test`:
|
||||
https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-test
|
||||
- VSTest `--filter`, `--list-tests`, and filter properties:
|
||||
https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-test-vstest
|
||||
- .NET 10 MTP project selection and argument forwarding:
|
||||
https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-test-mtp
|
||||
@@ -1,32 +0,0 @@
|
||||
# Go
|
||||
|
||||
Go tests are compiled and selected by package and test name, not reliably by
|
||||
running one `_test.go` file in isolation. Identify the owning module and package
|
||||
from `go.mod` and the target path.
|
||||
|
||||
Use the package plus an anchored `-run` expression:
|
||||
|
||||
```text
|
||||
["go", "test", "./path/to/package", "-run", "^TestName$", "-count=1"]
|
||||
```
|
||||
|
||||
For a top-level test, verify discovery without running it:
|
||||
|
||||
```text
|
||||
["go", "test", "./path/to/package", "-list", "^TestName$"]
|
||||
```
|
||||
|
||||
`-list` does not enumerate subtests. For a subtest, use an anchored
|
||||
parent/subtest expression, such as `^TestName$/^SubtestName$`, after confirming
|
||||
the exact names from source or verbose output. Go splits `-run` expressions at
|
||||
unbracketed `/` characters and may run a matching parent to discover its
|
||||
subtests.
|
||||
|
||||
Do not pass a single `_test.go` file merely to imitate file-oriented runners:
|
||||
that can omit package files, shared test helpers, or build-tag behavior. The
|
||||
expected scope is the owning package with the requested test selected.
|
||||
|
||||
## Official documentation
|
||||
|
||||
- Go testing flags (`-run`, `-list`, and `-count`):
|
||||
https://pkg.go.dev/cmd/go#hdr-Testing_flags
|
||||
@@ -1,46 +0,0 @@
|
||||
# JavaScript and TypeScript
|
||||
|
||||
Inspect the nearest `package.json`, the workspace manifest, the lockfile, and
|
||||
the runner config. Use the owning package's package-relative test path when a
|
||||
workspace command changes the runner's working directory.
|
||||
|
||||
For pnpm plus Vitest, when repository configuration does not provide a
|
||||
dedicated command, use this direct runner shape from the repository root:
|
||||
|
||||
```text
|
||||
["pnpm", "--filter", "<workspace>", "exec", "vitest", "run", "<package-relative-test-file>"]
|
||||
```
|
||||
|
||||
`pnpm exec` runs the dependency command in the selected project's scope and
|
||||
passes options after `exec` to that command. Vitest treats a positional value
|
||||
as a substring filter over test-file paths, so pass the full package-relative
|
||||
path and verify that it uniquely identifies the requested file.
|
||||
|
||||
Do not use this shape for a focused run:
|
||||
|
||||
```text
|
||||
["pnpm", "--filter", "<workspace>", "test", "--", "<test-file>"]
|
||||
```
|
||||
|
||||
pnpm passes arguments after the script name to the executed script. In this
|
||||
shape Vitest receives the literal separator before the path; that is not the
|
||||
direct file-filter argv above and can expand discovery to the whole package.
|
||||
|
||||
For other package managers or runners, inspect the repository script and local
|
||||
runner help. Do not translate the pnpm/Vitest argv mechanically.
|
||||
|
||||
If the installed Vitest version exposes `list` and `--filesOnly`, verify the
|
||||
same filter before execution:
|
||||
|
||||
```text
|
||||
["pnpm", "--filter", "<workspace>", "exec", "vitest", "list", "<package-relative-test-file>", "--filesOnly"]
|
||||
```
|
||||
|
||||
Require exactly one discovered test file.
|
||||
|
||||
## Official documentation
|
||||
|
||||
- pnpm filtering: https://pnpm.io/filtering
|
||||
- pnpm exec and option forwarding: https://pnpm.io/cli/exec
|
||||
- pnpm run argument forwarding: https://pnpm.io/cli/run
|
||||
- Vitest CLI file filters, `run`, and `list`: https://vitest.dev/guide/cli
|
||||
@@ -1,39 +0,0 @@
|
||||
# JVM
|
||||
|
||||
Use the repository wrapper (`gradlew` or `mvnw`) and identify the owning module
|
||||
before selecting a test. Build configuration may add plugins, profiles, or
|
||||
environment required by the suite.
|
||||
|
||||
For Gradle, after confirming the task path:
|
||||
|
||||
```text
|
||||
["./gradlew", ":module:test", "--tests", "package.ClassName.methodName"]
|
||||
```
|
||||
|
||||
Use `gradlew.bat` on Windows. If the repository's wrapper exposes
|
||||
`--test-dry-run`, add it first to inspect the selected tests without executing
|
||||
them. Filters configured in the build script still apply alongside `--tests`.
|
||||
|
||||
For Maven Surefire, after confirming the module and plugin:
|
||||
|
||||
```text
|
||||
["./mvnw", "-pl", "module", "-Dtest=ClassName#methodName", "test"]
|
||||
```
|
||||
|
||||
Use `mvnw.cmd` on Windows. The current Surefire documentation scopes its
|
||||
`ClassName#methodName` example to JUnit 4.x and TestNG. For JUnit 5 or another
|
||||
provider, use a method selector only after the repository's installed plugin
|
||||
and provider confirm support.
|
||||
|
||||
Do not assume these selectors apply to custom Gradle tasks, Maven Failsafe,
|
||||
integration-test source sets, parameterized cases, or other JVM runners.
|
||||
Inspect the build files and task/plugin help first.
|
||||
|
||||
## Official documentation
|
||||
|
||||
- Gradle wrapper, project task paths, and task options:
|
||||
https://docs.gradle.org/current/userguide/command_line_interface.html
|
||||
- Gradle `--tests` filtering and `--test-dry-run`:
|
||||
https://docs.gradle.org/current/userguide/java_testing.html#test_filtering
|
||||
- Maven Surefire single-class and method selectors:
|
||||
https://maven.apache.org/surefire/maven-surefire-plugin/examples/single-test.html
|
||||
@@ -1,33 +0,0 @@
|
||||
# Python
|
||||
|
||||
Inspect `pyproject.toml`, `pytest.ini`, `tox.ini`, `setup.cfg`, and repository
|
||||
scripts to identify the environment wrapper and runner. Preserve repository
|
||||
wrappers such as tox, nox, uv, or Poetry when they establish dependencies or
|
||||
environment variables.
|
||||
|
||||
For direct pytest usage, a file target is:
|
||||
|
||||
```text
|
||||
["python", "-m", "pytest", "path/to/test_file.py"]
|
||||
```
|
||||
|
||||
A single case uses its pytest node id:
|
||||
|
||||
```text
|
||||
["python", "-m", "pytest", "path/to/test_file.py::TestClass::test_name"]
|
||||
```
|
||||
|
||||
Verify the node id before executing:
|
||||
|
||||
```text
|
||||
["python", "-m", "pytest", "--collect-only", "-q", "path/to/test_file.py::TestClass::test_name"]
|
||||
```
|
||||
|
||||
Parameterized cases add their generated id in brackets; copy it from collection
|
||||
output instead of guessing it. Do not assume a unittest, Django, or custom
|
||||
runner accepts pytest selectors; use the detected runner's own syntax.
|
||||
|
||||
## Official documentation
|
||||
|
||||
- pytest invocation, node ids, `python -m pytest`, and `--collect-only`:
|
||||
https://docs.pytest.org/en/stable/how-to/usage.html
|
||||
@@ -1,35 +0,0 @@
|
||||
# Ruby
|
||||
|
||||
Inspect `Gemfile`, repository scripts, and runner configuration. Use
|
||||
`bundle exec` when the repository is Bundler-managed so the selected runner
|
||||
version and plugins match the project.
|
||||
|
||||
For RSpec, a file target is:
|
||||
|
||||
```text
|
||||
["bundle", "exec", "rspec", "spec/path/to/example_spec.rb"]
|
||||
```
|
||||
|
||||
RSpec can select an example or group by a line in the file:
|
||||
|
||||
```text
|
||||
["bundle", "exec", "rspec", "spec/path/to/example_spec.rb:<line>"]
|
||||
```
|
||||
|
||||
Do not apply RSpec syntax to Minitest, Rails test tasks, or custom runners.
|
||||
For example, Rails' Minitest runner has its own file-and-line form:
|
||||
|
||||
```text
|
||||
["bin/rails", "test", "test/models/user_test.rb:<line>"]
|
||||
```
|
||||
|
||||
Follow the repository's runner-specific command and expected scope.
|
||||
|
||||
## Official documentation
|
||||
|
||||
- Bundler execution context and its RSpec example:
|
||||
https://bundler.io/man/bundle-exec.1.html
|
||||
- RSpec file-and-line selection:
|
||||
https://rspec.info/features/3-12/rspec-core/command-line/line-number-appended-to-path/
|
||||
- Rails Minitest file, name, and line selection:
|
||||
https://guides.rubyonrails.org/testing.html#the-rails-test-runner
|
||||
@@ -1,40 +0,0 @@
|
||||
# Rust
|
||||
|
||||
Inspect the workspace `Cargo.toml` and the target crate's manifest. Rust's
|
||||
focused unit scope is usually a package plus a test name; an integration test
|
||||
file is a named Cargo test target.
|
||||
|
||||
For an integration-test target:
|
||||
|
||||
```text
|
||||
["cargo", "test", "-p", "<package>", "--test", "<integration-target>"]
|
||||
```
|
||||
|
||||
List the libtest names in that target without running them:
|
||||
|
||||
```text
|
||||
["cargo", "test", "-p", "<package>", "--test", "<integration-target>", "--", "--list"]
|
||||
```
|
||||
|
||||
Then run one case using the full path printed by libtest:
|
||||
|
||||
```text
|
||||
["cargo", "test", "-p", "<package>", "--test", "<integration-target>", "--", "<full-test-path>", "--exact"]
|
||||
```
|
||||
|
||||
For a library unit test, replace `--test <integration-target>` with `--lib`.
|
||||
Here the separator is required because the filter, `--list`, and `--exact`
|
||||
belong to the compiled libtest harness, not Cargo. `--exact` matches only a full
|
||||
path such as `module::tests::test_name`; a short function name can select zero
|
||||
tests. Confirm the target name with Cargo metadata or the manifest instead of
|
||||
deriving it only from a filesystem path.
|
||||
|
||||
These libtest arguments do not apply when the target declares
|
||||
`harness = false`; use that target's own CLI.
|
||||
|
||||
## Official documentation
|
||||
|
||||
- Cargo package/target selection and test-argument forwarding:
|
||||
https://doc.rust-lang.org/cargo/commands/cargo-test.html
|
||||
- libtest filters, `--list`, and `--exact`:
|
||||
https://doc.rust-lang.org/rustc/tests/
|
||||
@@ -518,121 +518,6 @@ func TestProjectsAndResourcesSkillCoversDurableContext(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFocusedTestingSkillUsesStackSpecificProgressiveDisclosure(t *testing.T) {
|
||||
skill, ok := findSkill(t, "multica-focused-testing")
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
fm, body, _ := splitFrontmatter(skill.Content)
|
||||
|
||||
description := fm["description"]
|
||||
for _, want := range []string{
|
||||
"focused or targeted test",
|
||||
"any user repository",
|
||||
"Detect the repository's stack and runner first",
|
||||
"Not for an explicitly requested full-suite run",
|
||||
} {
|
||||
if !strings.Contains(description, want) {
|
||||
t.Errorf("focused-testing description missing trigger text %q", want)
|
||||
}
|
||||
}
|
||||
|
||||
for _, want := range []string{
|
||||
"repository Agent configuration",
|
||||
"dedicated repository script",
|
||||
"runner-native focused selector",
|
||||
"Do not guess whether a wrapper",
|
||||
"forwards separators or positional arguments",
|
||||
"Never impose",
|
||||
"`expected_file_count=1` on a runner that does not discover by file",
|
||||
"read exactly the matching reference",
|
||||
"Do not borrow a template from another stack",
|
||||
} {
|
||||
if !strings.Contains(body, want) {
|
||||
t.Errorf("focused-testing skill missing stack-neutral rule %q", want)
|
||||
}
|
||||
}
|
||||
|
||||
// Concrete runner commands belong behind one-level-deep references. The
|
||||
// body is loaded for every focused-test task; keeping templates out of it
|
||||
// prevents a Go/Python/Rust repository from inheriting frontend noise.
|
||||
for _, runnerSpecific := range []string{
|
||||
"pnpm --filter",
|
||||
"go test",
|
||||
"python -m pytest",
|
||||
"cargo test",
|
||||
"./gradlew",
|
||||
"dotnet test",
|
||||
"bundle exec rspec",
|
||||
} {
|
||||
if strings.Contains(body, runnerSpecific) {
|
||||
t.Errorf("focused-testing body must stay stack-neutral; found %q", runnerSpecific)
|
||||
}
|
||||
}
|
||||
|
||||
references := map[string][]string{
|
||||
"references/javascript-typescript.md": {
|
||||
`["pnpm", "--filter", "<workspace>", "exec", "vitest", "run", "<package-relative-test-file>"]`,
|
||||
`["pnpm", "--filter", "<workspace>", "exec", "vitest", "list", "<package-relative-test-file>", "--filesOnly"]`,
|
||||
`["pnpm", "--filter", "<workspace>", "test", "--", "<test-file>"]`,
|
||||
"exactly one discovered test file",
|
||||
"https://pnpm.io/cli/exec",
|
||||
"https://vitest.dev/guide/cli",
|
||||
},
|
||||
"references/go.md": {
|
||||
`["go", "test", "./path/to/package", "-run", "^TestName$", "-count=1"]`,
|
||||
`["go", "test", "./path/to/package", "-list", "^TestName$"]`,
|
||||
"not reliably by\nrunning one `_test.go` file in isolation",
|
||||
"https://pkg.go.dev/cmd/go#hdr-Testing_flags",
|
||||
},
|
||||
"references/python.md": {
|
||||
`["python", "-m", "pytest", "path/to/test_file.py::TestClass::test_name"]`,
|
||||
`["python", "-m", "pytest", "--collect-only", "-q", "path/to/test_file.py::TestClass::test_name"]`,
|
||||
"https://docs.pytest.org/en/stable/how-to/usage.html",
|
||||
},
|
||||
"references/rust.md": {
|
||||
`["cargo", "test", "-p", "<package>", "--test", "<integration-target>"]`,
|
||||
`["cargo", "test", "-p", "<package>", "--test", "<integration-target>", "--", "<full-test-path>", "--exact"]`,
|
||||
"the separator is required",
|
||||
"`harness = false`",
|
||||
"https://doc.rust-lang.org/rustc/tests/",
|
||||
},
|
||||
"references/jvm.md": {
|
||||
`["./gradlew", ":module:test", "--tests", "package.ClassName.methodName"]`,
|
||||
`["./mvnw", "-pl", "module", "-Dtest=ClassName#methodName", "test"]`,
|
||||
"JUnit 4.x and TestNG",
|
||||
"https://docs.gradle.org/current/userguide/java_testing.html#test_filtering",
|
||||
"https://maven.apache.org/surefire/maven-surefire-plugin/examples/single-test.html",
|
||||
},
|
||||
"references/dotnet.md": {
|
||||
`["dotnet", "test", "path/to/project.csproj", "--filter", "FullyQualifiedName=Namespace.ClassName.MethodName"]`,
|
||||
`["dotnet", "test", "path/to/project.csproj", "--list-tests", "--filter", "FullyQualifiedName=Namespace.ClassName.MethodName"]`,
|
||||
"Do not reuse that argv for MTP",
|
||||
"https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-test-mtp",
|
||||
},
|
||||
"references/ruby.md": {
|
||||
`["bundle", "exec", "rspec", "spec/path/to/example_spec.rb"]`,
|
||||
`["bundle", "exec", "rspec", "spec/path/to/example_spec.rb:<line>"]`,
|
||||
`["bin/rails", "test", "test/models/user_test.rb:<line>"]`,
|
||||
"Do not apply RSpec syntax to Minitest",
|
||||
"https://bundler.io/man/bundle-exec.1.html",
|
||||
"https://guides.rubyonrails.org/testing.html#the-rails-test-runner",
|
||||
},
|
||||
}
|
||||
for path, mustContain := range references {
|
||||
content, ok := skillFileContent(skill, path)
|
||||
if !ok {
|
||||
t.Errorf("focused-testing skill missing supporting file %s", path)
|
||||
continue
|
||||
}
|
||||
for _, want := range mustContain {
|
||||
if !strings.Contains(content, want) {
|
||||
t.Errorf("%s missing %q", path, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func findSkill(t *testing.T, name string) (AgentSkillData, bool) {
|
||||
t.Helper()
|
||||
for _, s := range loadBuiltinSkills() {
|
||||
@@ -644,15 +529,6 @@ func findSkill(t *testing.T, name string) (AgentSkillData, bool) {
|
||||
return AgentSkillData{}, false
|
||||
}
|
||||
|
||||
func skillFileContent(skill AgentSkillData, path string) (string, bool) {
|
||||
for _, f := range skill.Files {
|
||||
if f.Path == path {
|
||||
return f.Content, true
|
||||
}
|
||||
}
|
||||
return "", false
|
||||
}
|
||||
|
||||
func skillHasFile(skill AgentSkillData, path string) bool {
|
||||
for _, f := range skill.Files {
|
||||
if f.Path == path {
|
||||
|
||||
Reference in New Issue
Block a user