@roarpeng/graphflow 1.14.1 → 1.15.1

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 (81) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +3 -3
  3. package/README.zh.md +1 -1
  4. package/dist/config/schema.d.ts +3 -1
  5. package/dist/config/schema.d.ts.map +1 -1
  6. package/dist/graph/client-factory.d.ts.map +1 -1
  7. package/dist/graph/client-factory.js +4 -1
  8. package/dist/graph/client-factory.js.map +1 -1
  9. package/dist/graph/graphify-mcp-client.d.ts +33 -0
  10. package/dist/graph/graphify-mcp-client.d.ts.map +1 -1
  11. package/dist/graph/graphify-mcp-client.js +66 -5
  12. package/dist/graph/graphify-mcp-client.js.map +1 -1
  13. package/dist/index.d.ts +3 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +10 -1
  16. package/dist/index.js.map +1 -1
  17. package/dist/integrations/claude-code-host-installer.d.ts +42 -0
  18. package/dist/integrations/claude-code-host-installer.d.ts.map +1 -0
  19. package/dist/integrations/claude-code-host-installer.js +341 -0
  20. package/dist/integrations/claude-code-host-installer.js.map +1 -0
  21. package/dist/integrations/cursor-host-installer.d.ts +38 -0
  22. package/dist/integrations/cursor-host-installer.d.ts.map +1 -0
  23. package/dist/integrations/cursor-host-installer.js +291 -0
  24. package/dist/integrations/cursor-host-installer.js.map +1 -0
  25. package/dist/integrations/host-adapter-install.d.ts +39 -4
  26. package/dist/integrations/host-adapter-install.d.ts.map +1 -1
  27. package/dist/integrations/host-adapter-install.js +90 -9
  28. package/dist/integrations/host-adapter-install.js.map +1 -1
  29. package/dist/integrations/host-adapter.d.ts +2 -2
  30. package/dist/security/rbac.d.ts +39 -0
  31. package/dist/security/rbac.d.ts.map +1 -0
  32. package/dist/security/rbac.js +213 -0
  33. package/dist/security/rbac.js.map +1 -0
  34. package/dist/security/token-auth.d.ts +15 -2
  35. package/dist/security/token-auth.d.ts.map +1 -1
  36. package/dist/security/token-auth.js +86 -5
  37. package/dist/security/token-auth.js.map +1 -1
  38. package/dist/surfaces/cli/index.js +79 -4
  39. package/dist/surfaces/cli/index.js.map +1 -1
  40. package/dist/surfaces/cli/init.d.ts +3 -0
  41. package/dist/surfaces/cli/init.d.ts.map +1 -1
  42. package/dist/surfaces/cli/init.js +133 -59
  43. package/dist/surfaces/cli/init.js.map +1 -1
  44. package/dist/surfaces/cli/output.d.ts.map +1 -1
  45. package/dist/surfaces/cli/output.js +7 -3
  46. package/dist/surfaces/cli/output.js.map +1 -1
  47. package/dist/surfaces/cli/runtime/graph.d.ts +13 -0
  48. package/dist/surfaces/cli/runtime/graph.d.ts.map +1 -1
  49. package/dist/surfaces/cli/runtime/graph.js +97 -9
  50. package/dist/surfaces/cli/runtime/graph.js.map +1 -1
  51. package/dist/surfaces/cli/runtime/routing.d.ts +1 -1
  52. package/dist/surfaces/cli/runtime/routing.d.ts.map +1 -1
  53. package/dist/surfaces/cli/runtime/routing.js +12 -2
  54. package/dist/surfaces/cli/runtime/routing.js.map +1 -1
  55. package/dist/surfaces/cli/runtime/types.d.ts +3 -0
  56. package/dist/surfaces/cli/runtime/types.d.ts.map +1 -1
  57. package/dist/surfaces/cli/runtime.d.ts +1 -1
  58. package/dist/surfaces/cli/runtime.d.ts.map +1 -1
  59. package/dist/surfaces/cli/runtime.js +3 -2
  60. package/dist/surfaces/cli/runtime.js.map +1 -1
  61. package/dist/surfaces/mcp/server.d.ts +2 -0
  62. package/dist/surfaces/mcp/server.d.ts.map +1 -1
  63. package/dist/surfaces/mcp/server.js +77 -37
  64. package/dist/surfaces/mcp/server.js.map +1 -1
  65. package/dist/surfaces/mcp/tool-handlers.d.ts.map +1 -1
  66. package/dist/surfaces/mcp/tool-handlers.js +2 -0
  67. package/dist/surfaces/mcp/tool-handlers.js.map +1 -1
  68. package/dist/surfaces/team/diagnose.d.ts +18 -0
  69. package/dist/surfaces/team/diagnose.d.ts.map +1 -0
  70. package/dist/surfaces/team/diagnose.js +57 -0
  71. package/dist/surfaces/team/diagnose.js.map +1 -0
  72. package/dist/surfaces/team/ops.d.ts +16 -0
  73. package/dist/surfaces/team/ops.d.ts.map +1 -0
  74. package/dist/surfaces/team/ops.js +137 -0
  75. package/dist/surfaces/team/ops.js.map +1 -0
  76. package/dist/surfaces/team/server.d.ts +48 -0
  77. package/dist/surfaces/team/server.d.ts.map +1 -0
  78. package/dist/surfaces/team/server.js +393 -0
  79. package/dist/surfaces/team/server.js.map +1 -0
  80. package/package.json +1 -1
  81. package/plugin.json +1 -1
