@kenkaiiii/ggcoder 5.73.0 → 5.74.1
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/assets/skills/refactoring/SKILL.md +3 -1
- package/dist/app-error.d.ts +21 -0
- package/dist/app-error.js +39 -0
- package/dist/app-error.js.map +1 -0
- package/dist/app-sidecar.js +39 -35
- package/dist/app-sidecar.js.map +1 -1
- package/dist/cli.js +4 -0
- package/dist/cli.js.map +1 -1
- package/dist/core/agent-session.d.ts +2 -2
- package/dist/core/agent-session.js +11 -2
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/checklist-detection.d.ts +11 -0
- package/dist/core/checklist-detection.js +238 -0
- package/dist/core/checklist-detection.js.map +1 -0
- package/dist/core/checklist-items.d.ts +180 -0
- package/dist/core/checklist-items.js +204 -0
- package/dist/core/checklist-items.js.map +1 -0
- package/dist/core/checklist-prompt.d.ts +3 -0
- package/dist/core/checklist-prompt.js +34 -0
- package/dist/core/checklist-prompt.js.map +1 -0
- package/dist/core/checklist-snapshot.d.ts +13 -0
- package/dist/core/checklist-snapshot.js +29 -0
- package/dist/core/checklist-snapshot.js.map +1 -0
- package/dist/core/checklist-store.d.ts +59 -0
- package/dist/core/checklist-store.js +242 -0
- package/dist/core/checklist-store.js.map +1 -0
- package/dist/core/lsp/client.d.ts +4 -0
- package/dist/core/lsp/client.js +71 -3
- package/dist/core/lsp/client.js.map +1 -1
- package/dist/core/lsp/manager.d.ts +1 -0
- package/dist/core/lsp/manager.js +9 -3
- package/dist/core/lsp/manager.js.map +1 -1
- package/dist/core/lsp/project-root.d.ts +9 -0
- package/dist/core/lsp/project-root.js +75 -0
- package/dist/core/lsp/project-root.js.map +1 -0
- package/dist/core/lsp/reference-project.d.ts +6 -0
- package/dist/core/lsp/reference-project.js +110 -0
- package/dist/core/lsp/reference-project.js.map +1 -0
- package/dist/core/lsp/servers.js +1 -0
- package/dist/core/lsp/servers.js.map +1 -1
- package/dist/core/subagent-manager.d.ts +2 -1
- package/dist/core/subagent-manager.js +8 -5
- package/dist/core/subagent-manager.js.map +1 -1
- package/dist/modes/acp-mode.d.ts +2 -1
- package/dist/modes/acp-mode.js +4 -1
- package/dist/modes/acp-mode.js.map +1 -1
- package/dist/modes/subagent-worker-mode.d.ts +2 -0
- package/dist/modes/subagent-worker-mode.js +1 -3
- package/dist/modes/subagent-worker-mode.js.map +1 -1
- package/dist/system-prompt.js +4 -4
- package/dist/tools/bash.d.ts +4 -1
- package/dist/tools/bash.js +32 -7
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/checklist.d.ts +56 -0
- package/dist/tools/checklist.js +178 -0
- package/dist/tools/checklist.js.map +1 -0
- package/dist/tools/code-nav.d.ts +1 -1
- package/dist/tools/code-nav.js +3 -2
- package/dist/tools/code-nav.js.map +1 -1
- package/dist/tools/exit-plan.d.ts +2 -2
- package/dist/tools/exit-plan.js +7 -1
- package/dist/tools/exit-plan.js.map +1 -1
- package/dist/tools/index.d.ts +5 -3
- package/dist/tools/index.js +5 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/prompt-hints.js +2 -0
- package/dist/tools/prompt-hints.js.map +1 -1
- package/dist/tools/subagent-shared.d.ts +6 -8
- package/dist/tools/subagent-shared.js +17 -11
- package/dist/tools/subagent-shared.js.map +1 -1
- package/dist/tools/subagent.d.ts +2 -1
- package/dist/tools/subagent.js +6 -6
- package/dist/tools/subagent.js.map +1 -1
- package/dist/tools/tool-tiers.js +1 -0
- package/dist/tools/tool-tiers.js.map +1 -1
- package/dist/tools/verification-review.d.ts +2 -0
- package/dist/tools/verification-review.js +41 -0
- package/dist/tools/verification-review.js.map +1 -0
- package/dist/ui/App.js +1 -0
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/hooks/useModeState.js +15 -0
- package/dist/ui/hooks/useModeState.js.map +1 -1
- package/dist/ui/tool-line-summary.js +11 -1
- package/dist/ui/tool-line-summary.js.map +1 -1
- package/dist/ui/transcript/tool-presentation.js +1 -1
- package/dist/ui/transcript/tool-presentation.js.map +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Observations of setup, never audit verdicts. No project code is executed. */
|
|
2
|
+
export interface ChecklistDetection {
|
|
3
|
+
readonly summary: string;
|
|
4
|
+
readonly facts: readonly string[];
|
|
5
|
+
}
|
|
6
|
+
export interface ChecklistDetections {
|
|
7
|
+
readonly items: Readonly<Record<string, ChecklistDetection>>;
|
|
8
|
+
readonly warnings: readonly string[];
|
|
9
|
+
}
|
|
10
|
+
/** Cheap, bounded, local observations. Missing/unsupported setup is not a failure. */
|
|
11
|
+
export declare function detectChecklist(cwd: string, signal?: AbortSignal): Promise<ChecklistDetections>;
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
import { constants } from "node:fs";
|
|
2
|
+
import fs, {} from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { runBackgroundGit } from "../utils/git.js";
|
|
6
|
+
import { log } from "./logger.js";
|
|
7
|
+
const MAX_ENTRIES = 256;
|
|
8
|
+
const MAX_PACKAGES = 32;
|
|
9
|
+
const MAX_MANIFEST_BYTES = 256 * 1024;
|
|
10
|
+
const Manifest = z.object({
|
|
11
|
+
scripts: z.record(z.string(), z.string()).optional(),
|
|
12
|
+
dependencies: z.record(z.string(), z.string()).optional(),
|
|
13
|
+
devDependencies: z.record(z.string(), z.string()).optional(),
|
|
14
|
+
});
|
|
15
|
+
/** Cheap, bounded, local observations. Missing/unsupported setup is not a failure. */
|
|
16
|
+
export async function detectChecklist(cwd, signal) {
|
|
17
|
+
const started = Date.now();
|
|
18
|
+
const items = {};
|
|
19
|
+
const warnings = new Set();
|
|
20
|
+
const facts = new Map();
|
|
21
|
+
let root;
|
|
22
|
+
try {
|
|
23
|
+
root = await fs.realpath(cwd);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return { items, warnings: ["Project setup could not be read."] };
|
|
27
|
+
}
|
|
28
|
+
function add(id, fact) {
|
|
29
|
+
const lines = facts.get(id) ?? new Set();
|
|
30
|
+
if (lines.size < 10)
|
|
31
|
+
lines.add(fact);
|
|
32
|
+
facts.set(id, lines);
|
|
33
|
+
}
|
|
34
|
+
async function contained(relative) {
|
|
35
|
+
if (signal?.aborted)
|
|
36
|
+
return null;
|
|
37
|
+
const file = path.join(root, relative);
|
|
38
|
+
try {
|
|
39
|
+
// Don't follow even in-project symlinks: opening a checklist must not
|
|
40
|
+
// traverse a link to a secret, device, or another project's files.
|
|
41
|
+
let current = root;
|
|
42
|
+
for (const part of relative.split("/")) {
|
|
43
|
+
current = path.join(current, part);
|
|
44
|
+
if ((await fs.lstat(current)).isSymbolicLink())
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
const resolved = await fs.realpath(file);
|
|
48
|
+
const rel = path.relative(root, resolved);
|
|
49
|
+
return rel === ".." || rel.startsWith(`..${path.sep}`) || path.isAbsolute(rel)
|
|
50
|
+
? null
|
|
51
|
+
: resolved;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
async function names(relative) {
|
|
58
|
+
const result = { files: [], directories: [] };
|
|
59
|
+
const directory = relative === "." ? root : await contained(relative);
|
|
60
|
+
if (!directory || signal?.aborted)
|
|
61
|
+
return result;
|
|
62
|
+
try {
|
|
63
|
+
let count = 0;
|
|
64
|
+
const handle = await fs.opendir(directory);
|
|
65
|
+
for await (const entry of handle) {
|
|
66
|
+
if (signal?.aborted)
|
|
67
|
+
break;
|
|
68
|
+
if (++count > MAX_ENTRIES) {
|
|
69
|
+
warnings.add("Setup detection was limited in a large directory; unlisted files were not checked.");
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
if (entry.isFile())
|
|
73
|
+
result.files.push(entry.name);
|
|
74
|
+
else if (entry.isDirectory())
|
|
75
|
+
result.directories.push(entry.name);
|
|
76
|
+
}
|
|
77
|
+
result.files.sort();
|
|
78
|
+
result.directories.sort();
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
warnings.add("Some project folders could not be read; setup detection may be incomplete.");
|
|
82
|
+
}
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
async function manifest(relative) {
|
|
86
|
+
const file = await contained(relative);
|
|
87
|
+
if (!file || signal?.aborted)
|
|
88
|
+
return null;
|
|
89
|
+
let handle;
|
|
90
|
+
try {
|
|
91
|
+
handle = await fs.open(file, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
|
|
92
|
+
const stat = await handle.stat();
|
|
93
|
+
if (!stat.isFile() || stat.size > MAX_MANIFEST_BYTES) {
|
|
94
|
+
warnings.add("A package manifest was too large or not a regular file; it was not inspected.");
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
// A capped handle read also bounds a file that grows after stat().
|
|
98
|
+
const buffer = Buffer.alloc(MAX_MANIFEST_BYTES + 1);
|
|
99
|
+
let length = 0;
|
|
100
|
+
while (length < buffer.length && !signal?.aborted) {
|
|
101
|
+
const { bytesRead } = await handle.read(buffer, length, buffer.length - length, null);
|
|
102
|
+
if (bytesRead === 0)
|
|
103
|
+
break;
|
|
104
|
+
length += bytesRead;
|
|
105
|
+
}
|
|
106
|
+
if (signal?.aborted)
|
|
107
|
+
return null;
|
|
108
|
+
if (length > MAX_MANIFEST_BYTES) {
|
|
109
|
+
warnings.add("A package manifest exceeded the read limit; it was not inspected.");
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
const parsed = Manifest.safeParse(JSON.parse(buffer.subarray(0, length).toString("utf-8")));
|
|
113
|
+
if (parsed.success)
|
|
114
|
+
return parsed.data;
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
// Never report file contents, script bodies or dependency URLs.
|
|
118
|
+
}
|
|
119
|
+
finally {
|
|
120
|
+
await handle?.close();
|
|
121
|
+
}
|
|
122
|
+
warnings.add("A package manifest could not be parsed; setup detection may be incomplete.");
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
const top = await names(".");
|
|
126
|
+
for (const file of top.files) {
|
|
127
|
+
if (/^(AGENTS|CLAUDE)\.md$/i.test(file))
|
|
128
|
+
add("agent-setup", `${file} found`);
|
|
129
|
+
if (/^readme(?:\.(?:md|rst|txt))?$/i.test(file))
|
|
130
|
+
add("docs", "README found");
|
|
131
|
+
if (/^(?:licen[cs]e|copying)(?:\.(?:md|txt|rst))?$/i.test(file))
|
|
132
|
+
add("docs", "Licence file found");
|
|
133
|
+
if (file === "CONTEXT.md")
|
|
134
|
+
add("naming", "Project glossary found");
|
|
135
|
+
if (file === ".gitignore")
|
|
136
|
+
add("git-github", ".gitignore found");
|
|
137
|
+
if (/^(?:pnpm-lock\.yaml|package-lock\.json|yarn\.lock|bun\.lockb?|Cargo\.lock|poetry\.lock|uv\.lock|Gemfile\.lock|composer\.lock|go\.sum)$/.test(file))
|
|
138
|
+
add("dependencies", `${file} found`);
|
|
139
|
+
if (/^(?:CHANGELOG|CHANGES)(?:\.md)?$/i.test(file))
|
|
140
|
+
add("build-release", "Changelog found");
|
|
141
|
+
if ([".gitlab-ci.yml", "azure-pipelines.yml", "Jenkinsfile"].includes(file))
|
|
142
|
+
add("ci", "CI configuration found");
|
|
143
|
+
}
|
|
144
|
+
for (const relative of [
|
|
145
|
+
".gg/commands/commit.md",
|
|
146
|
+
".claude/commands/commit.md",
|
|
147
|
+
".husky/pre-commit",
|
|
148
|
+
]) {
|
|
149
|
+
const file = await contained(relative);
|
|
150
|
+
if (file && (await fs.stat(file)).isFile())
|
|
151
|
+
add("commit-gate", "Project commit check configuration found");
|
|
152
|
+
}
|
|
153
|
+
if ((await names("docs/adr")).files.length > 0)
|
|
154
|
+
add("naming", "Decision records found in docs/adr");
|
|
155
|
+
const workflows = await names(".github/workflows");
|
|
156
|
+
if (workflows.files.some((file) => /\.ya?ml$/i.test(file)))
|
|
157
|
+
add("ci", "GitHub workflow files found");
|
|
158
|
+
const packages = ["."];
|
|
159
|
+
for (const parent of ["packages", "apps"]) {
|
|
160
|
+
for (const directory of (await names(parent)).directories) {
|
|
161
|
+
if (packages.length >= MAX_PACKAGES + 1) {
|
|
162
|
+
warnings.add("Setup detection covered only the first 32 workspace packages.");
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
packages.push(`${parent}/${directory}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
for (const directory of packages) {
|
|
169
|
+
if (signal?.aborted)
|
|
170
|
+
break;
|
|
171
|
+
const listing = directory === "." ? top : await names(directory);
|
|
172
|
+
if (listing.files.some((file) => /^(?:eslint\.config\.|\.eslintrc(?:\.|$)|biome\.jsonc?$|ruff\.toml$|\.ruff\.toml$|\.golangci\.)/.test(file)))
|
|
173
|
+
add("quality-tools", "Lint configuration found");
|
|
174
|
+
if (listing.files.some((file) => /^(?:\.prettierrc(?:\.|$)|prettier\.config\.|biome\.jsonc?$|rustfmt\.toml$|\.clang-format$)/.test(file)))
|
|
175
|
+
add("quality-tools", "Formatter configuration found");
|
|
176
|
+
if (listing.files.some((file) => /^tsconfig(?:\..+)?\.json$/.test(file)))
|
|
177
|
+
add("quality-tools", "TypeScript configuration found");
|
|
178
|
+
if (listing.files.some((file) => /^(?:vitest\.config\.|jest\.config\.|playwright\.config\.|pytest\.ini$|phpunit\.xml)/.test(file)) ||
|
|
179
|
+
listing.files.some((file) => /_test\.go$/.test(file)))
|
|
180
|
+
add("tests", "Test configuration or test files found");
|
|
181
|
+
if (!listing.files.includes("package.json"))
|
|
182
|
+
continue;
|
|
183
|
+
const data = await manifest(directory === "." ? "package.json" : `${directory}/package.json`);
|
|
184
|
+
if (!data)
|
|
185
|
+
continue;
|
|
186
|
+
const scriptNames = Object.keys(data.scripts ?? {});
|
|
187
|
+
if (scriptNames.some((name) => /^(?:lint|format|typecheck|type-check|check)(?::|$)/.test(name)))
|
|
188
|
+
add("quality-tools", "Code quality scripts found");
|
|
189
|
+
if (scriptNames.some((name) => /^test(?::|$)/.test(name)))
|
|
190
|
+
add("tests", "Test script found");
|
|
191
|
+
if (scriptNames.some((name) => /^build(?::|$)/.test(name)))
|
|
192
|
+
add("build-release", "Build script found");
|
|
193
|
+
const dependencies = { ...data.dependencies, ...data.devDependencies };
|
|
194
|
+
if (["eslint", "prettier", "typescript", "@biomejs/biome"].some((name) => Object.hasOwn(dependencies, name)))
|
|
195
|
+
add("quality-tools", "Code quality tools declared");
|
|
196
|
+
if (["vitest", "jest", "@playwright/test", "mocha"].some((name) => Object.hasOwn(dependencies, name)))
|
|
197
|
+
add("tests", "Test runner declared");
|
|
198
|
+
}
|
|
199
|
+
try {
|
|
200
|
+
const git = await runBackgroundGit(["rev-parse", "--is-inside-work-tree"], {
|
|
201
|
+
cwd: root,
|
|
202
|
+
timeoutMs: 3000,
|
|
203
|
+
maxBuffer: 4096,
|
|
204
|
+
...(signal ? { signal } : {}),
|
|
205
|
+
});
|
|
206
|
+
if (git.stdout.trim() === "true")
|
|
207
|
+
add("git-github", "Git repository initialized");
|
|
208
|
+
}
|
|
209
|
+
catch {
|
|
210
|
+
// Not a worktree or Git unavailable: do not claim setup is missing.
|
|
211
|
+
}
|
|
212
|
+
const summaries = {
|
|
213
|
+
"agent-setup": "Agent instructions found",
|
|
214
|
+
docs: "Documentation found",
|
|
215
|
+
naming: "Project vocabulary found",
|
|
216
|
+
"git-github": facts.get("git-github")?.has("Git repository initialized")
|
|
217
|
+
? "Git initialized"
|
|
218
|
+
: "Ignore file found",
|
|
219
|
+
"quality-tools": "Tools or configuration detected",
|
|
220
|
+
tests: "Test setup found",
|
|
221
|
+
ci: "CI configuration found",
|
|
222
|
+
"commit-gate": "Commit check configuration found",
|
|
223
|
+
dependencies: "Lockfile found",
|
|
224
|
+
"build-release": "Build or release setup found",
|
|
225
|
+
};
|
|
226
|
+
for (const id of [...facts.keys()].sort()) {
|
|
227
|
+
const lines = facts.get(id);
|
|
228
|
+
if (lines?.size)
|
|
229
|
+
items[id] = { summary: summaries[id] ?? "Setup detected", facts: [...lines].sort() };
|
|
230
|
+
}
|
|
231
|
+
log("INFO", "checklist", "Detected project setup", {
|
|
232
|
+
cwd: root,
|
|
233
|
+
detectedItems: Object.keys(items).length,
|
|
234
|
+
elapsedMs: Date.now() - started,
|
|
235
|
+
});
|
|
236
|
+
return { items, warnings: [...warnings].sort() };
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=checklist-detection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checklist-detection.js","sourceRoot":"","sources":["../../src/core/checklist-detection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/** Days after which a recorded check comes back as due. */
|
|
2
|
+
export declare const CHECKLIST_STALE_DAYS = 30;
|
|
3
|
+
/** The record lives at the project root (not under `.gg/`, which many projects ignore). */
|
|
4
|
+
export declare const CHECKLIST_FILE = ".gg-checklist.json";
|
|
5
|
+
export declare const CHECKLIST_GROUPS: readonly ["Foundations", "Source control", "Code quality", "Design & UX", "Safety", "Performance", "Shipping"];
|
|
6
|
+
export type ChecklistGroup = (typeof CHECKLIST_GROUPS)[number];
|
|
7
|
+
export interface ChecklistItem {
|
|
8
|
+
readonly id: string;
|
|
9
|
+
readonly group: ChecklistGroup;
|
|
10
|
+
readonly title: string;
|
|
11
|
+
/** A short, first-person purpose hint shown as the item's tooltip. */
|
|
12
|
+
readonly description: string;
|
|
13
|
+
/** What the agent should inspect, written as instructions. */
|
|
14
|
+
readonly check: string;
|
|
15
|
+
/** Bundled skill to load before checking, when one fits. */
|
|
16
|
+
readonly skill?: string;
|
|
17
|
+
/** Built-in setup command that fixes most gaps, when one exists. */
|
|
18
|
+
readonly setupCommand?: string;
|
|
19
|
+
}
|
|
20
|
+
/** In recommended run order. */
|
|
21
|
+
export declare const CHECKLIST_ITEMS: readonly [{
|
|
22
|
+
readonly id: "agent-setup";
|
|
23
|
+
readonly group: "Foundations";
|
|
24
|
+
readonly title: "Agent setup";
|
|
25
|
+
readonly description: "I start here so the agent knows the project. /init can create or update project instructions.";
|
|
26
|
+
readonly check: "A context file (AGENTS.md or CLAUDE.md) exists, its commands and architecture notes match the code today, and the project has the skills its recurring work needs.";
|
|
27
|
+
readonly setupCommand: "init";
|
|
28
|
+
}, {
|
|
29
|
+
readonly id: "docs";
|
|
30
|
+
readonly group: "Foundations";
|
|
31
|
+
readonly title: "README & setup docs";
|
|
32
|
+
readonly description: "I check this so someone new can get the project running without asking me.";
|
|
33
|
+
readonly check: "The README says what the project is and how to install, run and test it; an example env file lists required settings; a licence file exists.";
|
|
34
|
+
}, {
|
|
35
|
+
readonly id: "naming";
|
|
36
|
+
readonly group: "Foundations";
|
|
37
|
+
readonly title: "Shared vocabulary";
|
|
38
|
+
readonly description: "I use this to keep names consistent and big decisions written down.";
|
|
39
|
+
readonly check: "Each domain concept has one name across code and docs, a glossary (CONTEXT.md or similar) exists for non-trivial domains, and hard-to-reverse decisions are recorded (ADRs).";
|
|
40
|
+
readonly skill: "shared-language";
|
|
41
|
+
}, {
|
|
42
|
+
readonly id: "git-github";
|
|
43
|
+
readonly group: "Source control";
|
|
44
|
+
readonly title: "Git & GitHub";
|
|
45
|
+
readonly description: "I use this to check the repo setup, ignore rules and protection for main.";
|
|
46
|
+
readonly check: "The project is a Git repo with a GitHub remote, .gitignore covers build output and local files, the main branch is protected (ruleset or branch protection, via `gh` when available), and no large binaries are committed.";
|
|
47
|
+
readonly setupCommand: "setup-ci";
|
|
48
|
+
}, {
|
|
49
|
+
readonly id: "secrets";
|
|
50
|
+
readonly group: "Source control";
|
|
51
|
+
readonly title: "Secrets kept out";
|
|
52
|
+
readonly description: "I check this for keys and passwords that slipped into the code or Git history.";
|
|
53
|
+
readonly check: "No API keys, tokens, passwords or private keys in tracked files or Git history; env files are ignored; secrets are read from the environment or a secret store.";
|
|
54
|
+
readonly skill: "bulletproof";
|
|
55
|
+
}, {
|
|
56
|
+
readonly id: "quality-tools";
|
|
57
|
+
readonly group: "Code quality";
|
|
58
|
+
readonly title: "Lint, format & type checks";
|
|
59
|
+
readonly description: "I use this to catch formatting, lint and type errors before they pile up.";
|
|
60
|
+
readonly check: "A linter, formatter and type checker (where the language has one) are configured, have scripts to run them, and pass when run now.";
|
|
61
|
+
}, {
|
|
62
|
+
readonly id: "tests";
|
|
63
|
+
readonly group: "Code quality";
|
|
64
|
+
readonly title: "Tests";
|
|
65
|
+
readonly description: "I use this to check that tests pass and cover the parts that really matter.";
|
|
66
|
+
readonly check: "A test suite exists, runs green now, and covers the critical paths with real code paths rather than mocks alone.";
|
|
67
|
+
readonly skill: "tdd";
|
|
68
|
+
}, {
|
|
69
|
+
readonly id: "ci";
|
|
70
|
+
readonly group: "Code quality";
|
|
71
|
+
readonly title: "CI";
|
|
72
|
+
readonly description: "I use this to check that every pull request gets built and tested automatically.";
|
|
73
|
+
readonly check: "CI runs build, lint and tests on every pull request and push to main, and the workflows are hardened (pinned actions, least-privilege permissions, no untrusted input in run steps).";
|
|
74
|
+
readonly setupCommand: "setup-ci";
|
|
75
|
+
}, {
|
|
76
|
+
readonly id: "commit-gate";
|
|
77
|
+
readonly group: "Code quality";
|
|
78
|
+
readonly title: "Commit checks";
|
|
79
|
+
readonly description: "I use this to check that /commit runs checks and a review before saving a commit.";
|
|
80
|
+
readonly check: "A project /commit command exists that runs the project's checks and a review before committing.";
|
|
81
|
+
readonly setupCommand: "setup-commit";
|
|
82
|
+
}, {
|
|
83
|
+
readonly id: "code-health";
|
|
84
|
+
readonly group: "Code quality";
|
|
85
|
+
readonly title: "Code health";
|
|
86
|
+
readonly description: "I use this to spot dead code, repetition and files that are getting hard to work with.";
|
|
87
|
+
readonly check: "Look for duplicated logic, dead code, unused exports and very large files or functions that are hard to change safely.";
|
|
88
|
+
readonly skill: "refactoring";
|
|
89
|
+
}, {
|
|
90
|
+
readonly id: "errors-logging";
|
|
91
|
+
readonly group: "Code quality";
|
|
92
|
+
readonly title: "Errors & logging";
|
|
93
|
+
readonly description: "I use this to catch swallowed errors, confusing messages and leftover debug logs.";
|
|
94
|
+
readonly check: "Errors are handled at I/O boundaries with clear user-facing messages, nothing swallows errors silently, and there are no stray debug prints in shipped code.";
|
|
95
|
+
}, {
|
|
96
|
+
readonly id: "dependencies";
|
|
97
|
+
readonly group: "Code quality";
|
|
98
|
+
readonly title: "Dependencies";
|
|
99
|
+
readonly description: "I check this for risky, unused or abandoned packages.";
|
|
100
|
+
readonly check: "A lockfile is committed, the package manager's audit reports no known vulnerabilities, and there are no unused or abandoned packages.";
|
|
101
|
+
readonly skill: "bulletproof";
|
|
102
|
+
}, {
|
|
103
|
+
readonly id: "design-system";
|
|
104
|
+
readonly group: "Design & UX";
|
|
105
|
+
readonly title: "Design system";
|
|
106
|
+
readonly description: "I use this to check that colours, spacing and components come from one shared place.";
|
|
107
|
+
readonly check: "Colour, type, spacing and radius tokens are defined in one place and shared components exist for repeated UI. Not applicable without a UI.";
|
|
108
|
+
readonly skill: "evidence-led-ui";
|
|
109
|
+
}, {
|
|
110
|
+
readonly id: "styling-consistency";
|
|
111
|
+
readonly group: "Design & UX";
|
|
112
|
+
readonly title: "Consistent styling";
|
|
113
|
+
readonly description: "I use this to catch one-off styles that don't match the rest of the app.";
|
|
114
|
+
readonly check: "Find hard-coded colours and sizes and one-off styles where shared tokens or components already exist. Not applicable without a UI.";
|
|
115
|
+
readonly skill: "evidence-led-ui";
|
|
116
|
+
}, {
|
|
117
|
+
readonly id: "motion-consistency";
|
|
118
|
+
readonly group: "Design & UX";
|
|
119
|
+
readonly title: "Consistent animation";
|
|
120
|
+
readonly description: "I use this to keep animations consistent and check they respect reduced motion.";
|
|
121
|
+
readonly check: "Animations use shared durations and easings, and reduced-motion preferences are respected. Not applicable without a UI.";
|
|
122
|
+
readonly skill: "evidence-led-ui";
|
|
123
|
+
}, {
|
|
124
|
+
readonly id: "accessibility";
|
|
125
|
+
readonly group: "Design & UX";
|
|
126
|
+
readonly title: "Accessibility";
|
|
127
|
+
readonly description: "I use this to catch things that make the app hard to read or use without a mouse.";
|
|
128
|
+
readonly check: "Text contrast is sufficient, everything works by keyboard with visible focus, and controls and images have labels or alt text. Not applicable without a UI.";
|
|
129
|
+
readonly skill: "evidence-led-ui";
|
|
130
|
+
}, {
|
|
131
|
+
readonly id: "ui-states";
|
|
132
|
+
readonly group: "Design & UX";
|
|
133
|
+
readonly title: "Loading, empty & error states";
|
|
134
|
+
readonly description: "I check what people see while loading, when there's nothing to show or when things break.";
|
|
135
|
+
readonly check: "Every screen handles loading, empty and error states, and layouts survive small screens and long text. Not applicable without a UI.";
|
|
136
|
+
readonly skill: "evidence-led-ui";
|
|
137
|
+
}, {
|
|
138
|
+
readonly id: "security";
|
|
139
|
+
readonly group: "Safety";
|
|
140
|
+
readonly title: "Security audit";
|
|
141
|
+
readonly description: "I use this to look for security holes before shipping.";
|
|
142
|
+
readonly check: "Run a full security audit of the project following the skill.";
|
|
143
|
+
readonly skill: "bulletproof";
|
|
144
|
+
}, {
|
|
145
|
+
readonly id: "data-safety";
|
|
146
|
+
readonly group: "Safety";
|
|
147
|
+
readonly title: "Data safety";
|
|
148
|
+
readonly description: "I use this to check backups and catch changes that could lose someone's data.";
|
|
149
|
+
readonly check: "Migrations are reversible or guarded, backups exist for real data, and destructive operations are confirmed and recoverable. Not applicable without stored data.";
|
|
150
|
+
readonly skill: "durable";
|
|
151
|
+
}, {
|
|
152
|
+
readonly id: "compliance";
|
|
153
|
+
readonly group: "Safety";
|
|
154
|
+
readonly title: "Compliance";
|
|
155
|
+
readonly description: "I check this for gaps around privacy, cookies, payments and licences.";
|
|
156
|
+
readonly check: "Privacy policy and terms exist where users or personal data are involved, cookies and payments follow the rules, and dependency licences are compatible.";
|
|
157
|
+
readonly skill: "compliance-guard";
|
|
158
|
+
}, {
|
|
159
|
+
readonly id: "performance";
|
|
160
|
+
readonly group: "Performance";
|
|
161
|
+
readonly title: "Performance audit";
|
|
162
|
+
readonly description: "I use this to catch slow spots and things wasting memory.";
|
|
163
|
+
readonly check: "Run a full performance audit of the project following the skill.";
|
|
164
|
+
readonly skill: "lean";
|
|
165
|
+
}, {
|
|
166
|
+
readonly id: "build-release";
|
|
167
|
+
readonly group: "Shipping";
|
|
168
|
+
readonly title: "Build & release";
|
|
169
|
+
readonly description: "I use this to check that a fresh copy builds and the release steps are clear.";
|
|
170
|
+
readonly check: "The project builds from a clean clone with documented steps, versions are tracked, a changelog exists, and releases are documented or automated.";
|
|
171
|
+
}, {
|
|
172
|
+
readonly id: "monitoring";
|
|
173
|
+
readonly group: "Shipping";
|
|
174
|
+
readonly title: "Error reporting";
|
|
175
|
+
readonly description: "I use this to check that I'll hear about crashes and know where to look.";
|
|
176
|
+
readonly check: "Crashes and errors are reported somewhere the team sees them, logs can be found, and services have health checks where relevant. Not applicable for code with no running deployment.";
|
|
177
|
+
}];
|
|
178
|
+
export type ChecklistId = (typeof CHECKLIST_ITEMS)[number]["id"];
|
|
179
|
+
export declare const CHECKLIST_IDS: [ChecklistId, ...ChecklistId[]];
|
|
180
|
+
export declare function getChecklistItem(id: string): ChecklistItem | undefined;
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
// The built-in project health checklist: one definition list shared by the
|
|
2
|
+
// `checklist` tool, the run prompt (`checklist-prompt.ts`) and the app's
|
|
3
|
+
// Checklist screen, so the three can never drift apart.
|
|
4
|
+
/** Days after which a recorded check comes back as due. */
|
|
5
|
+
export const CHECKLIST_STALE_DAYS = 30;
|
|
6
|
+
/** The record lives at the project root (not under `.gg/`, which many projects ignore). */
|
|
7
|
+
export const CHECKLIST_FILE = ".gg-checklist.json";
|
|
8
|
+
export const CHECKLIST_GROUPS = [
|
|
9
|
+
"Foundations",
|
|
10
|
+
"Source control",
|
|
11
|
+
"Code quality",
|
|
12
|
+
"Design & UX",
|
|
13
|
+
"Safety",
|
|
14
|
+
"Performance",
|
|
15
|
+
"Shipping",
|
|
16
|
+
];
|
|
17
|
+
/** In recommended run order. */
|
|
18
|
+
export const CHECKLIST_ITEMS = [
|
|
19
|
+
{
|
|
20
|
+
id: "agent-setup",
|
|
21
|
+
group: "Foundations",
|
|
22
|
+
title: "Agent setup",
|
|
23
|
+
description: "I start here so the agent knows the project. /init can create or update project instructions.",
|
|
24
|
+
check: "A context file (AGENTS.md or CLAUDE.md) exists, its commands and architecture notes match the code today, and the project has the skills its recurring work needs.",
|
|
25
|
+
setupCommand: "init",
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
id: "docs",
|
|
29
|
+
group: "Foundations",
|
|
30
|
+
title: "README & setup docs",
|
|
31
|
+
description: "I check this so someone new can get the project running without asking me.",
|
|
32
|
+
check: "The README says what the project is and how to install, run and test it; an example env file lists required settings; a licence file exists.",
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: "naming",
|
|
36
|
+
group: "Foundations",
|
|
37
|
+
title: "Shared vocabulary",
|
|
38
|
+
description: "I use this to keep names consistent and big decisions written down.",
|
|
39
|
+
check: "Each domain concept has one name across code and docs, a glossary (CONTEXT.md or similar) exists for non-trivial domains, and hard-to-reverse decisions are recorded (ADRs).",
|
|
40
|
+
skill: "shared-language",
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: "git-github",
|
|
44
|
+
group: "Source control",
|
|
45
|
+
title: "Git & GitHub",
|
|
46
|
+
description: "I use this to check the repo setup, ignore rules and protection for main.",
|
|
47
|
+
check: "The project is a Git repo with a GitHub remote, .gitignore covers build output and local files, the main branch is protected (ruleset or branch protection, via `gh` when available), and no large binaries are committed.",
|
|
48
|
+
setupCommand: "setup-ci",
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: "secrets",
|
|
52
|
+
group: "Source control",
|
|
53
|
+
title: "Secrets kept out",
|
|
54
|
+
description: "I check this for keys and passwords that slipped into the code or Git history.",
|
|
55
|
+
check: "No API keys, tokens, passwords or private keys in tracked files or Git history; env files are ignored; secrets are read from the environment or a secret store.",
|
|
56
|
+
skill: "bulletproof",
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
id: "quality-tools",
|
|
60
|
+
group: "Code quality",
|
|
61
|
+
title: "Lint, format & type checks",
|
|
62
|
+
description: "I use this to catch formatting, lint and type errors before they pile up.",
|
|
63
|
+
check: "A linter, formatter and type checker (where the language has one) are configured, have scripts to run them, and pass when run now.",
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
id: "tests",
|
|
67
|
+
group: "Code quality",
|
|
68
|
+
title: "Tests",
|
|
69
|
+
description: "I use this to check that tests pass and cover the parts that really matter.",
|
|
70
|
+
check: "A test suite exists, runs green now, and covers the critical paths with real code paths rather than mocks alone.",
|
|
71
|
+
skill: "tdd",
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
id: "ci",
|
|
75
|
+
group: "Code quality",
|
|
76
|
+
title: "CI",
|
|
77
|
+
description: "I use this to check that every pull request gets built and tested automatically.",
|
|
78
|
+
check: "CI runs build, lint and tests on every pull request and push to main, and the workflows are hardened (pinned actions, least-privilege permissions, no untrusted input in run steps).",
|
|
79
|
+
setupCommand: "setup-ci",
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
id: "commit-gate",
|
|
83
|
+
group: "Code quality",
|
|
84
|
+
title: "Commit checks",
|
|
85
|
+
description: "I use this to check that /commit runs checks and a review before saving a commit.",
|
|
86
|
+
check: "A project /commit command exists that runs the project's checks and a review before committing.",
|
|
87
|
+
setupCommand: "setup-commit",
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
id: "code-health",
|
|
91
|
+
group: "Code quality",
|
|
92
|
+
title: "Code health",
|
|
93
|
+
description: "I use this to spot dead code, repetition and files that are getting hard to work with.",
|
|
94
|
+
check: "Look for duplicated logic, dead code, unused exports and very large files or functions that are hard to change safely.",
|
|
95
|
+
skill: "refactoring",
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
id: "errors-logging",
|
|
99
|
+
group: "Code quality",
|
|
100
|
+
title: "Errors & logging",
|
|
101
|
+
description: "I use this to catch swallowed errors, confusing messages and leftover debug logs.",
|
|
102
|
+
check: "Errors are handled at I/O boundaries with clear user-facing messages, nothing swallows errors silently, and there are no stray debug prints in shipped code.",
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
id: "dependencies",
|
|
106
|
+
group: "Code quality",
|
|
107
|
+
title: "Dependencies",
|
|
108
|
+
description: "I check this for risky, unused or abandoned packages.",
|
|
109
|
+
check: "A lockfile is committed, the package manager's audit reports no known vulnerabilities, and there are no unused or abandoned packages.",
|
|
110
|
+
skill: "bulletproof",
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
id: "design-system",
|
|
114
|
+
group: "Design & UX",
|
|
115
|
+
title: "Design system",
|
|
116
|
+
description: "I use this to check that colours, spacing and components come from one shared place.",
|
|
117
|
+
check: "Colour, type, spacing and radius tokens are defined in one place and shared components exist for repeated UI. Not applicable without a UI.",
|
|
118
|
+
skill: "evidence-led-ui",
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
id: "styling-consistency",
|
|
122
|
+
group: "Design & UX",
|
|
123
|
+
title: "Consistent styling",
|
|
124
|
+
description: "I use this to catch one-off styles that don't match the rest of the app.",
|
|
125
|
+
check: "Find hard-coded colours and sizes and one-off styles where shared tokens or components already exist. Not applicable without a UI.",
|
|
126
|
+
skill: "evidence-led-ui",
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
id: "motion-consistency",
|
|
130
|
+
group: "Design & UX",
|
|
131
|
+
title: "Consistent animation",
|
|
132
|
+
description: "I use this to keep animations consistent and check they respect reduced motion.",
|
|
133
|
+
check: "Animations use shared durations and easings, and reduced-motion preferences are respected. Not applicable without a UI.",
|
|
134
|
+
skill: "evidence-led-ui",
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
id: "accessibility",
|
|
138
|
+
group: "Design & UX",
|
|
139
|
+
title: "Accessibility",
|
|
140
|
+
description: "I use this to catch things that make the app hard to read or use without a mouse.",
|
|
141
|
+
check: "Text contrast is sufficient, everything works by keyboard with visible focus, and controls and images have labels or alt text. Not applicable without a UI.",
|
|
142
|
+
skill: "evidence-led-ui",
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
id: "ui-states",
|
|
146
|
+
group: "Design & UX",
|
|
147
|
+
title: "Loading, empty & error states",
|
|
148
|
+
description: "I check what people see while loading, when there's nothing to show or when things break.",
|
|
149
|
+
check: "Every screen handles loading, empty and error states, and layouts survive small screens and long text. Not applicable without a UI.",
|
|
150
|
+
skill: "evidence-led-ui",
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
id: "security",
|
|
154
|
+
group: "Safety",
|
|
155
|
+
title: "Security audit",
|
|
156
|
+
description: "I use this to look for security holes before shipping.",
|
|
157
|
+
check: "Run a full security audit of the project following the skill.",
|
|
158
|
+
skill: "bulletproof",
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
id: "data-safety",
|
|
162
|
+
group: "Safety",
|
|
163
|
+
title: "Data safety",
|
|
164
|
+
description: "I use this to check backups and catch changes that could lose someone's data.",
|
|
165
|
+
check: "Migrations are reversible or guarded, backups exist for real data, and destructive operations are confirmed and recoverable. Not applicable without stored data.",
|
|
166
|
+
skill: "durable",
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
id: "compliance",
|
|
170
|
+
group: "Safety",
|
|
171
|
+
title: "Compliance",
|
|
172
|
+
description: "I check this for gaps around privacy, cookies, payments and licences.",
|
|
173
|
+
check: "Privacy policy and terms exist where users or personal data are involved, cookies and payments follow the rules, and dependency licences are compatible.",
|
|
174
|
+
skill: "compliance-guard",
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
id: "performance",
|
|
178
|
+
group: "Performance",
|
|
179
|
+
title: "Performance audit",
|
|
180
|
+
description: "I use this to catch slow spots and things wasting memory.",
|
|
181
|
+
check: "Run a full performance audit of the project following the skill.",
|
|
182
|
+
skill: "lean",
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
id: "build-release",
|
|
186
|
+
group: "Shipping",
|
|
187
|
+
title: "Build & release",
|
|
188
|
+
description: "I use this to check that a fresh copy builds and the release steps are clear.",
|
|
189
|
+
check: "The project builds from a clean clone with documented steps, versions are tracked, a changelog exists, and releases are documented or automated.",
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
id: "monitoring",
|
|
193
|
+
group: "Shipping",
|
|
194
|
+
title: "Error reporting",
|
|
195
|
+
description: "I use this to check that I'll hear about crashes and know where to look.",
|
|
196
|
+
check: "Crashes and errors are reported somewhere the team sees them, logs can be found, and services have health checks where relevant. Not applicable for code with no running deployment.",
|
|
197
|
+
},
|
|
198
|
+
];
|
|
199
|
+
export const CHECKLIST_IDS = CHECKLIST_ITEMS.map((item) => item.id);
|
|
200
|
+
const ITEMS_BY_ID = new Map(CHECKLIST_ITEMS.map((item) => [item.id, item]));
|
|
201
|
+
export function getChecklistItem(id) {
|
|
202
|
+
return ITEMS_BY_ID.get(id);
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=checklist-items.js.map
|