@x12i/connectix-docs 0.1.0 → 0.1.2

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.
Files changed (67) hide show
  1. package/dist/generated/bundle.d.ts.map +1 -1
  2. package/dist/generated/bundle.js +50 -8
  3. package/dist/generated/bundle.js.map +1 -1
  4. package/dist/web/INDEX.md +38 -0
  5. package/dist/web/SEARCH.json +157 -0
  6. package/dist/web/agent/INDEX.md +38 -0
  7. package/dist/web/agent/SEARCH.json +157 -0
  8. package/dist/web/agent/agent-manifest.json +120 -0
  9. package/dist/web/agent/indexes/books.json +17 -0
  10. package/dist/web/agent/indexes/books.md +4 -0
  11. package/dist/web/agent/indexes/concepts.json +4 -0
  12. package/dist/web/agent/indexes/concepts.md +3 -0
  13. package/dist/web/agent/indexes/diagrams.json +4 -0
  14. package/dist/web/agent/indexes/diagrams.md +3 -0
  15. package/dist/web/agent/indexes/guides.json +4 -0
  16. package/dist/web/agent/indexes/guides.md +3 -0
  17. package/dist/web/agent/indexes/scenarios.json +4 -0
  18. package/dist/web/agent/indexes/scenarios.md +3 -0
  19. package/dist/web/agent/indexes/tutorials.json +4 -0
  20. package/dist/web/agent/indexes/tutorials.md +3 -0
  21. package/dist/web/agent/indexes/use-cases.json +29 -0
  22. package/dist/web/agent/indexes/use-cases.md +6 -0
  23. package/dist/web/agent/use-cases/call-connect-tools.md +78 -0
  24. package/dist/web/agent/use-cases/catalog-extension-overview.md +42 -0
  25. package/dist/web/agent/use-cases/orient-connectix.md +95 -0
  26. package/dist/web/agent/use-cases/run-package-simulator.md +48 -0
  27. package/dist/web/agent-manifest.json +20 -2
  28. package/dist/web/agents.html +38 -0
  29. package/dist/web/app.js +449 -0
  30. package/dist/web/assets/extras.css +302 -0
  31. package/dist/web/assets/site.css +21 -0
  32. package/dist/web/books/00-orient-connectix.html +35 -2
  33. package/dist/web/books/01-tools-and-simulator.html +35 -2
  34. package/dist/web/catalog.html +38 -0
  35. package/dist/web/concepts.html +65 -0
  36. package/dist/web/diagrams.html +65 -0
  37. package/dist/web/docs.html +38 -0
  38. package/dist/web/explore.html +76 -0
  39. package/dist/web/getting-started.html +38 -0
  40. package/dist/web/guides.html +65 -0
  41. package/dist/web/index.html +39 -1
  42. package/dist/web/indexes/books.json +17 -0
  43. package/dist/web/indexes/books.md +4 -0
  44. package/dist/web/indexes/concepts.json +4 -0
  45. package/dist/web/indexes/concepts.md +3 -0
  46. package/dist/web/indexes/diagrams.json +4 -0
  47. package/dist/web/indexes/diagrams.md +3 -0
  48. package/dist/web/indexes/guides.json +4 -0
  49. package/dist/web/indexes/guides.md +3 -0
  50. package/dist/web/indexes/scenarios.json +4 -0
  51. package/dist/web/indexes/scenarios.md +3 -0
  52. package/dist/web/indexes/tutorials.json +4 -0
  53. package/dist/web/indexes/tutorials.md +3 -0
  54. package/dist/web/indexes/use-cases.json +29 -0
  55. package/dist/web/indexes/use-cases.md +6 -0
  56. package/dist/web/knowledge.json +15 -0
  57. package/dist/web/read.html +161 -74
  58. package/dist/web/scenarios.html +65 -0
  59. package/dist/web/search.html +71 -0
  60. package/dist/web/site.json +1 -1
  61. package/dist/web/use-cases/call-connect-tools.md +78 -0
  62. package/dist/web/use-cases/catalog-extension-overview.md +42 -0
  63. package/dist/web/use-cases/orient-connectix.md +95 -0
  64. package/dist/web/use-cases/run-package-simulator.md +48 -0
  65. package/dist/web/use-cases.html +38 -0
  66. package/dist/web/use-cases.json +28 -4
  67. package/package.json +7 -7
@@ -8,39 +8,138 @@
8
8
  <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500;600&display=swap" rel="stylesheet">
9
9
  <link rel="stylesheet" href="/assets/site.css">
10
10
  <link rel="stylesheet" href="/assets/extras.css">
11
+ <link rel="stylesheet" href="/assets/book.css">
11
12
  <style>
