@hazeljs/cli 2.0.0 → 2.0.2
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/cli-manifest.json +167 -1
- package/dist/commands/agent-templates.d.ts +27 -0
- package/dist/commands/agent-templates.js +480 -0
- package/dist/commands/agent.d.ts +2 -0
- package/dist/commands/agent.js +368 -2
- package/dist/commands/agent.test.js +93 -3
- package/dist/commands/gatekeeper.d.ts +7 -0
- package/dist/commands/gatekeeper.js +170 -0
- package/dist/commands/store.d.ts +7 -0
- package/dist/commands/store.js +203 -0
- package/dist/commands/store.test.d.ts +1 -0
- package/dist/commands/store.test.js +120 -0
- package/dist/index.js +4 -0
- package/dist/utils/packages-registry.js +17 -1
- package/package.json +16 -19
package/dist/commands/agent.js
CHANGED
|
@@ -37,19 +37,92 @@ exports.registerAgentCommand = registerAgentCommand;
|
|
|
37
37
|
const fs = __importStar(require("fs"));
|
|
38
38
|
const os = __importStar(require("os"));
|
|
39
39
|
const path = __importStar(require("path"));
|
|
40
|
+
const agent_templates_1 = require("./agent-templates");
|
|
40
41
|
const DEFAULT_RUN_STORE = path.join('.hazel', 'agent-runs.json');
|
|
41
42
|
const DEFAULT_DURABLE_DIR = path.join('.hazel', 'runs');
|
|
42
43
|
const DEFAULT_TIMELINE = path.join('.hazel', 'runs', 'timeline.jsonl');
|
|
44
|
+
const DEFAULT_PLATFORM_STORE = path.join('.hazel', 'platform', 'resources.json');
|
|
43
45
|
/**
|
|
46
|
+
* `hazel agent new` — scaffold Agent OS / DNA templates (G2 template unification).
|
|
44
47
|
* `hazel agent install <file.dna.json>` — validate / print marketplace install plan.
|
|
45
48
|
* `hazel agent run` — live execute from DNA (AOS-011).
|
|
49
|
+
* `hazel agent apply|get|describe|delete|reconcile|events` — declarative platform resources (local control plane).
|
|
46
50
|
* `hazel agent logs` / `doctor` — timeline + environment checks.
|
|
47
51
|
* `hazel agent runs list|inspect|cancel|resume|approve` — durable store ops.
|
|
48
52
|
*/
|
|
49
53
|
function registerAgentCommand(program) {
|
|
50
54
|
const agent = program
|
|
51
55
|
.command('agent')
|
|
52
|
-
.description('Agent OS DNA / runtime / marketplace helpers');
|
|
56
|
+
.description('Agent OS DNA / runtime / marketplace / platform helpers');
|
|
57
|
+
agent
|
|
58
|
+
.command('templates')
|
|
59
|
+
.description('List Agent OS / DNA project templates')
|
|
60
|
+
.option('--json', 'Print JSON')
|
|
61
|
+
.action((opts) => {
|
|
62
|
+
const templates = (0, agent_templates_1.listAgentTemplates)();
|
|
63
|
+
if (opts.json) {
|
|
64
|
+
// eslint-disable-next-line no-console
|
|
65
|
+
console.log(JSON.stringify({ ok: true, templates }, null, 2));
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
// eslint-disable-next-line no-console
|
|
69
|
+
console.log('\nAgent OS templates (`hazel agent new <name> --template <id>`):\n');
|
|
70
|
+
for (const t of templates) {
|
|
71
|
+
// eslint-disable-next-line no-console
|
|
72
|
+
console.log(` ${t.id.padEnd(12)} ${t.label}`);
|
|
73
|
+
// eslint-disable-next-line no-console
|
|
74
|
+
console.log(` ${t.description}\n`);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
agent
|
|
78
|
+
.command('new')
|
|
79
|
+
.description('Scaffold an Agent OS / DNA project (bare | agent-os | skillgate). DNA = contract; app tools = implementation.')
|
|
80
|
+
.argument('<name>', 'Project directory / package name')
|
|
81
|
+
.option('-t, --template <id>', 'Template: bare | agent-os | skillgate', 'agent-os')
|
|
82
|
+
.option('-d, --dest <dir>', 'Parent directory', '.')
|
|
83
|
+
.option('-f, --force', 'Allow non-empty destination')
|
|
84
|
+
.option('--json', 'Print machine-readable result')
|
|
85
|
+
.action((name, opts) => {
|
|
86
|
+
try {
|
|
87
|
+
const destDir = path.resolve(process.cwd(), opts.dest, name);
|
|
88
|
+
const result = (0, agent_templates_1.scaffoldAgentProject)({
|
|
89
|
+
name,
|
|
90
|
+
destDir,
|
|
91
|
+
template: opts.template,
|
|
92
|
+
force: opts.force,
|
|
93
|
+
});
|
|
94
|
+
const payload = {
|
|
95
|
+
ok: true,
|
|
96
|
+
action: 'agent-new',
|
|
97
|
+
...result,
|
|
98
|
+
next: [
|
|
99
|
+
`cd ${path.relative(process.cwd(), result.path) || '.'}`,
|
|
100
|
+
result.template === 'bare'
|
|
101
|
+
? 'npx hazel agent run dna/agent.marketplace.json "hello"'
|
|
102
|
+
: 'npm install && npm run dev',
|
|
103
|
+
'npx hazel store publish dna/agent.marketplace.json',
|
|
104
|
+
],
|
|
105
|
+
};
|
|
106
|
+
// eslint-disable-next-line no-console
|
|
107
|
+
console.log(opts.json
|
|
108
|
+
? JSON.stringify(payload, null, 2)
|
|
109
|
+
: [
|
|
110
|
+
`✓ Created Agent OS project (${result.template})`,
|
|
111
|
+
` ${result.path}`,
|
|
112
|
+
` files: ${result.files.length}`,
|
|
113
|
+
'',
|
|
114
|
+
'Next:',
|
|
115
|
+
...payload.next.map((l) => ` ${l}`),
|
|
116
|
+
'',
|
|
117
|
+
'Note: `hazel agent run` on DNA uses stub tools. Use the app (`npm run dev`) for real @Tool / Skillgate handlers.',
|
|
118
|
+
].join('\n'));
|
|
119
|
+
}
|
|
120
|
+
catch (e) {
|
|
121
|
+
// eslint-disable-next-line no-console
|
|
122
|
+
console.error(e instanceof Error ? e.message : e);
|
|
123
|
+
process.exitCode = 1;
|
|
124
|
+
}
|
|
125
|
+
});
|
|
53
126
|
agent
|
|
54
127
|
.command('install')
|
|
55
128
|
.description('Validate a .dna / marketplace JSON package and print install plan')
|
|
@@ -66,7 +139,7 @@ function registerAgentCommand(program) {
|
|
|
66
139
|
agent: pkg.dna.name,
|
|
67
140
|
tools: pkg.dna.tools.map((t) => t.name),
|
|
68
141
|
hasPolicies: Boolean(pkg.dna.policies?.length),
|
|
69
|
-
note: '
|
|
142
|
+
note: 'Validate only. Use hazel store install to materialize into .hazel/agents; call runtime.installAgentPackage(path) to hot-reload',
|
|
70
143
|
}, null, 2));
|
|
71
144
|
if (opts.out) {
|
|
72
145
|
const outPath = path.join(opts.out, `${pkg.dna.name}.marketplace.json`);
|
|
@@ -445,4 +518,297 @@ function registerAgentCommand(program) {
|
|
|
445
518
|
.action(async (runId, opts) => {
|
|
446
519
|
await resumeAction(runId, { ...opts, approve: true });
|
|
447
520
|
});
|
|
521
|
+
agent
|
|
522
|
+
.command('apply')
|
|
523
|
+
.description('Apply declarative Agent OS platform resources (Definition / Deployment / Run)')
|
|
524
|
+
.requiredOption('-f, --file <path>', 'Manifest file (JSON or YAML)')
|
|
525
|
+
.option('--store <path>', 'Platform resource store path', DEFAULT_PLATFORM_STORE)
|
|
526
|
+
.option('--registry <path>', 'Local package registry root for packageRef resolution')
|
|
527
|
+
.option('--project <path>', 'Project root for .hazel/agents packageRef resolution', '.')
|
|
528
|
+
.action(async (opts) => {
|
|
529
|
+
try {
|
|
530
|
+
const { createLocalPlatform, defaultRegistryRoot, parsePlatformDocuments } = await Promise.resolve().then(() => __importStar(require('@hazeljs/agent')));
|
|
531
|
+
const text = fs.readFileSync(path.resolve(opts.file), 'utf8');
|
|
532
|
+
const docs = parsePlatformDocuments(text);
|
|
533
|
+
const projectRoot = path.resolve(opts.project);
|
|
534
|
+
const platform = createLocalPlatform({
|
|
535
|
+
storePath: path.resolve(opts.store),
|
|
536
|
+
projectRoot,
|
|
537
|
+
registryRoot: opts.registry ? path.resolve(opts.registry) : defaultRegistryRoot(),
|
|
538
|
+
});
|
|
539
|
+
const results = [];
|
|
540
|
+
for (const doc of docs) {
|
|
541
|
+
const result = await platform.reconciler.applyResource(doc);
|
|
542
|
+
results.push({
|
|
543
|
+
kind: result.resource.kind,
|
|
544
|
+
name: result.resource.metadata.name,
|
|
545
|
+
namespace: result.resource.metadata.namespace ?? 'default',
|
|
546
|
+
generation: result.resource.metadata.generation,
|
|
547
|
+
ready: result.ready,
|
|
548
|
+
message: result.message,
|
|
549
|
+
conditions: result.resource.status?.conditions,
|
|
550
|
+
resolved: result.resource.status?.backend,
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
// eslint-disable-next-line no-console
|
|
554
|
+
console.log(JSON.stringify({ applied: results.length, results }, null, 2));
|
|
555
|
+
if (results.some((r) => !r.ready))
|
|
556
|
+
process.exitCode = 1;
|
|
557
|
+
}
|
|
558
|
+
catch (e) {
|
|
559
|
+
// eslint-disable-next-line no-console
|
|
560
|
+
console.error(e instanceof Error ? e.message : e);
|
|
561
|
+
process.exitCode = 1;
|
|
562
|
+
}
|
|
563
|
+
});
|
|
564
|
+
agent
|
|
565
|
+
.command('get')
|
|
566
|
+
.description('List or get platform resources from the local store')
|
|
567
|
+
.argument('[type]', 'Resource type (e.g. agentdefinitions, agentdeployments)')
|
|
568
|
+
.argument('[name]', 'Resource name')
|
|
569
|
+
.option('--store <path>', 'Platform resource store path', DEFAULT_PLATFORM_STORE)
|
|
570
|
+
.option('-n, --namespace <ns>', 'Namespace filter', 'default')
|
|
571
|
+
.option('--all-namespaces', 'List across namespaces')
|
|
572
|
+
.option('--project <path>', 'Project root (durable run correlation)', '.')
|
|
573
|
+
.option('--summary', 'Print secret-safe summaries instead of full resources')
|
|
574
|
+
.action(async (type, name, opts) => {
|
|
575
|
+
try {
|
|
576
|
+
const { createLocalPlatform, parseResourceTypeArg, summarizeResource } = await Promise.resolve().then(() => __importStar(require('@hazeljs/agent')));
|
|
577
|
+
const platform = createLocalPlatform({
|
|
578
|
+
storePath: path.resolve(opts.store),
|
|
579
|
+
projectRoot: path.resolve(opts.project),
|
|
580
|
+
actor: 'cli',
|
|
581
|
+
});
|
|
582
|
+
let kind;
|
|
583
|
+
let resourceName = name;
|
|
584
|
+
if (type) {
|
|
585
|
+
const parsed = parseResourceTypeArg(name ? `${type}/${name}` : type);
|
|
586
|
+
kind = parsed.kind;
|
|
587
|
+
resourceName = parsed.name ?? name;
|
|
588
|
+
if (parsed.namespace && !opts.allNamespaces) {
|
|
589
|
+
opts.namespace = parsed.namespace;
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
if (kind && resourceName) {
|
|
593
|
+
const found = platform.repo.get(kind, resourceName, opts.namespace);
|
|
594
|
+
if (!found) {
|
|
595
|
+
// eslint-disable-next-line no-console
|
|
596
|
+
console.error(`Not found: ${opts.namespace}/${kind}/${resourceName}`);
|
|
597
|
+
process.exitCode = 1;
|
|
598
|
+
return;
|
|
599
|
+
}
|
|
600
|
+
// eslint-disable-next-line no-console
|
|
601
|
+
console.log(JSON.stringify(opts.summary ? summarizeResource(found) : found, null, 2));
|
|
602
|
+
return;
|
|
603
|
+
}
|
|
604
|
+
const items = platform.repo.list({
|
|
605
|
+
kind,
|
|
606
|
+
namespace: opts.allNamespaces ? undefined : opts.namespace,
|
|
607
|
+
});
|
|
608
|
+
// eslint-disable-next-line no-console
|
|
609
|
+
console.log(JSON.stringify({
|
|
610
|
+
items: opts.summary
|
|
611
|
+
? items.map(summarizeResource)
|
|
612
|
+
: items.map((r) => ({
|
|
613
|
+
kind: r.kind,
|
|
614
|
+
name: r.metadata.name,
|
|
615
|
+
namespace: r.metadata.namespace ?? 'default',
|
|
616
|
+
generation: r.metadata.generation,
|
|
617
|
+
ready: r.status?.conditions?.find((c) => c.type === 'Ready')?.status,
|
|
618
|
+
})),
|
|
619
|
+
}, null, 2));
|
|
620
|
+
}
|
|
621
|
+
catch (e) {
|
|
622
|
+
// eslint-disable-next-line no-console
|
|
623
|
+
console.error(e instanceof Error ? e.message : e);
|
|
624
|
+
process.exitCode = 1;
|
|
625
|
+
}
|
|
626
|
+
});
|
|
627
|
+
agent
|
|
628
|
+
.command('describe')
|
|
629
|
+
.description('Describe a platform resource (spec, status, conditions)')
|
|
630
|
+
.argument('<resource>', 'kind/name or namespace/kind/name')
|
|
631
|
+
.option('--store <path>', 'Platform resource store path', DEFAULT_PLATFORM_STORE)
|
|
632
|
+
.option('--project <path>', 'Project root (re-correlate durable runs on describe)', '.')
|
|
633
|
+
.option('--refresh', 'Re-reconcile before describe (refresh durable correlation)')
|
|
634
|
+
.action(async (resource, opts) => {
|
|
635
|
+
try {
|
|
636
|
+
const { createLocalPlatform, parseResourceTypeArg } = await Promise.resolve().then(() => __importStar(require('@hazeljs/agent')));
|
|
637
|
+
const parsed = parseResourceTypeArg(resource);
|
|
638
|
+
if (!parsed.name) {
|
|
639
|
+
throw new Error('describe requires kind/name (e.g. agentdeployment/support)');
|
|
640
|
+
}
|
|
641
|
+
const platform = createLocalPlatform({
|
|
642
|
+
storePath: path.resolve(opts.store),
|
|
643
|
+
projectRoot: path.resolve(opts.project),
|
|
644
|
+
});
|
|
645
|
+
const ns = parsed.namespace ?? 'default';
|
|
646
|
+
if (opts.refresh) {
|
|
647
|
+
if (parsed.kind === 'AgentDeployment') {
|
|
648
|
+
await platform.reconciler.reconcileDeployment(parsed.name, ns);
|
|
649
|
+
}
|
|
650
|
+
else if (parsed.kind === 'AgentRun') {
|
|
651
|
+
await platform.reconciler.reconcileRun(parsed.name, ns);
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
const found = platform.repo.get(parsed.kind, parsed.name, ns);
|
|
655
|
+
if (!found) {
|
|
656
|
+
// eslint-disable-next-line no-console
|
|
657
|
+
console.error(`Not found: ${ns}/${parsed.kind}/${parsed.name}`);
|
|
658
|
+
process.exitCode = 1;
|
|
659
|
+
return;
|
|
660
|
+
}
|
|
661
|
+
const { summarizeResource } = await Promise.resolve().then(() => __importStar(require('@hazeljs/agent')));
|
|
662
|
+
// eslint-disable-next-line no-console
|
|
663
|
+
console.log(JSON.stringify({
|
|
664
|
+
resource: found,
|
|
665
|
+
summary: summarizeResource(found),
|
|
666
|
+
}, null, 2));
|
|
667
|
+
}
|
|
668
|
+
catch (e) {
|
|
669
|
+
// eslint-disable-next-line no-console
|
|
670
|
+
console.error(e instanceof Error ? e.message : e);
|
|
671
|
+
process.exitCode = 1;
|
|
672
|
+
}
|
|
673
|
+
});
|
|
674
|
+
agent
|
|
675
|
+
.command('delete')
|
|
676
|
+
.description('Delete a platform resource (deployments clean up the local backend)')
|
|
677
|
+
.argument('<resource>', 'kind/name or namespace/kind/name')
|
|
678
|
+
.option('--store <path>', 'Platform resource store path', DEFAULT_PLATFORM_STORE)
|
|
679
|
+
.action(async (resource, opts) => {
|
|
680
|
+
try {
|
|
681
|
+
const { createLocalPlatform, parseResourceTypeArg } = await Promise.resolve().then(() => __importStar(require('@hazeljs/agent')));
|
|
682
|
+
const parsed = parseResourceTypeArg(resource);
|
|
683
|
+
if (!parsed.name) {
|
|
684
|
+
throw new Error('delete requires kind/name (e.g. agentdeployment/support)');
|
|
685
|
+
}
|
|
686
|
+
const platform = createLocalPlatform({
|
|
687
|
+
storePath: path.resolve(opts.store),
|
|
688
|
+
projectRoot: process.cwd(),
|
|
689
|
+
});
|
|
690
|
+
const result = await platform.reconciler.deleteResource({
|
|
691
|
+
kind: parsed.kind,
|
|
692
|
+
name: parsed.name,
|
|
693
|
+
namespace: parsed.namespace ?? 'default',
|
|
694
|
+
});
|
|
695
|
+
// FileResourceRepository auto-persists; keep save() for compatibility
|
|
696
|
+
platform.save();
|
|
697
|
+
// eslint-disable-next-line no-console
|
|
698
|
+
console.log(JSON.stringify({
|
|
699
|
+
deleted: result.deleted,
|
|
700
|
+
kind: parsed.kind,
|
|
701
|
+
name: parsed.name,
|
|
702
|
+
namespace: parsed.namespace ?? 'default',
|
|
703
|
+
backendMessage: result.backendMessage,
|
|
704
|
+
}, null, 2));
|
|
705
|
+
if (!result.deleted)
|
|
706
|
+
process.exitCode = 1;
|
|
707
|
+
}
|
|
708
|
+
catch (e) {
|
|
709
|
+
// eslint-disable-next-line no-console
|
|
710
|
+
console.error(e instanceof Error ? e.message : e);
|
|
711
|
+
process.exitCode = 1;
|
|
712
|
+
}
|
|
713
|
+
});
|
|
714
|
+
agent
|
|
715
|
+
.command('reconcile')
|
|
716
|
+
.description('Reconcile all AgentDeployments / AgentRuns in the local platform store (control-plane loop)')
|
|
717
|
+
.option('--store <path>', 'Platform resource store path', DEFAULT_PLATFORM_STORE)
|
|
718
|
+
.option('--project <path>', 'Project root for packageRef / durable run correlation', '.')
|
|
719
|
+
.option('--registry <path>', 'Local package registry root for packageRef resolution')
|
|
720
|
+
.option('-n, --namespace <ns>', 'Limit to one namespace')
|
|
721
|
+
.option('--watch', 'Keep reconciling on an interval until interrupted')
|
|
722
|
+
.option('--interval <seconds>', 'Watch interval in seconds (default 5)', '5')
|
|
723
|
+
.action(async (opts) => {
|
|
724
|
+
try {
|
|
725
|
+
const { createLocalPlatform, defaultRegistryRoot, watchLocalPlatform } = await Promise.resolve().then(() => __importStar(require('@hazeljs/agent')));
|
|
726
|
+
const projectRoot = path.resolve(opts.project);
|
|
727
|
+
const platform = createLocalPlatform({
|
|
728
|
+
storePath: path.resolve(opts.store),
|
|
729
|
+
projectRoot,
|
|
730
|
+
registryRoot: opts.registry ? path.resolve(opts.registry) : defaultRegistryRoot(),
|
|
731
|
+
actor: 'cli',
|
|
732
|
+
});
|
|
733
|
+
const namespace = opts.namespace;
|
|
734
|
+
const printTick = (result, tick) => {
|
|
735
|
+
// eslint-disable-next-line no-console
|
|
736
|
+
console.log(JSON.stringify({
|
|
737
|
+
tick: tick ?? 1,
|
|
738
|
+
ready: result.ready,
|
|
739
|
+
notReady: result.notReady,
|
|
740
|
+
errors: result.errors,
|
|
741
|
+
items: result.results.map((r) => ({
|
|
742
|
+
kind: r.resource.kind,
|
|
743
|
+
name: r.resource.metadata.name,
|
|
744
|
+
namespace: r.resource.metadata.namespace ?? 'default',
|
|
745
|
+
ready: r.ready,
|
|
746
|
+
message: r.message,
|
|
747
|
+
})),
|
|
748
|
+
}, null, 2));
|
|
749
|
+
};
|
|
750
|
+
if (!opts.watch) {
|
|
751
|
+
const result = await platform.reconcileAll({ namespace });
|
|
752
|
+
printTick(result);
|
|
753
|
+
if (result.notReady > 0 || result.errors.length > 0)
|
|
754
|
+
process.exitCode = 1;
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
const seconds = Math.max(1, Number(opts.interval) || 5);
|
|
758
|
+
const ac = new AbortController();
|
|
759
|
+
const onSig = () => ac.abort();
|
|
760
|
+
process.on('SIGINT', onSig);
|
|
761
|
+
process.on('SIGTERM', onSig);
|
|
762
|
+
// eslint-disable-next-line no-console
|
|
763
|
+
console.error(`Watching every ${seconds}s (Ctrl+C to stop)…`);
|
|
764
|
+
await watchLocalPlatform(platform, {
|
|
765
|
+
namespace,
|
|
766
|
+
intervalMs: seconds * 1000,
|
|
767
|
+
signal: ac.signal,
|
|
768
|
+
onTick: async (result, tick) => {
|
|
769
|
+
printTick(result, tick);
|
|
770
|
+
},
|
|
771
|
+
});
|
|
772
|
+
process.off('SIGINT', onSig);
|
|
773
|
+
process.off('SIGTERM', onSig);
|
|
774
|
+
}
|
|
775
|
+
catch (e) {
|
|
776
|
+
// eslint-disable-next-line no-console
|
|
777
|
+
console.error(e instanceof Error ? e.message : e);
|
|
778
|
+
process.exitCode = 1;
|
|
779
|
+
}
|
|
780
|
+
});
|
|
781
|
+
agent
|
|
782
|
+
.command('events')
|
|
783
|
+
.description('List platform control-plane events (audit log; no secrets)')
|
|
784
|
+
.option('--store <path>', 'Platform resource store path', DEFAULT_PLATFORM_STORE)
|
|
785
|
+
.option('--events <path>', 'Events JSONL path (default: beside store)')
|
|
786
|
+
.option('--type <type>', 'Filter by event type')
|
|
787
|
+
.option('--kind <kind>', 'Filter by resource kind')
|
|
788
|
+
.option('--limit <n>', 'Max events (most recent)', '50')
|
|
789
|
+
.action(async (opts) => {
|
|
790
|
+
try {
|
|
791
|
+
const { createLocalPlatform } = await Promise.resolve().then(() => __importStar(require('@hazeljs/agent')));
|
|
792
|
+
const storePath = path.resolve(opts.store);
|
|
793
|
+
const platform = createLocalPlatform({
|
|
794
|
+
storePath,
|
|
795
|
+
eventsPath: opts.events
|
|
796
|
+
? path.resolve(opts.events)
|
|
797
|
+
: path.join(path.dirname(storePath), 'events.jsonl'),
|
|
798
|
+
actor: 'cli',
|
|
799
|
+
});
|
|
800
|
+
const items = platform.events.list({
|
|
801
|
+
type: opts.type,
|
|
802
|
+
kind: opts.kind,
|
|
803
|
+
limit: Number(opts.limit) || 50,
|
|
804
|
+
});
|
|
805
|
+
// eslint-disable-next-line no-console
|
|
806
|
+
console.log(JSON.stringify({ items }, null, 2));
|
|
807
|
+
}
|
|
808
|
+
catch (e) {
|
|
809
|
+
// eslint-disable-next-line no-console
|
|
810
|
+
console.error(e instanceof Error ? e.message : e);
|
|
811
|
+
process.exitCode = 1;
|
|
812
|
+
}
|
|
813
|
+
});
|
|
448
814
|
}
|
|
@@ -1,14 +1,104 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const fs = __importStar(require("fs"));
|
|
37
|
+
const os = __importStar(require("os"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
3
39
|
const commander_1 = require("commander");
|
|
4
40
|
const agent_1 = require("./agent");
|
|
5
|
-
|
|
6
|
-
|
|
41
|
+
const agent_templates_1 = require("./agent-templates");
|
|
42
|
+
describe('registerAgentCommand (AOS-011 + templates)', () => {
|
|
43
|
+
it('registers run, logs, doctor, new, and templates subcommands', () => {
|
|
7
44
|
const program = new commander_1.Command();
|
|
8
45
|
(0, agent_1.registerAgentCommand)(program);
|
|
9
46
|
const agent = program.commands.find((c) => c.name() === 'agent');
|
|
10
47
|
expect(agent).toBeDefined();
|
|
11
48
|
const names = agent.commands.map((c) => c.name());
|
|
12
|
-
expect(names).toEqual(expect.arrayContaining([
|
|
49
|
+
expect(names).toEqual(expect.arrayContaining([
|
|
50
|
+
'install',
|
|
51
|
+
'dna',
|
|
52
|
+
'run',
|
|
53
|
+
'logs',
|
|
54
|
+
'doctor',
|
|
55
|
+
'runs',
|
|
56
|
+
'new',
|
|
57
|
+
'templates',
|
|
58
|
+
'apply',
|
|
59
|
+
'get',
|
|
60
|
+
'describe',
|
|
61
|
+
'delete',
|
|
62
|
+
'events',
|
|
63
|
+
]));
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
describe('agent templates scaffold', () => {
|
|
67
|
+
let tmp;
|
|
68
|
+
beforeEach(() => {
|
|
69
|
+
tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'hazel-agent-new-'));
|
|
70
|
+
});
|
|
71
|
+
afterEach(() => {
|
|
72
|
+
fs.rmSync(tmp, { recursive: true, force: true });
|
|
73
|
+
});
|
|
74
|
+
it('lists three templates', () => {
|
|
75
|
+
expect((0, agent_templates_1.listAgentTemplates)().map((t) => t.id)).toEqual(['bare', 'agent-os', 'skillgate']);
|
|
76
|
+
});
|
|
77
|
+
it('scaffolds bare DNA package', () => {
|
|
78
|
+
const dest = path.join(tmp, 'bare-demo');
|
|
79
|
+
const result = (0, agent_templates_1.scaffoldAgentProject)({ name: 'bare-demo', destDir: dest, template: 'bare' });
|
|
80
|
+
expect(result.files).toContain('dna/agent.marketplace.json');
|
|
81
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(dest, 'dna/agent.marketplace.json'), 'utf8'));
|
|
82
|
+
expect(pkg.dna.format).toBe('hazeljs.agent.dna');
|
|
83
|
+
expect(pkg.dna.name).toBeTruthy();
|
|
84
|
+
});
|
|
85
|
+
it('scaffolds agent-os with real tool source', () => {
|
|
86
|
+
const dest = path.join(tmp, 'os-demo');
|
|
87
|
+
(0, agent_templates_1.scaffoldAgentProject)({ name: 'os-demo', destDir: dest, template: 'agent-os' });
|
|
88
|
+
expect(fs.existsSync(path.join(dest, 'src/support.agent.ts'))).toBe(true);
|
|
89
|
+
expect(fs.existsSync(path.join(dest, 'src/main.ts'))).toBe(true);
|
|
90
|
+
expect(fs.existsSync(path.join(dest, 'dna/agent.marketplace.json'))).toBe(true);
|
|
91
|
+
});
|
|
92
|
+
it('scaffolds skillgate with openapi sample', () => {
|
|
93
|
+
const dest = path.join(tmp, 'sg-demo');
|
|
94
|
+
(0, agent_templates_1.scaffoldAgentProject)({ name: 'sg-demo', destDir: dest, template: 'skillgate' });
|
|
95
|
+
expect(fs.existsSync(path.join(dest, 'openapi/sample.openapi.json'))).toBe(true);
|
|
96
|
+
expect(fs.existsSync(path.join(dest, 'src/report.ts'))).toBe(true);
|
|
97
|
+
});
|
|
98
|
+
it('refuses non-empty dest without force', () => {
|
|
99
|
+
const dest = path.join(tmp, 'taken');
|
|
100
|
+
fs.mkdirSync(dest);
|
|
101
|
+
fs.writeFileSync(path.join(dest, 'x.txt'), 'x');
|
|
102
|
+
expect(() => (0, agent_templates_1.scaffoldAgentProject)({ name: 'taken', destDir: dest, template: 'bare' })).toThrow(/not empty/);
|
|
13
103
|
});
|
|
14
104
|
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
/**
|
|
3
|
+
* `hazel gatekeeper validate --config agent-gatekeeper.yaml`
|
|
4
|
+
* `hazel gatekeeper simulate --agent refund-agent --tool stripe.refund --input input.json`
|
|
5
|
+
* `hazel gatekeeper explain --invocation invocation.json`
|
|
6
|
+
*/
|
|
7
|
+
export declare function registerGatekeeperCommand(program: Command): void;
|