servicemap 0.1.43 → 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 CHANGED
@@ -93,12 +93,12 @@ Use `--no-deploy` to skip the prompt.
93
93
 
94
94
  ## Contents
95
95
 
96
- - `servicemap/`: installable skill folder
96
+ - `SKILL.md`: installable Servicemap skill entrypoint
97
97
  - `bin/servicemap.mjs`: npm CLI entrypoint
98
- - `servicemap/scripts/scan-project.mjs`: scans a project for service evidence
99
- - `servicemap/scripts/generate-page.mjs`: creates website routes
100
- - `servicemap/scripts/generate-desktop-app.mjs`: creates the desktop fallback
101
- - `servicemap/assets/service-logo-database.json`: 1,000 service logo records
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 servicemap
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
 
@@ -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 scanScript = resolve(packageRoot, 'servicemap/scripts/scan-project.mjs');
15
- const pageScript = resolve(packageRoot, 'servicemap/scripts/generate-page.mjs');
16
- const desktopScript = resolve(packageRoot, 'servicemap/scripts/generate-desktop-app.mjs');
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 resolve(sourceRoot, 'servicemap');
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 resolve(sourceRoot, 'servicemap');
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 = resolve(packageRoot, 'servicemap');
700
+ let source = resolveSkillSource(skillRoot);
691
701
  const method = options.installMethod ?? 'symlink';
692
702
 
693
- if (!existsSync(source)) {
694
- throw new Error(`Bundled skill folder not found: ${source}`);
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.43",
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
- "servicemap",
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 servicemap"
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