attacca-forge 0.5.2 → 0.6.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/package.json +2 -2
- package/src/commands/install.js +134 -68
- package/.claude-plugin/marketplace.json +0 -20
- /package/{plugins/attacca-forge/.claude-plugin → .claude-plugin}/plugin.json +0 -0
- /package/{plugins/attacca-forge/skills → skills}/agent-economics-analyzer/SKILL.md +0 -0
- /package/{plugins/attacca-forge/skills → skills}/agent-readiness-audit/SKILL.md +0 -0
- /package/{plugins/attacca-forge/skills → skills}/agent-stack-opportunity-mapper/SKILL.md +0 -0
- /package/{plugins/attacca-forge/skills → skills}/ai-dev-level-assessment/SKILL.md +0 -0
- /package/{plugins/attacca-forge/skills → skills}/ai-dev-talent-strategy/SKILL.md +0 -0
- /package/{plugins/attacca-forge/skills → skills}/ai-difficulty-rapid-audit/SKILL.md +0 -0
- /package/{plugins/attacca-forge/skills → skills}/ai-native-org-redesign/SKILL.md +0 -0
- /package/{plugins/attacca-forge/skills → skills}/ai-output-taste-builder/SKILL.md +0 -0
- /package/{plugins/attacca-forge/skills → skills}/ai-workflow-capability-map/SKILL.md +0 -0
- /package/{plugins/attacca-forge/skills → skills}/ai-workflow-optimizer/SKILL.md +0 -0
- /package/{plugins/attacca-forge/skills → skills}/build-orchestrator/SKILL.md +0 -0
- /package/{plugins/attacca-forge/skills → skills}/codebase-discovery/SKILL.md +0 -0
- /package/{plugins/attacca-forge/skills → skills}/forge-help/SKILL.md +0 -0
- /package/{plugins/attacca-forge/skills → skills}/forge-start/SKILL.md +0 -0
- /package/{plugins/attacca-forge/skills → skills}/harness-simulator/SKILL.md +0 -0
- /package/{plugins/attacca-forge/skills → skills}/insight-to-action-compression-map/SKILL.md +0 -0
- /package/{plugins/attacca-forge/skills → skills}/intent-audit/SKILL.md +0 -0
- /package/{plugins/attacca-forge/skills → skills}/intent-gap-diagnostic/SKILL.md +0 -0
- /package/{plugins/attacca-forge/skills → skills}/intent-spec/SKILL.md +0 -0
- /package/{plugins/attacca-forge/skills → skills}/legacy-migration-roadmap/SKILL.md +0 -0
- /package/{plugins/attacca-forge/skills → skills}/personal-intent-layer-builder/SKILL.md +0 -0
- /package/{plugins/attacca-forge/skills → skills}/problem-difficulty-decomposition/SKILL.md +0 -0
- /package/{plugins/attacca-forge/skills → skills}/spec-architect/SKILL.md +0 -0
- /package/{plugins/attacca-forge/skills → skills}/spec-writer/SKILL.md +0 -0
- /package/{plugins/attacca-forge/skills → skills}/stress-test/SKILL.md +0 -0
- /package/{plugins/attacca-forge/skills → skills}/web-fork-strategic-briefing/SKILL.md +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "attacca-forge",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Spec-driven AI development toolkit — design, evaluate, stress-test, and certify autonomous agents from your terminal",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"files": [
|
|
33
33
|
"bin/",
|
|
34
34
|
"src/",
|
|
35
|
-
"
|
|
35
|
+
"skills/",
|
|
36
36
|
".claude-plugin/",
|
|
37
37
|
"docs/",
|
|
38
38
|
"examples/",
|
package/src/commands/install.js
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
// =============================================================================
|
|
2
|
-
// attacca-forge install — Install
|
|
2
|
+
// attacca-forge install — Install as a Claude Code marketplace + plugin
|
|
3
|
+
//
|
|
4
|
+
// Registration approach (same pattern as nirbound-marketplace):
|
|
5
|
+
// 1. Build marketplace structure at ~/.claude/plugins/local/attacca-forge/
|
|
6
|
+
// 2. Register in settings.json (extraKnownMarketplaces + enabledPlugins)
|
|
7
|
+
// 3. Register in known_marketplaces.json
|
|
8
|
+
// 4. Register in installed_plugins.json + populate cache
|
|
3
9
|
// =============================================================================
|
|
4
10
|
|
|
5
|
-
import { cpSync, existsSync, mkdirSync, readFileSync,
|
|
11
|
+
import { cpSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
6
12
|
import { join } from 'node:path';
|
|
7
|
-
import { getClaudeDir,
|
|
13
|
+
import { getClaudeDir, isClaudeInstalled } from '../utils/detect-claude.js';
|
|
8
14
|
|
|
9
15
|
const MARKETPLACE_NAME = 'attacca-forge';
|
|
10
16
|
const PLUGIN_NAME = 'attacca-forge';
|
|
@@ -21,27 +27,107 @@ function writeJsonFile(path, data) {
|
|
|
21
27
|
writeFileSync(path, JSON.stringify(data, null, 2) + '\n', 'utf-8');
|
|
22
28
|
}
|
|
23
29
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
// Step 1: Build marketplace directory structure
|
|
31
|
+
function buildMarketplaceStructure(rootDir, targetDir, version) {
|
|
32
|
+
// Create marketplace root
|
|
33
|
+
mkdirSync(targetDir, { recursive: true });
|
|
34
|
+
|
|
35
|
+
// Write marketplace.json at marketplace root
|
|
36
|
+
const marketplaceJsonDir = join(targetDir, '.claude-plugin');
|
|
37
|
+
mkdirSync(marketplaceJsonDir, { recursive: true });
|
|
38
|
+
writeJsonFile(join(marketplaceJsonDir, 'marketplace.json'), {
|
|
39
|
+
$schema: 'https://anthropic.com/claude-code/marketplace.schema.json',
|
|
40
|
+
name: MARKETPLACE_NAME,
|
|
41
|
+
description:
|
|
42
|
+
'Spec-driven AI development toolkit — design, evaluate, stress-test, and certify autonomous agents',
|
|
43
|
+
owner: { name: 'Attacca' },
|
|
44
|
+
plugins: [
|
|
45
|
+
{
|
|
46
|
+
name: PLUGIN_NAME,
|
|
47
|
+
description:
|
|
48
|
+
'AI agent development methodology — design, evaluate, and align autonomous agents',
|
|
49
|
+
version,
|
|
50
|
+
author: { name: 'Attacca' },
|
|
51
|
+
source: `./plugins/${PLUGIN_NAME}`,
|
|
52
|
+
category: 'development',
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// Create plugin subdirectory: plugins/attacca-forge/
|
|
58
|
+
const pluginDir = join(targetDir, 'plugins', PLUGIN_NAME);
|
|
59
|
+
mkdirSync(pluginDir, { recursive: true });
|
|
60
|
+
|
|
61
|
+
// Copy plugin.json
|
|
62
|
+
const pluginJsonDir = join(pluginDir, '.claude-plugin');
|
|
63
|
+
mkdirSync(pluginJsonDir, { recursive: true });
|
|
64
|
+
const sourcePluginJson = join(rootDir, '.claude-plugin', 'plugin.json');
|
|
65
|
+
if (existsSync(sourcePluginJson)) {
|
|
66
|
+
cpSync(sourcePluginJson, join(pluginJsonDir, 'plugin.json'), { force: true });
|
|
67
|
+
}
|
|
27
68
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
69
|
+
// Copy skills into the plugin subdirectory
|
|
70
|
+
const sourceSkills = join(rootDir, 'skills');
|
|
71
|
+
const targetSkills = join(pluginDir, 'skills');
|
|
72
|
+
if (existsSync(sourceSkills)) {
|
|
73
|
+
cpSync(sourceSkills, targetSkills, { recursive: true, force: true });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return pluginDir;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Step 2: Register in settings.json
|
|
80
|
+
function registerInSettings(claudeDir, targetDir) {
|
|
81
|
+
const settingsPath = join(claudeDir, 'settings.json');
|
|
82
|
+
const settings = readJsonFile(settingsPath) || {};
|
|
83
|
+
|
|
84
|
+
let changed = false;
|
|
85
|
+
|
|
86
|
+
// Add to extraKnownMarketplaces
|
|
87
|
+
if (!settings.extraKnownMarketplaces) settings.extraKnownMarketplaces = {};
|
|
88
|
+
if (!settings.extraKnownMarketplaces[MARKETPLACE_NAME]) {
|
|
89
|
+
settings.extraKnownMarketplaces[MARKETPLACE_NAME] = {
|
|
32
90
|
source: {
|
|
33
91
|
source: 'directory',
|
|
34
92
|
path: targetDir,
|
|
35
93
|
},
|
|
36
|
-
installLocation: targetDir,
|
|
37
|
-
lastUpdated: new Date().toISOString(),
|
|
38
94
|
};
|
|
95
|
+
changed = true;
|
|
39
96
|
}
|
|
40
97
|
|
|
98
|
+
// Add to enabledPlugins
|
|
99
|
+
if (!settings.enabledPlugins) settings.enabledPlugins = {};
|
|
100
|
+
const pluginKey = `${PLUGIN_NAME}@${MARKETPLACE_NAME}`;
|
|
101
|
+
if (settings.enabledPlugins[pluginKey] === undefined) {
|
|
102
|
+
settings.enabledPlugins[pluginKey] = true;
|
|
103
|
+
changed = true;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (changed) {
|
|
107
|
+
writeJsonFile(settingsPath, settings);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return changed;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Step 3: Register in known_marketplaces.json
|
|
114
|
+
function registerMarketplace(claudeDir, targetDir) {
|
|
115
|
+
const marketplacesPath = join(claudeDir, 'plugins', 'known_marketplaces.json');
|
|
116
|
+
const marketplaces = readJsonFile(marketplacesPath) || {};
|
|
117
|
+
|
|
118
|
+
marketplaces[MARKETPLACE_NAME] = {
|
|
119
|
+
source: {
|
|
120
|
+
source: 'directory',
|
|
121
|
+
path: targetDir,
|
|
122
|
+
},
|
|
123
|
+
installLocation: targetDir,
|
|
124
|
+
lastUpdated: new Date().toISOString(),
|
|
125
|
+
};
|
|
126
|
+
|
|
41
127
|
writeJsonFile(marketplacesPath, marketplaces);
|
|
42
|
-
return true;
|
|
43
128
|
}
|
|
44
129
|
|
|
130
|
+
// Step 4: Register in installed_plugins.json + populate cache
|
|
45
131
|
function registerPlugin(claudeDir, pluginDir, version) {
|
|
46
132
|
const installedPath = join(claudeDir, 'plugins', 'installed_plugins.json');
|
|
47
133
|
const installed = readJsonFile(installedPath) || { version: 2, plugins: {} };
|
|
@@ -52,9 +138,18 @@ function registerPlugin(claudeDir, pluginDir, version) {
|
|
|
52
138
|
const pluginKey = `${PLUGIN_NAME}@${MARKETPLACE_NAME}`;
|
|
53
139
|
const now = new Date().toISOString();
|
|
54
140
|
|
|
55
|
-
//
|
|
141
|
+
// Copy to cache
|
|
56
142
|
const cachePath = join(claudeDir, 'plugins', 'cache', MARKETPLACE_NAME, PLUGIN_NAME, version);
|
|
57
|
-
|
|
143
|
+
mkdirSync(cachePath, { recursive: true });
|
|
144
|
+
|
|
145
|
+
const sourcePluginJsonDir = join(pluginDir, '.claude-plugin');
|
|
146
|
+
const cachePluginJsonDir = join(cachePath, '.claude-plugin');
|
|
147
|
+
mkdirSync(cachePluginJsonDir, { recursive: true });
|
|
148
|
+
if (existsSync(join(sourcePluginJsonDir, 'plugin.json'))) {
|
|
149
|
+
cpSync(join(sourcePluginJsonDir, 'plugin.json'), join(cachePluginJsonDir, 'plugin.json'), {
|
|
150
|
+
force: true,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
58
153
|
|
|
59
154
|
const sourceSkills = join(pluginDir, 'skills');
|
|
60
155
|
const cacheSkills = join(cachePath, 'skills');
|
|
@@ -62,6 +157,7 @@ function registerPlugin(claudeDir, pluginDir, version) {
|
|
|
62
157
|
cpSync(sourceSkills, cacheSkills, { recursive: true, force: true });
|
|
63
158
|
}
|
|
64
159
|
|
|
160
|
+
// Register
|
|
65
161
|
if (installed.plugins[pluginKey]) {
|
|
66
162
|
installed.plugins[pluginKey][0].version = version;
|
|
67
163
|
installed.plugins[pluginKey][0].installPath = cachePath;
|
|
@@ -79,7 +175,6 @@ function registerPlugin(claudeDir, pluginDir, version) {
|
|
|
79
175
|
}
|
|
80
176
|
|
|
81
177
|
writeJsonFile(installedPath, installed);
|
|
82
|
-
return true;
|
|
83
178
|
}
|
|
84
179
|
|
|
85
180
|
export default async function install({ args, cwd, rootDir }) {
|
|
@@ -98,80 +193,51 @@ export default async function install({ args, cwd, rootDir }) {
|
|
|
98
193
|
|
|
99
194
|
console.log(' ✓ Claude Code detected');
|
|
100
195
|
|
|
101
|
-
//
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
const sourceMarketplace = join(rootDir, '.claude-plugin', 'marketplace.json');
|
|
106
|
-
const sourcePlugin = join(rootDir, 'plugins', 'attacca-forge');
|
|
107
|
-
|
|
108
|
-
if (!existsSync(sourcePlugin)) {
|
|
109
|
-
console.error(' ✗ Plugin source not found. Package may be corrupted.');
|
|
196
|
+
// Verify source skills exist
|
|
197
|
+
const sourceSkills = join(rootDir, 'skills');
|
|
198
|
+
if (!existsSync(sourceSkills)) {
|
|
199
|
+
console.error(' ✗ Skills directory not found. Package may be corrupted.');
|
|
110
200
|
process.exit(1);
|
|
111
201
|
}
|
|
112
202
|
|
|
113
203
|
// Read version from package.json
|
|
114
204
|
const pkg = readJsonFile(join(rootDir, 'package.json'));
|
|
115
|
-
const version = pkg?.version || '0.
|
|
205
|
+
const version = pkg?.version || '0.6.0';
|
|
116
206
|
|
|
117
|
-
// Target: ~/.claude/plugins/local/attacca-forge/
|
|
118
|
-
// Installed layout (mirrors nirbound-marketplace):
|
|
119
|
-
// .claude-plugin/marketplace.json
|
|
120
|
-
// plugins/attacca-forge/.claude-plugin/plugin.json
|
|
121
|
-
// plugins/attacca-forge/skills/
|
|
122
207
|
const claudeDir = getClaudeDir();
|
|
123
|
-
const targetDir =
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (!existsSync(targetDir)) mkdirSync(targetDir, { recursive: true });
|
|
127
|
-
|
|
128
|
-
// 1. Copy marketplace descriptor to target root
|
|
129
|
-
const targetMarketplaceDir = join(targetDir, '.claude-plugin');
|
|
130
|
-
if (!existsSync(targetMarketplaceDir)) mkdirSync(targetMarketplaceDir, { recursive: true });
|
|
131
|
-
if (existsSync(sourceMarketplace)) {
|
|
132
|
-
cpSync(sourceMarketplace, join(targetMarketplaceDir, 'marketplace.json'), { force: true });
|
|
133
|
-
}
|
|
208
|
+
const targetDir = join(claudeDir, 'plugins', 'local', MARKETPLACE_NAME);
|
|
209
|
+
const pluginsDir = join(claudeDir, 'plugins');
|
|
210
|
+
if (!existsSync(pluginsDir)) mkdirSync(pluginsDir, { recursive: true });
|
|
134
211
|
|
|
135
|
-
//
|
|
136
|
-
const
|
|
137
|
-
if (!existsSync(targetPlugin)) mkdirSync(targetPlugin, { recursive: true });
|
|
138
|
-
cpSync(sourcePlugin, targetPlugin, { recursive: true, force: true });
|
|
212
|
+
// Step 1: Build marketplace structure
|
|
213
|
+
const pluginDir = buildMarketplaceStructure(rootDir, targetDir, version);
|
|
139
214
|
|
|
140
215
|
// Count skills
|
|
141
|
-
const
|
|
216
|
+
const { readdirSync } = await import('node:fs');
|
|
217
|
+
const skillsDir = join(pluginDir, 'skills');
|
|
142
218
|
let skillCount = 0;
|
|
143
|
-
if (existsSync(
|
|
144
|
-
skillCount = readdirSync(
|
|
145
|
-
return existsSync(join(
|
|
219
|
+
if (existsSync(skillsDir)) {
|
|
220
|
+
skillCount = readdirSync(skillsDir).filter((f) => {
|
|
221
|
+
return existsSync(join(skillsDir, f, 'SKILL.md'));
|
|
146
222
|
}).length;
|
|
147
223
|
}
|
|
148
224
|
|
|
149
|
-
console.log(` ✓
|
|
150
|
-
console.log(`
|
|
225
|
+
console.log(` ✓ Installed ${skillCount} skills`);
|
|
226
|
+
console.log(` Marketplace: ${targetDir}`);
|
|
151
227
|
|
|
152
|
-
//
|
|
153
|
-
const
|
|
154
|
-
|
|
228
|
+
// Step 2: Register in settings.json
|
|
229
|
+
const settingsChanged = registerInSettings(claudeDir, targetDir);
|
|
230
|
+
console.log(` ✓ Settings ${settingsChanged ? 'updated' : 'already configured'}`);
|
|
155
231
|
|
|
232
|
+
// Step 3: Register in known_marketplaces.json
|
|
156
233
|
registerMarketplace(claudeDir, targetDir);
|
|
157
234
|
console.log(' ✓ Marketplace registered');
|
|
158
235
|
|
|
159
|
-
// 4
|
|
160
|
-
registerPlugin(claudeDir,
|
|
236
|
+
// Step 4: Register plugin + populate cache
|
|
237
|
+
registerPlugin(claudeDir, pluginDir, version);
|
|
161
238
|
console.log(' ✓ Plugin registered');
|
|
162
239
|
|
|
163
240
|
console.log('');
|
|
164
241
|
console.log(' Restart Claude Code to load the new skills.');
|
|
165
242
|
console.log('');
|
|
166
|
-
console.log(' Available skills:');
|
|
167
|
-
console.log(' /spec-architect Full behavioral spec with intent contracts');
|
|
168
|
-
console.log(' /spec-writer Streamlined spec (no intent layer)');
|
|
169
|
-
console.log(' /stress-test Factorial stress testing (22 variation types)');
|
|
170
|
-
console.log(' /intent-spec Agent intent specification');
|
|
171
|
-
console.log(' /intent-audit Organizational AI maturity audit');
|
|
172
|
-
console.log(' /codebase-discovery Brownfield codebase discovery');
|
|
173
|
-
console.log(' /build-orchestrator Build pipeline with 4-layer eval stack');
|
|
174
|
-
console.log(' /forge-help Phase-aware guidance ("what\'s next?")');
|
|
175
|
-
console.log(' /forge-start IDEA phase onboarding');
|
|
176
|
-
console.log('');
|
|
177
243
|
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
|
|
3
|
-
"name": "attacca-forge",
|
|
4
|
-
"description": "Open-source AI agent development toolkit: spec writing, evaluation, intent engineering, and build orchestration for production-grade agents",
|
|
5
|
-
"owner": {
|
|
6
|
-
"name": "Attacca"
|
|
7
|
-
},
|
|
8
|
-
"plugins": [
|
|
9
|
-
{
|
|
10
|
-
"name": "attacca-forge",
|
|
11
|
-
"description": "AI agent development methodology — design, evaluate, and align autonomous agents with production-grade specifications, factorial stress testing, and intent engineering",
|
|
12
|
-
"version": "0.5.2",
|
|
13
|
-
"author": {
|
|
14
|
-
"name": "Attacca"
|
|
15
|
-
},
|
|
16
|
-
"source": "./plugins/attacca-forge",
|
|
17
|
-
"category": "development"
|
|
18
|
-
}
|
|
19
|
-
]
|
|
20
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|