@jive-ai/cli 0.0.36 → 0.0.38
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 +6 -1
- package/dist/index.mjs +31 -72
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -47,12 +47,17 @@ You can extend the Jive task runner image to add custom tools or dependencies:
|
|
|
47
47
|
FROM jiveai/task:latest
|
|
48
48
|
|
|
49
49
|
# Add your custom dependencies
|
|
50
|
-
RUN
|
|
50
|
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
51
|
+
python3 \
|
|
52
|
+
python3-pip \
|
|
53
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
51
54
|
|
|
52
55
|
# Install additional tools
|
|
53
56
|
RUN pip install --break-system-packages black ruff
|
|
54
57
|
```
|
|
55
58
|
|
|
59
|
+
**Note:** The base image is Debian-based (bookworm-slim), so use `apt-get` for package management.
|
|
60
|
+
|
|
56
61
|
## Publishing the Docker Image (Maintainers)
|
|
57
62
|
|
|
58
63
|
### One-Time Setup
|
package/dist/index.mjs
CHANGED
|
@@ -3357,20 +3357,14 @@ async function spawnTaskDocker(ctx, config$2, opts) {
|
|
|
3357
3357
|
envVars.push("-e", `GIT_USERNAME=${ctx.gitAuth.username}`);
|
|
3358
3358
|
envVars.push("-e", `GIT_PASSWORD=${ctx.gitAuth.token}`);
|
|
3359
3359
|
}
|
|
3360
|
-
const useSysbox = process.env.JIVE_USE_SYSBOX !== "false";
|
|
3361
3360
|
const dockerArgs = [
|
|
3362
3361
|
"run",
|
|
3363
3362
|
"--rm",
|
|
3364
|
-
"-i"
|
|
3363
|
+
"-i",
|
|
3364
|
+
"--runtime",
|
|
3365
|
+
"sysbox-runc"
|
|
3365
3366
|
];
|
|
3366
|
-
|
|
3367
|
-
dockerArgs.push("--runtime", "sysbox-runc");
|
|
3368
|
-
console.log(chalk.dim("Using Sysbox runtime for isolated Docker-in-Docker"));
|
|
3369
|
-
} else {
|
|
3370
|
-
dockerArgs.push("-v", "/var/run/docker.sock:/var/run/docker.sock");
|
|
3371
|
-
dockerArgs.push("--user", "root");
|
|
3372
|
-
console.log(chalk.yellow("Warning: Using Docker socket mount (no isolation). Set JIVE_USE_SYSBOX=true on Linux for secure mode."));
|
|
3373
|
-
}
|
|
3367
|
+
console.log(chalk.dim("Using Sysbox runtime for isolated Docker-in-Docker"));
|
|
3374
3368
|
dockerArgs.push("--network", "bridge");
|
|
3375
3369
|
if (isDevMode) {
|
|
3376
3370
|
dockerArgs.push("--add-host", "host.docker.internal:host-gateway");
|
|
@@ -3436,7 +3430,7 @@ async function createGraphQLClient() {
|
|
|
3436
3430
|
|
|
3437
3431
|
//#endregion
|
|
3438
3432
|
//#region package.json
|
|
3439
|
-
var version = "0.0.
|
|
3433
|
+
var version = "0.0.38";
|
|
3440
3434
|
|
|
3441
3435
|
//#endregion
|
|
3442
3436
|
//#region src/runner/index.ts
|
|
@@ -5139,18 +5133,32 @@ async function setupRunnerCommand(options) {
|
|
|
5139
5133
|
let config = null;
|
|
5140
5134
|
const runnerConfigPath = path.join(process.env.HOME || process.env.USERPROFILE || "", ".jive", "runner.json");
|
|
5141
5135
|
async function getRunnerConfig() {
|
|
5142
|
-
if (process.env.JIVE_RUNNER_ID && process.env.JIVE_TEAM_ID) return {
|
|
5143
|
-
id: parseInt(process.env.JIVE_RUNNER_ID),
|
|
5144
|
-
name: process.env.JIVE_RUNNER_NAME || "docker-runner",
|
|
5145
|
-
type: "docker",
|
|
5146
|
-
teamId: process.env.JIVE_TEAM_ID,
|
|
5147
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
5148
|
-
};
|
|
5149
5136
|
if (config) return config;
|
|
5150
|
-
|
|
5151
|
-
|
|
5152
|
-
|
|
5153
|
-
|
|
5137
|
+
let fileConfig = null;
|
|
5138
|
+
try {
|
|
5139
|
+
const configData = await fs.readFile(runnerConfigPath, "utf-8");
|
|
5140
|
+
fileConfig = JSON.parse(configData);
|
|
5141
|
+
} catch {}
|
|
5142
|
+
if (fileConfig) {
|
|
5143
|
+
config = {
|
|
5144
|
+
...fileConfig,
|
|
5145
|
+
...process.env.JIVE_RUNNER_ID && { id: parseInt(process.env.JIVE_RUNNER_ID) },
|
|
5146
|
+
...process.env.JIVE_RUNNER_NAME && { name: process.env.JIVE_RUNNER_NAME },
|
|
5147
|
+
...process.env.JIVE_TEAM_ID && { teamId: process.env.JIVE_TEAM_ID }
|
|
5148
|
+
};
|
|
5149
|
+
return config;
|
|
5150
|
+
}
|
|
5151
|
+
if (process.env.JIVE_RUNNER_ID && process.env.JIVE_TEAM_ID) {
|
|
5152
|
+
config = {
|
|
5153
|
+
id: parseInt(process.env.JIVE_RUNNER_ID),
|
|
5154
|
+
name: process.env.JIVE_RUNNER_NAME || "docker-runner",
|
|
5155
|
+
type: "docker",
|
|
5156
|
+
teamId: process.env.JIVE_TEAM_ID,
|
|
5157
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
5158
|
+
};
|
|
5159
|
+
return config;
|
|
5160
|
+
}
|
|
5161
|
+
throw new Error("Failed to load runner config - no config file found and JIVE_RUNNER_ID/JIVE_TEAM_ID env vars not set");
|
|
5154
5162
|
}
|
|
5155
5163
|
async function saveRunnerConfig(config$2) {
|
|
5156
5164
|
await fs.mkdir(path.dirname(runnerConfigPath), { recursive: true });
|
|
@@ -5565,42 +5573,6 @@ async function initCommand() {
|
|
|
5565
5573
|
}
|
|
5566
5574
|
}
|
|
5567
5575
|
|
|
5568
|
-
//#endregion
|
|
5569
|
-
//#region src/lib/git-utils.ts
|
|
5570
|
-
/**
|
|
5571
|
-
* Normalizes a git URL to a canonical form for comparison.
|
|
5572
|
-
* Handles SSH, HTTPS, with/without .git suffix, trailing slashes.
|
|
5573
|
-
* Returns format: github.com/owner/repo (lowercase)
|
|
5574
|
-
*/
|
|
5575
|
-
function normalizeGitUrl(url) {
|
|
5576
|
-
if (!url) return "";
|
|
5577
|
-
let normalized = url.trim();
|
|
5578
|
-
normalized = normalized.replace(/\.git$/, "");
|
|
5579
|
-
normalized = normalized.replace(/\/+$/, "");
|
|
5580
|
-
const sshMatch = normalized.match(/^git@([^:]+):(.+)$/);
|
|
5581
|
-
if (sshMatch) {
|
|
5582
|
-
const [, host, path$2] = sshMatch;
|
|
5583
|
-
normalized = `${host}/${path$2}`;
|
|
5584
|
-
}
|
|
5585
|
-
const httpsMatch = normalized.match(/^https?:\/\/([^/]+)\/(.+)$/);
|
|
5586
|
-
if (httpsMatch) {
|
|
5587
|
-
const [, host, path$2] = httpsMatch;
|
|
5588
|
-
normalized = `${host.includes("@") ? host.split("@")[1] : host}/${path$2}`;
|
|
5589
|
-
}
|
|
5590
|
-
const gitMatch = normalized.match(/^git:\/\/([^/]+)\/(.+)$/);
|
|
5591
|
-
if (gitMatch) {
|
|
5592
|
-
const [, host, path$2] = gitMatch;
|
|
5593
|
-
normalized = `${host}/${path$2}`;
|
|
5594
|
-
}
|
|
5595
|
-
return normalized.toLowerCase();
|
|
5596
|
-
}
|
|
5597
|
-
/**
|
|
5598
|
-
* Compares two git URLs to see if they point to the same repository.
|
|
5599
|
-
*/
|
|
5600
|
-
function gitUrlsMatch(url1, url2) {
|
|
5601
|
-
return normalizeGitUrl(url1) === normalizeGitUrl(url2);
|
|
5602
|
-
}
|
|
5603
|
-
|
|
5604
5576
|
//#endregion
|
|
5605
5577
|
//#region src/commands/task.ts
|
|
5606
5578
|
const execAsync = promisify(exec);
|
|
@@ -5630,27 +5602,14 @@ async function resumeCommand(taskId) {
|
|
|
5630
5602
|
}
|
|
5631
5603
|
const { task, project } = taskData;
|
|
5632
5604
|
spinner.text = "Verifying repository...";
|
|
5633
|
-
let localRemoteUrl;
|
|
5634
5605
|
try {
|
|
5635
5606
|
const { stdout } = await execAsync("git remote get-url origin");
|
|
5636
|
-
|
|
5607
|
+
stdout.trim();
|
|
5637
5608
|
} catch (error$1) {
|
|
5638
5609
|
spinner.fail(chalk.red("Current directory is not a git repository"));
|
|
5639
5610
|
console.error(chalk.dim("Run this command from within the project repository"));
|
|
5640
5611
|
process.exit(1);
|
|
5641
5612
|
}
|
|
5642
|
-
const projectRepoUrl = project.gitRepoUrl;
|
|
5643
|
-
if (!projectRepoUrl) {
|
|
5644
|
-
spinner.fail(chalk.red("Task project has no repository URL configured"));
|
|
5645
|
-
process.exit(1);
|
|
5646
|
-
}
|
|
5647
|
-
if (!gitUrlsMatch(localRemoteUrl, projectRepoUrl)) {
|
|
5648
|
-
spinner.fail(chalk.red("Repository mismatch"));
|
|
5649
|
-
console.error(chalk.dim(`Local repository: ${localRemoteUrl}`));
|
|
5650
|
-
console.error(chalk.dim(`Project repository: ${projectRepoUrl}`));
|
|
5651
|
-
console.error(chalk.dim("\nRun this command from within the correct project directory"));
|
|
5652
|
-
process.exit(1);
|
|
5653
|
-
}
|
|
5654
5613
|
spinner.text = "Fetching session data...";
|
|
5655
5614
|
const sessions = await apiClient$1.getTaskSessions(id);
|
|
5656
5615
|
if (!sessions || sessions.length === 0) {
|