jfl 0.2.3 → 0.2.5

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.
Files changed (128) hide show
  1. package/README.md +399 -423
  2. package/dist/commands/agent.d.ts +7 -0
  3. package/dist/commands/agent.d.ts.map +1 -0
  4. package/dist/commands/agent.js +170 -0
  5. package/dist/commands/agent.js.map +1 -0
  6. package/dist/commands/context-hub.d.ts.map +1 -1
  7. package/dist/commands/context-hub.js +134 -2
  8. package/dist/commands/context-hub.js.map +1 -1
  9. package/dist/commands/digest.d.ts +6 -0
  10. package/dist/commands/digest.d.ts.map +1 -0
  11. package/dist/commands/digest.js +126 -0
  12. package/dist/commands/digest.js.map +1 -0
  13. package/dist/commands/doctor.d.ts +7 -0
  14. package/dist/commands/doctor.d.ts.map +1 -0
  15. package/dist/commands/doctor.js +236 -0
  16. package/dist/commands/doctor.js.map +1 -0
  17. package/dist/commands/flows.d.ts +7 -0
  18. package/dist/commands/flows.d.ts.map +1 -0
  19. package/dist/commands/flows.js +264 -0
  20. package/dist/commands/flows.js.map +1 -0
  21. package/dist/commands/hooks.d.ts +13 -0
  22. package/dist/commands/hooks.d.ts.map +1 -0
  23. package/dist/commands/hooks.js +304 -0
  24. package/dist/commands/hooks.js.map +1 -0
  25. package/dist/commands/improve.d.ts +11 -0
  26. package/dist/commands/improve.d.ts.map +1 -0
  27. package/dist/commands/improve.js +77 -0
  28. package/dist/commands/improve.js.map +1 -0
  29. package/dist/commands/scope.d.ts +7 -0
  30. package/dist/commands/scope.d.ts.map +1 -0
  31. package/dist/commands/scope.js +227 -0
  32. package/dist/commands/scope.js.map +1 -0
  33. package/dist/commands/service-validate.js +7 -1
  34. package/dist/commands/service-validate.js.map +1 -1
  35. package/dist/commands/session.d.ts.map +1 -1
  36. package/dist/commands/session.js +23 -0
  37. package/dist/commands/session.js.map +1 -1
  38. package/dist/commands/update.d.ts.map +1 -1
  39. package/dist/commands/update.js +6 -0
  40. package/dist/commands/update.js.map +1 -1
  41. package/dist/index.js +243 -46
  42. package/dist/index.js.map +1 -1
  43. package/dist/lib/agent-manifest.d.ts +35 -0
  44. package/dist/lib/agent-manifest.d.ts.map +1 -0
  45. package/dist/lib/agent-manifest.js +75 -0
  46. package/dist/lib/agent-manifest.js.map +1 -0
  47. package/dist/lib/flow-engine.d.ts +34 -0
  48. package/dist/lib/flow-engine.d.ts.map +1 -0
  49. package/dist/lib/flow-engine.js +366 -0
  50. package/dist/lib/flow-engine.js.map +1 -0
  51. package/dist/lib/hook-transformer.d.ts +11 -0
  52. package/dist/lib/hook-transformer.d.ts.map +1 -0
  53. package/dist/lib/hook-transformer.js +74 -0
  54. package/dist/lib/hook-transformer.js.map +1 -0
  55. package/dist/lib/kuva.d.ts +45 -0
  56. package/dist/lib/kuva.d.ts.map +1 -0
  57. package/dist/lib/kuva.js +131 -0
  58. package/dist/lib/kuva.js.map +1 -0
  59. package/dist/lib/map-event-bus.d.ts +2 -0
  60. package/dist/lib/map-event-bus.d.ts.map +1 -1
  61. package/dist/lib/map-event-bus.js +44 -4
  62. package/dist/lib/map-event-bus.js.map +1 -1
  63. package/dist/lib/memory-indexer.d.ts.map +1 -1
  64. package/dist/lib/memory-indexer.js +26 -2
  65. package/dist/lib/memory-indexer.js.map +1 -1
  66. package/dist/lib/model-pricing.d.ts +11 -0
  67. package/dist/lib/model-pricing.d.ts.map +1 -0
  68. package/dist/lib/model-pricing.js +27 -0
  69. package/dist/lib/model-pricing.js.map +1 -0
  70. package/dist/lib/peter-parker-bridge.d.ts +1 -0
  71. package/dist/lib/peter-parker-bridge.d.ts.map +1 -1
  72. package/dist/lib/peter-parker-bridge.js +29 -0
  73. package/dist/lib/peter-parker-bridge.js.map +1 -1
  74. package/dist/lib/service-gtm.d.ts +7 -0
  75. package/dist/lib/service-gtm.d.ts.map +1 -1
  76. package/dist/lib/service-gtm.js.map +1 -1
  77. package/dist/lib/stratus-client.d.ts +1 -0
  78. package/dist/lib/stratus-client.d.ts.map +1 -1
  79. package/dist/lib/stratus-client.js +33 -2
  80. package/dist/lib/stratus-client.js.map +1 -1
  81. package/dist/lib/stratus-rollout-test.d.ts +10 -0
  82. package/dist/lib/stratus-rollout-test.d.ts.map +1 -0
  83. package/dist/lib/stratus-rollout-test.js +412 -0
  84. package/dist/lib/stratus-rollout-test.js.map +1 -0
  85. package/dist/lib/telemetry-digest.d.ts +10 -0
  86. package/dist/lib/telemetry-digest.d.ts.map +1 -0
  87. package/dist/lib/telemetry-digest.js +359 -0
  88. package/dist/lib/telemetry-digest.js.map +1 -0
  89. package/dist/lib/telemetry.d.ts +35 -0
  90. package/dist/lib/telemetry.d.ts.map +1 -0
  91. package/dist/lib/telemetry.js +320 -0
  92. package/dist/lib/telemetry.js.map +1 -0
  93. package/dist/lib/training-tuples.d.ts +33 -0
  94. package/dist/lib/training-tuples.d.ts.map +1 -0
  95. package/dist/lib/training-tuples.js +273 -0
  96. package/dist/lib/training-tuples.js.map +1 -0
  97. package/dist/mcp/context-hub-mcp.js +17 -0
  98. package/dist/mcp/context-hub-mcp.js.map +1 -1
  99. package/dist/types/flows.d.ts +69 -0
  100. package/dist/types/flows.d.ts.map +1 -0
  101. package/dist/types/flows.js +10 -0
  102. package/dist/types/flows.js.map +1 -0
  103. package/dist/types/map.d.ts +10 -1
  104. package/dist/types/map.d.ts.map +1 -1
  105. package/dist/types/map.js.map +1 -1
  106. package/dist/types/telemetry-digest.d.ts +73 -0
  107. package/dist/types/telemetry-digest.d.ts.map +1 -0
  108. package/dist/types/telemetry-digest.js +5 -0
  109. package/dist/types/telemetry-digest.js.map +1 -0
  110. package/dist/types/telemetry.d.ts +69 -0
  111. package/dist/types/telemetry.d.ts.map +1 -0
  112. package/dist/types/telemetry.js +5 -0
  113. package/dist/types/telemetry.js.map +1 -0
  114. package/dist/utils/jfl-paths.d.ts +1 -0
  115. package/dist/utils/jfl-paths.d.ts.map +1 -1
  116. package/dist/utils/jfl-paths.js +1 -0
  117. package/dist/utils/jfl-paths.js.map +1 -1
  118. package/dist/utils/settings-validator.d.ts +3 -2
  119. package/dist/utils/settings-validator.d.ts.map +1 -1
  120. package/dist/utils/settings-validator.js +25 -6
  121. package/dist/utils/settings-validator.js.map +1 -1
  122. package/package.json +3 -2
  123. package/scripts/session/fix-tracked-logs.sh +97 -0
  124. package/scripts/session/session-cleanup.sh +4 -1
  125. package/scripts/session/session-end.sh +10 -0
  126. package/scripts/session/session-init.sh +16 -0
  127. package/scripts/session/session-sync.sh +10 -0
  128. package/template/scripts/session/session-sync.sh +10 -0
