ghostrail 0.20.1 → 0.21.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/dist/board/page.d.ts.map +1 -1
- package/dist/board/page.js +8 -1
- package/dist/board/page.js.map +1 -1
- package/dist/cli/commands.d.ts +7 -1
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +80 -11
- package/dist/cli/commands.js.map +1 -1
- package/dist/commands/help.d.ts.map +1 -1
- package/dist/commands/help.js +3 -0
- package/dist/commands/help.js.map +1 -1
- package/dist/dashboard/page.d.ts.map +1 -1
- package/dist/dashboard/page.js +126 -4
- package/dist/dashboard/page.js.map +1 -1
- package/dist/dashboard/review-page.d.ts +5 -0
- package/dist/dashboard/review-page.d.ts.map +1 -1
- package/dist/dashboard/review-page.js +23 -3
- package/dist/dashboard/review-page.js.map +1 -1
- package/dist/dashboard/routes.d.ts +13 -0
- package/dist/dashboard/routes.d.ts.map +1 -1
- package/dist/dashboard/routes.js +21 -0
- package/dist/dashboard/routes.js.map +1 -1
- package/dist/dashboard/server.d.ts.map +1 -1
- package/dist/dashboard/server.js +19 -1
- package/dist/dashboard/server.js.map +1 -1
- package/dist/doctor/checks.d.ts +1 -0
- package/dist/doctor/checks.d.ts.map +1 -1
- package/dist/doctor/checks.js +1 -1
- package/dist/doctor/checks.js.map +1 -1
- package/dist/doctor/probes.d.ts +19 -3
- package/dist/doctor/probes.d.ts.map +1 -1
- package/dist/doctor/probes.js +22 -27
- package/dist/doctor/probes.js.map +1 -1
- package/dist/doctor/run.d.ts.map +1 -1
- package/dist/doctor/run.js +17 -3
- package/dist/doctor/run.js.map +1 -1
- package/dist/factory/build.d.ts.map +1 -1
- package/dist/factory/build.js +3 -0
- package/dist/factory/build.js.map +1 -1
- package/dist/loop/next-tick.d.ts +12 -0
- package/dist/loop/next-tick.d.ts.map +1 -0
- package/dist/loop/next-tick.js +37 -0
- package/dist/loop/next-tick.js.map +1 -0
- package/dist/loop/tick-log.d.ts +13 -0
- package/dist/loop/tick-log.d.ts.map +1 -0
- package/dist/loop/tick-log.js +64 -0
- package/dist/loop/tick-log.js.map +1 -0
- package/dist/respond/merge.js +3 -0
- package/dist/respond/merge.js.map +1 -1
- package/dist/respond/respond.d.ts +7 -0
- package/dist/respond/respond.d.ts.map +1 -1
- package/dist/respond/respond.js +1 -0
- package/dist/respond/respond.js.map +1 -1
- package/dist/store/events.d.ts +30 -0
- package/dist/store/events.d.ts.map +1 -1
- package/dist/store/events.js +38 -0
- package/dist/store/events.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/triage/engine.d.ts +6 -2
- package/dist/triage/engine.d.ts.map +1 -1
- package/dist/triage/engine.js +6 -1
- package/dist/triage/engine.js.map +1 -1
- package/package.json +1 -1
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":"AAEA,kFAAkF;AAClF,eAAO,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../src/board/page.ts"],"names":[],"mappings":"AAEA,kFAAkF;AAClF,eAAO,MAAM,SAAS,QAyTd,CAAC"}
|
package/dist/board/page.js
CHANGED
|
@@ -260,6 +260,12 @@ const runningBox = document.getElementById("running");
|
|
|
260
260
|
let toggling = false;
|
|
261
261
|
runningBox.addEventListener("change", async () => {
|
|
262
262
|
const wanted = runningBox.checked;
|
|
263
|
+
const before = !wanted;
|
|
264
|
+
// Undo the browser's own flip before anything else runs: nothing is true
|
|
265
|
+
// until the server confirms it, so the box shows the old value, not the
|
|
266
|
+
// clicked one, for the whole width of the request.
|
|
267
|
+
runningBox.checked = before;
|
|
268
|
+
runningBox.indeterminate = true;
|
|
263
269
|
toggling = true;
|
|
264
270
|
runningBox.disabled = true;
|
|
265
271
|
try {
|
|
@@ -272,8 +278,9 @@ runningBox.addEventListener("change", async () => {
|
|
|
272
278
|
const state = await res.json();
|
|
273
279
|
runningBox.checked = state.enabled;
|
|
274
280
|
} catch {
|
|
275
|
-
runningBox.checked =
|
|
281
|
+
runningBox.checked = before;
|
|
276
282
|
} finally {
|
|
283
|
+
runningBox.indeterminate = false;
|
|
277
284
|
runningBox.disabled = false;
|
|
278
285
|
toggling = false;
|
|
279
286
|
}
|
package/dist/board/page.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBAgMH,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC
|
|
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sBAgMH,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAyH/C,CAAC"}
|
package/dist/cli/commands.d.ts
CHANGED
|
@@ -86,7 +86,8 @@ export declare function cmdStatus(argv: readonly string[], streams: CommandStrea
|
|
|
86
86
|
/** The quickstart templates bundled with the package. */
|
|
87
87
|
export declare const TEMPLATES: readonly ["code", "content"];
|
|
88
88
|
/**
|
|
89
|
-
* `ghostrail init <template> [--repo <path>] [--force|--diff|--update|--greenroom
|
|
89
|
+
* `ghostrail init <template> [--repo <path>] [--force|--diff|--update|--greenroom
|
|
90
|
+
* [<path>]] [--register] [--repoint]`:
|
|
90
91
|
* scaffold `ghostrail.toml` and `prompts/` from a quickstart template. Safe for
|
|
91
92
|
* a fresh OR an existing repo: existing files are left untouched (skipped)
|
|
92
93
|
* unless `--force` is given. `--diff` reports drift instead of writing
|
|
@@ -98,6 +99,11 @@ export declare const TEMPLATES: readonly ["code", "content"];
|
|
|
98
99
|
*
|
|
99
100
|
* Registration is skipped, not just the write, when the target looks like a
|
|
100
101
|
* temp directory (TJ-1654); `--register` registers it anyway.
|
|
102
|
+
*
|
|
103
|
+
* `--repoint` opts into the one registry write that is an act rather than an
|
|
104
|
+
* add: moving an already-registered ghostrail's entry to this checkout when it
|
|
105
|
+
* is currently pointing somewhere else. Without it, that mismatch is reported
|
|
106
|
+
* and the registry is left alone (TJ-1652).
|
|
101
107
|
*/
|
|
102
108
|
export declare function cmdInit(argv: readonly string[], streams: CommandStreams, cwd?: string, env?: CommandEnv): Promise<number>;
|
|
103
109
|
interface SkillFlags {
|
|
@@ -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;AAoBtD,OAAO,EACL,KAAK,UAAU,EAKhB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/cli/commands.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAoBtD,OAAO,EACL,KAAK,UAAU,EAKhB,MAAM,oBAAoB,CAAC;AAuF5B,OAAO,EAGL,KAAK,cAAc,EAOpB,MAAM,qBAAqB,CAAC;AAU7B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAE1D,OAAO,EAAE,KAAK,KAAK,EAAqC,MAAM,aAAa,CAAC;AAG5E,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,QAAQ,EAAE,YAAY,GAAG,YAAY,CAc/F;AAED,UAAU,UAAU;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACnC;AA2ND,iDAAiD;AACjD,wBAAsB,MAAM,CAC1B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,cAAc,EACvB,GAAG,GAAE,UAAwB,EAC7B,GAAG,SAAgB,GAClB,OAAO,CAAC,MAAM,CAAC,CAQjB;AAED,UAAU,UAAU;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,GAAG,SAAS,CAoB/E;AAyDD,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,cAAc,EACvB,GAAG,GAAE,UAAwB,EAC7B,GAAG,SAAgB,GAClB,OAAO,CAAC,MAAM,CAAC,CAuEjB;AAED,sFAAsF;AACtF,wBAAsB,SAAS,CAC7B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,cAAc,EACvB,GAAG,GAAE,UAAwB,EAC7B,GAAG,SAAgB,GAClB,OAAO,CAAC,MAAM,CAAC,CA0CjB;AAED,gFAAgF;AAChF,wBAAsB,UAAU,CAC9B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,cAAc,EACvB,GAAG,GAAE,UAAwB,EAC7B,GAAG,SAAgB,GAClB,OAAO,CAAC,MAAM,CAAC,CA6CjB;AAED,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,YAAY,EAAE,OAAO,CAAC;IACtB,gFAAgF;IAChF,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,oEAAoE;AACpE,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,QAAQ,EAAE,UAAU,GAAG,UAAU,CAyBzF;AAcD,iFAAiF;AACjF,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,cAAc,EACvB,GAAG,GAAE,UAAwB,EAC7B,GAAG,SAAgB,GAClB,OAAO,CAAC,MAAM,CAAC,CAiFjB;AAED,2EAA2E;AAC3E,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAqE3C;;;;;;GAMG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,cAAc,EACvB,GAAG,GAAE,UAAwB,EAC7B,OAAO,GAAE,cAAyD,GACjE,OAAO,CAAC,MAAM,CAAC,CAoDjB;AAED,sFAAsF;AACtF,wBAAsB,YAAY,CAChC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,cAAc,EACvB,GAAG,GAAE,UAAwB,GAC5B,OAAO,CAAC,MAAM,CAAC,CAejB;AAED;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,IAAI,GAAG,WAAW,GAAG,SAAS,CAAC;AAE7D,4EAA4E;AAC5E,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAG5E;AAED,+DAA+D;AAC/D,wBAAsB,KAAK,CACzB,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,OAAO,EAAE,cAAc,EACvB,GAAG,GAAE,UAAwB,GAC5B,OAAO,CAAC,MAAM,CAAC,CA+BjB;AA0ID;;;GAGG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,cAAc,EACvB,GAAG,GAAE,UAAwB,EAC7B,GAAG,GAAE,KAAqB,EAC1B,KAAK,GAAE,OAAsC,EAC7C,OAAO,GAAE,cAAyD,GACjE,OAAO,CAAC,MAAM,CAAC,CAmKjB;AAED,+EAA+E;AAC/E,wBAAsB,OAAO,CAC3B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,cAAc,EACvB,GAAG,GAAE,UAAwB,EAC7B,OAAO,GAAE,cAAyD,GACjE,OAAO,CAAC,MAAM,CAAC,CAkDjB;AAED,qFAAqF;AACrF,wBAAsB,SAAS,CAC7B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,cAAc,EACvB,GAAG,GAAE,UAAwB,EAC7B,OAAO,GAAE,cAAyD,GACjE,OAAO,CAAC,MAAM,CAAC,CA+BjB;AAED,yDAAyD;AACzD,eAAO,MAAM,SAAS,8BAA+B,CAAC;AA4gBtD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,OAAO,CAC3B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,cAAc,EACvB,GAAG,SAAgB,EACnB,GAAG,GAAE,UAAwB,GAC5B,OAAO,CAAC,MAAM,CAAC,CAgLjB;AAwBD,UAAU,UAAU;IAClB,KAAK,EAAE,KAAK,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;IACnB,GAAG,EAAE,OAAO,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,CA8BnE;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,cAAc,EACvB,GAAG,GAAE,UAAwB,EAC7B,GAAG,SAAgB,GAClB,OAAO,CAAC,MAAM,CAAC,CAoDjB;AAiBD;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,cAAc,EACvB,GAAG,GAAE,UAAwB,EAC7B,GAAG,SAAgB,EACnB,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,MAAM,CAAC,CAWjB;AAED;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,cAAc,EACvB,GAAG,EAAE,UAAU,EACf,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,IAAI,CAAC,CAkEf;AAED;;;;;;;GAOG;AACH,wBAAsB,aAAa,CACjC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,cAAc,EACvB,IAAI,GAAE,cAAmB,GACxB,OAAO,CAAC,MAAM,CAAC,CAoEjB;AA0BD,gFAAgF;AAChF,MAAM,WAAW,cAAc;IAC7B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mFAAmF;IACnF,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAClD,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IACtD,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACrD,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;IAC5D,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjE;AAgED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,cAAc,EACvB,GAAG,GAAE,UAAwB,GAC5B,OAAO,CAAC,MAAM,CAAC,CAoDjB;AAED,4EAA4E;AAC5E,MAAM,WAAW,WAAY,SAAQ,gBAAgB;IACnD,qEAAqE;IACrE,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACzD,+CAA+C;IAC/C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,iEAAiE;IACjE,GAAG,CAAC,EAAE,KAAK,CAAC;IACZ;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACtD;AAED;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,cAAc,EACvB,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,MAAM,CAAC,CAyBjB;AAwBD,6EAA6E;AAC7E,MAAM,WAAW,gBAAgB;IAC/B,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7E,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,cAAc,EACvB,GAAG,GAAE,UAAwB,EAC7B,IAAI,GAAE,gBAAqB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAsCjB;AAwED;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,cAAc,EACvB,GAAG,GAAE,UAAwB,EAC7B,IAAI,GAAE,UAAe,GACpB,OAAO,CAAC,MAAM,CAAC,CAgCjB"}
|
package/dist/cli/commands.js
CHANGED
|
@@ -28,7 +28,9 @@ import { concurrencyAdvice } from "../loop/advice.js";
|
|
|
28
28
|
import { fileControl } from "../loop/control.js";
|
|
29
29
|
import { readControl } from "../loop/control.js";
|
|
30
30
|
import { runTick } from "../loop/engine.js";
|
|
31
|
+
import { writeNextTickAt } from "../loop/next-tick.js";
|
|
31
32
|
import { duePasses, } from "../loop/schedule.js";
|
|
33
|
+
import { appendLog } from "../loop/tick-log.js";
|
|
32
34
|
import { watchLoop } from "../loop/watch.js";
|
|
33
35
|
import { GhHost, parseRepoSlug } from "../publish/gh.js";
|
|
34
36
|
import { resolveIgnoredAuthors } from "../respond/authors.js";
|
|
@@ -68,6 +70,27 @@ function makeLogger(streams, secrets) {
|
|
|
68
70
|
warn: (message) => streams.err(`${redactSecrets(message, secrets)}\n`),
|
|
69
71
|
};
|
|
70
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* `watch`'s logger: everything `makeLogger` does, plus a redacted copy of
|
|
75
|
+
* every line appended to this repo's rolling watch log (`src/loop/tick-log.ts`),
|
|
76
|
+
* so the dashboard has something to show for a daemon it has no live
|
|
77
|
+
* connection to. `ghostrail run` and a standalone respond/triage pass keep
|
|
78
|
+
* using the plain logger: only the watch loop is what the dashboard's log
|
|
79
|
+
* section is about.
|
|
80
|
+
*/
|
|
81
|
+
function watchLogger(streams, secrets, dir) {
|
|
82
|
+
const base = makeLogger(streams, secrets);
|
|
83
|
+
return {
|
|
84
|
+
info: (message) => {
|
|
85
|
+
base.info(message);
|
|
86
|
+
void appendLog(dir, redactSecrets(message, secrets));
|
|
87
|
+
},
|
|
88
|
+
warn: (message) => {
|
|
89
|
+
base.warn(message);
|
|
90
|
+
void appendLog(dir, `WARN ${redactSecrets(message, secrets)}`);
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
}
|
|
71
94
|
/**
|
|
72
95
|
* The effective `ghostrail.toml` path for a repo: the repo's own file if it
|
|
73
96
|
* has one, else wherever its `.ghostrail-config` pointer file names, else
|
|
@@ -302,7 +325,7 @@ export async function cmdWatch(argv, streams, env = process.env, cwd = process.c
|
|
|
302
325
|
const onSignal = () => controller.abort();
|
|
303
326
|
process.once("SIGINT", onSignal);
|
|
304
327
|
process.once("SIGTERM", onSignal);
|
|
305
|
-
const logger =
|
|
328
|
+
const logger = watchLogger(streams, setup.secrets, setup.stateDir);
|
|
306
329
|
const passes = schedulablePasses(setup, streams);
|
|
307
330
|
streams.err(`watching every ${watch.intervalLabel}${describeSchedule(passes)}; press Ctrl-C to stop\n`);
|
|
308
331
|
try {
|
|
@@ -340,6 +363,15 @@ export async function cmdWatch(argv, streams, env = process.env, cwd = process.c
|
|
|
340
363
|
if (pass !== "fix")
|
|
341
364
|
lastRunAt[pass] = Date.now();
|
|
342
365
|
}
|
|
366
|
+
// Best-effort and for display only (specs/dashboard-log.spec.md): the
|
|
367
|
+
// dashboard's countdown reads this back, but nothing here depends on
|
|
368
|
+
// it, so a write failure must not touch the loop.
|
|
369
|
+
try {
|
|
370
|
+
await writeNextTickAt(setup.stateDir, Date.now() + watch.intervalMs);
|
|
371
|
+
}
|
|
372
|
+
catch {
|
|
373
|
+
// the countdown is a convenience, not something the loop depends on
|
|
374
|
+
}
|
|
343
375
|
},
|
|
344
376
|
});
|
|
345
377
|
streams.err(`stopped after ${ticks} tick(s)\n`);
|
|
@@ -1192,6 +1224,12 @@ async function ghostrailName(repo) {
|
|
|
1192
1224
|
* as it is, because re-running `init --update` must not switch `watch` back on
|
|
1193
1225
|
* for a ghostrail the operator deliberately turned off.
|
|
1194
1226
|
*
|
|
1227
|
+
* `options.repoint` gates the one case that is an act, not an add: an entry
|
|
1228
|
+
* that already has an identity, pointing at a checkout other than this one.
|
|
1229
|
+
* Off by default, an existing entry is reported and left alone rather than
|
|
1230
|
+
* rewritten, so a second clone of a registered repo cannot silently steal the
|
|
1231
|
+
* entry that governs what `start` runs unattended (TJ-1652).
|
|
1232
|
+
*
|
|
1195
1233
|
* Never fails the command. Scaffolding the repo is the job; registering it is a
|
|
1196
1234
|
* convenience, and aborting a good scaffold over an unwritable config dir would
|
|
1197
1235
|
* be the worse trade.
|
|
@@ -1241,11 +1279,11 @@ async function prepareState(repo, config, env, streams) {
|
|
|
1241
1279
|
streams.err(`${note}\n`);
|
|
1242
1280
|
return { dir: state.dir, repoId: state.repoId };
|
|
1243
1281
|
}
|
|
1244
|
-
async function registerGhostrail(repo, env, streams,
|
|
1282
|
+
async function registerGhostrail(repo, env, streams, options = {}) {
|
|
1245
1283
|
const store = globalStoreFor(env);
|
|
1246
1284
|
const path = resolve(repo);
|
|
1247
1285
|
try {
|
|
1248
|
-
if (
|
|
1286
|
+
if (options.forceRegister !== true && (await isTempPath(path, env))) {
|
|
1249
1287
|
// `watch` defaults to true and, for a repo with no remote, `path` is the
|
|
1250
1288
|
// identity: registering here would switch on a service unit pointed at a
|
|
1251
1289
|
// directory that is going to vanish. Scaffolding still happened; only the
|
|
@@ -1261,12 +1299,27 @@ async function registerGhostrail(repo, env, streams, forceRegister = false) {
|
|
|
1261
1299
|
const repoId = await resolveRepoId(path);
|
|
1262
1300
|
const existing = await findForRepoResolving(entries, repoId, path, resolveRepoId);
|
|
1263
1301
|
if (existing !== undefined) {
|
|
1302
|
+
if (existing.repo === repoId && existing.path === path)
|
|
1303
|
+
return;
|
|
1304
|
+
// An entry that already has an identity, at a *different* path than this
|
|
1305
|
+
// checkout, is a deliberate repoint, not a migration. `--update` promises
|
|
1306
|
+
// to write only what it can prove is safe everywhere else, and moving the
|
|
1307
|
+
// entry that governs what `start` runs unattended is a far bigger act
|
|
1308
|
+
// than anything else it does, so it never happens as a side effect of
|
|
1309
|
+
// asking for template changes. Report it and leave the registry alone,
|
|
1310
|
+
// the way a stale entry is already reported rather than pruned.
|
|
1311
|
+
if (existing.repo !== undefined && options.repoint !== true) {
|
|
1312
|
+
streams.out(`this repo already has the ghostrail "${existing.name}", registered at a different checkout
|
|
1313
|
+
registered: ${existing.path}
|
|
1314
|
+
this one: ${path}
|
|
1315
|
+
\`ghostrail ls\` lists it; re-run with --repoint to point it here instead
|
|
1316
|
+
`);
|
|
1317
|
+
return;
|
|
1318
|
+
}
|
|
1264
1319
|
// Everything the entry already carries survives, `watch` above all:
|
|
1265
1320
|
// re-registering must never switch a ghostrail back on that the operator
|
|
1266
1321
|
// deliberately turned off.
|
|
1267
1322
|
const adopted = { ...existing, repo: repoId, path };
|
|
1268
|
-
if (existing.repo === repoId && existing.path === path)
|
|
1269
|
-
return;
|
|
1270
1323
|
// By the entry's *old* key: adopting an identity re-keys it, so an
|
|
1271
1324
|
// ordinary upsert would append beside it rather than replace it.
|
|
1272
1325
|
await store.writeRegistry(replaceEntry(entries, entryKey(existing), adopted));
|
|
@@ -1333,7 +1386,7 @@ async function promptPathsAt(configPath) {
|
|
|
1333
1386
|
* the template gained, which is what every hand port consisted of before
|
|
1334
1387
|
* regions existed, and the skill places them in the repo's own wording.
|
|
1335
1388
|
*/
|
|
1336
|
-
async function applyTemplateUpdate(template, srcDir, repo, streams, env,
|
|
1389
|
+
async function applyTemplateUpdate(template, srcDir, repo, streams, env, options) {
|
|
1337
1390
|
const manifest = await readManifest(repo);
|
|
1338
1391
|
const rels = await scaffoldFiles(srcDir);
|
|
1339
1392
|
const templatePrompts = (await promptPathsAt(join(srcDir, "ghostrail.toml"))) ?? {};
|
|
@@ -1458,7 +1511,10 @@ async function applyTemplateUpdate(template, srcDir, repo, streams, env, registe
|
|
|
1458
1511
|
if (Object.keys(written).length > 0 || Object.keys(writtenRegions).length > 0) {
|
|
1459
1512
|
await writeManifest(repo, mergeManifest(manifest, template, VERSION, written, writtenRegions));
|
|
1460
1513
|
}
|
|
1461
|
-
await registerGhostrail(repo, env, streams,
|
|
1514
|
+
await registerGhostrail(repo, env, streams, {
|
|
1515
|
+
repoint: options.repoint,
|
|
1516
|
+
forceRegister: options.register,
|
|
1517
|
+
});
|
|
1462
1518
|
streams.out("\n");
|
|
1463
1519
|
if (took > 0)
|
|
1464
1520
|
streams.out(`took ${took} file(s) you had not edited\n`);
|
|
@@ -1502,7 +1558,8 @@ async function removeLocalScaffold(repo, rels) {
|
|
|
1502
1558
|
}
|
|
1503
1559
|
}
|
|
1504
1560
|
/**
|
|
1505
|
-
* `ghostrail init <template> [--repo <path>] [--force|--diff|--update|--greenroom
|
|
1561
|
+
* `ghostrail init <template> [--repo <path>] [--force|--diff|--update|--greenroom
|
|
1562
|
+
* [<path>]] [--register] [--repoint]`:
|
|
1506
1563
|
* scaffold `ghostrail.toml` and `prompts/` from a quickstart template. Safe for
|
|
1507
1564
|
* a fresh OR an existing repo: existing files are left untouched (skipped)
|
|
1508
1565
|
* unless `--force` is given. `--diff` reports drift instead of writing
|
|
@@ -1514,6 +1571,11 @@ async function removeLocalScaffold(repo, rels) {
|
|
|
1514
1571
|
*
|
|
1515
1572
|
* Registration is skipped, not just the write, when the target looks like a
|
|
1516
1573
|
* temp directory (TJ-1654); `--register` registers it anyway.
|
|
1574
|
+
*
|
|
1575
|
+
* `--repoint` opts into the one registry write that is an act rather than an
|
|
1576
|
+
* add: moving an already-registered ghostrail's entry to this checkout when it
|
|
1577
|
+
* is currently pointing somewhere else. Without it, that mismatch is reported
|
|
1578
|
+
* and the registry is left alone (TJ-1652).
|
|
1517
1579
|
*/
|
|
1518
1580
|
export async function cmdInit(argv, streams, cwd = process.cwd(), env = process.env) {
|
|
1519
1581
|
let template;
|
|
@@ -1521,6 +1583,7 @@ export async function cmdInit(argv, streams, cwd = process.cwd(), env = process.
|
|
|
1521
1583
|
let force = false;
|
|
1522
1584
|
let diff = false;
|
|
1523
1585
|
let update = false;
|
|
1586
|
+
let repoint = false;
|
|
1524
1587
|
let register = false;
|
|
1525
1588
|
let greenroom = false;
|
|
1526
1589
|
let greenroomPath;
|
|
@@ -1540,6 +1603,9 @@ export async function cmdInit(argv, streams, cwd = process.cwd(), env = process.
|
|
|
1540
1603
|
else if (arg === "--update") {
|
|
1541
1604
|
update = true;
|
|
1542
1605
|
}
|
|
1606
|
+
else if (arg === "--repoint") {
|
|
1607
|
+
repoint = true;
|
|
1608
|
+
}
|
|
1543
1609
|
else if (arg === "--register") {
|
|
1544
1610
|
register = true;
|
|
1545
1611
|
}
|
|
@@ -1555,7 +1621,7 @@ export async function cmdInit(argv, streams, cwd = process.cwd(), env = process.
|
|
|
1555
1621
|
}
|
|
1556
1622
|
}
|
|
1557
1623
|
if (template === undefined || !TEMPLATES.includes(template)) {
|
|
1558
|
-
streams.err(`usage: ghostrail init <template> [--repo <path>] [--force|--diff|--update|--greenroom [<path>]] [--register]\ntemplates: ${TEMPLATES.join(", ")}\n`);
|
|
1624
|
+
streams.err(`usage: ghostrail init <template> [--repo <path>] [--force|--diff|--update|--greenroom [<path>]] [--register] [--repoint]\ntemplates: ${TEMPLATES.join(", ")}\n`);
|
|
1559
1625
|
return 1;
|
|
1560
1626
|
}
|
|
1561
1627
|
if (diff && force) {
|
|
@@ -1578,7 +1644,10 @@ export async function cmdInit(argv, streams, cwd = process.cwd(), env = process.
|
|
|
1578
1644
|
const srcDir = join(templatesDir(), template);
|
|
1579
1645
|
if (update) {
|
|
1580
1646
|
try {
|
|
1581
|
-
return await applyTemplateUpdate(template, srcDir, repo, streams, env,
|
|
1647
|
+
return await applyTemplateUpdate(template, srcDir, repo, streams, env, {
|
|
1648
|
+
repoint,
|
|
1649
|
+
register,
|
|
1650
|
+
});
|
|
1582
1651
|
}
|
|
1583
1652
|
catch (error) {
|
|
1584
1653
|
streams.err(`init --update failed: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
@@ -1669,7 +1738,7 @@ export async function cmdInit(argv, streams, cwd = process.cwd(), env = process.
|
|
|
1669
1738
|
streams.out("this repo's config and prompts now live outside it; keep that pointer file out of\n" +
|
|
1670
1739
|
"version control (it is host-specific), the same as .ghostrail.env\n");
|
|
1671
1740
|
}
|
|
1672
|
-
await registerGhostrail(repo, env, streams, register);
|
|
1741
|
+
await registerGhostrail(repo, env, streams, { repoint, forceRegister: register });
|
|
1673
1742
|
streams.out(await initNextStepsHint(env, cwd));
|
|
1674
1743
|
return 0;
|
|
1675
1744
|
}
|