@robhowley/pi-structured-return 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.
Files changed (33) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +131 -0
  3. package/extensions/structured-return/examples/.pi/machine-readable.json +18 -0
  4. package/extensions/structured-return/examples/.pi/parsers/foo-cli.ts +25 -0
  5. package/extensions/structured-return/src/.tmp/vitest-report.xml +55 -0
  6. package/extensions/structured-return/src/config/project-config.ts +10 -0
  7. package/extensions/structured-return/src/config/registry.ts +89 -0
  8. package/extensions/structured-return/src/index.test.ts +98 -0
  9. package/extensions/structured-return/src/index.ts +161 -0
  10. package/extensions/structured-return/src/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  11. package/extensions/structured-return/src/parsers/eslint-json.test.ts +60 -0
  12. package/extensions/structured-return/src/parsers/eslint-json.ts +33 -0
  13. package/extensions/structured-return/src/parsers/junit-xml.test.ts +169 -0
  14. package/extensions/structured-return/src/parsers/junit-xml.ts +97 -0
  15. package/extensions/structured-return/src/parsers/minitest-text.test.ts +110 -0
  16. package/extensions/structured-return/src/parsers/minitest-text.ts +99 -0
  17. package/extensions/structured-return/src/parsers/pytest-json-report.test.ts +76 -0
  18. package/extensions/structured-return/src/parsers/pytest-json-report.ts +41 -0
  19. package/extensions/structured-return/src/parsers/rspec-json.test.ts +126 -0
  20. package/extensions/structured-return/src/parsers/rspec-json.ts +76 -0
  21. package/extensions/structured-return/src/parsers/ruff-json.test.ts +57 -0
  22. package/extensions/structured-return/src/parsers/ruff-json.ts +37 -0
  23. package/extensions/structured-return/src/parsers/tail-fallback.test.ts +41 -0
  24. package/extensions/structured-return/src/parsers/tail-fallback.ts +20 -0
  25. package/extensions/structured-return/src/parsers/vitest-json.test.ts +118 -0
  26. package/extensions/structured-return/src/parsers/vitest-json.ts +60 -0
  27. package/extensions/structured-return/src/storage/log-store.ts +23 -0
  28. package/extensions/structured-return/src/types.ts +55 -0
  29. package/extensions/structured-return/src/ui/widget.ts +3 -0
  30. package/extensions/structured-return/tsconfig.json +11 -0
  31. package/extensions/structured-return/vitest.config.ts +9 -0
  32. package/package.json +62 -0
  33. package/skills/structured-return/SKILL.md +67 -0
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@robhowley/pi-structured-return",
3
+ "version": "0.1.0",
4
+ "description": "Structured command execution for Pi agents: compact results for the model, full logs for humans.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/robhowley/pi-structured-return"
9
+ },
10
+ "homepage": "https://github.com/robhowley/pi-structured-return",
11
+ "bugs": {
12
+ "url": "https://github.com/robhowley/pi-structured-return/issues"
13
+ },
14
+ "keywords": [
15
+ "pi-package"
16
+ ],
17
+ "files": [
18
+ "extensions",
19
+ "skills",
20
+ "LICENSE",
21
+ "README.md"
22
+ ],
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "lint-staged": {
27
+ "extensions/structured-return/src/**/*.ts": [
28
+ "eslint --fix",
29
+ "prettier --write"
30
+ ]
31
+ },
32
+ "pi": {
33
+ "extensions": [
34
+ "./extensions/structured-return/src/index.ts"
35
+ ],
36
+ "skills": [
37
+ "./skills/structured-return"
38
+ ]
39
+ },
40
+ "scripts": {
41
+ "typecheck": "tsc --noEmit -p extensions/structured-return/tsconfig.json",
42
+ "test": "vitest run --config extensions/structured-return/vitest.config.ts",
43
+ "lint": "eslint 'extensions/structured-return/src/**/*.ts'",
44
+ "format:check": "prettier --check 'extensions/structured-return/src/**/*.ts'",
45
+ "format": "prettier --write 'extensions/structured-return/src/**/*.ts'",
46
+ "prepare": "husky"
47
+ },
48
+ "dependencies": {
49
+ "fast-xml-parser": "^5.4.1"
50
+ },
51
+ "devDependencies": {
52
+ "@mariozechner/pi-coding-agent": "*",
53
+ "@sinclair/typebox": "^0.34.0",
54
+ "eslint": "^9.0.0",
55
+ "husky": "^9.1.7",
56
+ "lint-staged": "^16.4.0",
57
+ "prettier": "^3.4.0",
58
+ "typescript": "^5.7.0",
59
+ "typescript-eslint": "^8.0.0",
60
+ "vitest": "^4.1.0"
61
+ }
62
+ }
@@ -0,0 +1,67 @@
1
+ ---
2
+ name: structured-return
3
+ description: Choose compact, machine-readable commands across common test, lint, build, and log workflows. Use when raw terminal output would be noisy and the agent should prefer json, junit/xml, porcelain, quiet, no-pretty, or narrow-scope command forms.
4
+ ---
5
+
6
+ # structured-return
7
+
8
+ Prefer better output at the source.
9
+
10
+ ## What structured_return does
11
+
12
+ `structured_return` is a tool — use it instead of `bash` for lint, test, and build commands. It runs the command, stores the full log, and returns a compact parsed result to the model. When a parser matches, only the signal (failures, errors, summary) comes back into context. When no parser matches, it falls back to the last 200 lines of output plus a log path — still better than dumping everything into context via `bash`.
13
+
14
+ ## Rules
15
+
16
+ 1. Before running any lint, test, or build command, check for project-defined scripts (`package.json`, `Makefile`, `pyproject.toml`, etc.). If a script exists for the task, inspect it to identify the underlying tool and the scope/paths it uses. Then invoke that tool directly with machine-readable flags and the same scope — rather than running through the script wrapper.
17
+ 2. Use `structured_return` instead of `bash` for lint, test, and build commands. For tools with a built-in parser, use the command form shown in the examples below. For tools without one, use known machine-readable flags (`--json`, `--format json`, `--message-format=json`, `--console=plain`, `--porcelain`, etc.) and let the tail fallback handle the result.
18
+ 3. Otherwise prefer quiet, plain, no-color, and narrow-scope modes.
19
+ 4. Prefer file/test-specific runs before full-suite runs.
20
+ 5. Prefer bounded log reads over full log dumps.
21
+ 6. Do not invent flags. Use known patterns from examples below or your own knowledge of the tool.
22
+ 7. When using `structured_return`, pass explicit parser hints when known.
23
+ 8. If a repo defines project-local parser mappings in `.pi/structured-return.json`, prefer those mappings.
24
+
25
+ ## Examples
26
+
27
+ ### pytest
28
+ - `structured_return({ command: "pytest [any pytest args] --json-report --json-report-file=.tmp/pytest-report.json", parseAs: "pytest-json-report", artifactPaths: [".tmp/pytest-report.json"] })` — append the json-report flags to whatever pytest invocation is needed; scope, filters, markers, etc. go in `[any pytest args]`
29
+ - `structured_return({ command: "pytest -q" })` — fallback when json-report is unavailable
30
+
31
+ ### ruff check
32
+ - `structured_return({ command: "ruff check [any ruff args] --output-format=json", parseAs: "ruff-json" })` — scope, selects, ignores, etc. go in `[any ruff args]`
33
+
34
+ ### ruff format
35
+ - `ruff format --check .` (no structured_return — json output not supported)
36
+
37
+ ### vitest
38
+ - `structured_return({ command: "vitest run [any vitest args] --reporter=json", parseAs: "vitest-json" })` — file paths, filters, etc. go in `[any vitest args]`
39
+
40
+ ### eslint
41
+ - `structured_return({ command: "eslint [any eslint args] -f json", parseAs: "eslint-json" })` — paths, configs, rules, etc. go in `[any eslint args]`
42
+
43
+ ### rspec
44
+ - `structured_return({ command: "bundle exec rspec [any rspec args] --format json", parseAs: "rspec-json" })` — `--format json` is required; without it output is not parseable
45
+
46
+ ### minitest
47
+ - `structured_return({ command: "ruby [any minitest args]", parseAs: "minitest-text" })` — no format flags needed; works with plain ruby invocation
48
+
49
+ ### junit-xml
50
+ JUnit XML is the de facto standard output format across the JVM ecosystem and many others — Maven, Gradle, pytest (`--junitxml`), Go (`go-junit-report`), .NET (`--logger trx` with conversion), Jest (`jest-junit`), and more. If a tool can emit JUnit XML, `junit-xml` covers it without a custom parser.
51
+
52
+ - `structured_return({ command: "[tool] [args] --junitxml=.tmp/report.xml", parseAs: "junit-xml", artifactPaths: [".tmp/report.xml"] })` — pytest, nose2, and others that write to a file
53
+ - `structured_return({ command: "gradle test", parseAs: "junit-xml", artifactPaths: ["build/test-results/test/TEST-*.xml"] })` — Gradle writes one XML per test class; pass all matching paths
54
+ - `structured_return({ command: "mvn test", parseAs: "junit-xml", artifactPaths: ["target/surefire-reports/TEST-*.xml"] })` — Maven surefire same pattern
55
+
56
+ #### Swift / XCTest (Swift Package Manager)
57
+
58
+ `swift test` has native JUnit XML output via `--xunit-output` (Swift 5.7+). Use this for all SPM projects — no third-party reporter needed.
59
+
60
+ - `structured_return({ command: "swift test --xunit-output .tmp/report.xml", parseAs: "junit-xml", artifactPaths: [".tmp/report.xml"] })` — full test suite
61
+ - `structured_return({ command: "swift test --filter MathTests --xunit-output .tmp/report.xml", parseAs: "junit-xml", artifactPaths: [".tmp/report.xml"] })` — single test target or test case; `--filter` accepts a target name, class name, or `ClassName/testMethodName`
62
+
63
+ #### Swift / XCTest (Xcode projects)
64
+
65
+ `xcodebuild` output is high-volume and not directly parseable. Pipe through `xcbeautify` (install with `brew install xcbeautify`) to get JUnit XML:
66
+
67
+ - `structured_return({ command: "xcodebuild test -scheme [scheme] -destination '[destination]' 2>&1 | xcbeautify --report junit --output .tmp", parseAs: "junit-xml", artifactPaths: [".tmp/report.junit.xml"] })` — xcbeautify writes `report.junit.xml` into the `--output` directory; run `xcodebuild -showdestinations -scheme [scheme]` first to find the correct `[destination]` string for the project