@codersbrew/pi-tools 0.1.0 → 0.2.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/README.md +21 -6
- package/extensions/session-breakdown.ts +72 -1
- package/package.json +8 -3
- package/skills/github-workflow/SKILL.md +185 -0
package/README.md
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# @codersbrew/pi-tools
|
|
2
2
|
|
|
3
|
-
A publishable [pi](https://github.com/badlogic/pi-mono) package that bundles CodersBrew's custom pi extensions.
|
|
3
|
+
A publishable [pi](https://github.com/badlogic/pi-mono) package that bundles CodersBrew's custom pi extensions and skills.
|
|
4
4
|
|
|
5
|
-
## Included
|
|
5
|
+
## Included resources
|
|
6
|
+
|
|
7
|
+
### Extensions
|
|
6
8
|
|
|
7
9
|
### `security`
|
|
8
10
|
Protects common dangerous tool operations by:
|
|
@@ -16,6 +18,17 @@ Adds an interactive TUI for analyzing pi session history from `~/.pi/agent/sessi
|
|
|
16
18
|
- model, cwd, day-of-week, and time-of-day breakdowns
|
|
17
19
|
- contribution-style heatmap visualizations
|
|
18
20
|
|
|
21
|
+
### Skill: `github-workflow`
|
|
22
|
+
An opinionated GitHub workflow skill for branch creation, commits, pushes, PR creation, review, and merge work.
|
|
23
|
+
|
|
24
|
+
It prefers `gh` for GitHub-aware actions and uses plain `git` where local source-control operations are the better tool.
|
|
25
|
+
|
|
26
|
+
Invoke it in pi with:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
/skill:github-workflow
|
|
30
|
+
```
|
|
31
|
+
|
|
19
32
|
## Install
|
|
20
33
|
|
|
21
34
|
Global install:
|
|
@@ -43,13 +56,15 @@ You can also add it manually to pi settings:
|
|
|
43
56
|
This package uses pi's standard package manifest:
|
|
44
57
|
- `extensions/security.ts`
|
|
45
58
|
- `extensions/session-breakdown.ts`
|
|
59
|
+
- `skills/github-workflow/SKILL.md`
|
|
46
60
|
|
|
47
61
|
The root `package.json` exposes them through:
|
|
48
62
|
|
|
49
63
|
```json
|
|
50
64
|
{
|
|
51
65
|
"pi": {
|
|
52
|
-
"extensions": ["./extensions"]
|
|
66
|
+
"extensions": ["./extensions"],
|
|
67
|
+
"skills": ["./skills"]
|
|
53
68
|
}
|
|
54
69
|
}
|
|
55
70
|
```
|
|
@@ -86,8 +101,8 @@ Bootstrap steps for `@codersbrew/pi-tools`:
|
|
|
86
101
|
|
|
87
102
|
1. Create an npm access token with publish rights
|
|
88
103
|
2. Add it to the GitHub repo as `NPM_TOKEN`
|
|
89
|
-
3. Confirm `package.json` has the intended version
|
|
90
|
-
4. Push a version tag such as `v0.
|
|
104
|
+
3. Confirm `package.json` has the intended version
|
|
105
|
+
4. Push a matching version tag such as `v0.2.0`
|
|
91
106
|
5. GitHub Actions will verify the package, publish it, and create a GitHub release
|
|
92
107
|
|
|
93
108
|
### Switch to trusted publishing after first release
|
|
@@ -106,7 +121,7 @@ After trusted publishing is configured, remove the `NPM_TOKEN` secret if you wan
|
|
|
106
121
|
|
|
107
122
|
1. Update the package version in `package.json`
|
|
108
123
|
2. Commit and push the change
|
|
109
|
-
3. Create and push a matching version tag such as `v0.
|
|
124
|
+
3. Create and push a matching version tag such as `v0.2.0`
|
|
110
125
|
4. GitHub Actions will run verification, publish to npm, and create a GitHub release
|
|
111
126
|
|
|
112
127
|
The workflow uses Node 24 so the npm CLI is new enough for trusted publishing and provenance support.
|
|
@@ -25,7 +25,6 @@ import {
|
|
|
25
25
|
truncateToWidth,
|
|
26
26
|
visibleWidth,
|
|
27
27
|
} from "@mariozechner/pi-tui";
|
|
28
|
-
import { sliceByColumn } from "@mariozechner/pi-tui/dist/utils.js";
|
|
29
28
|
import os from "node:os";
|
|
30
29
|
import path from "node:path";
|
|
31
30
|
import fs from "node:fs/promises";
|
|
@@ -48,6 +47,78 @@ const TOD_BUCKETS: { key: TodKey; label: string; from: number; to: number }[] =
|
|
|
48
47
|
{ key: "night", label: "Night (22–23)", from: 22, to: 23 },
|
|
49
48
|
];
|
|
50
49
|
|
|
50
|
+
const graphemeSegmenter = new Intl.Segmenter(undefined, { granularity: "grapheme" });
|
|
51
|
+
|
|
52
|
+
function extractAnsiCode(str: string, pos: number): { code: string; length: number } | null {
|
|
53
|
+
if (pos >= str.length || str[pos] !== "\x1b") return null;
|
|
54
|
+
const next = str[pos + 1];
|
|
55
|
+
|
|
56
|
+
if (next === "[") {
|
|
57
|
+
let j = pos + 2;
|
|
58
|
+
while (j < str.length && !/[mGKHJ]/.test(str[j])) j++;
|
|
59
|
+
if (j < str.length) return { code: str.substring(pos, j + 1), length: j + 1 - pos };
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (next === "]" || next === "_") {
|
|
64
|
+
let j = pos + 2;
|
|
65
|
+
while (j < str.length) {
|
|
66
|
+
if (str[j] === "\x07") return { code: str.substring(pos, j + 1), length: j + 1 - pos };
|
|
67
|
+
if (str[j] === "\x1b" && str[j + 1] === "\\") return { code: str.substring(pos, j + 2), length: j + 2 - pos };
|
|
68
|
+
j++;
|
|
69
|
+
}
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// pi's extension loader aliases @mariozechner/pi-tui to its dist/index.js entry.
|
|
77
|
+
// Importing deep internals like @mariozechner/pi-tui/dist/utils.js therefore resolves
|
|
78
|
+
// incorrectly under jiti (…/dist/index.js/dist/utils.js), so keep this local helper.
|
|
79
|
+
function sliceByColumn(line: string, startCol: number, length: number, strict = false): string {
|
|
80
|
+
if (length <= 0) return "";
|
|
81
|
+
|
|
82
|
+
const endCol = startCol + length;
|
|
83
|
+
let result = "";
|
|
84
|
+
let currentCol = 0;
|
|
85
|
+
let i = 0;
|
|
86
|
+
let pendingAnsi = "";
|
|
87
|
+
|
|
88
|
+
while (i < line.length) {
|
|
89
|
+
const ansi = extractAnsiCode(line, i);
|
|
90
|
+
if (ansi) {
|
|
91
|
+
if (currentCol >= startCol && currentCol < endCol) result += ansi.code;
|
|
92
|
+
else if (currentCol < startCol) pendingAnsi += ansi.code;
|
|
93
|
+
i += ansi.length;
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
let textEnd = i;
|
|
98
|
+
while (textEnd < line.length && !extractAnsiCode(line, textEnd)) textEnd++;
|
|
99
|
+
|
|
100
|
+
for (const { segment } of graphemeSegmenter.segment(line.slice(i, textEnd))) {
|
|
101
|
+
const w = visibleWidth(segment);
|
|
102
|
+
const inRange = currentCol >= startCol && currentCol < endCol;
|
|
103
|
+
const fits = !strict || currentCol + w <= endCol;
|
|
104
|
+
if (inRange && fits) {
|
|
105
|
+
if (pendingAnsi) {
|
|
106
|
+
result += pendingAnsi;
|
|
107
|
+
pendingAnsi = "";
|
|
108
|
+
}
|
|
109
|
+
result += segment;
|
|
110
|
+
}
|
|
111
|
+
currentCol += w;
|
|
112
|
+
if (currentCol >= endCol) break;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
i = textEnd;
|
|
116
|
+
if (currentCol >= endCol) break;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
|
|
51
122
|
function todBucketForHour(hour: number): TodKey {
|
|
52
123
|
for (const b of TOD_BUCKETS) {
|
|
53
124
|
if (hour >= b.from && hour <= b.to) return b.key;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codersbrew/pi-tools",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "A pi package bundling CodersBrew pi extensions.",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "A pi package bundling CodersBrew pi extensions and skills.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"pi-package",
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
},
|
|
23
23
|
"files": [
|
|
24
24
|
"extensions",
|
|
25
|
+
"skills",
|
|
25
26
|
"README.md",
|
|
26
27
|
"LICENSE"
|
|
27
28
|
],
|
|
@@ -29,9 +30,10 @@
|
|
|
29
30
|
"node": ">=20.6.0"
|
|
30
31
|
},
|
|
31
32
|
"scripts": {
|
|
33
|
+
"test": "node --test test/*.test.mjs",
|
|
32
34
|
"typecheck": "tsc --noEmit",
|
|
33
35
|
"pack:check": "npm pack --dry-run",
|
|
34
|
-
"check": "npm run typecheck && npm run pack:check"
|
|
36
|
+
"check": "npm run test && npm run typecheck && npm run pack:check"
|
|
35
37
|
},
|
|
36
38
|
"publishConfig": {
|
|
37
39
|
"access": "public"
|
|
@@ -49,6 +51,9 @@
|
|
|
49
51
|
"pi": {
|
|
50
52
|
"extensions": [
|
|
51
53
|
"./extensions"
|
|
54
|
+
],
|
|
55
|
+
"skills": [
|
|
56
|
+
"./skills"
|
|
52
57
|
]
|
|
53
58
|
}
|
|
54
59
|
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: github-workflow
|
|
3
|
+
description: Use when working in a git repository hosted on GitHub and handling branch creation, commits, pushes, pull requests, reviews, or merges with gh CLI available.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# GitHub Workflow
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Use a hybrid workflow: prefer `gh` for GitHub-aware tasks, and use `git` for local history editing, staging, and branch mechanics.
|
|
11
|
+
|
|
12
|
+
**Opinionated defaults:**
|
|
13
|
+
- inspect repo state before making changes
|
|
14
|
+
- keep branches focused and short-lived
|
|
15
|
+
- use conventional-commit-style messages when possible
|
|
16
|
+
- open PRs with clear titles and summaries
|
|
17
|
+
- merge with explicit intent, not guesswork
|
|
18
|
+
|
|
19
|
+
## Quick Start Checks
|
|
20
|
+
|
|
21
|
+
Run these before branching or opening a PR:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
gh auth status
|
|
25
|
+
git remote -v
|
|
26
|
+
gh repo view --json nameWithOwner,defaultBranchRef
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Confirm:
|
|
30
|
+
- `gh` is authenticated
|
|
31
|
+
- the repo remote points to the expected GitHub repository
|
|
32
|
+
- you know the default branch, usually `main` or `master`
|
|
33
|
+
|
|
34
|
+
If `gh repo view` fails because the current repo is not connected to GitHub, fall back to plain `git` and ask before attempting GitHub-specific actions.
|
|
35
|
+
|
|
36
|
+
## Tool Choice Rules
|
|
37
|
+
|
|
38
|
+
| Use `gh` for | Use `git` for |
|
|
39
|
+
|---|---|
|
|
40
|
+
| auth and repo checks | staging files |
|
|
41
|
+
| PR create/view/checkout/review/merge | commit creation/amend/rebase |
|
|
42
|
+
| PR status and checks | switching branches |
|
|
43
|
+
| opening web pages for repo or PR context | inspecting local diffs and history |
|
|
44
|
+
|
|
45
|
+
**Fallback rule:** if `gh` has a clean command for the task, prefer it. If the task is fundamentally local source control, use `git`.
|
|
46
|
+
|
|
47
|
+
## Branch Workflow
|
|
48
|
+
|
|
49
|
+
1. Sync and inspect the default branch.
|
|
50
|
+
2. Create a focused branch from the default branch.
|
|
51
|
+
3. Keep the branch name descriptive.
|
|
52
|
+
|
|
53
|
+
Example:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
git switch main
|
|
57
|
+
git pull --ff-only
|
|
58
|
+
git switch -c feat/add-github-workflow-skill
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Recommended prefixes:
|
|
62
|
+
- `feat/`
|
|
63
|
+
- `fix/`
|
|
64
|
+
- `docs/`
|
|
65
|
+
- `chore/`
|
|
66
|
+
- `refactor/`
|
|
67
|
+
- `test/`
|
|
68
|
+
|
|
69
|
+
Avoid vague names like `updates`, `stuff`, or `misc-fixes`.
|
|
70
|
+
|
|
71
|
+
## Commit Workflow
|
|
72
|
+
|
|
73
|
+
Use `git` for staging and committing. Keep commits small and readable.
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
git status
|
|
77
|
+
git add <paths>
|
|
78
|
+
git commit -m "feat: add github workflow skill"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Prefer conventional-commit-style summaries:
|
|
82
|
+
- `feat: add github workflow skill`
|
|
83
|
+
- `fix: correct PR base branch detection`
|
|
84
|
+
- `docs: document packaged skills`
|
|
85
|
+
- `chore: clean up release notes`
|
|
86
|
+
|
|
87
|
+
Before pushing, review what changed:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
git diff --staged
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
If a commit needs cleanup, use `git commit --amend` or interactive rebase deliberately. Do not use `gh` for local history surgery.
|
|
94
|
+
|
|
95
|
+
## Push and PR Workflow
|
|
96
|
+
|
|
97
|
+
Push with `git`, then use `gh` to work with the PR.
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
git push -u origin HEAD
|
|
101
|
+
gh pr create --fill --base main
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Useful `gh` commands:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
gh pr status
|
|
108
|
+
gh pr view --web
|
|
109
|
+
gh pr checks
|
|
110
|
+
gh pr create --fill --base <default-branch>
|
|
111
|
+
gh pr checkout <number>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
PR hygiene:
|
|
115
|
+
- make sure the base branch is correct
|
|
116
|
+
- use a title that matches the change
|
|
117
|
+
- include a short summary of what changed and any risk areas
|
|
118
|
+
- mention tests run when relevant
|
|
119
|
+
|
|
120
|
+
If `--fill` produces a weak title/body, replace it instead of accepting low-quality PR text.
|
|
121
|
+
|
|
122
|
+
## Review Workflow
|
|
123
|
+
|
|
124
|
+
Use `gh` to inspect and respond to review state.
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
gh pr view <number>
|
|
128
|
+
gh pr diff <number>
|
|
129
|
+
gh pr checks <number>
|
|
130
|
+
gh pr review <number> --comment -b "Looks good overall; left one suggestion."
|
|
131
|
+
gh pr review <number> --approve
|
|
132
|
+
gh pr review <number> --request-changes -b "Please address the failing tests and rename the branch."
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
When reviewing your own work, check:
|
|
136
|
+
- PR targets the correct base branch
|
|
137
|
+
- branch is up to date enough for the repo's workflow
|
|
138
|
+
- checks are green or known failures are explained
|
|
139
|
+
- description matches the actual diff
|
|
140
|
+
|
|
141
|
+
## Merge Workflow
|
|
142
|
+
|
|
143
|
+
Prefer `gh pr merge` so the merge action is tied to GitHub PR state.
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
gh pr merge <number> --squash --delete-branch
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Common variants:
|
|
150
|
+
- `--squash` for small or iterative branches
|
|
151
|
+
- `--merge` when the repo prefers merge commits
|
|
152
|
+
- `--rebase` when the repo explicitly prefers rebased history
|
|
153
|
+
|
|
154
|
+
Before merging, confirm:
|
|
155
|
+
- approvals or review requirements are satisfied
|
|
156
|
+
- required checks passed
|
|
157
|
+
- the chosen merge strategy matches repo norms
|
|
158
|
+
|
|
159
|
+
After merge, sync local state:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
git switch main
|
|
163
|
+
git pull --ff-only
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Common Mistakes
|
|
167
|
+
|
|
168
|
+
- using `gh` for tasks that are really local `git` operations
|
|
169
|
+
- forgetting to verify the default branch before creating the PR
|
|
170
|
+
- pushing a branch without `-u` and then losing the upstream link
|
|
171
|
+
- opening a PR with an unhelpful auto-filled title/body
|
|
172
|
+
- merging without checking CI or review status
|
|
173
|
+
- mixing unrelated changes into one branch or one commit
|
|
174
|
+
|
|
175
|
+
## Red Flags
|
|
176
|
+
|
|
177
|
+
Stop and re-check before acting if you see any of these:
|
|
178
|
+
- `gh auth status` is not healthy
|
|
179
|
+
- the remote is not the repo you expected
|
|
180
|
+
- you do not know the correct base branch
|
|
181
|
+
- the branch name does not describe the change
|
|
182
|
+
- the PR title says one thing but the diff shows another
|
|
183
|
+
- checks are failing and no reason is documented
|
|
184
|
+
|
|
185
|
+
When unsure, inspect first, then act.
|