jfl 0.9.1 → 0.9.3
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/dist/commands/context-hub.d.ts.map +1 -1
- package/dist/commands/context-hub.js +141 -3
- package/dist/commands/context-hub.js.map +1 -1
- package/dist/commands/ide.d.ts.map +1 -1
- package/dist/commands/ide.js +22 -0
- package/dist/commands/ide.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +6 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/linear.d.ts.map +1 -1
- package/dist/commands/linear.js +24 -0
- package/dist/commands/linear.js.map +1 -1
- package/dist/commands/peter.d.ts.map +1 -1
- package/dist/commands/peter.js +11 -15
- package/dist/commands/peter.js.map +1 -1
- package/dist/commands/pi.d.ts +3 -0
- package/dist/commands/pi.d.ts.map +1 -1
- package/dist/commands/pi.js +19 -0
- package/dist/commands/pi.js.map +1 -1
- package/dist/commands/pivot.d.ts.map +1 -1
- package/dist/commands/pivot.js +22 -25
- package/dist/commands/pivot.js.map +1 -1
- package/dist/commands/repair.d.ts.map +1 -1
- package/dist/commands/repair.js +26 -0
- package/dist/commands/repair.js.map +1 -1
- package/dist/commands/session.d.ts.map +1 -1
- package/dist/commands/session.js +39 -0
- package/dist/commands/session.js.map +1 -1
- package/dist/commands/start.d.ts.map +1 -1
- package/dist/commands/start.js +60 -0
- package/dist/commands/start.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +3 -1
- package/dist/commands/update.js.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/advanced-setup.js +7 -7
- package/dist/lib/advanced-setup.js.map +1 -1
- package/dist/lib/agent-session.d.ts.map +1 -1
- package/dist/lib/agent-session.js +6 -3
- package/dist/lib/agent-session.js.map +1 -1
- package/dist/lib/discovery-agent.js +1 -1
- package/dist/lib/discovery-agent.js.map +1 -1
- package/dist/lib/gtm-generator.js +7 -0
- package/dist/lib/gtm-generator.js.map +1 -1
- package/dist/lib/linear-webhook.d.ts +50 -0
- package/dist/lib/linear-webhook.d.ts.map +1 -0
- package/dist/lib/linear-webhook.js +92 -0
- package/dist/lib/linear-webhook.js.map +1 -0
- package/dist/lib/memory-db.d.ts +8 -0
- package/dist/lib/memory-db.d.ts.map +1 -1
- package/dist/lib/memory-db.js +24 -0
- package/dist/lib/memory-db.js.map +1 -1
- package/dist/lib/memory-indexer.d.ts +8 -0
- package/dist/lib/memory-indexer.d.ts.map +1 -1
- package/dist/lib/memory-indexer.js +30 -1
- package/dist/lib/memory-indexer.js.map +1 -1
- package/dist/lib/memory-search.d.ts.map +1 -1
- package/dist/lib/memory-search.js +2 -7
- package/dist/lib/memory-search.js.map +1 -1
- package/dist/lib/onboarding.js +1 -1
- package/dist/lib/onboarding.js.map +1 -1
- package/dist/lib/rl-manager.d.ts +1 -1
- package/dist/lib/rl-manager.d.ts.map +1 -1
- package/dist/lib/rl-manager.js +3 -3
- package/dist/lib/rl-manager.js.map +1 -1
- package/dist/lib/service-detector.js +2 -2
- package/dist/lib/service-detector.js.map +1 -1
- package/dist/lib/telemetry/physical-world-collector.js +1 -1
- package/dist/lib/telemetry/physical-world-collector.js.map +1 -1
- package/dist/lib/tool-schemas.d.ts +35 -0
- package/dist/lib/tool-schemas.d.ts.map +1 -0
- package/dist/lib/tool-schemas.js +246 -0
- package/dist/lib/tool-schemas.js.map +1 -0
- package/dist/lib/workspace/data-pipeline.d.ts.map +1 -1
- package/dist/lib/workspace/data-pipeline.js +29 -20
- package/dist/lib/workspace/data-pipeline.js.map +1 -1
- package/dist/lib/workspace/engine.d.ts +1 -0
- package/dist/lib/workspace/engine.d.ts.map +1 -1
- package/dist/lib/workspace/engine.js +10 -0
- package/dist/lib/workspace/engine.js.map +1 -1
- package/dist/mcp/context-hub-mcp.js +7 -1
- package/dist/mcp/context-hub-mcp.js.map +1 -1
- package/dist/types/telemetry.d.ts +1 -0
- package/dist/types/telemetry.d.ts.map +1 -1
- package/dist/utils/git.d.ts +1 -1
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js +9 -6
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/provenance.d.ts +65 -0
- package/dist/utils/provenance.d.ts.map +1 -0
- package/dist/utils/provenance.js +213 -0
- package/dist/utils/provenance.js.map +1 -0
- package/package.json +1 -1
- package/packages/pi/assets/boot.mp3 +0 -0
- package/packages/pi/extensions/autoresearch.ts +3 -2
- package/packages/pi/extensions/context.ts +38 -114
- package/packages/pi/extensions/eval.ts +2 -1
- package/packages/pi/extensions/header.ts +171 -0
- package/packages/pi/extensions/hub-tools.ts +31 -11
- package/packages/pi/extensions/hud-tool.ts +231 -70
- package/packages/pi/extensions/index.ts +65 -64
- package/packages/pi/extensions/jfl-resolve.ts +98 -0
- package/packages/pi/extensions/journal.ts +91 -6
- package/packages/pi/extensions/map-bridge.ts +31 -0
- package/packages/pi/extensions/memory-tool.ts +3 -3
- package/packages/pi/extensions/onboarding-v2.ts +263 -410
- package/packages/pi/extensions/onboarding-v3.ts +32 -21
- package/packages/pi/extensions/peter-parker.ts +2 -1
- package/packages/pi/extensions/policy-head-tool.ts +3 -2
- package/packages/pi/extensions/portfolio-bridge.ts +3 -4
- package/packages/pi/extensions/service-skills.ts +6 -1
- package/packages/pi/extensions/session.ts +97 -15
- package/packages/pi/extensions/startup-briefing.ts +313 -0
- package/packages/pi/extensions/stratus-bridge.ts +2 -1
- package/packages/pi/extensions/subway-mesh.ts +893 -0
- package/packages/pi/extensions/synopsis-tool.ts +6 -1
- package/packages/pi/extensions/training-buffer-tool.ts +3 -2
- package/packages/pi/extensions/types.ts +3 -0
- package/packages/pi/package.json +4 -1
- package/packages/pi/skills/viz/SKILL.md +204 -0
- package/scripts/pp-branch-pr.sh +24 -6
- package/scripts/pp-branch-pr.sh.bak +115 -0
- package/template/.pi/settings.json +5 -0
- package/template/CLAUDE.md +82 -1738
- package/template/CLAUDE.md.bak +0 -1187
|
@@ -48,7 +48,12 @@ export function setupSynopsisTool(ctx: PiContext): void {
|
|
|
48
48
|
},
|
|
49
49
|
},
|
|
50
50
|
async handler(input) {
|
|
51
|
-
const
|
|
51
|
+
const raw = input as { hours?: number | string; author?: string }
|
|
52
|
+
// Model sometimes passes "24h" or "48h" — strip the 'h' and parse
|
|
53
|
+
const hours = typeof raw.hours === "string"
|
|
54
|
+
? parseInt(String(raw.hours).replace(/[^0-9]/g, ""), 10) || 24
|
|
55
|
+
: raw.hours
|
|
56
|
+
const author = raw.author
|
|
52
57
|
|
|
53
58
|
const synopsisScript = findSynopsisScript(projectRoot)
|
|
54
59
|
if (synopsisScript) {
|
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
import { existsSync, readFileSync } from "fs"
|
|
15
15
|
import { join } from "path"
|
|
16
16
|
import type { PiContext, JflConfig, AgentEndEvent } from "./types.js"
|
|
17
|
+
import { jflImport } from "./jfl-resolve.js"
|
|
17
18
|
import { emitCustomEvent } from "./map-bridge.js"
|
|
18
19
|
|
|
19
20
|
let projectRoot = ""
|
|
@@ -21,7 +22,7 @@ let projectRoot = ""
|
|
|
21
22
|
async function getTrainingBuffer(): Promise<any> {
|
|
22
23
|
try {
|
|
23
24
|
// @ts-ignore — resolved from jfl package at runtime
|
|
24
|
-
const { TrainingBuffer } = await
|
|
25
|
+
const { TrainingBuffer } = await jflImport("training-buffer")
|
|
25
26
|
return new TrainingBuffer(projectRoot)
|
|
26
27
|
} catch {
|
|
27
28
|
return null
|
|
@@ -31,7 +32,7 @@ async function getTrainingBuffer(): Promise<any> {
|
|
|
31
32
|
async function getTupleMiner(): Promise<any> {
|
|
32
33
|
try {
|
|
33
34
|
// @ts-ignore — resolved from jfl package at runtime
|
|
34
|
-
return await
|
|
35
|
+
return await jflImport("tuple-miner")
|
|
35
36
|
} catch {
|
|
36
37
|
return null
|
|
37
38
|
}
|
|
@@ -74,6 +74,7 @@ export interface PiContext {
|
|
|
74
74
|
setWidget(id: string, content: string[] | WidgetFactory | undefined, opts?: { placement?: "aboveEditor" | "belowEditor" }): void
|
|
75
75
|
setStatus(key: string, text: string | undefined): void
|
|
76
76
|
setFooter(factory: ((tui: any, theme: PiTheme, footerData: any) => any) | undefined): void
|
|
77
|
+
setHeader?(factory: ((tui: any, theme: PiTheme) => { render: (width: number) => string[]; invalidate: () => void }) | undefined): void
|
|
77
78
|
setEditorText(text: string): void
|
|
78
79
|
theme: PiTheme
|
|
79
80
|
hasUI: boolean
|
|
@@ -115,6 +116,8 @@ export interface AgentEndEvent {
|
|
|
115
116
|
export interface ToolExecutionEvent {
|
|
116
117
|
toolName?: string
|
|
117
118
|
tool?: string
|
|
119
|
+
input?: Record<string, any>
|
|
120
|
+
args?: Record<string, any>
|
|
118
121
|
result?: unknown
|
|
119
122
|
isError?: boolean
|
|
120
123
|
duration?: number
|
package/packages/pi/package.json
CHANGED
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"axios": "^1.13.4",
|
|
32
|
+
"ws": "^8.19.0",
|
|
32
33
|
"yaml": "^2.8.2"
|
|
33
34
|
},
|
|
34
35
|
"devDependencies": {
|
|
@@ -36,7 +37,9 @@
|
|
|
36
37
|
"typescript": "^5.3.3"
|
|
37
38
|
},
|
|
38
39
|
"pi": {
|
|
39
|
-
|
|
40
|
+
|
|
41
|
+
"entry": "dist/index.js",
|
|
42
|
+
"extensions": ["dist/index.js"],
|
|
40
43
|
"skills": "skills",
|
|
41
44
|
"themes": "themes/jfl.theme.json",
|
|
42
45
|
"teams": "teams"
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: viz
|
|
3
|
+
description: Terminal data visualization via kuva — inline plots for agents and humans
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /viz — Terminal Visualization
|
|
7
|
+
|
|
8
|
+
Pipe JFL data to kuva for inline terminal plots. Agents see results without leaving flow.
|
|
9
|
+
|
|
10
|
+
## Prerequisites
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
cargo install kuva --features cli
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
If kuva is not installed, falls back to ASCII bar/sparkline rendering.
|
|
17
|
+
|
|
18
|
+
## Commands
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
/viz events # Event bus activity (bar chart by type, sankey of service flows)
|
|
22
|
+
/viz sessions # Session activity (line chart over time, duration box plot)
|
|
23
|
+
/viz costs # API costs (bar by model, pie by provider)
|
|
24
|
+
/viz tools # Tool usage frequency (bar chart)
|
|
25
|
+
/viz flows # Flow trigger rates (bar chart, sankey of trigger→action)
|
|
26
|
+
/viz arena # Arena leaderboard (composite bar chart, score trajectory)
|
|
27
|
+
/viz learning # Pattern confidence trends (line chart)
|
|
28
|
+
/viz health # Service health dashboard (cost sparklines, error bars, latency box)
|
|
29
|
+
/viz <custom> # Describe what you want to visualize
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## How It Works
|
|
33
|
+
|
|
34
|
+
Each `/viz` command:
|
|
35
|
+
1. Reads the relevant data source (events, journals, telemetry, arena results)
|
|
36
|
+
2. Transforms to TSV format
|
|
37
|
+
3. Pipes to `kuva [plot-type] --terminal`
|
|
38
|
+
4. Renders inline in the terminal
|
|
39
|
+
|
|
40
|
+
## Implementation
|
|
41
|
+
|
|
42
|
+
### /viz events
|
|
43
|
+
|
|
44
|
+
Read `.jfl/service-events.jsonl` and `.jfl/map-events.jsonl`:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# Event type distribution
|
|
48
|
+
cat .jfl/service-events.jsonl | \
|
|
49
|
+
jq -r '.type' | sort | uniq -c | sort -rn | \
|
|
50
|
+
awk '{print $2"\t"$1}' | \
|
|
51
|
+
kuva bar --label-col 0 --value-col 1 --title "Events by Type" --terminal
|
|
52
|
+
|
|
53
|
+
# Service-to-service flow (sankey)
|
|
54
|
+
cat .jfl/service-events.jsonl | \
|
|
55
|
+
jq -r '[.source // "unknown", .type, 1] | @tsv' | \
|
|
56
|
+
kuva sankey --source-col 0 --target-col 1 --value-col 2 --title "Event Flows" --terminal
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Or use the programmatic API from `jfl-cli/src/lib/kuva.ts`:
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
import { barChart, linePlot, sparkline } from 'jfl-cli/src/lib/kuva.js'
|
|
63
|
+
|
|
64
|
+
const events = loadEvents()
|
|
65
|
+
const byType = countBy(events, 'type')
|
|
66
|
+
const chart = barChart(
|
|
67
|
+
Object.entries(byType).map(([label, value]) => ({ label, value })),
|
|
68
|
+
'Events by Type'
|
|
69
|
+
)
|
|
70
|
+
console.log(chart)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### /viz sessions
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Sessions over time (line)
|
|
77
|
+
cat .jfl/journal/*.jsonl | \
|
|
78
|
+
jq -r 'select(.type == "session-end") | [.ts[:10], 1] | @tsv' | \
|
|
79
|
+
sort | uniq -c | awk '{print $2"\t"$1}' | \
|
|
80
|
+
kuva line --x 0 --y 1 --title "Sessions per Day" --terminal
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### /viz costs
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
# Cost by model (bar)
|
|
87
|
+
cat .jfl/telemetry-queue.jsonl | \
|
|
88
|
+
jq -r 'select(.event == "stratus:api_call") | [(.model_name // "unknown"), .estimated_cost_usd] | @tsv' | \
|
|
89
|
+
kuva bar --label-col 0 --value-col 1 --title "Cost by Model" --terminal
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### /viz arena
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
# Run from arena directory
|
|
96
|
+
cd /path/to/productrank-arena
|
|
97
|
+
npm run arena -- leaderboard --all --plots
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Or programmatically — arena's `formatLeaderboardPlots()` renders composite scores as kuva bar chart.
|
|
101
|
+
|
|
102
|
+
### /viz flows
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# Flow triggers (bar)
|
|
106
|
+
cat .jfl/service-events.jsonl | \
|
|
107
|
+
jq -r 'select(.type == "flow:triggered") | .data.flow_name' | \
|
|
108
|
+
sort | uniq -c | sort -rn | awk '{print $2"\t"$1}' | \
|
|
109
|
+
kuva bar --label-col 0 --value-col 1 --title "Flow Triggers" --terminal
|
|
110
|
+
|
|
111
|
+
# Flow trigger→action sankey
|
|
112
|
+
cat .jfl/service-events.jsonl | \
|
|
113
|
+
jq -r 'select(.type == "flow:completed") | [.data.flow_name, .data.action_type, 1] | @tsv' | \
|
|
114
|
+
kuva sankey --source-col 0 --target-col 1 --value-col 2 --title "Flow Actions" --terminal
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### /viz health
|
|
118
|
+
|
|
119
|
+
Composite dashboard — renders multiple charts:
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
Health Dashboard
|
|
123
|
+
━━━━━━━━━━━━━━━━
|
|
124
|
+
|
|
125
|
+
API Costs (last 24h)
|
|
126
|
+
[kuva bar: cost by model]
|
|
127
|
+
|
|
128
|
+
Error Rate ▁▂▁▁▃▅▂▁▁▁ (sparkline)
|
|
129
|
+
|
|
130
|
+
Latency Distribution
|
|
131
|
+
[kuva box: latency by endpoint]
|
|
132
|
+
|
|
133
|
+
Session Duration
|
|
134
|
+
[kuva box: duration by session]
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### /viz learning (RL / Training)
|
|
138
|
+
|
|
139
|
+
For agents with reinforcement learning loops:
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
// After each training epoch
|
|
143
|
+
const rewards = epochs.map((e, i) => ({ ts: `epoch-${i}`, value: e.reward }))
|
|
144
|
+
const chart = linePlot(rewards, 'Reward per Epoch')
|
|
145
|
+
console.log(chart)
|
|
146
|
+
|
|
147
|
+
// Action distribution
|
|
148
|
+
const actions = countBy(episodes, 'action')
|
|
149
|
+
const actionChart = barChart(
|
|
150
|
+
Object.entries(actions).map(([label, value]) => ({ label, value })),
|
|
151
|
+
'Action Frequency'
|
|
152
|
+
)
|
|
153
|
+
console.log(actionChart)
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### /viz custom
|
|
157
|
+
|
|
158
|
+
When user describes what they want to visualize, the agent:
|
|
159
|
+
1. Identifies the data source
|
|
160
|
+
2. Extracts/transforms to TSV
|
|
161
|
+
3. Picks the right kuva plot type
|
|
162
|
+
4. Renders with `--terminal`
|
|
163
|
+
|
|
164
|
+
## Available Plot Types
|
|
165
|
+
|
|
166
|
+
| kuva command | Best for | Key flags |
|
|
167
|
+
|-------------|----------|-----------|
|
|
168
|
+
| `bar` | Categorical comparisons | `--label-col`, `--value-col` |
|
|
169
|
+
| `line` | Time series, trends | `--x`, `--y`, `--color-by` |
|
|
170
|
+
| `scatter` | Correlations, clustering | `--x`, `--y`, `--color-by` |
|
|
171
|
+
| `box` | Distributions, outliers | `--group-col`, `--value-col` |
|
|
172
|
+
| `histogram` | Value distributions | `--value-col`, `--bins` |
|
|
173
|
+
| `pie` | Proportions | `--label-col`, `--value-col`, `--donut` |
|
|
174
|
+
| `sankey` | Flow routing, transitions | `--source-col`, `--target-col`, `--value-col` |
|
|
175
|
+
| `heatmap` | Matrix data, correlations | First col = row labels |
|
|
176
|
+
| `violin` | Distribution shape | `--group-col`, `--value-col` |
|
|
177
|
+
|
|
178
|
+
## Design Principles
|
|
179
|
+
|
|
180
|
+
1. **TSV is the universal interface** — any data source that can produce rows can generate kuva plots
|
|
181
|
+
2. **Graceful degradation** — ASCII fallback (bars, sparklines) when kuva isn't installed
|
|
182
|
+
3. **Agent-native** — inline terminal output, no browser needed, no context-switching
|
|
183
|
+
4. **Composable** — pipe any JSONL through `jq -r @tsv` into kuva. Unix philosophy.
|
|
184
|
+
5. **Zero coupling** — kuva is a standalone Rust binary. kuva.ts is a standalone module. Neither needs the other's internals.
|
|
185
|
+
|
|
186
|
+
## Examples
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
User: "show me event activity"
|
|
190
|
+
Agent: *runs /viz events*
|
|
191
|
+
→ Bar chart of event types + sankey of service flows
|
|
192
|
+
|
|
193
|
+
User: "what's our cost breakdown?"
|
|
194
|
+
Agent: *runs /viz costs*
|
|
195
|
+
→ Bar chart by model + pie chart by provider
|
|
196
|
+
|
|
197
|
+
User: "how is the arena looking?"
|
|
198
|
+
Agent: *runs /viz arena*
|
|
199
|
+
→ Leaderboard table + composite score bar chart
|
|
200
|
+
|
|
201
|
+
User: "plot my training rewards"
|
|
202
|
+
Agent: *runs /viz learning with user's data*
|
|
203
|
+
→ Line chart of reward per epoch + action frequency bars
|
|
204
|
+
```
|
package/scripts/pp-branch-pr.sh
CHANGED
|
@@ -43,15 +43,33 @@ if git diff --quiet HEAD && [ -z "$(git ls-files --others --exclude-standard)" ]
|
|
|
43
43
|
exit 0
|
|
44
44
|
fi
|
|
45
45
|
|
|
46
|
-
# 4. Commit
|
|
46
|
+
# 4. Commit with provenance signing
|
|
47
47
|
git add -A
|
|
48
|
-
COMMIT_MSG="fix(pp): ${TASK}
|
|
49
48
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
AGENT_ID="peter-parker"
|
|
50
|
+
AGENT_SESSION="${BRANCH_NAME}"
|
|
51
|
+
AGENT_TIMESTAMP="$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
|
|
52
|
+
|
|
53
|
+
# Compute provenance hash from staged diff + agent identity
|
|
54
|
+
PROVENANCE_KEY_PATH=".jfl/provenance-key"
|
|
55
|
+
if [ ! -f "${PROVENANCE_KEY_PATH}" ]; then
|
|
56
|
+
mkdir -p .jfl
|
|
57
|
+
openssl rand -hex 32 > "${PROVENANCE_KEY_PATH}"
|
|
58
|
+
chmod 600 "${PROVENANCE_KEY_PATH}"
|
|
59
|
+
fi
|
|
60
|
+
PROVENANCE_KEY=$(cat "${PROVENANCE_KEY_PATH}")
|
|
61
|
+
STAGED_DIFF=$(git diff --cached)
|
|
62
|
+
PROVENANCE_PAYLOAD="${AGENT_ID}
|
|
63
|
+
${AGENT_TIMESTAMP}
|
|
64
|
+
${STAGED_DIFF}"
|
|
65
|
+
PROVENANCE_HASH="sha256:$(printf '%s' "${PROVENANCE_PAYLOAD}" | openssl dgst -sha256 -hmac "${PROVENANCE_KEY}" | awk '{print $NF}')"
|
|
66
|
+
|
|
67
|
+
COMMIT_MSG="fix(pp): ${TASK}
|
|
53
68
|
|
|
54
|
-
|
|
69
|
+
Agent-Id: ${AGENT_ID}
|
|
70
|
+
Agent-Session: ${AGENT_SESSION}
|
|
71
|
+
Provenance-Hash: ${PROVENANCE_HASH}
|
|
72
|
+
Agent-Timestamp: ${AGENT_TIMESTAMP}"
|
|
55
73
|
|
|
56
74
|
git commit -m "${COMMIT_MSG}"
|
|
57
75
|
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# scripts/pp-branch-pr.sh
|
|
3
|
+
#
|
|
4
|
+
# Wraps Peter Parker agent execution in git branch + PR workflow.
|
|
5
|
+
# Creates a branch, runs the agent, commits changes, opens a PR,
|
|
6
|
+
# and posts a pr:created event to the hub.
|
|
7
|
+
#
|
|
8
|
+
# Called by flow engine spawn action or directly.
|
|
9
|
+
#
|
|
10
|
+
# Usage: pp-branch-pr.sh <task-description> [hub-url] [hub-token]
|
|
11
|
+
|
|
12
|
+
set -euo pipefail
|
|
13
|
+
|
|
14
|
+
TASK="${1:?Usage: pp-branch-pr.sh <task-description> [hub-url] [hub-token]}"
|
|
15
|
+
HUB_URL="${2:-}"
|
|
16
|
+
HUB_TOKEN="${3:-}"
|
|
17
|
+
BRANCH_NAME="pp/fix-$(date +%s)"
|
|
18
|
+
BASE_BRANCH="main"
|
|
19
|
+
|
|
20
|
+
if [ -z "$HUB_URL" ] && [ -f ".jfl/context-hub.port" ]; then
|
|
21
|
+
PORT=$(cat .jfl/context-hub.port)
|
|
22
|
+
HUB_URL="http://localhost:${PORT}"
|
|
23
|
+
fi
|
|
24
|
+
if [ -z "$HUB_TOKEN" ] && [ -f ".jfl/context-hub.token" ]; then
|
|
25
|
+
HUB_TOKEN=$(cat .jfl/context-hub.token)
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
echo "PP: Creating branch ${BRANCH_NAME}"
|
|
29
|
+
|
|
30
|
+
# 1. Create branch from clean main
|
|
31
|
+
git fetch origin "${BASE_BRANCH}" 2>/dev/null || true
|
|
32
|
+
git checkout -b "${BRANCH_NAME}" "origin/${BASE_BRANCH}" 2>/dev/null || git checkout -b "${BRANCH_NAME}" "${BASE_BRANCH}"
|
|
33
|
+
|
|
34
|
+
# 2. Run Peter Parker
|
|
35
|
+
echo "PP: Running agent on task: ${TASK}"
|
|
36
|
+
jfl peter run --task "${TASK}"
|
|
37
|
+
|
|
38
|
+
# 3. Check if anything changed
|
|
39
|
+
if git diff --quiet HEAD && [ -z "$(git ls-files --others --exclude-standard)" ]; then
|
|
40
|
+
echo "PP: No changes made, cleaning up"
|
|
41
|
+
git checkout "${BASE_BRANCH}" 2>/dev/null || true
|
|
42
|
+
git branch -D "${BRANCH_NAME}" 2>/dev/null || true
|
|
43
|
+
exit 0
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
# 4. Commit
|
|
47
|
+
git add -A
|
|
48
|
+
COMMIT_MSG="fix(pp): ${TASK}
|
|
49
|
+
|
|
50
|
+
Agent: peter-parker
|
|
51
|
+
Branch: ${BRANCH_NAME}
|
|
52
|
+
Auto-generated by JFL self-driving loop
|
|
53
|
+
|
|
54
|
+
Co-authored-by: Peter Parker <pp@jfl.dev>"
|
|
55
|
+
|
|
56
|
+
git commit -m "${COMMIT_MSG}"
|
|
57
|
+
|
|
58
|
+
# 5. Push
|
|
59
|
+
git push -u origin "${BRANCH_NAME}"
|
|
60
|
+
|
|
61
|
+
# 6. Create PR
|
|
62
|
+
PR_TITLE="PP: $(echo "${TASK}" | head -c 60)"
|
|
63
|
+
PR_BODY="## Auto-generated by Peter Parker
|
|
64
|
+
|
|
65
|
+
**Task:** ${TASK}
|
|
66
|
+
**Branch:** \`${BRANCH_NAME}\`
|
|
67
|
+
|
|
68
|
+
### Eval Suite
|
|
69
|
+
This PR will be evaluated by the CI eval suite.
|
|
70
|
+
Auto-merge will trigger if eval score improves over baseline.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
*Generated by JFL self-driving loop*"
|
|
74
|
+
|
|
75
|
+
PR_URL=$(gh pr create \
|
|
76
|
+
--title "${PR_TITLE}" \
|
|
77
|
+
--body "${PR_BODY}" \
|
|
78
|
+
--base "${BASE_BRANCH}" \
|
|
79
|
+
--head "${BRANCH_NAME}" \
|
|
80
|
+
--label "pp-generated" 2>&1) || {
|
|
81
|
+
echo "PP: Label may not exist, retrying without label"
|
|
82
|
+
PR_URL=$(gh pr create \
|
|
83
|
+
--title "${PR_TITLE}" \
|
|
84
|
+
--body "${PR_BODY}" \
|
|
85
|
+
--base "${BASE_BRANCH}" \
|
|
86
|
+
--head "${BRANCH_NAME}" 2>&1)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
echo "PP: PR created at ${PR_URL}"
|
|
90
|
+
|
|
91
|
+
# 7. Post event to hub
|
|
92
|
+
if [ -n "${HUB_URL}" ]; then
|
|
93
|
+
TASK_JSON=$(printf '%s' "${TASK}" | python3 -c 'import sys,json; print(json.dumps(sys.stdin.read().strip()))')
|
|
94
|
+
|
|
95
|
+
CURL_ARGS=(-s -X POST "${HUB_URL}/api/events" -H "Content-Type: application/json")
|
|
96
|
+
if [ -n "${HUB_TOKEN}" ]; then
|
|
97
|
+
CURL_ARGS+=(-H "Authorization: Bearer ${HUB_TOKEN}")
|
|
98
|
+
fi
|
|
99
|
+
CURL_ARGS+=(-d "{
|
|
100
|
+
\"type\": \"pr:created\",
|
|
101
|
+
\"source\": \"peter-parker\",
|
|
102
|
+
\"data\": {
|
|
103
|
+
\"task\": ${TASK_JSON},
|
|
104
|
+
\"pr_url\": \"${PR_URL}\",
|
|
105
|
+
\"branch\": \"${BRANCH_NAME}\"
|
|
106
|
+
}
|
|
107
|
+
}")
|
|
108
|
+
|
|
109
|
+
curl "${CURL_ARGS[@]}" 2>/dev/null || echo "PP: Warning - could not post event to hub"
|
|
110
|
+
fi
|
|
111
|
+
|
|
112
|
+
# 8. Return to base branch
|
|
113
|
+
git checkout "${BASE_BRANCH}" 2>/dev/null || true
|
|
114
|
+
|
|
115
|
+
echo "PP: Done"
|