mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-09-19 01:51:21 +08:00
fix(cli): check annotations across shared upstream paths
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env bun
|
||||
|
||||
/**
|
||||
* Verifies that every Kilo-specific change in shared packages/opencode/ files
|
||||
* Verifies that every Kilo-specific change in shared upstream-owned source files
|
||||
* is annotated with a kilocode_change marker.
|
||||
*
|
||||
* Usage:
|
||||
@@ -11,18 +11,20 @@
|
||||
* A line is "covered" if it:
|
||||
* - contains a kilocode_change marker comment (inline annotation)
|
||||
* - falls inside a kilocode_change start/end block (block annotation)
|
||||
* - is in a file whose first non-empty line is (whole-file annotation)
|
||||
* - is in a file whose first non-shebang non-empty line is (whole-file annotation)
|
||||
* // kilocode_change - new file
|
||||
* - is empty / whitespace-only (skipped)
|
||||
* - is itself a marker line (auto-covered)
|
||||
*
|
||||
* Both JS (//) and JSX ({/ * ... * /}) comment styles are recognized.
|
||||
* JS (//), JSX ({/ * ... * /}), YAML (#), and TOML (#) comment styles are recognized.
|
||||
*
|
||||
* Exempt paths (no markers needed — entirely Kilo-specific):
|
||||
* - packages/opencode/src/kilocode/**
|
||||
* - packages/opencode/test/kilocode/**
|
||||
* - Any path containing "kilocode" in directory or filename
|
||||
* - Any path with a directory starting with "kilo-" (e.g. kilo-sessions/)
|
||||
* - script/upstream/**
|
||||
* - Kilo-specific annotation checker support files
|
||||
*/
|
||||
|
||||
import { spawnSync } from "node:child_process"
|
||||
@@ -30,7 +32,28 @@ import { readFileSync } from "node:fs"
|
||||
import path from "node:path"
|
||||
|
||||
const ROOT = path.resolve(import.meta.dir, "..")
|
||||
const SOURCE_EXTS = new Set([".ts", ".tsx", ".js", ".jsx"])
|
||||
const SOURCE_EXTS = new Set([".ts", ".tsx", ".js", ".jsx", ".yml", ".yaml", ".toml"])
|
||||
const SCOPES = [
|
||||
"sdks/vscode",
|
||||
"packages/opencode",
|
||||
"packages/extensions",
|
||||
"packages/ui",
|
||||
"packages/app",
|
||||
"packages/desktop",
|
||||
"packages/desktop-electron",
|
||||
"packages/shared",
|
||||
"packages/script",
|
||||
"packages/storybook",
|
||||
"script",
|
||||
".github",
|
||||
"github",
|
||||
]
|
||||
const EXEMPT_SCOPES = [
|
||||
"script/upstream",
|
||||
"script/check-opencode-annotations.ts",
|
||||
"packages/script/tests/check-opencode-annotations.test.ts",
|
||||
".github/workflows/check-opencode-annotations.yml",
|
||||
]
|
||||
|
||||
const args = process.argv.slice(2)
|
||||
const baseIdx = args.indexOf("--base")
|
||||
@@ -47,7 +70,7 @@ function run(cmd: string, args: string[]) {
|
||||
}
|
||||
|
||||
function changedFiles() {
|
||||
const out = run("git", ["diff", "--name-only", "--diff-filter=AMRT", `${base}...HEAD`, "--", "packages/opencode"])
|
||||
const out = run("git", ["diff", "--name-only", "--diff-filter=AMRT", `${base}...HEAD`, "--", ...SCOPES])
|
||||
return out ? out.split("\n").filter(Boolean) : []
|
||||
}
|
||||
|
||||
@@ -63,7 +86,13 @@ function isUpstreamMerge() {
|
||||
|
||||
function isExempt(file: string) {
|
||||
const norm = file.replaceAll("\\", "/").toLowerCase()
|
||||
return norm.split("/").some((part) => part.includes("kilocode") || part.startsWith("kilo-"))
|
||||
if (norm.split("/").some((part) => part.includes("kilocode") || part.startsWith("kilo-"))) return true
|
||||
return EXEMPT_SCOPES.some((scope) => norm === scope || norm.startsWith(`${scope}/`))
|
||||
}
|
||||
|
||||
function isChecked(file: string) {
|
||||
const norm = file.replaceAll("\\", "/")
|
||||
return SCOPES.some((scope) => norm === scope || norm.startsWith(`${scope}/`))
|
||||
}
|
||||
|
||||
function isSource(file: string) {
|
||||
@@ -83,8 +112,8 @@ function addedLines(file: string): Set<number> {
|
||||
return out
|
||||
}
|
||||
|
||||
// Matches the start of a kilocode_change marker in both JS (//) and JSX ({/* */}) comments
|
||||
const MARKER_PREFIX = /(?:\/\/|\{?\s*\/\*)\s*kilocode_change\b/
|
||||
// Matches the start of a kilocode_change marker in JS, JSX, YAML, and TOML comments.
|
||||
const MARKER_PREFIX = /(?:\/\/|\{?\s*\/\*|#)\s*kilocode_change\b/
|
||||
|
||||
function hasMarker(line: string) {
|
||||
return MARKER_PREFIX.test(line)
|
||||
@@ -94,9 +123,9 @@ function coveredLines(text: string): { lines: string[]; covered: Set<number> } {
|
||||
const lines = text.split(/\r?\n/)
|
||||
const covered = new Set<number>()
|
||||
|
||||
// Whole-file annotation: first non-empty line is "// kilocode_change - new file"
|
||||
const first = lines.find((x) => x.trim() !== "")
|
||||
if (first?.match(/(?:\/\/|\{?\s*\/\*)\s*kilocode_change\s*-\s*new\s*file\b/)) {
|
||||
// Whole-file annotation: first non-shebang non-empty line is a kilocode_change - new file marker.
|
||||
const first = lines.find((x) => x.trim() !== "" && !x.startsWith("#!"))
|
||||
if (first?.match(/(?:\/\/|\{?\s*\/\*|#)\s*kilocode_change\s*-\s*new\s*file\b/)) {
|
||||
for (let i = 1; i <= lines.length; i++) covered.add(i)
|
||||
return { lines, covered }
|
||||
}
|
||||
@@ -106,13 +135,13 @@ function coveredLines(text: string): { lines: string[]; covered: Set<number> } {
|
||||
const n = i + 1
|
||||
const line = lines[i] ?? ""
|
||||
|
||||
if (line.match(/(?:\/\/|\{?\s*\/\*)\s*kilocode_change\s+start\b/)) {
|
||||
if (line.match(/(?:\/\/|\{?\s*\/\*|#)\s*kilocode_change\s+start\b/)) {
|
||||
block = true
|
||||
covered.add(n)
|
||||
continue
|
||||
}
|
||||
|
||||
if (line.match(/(?:\/\/|\{?\s*\/\*)\s*kilocode_change\s+end\b/)) {
|
||||
if (line.match(/(?:\/\/|\{?\s*\/\*|#)\s*kilocode_change\s+end\b/)) {
|
||||
covered.add(n)
|
||||
block = false
|
||||
continue
|
||||
@@ -132,14 +161,14 @@ function coveredLines(text: string): { lines: string[]; covered: Set<number> } {
|
||||
// --- main ---
|
||||
|
||||
if (isUpstreamMerge()) {
|
||||
console.log("Skipping opencode annotation check — upstream opencode merge detected.")
|
||||
console.log("Skipping shared upstream annotation check — upstream merge detected.")
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
const files = changedFiles().filter((f) => !isExempt(f) && isSource(f))
|
||||
const files = changedFiles().filter((f) => isChecked(f) && !isExempt(f) && isSource(f))
|
||||
|
||||
if (files.length === 0) {
|
||||
console.log("No shared opencode source files changed — nothing to check.")
|
||||
console.log("No shared upstream source files changed — nothing to check.")
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
@@ -163,17 +192,20 @@ for (const file of files) {
|
||||
}
|
||||
|
||||
if (violations.length === 0) {
|
||||
console.log("All shared opencode changes are annotated with kilocode_change markers.")
|
||||
console.log("All shared upstream changes are annotated with kilocode_change markers.")
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
console.error(
|
||||
[
|
||||
"Unannotated Kilo changes found in shared opencode files:",
|
||||
"Unannotated Kilo changes found in shared upstream files:",
|
||||
"",
|
||||
...violations,
|
||||
"",
|
||||
"Every Kilo-specific change in packages/opencode/ must be annotated.",
|
||||
"Every Kilo-specific change in shared upstream source files must be annotated.",
|
||||
"",
|
||||
"Checked paths:",
|
||||
...SCOPES.map((scope) => ` - ${scope}/**`),
|
||||
"",
|
||||
"Inline (single line):",
|
||||
" const url = Flag.KILO_MODELS_URL || 'https://models.dev' // kilocode_change",
|
||||
@@ -189,6 +221,12 @@ console.error(
|
||||
" ...",
|
||||
" {/* kilocode_change end */}",
|
||||
"",
|
||||
"YAML:",
|
||||
" # kilocode_change",
|
||||
" # kilocode_change start",
|
||||
" ...",
|
||||
" # kilocode_change end",
|
||||
"",
|
||||
"New file:",
|
||||
" // kilocode_change - new file",
|
||||
"",
|
||||
@@ -197,6 +235,8 @@ console.error(
|
||||
" - packages/opencode/test/kilocode/**",
|
||||
" - Any path containing 'kilocode' in the directory or filename",
|
||||
" - Any directory starting with 'kilo-' (e.g. kilo-sessions/)",
|
||||
" - script/upstream/**",
|
||||
" - Kilo-specific annotation checker support files",
|
||||
"",
|
||||
"See AGENTS.md for details.",
|
||||
].join("\n"),
|
||||
|
||||
Reference in New Issue
Block a user