@orgloop/cli 0.1.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 (94) hide show
  1. package/LICENSE.md +21 -0
  2. package/dist/commands/add.d.ts +8 -0
  3. package/dist/commands/add.d.ts.map +1 -0
  4. package/dist/commands/add.js +363 -0
  5. package/dist/commands/add.js.map +1 -0
  6. package/dist/commands/apply.d.ts +9 -0
  7. package/dist/commands/apply.d.ts.map +1 -0
  8. package/dist/commands/apply.js +289 -0
  9. package/dist/commands/apply.js.map +1 -0
  10. package/dist/commands/doctor.d.ts +45 -0
  11. package/dist/commands/doctor.d.ts.map +1 -0
  12. package/dist/commands/doctor.js +346 -0
  13. package/dist/commands/doctor.js.map +1 -0
  14. package/dist/commands/env.d.ts +23 -0
  15. package/dist/commands/env.d.ts.map +1 -0
  16. package/dist/commands/env.js +230 -0
  17. package/dist/commands/env.js.map +1 -0
  18. package/dist/commands/hook.d.ts +16 -0
  19. package/dist/commands/hook.d.ts.map +1 -0
  20. package/dist/commands/hook.js +80 -0
  21. package/dist/commands/hook.js.map +1 -0
  22. package/dist/commands/init.d.ts +42 -0
  23. package/dist/commands/init.d.ts.map +1 -0
  24. package/dist/commands/init.js +532 -0
  25. package/dist/commands/init.js.map +1 -0
  26. package/dist/commands/inspect.d.ts +8 -0
  27. package/dist/commands/inspect.d.ts.map +1 -0
  28. package/dist/commands/inspect.js +177 -0
  29. package/dist/commands/inspect.js.map +1 -0
  30. package/dist/commands/install-service.d.ts +8 -0
  31. package/dist/commands/install-service.d.ts.map +1 -0
  32. package/dist/commands/install-service.js +182 -0
  33. package/dist/commands/install-service.js.map +1 -0
  34. package/dist/commands/logs.d.ts +8 -0
  35. package/dist/commands/logs.d.ts.map +1 -0
  36. package/dist/commands/logs.js +197 -0
  37. package/dist/commands/logs.js.map +1 -0
  38. package/dist/commands/plan.d.ts +9 -0
  39. package/dist/commands/plan.d.ts.map +1 -0
  40. package/dist/commands/plan.js +200 -0
  41. package/dist/commands/plan.js.map +1 -0
  42. package/dist/commands/routes.d.ts +37 -0
  43. package/dist/commands/routes.d.ts.map +1 -0
  44. package/dist/commands/routes.js +167 -0
  45. package/dist/commands/routes.js.map +1 -0
  46. package/dist/commands/service.d.ts +9 -0
  47. package/dist/commands/service.d.ts.map +1 -0
  48. package/dist/commands/service.js +178 -0
  49. package/dist/commands/service.js.map +1 -0
  50. package/dist/commands/status.d.ts +8 -0
  51. package/dist/commands/status.d.ts.map +1 -0
  52. package/dist/commands/status.js +176 -0
  53. package/dist/commands/status.js.map +1 -0
  54. package/dist/commands/stop.d.ts +8 -0
  55. package/dist/commands/stop.d.ts.map +1 -0
  56. package/dist/commands/stop.js +102 -0
  57. package/dist/commands/stop.js.map +1 -0
  58. package/dist/commands/test.d.ts +8 -0
  59. package/dist/commands/test.d.ts.map +1 -0
  60. package/dist/commands/test.js +236 -0
  61. package/dist/commands/test.js.map +1 -0
  62. package/dist/commands/validate.d.ts +33 -0
  63. package/dist/commands/validate.d.ts.map +1 -0
  64. package/dist/commands/validate.js +501 -0
  65. package/dist/commands/validate.js.map +1 -0
  66. package/dist/commands/version.d.ts +8 -0
  67. package/dist/commands/version.d.ts.map +1 -0
  68. package/dist/commands/version.js +42 -0
  69. package/dist/commands/version.js.map +1 -0
  70. package/dist/config.d.ts +27 -0
  71. package/dist/config.d.ts.map +1 -0
  72. package/dist/config.js +169 -0
  73. package/dist/config.js.map +1 -0
  74. package/dist/env-metadata.d.ts +12 -0
  75. package/dist/env-metadata.d.ts.map +1 -0
  76. package/dist/env-metadata.js +39 -0
  77. package/dist/env-metadata.js.map +1 -0
  78. package/dist/index.d.ts +8 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.js +86 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/module-resolver.d.ts +42 -0
  83. package/dist/module-resolver.d.ts.map +1 -0
  84. package/dist/module-resolver.js +134 -0
  85. package/dist/module-resolver.js.map +1 -0
  86. package/dist/output.d.ts +36 -0
  87. package/dist/output.d.ts.map +1 -0
  88. package/dist/output.js +142 -0
  89. package/dist/output.js.map +1 -0
  90. package/dist/resolve-connectors.d.ts +27 -0
  91. package/dist/resolve-connectors.d.ts.map +1 -0
  92. package/dist/resolve-connectors.js +94 -0
  93. package/dist/resolve-connectors.js.map +1 -0
  94. package/package.json +51 -0
