Journal Entries
MECA Initiative - Phase III Project Plan
2025-06-11
The capstone phase: this plan details the implementation of the full MPI system for dynamic agent operations, a smart 'integrateExperiment' command, and the final 'promote' graduation pipeline to complete the core MECA workflow.
MECA Initiative: Completion of Phases I & II
2025-06-10
A memo from project management to the development team and stakeholders announcing the successful completion of Phases I and II of the MECA Initiative and the official kickoff of Phase III.
MECA Initiative - Phase II Project Plan
2025-06-09
Actionable plan to build the MECA engine. Covers the foundational transactional context (TxContext), the first AST-based helper (addImport), and the flagship 'createExperiment' operation to enable programmatic project scaffolding.
MECA Initiative - Phase I Project Plan
2025-06-08
Actionable plan to build the foundational MECA infrastructure. Covers workspace scaffolding, the core Project abstraction, and a 'hello-world' CLI to validate the entire toolchain.
Project Kickoff: The MECA Initiative
2025-06-07
Kickoff for the Metaprogramming-Enabled Component Architecture (MECA) Initiative
On the Care and Training of Digital Apprentices
2025-06-06
A wry examination of artificial intelligence through the eyes of someone who has seen many promised revolutions come and go.
MECA Initiative - Phase II Project Plan
❦
2025-06-09
meca
project-plan
phase-2
transactional-engine
ast
ts-morph
scaffolding
❦
The objective of Phase II is to evolve the MECA framework from a read-only tool into a state-changing "engine." We will implement the foundational transactional system for managing safe file modifications and build our first high-level, programmatic scaffolding operation. This phase will deliver the first tangible productivity gain by automating the creation of new experiments.
TxContext
: An initial implementation of a transactional context in meca-core
capable of staging and committing file system operations.addImport
helper function that uses ts-morph
to safely add or modify import statements in a TypeScript file.createExperiment
Operation: A complete, end-to-end meca create experiment <name>
command that uses the TxContext
to scaffold a new, well-structured package in the sandbox
.meca create experiment <name>
command executes successfully and creates a new package in the sandbox/
directory.package.json
, src/index.ts
, src/[ComponentName].tsx
, and src/[ComponentName].meta.ts
.addImport
helper function is covered by unit tests within the meca-core
package.createExperiment
are managed through the TxContext
.This task creates the core engine for managing safe state changes. The initial version will focus on aggregating operations and executing them sequentially.
Step 1.1: In packages/meca-core/src/
, create a new file transaction.ts
.
Step 1.2: Define the interfaces for pending operations and the initial TxContext
class.
// packages/meca-core/src/transaction.ts
import * as fs from 'fs/promises';
import * as path from 'path';
type PendingOperation =
| { type: 'CREATE_FILE'; path: string; content: string }
| { type: 'CREATE_DIRECTORY'; path: string };
export class TxContext {
private operations: PendingOperation[] = [];
public stage(op: PendingOperation): void {
this.operations.push(op);
}
public async commit(): Promise<void> {
// NOTE: This initial implementation is not truly atomic.
// It executes operations sequentially.
console.log(`Committing ${this.operations.length} operations...`);
for (const op of this.operations) {
switch (op.type) {
case 'CREATE_DIRECTORY':
await fs.mkdir(op.path, { recursive: true });
console.log(` CREATED DIR: ${op.path}`);
break;
case 'CREATE_FILE':
await fs.mkdir(path.dirname(op.path), { recursive: true });
await fs.writeFile(op.path, op.content);
console.log(` CREATED FILE: ${op.path}`);
break;
}
}
this.operations = []; // Clear operations after commit
}
}
Step 1.3: Modify the Project
class in packages/meca-core/src/index.ts
to include the transaction
method.
// Add to Project class in packages/meca-core/src/index.ts
import { TxContext } from './transaction';
// ... inside the Project class
public async transaction(run: (ctx: TxContext) => Promise<void>): Promise<void> {
const context = new TxContext();
await run(context);
await context.commit();
}
This task integrates ts-morph
to build our first reusable, code-aware tool.
Step 2.1: Install ts-morph
as a dependency in meca-core
:
pnpm add ts-morph -F @meca/core
Step 2.2: In packages/meca-core/src/
, create ast-helpers.ts
and implement the addImport
function.
// packages/meca-core/src/ast-helpers.ts
import { SourceFile } from 'ts-morph';
export interface AddImportParams {
moduleSpecifier: string;
namedImport?: string;
isDefault?: boolean;
}
export function addImport(sourceFile: SourceFile, params: AddImportParams): void {
const { moduleSpecifier, namedImport, isDefault } = params;
const existingDeclaration = sourceFile.getImportDeclaration(moduleSpecifier);
if (existingDeclaration) {
if (isDefault && namedImport && !existingDeclaration.getDefaultImport()) {
existingDeclaration.setDefaultImport(namedImport);
} else if (namedImport) {
const existingNamed = existingDeclaration.getNamedImports().map(ni => ni.getName());
if (!existingNamed.includes(namedImport)) {
existingDeclaration.addNamedImport(namedImport);
}
}
} else {
const newDeclaration = sourceFile.addImportDeclaration({ moduleSpecifier });
if (isDefault && namedImport) {
newDeclaration.setDefaultImport(namedImport);
} else if (namedImport) {
newDeclaration.addNamedImport(namedImport);
}
}
}
Step 2.3: Create a corresponding unit test file ast-helpers.test.ts
to validate the addImport
logic under various conditions (new import, existing import, etc.).
createExperiment
OperationThis task uses the new TxContext
to build the high-level scaffolding feature.
Project
class in packages/meca-core/src/index.ts
, implement the createExperiment
method.
// Add to Project class in packages/meca-core/src/index.ts
// ...
public async createExperiment(name: string): Promise<void> {
const componentName = name.charAt(0).toUpperCase() + name.slice(1).replace(/-/g, '');
const experimentPath = path.join(this.rootPath, 'sandbox', name);
await this.transaction(async (tx) => {
// package.json
tx.stage({
type: 'CREATE_FILE',
path: path.join(experimentPath, 'package.json'),
content: JSON.stringify({ name: name, version: '0.1.0' }, null, 2)
});
// src/index.ts
tx.stage({
type: 'CREATE_FILE',
path: path.join(experimentPath, 'src/index.ts'),
content: `export * from './${componentName}';`
});
// src/[ComponentName].tsx
tx.stage({
type: 'CREATE_FILE',
path: path.join(experimentPath, 'src', `${componentName}.tsx`),
content: `export const ${componentName} = () => <div>${componentName}</div>;`
});
// src/[ComponentName].meta.ts
tx.stage({
type: 'CREATE_FILE',
path: path.join(experimentPath, 'src', `${componentName}.meta.ts`),
content: `// MPI operations for ${componentName} go here\nexport default {};`
});
});
console.log(`Successfully created experiment '${name}' at ${experimentPath}`);
}
createExperiment
into the CLIThis task exposes the new core functionality through the meca
command.
packages/meca-cli/src/index.ts
, add the new command to the commander
program.
// Add to packages/meca-cli/src/index.ts
program
.command('create:experiment <name>')
.description('Scaffolds a new experiment package in the sandbox')
.action(async (name: string) => {
try {
const project = await Project.load(process.cwd());
await project.createExperiment(name);
} catch (error) {
console.error('An error occurred:', error);
process.exit(1);
}
});
This final task ensures all pieces of Phase II work together.
pnpm install
to ensure all dependencies are up to date.pnpm --filter "@meca/*" build
.pnpm exec meca create:experiment my-new-timeline
.sandbox/my-new-timeline
exists and contains the four specified files (package.json
, index.ts
, MyNewTimeline.tsx
, MyNewTimeline.meta.ts
), confirming the successful completion of Phase II.