Skip to content

Commit 39af167

Browse files
authored
Merge branch 'api-branch' into api/remove-git-feature
2 parents 92ee115 + ee9a422 commit 39af167

9 files changed

Lines changed: 253 additions & 17 deletions

File tree

packages/cli/package.json

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,17 @@
1414
},
1515
"keywords": [],
1616
"author": "",
17-
"license": "ISC",
17+
"license": "MIT",
1818
"dependencies": {
1919
"@octokit/rest": "^22.0.1",
20+
"adm-zip": "^0.5.17",
2021
"ansis": "^4.2.0",
2122
"citty": "^0.2.2"
2223
},
2324
"devDependencies": {
24-
"@types/node": "22.14.0",
25-
"@typescript/native-preview": "7.0.0-dev.20260418.1",
25+
"@types/adm-zip": "^0.5.8",
26+
"@types/node": "24.12.0",
27+
"@typescript/native-preview": "7.0.0-dev.20260502.1",
2628
"tsdown": "^0.21.7"
2729
}
2830
}

packages/cli/src/commands/new.ts

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
11
import { defineCommand } from 'citty';
2+
import * as fs from 'fs';
3+
import * as path from 'path';
4+
import * as os from 'os';
5+
import assert from 'assert';
6+
import { exec } from 'child_process';
27

38
export const newCommand = defineCommand({
49
meta: {
@@ -25,12 +30,68 @@ export const newCommand = defineCommand({
2530
},
2631
},
2732
async run(ctx) {
28-
if (!ctx.args.directory) console.warn(`No directory provided, defaulitng to ${process.cwd()}`);
33+
const targetDir = ctx.args.directory;
34+
35+
console.log(`Downloading template to ${targetDir}...`);
36+
37+
// Download the zipball
2938
const client = new (await import('@octokit/rest')).Octokit();
3039
const response = await client.repos.downloadZipballArchive({
3140
owner: 'VSC-NeuroPilot',
3241
repo: 'neuropilot-companion-template',
3342
ref: 'master',
3443
});
44+
45+
// Create a temporary file
46+
const tempDir = os.tmpdir();
47+
const tempZipPath = path.join(tempDir, `neuropilot-template-${Date.now()}.zip`);
48+
49+
// Write the zip data to the temp file
50+
// The response.data is a Buffer or ArrayBuffer
51+
fs.writeFileSync(tempZipPath, Buffer.from(response.data as ArrayBuffer));
52+
53+
// Extract the zip file
54+
const AdmZip = (await import('adm-zip')).default;
55+
const zip = new AdmZip(tempZipPath);
56+
const tempExtractDir = path.join(tempDir, `neuropilot-template-extract-${Date.now()}`);
57+
zip.extractAllTo(tempExtractDir, true);
58+
59+
// GitHub wraps the content in a folder named like "repo-ref"
60+
// Find that folder and copy its contents to the target directory
61+
const extractedContents = fs.readdirSync(tempExtractDir);
62+
assert(extractedContents.length !== 0, 'Extracted archive is empty');
63+
const wrappedFolder = extractedContents[0]!; // Should be the only item
64+
const sourceDir = path.join(tempExtractDir, wrappedFolder);
65+
66+
// Create target directory if it doesn't exist
67+
if (!fs.existsSync(targetDir)) {
68+
fs.mkdirSync(targetDir, { recursive: true });
69+
}
70+
71+
// Copy contents from source to target
72+
const copyRecursive = (src: string, dest: string) => {
73+
const items = fs.readdirSync(src);
74+
for (const item of items) {
75+
const srcPath = path.join(src, item);
76+
const destPath = path.join(dest, item);
77+
78+
if (fs.statSync(srcPath).isDirectory()) {
79+
fs.mkdirSync(destPath, { recursive: true });
80+
copyRecursive(srcPath, destPath);
81+
} else {
82+
fs.copyFileSync(srcPath, destPath);
83+
}
84+
}
85+
};
86+
87+
copyRecursive(sourceDir, targetDir);
88+
89+
// Clean up temporary files
90+
fs.rmSync(tempZipPath);
91+
fs.rmSync(tempExtractDir, { recursive: true });
92+
93+
console.log('Template downloaded successfully!');
94+
95+
// Handle git init and npm install based on args...
3596
},
3697
});

packages/cli/src/commands/test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { defineCommand } from 'citty';
2+
3+
export const testCommand = defineCommand({
4+
meta: {
5+
name: 'test',
6+
description: 'Install and open the integration test extension in VS Code.',
7+
hidden: true,
8+
},
9+
args: {
10+
version: {},
11+
github: {},
12+
vscode: {},
13+
},
14+
run(ctx) {},
15+
});

packages/cli/src/index.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
import { defineCommand, runMain } from 'citty';
22

3-
import { downloadCommand } from './commands/download';
4-
53
import pkg from '../package.json';
64

5+
import { downloadCommand } from './commands/download';
6+
import { newCommand } from './commands/new';
7+
import { testCommand } from './commands/test';
8+
79
const main = defineCommand({
810
meta: {
911
name: Object.keys(pkg.bin)[0]!,
1012
version: pkg.version,
1113
description: pkg.description,
1214
},
13-
subCommands: { download: downloadCommand },
15+
subCommands: { download: downloadCommand, new: newCommand, test: testCommand },
1416
});
1517

1618
runMain(main);

packages/types/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
},
2323
"keywords": [],
2424
"author": "KTrain5369",
25-
"license": "ISC",
25+
"license": "MIT",
2626
"devDependencies": {
2727
"@arethetypeswrong/core": "^0.18.2",
2828
"@types/vscode": "^1.95.0",

0 commit comments

Comments
 (0)