@a5gard/asgard 0.0.1
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/.env +2 -0
- package/.gitignore copy +6 -0
- package/.vscode/ntrsync/.vscode/ocrmnavigator/id.txt +1 -0
- package/.vscode/ntrsync/.vscode/ocrmnavigator.code-snippets +3664 -0
- package/.vscode/ntrsync/00002_CRM URGENT_todo.md +79 -0
- package/.vscode/ntrsync/10005_notes repo url.md +3 -0
- package/.vscode/ntrsync/10012_vscode_color_settings.md +133 -0
- package/.vscode/ntrsync/10013_Googles Snapchat Upload Hack note.md +11 -0
- package/.vscode/ntrsync/10014_APP IDEA - Lawyer CRM.md +229 -0
- package/.vscode/ntrsync/10015_APP IDEA - Onlyfans.md +293 -0
- package/.vscode/ntrsync/10016_notes repo url.md +3 -0
- package/.vscode/ntrsync/10504_adhd symptom.md +3 -0
- package/.vscode/ntrsync/10505_APP IDEA - GMAIL.md +39 -0
- package/.vscode/ntrsync/10506_container home - build mats.md +18 -0
- package/.vscode/ntrsync/10507_cleint facing site meta and loader function.md +25 -0
- package/.vscode/ntrsync/10508_Sabaak VSCode 1-8 players - private teams, solo q, duos q.md +11 -0
- package/.vscode/ntrsync/10509_schema dump.md +80 -0
- package/.vscode/ntrsync/10510_APPT BEACONHILL_reminder.md +7 -0
- package/.vscode/ntrsync/10512_clipboard very usefull should use asap within all apps.md +101 -0
- package/.vscode/ntrsync/10516_DevStack_todo.md +130 -0
- package/.vscode/ntrsync/10517_CRM_todo.md +95 -0
- package/.vscode/ntrsync/10518_Catalyst POS_todo.md +73 -0
- package/.vscode/ntrsync/10519_Catalyst Software_todo.md +497 -0
- package/.vscode/ntrsync/10523_new note.md +6 -0
- package/.vscode/ntrsync/10524_New Reminder_reminder.md +5 -0
- package/.vscode/ntrsync/10525_Mobile - Notes, To-Dos And Things_todo.md +4 -0
- package/.vscode/ntrsync/90002_COMPLETED_todo.md +97 -0
- package/.vscode/ntrsync/README.md +1 -0
- package/.vscode/ocrmnavigator/id.txt +1 -0
- package/.vscode/ocrmnavigator.code-snippets +349 -0
- package/.vscode/settings.json +1 -0
- package/CHANGELOG.md +6 -0
- package/LICENSE.md +21 -0
- package/README.md +1612 -0
- package/bin/dev.cmd +3 -0
- package/bin/dev.js +17 -0
- package/bin/run.cmd +3 -0
- package/bin/run.js +5 -0
- package/config.asgard +8 -0
- package/dist/commands/add-source.d.ts +9 -0
- package/dist/commands/add-source.d.ts.map +1 -0
- package/dist/commands/add-source.js +68 -0
- package/dist/commands/add-source.js.map +1 -0
- package/dist/commands/baldr.d.ts +5 -0
- package/dist/commands/baldr.d.ts.map +1 -0
- package/dist/commands/baldr.js +35 -0
- package/dist/commands/baldr.js.map +1 -0
- package/dist/commands/combine-timelines.d.ts +5 -0
- package/dist/commands/combine-timelines.d.ts.map +1 -0
- package/dist/commands/combine-timelines.js +53 -0
- package/dist/commands/combine-timelines.js.map +1 -0
- package/dist/commands/create-project.d.ts +10 -0
- package/dist/commands/create-project.d.ts.map +1 -0
- package/dist/commands/create-project.js +195 -0
- package/dist/commands/create-project.js.map +1 -0
- package/dist/commands/create-timeline.d.ts +8 -0
- package/dist/commands/create-timeline.d.ts.map +1 -0
- package/dist/commands/create-timeline.js +54 -0
- package/dist/commands/create-timeline.js.map +1 -0
- package/dist/commands/delete-project.d.ts +5 -0
- package/dist/commands/delete-project.d.ts.map +1 -0
- package/dist/commands/delete-project.js +47 -0
- package/dist/commands/delete-project.js.map +1 -0
- package/dist/commands/delete-source.d.ts +8 -0
- package/dist/commands/delete-source.d.ts.map +1 -0
- package/dist/commands/delete-source.js +57 -0
- package/dist/commands/delete-source.js.map +1 -0
- package/dist/commands/delete-timeline.d.ts +8 -0
- package/dist/commands/delete-timeline.d.ts.map +1 -0
- package/dist/commands/delete-timeline.js +54 -0
- package/dist/commands/delete-timeline.js.map +1 -0
- package/dist/commands/delete-version.d.ts +8 -0
- package/dist/commands/delete-version.d.ts.map +1 -0
- package/dist/commands/delete-version.js +65 -0
- package/dist/commands/delete-version.js.map +1 -0
- package/dist/commands/download-file.d.ts +17 -0
- package/dist/commands/download-file.d.ts.map +1 -0
- package/dist/commands/download-file.js +87 -0
- package/dist/commands/download-file.js.map +1 -0
- package/dist/commands/download-folder.d.ts +18 -0
- package/dist/commands/download-folder.d.ts.map +1 -0
- package/dist/commands/download-folder.js +111 -0
- package/dist/commands/download-folder.js.map +1 -0
- package/dist/commands/download-source.d.ts +12 -0
- package/dist/commands/download-source.d.ts.map +1 -0
- package/dist/commands/download-source.js +46 -0
- package/dist/commands/download-source.js.map +1 -0
- package/dist/commands/gh-setup.d.ts +7 -0
- package/dist/commands/gh-setup.d.ts.map +1 -0
- package/dist/commands/gh-setup.js +106 -0
- package/dist/commands/gh-setup.js.map +1 -0
- package/dist/commands/load-project.d.ts +5 -0
- package/dist/commands/load-project.d.ts.map +1 -0
- package/dist/commands/load-project.js +56 -0
- package/dist/commands/load-project.js.map +1 -0
- package/dist/commands/menu.d.ts +5 -0
- package/dist/commands/menu.d.ts.map +1 -0
- package/dist/commands/menu.js +41 -0
- package/dist/commands/menu.js.map +1 -0
- package/dist/commands/midgardr.d.ts +5 -0
- package/dist/commands/midgardr.d.ts.map +1 -0
- package/dist/commands/midgardr.js +24 -0
- package/dist/commands/midgardr.js.map +1 -0
- package/dist/commands/publish-project.d.ts +5 -0
- package/dist/commands/publish-project.d.ts.map +1 -0
- package/dist/commands/publish-project.js +102 -0
- package/dist/commands/publish-project.js.map +1 -0
- package/dist/commands/replace-timeline.d.ts +8 -0
- package/dist/commands/replace-timeline.d.ts.map +1 -0
- package/dist/commands/replace-timeline.js +63 -0
- package/dist/commands/replace-timeline.js.map +1 -0
- package/dist/commands/restore-version.d.ts +8 -0
- package/dist/commands/restore-version.d.ts.map +1 -0
- package/dist/commands/restore-version.js +67 -0
- package/dist/commands/restore-version.js.map +1 -0
- package/dist/commands/save-project.d.ts +8 -0
- package/dist/commands/save-project.d.ts.map +1 -0
- package/dist/commands/save-project.js +43 -0
- package/dist/commands/save-project.js.map +1 -0
- package/dist/commands/set-source.d.ts +9 -0
- package/dist/commands/set-source.d.ts.map +1 -0
- package/dist/commands/set-source.js +59 -0
- package/dist/commands/set-source.js.map +1 -0
- package/dist/commands/switch-timeline.d.ts +8 -0
- package/dist/commands/switch-timeline.d.ts.map +1 -0
- package/dist/commands/switch-timeline.js +61 -0
- package/dist/commands/switch-timeline.js.map +1 -0
- package/dist/commands/sync-source.d.ts +5 -0
- package/dist/commands/sync-source.d.ts.map +1 -0
- package/dist/commands/sync-source.js +29 -0
- package/dist/commands/sync-source.js.map +1 -0
- package/dist/commands/upload-project+++.d.ts +5 -0
- package/dist/commands/upload-project+++.d.ts.map +1 -0
- package/dist/commands/upload-project+++.js +32 -0
- package/dist/commands/upload-project+++.js.map +1 -0
- package/dist/commands/upload-project++.d.ts +5 -0
- package/dist/commands/upload-project++.d.ts.map +1 -0
- package/dist/commands/upload-project++.js +33 -0
- package/dist/commands/upload-project++.js.map +1 -0
- package/dist/commands/upload-project+.d.ts +5 -0
- package/dist/commands/upload-project+.d.ts.map +1 -0
- package/dist/commands/upload-project+.js +40 -0
- package/dist/commands/upload-project+.js.map +1 -0
- package/dist/commands/upload-project.d.ts +5 -0
- package/dist/commands/upload-project.d.ts.map +1 -0
- package/dist/commands/upload-project.js +29 -0
- package/dist/commands/upload-project.js.map +1 -0
- package/dist/commands/view-timeline.d.ts +5 -0
- package/dist/commands/view-timeline.d.ts.map +1 -0
- package/dist/commands/view-timeline.js +39 -0
- package/dist/commands/view-timeline.js.map +1 -0
- package/dist/commands/view-versions.d.ts +5 -0
- package/dist/commands/view-versions.d.ts.map +1 -0
- package/dist/commands/view-versions.js +45 -0
- package/dist/commands/view-versions.js.map +1 -0
- package/dist/git/helpers.d.ts +10 -0
- package/dist/git/helpers.d.ts.map +1 -0
- package/dist/git/helpers.js +300 -0
- package/dist/git/helpers.js.map +1 -0
- package/dist/git/sync-repo.d.ts +2 -0
- package/dist/git/sync-repo.d.ts.map +1 -0
- package/dist/git/sync-repo.js +17 -0
- package/dist/git/sync-repo.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/box.d.ts +11 -0
- package/dist/utils/box.d.ts.map +1 -0
- package/dist/utils/box.js +158 -0
- package/dist/utils/box.js.map +1 -0
- package/ideas.md +46 -0
- package/package.json +53 -0
- package/src/commands/add-source.js +72 -0
- package/src/commands/baldr.js +38 -0
- package/src/commands/combine-timelines.js +65 -0
- package/src/commands/create-project.js +216 -0
- package/src/commands/create-timeline.js +60 -0
- package/src/commands/delete-project.js +54 -0
- package/src/commands/delete-source.js +63 -0
- package/src/commands/delete-timeline.js +63 -0
- package/src/commands/delete-version.js +74 -0
- package/src/commands/download-file.js +101 -0
- package/src/commands/download-folder.js +123 -0
- package/src/commands/download-source.js +51 -0
- package/src/commands/gh-setup.js +77 -0
- package/src/commands/load-project.js +63 -0
- package/src/commands/menu.js +46 -0
- package/src/commands/midgardr.js +25 -0
- package/src/commands/publish-project.js +167 -0
- package/src/commands/replace-timeline.js +76 -0
- package/src/commands/restore-version.js +80 -0
- package/src/commands/save-project.js +48 -0
- package/src/commands/set-source.js +65 -0
- package/src/commands/switch-timeline.js +69 -0
- package/src/commands/sync-source.js +32 -0
- package/src/commands/upload-project+++.js +34 -0
- package/src/commands/upload-project++.js +35 -0
- package/src/commands/upload-project+.js +47 -0
- package/src/commands/upload-project.js +31 -0
- package/src/commands/view-timeline.js +43 -0
- package/src/commands/view-versions.js +50 -0
- package/src/git/helpers.js +333 -0
- package/src/git/sync-repo.js +16 -0
- package/src/index.js +2 -0
- package/src/utils/box.js +282 -0
- package/tsconfig.json +23 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { Command, Flags } from '@oclif/core';
|
|
2
|
+
import { execSync } from 'child_process';
|
|
3
|
+
import { ux } from '@oclif/core';
|
|
4
|
+
import ora from 'ora';
|
|
5
|
+
import { boxStart, boxDivider, boxEnd, boxLine } from '../utils/box.js';
|
|
6
|
+
|
|
7
|
+
export default class DeleteVersion extends Command {
|
|
8
|
+
static description = 'Delete git tags (local and remote)';
|
|
9
|
+
|
|
10
|
+
static flags = {
|
|
11
|
+
tag: Flags.string({ char: 't', description: 'Tag name' })
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
async run() {
|
|
15
|
+
const cwd = process.cwd();
|
|
16
|
+
boxStart('Delete Version');
|
|
17
|
+
|
|
18
|
+
const { flags } = await this.parse(DeleteVersion);
|
|
19
|
+
let tagName = flags.tag;
|
|
20
|
+
|
|
21
|
+
const spinner = ora('Loading tags...').start();
|
|
22
|
+
|
|
23
|
+
let tags = [];
|
|
24
|
+
try {
|
|
25
|
+
const tagsRaw = execSync('git tag', { cwd, encoding: 'utf8' }).trim();
|
|
26
|
+
tags = tagsRaw ? tagsRaw.split('\n').reverse() : [];
|
|
27
|
+
} catch (e) {
|
|
28
|
+
tags = [];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
spinner.stop();
|
|
32
|
+
|
|
33
|
+
if (tags.length === 0) {
|
|
34
|
+
boxLine('No tags found', 'warning');
|
|
35
|
+
boxDivider();
|
|
36
|
+
boxEnd(false, 'No tags available');
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (!tagName) {
|
|
41
|
+
boxLine('Please select a tag to delete:');
|
|
42
|
+
boxDivider();
|
|
43
|
+
|
|
44
|
+
tagName = await ux.select({
|
|
45
|
+
message: 'Select tag to delete',
|
|
46
|
+
options: tags.map(t => ({ label: t, value: t }))
|
|
47
|
+
});
|
|
48
|
+
boxDivider();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const deleteSpinner = ora(`Deleting tag '${tagName}'...`).start();
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
execSync(`git tag -d ${tagName}`, { cwd, stdio: 'pipe' });
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
execSync(`git push origin --delete ${tagName}`, { cwd, stdio: 'pipe' });
|
|
58
|
+
boxLine(`Tag '${tagName}' deleted locally and from origin`, 'success');
|
|
59
|
+
} catch (remoteError) {
|
|
60
|
+
boxLine(`Tag '${tagName}' deleted locally (failed to delete from remote)`, 'warning');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
deleteSpinner.stop();
|
|
64
|
+
boxDivider();
|
|
65
|
+
boxEnd(true, 'Complete');
|
|
66
|
+
} catch (error) {
|
|
67
|
+
deleteSpinner.stop();
|
|
68
|
+
const msg = error.stderr ? error.stderr.toString() : error.message;
|
|
69
|
+
boxLine(msg, 'error');
|
|
70
|
+
boxDivider();
|
|
71
|
+
boxEnd(false, 'Delete failed');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { Command, Flags } from '@oclif/core';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import { downloadFile } from '../git/helpers.js';
|
|
4
|
+
import { boxStart, boxDivider, boxEnd, boxLine } from '../utils/box.js';
|
|
5
|
+
import { syncRepo } from '../git/sync-repo.js';
|
|
6
|
+
|
|
7
|
+
export default class DownloadFile extends Command {
|
|
8
|
+
static description = 'Download a specific file from a GitHub repository';
|
|
9
|
+
|
|
10
|
+
static args = [
|
|
11
|
+
{ name: 'repo', description: 'Repository owner/repo', required: false },
|
|
12
|
+
{ name: 'file', description: 'File path to download', required: false },
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
static flags = {
|
|
16
|
+
url: Flags.string({ char: 'u', description: 'Full GitHub URL to file' }),
|
|
17
|
+
owner: Flags.string({ char: 'o', description: 'Repository owner' }),
|
|
18
|
+
repo: Flags.string({ char: 'r', description: 'Repository name' }),
|
|
19
|
+
path: Flags.string({ char: 'p', description: 'File path in repository' }),
|
|
20
|
+
branch: Flags.string({ char: 'b', description: 'Branch name', default: 'main' }),
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
async run() {
|
|
24
|
+
boxStart('Download File');
|
|
25
|
+
|
|
26
|
+
await syncRepo();
|
|
27
|
+
const { args, flags } = await this.parse(DownloadFile);
|
|
28
|
+
|
|
29
|
+
let owner, repo, filePath, branch;
|
|
30
|
+
|
|
31
|
+
if (flags.url) {
|
|
32
|
+
const urlPattern = /github\.com\/([^\/]+)\/([^\/]+)\/blob\/([^\/]+)\/(.+)/;
|
|
33
|
+
const match = flags.url.match(urlPattern);
|
|
34
|
+
|
|
35
|
+
if (!match) {
|
|
36
|
+
boxLine('Invalid GitHub URL format', 'error');
|
|
37
|
+
boxDivider();
|
|
38
|
+
boxEnd(false, 'Invalid URL');
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
[, owner, repo, branch, filePath] = match;
|
|
43
|
+
await downloadFile(owner, repo, filePath, branch);
|
|
44
|
+
boxDivider();
|
|
45
|
+
boxEnd(true, 'Complete');
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (flags.owner && flags.repo && flags.path) {
|
|
50
|
+
owner = flags.owner;
|
|
51
|
+
repo = flags.repo;
|
|
52
|
+
filePath = flags.path;
|
|
53
|
+
branch = flags.branch;
|
|
54
|
+
await downloadFile(owner, repo, filePath, branch);
|
|
55
|
+
boxDivider();
|
|
56
|
+
boxEnd(true, 'Complete');
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let repoArg = args.repo;
|
|
61
|
+
let fileArg = args.file;
|
|
62
|
+
|
|
63
|
+
if (!repoArg || !fileArg) {
|
|
64
|
+
boxLine('Download a specific file from a GitHub repository.');
|
|
65
|
+
boxDivider();
|
|
66
|
+
|
|
67
|
+
const response = await inquirer.prompt([
|
|
68
|
+
{
|
|
69
|
+
type: 'input',
|
|
70
|
+
name: 'repo',
|
|
71
|
+
message: 'Repository owner/repo:',
|
|
72
|
+
prefix: '',
|
|
73
|
+
suffix: '',
|
|
74
|
+
when: !repoArg,
|
|
75
|
+
validate: input => input.trim().length > 0 || 'Repository cannot be empty',
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
type: 'input',
|
|
79
|
+
name: 'file',
|
|
80
|
+
message: 'File path:',
|
|
81
|
+
prefix: '',
|
|
82
|
+
suffix: '',
|
|
83
|
+
when: !fileArg,
|
|
84
|
+
validate: input => input.trim().length > 0 || 'File path cannot be empty',
|
|
85
|
+
},
|
|
86
|
+
]);
|
|
87
|
+
|
|
88
|
+
repoArg = repoArg || response.repo;
|
|
89
|
+
fileArg = fileArg || response.file;
|
|
90
|
+
boxDivider();
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const parts = repoArg.replace('https://github.com/', '').replace('.git', '').split('/');
|
|
94
|
+
owner = parts[0];
|
|
95
|
+
repo = parts[1] || parts[0];
|
|
96
|
+
|
|
97
|
+
await downloadFile(owner, repo, fileArg, flags.branch);
|
|
98
|
+
boxDivider();
|
|
99
|
+
boxEnd(true, 'Complete');
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { Command, Flags } from '@oclif/core';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import { downloadFolder, downloadFolderRaw } from '../git/helpers.js';
|
|
4
|
+
import { boxStart, boxDivider, boxEnd, boxLine } from '../utils/box.js';
|
|
5
|
+
import { syncRepo } from '../git/sync-repo.js';
|
|
6
|
+
|
|
7
|
+
export default class DownloadFolder extends Command {
|
|
8
|
+
static description = 'Download a specific folder from a GitHub repository';
|
|
9
|
+
|
|
10
|
+
static args = [
|
|
11
|
+
{ name: 'repo', description: 'Repository URL or owner/repo', required: false },
|
|
12
|
+
{ name: 'folder', description: 'Folder path to download', required: false },
|
|
13
|
+
];
|
|
14
|
+
|
|
15
|
+
static flags = {
|
|
16
|
+
url: Flags.string({ char: 'u', description: 'Full GitHub URL to folder' }),
|
|
17
|
+
owner: Flags.string({ char: 'o', description: 'Repository owner' }),
|
|
18
|
+
repo: Flags.string({ char: 'r', description: 'Repository name' }),
|
|
19
|
+
path: Flags.string({ char: 'p', description: 'Folder path in repository' }),
|
|
20
|
+
branch: Flags.string({ char: 'b', description: 'Branch name', default: 'main' }),
|
|
21
|
+
raw: Flags.boolean({ description: 'Use raw HTTP method instead of sparse checkout', default: false }),
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
async run() {
|
|
25
|
+
boxStart('Download Folder');
|
|
26
|
+
|
|
27
|
+
await syncRepo();
|
|
28
|
+
const { args, flags } = await this.parse(DownloadFolder);
|
|
29
|
+
|
|
30
|
+
let owner, repo, folderPath, branch;
|
|
31
|
+
|
|
32
|
+
if (flags.url) {
|
|
33
|
+
const urlPattern = /github\.com\/([^\/]+)\/([^\/]+)\/(?:tree|blob)\/([^\/]+)\/(.+)/;
|
|
34
|
+
const match = flags.url.match(urlPattern);
|
|
35
|
+
|
|
36
|
+
if (!match) {
|
|
37
|
+
boxLine('Invalid GitHub URL format', 'error');
|
|
38
|
+
boxDivider();
|
|
39
|
+
boxEnd(false, 'Invalid URL');
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
[, owner, repo, branch, folderPath] = match;
|
|
44
|
+
|
|
45
|
+
if (flags.raw) {
|
|
46
|
+
await downloadFolderRaw(owner, repo, folderPath, branch);
|
|
47
|
+
} else {
|
|
48
|
+
const repoUrl = `https://github.com/${owner}/${repo}.git`;
|
|
49
|
+
await downloadFolder(repoUrl, folderPath, branch);
|
|
50
|
+
}
|
|
51
|
+
boxDivider();
|
|
52
|
+
boxEnd(true, 'Complete');
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (flags.owner && flags.repo && flags.path) {
|
|
57
|
+
owner = flags.owner;
|
|
58
|
+
repo = flags.repo;
|
|
59
|
+
folderPath = flags.path;
|
|
60
|
+
branch = flags.branch;
|
|
61
|
+
|
|
62
|
+
if (flags.raw) {
|
|
63
|
+
await downloadFolderRaw(owner, repo, folderPath, branch);
|
|
64
|
+
} else {
|
|
65
|
+
const repoUrl = `https://github.com/${owner}/${repo}.git`;
|
|
66
|
+
await downloadFolder(repoUrl, folderPath, branch);
|
|
67
|
+
}
|
|
68
|
+
boxDivider();
|
|
69
|
+
boxEnd(true, 'Complete');
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let repoArg = args.repo;
|
|
74
|
+
let folderArg = args.folder;
|
|
75
|
+
|
|
76
|
+
if (!repoArg || !folderArg) {
|
|
77
|
+
boxLine('Download a specific folder from a GitHub repository.');
|
|
78
|
+
boxLine('Default method: Sparse checkout (works with any Git provider)');
|
|
79
|
+
boxLine('Raw method (--raw): Direct HTTP download (GitHub only)');
|
|
80
|
+
boxDivider();
|
|
81
|
+
|
|
82
|
+
const response = await inquirer.prompt([
|
|
83
|
+
{
|
|
84
|
+
type: 'input',
|
|
85
|
+
name: 'repo',
|
|
86
|
+
message: 'Repository URL or owner/repo:',
|
|
87
|
+
prefix: '',
|
|
88
|
+
suffix: '',
|
|
89
|
+
when: !repoArg,
|
|
90
|
+
validate: input => input.trim().length > 0 || 'Repository cannot be empty',
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
type: 'input',
|
|
94
|
+
name: 'folder',
|
|
95
|
+
message: 'Folder path:',
|
|
96
|
+
prefix: '',
|
|
97
|
+
suffix: '',
|
|
98
|
+
when: !folderArg,
|
|
99
|
+
validate: input => input.trim().length > 0 || 'Folder path cannot be empty',
|
|
100
|
+
},
|
|
101
|
+
]);
|
|
102
|
+
|
|
103
|
+
repoArg = repoArg || response.repo;
|
|
104
|
+
folderArg = folderArg || response.folder;
|
|
105
|
+
boxDivider();
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (flags.raw) {
|
|
109
|
+
const parts = repoArg.replace('https://github.com/', '').replace('.git', '').split('/');
|
|
110
|
+
owner = parts[0];
|
|
111
|
+
repo = parts[1];
|
|
112
|
+
await downloadFolderRaw(owner, repo, folderArg, flags.branch);
|
|
113
|
+
} else {
|
|
114
|
+
let repoUrl = repoArg;
|
|
115
|
+
if (!repoUrl.startsWith('http')) {
|
|
116
|
+
repoUrl = `https://github.com/${repoArg}.git`;
|
|
117
|
+
}
|
|
118
|
+
await downloadFolder(repoUrl, folderArg, flags.branch);
|
|
119
|
+
}
|
|
120
|
+
boxDivider();
|
|
121
|
+
boxEnd(true, 'Complete');
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Command, Flags } from '@oclif/core';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import { cloneRepo } from '../git/helpers.js';
|
|
4
|
+
import { boxStart, boxDivider, boxEnd, boxLine } from '../utils/box.js';
|
|
5
|
+
|
|
6
|
+
export default class Download extends Command {
|
|
7
|
+
static description = 'Clone a GitHub repository';
|
|
8
|
+
|
|
9
|
+
static args = [{ name: 'repo', description: 'URL or owner/repo' }];
|
|
10
|
+
|
|
11
|
+
static flags = {
|
|
12
|
+
dir: Flags.string({ char: 'd', description: 'Target directory' }),
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
async run() {
|
|
16
|
+
const { args, flags } = await this.parse(Download);
|
|
17
|
+
boxStart('Clone Repository');
|
|
18
|
+
|
|
19
|
+
let repoInput = args.repo;
|
|
20
|
+
|
|
21
|
+
// 1. Prompt if no arg provided
|
|
22
|
+
if (!repoInput) {
|
|
23
|
+
const answers = await inquirer.prompt([{
|
|
24
|
+
type: 'input',
|
|
25
|
+
name: 'repo',
|
|
26
|
+
message: 'Repository (URL or owner/repo):',
|
|
27
|
+
prefix: '', suffix: '',
|
|
28
|
+
validate: i => i.trim().length > 0
|
|
29
|
+
}]);
|
|
30
|
+
repoInput = answers.repo;
|
|
31
|
+
boxDivider();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// 2. Format the URL (Assume GitHub if it's just owner/repo)
|
|
35
|
+
const repoUrl = repoInput.startsWith('http')
|
|
36
|
+
? repoInput
|
|
37
|
+
: `https://github.com/${repoInput}.git`;
|
|
38
|
+
|
|
39
|
+
// 3. Execution
|
|
40
|
+
try {
|
|
41
|
+
await cloneRepo(repoUrl, flags.dir || '');
|
|
42
|
+
boxLine(`Cloned to ${flags.dir || 'current directory'}`, 'success');
|
|
43
|
+
boxDivider();
|
|
44
|
+
boxEnd(true, 'Complete');
|
|
45
|
+
} catch (error) {
|
|
46
|
+
boxLine(error.message, 'error');
|
|
47
|
+
boxDivider();
|
|
48
|
+
boxEnd(false, 'Clone failed');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
import { execSync } from 'child_process';
|
|
3
|
+
import { existsSync } from 'fs';
|
|
4
|
+
import { homedir } from 'os';
|
|
5
|
+
import { join } from 'path';
|
|
6
|
+
import { boxStart, boxEnd, boxLine, boxDivider, boxList, boxPrompt, boxWaitForEnter} from '../utils/box.js';
|
|
7
|
+
|
|
8
|
+
export default class GhSetup extends Command {
|
|
9
|
+
static description = 'Step-by-step guide to install and authenticate GitHub CLI';
|
|
10
|
+
|
|
11
|
+
async run() {
|
|
12
|
+
try {
|
|
13
|
+
boxStart('Asgard: GitHub CLI Setup');
|
|
14
|
+
|
|
15
|
+
boxLine('1. Download & Install the official GitHub CLI');
|
|
16
|
+
boxLine(' Direct Link: https://cli.github.com/');
|
|
17
|
+
boxLine(' (Or run: winget install --id GitHub.cli)');
|
|
18
|
+
|
|
19
|
+
boxLine('Press [ENTER] once you have finished the installation...', 'warning');
|
|
20
|
+
|
|
21
|
+
await boxWaitForEnter();
|
|
22
|
+
|
|
23
|
+
this.refreshWindowsPath();
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
boxDivider();
|
|
27
|
+
boxLine('3. Authenticating with GitHub...', 'info');
|
|
28
|
+
boxLine(' The browser will open to link your account.', 'info');
|
|
29
|
+
boxLine(' Choose SSH when prompted for preferred protocol.', 'warning');
|
|
30
|
+
boxDivider();
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
execSync(`gh auth login`, { stdio: 'inherit' });
|
|
34
|
+
|
|
35
|
+
boxDivider();
|
|
36
|
+
boxLine('✓ GitHub CLI is now ready to use!', 'success');
|
|
37
|
+
boxEnd(true, 'Setup Complete');
|
|
38
|
+
} catch (error) {
|
|
39
|
+
boxLine('Authentication was cancelled or failed.', 'error');
|
|
40
|
+
boxLine(`Error: ${error.message}`, 'error');
|
|
41
|
+
if (error.stderr) boxLine(`Details: ${error.stderr.toString()}`, 'error');
|
|
42
|
+
boxLine('Note: If you just installed it, you might need to try opening a new terminal.', 'warning');
|
|
43
|
+
boxEnd(false, 'Setup Failed');
|
|
44
|
+
}
|
|
45
|
+
} catch (error) {
|
|
46
|
+
console.error('Fatal error:');
|
|
47
|
+
console.error(error.message);
|
|
48
|
+
console.error(error.stack);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
refreshWindowsPath() {
|
|
54
|
+
if (process.platform === 'win32') {
|
|
55
|
+
try {
|
|
56
|
+
const updatedPath = execSync(
|
|
57
|
+
`powershell -NoProfile -Command "[Environment]::GetEnvironmentVariable('Path', 'Machine') + ';' + [Environment]::GetEnvironmentVariable('Path', 'User')"`
|
|
58
|
+
).toString().trim();
|
|
59
|
+
|
|
60
|
+
if (updatedPath) {
|
|
61
|
+
process.env.PATH = updatedPath;
|
|
62
|
+
}
|
|
63
|
+
} catch (e) {
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async waitForEnter() {
|
|
69
|
+
return new Promise((resolve) => {
|
|
70
|
+
process.stdin.resume();
|
|
71
|
+
process.stdin.once('data', () => {
|
|
72
|
+
process.stdin.pause();
|
|
73
|
+
resolve();
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
import { execSync } from 'child_process';
|
|
3
|
+
import { ux } from '@oclif/core';
|
|
4
|
+
import ora from 'ora';
|
|
5
|
+
import { boxStart, boxDivider, boxEnd, boxLine } from '../utils/box.js';
|
|
6
|
+
|
|
7
|
+
export default class LoadProject extends Command {
|
|
8
|
+
static description = 'Restore stashed work';
|
|
9
|
+
|
|
10
|
+
async run() {
|
|
11
|
+
const cwd = process.cwd();
|
|
12
|
+
boxStart('Load Project');
|
|
13
|
+
|
|
14
|
+
const spinner = ora('Loading stash list...').start();
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
let stashRaw = '';
|
|
18
|
+
try {
|
|
19
|
+
stashRaw = execSync('git stash list', { cwd, encoding: 'utf8' }).trim();
|
|
20
|
+
} catch (e) {
|
|
21
|
+
// Git returns error if not a repo
|
|
22
|
+
}
|
|
23
|
+
spinner.stop();
|
|
24
|
+
|
|
25
|
+
if (!stashRaw) {
|
|
26
|
+
boxLine('No stashes found', 'warning');
|
|
27
|
+
boxDivider();
|
|
28
|
+
boxEnd(false, 'No stashes available');
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const stashes = stashRaw.split('\n').map((line, index) => ({
|
|
33
|
+
label: line,
|
|
34
|
+
value: index
|
|
35
|
+
}));
|
|
36
|
+
|
|
37
|
+
boxLine('Please select a stash to restore:');
|
|
38
|
+
boxDivider();
|
|
39
|
+
|
|
40
|
+
const stashIndex = await ux.select({
|
|
41
|
+
message: 'Select stash to restore',
|
|
42
|
+
options: stashes
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
boxDivider();
|
|
46
|
+
|
|
47
|
+
const restoreSpinner = ora('Restoring stash...').start();
|
|
48
|
+
// Using pop to restore and remove from list
|
|
49
|
+
execSync(`git stash pop stash@{${stashIndex}}`, { cwd, stdio: 'pipe' });
|
|
50
|
+
|
|
51
|
+
restoreSpinner.stop();
|
|
52
|
+
boxLine('Stash restored', 'success');
|
|
53
|
+
boxDivider();
|
|
54
|
+
boxEnd(true, 'Complete');
|
|
55
|
+
} catch (error) {
|
|
56
|
+
spinner.stop();
|
|
57
|
+
const msg = error.stderr ? error.stderr.toString() : error.message;
|
|
58
|
+
boxLine(msg, 'error');
|
|
59
|
+
boxDivider();
|
|
60
|
+
boxEnd(false, 'Load failed');
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
import { ux } from '@oclif/core';
|
|
3
|
+
import { boxStart, boxDivider, boxEnd, boxLine } from '../utils/box.js';
|
|
4
|
+
|
|
5
|
+
export default class Index extends Command {
|
|
6
|
+
static description = 'Asgard CLI - Interactive menu';
|
|
7
|
+
|
|
8
|
+
async run() {
|
|
9
|
+
boxStart('Asgard CLI');
|
|
10
|
+
boxLine('Select a command to run:');
|
|
11
|
+
boxDivider();
|
|
12
|
+
|
|
13
|
+
const command = await ux.select({
|
|
14
|
+
message: 'What would you like to do?',
|
|
15
|
+
options: [
|
|
16
|
+
{ label: 'Install BALDR Icons - Icons library for react applications', value: 'baldr' },
|
|
17
|
+
{ label: 'GH Setup - githubs CLI is required for some functionality', value: 'create-project' },
|
|
18
|
+
{ label: 'Create Project - Create a new project with GitHub repository', value: 'create-project' },
|
|
19
|
+
{ label: 'Publish Project - Create GitHub repository for existing project', value: 'publish-project' },
|
|
20
|
+
{ label: 'Download - Clone a GitHub repository', value: 'download' },
|
|
21
|
+
{ label: 'Download File - Download a specific file from a repository', value: 'download-file' },
|
|
22
|
+
{ label: 'Download Folder - Download a specific folder from a repository', value: 'download-folder' },
|
|
23
|
+
{ label: 'Save - Add, commit, and push changes', value: 'save' },
|
|
24
|
+
{ label: 'Load Project - Restore stashed work', value: 'load-project' },
|
|
25
|
+
{ label: 'Create Timeline - Create a new branch', value: 'create-timeline' },
|
|
26
|
+
{ label: 'Delete Timeline - Delete a branch', value: 'delete-timeline' },
|
|
27
|
+
{ label: 'Replace Timeline - Merge branch into main and delete source', value: 'replace-timeline' },
|
|
28
|
+
{ label: 'Delete Version - Delete git tags', value: 'delete-version' },
|
|
29
|
+
{ label: 'Set Source - Replace remote URL', value: 'set-source' },
|
|
30
|
+
{ label: 'Delete Source - Remove a remote', value: 'delete-source' },
|
|
31
|
+
{ label: 'Exit', value: 'exit' }
|
|
32
|
+
]
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
boxDivider();
|
|
36
|
+
|
|
37
|
+
if (command === 'exit') {
|
|
38
|
+
boxEnd(true, 'Goodbye!');
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
boxEnd(true, `Running ${command}...`);
|
|
43
|
+
|
|
44
|
+
await this.config.runCommand(command);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// src/commands/midgardr.js
|
|
2
|
+
import { Command } from '@oclif/core'
|
|
3
|
+
import { execSync } from 'child_process';
|
|
4
|
+
|
|
5
|
+
export default class MidgardrCommand extends Command {
|
|
6
|
+
static description = 'UI components installation and management'
|
|
7
|
+
static strict = false
|
|
8
|
+
|
|
9
|
+
async run(){
|
|
10
|
+
const { argv } = await this.parse(MidgardrCommand)
|
|
11
|
+
const cwd = process.cwd();
|
|
12
|
+
|
|
13
|
+
// SILENTLY check if midgardr is installed
|
|
14
|
+
try {
|
|
15
|
+
execSync('midgardr --version', { cwd, stdio: 'inherit' });
|
|
16
|
+
} catch {
|
|
17
|
+
// SILENTLY install if not found
|
|
18
|
+
execSync('npm install -g @a5gard/midgardr-cli', { cwd, stdio: 'inherit' });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// COMPLETE PASSTHROUGH - run midgardr with all arguments
|
|
22
|
+
// This shows midgardr's output exactly as if user ran it directly
|
|
23
|
+
execSync(`midgardr ${argv}`, {cwd, stdio: 'inherit' })
|
|
24
|
+
}
|
|
25
|
+
}
|