12
- body{ height: 100vh; overflow: hidden; display:flex; flex-direction:column; }
13
- main{ display:flex; flex-direction:column; flex:1; min-height:0; }
13
+ .reader-page { display: flex; flex-direction: column; min-height: 100vh; }
14
+ .reader-layout { display: grid; grid-template-columns: minmax(220px, 280px) minmax(0, 1fr); gap: 0; flex: 1; }
15
+ @media (max-width: 860px) {
16
+ .reader-layout { grid-template-columns: 1fr; }
17
+ .reader-sidebar { position: fixed; inset: 0 auto 0 0; width: min(86vw, 320px); z-index: 40; transform: translateX(-105%); transition: transform .2s ease; background: var(--surface, #fff); box-shadow: 0 0 0 1px rgba(0,0,0,.08); }
18
+ .reader-sidebar.open { transform: translateX(0); }
19
+ }
20
+ .reader-article { max-width: 46rem; margin: 0 auto; padding: 1.25rem 1.5rem 3rem; }
21
+ .reader-article :target { scroll-margin-top: 5rem; }
22
+ .skip-link { position: absolute; left: -999px; top: 0; background: #000; color: #fff; padding: .5rem 1rem; z-index: 100; }
23
+ .skip-link:focus { left: .5rem; top: .5rem; }
24
+ .reader-context { font-size: .9rem; color: var(--muted, #555); margin: 0 0 1rem; }
25
+ .reader-nav-chapters { list-style: none; padding: 0; margin: 0; }
26
+ .reader-nav-chapters a { display: flex; gap: .5rem; padding: .35rem .25rem; text-decoration: none; color: inherit; border-radius: 4px; }
27
+ .reader-nav-chapters a:hover, .reader-nav-chapters a[aria-current="true"] { background: rgba(15,98,254,.08); }
28
+ .reader-nav-chapters .num { font-variant-numeric: tabular-nums; opacity: .55; min-width: 1.6rem; }
29
+ .prev-next { display: flex; justify-content: space-between; gap: 1rem; margin-top: 2.5rem; padding-top: 1rem; border-top: 1px solid rgba(0,0,0,.1); }
14
30
  </style>
15
31
  </head>
16
- <body>
32
+ <body class="reader-page">
33
+ <a class="skip-link" href="#main-content">Skip to content</a>
17
34
  <div id="topbar-slot"></div>
18
- <button class="sidebar-toggle" id="toggle">Chapters</button>
19
- <main>
20
- <div class="reader-shell" style="flex:1;min-height:0;">
21
- <aside class="reader-sidebar" id="sidebar"></aside>
22
- <div class="reader-main">
23
- <div class="reader-topline" id="topline"></div>
24
- <div class="reader-frame-wrap">
25
- <iframe id="frame" title="Book content"></iframe>
26
- </div>
27
- </div>
28
- </div>
29
- </main>
35
+ <button type="button" class="sidebar-toggle" id="toggle" aria-controls="sidebar" aria-expanded="false">Chapters</button>
36
+ <div class="reader-layout">
37
+ <aside class="reader-sidebar" id="sidebar" aria-label="Chapter navigation"></aside>
38
+ <main id="main-content">
39
+ <div class="reader-topline" id="topline"></div>
40
+ <article class="reader-article" id="article" tabindex="-1">
41
+ <p>Loading…</p>
42
+ </article>
43
+ <nav class="prev-next reader-article" id="prevnext" aria-label="Adjacent chapters"></nav>
44
+ </main>
45
+ </div>
30
46
  <script src="/app.js"></script>
31
47
  <script>
32
48
  const bookId = qs("book");
33
49
  const role = qs("role") || "developers";
34
- const hashChapter = location.hash.replace(/^#/, "");
50
+ let chapters = [];
35
51
 
36
52
  document.getElementById("toggle").onclick = () => {
37
- document.getElementById("sidebar").classList.toggle("open");
53
+ const side = document.getElementById("sidebar");
54
+ const open = side.classList.toggle("open");
55
+ document.getElementById("toggle").setAttribute("aria-expanded", String(open));
38
56
  };
39
57
 
40
- Promise.all([loadCatalog(), loadSite(), loadJson("/agent-manifest.json")]).then(([catalog, site, manifest]) => {
58
+ function slugify(s) {
59
+ return String(s).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
60
+ }
61
+
62
+ function markdownLite(md) {
63
+ // Minimal, safe-ish rendering for chapter bodies already authored as docs Markdown.
64
+ let html = escapeHtml(md);
65
+ html = html.replace(/^### (.+)$/gm, "<h3>$1</h3>");
66
+ html = html.replace(/^## (.+)$/gm, "<h2 id=\"$1\">$1</h2>");
67
+ html = html.replace(/^# (.+)$/gm, "<h1>$1</h1>");
68
+ html = html.replace(/```([\s\S]*?)```/g, (m, code) => "<pre><code>" + code.trim() + "</code></pre>");
69
+ html = html.replace(/`([^`]+)`/g, "<code>$1</code>");
70
+ html = html.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>");
71
+ html = html.replace(/^\- (.+)$/gm, "<li>$1</li>");
72
+ html = html.replace(/(<li>.*<\/li>\n?)+/g, (m) => "<ul>" + m + "</ul>");
73
+ html = html.replace(/^(?!<[hul]|<pre|<li)(.+)$/gm, (line) => {
74
+ if (!line.trim()) return "";
75
+ if (line.startsWith("<")) return line;
76
+ return "<p>" + line + "</p>";
77
+ });
78
+ // Fix h2 ids to slug form
79
+ html = html.replace(/<h2 id="([^"]+)">/g, (_, t) => '<h2 id="' + slugify(t) + '">');
80
+ return html;
81
+ }
82
+
83
+ function setActive(slug) {
84
+ document.querySelectorAll(".reader-nav-chapters a").forEach((a) => {
85
+ a.setAttribute("aria-current", a.getAttribute("data-slug") === slug ? "true" : "false");
86
+ });
87
+ }
88
+
89
+ function showChapter(slug) {
90
+ const idx = chapters.findIndex((c) => c.slug === slug);
91
+ const ch = chapters[idx] || chapters[0];
92
+ if (!ch) return;
93
+ const article = document.getElementById("article");
94
+ article.innerHTML =
95
+ '<p class="reader-context">Audience: <strong>' + escapeHtml(role) +
96
+ "</strong> · Chapter " + (idx + 1) + " of " + chapters.length + "</p>" +
97
+ "<h1>" + escapeHtml(ch.title) + "</h1>" +
98
+ markdownLite(ch.body || "");
99
+ history.replaceState(null, "", "#" + ch.slug);
100
+ setActive(ch.slug);
101
+ const prev = chapters[idx - 1];
102
+ const next = chapters[idx + 1];
103
+ document.getElementById("prevnext").innerHTML =
104
+ (prev
105
+ ? '<a href="#' + prev.slug + '" data-nav-slug="' + prev.slug + '">← ' + escapeHtml(prev.title) + "</a>"
106
+ : "<span></span>") +
107
+ (next
108
+ ? '<a href="#' + next.slug + '" data-nav-slug="' + next.slug + '">' + escapeHtml(next.title) + " →</a>"
109
+ : "<span></span>");
110
+ document.querySelectorAll("[data-nav-slug]").forEach((a) => {
111
+ a.addEventListener("click", (e) => {
112
+ e.preventDefault();
113
+ showChapter(a.getAttribute("data-nav-slug"));
114
+ article.focus();
115
+ });
116
+ });
117
+ const el = document.getElementById(ch.slug);
118
+ if (el) el.scrollIntoView({ block: "start" });
119
+ else window.scrollTo(0, 0);
120
+ }
121
+
122
+ function splitChapters(md) {
123
+ const lines = md.replace(/\r\n/g, "\n").split("\n");
124
+ const out = [];
125
+ let current = null;
126
+ for (const line of lines) {
127
+ const m = /^##\s+(.+?)\s*$/.exec(line);
128
+ if (m) {
129
+ if (current) out.push(current);
130
+ current = { title: m[1], slug: slugify(m[1]), body: "" };
131
+ continue;
132
+ }
133
+ if (current) current.body += line + "\n";
134
+ }
135
+ if (current) out.push(current);
136
+ return out;
137
+ }
138
+
139
+ Promise.all([loadCatalog(), loadSite(), loadJson("/agent-manifest.json")]).then(async ([catalog, site, manifest]) => {
41
140
  const book = catalog.books.find((b) => b.id === bookId);
42
141
  if (!book) {
43
- document.getElementById("sidebar").innerHTML = `<div class="side-block"><p>Book not found.</p></div>`;
142
+ document.getElementById("article").innerHTML = "<p>Book not found.</p>";
44
143
  return;
45
144
  }
46
145
  if (site.accent) document.body.style.setProperty("--accent", site.accent);
@@ -50,71 +149,59 @@
50
149
  bindNavToggle();
51
150
 
52
151
  const mBook = manifest.books.find((b) => b.id === bookId);
53
- const md = mBook?.md?.[role];
152
+ const mdPath = mBook?.md?.[role];
54
153
  const pdf = mBook?.pdf?.[role];
55
154
  const chPath = mBook?.chapters?.[role];
56
155
 
57
156
  document.getElementById("topline").innerHTML = `
58
- <a href="/books/${encodeURIComponent(bookId)}">Book</a> /
59
- <a href="/catalog?role=${encodeURIComponent(role)}">Catalog</a> /
60
- <strong>${escapeHtml(book.title)}</strong>
61
- <span>(${escapeHtml(role)})</span>
62
- <span class="dl-row" style="margin-left:auto">
63
- ${md ? `<a class="btn btn-secondary btn-sm" href="${downloadHref(md)}" download>Download MD</a>` : ""}
64
- ${pdf ? `<a class="btn btn-secondary btn-sm" href="${downloadHref(pdf)}" download>Download PDF</a>` : ""}
65
- </span>
66
- `;
67
-
68
- const frame = document.getElementById("frame");
69
- frame.src = `/books/${encodeURIComponent(bookId)}/${encodeURIComponent(role)}.html`;
70
-
71
- function buildNav(chapters) {
72
- const items = chapters.map((c, i) => `
73
- <li><a href="#${escapeHtml(c.slug)}" data-slug="${escapeHtml(c.slug)}">
74
- <span class="num">${String(i + 1).padStart(2, "0")}</span>${escapeHtml(c.title)}
75
- </a></li>`).join("");
76
- document.getElementById("sidebar").innerHTML = `
77
- <div class="side-block">
78
- <div class="side-title">${escapeHtml(book.title)}</div>
79
- <div class="side-sub">${escapeHtml(book.kicker)}</div>
80
- ${md ? `<a class="export-btn" href="${downloadHref(md)}" download>Download MD</a>` : ""}
81
- ${pdf ? `<a class="export-btn" style="background:var(--ink);margin-top:8px" href="${downloadHref(pdf)}" download>Download PDF</a>` : ""}
82
- </div>
83
- <ul class="chapter-nav">${items}</ul>`;
157
+ <nav class="reader-topline" aria-label="Breadcrumb" style="display:flex;flex-wrap:wrap;gap:.5rem;align-items:center;padding:.75rem 1rem;border-bottom:1px solid rgba(0,0,0,.08)">
158
+ <a href="/books/${encodeURIComponent(bookId)}">Book</a> /
159
+ <a href="/catalog?role=${encodeURIComponent(role)}">Catalog</a> /
160
+ <strong>${escapeHtml(book.title)}</strong>
161
+ <span>(${escapeHtml(role)})</span>
162
+ <span class="dl-row" style="margin-left:auto;display:flex;gap:.5rem">
163
+ ${mdPath ? `<a class="btn btn-secondary btn-sm" href="${downloadHref(mdPath)}" download>Download MD</a>` : ""}
164
+ ${pdf ? `<a class="btn btn-secondary btn-sm" href="${downloadHref(pdf)}" download>Download PDF</a>` : ""}
165
+ </span>
166
+ </nav>`;
84
167
 
85
- document.querySelectorAll(".chapter-nav a").forEach((a) => {
86
- a.addEventListener("click", (e) => {
87
- e.preventDefault();
88
- const slug = a.getAttribute("data-slug");
89
- location.hash = slug;
90
- scrollToChapter(slug);
91
- document.querySelectorAll(".chapter-nav a").forEach((x) => x.classList.remove("active"));
92
- a.classList.add("active");
93
- });
94
- });
95
- }
96
-
97
- function scrollToChapter(slug) {
168
+ const md = mdPath ? await fetch(downloadHref(mdPath)).then((r) => r.text()) : "";
169
+ chapters = splitChapters(md);
170
+ if (chPath) {
98
171
  try {
99
- const doc = frame.contentDocument;
100
- const el = doc && doc.getElementById(slug);
101
- if (el) el.scrollIntoView({ behavior: "smooth", block: "start" });
102
- } catch (_) { /* ignore */ }
172
+ const idx = await loadJson("/" + chPath.replace(/^\//, ""));
173
+ if (Array.isArray(idx) && idx.length && chapters.length === 0) {
174
+ chapters = idx.map((c) => ({ ...c, body: "" }));
175
+ }
176
+ } catch (_) {}
103
177
  }
104
178
 
105
- frame.addEventListener("load", () => {
106
- if (hashChapter) scrollToChapter(hashChapter);
179
+ const items = chapters
180
+ .map(
181
+ (c, i) =>
182
+ `<li><a href="#${escapeHtml(c.slug)}" data-slug="${escapeHtml(c.slug)}"><span class="num">${String(i + 1).padStart(2, "0")}</span>${escapeHtml(c.title)}</a></li>`,
183
+ )
184
+ .join("");
185
+ document.getElementById("sidebar").innerHTML = `
186
+ <div class="side-block" style="padding:1rem">
187
+ <div class="side-title">${escapeHtml(book.title)}</div>
188
+ <div class="side-sub">${escapeHtml(book.kicker)}</div>
189
+ <ol class="reader-nav-chapters">${items}</ol>
190
+ </div>`;
191
+ document.querySelectorAll(".reader-nav-chapters a").forEach((a) => {
192
+ a.addEventListener("click", (e) => {
193
+ e.preventDefault();
194
+ showChapter(a.getAttribute("data-slug"));
195
+ document.getElementById("sidebar").classList.remove("open");
196
+ document.getElementById("toggle").setAttribute("aria-expanded", "false");
197
+ });
107
198
  });
108
199
 
109
- if (chPath) {
110
- loadJson("/" + chPath.replace(/^\//, "")).then((chapters) => {
111
- buildNav(chapters);
112
- if (hashChapter) {
113
- const active = document.querySelector(`.chapter-nav a[data-slug="${CSS.escape(hashChapter)}"]`);
114
- if (active) active.classList.add("active");
115
- }
116
- });
117
- }
200
+ const start = location.hash.replace(/^#/, "") || chapters[0]?.slug;
201
+ showChapter(start);
202
+ window.addEventListener("hashchange", () => {
203
+ showChapter(location.hash.replace(/^#/, "") || chapters[0]?.slug);
204
+ });
118
205
  });
119
206
  </script>
120
207
  </body>
@@ -0,0 +1,65 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>Scenarios · Connectix</title>
7
+ <link rel="preconnect" href="https://fonts.googleapis.com">
8
+ <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500;600&display=swap" rel="stylesheet">
9
+ <link rel="stylesheet" href="/assets/site.css">
10
+ <link rel="stylesheet" href="/assets/extras.css">
11
+ <script data-docify-guard="docify:serve-guard">
12
+ (function () {
13
+ if (window.location.protocol !== "file:") return;
14
+ var cmd = "npm run docs";
15
+ var dir = "";
16
+ function render() {
17
+ var host = document.createElement("div");
18
+ host.setAttribute("role", "alert");
19
+ host.setAttribute("style", "position:fixed;inset:0;z-index:2147483647;display:flex;align-items:center;justify-content:center;padding:24px;margin:0;background:#0b0e14;color:#e6e9ef;font:16px/1.55 ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,sans-serif");
20
+ host.innerHTML =
21
+ '<div style="max-width:44rem">' +
22
+ '<p style="margin:0 0 8px;font-size:13px;letter-spacing:.08em;text-transform:uppercase;color:#8b95a7">Docify</p>' +
23
+ '<h1 style="margin:0 0 12px;font-size:28px;line-height:1.2">Serve this site to view it</h1>' +
24
+ '<p style="margin:0 0 16px;color:#b6bfcf">This page was opened from the file system, so its stylesheets and scripts ' +
25
+ 'cannot load and the layout you see is not the real design. Docify sites are served over HTTP.</p>' +
26
+ '<pre style="margin:0 0 16px;padding:14px 16px;border-radius:10px;background:#151a23;border:1px solid #232a36;overflow:auto;font:14px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace;color:#e6e9ef"><code>' +
27
+ (dir ? "cd " + dir + "\n" : "") + cmd + '</code></pre>' +
28
+ '<p style="margin:0;color:#8b95a7;font-size:14px">The command builds the bundle, starts the local server, and opens the correct URL.</p>' +
29
+ "</div>";
30
+ document.documentElement.style.background = "#0b0e14";
31
+ if (document.body) {
32
+ document.body.innerHTML = "";
33
+ document.body.appendChild(host);
34
+ } else {
35
+ document.documentElement.appendChild(host);
36
+ }
37
+ }
38
+ if (document.readyState === "loading") {
39
+ document.addEventListener("DOMContentLoaded", render);
40
+ } else {
41
+ render();
42
+ }
43
+ })();
44
+ </script>
45
+ </head>
46
+ <body>
47
+ <a class="skip-link" href="#main-content">Skip to content</a>
48
+ <header class="site-header">
49
+ <a class="brand" href="/docs">
50
+ <span class="brand-mark" aria-hidden="true"></span>
51
+ <span class="brand-name">connectix</span>
52
+ <span class="brand-badge">docs</span>
53
+ </a>
54
+ <button type="button" class="nav-toggle" aria-label="Menu" data-nav-toggle>Menu</button>
55
+ <nav class="site-nav" data-site-nav>
56
+ <a href="/getting-started">Getting started</a><a href="/use-cases">Use cases</a><a href="/catalog">Catalog</a><a href="/agents">Agents/SDK</a><a href="/search">Search</a><a href="/explore">Explore</a>
57
+ </nav>
58
+ </header>
59
+ <main id="main-content" class="knowledge-page">
60
+ <article class="prose-column"><h1>Scenarios</h1><ul class="knowledge-index"></ul></article>
61
+ </main>
62
+ <script src="/app.js"></script>
63
+ <script>bindNavToggle();</script>
64
+ </body>
65
+ </html>
@@ -0,0 +1,71 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>Search · Connectix</title>
7
+ <link rel="preconnect" href="https://fonts.googleapis.com">
8
+ <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600;700&family=IBM+Plex+Mono:wght@400;500;600&display=swap" rel="stylesheet">
9
+ <link rel="stylesheet" href="/assets/site.css">
10
+ <link rel="stylesheet" href="/assets/extras.css">
11
+ <script data-docify-guard="docify:serve-guard">
12
+ (function () {
13
+ if (window.location.protocol !== "file:") return;
14
+ var cmd = "npm run docs";
15
+ var dir = "";
16
+ function render() {
17
+ var host = document.createElement("div");
18
+ host.setAttribute("role", "alert");
19
+ host.setAttribute("style", "position:fixed;inset:0;z-index:2147483647;display:flex;align-items:center;justify-content:center;padding:24px;margin:0;background:#0b0e14;color:#e6e9ef;font:16px/1.55 ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,sans-serif");
20
+ host.innerHTML =
21
+ '<div style="max-width:44rem">' +
22
+ '<p style="margin:0 0 8px;font-size:13px;letter-spacing:.08em;text-transform:uppercase;color:#8b95a7">Docify</p>' +
23
+ '<h1 style="margin:0 0 12px;font-size:28px;line-height:1.2">Serve this site to view it</h1>' +
24
+ '<p style="margin:0 0 16px;color:#b6bfcf">This page was opened from the file system, so its stylesheets and scripts ' +
25
+ 'cannot load and the layout you see is not the real design. Docify sites are served over HTTP.</p>' +
26
+ '<pre style="margin:0 0 16px;padding:14px 16px;border-radius:10px;background:#151a23;border:1px solid #232a36;overflow:auto;font:14px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace;color:#e6e9ef"><code>' +
27
+ (dir ? "cd " + dir + "\n" : "") + cmd + '</code></pre>' +
28
+ '<p style="margin:0;color:#8b95a7;font-size:14px">The command builds the bundle, starts the local server, and opens the correct URL.</p>' +
29
+ "</div>";
30
+ document.documentElement.style.background = "#0b0e14";
31
+ if (document.body) {
32
+ document.body.innerHTML = "";
33
+ document.body.appendChild(host);
34
+ } else {
35
+ document.documentElement.appendChild(host);
36
+ }
37
+ }
38
+ if (document.readyState === "loading") {
39
+ document.addEventListener("DOMContentLoaded", render);
40
+ } else {
41
+ render();
42
+ }
43
+ })();
44
+ </script>
45
+ </head>
46
+ <body>
47
+ <a class="skip-link" href="#main-content">Skip to content</a>
48
+ <header class="site-header">
49
+ <a class="brand" href="/docs">
50
+ <span class="brand-mark" aria-hidden="true"></span>
51
+ <span class="brand-name">connectix</span>
52
+ <span class="brand-badge">docs</span>
53
+ </a>
54
+ <button type="button" class="nav-toggle" aria-label="Menu" data-nav-toggle>Menu</button>
55
+ <nav class="site-nav" data-site-nav>
56
+ <a href="/getting-started">Getting started</a><a href="/use-cases">Use cases</a><a href="/catalog">Catalog</a><a href="/agents">Agents/SDK</a><a href="/search">Search</a><a href="/explore">Explore</a>
57
+ </nav>
58
+ </header>
59
+ <main id="main-content" class="knowledge-page">
60
+
61
+ <article class="prose-column">
62
+ <h1>Search</h1>
63
+ <p class="lead">Local search over explicitly authored knowledge. No hosted service.</p>
64
+ <div id="search-root"></div>
65
+ <p class="dl-row"><a href="/SEARCH.json">SEARCH.json</a> · <a href="/INDEX.md">INDEX.md</a> · <a href="/agent-manifest.json">agent-manifest.json</a></p>
66
+ </article>
67
+ </main>
68
+ <script src="/app.js"></script>
69
+ <script>bindNavToggle();hydrateSearch(document.getElementById("search-root"));</script>
70
+ </body>
71
+ </html>
@@ -2,7 +2,7 @@
2
2
  "product": "Connectix",
3
3
  "brand": "Connectix",
4
4
  "brandAccent": "#2f6feb",
5
- "siteUrl": "https://docs.x12i.dev/connectix",
5
+ "siteUrl": "https://docs.connectix.x12i.com",
6
6
  "knowledgePackage": "@x12i/connectix-docs",
7
7
  "footer": "Connectix — internal X12I provider connectivity service.",
8
8
  "accent": "#2f6feb",
@@ -0,0 +1,78 @@
1
+ # Expose Connectix as AI tools
2
+
3
+ > **Use case id:** `call-connect-tools`
4
+ > **Goal:** Register the four connect tools from @x12i/connectix-tools in an LLM tool registry and run them against a live service or the simulator.
5
+ > **Audiences:** developers
6
+ > **Tags:** ai-tools, agents
7
+
8
+ ## Reading path
9
+
10
+ 1. **AI Tools and the Package Simulator** (developers) → chapters: `1-the-four-connect-tools`, `3-stub-and-live-execution`
11
+
12
+ ## From: AI Tools and the Package Simulator — 1. The four connect tools
13
+
14
+ `@x12i/connectix-tools` publishes the four curated operations as machine-usable tool
15
+ definitions with JSON Schema inputs and outputs:
16
+
17
+ | Tool name | Operation |
18
+ |-----------|-----------|
19
+ | `connect_list_providers` | `connect.listProviders` |
20
+ | `connect_search_actions` | `connect.searchActions` |
21
+ | `connect_get_action` | `connect.getAction` |
22
+ | `connect_execute_action` | `connect.executeAction` |
23
+
24
+ Register the definitions in your LLM tool registry, then route tool calls through a runner:
25
+
26
+ ```ts
27
+ import { CONNECT_TOOLS, createHttpConnectToolRunner } from "@x12i/connectix-tools";
28
+
29
+ const runner = createHttpConnectToolRunner({
30
+ baseUrl: "http://127.0.0.1:9400",
31
+ callerId: "service:ai-skills",
32
+ callerToken: process.env.CONNECTIX_AI_SKILLS_TOKEN ?? "change-me-caller",
33
+ });
34
+
35
+ const result = await runner.run({
36
+ tool: "connect_execute_action",
37
+ input: {
38
+ actionId: "example.echo",
39
+ bindingRef: "demo-echo",
40
+ input: { message: "hello" },
41
+ stubEnabled: true,
42
+ },
43
+ });
44
+ ```
45
+
46
+ Rules for tool callers:
47
+
48
+ - The recommended flow is discover → describe → execute: search actions, fetch the descriptor,
49
+ read its `inputSchema`, then execute.
50
+ - Pass a `bindingRef`, never a credential. `stubEnabled: true` gives deterministic fixtures.
51
+ - Never add executor-source branches (n8n, Nango, OpenConnector) to caller code. Provenance is
52
+ internal to the service.
53
+
54
+ ## From: AI Tools and the Package Simulator — 3. Stub and live execution
55
+
56
+ Both call styles make execution mode explicit:
57
+
58
+ - Pipeline style: `stub: { enabled: true }` → stub; omitted or `false` → live.
59
+ - Canonical style: `execution: { mode: "stub" | "live" }`.
60
+
61
+ Stub execution validates binding policy exactly like live (unknown binding, provider mismatch,
62
+ and disallowed patterns are still rejected), returns the deterministic fixture published with
63
+ the action, and records `mode=stub` in the Memorix execution record. It never leases a
64
+ credential.
65
+
66
+ Live execution resolves the binding's `credentialRef` through Credorix (or the dev credential
67
+ resolver when Credorix env is unset) and runs the registered executor.
68
+
69
+ Development default: stub everywhere — simulator, CI, and Status UI Try. Live is opt-in per
70
+ request and per binding.
71
+
72
+ ## Also see
73
+
74
+ - **run-package-simulator** (`run-package-simulator`) —
75
+
76
+ ---
77
+
78
+ _Generated use-case pack for agents and humans. See `agent-manifest.json` for discovery._
@@ -0,0 +1,42 @@
1
+ # Understand catalog extension provenance
2
+
3
+ > **Use case id:** `catalog-extension-overview`
4
+ > **Goal:** Know how OpenConnector, n8n-node, and Nango-derived implementations reach the catalog while callers stay source-agnostic.
5
+ > **Audiences:** developers
6
+ > **Tags:** catalog, provenance
7
+
8
+ ## Reading path
9
+
10
+ 1. **AI Tools and the Package Simulator** (developers) → chapters: `4-catalog-extension-overview`
11
+
12
+ ## From: AI Tools and the Package Simulator — 4. Catalog extension overview
13
+
14
+ The catalog grows from three sources, all published behind the same caller contract:
15
+
16
+ | Source kind | What it is |
17
+ |-------------|------------|
18
+ | `openconnector` | Curated actions executed by the pinned `vendor/open-connector` engine |
19
+ | `n8n-node` | Selected n8n node resource/operations from an allowlisted, pinned package set |
20
+ | `nango-derived` | Native Connectix/OpenConnector code adapted from offline Nango knowledge |
21
+ | `connectix-native` | First-party executors (for example `example.echo`) |
22
+
23
+ Non-negotiables:
24
+
25
+ - Nango is **offline catalog intelligence only** — never a runtime dependency.
26
+ - Executor selection happens in the executor registry by descriptor; callers never choose a
27
+ backend.
28
+ - Every published action carries provenance (`sourceId`, `sourceVersion`, `fingerprint`,
29
+ license) which flows into Memorix execution records — but never secrets.
30
+ - Offline tooling: `npm run n8n:catalog`, `npm run nango:catalog`, `npm run catalog:gaps`,
31
+ `npm run catalog:review`, `npm run catalog:publish` (writes the reviewed publish list under
32
+ `generated/catalog-candidates/`).
33
+
34
+ Full design: `docs/Connectix-Catalog-Extension-Specification.md` in the Connectix repository.
35
+
36
+ ## Also see
37
+
38
+ - **orient-connectix** (`orient-connectix`) —
39
+
40
+ ---
41
+
42
+ _Generated use-case pack for agents and humans. See `agent-manifest.json` for discovery._
@@ -0,0 +1,95 @@
1
+ # Orient on Connectix
2
+
3
+ > **Use case id:** `orient-connectix`
4
+ > **Goal:** Understand what Connectix is, the four curated operations, and the caller contract before writing any integration code.
5
+ > **Audiences:** developers
6
+ > **Tags:** orientation, getting-started
7
+
8
+ ## Reading path
9
+
10
+ 1. **Orient on Connectix** (developers) → chapters: `1-what-connectix-is`, `2-call-styles-and-auth`, `3-ownership-boundaries`
11
+
12
+ ## From: Orient on Connectix — 1. What Connectix is
13
+
14
+ Connectix executes **curated provider actions** through one stable contract. Callers never learn
15
+ where an action implementation came from — OpenConnector, an n8n node, Nango-derived native code,
16
+ or Connectix-native code all look identical behind the same envelope.
17
+
18
+ The service exposes exactly four curated operations (never the full upstream provider catalog):
19
+
20
+ | Operation | Purpose |
21
+ |-----------|---------|
22
+ | `connect.listProviders` | List curated providers |
23
+ | `connect.searchActions` | Search curated actions |
24
+ | `connect.getAction` | Fetch one action descriptor |
25
+ | `connect.executeAction` | Run an action (stub or live) |
26
+
27
+ The runtime flow for every execution: validate caller → resolve binding → lease credential →
28
+ run action → observe in Memorix.
29
+
30
+ Key packages:
31
+
32
+ | Package | Role |
33
+ |---------|------|
34
+ | `@x12i/connectix-contracts` | Shared types and envelopes (`ConnectActionRequest`, `PipelineRequest`, error codes) |
35
+ | `@x12i/connectix-client` | Typed HTTP client for the service |
36
+ | `@x12i/connectix-tools` | The four operations as machine-usable LLM tool definitions + runners |
37
+ | `@x12i/connectix-simulator` | Package simulator for local development (no service required) |
38
+ | `@x12i/connectix-docs` | This knowledge package |
39
+
40
+ ## From: Orient on Connectix — 2. Call styles and auth
41
+
42
+ Every non-probe route requires two headers:
43
+
44
+ ```http
45
+ Authorization: Bearer <caller-token>
46
+ x-connectix-caller-id: service:ai-skills
47
+ ```
48
+
49
+ Caller identity always comes from headers. A `callerId` in the request body is overwritten by
50
+ the service. Public routes (no auth): `GET /health`, `GET /ready`, `GET /metadata`.
51
+
52
+ There are two equivalent call styles sharing one runtime:
53
+
54
+ 1. **Canonical execute** — `POST /v1/actions/execute` with a full `ConnectActionRequest`
55
+ (contractVersion `"1"`, explicit `execution.mode` of `stub` or `live`).
56
+ 2. **Pipeline step** — `POST /pipeline` with `serviceId`, `serviceType` (one of the four
57
+ operations), `input`, and optional `stub.enabled`. Preferred for Memorix Pipeline Services,
58
+ the Status UI Try panel, and AI tools.
59
+
60
+ Discovery routes: `GET /v1/providers`, `GET /v1/actions/search?query=`, and
61
+ `GET /v1/actions/:actionId`. Operation metadata (including example envelopes) is served by
62
+ `GET /metadata` — UIs and tools must load catalogs from there, never hardcode them.
63
+
64
+ Failures use stable error codes such as `ACTION_NOT_FOUND`, `ACTION_NOT_ALLOWED`,
65
+ `CONNECTION_BINDING_NOT_FOUND`, `CREDENTIAL_NOT_AVAILABLE`, and
66
+ `ACTION_IMPLEMENTATION_UNAVAILABLE`.
67
+
68
+ ## From: Orient on Connectix — 3. Ownership boundaries
69
+
70
+ Each fact has exactly one owner. Violating these boundaries is the primary review blocker:
71
+
72
+ | Fact | Owner |
73
+ |------|-------|
74
+ | Provider secrets and OAuth refresh | **Credorix** — never stored in Connectix or Memorix |
75
+ | Connection bindings and execution records | **Memorix adapter** (in-memory stub today) |
76
+ | Action implementations and provenance | **Connectix executor registry** |
77
+ | Provider definitions (catalog source) | `vendor/open-connector` (pinned engine) |
78
+
79
+ Callers send a `bindingRef`, never a credential. A binding points at a Credorix
80
+ `credentialRef` plus allowlisted action patterns for one provider. The runtime enforces:
81
+ binding exists and is enabled → binding provider matches the action provider → the action id
82
+ matches the binding's allowed patterns → only then lease a credential (live mode only).
83
+
84
+ Execution mode is always explicit. **Stub** returns the deterministic fixture published with the
85
+ action and records `mode=stub` in Memorix; **live** leases a credential and calls the provider.
86
+ Every published action must ship a schema-valid stub fixture, which is what makes local and CI
87
+ development safe by default.
88
+
89
+ ## Also see
90
+
91
+ - **call-connect-tools** (`call-connect-tools`) —
92
+
93
+ ---
94
+
95
+ _Generated use-case pack for agents and humans. See `agent-manifest.json` for discovery._