Implement OpenSpec artifacts and SDK contracts

This commit is contained in:
Anthony Ettinger 2026-06-06 16:44:58 +00:00
parent 1aa67367b8
commit 17942eef57
16 changed files with 486 additions and 21 deletions

View file

@ -15,8 +15,8 @@ apps/
packages/ packages/
cli logicsrc OpenSpec CLI, also exposed as commandboard/cb cli logicsrc OpenSpec CLI, also exposed as commandboard/cb
logicsrc-mcp @profullstack/logicsrc-mcp standards MCP server logicsrc-mcp @profullstack/logicsrc-mcp standards MCP server
sdk SDK contract types and helpers
tui terminal UI tui terminal UI
sdk planned Rust, Bun, Node, Python, and curl SDK surfaces
schemas LogicSRC JSON schemas schemas LogicSRC JSON schemas
validators schema validation utilities validators schema validation utilities
plugin-core plugin manifest and loader runtime plugin-core plugin manifest and loader runtime
@ -36,6 +36,8 @@ scripts/
npm install npm install
npm run check npm run check
npm --workspace @logicsrc/cli run dev -- --openspec agentswarm --yolo --repo profullstack/logicsrc npm --workspace @logicsrc/cli run dev -- --openspec agentswarm --yolo --repo profullstack/logicsrc
npm --workspace @logicsrc/cli run dev -- openspec import
npm --workspace @logicsrc/cli run dev -- openspec export --out logicsrc-openspec-summary.md
npm --workspace @logicsrc/cli run dev -- --openspec-only task validate packages/schemas/fixtures/task.yaml npm --workspace @logicsrc/cli run dev -- --openspec-only task validate packages/schemas/fixtures/task.yaml
npm --workspace @logicsrc/cli run dev -- agentswarm --yolo --repo profullstack/logicsrc npm --workspace @logicsrc/cli run dev -- agentswarm --yolo --repo profullstack/logicsrc
npm --workspace @logicsrc/cli run dev -- plugins npm --workspace @logicsrc/cli run dev -- plugins

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>LogicSRC Blog</title>
<link>https://logicsrc.com/blog</link>
<description>Project notes for LogicSRC OpenSpec standards, AgentSwarm, AgentByte, SDKs, MCP, and reference implementations.</description>
<language>en-us</language>
<atom:link href="https://logicsrc.com/blog/rss.xml" rel="self" type="application/rss+xml" />
<item>
<title>LogicSRC OpenSpec Compatibility</title>
<link>https://logicsrc.com/openspec</link>
<guid>https://logicsrc.com/openspec</guid>
<description>LogicSRC adds an OpenSpec.dev comparison and compatibility mode for repo-local specs, proposals, tasks, and deltas.</description>
<pubDate>Sat, 06 Jun 2026 00:00:00 GMT</pubDate>
</item>
</channel>
</rss>

View file

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://logicsrc.com/</loc>
<changefreq>weekly</changefreq>
<priority>1.0</priority>
</url>
<url>
<loc>https://logicsrc.com/docs</loc>
<changefreq>weekly</changefreq>
<priority>0.9</priority>
</url>
<url>
<loc>https://logicsrc.com/openspec</loc>
<changefreq>weekly</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>https://logicsrc.com/agent-swarm</loc>
<changefreq>weekly</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>https://logicsrc.com/agentbyte</loc>
<changefreq>weekly</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>https://logicsrc.com/blog</loc>
<changefreq>weekly</changefreq>
<priority>0.7</priority>
</url>
<url>
<loc>https://logicsrc.com/about</loc>
<changefreq>monthly</changefreq>
<priority>0.6</priority>
</url>
<url>
<loc>https://logicsrc.com/terms</loc>
<changefreq>monthly</changefreq>
<priority>0.4</priority>
</url>
<url>
<loc>https://logicsrc.com/privacy</loc>
<changefreq>monthly</changefreq>
<priority>0.4</priority>
</url>
</urlset>

View file

