servicemap 0.1.44 → 0.1.45
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 +6 -6
- package/{servicemap/SKILL.md → SKILL.md} +4 -0
- package/bin/servicemap.mjs +19 -9
- package/package.json +7 -3
- package/references/website-access-options.md +47 -0
- /package/{servicemap/agents → agents}/openai.yaml +0 -0
- /package/{servicemap/assets → assets}/service-logo-database.json +0 -0
- /package/{servicemap/references → references}/desktop-fallback.md +0 -0
- /package/{servicemap/references → references}/framework-routing.md +0 -0
- /package/{servicemap/references → references}/page-design.md +0 -0
- /package/{servicemap/references → references}/service-detection-rules.md +0 -0
- /package/{servicemap/scripts → scripts}/generate-desktop-app.mjs +0 -0
- /package/{servicemap/scripts → scripts}/generate-page.mjs +0 -0
- /package/{servicemap/scripts → scripts}/scan-project.mjs +0 -0
package/README.md
CHANGED
|
@@ -93,12 +93,12 @@ Use `--no-deploy` to skip the prompt.
|
|
|
93
93
|
|
|
94
94
|
## Contents
|
|
95
95
|
|
|
96
|
-
- `
|
|
96
|
+
- `SKILL.md`: installable Servicemap skill entrypoint
|
|
97
97
|
- `bin/servicemap.mjs`: npm CLI entrypoint
|
|
98
|
-
- `
|
|
99
|
-
- `
|
|
100
|
-
- `
|
|
101
|
-
- `
|
|
98
|
+
- `scripts/scan-project.mjs`: scans a project for service evidence
|
|
99
|
+
- `scripts/generate-page.mjs`: creates website routes
|
|
100
|
+
- `scripts/generate-desktop-app.mjs`: creates the desktop fallback
|
|
101
|
+
- `assets/service-logo-database.json`: 1,000 service logo records
|
|
102
102
|
|
|
103
103
|
## Validation
|
|
104
104
|
|
|
@@ -109,5 +109,5 @@ node bin/servicemap.mjs --dry-run
|
|
|
109
109
|
node bin/servicemap.mjs install-skill --agent all --dry-run
|
|
110
110
|
node bin/servicemap.mjs install-skill --targets universal,claude,grok --dry-run
|
|
111
111
|
node bin/servicemap.mjs skills install --agent claude --dry-run
|
|
112
|
-
python3 /Users/dougie/.codex/skills/.system/skill-creator/scripts/quick_validate.py
|
|
112
|
+
python3 /Users/dougie/.codex/skills/.system/skill-creator/scripts/quick_validate.py .
|
|
113
113
|
```
|
|
@@ -34,6 +34,10 @@ If no website can be found, create a desktop app fallback at `servicemap-desktop
|
|
|
34
34
|
Do not deploy unless the user explicitly says yes.
|
|
35
35
|
If they approve, use the project's existing deployment path, preferring `npm run deploy` when present, then provider-specific project configuration such as Vercel or Netlify.
|
|
36
36
|
11. Report the page or desktop app path, service count, validation run, any services marked low or medium confidence, whether requested email access was enforced, and whether deployment was skipped or completed.
|
|
37
|
+
12. If a desktop app was created and the chat client supports Codex inline follow-ups, end the final response with this button, replacing `<absolute-desktop-app-path>` with the generated app's actual absolute path:
|
|
38
|
+
`- :codex-followup[Launch Service Map]{prompt="Open a terminal in <absolute-desktop-app-path>, run npm run tauri dev, keep the process running, and tell me when the desktop app opens."}`
|
|
39
|
+
The button sends a follow-up request to Codex; do not claim that it executes the command directly.
|
|
40
|
+
If inline follow-ups are unavailable, report the absolute app path and the equivalent `npm run tauri dev` command instead.
|
|
37
41
|
|
|
38
42
|
## Safety Rules
|
|
39
43
|
|
package/bin/servicemap.mjs
CHANGED
|
@@ -11,12 +11,22 @@ import { fileURLToPath } from 'node:url';
|
|
|
11
11
|
const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
12
12
|
const repositoryUrl = 'https://github.com/douglasbrown11/servicemap.git';
|
|
13
13
|
const stableSourceRoot = () => resolve(homedir(), '.servicemap/source');
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const
|
|
14
|
+
const skillRoot = packageRoot;
|
|
15
|
+
const scanScript = resolve(skillRoot, 'scripts/scan-project.mjs');
|
|
16
|
+
const pageScript = resolve(skillRoot, 'scripts/generate-page.mjs');
|
|
17
|
+
const desktopScript = resolve(skillRoot, 'scripts/generate-desktop-app.mjs');
|
|
17
18
|
|
|
18
19
|
const universalRoot = () => resolve(homedir(), '.agents/skills');
|
|
19
20
|
|
|
21
|
+
function resolveSkillSource(root) {
|
|
22
|
+
if (existsSync(resolve(root, 'SKILL.md'))) return root;
|
|
23
|
+
|
|
24
|
+
const legacyNestedSource = resolve(root, 'servicemap');
|
|
25
|
+
if (existsSync(resolve(legacyNestedSource, 'SKILL.md'))) return legacyNestedSource;
|
|
26
|
+
|
|
27
|
+
return root;
|
|
28
|
+
}
|
|
29
|
+
|
|
20
30
|
const universalAgents = [
|
|
21
31
|
'Amp',
|
|
22
32
|
'Antigravity',
|
|
@@ -633,7 +643,7 @@ async function prepareStableSource(options) {
|
|
|
633
643
|
const sourceRoot = stableSourceRoot();
|
|
634
644
|
if (options.dryRun) {
|
|
635
645
|
timelineStep(`Would prepare stable source at ${sourceRoot}`);
|
|
636
|
-
return
|
|
646
|
+
return resolveSkillSource(sourceRoot);
|
|
637
647
|
}
|
|
638
648
|
|
|
639
649
|
timelineStep(`Source: ${repositoryUrl}`);
|
|
@@ -657,7 +667,7 @@ async function prepareStableSource(options) {
|
|
|
657
667
|
timelineStep('Repository unavailable; copied packaged source');
|
|
658
668
|
}
|
|
659
669
|
|
|
660
|
-
return
|
|
670
|
+
return resolveSkillSource(sourceRoot);
|
|
661
671
|
}
|
|
662
672
|
|
|
663
673
|
async function updateStableSource(options) {
|
|
@@ -687,11 +697,11 @@ async function installIntoRoot(root, source, method, options) {
|
|
|
687
697
|
}
|
|
688
698
|
|
|
689
699
|
async function installSkill(options) {
|
|
690
|
-
let source =
|
|
700
|
+
let source = resolveSkillSource(skillRoot);
|
|
691
701
|
const method = options.installMethod ?? 'symlink';
|
|
692
702
|
|
|
693
|
-
if (!existsSync(source)) {
|
|
694
|
-
throw new Error(`Bundled skill
|
|
703
|
+
if (!existsSync(resolve(source, 'SKILL.md'))) {
|
|
704
|
+
throw new Error(`Bundled skill source not found: ${source}`);
|
|
695
705
|
}
|
|
696
706
|
|
|
697
707
|
if (!['copy', 'symlink'].includes(method)) {
|
|
@@ -700,7 +710,7 @@ async function installSkill(options) {
|
|
|
700
710
|
|
|
701
711
|
if (method === 'symlink') {
|
|
702
712
|
source = await prepareStableSource(options);
|
|
703
|
-
if (!existsSync(source) && !options.dryRun) {
|
|
713
|
+
if (!existsSync(resolve(source, 'SKILL.md')) && !options.dryRun) {
|
|
704
714
|
throw new Error(`Stable skill source not found: ${source}`);
|
|
705
715
|
}
|
|
706
716
|
}
|
package/package.json
CHANGED
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "servicemap",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.45",
|
|
4
4
|
"description": "Generate an internal service map page or desktop app for a software project.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"servicemap": "bin/servicemap.mjs"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
|
+
"agents",
|
|
11
|
+
"assets",
|
|
10
12
|
"bin",
|
|
11
|
-
"
|
|
13
|
+
"references",
|
|
14
|
+
"scripts",
|
|
15
|
+
"SKILL.md",
|
|
12
16
|
"README.md"
|
|
13
17
|
],
|
|
14
18
|
"scripts": {
|
|
15
19
|
"test": "node bin/servicemap.mjs generate --root demo-project --allow-emails founder@example.com,ops@example.com --dry-run && node bin/servicemap.mjs --root no-website-demo --dry-run && node bin/servicemap.mjs --dry-run && HOME=\"$(mktemp -d)\" node bin/servicemap.mjs && node bin/servicemap.mjs install-skill --agent all --dry-run && node bin/servicemap.mjs install-skill --targets universal,claude,grok --dry-run && node bin/servicemap.mjs install-skill --targets codex,chatgpt,gpt-6-astra --dry-run && node bin/servicemap.mjs skills install --agent claude --dry-run",
|
|
16
|
-
"validate:skill": "python3 /Users/dougie/.codex/skills/.system/skill-creator/scripts/quick_validate.py
|
|
20
|
+
"validate:skill": "python3 /Users/dougie/.codex/skills/.system/skill-creator/scripts/quick_validate.py ."
|
|
17
21
|
},
|
|
18
22
|
"keywords": [
|
|
19
23
|
"ai-skill",
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Website access options for Servicemap
|
|
2
|
+
|
|
3
|
+
These are proposed ways to deliver a service map to a product's website. They are not all implemented today.
|
|
4
|
+
|
|
5
|
+
Scan the product's source repositories independently of the destination. Each destination adapter should consume the same service graph.
|
|
6
|
+
|
|
7
|
+
## 1. Website in the same repository
|
|
8
|
+
|
|
9
|
+
Find the website application or folder within the product repository. Detect its framework and generate the service map route there.
|
|
10
|
+
|
|
11
|
+
## 2. Separate local website repository
|
|
12
|
+
|
|
13
|
+
Use a user-supplied local path, or locate a related checkout in the workspace. Scan the product repository and generate the page in the website checkout.
|
|
14
|
+
|
|
15
|
+
## 3. Website repository on GitHub or another Git host
|
|
16
|
+
|
|
17
|
+
Use an authorized Git connection and an explicit repository URL, or resolve a related repository from available evidence. Clone or open the website repository, generate the page, validate it, and propose the change through a pull request or the user's requested workflow.
|
|
18
|
+
|
|
19
|
+
## 4. Hosting provider connection
|
|
20
|
+
|
|
21
|
+
Use a provider connection, such as Vercel or Netlify, to identify the hosting project associated with the supplied website domain. Where available, inspect the linked source repository and use it as the page destination. A hosting connection does not necessarily provide access to modify that repository.
|
|
22
|
+
|
|
23
|
+
## 5. Website builder or CMS
|
|
24
|
+
|
|
25
|
+
Use the website builder's or CMS's authorized API or plugin to add a page, custom code, or an embedded map, where supported. Adapt the output to the platform's capabilities rather than assuming it accepts a framework route.
|
|
26
|
+
|
|
27
|
+
## 6. Independently hosted service map
|
|
28
|
+
|
|
29
|
+
If the main website cannot accept a page, offer a separately hosted map that can be linked from or embedded in the website. Confirm this destination with the user before choosing it as a fallback.
|
|
30
|
+
|
|
31
|
+
## Shared resolution behavior
|
|
32
|
+
|
|
33
|
+
- Prefer explicit local paths and repository identifiers over inferred matches.
|
|
34
|
+
- Treat a website URL as a discovery clue, not as write access.
|
|
35
|
+
- Use domain references and hosting configuration to find candidate destinations; ask the user to choose when the evidence is ambiguous.
|
|
36
|
+
- Save the confirmed source-to-destination mapping for subsequent runs from either repository.
|
|
37
|
+
- Validate the generated page using the destination project's build and routing conventions.
|
|
38
|
+
- Follow existing access protection for internal pages and the user's deployment instructions.
|
|
39
|
+
- If destination access is missing, preserve the scan results and explain what access is needed. Do not silently substitute a desktop app for a requested website page.
|
|
40
|
+
|
|
41
|
+
## Lunifer example
|
|
42
|
+
|
|
43
|
+
Source: `douglasbrown11/Lunifer`, the product's Xcode app repository.
|
|
44
|
+
|
|
45
|
+
Website destination: `douglasbrown11/luniferWebsite`, the separate Next.js website repository.
|
|
46
|
+
|
|
47
|
+
Scan the product repository, then use its service graph to generate `/internalservicemap` in the website repository. The website's own dependencies must not replace the product's service inventory.
|
|
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
|