@kernelius/forge-cli 0.2.0 → 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 +49 -0
- package/README.md +49 -0
- package/dist/index.js +553 -216
- 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,67 +1451,81 @@ 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;
|
|
1139
1461
|
if (options.member) {
|
|
1140
|
-
const
|
|
1141
|
-
const result = await apiGet(
|
|
1142
|
-
`/api/users/${user.id}/organizations`
|
|
1143
|
-
);
|
|
1462
|
+
const result = await apiGet("/api/user/orgs");
|
|
1144
1463
|
organizations = result.organizations || [];
|
|
1145
1464
|
} else {
|
|
1146
|
-
|
|
1465
|
+
const result = await apiGet("/api/orgs/public");
|
|
1466
|
+
organizations = result.organizations || [];
|
|
1147
1467
|
}
|
|
1148
1468
|
if (organizations.length === 0) {
|
|
1149
|
-
console.log(
|
|
1469
|
+
console.log(chalk6.yellow("No organizations found"));
|
|
1150
1470
|
return;
|
|
1151
1471
|
}
|
|
1152
|
-
console.log(
|
|
1472
|
+
console.log(chalk6.bold(`Organizations (${organizations.length})`));
|
|
1153
1473
|
console.log();
|
|
1154
1474
|
for (const org of organizations) {
|
|
1155
|
-
console.log(
|
|
1156
|
-
console.log(
|
|
1475
|
+
console.log(chalk6.cyan(`@${org.slug}`));
|
|
1476
|
+
console.log(chalk6.dim(` ${org.name}`));
|
|
1477
|
+
if (org.metadata?.type) {
|
|
1478
|
+
console.log(chalk6.dim(` Type: ${org.metadata.type}`));
|
|
1479
|
+
}
|
|
1157
1480
|
if (org.metadata?.description) {
|
|
1158
|
-
console.log(
|
|
1481
|
+
console.log(chalk6.dim(` ${org.metadata.description}`));
|
|
1159
1482
|
}
|
|
1160
1483
|
}
|
|
1161
1484
|
} catch (error) {
|
|
1162
|
-
console.error(
|
|
1485
|
+
console.error(chalk6.red(`Error: ${error.message}`));
|
|
1163
1486
|
process.exit(1);
|
|
1164
1487
|
}
|
|
1165
1488
|
});
|
|
1166
1489
|
orgs.command("view").description("View organization details").argument("<slug>", "Organization slug").action(async (slug) => {
|
|
1167
1490
|
try {
|
|
1168
|
-
const org = await apiGet(`/api/
|
|
1169
|
-
console.log(
|
|
1170
|
-
console.log(
|
|
1491
|
+
const org = await apiGet(`/api/orgs/${slug}`);
|
|
1492
|
+
console.log(chalk6.bold(`@${org.slug}`));
|
|
1493
|
+
console.log(chalk6.dim(org.name));
|
|
1494
|
+
if (org.metadata?.type) {
|
|
1495
|
+
console.log(chalk6.dim(`Type: ${org.metadata.type}`));
|
|
1496
|
+
}
|
|
1171
1497
|
console.log();
|
|
1172
1498
|
if (org.metadata?.description) {
|
|
1173
1499
|
console.log(org.metadata.description);
|
|
1174
1500
|
console.log();
|
|
1175
1501
|
}
|
|
1176
|
-
console.log(
|
|
1502
|
+
console.log(chalk6.dim(`Created: ${new Date(org.createdAt).toLocaleDateString()}`));
|
|
1177
1503
|
} catch (error) {
|
|
1178
|
-
console.error(
|
|
1504
|
+
console.error(chalk6.red(`Error: ${error.message}`));
|
|
1179
1505
|
process.exit(1);
|
|
1180
1506
|
}
|
|
1181
1507
|
});
|
|
1182
|
-
orgs.command("create").description("Create a new organization").requiredOption("--name <name>", "Organization name").requiredOption("--slug <slug>", "Organization slug (URL identifier)").option("--description <desc>", "Organization description").action(async (options) => {
|
|
1508
|
+
orgs.command("create").description("Create a new organization").requiredOption("--name <name>", "Organization name").requiredOption("--slug <slug>", "Organization slug (URL identifier)").option("--description <desc>", "Organization description").option("--type <type>", "Organization type (e.g., personal, team, company, open-source)").action(async (options) => {
|
|
1183
1509
|
try {
|
|
1184
|
-
const
|
|
1510
|
+
const metadata = {};
|
|
1511
|
+
if (options.description) {
|
|
1512
|
+
metadata.description = options.description;
|
|
1513
|
+
}
|
|
1514
|
+
if (options.type) {
|
|
1515
|
+
metadata.type = options.type;
|
|
1516
|
+
}
|
|
1517
|
+
const org = await apiPost("/api/orgs", {
|
|
1185
1518
|
name: options.name,
|
|
1186
1519
|
slug: options.slug,
|
|
1187
|
-
metadata:
|
|
1520
|
+
metadata: Object.keys(metadata).length > 0 ? metadata : void 0
|
|
1188
1521
|
});
|
|
1189
|
-
console.log(
|
|
1190
|
-
console.log(
|
|
1522
|
+
console.log(chalk6.green("\u2713 Organization created successfully"));
|
|
1523
|
+
console.log(chalk6.dim(` @${org.slug}`));
|
|
1524
|
+
if (options.type) {
|
|
1525
|
+
console.log(chalk6.dim(` Type: ${options.type}`));
|
|
1526
|
+
}
|
|
1191
1527
|
} catch (error) {
|
|
1192
|
-
console.error(
|
|
1528
|
+
console.error(chalk6.red(`Error: ${error.message}`));
|
|
1193
1529
|
process.exit(1);
|
|
1194
1530
|
}
|
|
1195
1531
|
});
|
|
@@ -1197,17 +1533,17 @@ function createOrgsCommand() {
|
|
|
1197
1533
|
try {
|
|
1198
1534
|
const members = await apiGet(`/api/organizations/${slug}/members`);
|
|
1199
1535
|
if (members.length === 0) {
|
|
1200
|
-
console.log(
|
|
1536
|
+
console.log(chalk6.yellow("No members found"));
|
|
1201
1537
|
return;
|
|
1202
1538
|
}
|
|
1203
|
-
console.log(
|
|
1539
|
+
console.log(chalk6.bold(`Members (${members.length})`));
|
|
1204
1540
|
console.log();
|
|
1205
1541
|
for (const member of members) {
|
|
1206
1542
|
const roleIcon = member.role === "owner" ? "\u{1F451}" : member.role === "admin" ? "\u26A1" : "\u2022";
|
|
1207
|
-
console.log(`${roleIcon} ${
|
|
1543
|
+
console.log(`${roleIcon} ${chalk6.cyan(`@${member.user?.username || "unknown"}`)} ${chalk6.dim(member.role)}`);
|
|
1208
1544
|
}
|
|
1209
1545
|
} catch (error) {
|
|
1210
|
-
console.error(
|
|
1546
|
+
console.error(chalk6.red(`Error: ${error.message}`));
|
|
1211
1547
|
process.exit(1);
|
|
1212
1548
|
}
|
|
1213
1549
|
});
|
|
@@ -1217,18 +1553,18 @@ function createOrgsCommand() {
|
|
|
1217
1553
|
username,
|
|
1218
1554
|
role: options.role
|
|
1219
1555
|
});
|
|
1220
|
-
console.log(
|
|
1556
|
+
console.log(chalk6.green(`\u2713 Added @${username} to @${slug} as ${options.role}`));
|
|
1221
1557
|
} catch (error) {
|
|
1222
|
-
console.error(
|
|
1558
|
+
console.error(chalk6.red(`Error: ${error.message}`));
|
|
1223
1559
|
process.exit(1);
|
|
1224
1560
|
}
|
|
1225
1561
|
});
|
|
1226
1562
|
orgs.command("member-remove").description("Remove a member from organization").argument("<slug>", "Organization slug").argument("<username>", "Username to remove").action(async (slug, username) => {
|
|
1227
1563
|
try {
|
|
1228
1564
|
await apiDelete(`/api/organizations/${slug}/members/${username}`);
|
|
1229
|
-
console.log(
|
|
1565
|
+
console.log(chalk6.green(`\u2713 Removed @${username} from @${slug}`));
|
|
1230
1566
|
} catch (error) {
|
|
1231
|
-
console.error(
|
|
1567
|
+
console.error(chalk6.red(`Error: ${error.message}`));
|
|
1232
1568
|
process.exit(1);
|
|
1233
1569
|
}
|
|
1234
1570
|
});
|
|
@@ -1236,19 +1572,19 @@ function createOrgsCommand() {
|
|
|
1236
1572
|
try {
|
|
1237
1573
|
const teams = await apiGet(`/api/organizations/${slug}/teams`);
|
|
1238
1574
|
if (teams.length === 0) {
|
|
1239
|
-
console.log(
|
|
1575
|
+
console.log(chalk6.yellow("No teams found"));
|
|
1240
1576
|
return;
|
|
1241
1577
|
}
|
|
1242
|
-
console.log(
|
|
1578
|
+
console.log(chalk6.bold(`Teams (${teams.length})`));
|
|
1243
1579
|
console.log();
|
|
1244
1580
|
for (const team of teams) {
|
|
1245
|
-
console.log(
|
|
1581
|
+
console.log(chalk6.cyan(team.name));
|
|
1246
1582
|
if (team.description) {
|
|
1247
|
-
console.log(
|
|
1583
|
+
console.log(chalk6.dim(` ${team.description}`));
|
|
1248
1584
|
}
|
|
1249
1585
|
}
|
|
1250
1586
|
} catch (error) {
|
|
1251
|
-
console.error(
|
|
1587
|
+
console.error(chalk6.red(`Error: ${error.message}`));
|
|
1252
1588
|
process.exit(1);
|
|
1253
1589
|
}
|
|
1254
1590
|
});
|
|
@@ -1258,9 +1594,9 @@ function createOrgsCommand() {
|
|
|
1258
1594
|
name: options.name,
|
|
1259
1595
|
description: options.description
|
|
1260
1596
|
});
|
|
1261
|
-
console.log(
|
|
1597
|
+
console.log(chalk6.green(`\u2713 Team "${team.name}" created in @${slug}`));
|
|
1262
1598
|
} catch (error) {
|
|
1263
|
-
console.error(
|
|
1599
|
+
console.error(chalk6.red(`Error: ${error.message}`));
|
|
1264
1600
|
process.exit(1);
|
|
1265
1601
|
}
|
|
1266
1602
|
});
|
|
@@ -1270,16 +1606,16 @@ function createOrgsCommand() {
|
|
|
1270
1606
|
`/api/organizations/${slug}/teams/${team}/members`
|
|
1271
1607
|
);
|
|
1272
1608
|
if (members.length === 0) {
|
|
1273
|
-
console.log(
|
|
1609
|
+
console.log(chalk6.yellow("No team members found"));
|
|
1274
1610
|
return;
|
|
1275
1611
|
}
|
|
1276
|
-
console.log(
|
|
1612
|
+
console.log(chalk6.bold(`Team Members (${members.length})`));
|
|
1277
1613
|
console.log();
|
|
1278
1614
|
for (const member of members) {
|
|
1279
|
-
console.log(
|
|
1615
|
+
console.log(chalk6.cyan(`@${member.user?.username || "unknown"}`));
|
|
1280
1616
|
}
|
|
1281
1617
|
} catch (error) {
|
|
1282
|
-
console.error(
|
|
1618
|
+
console.error(chalk6.red(`Error: ${error.message}`));
|
|
1283
1619
|
process.exit(1);
|
|
1284
1620
|
}
|
|
1285
1621
|
});
|
|
@@ -1291,9 +1627,9 @@ function createOrgsCommand() {
|
|
|
1291
1627
|
username
|
|
1292
1628
|
}
|
|
1293
1629
|
);
|
|
1294
|
-
console.log(
|
|
1630
|
+
console.log(chalk6.green(`\u2713 Added @${username} to team ${team}`));
|
|
1295
1631
|
} catch (error) {
|
|
1296
|
-
console.error(
|
|
1632
|
+
console.error(chalk6.red(`Error: ${error.message}`));
|
|
1297
1633
|
process.exit(1);
|
|
1298
1634
|
}
|
|
1299
1635
|
});
|
|
@@ -1302,9 +1638,9 @@ function createOrgsCommand() {
|
|
|
1302
1638
|
await apiDelete(
|
|
1303
1639
|
`/api/organizations/${slug}/teams/${team}/members/${username}`
|
|
1304
1640
|
);
|
|
1305
|
-
console.log(
|
|
1641
|
+
console.log(chalk6.green(`\u2713 Removed @${username} from team ${team}`));
|
|
1306
1642
|
} catch (error) {
|
|
1307
|
-
console.error(
|
|
1643
|
+
console.error(chalk6.red(`Error: ${error.message}`));
|
|
1308
1644
|
process.exit(1);
|
|
1309
1645
|
}
|
|
1310
1646
|
});
|
|
@@ -1312,10 +1648,10 @@ function createOrgsCommand() {
|
|
|
1312
1648
|
}
|
|
1313
1649
|
|
|
1314
1650
|
// src/commands/user.ts
|
|
1315
|
-
import { Command as
|
|
1316
|
-
import
|
|
1651
|
+
import { Command as Command7 } from "commander";
|
|
1652
|
+
import chalk7 from "chalk";
|
|
1317
1653
|
function createUserCommand() {
|
|
1318
|
-
const user = new
|
|
1654
|
+
const user = new Command7("user").description("Manage user profile and settings");
|
|
1319
1655
|
user.command("profile").description("View user profile").argument("[username]", "Username (defaults to current user)").action(async (username) => {
|
|
1320
1656
|
try {
|
|
1321
1657
|
let profile;
|
|
@@ -1324,9 +1660,9 @@ function createUserCommand() {
|
|
|
1324
1660
|
} else {
|
|
1325
1661
|
profile = await apiGet("/api/users/me");
|
|
1326
1662
|
}
|
|
1327
|
-
console.log(
|
|
1663
|
+
console.log(chalk7.bold(`@${profile.username}`));
|
|
1328
1664
|
if (profile.name) {
|
|
1329
|
-
console.log(
|
|
1665
|
+
console.log(chalk7.dim(profile.name));
|
|
1330
1666
|
}
|
|
1331
1667
|
console.log();
|
|
1332
1668
|
if (profile.bio) {
|
|
@@ -1334,25 +1670,25 @@ function createUserCommand() {
|
|
|
1334
1670
|
console.log();
|
|
1335
1671
|
}
|
|
1336
1672
|
if (profile.location) {
|
|
1337
|
-
console.log(
|
|
1673
|
+
console.log(chalk7.dim(`\u{1F4CD} ${profile.location}`));
|
|
1338
1674
|
}
|
|
1339
1675
|
if (profile.website) {
|
|
1340
|
-
console.log(
|
|
1676
|
+
console.log(chalk7.dim(`\u{1F517} ${profile.website}`));
|
|
1341
1677
|
}
|
|
1342
1678
|
if (profile.company) {
|
|
1343
|
-
console.log(
|
|
1679
|
+
console.log(chalk7.dim(`\u{1F3E2} ${profile.company}`));
|
|
1344
1680
|
}
|
|
1345
1681
|
if (profile.pronouns) {
|
|
1346
|
-
console.log(
|
|
1682
|
+
console.log(chalk7.dim(`Pronouns: ${profile.pronouns}`));
|
|
1347
1683
|
}
|
|
1348
1684
|
if (profile.gitEmail) {
|
|
1349
|
-
console.log(
|
|
1685
|
+
console.log(chalk7.dim(`Git Email: ${profile.gitEmail}`));
|
|
1350
1686
|
}
|
|
1351
1687
|
console.log();
|
|
1352
|
-
console.log(
|
|
1353
|
-
console.log(
|
|
1688
|
+
console.log(chalk7.dim(`User type: ${profile.userType || "human"}`));
|
|
1689
|
+
console.log(chalk7.dim(`Joined: ${new Date(profile.createdAt).toLocaleDateString()}`));
|
|
1354
1690
|
} catch (error) {
|
|
1355
|
-
console.error(
|
|
1691
|
+
console.error(chalk7.red(`Error: ${error.message}`));
|
|
1356
1692
|
process.exit(1);
|
|
1357
1693
|
}
|
|
1358
1694
|
});
|
|
@@ -1368,16 +1704,16 @@ function createUserCommand() {
|
|
|
1368
1704
|
if (options.gitEmail !== void 0) updates.gitEmail = options.gitEmail;
|
|
1369
1705
|
if (Object.keys(updates).length === 0) {
|
|
1370
1706
|
console.log(
|
|
1371
|
-
|
|
1707
|
+
chalk7.yellow(
|
|
1372
1708
|
"No updates specified. Use --name, --bio, --location, --website, --pronouns, --company, or --git-email"
|
|
1373
1709
|
)
|
|
1374
1710
|
);
|
|
1375
1711
|
return;
|
|
1376
1712
|
}
|
|
1377
1713
|
await apiPatch("/api/users/me", updates);
|
|
1378
|
-
console.log(
|
|
1714
|
+
console.log(chalk7.green("\u2713 Profile updated successfully"));
|
|
1379
1715
|
} catch (error) {
|
|
1380
|
-
console.error(
|
|
1716
|
+
console.error(chalk7.red(`Error: ${error.message}`));
|
|
1381
1717
|
process.exit(1);
|
|
1382
1718
|
}
|
|
1383
1719
|
});
|
|
@@ -1388,24 +1724,24 @@ function createUserCommand() {
|
|
|
1388
1724
|
);
|
|
1389
1725
|
const users = results.users || [];
|
|
1390
1726
|
if (users.length === 0) {
|
|
1391
|
-
console.log(
|
|
1727
|
+
console.log(chalk7.yellow("No users found"));
|
|
1392
1728
|
return;
|
|
1393
1729
|
}
|
|
1394
|
-
console.log(
|
|
1730
|
+
console.log(chalk7.bold(`Users (${users.length})`));
|
|
1395
1731
|
console.log();
|
|
1396
1732
|
for (const u of users) {
|
|
1397
|
-
console.log(
|
|
1733
|
+
console.log(chalk7.cyan(`@${u.username}`));
|
|
1398
1734
|
if (u.name) {
|
|
1399
|
-
console.log(
|
|
1735
|
+
console.log(chalk7.dim(` ${u.name}`));
|
|
1400
1736
|
}
|
|
1401
1737
|
if (u.bio) {
|
|
1402
1738
|
const shortBio = u.bio.length > 60 ? u.bio.substring(0, 60) + "..." : u.bio;
|
|
1403
|
-
console.log(
|
|
1739
|
+
console.log(chalk7.dim(` ${shortBio}`));
|
|
1404
1740
|
}
|
|
1405
1741
|
console.log();
|
|
1406
1742
|
}
|
|
1407
1743
|
} catch (error) {
|
|
1408
|
-
console.error(
|
|
1744
|
+
console.error(chalk7.red(`Error: ${error.message}`));
|
|
1409
1745
|
process.exit(1);
|
|
1410
1746
|
}
|
|
1411
1747
|
});
|
|
@@ -1423,20 +1759,20 @@ function createUserCommand() {
|
|
|
1423
1759
|
);
|
|
1424
1760
|
const repositories = result.repos || [];
|
|
1425
1761
|
if (repositories.length === 0) {
|
|
1426
|
-
console.log(
|
|
1762
|
+
console.log(chalk7.yellow(`No repositories found for @${targetUsername}`));
|
|
1427
1763
|
return;
|
|
1428
1764
|
}
|
|
1429
|
-
console.log(
|
|
1765
|
+
console.log(chalk7.bold(`@${targetUsername}'s Repositories (${repositories.length})`));
|
|
1430
1766
|
console.log();
|
|
1431
1767
|
for (const repo of repositories) {
|
|
1432
1768
|
const visibility = repo.visibility === "private" ? "\u{1F512}" : "\u{1F310}";
|
|
1433
|
-
console.log(`${visibility} ${
|
|
1769
|
+
console.log(`${visibility} ${chalk7.cyan(repo.name)}`);
|
|
1434
1770
|
if (repo.description) {
|
|
1435
|
-
console.log(
|
|
1771
|
+
console.log(chalk7.dim(` ${repo.description}`));
|
|
1436
1772
|
}
|
|
1437
1773
|
}
|
|
1438
1774
|
} catch (error) {
|
|
1439
|
-
console.error(
|
|
1775
|
+
console.error(chalk7.red(`Error: ${error.message}`));
|
|
1440
1776
|
process.exit(1);
|
|
1441
1777
|
}
|
|
1442
1778
|
});
|
|
@@ -1449,7 +1785,7 @@ var __dirname2 = dirname(__filename2);
|
|
|
1449
1785
|
var packageJson = JSON.parse(
|
|
1450
1786
|
readFileSync(join2(__dirname2, "../package.json"), "utf-8")
|
|
1451
1787
|
);
|
|
1452
|
-
var program = new
|
|
1788
|
+
var program = new Command8();
|
|
1453
1789
|
program.name("forge").description("CLI tool for Kernelius Forge - the agent-native Git platform").version(packageJson.version);
|
|
1454
1790
|
program.addCommand(createAuthCommand());
|
|
1455
1791
|
program.addCommand(createReposCommand());
|
|
@@ -1457,4 +1793,5 @@ program.addCommand(createIssuesCommand());
|
|
|
1457
1793
|
program.addCommand(createPrsCommand());
|
|
1458
1794
|
program.addCommand(createOrgsCommand());
|
|
1459
1795
|
program.addCommand(createUserCommand());
|
|
1796
|
+
program.addCommand(createTemplatesCommand());
|
|
1460
1797
|
program.parse();
|