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
4 changes: 3 additions & 1 deletion docs/product-name-audit.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ git grep -n -i -E 'kapi|ilchul' -- ':!package-lock.json' ':!node_modules'
| Storage/config | `.ilchul`, `~/.ilchul`, `.kapi` historical references, and `ILCHUL_*` environment variables appear in docs/tests/runtime setup. | storage/config namespace | `.ilchul` is active storage; `.kapi` is legacy evidence only and must not be deleted by this issue. |
| GitHub review integration | `kapi-agent`, `kapi-agent/review`, and `kapi-review` remain literal external integration names. | external integration | Keep literal names while the GitHub App and required checks use them. |
| Documentation/history | README, policy docs, references, and historical explanations still mention Kapi and Ilchul. | documentation/history | New public runtime examples should use `ilchul`; internal implementation examples may use `runctl` / `runtime`; historical and compatibility prose may keep product names with context. |
| Core/domain/application identifiers | Existing exported types and classes such as `KapiRegistryEntry`, `KapiService`, and `KapiStore` remain product-prefixed. The local factory export is now `createLocalWorkflowService`. | known reusable-code leakage reduced by bounded slices | Follow-up slices should rename these by boundary (`RegistryEntry`, `WorkflowService`, `WorkflowStore`, etc.) with compatibility exports where safe. |
| Core/domain/application identifiers | The registry entry type now uses `WorkflowRegistryEntry`; exported classes such as `KapiService` and `KapiStore` remain product-prefixed. The local factory export is now `createLocalWorkflowService`. | known reusable-code leakage reduced by bounded slices | Follow-up slices should rename remaining service/store identifiers by boundary (`WorkflowService`, `WorkflowStore`, etc.) with compatibility exports where safe. |
| Application service filenames | The service implementation and factory now use semantic filenames: `src/application/workflow-service.ts` and `src/adapters/workflow-service-factory.ts`. | internal semantic implementation | Keep imports on the semantic service paths; exported class/function names are intentionally left for a smaller follow-up compatibility slice. |
| CLI worker/runtime helper filenames | Worker event, runtime observation, and GitHub issue context helpers now use semantic filenames: `src/cli/worker-events.ts`, `src/cli/worker-runtime.ts`, and `src/cli/github-issue-context.ts`. | internal semantic implementation | Keep imports on the semantic helper paths; remaining worker event payload names such as `kapi.worker.*` are external event contracts, not filenames. |

Expand All @@ -33,6 +33,8 @@ git grep -n -i -E 'kapi|ilchul' -- ':!package-lock.json' ':!node_modules'
- Application service implementation import paths no longer use `kapi-*` filenames for the generic workflow service and local service factory.
- The local service factory export uses the semantic `createLocalWorkflowService` name instead of `createLocalKapiService`.
- Presentation helper exports use semantic workflow/tool names for generic helpers (`WorkflowToolDefinition`, `shouldBlockWorkflowToolCall`, `formatWorkflowError`).
- PR review state helpers use generic pull-request / agent-review names (`PullRequestReviewState`, `PullRequestReviewView`, `latestAgentReview`, `reviewCheckConclusion`).
- Registry entry types now use the semantic `WorkflowRegistryEntry` name across the domain, adapter, CLI, presentation, and tests.

## Residual scan after service filename rename

Expand Down
24 changes: 12 additions & 12 deletions src/adapters/registry-store.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { KapiRegistryEntry, RegistryActivePointer, RegistryIndex, RegistryListResult } from "../domain/registry.js";
import type { WorkflowRegistryEntry, RegistryActivePointer, RegistryIndex, RegistryListResult } from "../domain/registry.js";
import { fs, isNotFoundError, path } from "./fs-path.js";

