rvlib-shipkit 1.4.0 → 1.6.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/CHANGELOG.md +114 -0
- package/README.md +17 -17
- package/package.json +3 -2
- package/src/assets/gen/comfyts-gen.ts +12 -8
- package/src/assets/server/studio-server.ts +14 -2
- package/src/check.ts +73 -103
- package/src/checks/SK001-package-json-shape.check.ts +11 -6
- package/src/checks/SK002-contracts-fulfillness.check.ts +4 -0
- package/src/checks/SK003-claude-md-shape.check.ts +7 -3
- package/src/checks/SK004-gitignore-policy.check.ts +7 -4
- package/src/checks/SK005-rvlib-versions.check.ts +53 -21
- package/src/checks/SK006-npm-publish-safety.check.ts +4 -0
- package/src/checks/SK007-github-visibility.check.ts +4 -2
- package/src/checks/SK008-reviewer-agent.check.ts +6 -4
- package/src/checks/SK009-commit-ai-tells.check.ts +4 -2
- package/src/checks/SK010-undeclared-unit.check.ts +4 -0
- package/src/checks/SK011-sibling-unit-ranges.check.ts +4 -0
- package/src/checks/SK012-config-barrel-import.check.ts +5 -1
- package/src/checks/SK013-one-way-in-policy.check.ts +7 -3
- package/src/checks/SK014-prose-ste.check.ts +4 -0
- package/src/checks/SK015-nested-repo.check.ts +4 -2
- package/src/checks/SK016-legacy-check-shapes.check.ts +13 -12
- package/src/checks/SK017-vscode-hub-task.check.ts +22 -7
- package/src/checks/SK018-test-files-run.check.ts +6 -2
- package/src/checks/SK019-tests-run-in-units.check.ts +8 -4
- package/src/checks/SK020-self-spawning-check.check.ts +4 -0
- package/src/checks/SK022-machine-runs-the-pin.check.ts +6 -4
- package/src/checks/SK024-identity-colors.check.ts +5 -3
- package/src/checks/SK025-release-drift.check.ts +4 -5
- package/src/checks/SK026-asks-autoclose.check.ts +4 -4
- package/src/checks/SK027-agent-wiki-links.check.ts +4 -1
- package/src/checks/SK028-readme.check.ts +5 -1
- package/src/checks/SK029-explicit-check-files.check.ts +95 -0
- package/src/checks/SK030-cache-audit.check.ts +34 -0
- package/src/checks/SK031-trace-audit.check.ts +39 -0
- package/src/checks/SK032-ignored-inputs.check.ts +79 -0
- package/src/cli/cmd_Asks.ts +5 -5
- package/src/cli/cmd_Assets.ts +17 -13
- package/src/cli/cmd_Bump.ts +12 -11
- package/src/cli/cmd_CacheAudit.ts +43 -0
- package/src/cli/cmd_Check.ts +8 -7
- package/src/cli/cmd_Checks.ts +7 -6
- package/src/cli/cmd_Ci.ts +12 -11
- package/src/cli/cmd_Commands.ts +16 -13
- package/src/cli/cmd_ConfigKeys.ts +7 -6
- package/src/cli/cmd_Contracts.ts +3 -3
- package/src/cli/cmd_CrossRepoActivity.ts +8 -6
- package/src/cli/cmd_Fleet.ts +9 -7
- package/src/cli/cmd_GlobalProcesses.ts +120 -7
- package/src/cli/cmd_Home.ts +26 -19
- package/src/cli/cmd_Hooks.ts +6 -5
- package/src/cli/cmd_Init.ts +5 -4
- package/src/cli/cmd_Keys.ts +20 -8
- package/src/cli/cmd_Mv.ts +7 -6
- package/src/cli/cmd_Needs.ts +4 -3
- package/src/cli/cmd_Overview.ts +5 -4
- package/src/cli/cmd_Pb.ts +2 -2
- package/src/cli/cmd_Planned.ts +6 -5
- package/src/cli/cmd_Prose.ts +5 -5
- package/src/cli/cmd_Reflect.ts +7 -7
- package/src/cli/cmd_Release.ts +6 -5
- package/src/cli/cmd_Releases.ts +5 -4
- package/src/cli/cmd_Serve.ts +6 -4
- package/src/cli/cmd_Smoke.ts +5 -4
- package/src/cli/cmd_Start.ts +7 -6
- package/src/cli/cmd_Status.ts +4 -3
- package/src/cli/cmd_TraceAudit.ts +62 -0
- package/src/cli/cmd_Tui.ts +3 -2
- package/src/cli/cmd_When.ts +71 -0
- package/src/cli/cmd_Wiki.ts +4 -4
- package/src/cli.ts +11 -2
- package/src/collections/checks.ts +2 -0
- package/src/collections/collection-types.ts +12 -4
- package/src/collections/providers.ts +5 -3
- package/src/core/app-icon.ts +154 -0
- package/src/core/audit-report.ts +21 -0
- package/src/core/cache-audit.ts +72 -0
- package/src/core/canonical-scripts.ts +2 -2
- package/src/core/check-ctx.ts +14 -5
- package/src/core/check-runner.ts +43 -23
- package/src/core/config-rewrite.ts +37 -24
- package/src/core/discover-checks.ts +23 -2
- package/src/core/floor-resolve.ts +5 -7
- package/src/core/git-root.ts +13 -0
- package/src/core/ignored-block.ts +94 -0
- package/src/core/ignored-inputs.ts +47 -0
- package/src/core/jobs.ts +9 -2
- package/src/core/legacy-shapes.ts +39 -10
- package/src/core/one-lib.ts +59 -4
- package/src/core/one-way-in-policy.ts +2 -2
- package/src/core/outcome-words.ts +18 -2
- package/src/core/port-check-cli.ts +52 -0
- package/src/core/port-check-file.ts +295 -0
- package/src/core/port-check-files.ts +31 -0
- package/src/core/read-set.ts +97 -9
- package/src/core/retention.ts +0 -14
- package/src/core/run-check.ts +12 -9
- package/src/core/run-ci.ts +14 -5
- package/src/core/run-fix.ts +30 -23
- package/src/core/run-fixers.ts +48 -5
- package/src/core/runs-matrix.ts +179 -0
- package/src/core/runs.ts +242 -0
- package/src/core/trace-audit.ts +120 -0
- package/src/core/update-policy.ts +20 -0
- package/src/core/when-block.ts +29 -30
- package/src/core/when.ts +41 -103
- package/src/core/wire.ts +10 -14
- package/src/fleet/scan-fleet.ts +20 -4
- package/src/fleet/update-fleet.ts +6 -6
- package/src/home/gui-app.ts +24 -27
- package/src/home/home-launchd.ts +20 -4
- package/src/home/home-routes.ts +12 -1
- package/src/home/home-start.ts +11 -5
- package/src/home/hubs.ts +5 -5
- package/src/home/open-app.ts +2 -2
- package/src/home/pm.ts +8 -0
- package/src/home/run-pm.ts +1 -0
- package/src/home/serve-web.ts +2 -2
- package/src/home/supervise.ts +24 -1
- package/src/home/via-hub.ts +14 -0
- package/src/hooks/run-hooks.ts +48 -4
- package/src/init-repo.ts +6 -6
- package/src/ledger/db.ts +2 -13
- package/src/ledger/gate-checks.ts +133 -61
- package/src/ledger/git-key.ts +153 -31
- package/src/ledger/git-scan.ts +5 -2
- package/src/ledger/ledger.ts +136 -21
- package/src/ledger/store.ts +14 -0
- package/src/ledger/toolchain-identity.ts +248 -45
- package/src/plan/repo-source.ts +18 -39
- package/src/problems/extract.ts +3 -0
- package/src/release/run-release.ts +5 -0
- package/src/repo-config.ts +46 -54
- package/src/rules/rule.ts +2 -2
- package/src/scaffold/files/agent-coding.md +1 -1
- package/src/scaffold/files/agent-index.md +1 -1
- package/src/scaffold/files/verify-skill.md +2 -2
- package/src/serve/hub-app/activity-st.ts +5 -4
- package/src/serve/hub-app/activity-view.tsx +1 -1
- package/src/serve/hub-app/admin-svc.ts +36 -3
- package/src/serve/hub-app/admin-view.tsx +46 -12
- package/src/serve/hub-app/check-view.tsx +66 -46
- package/src/serve/hub-app/check-words.ts +1 -11
- package/src/serve/hub-app/checks-svc.ts +14 -35
- package/src/serve/hub-app/col-card.tsx +1 -44
- package/src/serve/hub-app/col-tables-view.tsx +84 -11
- package/src/serve/hub-app/col-tables.ts +27 -0
- package/src/serve/hub-app/cols-svc.ts +5 -4
- package/src/serve/hub-app/dock-st.ts +3 -2
- package/src/serve/hub-app/dock-view.tsx +36 -0
- package/src/serve/hub-app/dock.css +6 -0
- package/src/serve/hub-app/float-cards.tsx +30 -0
- package/src/serve/hub-app/floating.tsx +41 -4
- package/src/serve/hub-app/git-st.ts +42 -0
- package/src/serve/hub-app/git-view.tsx +61 -0
- package/src/serve/hub-app/hash-route.ts +45 -1
- package/src/serve/hub-app/header-bar.tsx +62 -72
- package/src/serve/hub-app/health-svc.ts +3 -2
- package/src/serve/hub-app/home-st.ts +14 -2
- package/src/serve/hub-app/home-strip.css +43 -12
- package/src/serve/hub-app/home-strip.tsx +115 -64
- package/src/serve/hub-app/home.html +1 -0
- package/src/serve/hub-app/hub-app.tsx +32 -8
- package/src/serve/hub-app/hub-types.ts +5 -2
- package/src/serve/hub-app/hub.css +89 -63
- package/src/serve/hub-app/icons.tsx +11 -0
- package/src/serve/hub-app/index.html +1 -0
- package/src/serve/hub-app/keys.ts +15 -4
- package/src/serve/hub-app/live-svc.ts +3 -2
- package/src/serve/hub-app/machine-st.ts +18 -22
- package/src/serve/hub-app/plan-view.tsx +51 -0
- package/src/serve/hub-app/planned-st.ts +9 -4
- package/src/serve/hub-app/processes-view.tsx +45 -0
- package/src/serve/hub-app/project-list.css +4 -1
- package/src/serve/hub-app/project-list.tsx +6 -3
- package/src/serve/hub-app/projects-svc.ts +25 -10
- package/src/serve/hub-app/prose-hits-st.ts +3 -2
- package/src/serve/hub-app/reach.ts +36 -0
- package/src/serve/hub-app/readme-svc.ts +3 -2
- package/src/serve/hub-app/repo-sections.ts +131 -0
- package/src/serve/hub-app/repo-st.ts +70 -14
- package/src/serve/hub-app/sidebar.tsx +17 -42
- package/src/serve/hub-app/timeline-svc.ts +3 -2
- package/src/serve/hub-app/tree-build.ts +151 -155
- package/src/serve/hub-app/tree-row.tsx +55 -12
- package/src/serve/hub-app/tree-svc.ts +97 -56
- package/src/serve/hub-app/when-view.tsx +89 -0
- package/src/serve/hub-app/when.css +17 -0
- package/src/serve/hub-runtime.ts +7 -18
- package/src/serve/project-gutter-route.ts +22 -1
- package/src/serve/run-serve.ts +1 -1
- package/src/serve/serve-hub.ts +4 -14
- package/src/suite/judge-suites.ts +6 -0
- package/src/trace/interpose.c +655 -0
- package/src/trace/read-trace.ts +485 -0
- package/src/trace/tracer.ts +282 -0
- package/src/serve/hub-app/processes-svc.ts +0 -63
- package/src/serve/hub-app/repo-sections.tsx +0 -61
- package/src/serve/repo-processes.ts +0 -89
package/src/cli/cmd_Keys.ts
CHANGED
|
@@ -19,14 +19,15 @@ export class KeysCommand extends Command {
|
|
|
19
19
|
|
|
20
20
|
static override usage = Command.Usage({
|
|
21
21
|
category: 'Health',
|
|
22
|
-
description: 'the cache key of every gate check, and
|
|
22
|
+
description: 'the cache key of every gate check, and why the others have none',
|
|
23
|
+
details: 'the cache key of every gate check, and the reason the undeclared ones have none. Reports, never gates',
|
|
23
24
|
examples: [
|
|
24
|
-
['every check and its key', '
|
|
25
|
-
['only the ones nothing can cache yet', '
|
|
26
|
-
['why this key is what it is', '
|
|
27
|
-
['re-hash after the fact and report drift', '
|
|
28
|
-
['the keys a --full gate asks for', '
|
|
29
|
-
['machine-readable', '
|
|
25
|
+
['every check and its key', 'sk keys'],
|
|
26
|
+
['only the ones nothing can cache yet', 'sk keys --burn-down'],
|
|
27
|
+
['why this key is what it is', 'sk keys --why typecheck'],
|
|
28
|
+
['re-hash after the fact and report drift', 'sk keys --rescan'],
|
|
29
|
+
['the keys a --full gate asks for', 'sk keys --full'],
|
|
30
|
+
['machine-readable', 'sk keys --json'],
|
|
30
31
|
],
|
|
31
32
|
})
|
|
32
33
|
|
|
@@ -74,6 +75,14 @@ export class KeysCommand extends Command {
|
|
|
74
75
|
return 0
|
|
75
76
|
}
|
|
76
77
|
out(` key ${k.key}`)
|
|
78
|
+
// a lib hash names nothing by itself: the files behind it are what
|
|
79
|
+
// an edit has to touch to move this key
|
|
80
|
+
const lib = k.libFiles ?? []
|
|
81
|
+
if (lib.length > 0) {
|
|
82
|
+
out(` toolkit files in its lib components: ${lib.length}`)
|
|
83
|
+
for (const f of lib.slice(0, 12)) out(` ${f}`)
|
|
84
|
+
if (lib.length > 12) out(` … ${lib.length - 12} more (shipkit keys --json)`)
|
|
85
|
+
}
|
|
77
86
|
if (k.population === 'reads') {
|
|
78
87
|
for (const comp of k.components) out(` ${comp}`)
|
|
79
88
|
// the rest of its identity is what it READ, stored with the
|
|
@@ -88,12 +97,15 @@ export class KeysCommand extends Command {
|
|
|
88
97
|
const lists = Object.entries(set.lists)
|
|
89
98
|
const dirs = Object.entries(set.dirs ?? {})
|
|
90
99
|
const links = Object.entries(set.links ?? {})
|
|
91
|
-
|
|
100
|
+
// outside the repo a traced read is keyed on stat alone
|
|
101
|
+
const outside = Object.keys(set.sigs ?? {}).filter((p) => !(p in set.files))
|
|
102
|
+
out(` read set: ${files.length} file(s), ${exists.length} existence probe(s), ${lists.length} listing(s), ${dirs.length} dir read(s)${links.length > 0 ? `, ${links.length} link probe(s)` : ''}${outside.length > 0 ? `, ${outside.length} file(s) outside the repo, by stat` : ''}`)
|
|
92
103
|
for (const [p, oid] of files) out(` read ${p}=${oid ?? 'absent'}`)
|
|
93
104
|
for (const [p, kind] of exists) out(` exists ${p}=${kind ?? 'absent'}`)
|
|
94
105
|
for (const [g, h] of lists) out(` list ${g}=${h}`)
|
|
95
106
|
for (const [d, h] of dirs) out(` entries ${d}=${h ?? 'absent'}`)
|
|
96
107
|
for (const [p, is] of links) out(` link ${p}=${is ? 'yes' : 'no'}`)
|
|
108
|
+
for (const p of outside) out(` stat ${p}=${set.sigs![p]}`)
|
|
97
109
|
return 0
|
|
98
110
|
}
|
|
99
111
|
// the excluded block is 44 lines here and it buries the component
|
package/src/cli/cmd_Mv.ts
CHANGED
|
@@ -12,13 +12,14 @@ export class MvCommand extends Command {
|
|
|
12
12
|
|
|
13
13
|
static override usage = Command.Usage({
|
|
14
14
|
category: 'Refactor',
|
|
15
|
-
description: 'rename
|
|
15
|
+
description: 'rename a file, folder or md page and rewrite every reference (dry run by default)',
|
|
16
|
+
details: 'rename anything and sweep every reference: an md page (plus its sibling dir and its check file) or a code file or folder. Dry run by default. Renames must be CHEAP',
|
|
16
17
|
examples: [
|
|
17
|
-
['dry run, the default, shows what changes', '
|
|
18
|
-
['apply it', '
|
|
19
|
-
['apply + one conventional commit', '
|
|
20
|
-
['a code file, every import rewritten', '
|
|
21
|
-
['a whole folder', '
|
|
18
|
+
['dry run, the default, shows what changes', 'sk mv docs/old-name.md docs/new-name.md'],
|
|
19
|
+
['apply it', 'sk mv docs/old-name.md docs/new-name.md --write'],
|
|
20
|
+
['apply + one conventional commit', 'sk mv docs/old-name.md docs/new-name.md --commit'],
|
|
21
|
+
['a code file, every import rewritten', 'sk mv src/old-mod.ts src/new-mod.ts --write'],
|
|
22
|
+
['a whole folder', 'sk mv src/old-dir src/new-dir --write'],
|
|
22
23
|
],
|
|
23
24
|
})
|
|
24
25
|
|
package/src/cli/cmd_Needs.ts
CHANGED
|
@@ -12,10 +12,11 @@ export class NeedsCommand extends Command {
|
|
|
12
12
|
|
|
13
13
|
static override usage = Command.Usage({
|
|
14
14
|
category: 'Health',
|
|
15
|
-
description: 'everything blocked on a human,
|
|
15
|
+
description: 'everything blocked on a human, by collection. Report only',
|
|
16
|
+
details: 'everything blocked on a human, red/yellow by collection — report-only, exit 0 always (check/ci are the gates)',
|
|
16
17
|
examples: [
|
|
17
|
-
['what needs me', '
|
|
18
|
-
['machine-readable (agents, drills, cross-repo rollups)', '
|
|
18
|
+
['what needs me', 'sk needs'],
|
|
19
|
+
['machine-readable (agents, drills, cross-repo rollups)', 'sk needs --json'],
|
|
19
20
|
],
|
|
20
21
|
})
|
|
21
22
|
|
package/src/cli/cmd_Overview.ts
CHANGED
|
@@ -77,17 +77,18 @@ export class OverviewCommand extends Command {
|
|
|
77
77
|
|
|
78
78
|
static override usage = Command.Usage({
|
|
79
79
|
category: 'Home',
|
|
80
|
-
description: 'the overview page
|
|
80
|
+
description: 'the overview page as text: the widgets, then every process',
|
|
81
|
+
details: 'the overview page in the console: every monitor widget as text, from the html the daemon last rendered, then the processes as `shipkit gp` prints them (pm, the daemon and the web with pid, uptime and version, then every global process). When pm or the daemon does not answer, it says which and prints what is still known. Always exits 0',
|
|
81
82
|
examples: [
|
|
82
|
-
['the overview', '
|
|
83
|
-
['the answers the page reads, as json', '
|
|
83
|
+
['the overview', 'sk overview'],
|
|
84
|
+
['the answers the page reads, as json', 'sk overview --json'],
|
|
84
85
|
],
|
|
85
86
|
})
|
|
86
87
|
|
|
87
88
|
json = Option.Boolean('--json', false, { description: 'the answers as json: { now, pm, daemon, processes, widgets }, processes as `shipkit gp --json`, widgets the daemon route\'s payload' })
|
|
88
89
|
|
|
89
90
|
async execute(): Promise<number> {
|
|
90
|
-
const a = await overviewAnswer({ ...localProcessDeps(process.cwd()), pm: () => askPm(), daemon: () => askDaemon(), widgets: () => askWidgets(), now: Date.now() })
|
|
91
|
+
const a = await overviewAnswer({ ...(await localProcessDeps(process.cwd())), pm: () => askPm(), daemon: () => askDaemon(), widgets: () => askWidgets(), now: Date.now() })
|
|
91
92
|
if (this.json) {
|
|
92
93
|
this.context.stdout.write(`${JSON.stringify(a, null, 2)}\n`)
|
|
93
94
|
return 0
|
package/src/cli/cmd_Pb.ts
CHANGED
|
@@ -10,8 +10,8 @@ export class PbCollectionCommand extends Command {
|
|
|
10
10
|
category: 'Scaffold',
|
|
11
11
|
description: "a collection's CRUD UI folder from the app's generated pb types: columns, card, grid, form, index",
|
|
12
12
|
examples: [
|
|
13
|
-
['see the whole folder before it exists', '
|
|
14
|
-
['write src/collections/orders/', '
|
|
13
|
+
['see the whole folder before it exists', 'sk pb collection orders --dry-run'],
|
|
14
|
+
['write src/collections/orders/', 'sk pb collection orders'],
|
|
15
15
|
],
|
|
16
16
|
})
|
|
17
17
|
|
package/src/cli/cmd_Planned.ts
CHANGED
|
@@ -78,12 +78,13 @@ export class PlannedCommand extends Command {
|
|
|
78
78
|
|
|
79
79
|
static override usage = Command.Usage({
|
|
80
80
|
category: 'Home',
|
|
81
|
-
description: 'the
|
|
81
|
+
description: 'the plan as text: every check the machine runs on its own time',
|
|
82
|
+
details: 'the planned page in the console: every check the machine runs on its own time, running now, then next, each with its repo, check and title, when, the rule that planned it and its last result. Asks the daemon, which holds the plan. With the daemon down it says so and exits 0',
|
|
82
83
|
examples: [
|
|
83
|
-
['the plan, as the page lists it', '
|
|
84
|
-
['one repo only', '
|
|
85
|
-
['also the checks that only a save runs', '
|
|
86
|
-
['the route\'s exact payload', '
|
|
84
|
+
['the plan, as the page lists it', 'sk planned'],
|
|
85
|
+
['one repo only', 'sk planned --repo my-app'],
|
|
86
|
+
['also the checks that only a save runs', 'sk planned --all'],
|
|
87
|
+
['the route\'s exact payload', 'sk planned --json'],
|
|
87
88
|
],
|
|
88
89
|
})
|
|
89
90
|
|
package/src/cli/cmd_Prose.ts
CHANGED
|
@@ -13,11 +13,11 @@ export class ProseCommand extends Command {
|
|
|
13
13
|
category: 'Health',
|
|
14
14
|
description: 'STE prose check (identity/writing-voice.md): mechanical fixes, hard violations, soft warnings',
|
|
15
15
|
examples: [
|
|
16
|
-
['every file this repo declares as prose', '
|
|
17
|
-
['one file while drafting', '
|
|
18
|
-
['apply every mechanical rewrite', '
|
|
19
|
-
['the procedural 20-word limit', '
|
|
20
|
-
['machine-readable', '
|
|
16
|
+
['every file this repo declares as prose', 'sk prose'],
|
|
17
|
+
['one file while drafting', 'sk prose wiki/build/shipkit.md'],
|
|
18
|
+
['apply every mechanical rewrite', 'sk prose --fix'],
|
|
19
|
+
['the procedural 20-word limit', 'sk prose --strict'],
|
|
20
|
+
['machine-readable', 'sk prose --json'],
|
|
21
21
|
],
|
|
22
22
|
})
|
|
23
23
|
|
package/src/cli/cmd_Reflect.ts
CHANGED
|
@@ -17,14 +17,14 @@ export class ReflectCommand extends Command {
|
|
|
17
17
|
|
|
18
18
|
static override usage = Command.Usage({
|
|
19
19
|
category: 'Health',
|
|
20
|
-
description:
|
|
21
|
-
|
|
20
|
+
description: "the user's prompts across every Claude Code session of a repo, as a corpus",
|
|
21
|
+
details: "the user's typed prompts across every Claude Code session of a repo — chronological md corpus for retrospectives",
|
|
22
22
|
examples: [
|
|
23
|
-
['corpus for the current repo', '
|
|
24
|
-
['corpus for other repos', '
|
|
25
|
-
['drop the long pastes', '
|
|
26
|
-
['batch to files instead of stdout', '
|
|
27
|
-
['machine-readable', '
|
|
23
|
+
['corpus for the current repo', 'sk reflect'],
|
|
24
|
+
['corpus for other repos', 'sk reflect ~/dev/one-repo ~/dev/another-repo'],
|
|
25
|
+
['drop the long pastes', 'sk reflect --short'],
|
|
26
|
+
['batch to files instead of stdout', 'sk reflect ~/dev/a ~/dev/b --out stats'],
|
|
27
|
+
['machine-readable', 'sk reflect --json'],
|
|
28
28
|
],
|
|
29
29
|
})
|
|
30
30
|
|
package/src/cli/cmd_Release.ts
CHANGED
|
@@ -9,12 +9,13 @@ export class ReleaseCommand extends Command {
|
|
|
9
9
|
|
|
10
10
|
static override usage = Command.Usage({
|
|
11
11
|
category: 'Gate',
|
|
12
|
-
description: 'cut a release
|
|
12
|
+
description: 'cut a release of one unit: gate, npm publish, tag, push, GitHub release',
|
|
13
|
+
details: 'cut a release for ONE unit (default the repo root): ci gate → npm publish (non-private only) → git tag → push → GitHub release, notes from that unit CHANGELOG section. Resumable after a partial failure, which is why it takes no --all.',
|
|
13
14
|
examples: [
|
|
14
|
-
['rehearse — touches nothing', '
|
|
15
|
-
['release the version in package.json', '
|
|
16
|
-
['finish a sub-unit bump stopped part way (ids: shipkit releases)', '
|
|
17
|
-
['release with dirt elsewhere in the worktree', '
|
|
15
|
+
['rehearse — touches nothing', 'sk release --dry-run'],
|
|
16
|
+
['release the version in package.json', 'sk release'],
|
|
17
|
+
['finish a sub-unit bump stopped part way (ids: shipkit releases)', 'sk release rvlib-shipkit'],
|
|
18
|
+
['release with dirt elsewhere in the worktree', 'sk release --allow-dirty'],
|
|
18
19
|
],
|
|
19
20
|
})
|
|
20
21
|
|
package/src/cli/cmd_Releases.ts
CHANGED
|
@@ -9,11 +9,12 @@ export class ReleasesCommand extends Command {
|
|
|
9
9
|
|
|
10
10
|
static override usage = Command.Usage({
|
|
11
11
|
category: 'Gate',
|
|
12
|
-
description: 'every unit
|
|
12
|
+
description: 'every release unit and where it stands: version, npm, tags, GitHub',
|
|
13
|
+
details: 'every unit that releases and where it stands: version, npm, tag local and remote, GitHub release, drift. Reports, never gates (only an unresolvable config exits non-zero)',
|
|
13
14
|
examples: [
|
|
14
|
-
['what is published and what is not', '
|
|
15
|
-
['filesystem + local git only, no network', '
|
|
16
|
-
['machine-readable', '
|
|
15
|
+
['what is published and what is not', 'sk releases'],
|
|
16
|
+
['filesystem + local git only, no network', 'sk releases --offline'],
|
|
17
|
+
['machine-readable', 'sk releases --json'],
|
|
17
18
|
],
|
|
18
19
|
})
|
|
19
20
|
|
package/src/cli/cmd_Serve.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
// shipkit serve — the ONE hub server per repo (one vscode folder-open task,
|
|
2
2
|
// clickable URLs). Thin clipanion surface; logic in serve/run-serve.ts.
|
|
3
3
|
import { Command, Option } from 'clipanion'
|
|
4
|
-
import { runServe } from '../serve/run-serve.ts'
|
|
5
4
|
|
|
6
5
|
export class ServeCommand extends Command {
|
|
7
6
|
static override paths = [['serve']]
|
|
8
7
|
|
|
9
8
|
static override usage = Command.Usage({
|
|
10
9
|
category: 'Serve',
|
|
11
|
-
description: '
|
|
10
|
+
description: 'the repo hub: one server, one page (assets, asks, creds, posts, health, wikis)',
|
|
11
|
+
details: 'ONE server, ONE page: media studio + asks + creds + posts + health + wikis, each wiki a link graph page',
|
|
12
12
|
examples: [
|
|
13
|
-
['serve the repo toolbox', '
|
|
14
|
-
['pin the port for this launch', '
|
|
13
|
+
['serve the repo toolbox', 'sk serve'],
|
|
14
|
+
['pin the port for this launch', 'sk serve --port 4804'],
|
|
15
15
|
],
|
|
16
16
|
})
|
|
17
17
|
|
|
@@ -26,6 +26,8 @@ export class ServeCommand extends Command {
|
|
|
26
26
|
return 1
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
+
// the hub runtime carries the image tools: loaded when it serves
|
|
30
|
+
const { runServe } = await import('../serve/run-serve.ts')
|
|
29
31
|
return runServe(process.cwd(), {
|
|
30
32
|
print: (l) => this.context.stdout.write(`${l}\n`),
|
|
31
33
|
printErr: (l) => this.context.stderr.write(`${l}\n`),
|
package/src/cli/cmd_Smoke.ts
CHANGED
|
@@ -10,11 +10,12 @@ export class SmokeCommand extends Command {
|
|
|
10
10
|
|
|
11
11
|
static override usage = Command.Usage({
|
|
12
12
|
category: 'Health',
|
|
13
|
-
description: 'browser smoke pass over a deployed web app
|
|
13
|
+
description: 'browser smoke pass over a deployed web app, every declared route',
|
|
14
|
+
details: 'browser smoke pass over a deployed web app: login through the app, visit every declared route, read only, screenshots + console/network problems + host quota. Exit code = failed routes',
|
|
14
15
|
examples: [
|
|
15
|
-
['every route in repo.config smoke, against its base url', '
|
|
16
|
-
['a preview deploy', '
|
|
17
|
-
['two routes only', '
|
|
16
|
+
['every route in repo.config smoke, against its base url', 'sk smoke'],
|
|
17
|
+
['a preview deploy', 'sk smoke --base https://abc123.my-app.pages.dev'],
|
|
18
|
+
['two routes only', 'sk smoke --routes /orders,/clients'],
|
|
18
19
|
],
|
|
19
20
|
})
|
|
20
21
|
|
package/src/cli/cmd_Start.ts
CHANGED
|
@@ -9,13 +9,14 @@ export class StartCommand extends Command {
|
|
|
9
9
|
|
|
10
10
|
static override usage = Command.Usage({
|
|
11
11
|
category: 'Setup',
|
|
12
|
-
description: 'create
|
|
12
|
+
description: 'create or enter ~/dev/<name> from anywhere, ready to work in',
|
|
13
|
+
details: 'create (or enter) ~/dev/<name> from ANY cwd, READY to work in. On any dir with no commit history it writes the day-one shape (package.json + src/index.ts + lint/fmt/typecheck, tsconfig, .vscode tasks + settings, the verify skill, an agent/ wiki, .shipkit/reflections), installs the toolchain, wires shipkit (repo.config.ts via init), and runs the whole bootstrap chain: git init, first commit, PRIVATE github repo, push. Loose files ride in that first commit, and only a repo with real history is left as it is. Writes are create-only for files, additive for package.json scripts and .gitignore. CLAUDE.md is the two-line house template on its own (HOUSE_INCLUDE in src/start-repo.ts: the base wiki include, then `@./agent/index.md`, and --include overrides it), applied only on a machine where the house index exists, and the agent route lands last whenever the repo has agent/index.md. The house lines also opt the repo into the .claude/ policy files (a pre-approved shell allowlist + the attribution silencer), so a start with no house widens no agent permissions. Prints the dir on stdout so a shell alias can cd there. cwd-only sibling: `shipkit init`',
|
|
13
14
|
examples: [
|
|
14
|
-
['create or enter ~/dev/pong: dir, package.json, shipkit wiring, git, first commit, private github repo, push, the two-line CLAUDE.md', '
|
|
15
|
-
['another house: replace the include lines', "
|
|
16
|
-
['adopt a pre-existing repo from anywhere', '
|
|
17
|
-
['force the private github repo for a folder that was already there', '
|
|
18
|
-
['local git and the first commit, never touch github', '
|
|
15
|
+
['create or enter ~/dev/pong: dir, package.json, shipkit wiring, git, first commit, private github repo, push, the two-line CLAUDE.md', 'sk start pong'],
|
|
16
|
+
['another house: replace the include lines', "sk start pong --include '@~/wiki/index.md' --include '@./agent/index.md'"],
|
|
17
|
+
['adopt a pre-existing repo from anywhere', 'sk start my-old-project'],
|
|
18
|
+
['force the private github repo for a folder that was already there', 'sk start old-notes --github'],
|
|
19
|
+
['local git and the first commit, never touch github', 'sk start pong --no-github'],
|
|
19
20
|
],
|
|
20
21
|
})
|
|
21
22
|
|
package/src/cli/cmd_Status.ts
CHANGED
|
@@ -8,10 +8,11 @@ export class StatusCommand extends Command {
|
|
|
8
8
|
|
|
9
9
|
static override usage = Command.Usage({
|
|
10
10
|
category: 'Gate',
|
|
11
|
-
description:
|
|
11
|
+
description: 'the output and verdict of a gate started with `sk ci --detach`',
|
|
12
|
+
details: `a gate started with \`shipkit ci --detach\`: its wire lines so far, then its verdict. Exit code = the gate's own once it finished, ${STILL_RUNNING} while it still runs, 1 when it died without one`,
|
|
12
13
|
examples: [
|
|
13
|
-
['the latest detached run of this checkout', '
|
|
14
|
-
['one run by id', '
|
|
14
|
+
['the latest detached run of this checkout', 'sk status'],
|
|
15
|
+
['one run by id', 'sk status ci-mf3k2a-1x2y'],
|
|
15
16
|
],
|
|
16
17
|
})
|
|
17
18
|
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// sk trace-audit — which gitignored paths each gate task reads that its key
|
|
2
|
+
// cannot see, found by running the task once under the tracer, and with
|
|
3
|
+
// --fix written into repo.config.ts (core/trace-audit.ts).
|
|
4
|
+
import { Command, Option } from 'clipanion'
|
|
5
|
+
import { loadRepoConfig } from '../repo-config.ts'
|
|
6
|
+
import { applyAudit, traceAudit } from '../core/trace-audit.ts'
|
|
7
|
+
import { describeByTask } from '../core/audit-report.ts'
|
|
8
|
+
import { setTraceEnabled } from '../trace/tracer.ts'
|
|
9
|
+
|
|
10
|
+
export class TraceAuditCommand extends Command {
|
|
11
|
+
static override paths = [['trace-audit']]
|
|
12
|
+
|
|
13
|
+
static override usage = Command.Usage({
|
|
14
|
+
category: 'Health',
|
|
15
|
+
description: 'gitignored paths a gate task reads that its key misses, found by tracing it once',
|
|
16
|
+
details: 'Runs each gate task once under the tracer (on by default: --disable for this machine, or SHIPKIT_TRACE=0 for one run) and lists the gitignored paths it read that neither the tracked tree nor repo.config ignoredInputs covers. The answer is kept for about a day under the git common dir, where every worktree reads it, and each finding joins the key of the task that read it at once. --fix writes the findings into the managed block of repo.config.ts, per task, without tracing again. Exit 1 when a key misses something.',
|
|
17
|
+
examples: [
|
|
18
|
+
['audit, reusing a recent answer', 'sk trace-audit'],
|
|
19
|
+
['trace again now', 'sk trace-audit --fresh'],
|
|
20
|
+
['write the proposals into repo.config.ts', 'sk trace-audit --fix'],
|
|
21
|
+
['machine-readable', 'sk trace-audit --json'],
|
|
22
|
+
['stop tracing on this machine', 'sk trace-audit --disable'],
|
|
23
|
+
['trace again, the default', 'sk trace-audit --enable'],
|
|
24
|
+
],
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
fresh = Option.Boolean('--fresh', false, { description: 'trace again even when a recent answer is kept' })
|
|
28
|
+
fix = Option.Boolean('--fix', false, { description: 'write the kept proposals into repo.config.ts ignoredInputs' })
|
|
29
|
+
json = Option.Boolean('--json', false, { description: 'machine-readable report' })
|
|
30
|
+
enable = Option.Boolean('--enable', false, { description: 'turn tracing back on for this machine, the default: the daemon\'s health pass audits about daily (SK031)' })
|
|
31
|
+
disable = Option.Boolean('--disable', false, { description: 'stop tracing on this machine: nothing audits here until --enable' })
|
|
32
|
+
|
|
33
|
+
async execute(): Promise<number> {
|
|
34
|
+
const root = process.cwd()
|
|
35
|
+
const out = (l: string): void => { this.context.stdout.write(`${l}\n`) }
|
|
36
|
+
if (this.enable || this.disable) {
|
|
37
|
+
setTraceEnabled(this.enable)
|
|
38
|
+
out(this.enable ? 'ok: tracing is on for this machine: the health pass audits each repo about daily (SK031)' : 'ok: tracing is off for this machine')
|
|
39
|
+
return 0
|
|
40
|
+
}
|
|
41
|
+
if (this.fix) {
|
|
42
|
+
let r: Awaited<ReturnType<typeof applyAudit>>
|
|
43
|
+
// a config the block writer refuses (a hand edit, a key declared
|
|
44
|
+
// outside the markers) is an answer for a human, never a crash
|
|
45
|
+
try { r = await applyAudit(root) } catch (e) { out(`FAIL: ${(e as Error).message}`); return 1 }
|
|
46
|
+
if (r.note != null) out(`skip: ${r.note}`)
|
|
47
|
+
else out(Object.keys(r.added).length === 0 ? 'ok: repo.config.ts ignoredInputs already covers every path the audit found' : `ok: repo.config.ts ignoredInputs gained ${describeByTask(r.added)}`)
|
|
48
|
+
return 0
|
|
49
|
+
}
|
|
50
|
+
const r = await traceAudit(root, await loadRepoConfig(root), { fresh: this.fresh })
|
|
51
|
+
const missing = r.tasks.filter((t) => t.uncovered.length > 0)
|
|
52
|
+
if (this.json) { out(JSON.stringify(r)); return missing.length > 0 ? 1 : 0 }
|
|
53
|
+
if (r.skipped != null) { out(`skip: nothing traced: ${r.skipped}`); return 0 }
|
|
54
|
+
for (const t of r.tasks) {
|
|
55
|
+
if (t.status === 'unaudited') out(`WARN ${t.id} could not be audited: ${t.why}`)
|
|
56
|
+
else if (t.uncovered.length > 0) out(`FAIL: ${t.id} reads ${t.uncovered.length} gitignored path(s) its key misses: ${t.uncovered.slice(0, 5).join(', ')}${t.uncovered.length > 5 ? ', …' : ''}`)
|
|
57
|
+
else out(`ok: ${t.id}: its key covers every gitignored path it read`)
|
|
58
|
+
}
|
|
59
|
+
if (missing.length > 0) out(` fix: sk trace-audit --fix adds ${describeByTask(Object.fromEntries(missing.map((t) => [t.id, t.propose])))} to repo.config.ts ignoredInputs`)
|
|
60
|
+
return missing.length > 0 ? 1 : 0
|
|
61
|
+
}
|
|
62
|
+
}
|
package/src/cli/cmd_Tui.ts
CHANGED
|
@@ -11,8 +11,9 @@ export class TuiCommand extends Command {
|
|
|
11
11
|
|
|
12
12
|
static override usage = Command.Usage({
|
|
13
13
|
category: 'Health',
|
|
14
|
-
description: 'live dashboard: the gate
|
|
15
|
-
|
|
14
|
+
description: 'live dashboard: the gate steps, every other check, the repo\'s panels',
|
|
15
|
+
details: 'live dashboard: the gate build steps + every other check, plus panels the repo injects via repo.config tui.panels',
|
|
16
|
+
examples: [['open the dashboard', 'sk tui']],
|
|
16
17
|
})
|
|
17
18
|
|
|
18
19
|
async execute(): Promise<number> {
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// shipkit when — what runs when: the legend (every context, every value) and
|
|
2
|
+
// one row per check with its declared value on each axis. The same data the
|
|
3
|
+
// hub's when page draws (core/runs-matrix.ts), so the terminal and the page
|
|
4
|
+
// cannot disagree.
|
|
5
|
+
import { Command, Option } from 'clipanion'
|
|
6
|
+
import { loadRepoConfig } from '../repo-config.ts'
|
|
7
|
+
import { gateInventory } from '../ledger/gate-checks.ts'
|
|
8
|
+
import { legendMarkdown, MATRIX_AXES, matrixLines, RUNS_LEGEND, runsCellsOf, type MatrixAxis } from '../core/runs-matrix.ts'
|
|
9
|
+
import { spliceMarkedBlock } from '../core/doc-block.ts'
|
|
10
|
+
|
|
11
|
+
export const LEGEND_BEGIN = '<!-- shipkit:when-legend -->'
|
|
12
|
+
export const LEGEND_END = '<!-- /shipkit:when-legend -->'
|
|
13
|
+
|
|
14
|
+
export class WhenCommand extends Command {
|
|
15
|
+
static override paths = [['when']]
|
|
16
|
+
|
|
17
|
+
static override usage = Command.Usage({
|
|
18
|
+
category: 'Health',
|
|
19
|
+
description: 'what runs when: every check on every context, with the legend',
|
|
20
|
+
details: 'Every check on every context (commit, ci, full, release, health, save, clock, fix) and how its answer is cached, after the legend of every axis and value. Reports, never gates.',
|
|
21
|
+
examples: [
|
|
22
|
+
['the legend, then every check', 'sk when'],
|
|
23
|
+
['only what the quick gate runs', 'sk when --only onCi'],
|
|
24
|
+
['the matrix without the legend', 'sk when --no-legend'],
|
|
25
|
+
['machine-readable', 'sk when --json'],
|
|
26
|
+
['write the legend into a docs page between its markers', 'sk when --out wiki/build/shipkit/runs.md'],
|
|
27
|
+
['fail if that page is stale (lint mode)', 'sk when --out wiki/build/shipkit/runs.md --check'],
|
|
28
|
+
],
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
only = Option.String('--only', { required: false, description: `only the rows one context runs: ${MATRIX_AXES.join(', ')}` })
|
|
32
|
+
legend = Option.Boolean('--legend', true, { description: 'print the legend first. Default on, --no-legend drops it' })
|
|
33
|
+
out = Option.String('--out', { required: false, description: 'host file carrying the shipkit:when-legend markers. The legend between them is rewritten' })
|
|
34
|
+
check = Option.Boolean('--check', false, { description: 'with --out: exit 1 if the legend is stale, write nothing' })
|
|
35
|
+
json = Option.Boolean('--json', false, { description: 'machine-readable { legend, rows: [{ id, title, from, blocking, build, runs: { cells, cache, off, derivedWhy } }] }' })
|
|
36
|
+
|
|
37
|
+
async execute(): Promise<number> {
|
|
38
|
+
if (this.out != null) return await this.writeLegend(this.out)
|
|
39
|
+
const root = process.cwd()
|
|
40
|
+
const c = await loadRepoConfig(root)
|
|
41
|
+
if (this.only != null && !(MATRIX_AXES as readonly string[]).includes(this.only)) {
|
|
42
|
+
this.context.stdout.write(`FAIL: --only takes one of ${MATRIX_AXES.join(', ')}, got '${this.only}'\n`)
|
|
43
|
+
return 1
|
|
44
|
+
}
|
|
45
|
+
const rows = (await gateInventory(root, c)).map((r) => ({ id: r.decl.id, title: r.title, from: r.from, blocking: r.blocking, build: r.build, runs: runsCellsOf(r) }))
|
|
46
|
+
if (this.json) {
|
|
47
|
+
this.context.stdout.write(`${JSON.stringify({ legend: RUNS_LEGEND, rows })}\n`)
|
|
48
|
+
return 0
|
|
49
|
+
}
|
|
50
|
+
for (const l of matrixLines(rows, { legend: this.legend, only: this.only as MatrixAxis | undefined })) this.context.stdout.write(`${l}\n`)
|
|
51
|
+
return 0
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** the legend only depends on the binary, never on the repo */
|
|
55
|
+
private async writeLegend(path: string): Promise<number> {
|
|
56
|
+
const { existsSync, readFileSync, writeFileSync } = await import('fs')
|
|
57
|
+
if (!existsSync(path)) { this.context.stdout.write(`FAIL: ${path} does not exist\n`); return 1 }
|
|
58
|
+
const host = readFileSync(path, 'utf8')
|
|
59
|
+
const next = spliceMarkedBlock(host, legendMarkdown(), LEGEND_BEGIN, LEGEND_END)
|
|
60
|
+
if (next == null) { this.context.stdout.write(`FAIL: ${path} has no ${LEGEND_BEGIN} / ${LEGEND_END} markers\n`); return 1 }
|
|
61
|
+
if (next === host) { this.context.stdout.write(`ok: ${path} legend current\n`); return 0 }
|
|
62
|
+
if (this.check) {
|
|
63
|
+
this.context.stdout.write(`FAIL: ${path} legend is STALE, the binary's axes or values differ from the page\n`)
|
|
64
|
+
this.context.stdout.write(` fix: shipkit when --out ${path}\n`)
|
|
65
|
+
return 1
|
|
66
|
+
}
|
|
67
|
+
writeFileSync(path, next)
|
|
68
|
+
this.context.stdout.write(`ok: ${path} legend rewritten\n`)
|
|
69
|
+
return 0
|
|
70
|
+
}
|
|
71
|
+
}
|
package/src/cli/cmd_Wiki.ts
CHANGED
|
@@ -10,8 +10,8 @@ export class WikiServeCommand extends Command {
|
|
|
10
10
|
category: 'Wiki',
|
|
11
11
|
description: 'live md link-graph server — reload = rescan',
|
|
12
12
|
examples: [
|
|
13
|
-
['serve the cwd wiki', '
|
|
14
|
-
['serve a subtree on a port', '
|
|
13
|
+
['serve the cwd wiki', 'sk wiki serve'],
|
|
14
|
+
['serve a subtree on a port', 'sk wiki serve --root agent --index process.md --port 6162'],
|
|
15
15
|
],
|
|
16
16
|
})
|
|
17
17
|
|
|
@@ -38,8 +38,8 @@ export class WikiLintCommand extends Command {
|
|
|
38
38
|
category: 'Wiki',
|
|
39
39
|
description: 'fail on orphan pages and dangling refs (exit 1)',
|
|
40
40
|
examples: [
|
|
41
|
-
['lint the cwd wiki', '
|
|
42
|
-
['lint a subtree', '
|
|
41
|
+
['lint the cwd wiki', 'sk wiki lint'],
|
|
42
|
+
['lint a subtree', 'sk wiki lint --root agent --index process.md'],
|
|
43
43
|
],
|
|
44
44
|
})
|
|
45
45
|
|
package/src/cli.ts
CHANGED
|
@@ -11,7 +11,7 @@ import { CheckCommand } from './cli/cmd_Check.ts'
|
|
|
11
11
|
import { CommandsCommand } from './cli/cmd_Commands.ts'
|
|
12
12
|
import { aliasArgs, CrossRepoActivityCommand } from './cli/cmd_CrossRepoActivity.ts'
|
|
13
13
|
import { ConfigKeysCommand } from './cli/cmd_ConfigKeys.ts'
|
|
14
|
-
import { GlobalProcessesCommand } from './cli/cmd_GlobalProcesses.ts'
|
|
14
|
+
import { GlobalProcessesCommand, GlobalProcessRestartCommand, GlobalProcessStartCommand, GlobalProcessStopCommand } from './cli/cmd_GlobalProcesses.ts'
|
|
15
15
|
import { PlannedCommand } from './cli/cmd_Planned.ts'
|
|
16
16
|
import { OverviewCommand } from './cli/cmd_Overview.ts'
|
|
17
17
|
import { CiCommand } from './cli/cmd_Ci.ts'
|
|
@@ -29,6 +29,9 @@ import { ReflectCommand } from './cli/cmd_Reflect.ts'
|
|
|
29
29
|
import { ReleaseCommand } from './cli/cmd_Release.ts'
|
|
30
30
|
import { ReleasesCommand } from './cli/cmd_Releases.ts'
|
|
31
31
|
import { ChecksCommand, UnitsAliasCommand } from './cli/cmd_Checks.ts'
|
|
32
|
+
import { WhenCommand } from './cli/cmd_When.ts'
|
|
33
|
+
import { CacheAuditCommand } from './cli/cmd_CacheAudit.ts'
|
|
34
|
+
import { TraceAuditCommand } from './cli/cmd_TraceAudit.ts'
|
|
32
35
|
import { ServeCommand } from './cli/cmd_Serve.ts'
|
|
33
36
|
import { SmokeCommand } from './cli/cmd_Smoke.ts'
|
|
34
37
|
import { StatusCommand } from './cli/cmd_Status.ts'
|
|
@@ -43,7 +46,7 @@ import { WikiLintCommand, WikiServeCommand } from './cli/cmd_Wiki.ts'
|
|
|
43
46
|
export function buildCli(): Cli {
|
|
44
47
|
const cli = new Cli({
|
|
45
48
|
binaryLabel: 'shipkit — repo toolkit',
|
|
46
|
-
binaryName: '
|
|
49
|
+
binaryName: 'sk',
|
|
47
50
|
binaryVersion: LIB_VERSION,
|
|
48
51
|
enableCapture: true, // console output pipes into the command streams (testable)
|
|
49
52
|
enableColors: true,
|
|
@@ -91,10 +94,16 @@ export function buildCli(): Cli {
|
|
|
91
94
|
cli.register(ReflectCommand)
|
|
92
95
|
cli.register(KeysCommand)
|
|
93
96
|
cli.register(GlobalProcessesCommand)
|
|
97
|
+
cli.register(GlobalProcessStartCommand)
|
|
98
|
+
cli.register(GlobalProcessStopCommand)
|
|
99
|
+
cli.register(GlobalProcessRestartCommand)
|
|
94
100
|
cli.register(CrossRepoActivityCommand)
|
|
95
101
|
cli.register(PlannedCommand)
|
|
96
102
|
cli.register(OverviewCommand)
|
|
97
103
|
cli.register(ChecksCommand)
|
|
104
|
+
cli.register(WhenCommand)
|
|
105
|
+
cli.register(CacheAuditCommand)
|
|
106
|
+
cli.register(TraceAuditCommand)
|
|
98
107
|
cli.register(UnitsAliasCommand)
|
|
99
108
|
cli.register(CommandsCommand)
|
|
100
109
|
cli.register(ConfigKeysCommand)
|
|
@@ -20,6 +20,7 @@ import { rawName, routesToShipkit } from '../core/canonical-scripts.ts'
|
|
|
20
20
|
import { FLOOR_IDS } from '../core/floor.ts'
|
|
21
21
|
import { FOREVER_MS, formatLine, ttlMsOf } from '../core/wire.ts'
|
|
22
22
|
import { gateInventory, type CheckRow } from '../ledger/gate-checks.ts'
|
|
23
|
+
import { runsCellsOf } from '../core/runs-matrix.ts'
|
|
23
24
|
import { readLastLines, readRuns, runsPath, type LastLine, type RunRow } from '../ledger/run-log.ts'
|
|
24
25
|
import { checkStatsFor, type CheckStat } from '../ledger/check-stats.ts'
|
|
25
26
|
import { NEGATIVE_TTL_CAP_MS } from '../ledger/world-cache.ts'
|
|
@@ -114,6 +115,7 @@ function instanceOf(root: string, c: RepoConfig, row: CheckRow, stat: CheckStat
|
|
|
114
115
|
description: row.description,
|
|
115
116
|
lastLines: wireLines,
|
|
116
117
|
gate: row.gate,
|
|
118
|
+
runs: runsCellsOf(row),
|
|
117
119
|
build: row.build,
|
|
118
120
|
blocking: row.blocking,
|
|
119
121
|
advisory,
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
// the docs wiki this lib ships beside.
|
|
8
8
|
|
|
9
9
|
import type { WhenAt, WhenSource } from '../core/when.ts'
|
|
10
|
+
import type { RunsCells } from '../core/runs-matrix.ts'
|
|
10
11
|
import type { CheckFrom } from '../ledger/gate-checks.ts'
|
|
11
12
|
|
|
12
13
|
export type NeedSeverity = 'red' | 'yellow'
|
|
@@ -22,14 +23,15 @@ export const RUNS_ID = 'runs'
|
|
|
22
23
|
* row, the runs page and the to fix list all open the same page by it */
|
|
23
24
|
export const testId = (file: string): string => `test:${file}`
|
|
24
25
|
|
|
25
|
-
/**
|
|
26
|
+
/** the path segment of a test file no check reaches, where a check id sits
|
|
27
|
+
* for the others, so the filter finds a test file by its check */
|
|
26
28
|
export const NO_CHECK = 'in no check'
|
|
27
29
|
|
|
28
|
-
/** the resource KIND, never the collection it came from:
|
|
29
|
-
*
|
|
30
|
+
/** the resource KIND, never the collection it came from: it decides the
|
|
31
|
+
* section a row lives under (hub-app/tree-build.ts KIND_SECTION). There is no
|
|
30
32
|
* catch all kind: a row belongs to an owner, and what belongs to the hub
|
|
31
33
|
* itself is its status (serve/hub-problems.ts), never a row */
|
|
32
|
-
export const RESOURCE_TYPES = ['ask', 'secret', 'asset', 'post', 'workflow', 'wiki', 'contract', 'check', 'test', 'reflection'] as const
|
|
34
|
+
export const RESOURCE_TYPES = ['ask', 'secret', 'asset', 'post', 'workflow', 'wiki', 'contract', 'check', 'test', 'reflection', 'process'] as const
|
|
33
35
|
|
|
34
36
|
export type ResourceType = (typeof RESOURCE_TYPES)[number]
|
|
35
37
|
|
|
@@ -53,6 +55,9 @@ export type CheckFacts = {
|
|
|
53
55
|
lastLines: string[]
|
|
54
56
|
/** does `shipkit ci` run it? false = proactive, `shipkit check` only */
|
|
55
57
|
gate: boolean
|
|
58
|
+
/** every context it runs in and how it caches, as the when page draws
|
|
59
|
+
* it (core/runs-matrix.ts) */
|
|
60
|
+
runs: RunsCells
|
|
56
61
|
/** a BUILD STEP: the gate runs it, the health pass does not (derived from
|
|
57
62
|
* a floor slot or the repo's `tasks: []`, never declared by a check) */
|
|
58
63
|
build: boolean
|
|
@@ -223,6 +228,9 @@ export type Instance = {
|
|
|
223
228
|
* kind, a secret present or missing, a post its venue, an asset its roll
|
|
224
229
|
* count. Absent = this kind has nothing to say there */
|
|
225
230
|
slot?: string
|
|
231
|
+
/** the group it sits in on the tree, under its section: an asset's kit
|
|
232
|
+
* category. Absent = directly under the section */
|
|
233
|
+
group?: string
|
|
226
234
|
type: ResourceType
|
|
227
235
|
/** a slash path. Where a truth file exists this IS its repo-relative
|
|
228
236
|
* path; otherwise a VIRTUAL path under a root named for the type, and
|