@hanv89/azure-arch-skill 0.1.0 → 0.2.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 CHANGED
@@ -1,9 +1,9 @@
1
1
  # @hanv89/azure-arch-skill
2
2
 
3
- > **Status**: pre-publish. The package is not yet on npmjs.com — the `npx` command below works once the first release ships.
4
-
5
3
  CLI installer for the Azure architecture diagram skill. Drops the skill bundle (`SKILL.md` + worked PlantUML examples) into your AI coding agent's skill folder so that prompts like *"draw an Azure context diagram"* produce diagrams that use official Microsoft Azure architecture icons.
6
4
 
5
+ Published with Sigstore provenance via npm Trusted Publishing — verify with `npm view @hanv89/azure-arch-skill@latest dist.attestations`.
6
+
7
7
  ## Requirements
8
8
 
9
9
  - Node.js ≥ 20
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
26
26
  return (mod && mod.__esModule) ? mod : { "default": mod };
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.claudeCodeAdapter = exports.parseFrontmatter = void 0;
29
+ exports.claudeCodeAdapter = exports.parseFrontmatter = exports.fetchWithTimeout = void 0;
30
30
  const fs = __importStar(require("node:fs/promises"));
31
31
  const path = __importStar(require("node:path"));
32
32
  const os = __importStar(require("node:os"));
@@ -37,9 +37,12 @@ const DEFAULT_BASE_RAW_URL = "https://raw.githubusercontent.com/hanv89/azure-ico
37
37
  // existing installs become un-uninstallable until users upgrade the CLI
38
38
  // (uninstall's allow-list refuses folders whose SKILL.md `name` differs).
39
39
  const SKILL_NAME = "azure-architecture-diagram";
40
+ // Hard-coded bundle list. Keep SKILL.md as index 0 — install() relies on
41
+ // BUNDLE_FILES[0] for the frontmatter-parsing precheck.
40
42
  const BUNDLE_FILES = [
41
43
  { src: "dist/skill/SKILL.md", dest: "SKILL.md" },
42
44
  { src: "dist/skill/examples/01-context.puml", dest: "examples/01-context.puml" },
45
+ { src: "dist/skill/examples/02-fabric-data-pipeline.puml", dest: "examples/02-fabric-data-pipeline.puml" },
43
46
  ];
44
47
  const CANARY_ICON_PATH = "dist/Azure/Compute/AzureVirtualMachine.png";
45
48
  const FETCH_TIMEOUT_MS = 30_000;
@@ -128,20 +131,50 @@ async function safeResolveTarget(target) {
128
131
  }
129
132
  return realResolved;
130
133
  }
131
- async function fetchWithTimeout(url, init = {}) {
132
- const ctrl = new AbortController();
133
- const t = setTimeout(() => ctrl.abort(), FETCH_TIMEOUT_MS);
134
- try {
135
- return await fetch(url, {
136
- ...init,
137
- signal: ctrl.signal,
138
- headers: { ...(init.headers || {}), "User-Agent": USER_AGENT },
139
- });
140
- }
141
- finally {
142
- clearTimeout(t);
134
+ /**
135
+ * Fetch with timeout and 2-retry exponential backoff on transient 5xx
136
+ * responses. Used by `fetchText` and `headOk`; both inherit the retry
137
+ * behavior. Default `retries = 2` matches the R30 fix (Phase 1.0) —
138
+ * future agent adapters reusing this helper get the retry path for free.
139
+ *
140
+ * Backoff schedule: 500ms after attempt 0, 1s after attempt 1, 2s after
141
+ * attempt 2. Network errors (AbortError, DNS failures) re-throw only
142
+ * after the final attempt.
143
+ *
144
+ * @internal — exported only so unit tests can mock `globalThis.fetch`
145
+ * around it. Not part of the public adapter API.
146
+ */
147
+ async function fetchWithTimeout(url, init = {}, retries = 2) {
148
+ let lastError;
149
+ for (let attempt = 0; attempt <= retries; attempt++) {
150
+ const ctrl = new AbortController();
151
+ const t = setTimeout(() => ctrl.abort(), FETCH_TIMEOUT_MS);
152
+ try {
153
+ const res = await fetch(url, {
154
+ ...init,
155
+ signal: ctrl.signal,
156
+ headers: { ...(init.headers || {}), "User-Agent": USER_AGENT },
157
+ });
158
+ if (res.status < 500 || attempt === retries) {
159
+ return res;
160
+ }
161
+ // 5xx with retries remaining: fall through to backoff.
162
+ }
163
+ catch (e) {
164
+ lastError = e;
165
+ if (attempt === retries)
166
+ throw e;
167
+ }
168
+ finally {
169
+ clearTimeout(t);
170
+ }
171
+ // Exponential backoff: 500ms, 1s, 2s.
172
+ await new Promise((r) => setTimeout(r, 2 ** attempt * 500));
143
173
  }
174
+ // Unreachable: the loop body always returns or throws on the final attempt.
175
+ throw lastError ?? new Error("fetchWithTimeout: exhausted retries");
144
176
  }
177
+ exports.fetchWithTimeout = fetchWithTimeout;
145
178
  async function fetchText(url) {
146
179
  const res = await fetchWithTimeout(url);
147
180
  if (!res.ok)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hanv89/azure-arch-skill",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Install the Azure architecture diagram skill into your AI coding agent (Claude Code, Codex CLI, Cursor).",
5
5
  "bin": {
6
6
  "azure-arch-skill": "dist/index.js"