const SAFE_REGISTRY_SLUG = /^[a-z0-9](?:[a-z0-9-]{0,62}[a-z0-9])?$/;
Expand All @@ -10,7 +10,7 @@ export function assertSafeRegistrySlug(slug: string): void {
export class FileRegistryStore {
constructor(private readonly rootName = ".ilchul") {}

async saveEntry(baseRepo: string, entry: KapiRegistryEntry, options: { setActive?: boolean } = {}): Promise<void> {
async saveEntry(baseRepo: string, entry: WorkflowRegistryEntry, options: { setActive?: boolean } = {}): Promise<void> {
const file = this.entryPath(baseRepo, entry.slug);
await this.writeJsonAtomic(file, entry);
const entries = await this.listEntries(baseRepo);
Expand All @@ -19,19 +19,19 @@ export class FileRegistryStore {
if (options.setActive) await this.setActive(baseRepo, entry);
}

async loadEntry(baseRepo: string, slug: string): Promise<KapiRegistryEntry | undefined> {
const entry = await this.readJson<KapiRegistryEntry>(this.entryPath(baseRepo, slug));
async loadEntry(baseRepo: string, slug: string): Promise<WorkflowRegistryEntry | undefined> {
const entry = await this.readJson<WorkflowRegistryEntry>(this.entryPath(baseRepo, slug));
if (!entry) return undefined;
return this.validateLoadedEntry(entry, slug);
}

async listEntries(baseRepo: string): Promise<KapiRegistryEntry[]> {
async listEntries(baseRepo: string): Promise<WorkflowRegistryEntry[]> {
return (await this.listEntriesTolerant(baseRepo, { strict: true })).entries;
}

async listEntriesTolerant(baseRepo: string, options: { strict?: boolean } = {}): Promise<RegistryListResult> {
const dir = this.workflowsDir(baseRepo);
const entries: KapiRegistryEntry[] = [];
const entries: WorkflowRegistryEntry[] = [];
const warnings: RegistryListResult["warnings"] = [];
try {
for (const item of await fs.readdir(dir, { withFileTypes: true })) {
Expand All @@ -40,7 +40,7 @@ export class FileRegistryStore {
if (!this.isSafeRegistrySlug(fileSlug)) continue;
const file = path.join(dir, item.name);
try {
const entry = await this.readJson<KapiRegistryEntry>(file);
const entry = await this.readJson<WorkflowRegistryEntry>(file);
if (!entry) continue;
const validEntry = this.validateListedEntry(entry, fileSlug);
if (validEntry) entries.push(validEntry);
Expand All @@ -55,7 +55,7 @@ export class FileRegistryStore {
return { entries: entries.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt) || a.slug.localeCompare(b.slug)), warnings };
}

async setActive(baseRepo: string, entry: KapiRegistryEntry): Promise<void> {
async setActive(baseRepo: string, entry: WorkflowRegistryEntry): Promise<void> {
const active: RegistryActivePointer = {
schemaVersion: 1,
slug: entry.slug,
Expand All @@ -66,7 +66,7 @@ export class FileRegistryStore {
await this.writeJsonAtomic(this.activePath(baseRepo), active);
}

async loadActive(baseRepo: string): Promise<KapiRegistryEntry | undefined> {
async loadActive(baseRepo: string): Promise<WorkflowRegistryEntry | undefined> {
const active = await this.readJson<RegistryActivePointer>(this.activePath(baseRepo));
if (!active) return undefined;
return this.loadEntry(baseRepo, active.slug);
Expand Down Expand Up @@ -106,18 +106,18 @@ export class FileRegistryStore {
return SAFE_REGISTRY_SLUG.test(slug);
}

private validateLoadedEntry(entry: KapiRegistryEntry, expectedSlug: string): KapiRegistryEntry {
private validateLoadedEntry(entry: WorkflowRegistryEntry, expectedSlug: string): WorkflowRegistryEntry {
assertSafeRegistrySlug(entry.slug);
if (entry.slug !== expectedSlug) throw new Error(`Kapi registry entry slug mismatch: expected ${expectedSlug}, found ${entry.slug}`);
return entry;
}

private validateListedEntry(entry: KapiRegistryEntry, fileSlug: string): KapiRegistryEntry | undefined {
private validateListedEntry(entry: WorkflowRegistryEntry, fileSlug: string): WorkflowRegistryEntry | undefined {
if (!this.isSafeRegistrySlug(entry.slug)) return undefined;
return entry.slug === fileSlug ? entry : undefined;
}

private async writeIndex(baseRepo: string, entries: KapiRegistryEntry[]): Promise<void> {
private async writeIndex(baseRepo: string, entries: WorkflowRegistryEntry[]): Promise<void> {
const index: RegistryIndex = {
schemaVersion: 1,
updatedAt: new Date().toISOString(),
Expand Down
Loading
Loading