forgesmith 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,10 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 — Initial real release
4
+
5
+ - `generateReleaseNotes(data, opts, provider)` — LLM-powered release note generation from prism0x2A data
6
+ - `readPrismDirectory(path)` — reads `.prism/` folder structure into `PrismData`
7
+ - `DirectLlmProvider` — Anthropic SDK-backed LLM provider (import from `forgesmith/providers`)
8
+ - `LlmProvider` interface for custom/mock providers
9
+ - ESM + CJS dual-build via tsup
10
+ - 13 unit tests, all green
package/README.md CHANGED
@@ -1,15 +1,53 @@
1
1
  # forgesmith
2
2
 
3
- > Content & asset-generation engine for code intelligence.
4
- >
5
- > *The lens observes. The smith forges.*
3
+ Content & asset-generation engine for code intelligence.
6
4
 
7
- **Status:** Reserved first release follows after prism0x2A v0.3.x ships.
5
+ Forge release notes, blog posts, and social copy from [prism0x2A](https://github.com/dadenjo/prism0x2A) data.
8
6
 
9
- `forgesmith` is the engine library behind [`forge0x2B`](https://github.com/dadenjo/forge0x2B).
10
- It transforms code intelligence from [`prismlens`](https://github.com/dadenjo/prismlens) /
11
- [`prism0x2A`](https://github.com/dadenjo/prism0x2A) into communication-ready content:
12
- release notes, blog posts, social copy, internal updates.
7
+ ## Status
8
+
9
+ **Phase 1** — release-notes generator. More asset-types coming in Phase 2.
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ npm install forgesmith
15
+ ```
16
+
17
+ ## Use
18
+
19
+ ```ts
20
+ import { generateReleaseNotes, readPrismDirectory } from 'forgesmith'
21
+ import { DirectLlmProvider } from 'forgesmith/providers'
22
+
23
+ const data = await readPrismDirectory('./my-project/.prism')
24
+ const provider = new DirectLlmProvider({ apiKey: process.env.ANTHROPIC_KEY })
25
+ const result = await generateReleaseNotes(data, { tone: 'professional' }, provider)
26
+ console.log(result.text)
27
+ ```
28
+
29
+ ## API
30
+
31
+ ### `generateReleaseNotes(data, opts, provider)`
32
+
33
+ Generates release notes from prism data.
34
+
35
+ - `data: PrismData` — sessions, recommendations, insights from prism0x2A
36
+ - `opts: ReleaseNotesOpts` — `tone`, `length`, `format`
37
+ - `provider: LlmProvider` — any compatible LLM provider
38
+
39
+ ### `readPrismDirectory(prismPath)`
40
+
41
+ Reads a `.prism/` folder and returns a `PrismData` object.
42
+
43
+ ### `DirectLlmProvider`
44
+
45
+ Anthropic SDK-backed provider. Import from `forgesmith/providers`.
46
+
47
+ ```ts
48
+ import { DirectLlmProvider } from 'forgesmith/providers'
49
+ const provider = new DirectLlmProvider({ apiKey: '...', model: 'claude-sonnet-4-6' })
50
+ ```
13
51
 
14
52
  ## Architecture
15
53
 
@@ -20,20 +58,10 @@ prism0x2A (dashboard — persists .prism/ data)
20
58
 
21
59
  forgesmith (this — forges assets from data)
22
60
 
23
- forge0x2B (dashboard product for marketing/comms)
61
+ forge0x2B (dashboard for marketing/comms)
24
62
  ```
25
63
 
26
- ## Naming
27
-
28
- - **prismlens** *observes* — splits code into spectral analysis
29
- - **forgesmith** *produces* — takes the analysis and hammers out content
30
-
31
- Engines in this family carry **craft-appropriate** suffixes, not a forced uniform suffix.
32
-
33
- ## Companion repos
64
+ ## Related
34
65
 
35
- | Repo | Role |
36
- |---|---|
37
- | [`prismlens`](https://github.com/dadenjo/prismlens) | Code-intelligence engine |
38
- | [`prism0x2A`](https://github.com/dadenjo/prism0x2A) | Code-intelligence dashboard |
39
- | [`forge0x2B`](https://github.com/dadenjo/forge0x2B) | Content/comms dashboard |
66
+ - [prism0x2A](https://www.npmjs.com/package/prism0x2a) the intelligence layer
67
+ - [forge0x2B](https://www.npmjs.com/package/forge0x2b) — the dashboard that uses this engine
package/dist/index.cjs ADDED
@@ -0,0 +1,105 @@
1
+ 'use strict';
2
+
3
+ var fs = require('fs/promises');
4
+ var path = require('path');
5
+
6
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
+
8
+ var fs__default = /*#__PURE__*/_interopDefault(fs);
9
+ var path__default = /*#__PURE__*/_interopDefault(path);
10
+
11
+ // src/generators/releaseNotes.ts
12
+ function buildSystemPrompt() {
13
+ return `You are a technical writer and developer-relations expert. You generate clear, accurate release notes from structured code-intelligence data. Write only the release notes \u2014 no preamble, no meta-commentary.`;
14
+ }
15
+ function buildUserPrompt(data, opts) {
16
+ const tone = opts.tone ?? "professional";
17
+ const length = opts.length ?? "medium";
18
+ const format = opts.format ?? "markdown";
19
+ const lengthGuide = { short: "2-3 paragraphs or bullet groups", medium: "4-6 sections", long: "comprehensive, 6+ sections with details" }[length];
20
+ const toneGuide = { professional: "formal, clear, business-appropriate", casual: "friendly, approachable, conversational", technical: "precise, implementation-focused, developer-centric" }[tone];
21
+ const hasSessions = (data.sessions?.length ?? 0) > 0;
22
+ const hasRecs = (data.recommendations?.length ?? 0) > 0;
23
+ const hasInsights = (data.insights?.length ?? 0) > 0;
24
+ if (!hasSessions && !hasRecs && !hasInsights) {
25
+ return `Generate a brief release note in ${format} format stating there are no changes to report in this period${data.fromDate ? ` (${data.fromDate} to ${data.toDate ?? "now"})` : ""}.`;
26
+ }
27
+ const lines = [];
28
+ lines.push(`Generate release notes with the following requirements:`);
29
+ lines.push(`- Tone: ${tone} (${toneGuide})`);
30
+ lines.push(`- Length: ${length} (${lengthGuide})`);
31
+ lines.push(`- Format: ${format}`);
32
+ if (data.fromDate) lines.push(`- Period: ${data.fromDate}${data.toDate ? ` to ${data.toDate}` : " to now"}`);
33
+ lines.push(``);
34
+ if (hasSessions) {
35
+ lines.push(`## Sessions (${data.sessions.length})`);
36
+ for (const s of data.sessions) {
37
+ lines.push(`- **${s.title}**${s.summary ? `: ${s.summary}` : ""}${s.conclusion ? ` | Conclusion: ${s.conclusion}` : ""}`);
38
+ }
39
+ lines.push(``);
40
+ }
41
+ if (hasRecs) {
42
+ lines.push(`## Recommendations (${data.recommendations.length})`);
43
+ for (const r of data.recommendations) {
44
+ const accepted = r.accepted === true ? " [ACCEPTED]" : r.accepted === false ? " [DECLINED]" : "";
45
+ lines.push(`- [${r.severity?.toUpperCase() ?? "INFO"}${accepted}] **${r.title}**${r.description ? `: ${r.description}` : ""}`);
46
+ }
47
+ lines.push(``);
48
+ }
49
+ if (hasInsights) {
50
+ lines.push(`## Insights (${data.insights.length})`);
51
+ for (const i of data.insights) {
52
+ lines.push(`- **${i.title}**${i.body ? `: ${i.body}` : ""}`);
53
+ }
54
+ lines.push(``);
55
+ }
56
+ return lines.join("\n");
57
+ }
58
+ async function generateReleaseNotes(data, opts, provider) {
59
+ const systemPrompt = buildSystemPrompt();
60
+ const userPrompt = buildUserPrompt(data, opts);
61
+ const response = await provider.complete({
62
+ systemPrompt,
63
+ messages: [{ role: "user", content: userPrompt }],
64
+ maxTokens: 2048
65
+ });
66
+ return {
67
+ text: response.content,
68
+ metadata: {
69
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
70
+ usedTokens: response.usedTokens,
71
+ generator: "forgesmith"
72
+ }
73
+ };
74
+ }
75
+ async function readJsonFiles(dir) {
76
+ try {
77
+ const entries = await fs__default.default.readdir(dir);
78
+ const results = [];
79
+ for (const entry of entries) {
80
+ if (!entry.endsWith(".json")) continue;
81
+ try {
82
+ const raw = await fs__default.default.readFile(path__default.default.join(dir, entry), "utf-8");
83
+ results.push(JSON.parse(raw));
84
+ } catch {
85
+ }
86
+ }
87
+ return results;
88
+ } catch {
89
+ return [];
90
+ }
91
+ }
92
+ async function readPrismDirectory(prismPath) {
93
+ const sessionsDir = path__default.default.join(prismPath, "sessions");
94
+ const recsDir = path__default.default.join(prismPath, "recommendations");
95
+ const insightsDir = path__default.default.join(prismPath, "green", "insights", "accepted");
96
+ const [sessions, recommendations, insights] = await Promise.all([
97
+ readJsonFiles(sessionsDir),
98
+ readJsonFiles(recsDir),
99
+ readJsonFiles(insightsDir)
100
+ ]);
101
+ return { sessions, recommendations, insights };
102
+ }
103
+
104
+ exports.generateReleaseNotes = generateReleaseNotes;
105
+ exports.readPrismDirectory = readPrismDirectory;
@@ -0,0 +1,63 @@
1
+ interface PrismSession {
2
+ id: string;
3
+ title: string;
4
+ summary?: string;
5
+ conclusion?: string;
6
+ createdAt?: string;
7
+ }
8
+ interface PrismRecommendation {
9
+ id: string;
10
+ title: string;
11
+ severity?: "low" | "medium" | "high" | "critical";
12
+ accepted?: boolean;
13
+ description?: string;
14
+ }
15
+ interface PrismInsight {
16
+ id: string;
17
+ title: string;
18
+ body?: string;
19
+ }
20
+ interface PrismData {
21
+ sessions?: PrismSession[];
22
+ recommendations?: PrismRecommendation[];
23
+ insights?: PrismInsight[];
24
+ fromDate?: string;
25
+ toDate?: string;
26
+ }
27
+ interface ReleaseNotesOpts {
28
+ tone?: "professional" | "casual" | "technical";
29
+ length?: "short" | "medium" | "long";
30
+ format?: "markdown" | "plain";
31
+ }
32
+ interface GenerationResult {
33
+ text: string;
34
+ metadata: {
35
+ generatedAt: string;
36
+ usedTokens: number;
37
+ generator: "forgesmith";
38
+ };
39
+ }
40
+
41
+ interface LlmMessage {
42
+ role: "user" | "assistant";
43
+ content: string;
44
+ }
45
+ interface LlmRequest {
46
+ model?: string;
47
+ messages: LlmMessage[];
48
+ maxTokens?: number;
49
+ systemPrompt?: string;
50
+ }
51
+ interface LlmResponse {
52
+ content: string;
53
+ usedTokens: number;
54
+ }
55
+ interface LlmProvider {
56
+ complete(request: LlmRequest): Promise<LlmResponse>;
57
+ }
58
+
59
+ declare function generateReleaseNotes(data: PrismData, opts: ReleaseNotesOpts, provider: LlmProvider): Promise<GenerationResult>;
60
+
61
+ declare function readPrismDirectory(prismPath: string): Promise<PrismData>;
62
+
63
+ export { type GenerationResult, type LlmMessage, type LlmProvider, type LlmRequest, type LlmResponse, type PrismData, type PrismInsight, type PrismRecommendation, type PrismSession, type ReleaseNotesOpts, generateReleaseNotes, readPrismDirectory };
@@ -0,0 +1,63 @@
1
+ interface PrismSession {
2
+ id: string;
3
+ title: string;
4
+ summary?: string;
5
+ conclusion?: string;
6
+ createdAt?: string;
7
+ }
8
+ interface PrismRecommendation {
9
+ id: string;
10
+ title: string;
11
+ severity?: "low" | "medium" | "high" | "critical";
12
+ accepted?: boolean;
13
+ description?: string;
14
+ }
15
+ interface PrismInsight {
16
+ id: string;
17
+ title: string;
18
+ body?: string;
19
+ }
20
+ interface PrismData {
21
+ sessions?: PrismSession[];
22
+ recommendations?: PrismRecommendation[];
23
+ insights?: PrismInsight[];
24
+ fromDate?: string;
25
+ toDate?: string;
26
+ }
27
+ interface ReleaseNotesOpts {
28
+ tone?: "professional" | "casual" | "technical";
29
+ length?: "short" | "medium" | "long";
30
+ format?: "markdown" | "plain";
31
+ }
32
+ interface GenerationResult {
33
+ text: string;
34
+ metadata: {
35
+ generatedAt: string;
36
+ usedTokens: number;
37
+ generator: "forgesmith";
38
+ };
39
+ }
40
+
41
+ interface LlmMessage {
42
+ role: "user" | "assistant";
43
+ content: string;
44
+ }
45
+ interface LlmRequest {
46
+ model?: string;
47
+ messages: LlmMessage[];
48
+ maxTokens?: number;
49
+ systemPrompt?: string;
50
+ }
51
+ interface LlmResponse {
52
+ content: string;
53
+ usedTokens: number;
54
+ }
55
+ interface LlmProvider {
56
+ complete(request: LlmRequest): Promise<LlmResponse>;
57
+ }
58
+
59
+ declare function generateReleaseNotes(data: PrismData, opts: ReleaseNotesOpts, provider: LlmProvider): Promise<GenerationResult>;
60
+
61
+ declare function readPrismDirectory(prismPath: string): Promise<PrismData>;
62
+
63
+ export { type GenerationResult, type LlmMessage, type LlmProvider, type LlmRequest, type LlmResponse, type PrismData, type PrismInsight, type PrismRecommendation, type PrismSession, type ReleaseNotesOpts, generateReleaseNotes, readPrismDirectory };
package/dist/index.mjs ADDED
@@ -0,0 +1,97 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+
4
+ // src/generators/releaseNotes.ts
5
+ function buildSystemPrompt() {
6
+ return `You are a technical writer and developer-relations expert. You generate clear, accurate release notes from structured code-intelligence data. Write only the release notes \u2014 no preamble, no meta-commentary.`;
7
+ }
8
+ function buildUserPrompt(data, opts) {
9
+ const tone = opts.tone ?? "professional";
10
+ const length = opts.length ?? "medium";
11
+ const format = opts.format ?? "markdown";
12
+ const lengthGuide = { short: "2-3 paragraphs or bullet groups", medium: "4-6 sections", long: "comprehensive, 6+ sections with details" }[length];
13
+ const toneGuide = { professional: "formal, clear, business-appropriate", casual: "friendly, approachable, conversational", technical: "precise, implementation-focused, developer-centric" }[tone];
14
+ const hasSessions = (data.sessions?.length ?? 0) > 0;
15
+ const hasRecs = (data.recommendations?.length ?? 0) > 0;
16
+ const hasInsights = (data.insights?.length ?? 0) > 0;
17
+ if (!hasSessions && !hasRecs && !hasInsights) {
18
+ return `Generate a brief release note in ${format} format stating there are no changes to report in this period${data.fromDate ? ` (${data.fromDate} to ${data.toDate ?? "now"})` : ""}.`;
19
+ }
20
+ const lines = [];
21
+ lines.push(`Generate release notes with the following requirements:`);
22
+ lines.push(`- Tone: ${tone} (${toneGuide})`);
23
+ lines.push(`- Length: ${length} (${lengthGuide})`);
24
+ lines.push(`- Format: ${format}`);
25
+ if (data.fromDate) lines.push(`- Period: ${data.fromDate}${data.toDate ? ` to ${data.toDate}` : " to now"}`);
26
+ lines.push(``);
27
+ if (hasSessions) {
28
+ lines.push(`## Sessions (${data.sessions.length})`);
29
+ for (const s of data.sessions) {
30
+ lines.push(`- **${s.title}**${s.summary ? `: ${s.summary}` : ""}${s.conclusion ? ` | Conclusion: ${s.conclusion}` : ""}`);
31
+ }
32
+ lines.push(``);
33
+ }
34
+ if (hasRecs) {
35
+ lines.push(`## Recommendations (${data.recommendations.length})`);
36
+ for (const r of data.recommendations) {
37
+ const accepted = r.accepted === true ? " [ACCEPTED]" : r.accepted === false ? " [DECLINED]" : "";
38
+ lines.push(`- [${r.severity?.toUpperCase() ?? "INFO"}${accepted}] **${r.title}**${r.description ? `: ${r.description}` : ""}`);
39
+ }
40
+ lines.push(``);
41
+ }
42
+ if (hasInsights) {
43
+ lines.push(`## Insights (${data.insights.length})`);
44
+ for (const i of data.insights) {
45
+ lines.push(`- **${i.title}**${i.body ? `: ${i.body}` : ""}`);
46
+ }
47
+ lines.push(``);
48
+ }
49
+ return lines.join("\n");
50
+ }
51
+ async function generateReleaseNotes(data, opts, provider) {
52
+ const systemPrompt = buildSystemPrompt();
53
+ const userPrompt = buildUserPrompt(data, opts);
54
+ const response = await provider.complete({
55
+ systemPrompt,
56
+ messages: [{ role: "user", content: userPrompt }],
57
+ maxTokens: 2048
58
+ });
59
+ return {
60
+ text: response.content,
61
+ metadata: {
62
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
63
+ usedTokens: response.usedTokens,
64
+ generator: "forgesmith"
65
+ }
66
+ };
67
+ }
68
+ async function readJsonFiles(dir) {
69
+ try {
70
+ const entries = await fs.readdir(dir);
71
+ const results = [];
72
+ for (const entry of entries) {
73
+ if (!entry.endsWith(".json")) continue;
74
+ try {
75
+ const raw = await fs.readFile(path.join(dir, entry), "utf-8");
76
+ results.push(JSON.parse(raw));
77
+ } catch {
78
+ }
79
+ }
80
+ return results;
81
+ } catch {
82
+ return [];
83
+ }
84
+ }
85
+ async function readPrismDirectory(prismPath) {
86
+ const sessionsDir = path.join(prismPath, "sessions");
87
+ const recsDir = path.join(prismPath, "recommendations");
88
+ const insightsDir = path.join(prismPath, "green", "insights", "accepted");
89
+ const [sessions, recommendations, insights] = await Promise.all([
90
+ readJsonFiles(sessionsDir),
91
+ readJsonFiles(recsDir),
92
+ readJsonFiles(insightsDir)
93
+ ]);
94
+ return { sessions, recommendations, insights };
95
+ }
96
+
97
+ export { generateReleaseNotes, readPrismDirectory };
@@ -0,0 +1,36 @@
1
+ 'use strict';
2
+
3
+ var Anthropic = require('@anthropic-ai/sdk');
4
+
5
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
6
+
7
+ var Anthropic__default = /*#__PURE__*/_interopDefault(Anthropic);
8
+
9
+ // src/llm/providers/direct.ts
10
+ var DEFAULT_MODEL = "claude-sonnet-4-6";
11
+ var DirectLlmProvider = class {
12
+ client;
13
+ defaultModel;
14
+ constructor(opts) {
15
+ this.client = new Anthropic__default.default({ apiKey: opts.apiKey });
16
+ this.defaultModel = opts.model ?? DEFAULT_MODEL;
17
+ }
18
+ async complete(request) {
19
+ const model = request.model ?? this.defaultModel;
20
+ const maxTokens = request.maxTokens ?? 4096;
21
+ const response = await this.client.messages.create({
22
+ model,
23
+ max_tokens: maxTokens,
24
+ system: request.systemPrompt,
25
+ messages: request.messages.map((m) => ({
26
+ role: m.role,
27
+ content: m.content
28
+ }))
29
+ });
30
+ const content = response.content.filter((b) => b.type === "text").map((b) => b.text).join("");
31
+ const usedTokens = (response.usage?.input_tokens ?? 0) + (response.usage?.output_tokens ?? 0);
32
+ return { content, usedTokens };
33
+ }
34
+ };
35
+
36
+ exports.DirectLlmProvider = DirectLlmProvider;
@@ -0,0 +1,30 @@
1
+ interface LlmMessage {
2
+ role: "user" | "assistant";
3
+ content: string;
4
+ }
5
+ interface LlmRequest {
6
+ model?: string;
7
+ messages: LlmMessage[];
8
+ maxTokens?: number;
9
+ systemPrompt?: string;
10
+ }
11
+ interface LlmResponse {
12
+ content: string;
13
+ usedTokens: number;
14
+ }
15
+ interface LlmProvider {
16
+ complete(request: LlmRequest): Promise<LlmResponse>;
17
+ }
18
+
19
+ interface DirectLlmProviderOptions {
20
+ apiKey: string;
21
+ model?: string;
22
+ }
23
+ declare class DirectLlmProvider implements LlmProvider {
24
+ private client;
25
+ private defaultModel;
26
+ constructor(opts: DirectLlmProviderOptions);
27
+ complete(request: LlmRequest): Promise<LlmResponse>;
28
+ }
29
+
30
+ export { DirectLlmProvider, type DirectLlmProviderOptions };
@@ -0,0 +1,30 @@
1
+ interface LlmMessage {
2
+ role: "user" | "assistant";
3
+ content: string;
4
+ }
5
+ interface LlmRequest {
6
+ model?: string;
7
+ messages: LlmMessage[];
8
+ maxTokens?: number;
9
+ systemPrompt?: string;
10
+ }
11
+ interface LlmResponse {
12
+ content: string;
13
+ usedTokens: number;
14
+ }
15
+ interface LlmProvider {
16
+ complete(request: LlmRequest): Promise<LlmResponse>;
17
+ }
18
+
19
+ interface DirectLlmProviderOptions {
20
+ apiKey: string;
21
+ model?: string;
22
+ }
23
+ declare class DirectLlmProvider implements LlmProvider {
24
+ private client;
25
+ private defaultModel;
26
+ constructor(opts: DirectLlmProviderOptions);
27
+ complete(request: LlmRequest): Promise<LlmResponse>;
28
+ }
29
+
30
+ export { DirectLlmProvider, type DirectLlmProviderOptions };
@@ -0,0 +1,30 @@
1
+ import Anthropic from '@anthropic-ai/sdk';
2
+
3
+ // src/llm/providers/direct.ts
4
+ var DEFAULT_MODEL = "claude-sonnet-4-6";
5
+ var DirectLlmProvider = class {
6
+ client;
7
+ defaultModel;
8
+ constructor(opts) {
9
+ this.client = new Anthropic({ apiKey: opts.apiKey });
10
+ this.defaultModel = opts.model ?? DEFAULT_MODEL;
11
+ }
12
+ async complete(request) {
13
+ const model = request.model ?? this.defaultModel;
14
+ const maxTokens = request.maxTokens ?? 4096;
15
+ const response = await this.client.messages.create({
16
+ model,
17
+ max_tokens: maxTokens,
18
+ system: request.systemPrompt,
19
+ messages: request.messages.map((m) => ({
20
+ role: m.role,
21
+ content: m.content
22
+ }))
23
+ });
24
+ const content = response.content.filter((b) => b.type === "text").map((b) => b.text).join("");
25
+ const usedTokens = (response.usage?.input_tokens ?? 0) + (response.usage?.output_tokens ?? 0);
26
+ return { content, usedTokens };
27
+ }
28
+ };
29
+
30
+ export { DirectLlmProvider };
package/package.json CHANGED
@@ -1,11 +1,61 @@
1
1
  {
2
2
  "name": "forgesmith",
3
- "version": "0.0.1",
4
- "description": "forgesmith — content/asset-generation engine. The lens observes, the smith forges. Sister engine to prismlens. (Reserved package.)",
5
- "main": "index.js",
3
+ "version": "0.1.0",
4
+ "description": "forgesmith — content & asset-generation engine. Forge release notes, blog posts, social copy from prism0x2A data.",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.mjs",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.mjs",
13
+ "require": "./dist/index.cjs",
14
+ "default": "./dist/index.cjs"
15
+ },
16
+ "./providers": {
17
+ "types": "./dist/providers.d.ts",
18
+ "import": "./dist/providers.mjs",
19
+ "require": "./dist/providers.cjs",
20
+ "default": "./dist/providers.cjs"
21
+ }
22
+ },
23
+ "files": [
24
+ "dist",
25
+ "README.md",
26
+ "CHANGELOG.md"
27
+ ],
28
+ "scripts": {
29
+ "build": "tsup",
30
+ "test": "vitest run",
31
+ "test:watch": "vitest",
32
+ "typecheck": "tsc --noEmit",
33
+ "prepare": "npm run build",
34
+ "prepublishOnly": "npm run build && npm test"
35
+ },
36
+ "dependencies": {
37
+ "@anthropic-ai/sdk": "^0.37.0"
38
+ },
39
+ "devDependencies": {
40
+ "@types/node": "^22.0.0",
41
+ "tsup": "^8.3.5",
42
+ "typescript": "^5.7.2",
43
+ "vitest": "^2.1.8"
44
+ },
6
45
  "license": "UNLICENSED",
7
46
  "private": false,
8
47
  "homepage": "https://github.com/dadenjo/forgesmith",
9
- "keywords": ["code-intelligence", "content-generation", "release-notes", "marketing", "developer-tools"],
48
+ "repository": {
49
+ "type": "git",
50
+ "url": "https://github.com/dadenjo/forgesmith.git"
51
+ },
52
+ "keywords": [
53
+ "code-intelligence",
54
+ "content-generation",
55
+ "release-notes",
56
+ "marketing",
57
+ "developer-tools",
58
+ "prism0x2a"
59
+ ],
10
60
  "author": "dadenjo"
11
61
  }
package/index.js DELETED
@@ -1,5 +0,0 @@
1
- // forgesmith — placeholder reservation. Real release follows prism0x2A v0.3.x.
2
- // The lens observes. The smith forges.
3
- // See: https://github.com/dadenjo/forgesmith
4
- console.log("forgesmith — engine for forge0x2B. Reserved.");
5
- console.log("The lens observes. The smith forges.");