@metaphase-tech/fedspeak 0.1.0 → 1.0.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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 MetaPhase Consulting
3
+ Copyright (c) 2026 MetaPhase
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md ADDED
@@ -0,0 +1,284 @@
1
+ # FedSpeak
2
+
3
+ [![Netlify Status](https://api.netlify.com/api/v1/badges/597db6a2-1d41-4e63-8b46-b1ac35c79a6d/deploy-status)](https://app.netlify.com/projects/fedspeak/deploys)
4
+ [![npm version](https://img.shields.io/npm/v/fedspeak)](https://www.npmjs.com/package/fedspeak)
5
+ [![CI](https://github.com/MetaPhase-Consulting/fedspeak/actions/workflows/ci.yml/badge.svg)](https://github.com/MetaPhase-Consulting/fedspeak/actions/workflows/ci.yml)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
7
+ [![Built by MetaPhase](https://img.shields.io/badge/Built%20by-MetaPhase-fb641f)](https://metaphase.tech)
8
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.5-blue)](https://www.typescriptlang.org/)
9
+
10
+ **Federal Acronym Decoder** — Decode and encode U.S. government acronyms from text or single lookups.
11
+
12
+ FedSpeak is a REST API, interactive website, and npm package that expands **1,119 federal government acronyms** with full names, descriptions, agency context, and category classifications.
13
+
14
+ **Website:** [fedspeak.dev](https://fedspeak.dev)
15
+
16
+ ## Features
17
+
18
+ - **Decode** — Send any acronym, get the full expansion with description, agency, and category
19
+ - **Encode** — Send a full name, get the acronym back
20
+ - **Text Scanning** — Paste a block of text, FedSpeak finds and decodes every recognized acronym
21
+ - **1,119 Acronyms** — Departments, agencies, cybersecurity, NIST, CMMC, procurement, contract vehicles, legislation, and more
22
+ - **REST API** — GET and POST support, JSON responses, CORS enabled
23
+ - **npm Package** — Use the decoder directly in your Node.js projects
24
+ - **Interactive Demo** — Try it live at [fedspeak.dev](https://fedspeak.dev)
25
+
26
+ ## Quick Start
27
+
28
+ ### API
29
+
30
+ ```bash
31
+ # Decode an acronym
32
+ curl -X POST https://fedspeak.netlify.app/api/decode \
33
+ -H "Content-Type: application/json" \
34
+ -d '{"acronym": "DOD"}'
35
+
36
+ # Scan text for acronyms
37
+ curl -X POST https://fedspeak.netlify.app/api/decode \
38
+ -H "Content-Type: application/json" \
39
+ -d '{"text": "The DOD and GSA are working with OMB on the new RFP"}'
40
+
41
+ # Encode a full name to its acronym
42
+ curl -X POST https://fedspeak.netlify.app/api/encode \
43
+ -H "Content-Type: application/json" \
44
+ -d '{"name": "General Services Administration"}'
45
+ ```
46
+
47
+ ### npm Package
48
+
49
+ ```bash
50
+ npm install fedspeak
51
+ # or
52
+ npm install @metaphase-tech/fedspeak
53
+ ```
54
+
55
+ ```typescript
56
+ import { lookupAcronym, scanText, decode, encode, getAcronymCount } from 'fedspeak';
57
+
58
+ // Single lookup
59
+ const result = lookupAcronym('DOD');
60
+ console.log(result?.full); // "Department of Defense"
61
+
62
+ // Scan text for all acronyms
63
+ const found = scanText('The DOD and GSA are working with OMB');
64
+ found.forEach(r => console.log(`${r.acronym} = ${r.full}`));
65
+
66
+ // Full decode with response envelope
67
+ const response = decode({ text: 'Submit the RFP to the CO at GSA' });
68
+ console.log(response.results); // [{ acronym: 'RFP', ... }, { acronym: 'CO', ... }, { acronym: 'GSA', ... }]
69
+
70
+ // Reverse lookup: full name to acronym
71
+ const encoded = encode({ name: 'General Services Administration' });
72
+ console.log(encoded.results[0].acronym); // "GSA"
73
+
74
+ // Total count
75
+ console.log(getAcronymCount()); // 1069
76
+ ```
77
+
78
+ ## API Reference
79
+
80
+ ### Decode
81
+
82
+ ```
83
+ POST /api/decode
84
+ GET /api/decode?acronym=GSA
85
+ GET /api/decode?text=The+DOD+and+GSA+work+with+OMB
86
+ ```
87
+
88
+ **Single lookup request:**
89
+
90
+ ```json
91
+ { "acronym": "GSA" }
92
+ ```
93
+
94
+ **Text scan request:**
95
+
96
+ ```json
97
+ { "text": "The DOD and GSA are working with OMB on the new RFP" }
98
+ ```
99
+
100
+ **Response:**
101
+
102
+ ```json
103
+ {
104
+ "success": true,
105
+ "query": "GSA",
106
+ "mode": "single",
107
+ "results": [{
108
+ "acronym": "GSA",
109
+ "full": "General Services Administration",
110
+ "description": "Federal agency managing government buildings, procurement, and technology solutions.",
111
+ "agency": "GSA",
112
+ "category": "agency",
113
+ "url": "https://www.gsa.gov"
114
+ }],
115
+ "count": 1,
116
+ "truncated": false
117
+ }
118
+ ```
119
+
120
+ ### Encode
121
+
122
+ ```
123
+ POST /api/encode
124
+ GET /api/encode?name=General+Services+Administration
125
+ GET /api/encode?text=The+Department+of+Defense+is+working+with...
126
+ ```
127
+
128
+ **Single lookup request:**
129
+
130
+ ```json
131
+ { "name": "General Services Administration" }
132
+ ```
133
+
134
+ **Text scan request:**
135
+
136
+ ```json
137
+ { "text": "The Department of Defense and General Services Administration..." }
138
+ ```
139
+
140
+ ## npm Package API
141
+
142
+ ### Functions
143
+
144
+ | Function | Description |
145
+ |----------|-------------|
146
+ | `lookupAcronym(query)` | Look up a single acronym. Returns `DecodedResult` or `null` |
147
+ | `scanText(text)` | Scan text for all recognized acronyms. Returns `DecodedResult[]` |
148
+ | `decode(request)` | Full decode with response envelope (`{ acronym }` or `{ text }`) |
149
+ | `lookupName(query)` | Reverse lookup: full name to acronym. Returns `EncodedResult` or `null` |
150
+ | `scanTextForNames(text)` | Scan text for full names, return their acronyms. Returns `EncodedResult[]` |
151
+ | `encode(request)` | Full encode with response envelope (`{ name }` or `{ text }`) |
152
+ | `getAllAcronyms()` | Get sorted array of all acronym keys |
153
+ | `getAcronymCount()` | Get total number of acronyms in the database |
154
+ | `truncateResponse(response)` | Truncate response to fit 2000-char limit |
155
+
156
+ ### TypeScript Types
157
+
158
+ ```typescript
159
+ import type {
160
+ AcronymCategory, // 'department' | 'agency' | 'office' | 'bureau' | 'program' | 'process' | 'regulation' | 'system' | 'general'
161
+ AcronymEntry, // { full, description, agency, category, url?, aliases? }
162
+ AcronymData, // Record of acronym key to AcronymEntry
163
+ DecodedResult, // Single decode result
164
+ DecodeResponse, // Full decode response envelope
165
+ DecodeRequest, // { acronym?: string; text?: string }
166
+ EncodedResult, // Single encode result
167
+ EncodeResponse, // Full encode response envelope
168
+ EncodeRequest, // { name?: string; text?: string }
169
+ } from 'fedspeak';
170
+ ```
171
+
172
+ ## Acronym Coverage
173
+
174
+ 1,119 entries across these categories:
175
+
176
+ | Category | Examples |
177
+ |----------|----------|
178
+ | **Federal departments** | DOD, DOJ, DOE, HHS, DHS, VA, DOS, DOT, ... |
179
+ | **Agencies & offices** | NASA, GSA, EPA, SBA, CISA, NIST, OPM, FEMA, ... |
180
+ | **Cybersecurity & NIST** | CMMC, FedRAMP, FISMA, CVE, CVSS, ZTA, ATT&CK, CSF, ... |
181
+ | **Identity & auth** | IAL, AAL, FAL, MFA, FIDO, PIV, CAC, SSO, ... |
182
+ | **Procurement & acquisition** | FAR, DFARS, GWAC, IDIQ, BPA, RFP, CO, COR, ... |
183
+ | **Contract vehicles** | OASIS+, CIO-SP4, SEWP VI, 8(a) STARS III, ALLIANT 2, ... |
184
+ | **Legislation** | FITARA, FOIA, APA, NEPA, HIPAA, FISMA, ACA, ... |
185
+ | **IT & systems** | FedRAMP, ATO, HSPD-12, eMASS, Login.gov, ... |
186
+ | **Budget & finance** | OMB, CBO, GAO, PPBE, CR, ... |
187
+ | **HR & personnel** | OPM, GS, SES, USERRA, ... |
188
+
189
+ ## Development
190
+
191
+ ### Prerequisites
192
+
193
+ - Node.js 20+
194
+ - npm 10+
195
+
196
+ ### Setup
197
+
198
+ ```bash
199
+ git clone https://github.com/MetaPhase-Consulting/fedspeak.git
200
+ cd fedspeak
201
+ npm install
202
+ ```
203
+
204
+ ### Commands
205
+
206
+ | Command | Description |
207
+ |---------|-------------|
208
+ | `npm run dev` | Start Vite dev server |
209
+ | `npx netlify dev` | Full local dev with API at localhost:8888 |
210
+ | `npm run build` | Production build |
211
+ | `npm run lint` | ESLint |
212
+ | `npm run typecheck` | TypeScript strict check |
213
+ | `npm run test:run` | Run tests once |
214
+ | `npm run test` | Run tests in watch mode |
215
+ | `npm run test:coverage` | Run tests with coverage |
216
+
217
+ ### Project Structure
218
+
219
+ ```
220
+ fedspeak/
221
+ ├── netlify/functions/ Serverless API endpoints
222
+ │ ├── decode.ts POST /api/decode
223
+ │ └── encode.ts POST /api/encode
224
+ ├── src/
225
+ │ ├── shared/ Core logic (shared by API, website, npm package)
226
+ │ │ ├── decoder.ts lookupAcronym(), scanText(), decode()
227
+ │ │ ├── encoder.ts lookupName(), scanTextForNames(), encode()
228
+ │ │ ├── truncate.ts Response truncation
229
+ │ │ ├── types.ts TypeScript interfaces
230
+ │ │ └── data/
231
+ │ │ └── acronyms.json
232
+ │ ├── components/ React UI components
233
+ │ └── pages/ React Router pages
234
+ ├── cli-package/ npm package for publishing
235
+ ├── tests/ Vitest test suites
236
+ ├── public/openapi.json OpenAPI 3.1 specification
237
+ └── .github/workflows/ CI/CD pipelines
238
+ ```
239
+
240
+ ### Tech Stack
241
+
242
+ | Layer | Choice |
243
+ |-------|--------|
244
+ | Runtime | Node.js 20, TypeScript 5.5 |
245
+ | API | Netlify Functions v2 (serverless) |
246
+ | Data | Static JSON (no database) |
247
+ | Website | Vite + React 18 + Tailwind CSS + React Router |
248
+ | Testing | Vitest + @vitest/coverage-v8 |
249
+ | CI/CD | GitHub Actions |
250
+ | Deploy | Netlify |
251
+
252
+ ### Adding Acronyms
253
+
254
+ Add entries to `src/shared/data/acronyms.json` in alphabetical order:
255
+
256
+ ```json
257
+ "ACRONYM": {
258
+ "full": "Full Name",
259
+ "description": "Brief description (1-2 sentences).",
260
+ "agency": "Parent agency acronym or General",
261
+ "category": "department|agency|office|bureau|program|process|regulation|system|general",
262
+ "url": "https://optional-official-website.gov",
263
+ "aliases": ["optional", "alternate", "spellings"]
264
+ }
265
+ ```
266
+
267
+ ## Contributing
268
+
269
+ 1. Fork the repository
270
+ 2. Create a feature branch from `dev`
271
+ 3. Make your changes
272
+ 4. Ensure `npm run lint`, `npm run typecheck`, and `npm run test:run` all pass
273
+ 5. Open a PR to `dev`
274
+
275
+ ### Branching
276
+
277
+ - **`dev`** — Default branch, active development
278
+ - **`main`** — Production, deploys to Netlify
279
+ - Feature branches merge into `dev` via PR
280
+ - `dev` merges into `main` via PR for releases
281
+
282
+ ## License
283
+
284
+ [MIT](LICENSE) © [MetaPhase](https://metaphase.tech)
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { lookupAcronym, scanText, decode, getAllAcronyms, getAcronymCount } from './shared/decoder';
2
2
  export { lookupName, scanTextForNames, encode } from './shared/encoder';
3
- export { truncateForJoin39 } from './shared/truncate';
3
+ export { truncateResponse } from './shared/truncate';
4
4
  export type { AcronymCategory, AcronymEntry, AcronymData, DecodedResult, DecodeResponse, DecodeRequest, EncodedResult, EncodeResponse, EncodeRequest, } from './shared/types';
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACpG,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,YAAY,EACV,eAAe,EACf,YAAY,EACZ,WAAW,EACX,aAAa,EACb,cAAc,EACd,aAAa,EACb,aAAa,EACb,cAAc,EACd,aAAa,GACd,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACpG,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,YAAY,EACV,eAAe,EACf,YAAY,EACZ,WAAW,EACX,aAAa,EACb,cAAc,EACd,aAAa,EACb,aAAa,EACb,cAAc,EACd,aAAa,GACd,MAAM,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -2,5 +2,5 @@
2
2
  // Re-exports from shared core (files synced via scripts/sync-cli-package.sh)
3
3
  export { lookupAcronym, scanText, decode, getAllAcronyms, getAcronymCount } from './shared/decoder';
4
4
  export { lookupName, scanTextForNames, encode } from './shared/encoder';
5
- export { truncateForJoin39 } from './shared/truncate';
5
+ export { truncateResponse } from './shared/truncate';
6
6
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,6EAA6E;AAE7E,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACpG,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mCAAmC;AACnC,6EAA6E;AAE7E,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACpG,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC"}