@arvoretech/hub 0.1.2 → 0.3.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 +178 -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()}`);
|
|
@@ -786,6 +803,10 @@ Follow each step sequentially, applying the role-specific instructions from the
|
|
|
786
803
|
}
|
|
787
804
|
const stepTitle = step.step.charAt(0).toUpperCase() + step.step.slice(1);
|
|
788
805
|
parts.push(`### ${stepTitle}`);
|
|
806
|
+
if (step.mode === "plan") {
|
|
807
|
+
parts.push(`**This step is a planning phase.** Do NOT make any code changes. Focus on reading, analyzing, and collaborating with the user to define requirements before proceeding.`);
|
|
808
|
+
parts.push(``);
|
|
809
|
+
}
|
|
789
810
|
if (step.agent) {
|
|
790
811
|
parts.push(`Follow the instructions from the \`agent-${step.agent}.md\` steering file.${step.output ? ` Write output to \`${step.output}\`.` : ""}`);
|
|
791
812
|
if (step.step === "refinement") {
|
|
@@ -825,6 +846,7 @@ function buildOrchestratorRule(config) {
|
|
|
825
846
|
const taskFolder = config.workflow?.task_folder || "./tasks/<TASK_ID>/";
|
|
826
847
|
const steps = config.workflow?.pipeline || [];
|
|
827
848
|
const prompt = config.workflow?.prompt;
|
|
849
|
+
const enforce = config.workflow?.enforce_workflow ?? false;
|
|
828
850
|
const sections = [];
|
|
829
851
|
sections.push(`---
|
|
830
852
|
description: "Orchestrator agent \u2014 coordinates sub-agents through the development pipeline"
|
|
@@ -836,6 +858,22 @@ alwaysApply: true
|
|
|
836
858
|
## Your Main Responsibility
|
|
837
859
|
|
|
838
860
|
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.`);
|
|
861
|
+
if (enforce) {
|
|
862
|
+
sections.push(`
|
|
863
|
+
## STRICT WORKFLOW ENFORCEMENT
|
|
864
|
+
|
|
865
|
+
**YOU MUST FOLLOW THE PIPELINE DEFINED BELOW. NO EXCEPTIONS.**
|
|
866
|
+
|
|
867
|
+
- NEVER skip a pipeline step, even if the task seems simple or obvious.
|
|
868
|
+
- ALWAYS execute steps in the exact order defined. Do not reorder, merge, or parallelize steps unless the pipeline explicitly allows it.
|
|
869
|
+
- ALWAYS call the designated sub-agent for each step. Do not attempt to perform a step yourself if an agent is assigned to it.
|
|
870
|
+
- ALWAYS wait for a step to complete and validate its output before moving to the next step.
|
|
871
|
+
- If a step produces a document, READ the document and confirm it is complete before proceeding.
|
|
872
|
+
- If a step has unanswered questions or validation issues, RESOLVE them before advancing.
|
|
873
|
+
- NEVER jump directly to coding without completing refinement first.
|
|
874
|
+
- NEVER skip review or QA steps, even for small changes.
|
|
875
|
+
- If the user asks you to skip a step, explain why the pipeline exists and ask for explicit confirmation before proceeding.`);
|
|
876
|
+
}
|
|
839
877
|
if (prompt?.prepend) {
|
|
840
878
|
sections.push(`
|
|
841
879
|
${prompt.prepend.trim()}`);
|
|
@@ -963,6 +1001,10 @@ function buildPipelineSection(steps) {
|
|
|
963
1001
|
}
|
|
964
1002
|
const stepTitle = step.step.charAt(0).toUpperCase() + step.step.slice(1);
|
|
965
1003
|
parts.push(`### ${stepTitle}`);
|
|
1004
|
+
if (step.mode === "plan") {
|
|
1005
|
+
parts.push(`**Before starting this step, switch to Plan Mode** by calling \`SwitchMode\` with \`target_mode_id: "plan"\`. This ensures collaborative planning with the user in a read-only context before any implementation begins.`);
|
|
1006
|
+
parts.push(``);
|
|
1007
|
+
}
|
|
966
1008
|
if (step.agent) {
|
|
967
1009
|
parts.push(`Call the \`${step.agent}\` agent.${step.output ? ` It writes to \`${step.output}\`.` : ""}`);
|
|
968
1010
|
if (step.step === "refinement") {
|
|
@@ -998,6 +1040,10 @@ If any coding agent has doubts, they will write questions in their document. App
|
|
|
998
1040
|
If any validation agent leaves comments requiring fixes, call the relevant coding agents again to address them.`);
|
|
999
1041
|
}
|
|
1000
1042
|
}
|
|
1043
|
+
if (step.mode === "plan") {
|
|
1044
|
+
parts.push(`
|
|
1045
|
+
**After this step is complete and approved**, switch back to Agent Mode to proceed with the next step.`);
|
|
1046
|
+
}
|
|
1001
1047
|
parts.push("");
|
|
1002
1048
|
}
|
|
1003
1049
|
return parts.join("\n");
|
|
@@ -2291,6 +2337,55 @@ Agent '${name}' not found in ${opts.global ? "global" : "project"}
|
|
|
2291
2337
|
Removed agent: ${name}
|
|
2292
2338
|
`));
|
|
2293
2339
|
})
|
|
2340
|
+
).addCommand(
|
|
2341
|
+
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) => {
|
|
2342
|
+
const hubDir = process.cwd();
|
|
2343
|
+
let config;
|
|
2344
|
+
try {
|
|
2345
|
+
config = await loadHubConfig(hubDir);
|
|
2346
|
+
} catch {
|
|
2347
|
+
console.log(chalk9.red("\n Could not load hub.yaml in the current directory.\n"));
|
|
2348
|
+
return;
|
|
2349
|
+
}
|
|
2350
|
+
const steps = config.workflow?.pipeline || [];
|
|
2351
|
+
const agentNames = /* @__PURE__ */ new Set();
|
|
2352
|
+
for (const step of steps) {
|
|
2353
|
+
if (step.agent) agentNames.add(step.agent);
|
|
2354
|
+
if (Array.isArray(step.agents)) {
|
|
2355
|
+
for (const a of step.agents) {
|
|
2356
|
+
agentNames.add(typeof a === "string" ? a : a.agent);
|
|
2357
|
+
}
|
|
2358
|
+
}
|
|
2359
|
+
}
|
|
2360
|
+
if (agentNames.size === 0) {
|
|
2361
|
+
console.log(chalk9.yellow("\n No agents found in hub.yaml workflow pipeline.\n"));
|
|
2362
|
+
return;
|
|
2363
|
+
}
|
|
2364
|
+
console.log(chalk9.blue(`
|
|
2365
|
+
\u2501\u2501\u2501 Syncing ${agentNames.size} agent(s) from hub.yaml \u2501\u2501\u2501
|
|
2366
|
+
`));
|
|
2367
|
+
const targetBase = opts.global ? join10(process.env.HOME || "~", ".cursor", "agents") : join10(hubDir, "agents");
|
|
2368
|
+
let installed = 0;
|
|
2369
|
+
let skipped = 0;
|
|
2370
|
+
for (const name of agentNames) {
|
|
2371
|
+
const fileName = name.endsWith(".md") ? name : `${name}.md`;
|
|
2372
|
+
const targetPath = join10(targetBase, fileName);
|
|
2373
|
+
if (!opts.force && existsSync7(targetPath)) {
|
|
2374
|
+
console.log(chalk9.dim(` \u2713 ${name} (already installed)`));
|
|
2375
|
+
skipped++;
|
|
2376
|
+
continue;
|
|
2377
|
+
}
|
|
2378
|
+
await addFromRegistry2(name, hubDir, { global: opts.global, repo: opts.repo });
|
|
2379
|
+
installed++;
|
|
2380
|
+
}
|
|
2381
|
+
console.log();
|
|
2382
|
+
if (installed > 0) console.log(chalk9.green(` ${installed} agent(s) installed`));
|
|
2383
|
+
if (skipped > 0) console.log(chalk9.dim(` ${skipped} agent(s) already up to date`));
|
|
2384
|
+
if (installed === 0 && skipped > 0) {
|
|
2385
|
+
console.log(chalk9.green(" All agents are already installed. Use --force to re-install."));
|
|
2386
|
+
}
|
|
2387
|
+
console.log();
|
|
2388
|
+
})
|
|
2294
2389
|
);
|
|
2295
2390
|
|
|
2296
2391
|
// src/commands/hooks.ts
|
|
@@ -3246,11 +3341,90 @@ function extractVersion(s) {
|
|
|
3246
3341
|
return match?.[1] || s;
|
|
3247
3342
|
}
|
|
3248
3343
|
|
|
3344
|
+
// src/commands/update.ts
|
|
3345
|
+
import { Command as Command16 } from "commander";
|
|
3346
|
+
import { execSync as execSync12 } from "child_process";
|
|
3347
|
+
import { readFileSync } from "fs";
|
|
3348
|
+
import { join as join17, dirname } from "path";
|
|
3349
|
+
import { fileURLToPath } from "url";
|
|
3350
|
+
import chalk16 from "chalk";
|
|
3351
|
+
var PACKAGE_NAME = "@arvoretech/hub";
|
|
3352
|
+
function getCurrentVersion() {
|
|
3353
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
3354
|
+
const pkgPath = join17(__dirname, "..", "package.json");
|
|
3355
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
3356
|
+
return pkg.version;
|
|
3357
|
+
}
|
|
3358
|
+
async function getLatestVersion() {
|
|
3359
|
+
const res = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`);
|
|
3360
|
+
if (!res.ok) throw new Error(`npm registry returned ${res.status}`);
|
|
3361
|
+
const data = await res.json();
|
|
3362
|
+
return data.version;
|
|
3363
|
+
}
|
|
3364
|
+
function detectPackageManager() {
|
|
3365
|
+
try {
|
|
3366
|
+
execSync12("pnpm --version", { stdio: "pipe" });
|
|
3367
|
+
return "pnpm";
|
|
3368
|
+
} catch {
|
|
3369
|
+
try {
|
|
3370
|
+
execSync12("yarn --version", { stdio: "pipe" });
|
|
3371
|
+
return "yarn";
|
|
3372
|
+
} catch {
|
|
3373
|
+
return "npm";
|
|
3374
|
+
}
|
|
3375
|
+
}
|
|
3376
|
+
}
|
|
3377
|
+
var updateCommand = new Command16("update").description("Update hub CLI to the latest version").option("--check", "Only check for updates without installing").action(async (opts) => {
|
|
3378
|
+
const currentVersion = getCurrentVersion();
|
|
3379
|
+
console.log(chalk16.blue(`
|
|
3380
|
+
Current version: ${currentVersion}`));
|
|
3381
|
+
let latestVersion;
|
|
3382
|
+
try {
|
|
3383
|
+
latestVersion = await getLatestVersion();
|
|
3384
|
+
} catch (err) {
|
|
3385
|
+
console.log(chalk16.red(` Failed to check for updates: ${err.message}
|
|
3386
|
+
`));
|
|
3387
|
+
return;
|
|
3388
|
+
}
|
|
3389
|
+
console.log(chalk16.blue(` Latest version: ${latestVersion}`));
|
|
3390
|
+
if (currentVersion === latestVersion) {
|
|
3391
|
+
console.log(chalk16.green("\n You're already on the latest version.\n"));
|
|
3392
|
+
return;
|
|
3393
|
+
}
|
|
3394
|
+
console.log(chalk16.yellow(`
|
|
3395
|
+
Update available: ${currentVersion} \u2192 ${latestVersion}`));
|
|
3396
|
+
if (opts.check) {
|
|
3397
|
+
const pm2 = detectPackageManager();
|
|
3398
|
+
console.log(chalk16.dim(`
|
|
3399
|
+
Run 'hub update' or '${pm2} install -g ${PACKAGE_NAME}@latest' to update.
|
|
3400
|
+
`));
|
|
3401
|
+
return;
|
|
3402
|
+
}
|
|
3403
|
+
const pm = detectPackageManager();
|
|
3404
|
+
const installCmd = pm === "pnpm" ? `pnpm install -g ${PACKAGE_NAME}@latest` : pm === "yarn" ? `yarn global add ${PACKAGE_NAME}@latest` : `npm install -g ${PACKAGE_NAME}@latest`;
|
|
3405
|
+
console.log(chalk16.cyan(`
|
|
3406
|
+
Updating with ${pm}...
|
|
3407
|
+
`));
|
|
3408
|
+
console.log(chalk16.dim(` $ ${installCmd}
|
|
3409
|
+
`));
|
|
3410
|
+
try {
|
|
3411
|
+
execSync12(installCmd, { stdio: "inherit" });
|
|
3412
|
+
console.log(chalk16.green(`
|
|
3413
|
+
Updated to ${latestVersion} successfully.
|
|
3414
|
+
`));
|
|
3415
|
+
} catch {
|
|
3416
|
+
console.log(chalk16.red(`
|
|
3417
|
+
Update failed. Try running manually:`));
|
|
3418
|
+
console.log(chalk16.dim(` $ ${installCmd}
|
|
3419
|
+
`));
|
|
3420
|
+
}
|
|
3421
|
+
});
|
|
3422
|
+
|
|
3249
3423
|
// src/index.ts
|
|
3250
|
-
var program = new
|
|
3424
|
+
var program = new Command17();
|
|
3251
3425
|
program.name("hub").description(
|
|
3252
3426
|
"Give your AI coding assistant the full picture. Multi-repo context, agent orchestration, and end-to-end workflows."
|
|
3253
|
-
).version("0.
|
|
3427
|
+
).version("0.2.0").enablePositionalOptions();
|
|
3254
3428
|
program.addCommand(initCommand);
|
|
3255
3429
|
program.addCommand(addRepoCommand);
|
|
3256
3430
|
program.addCommand(setupCommand);
|
|
@@ -3268,4 +3442,5 @@ program.addCommand(execCommand);
|
|
|
3268
3442
|
program.addCommand(worktreeCommand);
|
|
3269
3443
|
program.addCommand(doctorCommand);
|
|
3270
3444
|
program.addCommand(toolsCommand);
|
|
3445
|
+
program.addCommand(updateCommand);
|
|
3271
3446
|
program.parse();
|