@a5c-ai/atlas-genty 5.0.1-staging.28347f861706
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/AGENTS.md +6 -0
- package/README.md +35 -0
- package/bin/cli.cjs +96 -0
- package/bin/install-shared.cjs +156 -0
- package/bin/install.cjs +30 -0
- package/bin/uninstall.cjs +24 -0
- package/commands/collect-nuances.md +11 -0
- package/commands/discover.md +11 -0
- package/commands/mine-data.md +11 -0
- package/commands/mine-processes.md +11 -0
- package/extensions/index.ts +37 -0
- package/package.json +57 -0
- package/scripts/create-release-tag.mjs +18 -0
- package/scripts/publish-from-tag.mjs +41 -0
- package/scripts/team-install.cjs +23 -0
- package/skills/atlas/SKILL.md +77 -0
- package/skills/atlas-graph-query/SKILL.md +60 -0
- package/versions.json +4 -0
package/AGENTS.md
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
This file was generated by @a5c-ai/extensions-adapter for target `genty`.
|
|
4
|
+
|
|
5
|
+
The plugin manifest for `atlas` does not declare a dedicated AGENTS.md source file.
|
|
6
|
+
Add `agents` and/or `contextFiles.genty` in `plugin.json` to replace this placeholder with real target guidance.
|
package/README.md
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Atlas Plugin for Genty
|
|
2
|
+
|
|
3
|
+
Atlas turns a stated need into a full system design by mining the Atlas
|
|
4
|
+
knowledge graph. This is the Genty harness surface for the `atlas` plugin.
|
|
5
|
+
|
|
6
|
+
## What's Included
|
|
7
|
+
|
|
8
|
+
- **Skills**: `atlas` (the need → design brain) and `atlas-graph-query`
|
|
9
|
+
(a reference for the Atlas MCP tool surface).
|
|
10
|
+
- **Commands**: `/atlas:discover`, `/atlas:mine-processes`,
|
|
11
|
+
`/atlas:mine-data`, `/atlas:collect-nuances` — each delegates orchestration
|
|
12
|
+
to the `babysitter:babysit` skill using an atlas-specific `.a5c` process.
|
|
13
|
+
- **MCP**: the Atlas knowledge-graph server (`atlas`), wired natively into
|
|
14
|
+
Genty's own MCP config format.
|
|
15
|
+
|
|
16
|
+
## Atlas MCP
|
|
17
|
+
|
|
18
|
+
The Atlas MCP server is wired natively for Genty — no manual setup. It
|
|
19
|
+
defaults to `https://atlas-staging.a5c.ai/api/mcp` and is overridable at
|
|
20
|
+
runtime via the `ATLAS_MCP_URL` environment variable. The
|
|
21
|
+
`mcp__atlas__atlas_public_*` tools are then available to the atlas skills.
|
|
22
|
+
|
|
23
|
+
## Installation
|
|
24
|
+
|
|
25
|
+
Atlas commands delegate orchestration to Babysitter, so install the Babysitter
|
|
26
|
+
CLI once, then install this plugin for Genty:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install -g @a5c-ai/babysitter
|
|
30
|
+
babysitter harness:install-plugin genty
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## License
|
|
34
|
+
|
|
35
|
+
See the repository license.
|
package/bin/cli.cjs
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const { spawnSync } = require('child_process');
|
|
6
|
+
|
|
7
|
+
const PACKAGE_ROOT = path.resolve(__dirname, '..');
|
|
8
|
+
let shared;
|
|
9
|
+
try { shared = require('./install-shared'); } catch {}
|
|
10
|
+
|
|
11
|
+
function printUsage() {
|
|
12
|
+
console.error([
|
|
13
|
+
'Usage:',
|
|
14
|
+
' atlas-genty install [--global]',
|
|
15
|
+
' atlas-genty install --workspace [path]',
|
|
16
|
+
' atlas-genty uninstall',
|
|
17
|
+
].join('\n'));
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function parseInstallArgs(argv) {
|
|
21
|
+
let scope = 'global';
|
|
22
|
+
let workspace = null;
|
|
23
|
+
const passthrough = [];
|
|
24
|
+
|
|
25
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
26
|
+
const arg = argv[i];
|
|
27
|
+
if (arg === '--global') {
|
|
28
|
+
scope = 'global';
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if (arg === '--workspace') {
|
|
32
|
+
scope = 'workspace';
|
|
33
|
+
const next = argv[i + 1];
|
|
34
|
+
if (next && !next.startsWith('-')) {
|
|
35
|
+
workspace = path.resolve(next);
|
|
36
|
+
i += 1;
|
|
37
|
+
} else {
|
|
38
|
+
workspace = process.cwd();
|
|
39
|
+
}
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
passthrough.push(arg);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return { scope, workspace, passthrough };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function runNodeScript(scriptPath, args, extraEnv = {}) {
|
|
49
|
+
const result = spawnSync(process.execPath, [scriptPath, ...args], {
|
|
50
|
+
cwd: process.cwd(),
|
|
51
|
+
stdio: 'inherit',
|
|
52
|
+
env: { ...process.env, ...extraEnv },
|
|
53
|
+
});
|
|
54
|
+
process.exitCode = result.status ?? 1;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function main() {
|
|
58
|
+
const [command, ...rest] = process.argv.slice(2);
|
|
59
|
+
if (!command || command === '--help' || command === '-h' || command === 'help') {
|
|
60
|
+
printUsage();
|
|
61
|
+
process.exitCode = command ? 0 : 1;
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (command === 'install') {
|
|
66
|
+
if (shared && typeof shared.harnessCliRoute === 'function' && shared.harnessCliRoute(rest, PACKAGE_ROOT, runNodeScript)) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const parsed = parseInstallArgs(rest);
|
|
70
|
+
if (parsed.scope === 'workspace') {
|
|
71
|
+
const args = [];
|
|
72
|
+
if (parsed.workspace) {
|
|
73
|
+
args.push('--workspace', parsed.workspace);
|
|
74
|
+
}
|
|
75
|
+
args.push(...parsed.passthrough);
|
|
76
|
+
runNodeScript(
|
|
77
|
+
path.join(PACKAGE_ROOT, 'scripts', 'team-install.cjs'),
|
|
78
|
+
args,
|
|
79
|
+
{ PLUGIN_PACKAGE_ROOT: PACKAGE_ROOT },
|
|
80
|
+
);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
runNodeScript(path.join(PACKAGE_ROOT, 'bin', 'install.cjs'), parsed.passthrough);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (command === 'uninstall') {
|
|
88
|
+
runNodeScript(path.join(PACKAGE_ROOT, 'bin', 'uninstall.cjs'), rest);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
printUsage();
|
|
93
|
+
process.exitCode = 1;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
main();
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const os = require('os');
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const { spawnSync } = require('child_process');
|
|
7
|
+
|
|
8
|
+
const PLUGIN_NAME = "atlas";
|
|
9
|
+
const PLUGIN_CATEGORY = 'Coding';
|
|
10
|
+
|
|
11
|
+
function getUserHome() {
|
|
12
|
+
return os.homedir();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function getHarnessHome() {
|
|
16
|
+
return path.join(os.homedir(), '.a5c');
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function getHomePluginRoot(scope) {
|
|
20
|
+
if (scope === 'workspace') return path.join(process.cwd(), '.a5c', 'plugins', PLUGIN_NAME);
|
|
21
|
+
return path.join(path.join(getHarnessHome(), 'plugins'), PLUGIN_NAME);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function getHomeMarketplacePath() {
|
|
25
|
+
return path.join(getHarnessHome(), 'plugins', 'marketplace.json');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function writeFileIfChanged(filePath, contents) {
|
|
29
|
+
try {
|
|
30
|
+
const existing = fs.readFileSync(filePath, 'utf8');
|
|
31
|
+
if (existing === contents) return false;
|
|
32
|
+
} catch (e) { process.stderr.write('[extensions-adapter] file read failed for ' + filePath + ', overwriting: ' + (e instanceof Error ? e.message : String(e)) + '\n'); }
|
|
33
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
34
|
+
fs.writeFileSync(filePath, contents);
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function copyRecursive(src, dest) {
|
|
39
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
40
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
41
|
+
if (entry.name === 'node_modules' || entry.name === '.git') continue;
|
|
42
|
+
const s = path.join(src, entry.name);
|
|
43
|
+
const d = path.join(dest, entry.name);
|
|
44
|
+
if (entry.isDirectory()) {
|
|
45
|
+
copyRecursive(s, d);
|
|
46
|
+
} else {
|
|
47
|
+
fs.copyFileSync(s, d);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function copyPluginBundle(packageRoot, pluginRoot) {
|
|
53
|
+
const bundleEntries = fs.readdirSync(packageRoot).filter(
|
|
54
|
+
e => !['node_modules', '.git', 'test', 'dist'].includes(e)
|
|
55
|
+
);
|
|
56
|
+
fs.mkdirSync(pluginRoot, { recursive: true });
|
|
57
|
+
for (const entry of bundleEntries) {
|
|
58
|
+
const src = path.join(packageRoot, entry);
|
|
59
|
+
const dest = path.join(pluginRoot, entry);
|
|
60
|
+
const stat = fs.statSync(src);
|
|
61
|
+
if (stat.isDirectory()) {
|
|
62
|
+
copyRecursive(src, dest);
|
|
63
|
+
} else {
|
|
64
|
+
fs.copyFileSync(src, dest);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function readJson(filePath) {
|
|
70
|
+
try {
|
|
71
|
+
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
72
|
+
} catch {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function writeJson(filePath, value) {
|
|
78
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
79
|
+
fs.writeFileSync(filePath, JSON.stringify(value, null, 2) + '\n');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function ensureExecutable(filePath) {
|
|
83
|
+
try {
|
|
84
|
+
fs.chmodSync(filePath, 0o755);
|
|
85
|
+
} catch (e) { process.stderr.write('[extensions-adapter] chmod failed for ' + filePath + ': ' + (e instanceof Error ? e.message : String(e)) + '\n'); }
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function normalizeMarketplaceSourcePath(source, marketplacePath) {
|
|
89
|
+
if (typeof source === 'string') {
|
|
90
|
+
return path.relative(path.dirname(marketplacePath), source).replace(/\\/g, '/');
|
|
91
|
+
}
|
|
92
|
+
return source;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function ensureMarketplaceEntry(marketplacePath, pluginRoot) {
|
|
96
|
+
let marketplace = readJson(marketplacePath) || {
|
|
97
|
+
name: "a5c.ai",
|
|
98
|
+
plugins: [],
|
|
99
|
+
};
|
|
100
|
+
if (!Array.isArray(marketplace.plugins)) marketplace.plugins = [];
|
|
101
|
+
const idx = marketplace.plugins.findIndex(p => p.name === PLUGIN_NAME);
|
|
102
|
+
const relSource = './' + normalizeMarketplaceSourcePath(pluginRoot, marketplacePath);
|
|
103
|
+
const entry = {
|
|
104
|
+
name: PLUGIN_NAME,
|
|
105
|
+
source: relSource,
|
|
106
|
+
description: "Turn a stated need into a full system design by mining the Atlas knowledge graph.",
|
|
107
|
+
version: "5.0.1-staging.28347f861706",
|
|
108
|
+
author: { name: "a5c.ai" },
|
|
109
|
+
};
|
|
110
|
+
if (idx >= 0) marketplace.plugins[idx] = entry;
|
|
111
|
+
else marketplace.plugins.push(entry);
|
|
112
|
+
writeJson(marketplacePath, marketplace);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function removeMarketplaceEntry(marketplacePath) {
|
|
116
|
+
const marketplace = readJson(marketplacePath);
|
|
117
|
+
if (!marketplace || !Array.isArray(marketplace.plugins)) return;
|
|
118
|
+
marketplace.plugins = marketplace.plugins.filter(p => p.name !== PLUGIN_NAME);
|
|
119
|
+
writeJson(marketplacePath, marketplace);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function warnWindowsHooks() {
|
|
123
|
+
if (process.platform === 'win32') {
|
|
124
|
+
console.warn('[' + PLUGIN_NAME + '] Windows detected — shell hooks (.sh) require Git Bash or WSL.');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function runPostInstall(pluginRoot) {
|
|
129
|
+
const postInstall = path.join(pluginRoot, 'scripts', 'post-install.js');
|
|
130
|
+
if (fs.existsSync(postInstall)) {
|
|
131
|
+
spawnSync(process.execPath, [postInstall], {
|
|
132
|
+
cwd: pluginRoot, stdio: 'inherit',
|
|
133
|
+
env: { ...process.env, PLUGIN_ROOT: pluginRoot, CLAUDE_PLUGIN_ROOT: pluginRoot },
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
module.exports = {
|
|
139
|
+
PLUGIN_NAME,
|
|
140
|
+
PLUGIN_CATEGORY,
|
|
141
|
+
getUserHome,
|
|
142
|
+
getHarnessHome,
|
|
143
|
+
getHomePluginRoot,
|
|
144
|
+
getHomeMarketplacePath,
|
|
145
|
+
writeFileIfChanged,
|
|
146
|
+
copyRecursive,
|
|
147
|
+
copyPluginBundle,
|
|
148
|
+
readJson,
|
|
149
|
+
writeJson,
|
|
150
|
+
ensureExecutable,
|
|
151
|
+
normalizeMarketplaceSourcePath,
|
|
152
|
+
ensureMarketplaceEntry,
|
|
153
|
+
removeMarketplaceEntry,
|
|
154
|
+
warnWindowsHooks,
|
|
155
|
+
runPostInstall,
|
|
156
|
+
};
|
package/bin/install.cjs
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const shared = require('./install-shared');
|
|
6
|
+
|
|
7
|
+
const PACKAGE_ROOT = path.resolve(__dirname, '..');
|
|
8
|
+
|
|
9
|
+
function main() {
|
|
10
|
+
const pluginRoot = shared.getHomePluginRoot();
|
|
11
|
+
const marketplacePath = shared.getHomeMarketplacePath();
|
|
12
|
+
|
|
13
|
+
console.log(`[${shared.PLUGIN_NAME}] Installing plugin to ${pluginRoot}`);
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
shared.copyPluginBundle(PACKAGE_ROOT, pluginRoot);
|
|
17
|
+
shared.ensureMarketplaceEntry(marketplacePath, pluginRoot);
|
|
18
|
+
if (typeof shared.harnessInstall === 'function') {
|
|
19
|
+
shared.harnessInstall(PACKAGE_ROOT, pluginRoot);
|
|
20
|
+
}
|
|
21
|
+
shared.runPostInstall && shared.runPostInstall(pluginRoot);
|
|
22
|
+
console.log(`[${shared.PLUGIN_NAME}] Installation complete!`);
|
|
23
|
+
console.log(`[${shared.PLUGIN_NAME}] Restart your IDE/CLI to pick up the plugin.`);
|
|
24
|
+
} catch (err) {
|
|
25
|
+
console.error(`[${shared.PLUGIN_NAME}] Failed to install: ${err.message}`);
|
|
26
|
+
process.exitCode = 1;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
main();
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const fs = require('fs');
|
|
5
|
+
const shared = require('./install-shared');
|
|
6
|
+
|
|
7
|
+
function main() {
|
|
8
|
+
const pluginRoot = shared.getHomePluginRoot();
|
|
9
|
+
|
|
10
|
+
if (!fs.existsSync(pluginRoot)) {
|
|
11
|
+
console.log(`[${shared.PLUGIN_NAME}] Plugin not installed at ${pluginRoot}`);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
fs.rmSync(pluginRoot, { recursive: true, force: true });
|
|
17
|
+
console.log(`[${shared.PLUGIN_NAME}] Uninstalled from ${pluginRoot}`);
|
|
18
|
+
} catch (err) {
|
|
19
|
+
console.error(`[${shared.PLUGIN_NAME}] Failed to uninstall: ${err.message}`);
|
|
20
|
+
process.exitCode = 1;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
main();
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Collect nuances — gather domain-specific edge cases, constraints, and gotchas from the Atlas graph.
|
|
3
|
+
argument-hint: The domain/system to collect nuances for.
|
|
4
|
+
allowed-tools: Read, Grep, Write, Task, Bash, Edit, Glob, AskUserQuestion, TodoWrite, Skill, mcp__atlas__atlas_public_search, mcp__atlas__atlas_public_record, mcp__atlas__atlas_public_neighbors, mcp__atlas__atlas_public_kinds, mcp__atlas__atlas_public_clusters, mcp__atlas__atlas_public_wiki_page
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Invoke the babysitter:babysit skill (using the Skill tool) and follow its instructions (SKILL.md) to run the atlas process `atlas-collect-nuances`. Pass the user arguments below as the run's stated need. Then continue executing the returned instructions in this same turn; do not stop after the Skill tool returns. Use the atlas skill and the Atlas MCP tools (mcp__atlas__atlas_public_*) for all graph queries.
|
|
8
|
+
|
|
9
|
+
User arguments for this command:
|
|
10
|
+
|
|
11
|
+
$ARGUMENTS
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Interactive systems discovery — turn a stated need into a full system design via the Atlas graph.
|
|
3
|
+
argument-hint: The system/need to design.
|
|
4
|
+
allowed-tools: Read, Grep, Write, Task, Bash, Edit, Glob, AskUserQuestion, TodoWrite, Skill, mcp__atlas__atlas_public_search, mcp__atlas__atlas_public_record, mcp__atlas__atlas_public_neighbors, mcp__atlas__atlas_public_kinds, mcp__atlas__atlas_public_clusters, mcp__atlas__atlas_public_wiki_page
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Invoke the babysitter:babysit skill (using the Skill tool) and follow its instructions (SKILL.md) to run the atlas process `atlas-systems-discovery`. Pass the user arguments below as the run's stated need. Then continue executing the returned instructions in this same turn; do not stop after the Skill tool returns. Use the atlas skill and the Atlas MCP tools (mcp__atlas__atlas_public_*) for all graph queries.
|
|
8
|
+
|
|
9
|
+
User arguments for this command:
|
|
10
|
+
|
|
11
|
+
$ARGUMENTS
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Data mining — discover the data models/entities a domain requires from the Atlas graph.
|
|
3
|
+
argument-hint: The domain or goal to mine data for.
|
|
4
|
+
allowed-tools: Read, Grep, Write, Task, Bash, Edit, Glob, AskUserQuestion, TodoWrite, Skill, mcp__atlas__atlas_public_search, mcp__atlas__atlas_public_record, mcp__atlas__atlas_public_neighbors, mcp__atlas__atlas_public_kinds, mcp__atlas__atlas_public_clusters, mcp__atlas__atlas_public_wiki_page
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Invoke the babysitter:babysit skill (using the Skill tool) and follow its instructions (SKILL.md) to run the atlas process `atlas-data-mining`. Pass the user arguments below as the run's stated need. Then continue executing the returned instructions in this same turn; do not stop after the Skill tool returns. Use the atlas skill and the Atlas MCP tools (mcp__atlas__atlas_public_*) for all graph queries.
|
|
8
|
+
|
|
9
|
+
User arguments for this command:
|
|
10
|
+
|
|
11
|
+
$ARGUMENTS
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Process mining — discover the processes/workflows a domain requires from the Atlas graph.
|
|
3
|
+
argument-hint: The domain or goal to mine processes for.
|
|
4
|
+
allowed-tools: Read, Grep, Write, Task, Bash, Edit, Glob, AskUserQuestion, TodoWrite, Skill, mcp__atlas__atlas_public_search, mcp__atlas__atlas_public_record, mcp__atlas__atlas_public_neighbors, mcp__atlas__atlas_public_kinds, mcp__atlas__atlas_public_clusters, mcp__atlas__atlas_public_wiki_page
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Invoke the babysitter:babysit skill (using the Skill tool) and follow its instructions (SKILL.md) to run the atlas process `atlas-process-mining`. Pass the user arguments below as the run's stated need. Then continue executing the returned instructions in this same turn; do not stop after the Skill tool returns. Use the atlas skill and the Atlas MCP tools (mcp__atlas__atlas_public_*) for all graph queries.
|
|
8
|
+
|
|
9
|
+
User arguments for this command:
|
|
10
|
+
|
|
11
|
+
$ARGUMENTS
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// Programmatic extension for genty
|
|
2
|
+
// Generated by extensions-adapter compiler
|
|
3
|
+
|
|
4
|
+
import { execSync } from "child_process";
|
|
5
|
+
import * as path from "path";
|
|
6
|
+
|
|
7
|
+
const PLUGIN_ROOT = path.resolve(__dirname, "..");
|
|
8
|
+
|
|
9
|
+
function runProxiedHook(
|
|
10
|
+
scriptName: string,
|
|
11
|
+
inputData?: Record<string, unknown>
|
|
12
|
+
): Record<string, unknown> {
|
|
13
|
+
const scriptPath = path.join(PLUGIN_ROOT, "hooks", scriptName);
|
|
14
|
+
try {
|
|
15
|
+
const result = execSync(`node "${scriptPath}"`, {
|
|
16
|
+
input: inputData ? JSON.stringify(inputData) : undefined,
|
|
17
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
18
|
+
timeout: 30000,
|
|
19
|
+
env: {
|
|
20
|
+
...process.env,
|
|
21
|
+
GENTY_PLUGIN_ROOT: PLUGIN_ROOT,
|
|
22
|
+
CLAUDE_PLUGIN_ROOT: PLUGIN_ROOT,
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
return JSON.parse(result.toString("utf8").trim());
|
|
26
|
+
} catch {
|
|
27
|
+
return {};
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const COMMANDS = [
|
|
32
|
+
"atlas-graph-query", "collect-nuances", "discover", "mine-data", "mine-processes"
|
|
33
|
+
] as const;
|
|
34
|
+
|
|
35
|
+
export function activate(api: unknown): void {
|
|
36
|
+
// Register commands via target-specific API
|
|
37
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@a5c-ai/atlas-genty",
|
|
3
|
+
"version": "5.0.1-staging.28347f861706",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Turn a stated need into a full system design by mining the Atlas knowledge graph. — genty",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"genty",
|
|
8
|
+
"atlas",
|
|
9
|
+
"orchestration"
|
|
10
|
+
],
|
|
11
|
+
"genty": {
|
|
12
|
+
"extensions": [
|
|
13
|
+
"./extensions"
|
|
14
|
+
],
|
|
15
|
+
"skills": [
|
|
16
|
+
"./skills"
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"@a5c-ai/genty-core": "*"
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"test": "npm run validate:ci",
|
|
24
|
+
"test:integration": "node --test test/integration.test.js",
|
|
25
|
+
"test:packaged-install": "node test/packaged-install.test.cjs",
|
|
26
|
+
"validate:ci": "npm run test:integration && npm run test:packaged-install",
|
|
27
|
+
"deploy": "npm publish --access public",
|
|
28
|
+
"deploy:staging": "npm publish --access public --tag staging"
|
|
29
|
+
},
|
|
30
|
+
"bin": {
|
|
31
|
+
"atlas-genty": "bin/cli.cjs"
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"bin/",
|
|
35
|
+
"package.json",
|
|
36
|
+
"versions.json",
|
|
37
|
+
"README.md",
|
|
38
|
+
"AGENTS.md",
|
|
39
|
+
"extensions/",
|
|
40
|
+
"skills/",
|
|
41
|
+
"commands/",
|
|
42
|
+
"scripts/"
|
|
43
|
+
],
|
|
44
|
+
"author": "a5c.ai",
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public"
|
|
48
|
+
},
|
|
49
|
+
"repository": {
|
|
50
|
+
"type": "git",
|
|
51
|
+
"url": "git+https://github.com/a5c-ai/atlas-genty.git"
|
|
52
|
+
},
|
|
53
|
+
"homepage": "https://github.com/a5c-ai/atlas-genty#readme",
|
|
54
|
+
"bugs": {
|
|
55
|
+
"url": "https://github.com/a5c-ai/atlas-genty/issues"
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
4
|
+
|
|
5
|
+
function run(command, args) {
|
|
6
|
+
const result = spawnSync(command, args, { encoding: 'utf8', stdio: 'inherit' });
|
|
7
|
+
if (result.status !== 0) process.exit(result.status || 1);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const branch = process.env.GITHUB_REF_NAME || 'develop';
|
|
11
|
+
const sha = (process.env.GITHUB_SHA || '').slice(0, 12);
|
|
12
|
+
const version = existsSync('package.json') ? JSON.parse(readFileSync('package.json', 'utf8')).version : JSON.parse(readFileSync('versions.json', 'utf8')).sdkVersion;
|
|
13
|
+
const normalized = String(version).replace(/[^0-9A-Za-z._-]/g, '-');
|
|
14
|
+
const tag = 'release/' + branch + '/v' + normalized + '-' + sha;
|
|
15
|
+
run('git', ['config', 'user.name', 'github-actions[bot]']);
|
|
16
|
+
run('git', ['config', 'user.email', 'github-actions[bot]@users.noreply.github.com']);
|
|
17
|
+
run('git', ['tag', tag]);
|
|
18
|
+
run('git', ['push', 'origin', tag]);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
3
|
+
import { readFileSync } from 'node:fs';
|
|
4
|
+
|
|
5
|
+
function run(command, args, options = {}) {
|
|
6
|
+
const result = spawnSync(command, args, { stdio: options.stdio || 'inherit', encoding: options.encoding });
|
|
7
|
+
if (result.status !== 0 && !options.allowFailure) process.exit(result.status || 1);
|
|
8
|
+
return result;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function npmView(packageSpec) {
|
|
12
|
+
return run('npm', ['view', packageSpec, 'version'], { allowFailure: true, stdio: 'pipe', encoding: 'utf8' }).status === 0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const pkg = JSON.parse(readFileSync('package.json', 'utf8'));
|
|
16
|
+
const ref = process.env.GITHUB_REF_NAME || '';
|
|
17
|
+
const branch = ref.split('/')[1] || 'develop';
|
|
18
|
+
const tag = branch === 'main' ? 'latest' : branch;
|
|
19
|
+
|
|
20
|
+
if (!process.env.NODE_AUTH_TOKEN) {
|
|
21
|
+
console.log('NODE_AUTH_TOKEN is not configured; skipping npm publish.');
|
|
22
|
+
process.exit(0);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (npmView(pkg.name + '@' + pkg.version)) {
|
|
26
|
+
console.log(pkg.name + '@' + pkg.version + ' already exists; ensuring dist-tag ' + tag + '.');
|
|
27
|
+
run('npm', ['dist-tag', 'add', pkg.name + '@' + pkg.version, tag], { allowFailure: true });
|
|
28
|
+
process.exit(0);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
for (const field of ['dependencies', 'peerDependencies', 'optionalDependencies']) {
|
|
32
|
+
for (const [name, version] of Object.entries(pkg[field] || {})) {
|
|
33
|
+
if (!name.startsWith('@a5c-ai/') || version.startsWith('^') || version.startsWith('~') || version === '*' || version.startsWith('workspace:')) continue;
|
|
34
|
+
if (!npmView(name + '@' + version)) {
|
|
35
|
+
console.log('Required internal dependency ' + name + '@' + version + ' is not published yet; skipping npm publish.');
|
|
36
|
+
process.exit(0);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
run('npm', ['publish', '--access', 'public', '--tag', tag]);
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var path = require('path');
|
|
5
|
+
var shared = require('../bin/install-shared.cjs');
|
|
6
|
+
|
|
7
|
+
var workspace = process.cwd();
|
|
8
|
+
for (var i = 0; i < process.argv.length; i++) {
|
|
9
|
+
if (process.argv[i] === '--workspace' && process.argv[i + 1]) {
|
|
10
|
+
workspace = path.resolve(process.argv[i + 1]);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
var src = process.env.PLUGIN_PACKAGE_ROOT || path.resolve(__dirname, '..');
|
|
15
|
+
var dest = shared.getHomePluginRoot('workspace');
|
|
16
|
+
console.log('[atlas] Team install to ' + dest);
|
|
17
|
+
|
|
18
|
+
shared.copyPluginBundle(src, dest);
|
|
19
|
+
if (typeof shared.harnessTeamInstall === 'function') {
|
|
20
|
+
shared.harnessTeamInstall(src, dest, workspace);
|
|
21
|
+
}
|
|
22
|
+
shared.runPostInstall(dest);
|
|
23
|
+
console.log('[atlas] Team install complete.');
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: atlas
|
|
3
|
+
description: >
|
|
4
|
+
Turn a stated need into a full system design by mining the Atlas knowledge
|
|
5
|
+
graph. Use this skill when asked to design a system from a goal, discover the
|
|
6
|
+
components/processes/data a domain needs, mine processes or data models, or
|
|
7
|
+
collect domain nuances. (atlas, design a system, what does X need, system
|
|
8
|
+
discovery, process mining, data mining, collect nuances, blueprint from a need,
|
|
9
|
+
graph-driven design)
|
|
10
|
+
allowed-tools: Read, Grep, Glob, Write, Edit, Task, Bash, AskUserQuestion, TodoWrite, Skill, mcp__atlas__atlas_public_search, mcp__atlas__atlas_public_record, mcp__atlas__atlas_public_neighbors, mcp__atlas__atlas_public_kinds, mcp__atlas__atlas_public_kind, mcp__atlas__atlas_public_clusters, mcp__atlas__atlas_public_stats, mcp__atlas__atlas_public_wiki_page
|
|
11
|
+
version: 0.1.0
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
# atlas
|
|
15
|
+
|
|
16
|
+
This skill turns a stated need into an entire system design by mining the Atlas
|
|
17
|
+
knowledge graph. It is the brain of the `atlas` plugin. For non-trivial runs it
|
|
18
|
+
delegates orchestration to `babysitter:babysit` using an atlas-specific `.a5c`
|
|
19
|
+
process; for simple lookups it queries the graph directly.
|
|
20
|
+
|
|
21
|
+
## 1. What Atlas is
|
|
22
|
+
|
|
23
|
+
Atlas is a knowledge graph of agents, processes, data models, capabilities,
|
|
24
|
+
workflows, clusters, and wiki pages. You reach it through the
|
|
25
|
+
`mcp__atlas__atlas_public_*` MCP tools, which this plugin wires natively into
|
|
26
|
+
your harness (see the plugin README "Atlas MCP" section; the server URL is
|
|
27
|
+
overridable via `ATLAS_MCP_URL`). Never assume the graph's shape — discover it
|
|
28
|
+
through the tools.
|
|
29
|
+
|
|
30
|
+
## 2. When to use
|
|
31
|
+
|
|
32
|
+
| Trigger phrase | Command |
|
|
33
|
+
|----------------|---------|
|
|
34
|
+
| design a system, blueprint from a need, graph-driven design | `/atlas:discover` |
|
|
35
|
+
| process mining, what processes does X need | `/atlas:mine-processes` |
|
|
36
|
+
| data mining, what data does X need | `/atlas:mine-data` |
|
|
37
|
+
| collect nuances, edge cases/constraints for X | `/atlas:collect-nuances` |
|
|
38
|
+
|
|
39
|
+
## 3. The need → design pipeline (core method)
|
|
40
|
+
|
|
41
|
+
1. **Frame the need** — restate the goal as a domain + concrete outcomes. If the
|
|
42
|
+
request is ambiguous, run a short interview (`AskUserQuestion`). Per repo
|
|
43
|
+
policy, interview ONLY when requirements are genuinely unclear.
|
|
44
|
+
2. **Locate anchors** — `atlas_public_search(q=<need terms>)` to find seed nodes;
|
|
45
|
+
`atlas_public_clusters` / `atlas_public_kinds` to scope the domain.
|
|
46
|
+
3. **Expand the graph** — `atlas_public_neighbors(id, depth, edges, kinds)` from
|
|
47
|
+
the anchors to gather the system's parts: components, workflows, processes,
|
|
48
|
+
data models, capabilities.
|
|
49
|
+
4. **Read detail** — `atlas_public_record(id, expandNeighbors)` for fields and
|
|
50
|
+
edges; `atlas_public_wiki_page` for narrative context.
|
|
51
|
+
5. **Synthesize the design** — assemble the discovered nodes into a layered
|
|
52
|
+
system design (components, processes, data, integrations, nuances) and write a
|
|
53
|
+
design artifact under `.a5c/atlas/<run>/design.md` plus a machine mirror.
|
|
54
|
+
6. **Converge (TDD)** — each phase asserts its own checkable outputs before
|
|
55
|
+
proceeding (see the atlas processes), iterating until the assertions pass.
|
|
56
|
+
|
|
57
|
+
## 4. How to delegate
|
|
58
|
+
|
|
59
|
+
For any non-trivial run, hand off to `babysitter:babysit` (via the Skill tool)
|
|
60
|
+
naming the matching atlas process:
|
|
61
|
+
|
|
62
|
+
- `/atlas:discover` → `atlas-systems-discovery`
|
|
63
|
+
- `/atlas:mine-processes` → `atlas-process-mining`
|
|
64
|
+
- `/atlas:mine-data` → `atlas-data-mining`
|
|
65
|
+
- `/atlas:collect-nuances` → `atlas-collect-nuances`
|
|
66
|
+
|
|
67
|
+
Do not hand-roll orchestration when a process exists.
|
|
68
|
+
|
|
69
|
+
## 5. Guardrails
|
|
70
|
+
|
|
71
|
+
- No fallbacks (repo rule). If you find yourself writing a fallback, stop and fix
|
|
72
|
+
the root cause.
|
|
73
|
+
- Never invent graph node ids — only reference ids returned by Atlas tools.
|
|
74
|
+
- Keep breakpoints sparse; use them only when user input is genuinely critical or
|
|
75
|
+
ambiguous.
|
|
76
|
+
- Do not emit `kind: 'shell'` subtasks unless the user explicitly asks for a
|
|
77
|
+
shell-oriented workflow.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: atlas-graph-query
|
|
3
|
+
description: >
|
|
4
|
+
Reference for querying the Atlas knowledge graph through its MCP tools. Use
|
|
5
|
+
when you need to look up nodes, edges, kinds, clusters, stats, or wiki pages in
|
|
6
|
+
Atlas. (atlas graph, query atlas, atlas mcp, search the graph, graph neighbors,
|
|
7
|
+
atlas record, atlas kinds)
|
|
8
|
+
allowed-tools: mcp__atlas__atlas_public_search, mcp__atlas__atlas_public_record, mcp__atlas__atlas_public_neighbors, mcp__atlas__atlas_public_kinds, mcp__atlas__atlas_public_kind, mcp__atlas__atlas_public_edge_kinds, mcp__atlas__atlas_public_edge_kind, mcp__atlas__atlas_public_clusters, mcp__atlas__atlas_public_stats, mcp__atlas__atlas_public_wiki_page
|
|
9
|
+
version: 0.1.0
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# atlas-graph-query
|
|
13
|
+
|
|
14
|
+
A thin reference for the Atlas knowledge-graph MCP tool surface so any agent
|
|
15
|
+
(including sub-agents) can query the graph without re-deriving conventions. The
|
|
16
|
+
server URL is wired natively by the `atlas` plugin and is overridable via
|
|
17
|
+
`ATLAS_MCP_URL`. Never invent node ids — only use ids returned by these tools.
|
|
18
|
+
|
|
19
|
+
## Tools
|
|
20
|
+
|
|
21
|
+
### `mcp__atlas__atlas_public_search`
|
|
22
|
+
Full-text/semantic search over the graph. Key params: `q` (query), optional
|
|
23
|
+
`kind` filter, `limit`. Prefer it to find seed/anchor nodes from need terms.
|
|
24
|
+
|
|
25
|
+
### `mcp__atlas__atlas_public_record`
|
|
26
|
+
Fetch one node's full record by `id` (fields + edges). Use `expandNeighbors` to
|
|
27
|
+
pull immediate relations in one call. Prefer it to read detail once you have ids.
|
|
28
|
+
|
|
29
|
+
### `mcp__atlas__atlas_public_neighbors`
|
|
30
|
+
Traverse the graph from a node. Key params: `id`, `depth`, `edges` (edge-kind
|
|
31
|
+
filter), `kinds` (node-kind filter). Prefer it to expand a subsystem from anchors.
|
|
32
|
+
|
|
33
|
+
### `mcp__atlas__atlas_public_kinds`
|
|
34
|
+
List all node kinds in the graph. Use to scope a domain to relevant kinds.
|
|
35
|
+
|
|
36
|
+
### `mcp__atlas__atlas_public_kind`
|
|
37
|
+
Describe a single node kind (schema/fields). Use before relying on a kind's shape.
|
|
38
|
+
|
|
39
|
+
### `mcp__atlas__atlas_public_edge_kinds`
|
|
40
|
+
List all edge kinds. Use to understand how nodes relate.
|
|
41
|
+
|
|
42
|
+
### `mcp__atlas__atlas_public_edge_kind`
|
|
43
|
+
Describe a single edge kind. Use to interpret a specific relation type.
|
|
44
|
+
|
|
45
|
+
### `mcp__atlas__atlas_public_clusters`
|
|
46
|
+
List graph clusters (thematic groupings). Use to scope a domain to cluster(s).
|
|
47
|
+
|
|
48
|
+
### `mcp__atlas__atlas_public_stats`
|
|
49
|
+
Graph-level counts/metrics. Use for sizing and sanity checks.
|
|
50
|
+
|
|
51
|
+
### `mcp__atlas__atlas_public_wiki_page`
|
|
52
|
+
Fetch a narrative wiki page for context. Use to capture human-readable nuance.
|
|
53
|
+
|
|
54
|
+
## Query recipes
|
|
55
|
+
|
|
56
|
+
- **Find by need** — `atlas_public_search(q=<need terms>)` → take top ids.
|
|
57
|
+
- **Expand a subsystem** — `atlas_public_neighbors(id, depth=2, kinds=[...])`.
|
|
58
|
+
- **Inspect a node** — `atlas_public_record(id, expandNeighbors=true)`.
|
|
59
|
+
- **Browse a cluster** — `atlas_public_clusters` → pick cluster → `search`/
|
|
60
|
+
`neighbors` scoped to it.
|
package/versions.json
ADDED