@nebutra/ecosystem-safety 0.1.2 → 0.1.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # @nebutra/ecosystem-safety
2
2
 
3
+ ## 0.1.4
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies []:
8
+ - @nebutra/errors@2.0.0
9
+
3
10
  ## 0.1.2
4
11
 
5
12
  ### Patch Changes
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@nebutra/ecosystem-safety",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Shared public-disclosure safety primitives for ecosystem publishing surfaces",
5
5
  "private": false,
6
6
  "license": "MIT",
7
7
  "type": "module",
8
8
  "nebutra": {
9
+ "graph": "labs",
9
10
  "status": "wip",
10
11
  "productionReady": false,
11
12
  "surface": "support-contract",
@@ -21,13 +22,17 @@
21
22
  "category": "ai",
22
23
  "summary": "Single shared owner for public-disclosure sensitive-field scanning"
23
24
  },
24
- "main": "./src/index.ts",
25
- "types": "./src/index.ts",
25
+ "main": "./dist/index.js",
26
+ "types": "./dist/index.d.ts",
26
27
  "exports": {
27
- ".": "./src/index.ts"
28
+ ".": {
29
+ "types": "./dist/index.d.ts",
30
+ "import": "./dist/index.js",
31
+ "default": "./dist/index.js"
32
+ }
28
33
  },
29
34
  "dependencies": {
30
- "@nebutra/errors": "0.1.2"
35
+ "@nebutra/errors": "2.0.0"
31
36
  },
