attacca-forge 0.5.1 → 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 +135 -68
- package/.claude-plugin/marketplace.json +0 -20
- package/plugins/attacca-forge/.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
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,52 +27,138 @@ 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
|
-
|
|
32
|
-
|
|
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] = {
|
|
33
90
|
source: {
|
|
34
91
|
source: 'directory',
|
|
35
92
|
path: targetDir,
|
|
36
93
|
},
|
|
37
|
-
installLocation: targetDir,
|
|
38
|
-
lastUpdated: new Date().toISOString(),
|
|
39
94
|
};
|
|
95
|
+
changed = true;
|
|
96
|
+
}
|
|
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);
|
|
40
108
|
}
|
|
41
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
|
+
|
|
42
127
|
writeJsonFile(marketplacesPath, marketplaces);
|
|
43
|
-
return true;
|
|
44
128
|
}
|
|
45
129
|
|
|
46
|
-
|
|
130
|
+
// Step 4: Register in installed_plugins.json + populate cache
|
|
131
|
+
function registerPlugin(claudeDir, pluginDir, version) {
|
|
47
132
|
const installedPath = join(claudeDir, 'plugins', 'installed_plugins.json');
|
|
48
133
|
const installed = readJsonFile(installedPath) || { version: 2, plugins: {} };
|
|
49
134
|
|
|
50
|
-
// Ensure version 2 format
|
|
51
135
|
if (!installed.version) installed.version = 2;
|
|
52
136
|
if (!installed.plugins) installed.plugins = {};
|
|
53
137
|
|
|
54
138
|
const pluginKey = `${PLUGIN_NAME}@${MARKETPLACE_NAME}`;
|
|
55
139
|
const now = new Date().toISOString();
|
|
56
140
|
|
|
57
|
-
//
|
|
141
|
+
// Copy to cache
|
|
58
142
|
const cachePath = join(claudeDir, 'plugins', 'cache', MARKETPLACE_NAME, PLUGIN_NAME, version);
|
|
59
|
-
|
|
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
|
+
}
|
|
60
153
|
|
|
61
|
-
|
|
62
|
-
const sourceSkills = join(targetDir, 'skills');
|
|
154
|
+
const sourceSkills = join(pluginDir, 'skills');
|
|
63
155
|
const cacheSkills = join(cachePath, 'skills');
|
|
64
156
|
if (existsSync(sourceSkills)) {
|
|
65
157
|
cpSync(sourceSkills, cacheSkills, { recursive: true, force: true });
|
|
66
158
|
}
|
|
67
159
|
|
|
160
|
+
// Register
|
|
68
161
|
if (installed.plugins[pluginKey]) {
|
|
69
|
-
// Update existing entry
|
|
70
162
|
installed.plugins[pluginKey][0].version = version;
|
|
71
163
|
installed.plugins[pluginKey][0].installPath = cachePath;
|
|
72
164
|
installed.plugins[pluginKey][0].lastUpdated = now;
|
|
@@ -83,7 +175,6 @@ function registerPlugin(claudeDir, targetDir, version) {
|
|
|
83
175
|
}
|
|
84
176
|
|
|
85
177
|
writeJsonFile(installedPath, installed);
|
|
86
|
-
return true;
|
|
87
178
|
}
|
|
88
179
|
|
|
89
180
|
export default async function install({ args, cwd, rootDir }) {
|
|
@@ -102,75 +193,51 @@ export default async function install({ args, cwd, rootDir }) {
|
|
|
102
193
|
|
|
103
194
|
console.log(' ✓ Claude Code detected');
|
|
104
195
|
|
|
105
|
-
//
|
|
106
|
-
const
|
|
107
|
-
if (!existsSync(
|
|
108
|
-
console.error(' ✗
|
|
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.');
|
|
109
200
|
process.exit(1);
|
|
110
201
|
}
|
|
111
202
|
|
|
112
203
|
// Read version from package.json
|
|
113
204
|
const pkg = readJsonFile(join(rootDir, 'package.json'));
|
|
114
|
-
const version = pkg?.version || '0.
|
|
205
|
+
const version = pkg?.version || '0.6.0';
|
|
115
206
|
|
|
116
|
-
// Target plugin directory
|
|
117
207
|
const claudeDir = getClaudeDir();
|
|
118
|
-
const targetDir =
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
// Create directories
|
|
122
|
-
if (!existsSync(localDir)) mkdirSync(localDir, { recursive: true });
|
|
123
|
-
|
|
124
|
-
// Copy .claude-plugin/ and skills/
|
|
125
|
-
const existed = existsSync(targetDir);
|
|
126
|
-
if (!existsSync(targetDir)) mkdirSync(targetDir, { recursive: true });
|
|
127
|
-
|
|
128
|
-
const sourceClaudePlugin = join(sourcePlugin, '.claude-plugin');
|
|
129
|
-
const sourceSkills = join(sourcePlugin, 'skills');
|
|
130
|
-
const targetClaudePlugin = join(targetDir, '.claude-plugin');
|
|
131
|
-
const targetSkills = join(targetDir, 'skills');
|
|
208
|
+
const targetDir = join(claudeDir, 'plugins', 'local', MARKETPLACE_NAME);
|
|
209
|
+
const pluginsDir = join(claudeDir, 'plugins');
|
|
210
|
+
if (!existsSync(pluginsDir)) mkdirSync(pluginsDir, { recursive: true });
|
|
132
211
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
if (existsSync(sourceSkills)) {
|
|
137
|
-
cpSync(sourceSkills, targetSkills, { recursive: true, force: true });
|
|
138
|
-
}
|
|
212
|
+
// Step 1: Build marketplace structure
|
|
213
|
+
const pluginDir = buildMarketplaceStructure(rootDir, targetDir, version);
|
|
139
214
|
|
|
140
215
|
// Count skills
|
|
216
|
+
const { readdirSync } = await import('node:fs');
|
|
217
|
+
const skillsDir = join(pluginDir, 'skills');
|
|
141
218
|
let skillCount = 0;
|
|
142
|
-
if (existsSync(
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
return existsSync(join(targetSkills, f, 'SKILL.md'));
|
|
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
|
-
// Register
|
|
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
|
-
|
|
236
|
+
// Step 4: Register plugin + populate cache
|
|
237
|
+
registerPlugin(claudeDir, pluginDir, version);
|
|
160
238
|
console.log(' ✓ Plugin registered');
|
|
161
239
|
|
|
162
240
|
console.log('');
|
|
163
241
|
console.log(' Restart Claude Code to load the new skills.');
|
|
164
242
|
console.log('');
|
|
165
|
-
console.log(' Available skills:');
|
|
166
|
-
console.log(' /spec-architect Full behavioral spec with intent contracts');
|
|
167
|
-
console.log(' /spec-writer Streamlined spec (no intent layer)');
|
|
168
|
-
console.log(' /stress-test Factorial stress testing (22 variation types)');
|
|
169
|
-
console.log(' /intent-spec Agent intent specification');
|
|
170
|
-
console.log(' /intent-audit Organizational AI maturity audit');
|
|
171
|
-
console.log(' /codebase-discovery Brownfield codebase discovery');
|
|
172
|
-
console.log(' /build-orchestrator Build pipeline with 4-layer eval stack');
|
|
173
|
-
console.log(' /forge-help Phase-aware guidance ("what\'s next?")');
|
|
174
|
-
console.log(' /forge-start IDEA phase onboarding');
|
|
175
|
-
console.log('');
|
|
176
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.1",
|
|
13
|
-
"author": {
|
|
14
|
-
"name": "Attacca"
|
|
15
|
-
},
|
|
16
|
-
"source": "./plugins/attacca-forge",
|
|
17
|
-
"category": "development"
|
|
18
|
-
}
|
|
19
|
-
]
|
|
20
|
-
}
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
|
|
3
|
-
"name": "attacca-forge",
|
|
4
|
-
"description": "Attacca Forge — AI agent development methodology: design, evaluate, align, and orchestrate autonomous 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. 26 skills across spec writing, stress testing, intent engineering, and build orchestration.",
|
|
12
|
-
"version": "0.5.1",
|
|
13
|
-
"author": {
|
|
14
|
-
"name": "Attacca"
|
|
15
|
-
},
|
|
16
|
-
"source": ".",
|
|
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
|