@@ -0,0 +1,304 @@
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 { initHooks };
280
+ export async function hooksCommand(action) {
281
+ switch (action) {
282
+ case "init":
283
+ await initHooks();
284
+ break;
285
+ case "status":
286
+ await statusHooks();
287
+ break;
288
+ case "remove":
289
+ await removeHooks();
290
+ break;
291
+ case "deploy":
292
+ await deployHooks(true);
293
+ break;
294
+ default:
295
+ console.log(chalk.bold("\n jfl hooks - Claude Code HTTP hooks for Context Hub\n"));
296
+ console.log(chalk.gray(" Commands:"));
297
+ console.log(" jfl hooks init Configure HTTP hooks in .claude/settings.json");
298
+ console.log(" jfl hooks status Show configured hooks and hub connectivity");
299
+ console.log(" jfl hooks remove Remove HTTP hooks (preserve shell hooks)");
300
+ console.log(" jfl hooks deploy Deploy hooks to all registered services");
301
+ console.log();
302
+ }
303
+ }
304
+ //# 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":"AAAA;;GAEG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAA;AAS9G,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAuB;IAC1D,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,IAAI,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,CAAA;IAEvD,MAAM,MAAM,GAAG;QACb,GAAG,eAAe,EAAE;QACpB,GAAG,SAAS,CAAC,kBAAkB,EAAE;KAClC,CAAA;IAED,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAC7B,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CACnD,CAAA;IAED,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,2DAA2D,CAAC,CAAC,CAAA;QACpF,OAAM;IACR,CAAC;IAED,MAAM,MAAM,GAAG,aAAa,CAAC,YAAY,EAAE,KAAK,CAAC,CAAA;IACjD,MAAM,WAAW,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAA;IAE/C,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAEzC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,8DAA8D,CAAC,CAAC,CAAA;QACxF,OAAM;IACR,CAAC;IAED,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAA;IAE5F,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,WAAW,CAAC,MAAM,0BAA0B,CAAC,CAAC,CAAA;IAC5E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,UAAU,CAAC,MAAM,gBAAgB,CAAC,CAAC,CAAA;IAEhE,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,MAAM,aAAa,GAAG,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;YAC1E,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;gBAC3D,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAA;QAC/B,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAA;QAC3C,OAAO,CAAC,GAAG,CAAC,KAAK,aAAa,IAAI,SAAS,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,CAAA;QACzD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAA;QAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAA;QACtD,OAAO,CAAC,GAAG,EAAE,CAAA;IACf,CAAC;IAED,MAAM,eAAe,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAA;IACnE,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAA;QAC5C,KAAK,MAAM,CAAC,IAAI,eAAe,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAA;YACzC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,CAAA;QACnD,CAAC;IACH,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,6BAA6B,UAAU,CAAC,MAAM,mBAAmB,CAAC,CAAC,CAAA;QAC1F,OAAM;IACR,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,UAAU,CAAC,MAAM,qBAAqB,CAAC,CAAC,CAAA;QAE7E,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,iBAAiB,CAAC,CAAC,KAAK,EAAE,CAAA;gBACxC,MAAM,IAAI,GAAG;oBACX,aAAa,CAAC,CAAC,IAAI,EAAE;oBACrB,iBAAiB,CAAC,CAAC,QAAQ,EAAE;oBAC7B,EAAE;oBACF,CAAC,CAAC,WAAW;oBACb,EAAE;oBACF,sBAAsB,CAAC,CAAC,YAAY,EAAE;oBACtC,EAAE;oBACF,yCAAyC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,GAAG;iBACrE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBAEZ,MAAM,MAAM,GAAG,QAAQ,CACrB,4BAA4B,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,aAAa,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,8BAA8B,EAC1H,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CACtC,CAAC,IAAI,EAAE,CAAA;gBAER,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,MAAM,EAAE,CAAC,CAAC,CAAA;YAClD,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,OAAO,IAAI,eAAe,CAAA;gBACxD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC,KAAK,MAAM,GAAG,EAAE,CAAC,CAAC,CAAA;YAC7E,CAAC;QACH,CAAC;QACD,OAAO,CAAC,GAAG,EAAE,CAAA;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * jfl scope — View and manage service context scopes
3
+ *
4
+ * @purpose CLI commands to view, set, and test context scope declarations
5
+ */
6
+ export declare function scopeCommand(action?: string, ...args: string[]): Promise<void>;
7
+ //# sourceMappingURL=scope.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../src/commands/scope.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AA8NH,wBAAsB,YAAY,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAgCpF"}
@@ -0,0 +1,227 @@
1
+ /**
2
+ * jfl scope — View and manage service context scopes
3
+ *
4
+ * @purpose CLI commands to view, set, and test context scope declarations
5
+ */
6
+ import chalk from "chalk";
7
+ import * as fs from "fs";
8
+ import * as path from "path";
9
+ function findProjectRoot() {
10
+ let dir = process.cwd();
11
+ while (dir !== path.dirname(dir)) {
12
+ if (fs.existsSync(path.join(dir, ".jfl", "config.json"))) {
13
+ return dir;
14
+ }
15
+ dir = path.dirname(dir);
16
+ }
17
+ return null;
18
+ }
19
+ function loadConfig(root) {
20
+ const configPath = path.join(root, ".jfl", "config.json");
21
+ if (!fs.existsSync(configPath))
22
+ return null;
23
+ try {
24
+ return JSON.parse(fs.readFileSync(configPath, "utf-8"));
25
+ }
26
+ catch {
27
+ return null;
28
+ }
29
+ }
30
+ function saveConfig(root, config) {
31
+ const configPath = path.join(root, ".jfl", "config.json");
32
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
33
+ }
34
+ function formatScope(scope, indent = " ") {
35
+ if (!scope)
36
+ return `${indent}${chalk.dim("(no scope declared — unrestricted)")}`;
37
+ const lines = [];
38
+ if (scope.produces?.length) {
39
+ lines.push(`${indent}${chalk.green("produces:")}`);
40
+ for (const p of scope.produces) {
41
+ lines.push(`${indent} ${chalk.green("+")} ${p}`);
42
+ }
43
+ }
44
+ if (scope.consumes?.length) {
45
+ lines.push(`${indent}${chalk.cyan("consumes:")}`);
46
+ for (const c of scope.consumes) {
47
+ lines.push(`${indent} ${chalk.cyan("←")} ${c}`);
48
+ }
49
+ }
50
+ if (scope.denied?.length) {
51
+ lines.push(`${indent}${chalk.red("denied:")}`);
52
+ for (const d of scope.denied) {
53
+ lines.push(`${indent} ${chalk.red("✗")} ${d}`);
54
+ }
55
+ }
56
+ return lines.length > 0 ? lines.join("\n") : `${indent}${chalk.dim("(empty scope)")}`;
57
+ }
58
+ async function listScopes() {
59
+ const root = findProjectRoot();
60
+ if (!root) {
61
+ console.log(chalk.red("Not in a JFL project"));
62
+ return;
63
+ }
64
+ const config = loadConfig(root);
65
+ if (!config) {
66
+ console.log(chalk.red("No .jfl/config.json found"));
67
+ return;
68
+ }
69
+ console.log(chalk.bold("\nContext Scopes"));
70
+ console.log(chalk.dim("─".repeat(50)));
71
+ // Show this workspace's scope
72
+ console.log(`\n${chalk.bold(config.name || "this workspace")} ${chalk.dim(`(${config.type})`)}`);
73
+ console.log(formatScope(config.context_scope));
74
+ // Show registered services' scopes
75
+ const services = config.registered_services || [];
76
+ if (services.length === 0) {
77
+ console.log(chalk.dim("\nNo registered services"));
78
+ return;
79
+ }
80
+ for (const svc of services) {
81
+ const status = svc.status === "active" ? chalk.green("active") : chalk.dim("inactive");
82
+ console.log(`\n${chalk.bold(svc.name)} ${chalk.dim("—")} ${status}`);
83
+ // Check the service's own config for scope
84
+ const svcConfigPath = path.join(svc.path, ".jfl", "config.json");
85
+ let svcScope = svc.context_scope;
86
+ if (!svcScope && fs.existsSync(svcConfigPath)) {
87
+ try {
88
+ const svcConfig = JSON.parse(fs.readFileSync(svcConfigPath, "utf-8"));
89
+ svcScope = svcConfig.context_scope;
90
+ }
91
+ catch {
92
+ // skip
93
+ }
94
+ }
95
+ console.log(formatScope(svcScope));
96
+ }
97
+ console.log();
98
+ }
99
+ async function setScope(serviceName, scopeType, patterns) {
100
+ const root = findProjectRoot();
101
+ if (!root) {
102
+ console.log(chalk.red("Not in a JFL project"));
103
+ return;
104
+ }
105
+ const config = loadConfig(root);
106
+ if (!config) {
107
+ console.log(chalk.red("No .jfl/config.json found"));
108
+ return;
109
+ }
110
+ if (!["produces", "consumes", "denied"].includes(scopeType)) {
111
+ console.log(chalk.red(`Invalid scope type: ${scopeType}. Must be: produces, consumes, denied`));
112
+ return;
113
+ }
114
+ // Find the service
115
+ if (serviceName === "self" || serviceName === config.name) {
116
+ if (!config.context_scope)
117
+ config.context_scope = {};
118
+ config.context_scope[scopeType] = patterns;
119
+ saveConfig(root, config);
120
+ console.log(chalk.green(`Updated ${config.name || "workspace"} scope.${scopeType}`));
121
+ return;
122
+ }
123
+ const services = config.registered_services || [];
124
+ const svc = services.find(s => s.name === serviceName);
125
+ if (!svc) {
126
+ console.log(chalk.red(`Service "${serviceName}" not found. Available: ${services.map(s => s.name).join(", ")}`));
127
+ return;
128
+ }
129
+ if (!svc.context_scope)
130
+ svc.context_scope = {};
131
+ svc.context_scope[scopeType] = patterns;
132
+ saveConfig(root, config);
133
+ // Also update the service's own config if it exists
134
+ const svcConfigPath = path.join(svc.path, ".jfl", "config.json");
135
+ if (fs.existsSync(svcConfigPath)) {
136
+ try {
137
+ const svcConfig = JSON.parse(fs.readFileSync(svcConfigPath, "utf-8"));
138
+ if (!svcConfig.context_scope)
139
+ svcConfig.context_scope = {};
140
+ svcConfig.context_scope[scopeType] = patterns;
141
+ fs.writeFileSync(svcConfigPath, JSON.stringify(svcConfig, null, 2) + "\n");
142
+ }
143
+ catch {
144
+ // non-fatal
145
+ }
146
+ }
147
+ console.log(chalk.green(`Updated ${serviceName} scope.${scopeType}: [${patterns.join(", ")}]`));
148
+ }
149
+ async function testScope(serviceName, eventType, eventSource) {
150
+ const root = findProjectRoot();
151
+ if (!root) {
152
+ console.log(chalk.red("Not in a JFL project"));
153
+ return;
154
+ }
155
+ const config = loadConfig(root);
156
+ if (!config) {
157
+ console.log(chalk.red("No .jfl/config.json found"));
158
+ return;
159
+ }
160
+ const services = config.registered_services || [];
161
+ const svc = services.find(s => s.name === serviceName);
162
+ const scope = svc?.context_scope || (serviceName === "self" ? config.context_scope : undefined);
163
+ if (!scope) {
164
+ console.log(chalk.yellow(`${serviceName}: No scope declared — event would be ${chalk.green("ALLOWED")} (unrestricted)`));
165
+ return;
166
+ }
167
+ // Check denied
168
+ const denied = scope.denied || [];
169
+ for (const pattern of denied) {
170
+ if (matchScopePattern(pattern, eventType) || matchScopePattern(pattern, eventSource)) {
171
+ console.log(chalk.red(`${serviceName}: event "${eventType}" from "${eventSource}" — DENIED by pattern "${pattern}"`));
172
+ return;
173
+ }
174
+ }
175
+ // Check consumes
176
+ const consumes = scope.consumes || [];
177
+ if (consumes.length > 0) {
178
+ const allowed = consumes.some(p => matchScopePattern(p, eventType) || matchScopePattern(p, eventSource));
179
+ if (!allowed) {
180
+ console.log(chalk.red(`${serviceName}: event "${eventType}" from "${eventSource}" — NOT in consumes list`));
181
+ return;
182
+ }
183
+ }
184
+ console.log(chalk.green(`${serviceName}: event "${eventType}" from "${eventSource}" — ALLOWED`));
185
+ }
186
+ function matchScopePattern(pattern, value) {
187
+ if (pattern === "*")
188
+ return true;
189
+ if (pattern === value)
190
+ return true;
191
+ if (pattern.includes("*")) {
192
+ const regex = new RegExp("^" + pattern.replace(/\*/g, ".*") + "$");
193
+ return regex.test(value);
194
+ }
195
+ return false;
196
+ }
197
+ export async function scopeCommand(action, ...args) {
198
+ switch (action) {
199
+ case "list":
200
+ case undefined:
201
+ await listScopes();
202
+ break;
203
+ case "set": {
204
+ const [serviceName, scopeType, ...patterns] = args;
205
+ if (!serviceName || !scopeType || patterns.length === 0) {
206
+ console.log(chalk.yellow("Usage: jfl scope set <service> <produces|consumes|denied> <pattern1> [pattern2] ..."));
207
+ console.log(chalk.dim(' Example: jfl scope set seo-agent denied "team-journals:*" "shadow:*"'));
208
+ return;
209
+ }
210
+ await setScope(serviceName, scopeType, patterns);
211
+ break;
212
+ }
213
+ case "test": {
214
+ const [serviceName, eventType, eventSource] = args;
215
+ if (!serviceName || !eventType) {
216
+ console.log(chalk.yellow("Usage: jfl scope test <service> <event-type> [event-source]"));
217
+ console.log(chalk.dim(' Example: jfl scope test seo-agent journal:entry journal:productrank-lobsters'));
218
+ return;
219
+ }
220
+ await testScope(serviceName, eventType, eventSource || "unknown");
221
+ break;
222
+ }
223
+ default:
224
+ console.log(chalk.yellow("Unknown action. Usage: jfl scope [list|set|test]"));
225
+ }
226
+ }
227
+ //# sourceMappingURL=scope.js.map