unfairly 0.8.1 → 0.8.2

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 (80) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +15 -2
  3. package/dist/auth/browser-flow.d.ts +9 -0
  4. package/dist/auth/browser-flow.d.ts.map +1 -1
  5. package/dist/auth/browser-flow.js +11 -4
  6. package/dist/auth/browser-flow.js.map +1 -1
  7. package/dist/cmd/invite.js +2 -2
  8. package/dist/cmd/invite.js.map +1 -1
  9. package/dist/cmd/pace.d.ts +80 -0
  10. package/dist/cmd/pace.d.ts.map +1 -0
  11. package/dist/cmd/pace.js +393 -0
  12. package/dist/cmd/pace.js.map +1 -0
  13. package/dist/cmd/setup.d.ts +2 -0
  14. package/dist/cmd/setup.d.ts.map +1 -1
  15. package/dist/cmd/setup.js +20 -6
  16. package/dist/cmd/setup.js.map +1 -1
  17. package/dist/index.js +96 -2
  18. package/dist/index.js.map +1 -1
  19. package/dist/lib/types/index.d.ts +6 -6
  20. package/dist/pace/device.d.ts +101 -0
  21. package/dist/pace/device.d.ts.map +1 -0
  22. package/dist/pace/device.js +148 -0
  23. package/dist/pace/device.js.map +1 -0
  24. package/dist/pace/identity.d.ts +10 -0
  25. package/dist/pace/identity.d.ts.map +1 -0
  26. package/dist/pace/identity.js +17 -0
  27. package/dist/pace/identity.js.map +1 -0
  28. package/dist/pace/install.d.ts +28 -0
  29. package/dist/pace/install.d.ts.map +1 -0
  30. package/dist/pace/install.js +127 -0
  31. package/dist/pace/install.js.map +1 -0
  32. package/dist/pace/local-evidence.d.ts +75 -0
  33. package/dist/pace/local-evidence.d.ts.map +1 -0
  34. package/dist/pace/local-evidence.js +228 -0
  35. package/dist/pace/local-evidence.js.map +1 -0
  36. package/dist/pace/local-sessions.d.ts +48 -0
  37. package/dist/pace/local-sessions.d.ts.map +1 -0
  38. package/dist/pace/local-sessions.js +254 -0
  39. package/dist/pace/local-sessions.js.map +1 -0
  40. package/dist/pace/managed-config.d.ts +21 -0
  41. package/dist/pace/managed-config.d.ts.map +1 -0
  42. package/dist/pace/managed-config.js +102 -0
  43. package/dist/pace/managed-config.js.map +1 -0
  44. package/dist/pace/normalize.d.ts +10 -0
  45. package/dist/pace/normalize.d.ts.map +1 -0
  46. package/dist/pace/normalize.js +293 -0
  47. package/dist/pace/normalize.js.map +1 -0
  48. package/dist/pace/repository.d.ts +72 -0
  49. package/dist/pace/repository.d.ts.map +1 -0
  50. package/dist/pace/repository.js +120 -0
  51. package/dist/pace/repository.js.map +1 -0
  52. package/dist/pace/schema.d.ts +1325 -0
  53. package/dist/pace/schema.d.ts.map +1 -0
  54. package/dist/pace/schema.js +134 -0
  55. package/dist/pace/schema.js.map +1 -0
  56. package/dist/pace/session-summary.d.ts +179 -0
  57. package/dist/pace/session-summary.d.ts.map +1 -0
  58. package/dist/pace/session-summary.js +140 -0
  59. package/dist/pace/session-summary.js.map +1 -0
  60. package/dist/pace/spool.d.ts +6 -0
  61. package/dist/pace/spool.d.ts.map +1 -0
  62. package/dist/pace/spool.js +87 -0
  63. package/dist/pace/spool.js.map +1 -0
  64. package/package.json +3 -1
  65. package/plugin/.claude-plugin/plugin.json +9 -0
  66. package/plugin/.codex-plugin/plugin.json +21 -0
  67. package/plugin/.cursor-plugin/plugin.json +16 -0
  68. package/plugin/.mcp.json +8 -0
  69. package/plugin/README.md +19 -0
  70. package/plugin/deploy/README.md +30 -0
  71. package/plugin/gemini/GEMINI.md +3 -0
  72. package/plugin/gemini/gemini-extension.json +12 -0
  73. package/plugin/gemini/hooks/hooks.json +52 -0
  74. package/plugin/hooks/cursor-hooks.json +25 -0
  75. package/plugin/hooks/hooks.json +56 -0
  76. package/plugin/mcp.json +10 -0
  77. package/plugin/plugin.json +32 -0
  78. package/plugin/scripts/capture.cjs +46 -0
  79. package/plugin/skills/find-company-playbook/SKILL.md +12 -0
  80. package/plugin/skills/publish-learning/SKILL.md +8 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/pace/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,134 @@
