hacklab 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/README.md +67 -0
- package/dist/api/client.d.ts +118 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +214 -0
- package/dist/api/client.js.map +1 -0
- package/dist/commands/brag.d.ts +8 -0
- package/dist/commands/brag.d.ts.map +1 -0
- package/dist/commands/brag.js +318 -0
- package/dist/commands/brag.js.map +1 -0
- package/dist/commands/brag.utils.d.ts +12 -0
- package/dist/commands/brag.utils.d.ts.map +1 -0
- package/dist/commands/brag.utils.js +43 -0
- package/dist/commands/brag.utils.js.map +1 -0
- package/dist/commands/essay.d.ts +18 -0
- package/dist/commands/essay.d.ts.map +1 -0
- package/dist/commands/essay.js +117 -0
- package/dist/commands/essay.js.map +1 -0
- package/dist/commands/init.d.ts +16 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +237 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/join.d.ts +10 -0
- package/dist/commands/join.d.ts.map +1 -0
- package/dist/commands/join.js +314 -0
- package/dist/commands/join.js.map +1 -0
- package/dist/commands/link.d.ts +17 -0
- package/dist/commands/link.d.ts.map +1 -0
- package/dist/commands/link.js +36 -0
- package/dist/commands/link.js.map +1 -0
- package/dist/commands/login.d.ts +15 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +108 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/login.utils.d.ts +3 -0
- package/dist/commands/login.utils.d.ts.map +1 -0
- package/dist/commands/login.utils.js +13 -0
- package/dist/commands/login.utils.js.map +1 -0
- package/dist/commands/new.d.ts +15 -0
- package/dist/commands/new.d.ts.map +1 -0
- package/dist/commands/new.js +172 -0
- package/dist/commands/new.js.map +1 -0
- package/dist/commands/new.utils.d.ts +7 -0
- package/dist/commands/new.utils.d.ts.map +1 -0
- package/dist/commands/new.utils.js +50 -0
- package/dist/commands/new.utils.js.map +1 -0
- package/dist/commands/onboard.d.ts +10 -0
- package/dist/commands/onboard.d.ts.map +1 -0
- package/dist/commands/onboard.js +93 -0
- package/dist/commands/onboard.js.map +1 -0
- package/dist/commands/tui.d.ts +12 -0
- package/dist/commands/tui.d.ts.map +1 -0
- package/dist/commands/tui.js +112 -0
- package/dist/commands/tui.js.map +1 -0
- package/dist/commands/whoami.d.ts +2 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +23 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/help-format.d.ts +4 -0
- package/dist/help-format.d.ts.map +1 -0
- package/dist/help-format.js +30 -0
- package/dist/help-format.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +138 -0
- package/dist/index.js.map +1 -0
- package/dist/lab/config.d.ts +32 -0
- package/dist/lab/config.d.ts.map +1 -0
- package/dist/lab/config.js +148 -0
- package/dist/lab/config.js.map +1 -0
- package/dist/lab/contentStatus.d.ts +6 -0
- package/dist/lab/contentStatus.d.ts.map +1 -0
- package/dist/lab/contentStatus.js +19 -0
- package/dist/lab/contentStatus.js.map +1 -0
- package/dist/session.d.ts +18 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +158 -0
- package/dist/session.js.map +1 -0
- package/dist/ui/banner.d.ts +2 -0
- package/dist/ui/banner.d.ts.map +1 -0
- package/dist/ui/banner.js +22 -0
- package/dist/ui/banner.js.map +1 -0
- package/dist/utils/findRepoRoot.d.ts +2 -0
- package/dist/utils/findRepoRoot.d.ts.map +1 -0
- package/dist/utils/findRepoRoot.js +17 -0
- package/dist/utils/findRepoRoot.js.map +1 -0
- package/dist/utils/openBrowser.d.ts +2 -0
- package/dist/utils/openBrowser.d.ts.map +1 -0
- package/dist/utils/openBrowser.js +29 -0
- package/dist/utils/openBrowser.js.map +1 -0
- package/dist/utils/pathExists.d.ts +2 -0
- package/dist/utils/pathExists.d.ts.map +1 -0
- package/dist/utils/pathExists.js +11 -0
- package/dist/utils/pathExists.js.map +1 -0
- package/package.json +29 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { cancel, intro, isCancel, note, outro, select, text } from '@clack/prompts';
|
|
2
|
+
import { newCommand } from './new.js';
|
|
3
|
+
import { printTuiSplash } from '../ui/banner.js';
|
|
4
|
+
const SLASH_COMMANDS = [
|
|
5
|
+
{
|
|
6
|
+
command: '/new',
|
|
7
|
+
description: 'create new content',
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
command: '/help',
|
|
11
|
+
description: 'show commands',
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
command: '/exit',
|
|
15
|
+
description: 'leave tui',
|
|
16
|
+
},
|
|
17
|
+
];
|
|
18
|
+
export function parseSlashCommand(rawInput) {
|
|
19
|
+
const parts = rawInput.trim().split(/\s+/).filter(Boolean);
|
|
20
|
+
return {
|
|
21
|
+
command: parts[0] || '',
|
|
22
|
+
args: parts.slice(1),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export function getSlashCommandMatches(query) {
|
|
26
|
+
const normalized = query.trim().toLowerCase();
|
|
27
|
+
if (!normalized || normalized === '/') {
|
|
28
|
+
return [...SLASH_COMMANDS];
|
|
29
|
+
}
|
|
30
|
+
return SLASH_COMMANDS.filter((entry) => entry.command.startsWith(normalized));
|
|
31
|
+
}
|
|
32
|
+
function commandListText() {
|
|
33
|
+
return SLASH_COMMANDS.map((entry) => {
|
|
34
|
+
return `${entry.command} - ${entry.description}`;
|
|
35
|
+
}).join('\n');
|
|
36
|
+
}
|
|
37
|
+
async function pickSlashCommand(query) {
|
|
38
|
+
const matches = getSlashCommandMatches(query);
|
|
39
|
+
if (matches.length === 0) {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
const selected = await select({
|
|
43
|
+
message: 'slash commands',
|
|
44
|
+
options: matches.map((entry) => {
|
|
45
|
+
return {
|
|
46
|
+
value: entry.command,
|
|
47
|
+
label: `${entry.command} ${entry.description}`,
|
|
48
|
+
};
|
|
49
|
+
}),
|
|
50
|
+
});
|
|
51
|
+
if (isCancel(selected)) {
|
|
52
|
+
cancel('tui cancelled.');
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
return String(selected);
|
|
56
|
+
}
|
|
57
|
+
async function runSlashCommand(command, args) {
|
|
58
|
+
if (command === '/exit' || command === '/quit') {
|
|
59
|
+
outro('leaving hacklab tui.');
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
if (command === '/help') {
|
|
63
|
+
note(commandListText(), 'slash commands');
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
if (command === '/new') {
|
|
67
|
+
const type = args[0];
|
|
68
|
+
const slug = args[1];
|
|
69
|
+
await newCommand(type, slug);
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
note(`unknown command: ${command}. use /help to list commands.`, 'error');
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
export async function tuiCommand() {
|
|
76
|
+
printTuiSplash();
|
|
77
|
+
intro('hacklab tui');
|
|
78
|
+
note('type / to open slash commands', 'hint');
|
|
79
|
+
note(commandListText(), 'slash commands');
|
|
80
|
+
while (true) {
|
|
81
|
+
const input = await text({
|
|
82
|
+
message: 'tui',
|
|
83
|
+
placeholder: '/',
|
|
84
|
+
});
|
|
85
|
+
if (isCancel(input)) {
|
|
86
|
+
cancel('tui cancelled.');
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
const value = String(input).trim();
|
|
90
|
+
if (!value) {
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if (value.startsWith('/') && !value.includes(' ')) {
|
|
94
|
+
const selected = await pickSlashCommand(value);
|
|
95
|
+
if (!selected) {
|
|
96
|
+
note(`no slash commands found for "${value}".`, 'error');
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
const shouldExit = await runSlashCommand(selected, []);
|
|
100
|
+
if (shouldExit) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
const parsed = parseSlashCommand(value);
|
|
106
|
+
const shouldExit = await runSlashCommand(parsed.command, parsed.args);
|
|
107
|
+
if (shouldExit) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=tui.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tui.js","sourceRoot":"","sources":["../../src/commands/tui.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whoami.d.ts","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAMA,wBAAsB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAsBnD"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { intro, outro } from '@clack/prompts';
|
|
2
|
+
import { fetchCliWhoAmI } from '../api/client.js';
|
|
3
|
+
import { loadSession } from '../session.js';
|
|
4
|
+
import { getAppUrl } from './login.utils.js';
|
|
5
|
+
export async function whoamiCommand() {
|
|
6
|
+
intro('hacklab cli');
|
|
7
|
+
const session = await loadSession();
|
|
8
|
+
if (!session) {
|
|
9
|
+
outro('not logged in. run `hacklab login`.');
|
|
10
|
+
process.exitCode = 1;
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const appUrl = getAppUrl(session.appUrl);
|
|
14
|
+
const identity = await fetchCliWhoAmI(appUrl, session.token);
|
|
15
|
+
if (!identity) {
|
|
16
|
+
outro('your cli session is invalid or expired. run `hacklab login`.');
|
|
17
|
+
process.exitCode = 1;
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const nicknameLabel = session.nickname ? ` (${session.nickname})` : '';
|
|
21
|
+
outro(`logged in as ${identity.user.email}${nicknameLabel}`);
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=whoami.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whoami.js","sourceRoot":"","sources":["../../src/commands/whoami.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAE7C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAE5C,MAAM,CAAC,KAAK,UAAU,aAAa;IAC/B,KAAK,CAAC,aAAa,CAAC,CAAA;IAEpB,MAAM,OAAO,GAAG,MAAM,WAAW,EAAE,CAAA;IAEnC,IAAI,CAAC,OAAO,EAAE,CAAC;QACX,KAAK,CAAC,qCAAqC,CAAC,CAAA;QAC5C,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;QACpB,OAAM;IACV,CAAC;IAED,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IACxC,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAA;IAE5D,IAAI,CAAC,QAAQ,EAAE,CAAC;QACZ,KAAK,CAAC,8DAA8D,CAAC,CAAA;QACrE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAA;QACpB,OAAM;IACV,CAAC;IAED,MAAM,aAAa,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;IACtE,KAAK,CAAC,gBAAgB,QAAQ,CAAC,IAAI,CAAC,KAAK,GAAG,aAAa,EAAE,CAAC,CAAA;AAChE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help-format.d.ts","sourceRoot":"","sources":["../src/help-format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAkBrC,eAAO,MAAM,WAAW,QAMZ,CAAA;AAEZ,wBAAgB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAUrD"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const ANSI_RESET = '\x1b[0m';
|
|
2
|
+
const ANSI_BOLD = '\x1b[1m';
|
|
3
|
+
const ANSI_GREEN = '\x1b[32m';
|
|
4
|
+
function green(value) {
|
|
5
|
+
return `${ANSI_GREEN}${value}${ANSI_RESET}`;
|
|
6
|
+
}
|
|
7
|
+
function greenBold(value) {
|
|
8
|
+
return `${ANSI_BOLD}${ANSI_GREEN}${value}${ANSI_RESET}`;
|
|
9
|
+
}
|
|
10
|
+
function bold(value) {
|
|
11
|
+
return `${ANSI_BOLD}${value}${ANSI_RESET}`;
|
|
12
|
+
}
|
|
13
|
+
export const HELP_BANNER = [
|
|
14
|
+
'',
|
|
15
|
+
bold('👽 hacklab'),
|
|
16
|
+
'',
|
|
17
|
+
`${bold('☠︎')} ${greenBold('information wants to be free')} ${bold('☠︎')}`,
|
|
18
|
+
'',
|
|
19
|
+
].join('\n');
|
|
20
|
+
export function createGreenHelpConfig() {
|
|
21
|
+
return {
|
|
22
|
+
styleTitle: (title) => {
|
|
23
|
+
if (title === 'Options:' || title === 'Commands:') {
|
|
24
|
+
return greenBold(title);
|
|
25
|
+
}
|
|
26
|
+
return title;
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=help-format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help-format.js","sourceRoot":"","sources":["../src/help-format.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,GAAG,SAAS,CAAA;AAC5B,MAAM,SAAS,GAAG,SAAS,CAAA;AAC3B,MAAM,UAAU,GAAG,UAAU,CAAA;AAE7B,SAAS,KAAK,CAAC,KAAa;IACxB,OAAO,GAAG,UAAU,GAAG,KAAK,GAAG,UAAU,EAAE,CAAA;AAC/C,CAAC;AAED,SAAS,SAAS,CAAC,KAAa;IAC5B,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,KAAK,GAAG,UAAU,EAAE,CAAA;AAC3D,CAAC;AAED,SAAS,IAAI,CAAC,KAAa;IACvB,OAAO,GAAG,SAAS,GAAG,KAAK,GAAG,UAAU,EAAE,CAAA;AAC9C,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG;IACvB,EAAE;IACF,IAAI,CAAC,YAAY,CAAC;IAClB,EAAE;IACF,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC,8BAA8B,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE;IAC1E,EAAE;CACL,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAEZ,MAAM,UAAU,qBAAqB;IACjC,OAAO;QACH,UAAU,EAAE,CAAC,KAAa,EAAE,EAAE;YAC1B,IAAI,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,WAAW,EAAE,CAAC;gBAChD,OAAO,SAAS,CAAC,KAAK,CAAC,CAAA;YAC3B,CAAC;YAED,OAAO,KAAK,CAAA;QAChB,CAAC;KACJ,CAAA;AACL,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from "commander";
|
|
3
|
+
import { bragCommand } from "./commands/brag.js";
|
|
4
|
+
import { essayCommand } from "./commands/essay.js";
|
|
5
|
+
import { initCommand } from "./commands/init.js";
|
|
6
|
+
import { joinCommand } from "./commands/join.js";
|
|
7
|
+
import { linkCommand } from "./commands/link.js";
|
|
8
|
+
import { loginCommand } from "./commands/login.js";
|
|
9
|
+
import { newCommand } from "./commands/new.js";
|
|
10
|
+
import { onboardCommand } from "./commands/onboard.js";
|
|
11
|
+
import { tuiCommand } from "./commands/tui.js";
|
|
12
|
+
import { whoamiCommand } from "./commands/whoami.js";
|
|
13
|
+
import { createGreenHelpConfig, HELP_BANNER } from "./help-format.js";
|
|
14
|
+
const program = new Command();
|
|
15
|
+
program
|
|
16
|
+
.name("hacklab")
|
|
17
|
+
.description("hacklab command line tool")
|
|
18
|
+
.version("0.0.1")
|
|
19
|
+
.addHelpText("beforeAll", HELP_BANNER);
|
|
20
|
+
program.configureHelp(createGreenHelpConfig());
|
|
21
|
+
program
|
|
22
|
+
.command("join")
|
|
23
|
+
.description("authenticate account and optionally set up your hq")
|
|
24
|
+
.option("-a, --app-url <url>", "hacklab app url (defaults to localhost)")
|
|
25
|
+
.action(async (options) => {
|
|
26
|
+
await joinCommand({
|
|
27
|
+
appUrl: options.appUrl,
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
program
|
|
31
|
+
.command("brag")
|
|
32
|
+
.description("add current github project repo to your hacklab hq as draft")
|
|
33
|
+
.option("-a, --app-url <url>", "hacklab app url (defaults to localhost)")
|
|
34
|
+
.option("--as <account>", "account email or nickname to use")
|
|
35
|
+
.option("--hq <path>", "path to your hq repository")
|
|
36
|
+
.action(async (options) => {
|
|
37
|
+
await bragCommand({
|
|
38
|
+
appUrl: options.appUrl,
|
|
39
|
+
as: options.as,
|
|
40
|
+
hq: options.hq,
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
program
|
|
44
|
+
.command("essay")
|
|
45
|
+
.description("add an essay to your studio lab")
|
|
46
|
+
.option("-a, --app-url <url>", "hacklab app url (defaults to localhost)")
|
|
47
|
+
.option("-l, --lab <slug>", "lab slug (defaults to local .hacklab config)")
|
|
48
|
+
.option("-t, --title <title>", "essay title")
|
|
49
|
+
.option("-s, --summary <summary>", "essay summary")
|
|
50
|
+
.option("-b, --body <markdown>", "essay body markdown")
|
|
51
|
+
.option("-f, --file <path>", "read essay body markdown from file")
|
|
52
|
+
.option("-p, --publish", "publish immediately")
|
|
53
|
+
.action(async (options) => {
|
|
54
|
+
await essayCommand({
|
|
55
|
+
appUrl: options.appUrl,
|
|
56
|
+
lab: options.lab,
|
|
57
|
+
title: options.title,
|
|
58
|
+
summary: options.summary,
|
|
59
|
+
body: options.body,
|
|
60
|
+
file: options.file,
|
|
61
|
+
publish: options.publish,
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
program
|
|
65
|
+
.command("onboard")
|
|
66
|
+
.description("run cli onboarding (profile + lab)")
|
|
67
|
+
.option("-a, --app-url <url>", "hacklab app url (defaults to localhost)")
|
|
68
|
+
.option("-u, --username <username>", "profile username")
|
|
69
|
+
.option("-b, --bio <bio>", "profile bio")
|
|
70
|
+
.option("-l, --lab-name <name>", "lab name")
|
|
71
|
+
.action(async (options) => {
|
|
72
|
+
await onboardCommand({
|
|
73
|
+
appUrl: options.appUrl,
|
|
74
|
+
username: options.username,
|
|
75
|
+
bio: options.bio,
|
|
76
|
+
labName: options.labName,
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
program
|
|
80
|
+
.command("login")
|
|
81
|
+
.description("login with your browser and store session locally")
|
|
82
|
+
.option("-a, --app-url <url>", "hacklab app url (defaults to localhost)")
|
|
83
|
+
.action(async (options) => {
|
|
84
|
+
await loginCommand({
|
|
85
|
+
appUrl: options.appUrl,
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
program
|
|
89
|
+
.command("whoami")
|
|
90
|
+
.description("print current logged in account")
|
|
91
|
+
.action(async () => {
|
|
92
|
+
await whoamiCommand();
|
|
93
|
+
});
|
|
94
|
+
program
|
|
95
|
+
.command("init")
|
|
96
|
+
.description("initialize this repository as a hacklab repo")
|
|
97
|
+
.option("-n, --name <name>", "lab display name")
|
|
98
|
+
.option("-f, --force", "overwrite existing .hacklab/config.json")
|
|
99
|
+
.action(async (options) => {
|
|
100
|
+
await initCommand({
|
|
101
|
+
name: options.name,
|
|
102
|
+
force: options.force,
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
program
|
|
106
|
+
.command("new")
|
|
107
|
+
.description("create new hacklab content")
|
|
108
|
+
.argument("[type]", "project | guide | course | essay | research-paper")
|
|
109
|
+
.argument("[slug]", "content slug, e.g. my-first-project")
|
|
110
|
+
.option("-t, --title <title>", "custom title")
|
|
111
|
+
.action(async (type, slug, options) => {
|
|
112
|
+
await newCommand(type, slug, {
|
|
113
|
+
title: options.title,
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
program
|
|
117
|
+
.command("link")
|
|
118
|
+
.description("link an existing repository to hacklab without scaffolding")
|
|
119
|
+
.option("-n, --name <name>", "lab display name")
|
|
120
|
+
.option("-f, --force", "overwrite existing .hacklab/config.json")
|
|
121
|
+
.action(async (options) => {
|
|
122
|
+
await linkCommand({
|
|
123
|
+
name: options.name,
|
|
124
|
+
force: options.force,
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
program
|
|
128
|
+
.command("tui")
|
|
129
|
+
.alias("/tui")
|
|
130
|
+
.description("open hacklab tui entrypoint")
|
|
131
|
+
.action(async () => {
|
|
132
|
+
await tuiCommand();
|
|
133
|
+
});
|
|
134
|
+
program.parseAsync(process.argv).catch((error) => {
|
|
135
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
136
|
+
process.exit(1);
|
|
137
|
+
});
|
|
138
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export declare const HACKLAB_SCHEMA_VERSION = 1;
|
|
2
|
+
export type WorkspaceType = 'personal' | 'team' | 'org';
|
|
3
|
+
export type HacklabConfig = {
|
|
4
|
+
schemaVersion: number;
|
|
5
|
+
labId?: string;
|
|
6
|
+
labSlug: string;
|
|
7
|
+
labName: string;
|
|
8
|
+
workspaceType: WorkspaceType;
|
|
9
|
+
owner: string;
|
|
10
|
+
contentDirs: {
|
|
11
|
+
projects: string;
|
|
12
|
+
guides: string;
|
|
13
|
+
courses: string;
|
|
14
|
+
essays: string;
|
|
15
|
+
research: string;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
type CreateHacklabConfigOptions = {
|
|
19
|
+
labId?: string;
|
|
20
|
+
labSlug?: string;
|
|
21
|
+
labName: string;
|
|
22
|
+
workspaceType?: WorkspaceType;
|
|
23
|
+
owner?: string;
|
|
24
|
+
};
|
|
25
|
+
export declare function createDefaultHacklabConfig(options: string | CreateHacklabConfigOptions): HacklabConfig;
|
|
26
|
+
export declare function getHacklabConfigDir(repoRoot: string): string;
|
|
27
|
+
export declare function getHacklabConfigPath(repoRoot: string): string;
|
|
28
|
+
export declare function hasHacklabConfig(repoRoot: string): Promise<boolean>;
|
|
29
|
+
export declare function loadHacklabConfig(repoRoot: string): Promise<HacklabConfig | null>;
|
|
30
|
+
export declare function saveHacklabConfig(repoRoot: string, config: HacklabConfig): Promise<void>;
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lab/config.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,sBAAsB,IAAI,CAAA;AAEvC,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,MAAM,GAAG,KAAK,CAAA;AAEvD,MAAM,MAAM,aAAa,GAAG;IACxB,aAAa,EAAE,MAAM,CAAA;IACrB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,aAAa,EAAE,aAAa,CAAA;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE;QACT,QAAQ,EAAE,MAAM,CAAA;QAChB,MAAM,EAAE,MAAM,CAAA;QACd,OAAO,EAAE,MAAM,CAAA;QACf,MAAM,EAAE,MAAM,CAAA;QACd,QAAQ,EAAE,MAAM,CAAA;KACnB,CAAA;CACJ,CAAA;AAED,KAAK,0BAA0B,GAAG;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAA;CACjB,CAAA;AA0FD,wBAAgB,0BAA0B,CACtC,OAAO,EAAE,MAAM,GAAG,0BAA0B,GAC7C,aAAa,CAqBf;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEzE;AAED,wBAAsB,iBAAiB,CACnC,QAAQ,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CA+C/B;AAED,wBAAsB,iBAAiB,CACnC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,aAAa,GACtB,OAAO,CAAC,IAAI,CAAC,CAMf"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { pathExists } from '../utils/pathExists.js';
|
|
4
|
+
export const HACKLAB_SCHEMA_VERSION = 1;
|
|
5
|
+
const DEFAULT_CONTENT_DIRS = {
|
|
6
|
+
projects: 'projects',
|
|
7
|
+
guides: 'guides',
|
|
8
|
+
courses: 'courses',
|
|
9
|
+
essays: 'essays',
|
|
10
|
+
research: 'research',
|
|
11
|
+
};
|
|
12
|
+
const WORKSPACE_TYPES = ['personal', 'team', 'org'];
|
|
13
|
+
function slugify(rawValue) {
|
|
14
|
+
const normalized = rawValue
|
|
15
|
+
.trim()
|
|
16
|
+
.toLowerCase()
|
|
17
|
+
.replace(/[^a-z0-9\s-_]/g, '')
|
|
18
|
+
.replace(/[\s_]+/g, '-')
|
|
19
|
+
.replace(/-+/g, '-')
|
|
20
|
+
.replace(/^-|-$/g, '');
|
|
21
|
+
return normalized;
|
|
22
|
+
}
|
|
23
|
+
function normalizeLabName(rawName) {
|
|
24
|
+
const trimmed = rawName.trim();
|
|
25
|
+
if (!trimmed) {
|
|
26
|
+
return 'my-lab';
|
|
27
|
+
}
|
|
28
|
+
return trimmed;
|
|
29
|
+
}
|
|
30
|
+
function normalizeLabSlug(rawValue) {
|
|
31
|
+
const normalized = slugify(rawValue);
|
|
32
|
+
if (!normalized) {
|
|
33
|
+
return 'my-lab';
|
|
34
|
+
}
|
|
35
|
+
return normalized;
|
|
36
|
+
}
|
|
37
|
+
function normalizeOwner(rawValue) {
|
|
38
|
+
const normalized = rawValue
|
|
39
|
+
.trim()
|
|
40
|
+
.toLowerCase()
|
|
41
|
+
.replace(/\s+/g, '-')
|
|
42
|
+
.replace(/[^a-z0-9._-]/g, '');
|
|
43
|
+
if (!normalized) {
|
|
44
|
+
return 'unknown';
|
|
45
|
+
}
|
|
46
|
+
return normalized;
|
|
47
|
+
}
|
|
48
|
+
function getDefaultOwner() {
|
|
49
|
+
return (process.env.HACKLAB_OWNER ||
|
|
50
|
+
process.env.GITHUB_USER ||
|
|
51
|
+
process.env.GITHUB_ACTOR ||
|
|
52
|
+
process.env.USER ||
|
|
53
|
+
process.env.USERNAME ||
|
|
54
|
+
'unknown');
|
|
55
|
+
}
|
|
56
|
+
function normalizeWorkspaceType(value) {
|
|
57
|
+
if (typeof value !== 'string') {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
if (WORKSPACE_TYPES.includes(value)) {
|
|
61
|
+
return value;
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
function normalizeLabId(rawValue) {
|
|
66
|
+
if (typeof rawValue !== 'string') {
|
|
67
|
+
return undefined;
|
|
68
|
+
}
|
|
69
|
+
const trimmed = rawValue.trim();
|
|
70
|
+
return trimmed || undefined;
|
|
71
|
+
}
|
|
72
|
+
export function createDefaultHacklabConfig(options) {
|
|
73
|
+
const normalizedOptions = typeof options === 'string' ? { labName: options } : options;
|
|
74
|
+
const labName = normalizeLabName(normalizedOptions.labName);
|
|
75
|
+
const workspaceType = normalizedOptions.workspaceType ?? 'personal';
|
|
76
|
+
const labSlug = normalizeLabSlug(normalizedOptions.labSlug || labName);
|
|
77
|
+
const owner = normalizeOwner(normalizedOptions.owner || getDefaultOwner());
|
|
78
|
+
const labId = normalizeLabId(normalizedOptions.labId);
|
|
79
|
+
return {
|
|
80
|
+
schemaVersion: HACKLAB_SCHEMA_VERSION,
|
|
81
|
+
...(labId ? { labId } : {}),
|
|
82
|
+
labSlug,
|
|
83
|
+
labName,
|
|
84
|
+
workspaceType,
|
|
85
|
+
owner,
|
|
86
|
+
contentDirs: {
|
|
87
|
+
...DEFAULT_CONTENT_DIRS,
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
export function getHacklabConfigDir(repoRoot) {
|
|
92
|
+
return join(repoRoot, '.hacklab');
|
|
93
|
+
}
|
|
94
|
+
export function getHacklabConfigPath(repoRoot) {
|
|
95
|
+
return join(getHacklabConfigDir(repoRoot), 'config.json');
|
|
96
|
+
}
|
|
97
|
+
export async function hasHacklabConfig(repoRoot) {
|
|
98
|
+
return pathExists(getHacklabConfigPath(repoRoot));
|
|
99
|
+
}
|
|
100
|
+
export async function loadHacklabConfig(repoRoot) {
|
|
101
|
+
const configPath = getHacklabConfigPath(repoRoot);
|
|
102
|
+
if (!(await pathExists(configPath))) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
try {
|
|
106
|
+
const content = await readFile(configPath, 'utf8');
|
|
107
|
+
const parsed = JSON.parse(content);
|
|
108
|
+
const workspaceType = normalizeWorkspaceType(parsed.workspaceType);
|
|
109
|
+
if (parsed.schemaVersion !== HACKLAB_SCHEMA_VERSION ||
|
|
110
|
+
!parsed.labName ||
|
|
111
|
+
!workspaceType ||
|
|
112
|
+
!parsed.contentDirs?.projects ||
|
|
113
|
+
!parsed.contentDirs?.courses ||
|
|
114
|
+
!parsed.contentDirs?.essays ||
|
|
115
|
+
!parsed.contentDirs?.research) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
const labName = normalizeLabName(parsed.labName);
|
|
119
|
+
const owner = normalizeOwner(parsed.owner || getDefaultOwner());
|
|
120
|
+
const labSlug = normalizeLabSlug(parsed.labSlug || parsed.labName);
|
|
121
|
+
const labId = normalizeLabId(parsed.labId);
|
|
122
|
+
return {
|
|
123
|
+
schemaVersion: parsed.schemaVersion,
|
|
124
|
+
...(labId ? { labId } : {}),
|
|
125
|
+
labSlug,
|
|
126
|
+
labName,
|
|
127
|
+
workspaceType,
|
|
128
|
+
owner,
|
|
129
|
+
contentDirs: {
|
|
130
|
+
projects: parsed.contentDirs.projects,
|
|
131
|
+
guides: parsed.contentDirs.guides || DEFAULT_CONTENT_DIRS.guides,
|
|
132
|
+
courses: parsed.contentDirs.courses,
|
|
133
|
+
essays: parsed.contentDirs.essays,
|
|
134
|
+
research: parsed.contentDirs.research,
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
export async function saveHacklabConfig(repoRoot, config) {
|
|
143
|
+
const configDir = getHacklabConfigDir(repoRoot);
|
|
144
|
+
const configPath = getHacklabConfigPath(repoRoot);
|
|
145
|
+
await mkdir(configDir, { recursive: true });
|
|
146
|
+
await writeFile(configPath, `${JSON.stringify(config, null, 2)}\n`, 'utf8');
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lab/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const CONTENT_STATUSES: readonly ["idea", "draft", "in_progress", "in_review", "published", "archived"];
|
|
2
|
+
export type ContentStatus = (typeof CONTENT_STATUSES)[number];
|
|
3
|
+
export declare const DEFAULT_CONTENT_STATUS: ContentStatus;
|
|
4
|
+
export declare const DEFAULT_CONTENT_VISIBILITY = "private";
|
|
5
|
+
export declare const STATUS_DESCRIPTIONS: Record<ContentStatus, string>;
|
|
6
|
+
//# sourceMappingURL=contentStatus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contentStatus.d.ts","sourceRoot":"","sources":["../../src/lab/contentStatus.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,iFAOnB,CAAA;AAEV,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAA;AAE7D,eAAO,MAAM,sBAAsB,EAAE,aAAuB,CAAA;AAC5D,eAAO,MAAM,0BAA0B,YAAY,CAAA;AAEnD,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAO7D,CAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export const CONTENT_STATUSES = [
|
|
2
|
+
'idea',
|
|
3
|
+
'draft',
|
|
4
|
+
'in_progress',
|
|
5
|
+
'in_review',
|
|
6
|
+
'published',
|
|
7
|
+
'archived',
|
|
8
|
+
];
|
|
9
|
+
export const DEFAULT_CONTENT_STATUS = 'draft';
|
|
10
|
+
export const DEFAULT_CONTENT_VISIBILITY = 'private';
|
|
11
|
+
export const STATUS_DESCRIPTIONS = {
|
|
12
|
+
idea: 'early concept or note, no substantial draft yet',
|
|
13
|
+
draft: 'first pass exists but still rough',
|
|
14
|
+
in_progress: 'actively being developed toward completion',
|
|
15
|
+
in_review: 'ready for feedback before publishing',
|
|
16
|
+
published: 'live and considered complete for now',
|
|
17
|
+
archived: 'retired and not actively maintained',
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=contentStatus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contentStatus.js","sourceRoot":"","sources":["../../src/lab/contentStatus.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC5B,MAAM;IACN,OAAO;IACP,aAAa;IACb,WAAW;IACX,WAAW;IACX,UAAU;CACJ,CAAA;AAIV,MAAM,CAAC,MAAM,sBAAsB,GAAkB,OAAO,CAAA;AAC5D,MAAM,CAAC,MAAM,0BAA0B,GAAG,SAAS,CAAA;AAEnD,MAAM,CAAC,MAAM,mBAAmB,GAAkC;IAC9D,IAAI,EAAE,iDAAiD;IACvD,KAAK,EAAE,mCAAmC;IAC1C,WAAW,EAAE,4CAA4C;IACzD,SAAS,EAAE,sCAAsC;IACjD,SAAS,EAAE,sCAAsC;IACjD,QAAQ,EAAE,qCAAqC;CAClD,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type Session = {
|
|
2
|
+
email: string;
|
|
3
|
+
token: string;
|
|
4
|
+
loggedInAt: string;
|
|
5
|
+
appUrl?: string;
|
|
6
|
+
nickname?: string;
|
|
7
|
+
};
|
|
8
|
+
export type Account = Session & {
|
|
9
|
+
hqPaths?: string[];
|
|
10
|
+
activeHqPath?: string;
|
|
11
|
+
};
|
|
12
|
+
export declare function getSessionPath(): string;
|
|
13
|
+
export declare function getAccountsPath(): string;
|
|
14
|
+
export declare function saveSession(session: Session, sessionPath?: string): Promise<void>;
|
|
15
|
+
export declare function loadSession(sessionPath?: string): Promise<Session | null>;
|
|
16
|
+
export declare function loadKnownAccounts(): Promise<Account[]>;
|
|
17
|
+
export declare function linkHqToAccount(email: string, hqPath: string): Promise<void>;
|
|
18
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,OAAO,GAAG;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAKD,MAAM,MAAM,OAAO,GAAG,OAAO,GAAG;IAC5B,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAOD,wBAAgB,cAAc,IAAI,MAAM,CAMvC;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AA2DD,wBAAsB,WAAW,CAC7B,OAAO,EAAE,OAAO,EAChB,WAAW,SAAmB,GAC/B,OAAO,CAAC,IAAI,CAAC,CAwBf;AAED,wBAAsB,WAAW,CAC7B,WAAW,SAAmB,GAC/B,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CA2BzB;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAmB5D;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuClF"}
|