@potential-agents/cli 0.0.0-stage → 0.1.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.
Files changed (57) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +83 -2
  3. package/dist/adapters/outbound/filesystem/bundle-filesystem-repository.d.ts +20 -0
  4. package/dist/adapters/outbound/filesystem/bundle-filesystem-repository.js +181 -0
  5. package/dist/adapters/outbound/filesystem/bundle-filesystem-repository.js.map +1 -0
  6. package/dist/adapters/outbound/filesystem/yaml-lock-repository.d.ts +7 -0
  7. package/dist/adapters/outbound/filesystem/yaml-lock-repository.js +64 -0
  8. package/dist/adapters/outbound/filesystem/yaml-lock-repository.js.map +1 -0
  9. package/dist/adapters/outbound/http/http-potential-agents-api.d.ts +36 -0
  10. package/dist/adapters/outbound/http/http-potential-agents-api.js +150 -0
  11. package/dist/adapters/outbound/http/http-potential-agents-api.js.map +1 -0
  12. package/dist/adapters/outbound/runtime/sha256-idempotency-key-generator.d.ts +5 -0
  13. package/dist/adapters/outbound/runtime/sha256-idempotency-key-generator.js +8 -0
  14. package/dist/adapters/outbound/runtime/sha256-idempotency-key-generator.js.map +1 -0
  15. package/dist/application/apply-bundle.d.ts +22 -0
  16. package/dist/application/apply-bundle.js +78 -0
  17. package/dist/application/apply-bundle.js.map +1 -0
  18. package/dist/application/plan-bundle.d.ts +18 -0
  19. package/dist/application/plan-bundle.js +22 -0
  20. package/dist/application/plan-bundle.js.map +1 -0
  21. package/dist/application/ports/bundle-repository.d.ts +6 -0
  22. package/dist/application/ports/bundle-repository.js +2 -0
  23. package/dist/application/ports/bundle-repository.js.map +1 -0
  24. package/dist/application/ports/idempotency-key-generator.d.ts +4 -0
  25. package/dist/application/ports/idempotency-key-generator.js +2 -0
  26. package/dist/application/ports/idempotency-key-generator.js.map +1 -0
  27. package/dist/application/ports/lock-repository.d.ts +6 -0
  28. package/dist/application/ports/lock-repository.js +2 -0
  29. package/dist/application/ports/lock-repository.js.map +1 -0
  30. package/dist/application/ports/potential-agents-api.d.ts +35 -0
  31. package/dist/application/ports/potential-agents-api.js +2 -0
  32. package/dist/application/ports/potential-agents-api.js.map +1 -0
  33. package/dist/application/run-agent.d.ts +14 -0
  34. package/dist/application/run-agent.js +20 -0
  35. package/dist/application/run-agent.js.map +1 -0
  36. package/dist/application/validate-bundle.d.ts +8 -0
  37. package/dist/application/validate-bundle.js +11 -0
  38. package/dist/application/validate-bundle.js.map +1 -0
  39. package/dist/cli.d.ts +4 -0
  40. package/dist/cli.js +120 -0
  41. package/dist/cli.js.map +1 -0
  42. package/dist/composition-root.d.ts +29 -0
  43. package/dist/composition-root.js +35 -0
  44. package/dist/composition-root.js.map +1 -0
  45. package/dist/domain/agent-definition.d.ts +40 -0
  46. package/dist/domain/agent-definition.js +94 -0
  47. package/dist/domain/agent-definition.js.map +1 -0
  48. package/dist/domain/bundle.d.ts +16 -0
  49. package/dist/domain/bundle.js +29 -0
  50. package/dist/domain/bundle.js.map +1 -0
  51. package/dist/domain/errors.d.ts +10 -0
  52. package/dist/domain/errors.js +16 -0
  53. package/dist/domain/errors.js.map +1 -0
  54. package/dist/domain/lock.d.ts +18 -0
  55. package/dist/domain/lock.js +2 -0
  56. package/dist/domain/lock.js.map +1 -0
  57. package/package.json +45 -4
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Potential Agents contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,84 @@
1
- # Temporary Holding Version
1
+ # Potential Agents CLI
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ `p-agents` turns a reviewed `potential.md` into a managed Potential Agent revision. The bundle
4
+ contains only logical agent intent; runtime profile IDs, cloud infrastructure, secrets, images,
5
+ and IAM never enter the repository.
6
+
7
+ ## Install
8
+
9
+ After publication to npm:
10
+
11
+ ```bash
12
+ npm install -g @potential-agents/cli
13
+ p-agents validate
14
+ ```
15
+
16
+ CI should pin the version it executes:
17
+
18
+ ```bash
19
+ npx --yes @potential-agents/cli@0.1.0 validate
20
+ ```
21
+
22
+ ## Bundle
23
+
24
+ ```md
25
+ ---
26
+ apiVersion: potentialagents/v1alpha1
27
+ id: research-agent
28
+ name: Research Agent
29
+ engine: claude
30
+ model: claude-sonnet-4-6
31
+ tools: [Read, Glob, Grep]
32
+ browser: false
33
+ skills: []
34
+ ---
35
+
36
+ Use evidence and identify uncertainty.
37
+ ```
38
+
39
+ Run `p-agents validate` without credentials. Connected commands require configuration outside
40
+ the bundle:
41
+
42
+ ```bash
43
+ export POTENTIAL_AGENTS_API_URL=https://api.example.com
44
+ export POTENTIAL_AGENTS_ORGANIZATION=org_example
45
+ export POTENTIAL_AGENTS_TOKEN=short_lived_token
46
+
47
+ p-agents plan
48
+ p-agents apply
49
+ ```
50
+
51
+ `apply` writes `potential.lock`. Commit that generated identity with the reviewed source bundle.
52
+
53
+ ## Architecture
54
+
55
+ The implementation is intentionally hexagonal:
56
+
57
+ - `src/domain`: immutable values, invariants and deterministic hashes.
58
+ - `src/application`: SOLID use cases and small ports.
59
+ - `src/adapters`: Commander/terminal inbound adapter plus filesystem, YAML, HTTPS and runtime
60
+ outbound adapters.
61
+ - `src/composition-root.ts`: the only place concrete adapters are injected.
62
+
63
+ No application or domain code depends on Commander, Node filesystem APIs, `fetch`, environment
64
+ variables, or cloud SDKs.
65
+
66
+ ## Development
67
+
68
+ ```bash
69
+ npm ci
70
+ npm run typecheck
71
+ npm run build
72
+ npm test
73
+ npm pack --dry-run
74
+ ```
75
+
76
+ The black-box test starts a disposable control-plane fixture and executes the compiled binary. It
77
+ verifies create, readiness, generated lockfile, no-op and run without a real cloud account.
78
+
79
+ ## Releases
80
+
81
+ Tags in the form `v*` invoke `.github/workflows/publish.yml`. Configure npm Trusted Publishing
82
+ for `shinsekai-dev/potential-agents-cli` and `publish.yml`; the workflow uses GitHub OIDC and has
83
+ no long-lived npm publish token. The first package publication requires the npm scope to have
84
+ been claimed by a maintainer.
@@ -0,0 +1,20 @@
1
+ import type { BundleRepository } from '../../../application/ports/bundle-repository.js';
2
+ import { Bundle } from '../../../domain/bundle.js';
3
+ /** Filesystem adapter that parses potential.md and produces deterministic skill hashes. */
4
+ export declare class FilesystemBundleRepository implements BundleRepository {
5
+ read(root: string): Promise<Bundle>;
6
+ initialize(root: string, overwrite: boolean): Promise<string>;
7
+ /** Parses YAML front matter and rejects ambiguous or malformed Markdown documents. */
8
+ private _parseMarkdown;
9
+ /** Maps a closed YAML contract to a domain definition. */
10
+ private _toDefinition;
11
+ /** Resolves one declared skill directory without allowing an escape from the bundle root. */
12
+ private _readSkill;
13
+ /** Lists UTF-8 skill support files in a stable recursive order and rejects symlinks. */
14
+ private _listFiles;
15
+ private _readUtf8;
16
+ private _string;
17
+ private _number;
18
+ private _boolean;
19
+ private _stringArray;
20
+ }
@@ -0,0 +1,181 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { lstat, mkdir, readdir, readFile, stat, writeFile } from 'node:fs/promises';
3
+ import { basename, relative, resolve, sep } from 'node:path';
4
+ import { parseDocument } from 'yaml';
5
+ import { AgentDefinition } from '../../../domain/agent-definition.js';
6
+ import { Bundle } from '../../../domain/bundle.js';
7
+ import { PotentialAgentsError, validationError } from '../../../domain/errors.js';
8
+ const TEMPLATE = `---
9
+ apiVersion: potentialagents/v1alpha1
10
+ id: my-agent
11
+ name: My Agent
12
+ description: A managed Potential Agent.
13
+ engine: claude
14
+ model: claude-sonnet-4-6
15
+ tools: []
16
+ browser: false
17
+ skills: []
18
+ # limits:
19
+ # duration_seconds: 300
20
+ # max_budget_usd: 0.50
21
+ ---
22
+
23
+ Describe the agent's system instructions here.
24
+ `;
25
+ /** Filesystem adapter that parses potential.md and produces deterministic skill hashes. */
26
+ export class FilesystemBundleRepository {
27
+ async read(root) {
28
+ const resolvedRoot = resolve(root);
29
+ const sourcePath = resolve(resolvedRoot, 'potential.md');
30
+ const source = await this._readUtf8(sourcePath, 'potential.md');
31
+ const { attributes, instructions } = this._parseMarkdown(source);
32
+ const definition = this._toDefinition(attributes, instructions);
33
+ const skills = await Promise.all(definition.skillPaths.map((skillPath) => this._readSkill(resolvedRoot, skillPath)));
34
+ const names = new Set();
35
+ for (const skill of skills) {
36
+ if (names.has(skill.name))
37
+ throw validationError(`Duplicate skill name "${skill.name}".`);
38
+ names.add(skill.name);
39
+ }
40
+ return new Bundle(resolvedRoot, definition, skills.sort((left, right) => left.path.localeCompare(right.path)));
41
+ }
42
+ async initialize(root, overwrite) {
43
+ const destination = resolve(root, 'potential.md');
44
+ await mkdir(resolve(root), { recursive: true });
45
+ try {
46
+ await stat(destination);
47
+ if (!overwrite)
48
+ throw new PotentialAgentsError('FILE_EXISTS', 'potential.md already exists; use --force to overwrite it.');
49
+ }
50
+ catch (error) {
51
+ if (!(error instanceof Error) || !('code' in error) || error.code !== 'ENOENT')
52
+ throw error;
53
+ }
54
+ await writeFile(destination, TEMPLATE, { encoding: 'utf8', flag: 'w' });
55
+ return destination;
56
+ }
57
+ /** Parses YAML front matter and rejects ambiguous or malformed Markdown documents. */
58
+ _parseMarkdown(source) {
59
+ const match = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/u.exec(source);
60
+ if (!match)
61
+ throw validationError('potential.md must start with YAML front matter delimited by --- lines.');
62
+ const yaml = parseDocument(match[1] ?? '');
63
+ if (yaml.errors.length > 0)
64
+ throw validationError(`Invalid YAML front matter: ${yaml.errors[0]?.message ?? 'unknown error'}`);
65
+ const content = yaml.toJS();
66
+ if (content === null || Array.isArray(content) || typeof content !== 'object')
67
+ throw validationError('YAML front matter must be an object.');
68
+ return { attributes: content, instructions: match[2] ?? '' };
69
+ }
70
+ /** Maps a closed YAML contract to a domain definition. */
71
+ _toDefinition(attributes, instructions) {
72
+ const allowed = new Set(['apiVersion', 'id', 'name', 'description', 'engine', 'model', 'tools', 'browser', 'skills', 'limits']);
73
+ for (const key of Object.keys(attributes)) {
74
+ if (!allowed.has(key))
75
+ throw validationError(`Unknown field "${key}" in potential.md.`);
76
+ }
77
+ const limitsValue = attributes.limits;
78
+ if (limitsValue !== undefined && (limitsValue === null || Array.isArray(limitsValue) || typeof limitsValue !== 'object')) {
79
+ throw validationError('limits must be an object.');
80
+ }
81
+ const limitsRecord = (limitsValue ?? {});
82
+ for (const key of Object.keys(limitsRecord)) {
83
+ if (!['duration_seconds', 'max_budget_usd'].includes(key))
84
+ throw validationError(`Unknown limits field "${key}".`);
85
+ }
86
+ const tools = this._stringArray(attributes.tools, 'tools');
87
+ const skills = this._stringArray(attributes.skills, 'skills');
88
+ const limits = {
89
+ ...(limitsRecord.duration_seconds === undefined ? {} : { durationSeconds: this._number(limitsRecord.duration_seconds, 'limits.duration_seconds') }),
90
+ ...(limitsRecord.max_budget_usd === undefined ? {} : { maxBudgetUsd: this._number(limitsRecord.max_budget_usd, 'limits.max_budget_usd') }),
91
+ };
92
+ return AgentDefinition.create({
93
+ apiVersion: this._string(attributes.apiVersion, 'apiVersion'),
94
+ id: this._string(attributes.id, 'id'),
95
+ name: this._string(attributes.name, 'name'),
96
+ ...(attributes.description === undefined ? {} : { description: this._string(attributes.description, 'description') }),
97
+ engine: this._string(attributes.engine, 'engine'),
98
+ model: this._string(attributes.model, 'model'),
99
+ tools,
100
+ browser: attributes.browser === undefined ? false : this._boolean(attributes.browser, 'browser'),
101
+ skillPaths: skills,
102
+ limits,
103
+ instructions,
104
+ });
105
+ }
106
+ /** Resolves one declared skill directory without allowing an escape from the bundle root. */
107
+ async _readSkill(root, declaredPath) {
108
+ if (!declaredPath.trim())
109
+ throw validationError('Skill paths must be non-blank.');
110
+ const absolute = resolve(root, declaredPath);
111
+ const relativePath = relative(root, absolute);
112
+ if (!relativePath || relativePath === '..' || relativePath.startsWith(`..${sep}`) || relativePath.split(sep).includes('..')) {
113
+ throw validationError(`Skill path "${declaredPath}" escapes the bundle root.`);
114
+ }
115
+ const directory = await lstat(absolute);
116
+ if (directory.isSymbolicLink())
117
+ throw validationError(`Skill path "${declaredPath}" may not be a symlink.`);
118
+ if (!directory.isDirectory())
119
+ throw validationError(`Skill path "${declaredPath}" must be a directory.`);
120
+ await stat(resolve(absolute, 'SKILL.md'));
121
+ const files = await this._listFiles(absolute, root);
122
+ const hash = createHash('sha256');
123
+ for (const file of files) {
124
+ hash.update(relative(root, file).replaceAll('\\', '/'));
125
+ hash.update('\0');
126
+ hash.update(await readFile(file));
127
+ hash.update('\0');
128
+ }
129
+ return { path: `./${relativePath.replaceAll('\\', '/')}`, name: basename(absolute), sha256: `sha256:${hash.digest('hex')}`, sourceDirectory: absolute };
130
+ }
131
+ /** Lists UTF-8 skill support files in a stable recursive order and rejects symlinks. */
132
+ async _listFiles(directory, root) {
133
+ const entries = await readdir(directory, { withFileTypes: true });
134
+ const files = [];
135
+ for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {
136
+ const absolute = resolve(directory, entry.name);
137
+ if (entry.isSymbolicLink())
138
+ throw validationError(`Skills may not contain symlinks: ${relative(root, absolute)}.`);
139
+ if (entry.isDirectory())
140
+ files.push(...await this._listFiles(absolute, root));
141
+ else if (entry.isFile())
142
+ files.push(absolute);
143
+ else
144
+ throw validationError(`Unsupported skill entry: ${relative(root, absolute)}.`);
145
+ }
146
+ return files;
147
+ }
148
+ async _readUtf8(path, label) {
149
+ try {
150
+ return await readFile(path, 'utf8');
151
+ }
152
+ catch (error) {
153
+ if (error instanceof Error && 'code' in error && error.code === 'ENOENT')
154
+ throw validationError(`${label} is required.`);
155
+ throw error;
156
+ }
157
+ }
158
+ _string(value, field) {
159
+ if (typeof value !== 'string')
160
+ throw validationError(`${field} must be a string.`);
161
+ return value;
162
+ }
163
+ _number(value, field) {
164
+ if (typeof value !== 'number')
165
+ throw validationError(`${field} must be a number.`);
166
+ return value;
167
+ }
168
+ _boolean(value, field) {
169
+ if (typeof value !== 'boolean')
170
+ throw validationError(`${field} must be a boolean.`);
171
+ return value;
172
+ }
173
+ _stringArray(value, field) {
174
+ if (value === undefined)
175
+ return [];
176
+ if (!Array.isArray(value) || value.some((item) => typeof item !== 'string'))
177
+ throw validationError(`${field} must be a list of strings.`);
178
+ return [...value];
179
+ }
180
+ }
181
+ //# sourceMappingURL=bundle-filesystem-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle-filesystem-repository.js","sourceRoot":"","sources":["../../../../src/adapters/outbound/filesystem/bundle-filesystem-repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { LockRepository } from '../../../application/ports/lock-repository.js';
2
+ import type { PotentialLock } from '../../../domain/lock.js';
3
+ /** Reads and atomically writes the generated potential.lock document. */
4
+ export declare class YamlLockRepository implements LockRepository {
5
+ read(root: string): Promise<PotentialLock | undefined>;
6
+ write(root: string, lock: PotentialLock): Promise<void>;
7
+ }
@@ -0,0 +1,64 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { readFile, rename, writeFile } from 'node:fs/promises';
3
+ import { resolve } from 'node:path';
4
+ import { parse, stringify } from 'yaml';
5
+ import { PotentialAgentsError } from '../../../domain/errors.js';
6
+ /** Reads and atomically writes the generated potential.lock document. */
7
+ export class YamlLockRepository {
8
+ async read(root) {
9
+ const path = resolve(root, 'potential.lock');
10
+ try {
11
+ const parsed = parse(await readFile(path, 'utf8'));
12
+ const agent = parsed.agent;
13
+ if (parsed.format !== 'potentialagents/lock/v1' || !agent || typeof agent.remote_id !== 'string' || typeof agent.local_id !== 'string' || typeof agent.active_revision !== 'string' || typeof agent.deployment_id !== 'string' || typeof agent.definition_sha256 !== 'string' || typeof agent.status !== 'string') {
14
+ throw new PotentialAgentsError('LOCK_ERROR', 'potential.lock has an unsupported or incomplete format.');
15
+ }
16
+ const skills = Object.fromEntries(Object.entries(parsed.skills ?? {}).map(([pathKey, value]) => {
17
+ if (typeof value.path !== 'string' || typeof value.skill_id !== 'string' || typeof value.revision !== 'string' || typeof value.sha256 !== 'string') {
18
+ throw new PotentialAgentsError('LOCK_ERROR', `potential.lock skill ${pathKey} is incomplete.`);
19
+ }
20
+ return [pathKey, { path: value.path, skillId: value.skill_id, revision: value.revision, sha256: value.sha256 }];
21
+ }));
22
+ return {
23
+ format: 'potentialagents/lock/v1',
24
+ agent: {
25
+ localId: agent.local_id,
26
+ remoteId: agent.remote_id,
27
+ activeRevision: agent.active_revision,
28
+ deploymentId: agent.deployment_id,
29
+ definitionSha256: agent.definition_sha256,
30
+ status: agent.status,
31
+ },
32
+ skills,
33
+ };
34
+ }
35
+ catch (error) {
36
+ if (error instanceof Error && 'code' in error && error.code === 'ENOENT')
37
+ return undefined;
38
+ throw error;
39
+ }
40
+ }
41
+ async write(root, lock) {
42
+ const destination = resolve(root, 'potential.lock');
43
+ const temporary = resolve(root, `.potential.lock.${randomUUID()}.tmp`);
44
+ await writeFile(temporary, stringify({
45
+ format: lock.format,
46
+ agent: {
47
+ local_id: lock.agent.localId,
48
+ remote_id: lock.agent.remoteId,
49
+ active_revision: lock.agent.activeRevision,
50
+ deployment_id: lock.agent.deploymentId,
51
+ definition_sha256: lock.agent.definitionSha256,
52
+ status: lock.agent.status,
53
+ },
54
+ skills: Object.fromEntries(Object.entries(lock.skills).map(([path, skill]) => [path, {
55
+ path: skill.path,
56
+ skill_id: skill.skillId,
57
+ revision: skill.revision,
58
+ sha256: skill.sha256,
59
+ }])),
60
+ }), 'utf8');
61
+ await rename(temporary, destination);
62
+ }
63
+ }
64
+ //# sourceMappingURL=yaml-lock-repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yaml-lock-repository.js","sourceRoot":"","sources":["../../../../src/adapters/outbound/filesystem/yaml-lock-repository.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import type { PotentialAgentsApi, ApiSkillRevision, ApplyAccepted, PlanResult, RemoteAgent } from '../../../application/ports/potential-agents-api.js';
2
+ import type { Bundle, SkillSource } from '../../../domain/bundle.js';
3
+ interface HttpApiOptions {
4
+ readonly baseUrl: string;
5
+ readonly accessToken?: string;
6
+ }
7
+ /** HTTPS adapter for the public Potential Agents control-plane contract. */
8
+ export declare class HttpPotentialAgentsApi implements PotentialAgentsApi {
9
+ private readonly options;
10
+ private readonly baseUrl;
11
+ constructor(options: HttpApiOptions);
12
+ plan(organizationId: string, bundle: Bundle, remoteId?: string): Promise<PlanResult>;
13
+ uploadSkill(organizationId: string, skill: SkillSource): Promise<ApiSkillRevision>;
14
+ createAgent(organizationId: string, bundle: Bundle, skills: readonly ApiSkillRevision[], idempotencyKey: string): Promise<ApplyAccepted>;
15
+ createRevision(organizationId: string, remoteId: string, bundle: Bundle, skills: readonly ApiSkillRevision[], idempotencyKey: string): Promise<ApplyAccepted>;
16
+ getAgent(organizationId: string, remoteId: string): Promise<RemoteAgent>;
17
+ createSession(organizationId: string, remoteId: string): Promise<{
18
+ readonly sessionId: string;
19
+ }>;
20
+ createRun(sessionId: string, message: string, idempotencyKey: string): Promise<{
21
+ readonly runId: string;
22
+ readonly status: string;
23
+ }>;
24
+ archiveAgent(organizationId: string, remoteId: string): Promise<void>;
25
+ /** Constructs only public logical runtime intent; profile IDs cannot enter this adapter. */
26
+ private _intent;
27
+ /** Loads a small, explicit UTF-8 skill directory for the public immutable-skill API. */
28
+ private _skillContent;
29
+ /** Sends one authenticated JSON request and converts server failures to safe typed errors. */
30
+ private _json;
31
+ private _parseJson;
32
+ private _errorMessage;
33
+ private _string;
34
+ private _remoteAgent;
35
+ }
36
+ export {};
@@ -0,0 +1,150 @@
1
+ import { lstat, readdir, readFile } from 'node:fs/promises';
2
+ import { relative, resolve } from 'node:path';
3
+ import { PotentialAgentsError } from '../../../domain/errors.js';
4
+ /** HTTPS adapter for the public Potential Agents control-plane contract. */
5
+ export class HttpPotentialAgentsApi {
6
+ options;
7
+ baseUrl;
8
+ constructor(options) {
9
+ this.options = options;
10
+ this.baseUrl = options.baseUrl.replace(/\/$/u, '');
11
+ }
12
+ async plan(organizationId, bundle, remoteId) {
13
+ return this._json('POST', '/v1/managed-agents:plan', {
14
+ organization_id: organizationId,
15
+ remote_id: remoteId,
16
+ definition_sha256: bundle.definitionSha256,
17
+ intent: this._intent(bundle, []),
18
+ });
19
+ }
20
+ async uploadSkill(organizationId, skill) {
21
+ const content = await this._skillContent(skill.sourceDirectory);
22
+ const response = await this._json('POST', '/v1/skills:publish', {
23
+ organization_id: organizationId,
24
+ name: skill.name,
25
+ sha256: skill.sha256,
26
+ files: content,
27
+ });
28
+ return {
29
+ skillId: this._string(response.skill_id, 'skill_id'),
30
+ revision: this._string(response.revision, 'revision'),
31
+ sha256: this._string(response.sha256, 'sha256'),
32
+ };
33
+ }
34
+ async createAgent(organizationId, bundle, skills, idempotencyKey) {
35
+ const response = await this._json('POST', '/v1/managed-agents', {
36
+ organization_id: organizationId,
37
+ definition_sha256: bundle.definitionSha256,
38
+ ...this._intent(bundle, skills),
39
+ }, { 'Idempotency-Key': idempotencyKey });
40
+ return this._remoteAgent(response);
41
+ }
42
+ async createRevision(organizationId, remoteId, bundle, skills, idempotencyKey) {
43
+ const response = await this._json('POST', `/v1/managed-agents/${encodeURIComponent(remoteId)}/revisions`, {
44
+ definition_sha256: bundle.definitionSha256,
45
+ ...this._intent(bundle, skills),
46
+ }, { 'Idempotency-Key': idempotencyKey, 'X-Potential-Organization': organizationId });
47
+ return this._remoteAgent(response);
48
+ }
49
+ async getAgent(organizationId, remoteId) {
50
+ const response = await this._json('GET', `/v1/managed-agents/${encodeURIComponent(remoteId)}`, undefined, { 'X-Potential-Organization': organizationId });
51
+ return this._remoteAgent(response);
52
+ }
53
+ async createSession(organizationId, remoteId) {
54
+ const response = await this._json('POST', `/v1/managed-agents/${encodeURIComponent(remoteId)}/sessions`, { organization_id: organizationId });
55
+ return { sessionId: this._string(response.session_id, 'session_id') };
56
+ }
57
+ async createRun(sessionId, message, idempotencyKey) {
58
+ const response = await this._json('POST', `/v1/sessions/${encodeURIComponent(sessionId)}/runs`, { input: { message, data: null }, metadata: {} }, { 'Idempotency-Key': idempotencyKey });
59
+ return { runId: this._string(response.run_id, 'run_id'), status: this._string(response.status, 'status') };
60
+ }
61
+ async archiveAgent(organizationId, remoteId) {
62
+ await this._json('DELETE', `/v1/managed-agents/${encodeURIComponent(remoteId)}`, undefined, { 'X-Potential-Organization': organizationId });
63
+ }
64
+ /** Constructs only public logical runtime intent; profile IDs cannot enter this adapter. */
65
+ _intent(bundle, skills) {
66
+ return {
67
+ agent: { name: bundle.definition.name, ...(bundle.definition.description ? { description: bundle.definition.description } : {}) },
68
+ runtime: { engine: bundle.definition.engine, model: bundle.definition.model },
69
+ behavior: {
70
+ instructions: bundle.definition.instructions,
71
+ input_schema: { type: 'object', additionalProperties: true },
72
+ output_schema: { type: 'object', additionalProperties: true },
73
+ skills: skills.map((skill) => ({ skill_id: skill.skillId, revision: skill.revision, sha256: skill.sha256 })),
74
+ },
75
+ execution: {
76
+ tools: bundle.definition.tools,
77
+ browser: bundle.definition.browser,
78
+ limits: {
79
+ ...(bundle.definition.limits.durationSeconds === undefined ? {} : { duration_seconds: bundle.definition.limits.durationSeconds }),
80
+ ...(bundle.definition.limits.maxBudgetUsd === undefined ? {} : { max_budget_usd: bundle.definition.limits.maxBudgetUsd }),
81
+ },
82
+ },
83
+ };
84
+ }
85
+ /** Loads a small, explicit UTF-8 skill directory for the public immutable-skill API. */
86
+ async _skillContent(directory, root = directory) {
87
+ const entries = await readdir(directory, { withFileTypes: true });
88
+ const files = [];
89
+ for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {
90
+ const path = resolve(directory, entry.name);
91
+ const info = await lstat(path);
92
+ if (info.isSymbolicLink())
93
+ throw new PotentialAgentsError('VALIDATION_ERROR', `Skills may not contain symlinks: ${relative(root, path)}.`);
94
+ if (info.isDirectory())
95
+ files.push(...await this._skillContent(path, root));
96
+ else if (info.isFile())
97
+ files.push({ path: relative(root, path).replaceAll('\\', '/'), content: await readFile(path, 'utf8') });
98
+ }
99
+ return files;
100
+ }
101
+ /** Sends one authenticated JSON request and converts server failures to safe typed errors. */
102
+ async _json(method, path, body, headers = {}) {
103
+ const response = await fetch(`${this.baseUrl}${path}`, {
104
+ method,
105
+ headers: {
106
+ Accept: 'application/json',
107
+ ...(body === undefined ? {} : { 'Content-Type': 'application/json' }),
108
+ ...(this.options.accessToken ? { Authorization: `Bearer ${this.options.accessToken}` } : {}),
109
+ ...headers,
110
+ },
111
+ ...(body === undefined ? {} : { body: JSON.stringify(body) }),
112
+ });
113
+ const text = await response.text();
114
+ const parsed = text ? this._parseJson(text) : undefined;
115
+ if (!response.ok) {
116
+ const message = parsed !== null && typeof parsed === 'object' && 'error' in parsed
117
+ ? `Potential Agents API returned ${response.status}: ${this._errorMessage(parsed.error)}`
118
+ : `Potential Agents API returned ${response.status}.`;
119
+ throw new PotentialAgentsError('API_ERROR', message);
120
+ }
121
+ return parsed;
122
+ }
123
+ _parseJson(text) {
124
+ try {
125
+ return JSON.parse(text);
126
+ }
127
+ catch {
128
+ throw new PotentialAgentsError('API_PROTOCOL_ERROR', 'Potential Agents API returned invalid JSON.');
129
+ }
130
+ }
131
+ _errorMessage(error) {
132
+ if (error !== null && typeof error === 'object' && 'message' in error && typeof error.message === 'string')
133
+ return error.message;
134
+ return 'request failed';
135
+ }
136
+ _string(value, field) {
137
+ if (typeof value !== 'string' || !value)
138
+ throw new PotentialAgentsError('API_PROTOCOL_ERROR', `Potential Agents API response lacks ${field}.`);
139
+ return value;
140
+ }
141
+ _remoteAgent(response) {
142
+ return {
143
+ agentId: this._string(response.agent_id, 'agent_id'),
144
+ activeRevision: this._string(response.active_revision, 'active_revision'),
145
+ deploymentId: this._string(response.deployment_id, 'deployment_id'),
146
+ status: this._string(response.status, 'status'),
147
+ };
148
+ }
149
+ }
150
+ //# sourceMappingURL=http-potential-agents-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-potential-agents-api.js","sourceRoot":"","sources":["../../../../src/adapters/outbound/http/http-potential-agents-api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { IdempotencyKeyGenerator } from '../../../application/ports/idempotency-key-generator.js';
2
+ /** Derives retry-safe idempotency keys from scoped immutable definitions. */
3
+ export declare class Sha256IdempotencyKeyGenerator implements IdempotencyKeyGenerator {
4
+ generate(organizationId: string, definitionSha256: string, operation: 'create' | 'revision' | 'run'): string;
5
+ }
@@ -0,0 +1,8 @@
1
+ import { createHash } from 'node:crypto';
2
+ /** Derives retry-safe idempotency keys from scoped immutable definitions. */
3
+ export class Sha256IdempotencyKeyGenerator {
4
+ generate(organizationId, definitionSha256, operation) {
5
+ return createHash('sha256').update(`${operation}\0${organizationId}\0${definitionSha256}`).digest('hex');
6
+ }
7
+ }
8
+ //# sourceMappingURL=sha256-idempotency-key-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sha256-idempotency-key-generator.js","sourceRoot":"","sources":["../../../../src/adapters/outbound/runtime/sha256-idempotency-key-generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,6EAA6E;AAC7E,MAAM,OAAO,6BAA6B;IACjC,QAAQ,CAAC,cAAsB,EAAE,gBAAwB,EAAE,SAAwC;QACxG,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,SAAS,KAAK,cAAc,KAAK,gBAAgB,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC3G,CAAC;CACF"}