@ -1,6 +1,6 @@
import { accessSync } from "node:fs"; import { accessSync } from "node:fs";
for (const file of ["index.html", "public/manifest.webmanifest", "public/icon.svg", "public/service-worker.js", "src/main.ts", "src/styles.css"]) { for (const file of ["index.html", "public/manifest.webmanifest", "public/icon.svg", "public/service-worker.js", "public/sitemap.xml", "public/blog/rss.xml", "src/main.ts", "src/styles.css"]) {
accessSync(new URL(`../${file}`, import.meta.url)); accessSync(new URL(`../${file}`, import.meta.url));
} }

View file

@ -18,7 +18,8 @@ const mimeTypes = {
".json": "application/json; charset=utf-8", ".json": "application/json; charset=utf-8",
".png": "image/png", ".png": "image/png",
".svg": "image/svg+xml", ".svg": "image/svg+xml",
".webmanifest": "application/manifest+json; charset=utf-8" ".webmanifest": "application/manifest+json; charset=utf-8",
".xml": "application/xml; charset=utf-8"
}; };
createServer((request, response) => { createServer((request, response) => {
@ -76,7 +77,7 @@ function sendFile(file, headOnly, response) {
const extension = extname(file); const extension = extname(file);
response.writeHead(200, { response.writeHead(200, {
"cache-control": extension === ".html" ? "no-store" : "public, max-age=31536000, immutable", "cache-control": extension === ".html" || extension === ".xml" ? "no-store" : "public, max-age=31536000, immutable",
"content-type": mimeTypes[extension] ?? "application/octet-stream" "content-type": mimeTypes[extension] ?? "application/octet-stream"
}); });

View file

@ -19,7 +19,7 @@ const schemas = [
const implementations = [ const implementations = [
{ name: "CommandBoard.run", detail: "Hosted reference product implementing the LogicSRC primitives." }, { name: "CommandBoard.run", detail: "Hosted reference product implementing the LogicSRC primitives." },
{ name: "CLI and TUI", detail: "`logicsrc` is the standards CLI; `commandboard` and `cb` remain compatible product aliases." }, { name: "CLI and TUI", detail: "`logicsrc` is the standards CLI; `commandboard` and `cb` remain compatible product aliases." },
{ name: "SDKs", detail: "Planned Rust, Bun, Node, Python, and curl surfaces mirror the same OpenSpec resources." }, { name: "SDKs", detail: "`@logicsrc/sdk` defines contract types now; Rust, Bun, Node, Python, and curl surfaces mirror the same resources." },
{ name: "sh1pt CLI", detail: "`sh1pt logicsrc ...` lets sh1pt users choose LogicSRC OpenSpec-only workflows." }, { name: "sh1pt CLI", detail: "`sh1pt logicsrc ...` lets sh1pt users choose LogicSRC OpenSpec-only workflows." },
{ name: "Reference API", detail: "Sample REST API available under `/api/*` for contract testing." }, { name: "Reference API", detail: "Sample REST API available under `/api/*` for contract testing." },
{ name: "Plugins", detail: "CoinPay, uGig, and sh1pt adapters prove the plugin manifest shape." } { name: "Plugins", detail: "CoinPay, uGig, and sh1pt adapters prove the plugin manifest shape." }
@ -56,7 +56,7 @@ const comparisonRows = [
}, },
{ {
area: "Artifacts", area: "Artifacts",
logicsrc: "Schemas, plugin manifests, task/agent/run docs, event contracts, SDKs, MCP resources, CLI/TUI/PWA/API surfaces.", logicsrc: "Schemas, plugin manifests, task/agent/run docs, event contracts, `@logicsrc/sdk`, MCP resources, CLI/TUI/PWA/API surfaces.",
openspec: "Repo-local specs, proposals, design docs, implementation tasks, and spec deltas." openspec: "Repo-local specs, proposals, design docs, implementation tasks, and spec deltas."
}, },
{ {
@ -243,7 +243,7 @@ sh1pt logicsrc --openspec-only \\
sh1pt logicsrc --openspec \\ sh1pt logicsrc --openspec \\
agentswarm --yolo</code></pre> agentswarm --yolo</code></pre>
<p><code>--openspec</code> enables OpenSpec.dev-compatible repo-local specs, proposals, tasks, and deltas where supported. <code>--openspec-only</code> restricts work to LogicSRC-published contracts.</p> <p><code>--openspec</code> enables OpenSpec.dev-compatible repo-local specs, proposals, tasks, and deltas where supported. <code>openspec import</code> and <code>openspec export</code> summarize those artifacts for LogicSRC workflows. <code>--openspec-only</code> restricts work to LogicSRC-published contracts.</p>
</div> </div>
</section> </section>

View file

@ -41,6 +41,7 @@ task
wallet wallet
events events
agentswarm agentswarm
openspec
plugins plugins
tui tui
update / upgrade update / upgrade
@ -57,6 +58,16 @@ sh1pt logicsrc --openspec-only agentswarm --yolo --repo profullstack/logicsrc
`agentswarm --yolo` opens the master agent flow. The master agent coordinates slave agents for scoped work such as reproduction, patching, review, documentation, and release evidence. `agentswarm --yolo` opens the master agent flow. The master agent coordinates slave agents for scoped work such as reproduction, patching, review, documentation, and release evidence.
OpenSpec-compatible artifact commands:
```bash
logicsrc openspec import
logicsrc openspec export --out logicsrc-openspec-summary.md
logicsrc openspec change --id add-agent-policy --capability agents
```
When `--openspec` is enabled, AgentSwarm writes OpenSpec.dev-style files under `openspec/changes/<change-id>/`.
Machine-readable output should be available anywhere data is returned: Machine-readable output should be available anywhere data is returned:
```bash ```bash

View file

@ -21,9 +21,13 @@ The projects can be complementary. LogicSRC should support an `--openspec` compa
```bash ```bash
logicsrc --openspec agentswarm --yolo --repo profullstack/logicsrc logicsrc --openspec agentswarm --yolo --repo profullstack/logicsrc
logicsrc openspec import
logicsrc openspec export --out logicsrc-openspec-summary.md
logicsrc --openspec-only task validate ./task.yaml logicsrc --openspec-only task validate ./task.yaml
sh1pt logicsrc --openspec agentswarm --yolo --repo profullstack/logicsrc sh1pt logicsrc --openspec agentswarm --yolo --repo profullstack/logicsrc
``` ```
- `--openspec` enables OpenSpec.dev-compatible repo-local planning conventions where supported. - `--openspec` enables OpenSpec.dev-compatible repo-local planning conventions where supported.
- `--openspec-only` restricts work to LogicSRC-published OpenSpec contracts. - `--openspec-only` restricts work to LogicSRC-published OpenSpec contracts.
- `openspec import` summarizes repo-local OpenSpec.dev-style specs and changes.
- `openspec export` writes a LogicSRC-readable markdown summary of those artifacts.

11
package-lock.json generated
View file

@ -1003,6 +1003,10 @@
"resolved": "packages/schemas", "resolved": "packages/schemas",
"link": true "link": true
}, },
"node_modules/@logicsrc/sdk": {
"resolved": "packages/sdk",
"link": true
},
"node_modules/@logicsrc/tui": { "node_modules/@logicsrc/tui": {
"resolved": "packages/tui", "resolved": "packages/tui",
"link": true "link": true
@ -4692,6 +4696,13 @@
"name": "@logicsrc/schemas", "name": "@logicsrc/schemas",
"version": "0.1.0" "version": "0.1.0"
}, },
"packages/sdk": {
"name": "@logicsrc/sdk",
"version": "0.1.0",
"devDependencies": {
"vitest": "^4.0.8"
}
},
"packages/tui": { "packages/tui": {
"name": "@logicsrc/tui", "name": "@logicsrc/tui",
"version": "0.1.0", "version": "0.1.0",

View file

@ -12,7 +12,7 @@
"apps/*" "apps/*"
], ],
"scripts": { "scripts": {
"build": "npm --workspace @logicsrc/schemas run build && npm --workspace @logicsrc/validators run build && npm --workspace @logicsrc/plugin-core run build && npm --workspace @logicsrc/plugin-coinpay run build && npm --workspace @logicsrc/plugin-ugig run build && npm --workspace @logicsrc/plugin-sh1pt run build && npm --workspace @logicsrc/tui run build && npm --workspace @logicsrc/cli run build && npm --workspace @profullstack/logicsrc-mcp run build && npm --workspace @logicsrc/commandboard-api run build && npm --workspace @logicsrc/commandboard-web run build && npm --workspace @logicsrc/web run build", "build": "npm --workspace @logicsrc/schemas run build && npm --workspace @logicsrc/validators run build && npm --workspace @logicsrc/sdk run build && npm --workspace @logicsrc/plugin-core run build && npm --workspace @logicsrc/plugin-coinpay run build && npm --workspace @logicsrc/plugin-ugig run build && npm --workspace @logicsrc/plugin-sh1pt run build && npm --workspace @logicsrc/tui run build && npm --workspace @logicsrc/cli run build && npm --workspace @profullstack/logicsrc-mcp run build && npm --workspace @logicsrc/commandboard-api run build && npm --workspace @logicsrc/commandboard-web run build && npm --workspace @logicsrc/web run build",
"start": "npm --workspace @logicsrc/web run start", "start": "npm --workspace @logicsrc/web run start",
"test": "npm run test --workspaces --if-present", "test": "npm run test --workspaces --if-present",
"check": "npm run build && npm run test", "check": "npm run build && npm run test",

View file

@ -6,6 +6,7 @@ import { renderPluginStatus, renderTui } from "@logicsrc/tui";
import { assertSchemaKind, parseDocument, validate } from "@logicsrc/validators"; import { assertSchemaKind, parseDocument, validate } from "@logicsrc/validators";
import { boards, tasks } from "./fixtures.js"; import { boards, tasks } from "./fixtures.js";
import { print, type OutputFormat } from "./format.js"; import { print, type OutputFormat } from "./format.js";
import { exportOpenSpecSummary, importOpenSpec, writeOpenSpecChange } from "./openspec.js";
import { defaultPluginRegistry } from "./registry.js"; import { defaultPluginRegistry } from "./registry.js";
const program = new Command(); const program = new Command();
@ -134,6 +135,8 @@ program
.option("--yolo", "Start the master agent with autonomous execution enabled.") .option("--yolo", "Start the master agent with autonomous execution enabled.")
.option("--repo <repo>", "Target repository, for example profullstack/logicsrc") .option("--repo <repo>", "Target repository, for example profullstack/logicsrc")
.option("--agents <agents>", "Comma-separated slave agent roles", "reproduce,patch,review") .option("--agents <agents>", "Comma-separated slave agent roles", "reproduce,patch,review")
.option("--change <id>", "OpenSpec-compatible change id", "agentswarm-yolo")
.option("--out <dir>", "OpenSpec-compatible output directory")
.action((options) => { .action((options) => {
if (!options.yolo) { if (!options.yolo) {
console.log("AgentSwarm is coming soon. Run `logicsrc agentswarm --yolo` to open the master agent flow."); console.log("AgentSwarm is coming soon. Run `logicsrc agentswarm --yolo` to open the master agent flow.");
@ -145,21 +148,69 @@ program
.map((agent) => agent.trim()) .map((agent) => agent.trim())
.filter(Boolean); .filter(Boolean);
print( const openspecCompatible = program.opts().openspec || process.env.LOGICSRC_OPENSPEC_COMPAT === "1";
{ const openspecArtifacts = openspecCompatible
? writeOpenSpecChange({
id: options.change,
title: "AgentSwarm YOLO Session",
summary: "Open a LogicSRC AgentSwarm master agent session and coordinate scoped slave agents.",
capability: "agentswarm",
repo: options.repo,
agents: slaveAgents,
outDir: options.out
})
: null;
print({
type: "logicsrc.agentswarm.session", type: "logicsrc.agentswarm.session",
status: "opening", status: "opening",
mode: "yolo", mode: "yolo",
master_agent: "agentswarm-master", master_agent: "agentswarm-master",
slave_agents: slaveAgents, slave_agents: slaveAgents,
repo: options.repo ?? null, repo: options.repo ?? null,
openspec_compatible: program.opts().openspec || process.env.LOGICSRC_OPENSPEC_COMPAT === "1", openspec_compatible: openspecCompatible,
openspec_only: program.opts().openspecOnly || process.env.LOGICSRC_OPENSPEC_ONLY === "1" openspec_only: program.opts().openspecOnly || process.env.LOGICSRC_OPENSPEC_ONLY === "1",
}, openspec_artifacts: openspecArtifacts
"json" }, "json");
);
}); });
const openspec = program.command("openspec").description("Import, export, and generate OpenSpec.dev-compatible repo-local planning artifacts.");
openspec
.command("import")
.argument("[root]", "OpenSpec root directory", "openspec")
.option("--format <format>", "table, json, or markdown", "json")
.description("Read OpenSpec.dev-style specs and changes from a repo.")
.action((root, options) => print(importOpenSpec(root), options.format as OutputFormat));
openspec
.command("export")
.argument("[root]", "OpenSpec root directory", "openspec")
.option("--out <file>", "Write a markdown summary", "logicsrc-openspec-summary.md")
.description("Export OpenSpec.dev-style repo artifacts into a LogicSRC-readable summary.")
.action((root, options) => {
const outFile = exportOpenSpecSummary(importOpenSpec(root), options.out);
console.log(`Wrote ${outFile}`);
});
openspec
.command("change")
.option("--id <id>", "Change id", "logic-src-change")
.option("--title <title>", "Change title", "LogicSRC OpenSpec Change")
.option("--summary <summary>", "Change summary", "Describe a LogicSRC-compatible change.")
.option("--capability <capability>", "Capability/spec id", "logicsrc")
.option("--repo <repo>", "Target repository")
.option("--out <dir>", "Output directory")
.description("Create an OpenSpec.dev-style proposal/design/tasks/spec delta.")
.action((options) => print(writeOpenSpecChange({
id: options.id,
title: options.title,
summary: options.summary,
capability: options.capability,
repo: options.repo,
outDir: options.out
}), "json"));
program.command("plugins").option("--format <format>", "table, json, or markdown", "table").description("Show plugin status.").action((options) => { program.command("plugins").option("--format <format>", "table, json, or markdown", "table").description("Show plugin status.").action((options) => {
const snapshot = defaultPluginRegistry().snapshot(); const snapshot = defaultPluginRegistry().snapshot();
print(snapshot.plugins, options.format as OutputFormat); print(snapshot.plugins, options.format as OutputFormat);

View file

@ -0,0 +1,176 @@
import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
import { basename, join } from "node:path";
export interface OpenSpecChangeInput {
id: string;
title: string;
summary: string;
capability: string;
repo?: string;
agents?: string[];
outDir?: string;
tasks?: string[];
}
export interface OpenSpecImportSummary {
root: string;
specs: Array<{ id: string; path: string; title: string }>;
changes: Array<{ id: string; path: string; files: string[] }>;
}
export function writeOpenSpecChange(input: OpenSpecChangeInput) {
const root = input.outDir ?? join("openspec", "changes", input.id);
const specRoot = join(root, "specs", input.capability);
mkdirSync(specRoot, { recursive: true });
const tasks = input.tasks?.length ? input.tasks : [
"Review existing LogicSRC schemas and CLI conventions.",
"Open the AgentSwarm master agent session.",
"Assign slave agents to reproduction, patching, review, and evidence.",
"Export audit artifacts back into LogicSRC run/event documents."
];
const proposal = `# ${input.title}
## Summary
${input.summary}
## Repository
${input.repo ?? "not specified"}
## Compatibility
This change uses OpenSpec.dev-style repo-local planning artifacts while preserving LogicSRC task, agent, run, event, plugin, SDK, MCP, CLI, TUI, PWA, and API contract names.
`;
const design = `# ${input.title} Design
## Architecture
- A master agent owns the session goal, policy, and final decision packet.
- Slave agents execute scoped work such as reproduction, patching, review, documentation, and release evidence.
- LogicSRC records agent runs, model/tool use, artifacts, audit events, and schema versions.
## OpenSpec Compatibility
OpenSpec-compatible files stay under \`openspec/changes/${input.id}\` and can be reviewed through normal git workflows.
`;
const taskList = tasks.map((task, index) => `- [ ] ${index + 1}. ${task}`).join("\n");
const spec = `# ${input.capability} Specification
## Purpose
${input.summary}
## Requirements
### Requirement: Master agent session
The system SHALL create a master agent session that can coordinate scoped slave agents.
#### Scenario: YOLO AgentSwarm session
- GIVEN a repository target${input.repo ? ` of \`${input.repo}\`` : ""}
- WHEN \`logicsrc --openspec agentswarm --yolo\` runs
- THEN create OpenSpec-compatible proposal, design, task, and spec-delta artifacts
- AND keep LogicSRC audit and run contracts available for export
### Requirement: Slave agent coordination
The system SHALL record slave agent roles for reproducible review.
#### Scenario: Declared slave agents
- GIVEN slave agents ${input.agents?.length ? input.agents.map((agent) => `\`${agent}\``).join(", ") : "are declared"}
- WHEN the session opens
- THEN include those roles in the LogicSRC session output
- AND include them in the repo-local OpenSpec artifacts
`;
const files = [
{ path: join(root, "proposal.md"), content: proposal },
{ path: join(root, "design.md"), content: design },
{ path: join(root, "tasks.md"), content: `# ${input.title} Tasks\n\n${taskList}\n` },
{ path: join(specRoot, "spec.md"), content: spec }
];
for (const file of files) {
writeFileSync(file.path, file.content);
}
return {
id: input.id,
root,
files: files.map((file) => file.path)
};
}
export function importOpenSpec(root = "openspec"): OpenSpecImportSummary {
const specsRoot = join(root, "specs");
const changesRoot = join(root, "changes");
const specs = existsSync(specsRoot)
? listDirectories(specsRoot).map((directory) => {
const specPath = join(specsRoot, directory, "spec.md");
return {
id: directory,
path: specPath,
title: readMarkdownTitle(specPath) ?? directory
};
})
: [];
const changes = existsSync(changesRoot)
? listDirectories(changesRoot).map((directory) => {
const changePath = join(changesRoot, directory);
return {
id: directory,
path: changePath,
files: listFiles(changePath).map((file) => file.slice(changePath.length + 1))
};
})
: [];
return { root, specs, changes };
}
export function exportOpenSpecSummary(summary: OpenSpecImportSummary, outFile: string) {
const markdown = `# OpenSpec Import Summary
Root: \`${summary.root}\`
## Specs
${summary.specs.length ? summary.specs.map((spec) => `- \`${spec.id}\`${spec.title} (${spec.path})`).join("\n") : "- none"}
## Changes
${summary.changes.length ? summary.changes.map((change) => `- \`${change.id}\`${change.files.length} file(s) (${change.path})`).join("\n") : "- none"}
`;
writeFileSync(outFile, markdown);
return outFile;
}
function listDirectories(root: string) {
return readdirSync(root).filter((entry) => statSync(join(root, entry)).isDirectory()).sort();
}
function listFiles(root: string): string[] {
const entries = readdirSync(root);
return entries.flatMap((entry) => {
const path = join(root, entry);
return statSync(path).isDirectory() ? listFiles(path) : [path];
}).sort();
}
function readMarkdownTitle(path: string) {
if (!existsSync(path)) {
return null;
}
const line = readFileSync(path, "utf8").split(/\r?\n/).find((entry) => entry.startsWith("# "));
return line ? line.replace(/^#\s+/, "").trim() : basename(path);
}

15
packages/sdk/package.json Normal file
View file

@ -0,0 +1,15 @@
{
"name": "@logicsrc/sdk",
"version": "0.1.0",
"description": "LogicSRC SDK contract types and client interface.",
"type": "module",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"scripts": {
"build": "tsc -p tsconfig.json",
"test": "vitest run src"
},
"devDependencies": {
"vitest": "^4.0.8"
}
}

View file

@ -0,0 +1,31 @@
import { describe, expect, it } from "vitest";
import { createAgentSwarmSession, createTask } from "./index.js";
describe("LogicSRC SDK contract helpers", () => {
it("creates task documents with LogicSRC defaults", () => {
expect(createTask({
title: "Document SDK",
description: "Add SDK contract helpers.",
board: "/docs",
creator_did: "did:example:alice"
})).toMatchObject({
type: "logicsrc.task",
version: "0.1",
status: "draft"
});
});
it("creates AgentSwarm session documents", () => {
expect(createAgentSwarmSession({
repo: "profullstack/logicsrc",
agents: ["reproduce", "patch"],
yolo: true,
openspec: true
})).toMatchObject({
type: "logicsrc.agentswarm.session",
mode: "yolo",
openspec_compatible: true,
slave_agents: ["reproduce", "patch"]
});
});
});

90
packages/sdk/src/index.ts Normal file
View file

@ -0,0 +1,90 @@
export type LogicSrcId = string;
export interface LogicSrcTask {
type: "logicsrc.task";
version: string;
title: string;
description: string;
board: string;
creator_did: string;
status: "draft" | "open" | "funded" | "claimed" | "submitted" | "approved" | "rejected" | "disputed" | "closed";
budget?: {
amount: number;
currency: string;
};
assignee_did?: string;
}
export interface LogicSrcAgent {
type: "logicsrc.agent";
id: LogicSrcId;
name: string;
capabilities: string[];
logicsrc_compatibility_version?: string;
}
export interface LogicSrcRun {
type: "logicsrc.agent_run";
id: LogicSrcId;
agent_id: LogicSrcId;
status: "queued" | "running" | "succeeded" | "failed" | "canceled";
task_id?: LogicSrcId;
}
export interface LogicSrcEvent {
type: "logicsrc.event";
event: string;
resource_id: LogicSrcId;
created_at?: string;
}
export interface AgentSwarmSession {
type: "logicsrc.agentswarm.session";
status: "opening" | "active" | "paused" | "completed" | "failed";
mode: "yolo" | "review";
master_agent: string;
slave_agents: string[];
repo: string | null;
openspec_compatible: boolean;
openspec_only: boolean;
}
export interface LogicSrcClient {
createTask(input: Omit<LogicSrcTask, "type" | "version" | "status"> & Partial<Pick<LogicSrcTask, "version" | "status">>): Promise<LogicSrcTask>;
validateTask(input: unknown): Promise<{ ok: boolean; errors: string[] }>;
startAgentSwarm(input: {
repo?: string;
agents?: string[];
yolo?: boolean;
openspec?: boolean;
openspecOnly?: boolean;
}): Promise<AgentSwarmSession>;
}
export function createTask(input: Omit<LogicSrcTask, "type" | "version" | "status"> & Partial<Pick<LogicSrcTask, "version" | "status">>): LogicSrcTask {
return {
type: "logicsrc.task",
version: input.version ?? "0.1",
status: input.status ?? "draft",
...input
};
}
export function createAgentSwarmSession(input: {
repo?: string;
agents?: string[];
yolo?: boolean;
openspec?: boolean;
openspecOnly?: boolean;
}): AgentSwarmSession {
return {
type: "logicsrc.agentswarm.session",
status: "opening",
mode: input.yolo ? "yolo" : "review",
master_agent: "agentswarm-master",
slave_agents: input.agents ?? ["reproduce", "patch", "review"],
repo: input.repo ?? null,
openspec_compatible: input.openspec ?? false,
openspec_only: input.openspecOnly ?? false
};
}

View file

@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"rootDir": "src",
"outDir": "dist"
},
"include": ["src/**/*.ts"]
}