@kernelius/forge-cli 0.2.1 → 0.3.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/CHANGELOG.md +30 -0
- package/README.md +49 -0
- package/dist/index.js +533 -210
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import { Command as
|
|
4
|
+
import { Command as Command8 } from "commander";
|
|
5
5
|
import { readFileSync } from "fs";
|
|
6
6
|
import { fileURLToPath } from "url";
|
|
7
7
|
import { dirname, join as join2 } from "path";
|
|
@@ -301,11 +301,318 @@ function createAuthCommand() {
|
|
|
301
301
|
}
|
|
302
302
|
|
|
303
303
|
// src/commands/repos.ts
|
|
304
|
+
import { Command as Command3 } from "commander";
|
|
305
|
+
import chalk3 from "chalk";
|
|
306
|
+
import { spawn } from "child_process";
|
|
307
|
+
|
|
308
|
+
// src/commands/templates.ts
|
|
304
309
|
import { Command as Command2 } from "commander";
|
|
305
310
|
import chalk2 from "chalk";
|
|
306
|
-
|
|
311
|
+
var HEALTHCARE_TEMPLATES = [
|
|
312
|
+
{
|
|
313
|
+
id: "patient-record",
|
|
314
|
+
name: "Patient Record",
|
|
315
|
+
description: "FHIR-compliant patient medical record repository",
|
|
316
|
+
icon: "User",
|
|
317
|
+
orgType: "healthcare",
|
|
318
|
+
metadata: {
|
|
319
|
+
repoType: "patient-record",
|
|
320
|
+
tags: ["patient", "medical-record"],
|
|
321
|
+
domainData: {
|
|
322
|
+
healthcare: {
|
|
323
|
+
resourceType: "Patient",
|
|
324
|
+
fhirVersion: "R4"
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
namingPattern: "patient-{name}",
|
|
329
|
+
namingExample: "patient-john-doe",
|
|
330
|
+
initialFiles: []
|
|
331
|
+
},
|
|
332
|
+
{
|
|
333
|
+
id: "fhir-resource",
|
|
334
|
+
name: "FHIR Resource Collection",
|
|
335
|
+
description: "Collection of FHIR resources (observations, conditions, etc.)",
|
|
336
|
+
icon: "FileJson",
|
|
337
|
+
orgType: "healthcare",
|
|
338
|
+
metadata: {
|
|
339
|
+
repoType: "fhir",
|
|
340
|
+
tags: ["fhir", "resources"],
|
|
341
|
+
domainData: {
|
|
342
|
+
healthcare: {
|
|
343
|
+
fhirVersion: "R4"
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
},
|
|
347
|
+
namingPattern: "fhir-{resource-type}",
|
|
348
|
+
namingExample: "fhir-observations-2026",
|
|
349
|
+
initialFiles: []
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
id: "medical-protocol",
|
|
353
|
+
name: "Medical Protocol",
|
|
354
|
+
description: "Clinical protocol or treatment guideline",
|
|
355
|
+
icon: "FileText",
|
|
356
|
+
orgType: "healthcare",
|
|
357
|
+
metadata: {
|
|
358
|
+
repoType: "protocol",
|
|
359
|
+
tags: ["protocol", "guidelines"]
|
|
360
|
+
},
|
|
361
|
+
namingPattern: "protocol-{name}",
|
|
362
|
+
namingExample: "protocol-diabetes-management",
|
|
363
|
+
initialFiles: []
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
id: "clinical-study",
|
|
367
|
+
name: "Clinical Study",
|
|
368
|
+
description: "Clinical trial or research study data",
|
|
369
|
+
icon: "FlaskConical",
|
|
370
|
+
orgType: "healthcare",
|
|
371
|
+
metadata: {
|
|
372
|
+
repoType: "experiment",
|
|
373
|
+
tags: ["clinical-trial", "research"]
|
|
374
|
+
},
|
|
375
|
+
namingPattern: "study-{name}",
|
|
376
|
+
namingExample: "study-drug-efficacy-2026",
|
|
377
|
+
initialFiles: []
|
|
378
|
+
}
|
|
379
|
+
];
|
|
380
|
+
var RESEARCH_TEMPLATES = [
|
|
381
|
+
{
|
|
382
|
+
id: "research-dataset",
|
|
383
|
+
name: "Research Dataset",
|
|
384
|
+
description: "Versioned research dataset with metadata",
|
|
385
|
+
icon: "Database",
|
|
386
|
+
orgType: "research",
|
|
387
|
+
metadata: {
|
|
388
|
+
repoType: "dataset",
|
|
389
|
+
tags: ["dataset", "data"]
|
|
390
|
+
},
|
|
391
|
+
namingPattern: "{topic}-dataset",
|
|
392
|
+
namingExample: "climate-data-2026",
|
|
393
|
+
initialFiles: []
|
|
394
|
+
},
|
|
395
|
+
{
|
|
396
|
+
id: "research-experiment",
|
|
397
|
+
name: "Research Experiment",
|
|
398
|
+
description: "Experimental study with methodology and results",
|
|
399
|
+
icon: "FlaskConical",
|
|
400
|
+
orgType: "research",
|
|
401
|
+
metadata: {
|
|
402
|
+
repoType: "experiment",
|
|
403
|
+
tags: ["experiment", "study"]
|
|
404
|
+
},
|
|
405
|
+
namingPattern: "experiment-{name}",
|
|
406
|
+
namingExample: "experiment-protein-analysis",
|
|
407
|
+
initialFiles: []
|
|
408
|
+
},
|
|
409
|
+
{
|
|
410
|
+
id: "research-publication",
|
|
411
|
+
name: "Research Publication",
|
|
412
|
+
description: "Academic paper with LaTeX source and supplementary materials",
|
|
413
|
+
icon: "BookOpen",
|
|
414
|
+
orgType: "research",
|
|
415
|
+
metadata: {
|
|
416
|
+
repoType: "publication",
|
|
417
|
+
tags: ["paper", "publication"]
|
|
418
|
+
},
|
|
419
|
+
namingPattern: "paper-{title}",
|
|
420
|
+
namingExample: "paper-ml-genomics-2026",
|
|
421
|
+
initialFiles: []
|
|
422
|
+
},
|
|
423
|
+
{
|
|
424
|
+
id: "research-analysis",
|
|
425
|
+
name: "Data Analysis",
|
|
426
|
+
description: "Statistical analysis and computational notebooks",
|
|
427
|
+
icon: "TrendingUp",
|
|
428
|
+
orgType: "research",
|
|
429
|
+
metadata: {
|
|
430
|
+
repoType: "analysis",
|
|
431
|
+
tags: ["analysis", "statistics"]
|
|
432
|
+
},
|
|
433
|
+
namingPattern: "analysis-{topic}",
|
|
434
|
+
namingExample: "analysis-gene-expression",
|
|
435
|
+
initialFiles: []
|
|
436
|
+
}
|
|
437
|
+
];
|
|
438
|
+
var COMPANY_TEMPLATES = [
|
|
439
|
+
{
|
|
440
|
+
id: "code-repository",
|
|
441
|
+
name: "Code Repository",
|
|
442
|
+
description: "Standard software project",
|
|
443
|
+
icon: "Code",
|
|
444
|
+
orgType: "company",
|
|
445
|
+
metadata: {
|
|
446
|
+
repoType: "code",
|
|
447
|
+
tags: ["code", "software"]
|
|
448
|
+
},
|
|
449
|
+
namingPattern: "{project-name}",
|
|
450
|
+
namingExample: "web-app",
|
|
451
|
+
initialFiles: []
|
|
452
|
+
}
|
|
453
|
+
];
|
|
454
|
+
var EDUCATION_TEMPLATES = [
|
|
455
|
+
{
|
|
456
|
+
id: "course-materials",
|
|
457
|
+
name: "Course Materials",
|
|
458
|
+
description: "Course curriculum and lecture materials",
|
|
459
|
+
icon: "GraduationCap",
|
|
460
|
+
orgType: "education",
|
|
461
|
+
metadata: {
|
|
462
|
+
repoType: "course",
|
|
463
|
+
tags: ["course", "curriculum"]
|
|
464
|
+
},
|
|
465
|
+
namingPattern: "{course-code}-{title}",
|
|
466
|
+
namingExample: "cs101-intro-programming",
|
|
467
|
+
initialFiles: []
|
|
468
|
+
}
|
|
469
|
+
];
|
|
470
|
+
var NONPROFIT_TEMPLATES = [
|
|
471
|
+
{
|
|
472
|
+
id: "campaign",
|
|
473
|
+
name: "Campaign",
|
|
474
|
+
description: "Fundraising or advocacy campaign materials",
|
|
475
|
+
icon: "Megaphone",
|
|
476
|
+
orgType: "nonprofit",
|
|
477
|
+
metadata: {
|
|
478
|
+
repoType: "campaign",
|
|
479
|
+
tags: ["campaign", "advocacy"]
|
|
480
|
+
},
|
|
481
|
+
namingPattern: "campaign-{name}",
|
|
482
|
+
namingExample: "campaign-clean-water-2026",
|
|
483
|
+
initialFiles: []
|
|
484
|
+
}
|
|
485
|
+
];
|
|
486
|
+
var REPO_TEMPLATES = {
|
|
487
|
+
healthcare: HEALTHCARE_TEMPLATES,
|
|
488
|
+
research: RESEARCH_TEMPLATES,
|
|
489
|
+
company: COMPANY_TEMPLATES,
|
|
490
|
+
education: EDUCATION_TEMPLATES,
|
|
491
|
+
nonprofit: NONPROFIT_TEMPLATES,
|
|
492
|
+
generic: COMPANY_TEMPLATES
|
|
493
|
+
};
|
|
494
|
+
function getAllTemplates() {
|
|
495
|
+
return Object.values(REPO_TEMPLATES).flat();
|
|
496
|
+
}
|
|
497
|
+
function getTemplatesForOrgType(orgType) {
|
|
498
|
+
return REPO_TEMPLATES[orgType || "generic"] || COMPANY_TEMPLATES;
|
|
499
|
+
}
|
|
500
|
+
function getTemplateById(templateId) {
|
|
501
|
+
for (const templates of Object.values(REPO_TEMPLATES)) {
|
|
502
|
+
const template = templates.find((t) => t.id === templateId);
|
|
503
|
+
if (template) return template;
|
|
504
|
+
}
|
|
505
|
+
return void 0;
|
|
506
|
+
}
|
|
507
|
+
function getOrgTypeIcon(orgType) {
|
|
508
|
+
const icons = {
|
|
509
|
+
healthcare: "\u{1F3E5}",
|
|
510
|
+
research: "\u{1F52C}",
|
|
511
|
+
company: "\u{1F3E2}",
|
|
512
|
+
education: "\u{1F393}",
|
|
513
|
+
nonprofit: "\u{1F91D}",
|
|
514
|
+
generic: "\u{1F4E6}"
|
|
515
|
+
};
|
|
516
|
+
return icons[orgType] || "\u{1F4E6}";
|
|
517
|
+
}
|
|
518
|
+
function createTemplatesCommand() {
|
|
519
|
+
const templates = new Command2("templates").description(
|
|
520
|
+
"Manage repository templates"
|
|
521
|
+
);
|
|
522
|
+
templates.command("list").description("List available repository templates").option("--org-type <type>", "Filter by organization type (healthcare, research, company, education, nonprofit)").action((options) => {
|
|
523
|
+
try {
|
|
524
|
+
let templateList;
|
|
525
|
+
if (options.orgType) {
|
|
526
|
+
const orgType = options.orgType;
|
|
527
|
+
if (!REPO_TEMPLATES[orgType]) {
|
|
528
|
+
console.error(chalk2.red(`Error: Invalid org type "${orgType}"`));
|
|
529
|
+
console.log(chalk2.dim("\nAvailable types: healthcare, research, company, education, nonprofit"));
|
|
530
|
+
process.exit(1);
|
|
531
|
+
}
|
|
532
|
+
templateList = getTemplatesForOrgType(orgType);
|
|
533
|
+
console.log(chalk2.bold(`${getOrgTypeIcon(orgType)} ${orgType.charAt(0).toUpperCase() + orgType.slice(1)} Templates
|
|
534
|
+
`));
|
|
535
|
+
} else {
|
|
536
|
+
templateList = getAllTemplates();
|
|
537
|
+
console.log(chalk2.bold("Available Repository Templates\n"));
|
|
538
|
+
}
|
|
539
|
+
if (templateList.length === 0) {
|
|
540
|
+
console.log(chalk2.yellow("No templates found"));
|
|
541
|
+
return;
|
|
542
|
+
}
|
|
543
|
+
if (!options.orgType) {
|
|
544
|
+
const grouped = templateList.reduce((acc, template) => {
|
|
545
|
+
if (!acc[template.orgType]) {
|
|
546
|
+
acc[template.orgType] = [];
|
|
547
|
+
}
|
|
548
|
+
acc[template.orgType].push(template);
|
|
549
|
+
return acc;
|
|
550
|
+
}, {});
|
|
551
|
+
for (const [orgType, templates2] of Object.entries(grouped)) {
|
|
552
|
+
console.log(chalk2.bold(`${getOrgTypeIcon(orgType)} ${orgType.charAt(0).toUpperCase() + orgType.slice(1)}`));
|
|
553
|
+
for (const template of templates2) {
|
|
554
|
+
console.log(` ${chalk2.cyan(template.id.padEnd(25))} ${chalk2.dim(template.name)}`);
|
|
555
|
+
console.log(` ${" ".repeat(25)} ${chalk2.dim(template.description)}`);
|
|
556
|
+
}
|
|
557
|
+
console.log();
|
|
558
|
+
}
|
|
559
|
+
} else {
|
|
560
|
+
for (const template of templateList) {
|
|
561
|
+
console.log(`${chalk2.cyan(template.id.padEnd(25))} ${chalk2.dim(template.name)}`);
|
|
562
|
+
console.log(`${" ".repeat(25)} ${chalk2.dim(template.description)}`);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
console.log(chalk2.dim("\nUse 'forge templates view <id>' to see details"));
|
|
566
|
+
} catch (error) {
|
|
567
|
+
console.error(chalk2.red(`Error: ${error.message}`));
|
|
568
|
+
process.exit(1);
|
|
569
|
+
}
|
|
570
|
+
});
|
|
571
|
+
templates.command("view").description("View template details").argument("<id>", "Template ID").action((templateId) => {
|
|
572
|
+
try {
|
|
573
|
+
const template = getTemplateById(templateId);
|
|
574
|
+
if (!template) {
|
|
575
|
+
console.error(chalk2.red(`Error: Template "${templateId}" not found`));
|
|
576
|
+
console.log(chalk2.dim("\nUse 'forge templates list' to see available templates"));
|
|
577
|
+
process.exit(1);
|
|
578
|
+
}
|
|
579
|
+
console.log(chalk2.bold(`${template.name}
|
|
580
|
+
`));
|
|
581
|
+
console.log(chalk2.dim("ID: ") + chalk2.cyan(template.id));
|
|
582
|
+
console.log(chalk2.dim("Type: ") + `${getOrgTypeIcon(template.orgType)} ${template.orgType}`);
|
|
583
|
+
console.log(chalk2.dim("Description: ") + template.description);
|
|
584
|
+
console.log();
|
|
585
|
+
console.log(chalk2.bold("Naming Pattern"));
|
|
586
|
+
console.log(chalk2.dim(" Pattern: ") + template.namingPattern);
|
|
587
|
+
console.log(chalk2.dim(" Example: ") + chalk2.cyan(template.namingExample));
|
|
588
|
+
console.log();
|
|
589
|
+
if (template.metadata) {
|
|
590
|
+
console.log(chalk2.bold("Metadata"));
|
|
591
|
+
if (template.metadata.repoType) {
|
|
592
|
+
console.log(chalk2.dim(" Repo Type: ") + template.metadata.repoType);
|
|
593
|
+
}
|
|
594
|
+
if (template.metadata.tags && template.metadata.tags.length > 0) {
|
|
595
|
+
console.log(chalk2.dim(" Tags: ") + template.metadata.tags.join(", "));
|
|
596
|
+
}
|
|
597
|
+
if (template.metadata.domainData) {
|
|
598
|
+
console.log(chalk2.dim(" Domain: ") + JSON.stringify(template.metadata.domainData, null, 2).split("\n").join("\n "));
|
|
599
|
+
}
|
|
600
|
+
console.log();
|
|
601
|
+
}
|
|
602
|
+
console.log(chalk2.bold("Usage"));
|
|
603
|
+
console.log(chalk2.dim(" forge repos create --name ") + chalk2.cyan(template.namingExample) + chalk2.dim(" --template ") + chalk2.cyan(template.id));
|
|
604
|
+
console.log();
|
|
605
|
+
} catch (error) {
|
|
606
|
+
console.error(chalk2.red(`Error: ${error.message}`));
|
|
607
|
+
process.exit(1);
|
|
608
|
+
}
|
|
609
|
+
});
|
|
610
|
+
return templates;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
// src/commands/repos.ts
|
|
307
614
|
function createReposCommand() {
|
|
308
|
-
const repos = new
|
|
615
|
+
const repos = new Command3("repos").description(
|
|
309
616
|
"Manage repositories"
|
|
310
617
|
);
|
|
311
618
|
repos.command("list").description("List accessible repositories").action(async () => {
|
|
@@ -316,22 +623,22 @@ function createReposCommand() {
|
|
|
316
623
|
);
|
|
317
624
|
const repositories = result.repos || [];
|
|
318
625
|
if (repositories.length === 0) {
|
|
319
|
-
console.log(
|
|
626
|
+
console.log(chalk3.yellow("No repositories found"));
|
|
320
627
|
return;
|
|
321
628
|
}
|
|
322
|
-
console.log(
|
|
629
|
+
console.log(chalk3.bold(`Repositories (${repositories.length})`));
|
|
323
630
|
console.log();
|
|
324
631
|
for (const repo of repositories) {
|
|
325
632
|
const ownerName = repo.owner?.identifier || repo.owner?.username || user.username;
|
|
326
633
|
const identifier = `@${ownerName}/${repo.name}`;
|
|
327
634
|
const visibility = repo.visibility === "private" ? "\u{1F512}" : "\u{1F310}";
|
|
328
|
-
console.log(`${visibility} ${
|
|
635
|
+
console.log(`${visibility} ${chalk3.cyan(identifier)}`);
|
|
329
636
|
if (repo.description) {
|
|
330
|
-
console.log(
|
|
637
|
+
console.log(chalk3.dim(` ${repo.description}`));
|
|
331
638
|
}
|
|
332
639
|
}
|
|
333
640
|
} catch (error) {
|
|
334
|
-
console.error(
|
|
641
|
+
console.error(chalk3.red(`Error: ${error.message}`));
|
|
335
642
|
process.exit(1);
|
|
336
643
|
}
|
|
337
644
|
});
|
|
@@ -341,16 +648,16 @@ function createReposCommand() {
|
|
|
341
648
|
const repo = await apiGet(
|
|
342
649
|
`/api/repositories/${ownerIdentifier}/${name}`
|
|
343
650
|
);
|
|
344
|
-
console.log(
|
|
651
|
+
console.log(chalk3.bold(`${repo.ownerIdentifier}/${repo.name}`));
|
|
345
652
|
if (repo.description) {
|
|
346
|
-
console.log(
|
|
653
|
+
console.log(chalk3.dim(repo.description));
|
|
347
654
|
}
|
|
348
655
|
console.log();
|
|
349
|
-
console.log(
|
|
350
|
-
console.log(
|
|
351
|
-
console.log(
|
|
656
|
+
console.log(chalk3.dim(` Visibility: ${repo.visibility}`));
|
|
657
|
+
console.log(chalk3.dim(` Type: ${repo.repoType || "standard"}`));
|
|
658
|
+
console.log(chalk3.dim(` Created: ${new Date(repo.createdAt).toLocaleDateString()}`));
|
|
352
659
|
} catch (error) {
|
|
353
|
-
console.error(
|
|
660
|
+
console.error(chalk3.red(`Error: ${error.message}`));
|
|
354
661
|
process.exit(1);
|
|
355
662
|
}
|
|
356
663
|
});
|
|
@@ -362,7 +669,7 @@ function createReposCommand() {
|
|
|
362
669
|
const apiUrl = new URL(config.apiUrl);
|
|
363
670
|
const cloneUrl = `${apiUrl.protocol}//${apiUrl.host}/git/${ownerIdentifier}/${name}`;
|
|
364
671
|
const dest = destination || name;
|
|
365
|
-
console.log(
|
|
672
|
+
console.log(chalk3.dim(`Cloning ${ownerIdentifier}/${name} into ${dest}...`));
|
|
366
673
|
const gitProcess = spawn(
|
|
367
674
|
"git",
|
|
368
675
|
["clone", cloneUrl, dest],
|
|
@@ -383,27 +690,42 @@ function createReposCommand() {
|
|
|
383
690
|
}
|
|
384
691
|
});
|
|
385
692
|
});
|
|
386
|
-
console.log(
|
|
693
|
+
console.log(chalk3.green(`\u2713 Repository cloned successfully`));
|
|
387
694
|
} catch (error) {
|
|
388
|
-
console.error(
|
|
695
|
+
console.error(chalk3.red(`Error: ${error.message}`));
|
|
389
696
|
process.exit(1);
|
|
390
697
|
}
|
|
391
698
|
});
|
|
392
|
-
repos.command("create").description("Create a new repository").requiredOption("--name <name>", "Repository name").option("--description <desc>", "Repository description").option("--visibility <type>", "Visibility (public/private)", "private").option("--org <identifier>", "Organization identifier (defaults to your personal org)").action(async (options) => {
|
|
699
|
+
repos.command("create").description("Create a new repository").requiredOption("--name <name>", "Repository name").option("--description <desc>", "Repository description").option("--visibility <type>", "Visibility (public/private)", "private").option("--org <identifier>", "Organization identifier (defaults to your personal org)").option("--template <id>", "Repository template ID (e.g., patient-record, research-dataset, code-repository)").action(async (options) => {
|
|
393
700
|
try {
|
|
394
|
-
const { name, description, visibility, org } = options;
|
|
701
|
+
const { name, description, visibility, org, template } = options;
|
|
702
|
+
if (template) {
|
|
703
|
+
const templateObj = getTemplateById(template);
|
|
704
|
+
if (!templateObj) {
|
|
705
|
+
console.error(chalk3.red(`Error: Template "${template}" not found`));
|
|
706
|
+
console.log(chalk3.dim("\nAvailable templates:"));
|
|
707
|
+
console.log(chalk3.dim(" Use 'forge templates list' to see all available templates"));
|
|
708
|
+
console.log(chalk3.dim(" Use 'forge templates view <id>' to see template details"));
|
|
709
|
+
process.exit(1);
|
|
710
|
+
}
|
|
711
|
+
}
|
|
395
712
|
const user = await apiGet("/api/users/me");
|
|
396
713
|
const orgIdentifier = org || user.username;
|
|
397
714
|
const repo = await apiPost("/api/repositories", {
|
|
398
715
|
name,
|
|
399
716
|
description,
|
|
400
717
|
visibility,
|
|
401
|
-
orgIdentifier
|
|
718
|
+
orgIdentifier,
|
|
719
|
+
templateId: template
|
|
402
720
|
});
|
|
403
|
-
console.log(
|
|
404
|
-
console.log(
|
|
721
|
+
console.log(chalk3.green("\u2713 Repository created successfully"));
|
|
722
|
+
console.log(chalk3.dim(` @${repo.ownerIdentifier}/${repo.name}`));
|
|
723
|
+
if (template) {
|
|
724
|
+
const templateObj = getTemplateById(template);
|
|
725
|
+
console.log(chalk3.dim(` Template: ${templateObj?.name || template}`));
|
|
726
|
+
}
|
|
405
727
|
} catch (error) {
|
|
406
|
-
console.error(
|
|
728
|
+
console.error(chalk3.red(`Error: ${error.message}`));
|
|
407
729
|
process.exit(1);
|
|
408
730
|
}
|
|
409
731
|
});
|
|
@@ -419,11 +741,11 @@ function createReposCommand() {
|
|
|
419
741
|
orgIdentifier: targetOrgIdentifier
|
|
420
742
|
}
|
|
421
743
|
);
|
|
422
|
-
console.log(
|
|
423
|
-
console.log(
|
|
424
|
-
console.log(
|
|
744
|
+
console.log(chalk3.green("\u2713 Repository forked successfully"));
|
|
745
|
+
console.log(chalk3.dim(` @${fork.ownerIdentifier}/${fork.name}`));
|
|
746
|
+
console.log(chalk3.dim(` Forked from @${ownerIdentifier}/${name}`));
|
|
425
747
|
} catch (error) {
|
|
426
|
-
console.error(
|
|
748
|
+
console.error(chalk3.red(`Error: ${error.message}`));
|
|
427
749
|
process.exit(1);
|
|
428
750
|
}
|
|
429
751
|
});
|
|
@@ -434,9 +756,9 @@ function createReposCommand() {
|
|
|
434
756
|
`/api/repositories/${ownerIdentifier}/${name}/star`,
|
|
435
757
|
{}
|
|
436
758
|
);
|
|
437
|
-
console.log(
|
|
759
|
+
console.log(chalk3.green(`\u2713 Starred @${ownerIdentifier}/${name}`));
|
|
438
760
|
} catch (error) {
|
|
439
|
-
console.error(
|
|
761
|
+
console.error(chalk3.red(`Error: ${error.message}`));
|
|
440
762
|
process.exit(1);
|
|
441
763
|
}
|
|
442
764
|
});
|
|
@@ -447,9 +769,9 @@ function createReposCommand() {
|
|
|
447
769
|
`/api/repositories/${ownerIdentifier}/${name}/unstar`,
|
|
448
770
|
{}
|
|
449
771
|
);
|
|
450
|
-
console.log(
|
|
772
|
+
console.log(chalk3.green(`\u2713 Unstarred @${ownerIdentifier}/${name}`));
|
|
451
773
|
} catch (error) {
|
|
452
|
-
console.error(
|
|
774
|
+
console.error(chalk3.red(`Error: ${error.message}`));
|
|
453
775
|
process.exit(1);
|
|
454
776
|
}
|
|
455
777
|
});
|
|
@@ -461,22 +783,22 @@ function createReposCommand() {
|
|
|
461
783
|
);
|
|
462
784
|
const stars = result.stars || [];
|
|
463
785
|
if (stars.length === 0) {
|
|
464
|
-
console.log(
|
|
786
|
+
console.log(chalk3.yellow("No starred repositories"));
|
|
465
787
|
return;
|
|
466
788
|
}
|
|
467
|
-
console.log(
|
|
789
|
+
console.log(chalk3.bold(`Starred Repositories (${stars.length})`));
|
|
468
790
|
console.log();
|
|
469
791
|
for (const star of stars) {
|
|
470
792
|
const repo = star.repository;
|
|
471
793
|
const identifier = `@${repo.ownerIdentifier}/${repo.name}`;
|
|
472
794
|
const visibility = repo.visibility === "private" ? "\u{1F512}" : "\u{1F310}";
|
|
473
|
-
console.log(`${visibility} ${
|
|
795
|
+
console.log(`${visibility} ${chalk3.cyan(identifier)}`);
|
|
474
796
|
if (repo.description) {
|
|
475
|
-
console.log(
|
|
797
|
+
console.log(chalk3.dim(` ${repo.description}`));
|
|
476
798
|
}
|
|
477
799
|
}
|
|
478
800
|
} catch (error) {
|
|
479
|
-
console.error(
|
|
801
|
+
console.error(chalk3.red(`Error: ${error.message}`));
|
|
480
802
|
process.exit(1);
|
|
481
803
|
}
|
|
482
804
|
});
|
|
@@ -488,19 +810,19 @@ function createReposCommand() {
|
|
|
488
810
|
if (options.description !== void 0) updates.description = options.description;
|
|
489
811
|
if (options.visibility) updates.visibility = options.visibility;
|
|
490
812
|
if (Object.keys(updates).length === 0) {
|
|
491
|
-
console.log(
|
|
813
|
+
console.log(chalk3.yellow("No updates specified. Use --name, --description, or --visibility"));
|
|
492
814
|
return;
|
|
493
815
|
}
|
|
494
816
|
await apiPost(
|
|
495
817
|
`/api/repositories/${ownerIdentifier}/${name}/settings`,
|
|
496
818
|
updates
|
|
497
819
|
);
|
|
498
|
-
console.log(
|
|
820
|
+
console.log(chalk3.green("\u2713 Repository updated successfully"));
|
|
499
821
|
if (options.name) {
|
|
500
|
-
console.log(
|
|
822
|
+
console.log(chalk3.dim(` Renamed to: ${options.name}`));
|
|
501
823
|
}
|
|
502
824
|
} catch (error) {
|
|
503
|
-
console.error(
|
|
825
|
+
console.error(chalk3.red(`Error: ${error.message}`));
|
|
504
826
|
process.exit(1);
|
|
505
827
|
}
|
|
506
828
|
});
|
|
@@ -508,17 +830,17 @@ function createReposCommand() {
|
|
|
508
830
|
try {
|
|
509
831
|
const [ownerIdentifier, name] = parseRepoArg(repoArg);
|
|
510
832
|
if (!options.confirm) {
|
|
511
|
-
console.log(
|
|
512
|
-
console.log(
|
|
833
|
+
console.log(chalk3.yellow(`\u26A0\uFE0F WARNING: This will permanently delete @${ownerIdentifier}/${name}`));
|
|
834
|
+
console.log(chalk3.dim("Run with --confirm to proceed"));
|
|
513
835
|
process.exit(1);
|
|
514
836
|
}
|
|
515
837
|
await apiPost(
|
|
516
838
|
`/api/repositories/${ownerIdentifier}/${name}/delete`,
|
|
517
839
|
{}
|
|
518
840
|
);
|
|
519
|
-
console.log(
|
|
841
|
+
console.log(chalk3.green(`\u2713 Repository @${ownerIdentifier}/${name} deleted`));
|
|
520
842
|
} catch (error) {
|
|
521
|
-
console.error(
|
|
843
|
+
console.error(chalk3.red(`Error: ${error.message}`));
|
|
522
844
|
process.exit(1);
|
|
523
845
|
}
|
|
524
846
|
});
|
|
@@ -535,10 +857,10 @@ function parseRepoArg(arg) {
|
|
|
535
857
|
}
|
|
536
858
|
|
|
537
859
|
// src/commands/issues.ts
|
|
538
|
-
import { Command as
|
|
539
|
-
import
|
|
860
|
+
import { Command as Command4 } from "commander";
|
|
861
|
+
import chalk4 from "chalk";
|
|
540
862
|
function createIssuesCommand() {
|
|
541
|
-
const issues = new
|
|
863
|
+
const issues = new Command4("issues").description("Manage issues");
|
|
542
864
|
issues.command("list").description("List issues in a repository").requiredOption("--repo <repo>", "Repository (@owner/name)").option("--state <state>", "Filter by state (open/closed)", "open").action(async (options) => {
|
|
543
865
|
try {
|
|
544
866
|
const [ownerIdentifier, name] = parseRepoArg2(options.repo);
|
|
@@ -547,24 +869,24 @@ function createIssuesCommand() {
|
|
|
547
869
|
);
|
|
548
870
|
const issuesList = result.issues || [];
|
|
549
871
|
if (issuesList.length === 0) {
|
|
550
|
-
console.log(
|
|
872
|
+
console.log(chalk4.yellow(`No ${options.state} issues found`));
|
|
551
873
|
return;
|
|
552
874
|
}
|
|
553
875
|
console.log(
|
|
554
|
-
|
|
876
|
+
chalk4.bold(`Issues in @${ownerIdentifier}/${name} (${issuesList.length})`)
|
|
555
877
|
);
|
|
556
878
|
console.log();
|
|
557
879
|
for (const issue of issuesList) {
|
|
558
880
|
const stateIcon = issue.state === "open" ? "\u{1F7E2}" : "\u26AA";
|
|
559
881
|
console.log(
|
|
560
|
-
`${stateIcon} #${issue.number} ${
|
|
882
|
+
`${stateIcon} #${issue.number} ${chalk4.cyan(issue.title)}`
|
|
561
883
|
);
|
|
562
884
|
console.log(
|
|
563
|
-
|
|
885
|
+
chalk4.dim(` by @${issue.author?.username || "unknown"} \xB7 ${new Date(issue.createdAt).toLocaleDateString()}`)
|
|
564
886
|
);
|
|
565
887
|
}
|
|
566
888
|
} catch (error) {
|
|
567
|
-
console.error(
|
|
889
|
+
console.error(chalk4.red(`Error: ${error.message}`));
|
|
568
890
|
process.exit(1);
|
|
569
891
|
}
|
|
570
892
|
});
|
|
@@ -576,10 +898,10 @@ function createIssuesCommand() {
|
|
|
576
898
|
);
|
|
577
899
|
const stateIcon = issue.state === "open" ? "\u{1F7E2}" : "\u26AA";
|
|
578
900
|
console.log(
|
|
579
|
-
`${stateIcon} ${
|
|
901
|
+
`${stateIcon} ${chalk4.bold(`#${issue.number} ${issue.title}`)}`
|
|
580
902
|
);
|
|
581
903
|
console.log(
|
|
582
|
-
|
|
904
|
+
chalk4.dim(
|
|
583
905
|
`by @${issue.author.username} \xB7 ${new Date(issue.createdAt).toLocaleDateString()}`
|
|
584
906
|
)
|
|
585
907
|
);
|
|
@@ -588,14 +910,14 @@ function createIssuesCommand() {
|
|
|
588
910
|
console.log(issue.body);
|
|
589
911
|
console.log();
|
|
590
912
|
}
|
|
591
|
-
console.log(
|
|
913
|
+
console.log(chalk4.dim(`State: ${issue.state}`));
|
|
592
914
|
if (issue.closedAt) {
|
|
593
915
|
console.log(
|
|
594
|
-
|
|
916
|
+
chalk4.dim(`Closed: ${new Date(issue.closedAt).toLocaleDateString()}`)
|
|
595
917
|
);
|
|
596
918
|
}
|
|
597
919
|
} catch (error) {
|
|
598
|
-
console.error(
|
|
920
|
+
console.error(chalk4.red(`Error: ${error.message}`));
|
|
599
921
|
process.exit(1);
|
|
600
922
|
}
|
|
601
923
|
});
|
|
@@ -609,13 +931,13 @@ function createIssuesCommand() {
|
|
|
609
931
|
body: options.body || ""
|
|
610
932
|
}
|
|
611
933
|
);
|
|
612
|
-
console.log(
|
|
613
|
-
console.log(
|
|
934
|
+
console.log(chalk4.green("\u2713 Issue created successfully"));
|
|
935
|
+
console.log(chalk4.dim(` #${issue.number} ${issue.title}`));
|
|
614
936
|
console.log(
|
|
615
|
-
|
|
937
|
+
chalk4.dim(` @${ownerIdentifier}/${name}#${issue.number}`)
|
|
616
938
|
);
|
|
617
939
|
} catch (error) {
|
|
618
|
-
console.error(
|
|
940
|
+
console.error(chalk4.red(`Error: ${error.message}`));
|
|
619
941
|
process.exit(1);
|
|
620
942
|
}
|
|
621
943
|
});
|
|
@@ -628,9 +950,9 @@ function createIssuesCommand() {
|
|
|
628
950
|
state: "closed"
|
|
629
951
|
}
|
|
630
952
|
);
|
|
631
|
-
console.log(
|
|
953
|
+
console.log(chalk4.green("\u2713 Issue closed successfully"));
|
|
632
954
|
} catch (error) {
|
|
633
|
-
console.error(
|
|
955
|
+
console.error(chalk4.red(`Error: ${error.message}`));
|
|
634
956
|
process.exit(1);
|
|
635
957
|
}
|
|
636
958
|
});
|
|
@@ -643,9 +965,9 @@ function createIssuesCommand() {
|
|
|
643
965
|
body: options.body
|
|
644
966
|
}
|
|
645
967
|
);
|
|
646
|
-
console.log(
|
|
968
|
+
console.log(chalk4.green("\u2713 Comment added successfully"));
|
|
647
969
|
} catch (error) {
|
|
648
|
-
console.error(
|
|
970
|
+
console.error(chalk4.red(`Error: ${error.message}`));
|
|
649
971
|
process.exit(1);
|
|
650
972
|
}
|
|
651
973
|
});
|
|
@@ -657,16 +979,16 @@ function createIssuesCommand() {
|
|
|
657
979
|
if (options.body !== void 0) updates.body = options.body;
|
|
658
980
|
if (options.state) updates.state = options.state;
|
|
659
981
|
if (Object.keys(updates).length === 0) {
|
|
660
|
-
console.log(
|
|
982
|
+
console.log(chalk4.yellow("No updates specified. Use --title, --body, or --state"));
|
|
661
983
|
return;
|
|
662
984
|
}
|
|
663
985
|
await apiPatch(
|
|
664
986
|
`/api/repositories/${ownerIdentifier}/${name}/issues/${options.number}`,
|
|
665
987
|
updates
|
|
666
988
|
);
|
|
667
|
-
console.log(
|
|
989
|
+
console.log(chalk4.green("\u2713 Issue updated successfully"));
|
|
668
990
|
} catch (error) {
|
|
669
|
-
console.error(
|
|
991
|
+
console.error(chalk4.red(`Error: ${error.message}`));
|
|
670
992
|
process.exit(1);
|
|
671
993
|
}
|
|
672
994
|
});
|
|
@@ -679,9 +1001,9 @@ function createIssuesCommand() {
|
|
|
679
1001
|
state: "open"
|
|
680
1002
|
}
|
|
681
1003
|
);
|
|
682
|
-
console.log(
|
|
1004
|
+
console.log(chalk4.green("\u2713 Issue reopened successfully"));
|
|
683
1005
|
} catch (error) {
|
|
684
|
-
console.error(
|
|
1006
|
+
console.error(chalk4.red(`Error: ${error.message}`));
|
|
685
1007
|
process.exit(1);
|
|
686
1008
|
}
|
|
687
1009
|
});
|
|
@@ -693,19 +1015,19 @@ function createIssuesCommand() {
|
|
|
693
1015
|
);
|
|
694
1016
|
const comments = result.comments || [];
|
|
695
1017
|
if (comments.length === 0) {
|
|
696
|
-
console.log(
|
|
1018
|
+
console.log(chalk4.yellow("No comments found"));
|
|
697
1019
|
return;
|
|
698
1020
|
}
|
|
699
|
-
console.log(
|
|
1021
|
+
console.log(chalk4.bold(`Comments (${comments.length})`));
|
|
700
1022
|
console.log();
|
|
701
1023
|
for (const comment of comments) {
|
|
702
|
-
console.log(
|
|
703
|
-
console.log(
|
|
1024
|
+
console.log(chalk4.cyan(`@${comment.author?.username || "unknown"}`));
|
|
1025
|
+
console.log(chalk4.dim(` ${new Date(comment.createdAt).toLocaleString()}`));
|
|
704
1026
|
console.log(` ${comment.body}`);
|
|
705
1027
|
console.log();
|
|
706
1028
|
}
|
|
707
1029
|
} catch (error) {
|
|
708
|
-
console.error(
|
|
1030
|
+
console.error(chalk4.red(`Error: ${error.message}`));
|
|
709
1031
|
process.exit(1);
|
|
710
1032
|
}
|
|
711
1033
|
});
|
|
@@ -716,19 +1038,19 @@ function createIssuesCommand() {
|
|
|
716
1038
|
`/api/repositories/${ownerIdentifier}/${name}/labels`
|
|
717
1039
|
);
|
|
718
1040
|
if (labels.length === 0) {
|
|
719
|
-
console.log(
|
|
1041
|
+
console.log(chalk4.yellow("No labels found"));
|
|
720
1042
|
return;
|
|
721
1043
|
}
|
|
722
|
-
console.log(
|
|
1044
|
+
console.log(chalk4.bold(`Labels (${labels.length})`));
|
|
723
1045
|
console.log();
|
|
724
1046
|
for (const label of labels) {
|
|
725
|
-
console.log(`${
|
|
1047
|
+
console.log(`${chalk4.hex(label.color || "#000000")("\u25A0")} ${label.name}`);
|
|
726
1048
|
if (label.description) {
|
|
727
|
-
console.log(
|
|
1049
|
+
console.log(chalk4.dim(` ${label.description}`));
|
|
728
1050
|
}
|
|
729
1051
|
}
|
|
730
1052
|
} catch (error) {
|
|
731
|
-
console.error(
|
|
1053
|
+
console.error(chalk4.red(`Error: ${error.message}`));
|
|
732
1054
|
process.exit(1);
|
|
733
1055
|
}
|
|
734
1056
|
});
|
|
@@ -741,9 +1063,9 @@ function createIssuesCommand() {
|
|
|
741
1063
|
labelName: options.label
|
|
742
1064
|
}
|
|
743
1065
|
);
|
|
744
|
-
console.log(
|
|
1066
|
+
console.log(chalk4.green(`\u2713 Label "${options.label}" added to issue #${options.number}`));
|
|
745
1067
|
} catch (error) {
|
|
746
|
-
console.error(
|
|
1068
|
+
console.error(chalk4.red(`Error: ${error.message}`));
|
|
747
1069
|
process.exit(1);
|
|
748
1070
|
}
|
|
749
1071
|
});
|
|
@@ -753,9 +1075,9 @@ function createIssuesCommand() {
|
|
|
753
1075
|
await apiDelete(
|
|
754
1076
|
`/api/repositories/${ownerIdentifier}/${name}/issues/${options.number}/labels/${options.label}`
|
|
755
1077
|
);
|
|
756
|
-
console.log(
|
|
1078
|
+
console.log(chalk4.green(`\u2713 Label "${options.label}" removed from issue #${options.number}`));
|
|
757
1079
|
} catch (error) {
|
|
758
|
-
console.error(
|
|
1080
|
+
console.error(chalk4.red(`Error: ${error.message}`));
|
|
759
1081
|
process.exit(1);
|
|
760
1082
|
}
|
|
761
1083
|
});
|
|
@@ -768,9 +1090,9 @@ function createIssuesCommand() {
|
|
|
768
1090
|
username: options.user
|
|
769
1091
|
}
|
|
770
1092
|
);
|
|
771
|
-
console.log(
|
|
1093
|
+
console.log(chalk4.green(`\u2713 Assigned @${options.user} to issue #${options.number}`));
|
|
772
1094
|
} catch (error) {
|
|
773
|
-
console.error(
|
|
1095
|
+
console.error(chalk4.red(`Error: ${error.message}`));
|
|
774
1096
|
process.exit(1);
|
|
775
1097
|
}
|
|
776
1098
|
});
|
|
@@ -780,9 +1102,9 @@ function createIssuesCommand() {
|
|
|
780
1102
|
await apiDelete(
|
|
781
1103
|
`/api/repositories/${ownerIdentifier}/${name}/issues/${options.number}/assignees/${options.user}`
|
|
782
1104
|
);
|
|
783
|
-
console.log(
|
|
1105
|
+
console.log(chalk4.green(`\u2713 Unassigned @${options.user} from issue #${options.number}`));
|
|
784
1106
|
} catch (error) {
|
|
785
|
-
console.error(
|
|
1107
|
+
console.error(chalk4.red(`Error: ${error.message}`));
|
|
786
1108
|
process.exit(1);
|
|
787
1109
|
}
|
|
788
1110
|
});
|
|
@@ -799,10 +1121,10 @@ function parseRepoArg2(arg) {
|
|
|
799
1121
|
}
|
|
800
1122
|
|
|
801
1123
|
// src/commands/prs.ts
|
|
802
|
-
import { Command as
|
|
803
|
-
import
|
|
1124
|
+
import { Command as Command5 } from "commander";
|
|
1125
|
+
import chalk5 from "chalk";
|
|
804
1126
|
function createPrsCommand() {
|
|
805
|
-
const prs = new
|
|
1127
|
+
const prs = new Command5("prs").alias("pr").description("Manage pull requests");
|
|
806
1128
|
prs.command("list").description("List pull requests in a repository").requiredOption("--repo <repo>", "Repository (@owner/name)").option("--state <state>", "Filter by state (open/closed/merged)", "open").action(async (options) => {
|
|
807
1129
|
try {
|
|
808
1130
|
const [ownerIdentifier, name] = parseRepoArg3(options.repo);
|
|
@@ -811,26 +1133,26 @@ function createPrsCommand() {
|
|
|
811
1133
|
);
|
|
812
1134
|
const prsList = result.pullRequests || [];
|
|
813
1135
|
if (prsList.length === 0) {
|
|
814
|
-
console.log(
|
|
1136
|
+
console.log(chalk5.yellow(`No ${options.state} pull requests found`));
|
|
815
1137
|
return;
|
|
816
1138
|
}
|
|
817
1139
|
console.log(
|
|
818
|
-
|
|
1140
|
+
chalk5.bold(
|
|
819
1141
|
`Pull Requests in @${ownerIdentifier}/${name} (${prsList.length})`
|
|
820
1142
|
)
|
|
821
1143
|
);
|
|
822
1144
|
console.log();
|
|
823
1145
|
for (const pr of prsList) {
|
|
824
1146
|
const stateIcon = pr.merged ? "\u{1F7E3}" : pr.state === "open" ? "\u{1F7E2}" : "\u26AA";
|
|
825
|
-
console.log(`${stateIcon} #${pr.number} ${
|
|
1147
|
+
console.log(`${stateIcon} #${pr.number} ${chalk5.cyan(pr.title)}`);
|
|
826
1148
|
console.log(
|
|
827
|
-
|
|
1149
|
+
chalk5.dim(
|
|
828
1150
|
` ${pr.headBranch} \u2192 ${pr.baseBranch} by @${pr.author?.username || "unknown"} \xB7 ${new Date(pr.createdAt).toLocaleDateString()}`
|
|
829
1151
|
)
|
|
830
1152
|
);
|
|
831
1153
|
}
|
|
832
1154
|
} catch (error) {
|
|
833
|
-
console.error(
|
|
1155
|
+
console.error(chalk5.red(`Error: ${error.message}`));
|
|
834
1156
|
process.exit(1);
|
|
835
1157
|
}
|
|
836
1158
|
});
|
|
@@ -841,9 +1163,9 @@ function createPrsCommand() {
|
|
|
841
1163
|
`/api/repositories/${ownerIdentifier}/${name}/pulls/${options.number}`
|
|
842
1164
|
);
|
|
843
1165
|
const stateIcon = pr.merged ? "\u{1F7E3}" : pr.state === "open" ? "\u{1F7E2}" : "\u26AA";
|
|
844
|
-
console.log(`${stateIcon} ${
|
|
1166
|
+
console.log(`${stateIcon} ${chalk5.bold(`#${pr.number} ${pr.title}`)}`);
|
|
845
1167
|
console.log(
|
|
846
|
-
|
|
1168
|
+
chalk5.dim(
|
|
847
1169
|
`${pr.headBranch} \u2192 ${pr.baseBranch} by @${pr.author?.username || "unknown"} \xB7 ${new Date(pr.createdAt).toLocaleDateString()}`
|
|
848
1170
|
)
|
|
849
1171
|
);
|
|
@@ -852,19 +1174,19 @@ function createPrsCommand() {
|
|
|
852
1174
|
console.log(pr.body);
|
|
853
1175
|
console.log();
|
|
854
1176
|
}
|
|
855
|
-
console.log(
|
|
1177
|
+
console.log(chalk5.dim(`State: ${pr.merged ? "merged" : pr.state}`));
|
|
856
1178
|
if (pr.mergedAt) {
|
|
857
1179
|
console.log(
|
|
858
|
-
|
|
1180
|
+
chalk5.dim(`Merged: ${new Date(pr.mergedAt).toLocaleDateString()}`)
|
|
859
1181
|
);
|
|
860
1182
|
}
|
|
861
1183
|
if (pr.closedAt && !pr.merged) {
|
|
862
1184
|
console.log(
|
|
863
|
-
|
|
1185
|
+
chalk5.dim(`Closed: ${new Date(pr.closedAt).toLocaleDateString()}`)
|
|
864
1186
|
);
|
|
865
1187
|
}
|
|
866
1188
|
} catch (error) {
|
|
867
|
-
console.error(
|
|
1189
|
+
console.error(chalk5.red(`Error: ${error.message}`));
|
|
868
1190
|
process.exit(1);
|
|
869
1191
|
}
|
|
870
1192
|
});
|
|
@@ -880,13 +1202,13 @@ function createPrsCommand() {
|
|
|
880
1202
|
body: options.body || ""
|
|
881
1203
|
}
|
|
882
1204
|
);
|
|
883
|
-
console.log(
|
|
884
|
-
console.log(
|
|
1205
|
+
console.log(chalk5.green("\u2713 Pull request created successfully"));
|
|
1206
|
+
console.log(chalk5.dim(` #${pr.number} ${pr.title}`));
|
|
885
1207
|
console.log(
|
|
886
|
-
|
|
1208
|
+
chalk5.dim(` @${ownerIdentifier}/${name}#${pr.number}`)
|
|
887
1209
|
);
|
|
888
1210
|
} catch (error) {
|
|
889
|
-
console.error(
|
|
1211
|
+
console.error(chalk5.red(`Error: ${error.message}`));
|
|
890
1212
|
process.exit(1);
|
|
891
1213
|
}
|
|
892
1214
|
});
|
|
@@ -899,9 +1221,9 @@ function createPrsCommand() {
|
|
|
899
1221
|
await apiPost(`/api/pulls/${pr.id}/merge`, {
|
|
900
1222
|
commitMessage: options.message
|
|
901
1223
|
});
|
|
902
|
-
console.log(
|
|
1224
|
+
console.log(chalk5.green("\u2713 Pull request merged successfully"));
|
|
903
1225
|
} catch (error) {
|
|
904
|
-
console.error(
|
|
1226
|
+
console.error(chalk5.red(`Error: ${error.message}`));
|
|
905
1227
|
process.exit(1);
|
|
906
1228
|
}
|
|
907
1229
|
});
|
|
@@ -914,9 +1236,9 @@ function createPrsCommand() {
|
|
|
914
1236
|
await apiPatch(`/api/pulls/${pr.id}`, {
|
|
915
1237
|
state: "closed"
|
|
916
1238
|
});
|
|
917
|
-
console.log(
|
|
1239
|
+
console.log(chalk5.green("\u2713 Pull request closed successfully"));
|
|
918
1240
|
} catch (error) {
|
|
919
|
-
console.error(
|
|
1241
|
+
console.error(chalk5.red(`Error: ${error.message}`));
|
|
920
1242
|
process.exit(1);
|
|
921
1243
|
}
|
|
922
1244
|
});
|
|
@@ -929,9 +1251,9 @@ function createPrsCommand() {
|
|
|
929
1251
|
await apiPost(`/api/pulls/${pr.id}/comments`, {
|
|
930
1252
|
body: options.body
|
|
931
1253
|
});
|
|
932
|
-
console.log(
|
|
1254
|
+
console.log(chalk5.green("\u2713 Comment added successfully"));
|
|
933
1255
|
} catch (error) {
|
|
934
|
-
console.error(
|
|
1256
|
+
console.error(chalk5.red(`Error: ${error.message}`));
|
|
935
1257
|
process.exit(1);
|
|
936
1258
|
}
|
|
937
1259
|
});
|
|
@@ -942,16 +1264,16 @@ function createPrsCommand() {
|
|
|
942
1264
|
if (options.title) updates.title = options.title;
|
|
943
1265
|
if (options.body !== void 0) updates.body = options.body;
|
|
944
1266
|
if (Object.keys(updates).length === 0) {
|
|
945
|
-
console.log(
|
|
1267
|
+
console.log(chalk5.yellow("No updates specified. Use --title or --body"));
|
|
946
1268
|
return;
|
|
947
1269
|
}
|
|
948
1270
|
const pr = await apiGet(
|
|
949
1271
|
`/api/repositories/${ownerIdentifier}/${name}/pulls/${options.number}`
|
|
950
1272
|
);
|
|
951
1273
|
await apiPatch(`/api/pulls/${pr.id}`, updates);
|
|
952
|
-
console.log(
|
|
1274
|
+
console.log(chalk5.green("\u2713 Pull request updated successfully"));
|
|
953
1275
|
} catch (error) {
|
|
954
|
-
console.error(
|
|
1276
|
+
console.error(chalk5.red(`Error: ${error.message}`));
|
|
955
1277
|
process.exit(1);
|
|
956
1278
|
}
|
|
957
1279
|
});
|
|
@@ -964,9 +1286,9 @@ function createPrsCommand() {
|
|
|
964
1286
|
await apiPatch(`/api/pulls/${pr.id}`, {
|
|
965
1287
|
state: "open"
|
|
966
1288
|
});
|
|
967
|
-
console.log(
|
|
1289
|
+
console.log(chalk5.green("\u2713 Pull request reopened successfully"));
|
|
968
1290
|
} catch (error) {
|
|
969
|
-
console.error(
|
|
1291
|
+
console.error(chalk5.red(`Error: ${error.message}`));
|
|
970
1292
|
process.exit(1);
|
|
971
1293
|
}
|
|
972
1294
|
});
|
|
@@ -979,9 +1301,9 @@ function createPrsCommand() {
|
|
|
979
1301
|
await apiPatch(`/api/pulls/${pr.id}`, {
|
|
980
1302
|
draft: true
|
|
981
1303
|
});
|
|
982
|
-
console.log(
|
|
1304
|
+
console.log(chalk5.green("\u2713 Pull request marked as draft"));
|
|
983
1305
|
} catch (error) {
|
|
984
|
-
console.error(
|
|
1306
|
+
console.error(chalk5.red(`Error: ${error.message}`));
|
|
985
1307
|
process.exit(1);
|
|
986
1308
|
}
|
|
987
1309
|
});
|
|
@@ -994,9 +1316,9 @@ function createPrsCommand() {
|
|
|
994
1316
|
await apiPatch(`/api/pulls/${pr.id}`, {
|
|
995
1317
|
draft: false
|
|
996
1318
|
});
|
|
997
|
-
console.log(
|
|
1319
|
+
console.log(chalk5.green("\u2713 Pull request marked as ready for review"));
|
|
998
1320
|
} catch (error) {
|
|
999
|
-
console.error(
|
|
1321
|
+
console.error(chalk5.red(`Error: ${error.message}`));
|
|
1000
1322
|
process.exit(1);
|
|
1001
1323
|
}
|
|
1002
1324
|
});
|
|
@@ -1008,7 +1330,7 @@ function createPrsCommand() {
|
|
|
1008
1330
|
);
|
|
1009
1331
|
const validStates = ["approve", "request_changes", "comment"];
|
|
1010
1332
|
if (!validStates.includes(options.state)) {
|
|
1011
|
-
console.log(
|
|
1333
|
+
console.log(chalk5.red(`Invalid state. Must be one of: ${validStates.join(", ")}`));
|
|
1012
1334
|
process.exit(1);
|
|
1013
1335
|
}
|
|
1014
1336
|
await apiPost(`/api/pulls/${pr.id}/reviews`, {
|
|
@@ -1020,9 +1342,9 @@ function createPrsCommand() {
|
|
|
1020
1342
|
request_changes: "requested changes",
|
|
1021
1343
|
comment: "commented"
|
|
1022
1344
|
};
|
|
1023
|
-
console.log(
|
|
1345
|
+
console.log(chalk5.green(`\u2713 Review submitted: ${stateLabels[options.state]}`));
|
|
1024
1346
|
} catch (error) {
|
|
1025
|
-
console.error(
|
|
1347
|
+
console.error(chalk5.red(`Error: ${error.message}`));
|
|
1026
1348
|
process.exit(1);
|
|
1027
1349
|
}
|
|
1028
1350
|
});
|
|
@@ -1034,10 +1356,10 @@ function createPrsCommand() {
|
|
|
1034
1356
|
);
|
|
1035
1357
|
const reviews = await apiGet(`/api/pulls/${pr.id}/reviews`);
|
|
1036
1358
|
if (reviews.length === 0) {
|
|
1037
|
-
console.log(
|
|
1359
|
+
console.log(chalk5.yellow("No reviews found"));
|
|
1038
1360
|
return;
|
|
1039
1361
|
}
|
|
1040
|
-
console.log(
|
|
1362
|
+
console.log(chalk5.bold(`Reviews (${reviews.length})`));
|
|
1041
1363
|
console.log();
|
|
1042
1364
|
for (const review of reviews) {
|
|
1043
1365
|
const stateIcons = {
|
|
@@ -1047,16 +1369,16 @@ function createPrsCommand() {
|
|
|
1047
1369
|
};
|
|
1048
1370
|
const icon = stateIcons[review.state] || "\u2022";
|
|
1049
1371
|
console.log(
|
|
1050
|
-
`${icon} ${
|
|
1372
|
+
`${icon} ${chalk5.cyan(`@${review.author?.username || "unknown"}`)} ${chalk5.dim(review.state)}`
|
|
1051
1373
|
);
|
|
1052
|
-
console.log(
|
|
1374
|
+
console.log(chalk5.dim(` ${new Date(review.createdAt).toLocaleString()}`));
|
|
1053
1375
|
if (review.body) {
|
|
1054
1376
|
console.log(` ${review.body}`);
|
|
1055
1377
|
}
|
|
1056
1378
|
console.log();
|
|
1057
1379
|
}
|
|
1058
1380
|
} catch (error) {
|
|
1059
|
-
console.error(
|
|
1381
|
+
console.error(chalk5.red(`Error: ${error.message}`));
|
|
1060
1382
|
process.exit(1);
|
|
1061
1383
|
}
|
|
1062
1384
|
});
|
|
@@ -1068,21 +1390,21 @@ function createPrsCommand() {
|
|
|
1068
1390
|
);
|
|
1069
1391
|
const commits = await apiGet(`/api/pulls/${pr.id}/commits`);
|
|
1070
1392
|
if (commits.length === 0) {
|
|
1071
|
-
console.log(
|
|
1393
|
+
console.log(chalk5.yellow("No commits found"));
|
|
1072
1394
|
return;
|
|
1073
1395
|
}
|
|
1074
|
-
console.log(
|
|
1396
|
+
console.log(chalk5.bold(`Commits (${commits.length})`));
|
|
1075
1397
|
console.log();
|
|
1076
1398
|
for (const commit of commits) {
|
|
1077
|
-
console.log(
|
|
1399
|
+
console.log(chalk5.cyan(commit.sha?.substring(0, 7) || "unknown"));
|
|
1078
1400
|
console.log(` ${commit.message || "(no message)"}`);
|
|
1079
1401
|
console.log(
|
|
1080
|
-
|
|
1402
|
+
chalk5.dim(` by ${commit.author?.name || "unknown"} on ${new Date(commit.createdAt).toLocaleDateString()}`)
|
|
1081
1403
|
);
|
|
1082
1404
|
console.log();
|
|
1083
1405
|
}
|
|
1084
1406
|
} catch (error) {
|
|
1085
|
-
console.error(
|
|
1407
|
+
console.error(chalk5.red(`Error: ${error.message}`));
|
|
1086
1408
|
process.exit(1);
|
|
1087
1409
|
}
|
|
1088
1410
|
});
|
|
@@ -1094,25 +1416,25 @@ function createPrsCommand() {
|
|
|
1094
1416
|
);
|
|
1095
1417
|
const diff = await apiGet(`/api/pulls/${pr.id}/diff`);
|
|
1096
1418
|
if (!diff || !diff.files || diff.files.length === 0) {
|
|
1097
|
-
console.log(
|
|
1419
|
+
console.log(chalk5.yellow("No changes found"));
|
|
1098
1420
|
return;
|
|
1099
1421
|
}
|
|
1100
|
-
console.log(
|
|
1422
|
+
console.log(chalk5.bold(`Diff for PR #${options.number}`));
|
|
1101
1423
|
console.log();
|
|
1102
1424
|
for (const file of diff.files) {
|
|
1103
|
-
console.log(
|
|
1425
|
+
console.log(chalk5.cyan(`${file.path}`));
|
|
1104
1426
|
console.log(
|
|
1105
|
-
|
|
1427
|
+
chalk5.dim(` ${file.additions || 0} additions, ${file.deletions || 0} deletions`)
|
|
1106
1428
|
);
|
|
1107
1429
|
}
|
|
1108
1430
|
console.log();
|
|
1109
1431
|
console.log(
|
|
1110
|
-
|
|
1432
|
+
chalk5.dim(
|
|
1111
1433
|
`Total: ${diff.additions || 0} additions, ${diff.deletions || 0} deletions across ${diff.files.length} files`
|
|
1112
1434
|
)
|
|
1113
1435
|
);
|
|
1114
1436
|
} catch (error) {
|
|
1115
|
-
console.error(
|
|
1437
|
+
console.error(chalk5.red(`Error: ${error.message}`));
|
|
1116
1438
|
process.exit(1);
|
|
1117
1439
|
}
|
|
1118
1440
|
});
|
|
@@ -1129,10 +1451,10 @@ function parseRepoArg3(arg) {
|
|
|
1129
1451
|
}
|
|
1130
1452
|
|
|
1131
1453
|
// src/commands/orgs.ts
|
|
1132
|
-
import { Command as
|
|
1133
|
-
import
|
|
1454
|
+
import { Command as Command6 } from "commander";
|
|
1455
|
+
import chalk6 from "chalk";
|
|
1134
1456
|
function createOrgsCommand() {
|
|
1135
|
-
const orgs = new
|
|
1457
|
+
const orgs = new Command6("orgs").alias("org").description("Manage organizations");
|
|
1136
1458
|
orgs.command("list").description("List organizations").option("--member", "Show only organizations you're a member of").action(async (options) => {
|
|
1137
1459
|
try {
|
|
1138
1460
|
let organizations;
|
|
@@ -1144,42 +1466,42 @@ function createOrgsCommand() {
|
|
|
1144
1466
|
organizations = result.organizations || [];
|
|
1145
1467
|
}
|
|
1146
1468
|
if (organizations.length === 0) {
|
|
1147
|
-
console.log(
|
|
1469
|
+
console.log(chalk6.yellow("No organizations found"));
|
|
1148
1470
|
return;
|
|
1149
1471
|
}
|
|
1150
|
-
console.log(
|
|
1472
|
+
console.log(chalk6.bold(`Organizations (${organizations.length})`));
|
|
1151
1473
|
console.log();
|
|
1152
1474
|
for (const org of organizations) {
|
|
1153
|
-
console.log(
|
|
1154
|
-
console.log(
|
|
1475
|
+
console.log(chalk6.cyan(`@${org.slug}`));
|
|
1476
|
+
console.log(chalk6.dim(` ${org.name}`));
|
|
1155
1477
|
if (org.metadata?.type) {
|
|
1156
|
-
console.log(
|
|
1478
|
+
console.log(chalk6.dim(` Type: ${org.metadata.type}`));
|
|
1157
1479
|
}
|
|
1158
1480
|
if (org.metadata?.description) {
|
|
1159
|
-
console.log(
|
|
1481
|
+
console.log(chalk6.dim(` ${org.metadata.description}`));
|
|
1160
1482
|
}
|
|
1161
1483
|
}
|
|
1162
1484
|
} catch (error) {
|
|
1163
|
-
console.error(
|
|
1485
|
+
console.error(chalk6.red(`Error: ${error.message}`));
|
|
1164
1486
|
process.exit(1);
|
|
1165
1487
|
}
|
|
1166
1488
|
});
|
|
1167
1489
|
orgs.command("view").description("View organization details").argument("<slug>", "Organization slug").action(async (slug) => {
|
|
1168
1490
|
try {
|
|
1169
1491
|
const org = await apiGet(`/api/orgs/${slug}`);
|
|
1170
|
-
console.log(
|
|
1171
|
-
console.log(
|
|
1492
|
+
console.log(chalk6.bold(`@${org.slug}`));
|
|
1493
|
+
console.log(chalk6.dim(org.name));
|
|
1172
1494
|
if (org.metadata?.type) {
|
|
1173
|
-
console.log(
|
|
1495
|
+
console.log(chalk6.dim(`Type: ${org.metadata.type}`));
|
|
1174
1496
|
}
|
|
1175
1497
|
console.log();
|
|
1176
1498
|
if (org.metadata?.description) {
|
|
1177
1499
|
console.log(org.metadata.description);
|
|
1178
1500
|
console.log();
|
|
1179
1501
|
}
|
|
1180
|
-
console.log(
|
|
1502
|
+
console.log(chalk6.dim(`Created: ${new Date(org.createdAt).toLocaleDateString()}`));
|
|
1181
1503
|
} catch (error) {
|
|
1182
|
-
console.error(
|
|
1504
|
+
console.error(chalk6.red(`Error: ${error.message}`));
|
|
1183
1505
|
process.exit(1);
|
|
1184
1506
|
}
|
|
1185
1507
|
});
|
|
@@ -1197,13 +1519,13 @@ function createOrgsCommand() {
|
|
|
1197
1519
|
slug: options.slug,
|
|
1198
1520
|
metadata: Object.keys(metadata).length > 0 ? metadata : void 0
|
|
1199
1521
|
});
|
|
1200
|
-
console.log(
|
|
1201
|
-
console.log(
|
|
1522
|
+
console.log(chalk6.green("\u2713 Organization created successfully"));
|
|
1523
|
+
console.log(chalk6.dim(` @${org.slug}`));
|
|
1202
1524
|
if (options.type) {
|
|
1203
|
-
console.log(
|
|
1525
|
+
console.log(chalk6.dim(` Type: ${options.type}`));
|
|
1204
1526
|
}
|
|
1205
1527
|
} catch (error) {
|
|
1206
|
-
console.error(
|
|
1528
|
+
console.error(chalk6.red(`Error: ${error.message}`));
|
|
1207
1529
|
process.exit(1);
|
|
1208
1530
|
}
|
|
1209
1531
|
});
|
|
@@ -1211,17 +1533,17 @@ function createOrgsCommand() {
|
|
|
1211
1533
|
try {
|
|
1212
1534
|
const members = await apiGet(`/api/organizations/${slug}/members`);
|
|
1213
1535
|
if (members.length === 0) {
|
|
1214
|
-
console.log(
|
|
1536
|
+
console.log(chalk6.yellow("No members found"));
|
|
1215
1537
|
return;
|
|
1216
1538
|
}
|
|
1217
|
-
console.log(
|
|
1539
|
+
console.log(chalk6.bold(`Members (${members.length})`));
|
|
1218
1540
|
console.log();
|
|
1219
1541
|
for (const member of members) {
|
|
1220
1542
|
const roleIcon = member.role === "owner" ? "\u{1F451}" : member.role === "admin" ? "\u26A1" : "\u2022";
|
|
1221
|
-
console.log(`${roleIcon} ${
|
|
1543
|
+
console.log(`${roleIcon} ${chalk6.cyan(`@${member.user?.username || "unknown"}`)} ${chalk6.dim(member.role)}`);
|
|
1222
1544
|
}
|
|
1223
1545
|
} catch (error) {
|
|
1224
|
-
console.error(
|
|
1546
|
+
console.error(chalk6.red(`Error: ${error.message}`));
|
|
1225
1547
|
process.exit(1);
|
|
1226
1548
|
}
|
|
1227
1549
|
});
|
|
@@ -1231,18 +1553,18 @@ function createOrgsCommand() {
|
|
|
1231
1553
|
username,
|
|
1232
1554
|
role: options.role
|
|
1233
1555
|
});
|
|
1234
|
-
console.log(
|
|
1556
|
+
console.log(chalk6.green(`\u2713 Added @${username} to @${slug} as ${options.role}`));
|
|
1235
1557
|
} catch (error) {
|
|
1236
|
-
console.error(
|
|
1558
|
+
console.error(chalk6.red(`Error: ${error.message}`));
|
|
1237
1559
|
process.exit(1);
|
|
1238
1560
|
}
|
|
1239
1561
|
});
|
|
1240
1562
|
orgs.command("member-remove").description("Remove a member from organization").argument("<slug>", "Organization slug").argument("<username>", "Username to remove").action(async (slug, username) => {
|
|
1241
1563
|
try {
|
|
1242
1564
|
await apiDelete(`/api/organizations/${slug}/members/${username}`);
|
|
1243
|
-
console.log(
|
|
1565
|
+
console.log(chalk6.green(`\u2713 Removed @${username} from @${slug}`));
|
|
1244
1566
|
} catch (error) {
|
|
1245
|
-
console.error(
|
|
1567
|
+
console.error(chalk6.red(`Error: ${error.message}`));
|
|
1246
1568
|
process.exit(1);
|
|
1247
1569
|
}
|
|
1248
1570
|
});
|
|
@@ -1250,19 +1572,19 @@ function createOrgsCommand() {
|
|
|
1250
1572
|
try {
|
|
1251
1573
|
const teams = await apiGet(`/api/organizations/${slug}/teams`);
|
|
1252
1574
|
if (teams.length === 0) {
|
|
1253
|
-
console.log(
|
|
1575
|
+
console.log(chalk6.yellow("No teams found"));
|
|
1254
1576
|
return;
|
|
1255
1577
|
}
|
|
1256
|
-
console.log(
|
|
1578
|
+
console.log(chalk6.bold(`Teams (${teams.length})`));
|
|
1257
1579
|
console.log();
|
|
1258
1580
|
for (const team of teams) {
|
|
1259
|
-
console.log(
|
|
1581
|
+
console.log(chalk6.cyan(team.name));
|
|
1260
1582
|
if (team.description) {
|
|
1261
|
-
console.log(
|
|
1583
|
+
console.log(chalk6.dim(` ${team.description}`));
|
|
1262
1584
|
}
|
|
1263
1585
|
}
|
|
1264
1586
|
} catch (error) {
|
|
1265
|
-
console.error(
|
|
1587
|
+
console.error(chalk6.red(`Error: ${error.message}`));
|
|
1266
1588
|
process.exit(1);
|
|
1267
1589
|
}
|
|
1268
1590
|
});
|
|
@@ -1272,9 +1594,9 @@ function createOrgsCommand() {
|
|
|
1272
1594
|
name: options.name,
|
|
1273
1595
|
description: options.description
|
|
1274
1596
|
});
|
|
1275
|
-
console.log(
|
|
1597
|
+
console.log(chalk6.green(`\u2713 Team "${team.name}" created in @${slug}`));
|
|
1276
1598
|
} catch (error) {
|
|
1277
|
-
console.error(
|
|
1599
|
+
console.error(chalk6.red(`Error: ${error.message}`));
|
|
1278
1600
|
process.exit(1);
|
|
1279
1601
|
}
|
|
1280
1602
|
});
|
|
@@ -1284,16 +1606,16 @@ function createOrgsCommand() {
|
|
|
1284
1606
|
`/api/organizations/${slug}/teams/${team}/members`
|
|
1285
1607
|
);
|
|
1286
1608
|
if (members.length === 0) {
|
|
1287
|
-
console.log(
|
|
1609
|
+
console.log(chalk6.yellow("No team members found"));
|
|
1288
1610
|
return;
|
|
1289
1611
|
}
|
|
1290
|
-
console.log(
|
|
1612
|
+
console.log(chalk6.bold(`Team Members (${members.length})`));
|
|
1291
1613
|
console.log();
|
|
1292
1614
|
for (const member of members) {
|
|
1293
|
-
console.log(
|
|
1615
|
+
console.log(chalk6.cyan(`@${member.user?.username || "unknown"}`));
|
|
1294
1616
|
}
|
|
1295
1617
|
} catch (error) {
|
|
1296
|
-
console.error(
|
|
1618
|
+
console.error(chalk6.red(`Error: ${error.message}`));
|
|
1297
1619
|
process.exit(1);
|
|
1298
1620
|
}
|
|
1299
1621
|
});
|
|
@@ -1305,9 +1627,9 @@ function createOrgsCommand() {
|
|
|
1305
1627
|
username
|
|
1306
1628
|
}
|
|
1307
1629
|
);
|
|
1308
|
-
console.log(
|
|
1630
|
+
console.log(chalk6.green(`\u2713 Added @${username} to team ${team}`));
|
|
1309
1631
|
} catch (error) {
|
|
1310
|
-
console.error(
|
|
1632
|
+
console.error(chalk6.red(`Error: ${error.message}`));
|
|
1311
1633
|
process.exit(1);
|
|
1312
1634
|
}
|
|
1313
1635
|
});
|
|
@@ -1316,9 +1638,9 @@ function createOrgsCommand() {
|
|
|
1316
1638
|
await apiDelete(
|
|
1317
1639
|
`/api/organizations/${slug}/teams/${team}/members/${username}`
|
|
1318
1640
|
);
|
|
1319
|
-
console.log(
|
|
1641
|
+
console.log(chalk6.green(`\u2713 Removed @${username} from team ${team}`));
|
|
1320
1642
|
} catch (error) {
|
|
1321
|
-
console.error(
|
|
1643
|
+
console.error(chalk6.red(`Error: ${error.message}`));
|
|
1322
1644
|
process.exit(1);
|
|
1323
1645
|
}
|
|
1324
1646
|
});
|
|
@@ -1326,10 +1648,10 @@ function createOrgsCommand() {
|
|
|
1326
1648
|
}
|
|
1327
1649
|
|
|
1328
1650
|
// src/commands/user.ts
|
|
1329
|
-
import { Command as
|
|
1330
|
-
import
|
|
1651
|
+
import { Command as Command7 } from "commander";
|
|
1652
|
+
import chalk7 from "chalk";
|
|
1331
1653
|
function createUserCommand() {
|
|
1332
|
-
const user = new
|
|
1654
|
+
const user = new Command7("user").description("Manage user profile and settings");
|
|
1333
1655
|
user.command("profile").description("View user profile").argument("[username]", "Username (defaults to current user)").action(async (username) => {
|
|
1334
1656
|
try {
|
|
1335
1657
|
let profile;
|
|
@@ -1338,9 +1660,9 @@ function createUserCommand() {
|
|
|
1338
1660
|
} else {
|
|
1339
1661
|
profile = await apiGet("/api/users/me");
|
|
1340
1662
|
}
|
|
1341
|
-
console.log(
|
|
1663
|
+
console.log(chalk7.bold(`@${profile.username}`));
|
|
1342
1664
|
if (profile.name) {
|
|
1343
|
-
console.log(
|
|
1665
|
+
console.log(chalk7.dim(profile.name));
|
|
1344
1666
|
}
|
|
1345
1667
|
console.log();
|
|
1346
1668
|
if (profile.bio) {
|
|
@@ -1348,25 +1670,25 @@ function createUserCommand() {
|
|
|
1348
1670
|
console.log();
|
|
1349
1671
|
}
|
|
1350
1672
|
if (profile.location) {
|
|
1351
|
-
console.log(
|
|
1673
|
+
console.log(chalk7.dim(`\u{1F4CD} ${profile.location}`));
|
|
1352
1674
|
}
|
|
1353
1675
|
if (profile.website) {
|
|
1354
|
-
console.log(
|
|
1676
|
+
console.log(chalk7.dim(`\u{1F517} ${profile.website}`));
|
|
1355
1677
|
}
|
|
1356
1678
|
if (profile.company) {
|
|
1357
|
-
console.log(
|
|
1679
|
+
console.log(chalk7.dim(`\u{1F3E2} ${profile.company}`));
|
|
1358
1680
|
}
|
|
1359
1681
|
if (profile.pronouns) {
|
|
1360
|
-
console.log(
|
|
1682
|
+
console.log(chalk7.dim(`Pronouns: ${profile.pronouns}`));
|
|
1361
1683
|
}
|
|
1362
1684
|
if (profile.gitEmail) {
|
|
1363
|
-
console.log(
|
|
1685
|
+
console.log(chalk7.dim(`Git Email: ${profile.gitEmail}`));
|
|
1364
1686
|
}
|
|
1365
1687
|
console.log();
|
|
1366
|
-
console.log(
|
|
1367
|
-
console.log(
|
|
1688
|
+
console.log(chalk7.dim(`User type: ${profile.userType || "human"}`));
|
|
1689
|
+
console.log(chalk7.dim(`Joined: ${new Date(profile.createdAt).toLocaleDateString()}`));
|
|
1368
1690
|
} catch (error) {
|
|
1369
|
-
console.error(
|
|
1691
|
+
console.error(chalk7.red(`Error: ${error.message}`));
|
|
1370
1692
|
process.exit(1);
|
|
1371
1693
|
}
|
|
1372
1694
|
});
|
|
@@ -1382,16 +1704,16 @@ function createUserCommand() {
|
|
|
1382
1704
|
if (options.gitEmail !== void 0) updates.gitEmail = options.gitEmail;
|
|
1383
1705
|
if (Object.keys(updates).length === 0) {
|
|
1384
1706
|
console.log(
|
|
1385
|
-
|
|
1707
|
+
chalk7.yellow(
|
|
1386
1708
|
"No updates specified. Use --name, --bio, --location, --website, --pronouns, --company, or --git-email"
|
|
1387
1709
|
)
|
|
1388
1710
|
);
|
|
1389
1711
|
return;
|
|
1390
1712
|
}
|
|
1391
1713
|
await apiPatch("/api/users/me", updates);
|
|
1392
|
-
console.log(
|
|
1714
|
+
console.log(chalk7.green("\u2713 Profile updated successfully"));
|
|
1393
1715
|
} catch (error) {
|
|
1394
|
-
console.error(
|
|
1716
|
+
console.error(chalk7.red(`Error: ${error.message}`));
|
|
1395
1717
|
process.exit(1);
|
|
1396
1718
|
}
|
|
1397
1719
|
});
|
|
@@ -1402,24 +1724,24 @@ function createUserCommand() {
|
|
|
1402
1724
|
);
|
|
1403
1725
|
const users = results.users || [];
|
|
1404
1726
|
if (users.length === 0) {
|
|
1405
|
-
console.log(
|
|
1727
|
+
console.log(chalk7.yellow("No users found"));
|
|
1406
1728
|
return;
|
|
1407
1729
|
}
|
|
1408
|
-
console.log(
|
|
1730
|
+
console.log(chalk7.bold(`Users (${users.length})`));
|
|
1409
1731
|
console.log();
|
|
1410
1732
|
for (const u of users) {
|
|
1411
|
-
console.log(
|
|
1733
|
+
console.log(chalk7.cyan(`@${u.username}`));
|
|
1412
1734
|
if (u.name) {
|
|
1413
|
-
console.log(
|
|
1735
|
+
console.log(chalk7.dim(` ${u.name}`));
|
|
1414
1736
|
}
|
|
1415
1737
|
if (u.bio) {
|
|
1416
1738
|
const shortBio = u.bio.length > 60 ? u.bio.substring(0, 60) + "..." : u.bio;
|
|
1417
|
-
console.log(
|
|
1739
|
+
console.log(chalk7.dim(` ${shortBio}`));
|
|
1418
1740
|
}
|
|
1419
1741
|
console.log();
|
|
1420
1742
|
}
|
|
1421
1743
|
} catch (error) {
|
|
1422
|
-
console.error(
|
|
1744
|
+
console.error(chalk7.red(`Error: ${error.message}`));
|
|
1423
1745
|
process.exit(1);
|
|
1424
1746
|
}
|
|
1425
1747
|
});
|
|
@@ -1437,20 +1759,20 @@ function createUserCommand() {
|
|
|
1437
1759
|
);
|
|
1438
1760
|
const repositories = result.repos || [];
|
|
1439
1761
|
if (repositories.length === 0) {
|
|
1440
|
-
console.log(
|
|
1762
|
+
console.log(chalk7.yellow(`No repositories found for @${targetUsername}`));
|
|
1441
1763
|
return;
|
|
1442
1764
|
}
|
|
1443
|
-
console.log(
|
|
1765
|
+
console.log(chalk7.bold(`@${targetUsername}'s Repositories (${repositories.length})`));
|
|
1444
1766
|
console.log();
|
|
1445
1767
|
for (const repo of repositories) {
|
|
1446
1768
|
const visibility = repo.visibility === "private" ? "\u{1F512}" : "\u{1F310}";
|
|
1447
|
-
console.log(`${visibility} ${
|
|
1769
|
+
console.log(`${visibility} ${chalk7.cyan(repo.name)}`);
|
|
1448
1770
|
if (repo.description) {
|
|
1449
|
-
console.log(
|
|
1771
|
+
console.log(chalk7.dim(` ${repo.description}`));
|
|
1450
1772
|
}
|
|
1451
1773
|
}
|
|
1452
1774
|
} catch (error) {
|
|
1453
|
-
console.error(
|
|
1775
|
+
console.error(chalk7.red(`Error: ${error.message}`));
|
|
1454
1776
|
process.exit(1);
|
|
1455
1777
|
}
|
|
1456
1778
|
});
|
|
@@ -1463,7 +1785,7 @@ var __dirname2 = dirname(__filename2);
|
|
|
1463
1785
|
var packageJson = JSON.parse(
|
|
1464
1786
|
readFileSync(join2(__dirname2, "../package.json"), "utf-8")
|
|
1465
1787
|
);
|
|
1466
|
-
var program = new
|
|
1788
|
+
var program = new Command8();
|
|
1467
1789
|
program.name("forge").description("CLI tool for Kernelius Forge - the agent-native Git platform").version(packageJson.version);
|
|
1468
1790
|
program.addCommand(createAuthCommand());
|
|
1469
1791
|
program.addCommand(createReposCommand());
|
|
@@ -1471,4 +1793,5 @@ program.addCommand(createIssuesCommand());
|
|
|
1471
1793
|
program.addCommand(createPrsCommand());
|
|
1472
1794
|
program.addCommand(createOrgsCommand());
|
|
1473
1795
|
program.addCommand(createUserCommand());
|
|
1796
|
+
program.addCommand(createTemplatesCommand());
|
|
1474
1797
|
program.parse();
|