Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 6 additions & 9 deletions packages/coding-agent/src/core/skills.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { createHash } from "node:crypto";
import type { HarnessVersionBundle, HarnessWorkspaceIdentity } from "@earendil-works/diffex-harness-state";
import {
computeHarnessSkillId,
type HarnessVersionBundle,
type HarnessWorkspaceIdentity,
} from "@earendil-works/diffex-harness-state";
import { existsSync, readdirSync, readFileSync, statSync } from "fs";
import ignore from "ignore";
import { basename, dirname, join, relative, resolve, sep } from "path";
Expand Down Expand Up @@ -215,14 +219,7 @@ export function createEvolvedSkillCatalog(
content: artifact.content,
sourceKind: "evolved",
scope: "workspace",
skillId: `skill:${sha256(
JSON.stringify([
"evolved",
artifact.workspace.repositoryId,
artifact.workspace.directoryId ?? null,
artifact.path,
]),
)}`,
skillId: computeHarnessSkillId(artifact.workspace, artifact.path),
contentDigest: artifact.contentHash,
version: artifact.contentHash,
harnessRevision: bundle.manifest.version,
Expand Down
50 changes: 50 additions & 0 deletions packages/evolution/src/contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1090,6 +1090,56 @@ export interface MutationBatch {
readonly mutations: readonly EvolutionMutation[];
}

export interface SkillMutationExistingArtifact {
readonly skillId: string;
readonly path: string;
readonly contentDigest: string;
}

export interface SkillMutationArtifact {
readonly path: string;
readonly content: string;
readonly contentDigest: string;
}

export interface SkillMutation {
readonly mutationId: string;
readonly groupId: string;
readonly operation: SkillCandidateOperation;
readonly proposedName: string;
readonly workspace: EvolutionSkillWorkspaceIdentity;
readonly proposalRevisionIds: readonly string[];
readonly draft: EvolutionArtifactReference;
readonly validation: EvolutionArtifactReference;
readonly evaluation: EvolutionArtifactReference;
readonly existingSkills: readonly SkillMutationExistingArtifact[];
readonly skill: SkillMutationArtifact | null;
}

export interface SkillMutationBatch {
readonly metadata: EvolutionArtifactMetadata;
readonly batchId: string;
readonly targetKind: "skill";
readonly expectedBaseVersion: HarnessVersion;
readonly workspace: EvolutionSkillWorkspaceIdentity;
readonly mutations: readonly SkillMutation[];
}

export type SkillMutationExactDiff = JsonObject & {
readonly removed: readonly JsonObject[];
readonly added: readonly JsonObject[];
};

export type SkillMutationWriteOutput = JsonObject & {
readonly candidateId: string;
readonly candidateDigest: string;
readonly batchHash: string;
readonly expectedBaseVersion: HarnessVersion;
readonly resultingHarnessVersion: HarnessVersion;
readonly operationIds: readonly string[];
readonly diff: SkillMutationExactDiff;
};

export type EvolutionMemoryExactDiff = JsonObject & {
readonly start: number;
readonly removed: string;
Expand Down
4 changes: 4 additions & 0 deletions packages/evolution/src/filesystem-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,10 @@ export class FileEvolutionPersistence
}
}

assertHeld(lease: EvolutionLeaseToken): Promise<void> {
return this.#withStoreLock(() => this.#assertLeaseHeld(lease));
}

async put(artifact: EvolutionArtifact): Promise<EvolutionArtifactReference> {
await this.#ensureDirectories();
const content = serializeEvolutionValue(artifact);
Expand Down
12 changes: 12 additions & 0 deletions packages/evolution/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,12 @@ export {
type SkillEvaluationVerifier,
type SkillEvaluationVerifierKind,
type SkillMemoryRelationshipClassification,
type SkillMutation,
type SkillMutationArtifact,
type SkillMutationBatch,
type SkillMutationExactDiff,
type SkillMutationExistingArtifact,
type SkillMutationWriteOutput,
type SkillRetrievalEvaluationResult,
type SkillTarget,
type ValidationIssue,
Expand Down Expand Up @@ -376,6 +382,12 @@ export {
StructuredSkillSynthesizer,
type StructuredSkillSynthesizerDependencies,
} from "./skill-synthesizer.ts";
export {
SkillWriter,
type SkillWriterBuildInput,
type SkillWriterContext,
type SkillWriterDependencies,
} from "./skill-writer.ts";
export {
EvolutionTargetAdapterRegistry,
type EvolutionTargetAdapterRegistryOptions,
Expand Down
3 changes: 3 additions & 0 deletions packages/evolution/src/ports.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import type {
SkillEvaluationPoolSkill,
SkillEvaluationReport,
SkillEvaluationRuntimeConfiguration,
SkillMutationBatch,
SkillRetrievalEvaluationResult,
ValidationReport,
} from "./contracts.ts";
Expand All @@ -70,6 +71,7 @@ export type EvolutionArtifact =
| SkillDraft
| SkillDraftValidationReport
| SkillEvaluationReport
| SkillMutationBatch
| DeferredSkillCandidateFinding
| ValidationReport;

Expand Down Expand Up @@ -504,6 +506,7 @@ export interface EvolutionCursorStore {
}

export interface EvolutionLeaseStore {
assertHeld(lease: EvolutionLeaseToken): Promise<void>;
acquire(
kind: EvolutionLeaseToken["kind"],
key: string,
Expand Down
Loading
Loading