jfl 0.2.2 → 0.2.4
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 +399 -423
- package/clawdbot-plugin/clawdbot.plugin.json +12 -1
- package/clawdbot-plugin/index.js +5 -5
- package/clawdbot-plugin/index.ts +5 -5
- package/dist/commands/context-hub.d.ts +4 -0
- package/dist/commands/context-hub.d.ts.map +1 -1
- package/dist/commands/context-hub.js +704 -83
- package/dist/commands/context-hub.js.map +1 -1
- package/dist/commands/digest.d.ts +6 -0
- package/dist/commands/digest.d.ts.map +1 -0
- package/dist/commands/digest.js +81 -0
- package/dist/commands/digest.js.map +1 -0
- package/dist/commands/flows.d.ts +7 -0
- package/dist/commands/flows.d.ts.map +1 -0
- package/dist/commands/flows.js +264 -0
- package/dist/commands/flows.js.map +1 -0
- package/dist/commands/hooks.d.ts +11 -0
- package/dist/commands/hooks.d.ts.map +1 -0
- package/dist/commands/hooks.js +303 -0
- package/dist/commands/hooks.js.map +1 -0
- package/dist/commands/improve.d.ts +11 -0
- package/dist/commands/improve.d.ts.map +1 -0
- package/dist/commands/improve.js +77 -0
- package/dist/commands/improve.js.map +1 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +42 -11
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/peter.d.ts +15 -0
- package/dist/commands/peter.d.ts.map +1 -0
- package/dist/commands/peter.js +198 -0
- package/dist/commands/peter.js.map +1 -0
- package/dist/commands/ralph.d.ts +3 -1
- package/dist/commands/ralph.d.ts.map +1 -1
- package/dist/commands/ralph.js +40 -5
- package/dist/commands/ralph.js.map +1 -1
- package/dist/commands/scope.d.ts +7 -0
- package/dist/commands/scope.d.ts.map +1 -0
- package/dist/commands/scope.js +227 -0
- package/dist/commands/scope.js.map +1 -0
- package/dist/commands/service-validate.js +7 -1
- package/dist/commands/service-validate.js.map +1 -1
- package/dist/commands/session.d.ts +2 -1
- package/dist/commands/session.d.ts.map +1 -1
- package/dist/commands/session.js +519 -49
- package/dist/commands/session.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +25 -6
- package/dist/commands/update.js.map +1 -1
- package/dist/dashboard/components.d.ts +7 -0
- package/dist/dashboard/components.d.ts.map +1 -0
- package/dist/dashboard/components.js +163 -0
- package/dist/dashboard/components.js.map +1 -0
- package/dist/dashboard/index.d.ts +12 -0
- package/dist/dashboard/index.d.ts.map +1 -0
- package/dist/dashboard/index.js +132 -0
- package/dist/dashboard/index.js.map +1 -0
- package/dist/dashboard/pages.d.ts +7 -0
- package/dist/dashboard/pages.d.ts.map +1 -0
- package/dist/dashboard/pages.js +742 -0
- package/dist/dashboard/pages.js.map +1 -0
- package/dist/dashboard/styles.d.ts +7 -0
- package/dist/dashboard/styles.d.ts.map +1 -0
- package/dist/dashboard/styles.js +497 -0
- package/dist/dashboard/styles.js.map +1 -0
- package/dist/index.js +196 -8
- package/dist/index.js.map +1 -1
- package/dist/lib/flow-engine.d.ts +34 -0
- package/dist/lib/flow-engine.d.ts.map +1 -0
- package/dist/lib/flow-engine.js +321 -0
- package/dist/lib/flow-engine.js.map +1 -0
- package/dist/lib/hook-transformer.d.ts +11 -0
- package/dist/lib/hook-transformer.d.ts.map +1 -0
- package/dist/lib/hook-transformer.js +74 -0
- package/dist/lib/hook-transformer.js.map +1 -0
- package/dist/lib/map-event-bus.d.ts +50 -0
- package/dist/lib/map-event-bus.d.ts.map +1 -0
- package/dist/lib/map-event-bus.js +366 -0
- package/dist/lib/map-event-bus.js.map +1 -0
- package/dist/lib/memory-indexer.d.ts.map +1 -1
- package/dist/lib/memory-indexer.js +26 -2
- package/dist/lib/memory-indexer.js.map +1 -1
- package/dist/lib/model-pricing.d.ts +11 -0
- package/dist/lib/model-pricing.d.ts.map +1 -0
- package/dist/lib/model-pricing.js +27 -0
- package/dist/lib/model-pricing.js.map +1 -0
- package/dist/lib/peter-parker-bridge.d.ts +34 -0
- package/dist/lib/peter-parker-bridge.d.ts.map +1 -0
- package/dist/lib/peter-parker-bridge.js +145 -0
- package/dist/lib/peter-parker-bridge.js.map +1 -0
- package/dist/lib/peter-parker-config.d.ts +13 -0
- package/dist/lib/peter-parker-config.d.ts.map +1 -0
- package/dist/lib/peter-parker-config.js +86 -0
- package/dist/lib/peter-parker-config.js.map +1 -0
- package/dist/lib/service-gtm.d.ts +7 -0
- package/dist/lib/service-gtm.d.ts.map +1 -1
- package/dist/lib/service-gtm.js.map +1 -1
- package/dist/lib/service-utils.d.ts.map +1 -1
- package/dist/lib/service-utils.js +33 -17
- package/dist/lib/service-utils.js.map +1 -1
- package/dist/lib/stratus-client.d.ts +1 -0
- package/dist/lib/stratus-client.d.ts.map +1 -1
- package/dist/lib/stratus-client.js +33 -2
- package/dist/lib/stratus-client.js.map +1 -1
- package/dist/lib/stratus-rollout-test.d.ts +10 -0
- package/dist/lib/stratus-rollout-test.d.ts.map +1 -0
- package/dist/lib/stratus-rollout-test.js +412 -0
- package/dist/lib/stratus-rollout-test.js.map +1 -0
- package/dist/lib/telemetry-digest.d.ts +10 -0
- package/dist/lib/telemetry-digest.d.ts.map +1 -0
- package/dist/lib/telemetry-digest.js +359 -0
- package/dist/lib/telemetry-digest.js.map +1 -0
- package/dist/lib/telemetry.d.ts +35 -0
- package/dist/lib/telemetry.d.ts.map +1 -0
- package/dist/lib/telemetry.js +320 -0
- package/dist/lib/telemetry.js.map +1 -0
- package/dist/lib/training-tuples.d.ts +33 -0
- package/dist/lib/training-tuples.d.ts.map +1 -0
- package/dist/lib/training-tuples.js +273 -0
- package/dist/lib/training-tuples.js.map +1 -0
- package/dist/mcp/context-hub-mcp.js +139 -22
- package/dist/mcp/context-hub-mcp.js.map +1 -1
- package/dist/types/flows.d.ts +62 -0
- package/dist/types/flows.d.ts.map +1 -0
- package/dist/types/flows.js +10 -0
- package/dist/types/flows.js.map +1 -0
- package/dist/types/map.d.ts +42 -0
- package/dist/types/map.d.ts.map +1 -0
- package/dist/types/map.js +39 -0
- package/dist/types/map.js.map +1 -0
- package/dist/types/telemetry-digest.d.ts +73 -0
- package/dist/types/telemetry-digest.d.ts.map +1 -0
- package/dist/types/telemetry-digest.js +5 -0
- package/dist/types/telemetry-digest.js.map +1 -0
- package/dist/types/telemetry.d.ts +69 -0
- package/dist/types/telemetry.d.ts.map +1 -0
- package/dist/types/telemetry.js +5 -0
- package/dist/types/telemetry.js.map +1 -0
- package/dist/ui/event-dashboard.d.ts +12 -0
- package/dist/ui/event-dashboard.d.ts.map +1 -0
- package/dist/ui/event-dashboard.js +342 -0
- package/dist/ui/event-dashboard.js.map +1 -0
- package/dist/utils/jfl-paths.d.ts +1 -0
- package/dist/utils/jfl-paths.d.ts.map +1 -1
- package/dist/utils/jfl-paths.js +1 -0
- package/dist/utils/jfl-paths.js.map +1 -1
- package/dist/utils/settings-validator.d.ts +3 -2
- package/dist/utils/settings-validator.d.ts.map +1 -1
- package/dist/utils/settings-validator.js +25 -6
- package/dist/utils/settings-validator.js.map +1 -1
- package/package.json +3 -2
- package/scripts/session/session-end.sh +10 -0
- package/scripts/session/session-init.sh +16 -0
- package/scripts/test-map-eventbus.sh +357 -0
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* jfl hooks - Manage Claude Code HTTP hooks for Context Hub
|
|
3
|
+
*
|
|
4
|
+
* Configures Claude Code to POST hook events to Context Hub's /api/hooks
|
|
5
|
+
* endpoint, bridging tool use, session lifecycle, and subagent events
|
|
6
|
+
* into the MAP event bus.
|
|
7
|
+
*
|
|
8
|
+
* @purpose CLI command to init/status/remove Claude Code HTTP hooks
|
|
9
|
+
*/
|
|
10
|
+
export declare function hooksCommand(action?: string): Promise<void>;
|
|
11
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/commands/hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAmVH,wBAAsB,YAAY,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBjE"}
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* jfl hooks - Manage Claude Code HTTP hooks for Context Hub
|
|
3
|
+
*
|
|
4
|
+
* Configures Claude Code to POST hook events to Context Hub's /api/hooks
|
|
5
|
+
* endpoint, bridging tool use, session lifecycle, and subagent events
|
|
6
|
+
* into the MAP event bus.
|
|
7
|
+
*
|
|
8
|
+
* @purpose CLI command to init/status/remove Claude Code HTTP hooks
|
|
9
|
+
*/
|
|
10
|
+
import chalk from "chalk";
|
|
11
|
+
import * as fs from "fs";
|
|
12
|
+
import * as path from "path";
|
|
13
|
+
import { getProjectPort } from "../utils/context-hub-port.js";
|
|
14
|
+
import { stringify as stringifyYaml } from "yaml";
|
|
15
|
+
const HOOK_EVENTS = ["PostToolUse", "Stop", "PreCompact", "SubagentStart", "SubagentStop"];
|
|
16
|
+
const DEFAULT_FLOWS_YAML = {
|
|
17
|
+
flows: [
|
|
18
|
+
{
|
|
19
|
+
name: "session-activity-log",
|
|
20
|
+
description: "Log tool use activity for session analysis",
|
|
21
|
+
enabled: true,
|
|
22
|
+
trigger: { pattern: "hook:tool-use" },
|
|
23
|
+
actions: [{ type: "log", message: "Tool used: {{data.tool_name}} on {{data.file_paths}}" }],
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: "session-end-summary",
|
|
27
|
+
description: "Emit summary event when session stops",
|
|
28
|
+
enabled: true,
|
|
29
|
+
trigger: { pattern: "hook:stop" },
|
|
30
|
+
actions: [{
|
|
31
|
+
type: "emit",
|
|
32
|
+
event_type: "session:ended",
|
|
33
|
+
data: { source: "flow:session-end-summary", auto_captured: true },
|
|
34
|
+
}],
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
};
|
|
38
|
+
function findProjectRoot() {
|
|
39
|
+
let dir = process.cwd();
|
|
40
|
+
while (dir !== path.dirname(dir)) {
|
|
41
|
+
if (fs.existsSync(path.join(dir, ".jfl", "config.json"))) {
|
|
42
|
+
return dir;
|
|
43
|
+
}
|
|
44
|
+
dir = path.dirname(dir);
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
function resolvePort() {
|
|
49
|
+
const projectRoot = findProjectRoot();
|
|
50
|
+
if (projectRoot) {
|
|
51
|
+
const configPath = path.join(projectRoot, ".jfl", "config.json");
|
|
52
|
+
try {
|
|
53
|
+
const config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
54
|
+
if (config.type === "service" && config.gtm_parent) {
|
|
55
|
+
const parentPort = getProjectPort(config.gtm_parent);
|
|
56
|
+
return parentPort;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch { }
|
|
60
|
+
}
|
|
61
|
+
return getProjectPort(projectRoot || process.cwd());
|
|
62
|
+
}
|
|
63
|
+
function readSettings() {
|
|
64
|
+
const settingsPath = path.join(process.cwd(), ".claude", "settings.json");
|
|
65
|
+
if (!fs.existsSync(settingsPath)) {
|
|
66
|
+
return {};
|
|
67
|
+
}
|
|
68
|
+
return JSON.parse(fs.readFileSync(settingsPath, "utf-8"));
|
|
69
|
+
}
|
|
70
|
+
function writeSettings(settings) {
|
|
71
|
+
const settingsDir = path.join(process.cwd(), ".claude");
|
|
72
|
+
if (!fs.existsSync(settingsDir)) {
|
|
73
|
+
fs.mkdirSync(settingsDir, { recursive: true });
|
|
74
|
+
}
|
|
75
|
+
fs.writeFileSync(path.join(settingsDir, "settings.json"), JSON.stringify(settings, null, 2) + "\n");
|
|
76
|
+
}
|
|
77
|
+
function isHttpHook(cmd) {
|
|
78
|
+
return cmd.type === "http";
|
|
79
|
+
}
|
|
80
|
+
async function initHooks() {
|
|
81
|
+
const port = resolvePort();
|
|
82
|
+
const hookUrl = `http://localhost:${port}/api/hooks`;
|
|
83
|
+
const settings = readSettings();
|
|
84
|
+
if (!settings.hooks) {
|
|
85
|
+
settings.hooks = {};
|
|
86
|
+
}
|
|
87
|
+
let added = 0;
|
|
88
|
+
for (const eventName of HOOK_EVENTS) {
|
|
89
|
+
if (!settings.hooks[eventName]) {
|
|
90
|
+
settings.hooks[eventName] = [];
|
|
91
|
+
}
|
|
92
|
+
const entries = settings.hooks[eventName];
|
|
93
|
+
const alreadyHasHttp = entries.some((entry) => entry.hooks?.some((h) => isHttpHook(h) && h.url?.includes("/api/hooks")));
|
|
94
|
+
if (alreadyHasHttp) {
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
entries.push({
|
|
98
|
+
matcher: "",
|
|
99
|
+
hooks: [{ type: "http", url: hookUrl }],
|
|
100
|
+
});
|
|
101
|
+
added++;
|
|
102
|
+
}
|
|
103
|
+
writeSettings(settings);
|
|
104
|
+
if (added > 0) {
|
|
105
|
+
console.log(chalk.green(`\n HTTP hooks configured for ${added} events → ${hookUrl}\n`));
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
console.log(chalk.yellow(`\n HTTP hooks already configured → ${hookUrl}\n`));
|
|
109
|
+
}
|
|
110
|
+
console.log(chalk.gray(" Events:"));
|
|
111
|
+
for (const eventName of HOOK_EVENTS) {
|
|
112
|
+
console.log(chalk.gray(` ${eventName}`));
|
|
113
|
+
}
|
|
114
|
+
console.log();
|
|
115
|
+
const flowsPath = path.join(process.cwd(), ".jfl", "flows.yaml");
|
|
116
|
+
if (!fs.existsSync(flowsPath)) {
|
|
117
|
+
const jflDir = path.join(process.cwd(), ".jfl");
|
|
118
|
+
if (!fs.existsSync(jflDir)) {
|
|
119
|
+
fs.mkdirSync(jflDir, { recursive: true });
|
|
120
|
+
}
|
|
121
|
+
fs.writeFileSync(flowsPath, stringifyYaml(DEFAULT_FLOWS_YAML, { lineWidth: 120 }));
|
|
122
|
+
console.log(chalk.green(" Default flows created → .jfl/flows.yaml"));
|
|
123
|
+
console.log(chalk.gray(" Run: jfl flows list"));
|
|
124
|
+
console.log();
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async function statusHooks() {
|
|
128
|
+
const port = resolvePort();
|
|
129
|
+
const hookUrl = `http://localhost:${port}/api/hooks`;
|
|
130
|
+
const settings = readSettings();
|
|
131
|
+
console.log(chalk.bold("\n Claude Code HTTP Hooks\n"));
|
|
132
|
+
console.log(chalk.gray(" Target: ") + chalk.cyan(hookUrl));
|
|
133
|
+
if (!settings.hooks) {
|
|
134
|
+
console.log(chalk.yellow("\n No hooks configured.\n"));
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
let httpCount = 0;
|
|
138
|
+
for (const [eventName, entries] of Object.entries(settings.hooks)) {
|
|
139
|
+
for (const entry of entries) {
|
|
140
|
+
for (const cmd of entry.hooks || []) {
|
|
141
|
+
if (isHttpHook(cmd)) {
|
|
142
|
+
console.log(chalk.green(" ✓ ") + chalk.bold(eventName) + chalk.gray(` → ${cmd.url}`));
|
|
143
|
+
httpCount++;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (httpCount === 0) {
|
|
149
|
+
console.log(chalk.yellow(" No HTTP hooks found."));
|
|
150
|
+
console.log(chalk.gray(" Run: jfl hooks init"));
|
|
151
|
+
}
|
|
152
|
+
console.log();
|
|
153
|
+
try {
|
|
154
|
+
const response = await fetch(`http://localhost:${port}/health`, {
|
|
155
|
+
signal: AbortSignal.timeout(2000),
|
|
156
|
+
});
|
|
157
|
+
if (response.ok) {
|
|
158
|
+
console.log(chalk.green(" Context Hub: running") + chalk.gray(` (port ${port})`));
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
console.log(chalk.red(" Context Hub: not responding"));
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
console.log(chalk.red(" Context Hub: not running"));
|
|
166
|
+
console.log(chalk.gray(" Run: jfl context-hub start"));
|
|
167
|
+
}
|
|
168
|
+
console.log();
|
|
169
|
+
}
|
|
170
|
+
async function removeHooks() {
|
|
171
|
+
const settings = readSettings();
|
|
172
|
+
if (!settings.hooks) {
|
|
173
|
+
console.log(chalk.yellow("\n No hooks configured.\n"));
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
let removed = 0;
|
|
177
|
+
for (const [eventName, entries] of Object.entries(settings.hooks)) {
|
|
178
|
+
const filtered = entries.map((entry) => {
|
|
179
|
+
const originalLen = entry.hooks?.length || 0;
|
|
180
|
+
const kept = (entry.hooks || []).filter((cmd) => !isHttpHook(cmd));
|
|
181
|
+
removed += originalLen - kept.length;
|
|
182
|
+
return { ...entry, hooks: kept };
|
|
183
|
+
}).filter((entry) => entry.hooks.length > 0);
|
|
184
|
+
if (filtered.length > 0) {
|
|
185
|
+
settings.hooks[eventName] = filtered;
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
delete settings.hooks[eventName];
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
writeSettings(settings);
|
|
192
|
+
if (removed > 0) {
|
|
193
|
+
console.log(chalk.green(`\n Removed ${removed} HTTP hook(s). Shell hooks preserved.\n`));
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
console.log(chalk.yellow("\n No HTTP hooks found to remove.\n"));
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
async function deployHooks(all) {
|
|
200
|
+
const projectRoot = findProjectRoot();
|
|
201
|
+
if (!projectRoot) {
|
|
202
|
+
console.log(chalk.red("\n Not in a JFL project. Run from a directory with .jfl/config.json\n"));
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
const configPath = path.join(projectRoot, ".jfl", "config.json");
|
|
206
|
+
let config;
|
|
207
|
+
try {
|
|
208
|
+
config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
console.log(chalk.red("\n Failed to read .jfl/config.json\n"));
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
const services = config.registered_services || [];
|
|
215
|
+
if (services.length === 0) {
|
|
216
|
+
console.log(chalk.yellow("\n No registered services found in .jfl/config.json"));
|
|
217
|
+
console.log(chalk.gray(" Register services with: jfl services register <path>\n"));
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
console.log(chalk.bold(`\n Deploying hooks to ${services.length} service(s)\n`));
|
|
221
|
+
let success = 0;
|
|
222
|
+
let skipped = 0;
|
|
223
|
+
let failed = 0;
|
|
224
|
+
for (const service of services) {
|
|
225
|
+
const servicePath = path.isAbsolute(service.path)
|
|
226
|
+
? service.path
|
|
227
|
+
: path.resolve(projectRoot, service.path);
|
|
228
|
+
const serviceName = service.name || path.basename(servicePath);
|
|
229
|
+
if (!fs.existsSync(servicePath)) {
|
|
230
|
+
console.log(chalk.red(` ✗ ${serviceName} — directory not found: ${servicePath}`));
|
|
231
|
+
failed++;
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
const settingsDir = path.join(servicePath, ".claude");
|
|
235
|
+
const settingsPath = path.join(settingsDir, "settings.json");
|
|
236
|
+
let settings = {};
|
|
237
|
+
if (fs.existsSync(settingsPath)) {
|
|
238
|
+
try {
|
|
239
|
+
settings = JSON.parse(fs.readFileSync(settingsPath, "utf-8"));
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
settings = {};
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
if (!settings.hooks) {
|
|
246
|
+
settings.hooks = {};
|
|
247
|
+
}
|
|
248
|
+
const port = getProjectPort(projectRoot);
|
|
249
|
+
const hookUrl = `http://localhost:${port}/api/hooks`;
|
|
250
|
+
let added = 0;
|
|
251
|
+
for (const eventName of HOOK_EVENTS) {
|
|
252
|
+
if (!settings.hooks[eventName]) {
|
|
253
|
+
settings.hooks[eventName] = [];
|
|
254
|
+
}
|
|
255
|
+
const entries = settings.hooks[eventName];
|
|
256
|
+
const alreadyHasHttp = entries.some((entry) => entry.hooks?.some((h) => h.type === "http" && h.url?.includes("/api/hooks")));
|
|
257
|
+
if (alreadyHasHttp)
|
|
258
|
+
continue;
|
|
259
|
+
entries.push({
|
|
260
|
+
matcher: "",
|
|
261
|
+
hooks: [{ type: "http", url: hookUrl }],
|
|
262
|
+
});
|
|
263
|
+
added++;
|
|
264
|
+
}
|
|
265
|
+
if (added === 0) {
|
|
266
|
+
console.log(chalk.gray(` - ${serviceName} — hooks already configured`));
|
|
267
|
+
skipped++;
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
270
|
+
if (!fs.existsSync(settingsDir)) {
|
|
271
|
+
fs.mkdirSync(settingsDir, { recursive: true });
|
|
272
|
+
}
|
|
273
|
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
|
|
274
|
+
console.log(chalk.green(` ✓ ${serviceName} — ${added} hook events → ${hookUrl}`));
|
|
275
|
+
success++;
|
|
276
|
+
}
|
|
277
|
+
console.log(chalk.bold(`\n Done: ${success} configured, ${skipped} already set, ${failed} failed\n`));
|
|
278
|
+
}
|
|
279
|
+
export async function hooksCommand(action) {
|
|
280
|
+
switch (action) {
|
|
281
|
+
case "init":
|
|
282
|
+
await initHooks();
|
|
283
|
+
break;
|
|
284
|
+
case "status":
|
|
285
|
+
await statusHooks();
|
|
286
|
+
break;
|
|
287
|
+
case "remove":
|
|
288
|
+
await removeHooks();
|
|
289
|
+
break;
|
|
290
|
+
case "deploy":
|
|
291
|
+
await deployHooks(true);
|
|
292
|
+
break;
|
|
293
|
+
default:
|
|
294
|
+
console.log(chalk.bold("\n jfl hooks - Claude Code HTTP hooks for Context Hub\n"));
|
|
295
|
+
console.log(chalk.gray(" Commands:"));
|
|
296
|
+
console.log(" jfl hooks init Configure HTTP hooks in .claude/settings.json");
|
|
297
|
+
console.log(" jfl hooks status Show configured hooks and hub connectivity");
|
|
298
|
+
console.log(" jfl hooks remove Remove HTTP hooks (preserve shell hooks)");
|
|
299
|
+
console.log(" jfl hooks deploy Deploy hooks to all registered services");
|
|
300
|
+
console.log();
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/commands/hooks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @purpose Self-improvement loop: analyze telemetry, generate suggestions, optionally create GitHub issues
|
|
3
|
+
*/
|
|
4
|
+
interface ImproveOptions {
|
|
5
|
+
dryRun?: boolean;
|
|
6
|
+
auto?: boolean;
|
|
7
|
+
hours?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function improveCommand(options: ImproveOptions): Promise<void>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=improve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"improve.d.ts","sourceRoot":"","sources":["../../src/commands/improve.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,UAAU,cAAc;IACtB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAuF3E"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @purpose Self-improvement loop: analyze telemetry, generate suggestions, optionally create GitHub issues
|
|
3
|
+
*/
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { execSync } from 'child_process';
|
|
6
|
+
import { telemetry } from '../lib/telemetry.js';
|
|
7
|
+
import { loadLocalEvents, analyzeEvents, generateSuggestions, formatDigest } from '../lib/telemetry-digest.js';
|
|
8
|
+
export async function improveCommand(options) {
|
|
9
|
+
const hours = parseInt(options.hours || '24', 10) || 24;
|
|
10
|
+
const events = [
|
|
11
|
+
...loadLocalEvents(),
|
|
12
|
+
...telemetry.getSpilloverEvents(),
|
|
13
|
+
];
|
|
14
|
+
const uniqueEvents = Array.from(new Map(events.map(e => [e.event_id, e])).values());
|
|
15
|
+
if (uniqueEvents.length === 0) {
|
|
16
|
+
console.log(chalk.gray('\n No telemetry events found. Run some commands first.\n'));
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const digest = analyzeEvents(uniqueEvents, hours);
|
|
20
|
+
const suggestions = generateSuggestions(digest);
|
|
21
|
+
console.log(formatDigest(digest, 'text'));
|
|
22
|
+
if (suggestions.length === 0) {
|
|
23
|
+
console.log(chalk.green('\n No improvement suggestions — everything looks healthy.\n'));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const actionable = suggestions.filter(s => s.severity === 'high' || s.severity === 'medium');
|
|
27
|
+
console.log(chalk.bold(`\n ${suggestions.length} Improvement Suggestions`));
|
|
28
|
+
console.log(chalk.gray(` (${actionable.length} actionable)\n`));
|
|
29
|
+
for (const s of suggestions) {
|
|
30
|
+
const severityLabel = s.severity === 'high' ? chalk.red(`[${s.severity}]`) :
|
|
31
|
+
s.severity === 'medium' ? chalk.yellow(`[${s.severity}]`) :
|
|
32
|
+
chalk.gray(`[${s.severity}]`);
|
|
33
|
+
const typeLabel = chalk.cyan(`[${s.type}]`);
|
|
34
|
+
console.log(` ${severityLabel} ${typeLabel} ${s.title}`);
|
|
35
|
+
console.log(chalk.gray(` ${s.description}`));
|
|
36
|
+
console.log(chalk.white(` Fix: ${s.suggestedFix}`));
|
|
37
|
+
console.log();
|
|
38
|
+
}
|
|
39
|
+
const hookSuggestions = suggestions.filter(s => s.type === 'usage');
|
|
40
|
+
if (hookSuggestions.length > 0) {
|
|
41
|
+
console.log(chalk.bold(`\n Hook Insights`));
|
|
42
|
+
for (const s of hookSuggestions) {
|
|
43
|
+
console.log(chalk.cyan(` ${s.title}`));
|
|
44
|
+
console.log(chalk.gray(` ${s.description}\n`));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (options.dryRun) {
|
|
48
|
+
console.log(chalk.gray(` --dry-run: Would create ${actionable.length} GitHub issues.\n`));
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (options.auto && actionable.length > 0) {
|
|
52
|
+
console.log(chalk.bold(` Creating ${actionable.length} GitHub issues...\n`));
|
|
53
|
+
for (const s of actionable) {
|
|
54
|
+
try {
|
|
55
|
+
const title = `[jfl-improve] ${s.title}`;
|
|
56
|
+
const body = [
|
|
57
|
+
`**Type:** ${s.type}`,
|
|
58
|
+
`**Severity:** ${s.severity}`,
|
|
59
|
+
'',
|
|
60
|
+
s.description,
|
|
61
|
+
'',
|
|
62
|
+
`**Suggested Fix:** ${s.suggestedFix}`,
|
|
63
|
+
'',
|
|
64
|
+
`_Auto-generated by \`jfl improve\` at ${new Date().toISOString()}_`,
|
|
65
|
+
].join('\n');
|
|
66
|
+
const result = execSync(`gh issue create --title "${title.replace(/"/g, '\\"')}" --body "${body.replace(/"/g, '\\"')}" --label "jfl-improve" 2>&1`, { encoding: 'utf-8', timeout: 15000 }).trim();
|
|
67
|
+
console.log(chalk.green(` Created: ${result}`));
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
const msg = err.stderr || err.message || 'Unknown error';
|
|
71
|
+
console.log(chalk.red(` Failed to create issue for "${s.title}": ${msg}`));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
console.log();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=improve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"improve.js","sourceRoot":"","sources":["../../src/commands/improve.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAoBA,wBAAsB,WAAW,CAAC,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,iBAs3B5D"}
|
package/dist/commands/init.js
CHANGED
|
@@ -3,7 +3,7 @@ import ora from "ora";
|
|
|
3
3
|
import * as p from "@clack/prompts";
|
|
4
4
|
import { execSync, spawn } from "child_process";
|
|
5
5
|
import { existsSync, mkdirSync, writeFileSync, rmSync, readFileSync } from "fs";
|
|
6
|
-
import { join } from "path";
|
|
6
|
+
import { join, basename } from "path";
|
|
7
7
|
import { tmpdir } from "os";
|
|
8
8
|
import { isAuthenticated, getUser, getAuthMethod, getX402Address } from "./login.js";
|
|
9
9
|
import { extractServiceMetadata } from "../lib/service-detector.js";
|
|
@@ -13,6 +13,7 @@ import { getProfile } from "./profile.js";
|
|
|
13
13
|
import { generateClaudeMdFromProfile } from "../utils/claude-md-generator.js";
|
|
14
14
|
import { validateSettings, fixSettings } from "../utils/settings-validator.js";
|
|
15
15
|
import { persistProjectPort } from "../utils/context-hub-port.js";
|
|
16
|
+
import { ensureDaemonInstalled } from "./context-hub.js";
|
|
16
17
|
const TEMPLATE_REPO = "https://github.com/402goose/jfl-template.git";
|
|
17
18
|
export async function initCommand(options) {
|
|
18
19
|
// Start Clawdbot-style flow
|
|
@@ -66,11 +67,19 @@ export async function initCommand(options) {
|
|
|
66
67
|
}
|
|
67
68
|
projectName = name;
|
|
68
69
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
// If cwd already matches the project name, initialize in place
|
|
71
|
+
const cwdBasename = basename(process.cwd());
|
|
72
|
+
const initInPlace = cwdBasename === projectName;
|
|
73
|
+
const projectPath = initInPlace ? process.cwd() : join(process.cwd(), projectName);
|
|
74
|
+
if (!initInPlace) {
|
|
75
|
+
// Check if directory exists (only when creating a new subdirectory)
|
|
76
|
+
if (existsSync(projectPath)) {
|
|
77
|
+
console.log(chalk.red(`\nDirectory ${projectName} already exists.`));
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
p.log.info(`Initializing in current directory (matches project name: ${projectName})`);
|
|
74
83
|
}
|
|
75
84
|
// Pre-flight check: is git installed?
|
|
76
85
|
try {
|
|
@@ -122,13 +131,25 @@ export async function initCommand(options) {
|
|
|
122
131
|
}
|
|
123
132
|
// Clean up temp directory
|
|
124
133
|
rmSync(tempDir, { recursive: true, force: true });
|
|
125
|
-
// Remove template's .git if it was copied (we want a fresh repo)
|
|
134
|
+
// Remove template's .git if it was copied (we want a fresh repo or to keep existing)
|
|
126
135
|
const templateGit = join(projectPath, ".git");
|
|
127
|
-
if (
|
|
128
|
-
|
|
136
|
+
if (initInPlace) {
|
|
137
|
+
// In-place init: template .git would overwrite existing — but cp -r shouldn't
|
|
138
|
+
// copy .git over an existing .git. Just ensure we don't have a stale one.
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
if (existsSync(templateGit)) {
|
|
142
|
+
rmSync(templateGit, { recursive: true, force: true });
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// Initialize git repo if not already one
|
|
146
|
+
try {
|
|
147
|
+
execSync(`git rev-parse --git-dir`, { cwd: projectPath, stdio: "pipe" });
|
|
148
|
+
// Already a git repo — skip init
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
execSync(`git init`, { cwd: projectPath, stdio: "pipe" });
|
|
129
152
|
}
|
|
130
|
-
// Initialize new git repo
|
|
131
|
-
execSync(`git init`, { cwd: projectPath, stdio: "pipe" });
|
|
132
153
|
spinner.succeed("GTM workspace created!");
|
|
133
154
|
// Validate and fix .claude/settings.json
|
|
134
155
|
const settingsPath = join(projectPath, ".claude", "settings.json");
|
|
@@ -350,6 +371,16 @@ export async function initCommand(options) {
|
|
|
350
371
|
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
351
372
|
// Assign deterministic port and write to config + .mcp.json
|
|
352
373
|
const hubPort = persistProjectPort(projectPath);
|
|
374
|
+
// Start Context Hub for the new project
|
|
375
|
+
try {
|
|
376
|
+
const { contextHubCommand: chCmd } = await import("./context-hub.js");
|
|
377
|
+
await chCmd("ensure", { port: hubPort });
|
|
378
|
+
}
|
|
379
|
+
catch {
|
|
380
|
+
// Non-blocking — hub can be started manually later
|
|
381
|
+
}
|
|
382
|
+
// Auto-install daemon (fire-and-forget, silent)
|
|
383
|
+
ensureDaemonInstalled({ quiet: true }).catch(() => { });
|
|
353
384
|
// Generate or update CLAUDE.md
|
|
354
385
|
const claudePath = join(projectPath, "CLAUDE.md");
|
|
355
386
|
const profile = getProfile();
|