@arvoretech/hub 0.1.2 → 0.2.0
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/index.js +166 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import { Command as
|
|
4
|
+
import { Command as Command17 } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/commands/init.ts
|
|
7
7
|
import { Command } from "commander";
|
|
@@ -679,6 +679,7 @@ function buildKiroOrchestratorRule(config) {
|
|
|
679
679
|
const taskFolder = config.workflow?.task_folder || "./tasks/<TASK_ID>/";
|
|
680
680
|
const steps = config.workflow?.pipeline || [];
|
|
681
681
|
const prompt = config.workflow?.prompt;
|
|
682
|
+
const enforce = config.workflow?.enforce_workflow ?? false;
|
|
682
683
|
const sections = [];
|
|
683
684
|
sections.push(`# Orchestrator
|
|
684
685
|
|
|
@@ -687,6 +688,22 @@ function buildKiroOrchestratorRule(config) {
|
|
|
687
688
|
You are the development orchestrator. Your job is to ensure that any feature or task requested by the user is completed end-to-end by following a structured pipeline. You work as a single agent but follow specialized instructions from steering files for each phase of development.
|
|
688
689
|
|
|
689
690
|
> **Note:** This workspace uses steering files in \`.kiro/steering/\` to provide role-specific instructions for each pipeline step. When a step says "follow the instructions from steering file X", read that file and apply its guidelines to the current task.`);
|
|
691
|
+
if (enforce) {
|
|
692
|
+
sections.push(`
|
|
693
|
+
## STRICT WORKFLOW ENFORCEMENT
|
|
694
|
+
|
|
695
|
+
**YOU MUST FOLLOW THE PIPELINE DEFINED BELOW. NO EXCEPTIONS.**
|
|
696
|
+
|
|
697
|
+
- NEVER skip a pipeline step, even if the task seems simple or obvious.
|
|
698
|
+
- ALWAYS execute steps in the exact order defined. Do not reorder, merge, or parallelize steps unless the pipeline explicitly allows it.
|
|
699
|
+
- ALWAYS follow the designated steering file for each step. Do not improvise if a steering file is assigned.
|
|
700
|
+
- ALWAYS wait for a step to complete and validate its output before moving to the next step.
|
|
701
|
+
- If a step produces a document, READ the document and confirm it is complete before proceeding.
|
|
702
|
+
- If a step has unanswered questions or validation issues, RESOLVE them before advancing.
|
|
703
|
+
- NEVER jump directly to coding without completing refinement first.
|
|
704
|
+
- NEVER skip review or QA steps, even for small changes.
|
|
705
|
+
- If the user asks you to skip a step, explain why the pipeline exists and ask for explicit confirmation before proceeding.`);
|
|
706
|
+
}
|
|
690
707
|
if (prompt?.prepend) {
|
|
691
708
|
sections.push(`
|
|
692
709
|
${prompt.prepend.trim()}`);
|
|
@@ -825,6 +842,7 @@ function buildOrchestratorRule(config) {
|
|
|
825
842
|
const taskFolder = config.workflow?.task_folder || "./tasks/<TASK_ID>/";
|
|
826
843
|
const steps = config.workflow?.pipeline || [];
|
|
827
844
|
const prompt = config.workflow?.prompt;
|
|
845
|
+
const enforce = config.workflow?.enforce_workflow ?? false;
|
|
828
846
|
const sections = [];
|
|
829
847
|
sections.push(`---
|
|
830
848
|
description: "Orchestrator agent \u2014 coordinates sub-agents through the development pipeline"
|
|
@@ -836,6 +854,22 @@ alwaysApply: true
|
|
|
836
854
|
## Your Main Responsibility
|
|
837
855
|
|
|
838
856
|
You are an agent orchestrator. Your job is to ensure that any feature or task requested by the user is completed end-to-end using specialized sub-agents.`);
|
|
857
|
+
if (enforce) {
|
|
858
|
+
sections.push(`
|
|
859
|
+
## STRICT WORKFLOW ENFORCEMENT
|
|
860
|
+
|
|
861
|
+
**YOU MUST FOLLOW THE PIPELINE DEFINED BELOW. NO EXCEPTIONS.**
|
|
862
|
+
|
|
863
|
+
- NEVER skip a pipeline step, even if the task seems simple or obvious.
|
|
864
|
+
- ALWAYS execute steps in the exact order defined. Do not reorder, merge, or parallelize steps unless the pipeline explicitly allows it.
|
|
865
|
+
- ALWAYS call the designated sub-agent for each step. Do not attempt to perform a step yourself if an agent is assigned to it.
|
|
866
|
+
- ALWAYS wait for a step to complete and validate its output before moving to the next step.
|
|
867
|
+
- If a step produces a document, READ the document and confirm it is complete before proceeding.
|
|
868
|
+
- If a step has unanswered questions or validation issues, RESOLVE them before advancing.
|
|
869
|
+
- NEVER jump directly to coding without completing refinement first.
|
|
870
|
+
- NEVER skip review or QA steps, even for small changes.
|
|
871
|
+
- If the user asks you to skip a step, explain why the pipeline exists and ask for explicit confirmation before proceeding.`);
|
|
872
|
+
}
|
|
839
873
|
if (prompt?.prepend) {
|
|
840
874
|
sections.push(`
|
|
841
875
|
${prompt.prepend.trim()}`);
|
|
@@ -2291,6 +2325,55 @@ Agent '${name}' not found in ${opts.global ? "global" : "project"}
|
|
|
2291
2325
|
Removed agent: ${name}
|
|
2292
2326
|
`));
|
|
2293
2327
|
})
|
|
2328
|
+
).addCommand(
|
|
2329
|
+
new Command9("sync").description("Install all agents referenced in hub.yaml from the registry").option("-g, --global", "Install to global ~/.cursor/agents/").option("-r, --repo <repo>", "Registry repository (owner/repo)").option("-f, --force", "Re-install even if the agent already exists locally").action(async (opts) => {
|
|
2330
|
+
const hubDir = process.cwd();
|
|
2331
|
+
let config;
|
|
2332
|
+
try {
|
|
2333
|
+
config = await loadHubConfig(hubDir);
|
|
2334
|
+
} catch {
|
|
2335
|
+
console.log(chalk9.red("\n Could not load hub.yaml in the current directory.\n"));
|
|
2336
|
+
return;
|
|
2337
|
+
}
|
|
2338
|
+
const steps = config.workflow?.pipeline || [];
|
|
2339
|
+
const agentNames = /* @__PURE__ */ new Set();
|
|
2340
|
+
for (const step of steps) {
|
|
2341
|
+
if (step.agent) agentNames.add(step.agent);
|
|
2342
|
+
if (Array.isArray(step.agents)) {
|
|
2343
|
+
for (const a of step.agents) {
|
|
2344
|
+
agentNames.add(typeof a === "string" ? a : a.agent);
|
|
2345
|
+
}
|
|
2346
|
+
}
|
|
2347
|
+
}
|
|
2348
|
+
if (agentNames.size === 0) {
|
|
2349
|
+
console.log(chalk9.yellow("\n No agents found in hub.yaml workflow pipeline.\n"));
|
|
2350
|
+
return;
|
|
2351
|
+
}
|
|
2352
|
+
console.log(chalk9.blue(`
|
|
2353
|
+
\u2501\u2501\u2501 Syncing ${agentNames.size} agent(s) from hub.yaml \u2501\u2501\u2501
|
|
2354
|
+
`));
|
|
2355
|
+
const targetBase = opts.global ? join10(process.env.HOME || "~", ".cursor", "agents") : join10(hubDir, "agents");
|
|
2356
|
+
let installed = 0;
|
|
2357
|
+
let skipped = 0;
|
|
2358
|
+
for (const name of agentNames) {
|
|
2359
|
+
const fileName = name.endsWith(".md") ? name : `${name}.md`;
|
|
2360
|
+
const targetPath = join10(targetBase, fileName);
|
|
2361
|
+
if (!opts.force && existsSync7(targetPath)) {
|
|
2362
|
+
console.log(chalk9.dim(` \u2713 ${name} (already installed)`));
|
|
2363
|
+
skipped++;
|
|
2364
|
+
continue;
|
|
2365
|
+
}
|
|
2366
|
+
await addFromRegistry2(name, hubDir, { global: opts.global, repo: opts.repo });
|
|
2367
|
+
installed++;
|
|
2368
|
+
}
|
|
2369
|
+
console.log();
|
|
2370
|
+
if (installed > 0) console.log(chalk9.green(` ${installed} agent(s) installed`));
|
|
2371
|
+
if (skipped > 0) console.log(chalk9.dim(` ${skipped} agent(s) already up to date`));
|
|
2372
|
+
if (installed === 0 && skipped > 0) {
|
|
2373
|
+
console.log(chalk9.green(" All agents are already installed. Use --force to re-install."));
|
|
2374
|
+
}
|
|
2375
|
+
console.log();
|
|
2376
|
+
})
|
|
2294
2377
|
);
|
|
2295
2378
|
|
|
2296
2379
|
// src/commands/hooks.ts
|
|
@@ -3246,11 +3329,90 @@ function extractVersion(s) {
|
|
|
3246
3329
|
return match?.[1] || s;
|
|
3247
3330
|
}
|
|
3248
3331
|
|
|
3332
|
+
// src/commands/update.ts
|
|
3333
|
+
import { Command as Command16 } from "commander";
|
|
3334
|
+
import { execSync as execSync12 } from "child_process";
|
|
3335
|
+
import { readFileSync } from "fs";
|
|
3336
|
+
import { join as join17, dirname } from "path";
|
|
3337
|
+
import { fileURLToPath } from "url";
|
|
3338
|
+
import chalk16 from "chalk";
|
|
3339
|
+
var PACKAGE_NAME = "@arvoretech/hub";
|
|
3340
|
+
function getCurrentVersion() {
|
|
3341
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
3342
|
+
const pkgPath = join17(__dirname, "..", "package.json");
|
|
3343
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
3344
|
+
return pkg.version;
|
|
3345
|
+
}
|
|
3346
|
+
async function getLatestVersion() {
|
|
3347
|
+
const res = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`);
|
|
3348
|
+
if (!res.ok) throw new Error(`npm registry returned ${res.status}`);
|
|
3349
|
+
const data = await res.json();
|
|
3350
|
+
return data.version;
|
|
3351
|
+
}
|
|
3352
|
+
function detectPackageManager() {
|
|
3353
|
+
try {
|
|
3354
|
+
execSync12("pnpm --version", { stdio: "pipe" });
|
|
3355
|
+
return "pnpm";
|
|
3356
|
+
} catch {
|
|
3357
|
+
try {
|
|
3358
|
+
execSync12("yarn --version", { stdio: "pipe" });
|
|
3359
|
+
return "yarn";
|
|
3360
|
+
} catch {
|
|
3361
|
+
return "npm";
|
|
3362
|
+
}
|
|
3363
|
+
}
|
|
3364
|
+
}
|
|
3365
|
+
var updateCommand = new Command16("update").description("Update hub CLI to the latest version").option("--check", "Only check for updates without installing").action(async (opts) => {
|
|
3366
|
+
const currentVersion = getCurrentVersion();
|
|
3367
|
+
console.log(chalk16.blue(`
|
|
3368
|
+
Current version: ${currentVersion}`));
|
|
3369
|
+
let latestVersion;
|
|
3370
|
+
try {
|
|
3371
|
+
latestVersion = await getLatestVersion();
|
|
3372
|
+
} catch (err) {
|
|
3373
|
+
console.log(chalk16.red(` Failed to check for updates: ${err.message}
|
|
3374
|
+
`));
|
|
3375
|
+
return;
|
|
3376
|
+
}
|
|
3377
|
+
console.log(chalk16.blue(` Latest version: ${latestVersion}`));
|
|
3378
|
+
if (currentVersion === latestVersion) {
|
|
3379
|
+
console.log(chalk16.green("\n You're already on the latest version.\n"));
|
|
3380
|
+
return;
|
|
3381
|
+
}
|
|
3382
|
+
console.log(chalk16.yellow(`
|
|
3383
|
+
Update available: ${currentVersion} \u2192 ${latestVersion}`));
|
|
3384
|
+
if (opts.check) {
|
|
3385
|
+
const pm2 = detectPackageManager();
|
|
3386
|
+
console.log(chalk16.dim(`
|
|
3387
|
+
Run 'hub update' or '${pm2} install -g ${PACKAGE_NAME}@latest' to update.
|
|
3388
|
+
`));
|
|
3389
|
+
return;
|
|
3390
|
+
}
|
|
3391
|
+
const pm = detectPackageManager();
|
|
3392
|
+
const installCmd = pm === "pnpm" ? `pnpm install -g ${PACKAGE_NAME}@latest` : pm === "yarn" ? `yarn global add ${PACKAGE_NAME}@latest` : `npm install -g ${PACKAGE_NAME}@latest`;
|
|
3393
|
+
console.log(chalk16.cyan(`
|
|
3394
|
+
Updating with ${pm}...
|
|
3395
|
+
`));
|
|
3396
|
+
console.log(chalk16.dim(` $ ${installCmd}
|
|
3397
|
+
`));
|
|
3398
|
+
try {
|
|
3399
|
+
execSync12(installCmd, { stdio: "inherit" });
|
|
3400
|
+
console.log(chalk16.green(`
|
|
3401
|
+
Updated to ${latestVersion} successfully.
|
|
3402
|
+
`));
|
|
3403
|
+
} catch {
|
|
3404
|
+
console.log(chalk16.red(`
|
|
3405
|
+
Update failed. Try running manually:`));
|
|
3406
|
+
console.log(chalk16.dim(` $ ${installCmd}
|
|
3407
|
+
`));
|
|
3408
|
+
}
|
|
3409
|
+
});
|
|
3410
|
+
|
|
3249
3411
|
// src/index.ts
|
|
3250
|
-
var program = new
|
|
3412
|
+
var program = new Command17();
|
|
3251
3413
|
program.name("hub").description(
|
|
3252
3414
|
"Give your AI coding assistant the full picture. Multi-repo context, agent orchestration, and end-to-end workflows."
|
|
3253
|
-
).version("0.
|
|
3415
|
+
).version("0.2.0").enablePositionalOptions();
|
|
3254
3416
|
program.addCommand(initCommand);
|
|
3255
3417
|
program.addCommand(addRepoCommand);
|
|
3256
3418
|
program.addCommand(setupCommand);
|
|
@@ -3268,4 +3430,5 @@ program.addCommand(execCommand);
|
|
|
3268
3430
|
program.addCommand(worktreeCommand);
|
|
3269
3431
|
program.addCommand(doctorCommand);
|
|
3270
3432
|
program.addCommand(toolsCommand);
|
|
3433
|
+
program.addCommand(updateCommand);
|
|
3271
3434
|
program.parse();
|