1
+ import { z } from "zod";
2
+ export const PaceSourceSchema = z.enum([
3
+ "codex", "claude_code", "cursor", "gemini_cli", "openrouter", "chatgpt",
4
+ "claude_desktop", "claude_web", "gemini_web", "local_filesystem", "unknown",
5
+ ]);
6
+ export const PaceEventTypeSchema = z.enum([
7
+ "session.started", "session.ended", "model.completed", "tool.completed",
8
+ "tool.failed", "workflow.stopped", "artifact.created", "artifact.modified",
9
+ "desktop.activity", "unknown.observed",
10
+ ]);
11
+ export const PaceEvidenceLevelSchema = z.enum(["exact", "correlated", "inferred"]);
12
+ export const PaceToolCategorySchema = z.enum([
13
+ "file_read", "file_write", "code_search", "shell", "version_control",
14
+ "web", "connector", "agent", "skill", "other", "unknown",
15
+ ]);
16
+ export const PaceBlockerCategorySchema = z.enum([
17
+ "authentication", "authorization_permission", "approval_required",
18
+ "missing_dependency_tool", "configuration", "rate_limit_quota", "tool_failure",
19
+ "model_provider_unavailable", "workflow_stopped", "unknown",
20
+ ]);
21
+ export const PaceModelFamilySchema = z.enum([
22
+ "openai_gpt", "anthropic_claude", "google_gemini", "meta_llama",
23
+ "mistral", "other", "unknown",
24
+ ]);
25
+ export const PaceApprovalModeSchema = z.enum(["none", "manual", "automatic", "unknown"]);
26
+ export const PacePermissionModeSchema = z.enum([
27
+ "read_only", "workspace_write", "elevated", "unrestricted", "unknown",
28
+ ]);
29
+ export const PaceDurationBucketSchema = z.enum([
30
+ "under_1s", "1s_to_10s", "10s_to_60s", "1m_to_5m", "over_5m", "unknown",
31
+ ]);
32
+ export const PaceExitCodeBucketSchema = z.enum(["success", "failure", "signal", "unknown"]);
33
+ const OptionalOpaqueId = z.string().trim().regex(/^[A-Za-z0-9_-]{1,128}$/).optional();
34
+ // Legacy schemas exist only so an old local spool can be sanitized in place.
35
+ // New collection and network upload use v3 exclusively.
36
+ const LegacyAttributesSchema = z.object({
37
+ hook_event: z.string().max(128),
38
+ approval_mode: z.string().max(128).optional(),
39
+ permission_mode: z.string().max(128).optional(),
40
+ status: z.string().max(128).optional(),
41
+ success: z.boolean().optional(),
42
+ exit_code: z.number().int().optional(),
43
+ duration_ms: z.number().nonnegative().optional(),
44
+ input_tokens: z.number().int().nonnegative().optional(),
45
+ output_tokens: z.number().int().nonnegative().optional(),
46
+ cached_tokens: z.number().int().nonnegative().optional(),
47
+ error_type: z.string().max(128).optional(),
48
+ stop_reason: z.string().max(128).optional(),
49
+ root_label: z.string().max(128).optional(),
50
+ path_fingerprint: z.string().regex(/^[a-f0-9]{64}$/).optional(),
51
+ file_extension: z.string().max(32).optional(),
52
+ file_name: z.string().max(255).optional(),
53
+ size_bytes: z.number().int().nonnegative().optional(),
54
+ files_changed: z.number().int().nonnegative().optional(),
55
+ local_signal: z.enum(["approved_output", "app_state_change"]).optional(),
56
+ source_app: z.enum(["chatgpt", "claude_desktop", "other"]).optional(),
57
+ }).strict();
58
+ const LegacyEventBaseSchema = z.object({
59
+ event_id: z.string().uuid(),
60
+ installation_id: z.string().uuid().optional(),
61
+ occurred_at: z.string().datetime(),
62
+ source: PaceSourceSchema,
63
+ event_type: PaceEventTypeSchema,
64
+ evidence_level: PaceEvidenceLevelSchema,
65
+ session_id: z.string().trim().min(1).max(512).optional(),
66
+ model: z.string().trim().min(1).max(512).optional(),
67
+ tool: z.string().trim().min(1).max(512).optional(),
68
+ skill: z.string().trim().min(1).max(512).optional(),
69
+ cwd: z.string().trim().min(1).max(512).optional(),
70
+ repository: z.string().trim().min(1).max(512).optional(),
71
+ branch: z.string().trim().min(1).max(512).optional(),
72
+ commit_sha: z.string().regex(/^[a-f0-9]{7,64}$/i).optional(),
73
+ artifact_type: z.enum([
74
+ "code", "pull_request", "document", "deck", "spreadsheet", "analysis",
75
+ "workflow", "decision", "other",
76
+ ]).optional(),
77
+ attributes: LegacyAttributesSchema,
78
+ });
79
+ export const PaceEventV1Schema = LegacyEventBaseSchema.extend({ schema_version: z.literal(1) }).strict();
80
+ export const PaceEventV2Schema = LegacyEventBaseSchema.extend({
81
+ schema_version: z.literal(2),
82
+ workflow_id: z.string().uuid().optional(),
83
+ initiative_id: z.string().trim().min(1).max(512).optional(),
84
+ playbook_id: z.string().trim().min(1).max(512).optional(),
85
+ playbook_version: z.string().trim().min(1).max(512).optional(),
86
+ }).strict();
87
+ export const PaceEventV3Schema = z.object({
88
+ schema_version: z.literal(3),
89
+ collection_policy_version: z.literal("metadata-v3"),
90
+ event_id: z.string().uuid(),
91
+ installation_id: z.string().uuid().optional(),
92
+ occurred_at: z.string().datetime(),
93
+ source: PaceSourceSchema,
94
+ event_type: PaceEventTypeSchema,
95
+ evidence_level: PaceEvidenceLevelSchema,
96
+ session_id: OptionalOpaqueId,
97
+ workflow_id: z.string().uuid().optional(),
98
+ initiative_id: OptionalOpaqueId,
99
+ playbook_id: OptionalOpaqueId,
100
+ playbook_version: OptionalOpaqueId,
101
+ repository_id: z.string().uuid().optional(),
102
+ commit_sha: z.string().regex(/^[a-f0-9]{40}$/i).optional(),
103
+ model_family: PaceModelFamilySchema.optional(),
104
+ tool_category: PaceToolCategorySchema.optional(),
105
+ blocker_category: PaceBlockerCategorySchema.optional(),
106
+ artifact_type: z.enum([
107
+ "code", "pull_request", "document", "deck", "spreadsheet", "analysis",
108
+ "workflow", "decision", "other",
109
+ ]).optional(),
110
+ attributes: z.object({
111
+ client_event: z.enum([
112
+ "session_start", "session_end", "before_agent", "after_agent", "stop",
113
+ "tool_success", "tool_failure", "model_complete", "local_output", "local_activity", "unknown",
114
+ ]),
115
+ approval_mode: PaceApprovalModeSchema.optional(),
116
+ permission_mode: PacePermissionModeSchema.optional(),
117
+ success: z.boolean().optional(),
118
+ exit_code_bucket: PaceExitCodeBucketSchema.optional(),
119
+ duration_bucket: PaceDurationBucketSchema.optional(),
120
+ input_tokens: z.number().int().nonnegative().optional(),
121
+ output_tokens: z.number().int().nonnegative().optional(),
122
+ cached_tokens: z.number().int().nonnegative().optional(),
123
+ files_changed_bucket: z.enum(["one", "two_to_five", "six_to_twenty", "over_twenty", "unknown"]).optional(),
124
+ local_signal: z.enum(["approved_output", "app_state_change"]).optional(),
125
+ }).strict(),
126
+ }).strict().superRefine((event, context) => {
127
+ if (event.commit_sha && !event.repository_id) {
128
+ context.addIssue({ code: z.ZodIssueCode.custom, path: ["commit_sha"], message: "commit_sha requires an approved repository_id" });
129
+ }
130
+ });
131
+ export const PaceLegacyEventSchema = z.discriminatedUnion("schema_version", [PaceEventV1Schema, PaceEventV2Schema]);
132
+ export const PaceEventSchema = PaceEventV3Schema;
133
+ export const PaceBatchSchema = z.object({ events: z.array(PaceEventV3Schema).min(1).max(250) }).strict();
134
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/pace/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,179 @@
1
+ import { z } from "zod";
2
+ import { type LocalSessionSummary } from "./local-sessions.js";
3
+ import { type RepositoryPolicy } from "./repository.js";
4
+ /**
5
+ * Splits a session's skills into names that may be reported (published plugin
6
+ * skills and the organization's own catalog) and a count of everything else,
7
+ * such as personal or project skills, whose names never leave the device.
8
+ */
9
+ export declare function reportableSkills(skills: string[], orgCatalog?: string[]): {
10
+ skills: string[];
11
+ unlisted: number;
12
+ };
13
+ export declare const SessionSummaryUploadSchema: z.ZodEffects<z.ZodObject<{
14
+ schema_version: z.ZodLiteral<1>;
15
+ collection_policy_version: z.ZodLiteral<"metadata-v3">;
16
+ installation_id: z.ZodString;
17
+ session_id: z.ZodString;
18
+ source: z.ZodEnum<["claude_code", "codex"]>;
19
+ collected_via: z.ZodEnum<["hook", "backfill"]>;
20
+ started_at: z.ZodString;
21
+ ended_at: z.ZodString;
22
+ model_id: z.ZodNullable<z.ZodString>;
23
+ tokens: z.ZodObject<{
24
+ input: z.ZodNumber;
25
+ output: z.ZodNumber;
26
+ cache_read: z.ZodNumber;
27
+ cache_write: z.ZodNumber;
28
+ }, "strict", z.ZodTypeAny, {
29
+ input: number;
30
+ output: number;
31
+ cache_read: number;
32
+ cache_write: number;
33
+ }, {
34
+ input: number;
35
+ output: number;
36
+ cache_read: number;
37
+ cache_write: number;
38
+ }>;
39
+ user_turns: z.ZodNumber;
40
+ tool_calls: z.ZodNumber;
41
+ tool_errors: z.ZodNumber;
42
+ approval_denials: z.ZodNumber;
43
+ delegated: z.ZodBoolean;
44
+ launched_by: z.ZodNullable<z.ZodEnum<["claude_code"]>>;
45
+ repository_id: z.ZodNullable<z.ZodString>;
46
+ commit_shas: z.ZodArray<z.ZodString, "many">;
47
+ skills: z.ZodArray<z.ZodString, "many">;
48
+ unlisted_skills: z.ZodNumber;
49
+ }, "strict", z.ZodTypeAny, {
50
+ installation_id: string;
51
+ source: "codex" | "claude_code";
52
+ session_id: string;
53
+ schema_version: 1;
54
+ collection_policy_version: "metadata-v3";
55
+ repository_id: string | null;
56
+ skills: string[];
57
+ delegated: boolean;
58
+ tokens: {
59
+ input: number;
60
+ output: number;
61
+ cache_read: number;
62
+ cache_write: number;
63
+ };
64
+ collected_via: "hook" | "backfill";
65
+ started_at: string;
66
+ ended_at: string;
67
+ model_id: string | null;
68
+ user_turns: number;
69
+ tool_calls: number;
70
+ tool_errors: number;
71
+ approval_denials: number;
72
+ launched_by: "claude_code" | null;
73
+ commit_shas: string[];
74
+ unlisted_skills: number;
75
+ }, {
76
+ installation_id: string;
77
+ source: "codex" | "claude_code";
78
+ session_id: string;
79
+ schema_version: 1;
80
+ collection_policy_version: "metadata-v3";
81
+ repository_id: string | null;
82
+ skills: string[];
83
+ delegated: boolean;
84
+ tokens: {
85
+ input: number;
86
+ output: number;
87
+ cache_read: number;
88
+ cache_write: number;
89
+ };
90
+ collected_via: "hook" | "backfill";
91
+ started_at: string;
92
+ ended_at: string;
93
+ model_id: string | null;
94
+ user_turns: number;
95
+ tool_calls: number;
96
+ tool_errors: number;
97
+ approval_denials: number;
98
+ launched_by: "claude_code" | null;
99
+ commit_shas: string[];
100
+ unlisted_skills: number;
101
+ }>, {
102
+ installation_id: string;
103
+ source: "codex" | "claude_code";
104
+ session_id: string;
105
+ schema_version: 1;
106
+ collection_policy_version: "metadata-v3";
107
+ repository_id: string | null;
108
+ skills: string[];
109
+ delegated: boolean;
110
+ tokens: {
111
+ input: number;
112
+ output: number;
113
+ cache_read: number;
114
+ cache_write: number;
115
+ };
116
+ collected_via: "hook" | "backfill";
117
+ started_at: string;
118
+ ended_at: string;
119
+ model_id: string | null;
120
+ user_turns: number;
121
+ tool_calls: number;
122
+ tool_errors: number;
123
+ approval_denials: number;
124
+ launched_by: "claude_code" | null;
125
+ commit_shas: string[];
126
+ unlisted_skills: number;
127
+ }, {
128
+ installation_id: string;
129
+ source: "codex" | "claude_code";
130
+ session_id: string;
131
+ schema_version: 1;
132
+ collection_policy_version: "metadata-v3";
133
+ repository_id: string | null;
134
+ skills: string[];
135
+ delegated: boolean;
136
+ tokens: {
137
+ input: number;
138
+ output: number;
139
+ cache_read: number;
140
+ cache_write: number;
141
+ };
142
+ collected_via: "hook" | "backfill";
143
+ started_at: string;
144
+ ended_at: string;
145
+ model_id: string | null;
146
+ user_turns: number;
147
+ tool_calls: number;
148
+ tool_errors: number;
149
+ approval_denials: number;
150
+ launched_by: "claude_code" | null;
151
+ commit_shas: string[];
152
+ unlisted_skills: number;
153
+ }>;
154
+ export type SessionSummaryUpload = z.infer<typeof SessionSummaryUploadSchema>;
155
+ /** Only recognizable model identifiers leave the device; anything else is reported as unknown. */
156
+ export declare function allowlistedModelId(model: string | null): string | null;
157
+ export declare function toSessionUpload(session: LocalSessionSummary, context: {
158
+ installationId: string;
159
+ collectedVia: "hook" | "backfill";
160
+ policy?: RepositoryPolicy;
161
+ }): SessionSummaryUpload;
162
+ export declare function sessionSpoolPath(): string;
163
+ type SessionSpool = Record<string, SessionSummaryUpload>;
164
+ export declare function readSessionSpool(): Promise<SessionSpool>;
165
+ export declare function queueSessionSummaries(summaries: SessionSummaryUpload[]): Promise<number>;
166
+ export declare function removeSessionSummaries(sent: SessionSummaryUpload[]): Promise<void>;
167
+ /** Summarizes every local session whose transcript changed since `since` and queues it for upload. */
168
+ export declare function sweepLocalSessions(input: {
169
+ since: number;
170
+ installationId: string;
171
+ collectedVia: "hook" | "backfill";
172
+ policy?: RepositoryPolicy;
173
+ home?: string;
174
+ }): Promise<{
175
+ summarized: number;
176
+ queued: number;
177
+ }>;
178
+ export {};
179
+ //# sourceMappingURL=session-summary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-summary.d.ts","sourceRoot":"","sources":["../../src/pace/session-summary.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAwB,KAAK,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AACrF,OAAO,EAAiE,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAkBvH;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,UAAU,GAAE,MAAM,EAAO,GAAG;IAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAIpH;AAED,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyBrC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,kGAAkG;AAClG,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAItE;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,mBAAmB,EAC5B,OAAO,EAAE;IAAE,cAAc,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,GAAG,UAAU,CAAC;IAAC,MAAM,CAAC,EAAE,gBAAgB,CAAA;CAAE,GAChG,oBAAoB,CA0BtB;AAID,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;AAGzD,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,YAAY,CAAC,CAY9D;AAQD,wBAAsB,qBAAqB,CAAC,SAAS,EAAE,oBAAoB,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAK9F;AAED,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,oBAAoB,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAQxF;AAED,sGAAsG;AACtG,wBAAsB,kBAAkB,CAAC,KAAK,EAAE;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,UAAU,CAAC;IAClC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAKlD"}
@@ -0,0 +1,140 @@
1
+ import fs from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { z } from "zod";
5
+ import { collectLocalSessions } from "./local-sessions.js";
6
+ import { approvedRepositoryId, readRepositoryPolicy, sessionCommitShas } from "./repository.js";
7
+ function readPolicySkills() {
8
+ return readRepositoryPolicy()?.skills ?? [];
9
+ }
10
+ /**
11
+ * One content-free summary per AI coding session, uploaded to Unfairly
12
+ * Intelligence. This is the unit the server joins to GitHub pull requests and
13
+ * prices into spend. Keep in sync with src/lib/ai-pace/sessions.ts.
14
+ */
15
+ const MODEL_ID = /^(claude-[a-z0-9.-]{1,48}|gpt-[a-z0-9.-]{1,32}|o[1-9][a-z0-9-]{0,20}|gemini-[a-z0-9.-]{1,40}|codex-[a-z0-9.-]{1,32})$/;
16
+ const Count = z.number().int().nonnegative();
17
+ const SKILL_ID = /^[a-z0-9][a-z0-9:_.-]{0,119}$/;
18
+ /** Published plugin skills are namespaced (`superpowers:brainstorming`); a public name, not content. */
19
+ const PUBLIC_SKILL = /^[a-z0-9][a-z0-9-]{0,40}:[a-z0-9][a-z0-9-]{0,78}$/;
20
+ /**
21
+ * Splits a session's skills into names that may be reported (published plugin
22
+ * skills and the organization's own catalog) and a count of everything else,
23
+ * such as personal or project skills, whose names never leave the device.
24
+ */
25
+ export function reportableSkills(skills, orgCatalog = []) {
26
+ const catalog = new Set(orgCatalog);
27
+ const reportable = [...new Set(skills)].filter((skill) => SKILL_ID.test(skill) && (PUBLIC_SKILL.test(skill) || catalog.has(skill)));
28
+ return { skills: reportable.slice(0, 20), unlisted: new Set(skills).size - reportable.length };
29
+ }
30
+ export const SessionSummaryUploadSchema = z.object({
31
+ schema_version: z.literal(1),
32
+ collection_policy_version: z.literal("metadata-v3"),
33
+ installation_id: z.string().uuid(),
34
+ session_id: z.string().regex(/^[A-Za-z0-9_-]{1,128}$/),
35
+ source: z.enum(["claude_code", "codex"]),
36
+ collected_via: z.enum(["hook", "backfill"]),
37
+ started_at: z.string().datetime(),
38
+ ended_at: z.string().datetime(),
39
+ model_id: z.string().regex(MODEL_ID).nullable(),
40
+ tokens: z.object({ input: Count, output: Count, cache_read: Count, cache_write: Count }).strict(),
41
+ user_turns: Count,
42
+ tool_calls: Count,
43
+ tool_errors: Count,
44
+ approval_denials: Count,
45
+ delegated: z.boolean(),
46
+ launched_by: z.enum(["claude_code"]).nullable(),
47
+ repository_id: z.string().uuid().nullable(),
48
+ commit_shas: z.array(z.string().regex(/^[a-f0-9]{40}$/)).max(50),
49
+ skills: z.array(z.string().regex(SKILL_ID)).max(20),
50
+ unlisted_skills: Count,
51
+ }).strict().superRefine((summary, context) => {
52
+ if (summary.commit_shas.length && !summary.repository_id) {
53
+ context.addIssue({ code: z.ZodIssueCode.custom, path: ["commit_shas"], message: "commit_shas require an approved repository_id" });
54
+ }
55
+ });
56
+ /** Only recognizable model identifiers leave the device; anything else is reported as unknown. */
57
+ export function allowlistedModelId(model) {
58
+ if (!model)
59
+ return null;
60
+ const normalized = model.trim().toLowerCase();
61
+ return MODEL_ID.test(normalized) ? normalized : null;
62
+ }
63
+ export function toSessionUpload(session, context) {
64
+ const repositoryId = approvedRepositoryId(session.cwd, context.policy) ?? null;
65
+ const commits = repositoryId && session.cwd ? sessionCommitShas(session.cwd, session).map((sha) => sha.toLowerCase()) : [];
66
+ const skillReport = reportableSkills(session.skills ?? [], context.policy?.skills ?? readPolicySkills());
67
+ return SessionSummaryUploadSchema.parse({
68
+ schema_version: 1,
69
+ collection_policy_version: "metadata-v3",
70
+ installation_id: context.installationId,
71
+ session_id: session.sessionId.replace(/[^A-Za-z0-9_-]/g, "").slice(0, 128) || "unknown",
72
+ source: session.client,
73
+ collected_via: context.collectedVia,
74
+ started_at: new Date(session.startedAt).toISOString(),
75
+ ended_at: new Date(session.endedAt).toISOString(),
76
+ model_id: allowlistedModelId(session.primaryModel),
77
+ tokens: { input: session.tokens.input, output: session.tokens.output, cache_read: session.tokens.cacheRead, cache_write: session.tokens.cacheWrite },
78
+ user_turns: session.userTurns,
79
+ tool_calls: session.toolCalls,
80
+ tool_errors: session.toolErrors,
81
+ approval_denials: session.approvalDenials,
82
+ delegated: session.delegated,
83
+ launched_by: session.launchedBy,
84
+ repository_id: repositoryId,
85
+ commit_shas: commits,
86
+ skills: skillReport.skills,
87
+ unlisted_skills: skillReport.unlisted,
88
+ });
89
+ }
90
+ // Pending uploads, keyed by source and session so a later, fuller summary of a
91
+ // still-running session replaces the earlier one.
92
+ export function sessionSpoolPath() {
93
+ return process.env.UNFAIRLY_PACE_SESSION_SPOOL ?? path.join(os.homedir(), ".unfairly", "pace", "sessions.json");
94
+ }
95
+ const spoolKey = (summary) => `${summary.source}:${summary.session_id}`;
96
+ export async function readSessionSpool() {
97
+ try {
98
+ const parsed = JSON.parse(await fs.readFile(sessionSpoolPath(), "utf8"));
99
+ const valid = {};
100
+ for (const [key, value] of Object.entries(parsed)) {
101
+ const summary = SessionSummaryUploadSchema.safeParse(value);
102
+ if (summary.success)
103
+ valid[key] = summary.data;
104
+ }
105
+ return valid;
106
+ }
107
+ catch {
108
+ return {};
109
+ }
110
+ }
111
+ async function writeSessionSpool(spool) {
112
+ const file = sessionSpoolPath();
113
+ await fs.mkdir(path.dirname(file), { recursive: true, mode: 0o700 });
114
+ await fs.writeFile(file, `${JSON.stringify(spool)}\n`, { encoding: "utf8", mode: 0o600 });
115
+ }
116
+ export async function queueSessionSummaries(summaries) {
117
+ const spool = await readSessionSpool();
118
+ for (const summary of summaries)
119
+ spool[spoolKey(summary)] = summary;
120
+ await writeSessionSpool(spool);
121
+ return Object.keys(spool).length;
122
+ }
123
+ export async function removeSessionSummaries(sent) {
124
+ const spool = await readSessionSpool();
125
+ for (const summary of sent) {
126
+ const current = spool[spoolKey(summary)];
127
+ // Keep a newer summary that arrived while this batch was uploading.
128
+ if (current && current.ended_at === summary.ended_at)
129
+ delete spool[spoolKey(summary)];
130
+ }
131
+ await writeSessionSpool(spool);
132
+ }
133
+ /** Summarizes every local session whose transcript changed since `since` and queues it for upload. */
134
+ export async function sweepLocalSessions(input) {
135
+ const sessions = await collectLocalSessions({ since: input.since, home: input.home });
136
+ const summaries = sessions.map((session) => toSessionUpload(session, input));
137
+ const queued = summaries.length ? await queueSessionSummaries(summaries) : (Object.keys(await readSessionSpool()).length);
138
+ return { summarized: summaries.length, queued };
139
+ }
140
+ //# sourceMappingURL=session-summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-summary.js","sourceRoot":"","sources":["../../src/pace/session-summary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { type PaceEvent } from "./schema.js";
2
+ export declare function paceSpoolPath(): string;
3
+ export declare function appendPaceEvent(event: PaceEvent): Promise<string>;
4
+ export declare function readPaceEvents(limit?: number): Promise<PaceEvent[]>;
5
+ export declare function removePaceEvents(ids: Set<string>): Promise<void>;
6
+ //# sourceMappingURL=spool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spool.d.ts","sourceRoot":"","sources":["../../src/pace/spool.ts"],"names":[],"mappings":"AAIA,OAAO,EAA0C,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAErF,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAsB,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAOvE;AAED,wBAAsB,cAAc,CAAC,KAAK,SAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAoCtE;AAED,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBtE"}
@@ -0,0 +1,87 @@
1
+ import fs from "node:fs/promises";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { migrateLegacyEvent } from "./normalize.js";
5
+ import { PaceEventSchema, PaceLegacyEventSchema } from "./schema.js";
6
+ export function paceSpoolPath() {
7
+ return process.env.UNFAIRLY_PACE_SPOOL ?? path.join(os.homedir(), ".unfairly", "pace", "events.jsonl");
8
+ }
9
+ export async function appendPaceEvent(event) {
10
+ const parsed = PaceEventSchema.parse(event);
11
+ const spool = paceSpoolPath();
12
+ await fs.mkdir(path.dirname(spool), { recursive: true, mode: 0o700 });
13
+ await fs.appendFile(spool, `${JSON.stringify(parsed)}\n`, { encoding: "utf8", mode: 0o600 });
14
+ await fs.chmod(spool, 0o600).catch(() => undefined);
15
+ return spool;
16
+ }
17
+ export async function readPaceEvents(limit = 250) {
18
+ let raw;
19
+ try {
20
+ raw = await fs.readFile(paceSpoolPath(), "utf8");
21
+ }
22
+ catch (error) {
23
+ if (error.code === "ENOENT")
24
+ return [];
25
+ throw error;
26
+ }
27
+ const events = [];
28
+ let needsMigration = false;
29
+ for (const line of raw.split("\n")) {
30
+ if (!line.trim())
31
+ continue;
32
+ let candidate;
33
+ try {
34
+ candidate = JSON.parse(line);
35
+ }
36
+ catch {
37
+ needsMigration = true;
38
+ continue;
39
+ }
40
+ const parsed = PaceEventSchema.safeParse(candidate);
41
+ if (parsed.success) {
42
+ events.push(parsed.data);
43
+ }
44
+ else {
45
+ const legacy = PaceLegacyEventSchema.safeParse(candidate);
46
+ if (legacy.success)
47
+ events.push(migrateLegacyEvent(legacy.data));
48
+ needsMigration = true;
49
+ }
50
+ }
51
+ if (needsMigration) {
52
+ const spool = paceSpoolPath();
53
+ await fs.writeFile(spool, events.length ? `${events.map((event) => JSON.stringify(event)).join("\n")}\n` : "", {
54
+ encoding: "utf8",
55
+ mode: 0o600,
56
+ });
57
+ }
58
+ return events.slice(0, limit);
59
+ }
60
+ export async function removePaceEvents(ids) {
61
+ const spool = paceSpoolPath();
62
+ let raw;
63
+ try {
64
+ raw = await fs.readFile(spool, "utf8");
65
+ }
66
+ catch (error) {
67
+ if (error.code === "ENOENT")
68
+ return;
69
+ throw error;
70
+ }
71
+ const remaining = raw.split("\n").filter((line) => {
72
+ if (!line.trim())
73
+ return false;
74
+ try {
75
+ const event = JSON.parse(line);
76
+ return !event.event_id || !ids.has(event.event_id);
77
+ }
78
+ catch {
79
+ return true;
80
+ }
81
+ });
82
+ await fs.writeFile(spool, remaining.length ? `${remaining.join("\n")}\n` : "", {
83
+ encoding: "utf8",
84
+ mode: 0o600,
85
+ });
86
+ }
87
+ //# sourceMappingURL=spool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spool.js","sourceRoot":"","sources":["../../src/pace/spool.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unfairly",
3
- "version": "0.8.1",
3
+ "version": "0.8.2",
4
4
  "description": "CLI + stdio MCP + library SDK for the Unfairly multiplayer context layer — sync vaults, run agents, emit events",
5
5
  "keywords": [
6
6
  "unfairly",
@@ -53,6 +53,7 @@
53
53
  "build": "tsc && chmod +x dist/index.js",
54
54
  "dev": "tsx src/index.ts",
55
55
  "test": "vitest run",
56
+ "prepack": "npm run build && node scripts/stage-intelligence-plugin.mjs",
56
57
  "prepublishOnly": "npm run build"
57
58
  },
58
59
  "dependencies": {
@@ -76,6 +77,7 @@
76
77
  },
77
78
  "files": [
78
79
  "dist",
80
+ "plugin",
79
81
  "README.md",
80
82
  "CHANGELOG.md"
81
83
  ]
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "ai-pace",
3
+ "version": "0.1.0",
4
+ "description": "Unfairly Intelligence: content-free organizational learning and reusable team playbooks.",
5
+ "author": {
6
+ "name": "Unfairly"
7
+ },
8
+ "skills": "./skills/"
9
+ }