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,237 @@
|
|
|
1
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { basename, dirname, join, relative } from 'node:path';
|
|
3
|
+
import { cancel, intro, note, outro } from '@clack/prompts';
|
|
4
|
+
import { CONTENT_STATUSES, DEFAULT_CONTENT_STATUS, DEFAULT_CONTENT_VISIBILITY, STATUS_DESCRIPTIONS, } from '../lab/contentStatus.js';
|
|
5
|
+
import { createDefaultHacklabConfig, getHacklabConfigPath, hasHacklabConfig, saveHacklabConfig, } from '../lab/config.js';
|
|
6
|
+
import { findRepoRoot } from '../utils/findRepoRoot.js';
|
|
7
|
+
import { pathExists } from '../utils/pathExists.js';
|
|
8
|
+
function currentDate() {
|
|
9
|
+
return new Date().toISOString().slice(0, 10);
|
|
10
|
+
}
|
|
11
|
+
function buildFrontmatter(type, title) {
|
|
12
|
+
const date = currentDate();
|
|
13
|
+
return [
|
|
14
|
+
'---',
|
|
15
|
+
`title: ${title}`,
|
|
16
|
+
`type: ${type}`,
|
|
17
|
+
`status: ${DEFAULT_CONTENT_STATUS}`,
|
|
18
|
+
`visibility: ${DEFAULT_CONTENT_VISIBILITY}`,
|
|
19
|
+
`created_at: ${date}`,
|
|
20
|
+
`updated_at: ${date}`,
|
|
21
|
+
'---',
|
|
22
|
+
].join('\n');
|
|
23
|
+
}
|
|
24
|
+
function buildExampleContent(type, title, body) {
|
|
25
|
+
return [buildFrontmatter(type, title), '', ...body, ''].join('\n');
|
|
26
|
+
}
|
|
27
|
+
async function ensureDirectoryWithGitkeep(path) {
|
|
28
|
+
await mkdir(path, { recursive: true });
|
|
29
|
+
const gitkeepPath = join(path, '.gitkeep');
|
|
30
|
+
if (!(await pathExists(gitkeepPath))) {
|
|
31
|
+
await writeFile(gitkeepPath, '', 'utf8');
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
async function writeFileIfMissing(path, content) {
|
|
35
|
+
if (await pathExists(path)) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
await mkdir(dirname(path), { recursive: true });
|
|
39
|
+
await writeFile(path, content, 'utf8');
|
|
40
|
+
}
|
|
41
|
+
function buildContentModelDoc() {
|
|
42
|
+
const statusLines = CONTENT_STATUSES.map((status) => {
|
|
43
|
+
return `- \`${status}\`: ${STATUS_DESCRIPTIONS[status]}`;
|
|
44
|
+
});
|
|
45
|
+
return [
|
|
46
|
+
'# content model',
|
|
47
|
+
'',
|
|
48
|
+
'this repo stores authored content in these directories:',
|
|
49
|
+
'',
|
|
50
|
+
'- `profile/`',
|
|
51
|
+
'- `projects/`',
|
|
52
|
+
'- `guides/`',
|
|
53
|
+
'- `courses/`',
|
|
54
|
+
'- `essays/`',
|
|
55
|
+
'- `research/`',
|
|
56
|
+
'',
|
|
57
|
+
'## statuses',
|
|
58
|
+
'',
|
|
59
|
+
...statusLines,
|
|
60
|
+
'',
|
|
61
|
+
'## notes',
|
|
62
|
+
'',
|
|
63
|
+
'- use lowercase values for all status/type frontmatter fields.',
|
|
64
|
+
'- keep `status` and `visibility` separate.',
|
|
65
|
+
'- start new content as `draft` unless intentionally only an idea.',
|
|
66
|
+
'',
|
|
67
|
+
].join('\n');
|
|
68
|
+
}
|
|
69
|
+
function buildFrontmatterDoc() {
|
|
70
|
+
return [
|
|
71
|
+
'# frontmatter',
|
|
72
|
+
'',
|
|
73
|
+
'use this base frontmatter for all `.mdx` content:',
|
|
74
|
+
'',
|
|
75
|
+
'```mdx',
|
|
76
|
+
'---',
|
|
77
|
+
'title: my title',
|
|
78
|
+
'type: essay',
|
|
79
|
+
'status: draft',
|
|
80
|
+
'visibility: private',
|
|
81
|
+
'created_at: 2026-02-19',
|
|
82
|
+
'updated_at: 2026-02-19',
|
|
83
|
+
'---',
|
|
84
|
+
'```',
|
|
85
|
+
'',
|
|
86
|
+
'allowed statuses:',
|
|
87
|
+
'',
|
|
88
|
+
`- ${CONTENT_STATUSES.join(', ')}`,
|
|
89
|
+
'',
|
|
90
|
+
].join('\n');
|
|
91
|
+
}
|
|
92
|
+
function buildDocsReadme() {
|
|
93
|
+
return [
|
|
94
|
+
'# docs',
|
|
95
|
+
'',
|
|
96
|
+
'- `profile.mdx`: profile content and ownership guidance',
|
|
97
|
+
'- `content-model.mdx`: directory and status model',
|
|
98
|
+
'- `frontmatter.mdx`: canonical frontmatter format',
|
|
99
|
+
'',
|
|
100
|
+
].join('\n');
|
|
101
|
+
}
|
|
102
|
+
function buildProfileDoc() {
|
|
103
|
+
return [
|
|
104
|
+
'# profile content',
|
|
105
|
+
'',
|
|
106
|
+
'- personal profile content belongs in `profile/`.',
|
|
107
|
+
'- suggested files: `bio.mdx`, `cv.mdx`.',
|
|
108
|
+
'- keep lab identity and machine config in `.hacklab/config.json`.',
|
|
109
|
+
'',
|
|
110
|
+
].join('\n');
|
|
111
|
+
}
|
|
112
|
+
function buildHacklabMetadataReadme() {
|
|
113
|
+
return [
|
|
114
|
+
'# .hacklab metadata',
|
|
115
|
+
'',
|
|
116
|
+
'this folder stores hacklab metadata and tooling files only.',
|
|
117
|
+
'',
|
|
118
|
+
'- `config.json` defines local lab structure and defaults.',
|
|
119
|
+
'- identity fields include `labId` (optional), `labSlug`, `labName`, `owner`, `workspaceType`.',
|
|
120
|
+
'- do not store authored content here.',
|
|
121
|
+
'- authored content belongs in `profile/`, `projects/`, `guides/`, `courses/`, `essays/`, `research/`.',
|
|
122
|
+
'',
|
|
123
|
+
].join('\n');
|
|
124
|
+
}
|
|
125
|
+
export async function initializeRepository(repoRoot, options = {}) {
|
|
126
|
+
const configPath = getHacklabConfigPath(repoRoot);
|
|
127
|
+
if ((await hasHacklabConfig(repoRoot)) && !options.force) {
|
|
128
|
+
return {
|
|
129
|
+
status: 'already-initialized',
|
|
130
|
+
configPath,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
const defaultLabName = basename(repoRoot);
|
|
134
|
+
const config = createDefaultHacklabConfig({
|
|
135
|
+
labName: options.name || defaultLabName,
|
|
136
|
+
});
|
|
137
|
+
await saveHacklabConfig(repoRoot, config);
|
|
138
|
+
await ensureDirectoryWithGitkeep(join(repoRoot, 'assets'));
|
|
139
|
+
await ensureDirectoryWithGitkeep(join(repoRoot, 'profile'));
|
|
140
|
+
await ensureDirectoryWithGitkeep(join(repoRoot, config.contentDirs.projects));
|
|
141
|
+
await ensureDirectoryWithGitkeep(join(repoRoot, config.contentDirs.guides));
|
|
142
|
+
await ensureDirectoryWithGitkeep(join(repoRoot, config.contentDirs.courses));
|
|
143
|
+
await ensureDirectoryWithGitkeep(join(repoRoot, config.contentDirs.essays));
|
|
144
|
+
await ensureDirectoryWithGitkeep(join(repoRoot, config.contentDirs.research));
|
|
145
|
+
await writeFileIfMissing(join(repoRoot, 'home.mdx'), [
|
|
146
|
+
'# home',
|
|
147
|
+
'',
|
|
148
|
+
'welcome to your lab home.',
|
|
149
|
+
'',
|
|
150
|
+
'- run `hacklab tui` and type `/new` to create content.',
|
|
151
|
+
'',
|
|
152
|
+
].join('\n'));
|
|
153
|
+
await writeFileIfMissing(join(repoRoot, 'readme.mdx'), [
|
|
154
|
+
'# readme',
|
|
155
|
+
'',
|
|
156
|
+
'this repository is a hacklab.',
|
|
157
|
+
'',
|
|
158
|
+
].join('\n'));
|
|
159
|
+
await writeFileIfMissing(join(repoRoot, 'profile', 'bio.mdx'), [
|
|
160
|
+
'# bio',
|
|
161
|
+
'',
|
|
162
|
+
'write a short introduction about yourself.',
|
|
163
|
+
'',
|
|
164
|
+
].join('\n'));
|
|
165
|
+
await writeFileIfMissing(join(repoRoot, 'profile', 'cv.mdx'), [
|
|
166
|
+
'# cv',
|
|
167
|
+
'',
|
|
168
|
+
'list experience, projects, and education.',
|
|
169
|
+
'',
|
|
170
|
+
].join('\n'));
|
|
171
|
+
await writeFileIfMissing(join(repoRoot, config.contentDirs.projects, 'example-project', 'README.mdx'), buildExampleContent('project', 'example project', [
|
|
172
|
+
'# example project',
|
|
173
|
+
'',
|
|
174
|
+
'describe what you are building and why.',
|
|
175
|
+
]));
|
|
176
|
+
await writeFileIfMissing(join(repoRoot, config.contentDirs.guides, 'example-guide', 'README.mdx'), buildExampleContent('guide', 'example guide', [
|
|
177
|
+
'# example guide',
|
|
178
|
+
'',
|
|
179
|
+
'step-by-step guide content goes here.',
|
|
180
|
+
]));
|
|
181
|
+
await writeFileIfMissing(join(repoRoot, config.contentDirs.courses, 'example-course', 'README.mdx'), buildExampleContent('course', 'example course', [
|
|
182
|
+
'# example course',
|
|
183
|
+
'',
|
|
184
|
+
'outline modules, chapters, and outcomes.',
|
|
185
|
+
]));
|
|
186
|
+
await writeFileIfMissing(join(repoRoot, config.contentDirs.essays, 'example-essay.mdx'), buildExampleContent('essay', 'example essay', [
|
|
187
|
+
'# example essay',
|
|
188
|
+
'',
|
|
189
|
+
'write your perspective here.',
|
|
190
|
+
]));
|
|
191
|
+
await writeFileIfMissing(join(repoRoot, config.contentDirs.research, 'example-research-paper.mdx'), buildExampleContent('research-paper', 'example research paper', [
|
|
192
|
+
'# example research paper',
|
|
193
|
+
'',
|
|
194
|
+
'abstract:',
|
|
195
|
+
'',
|
|
196
|
+
'## notes',
|
|
197
|
+
]));
|
|
198
|
+
await writeFileIfMissing(join(repoRoot, 'docs', 'README.mdx'), buildDocsReadme());
|
|
199
|
+
await writeFileIfMissing(join(repoRoot, 'docs', 'profile.mdx'), buildProfileDoc());
|
|
200
|
+
await writeFileIfMissing(join(repoRoot, 'docs', 'content-model.mdx'), buildContentModelDoc());
|
|
201
|
+
await writeFileIfMissing(join(repoRoot, 'docs', 'frontmatter.mdx'), buildFrontmatterDoc());
|
|
202
|
+
await writeFileIfMissing(join(repoRoot, '.hacklab', 'README.mdx'), buildHacklabMetadataReadme());
|
|
203
|
+
return {
|
|
204
|
+
status: 'initialized',
|
|
205
|
+
configPath,
|
|
206
|
+
config,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
export async function initCommand(options = {}) {
|
|
210
|
+
intro('initialize hacklab repository');
|
|
211
|
+
const repoRoot = await findRepoRoot();
|
|
212
|
+
const result = await initializeRepository(repoRoot, options);
|
|
213
|
+
if (result.status === 'already-initialized') {
|
|
214
|
+
cancel(`hacklab is already initialized at ${relative(process.cwd(), result.configPath) || result.configPath}. use --force to overwrite config.`);
|
|
215
|
+
process.exit(1);
|
|
216
|
+
}
|
|
217
|
+
const config = result.config;
|
|
218
|
+
note(`initialized in ${repoRoot}`, 'repository');
|
|
219
|
+
note([
|
|
220
|
+
'- assets/',
|
|
221
|
+
'- profile/',
|
|
222
|
+
`- ${config.contentDirs.projects}/`,
|
|
223
|
+
`- ${config.contentDirs.guides}/`,
|
|
224
|
+
`- ${config.contentDirs.courses}/`,
|
|
225
|
+
`- ${config.contentDirs.essays}/`,
|
|
226
|
+
`- ${config.contentDirs.research}/`,
|
|
227
|
+
'- home.mdx',
|
|
228
|
+
'- readme.mdx',
|
|
229
|
+
'- profile/bio.mdx',
|
|
230
|
+
'- profile/cv.mdx',
|
|
231
|
+
'- docs/profile.mdx',
|
|
232
|
+
'- docs/content-model.mdx',
|
|
233
|
+
'- docs/frontmatter.mdx',
|
|
234
|
+
].join('\n'), 'created structure');
|
|
235
|
+
outro('hacklab repo initialized. run `hacklab new` to create your first entry.');
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
type JoinOptions = {
|
|
2
|
+
appUrl?: string;
|
|
3
|
+
};
|
|
4
|
+
export declare function normalizeRepoName(rawValue: string): string;
|
|
5
|
+
export declare function resolveWizardLocation(input: string, currentLocation: string): string;
|
|
6
|
+
export declare function pickDefaultBaseLocation(currentDirectory: string, homeDirectory: string, hasHomeGhDirectory: boolean): string;
|
|
7
|
+
export declare function normalizeAgentHandle(rawValue: string): string;
|
|
8
|
+
export declare function joinCommand(options?: JoinOptions): Promise<void>;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=join.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"join.d.ts","sourceRoot":"","sources":["../../src/commands/join.ts"],"names":[],"mappings":"AAeA,KAAK,WAAW,GAAG;IACf,MAAM,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAQD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,MAAM,CAQpF;AAED,wBAAgB,uBAAuB,CACnC,gBAAgB,EAAE,MAAM,EACxB,aAAa,EAAE,MAAM,EACrB,kBAAkB,EAAE,OAAO,GAC5B,MAAM,CAUR;AAgFD,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAO7D;AA0JD,wBAAsB,WAAW,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmH1E"}
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { mkdir } from 'node:fs/promises';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { relative, resolve } from 'node:path';
|
|
5
|
+
import { promisify } from 'node:util';
|
|
6
|
+
import { cancel, intro, isCancel, note, outro, select, text } from '@clack/prompts';
|
|
7
|
+
import { initializeRepository } from './init.js';
|
|
8
|
+
import { getAppUrl } from './login.utils.js';
|
|
9
|
+
import { loginCommand } from './login.js';
|
|
10
|
+
import { createPublicCliAgent } from '../api/client.js';
|
|
11
|
+
import { linkHqToAccount } from '../session.js';
|
|
12
|
+
import { pathExists } from '../utils/pathExists.js';
|
|
13
|
+
const execFileAsync = promisify(execFile);
|
|
14
|
+
export function normalizeRepoName(rawValue) {
|
|
15
|
+
return rawValue
|
|
16
|
+
.trim()
|
|
17
|
+
.toLowerCase()
|
|
18
|
+
.replace(/\s+/g, '-')
|
|
19
|
+
.replace(/[^a-z0-9._-]/g, '');
|
|
20
|
+
}
|
|
21
|
+
export function resolveWizardLocation(input, currentLocation) {
|
|
22
|
+
const normalized = input.trim();
|
|
23
|
+
if (!normalized) {
|
|
24
|
+
return currentLocation;
|
|
25
|
+
}
|
|
26
|
+
return resolve(currentLocation, normalized);
|
|
27
|
+
}
|
|
28
|
+
export function pickDefaultBaseLocation(currentDirectory, homeDirectory, hasHomeGhDirectory) {
|
|
29
|
+
if (currentDirectory && currentDirectory !== '/') {
|
|
30
|
+
return currentDirectory;
|
|
31
|
+
}
|
|
32
|
+
if (hasHomeGhDirectory) {
|
|
33
|
+
return resolve(homeDirectory, 'gh');
|
|
34
|
+
}
|
|
35
|
+
return homeDirectory;
|
|
36
|
+
}
|
|
37
|
+
async function getDefaultBaseLocation() {
|
|
38
|
+
const currentDirectory = process.cwd();
|
|
39
|
+
const homeDirectory = homedir();
|
|
40
|
+
const homeGhDirectory = resolve(homeDirectory, 'gh');
|
|
41
|
+
const hasHomeGhDirectory = await pathExists(homeGhDirectory);
|
|
42
|
+
return pickDefaultBaseLocation(currentDirectory, homeDirectory, hasHomeGhDirectory);
|
|
43
|
+
}
|
|
44
|
+
async function promptForLabLocation(initialLocation) {
|
|
45
|
+
let selectedLocation = initialLocation;
|
|
46
|
+
while (true) {
|
|
47
|
+
const action = await select({
|
|
48
|
+
message: `create hq in ${selectedLocation}?`,
|
|
49
|
+
options: [
|
|
50
|
+
{
|
|
51
|
+
value: 'continue',
|
|
52
|
+
label: 'yes, continue',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
value: 'change',
|
|
56
|
+
label: 'change location',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
value: 'exit',
|
|
60
|
+
label: 'exit',
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
});
|
|
64
|
+
if (isCancel(action)) {
|
|
65
|
+
cancel('join cancelled.');
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
const parsedAction = String(action);
|
|
69
|
+
if (parsedAction === 'continue') {
|
|
70
|
+
return selectedLocation;
|
|
71
|
+
}
|
|
72
|
+
if (parsedAction === 'exit') {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
const pathInput = await text({
|
|
76
|
+
message: 'new location',
|
|
77
|
+
placeholder: selectedLocation,
|
|
78
|
+
});
|
|
79
|
+
if (isCancel(pathInput)) {
|
|
80
|
+
cancel('join cancelled.');
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
selectedLocation = resolveWizardLocation(String(pathInput), selectedLocation);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
async function ensureGitRepository(repoLocation) {
|
|
87
|
+
if (await pathExists(resolve(repoLocation, '.git'))) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
await execFileAsync('git', ['init', '-q'], {
|
|
91
|
+
cwd: repoLocation,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
function defaultRepoName(nickname) {
|
|
95
|
+
return nickname ? `${nickname}-hq` : 'my-hq';
|
|
96
|
+
}
|
|
97
|
+
export function normalizeAgentHandle(rawValue) {
|
|
98
|
+
return rawValue
|
|
99
|
+
.trim()
|
|
100
|
+
.toLowerCase()
|
|
101
|
+
.replace(/[^a-z0-9-]/g, '-')
|
|
102
|
+
.replace(/-+/g, '-')
|
|
103
|
+
.replace(/^-|-$/g, '');
|
|
104
|
+
}
|
|
105
|
+
async function runAgentJoinFlow(options) {
|
|
106
|
+
const appUrl = getAppUrl(options.appUrl);
|
|
107
|
+
let result = null;
|
|
108
|
+
while (!result) {
|
|
109
|
+
const handleInput = await text({
|
|
110
|
+
message: 'agent handle',
|
|
111
|
+
placeholder: 'my-agent',
|
|
112
|
+
validate: (value) => {
|
|
113
|
+
const normalized = normalizeAgentHandle(String(value));
|
|
114
|
+
if (!normalized) {
|
|
115
|
+
return 'handle is required.';
|
|
116
|
+
}
|
|
117
|
+
if (normalized.length < 2) {
|
|
118
|
+
return 'handle must be at least 2 characters.';
|
|
119
|
+
}
|
|
120
|
+
if (normalized.length > 80) {
|
|
121
|
+
return 'handle must be at most 80 characters.';
|
|
122
|
+
}
|
|
123
|
+
return undefined;
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
if (isCancel(handleInput)) {
|
|
127
|
+
cancel('join cancelled.');
|
|
128
|
+
process.exit(1);
|
|
129
|
+
}
|
|
130
|
+
const handle = normalizeAgentHandle(String(handleInput));
|
|
131
|
+
const bioInput = await text({
|
|
132
|
+
message: 'agent bio',
|
|
133
|
+
placeholder: 'what does this agent do?',
|
|
134
|
+
});
|
|
135
|
+
if (isCancel(bioInput)) {
|
|
136
|
+
cancel('join cancelled.');
|
|
137
|
+
process.exit(1);
|
|
138
|
+
}
|
|
139
|
+
const avatarInput = await text({
|
|
140
|
+
message: 'profile pic url',
|
|
141
|
+
placeholder: 'https://...',
|
|
142
|
+
});
|
|
143
|
+
if (isCancel(avatarInput)) {
|
|
144
|
+
cancel('join cancelled.');
|
|
145
|
+
process.exit(1);
|
|
146
|
+
}
|
|
147
|
+
const bio = String(bioInput).trim();
|
|
148
|
+
const avatarUrl = String(avatarInput).trim();
|
|
149
|
+
try {
|
|
150
|
+
result = await createPublicCliAgent(appUrl, {
|
|
151
|
+
handle,
|
|
152
|
+
bio,
|
|
153
|
+
avatarUrl,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
158
|
+
if (message.toLowerCase().includes('handle') &&
|
|
159
|
+
message.toLowerCase().includes('taken')) {
|
|
160
|
+
note('handle is already taken. choose another one.', 'error');
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
if (message.toLowerCase().includes('invalid request payload')) {
|
|
164
|
+
note('invalid bio or profile pic url. try again.', 'error');
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
if (message.toLowerCase().includes('fetch failed')) {
|
|
168
|
+
cancel('cannot reach hacklab app. use `--app-url <url>`.');
|
|
169
|
+
process.exit(1);
|
|
170
|
+
}
|
|
171
|
+
cancel(`failed to create agent profile: ${message}`);
|
|
172
|
+
process.exit(1);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
note(result.agent.claimState.toLowerCase(), 'claim state');
|
|
176
|
+
note(result.agent.slug, 'handle');
|
|
177
|
+
note(result.profileUrl, 'profile');
|
|
178
|
+
note(result.claimUrl, 'claim link');
|
|
179
|
+
outro([
|
|
180
|
+
'agent join complete.',
|
|
181
|
+
'you are currently in unclaimed mode.',
|
|
182
|
+
'share the claim link with a human owner to activate gated capabilities.',
|
|
183
|
+
].join('\n'));
|
|
184
|
+
}
|
|
185
|
+
async function promptSetupAction() {
|
|
186
|
+
const value = await select({
|
|
187
|
+
message: 'set up your hq now?',
|
|
188
|
+
options: [
|
|
189
|
+
{
|
|
190
|
+
value: 'setup-now',
|
|
191
|
+
label: 'yes, set up hq now (recommended)',
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
value: 'skip',
|
|
195
|
+
label: 'skip for now',
|
|
196
|
+
},
|
|
197
|
+
],
|
|
198
|
+
});
|
|
199
|
+
if (isCancel(value)) {
|
|
200
|
+
return 'skip';
|
|
201
|
+
}
|
|
202
|
+
return String(value);
|
|
203
|
+
}
|
|
204
|
+
async function promptJoinIdentity() {
|
|
205
|
+
const value = await select({
|
|
206
|
+
message: 'who are you?',
|
|
207
|
+
options: [
|
|
208
|
+
{
|
|
209
|
+
value: 'human',
|
|
210
|
+
label: 'human',
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
value: 'agent',
|
|
214
|
+
label: 'agent',
|
|
215
|
+
},
|
|
216
|
+
],
|
|
217
|
+
});
|
|
218
|
+
if (isCancel(value)) {
|
|
219
|
+
cancel('join cancelled.');
|
|
220
|
+
process.exit(1);
|
|
221
|
+
}
|
|
222
|
+
return String(value);
|
|
223
|
+
}
|
|
224
|
+
export async function joinCommand(options = {}) {
|
|
225
|
+
intro('join hacklab');
|
|
226
|
+
const identity = await promptJoinIdentity();
|
|
227
|
+
note(`identity: ${identity}`, 'identity');
|
|
228
|
+
if (identity === 'agent') {
|
|
229
|
+
await runAgentJoinFlow(options);
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
const loginResult = await loginCommand({
|
|
233
|
+
appUrl: options.appUrl,
|
|
234
|
+
mode: 'join',
|
|
235
|
+
showIntro: false,
|
|
236
|
+
showSuccess: false,
|
|
237
|
+
showAuthorizeUrlWhenOpened: true,
|
|
238
|
+
});
|
|
239
|
+
const nicknameLabel = loginResult.nickname ? ` (${loginResult.nickname})` : '';
|
|
240
|
+
note(`joined as ${loginResult.email}${nicknameLabel}`, 'account');
|
|
241
|
+
const setupAction = await promptSetupAction();
|
|
242
|
+
if (setupAction === 'skip') {
|
|
243
|
+
outro([
|
|
244
|
+
'join complete.',
|
|
245
|
+
'next:',
|
|
246
|
+
'- run `hacklab init` in a new repo to scaffold a fresh hq',
|
|
247
|
+
'- or run `hacklab link` in an existing repo',
|
|
248
|
+
].join('\n'));
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
const defaultBaseLocation = await getDefaultBaseLocation();
|
|
252
|
+
const baseLocation = await promptForLabLocation(defaultBaseLocation);
|
|
253
|
+
if (!baseLocation) {
|
|
254
|
+
outro([
|
|
255
|
+
'join complete.',
|
|
256
|
+
'hq setup skipped.',
|
|
257
|
+
'run `hacklab init` or `hacklab link` when ready.',
|
|
258
|
+
].join('\n'));
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
const suggestedRepoName = defaultRepoName(loginResult.nickname);
|
|
262
|
+
const repoNameInput = await text({
|
|
263
|
+
message: 'hq repo name',
|
|
264
|
+
placeholder: suggestedRepoName,
|
|
265
|
+
validate: (value) => {
|
|
266
|
+
const rawValue = String(value).trim();
|
|
267
|
+
if (!rawValue) {
|
|
268
|
+
return undefined;
|
|
269
|
+
}
|
|
270
|
+
const normalized = normalizeRepoName(rawValue);
|
|
271
|
+
if (!normalized) {
|
|
272
|
+
return 'repository name is required.';
|
|
273
|
+
}
|
|
274
|
+
if (normalized.length < 2) {
|
|
275
|
+
return 'repository name must be at least 2 characters.';
|
|
276
|
+
}
|
|
277
|
+
if (normalized.length > 64) {
|
|
278
|
+
return 'repository name must be at most 64 characters.';
|
|
279
|
+
}
|
|
280
|
+
return undefined;
|
|
281
|
+
},
|
|
282
|
+
});
|
|
283
|
+
if (isCancel(repoNameInput)) {
|
|
284
|
+
outro([
|
|
285
|
+
'join complete.',
|
|
286
|
+
'hq setup skipped.',
|
|
287
|
+
'run `hacklab init` or `hacklab link` when ready.',
|
|
288
|
+
].join('\n'));
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
const repoName = normalizeRepoName(String(repoNameInput)) || suggestedRepoName;
|
|
292
|
+
const repoLocation = resolve(baseLocation, repoName);
|
|
293
|
+
await mkdir(repoLocation, { recursive: true });
|
|
294
|
+
try {
|
|
295
|
+
await ensureGitRepository(repoLocation);
|
|
296
|
+
}
|
|
297
|
+
catch {
|
|
298
|
+
cancel('failed to initialize git repository. make sure git is installed.');
|
|
299
|
+
process.exit(1);
|
|
300
|
+
}
|
|
301
|
+
const result = await initializeRepository(repoLocation, {
|
|
302
|
+
name: repoName,
|
|
303
|
+
});
|
|
304
|
+
if (result.status === 'already-initialized') {
|
|
305
|
+
note(`hq already initialized at ${repoLocation}`, 'hq');
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
note(`hq ready at ${repoLocation}`, 'hq');
|
|
309
|
+
}
|
|
310
|
+
await linkHqToAccount(loginResult.email, repoLocation);
|
|
311
|
+
const relativePath = relative(process.cwd(), repoLocation) || '.';
|
|
312
|
+
outro(`join complete.\nnext: cd ${relativePath} && hacklab tui`);
|
|
313
|
+
}
|
|
314
|
+
//# sourceMappingURL=join.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"join.js","sourceRoot":"","sources":["../../src/commands/join.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type HacklabConfig } from '../lab/config.js';
|
|
2
|
+
type LinkOptions = {
|
|
3
|
+
name?: string;
|
|
4
|
+
force?: boolean;
|
|
5
|
+
};
|
|
6
|
+
export type LinkResult = {
|
|
7
|
+
status: 'linked';
|
|
8
|
+
configPath: string;
|
|
9
|
+
config: HacklabConfig;
|
|
10
|
+
} | {
|
|
11
|
+
status: 'already-linked';
|
|
12
|
+
configPath: string;
|
|
13
|
+
};
|
|
14
|
+
export declare function linkRepository(repoRoot: string, options?: LinkOptions): Promise<LinkResult>;
|
|
15
|
+
export declare function linkCommand(options?: LinkOptions): Promise<void>;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=link.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../src/commands/link.ts"],"names":[],"mappings":"AAIA,OAAO,EAKH,KAAK,aAAa,EACrB,MAAM,kBAAkB,CAAA;AAGzB,KAAK,WAAW,GAAG;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,OAAO,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,UAAU,GAChB;IACI,MAAM,EAAE,QAAQ,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,aAAa,CAAA;CACxB,GACD;IACI,MAAM,EAAE,gBAAgB,CAAA;IACxB,UAAU,EAAE,MAAM,CAAA;CACrB,CAAA;AAEP,wBAAsB,cAAc,CAChC,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,WAAgB,GAC1B,OAAO,CAAC,UAAU,CAAC,CAqBrB;AAED,wBAAsB,WAAW,CAAC,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB1E"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { basename, relative } from 'node:path';
|
|
2
|
+
import { cancel, intro, note, outro } from '@clack/prompts';
|
|
3
|
+
import { createDefaultHacklabConfig, getHacklabConfigPath, hasHacklabConfig, saveHacklabConfig, } from '../lab/config.js';
|
|
4
|
+
import { findRepoRoot } from '../utils/findRepoRoot.js';
|
|
5
|
+
export async function linkRepository(repoRoot, options = {}) {
|
|
6
|
+
const configPath = getHacklabConfigPath(repoRoot);
|
|
7
|
+
if ((await hasHacklabConfig(repoRoot)) && !options.force) {
|
|
8
|
+
return {
|
|
9
|
+
status: 'already-linked',
|
|
10
|
+
configPath,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
const defaultLabName = basename(repoRoot);
|
|
14
|
+
const config = createDefaultHacklabConfig({
|
|
15
|
+
labName: options.name || defaultLabName,
|
|
16
|
+
});
|
|
17
|
+
await saveHacklabConfig(repoRoot, config);
|
|
18
|
+
return {
|
|
19
|
+
status: 'linked',
|
|
20
|
+
configPath,
|
|
21
|
+
config,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export async function linkCommand(options = {}) {
|
|
25
|
+
intro('link existing repository to hacklab');
|
|
26
|
+
const repoRoot = await findRepoRoot();
|
|
27
|
+
const result = await linkRepository(repoRoot, options);
|
|
28
|
+
if (result.status === 'already-linked') {
|
|
29
|
+
cancel(`repository is already linked at ${relative(process.cwd(), result.configPath) || result.configPath}. use --force to overwrite config.`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
note(`linked ${repoRoot}`, 'repository');
|
|
33
|
+
note(relative(process.cwd(), result.configPath) || result.configPath, 'config path');
|
|
34
|
+
outro('repository linked. no content folders were created.');
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=link.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"link.js","sourceRoot":"","sources":["../../src/commands/link.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAE9C,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAA;AAE3D,OAAO,EACH,0BAA0B,EAC1B,oBAAoB,EACpB,gBAAgB,EAChB,iBAAiB,GAEpB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AAkBvD,MAAM,CAAC,KAAK,UAAU,cAAc,CAChC,QAAgB,EAChB,UAAuB,EAAE;IAEzB,MAAM,UAAU,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAA;IAEjD,IAAI,CAAC,MAAM,gBAAgB,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACvD,OAAO;YACH,MAAM,EAAE,gBAAgB;YACxB,UAAU;SACb,CAAA;IACL,CAAC;IAED,MAAM,cAAc,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAA;IACzC,MAAM,MAAM,GAAG,0BAA0B,CAAC;QACtC,OAAO,EAAE,OAAO,CAAC,IAAI,IAAI,cAAc;KAC1C,CAAC,CAAA;IACF,MAAM,iBAAiB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;IAEzC,OAAO;QACH,MAAM,EAAE,QAAQ;QAChB,UAAU;QACV,MAAM;KACT,CAAA;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,UAAuB,EAAE;IACvD,KAAK,CAAC,qCAAqC,CAAC,CAAA;IAE5C,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAA;IACrC,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;IAEtD,IAAI,MAAM,CAAC,MAAM,KAAK,gBAAgB,EAAE,CAAC;QACrC,MAAM,CACF,mCAAmC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,UAAU,oCAAoC,CACzI,CAAA;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC;IAED,IAAI,CAAC,UAAU,QAAQ,EAAE,EAAE,YAAY,CAAC,CAAA;IACxC,IAAI,CACA,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,UAAU,EAC/D,aAAa,CAChB,CAAA;IACD,KAAK,CAAC,qDAAqD,CAAC,CAAA;AAChE,CAAC"}
|