Skip to main content

Items Module

Overview

The Items module in @ever-works/agent handles individual item lifecycle within a work -- submission, removal, metadata updates, and content enrichment. Items are the fundamental content units of a work, stored as structured data in per-item works within the Git-backed data repository.

The module supports two workflow modes for item modifications: direct-commit (changes are pushed to the main branch immediately) and PR-based (changes are submitted as pull requests for review). The PR-based workflow integrates with the community PR processing system for external contributions.

Module Structure

packages/agent/src/
items-generator/
item-submission.service.ts # Core item submission, removal, update
items-generator.module.ts # NestJS module definition
generators/
data-generator/
data-repository.ts # Item file I/O (data.json, content.md)
services/
work-generation.service.ts # Higher-level item operations (submitItem, removeItem, etc.)
dto/
submit-item.dto.ts # Submission validation

Key Classes and Services

ItemSubmissionService

The core service for item-level operations that manages Git repository interactions:

submitItem(work, user, itemData, options)

Adds a new item to the work:

  1. Clones or pulls the data repository locally
  2. Creates the item work structure (data/<item-slug>/)
  3. Writes data.json (structured metadata) and content.md (markdown description)
  4. If a source_url is provided, attempts to auto-capture a screenshot via the screenshot facade
  5. Commits the changes with a descriptive message
  6. Either pushes directly to main or creates a pull request, based on the autoapproval setting

removeItem(work, user, itemSlug, options)

Removes an item from the work:

  1. Clones or pulls the data repository
  2. Verifies the item work exists
  3. Removes the entire item work
  4. Commits and pushes (direct or PR-based)

updateItem(work, user, itemSlug, metadata, options)

Updates item metadata without changing content:

  1. Clones or pulls the data repository
  2. Reads the existing data.json
  3. Merges in the metadata updates (e.g., featured, order, custom fields)
  4. Writes back and commits

Workflow modes:

ModeBehavior
Direct commitChanges pushed to main branch immediately. Used when the user is the work owner/editor.
PR-basedChanges submitted as a pull request. Used for community contributions or when approval is required.

The mode is determined by the autoapproval option and the user's role in the work.

DataRepository (Item Methods)

Low-level file operations for item data:

  • getItems() -- scan all item works under data/ and parse their data.json files
  • getItem(slug) -- read a single item's data
  • createItemDir(itemData) -- create the data/<slug>/ work
  • writeItem(itemData) -- write data.json with structured fields
  • writeItemMarkdown(itemData, markdown) -- write content.md
  • removeItemDir(slug) -- delete an item work

Item Data Structure

Each item is stored in data/<item-slug>/ with two files:

data.json:

{
"name": "Example Tool",
"slug": "example-tool",
"description": "A brief description of the tool",
"source_url": "https://example.com",
"category": "developer-tools",
"tags": ["open-source", "freemium"],
"images": ["screenshot.png"],
"featured": false,
"order": 0,
"metadata": {}
}

content.md:

# Example Tool

A detailed description of the tool with markdown formatting.

## Features

- Feature 1
- Feature 2

API Reference

ItemSubmissionService

submitItem(
work: Work,
user: User,
itemData: {
name: string;
slug?: string;
description: string;
source_url?: string;
category?: string;
tags?: string[];
content?: string;
},
options?: {
autoapproval?: boolean;
prTitle?: string;
prBody?: string;
}
): Promise<{ slug: string; prUrl?: string }>

removeItem(
work: Work,
user: User,
itemSlug: string,
options?: { autoapproval?: boolean }
): Promise<{ prUrl?: string }>

updateItem(
work: Work,
user: User,
itemSlug: string,
metadata: {
featured?: boolean;
order?: number;
[key: string]: unknown;
},
options?: { autoapproval?: boolean }
): Promise<void>

WorkGenerationService (Item Operations)

Higher-level wrappers that add validation, notifications, and item count tracking:

submitItem(work: Work, user: User, itemData: SubmitItemDto): Promise<void>
removeItem(work: Work, user: User, itemSlug: string): Promise<void>
updateItemMetadata(work: Work, user: User, slug: string, metadata: object): Promise<void>
extractItemDetails(work: Work, user: User, url: string): Promise<ExtractedItemDetails>

Configuration

Auto-Screenshot Capture

When a source_url is provided during item submission, the system attempts to capture a screenshot if the screenshot facade is configured. The captured image is saved to the item's work and referenced in data.json.

This behavior is automatic and requires no configuration beyond having a screenshot provider plugin enabled (e.g., screenshotone, urlbox).

PR-Based Workflow Settings

PR-based submission is controlled by:

  • The autoapproval option on the submission call
  • The user's role in the work (owners/editors default to direct commit)
  • The work's communityPrEnabled setting (enables external PR processing)

Item Slug Generation

If no slug is provided, it is auto-generated from the item name using slugifyText(). Slugs must be unique within a work -- the service checks for existing item works before creating.

Dependencies

DependencyPurpose
@ever-works/agent/facadesGitFacadeService for repository operations, ScreenshotFacadeService for auto-capture
@ever-works/agent/generatorsDataRepository for item file I/O
@ever-works/agent/utilsslugifyText for slug generation
isomorphic-gitLocal git clone, commit, push operations

Usage Examples

Submitting a New Item

import { ItemSubmissionService } from '@ever-works/agent/items-generator';

const result = await submissionService.submitItem(
work,
user,
{
name: 'VS Code',
description: 'A powerful code editor by Microsoft',
source_url: 'https://code.visualstudio.com',
category: 'developer-tools',
tags: ['editor', 'open-source', 'microsoft']
},
{ autoapproval: true }
);

console.log(`Item created: ${result.slug}`); // 'vs-code'

Removing an Item

await submissionService.removeItem(work, user, 'vs-code', {
autoapproval: true
});

Submitting via Pull Request

const result = await submissionService.submitItem(
work,
user,
{
name: 'New Tool',
description: 'A new tool to add',
source_url: 'https://newtool.dev'
},
{
autoapproval: false,
prTitle: 'Add New Tool to work',
prBody: 'This tool provides...'
}
);

console.log(`PR created: ${result.prUrl}`);

Updating Item Metadata

await submissionService.updateItem(work, user, 'vs-code', {
featured: true,
order: 1
});