@zibby/skills 0.1.95 → 0.2.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/README.md +1 -1
- package/dist/artifact.d.ts +1 -115
- package/dist/browser.d.ts +10 -19
- package/dist/chartRender.d.ts +46 -57
- package/dist/chartRender.js +1 -1
- package/dist/chat-memory.d.ts +26 -330
- package/dist/chat-notify.d.ts +30 -409
- package/dist/chat-notify.js +3 -3
- package/dist/chatProgress.d.ts +28 -47
- package/dist/code-scan.d.ts +52 -58
- package/dist/codeStats.d.ts +36 -136
- package/dist/codeStats.js +1 -1
- package/dist/codebaseMemory.d.ts +52 -32
- package/dist/codebaseMemory.js +2 -2
- package/dist/core-tools.d.ts +10 -131
- package/dist/datasetStore.d.ts +52 -179
- package/dist/datasetStore.js +12 -3
- package/dist/discord.d.ts +32 -68
- package/dist/figma.d.ts +5 -408
- package/dist/function-skill.d.ts +23 -135
- package/dist/function-skill.js +1 -1
- package/dist/gbrain.d.ts +46 -114
- package/dist/git-write.d.ts +45 -137
- package/dist/git-write.js +6 -6
- package/dist/git.d.ts +2 -73
- package/dist/github.d.ts +2 -1202
- package/dist/gitlab.d.ts +55 -1059
- package/dist/gitlab.js +2 -2
- package/dist/googleDocs.d.ts +39 -175
- package/dist/hubspot.d.ts +1 -381
- package/dist/index.d.ts +19 -12
- package/dist/index.js +157 -148
- package/dist/integrations.d.ts +2 -2
- package/dist/jira.d.ts +2 -532
- package/dist/jira.js +4 -4
- package/dist/kvMemory.d.ts +47 -78
- package/dist/lark.d.ts +2 -161
- package/dist/lark.js +1 -1
- package/dist/larkDocs.d.ts +35 -236
- package/dist/linear.d.ts +36 -343
- package/dist/linkedin.d.ts +10 -120
- package/dist/llm-billing.d.ts +92 -180
- package/dist/llm-billing.js +1 -1
- package/dist/memory.d.ts +11 -137
- package/dist/notion.d.ts +28 -276
- package/dist/notion.js +4 -4
- package/dist/opendesign.d.ts +24 -202
- package/dist/opendesign.js +2 -2
- package/dist/package.json +3 -2
- package/dist/plane.d.ts +40 -24
- package/dist/report.d.ts +153 -110
- package/dist/review-dedup.d.ts +8 -8
- package/dist/review.d.ts +12 -2
- package/dist/reviewMemoryIo.d.ts +37 -3
- package/dist/reviewRecord.d.ts +41 -47
- package/dist/sentry.d.ts +25 -22
- package/dist/skill-installer.d.ts +11 -86
- package/dist/slack.d.ts +1 -284
- package/dist/socialCard.d.ts +35 -89
- package/dist/test-runner.d.ts +1 -220
- package/dist/trackers/github-adapter.d.ts +39 -94
- package/dist/trackers/index.d.ts +25 -18
- package/dist/trackers/jira-adapter.d.ts +20 -88
- package/dist/trackers/linear-adapter.d.ts +24 -87
- package/dist/trackers/plane-adapter.d.ts +29 -85
- package/dist/trackers/plane-adapter.js +1 -1
- package/dist/trackers/types.d.ts +1 -186
- package/dist/triggerAgent.d.ts +26 -42
- package/dist/triggerAgent.js +1 -1
- package/dist/workflow-builder.d.ts +11 -245
- package/docs/cli-reference.md +33 -0
- package/docs/concepts/designing-agents.md +201 -0
- package/docs/self-host/backup-restore.md +52 -0
- package/docs/self-host/index.md +75 -0
- package/docs/self-host/storage.md +50 -0
- package/docs/self-host/troubleshooting.md +48 -0
- package/docs/self-host/upgrade.md +81 -0
- package/package.json +3 -2
package/dist/linkedin.d.ts
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* unchanged (self-host + cloud), so the Fargate linkedin-post workflow, which
|
|
22
22
|
* never sets these vars, is byte-for-byte unaffected.
|
|
23
23
|
*/
|
|
24
|
-
export function injectedPersonalToken(): {
|
|
24
|
+
export declare function injectedPersonalToken(): {
|
|
25
25
|
token: string;
|
|
26
26
|
memberId: string;
|
|
27
27
|
};
|
|
@@ -39,9 +39,10 @@ export function injectedPersonalToken(): {
|
|
|
39
39
|
* Absent the flag (Fargate workflows, self-host, direct tool use) → the
|
|
40
40
|
* normal PAT chokepoint runs unchanged.
|
|
41
41
|
*/
|
|
42
|
-
export function chatStrictPersonal(): boolean;
|
|
42
|
+
export declare function chatStrictPersonal(): boolean;
|
|
43
43
|
/** Belt-and-braces legacy flag: this turn's verified sender ≠ the tenant owner. */
|
|
44
|
-
export function senderIsNonOwner(): boolean;
|
|
44
|
+
export declare function senderIsNonOwner(): boolean;
|
|
45
|
+
export declare const PERSONAL_REFUSAL = "You haven't connected your own LinkedIn account \u2014 connect it at https://studio.zibby.dev/integrations (LinkedIn). For privacy, I can't post or act as anyone else's LinkedIn (including the project owner's) on your behalf.";
|
|
45
46
|
/**
|
|
46
47
|
* The single PERSONAL-tier credential gate for linkedin_personal calls:
|
|
47
48
|
* injected sender token wins; otherwise a strict chat turn (or a flagged
|
|
@@ -49,7 +50,7 @@ export function senderIsNonOwner(): boolean;
|
|
|
49
50
|
* PAT-resolved token. Returns the injected token/memberId or null (= caller
|
|
50
51
|
* may use the legacy PAT path). Throws PERSONAL_REFUSAL on the gated paths.
|
|
51
52
|
*/
|
|
52
|
-
export function personalTierCredentialGate(): {
|
|
53
|
+
export declare function personalTierCredentialGate(): {
|
|
53
54
|
token: string;
|
|
54
55
|
memberId: string;
|
|
55
56
|
};
|
|
@@ -57,7 +58,7 @@ export function personalTierCredentialGate(): {
|
|
|
57
58
|
* Extract a numeric organization id from a urn (urn:li:organization:123) or a
|
|
58
59
|
* bare numeric id. Returns the id string, or null if none can be found.
|
|
59
60
|
*/
|
|
60
|
-
export function parseOrgId(ref: any): string;
|
|
61
|
+
export declare function parseOrgId(ref: any): string;
|
|
61
62
|
/**
|
|
62
63
|
* Single chokepoint for every LinkedIn REST call. Resolves the OAuth bearer
|
|
63
64
|
* for the given `provider` via resolveIntegrationToken(provider) — defaulting
|
|
@@ -69,10 +70,10 @@ export function parseOrgId(ref: any): string;
|
|
|
69
70
|
*
|
|
70
71
|
* Keep this the single auth chokepoint — don't resolve tokens at call sites.
|
|
71
72
|
*/
|
|
72
|
-
export function linkedinApi(path: any, opts?:
|
|
73
|
+
export declare function linkedinApi(path: any, opts?: any, provider?: string): Promise<{
|
|
73
74
|
status: number;
|
|
74
75
|
headers: Headers;
|
|
75
|
-
body:
|
|
76
|
+
body: any;
|
|
76
77
|
}>;
|
|
77
78
|
/**
|
|
78
79
|
* Upload a LOCAL image file to LinkedIn's Images API and return its
|
|
@@ -91,116 +92,5 @@ export function linkedinApi(path: any, opts?: {}, provider?: string): Promise<{
|
|
|
91
92
|
* Throws on any non-2xx / missing field — handleToolCall catches it and returns
|
|
92
93
|
* { ok:false, error } so a bad image can't crash the run or cause a post.
|
|
93
94
|
*/
|
|
94
|
-
export function uploadImage(provider: any, ownerUrn: any, imagePath: any, mimeType
|
|
95
|
-
export const
|
|
96
|
-
export namespace linkedinSkill {
|
|
97
|
-
let id: string;
|
|
98
|
-
let serverName: string;
|
|
99
|
-
let allowedTools: string[];
|
|
100
|
-
let envKeys: any[];
|
|
101
|
-
let description: string;
|
|
102
|
-
let promptFragment: string;
|
|
103
|
-
function resolve(): {
|
|
104
|
-
command: any;
|
|
105
|
-
args: any[];
|
|
106
|
-
env: {};
|
|
107
|
-
description: string;
|
|
108
|
-
type?: undefined;
|
|
109
|
-
alwaysLoad?: undefined;
|
|
110
|
-
} | {
|
|
111
|
-
type: string;
|
|
112
|
-
command: string;
|
|
113
|
-
args: any[];
|
|
114
|
-
env: {};
|
|
115
|
-
description: string;
|
|
116
|
-
alwaysLoad: boolean;
|
|
117
|
-
};
|
|
118
|
-
function handleToolCall(name: any, args: any): Promise<string>;
|
|
119
|
-
let tools: ({
|
|
120
|
-
name: string;
|
|
121
|
-
description: string;
|
|
122
|
-
input_schema: {
|
|
123
|
-
type: string;
|
|
124
|
-
properties: {
|
|
125
|
-
organizationId?: undefined;
|
|
126
|
-
organizationUrn?: undefined;
|
|
127
|
-
text?: undefined;
|
|
128
|
-
visibility?: undefined;
|
|
129
|
-
imagePath?: undefined;
|
|
130
|
-
imageAltText?: undefined;
|
|
131
|
-
dry_run?: undefined;
|
|
132
|
-
};
|
|
133
|
-
required?: undefined;
|
|
134
|
-
};
|
|
135
|
-
} | {
|
|
136
|
-
name: string;
|
|
137
|
-
description: string;
|
|
138
|
-
input_schema: {
|
|
139
|
-
type: string;
|
|
140
|
-
properties: {
|
|
141
|
-
organizationId: {
|
|
142
|
-
type: string;
|
|
143
|
-
description: string;
|
|
144
|
-
};
|
|
145
|
-
organizationUrn: {
|
|
146
|
-
type: string;
|
|
147
|
-
description: string;
|
|
148
|
-
};
|
|
149
|
-
text: {
|
|
150
|
-
type: string;
|
|
151
|
-
description: string;
|
|
152
|
-
};
|
|
153
|
-
visibility: {
|
|
154
|
-
type: string;
|
|
155
|
-
enum: string[];
|
|
156
|
-
description: string;
|
|
157
|
-
};
|
|
158
|
-
imagePath: {
|
|
159
|
-
type: string;
|
|
160
|
-
description: string;
|
|
161
|
-
};
|
|
162
|
-
imageAltText: {
|
|
163
|
-
type: string;
|
|
164
|
-
description: string;
|
|
165
|
-
};
|
|
166
|
-
dry_run: {
|
|
167
|
-
type: string;
|
|
168
|
-
description: string;
|
|
169
|
-
};
|
|
170
|
-
};
|
|
171
|
-
required: string[];
|
|
172
|
-
};
|
|
173
|
-
} | {
|
|
174
|
-
name: string;
|
|
175
|
-
description: string;
|
|
176
|
-
input_schema: {
|
|
177
|
-
type: string;
|
|
178
|
-
properties: {
|
|
179
|
-
text: {
|
|
180
|
-
type: string;
|
|
181
|
-
description: string;
|
|
182
|
-
};
|
|
183
|
-
visibility: {
|
|
184
|
-
type: string;
|
|
185
|
-
enum: string[];
|
|
186
|
-
description: string;
|
|
187
|
-
};
|
|
188
|
-
imagePath: {
|
|
189
|
-
type: string;
|
|
190
|
-
description: string;
|
|
191
|
-
};
|
|
192
|
-
imageAltText: {
|
|
193
|
-
type: string;
|
|
194
|
-
description: string;
|
|
195
|
-
};
|
|
196
|
-
dry_run: {
|
|
197
|
-
type: string;
|
|
198
|
-
description: string;
|
|
199
|
-
};
|
|
200
|
-
organizationId?: undefined;
|
|
201
|
-
organizationUrn?: undefined;
|
|
202
|
-
};
|
|
203
|
-
required: string[];
|
|
204
|
-
};
|
|
205
|
-
})[];
|
|
206
|
-
}
|
|
95
|
+
export declare function uploadImage(provider: any, ownerUrn: any, imagePath: any, mimeType?: any): Promise<any>;
|
|
96
|
+
export declare const linkedinSkill: any;
|
package/dist/llm-billing.d.ts
CHANGED
|
@@ -1,3 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* llm-billing — read-only fetch + normalize for LLM-provider cost/usage
|
|
3
|
+
* admin APIs (OpenAI / Anthropic / Cursor).
|
|
4
|
+
*
|
|
5
|
+
* Design notes:
|
|
6
|
+
*
|
|
7
|
+
* - This file exports BOTH the minimal skill declarations (id +
|
|
8
|
+
* requiresIntegration only — these gate marketplace deploys via the
|
|
9
|
+
* backend's deriveRequiredIntegrations) AND a plain-function
|
|
10
|
+
* fetch SDK (fetchOpenAICosts / fetchAnthropicCosts / fetchCursorSpend
|
|
11
|
+
* + fetchAllProviders). Skill objects are registered in index.js;
|
|
12
|
+
* fetch functions are imported directly by template nodes.
|
|
13
|
+
*
|
|
14
|
+
* - We deliberately do NOT expose this as an MCP server. The fetch
|
|
15
|
+
* surface is small (3 endpoints) and deterministic — workflow code
|
|
16
|
+
* knows exactly what to ask for. MCP would add a JSON-RPC hop and
|
|
17
|
+
* LLM-driven tool selection for no gain. See README discussion
|
|
18
|
+
* re: REST vs MCP for the broader rationale.
|
|
19
|
+
*
|
|
20
|
+
* - Output shape is normalized across providers so downstream
|
|
21
|
+
* analysis (baseline diff, anomaly detection) doesn't need
|
|
22
|
+
* per-provider branches. See NormalizedSpendRecord JSDoc below.
|
|
23
|
+
*
|
|
24
|
+
* - Failure mode is partial: `fetchAllProviders` uses Promise.allSettled
|
|
25
|
+
* so one provider being down (or not connected) doesn't kill the
|
|
26
|
+
* whole digest. Each leg returns either { items, ok: true } or
|
|
27
|
+
* { error, ok: false } so the analyze node can render a degraded
|
|
28
|
+
* digest.
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Normalized record shape — one entry per (provider × day × dimension)
|
|
32
|
+
* after each provider's response is unpacked. Optional fields are
|
|
33
|
+
* provider-specific and may be undefined.
|
|
34
|
+
*
|
|
35
|
+
* @typedef {Object} NormalizedSpendRecord
|
|
36
|
+
* @property {'openai'|'anthropic'|'cursor'} provider
|
|
37
|
+
* @property {string} day ISO date (YYYY-MM-DD)
|
|
38
|
+
* @property {number} costUsd USD, positive
|
|
39
|
+
* @property {string} [projectId] OpenAI project_id
|
|
40
|
+
* @property {string} [projectName] OpenAI project metadata (joined on lookup)
|
|
41
|
+
* @property {string} [workspaceId] Anthropic workspace_id
|
|
42
|
+
* @property {string} [workspaceName] Anthropic workspace metadata
|
|
43
|
+
* @property {string} [apiKeyId] OpenAI / Anthropic api_key_id
|
|
44
|
+
* @property {string} [userEmail] Cursor team-member email
|
|
45
|
+
* @property {string} [model] Model id (when grouped by model)
|
|
46
|
+
* @property {number} [tokensIn]
|
|
47
|
+
* @property {number} [tokensOut]
|
|
48
|
+
* @property {number} [cachedTokens]
|
|
49
|
+
* @property {number} [requestCount] Cursor
|
|
50
|
+
* @property {number} [acceptanceRate] Cursor: 0..1
|
|
51
|
+
*/
|
|
52
|
+
/**
|
|
53
|
+
* Marketplace-gating skill declarations. The id matches the
|
|
54
|
+
* REQUIRED_INTEGRATION_MAP entry on the backend; the template's node
|
|
55
|
+
* just declares `skills: [SKILLS.OPENAI_BILLING, ...]` and the bundler
|
|
56
|
+
* derives required integrations automatically.
|
|
57
|
+
*
|
|
58
|
+
* These are intentionally minimal — no MCP tools, no resolve(), no
|
|
59
|
+
* prompt fragments. The skill object exists ONLY to register the
|
|
60
|
+
* integration dependency. Runtime behavior lives in the fetch fns below.
|
|
61
|
+
*/
|
|
62
|
+
export declare const openaiBillingSkill: Readonly<{
|
|
63
|
+
id: "openai_billing";
|
|
64
|
+
requiresIntegration: "openai_billing";
|
|
65
|
+
description: "OpenAI organization billing/usage admin API (paste sk-admin-... key)";
|
|
66
|
+
}>;
|
|
67
|
+
export declare const anthropicBillingSkill: Readonly<{
|
|
68
|
+
id: "anthropic_billing";
|
|
69
|
+
requiresIntegration: "anthropic_billing";
|
|
70
|
+
description: "Anthropic organization cost/usage admin API (paste sk-ant-admin-... key)";
|
|
71
|
+
}>;
|
|
72
|
+
export declare const cursorAdminSkill: Readonly<{
|
|
73
|
+
id: "cursor_admin";
|
|
74
|
+
requiresIntegration: "cursor_admin";
|
|
75
|
+
description: "Cursor Team/Enterprise admin API (paste admin key)";
|
|
76
|
+
}>;
|
|
1
77
|
/**
|
|
2
78
|
* Fetch OpenAI org costs + usage for the window. Iterates pagination
|
|
3
79
|
* (page_token) until exhausted.
|
|
@@ -21,13 +97,9 @@
|
|
|
21
97
|
* @param {{ startMs: number, endMs: number, groupBy?: string[] }} opts
|
|
22
98
|
* @returns {Promise<{ ok: true, items: NormalizedSpendRecord[], rawBuckets: number }>}
|
|
23
99
|
*/
|
|
24
|
-
export function fetchOpenAICosts({ startMs, endMs, groupBy }: {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
groupBy?: string[];
|
|
28
|
-
}): Promise<{
|
|
29
|
-
ok: true;
|
|
30
|
-
items: NormalizedSpendRecord[];
|
|
100
|
+
export declare function fetchOpenAICosts({ startMs, endMs, groupBy }: any): Promise<{
|
|
101
|
+
ok: boolean;
|
|
102
|
+
items: any[];
|
|
31
103
|
rawBuckets: number;
|
|
32
104
|
}>;
|
|
33
105
|
/**
|
|
@@ -35,7 +107,7 @@ export function fetchOpenAICosts({ startMs, endMs, groupBy }: {
|
|
|
35
107
|
* to display "acme-prod" instead of "proj_abc123". Cheap — usually
|
|
36
108
|
* <50 projects. Returns Map<projectId, projectName>.
|
|
37
109
|
*/
|
|
38
|
-
export function fetchOpenAIProjects(): Promise<Map<any, any>>;
|
|
110
|
+
export declare function fetchOpenAIProjects(): Promise<Map<any, any>>;
|
|
39
111
|
/**
|
|
40
112
|
* Fetch Anthropic cost report.
|
|
41
113
|
*
|
|
@@ -56,29 +128,15 @@ export function fetchOpenAIProjects(): Promise<Map<any, any>>;
|
|
|
56
128
|
* Multiply-by-100 then parse-int → exact-cents arithmetic OK; for the
|
|
57
129
|
* digest we just parseFloat (drift over 28 days is negligible).
|
|
58
130
|
*/
|
|
59
|
-
export function fetchAnthropicCosts({ startMs, endMs, groupBy }: {
|
|
60
|
-
startMs: any;
|
|
61
|
-
endMs: any;
|
|
62
|
-
groupBy?: string[];
|
|
63
|
-
}): Promise<{
|
|
131
|
+
export declare function fetchAnthropicCosts({ startMs, endMs, groupBy }: any): Promise<{
|
|
64
132
|
ok: boolean;
|
|
65
|
-
items:
|
|
66
|
-
provider: string;
|
|
67
|
-
day: any;
|
|
68
|
-
costUsd: number;
|
|
69
|
-
workspaceId: any;
|
|
70
|
-
apiKeyId: any;
|
|
71
|
-
model: any;
|
|
72
|
-
tokensIn: number;
|
|
73
|
-
tokensOut: number;
|
|
74
|
-
cachedTokens: number;
|
|
75
|
-
}[];
|
|
133
|
+
items: any[];
|
|
76
134
|
rawBuckets: number;
|
|
77
135
|
}>;
|
|
78
136
|
/**
|
|
79
137
|
* Fetch Anthropic workspace catalog (id → name).
|
|
80
138
|
*/
|
|
81
|
-
export function fetchAnthropicWorkspaces(): Promise<Map<any, any>>;
|
|
139
|
+
export declare function fetchAnthropicWorkspaces(): Promise<Map<any, any>>;
|
|
82
140
|
/**
|
|
83
141
|
* Fetch Cursor team daily-usage data. The endpoint returns per-day,
|
|
84
142
|
* per-user, per-model rolls — we flatten to NormalizedSpendRecord.
|
|
@@ -99,28 +157,9 @@ export function fetchAnthropicWorkspaces(): Promise<Map<any, any>>;
|
|
|
99
157
|
* acceptanceRate = acceptedLines / suggestedLines (per model per user
|
|
100
158
|
* per day). The digest aggregates across users for the team-level rate.
|
|
101
159
|
*/
|
|
102
|
-
export function fetchCursorSpend({ startMs, endMs }: {
|
|
103
|
-
startMs: any;
|
|
104
|
-
endMs: any;
|
|
105
|
-
}): Promise<{
|
|
160
|
+
export declare function fetchCursorSpend({ startMs, endMs }: any): Promise<{
|
|
106
161
|
ok: boolean;
|
|
107
|
-
items:
|
|
108
|
-
provider: string;
|
|
109
|
-
day: any;
|
|
110
|
-
costUsd: number;
|
|
111
|
-
userEmail: any;
|
|
112
|
-
model: any;
|
|
113
|
-
requestCount: number;
|
|
114
|
-
acceptanceRate: number;
|
|
115
|
-
} | {
|
|
116
|
-
provider: string;
|
|
117
|
-
day: any;
|
|
118
|
-
costUsd: number;
|
|
119
|
-
userEmail: any;
|
|
120
|
-
model?: undefined;
|
|
121
|
-
requestCount?: undefined;
|
|
122
|
-
acceptanceRate?: undefined;
|
|
123
|
-
})[];
|
|
162
|
+
items: any[];
|
|
124
163
|
rawBuckets: number;
|
|
125
164
|
}>;
|
|
126
165
|
/**
|
|
@@ -136,34 +175,13 @@ export function fetchCursorSpend({ startMs, endMs }: {
|
|
|
136
175
|
* totals: { provider: string, totalUsd: number }[],
|
|
137
176
|
* }>}
|
|
138
177
|
*/
|
|
139
|
-
export function fetchAllProviders({ startMs, endMs }: {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
openai: {
|
|
144
|
-
ok: true;
|
|
145
|
-
items: NormalizedSpendRecord[];
|
|
146
|
-
} | {
|
|
147
|
-
ok: false;
|
|
148
|
-
error: string;
|
|
149
|
-
};
|
|
150
|
-
anthropic: {
|
|
151
|
-
ok: true;
|
|
152
|
-
items: NormalizedSpendRecord[];
|
|
153
|
-
} | {
|
|
154
|
-
ok: false;
|
|
155
|
-
error: string;
|
|
156
|
-
};
|
|
157
|
-
cursor: {
|
|
158
|
-
ok: true;
|
|
159
|
-
items: NormalizedSpendRecord[];
|
|
160
|
-
} | {
|
|
161
|
-
ok: false;
|
|
162
|
-
error: string;
|
|
163
|
-
};
|
|
178
|
+
export declare function fetchAllProviders({ startMs, endMs }: any): Promise<{
|
|
179
|
+
openai: any;
|
|
180
|
+
anthropic: any;
|
|
181
|
+
cursor: any;
|
|
164
182
|
totals: {
|
|
165
183
|
provider: string;
|
|
166
|
-
totalUsd:
|
|
184
|
+
totalUsd: any;
|
|
167
185
|
}[];
|
|
168
186
|
}>;
|
|
169
187
|
/**
|
|
@@ -174,11 +192,7 @@ export function fetchAllProviders({ startMs, endMs }: {
|
|
|
174
192
|
* @param {(item: NormalizedSpendRecord) => string} keyFn
|
|
175
193
|
* @returns {{ key: string, totalUsd: number, count: number }[]} sorted desc by totalUsd
|
|
176
194
|
*/
|
|
177
|
-
export function groupByKey(items:
|
|
178
|
-
key: string;
|
|
179
|
-
totalUsd: number;
|
|
180
|
-
count: number;
|
|
181
|
-
}[];
|
|
195
|
+
export declare function groupByKey(items: any, keyFn: any): any[];
|
|
182
196
|
/**
|
|
183
197
|
* Compute mean + stddev over a numeric window. Used by analyze nodes
|
|
184
198
|
* to flag this-week-vs-baseline anomalies (>2σ).
|
|
@@ -186,109 +200,7 @@ export function groupByKey(items: NormalizedSpendRecord[], keyFn: (item: Normali
|
|
|
186
200
|
* @param {number[]} xs
|
|
187
201
|
* @returns {{ mean: number, stddev: number }}
|
|
188
202
|
*/
|
|
189
|
-
export function meanStddev(xs:
|
|
203
|
+
export declare function meanStddev(xs: any): {
|
|
190
204
|
mean: number;
|
|
191
205
|
stddev: number;
|
|
192
206
|
};
|
|
193
|
-
/**
|
|
194
|
-
* Normalized record shape — one entry per (provider × day × dimension)
|
|
195
|
-
* after each provider's response is unpacked. Optional fields are
|
|
196
|
-
* provider-specific and may be undefined.
|
|
197
|
-
*
|
|
198
|
-
* @typedef {Object} NormalizedSpendRecord
|
|
199
|
-
* @property {'openai'|'anthropic'|'cursor'} provider
|
|
200
|
-
* @property {string} day ISO date (YYYY-MM-DD)
|
|
201
|
-
* @property {number} costUsd USD, positive
|
|
202
|
-
* @property {string} [projectId] OpenAI project_id
|
|
203
|
-
* @property {string} [projectName] OpenAI project metadata (joined on lookup)
|
|
204
|
-
* @property {string} [workspaceId] Anthropic workspace_id
|
|
205
|
-
* @property {string} [workspaceName] Anthropic workspace metadata
|
|
206
|
-
* @property {string} [apiKeyId] OpenAI / Anthropic api_key_id
|
|
207
|
-
* @property {string} [userEmail] Cursor team-member email
|
|
208
|
-
* @property {string} [model] Model id (when grouped by model)
|
|
209
|
-
* @property {number} [tokensIn]
|
|
210
|
-
* @property {number} [tokensOut]
|
|
211
|
-
* @property {number} [cachedTokens]
|
|
212
|
-
* @property {number} [requestCount] Cursor
|
|
213
|
-
* @property {number} [acceptanceRate] Cursor: 0..1
|
|
214
|
-
*/
|
|
215
|
-
/**
|
|
216
|
-
* Marketplace-gating skill declarations. The id matches the
|
|
217
|
-
* REQUIRED_INTEGRATION_MAP entry on the backend; the template's node
|
|
218
|
-
* just declares `skills: [SKILLS.OPENAI_BILLING, ...]` and the bundler
|
|
219
|
-
* derives required integrations automatically.
|
|
220
|
-
*
|
|
221
|
-
* These are intentionally minimal — no MCP tools, no resolve(), no
|
|
222
|
-
* prompt fragments. The skill object exists ONLY to register the
|
|
223
|
-
* integration dependency. Runtime behavior lives in the fetch fns below.
|
|
224
|
-
*/
|
|
225
|
-
export const openaiBillingSkill: Readonly<{
|
|
226
|
-
id: "openai_billing";
|
|
227
|
-
requiresIntegration: "openai_billing";
|
|
228
|
-
description: "OpenAI organization billing/usage admin API (paste sk-admin-... key)";
|
|
229
|
-
}>;
|
|
230
|
-
export const anthropicBillingSkill: Readonly<{
|
|
231
|
-
id: "anthropic_billing";
|
|
232
|
-
requiresIntegration: "anthropic_billing";
|
|
233
|
-
description: "Anthropic organization cost/usage admin API (paste sk-ant-admin-... key)";
|
|
234
|
-
}>;
|
|
235
|
-
export const cursorAdminSkill: Readonly<{
|
|
236
|
-
id: "cursor_admin";
|
|
237
|
-
requiresIntegration: "cursor_admin";
|
|
238
|
-
description: "Cursor Team/Enterprise admin API (paste admin key)";
|
|
239
|
-
}>;
|
|
240
|
-
/**
|
|
241
|
-
* Normalized record shape — one entry per (provider × day × dimension)
|
|
242
|
-
* after each provider's response is unpacked. Optional fields are
|
|
243
|
-
* provider-specific and may be undefined.
|
|
244
|
-
*/
|
|
245
|
-
export type NormalizedSpendRecord = {
|
|
246
|
-
provider: "openai" | "anthropic" | "cursor";
|
|
247
|
-
/**
|
|
248
|
-
* ISO date (YYYY-MM-DD)
|
|
249
|
-
*/
|
|
250
|
-
day: string;
|
|
251
|
-
/**
|
|
252
|
-
* USD, positive
|
|
253
|
-
*/
|
|
254
|
-
costUsd: number;
|
|
255
|
-
/**
|
|
256
|
-
* OpenAI project_id
|
|
257
|
-
*/
|
|
258
|
-
projectId?: string;
|
|
259
|
-
/**
|
|
260
|
-
* OpenAI project metadata (joined on lookup)
|
|
261
|
-
*/
|
|
262
|
-
projectName?: string;
|
|
263
|
-
/**
|
|
264
|
-
* Anthropic workspace_id
|
|
265
|
-
*/
|
|
266
|
-
workspaceId?: string;
|
|
267
|
-
/**
|
|
268
|
-
* Anthropic workspace metadata
|
|
269
|
-
*/
|
|
270
|
-
workspaceName?: string;
|
|
271
|
-
/**
|
|
272
|
-
* OpenAI / Anthropic api_key_id
|
|
273
|
-
*/
|
|
274
|
-
apiKeyId?: string;
|
|
275
|
-
/**
|
|
276
|
-
* Cursor team-member email
|
|
277
|
-
*/
|
|
278
|
-
userEmail?: string;
|
|
279
|
-
/**
|
|
280
|
-
* Model id (when grouped by model)
|
|
281
|
-
*/
|
|
282
|
-
model?: string;
|
|
283
|
-
tokensIn?: number;
|
|
284
|
-
tokensOut?: number;
|
|
285
|
-
cachedTokens?: number;
|
|
286
|
-
/**
|
|
287
|
-
* Cursor
|
|
288
|
-
*/
|
|
289
|
-
requestCount?: number;
|
|
290
|
-
/**
|
|
291
|
-
* Cursor: 0..1
|
|
292
|
-
*/
|
|
293
|
-
acceptanceRate?: number;
|
|
294
|
-
};
|
package/dist/llm-billing.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{resolveIntegrationToken as w}from"@zibby/core/backend-client.js";var k=Object.freeze({SENTRY:"sentry",JIRA:"jira",GITHUB:"github",GITLAB:"gitlab",SLACK:"slack",LARK:"lark",OPENAI_BILLING:"openai_billing",ANTHROPIC_BILLING:"anthropic_billing",CURSOR_ADMIN:"cursor_admin",NOTION:"notion",GOOGLE:"google",PLANE:"plane",LINEAR:"linear",FIGMA:"figma",HUBSPOT:"hubspot",OPEN_DESIGN:"open_design",LINKEDIN_PERSONAL:"linkedin_personal",LINKEDIN_BUSINESS:"linkedin_business",DISCORD:"discord"}),
|
|
1
|
+
import{resolveIntegrationToken as w}from"@zibby/core/backend-client.js";var k=Object.freeze({SENTRY:"sentry",JIRA:"jira",GITHUB:"github",GITLAB:"gitlab",SLACK:"slack",LARK:"lark",OPENAI_BILLING:"openai_billing",ANTHROPIC_BILLING:"anthropic_billing",CURSOR_ADMIN:"cursor_admin",NOTION:"notion",GOOGLE:"google",PLANE:"plane",LINEAR:"linear",FIGMA:"figma",HUBSPOT:"hubspot",OPEN_DESIGN:"open_design",LINKEDIN_PERSONAL:"linkedin_personal",LINKEDIN_BUSINESS:"linkedin_business",DISCORD:"discord"}),P=Object.freeze({sentry:{id:"sentry",name:"Sentry",connectPath:"/integrations?provider=sentry"},jira:{id:"jira",name:"Jira",connectPath:"/integrations?provider=jira"},github:{id:"github",name:"GitHub",connectPath:"/integrations?provider=github"},gitlab:{id:"gitlab",name:"GitLab",connectPath:"/integrations?provider=gitlab"},slack:{id:"slack",name:"Slack",connectPath:"/integrations?provider=slack"},lark:{id:"lark",name:"Lark",connectPath:"/integrations?provider=lark"},openai_billing:{id:"openai_billing",name:"OpenAI Admin",connectPath:"/integrations?provider=openai_billing"},anthropic_billing:{id:"anthropic_billing",name:"Anthropic Admin",connectPath:"/integrations?provider=anthropic_billing"},cursor_admin:{id:"cursor_admin",name:"Cursor Admin",connectPath:"/integrations?provider=cursor_admin"},notion:{id:"notion",name:"Notion",connectPath:"/integrations?provider=notion"},google:{id:"google",name:"Google Docs",connectPath:"/integrations?provider=google"},plane:{id:"plane",name:"Plane",connectPath:"/integrations?provider=plane"},linear:{id:"linear",name:"Linear",connectPath:"/integrations?provider=linear"},figma:{id:"figma",name:"Figma",connectPath:"/integrations?provider=figma"},hubspot:{id:"hubspot",name:"HubSpot",connectPath:"/integrations?provider=hubspot"},open_design:{id:"open_design",name:"OpenDesign",connectPath:"/integrations?provider=open_design"},linkedin_personal:{id:"linkedin_personal",name:"LinkedIn (Personal)",connectPath:"/integrations?provider=linkedin_personal"},linkedin_business:{id:"linkedin_business",name:"LinkedIn (Business)",connectPath:"/integrations?provider=linkedin_business"},discord:{id:"discord",name:"Discord",connectPath:"/integrations?provider=discord"}});var S=Object.freeze({id:"openai_billing",requiresIntegration:k.OPENAI_BILLING,description:"OpenAI organization billing/usage admin API (paste sk-admin-... key)"}),$=Object.freeze({id:"anthropic_billing",requiresIntegration:k.ANTHROPIC_BILLING,description:"Anthropic organization cost/usage admin API (paste sk-ant-admin-... key)"}),E=Object.freeze({id:"cursor_admin",requiresIntegration:k.CURSOR_ADMIN,description:"Cursor Team/Enterprise admin API (paste admin key)"});function I(t){return Math.floor(t/1e3)}function _(t){return new Date(t).toISOString().slice(0,10)}function b(t){return new Date(t).toISOString()}async function f(t){let a=await w(t);if(!a?.token)throw new Error(`${t} token resolver returned no token`);return a.token}async function y({startMs:t,endMs:a,groupBy:o=["project_id","line_item"]}){let i=await f("openai_billing"),e=[],n=0,m=o.map(d=>`group_by[]=${encodeURIComponent(d)}`).join("&"),u=null;for(let d=0;d<50;d++){let r=`https://api.openai.com/v1/organization/costs?${[`start_time=${I(t)}`,`end_time=${I(a)}`,"bucket_width=1d","limit=180",m,u?`page=${encodeURIComponent(u)}`:""].filter(Boolean).join("&")}`,c=await fetch(r,{headers:{Authorization:`Bearer ${i}`}});if(!c.ok){let l=await c.text().catch(()=>"");throw new Error(`OpenAI costs API ${c.status}: ${l.slice(0,200)}`)}let p=await c.json();for(let l of p.data||[]){n+=1;let h=_((l.start_time||0)*1e3);for(let s of l.results||[])e.push({provider:"openai",day:h,costUsd:Number(s.amount?.value??0),projectId:s.project_id||void 0,apiKeyId:s.api_key_id||void 0,model:s.line_item||void 0})}if(!p.has_more||!p.next_page)break;u=p.next_page}return{ok:!0,items:e,rawBuckets:n}}async function R(){let t=await f("openai_billing"),o=await fetch("https://api.openai.com/v1/organization/projects?limit=100",{headers:{Authorization:`Bearer ${t}`}});if(!o.ok){let n=await o.text().catch(()=>"");throw new Error(`OpenAI projects API ${o.status}: ${n.slice(0,200)}`)}let i=await o.json(),e=new Map;for(let n of i.data||[])e.set(n.id,n.name);return e}async function v({startMs:t,endMs:a,groupBy:o=["workspace_id"]}){let i=await f("anthropic_billing"),e=[],n=0,m=o.map(d=>`group_by[]=${encodeURIComponent(d)}`).join("&"),u=null;for(let d=0;d<50;d++){let r=`https://api.anthropic.com/v1/organizations/cost_report?${[`starting_at=${encodeURIComponent(b(t))}`,`ending_at=${encodeURIComponent(b(a))}`,"bucket=1d","limit=100",m,u?`page=${encodeURIComponent(u)}`:""].filter(Boolean).join("&")}`,c=await fetch(r,{headers:{"x-api-key":i,"anthropic-version":"2023-06-01"}});if(!c.ok){let l=await c.text().catch(()=>"");throw new Error(`Anthropic cost_report ${c.status}: ${l.slice(0,200)}`)}let p=await c.json();for(let l of p.data||[]){n+=1;let h=(l.starting_at||"").slice(0,10);for(let s of l.results||[])e.push({provider:"anthropic",day:h,costUsd:Number(s.amount??s.cost??0),workspaceId:s.workspace_id||void 0,apiKeyId:s.api_key_id||void 0,model:s.model||void 0,tokensIn:s.uncached_input_tokens!=null?Number(s.uncached_input_tokens):void 0,tokensOut:s.output_tokens!=null?Number(s.output_tokens):void 0,cachedTokens:s.cached_input_tokens!=null?Number(s.cached_input_tokens):void 0})}if(!p.has_more||!p.next_page)break;u=p.next_page}return{ok:!0,items:e,rawBuckets:n}}async function j(){let t=await f("anthropic_billing"),o=await fetch("https://api.anthropic.com/v1/organizations/workspaces?limit=100",{headers:{"x-api-key":t,"anthropic-version":"2023-06-01"}});if(!o.ok){let n=await o.text().catch(()=>"");throw new Error(`Anthropic workspaces ${o.status}: ${n.slice(0,200)}`)}let i=await o.json(),e=new Map;for(let n of i.data||[])e.set(n.id,n.name);return e}async function A({startMs:t,endMs:a}){let o=await f("cursor_admin"),i=_(t),e=_(a),n=`https://api.cursor.com/teams/daily-usage-data?startDate=${i}&endDate=${e}`,m=await fetch(n,{headers:{Authorization:`Bearer ${o}`}});if(!m.ok){let r=await m.text().catch(()=>"");throw new Error(`Cursor daily-usage ${m.status}: ${r.slice(0,200)}`)}let u=await m.json(),d=[],g=0;for(let r of u.data||[]){g+=1;let c=r.date;for(let p of r.userMetrics||[]){for(let l of p.modelUsage||[]){let h=Number(l.acceptedLines??0),s=Number(l.suggestedLines??0);d.push({provider:"cursor",day:c,costUsd:Number(l.totalCents??0)/100,userEmail:p.email,model:l.model,requestCount:Number(l.requestCount??0),acceptanceRate:s>0?h/s:void 0})}(!p.modelUsage||p.modelUsage.length===0)&&d.push({provider:"cursor",day:c,costUsd:Number(p.totalCents??0)/100,userEmail:p.email})}}return{ok:!0,items:d,rawBuckets:g}}async function L({startMs:t,endMs:a}){let[o,i,e]=await Promise.allSettled([y({startMs:t,endMs:a}),v({startMs:t,endMs:a}),A({startMs:t,endMs:a})]),n=r=>r.status==="fulfilled"?r.value:{ok:!1,error:r.reason?.message||String(r.reason),items:[]},m=n(o),u=n(i),d=n(e),g=[{provider:"openai",totalUsd:m.items.reduce((r,c)=>r+(c.costUsd||0),0)},{provider:"anthropic",totalUsd:u.items.reduce((r,c)=>r+(c.costUsd||0),0)},{provider:"cursor",totalUsd:d.items.reduce((r,c)=>r+(c.costUsd||0),0)}];return{openai:m,anthropic:u,cursor:d,totals:g}}function x(t,a){let o=new Map;for(let i of t){let e=a(i);if(!e)continue;let n=o.get(e)||{key:e,totalUsd:0,count:0};n.totalUsd+=i.costUsd||0,n.count+=1,o.set(e,n)}return[...o.values()].sort((i,e)=>e.totalUsd-i.totalUsd)}function B(t){if(!t.length)return{mean:0,stddev:0};let a=t.reduce((i,e)=>i+e,0)/t.length,o=t.reduce((i,e)=>i+(e-a)**2,0)/t.length;return{mean:a,stddev:Math.sqrt(o)}}export{$ as anthropicBillingSkill,E as cursorAdminSkill,L as fetchAllProviders,v as fetchAnthropicCosts,j as fetchAnthropicWorkspaces,A as fetchCursorSpend,y as fetchOpenAICosts,R as fetchOpenAIProjects,x as groupByKey,B as meanStddev,S as openaiBillingSkill};
|
package/dist/memory.d.ts
CHANGED
|
@@ -1,137 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
description: string;
|
|
13
|
-
};
|
|
14
|
-
let tools: ({
|
|
15
|
-
name: string;
|
|
16
|
-
description: string;
|
|
17
|
-
input_schema: {
|
|
18
|
-
type: string;
|
|
19
|
-
properties: {
|
|
20
|
-
specPath: {
|
|
21
|
-
type: string;
|
|
22
|
-
description: string;
|
|
23
|
-
};
|
|
24
|
-
limit: {
|
|
25
|
-
type: string;
|
|
26
|
-
description: string;
|
|
27
|
-
};
|
|
28
|
-
pageUrl?: undefined;
|
|
29
|
-
url?: undefined;
|
|
30
|
-
fromUrl?: undefined;
|
|
31
|
-
category?: undefined;
|
|
32
|
-
content?: undefined;
|
|
33
|
-
sessionId?: undefined;
|
|
34
|
-
};
|
|
35
|
-
required?: undefined;
|
|
36
|
-
};
|
|
37
|
-
} | {
|
|
38
|
-
name: string;
|
|
39
|
-
description: string;
|
|
40
|
-
input_schema: {
|
|
41
|
-
type: string;
|
|
42
|
-
properties: {
|
|
43
|
-
pageUrl: {
|
|
44
|
-
type: string;
|
|
45
|
-
description: string;
|
|
46
|
-
};
|
|
47
|
-
limit: {
|
|
48
|
-
type: string;
|
|
49
|
-
description: string;
|
|
50
|
-
};
|
|
51
|
-
specPath?: undefined;
|
|
52
|
-
url?: undefined;
|
|
53
|
-
fromUrl?: undefined;
|
|
54
|
-
category?: undefined;
|
|
55
|
-
content?: undefined;
|
|
56
|
-
sessionId?: undefined;
|
|
57
|
-
};
|
|
58
|
-
required?: undefined;
|
|
59
|
-
};
|
|
60
|
-
} | {
|
|
61
|
-
name: string;
|
|
62
|
-
description: string;
|
|
63
|
-
input_schema: {
|
|
64
|
-
type: string;
|
|
65
|
-
properties: {
|
|
66
|
-
url: {
|
|
67
|
-
type: string;
|
|
68
|
-
description: string;
|
|
69
|
-
};
|
|
70
|
-
limit: {
|
|
71
|
-
type: string;
|
|
72
|
-
description: string;
|
|
73
|
-
};
|
|
74
|
-
specPath?: undefined;
|
|
75
|
-
pageUrl?: undefined;
|
|
76
|
-
fromUrl?: undefined;
|
|
77
|
-
category?: undefined;
|
|
78
|
-
content?: undefined;
|
|
79
|
-
sessionId?: undefined;
|
|
80
|
-
};
|
|
81
|
-
required?: undefined;
|
|
82
|
-
};
|
|
83
|
-
} | {
|
|
84
|
-
name: string;
|
|
85
|
-
description: string;
|
|
86
|
-
input_schema: {
|
|
87
|
-
type: string;
|
|
88
|
-
properties: {
|
|
89
|
-
fromUrl: {
|
|
90
|
-
type: string;
|
|
91
|
-
description: string;
|
|
92
|
-
};
|
|
93
|
-
limit: {
|
|
94
|
-
type: string;
|
|
95
|
-
description: string;
|
|
96
|
-
};
|
|
97
|
-
specPath?: undefined;
|
|
98
|
-
pageUrl?: undefined;
|
|
99
|
-
url?: undefined;
|
|
100
|
-
category?: undefined;
|
|
101
|
-
content?: undefined;
|
|
102
|
-
sessionId?: undefined;
|
|
103
|
-
};
|
|
104
|
-
required?: undefined;
|
|
105
|
-
};
|
|
106
|
-
} | {
|
|
107
|
-
name: string;
|
|
108
|
-
description: string;
|
|
109
|
-
input_schema: {
|
|
110
|
-
type: string;
|
|
111
|
-
properties: {
|
|
112
|
-
category: {
|
|
113
|
-
type: string;
|
|
114
|
-
enum: string[];
|
|
115
|
-
description: string;
|
|
116
|
-
};
|
|
117
|
-
content: {
|
|
118
|
-
type: string;
|
|
119
|
-
description: string;
|
|
120
|
-
};
|
|
121
|
-
specPath: {
|
|
122
|
-
type: string;
|
|
123
|
-
description: string;
|
|
124
|
-
};
|
|
125
|
-
sessionId: {
|
|
126
|
-
type: string;
|
|
127
|
-
description: string;
|
|
128
|
-
};
|
|
129
|
-
limit?: undefined;
|
|
130
|
-
pageUrl?: undefined;
|
|
131
|
-
url?: undefined;
|
|
132
|
-
fromUrl?: undefined;
|
|
133
|
-
};
|
|
134
|
-
required: string[];
|
|
135
|
-
};
|
|
136
|
-
})[];
|
|
137
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Memory Skill
|
|
3
|
+
*
|
|
4
|
+
* Provides test memory database tools via MCP (Dolt-backed).
|
|
5
|
+
* The AI agent can query test history, selector stability, page model,
|
|
6
|
+
* and navigation patterns from previous runs.
|
|
7
|
+
*
|
|
8
|
+
* Activated when SKILLS.MEMORY is included in node's skills array.
|
|
9
|
+
* Throws clear errors if dolt or database not set up.
|
|
10
|
+
*/
|
|
11
|
+
export declare const memorySkill: any;
|