@@ -0,0 +1,213 @@
1
+ "use strict";
2
+ /**
3
+ * Team HTTP RBAC — viewer | contributor | admin.
4
+ *
5
+ * Local-first surfaces (stdio, loopback file/sqlite, unauthenticated loopback
6
+ * HTTP) never consult this module. Shared HTTP surfaces fail closed: a missing
7
+ * role is a deny, not a silent grant.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.TeamAuthorizationError = exports.TEAM_PERMISSIONS = exports.TEAM_ROLES = void 0;
11
+ exports.isTeamRole = isTeamRole;
12
+ exports.permissionsForRole = permissionsForRole;
13
+ exports.roleSatisfies = roleSatisfies;
14
+ exports.hasPermission = hasPermission;
15
+ exports.roleFromScopes = roleFromScopes;
16
+ exports.defaultScopesForRole = defaultScopesForRole;
17
+ exports.permissionForTeamMethod = permissionForTeamMethod;
18
+ exports.permissionForMcpTool = permissionForMcpTool;
19
+ exports.authorizePermission = authorizePermission;
20
+ exports.authorizeTeamMethod = authorizeTeamMethod;
21
+ exports.authorizeMcpTool = authorizeMcpTool;
22
+ exports.assertAuthorized = assertAuthorized;
23
+ exports.TEAM_ROLES = ["viewer", "contributor", "admin"];
24
+ exports.TEAM_PERMISSIONS = [
25
+ "graph.read",
26
+ "graph.write",
27
+ "graph.delete",
28
+ "skill.read",
29
+ "skill.sync",
30
+ "artifact.import",
31
+ "governance.mutate",
32
+ "diagnose.read",
33
+ ];
34
+ const ROLE_RANK = {
35
+ viewer: 0,
36
+ contributor: 1,
37
+ admin: 2,
38
+ };
39
+ const ROLE_PERMISSIONS = {
40
+ viewer: ["graph.read", "skill.read", "diagnose.read"],
41
+ contributor: [
42
+ "graph.read",
43
+ "graph.write",
44
+ "skill.read",
45
+ "skill.sync",
46
+ "artifact.import",
47
+ "diagnose.read",
48
+ ],
49
+ admin: [
50
+ "graph.read",
51
+ "graph.write",
52
+ "graph.delete",
53
+ "skill.read",
54
+ "skill.sync",
55
+ "artifact.import",
56
+ "governance.mutate",
57
+ "diagnose.read",
58
+ ],
59
+ };
60
+ /** Graphify / team-memory JSON-RPC methods. */
61
+ const TEAM_METHOD_PERMISSION = {
62
+ "graph.query_subgraph": "graph.read",
63
+ "graph.get_nodes": "graph.read",
64
+ "graph.get_neighbors": "graph.read",
65
+ "graph.read_snapshot": "graph.read",
66
+ "team.health": "diagnose.read",
67
+ "graph.upsert_nodes": "graph.write",
68
+ "graph.upsert_edges": "graph.write",
69
+ "graph.delete_node": "graph.delete",
70
+ "graph.delete_edge": "graph.delete",
71
+ "skill.sync_push": "skill.sync",
72
+ "skill.sync_pull": "skill.read",
73
+ "artifact.import": "artifact.import",
74
+ "governance.quarantine": "governance.mutate",
75
+ "governance.review": "governance.mutate",
76
+ };
77
+ /** GraphFlow MCP tool names on the shared HTTP surface. */
78
+ const MCP_TOOL_PERMISSION = {
79
+ graphflow_context: "graph.read",
80
+ graphflow_diagnose: "diagnose.read",
81
+ graphflow_skill_insights: "skill.read",
82
+ graphflow_skill_guide: "diagnose.read",
83
+ graphflow_run: "graph.write",
84
+ graphflow_plan: "graph.write",
85
+ graphflow_index: "graph.write",
86
+ graphflow_insight: "graph.write",
87
+ graphflow_report_outcome: "graph.write",
88
+ graphflow_artifact: "artifact.import",
89
+ };
90
+ function isTeamRole(value) {
91
+ return typeof value === "string" && exports.TEAM_ROLES.includes(value);
92
+ }
93
+ function permissionsForRole(role) {
94
+ return ROLE_PERMISSIONS[role];
95
+ }
96
+ function roleSatisfies(actual, required) {
97
+ return ROLE_RANK[actual] >= ROLE_RANK[required];
98
+ }
99
+ function hasPermission(role, permission) {
100
+ if (!role)
101
+ return false;
102
+ return ROLE_PERMISSIONS[role].includes(permission);
103
+ }
104
+ /**
105
+ * Map JWT `scope` tokens (and a few aliases) to the strongest matching role.
106
+ * Unknown scopes are ignored — absence of a known role scope means unresolved.
107
+ */
108
+ function roleFromScopes(scopes) {
109
+ let best;
110
+ for (const raw of scopes) {
111
+ const scope = raw.trim().toLowerCase();
112
+ if (!scope)
113
+ continue;
114
+ const mapped = mapScopeToken(scope);
115
+ if (!mapped)
116
+ continue;
117
+ if (!best || ROLE_RANK[mapped] > ROLE_RANK[best])
118
+ best = mapped;
119
+ }
120
+ return best;
121
+ }
122
+ function mapScopeToken(scope) {
123
+ if (scope === "memory:admin" ||
124
+ scope === "admin" ||
125
+ scope === "role:admin" ||
126
+ scope === "graphflow:admin") {
127
+ return "admin";
128
+ }
129
+ if (scope === "memory:write" ||
130
+ scope === "contributor" ||
131
+ scope === "role:contributor" ||
132
+ scope === "editor" ||
133
+ scope === "role:editor" ||
134
+ scope === "graphflow:write") {
135
+ return "contributor";
136
+ }
137
+ if (scope === "memory:read" ||
138
+ scope === "viewer" ||
139
+ scope === "role:viewer" ||
140
+ scope === "graphflow:read") {
141
+ return "viewer";
142
+ }
143
+ return undefined;
144
+ }
145
+ function defaultScopesForRole(role) {
146
+ if (role === "admin")
147
+ return "memory:read memory:write memory:admin";
148
+ if (role === "contributor")
149
+ return "memory:read memory:write";
150
+ return "memory:read";
151
+ }
152
+ function permissionForTeamMethod(method) {
153
+ return TEAM_METHOD_PERMISSION[method];
154
+ }
155
+ function permissionForMcpTool(toolName) {
156
+ return MCP_TOOL_PERMISSION[toolName];
157
+ }
158
+ function authorizePermission(role, permission, subject = "action") {
159
+ if (!role) {
160
+ return {
161
+ ok: false,
162
+ permission,
163
+ reason: `RBAC denied ${subject}: role unresolved (fail closed)`,
164
+ };
165
+ }
166
+ if (!hasPermission(role, permission)) {
167
+ return {
168
+ ok: false,
169
+ role,
170
+ permission,
171
+ reason: `RBAC denied ${subject}: role '${role}' lacks '${permission}'`,
172
+ };
173
+ }
174
+ return { ok: true, role, permission };
175
+ }
176
+ function authorizeTeamMethod(role, method) {
177
+ const permission = permissionForTeamMethod(method);
178
+ if (!permission) {
179
+ return {
180
+ ok: false,
181
+ ...(role ? { role } : {}),
182
+ reason: `RBAC denied ${method}: unknown method (fail closed)`,
183
+ };
184
+ }
185
+ return authorizePermission(role, permission, method);
186
+ }
187
+ function authorizeMcpTool(role, toolName) {
188
+ const permission = permissionForMcpTool(toolName);
189
+ if (!permission) {
190
+ return {
191
+ ok: false,
192
+ ...(role ? { role } : {}),
193
+ reason: `RBAC denied ${toolName}: unknown tool (fail closed)`,
194
+ };
195
+ }
196
+ return authorizePermission(role, permission, toolName);
197
+ }
198
+ class TeamAuthorizationError extends Error {
199
+ statusCode = 403;
200
+ decision;
201
+ constructor(decision) {
202
+ super(decision.reason ?? "RBAC denied");
203
+ this.name = "TeamAuthorizationError";
204
+ this.decision = decision;
205
+ }
206
+ }
207
+ exports.TeamAuthorizationError = TeamAuthorizationError;
208
+ function assertAuthorized(decision) {
209
+ if (!decision.ok) {
210
+ throw new TeamAuthorizationError(decision);
211
+ }
212
+ }
213
+ //# sourceMappingURL=rbac.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rbac.js","sourceRoot":"","sources":["../../src/security/rbac.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,9 @@
1
+ import { type TeamRole } from "./rbac.js";
1
2
  export interface TokenAuthConfig {
2
3
  /** Shared-secret bearer tokens for local/team deployments. */
3
4
  bearerTokens?: readonly string[];
5
+ /** Optional role assignment for each bearer token value. */
6
+ bearerRoleMap?: Readonly<Record<string, TeamRole>>;
4
7
  /** HS256 JWT secret. */
5
8
  jwtSecret?: string;
6
9
  /** RS256/ES256 public key PEM for OIDC providers. */
@@ -9,15 +12,25 @@ export interface TokenAuthConfig {
9
12
  audience?: string;
10
13
  requiredScope?: string;
11
14
  }
12
- export declare function verifyAccessToken(authorizationHeader: string | undefined, config: TokenAuthConfig): Promise<{
15
+ export interface AccessTokenResult {
13
16
  authenticated: boolean;
14
17
  subject?: string;
15
18
  reason?: string;
16
- }>;
19
+ role?: TeamRole;
20
+ scopes?: string[];
21
+ }
22
+ export declare function verifyAccessToken(authorizationHeader: string | undefined, config: TokenAuthConfig): Promise<AccessTokenResult>;
17
23
  export declare function issueLocalJwt(subject: string, secret: string, options?: {
18
24
  issuer?: string;
19
25
  audience?: string;
20
26
  scope?: string;
27
+ role?: TeamRole;
21
28
  ttlSeconds?: number;
22
29
  }): string;
30
+ /** Parse `viewer:secret`, `admin:secret`, or `secret:admin` into token + role. Bare tokens have no role. */
31
+ export declare function parseRoleTaggedBearer(raw: string): {
32
+ token: string;
33
+ role?: TeamRole;
34
+ };
35
+ export declare function credentialsConfigured(config: TokenAuthConfig | undefined): boolean;
23
36
  //# sourceMappingURL=token-auth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"token-auth.d.ts","sourceRoot":"","sources":["../../src/security/token-auth.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,wBAAwB;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAwCD,wBAAsB,iBAAiB,CACrC,mBAAmB,EAAE,MAAM,GAAG,SAAS,EACvC,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC;IAAE,aAAa,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAkDxE;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAO,GACxF,MAAM,CAeR"}
1
+ {"version":3,"file":"token-auth.d.ts","sourceRoot":"","sources":["../../src/security/token-auth.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,QAAQ,EACd,MAAM,WAAW,CAAC;AAEnB,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,4DAA4D;IAC5D,aAAa,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IACnD,wBAAwB;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAkFD,wBAAsB,iBAAiB,CACrC,mBAAmB,EAAE,MAAM,GAAG,SAAS,EACvC,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,iBAAiB,CAAC,CAqE5B;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IACP,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CAChB,GACL,MAAM,CAkBR;AAED,4GAA4G;AAC5G,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,QAAQ,CAAA;CAAE,CAcrF;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,GAAG,OAAO,CAOlF"}
@@ -2,7 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.verifyAccessToken = verifyAccessToken;
4
4
  exports.issueLocalJwt = issueLocalJwt;
5
+ exports.parseRoleTaggedBearer = parseRoleTaggedBearer;
6
+ exports.credentialsConfigured = credentialsConfigured;
5
7
  const node_crypto_1 = require("node:crypto");
8
+ const rbac_js_1 = require("./rbac.js");
6
9
  function splitToken(token) {
7
10
  const parts = token.split(".");
8
11
  if (parts.length !== 3)
@@ -23,14 +26,54 @@ function secureEquals(left, right) {
23
26
  const b = Buffer.from(right);
24
27
  return a.length === b.length && (0, node_crypto_1.timingSafeEqual)(a, b);
25
28
  }
29
+ function parseScopeList(value) {
30
+ if (typeof value === "string") {
31
+ return value.split(/[\s,]+/).map((item) => item.trim()).filter(Boolean);
32
+ }
33
+ if (Array.isArray(value)) {
34
+ return value.filter((item) => typeof item === "string" && item.trim().length > 0);
35
+ }
36
+ return [];
37
+ }
38
+ function roleFromClaims(payload) {
39
+ if ((0, rbac_js_1.isTeamRole)(payload.role))
40
+ return payload.role;
41
+ const roles = Array.isArray(payload.roles) ? payload.roles : [];
42
+ const fromRoles = (0, rbac_js_1.roleFromScopes)(roles.filter((item) => typeof item === "string"));
43
+ if (fromRoles)
44
+ return fromRoles;
45
+ return (0, rbac_js_1.roleFromScopes)([...parseScopeList(payload.scope), ...parseScopeList(payload.scp)]);
46
+ }
47
+ function bearerCandidates(config) {
48
+ const seen = new Set();
49
+ const out = [];
50
+ for (const token of config.bearerTokens ?? []) {
51
+ if (token && !seen.has(token)) {
52
+ seen.add(token);
53
+ out.push(token);
54
+ }
55
+ }
56
+ for (const token of Object.keys(config.bearerRoleMap ?? {})) {
57
+ if (token && !seen.has(token)) {
58
+ seen.add(token);
59
+ out.push(token);
60
+ }
61
+ }
62
+ return out;
63
+ }
26
64
  async function verifyAccessToken(authorizationHeader, config) {
27
65
  if (!authorizationHeader?.startsWith("Bearer ")) {
28
66
  return { authenticated: false, reason: "missing bearer token" };
29
67
  }
30
68
  const token = authorizationHeader.slice(7).trim();
31
- for (const expected of config.bearerTokens ?? []) {
69
+ for (const expected of bearerCandidates(config)) {
32
70
  if (expected && secureEquals(token, expected)) {
33
- return { authenticated: true, subject: "bearer" };
71
+ const role = config.bearerRoleMap?.[expected];
72
+ return {
73
+ authenticated: true,
74
+ subject: "bearer",
75
+ ...(role ? { role } : {}),
76
+ };
34
77
  }
35
78
  }
36
79
  const jwt = splitToken(token);
@@ -54,6 +97,13 @@ async function verifyAccessToken(authorizationHeader, config) {
54
97
  }
55
98
  if (!verified)
56
99
  return { authenticated: false, reason: "signature rejected" };
100
+ const now = Math.floor(Date.now() / 1000);
101
+ if (typeof jwt.payload.exp === "number" && jwt.payload.exp < now) {
102
+ return { authenticated: false, reason: "token expired" };
103
+ }
104
+ if (typeof jwt.payload.nbf === "number" && jwt.payload.nbf > now) {
105
+ return { authenticated: false, reason: "token not yet valid" };
106
+ }
57
107
  if (config.issuer && jwt.payload.iss !== config.issuer) {
58
108
  return { authenticated: false, reason: "issuer rejected" };
59
109
  }
@@ -61,21 +111,30 @@ async function verifyAccessToken(authorizationHeader, config) {
61
111
  if (config.audience && !audience.includes(config.audience)) {
62
112
  return { authenticated: false, reason: "audience rejected" };
63
113
  }
64
- const scopes = typeof jwt.payload.scope === "string" ? jwt.payload.scope.split(/\s+/) : [];
114
+ const scopes = [...parseScopeList(jwt.payload.scope), ...parseScopeList(jwt.payload.scp)];
65
115
  if (config.requiredScope && !scopes.includes(config.requiredScope)) {
66
116
  return { authenticated: false, reason: "scope rejected" };
67
117
  }
68
- return { authenticated: true, subject: typeof jwt.payload.sub === "string" ? jwt.payload.sub : "jwt" };
118
+ const role = roleFromClaims(jwt.payload);
119
+ return {
120
+ authenticated: true,
121
+ subject: typeof jwt.payload.sub === "string" ? jwt.payload.sub : "jwt",
122
+ ...(role ? { role } : {}),
123
+ ...(scopes.length > 0 ? { scopes } : {}),
124
+ };
69
125
  }
70
126
  function issueLocalJwt(subject, secret, options = {}) {
71
127
  const encode = (value) => Buffer.from(JSON.stringify(value)).toString("base64url");
72
128
  const now = Math.floor(Date.now() / 1000);
129
+ const role = options.role;
130
+ const scope = options.scope ?? (role ? (0, rbac_js_1.defaultScopesForRole)(role) : undefined);
73
131
  const header = encode({ alg: "HS256", typ: "JWT" });
74
132
  const payload = encode({
75
133
  sub: subject,
76
134
  ...(options.issuer ? { iss: options.issuer } : {}),
77
135
  ...(options.audience ? { aud: options.audience } : {}),
78
- ...(options.scope ? { scope: options.scope } : {}),
136
+ ...(scope ? { scope } : {}),
137
+ ...(role ? { role } : {}),
79
138
  iat: now,
80
139
  exp: now + (options.ttlSeconds ?? 3600),
81
140
  });
@@ -83,4 +142,26 @@ function issueLocalJwt(subject, secret, options = {}) {
83
142
  const signature = (0, node_crypto_1.createHmac)("sha256", secret).update(data).digest("base64url");
84
143
  return `${data}.${signature}`;
85
144
  }
145
+ /** Parse `viewer:secret`, `admin:secret`, or `secret:admin` into token + role. Bare tokens have no role. */
146
+ function parseRoleTaggedBearer(raw) {
147
+ const trimmed = raw.trim();
148
+ const sep = trimmed.indexOf(":");
149
+ if (sep > 0) {
150
+ const left = trimmed.slice(0, sep).trim();
151
+ const right = trimmed.slice(sep + 1).trim();
152
+ if (right && (0, rbac_js_1.isTeamRole)(left.toLowerCase())) {
153
+ return { token: right, role: left.toLowerCase() };
154
+ }
155
+ if (left && (0, rbac_js_1.isTeamRole)(right.toLowerCase())) {
156
+ return { token: left, role: right.toLowerCase() };
157
+ }
158
+ }
159
+ return { token: trimmed };
160
+ }
161
+ function credentialsConfigured(config) {
162
+ return Boolean(config?.bearerTokens?.length ||
163
+ (config?.bearerRoleMap && Object.keys(config.bearerRoleMap).length > 0) ||
164
+ config?.jwtSecret ||
165
+ config?.publicKeyPem);
166
+ }
86
167
  //# sourceMappingURL=token-auth.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"token-auth.js","sourceRoot":"","sources":["../../src/security/token-auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"token-auth.js","sourceRoot":"","sources":["../../src/security/token-auth.ts"],"names":[],"mappings":"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"}
@@ -31,6 +31,10 @@ async function executeCommand(command, args, configPath) {
31
31
  if (command === "doctor") {
32
32
  const { buildDoctorReport, formatDoctorLegacyText } = require("./init");
33
33
  const data = buildDoctorReport(process.cwd());
34
+ if (data.team?.enabled) {
35
+ const { probeTeamDiagnosis } = await import("../team/diagnose.js");
36
+ data.team = await probeTeamDiagnosis(configPath);
37
+ }
34
38
  if (!data.ok) {
35
39
  process.exitCode = 1;
36
40
  }
@@ -59,9 +63,22 @@ async function executeCommand(command, args, configPath) {
59
63
  legacyText: `MCP removal complete`,
60
64
  };
61
65
  }
66
+ if (command === "team") {
67
+ return executeTeamCommand(args);
68
+ }
69
+ if (command === "diagnose") {
70
+ const data = (0, runtime_1.diagnoseRoutingResult)(configPath);
71
+ const { probeTeamDiagnosis } = await import("../team/diagnose.js");
72
+ data.team = await probeTeamDiagnosis(configPath);
73
+ return {
74
+ command: "diagnose",
75
+ data,
76
+ legacyText: (0, runtime_1.diagnoseRouting)(configPath, data),
77
+ };
78
+ }
62
79
  if (command === "mcp" && args[0] === "serve") {
63
80
  if (!args.includes("--http")) {
64
- console.log("Usage: graphflow mcp serve --http [--host <host>] [--port <port>] [--endpoint </path>] [--stateful] [--sse-only]");
81
+ console.log("Usage: graphflow mcp serve --http [--host <host>] [--port <port>] [--endpoint </path>] [--stateful] [--sse-only] [--http-token <role:token>] [--rbac]");
65
82
  process.exitCode = 1;
66
83
  return undefined;
67
84
  }
@@ -584,16 +601,27 @@ async function executeCommand(command, args, configPath) {
584
601
  // overwrite semantics. Team golden queries ride along and merge into
585
602
  // `.graphflow/team-golden.json` (dedupe by text, local-first order).
586
603
  const directionArg = args[1]?.trim().toLowerCase();
587
- if (directionArg !== "export" && directionArg !== "import") {
588
- console.log("Usage: graphflow skill sync <export|import> [--path <file>] [--force]");
604
+ if (directionArg !== "export" && directionArg !== "import" && directionArg !== "push" && directionArg !== "pull") {
605
+ console.log("Usage: graphflow skill sync <export|import|push|pull> [--path <file>] [--force]");
589
606
  console.log(" import MERGES per-skill-id: newer updatedAt wins; ties keep local; --force overwrites.");
590
607
  console.log(" team golden queries ride along -> .graphflow/team-golden.json (dedupe, local-first).");
608
+ console.log(" push/pull use graphPolicy.mcpEndpoint (mcp-http team server) and keep MERGE on pull.");
591
609
  process.exitCode = 1;
592
610
  return undefined;
593
611
  }
594
612
  const pathIdx = args.indexOf("--path");
595
613
  const customPath = pathIdx >= 0 ? args[pathIdx + 1]?.trim() : undefined;
596
614
  const force = args.includes("--force");
615
+ if (directionArg === "push" || directionArg === "pull") {
616
+ const data = await (0, runtime_1.syncSkillPackageRemote)(configPath, directionArg, { force });
617
+ return {
618
+ command: "skill-sync",
619
+ data,
620
+ legacyText: data.direction === "push"
621
+ ? `direction=push; path=${data.path}; skillCount=${data.skillCount ?? 0}; revision=${data.revision ?? 0}`
622
+ : `direction=pull; path=${data.path}; imported=${data.imported ?? 0}; skipped=${data.skipped ?? 0}; updated=${data.updated ?? 0}; revision=${data.revision ?? 0}`,
623
+ };
624
+ }
597
625
  const data = await (0, runtime_1.syncSkillPackageRuntime)(configPath, directionArg, customPath, { force });
598
626
  return {
599
627
  command: "skill-sync",
@@ -721,10 +749,12 @@ async function executeCommand(command, args, configPath) {
721
749
  }
722
750
  if (command === "route" && args[0] === "diagnose") {
723
751
  const data = (0, runtime_1.diagnoseRoutingResult)(configPath);
752
+ const { probeTeamDiagnosis } = await import("../team/diagnose.js");
753
+ data.team = await probeTeamDiagnosis(configPath);
724
754
  return {
725
755
  command: "route-diagnose",
726
756
  data,
727
- legacyText: (0, runtime_1.diagnoseRouting)(configPath),
757
+ legacyText: (0, runtime_1.diagnoseRouting)(configPath, data),
728
758
  };
729
759
  }
730
760
  if (command === "artifact" && args[0] === "export") {
@@ -1109,6 +1139,51 @@ main().catch((error) => {
1109
1139
  console.error("GraphFlow execution failed:", error);
1110
1140
  process.exitCode = 1;
1111
1141
  });
1142
+ async function executeTeamCommand(args) {
1143
+ const sub = args[0]?.trim();
1144
+ if (sub === "serve") {
1145
+ const { startTeamServerFromArgv } = await import("../team/ops.js");
1146
+ const started = await startTeamServerFromArgv(args.slice(1));
1147
+ const { httpServer: _httpServer, close: _close, ...data } = started;
1148
+ return {
1149
+ command: "team-serve",
1150
+ data,
1151
+ legacyText: `GraphFlow team memory listening on ${data.url} ` +
1152
+ `(auth=${data.requireAuth ? "required" : "optional"}; rbac=on; store=${data.storeRoot})`,
1153
+ };
1154
+ }
1155
+ if (sub === "issue-token") {
1156
+ const { issueTeamTokenFromArgv } = await import("../team/ops.js");
1157
+ const data = issueTeamTokenFromArgv(args.slice(1));
1158
+ return {
1159
+ command: "team-issue-token",
1160
+ data,
1161
+ legacyText: `subject=${data.subject}; role=${data.role}; ttl=${data.ttlSeconds}; token=${data.token}`,
1162
+ };
1163
+ }
1164
+ if (sub === "example-config") {
1165
+ const { buildTeamClientExampleConfig } = await import("../team/ops.js");
1166
+ const endpoint = (0, output_1.readCliFlagValue)(args, "--endpoint");
1167
+ const tenant = (0, output_1.readCliFlagValue)(args, "--tenant");
1168
+ const apiKey = (0, output_1.readCliFlagValue)(args, "--api-key");
1169
+ const data = buildTeamClientExampleConfig({
1170
+ ...(endpoint ? { endpoint } : {}),
1171
+ ...(tenant ? { tenant } : {}),
1172
+ ...(apiKey ? { apiKey } : {}),
1173
+ });
1174
+ return {
1175
+ command: "team-example-config",
1176
+ data,
1177
+ legacyText: JSON.stringify(data, null, 2),
1178
+ };
1179
+ }
1180
+ console.log("Usage: graphflow team <serve|issue-token|example-config>");
1181
+ console.log(" team serve [--host <host>] [--port <port>] [--store <dir>] [--http-token <role:token>] [--http-jwt-secret <secret>] [--allow-tenant <id>]");
1182
+ console.log(" team issue-token --subject <id> --role <viewer|contributor|admin> [--secret <jwt>] [--ttl <seconds>]");
1183
+ console.log(" team example-config [--endpoint <url>] [--tenant <id>]");
1184
+ process.exitCode = 1;
1185
+ return undefined;
1186
+ }
1112
1187
  function buildInsightLegacyText(data) {
1113
1188
  const lines = [];
1114
1189
  lines.push("=== Six Thinking Hats Insight ===");