litmus-cli 1.0.14 → 1.0.17
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 +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +151 -20
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +12 -2
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/submit.d.ts.map +1 -1
- package/dist/commands/submit.js +41 -19
- package/dist/commands/submit.js.map +1 -1
- package/dist/lib/api.d.ts +2 -2
- package/dist/lib/api.d.ts.map +1 -1
- package/dist/lib/api.js +3 -6
- package/dist/lib/api.js.map +1 -1
- package/dist/lib/config.d.ts +9 -2
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +16 -3
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/hook-logger.cjs +180 -0
- package/dist/lib/tracker.d.ts +1 -1
- package/dist/lib/tracker.d.ts.map +1 -1
- package/dist/lib/tracker.js +29 -21
- package/dist/lib/tracker.js.map +1 -1
- package/dist/lib/watcher.cjs +354 -19
- package/dist/lib/zip.d.ts.map +1 -1
- package/dist/lib/zip.js +32 -15
- package/dist/lib/zip.js.map +1 -1
- package/dist/staging.d.ts +2 -0
- package/dist/staging.d.ts.map +1 -0
- package/dist/staging.js +6 -0
- package/dist/staging.js.map +1 -0
- package/dist/utils/detect-project.d.ts +0 -1
- package/dist/utils/detect-project.d.ts.map +1 -1
- package/dist/utils/detect-project.js +10 -14
- package/dist/utils/detect-project.js.map +1 -1
- package/dist/utils/errors.js +1 -1
- package/dist/utils/errors.js.map +1 -1
- package/package.json +4 -3
- package/dist/watcher.cjs +0 -79
package/dist/lib/config.js
CHANGED
|
@@ -1,11 +1,24 @@
|
|
|
1
1
|
import { readFile, writeFile, mkdir } from "fs/promises";
|
|
2
2
|
import { existsSync } from "fs";
|
|
3
3
|
import path from "path";
|
|
4
|
+
/**
|
|
5
|
+
* Calculate the effective deadline timestamp (ms) from config.
|
|
6
|
+
* Returns null if no deadline or time limit is configured.
|
|
7
|
+
*
|
|
8
|
+
* NOTE: This logic is duplicated in watcher.cjs (which is CommonJS and
|
|
9
|
+
* cannot import this module). Keep both in sync.
|
|
10
|
+
*/
|
|
11
|
+
export function getEffectiveDeadline(config) {
|
|
12
|
+
const candidates = [
|
|
13
|
+
config.deadline ? new Date(config.deadline).getTime() : Infinity,
|
|
14
|
+
config.startedAt && config.timeLimit
|
|
15
|
+
? new Date(config.startedAt).getTime() + config.timeLimit * 60000
|
|
16
|
+
: Infinity,
|
|
17
|
+
].filter(t => t !== Infinity);
|
|
18
|
+
return candidates.length > 0 ? Math.min(...candidates) : null;
|
|
19
|
+
}
|
|
4
20
|
const CONFIG_DIR = ".litmus";
|
|
5
21
|
const CONFIG_FILE = "config.json";
|
|
6
|
-
export function getConfigPath(projectRoot) {
|
|
7
|
-
return path.join(projectRoot, CONFIG_DIR, CONFIG_FILE);
|
|
8
|
-
}
|
|
9
22
|
export async function writeConfig(projectRoot, config) {
|
|
10
23
|
const configDir = path.join(projectRoot, CONFIG_DIR);
|
|
11
24
|
await mkdir(configDir, { recursive: true });
|
package/dist/lib/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAA;AAC/B,OAAO,IAAI,MAAM,MAAM,CAAA;AAevB,MAAM,UAAU,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Litmus AI prompt logger.
|
|
4
|
+
* Universal hook script invoked by Claude Code, GitHub Copilot CLI, and OpenAI Codex CLI.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* node hook-logger.cjs <tool>
|
|
8
|
+
*
|
|
9
|
+
* Each tool pipes JSON on stdin when a user submits a prompt:
|
|
10
|
+
* - Claude Code (UserPromptSubmit): stdin JSON with session_id, prompt content
|
|
11
|
+
* - Copilot CLI (userPromptSubmitted): { timestamp, cwd, prompt }
|
|
12
|
+
* - Codex CLI: experimental hooks support (format TBD)
|
|
13
|
+
*
|
|
14
|
+
* Normalizes to: { ts, type: "ai_prompt", tool, prompt, sessionId? }
|
|
15
|
+
* Appends to .litmus/activity.jsonl — the same file the watcher uses,
|
|
16
|
+
* so prompts flow through the existing analysis pipeline.
|
|
17
|
+
* Also uploads the event to the server (fire-and-forget) for real-time backup.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
const fs = require("fs")
|
|
21
|
+
const path = require("path")
|
|
22
|
+
const https = require("https")
|
|
23
|
+
const http = require("http")
|
|
24
|
+
|
|
25
|
+
// Keep under the server's MAX_EVENT_SIZE (2048 bytes) after JSON serialization.
|
|
26
|
+
// ~1800 chars of prompt + ~150 bytes of wrapper fields + JSON escaping = safely under 2KB.
|
|
27
|
+
const MAX_PROMPT_LENGTH = 1800
|
|
28
|
+
|
|
29
|
+
const tool = process.argv[2] || "unknown"
|
|
30
|
+
|
|
31
|
+
// Find the .litmus directory — walk up from cwd
|
|
32
|
+
function findLitmusDir() {
|
|
33
|
+
let dir = process.cwd()
|
|
34
|
+
for (let i = 0; i < 10; i++) {
|
|
35
|
+
const candidate = path.join(dir, ".litmus")
|
|
36
|
+
if (fs.existsSync(candidate)) return candidate
|
|
37
|
+
const parent = path.dirname(dir)
|
|
38
|
+
if (parent === dir) break
|
|
39
|
+
dir = parent
|
|
40
|
+
}
|
|
41
|
+
return null
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Read config.json for server upload credentials
|
|
45
|
+
function readConfig(litmusDir) {
|
|
46
|
+
try {
|
|
47
|
+
const configPath = path.join(litmusDir, "config.json")
|
|
48
|
+
return JSON.parse(fs.readFileSync(configPath, "utf8"))
|
|
49
|
+
} catch {
|
|
50
|
+
return null
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Fire-and-forget upload to /cli/activity.
|
|
55
|
+
// Uses socket.unref() so Node exits immediately without waiting for the response —
|
|
56
|
+
// the OS TCP stack still flushes the outbound data after our process exits.
|
|
57
|
+
function uploadEvent(config, event) {
|
|
58
|
+
if (!config || !config.token || !config.backendUrl) return
|
|
59
|
+
|
|
60
|
+
const body = JSON.stringify({ events: [event] })
|
|
61
|
+
const url = new URL(
|
|
62
|
+
`${config.backendUrl}/cli/activity?token=${encodeURIComponent(config.token)}`
|
|
63
|
+
)
|
|
64
|
+
const reqFn = url.protocol === "https:" ? https.request : http.request
|
|
65
|
+
|
|
66
|
+
const req = reqFn(url, {
|
|
67
|
+
method: "POST",
|
|
68
|
+
headers: { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(body) },
|
|
69
|
+
timeout: 5000,
|
|
70
|
+
})
|
|
71
|
+
req.on("error", () => {}) // Swallow — fire-and-forget
|
|
72
|
+
req.on("timeout", () => { req.destroy() })
|
|
73
|
+
req.on("socket", (socket) => { socket.unref() }) // Don't keep process alive for response
|
|
74
|
+
req.end(body)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function readStdin() {
|
|
78
|
+
return new Promise((resolve) => {
|
|
79
|
+
let resolved = false
|
|
80
|
+
const chunks = []
|
|
81
|
+
process.stdin.setEncoding("utf8")
|
|
82
|
+
process.stdin.on("data", (chunk) => chunks.push(chunk))
|
|
83
|
+
process.stdin.on("end", () => {
|
|
84
|
+
if (!resolved) { resolved = true; resolve(chunks.join("")) }
|
|
85
|
+
})
|
|
86
|
+
// Safety timeout — stdin should arrive immediately from hook runners.
|
|
87
|
+
// Keep this short to avoid blocking the AI tool.
|
|
88
|
+
setTimeout(() => {
|
|
89
|
+
if (!resolved) { resolved = true; resolve(chunks.join("")) }
|
|
90
|
+
}, 300)
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function extractPrompt(input, toolName) {
|
|
95
|
+
try {
|
|
96
|
+
const data = JSON.parse(input)
|
|
97
|
+
|
|
98
|
+
switch (toolName) {
|
|
99
|
+
case "claude": {
|
|
100
|
+
// Claude Code UserPromptSubmit: prompt may be in message.content or content field
|
|
101
|
+
const prompt = data.user_message
|
|
102
|
+
|| data.prompt
|
|
103
|
+
|| (data.message && data.message.content)
|
|
104
|
+
|| null
|
|
105
|
+
return {
|
|
106
|
+
prompt: typeof prompt === "string" ? prompt : JSON.stringify(prompt),
|
|
107
|
+
sessionId: data.session_id || null,
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
case "copilot": {
|
|
111
|
+
// Copilot CLI userPromptSubmitted: { timestamp, cwd, prompt }
|
|
112
|
+
return {
|
|
113
|
+
prompt: data.prompt || null,
|
|
114
|
+
sessionId: null,
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
case "codex": {
|
|
118
|
+
// Codex CLI: experimental, extract what we can
|
|
119
|
+
const prompt = data.prompt
|
|
120
|
+
|| data.user_message
|
|
121
|
+
|| (data.message && data.message.content)
|
|
122
|
+
|| null
|
|
123
|
+
return {
|
|
124
|
+
prompt: typeof prompt === "string" ? prompt : JSON.stringify(prompt),
|
|
125
|
+
sessionId: data.thread_id || null,
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
default: {
|
|
129
|
+
// Best-effort: look for common field names
|
|
130
|
+
const prompt = data.prompt || data.user_message || data.content || null
|
|
131
|
+
return {
|
|
132
|
+
prompt: typeof prompt === "string" ? prompt : JSON.stringify(prompt),
|
|
133
|
+
sessionId: data.session_id || null,
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
} catch {
|
|
138
|
+
return { prompt: null, sessionId: null }
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
async function main() {
|
|
143
|
+
const litmusDir = findLitmusDir()
|
|
144
|
+
if (!litmusDir) return // Not in a Litmus assessment — silently exit
|
|
145
|
+
|
|
146
|
+
const raw = await readStdin()
|
|
147
|
+
if (!raw.trim()) return
|
|
148
|
+
|
|
149
|
+
const { prompt, sessionId } = extractPrompt(raw, tool)
|
|
150
|
+
if (!prompt) return
|
|
151
|
+
|
|
152
|
+
const truncated = prompt.length > MAX_PROMPT_LENGTH
|
|
153
|
+
? prompt.slice(0, MAX_PROMPT_LENGTH) + "...[truncated]"
|
|
154
|
+
: prompt
|
|
155
|
+
|
|
156
|
+
const event = {
|
|
157
|
+
ts: new Date().toISOString(),
|
|
158
|
+
type: "ai_prompt",
|
|
159
|
+
tool,
|
|
160
|
+
prompt: truncated,
|
|
161
|
+
}
|
|
162
|
+
if (sessionId) event.sessionId = sessionId
|
|
163
|
+
|
|
164
|
+
// 1. Append to activity.jsonl (for submission ZIP)
|
|
165
|
+
const logPath = path.join(litmusDir, "activity.jsonl")
|
|
166
|
+
try {
|
|
167
|
+
fs.appendFileSync(logPath, JSON.stringify(event) + "\n")
|
|
168
|
+
} catch {
|
|
169
|
+
// Non-critical
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// 2. Upload to server (fire-and-forget, for real-time backup)
|
|
173
|
+
const config = readConfig(litmusDir)
|
|
174
|
+
uploadEvent(config, event)
|
|
175
|
+
|
|
176
|
+
// No explicit process.exit() — the event loop drains naturally.
|
|
177
|
+
// The HTTP socket is unref'd so it won't keep the process alive.
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
main().catch(() => process.exit(0))
|
package/dist/lib/tracker.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Start the file watcher in the background.
|
|
3
|
-
* Spawns
|
|
3
|
+
* Spawns watcher.cjs as a detached process; logs file events to
|
|
4
4
|
* <projectDir>/.litmus/activity.jsonl for later inclusion in the submission ZIP.
|
|
5
5
|
*/
|
|
6
6
|
export declare function startTracker(projectDir: string): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../../src/lib/tracker.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"tracker.d.ts","sourceRoot":"","sources":["../../src/lib/tracker.ts"],"names":[],"mappings":"AAiBA;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAyCrD"}
|
package/dist/lib/tracker.js
CHANGED
|
@@ -1,27 +1,21 @@
|
|
|
1
1
|
import { spawn } from "child_process";
|
|
2
|
-
import { mkdirSync, openSync, writeFileSync } from "fs";
|
|
2
|
+
import { existsSync, mkdirSync, openSync, readFileSync, writeFileSync } from "fs";
|
|
3
3
|
import path from "path";
|
|
4
|
-
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
function write(type, rel) { log.write(JSON.stringify({ ts: new Date().toISOString(), type, path: rel }) + "\\n"); }
|
|
17
|
-
process.on("uncaughtException", (err) => { process.stderr.write("[watcher] crash: " + err + "\\n"); process.exit(1); });
|
|
18
|
-
const w = fs.watch(projectDir, { recursive: true }, (ev, f) => { if (f && !shouldIgnore(f)) write(ev, f); });
|
|
19
|
-
w.on("error", (err) => { process.stderr.write("[watcher] watch error: " + err + "\\n"); });
|
|
20
|
-
process.stderr.write("[watcher] running, watching " + projectDir + "\\n");
|
|
21
|
-
`;
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
6
|
+
const __dirname = path.dirname(__filename);
|
|
7
|
+
function isProcessAlive(pid) {
|
|
8
|
+
try {
|
|
9
|
+
process.kill(pid, 0); // Signal 0 = check if process exists
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
22
16
|
/**
|
|
23
17
|
* Start the file watcher in the background.
|
|
24
|
-
* Spawns
|
|
18
|
+
* Spawns watcher.cjs as a detached process; logs file events to
|
|
25
19
|
* <projectDir>/.litmus/activity.jsonl for later inclusion in the submission ZIP.
|
|
26
20
|
*/
|
|
27
21
|
export function startTracker(projectDir) {
|
|
@@ -35,8 +29,22 @@ export function startTracker(projectDir) {
|
|
|
35
29
|
catch {
|
|
36
30
|
// Non-critical
|
|
37
31
|
}
|
|
32
|
+
// Check if a watcher is already running
|
|
33
|
+
if (existsSync(pidFile)) {
|
|
34
|
+
try {
|
|
35
|
+
const existingPid = parseInt(readFileSync(pidFile, "utf8").trim(), 10);
|
|
36
|
+
if (!isNaN(existingPid) && isProcessAlive(existingPid)) {
|
|
37
|
+
return; // Watcher already running
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// PID file unreadable — proceed to spawn a new watcher
|
|
42
|
+
}
|
|
43
|
+
}
|
|
38
44
|
const errFd = openSync(errLog, "a");
|
|
39
|
-
const
|
|
45
|
+
const watcherPath = path.join(__dirname, "watcher.cjs");
|
|
46
|
+
const cliBinPath = path.join(__dirname, "..", "index.js");
|
|
47
|
+
const child = spawn(process.execPath, [watcherPath, projectDir, activityLog, cliBinPath], {
|
|
40
48
|
detached: true,
|
|
41
49
|
stdio: ["ignore", "ignore", errFd],
|
|
42
50
|
});
|
package/dist/lib/tracker.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracker.js","sourceRoot":"","sources":["../../src/lib/tracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AACrC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"tracker.js","sourceRoot":"","sources":["../../src/lib/tracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AACrC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,IAAI,CAAA;AACjF,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAA;AAEnC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACjD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAA;AAE1C,SAAS,cAAc,CAAC,GAAW;IACjC,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA,CAAC,qCAAqC;QAC1D,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,UAAkB;IAC7C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAA;IAClD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,gBAAgB,CAAC,CAAA;IAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;IACnD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;IAElD,IAAI,CAAC;QACH,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,eAAe;IACjB,CAAC;IAED,wCAAwC;IACxC,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxB,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,QAAQ,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAA;YACtE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,cAAc,CAAC,WAAW,CAAC,EAAE,CAAC;gBACvD,OAAM,CAAC,0BAA0B;YACnC,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,uDAAuD;QACzD,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACnC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAA;IACvD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,UAAU,CAAC,CAAA;IAEzD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,WAAW,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,CAAC,EAAE;QACxF,QAAQ,EAAE,IAAI;QACd,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC;KACnC,CAAC,CAAA;IAEF,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;QACd,KAAK,CAAC,KAAK,EAAE,CAAA;QACb,IAAI,CAAC;YACH,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAA;QACnD,CAAC;QAAC,MAAM,CAAC;YACP,eAAe;QACjB,CAAC;IACH,CAAC;AACH,CAAC"}
|