ghostrail 0.15.2 → 0.16.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 +12 -9
- package/dist/agent/claude-code.d.ts.map +1 -1
- package/dist/agent/claude-code.js +4 -1
- package/dist/agent/claude-code.js.map +1 -1
- package/dist/board/page.d.ts +1 -1
- package/dist/board/page.d.ts.map +1 -1
- package/dist/board/page.js +2 -1
- package/dist/board/page.js.map +1 -1
- package/dist/board/server.d.ts +1 -1
- package/dist/board/server.d.ts.map +1 -1
- package/dist/board/server.js +7 -1
- package/dist/board/server.js.map +1 -1
- package/dist/board/stats.d.ts +1 -1
- package/dist/board/stats.d.ts.map +1 -1
- package/dist/board/stats.js +2 -1
- package/dist/board/stats.js.map +1 -1
- package/dist/claude-profile/index.d.ts +1 -1
- package/dist/claude-profile/index.d.ts.map +1 -1
- package/dist/claude-profile/index.js +1 -1
- package/dist/claude-profile/index.js.map +1 -1
- package/dist/claude-profile/setup.d.ts +7 -0
- package/dist/claude-profile/setup.d.ts.map +1 -1
- package/dist/claude-profile/setup.js +7 -0
- package/dist/claude-profile/setup.js.map +1 -1
- package/dist/cli/commands.d.ts +6 -0
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +98 -2
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +3 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/help.d.ts.map +1 -1
- package/dist/commands/help.js +11 -0
- package/dist/commands/help.js.map +1 -1
- package/dist/config/load.d.ts.map +1 -1
- package/dist/config/load.js +18 -2
- package/dist/config/load.js.map +1 -1
- package/dist/config/schema.d.ts +8 -2
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js.map +1 -1
- package/dist/dashboard/page.d.ts +7 -1
- package/dist/dashboard/page.d.ts.map +1 -1
- package/dist/dashboard/page.js +204 -39
- package/dist/dashboard/page.js.map +1 -1
- package/dist/dashboard/routes.d.ts +32 -0
- package/dist/dashboard/routes.d.ts.map +1 -1
- package/dist/dashboard/routes.js +45 -0
- package/dist/dashboard/routes.js.map +1 -1
- package/dist/dashboard/server.d.ts +35 -9
- package/dist/dashboard/server.d.ts.map +1 -1
- package/dist/dashboard/server.js +75 -11
- package/dist/dashboard/server.js.map +1 -1
- package/dist/doctor/checks.d.ts +87 -0
- package/dist/doctor/checks.d.ts.map +1 -0
- package/dist/doctor/checks.js +414 -0
- package/dist/doctor/checks.js.map +1 -0
- package/dist/doctor/index.d.ts +6 -0
- package/dist/doctor/index.d.ts.map +1 -0
- package/dist/doctor/index.js +5 -0
- package/dist/doctor/index.js.map +1 -0
- package/dist/doctor/probes.d.ts +42 -0
- package/dist/doctor/probes.d.ts.map +1 -0
- package/dist/doctor/probes.js +136 -0
- package/dist/doctor/probes.js.map +1 -0
- package/dist/doctor/report.d.ts +13 -0
- package/dist/doctor/report.d.ts.map +1 -0
- package/dist/doctor/report.js +32 -0
- package/dist/doctor/report.js.map +1 -0
- package/dist/doctor/run.d.ts +48 -0
- package/dist/doctor/run.d.ts.map +1 -0
- package/dist/doctor/run.js +109 -0
- package/dist/doctor/run.js.map +1 -0
- package/dist/doctor/types.d.ts +17 -0
- package/dist/doctor/types.d.ts.map +1 -0
- package/dist/doctor/types.js +6 -0
- package/dist/doctor/types.js.map +1 -0
- package/dist/loop/budget.d.ts +11 -2
- package/dist/loop/budget.d.ts.map +1 -1
- package/dist/loop/budget.js +13 -3
- package/dist/loop/budget.js.map +1 -1
- package/dist/loop/comments.d.ts +20 -0
- package/dist/loop/comments.d.ts.map +1 -0
- package/dist/loop/comments.js +35 -0
- package/dist/loop/comments.js.map +1 -0
- package/dist/loop/engine.d.ts.map +1 -1
- package/dist/loop/engine.js +18 -0
- package/dist/loop/engine.js.map +1 -1
- package/dist/loop/index.d.ts +1 -0
- package/dist/loop/index.d.ts.map +1 -1
- package/dist/loop/index.js +1 -0
- package/dist/loop/index.js.map +1 -1
- package/dist/source/dependencies.d.ts +81 -0
- package/dist/source/dependencies.d.ts.map +1 -0
- package/dist/source/dependencies.js +218 -0
- package/dist/source/dependencies.js.map +1 -0
- package/dist/source/index.d.ts +1 -0
- package/dist/source/index.d.ts.map +1 -1
- package/dist/source/index.js +1 -0
- package/dist/source/index.js.map +1 -1
- package/dist/source/linear.d.ts +17 -1
- package/dist/source/linear.d.ts.map +1 -1
- package/dist/source/linear.js +75 -9
- package/dist/source/linear.js.map +1 -1
- package/dist/store/events.d.ts +8 -0
- package/dist/store/events.d.ts.map +1 -1
- package/dist/store/events.js +10 -0
- package/dist/store/events.js.map +1 -1
- package/dist/store/file-store.d.ts +1 -1
- package/dist/store/file-store.d.ts.map +1 -1
- package/dist/store/file-store.js +7 -0
- package/dist/store/file-store.js.map +1 -1
- package/dist/store/index.d.ts +1 -1
- package/dist/store/index.d.ts.map +1 -1
- package/dist/store/index.js +1 -1
- package/dist/store/index.js.map +1 -1
- package/dist/store/port.d.ts +15 -0
- package/dist/store/port.d.ts.map +1 -1
- package/dist/store/port.js +17 -1
- package/dist/store/port.js.map +1 -1
- package/dist/triage/engine.d.ts.map +1 -1
- package/dist/triage/engine.js +2 -0
- package/dist/triage/engine.js.map +1 -1
- package/package.json +3 -1
- package/skill/ghostrail/SKILL.md +15 -34
- package/templates/code/prompts/resolve-issue.md +7 -0
- package/templates/code/prompts/triage.md +7 -0
- package/templates/content/prompts/draft.md +7 -0
package/README.md
CHANGED
|
@@ -26,6 +26,11 @@ ghostrail respond # fold new human PR comments back into branch
|
|
|
26
26
|
ghostrail board # watch runs at http://127.0.0.1:5050/
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
+
`ghostrail run` does one tick and exits; `ghostrail watch --interval <dur>` and
|
|
30
|
+
`ghostrail start --interval <dur>` run ticks on a loop. For exactly what a
|
|
31
|
+
tick does end to end, and how the `[guardrails]` levers interact (including
|
|
32
|
+
combinations that quietly do nothing), see [how a tick works](docs/ticks.md).
|
|
33
|
+
|
|
29
34
|
## Configuration reference
|
|
30
35
|
|
|
31
36
|
`ghostrail.toml` is the whole factory: one file, one table per adapter seam.
|
|
@@ -117,8 +122,8 @@ working checkout instead. See [choosing a backend](docs/backends.md).
|
|
|
117
122
|
| Key | Type | Values | Default | Required |
|
|
118
123
|
| --- | --- | --- | --- | --- |
|
|
119
124
|
| `max_items_per_run` | number | > 0 | `3` | no |
|
|
120
|
-
| `budget_usd_per_item` | number | > 0 | `3` | no |
|
|
121
|
-
| `max_cost_usd_per_run` | number | > 0 | `5` | no |
|
|
125
|
+
| `budget_usd_per_item` | number or string | > 0, or `"unlimited"` | `3` | no |
|
|
126
|
+
| `max_cost_usd_per_run` | number or string | > 0, or `"unlimited"` | `5` | no |
|
|
122
127
|
| `timeout` | duration string | e.g. `"30m"` | `"30m"` | no |
|
|
123
128
|
| `claim_ttl` | duration string | e.g. `"2h"` | `"2h"` | no |
|
|
124
129
|
| `concurrency` | number | > 0 | `1` | no |
|
|
@@ -127,14 +132,12 @@ working checkout instead. See [choosing a backend](docs/backends.md).
|
|
|
127
132
|
*and* it's the cost ghostrail assumes for an item that finishes without
|
|
128
133
|
reporting any cost at all. Raising it to give one item more headroom also
|
|
129
134
|
raises what an unreported-cost item gets charged.
|
|
130
|
-
-
|
|
131
|
-
|
|
132
|
-
|
|
135
|
+
- Either budget key also accepts the string `"unlimited"` to disable its cap
|
|
136
|
+
entirely. An item that reports no cost is then charged `$0` rather than
|
|
137
|
+
`budget_usd_per_item`, and the tick logs which cap is uncapped.
|
|
133
138
|
- This table says what each key accepts. What each one bounds inside a tick,
|
|
134
|
-
and how they interact with `concurrency`, is
|
|
135
|
-
|
|
136
|
-
[TJ-1580](https://linear.app/timothyjordan/issue/TJ-1580/docs-explain-how-a-tick-works-and-how-every-guardrail-lever-changes-it));
|
|
137
|
-
until it lands, see "How it works" in [`docs/index.md`](docs/index.md).
|
|
139
|
+
and how they interact with `concurrency`, is covered in
|
|
140
|
+
[how a tick works](docs/ticks.md).
|
|
138
141
|
|
|
139
142
|
### `[output]`
|
|
140
143
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../src/agent/claude-code.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAc,MAAM,kBAAkB,CAAC;AAKtF,+EAA+E;AAC/E,eAAO,MAAM,WAAW,2BAA2B,CAAC;AAEpD,MAAM,WAAW,iBAAiB;IAChC,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,8EAA8E;IAC9E,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,aAAa,CAAC;IAC/C,sDAAsD;IACtD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oCAAoC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,EAAE,CAwBpE;AAYD;;;;;;GAMG;AACH,qBAAa,eAAgB,YAAW,KAAK;IAO/B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;IANxC;;;;;OAKG;gBAC0B,UAAU,CAAC,EAAE,MAAM,YAAA;IAE1C,GAAG,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"claude-code.d.ts","sourceRoot":"","sources":["../../src/agent/claude-code.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,YAAY,EAAc,MAAM,kBAAkB,CAAC;AAKtF,+EAA+E;AAC/E,eAAO,MAAM,WAAW,2BAA2B,CAAC;AAEpD,MAAM,WAAW,iBAAiB;IAChC,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,8EAA8E;IAC9E,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,aAAa,CAAC;IAC/C,sDAAsD;IACtD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oCAAoC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,iBAAiB,GAAG,MAAM,EAAE,CAwBpE;AAYD;;;;;;GAMG;AACH,qBAAa,eAAgB,YAAW,KAAK;IAO/B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;IANxC;;;;;OAKG;gBAC0B,UAAU,CAAC,EAAE,MAAM,YAAA;IAE1C,GAAG,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;CAuExD"}
|
|
@@ -75,7 +75,10 @@ export class ClaudeCodeAgent {
|
|
|
75
75
|
prompt: renderPrompt(template, item),
|
|
76
76
|
allowedTools: agent.allowedTools,
|
|
77
77
|
addDir: ".",
|
|
78
|
-
|
|
78
|
+
// "unlimited" means no --max-budget-usd flag at all, not a very large one.
|
|
79
|
+
...(guardrails.budgetUsdPerItem === "unlimited"
|
|
80
|
+
? {}
|
|
81
|
+
: { maxBudgetUsd: guardrails.budgetUsdPerItem }),
|
|
79
82
|
...(profileDir === undefined
|
|
80
83
|
? {}
|
|
81
84
|
: { settingsPath: join(profileDir, ".claude", "settings.json") }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/agent/claude-code.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../src/agent/claude-code.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAIjC,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACnG,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,+EAA+E;AAC/E,MAAM,CAAC,MAAM,WAAW,GAAG,wBAAwB,CAAC;AAqBpD;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,OAA0B;IACxD,MAAM,IAAI,GAAG;QACX,IAAI;QACJ,OAAO,CAAC,MAAM;QACd,iBAAiB;QACjB,OAAO,CAAC,YAAY,IAAI,MAAM;QAC9B,mBAAmB;QACnB,OAAO,CAAC,cAAc,IAAI,aAAa;QACvC,WAAW;QACX,OAAO,CAAC,MAAM;KACf,CAAC;IACF,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACvC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAChD,CAAC;IACD,IAAI,OAAO,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACvC,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;IAC9D,CAAC;IACD,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,iFAAiF;AACjF,KAAK,UAAU,QAAQ,CACrB,OAAgB,EAChB,SAAoB,EACpB,IAAY;IAEZ,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;IAC5D,OAAO,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,OAAO,eAAe;IAOG;IAN7B;;;;;OAKG;IACH,YAA6B,UAAmB;QAAnB,eAAU,GAAV,UAAU,CAAS;IAAG,CAAC;IAEpD,KAAK,CAAC,GAAG,CAAC,OAAqB;QAC7B,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;QAChE,2EAA2E;QAC3E,2EAA2E;QAC3E,uEAAuE;QACvE,wEAAwE;QACxE,0EAA0E;QAC1E,6DAA6D;QAC7D,MAAM,UAAU,GAAG,SAAS,CAAC,WAAW,IAAI,IAAI,CAAC,UAAU,CAAC;QAE5D,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAClE,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,+BAA+B,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;QACpF,CAAC;QAED,MAAM,IAAI,GAAG,eAAe,CAAC;YAC3B,MAAM,EAAE,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC;YACpC,YAAY,EAAE,KAAK,CAAC,YAAY;YAChC,MAAM,EAAE,GAAG;YACX,2EAA2E;YAC3E,GAAG,CAAC,UAAU,CAAC,gBAAgB,KAAK,WAAW;gBAC7C,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,EAAE,YAAY,EAAE,UAAU,CAAC,gBAAgB,EAAE,CAAC;YAClD,GAAG,CAAC,UAAU,KAAK,SAAS;gBAC1B,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,UAAU,EAAE,SAAS,EAAE,eAAe,CAAC,EAAE,CAAC;SACpE,CAAC,CAAC;QAEH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,EAAE;YAC7D,SAAS,EAAE,UAAU,CAAC,SAAS;YAC/B,GAAG,CAAC,UAAU,KAAK,SAAS;gBAC1B,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,iBAAiB,EAAE,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,EAAE,EAAE,CAAC;SACnF,CAAC,CAAC;QACH,yEAAyE;QACzE,wEAAwE;QACxE,4EAA4E;QAC5E,iEAAiE;QACjE,MAAM,KAAK,GAAG,SAAS,CAAC,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QAElD,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;YACjB,OAAO,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC;QAClE,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;QAC5D,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/C,MAAM,OAAO,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;YACtC,wEAAwE;YACxE,0EAA0E;YAC1E,sEAAsE;YACtE,0EAA0E;YAC1E,uEAAuE;YACvE,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC9D,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;gBACxC,IAAI,MAAM,KAAK,SAAS;oBAAE,OAAO,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;YAChF,CAAC;YACD,OAAO,EAAE,GAAG,KAAK,EAAE,GAAG,OAAO,EAAE,CAAC;QAClC,CAAC;QACD,IAAI,GAAG,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO;gBACL,GAAG,KAAK;gBACR,MAAM,EAAE,QAAQ;gBAChB,KAAK,EAAE,oBAAoB,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC;aAClE,CAAC;QACJ,CAAC;QACD,sEAAsE;QACtE,0EAA0E;QAC1E,0EAA0E;QAC1E,mEAAmE;QACnE,OAAO,EAAE,GAAG,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,iBAAiB,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;IACzF,CAAC;CACF;AAED,uEAAuE;AACvE,SAAS,SAAS,CAAC,OAA2B;IAC5C,OAAO,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;AAClD,CAAC"}
|
package/dist/board/page.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/** The self-contained board page: polls the read API and renders runs + stats. */
|
|
2
|
-
export declare const PAGE_HTML = "<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n<title>ghostrail board</title>\n<style>\n :root { color-scheme: light dark; }\n body { font: 14px/1.5 system-ui, sans-serif; margin: 0; padding: 1.5rem; }\n h1 { font-size: 1.1rem; margin: 0 0 1rem; }\n .stats { display: flex; gap: 1rem; flex-wrap: wrap; margin-bottom: 1rem; }\n .stat { border: 1px solid #8884; border-radius: 8px; padding: .5rem .75rem; }\n .stat b { display: block; font-size: 1.3rem; }\n table { border-collapse: collapse; width: 100%; }\n th, td { text-align: left; padding: .4rem .6rem; border-bottom: 1px solid #8883; }\n .state { font-weight: 600; }\n .done { color: #2a9d3a; } .failed { color: #d33; } .blocked { color: #d90; }\n .noop, .skipped { opacity: .6; } .muted { opacity: .6; }\n a { color: inherit; }\n .twirl {\n background: none; border: none; cursor: pointer; font: inherit; padding: 0 .3rem;\n display: inline-block; transition: transform .15s ease;\n }\n .twirl.open { transform: rotate(90deg); }\n .detail-cell { padding: .75rem 1.5rem; background: #8881; }\n .detail-cell > div { margin-bottom: .5rem; }\n .detail-cell pre { white-space: pre-wrap; word-break: break-word; margin: .25rem 0 0; font: inherit; }\n .subtable { border-collapse: collapse; margin-top: .25rem; }\n .subtable td { padding: .15rem .5rem .15rem 0; border-bottom: none; }\n .detail-cell ul { margin: .25rem 0 0; padding-left: 1.2rem; }\n .toggle { font-size: .8rem; font-weight: normal; margin-left: .75rem; }\n</style>\n</head>\n<body>\n<h1>ghostrail board <label class=\"toggle\"><input type=\"checkbox\" id=\"running\" /> running</label></h1>\n<div class=\"stats\" id=\"stats\"></div>\n<table><thead><tr><th></th><th>Run</th><th>Item</th><th>State</th><th>Backend</th><th>Gate</th><th>PR</th><th>When</th></tr></thead>\n<tbody id=\"rows\"></tbody></table>\n<script>\nconst esc = (s) => String(s ?? \"\").replace(/[&<>\"]/g, (c) => (\n { \"&\": \"&\", \"<\": \"<\", \">\": \">\", '\"': \""\" }[c]\n));\nconst expanded = new Set();\nconst detailHtml = new Map();\nconst prStatusCache = new Map();\n\nfunction fmtWhen(ts) {\n return ts ? new Date(ts).toLocaleString() : \"\";\n}\n\nfunction gateStepsHtml(gate) {\n if (!gate || gate.length === 0) return \"<div class=muted>no gate steps</div>\";\n const rows = gate.map((s) =>\n \"<tr><td>\" + esc(s.name) + \"</td><td class='\" + (s.exitCode === 0 ? \"done\" : \"failed\") + \"'>\" +\n (s.exitCode === 0 ? \"passed\" : \"failed (exit \" + esc(s.exitCode) + \")\") + \"</td><td class=muted>\" +\n esc(s.durationMs) + \"ms</td></tr>\"\n ).join(\"\");\n return \"<table class=subtable>\" + rows + \"</table>\";\n}\n\nfunction artifactsHtml(artifacts) {\n if (!artifacts || artifacts.length === 0) return \"\";\n const items = artifacts.map((a) =>\n '<li><a href=\"api/artifacts/' + esc(a.hash) + '\">' + esc(a.name) + \"</a></li>\"\n ).join(\"\");\n return \"<div><b>Artifacts</b><ul>\" + items + \"</ul></div>\";\n}\n\nfunction checkLineHtml(c) {\n const label = c.conclusion || c.status;\n const cls = c.conclusion === \"success\" ? \"done\" : c.conclusion ? \"failed\" : \"muted\";\n const name = c.url ? '<a href=\"' + esc(c.url) + '\">' + esc(c.name) + \"</a>\" : esc(c.name);\n return \"<li>\" + name + \": <span class='\" + cls + \"'>\" + esc(label) + \"</span></li>\";\n}\n\nfunction prStatusHtml(status) {\n if (!status) return \"<div class=muted>loading CI status\u2026</div>\";\n if (!status.available) {\n return \"<div class=muted>PR status unknown\" + (status.error ? \": \" + esc(status.error) : \"\") + \"</div>\";\n }\n const merged = status.state === \"merged\";\n const parts = [\n \"<div><b>PR state:</b> \" + esc(status.state) +\n (merged && status.mergedAt ? \" at \" + esc(new Date(status.mergedAt).toLocaleString()) : \"\") + \"</div>\",\n ];\n if (status.checks && status.checks.length > 0) {\n parts.push(\"<div><b>CI checks</b><ul>\" + status.checks.map(checkLineHtml).join(\"\") + \"</ul></div>\");\n } else {\n parts.push(\"<div class=muted>no CI checks reported</div>\");\n }\n return parts.join(\"\");\n}\n\nfunction detailBodyHtml(row) {\n const parts = [];\n parts.push(\"<div><b>Item</b> \" + esc(row.itemId || \"\") + (row.kind ? \" (\" + esc(row.kind) + \")\" : \"\") + \"</div>\");\n if (row.branch) parts.push(\"<div><b>Branch</b> \" + esc(row.branch) + \"</div>\");\n if (row.costUsd !== undefined) {\n parts.push(\"<div><b>Cost</b> $\" + esc(Number(row.costUsd).toFixed(4)) + \"</div>\");\n }\n if (row.tokensIn !== undefined || row.tokensOut !== undefined) {\n parts.push(\"<div><b>Tokens</b> in \" + esc(row.tokensIn ?? 0) + \" / out \" + esc(row.tokensOut ?? 0) + \"</div>\");\n }\n parts.push(\"<div><b>Gate</b>\" + gateStepsHtml(row.gate) + \"</div>\");\n if (row.error) parts.push(\"<div><b>Error</b><pre class=failed>\" + esc(row.error) + \"</pre></div>\");\n if (row.summary) parts.push(\"<div><b>Comment</b><pre>\" + esc(row.summary) + \"</pre></div>\");\n if (row.prUrl) {\n parts.push('<div><b>PR</b> <a href=\"' + esc(row.prUrl) + '\">' + esc(row.prUrl) + \"</a></div>\");\n }\n parts.push(artifactsHtml(row.artifacts));\n parts.push(\n \"<div class=muted>started \" + esc(fmtWhen(row.startedAt)) +\n \", finished \" + esc(fmtWhen(row.finishedAt)) + \"</div>\",\n );\n return parts.join(\"\");\n}\n\nasync function loadDetail(runId) {\n let row;\n try {\n const res = await fetch(\"api/runs/\" + encodeURIComponent(runId));\n if (!res.ok) return;\n row = (await res.json()).row;\n } catch {\n return;\n }\n let html = detailBodyHtml(row);\n if (row.prNumber !== undefined) {\n html += '<div class=\"pr-status\" data-run-id=\"' + esc(runId) + '\">' +\n prStatusHtml(prStatusCache.get(runId)) + \"</div>\";\n }\n detailHtml.set(runId, html);\n paintDetail(runId);\n if (row.prNumber !== undefined) await loadPrStatus(runId);\n}\n\nasync function loadPrStatus(runId) {\n let status;\n try {\n status = await (await fetch(\"api/runs/\" + encodeURIComponent(runId) + \"/pr-status\")).json();\n } catch {\n return;\n }\n prStatusCache.set(runId, status);\n const el = document.querySelector('.pr-status[data-run-id=\"' + runId + '\"]');\n if (el) el.innerHTML = prStatusHtml(status);\n}\n\nfunction paintDetail(runId) {\n const cell = document.getElementById(\"detail-\" + runId);\n if (cell) cell.innerHTML = detailHtml.get(runId) || \"<div class=muted>loading\u2026</div>\";\n}\n\nfunction toggle(runId) {\n if (expanded.has(runId)) {\n expanded.delete(runId);\n } else {\n expanded.add(runId);\n if (!detailHtml.has(runId)) loadDetail(runId);\n }\n const btn = document.querySelector('.twirl[data-run-id=\"' + runId + '\"]');\n if (btn) btn.classList.toggle(\"open\", expanded.has(runId));\n const detailRow = document.getElementById(\"detail-row-\" + runId);\n if (detailRow) detailRow.style.display = expanded.has(runId) ? \"table-row\" : \"none\";\n if (expanded.has(runId)) paintDetail(runId);\n}\n\nfunction rowHtml(r) {\n const isOpen = expanded.has(r.runId);\n const gate = (r.gate || []).map((s) => (s.exitCode === 0 ? \"\u2713\" : \"\u2717\")).join(\"\");\n const pr = r.prUrl ? '<a href=\"' + esc(r.prUrl) + '\">#' + esc(r.prNumber) + \"</a>\" : \"\";\n const when = fmtWhen(r.startedAt);\n const state = esc(r.state || \"in-progress\");\n const main = \"<tr class=run-row>\" +\n \"<td><button class='twirl\" + (isOpen ? \" open\" : \"\") + \"' data-run-id='\" + esc(r.runId) + \"'>\u25B6</button></td>\" +\n \"<td class=muted>\" + esc(r.runId.slice(0, 8)) + \"</td>\" +\n \"<td>\" + esc(r.title || r.itemId || \"\") + \"</td>\" +\n \"<td class='state \" + state + \"'>\" + state + \"</td>\" +\n \"<td>\" + esc(r.backend || \"\") + \"</td>\" +\n \"<td>\" + gate + \"</td>\" +\n \"<td>\" + pr + \"</td>\" +\n \"<td class=muted>\" + esc(when) + \"</td></tr>\";\n const cellContent = isOpen ? (detailHtml.get(r.runId) || \"<div class=muted>loading\u2026</div>\") : \"\";\n const detail = \"<tr class=detail-row id='detail-row-\" + esc(r.runId) + \"'\" +\n \" style='display:\" + (isOpen ? \"table-row\" : \"none\") + \"'>\" +\n \"<td colspan=8 class=detail-cell id='detail-\" + esc(r.runId) + \"'>\" + cellContent + \"</td></tr>\";\n return main + detail;\n}\n\ndocument.getElementById(\"rows\").addEventListener(\"click\", (e) => {\n const btn = e.target.closest(\".twirl\");\n if (btn) toggle(btn.dataset.runId);\n});\n\nconst runningBox = document.getElementById(\"running\");\nlet toggling = false;\nrunningBox.addEventListener(\"change\", async () => {\n const wanted = runningBox.checked;\n toggling = true;\n runningBox.disabled = true;\n try {\n const res = await fetch(\"api/control\", {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ enabled: wanted }),\n });\n if (!res.ok) throw new Error(\"toggle failed\");\n const state = await res.json();\n runningBox.checked = state.enabled;\n } catch {\n runningBox.checked = !wanted;\n } finally {\n runningBox.disabled = false;\n toggling = false;\n }\n});\nasync function refresh() {\n const [runs, stats, control] = await Promise.all([\n fetch(\"api/runs\").then((r) => r.json()),\n fetch(\"api/stats\").then((r) => r.json()),\n fetch(\"api/control\").then((r) => r.json()),\n ]);\n if (!toggling) runningBox.checked = control.enabled;\n document.getElementById(\"stats\").innerHTML = [\n [\"runs\", stats.total],\n [\"success\", (stats.successRate * 100).toFixed(0) + \"%\"],\n [\"PRs\", stats.prCount],\n ].map(([k, v]) => '<div class=\"stat\"><b>' + esc(v) + \"</b>\" + esc(k) + \"</div>\").join(\"\");\n document.getElementById(\"rows\").innerHTML = runs.map(rowHtml).join(\"\");\n for (const runId of expanded) loadDetail(runId);\n}\nrefresh();\nsetInterval(refresh, 5000);\n</script>\n</body>\n</html>";
|
|
2
|
+
export declare const PAGE_HTML: string;
|
|
3
3
|
//# sourceMappingURL=page.d.ts.map
|
package/dist/board/page.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../src/board/page.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../src/board/page.ts"],"names":[],"mappings":"AAEA,kFAAkF;AAClF,eAAO,MAAM,SAAS,QA2Od,CAAC"}
|
package/dist/board/page.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { IN_PROGRESS_STATE } from "../store/events.js";
|
|
1
2
|
/** The self-contained board page: polls the read API and renders runs + stats. */
|
|
2
3
|
export const PAGE_HTML = `<!doctype html>
|
|
3
4
|
<html lang="en">
|
|
@@ -171,7 +172,7 @@ function rowHtml(r) {
|
|
|
171
172
|
const gate = (r.gate || []).map((s) => (s.exitCode === 0 ? "✓" : "✗")).join("");
|
|
172
173
|
const pr = r.prUrl ? '<a href="' + esc(r.prUrl) + '">#' + esc(r.prNumber) + "</a>" : "";
|
|
173
174
|
const when = fmtWhen(r.startedAt);
|
|
174
|
-
const state = esc(r.state ||
|
|
175
|
+
const state = esc(r.state || ${JSON.stringify(IN_PROGRESS_STATE)});
|
|
175
176
|
const main = "<tr class=run-row>" +
|
|
176
177
|
"<td><button class='twirl" + (isOpen ? " open" : "") + "' data-run-id='" + esc(r.runId) + "'>▶</button></td>" +
|
|
177
178
|
"<td class=muted>" + esc(r.runId.slice(0, 8)) + "</td>" +
|
package/dist/board/page.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page.js","sourceRoot":"","sources":["../../src/board/page.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,MAAM,CAAC,MAAM,SAAS,GAAG
|
|
1
|
+
{"version":3,"file":"page.js","sourceRoot":"","sources":["../../src/board/page.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,kFAAkF;AAClF,MAAM,CAAC,MAAM,SAAS,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iCA4KQ,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QA+D1D,CAAC"}
|
package/dist/board/server.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type Server } from "node:http";
|
|
2
2
|
import type { RunControl } from "../loop/control.js";
|
|
3
3
|
import type { PrStatus } from "../publish/githost.js";
|
|
4
|
-
import type
|
|
4
|
+
import { type RunStore } from "../store/port.js";
|
|
5
5
|
export type Route = {
|
|
6
6
|
kind: "page";
|
|
7
7
|
} | {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/board/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,MAAM,EAAqC,MAAM,WAAW,CAAC;AACjG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/board/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwB,KAAK,MAAM,EAAqC,MAAM,WAAW,CAAC;AACjG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAkB,KAAK,QAAQ,EAAkB,MAAM,kBAAkB,CAAC;AAIjF,MAAM,MAAM,KAAK,GACb;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC3B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,CAAC;AAEzB,qDAAqD;AACrD,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,KAAK,CAwBlD;AAED,2FAA2F;AAC3F,MAAM,WAAW,cAAc;IAC7B,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;CAClD;AAuBD,MAAM,WAAW,YAAY;IAC3B,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4FAA4F;IAC5F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,oGAAoG;IACpG,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB;;;;OAIG;IACH,OAAO,CAAC,EAAE,UAAU,CAAC;CACtB;AAED,kFAAkF;AAClF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEhD;AAQD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,GAAE,YAAiB,GAAG,MAAM,CAqBrF;AAED,4EAA4E;AAC5E;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAG5E"}
|
package/dist/board/server.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { createServer } from "node:http";
|
|
2
|
+
import { isArtifactHash } from "../store/port.js";
|
|
2
3
|
import { PAGE_HTML } from "./page.js";
|
|
3
4
|
import { computeStats } from "./stats.js";
|
|
4
5
|
/** Map a request pathname to a board route. Pure. */
|
|
@@ -25,7 +26,12 @@ export function parseRoute(pathname) {
|
|
|
25
26
|
if (parts[1] === "control" && parts.length === 2)
|
|
26
27
|
return { kind: "control" };
|
|
27
28
|
if (parts[1] === "artifacts" && parts.length === 3) {
|
|
28
|
-
|
|
29
|
+
// Decoding is what makes this dangerous: `..%2F..%2Fetc%2Fpasswd` is one
|
|
30
|
+
// path segment until this call turns it back into slashes. A hash that is
|
|
31
|
+
// not a sha256 digest names nothing the store holds, so it is a 404 here
|
|
32
|
+
// rather than a path handed downward and hoped about.
|
|
33
|
+
const hash = decodeURIComponent(parts[2] ?? "");
|
|
34
|
+
return isArtifactHash(hash) ? { kind: "artifact", hash } : { kind: "notfound" };
|
|
29
35
|
}
|
|
30
36
|
return { kind: "notfound" };
|
|
31
37
|
}
|
package/dist/board/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/board/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0D,YAAY,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/board/server.ts"],"names":[],"mappings":"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"}
|
package/dist/board/stats.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/board/stats.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../src/board/stats.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,MAAM,EAAgB,MAAM,oBAAoB,CAAC;AAE/D,MAAM,WAAW,KAAK;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,6BAA6B;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAC;IACpB,qEAAqE;IACrE,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,qEAAqE;IACrE,YAAY,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACjD;AAaD;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,KAAK,CAqC3D"}
|
package/dist/board/stats.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { displayState } from "../store/events.js";
|
|
1
2
|
/** Median of a numeric list (average of the two middles for even length); null if empty. */
|
|
2
3
|
function median(values) {
|
|
3
4
|
if (values.length === 0)
|
|
@@ -25,7 +26,7 @@ export function computeStats(rows) {
|
|
|
25
26
|
let terminal = 0;
|
|
26
27
|
let done = 0;
|
|
27
28
|
for (const row of rows) {
|
|
28
|
-
const state = row.state
|
|
29
|
+
const state = displayState(row.state);
|
|
29
30
|
byState[state] = (byState[state] ?? 0) + 1;
|
|
30
31
|
if (row.prNumber !== undefined)
|
|
31
32
|
prCount++;
|
package/dist/board/stats.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stats.js","sourceRoot":"","sources":["../../src/board/stats.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"stats.js","sourceRoot":"","sources":["../../src/board/stats.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { type ClaudeMdSection, classifyClaudeMdSections, classifySettingsKeys, composeFactoryClaudeMd, composeFactorySettings, type Section, type SettingsKeyReport, splitSections, type Verdict, } from "./classify.js";
|
|
2
|
-
export { buildProposal, type SetupProposal, type SkillReport, writeProfile } from "./setup.js";
|
|
2
|
+
export { buildProposal, DEFAULT_CLAUDE_PINS, type SetupProposal, type SkillReport, writeProfile, } from "./setup.js";
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/claude-profile/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,eAAe,EACpB,wBAAwB,EACxB,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,EACtB,KAAK,OAAO,EACZ,KAAK,iBAAiB,EACtB,aAAa,EACb,KAAK,OAAO,GACb,MAAM,eAAe,CAAC;AACvB,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/claude-profile/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,eAAe,EACpB,wBAAwB,EACxB,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,EACtB,KAAK,OAAO,EACZ,KAAK,iBAAiB,EACtB,aAAa,EACb,KAAK,OAAO,GACb,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,YAAY,GACb,MAAM,YAAY,CAAC"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { classifyClaudeMdSections, classifySettingsKeys, composeFactoryClaudeMd, composeFactorySettings, splitSections, } from "./classify.js";
|
|
2
|
-
export { buildProposal, writeProfile } from "./setup.js";
|
|
2
|
+
export { buildProposal, DEFAULT_CLAUDE_PINS, writeProfile, } from "./setup.js";
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/claude-profile/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,wBAAwB,EACxB,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,EAGtB,aAAa,GAEd,MAAM,eAAe,CAAC;AACvB,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/claude-profile/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,wBAAwB,EACxB,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,EAGtB,aAAa,GAEd,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,aAAa,EACb,mBAAmB,EAGnB,YAAY,GACb,MAAM,YAAY,CAAC"}
|
|
@@ -3,6 +3,13 @@ export interface SkillReport {
|
|
|
3
3
|
name: string;
|
|
4
4
|
pin: boolean;
|
|
5
5
|
}
|
|
6
|
+
/**
|
|
7
|
+
* Skills pinned by default when `--pin` names none explicitly. Shared by
|
|
8
|
+
* `claude-setup` (which uses it directly) and `doctor` (which recomputes
|
|
9
|
+
* `missingPins` against the same list, since claude-setup's own report of a
|
|
10
|
+
* missing pin is otherwise only ever seen once, at write time).
|
|
11
|
+
*/
|
|
12
|
+
export declare const DEFAULT_CLAUDE_PINS: readonly ["testbotpro"];
|
|
6
13
|
/** A proposal for the factory Claude profile, derived from an existing ~/.claude. */
|
|
7
14
|
export interface SetupProposal {
|
|
8
15
|
sourceHome: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/claude-profile/setup.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,iBAAiB,EAMvB,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;CACd;AAED,qFAAqF;AACrF,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,eAAe,EAAE,CAAA;KAAE,CAAC;IAC5D,QAAQ,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,iBAAiB,EAAE,CAAA;KAAE,CAAC;IAC1D,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,wFAAwF;IACxF,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAqBD;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,SAAS,MAAM,EAAE,GACrB,OAAO,CAAC,aAAa,CAAC,CAgCxB;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBzE"}
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/claude-profile/setup.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,eAAe,EACpB,KAAK,iBAAiB,EAMvB,MAAM,eAAe,CAAC;AAEvB,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,OAAO,CAAC;CACd;AAED;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,yBAA0B,CAAC;AAE3D,qFAAqF;AACrF,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,eAAe,EAAE,CAAA;KAAE,CAAC;IAC5D,QAAQ,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,iBAAiB,EAAE,CAAA;KAAE,CAAC;IAC1D,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,wFAAwF;IACxF,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAqBD;;;;GAIG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,SAAS,MAAM,EAAE,GACrB,OAAO,CAAC,aAAa,CAAC,CAgCxB;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBzE"}
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
import { cp, mkdir, readFile, readdir, writeFile } from "node:fs/promises";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { classifyClaudeMdSections, classifySettingsKeys, composeFactoryClaudeMd, composeFactorySettings, splitSections, } from "./classify.js";
|
|
4
|
+
/**
|
|
5
|
+
* Skills pinned by default when `--pin` names none explicitly. Shared by
|
|
6
|
+
* `claude-setup` (which uses it directly) and `doctor` (which recomputes
|
|
7
|
+
* `missingPins` against the same list, since claude-setup's own report of a
|
|
8
|
+
* missing pin is otherwise only ever seen once, at write time).
|
|
9
|
+
*/
|
|
10
|
+
export const DEFAULT_CLAUDE_PINS = ["testbotpro"];
|
|
4
11
|
async function readIfPresent(path) {
|
|
5
12
|
try {
|
|
6
13
|
return await readFile(path, "utf8");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/claude-profile/setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAGL,wBAAwB,EACxB,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,EACtB,aAAa,GACd,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/claude-profile/setup.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/commands.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ExecResult } from "../backend/types.js";
|
|
2
|
+
import { type DoctorDeps } from "../doctor/index.js";
|
|
2
3
|
import { type ServiceManager } from "../service/index.js";
|
|
3
4
|
import type { Scope } from "../vendor/skilltend/paths.js";
|
|
4
5
|
import { type Asker } from "./prompt.js";
|
|
@@ -203,5 +204,10 @@ export interface SecretsSetupDeps {
|
|
|
203
204
|
* Output names keys only. No value from the file is ever printed.
|
|
204
205
|
*/
|
|
205
206
|
export declare function cmdSecretsSetup(argv: readonly string[], streams: CommandStreams, env?: CommandEnv, deps?: SecretsSetupDeps): Promise<number>;
|
|
207
|
+
/**
|
|
208
|
+
* `ghostrail doctor`: probe a setup rather than merely inspect it, and name the
|
|
209
|
+
* fix for whatever is broken. See specs/doctor-command.spec.md.
|
|
210
|
+
*/
|
|
211
|
+
export declare function cmdDoctor(argv: readonly string[], streams: CommandStreams, env?: CommandEnv, deps?: DoctorDeps): Promise<number>;
|
|
206
212
|
export {};
|
|
207
213
|
//# sourceMappingURL=commands.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/commands.js
CHANGED
|
@@ -7,10 +7,11 @@ import { fileURLToPath } from "node:url";
|
|
|
7
7
|
import { spawnCollect } from "../backend/proc.js";
|
|
8
8
|
import { DEFAULT_BOARD_PORT, PORT_FALLBACK_ATTEMPTS, isAddressInUse, isValidPort, portCandidates, } from "../board/port.js";
|
|
9
9
|
import { createBoardServer, isLoopback, normalizeToken } from "../board/server.js";
|
|
10
|
-
import { buildProposal, writeProfile } from "../claude-profile/index.js";
|
|
10
|
+
import { DEFAULT_CLAUDE_PINS, buildProposal, writeProfile } from "../claude-profile/index.js";
|
|
11
11
|
import { parseDuration } from "../config/duration.js";
|
|
12
12
|
import { parseConfig, parseMergedConfig } from "../config/load.js";
|
|
13
13
|
import { createDashboardServer, defaultStateDir } from "../dashboard/index.js";
|
|
14
|
+
import { hasFailure, renderDoctorJson, renderDoctorText, runDoctor, } from "../doctor/index.js";
|
|
14
15
|
import { buildLoopDeps, buildRespondDeps, buildTriageDeps, repoGhRunner, resolveRepoSlug, } from "../factory/build.js";
|
|
15
16
|
import { describeMigration, migrateLegacyStore, resolveWorkRepo, stateDirFor, } from "../factory/state.js";
|
|
16
17
|
import { entryKey, findByPath, findForRepoResolving, replaceEntry, upsert, } from "../global/registry.js";
|
|
@@ -430,10 +431,49 @@ export async function cmdBoard(argv, streams, env = process.env, cwd = process.c
|
|
|
430
431
|
}
|
|
431
432
|
/** The cross-ghostrail dashboard's default port, one above the board's. */
|
|
432
433
|
export const DEFAULT_DASHBOARD_PORT = 5051;
|
|
434
|
+
/**
|
|
435
|
+
* The `owner/repo` slug for a registered ghostrail, for `gh --repo`.
|
|
436
|
+
*
|
|
437
|
+
* The registry's `repo` is the ghostrail's identity and is already canonical
|
|
438
|
+
* (`host/owner/name`), so it answers this without running anything. Two entries
|
|
439
|
+
* cannot: `local:<path>` has no remote by definition, and an entry written
|
|
440
|
+
* before repo identities existed has no `repo` at all. Both fall back to the
|
|
441
|
+
* checkout's origin, which is what `board` does with its one repo.
|
|
442
|
+
*
|
|
443
|
+
* Undefined is not a failure. It leaves `gh` to infer the repo from the
|
|
444
|
+
* checkout, exactly as an unscoped invocation always has.
|
|
445
|
+
*/
|
|
446
|
+
async function dashboardRepoSlug(entry) {
|
|
447
|
+
const repo = entry.repo;
|
|
448
|
+
if (repo !== undefined && !repo.startsWith("local:")) {
|
|
449
|
+
const parts = repo.split("/");
|
|
450
|
+
if (parts.length === 3)
|
|
451
|
+
return `${parts[1]}/${parts[2]}`;
|
|
452
|
+
}
|
|
453
|
+
return resolveBoardRepoSlug(entry.path);
|
|
454
|
+
}
|
|
433
455
|
/** Build the dashboard server's dependencies from the real environment. */
|
|
434
456
|
function dashboardDeps(env, manager) {
|
|
435
457
|
const store = globalStoreFor(env);
|
|
458
|
+
// A ghostrail's slug does not change while the dashboard runs, and resolving
|
|
459
|
+
// it can cost a `git` call. The page refetches PR status for every expanded
|
|
460
|
+
// row every 10s, so without this that cost recurs for as long as a row is
|
|
461
|
+
// open. Keyed on the identity, so two clones of one repo share the answer.
|
|
462
|
+
const slugs = new Map();
|
|
463
|
+
const slugFor = (entry) => {
|
|
464
|
+
const key = entryKey(entry);
|
|
465
|
+
const known = slugs.get(key);
|
|
466
|
+
if (known !== undefined)
|
|
467
|
+
return known;
|
|
468
|
+
const resolving = dashboardRepoSlug(entry);
|
|
469
|
+
slugs.set(key, resolving);
|
|
470
|
+
return resolving;
|
|
471
|
+
};
|
|
436
472
|
return {
|
|
473
|
+
// Constructing this runs nothing; only a request that needs it spends a
|
|
474
|
+
// subprocess. A machine with no `gh` and no credentials still serves the
|
|
475
|
+
// whole dashboard, with PR status reported as unavailable.
|
|
476
|
+
prStatus: async (entry, prNumber) => new GhHost(repoGhRunner(entry.path), await slugFor(entry)).getPrStatus(prNumber),
|
|
437
477
|
readRegistry: () => store.readRegistry(),
|
|
438
478
|
writeRegistry: (entries) => store.writeRegistry(entries),
|
|
439
479
|
health: ghostrailHealth,
|
|
@@ -1675,7 +1715,7 @@ export async function cmdClaudeSetup(argv, streams, env = process.env) {
|
|
|
1675
1715
|
home: env.HOME ?? homedir(),
|
|
1676
1716
|
profile: join(globalDir, "claude"),
|
|
1677
1717
|
write: false,
|
|
1678
|
-
pins: [
|
|
1718
|
+
pins: [...DEFAULT_CLAUDE_PINS],
|
|
1679
1719
|
});
|
|
1680
1720
|
const proposal = await buildProposal(flags.home, flags.profile, flags.pins);
|
|
1681
1721
|
streams.out("Claude profile setup\n");
|
|
@@ -1820,4 +1860,60 @@ async function openSecretsInEditor(path, flags, streams, env, deps) {
|
|
|
1820
1860
|
streams.err(`editor exited ${code}; the file is written. ${fill}`);
|
|
1821
1861
|
return 0;
|
|
1822
1862
|
}
|
|
1863
|
+
/** Parse `doctor` flags: the shared `-c/-C` pair, plus `--json` and `--quick`. */
|
|
1864
|
+
function parseDoctorFlags(argv, defaults) {
|
|
1865
|
+
const base = parseCommandFlags(argv, defaults);
|
|
1866
|
+
return {
|
|
1867
|
+
...base,
|
|
1868
|
+
json: defaults.json || argv.includes("--json"),
|
|
1869
|
+
quick: defaults.quick || argv.includes("--quick"),
|
|
1870
|
+
};
|
|
1871
|
+
}
|
|
1872
|
+
/**
|
|
1873
|
+
* Load `ghostrail.toml` merged with the global settings as a {@link Result},
|
|
1874
|
+
* rather than printing and returning undefined like {@link loadConfig} — unlike
|
|
1875
|
+
* every other command, `doctor` has useful things to say even when config is
|
|
1876
|
+
* broken (credentials, the Claude profile, run history), so it never aborts.
|
|
1877
|
+
*/
|
|
1878
|
+
async function loadDoctorConfig(configPath, env) {
|
|
1879
|
+
let repoToml;
|
|
1880
|
+
try {
|
|
1881
|
+
repoToml = await readFile(configPath, "utf8");
|
|
1882
|
+
}
|
|
1883
|
+
catch {
|
|
1884
|
+
return { ok: false, errors: [{ path: "", message: `cannot read config file: ${configPath}` }] };
|
|
1885
|
+
}
|
|
1886
|
+
const globalToml = await globalStoreFor(env).readSettings();
|
|
1887
|
+
return parseMergedConfig(repoToml, globalToml);
|
|
1888
|
+
}
|
|
1889
|
+
/**
|
|
1890
|
+
* `ghostrail doctor`: probe a setup rather than merely inspect it, and name the
|
|
1891
|
+
* fix for whatever is broken. See specs/doctor-command.spec.md.
|
|
1892
|
+
*/
|
|
1893
|
+
export async function cmdDoctor(argv, streams, env = process.env, deps = {}) {
|
|
1894
|
+
const flags = parseDoctorFlags(argv, {
|
|
1895
|
+
config: "ghostrail.toml",
|
|
1896
|
+
repo: ".",
|
|
1897
|
+
json: false,
|
|
1898
|
+
quick: false,
|
|
1899
|
+
});
|
|
1900
|
+
const secrets = await applySecrets(flags, env);
|
|
1901
|
+
const configPath = isAbsolute(flags.config) ? flags.config : join(flags.repo, flags.config);
|
|
1902
|
+
const config = await loadDoctorConfig(configPath, env);
|
|
1903
|
+
const claudeProfileDir = await resolveClaudeProfile(env);
|
|
1904
|
+
const state = await stateDirFor(flags.repo, config.ok ? config.value : undefined, env);
|
|
1905
|
+
const historyRows = await new FileStore(state.dir).listRuns();
|
|
1906
|
+
const report = await runDoctor({
|
|
1907
|
+
repoPath: flags.repo,
|
|
1908
|
+
config,
|
|
1909
|
+
env,
|
|
1910
|
+
quick: flags.quick,
|
|
1911
|
+
claudeProfileDir,
|
|
1912
|
+
claudeSourceHome: env.HOME ?? homedir(),
|
|
1913
|
+
historyRows,
|
|
1914
|
+
}, deps);
|
|
1915
|
+
const rendered = flags.json ? renderDoctorJson(report) : renderDoctorText(report);
|
|
1916
|
+
streams.out(redactSecrets(rendered, secrets));
|
|
1917
|
+
return hasFailure(report) ? 1 : 0;
|
|
1918
|
+
}
|
|
1823
1919
|
//# sourceMappingURL=commands.js.map
|