agent-authority 0.1.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/CHANGELOG.md +118 -0
- package/LICENSE +21 -0
- package/QUICKSTART.md +91 -0
- package/README.md +553 -0
- package/dist/a2a.d.ts +73 -0
- package/dist/a2a.d.ts.map +1 -0
- package/dist/a2a.js +117 -0
- package/dist/a2a.js.map +1 -0
- package/dist/audit.d.ts +12 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +52 -0
- package/dist/audit.js.map +1 -0
- package/dist/behalf.d.ts +173 -0
- package/dist/behalf.d.ts.map +1 -0
- package/dist/behalf.js +475 -0
- package/dist/behalf.js.map +1 -0
- package/dist/capability.d.ts +56 -0
- package/dist/capability.d.ts.map +1 -0
- package/dist/capability.js +176 -0
- package/dist/capability.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +273 -0
- package/dist/cli.js.map +1 -0
- package/dist/control-plane.d.ts +57 -0
- package/dist/control-plane.d.ts.map +1 -0
- package/dist/control-plane.js +332 -0
- package/dist/control-plane.js.map +1 -0
- package/dist/crypto.d.ts +68 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +105 -0
- package/dist/crypto.js.map +1 -0
- package/dist/errors.d.ts +25 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +40 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +34 -0
- package/dist/index.js.map +1 -0
- package/dist/lint.d.ts +17 -0
- package/dist/lint.d.ts.map +1 -0
- package/dist/lint.js +75 -0
- package/dist/lint.js.map +1 -0
- package/dist/mandate.d.ts +99 -0
- package/dist/mandate.d.ts.map +1 -0
- package/dist/mandate.js +141 -0
- package/dist/mandate.js.map +1 -0
- package/dist/mcp-server.d.ts +26 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +111 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/mcp.d.ts +63 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +123 -0
- package/dist/mcp.js.map +1 -0
- package/dist/persist.d.ts +51 -0
- package/dist/persist.d.ts.map +1 -0
- package/dist/persist.js +150 -0
- package/dist/persist.js.map +1 -0
- package/dist/quickstart.d.ts +63 -0
- package/dist/quickstart.d.ts.map +1 -0
- package/dist/quickstart.js +171 -0
- package/dist/quickstart.js.map +1 -0
- package/dist/remote.d.ts +93 -0
- package/dist/remote.d.ts.map +1 -0
- package/dist/remote.js +120 -0
- package/dist/remote.js.map +1 -0
- package/dist/seal.d.ts +12 -0
- package/dist/seal.d.ts.map +1 -0
- package/dist/seal.js +96 -0
- package/dist/seal.js.map +1 -0
- package/dist/store.d.ts +119 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +139 -0
- package/dist/store.js.map +1 -0
- package/dist/types.d.ts +173 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +17 -0
- package/dist/types.js.map +1 -0
- package/llms.txt +106 -0
- package/package.json +107 -0
- package/schemas/capability.schema.json +14 -0
- package/schemas/mandate.schema.json +68 -0
- package/vectors/mandate-vector.json +63 -0
package/dist/mcp.d.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Behalf } from "./behalf.js";
|
|
2
|
+
import { Mandate } from "./mandate.js";
|
|
3
|
+
/**
|
|
4
|
+
* MCP middleware — the adoption killer. Wrap any MCP-style tool server once and
|
|
5
|
+
* every tool call is automatically checked against the caller's mandate: scope,
|
|
6
|
+
* limits, expiry, revocation, and audit, with no per-tool code.
|
|
7
|
+
*/
|
|
8
|
+
/** Minimal structural view of an MCP-ish tool server. */
|
|
9
|
+
export interface ToolServerLike {
|
|
10
|
+
callTool(name: string, args: Record<string, unknown>, ctx?: CallContext): Promise<unknown>;
|
|
11
|
+
}
|
|
12
|
+
/** Per-call context; the caller's mandate rides here. */
|
|
13
|
+
export interface CallContext {
|
|
14
|
+
mandate?: Mandate;
|
|
15
|
+
[k: string]: unknown;
|
|
16
|
+
}
|
|
17
|
+
/** A capability requirement: a fixed string or one derived from call args. */
|
|
18
|
+
export type CapabilityRule = string | ((args: Record<string, unknown>) => string);
|
|
19
|
+
export interface WithBehalfOptions {
|
|
20
|
+
/** Map each tool name to the capability it requires. */
|
|
21
|
+
policy: Record<string, CapabilityRule>;
|
|
22
|
+
/** What to do on a denied call. */
|
|
23
|
+
onDenied?: "throw" | "prompt";
|
|
24
|
+
/**
|
|
25
|
+
* Just-in-time consent callback (used when onDenied === "prompt"). Return true
|
|
26
|
+
* to allow the call through despite the missing authority.
|
|
27
|
+
*/
|
|
28
|
+
onPrompt?: (info: {
|
|
29
|
+
tool: string;
|
|
30
|
+
capability: string;
|
|
31
|
+
mandate?: Mandate;
|
|
32
|
+
}) => Promise<boolean>;
|
|
33
|
+
/** Engine to use (defaults to the shared Behalf default). */
|
|
34
|
+
engine?: Behalf;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Wrap a tool server so every call is authorized first.
|
|
38
|
+
*
|
|
39
|
+
* const server = withBehalf(myMcpServer, {
|
|
40
|
+
* policy: {
|
|
41
|
+
* send_email: "write:email",
|
|
42
|
+
* read_calendar: "read:calendar",
|
|
43
|
+
* transfer_funds: (args) => `spend:usd<=${args.amount}`,
|
|
44
|
+
* },
|
|
45
|
+
* onDenied: "throw",
|
|
46
|
+
* });
|
|
47
|
+
*/
|
|
48
|
+
export declare function withBehalf(server: ToolServerLike, opts: WithBehalfOptions): ToolServerLike;
|
|
49
|
+
/** Symmetric binding for agent-to-agent (A2A) calls — same enforcement shape. */
|
|
50
|
+
export declare function withBehalfA2A(server: ToolServerLike, opts: WithBehalfOptions): ToolServerLike;
|
|
51
|
+
/** A tool definition for the agent-legibility layer. */
|
|
52
|
+
export interface ToolDefinition {
|
|
53
|
+
name: string;
|
|
54
|
+
description: string;
|
|
55
|
+
inputSchema: Record<string, unknown>;
|
|
56
|
+
handler: (args: Record<string, unknown>, ctx?: CallContext) => Promise<unknown>;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* The three discovery tools that let any agent obtain and use authority
|
|
60
|
+
* natively: `request_mandate`, `present_mandate`, and `check_authority`.
|
|
61
|
+
*/
|
|
62
|
+
export declare function behalfMcpTools(engine?: Behalf): ToolDefinition[];
|
|
63
|
+
//# sourceMappingURL=mcp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC;;;;GAIG;AAEH,yDAAyD;AACzD,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC5F;AAED,yDAAyD;AACzD,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CACtB;AAED,8EAA8E;AAC9E,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC,CAAC;AAElF,MAAM,WAAW,iBAAiB;IAChC,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACvC,mCAAmC;IACnC,QAAQ,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC9B;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/F,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,iBAAiB,GAAG,cAAc,CAiC1F;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,iBAAiB,GAAG,cAAc,CAE7F;AAED,wDAAwD;AACxD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACjF;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,GAAE,MAAuB,GAAG,cAAc,EAAE,CAkEhF"}
|
package/dist/mcp.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { Behalf } from "./behalf.js";
|
|
2
|
+
import { AuthorizationError } from "./errors.js";
|
|
3
|
+
/**
|
|
4
|
+
* Wrap a tool server so every call is authorized first.
|
|
5
|
+
*
|
|
6
|
+
* const server = withBehalf(myMcpServer, {
|
|
7
|
+
* policy: {
|
|
8
|
+
* send_email: "write:email",
|
|
9
|
+
* read_calendar: "read:calendar",
|
|
10
|
+
* transfer_funds: (args) => `spend:usd<=${args.amount}`,
|
|
11
|
+
* },
|
|
12
|
+
* onDenied: "throw",
|
|
13
|
+
* });
|
|
14
|
+
*/
|
|
15
|
+
export function withBehalf(server, opts) {
|
|
16
|
+
return {
|
|
17
|
+
async callTool(name, args, ctx) {
|
|
18
|
+
const rule = opts.policy[name];
|
|
19
|
+
// Tools without a policy entry pass through unguarded (explicit opt-in).
|
|
20
|
+
if (rule === undefined)
|
|
21
|
+
return server.callTool(name, args, ctx);
|
|
22
|
+
const capability = typeof rule === "function" ? rule(args) : rule;
|
|
23
|
+
const mandate = ctx?.mandate;
|
|
24
|
+
let denied;
|
|
25
|
+
if (!mandate) {
|
|
26
|
+
denied = "no mandate presented";
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
try {
|
|
30
|
+
await mandate.authorize(capability);
|
|
31
|
+
}
|
|
32
|
+
catch (e) {
|
|
33
|
+
denied = e instanceof AuthorizationError ? e.reason : String(e);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (denied) {
|
|
37
|
+
if (opts.onDenied === "prompt" && opts.onPrompt) {
|
|
38
|
+
const allow = await opts.onPrompt({ tool: name, capability, mandate });
|
|
39
|
+
if (!allow)
|
|
40
|
+
throw new AuthorizationError(capability, `${denied} (consent declined)`);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
throw new AuthorizationError(capability, denied);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return server.callTool(name, args, ctx);
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/** Symmetric binding for agent-to-agent (A2A) calls — same enforcement shape. */
|
|
51
|
+
export function withBehalfA2A(server, opts) {
|
|
52
|
+
return withBehalf(server, opts);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The three discovery tools that let any agent obtain and use authority
|
|
56
|
+
* natively: `request_mandate`, `present_mandate`, and `check_authority`.
|
|
57
|
+
*/
|
|
58
|
+
export function behalfMcpTools(engine = Behalf.default) {
|
|
59
|
+
return [
|
|
60
|
+
{
|
|
61
|
+
name: "request_mandate",
|
|
62
|
+
description: "Request a scoped, time-bound mandate authorizing an agent to act on a principal's behalf. " +
|
|
63
|
+
"Returns `mandate` (a HOLDER credential containing the delegation key — treat it as a secret) " +
|
|
64
|
+
"and `publicToken` (safe to share for inspection/presentation).",
|
|
65
|
+
inputSchema: {
|
|
66
|
+
type: "object",
|
|
67
|
+
required: ["principal", "agent", "can", "expiresIn"],
|
|
68
|
+
properties: {
|
|
69
|
+
principal: { type: "string" },
|
|
70
|
+
agent: { type: "string" },
|
|
71
|
+
can: { type: "array", items: { type: "string" } },
|
|
72
|
+
expiresIn: { type: "string", description: 'e.g. "1h", "10m"' },
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
handler: async (args) => {
|
|
76
|
+
const m = engine.grant({
|
|
77
|
+
principal: String(args.principal),
|
|
78
|
+
agent: String(args.agent),
|
|
79
|
+
can: args.can,
|
|
80
|
+
expiresIn: String(args.expiresIn),
|
|
81
|
+
});
|
|
82
|
+
// The holder credential includes the delegation key — without it the
|
|
83
|
+
// requester could never authorize (proof of possession would fail).
|
|
84
|
+
return { mandate: m.serializeWithKey(), publicToken: m.serialize(), id: m.id };
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: "present_mandate",
|
|
89
|
+
description: "Validate a serialized mandate and return its decoded scope, principal, and expiry.",
|
|
90
|
+
inputSchema: {
|
|
91
|
+
type: "object",
|
|
92
|
+
required: ["mandate"],
|
|
93
|
+
properties: { mandate: { type: "string" } },
|
|
94
|
+
},
|
|
95
|
+
handler: async (args) => {
|
|
96
|
+
const m = engine.import(String(args.mandate));
|
|
97
|
+
engine.verifySignature(m.token);
|
|
98
|
+
return {
|
|
99
|
+
valid: true,
|
|
100
|
+
id: m.id,
|
|
101
|
+
principal: m.principal,
|
|
102
|
+
agent: m.agent,
|
|
103
|
+
expiresAt: m.expiresAt,
|
|
104
|
+
chain: m.chain,
|
|
105
|
+
};
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
name: "check_authority",
|
|
110
|
+
description: "Advisory check of whether a mandate's scope would allow an action (does not perform it and does not prove possession).",
|
|
111
|
+
inputSchema: {
|
|
112
|
+
type: "object",
|
|
113
|
+
required: ["mandate", "action"],
|
|
114
|
+
properties: { mandate: { type: "string" }, action: { type: "string" } },
|
|
115
|
+
},
|
|
116
|
+
handler: async (args) => {
|
|
117
|
+
const m = engine.import(String(args.mandate));
|
|
118
|
+
return engine.inspect(m.token, String(args.action));
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
];
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=mcp.js.map
|
package/dist/mcp.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { AuditEntry, AuditFields, ConsentRecord } from "./types.js";
|
|
2
|
+
import type { AuditStore, ConsentStore, PolicyStore, RateStore, RevocationStore } from "./store.js";
|
|
3
|
+
/** Revocation list persisted as a JSON array of ids. */
|
|
4
|
+
export declare class FileRevocationStore implements RevocationStore {
|
|
5
|
+
private readonly path;
|
|
6
|
+
private readonly revoked;
|
|
7
|
+
constructor(path: string);
|
|
8
|
+
revoke(id: string): void;
|
|
9
|
+
isRevoked(id: string): boolean;
|
|
10
|
+
}
|
|
11
|
+
/** Append-only audit log persisted as JSON Lines (one entry per line). */
|
|
12
|
+
export declare class FileAuditStore implements AuditStore {
|
|
13
|
+
private readonly path;
|
|
14
|
+
/** Last sealed entry, tracked in memory so writes stay O(1) (no full re-read). */
|
|
15
|
+
private last;
|
|
16
|
+
constructor(path: string);
|
|
17
|
+
record(fields: AuditFields): AuditEntry;
|
|
18
|
+
append(entry: AuditEntry): void;
|
|
19
|
+
all(): AuditEntry[];
|
|
20
|
+
forMandate(mandateId: string): AuditEntry[];
|
|
21
|
+
forIssuer(issuer: string): AuditEntry[];
|
|
22
|
+
}
|
|
23
|
+
/** Consent records persisted as a JSON object keyed by id. */
|
|
24
|
+
export declare class FileConsentStore implements ConsentStore {
|
|
25
|
+
private readonly path;
|
|
26
|
+
private readonly records;
|
|
27
|
+
constructor(path: string);
|
|
28
|
+
private flush;
|
|
29
|
+
put(record: ConsentRecord): void;
|
|
30
|
+
get(id: string): ConsentRecord | undefined;
|
|
31
|
+
list(): ConsentRecord[];
|
|
32
|
+
}
|
|
33
|
+
/** Named policies persisted as a JSON object keyed by name. */
|
|
34
|
+
export declare class FilePolicyStore implements PolicyStore {
|
|
35
|
+
private readonly path;
|
|
36
|
+
private readonly policies;
|
|
37
|
+
constructor(path: string);
|
|
38
|
+
private flush;
|
|
39
|
+
set(name: string, policy: unknown): void;
|
|
40
|
+
get(name: string): unknown;
|
|
41
|
+
has(name: string): boolean;
|
|
42
|
+
}
|
|
43
|
+
/** Rate-limit windows persisted as a JSON object of key → hit timestamps. */
|
|
44
|
+
export declare class FileRateStore implements RateStore {
|
|
45
|
+
private readonly path;
|
|
46
|
+
private readonly hits;
|
|
47
|
+
constructor(path: string);
|
|
48
|
+
private flush;
|
|
49
|
+
hit(key: string, windowMs: number, limit: number, now: number): boolean;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=persist.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persist.d.ts","sourceRoot":"","sources":["../src/persist.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAcpG,wDAAwD;AACxD,qBAAa,mBAAoB,YAAW,eAAe;IAG7C,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;gBAET,IAAI,EAAE,MAAM;IAOzC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAKxB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;CAG/B;AAED,0EAA0E;AAC1E,qBAAa,cAAe,YAAW,UAAU;IAInC,OAAO,CAAC,QAAQ,CAAC,IAAI;IAHjC,kFAAkF;IAClF,OAAO,CAAC,IAAI,CAA2B;gBAEV,IAAI,EAAE,MAAM;IAUzC,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,UAAU;IAMvC,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAK/B,GAAG,IAAI,UAAU,EAAE;IAQnB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,EAAE;IAI3C,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE;CAGxC;AAED,8DAA8D;AAC9D,qBAAa,gBAAiB,YAAW,YAAY;IAGvC,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA6B;gBAExB,IAAI,EAAE,MAAM;IAOzC,OAAO,CAAC,KAAK;IAIb,GAAG,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;IAIhC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAG1C,IAAI,IAAI,aAAa,EAAE;CAGxB;AAED,+DAA+D;AAC/D,qBAAa,eAAgB,YAAW,WAAW;IAGrC,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuB;gBAEnB,IAAI,EAAE,MAAM;IAOzC,OAAO,CAAC,KAAK;IAIb,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;IAIxC,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAG1B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;CAG3B;AAED,6EAA6E;AAC7E,qBAAa,aAAc,YAAW,SAAS;IAGjC,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAwB;gBAEhB,IAAI,EAAE,MAAM;IAOzC,OAAO,CAAC,KAAK;IAIb,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO;CAYxE"}
|
package/dist/persist.js
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, appendFileSync, existsSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { dirname } from "node:path";
|
|
3
|
+
import { seal } from "./audit.js";
|
|
4
|
+
/**
|
|
5
|
+
* Local-first, file-backed stores. These keep revocation and audit state across
|
|
6
|
+
* process restarts with zero infrastructure — the "offline-verifiable, only
|
|
7
|
+
* revocation needs a check" model, persisted to disk. Swap in a networked store
|
|
8
|
+
* for distributed revocation propagation (the Phase-2 control plane).
|
|
9
|
+
*/
|
|
10
|
+
function ensureDir(file) {
|
|
11
|
+
const dir = dirname(file);
|
|
12
|
+
if (dir && !existsSync(dir))
|
|
13
|
+
mkdirSync(dir, { recursive: true });
|
|
14
|
+
}
|
|
15
|
+
/** Revocation list persisted as a JSON array of ids. */
|
|
16
|
+
export class FileRevocationStore {
|
|
17
|
+
path;
|
|
18
|
+
revoked;
|
|
19
|
+
constructor(path) {
|
|
20
|
+
this.path = path;
|
|
21
|
+
ensureDir(path);
|
|
22
|
+
this.revoked = existsSync(path)
|
|
23
|
+
? new Set(JSON.parse(readFileSync(path, "utf8")))
|
|
24
|
+
: new Set();
|
|
25
|
+
}
|
|
26
|
+
revoke(id) {
|
|
27
|
+
this.revoked.add(id);
|
|
28
|
+
writeFileSync(this.path, JSON.stringify([...this.revoked]), "utf8");
|
|
29
|
+
}
|
|
30
|
+
isRevoked(id) {
|
|
31
|
+
return this.revoked.has(id);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/** Append-only audit log persisted as JSON Lines (one entry per line). */
|
|
35
|
+
export class FileAuditStore {
|
|
36
|
+
path;
|
|
37
|
+
/** Last sealed entry, tracked in memory so writes stay O(1) (no full re-read). */
|
|
38
|
+
last = null;
|
|
39
|
+
constructor(path) {
|
|
40
|
+
this.path = path;
|
|
41
|
+
ensureDir(path);
|
|
42
|
+
if (existsSync(path)) {
|
|
43
|
+
const entries = this.all();
|
|
44
|
+
this.last = entries[entries.length - 1] ?? null;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
writeFileSync(path, "", "utf8");
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
record(fields) {
|
|
51
|
+
const entry = seal(this.last, fields);
|
|
52
|
+
this.append(entry);
|
|
53
|
+
return entry;
|
|
54
|
+
}
|
|
55
|
+
append(entry) {
|
|
56
|
+
appendFileSync(this.path, JSON.stringify(entry) + "\n", "utf8");
|
|
57
|
+
this.last = entry;
|
|
58
|
+
}
|
|
59
|
+
all() {
|
|
60
|
+
const raw = readFileSync(this.path, "utf8");
|
|
61
|
+
return raw
|
|
62
|
+
.split("\n")
|
|
63
|
+
.filter((l) => l.length > 0)
|
|
64
|
+
.map((l) => JSON.parse(l));
|
|
65
|
+
}
|
|
66
|
+
forMandate(mandateId) {
|
|
67
|
+
return this.all().filter((e) => e.chain.includes(mandateId));
|
|
68
|
+
}
|
|
69
|
+
forIssuer(issuer) {
|
|
70
|
+
return this.all().filter((e) => e.issuer === issuer);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/** Consent records persisted as a JSON object keyed by id. */
|
|
74
|
+
export class FileConsentStore {
|
|
75
|
+
path;
|
|
76
|
+
records;
|
|
77
|
+
constructor(path) {
|
|
78
|
+
this.path = path;
|
|
79
|
+
ensureDir(path);
|
|
80
|
+
this.records = existsSync(path)
|
|
81
|
+
? new Map(Object.entries(JSON.parse(readFileSync(path, "utf8"))))
|
|
82
|
+
: new Map();
|
|
83
|
+
}
|
|
84
|
+
flush() {
|
|
85
|
+
writeFileSync(this.path, JSON.stringify(Object.fromEntries(this.records)), "utf8");
|
|
86
|
+
}
|
|
87
|
+
put(record) {
|
|
88
|
+
this.records.set(record.id, record);
|
|
89
|
+
this.flush();
|
|
90
|
+
}
|
|
91
|
+
get(id) {
|
|
92
|
+
return this.records.get(id);
|
|
93
|
+
}
|
|
94
|
+
list() {
|
|
95
|
+
return [...this.records.values()];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/** Named policies persisted as a JSON object keyed by name. */
|
|
99
|
+
export class FilePolicyStore {
|
|
100
|
+
path;
|
|
101
|
+
policies;
|
|
102
|
+
constructor(path) {
|
|
103
|
+
this.path = path;
|
|
104
|
+
ensureDir(path);
|
|
105
|
+
this.policies = existsSync(path)
|
|
106
|
+
? new Map(Object.entries(JSON.parse(readFileSync(path, "utf8"))))
|
|
107
|
+
: new Map();
|
|
108
|
+
}
|
|
109
|
+
flush() {
|
|
110
|
+
writeFileSync(this.path, JSON.stringify(Object.fromEntries(this.policies)), "utf8");
|
|
111
|
+
}
|
|
112
|
+
set(name, policy) {
|
|
113
|
+
this.policies.set(name, policy);
|
|
114
|
+
this.flush();
|
|
115
|
+
}
|
|
116
|
+
get(name) {
|
|
117
|
+
return this.policies.get(name);
|
|
118
|
+
}
|
|
119
|
+
has(name) {
|
|
120
|
+
return this.policies.has(name);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/** Rate-limit windows persisted as a JSON object of key → hit timestamps. */
|
|
124
|
+
export class FileRateStore {
|
|
125
|
+
path;
|
|
126
|
+
hits;
|
|
127
|
+
constructor(path) {
|
|
128
|
+
this.path = path;
|
|
129
|
+
ensureDir(path);
|
|
130
|
+
this.hits = existsSync(path)
|
|
131
|
+
? new Map(Object.entries(JSON.parse(readFileSync(path, "utf8"))))
|
|
132
|
+
: new Map();
|
|
133
|
+
}
|
|
134
|
+
flush() {
|
|
135
|
+
writeFileSync(this.path, JSON.stringify(Object.fromEntries(this.hits)), "utf8");
|
|
136
|
+
}
|
|
137
|
+
hit(key, windowMs, limit, now) {
|
|
138
|
+
const recent = (this.hits.get(key) ?? []).filter((t) => now - t < windowMs);
|
|
139
|
+
if (recent.length + 1 > limit) {
|
|
140
|
+
this.hits.set(key, recent);
|
|
141
|
+
this.flush();
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
recent.push(now);
|
|
145
|
+
this.hits.set(key, recent);
|
|
146
|
+
this.flush();
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=persist.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persist.js","sourceRoot":"","sources":["../src/persist.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dynamic, per-surface quickstart generator.
|
|
3
|
+
*
|
|
4
|
+
* Wiring Behalf into an AI surface is one of two shapes: an MCP server entry
|
|
5
|
+
* (Claude Code/Desktop, Cursor, Copilot/VS Code, Windsurf, Gemini CLI, OpenAI
|
|
6
|
+
* Agents, ...) or a function-calling tool schema (OpenAI / Gemini APIs). Rather
|
|
7
|
+
* than hand-write a doc per tool, surfaces are described as DATA and rendered on
|
|
8
|
+
* demand — so the three mains (Claude Code, Cursor, Copilot), Gemini and GPT are
|
|
9
|
+
* built in, and ANY other AI is configurable via a custom surface or the generic
|
|
10
|
+
* MCP template.
|
|
11
|
+
*/
|
|
12
|
+
export interface Surface {
|
|
13
|
+
id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
kind: "mcp" | "tool-api";
|
|
16
|
+
/** mcp: where the config lives. */
|
|
17
|
+
configFile?: string;
|
|
18
|
+
/** mcp: top-level key — usually "mcpServers", VS Code uses "servers". */
|
|
19
|
+
configKey?: string;
|
|
20
|
+
/** mcp: include `"type": "stdio"` in the entry (VS Code, some clients). */
|
|
21
|
+
stdioType?: boolean;
|
|
22
|
+
/** mcp: optional one-liner CLI to register, with {name}/{command}/{args}. */
|
|
23
|
+
cli?: string;
|
|
24
|
+
/** tool-api: which function-calling dialect to emit. */
|
|
25
|
+
api?: "openai" | "gemini";
|
|
26
|
+
/** Freeform guidance shown with the snippet. */
|
|
27
|
+
notes?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface QuickstartOptions {
|
|
30
|
+
/** Server name shown in the client config. Default "agent-authority". */
|
|
31
|
+
name?: string;
|
|
32
|
+
/** Command to launch the MCP server. Default "npx". */
|
|
33
|
+
command?: string;
|
|
34
|
+
/** Args for the command. Default ["-y", "agent-authority-mcp"]. */
|
|
35
|
+
args?: string[];
|
|
36
|
+
/** Extra environment variables for the server entry. */
|
|
37
|
+
env?: Record<string, string>;
|
|
38
|
+
}
|
|
39
|
+
export interface Quickstart {
|
|
40
|
+
surface: string;
|
|
41
|
+
name: string;
|
|
42
|
+
kind: Surface["kind"];
|
|
43
|
+
instructions: string;
|
|
44
|
+
/** The config/snippet to paste (JSON or code). */
|
|
45
|
+
snippet: string;
|
|
46
|
+
/** Optional one-line CLI alternative (MCP surfaces). */
|
|
47
|
+
cli?: string;
|
|
48
|
+
notes?: string;
|
|
49
|
+
/** A ready-to-print text rendering of everything above. */
|
|
50
|
+
text: string;
|
|
51
|
+
}
|
|
52
|
+
/** Built-in surfaces. Extend at runtime by passing your own {@link Surface}. */
|
|
53
|
+
export declare const DEFAULT_SURFACES: Surface[];
|
|
54
|
+
/** Look up a built-in (or supplied) surface by id. */
|
|
55
|
+
export declare function findSurface(id: string, extra?: Surface[]): Surface | undefined;
|
|
56
|
+
/** List all surface ids/names (built-in plus any supplied). */
|
|
57
|
+
export declare function listSurfaces(extra?: Surface[]): {
|
|
58
|
+
id: string;
|
|
59
|
+
name: string;
|
|
60
|
+
}[];
|
|
61
|
+
/** Render a ready-to-paste quickstart for a surface. */
|
|
62
|
+
export declare function generateQuickstart(surface: Surface, opts?: QuickstartOptions): Quickstart;
|
|
63
|
+
//# sourceMappingURL=quickstart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quickstart.d.ts","sourceRoot":"","sources":["../src/quickstart.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,KAAK,GAAG,UAAU,CAAC;IACzB,mCAAmC;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,6EAA6E;IAC7E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,GAAG,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,yEAAyE;IACzE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,wDAAwD;IACxD,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,wDAAwD;IACxD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;CACd;AAED,gFAAgF;AAChF,eAAO,MAAM,gBAAgB,EAAE,OAAO,EA8ErC,CAAC;AAQF,sDAAsD;AACtD,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,GAAE,OAAO,EAAO,GAAG,OAAO,GAAG,SAAS,CAElF;AAED,+DAA+D;AAC/D,wBAAgB,YAAY,CAAC,KAAK,GAAE,OAAO,EAAO,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,CAElF;AAED,wDAAwD;AACxD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,GAAE,iBAAsB,GAAG,UAAU,CAY7F"}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { behalfMcpTools } from "./mcp.js";
|
|
2
|
+
/** Built-in surfaces. Extend at runtime by passing your own {@link Surface}. */
|
|
3
|
+
export const DEFAULT_SURFACES = [
|
|
4
|
+
{
|
|
5
|
+
id: "claude-code",
|
|
6
|
+
name: "Claude Code",
|
|
7
|
+
kind: "mcp",
|
|
8
|
+
configFile: ".mcp.json (project) or ~/.claude.json",
|
|
9
|
+
configKey: "mcpServers",
|
|
10
|
+
cli: "claude mcp add {name} -- {command} {args}",
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
id: "claude-desktop",
|
|
14
|
+
name: "Claude Desktop",
|
|
15
|
+
kind: "mcp",
|
|
16
|
+
configFile: "~/Library/Application Support/Claude/claude_desktop_config.json (macOS) / %APPDATA%\\Claude\\claude_desktop_config.json (Windows)",
|
|
17
|
+
configKey: "mcpServers",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
id: "cursor",
|
|
21
|
+
name: "Cursor",
|
|
22
|
+
kind: "mcp",
|
|
23
|
+
configFile: ".cursor/mcp.json (project) or ~/.cursor/mcp.json (global)",
|
|
24
|
+
configKey: "mcpServers",
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: "copilot",
|
|
28
|
+
name: "GitHub Copilot (VS Code)",
|
|
29
|
+
kind: "mcp",
|
|
30
|
+
configFile: ".vscode/mcp.json",
|
|
31
|
+
configKey: "servers",
|
|
32
|
+
stdioType: true,
|
|
33
|
+
notes: "Enable agent mode; VS Code uses the `servers` key and a `type` field.",
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: "windsurf",
|
|
37
|
+
name: "Windsurf",
|
|
38
|
+
kind: "mcp",
|
|
39
|
+
configFile: "~/.codeium/windsurf/mcp_config.json",
|
|
40
|
+
configKey: "mcpServers",
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: "gemini-cli",
|
|
44
|
+
name: "Gemini CLI",
|
|
45
|
+
kind: "mcp",
|
|
46
|
+
configFile: "~/.gemini/settings.json",
|
|
47
|
+
configKey: "mcpServers",
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
id: "openai-agents",
|
|
51
|
+
name: "OpenAI Agents SDK",
|
|
52
|
+
kind: "mcp",
|
|
53
|
+
configFile: "your agent setup (MCP stdio server)",
|
|
54
|
+
configKey: "mcpServers",
|
|
55
|
+
notes: "The Agents SDK launches MCP servers over stdio; use this command/args.",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: "gpt",
|
|
59
|
+
name: "GPT / OpenAI API (function calling)",
|
|
60
|
+
kind: "tool-api",
|
|
61
|
+
api: "openai",
|
|
62
|
+
notes: "Pass these as `tools`. Have the model call `check_authority` before any sensitive action.",
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
id: "gemini",
|
|
66
|
+
name: "Gemini API (function calling)",
|
|
67
|
+
kind: "tool-api",
|
|
68
|
+
api: "gemini",
|
|
69
|
+
notes: "Pass these as `functionDeclarations` in a `tools` entry.",
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
id: "generic-mcp",
|
|
73
|
+
name: "Any MCP client (generic)",
|
|
74
|
+
kind: "mcp",
|
|
75
|
+
configFile: "your MCP client's config",
|
|
76
|
+
configKey: "mcpServers",
|
|
77
|
+
notes: "Most MCP clients accept a `mcpServers` map of stdio servers.",
|
|
78
|
+
},
|
|
79
|
+
];
|
|
80
|
+
const DEFAULTS = {
|
|
81
|
+
name: "agent-authority",
|
|
82
|
+
command: "npx",
|
|
83
|
+
args: ["-y", "agent-authority-mcp"],
|
|
84
|
+
};
|
|
85
|
+
/** Look up a built-in (or supplied) surface by id. */
|
|
86
|
+
export function findSurface(id, extra = []) {
|
|
87
|
+
return [...DEFAULT_SURFACES, ...extra].find((s) => s.id === id);
|
|
88
|
+
}
|
|
89
|
+
/** List all surface ids/names (built-in plus any supplied). */
|
|
90
|
+
export function listSurfaces(extra = []) {
|
|
91
|
+
return [...DEFAULT_SURFACES, ...extra].map((s) => ({ id: s.id, name: s.name }));
|
|
92
|
+
}
|
|
93
|
+
/** Render a ready-to-paste quickstart for a surface. */
|
|
94
|
+
export function generateQuickstart(surface, opts = {}) {
|
|
95
|
+
const o = {
|
|
96
|
+
name: opts.name ?? DEFAULTS.name,
|
|
97
|
+
command: opts.command ?? DEFAULTS.command,
|
|
98
|
+
args: opts.args ?? DEFAULTS.args,
|
|
99
|
+
env: opts.env,
|
|
100
|
+
};
|
|
101
|
+
if (surface.kind === "tool-api") {
|
|
102
|
+
return renderToolApi(surface, o);
|
|
103
|
+
}
|
|
104
|
+
return renderMcp(surface, o);
|
|
105
|
+
}
|
|
106
|
+
function renderMcp(surface, o) {
|
|
107
|
+
const entry = { command: o.command, args: o.args };
|
|
108
|
+
if (surface.stdioType)
|
|
109
|
+
entry.type = "stdio";
|
|
110
|
+
if (o.env)
|
|
111
|
+
entry.env = o.env;
|
|
112
|
+
const config = { [surface.configKey ?? "mcpServers"]: { [o.name]: entry } };
|
|
113
|
+
const snippet = JSON.stringify(config, null, 2);
|
|
114
|
+
const cli = surface.cli
|
|
115
|
+
? surface.cli
|
|
116
|
+
.replace("{name}", o.name)
|
|
117
|
+
.replace("{command}", o.command)
|
|
118
|
+
.replace("{args}", o.args.join(" "))
|
|
119
|
+
: undefined;
|
|
120
|
+
const instructions = `Add to ${surface.configFile ?? "your MCP client config"}:`;
|
|
121
|
+
const text = [
|
|
122
|
+
`# ${surface.name} — Behalf quickstart`,
|
|
123
|
+
"",
|
|
124
|
+
instructions,
|
|
125
|
+
"",
|
|
126
|
+
"```json",
|
|
127
|
+
snippet,
|
|
128
|
+
"```",
|
|
129
|
+
cli ? `\nOr from the CLI:\n\n\`\`\`bash\n${cli}\n\`\`\`` : "",
|
|
130
|
+
surface.notes ? `\nNote: ${surface.notes}` : "",
|
|
131
|
+
]
|
|
132
|
+
.filter(Boolean)
|
|
133
|
+
.join("\n");
|
|
134
|
+
return { surface: surface.id, name: surface.name, kind: "mcp", instructions, snippet, cli, notes: surface.notes, text };
|
|
135
|
+
}
|
|
136
|
+
function renderToolApi(surface, o) {
|
|
137
|
+
const tools = behalfMcpTools();
|
|
138
|
+
let snippet;
|
|
139
|
+
let instructions;
|
|
140
|
+
if (surface.api === "gemini") {
|
|
141
|
+
const decls = tools.map((t) => ({
|
|
142
|
+
name: t.name,
|
|
143
|
+
description: t.description,
|
|
144
|
+
parameters: t.inputSchema,
|
|
145
|
+
}));
|
|
146
|
+
snippet = JSON.stringify({ tools: [{ functionDeclarations: decls }] }, null, 2);
|
|
147
|
+
instructions = "Register these function declarations with the Gemini API:";
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
const fns = tools.map((t) => ({
|
|
151
|
+
type: "function",
|
|
152
|
+
function: { name: t.name, description: t.description, parameters: t.inputSchema },
|
|
153
|
+
}));
|
|
154
|
+
snippet = JSON.stringify({ tools: fns }, null, 2);
|
|
155
|
+
instructions = "Pass these tools to the OpenAI API (Chat Completions / Responses):";
|
|
156
|
+
}
|
|
157
|
+
const text = [
|
|
158
|
+
`# ${surface.name} — Behalf quickstart`,
|
|
159
|
+
"",
|
|
160
|
+
instructions,
|
|
161
|
+
"",
|
|
162
|
+
"```json",
|
|
163
|
+
snippet,
|
|
164
|
+
"```",
|
|
165
|
+
surface.notes ? `\nNote: ${surface.notes}` : "",
|
|
166
|
+
]
|
|
167
|
+
.filter(Boolean)
|
|
168
|
+
.join("\n");
|
|
169
|
+
return { surface: surface.id, name: surface.name, kind: "tool-api", instructions, snippet, notes: surface.notes, text };
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=quickstart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quickstart.js","sourceRoot":"","sources":["../src/quickstart.ts"],"names":[],"mappings":"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"}
|