@cosmicdrift/kumiko-guards 0.363.0 → 0.365.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 +28 -0
- package/package.json +2 -2
- package/src/_lib/agent-docs.ts +425 -0
- package/src/_lib/dependency-cli.ts +27 -0
- package/src/_lib/dependency-exceptions.ts +135 -0
- package/src/_lib/direct-dependencies.ts +80 -0
- package/src/_lib/installed-packages.ts +146 -0
- package/src/_lib/npm-registry.ts +168 -0
- package/src/_lib/push-root.ts +5 -3
- package/src/_lib/security-audit.ts +390 -0
- package/src/_lib/security-baseline.ts +14 -3
- package/src/changes.json +47 -5
- package/src/check-licenses.ts +288 -0
- package/src/check-outdated.ts +234 -0
- package/src/check-runtime-isolation.ts +3 -1
- package/src/check-security.ts +182 -0
- package/src/check-single-runtime-instance.ts +1 -1
- package/src/cli.ts +27 -10
- package/src/dependency-license-exceptions.json +77 -0
- package/src/dependency-security-exceptions.json +4 -0
- package/src/guard-agent-docs-drift.ts +137 -0
- package/src/guard-comment-lang.ts +76 -40
- package/src/guard-direct-entity-writes.ts +3 -0
- package/src/guard-lib-test-coverage.ts +1 -1
- package/src/guard-no-direct-fs.ts +0 -1
- package/src/guard-pre-es-patterns.ts +3 -0
- package/src/guard-public-exports-changelog.ts +159 -24
- package/src/guard-test-timeouts.ts +5 -1
- package/src/guard-thin-wrappers.ts +9 -2
- package/src/guard-upgrade-state.ts +40 -11
- package/src/index.ts +1 -0
- package/src/pre-push.sh +20 -0
- package/src/run-repo-checks.ts +2 -0
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
* bun guard-upgrade-state.ts
|
|
22
22
|
*/
|
|
23
23
|
|
|
24
|
+
import { createHash } from "node:crypto";
|
|
24
25
|
import { existsSync, readFileSync } from "node:fs";
|
|
25
26
|
import { join } from "node:path";
|
|
26
27
|
import {
|
|
@@ -84,19 +85,45 @@ export function isUpgradeJson(value: unknown): value is UpgradeJson {
|
|
|
84
85
|
);
|
|
85
86
|
}
|
|
86
87
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
);
|
|
88
|
+
// Same id scheme as manualEntryId in @cosmicdrift/kumiko-framework/upgrade-cli. Duplicated because
|
|
89
|
+
// this package must stay installable without the framework; a test pins both to the same value.
|
|
90
|
+
const MANUAL_ID_HASH_LENGTH = 8;
|
|
91
|
+
|
|
92
|
+
export function manualEntryId(version: string, title: string): string {
|
|
93
|
+
const hash = createHash("sha256").update(title).digest("hex").slice(0, MANUAL_ID_HASH_LENGTH);
|
|
94
|
+
return `${version}:${hash}`;
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
|
|
97
|
+
/** Markers written before entries carried an `id` get the id the CLI derives for them. */
|
|
98
|
+
export function parsePendingManualStep(value: unknown): PendingManualStep | null {
|
|
99
|
+
if (!isRecord(value)) return null;
|
|
100
|
+
const { id, version, title } = value;
|
|
101
|
+
if (typeof version !== "string" || typeof title !== "string") return null;
|
|
102
|
+
return {
|
|
103
|
+
id: typeof id === "string" && id.length > 0 ? id : manualEntryId(version, title),
|
|
104
|
+
version,
|
|
105
|
+
title,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function readPendingManual(
|
|
110
|
+
parsed: unknown,
|
|
111
|
+
): { readonly steps: readonly PendingManualStep[] } | { readonly error: string } {
|
|
98
112
|
const raw = isRecord(parsed) ? parsed["pendingManual"] : undefined;
|
|
99
|
-
|
|
113
|
+
if (raw === undefined) return { steps: [] };
|
|
114
|
+
if (!Array.isArray(raw))
|
|
115
|
+
return { error: `${MARKER_REL} has a "pendingManual" that is not an array` };
|
|
116
|
+
const steps: PendingManualStep[] = [];
|
|
117
|
+
for (const [index, entry] of raw.entries()) {
|
|
118
|
+
const step = parsePendingManualStep(entry);
|
|
119
|
+
if (step === null) {
|
|
120
|
+
return {
|
|
121
|
+
error: `${MARKER_REL} has a malformed pendingManual entry at index ${index} (needs string "version" and "title")`,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
steps.push(step);
|
|
125
|
+
}
|
|
126
|
+
return { steps };
|
|
100
127
|
}
|
|
101
128
|
|
|
102
129
|
export function readMarker(root: string): UpgradeMarker | { error: string } {
|
|
@@ -118,7 +145,9 @@ export function readMarker(root: string): UpgradeMarker | { error: string } {
|
|
|
118
145
|
error: `${MARKER_REL} is missing a valid "version" field (expected semver x.y.z[-pre][+build]) — broken marker file`,
|
|
119
146
|
};
|
|
120
147
|
}
|
|
121
|
-
|
|
148
|
+
const pendingManual = readPendingManual(parsed);
|
|
149
|
+
if ("error" in pendingManual) return pendingManual;
|
|
150
|
+
return { version, pendingManual: pendingManual.steps };
|
|
122
151
|
}
|
|
123
152
|
|
|
124
153
|
/** Pending changelog entries turned into guard violations — pure, testable without a subprocess. */
|
package/src/index.ts
CHANGED
package/src/pre-push.sh
CHANGED
|
@@ -18,6 +18,9 @@
|
|
|
18
18
|
# sub-repo's own package.json `test` script — refuses the push if that
|
|
19
19
|
# script is missing.
|
|
20
20
|
#
|
|
21
|
+
# Before the checks below, the hook runs a gitleaks scan of origin/main..HEAD
|
|
22
|
+
# when the binary is installed.
|
|
23
|
+
#
|
|
21
24
|
# Extension point: a tracked, executable scripts/pre-push-extra.sh runs
|
|
22
25
|
# before the main check in every branch above, with KUMIKO_PUSH_REPO_ROOT
|
|
23
26
|
# and KUMIKO_PUSH_PARENT_DIR available inline (never exported).
|
|
@@ -118,6 +121,22 @@ if [ -f "$REPO_ROOT/.kumiko/upgrade-state.json" ]; then
|
|
|
118
121
|
fi
|
|
119
122
|
fi
|
|
120
123
|
|
|
124
|
+
# Secret scan: runs before check-wt.sh/bun check so a leaked credential is
|
|
125
|
+
# caught in seconds, not after the long checks. A missing binary or a missing
|
|
126
|
+
# origin/main only warns, so a machine without gitleaks is not locked out.
|
|
127
|
+
# No --config: gitleaks reads a .gitleaks.toml in the repo root itself.
|
|
128
|
+
if ! command -v gitleaks >/dev/null 2>&1; then
|
|
129
|
+
echo "[pre-push] gitleaks not installed — secret scan skipped. Install: brew install gitleaks" >&2
|
|
130
|
+
elif ! git -C "$REPO_ROOT" rev-parse --verify --quiet origin/main >/dev/null 2>&1; then
|
|
131
|
+
echo "[pre-push] origin/main not found — secret scan skipped" >&2
|
|
132
|
+
else
|
|
133
|
+
echo "[pre-push] gitleaks git origin/main..HEAD"
|
|
134
|
+
if ! (cd "$REPO_ROOT" && gitleaks git --no-banner --redact --log-opts="origin/main..HEAD" .); then
|
|
135
|
+
echo "[pre-push] gitleaks found secrets — refusing push" >&2
|
|
136
|
+
exit 1
|
|
137
|
+
fi
|
|
138
|
+
fi
|
|
139
|
+
|
|
121
140
|
# infra#559/#569: from a worktree, `--git-common-dir` resolves to the main
|
|
122
141
|
# checkout's .git, so the branch below would scope `bun check` to the
|
|
123
142
|
# canonical sibling path instead of this worktree — checking the wrong
|
|
@@ -176,6 +195,7 @@ if [ "$(git rev-parse --path-format=absolute --git-dir)" != "$GIT_COMMON_DIR" ]
|
|
|
176
195
|
run_guard_bin guards kumiko-guards guards
|
|
177
196
|
run_guard_bin checks kumiko-guards checks
|
|
178
197
|
run_guard_bin comment-lang kumiko-guards comment-lang --touched --base=origin/main
|
|
198
|
+
run_guard_bin public-exports-changelog kumiko-guards public-exports-changelog --base=origin/main
|
|
179
199
|
if [ -n "$FAILED" ]; then
|
|
180
200
|
echo "[pre-push] worktree check failed:$FAILED" >&2
|
|
181
201
|
exit 1
|
package/src/run-repo-checks.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { check as realProviderIsolation } from "./check-real-provider-isolation"
|
|
|
7
7
|
import { check as runtimeIsolation } from "./check-runtime-isolation";
|
|
8
8
|
import { check as secretLiterals } from "./check-secret-literals";
|
|
9
9
|
import { check as singleRuntimeInstance } from "./check-single-runtime-instance";
|
|
10
|
+
import { check as agentDocsDrift } from "./guard-agent-docs-drift";
|
|
10
11
|
import { check as featureIntegrationTests } from "./guard-feature-integration-tests";
|
|
11
12
|
import { check as noDirectProcessEnv } from "./guard-no-direct-process-env";
|
|
12
13
|
import { check as primitivesDiscipline } from "./guard-primitives-discipline";
|
|
@@ -29,6 +30,7 @@ export const REPO_CHECKS = [
|
|
|
29
30
|
upgradeState,
|
|
30
31
|
realProviderIsolation,
|
|
31
32
|
singleRuntimeInstance,
|
|
33
|
+
agentDocsDrift,
|
|
32
34
|
];
|
|
33
35
|
|
|
34
36
|
export const REPO_CHECK_FLAGS: readonly string[] = ["--write-baseline"];
|