@harness-engineering/cli 1.25.1 → 1.25.2
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/dist/bin/harness-mcp.js +1 -1
- package/dist/bin/harness.js +93 -2
- package/dist/{chunk-CJXVNDZZ.js → chunk-5I3W4J5X.js} +24 -7
- package/dist/{chunk-RX7TUMBR.js → chunk-TBGIHPNA.js} +2 -0
- package/dist/index.js +2 -2
- package/dist/{mcp-2553PNUC.js → mcp-W3FLXSFF.js} +1 -1
- package/package.json +2 -2
package/dist/bin/harness-mcp.js
CHANGED
package/dist/bin/harness.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
createProgram,
|
|
4
4
|
printFirstRunWelcome
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-5I3W4J5X.js";
|
|
6
6
|
import "../chunk-5BQ5BOJL.js";
|
|
7
7
|
import "../chunk-EHRZMOQ2.js";
|
|
8
8
|
import "../chunk-XTITAVUR.js";
|
|
@@ -19,7 +19,7 @@ import "../chunk-P7PANON5.js";
|
|
|
19
19
|
import "../chunk-4NK7Z3BP.js";
|
|
20
20
|
import {
|
|
21
21
|
dispatchSkillsFromGit
|
|
22
|
-
} from "../chunk-
|
|
22
|
+
} from "../chunk-TBGIHPNA.js";
|
|
23
23
|
import "../chunk-FES2YEQU.js";
|
|
24
24
|
import "../chunk-UV3BZMGT.js";
|
|
25
25
|
import "../chunk-F23H3U5U.js";
|
|
@@ -113,6 +113,96 @@ ${message}
|
|
|
113
113
|
}
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
+
// src/bin/command-telemetry.ts
|
|
117
|
+
import { existsSync, readFileSync, mkdirSync, appendFileSync, writeFileSync } from "fs";
|
|
118
|
+
import { join, parse as parsePath, resolve } from "path";
|
|
119
|
+
import { spawn } from "child_process";
|
|
120
|
+
var EXCLUDED_COMMANDS = /* @__PURE__ */ new Set(["help", "completion"]);
|
|
121
|
+
function findProjectRoot(cwd) {
|
|
122
|
+
let dir = resolve(cwd);
|
|
123
|
+
const { root } = parsePath(dir);
|
|
124
|
+
while (dir !== root) {
|
|
125
|
+
if (existsSync(join(dir, "harness.config.json"))) return dir;
|
|
126
|
+
dir = resolve(dir, "..");
|
|
127
|
+
}
|
|
128
|
+
return cwd;
|
|
129
|
+
}
|
|
130
|
+
var commandName = "";
|
|
131
|
+
var startTime = 0;
|
|
132
|
+
var recorded = false;
|
|
133
|
+
function installCommandTelemetry(program, cwd) {
|
|
134
|
+
if (typeof program.hook !== "function") return;
|
|
135
|
+
const projectRoot = findProjectRoot(cwd);
|
|
136
|
+
flushTelemetryBackground(projectRoot);
|
|
137
|
+
program.hook("preAction", (thisCommand) => {
|
|
138
|
+
commandName = resolveCommandName(thisCommand);
|
|
139
|
+
startTime = Date.now();
|
|
140
|
+
});
|
|
141
|
+
process.on("exit", (code) => {
|
|
142
|
+
if (recorded || !commandName || EXCLUDED_COMMANDS.has(commandName)) return;
|
|
143
|
+
recorded = true;
|
|
144
|
+
const duration = Date.now() - startTime;
|
|
145
|
+
const outcome = code === 0 ? "completed" : "failed";
|
|
146
|
+
writeCommandRecordSync(projectRoot, commandName, duration, outcome);
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
function resolveCommandName(cmd) {
|
|
150
|
+
const parts = [];
|
|
151
|
+
let current = cmd;
|
|
152
|
+
while (current) {
|
|
153
|
+
const name = current.name();
|
|
154
|
+
if (name && name !== "harness") {
|
|
155
|
+
parts.unshift(name);
|
|
156
|
+
}
|
|
157
|
+
current = current.parent;
|
|
158
|
+
}
|
|
159
|
+
return parts.length > 0 ? `cli/${parts.join(".")}` : "";
|
|
160
|
+
}
|
|
161
|
+
function writeCommandRecordSync(cwd, command, duration, outcome) {
|
|
162
|
+
try {
|
|
163
|
+
const metricsDir = join(cwd, ".harness", "metrics");
|
|
164
|
+
mkdirSync(metricsDir, { recursive: true });
|
|
165
|
+
const record = {
|
|
166
|
+
skill: command,
|
|
167
|
+
session: `cli-${Date.now()}`,
|
|
168
|
+
startedAt: new Date(Date.now() - duration).toISOString(),
|
|
169
|
+
duration,
|
|
170
|
+
outcome,
|
|
171
|
+
phasesReached: []
|
|
172
|
+
};
|
|
173
|
+
const adoptionFile = join(metricsDir, "adoption.jsonl");
|
|
174
|
+
appendFileSync(adoptionFile, JSON.stringify(record) + "\n");
|
|
175
|
+
} catch {
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
function flushTelemetryBackground(cwd) {
|
|
179
|
+
try {
|
|
180
|
+
const adoptionFile = join(cwd, ".harness", "metrics", "adoption.jsonl");
|
|
181
|
+
if (!existsSync(adoptionFile)) return;
|
|
182
|
+
const configPath = join(cwd, "harness.config.json");
|
|
183
|
+
if (existsSync(configPath)) {
|
|
184
|
+
try {
|
|
185
|
+
const config = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
186
|
+
if (config?.telemetry?.enabled === false) return;
|
|
187
|
+
} catch {
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (process.env.DO_NOT_TRACK === "1") return;
|
|
191
|
+
if (process.env.HARNESS_TELEMETRY_OPTOUT === "1") return;
|
|
192
|
+
const reporterPath = join(cwd, ".harness", "hooks", "telemetry-reporter.js");
|
|
193
|
+
if (!existsSync(reporterPath)) return;
|
|
194
|
+
const child = spawn(process.execPath, [reporterPath], {
|
|
195
|
+
cwd,
|
|
196
|
+
stdio: ["pipe", "ignore", "ignore"],
|
|
197
|
+
detached: true
|
|
198
|
+
});
|
|
199
|
+
child.stdin?.write("{}");
|
|
200
|
+
child.stdin?.end();
|
|
201
|
+
child.unref();
|
|
202
|
+
} catch {
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
116
206
|
// src/skill/dispatch-session.ts
|
|
117
207
|
import { execSync } from "child_process";
|
|
118
208
|
import fs from "fs";
|
|
@@ -211,6 +301,7 @@ async function main() {
|
|
|
211
301
|
() => ({ dispatched: false })
|
|
212
302
|
);
|
|
213
303
|
const program = createProgram();
|
|
304
|
+
installCommandTelemetry(program, process.cwd());
|
|
214
305
|
try {
|
|
215
306
|
await program.parseAsync(process.argv);
|
|
216
307
|
} catch (error) {
|
|
@@ -56,7 +56,7 @@ import {
|
|
|
56
56
|
loadOrRebuildIndex,
|
|
57
57
|
persistToolingConfig,
|
|
58
58
|
recommend
|
|
59
|
-
} from "./chunk-
|
|
59
|
+
} from "./chunk-TBGIHPNA.js";
|
|
60
60
|
import {
|
|
61
61
|
findConfigFile,
|
|
62
62
|
resolveConfig
|
|
@@ -3137,7 +3137,12 @@ function buildSettingsHooks(profile) {
|
|
|
3137
3137
|
}
|
|
3138
3138
|
hooks[script.event].push({
|
|
3139
3139
|
matcher: script.matcher,
|
|
3140
|
-
hooks: [
|
|
3140
|
+
hooks: [
|
|
3141
|
+
{
|
|
3142
|
+
type: "command",
|
|
3143
|
+
command: `node "$(git rev-parse --show-toplevel)/.harness/hooks/${script.name}.js"`
|
|
3144
|
+
}
|
|
3145
|
+
]
|
|
3141
3146
|
});
|
|
3142
3147
|
}
|
|
3143
3148
|
return hooks;
|
|
@@ -3355,7 +3360,7 @@ function readJson(p) {
|
|
|
3355
3360
|
}
|
|
3356
3361
|
function registerHook(s, ev, matcher, name) {
|
|
3357
3362
|
if (!s.hooks[ev]) s.hooks[ev] = [];
|
|
3358
|
-
const cmd = `node
|
|
3363
|
+
const cmd = `node "$(git rev-parse --show-toplevel)/.harness/hooks/${name}.js"`;
|
|
3359
3364
|
if (!s.hooks[ev].some((e) => e.hooks?.some((h) => h.command === cmd))) {
|
|
3360
3365
|
s.hooks[ev].push({ matcher, hooks: [{ type: "command", command: cmd }] });
|
|
3361
3366
|
}
|
|
@@ -5418,7 +5423,7 @@ function createMcpCommand() {
|
|
|
5418
5423
|
parseBudget
|
|
5419
5424
|
).action(async (opts) => {
|
|
5420
5425
|
const [{ startServer: startServer2, getToolDefinitions: getToolDefinitions2 }, { selectTier }] = await Promise.all([
|
|
5421
|
-
import("./mcp-
|
|
5426
|
+
import("./mcp-W3FLXSFF.js"),
|
|
5422
5427
|
import("./tool-tiers-7QGZ3FKY.js")
|
|
5423
5428
|
]);
|
|
5424
5429
|
if (opts.tools && opts.tools.length > 0) {
|
|
@@ -6272,6 +6277,18 @@ function prompt(question) {
|
|
|
6272
6277
|
});
|
|
6273
6278
|
});
|
|
6274
6279
|
}
|
|
6280
|
+
function promptRaw(question) {
|
|
6281
|
+
const rl = readline.createInterface({
|
|
6282
|
+
input: process.stdin,
|
|
6283
|
+
output: process.stdout
|
|
6284
|
+
});
|
|
6285
|
+
return new Promise((resolve35) => {
|
|
6286
|
+
rl.question(question, (answer) => {
|
|
6287
|
+
rl.close();
|
|
6288
|
+
resolve35(answer.trim());
|
|
6289
|
+
});
|
|
6290
|
+
});
|
|
6291
|
+
}
|
|
6275
6292
|
function isNo(answer) {
|
|
6276
6293
|
return answer === "n" || answer === "no";
|
|
6277
6294
|
}
|
|
@@ -6312,11 +6329,11 @@ async function promptIdentity() {
|
|
|
6312
6329
|
const answer = await prompt(" Set identity fields? (y/N) ");
|
|
6313
6330
|
const identity = {};
|
|
6314
6331
|
if (answer === "y" || answer === "yes") {
|
|
6315
|
-
const projectName = await
|
|
6332
|
+
const projectName = await promptRaw(" Project name: ");
|
|
6316
6333
|
if (projectName) identity.project = projectName;
|
|
6317
|
-
const teamName = await
|
|
6334
|
+
const teamName = await promptRaw(" Team name: ");
|
|
6318
6335
|
if (teamName) identity.team = teamName;
|
|
6319
|
-
const alias = await
|
|
6336
|
+
const alias = await promptRaw(" Alias: ");
|
|
6320
6337
|
if (alias) identity.alias = alias;
|
|
6321
6338
|
}
|
|
6322
6339
|
return identity;
|
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
runSnapshotCapture,
|
|
13
13
|
runUninstall,
|
|
14
14
|
runUninstallConstraints
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-5I3W4J5X.js";
|
|
16
16
|
import {
|
|
17
17
|
generateAgentsMd
|
|
18
18
|
} from "./chunk-5BQ5BOJL.js";
|
|
@@ -66,7 +66,7 @@ import {
|
|
|
66
66
|
generateSlashCommands,
|
|
67
67
|
getToolDefinitions,
|
|
68
68
|
startServer
|
|
69
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-TBGIHPNA.js";
|
|
70
70
|
import "./chunk-FES2YEQU.js";
|
|
71
71
|
import "./chunk-UV3BZMGT.js";
|
|
72
72
|
import "./chunk-F23H3U5U.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@harness-engineering/cli",
|
|
3
|
-
"version": "1.25.
|
|
3
|
+
"version": "1.25.2",
|
|
4
4
|
"description": "CLI for Harness Engineering toolkit",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
"@harness-engineering/core": "0.22.0",
|
|
41
41
|
"@harness-engineering/dashboard": "0.1.5",
|
|
42
42
|
"@harness-engineering/graph": "0.4.3",
|
|
43
|
-
"@harness-engineering/orchestrator": "0.2.8",
|
|
44
43
|
"@harness-engineering/linter-gen": "0.1.6",
|
|
44
|
+
"@harness-engineering/orchestrator": "0.2.8",
|
|
45
45
|
"@harness-engineering/types": "0.9.2"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|