promptvc 0.1.6 → 0.1.8
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 +57 -7
- package/dist/codexVersion.d.ts +16 -0
- package/dist/codexVersion.d.ts.map +1 -0
- package/dist/codexVersion.js +85 -0
- package/dist/codexVersion.js.map +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +296 -55
- package/dist/config.js.map +1 -1
- package/dist/index.js +46 -2
- package/dist/index.js.map +1 -1
- package/dist/prompt.d.ts +2 -0
- package/dist/prompt.d.ts.map +1 -0
- package/dist/prompt.js +55 -0
- package/dist/prompt.js.map +1 -0
- package/dist/proxyCodex.d.ts.map +1 -1
- package/dist/proxyCodex.js +1 -0
- package/dist/proxyCodex.js.map +1 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +1 -0
- package/dist/store.js.map +1 -1
- package/dist/toolVersions.d.ts +26 -0
- package/dist/toolVersions.d.ts.map +1 -0
- package/dist/toolVersions.js +124 -0
- package/dist/toolVersions.js.map +1 -0
- package/hooks/claude-notify-node.js +679 -0
- package/hooks/claude-notify.sh +42 -0
- package/hooks/codex-notify-debug.sh +13 -0
- package/hooks/codex-notify-node.js +698 -0
- package/hooks/codex-notify.sh +155 -31
- package/package.json +12 -10
- package/LICENSE +0 -21
package/README.md
CHANGED
|
@@ -5,15 +5,17 @@ Local-first, prompt-by-prompt diff tracking for AI coding sessions.
|
|
|
5
5
|
## Requirements
|
|
6
6
|
|
|
7
7
|
- Node.js 22+ (use nvm: `nvm install 22 && nvm use 22`)
|
|
8
|
+
- npm 11.5.1 (set `PROMPTVC_EXPECTED_NPM_VERSION` to override)
|
|
8
9
|
- Git
|
|
9
|
-
- Codex CLI
|
|
10
|
-
-
|
|
10
|
+
- Codex CLI 0.80.0 (set `PROMPTVC_EXPECTED_CODEX_VERSION` to override)
|
|
11
|
+
- Claude Code (for Claude session capture)
|
|
12
|
+
- jq (optional; legacy hook fallback)
|
|
11
13
|
- macOS/Linux
|
|
12
14
|
- Windows: Git Bash required (run `promptvc` + `codex` in Git Bash)
|
|
13
15
|
|
|
14
16
|
### Windows notes
|
|
15
17
|
|
|
16
|
-
|
|
18
|
+
If the legacy shell hook fallback is used, install `jq` (pick one):
|
|
17
19
|
|
|
18
20
|
```bash
|
|
19
21
|
winget install jqlang.jq
|
|
@@ -39,15 +41,20 @@ npm install -g promptvc
|
|
|
39
41
|
promptvc config
|
|
40
42
|
```
|
|
41
43
|
|
|
42
|
-
This command finds the installed notify
|
|
44
|
+
This command finds the installed notify hooks, verifies Codex/npm versions, and updates `~/.codex/config.toml` plus `~/.claude/settings.json`. If it cannot edit a file, it prints a ready-to-paste snippet.
|
|
45
|
+
|
|
46
|
+
If you need to bypass the version guard, set:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
PROMPTVC_ALLOW_VERSION_MISMATCH=1
|
|
50
|
+
```
|
|
43
51
|
|
|
44
52
|
### Manual setup
|
|
45
53
|
|
|
46
54
|
Add to `~/.codex/config.toml`:
|
|
47
55
|
|
|
48
56
|
```toml
|
|
49
|
-
[hooks]
|
|
50
|
-
notify = "/absolute/path/to/promptvc/hooks/codex-notify.sh"
|
|
57
|
+
notify = ["/absolute/path/to/promptvc/hooks/codex-notify.sh"]
|
|
51
58
|
```
|
|
52
59
|
|
|
53
60
|
If installed globally via npm, the hook is typically at:
|
|
@@ -56,6 +63,49 @@ If installed globally via npm, the hook is typically at:
|
|
|
56
63
|
$(npm root -g)/promptvc/hooks/codex-notify.sh
|
|
57
64
|
```
|
|
58
65
|
|
|
66
|
+
Add (or merge) into `~/.claude/settings.json`:
|
|
67
|
+
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"hooks": {
|
|
71
|
+
"SessionEnd": [
|
|
72
|
+
{
|
|
73
|
+
"hooks": [
|
|
74
|
+
{
|
|
75
|
+
"type": "command",
|
|
76
|
+
"command": "/absolute/path/to/promptvc/hooks/claude-notify.sh"
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
],
|
|
81
|
+
"Stop": [
|
|
82
|
+
{
|
|
83
|
+
"hooks": [
|
|
84
|
+
{
|
|
85
|
+
"type": "command",
|
|
86
|
+
"command": "/absolute/path/to/promptvc/hooks/claude-notify.sh"
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
}
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
If installed globally via npm, the hook is typically at:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
$(npm root -g)/promptvc/hooks/claude-notify.sh
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Version guard
|
|
102
|
+
|
|
103
|
+
PromptVC checks Codex and npm versions during `promptvc config` and `promptvc init`.
|
|
104
|
+
|
|
105
|
+
- Expected Codex: `0.80.0` (override with `PROMPTVC_EXPECTED_CODEX_VERSION`)
|
|
106
|
+
- Expected npm: `11.5.1` (override with `PROMPTVC_EXPECTED_NPM_VERSION`)
|
|
107
|
+
- Bypass the guard: `PROMPTVC_ALLOW_VERSION_MISMATCH=1`
|
|
108
|
+
|
|
59
109
|
## Usage
|
|
60
110
|
|
|
61
111
|
Initialize a repo:
|
|
@@ -92,4 +142,4 @@ promptvc-codex
|
|
|
92
142
|
## Troubleshooting
|
|
93
143
|
|
|
94
144
|
- If `promptvc` resolves to a Python shim, run `which promptvc` and ensure your npm global bin is ahead of pyenv on PATH.
|
|
95
|
-
-
|
|
145
|
+
- If you’re using the legacy shell hook fallback, ensure `jq` is installed and available on PATH.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type CodexVersionInfo = {
|
|
2
|
+
version: string | null;
|
|
3
|
+
raw: string | null;
|
|
4
|
+
binaryPath: string | null;
|
|
5
|
+
};
|
|
6
|
+
export declare const EXPECTED_CODEX_VERSION = "0.80.0";
|
|
7
|
+
export declare const NOTIFY_ARRAY_MIN_VERSION = "0.80.0";
|
|
8
|
+
export declare function getCodexVersionInfo(): CodexVersionInfo;
|
|
9
|
+
export declare function compareSemver(a: string, b: string): number;
|
|
10
|
+
export declare function getNotifyConfigLine(hookPath: string, codexVersion: string | null): {
|
|
11
|
+
line: string;
|
|
12
|
+
usesArray: boolean;
|
|
13
|
+
useHooksSection: boolean;
|
|
14
|
+
};
|
|
15
|
+
export declare function getCodexVersionWarnings(codexVersion: string | null): string[];
|
|
16
|
+
//# sourceMappingURL=codexVersion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codexVersion.d.ts","sourceRoot":"","sources":["../src/codexVersion.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,CAAC;AAEF,eAAO,MAAM,sBAAsB,WAAW,CAAC;AAC/C,eAAO,MAAM,wBAAwB,WAAW,CAAC;AAkBjD,wBAAgB,mBAAmB,IAAI,gBAAgB,CAkBtD;AASD,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAU1D;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG;IAClF,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;CAC1B,CAQA;AAED,wBAAgB,uBAAuB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,EAAE,CAW7E"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.NOTIFY_ARRAY_MIN_VERSION = exports.EXPECTED_CODEX_VERSION = void 0;
|
|
4
|
+
exports.getCodexVersionInfo = getCodexVersionInfo;
|
|
5
|
+
exports.compareSemver = compareSemver;
|
|
6
|
+
exports.getNotifyConfigLine = getNotifyConfigLine;
|
|
7
|
+
exports.getCodexVersionWarnings = getCodexVersionWarnings;
|
|
8
|
+
const child_process_1 = require("child_process");
|
|
9
|
+
exports.EXPECTED_CODEX_VERSION = '0.80.0';
|
|
10
|
+
exports.NOTIFY_ARRAY_MIN_VERSION = '0.80.0';
|
|
11
|
+
const VERSION_PATTERN = /\b(\d+\.\d+\.\d+)\b/;
|
|
12
|
+
function parseVersion(raw) {
|
|
13
|
+
const match = raw.match(VERSION_PATTERN);
|
|
14
|
+
return match ? match[1] : null;
|
|
15
|
+
}
|
|
16
|
+
function getCodexBinaryPath() {
|
|
17
|
+
const command = process.platform === 'win32' ? 'where' : 'which';
|
|
18
|
+
const result = (0, child_process_1.spawnSync)(command, ['codex'], { encoding: 'utf8' });
|
|
19
|
+
if (result.status !== 0)
|
|
20
|
+
return null;
|
|
21
|
+
const output = (result.stdout || '').trim();
|
|
22
|
+
if (!output)
|
|
23
|
+
return null;
|
|
24
|
+
return output.split(/\r?\n/)[0] || null;
|
|
25
|
+
}
|
|
26
|
+
function getCodexVersionInfo() {
|
|
27
|
+
const commands = [['--version'], ['version']];
|
|
28
|
+
let raw = null;
|
|
29
|
+
for (const args of commands) {
|
|
30
|
+
const result = (0, child_process_1.spawnSync)('codex', args, { encoding: 'utf8' });
|
|
31
|
+
if (result.status !== 0)
|
|
32
|
+
continue;
|
|
33
|
+
const output = ((result.stdout || '') + (result.stderr || '')).trim();
|
|
34
|
+
if (output) {
|
|
35
|
+
raw = output;
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const version = raw ? parseVersion(raw) : null;
|
|
40
|
+
return {
|
|
41
|
+
version,
|
|
42
|
+
raw,
|
|
43
|
+
binaryPath: getCodexBinaryPath(),
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function toSemverParts(version) {
|
|
47
|
+
return version.split('.').map((part) => {
|
|
48
|
+
const value = Number.parseInt(part, 10);
|
|
49
|
+
return Number.isFinite(value) ? value : 0;
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function compareSemver(a, b) {
|
|
53
|
+
const aParts = toSemverParts(a);
|
|
54
|
+
const bParts = toSemverParts(b);
|
|
55
|
+
const maxLen = Math.max(aParts.length, bParts.length);
|
|
56
|
+
for (let i = 0; i < maxLen; i += 1) {
|
|
57
|
+
const left = aParts[i] ?? 0;
|
|
58
|
+
const right = bParts[i] ?? 0;
|
|
59
|
+
if (left !== right)
|
|
60
|
+
return left > right ? 1 : -1;
|
|
61
|
+
}
|
|
62
|
+
return 0;
|
|
63
|
+
}
|
|
64
|
+
function getNotifyConfigLine(hookPath, codexVersion) {
|
|
65
|
+
const isLegacy = codexVersion ? compareSemver(codexVersion, exports.NOTIFY_ARRAY_MIN_VERSION) < 0 : false;
|
|
66
|
+
const useArray = !isLegacy;
|
|
67
|
+
return {
|
|
68
|
+
line: useArray ? `notify = ["${hookPath}"]` : `notify = "${hookPath}"`,
|
|
69
|
+
usesArray: useArray,
|
|
70
|
+
useHooksSection: isLegacy,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function getCodexVersionWarnings(codexVersion) {
|
|
74
|
+
if (!codexVersion) {
|
|
75
|
+
return ['Codex version not detected. Run `codex --version` to verify your installation.'];
|
|
76
|
+
}
|
|
77
|
+
if (codexVersion !== exports.EXPECTED_CODEX_VERSION) {
|
|
78
|
+
return [
|
|
79
|
+
`PromptVC is tested with Codex ${exports.EXPECTED_CODEX_VERSION}, detected ${codexVersion}.`,
|
|
80
|
+
'If hooks do not fire, install the tested version.',
|
|
81
|
+
];
|
|
82
|
+
}
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=codexVersion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codexVersion.js","sourceRoot":"","sources":["../src/codexVersion.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AA0SA,eAAO,MAAM,gBAAgB,QAAa,OAAO,CAAC,IAAI,CAmPrD,CAAC"}
|
package/dist/config.js
CHANGED
|
@@ -1,37 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
4
|
};
|
|
@@ -41,13 +8,17 @@ const fs_1 = __importDefault(require("fs"));
|
|
|
41
8
|
const os_1 = __importDefault(require("os"));
|
|
42
9
|
const path_1 = __importDefault(require("path"));
|
|
43
10
|
const child_process_1 = require("child_process");
|
|
44
|
-
const readline = __importStar(require("readline/promises"));
|
|
45
11
|
const kleur_1 = __importDefault(require("kleur"));
|
|
46
12
|
const branding_1 = require("./branding");
|
|
13
|
+
const toolVersions_1 = require("./toolVersions");
|
|
14
|
+
const prompt_1 = require("./prompt");
|
|
47
15
|
const getCodexConfigPath = () => path_1.default.join(os_1.default.homedir(), '.codex', 'config.toml');
|
|
48
16
|
const getCodexDir = () => path_1.default.join(os_1.default.homedir(), '.codex');
|
|
49
17
|
const getNotifyHookPath = () => path_1.default.resolve(__dirname, '..', 'hooks', 'codex-notify.sh');
|
|
50
18
|
const isWindows = process.platform === 'win32';
|
|
19
|
+
const getClaudeSettingsPath = () => path_1.default.join(os_1.default.homedir(), '.claude', 'settings.json');
|
|
20
|
+
const getClaudeDir = () => path_1.default.join(os_1.default.homedir(), '.claude');
|
|
21
|
+
const getClaudeHookPath = () => path_1.default.resolve(__dirname, '..', 'hooks', 'claude-notify.sh');
|
|
51
22
|
const isCodexInstalled = () => {
|
|
52
23
|
const codexDir = getCodexDir();
|
|
53
24
|
return fs_1.default.existsSync(codexDir);
|
|
@@ -83,33 +54,154 @@ const normalizeHookPathForToml = (hookPath) => {
|
|
|
83
54
|
}
|
|
84
55
|
return hookPath.replace(/\\/g, '/');
|
|
85
56
|
};
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
57
|
+
const normalizeHookPathForCommand = (hookPath) => {
|
|
58
|
+
if (!isWindows) {
|
|
59
|
+
return hookPath;
|
|
60
|
+
}
|
|
61
|
+
return hookPath.replace(/\\/g, '/');
|
|
62
|
+
};
|
|
63
|
+
const isClaudeInstalled = () => {
|
|
64
|
+
const claudeDir = getClaudeDir();
|
|
65
|
+
return fs_1.default.existsSync(claudeDir);
|
|
66
|
+
};
|
|
67
|
+
const hasClaudeConfig = () => {
|
|
68
|
+
const configPath = getClaudeSettingsPath();
|
|
69
|
+
return fs_1.default.existsSync(configPath);
|
|
70
|
+
};
|
|
71
|
+
const isClaudeMatcherEntry = (entry) => {
|
|
72
|
+
if (!entry || typeof entry !== 'object') {
|
|
89
73
|
return false;
|
|
90
74
|
}
|
|
91
|
-
return
|
|
75
|
+
return 'matcher' in entry || 'hooks' in entry;
|
|
76
|
+
};
|
|
77
|
+
const isClaudeHookEntry = (entry) => {
|
|
78
|
+
if (!entry || typeof entry !== 'object') {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
return 'type' in entry || 'command' in entry;
|
|
92
82
|
};
|
|
93
|
-
const
|
|
94
|
-
|
|
83
|
+
const hasClaudeHook = (settings, eventName, hookPath) => {
|
|
84
|
+
const hooks = settings?.hooks?.[eventName];
|
|
85
|
+
if (!Array.isArray(hooks)) {
|
|
95
86
|
return false;
|
|
96
87
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
88
|
+
return hooks.some((entry) => {
|
|
89
|
+
if (isClaudeMatcherEntry(entry)) {
|
|
90
|
+
return Array.isArray(entry.hooks)
|
|
91
|
+
&& entry.hooks.some((hook) => hook?.type === 'command' && hook.command === hookPath);
|
|
92
|
+
}
|
|
93
|
+
return isClaudeHookEntry(entry) && entry.type === 'command' && entry.command === hookPath;
|
|
100
94
|
});
|
|
95
|
+
};
|
|
96
|
+
const getClaudeHookStatus = (hookPath) => {
|
|
97
|
+
const configPath = getClaudeSettingsPath();
|
|
98
|
+
if (!fs_1.default.existsSync(configPath)) {
|
|
99
|
+
return { stop: false, sessionEnd: false };
|
|
100
|
+
}
|
|
101
101
|
try {
|
|
102
|
-
const
|
|
103
|
-
return
|
|
102
|
+
const settings = JSON.parse(fs_1.default.readFileSync(configPath, 'utf-8'));
|
|
103
|
+
return {
|
|
104
|
+
stop: hasClaudeHook(settings, 'Stop', hookPath),
|
|
105
|
+
sessionEnd: hasClaudeHook(settings, 'SessionEnd', hookPath),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return { stop: false, sessionEnd: false };
|
|
104
110
|
}
|
|
105
|
-
|
|
106
|
-
|
|
111
|
+
};
|
|
112
|
+
const normalizeClaudeEventHooks = (entries) => {
|
|
113
|
+
const normalized = [];
|
|
114
|
+
const directHooks = [];
|
|
115
|
+
let changed = false;
|
|
116
|
+
for (const entry of entries) {
|
|
117
|
+
if (isClaudeMatcherEntry(entry)) {
|
|
118
|
+
const entryHooks = Array.isArray(entry.hooks) ? [...entry.hooks] : [];
|
|
119
|
+
if (!Array.isArray(entry.hooks)) {
|
|
120
|
+
changed = true;
|
|
121
|
+
}
|
|
122
|
+
normalized.push({ ...entry, hooks: entryHooks });
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
if (isClaudeHookEntry(entry)) {
|
|
126
|
+
directHooks.push(entry);
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
normalized.push(entry);
|
|
130
|
+
}
|
|
131
|
+
if (directHooks.length > 0) {
|
|
132
|
+
let targetIndex = normalized.findIndex((entry) => entry.matcher == null || entry.matcher === '');
|
|
133
|
+
if (targetIndex === -1) {
|
|
134
|
+
normalized.push({ hooks: [...directHooks] });
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
const mergedHooks = Array.isArray(normalized[targetIndex].hooks)
|
|
138
|
+
? [...normalized[targetIndex].hooks]
|
|
139
|
+
: [];
|
|
140
|
+
for (const hook of directHooks) {
|
|
141
|
+
const exists = mergedHooks.some((existing) => existing?.type === hook?.type && existing?.command === hook?.command);
|
|
142
|
+
if (!exists) {
|
|
143
|
+
mergedHooks.push(hook);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
normalized[targetIndex] = { ...normalized[targetIndex], hooks: mergedHooks };
|
|
147
|
+
}
|
|
148
|
+
changed = true;
|
|
149
|
+
}
|
|
150
|
+
return { entries: normalized, changed };
|
|
151
|
+
};
|
|
152
|
+
const upsertClaudeEventHook = (settings, eventName, hookPath) => {
|
|
153
|
+
const updated = settings && typeof settings === 'object' ? { ...settings } : {};
|
|
154
|
+
const hooks = updated.hooks && typeof updated.hooks === 'object' ? { ...updated.hooks } : {};
|
|
155
|
+
const existingEntries = Array.isArray(hooks[eventName]) ? [...hooks[eventName]] : [];
|
|
156
|
+
const normalized = normalizeClaudeEventHooks(existingEntries);
|
|
157
|
+
const eventEntries = normalized.entries;
|
|
158
|
+
let changed = normalized.changed;
|
|
159
|
+
let entryIndex = eventEntries.findIndex((entry) => entry.matcher == null || entry.matcher === '');
|
|
160
|
+
if (entryIndex === -1) {
|
|
161
|
+
eventEntries.push({ hooks: [] });
|
|
162
|
+
entryIndex = eventEntries.length - 1;
|
|
163
|
+
changed = true;
|
|
164
|
+
}
|
|
165
|
+
const entry = { ...eventEntries[entryIndex] };
|
|
166
|
+
const entryHooks = Array.isArray(entry.hooks) ? [...entry.hooks] : [];
|
|
167
|
+
const hasHook = entryHooks.some((hook) => hook?.type === 'command' && hook.command === hookPath);
|
|
168
|
+
if (!hasHook) {
|
|
169
|
+
entryHooks.push({ type: 'command', command: hookPath });
|
|
170
|
+
changed = true;
|
|
107
171
|
}
|
|
172
|
+
entry.hooks = entryHooks;
|
|
173
|
+
eventEntries[entryIndex] = entry;
|
|
174
|
+
hooks[eventName] = eventEntries;
|
|
175
|
+
updated.hooks = hooks;
|
|
176
|
+
return { updated, changed };
|
|
108
177
|
};
|
|
109
|
-
const
|
|
178
|
+
const hasJq = () => {
|
|
179
|
+
const result = (0, child_process_1.spawnSync)('jq', ['--version'], { stdio: 'ignore' });
|
|
180
|
+
if (result.error) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
return result.status === 0;
|
|
184
|
+
};
|
|
185
|
+
const upsertNotifyHook = (content, notifyLine) => {
|
|
186
|
+
const usesCrlf = content.includes('\r\n');
|
|
187
|
+
const normalized = content.replace(/\r\n/g, '\n');
|
|
188
|
+
if (!normalized.trim()) {
|
|
189
|
+
const fresh = `${notifyLine}\n`;
|
|
190
|
+
return usesCrlf ? fresh.replace(/\n/g, '\r\n') : fresh;
|
|
191
|
+
}
|
|
192
|
+
const lines = normalized.split('\n');
|
|
193
|
+
const filtered = lines.filter((line) => !/^\s*notify\s*=/.test(line));
|
|
194
|
+
let insertIndex = filtered.findIndex((line) => /^\s*\[/.test(line));
|
|
195
|
+
if (insertIndex === -1)
|
|
196
|
+
insertIndex = filtered.length;
|
|
197
|
+
filtered.splice(insertIndex, 0, notifyLine);
|
|
198
|
+
let updated = filtered.join('\n');
|
|
199
|
+
updated = updated.replace(/\n{3,}/g, '\n\n').trimEnd() + '\n';
|
|
200
|
+
return usesCrlf ? updated.replace(/\n/g, '\r\n') : updated;
|
|
201
|
+
};
|
|
202
|
+
const upsertNotifyHookLegacy = (content, notifyLine) => {
|
|
110
203
|
const usesCrlf = content.includes('\r\n');
|
|
111
204
|
const normalized = content.replace(/\r\n/g, '\n');
|
|
112
|
-
const notifyLine = `notify = "${hookPath}"`;
|
|
113
205
|
if (!normalized.trim()) {
|
|
114
206
|
const fresh = `[hooks]\n${notifyLine}\n`;
|
|
115
207
|
return usesCrlf ? fresh.replace(/\n/g, '\r\n') : fresh;
|
|
@@ -149,7 +241,7 @@ const runConfigCommand = async () => {
|
|
|
149
241
|
console.log(' - winget install jqlang.jq');
|
|
150
242
|
console.log(' - choco install jq');
|
|
151
243
|
console.log(' - scoop install jq');
|
|
152
|
-
const shouldInstall = await promptYesNo('Install jq now? (y/N): ');
|
|
244
|
+
const shouldInstall = await (0, prompt_1.promptYesNo)('Install jq now? (y/N): ');
|
|
153
245
|
if (shouldInstall) {
|
|
154
246
|
console.log('');
|
|
155
247
|
console.log('Run one of the commands above, then re-run `promptvc config`.');
|
|
@@ -160,14 +252,49 @@ const runConfigCommand = async () => {
|
|
|
160
252
|
}
|
|
161
253
|
const hookPath = getNotifyHookPath();
|
|
162
254
|
const hookPathForConfig = normalizeHookPathForToml(hookPath);
|
|
255
|
+
const claudeHookPath = getClaudeHookPath();
|
|
256
|
+
const claudeHookPathForConfig = normalizeHookPathForCommand(claudeHookPath);
|
|
257
|
+
const codexInfo = (0, toolVersions_1.getCodexVersionInfo)();
|
|
258
|
+
const npmInfo = (0, toolVersions_1.getNpmVersionInfo)();
|
|
259
|
+
const notifyConfig = (0, toolVersions_1.getNotifyConfigLine)(hookPathForConfig, codexInfo.version);
|
|
163
260
|
const configPath = getCodexConfigPath();
|
|
164
|
-
const snippet =
|
|
261
|
+
const snippet = notifyConfig.useHooksSection
|
|
262
|
+
? `[hooks]\n${notifyConfig.line}\n`
|
|
263
|
+
: `${notifyConfig.line}\n`;
|
|
264
|
+
const claudeConfigPath = getClaudeSettingsPath();
|
|
265
|
+
const claudeSnippet = JSON.stringify({
|
|
266
|
+
hooks: {
|
|
267
|
+
SessionEnd: [
|
|
268
|
+
{
|
|
269
|
+
hooks: [
|
|
270
|
+
{
|
|
271
|
+
type: 'command',
|
|
272
|
+
command: claudeHookPathForConfig,
|
|
273
|
+
},
|
|
274
|
+
],
|
|
275
|
+
},
|
|
276
|
+
],
|
|
277
|
+
Stop: [
|
|
278
|
+
{
|
|
279
|
+
hooks: [
|
|
280
|
+
{
|
|
281
|
+
type: 'command',
|
|
282
|
+
command: claudeHookPathForConfig,
|
|
283
|
+
},
|
|
284
|
+
],
|
|
285
|
+
},
|
|
286
|
+
],
|
|
287
|
+
},
|
|
288
|
+
}, null, 2);
|
|
165
289
|
console.log(kleur_1.default.bold().cyan('PromptVC Config'));
|
|
166
290
|
console.log((0, branding_1.renderLogo)());
|
|
167
291
|
console.log('');
|
|
168
292
|
// Check Codex installation status
|
|
169
293
|
const codexInstalled = isCodexInstalled();
|
|
170
294
|
const codexConfigured = isCodexConfigured();
|
|
295
|
+
const claudeInstalled = isClaudeInstalled();
|
|
296
|
+
const claudeStatus = getClaudeHookStatus(claudeHookPathForConfig);
|
|
297
|
+
const claudeConfigured = claudeStatus.stop && claudeStatus.sessionEnd;
|
|
171
298
|
console.log(`${kleur_1.default.bold('Codex status:')}`);
|
|
172
299
|
if (codexInstalled) {
|
|
173
300
|
console.log(` ${kleur_1.default.green('✓')} Codex is installed (${getCodexDir()} found)`);
|
|
@@ -183,18 +310,98 @@ const runConfigCommand = async () => {
|
|
|
183
310
|
}
|
|
184
311
|
else {
|
|
185
312
|
console.log(` ${kleur_1.default.red('✗')} Codex not found (${getCodexDir()} does not exist)`);
|
|
186
|
-
console.log(` ${kleur_1.default.yellow('→')} Install Codex
|
|
313
|
+
console.log(` ${kleur_1.default.yellow('→')} Install Codex: npm i -g @openai/codex`);
|
|
187
314
|
}
|
|
188
315
|
console.log('');
|
|
189
|
-
console.log(`${kleur_1.default.bold('
|
|
316
|
+
console.log(`${kleur_1.default.bold('Codex hook path:')} ${hookPathForConfig}`);
|
|
190
317
|
console.log(`${kleur_1.default.bold('Codex config:')} ${configPath}`);
|
|
318
|
+
console.log('');
|
|
319
|
+
console.log(`${kleur_1.default.bold('Claude status:')}`);
|
|
320
|
+
if (claudeInstalled) {
|
|
321
|
+
console.log(` ${kleur_1.default.green('✓')} Claude config directory detected (${getClaudeDir()} found)`);
|
|
322
|
+
if (claudeConfigured) {
|
|
323
|
+
console.log(` ${kleur_1.default.green('✓')} Claude is already configured with PromptVC`);
|
|
324
|
+
}
|
|
325
|
+
else if (claudeStatus.stop || claudeStatus.sessionEnd) {
|
|
326
|
+
console.log(` ${kleur_1.default.yellow('○')} Claude config partially configured (Stop: ${claudeStatus.stop ? 'yes' : 'no'}, SessionEnd: ${claudeStatus.sessionEnd ? 'yes' : 'no'})`);
|
|
327
|
+
}
|
|
328
|
+
else if (hasClaudeConfig()) {
|
|
329
|
+
console.log(` ${kleur_1.default.yellow('○')} Claude config exists but PromptVC not configured`);
|
|
330
|
+
}
|
|
331
|
+
else {
|
|
332
|
+
console.log(` ${kleur_1.default.yellow('○')} Claude config not found, will be created`);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
console.log(` ${kleur_1.default.red('✗')} Claude config directory not found (${getClaudeDir()} does not exist)`);
|
|
337
|
+
console.log(` ${kleur_1.default.yellow('→')} Install Claude Code to use this integration`);
|
|
338
|
+
}
|
|
339
|
+
console.log('');
|
|
340
|
+
console.log(`${kleur_1.default.bold('Claude hook path:')} ${claudeHookPathForConfig}`);
|
|
341
|
+
console.log(`${kleur_1.default.bold('Claude config:')} ${claudeConfigPath}`);
|
|
342
|
+
if (codexInfo.binaryPath) {
|
|
343
|
+
console.log(`${kleur_1.default.bold('Codex binary:')} ${codexInfo.binaryPath}`);
|
|
344
|
+
}
|
|
345
|
+
if (codexInfo.version) {
|
|
346
|
+
console.log(`${kleur_1.default.bold('Codex version:')} ${codexInfo.version}`);
|
|
347
|
+
}
|
|
348
|
+
else if (codexInfo.raw) {
|
|
349
|
+
console.log(`${kleur_1.default.bold('Codex version:')} ${codexInfo.raw}`);
|
|
350
|
+
}
|
|
351
|
+
if (npmInfo.binaryPath) {
|
|
352
|
+
console.log(`${kleur_1.default.bold('npm binary:')} ${npmInfo.binaryPath}`);
|
|
353
|
+
}
|
|
354
|
+
if (npmInfo.version) {
|
|
355
|
+
console.log(`${kleur_1.default.bold('npm version:')} ${npmInfo.version}`);
|
|
356
|
+
}
|
|
357
|
+
else if (npmInfo.raw) {
|
|
358
|
+
console.log(`${kleur_1.default.bold('npm version:')} ${npmInfo.raw}`);
|
|
359
|
+
}
|
|
360
|
+
const warnings = (0, toolVersions_1.getCodexVersionWarnings)(codexInfo.version);
|
|
361
|
+
if (warnings.length > 0) {
|
|
362
|
+
for (const warning of warnings) {
|
|
363
|
+
console.log(kleur_1.default.yellow(`Warning: ${warning}`));
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
const npmWarnings = (0, toolVersions_1.getNpmVersionWarnings)(npmInfo.version);
|
|
367
|
+
if (npmWarnings.length > 0) {
|
|
368
|
+
for (const warning of npmWarnings) {
|
|
369
|
+
console.log(kleur_1.default.yellow(`Warning: ${warning}`));
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
if (notifyConfig.useHooksSection) {
|
|
373
|
+
console.log(kleur_1.default.yellow('Warning: Codex is using the legacy [hooks] notify format; upgrade recommended.'));
|
|
374
|
+
}
|
|
375
|
+
console.log('');
|
|
376
|
+
const codexMismatch = (0, toolVersions_1.isVersionMismatch)(codexInfo.version, toolVersions_1.EXPECTED_CODEX_VERSION);
|
|
377
|
+
const npmMismatch = (0, toolVersions_1.isVersionMismatch)(npmInfo.version, toolVersions_1.EXPECTED_NPM_VERSION);
|
|
378
|
+
if ((codexMismatch || npmMismatch) && !(0, toolVersions_1.allowVersionMismatch)()) {
|
|
379
|
+
const reason = codexMismatch && npmMismatch
|
|
380
|
+
? 'Codex and npm versions do not match the expected versions.'
|
|
381
|
+
: codexMismatch
|
|
382
|
+
? 'Codex version does not match the expected version.'
|
|
383
|
+
: 'npm version does not match the expected version.';
|
|
384
|
+
console.log(kleur_1.default.yellow(`Warning: ${reason}`));
|
|
385
|
+
console.log(kleur_1.default.yellow('Set PROMPTVC_ALLOW_VERSION_MISMATCH=1 to bypass this check.'));
|
|
386
|
+
const shouldContinue = await (0, prompt_1.promptYesNo)('Continue anyway? (y/N): ');
|
|
387
|
+
if (!shouldContinue) {
|
|
388
|
+
process.exit(1);
|
|
389
|
+
}
|
|
390
|
+
console.log('');
|
|
391
|
+
}
|
|
191
392
|
if (!fs_1.default.existsSync(hookPath)) {
|
|
192
393
|
console.log(kleur_1.default.yellow('Warning: notify hook not found at this path.'));
|
|
193
394
|
}
|
|
395
|
+
if (!fs_1.default.existsSync(claudeHookPath)) {
|
|
396
|
+
console.log(kleur_1.default.yellow('Warning: Claude notify hook not found at this path.'));
|
|
397
|
+
}
|
|
398
|
+
let updatedSomething = false;
|
|
194
399
|
try {
|
|
195
400
|
fs_1.default.mkdirSync(path_1.default.dirname(configPath), { recursive: true });
|
|
196
401
|
const existing = fs_1.default.existsSync(configPath) ? fs_1.default.readFileSync(configPath, 'utf-8') : '';
|
|
197
|
-
const updated =
|
|
402
|
+
const updated = notifyConfig.useHooksSection
|
|
403
|
+
? upsertNotifyHookLegacy(existing, notifyConfig.line)
|
|
404
|
+
: upsertNotifyHook(existing, notifyConfig.line);
|
|
198
405
|
fs_1.default.writeFileSync(configPath, updated, 'utf-8');
|
|
199
406
|
console.log('');
|
|
200
407
|
if (codexConfigured) {
|
|
@@ -208,7 +415,7 @@ const runConfigCommand = async () => {
|
|
|
208
415
|
console.log(kleur_1.default.yellow('Note: Codex installation not detected. Install Codex to use this integration.'));
|
|
209
416
|
}
|
|
210
417
|
console.log('');
|
|
211
|
-
|
|
418
|
+
updatedSomething = true;
|
|
212
419
|
}
|
|
213
420
|
catch (error) {
|
|
214
421
|
console.log('');
|
|
@@ -216,6 +423,40 @@ const runConfigCommand = async () => {
|
|
|
216
423
|
console.log(`Add this to ${configPath}:`);
|
|
217
424
|
console.log(snippet);
|
|
218
425
|
}
|
|
426
|
+
try {
|
|
427
|
+
fs_1.default.mkdirSync(path_1.default.dirname(claudeConfigPath), { recursive: true });
|
|
428
|
+
const existingRaw = fs_1.default.existsSync(claudeConfigPath) ? fs_1.default.readFileSync(claudeConfigPath, 'utf-8') : '';
|
|
429
|
+
const existing = existingRaw.trim().length === 0 ? '{}' : existingRaw;
|
|
430
|
+
const parsed = JSON.parse(existing);
|
|
431
|
+
const stopResult = upsertClaudeEventHook(parsed, 'Stop', claudeHookPathForConfig);
|
|
432
|
+
const sessionEndResult = upsertClaudeEventHook(stopResult.updated, 'SessionEnd', claudeHookPathForConfig);
|
|
433
|
+
const claudeChanged = stopResult.changed || sessionEndResult.changed || existing.trim().length === 0;
|
|
434
|
+
if (claudeChanged) {
|
|
435
|
+
fs_1.default.writeFileSync(claudeConfigPath, JSON.stringify(sessionEndResult.updated, null, 2) + '\n', 'utf-8');
|
|
436
|
+
}
|
|
437
|
+
console.log('');
|
|
438
|
+
if (claudeConfigured) {
|
|
439
|
+
console.log(kleur_1.default.green('OK: Claude config verified (already configured).'));
|
|
440
|
+
}
|
|
441
|
+
else {
|
|
442
|
+
console.log(kleur_1.default.green('OK: Claude config updated successfully.'));
|
|
443
|
+
}
|
|
444
|
+
if (!claudeInstalled) {
|
|
445
|
+
console.log('');
|
|
446
|
+
console.log(kleur_1.default.yellow('Note: Claude installation not detected. Install Claude Code to use this integration.'));
|
|
447
|
+
}
|
|
448
|
+
console.log('');
|
|
449
|
+
updatedSomething = true;
|
|
450
|
+
}
|
|
451
|
+
catch (error) {
|
|
452
|
+
console.log('');
|
|
453
|
+
console.log(kleur_1.default.yellow('Manual setup required for Claude.'));
|
|
454
|
+
console.log(`Merge this into ${claudeConfigPath}:`);
|
|
455
|
+
console.log(claudeSnippet);
|
|
456
|
+
}
|
|
457
|
+
if (updatedSomething) {
|
|
458
|
+
console.log(kleur_1.default.bgBlue('Run "promptvc init" to initialize Prompt Version Control in your repository.'));
|
|
459
|
+
}
|
|
219
460
|
};
|
|
220
461
|
exports.runConfigCommand = runConfigCommand;
|
|
221
462
|
//# sourceMappingURL=config.js.map
|