myvillage-clients-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.
- package/__pycache__/myvillage_cli.cpython-313.pyc +0 -0
- package/bin/cli.js +268 -0
- package/build/myvillage_cli/Analysis-00.toc +1732 -0
- package/build/myvillage_cli/EXE-00.toc +331 -0
- package/build/myvillage_cli/PKG-00.toc +309 -0
- package/build/myvillage_cli/PYZ-00.pyz +0 -0
- package/build/myvillage_cli/PYZ-00.toc +973 -0
- package/build/myvillage_cli/base_library.zip +0 -0
- package/build/myvillage_cli/localpycs/pyimod01_archive.pyc +0 -0
- package/build/myvillage_cli/localpycs/pyimod02_importers.pyc +0 -0
- package/build/myvillage_cli/localpycs/pyimod03_ctypes.pyc +0 -0
- package/build/myvillage_cli/localpycs/pyimod04_pywin32.pyc +0 -0
- package/build/myvillage_cli/localpycs/struct.pyc +0 -0
- package/build/myvillage_cli/myvillage_cli.pkg +0 -0
- package/build/myvillage_cli/warn-myvillage_cli.txt +54 -0
- package/build/myvillage_cli/xref-myvillage_cli.html +14622 -0
- package/dist/myvillage_cli.exe +0 -0
- package/myvillage_cli.py +251 -0
- package/myvillage_cli.spec +38 -0
- package/myvillage_clients_cli.egg-info/PKG-INFO +4 -0
- package/myvillage_clients_cli.egg-info/SOURCES.txt +8 -0
- package/myvillage_clients_cli.egg-info/dependency_links.txt +1 -0
- package/myvillage_clients_cli.egg-info/entry_points.txt +2 -0
- package/myvillage_clients_cli.egg-info/requires.txt +1 -0
- package/myvillage_clients_cli.egg-info/top_level.txt +1 -0
- package/package.json +24 -0
- package/pyproject.toml +11 -0
- package/requirements.txt +1 -0
|
Binary file
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { program } = require('commander');
|
|
4
|
+
const readline = require('readline');
|
|
5
|
+
|
|
6
|
+
const DEFAULT_WEBHOOK_URL = 'https://myvillageproject.app.n8n.cloud/webhook/7c7b9591-54f4-47eb-8b81-6464339a497d';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Pretty print the report data
|
|
10
|
+
*/
|
|
11
|
+
function prettyPrintReport(data) {
|
|
12
|
+
if (Array.isArray(data)) {
|
|
13
|
+
printUpdates(data);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
if (typeof data === 'object' && data !== null) {
|
|
18
|
+
// Handle simple output response
|
|
19
|
+
if (data.output && typeof data.output === 'string') {
|
|
20
|
+
console.log(data.output);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const updates = data.updates || data.items || null;
|
|
25
|
+
const meta = Object.fromEntries(
|
|
26
|
+
Object.entries(data).filter(([k]) => !['updates', 'items'].includes(k))
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
if (Object.keys(meta).length > 0) {
|
|
30
|
+
console.log('== Meta ==');
|
|
31
|
+
for (const [k, v] of Object.entries(meta)) {
|
|
32
|
+
console.log(`- ${k}: ${v}`);
|
|
33
|
+
}
|
|
34
|
+
console.log();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (!updates) {
|
|
38
|
+
console.log('No updates returned.');
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (!Array.isArray(updates)) {
|
|
43
|
+
console.log(typeof updates === 'object' ? JSON.stringify(updates, null, 2) : String(updates));
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
printUpdates(updates);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
console.log(String(data));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function printUpdates(updates) {
|
|
55
|
+
console.log('== GitHub Updates ==');
|
|
56
|
+
updates.forEach((u, i) => {
|
|
57
|
+
const idx = i + 1;
|
|
58
|
+
if (typeof u !== 'object' || u === null) {
|
|
59
|
+
console.log(`${idx}. ${u}`);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const repo = u.repo || u.repository || u.full_name || 'Unknown repo';
|
|
64
|
+
const title = u.title || u.message || u.summary || '';
|
|
65
|
+
const author = u.author || u.user || u.actor || '';
|
|
66
|
+
const url = u.url || u.html_url || u.link || '';
|
|
67
|
+
const ts = u.timestamp || u.time || u.created_at || '';
|
|
68
|
+
|
|
69
|
+
let line = `${idx}. ${repo}`;
|
|
70
|
+
if (title) line += ` — ${title}`;
|
|
71
|
+
console.log(line);
|
|
72
|
+
|
|
73
|
+
const extra = [];
|
|
74
|
+
if (author) extra.push(`by ${author}`);
|
|
75
|
+
if (ts) extra.push(`at ${ts}`);
|
|
76
|
+
if (extra.length > 0) console.log(' ' + extra.join(' | '));
|
|
77
|
+
if (url) console.log(` ${url}`);
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Fetch updates from the webhook
|
|
83
|
+
*/
|
|
84
|
+
async function getUpdates(options) {
|
|
85
|
+
const url = new URL(options.url || DEFAULT_WEBHOOK_URL);
|
|
86
|
+
|
|
87
|
+
if (options.client) url.searchParams.set('client', options.client);
|
|
88
|
+
if (options.since) url.searchParams.set('since', options.since);
|
|
89
|
+
if (options.limit) url.searchParams.set('limit', options.limit);
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
const controller = new AbortController();
|
|
93
|
+
const timeout = setTimeout(() => controller.abort(), (options.timeout || 30) * 1000);
|
|
94
|
+
|
|
95
|
+
const resp = await fetch(url.toString(), {
|
|
96
|
+
method: 'GET',
|
|
97
|
+
signal: controller.signal,
|
|
98
|
+
});
|
|
99
|
+
clearTimeout(timeout);
|
|
100
|
+
|
|
101
|
+
if (resp.status >= 400) {
|
|
102
|
+
const text = await resp.text();
|
|
103
|
+
console.error(`❌ HTTP ${resp.status}`);
|
|
104
|
+
console.error(text.slice(0, 2000));
|
|
105
|
+
process.exit(3);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const text = await resp.text();
|
|
109
|
+
let data;
|
|
110
|
+
try {
|
|
111
|
+
data = JSON.parse(text);
|
|
112
|
+
} catch {
|
|
113
|
+
if (options.json) {
|
|
114
|
+
console.log(JSON.stringify({ raw: text.trim() }));
|
|
115
|
+
} else {
|
|
116
|
+
console.log(text.trim());
|
|
117
|
+
}
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (options.json) {
|
|
122
|
+
console.log(JSON.stringify(data, null, 2));
|
|
123
|
+
} else {
|
|
124
|
+
prettyPrintReport(data);
|
|
125
|
+
}
|
|
126
|
+
} catch (err) {
|
|
127
|
+
if (err.name === 'AbortError') {
|
|
128
|
+
console.error('❌ Request timed out');
|
|
129
|
+
} else {
|
|
130
|
+
console.error(`❌ Request failed: ${err.message}`);
|
|
131
|
+
}
|
|
132
|
+
process.exit(2);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Interactive REPL mode
|
|
138
|
+
*/
|
|
139
|
+
async function interactiveMode() {
|
|
140
|
+
console.log('MyVillage CLI Client Updates - Interactive Mode');
|
|
141
|
+
console.log("Type 'help' for commands, 'exit' to quit.\n");
|
|
142
|
+
|
|
143
|
+
const settings = {
|
|
144
|
+
client: null,
|
|
145
|
+
since: null,
|
|
146
|
+
url: DEFAULT_WEBHOOK_URL,
|
|
147
|
+
timeout: 30,
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
const rl = readline.createInterface({
|
|
151
|
+
input: process.stdin,
|
|
152
|
+
output: process.stdout,
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
const prompt = () => {
|
|
156
|
+
rl.question('myvillage-client-updates> ', async (input) => {
|
|
157
|
+
const userInput = input.trim();
|
|
158
|
+
if (!userInput) {
|
|
159
|
+
prompt();
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const parts = userInput.split(/\s+/);
|
|
164
|
+
const cmd = parts[0].toLowerCase();
|
|
165
|
+
const arg = parts.slice(1).join(' ');
|
|
166
|
+
|
|
167
|
+
switch (cmd) {
|
|
168
|
+
case 'exit':
|
|
169
|
+
case 'quit':
|
|
170
|
+
case 'q':
|
|
171
|
+
console.log('Goodbye!');
|
|
172
|
+
rl.close();
|
|
173
|
+
return;
|
|
174
|
+
|
|
175
|
+
case 'help':
|
|
176
|
+
console.log('Commands:');
|
|
177
|
+
console.log(' updates [client] - Get updates (uses current client if not specified)');
|
|
178
|
+
console.log(' client <name> - Set the current client');
|
|
179
|
+
console.log(' since <date> - Set the since date filter (e.g., 2026-02-01)');
|
|
180
|
+
console.log(' status - Show current settings');
|
|
181
|
+
console.log(' clear - Clear current settings');
|
|
182
|
+
console.log(' exit / quit / q - Exit the CLI');
|
|
183
|
+
break;
|
|
184
|
+
|
|
185
|
+
case 'client':
|
|
186
|
+
if (arg) {
|
|
187
|
+
settings.client = arg;
|
|
188
|
+
console.log(`Client set to: ${arg}`);
|
|
189
|
+
} else {
|
|
190
|
+
console.log(`Current client: ${settings.client || '(not set)'}`);
|
|
191
|
+
}
|
|
192
|
+
break;
|
|
193
|
+
|
|
194
|
+
case 'since':
|
|
195
|
+
if (arg) {
|
|
196
|
+
settings.since = arg;
|
|
197
|
+
console.log(`Since date set to: ${arg}`);
|
|
198
|
+
} else {
|
|
199
|
+
console.log(`Current since: ${settings.since || '(not set)'}`);
|
|
200
|
+
}
|
|
201
|
+
break;
|
|
202
|
+
|
|
203
|
+
case 'status':
|
|
204
|
+
console.log(` Client: ${settings.client || '(not set)'}`);
|
|
205
|
+
console.log(` Since: ${settings.since || '(not set)'}`);
|
|
206
|
+
console.log(` URL: ${settings.url}`);
|
|
207
|
+
console.log(` Timeout: ${settings.timeout}s`);
|
|
208
|
+
break;
|
|
209
|
+
|
|
210
|
+
case 'clear':
|
|
211
|
+
settings.client = null;
|
|
212
|
+
settings.since = null;
|
|
213
|
+
console.log('Settings cleared.');
|
|
214
|
+
break;
|
|
215
|
+
|
|
216
|
+
case 'updates':
|
|
217
|
+
const client = arg || settings.client;
|
|
218
|
+
if (!client) {
|
|
219
|
+
console.log("No client specified. Use 'client <name>' or 'updates <client>'");
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
await getUpdates({
|
|
223
|
+
url: settings.url,
|
|
224
|
+
client,
|
|
225
|
+
since: settings.since,
|
|
226
|
+
timeout: settings.timeout,
|
|
227
|
+
json: false,
|
|
228
|
+
});
|
|
229
|
+
break;
|
|
230
|
+
|
|
231
|
+
default:
|
|
232
|
+
console.log(`Unknown command: ${cmd}. Type 'help' for available commands.`);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
prompt();
|
|
236
|
+
});
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
rl.on('close', () => {
|
|
240
|
+
process.exit(0);
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
prompt();
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// CLI setup with commander
|
|
247
|
+
program
|
|
248
|
+
.name('myvillage-clients-cli')
|
|
249
|
+
.description('MyVillage CLI - report client GitHub updates via n8n webhook')
|
|
250
|
+
.version('0.1.0');
|
|
251
|
+
|
|
252
|
+
program
|
|
253
|
+
.command('get-updates')
|
|
254
|
+
.description('Fetch and print client GitHub updates (via n8n webhook)')
|
|
255
|
+
.option('--url <url>', 'Override webhook URL', DEFAULT_WEBHOOK_URL)
|
|
256
|
+
.option('--client <name>', 'Client name/id used by your n8n workflow')
|
|
257
|
+
.option('--since <date>', 'ISO date/time filter, e.g. "2026-02-01"')
|
|
258
|
+
.option('--limit <number>', 'Limit number of updates returned', parseInt)
|
|
259
|
+
.option('--timeout <seconds>', 'Request timeout (seconds)', parseInt, 30)
|
|
260
|
+
.option('--json', 'Print raw JSON instead of a formatted report', false)
|
|
261
|
+
.action(getUpdates);
|
|
262
|
+
|
|
263
|
+
// If no arguments, run interactive mode
|
|
264
|
+
if (process.argv.length <= 2) {
|
|
265
|
+
interactiveMode();
|
|
266
|
+
} else {
|
|
267
|
+
program.parse();
|
|
268
|
+
}
|