@comma-agents/core 2.0.0-rc.0 → 2.0.0-rc.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/dist/agents/agent/agent.types.d.ts +2 -2
- package/dist/agents/loader/index.d.ts +2 -2
- package/dist/agents/loader/loader.d.ts +3 -5
- package/dist/agents/loader/loader.schema.d.ts +226 -13
- package/dist/agents/loader/loader.types.d.ts +9 -8
- package/dist/agents/registry/agent-registry.constants.d.ts +1 -0
- package/dist/agents/registry/agent-registry.d.ts +38 -0
- package/dist/agents/registry/agent-registry.types.d.ts +58 -0
- package/dist/agents/registry/index.d.ts +2 -0
- package/dist/credentials/backends/json-file.d.ts +1 -1
- package/dist/credentials/credentials.constants.d.ts +2 -0
- package/dist/credentials/credentials.utils.d.ts +0 -19
- package/dist/credentials/index.d.ts +1 -1
- package/dist/data-directory/data-directory.d.ts +11 -0
- package/dist/data-directory/index.d.ts +1 -0
- package/dist/defaults/defaults.d.ts +1 -1
- package/dist/flows/index.d.ts +2 -0
- package/dist/flows/loader/loader.schema.d.ts +2 -195
- package/dist/flows/loader/loader.utils.d.ts +5 -0
- package/dist/flows/registry/flow-registry.constants.d.ts +1 -0
- package/dist/flows/registry/flow-registry.d.ts +45 -0
- package/dist/flows/registry/flow-registry.types.d.ts +31 -0
- package/dist/flows/registry/index.d.ts +2 -0
- package/dist/hub/archive/archive.d.ts +2 -0
- package/dist/hub/archive/index.d.ts +1 -0
- package/dist/hub/comma-project.schema.json +171 -0
- package/dist/hub/hub.constants.d.ts +5 -0
- package/dist/hub/hub.d.ts +13 -0
- package/dist/hub/hub.schema.d.ts +1093 -0
- package/dist/hub/hub.types.d.ts +50 -0
- package/dist/hub/hub.utils.d.ts +3 -0
- package/dist/hub/index.d.ts +3 -0
- package/dist/hub/index.js +404 -0
- package/dist/hub/installed-packages/index.d.ts +2 -0
- package/dist/hub/installed-packages/installed-packages.d.ts +3 -0
- package/dist/hub/installed-packages/installed-packages.types.d.ts +14 -0
- package/dist/hub/package-installer/index.d.ts +2 -0
- package/dist/hub/package-installer/package-installer.d.ts +3 -0
- package/dist/hub/package-installer/package-installer.types.d.ts +11 -0
- package/dist/hub/registry-client/index.d.ts +2 -0
- package/dist/hub/registry-client/registry-client.d.ts +3 -0
- package/dist/hub/registry-client/registry-client.types.d.ts +10 -0
- package/dist/index.d.ts +13 -10
- package/dist/index.js +1386 -769
- package/dist/model/providers/catalog/catalog.utils.d.ts +2 -9
- package/dist/skills/skills.constants.d.ts +2 -2
- package/dist/skills/skills.types.d.ts +1 -1
- package/dist/skills/skills.utils.d.ts +0 -10
- package/dist/strategies/@comma/core-strategies/README.md +9 -0
- package/dist/strategies/@comma/core-strategies/build/build.json +69 -0
- package/dist/strategies/@comma/core-strategies/build/prompts/coder.md +56 -0
- package/dist/strategies/@comma/core-strategies/build/prompts/tester.md +39 -0
- package/dist/strategies/@comma/core-strategies/comma-project.json +49 -0
- package/dist/strategies/@comma/core-strategies/plan/plan.json +66 -0
- package/dist/strategies/@comma/core-strategies/plan/prompts/planner.md +59 -0
- package/dist/strategies/@comma/core-strategies/plan/prompts/reviewer.md +34 -0
- package/dist/strategies/@comma/core-strategies/qa.json +36 -0
- package/dist/strategies/@comma/core-strategies/reduce-complexity/reduce-complexity.jsonc +24 -0
- package/dist/strategies/@comma/core-strategies/standardize/manager.jsonc +54 -0
- package/dist/strategies/@comma/core-strategies/standardize/prompts/manager.md +278 -0
- package/dist/strategies/@comma/core-strategies/standardize/prompts/worker-auditor.md +131 -0
- package/dist/strategies/@comma/core-strategies/standardize/prompts/worker-reviewer.md +58 -0
- package/dist/strategies/@comma/core-strategies/standardize/worker.jsonc +69 -0
- package/dist/strategies/@comma/core-strategies/talk.json +42 -0
- package/dist/strategy/discover/discover.d.ts +10 -2
- package/dist/strategy/discover/discover.types.d.ts +6 -5
- package/dist/strategy/discover/discover.utils.d.ts +2 -13
- package/dist/strategy/discover/index.d.ts +1 -1
- package/dist/strategy/index.d.ts +3 -3
- package/dist/strategy/loader/loader.types.d.ts +2 -70
- package/dist/strategy/loader/loader.utils.d.ts +1 -8
- package/dist/strategy/loader/project-loader.d.ts +7 -1
- package/dist/strategy/schema.d.ts +154 -60
- package/dist/tools/built-in/list-strategy/list-strategy.d.ts +2 -2
- package/package.json +18 -7
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
import type { CommaProjectManifestSchema, HubEnvironmentVariableSchema, HubPackageSchema, HubPermissionsSchema, HubPersonSchema, HubRegistryArtifactSchema, HubRegistrySchema, ProjectArtifactEntrySchema } from "./hub.schema";
|
|
3
|
+
/** Public metadata for a person associated with a Hub project. */
|
|
4
|
+
export type HubPerson = z.infer<typeof HubPersonSchema>;
|
|
5
|
+
/** A declared environment variable used by a project. */
|
|
6
|
+
export type HubEnvironmentVariable = z.infer<typeof HubEnvironmentVariableSchema>;
|
|
7
|
+
/** Runtime capabilities required by a project. */
|
|
8
|
+
export type HubPermissions = z.infer<typeof HubPermissionsSchema>;
|
|
9
|
+
/** One artifact declared by a project manifest. */
|
|
10
|
+
export type ProjectArtifactEntry = z.infer<typeof ProjectArtifactEntrySchema>;
|
|
11
|
+
/** Canonical `comma-project.json` contract inferred from the public schema. */
|
|
12
|
+
export type CommaProjectManifest = z.infer<typeof CommaProjectManifestSchema>;
|
|
13
|
+
export type HubArtifactKind = "strategies" | "agents" | "flows" | "tools";
|
|
14
|
+
export type HubRegistryArtifact = z.infer<typeof HubRegistryArtifactSchema>;
|
|
15
|
+
export type HubPackage = z.infer<typeof HubPackageSchema>;
|
|
16
|
+
export type HubRegistry = z.infer<typeof HubRegistrySchema>;
|
|
17
|
+
export interface HubRegistrySnapshot {
|
|
18
|
+
readonly commit: string;
|
|
19
|
+
readonly registry: HubRegistry;
|
|
20
|
+
}
|
|
21
|
+
export interface InstalledHubPackage {
|
|
22
|
+
readonly name: string;
|
|
23
|
+
readonly version: string;
|
|
24
|
+
readonly commit: string;
|
|
25
|
+
readonly path: string;
|
|
26
|
+
readonly executableCodeApproved: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface HubInstallOptions {
|
|
29
|
+
readonly allowCode?: boolean;
|
|
30
|
+
}
|
|
31
|
+
export interface HubRepositoryConfig {
|
|
32
|
+
readonly owner: string;
|
|
33
|
+
readonly repository: string;
|
|
34
|
+
readonly branch: string;
|
|
35
|
+
}
|
|
36
|
+
export interface CreateHubManagerOptions {
|
|
37
|
+
readonly dataDir?: string;
|
|
38
|
+
readonly repository?: HubRepositoryConfig;
|
|
39
|
+
readonly fetch?: typeof globalThis.fetch;
|
|
40
|
+
}
|
|
41
|
+
export interface HubManager {
|
|
42
|
+
refreshRegistry(): Promise<HubRegistrySnapshot>;
|
|
43
|
+
listAvailable(): Promise<readonly HubPackage[]>;
|
|
44
|
+
listInstalled(): Promise<readonly InstalledHubPackage[]>;
|
|
45
|
+
install(name: string, options?: HubInstallOptions): Promise<InstalledHubPackage>;
|
|
46
|
+
update(name: string, options?: HubInstallOptions): Promise<InstalledHubPackage>;
|
|
47
|
+
remove(name: string): Promise<boolean>;
|
|
48
|
+
getInstalled(name: string): Promise<InstalledHubPackage | undefined>;
|
|
49
|
+
isExecutableCodeApproved(manifestPath: string): Promise<boolean>;
|
|
50
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { createHubManager } from "./hub";
|
|
2
|
+
export { CommaProjectManifestSchema, HubPackageSchema, HubRegistryArtifactSchema, HubRegistrySchema, ProjectArtifactEntrySchema, } from "./hub.schema";
|
|
3
|
+
export type { CommaProjectManifest, CreateHubManagerOptions, HubArtifactKind, HubEnvironmentVariable, HubInstallOptions, HubManager, HubPackage, HubPermissions, HubPerson, HubRegistry, HubRegistryArtifact, HubRegistrySnapshot, HubRepositoryConfig, InstalledHubPackage, ProjectArtifactEntry, } from "./hub.types";
|
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var __require = import.meta.require;
|
|
3
|
+
|
|
4
|
+
// src/hub/hub.ts
|
|
5
|
+
import { join as join3 } from "path";
|
|
6
|
+
|
|
7
|
+
// src/data-directory/data-directory.ts
|
|
8
|
+
import { homedir } from "os";
|
|
9
|
+
import { join } from "path";
|
|
10
|
+
function resolveDataDir() {
|
|
11
|
+
return join(homedir(), ".comma");
|
|
12
|
+
}
|
|
13
|
+
// src/hub/hub.constants.ts
|
|
14
|
+
var DEFAULT_HUB_REPOSITORY = {
|
|
15
|
+
owner: "CloAI",
|
|
16
|
+
repository: "CommaAgentsHub",
|
|
17
|
+
branch: "main"
|
|
18
|
+
};
|
|
19
|
+
var HUB_MAX_FILES = 2000;
|
|
20
|
+
var HUB_MAX_UNCOMPRESSED_BYTES = 50 * 1024 * 1024;
|
|
21
|
+
var HUB_INSTALLED_STATE_FILENAME = "installed-packages.json";
|
|
22
|
+
|
|
23
|
+
// src/hub/hub.utils.ts
|
|
24
|
+
function findAvailableHubPackage(snapshot, name) {
|
|
25
|
+
const project = snapshot.registry.packages.find((availablePackage) => availablePackage.name === name);
|
|
26
|
+
if (!project)
|
|
27
|
+
throw new Error(`Hub package not found: ${name}`);
|
|
28
|
+
return project;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// src/hub/installed-packages/installed-packages.ts
|
|
32
|
+
import { mkdir, readFile, rename, rm, writeFile } from "fs/promises";
|
|
33
|
+
import { dirname, resolve } from "path";
|
|
34
|
+
function createInstalledPackageStore({
|
|
35
|
+
statePath
|
|
36
|
+
}) {
|
|
37
|
+
async function readState() {
|
|
38
|
+
try {
|
|
39
|
+
const parsed = JSON.parse(await readFile(statePath, "utf8"));
|
|
40
|
+
return {
|
|
41
|
+
packages: Array.isArray(parsed.packages) ? parsed.packages : []
|
|
42
|
+
};
|
|
43
|
+
} catch (error) {
|
|
44
|
+
if (error.code === "ENOENT")
|
|
45
|
+
return { packages: [] };
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async function writeState(packages) {
|
|
50
|
+
await mkdir(dirname(statePath), { recursive: true });
|
|
51
|
+
const temporaryPath = `${statePath}.${crypto.randomUUID()}.tmp`;
|
|
52
|
+
await writeFile(temporaryPath, `${JSON.stringify({ packages: [...packages].sort((firstPackage, secondPackage) => firstPackage.name.localeCompare(secondPackage.name)) }, null, 2)}
|
|
53
|
+
`);
|
|
54
|
+
await rename(temporaryPath, statePath);
|
|
55
|
+
}
|
|
56
|
+
async function list() {
|
|
57
|
+
return (await readState()).packages;
|
|
58
|
+
}
|
|
59
|
+
async function get(name) {
|
|
60
|
+
return (await list()).find((installedPackage) => installedPackage.name === name);
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
list,
|
|
64
|
+
get,
|
|
65
|
+
async replace(installedPackage) {
|
|
66
|
+
const state = await readState();
|
|
67
|
+
await writeState([
|
|
68
|
+
...state.packages.filter((statePackage) => statePackage.name !== installedPackage.name),
|
|
69
|
+
installedPackage
|
|
70
|
+
]);
|
|
71
|
+
},
|
|
72
|
+
async remove(name) {
|
|
73
|
+
const installedPackage = await get(name);
|
|
74
|
+
if (!installedPackage)
|
|
75
|
+
return false;
|
|
76
|
+
const backupPath = `${installedPackage.path}.${crypto.randomUUID()}.removing`;
|
|
77
|
+
const state = await readState();
|
|
78
|
+
await rename(installedPackage.path, backupPath);
|
|
79
|
+
try {
|
|
80
|
+
await writeState(state.packages.filter((statePackage) => statePackage.name !== name));
|
|
81
|
+
await rm(backupPath, { recursive: true, force: true });
|
|
82
|
+
return true;
|
|
83
|
+
} catch (error) {
|
|
84
|
+
await rename(backupPath, installedPackage.path);
|
|
85
|
+
throw error;
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
async isExecutableCodeApproved(manifestPath) {
|
|
89
|
+
const installedPackage = (await list()).find((statePackage) => resolve(statePackage.path, "comma-project.json") === resolve(manifestPath));
|
|
90
|
+
return installedPackage?.executableCodeApproved ?? false;
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
// src/hub/package-installer/package-installer.ts
|
|
95
|
+
import { mkdir as mkdir3, mkdtemp, readFile as readFile2, rename as rename2, rm as rm2, stat } from "fs/promises";
|
|
96
|
+
import { tmpdir } from "os";
|
|
97
|
+
import { dirname as dirname3, join as join2 } from "path";
|
|
98
|
+
|
|
99
|
+
// src/hub/archive/archive.ts
|
|
100
|
+
import { createWriteStream } from "fs";
|
|
101
|
+
import { mkdir as mkdir2 } from "fs/promises";
|
|
102
|
+
import { dirname as dirname2, relative, resolve as resolve2, sep } from "path";
|
|
103
|
+
import { extract } from "tar-stream";
|
|
104
|
+
async function extractHubPackageArchive(compressedArchive, packageName, destination) {
|
|
105
|
+
const unpackedArchive = Bun.gunzipSync(compressedArchive.buffer);
|
|
106
|
+
const archive = extract();
|
|
107
|
+
const packageMarker = `/packages/${packageName}/`;
|
|
108
|
+
let fileCount = 0;
|
|
109
|
+
let byteCount = 0;
|
|
110
|
+
let foundManifest = false;
|
|
111
|
+
await new Promise((resolveExtraction, rejectExtraction) => {
|
|
112
|
+
archive.on("entry", (header, stream, next) => {
|
|
113
|
+
const markerIndex = header.name.indexOf(packageMarker);
|
|
114
|
+
if (markerIndex === -1) {
|
|
115
|
+
stream.resume();
|
|
116
|
+
stream.once("end", next);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const relativePath = header.name.slice(markerIndex + packageMarker.length);
|
|
120
|
+
if (relativePath.length === 0 || header.type === "directory") {
|
|
121
|
+
stream.resume();
|
|
122
|
+
stream.once("end", next);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
if (header.type !== "file") {
|
|
126
|
+
rejectExtraction(new Error(`Hub archive contains unsupported ${header.type} entry: ${relativePath}`));
|
|
127
|
+
stream.resume();
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const outputPath = resolve2(destination, relativePath);
|
|
131
|
+
const relativeOutputPath = relative(resolve2(destination), resolve2(outputPath));
|
|
132
|
+
if (relativeOutputPath === "" || relativeOutputPath === ".." || relativeOutputPath.startsWith(`..${sep}`)) {
|
|
133
|
+
rejectExtraction(new Error(`Hub archive path escapes package root: ${relativePath}`));
|
|
134
|
+
stream.resume();
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
fileCount += 1;
|
|
138
|
+
byteCount += header.size ?? 0;
|
|
139
|
+
if (fileCount > HUB_MAX_FILES || byteCount > HUB_MAX_UNCOMPRESSED_BYTES) {
|
|
140
|
+
rejectExtraction(new Error("Hub package exceeds extraction limits"));
|
|
141
|
+
stream.resume();
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
mkdir2(dirname2(outputPath), { recursive: true }).then(() => {
|
|
145
|
+
if (relativePath === "comma-project.json")
|
|
146
|
+
foundManifest = true;
|
|
147
|
+
const output = createWriteStream(outputPath, { flags: "wx" });
|
|
148
|
+
output.once("error", rejectExtraction);
|
|
149
|
+
output.once("finish", next);
|
|
150
|
+
stream.once("error", rejectExtraction);
|
|
151
|
+
stream.pipe(output);
|
|
152
|
+
}).catch(rejectExtraction);
|
|
153
|
+
});
|
|
154
|
+
archive.once("finish", () => {
|
|
155
|
+
if (!foundManifest) {
|
|
156
|
+
rejectExtraction(new Error(`Package ${packageName} was not found in the Hub archive`));
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
resolveExtraction();
|
|
160
|
+
});
|
|
161
|
+
archive.once("error", rejectExtraction);
|
|
162
|
+
archive.end(unpackedArchive);
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
// src/hub/hub.schema.ts
|
|
166
|
+
import { z } from "zod";
|
|
167
|
+
var PACKAGE_NAME_PATTERN = /^@[a-z0-9][a-z0-9-]*\/[a-z0-9][a-z0-9-]*$/;
|
|
168
|
+
var ARTIFACT_NAME_PATTERN = /^[a-z0-9][a-z0-9-]*$/;
|
|
169
|
+
var SEMVER_PATTERN = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
170
|
+
var HubPersonSchema = z.object({
|
|
171
|
+
name: z.string().min(1),
|
|
172
|
+
email: z.string().email().optional(),
|
|
173
|
+
url: z.string().url().optional()
|
|
174
|
+
}).strict();
|
|
175
|
+
var HubEnvironmentVariableSchema = z.object({
|
|
176
|
+
description: z.string().optional(),
|
|
177
|
+
required: z.boolean().optional(),
|
|
178
|
+
default: z.string().optional(),
|
|
179
|
+
example: z.string().optional()
|
|
180
|
+
}).strict();
|
|
181
|
+
var HubPermissionsSchema = z.object({
|
|
182
|
+
network: z.boolean().optional(),
|
|
183
|
+
filesystem: z.boolean().optional(),
|
|
184
|
+
shell: z.boolean().optional(),
|
|
185
|
+
executesCode: z.boolean().optional()
|
|
186
|
+
}).strict();
|
|
187
|
+
var ProjectArtifactEntrySchema = z.object({
|
|
188
|
+
path: z.string().min(1),
|
|
189
|
+
expose: z.boolean().optional(),
|
|
190
|
+
description: z.string().optional()
|
|
191
|
+
}).strict();
|
|
192
|
+
var ArtifactMapSchema = z.record(z.string().regex(ARTIFACT_NAME_PATTERN), ProjectArtifactEntrySchema);
|
|
193
|
+
var CommaProjectManifestSchema = z.object({
|
|
194
|
+
name: z.string().regex(PACKAGE_NAME_PATTERN),
|
|
195
|
+
version: z.string().regex(SEMVER_PATTERN, "Expected semantic version x.y.z"),
|
|
196
|
+
description: z.string().optional(),
|
|
197
|
+
license: z.string().optional(),
|
|
198
|
+
author: HubPersonSchema.optional(),
|
|
199
|
+
contributors: z.array(HubPersonSchema).optional(),
|
|
200
|
+
keywords: z.array(z.string()).optional(),
|
|
201
|
+
strategies: ArtifactMapSchema.optional(),
|
|
202
|
+
agents: ArtifactMapSchema.optional(),
|
|
203
|
+
flows: ArtifactMapSchema.optional(),
|
|
204
|
+
tools: ArtifactMapSchema.optional(),
|
|
205
|
+
entry: z.string().min(1).optional(),
|
|
206
|
+
dependencies: z.record(z.string(), z.string()).optional(),
|
|
207
|
+
environment: z.record(z.string().regex(/^[A-Z_][A-Z0-9_]*$/), HubEnvironmentVariableSchema).optional(),
|
|
208
|
+
permissions: HubPermissionsSchema.optional(),
|
|
209
|
+
links: z.object({
|
|
210
|
+
homepage: z.string().url().optional(),
|
|
211
|
+
repository: z.string().url().optional(),
|
|
212
|
+
docs: z.string().url().optional(),
|
|
213
|
+
issues: z.string().url().optional()
|
|
214
|
+
}).strict().optional()
|
|
215
|
+
}).strict();
|
|
216
|
+
var HubRegistryArtifactSchema = z.object({
|
|
217
|
+
id: z.string().regex(ARTIFACT_NAME_PATTERN),
|
|
218
|
+
ref: z.string().min(1),
|
|
219
|
+
path: z.string().min(1),
|
|
220
|
+
description: z.string().optional()
|
|
221
|
+
}).strict();
|
|
222
|
+
var RegistryArtifactListSchema = z.array(HubRegistryArtifactSchema);
|
|
223
|
+
var HubPackageSchema = z.object({
|
|
224
|
+
name: z.string().regex(PACKAGE_NAME_PATTERN),
|
|
225
|
+
version: z.string().regex(SEMVER_PATTERN),
|
|
226
|
+
description: z.string().optional(),
|
|
227
|
+
license: z.string().optional(),
|
|
228
|
+
path: z.string().min(1),
|
|
229
|
+
author: HubPersonSchema.optional(),
|
|
230
|
+
contributors: z.array(HubPersonSchema).optional(),
|
|
231
|
+
keywords: z.array(z.string()).optional(),
|
|
232
|
+
exports: z.object({
|
|
233
|
+
strategies: RegistryArtifactListSchema,
|
|
234
|
+
agents: RegistryArtifactListSchema,
|
|
235
|
+
flows: RegistryArtifactListSchema,
|
|
236
|
+
tools: RegistryArtifactListSchema
|
|
237
|
+
}).strict(),
|
|
238
|
+
environment: z.record(HubEnvironmentVariableSchema).optional(),
|
|
239
|
+
permissions: HubPermissionsSchema.optional(),
|
|
240
|
+
links: z.object({
|
|
241
|
+
homepage: z.string().url().optional(),
|
|
242
|
+
repository: z.string().url().optional(),
|
|
243
|
+
docs: z.string().url().optional(),
|
|
244
|
+
issues: z.string().url().optional()
|
|
245
|
+
}).strict().optional()
|
|
246
|
+
}).strict();
|
|
247
|
+
var HubRegistrySchema = z.object({
|
|
248
|
+
version: z.literal(1),
|
|
249
|
+
packages: z.array(HubPackageSchema)
|
|
250
|
+
}).strict();
|
|
251
|
+
|
|
252
|
+
// src/hub/package-installer/package-installer.ts
|
|
253
|
+
function createHubPackageInstaller({
|
|
254
|
+
packagesRoot,
|
|
255
|
+
installedPackages,
|
|
256
|
+
registryClient
|
|
257
|
+
}) {
|
|
258
|
+
return {
|
|
259
|
+
async install(project, snapshot, options, replace) {
|
|
260
|
+
if (project.permissions?.executesCode === true && options.allowCode !== true) {
|
|
261
|
+
throw new Error(`Package ${project.name} contains executable code; pass allowCode: true to install it`);
|
|
262
|
+
}
|
|
263
|
+
const existingPackage = await installedPackages.get(project.name);
|
|
264
|
+
if (existingPackage && !replace)
|
|
265
|
+
throw new Error(`Package ${project.name} is already installed`);
|
|
266
|
+
const stagingRoot = await mkdtemp(join2(tmpdir(), "comma-hub-"));
|
|
267
|
+
const stagedPackagePath = join2(stagingRoot, "package");
|
|
268
|
+
const destinationPath = join2(packagesRoot, ...project.name.split("/"));
|
|
269
|
+
const backupPath = `${destinationPath}.${crypto.randomUUID()}.backup`;
|
|
270
|
+
let destinationReplaced = false;
|
|
271
|
+
try {
|
|
272
|
+
await mkdir3(stagedPackagePath, { recursive: true });
|
|
273
|
+
await extractHubPackageArchive(await registryClient.fetchArchive(snapshot.commit), project.name, stagedPackagePath);
|
|
274
|
+
const manifest = CommaProjectManifestSchema.safeParse(JSON.parse(await readFile2(join2(stagedPackagePath, "comma-project.json"), "utf8")));
|
|
275
|
+
if (!manifest.success || manifest.data.name !== project.name || manifest.data.version !== project.version) {
|
|
276
|
+
throw new Error(`Installed manifest does not match registry entry for ${project.name}`);
|
|
277
|
+
}
|
|
278
|
+
if (manifest.data.permissions?.executesCode !== project.permissions?.executesCode) {
|
|
279
|
+
throw new Error(`Installed manifest permissions do not match registry entry for ${project.name}`);
|
|
280
|
+
}
|
|
281
|
+
if (manifest.data.dependencies && Object.keys(manifest.data.dependencies).length > 0) {
|
|
282
|
+
throw new Error(`Package dependencies are not supported in v1: ${project.name}`);
|
|
283
|
+
}
|
|
284
|
+
await mkdir3(dirname3(destinationPath), { recursive: true });
|
|
285
|
+
if (existingPackage)
|
|
286
|
+
await rename2(destinationPath, backupPath);
|
|
287
|
+
await rename2(stagedPackagePath, destinationPath);
|
|
288
|
+
destinationReplaced = true;
|
|
289
|
+
const installedPackage = {
|
|
290
|
+
name: project.name,
|
|
291
|
+
version: project.version,
|
|
292
|
+
commit: snapshot.commit,
|
|
293
|
+
path: destinationPath,
|
|
294
|
+
executableCodeApproved: project.permissions?.executesCode === true
|
|
295
|
+
};
|
|
296
|
+
await installedPackages.replace(installedPackage);
|
|
297
|
+
await rm2(backupPath, { recursive: true, force: true });
|
|
298
|
+
return installedPackage;
|
|
299
|
+
} catch (error) {
|
|
300
|
+
try {
|
|
301
|
+
if (destinationReplaced) {
|
|
302
|
+
await rm2(destinationPath, { recursive: true, force: true });
|
|
303
|
+
}
|
|
304
|
+
if (existingPackage && (await stat(backupPath)).isDirectory()) {
|
|
305
|
+
await rename2(backupPath, destinationPath);
|
|
306
|
+
}
|
|
307
|
+
} catch {}
|
|
308
|
+
throw error;
|
|
309
|
+
} finally {
|
|
310
|
+
await rm2(stagingRoot, { recursive: true, force: true });
|
|
311
|
+
await rm2(backupPath, { recursive: true, force: true });
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
// src/hub/registry-client/registry-client.ts
|
|
317
|
+
function createHubRegistryClient({
|
|
318
|
+
repository,
|
|
319
|
+
fetch
|
|
320
|
+
}) {
|
|
321
|
+
let registrySnapshot;
|
|
322
|
+
async function fetchRequired(url) {
|
|
323
|
+
const response = await fetch(url, {
|
|
324
|
+
headers: { Accept: "application/vnd.github+json" }
|
|
325
|
+
});
|
|
326
|
+
if (!response.ok)
|
|
327
|
+
throw new Error(`Hub request failed (${response.status}): ${url}`);
|
|
328
|
+
return response;
|
|
329
|
+
}
|
|
330
|
+
async function refresh() {
|
|
331
|
+
const repositoryUrl = `https://api.github.com/repos/${repository.owner}/${repository.repository}`;
|
|
332
|
+
const commitResponse = await fetchRequired(`${repositoryUrl}/commits/${repository.branch}`);
|
|
333
|
+
const commitJson = await commitResponse.json();
|
|
334
|
+
if (typeof commitJson.sha !== "string")
|
|
335
|
+
throw new Error("Hub commit response did not contain a SHA");
|
|
336
|
+
const registryResponse = await fetchRequired(`https://raw.githubusercontent.com/${repository.owner}/${repository.repository}/${commitJson.sha}/registry.json`);
|
|
337
|
+
const parsedRegistry = HubRegistrySchema.safeParse(await registryResponse.json());
|
|
338
|
+
if (!parsedRegistry.success) {
|
|
339
|
+
throw new Error(`Hub registry validation failed: ${parsedRegistry.error.message}`);
|
|
340
|
+
}
|
|
341
|
+
registrySnapshot = {
|
|
342
|
+
commit: commitJson.sha,
|
|
343
|
+
registry: parsedRegistry.data
|
|
344
|
+
};
|
|
345
|
+
return registrySnapshot;
|
|
346
|
+
}
|
|
347
|
+
return {
|
|
348
|
+
refresh,
|
|
349
|
+
async getSnapshot() {
|
|
350
|
+
return registrySnapshot ?? refresh();
|
|
351
|
+
},
|
|
352
|
+
async fetchArchive(commit) {
|
|
353
|
+
const archiveResponse = await fetchRequired(`https://codeload.github.com/${repository.owner}/${repository.repository}/tar.gz/${commit}`);
|
|
354
|
+
return new Uint8Array(await archiveResponse.arrayBuffer());
|
|
355
|
+
}
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
// src/hub/hub.ts
|
|
359
|
+
function createHubManager(options = {}) {
|
|
360
|
+
const dataDirectory = options.dataDir ?? resolveDataDir();
|
|
361
|
+
const repository = options.repository ?? DEFAULT_HUB_REPOSITORY;
|
|
362
|
+
const registryClient = createHubRegistryClient({
|
|
363
|
+
repository,
|
|
364
|
+
fetch: options.fetch ?? globalThis.fetch
|
|
365
|
+
});
|
|
366
|
+
const installedPackages = createInstalledPackageStore({
|
|
367
|
+
statePath: join3(dataDirectory, "hub", HUB_INSTALLED_STATE_FILENAME)
|
|
368
|
+
});
|
|
369
|
+
const packageInstaller = createHubPackageInstaller({
|
|
370
|
+
packagesRoot: join3(dataDirectory, "packages"),
|
|
371
|
+
installedPackages,
|
|
372
|
+
registryClient
|
|
373
|
+
});
|
|
374
|
+
return {
|
|
375
|
+
refreshRegistry: registryClient.refresh,
|
|
376
|
+
async listAvailable() {
|
|
377
|
+
return (await registryClient.getSnapshot()).registry.packages;
|
|
378
|
+
},
|
|
379
|
+
listInstalled: installedPackages.list,
|
|
380
|
+
async install(name, installOptions = {}) {
|
|
381
|
+
const snapshot = await registryClient.getSnapshot();
|
|
382
|
+
const project = findAvailableHubPackage(snapshot, name);
|
|
383
|
+
return packageInstaller.install(project, snapshot, installOptions, false);
|
|
384
|
+
},
|
|
385
|
+
async update(name, installOptions = {}) {
|
|
386
|
+
if (!await installedPackages.get(name))
|
|
387
|
+
throw new Error(`Package ${name} is not installed`);
|
|
388
|
+
const snapshot = await registryClient.refresh();
|
|
389
|
+
const project = findAvailableHubPackage(snapshot, name);
|
|
390
|
+
return packageInstaller.install(project, snapshot, installOptions, true);
|
|
391
|
+
},
|
|
392
|
+
remove: installedPackages.remove,
|
|
393
|
+
getInstalled: installedPackages.get,
|
|
394
|
+
isExecutableCodeApproved: installedPackages.isExecutableCodeApproved
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
export {
|
|
398
|
+
createHubManager,
|
|
399
|
+
ProjectArtifactEntrySchema,
|
|
400
|
+
HubRegistrySchema,
|
|
401
|
+
HubRegistryArtifactSchema,
|
|
402
|
+
HubPackageSchema,
|
|
403
|
+
CommaProjectManifestSchema
|
|
404
|
+
};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { CreateInstalledPackageStoreOptions, InstalledPackageStore } from "./installed-packages.types";
|
|
2
|
+
/** Create the persistent store used to track installed Hub packages. */
|
|
3
|
+
export declare function createInstalledPackageStore({ statePath, }: CreateInstalledPackageStoreOptions): InstalledPackageStore;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { InstalledHubPackage } from "../hub.types";
|
|
2
|
+
export interface InstalledPackageStore {
|
|
3
|
+
list(): Promise<readonly InstalledHubPackage[]>;
|
|
4
|
+
get(name: string): Promise<InstalledHubPackage | undefined>;
|
|
5
|
+
replace(installedPackage: InstalledHubPackage): Promise<void>;
|
|
6
|
+
remove(name: string): Promise<boolean>;
|
|
7
|
+
isExecutableCodeApproved(manifestPath: string): Promise<boolean>;
|
|
8
|
+
}
|
|
9
|
+
export interface CreateInstalledPackageStoreOptions {
|
|
10
|
+
readonly statePath: string;
|
|
11
|
+
}
|
|
12
|
+
export interface InstalledPackageState {
|
|
13
|
+
readonly packages: readonly InstalledHubPackage[];
|
|
14
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { CreateHubPackageInstallerOptions, HubPackageInstaller } from "./package-installer.types";
|
|
2
|
+
/** Create the transaction that validates and installs Hub packages. */
|
|
3
|
+
export declare function createHubPackageInstaller({ packagesRoot, installedPackages, registryClient, }: CreateHubPackageInstallerOptions): HubPackageInstaller;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { HubInstallOptions, HubPackage, HubRegistrySnapshot, InstalledHubPackage } from "../hub.types";
|
|
2
|
+
import type { InstalledPackageStore } from "../installed-packages";
|
|
3
|
+
import type { HubRegistryClient } from "../registry-client";
|
|
4
|
+
export interface CreateHubPackageInstallerOptions {
|
|
5
|
+
readonly packagesRoot: string;
|
|
6
|
+
readonly installedPackages: InstalledPackageStore;
|
|
7
|
+
readonly registryClient: HubRegistryClient;
|
|
8
|
+
}
|
|
9
|
+
export interface HubPackageInstaller {
|
|
10
|
+
install(project: HubPackage, snapshot: HubRegistrySnapshot, options: HubInstallOptions, replace: boolean): Promise<InstalledHubPackage>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { CreateHubRegistryClientOptions, HubRegistryClient } from "./registry-client.types";
|
|
2
|
+
/** Create a client for fetching a Hub registry and its repository archive. */
|
|
3
|
+
export declare function createHubRegistryClient({ repository, fetch, }: CreateHubRegistryClientOptions): HubRegistryClient;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { HubRegistrySnapshot, HubRepositoryConfig } from "../hub.types";
|
|
2
|
+
export interface HubRegistryClient {
|
|
3
|
+
refresh(): Promise<HubRegistrySnapshot>;
|
|
4
|
+
getSnapshot(): Promise<HubRegistrySnapshot>;
|
|
5
|
+
fetchArchive(commit: string): Promise<Uint8Array>;
|
|
6
|
+
}
|
|
7
|
+
export interface CreateHubRegistryClientOptions {
|
|
8
|
+
readonly repository: HubRepositoryConfig;
|
|
9
|
+
readonly fetch: typeof globalThis.fetch;
|
|
10
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -6,18 +6,21 @@ export { createUserAgent } from "./agents/built-in/user/user-agent";
|
|
|
6
6
|
export type { InputCollector, InputRequest, UserAgentConfig, } from "./agents/built-in/user/user-agent.types";
|
|
7
7
|
export { hookIntoAgent } from "./agents/hook-into-agent/hook-into-agent";
|
|
8
8
|
export type { AgentHooks, ToolHooks } from "./agents/hooks/hooks.types";
|
|
9
|
-
export type { AgentDescription, LoadAgentOptions } from "./agents/loader/index";
|
|
10
|
-
export { AgentDescriptionSchema, loadAgent, loadAgentFromString, } from "./agents/loader/index";
|
|
11
|
-
export type {
|
|
9
|
+
export type { AgentDescription, CustomAgentDescription, LLMAgentDescription, LoadAgentOptions, } from "./agents/loader/index";
|
|
10
|
+
export { AgentDescriptionSchema, CustomAgentDescriptionSchema, LLMAgentDescriptionSchema, loadAgent, loadAgentFromString, } from "./agents/loader/index";
|
|
11
|
+
export type { AgentTypeContext, AgentTypeDefinition, AgentTypeRuntime, } from "./agents/registry";
|
|
12
|
+
export { defineAgentType, getRegisteredAgentNames, registerAgent, resetAgentRegistry, unregisterAgent, } from "./agents/registry";
|
|
13
|
+
export type { AssistantModelMessage, CompactionOptions, ContextPrepareInput, ContextRecordTransform, ContextRetentionOptions, ContextTransformInput, ContextUsage, ConversationHistory, ConversationRecord, ConversationRecordStatus, ConversationRetentionEvent, ConversationUsage, CreateConversationRecordInput, ModelMessage, ResponseMessage, RollingWindowOptions, SummarizeRecords, ToolModelMessage, UserModelMessage, } from "./conversation-context";
|
|
12
14
|
export type { ConversationContext, ConversationContextOptions, } from "./conversation-context/index";
|
|
13
|
-
export { applyCompaction, applyRollingWindow, contextUsageFromSteps, createConversationContext, createConversationRecord, parseConversationJson, parseConversationJsonl, parseConversationYaml, prepareContextRecords, recordsToMessages, recordToJsonlLine,
|
|
15
|
+
export { applyCompaction, applyRollingWindow, contextUsageFromSteps, createConversationContext, createConversationRecord, parseConversationJson, parseConversationJsonl, parseConversationYaml, prepareContextRecords, recordsToMessages, recordToJsonlLine, serializeConversationRecords, serializeConversationRecordsJson, serializeConversationRecordsYaml, } from "./conversation-context/index";
|
|
14
16
|
export type { ApiCredential, AuthStatus, CreateCredentialStoreOptions, Credential, CredentialBackend, CredentialStore, CredentialStoreData, CustomCredential, EnvVarMap, OAuthCredential, } from "./credentials/index";
|
|
15
|
-
export { ApiCredentialSchema, CredentialSchema, CustomCredentialSchema, createCredentialStore, createJsonFileBackend, OAuthCredentialSchema, resolveCredentialsPath,
|
|
17
|
+
export { ApiCredentialSchema, CredentialSchema, CustomCredentialSchema, createCredentialStore, createJsonFileBackend, OAuthCredentialSchema, resolveCredentialsPath, } from "./credentials/index";
|
|
18
|
+
export { resolveDataDir } from "./data-directory";
|
|
16
19
|
export type { GlobalDefaults, ProviderRegistration } from "./defaults/index";
|
|
17
20
|
export { getGlobalCredentialStore, getGlobalDefaults, getGlobalProviderResolver, registerProvider, resetGlobalDefaults, setGlobalCredentialStore, setProviderCacheDir, unregisterProvider, } from "./defaults/index";
|
|
18
21
|
export { AgentCallError, CommaAgentsError, FlowExecutionError, HookExecutionError, ModelResolutionError, SandboxViolationError, StrategyValidationError, ToolExecutionError, } from "./errors/index";
|
|
19
|
-
export type { BroadcastFlowConfig, CustomFlowConfig, CycleFlowConfig, CycleHooks, FlowConfig, FlowContext, FlowExecutor, FlowHooks, FlowResult, } from "./flows/index";
|
|
20
|
-
export { buildFlowAgent, createBroadcastFlow, createCycleFlow, createFlow, createSequentialFlow, hookIntoFlow, } from "./flows/index";
|
|
22
|
+
export type { BroadcastFlowConfig, CustomFlowConfig, CycleFlowConfig, CycleHooks, FlowConfig, FlowContext, FlowExecutor, FlowHooks, FlowResult, FlowTypeContext, FlowTypeDefinition, } from "./flows/index";
|
|
23
|
+
export { buildFlowAgent, createBroadcastFlow, createCycleFlow, createFlow, createSequentialFlow, defineFlowType, getRegisteredFlowNames, hookIntoFlow, registerFlow, resetFlowRegistry, unregisterFlow, } from "./flows/index";
|
|
21
24
|
export type { FlowDescription, LoadFlowOptions } from "./flows/loader/index";
|
|
22
25
|
export { FlowDescriptionSchema, loadFlow, loadFlowFromString, } from "./flows/loader/index";
|
|
23
26
|
export type { AccessRequest, AccessType, Guard, GuardCallbacks, GuardPermissionRequest, GuardPolicySnapshot, Policy, PolicyDecision, } from "./guard/index";
|
|
@@ -28,15 +31,15 @@ export type { ModelMetadata, TokenSnapshot, TokenTracker, TokenTrackerConfig, To
|
|
|
28
31
|
export { createTokenTracker, useTokenTracking, } from "./hooks/built-in/token-tracking/index";
|
|
29
32
|
export type { LanguageDiagnostic, LanguageDiagnosticSeverity, LanguageHoverResult, LanguageLocation, LanguagePosition, LanguageRange, LanguageService, LanguageSymbol, LspMethod, LspRequest, LspResponse, } from "./language/index";
|
|
30
33
|
export type { CatalogData, CatalogModel, CatalogProvider, ListModelsContext, ListModelsFn, ListModelsResult, Modality, ModelCapabilities, ModelCost, ModelInfo, ModelModalities, ModelStatus, ModelsSource, ParsedModel, ProviderDefinition, ProviderFactory, ProviderInfo, ProviderResolver, ProviderWithModels, } from "./model/index";
|
|
31
|
-
export { extractProviderIds, getCatalogModels, getCatalogProvider, getCatalogProviderSync, getCatalogSnapshot, getModelCapabilities, getModelMetadata,
|
|
34
|
+
export { extractProviderIds, getCatalogModels, getCatalogProvider, getCatalogProviderSync, getCatalogSnapshot, getModelCapabilities, getModelMetadata, getProviderDefinition, getProviderInfo, getProviderPackage, getProvidersForModel, getQualifiedModelMetadata, getReverseModelIndex, isKnownProvider, listAllProviderModels, listCatalogProviders, listProviderDefinitions, listProviderModels, listProviders, loadCatalog, parseModel, refreshCatalog, registerModel, registerProviderDefinition, resetCatalog, resetModelRegistry, resetProviderRegistry, resolveCatalogCachePath, resolveModel, toModelInfo, unregisterModel, unregisterProviderDefinition, } from "./model/index";
|
|
32
35
|
export type { BuildMessagesOptions, PromptTemplate, PromptTemplateConfig, SystemPromptOptions, TemplateValue, TemplateVariables, } from "./prompts/index";
|
|
33
36
|
export { buildMessages, createPromptTemplate, resolveSystemPrompt, } from "./prompts/index";
|
|
34
37
|
export type { AccessMode, PathPolicy, PermissionDecision, PermissionOperation, PermissionRequest, PermissionRequester, PolicyPatch, Sandbox, SandboxConfig, } from "./sandbox/index";
|
|
35
38
|
export { createSandbox, DEFAULT_DAEMON_SANDBOX_CONFIG, DEFAULT_FORBIDDEN_GLOBS, DEFAULT_SANDBOX_CONFIG, getSandbox, inSandbox, PERMISSIVE_SANDBOX_CONFIG, } from "./sandbox/index";
|
|
36
39
|
export type { LoadSkillsOptions, Skill, SkillLoadResult, SkillLoadWarning, SkillMetadata, SkillRegistry, } from "./skills/index";
|
|
37
40
|
export { buildSkillsPromptHeader, createSkillRegistry, loadSkills, } from "./skills/index";
|
|
38
|
-
export type { AgentDef, AgentStep, BroadcastFlowDef, BuiltInToolName,
|
|
39
|
-
export {
|
|
41
|
+
export type { AgentDef, AgentStep, BroadcastFlowDef, BuiltInToolName, CustomAgentDef, CustomFlowDef, CycleFlowDef, DiscoveredStrategy, DiscoveredStrategyOrigin, DiscoverStrategiesOptions, DiscoverStrategiesResult, DiscoveryWarning, ExportStrategyOptions, FlowDef, LLMAgentDef, LoadedProject, LoadedStrategy, LoadStrategyOptions, SequentialFlowDef, Strategy, UserAgentDef, } from "./strategy/index";
|
|
42
|
+
export { CustomAgentDefSchema, CustomFlowDefSchema, discoverStrategies, exportStrategy, isAgentStep, isCustomAgentDef, isFlowDef, isLLMAgentDef, isUserAgentDef, loadProject, loadStrategy, loadStrategyFromString, readStrategyFile, StrategySchema, } from "./strategy/index";
|
|
40
43
|
export type { ProjectedConversationContext, Timeline, TimelineEvent, TimelineFilter, } from "./timeline/index";
|
|
41
44
|
export { createTimeline, projectConversationContext, projectFileState, } from "./timeline/index";
|
|
42
45
|
export { buildToolSystemPrompt, mergeSystemPrompts, } from "./tools/build-tool-system-prompt";
|