@@ -0,0 +1,289 @@
1
+ /**
2
+ * orgloop apply — Start/update the runtime with current config.
3
+ *
4
+ * Loads config, creates OrgLoop engine instance, starts it.
5
+ * Foreground by default; --daemon forks to background.
6
+ */
7
+ import { fork } from 'node:child_process';
8
+ import { mkdir, writeFile } from 'node:fs/promises';
9
+ import { homedir } from 'node:os';
10
+ import { join } from 'node:path';
11
+ import { fileURLToPath } from 'node:url';
12
+ import chalk from 'chalk';
13
+ import { loadCliConfig, resolveConfigPath } from '../config.js';
14
+ import { getEnvVarMeta } from '../env-metadata.js';
15
+ import * as output from '../output.js';
16
+ import { resolveConnectors } from '../resolve-connectors.js';
17
+ import { scanEnvVars } from './env.js';
18
+ const PID_DIR = join(homedir(), '.orgloop');
19
+ const PID_FILE = join(PID_DIR, 'orgloop.pid');
20
+ const STATE_FILE = join(PID_DIR, 'state.json');
21
+ // ─── State persistence ──────────────────────────────────────────────────────
22
+ async function saveState(config) {
23
+ await mkdir(PID_DIR, { recursive: true });
24
+ const state = {
25
+ sources: Object.fromEntries(config.sources.map((s) => [
26
+ s.id,
27
+ { connector: s.connector, poll_interval: s.poll?.interval },
28
+ ])),
29
+ actors: Object.fromEntries(config.actors.map((a) => [a.id, { connector: a.connector }])),
30
+ routes: Object.fromEntries(config.routes.map((r) => [r.name, { source: r.when.source, actor: r.then.actor }])),
31
+ transforms: Object.fromEntries(config.transforms.map((t) => [t.name, { type: t.type }])),
32
+ loggers: Object.fromEntries(config.loggers.map((l) => [l.name, { type: l.type }])),
33
+ };
34
+ await writeFile(STATE_FILE, JSON.stringify(state, null, 2), 'utf-8');
35
+ }
36
+ // ─── Foreground run ──────────────────────────────────────────────────────────
37
+ async function runForeground(configPath) {
38
+ // Pre-flight: check all env vars before loadCliConfig crashes on the first one
39
+ try {
40
+ const resolvedPath = resolveConfigPath(configPath);
41
+ const envVars = await scanEnvVars(resolvedPath);
42
+ const missing = [];
43
+ const present = [];
44
+ for (const [name, source] of envVars) {
45
+ if (process.env[name] === undefined) {
46
+ missing.push({ name, source });
47
+ }
48
+ else {
49
+ present.push({ name, source });
50
+ }
51
+ }
52
+ if (missing.length > 0) {
53
+ const maxLen = Math.max(...[...envVars.keys()].map((k) => k.length));
54
+ output.blank();
55
+ output.heading('Environment Variables:');
56
+ output.blank();
57
+ for (const v of present) {
58
+ console.log(` ${chalk.green('\u2713')} ${v.name.padEnd(maxLen)} ${chalk.dim(v.source)}`);
59
+ }
60
+ for (const v of missing) {
61
+ console.log(` ${chalk.red('\u2717')} ${v.name.padEnd(maxLen)} ${chalk.dim(v.source)}`);
62
+ const meta = getEnvVarMeta(v.name);
63
+ if (meta) {
64
+ console.log(` ${chalk.dim('\u2192')} ${chalk.dim(meta.description)}`);
65
+ if (meta.help_url) {
66
+ console.log(` ${chalk.dim('\u2192')} ${chalk.dim(meta.help_url)}`);
67
+ }
68
+ }
69
+ }
70
+ output.blank();
71
+ output.error(`${missing.length} variable${missing.length > 1 ? 's' : ''} missing \u2014 run \`orgloop env\` for details.`);
72
+ process.exitCode = 1;
73
+ return;
74
+ }
75
+ }
76
+ catch {
77
+ // Pre-flight is best-effort — fall through to loadCliConfig
78
+ }
79
+ const config = await loadCliConfig({ configPath });
80
+ output.blank();
81
+ output.info('Applying plan...');
82
+ output.blank();
83
+ // Import OrgLoop from core — this may fail if core isn't built yet
84
+ let OrgLoop;
85
+ try {
86
+ const core = await import('@orgloop/core');
87
+ OrgLoop = core.OrgLoop;
88
+ }
89
+ catch {
90
+ // Core not available yet — run in stub mode
91
+ output.warn('OrgLoop core not available — running in config-only mode');
92
+ output.blank();
93
+ // Display what would be started
94
+ for (const s of config.sources) {
95
+ const interval = s.poll?.interval
96
+ ? `polling started (every ${s.poll.interval})`
97
+ : 'hook listener started';
98
+ output.success(`Source ${s.id} — ${interval}`);
99
+ }
100
+ for (const a of config.actors) {
101
+ output.success(`Actor ${a.id} — ready`);
102
+ }
103
+ for (const r of config.routes) {
104
+ output.success(`Route ${r.name} — active`);
105
+ }
106
+ for (const l of config.loggers) {
107
+ output.success(`Logger ${l.name} — configured`);
108
+ }
109
+ await saveState(config);
110
+ // Write PID file
111
+ await mkdir(PID_DIR, { recursive: true });
112
+ await writeFile(PID_FILE, String(process.pid), 'utf-8');
113
+ output.blank();
114
+ output.info(`OrgLoop is running. PID: ${process.pid}`);
115
+ output.info('Logs: orgloop logs | Status: orgloop status | Stop: orgloop stop');
116
+ // Keep process alive
117
+ const shutdown = async () => {
118
+ output.blank();
119
+ output.info('Shutting down...');
120
+ const { unlink } = await import('node:fs/promises');
121
+ try {
122
+ await unlink(PID_FILE);
123
+ }
124
+ catch {
125
+ /* ignore */
126
+ }
127
+ process.exit(0);
128
+ };
129
+ process.on('SIGTERM', shutdown);
130
+ process.on('SIGINT', shutdown);
131
+ // Block forever
132
+ await new Promise(() => { });
133
+ return;
134
+ }
135
+ // Resolve connectors from config
136
+ let resolvedSources;
137
+ let resolvedActors;
138
+ try {
139
+ const resolved = await resolveConnectors(config);
140
+ resolvedSources = resolved.sources;
141
+ resolvedActors = resolved.actors;
142
+ }
143
+ catch (err) {
144
+ output.error(`Connector resolution failed: ${err instanceof Error ? err.message : String(err)}`);
145
+ process.exitCode = 1;
146
+ return;
147
+ }
148
+ // Create persistent checkpoint store
149
+ let checkpointStore;
150
+ try {
151
+ const { FileCheckpointStore } = await import('@orgloop/core');
152
+ checkpointStore = new FileCheckpointStore();
153
+ }
154
+ catch {
155
+ // Fall through — engine will use InMemoryCheckpointStore
156
+ }
157
+ // Resolve package transforms from config
158
+ const resolvedTransforms = new Map();
159
+ for (const tDef of config.transforms) {
160
+ if (tDef.type === 'package' && tDef.package) {
161
+ try {
162
+ const mod = await import(tDef.package);
163
+ if (typeof mod.register === 'function') {
164
+ const reg = mod.register();
165
+ resolvedTransforms.set(tDef.name, new reg.transform());
166
+ }
167
+ }
168
+ catch (err) {
169
+ output.warn(`Transform "${tDef.name}" (${tDef.package}) not available: ${err instanceof Error ? err.message : String(err)}`);
170
+ }
171
+ }
172
+ }
173
+ // Resolve loggers from config
174
+ const resolvedLoggers = new Map();
175
+ for (const loggerDef of config.loggers) {
176
+ try {
177
+ const mod = await import(loggerDef.type);
178
+ if (typeof mod.register === 'function') {
179
+ const reg = mod.register();
180
+ resolvedLoggers.set(loggerDef.name, new reg.logger());
181
+ }
182
+ }
183
+ catch (err) {
184
+ output.warn(`Logger "${loggerDef.name}" (${loggerDef.type}) not available: ${err instanceof Error ? err.message : String(err)}`);
185
+ }
186
+ }
187
+ // Core is available — start the engine
188
+ const engine = new OrgLoop(config, {
189
+ sources: resolvedSources,
190
+ actors: resolvedActors,
191
+ transforms: resolvedTransforms,
192
+ loggers: resolvedLoggers,
193
+ ...(checkpointStore ? { checkpointStore } : {}),
194
+ });
195
+ // Signal handling
196
+ const shutdown = async () => {
197
+ output.blank();
198
+ output.info('Shutting down...');
199
+ await engine.stop();
200
+ const { unlink } = await import('node:fs/promises');
201
+ try {
202
+ await unlink(PID_FILE);
203
+ }
204
+ catch {
205
+ /* ignore */
206
+ }
207
+ process.exit(0);
208
+ };
209
+ process.on('SIGTERM', shutdown);
210
+ process.on('SIGINT', shutdown);
211
+ try {
212
+ // Display progress as components initialize
213
+ for (const s of config.sources) {
214
+ const interval = s.poll?.interval
215
+ ? `polling started (every ${s.poll.interval})`
216
+ : 'hook listener started';
217
+ output.success(`Source ${s.id} — ${interval}`);
218
+ }
219
+ for (const a of config.actors) {
220
+ output.success(`Actor ${a.id} — ready`);
221
+ }
222
+ for (const r of config.routes) {
223
+ output.success(`Route ${r.name} — active`);
224
+ }
225
+ for (const l of config.loggers) {
226
+ output.success(`Logger ${l.name} — configured`);
227
+ }
228
+ await engine.start();
229
+ await saveState(config);
230
+ // Write PID file
231
+ await mkdir(PID_DIR, { recursive: true });
232
+ await writeFile(PID_FILE, String(process.pid), 'utf-8');
233
+ output.blank();
234
+ output.info(`OrgLoop is running. PID: ${process.pid}`);
235
+ output.info('Logs: orgloop logs | Status: orgloop status | Stop: orgloop stop');
236
+ }
237
+ catch (err) {
238
+ output.error(`Failed to start: ${err instanceof Error ? err.message : String(err)}`);
239
+ process.exitCode = 1;
240
+ }
241
+ }
242
+ // ─── Command registration ────────────────────────────────────────────────────
243
+ export function registerApplyCommand(program) {
244
+ program
245
+ .command('apply')
246
+ .description('Start/update the runtime with current config')
247
+ .option('--daemon', 'Run as background daemon')
248
+ .action(async (opts, cmd) => {
249
+ try {
250
+ const globalOpts = cmd.parent?.opts() ?? {};
251
+ if (opts.daemon) {
252
+ // Fork to background
253
+ const config = await loadCliConfig({ configPath: globalOpts.config });
254
+ output.info('Starting OrgLoop daemon...');
255
+ const child = fork(fileURLToPath(import.meta.url), ['--foreground'], {
256
+ detached: true,
257
+ stdio: 'ignore',
258
+ env: {
259
+ ...process.env,
260
+ ORGLOOP_CONFIG: globalOpts.config ?? '',
261
+ ORGLOOP_DAEMON: '1',
262
+ },
263
+ });
264
+ child.unref();
265
+ if (child.pid) {
266
+ await mkdir(PID_DIR, { recursive: true });
267
+ await writeFile(PID_FILE, String(child.pid), 'utf-8');
268
+ output.success(`OrgLoop daemon started. PID: ${child.pid}`);
269
+ output.info(`PID file: ${PID_FILE}`);
270
+ }
271
+ }
272
+ else {
273
+ await runForeground(globalOpts.config);
274
+ }
275
+ }
276
+ catch (err) {
277
+ output.error(`Apply failed: ${err instanceof Error ? err.message : String(err)}`);
278
+ process.exitCode = 1;
279
+ }
280
+ });
281
+ }
282
+ // Handle being run as a forked daemon child
283
+ if (process.env.ORGLOOP_DAEMON === '1') {
284
+ runForeground(process.env.ORGLOOP_CONFIG || undefined).catch((err) => {
285
+ console.error('Daemon failed:', err);
286
+ process.exit(1);
287
+ });
288
+ }
289
+ //# sourceMappingURL=apply.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apply.js","sourceRoot":"","sources":["../../src/commands/apply.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * orgloop doctor — Pre-flight environment validation.
3
+ *
4
+ * Runs validate internally (config, transforms, route graph), then adds
5
+ * live checks: credential validation, service detection. Uses Stage 2
6
+ * connector maturity (credential validators and service detectors) when
7
+ * connectors provide them.
8
+ *
9
+ * Supports --json for machine-readable output.
10
+ */
11
+ import type { CredentialValidator, ServiceDetector } from '@orgloop/sdk';
12
+ import type { Command } from 'commander';
13
+ import { type ImportFn } from '../resolve-connectors.js';
14
+ export interface DoctorCheck {
15
+ category: 'credential' | 'config' | 'transform' | 'route-graph' | 'service';
16
+ name: string;
17
+ status: 'ok' | 'missing' | 'error' | 'warning';
18
+ detail?: string;
19
+ description?: string;
20
+ help_url?: string;
21
+ /** Identity from credential validation (e.g., "user: @alice") */
22
+ identity?: string;
23
+ /** Scopes from credential validation (e.g., ["repo", "read:org"]) */
24
+ scopes?: string[];
25
+ }
26
+ export interface DoctorResult {
27
+ status: 'ok' | 'degraded' | 'error';
28
+ project: string;
29
+ checks: DoctorCheck[];
30
+ }
31
+ /**
32
+ * Run validate internally, converting its results to DoctorCheck format.
33
+ * This is the static analysis phase — config, transforms, route graph.
34
+ */
35
+ export declare function checkValidation(configPath: string): Promise<DoctorCheck[]>;
36
+ export declare function checkCredentials(configPath: string, validators?: Map<string, CredentialValidator>): Promise<DoctorCheck[]>;
37
+ /**
38
+ * Check service availability using service detectors from connector registrations.
39
+ * Connector-agnostic: discovers detectors through the registration, never hardcodes
40
+ * connector-specific logic.
41
+ */
42
+ export declare function checkServices(detectors: Map<string, ServiceDetector>): Promise<DoctorCheck[]>;
43
+ export declare function runDoctor(configPath: string, importFn?: ImportFn): Promise<DoctorResult>;
44
+ export declare function registerDoctorCommand(program: Command): void;
45
+ //# sourceMappingURL=doctor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEzE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKzC,OAAO,EAAE,KAAK,QAAQ,EAAiC,MAAM,0BAA0B,CAAC;AAMxF,MAAM,WAAW,WAAW;IAC3B,QAAQ,EAAE,YAAY,GAAG,QAAQ,GAAG,WAAW,GAAG,aAAa,GAAG,SAAS,CAAC;IAC5E,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,IAAI,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;IAC/C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC5B,MAAM,EAAE,IAAI,GAAG,UAAU,GAAG,OAAO,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,WAAW,EAAE,CAAC;CACtB;AAWD;;;GAGG;AACH,wBAAsB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CA4ChF;AAED,wBAAsB,gBAAgB,CACrC,UAAU,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,GAC3C,OAAO,CAAC,WAAW,EAAE,CAAC,CAiExB;AAED;;;;GAIG;AACH,wBAAsB,aAAa,CAClC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,GACrC,OAAO,CAAC,WAAW,EAAE,CAAC,CAmCxB;AAID,wBAAsB,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC,CA+D9F;AAiFD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA2B5D"}