@harness-engineering/cli 1.26.1 → 1.27.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/dist/agents/skills/claude-code/cleanup-dead-code/SKILL.md +3 -1
- package/dist/agents/skills/claude-code/detect-doc-drift/SKILL.md +3 -1
- package/dist/agents/skills/claude-code/harness-architecture-advisor/SKILL.md +4 -0
- package/dist/agents/skills/claude-code/harness-autopilot/SKILL.md +55 -24
- package/dist/agents/skills/claude-code/harness-brainstorming/SKILL.md +16 -5
- package/dist/agents/skills/claude-code/harness-code-review/SKILL.md +21 -6
- package/dist/agents/skills/claude-code/harness-codebase-cleanup/SKILL.md +2 -0
- package/dist/agents/skills/claude-code/harness-debugging/SKILL.md +13 -1
- package/dist/agents/skills/claude-code/harness-dependency-health/SKILL.md +4 -0
- package/dist/agents/skills/claude-code/harness-execution/SKILL.md +16 -6
- package/dist/agents/skills/claude-code/harness-impact-analysis/SKILL.md +2 -0
- package/dist/agents/skills/claude-code/harness-integration/SKILL.md +560 -0
- package/dist/agents/skills/claude-code/harness-integration/skill.yaml +65 -0
- package/dist/agents/skills/claude-code/harness-integrity/SKILL.md +2 -0
- package/dist/agents/skills/claude-code/harness-onboarding/SKILL.md +4 -0
- package/dist/agents/skills/claude-code/harness-perf/SKILL.md +9 -7
- package/dist/agents/skills/claude-code/harness-planning/SKILL.md +77 -10
- package/dist/agents/skills/claude-code/harness-refactoring/SKILL.md +13 -4
- package/dist/agents/skills/claude-code/harness-security-scan/SKILL.md +3 -1
- package/dist/agents/skills/claude-code/harness-soundness-review/SKILL.md +4 -0
- package/dist/agents/skills/claude-code/harness-tdd/SKILL.md +5 -2
- package/dist/agents/skills/claude-code/harness-verification/SKILL.md +4 -0
- package/dist/agents/skills/codex/cleanup-dead-code/SKILL.md +3 -1
- package/dist/agents/skills/codex/detect-doc-drift/SKILL.md +3 -1
- package/dist/agents/skills/codex/harness-architecture-advisor/SKILL.md +4 -0
- package/dist/agents/skills/codex/harness-autopilot/SKILL.md +55 -24
- package/dist/agents/skills/codex/harness-brainstorming/SKILL.md +16 -5
- package/dist/agents/skills/codex/harness-code-review/SKILL.md +21 -6
- package/dist/agents/skills/codex/harness-codebase-cleanup/SKILL.md +2 -0
- package/dist/agents/skills/codex/harness-debugging/SKILL.md +13 -1
- package/dist/agents/skills/codex/harness-dependency-health/SKILL.md +4 -0
- package/dist/agents/skills/codex/harness-execution/SKILL.md +16 -6
- package/dist/agents/skills/codex/harness-impact-analysis/SKILL.md +2 -0
- package/dist/agents/skills/codex/harness-integration/SKILL.md +560 -0
- package/dist/agents/skills/codex/harness-integration/skill.yaml +65 -0
- package/dist/agents/skills/codex/harness-integrity/SKILL.md +2 -0
- package/dist/agents/skills/codex/harness-onboarding/SKILL.md +4 -0
- package/dist/agents/skills/codex/harness-perf/SKILL.md +9 -7
- package/dist/agents/skills/codex/harness-planning/SKILL.md +77 -10
- package/dist/agents/skills/codex/harness-refactoring/SKILL.md +13 -4
- package/dist/agents/skills/codex/harness-security-scan/SKILL.md +3 -1
- package/dist/agents/skills/codex/harness-soundness-review/SKILL.md +4 -0
- package/dist/agents/skills/codex/harness-tdd/SKILL.md +5 -2
- package/dist/agents/skills/codex/harness-verification/SKILL.md +4 -0
- package/dist/agents/skills/cursor/cleanup-dead-code/SKILL.md +3 -1
- package/dist/agents/skills/cursor/detect-doc-drift/SKILL.md +3 -1
- package/dist/agents/skills/cursor/harness-architecture-advisor/SKILL.md +4 -0
- package/dist/agents/skills/cursor/harness-autopilot/SKILL.md +55 -24
- package/dist/agents/skills/cursor/harness-brainstorming/SKILL.md +16 -5
- package/dist/agents/skills/cursor/harness-code-review/SKILL.md +21 -6
- package/dist/agents/skills/cursor/harness-codebase-cleanup/SKILL.md +2 -0
- package/dist/agents/skills/cursor/harness-debugging/SKILL.md +13 -1
- package/dist/agents/skills/cursor/harness-dependency-health/SKILL.md +4 -0
- package/dist/agents/skills/cursor/harness-execution/SKILL.md +16 -6
- package/dist/agents/skills/cursor/harness-impact-analysis/SKILL.md +2 -0
- package/dist/agents/skills/cursor/harness-integration/SKILL.md +560 -0
- package/dist/agents/skills/cursor/harness-integration/skill.yaml +65 -0
- package/dist/agents/skills/cursor/harness-integrity/SKILL.md +2 -0
- package/dist/agents/skills/cursor/harness-onboarding/SKILL.md +4 -0
- package/dist/agents/skills/cursor/harness-perf/SKILL.md +9 -7
- package/dist/agents/skills/cursor/harness-planning/SKILL.md +77 -10
- package/dist/agents/skills/cursor/harness-refactoring/SKILL.md +13 -4
- package/dist/agents/skills/cursor/harness-security-scan/SKILL.md +3 -1
- package/dist/agents/skills/cursor/harness-soundness-review/SKILL.md +4 -0
- package/dist/agents/skills/cursor/harness-tdd/SKILL.md +5 -2
- package/dist/agents/skills/cursor/harness-verification/SKILL.md +4 -0
- package/dist/agents/skills/gemini-cli/cleanup-dead-code/SKILL.md +3 -1
- package/dist/agents/skills/gemini-cli/detect-doc-drift/SKILL.md +3 -1
- package/dist/agents/skills/gemini-cli/harness-architecture-advisor/SKILL.md +4 -0
- package/dist/agents/skills/gemini-cli/harness-autopilot/SKILL.md +55 -24
- package/dist/agents/skills/gemini-cli/harness-brainstorming/SKILL.md +16 -5
- package/dist/agents/skills/gemini-cli/harness-code-review/SKILL.md +21 -6
- package/dist/agents/skills/gemini-cli/harness-codebase-cleanup/SKILL.md +2 -0
- package/dist/agents/skills/gemini-cli/harness-debugging/SKILL.md +13 -1
- package/dist/agents/skills/gemini-cli/harness-dependency-health/SKILL.md +4 -0
- package/dist/agents/skills/gemini-cli/harness-execution/SKILL.md +16 -6
- package/dist/agents/skills/gemini-cli/harness-impact-analysis/SKILL.md +2 -0
- package/dist/agents/skills/gemini-cli/harness-integration/SKILL.md +560 -0
- package/dist/agents/skills/gemini-cli/harness-integration/skill.yaml +65 -0
- package/dist/agents/skills/gemini-cli/harness-integrity/SKILL.md +2 -0
- package/dist/agents/skills/gemini-cli/harness-onboarding/SKILL.md +4 -0
- package/dist/agents/skills/gemini-cli/harness-perf/SKILL.md +9 -7
- package/dist/agents/skills/gemini-cli/harness-planning/SKILL.md +77 -10
- package/dist/agents/skills/gemini-cli/harness-refactoring/SKILL.md +13 -4
- package/dist/agents/skills/gemini-cli/harness-security-scan/SKILL.md +3 -1
- package/dist/agents/skills/gemini-cli/harness-soundness-review/SKILL.md +4 -0
- package/dist/agents/skills/gemini-cli/harness-tdd/SKILL.md +5 -2
- package/dist/agents/skills/gemini-cli/harness-verification/SKILL.md +4 -0
- package/dist/{agents-md-VI3HLR7E.js → agents-md-2RN666DE.js} +3 -3
- package/dist/{architecture-ZDDKEVID.js → architecture-ZR33YKJB.js} +4 -4
- package/dist/{assess-project-Y6W7YDUA.js → assess-project-LLWWEQEV.js} +1 -1
- package/dist/bin/harness-mcp.js +17 -16
- package/dist/bin/harness.js +27 -26
- package/dist/{business-knowledge-6RHYJOB3.js → business-knowledge-EISPR7FU.js} +1 -1
- package/dist/{check-phase-gate-CXR3VM22.js → check-phase-gate-ZVG56NT2.js} +4 -4
- package/dist/chunk-27AJKSQY.js +107 -0
- package/dist/{chunk-DBIX3X4H.js → chunk-2FOLD76X.js} +2 -2
- package/dist/{chunk-3AMQYWGT.js → chunk-3AJW7VQ3.js} +2 -2
- package/dist/{chunk-FUND5WJR.js → chunk-3XMOWLK3.js} +2 -2
- package/dist/{chunk-OLW7BJ5N.js → chunk-776JFSPK.js} +1 -1
- package/dist/{chunk-VKS3F46M.js → chunk-A4ETL34H.js} +7 -2
- package/dist/{chunk-JV4Y2U5F.js → chunk-BO4AJZRE.js} +1 -1
- package/dist/{chunk-WZ7UHPT3.js → chunk-BZZNYHRY.js} +9 -9
- package/dist/{chunk-ZN6ROTYP.js → chunk-C7RPQWBG.js} +1 -1
- package/dist/{chunk-RAVD7QLY.js → chunk-CJYNZMOP.js} +8 -8
- package/dist/{chunk-PNNFCVW4.js → chunk-EGRQHLDM.js} +5 -5
- package/dist/{chunk-2BPPS6YQ.js → chunk-EHTUWULH.js} +458 -363
- package/dist/{chunk-N6B6RKQQ.js → chunk-EICASBYP.js} +1 -1
- package/dist/{chunk-K56DTX7G.js → chunk-F3Y64VNF.js} +6 -6
- package/dist/{chunk-ORNEK65Y.js → chunk-FUS4OOGC.js} +1 -1
- package/dist/{chunk-2FPUPRCY.js → chunk-GAIOIINV.js} +594 -127
- package/dist/{chunk-YC4EYIER.js → chunk-IBTHD2UA.js} +132 -77
- package/dist/{chunk-RC5ZY3EV.js → chunk-IOW3MW2K.js} +2 -2
- package/dist/{chunk-B66LRB5M.js → chunk-L3Y7L4EG.js} +1 -1
- package/dist/{chunk-BK4DJIIY.js → chunk-MGPVA2EM.js} +27 -4
- package/dist/{chunk-NY7DTZ6K.js → chunk-Q5DKIL46.js} +3 -3
- package/dist/{chunk-TY2ESLVL.js → chunk-SDDQPMZK.js} +1 -1
- package/dist/{chunk-7GY6WNEI.js → chunk-SDPHFDQS.js} +1 -1
- package/dist/{chunk-56A6OXVA.js → chunk-T7UZOJF4.js} +9 -9
- package/dist/{chunk-AMRC4FU2.js → chunk-VCC47EXU.js} +109 -57
- package/dist/{chunk-Q3ZLVMQM.js → chunk-XKU37HGH.js} +10 -1
- package/dist/{chunk-TSVYBDDE.js → chunk-YZH4I4JO.js} +1 -1
- package/dist/{ci-workflow-EW37KVPS.js → ci-workflow-JFOL4YWW.js} +3 -3
- package/dist/{dist-NCNAXUFD.js → dist-BZS2XRLG.js} +5 -1
- package/dist/{dist-CJDGASPP.js → dist-CPKL5Y2R.js} +2 -2
- package/dist/{docs-4XI2FQW2.js → docs-FUTRJQHA.js} +4 -4
- package/dist/{engine-4L4CDTHU.js → engine-FB3HCNVT.js} +3 -3
- package/dist/{entropy-PBYSIQYS.js → entropy-FIEE4YDA.js} +3 -3
- package/dist/{feedback-OTIFW5MK.js → feedback-7EC4T6XG.js} +1 -1
- package/dist/{generate-agent-definitions-CZGUXIIN.js → generate-agent-definitions-FOSFADNR.js} +4 -4
- package/dist/{graph-loader-RDXSEBD7.js → graph-loader-QEI7SYOQ.js} +1 -1
- package/dist/hooks/adoption-tracker.js +36 -8
- package/dist/hooks/sentinel-pre.js +3 -2
- package/dist/hooks/telemetry-reporter.js +34 -15
- package/dist/index-builder-3AOQ3ZII.js +13 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +29 -28
- package/dist/{loader-UZOXCWFC.js → loader-HXUOBTYA.js} +3 -3
- package/dist/{mcp-GWVVV6LH.js → mcp-NUG4BMKJ.js} +17 -16
- package/dist/{performance-5UQPP3XX.js → performance-TYXBCTR7.js} +4 -4
- package/dist/{review-pipeline-65V4EO6O.js → review-pipeline-B4WPU6BQ.js} +3 -3
- package/dist/{runtime-PXX7HNB3.js → runtime-HQQNOARD.js} +3 -3
- package/dist/{scan-WM7XDUF7.js → scan-M4EGDAQ2.js} +1 -1
- package/dist/{security-CAYDRZIZ.js → security-25VFLIAO.js} +1 -1
- package/dist/templates/orchestrator/harness.orchestrator.md +18 -8
- package/dist/{validate-CWGXR7QM.js → validate-EAVGKZQB.js} +4 -4
- package/dist/{validate-cross-check-BKCNLZYG.js → validate-cross-check-SPL3H4O5.js} +3 -3
- package/package.json +13 -5
- package/dist/hooks/profiles.ts +0 -48
|
@@ -4,10 +4,12 @@
|
|
|
4
4
|
// appends SkillInvocationRecord entries to .harness/metrics/adoption.jsonl.
|
|
5
5
|
// Exit codes: 0 = allow (always, log-only hook)
|
|
6
6
|
|
|
7
|
-
import { readFileSync, mkdirSync, appendFileSync, existsSync } from 'node:fs';
|
|
7
|
+
import { readFileSync, writeFileSync, mkdirSync, appendFileSync, existsSync } from 'node:fs';
|
|
8
8
|
import { join } from 'node:path';
|
|
9
9
|
import process from 'node:process';
|
|
10
10
|
|
|
11
|
+
const ADOPTION_CURSOR_FILE = '.adoption-cursor';
|
|
12
|
+
|
|
11
13
|
/** Read and parse a JSON file, returning null on any error. */
|
|
12
14
|
function readJsonSafe(filePath) {
|
|
13
15
|
try {
|
|
@@ -25,17 +27,27 @@ function isAdoptionEnabled(cwd) {
|
|
|
25
27
|
return true;
|
|
26
28
|
}
|
|
27
29
|
|
|
28
|
-
/**
|
|
29
|
-
function
|
|
30
|
-
let raw;
|
|
30
|
+
/** Read the cursor offset for events.jsonl processing. */
|
|
31
|
+
function readEventsCursor(cwd) {
|
|
31
32
|
try {
|
|
32
|
-
|
|
33
|
+
const data = JSON.parse(readFileSync(join(cwd, '.harness', 'metrics', ADOPTION_CURSOR_FILE), 'utf-8'));
|
|
34
|
+
return typeof data.offset === 'number' ? data.offset : 0;
|
|
33
35
|
} catch {
|
|
34
|
-
return
|
|
36
|
+
return 0;
|
|
35
37
|
}
|
|
38
|
+
}
|
|
36
39
|
|
|
40
|
+
/** Save the cursor offset after processing events. */
|
|
41
|
+
function writeEventsCursor(cwd, offset) {
|
|
42
|
+
const metricsDir = join(cwd, '.harness', 'metrics');
|
|
43
|
+
mkdirSync(metricsDir, { recursive: true });
|
|
44
|
+
writeFileSync(join(metricsDir, ADOPTION_CURSOR_FILE), JSON.stringify({ offset }) + '\n');
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Parse events from a content string. Skips malformed lines. */
|
|
48
|
+
function parseEventsContent(content) {
|
|
37
49
|
const events = [];
|
|
38
|
-
const lines =
|
|
50
|
+
const lines = content.split('\n');
|
|
39
51
|
for (const line of lines) {
|
|
40
52
|
const trimmed = line.trim();
|
|
41
53
|
if (!trimmed) continue;
|
|
@@ -135,11 +147,24 @@ function main() {
|
|
|
135
147
|
process.exit(0);
|
|
136
148
|
}
|
|
137
149
|
|
|
138
|
-
const
|
|
150
|
+
const fullContent = readFileSync(eventsPath, 'utf-8');
|
|
151
|
+
const cursor = readEventsCursor(cwd);
|
|
152
|
+
// If file shrank (was manually reset), reprocess from start
|
|
153
|
+
const effectiveCursor = cursor > fullContent.length ? 0 : cursor;
|
|
154
|
+
const newContent = fullContent.slice(effectiveCursor);
|
|
155
|
+
|
|
156
|
+
if (!newContent.trim()) {
|
|
157
|
+
process.stderr.write('[adoption-tracker] No new events since last run — skipping\n');
|
|
158
|
+
process.exit(0);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const allEvents = parseEventsContent(newContent);
|
|
139
162
|
// Filter to relevant event types
|
|
140
163
|
const relevantEvents = allEvents.filter((e) => RELEVANT_TYPES.has(e.type));
|
|
141
164
|
if (relevantEvents.length === 0) {
|
|
142
165
|
process.stderr.write('[adoption-tracker] No relevant skill events — skipping\n');
|
|
166
|
+
// Still advance cursor past non-relevant events
|
|
167
|
+
writeEventsCursor(cwd, fullContent.length);
|
|
143
168
|
process.exit(0);
|
|
144
169
|
}
|
|
145
170
|
|
|
@@ -176,6 +201,9 @@ function main() {
|
|
|
176
201
|
written++;
|
|
177
202
|
}
|
|
178
203
|
|
|
204
|
+
// Advance cursor past processed events
|
|
205
|
+
writeEventsCursor(cwd, fullContent.length);
|
|
206
|
+
|
|
179
207
|
process.stderr.write(
|
|
180
208
|
`[adoption-tracker] Wrote ${written} adoption record(s) for session ${sessionId}\n`
|
|
181
209
|
);
|
|
@@ -75,8 +75,9 @@ function inlineScan(text) {
|
|
|
75
75
|
if (/(?:auto[- ]?approve|--no-verify|--dangerously-skip-permissions)/i.test(line)) {
|
|
76
76
|
findings.push({ severity: 'high', ruleId: 'INJ-PERM-003', match: line.trim(), line: i + 1 });
|
|
77
77
|
}
|
|
78
|
-
// HIGH: INJ-ENC-001 — Suspicious base64
|
|
79
|
-
if (
|
|
78
|
+
// HIGH: INJ-ENC-001 — Suspicious base64 (skip lines that look like file paths or CLI commands)
|
|
79
|
+
if (!/^[\s]*(?:cd |git |node |pnpm |npm |\/|packages\/|agents\/|src\/)/.test(line) &&
|
|
80
|
+
/(?<!Bearer\s)(?<![:])(?<![A-Za-z0-9/])(?!eyJ)(?:[A-Za-z0-9+/]{4}){7,}(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?(?![A-Za-z0-9/])/.test(line)) {
|
|
80
81
|
findings.push({ severity: 'high', ruleId: 'INJ-ENC-001', match: line.trim(), line: i + 1 });
|
|
81
82
|
}
|
|
82
83
|
// MEDIUM: INJ-CTX-001 — System prompt claims
|
|
@@ -98,19 +98,43 @@ function getOrCreateInstallId(cwd) {
|
|
|
98
98
|
return id;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
+
// --- Cursor ---
|
|
102
|
+
|
|
103
|
+
const TELEMETRY_CURSOR_FILE = '.telemetry-cursor';
|
|
104
|
+
|
|
105
|
+
function readCursor(cwd) {
|
|
106
|
+
try {
|
|
107
|
+
const data = JSON.parse(readFileSync(join(cwd, '.harness', 'metrics', TELEMETRY_CURSOR_FILE), 'utf-8'));
|
|
108
|
+
return typeof data.offset === 'number' ? data.offset : 0;
|
|
109
|
+
} catch {
|
|
110
|
+
return 0;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function writeCursor(cwd, offset) {
|
|
115
|
+
const metricsDir = join(cwd, '.harness', 'metrics');
|
|
116
|
+
mkdirSync(metricsDir, { recursive: true });
|
|
117
|
+
writeFileSync(join(metricsDir, TELEMETRY_CURSOR_FILE), JSON.stringify({ offset }) + '\n');
|
|
118
|
+
}
|
|
119
|
+
|
|
101
120
|
// --- Collector ---
|
|
102
121
|
|
|
103
|
-
function
|
|
122
|
+
function readNewAdoptionRecords(cwd) {
|
|
104
123
|
const adoptionFile = join(cwd, '.harness', 'metrics', 'adoption.jsonl');
|
|
105
124
|
let raw;
|
|
106
125
|
try {
|
|
107
126
|
raw = readFileSync(adoptionFile, 'utf-8');
|
|
108
127
|
} catch {
|
|
109
|
-
return [];
|
|
128
|
+
return { records: [], newOffset: 0 };
|
|
110
129
|
}
|
|
111
130
|
|
|
131
|
+
const cursor = readCursor(cwd);
|
|
132
|
+
// If file shrank (was manually reset), reprocess from start
|
|
133
|
+
const effectiveCursor = cursor > raw.length ? 0 : cursor;
|
|
134
|
+
const newContent = raw.slice(effectiveCursor);
|
|
135
|
+
|
|
112
136
|
const records = [];
|
|
113
|
-
for (const line of
|
|
137
|
+
for (const line of newContent.split('\n')) {
|
|
114
138
|
const trimmed = line.trim();
|
|
115
139
|
if (!trimmed) continue;
|
|
116
140
|
try {
|
|
@@ -128,11 +152,10 @@ function readAdoptionRecords(cwd) {
|
|
|
128
152
|
// Skip malformed lines
|
|
129
153
|
}
|
|
130
154
|
}
|
|
131
|
-
return records;
|
|
155
|
+
return { records, newOffset: raw.length };
|
|
132
156
|
}
|
|
133
157
|
|
|
134
|
-
function collectEvents(cwd, consent) {
|
|
135
|
-
const records = readAdoptionRecords(cwd);
|
|
158
|
+
function collectEvents(cwd, records, consent) {
|
|
136
159
|
if (records.length === 0) return [];
|
|
137
160
|
|
|
138
161
|
const { installId, identity } = consent;
|
|
@@ -242,21 +265,17 @@ async function main() {
|
|
|
242
265
|
// Show first-run notice (before sending, so user sees it even if send fails)
|
|
243
266
|
showFirstRunNotice(cwd);
|
|
244
267
|
|
|
245
|
-
const
|
|
268
|
+
const { records, newOffset } = readNewAdoptionRecords(cwd);
|
|
269
|
+
const events = collectEvents(cwd, records, consent);
|
|
246
270
|
if (events.length === 0) {
|
|
247
|
-
process.stderr.write('[telemetry-reporter] No adoption records to report\n');
|
|
271
|
+
process.stderr.write('[telemetry-reporter] No new adoption records to report\n');
|
|
248
272
|
process.exit(0);
|
|
249
273
|
}
|
|
250
274
|
|
|
251
275
|
await sendEvents(events);
|
|
252
276
|
|
|
253
|
-
//
|
|
254
|
-
|
|
255
|
-
try {
|
|
256
|
-
writeFileSync(adoptionFile, '', 'utf-8');
|
|
257
|
-
} catch {
|
|
258
|
-
// Non-fatal — records may be re-sent next session
|
|
259
|
-
}
|
|
277
|
+
// Advance cursor past sent records (adoption.jsonl is preserved for CLI reads)
|
|
278
|
+
writeCursor(cwd, newOffset);
|
|
260
279
|
|
|
261
280
|
process.stderr.write(`[telemetry-reporter] Sent ${events.length} telemetry event(s)\n`);
|
|
262
281
|
process.exit(0);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
buildIndex,
|
|
3
|
+
computeSkillsDirHash,
|
|
4
|
+
loadOrRebuildIndex
|
|
5
|
+
} from "./chunk-27AJKSQY.js";
|
|
6
|
+
import "./chunk-6B6UN6SG.js";
|
|
7
|
+
import "./chunk-HIK6OEUF.js";
|
|
8
|
+
import "./chunk-KFQGP6VL.js";
|
|
9
|
+
export {
|
|
10
|
+
buildIndex,
|
|
11
|
+
computeSkillsDirHash,
|
|
12
|
+
loadOrRebuildIndex
|
|
13
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -848,6 +848,15 @@ declare const HarnessConfigSchema: z.ZodObject<{
|
|
|
848
848
|
}>>;
|
|
849
849
|
/** How often (in ms) to check for CLI updates */
|
|
850
850
|
updateCheckInterval: z.ZodOptional<z.ZodNumber>;
|
|
851
|
+
/** Graph ingest and connector settings */
|
|
852
|
+
graph: z.ZodOptional<z.ZodObject<{
|
|
853
|
+
/** Per-connector configuration (keyed by connector name: jira, slack, ci, confluence, figma, miro) */
|
|
854
|
+
connectors: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
855
|
+
}, "strip", z.ZodTypeAny, {
|
|
856
|
+
connectors: Record<string, Record<string, unknown>>;
|
|
857
|
+
}, {
|
|
858
|
+
connectors?: Record<string, Record<string, unknown>> | undefined;
|
|
859
|
+
}>>;
|
|
851
860
|
}, "strip", z.ZodTypeAny, {
|
|
852
861
|
version: 1;
|
|
853
862
|
rootDir: string;
|
|
@@ -992,6 +1001,9 @@ declare const HarnessConfigSchema: z.ZodObject<{
|
|
|
992
1001
|
enabled: boolean;
|
|
993
1002
|
} | undefined;
|
|
994
1003
|
updateCheckInterval?: number | undefined;
|
|
1004
|
+
graph?: {
|
|
1005
|
+
connectors: Record<string, Record<string, unknown>>;
|
|
1006
|
+
} | undefined;
|
|
995
1007
|
}, {
|
|
996
1008
|
version: 1;
|
|
997
1009
|
name?: string | undefined;
|
|
@@ -1136,6 +1148,9 @@ declare const HarnessConfigSchema: z.ZodObject<{
|
|
|
1136
1148
|
enabled?: boolean | undefined;
|
|
1137
1149
|
} | undefined;
|
|
1138
1150
|
updateCheckInterval?: number | undefined;
|
|
1151
|
+
graph?: {
|
|
1152
|
+
connectors?: Record<string, Record<string, unknown>> | undefined;
|
|
1153
|
+
} | undefined;
|
|
1139
1154
|
}>;
|
|
1140
1155
|
/**
|
|
1141
1156
|
* Type representing the full Harness configuration.
|
package/dist/index.js
CHANGED
|
@@ -12,23 +12,23 @@ import {
|
|
|
12
12
|
runSnapshotCapture,
|
|
13
13
|
runUninstall,
|
|
14
14
|
runUninstallConstraints
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-VCC47EXU.js";
|
|
16
|
+
import {
|
|
17
|
+
generateRuntime
|
|
18
|
+
} from "./chunk-EICASBYP.js";
|
|
16
19
|
import {
|
|
17
20
|
generateAgentsMd
|
|
18
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-C7RPQWBG.js";
|
|
19
22
|
import {
|
|
20
23
|
generateCIWorkflow
|
|
21
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-FUS4OOGC.js";
|
|
22
25
|
import {
|
|
23
26
|
runCrossCheck
|
|
24
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-SDPHFDQS.js";
|
|
25
28
|
import {
|
|
26
29
|
TemplateEngine
|
|
27
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-L3Y7L4EG.js";
|
|
28
31
|
import "./chunk-CQ553GZO.js";
|
|
29
|
-
import {
|
|
30
|
-
generateRuntime
|
|
31
|
-
} from "./chunk-N6B6RKQQ.js";
|
|
32
32
|
import {
|
|
33
33
|
detectTrigger,
|
|
34
34
|
runPersona
|
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
OutputFormatter,
|
|
44
44
|
OutputMode,
|
|
45
45
|
runCheckPhaseGate
|
|
46
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-3XMOWLK3.js";
|
|
47
47
|
import {
|
|
48
48
|
AGENT_DESCRIPTIONS,
|
|
49
49
|
DEFAULT_TOOLS,
|
|
@@ -52,46 +52,47 @@ import {
|
|
|
52
52
|
generateAgentDefinitions,
|
|
53
53
|
renderClaudeCodeAgent,
|
|
54
54
|
renderGeminiAgent
|
|
55
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-SDDQPMZK.js";
|
|
56
56
|
import "./chunk-KET4QQZB.js";
|
|
57
57
|
import {
|
|
58
58
|
listPersonas,
|
|
59
59
|
loadPersona
|
|
60
|
-
} from "./chunk-
|
|
60
|
+
} from "./chunk-BO4AJZRE.js";
|
|
61
61
|
import {
|
|
62
62
|
runScan
|
|
63
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-XKU37HGH.js";
|
|
64
64
|
import {
|
|
65
65
|
createHarnessServer,
|
|
66
66
|
generateSlashCommands,
|
|
67
67
|
getToolDefinitions,
|
|
68
68
|
startServer
|
|
69
|
-
} from "./chunk-
|
|
70
|
-
import "./chunk-
|
|
71
|
-
import "./chunk-
|
|
72
|
-
import "./chunk-
|
|
73
|
-
import "./chunk-
|
|
74
|
-
import "./chunk-
|
|
75
|
-
import "./chunk-
|
|
76
|
-
import "./chunk-
|
|
77
|
-
import "./chunk-
|
|
78
|
-
import "./chunk-
|
|
79
|
-
import "./chunk-
|
|
80
|
-
import "./chunk-
|
|
69
|
+
} from "./chunk-EHTUWULH.js";
|
|
70
|
+
import "./chunk-2FOLD76X.js";
|
|
71
|
+
import "./chunk-F3Y64VNF.js";
|
|
72
|
+
import "./chunk-IOW3MW2K.js";
|
|
73
|
+
import "./chunk-BZZNYHRY.js";
|
|
74
|
+
import "./chunk-3AJW7VQ3.js";
|
|
75
|
+
import "./chunk-776JFSPK.js";
|
|
76
|
+
import "./chunk-Q5DKIL46.js";
|
|
77
|
+
import "./chunk-MGPVA2EM.js";
|
|
78
|
+
import "./chunk-YZH4I4JO.js";
|
|
79
|
+
import "./chunk-T7UZOJF4.js";
|
|
80
|
+
import "./chunk-EGRQHLDM.js";
|
|
81
|
+
import "./chunk-CJYNZMOP.js";
|
|
81
82
|
import "./chunk-EPUKTTJZ.js";
|
|
82
83
|
import "./chunk-W6Y7ZW3Y.js";
|
|
84
|
+
import "./chunk-27AJKSQY.js";
|
|
83
85
|
import {
|
|
84
86
|
findConfigFile,
|
|
85
87
|
loadConfig,
|
|
86
88
|
resolveConfig
|
|
87
|
-
} from "./chunk-
|
|
89
|
+
} from "./chunk-A4ETL34H.js";
|
|
88
90
|
import "./chunk-3ISINLYT.js";
|
|
89
91
|
import "./chunk-6B6UN6SG.js";
|
|
90
|
-
import "./chunk-OLW7BJ5N.js";
|
|
91
92
|
import "./chunk-BM3PWGXQ.js";
|
|
92
|
-
import "./chunk-
|
|
93
|
+
import "./chunk-IBTHD2UA.js";
|
|
93
94
|
import "./chunk-RL4VMEXL.js";
|
|
94
|
-
import "./chunk-
|
|
95
|
+
import "./chunk-GAIOIINV.js";
|
|
95
96
|
import {
|
|
96
97
|
generateSkillFiles
|
|
97
98
|
} from "./chunk-ZP5E7YET.js";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
listPersonas,
|
|
3
3
|
loadPersona
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-BO4AJZRE.js";
|
|
5
|
+
import "./chunk-IBTHD2UA.js";
|
|
6
6
|
import "./chunk-RL4VMEXL.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-GAIOIINV.js";
|
|
8
8
|
import "./chunk-KFQGP6VL.js";
|
|
9
9
|
export {
|
|
10
10
|
listPersonas,
|
|
@@ -2,31 +2,32 @@ import {
|
|
|
2
2
|
createHarnessServer,
|
|
3
3
|
getToolDefinitions,
|
|
4
4
|
startServer
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
9
|
-
import "./chunk-
|
|
10
|
-
import "./chunk-
|
|
11
|
-
import "./chunk-
|
|
12
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-EHTUWULH.js";
|
|
6
|
+
import "./chunk-2FOLD76X.js";
|
|
7
|
+
import "./chunk-F3Y64VNF.js";
|
|
8
|
+
import "./chunk-IOW3MW2K.js";
|
|
9
|
+
import "./chunk-BZZNYHRY.js";
|
|
10
|
+
import "./chunk-3AJW7VQ3.js";
|
|
11
|
+
import "./chunk-776JFSPK.js";
|
|
12
|
+
import "./chunk-Q5DKIL46.js";
|
|
13
|
+
import "./chunk-MGPVA2EM.js";
|
|
13
14
|
import {
|
|
14
15
|
resolveProjectConfig
|
|
15
|
-
} from "./chunk-
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
18
|
-
import "./chunk-
|
|
16
|
+
} from "./chunk-YZH4I4JO.js";
|
|
17
|
+
import "./chunk-T7UZOJF4.js";
|
|
18
|
+
import "./chunk-EGRQHLDM.js";
|
|
19
|
+
import "./chunk-CJYNZMOP.js";
|
|
19
20
|
import {
|
|
20
21
|
resultToMcpResponse
|
|
21
22
|
} from "./chunk-EPUKTTJZ.js";
|
|
22
23
|
import "./chunk-W6Y7ZW3Y.js";
|
|
23
|
-
import "./chunk-
|
|
24
|
+
import "./chunk-27AJKSQY.js";
|
|
25
|
+
import "./chunk-A4ETL34H.js";
|
|
24
26
|
import "./chunk-3ISINLYT.js";
|
|
25
27
|
import "./chunk-6B6UN6SG.js";
|
|
26
|
-
import "./chunk-
|
|
27
|
-
import "./chunk-YC4EYIER.js";
|
|
28
|
+
import "./chunk-IBTHD2UA.js";
|
|
28
29
|
import "./chunk-RL4VMEXL.js";
|
|
29
|
-
import "./chunk-
|
|
30
|
+
import "./chunk-GAIOIINV.js";
|
|
30
31
|
import "./chunk-HIK6OEUF.js";
|
|
31
32
|
import "./chunk-EBJQ6N4M.js";
|
|
32
33
|
import "./chunk-3WGJMBKH.js";
|
|
@@ -7,13 +7,13 @@ import {
|
|
|
7
7
|
handleGetPerfBaselines,
|
|
8
8
|
handleUpdatePerfBaselines,
|
|
9
9
|
updatePerfBaselinesDefinition
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-CJYNZMOP.js";
|
|
11
11
|
import "./chunk-EPUKTTJZ.js";
|
|
12
12
|
import "./chunk-W6Y7ZW3Y.js";
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
13
|
+
import "./chunk-A4ETL34H.js";
|
|
14
|
+
import "./chunk-IBTHD2UA.js";
|
|
15
15
|
import "./chunk-RL4VMEXL.js";
|
|
16
|
-
import "./chunk-
|
|
16
|
+
import "./chunk-GAIOIINV.js";
|
|
17
17
|
import "./chunk-3WGJMBKH.js";
|
|
18
18
|
import "./chunk-KFQGP6VL.js";
|
|
19
19
|
export {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
handleRunCodeReview,
|
|
3
3
|
runCodeReviewDefinition
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-2FOLD76X.js";
|
|
5
5
|
import "./chunk-W6Y7ZW3Y.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-IBTHD2UA.js";
|
|
7
7
|
import "./chunk-RL4VMEXL.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-GAIOIINV.js";
|
|
9
9
|
import "./chunk-KFQGP6VL.js";
|
|
10
10
|
export {
|
|
11
11
|
handleRunCodeReview,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
generateRuntime
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-EICASBYP.js";
|
|
4
4
|
import "./chunk-KET4QQZB.js";
|
|
5
|
-
import "./chunk-
|
|
5
|
+
import "./chunk-IBTHD2UA.js";
|
|
6
6
|
import "./chunk-RL4VMEXL.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-GAIOIINV.js";
|
|
8
8
|
import "./chunk-KFQGP6VL.js";
|
|
9
9
|
export {
|
|
10
10
|
generateRuntime
|
|
@@ -64,14 +64,24 @@ Your goal is to implement the following issue using the standard Harness Enginee
|
|
|
64
64
|
|
|
65
65
|
## Standard Workflow
|
|
66
66
|
|
|
67
|
-
Follow these steps exactly, using the corresponding slash commands to ensure
|
|
67
|
+
Follow these steps exactly, using the corresponding slash commands to ensure
|
|
68
|
+
high-quality, architecturally sound delivery:
|
|
68
69
|
|
|
69
|
-
1. **Brainstorming:** Use `/harness:brainstorming` to explore the problem space
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
70
|
+
1. **Brainstorming:** Use `/harness:brainstorming` to explore the problem space
|
|
71
|
+
and draft a technical proposal in `docs/changes/`. The spec MUST include an
|
|
72
|
+
Integration Points section defining how the feature connects to the system.
|
|
73
|
+
2. **Planning:** Use `/harness:planning` to create a detailed implementation plan.
|
|
74
|
+
The plan MUST include integration tasks derived from the spec's Integration Points.
|
|
75
|
+
3. **Execution:** Use `/harness:execution` to implement the changes task-by-task,
|
|
76
|
+
including integration tasks (registrations, ADRs, doc updates).
|
|
77
|
+
4. **Verification:** Use `/harness:verification` to ensure the implementation is
|
|
78
|
+
complete, wired correctly, and meets all requirements.
|
|
79
|
+
5. **Integration:** Use `/harness:integration` to verify that system wiring,
|
|
80
|
+
knowledge materialization, and documentation updates are complete per the
|
|
81
|
+
integration tier.
|
|
82
|
+
6. **Code Review:** Use `/harness:code-review` and `/harness:pre-commit-review`
|
|
83
|
+
to perform a final quality check before completing the task.
|
|
84
|
+
7. **Ship:** When the review is clean, you are pre-authorized to ship without asking:
|
|
75
85
|
- Create a topic branch if you are still on `main`/`master` (e.g. `feat/{{ issue.identifier }}`).
|
|
76
86
|
- Stage your changes and create a descriptive commit (Conventional Commits style).
|
|
77
87
|
- Push the branch with `git push -u origin HEAD`.
|
|
@@ -91,6 +101,6 @@ Follow these steps exactly, using the corresponding slash commands to ensure hig
|
|
|
91
101
|
- Always verify your changes with `harness validate`.
|
|
92
102
|
- Adhere to the architectural constraints defined in `harness.config.json`.
|
|
93
103
|
- Document your progress and any learnings in `.harness/learnings.md`.
|
|
94
|
-
- Step
|
|
104
|
+
- Step 7 (Ship) is part of the standard workflow. Do not pause to ask for commit authorization — completing the issue means the PR has been opened.
|
|
95
105
|
|
|
96
106
|
Attempt Number: {{ attempt }}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
handleValidateProject,
|
|
3
3
|
validateToolDefinition
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-Q5DKIL46.js";
|
|
5
|
+
import "./chunk-YZH4I4JO.js";
|
|
6
6
|
import "./chunk-W6Y7ZW3Y.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-IBTHD2UA.js";
|
|
8
8
|
import "./chunk-RL4VMEXL.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-GAIOIINV.js";
|
|
10
10
|
import "./chunk-KFQGP6VL.js";
|
|
11
11
|
export {
|
|
12
12
|
handleValidateProject,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
runCrossCheck
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import "./chunk-
|
|
3
|
+
} from "./chunk-SDPHFDQS.js";
|
|
4
|
+
import "./chunk-IBTHD2UA.js";
|
|
5
5
|
import "./chunk-RL4VMEXL.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-GAIOIINV.js";
|
|
7
7
|
import "./chunk-KFQGP6VL.js";
|
|
8
8
|
export {
|
|
9
9
|
runCrossCheck
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@harness-engineering/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.27.1",
|
|
4
4
|
"description": "CLI for Harness Engineering toolkit",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -37,13 +37,21 @@
|
|
|
37
37
|
"web-tree-sitter": "^0.24.7",
|
|
38
38
|
"yaml": "^2.8.3",
|
|
39
39
|
"zod": "^3.25.76",
|
|
40
|
-
"@harness-engineering/
|
|
41
|
-
"@harness-engineering/
|
|
42
|
-
"@harness-engineering/graph": "0.5.0",
|
|
40
|
+
"@harness-engineering/graph": "0.6.0",
|
|
41
|
+
"@harness-engineering/orchestrator": "0.2.15",
|
|
43
42
|
"@harness-engineering/linter-gen": "0.1.7",
|
|
44
|
-
"@harness-engineering/
|
|
43
|
+
"@harness-engineering/core": "0.23.3",
|
|
44
|
+
"@harness-engineering/dashboard": "0.3.0",
|
|
45
45
|
"@harness-engineering/types": "0.10.1"
|
|
46
46
|
},
|
|
47
|
+
"peerDependencies": {
|
|
48
|
+
"@harness-engineering/intelligence": "0.1.3"
|
|
49
|
+
},
|
|
50
|
+
"peerDependenciesMeta": {
|
|
51
|
+
"@harness-engineering/intelligence": {
|
|
52
|
+
"optional": true
|
|
53
|
+
}
|
|
54
|
+
},
|
|
47
55
|
"devDependencies": {
|
|
48
56
|
"@types/node": "^22.19.15",
|
|
49
57
|
"@types/semver": "^7.7.1",
|
package/dist/hooks/profiles.ts
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Hook profile definitions.
|
|
3
|
-
*
|
|
4
|
-
* Profiles are additive: each higher tier includes all hooks from lower tiers.
|
|
5
|
-
* - minimal: safety floor (block-no-verify only)
|
|
6
|
-
* - standard: + protect-config, quality-gate, pre-compact-state (default)
|
|
7
|
-
* - strict: + cost-tracker, sentinel-pre, sentinel-post
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
export type HookProfile = 'minimal' | 'standard' | 'strict';
|
|
11
|
-
|
|
12
|
-
export interface HookScript {
|
|
13
|
-
/** Script filename without .js extension */
|
|
14
|
-
name: string;
|
|
15
|
-
/** Claude Code hook event */
|
|
16
|
-
event: 'PreToolUse' | 'PostToolUse' | 'PreCompact' | 'Stop';
|
|
17
|
-
/** Tool matcher pattern */
|
|
18
|
-
matcher: string;
|
|
19
|
-
/** Minimum profile tier that includes this hook */
|
|
20
|
-
minProfile: HookProfile;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export const HOOK_SCRIPTS: HookScript[] = [
|
|
24
|
-
{ name: 'block-no-verify', event: 'PreToolUse', matcher: 'Bash', minProfile: 'minimal' },
|
|
25
|
-
{ name: 'protect-config', event: 'PreToolUse', matcher: 'Write|Edit', minProfile: 'standard' },
|
|
26
|
-
{ name: 'quality-gate', event: 'PostToolUse', matcher: 'Edit|Write', minProfile: 'standard' },
|
|
27
|
-
{ name: 'pre-compact-state', event: 'PreCompact', matcher: '*', minProfile: 'standard' },
|
|
28
|
-
{ name: 'adoption-tracker', event: 'Stop', matcher: '*', minProfile: 'standard' },
|
|
29
|
-
{ name: 'telemetry-reporter', event: 'Stop', matcher: '*', minProfile: 'standard' },
|
|
30
|
-
{ name: 'cost-tracker', event: 'Stop', matcher: '*', minProfile: 'strict' },
|
|
31
|
-
{ name: 'sentinel-pre', event: 'PreToolUse', matcher: '*', minProfile: 'strict' },
|
|
32
|
-
{ name: 'sentinel-post', event: 'PostToolUse', matcher: '*', minProfile: 'strict' },
|
|
33
|
-
];
|
|
34
|
-
|
|
35
|
-
const PROFILE_ORDER: HookProfile[] = ['minimal', 'standard', 'strict'];
|
|
36
|
-
|
|
37
|
-
function hooksForProfile(profile: HookProfile): string[] {
|
|
38
|
-
const profileIndex = PROFILE_ORDER.indexOf(profile);
|
|
39
|
-
return HOOK_SCRIPTS.filter((h) => PROFILE_ORDER.indexOf(h.minProfile) <= profileIndex).map(
|
|
40
|
-
(h) => h.name
|
|
41
|
-
);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export const PROFILES: Record<HookProfile, string[]> = {
|
|
45
|
-
minimal: hooksForProfile('minimal'),
|
|
46
|
-
standard: hooksForProfile('standard'),
|
|
47
|
-
strict: hooksForProfile('strict'),
|
|
48
|
-
};
|