create-hq 10.12.3 → 10.12.4
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/dist/__tests__/fetch-template.test.d.ts +2 -0
- package/dist/__tests__/fetch-template.test.d.ts.map +1 -0
- package/dist/__tests__/fetch-template.test.js +103 -0
- package/dist/__tests__/fetch-template.test.js.map +1 -0
- package/dist/fetch-template.d.ts +14 -0
- package/dist/fetch-template.d.ts.map +1 -1
- package/dist/fetch-template.js +72 -10
- package/dist/fetch-template.js.map +1 -1
- package/package.json +7 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-template.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/fetch-template.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import fs from "fs-extra";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
import * as os from "os";
|
|
5
|
+
import { extractTemplateDirFromTar } from "../fetch-template.js";
|
|
6
|
+
/**
|
|
7
|
+
* CREATE-HQ-2 regression coverage for the Windows extraction path.
|
|
8
|
+
*
|
|
9
|
+
* On Windows, `tar` exits non-zero when it cannot create the
|
|
10
|
+
* `core/.agents/skills -> ../.claude/skills` symlink entry (no Developer
|
|
11
|
+
* Mode / admin), even though every REAL file extracted fine. The extractor
|
|
12
|
+
* must NOT treat that as a fatal fetch-fail — `hq reindex` regenerates the
|
|
13
|
+
* symlink on first run. These tests inject a `runTar` that reproduces that
|
|
14
|
+
* behavior without a real `tar` binary.
|
|
15
|
+
*/
|
|
16
|
+
let targetDir;
|
|
17
|
+
beforeEach(async () => {
|
|
18
|
+
targetDir = await fs.mkdtemp(path.join(os.tmpdir(), "create-hq-test-target-"));
|
|
19
|
+
});
|
|
20
|
+
afterEach(async () => {
|
|
21
|
+
await fs.remove(targetDir);
|
|
22
|
+
});
|
|
23
|
+
/**
|
|
24
|
+
* Build a `runTar` that populates `dest` with a realistic hq-core tarball root
|
|
25
|
+
* (real files + `core/core.yaml`), but — if `failAfter` is set — throws a
|
|
26
|
+
* tar-style symlink error AFTER writing the real files, exactly like Windows.
|
|
27
|
+
*/
|
|
28
|
+
function makeRunTar(opts) {
|
|
29
|
+
const rootName = opts.rootName ?? "indigoai-us-hq-core-deadbeef";
|
|
30
|
+
return async (_tarPath, dest) => {
|
|
31
|
+
const root = path.join(dest, rootName);
|
|
32
|
+
// Real files always extract.
|
|
33
|
+
await fs.ensureDir(path.join(root, "core"));
|
|
34
|
+
await fs.writeFile(path.join(root, "README.md"), "# HQ\n");
|
|
35
|
+
await fs.writeFile(path.join(root, "core", "scaffold.txt"), "real scaffold file\n");
|
|
36
|
+
if (opts.coreYamlUnder === "core") {
|
|
37
|
+
await fs.writeFile(path.join(root, "core", "core.yaml"), "version: 1\nhqVersion: 14.0.0\n");
|
|
38
|
+
}
|
|
39
|
+
else if (opts.coreYamlUnder === "root") {
|
|
40
|
+
await fs.writeFile(path.join(root, "core.yaml"), "version: 1\nhqVersion: 13.0.0\n");
|
|
41
|
+
}
|
|
42
|
+
// The .agents/skills symlink is the entry tar fails on under Windows — we
|
|
43
|
+
// simply DON'T create it, then throw to mimic the non-zero exit.
|
|
44
|
+
if (opts.failWith) {
|
|
45
|
+
throw new Error(opts.failWith);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
const WINDOWS_TAR_SYMLINK_ERROR = "tar: core/.agents/skills: Cannot create symlink to '../.claude/skills': A required privilege is not held by the client";
|
|
50
|
+
describe("extractTemplateDirFromTar — Windows symlink tolerance (CREATE-HQ-2)", () => {
|
|
51
|
+
it("succeeds when tar exits non-zero on the symlink entry but real files extracted (v14 core/ layout)", async () => {
|
|
52
|
+
const runTar = makeRunTar({
|
|
53
|
+
coreYamlUnder: "core",
|
|
54
|
+
failWith: WINDOWS_TAR_SYMLINK_ERROR,
|
|
55
|
+
});
|
|
56
|
+
await expect(extractTemplateDirFromTar("/tmp/ignored.tgz", targetDir, undefined, {
|
|
57
|
+
runTar,
|
|
58
|
+
})).resolves.toBeUndefined();
|
|
59
|
+
// The real scaffold landed in the target despite the tar symlink failure.
|
|
60
|
+
expect(await fs.pathExists(path.join(targetDir, "core", "core.yaml"))).toBe(true);
|
|
61
|
+
expect(await fs.pathExists(path.join(targetDir, "core", "scaffold.txt"))).toBe(true);
|
|
62
|
+
expect(await fs.pathExists(path.join(targetDir, "README.md"))).toBe(true);
|
|
63
|
+
// The symlink entry was skipped — reindex regenerates it; it must NOT be a
|
|
64
|
+
// fatal install failure.
|
|
65
|
+
expect(await fs.pathExists(path.join(targetDir, "core", ".agents"))).toBe(false);
|
|
66
|
+
});
|
|
67
|
+
it("tolerates the tar symlink failure for the pre-v14 root-level core.yaml layout too", async () => {
|
|
68
|
+
const runTar = makeRunTar({
|
|
69
|
+
coreYamlUnder: "root",
|
|
70
|
+
failWith: WINDOWS_TAR_SYMLINK_ERROR,
|
|
71
|
+
});
|
|
72
|
+
await expect(extractTemplateDirFromTar("/tmp/ignored.tgz", targetDir, undefined, {
|
|
73
|
+
runTar,
|
|
74
|
+
})).resolves.toBeUndefined();
|
|
75
|
+
expect(await fs.pathExists(path.join(targetDir, "core.yaml"))).toBe(true);
|
|
76
|
+
});
|
|
77
|
+
it("still throws (with the tar error) when extraction truly produced no core.yaml", async () => {
|
|
78
|
+
const runTar = makeRunTar({
|
|
79
|
+
coreYamlUnder: "none",
|
|
80
|
+
failWith: WINDOWS_TAR_SYMLINK_ERROR,
|
|
81
|
+
});
|
|
82
|
+
await expect(extractTemplateDirFromTar("/tmp/ignored.tgz", targetDir, undefined, {
|
|
83
|
+
runTar,
|
|
84
|
+
})).rejects.toThrow(/core\.yaml not found after extraction/);
|
|
85
|
+
});
|
|
86
|
+
it("surfaces the tar error when nothing extracted at all", async () => {
|
|
87
|
+
const runTar = async () => {
|
|
88
|
+
throw new Error("tar: unrecognized archive format");
|
|
89
|
+
};
|
|
90
|
+
await expect(extractTemplateDirFromTar("/tmp/ignored.tgz", targetDir, undefined, {
|
|
91
|
+
runTar,
|
|
92
|
+
})).rejects.toThrow(/Tarball extraction failed: tar: unrecognized archive format/);
|
|
93
|
+
});
|
|
94
|
+
it("happy path: tar succeeds cleanly and the scaffold is copied", async () => {
|
|
95
|
+
const runTar = makeRunTar({ coreYamlUnder: "core", failWith: null });
|
|
96
|
+
await extractTemplateDirFromTar("/tmp/ignored.tgz", targetDir, undefined, {
|
|
97
|
+
runTar,
|
|
98
|
+
});
|
|
99
|
+
expect(await fs.pathExists(path.join(targetDir, "core", "core.yaml"))).toBe(true);
|
|
100
|
+
expect(await fs.pathExists(path.join(targetDir, "README.md"))).toBe(true);
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
//# sourceMappingURL=fetch-template.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch-template.test.js","sourceRoot":"","sources":["../../src/__tests__/fetch-template.test.ts"],"names":[],"mappings":"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"}
|
package/dist/fetch-template.d.ts
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Injectable seam for the tar extraction step so the Windows symlink-failure
|
|
3
|
+
* path is unit-testable without a real `tar` binary.
|
|
4
|
+
*/
|
|
5
|
+
export interface ExtractDeps {
|
|
6
|
+
/**
|
|
7
|
+
* Extract `tarPath` into `dest`. May reject with a non-zero exit even when
|
|
8
|
+
* every real file extracted (e.g. `tar` on Windows cannot create the
|
|
9
|
+
* `core/.agents/skills` symlink entry without Developer Mode) — callers MUST
|
|
10
|
+
* validate extracted content rather than trust the exit code.
|
|
11
|
+
*/
|
|
12
|
+
runTar?: (tarPath: string, dest: string) => Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
export declare function extractTemplateDirFromTar(tarPath: string, targetDir: string, onProgress?: (phase: string) => void, deps?: ExtractDeps): Promise<void>;
|
|
1
15
|
/**
|
|
2
16
|
* Fetch the hq-core scaffold from GitHub and extract it into targetDir.
|
|
3
17
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-template.d.ts","sourceRoot":"","sources":["../src/fetch-template.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"fetch-template.d.ts","sourceRoot":"","sources":["../src/fetch-template.ts"],"names":[],"mappings":"AAcA;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B;;;;;OAKG;IACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3D;AA4ID,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EACpC,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,IAAI,CAAC,CA2Df;AAwBD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,EACjB,GAAG,CAAC,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GACnC,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAyC9B"}
|
package/dist/fetch-template.js
CHANGED
|
@@ -1,11 +1,50 @@
|
|
|
1
1
|
import fs from "fs-extra";
|
|
2
2
|
import * as path from "path";
|
|
3
3
|
import * as os from "os";
|
|
4
|
-
import { exec } from "child_process";
|
|
4
|
+
import { exec, spawn } from "child_process";
|
|
5
5
|
import { promisify } from "util";
|
|
6
6
|
import { buildClientHeaders } from "@indigoai-us/hq-cloud";
|
|
7
7
|
import { CREATE_HQ_CLIENT_INFO } from "./client-info.js";
|
|
8
8
|
const execAsync = promisify(exec);
|
|
9
|
+
function errMessage(err) {
|
|
10
|
+
return err instanceof Error ? err.message : String(err);
|
|
11
|
+
}
|
|
12
|
+
async function defaultRunTar(tarPath, dest) {
|
|
13
|
+
await execAsync(`tar -xzf "${tarPath}" -C "${dest}"`);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Run `gh api <path>` and stream its (binary) stdout to `outPath`.
|
|
17
|
+
*
|
|
18
|
+
* Uses `spawn` WITHOUT a shell, so there is no `/bin/sh` dependency (which
|
|
19
|
+
* ENOENTs on Windows) and no shell redirect to interpret. `gh` ships as
|
|
20
|
+
* `gh.exe` on Windows, which `spawn` resolves directly. A missing `gh` binary
|
|
21
|
+
* surfaces as the spawn `error` event (rejected) on every platform.
|
|
22
|
+
*/
|
|
23
|
+
function ghApiToFile(apiPath, outPath) {
|
|
24
|
+
return new Promise((resolve, reject) => {
|
|
25
|
+
const out = fs.createWriteStream(outPath);
|
|
26
|
+
out.on("error", reject);
|
|
27
|
+
const child = spawn("gh", ["api", apiPath], {
|
|
28
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
29
|
+
});
|
|
30
|
+
let stderr = "";
|
|
31
|
+
child.stderr.on("data", (chunk) => {
|
|
32
|
+
stderr += chunk.toString();
|
|
33
|
+
});
|
|
34
|
+
child.on("error", reject);
|
|
35
|
+
child.stdout.pipe(out);
|
|
36
|
+
child.on("close", (code) => {
|
|
37
|
+
out.end(() => {
|
|
38
|
+
if (code === 0) {
|
|
39
|
+
resolve();
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
reject(new Error(`gh api exited with code ${code}${stderr ? `: ${stderr.trim()}` : ""}`));
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
}
|
|
9
48
|
// Pre-computed at module load — GitHub requires a User-Agent header (otherwise
|
|
10
49
|
// requests are rejected from anonymous clients), and stamping the create-hq
|
|
11
50
|
// version makes our own rate-limit usage attributable in GitHub's API logs.
|
|
@@ -90,28 +129,50 @@ async function downloadAndExtractViaApi(tarballUrl, targetDir, onProgress) {
|
|
|
90
129
|
await fs.remove(tmpDir);
|
|
91
130
|
}
|
|
92
131
|
}
|
|
93
|
-
async function extractTemplateDirFromTar(tarPath, targetDir, onProgress) {
|
|
132
|
+
export async function extractTemplateDirFromTar(tarPath, targetDir, onProgress, deps = {}) {
|
|
94
133
|
// The tarball contains a top-level directory like `indigoai-us-hq-core-<sha>/`.
|
|
95
134
|
// The hq-core repo IS the scaffold — every file in it becomes part of the
|
|
96
135
|
// new HQ instance. Copy the entire root directory's contents (not a subdir).
|
|
136
|
+
const runTar = deps.runTar ?? defaultRunTar;
|
|
97
137
|
const tmpExtract = await fs.mkdtemp(path.join(os.tmpdir(), "create-hq-extract-"));
|
|
98
138
|
try {
|
|
99
|
-
// Extract the full tarball to a temp location
|
|
100
|
-
|
|
139
|
+
// Extract the full tarball to a temp location. `tar` can exit NON-ZERO on
|
|
140
|
+
// Windows when it cannot create a symlink entry it does not have rights for
|
|
141
|
+
// — hq-core ships `core/.agents/skills -> ../.claude/skills`, and creating a
|
|
142
|
+
// symlink on Windows needs Developer Mode or admin. Crucially, every *real*
|
|
143
|
+
// file still extracts; only the symlink entry is skipped, and `hq reindex`
|
|
144
|
+
// regenerates that symlink on first run. So a `tar` failure is NOT
|
|
145
|
+
// authoritative here — we capture it and let the content validation below be
|
|
146
|
+
// the source of truth (CREATE-HQ-2).
|
|
147
|
+
let tarError = null;
|
|
148
|
+
try {
|
|
149
|
+
await runTar(tarPath, tmpExtract);
|
|
150
|
+
}
|
|
151
|
+
catch (err) {
|
|
152
|
+
tarError = err;
|
|
153
|
+
}
|
|
101
154
|
// Find the top-level directory created by GitHub's tarball
|
|
102
155
|
const entries = await fs.readdir(tmpExtract);
|
|
103
156
|
if (entries.length === 0) {
|
|
104
|
-
|
|
157
|
+
// Nothing extracted at all — now the tar failure (if any) IS the cause.
|
|
158
|
+
throw new Error(tarError
|
|
159
|
+
? `Tarball extraction failed: ${errMessage(tarError)}`
|
|
160
|
+
: "Tarball was empty");
|
|
105
161
|
}
|
|
106
162
|
const rootDir = path.join(tmpExtract, entries[0]);
|
|
107
163
|
// Sanity check — hq-core@v14+ carries core.yaml under core/. (Pre-v14 had
|
|
108
164
|
// it at the tarball root.) Accept either to keep older tagged releases
|
|
109
|
-
// installable via `npx create-hq <name> --tag <pre-v14-tag>`.
|
|
165
|
+
// installable via `npx create-hq <name> --tag <pre-v14-tag>`. This doubles
|
|
166
|
+
// as the "did the real files extract?" gate: if core.yaml is present, the
|
|
167
|
+
// scaffold extracted fine and any `tar` exit error was a non-fatal symlink
|
|
168
|
+
// entry we can safely ignore.
|
|
110
169
|
const coreYaml = (await fs.pathExists(path.join(rootDir, "core", "core.yaml")))
|
|
111
170
|
? path.join(rootDir, "core", "core.yaml")
|
|
112
171
|
: path.join(rootDir, "core.yaml");
|
|
113
172
|
if (!await fs.pathExists(coreYaml)) {
|
|
114
|
-
throw new Error(
|
|
173
|
+
throw new Error(tarError
|
|
174
|
+
? `core.yaml not found after extraction (tar error: ${errMessage(tarError)}) — the scaffold did not extract correctly`
|
|
175
|
+
: "core.yaml not found at core/core.yaml or tarball root — this does not look like an hq-core scaffold");
|
|
115
176
|
}
|
|
116
177
|
// Copy the entire hq-core tree to targetDir
|
|
117
178
|
onProgress?.("Copying scaffold files...");
|
|
@@ -128,9 +189,10 @@ async function extractTemplateDirViaGhCli(tag, targetDir, onProgress) {
|
|
|
128
189
|
const tarPath = path.join(tmpDir, "hq.tar.gz");
|
|
129
190
|
try {
|
|
130
191
|
onProgress?.("Downloading via gh CLI...");
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
192
|
+
// Stream `gh api .../tarball/<ref>` straight to the tar file via spawn (no
|
|
193
|
+
// shell). The previous `execAsync(... > file, { shell: "/bin/sh" })` ENOENTs
|
|
194
|
+
// on Windows, where `/bin/sh` does not exist (CREATE-HQ-2).
|
|
195
|
+
await ghApiToFile(`repos/${REPO}/tarball/${ref}`, tarPath);
|
|
134
196
|
onProgress?.("Extracting template...");
|
|
135
197
|
await extractTemplateDirFromTar(tarPath, targetDir, onProgress);
|
|
136
198
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fetch-template.js","sourceRoot":"","sources":["../src/fetch-template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"fetch-template.js","sourceRoot":"","sources":["../src/fetch-template.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-hq",
|
|
3
|
-
"version": "10.12.
|
|
3
|
+
"version": "10.12.4",
|
|
4
4
|
"description": "Create a new HQ by Indigo — Personal OS for AI Workers",
|
|
5
5
|
"bin": {
|
|
6
6
|
"create-hq": "./dist/index.js"
|
|
@@ -13,8 +13,11 @@
|
|
|
13
13
|
"build": "node scripts/generate-dsn.mjs && tsc",
|
|
14
14
|
"typecheck": "tsc --noEmit",
|
|
15
15
|
"clean": "rm -rf dist",
|
|
16
|
+
"lint": "eslint .",
|
|
16
17
|
"prepack": "npm run build",
|
|
17
18
|
"test": "vitest run",
|
|
19
|
+
"coverage": "vitest run --coverage --coverage.reporter=text-summary --coverage.reporter=json-summary",
|
|
20
|
+
"test:e2e": "npm run build && vitest run e2e",
|
|
18
21
|
"test:containers": "vitest run test/container.test.ts"
|
|
19
22
|
},
|
|
20
23
|
"dependencies": {
|
|
@@ -26,10 +29,13 @@
|
|
|
26
29
|
"ora": "^8.1.0"
|
|
27
30
|
},
|
|
28
31
|
"devDependencies": {
|
|
32
|
+
"@eslint/js": "^10.0.1",
|
|
29
33
|
"@types/fs-extra": "^11.0.4",
|
|
30
34
|
"@types/node": "^22.0.0",
|
|
31
35
|
"@vitest/coverage-v8": "^4.1.2",
|
|
36
|
+
"eslint": "^10.5.0",
|
|
32
37
|
"typescript": "^5.7.0",
|
|
38
|
+
"typescript-eslint": "^8.61.1",
|
|
33
39
|
"vitest": "^4.1.2"
|
|
34
40
|
},
|
|
35
41
|
"engines": {
|