@potential-agents/cli 0.0.0-stage → 0.1.1
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/LICENSE +21 -0
- package/README.md +83 -2
- package/dist/adapters/outbound/filesystem/bundle-filesystem-repository.d.ts +20 -0
- package/dist/adapters/outbound/filesystem/bundle-filesystem-repository.js +181 -0
- package/dist/adapters/outbound/filesystem/bundle-filesystem-repository.js.map +1 -0
- package/dist/adapters/outbound/filesystem/yaml-lock-repository.d.ts +7 -0
- package/dist/adapters/outbound/filesystem/yaml-lock-repository.js +64 -0
- package/dist/adapters/outbound/filesystem/yaml-lock-repository.js.map +1 -0
- package/dist/adapters/outbound/http/http-potential-agents-api.d.ts +36 -0
- package/dist/adapters/outbound/http/http-potential-agents-api.js +150 -0
- package/dist/adapters/outbound/http/http-potential-agents-api.js.map +1 -0
- package/dist/adapters/outbound/runtime/sha256-idempotency-key-generator.d.ts +5 -0
- package/dist/adapters/outbound/runtime/sha256-idempotency-key-generator.js +8 -0
- package/dist/adapters/outbound/runtime/sha256-idempotency-key-generator.js.map +1 -0
- package/dist/application/apply-bundle.d.ts +22 -0
- package/dist/application/apply-bundle.js +78 -0
- package/dist/application/apply-bundle.js.map +1 -0
- package/dist/application/plan-bundle.d.ts +18 -0
- package/dist/application/plan-bundle.js +22 -0
- package/dist/application/plan-bundle.js.map +1 -0
- package/dist/application/ports/bundle-repository.d.ts +6 -0
- package/dist/application/ports/bundle-repository.js +2 -0
- package/dist/application/ports/bundle-repository.js.map +1 -0
- package/dist/application/ports/idempotency-key-generator.d.ts +4 -0
- package/dist/application/ports/idempotency-key-generator.js +2 -0
- package/dist/application/ports/idempotency-key-generator.js.map +1 -0
- package/dist/application/ports/lock-repository.d.ts +6 -0
- package/dist/application/ports/lock-repository.js +2 -0
- package/dist/application/ports/lock-repository.js.map +1 -0
- package/dist/application/ports/potential-agents-api.d.ts +35 -0
- package/dist/application/ports/potential-agents-api.js +2 -0
- package/dist/application/ports/potential-agents-api.js.map +1 -0
- package/dist/application/run-agent.d.ts +14 -0
- package/dist/application/run-agent.js +20 -0
- package/dist/application/run-agent.js.map +1 -0
- package/dist/application/validate-bundle.d.ts +8 -0
- package/dist/application/validate-bundle.js +11 -0
- package/dist/application/validate-bundle.js.map +1 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.js +120 -0
- package/dist/cli.js.map +1 -0
- package/dist/composition-root.d.ts +29 -0
- package/dist/composition-root.js +35 -0
- package/dist/composition-root.js.map +1 -0
- package/dist/domain/agent-definition.d.ts +40 -0
- package/dist/domain/agent-definition.js +94 -0
- package/dist/domain/agent-definition.js.map +1 -0
- package/dist/domain/bundle.d.ts +16 -0
- package/dist/domain/bundle.js +29 -0
- package/dist/domain/bundle.js.map +1 -0
- package/dist/domain/errors.d.ts +10 -0
- package/dist/domain/errors.js +16 -0
- package/dist/domain/errors.js.map +1 -0
- package/dist/domain/lock.d.ts +18 -0
- package/dist/domain/lock.js +2 -0
- package/dist/domain/lock.js.map +1 -0
- package/package.json +45 -4
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { BundleRepository } from './ports/bundle-repository.js';
|
|
2
|
+
import type { IdempotencyKeyGenerator } from './ports/idempotency-key-generator.js';
|
|
3
|
+
import type { LockRepository } from './ports/lock-repository.js';
|
|
4
|
+
import type { PotentialAgentsApi, RemoteAgent } from './ports/potential-agents-api.js';
|
|
5
|
+
import { PlanBundle } from './plan-bundle.js';
|
|
6
|
+
export interface ApplyOptions {
|
|
7
|
+
readonly wait: boolean;
|
|
8
|
+
readonly timeoutMs: number;
|
|
9
|
+
readonly pollIntervalMs: number;
|
|
10
|
+
}
|
|
11
|
+
/** Applies a planned immutable revision and updates the generated lockfile. */
|
|
12
|
+
export declare class ApplyBundle {
|
|
13
|
+
private readonly bundles;
|
|
14
|
+
private readonly locks;
|
|
15
|
+
private readonly planner;
|
|
16
|
+
private readonly api;
|
|
17
|
+
private readonly keys;
|
|
18
|
+
constructor(bundles: BundleRepository, locks: LockRepository, planner: PlanBundle, api: PotentialAgentsApi, keys: IdempotencyKeyGenerator);
|
|
19
|
+
execute(root: string, organizationId: string, options: ApplyOptions): Promise<RemoteAgent>;
|
|
20
|
+
/** Polls the control plane without changing state until a deployment becomes terminal. */
|
|
21
|
+
private _waitForReady;
|
|
22
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { configurationError, PotentialAgentsError } from '../domain/errors.js';
|
|
2
|
+
import { PlanBundle } from './plan-bundle.js';
|
|
3
|
+
/** Applies a planned immutable revision and updates the generated lockfile. */
|
|
4
|
+
export class ApplyBundle {
|
|
5
|
+
bundles;
|
|
6
|
+
locks;
|
|
7
|
+
planner;
|
|
8
|
+
api;
|
|
9
|
+
keys;
|
|
10
|
+
constructor(bundles, locks, planner, api, keys) {
|
|
11
|
+
this.bundles = bundles;
|
|
12
|
+
this.locks = locks;
|
|
13
|
+
this.planner = planner;
|
|
14
|
+
this.api = api;
|
|
15
|
+
this.keys = keys;
|
|
16
|
+
}
|
|
17
|
+
async execute(root, organizationId, options) {
|
|
18
|
+
const planned = await this.planner.execute(root, organizationId);
|
|
19
|
+
if (planned.plan.change === 'noop') {
|
|
20
|
+
if (!planned.lock)
|
|
21
|
+
throw new PotentialAgentsError('LOCK_ERROR', 'A no-op plan requires potential.lock.');
|
|
22
|
+
return this.api.getAgent(organizationId, planned.lock.agent.remoteId);
|
|
23
|
+
}
|
|
24
|
+
const updatesExistingAgent = planned.lock?.agent.localId === planned.bundle.definition.id;
|
|
25
|
+
if (updatesExistingAgent && planned.plan.change !== 'revision') {
|
|
26
|
+
throw new PotentialAgentsError('PLAN_CONFLICT', 'The control plane attempted to create a new agent for an existing local identity.');
|
|
27
|
+
}
|
|
28
|
+
if (!updatesExistingAgent && planned.plan.change !== 'create') {
|
|
29
|
+
throw new PotentialAgentsError('PLAN_CONFLICT', 'The control plane did not return a create plan for a new local identity.');
|
|
30
|
+
}
|
|
31
|
+
const uploadedSkills = await Promise.all(planned.bundle.skills.map((skill) => {
|
|
32
|
+
const locked = planned.lock?.skills[skill.path];
|
|
33
|
+
if (locked?.sha256 === skill.sha256) {
|
|
34
|
+
return Promise.resolve({ skillId: locked.skillId, revision: locked.revision, sha256: locked.sha256 });
|
|
35
|
+
}
|
|
36
|
+
return this.api.uploadSkill(organizationId, skill);
|
|
37
|
+
}));
|
|
38
|
+
const accepted = updatesExistingAgent
|
|
39
|
+
? await this.api.createRevision(organizationId, planned.lock.agent.remoteId, planned.bundle, uploadedSkills, this.keys.generate(organizationId, planned.bundle.definitionSha256, 'revision'))
|
|
40
|
+
: await this.api.createAgent(organizationId, planned.bundle, uploadedSkills, this.keys.generate(organizationId, planned.bundle.definitionSha256, 'create'));
|
|
41
|
+
const remote = options.wait ? await this._waitForReady(organizationId, accepted.agentId, options) : accepted;
|
|
42
|
+
const lock = {
|
|
43
|
+
format: 'potentialagents/lock/v1',
|
|
44
|
+
agent: {
|
|
45
|
+
localId: planned.bundle.definition.id,
|
|
46
|
+
remoteId: remote.agentId,
|
|
47
|
+
activeRevision: remote.activeRevision,
|
|
48
|
+
deploymentId: remote.deploymentId,
|
|
49
|
+
definitionSha256: planned.bundle.definitionSha256,
|
|
50
|
+
status: remote.status,
|
|
51
|
+
},
|
|
52
|
+
skills: Object.fromEntries(uploadedSkills.map((skill, index) => {
|
|
53
|
+
const source = planned.bundle.skills[index];
|
|
54
|
+
if (!source)
|
|
55
|
+
throw configurationError('Skill upload response did not match bundle skill order.');
|
|
56
|
+
return [source.path, { path: source.path, skillId: skill.skillId, revision: skill.revision, sha256: skill.sha256 }];
|
|
57
|
+
})),
|
|
58
|
+
};
|
|
59
|
+
await this.locks.write(root, lock);
|
|
60
|
+
return remote;
|
|
61
|
+
}
|
|
62
|
+
/** Polls the control plane without changing state until a deployment becomes terminal. */
|
|
63
|
+
async _waitForReady(organizationId, remoteId, options) {
|
|
64
|
+
const deadline = Date.now() + options.timeoutMs;
|
|
65
|
+
while (true) {
|
|
66
|
+
const current = await this.api.getAgent(organizationId, remoteId);
|
|
67
|
+
if (current.status === 'ready')
|
|
68
|
+
return current;
|
|
69
|
+
if (['failed', 'archived'].includes(current.status)) {
|
|
70
|
+
throw new PotentialAgentsError('DEPLOYMENT_FAILED', `Deployment for ${remoteId} is ${current.status}.`);
|
|
71
|
+
}
|
|
72
|
+
if (Date.now() >= deadline)
|
|
73
|
+
throw new PotentialAgentsError('DEPLOYMENT_TIMEOUT', `Timed out waiting for ${remoteId} to become ready.`);
|
|
74
|
+
await new Promise((resolve) => setTimeout(resolve, options.pollIntervalMs));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=apply-bundle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apply-bundle.js","sourceRoot":"","sources":["../../src/application/apply-bundle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Bundle } from '../domain/bundle.js';
|
|
2
|
+
import type { PotentialLock } from '../domain/lock.js';
|
|
3
|
+
import type { BundleRepository } from './ports/bundle-repository.js';
|
|
4
|
+
import type { LockRepository } from './ports/lock-repository.js';
|
|
5
|
+
import type { PlanResult, PotentialAgentsApi } from './ports/potential-agents-api.js';
|
|
6
|
+
export interface PlannedBundle {
|
|
7
|
+
readonly bundle: Bundle;
|
|
8
|
+
readonly lock?: PotentialLock;
|
|
9
|
+
readonly plan: PlanResult;
|
|
10
|
+
}
|
|
11
|
+
/** Resolves remote policy and determines whether an apply will create, revise, or do nothing. */
|
|
12
|
+
export declare class PlanBundle {
|
|
13
|
+
private readonly bundles;
|
|
14
|
+
private readonly locks;
|
|
15
|
+
private readonly api;
|
|
16
|
+
constructor(bundles: BundleRepository, locks: LockRepository, api: PotentialAgentsApi);
|
|
17
|
+
execute(root: string, organizationId: string): Promise<PlannedBundle>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Resolves remote policy and determines whether an apply will create, revise, or do nothing. */
|
|
2
|
+
export class PlanBundle {
|
|
3
|
+
bundles;
|
|
4
|
+
locks;
|
|
5
|
+
api;
|
|
6
|
+
constructor(bundles, locks, api) {
|
|
7
|
+
this.bundles = bundles;
|
|
8
|
+
this.locks = locks;
|
|
9
|
+
this.api = api;
|
|
10
|
+
}
|
|
11
|
+
async execute(root, organizationId) {
|
|
12
|
+
const bundle = await this.bundles.read(root);
|
|
13
|
+
const lock = await this.locks.read(root);
|
|
14
|
+
const sameLocalIdentity = lock?.agent.localId === bundle.definition.id;
|
|
15
|
+
if (sameLocalIdentity && lock?.agent.definitionSha256 === bundle.definitionSha256) {
|
|
16
|
+
return { bundle, lock, plan: { change: 'noop', reason: 'The normalized definition matches potential.lock.' } };
|
|
17
|
+
}
|
|
18
|
+
const plan = await this.api.plan(organizationId, bundle, sameLocalIdentity ? lock?.agent.remoteId : undefined);
|
|
19
|
+
return lock ? { bundle, lock, plan } : { bundle, plan };
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=plan-bundle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan-bundle.js","sourceRoot":"","sources":["../../src/application/plan-bundle.ts"],"names":[],"mappings":"AAYA,iGAAiG;AACjG,MAAM,OAAO,UAAU;IAEF;IACA;IACA;IAHnB,YACmB,OAAyB,EACzB,KAAqB,EACrB,GAAuB;QAFvB,YAAO,GAAP,OAAO,CAAkB;QACzB,UAAK,GAAL,KAAK,CAAgB;QACrB,QAAG,GAAH,GAAG,CAAoB;IACvC,CAAC;IAEG,KAAK,CAAC,OAAO,CAAC,IAAY,EAAE,cAAsB;QACvD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,MAAM,iBAAiB,GAAG,IAAI,EAAE,KAAK,CAAC,OAAO,KAAK,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;QACvE,IAAI,iBAAiB,IAAI,IAAI,EAAE,KAAK,CAAC,gBAAgB,KAAK,MAAM,CAAC,gBAAgB,EAAE,CAAC;YAClF,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,mDAAmD,EAAE,EAAE,CAAC;QACjH,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,EAAE,iBAAiB,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QAC/G,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC1D,CAAC;CACF"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Bundle } from '../../domain/bundle.js';
|
|
2
|
+
/** Loads and resolves a Potential Agents bundle from the local filesystem. */
|
|
3
|
+
export interface BundleRepository {
|
|
4
|
+
read(root: string): Promise<Bundle>;
|
|
5
|
+
initialize(root: string, overwrite: boolean): Promise<string>;
|
|
6
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle-repository.js","sourceRoot":"","sources":["../../../src/application/ports/bundle-repository.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"idempotency-key-generator.js","sourceRoot":"","sources":["../../../src/application/ports/idempotency-key-generator.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { PotentialLock } from '../../domain/lock.js';
|
|
2
|
+
/** Persists the generated remote identity separately from authored bundle intent. */
|
|
3
|
+
export interface LockRepository {
|
|
4
|
+
read(root: string): Promise<PotentialLock | undefined>;
|
|
5
|
+
write(root: string, lock: PotentialLock): Promise<void>;
|
|
6
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock-repository.js","sourceRoot":"","sources":["../../../src/application/ports/lock-repository.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Bundle, SkillSource } from '../../domain/bundle.js';
|
|
2
|
+
export interface ApiSkillRevision {
|
|
3
|
+
readonly skillId: string;
|
|
4
|
+
readonly revision: string;
|
|
5
|
+
readonly sha256: string;
|
|
6
|
+
}
|
|
7
|
+
export interface RemoteAgent {
|
|
8
|
+
readonly agentId: string;
|
|
9
|
+
readonly activeRevision: string;
|
|
10
|
+
readonly deploymentId: string;
|
|
11
|
+
readonly status: string;
|
|
12
|
+
}
|
|
13
|
+
export interface ApplyAccepted extends RemoteAgent {
|
|
14
|
+
}
|
|
15
|
+
export type PlanChange = 'create' | 'revision' | 'noop';
|
|
16
|
+
export interface PlanResult {
|
|
17
|
+
readonly change: PlanChange;
|
|
18
|
+
readonly reason: string;
|
|
19
|
+
}
|
|
20
|
+
/** Outbound port for the public Potential Agents API, never a cloud-provider SDK. */
|
|
21
|
+
export interface PotentialAgentsApi {
|
|
22
|
+
plan(organizationId: string, bundle: Bundle, remoteId?: string): Promise<PlanResult>;
|
|
23
|
+
uploadSkill(organizationId: string, skill: SkillSource): Promise<ApiSkillRevision>;
|
|
24
|
+
createAgent(organizationId: string, bundle: Bundle, skills: readonly ApiSkillRevision[], idempotencyKey: string): Promise<ApplyAccepted>;
|
|
25
|
+
createRevision(organizationId: string, remoteId: string, bundle: Bundle, skills: readonly ApiSkillRevision[], idempotencyKey: string): Promise<ApplyAccepted>;
|
|
26
|
+
getAgent(organizationId: string, remoteId: string): Promise<RemoteAgent>;
|
|
27
|
+
createSession(organizationId: string, remoteId: string): Promise<{
|
|
28
|
+
readonly sessionId: string;
|
|
29
|
+
}>;
|
|
30
|
+
createRun(sessionId: string, message: string, idempotencyKey: string): Promise<{
|
|
31
|
+
readonly runId: string;
|
|
32
|
+
readonly status: string;
|
|
33
|
+
}>;
|
|
34
|
+
archiveAgent(organizationId: string, remoteId: string): Promise<void>;
|
|
35
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"potential-agents-api.js","sourceRoot":"","sources":["../../../src/application/ports/potential-agents-api.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { IdempotencyKeyGenerator } from './ports/idempotency-key-generator.js';
|
|
2
|
+
import type { LockRepository } from './ports/lock-repository.js';
|
|
3
|
+
import type { PotentialAgentsApi } from './ports/potential-agents-api.js';
|
|
4
|
+
/** Opens a session against the locked active revision and starts one run. */
|
|
5
|
+
export declare class RunAgent {
|
|
6
|
+
private readonly locks;
|
|
7
|
+
private readonly api;
|
|
8
|
+
private readonly keys;
|
|
9
|
+
constructor(locks: LockRepository, api: PotentialAgentsApi, keys: IdempotencyKeyGenerator);
|
|
10
|
+
execute(root: string, organizationId: string, message: string): Promise<{
|
|
11
|
+
readonly runId: string;
|
|
12
|
+
readonly status: string;
|
|
13
|
+
}>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { configurationError } from '../domain/errors.js';
|
|
2
|
+
/** Opens a session against the locked active revision and starts one run. */
|
|
3
|
+
export class RunAgent {
|
|
4
|
+
locks;
|
|
5
|
+
api;
|
|
6
|
+
keys;
|
|
7
|
+
constructor(locks, api, keys) {
|
|
8
|
+
this.locks = locks;
|
|
9
|
+
this.api = api;
|
|
10
|
+
this.keys = keys;
|
|
11
|
+
}
|
|
12
|
+
async execute(root, organizationId, message) {
|
|
13
|
+
const lock = await this.locks.read(root);
|
|
14
|
+
if (!lock)
|
|
15
|
+
throw configurationError('potential.lock is required before p-agents run.');
|
|
16
|
+
const session = await this.api.createSession(organizationId, lock.agent.remoteId);
|
|
17
|
+
return this.api.createRun(session.sessionId, message, this.keys.generate(organizationId, lock.agent.definitionSha256, 'run'));
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=run-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-agent.js","sourceRoot":"","sources":["../../src/application/run-agent.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,6EAA6E;AAC7E,MAAM,OAAO,QAAQ;IAEA;IACA;IACA;IAHnB,YACmB,KAAqB,EACrB,GAAuB,EACvB,IAA6B;QAF7B,UAAK,GAAL,KAAK,CAAgB;QACrB,QAAG,GAAH,GAAG,CAAoB;QACvB,SAAI,GAAJ,IAAI,CAAyB;IAC7C,CAAC;IAEG,KAAK,CAAC,OAAO,CAAC,IAAY,EAAE,cAAsB,EAAE,OAAe;QACxE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI;YAAE,MAAM,kBAAkB,CAAC,iDAAiD,CAAC,CAAC;QACvF,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC,cAAc,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAClF,OAAO,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,IAAI,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC,CAAC;IAChI,CAAC;CACF"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Bundle } from '../domain/bundle.js';
|
|
2
|
+
import type { BundleRepository } from './ports/bundle-repository.js';
|
|
3
|
+
/** Validates a local bundle without network access. */
|
|
4
|
+
export declare class ValidateBundle {
|
|
5
|
+
private readonly bundles;
|
|
6
|
+
constructor(bundles: BundleRepository);
|
|
7
|
+
execute(root: string): Promise<Bundle>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Validates a local bundle without network access. */
|
|
2
|
+
export class ValidateBundle {
|
|
3
|
+
bundles;
|
|
4
|
+
constructor(bundles) {
|
|
5
|
+
this.bundles = bundles;
|
|
6
|
+
}
|
|
7
|
+
async execute(root) {
|
|
8
|
+
return this.bundles.read(root);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=validate-bundle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-bundle.js","sourceRoot":"","sources":["../../src/application/validate-bundle.ts"],"names":[],"mappings":"AAGA,uDAAuD;AACvD,MAAM,OAAO,cAAc;IACW;IAApC,YAAoC,OAAyB;QAAzB,YAAO,GAAP,OAAO,CAAkB;IAAG,CAAC;IAE1D,KAAK,CAAC,OAAO,CAAC,IAAY;QAC/B,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;CACF"}
|
package/dist/cli.d.ts
ADDED
package/dist/cli.js
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { resolve } from 'node:path';
|
|
4
|
+
import { CliCompositionRoot } from './composition-root.js';
|
|
5
|
+
import { PotentialAgentsError } from './domain/errors.js';
|
|
6
|
+
const root = new CliCompositionRoot();
|
|
7
|
+
/** Builds the process-facing CLI while keeping workflow logic in application use cases. */
|
|
8
|
+
export const createProgram = () => {
|
|
9
|
+
const program = new Command();
|
|
10
|
+
program
|
|
11
|
+
.name('p-agents')
|
|
12
|
+
.description('Declarative GitOps CLI for Potential Agents')
|
|
13
|
+
.version('0.1.0')
|
|
14
|
+
.option('--api-url <url>', 'Potential Agents public API URL', process.env.POTENTIAL_AGENTS_API_URL)
|
|
15
|
+
.option('--organization <id>', 'Potential Agents organization ID', process.env.POTENTIAL_AGENTS_ORGANIZATION)
|
|
16
|
+
.option('--token <token>', 'short-lived Potential Agents access token', process.env.POTENTIAL_AGENTS_TOKEN)
|
|
17
|
+
.option('--json', 'print machine-readable JSON');
|
|
18
|
+
program.command('init [path]')
|
|
19
|
+
.option('--force', 'overwrite an existing potential.md')
|
|
20
|
+
.description('create a commented potential.md template')
|
|
21
|
+
.action(async (path, options) => {
|
|
22
|
+
const services = root.createOfflineServices();
|
|
23
|
+
const destination = await services.bundles.initialize(resolve(path ?? '.'), options.force ?? false);
|
|
24
|
+
output(program, { potential_md: destination }, `Created ${destination}`);
|
|
25
|
+
});
|
|
26
|
+
program.command('validate [path]')
|
|
27
|
+
.description('validate potential.md and local skills without network access')
|
|
28
|
+
.action(async (path) => {
|
|
29
|
+
const bundle = await root.createOfflineServices().validate.execute(resolve(path ?? '.'));
|
|
30
|
+
output(program, { id: bundle.definition.id, definition_sha256: bundle.definitionSha256, skills: bundle.skills.map((skill) => ({ path: skill.path, sha256: skill.sha256 })) }, `Valid: ${bundle.definition.id} (${bundle.definitionSha256})`);
|
|
31
|
+
});
|
|
32
|
+
program.command('plan [path]')
|
|
33
|
+
.description('show create, revision, or no-op after policy resolution')
|
|
34
|
+
.action(async (path) => {
|
|
35
|
+
const options = connectionOptions(program);
|
|
36
|
+
const services = root.createConnectedServices(options);
|
|
37
|
+
const planned = await services.planner.execute(resolve(path ?? '.'), requiredOrganization(options));
|
|
38
|
+
output(program, { change: planned.plan.change, reason: planned.plan.reason, definition_sha256: planned.bundle.definitionSha256 }, `${planned.plan.change}: ${planned.plan.reason}`);
|
|
39
|
+
});
|
|
40
|
+
program.command('apply [path]')
|
|
41
|
+
.option('--no-wait', 'return after the control plane accepts deployment')
|
|
42
|
+
.option('--wait-timeout-seconds <seconds>', 'maximum readiness wait', '300')
|
|
43
|
+
.description('create or revise an agent and write potential.lock')
|
|
44
|
+
.action(async (path, options) => {
|
|
45
|
+
const connection = connectionOptions(program);
|
|
46
|
+
const services = root.createConnectedServices(connection);
|
|
47
|
+
const timeoutSeconds = Number(options.waitTimeoutSeconds);
|
|
48
|
+
if (!Number.isInteger(timeoutSeconds) || timeoutSeconds < 1 || timeoutSeconds > 28_800)
|
|
49
|
+
throw new PotentialAgentsError('VALIDATION_ERROR', '--wait-timeout-seconds must be an integer from 1 through 28800.');
|
|
50
|
+
const agent = await services.apply.execute(resolve(path ?? '.'), requiredOrganization(connection), {
|
|
51
|
+
wait: options.wait !== false,
|
|
52
|
+
timeoutMs: timeoutSeconds * 1000,
|
|
53
|
+
pollIntervalMs: 1_000,
|
|
54
|
+
});
|
|
55
|
+
output(program, agent, `${agent.status}: ${agent.agentId} revision ${agent.activeRevision}`);
|
|
56
|
+
});
|
|
57
|
+
program.command('status [path]')
|
|
58
|
+
.description('show live status for the lockfile agent')
|
|
59
|
+
.action(async (path) => {
|
|
60
|
+
const connection = connectionOptions(program);
|
|
61
|
+
const services = root.createConnectedServices(connection);
|
|
62
|
+
const bundlePath = resolve(path ?? '.');
|
|
63
|
+
const lock = await services.locks.read(bundlePath);
|
|
64
|
+
if (!lock)
|
|
65
|
+
throw new PotentialAgentsError('LOCK_ERROR', 'potential.lock is required before p-agents status.');
|
|
66
|
+
const agent = await services.api.getAgent(requiredOrganization(connection), lock.agent.remoteId);
|
|
67
|
+
output(program, agent, `${agent.status}: ${agent.agentId} revision ${agent.activeRevision}`);
|
|
68
|
+
});
|
|
69
|
+
program.command('run <message>')
|
|
70
|
+
.option('--path <path>', 'bundle directory', '.')
|
|
71
|
+
.description('start one run against the locked active revision')
|
|
72
|
+
.action(async (message, options) => {
|
|
73
|
+
const connection = connectionOptions(program);
|
|
74
|
+
const services = root.createConnectedServices(connection);
|
|
75
|
+
const run = await services.run.execute(resolve(options.path), requiredOrganization(connection), message);
|
|
76
|
+
output(program, run, `${run.status}: ${run.runId}`);
|
|
77
|
+
});
|
|
78
|
+
program.command('archive [path]')
|
|
79
|
+
.option('--yes', 'confirm the archive operation')
|
|
80
|
+
.description('archive the remote agent in potential.lock')
|
|
81
|
+
.action(async (path, options) => {
|
|
82
|
+
if (!options.yes)
|
|
83
|
+
throw new PotentialAgentsError('CONFIRMATION_REQUIRED', 'Pass --yes to archive the remote agent.');
|
|
84
|
+
const connection = connectionOptions(program);
|
|
85
|
+
const services = root.createConnectedServices(connection);
|
|
86
|
+
const lock = await services.locks.read(resolve(path ?? '.'));
|
|
87
|
+
if (!lock)
|
|
88
|
+
throw new PotentialAgentsError('LOCK_ERROR', 'potential.lock is required before p-agents archive.');
|
|
89
|
+
await services.api.archiveAgent(requiredOrganization(connection), lock.agent.remoteId);
|
|
90
|
+
output(program, { agent_id: lock.agent.remoteId, status: 'archived' }, `archived: ${lock.agent.remoteId}`);
|
|
91
|
+
});
|
|
92
|
+
return program;
|
|
93
|
+
};
|
|
94
|
+
/** Reads connection inputs outside bundle content so Git stays free of credentials. */
|
|
95
|
+
const connectionOptions = (program) => program.opts();
|
|
96
|
+
const requiredOrganization = (options) => {
|
|
97
|
+
if (!options.organization)
|
|
98
|
+
throw new PotentialAgentsError('CONFIGURATION_ERROR', 'POTENTIAL_AGENTS_ORGANIZATION or --organization is required.');
|
|
99
|
+
return options.organization;
|
|
100
|
+
};
|
|
101
|
+
/** Renders either human output or a stable JSON object for CI. */
|
|
102
|
+
const output = (program, value, human) => {
|
|
103
|
+
if (program.opts().json)
|
|
104
|
+
console.log(JSON.stringify(value));
|
|
105
|
+
else
|
|
106
|
+
console.log(human);
|
|
107
|
+
};
|
|
108
|
+
const main = async () => {
|
|
109
|
+
try {
|
|
110
|
+
await createProgram().parseAsync(process.argv);
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
const message = error instanceof Error ? error.message : 'Unexpected error.';
|
|
114
|
+
const code = error instanceof PotentialAgentsError ? error.code : 'UNEXPECTED_ERROR';
|
|
115
|
+
console.error(`${code}: ${message}`);
|
|
116
|
+
process.exitCode = code === 'VALIDATION_ERROR' || code === 'CONFIGURATION_ERROR' || code === 'CONFIRMATION_REQUIRED' ? 2 : 1;
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
void main();
|
|
120
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAS1D,MAAM,IAAI,GAAG,IAAI,kBAAkB,EAAE,CAAC;AAEtC,2FAA2F;AAC3F,MAAM,CAAC,MAAM,aAAa,GAAG,GAAY,EAAE;IACzC,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAC9B,OAAO;SACJ,IAAI,CAAC,UAAU,CAAC;SAChB,WAAW,CAAC,6CAA6C,CAAC;SAC1D,OAAO,CAAC,OAAO,CAAC;SAChB,MAAM,CAAC,iBAAiB,EAAE,iCAAiC,EAAE,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC;SAClG,MAAM,CAAC,qBAAqB,EAAE,kCAAkC,EAAE,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC;SAC5G,MAAM,CAAC,iBAAiB,EAAE,2CAA2C,EAAE,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC;SAC1G,MAAM,CAAC,QAAQ,EAAE,6BAA6B,CAAC,CAAC;IAEnD,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC;SAC3B,MAAM,CAAC,SAAS,EAAE,oCAAoC,CAAC;SACvD,WAAW,CAAC,0CAA0C,CAAC;SACvD,MAAM,CAAC,KAAK,EAAE,IAAwB,EAAE,OAAqC,EAAE,EAAE;QAChF,MAAM,QAAQ,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC9C,MAAM,WAAW,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC;QACpG,MAAM,CAAC,OAAO,EAAE,EAAE,YAAY,EAAE,WAAW,EAAE,EAAE,WAAW,WAAW,EAAE,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEL,OAAO,CAAC,OAAO,CAAC,iBAAiB,CAAC;SAC/B,WAAW,CAAC,+DAA+D,CAAC;SAC5E,MAAM,CAAC,KAAK,EAAE,IAAwB,EAAE,EAAE;QACzC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC;QACzF,MAAM,CAAC,OAAO,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,UAAU,CAAC,EAAE,EAAE,iBAAiB,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,UAAU,MAAM,CAAC,UAAU,CAAC,EAAE,KAAK,MAAM,CAAC,gBAAgB,GAAG,CAAC,CAAC;IAC/O,CAAC,CAAC,CAAC;IAEL,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC;SAC3B,WAAW,CAAC,yDAAyD,CAAC;SACtE,MAAM,CAAC,KAAK,EAAE,IAAwB,EAAE,EAAE;QACzC,MAAM,OAAO,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;QACvD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC;QACpG,MAAM,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,iBAAiB,EAAE,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACtL,CAAC,CAAC,CAAC;IAEL,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC;SAC5B,MAAM,CAAC,WAAW,EAAE,mDAAmD,CAAC;SACxE,MAAM,CAAC,kCAAkC,EAAE,wBAAwB,EAAE,KAAK,CAAC;SAC3E,WAAW,CAAC,oDAAoD,CAAC;SACjE,MAAM,CAAC,KAAK,EAAE,IAAwB,EAAE,OAAyE,EAAE,EAAE;QACpH,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;QAC1D,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;QAC1D,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,cAAc,GAAG,CAAC,IAAI,cAAc,GAAG,MAAM;YAAE,MAAM,IAAI,oBAAoB,CAAC,kBAAkB,EAAE,iEAAiE,CAAC,CAAC;QAC9M,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE,oBAAoB,CAAC,UAAU,CAAC,EAAE;YACjG,IAAI,EAAE,OAAO,CAAC,IAAI,KAAK,KAAK;YAC5B,SAAS,EAAE,cAAc,GAAG,IAAI;YAChC,cAAc,EAAE,KAAK;SACtB,CAAC,CAAC;QACH,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,OAAO,aAAa,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC;IAC/F,CAAC,CAAC,CAAC;IAEL,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC;SAC7B,WAAW,CAAC,yCAAyC,CAAC;SACtD,MAAM,CAAC,KAAK,EAAE,IAAwB,EAAE,EAAE;QACzC,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;QAC1D,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC;QACxC,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,oBAAoB,CAAC,YAAY,EAAE,oDAAoD,CAAC,CAAC;QAC9G,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,oBAAoB,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACjG,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,OAAO,aAAa,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC;IAC/F,CAAC,CAAC,CAAC;IAEL,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC;SAC7B,MAAM,CAAC,eAAe,EAAE,kBAAkB,EAAE,GAAG,CAAC;SAChD,WAAW,CAAC,kDAAkD,CAAC;SAC/D,MAAM,CAAC,KAAK,EAAE,OAAe,EAAE,OAAkC,EAAE,EAAE;QACpE,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;QAC1D,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,oBAAoB,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC,CAAC;QACzG,MAAM,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEL,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAC;SAC9B,MAAM,CAAC,OAAO,EAAE,+BAA+B,CAAC;SAChD,WAAW,CAAC,4CAA4C,CAAC;SACzD,MAAM,CAAC,KAAK,EAAE,IAAwB,EAAE,OAAmC,EAAE,EAAE;QAC9E,IAAI,CAAC,OAAO,CAAC,GAAG;YAAE,MAAM,IAAI,oBAAoB,CAAC,uBAAuB,EAAE,yCAAyC,CAAC,CAAC;QACrH,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;QAC1D,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC;QAC7D,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,oBAAoB,CAAC,YAAY,EAAE,qDAAqD,CAAC,CAAC;QAC/G,MAAM,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC,oBAAoB,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACvF,MAAM,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,aAAa,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC7G,CAAC,CAAC,CAAC;IACL,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF,uFAAuF;AACvF,MAAM,iBAAiB,GAAG,CAAC,OAAgB,EAAiB,EAAE,CAAC,OAAO,CAAC,IAAI,EAAiB,CAAC;AAE7F,MAAM,oBAAoB,GAAG,CAAC,OAAsB,EAAU,EAAE;IAC9D,IAAI,CAAC,OAAO,CAAC,YAAY;QAAE,MAAM,IAAI,oBAAoB,CAAC,qBAAqB,EAAE,8DAA8D,CAAC,CAAC;IACjJ,OAAO,OAAO,CAAC,YAAY,CAAC;AAC9B,CAAC,CAAC;AAEF,kEAAkE;AAClE,MAAM,MAAM,GAAG,CAAC,OAAgB,EAAE,KAAc,EAAE,KAAa,EAAQ,EAAE;IACvE,IAAI,OAAO,CAAC,IAAI,EAAiB,CAAC,IAAI;QAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;;QACtE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC1B,CAAC,CAAC;AAEF,MAAM,IAAI,GAAG,KAAK,IAAmB,EAAE;IACrC,IAAI,CAAC;QACH,MAAM,aAAa,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC;QAC7E,MAAM,IAAI,GAAG,KAAK,YAAY,oBAAoB,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC;QACrF,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,KAAK,OAAO,EAAE,CAAC,CAAC;QACrC,OAAO,CAAC,QAAQ,GAAG,IAAI,KAAK,kBAAkB,IAAI,IAAI,KAAK,qBAAqB,IAAI,IAAI,KAAK,uBAAuB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/H,CAAC;AACH,CAAC,CAAC;AAEF,KAAK,IAAI,EAAE,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { ApplyBundle } from './application/apply-bundle.js';
|
|
2
|
+
import { PlanBundle } from './application/plan-bundle.js';
|
|
3
|
+
import { RunAgent } from './application/run-agent.js';
|
|
4
|
+
import { ValidateBundle } from './application/validate-bundle.js';
|
|
5
|
+
import { FilesystemBundleRepository } from './adapters/outbound/filesystem/bundle-filesystem-repository.js';
|
|
6
|
+
import { YamlLockRepository } from './adapters/outbound/filesystem/yaml-lock-repository.js';
|
|
7
|
+
import { HttpPotentialAgentsApi } from './adapters/outbound/http/http-potential-agents-api.js';
|
|
8
|
+
export interface RuntimeConfiguration {
|
|
9
|
+
readonly apiUrl?: string;
|
|
10
|
+
readonly organization?: string;
|
|
11
|
+
readonly token?: string;
|
|
12
|
+
}
|
|
13
|
+
/** Composition root: the sole place that binds hexagonal ports to concrete adapters. */
|
|
14
|
+
export declare class CliCompositionRoot {
|
|
15
|
+
private readonly bundles;
|
|
16
|
+
private readonly locks;
|
|
17
|
+
private readonly keys;
|
|
18
|
+
createOfflineServices(): {
|
|
19
|
+
readonly validate: ValidateBundle;
|
|
20
|
+
readonly bundles: FilesystemBundleRepository;
|
|
21
|
+
};
|
|
22
|
+
createConnectedServices(configuration: RuntimeConfiguration): {
|
|
23
|
+
readonly planner: PlanBundle;
|
|
24
|
+
readonly apply: ApplyBundle;
|
|
25
|
+
readonly run: RunAgent;
|
|
26
|
+
readonly locks: YamlLockRepository;
|
|
27
|
+
readonly api: HttpPotentialAgentsApi;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ApplyBundle } from './application/apply-bundle.js';
|
|
2
|
+
import { PlanBundle } from './application/plan-bundle.js';
|
|
3
|
+
import { RunAgent } from './application/run-agent.js';
|
|
4
|
+
import { ValidateBundle } from './application/validate-bundle.js';
|
|
5
|
+
import { FilesystemBundleRepository } from './adapters/outbound/filesystem/bundle-filesystem-repository.js';
|
|
6
|
+
import { YamlLockRepository } from './adapters/outbound/filesystem/yaml-lock-repository.js';
|
|
7
|
+
import { HttpPotentialAgentsApi } from './adapters/outbound/http/http-potential-agents-api.js';
|
|
8
|
+
import { Sha256IdempotencyKeyGenerator } from './adapters/outbound/runtime/sha256-idempotency-key-generator.js';
|
|
9
|
+
/** Composition root: the sole place that binds hexagonal ports to concrete adapters. */
|
|
10
|
+
export class CliCompositionRoot {
|
|
11
|
+
bundles = new FilesystemBundleRepository();
|
|
12
|
+
locks = new YamlLockRepository();
|
|
13
|
+
keys = new Sha256IdempotencyKeyGenerator();
|
|
14
|
+
createOfflineServices() {
|
|
15
|
+
return { validate: new ValidateBundle(this.bundles), bundles: this.bundles };
|
|
16
|
+
}
|
|
17
|
+
createConnectedServices(configuration) {
|
|
18
|
+
if (!configuration.apiUrl)
|
|
19
|
+
throw new Error('POTENTIAL_AGENTS_API_URL or --api-url is required.');
|
|
20
|
+
if (!configuration.organization)
|
|
21
|
+
throw new Error('POTENTIAL_AGENTS_ORGANIZATION or --organization is required.');
|
|
22
|
+
if (!configuration.token)
|
|
23
|
+
throw new Error('POTENTIAL_AGENTS_TOKEN or --token is required.');
|
|
24
|
+
const api = new HttpPotentialAgentsApi({ baseUrl: configuration.apiUrl, accessToken: configuration.token });
|
|
25
|
+
const planner = new PlanBundle(this.bundles, this.locks, api);
|
|
26
|
+
return {
|
|
27
|
+
planner,
|
|
28
|
+
apply: new ApplyBundle(this.bundles, this.locks, planner, api, this.keys),
|
|
29
|
+
run: new RunAgent(this.locks, api, this.keys),
|
|
30
|
+
locks: this.locks,
|
|
31
|
+
api,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=composition-root.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composition-root.js","sourceRoot":"","sources":["../src/composition-root.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,0BAA0B,EAAE,MAAM,gEAAgE,CAAC;AAC5G,OAAO,EAAE,kBAAkB,EAAE,MAAM,wDAAwD,CAAC;AAC5F,OAAO,EAAE,sBAAsB,EAAE,MAAM,uDAAuD,CAAC;AAC/F,OAAO,EAAE,6BAA6B,EAAE,MAAM,iEAAiE,CAAC;AAQhH,wFAAwF;AACxF,MAAM,OAAO,kBAAkB;IACZ,OAAO,GAAG,IAAI,0BAA0B,EAAE,CAAC;IAC3C,KAAK,GAAG,IAAI,kBAAkB,EAAE,CAAC;IACjC,IAAI,GAAG,IAAI,6BAA6B,EAAE,CAAC;IAErD,qBAAqB;QAC1B,OAAO,EAAE,QAAQ,EAAE,IAAI,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;IAC/E,CAAC;IAEM,uBAAuB,CAAC,aAAmC;QAOhE,IAAI,CAAC,aAAa,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;QACjG,IAAI,CAAC,aAAa,CAAC,YAAY;YAAE,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;QACjH,IAAI,CAAC,aAAa,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QAC5F,MAAM,GAAG,GAAG,IAAI,sBAAsB,CAAC,EAAE,OAAO,EAAE,aAAa,CAAC,MAAM,EAAE,WAAW,EAAE,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC;QAC5G,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC9D,OAAO;YACL,OAAO;YACP,KAAK,EAAE,IAAI,WAAW,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC;YACzE,GAAG,EAAE,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC;YAC7C,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,GAAG;SACJ,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export declare const ALLOWED_TOOLS: readonly ["Read", "Write", "Edit", "Bash", "Glob", "Grep"];
|
|
2
|
+
export type Tool = (typeof ALLOWED_TOOLS)[number];
|
|
3
|
+
export interface Limits {
|
|
4
|
+
readonly durationSeconds?: number;
|
|
5
|
+
readonly maxBudgetUsd?: number;
|
|
6
|
+
}
|
|
7
|
+
export interface AgentDefinitionInput {
|
|
8
|
+
readonly apiVersion: string;
|
|
9
|
+
readonly id: string;
|
|
10
|
+
readonly name: string;
|
|
11
|
+
readonly description?: string;
|
|
12
|
+
readonly engine: string;
|
|
13
|
+
readonly model: string;
|
|
14
|
+
readonly tools?: readonly Tool[];
|
|
15
|
+
readonly browser?: boolean;
|
|
16
|
+
readonly skillPaths?: readonly string[];
|
|
17
|
+
readonly limits?: Limits;
|
|
18
|
+
readonly instructions: string;
|
|
19
|
+
}
|
|
20
|
+
/** Immutable, validated user intent for one Potential Agent revision. */
|
|
21
|
+
export declare class AgentDefinition {
|
|
22
|
+
readonly apiVersion: 'potentialagents/v1alpha1';
|
|
23
|
+
readonly id: string;
|
|
24
|
+
readonly name: string;
|
|
25
|
+
readonly description: string | undefined;
|
|
26
|
+
readonly engine: 'claude';
|
|
27
|
+
readonly model: string;
|
|
28
|
+
readonly tools: readonly Tool[];
|
|
29
|
+
readonly browser: boolean;
|
|
30
|
+
readonly skillPaths: readonly string[];
|
|
31
|
+
readonly limits: Limits;
|
|
32
|
+
readonly instructions: string;
|
|
33
|
+
private constructor();
|
|
34
|
+
/** Validates raw parsed content and constructs one immutable definition. */
|
|
35
|
+
static create(input: AgentDefinitionInput): AgentDefinition;
|
|
36
|
+
}
|
|
37
|
+
/** Returns deterministic JSON by sorting object keys recursively. */
|
|
38
|
+
export declare const stableJson: (value: unknown) => string;
|
|
39
|
+
/** Calculates the version-independent SHA-256 representation of an agent intent. */
|
|
40
|
+
export declare const sha256: (value: unknown) => string;
|