@dev-guard/cli 0.1.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/LICENSE +21 -0
- package/README.md +79 -0
- package/dist/agent-strategies.d.ts +23 -0
- package/dist/agent-strategies.js +130 -0
- package/dist/agent-strategies.js.map +1 -0
- package/dist/ai-context.d.ts +10 -0
- package/dist/ai-context.js +143 -0
- package/dist/ai-context.js.map +1 -0
- package/dist/check.d.ts +6 -0
- package/dist/check.js +89 -0
- package/dist/check.js.map +1 -0
- package/dist/clipboard.d.ts +6 -0
- package/dist/clipboard.js +43 -0
- package/dist/clipboard.js.map +1 -0
- package/dist/codex-notify.d.ts +23 -0
- package/dist/codex-notify.js +146 -0
- package/dist/codex-notify.js.map +1 -0
- package/dist/command-targets.d.ts +10 -0
- package/dist/command-targets.js +124 -0
- package/dist/command-targets.js.map +1 -0
- package/dist/config.d.ts +22 -0
- package/dist/config.js +180 -0
- package/dist/config.js.map +1 -0
- package/dist/configure.d.ts +1 -0
- package/dist/configure.js +79 -0
- package/dist/configure.js.map +1 -0
- package/dist/doctor.d.ts +1 -0
- package/dist/doctor.js +326 -0
- package/dist/doctor.js.map +1 -0
- package/dist/drift-telemetry.d.ts +13 -0
- package/dist/drift-telemetry.js +64 -0
- package/dist/drift-telemetry.js.map +1 -0
- package/dist/effective-task.d.ts +44 -0
- package/dist/effective-task.js +355 -0
- package/dist/effective-task.js.map +1 -0
- package/dist/fs.d.ts +10 -0
- package/dist/fs.js +58 -0
- package/dist/fs.js.map +1 -0
- package/dist/git.d.ts +24 -0
- package/dist/git.js +235 -0
- package/dist/git.js.map +1 -0
- package/dist/hooks.d.ts +39 -0
- package/dist/hooks.js +513 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +555 -0
- package/dist/index.js.map +1 -0
- package/dist/infer-task.d.ts +1 -0
- package/dist/infer-task.js +120 -0
- package/dist/infer-task.js.map +1 -0
- package/dist/init.d.ts +1 -0
- package/dist/init.js +50 -0
- package/dist/init.js.map +1 -0
- package/dist/install-agent-instructions.d.ts +1 -0
- package/dist/install-agent-instructions.js +113 -0
- package/dist/install-agent-instructions.js.map +1 -0
- package/dist/migration.d.ts +8 -0
- package/dist/migration.js +43 -0
- package/dist/migration.js.map +1 -0
- package/dist/paths.d.ts +38 -0
- package/dist/paths.js +41 -0
- package/dist/paths.js.map +1 -0
- package/dist/project-detection.d.ts +10 -0
- package/dist/project-detection.js +144 -0
- package/dist/project-detection.js.map +1 -0
- package/dist/project-identity.d.ts +7 -0
- package/dist/project-identity.js +93 -0
- package/dist/project-identity.js.map +1 -0
- package/dist/project-memory.d.ts +4 -0
- package/dist/project-memory.js +32 -0
- package/dist/project-memory.js.map +1 -0
- package/dist/prompt.d.ts +13 -0
- package/dist/prompt.js +125 -0
- package/dist/prompt.js.map +1 -0
- package/dist/refresh.d.ts +15 -0
- package/dist/refresh.js +146 -0
- package/dist/refresh.js.map +1 -0
- package/dist/report.d.ts +1 -0
- package/dist/report.js +109 -0
- package/dist/report.js.map +1 -0
- package/dist/review.d.ts +2 -0
- package/dist/review.js +653 -0
- package/dist/review.js.map +1 -0
- package/dist/rule-filter.d.ts +8 -0
- package/dist/rule-filter.js +79 -0
- package/dist/rule-filter.js.map +1 -0
- package/dist/runs.d.ts +21 -0
- package/dist/runs.js +142 -0
- package/dist/runs.js.map +1 -0
- package/dist/runtime-state.d.ts +69 -0
- package/dist/runtime-state.js +1383 -0
- package/dist/runtime-state.js.map +1 -0
- package/dist/scan.d.ts +1 -0
- package/dist/scan.js +55 -0
- package/dist/scan.js.map +1 -0
- package/dist/self.d.ts +3 -0
- package/dist/self.js +235 -0
- package/dist/self.js.map +1 -0
- package/dist/task-ai.d.ts +1 -0
- package/dist/task-ai.js +643 -0
- package/dist/task-ai.js.map +1 -0
- package/dist/telemetry.d.ts +1 -0
- package/dist/telemetry.js +11 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/update.d.ts +6 -0
- package/dist/update.js +154 -0
- package/dist/update.js.map +1 -0
- package/dist/watch.d.ts +1 -0
- package/dist/watch.js +303 -0
- package/dist/watch.js.map +1 -0
- package/package.json +31 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 everyshare
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# dev-guard CLI
|
|
2
|
+
|
|
3
|
+
`dev-guard` is a local CLI guardrail for Codex / Claude coding workflows. It watches project changes, processes completed work, and generates quality reports plus handoff prompts under `.devguard/`.
|
|
4
|
+
|
|
5
|
+
## Install Or Update
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @dev-guard/cli@latest
|
|
9
|
+
dev-guard --help
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Run without a global install:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npx @dev-guard/cli --help
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Initial Setup
|
|
19
|
+
|
|
20
|
+
Run from your project root:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
dev-guard init
|
|
24
|
+
dev-guard install-agent-instructions
|
|
25
|
+
dev-guard install-hooks
|
|
26
|
+
dev-guard status
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## GPT Setup
|
|
30
|
+
|
|
31
|
+
The default `watch`, `done`, `status`, and `handoff` workflow does not require GPT/API setup. Configure an OpenAI provider only for AI-assisted commands such as `review`, `task-ai`, and `prompt`.
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
export OPENAI_API_KEY="your_api_key"
|
|
35
|
+
dev-guard configure ai --provider openai --model gpt-4o-mini
|
|
36
|
+
dev-guard config show
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Do not store API keys in project files.
|
|
40
|
+
|
|
41
|
+
## Agent Instruction Files
|
|
42
|
+
|
|
43
|
+
`dev-guard install-agent-instructions` creates or updates `AGENTS.md` and `CLAUDE.md` with instructions to read:
|
|
44
|
+
|
|
45
|
+
- `.devguard/context/agent-context.md`
|
|
46
|
+
- `.devguard/reports/project-handoff.md`
|
|
47
|
+
- `.devguard/reports/quality-report.md`
|
|
48
|
+
|
|
49
|
+
This keeps new Codex / Claude sessions aligned with the latest dev-guard state before broad repository exploration.
|
|
50
|
+
|
|
51
|
+
## Daily CLI Flow
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
dev-guard watch
|
|
55
|
+
# Codex/Claude edits files; verified hook/notify runs dev-guard done
|
|
56
|
+
dev-guard status
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Manual fallback:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
dev-guard watch --manual
|
|
63
|
+
dev-guard done
|
|
64
|
+
dev-guard status
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Resume a new session:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
dev-guard handoff
|
|
71
|
+
cat .devguard/reports/project-handoff.md
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Full documentation:
|
|
75
|
+
|
|
76
|
+
- Korean npm guide: https://github.com/projectbom/dev-guard/blob/main/docs/npm-setup.ko.md
|
|
77
|
+
- English npm guide: https://github.com/projectbom/dev-guard/blob/main/docs/npm-setup.md
|
|
78
|
+
- Repository README: https://github.com/projectbom/dev-guard
|
|
79
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export type AgentStrategyName = "claude-stop-hook" | "codex-notify" | "codex-stop-hook" | "codex-jsonl-listener" | "manual";
|
|
2
|
+
export interface AgentStrategyStatus {
|
|
3
|
+
name: AgentStrategyName;
|
|
4
|
+
agent: "Claude Code" | "Codex" | "Manual";
|
|
5
|
+
available: boolean;
|
|
6
|
+
installed: boolean;
|
|
7
|
+
scriptVerified: boolean;
|
|
8
|
+
runtimeVerified: boolean;
|
|
9
|
+
requiresUserTrust: boolean;
|
|
10
|
+
recommended: boolean;
|
|
11
|
+
next: string;
|
|
12
|
+
}
|
|
13
|
+
export interface AgentStrategyReport {
|
|
14
|
+
strategies: AgentStrategyStatus[];
|
|
15
|
+
claude: AgentStrategyStatus;
|
|
16
|
+
codexNotify: AgentStrategyStatus;
|
|
17
|
+
codexStopHook: AgentStrategyStatus;
|
|
18
|
+
codexJsonlListener: AgentStrategyStatus;
|
|
19
|
+
manual: AgentStrategyStatus;
|
|
20
|
+
}
|
|
21
|
+
export declare function getAgentStrategyReport(root: string): Promise<AgentStrategyReport>;
|
|
22
|
+
export declare function formatStrategyFlag(value: boolean): string;
|
|
23
|
+
export declare function pathExists(root: string, path: string): Promise<boolean>;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { constants, existsSync } from "node:fs";
|
|
2
|
+
import { access, stat } from "node:fs/promises";
|
|
3
|
+
import { spawnSync } from "node:child_process";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { fromRoot, readTextFile } from "./fs.js";
|
|
7
|
+
import { getHookStatus, hookConfigPaths } from "./hooks.js";
|
|
8
|
+
import { devguardPaths } from "./paths.js";
|
|
9
|
+
import { getCodexNotifyConfigStatus } from "./codex-notify.js";
|
|
10
|
+
const codexUserConfigPath = join(homedir(), ".codex", "config.toml");
|
|
11
|
+
export async function getAgentStrategyReport(root) {
|
|
12
|
+
const hookStatus = await getHookStatus(root);
|
|
13
|
+
const [claudeScriptVerified, codexStopScriptVerified, codexNotifyScriptVerified, codexJsonlScriptVerified] = await Promise.all([
|
|
14
|
+
isExecutable(root, devguardPaths.claudeHook),
|
|
15
|
+
isExecutable(root, devguardPaths.codexHook),
|
|
16
|
+
isExecutable(root, devguardPaths.codexNotifyHook),
|
|
17
|
+
isExecutable(root, devguardPaths.codexEventListener)
|
|
18
|
+
]);
|
|
19
|
+
const codexNotifyInstalled = await isCodexNotifyConfigured(root);
|
|
20
|
+
const codexNotifyConfig = await getCodexNotifyConfigStatus();
|
|
21
|
+
const codexNotifyRuntimeVerified = await hasFinalLogLine(root, devguardPaths.codexNotifyLog, /hook=codex\.notify status=success\b.*source=agent_runtime\b/);
|
|
22
|
+
const codexJsonlRuntimeVerified = await hasFinalLogLine(root, devguardPaths.codexLog, /hook=codex\.turn\.completed status=success\b/);
|
|
23
|
+
const claudeInstalled = hookStatus.claudeInstalled && hookStatus.claudeHookFile;
|
|
24
|
+
const codexStopInstalled = hookStatus.codexInstalled && hookStatus.codexHookFile;
|
|
25
|
+
const codexCliAvailable = commandAvailable("codex");
|
|
26
|
+
const claudeRuntimeVerified = await hasFinalLogLine(root, devguardPaths.claudeLog, /hook=claude\.stop status=success\b/);
|
|
27
|
+
const codexStopRuntimeVerified = await hasFinalLogLine(root, devguardPaths.codexLog, /hook=codex\.stop status=success\b.*source=agent_runtime\b/);
|
|
28
|
+
const claude = {
|
|
29
|
+
name: "claude-stop-hook",
|
|
30
|
+
agent: "Claude Code",
|
|
31
|
+
available: commandAvailable("claude") || existsSync(fromRoot(root, hookConfigPaths.claudeSettingsPath)),
|
|
32
|
+
installed: claudeInstalled,
|
|
33
|
+
scriptVerified: claudeScriptVerified,
|
|
34
|
+
runtimeVerified: claudeRuntimeVerified,
|
|
35
|
+
requiresUserTrust: false,
|
|
36
|
+
recommended: true,
|
|
37
|
+
next: claudeRuntimeVerified ? "Claude Stop Hook runtime verified." : "Run Claude Code in this repo and check .devguard/logs/claude-hook.log."
|
|
38
|
+
};
|
|
39
|
+
const codexNotify = {
|
|
40
|
+
name: "codex-notify",
|
|
41
|
+
agent: "Codex",
|
|
42
|
+
available: codexCliAvailable,
|
|
43
|
+
installed: codexNotifyInstalled || codexNotifyConfig.notifyIsDispatcher,
|
|
44
|
+
scriptVerified: codexNotifyScriptVerified,
|
|
45
|
+
runtimeVerified: codexNotifyRuntimeVerified,
|
|
46
|
+
requiresUserTrust: false,
|
|
47
|
+
recommended: true,
|
|
48
|
+
next: codexNotifyConfig.existingNotifyDetected
|
|
49
|
+
? "Existing Codex notify detected. Run dev-guard install-hooks --agent codex-notify --install-dispatcher."
|
|
50
|
+
: codexNotifyInstalled || codexNotifyConfig.notifyIsDispatcher
|
|
51
|
+
? "Run a Codex turn and check .devguard/logs/codex-notify.log."
|
|
52
|
+
: "Configure user-level ~/.codex/config.toml notify to call .devguard/hooks/codex-notify.sh."
|
|
53
|
+
};
|
|
54
|
+
const codexStopHook = {
|
|
55
|
+
name: "codex-stop-hook",
|
|
56
|
+
agent: "Codex",
|
|
57
|
+
available: codexCliAvailable,
|
|
58
|
+
installed: codexStopInstalled,
|
|
59
|
+
scriptVerified: codexStopScriptVerified,
|
|
60
|
+
runtimeVerified: codexStopRuntimeVerified,
|
|
61
|
+
requiresUserTrust: true,
|
|
62
|
+
recommended: false,
|
|
63
|
+
next: codexStopRuntimeVerified ? "Codex Stop Hook runtime verified." : "Open Codex TUI in this repo and run /hooks to review/trust the Stop Hook."
|
|
64
|
+
};
|
|
65
|
+
const codexJsonlListener = {
|
|
66
|
+
name: "codex-jsonl-listener",
|
|
67
|
+
agent: "Codex",
|
|
68
|
+
available: codexCliAvailable,
|
|
69
|
+
installed: existsSync(fromRoot(root, devguardPaths.codexEventListener)),
|
|
70
|
+
scriptVerified: codexJsonlScriptVerified,
|
|
71
|
+
runtimeVerified: codexJsonlRuntimeVerified,
|
|
72
|
+
requiresUserTrust: false,
|
|
73
|
+
recommended: false,
|
|
74
|
+
next: "Use codex exec --json ... | .devguard/hooks/codex-event-listener.ts for non-interactive runs."
|
|
75
|
+
};
|
|
76
|
+
const manual = {
|
|
77
|
+
name: "manual",
|
|
78
|
+
agent: "Manual",
|
|
79
|
+
available: true,
|
|
80
|
+
installed: true,
|
|
81
|
+
scriptVerified: true,
|
|
82
|
+
runtimeVerified: true,
|
|
83
|
+
requiresUserTrust: false,
|
|
84
|
+
recommended: false,
|
|
85
|
+
next: "Run dev-guard done when the agent task finishes."
|
|
86
|
+
};
|
|
87
|
+
return {
|
|
88
|
+
strategies: [claude, codexNotify, codexStopHook, codexJsonlListener, manual],
|
|
89
|
+
claude,
|
|
90
|
+
codexNotify,
|
|
91
|
+
codexStopHook,
|
|
92
|
+
codexJsonlListener,
|
|
93
|
+
manual
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
export function formatStrategyFlag(value) {
|
|
97
|
+
return value ? "yes" : "no";
|
|
98
|
+
}
|
|
99
|
+
async function isCodexNotifyConfigured(root) {
|
|
100
|
+
const text = await readTextFile(codexUserConfigPath);
|
|
101
|
+
if (!text)
|
|
102
|
+
return false;
|
|
103
|
+
return text.includes(fromRoot(root, devguardPaths.codexNotifyHook)) || text.includes(devguardPaths.codexNotifyHook);
|
|
104
|
+
}
|
|
105
|
+
async function hasFinalLogLine(root, path, pattern) {
|
|
106
|
+
const text = await readTextFile(fromRoot(root, path));
|
|
107
|
+
return text.split(/\r?\n/).some((line) => pattern.test(line));
|
|
108
|
+
}
|
|
109
|
+
async function isExecutable(root, path) {
|
|
110
|
+
try {
|
|
111
|
+
await access(fromRoot(root, path), constants.X_OK);
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function commandAvailable(command) {
|
|
119
|
+
return spawnSync("sh", ["-c", `command -v ${command}`], { encoding: "utf8" }).status === 0;
|
|
120
|
+
}
|
|
121
|
+
export async function pathExists(root, path) {
|
|
122
|
+
try {
|
|
123
|
+
await stat(fromRoot(root, path));
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=agent-strategies.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-strategies.js","sourceRoot":"","sources":["../src/agent-strategies.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generates and writes .devguard/AI_CONTEXT.md.
|
|
3
|
+
* Called after refresh, infer-task --write, and task-ai --write.
|
|
4
|
+
* Silent on error to avoid breaking the main workflow.
|
|
5
|
+
*/
|
|
6
|
+
export declare function writeAIContext(root: string): Promise<void>;
|
|
7
|
+
/**
|
|
8
|
+
* Short preamble prepended to Codex/Claude prompts so they know to read AI_CONTEXT.md first.
|
|
9
|
+
*/
|
|
10
|
+
export declare function buildAIContextPreamble(): string;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { filterDevGuardContextFiles, inferDiffIntentClusters, scoreTaskAnchorFreshness } from "@dev-guard/core";
|
|
2
|
+
import { fromRoot, readJsonFile, readTextFile, writeTextFile } from "./fs.js";
|
|
3
|
+
import { getGitChanges } from "./git.js";
|
|
4
|
+
/**
|
|
5
|
+
* Generates and writes .devguard/AI_CONTEXT.md.
|
|
6
|
+
* Called after refresh, infer-task --write, and task-ai --write.
|
|
7
|
+
* Silent on error to avoid breaking the main workflow.
|
|
8
|
+
*/
|
|
9
|
+
export async function writeAIContext(root) {
|
|
10
|
+
const [gitChanges, taskMarkdown, codeGraph] = await Promise.all([
|
|
11
|
+
getGitChanges(root),
|
|
12
|
+
readTextFile(fromRoot(root, ".devguard/task.md")),
|
|
13
|
+
readJsonFile(fromRoot(root, ".devguard/code-graph.json"), [])
|
|
14
|
+
]);
|
|
15
|
+
const changeFiles = filterDevGuardContextFiles(gitChanges.changeFiles, false);
|
|
16
|
+
const changedFiles = [...new Set(changeFiles.map((f) => f.path))].sort();
|
|
17
|
+
const anchor = scoreTaskAnchorFreshness({
|
|
18
|
+
taskMarkdown,
|
|
19
|
+
diffText: gitChanges.diffText,
|
|
20
|
+
changedFiles,
|
|
21
|
+
changeFiles
|
|
22
|
+
});
|
|
23
|
+
const clusters = changedFiles.length > 0
|
|
24
|
+
? inferDiffIntentClusters({ changedFiles, changeFiles, diffText: gitChanges.diffText, codeGraph })
|
|
25
|
+
: null;
|
|
26
|
+
const content = generateAIContextMarkdown({ anchor, clusters, changedFiles, taskMarkdown });
|
|
27
|
+
await writeTextFile(fromRoot(root, ".devguard/AI_CONTEXT.md"), content);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Short preamble prepended to Codex/Claude prompts so they know to read AI_CONTEXT.md first.
|
|
31
|
+
*/
|
|
32
|
+
export function buildAIContextPreamble() {
|
|
33
|
+
return "Start by reading `.devguard/AI_CONTEXT.md` for task anchor and project context.\n\n---\n\n";
|
|
34
|
+
}
|
|
35
|
+
function generateAIContextMarkdown(input) {
|
|
36
|
+
const { anchor, clusters, changedFiles } = input;
|
|
37
|
+
const now = new Date().toISOString();
|
|
38
|
+
const anchorStatus = anchor.mode === "anchor_absent"
|
|
39
|
+
? "absent"
|
|
40
|
+
: anchor.mode === "stale"
|
|
41
|
+
? `stale (match score: ${anchor.matchScore})`
|
|
42
|
+
: anchor.mode === "uncertain"
|
|
43
|
+
? `uncertain (match score: ${anchor.matchScore})`
|
|
44
|
+
: `fresh (match score: ${anchor.matchScore})`;
|
|
45
|
+
const anchorMode = anchor.mode === "anchor_absent" || anchor.mode === "stale" ? "diff-first" : "task-first";
|
|
46
|
+
const taskSection = buildTaskSection(anchor, clusters, input.taskMarkdown);
|
|
47
|
+
const changedSection = changedFiles.length > 0
|
|
48
|
+
? [
|
|
49
|
+
...changedFiles.slice(0, 12).map((f) => `- ${f}`),
|
|
50
|
+
...(changedFiles.length > 12 ? [`- ... +${changedFiles.length - 12} more`] : [])
|
|
51
|
+
].join("\n")
|
|
52
|
+
: "- (no current changes)";
|
|
53
|
+
const readFirst = [
|
|
54
|
+
"- `.devguard/project-map.md` — project structure overview",
|
|
55
|
+
"- `.devguard/file-summaries.json` — per-file roles and keywords",
|
|
56
|
+
...(anchorMode === "task-first"
|
|
57
|
+
? ["- `.devguard/task.md` — current task specification", "- `docs/CURRENT_TASK.md` — task history (if relevant)"]
|
|
58
|
+
: [])
|
|
59
|
+
].join("\n");
|
|
60
|
+
return [
|
|
61
|
+
"# dev-guard AI Context",
|
|
62
|
+
`Generated: ${now}`,
|
|
63
|
+
"",
|
|
64
|
+
"Start here before scanning the full project.",
|
|
65
|
+
"",
|
|
66
|
+
"## Task Anchor",
|
|
67
|
+
`- status: ${anchorStatus}`,
|
|
68
|
+
`- mode: ${anchorMode}`,
|
|
69
|
+
"",
|
|
70
|
+
"## Current Task",
|
|
71
|
+
taskSection,
|
|
72
|
+
"",
|
|
73
|
+
"## Changed Files",
|
|
74
|
+
changedSection,
|
|
75
|
+
"",
|
|
76
|
+
"## Read First",
|
|
77
|
+
readFirst,
|
|
78
|
+
"",
|
|
79
|
+
"## Use If Needed",
|
|
80
|
+
"- `.devguard/code-graph.json` — import/export graph",
|
|
81
|
+
"- `docs/PROJECT_STATE.md` — project state",
|
|
82
|
+
"- `docs/DECISIONS.md` — past decisions",
|
|
83
|
+
"- `docs/DO_NOT_REPEAT.md` — mistakes to avoid",
|
|
84
|
+
"",
|
|
85
|
+
"## AI Rules",
|
|
86
|
+
"- Do not scan the whole project directory first.",
|
|
87
|
+
"- Use current git diff as source of truth when task anchor is absent or stale.",
|
|
88
|
+
"- Open targeted files only — use project-map + file-summaries for discovery.",
|
|
89
|
+
"- Verify stale context before trusting it.",
|
|
90
|
+
"- When task.md is fresh, treat it as the authoritative task specification.",
|
|
91
|
+
""
|
|
92
|
+
].join("\n");
|
|
93
|
+
}
|
|
94
|
+
function buildTaskSection(anchor, clusters, taskMarkdown) {
|
|
95
|
+
if (anchor.mode === "anchor_absent") {
|
|
96
|
+
if (!clusters)
|
|
97
|
+
return "- (no diff to infer from)";
|
|
98
|
+
const intent = clusters.primaryIntent;
|
|
99
|
+
return [
|
|
100
|
+
`- type: ${intent.type}`,
|
|
101
|
+
intent.subtype ? `- subtype: ${intent.subtype}` : "",
|
|
102
|
+
intent.targetCommand ? `- target: ${intent.targetCommand}` : "",
|
|
103
|
+
`- scope: ${intent.scope.join(", ") || "changed files"}`,
|
|
104
|
+
`- confidence: ${intent.confidence}`,
|
|
105
|
+
"- source: inferred from diff (task anchor absent)"
|
|
106
|
+
]
|
|
107
|
+
.filter(Boolean)
|
|
108
|
+
.join("\n");
|
|
109
|
+
}
|
|
110
|
+
if (anchor.mode === "stale") {
|
|
111
|
+
if (!clusters)
|
|
112
|
+
return "- (task.md stale, no diff)";
|
|
113
|
+
const intent = clusters.primaryIntent;
|
|
114
|
+
return [
|
|
115
|
+
`- type: ${intent.type}`,
|
|
116
|
+
intent.subtype ? `- subtype: ${intent.subtype}` : "",
|
|
117
|
+
`- scope: ${intent.scope.join(", ") || "changed files"}`,
|
|
118
|
+
`- confidence: ${intent.confidence}`,
|
|
119
|
+
anchor.taskType ? `- task.md type (stale): ${anchor.taskType}` : "",
|
|
120
|
+
"- source: inferred from diff (task.md stale)"
|
|
121
|
+
]
|
|
122
|
+
.filter(Boolean)
|
|
123
|
+
.join("\n");
|
|
124
|
+
}
|
|
125
|
+
// uncertain or use_task
|
|
126
|
+
const goalLine = extractTaskGoalLine(taskMarkdown);
|
|
127
|
+
return [
|
|
128
|
+
anchor.taskType ? `- type: ${anchor.taskType}` : "",
|
|
129
|
+
goalLine ? `- goal: ${goalLine}` : "",
|
|
130
|
+
anchor.mode === "uncertain"
|
|
131
|
+
? `- note: task.md uncertain (match score ${anchor.matchScore}), verify before trusting`
|
|
132
|
+
: "",
|
|
133
|
+
"- source: task.md"
|
|
134
|
+
]
|
|
135
|
+
.filter(Boolean)
|
|
136
|
+
.join("\n");
|
|
137
|
+
}
|
|
138
|
+
function extractTaskGoalLine(markdown) {
|
|
139
|
+
const match = markdown.match(/^##\s+목표\s*\n[-•]\s+(.+)/m) ??
|
|
140
|
+
markdown.match(/^##\s+Goal\s*\n[-•]\s+(.+)/im);
|
|
141
|
+
return match?.[1]?.trim().slice(0, 120);
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=ai-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-context.js","sourceRoot":"","sources":["../src/ai-context.ts"],"names":[],"mappings":"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"}
|
package/dist/check.d.ts
ADDED
package/dist/check.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { analyzeDiff, analyzeGeneratedDiffDrift } from "@dev-guard/core";
|
|
2
|
+
import { recordDriftTelemetry } from "./drift-telemetry.js";
|
|
3
|
+
import { fromRoot, readJsonFile, readTextFile } from "./fs.js";
|
|
4
|
+
import { getGitChanges, hasGitBaseline } from "./git.js";
|
|
5
|
+
import { loadConfig } from "./config.js";
|
|
6
|
+
export async function runCheck(root, options) {
|
|
7
|
+
const [gitChanges, taskText, rulesText, resolvedConfig, baseline, codeGraph] = await Promise.all([
|
|
8
|
+
getGitChanges(root),
|
|
9
|
+
readTextFile(fromRoot(root, ".devguard/task.md")),
|
|
10
|
+
readTextFile(fromRoot(root, ".devguard/rules.md")),
|
|
11
|
+
loadConfig(root),
|
|
12
|
+
hasGitBaseline(root),
|
|
13
|
+
readJsonFile(fromRoot(root, ".devguard/code-graph.json"), [])
|
|
14
|
+
]);
|
|
15
|
+
const report = analyzeDiff({
|
|
16
|
+
changedFiles: gitChanges.changedFiles,
|
|
17
|
+
changeFiles: gitChanges.changeFiles,
|
|
18
|
+
diffText: gitChanges.diffText,
|
|
19
|
+
taskText,
|
|
20
|
+
rulesText,
|
|
21
|
+
config: resolvedConfig.config,
|
|
22
|
+
includeContextFiles: options.includeContextFiles,
|
|
23
|
+
codeGraph
|
|
24
|
+
});
|
|
25
|
+
await recordDriftTelemetry(root, {
|
|
26
|
+
result: analyzeGeneratedDiffDrift({
|
|
27
|
+
requirementText: taskText,
|
|
28
|
+
taskMarkdown: taskText,
|
|
29
|
+
diffText: gitChanges.diffText,
|
|
30
|
+
changedFiles: report.changedFiles,
|
|
31
|
+
changeFiles: report.changeFiles
|
|
32
|
+
}),
|
|
33
|
+
source: "check:local",
|
|
34
|
+
subtype: taskText.match(/subtype:\s*([a-z_.]+)/i)?.[1]
|
|
35
|
+
}).catch((error) => console.error(`dev-guard check: telemetry warning: ${errorMessage(error)}`));
|
|
36
|
+
printReport(report, { mode: options.local ? "local heuristic" : "local heuristic", configSource: resolvedConfig.source, baseline });
|
|
37
|
+
}
|
|
38
|
+
function printReport(report, meta) {
|
|
39
|
+
console.log("dev-guard check");
|
|
40
|
+
console.log(`Mode: ${meta.mode}`);
|
|
41
|
+
console.log(`Config Source: ${meta.configSource}`);
|
|
42
|
+
if (!meta.baseline) {
|
|
43
|
+
console.log("Git baseline: none");
|
|
44
|
+
console.log("No git baseline found. Initial/untracked files can make check output noisy.");
|
|
45
|
+
console.log('Run: git add . && git commit -m "initial commit"');
|
|
46
|
+
}
|
|
47
|
+
console.log("");
|
|
48
|
+
console.log("Changed files:");
|
|
49
|
+
if (report.changeFiles.length === 0) {
|
|
50
|
+
console.log("- none");
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
printChangeSection("Working tree", report.changeFiles.filter((file) => file.source === "workingTree"));
|
|
54
|
+
printChangeSection("Staged", report.changeFiles.filter((file) => file.source === "staged"));
|
|
55
|
+
printChangeSection("Untracked", report.changeFiles.filter((file) => file.source === "untracked"));
|
|
56
|
+
}
|
|
57
|
+
console.log("");
|
|
58
|
+
console.log("Findings:");
|
|
59
|
+
if (report.findings.length === 0) {
|
|
60
|
+
console.log("- no warnings");
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
for (const finding of report.findings) {
|
|
64
|
+
const prefix = finding.severity === "warning" ? "warning" : "info";
|
|
65
|
+
console.log(`- [${prefix}] ${finding.title}`);
|
|
66
|
+
console.log(` ${finding.message}`);
|
|
67
|
+
if (finding.files && finding.files.length > 0) {
|
|
68
|
+
console.log(` files: ${finding.files.join(", ")}`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
console.log("");
|
|
73
|
+
console.log(`Docs update needed: ${report.docsUpdateNeeded ? "yes" : "no"}`);
|
|
74
|
+
}
|
|
75
|
+
function printChangeSection(title, files) {
|
|
76
|
+
console.log(`${title}:`);
|
|
77
|
+
if (files.length === 0) {
|
|
78
|
+
console.log("- none");
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
for (const file of files) {
|
|
82
|
+
const rename = file.oldPath ? ` from ${file.oldPath}` : "";
|
|
83
|
+
console.log(`- ${file.path} (${file.status}${rename})`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function errorMessage(error) {
|
|
87
|
+
return error instanceof Error ? error.message : String(error);
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../src/check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
export async function copyTextToClipboard(text) {
|
|
3
|
+
const command = clipboardCommand();
|
|
4
|
+
if (!command) {
|
|
5
|
+
return { ok: false, reason: "unsupported OS clipboard command" };
|
|
6
|
+
}
|
|
7
|
+
try {
|
|
8
|
+
await writeToCommand(command.command, command.args, text);
|
|
9
|
+
return { ok: true };
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
13
|
+
return { ok: false, reason };
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function writeToCommand(command, args, input) {
|
|
17
|
+
return new Promise((resolve, reject) => {
|
|
18
|
+
const child = spawn(command, args, { stdio: ["pipe", "ignore", "pipe"] });
|
|
19
|
+
let stderr = "";
|
|
20
|
+
child.stderr.on("data", (chunk) => {
|
|
21
|
+
stderr += chunk.toString("utf8");
|
|
22
|
+
});
|
|
23
|
+
child.on("error", reject);
|
|
24
|
+
child.on("close", (code) => {
|
|
25
|
+
if (code === 0) {
|
|
26
|
+
resolve();
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
reject(new Error(stderr.trim() || `${command} exited with code ${code}`));
|
|
30
|
+
});
|
|
31
|
+
child.stdin.end(input);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
function clipboardCommand() {
|
|
35
|
+
if (process.platform === "darwin") {
|
|
36
|
+
return { command: "pbcopy", args: [] };
|
|
37
|
+
}
|
|
38
|
+
if (process.platform === "win32") {
|
|
39
|
+
return { command: "clip", args: [] };
|
|
40
|
+
}
|
|
41
|
+
return { command: "wl-copy", args: [] };
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=clipboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clipboard.js","sourceRoot":"","sources":["../src/clipboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAAY;IACpD,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;IACnC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,kCAAkC,EAAE,CAAC;IACnE,CAAC;IAED,IAAI,CAAC;QACH,MAAM,cAAc,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAC1D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IACtB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACtE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAC/B,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,OAAe,EAAE,IAAc,EAAE,KAAa;IACpE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;QAC1E,IAAI,MAAM,GAAG,EAAE,CAAC;QAEhB,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACxC,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1B,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,IAAI,IAAI,KAAK,CAAC,EAAE,CAAC;gBACf,OAAO,EAAE,CAAC;gBACV,OAAO;YACT,CAAC;YAED,MAAM,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,qBAAqB,IAAI,EAAE,CAAC,CAAC,CAAC;QAC5E,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,gBAAgB;IACvB,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;IACzC,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;IACvC,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AAC1C,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface CodexNotifyConfigStatus {
|
|
2
|
+
configPath: string;
|
|
3
|
+
dispatcherPath: string;
|
|
4
|
+
dispatcherInstalled: boolean;
|
|
5
|
+
notify?: string[];
|
|
6
|
+
notifyConfigured: boolean;
|
|
7
|
+
notifyIsDispatcher: boolean;
|
|
8
|
+
existingNotifyDetected: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface InstallCodexNotifyDispatcherResult {
|
|
11
|
+
changed: boolean;
|
|
12
|
+
backupPath?: string;
|
|
13
|
+
dispatcherPath: string;
|
|
14
|
+
message: string;
|
|
15
|
+
}
|
|
16
|
+
export declare const codexNotifyConfigPath: string;
|
|
17
|
+
export declare const codexNotifyDispatcherPath: string;
|
|
18
|
+
export declare const codexNotifyDispatcherLogPath: string;
|
|
19
|
+
export declare function getCodexNotifyConfigStatus(): Promise<CodexNotifyConfigStatus>;
|
|
20
|
+
export declare function installCodexNotifyDispatcher(options?: {
|
|
21
|
+
force?: boolean;
|
|
22
|
+
}): Promise<InstallCodexNotifyDispatcherResult>;
|
|
23
|
+
export declare function formatNotifyCommand(command: string[] | undefined): string;
|