jfl 0.1.0 → 0.2.0

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 (262) hide show
  1. package/README.md +443 -145
  2. package/clawdbot-plugin/clawdbot.plugin.json +20 -0
  3. package/clawdbot-plugin/index.js +555 -0
  4. package/clawdbot-plugin/index.ts +582 -0
  5. package/clawdbot-skill/SKILL.md +33 -336
  6. package/clawdbot-skill/index.ts +491 -321
  7. package/clawdbot-skill/skill.json +4 -13
  8. package/dist/commands/clawdbot.d.ts +11 -0
  9. package/dist/commands/clawdbot.d.ts.map +1 -0
  10. package/dist/commands/clawdbot.js +215 -0
  11. package/dist/commands/clawdbot.js.map +1 -0
  12. package/dist/commands/context-hub.d.ts +5 -0
  13. package/dist/commands/context-hub.d.ts.map +1 -1
  14. package/dist/commands/context-hub.js +394 -28
  15. package/dist/commands/context-hub.js.map +1 -1
  16. package/dist/commands/gtm-process-update.d.ts +10 -0
  17. package/dist/commands/gtm-process-update.d.ts.map +1 -0
  18. package/dist/commands/gtm-process-update.js +101 -0
  19. package/dist/commands/gtm-process-update.js.map +1 -0
  20. package/dist/commands/init.d.ts.map +1 -1
  21. package/dist/commands/init.js +278 -4
  22. package/dist/commands/init.js.map +1 -1
  23. package/dist/commands/login.d.ts.map +1 -1
  24. package/dist/commands/login.js +32 -33
  25. package/dist/commands/login.js.map +1 -1
  26. package/dist/commands/memory.d.ts +38 -0
  27. package/dist/commands/memory.d.ts.map +1 -0
  28. package/dist/commands/memory.js +229 -0
  29. package/dist/commands/memory.js.map +1 -0
  30. package/dist/commands/migrate-services.d.ts +8 -0
  31. package/dist/commands/migrate-services.d.ts.map +1 -0
  32. package/dist/commands/migrate-services.js +182 -0
  33. package/dist/commands/migrate-services.js.map +1 -0
  34. package/dist/commands/onboard.d.ts +24 -0
  35. package/dist/commands/onboard.d.ts.map +1 -0
  36. package/dist/commands/onboard.js +663 -0
  37. package/dist/commands/onboard.js.map +1 -0
  38. package/dist/commands/openclaw.d.ts +56 -0
  39. package/dist/commands/openclaw.d.ts.map +1 -0
  40. package/dist/commands/openclaw.js +700 -0
  41. package/dist/commands/openclaw.js.map +1 -0
  42. package/dist/commands/orchestrate.d.ts +14 -0
  43. package/dist/commands/orchestrate.d.ts.map +1 -0
  44. package/dist/commands/orchestrate.js +270 -0
  45. package/dist/commands/orchestrate.js.map +1 -0
  46. package/dist/commands/profile.d.ts +46 -0
  47. package/dist/commands/profile.d.ts.map +1 -0
  48. package/dist/commands/profile.js +498 -0
  49. package/dist/commands/profile.js.map +1 -0
  50. package/dist/commands/repair.d.ts.map +1 -1
  51. package/dist/commands/repair.js +37 -0
  52. package/dist/commands/repair.js.map +1 -1
  53. package/dist/commands/service-agent.d.ts +16 -0
  54. package/dist/commands/service-agent.d.ts.map +1 -0
  55. package/dist/commands/service-agent.js +375 -0
  56. package/dist/commands/service-agent.js.map +1 -0
  57. package/dist/commands/service-manager.d.ts +12 -0
  58. package/dist/commands/service-manager.d.ts.map +1 -0
  59. package/dist/commands/service-manager.js +967 -0
  60. package/dist/commands/service-manager.js.map +1 -0
  61. package/dist/commands/service-validate.d.ts +12 -0
  62. package/dist/commands/service-validate.d.ts.map +1 -0
  63. package/dist/commands/service-validate.js +611 -0
  64. package/dist/commands/service-validate.js.map +1 -0
  65. package/dist/commands/services-create.d.ts +15 -0
  66. package/dist/commands/services-create.d.ts.map +1 -0
  67. package/dist/commands/services-create.js +1452 -0
  68. package/dist/commands/services-create.js.map +1 -0
  69. package/dist/commands/services-scan.d.ts +13 -0
  70. package/dist/commands/services-scan.d.ts.map +1 -0
  71. package/dist/commands/services-scan.js +251 -0
  72. package/dist/commands/services-scan.js.map +1 -0
  73. package/dist/commands/services-sync-agents.d.ts +23 -0
  74. package/dist/commands/services-sync-agents.d.ts.map +1 -0
  75. package/dist/commands/services-sync-agents.js +207 -0
  76. package/dist/commands/services-sync-agents.js.map +1 -0
  77. package/dist/commands/services.d.ts +19 -0
  78. package/dist/commands/services.d.ts.map +1 -0
  79. package/dist/commands/services.js +742 -0
  80. package/dist/commands/services.js.map +1 -0
  81. package/dist/commands/session.d.ts +5 -1
  82. package/dist/commands/session.d.ts.map +1 -1
  83. package/dist/commands/session.js +68 -586
  84. package/dist/commands/session.js.map +1 -1
  85. package/dist/commands/status.d.ts.map +1 -1
  86. package/dist/commands/status.js +17 -0
  87. package/dist/commands/status.js.map +1 -1
  88. package/dist/commands/update.d.ts.map +1 -1
  89. package/dist/commands/update.js +75 -21
  90. package/dist/commands/update.js.map +1 -1
  91. package/dist/commands/validate-settings.d.ts +37 -0
  92. package/dist/commands/validate-settings.d.ts.map +1 -0
  93. package/dist/commands/validate-settings.js +197 -0
  94. package/dist/commands/validate-settings.js.map +1 -0
  95. package/dist/commands/voice.d.ts +0 -1
  96. package/dist/commands/voice.d.ts.map +1 -1
  97. package/dist/commands/voice.js +16 -15
  98. package/dist/commands/voice.js.map +1 -1
  99. package/dist/index.js +395 -141
  100. package/dist/index.js.map +1 -1
  101. package/dist/lib/agent-generator.d.ts +26 -0
  102. package/dist/lib/agent-generator.d.ts.map +1 -0
  103. package/dist/lib/agent-generator.js +331 -0
  104. package/dist/lib/agent-generator.js.map +1 -0
  105. package/dist/lib/memory-db.d.ts +102 -0
  106. package/dist/lib/memory-db.d.ts.map +1 -0
  107. package/dist/lib/memory-db.js +313 -0
  108. package/dist/lib/memory-db.js.map +1 -0
  109. package/dist/lib/memory-indexer.d.ts +47 -0
  110. package/dist/lib/memory-indexer.d.ts.map +1 -0
  111. package/dist/lib/memory-indexer.js +215 -0
  112. package/dist/lib/memory-indexer.js.map +1 -0
  113. package/dist/lib/memory-search.d.ts +41 -0
  114. package/dist/lib/memory-search.d.ts.map +1 -0
  115. package/dist/lib/memory-search.js +246 -0
  116. package/dist/lib/memory-search.js.map +1 -0
  117. package/dist/lib/openclaw-registry.d.ts +48 -0
  118. package/dist/lib/openclaw-registry.d.ts.map +1 -0
  119. package/dist/lib/openclaw-registry.js +181 -0
  120. package/dist/lib/openclaw-registry.js.map +1 -0
  121. package/dist/lib/openclaw-sdk.d.ts +107 -0
  122. package/dist/lib/openclaw-sdk.d.ts.map +1 -0
  123. package/dist/lib/openclaw-sdk.js +208 -0
  124. package/dist/lib/openclaw-sdk.js.map +1 -0
  125. package/dist/lib/peer-agent-generator.d.ts +44 -0
  126. package/dist/lib/peer-agent-generator.d.ts.map +1 -0
  127. package/dist/lib/peer-agent-generator.js +286 -0
  128. package/dist/lib/peer-agent-generator.js.map +1 -0
  129. package/dist/lib/service-dependencies.d.ts +44 -0
  130. package/dist/lib/service-dependencies.d.ts.map +1 -0
  131. package/dist/lib/service-dependencies.js +314 -0
  132. package/dist/lib/service-dependencies.js.map +1 -0
  133. package/dist/lib/service-detector.d.ts +61 -0
  134. package/dist/lib/service-detector.d.ts.map +1 -0
  135. package/dist/lib/service-detector.js +521 -0
  136. package/dist/lib/service-detector.js.map +1 -0
  137. package/dist/lib/service-gtm.d.ts +157 -0
  138. package/dist/lib/service-gtm.d.ts.map +1 -0
  139. package/dist/lib/service-gtm.js +786 -0
  140. package/dist/lib/service-gtm.js.map +1 -0
  141. package/dist/lib/service-mcp-base.d.ts +103 -0
  142. package/dist/lib/service-mcp-base.d.ts.map +1 -0
  143. package/dist/lib/service-mcp-base.js +263 -0
  144. package/dist/lib/service-mcp-base.js.map +1 -0
  145. package/dist/lib/service-utils.d.ts +103 -0
  146. package/dist/lib/service-utils.d.ts.map +1 -0
  147. package/dist/lib/service-utils.js +368 -0
  148. package/dist/lib/service-utils.js.map +1 -0
  149. package/dist/lib/skill-generator.d.ts +21 -0
  150. package/dist/lib/skill-generator.d.ts.map +1 -0
  151. package/dist/lib/skill-generator.js +253 -0
  152. package/dist/lib/skill-generator.js.map +1 -0
  153. package/dist/lib/stratus-client.d.ts +100 -0
  154. package/dist/lib/stratus-client.d.ts.map +1 -0
  155. package/dist/lib/stratus-client.js +255 -0
  156. package/dist/lib/stratus-client.js.map +1 -0
  157. package/dist/mcp/context-hub-mcp.js +135 -53
  158. package/dist/mcp/context-hub-mcp.js.map +1 -1
  159. package/dist/mcp/service-mcp-server.d.ts +12 -0
  160. package/dist/mcp/service-mcp-server.d.ts.map +1 -0
  161. package/dist/mcp/service-mcp-server.js +434 -0
  162. package/dist/mcp/service-mcp-server.js.map +1 -0
  163. package/dist/mcp/service-peer-mcp.d.ts +36 -0
  164. package/dist/mcp/service-peer-mcp.d.ts.map +1 -0
  165. package/dist/mcp/service-peer-mcp.js +220 -0
  166. package/dist/mcp/service-peer-mcp.js.map +1 -0
  167. package/dist/mcp/service-registry-mcp.d.ts +13 -0
  168. package/dist/mcp/service-registry-mcp.d.ts.map +1 -0
  169. package/dist/mcp/service-registry-mcp.js +330 -0
  170. package/dist/mcp/service-registry-mcp.js.map +1 -0
  171. package/dist/ui/banner.js +1 -1
  172. package/dist/ui/banner.js.map +1 -1
  173. package/dist/ui/context-hub-logs.d.ts +10 -0
  174. package/dist/ui/context-hub-logs.d.ts.map +1 -0
  175. package/dist/ui/context-hub-logs.js +175 -0
  176. package/dist/ui/context-hub-logs.js.map +1 -0
  177. package/dist/ui/service-dashboard.d.ts +11 -0
  178. package/dist/ui/service-dashboard.d.ts.map +1 -0
  179. package/dist/ui/service-dashboard.js +357 -0
  180. package/dist/ui/service-dashboard.js.map +1 -0
  181. package/dist/ui/services-manager.d.ts +11 -0
  182. package/dist/ui/services-manager.d.ts.map +1 -0
  183. package/dist/ui/services-manager.js +507 -0
  184. package/dist/ui/services-manager.js.map +1 -0
  185. package/dist/utils/auth-guard.d.ts.map +1 -1
  186. package/dist/utils/auth-guard.js +8 -9
  187. package/dist/utils/auth-guard.js.map +1 -1
  188. package/dist/utils/claude-md-generator.d.ts +10 -0
  189. package/dist/utils/claude-md-generator.d.ts.map +1 -0
  190. package/dist/utils/claude-md-generator.js +215 -0
  191. package/dist/utils/claude-md-generator.js.map +1 -0
  192. package/dist/utils/ensure-context-hub.d.ts +20 -0
  193. package/dist/utils/ensure-context-hub.d.ts.map +1 -0
  194. package/dist/utils/ensure-context-hub.js +65 -0
  195. package/dist/utils/ensure-context-hub.js.map +1 -0
  196. package/dist/utils/ensure-project.d.ts.map +1 -1
  197. package/dist/utils/ensure-project.js +3 -4
  198. package/dist/utils/ensure-project.js.map +1 -1
  199. package/dist/utils/jfl-config.d.ts +19 -0
  200. package/dist/utils/jfl-config.d.ts.map +1 -0
  201. package/dist/utils/jfl-config.js +112 -0
  202. package/dist/utils/jfl-config.js.map +1 -0
  203. package/dist/utils/jfl-migration.d.ts +29 -0
  204. package/dist/utils/jfl-migration.d.ts.map +1 -0
  205. package/dist/utils/jfl-migration.js +142 -0
  206. package/dist/utils/jfl-migration.js.map +1 -0
  207. package/dist/utils/jfl-paths.d.ts +55 -0
  208. package/dist/utils/jfl-paths.d.ts.map +1 -0
  209. package/dist/utils/jfl-paths.js +120 -0
  210. package/dist/utils/jfl-paths.js.map +1 -0
  211. package/dist/utils/settings-validator.d.ts +73 -0
  212. package/dist/utils/settings-validator.d.ts.map +1 -0
  213. package/dist/utils/settings-validator.js +222 -0
  214. package/dist/utils/settings-validator.js.map +1 -0
  215. package/package.json +19 -3
  216. package/scripts/commit-gtm.sh +56 -0
  217. package/scripts/commit-product.sh +68 -0
  218. package/scripts/context-query.sh +45 -0
  219. package/scripts/session/auto-commit.sh +297 -0
  220. package/scripts/session/jfl-doctor.sh +707 -0
  221. package/scripts/session/session-cleanup.sh +268 -0
  222. package/scripts/session/session-end.sh +198 -0
  223. package/scripts/session/session-init.sh +350 -0
  224. package/scripts/session/session-init.sh.backup +292 -0
  225. package/scripts/session/session-sync.sh +167 -0
  226. package/scripts/session/test-context-preservation.sh +160 -0
  227. package/scripts/session/test-critical-infrastructure.sh +293 -0
  228. package/scripts/session/test-experience-level.sh +336 -0
  229. package/scripts/session/test-session-cleanup.sh +268 -0
  230. package/scripts/session/test-session-sync.sh +320 -0
  231. package/scripts/voice-start.sh +36 -8
  232. package/scripts/where-am-i.sh +78 -0
  233. package/template/.claude/service-settings.json +32 -0
  234. package/template/.claude/settings.json +14 -1
  235. package/template/.claude/skills/end/SKILL.md +1780 -0
  236. package/template/.jfl/config.json +2 -1
  237. package/template/CLAUDE.md +1039 -134
  238. package/template/CLAUDE.md.bak +1187 -0
  239. package/template/scripts/commit-gtm.sh +56 -0
  240. package/template/scripts/commit-product.sh +68 -0
  241. package/template/scripts/migrate-to-branch-sessions.sh +201 -0
  242. package/template/scripts/session/auto-commit.sh +58 -6
  243. package/template/scripts/session/jfl-doctor.sh +137 -17
  244. package/template/scripts/session/session-cleanup.sh +268 -0
  245. package/template/scripts/session/session-end.sh +4 -0
  246. package/template/scripts/session/session-init.sh +253 -66
  247. package/template/scripts/session/test-critical-infrastructure.sh +293 -0
  248. package/template/scripts/session/test-experience-level.sh +336 -0
  249. package/template/scripts/session/test-session-cleanup.sh +268 -0
  250. package/template/scripts/session/test-session-sync.sh +320 -0
  251. package/template/scripts/where-am-i.sh +78 -0
  252. package/template/templates/service-agent/.claude/settings.json +32 -0
  253. package/template/templates/service-agent/CLAUDE.md +334 -0
  254. package/template/templates/service-agent/knowledge/ARCHITECTURE.md +115 -0
  255. package/template/templates/service-agent/knowledge/DEPLOYMENT.md +199 -0
  256. package/template/templates/service-agent/knowledge/RUNBOOK.md +412 -0
  257. package/template/templates/service-agent/knowledge/SERVICE_SPEC.md +77 -0
  258. package/dist/commands/session-mgmt.d.ts +0 -33
  259. package/dist/commands/session-mgmt.d.ts.map +0 -1
  260. package/dist/commands/session-mgmt.js +0 -404
  261. package/dist/commands/session-mgmt.js.map +0 -1
  262. package/template/scripts/session/auto-merge.sh +0 -325
