@ductape/mcp 0.1.49 → 0.1.51

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.
@@ -15,6 +15,7 @@ export interface IGenerateExecutablePayloadRequest {
15
15
  method: string;
16
16
  targets?: Record<string, unknown>;
17
17
  include_session?: boolean;
18
+ execution_context?: 'user' | 'delegated' | 'system';
18
19
  include_cache?: boolean;
19
20
  schema_mode?: 'strict' | 'best_effort';
20
21
  input_hint?: Record<string, unknown>;
@@ -1 +1 @@
1
- {"version":3,"file":"proxy-client.d.ts","sourceRoot":"","sources":["../src/proxy-client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,YAAY,4BAA4B,CAAC;AAEtD,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,KAAK,GACL,WAAW,GACX,OAAO,GACP,UAAU,GACV,eAAe,GACf,gBAAgB,GAChB,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,UAAU,GACV,QAAQ,GACR,SAAS,GACT,UAAU,GACV,MAAM,GACN,MAAM,GACN,YAAY,GACZ,QAAQ,GACR,UAAU,GACV,SAAS,CAAC;AAUd;;GAEG;AACH,wBAAsB,eAAe,CAAC,CAAC,GAAG,OAAO,EAC/C,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,OAAO,EAAO,GACrB,OAAO,CAAC,CAAC,CAAC,CAuBZ;AAED,MAAM,WAAW,iCAAiC;IAChD,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,QAAQ,GAAG,aAAa,CAAC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,kCAAkC;IACjD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AASD,wBAAsB,eAAe,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAYvE;AA4BD,wBAAsB,yBAAyB,CAAC,CAAC,GAAG,kCAAkC,EACpF,OAAO,EAAE,iCAAiC,GACzC,OAAO,CAAC,CAAC,CAAC,CAwBZ"}
1
+ {"version":3,"file":"proxy-client.d.ts","sourceRoot":"","sources":["../src/proxy-client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,YAAY,4BAA4B,CAAC;AAEtD,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,KAAK,GACL,WAAW,GACX,OAAO,GACP,UAAU,GACV,eAAe,GACf,gBAAgB,GAChB,QAAQ,GACR,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,UAAU,GACV,QAAQ,GACR,SAAS,GACT,UAAU,GACV,MAAM,GACN,MAAM,GACN,YAAY,GACZ,QAAQ,GACR,UAAU,GACV,SAAS,CAAC;AAUd;;GAEG;AACH,wBAAsB,eAAe,CAAC,CAAC,GAAG,OAAO,EAC/C,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,OAAO,EAAO,GACrB,OAAO,CAAC,CAAC,CAAC,CAuBZ;AAED,MAAM,WAAW,iCAAiC;IAChD,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,iBAAiB,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;IACpD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,QAAQ,GAAG,aAAa,CAAC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,kCAAkC;IACjD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AASD,wBAAsB,eAAe,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAYvE;AA4BD,wBAAsB,yBAAyB,CAAC,CAAC,GAAG,kCAAkC,EACpF,OAAO,EAAE,iCAAiC,GACzC,OAAO,CAAC,CAAC,CAAC,CAwBZ"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ductape/mcp",
3
- "version": "0.1.49",
3
+ "version": "0.1.51",
4
4
  "description": "MCP server that exposes Ductape SDK operations via the backend proxy",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -9,6 +9,7 @@
9
9
  },
10
10
  "scripts": {
11
11
  "build": "tsc",
12
+ "test": "node scripts/check-frontend-analytics-guidance.mjs",
12
13
  "start": "node dist/index.js",
13
14
  "dev": "tsx src/index.ts"
14
15
  },
@@ -0,0 +1,57 @@
1
+ import assert from 'node:assert/strict';
2
+ import { readFileSync } from 'node:fs';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { dirname, resolve } from 'node:path';
5
+
6
+ const here = dirname(fileURLToPath(import.meta.url));
7
+ const source = readFileSync(resolve(here, '../src/index.ts'), 'utf8');
8
+
9
+ const checks = [
10
+ ['dedicated docs topic', /'frontend-analytics': `/],
11
+ ['anonymous analytics without an invented session', /Before login:[\s\S]*do not invent a session/i],
12
+ ['identify after authentication', /After login\/registration:[\s\S]*identify\(fullSessionToken\)/i],
13
+ ['identify after refresh', /After refresh:[\s\S]*identify\(newSessionToken\)/i],
14
+ ['clear identity on logout and account switching', /LOGOUT \/ ACCOUNT SWITCHING[\s\S]*clearSession\(\)/],
15
+ ['SPA route pageviews', /location\.pathname[\s\S]*analytics\.pageview/],
16
+ ['pageviews and custom events', /CUSTOM EVENTS[\s\S]*PAGE VIEWS/],
17
+ ['analytics is non-authoritative', /Analytics is never an authoritative order/],
18
+ ['tokens excluded from properties', /session\/refresh tokens in event[\s\S]*properties/],
19
+ ['hidden multiplayer state warning', /HIDDEN AND SENSITIVE DATA/],
20
+ ['masking review before auto-capture', /AUTO-CAPTURE — OPT IN ONLY AFTER A PRIVACY AUDIT/],
21
+ ['visitor ID is not authentication', /visitor ID is anonymous analytics identity, not authentication/i],
22
+ ['trace correlation', /traceId\s*= correlation/],
23
+ ['dashboard troubleshooting covers both tracks', /Investigate both tracks before blaming the SDK/],
24
+ ['installed exports take precedence', /Installed package types and exports determine what can be called now/],
25
+ ];
26
+
27
+ for (const [name, pattern] of checks) {
28
+ assert.match(source, pattern, `Missing frontend analytics guidance: ${name}`);
29
+ }
30
+
31
+ assert.doesNotMatch(
32
+ source,
33
+ /analytics\.identify\(\{\s*userId/,
34
+ 'MCP guidance must not use the obsolete identify({ userId, traits }) signature',
35
+ );
36
+
37
+ const safetyChecks = [
38
+ ['admin execute calls removed', /ductape_execute\("[^"\n]*(?:create|update)/],
39
+ ['obsolete NestJS consumer removed', /events\.consume in onModuleInit/],
40
+ ['canonical NestJS consumer present', /@Events\.Consumer\(\{ event:/],
41
+ ['request actor context documented', /AsyncLocalStorage[\s\S]*ActorContext/],
42
+ ['raw token logging prohibited', /Never log,[\s\S]*raw session\/refresh token/],
43
+ ['durable token expiry semantics documented', /does not expose an immutable[\s\S]*expired-token attribution contract/],
44
+ ['resilience decision matrix present', /DECISION MATRIX[\s\S]*Database atomicity/],
45
+ ['payload session-awareness metadata present', /session_awareness:[\s\S]*accepts_session/],
46
+ ['execute blocks administrative mutations', /Administrative operation.*is blocked in ductape_execute/],
47
+ ];
48
+
49
+ for (const [name, pattern] of safetyChecks) {
50
+ if (name === 'admin execute calls removed' || name === 'obsolete NestJS consumer removed') {
51
+ assert.doesNotMatch(source, pattern, `Unsafe MCP guidance remains: ${name}`);
52
+ } else {
53
+ assert.match(source, pattern, `Missing MCP safety guidance: ${name}`);
54
+ }
55
+ }
56
+
57
+ console.log(`MCP guidance: ${checks.length + 1 + safetyChecks.length} acceptance checks passed`);