32
37
  "devDependencies": {
33
38
  "@types/node": "^25.9.1",
@@ -47,6 +52,12 @@
47
52
  "publishConfig": {
48
53
  "access": "public"
49
54
  },
55
+ "files": [
56
+ "dist",
57
+ "README.md",
58
+ "LICENSE",
59
+ "CHANGELOG.md"
60
+ ],
50
61
  "scripts": {
51
62
  "build": "tsup",
52
63
  "test": "vitest run",
@@ -1,17 +0,0 @@
1
-
2
- > @nebutra/ecosystem-safety@0.1.2 build /Users/tseka_luk/Documents/Nebutra-SaaS-Lab/Nebutra-Sailor/packages/ai/ecosystem-safety
3
- > tsup
4
-
5
- CLI Building entry: src/index.ts
6
- CLI Using tsconfig: tsconfig.json
7
- CLI tsup v8.5.1
8
- CLI Using tsup config: /Users/tseka_luk/Documents/Nebutra-SaaS-Lab/Nebutra-Sailor/packages/ai/ecosystem-safety/tsup.config.ts
9
- CLI Target: es2022
10
- CLI Cleaning output folder
11
- ESM Build start
12
- ESM dist/index.js 1.60 KB
13
- ESM dist/index.js.map 3.27 KB
14
- ESM ⚡️ Build success in 9ms
15
- DTS Build start
16
- DTS ⚡️ Build success in 1574ms
17
- DTS dist/index.d.ts 662.00 B
@@ -1,14 +0,0 @@
1
-
2
- > @nebutra/ecosystem-safety@0.1.1 test /Users/tseka_luk/Documents/Nebutra-SaaS-Lab/Nebutra-Sailor/packages/ai/ecosystem-safety
3
- > vitest run
4
-
5
-
6
- RUN v4.1.4 /Users/tseka_luk/Documents/Nebutra-SaaS-Lab/Nebutra-Sailor/packages/ai/ecosystem-safety
7
-
8
- ✓ src/index.test.ts (3 tests) 4ms
9
-
10
- Test Files 1 passed (1)
11
- Tests 3 passed (3)
12
- Start at 09:38:31
13
- Duration 248ms (transform 43ms, setup 0ms, import 56ms, tests 4ms, environment 0ms)
14
-
@@ -1,4 +0,0 @@
1
-
2
- > @nebutra/ecosystem-safety@0.1.2 typecheck /Users/tseka_luk/Documents/Nebutra-SaaS-Lab/Nebutra-Sailor/packages/ai/ecosystem-safety
3
- > tsc --noEmit
4
-
package/src/index.test.ts DELETED
@@ -1,32 +0,0 @@
1
- import { describe, expect, it } from "vitest";
2
- import { assertPublicDisclosureSafe, scanForSensitiveFields } from "./index";
3
-
4
- describe("ecosystem-safety", () => {
5
- it("detects emails and token-like secrets deterministically", () => {
6
- expect(
7
- scanForSensitiveFields("Contact alice@example.com with api key sk-test-1234567890."),
8
- ).toEqual([
9
- { kind: "email", value: "alice@example.com" },
10
- { kind: "secret", value: "sk-test-1234567890" },
11
- ]);
12
- });
13
-
14
- it("rejects public disclosure when sensitive fields have no explicit redaction", () => {
15
- expect(() =>
16
- assertPublicDisclosureSafe({
17
- capability: "idea-plaza",
18
- content: "customer bob@example.com uses token-api-12345678",
19
- }),
20
- ).toThrow(expect.objectContaining({ capability: "idea-plaza" }));
21
- });
22
-
23
- it("returns detected fields when the caller provides explicit redaction intent", () => {
24
- expect(
25
- assertPublicDisclosureSafe({
26
- capability: "founder-cemetery",
27
- content: "customer bob@example.com",
28
- redactions: ["customers"],
29
- }),
30
- ).toEqual([{ kind: "email", value: "bob@example.com" }]);
31
- });
32
- });
package/src/index.ts DELETED
@@ -1,65 +0,0 @@
1
- import { CapabilityError } from "@nebutra/errors";
2
-
3
- export type SensitiveFieldKind = "email" | "secret";
4
-
5
- export interface SensitiveField {
6
- readonly kind: SensitiveFieldKind;
7
- readonly value: string;
8
- }
9
-
10
- export interface PublicDisclosureSafetyRequest {
11
- readonly capability: string;
12
- readonly content: string;
13
- readonly redactions?: readonly string[];
14
- readonly suggestion?: string;
15
- }
16
-
17
- const EMAIL_RE = /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi;
18
- const SECRET_RE = /\b(?:sk|pk|api|key|token)[-_][A-Za-z0-9][A-Za-z0-9_-]{7,}\b/g;
19
-
20
- function hasExplicitRedaction(redactions: readonly string[] | undefined): boolean {
21
- return Boolean(redactions?.some((item) => item.trim().length > 0));
22
- }
23
-
24
- function uniqueFields(fields: readonly SensitiveField[]): SensitiveField[] {
25
- const seen = new Set<string>();
26
- const unique: SensitiveField[] = [];
27
- for (const field of fields) {
28
- const key = `${field.kind}:${field.value.toLowerCase()}`;
29
- if (seen.has(key)) continue;
30
- seen.add(key);
31
- unique.push(field);
32
- }
33
- return unique;
34
- }
35
-
36
- export function scanForSensitiveFields(content: string): SensitiveField[] {
37
- const emails = [...content.matchAll(EMAIL_RE)].map((match) => ({
38
- kind: "email" as const,
39
- value: match[0],
40
- }));
41
- const secrets = [...content.matchAll(SECRET_RE)].map((match) => ({
42
- kind: "secret" as const,
43
- value: match[0],
44
- }));
45
- return uniqueFields([...emails, ...secrets]);
46
- }
47
-
48
- export function assertPublicDisclosureSafe(
49
- request: PublicDisclosureSafetyRequest,
50
- ): readonly SensitiveField[] {
51
- const sensitive = scanForSensitiveFields(request.content);
52
- if (sensitive.length > 0 && !hasExplicitRedaction(request.redactions)) {
53
- throw new CapabilityError(request.capability, "Sensitive fields require explicit redaction", {
54
- suggestion:
55
- request.suggestion ??
56
- "Review detected private values and pass explicit redactions before publishing.",
57
- metadata: {
58
- sensitiveKinds: [...new Set(sensitive.map((item) => item.kind))],
59
- sensitiveCount: sensitive.length,
60
- },
61
- statusCode: 400,
62
- });
63
- }
64
- return sensitive;
65
- }
package/tsconfig.json DELETED
@@ -1,9 +0,0 @@
1
- {
2
- "extends": "../../../tsconfig.base.json",
3
- "compilerOptions": {
4
- "outDir": "dist",
5
- "rootDir": "src",
6
- "types": ["node", "vitest/globals"]
7
- },
8
- "include": ["src/**/*.ts"]
9
- }
package/tsup.config.ts DELETED
@@ -1,9 +0,0 @@
1
- import { defineConfig } from "tsup";
2
-
3
- export default defineConfig({
4
- clean: true,
5
- dts: true,
6
- entry: ["src/index.ts"],
7
- format: ["esm"],
8
- sourcemap: true,
9
- });