@@ -0,0 +1,368 @@
1
+ /**
2
+ * Service Management Utilities
3
+ *
4
+ * Shared utilities for service lifecycle management across commands.
5
+ * Provides version tracking, health checks, and restart logic.
6
+ *
7
+ * @purpose Shared service management utilities for update flow
8
+ */
9
+ import * as fs from "fs";
10
+ import * as path from "path";
11
+ import { execSync } from "child_process";
12
+ import chalk from "chalk";
13
+ import ora from "ora";
14
+ import { JFL_PATHS } from "../utils/jfl-paths.js";
15
+ // ============================================================================
16
+ // Version Tracking
17
+ // ============================================================================
18
+ const CLI_VERSION_FILE = path.join(JFL_PATHS.data, "cli-version.json");
19
+ /**
20
+ * Get current CLI version from package.json
21
+ */
22
+ export function getCurrentCliVersion() {
23
+ try {
24
+ const packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, "../../package.json"), "utf-8"));
25
+ return packageJson.version;
26
+ }
27
+ catch {
28
+ return "0.0.0";
29
+ }
30
+ }
31
+ /**
32
+ * Read stored CLI version info
33
+ */
34
+ export function readCliVersion() {
35
+ if (!fs.existsSync(CLI_VERSION_FILE)) {
36
+ return null;
37
+ }
38
+ try {
39
+ const content = fs.readFileSync(CLI_VERSION_FILE, "utf-8");
40
+ return JSON.parse(content);
41
+ }
42
+ catch {
43
+ return null;
44
+ }
45
+ }
46
+ /**
47
+ * Write CLI version info
48
+ */
49
+ export function writeCliVersion(version, services) {
50
+ const dir = path.dirname(CLI_VERSION_FILE);
51
+ if (!fs.existsSync(dir)) {
52
+ fs.mkdirSync(dir, { recursive: true });
53
+ }
54
+ const versionInfo = {
55
+ version,
56
+ updated_at: new Date().toISOString(),
57
+ services: services || {
58
+ "context-hub": { version, port: 4242 },
59
+ "service-manager": { version, port: 3402 }
60
+ }
61
+ };
62
+ fs.writeFileSync(CLI_VERSION_FILE, JSON.stringify(versionInfo, null, 2));
63
+ }
64
+ /**
65
+ * Detect if services have changed (CLI version bump)
66
+ */
67
+ export async function detectServiceChanges() {
68
+ const currentVersion = getCurrentCliVersion();
69
+ const storedInfo = readCliVersion();
70
+ if (!storedInfo) {
71
+ // First time - no stored version yet
72
+ return { changed: false, newVersion: currentVersion };
73
+ }
74
+ const changed = storedInfo.version !== currentVersion;
75
+ return {
76
+ changed,
77
+ oldVersion: storedInfo.version,
78
+ newVersion: currentVersion
79
+ };
80
+ }
81
+ // ============================================================================
82
+ // Service Health Checks
83
+ // ============================================================================
84
+ /**
85
+ * Check if a service is running via health endpoint
86
+ */
87
+ export async function waitForHealthy(url, timeout = 5000) {
88
+ const startTime = Date.now();
89
+ while (Date.now() - startTime < timeout) {
90
+ try {
91
+ const controller = new AbortController();
92
+ const timeoutId = setTimeout(() => controller.abort(), 2000);
93
+ const response = await fetch(url, {
94
+ signal: controller.signal
95
+ });
96
+ clearTimeout(timeoutId);
97
+ if (response.ok) {
98
+ return true;
99
+ }
100
+ }
101
+ catch {
102
+ // Health check failed, retry
103
+ }
104
+ // Wait 500ms before retry
105
+ await new Promise(resolve => setTimeout(resolve, 500));
106
+ }
107
+ return false;
108
+ }
109
+ /**
110
+ * Check if a service is running via PID file
111
+ */
112
+ export function isServiceRunningViaPid(pidFile) {
113
+ if (!fs.existsSync(pidFile)) {
114
+ return { running: false };
115
+ }
116
+ try {
117
+ const pid = parseInt(fs.readFileSync(pidFile, "utf-8").trim(), 10);
118
+ process.kill(pid, 0); // Check if process exists
119
+ return { running: true, pid };
120
+ }
121
+ catch {
122
+ // Process doesn't exist, clean up stale PID file
123
+ try {
124
+ fs.unlinkSync(pidFile);
125
+ }
126
+ catch {
127
+ // Ignore cleanup errors
128
+ }
129
+ return { running: false };
130
+ }
131
+ }
132
+ /**
133
+ * Check health of a service
134
+ */
135
+ export async function checkServiceHealth(serviceName, healthUrl, pidFile) {
136
+ // If health URL provided, check that
137
+ if (healthUrl) {
138
+ try {
139
+ const controller = new AbortController();
140
+ const timeoutId = setTimeout(() => controller.abort(), 3000);
141
+ const response = await fetch(healthUrl, {
142
+ signal: controller.signal
143
+ });
144
+ clearTimeout(timeoutId);
145
+ if (response.ok) {
146
+ const data = await response.json().catch(() => ({}));
147
+ return {
148
+ healthy: true,
149
+ message: `${serviceName} is healthy`,
150
+ port: data.port
151
+ };
152
+ }
153
+ return {
154
+ healthy: false,
155
+ message: `${serviceName} health check failed: HTTP ${response.status}`
156
+ };
157
+ }
158
+ catch (err) {
159
+ return {
160
+ healthy: false,
161
+ message: `${serviceName} health check failed: ${err.message}`
162
+ };
163
+ }
164
+ }
165
+ // Fallback to PID file check
166
+ if (pidFile) {
167
+ const status = isServiceRunningViaPid(pidFile);
168
+ return {
169
+ healthy: status.running,
170
+ message: status.running
171
+ ? `${serviceName} is running (PID: ${status.pid})`
172
+ : `${serviceName} is not running`
173
+ };
174
+ }
175
+ return {
176
+ healthy: false,
177
+ message: `Cannot determine health for ${serviceName} (no health URL or PID file)`
178
+ };
179
+ }
180
+ // ============================================================================
181
+ // Service Control
182
+ // ============================================================================
183
+ /**
184
+ * Wait for a service to stop
185
+ */
186
+ async function waitForStop(pidFile, timeout) {
187
+ const startTime = Date.now();
188
+ while (Date.now() - startTime < timeout) {
189
+ if (!fs.existsSync(pidFile)) {
190
+ return true;
191
+ }
192
+ try {
193
+ const pid = parseInt(fs.readFileSync(pidFile, "utf-8").trim(), 10);
194
+ process.kill(pid, 0); // Check if process exists
195
+ }
196
+ catch {
197
+ // Process is gone
198
+ return true;
199
+ }
200
+ await new Promise(resolve => setTimeout(resolve, 200));
201
+ }
202
+ return false;
203
+ }
204
+ /**
205
+ * Execute a command silently
206
+ */
207
+ function execSilent(command) {
208
+ try {
209
+ execSync(command, { stdio: "pipe" });
210
+ return { success: true };
211
+ }
212
+ catch (err) {
213
+ return { success: false, error: err.message };
214
+ }
215
+ }
216
+ /**
217
+ * Restart a service with health validation
218
+ */
219
+ export async function restartService(serviceName, opts) {
220
+ const spinner = ora(`Restarting ${serviceName}...`).start();
221
+ try {
222
+ // 1. Stop the service
223
+ const stopResult = execSilent(opts.stopCommand);
224
+ if (stopResult.success) {
225
+ spinner.text = `${serviceName} stopped, starting...`;
226
+ await new Promise(resolve => setTimeout(resolve, 500));
227
+ }
228
+ // 2. Start the service
229
+ const startResult = execSilent(opts.startCommand);
230
+ if (!startResult.success) {
231
+ spinner.fail(`${serviceName} failed to start`);
232
+ return {
233
+ success: false,
234
+ message: `Failed to start: ${startResult.error}`
235
+ };
236
+ }
237
+ // 3. Wait a moment for startup
238
+ await new Promise(resolve => setTimeout(resolve, 800));
239
+ // 4. Health check if URL provided
240
+ if (opts.healthCheck) {
241
+ spinner.text = `Checking ${serviceName} health...`;
242
+ const healthy = await waitForHealthy(opts.healthCheck, opts.timeout || 5000);
243
+ if (healthy) {
244
+ spinner.succeed(`${serviceName} restarted`);
245
+ return { success: true, message: "Service restarted and healthy" };
246
+ }
247
+ else {
248
+ spinner.warn(`${serviceName} started but health check failed`);
249
+ return {
250
+ success: false,
251
+ message: "Service started but not responding to health checks"
252
+ };
253
+ }
254
+ }
255
+ spinner.succeed(`${serviceName} restarted`);
256
+ return { success: true, message: "Service restarted" };
257
+ }
258
+ catch (error) {
259
+ spinner.fail(`${serviceName} restart failed`);
260
+ return {
261
+ success: false,
262
+ message: error.message
263
+ };
264
+ }
265
+ }
266
+ /**
267
+ * Ensure a service is running (start if not, validate if running)
268
+ */
269
+ export async function ensureServiceRunning(serviceName, startCommand, healthCheck, pidFile) {
270
+ // Check if already running
271
+ if (pidFile) {
272
+ const status = isServiceRunningViaPid(pidFile);
273
+ if (status.running && healthCheck) {
274
+ // Verify health
275
+ const healthy = await waitForHealthy(healthCheck, 2000);
276
+ if (healthy) {
277
+ return { success: true, message: `${serviceName} already running` };
278
+ }
279
+ // Process exists but not healthy - fall through to restart
280
+ }
281
+ else if (status.running) {
282
+ return { success: true, message: `${serviceName} already running` };
283
+ }
284
+ }
285
+ // Start the service
286
+ const result = execSilent(startCommand);
287
+ if (!result.success) {
288
+ return {
289
+ success: false,
290
+ message: `Failed to start: ${result.error}`
291
+ };
292
+ }
293
+ // Wait for startup
294
+ await new Promise(resolve => setTimeout(resolve, 800));
295
+ // Validate health if URL provided
296
+ if (healthCheck) {
297
+ const healthy = await waitForHealthy(healthCheck, 5000);
298
+ if (healthy) {
299
+ return { success: true, message: `${serviceName} started successfully` };
300
+ }
301
+ else {
302
+ return {
303
+ success: false,
304
+ message: `${serviceName} started but health check failed`
305
+ };
306
+ }
307
+ }
308
+ return { success: true, message: `${serviceName} started` };
309
+ }
310
+ // ============================================================================
311
+ // Multi-Service Operations
312
+ // ============================================================================
313
+ /**
314
+ * Restart all core services (Context Hub + Service Manager)
315
+ */
316
+ export async function restartCoreServices(options = {}) {
317
+ const results = {
318
+ contextHub: false,
319
+ serviceManager: false
320
+ };
321
+ console.log(chalk.cyan("\n📦 Restarting services...\n"));
322
+ // Restart Context Hub
323
+ const contextHubResult = await restartService("context-hub", {
324
+ stopCommand: "jfl context-hub stop",
325
+ startCommand: "jfl context-hub ensure",
326
+ healthCheck: "http://localhost:4242/health",
327
+ timeout: 5000
328
+ });
329
+ results.contextHub = contextHubResult.success;
330
+ // Restart Service Manager
331
+ const serviceManagerResult = await restartService("service-manager", {
332
+ stopCommand: "jfl service-manager stop",
333
+ startCommand: "jfl service-manager ensure",
334
+ healthCheck: "http://localhost:3402/health",
335
+ timeout: 5000
336
+ });
337
+ results.serviceManager = serviceManagerResult.success;
338
+ return results;
339
+ }
340
+ /**
341
+ * Validate all core services are healthy
342
+ */
343
+ export async function validateCoreServices() {
344
+ const issues = [];
345
+ // Check Context Hub
346
+ const contextHubHealth = await checkServiceHealth("context-hub", "http://localhost:4242/health", ".jfl/context-hub.pid");
347
+ if (!contextHubHealth.healthy) {
348
+ issues.push({
349
+ service: "context-hub",
350
+ message: contextHubHealth.message,
351
+ remedy: "Run: jfl context-hub restart"
352
+ });
353
+ }
354
+ // Check Service Manager
355
+ const serviceManagerHealth = await checkServiceHealth("service-manager", "http://localhost:3402/health", path.join(JFL_PATHS.data, "services", "pids", "service-manager.pid"));
356
+ if (!serviceManagerHealth.healthy) {
357
+ issues.push({
358
+ service: "service-manager",
359
+ message: serviceManagerHealth.message,
360
+ remedy: "Run: jfl service-manager restart"
361
+ });
362
+ }
363
+ return {
364
+ healthy: issues.length === 0,
365
+ issues
366
+ };
367
+ }
368
+ //# sourceMappingURL=service-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-utils.js","sourceRoot":"","sources":["../../src/lib/service-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Skill Generator
3
+ *
4
+ * Generates service skill wrappers in GTM .claude/skills/ directory
5
+ *
6
+ * @purpose Generate skill wrappers for service agent invocation
7
+ */
8
+ import type { ServiceMetadata } from "./service-detector.js";
9
+ /**
10
+ * Generate skill definition (SKILL.md)
11
+ */
12
+ export declare function generateSkillDefinition(metadata: ServiceMetadata, servicePath: string): string;
13
+ /**
14
+ * Generate skill handler script
15
+ */
16
+ export declare function generateSkillHandler(metadata: ServiceMetadata, servicePath: string, gtmPath: string): string;
17
+ /**
18
+ * Write skill files to GTM repo
19
+ */
20
+ export declare function writeSkillFiles(metadata: ServiceMetadata, servicePath: string, gtmPath: string): string;
21
+ //# sourceMappingURL=skill-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-generator.d.ts","sourceRoot":"","sources":["../../src/lib/skill-generator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAE5D;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,eAAe,EACzB,WAAW,EAAE,MAAM,GAClB,MAAM,CAmFR;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,eAAe,EACzB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,MAAM,CAsIR;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,eAAe,EACzB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GACd,MAAM,CAoBR"}
@@ -0,0 +1,253 @@
1
+ /**
2
+ * Skill Generator
3
+ *
4
+ * Generates service skill wrappers in GTM .claude/skills/ directory
5
+ *
6
+ * @purpose Generate skill wrappers for service agent invocation
7
+ */
8
+ import { writeFileSync, mkdirSync, existsSync } from "fs";
9
+ import { join } from "path";
10
+ /**
11
+ * Generate skill definition (SKILL.md)
12
+ */
13
+ export function generateSkillDefinition(metadata, servicePath) {
14
+ const skillName = metadata.name;
15
+ return `---
16
+ name: ${skillName}
17
+ version: 1.0.0
18
+ type: service
19
+ description: ${metadata.description}
20
+ service_path: ${servicePath}
21
+ ---
22
+
23
+ # ${skillName} - Service Agent Skill
24
+
25
+ Quick access to **${metadata.name}** service agent.
26
+
27
+ ## Usage
28
+
29
+ \`\`\`
30
+ /${skillName} [command]
31
+ \`\`\`
32
+
33
+ ## Commands
34
+
35
+ | Command | Description |
36
+ |---------|-------------|
37
+ | \`status\` | Show service status |
38
+ | \`logs\` | Show service logs |
39
+ | \`start\` | Start the service |
40
+ | \`stop\` | Stop the service |
41
+ | \`restart\` | Restart the service |
42
+ | \`health\` | Check service health |
43
+ | \`recent\` | Show recent changes |
44
+ | \`deploy\` | Deploy to production (requires approval) |
45
+
46
+ ## Examples
47
+
48
+ \`\`\`
49
+ /${skillName} status
50
+ /${skillName} logs
51
+ /${skillName} restart
52
+ /${skillName} deploy
53
+ \`\`\`
54
+
55
+ ## How It Works
56
+
57
+ This skill spawns the **service-${skillName}** agent with your request. The agent:
58
+
59
+ 1. Reads service knowledge docs (SERVICE_SPEC, ARCHITECTURE, DEPLOYMENT, RUNBOOK)
60
+ 2. Performs the requested operation
61
+ 3. Updates service status
62
+ 4. Emits event to GTM
63
+ 5. Writes journal entry if significant
64
+ 6. Returns the result
65
+
66
+ ## Metadata
67
+
68
+ - **Type**: ${metadata.type}
69
+ - **Port**: ${metadata.port || "N/A"}
70
+ - **Version**: ${metadata.version}
71
+ - **Dependencies**: ${metadata.dependencies.join(", ") || "None"}
72
+ ${metadata.healthcheck ? `- **Healthcheck**: \`${metadata.healthcheck}\`` : ""}
73
+
74
+ ## Service Path
75
+
76
+ \`${servicePath}\`
77
+
78
+ ## Knowledge Docs
79
+
80
+ - \`${servicePath}/knowledge/SERVICE_SPEC.md\`
81
+ - \`${servicePath}/knowledge/ARCHITECTURE.md\`
82
+ - \`${servicePath}/knowledge/DEPLOYMENT.md\`
83
+ - \`${servicePath}/knowledge/RUNBOOK.md\`
84
+
85
+ ## Direct Invocation
86
+
87
+ You can also invoke via @-mention in conversation:
88
+
89
+ \`\`\`
90
+ @${skillName} what's your current status?
91
+ @${skillName} show me recent changes
92
+ @${skillName} deploy latest changes
93
+ \`\`\`
94
+ `;
95
+ }
96
+ /**
97
+ * Generate skill handler script
98
+ */
99
+ export function generateSkillHandler(metadata, servicePath, gtmPath) {
100
+ const skillName = metadata.name;
101
+ return `#!/bin/bash
102
+ #
103
+ # Service Agent Skill Handler: ${skillName}
104
+ #
105
+ # Routes skill invocations to service agent
106
+ #
107
+
108
+ set -e
109
+
110
+ COMMAND="\${1:-status}"
111
+ GTM_PATH="${gtmPath}"
112
+ SERVICE_PATH="${servicePath}"
113
+ SERVICE_NAME="${skillName}"
114
+
115
+ # Validate command
116
+ case "$COMMAND" in
117
+ status|logs|start|stop|restart|health|recent|deploy|help)
118
+ # Valid command
119
+ ;;
120
+ *)
121
+ echo "Unknown command: $COMMAND"
122
+ echo ""
123
+ echo "Available commands:"
124
+ echo " status - Show service status"
125
+ echo " logs - Show service logs"
126
+ echo " start - Start the service"
127
+ echo " stop - Stop the service"
128
+ echo " restart - Restart the service"
129
+ echo " health - Check service health"
130
+ echo " recent - Show recent changes"
131
+ echo " deploy - Deploy to production"
132
+ echo " help - Show this help"
133
+ exit 1
134
+ ;;
135
+ esac
136
+
137
+ # For help, show skill documentation
138
+ if [[ "$COMMAND" == "help" ]]; then
139
+ cat << EOF
140
+ Service Agent Skill: ${skillName}
141
+
142
+ Commands:
143
+ /${skillName} status - Show service status
144
+ /${skillName} logs - Show service logs
145
+ /${skillName} start - Start the service
146
+ /${skillName} stop - Stop the service
147
+ /${skillName} restart - Restart the service
148
+ /${skillName} health - Check service health
149
+ /${skillName} recent - Show recent changes
150
+ /${skillName} deploy - Deploy to production
151
+
152
+ Metadata:
153
+ Type: ${metadata.type}
154
+ Port: ${metadata.port || "N/A"}
155
+ Version: ${metadata.version}
156
+ Path: ${servicePath}
157
+
158
+ You can also use @-mentions:
159
+ @${skillName} what's your status?
160
+ @${skillName} show recent changes
161
+ @${skillName} deploy latest version
162
+ EOF
163
+ exit 0
164
+ fi
165
+
166
+ # Quick status check (no agent spawn needed)
167
+ if [[ "$COMMAND" == "status" ]]; then
168
+ if [[ -f "$SERVICE_PATH/.jfl/status.json" ]]; then
169
+ echo "Service Status: ${skillName}"
170
+ echo ""
171
+ jq '.' "$SERVICE_PATH/.jfl/status.json"
172
+ else
173
+ echo "Status file not found. Service may not be onboarded yet."
174
+ exit 1
175
+ fi
176
+ exit 0
177
+ fi
178
+
179
+ # Quick health check (no agent spawn needed)
180
+ if [[ "$COMMAND" == "health" ]]; then
181
+ ${metadata.healthcheck || 'echo "No healthcheck defined"'}
182
+ exit $?
183
+ fi
184
+
185
+ # Quick recent changes (no agent spawn needed)
186
+ if [[ "$COMMAND" == "recent" ]]; then
187
+ echo "Recent Changes: ${skillName}"
188
+ echo ""
189
+ if [[ -f "$SERVICE_PATH/.jfl/status.json" ]]; then
190
+ jq -r '.recent_changes[]' "$SERVICE_PATH/.jfl/status.json"
191
+ fi
192
+ echo ""
193
+ echo "Recent Journal Entries:"
194
+ cat "$SERVICE_PATH/.jfl/journal"/*.jsonl 2>/dev/null | tail -5 | jq -r '"\(.ts) - \(.title)"'
195
+ echo ""
196
+ echo "Recent Commits:"
197
+ cd "$SERVICE_PATH" && git log --oneline -5
198
+ exit 0
199
+ fi
200
+
201
+ # For other commands, this should spawn the service agent via Claude Code
202
+ # Since we're in a skill handler, we need to return instructions for Claude
203
+ cat << EOF
204
+ [SPAWN_SERVICE_AGENT]
205
+ Service: ${skillName}
206
+ Command: $COMMAND
207
+ Agent: service-${skillName}
208
+ Working Directory: ${servicePath}
209
+
210
+ Claude should:
211
+ 1. Spawn Task tool with subagent_type="general-purpose"
212
+ 2. Set working directory to: ${servicePath}
213
+ 3. Pass this request to the agent:
214
+
215
+ "You are the service agent for ${skillName}.
216
+
217
+ Your working directory is: ${servicePath}
218
+
219
+ Read your knowledge docs to understand the service:
220
+ - knowledge/SERVICE_SPEC.md
221
+ - knowledge/ARCHITECTURE.md
222
+ - knowledge/DEPLOYMENT.md
223
+ - knowledge/RUNBOOK.md
224
+
225
+ User request: $COMMAND the service
226
+
227
+ Execute the operation, update status, emit event, write journal, and report outcome."
228
+
229
+ [/SPAWN_SERVICE_AGENT]
230
+ EOF
231
+ `;
232
+ }
233
+ /**
234
+ * Write skill files to GTM repo
235
+ */
236
+ export function writeSkillFiles(metadata, servicePath, gtmPath) {
237
+ const skillName = metadata.name;
238
+ const skillDir = join(gtmPath, ".claude/skills", skillName);
239
+ // Ensure directory exists
240
+ if (!existsSync(skillDir)) {
241
+ mkdirSync(skillDir, { recursive: true });
242
+ }
243
+ // Write SKILL.md
244
+ const skillMd = generateSkillDefinition(metadata, servicePath);
245
+ const skillMdPath = join(skillDir, "SKILL.md");
246
+ writeFileSync(skillMdPath, skillMd);
247
+ // Write handler.sh
248
+ const handler = generateSkillHandler(metadata, servicePath, gtmPath);
249
+ const handlerPath = join(skillDir, "handler.sh");
250
+ writeFileSync(handlerPath, handler, { mode: 0o755 });
251
+ return skillDir;
252
+ }
253
+ //# sourceMappingURL=skill-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-generator.js","sourceRoot":"","sources":["../../src/lib/skill-generator.ts"],"names":[],"mappings":"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"}