servicemap 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/README.md +51 -0
- package/bin/servicemap.mjs +98 -0
- package/package.json +34 -0
- package/servicemap/SKILL.md +40 -0
- package/servicemap/agents/openai.yaml +3 -0
- package/servicemap/assets/service-logo-database.json +13194 -0
- package/servicemap/references/desktop-fallback.md +29 -0
- package/servicemap/references/framework-routing.md +16 -0
- package/servicemap/references/page-design.md +22 -0
- package/servicemap/references/service-detection-rules.md +22 -0
- package/servicemap/scripts/generate-desktop-app.mjs +411 -0
- package/servicemap/scripts/generate-page.mjs +184 -0
- package/servicemap/scripts/scan-project.mjs +290 -0
package/README.md
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Servicemap
|
|
2
|
+
|
|
3
|
+
Reusable `servicemap` skill package and CLI.
|
|
4
|
+
|
|
5
|
+
The skill scans a software project for external services, resolves service logos from a bundled database, and creates either an `/internalservicemap` website route or a desktop app fallback.
|
|
6
|
+
|
|
7
|
+
## Terminal Use
|
|
8
|
+
|
|
9
|
+
The npm package name `servicemap` is available, so users can run the clean command:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npx servicemap
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
After a global install, the command is:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
servicemap
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Install globally:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install -g servicemap
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
CLI options:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
servicemap --root <project-path>
|
|
31
|
+
servicemap --mode page
|
|
32
|
+
servicemap --mode desktop
|
|
33
|
+
servicemap --dry-run
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Contents
|
|
37
|
+
|
|
38
|
+
- `servicemap/`: installable skill folder
|
|
39
|
+
- `bin/servicemap.mjs`: npm CLI entrypoint
|
|
40
|
+
- `servicemap/scripts/scan-project.mjs`: scans a project for service evidence
|
|
41
|
+
- `servicemap/scripts/generate-page.mjs`: creates website routes
|
|
42
|
+
- `servicemap/scripts/generate-desktop-app.mjs`: creates the desktop fallback
|
|
43
|
+
- `servicemap/assets/service-logo-database.json`: 1,000 service logo records
|
|
44
|
+
|
|
45
|
+
## Validation
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
node bin/servicemap.mjs --root demo-project --dry-run
|
|
49
|
+
node bin/servicemap.mjs --root no-website-demo --dry-run
|
|
50
|
+
python3 /Users/dougie/.codex/skills/.system/skill-creator/scripts/quick_validate.py servicemap
|
|
51
|
+
```
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
|
+
import { readFile } from 'node:fs/promises';
|
|
4
|
+
import { dirname, resolve } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
|
|
7
|
+
const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
8
|
+
const scanScript = resolve(packageRoot, 'servicemap/scripts/scan-project.mjs');
|
|
9
|
+
const pageScript = resolve(packageRoot, 'servicemap/scripts/generate-page.mjs');
|
|
10
|
+
const desktopScript = resolve(packageRoot, 'servicemap/scripts/generate-desktop-app.mjs');
|
|
11
|
+
|
|
12
|
+
function parseArgs() {
|
|
13
|
+
const args = process.argv.slice(2);
|
|
14
|
+
const options = {
|
|
15
|
+
root: process.cwd(),
|
|
16
|
+
mode: 'auto',
|
|
17
|
+
dryRun: false,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
21
|
+
const arg = args[index];
|
|
22
|
+
if (arg === '--root') options.root = args[++index] ?? options.root;
|
|
23
|
+
if (arg === '--mode') options.mode = args[++index] ?? options.mode;
|
|
24
|
+
if (arg === '--dry-run') options.dryRun = true;
|
|
25
|
+
if (arg === '--help' || arg === '-h') options.help = true;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
options.root = resolve(options.root);
|
|
29
|
+
return options;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function help() {
|
|
33
|
+
console.log(`Servicemap
|
|
34
|
+
|
|
35
|
+
Usage:
|
|
36
|
+
servicemap [--root <project>] [--mode auto|page|desktop] [--dry-run]
|
|
37
|
+
|
|
38
|
+
Examples:
|
|
39
|
+
npx servicemap
|
|
40
|
+
npx servicemap -- --root ../my-app
|
|
41
|
+
servicemap --mode desktop
|
|
42
|
+
`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function run(command, args, options = {}) {
|
|
46
|
+
return new Promise((resolvePromise, reject) => {
|
|
47
|
+
const child = spawn(command, args, {
|
|
48
|
+
stdio: 'inherit',
|
|
49
|
+
...options,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
child.on('error', reject);
|
|
53
|
+
child.on('exit', (code) => {
|
|
54
|
+
if (code === 0) resolvePromise();
|
|
55
|
+
else reject(new Error(`${command} ${args.join(' ')} exited with code ${code}`));
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async function readScan(root) {
|
|
61
|
+
const scanPath = resolve(root, '.servicemap/internal-servicemap.json');
|
|
62
|
+
return JSON.parse(await readFile(scanPath, 'utf8'));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async function main() {
|
|
66
|
+
const options = parseArgs();
|
|
67
|
+
if (options.help) {
|
|
68
|
+
help();
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (!['auto', 'page', 'desktop'].includes(options.mode)) {
|
|
73
|
+
throw new Error(`Unknown mode "${options.mode}". Use auto, page, or desktop.`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
await run(process.execPath, [scanScript, '--root', options.root]);
|
|
77
|
+
const scan = await readScan(options.root);
|
|
78
|
+
const selectedMode = options.mode === 'auto'
|
|
79
|
+
? scan.project?.framework === 'static' ? 'desktop' : 'page'
|
|
80
|
+
: options.mode;
|
|
81
|
+
|
|
82
|
+
console.log(`Servicemap detected ${scan.summary?.serviceCount ?? 0} services.`);
|
|
83
|
+
console.log(`Framework: ${scan.project?.framework ?? 'unknown'}`);
|
|
84
|
+
console.log(`Mode: ${selectedMode}`);
|
|
85
|
+
|
|
86
|
+
if (options.dryRun) return;
|
|
87
|
+
|
|
88
|
+
if (selectedMode === 'desktop') {
|
|
89
|
+
await run(process.execPath, [desktopScript, '--root', options.root]);
|
|
90
|
+
} else {
|
|
91
|
+
await run(process.execPath, [pageScript, '--root', options.root]);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
main().catch((error) => {
|
|
96
|
+
console.error(error.message);
|
|
97
|
+
process.exit(1);
|
|
98
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "servicemap",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Generate an internal service map page or desktop app for a software project.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"servicemap": "bin/servicemap.mjs"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin",
|
|
11
|
+
"servicemap",
|
|
12
|
+
"README.md"
|
|
13
|
+
],
|
|
14
|
+
"scripts": {
|
|
15
|
+
"test": "node bin/servicemap.mjs --root demo-project --dry-run && node bin/servicemap.mjs --root no-website-demo --dry-run",
|
|
16
|
+
"validate:skill": "python3 /Users/dougie/.codex/skills/.system/skill-creator/scripts/quick_validate.py servicemap"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"ai-skill",
|
|
20
|
+
"service-map",
|
|
21
|
+
"servicemap",
|
|
22
|
+
"developer-tools",
|
|
23
|
+
"internal-tools"
|
|
24
|
+
],
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "git+https://github.com/douglasbrown11/servicemap.git"
|
|
29
|
+
},
|
|
30
|
+
"bugs": {
|
|
31
|
+
"url": "https://github.com/douglasbrown11/servicemap/issues"
|
|
32
|
+
},
|
|
33
|
+
"homepage": "https://github.com/douglasbrown11/servicemap#readme"
|
|
34
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: servicemap
|
|
3
|
+
description: Create an /internalservicemap page or desktop app for a software project by scanning its codebase for external services, resolving logos, and attaching the map to the existing website when one is present.
|
|
4
|
+
metadata:
|
|
5
|
+
short-description: Generate an internal servicemap page
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Servicemap
|
|
9
|
+
|
|
10
|
+
Use this skill when a user invokes `servicemap` or asks to create an internal servicemap for a software project.
|
|
11
|
+
The outcome is a working `/internalservicemap` page attached to the existing website when possible.
|
|
12
|
+
If no website can be found, create a desktop app fallback at `servicemap-desktop`.
|
|
13
|
+
|
|
14
|
+
## Workflow
|
|
15
|
+
|
|
16
|
+
1. Inspect the project layout and current web framework.
|
|
17
|
+
2. Run `scripts/scan-project.mjs --root <project-root>` to create `.servicemap/internal-servicemap.json`.
|
|
18
|
+
3. Review the scan output for obvious false positives or missing high-confidence services.
|
|
19
|
+
4. If the scan detects a web framework or routeable website, run `scripts/generate-page.mjs --root <project-root>` to create the framework-specific `/internalservicemap` route.
|
|
20
|
+
5. If the scan reports `framework: static` or no website route can be safely attached, run `scripts/generate-desktop-app.mjs --root <project-root>` to create `servicemap-desktop`.
|
|
21
|
+
6. Adapt the generated surface to the project's existing design system only when the route is clear and the edits are low-risk.
|
|
22
|
+
7. Run the project's relevant build, lint, and focused tests.
|
|
23
|
+
8. Report the page or desktop app path, service count, validation run, and any services marked low or medium confidence.
|
|
24
|
+
|
|
25
|
+
## Safety Rules
|
|
26
|
+
|
|
27
|
+
Read environment variable names only.
|
|
28
|
+
Never copy, expose, summarize, or commit secret values.
|
|
29
|
+
The scan output may include env var names such as `STRIPE_SECRET_KEY`, but not their values.
|
|
30
|
+
|
|
31
|
+
Do not add authentication, deployment, analytics, or external writes unless the user explicitly asks.
|
|
32
|
+
If the repository already has route protection conventions for internal pages, follow them.
|
|
33
|
+
If no website route can be safely attached, create the desktop app fallback instead of forcing website files into an unrelated project.
|
|
34
|
+
|
|
35
|
+
## Supporting References
|
|
36
|
+
|
|
37
|
+
- For detection rules and evidence confidence, read [references/service-detection-rules.md](references/service-detection-rules.md).
|
|
38
|
+
- For route placement by framework, read [references/framework-routing.md](references/framework-routing.md).
|
|
39
|
+
- For page quality expectations, read [references/page-design.md](references/page-design.md).
|
|
40
|
+
- For desktop fallback behavior, read [references/desktop-fallback.md](references/desktop-fallback.md).
|