@axiomatic-labs/claudeflow 2.49.31 → 2.49.32
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/lib/install.js +75 -3
- package/package.json +1 -1
package/lib/install.js
CHANGED
|
@@ -27,7 +27,19 @@ const PER_PROJECT_CONFIGS = ['brand.json', 'risk-signals.json', 'test-context.js
|
|
|
27
27
|
// Paths appended to the project's .gitignore (add-if-absent). These hold TEST credentials / Playwright
|
|
28
28
|
// storage state — they must NEVER be committed. test-context.json is per-project runtime state; .auth/
|
|
29
29
|
// holds storageState files the orchestrator seeds for auth-gated functional verification.
|
|
30
|
-
const GITIGNORE_LINES = [
|
|
30
|
+
const GITIGNORE_LINES = [
|
|
31
|
+
'__pycache__/',
|
|
32
|
+
'*.pyc',
|
|
33
|
+
'.claudeflow/test-context.json',
|
|
34
|
+
'.claudeflow/.auth/',
|
|
35
|
+
'.claudeflow/telemetry/',
|
|
36
|
+
'.claudeflow/certification/',
|
|
37
|
+
'.claudeflow/headless-e2e/',
|
|
38
|
+
'.claudeflow/headless-claude/',
|
|
39
|
+
'.claudeflow/e2e-runs/',
|
|
40
|
+
'.claudeflow/tools/',
|
|
41
|
+
'.claudeflow/backups/',
|
|
42
|
+
];
|
|
31
43
|
const SHARED_CONFIGS = ['playbook-map.json', 'agent-map.json']; // always refreshed (shared system)
|
|
32
44
|
const CODEX_DOCS = ['claudeflow-codex-migration.md', 'codexflow-codex-native-workflow.md', 'codexflow-local-actions.md'];
|
|
33
45
|
|
|
@@ -623,8 +635,8 @@ function mergeCodexMarketplace(cwd, payloadMarketplace) {
|
|
|
623
635
|
return true;
|
|
624
636
|
}
|
|
625
637
|
|
|
626
|
-
// Seed the BASE MCP server set (
|
|
627
|
-
//
|
|
638
|
+
// Seed the BASE MCP server set (context7 for live library docs during Discover, chrome-devtools for Chrome
|
|
639
|
+
// DevTools inspection) into the project's root `.mcp.json`.
|
|
628
640
|
// ADD-IF-ABSENT by server key: create the file if missing, else merge in only the keys the user doesn't
|
|
629
641
|
// already have (never clobber a server they configured). A corrupt/unexpected `.mcp.json` is left untouched
|
|
630
642
|
// (don't risk eating the user's servers). Returns the number of servers added (0 = nothing to do). Like the
|
|
@@ -644,6 +656,53 @@ function mergeMcp(cwd, baseServers) {
|
|
|
644
656
|
return added;
|
|
645
657
|
}
|
|
646
658
|
|
|
659
|
+
function isManagedPlaywrightMcp(server) {
|
|
660
|
+
const args = Array.isArray(server && server.args) ? server.args.join(' ') : '';
|
|
661
|
+
return Boolean(server && String(server.command || '').includes('npx') && args.includes('@playwright/mcp'));
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
function pruneManagedPlaywrightMcpFile(mp) {
|
|
665
|
+
if (!fs.existsSync(mp)) return false;
|
|
666
|
+
let data = {};
|
|
667
|
+
try { data = JSON.parse(fs.readFileSync(mp, 'utf8')); } catch { return false; }
|
|
668
|
+
if (typeof data !== 'object' || data === null || Array.isArray(data)) return false;
|
|
669
|
+
const servers = data.mcpServers;
|
|
670
|
+
if (!servers || !isManagedPlaywrightMcp(servers.playwright)) return false;
|
|
671
|
+
delete servers.playwright;
|
|
672
|
+
fs.writeFileSync(mp, JSON.stringify(data, null, 2) + '\n');
|
|
673
|
+
return true;
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
function pruneManagedPlaywrightMcp(cwd) {
|
|
677
|
+
return pruneManagedPlaywrightMcpFile(path.join(cwd, '.mcp.json'));
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
function pruneManagedPlaywrightCodexConfigFile(cp) {
|
|
681
|
+
if (!fs.existsSync(cp)) return false;
|
|
682
|
+
const before = fs.readFileSync(cp, 'utf8');
|
|
683
|
+
const range = tomlSectionRange(before, 'mcp_servers.playwright');
|
|
684
|
+
if (!range) return false;
|
|
685
|
+
const section = before.slice(range.start, range.end);
|
|
686
|
+
if (!section.includes('@playwright/mcp')) return false;
|
|
687
|
+
const updated = (before.slice(0, range.start) + before.slice(range.end)).replace(/\n{3,}/g, '\n\n').replace(/\s*$/, '\n');
|
|
688
|
+
fs.writeFileSync(cp, updated);
|
|
689
|
+
return true;
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
function pruneManagedPlaywrightCodexConfig(cwd) {
|
|
693
|
+
return pruneManagedPlaywrightCodexConfigFile(path.join(cwd, '.codex', 'config.toml'));
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
function pruneGlobalManagedPlaywrightMcp(homeDir) {
|
|
697
|
+
const home = homeDir || os.homedir();
|
|
698
|
+
let changed = 0;
|
|
699
|
+
if (pruneManagedPlaywrightMcpFile(path.join(home, '.mcp.json'))) changed++;
|
|
700
|
+
if (pruneManagedPlaywrightMcpFile(path.join(home, '.claude', 'mcp-configs', 'mcp-servers.json'))) changed++;
|
|
701
|
+
if (pruneManagedPlaywrightCodexConfigFile(path.join(home, '.claude', '.codex', 'config.toml'))) changed++;
|
|
702
|
+
if (pruneManagedPlaywrightCodexConfigFile(path.join(home, '.codex', 'config.toml'))) changed++;
|
|
703
|
+
return changed;
|
|
704
|
+
}
|
|
705
|
+
|
|
647
706
|
// Append the claudeflow runtime/cache paths to the project's .gitignore, ADD-IF-ABSENT. These hold TEST
|
|
648
707
|
// credentials / Playwright storage state and Python hook bytecode; they must never be committed. Create the file if missing; else
|
|
649
708
|
// append only the lines NOT already present as an EXACT line (a `Set.has()` on the trimmed existing lines —
|
|
@@ -714,16 +773,19 @@ function installFromPayload(src, cwd, options = {}) {
|
|
|
714
773
|
globalAgents: 0,
|
|
715
774
|
globalChanged: 0,
|
|
716
775
|
globalBackups: 0,
|
|
776
|
+
globalMcpPruned: 0,
|
|
717
777
|
localBackups: 0,
|
|
718
778
|
ownershipRepaired: 0,
|
|
719
779
|
codexSkills: 0,
|
|
720
780
|
codexAgents: 0,
|
|
721
781
|
codexHooks: false,
|
|
722
782
|
codexConfig: false,
|
|
783
|
+
codexConfigPruned: false,
|
|
723
784
|
codexMarketplace: false,
|
|
724
785
|
codexPlugin: 0,
|
|
725
786
|
docs: 0,
|
|
726
787
|
mcp: 0,
|
|
788
|
+
mcpPruned: false,
|
|
727
789
|
serenaMcp: 0,
|
|
728
790
|
serenaCodexConfig: false,
|
|
729
791
|
tooling: {},
|
|
@@ -834,6 +896,7 @@ function installFromPayload(src, cwd, options = {}) {
|
|
|
834
896
|
out.globalAgents = r.agents;
|
|
835
897
|
out.globalChanged = r.changed;
|
|
836
898
|
out.globalBackups = r.backups;
|
|
899
|
+
out.globalMcpPruned = pruneGlobalManagedPlaywrightMcp(options.globalHome || os.homedir());
|
|
837
900
|
if (r.failed) {
|
|
838
901
|
out.failed.push(`global-claude-artifacts:${r.failed}`);
|
|
839
902
|
for (const f of r.failures || []) out.failed.push(f);
|
|
@@ -882,6 +945,9 @@ function installFromPayload(src, cwd, options = {}) {
|
|
|
882
945
|
});
|
|
883
946
|
|
|
884
947
|
// 7) .mcp.json — seed the base MCP servers (add-if-absent; never clobber the user's own servers).
|
|
948
|
+
step('mcp-prune-playwright', () => {
|
|
949
|
+
out.mcpPruned = pruneManagedPlaywrightMcp(cwd);
|
|
950
|
+
});
|
|
885
951
|
step('mcp', () => {
|
|
886
952
|
const srcMcp = path.join(src, 'assets', 'mcp.base.json');
|
|
887
953
|
if (fs.existsSync(srcMcp)) {
|
|
@@ -910,6 +976,7 @@ function installFromPayload(src, cwd, options = {}) {
|
|
|
910
976
|
if (fs.existsSync(srcHooks)) out.codexHooks = mergeCodexHooks(cwd, JSON.parse(fs.readFileSync(srcHooks, 'utf8')));
|
|
911
977
|
});
|
|
912
978
|
step('codex-config', () => {
|
|
979
|
+
out.codexConfigPruned = pruneManagedPlaywrightCodexConfig(cwd);
|
|
913
980
|
const srcConfig = path.join(src, '.codex', 'config.toml');
|
|
914
981
|
if (fs.existsSync(srcConfig)) out.codexConfig = mergeCodexConfig(cwd, fs.readFileSync(srcConfig, 'utf8'));
|
|
915
982
|
});
|
|
@@ -1025,12 +1092,14 @@ async function run() {
|
|
|
1025
1092
|
+ (summary.globalBackups ? `, ${summary.globalBackups} backups` : '')
|
|
1026
1093
|
+ ')'
|
|
1027
1094
|
: '')
|
|
1095
|
+
+ (summary.globalMcpPruned ? ` · global Playwright MCP removed (${summary.globalMcpPruned})` : '')
|
|
1028
1096
|
+ (summary.localBackups ? ` · ${summary.localBackups} local stale path${summary.localBackups > 1 ? 's' : ''} moved to backup` : '')
|
|
1029
1097
|
+ (summary.ownershipRepaired ? ` · ownership restored on ${summary.ownershipRepaired} path${summary.ownershipRepaired > 1 ? 's' : ''}` : '')
|
|
1030
1098
|
+ (summary.codexSkills ? ` · ${summary.codexSkills} Codex skills` : '')
|
|
1031
1099
|
+ (summary.codexAgents ? ` · ${summary.codexAgents} Codex agents` : '')
|
|
1032
1100
|
+ (summary.codexHooks ? ' · Codex hooks merged' : '')
|
|
1033
1101
|
+ (summary.codexConfig ? ' · Codex config synced' : '')
|
|
1102
|
+
+ (summary.mcpPruned || summary.codexConfigPruned ? ' · Playwright MCP removed' : '')
|
|
1034
1103
|
+ (summary.tooling && summary.tooling.serena && summary.tooling.serena.status === 'ready' ? ' · Serena ready' : '')
|
|
1035
1104
|
+ (summary.tooling && summary.tooling.astGrep && summary.tooling.astGrep.status === 'ready' ? ' · ast-grep ready' : '')
|
|
1036
1105
|
+ (summary.serenaMcp || summary.serenaCodexConfig ? ' · Serena MCP configured' : '')
|
|
@@ -1061,6 +1130,9 @@ module.exports.syncClaudeMd = syncClaudeMd;
|
|
|
1061
1130
|
module.exports.syncAgentsMd = syncAgentsMd;
|
|
1062
1131
|
module.exports.syncGlobalClaudeArtifacts = syncGlobalClaudeArtifacts;
|
|
1063
1132
|
module.exports.mergeMcp = mergeMcp;
|
|
1133
|
+
module.exports.pruneManagedPlaywrightMcp = pruneManagedPlaywrightMcp;
|
|
1134
|
+
module.exports.pruneManagedPlaywrightCodexConfig = pruneManagedPlaywrightCodexConfig;
|
|
1135
|
+
module.exports.pruneGlobalManagedPlaywrightMcp = pruneGlobalManagedPlaywrightMcp;
|
|
1064
1136
|
module.exports.mergeGitignore = mergeGitignore;
|
|
1065
1137
|
module.exports.mergeCodexHooks = mergeCodexHooks;
|
|
1066
1138
|
module.exports.mergeCodexConfig = mergeCodexConfig;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axiomatic-labs/claudeflow",
|
|
3
|
-
"version": "2.49.
|
|
3
|
+
"version": "2.49.32",
|
|
4
4
|
"description": "Claudeflow — AI-powered development toolkit for Claude Code and Codex. Skills, agents, hooks, and quality gates that ship production apps.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"claudeflow": "./bin/cli.js"
|